From c480ed3b22f500ee4b0bf976b2a0e5d4d2ac5847 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Nov 05 2019 19:04:39 +0000 Subject: import libvirt-4.5.0-35.module+el8.1.0+4227+b2722cb3 --- 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..4f8ba04 --- /dev/null +++ b/SOURCES/libvirt-Handle-copying-bitmaps-to-larger-data-buffers.patch @@ -0,0 +1,56 @@ +From e75abae126f9fcaf1e8478f0780ecae736f7d3e1 Mon Sep 17 00:00:00 2001 +Message-Id: +From: "Allen, John" +Date: Tue, 2 Jul 2019 17:05:34 +0200 +Subject: [PATCH] Handle copying bitmaps to larger data buffers +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +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) + +https: //bugzilla.redhat.com/show_bug.cgi?id=1703160 +Signed-off-by: Erik Skultety +Message-Id: <1a487c4f1ba9725eb7325debeeff2861d7047890.1562079635.git.eskultet@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/virbitmap.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/util/virbitmap.c b/src/util/virbitmap.c +index 49e542a4e6..7df0a2d4f3 100644 +--- a/src/util/virbitmap.c ++++ b/src/util/virbitmap.c +@@ -831,11 +831,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.22.0 + diff --git a/SOURCES/libvirt-PPC64-support-for-NVIDIA-V100-GPU-with-NVLink2-passthrough.patch b/SOURCES/libvirt-PPC64-support-for-NVIDIA-V100-GPU-with-NVLink2-passthrough.patch new file mode 100644 index 0000000..d29a9cf --- /dev/null +++ b/SOURCES/libvirt-PPC64-support-for-NVIDIA-V100-GPU-with-NVLink2-passthrough.patch @@ -0,0 +1,183 @@ +From 5347b12008842b5c86f766e391c6f3756afbff7d Mon Sep 17 00:00:00 2001 +Message-Id: <5347b12008842b5c86f766e391c6f3756afbff7d@dist-git> +From: Daniel Henrique Barboza +Date: Fri, 3 May 2019 13:54:53 +0200 +Subject: [PATCH] PPC64 support for NVIDIA V100 GPU with NVLink2 passthrough + +The NVIDIA V100 GPU has an onboard RAM that is mapped into the +host memory and accessible as normal RAM via an NVLink2 bridge. When +passed through in a guest, QEMU puts the NVIDIA RAM window in a +non-contiguous area, above the PCI MMIO area that starts at 32TiB. +This means that the NVIDIA RAM window starts at 64TiB and go all the +way to 128TiB. + +This means that the guest might request a 64-bit window, for each PCI +Host Bridge, that goes all the way to 128TiB. However, the NVIDIA RAM +window isn't counted as regular RAM, thus this window is considered +only for the allocation of the Translation and Control Entry (TCE). +For more information about how NVLink2 support works in QEMU, +refer to the accepted implementation [1]. + +This memory layout differs from the existing VFIO case, requiring its +own formula. This patch changes the PPC64 code of +@qemuDomainGetMemLockLimitBytes to: + +- detect if we have a NVLink2 bridge being passed through to the +guest. This is done by using the @ppc64VFIODeviceIsNV2Bridge function +added in the previous patch. The existence of the NVLink2 bridge in +the guest means that we are dealing with the NVLink2 memory layout; + +- if an IBM NVLink2 bridge exists, passthroughLimit is calculated in a +different way to account for the extra memory the TCE table can alloc. +The 64TiB..128TiB window is more than enough to fit all possible +GPUs, thus the memLimit is the same regardless of passing through 1 or +multiple V100 GPUs. + +Further reading explaining the background +[1] https://lists.gnu.org/archive/html/qemu-devel/2019-03/msg03700.html +[2] https://www.redhat.com/archives/libvir-list/2019-March/msg00660.html +[3] https://www.redhat.com/archives/libvir-list/2019-April/msg00527.html + +Signed-off-by: Daniel Henrique Barboza +Reviewed-by: Erik Skultety +(cherry picked from commit 1a922648f67f56c4374d647feebf2adb9a642f96) + +https://bugzilla.redhat.com/show_bug.cgi?id=1505998 + +Conflicts: + The upstream commit relied on: + - v4.7.0-37-gb72183223f + - v4.7.0-38-ga14f597266 + which were not backported so virPCIDeviceAddressAsString had to + swapped for the former virDomainPCIAddressAsString in order to + compile. + +Signed-off-by: Erik Skultety +Message-Id: <03c00ebf46d85b0615134ef8655e67a4c909b7da.1556884443.git.eskultet@redhat.com> +Reviewed-by: Andrea Bolognani +--- + src/qemu/qemu_domain.c | 80 ++++++++++++++++++++++++++++++++---------- + 1 file changed, 61 insertions(+), 19 deletions(-) + +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index a8bc618389..21f0722495 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -9813,7 +9813,7 @@ qemuDomainUpdateCurrentMemorySize(virQEMUDriverPtr driver, + * such as '0004:04:00.0', and tells if the device is a NVLink2 + * bridge. + */ +-static ATTRIBUTE_UNUSED bool ++static bool + ppc64VFIODeviceIsNV2Bridge(const char *device) + { + const char *nvlink2Files[] = {"ibm,gpu", "ibm,nvlink", +@@ -9851,7 +9851,9 @@ getPPC64MemLockLimitBytes(virDomainDefPtr def) + unsigned long long maxMemory = 0; + unsigned long long passthroughLimit = 0; + size_t i, nPCIHostBridges = 0; ++ virPCIDeviceAddressPtr pciAddr; + bool usesVFIO = false; ++ bool nvlink2Capable = false; + + for (i = 0; i < def->ncontrollers; i++) { + virDomainControllerDefPtr cont = def->controllers[i]; +@@ -9869,7 +9871,17 @@ getPPC64MemLockLimitBytes(virDomainDefPtr def) + dev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI && + dev->source.subsys.u.pci.backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) { + usesVFIO = true; +- break; ++ ++ pciAddr = &dev->source.subsys.u.pci.addr; ++ if (virPCIDeviceAddressIsValid(pciAddr, false)) { ++ VIR_AUTOFREE(char *) pciAddrStr = NULL; ++ ++ pciAddrStr = virDomainPCIAddressAsString(pciAddr); ++ if (ppc64VFIODeviceIsNV2Bridge(pciAddrStr)) { ++ nvlink2Capable = true; ++ break; ++ } ++ } + } + } + +@@ -9896,29 +9908,59 @@ getPPC64MemLockLimitBytes(virDomainDefPtr def) + 4096 * nPCIHostBridges + + 8192; + +- /* passthroughLimit := max( 2 GiB * #PHBs, (c) +- * memory (d) +- * + memory * 1/512 * #PHBs + 8 MiB ) (e) ++ /* NVLink2 support in QEMU is a special case of the passthrough ++ * mechanics explained in the usesVFIO case below. The GPU RAM ++ * is placed with a gap after maxMemory. The current QEMU ++ * implementation puts the NVIDIA RAM above the PCI MMIO, which ++ * starts at 32TiB and is the MMIO reserved for the guest main RAM. + * +- * (c) is the pre-DDW VFIO DMA window accounting. We're allowing 2 GiB +- * rather than 1 GiB ++ * This window ends at 64TiB, and this is where the GPUs are being ++ * placed. The next available window size is at 128TiB, and ++ * 64TiB..128TiB will fit all possible NVIDIA GPUs. + * +- * (d) is the with-DDW (and memory pre-registration and related +- * features) DMA window accounting - assuming that we only account RAM +- * once, even if mapped to multiple PHBs ++ * The same assumption as the most common case applies here: ++ * the guest will request a 64-bit DMA window, per PHB, that is ++ * big enough to map all its RAM, which is now at 128TiB due ++ * to the GPUs. + * +- * (e) is the with-DDW userspace view and overhead for the 64-bit DMA +- * window. This is based a bit on expected guest behaviour, but there +- * really isn't a way to completely avoid that. We assume the guest +- * requests a 64-bit DMA window (per PHB) just big enough to map all +- * its RAM. 4 kiB page size gives the 1/512; it will be less with 64 +- * kiB pages, less still if the guest is mapped with hugepages (unlike +- * the default 32-bit DMA window, DDW windows can use large IOMMU +- * pages). 8 MiB is for second and further level overheads, like (b) */ +- if (usesVFIO) ++ * Note that the NVIDIA RAM window must be accounted for the TCE ++ * table size, but *not* for the main RAM (maxMemory). This gives ++ * us the following passthroughLimit for the NVLink2 case: ++ * ++ * passthroughLimit = maxMemory + ++ * 128TiB/512KiB * #PHBs + 8 MiB */ ++ if (nvlink2Capable) { ++ passthroughLimit = maxMemory + ++ 128 * (1ULL<<30) / 512 * nPCIHostBridges + ++ 8192; ++ } else if (usesVFIO) { ++ /* For regular (non-NVLink2 present) VFIO passthrough, the value ++ * of passthroughLimit is: ++ * ++ * passthroughLimit := max( 2 GiB * #PHBs, (c) ++ * memory (d) ++ * + memory * 1/512 * #PHBs + 8 MiB ) (e) ++ * ++ * (c) is the pre-DDW VFIO DMA window accounting. We're allowing 2 ++ * GiB rather than 1 GiB ++ * ++ * (d) is the with-DDW (and memory pre-registration and related ++ * features) DMA window accounting - assuming that we only account ++ * RAM once, even if mapped to multiple PHBs ++ * ++ * (e) is the with-DDW userspace view and overhead for the 64-bit ++ * DMA window. This is based a bit on expected guest behaviour, but ++ * there really isn't a way to completely avoid that. We assume the ++ * guest requests a 64-bit DMA window (per PHB) just big enough to ++ * map all its RAM. 4 kiB page size gives the 1/512; it will be ++ * less with 64 kiB pages, less still if the guest is mapped with ++ * hugepages (unlike the default 32-bit DMA window, DDW windows ++ * can use large IOMMU pages). 8 MiB is for second and further level ++ * overheads, like (b) */ + passthroughLimit = MAX(2 * 1024 * 1024 * nPCIHostBridges, + memory + + memory / 512 * nPCIHostBridges + 8192); ++ } + + memKB = baseLimit + passthroughLimit; + +-- +2.21.0 + diff --git a/SOURCES/libvirt-Revert-Separate-out-StateAutoStart-from-StateInitialize.patch b/SOURCES/libvirt-Revert-Separate-out-StateAutoStart-from-StateInitialize.patch new file mode 100644 index 0000000..abec5aa --- /dev/null +++ b/SOURCES/libvirt-Revert-Separate-out-StateAutoStart-from-StateInitialize.patch @@ -0,0 +1,93 @@ +From 8069bb50b2548acd3f2176499ede205e6099c067 Mon Sep 17 00:00:00 2001 +Message-Id: <8069bb50b2548acd3f2176499ede205e6099c067@dist-git> +From: Michal Privoznik +Date: Thu, 27 Jun 2019 15:18:17 +0200 +Subject: [PATCH] Revert "Separate out StateAutoStart from StateInitialize" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This reverts commit e4a969092bda5b3b952963fdf6658895165040b7. + +Now that drivers may call virConnectOpen() on secondary drivers, it +doesn't make much sense to have autostart separated from driver +initialization callback. In fact, it creates a problem because one +driver during its initialization might try to fetch an object from +another driver but since the object is yet to be autostarted the fetch +fails. This has been observed in reality: qemu driver performs +qemuProcessReconnect() during qemu's stateInitialize phase which may +call virDomainDiskTranslateSourcePool() which connects to the storage +driver to look up the volume. But the storage driver did not autostart +its pools yet therefore volume lookup fails and the domain is killed. + +Signed-off-by: Michal Privoznik +Reviewed-by: Ján Tomko +(cherry picked from commit 07a9c8bae8b80ef1650e6d05869cbf55c6aea837) + +https://bugzilla.redhat.com/show_bug.cgi?id=1685151 + +Signed-off-by: Michal Privoznik +Message-Id: <4ed5f8f4edd0053cc14f4bb579a945b606b36f5a.1561641375.git.mprivozn@redhat.com> +Reviewed-by: Jiri Denemark +--- + src/driver-state.h | 4 ---- + src/libvirt.c | 14 +------------- + 2 files changed, 1 insertion(+), 17 deletions(-) + +diff --git a/src/driver-state.h b/src/driver-state.h +index 1cb3e4faf3..e1e060bcc5 100644 +--- a/src/driver-state.h ++++ b/src/driver-state.h +@@ -30,9 +30,6 @@ typedef int + virStateInhibitCallback callback, + void *opaque); + +-typedef void +-(*virDrvStateAutoStart)(void); +- + typedef int + (*virDrvStateCleanup)(void); + +@@ -48,7 +45,6 @@ typedef virStateDriver *virStateDriverPtr; + struct _virStateDriver { + const char *name; + virDrvStateInitialize stateInitialize; +- virDrvStateAutoStart stateAutoStart; + virDrvStateCleanup stateCleanup; + virDrvStateReload stateReload; + virDrvStateStop stateStop; +diff --git a/src/libvirt.c b/src/libvirt.c +index 52f4dd2808..c9e5f47fd4 100644 +--- a/src/libvirt.c ++++ b/src/libvirt.c +@@ -637,11 +637,7 @@ virRegisterStateDriver(virStateDriverPtr driver) + * @callback: callback to invoke to inhibit shutdown of the daemon + * @opaque: data to pass to @callback + * +- * Initialize all virtualization drivers. Accomplished in two phases, +- * the first being state and structure initialization followed by any +- * auto start supported by the driver. This is done to ensure dependencies +- * that some drivers may have on another driver having been initialized +- * will exist, such as the storage driver's need to use the secret driver. ++ * Initialize all virtualization drivers. + * + * Returns 0 if all succeed, -1 upon any failure. + */ +@@ -669,14 +665,6 @@ virStateInitialize(bool privileged, + } + } + } +- +- for (i = 0; i < virStateDriverTabCount; i++) { +- if (virStateDriverTab[i]->stateAutoStart) { +- VIR_DEBUG("Running global auto start for %s state driver", +- virStateDriverTab[i]->name); +- virStateDriverTab[i]->stateAutoStart(); +- } +- } + return 0; + } + +-- +2.22.0 + diff --git a/SOURCES/libvirt-Revert-util-vircgroup-pass-parent-cgroup-into-virCgroupDetectControllersCB.patch b/SOURCES/libvirt-Revert-util-vircgroup-pass-parent-cgroup-into-virCgroupDetectControllersCB.patch new file mode 100644 index 0000000..796cc2e --- /dev/null +++ b/SOURCES/libvirt-Revert-util-vircgroup-pass-parent-cgroup-into-virCgroupDetectControllersCB.patch @@ -0,0 +1,108 @@ +From 2395bf301cf76ffa863a3c2e125d52345cfbf6b5 Mon Sep 17 00:00:00 2001 +Message-Id: <2395bf301cf76ffa863a3c2e125d52345cfbf6b5@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:08:23 +0200 +Subject: [PATCH] Revert "util: vircgroup: pass parent cgroup into + virCgroupDetectControllersCB" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This reverts commit 7bca1c9bdc85247446129f856e27c80a32819e17. + +As it turns out it's not a good idea on systemd hosts. The root +cgroup can have all controllers enabled but they don't have to be +enabled for sub-cgroups. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Ján Tomko +(cherry picked from commit d117431143d5b6dcfc8fae4a6b3fae23881d0937) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <754b0ac5a0f1bd21e79eaeb71f6d2ab811446168.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 2 +- + src/util/vircgroupbackend.h | 3 +-- + src/util/vircgroupv1.c | 3 +-- + src/util/vircgroupv2.c | 17 ++++++----------- + 4 files changed, 9 insertions(+), 16 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index ff2a0b75b5..a7fb595bce 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -412,7 +412,7 @@ virCgroupDetect(virCgroupPtr group, + + for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) { + if (group->backends[i]) { +- int rc = group->backends[i]->detectControllers(group, controllers, parent); ++ int rc = group->backends[i]->detectControllers(group, controllers); + if (rc < 0) + return -1; + controllersAvailable |= rc; +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index 05af118ec1..a825dc4be7 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -96,8 +96,7 @@ typedef char * + + typedef int + (*virCgroupDetectControllersCB)(virCgroupPtr group, +- int controllers, +- virCgroupPtr parent); ++ int controllers); + + typedef bool + (*virCgroupHasControllerCB)(virCgroupPtr cgroup, +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 5b218c7f78..58bd20d636 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -419,8 +419,7 @@ virCgroupV1StealPlacement(virCgroupPtr group) + + static int + virCgroupV1DetectControllers(virCgroupPtr group, +- int controllers, +- virCgroupPtr parent ATTRIBUTE_UNUSED) ++ int controllers) + { + size_t i; + size_t j; +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index bdeab397a3..b0ed889cc8 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -285,21 +285,16 @@ virCgroupV2ParseControllersFile(virCgroupPtr group) + + static int + virCgroupV2DetectControllers(virCgroupPtr group, +- int controllers, +- virCgroupPtr parent) ++ int controllers) + { + size_t i; + +- if (parent) { +- group->unified.controllers = parent->unified.controllers; +- } else { +- if (virCgroupV2ParseControllersFile(group) < 0) +- return -1; ++ if (virCgroupV2ParseControllersFile(group) < 0) ++ return -1; + +- /* In cgroup v2 there is no cpuacct controller, the cpu.stat file always +- * exists with usage stats. */ +- group->unified.controllers |= 1 << VIR_CGROUP_CONTROLLER_CPUACCT; +- } ++ /* In cgroup v2 there is no cpuacct controller, the cpu.stat file always ++ * exists with usage stats. */ ++ group->unified.controllers |= 1 << VIR_CGROUP_CONTROLLER_CPUACCT; + + if (controllers >= 0) + group->unified.controllers &= controllers; +-- +2.22.0 + diff --git a/SOURCES/libvirt-Revert-virStateDriver-Separate-AutoStart-from-Initialize.patch b/SOURCES/libvirt-Revert-virStateDriver-Separate-AutoStart-from-Initialize.patch new file mode 100644 index 0000000..45fdd94 --- /dev/null +++ b/SOURCES/libvirt-Revert-virStateDriver-Separate-AutoStart-from-Initialize.patch @@ -0,0 +1,295 @@ +From 799c9dd37390878a54be303b3e3e27445049bf2b Mon Sep 17 00:00:00 2001 +Message-Id: <799c9dd37390878a54be303b3e3e27445049bf2b@dist-git> +From: Michal Privoznik +Date: Thu, 27 Jun 2019 15:18:16 +0200 +Subject: [PATCH] Revert "virStateDriver - Separate AutoStart from Initialize" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This reverts commit cefb97fb815c81fc882da752f45effd23bcb9b4b. + +The stateAutoStart callback will be removed in the next commit. +Therefore move autostarting of domains, networks and storage +pools back into stateInitialize callbacks. + +Signed-off-by: Michal Privoznik +Reviewed-by: Ján Tomko +(cherry picked from commit fc380c2e018ae15347d4c281a7e74896c48cac4a) + +https://bugzilla.redhat.com/show_bug.cgi?id=1685151 + +The difference to the upstream commit is uml driver change. In +upstream, the uml driver was dropped, but it's still kept around +in downstream. + +Signed-off-by: Michal Privoznik +Message-Id: +Reviewed-by: Jiri Denemark +--- + src/libxl/libxl_driver.c | 14 +++----------- + src/lxc/lxc_driver.c | 16 ++-------------- + src/network/bridge_driver.c | 22 ++++------------------ + src/qemu/qemu_driver.c | 17 ++--------------- + src/storage/storage_driver.c | 19 ++----------------- + src/uml/uml_driver.c | 17 ++--------------- + 6 files changed, 15 insertions(+), 90 deletions(-) + +diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c +index 5a5e792957..99bb010af4 100644 +--- a/src/libxl/libxl_driver.c ++++ b/src/libxl/libxl_driver.c +@@ -773,6 +773,9 @@ libxlStateInitialize(bool privileged, + NULL, NULL) < 0) + goto error; + ++ virDomainObjListForEach(libxl_driver->domains, libxlAutostartDomain, ++ libxl_driver); ++ + virDomainObjListForEach(libxl_driver->domains, libxlDomainManagedSaveLoad, + libxl_driver); + +@@ -784,16 +787,6 @@ libxlStateInitialize(bool privileged, + return -1; + } + +-static void +-libxlStateAutoStart(void) +-{ +- if (!libxl_driver) +- return; +- +- virDomainObjListForEach(libxl_driver->domains, libxlAutostartDomain, +- libxl_driver); +-} +- + static int + libxlStateReload(void) + { +@@ -6479,7 +6472,6 @@ static virConnectDriver libxlConnectDriver = { + static virStateDriver libxlStateDriver = { + .name = "LIBXL", + .stateInitialize = libxlStateInitialize, +- .stateAutoStart = libxlStateAutoStart, + .stateCleanup = libxlStateCleanup, + .stateReload = libxlStateReload, + }; +diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c +index f9794e0655..527fa72083 100644 +--- a/src/lxc/lxc_driver.c ++++ b/src/lxc/lxc_driver.c +@@ -1646,6 +1646,8 @@ static int lxcStateInitialize(bool privileged, + NULL, NULL) < 0) + goto cleanup; + ++ virLXCProcessAutostartAll(lxc_driver); ++ + virObjectUnref(caps); + return 0; + +@@ -1655,19 +1657,6 @@ static int lxcStateInitialize(bool privileged, + return -1; + } + +-/** +- * lxcStateAutoStart: +- * +- * Function to autostart the LXC daemons +- */ +-static void lxcStateAutoStart(void) +-{ +- if (!lxc_driver) +- return; +- +- virLXCProcessAutostartAll(lxc_driver); +-} +- + static void lxcNotifyLoadDomain(virDomainObjPtr vm, int newVM, void *opaque) + { + virLXCDriverPtr driver = opaque; +@@ -5550,7 +5539,6 @@ static virConnectDriver lxcConnectDriver = { + static virStateDriver lxcStateDriver = { + .name = LXC_DRIVER_NAME, + .stateInitialize = lxcStateInitialize, +- .stateAutoStart = lxcStateAutoStart, + .stateCleanup = lxcStateCleanup, + .stateReload = lxcStateReload, + }; +diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c +index d153a8cdb6..a60d7db685 100644 +--- a/src/network/bridge_driver.c ++++ b/src/network/bridge_driver.c +@@ -755,6 +755,10 @@ networkStateInitialize(bool privileged, + networkReloadFirewallRules(network_driver); + networkRefreshDaemons(network_driver); + ++ virNetworkObjListForEach(network_driver->networks, ++ networkAutostartConfig, ++ network_driver); ++ + network_driver->networkEventState = virObjectEventStateNew(); + + #ifdef WITH_FIREWALLD +@@ -794,23 +798,6 @@ networkStateInitialize(bool privileged, + } + + +-/** +- * networkStateAutoStart: +- * +- * Function to AutoStart the bridge configs +- */ +-static void +-networkStateAutoStart(void) +-{ +- if (!network_driver) +- return; +- +- virNetworkObjListForEach(network_driver->networks, +- networkAutostartConfig, +- network_driver); +-} +- +- + /** + * networkStateReload: + * +@@ -5616,7 +5603,6 @@ static virConnectDriver networkConnectDriver = { + static virStateDriver networkStateDriver = { + .name = "bridge", + .stateInitialize = networkStateInitialize, +- .stateAutoStart = networkStateAutoStart, + .stateCleanup = networkStateCleanup, + .stateReload = networkStateReload, + }; +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index 2da87992fd..056d324a62 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -911,6 +911,8 @@ qemuStateInitialize(bool privileged, + + qemuProcessReconnectAll(qemu_driver); + ++ qemuAutostartDomains(qemu_driver); ++ + return 0; + + error: +@@ -921,20 +923,6 @@ qemuStateInitialize(bool privileged, + return -1; + } + +-/** +- * qemuStateAutoStart: +- * +- * Function to auto start the QEMU daemons +- */ +-static void +-qemuStateAutoStart(void) +-{ +- if (!qemu_driver) +- return; +- +- qemuAutostartDomains(qemu_driver); +-} +- + static void qemuNotifyLoadDomain(virDomainObjPtr vm, int newVM, void *opaque) + { + virQEMUDriverPtr driver = opaque; +@@ -21846,7 +21834,6 @@ static virConnectDriver qemuConnectDriver = { + static virStateDriver qemuStateDriver = { + .name = QEMU_DRIVER_NAME, + .stateInitialize = qemuStateInitialize, +- .stateAutoStart = qemuStateAutoStart, + .stateCleanup = qemuStateCleanup, + .stateReload = qemuStateReload, + .stateStop = qemuStateStop, +diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c +index 254818e308..f61fb074e6 100644 +--- a/src/storage/storage_driver.c ++++ b/src/storage/storage_driver.c +@@ -291,6 +291,8 @@ storageStateInitialize(bool privileged, + + storagePoolUpdateAllState(); + ++ storageDriverAutostart(); ++ + driver->storageEventState = virObjectEventStateNew(); + + storageDriverUnlock(); +@@ -307,22 +309,6 @@ storageStateInitialize(bool privileged, + goto cleanup; + } + +-/** +- * storageStateAutoStart: +- * +- * Function to auto start the storage driver +- */ +-static void +-storageStateAutoStart(void) +-{ +- if (!driver) +- return; +- +- storageDriverLock(); +- storageDriverAutostart(); +- storageDriverUnlock(); +-} +- + /** + * storageStateReload: + * +@@ -2843,7 +2829,6 @@ static virConnectDriver storageConnectDriver = { + static virStateDriver stateDriver = { + .name = "storage", + .stateInitialize = storageStateInitialize, +- .stateAutoStart = storageStateAutoStart, + .stateCleanup = storageStateCleanup, + .stateReload = storageStateReload, + }; +diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c +index c77988f01e..296adf55d1 100644 +--- a/src/uml/uml_driver.c ++++ b/src/uml/uml_driver.c +@@ -575,6 +575,8 @@ umlStateInitialize(bool privileged, + + umlDriverUnlock(uml_driver); + ++ umlAutostartConfigs(uml_driver); ++ + VIR_FREE(userdir); + + return 0; +@@ -590,20 +592,6 @@ umlStateInitialize(bool privileged, + return -1; + } + +-/** +- * umlStateAutoStart: +- * +- * Function to autostart the Uml daemons +- */ +-static void +-umlStateAutoStart(void) +-{ +- if (!uml_driver) +- return; +- +- umlAutostartConfigs(uml_driver); +-} +- + static void umlNotifyLoadDomain(virDomainObjPtr vm, int newVM, void *opaque) + { + struct uml_driver *driver = opaque; +@@ -2826,7 +2814,6 @@ static virConnectDriver umlConnectDriver = { + static virStateDriver umlStateDriver = { + .name = "UML", + .stateInitialize = umlStateInitialize, +- .stateAutoStart = umlStateAutoStart, + .stateCleanup = umlStateCleanup, + .stateReload = umlStateReload, + }; +-- +2.22.0 + diff --git a/SOURCES/libvirt-Revert-vircgroup-cleanup-controllers-not-managed-by-systemd-on-error.patch b/SOURCES/libvirt-Revert-vircgroup-cleanup-controllers-not-managed-by-systemd-on-error.patch new file mode 100644 index 0000000..44f72a9 --- /dev/null +++ b/SOURCES/libvirt-Revert-vircgroup-cleanup-controllers-not-managed-by-systemd-on-error.patch @@ -0,0 +1,83 @@ +From ddea95c1c2e32c6454c89aa83d78b26a83564cd4 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:11 +0200 +Subject: [PATCH] Revert "vircgroup: cleanup controllers not managed by systemd + on error" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This reverts commit 1602aa28f820ada66f707cef3e536e8572fbda1e. + +There is no need to call virCgroupRemove() nor virCgroupFree() if +virCgroupEnableMissingControllers() fails because it will not modify +'group' at all. + +The cleanup of directories is done in virCgroupMakeGroup(). + +Reviewed-by: John Ferlan +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Marc Hartmayer +Signed-off-by: Pavel Hrdina +(cherry picked from commit 199eee6aae7af3d813fbe98660c7e0fa1a8ae7b7) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <53288dd310e0305ac3179693e64684eb8b3a31ab.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 25 ++++++++++--------------- + 1 file changed, 10 insertions(+), 15 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index a376b9b89a..7ec1399bc6 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -1059,7 +1059,6 @@ virCgroupNewMachineSystemd(const char *name, + int rv; + virCgroupPtr init; + VIR_AUTOFREE(char *) path = NULL; +- virErrorPtr saved = NULL; + + VIR_DEBUG("Trying to setup machine '%s' via systemd", name); + if ((rv = virSystemdCreateMachine(name, +@@ -1092,24 +1091,20 @@ virCgroupNewMachineSystemd(const char *name, + + if (virCgroupEnableMissingControllers(path, pidleader, + controllers, group) < 0) { +- goto error; ++ return -1; + } + +- if (virCgroupAddProcess(*group, pidleader) < 0) +- goto error; ++ if (virCgroupAddProcess(*group, pidleader) < 0) { ++ virErrorPtr saved = virSaveLastError(); ++ virCgroupRemove(*group); ++ virCgroupFree(group); ++ if (saved) { ++ virSetError(saved); ++ virFreeError(saved); ++ } ++ } + + return 0; +- +- error: +- saved = virSaveLastError(); +- virCgroupRemove(*group); +- virCgroupFree(group); +- if (saved) { +- virSetError(saved); +- virFreeError(saved); +- } +- +- return -1; + } + + +-- +2.22.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 index 936e3ce..a6c1113 100644 --- 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 @@ -1,5 +1,5 @@ -From 5ed86f689f011c36e8008c30dc3dfe89bfbf280a Mon Sep 17 00:00:00 2001 -Message-Id: <5ed86f689f011c36e8008c30dc3dfe89bfbf280a@dist-git> +From 3eaa16967f0546c5d1596bb6c36767cbe01040b9 Mon Sep 17 00:00:00 2001 +Message-Id: <3eaa16967f0546c5d1596bb6c36767cbe01040b9@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 @@ -16,7 +16,7 @@ Fixes CVE-2019-10132 Reviewed-by: Ján Tomko Signed-off-by: Daniel P. Berrangé -(cherry picked from a private commit) +(cherry picked from commit 96f41cd765c9e525fe28ee5abbfbf4a79b3720c7) Reviewed-by: Jiri Denemark Message-Id: <20190515204058.28077-2-berrange@redhat.com> --- @@ -57,5 +57,5 @@ index b78ff902c0..9f25813ae3 100644 if (VIR_ALLOC(priv) < 0) return NULL; -- -2.21.0 +2.22.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 index 0f182be..70eecbc 100644 --- a/SOURCES/libvirt-api-disallow-virConnect-HypervisorCPU-on-read-only-connections.patch +++ b/SOURCES/libvirt-api-disallow-virConnect-HypervisorCPU-on-read-only-connections.patch @@ -1,5 +1,5 @@ -From 80850486e791a69a4cd58851617f321b84f7c178 Mon Sep 17 00:00:00 2001 -Message-Id: <80850486e791a69a4cd58851617f321b84f7c178@dist-git> +From bab30af2d83e27d9141545cb9dcff51924e52b4d 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 diff --git a/SOURCES/libvirt-api-disallow-virConnectGetDomainCapabilities-on-read-only-connections.patch b/SOURCES/libvirt-api-disallow-virConnectGetDomainCapabilities-on-read-only-connections.patch index b04e5f4..6815a55 100644 --- a/SOURCES/libvirt-api-disallow-virConnectGetDomainCapabilities-on-read-only-connections.patch +++ b/SOURCES/libvirt-api-disallow-virConnectGetDomainCapabilities-on-read-only-connections.patch @@ -1,5 +1,5 @@ -From b77317482326f31c796e16bda24c1eb344be2d21 Mon Sep 17 00:00:00 2001 -Message-Id: +From 2b0e20b240848c84932aa549e8ec2b6e0a5646fa Mon Sep 17 00:00:00 2001 +Message-Id: <2b0e20b240848c84932aa549e8ec2b6e0a5646fa@dist-git> 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 diff --git a/SOURCES/libvirt-api-disallow-virDomainManagedSaveDefineXML-on-read-only-connections.patch b/SOURCES/libvirt-api-disallow-virDomainManagedSaveDefineXML-on-read-only-connections.patch index 461c8f6..c02b5b9 100644 --- a/SOURCES/libvirt-api-disallow-virDomainManagedSaveDefineXML-on-read-only-connections.patch +++ b/SOURCES/libvirt-api-disallow-virDomainManagedSaveDefineXML-on-read-only-connections.patch @@ -1,5 +1,5 @@ -From 2f8042cc71d65391e702c48f4e5e9dd38811cf4a Mon Sep 17 00:00:00 2001 -Message-Id: <2f8042cc71d65391e702c48f4e5e9dd38811cf4a@dist-git> +From 0673d5b707d68562732b78c89fe339e8558f8496 Mon Sep 17 00:00:00 2001 +Message-Id: <0673d5b707d68562732b78c89fe339e8558f8496@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 diff --git a/SOURCES/libvirt-api-disallow-virDomainSaveImageGetXMLDesc-on-read-only-connections.patch b/SOURCES/libvirt-api-disallow-virDomainSaveImageGetXMLDesc-on-read-only-connections.patch index f0ee792..f2ec040 100644 --- a/SOURCES/libvirt-api-disallow-virDomainSaveImageGetXMLDesc-on-read-only-connections.patch +++ b/SOURCES/libvirt-api-disallow-virDomainSaveImageGetXMLDesc-on-read-only-connections.patch @@ -1,5 +1,5 @@ -From d5b7ada5278e175d3174a6bcdc4338684ae4376e Mon Sep 17 00:00:00 2001 -Message-Id: +From 8533d820c378ae31176922703b7368f586a59bc0 Mon Sep 17 00:00:00 2001 +Message-Id: <8533d820c378ae31176922703b7368f586a59bc0@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 diff --git a/SOURCES/libvirt-bhyve-Move-autostarting-of-domains-into-bhyveStateInitialize.patch b/SOURCES/libvirt-bhyve-Move-autostarting-of-domains-into-bhyveStateInitialize.patch new file mode 100644 index 0000000..2f0f16b --- /dev/null +++ b/SOURCES/libvirt-bhyve-Move-autostarting-of-domains-into-bhyveStateInitialize.patch @@ -0,0 +1,65 @@ +From a26ad1b57617abc4de8a0d13716b898d311ee01e Mon Sep 17 00:00:00 2001 +Message-Id: +From: Michal Privoznik +Date: Thu, 27 Jun 2019 15:18:15 +0200 +Subject: [PATCH] bhyve: Move autostarting of domains into bhyveStateInitialize +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The stateAutoStart callback will go away shortly. Therefore, move +the autostart call into state initialize callback. + +Signed-off-by: Michal Privoznik +Reviewed-by: Ján Tomko +(cherry picked from commit 31c3c35c940010a793fea8351751bb04fab1a6d4) + +https://bugzilla.redhat.com/show_bug.cgi?id=1685151 + +Signed-off-by: Michal Privoznik +Message-Id: <1a93e2bef531c11190c652fcfb73b568ee73e487.1561641375.git.mprivozn@redhat.com> +Reviewed-by: Jiri Denemark +--- + src/bhyve/bhyve_driver.c | 12 ++---------- + 1 file changed, 2 insertions(+), 10 deletions(-) + +diff --git a/src/bhyve/bhyve_driver.c b/src/bhyve/bhyve_driver.c +index 9284b51783..ec016ecc0c 100644 +--- a/src/bhyve/bhyve_driver.c ++++ b/src/bhyve/bhyve_driver.c +@@ -1270,6 +1270,8 @@ bhyveStateInitialize(bool privileged, + + virBhyveProcessReconnectAll(bhyve_driver); + ++ bhyveAutostartDomains(bhyve_driver); ++ + return 0; + + cleanup: +@@ -1297,15 +1299,6 @@ bhyveDriverGetGrubCaps(virConnectPtr conn) + return 0; + } + +-static void +-bhyveStateAutoStart(void) +-{ +- if (!bhyve_driver) +- return; +- +- bhyveAutostartDomains(bhyve_driver); +-} +- + static int + bhyveConnectGetMaxVcpus(virConnectPtr conn, + const char *type) +@@ -1713,7 +1706,6 @@ static virConnectDriver bhyveConnectDriver = { + static virStateDriver bhyveStateDriver = { + .name = "bhyve", + .stateInitialize = bhyveStateInitialize, +- .stateAutoStart = bhyveStateAutoStart, + .stateCleanup = bhyveStateCleanup, + }; + +-- +2.22.0 + diff --git a/SOURCES/libvirt-conf-Add-definitions-for-uid-and-fid-PCI-address-attributes.patch b/SOURCES/libvirt-conf-Add-definitions-for-uid-and-fid-PCI-address-attributes.patch new file mode 100644 index 0000000..17eb235 --- /dev/null +++ b/SOURCES/libvirt-conf-Add-definitions-for-uid-and-fid-PCI-address-attributes.patch @@ -0,0 +1,67 @@ +From dd083516c7057ee50e59290643634156daf0773b Mon Sep 17 00:00:00 2001 +Message-Id: +From: Yi Min Zhao +Date: Mon, 8 Apr 2019 10:57:18 +0200 +Subject: [PATCH] conf: Add definitions for 'uid' and 'fid' PCI address + attributes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add zPCI definitions in preparation of extending the PCI address +with parameters uid (user-defined identifier) and fid (PCI function +identifier). + +Signed-off-by: Yi Min Zhao +Reviewed-by: Boris Fiuczynski +Reviewed-by: Stefan Zimmermann +Reviewed-by: Bjoern Walk +Reviewed-by: Ján Tomko +Reviewed-by: Andrea Bolognani + +(cherry-picked from commit 30522c78c11d9ff6c6c177dfca4a0da8057095fe) + +https://bugzilla.redhat.com/show_bug.cgi?id=1508149 + +Signed-off-by: Andrea Bolognani +Message-Id: <20190408085732.28684-2-abologna@redhat.com> +Reviewed-by: Laine Stump +Reviewed-by: Ján Tomko +--- + cfg.mk | 1 + + src/util/virpci.h | 7 +++++++ + 2 files changed, 8 insertions(+) + +diff --git a/cfg.mk b/cfg.mk +index e3e94bf6f0..7fd2b1dcb6 100644 +--- a/cfg.mk ++++ b/cfg.mk +@@ -472,6 +472,7 @@ sc_prohibit_canonicalize_file_name: + # Insist on correct types for [pug]id. + sc_correct_id_types: + @prohibit='\<(int|long) *[pug]id\>' \ ++ exclude='exempt from syntax-check' \ + halt='use pid_t for pid, uid_t for uid, gid_t for gid' \ + $(_sc_search_regexp) + +diff --git a/src/util/virpci.h b/src/util/virpci.h +index 794b7e59db..01df652b86 100644 +--- a/src/util/virpci.h ++++ b/src/util/virpci.h +@@ -36,6 +36,13 @@ typedef virPCIDeviceAddress *virPCIDeviceAddressPtr; + typedef struct _virPCIDeviceList virPCIDeviceList; + typedef virPCIDeviceList *virPCIDeviceListPtr; + ++typedef struct _virZPCIDeviceAddress virZPCIDeviceAddress; ++typedef virZPCIDeviceAddress *virZPCIDeviceAddressPtr; ++struct _virZPCIDeviceAddress { ++ unsigned int uid; /* exempt from syntax-check */ ++ unsigned int fid; ++}; ++ + struct _virPCIDeviceAddress { + unsigned int domain; + unsigned int bus; +-- +2.22.0 + diff --git a/SOURCES/libvirt-conf-Allocate-release-uid-and-fid-in-PCI-address.patch b/SOURCES/libvirt-conf-Allocate-release-uid-and-fid-in-PCI-address.patch new file mode 100644 index 0000000..d99def9 --- /dev/null +++ b/SOURCES/libvirt-conf-Allocate-release-uid-and-fid-in-PCI-address.patch @@ -0,0 +1,527 @@ +From 87e3a5f2f797c79516a560ddc224074c834ef528 Mon Sep 17 00:00:00 2001 +Message-Id: <87e3a5f2f797c79516a560ddc224074c834ef528@dist-git> +From: Yi Min Zhao +Date: Mon, 8 Apr 2019 10:57:27 +0200 +Subject: [PATCH] conf: Allocate/release 'uid' and 'fid' in PCI address +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This patch adds new functions for reservation, assignment and release +to handle the uid/fid. If the uid/fid is defined in the domain XML, +they will be reserved directly in the collecting phase. If any of them +is not defined, we will find out an available value for them from the +zPCI address hashtable, and reserve them. For the hotplug case there +might not be a zPCI definition. So allocate and reserve uid/fid the +case. Assign if needed and reserve uid/fid for the defined case. + +Signed-off-by: Yi Min Zhao +Reviewed-by: Bjoern Walk +Reviewed-by: Boris Fiuczynski +Reviewed-by: Andrea Bolognani + +(cherry picked from commit f183b87fc1dbcc6446ac3c1cef9cdd345b9725fb) + +https://bugzilla.redhat.com/show_bug.cgi?id=1508149 + +Conflicts: + + * src/libvirt_private.syms + + several symbols are not present in the list + - missing 9ad119f4db5, ab3f781a10c, edeef779585, b899726faa5 + + * src/qemu/qemu_domain_address.c + + the old name for virDeviceInfoPCIAddressIsPresent() is used + - missing 76151a53a100 + +Signed-off-by: Andrea Bolognani +Message-Id: <20190408085732.28684-11-abologna@redhat.com> +Reviewed-by: Laine Stump +Reviewed-by: Ján Tomko +--- + src/conf/device_conf.c | 16 +++ + src/conf/device_conf.h | 3 + + src/conf/domain_addr.c | 244 +++++++++++++++++++++++++++++++++ + src/conf/domain_addr.h | 12 ++ + src/libvirt_private.syms | 5 + + src/qemu/qemu_domain_address.c | 59 +++++++- + 6 files changed, 338 insertions(+), 1 deletion(-) + +diff --git a/src/conf/device_conf.c b/src/conf/device_conf.c +index cadac32603..76370d30a2 100644 +--- a/src/conf/device_conf.c ++++ b/src/conf/device_conf.c +@@ -28,6 +28,7 @@ + #include "viruuid.h" + #include "virbuffer.h" + #include "device_conf.h" ++#include "domain_addr.h" + #include "virstring.h" + + #define VIR_FROM_THIS VIR_FROM_DEVICE +@@ -230,6 +231,21 @@ int virPCIDeviceAddressIsValid(virPCIDeviceAddressPtr addr, + } + + ++bool ++virDeviceInfoPCIAddressExtensionIsWanted(const virDomainDeviceInfo *info) ++{ ++ return (info->addr.pci.extFlags & VIR_PCI_ADDRESS_EXTENSION_ZPCI) && ++ virZPCIDeviceAddressIsEmpty(&info->addr.pci.zpci); ++} ++ ++bool ++virDeviceInfoPCIAddressExtensionIsPresent(const virDomainDeviceInfo *info) ++{ ++ return (info->addr.pci.extFlags & VIR_PCI_ADDRESS_EXTENSION_ZPCI) && ++ !virZPCIDeviceAddressIsEmpty(&info->addr.pci.zpci); ++} ++ ++ + int + virPCIDeviceAddressParseXML(xmlNodePtr node, + virPCIDeviceAddressPtr addr) +diff --git a/src/conf/device_conf.h b/src/conf/device_conf.h +index c79066ec02..6bef2f093a 100644 +--- a/src/conf/device_conf.h ++++ b/src/conf/device_conf.h +@@ -214,6 +214,9 @@ virDeviceInfoPCIAddressPresent(const virDomainDeviceInfo *info) + !virPCIDeviceAddressIsEmpty(&info->addr.pci); + } + ++bool virDeviceInfoPCIAddressExtensionIsWanted(const virDomainDeviceInfo *info); ++bool virDeviceInfoPCIAddressExtensionIsPresent(const virDomainDeviceInfo *info); ++ + int virPCIDeviceAddressParseXML(xmlNodePtr node, + virPCIDeviceAddressPtr addr); + +diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c +index 9e0a0fdf95..a58910c394 100644 +--- a/src/conf/domain_addr.c ++++ b/src/conf/domain_addr.c +@@ -33,6 +33,238 @@ + + VIR_LOG_INIT("conf.domain_addr"); + ++static int ++virDomainZPCIAddressReserveId(virHashTablePtr set, ++ unsigned int id, ++ const char *name) ++{ ++ if (virHashLookup(set, &id)) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("zPCI %s %o is already reserved"), ++ name, id); ++ return -1; ++ } ++ ++ if (virHashAddEntry(set, &id, (void*)1) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Failed to reserve %s %o"), ++ name, id); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++ ++static int ++virDomainZPCIAddressReserveUid(virHashTablePtr set, ++ virZPCIDeviceAddressPtr addr) ++{ ++ return virDomainZPCIAddressReserveId(set, addr->uid, "uid"); ++} ++ ++ ++static int ++virDomainZPCIAddressReserveFid(virHashTablePtr set, ++ virZPCIDeviceAddressPtr addr) ++{ ++ return virDomainZPCIAddressReserveId(set, addr->fid, "fid"); ++} ++ ++ ++static int ++virDomainZPCIAddressAssignId(virHashTablePtr set, ++ unsigned int *id, ++ unsigned int min, ++ unsigned int max, ++ const char *name) ++{ ++ while (virHashLookup(set, &min)) { ++ if (min == max) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("There is no more free %s."), ++ name); ++ return -1; ++ } ++ ++min; ++ } ++ *id = min; ++ ++ return 0; ++} ++ ++ ++static int ++virDomainZPCIAddressAssignUid(virHashTablePtr set, ++ virZPCIDeviceAddressPtr addr) ++{ ++ return virDomainZPCIAddressAssignId(set, &addr->uid, 1, ++ VIR_DOMAIN_DEVICE_ZPCI_MAX_UID, "uid"); ++} ++ ++ ++static int ++virDomainZPCIAddressAssignFid(virHashTablePtr set, ++ virZPCIDeviceAddressPtr addr) ++{ ++ return virDomainZPCIAddressAssignId(set, &addr->fid, 0, ++ VIR_DOMAIN_DEVICE_ZPCI_MAX_FID, "fid"); ++} ++ ++ ++static void ++virDomainZPCIAddressReleaseId(virHashTablePtr set, ++ unsigned int *id, ++ const char *name) ++{ ++ if (virHashRemoveEntry(set, id) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Release %s %o failed"), ++ name, *id); ++ } ++ ++ *id = 0; ++} ++ ++ ++static void ++virDomainZPCIAddressReleaseUid(virHashTablePtr set, ++ virZPCIDeviceAddressPtr addr) ++{ ++ virDomainZPCIAddressReleaseId(set, &addr->uid, "uid"); ++} ++ ++ ++static void ++virDomainZPCIAddressReleaseFid(virHashTablePtr set, ++ virZPCIDeviceAddressPtr addr) ++{ ++ virDomainZPCIAddressReleaseId(set, &addr->fid, "fid"); ++} ++ ++ ++static void ++virDomainZPCIAddressReleaseIds(virDomainZPCIAddressIdsPtr zpciIds, ++ virZPCIDeviceAddressPtr addr) ++{ ++ if (!zpciIds || virZPCIDeviceAddressIsEmpty(addr)) ++ return; ++ ++ virDomainZPCIAddressReleaseUid(zpciIds->uids, addr); ++ ++ virDomainZPCIAddressReleaseFid(zpciIds->fids, addr); ++} ++ ++ ++static int ++virDomainZPCIAddressReserveNextUid(virHashTablePtr uids, ++ virZPCIDeviceAddressPtr zpci) ++{ ++ if (virDomainZPCIAddressAssignUid(uids, zpci) < 0) ++ return -1; ++ ++ if (virDomainZPCIAddressReserveUid(uids, zpci) < 0) ++ return -1; ++ ++ return 0; ++} ++ ++ ++static int ++virDomainZPCIAddressReserveNextFid(virHashTablePtr fids, ++ virZPCIDeviceAddressPtr zpci) ++{ ++ if (virDomainZPCIAddressAssignFid(fids, zpci) < 0) ++ return -1; ++ ++ if (virDomainZPCIAddressReserveFid(fids, zpci) < 0) ++ return -1; ++ ++ return 0; ++} ++ ++ ++static int ++virDomainZPCIAddressReserveAddr(virDomainZPCIAddressIdsPtr zpciIds, ++ virZPCIDeviceAddressPtr addr) ++{ ++ if (virDomainZPCIAddressReserveUid(zpciIds->uids, addr) < 0) ++ return -1; ++ ++ if (virDomainZPCIAddressReserveFid(zpciIds->fids, addr) < 0) { ++ virDomainZPCIAddressReleaseUid(zpciIds->uids, addr); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++ ++static int ++virDomainZPCIAddressReserveNextAddr(virDomainZPCIAddressIdsPtr zpciIds, ++ virZPCIDeviceAddressPtr addr) ++{ ++ if (virDomainZPCIAddressReserveNextUid(zpciIds->uids, addr) < 0) ++ return -1; ++ ++ if (virDomainZPCIAddressReserveNextFid(zpciIds->fids, addr) < 0) { ++ virDomainZPCIAddressReleaseUid(zpciIds->uids, addr); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++ ++int ++virDomainPCIAddressExtensionReserveAddr(virDomainPCIAddressSetPtr addrs, ++ virPCIDeviceAddressPtr addr) ++{ ++ if (addr->extFlags & VIR_PCI_ADDRESS_EXTENSION_ZPCI) { ++ /* Reserve uid/fid to ZPCI device which has defined uid/fid ++ * in the domain. ++ */ ++ return virDomainZPCIAddressReserveAddr(addrs->zpciIds, &addr->zpci); ++ } ++ ++ return 0; ++} ++ ++ ++int ++virDomainPCIAddressExtensionReserveNextAddr(virDomainPCIAddressSetPtr addrs, ++ virPCIDeviceAddressPtr addr) ++{ ++ if (addr->extFlags & VIR_PCI_ADDRESS_EXTENSION_ZPCI) { ++ virZPCIDeviceAddress zpci = { 0 }; ++ ++ if (virDomainZPCIAddressReserveNextAddr(addrs->zpciIds, &zpci) < 0) ++ return -1; ++ ++ if (!addrs->dryRun) ++ addr->zpci = zpci; ++ } ++ ++ return 0; ++} ++ ++static int ++virDomainPCIAddressExtensionEnsureAddr(virDomainPCIAddressSetPtr addrs, ++ virPCIDeviceAddressPtr addr) ++{ ++ if (addr->extFlags & VIR_PCI_ADDRESS_EXTENSION_ZPCI) { ++ virZPCIDeviceAddressPtr zpci = &addr->zpci; ++ ++ if (virZPCIDeviceAddressIsEmpty(zpci)) ++ return virDomainZPCIAddressReserveNextAddr(addrs->zpciIds, zpci); ++ else ++ return virDomainZPCIAddressReserveAddr(addrs->zpciIds, zpci); ++ } ++ ++ return 0; ++} ++ ++ + virDomainPCIConnectFlags + virDomainPCIControllerModelToConnectType(virDomainControllerModelPCI model) + { +@@ -729,12 +961,24 @@ virDomainPCIAddressEnsureAddr(virDomainPCIAddressSetPtr addrs, + ret = virDomainPCIAddressReserveNextAddr(addrs, dev, flags, -1); + } + ++ dev->addr.pci.extFlags = dev->pciAddrExtFlags; ++ ret = virDomainPCIAddressExtensionEnsureAddr(addrs, &dev->addr.pci); ++ + cleanup: + VIR_FREE(addrStr); + return ret; + } + + ++void ++virDomainPCIAddressExtensionReleaseAddr(virDomainPCIAddressSetPtr addrs, ++ virPCIDeviceAddressPtr addr) ++{ ++ if (addr->extFlags & VIR_PCI_ADDRESS_EXTENSION_ZPCI) ++ virDomainZPCIAddressReleaseIds(addrs->zpciIds, &addr->zpci); ++} ++ ++ + void + virDomainPCIAddressReleaseAddr(virDomainPCIAddressSetPtr addrs, + virPCIDeviceAddressPtr addr) +diff --git a/src/conf/domain_addr.h b/src/conf/domain_addr.h +index b01e6b9d20..e5ce4868d5 100644 +--- a/src/conf/domain_addr.h ++++ b/src/conf/domain_addr.h +@@ -166,6 +166,14 @@ bool virDomainPCIAddressSlotInUse(virDomainPCIAddressSetPtr addrs, + virPCIDeviceAddressPtr addr) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + ++int virDomainPCIAddressExtensionReserveAddr(virDomainPCIAddressSetPtr addrs, ++ virPCIDeviceAddressPtr addr) ++ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); ++ ++int virDomainPCIAddressExtensionReserveNextAddr(virDomainPCIAddressSetPtr addrs, ++ virPCIDeviceAddressPtr addr) ++ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); ++ + int virDomainPCIAddressReserveAddr(virDomainPCIAddressSetPtr addrs, + virPCIDeviceAddressPtr addr, + virDomainPCIConnectFlags flags, +@@ -187,6 +195,10 @@ void virDomainPCIAddressReleaseAddr(virDomainPCIAddressSetPtr addrs, + virPCIDeviceAddressPtr addr) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + ++void virDomainPCIAddressExtensionReleaseAddr(virDomainPCIAddressSetPtr addrs, ++ virPCIDeviceAddressPtr addr) ++ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); ++ + void virDomainPCIAddressSetAllMulti(virDomainDefPtr def) + ATTRIBUTE_NONNULL(1); + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index b2a2a1f265..ee7625b0f3 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -93,6 +93,8 @@ virCPUModeTypeToString; + + + # conf/device_conf.h ++virDeviceInfoPCIAddressExtensionIsPresent; ++virDeviceInfoPCIAddressExtensionIsWanted; + virDomainDeviceInfoAddressIsEqual; + virDomainDeviceInfoCopy; + virInterfaceLinkFormat; +@@ -114,6 +116,9 @@ virDomainPCIAddressAsString; + virDomainPCIAddressBusIsFullyReserved; + virDomainPCIAddressBusSetModel; + virDomainPCIAddressEnsureAddr; ++virDomainPCIAddressExtensionReleaseAddr; ++virDomainPCIAddressExtensionReserveAddr; ++virDomainPCIAddressExtensionReserveNextAddr; + virDomainPCIAddressReleaseAddr; + virDomainPCIAddressReserveAddr; + virDomainPCIAddressReserveNextAddr; +diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c +index ba870d56b1..8338241cba 100644 +--- a/src/qemu/qemu_domain_address.c ++++ b/src/qemu/qemu_domain_address.c +@@ -1405,6 +1405,24 @@ qemuDomainPCIAddressReserveNextAddr(virDomainPCIAddressSetPtr addrs, + } + + ++static int ++qemuDomainAssignPCIAddressExtension(virDomainDefPtr def ATTRIBUTE_UNUSED, ++ virDomainDeviceDefPtr device ATTRIBUTE_UNUSED, ++ virDomainDeviceInfoPtr info, ++ void *opaque) ++{ ++ virDomainPCIAddressSetPtr addrs = opaque; ++ virPCIDeviceAddressPtr addr = &info->addr.pci; ++ ++ if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) ++ addr->extFlags = info->pciAddrExtFlags; ++ ++ if (virDeviceInfoPCIAddressExtensionIsWanted(info)) ++ return virDomainPCIAddressExtensionReserveNextAddr(addrs, addr); ++ ++ return 0; ++} ++ + static int + qemuDomainCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED, + virDomainDeviceDefPtr device, +@@ -1498,6 +1516,31 @@ qemuDomainCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED, + return ret; + } + ++static int ++qemuDomainCollectPCIAddressExtension(virDomainDefPtr def ATTRIBUTE_UNUSED, ++ virDomainDeviceDefPtr device, ++ virDomainDeviceInfoPtr info, ++ void *opaque) ++{ ++ virDomainPCIAddressSetPtr addrs = opaque; ++ virPCIDeviceAddressPtr addr = &info->addr.pci; ++ ++ if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) ++ addr->extFlags = info->pciAddrExtFlags; ++ ++ if (!virDeviceInfoPCIAddressExtensionIsPresent(info) || ++ ((device->type == VIR_DOMAIN_DEVICE_HOSTDEV) && ++ (device->data.hostdev->parent.type != VIR_DOMAIN_DEVICE_NONE))) { ++ /* If a hostdev has a parent, its info will be a part of the ++ * parent, and will have its address collected during the scan ++ * of the parent's device type. ++ */ ++ return 0; ++ } ++ ++ return virDomainPCIAddressExtensionReserveAddr(addrs, addr); ++} ++ + static virDomainPCIAddressSetPtr + qemuDomainPCIAddressSetCreate(virDomainDefPtr def, + virQEMUCapsPtr qemuCaps, +@@ -1589,6 +1632,12 @@ qemuDomainPCIAddressSetCreate(virDomainDefPtr def, + if (virDomainDeviceInfoIterate(def, qemuDomainCollectPCIAddress, addrs) < 0) + goto error; + ++ if (virDomainDeviceInfoIterate(def, ++ qemuDomainCollectPCIAddressExtension, ++ addrs) < 0) { ++ goto error; ++ } ++ + return addrs; + + error: +@@ -2590,6 +2639,9 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def, + if (qemuDomainAssignDevicePCISlots(def, qemuCaps, addrs) < 0) + goto cleanup; + ++ if (virDomainDeviceInfoIterate(def, qemuDomainAssignPCIAddressExtension, addrs) < 0) ++ goto cleanup; ++ + /* Only for *new* domains with pcie-root (and no other + * manually specified PCI controllers in the definition): If, + * after assigning addresses/reserving slots for all devices, +@@ -2684,6 +2736,9 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def, + if (qemuDomainAssignDevicePCISlots(def, qemuCaps, addrs) < 0) + goto cleanup; + ++ if (virDomainDeviceInfoIterate(def, qemuDomainAssignPCIAddressExtension, addrs) < 0) ++ goto cleanup; ++ + /* set multi attribute for devices at function 0 of + * any slot that has multiple functions in use + */ +@@ -3143,8 +3198,10 @@ qemuDomainReleaseDeviceAddress(virDomainObjPtr vm, + if (!devstr) + devstr = info->alias; + +- if (virDeviceInfoPCIAddressPresent(info)) ++ if (virDeviceInfoPCIAddressPresent(info)) { + virDomainPCIAddressReleaseAddr(priv->pciaddrs, &info->addr.pci); ++ virDomainPCIAddressExtensionReleaseAddr(priv->pciaddrs, &info->addr.pci); ++ } + + if (virDomainUSBAddressRelease(priv->usbaddrs, info) < 0) + VIR_WARN("Unable to release USB address on %s", NULLSTR(devstr)); +-- +2.22.0 + diff --git a/SOURCES/libvirt-conf-Expose-virDomainSCSIDriveAddressIsUsed.patch b/SOURCES/libvirt-conf-Expose-virDomainSCSIDriveAddressIsUsed.patch new file mode 100644 index 0000000..9d79b6a --- /dev/null +++ b/SOURCES/libvirt-conf-Expose-virDomainSCSIDriveAddressIsUsed.patch @@ -0,0 +1,69 @@ +From 2e3774564235a185a2cc4b7a22c17de17498db68 Mon Sep 17 00:00:00 2001 +Message-Id: <2e3774564235a185a2cc4b7a22c17de17498db68@dist-git> +From: Michal Privoznik +Date: Thu, 18 Apr 2019 19:36:31 +0200 +Subject: [PATCH] conf: Expose virDomainSCSIDriveAddressIsUsed + +RHEl-7.7: https://bugzilla.redhat.com/show_bug.cgi?id=1692296 +RHEL-8.1.0: https://bugzilla.redhat.com/show_bug.cgi?id=1692354 + +This function checks if given drive address is already present in +passed domain definition. Expose the function as it will be used +shortly. + +Signed-off-by: Michal Privoznik +Tested-by: Daniel Henrique Barboza +Reviewed-by: Jim Fehlig +(cherry picked from commit 89237d534f0fe950d06a2081089154160c6c2224) +Signed-off-by: Michal Privoznik +Message-Id: +Reviewed-by: Jiri Denemark +--- + src/conf/domain_conf.c | 2 +- + src/conf/domain_conf.h | 4 ++++ + src/libvirt_private.syms | 1 + + 3 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index d431441f62..e62f78471c 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -4404,7 +4404,7 @@ virDomainDriveAddressIsUsedByHostdev(const virDomainDef *def, + * Return true if the SCSI drive address is already in use, false + * otherwise. + */ +-static bool ++bool + virDomainSCSIDriveAddressIsUsed(const virDomainDef *def, + const virDomainDeviceDriveAddress *addr) + { +diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h +index f05fca284f..dbccf2cf24 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -2789,6 +2789,10 @@ virDomainXMLNamespacePtr + virDomainXMLOptionGetNamespace(virDomainXMLOptionPtr xmlopt) + ATTRIBUTE_NONNULL(1); + ++bool ++virDomainSCSIDriveAddressIsUsed(const virDomainDef *def, ++ const virDomainDeviceDriveAddress *addr); ++ + int virDomainDefPostParse(virDomainDefPtr def, + virCapsPtr caps, + unsigned int parseFlags, +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 624151056a..df27ac4b3a 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -520,6 +520,7 @@ virDomainRunningReasonTypeToString; + virDomainSaveConfig; + virDomainSaveStatus; + virDomainSaveXML; ++virDomainSCSIDriveAddressIsUsed; + virDomainSeclabelTypeFromString; + virDomainSeclabelTypeToString; + virDomainShmemDefEquals; +-- +2.21.0 + diff --git a/SOURCES/libvirt-conf-Introduce-address-caching-for-PCI-extensions.patch b/SOURCES/libvirt-conf-Introduce-address-caching-for-PCI-extensions.patch new file mode 100644 index 0000000..a186a21 --- /dev/null +++ b/SOURCES/libvirt-conf-Introduce-address-caching-for-PCI-extensions.patch @@ -0,0 +1,241 @@ +From 7888472ef1d57d992995a16dc7c9ba0fe18562a8 Mon Sep 17 00:00:00 2001 +Message-Id: <7888472ef1d57d992995a16dc7c9ba0fe18562a8@dist-git> +From: Yi Min Zhao +Date: Mon, 8 Apr 2019 10:57:22 +0200 +Subject: [PATCH] conf: Introduce address caching for PCI extensions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This patch provides a caching mechanism for the device address +extensions uid and fid on S390. For efficient sparse address allocation, +we introduce two hash tables for uid/fid which hold the address set +information per domain. Also in order to improve performance of +searching available value, we introduce our own callbacks for the two +hashtables. In this way, uid/fid is saved in hash key and hash value +could be any non-NULL pointer due to no operation on hash value. That is +also the reason why we don't introduce hash value free callback. + +Signed-off-by: Yi Min Zhao +Reviewed-by: Boris Fiuczynski +Reviewed-by: Bjoern Walk +Reviewed-by: Ján Tomko +Reviewed-by: Andrea Bolognani + +(cherry picked from commit 28831e1f1ec001882e907f03f7618f7c00ebc98d) + +https://bugzilla.redhat.com/show_bug.cgi?id=1508149 + +Conflicts: + + * src/conf/domain_addr.h + + context + - missing b72183223f3b + +Signed-off-by: Andrea Bolognani +Message-Id: <20190408085732.28684-6-abologna@redhat.com> +Reviewed-by: Laine Stump +Reviewed-by: Ján Tomko +--- + src/bhyve/bhyve_device.c | 3 +- + src/conf/domain_addr.c | 93 +++++++++++++++++++++++++++++++++- + src/conf/domain_addr.h | 10 +++- + src/qemu/qemu_domain_address.c | 6 ++- + 4 files changed, 108 insertions(+), 4 deletions(-) + +diff --git a/src/bhyve/bhyve_device.c b/src/bhyve/bhyve_device.c +index 03aa6c93bd..8f0862b0b6 100644 +--- a/src/bhyve/bhyve_device.c ++++ b/src/bhyve/bhyve_device.c +@@ -71,7 +71,8 @@ bhyveDomainPCIAddressSetCreate(virDomainDefPtr def, unsigned int nbuses) + { + virDomainPCIAddressSetPtr addrs; + +- if ((addrs = virDomainPCIAddressSetAlloc(nbuses)) == NULL) ++ if ((addrs = virDomainPCIAddressSetAlloc(nbuses, ++ VIR_PCI_ADDRESS_EXTENSION_NONE)) == NULL) + return NULL; + + if (virDomainPCIAddressBusSetModel(&addrs->buses[0], +diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c +index 39f22b82eb..3e33549c3d 100644 +--- a/src/conf/domain_addr.c ++++ b/src/conf/domain_addr.c +@@ -27,6 +27,7 @@ + #include "virlog.h" + #include "virstring.h" + #include "domain_addr.h" ++#include "virhashcode.h" + + #define VIR_FROM_THIS VIR_FROM_DOMAIN + +@@ -741,8 +742,93 @@ virDomainPCIAddressReleaseAddr(virDomainPCIAddressSetPtr addrs, + addrs->buses[addr->bus].slot[addr->slot].functions &= ~(1 << addr->function); + } + ++ ++static uint32_t ++virZPCIAddrKeyCode(const void *name, ++ uint32_t seed) ++{ ++ unsigned int value = *((unsigned int *)name); ++ return virHashCodeGen(&value, sizeof(value), seed); ++} ++ ++ ++static bool ++virZPCIAddrKeyEqual(const void *namea, ++ const void *nameb) ++{ ++ return *((unsigned int *)namea) == *((unsigned int *)nameb); ++} ++ ++ ++static void * ++virZPCIAddrKeyCopy(const void *name) ++{ ++ unsigned int *copy; ++ ++ if (VIR_ALLOC(copy) < 0) ++ return NULL; ++ ++ *copy = *((unsigned int *)name); ++ return (void *)copy; ++} ++ ++ ++static void ++virZPCIAddrKeyFree(void *name) ++{ ++ VIR_FREE(name); ++} ++ ++ ++static void ++virDomainPCIAddressSetExtensionFree(virDomainPCIAddressSetPtr addrs) ++{ ++ if (!addrs || !addrs->zpciIds) ++ return; ++ ++ virHashFree(addrs->zpciIds->uids); ++ virHashFree(addrs->zpciIds->fids); ++ VIR_FREE(addrs->zpciIds); ++} ++ ++ ++static int ++virDomainPCIAddressSetExtensionAlloc(virDomainPCIAddressSetPtr addrs, ++ virPCIDeviceAddressExtensionFlags extFlags) ++{ ++ if (extFlags & VIR_PCI_ADDRESS_EXTENSION_ZPCI) { ++ if (addrs->zpciIds) ++ return 0; ++ ++ if (VIR_ALLOC(addrs->zpciIds) < 0) ++ return -1; ++ ++ if (!(addrs->zpciIds->uids = virHashCreateFull(10, NULL, ++ virZPCIAddrKeyCode, ++ virZPCIAddrKeyEqual, ++ virZPCIAddrKeyCopy, ++ virZPCIAddrKeyFree))) ++ goto error; ++ ++ if (!(addrs->zpciIds->fids = virHashCreateFull(10, NULL, ++ virZPCIAddrKeyCode, ++ virZPCIAddrKeyEqual, ++ virZPCIAddrKeyCopy, ++ virZPCIAddrKeyFree))) ++ goto error; ++ } ++ ++ return 0; ++ ++ error: ++ virDomainPCIAddressSetExtensionFree(addrs); ++ return -1; ++} ++ ++ + virDomainPCIAddressSetPtr +-virDomainPCIAddressSetAlloc(unsigned int nbuses) ++virDomainPCIAddressSetAlloc(unsigned int nbuses, ++ virPCIDeviceAddressExtensionFlags extFlags) + { + virDomainPCIAddressSetPtr addrs; + +@@ -753,6 +839,10 @@ virDomainPCIAddressSetAlloc(unsigned int nbuses) + goto error; + + addrs->nbuses = nbuses; ++ ++ if (virDomainPCIAddressSetExtensionAlloc(addrs, extFlags) < 0) ++ goto error; ++ + return addrs; + + error: +@@ -767,6 +857,7 @@ virDomainPCIAddressSetFree(virDomainPCIAddressSetPtr addrs) + if (!addrs) + return; + ++ virDomainPCIAddressSetExtensionFree(addrs); + VIR_FREE(addrs->buses); + VIR_FREE(addrs); + } +diff --git a/src/conf/domain_addr.h b/src/conf/domain_addr.h +index fd06008e26..b01e6b9d20 100644 +--- a/src/conf/domain_addr.h ++++ b/src/conf/domain_addr.h +@@ -116,6 +116,12 @@ typedef struct { + } virDomainPCIAddressBus; + typedef virDomainPCIAddressBus *virDomainPCIAddressBusPtr; + ++typedef struct { ++ virHashTablePtr uids; ++ virHashTablePtr fids; ++} virDomainZPCIAddressIds; ++typedef virDomainZPCIAddressIds *virDomainZPCIAddressIdsPtr; ++ + struct _virDomainPCIAddressSet { + virDomainPCIAddressBus *buses; + size_t nbuses; +@@ -125,6 +131,7 @@ struct _virDomainPCIAddressSet { + bool areMultipleRootsSupported; + /* If true, the guest can use the pcie-to-pci-bridge controller */ + bool isPCIeToPCIBridgeSupported; ++ virDomainZPCIAddressIdsPtr zpciIds; + }; + typedef struct _virDomainPCIAddressSet virDomainPCIAddressSet; + typedef virDomainPCIAddressSet *virDomainPCIAddressSetPtr; +@@ -132,7 +139,8 @@ typedef virDomainPCIAddressSet *virDomainPCIAddressSetPtr; + char *virDomainPCIAddressAsString(virPCIDeviceAddressPtr addr) + ATTRIBUTE_NONNULL(1); + +-virDomainPCIAddressSetPtr virDomainPCIAddressSetAlloc(unsigned int nbuses); ++virDomainPCIAddressSetPtr virDomainPCIAddressSetAlloc(unsigned int nbuses, ++ virPCIDeviceAddressExtensionFlags extFlags); + + void virDomainPCIAddressSetFree(virDomainPCIAddressSetPtr addrs); + +diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c +index 3d01d14b46..ba870d56b1 100644 +--- a/src/qemu/qemu_domain_address.c ++++ b/src/qemu/qemu_domain_address.c +@@ -1508,8 +1508,12 @@ qemuDomainPCIAddressSetCreate(virDomainDefPtr def, + size_t i; + bool hasPCIeRoot = false; + virDomainControllerModelPCI defaultModel; ++ virPCIDeviceAddressExtensionFlags extFlags = VIR_PCI_ADDRESS_EXTENSION_NONE; + +- if ((addrs = virDomainPCIAddressSetAlloc(nbuses)) == NULL) ++ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_ZPCI)) ++ extFlags |= VIR_PCI_ADDRESS_EXTENSION_ZPCI; ++ ++ if ((addrs = virDomainPCIAddressSetAlloc(nbuses, extFlags)) == NULL) + return NULL; + + addrs->dryRun = dryRun; +-- +2.22.0 + diff --git a/SOURCES/libvirt-conf-Introduce-extension-flag-and-zPCI-member-for-PCI-address.patch b/SOURCES/libvirt-conf-Introduce-extension-flag-and-zPCI-member-for-PCI-address.patch new file mode 100644 index 0000000..3093f57 --- /dev/null +++ b/SOURCES/libvirt-conf-Introduce-extension-flag-and-zPCI-member-for-PCI-address.patch @@ -0,0 +1,283 @@ +From 050eb598af9291f385998cb1127d5bdf83305501 Mon Sep 17 00:00:00 2001 +Message-Id: <050eb598af9291f385998cb1127d5bdf83305501@dist-git> +From: Yi Min Zhao +Date: Mon, 8 Apr 2019 10:57:21 +0200 +Subject: [PATCH] conf: Introduce extension flag and zPCI member for PCI + address +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This patch introduces PCI address extension flag for virDomainDeviceInfo +and virPCIDeviceAddress. The extension flag in virDomainDeviceInfo is +used internally during calculating PCI extension flag. The one in +virPCIDeviceAddress is the duplicate to indicate extension address is +being used. Currently only zPCI extension address is introduced to deal +with 'uid' and 'fid' on the S390 platform. + +Signed-off-by: Yi Min Zhao +Reviewed-by: Boris Fiuczynski +Reviewed-by: Ján Tomko +Reviewed-by: Andrea Bolognani + +(cherry picked from commit 478e5f90fd4c0c0a8c1b3a8e19b9cae93ed78a4e) + +https://bugzilla.redhat.com/show_bug.cgi?id=1508149 + +Conflicts: + + * src/qemu/qemu_domain_address.c + + context + - missing db98a426a640 + +Signed-off-by: Andrea Bolognani +Message-Id: <20190408085732.28684-5-abologna@redhat.com> +Reviewed-by: Laine Stump +Reviewed-by: Ján Tomko +--- + src/conf/device_conf.h | 4 + + src/conf/domain_addr.h | 5 ++ + src/qemu/qemu_domain_address.c | 140 ++++++++++++++++++++++++++++++++- + src/util/virpci.h | 2 + + 4 files changed, 149 insertions(+), 2 deletions(-) + +diff --git a/src/conf/device_conf.h b/src/conf/device_conf.h +index a31ce9c376..c79066ec02 100644 +--- a/src/conf/device_conf.h ++++ b/src/conf/device_conf.h +@@ -164,6 +164,10 @@ struct _virDomainDeviceInfo { + * assignment, never saved and never reported. + */ + int pciConnectFlags; /* enum virDomainPCIConnectFlags */ ++ /* pciAddrExtFlags is only used internally to calculate PCI ++ * address extension flags during address assignment. ++ */ ++ int pciAddrExtFlags; /* enum virDomainPCIAddressExtensionFlags */ + char *loadparm; + + /* PCI devices will only be automatically placed on a PCI bus +diff --git a/src/conf/domain_addr.h b/src/conf/domain_addr.h +index 3236b7d6de..fd06008e26 100644 +--- a/src/conf/domain_addr.h ++++ b/src/conf/domain_addr.h +@@ -29,6 +29,11 @@ + # define VIR_PCI_ADDRESS_SLOT_LAST 31 + # define VIR_PCI_ADDRESS_FUNCTION_LAST 7 + ++typedef enum { ++ VIR_PCI_ADDRESS_EXTENSION_NONE = 0, /* no extension */ ++ VIR_PCI_ADDRESS_EXTENSION_ZPCI = 1 << 0, /* zPCI support */ ++} virPCIDeviceAddressExtensionFlags; ++ + typedef enum { + VIR_PCI_CONNECT_HOTPLUGGABLE = 1 << 0, /* is hotplug needed/supported */ + +diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c +index 79d2b9f9c4..3d01d14b46 100644 +--- a/src/qemu/qemu_domain_address.c ++++ b/src/qemu/qemu_domain_address.c +@@ -511,6 +511,64 @@ qemuDomainAssignARMVirtioMMIOAddresses(virDomainDefPtr def, + } + + ++static bool ++qemuDomainDeviceSupportZPCI(virDomainDeviceDefPtr device) ++{ ++ switch ((virDomainDeviceType)device->type) { ++ case VIR_DOMAIN_DEVICE_CHR: ++ return false; ++ ++ case VIR_DOMAIN_DEVICE_CONTROLLER: ++ case VIR_DOMAIN_DEVICE_DISK: ++ case VIR_DOMAIN_DEVICE_LEASE: ++ case VIR_DOMAIN_DEVICE_FS: ++ case VIR_DOMAIN_DEVICE_NET: ++ case VIR_DOMAIN_DEVICE_INPUT: ++ case VIR_DOMAIN_DEVICE_SOUND: ++ case VIR_DOMAIN_DEVICE_VIDEO: ++ case VIR_DOMAIN_DEVICE_HOSTDEV: ++ case VIR_DOMAIN_DEVICE_WATCHDOG: ++ case VIR_DOMAIN_DEVICE_GRAPHICS: ++ case VIR_DOMAIN_DEVICE_HUB: ++ case VIR_DOMAIN_DEVICE_REDIRDEV: ++ case VIR_DOMAIN_DEVICE_SMARTCARD: ++ case VIR_DOMAIN_DEVICE_MEMBALLOON: ++ case VIR_DOMAIN_DEVICE_NVRAM: ++ case VIR_DOMAIN_DEVICE_RNG: ++ case VIR_DOMAIN_DEVICE_SHMEM: ++ case VIR_DOMAIN_DEVICE_TPM: ++ case VIR_DOMAIN_DEVICE_PANIC: ++ case VIR_DOMAIN_DEVICE_MEMORY: ++ case VIR_DOMAIN_DEVICE_IOMMU: ++ case VIR_DOMAIN_DEVICE_VSOCK: ++ break; ++ ++ case VIR_DOMAIN_DEVICE_NONE: ++ case VIR_DOMAIN_DEVICE_LAST: ++ default: ++ virReportEnumRangeError(virDomainDeviceType, device->type); ++ return false; ++ } ++ ++ return true; ++} ++ ++ ++static virPCIDeviceAddressExtensionFlags ++qemuDomainDeviceCalculatePCIAddressExtensionFlags(virQEMUCapsPtr qemuCaps, ++ virDomainDeviceDefPtr dev) ++{ ++ virPCIDeviceAddressExtensionFlags extFlags = 0; ++ ++ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_ZPCI) && ++ qemuDomainDeviceSupportZPCI(dev)) { ++ extFlags |= VIR_PCI_ADDRESS_EXTENSION_ZPCI; ++ } ++ ++ return extFlags; ++} ++ ++ + /** + * qemuDomainDeviceCalculatePCIConnectFlags: + * +@@ -993,6 +1051,56 @@ qemuDomainFillAllPCIConnectFlags(virDomainDefPtr def, + } + + ++/** ++ * qemuDomainFillDevicePCIExtensionFlagsIter: ++ * ++ * @def: the entire DomainDef ++ * @dev: The device to be checked ++ * @info: virDomainDeviceInfo within the device ++ * @opaque: qemu capabilities ++ * ++ * Sets the pciAddressExtFlags for a single device's info. Has properly ++ * formatted arguments to be called by virDomainDeviceInfoIterate(). ++ * ++ * Always returns 0 - there is no failure. ++ */ ++static int ++qemuDomainFillDevicePCIExtensionFlagsIter(virDomainDefPtr def ATTRIBUTE_UNUSED, ++ virDomainDeviceDefPtr dev, ++ virDomainDeviceInfoPtr info, ++ void *opaque) ++{ ++ virQEMUCapsPtr qemuCaps = opaque; ++ ++ info->pciAddrExtFlags = ++ qemuDomainDeviceCalculatePCIAddressExtensionFlags(qemuCaps, dev); ++ ++ return 0; ++} ++ ++ ++/** ++ * qemuDomainFillAllPCIExtensionFlags: ++ * ++ * @def: the entire DomainDef ++ * @qemuCaps: as you'd expect ++ * ++ * Set the info->pciAddressExtFlags for all devices in the domain. ++ * ++ * Returns 0 on success or -1 on failure (the only possibility of ++ * failure would be some internal problem with ++ * virDomainDeviceInfoIterate()) ++ */ ++static int ++qemuDomainFillAllPCIExtensionFlags(virDomainDefPtr def, ++ virQEMUCapsPtr qemuCaps) ++{ ++ return virDomainDeviceInfoIterate(def, ++ qemuDomainFillDevicePCIExtensionFlagsIter, ++ qemuCaps); ++} ++ ++ + /** + * qemuDomainFindUnusedIsolationGroupIter: + * @def: domain definition +@@ -1267,6 +1375,27 @@ qemuDomainFillDevicePCIConnectFlags(virDomainDefPtr def, + } + + ++/** ++ * qemuDomainFillDevicePCIExtensionFlags: ++ * ++ * @dev: The device to be checked ++ * @info: virDomainDeviceInfo within the device ++ * @qemuCaps: as you'd expect ++ * ++ * Set the info->pciAddressExtFlags for a single device. ++ * ++ * No return value. ++ */ ++static void ++qemuDomainFillDevicePCIExtensionFlags(virDomainDeviceDefPtr dev, ++ virDomainDeviceInfoPtr info, ++ virQEMUCapsPtr qemuCaps) ++{ ++ info->pciAddrExtFlags = ++ qemuDomainDeviceCalculatePCIAddressExtensionFlags(qemuCaps, dev); ++} ++ ++ + static int + qemuDomainPCIAddressReserveNextAddr(virDomainPCIAddressSetPtr addrs, + virDomainDeviceInfoPtr dev) +@@ -2400,6 +2529,9 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def, + if (qemuDomainFillAllPCIConnectFlags(def, qemuCaps, driver) < 0) + goto cleanup; + ++ if (qemuDomainFillAllPCIExtensionFlags(def, qemuCaps) < 0) ++ goto cleanup; ++ + if (qemuDomainSetupIsolationGroups(def) < 0) + goto cleanup; + +@@ -2435,7 +2567,8 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def, + */ + virDomainDeviceInfo info = { + .pciConnectFlags = (VIR_PCI_CONNECT_HOTPLUGGABLE | +- VIR_PCI_CONNECT_TYPE_PCI_DEVICE) ++ VIR_PCI_CONNECT_TYPE_PCI_DEVICE), ++ .pciAddrExtFlags = VIR_PCI_ADDRESS_EXTENSION_NONE + }; + bool buses_reserved = true; + +@@ -2472,7 +2605,8 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def, + qemuDomainHasPCIeRoot(def)) { + virDomainDeviceInfo info = { + .pciConnectFlags = (VIR_PCI_CONNECT_HOTPLUGGABLE | +- VIR_PCI_CONNECT_TYPE_PCIE_DEVICE) ++ VIR_PCI_CONNECT_TYPE_PCIE_DEVICE), ++ .pciAddrExtFlags = VIR_PCI_ADDRESS_EXTENSION_NONE + }; + + /* if there isn't an empty pcie-root-port, this will +@@ -2989,6 +3123,8 @@ qemuDomainEnsurePCIAddress(virDomainObjPtr obj, + + qemuDomainFillDevicePCIConnectFlags(obj->def, dev, priv->qemuCaps, driver); + ++ qemuDomainFillDevicePCIExtensionFlags(dev, info, priv->qemuCaps); ++ + return virDomainPCIAddressEnsureAddr(priv->pciaddrs, info, + info->pciConnectFlags); + } +diff --git a/src/util/virpci.h b/src/util/virpci.h +index 01df652b86..b366d7d9c3 100644 +--- a/src/util/virpci.h ++++ b/src/util/virpci.h +@@ -49,6 +49,8 @@ struct _virPCIDeviceAddress { + unsigned int slot; + unsigned int function; + int multi; /* virTristateSwitch */ ++ int extFlags; /* enum virPCIDeviceAddressExtensionFlags */ ++ virZPCIDeviceAddress zpci; + }; + + typedef enum { +-- +2.22.0 + diff --git a/SOURCES/libvirt-conf-Introduce-parser-formatter-for-uid-and-fid.patch b/SOURCES/libvirt-conf-Introduce-parser-formatter-for-uid-and-fid.patch new file mode 100644 index 0000000..3bd46dd --- /dev/null +++ b/SOURCES/libvirt-conf-Introduce-parser-formatter-for-uid-and-fid.patch @@ -0,0 +1,574 @@ +From fddd43e717869d56e481c3fde2d5ee6b5513a1f5 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Yi Min Zhao +Date: Mon, 8 Apr 2019 10:57:25 +0200 +Subject: [PATCH] conf: Introduce parser, formatter for uid and fid +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This patch introduces new XML parser/formatter functions. Uid is +16-bit and non-zero. Fid is 32-bit. They are the two attributes of zpci +which is introduced as PCI address element. Zpci element is parsed and +formatted along with PCI address. And add the related test cases. + +Signed-off-by: Yi Min Zhao +Reviewed-by: Boris Fiuczynski +Reviewed-by: Stefan Zimmermann +Reviewed-by: Bjoern Walk +Reviewed-by: Ján Tomko +Reviewed-by: Andrea Bolognani + +(cherry picked from commit b4833b2c2f7be8a68eb6495ed57ed61918e3ecd8) + +https://bugzilla.redhat.com/show_bug.cgi?id=1508149 + +Conflicts: + + * src/conf/device_conf.c + + context + - missing edeef779585 + + * tests/qemuxml2argvtest.c + + context + - missing a0ff9fbe5cad, 0bdb704383f7 + +Changed: + + * tests/qemuxml2argvdata/disk-virtio-s390-zpci.args + tests/qemuxml2argvdata/hostdev-vfio-zpci.args + + no -boot in output + - missing caccbba64aa9 + +Signed-off-by: Andrea Bolognani +Message-Id: <20190408085732.28684-9-abologna@redhat.com> +Reviewed-by: Laine Stump +Reviewed-by: Ján Tomko +--- + docs/schemas/basictypes.rng | 27 ++++++++++ + docs/schemas/domaincommon.rng | 1 + + src/conf/device_conf.c | 53 +++++++++++++++++++ + src/conf/domain_addr.c | 3 ++ + src/conf/domain_conf.c | 12 ++++- + src/libvirt_private.syms | 2 + + src/util/virpci.c | 26 +++++++++ + src/util/virpci.h | 6 +++ + .../disk-virtio-s390-zpci.args | 26 +++++++++ + .../disk-virtio-s390-zpci.xml | 19 +++++++ + tests/qemuxml2argvdata/hostdev-vfio-zpci.args | 24 +++++++++ + tests/qemuxml2argvdata/hostdev-vfio-zpci.xml | 21 ++++++++ + tests/qemuxml2argvtest.c | 7 +++ + .../disk-virtio-s390-zpci.xml | 31 +++++++++++ + .../qemuxml2xmloutdata/hostdev-vfio-zpci.xml | 32 +++++++++++ + tests/qemuxml2xmltest.c | 6 +++ + 16 files changed, 295 insertions(+), 1 deletion(-) + create mode 100644 tests/qemuxml2argvdata/disk-virtio-s390-zpci.args + create mode 100644 tests/qemuxml2argvdata/disk-virtio-s390-zpci.xml + create mode 100644 tests/qemuxml2argvdata/hostdev-vfio-zpci.args + create mode 100644 tests/qemuxml2argvdata/hostdev-vfio-zpci.xml + create mode 100644 tests/qemuxml2xmloutdata/disk-virtio-s390-zpci.xml + create mode 100644 tests/qemuxml2xmloutdata/hostdev-vfio-zpci.xml + +diff --git a/docs/schemas/basictypes.rng b/docs/schemas/basictypes.rng +index b45a7fcdc8..97e14d7ca8 100644 +--- a/docs/schemas/basictypes.rng ++++ b/docs/schemas/basictypes.rng +@@ -65,6 +65,17 @@ + + + ++ ++ ++ ++ (0x)?[0-9a-fA-F]{1,8} ++ ++ ++ 0 ++ 4294967295 ++ ++ ++ + + + +@@ -111,6 +122,22 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng +index 70a7767d9c..2b6d4dced6 100644 +--- a/docs/schemas/domaincommon.rng ++++ b/docs/schemas/domaincommon.rng +@@ -5186,6 +5186,7 @@ + pci + + ++ + + + +diff --git a/src/conf/device_conf.c b/src/conf/device_conf.c +index d69f94fadf..cadac32603 100644 +--- a/src/conf/device_conf.c ++++ b/src/conf/device_conf.c +@@ -32,6 +32,45 @@ + + #define VIR_FROM_THIS VIR_FROM_DEVICE + ++static int ++virZPCIDeviceAddressParseXML(xmlNodePtr node, ++ virPCIDeviceAddressPtr addr) ++{ ++ virZPCIDeviceAddress def = { 0 }; ++ char *uid; ++ char *fid; ++ int ret = -1; ++ ++ uid = virXMLPropString(node, "uid"); ++ fid = virXMLPropString(node, "fid"); ++ ++ if (uid && ++ virStrToLong_uip(uid, NULL, 0, &def.uid) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("Cannot parse
'uid' attribute")); ++ goto cleanup; ++ } ++ ++ if (fid && ++ virStrToLong_uip(fid, NULL, 0, &def.fid) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("Cannot parse
'fid' attribute")); ++ goto cleanup; ++ } ++ ++ if (!virZPCIDeviceAddressIsEmpty(&def) && ++ !virZPCIDeviceAddressIsValid(&def)) ++ goto cleanup; ++ ++ addr->zpci = def; ++ ret = 0; ++ ++ cleanup: ++ VIR_FREE(uid); ++ VIR_FREE(fid); ++ return ret; ++} ++ + int + virDomainDeviceInfoCopy(virDomainDeviceInfoPtr dst, + virDomainDeviceInfoPtr src) +@@ -196,6 +235,8 @@ virPCIDeviceAddressParseXML(xmlNodePtr node, + virPCIDeviceAddressPtr addr) + { + char *domain, *slot, *bus, *function, *multi; ++ xmlNodePtr cur; ++ xmlNodePtr zpci = NULL; + int ret = -1; + + memset(addr, 0, sizeof(*addr)); +@@ -245,6 +286,18 @@ virPCIDeviceAddressParseXML(xmlNodePtr node, + if (!virPCIDeviceAddressIsEmpty(addr) && !virPCIDeviceAddressIsValid(addr, true)) + goto cleanup; + ++ cur = node->children; ++ while (cur) { ++ if (cur->type == XML_ELEMENT_NODE && ++ virXMLNodeNameEqual(cur, "zpci")) { ++ zpci = cur; ++ } ++ cur = cur->next; ++ } ++ ++ if (zpci && virZPCIDeviceAddressParseXML(zpci, addr) < 0) ++ goto cleanup; ++ + ret = 0; + + cleanup: +diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c +index 3e33549c3d..9e0a0fdf95 100644 +--- a/src/conf/domain_addr.c ++++ b/src/conf/domain_addr.c +@@ -1054,6 +1054,9 @@ virDomainPCIAddressReserveNextAddr(virDomainPCIAddressSetPtr addrs, + dev->isolationGroup, false) < 0) + return -1; + ++ addr.extFlags = dev->addr.pci.extFlags; ++ addr.zpci = dev->addr.pci.zpci; ++ + if (!addrs->dryRun) { + dev->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; + dev->addr.pci = addr; +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index bcb0558bc3..29ebf0a930 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -6448,6 +6448,7 @@ virDomainDeviceInfoFormat(virBufferPtr buf, + unsigned int flags) + { + virBuffer attrBuf = VIR_BUFFER_INITIALIZER; ++ virBuffer childBuf = VIR_BUFFER_INITIALIZER; + + if ((flags & VIR_DOMAIN_DEF_FORMAT_ALLOW_BOOT) && info->bootIndex) { + virBufferAsprintf(buf, "bootIndex); +@@ -6510,6 +6511,14 @@ virDomainDeviceInfoFormat(virBufferPtr buf, + virBufferAsprintf(&attrBuf, " multifunction='%s'", + virTristateSwitchTypeToString(info->addr.pci.multi)); + } ++ ++ if (!virZPCIDeviceAddressIsEmpty(&info->addr.pci.zpci)) { ++ virBufferSetChildIndent(&childBuf, buf); ++ virBufferAsprintf(&childBuf, ++ "\n", ++ info->addr.pci.zpci.uid, ++ info->addr.pci.zpci.fid); ++ } + break; + + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE: +@@ -6577,9 +6586,10 @@ virDomainDeviceInfoFormat(virBufferPtr buf, + break; + } + +- virXMLFormatElement(buf, "address", &attrBuf, NULL); ++ virXMLFormatElement(buf, "address", &attrBuf, &childBuf); + + virBufferFreeAndReset(&attrBuf); ++ virBufferFreeAndReset(&childBuf); + } + + static int +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index df27ac4b3a..b2a2a1f265 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -2569,6 +2569,8 @@ virPCIHeaderTypeToString; + virPCIIsVirtualFunction; + virPCIStubDriverTypeFromString; + virPCIStubDriverTypeToString; ++virZPCIDeviceAddressIsEmpty; ++virZPCIDeviceAddressIsValid; + + + # util/virperf.h +diff --git a/src/util/virpci.c b/src/util/virpci.c +index 8d02366664..3a1e49a7a7 100644 +--- a/src/util/virpci.c ++++ b/src/util/virpci.c +@@ -2597,6 +2597,32 @@ virPCIDeviceAddressParse(char *address, + + #ifdef __linux__ + ++bool ++virZPCIDeviceAddressIsValid(virZPCIDeviceAddressPtr zpci) ++{ ++ /* We don't need to check fid because fid covers ++ * all range of uint32 type. ++ */ ++ if (zpci->uid > VIR_DOMAIN_DEVICE_ZPCI_MAX_UID || ++ zpci->uid == 0) { ++ virReportError(VIR_ERR_XML_ERROR, ++ _("Invalid PCI address uid='0x%.4x', " ++ "must be > 0x0000 and <= 0x%.4x"), ++ zpci->uid, ++ VIR_DOMAIN_DEVICE_ZPCI_MAX_UID); ++ return false; ++ } ++ ++ return true; ++} ++ ++bool ++virZPCIDeviceAddressIsEmpty(const virZPCIDeviceAddress *addr) ++{ ++ return !(addr->uid || addr->fid); ++} ++ ++ + /* + * returns true if equal + */ +diff --git a/src/util/virpci.h b/src/util/virpci.h +index b366d7d9c3..1ed9e2381e 100644 +--- a/src/util/virpci.h ++++ b/src/util/virpci.h +@@ -36,6 +36,9 @@ typedef virPCIDeviceAddress *virPCIDeviceAddressPtr; + typedef struct _virPCIDeviceList virPCIDeviceList; + typedef virPCIDeviceList *virPCIDeviceListPtr; + ++# define VIR_DOMAIN_DEVICE_ZPCI_MAX_UID UINT16_MAX ++# define VIR_DOMAIN_DEVICE_ZPCI_MAX_FID UINT32_MAX ++ + typedef struct _virZPCIDeviceAddress virZPCIDeviceAddress; + typedef virZPCIDeviceAddress *virZPCIDeviceAddressPtr; + struct _virZPCIDeviceAddress { +@@ -235,6 +238,9 @@ int virPCIGetAddrString(unsigned int domain, + + int virPCIDeviceAddressParse(char *address, virPCIDeviceAddressPtr bdf); + ++bool virZPCIDeviceAddressIsValid(virZPCIDeviceAddressPtr zpci); ++bool virZPCIDeviceAddressIsEmpty(const virZPCIDeviceAddress *addr); ++ + int virPCIGetVirtualFunctionInfo(const char *vf_sysfs_device_path, + int pfNetDevIdx, + char **pfname, +diff --git a/tests/qemuxml2argvdata/disk-virtio-s390-zpci.args b/tests/qemuxml2argvdata/disk-virtio-s390-zpci.args +new file mode 100644 +index 0000000000..20e63a15b5 +--- /dev/null ++++ b/tests/qemuxml2argvdata/disk-virtio-s390-zpci.args +@@ -0,0 +1,26 @@ ++LC_ALL=C \ ++PATH=/bin \ ++HOME=/home/test \ ++USER=test \ ++LOGNAME=test \ ++QEMU_AUDIO_DRV=none \ ++/usr/bin/qemu-system-s390x \ ++-name QEMUGuest1 \ ++-S \ ++-machine s390-ccw-virtio,accel=tcg,usb=off,dump-guest-core=off \ ++-m 214 \ ++-smp 1,sockets=1,cores=1,threads=1 \ ++-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ ++-display none \ ++-no-user-config \ ++-nodefaults \ ++-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\ ++server,nowait \ ++-mon chardev=charmonitor,id=monitor,mode=control \ ++-rtc base=utc \ ++-no-shutdown \ ++-boot c \ ++-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-virtio-disk0 \ ++-device virtio-blk-pci,bus=pci.0,addr=0x8,drive=drive-virtio-disk0,\ ++id=virtio-disk0 \ ++-device virtio-balloon-ccw,id=balloon0,devno=fe.0.0000 +diff --git a/tests/qemuxml2argvdata/disk-virtio-s390-zpci.xml b/tests/qemuxml2argvdata/disk-virtio-s390-zpci.xml +new file mode 100644 +index 0000000000..8bf4a23670 +--- /dev/null ++++ b/tests/qemuxml2argvdata/disk-virtio-s390-zpci.xml +@@ -0,0 +1,19 @@ ++ ++ QEMUGuest1 ++ c7a5fdbd-edaf-9455-926a-d65c16db1809 ++ 219136 ++ 1 ++ ++ hvm ++ ++ ++ /usr/bin/qemu-system-s390x ++ ++ ++ ++
++ ++
++
++
++
+diff --git a/tests/qemuxml2argvdata/hostdev-vfio-zpci.args b/tests/qemuxml2argvdata/hostdev-vfio-zpci.args +new file mode 100644 +index 0000000000..622c504da0 +--- /dev/null ++++ b/tests/qemuxml2argvdata/hostdev-vfio-zpci.args +@@ -0,0 +1,24 @@ ++LC_ALL=C \ ++PATH=/bin \ ++HOME=/home/test \ ++USER=test \ ++LOGNAME=test \ ++QEMU_AUDIO_DRV=none \ ++/usr/bin/qemu-system-s390x \ ++-name QEMUGuest1 \ ++-S \ ++-machine s390-ccw-virtio,accel=tcg,usb=off,dump-guest-core=off \ ++-m 214 \ ++-smp 1,sockets=1,cores=1,threads=1 \ ++-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ ++-display none \ ++-no-user-config \ ++-nodefaults \ ++-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\ ++server,nowait \ ++-mon chardev=charmonitor,id=monitor,mode=control \ ++-rtc base=utc \ ++-no-shutdown \ ++-boot c \ ++-device vfio-pci,host=00:00.0,id=hostdev0,bus=pci.0,addr=0x8 \ ++-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x1 +diff --git a/tests/qemuxml2argvdata/hostdev-vfio-zpci.xml b/tests/qemuxml2argvdata/hostdev-vfio-zpci.xml +new file mode 100644 +index 0000000000..002b99c52d +--- /dev/null ++++ b/tests/qemuxml2argvdata/hostdev-vfio-zpci.xml +@@ -0,0 +1,21 @@ ++ ++ QEMUGuest1 ++ c7a5fdbd-edaf-9455-926a-d65c16db1809 ++ 219100 ++ ++ hvm ++ ++ ++ /usr/bin/qemu-system-s390x ++ ++ ++ ++ ++
++ ++
++ ++
++ ++ ++ +diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c +index 7f25cccf9d..2eb2505971 100644 +--- a/tests/qemuxml2argvtest.c ++++ b/tests/qemuxml2argvtest.c +@@ -1038,6 +1038,10 @@ mymain(void) + QEMU_CAPS_CCW, QEMU_CAPS_VIRTIO_S390); + DO_TEST("disk-virtio-scsi-ccw", QEMU_CAPS_VIRTIO_SCSI, + QEMU_CAPS_CCW, QEMU_CAPS_VIRTIO_S390); ++ DO_TEST("disk-virtio-s390-zpci", ++ QEMU_CAPS_DEVICE_ZPCI, ++ QEMU_CAPS_CCW, ++ QEMU_CAPS_VIRTIO_S390); + DO_TEST("disk-order", + QEMU_CAPS_DRIVE_BOOT, QEMU_CAPS_VIRTIO_BLK_SCSI); + DO_TEST("disk-virtio-drive-queues", +@@ -1628,6 +1632,9 @@ mymain(void) + DO_TEST_PARSE_ERROR("hostdev-mdev-display-missing-graphics", + QEMU_CAPS_DEVICE_VFIO_PCI, + QEMU_CAPS_VFIO_PCI_DISPLAY); ++ DO_TEST("hostdev-vfio-zpci", ++ QEMU_CAPS_DEVICE_VFIO_PCI, ++ QEMU_CAPS_DEVICE_ZPCI); + DO_TEST("pci-rom", NONE); + DO_TEST("pci-rom-disabled", NONE); + DO_TEST("pci-rom-disabled-invalid", NONE); +diff --git a/tests/qemuxml2xmloutdata/disk-virtio-s390-zpci.xml b/tests/qemuxml2xmloutdata/disk-virtio-s390-zpci.xml +new file mode 100644 +index 0000000000..37684c82b1 +--- /dev/null ++++ b/tests/qemuxml2xmloutdata/disk-virtio-s390-zpci.xml +@@ -0,0 +1,31 @@ ++ ++ QEMUGuest1 ++ c7a5fdbd-edaf-9455-926a-d65c16db1809 ++ 219136 ++ 219136 ++ 1 ++ ++ hvm ++ ++ ++ ++ destroy ++ restart ++ destroy ++ ++ /usr/bin/qemu-system-s390x ++ ++ ++ ++ ++
++ ++
++
++ ++ ++
++ ++ ++ ++ +diff --git a/tests/qemuxml2xmloutdata/hostdev-vfio-zpci.xml b/tests/qemuxml2xmloutdata/hostdev-vfio-zpci.xml +new file mode 100644 +index 0000000000..fc8c38ab66 +--- /dev/null ++++ b/tests/qemuxml2xmloutdata/hostdev-vfio-zpci.xml +@@ -0,0 +1,32 @@ ++ ++ QEMUGuest1 ++ c7a5fdbd-edaf-9455-926a-d65c16db1809 ++ 219100 ++ 219100 ++ 1 ++ ++ hvm ++ ++ ++ ++ destroy ++ restart ++ destroy ++ ++ /usr/bin/qemu-system-s390x ++ ++ ++ ++ ++
++ ++
++ ++
++ ++ ++
++ ++ ++ ++ +diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c +index 2a2bf01ffa..a787f4f4a3 100644 +--- a/tests/qemuxml2xmltest.c ++++ b/tests/qemuxml2xmltest.c +@@ -400,6 +400,9 @@ mymain(void) + QEMU_CAPS_VIRTIO_SCSI); + DO_TEST("disk-virtio-scsi-ioeventfd", + QEMU_CAPS_VIRTIO_SCSI); ++ DO_TEST("disk-virtio-s390-zpci", ++ QEMU_CAPS_DEVICE_ZPCI, ++ QEMU_CAPS_CCW); + DO_TEST("disk-scsi-megasas", + QEMU_CAPS_SCSI_MEGASAS); + DO_TEST("disk-scsi-mptsas1068", +@@ -482,6 +485,9 @@ mymain(void) + DO_TEST("hostdev-usb-address", NONE); + DO_TEST("hostdev-pci-address", NONE); + DO_TEST("hostdev-vfio", NONE); ++ DO_TEST("hostdev-vfio-zpci", ++ QEMU_CAPS_DEVICE_ZPCI, ++ QEMU_CAPS_CCW); + DO_TEST("hostdev-mdev-precreated", NONE); + DO_TEST("hostdev-mdev-display", QEMU_CAPS_VFIO_PCI_DISPLAY); + DO_TEST("pci-rom", NONE); +-- +2.22.0 + diff --git a/SOURCES/libvirt-conf-Introduce-virCPUDefCheckFeatures.patch b/SOURCES/libvirt-conf-Introduce-virCPUDefCheckFeatures.patch new file mode 100644 index 0000000..509c5cf --- /dev/null +++ b/SOURCES/libvirt-conf-Introduce-virCPUDefCheckFeatures.patch @@ -0,0 +1,103 @@ +From 0bed2e17ea6469ccabb374c0520a97706b281911 Mon Sep 17 00:00:00 2001 +Message-Id: <0bed2e17ea6469ccabb374c0520a97706b281911@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:26:06 +0200 +Subject: [PATCH] conf: Introduce virCPUDefCheckFeatures +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This API can be used to check whether a CPU definition contains features +matching a given filter. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 4e6f58b8d55d44fa9f80736b2745b44710f6e25a) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Signed-off-by: Jiri Denemark +Message-Id: +Reviewed-by: Ján Tomko +--- + src/conf/cpu_conf.c | 33 +++++++++++++++++++++++++++++++++ + src/conf/cpu_conf.h | 6 ++++++ + src/libvirt_private.syms | 1 + + 3 files changed, 40 insertions(+) + +diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c +index 51e2a83eae..4cccea9981 100644 +--- a/src/conf/cpu_conf.c ++++ b/src/conf/cpu_conf.c +@@ -872,6 +872,39 @@ virCPUDefFilterFeatures(virCPUDefPtr cpu, + } + + ++/** ++ * virCPUDefCheckFeatures: ++ * ++ * Check CPU features for which @filter reports true and store them in a NULL ++ * terminated list returned via @features. ++ * ++ * Returns the number of features matching @filter or -1 on error. ++ */ ++int ++virCPUDefCheckFeatures(virCPUDefPtr cpu, ++ virCPUDefFeatureFilter filter, ++ void *opaque, ++ char ***features) ++{ ++ VIR_AUTOSTRINGLIST list = NULL; ++ size_t n = 0; ++ size_t i; ++ ++ *features = NULL; ++ ++ for (i = 0; i < cpu->nfeatures; i++) { ++ if (filter(cpu->features[i].name, opaque)) { ++ if (virStringListAdd(&list, cpu->features[i].name) < 0) ++ return -1; ++ n++; ++ } ++ } ++ ++ VIR_STEAL_PTR(*features, list); ++ return n; ++} ++ ++ + bool + virCPUDefIsEqual(virCPUDefPtr src, + virCPUDefPtr dst, +diff --git a/src/conf/cpu_conf.h b/src/conf/cpu_conf.h +index ad25932b9b..cba0ec7c81 100644 +--- a/src/conf/cpu_conf.h ++++ b/src/conf/cpu_conf.h +@@ -225,6 +225,12 @@ virCPUDefFilterFeatures(virCPUDefPtr cpu, + virCPUDefFeatureFilter filter, + void *opaque); + ++int ++virCPUDefCheckFeatures(virCPUDefPtr cpu, ++ virCPUDefFeatureFilter filter, ++ void *opaque, ++ char ***features); ++ + virCPUDefPtr * + virCPUDefListParse(const char **xmlCPUs, + unsigned int ncpus, +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 06374deaae..0290f960a0 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -72,6 +72,7 @@ virCapabilitiesSetNetPrefix; + virCPUCacheModeTypeFromString; + virCPUCacheModeTypeToString; + virCPUDefAddFeature; ++virCPUDefCheckFeatures; + virCPUDefCopy; + virCPUDefCopyModel; + virCPUDefCopyModelFilter; +-- +2.22.0 + diff --git a/SOURCES/libvirt-conf-use-virXMLFormatElement-in-virDomainDeviceInfoFormat.patch b/SOURCES/libvirt-conf-use-virXMLFormatElement-in-virDomainDeviceInfoFormat.patch new file mode 100644 index 0000000..1747e21 --- /dev/null +++ b/SOURCES/libvirt-conf-use-virXMLFormatElement-in-virDomainDeviceInfoFormat.patch @@ -0,0 +1,154 @@ +From 2566a32fae64fa5cc8a3d3c30778d0ea7d8c4faa Mon Sep 17 00:00:00 2001 +Message-Id: <2566a32fae64fa5cc8a3d3c30778d0ea7d8c4faa@dist-git> +From: Yi Min Zhao +Date: Mon, 8 Apr 2019 10:57:24 +0200 +Subject: [PATCH] conf: use virXMLFormatElement() in + virDomainDeviceInfoFormat() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In order to add zPCI child element for PCI address, we update +virDomainDeviceInfoFormat() to format device info by helper function +virXMLFormatElement(). Then we could simply format zPCI address into +child buffer later. + +Signed-off-by: Yi Min Zhao +Reviewed-by: Boris Fiuczynski +Reviewed-by: Andrea Bolognani + +(cherry picked from commit 0d6b87335c00451b0923ecc91d617f71e4135bf8) + +https://bugzilla.redhat.com/show_bug.cgi?id=1508149 + +Signed-off-by: Andrea Bolognani +Message-Id: <20190408085732.28684-8-abologna@redhat.com> +Reviewed-by: Laine Stump +Reviewed-by: Ján Tomko +--- + src/conf/domain_conf.c | 40 ++++++++++++++++++++++------------------ + 1 file changed, 22 insertions(+), 18 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index e62f78471c..bcb0558bc3 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -6447,6 +6447,8 @@ virDomainDeviceInfoFormat(virBufferPtr buf, + virDomainDeviceInfoPtr info, + unsigned int flags) + { ++ virBuffer attrBuf = VIR_BUFFER_INITIALIZER; ++ + if ((flags & VIR_DOMAIN_DEF_FORMAT_ALLOW_BOOT) && info->bootIndex) { + virBufferAsprintf(buf, "bootIndex); + +@@ -6491,13 +6493,13 @@ virDomainDeviceInfoFormat(virBufferPtr buf, + info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) + return; + +- virBufferAsprintf(buf, "
type)); + + switch ((virDomainDeviceAddressType) info->type) { + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI: + if (!virPCIDeviceAddressIsEmpty(&info->addr.pci)) { +- virBufferAsprintf(buf, " domain='0x%.4x' bus='0x%.2x' " ++ virBufferAsprintf(&attrBuf, " domain='0x%.4x' bus='0x%.2x' " + "slot='0x%.2x' function='0x%.1x'", + info->addr.pci.domain, + info->addr.pci.bus, +@@ -6505,13 +6507,13 @@ virDomainDeviceInfoFormat(virBufferPtr buf, + info->addr.pci.function); + } + if (info->addr.pci.multi) { +- virBufferAsprintf(buf, " multifunction='%s'", +- virTristateSwitchTypeToString(info->addr.pci.multi)); ++ virBufferAsprintf(&attrBuf, " multifunction='%s'", ++ virTristateSwitchTypeToString(info->addr.pci.multi)); + } + break; + + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE: +- virBufferAsprintf(buf, " controller='%d' bus='%d' target='%d' unit='%d'", ++ virBufferAsprintf(&attrBuf, " controller='%d' bus='%d' target='%d' unit='%d'", + info->addr.drive.controller, + info->addr.drive.bus, + info->addr.drive.target, +@@ -6519,34 +6521,34 @@ virDomainDeviceInfoFormat(virBufferPtr buf, + break; + + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL: +- virBufferAsprintf(buf, " controller='%d' bus='%d' port='%d'", ++ virBufferAsprintf(&attrBuf, " controller='%d' bus='%d' port='%d'", + info->addr.vioserial.controller, + info->addr.vioserial.bus, + info->addr.vioserial.port); + break; + + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCID: +- virBufferAsprintf(buf, " controller='%d' slot='%d'", ++ virBufferAsprintf(&attrBuf, " controller='%d' slot='%d'", + info->addr.ccid.controller, + info->addr.ccid.slot); + break; + + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB: +- virBufferAsprintf(buf, " bus='%d'", info->addr.usb.bus); ++ virBufferAsprintf(&attrBuf, " bus='%d'", info->addr.usb.bus); + if (virDomainUSBAddressPortIsValid(info->addr.usb.port)) { +- virBufferAddLit(buf, " port='"); +- virDomainUSBAddressPortFormatBuf(buf, info->addr.usb.port); +- virBufferAddLit(buf, "'"); ++ virBufferAddLit(&attrBuf, " port='"); ++ virDomainUSBAddressPortFormatBuf(&attrBuf, info->addr.usb.port); ++ virBufferAddLit(&attrBuf, "'"); + } + break; + + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO: + if (info->addr.spaprvio.has_reg) +- virBufferAsprintf(buf, " reg='0x%llx'", info->addr.spaprvio.reg); ++ virBufferAsprintf(&attrBuf, " reg='0x%llx'", info->addr.spaprvio.reg); + break; + + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW: +- virBufferAsprintf(buf, " cssid='0x%x' ssid='0x%x' devno='0x%04x'", ++ virBufferAsprintf(&attrBuf, " cssid='0x%x' ssid='0x%x' devno='0x%04x'", + info->addr.ccw.cssid, + info->addr.ccw.ssid, + info->addr.ccw.devno); +@@ -6557,15 +6559,15 @@ virDomainDeviceInfoFormat(virBufferPtr buf, + + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_ISA: + if (info->addr.isa.iobase > 0) +- virBufferAsprintf(buf, " iobase='0x%x'", info->addr.isa.iobase); ++ virBufferAsprintf(&attrBuf, " iobase='0x%x'", info->addr.isa.iobase); + if (info->addr.isa.irq > 0) +- virBufferAsprintf(buf, " irq='0x%x'", info->addr.isa.irq); ++ virBufferAsprintf(&attrBuf, " irq='0x%x'", info->addr.isa.irq); + break; + + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM: +- virBufferAsprintf(buf, " slot='%u'", info->addr.dimm.slot); ++ virBufferAsprintf(&attrBuf, " slot='%u'", info->addr.dimm.slot); + if (info->addr.dimm.base) +- virBufferAsprintf(buf, " base='0x%llx'", info->addr.dimm.base); ++ virBufferAsprintf(&attrBuf, " base='0x%llx'", info->addr.dimm.base); + + break; + +@@ -6575,7 +6577,9 @@ virDomainDeviceInfoFormat(virBufferPtr buf, + break; + } + +- virBufferAddLit(buf, "/>\n"); ++ virXMLFormatElement(buf, "address", &attrBuf, NULL); ++ ++ virBufferFreeAndReset(&attrBuf); + } + + static int +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu-Don-t-access-invalid-memory-in-virCPUx86Translate.patch b/SOURCES/libvirt-cpu-Don-t-access-invalid-memory-in-virCPUx86Translate.patch new file mode 100644 index 0000000..d8224ba --- /dev/null +++ b/SOURCES/libvirt-cpu-Don-t-access-invalid-memory-in-virCPUx86Translate.patch @@ -0,0 +1,59 @@ +From b339a54e493d97a5616be8883d1a0b4ebcd149d3 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Michal Privoznik +Date: Fri, 21 Jun 2019 09:25:18 +0200 +Subject: [PATCH] cpu: Don't access invalid memory in virCPUx86Translate +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Problem is that if there are no signatures for a CPU, then we +still allocate cpu->signatures (even though with size 0). Later, +we access cpu->signatures[0] if cpu->signatures is not NULL. + + Invalid read of size 4 + at 0x5F439D7: virCPUx86Translate (cpu_x86.c:2930) + by 0x5F3C239: virCPUTranslate (cpu.c:927) + by 0x57CE7A1: qemuProcessUpdateGuestCPU (qemu_process.c:5870) + ... + Address 0xf752d40 is 0 bytes after a block of size 0 alloc'd + at 0x4C30EC6: calloc (vg_replace_malloc.c:711) + by 0x5DBDE4E: virAllocN (viralloc.c:190) + by 0x5F3E4FA: x86ModelCopySignatures (cpu_x86.c:990) + by 0x5F3E60F: x86ModelCopy (cpu_x86.c:1008) + by 0x5F3E7CB: x86ModelFromCPU (cpu_x86.c:1068) + by 0x5F4397E: virCPUx86Translate (cpu_x86.c:2922) + by 0x5F3C239: virCPUTranslate (cpu.c:927) + by 0x57CE7A1: qemuProcessUpdateGuestCPU (qemu_process.c:5870) + ... + +Signed-off-by: Michal Privoznik +Reviewed-by: Jiri Denemark +(cherry picked from commit 62cb9c335c43a722e81ac0a1ed6e1111ba1d428b) + +https://bugzilla.redhat.com/show_bug.cgi?id=1686895 + +Signed-off-by: Jiri Denemark +Message-Id: +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_x86.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index 24569a90f3..66aa5a612c 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -985,6 +985,9 @@ x86ModelCopySignatures(virCPUx86ModelPtr dst, + { + size_t i; + ++ if (src->nsignatures == 0) ++ return 0; ++ + if (VIR_ALLOC_N(dst->signatures, src->nsignatures) < 0) + return -1; + +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu-Introduce-virCPUDataAddFeature.patch b/SOURCES/libvirt-cpu-Introduce-virCPUDataAddFeature.patch new file mode 100644 index 0000000..89765cf --- /dev/null +++ b/SOURCES/libvirt-cpu-Introduce-virCPUDataAddFeature.patch @@ -0,0 +1,176 @@ +From 992af2f6564b899142a2be5f342e0cdbdd13eadc Mon Sep 17 00:00:00 2001 +Message-Id: <992af2f6564b899142a2be5f342e0cdbdd13eadc@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:59 +0200 +Subject: [PATCH] cpu: Introduce virCPUDataAddFeature +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This is a generic replacement for the former virCPUx86DataAddFeature, +which worked on the generic virCPUDataPtr anyway. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit df73078c612a70e48aa76e889a7026e2daa47b16) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Conflicts: + src/cpu/cpu_x86.h + - downstream did not switch to #pragma once + +Signed-off-by: Jiri Denemark +Message-Id: <4e946f702092fe5eb4c8235dbb98402b30876a5f.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/cpu/cpu.c | 33 +++++++++++++++++++++++++++++++++ + src/cpu/cpu.h | 9 +++++++++ + src/cpu/cpu_x86.c | 3 ++- + src/cpu/cpu_x86.h | 3 --- + src/libvirt_private.syms | 2 +- + src/qemu/qemu_capabilities.c | 2 +- + 6 files changed, 46 insertions(+), 6 deletions(-) + +diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c +index cc93c49418..a2d143c94a 100644 +--- a/src/cpu/cpu.c ++++ b/src/cpu/cpu.c +@@ -1078,3 +1078,36 @@ virCPUValidateFeatures(virArch arch, + else + return 0; + } ++ ++ ++/** ++ * virCPUDataAddFeature: ++ * ++ * @cpuData: CPU data ++ * @name: feature to be added to @cpuData ++ * ++ * Adds a feature called @name to @cpuData. ++ * ++ * Returns 0 on success, -1 on error. ++ */ ++int ++virCPUDataAddFeature(virCPUDataPtr cpuData, ++ const char *name) ++{ ++ struct cpuArchDriver *driver; ++ ++ VIR_DEBUG("arch=%s, cpuData=%p, name=%s", ++ virArchToString(cpuData->arch), cpuData, name); ++ ++ if (!(driver = cpuGetSubDriver(cpuData->arch))) ++ return -1; ++ ++ if (!driver->dataAddFeature) { ++ virReportError(VIR_ERR_NO_SUPPORT, ++ _("cannot add guest CPU feature for %s architecture"), ++ virArchToString(cpuData->arch)); ++ return -1; ++ } ++ ++ return driver->dataAddFeature(cpuData, name); ++} +diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h +index 81119b6aeb..e5fae31e30 100644 +--- a/src/cpu/cpu.h ++++ b/src/cpu/cpu.h +@@ -121,6 +121,10 @@ typedef virCPUDefPtr + typedef int + (*virCPUArchValidateFeatures)(virCPUDefPtr cpu); + ++typedef int ++(*virCPUArchDataAddFeature)(virCPUDataPtr cpuData, ++ const char *name); ++ + struct cpuArchDriver { + const char *name; + const virArch *arch; +@@ -143,6 +147,7 @@ struct cpuArchDriver { + virCPUArchExpandFeatures expandFeatures; + virCPUArchCopyMigratable copyMigratable; + virCPUArchValidateFeatures validateFeatures; ++ virCPUArchDataAddFeature dataAddFeature; + }; + + +@@ -260,6 +265,10 @@ virCPUValidateFeatures(virArch arch, + virCPUDefPtr cpu) + ATTRIBUTE_NONNULL(2); + ++int ++virCPUDataAddFeature(virCPUDataPtr cpuData, ++ const char *name); ++ + /* virCPUDataFormat and virCPUDataParse are implemented for unit tests only and + * have no real-life usage + */ +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index 3c1bd623db..ead962ae06 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -3316,7 +3316,7 @@ virCPUx86DataSetVendor(virCPUDataPtr cpuData, + } + + +-int ++static int + virCPUx86DataAddFeature(virCPUDataPtr cpuData, + const char *name) + { +@@ -3361,4 +3361,5 @@ struct cpuArchDriver cpuDriverX86 = { + .expandFeatures = virCPUx86ExpandFeatures, + .copyMigratable = virCPUx86CopyMigratable, + .validateFeatures = virCPUx86ValidateFeatures, ++ .dataAddFeature = virCPUx86DataAddFeature, + }; +diff --git a/src/cpu/cpu_x86.h b/src/cpu/cpu_x86.h +index 8b51cef9c1..519024b7c0 100644 +--- a/src/cpu/cpu_x86.h ++++ b/src/cpu/cpu_x86.h +@@ -45,7 +45,4 @@ uint32_t virCPUx86DataGetSignature(virCPUDataPtr cpuData, + int virCPUx86DataSetVendor(virCPUDataPtr cpuData, + const char *vendor); + +-int virCPUx86DataAddFeature(virCPUDataPtr cpuData, +- const char *name); +- + #endif /* __VIR_CPU_X86_H__ */ +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 57508de0c1..a20e0593f0 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -1187,6 +1187,7 @@ virCPUCompare; + virCPUCompareXML; + virCPUConvertLegacy; + virCPUCopyMigratable; ++virCPUDataAddFeature; + virCPUDataCheckFeature; + virCPUDataFormat; + virCPUDataFree; +@@ -1205,7 +1206,6 @@ virCPUValidateFeatures; + + # cpu/cpu_x86.h + virCPUx86DataAdd; +-virCPUx86DataAddFeature; + virCPUx86DataGetSignature; + virCPUx86DataSetSignature; + virCPUx86DataSetVendor; +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index 78be2d35f4..4be0ec305f 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -2916,7 +2916,7 @@ virQEMUCapsGetCPUModelX86Data(virQEMUCapsPtr qemuCaps, + (migratable && prop->migratable == VIR_TRISTATE_BOOL_NO)) + continue; + +- if (virCPUx86DataAddFeature(data, name) < 0) ++ if (virCPUDataAddFeature(data, name) < 0) + goto cleanup; + + break; +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu-allow-include-files-for-CPU-definition.patch b/SOURCES/libvirt-cpu-allow-include-files-for-CPU-definition.patch new file mode 100644 index 0000000..84abe17 --- /dev/null +++ b/SOURCES/libvirt-cpu-allow-include-files-for-CPU-definition.patch @@ -0,0 +1,159 @@ +From 6438640b53fef3e889c21a2ed016638b91c5ac80 Mon Sep 17 00:00:00 2001 +Message-Id: <6438640b53fef3e889c21a2ed016638b91c5ac80@dist-git> +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Fri, 21 Jun 2019 09:24:44 +0200 +Subject: [PATCH] cpu: allow include files for CPU definition +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Allow for syntax + + + +to reference other files in the CPU database directory + +Reviewed-by: Jiri Denemark +Signed-off-by: Daniel P. Berrangé +(cherry picked from commit eda5f575f2a7530fc7f6471f88496778a9bc9fcb) + +https://bugzilla.redhat.com/show_bug.cgi?id=1686895 + +Signed-off-by: Jiri Denemark +Message-Id: <800e5ebbc30502fd780a3ef84fe524f1dc0ffd67.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_map.c | 92 +++++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 89 insertions(+), 3 deletions(-) + +diff --git a/src/cpu/cpu_map.c b/src/cpu/cpu_map.c +index d263eb8cdd..333c7ef24f 100644 +--- a/src/cpu/cpu_map.c ++++ b/src/cpu/cpu_map.c +@@ -1,7 +1,7 @@ + /* + * cpu_map.c: internal functions for handling CPU mapping configuration + * +- * Copyright (C) 2009-2010 Red Hat, Inc. ++ * Copyright (C) 2009-2018 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -70,6 +70,89 @@ static int load(xmlXPathContextPtr ctxt, + return ret; + } + ++static int ++cpuMapLoadInclude(const char *filename, ++ cpuMapLoadCallback cb, ++ void *data) ++{ ++ xmlDocPtr xml = NULL; ++ xmlXPathContextPtr ctxt = NULL; ++ int ret = -1; ++ int element; ++ char *mapfile; ++ ++ if (!(mapfile = virFileFindResource(filename, ++ abs_topsrcdir "/src/cpu", ++ PKGDATADIR))) ++ return -1; ++ ++ VIR_DEBUG("Loading CPU map include from %s", mapfile); ++ ++ if (!(xml = virXMLParseFileCtxt(mapfile, &ctxt))) ++ goto cleanup; ++ ++ ctxt->node = xmlDocGetRootElement(xml); ++ ++ for (element = 0; element < CPU_MAP_ELEMENT_LAST; element++) { ++ if (load(ctxt, element, cb, data) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("cannot parse CPU map '%s'"), mapfile); ++ goto cleanup; ++ } ++ } ++ ++ ret = 0; ++ ++ cleanup: ++ xmlXPathFreeContext(ctxt); ++ xmlFreeDoc(xml); ++ VIR_FREE(mapfile); ++ ++ return ret; ++} ++ ++ ++static int ++loadIncludes(xmlXPathContextPtr ctxt, ++ cpuMapLoadCallback callback, ++ void *data) ++{ ++ int ret = -1; ++ xmlNodePtr ctxt_node; ++ xmlNodePtr *nodes = NULL; ++ int n; ++ size_t i; ++ ++ ctxt_node = ctxt->node; ++ ++ n = virXPathNodeSet("include", ctxt, &nodes); ++ if (n < 0) ++ goto cleanup; ++ ++ for (i = 0; i < n; i++) { ++ char *filename = virXMLPropString(nodes[i], "filename"); ++ if (!filename) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("Missing 'filename' in CPU map include")); ++ goto cleanup; ++ } ++ VIR_DEBUG("Finding CPU map include '%s'", filename); ++ if (cpuMapLoadInclude(filename, callback, data) < 0) { ++ VIR_FREE(filename); ++ goto cleanup; ++ } ++ VIR_FREE(filename); ++ } ++ ++ ret = 0; ++ ++ cleanup: ++ ctxt->node = ctxt_node; ++ VIR_FREE(nodes); ++ ++ return ret; ++} ++ + + int cpuMapLoad(const char *arch, + cpuMapLoadCallback cb, +@@ -88,7 +171,7 @@ int cpuMapLoad(const char *arch, + PKGDATADIR))) + return -1; + +- VIR_DEBUG("Loading CPU map from %s", mapfile); ++ VIR_DEBUG("Loading '%s' CPU map from %s", NULLSTR(arch), mapfile); + + if (arch == NULL) { + virReportError(VIR_ERR_INTERNAL_ERROR, +@@ -122,11 +205,14 @@ int cpuMapLoad(const char *arch, + for (element = 0; element < CPU_MAP_ELEMENT_LAST; element++) { + if (load(ctxt, element, cb, data) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, +- _("cannot parse CPU map for %s architecture"), arch); ++ _("cannot parse CPU map '%s'"), mapfile); + goto cleanup; + } + } + ++ if (loadIncludes(ctxt, cb, data) < 0) ++ goto cleanup; ++ + ret = 0; + + cleanup: +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu-fix-cleanup-when-signature-parsing-fails.patch b/SOURCES/libvirt-cpu-fix-cleanup-when-signature-parsing-fails.patch new file mode 100644 index 0000000..1b253a4 --- /dev/null +++ b/SOURCES/libvirt-cpu-fix-cleanup-when-signature-parsing-fails.patch @@ -0,0 +1,51 @@ +From 612913a764992dc1a9ae63762749ecee447427d7 Mon Sep 17 00:00:00 2001 +Message-Id: <612913a764992dc1a9ae63762749ecee447427d7@dist-git> +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Fri, 21 Jun 2019 09:24:45 +0200 +Subject: [PATCH] cpu: fix cleanup when signature parsing fails +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Two pieces of code accidentally jumped to the wrong label when they +failed causing incorrect cleanup, returning a partially initialized +CPU model struct. + +Reviewed-by: Jiri Denemark +Signed-off-by: Daniel P. Berrangé +(cherry picked from commit 118fcdd480ad38a3e8477f466f6a876dce7e9fa6) + +https://bugzilla.redhat.com/show_bug.cgi?id=1686895 + +Signed-off-by: Jiri Denemark +Message-Id: <5e9aedc6fd4f4570322a7d13626863bec0449283.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_x86.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index 89baf94d7d..124aa5fd5e 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -1250,7 +1250,7 @@ x86ModelParse(xmlXPathContextPtr ctxt, + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Invalid CPU signature family in model %s"), + model->name); +- goto cleanup; ++ goto error; + } + + rc = virXPathUInt("string(./signature/@model)", ctxt, &sigModel); +@@ -1258,7 +1258,7 @@ x86ModelParse(xmlXPathContextPtr ctxt, + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Invalid CPU signature model in model %s"), + model->name); +- goto cleanup; ++ goto error; + } + + model->signature = x86MakeSignature(sigFamily, sigModel, 0); +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu-push-more-parsing-logic-into-common-code.patch b/SOURCES/libvirt-cpu-push-more-parsing-logic-into-common-code.patch new file mode 100644 index 0000000..357b983 --- /dev/null +++ b/SOURCES/libvirt-cpu-push-more-parsing-logic-into-common-code.patch @@ -0,0 +1,782 @@ +From 728231dcbbf2a4ab8a4bfe03fdf43d78bdeccbb0 Mon Sep 17 00:00:00 2001 +Message-Id: <728231dcbbf2a4ab8a4bfe03fdf43d78bdeccbb0@dist-git> +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Fri, 21 Jun 2019 09:24:46 +0200 +Subject: [PATCH] cpu: push more parsing logic into common code +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The x86 and ppc impls both duplicate some logic when parsing CPU +features. Change the callback signature so that this duplication can be +pushed up a level to common code. + +Reviewed-by: Jiri Denemark +Signed-off-by: Daniel P. Berrangé +(cherry picked from commit 0815f519784a7c565c543498777dc25f129620f9) + +https://bugzilla.redhat.com/show_bug.cgi?id=1686895 + +Signed-off-by: Jiri Denemark +Message-Id: +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_map.c | 98 +++++++++++++--------- + src/cpu/cpu_map.h | 22 ++--- + src/cpu/cpu_ppc64.c | 112 ++++++------------------- + src/cpu/cpu_x86.c | 196 +++++++++++++------------------------------- + 4 files changed, 143 insertions(+), 285 deletions(-) + +diff --git a/src/cpu/cpu_map.c b/src/cpu/cpu_map.c +index 333c7ef24f..ac7e58037a 100644 +--- a/src/cpu/cpu_map.c ++++ b/src/cpu/cpu_map.c +@@ -35,31 +35,47 @@ + + VIR_LOG_INIT("cpu.cpu_map"); + +-VIR_ENUM_IMPL(cpuMapElement, CPU_MAP_ELEMENT_LAST, +- "vendor", +- "feature", +- "model") +- +- +-static int load(xmlXPathContextPtr ctxt, +- cpuMapElement element, +- cpuMapLoadCallback callback, +- void *data) ++static int ++loadData(const char *mapfile, ++ xmlXPathContextPtr ctxt, ++ const char *element, ++ cpuMapLoadCallback callback, ++ void *data) + { + int ret = -1; + xmlNodePtr ctxt_node; + xmlNodePtr *nodes = NULL; + int n; ++ size_t i; ++ int rv; + + ctxt_node = ctxt->node; + +- n = virXPathNodeSet(cpuMapElementTypeToString(element), ctxt, &nodes); +- if (n < 0) ++ if ((n = virXPathNodeSet(element, ctxt, &nodes)) < 0) + goto cleanup; + +- if (n > 0 && +- callback(element, ctxt, nodes, n, data) < 0) ++ if (n > 0 && !callback) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Unexpected element '%s' in CPU map '%s'"), element, mapfile); + goto cleanup; ++ } ++ ++ for (i = 0; i < n; i++) { ++ xmlNodePtr old = ctxt->node; ++ char *name = virXMLPropString(nodes[i], "name"); ++ if (!name) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("cannot find %s name in CPU map '%s'"), element, mapfile); ++ goto cleanup; ++ } ++ VIR_DEBUG("Load %s name %s", element, name); ++ ctxt->node = nodes[i]; ++ rv = callback(ctxt, name, data); ++ ctxt->node = old; ++ VIR_FREE(name); ++ if (rv < 0) ++ goto cleanup; ++ } + + ret = 0; + +@@ -72,13 +88,14 @@ static int load(xmlXPathContextPtr ctxt, + + static int + cpuMapLoadInclude(const char *filename, +- cpuMapLoadCallback cb, ++ cpuMapLoadCallback vendorCB, ++ cpuMapLoadCallback featureCB, ++ cpuMapLoadCallback modelCB, + void *data) + { + xmlDocPtr xml = NULL; + xmlXPathContextPtr ctxt = NULL; + int ret = -1; +- int element; + char *mapfile; + + if (!(mapfile = virFileFindResource(filename, +@@ -93,13 +110,14 @@ cpuMapLoadInclude(const char *filename, + + ctxt->node = xmlDocGetRootElement(xml); + +- for (element = 0; element < CPU_MAP_ELEMENT_LAST; element++) { +- if (load(ctxt, element, cb, data) < 0) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("cannot parse CPU map '%s'"), mapfile); +- goto cleanup; +- } +- } ++ if (loadData(mapfile, ctxt, "vendor", vendorCB, data) < 0) ++ goto cleanup; ++ ++ if (loadData(mapfile, ctxt, "feature", featureCB, data) < 0) ++ goto cleanup; ++ ++ if (loadData(mapfile, ctxt, "model", modelCB, data) < 0) ++ goto cleanup; + + ret = 0; + +@@ -114,7 +132,9 @@ cpuMapLoadInclude(const char *filename, + + static int + loadIncludes(xmlXPathContextPtr ctxt, +- cpuMapLoadCallback callback, ++ cpuMapLoadCallback vendorCB, ++ cpuMapLoadCallback featureCB, ++ cpuMapLoadCallback modelCB, + void *data) + { + int ret = -1; +@@ -137,7 +157,7 @@ loadIncludes(xmlXPathContextPtr ctxt, + goto cleanup; + } + VIR_DEBUG("Finding CPU map include '%s'", filename); +- if (cpuMapLoadInclude(filename, callback, data) < 0) { ++ if (cpuMapLoadInclude(filename, vendorCB, featureCB, modelCB, data) < 0) { + VIR_FREE(filename); + goto cleanup; + } +@@ -155,7 +175,9 @@ loadIncludes(xmlXPathContextPtr ctxt, + + + int cpuMapLoad(const char *arch, +- cpuMapLoadCallback cb, ++ cpuMapLoadCallback vendorCB, ++ cpuMapLoadCallback featureCB, ++ cpuMapLoadCallback modelCB, + void *data) + { + xmlDocPtr xml = NULL; +@@ -163,7 +185,6 @@ int cpuMapLoad(const char *arch, + virBuffer buf = VIR_BUFFER_INITIALIZER; + char *xpath = NULL; + int ret = -1; +- int element; + char *mapfile; + + if (!(mapfile = virFileFindResource("cpu_map.xml", +@@ -179,12 +200,6 @@ int cpuMapLoad(const char *arch, + goto cleanup; + } + +- if (cb == NULL) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- "%s", _("no callback provided")); +- goto cleanup; +- } +- + if (!(xml = virXMLParseFileCtxt(mapfile, &ctxt))) + goto cleanup; + +@@ -202,15 +217,16 @@ int cpuMapLoad(const char *arch, + goto cleanup; + } + +- for (element = 0; element < CPU_MAP_ELEMENT_LAST; element++) { +- if (load(ctxt, element, cb, data) < 0) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("cannot parse CPU map '%s'"), mapfile); +- goto cleanup; +- } +- } ++ if (loadData(mapfile, ctxt, "vendor", vendorCB, data) < 0) ++ goto cleanup; + +- if (loadIncludes(ctxt, cb, data) < 0) ++ if (loadData(mapfile, ctxt, "feature", featureCB, data) < 0) ++ goto cleanup; ++ ++ if (loadData(mapfile, ctxt, "model", modelCB, data) < 0) ++ goto cleanup; ++ ++ if (loadIncludes(ctxt, vendorCB, featureCB, modelCB, data) < 0) + goto cleanup; + + ret = 0; +diff --git a/src/cpu/cpu_map.h b/src/cpu/cpu_map.h +index 0c7507e98f..4596987150 100644 +--- a/src/cpu/cpu_map.h ++++ b/src/cpu/cpu_map.h +@@ -26,28 +26,16 @@ + + # include "virxml.h" + +- +-typedef enum { +- CPU_MAP_ELEMENT_VENDOR, +- CPU_MAP_ELEMENT_FEATURE, +- CPU_MAP_ELEMENT_MODEL, +- +- CPU_MAP_ELEMENT_LAST +-} cpuMapElement; +- +-VIR_ENUM_DECL(cpuMapElement) +- +- + typedef int +-(*cpuMapLoadCallback) (cpuMapElement element, +- xmlXPathContextPtr ctxt, +- xmlNodePtr *nodes, +- int n, ++(*cpuMapLoadCallback) (xmlXPathContextPtr ctxt, ++ const char *name, + void *data); + + int + cpuMapLoad(const char *arch, +- cpuMapLoadCallback cb, ++ cpuMapLoadCallback vendorCB, ++ cpuMapLoadCallback featureCB, ++ cpuMapLoadCallback modelCB, + void *data); + + #endif /* __VIR_CPU_MAP_H__ */ +diff --git a/src/cpu/cpu_ppc64.c b/src/cpu/cpu_ppc64.c +index d562677fa3..75da5b77d8 100644 +--- a/src/cpu/cpu_ppc64.c ++++ b/src/cpu/cpu_ppc64.c +@@ -281,21 +281,19 @@ ppc64MapFree(struct ppc64_map *map) + VIR_FREE(map); + } + +-static struct ppc64_vendor * +-ppc64VendorParse(xmlXPathContextPtr ctxt, +- struct ppc64_map *map) ++static int ++ppc64VendorParse(xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED, ++ const char *name, ++ void *data) + { ++ struct ppc64_map *map = data; + struct ppc64_vendor *vendor; + + if (VIR_ALLOC(vendor) < 0) +- return NULL; ++ return -1; + +- vendor->name = virXPathString("string(@name)", ctxt); +- if (!vendor->name) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- "%s", _("Missing CPU vendor name")); ++ if (VIR_STRDUP(vendor->name, name) < 0) + goto error; +- } + + if (ppc64VendorFind(map, vendor->name)) { + virReportError(VIR_ERR_INTERNAL_ERROR, +@@ -303,57 +301,36 @@ ppc64VendorParse(xmlXPathContextPtr ctxt, + goto error; + } + +- return vendor; ++ if (VIR_APPEND_ELEMENT(map->vendors, map->nvendors, vendor) < 0) ++ goto error; ++ ++ return 0; + + error: + ppc64VendorFree(vendor); +- return NULL; ++ return -1; + } + + + static int +-ppc64VendorsLoad(struct ppc64_map *map, +- xmlXPathContextPtr ctxt, +- xmlNodePtr *nodes, +- int n) +-{ +- struct ppc64_vendor *vendor; +- size_t i; +- +- if (VIR_ALLOC_N(map->vendors, n) < 0) +- return -1; +- +- for (i = 0; i < n; i++) { +- ctxt->node = nodes[i]; +- if (!(vendor = ppc64VendorParse(ctxt, map))) +- return -1; +- map->vendors[map->nvendors++] = vendor; +- } +- +- return 0; +-} +- +- +-static struct ppc64_model * + ppc64ModelParse(xmlXPathContextPtr ctxt, +- struct ppc64_map *map) ++ const char *name, ++ void *data) + { ++ struct ppc64_map *map = data; + struct ppc64_model *model; + xmlNodePtr *nodes = NULL; + char *vendor = NULL; + unsigned long pvr; + size_t i; + int n; ++ int ret = -1; + + if (VIR_ALLOC(model) < 0) + goto error; + +- model->name = virXPathString("string(@name)", ctxt); +- if (!model->name) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- "%s", _("Missing CPU model name")); ++ if (VIR_STRDUP(model->name, name) < 0) + goto error; +- } + + if (ppc64ModelFind(map, model->name)) { + virReportError(VIR_ERR_INTERNAL_ERROR, +@@ -410,63 +387,22 @@ ppc64ModelParse(xmlXPathContextPtr ctxt, + model->data.pvr[i].mask = pvr; + } + ++ if (VIR_APPEND_ELEMENT(map->models, map->nmodels, model) < 0) ++ goto error; ++ ++ ret = 0; ++ + cleanup: + VIR_FREE(vendor); + VIR_FREE(nodes); +- return model; ++ return ret; + + error: + ppc64ModelFree(model); +- model = NULL; + goto cleanup; + } + + +-static int +-ppc64ModelsLoad(struct ppc64_map *map, +- xmlXPathContextPtr ctxt, +- xmlNodePtr *nodes, +- int n) +-{ +- struct ppc64_model *model; +- size_t i; +- +- if (VIR_ALLOC_N(map->models, n) < 0) +- return -1; +- +- for (i = 0; i < n; i++) { +- ctxt->node = nodes[i]; +- if (!(model = ppc64ModelParse(ctxt, map))) +- return -1; +- map->models[map->nmodels++] = model; +- } +- +- return 0; +-} +- +- +-static int +-ppc64MapLoadCallback(cpuMapElement element, +- xmlXPathContextPtr ctxt, +- xmlNodePtr *nodes, +- int n, +- void *data) +-{ +- struct ppc64_map *map = data; +- +- switch (element) { +- case CPU_MAP_ELEMENT_VENDOR: +- return ppc64VendorsLoad(map, ctxt, nodes, n); +- case CPU_MAP_ELEMENT_MODEL: +- return ppc64ModelsLoad(map, ctxt, nodes, n); +- case CPU_MAP_ELEMENT_FEATURE: +- case CPU_MAP_ELEMENT_LAST: +- break; +- } +- +- return 0; +-} +- + static struct ppc64_map * + ppc64LoadMap(void) + { +@@ -475,7 +411,7 @@ ppc64LoadMap(void) + if (VIR_ALLOC(map) < 0) + goto error; + +- if (cpuMapLoad("ppc64", ppc64MapLoadCallback, map) < 0) ++ if (cpuMapLoad("ppc64", ppc64VendorParse, NULL, ppc64ModelParse, map) < 0) + goto error; + + return map; +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index 124aa5fd5e..11dbd1e757 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -720,22 +720,21 @@ x86VendorFind(virCPUx86MapPtr map, + } + + +-static virCPUx86VendorPtr ++static int + x86VendorParse(xmlXPathContextPtr ctxt, +- virCPUx86MapPtr map) ++ const char *name, ++ void *data) + { ++ virCPUx86MapPtr map = data; + virCPUx86VendorPtr vendor = NULL; + char *string = NULL; ++ int ret = -1; + + if (VIR_ALLOC(vendor) < 0) + goto error; + +- vendor->name = virXPathString("string(@name)", ctxt); +- if (!vendor->name) { +- virReportError(VIR_ERR_INTERNAL_ERROR, "%s", +- _("Missing CPU vendor name")); ++ if (VIR_STRDUP(vendor->name, name) < 0) + goto error; +- } + + if (x86VendorFind(map, vendor->name)) { + virReportError(VIR_ERR_INTERNAL_ERROR, +@@ -754,40 +753,21 @@ x86VendorParse(xmlXPathContextPtr ctxt, + if (virCPUx86VendorToCPUID(string, &vendor->cpuid) < 0) + goto error; + ++ if (VIR_APPEND_ELEMENT(map->vendors, map->nvendors, vendor) < 0) ++ goto error; ++ ++ ret = 0; ++ + cleanup: + VIR_FREE(string); +- return vendor; ++ return ret; + + error: + x86VendorFree(vendor); +- vendor = NULL; + goto cleanup; + } + + +-static int +-x86VendorsLoad(virCPUx86MapPtr map, +- xmlXPathContextPtr ctxt, +- xmlNodePtr *nodes, +- int n) +-{ +- virCPUx86VendorPtr vendor; +- size_t i; +- +- if (VIR_ALLOC_N(map->vendors, n) < 0) +- return -1; +- +- for (i = 0; i < n; i++) { +- ctxt->node = nodes[i]; +- if (!(vendor = x86VendorParse(ctxt, map))) +- return -1; +- map->vendors[map->nvendors++] = vendor; +- } +- +- return 0; +-} +- +- + static virCPUx86FeaturePtr + x86FeatureNew(void) + { +@@ -909,27 +889,27 @@ x86ParseCPUID(xmlXPathContextPtr ctxt, + } + + +-static virCPUx86FeaturePtr ++static int + x86FeatureParse(xmlXPathContextPtr ctxt, +- virCPUx86MapPtr map) ++ const char *name, ++ void *data) + { ++ virCPUx86MapPtr map = data; + xmlNodePtr *nodes = NULL; + virCPUx86FeaturePtr feature; + virCPUx86CPUID cpuid; + size_t i; + int n; + char *str = NULL; ++ int ret = -1; + + if (!(feature = x86FeatureNew())) + goto error; + + feature->migratable = true; +- feature->name = virXPathString("string(@name)", ctxt); +- if (!feature->name) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- "%s", _("Missing CPU feature name")); ++ ++ if (VIR_STRDUP(feature->name, name) < 0) + goto error; +- } + + if (x86FeatureFind(map, feature->name)) { + virReportError(VIR_ERR_INTERNAL_ERROR, +@@ -957,46 +937,28 @@ x86FeatureParse(xmlXPathContextPtr ctxt, + goto error; + } + ++ if (!feature->migratable && ++ VIR_APPEND_ELEMENT_COPY(map->migrate_blockers, ++ map->nblockers, ++ feature) < 0) ++ goto error; ++ ++ if (VIR_APPEND_ELEMENT(map->features, map->nfeatures, feature) < 0) ++ goto error; ++ ++ ret = 0; ++ + cleanup: + VIR_FREE(nodes); + VIR_FREE(str); +- return feature; ++ return ret; + + error: + x86FeatureFree(feature); +- feature = NULL; + goto cleanup; + } + + +-static int +-x86FeaturesLoad(virCPUx86MapPtr map, +- xmlXPathContextPtr ctxt, +- xmlNodePtr *nodes, +- int n) +-{ +- virCPUx86FeaturePtr feature; +- size_t i; +- +- if (VIR_ALLOC_N(map->features, n) < 0) +- return -1; +- +- for (i = 0; i < n; i++) { +- ctxt->node = nodes[i]; +- if (!(feature = x86FeatureParse(ctxt, map))) +- return -1; +- map->features[map->nfeatures++] = feature; +- if (!feature->migratable && +- VIR_APPEND_ELEMENT(map->migrate_blockers, +- map->nblockers, +- feature) < 0) +- return -1; +- } +- +- return 0; +-} +- +- + static virCPUx86ModelPtr + x86ModelNew(void) + { +@@ -1192,47 +1154,46 @@ x86ModelCompare(virCPUx86ModelPtr model1, + } + + +-static virCPUx86ModelPtr ++static int + x86ModelParse(xmlXPathContextPtr ctxt, +- virCPUx86MapPtr map) ++ const char *name, ++ void *data) + { ++ virCPUx86MapPtr map = data; + xmlNodePtr *nodes = NULL; + virCPUx86ModelPtr model; + char *vendor = NULL; + size_t i; + int n; ++ int ret = -1; + + if (!(model = x86ModelNew())) + goto error; + +- model->name = virXPathString("string(@name)", ctxt); +- if (!model->name) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- "%s", _("Missing CPU model name")); ++ if (VIR_STRDUP(model->name, name) < 0) + goto error; +- } + + if (virXPathNode("./model", ctxt)) { + virCPUx86ModelPtr ancestor; +- char *name; ++ char *anname; + +- name = virXPathString("string(./model/@name)", ctxt); +- if (!name) { ++ anname = virXPathString("string(./model/@name)", ctxt); ++ if (!anname) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Missing ancestor's name in CPU model %s"), + model->name); + goto error; + } + +- if (!(ancestor = x86ModelFind(map, name))) { ++ if (!(ancestor = x86ModelFind(map, anname))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Ancestor model %s not found for CPU model %s"), +- name, model->name); +- VIR_FREE(name); ++ anname, model->name); ++ VIR_FREE(anname); + goto error; + } + +- VIR_FREE(name); ++ VIR_FREE(anname); + + model->vendor = ancestor->vendor; + model->signature = ancestor->signature; +@@ -1287,62 +1248,43 @@ x86ModelParse(xmlXPathContextPtr ctxt, + + for (i = 0; i < n; i++) { + virCPUx86FeaturePtr feature; +- char *name; ++ char *ftname; + +- if (!(name = virXMLPropString(nodes[i], "name"))) { ++ if (!(ftname = virXMLPropString(nodes[i], "name"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Missing feature name for CPU model %s"), model->name); + goto error; + } + +- if (!(feature = x86FeatureFind(map, name))) { ++ if (!(feature = x86FeatureFind(map, ftname))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Feature %s required by CPU model %s not found"), +- name, model->name); +- VIR_FREE(name); ++ ftname, model->name); ++ VIR_FREE(ftname); + goto error; + } +- VIR_FREE(name); ++ VIR_FREE(ftname); + + if (x86DataAdd(&model->data, &feature->data)) + goto error; + } + ++ if (VIR_APPEND_ELEMENT(map->models, map->nmodels, model) < 0) ++ goto error; ++ ++ ret = 0; ++ + cleanup: + VIR_FREE(vendor); + VIR_FREE(nodes); +- return model; ++ return ret; + + error: + x86ModelFree(model); +- model = NULL; + goto cleanup; + } + + +-static int +-x86ModelsLoad(virCPUx86MapPtr map, +- xmlXPathContextPtr ctxt, +- xmlNodePtr *nodes, +- int n) +-{ +- virCPUx86ModelPtr model; +- size_t i; +- +- if (VIR_ALLOC_N(map->models, n) < 0) +- return -1; +- +- for (i = 0; i < n; i++) { +- ctxt->node = nodes[i]; +- if (!(model = x86ModelParse(ctxt, map))) +- return -1; +- map->models[map->nmodels++] = model; +- } +- +- return 0; +-} +- +- + static void + x86MapFree(virCPUx86MapPtr map) + { +@@ -1372,30 +1314,6 @@ x86MapFree(virCPUx86MapPtr map) + } + + +-static int +-x86MapLoadCallback(cpuMapElement element, +- xmlXPathContextPtr ctxt, +- xmlNodePtr *nodes, +- int n, +- void *data) +-{ +- virCPUx86MapPtr map = data; +- +- switch (element) { +- case CPU_MAP_ELEMENT_VENDOR: +- return x86VendorsLoad(map, ctxt, nodes, n); +- case CPU_MAP_ELEMENT_FEATURE: +- return x86FeaturesLoad(map, ctxt, nodes, n); +- case CPU_MAP_ELEMENT_MODEL: +- return x86ModelsLoad(map, ctxt, nodes, n); +- case CPU_MAP_ELEMENT_LAST: +- break; +- } +- +- return 0; +-} +- +- + static virCPUx86MapPtr + virCPUx86LoadMap(void) + { +@@ -1404,7 +1322,7 @@ virCPUx86LoadMap(void) + if (VIR_ALLOC(map) < 0) + return NULL; + +- if (cpuMapLoad("x86", x86MapLoadCallback, map) < 0) ++ if (cpuMapLoad("x86", x86VendorParse, x86FeatureParse, x86ModelParse, map) < 0) + goto error; + + return map; +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu-simplify-failure-cleanup-paths.patch b/SOURCES/libvirt-cpu-simplify-failure-cleanup-paths.patch new file mode 100644 index 0000000..74ad548 --- /dev/null +++ b/SOURCES/libvirt-cpu-simplify-failure-cleanup-paths.patch @@ -0,0 +1,397 @@ +From 85d367abe6063225117cc27c85e01e36a7b70409 Mon Sep 17 00:00:00 2001 +Message-Id: <85d367abe6063225117cc27c85e01e36a7b70409@dist-git> +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Fri, 21 Jun 2019 09:24:47 +0200 +Subject: [PATCH] cpu: simplify failure cleanup paths +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Get rid of the separate 'error:' label, so all code paths jump straight +to the 'cleanup:' label. + +Reviewed-by: Jiri Denemark +Signed-off-by: Daniel P. Berrangé +(cherry picked from commit 18cab54c3a0bc72390f29300684396690a7ecf51) + +https://bugzilla.redhat.com/show_bug.cgi?id=1686895 + +Signed-off-by: Jiri Denemark +Message-Id: <40ff4abfea153cf8210286a84967c3ca7850b775.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_ppc64.c | 38 ++++++++++++------------ + src/cpu/cpu_x86.c | 71 ++++++++++++++++++++------------------------- + 2 files changed, 49 insertions(+), 60 deletions(-) + +diff --git a/src/cpu/cpu_ppc64.c b/src/cpu/cpu_ppc64.c +index 75da5b77d8..fcba7e9b37 100644 +--- a/src/cpu/cpu_ppc64.c ++++ b/src/cpu/cpu_ppc64.c +@@ -288,27 +288,28 @@ ppc64VendorParse(xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED, + { + struct ppc64_map *map = data; + struct ppc64_vendor *vendor; ++ int ret = -1; + + if (VIR_ALLOC(vendor) < 0) + return -1; + + if (VIR_STRDUP(vendor->name, name) < 0) +- goto error; ++ goto cleanup; + + if (ppc64VendorFind(map, vendor->name)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("CPU vendor %s already defined"), vendor->name); +- goto error; ++ goto cleanup; + } + + if (VIR_APPEND_ELEMENT(map->vendors, map->nvendors, vendor) < 0) +- goto error; ++ goto cleanup; + +- return 0; ++ ret = 0; + +- error: ++ cleanup: + ppc64VendorFree(vendor); +- return -1; ++ return ret; + } + + +@@ -327,15 +328,15 @@ ppc64ModelParse(xmlXPathContextPtr ctxt, + int ret = -1; + + if (VIR_ALLOC(model) < 0) +- goto error; ++ goto cleanup; + + if (VIR_STRDUP(model->name, name) < 0) +- goto error; ++ goto cleanup; + + if (ppc64ModelFind(map, model->name)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("CPU model %s already defined"), model->name); +- goto error; ++ goto cleanup; + } + + if (virXPathBoolean("boolean(./vendor)", ctxt)) { +@@ -344,14 +345,14 @@ ppc64ModelParse(xmlXPathContextPtr ctxt, + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Invalid vendor element in CPU model %s"), + model->name); +- goto error; ++ goto cleanup; + } + + if (!(model->vendor = ppc64VendorFind(map, vendor))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unknown vendor %s referenced by CPU model %s"), + vendor, model->name); +- goto error; ++ goto cleanup; + } + } + +@@ -359,11 +360,11 @@ ppc64ModelParse(xmlXPathContextPtr ctxt, + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Missing PVR information for CPU model %s"), + model->name); +- goto error; ++ goto cleanup; + } + + if (VIR_ALLOC_N(model->data.pvr, n) < 0) +- goto error; ++ goto cleanup; + + model->data.len = n; + +@@ -374,7 +375,7 @@ ppc64ModelParse(xmlXPathContextPtr ctxt, + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Missing or invalid PVR value in CPU model %s"), + model->name); +- goto error; ++ goto cleanup; + } + model->data.pvr[i].value = pvr; + +@@ -382,24 +383,21 @@ ppc64ModelParse(xmlXPathContextPtr ctxt, + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Missing or invalid PVR mask in CPU model %s"), + model->name); +- goto error; ++ goto cleanup; + } + model->data.pvr[i].mask = pvr; + } + + if (VIR_APPEND_ELEMENT(map->models, map->nmodels, model) < 0) +- goto error; ++ goto cleanup; + + ret = 0; + + cleanup: ++ ppc64ModelFree(model); + VIR_FREE(vendor); + VIR_FREE(nodes); + return ret; +- +- error: +- ppc64ModelFree(model); +- goto cleanup; + } + + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index 11dbd1e757..ce48ca6867 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -731,15 +731,15 @@ x86VendorParse(xmlXPathContextPtr ctxt, + int ret = -1; + + if (VIR_ALLOC(vendor) < 0) +- goto error; ++ goto cleanup; + + if (VIR_STRDUP(vendor->name, name) < 0) +- goto error; ++ goto cleanup; + + if (x86VendorFind(map, vendor->name)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("CPU vendor %s already defined"), vendor->name); +- goto error; ++ goto cleanup; + } + + string = virXPathString("string(@string)", ctxt); +@@ -747,24 +747,21 @@ x86VendorParse(xmlXPathContextPtr ctxt, + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Missing vendor string for CPU vendor %s"), + vendor->name); +- goto error; ++ goto cleanup; + } + + if (virCPUx86VendorToCPUID(string, &vendor->cpuid) < 0) +- goto error; ++ goto cleanup; + + if (VIR_APPEND_ELEMENT(map->vendors, map->nvendors, vendor) < 0) +- goto error; ++ goto cleanup; + + ret = 0; + + cleanup: ++ x86VendorFree(vendor); + VIR_FREE(string); + return ret; +- +- error: +- x86VendorFree(vendor); +- goto cleanup; + } + + +@@ -904,17 +901,17 @@ x86FeatureParse(xmlXPathContextPtr ctxt, + int ret = -1; + + if (!(feature = x86FeatureNew())) +- goto error; ++ goto cleanup; + + feature->migratable = true; + + if (VIR_STRDUP(feature->name, name) < 0) +- goto error; ++ goto cleanup; + + if (x86FeatureFind(map, feature->name)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("CPU feature %s already defined"), feature->name); +- goto error; ++ goto cleanup; + } + + str = virXPathString("string(@migratable)", ctxt); +@@ -923,7 +920,7 @@ x86FeatureParse(xmlXPathContextPtr ctxt, + + n = virXPathNodeSet("./cpuid", ctxt, &nodes); + if (n < 0) +- goto error; ++ goto cleanup; + + for (i = 0; i < n; i++) { + ctxt->node = nodes[i]; +@@ -931,31 +928,28 @@ x86FeatureParse(xmlXPathContextPtr ctxt, + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Invalid cpuid[%zu] in %s feature"), + i, feature->name); +- goto error; ++ goto cleanup; + } + if (virCPUx86DataAddCPUIDInt(&feature->data, &cpuid)) +- goto error; ++ goto cleanup; + } + + if (!feature->migratable && + VIR_APPEND_ELEMENT_COPY(map->migrate_blockers, + map->nblockers, + feature) < 0) +- goto error; ++ goto cleanup; + + if (VIR_APPEND_ELEMENT(map->features, map->nfeatures, feature) < 0) +- goto error; ++ goto cleanup; + + ret = 0; + + cleanup: ++ x86FeatureFree(feature); + VIR_FREE(nodes); + VIR_FREE(str); + return ret; +- +- error: +- x86FeatureFree(feature); +- goto cleanup; + } + + +@@ -1168,10 +1162,10 @@ x86ModelParse(xmlXPathContextPtr ctxt, + int ret = -1; + + if (!(model = x86ModelNew())) +- goto error; ++ goto cleanup; + + if (VIR_STRDUP(model->name, name) < 0) +- goto error; ++ goto cleanup; + + if (virXPathNode("./model", ctxt)) { + virCPUx86ModelPtr ancestor; +@@ -1182,7 +1176,7 @@ x86ModelParse(xmlXPathContextPtr ctxt, + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Missing ancestor's name in CPU model %s"), + model->name); +- goto error; ++ goto cleanup; + } + + if (!(ancestor = x86ModelFind(map, anname))) { +@@ -1190,7 +1184,7 @@ x86ModelParse(xmlXPathContextPtr ctxt, + _("Ancestor model %s not found for CPU model %s"), + anname, model->name); + VIR_FREE(anname); +- goto error; ++ goto cleanup; + } + + VIR_FREE(anname); +@@ -1198,7 +1192,7 @@ x86ModelParse(xmlXPathContextPtr ctxt, + model->vendor = ancestor->vendor; + model->signature = ancestor->signature; + if (x86DataCopy(&model->data, &ancestor->data) < 0) +- goto error; ++ goto cleanup; + } + + if (virXPathBoolean("boolean(./signature)", ctxt)) { +@@ -1211,7 +1205,7 @@ x86ModelParse(xmlXPathContextPtr ctxt, + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Invalid CPU signature family in model %s"), + model->name); +- goto error; ++ goto cleanup; + } + + rc = virXPathUInt("string(./signature/@model)", ctxt, &sigModel); +@@ -1219,7 +1213,7 @@ x86ModelParse(xmlXPathContextPtr ctxt, + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Invalid CPU signature model in model %s"), + model->name); +- goto error; ++ goto cleanup; + } + + model->signature = x86MakeSignature(sigFamily, sigModel, 0); +@@ -1231,20 +1225,20 @@ x86ModelParse(xmlXPathContextPtr ctxt, + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Invalid vendor element in CPU model %s"), + model->name); +- goto error; ++ goto cleanup; + } + + if (!(model->vendor = x86VendorFind(map, vendor))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unknown vendor %s referenced by CPU model %s"), + vendor, model->name); +- goto error; ++ goto cleanup; + } + } + + n = virXPathNodeSet("./feature", ctxt, &nodes); + if (n < 0) +- goto error; ++ goto cleanup; + + for (i = 0; i < n; i++) { + virCPUx86FeaturePtr feature; +@@ -1253,7 +1247,7 @@ x86ModelParse(xmlXPathContextPtr ctxt, + if (!(ftname = virXMLPropString(nodes[i], "name"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Missing feature name for CPU model %s"), model->name); +- goto error; ++ goto cleanup; + } + + if (!(feature = x86FeatureFind(map, ftname))) { +@@ -1261,27 +1255,24 @@ x86ModelParse(xmlXPathContextPtr ctxt, + _("Feature %s required by CPU model %s not found"), + ftname, model->name); + VIR_FREE(ftname); +- goto error; ++ goto cleanup; + } + VIR_FREE(ftname); + + if (x86DataAdd(&model->data, &feature->data)) +- goto error; ++ goto cleanup; + } + + if (VIR_APPEND_ELEMENT(map->models, map->nmodels, model) < 0) +- goto error; ++ goto cleanup; + + ret = 0; + + cleanup: ++ x86ModelFree(model); + VIR_FREE(vendor); + VIR_FREE(nodes); + return ret; +- +- error: +- x86ModelFree(model); +- goto cleanup; + } + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_conf-Introduce-virCPUDefFilterFeatures.patch b/SOURCES/libvirt-cpu_conf-Introduce-virCPUDefFilterFeatures.patch new file mode 100644 index 0000000..debce13 --- /dev/null +++ b/SOURCES/libvirt-cpu_conf-Introduce-virCPUDefFilterFeatures.patch @@ -0,0 +1,91 @@ +From 296ff8fbba31a8052bdf24e409b0bb9e3c041c8f Mon Sep 17 00:00:00 2001 +Message-Id: <296ff8fbba31a8052bdf24e409b0bb9e3c041c8f@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:46 +0200 +Subject: [PATCH] cpu_conf: Introduce virCPUDefFilterFeatures +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This new internal API can be used for in place filtering of CPU features +in virCPUDef. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit c145b660b8225f73db16660461077ef931730939) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Signed-off-by: Jiri Denemark +Message-Id: +Reviewed-by: Ján Tomko +--- + src/conf/cpu_conf.c | 22 ++++++++++++++++++++++ + src/conf/cpu_conf.h | 5 +++++ + src/libvirt_private.syms | 1 + + 3 files changed, 28 insertions(+) + +diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c +index 43a3ab5dcd..51e2a83eae 100644 +--- a/src/conf/cpu_conf.c ++++ b/src/conf/cpu_conf.c +@@ -850,6 +850,28 @@ virCPUDefFindFeature(virCPUDefPtr def, + } + + ++int ++virCPUDefFilterFeatures(virCPUDefPtr cpu, ++ virCPUDefFeatureFilter filter, ++ void *opaque) ++{ ++ size_t i = 0; ++ ++ while (i < cpu->nfeatures) { ++ if (filter(cpu->features[i].name, opaque)) { ++ i++; ++ continue; ++ } ++ ++ VIR_FREE(cpu->features[i].name); ++ if (VIR_DELETE_ELEMENT_INPLACE(cpu->features, i, cpu->nfeatures) < 0) ++ return -1; ++ } ++ ++ return 0; ++} ++ ++ + bool + virCPUDefIsEqual(virCPUDefPtr src, + virCPUDefPtr dst, +diff --git a/src/conf/cpu_conf.h b/src/conf/cpu_conf.h +index 9f2e7ee264..ad25932b9b 100644 +--- a/src/conf/cpu_conf.h ++++ b/src/conf/cpu_conf.h +@@ -220,6 +220,11 @@ virCPUFeatureDefPtr + virCPUDefFindFeature(virCPUDefPtr def, + const char *name); + ++int ++virCPUDefFilterFeatures(virCPUDefPtr cpu, ++ virCPUDefFeatureFilter filter, ++ void *opaque); ++ + virCPUDefPtr * + virCPUDefListParse(const char **xmlCPUs, + unsigned int ncpus, +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 9ebc5384fb..57508de0c1 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -76,6 +76,7 @@ virCPUDefCopy; + virCPUDefCopyModel; + virCPUDefCopyModelFilter; + virCPUDefCopyWithoutModel; ++virCPUDefFilterFeatures; + virCPUDefFindFeature; + virCPUDefFormat; + virCPUDefFormatBuf; +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_map-Add-Cascadelake-Server-CPU-model.patch b/SOURCES/libvirt-cpu_map-Add-Cascadelake-Server-CPU-model.patch new file mode 100644 index 0000000..7febd6c --- /dev/null +++ b/SOURCES/libvirt-cpu_map-Add-Cascadelake-Server-CPU-model.patch @@ -0,0 +1,211 @@ +From 6d31e77ae83bb2b29d3bff5bd08742ee4c611e25 Mon Sep 17 00:00:00 2001 +Message-Id: <6d31e77ae83bb2b29d3bff5bd08742ee4c611e25@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:21 +0200 +Subject: [PATCH] cpu_map: Add Cascadelake-Server CPU model +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Introduced in QEMU 3.1.0 by commit +c7a88b52f62b30c04158eeb07f73e3f72221b6a8 + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 2878278c74cc450a7e28a3830ed0ceff3126f12f) + +https://bugzilla.redhat.com/show_bug.cgi?id=1693433 + +Conflicts: + src/cpu_map/index.xml + src/cpu_map/x86_Cascadelake-Server.xml + - cpu_map split not backported + + tests/domaincapsschemadata/qemu_3.1.0.x86_64.xml + tests/domaincapsschemadata/qemu_4.0.0.x86_64.xml + - test data missing + + tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-guest.xml + tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-host.xml + - md-clear feature did not exist at the time of the original + patch, but downstream already has it + +Signed-off-by: Jiri Denemark +Message-Id: +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_map.xml | 81 +++++++++++++++++++ + .../x86_64-cpuid-Xeon-Platinum-8268-guest.xml | 5 +- + .../x86_64-cpuid-Xeon-Platinum-8268-host.xml | 5 +- + .../x86_64-cpuid-Xeon-Platinum-8268-json.xml | 5 +- + 4 files changed, 84 insertions(+), 12 deletions(-) + +diff --git a/src/cpu/cpu_map.xml b/src/cpu/cpu_map.xml +index b2eb07b832..9b289556e8 100644 +--- a/src/cpu/cpu_map.xml ++++ b/src/cpu/cpu_map.xml +@@ -2193,6 +2193,87 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-guest.xml b/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-guest.xml +index 2836481454..c7e8a1fccf 100644 +--- a/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-guest.xml ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-guest.xml +@@ -1,5 +1,5 @@ + +- Skylake-Server-IBRS ++ Cascadelake-Server + Intel + + +@@ -20,15 +20,12 @@ + + + +- + + + +- + + + +- + + + +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-host.xml b/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-host.xml +index 032d8ffeca..d7482751b4 100644 +--- a/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-host.xml ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-host.xml +@@ -1,6 +1,6 @@ + + x86_64 +- Skylake-Server-IBRS ++ Cascadelake-Server + Intel + + +@@ -21,15 +21,12 @@ + + + +- + + + +- + + + +- + + + +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-json.xml b/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-json.xml +index 12431de213..b7d12dced7 100644 +--- a/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-json.xml ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-json.xml +@@ -1,13 +1,10 @@ + +- Skylake-Server-IBRS ++ Cascadelake-Server + Intel + + + +- + + +- +- + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_map-Add-hex-representation-of-signatures.patch b/SOURCES/libvirt-cpu_map-Add-hex-representation-of-signatures.patch new file mode 100644 index 0000000..3319ca2 --- /dev/null +++ b/SOURCES/libvirt-cpu_map-Add-hex-representation-of-signatures.patch @@ -0,0 +1,318 @@ +From 83a1114820c95f9cd98789b14044a229dcc090a7 Mon Sep 17 00:00:00 2001 +Message-Id: <83a1114820c95f9cd98789b14044a229dcc090a7@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:07 +0200 +Subject: [PATCH] cpu_map: Add hex representation of signatures +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The family/model numbers are nice for humans or for comparing with +/proc/cpuinfo, but sometimes there's a need to see the CPUID +representation of the signature. Let's add it into a comment for each +signature in out cpu_map XMLs as the conversion is not exactly +straightforward. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 61be05a00fd383f11070761fac5ae28272b784dd) + +https://bugzilla.redhat.com/show_bug.cgi?id=1686895 + +Conflicts: + src/cpu/cpu_map.xml + - the cpu_map split was not backported + +Signed-off-by: Jiri Denemark +Message-Id: +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_map.xml | 62 ++++++++++++++++++++++----------------------- + 1 file changed, 31 insertions(+), 31 deletions(-) + +diff --git a/src/cpu/cpu_map.xml b/src/cpu/cpu_map.xml +index a9f284fbbe..a5a5290a09 100644 +--- a/src/cpu/cpu_map.xml ++++ b/src/cpu/cpu_map.xml +@@ -828,7 +828,7 @@ + + + +- ++ + + + +@@ -860,7 +860,7 @@ + + + +- ++ + + + +@@ -894,7 +894,7 @@ + + + +- ++ + + + +@@ -930,7 +930,7 @@ + + + +- ++ + + + +@@ -967,7 +967,7 @@ + + + +- ++ + + + +@@ -1004,7 +1004,7 @@ + + + +- ++ + + + +@@ -1042,7 +1042,7 @@ + + + +- ++ + + + +@@ -1085,7 +1085,7 @@ + + + +- ++ + + + +@@ -1129,7 +1129,7 @@ + + + +- ++ + + + +@@ -1178,7 +1178,7 @@ + + + +- ++ + + + +@@ -1228,7 +1228,7 @@ + + + +- ++ + + + +@@ -1281,7 +1281,7 @@ + + + +- ++ + + + +@@ -1335,7 +1335,7 @@ + + + +- ++ + + + +@@ -1390,7 +1390,7 @@ + + + +- ++ + + + +@@ -1446,7 +1446,7 @@ + + + +- ++ + + + +@@ -1503,7 +1503,7 @@ + + + +- ++ + + + +@@ -1561,7 +1561,7 @@ + + + +- ++ + + + +@@ -1620,7 +1620,7 @@ + + + +- ++ + + + +@@ -1680,7 +1680,7 @@ + + + +- ++ + + + +@@ -1748,7 +1748,7 @@ + + + +- ++ + + + +@@ -1817,7 +1817,7 @@ + + + +- ++ + + + +@@ -1892,7 +1892,7 @@ + + + +- ++ + + + +@@ -1968,7 +1968,7 @@ + + + +- ++ + + + +@@ -2052,7 +2052,7 @@ + + + +- ++ + + + +@@ -2209,7 +2209,7 @@ + + + +- ++ + + + +@@ -2239,7 +2239,7 @@ + + + +- ++ + + + +@@ -2273,7 +2273,7 @@ + + + +- ++ + + + +@@ -2312,7 +2312,7 @@ + + + +- ++ + + + +@@ -2361,7 +2361,7 @@ + + + +- ++ + + + +@@ -2413,7 +2413,7 @@ + + + +- ++ + + + +@@ -2484,7 +2484,7 @@ + + + +- ++ + + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_map-Add-more-signatures-for-Broadwell-CPU-models.patch b/SOURCES/libvirt-cpu_map-Add-more-signatures-for-Broadwell-CPU-models.patch new file mode 100644 index 0000000..5a1e320 --- /dev/null +++ b/SOURCES/libvirt-cpu_map-Add-more-signatures-for-Broadwell-CPU-models.patch @@ -0,0 +1,254 @@ +From 77ad41e460c2e91f2c2e187c80581069654b741d Mon Sep 17 00:00:00 2001 +Message-Id: <77ad41e460c2e91f2c2e187c80581069654b741d@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:16 +0200 +Subject: [PATCH] cpu_map: Add more signatures for Broadwell CPU models +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This fixes several CPUs which were incorrectly detected as +Skylake-Client. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 4ff74a806ad42820eef3877c8ec146770914d8df) + +https://bugzilla.redhat.com/show_bug.cgi?id=1686895 + +Conflicts: + src/cpu_map/x86_Broadwell-IBRS.xml + src/cpu_map/x86_Broadwell-noTSX-IBRS.xml + src/cpu_map/x86_Broadwell-noTSX.xml + src/cpu_map/x86_Broadwell.xml + - cpu_map split not backported + +Signed-off-by: Jiri Denemark +Message-Id: <543534b544d2d09470c218aeb6c7d945facaf2c8.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_map.xml | 12 ++++++++++++ + .../x86_64-cpuid-Xeon-E5-2623-v4-guest.xml | 11 +++++++---- + .../x86_64-cpuid-Xeon-E5-2623-v4-json.xml | 11 +++++++---- + .../x86_64-cpuid-Xeon-E5-2630-v4-guest.xml | 11 +++++++---- + .../x86_64-cpuid-Xeon-E5-2630-v4-json.xml | 11 +++++++---- + .../x86_64-cpuid-Xeon-E5-2650-v4-guest.xml | 11 +++++++---- + .../x86_64-cpuid-Xeon-E5-2650-v4-json.xml | 11 +++++++---- + 7 files changed, 54 insertions(+), 24 deletions(-) + +diff --git a/src/cpu/cpu_map.xml b/src/cpu/cpu_map.xml +index ed6006643b..04369d1eda 100644 +--- a/src/cpu/cpu_map.xml ++++ b/src/cpu/cpu_map.xml +@@ -1473,6 +1473,9 @@ + + + ++ ++ ++ + + + +@@ -1530,6 +1533,9 @@ + + + ++ ++ ++ + + + +@@ -1588,6 +1594,9 @@ + + + ++ ++ ++ + + + +@@ -1647,6 +1656,9 @@ + + + ++ ++ ++ + + + +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 7718d7ca59..a5c6d9b471 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 +@@ -1,6 +1,7 @@ + +- Skylake-Client-IBRS ++ Broadwell-IBRS + Intel ++ + + + +@@ -18,15 +19,17 @@ + + + ++ ++ ++ + + + + ++ + + + ++ + +- +- +- + +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2623-v4-json.xml b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2623-v4-json.xml +index 167a9028ab..de082dbd93 100644 +--- a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2623-v4-json.xml ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2623-v4-json.xml +@@ -1,11 +1,14 @@ + +- Skylake-Client-IBRS ++ Broadwell-IBRS + Intel ++ + ++ ++ + ++ + ++ + +- +- +- ++ + +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4-guest.xml b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4-guest.xml +index cd7e25b52a..e2999db8e9 100644 +--- a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4-guest.xml ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4-guest.xml +@@ -1,6 +1,7 @@ + +- Skylake-Client ++ Broadwell + Intel ++ + + + +@@ -18,14 +19,16 @@ + + + ++ ++ ++ + + + ++ + + + ++ + +- +- +- + +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4-json.xml b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4-json.xml +index 5dfce947b2..5b8891093a 100644 +--- a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4-json.xml ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4-json.xml +@@ -1,11 +1,14 @@ + +- Skylake-Client ++ Broadwell + Intel ++ + ++ ++ + ++ + ++ + +- +- +- ++ + +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-v4-guest.xml b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-v4-guest.xml +index cd7e25b52a..e2999db8e9 100644 +--- a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-v4-guest.xml ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-v4-guest.xml +@@ -1,6 +1,7 @@ + +- Skylake-Client ++ Broadwell + Intel ++ + + + +@@ -18,14 +19,16 @@ + + + ++ ++ ++ + + + ++ + + + ++ + +- +- +- + +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-v4-json.xml b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-v4-json.xml +index 5dfce947b2..5b8891093a 100644 +--- a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-v4-json.xml ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-v4-json.xml +@@ -1,11 +1,14 @@ + +- Skylake-Client ++ Broadwell + Intel ++ + ++ ++ + ++ + ++ + +- +- +- ++ + +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_map-Add-more-signatures-for-Conroe-CPU-model.patch b/SOURCES/libvirt-cpu_map-Add-more-signatures-for-Conroe-CPU-model.patch new file mode 100644 index 0000000..677455f --- /dev/null +++ b/SOURCES/libvirt-cpu_map-Add-more-signatures-for-Conroe-CPU-model.patch @@ -0,0 +1,41 @@ +From 93520cb5f3b412c8cb4b5cf7098ff4a8c6c819ab Mon Sep 17 00:00:00 2001 +Message-Id: <93520cb5f3b412c8cb4b5cf7098ff4a8c6c819ab@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:09 +0200 +Subject: [PATCH] cpu_map: Add more signatures for Conroe CPU model +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit c1f6a3269c595e7d3d0c9cf31ef7e6cf88291056) + +https://bugzilla.redhat.com/show_bug.cgi?id=1686895 + +Conflicts: + src/cpu_map/x86_Conroe.xml + - cpu_map split not backported + +Signed-off-by: Jiri Denemark +Message-Id: +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_map.xml | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/cpu/cpu_map.xml b/src/cpu/cpu_map.xml +index a5a5290a09..1699aec2cf 100644 +--- a/src/cpu/cpu_map.xml ++++ b/src/cpu/cpu_map.xml +@@ -829,6 +829,7 @@ + + + ++ + + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_map-Add-more-signatures-for-Haswell-CPU-models.patch b/SOURCES/libvirt-cpu_map-Add-more-signatures-for-Haswell-CPU-models.patch new file mode 100644 index 0000000..a2782c6 --- /dev/null +++ b/SOURCES/libvirt-cpu_map-Add-more-signatures-for-Haswell-CPU-models.patch @@ -0,0 +1,76 @@ +From 41472ea4967eed29a41f619aca9c3d78504d0031 Mon Sep 17 00:00:00 2001 +Message-Id: <41472ea4967eed29a41f619aca9c3d78504d0031@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:15 +0200 +Subject: [PATCH] cpu_map: Add more signatures for Haswell CPU models +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit e58ca588cc0deee36c8ae44f2ad75bf9b1680fc5) + +https://bugzilla.redhat.com/show_bug.cgi?id=1686895 + +Conflicts: + src/cpu_map/x86_Haswell-IBRS.xml + src/cpu_map/x86_Haswell-noTSX-IBRS.xml + src/cpu_map/x86_Haswell-noTSX.xml + src/cpu_map/x86_Haswell.xml + - cpu_map split not backported + +Signed-off-by: Jiri Denemark +Message-Id: +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_map.xml | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/src/cpu/cpu_map.xml b/src/cpu/cpu_map.xml +index 9bd8bbbfbb..ed6006643b 100644 +--- a/src/cpu/cpu_map.xml ++++ b/src/cpu/cpu_map.xml +@@ -1243,6 +1243,9 @@ + + + ++ ++ ++ + + + +@@ -1296,6 +1299,9 @@ + + + ++ ++ ++ + + + +@@ -1350,6 +1356,9 @@ + + + ++ ++ ++ + + + +@@ -1405,6 +1414,9 @@ + + + ++ ++ ++ + + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_map-Add-more-signatures-for-IvyBridge-CPU-models.patch b/SOURCES/libvirt-cpu_map-Add-more-signatures-for-IvyBridge-CPU-models.patch new file mode 100644 index 0000000..9f0f253 --- /dev/null +++ b/SOURCES/libvirt-cpu_map-Add-more-signatures-for-IvyBridge-CPU-models.patch @@ -0,0 +1,50 @@ +From 182faff133a2a21d6ce9fb2d2f2a59c10bded7a4 Mon Sep 17 00:00:00 2001 +Message-Id: <182faff133a2a21d6ce9fb2d2f2a59c10bded7a4@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:14 +0200 +Subject: [PATCH] cpu_map: Add more signatures for IvyBridge CPU models +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 194105fef1a3a8645486df3323e460cc4a9b2d4c) + +https://bugzilla.redhat.com/show_bug.cgi?id=1686895 + +Conflicts: + src/cpu_map/x86_IvyBridge-IBRS.xml + src/cpu_map/x86_IvyBridge.xml + - cpu_map split not backported + +Signed-off-by: Jiri Denemark +Message-Id: <07778daea0841ab2e211311adc90fd04967b2fb3.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_map.xml | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/cpu/cpu_map.xml b/src/cpu/cpu_map.xml +index 9eaba9572c..9bd8bbbfbb 100644 +--- a/src/cpu/cpu_map.xml ++++ b/src/cpu/cpu_map.xml +@@ -1142,6 +1142,7 @@ + + + ++ + + + +@@ -1191,6 +1192,7 @@ + + + ++ + + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_map-Add-more-signatures-for-Nehalem-CPU-models.patch b/SOURCES/libvirt-cpu_map-Add-more-signatures-for-Nehalem-CPU-models.patch new file mode 100644 index 0000000..ef1931e --- /dev/null +++ b/SOURCES/libvirt-cpu_map-Add-more-signatures-for-Nehalem-CPU-models.patch @@ -0,0 +1,54 @@ +From 72bcfcf07c76288e943602995308d3e505aa1cff Mon Sep 17 00:00:00 2001 +Message-Id: <72bcfcf07c76288e943602995308d3e505aa1cff@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:11 +0200 +Subject: [PATCH] cpu_map: Add more signatures for Nehalem CPU models +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit f349f3c53f6427d9955ab7c57900c094f06dfd87) + +https://bugzilla.redhat.com/show_bug.cgi?id=1686895 + +Conflicts: + src/cpu_map/x86_Nehalem-IBRS.xml + src/cpu_map/x86_Nehalem.xml + - cpu_map split not backported + +Signed-off-by: Jiri Denemark +Message-Id: <6351ae62d5ea091e831968cd1fc50176d1552a86.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_map.xml | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/cpu/cpu_map.xml b/src/cpu/cpu_map.xml +index f42b2e629c..4f9c247f3e 100644 +--- a/src/cpu/cpu_map.xml ++++ b/src/cpu/cpu_map.xml +@@ -897,6 +897,9 @@ + + + ++ ++ ++ + + + +@@ -933,6 +936,9 @@ + + + ++ ++ ++ + + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_map-Add-more-signatures-for-Penryn-CPU-model.patch b/SOURCES/libvirt-cpu_map-Add-more-signatures-for-Penryn-CPU-model.patch new file mode 100644 index 0000000..ff07b98 --- /dev/null +++ b/SOURCES/libvirt-cpu_map-Add-more-signatures-for-Penryn-CPU-model.patch @@ -0,0 +1,41 @@ +From 4042ef3cf2a0221d4c59a5adc9051ee9ae41aa7d Mon Sep 17 00:00:00 2001 +Message-Id: <4042ef3cf2a0221d4c59a5adc9051ee9ae41aa7d@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:10 +0200 +Subject: [PATCH] cpu_map: Add more signatures for Penryn CPU model +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 0a09e59457f843b53c2702d1936bca6513868320) + +https://bugzilla.redhat.com/show_bug.cgi?id=1686895 + +Conflicts: + src/cpu_map/x86_Penryn.xml + - cpu_map split not backported + +Signed-off-by: Jiri Denemark +Message-Id: <1604252f9ef65cfb55161a0f8329ee6868926814.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_map.xml | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/cpu/cpu_map.xml b/src/cpu/cpu_map.xml +index 1699aec2cf..f42b2e629c 100644 +--- a/src/cpu/cpu_map.xml ++++ b/src/cpu/cpu_map.xml +@@ -862,6 +862,7 @@ + + + ++ + + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_map-Add-more-signatures-for-SandyBridge-CPU-models.patch b/SOURCES/libvirt-cpu_map-Add-more-signatures-for-SandyBridge-CPU-models.patch new file mode 100644 index 0000000..5685e1c --- /dev/null +++ b/SOURCES/libvirt-cpu_map-Add-more-signatures-for-SandyBridge-CPU-models.patch @@ -0,0 +1,50 @@ +From 250d216f3f9f033ec39b2116b30c93b37967484c Mon Sep 17 00:00:00 2001 +Message-Id: <250d216f3f9f033ec39b2116b30c93b37967484c@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:13 +0200 +Subject: [PATCH] cpu_map: Add more signatures for SandyBridge CPU models +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 4a3c3682f3da4ae1e1036c67db7ddba3dcc66d68) + +https://bugzilla.redhat.com/show_bug.cgi?id=1686895 + +Conflicts: + src/cpu_map/x86_SandyBridge-IBRS.xml + src/cpu_map/x86_SandyBridge.xml + - cpu_map split not backported + +Signed-off-by: Jiri Denemark +Message-Id: <521680181b58a762b0d6b3668e0d162fbc5d3cf9.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_map.xml | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/cpu/cpu_map.xml b/src/cpu/cpu_map.xml +index fed0f51934..9eaba9572c 100644 +--- a/src/cpu/cpu_map.xml ++++ b/src/cpu/cpu_map.xml +@@ -1053,6 +1053,7 @@ + + + ++ + + + +@@ -1096,6 +1097,7 @@ + + + ++ + + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_map-Add-more-signatures-for-Skylake-Client-CPU-models.patch b/SOURCES/libvirt-cpu_map-Add-more-signatures-for-Skylake-Client-CPU-models.patch new file mode 100644 index 0000000..4672c57 --- /dev/null +++ b/SOURCES/libvirt-cpu_map-Add-more-signatures-for-Skylake-Client-CPU-models.patch @@ -0,0 +1,58 @@ +From f1a00c505aac83fe04f5385db5a9ed4768b0222b Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:17 +0200 +Subject: [PATCH] cpu_map: Add more signatures for Skylake-Client CPU models +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 367d96a5d6b04bf25d025ed59a7079d71f843c56) + +https://bugzilla.redhat.com/show_bug.cgi?id=1686895 + +Conflicts: + src/cpu_map/x86_Skylake-Client-IBRS.xml + src/cpu_map/x86_Skylake-Client.xml + - cpu_map split not backported + +Signed-off-by: Jiri Denemark +Message-Id: +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_map.xml | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/src/cpu/cpu_map.xml b/src/cpu/cpu_map.xml +index 04369d1eda..b2eb07b832 100644 +--- a/src/cpu/cpu_map.xml ++++ b/src/cpu/cpu_map.xml +@@ -1719,6 +1719,11 @@ + + + ++ ++ ++ ++ + + + +@@ -1787,6 +1792,11 @@ + + + ++ ++ ++ ++ + + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_map-Add-more-signatures-for-Westmere-CPU-model.patch b/SOURCES/libvirt-cpu_map-Add-more-signatures-for-Westmere-CPU-model.patch new file mode 100644 index 0000000..ab8878e --- /dev/null +++ b/SOURCES/libvirt-cpu_map-Add-more-signatures-for-Westmere-CPU-model.patch @@ -0,0 +1,184 @@ +From d31a3ba6c9396f8ede2966d49030e9b4011be636 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:12 +0200 +Subject: [PATCH] cpu_map: Add more signatures for Westmere CPU model +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This fixes several CPUs which were incorrectly detected as a different +CPU model. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit e89f87721406f6ad6e811ff613a22dc804d69355) + +https://bugzilla.redhat.com/show_bug.cgi?id=1686895 + +Conflicts: + src/cpu_map/x86_Westmere.xml + - cpu_map split not backported + +Signed-off-by: Jiri Denemark +Message-Id: +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_map.xml | 2 ++ + tests/cputestdata/x86_64-cpuid-Core-i5-650-json.xml | 9 +++++---- + tests/cputestdata/x86_64-cpuid-Pentium-P6100-guest.xml | 10 ++++++---- + tests/cputestdata/x86_64-cpuid-Xeon-E7-4820-guest.xml | 8 ++++---- + tests/cputestdata/x86_64-cpuid-Xeon-E7-4820-json.xml | 8 +++++--- + tests/cputestdata/x86_64-cpuid-Xeon-E7-4830-json.xml | 9 +++++---- + 6 files changed, 27 insertions(+), 19 deletions(-) + +diff --git a/src/cpu/cpu_map.xml b/src/cpu/cpu_map.xml +index 4f9c247f3e..fed0f51934 100644 +--- a/src/cpu/cpu_map.xml ++++ b/src/cpu/cpu_map.xml +@@ -976,6 +976,8 @@ + + + ++ ++ + + + +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i5-650-json.xml b/tests/cputestdata/x86_64-cpuid-Core-i5-650-json.xml +index f5980f53e5..cb21e48a9f 100644 +--- a/tests/cputestdata/x86_64-cpuid-Core-i5-650-json.xml ++++ b/tests/cputestdata/x86_64-cpuid-Core-i5-650-json.xml +@@ -1,12 +1,13 @@ + +- SandyBridge ++ Westmere + Intel + + ++ ++ ++ + + + +- +- +- ++ + +diff --git a/tests/cputestdata/x86_64-cpuid-Pentium-P6100-guest.xml b/tests/cputestdata/x86_64-cpuid-Pentium-P6100-guest.xml +index db5e0ae6af..20e2fa363a 100644 +--- a/tests/cputestdata/x86_64-cpuid-Pentium-P6100-guest.xml ++++ b/tests/cputestdata/x86_64-cpuid-Pentium-P6100-guest.xml +@@ -1,6 +1,7 @@ + +- core2duo ++ Westmere + Intel ++ + + + +@@ -8,16 +9,17 @@ + + + ++ + + + +- + + + +- + + +- + ++ ++ ++ + +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E7-4820-guest.xml b/tests/cputestdata/x86_64-cpuid-Xeon-E7-4820-guest.xml +index dbf8580a0e..659779687a 100644 +--- a/tests/cputestdata/x86_64-cpuid-Xeon-E7-4820-guest.xml ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E7-4820-guest.xml +@@ -1,5 +1,5 @@ + +- SandyBridge ++ Westmere + Intel + + +@@ -8,6 +8,7 @@ + + + ++ + + + +@@ -19,10 +20,9 @@ + + + ++ + + ++ + +- +- +- + +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E7-4820-json.xml b/tests/cputestdata/x86_64-cpuid-Xeon-E7-4820-json.xml +index d94a330f37..e8b74c5c30 100644 +--- a/tests/cputestdata/x86_64-cpuid-Xeon-E7-4820-json.xml ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E7-4820-json.xml +@@ -1,12 +1,14 @@ + +- SandyBridge ++ Westmere + Intel + + ++ + ++ ++ + + + +- +- ++ + +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E7-4830-json.xml b/tests/cputestdata/x86_64-cpuid-Xeon-E7-4830-json.xml +index aae32bd7e2..da949ad25e 100644 +--- a/tests/cputestdata/x86_64-cpuid-Xeon-E7-4830-json.xml ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E7-4830-json.xml +@@ -1,14 +1,15 @@ + +- SandyBridge ++ Westmere + Intel + + ++ + ++ ++ + + + + +- +- +- ++ + +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_map-Add-support-for-arch-capabilities-feature.patch b/SOURCES/libvirt-cpu_map-Add-support-for-arch-capabilities-feature.patch new file mode 100644 index 0000000..e84978d --- /dev/null +++ b/SOURCES/libvirt-cpu_map-Add-support-for-arch-capabilities-feature.patch @@ -0,0 +1,110 @@ +From bd665085c2cd890f2249042f135b7a1735932d1b Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:24:48 +0200 +Subject: [PATCH] cpu_map: Add support for arch-capabilities feature +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The feature was added to QEMU in 3.1.0 and it is currently blocking +migration, which is expected to change in the future. Luckily 3.1.0 is +new enough to give us migratability hints on each feature via +query-cpu-model-expension, which means we don't need to use the +"migratable" attribute on the CPU map XML. + +The kernel calls this feature arch_capabilities and RHEL/CentOS 7.* use +arch-facilities. Apparently some CPU test files were gathered with the +RHEL version of QEMU. Let's update the test files to avoid possible +confusion about the correct naming. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 511df17aec36385320dbcc088ba85968537d1d42) + +https://bugzilla.redhat.com/show_bug.cgi?id=1693433 + +Conflicts: + src/cpu_map/x86_features.xml + - cpu_map split was not backported + +Signed-off-by: Jiri Denemark +Message-Id: +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_map.xml | 3 +++ + tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb.json | 2 +- + tests/cputestdata/x86_64-cpuid-Xeon-E5-2609-v3.json | 2 +- + tests/cputestdata/x86_64-cpuid-Xeon-E5-2623-v4.json | 2 +- + tests/cputestdata/x86_64-cpuid-Xeon-Gold-5115.json | 2 +- + 5 files changed, 7 insertions(+), 4 deletions(-) + +diff --git a/src/cpu/cpu_map.xml b/src/cpu/cpu_map.xml +index ceee0ae489..a9f284fbbe 100644 +--- a/src/cpu/cpu_map.xml ++++ b/src/cpu/cpu_map.xml +@@ -337,6 +337,9 @@ + + + ++ ++ ++ + + + +diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb.json b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb.json +index 94a60fcc8f..1f53bb8bf3 100644 +--- a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb.json ++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb.json +@@ -232,7 +232,7 @@ + "avx512vbmi": false, + "kvm-asyncpf": true, + "spec-ctrl": false, +- "arch-facilities": false, ++ "arch-capabilities": false, + "model": 1, + "node-id": -1 + } +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2609-v3.json b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2609-v3.json +index 10c5434263..6bdaf6e83a 100644 +--- a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2609-v3.json ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2609-v3.json +@@ -232,7 +232,7 @@ + "avx512vbmi": false, + "kvm-asyncpf": true, + "spec-ctrl": true, +- "arch-facilities": false, ++ "arch-capabilities": false, + "model": 63, + "node-id": -1 + } +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2623-v4.json b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2623-v4.json +index 0506dec0a7..2c6be20768 100644 +--- a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2623-v4.json ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2623-v4.json +@@ -232,7 +232,7 @@ + "avx512vbmi": false, + "kvm-asyncpf": true, + "spec-ctrl": true, +- "arch-facilities": false, ++ "arch-capabilities": false, + "model": 79, + "node-id": -1 + } +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-Gold-5115.json b/tests/cputestdata/x86_64-cpuid-Xeon-Gold-5115.json +index 79f3580219..79b47a56fb 100644 +--- a/tests/cputestdata/x86_64-cpuid-Xeon-Gold-5115.json ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-Gold-5115.json +@@ -232,7 +232,7 @@ + "avx512vbmi": false, + "kvm-asyncpf": true, + "spec-ctrl": true, +- "arch-facilities": false, ++ "arch-capabilities": false, + "model": 85, + "node-id": -1 + } +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_map-Add-support-for-cldemote-CPU-feature.patch b/SOURCES/libvirt-cpu_map-Add-support-for-cldemote-CPU-feature.patch new file mode 100644 index 0000000..913e7e7 --- /dev/null +++ b/SOURCES/libvirt-cpu_map-Add-support-for-cldemote-CPU-feature.patch @@ -0,0 +1,46 @@ +From e7f71788bb7c3534b97fe50b05212e64aa9d1412 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jiri Denemark +Date: Thu, 25 Apr 2019 16:36:43 +0200 +Subject: [PATCH] cpu_map: Add support for cldemote CPU feature +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Added in QEMU by v2.12.0-481-g0da0fb0628 (released in 3.0). + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 8feeee9ee23f0500cc2585e1b11231c54de8e93d) + +https://bugzilla.redhat.com/show_bug.cgi?id=1537731 +https://bugzilla.redhat.com/show_bug.cgi?id=1537777 + +Conflicts: + src/cpu_map/x86_features.xml + - features are defined in src/cpu/cpu_map.xml downstream + +Signed-off-by: Jiri Denemark +Message-Id: +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_map.xml | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/cpu/cpu_map.xml b/src/cpu/cpu_map.xml +index 095d49a69a..79c40cff34 100644 +--- a/src/cpu/cpu_map.xml ++++ b/src/cpu/cpu_map.xml +@@ -315,6 +315,9 @@ + + + ++ ++ ++ + + + +-- +2.21.0 + diff --git a/SOURCES/libvirt-cpu_map-Define-md-clear-CPUID-bit.patch b/SOURCES/libvirt-cpu_map-Define-md-clear-CPUID-bit.patch index 856d764..61a7eec 100644 --- a/SOURCES/libvirt-cpu_map-Define-md-clear-CPUID-bit.patch +++ b/SOURCES/libvirt-cpu_map-Define-md-clear-CPUID-bit.patch @@ -1,5 +1,5 @@ -From 9ee392a5b6700c0aca597338106f2bd02ef9c4ec Mon Sep 17 00:00:00 2001 -Message-Id: <9ee392a5b6700c0aca597338106f2bd02ef9c4ec@dist-git> +From 28c9a09d1f42513344c546ac344f90ae3280fd5b Mon Sep 17 00:00:00 2001 +Message-Id: <28c9a09d1f42513344c546ac344f90ae3280fd5b@dist-git> From: Jiri Denemark Date: Fri, 5 Apr 2019 15:11:20 +0200 Subject: [PATCH] cpu_map: Define md-clear CPUID bit @@ -7,7 +7,7 @@ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -CVE-2018-11091, CVE-2018-12126, CVE-2018-12127, CVE-2018-12130 +CVE-2018-12126, CVE-2018-12127, CVE-2018-12130, CVE-2019-11091 The bit is set when microcode provides the mechanism to invoke a flush of various exploitable CPU buffers by invoking the VERW instruction. @@ -15,7 +15,7 @@ of various exploitable CPU buffers by invoking the VERW instruction. Signed-off-by: Paolo Bonzini Signed-off-by: Jiri Denemark Reviewed-by: Daniel P. Berrangé -(cherry picked from a private commit) +(cherry picked from commit 538d873571d7a682852dc1d70e5f4478f4d64e85) Conflicts: src/cpu_map/x86_features.xml @@ -35,10 +35,10 @@ Signed-off-by: Jiri Denemark 5 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/cpu/cpu_map.xml b/src/cpu/cpu_map.xml -index 095d49a69a..2f77e5cc7f 100644 +index 79c40cff34..ceee0ae489 100644 --- a/src/cpu/cpu_map.xml +++ b/src/cpu/cpu_map.xml -@@ -322,6 +322,9 @@ +@@ -325,6 +325,9 @@ diff --git a/SOURCES/libvirt-cpu_map-Introduce-IA32_ARCH_CAPABILITIES-MSR-features.patch b/SOURCES/libvirt-cpu_map-Introduce-IA32_ARCH_CAPABILITIES-MSR-features.patch new file mode 100644 index 0000000..945e56f --- /dev/null +++ b/SOURCES/libvirt-cpu_map-Introduce-IA32_ARCH_CAPABILITIES-MSR-features.patch @@ -0,0 +1,155 @@ +From 0c781b84fe81ca2d4865e92d6c22dafcea62261c Mon Sep 17 00:00:00 2001 +Message-Id: <0c781b84fe81ca2d4865e92d6c22dafcea62261c@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:26:10 +0200 +Subject: [PATCH] cpu_map: Introduce IA32_ARCH_CAPABILITIES MSR features +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit c8ec678fd9d97189667c0121f48a220dd26856b7) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Conflicts: + src/cpu_map/x86_features.xml + - cpu_map XML is not split downstream + + tests/domaincapsschemadata/qemu_3.1.0.x86_64.xml + tests/domaincapsschemadata/qemu_4.0.0.x86_64.xml + - missing + + tests/domaincapsschemadata/qemu_4.1.0.x86_64.xml + - commit 4586b11bed9bc59ea749e28f522bf5e0b462c4c7 not + backported + +Signed-off-by: Jiri Denemark +Message-Id: +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_map.xml | 20 +++++++++++++++++++ + .../x86_64-cpuid-Core-i7-7600U-enabled.xml | 1 + + .../x86_64-cpuid-Core-i7-7600U-json.xml | 1 + + ...86_64-cpuid-Xeon-Platinum-8268-enabled.xml | 1 + + .../x86_64-cpuid-Xeon-Platinum-8268-guest.xml | 4 ++++ + .../x86_64-cpuid-Xeon-Platinum-8268-host.xml | 4 ++++ + .../x86_64-cpuid-Xeon-Platinum-8268-json.xml | 3 +++ + .../qemu_4.1.0.x86_64.xml | 1 + + 8 files changed, 35 insertions(+) + +diff --git a/src/cpu/cpu_map.xml b/src/cpu/cpu_map.xml +index 9b289556e8..acd9dad7dc 100644 +--- a/src/cpu/cpu_map.xml ++++ b/src/cpu/cpu_map.xml +@@ -482,6 +482,26 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-7600U-enabled.xml b/tests/cputestdata/x86_64-cpuid-Core-i7-7600U-enabled.xml +index b1cdaa802a..58bc84577c 100644 +--- a/tests/cputestdata/x86_64-cpuid-Core-i7-7600U-enabled.xml ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-7600U-enabled.xml +@@ -5,4 +5,5 @@ + + + ++ + +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-7600U-json.xml b/tests/cputestdata/x86_64-cpuid-Core-i7-7600U-json.xml +index 48089c6003..690081493b 100644 +--- a/tests/cputestdata/x86_64-cpuid-Core-i7-7600U-json.xml ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-7600U-json.xml +@@ -10,4 +10,5 @@ + + + ++ + +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-enabled.xml b/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-enabled.xml +index 434ac1956a..313009b156 100644 +--- a/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-enabled.xml ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-enabled.xml +@@ -5,4 +5,5 @@ + + + ++ + +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-guest.xml b/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-guest.xml +index c7e8a1fccf..988fb1dbdc 100644 +--- a/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-guest.xml ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-guest.xml +@@ -30,4 +30,8 @@ + + + ++ ++ ++ ++ + +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-host.xml b/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-host.xml +index d7482751b4..fdeafc4870 100644 +--- a/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-host.xml ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-host.xml +@@ -31,4 +31,8 @@ + + + ++ ++ ++ ++ + +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-json.xml b/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-json.xml +index b7d12dced7..78863c61d1 100644 +--- a/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-json.xml ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-json.xml +@@ -7,4 +7,7 @@ + + + ++ ++ ++ + +diff --git a/tests/domaincapsschemadata/qemu_4.1.0.x86_64.xml b/tests/domaincapsschemadata/qemu_4.1.0.x86_64.xml +index 47aed6a43a..63ae7957c4 100644 +--- a/tests/domaincapsschemadata/qemu_4.1.0.x86_64.xml ++++ b/tests/domaincapsschemadata/qemu_4.1.0.x86_64.xml +@@ -34,6 +34,7 @@ + + + ++ + + + qemu64 +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_x86-Add-support-for-storing-MSR-features-in-CPU-map.patch b/SOURCES/libvirt-cpu_x86-Add-support-for-storing-MSR-features-in-CPU-map.patch new file mode 100644 index 0000000..8f72765 --- /dev/null +++ b/SOURCES/libvirt-cpu_x86-Add-support-for-storing-MSR-features-in-CPU-map.patch @@ -0,0 +1,328 @@ +From 808b0c73134cd3c6a7fdd387fd9654dbd41356ac Mon Sep 17 00:00:00 2001 +Message-Id: <808b0c73134cd3c6a7fdd387fd9654dbd41356ac@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:39 +0200 +Subject: [PATCH] cpu_x86: Add support for storing MSR features in CPU map +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit fcf4846a6bb902a5cd2230fff2a1e7591dcb7456) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Conflicts: + tests/cputestdata/cpu-cpuid.py + - no need to update this script downstream + +Signed-off-by: Jiri Denemark +Message-Id: <0c37dabaaa6c2559b48918ca55e170750fe34ea0.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_x86.c | 127 +++++++++++++++++++++++++++++++++++++---- + src/cpu/cpu_x86_data.h | 10 ++++ + 2 files changed, 125 insertions(+), 12 deletions(-) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index e6da974b31..49562944c1 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -197,6 +197,8 @@ virCPUx86DataItemMatch(const virCPUx86DataItem *item1, + { + const virCPUx86CPUID *cpuid1; + const virCPUx86CPUID *cpuid2; ++ const virCPUx86MSR *msr1; ++ const virCPUx86MSR *msr2; + + switch (item1->type) { + case VIR_CPU_X86_DATA_CPUID: +@@ -207,6 +209,12 @@ virCPUx86DataItemMatch(const virCPUx86DataItem *item1, + cpuid1->ecx == cpuid2->ecx && + cpuid1->edx == cpuid2->edx); + ++ case VIR_CPU_X86_DATA_MSR: ++ msr1 = &item1->data.msr; ++ msr2 = &item2->data.msr; ++ return (msr1->eax == msr2->eax && ++ msr1->edx == msr2->edx); ++ + case VIR_CPU_X86_DATA_NONE: + default: + return false; +@@ -220,6 +228,8 @@ virCPUx86DataItemMatchMasked(const virCPUx86DataItem *item, + { + const virCPUx86CPUID *cpuid; + const virCPUx86CPUID *cpuidMask; ++ const virCPUx86MSR *msr; ++ const virCPUx86MSR *msrMask; + + switch (item->type) { + case VIR_CPU_X86_DATA_CPUID: +@@ -230,6 +240,12 @@ virCPUx86DataItemMatchMasked(const virCPUx86DataItem *item, + (cpuid->ecx & cpuidMask->ecx) == cpuidMask->ecx && + (cpuid->edx & cpuidMask->edx) == cpuidMask->edx); + ++ case VIR_CPU_X86_DATA_MSR: ++ msr = &item->data.msr; ++ msrMask = &mask->data.msr; ++ return ((msr->eax & msrMask->eax) == msrMask->eax && ++ (msr->edx & msrMask->edx) == msrMask->edx); ++ + case VIR_CPU_X86_DATA_NONE: + default: + return false; +@@ -243,6 +259,8 @@ virCPUx86DataItemSetBits(virCPUx86DataItemPtr item, + { + virCPUx86CPUIDPtr cpuid; + const virCPUx86CPUID *cpuidMask; ++ virCPUx86MSRPtr msr; ++ const virCPUx86MSR *msrMask; + + if (!mask) + return; +@@ -257,6 +275,13 @@ virCPUx86DataItemSetBits(virCPUx86DataItemPtr item, + cpuid->edx |= cpuidMask->edx; + break; + ++ case VIR_CPU_X86_DATA_MSR: ++ msr = &item->data.msr; ++ msrMask = &mask->data.msr; ++ msr->eax |= msrMask->eax; ++ msr->edx |= msrMask->edx; ++ break; ++ + case VIR_CPU_X86_DATA_NONE: + default: + break; +@@ -270,6 +295,8 @@ virCPUx86DataItemClearBits(virCPUx86DataItemPtr item, + { + virCPUx86CPUIDPtr cpuid; + const virCPUx86CPUID *cpuidMask; ++ virCPUx86MSRPtr msr; ++ const virCPUx86MSR *msrMask; + + if (!mask) + return; +@@ -284,6 +311,13 @@ virCPUx86DataItemClearBits(virCPUx86DataItemPtr item, + cpuid->edx &= ~cpuidMask->edx; + break; + ++ case VIR_CPU_X86_DATA_MSR: ++ msr = &item->data.msr; ++ msrMask = &mask->data.msr; ++ msr->eax &= ~msrMask->eax; ++ msr->edx &= ~msrMask->edx; ++ break; ++ + case VIR_CPU_X86_DATA_NONE: + default: + break; +@@ -297,6 +331,8 @@ virCPUx86DataItemAndBits(virCPUx86DataItemPtr item, + { + virCPUx86CPUIDPtr cpuid; + const virCPUx86CPUID *cpuidMask; ++ virCPUx86MSRPtr msr; ++ const virCPUx86MSR *msrMask; + + if (!mask) + return; +@@ -311,6 +347,13 @@ virCPUx86DataItemAndBits(virCPUx86DataItemPtr item, + cpuid->edx &= cpuidMask->edx; + break; + ++ case VIR_CPU_X86_DATA_MSR: ++ msr = &item->data.msr; ++ msrMask = &mask->data.msr; ++ msr->eax &= msrMask->eax; ++ msr->edx &= msrMask->edx; ++ break; ++ + case VIR_CPU_X86_DATA_NONE: + default: + break; +@@ -373,6 +416,14 @@ virCPUx86DataSorter(const void *a, const void *b) + + break; + ++ case VIR_CPU_X86_DATA_MSR: ++ if (da->data.msr.index > db->data.msr.index) ++ return 1; ++ else if (da->data.msr.index < db->data.msr.index) ++ return -1; ++ ++ break; ++ + case VIR_CPU_X86_DATA_NONE: + default: + break; +@@ -978,6 +1029,31 @@ x86ParseCPUID(xmlXPathContextPtr ctxt, + } + + ++static int ++x86ParseMSR(xmlXPathContextPtr ctxt, ++ virCPUx86DataItemPtr item) ++{ ++ virCPUx86MSRPtr msr; ++ unsigned long index; ++ unsigned long eax; ++ unsigned long edx; ++ ++ memset(item, 0, sizeof(*item)); ++ ++ if (virXPathULongHex("string(@index)", ctxt, &index) < 0 || ++ virXPathULongHex("string(@eax)", ctxt, &eax) < 0 || ++ virXPathULongHex("string(@edx)", ctxt, &edx) < 0) ++ return -1; ++ ++ item->type = VIR_CPU_X86_DATA_MSR; ++ msr = &item->data.msr; ++ msr->index = index; ++ msr->eax = eax; ++ msr->edx = edx; ++ return 0; ++} ++ ++ + static int + x86FeatureParse(xmlXPathContextPtr ctxt, + const char *name, +@@ -1010,25 +1086,35 @@ x86FeatureParse(xmlXPathContextPtr ctxt, + if (STREQ_NULLABLE(str, "no")) + feature->migratable = false; + +- n = virXPathNodeSet("./cpuid", ctxt, &nodes); ++ n = virXPathNodeSet("./cpuid|./msr", ctxt, &nodes); + if (n < 0) + goto cleanup; + + if (n == 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Missing cpuid for feature %s"), ++ _("Missing cpuid or msr element in feature %s"), + feature->name); + goto cleanup; + } + + for (i = 0; i < n; i++) { + ctxt->node = nodes[i]; +- if (x86ParseCPUID(ctxt, &item) < 0) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Invalid cpuid[%zu] in %s feature"), +- i, feature->name); +- goto cleanup; ++ if (virXMLNodeNameEqual(nodes[i], "cpuid")) { ++ if (x86ParseCPUID(ctxt, &item) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Invalid cpuid[%zu] in %s feature"), ++ i, feature->name); ++ goto cleanup; ++ } ++ } else { ++ if (x86ParseMSR(ctxt, &item) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Invalid msr[%zu] in %s feature"), ++ i, feature->name); ++ goto cleanup; ++ } + } ++ + if (virCPUx86DataAddItem(&feature->data, &item)) + goto cleanup; + } +@@ -1544,6 +1630,7 @@ virCPUx86DataFormat(const virCPUData *data) + virBufferAddLit(&buf, "\n"); + while ((item = virCPUx86DataNext(&iter))) { + virCPUx86CPUIDPtr cpuid; ++ virCPUx86MSRPtr msr; + + switch (item->type) { + case VIR_CPU_X86_DATA_CPUID: +@@ -1556,6 +1643,13 @@ virCPUx86DataFormat(const virCPUData *data) + cpuid->eax, cpuid->ebx, cpuid->ecx, cpuid->edx); + break; + ++ case VIR_CPU_X86_DATA_MSR: ++ msr = &item->data.msr; ++ virBufferAsprintf(&buf, ++ " \n", ++ msr->index, msr->eax, msr->edx); ++ break; ++ + case VIR_CPU_X86_DATA_NONE: + default: + break; +@@ -1579,7 +1673,7 @@ virCPUx86DataParse(xmlXPathContextPtr ctxt) + size_t i; + int n; + +- n = virXPathNodeSet("/cpudata/cpuid", ctxt, &nodes); ++ n = virXPathNodeSet("/cpudata/cpuid|/cpudata/msr", ctxt, &nodes); + if (n <= 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("no x86 CPU data found")); +@@ -1591,11 +1685,20 @@ virCPUx86DataParse(xmlXPathContextPtr ctxt) + + for (i = 0; i < n; i++) { + ctxt->node = nodes[i]; +- if (x86ParseCPUID(ctxt, &item) < 0) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("failed to parse cpuid[%zu]"), i); +- goto error; ++ if (virXMLNodeNameEqual(nodes[i], "cpuid")) { ++ if (x86ParseCPUID(ctxt, &item) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("failed to parse cpuid[%zu]"), i); ++ goto error; ++ } ++ } else { ++ if (x86ParseMSR(ctxt, &item) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("failed to parse msr[%zu]"), i); ++ goto error; ++ } + } ++ + if (virCPUx86DataAdd(cpuData, &item) < 0) + goto error; + } +diff --git a/src/cpu/cpu_x86_data.h b/src/cpu/cpu_x86_data.h +index da8e91fe71..454345b688 100644 +--- a/src/cpu/cpu_x86_data.h ++++ b/src/cpu/cpu_x86_data.h +@@ -37,6 +37,14 @@ struct _virCPUx86CPUID { + uint32_t edx; + }; + ++typedef struct _virCPUx86MSR virCPUx86MSR; ++typedef virCPUx86MSR *virCPUx86MSRPtr; ++struct _virCPUx86MSR { ++ uint32_t index; ++ uint32_t eax; ++ uint32_t edx; ++}; ++ + # define CPUX86_BASIC 0x0 + # define CPUX86_KVM 0x40000000 + # define CPUX86_EXTENDED 0x80000000 +@@ -74,6 +82,7 @@ struct _virCPUx86CPUID { + typedef enum { + VIR_CPU_X86_DATA_NONE = 0, + VIR_CPU_X86_DATA_CPUID, ++ VIR_CPU_X86_DATA_MSR, + } virCPUx86DataType; + + typedef struct _virCPUx86DataItem virCPUx86DataItem; +@@ -82,6 +91,7 @@ struct _virCPUx86DataItem { + virCPUx86DataType type; + union { + virCPUx86CPUID cpuid; ++ virCPUx86MSR msr; + } data; + }; + +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_x86-Add-virCPUx86DataGetSignature-for-tests.patch b/SOURCES/libvirt-cpu_x86-Add-virCPUx86DataGetSignature-for-tests.patch new file mode 100644 index 0000000..034a778 --- /dev/null +++ b/SOURCES/libvirt-cpu_x86-Add-virCPUx86DataGetSignature-for-tests.patch @@ -0,0 +1,81 @@ +From 459e059de518794d909c77b6c24fd6962558d362 Mon Sep 17 00:00:00 2001 +Message-Id: <459e059de518794d909c77b6c24fd6962558d362@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:06 +0200 +Subject: [PATCH] cpu_x86: Add virCPUx86DataGetSignature for tests +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The function exports the functionality of x86DataToSignatureFull and +x86MakeSignature to the test suite. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 661307b4b2e8597d889efddfac0ff5d324c9fa42) + +https://bugzilla.redhat.com/show_bug.cgi?id=1686895 + +Signed-off-by: Jiri Denemark +Message-Id: <7964c9cc9ea47fdce4c2b07fda8efa2cb9f9f384.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_x86.c | 12 ++++++++++++ + src/cpu/cpu_x86.h | 5 +++++ + src/libvirt_private.syms | 1 + + 3 files changed, 18 insertions(+) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index ba14a6097d..24569a90f3 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -3066,6 +3066,18 @@ virCPUx86DataSetSignature(virCPUDataPtr cpuData, + } + + ++uint32_t ++virCPUx86DataGetSignature(virCPUDataPtr cpuData, ++ unsigned int *family, ++ unsigned int *model, ++ unsigned int *stepping) ++{ ++ x86DataToSignatureFull(&cpuData->data.x86, family, model, stepping); ++ ++ return x86MakeSignature(*family, *model, *stepping); ++} ++ ++ + int + virCPUx86DataSetVendor(virCPUDataPtr cpuData, + const char *vendor) +diff --git a/src/cpu/cpu_x86.h b/src/cpu/cpu_x86.h +index 5d14d83e1b..9d3c2b2cdd 100644 +--- a/src/cpu/cpu_x86.h ++++ b/src/cpu/cpu_x86.h +@@ -37,6 +37,11 @@ int virCPUx86DataSetSignature(virCPUDataPtr cpuData, + unsigned int model, + unsigned int stepping); + ++uint32_t virCPUx86DataGetSignature(virCPUDataPtr cpuData, ++ unsigned int *family, ++ unsigned int *model, ++ unsigned int *stepping); ++ + int virCPUx86DataSetVendor(virCPUDataPtr cpuData, + const char *vendor); + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 7c48908a54..a275fa9aa1 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -1205,6 +1205,7 @@ virCPUValidateFeatures; + # cpu/cpu_x86.h + virCPUx86DataAddCPUID; + virCPUx86DataAddFeature; ++virCPUx86DataGetSignature; + virCPUx86DataSetSignature; + virCPUx86DataSetVendor; + +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_x86-Add-x86ModelCopySignatures-helper.patch b/SOURCES/libvirt-cpu_x86-Add-x86ModelCopySignatures-helper.patch new file mode 100644 index 0000000..9d389e8 --- /dev/null +++ b/SOURCES/libvirt-cpu_x86-Add-x86ModelCopySignatures-helper.patch @@ -0,0 +1,77 @@ +From 0b98a3d385f3d46949c5b2bc15c27c7c62739496 Mon Sep 17 00:00:00 2001 +Message-Id: <0b98a3d385f3d46949c5b2bc15c27c7c62739496@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:24:59 +0200 +Subject: [PATCH] cpu_x86: Add x86ModelCopySignatures helper +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Introduce a helper for copying CPU signature between two CPU models. + +It's not very useful until the way we store signatures is changed in the +next patch. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 2254c1cfb854dfc52f3b4bfdfca2bd995b0a163c) + +https://bugzilla.redhat.com/show_bug.cgi?id=1686895 + +Signed-off-by: Jiri Denemark +Message-Id: +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_x86.c | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index 51cb9b7143..e25bc691ae 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -977,6 +977,16 @@ x86ModelFree(virCPUx86ModelPtr model) + } + + ++static int ++x86ModelCopySignatures(virCPUx86ModelPtr dst, ++ virCPUx86ModelPtr src) ++{ ++ dst->signature = src->signature; ++ ++ return 0; ++} ++ ++ + static virCPUx86ModelPtr + x86ModelCopy(virCPUx86ModelPtr model) + { +@@ -984,13 +994,13 @@ x86ModelCopy(virCPUx86ModelPtr model) + + if (VIR_ALLOC(copy) < 0 || + VIR_STRDUP(copy->name, model->name) < 0 || ++ x86ModelCopySignatures(copy, model) < 0 || + x86DataCopy(©->data, &model->data) < 0) { + x86ModelFree(copy); + return NULL; + } + + copy->vendor = model->vendor; +- copy->signature = model->signature; + + return copy; + } +@@ -1176,8 +1186,8 @@ x86ModelParseAncestor(virCPUx86ModelPtr model, + } + + model->vendor = ancestor->vendor; +- model->signature = ancestor->signature; +- if (x86DataCopy(&model->data, &ancestor->data) < 0) ++ if (x86ModelCopySignatures(model, ancestor) < 0 || ++ x86DataCopy(&model->data, &ancestor->data) < 0) + return -1; + + return 0; +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_x86-Allow-multiple-signatures-for-a-CPU-model.patch b/SOURCES/libvirt-cpu_x86-Allow-multiple-signatures-for-a-CPU-model.patch new file mode 100644 index 0000000..faa8177 --- /dev/null +++ b/SOURCES/libvirt-cpu_x86-Allow-multiple-signatures-for-a-CPU-model.patch @@ -0,0 +1,114 @@ +From 5196a4b5fad475a8489faa9b5542536a941bd9da Mon Sep 17 00:00:00 2001 +Message-Id: <5196a4b5fad475a8489faa9b5542536a941bd9da@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:01 +0200 +Subject: [PATCH] cpu_x86: Allow multiple signatures for a CPU model +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +CPU signatures in the cpu_map serve as a hint for CPUID to CPU model +matching algorithm. If the CPU signatures matches any CPU model in the +cpu_map, this model will be the preferred one. + +This works out well and solved several mismatches, but in real world +CPUs which should match a single CPU model may be produced with several +different signatures. For example, low voltage Broadwell CPUs for +laptops and Broadwell CPUs for servers differ in CPU model numbers while +we should detect them all as Broadwell CPU model. + +This patch adds support for storing several signatures for a single CPU +model to make this hint useful for more CPUs. Later commits will provide +additional signatures for existing CPU models, which will correct some +results in our CPU test suite. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit dfeb3e598438a891a05487c34e6723d1d3ed9256) + +https://bugzilla.redhat.com/show_bug.cgi?id=1686895 + +Signed-off-by: Jiri Denemark +Message-Id: <393649e6301769c297f2d09bcb88d6200882eb9d.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_x86.c | 31 +++++++++++++++++++++---------- + 1 file changed, 21 insertions(+), 10 deletions(-) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index f8b8d8a96b..7bd8119c23 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -1204,22 +1204,32 @@ x86ModelParseAncestor(virCPUx86ModelPtr model, + + + static int +-x86ModelParseSignature(virCPUx86ModelPtr model, +- xmlXPathContextPtr ctxt) ++x86ModelParseSignatures(virCPUx86ModelPtr model, ++ xmlXPathContextPtr ctxt) + { ++ VIR_AUTOFREE(xmlNodePtr *) nodes = NULL; ++ xmlNodePtr root = ctxt->node; ++ size_t i; ++ int n; ++ ++ if ((n = virXPathNodeSet("./signature", ctxt, &nodes)) <= 0) ++ return n; ++ + /* Remove inherited signatures. */ + VIR_FREE(model->signatures); + +- if (virXPathBoolean("boolean(./signature)", ctxt)) { ++ model->nsignatures = n; ++ if (VIR_ALLOC_N(model->signatures, n) < 0) ++ return -1; ++ ++ for (i = 0; i < n; i++) { + unsigned int sigFamily = 0; + unsigned int sigModel = 0; + int rc; + +- model->nsignatures = 1; +- if (VIR_ALLOC_N(model->signatures, 1) < 0) +- return -1; ++ ctxt->node = nodes[i]; + +- rc = virXPathUInt("string(./signature/@family)", ctxt, &sigFamily); ++ rc = virXPathUInt("string(@family)", ctxt, &sigFamily); + if (rc < 0 || sigFamily == 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Invalid CPU signature family in model %s"), +@@ -1227,7 +1237,7 @@ x86ModelParseSignature(virCPUx86ModelPtr model, + return -1; + } + +- rc = virXPathUInt("string(./signature/@model)", ctxt, &sigModel); ++ rc = virXPathUInt("string(@model)", ctxt, &sigModel); + if (rc < 0 || sigModel == 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Invalid CPU signature model in model %s"), +@@ -1235,9 +1245,10 @@ x86ModelParseSignature(virCPUx86ModelPtr model, + return -1; + } + +- model->signatures[0] = x86MakeSignature(sigFamily, sigModel, 0); ++ model->signatures[i] = x86MakeSignature(sigFamily, sigModel, 0); + } + ++ ctxt->node = root; + return 0; + } + +@@ -1334,7 +1345,7 @@ x86ModelParse(xmlXPathContextPtr ctxt, + if (x86ModelParseAncestor(model, ctxt, map) < 0) + goto cleanup; + +- if (x86ModelParseSignature(model, ctxt) < 0) ++ if (x86ModelParseSignatures(model, ctxt) < 0) + goto cleanup; + + if (x86ModelParseVendor(model, ctxt, map) < 0) +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_x86-Do-not-cache-microcode-version.patch b/SOURCES/libvirt-cpu_x86-Do-not-cache-microcode-version.patch index 38db4a7..d6ba3b3 100644 --- a/SOURCES/libvirt-cpu_x86-Do-not-cache-microcode-version.patch +++ b/SOURCES/libvirt-cpu_x86-Do-not-cache-microcode-version.patch @@ -1,5 +1,5 @@ -From eb1ac28530d9fe608ada1a3b44ac757c2b4ae020 Mon Sep 17 00:00:00 2001 -Message-Id: +From f574d83a57b54248bc1f1c7fd3b25894d579c8e3 Mon Sep 17 00:00:00 2001 +Message-Id: From: Jiri Denemark Date: Fri, 5 Apr 2019 11:33:32 +0200 Subject: [PATCH] cpu_x86: Do not cache microcode version @@ -18,7 +18,7 @@ Signed-off-by: Jiri Denemark Reviewed-by: Ján Tomko (cherry picked from commit be46f613261d3b655a1f15afd635087e68a9c39b) -CVE-2018-11091, CVE-2018-12126, CVE-2018-12127, CVE-2018-12130 +CVE-2018-12126, CVE-2018-12127, CVE-2018-12130, CVE-2019-11091 Signed-off-by: Jiri Denemark --- diff --git a/SOURCES/libvirt-cpu_x86-Fix-memory-leak-virCPUx86GetHost.patch b/SOURCES/libvirt-cpu_x86-Fix-memory-leak-virCPUx86GetHost.patch new file mode 100644 index 0000000..c8111f6 --- /dev/null +++ b/SOURCES/libvirt-cpu_x86-Fix-memory-leak-virCPUx86GetHost.patch @@ -0,0 +1,43 @@ +From b63d4e603a3617bd0d68d8897afb5e1c13a75165 Mon Sep 17 00:00:00 2001 +Message-Id: +From: John Ferlan +Date: Tue, 2 Jul 2019 12:57:21 +0200 +Subject: [PATCH] cpu_x86: Fix memory leak - virCPUx86GetHost +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Commit 56b254dcc called virCPUx86DataAdd, but returned -1 directly +without calling the virCPUx86DataFree. + +Found by Coverity. + +Signed-off-by: John Ferlan +Reviewed-by: Michal Privoznik +(cherry picked from commit 5acb4eede23bcd5bc75193ea21542e0fb04b6e45) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Signed-off-by: Jiri Denemark +Message-Id: <96135f1275b80b251c83ca947333b1969380ef7b.1562064911.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_x86.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index 0a520f07ff..9104bdbf1e 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -2789,7 +2789,7 @@ virCPUx86GetHost(virCPUDefPtr cpu, + }; + + if (virCPUx86DataAdd(cpuData, &item) < 0) +- return -1; ++ goto cleanup; + } + } + +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_x86-Fix-placement-of-CheckFeature-functions.patch b/SOURCES/libvirt-cpu_x86-Fix-placement-of-CheckFeature-functions.patch new file mode 100644 index 0000000..b99049d --- /dev/null +++ b/SOURCES/libvirt-cpu_x86-Fix-placement-of-CheckFeature-functions.patch @@ -0,0 +1,119 @@ +From e0ea2a8c9fb17cbb0b48cb8a1548152e962b126b Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:45 +0200 +Subject: [PATCH] cpu_x86: Fix placement of *CheckFeature functions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Commit 0a97486e09 moved them outside #ifdef, but after virCPUx86GetHost, +which will start calling them in the following patch. + +Signed-off-by: Jiri Denemark +(cherry picked from commit 32f577ab10aefda6c4666abd07814c5c39f57788) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Conflicts: + src/cpu/cpu_x86.c + - only the last patch moving these functions is backported + +Signed-off-by: Jiri Denemark +Message-Id: <7bb25ee8ca5b743934fa2ae8249f5715a47aba06.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_x86.c | 70 +++++++++++++++++++++++------------------------ + 1 file changed, 35 insertions(+), 35 deletions(-) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index fdc2974a0d..3c1bd623db 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -2377,6 +2377,41 @@ x86Encode(virArch arch, + } + + ++static int ++virCPUx86CheckFeature(const virCPUDef *cpu, ++ const char *name) ++{ ++ int ret = -1; ++ virCPUx86MapPtr map; ++ virCPUx86ModelPtr model = NULL; ++ ++ if (!(map = virCPUx86GetMap())) ++ return -1; ++ ++ if (!(model = x86ModelFromCPU(cpu, map, -1))) ++ goto cleanup; ++ ++ ret = x86FeatureInData(name, &model->data, map); ++ ++ cleanup: ++ x86ModelFree(model); ++ return ret; ++} ++ ++ ++static int ++virCPUx86DataCheckFeature(const virCPUData *data, ++ const char *name) ++{ ++ virCPUx86MapPtr map; ++ ++ if (!(map = virCPUx86GetMap())) ++ return -1; ++ ++ return x86FeatureInData(name, &data->data.x86, map); ++} ++ ++ + #if defined(__i386__) || defined(__x86_64__) + static inline void + cpuidCall(virCPUx86CPUID *cpuid) +@@ -2706,41 +2741,6 @@ cpuidSet(uint32_t base, virCPUDataPtr data) + } + + +-static int +-virCPUx86CheckFeature(const virCPUDef *cpu, +- const char *name) +-{ +- int ret = -1; +- virCPUx86MapPtr map; +- virCPUx86ModelPtr model = NULL; +- +- if (!(map = virCPUx86GetMap())) +- return -1; +- +- if (!(model = x86ModelFromCPU(cpu, map, -1))) +- goto cleanup; +- +- ret = x86FeatureInData(name, &model->data, map); +- +- cleanup: +- x86ModelFree(model); +- return ret; +-} +- +- +-static int +-virCPUx86DataCheckFeature(const virCPUData *data, +- const char *name) +-{ +- virCPUx86MapPtr map; +- +- if (!(map = virCPUx86GetMap())) +- return -1; +- +- return x86FeatureInData(name, &data->data.x86, map); +-} +- +- + static int + virCPUx86GetHost(virCPUDefPtr cpu, + virDomainCapsCPUModelsPtr models) +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_x86-Introduce-virCPUx86DataCmp.patch b/SOURCES/libvirt-cpu_x86-Introduce-virCPUx86DataCmp.patch new file mode 100644 index 0000000..1138e87 --- /dev/null +++ b/SOURCES/libvirt-cpu_x86-Introduce-virCPUx86DataCmp.patch @@ -0,0 +1,60 @@ +From 5354c931f98f2d95d131bf4d490d0e5e057157fe Mon Sep 17 00:00:00 2001 +Message-Id: <5354c931f98f2d95d131bf4d490d0e5e057157fe@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:32 +0200 +Subject: [PATCH] cpu_x86: Introduce virCPUx86DataCmp +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +virCPUx86DataSorter already compares two virCPUx86DataItem structs. +Let's add a tiny wrapper around it called virCPUx86DataCmp and use it +instead of open coded comparisons. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 559ccd7815056af23de24b7a01e8f644d97b6a92) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Signed-off-by: Jiri Denemark +Message-Id: <9623fdd20059ec6abc7f09c5e7f1e13927c56944.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_x86.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index 0582be63e2..5a09033d2a 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -304,6 +304,13 @@ virCPUx86DataSorter(const void *a, const void *b) + return 0; + } + ++static int ++virCPUx86DataItemCmp(const virCPUx86DataItem *item1, ++ const virCPUx86DataItem *item2) ++{ ++ return virCPUx86DataSorter(item1, item2); ++} ++ + + /* skips all zero CPUID leaves */ + static virCPUx86DataItemPtr +@@ -332,9 +339,9 @@ virCPUx86DataGet(const virCPUx86Data *data, + size_t i; + + for (i = 0; i < data->len; i++) { +- if (data->items[i].cpuid.eax_in == item->cpuid.eax_in && +- data->items[i].cpuid.ecx_in == item->cpuid.ecx_in) +- return data->items + i; ++ virCPUx86DataItemPtr di = data->items + i; ++ if (virCPUx86DataItemCmp(di, item) == 0) ++ return di; + } + + return NULL; +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_x86-Introduce-virCPUx86DataItem-container-struct.patch b/SOURCES/libvirt-cpu_x86-Introduce-virCPUx86DataItem-container-struct.patch new file mode 100644 index 0000000..6bdf1ff --- /dev/null +++ b/SOURCES/libvirt-cpu_x86-Introduce-virCPUx86DataItem-container-struct.patch @@ -0,0 +1,850 @@ +From 891f6c594088c787c92279af08ba0ab037492bdd Mon Sep 17 00:00:00 2001 +Message-Id: <891f6c594088c787c92279af08ba0ab037492bdd@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:22 +0200 +Subject: [PATCH] cpu_x86: Introduce virCPUx86DataItem container struct +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The following patches introduce CPU features read from MSR in addition +to those queried via CPUID instruction. Let's introduce a container +struct which will be able to describe either feature type. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 3673269e3aa22566f87e06a2b10dbc3b20110f84) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Signed-off-by: Jiri Denemark +Message-Id: <161419b9968304180f18b33e6dc29ba70d9174d0.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_x86.c | 312 ++++++++++++++++++--------------- + src/cpu/cpu_x86.h | 2 +- + src/cpu/cpu_x86_data.h | 9 +- + src/libxl/libxl_capabilities.c | 8 +- + src/qemu/qemu_monitor_json.c | 6 +- + 5 files changed, 183 insertions(+), 154 deletions(-) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index 98e8d608d6..2e953eaa12 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -49,7 +49,7 @@ typedef struct _virCPUx86Vendor virCPUx86Vendor; + typedef virCPUx86Vendor *virCPUx86VendorPtr; + struct _virCPUx86Vendor { + char *name; +- virCPUx86CPUID cpuid; ++ virCPUx86DataItem cpuid; + }; + + typedef struct _virCPUx86Feature virCPUx86Feature; +@@ -61,17 +61,19 @@ struct _virCPUx86Feature { + }; + + ++#define CPUID(...) { .cpuid = {__VA_ARGS__} } ++ + #define KVM_FEATURE_DEF(Name, Eax_in, Eax) \ +- static virCPUx86CPUID Name ## _cpuid[] = { \ +- { .eax_in = Eax_in, .eax = Eax }, \ ++ static virCPUx86DataItem Name ## _data[] = { \ ++ CPUID(.eax_in = Eax_in, .eax = Eax), \ + } + + #define KVM_FEATURE(Name) \ + { \ + .name = (char *) Name, \ + .data = { \ +- .len = ARRAY_CARDINALITY(Name ## _cpuid), \ +- .data = Name ## _cpuid \ ++ .len = ARRAY_CARDINALITY(Name ## _data), \ ++ .items = Name ## _data, \ + } \ + } + +@@ -286,17 +288,17 @@ x86FeatureFindInternal(const char *name) + static int + virCPUx86CPUIDSorter(const void *a, const void *b) + { +- virCPUx86CPUID *da = (virCPUx86CPUID *) a; +- virCPUx86CPUID *db = (virCPUx86CPUID *) b; ++ virCPUx86DataItemPtr da = (virCPUx86DataItemPtr) a; ++ virCPUx86DataItemPtr db = (virCPUx86DataItemPtr) b; + +- if (da->eax_in > db->eax_in) ++ if (da->cpuid.eax_in > db->cpuid.eax_in) + return 1; +- else if (da->eax_in < db->eax_in) ++ else if (da->cpuid.eax_in < db->cpuid.eax_in) + return -1; + +- if (da->ecx_in > db->ecx_in) ++ if (da->cpuid.ecx_in > db->cpuid.ecx_in) + return 1; +- else if (da->ecx_in < db->ecx_in) ++ else if (da->cpuid.ecx_in < db->cpuid.ecx_in) + return -1; + + return 0; +@@ -304,7 +306,7 @@ virCPUx86CPUIDSorter(const void *a, const void *b) + + + /* skips all zero CPUID leaves */ +-static virCPUx86CPUID * ++static virCPUx86DataItemPtr + x86DataCpuidNext(virCPUx86DataIteratorPtr iterator) + { + const virCPUx86Data *data = iterator->data; +@@ -313,24 +315,26 @@ x86DataCpuidNext(virCPUx86DataIteratorPtr iterator) + return NULL; + + while (++iterator->pos < data->len) { +- if (!x86cpuidMatch(data->data + iterator->pos, &cpuidNull)) +- return data->data + iterator->pos; ++ virCPUx86DataItemPtr item = data->items + iterator->pos; ++ ++ if (!x86cpuidMatch(&item->cpuid, &cpuidNull)) ++ return item; + } + + return NULL; + } + + +-static virCPUx86CPUID * ++static virCPUx86DataItemPtr + x86DataCpuid(const virCPUx86Data *data, +- const virCPUx86CPUID *cpuid) ++ const virCPUx86DataItem *cpuid) + { + size_t i; + + for (i = 0; i < data->len; i++) { +- if (data->data[i].eax_in == cpuid->eax_in && +- data->data[i].ecx_in == cpuid->ecx_in) +- return data->data + i; ++ if (data->items[i].cpuid.eax_in == cpuid->cpuid.eax_in && ++ data->items[i].cpuid.ecx_in == cpuid->cpuid.ecx_in) ++ return data->items + i; + } + + return NULL; +@@ -342,7 +346,7 @@ virCPUx86DataClear(virCPUx86Data *data) + if (!data) + return; + +- VIR_FREE(data->data); ++ VIR_FREE(data->items); + } + + +@@ -362,12 +366,12 @@ x86DataCopy(virCPUx86Data *dst, const virCPUx86Data *src) + { + size_t i; + +- if (VIR_ALLOC_N(dst->data, src->len) < 0) ++ if (VIR_ALLOC_N(dst->items, src->len) < 0) + return -1; + + dst->len = src->len; + for (i = 0; i < src->len; i++) +- dst->data[i] = src->data[i]; ++ dst->items[i] = src->items[i]; + + return 0; + } +@@ -375,19 +379,19 @@ x86DataCopy(virCPUx86Data *dst, const virCPUx86Data *src) + + static int + virCPUx86DataAddCPUIDInt(virCPUx86Data *data, +- const virCPUx86CPUID *cpuid) ++ const virCPUx86DataItem *cpuid) + { +- virCPUx86CPUID *existing; ++ virCPUx86DataItemPtr existing; + + if ((existing = x86DataCpuid(data, cpuid))) { +- x86cpuidSetBits(existing, cpuid); ++ x86cpuidSetBits(&existing->cpuid, &cpuid->cpuid); + } else { +- if (VIR_APPEND_ELEMENT_COPY(data->data, data->len, +- *((virCPUx86CPUID *)cpuid)) < 0) ++ if (VIR_APPEND_ELEMENT_COPY(data->items, data->len, ++ *((virCPUx86DataItemPtr)cpuid)) < 0) + return -1; + +- qsort(data->data, data->len, +- sizeof(virCPUx86CPUID), virCPUx86CPUIDSorter); ++ qsort(data->items, data->len, ++ sizeof(virCPUx86DataItem), virCPUx86CPUIDSorter); + } + + return 0; +@@ -399,14 +403,14 @@ x86DataAdd(virCPUx86Data *data1, + const virCPUx86Data *data2) + { + virCPUx86DataIterator iter = virCPUx86DataIteratorInit(data2); +- virCPUx86CPUID *cpuid1; +- virCPUx86CPUID *cpuid2; ++ virCPUx86DataItemPtr cpuid1; ++ virCPUx86DataItemPtr cpuid2; + + while ((cpuid2 = x86DataCpuidNext(&iter))) { + cpuid1 = x86DataCpuid(data1, cpuid2); + + if (cpuid1) { +- x86cpuidSetBits(cpuid1, cpuid2); ++ x86cpuidSetBits(&cpuid1->cpuid, &cpuid2->cpuid); + } else { + if (virCPUx86DataAddCPUIDInt(data1, cpuid2) < 0) + return -1; +@@ -422,12 +426,12 @@ x86DataSubtract(virCPUx86Data *data1, + const virCPUx86Data *data2) + { + virCPUx86DataIterator iter = virCPUx86DataIteratorInit(data1); +- virCPUx86CPUID *cpuid1; +- virCPUx86CPUID *cpuid2; ++ virCPUx86DataItemPtr cpuid1; ++ virCPUx86DataItemPtr cpuid2; + + while ((cpuid1 = x86DataCpuidNext(&iter))) { +- cpuid2 = x86DataCpuid(data2, cpuid1); +- x86cpuidClearBits(cpuid1, cpuid2); ++ if ((cpuid2 = x86DataCpuid(data2, cpuid1))) ++ x86cpuidClearBits(&cpuid1->cpuid, &cpuid2->cpuid); + } + } + +@@ -437,15 +441,15 @@ x86DataIntersect(virCPUx86Data *data1, + const virCPUx86Data *data2) + { + virCPUx86DataIterator iter = virCPUx86DataIteratorInit(data1); +- virCPUx86CPUID *cpuid1; +- virCPUx86CPUID *cpuid2; ++ virCPUx86DataItemPtr cpuid1; ++ virCPUx86DataItemPtr cpuid2; + + while ((cpuid1 = x86DataCpuidNext(&iter))) { + cpuid2 = x86DataCpuid(data2, cpuid1); + if (cpuid2) +- x86cpuidAndBits(cpuid1, cpuid2); ++ x86cpuidAndBits(&cpuid1->cpuid, &cpuid2->cpuid); + else +- x86cpuidClearBits(cpuid1, cpuid1); ++ x86cpuidClearBits(&cpuid1->cpuid, &cpuid1->cpuid); + } + } + +@@ -465,12 +469,12 @@ x86DataIsSubset(const virCPUx86Data *data, + { + + virCPUx86DataIterator iter = virCPUx86DataIteratorInit((virCPUx86Data *)subset); +- const virCPUx86CPUID *cpuid; +- const virCPUx86CPUID *cpuidSubset; ++ const virCPUx86DataItem *cpuid; ++ const virCPUx86DataItem *cpuidSubset; + + while ((cpuidSubset = x86DataCpuidNext(&iter))) { + if (!(cpuid = x86DataCpuid(data, cpuidSubset)) || +- !x86cpuidMatchMasked(cpuid, cpuidSubset)) ++ !x86cpuidMatchMasked(&cpuid->cpuid, &cpuidSubset->cpuid)) + return false; + } + +@@ -505,14 +509,14 @@ static virCPUx86VendorPtr + x86DataToVendor(const virCPUx86Data *data, + virCPUx86MapPtr map) + { +- virCPUx86CPUID *cpuid; ++ virCPUx86DataItemPtr cpuid; + size_t i; + + for (i = 0; i < map->nvendors; i++) { + virCPUx86VendorPtr vendor = map->vendors[i]; + if ((cpuid = x86DataCpuid(data, &vendor->cpuid)) && +- x86cpuidMatchMasked(cpuid, &vendor->cpuid)) { +- x86cpuidClearBits(cpuid, &vendor->cpuid); ++ x86cpuidMatchMasked(&cpuid->cpuid, &vendor->cpuid.cpuid)) { ++ x86cpuidClearBits(&cpuid->cpuid, &vendor->cpuid.cpuid); + return vendor; + } + } +@@ -523,8 +527,10 @@ x86DataToVendor(const virCPUx86Data *data, + + static int + virCPUx86VendorToCPUID(const char *vendor, +- virCPUx86CPUID *cpuid) ++ virCPUx86DataItemPtr data) + { ++ virCPUx86CPUIDPtr cpuid = &data->cpuid; ++ + if (strlen(vendor) != VENDOR_STRING_LENGTH) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Invalid CPU vendor string '%s'"), vendor); +@@ -597,14 +603,16 @@ x86DataToSignatureFull(const virCPUx86Data *data, + unsigned int *model, + unsigned int *stepping) + { +- virCPUx86CPUID leaf1 = { .eax_in = 0x1 }; +- virCPUx86CPUID *cpuid; ++ virCPUx86DataItem leaf1 = CPUID(.eax_in = 0x1); ++ virCPUx86DataItemPtr item; ++ virCPUx86CPUIDPtr cpuid; + + *family = *model = *stepping = 0; + +- if (!(cpuid = x86DataCpuid(data, &leaf1))) ++ if (!(item = x86DataCpuid(data, &leaf1))) + return; + ++ cpuid = &item->cpuid; + *family = ((cpuid->eax >> 20) & 0xff) + ((cpuid->eax >> 8) & 0xf); + *model = ((cpuid->eax >> 12) & 0xf0) + ((cpuid->eax >> 4) & 0xf); + *stepping = cpuid->eax & 0xf; +@@ -617,13 +625,13 @@ x86DataToSignatureFull(const virCPUx86Data *data, + static uint32_t + x86DataToSignature(const virCPUx86Data *data) + { +- virCPUx86CPUID leaf1 = { .eax_in = 0x1 }; +- virCPUx86CPUID *cpuid; ++ virCPUx86DataItem leaf1 = CPUID(.eax_in = 0x1); ++ virCPUx86DataItemPtr cpuid; + + if (!(cpuid = x86DataCpuid(data, &leaf1))) + return 0; + +- return cpuid->eax & SIGNATURE_MASK; ++ return cpuid->cpuid.eax & SIGNATURE_MASK; + } + + +@@ -631,7 +639,7 @@ static int + x86DataAddSignature(virCPUx86Data *data, + uint32_t signature) + { +- virCPUx86CPUID cpuid = { .eax_in = 0x1, .eax = signature }; ++ virCPUx86DataItem cpuid = CPUID(.eax_in = 0x1, .eax = signature); + + return virCPUx86DataAddCPUIDInt(data, &cpuid); + } +@@ -856,13 +864,14 @@ x86FeatureNames(virCPUx86MapPtr map, + + static int + x86ParseCPUID(xmlXPathContextPtr ctxt, +- virCPUx86CPUID *cpuid) ++ virCPUx86DataItemPtr item) + { ++ virCPUx86CPUIDPtr cpuid; + unsigned long eax_in, ecx_in; + unsigned long eax, ebx, ecx, edx; + int ret_eax_in, ret_ecx_in, ret_eax, ret_ebx, ret_ecx, ret_edx; + +- memset(cpuid, 0, sizeof(*cpuid)); ++ memset(item, 0, sizeof(*item)); + + eax_in = ecx_in = 0; + eax = ebx = ecx = edx = 0; +@@ -877,6 +886,7 @@ x86ParseCPUID(xmlXPathContextPtr ctxt, + ret_eax == -2 || ret_ebx == -2 || ret_ecx == -2 || ret_edx == -2) + return -1; + ++ cpuid = &item->cpuid; + cpuid->eax_in = eax_in; + cpuid->ecx_in = ecx_in; + cpuid->eax = eax; +@@ -895,7 +905,7 @@ x86FeatureParse(xmlXPathContextPtr ctxt, + virCPUx86MapPtr map = data; + xmlNodePtr *nodes = NULL; + virCPUx86FeaturePtr feature; +- virCPUx86CPUID cpuid; ++ virCPUx86DataItem cpuid; + size_t i; + int n; + char *str = NULL; +@@ -1138,16 +1148,16 @@ x86ModelCompare(virCPUx86ModelPtr model1, + virCPUx86CompareResult result = EQUAL; + virCPUx86DataIterator iter1 = virCPUx86DataIteratorInit(&model1->data); + virCPUx86DataIterator iter2 = virCPUx86DataIteratorInit(&model2->data); +- virCPUx86CPUID *cpuid1; +- virCPUx86CPUID *cpuid2; ++ virCPUx86DataItemPtr cpuid1; ++ virCPUx86DataItemPtr cpuid2; + + while ((cpuid1 = x86DataCpuidNext(&iter1))) { + virCPUx86CompareResult match = SUPERSET; + + if ((cpuid2 = x86DataCpuid(&model2->data, cpuid1))) { +- if (x86cpuidMatch(cpuid1, cpuid2)) ++ if (x86cpuidMatch(&cpuid1->cpuid, &cpuid2->cpuid)) + continue; +- else if (!x86cpuidMatchMasked(cpuid1, cpuid2)) ++ else if (!x86cpuidMatchMasked(&cpuid1->cpuid, &cpuid2->cpuid)) + match = SUBSET; + } + +@@ -1161,9 +1171,9 @@ x86ModelCompare(virCPUx86ModelPtr model1, + virCPUx86CompareResult match = SUBSET; + + if ((cpuid1 = x86DataCpuid(&model1->data, cpuid2))) { +- if (x86cpuidMatch(cpuid2, cpuid1)) ++ if (x86cpuidMatch(&cpuid2->cpuid, &cpuid1->cpuid)) + continue; +- else if (!x86cpuidMatchMasked(cpuid2, cpuid1)) ++ else if (!x86cpuidMatchMasked(&cpuid2->cpuid, &cpuid1->cpuid)) + match = SUPERSET; + } + +@@ -1447,11 +1457,12 @@ static char * + virCPUx86DataFormat(const virCPUData *data) + { + virCPUx86DataIterator iter = virCPUx86DataIteratorInit(&data->data.x86); +- virCPUx86CPUID *cpuid; ++ virCPUx86DataItemPtr item; + virBuffer buf = VIR_BUFFER_INITIALIZER; + + virBufferAddLit(&buf, "\n"); +- while ((cpuid = x86DataCpuidNext(&iter))) { ++ while ((item = x86DataCpuidNext(&iter))) { ++ virCPUx86CPUIDPtr cpuid = &item->cpuid; + virBufferAsprintf(&buf, + " data; + model->data.len = 0; +- model->data.data = NULL; ++ model->data.items = NULL; + x86ModelFree(model); + + return 0; +@@ -2213,17 +2224,18 @@ cpuidCall(virCPUx86CPUID *cpuid) + */ + static int + cpuidSetLeaf4(virCPUDataPtr data, +- virCPUx86CPUID *subLeaf0) ++ virCPUx86DataItemPtr subLeaf0) + { +- virCPUx86CPUID cpuid = *subLeaf0; ++ virCPUx86DataItem item = *subLeaf0; ++ virCPUx86CPUIDPtr cpuid = &item.cpuid; + + if (virCPUx86DataAddCPUID(data, subLeaf0) < 0) + return -1; + +- while (cpuid.eax & 0x1f) { +- cpuid.ecx_in++; +- cpuidCall(&cpuid); +- if (virCPUx86DataAddCPUID(data, &cpuid) < 0) ++ while (cpuid->eax & 0x1f) { ++ cpuid->ecx_in++; ++ cpuidCall(cpuid); ++ if (virCPUx86DataAddCPUID(data, &item) < 0) + return -1; + } + return 0; +@@ -2236,18 +2248,19 @@ cpuidSetLeaf4(virCPUDataPtr data, + */ + static int + cpuidSetLeaf7(virCPUDataPtr data, +- virCPUx86CPUID *subLeaf0) ++ virCPUx86DataItemPtr subLeaf0) + { +- virCPUx86CPUID cpuid = { .eax_in = 0x7 }; ++ virCPUx86DataItem item = CPUID(.eax_in = 0x7); ++ virCPUx86CPUIDPtr cpuid = &item.cpuid; + uint32_t sub; + + if (virCPUx86DataAddCPUID(data, subLeaf0) < 0) + return -1; + +- for (sub = 1; sub <= subLeaf0->eax; sub++) { +- cpuid.ecx_in = sub; +- cpuidCall(&cpuid); +- if (virCPUx86DataAddCPUID(data, &cpuid) < 0) ++ for (sub = 1; sub <= subLeaf0->cpuid.eax; sub++) { ++ cpuid->ecx_in = sub; ++ cpuidCall(cpuid); ++ if (virCPUx86DataAddCPUID(data, &item) < 0) + return -1; + } + return 0; +@@ -2263,15 +2276,16 @@ cpuidSetLeaf7(virCPUDataPtr data, + */ + static int + cpuidSetLeafB(virCPUDataPtr data, +- virCPUx86CPUID *subLeaf0) ++ virCPUx86DataItemPtr subLeaf0) + { +- virCPUx86CPUID cpuid = *subLeaf0; ++ virCPUx86DataItem item = *subLeaf0; ++ virCPUx86CPUIDPtr cpuid = &item.cpuid; + +- while (cpuid.ecx & 0xff00) { +- if (virCPUx86DataAddCPUID(data, &cpuid) < 0) ++ while (cpuid->ecx & 0xff00) { ++ if (virCPUx86DataAddCPUID(data, &item) < 0) + return -1; +- cpuid.ecx_in++; +- cpuidCall(&cpuid); ++ cpuid->ecx_in++; ++ cpuidCall(cpuid); + } + return 0; + } +@@ -2287,9 +2301,10 @@ cpuidSetLeafB(virCPUDataPtr data, + */ + static int + cpuidSetLeafD(virCPUDataPtr data, +- virCPUx86CPUID *subLeaf0) ++ virCPUx86DataItemPtr subLeaf0) + { +- virCPUx86CPUID cpuid = { .eax_in = 0xd }; ++ virCPUx86DataItem item = CPUID(.eax_in = 0xd); ++ virCPUx86CPUIDPtr cpuid = &item.cpuid; + virCPUx86CPUID sub0; + virCPUx86CPUID sub1; + uint32_t sub; +@@ -2297,13 +2312,13 @@ cpuidSetLeafD(virCPUDataPtr data, + if (virCPUx86DataAddCPUID(data, subLeaf0) < 0) + return -1; + +- cpuid.ecx_in = 1; +- cpuidCall(&cpuid); +- if (virCPUx86DataAddCPUID(data, &cpuid) < 0) ++ cpuid->ecx_in = 1; ++ cpuidCall(cpuid); ++ if (virCPUx86DataAddCPUID(data, &item) < 0) + return -1; + +- sub0 = *subLeaf0; +- sub1 = cpuid; ++ sub0 = subLeaf0->cpuid; ++ sub1 = *cpuid; + for (sub = 2; sub < 64; sub++) { + if (sub < 32 && + !(sub0.eax & (1 << sub)) && +@@ -2314,9 +2329,9 @@ cpuidSetLeafD(virCPUDataPtr data, + !(sub1.edx & (1 << (sub - 32)))) + continue; + +- cpuid.ecx_in = sub; +- cpuidCall(&cpuid); +- if (virCPUx86DataAddCPUID(data, &cpuid) < 0) ++ cpuid->ecx_in = sub; ++ cpuidCall(cpuid); ++ if (virCPUx86DataAddCPUID(data, &item) < 0) + return -1; + } + return 0; +@@ -2334,10 +2349,11 @@ cpuidSetLeafD(virCPUDataPtr data, + */ + static int + cpuidSetLeafResID(virCPUDataPtr data, +- virCPUx86CPUID *subLeaf0, ++ virCPUx86DataItemPtr subLeaf0, + uint32_t res) + { +- virCPUx86CPUID cpuid = { .eax_in = subLeaf0->eax_in }; ++ virCPUx86DataItem item = CPUID(.eax_in = subLeaf0->cpuid.eax_in); ++ virCPUx86CPUIDPtr cpuid = &item.cpuid; + uint32_t sub; + + if (virCPUx86DataAddCPUID(data, subLeaf0) < 0) +@@ -2346,9 +2362,9 @@ cpuidSetLeafResID(virCPUDataPtr data, + for (sub = 1; sub < 32; sub++) { + if (!(res & (1 << sub))) + continue; +- cpuid.ecx_in = sub; +- cpuidCall(&cpuid); +- if (virCPUx86DataAddCPUID(data, &cpuid) < 0) ++ cpuid->ecx_in = sub; ++ cpuidCall(cpuid); ++ if (virCPUx86DataAddCPUID(data, &item) < 0) + return -1; + } + return 0; +@@ -2362,31 +2378,32 @@ cpuidSetLeafResID(virCPUDataPtr data, + */ + static int + cpuidSetLeaf12(virCPUDataPtr data, +- virCPUx86CPUID *subLeaf0) ++ virCPUx86DataItemPtr subLeaf0) + { +- virCPUx86CPUID cpuid = { .eax_in = 0x7 }; +- virCPUx86CPUID *cpuid7; ++ virCPUx86DataItem item = CPUID(.eax_in = 0x7); ++ virCPUx86CPUIDPtr cpuid = &item.cpuid; ++ virCPUx86DataItemPtr cpuid7; + +- if (!(cpuid7 = x86DataCpuid(&data->data.x86, &cpuid)) || +- !(cpuid7->ebx & (1 << 2))) ++ if (!(cpuid7 = x86DataCpuid(&data->data.x86, &item)) || ++ !(cpuid7->cpuid.ebx & (1 << 2))) + return 0; + + if (virCPUx86DataAddCPUID(data, subLeaf0) < 0) + return -1; + +- cpuid.eax_in = 0x12; +- cpuid.ecx_in = 1; +- cpuidCall(&cpuid); +- if (virCPUx86DataAddCPUID(data, &cpuid) < 0) ++ cpuid->eax_in = 0x12; ++ cpuid->ecx_in = 1; ++ cpuidCall(cpuid); ++ if (virCPUx86DataAddCPUID(data, &item) < 0) + return -1; + +- cpuid.ecx_in = 2; +- cpuidCall(&cpuid); +- while (cpuid.eax & 0xf) { +- if (virCPUx86DataAddCPUID(data, &cpuid) < 0) ++ cpuid->ecx_in = 2; ++ cpuidCall(cpuid); ++ while (cpuid->eax & 0xf) { ++ if (virCPUx86DataAddCPUID(data, &item) < 0) + return -1; +- cpuid.ecx_in++; +- cpuidCall(&cpuid); ++ cpuid->ecx_in++; ++ cpuidCall(cpuid); + } + return 0; + } +@@ -2398,18 +2415,19 @@ cpuidSetLeaf12(virCPUDataPtr data, + */ + static int + cpuidSetLeaf14(virCPUDataPtr data, +- virCPUx86CPUID *subLeaf0) ++ virCPUx86DataItemPtr subLeaf0) + { +- virCPUx86CPUID cpuid = { .eax_in = 0x14 }; ++ virCPUx86DataItem item = CPUID(.eax_in = 0x14); ++ virCPUx86CPUIDPtr cpuid = &item.cpuid; + uint32_t sub; + + if (virCPUx86DataAddCPUID(data, subLeaf0) < 0) + return -1; + +- for (sub = 1; sub <= subLeaf0->eax; sub++) { +- cpuid.ecx_in = sub; +- cpuidCall(&cpuid); +- if (virCPUx86DataAddCPUID(data, &cpuid) < 0) ++ for (sub = 1; sub <= subLeaf0->cpuid.eax; sub++) { ++ cpuid->ecx_in = sub; ++ cpuidCall(cpuid); ++ if (virCPUx86DataAddCPUID(data, &item) < 0) + return -1; + } + return 0; +@@ -2423,21 +2441,22 @@ cpuidSetLeaf14(virCPUDataPtr data, + */ + static int + cpuidSetLeaf17(virCPUDataPtr data, +- virCPUx86CPUID *subLeaf0) ++ virCPUx86DataItemPtr subLeaf0) + { +- virCPUx86CPUID cpuid = { .eax_in = 0x17 }; ++ virCPUx86DataItem item = CPUID(.eax_in = 0x17); ++ virCPUx86CPUIDPtr cpuid = &item.cpuid; + uint32_t sub; + +- if (subLeaf0->eax < 3) ++ if (subLeaf0->cpuid.eax < 3) + return 0; + + if (virCPUx86DataAddCPUID(data, subLeaf0) < 0) + return -1; + +- for (sub = 1; sub <= subLeaf0->eax; sub++) { +- cpuid.ecx_in = sub; +- cpuidCall(&cpuid); +- if (virCPUx86DataAddCPUID(data, &cpuid) < 0) ++ for (sub = 1; sub <= subLeaf0->cpuid.eax; sub++) { ++ cpuid->ecx_in = sub; ++ cpuidCall(cpuid); ++ if (virCPUx86DataAddCPUID(data, &item) < 0) + return -1; + } + return 0; +@@ -2450,39 +2469,40 @@ cpuidSet(uint32_t base, virCPUDataPtr data) + int rc; + uint32_t max; + uint32_t leaf; +- virCPUx86CPUID cpuid = { .eax_in = base }; ++ virCPUx86DataItem item = CPUID(.eax_in = base); ++ virCPUx86CPUIDPtr cpuid = &item.cpuid; + +- cpuidCall(&cpuid); +- max = cpuid.eax; ++ cpuidCall(cpuid); ++ max = cpuid->eax; + + for (leaf = base; leaf <= max; leaf++) { +- cpuid.eax_in = leaf; +- cpuid.ecx_in = 0; +- cpuidCall(&cpuid); ++ cpuid->eax_in = leaf; ++ cpuid->ecx_in = 0; ++ cpuidCall(cpuid); + + /* Handle CPUID leaves that depend on previously queried bits or + * which provide additional sub leaves for ecx_in > 0 + */ + if (leaf == 0x4) +- rc = cpuidSetLeaf4(data, &cpuid); ++ rc = cpuidSetLeaf4(data, &item); + else if (leaf == 0x7) +- rc = cpuidSetLeaf7(data, &cpuid); ++ rc = cpuidSetLeaf7(data, &item); + else if (leaf == 0xb) +- rc = cpuidSetLeafB(data, &cpuid); ++ rc = cpuidSetLeafB(data, &item); + else if (leaf == 0xd) +- rc = cpuidSetLeafD(data, &cpuid); ++ rc = cpuidSetLeafD(data, &item); + else if (leaf == 0xf) +- rc = cpuidSetLeafResID(data, &cpuid, cpuid.edx); ++ rc = cpuidSetLeafResID(data, &item, cpuid->edx); + else if (leaf == 0x10) +- rc = cpuidSetLeafResID(data, &cpuid, cpuid.ebx); ++ rc = cpuidSetLeafResID(data, &item, cpuid->ebx); + else if (leaf == 0x12) +- rc = cpuidSetLeaf12(data, &cpuid); ++ rc = cpuidSetLeaf12(data, &item); + else if (leaf == 0x14) +- rc = cpuidSetLeaf14(data, &cpuid); ++ rc = cpuidSetLeaf14(data, &item); + else if (leaf == 0x17) +- rc = cpuidSetLeaf17(data, &cpuid); ++ rc = cpuidSetLeaf17(data, &item); + else +- rc = virCPUx86DataAddCPUID(data, &cpuid); ++ rc = virCPUx86DataAddCPUID(data, &item); + + if (rc < 0) + return -1; +@@ -3058,7 +3078,7 @@ virCPUx86ValidateFeatures(virCPUDefPtr cpu) + + int + virCPUx86DataAddCPUID(virCPUDataPtr cpuData, +- const virCPUx86CPUID *cpuid) ++ const virCPUx86DataItem *cpuid) + { + return virCPUx86DataAddCPUIDInt(&cpuData->data.x86, cpuid); + } +@@ -3092,7 +3112,7 @@ int + virCPUx86DataSetVendor(virCPUDataPtr cpuData, + const char *vendor) + { +- virCPUx86CPUID cpuid = { 0 }; ++ virCPUx86DataItem cpuid = CPUID(0); + + if (virCPUx86VendorToCPUID(vendor, &cpuid) < 0) + return -1; +diff --git a/src/cpu/cpu_x86.h b/src/cpu/cpu_x86.h +index 9d3c2b2cdd..94655746c6 100644 +--- a/src/cpu/cpu_x86.h ++++ b/src/cpu/cpu_x86.h +@@ -30,7 +30,7 @@ + extern struct cpuArchDriver cpuDriverX86; + + int virCPUx86DataAddCPUID(virCPUDataPtr cpuData, +- const virCPUx86CPUID *cpuid); ++ const virCPUx86DataItem *cpuid); + + int virCPUx86DataSetSignature(virCPUDataPtr cpuData, + unsigned int family, +diff --git a/src/cpu/cpu_x86_data.h b/src/cpu/cpu_x86_data.h +index 090a21156f..e93b355cf0 100644 +--- a/src/cpu/cpu_x86_data.h ++++ b/src/cpu/cpu_x86_data.h +@@ -27,6 +27,7 @@ + # include + + typedef struct _virCPUx86CPUID virCPUx86CPUID; ++typedef virCPUx86CPUID *virCPUx86CPUIDPtr; + struct _virCPUx86CPUID { + uint32_t eax_in; + uint32_t ecx_in; +@@ -70,10 +71,16 @@ struct _virCPUx86CPUID { + + # define VIR_CPU_X86_DATA_INIT { 0 } + ++typedef struct _virCPUx86DataItem virCPUx86DataItem; ++typedef virCPUx86DataItem *virCPUx86DataItemPtr; ++struct _virCPUx86DataItem { ++ virCPUx86CPUID cpuid; ++}; ++ + typedef struct _virCPUx86Data virCPUx86Data; + struct _virCPUx86Data { + size_t len; +- virCPUx86CPUID *data; ++ virCPUx86DataItem *items; + }; + + #endif /* __VIR_CPU_X86_DATA_H__ */ +diff --git a/src/libxl/libxl_capabilities.c b/src/libxl/libxl_capabilities.c +index 18596c7c72..231d72669f 100644 +--- a/src/libxl/libxl_capabilities.c ++++ b/src/libxl/libxl_capabilities.c +@@ -67,13 +67,15 @@ struct guest_arch { + static int + libxlCapsAddCPUID(virCPUDataPtr data, virCPUx86CPUID *cpuid, ssize_t ncaps) + { ++ virCPUx86DataItem item = { 0 }; + size_t i; + + for (i = 0; i < ncaps; i++) { +- virCPUx86CPUID *c = &cpuid[i]; ++ item.cpuid = cpuid[i]; + +- if (virCPUx86DataAddCPUID(data, c) < 0) { +- VIR_DEBUG("Failed to add CPUID(%x,%x)", c->eax_in, c->ecx_in); ++ if (virCPUx86DataAddCPUID(data, &item) < 0) { ++ VIR_DEBUG("Failed to add CPUID(%x,%x)", ++ cpuid[i].eax_in, cpuid[i].ecx_in); + return -1; + } + } +diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c +index d6c11666c5..0b4dfd70c0 100644 +--- a/src/qemu/qemu_monitor_json.c ++++ b/src/qemu/qemu_monitor_json.c +@@ -7043,7 +7043,7 @@ static virCPUDataPtr + qemuMonitorJSONParseCPUx86Features(virJSONValuePtr data) + { + virCPUDataPtr cpudata = NULL; +- virCPUx86CPUID cpuid; ++ virCPUx86DataItem item = { 0 }; + size_t i; + + if (!(cpudata = virCPUDataNew(VIR_ARCH_X86_64))) +@@ -7051,8 +7051,8 @@ qemuMonitorJSONParseCPUx86Features(virJSONValuePtr data) + + for (i = 0; i < virJSONValueArraySize(data); i++) { + if (qemuMonitorJSONParseCPUx86FeatureWord(virJSONValueArrayGet(data, i), +- &cpuid) < 0 || +- virCPUx86DataAddCPUID(cpudata, &cpuid) < 0) ++ &item.cpuid) < 0 || ++ virCPUx86DataAddCPUID(cpudata, &item) < 0) + goto error; + } + +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_x86-Introduce-virCPUx86FeatureFilter-MSR.patch b/SOURCES/libvirt-cpu_x86-Introduce-virCPUx86FeatureFilter-MSR.patch new file mode 100644 index 0000000..33dd149 --- /dev/null +++ b/SOURCES/libvirt-cpu_x86-Introduce-virCPUx86FeatureFilter-MSR.patch @@ -0,0 +1,133 @@ +From 016b5348df8fc1007c08b0d0deec68d923be2e75 Mon Sep 17 00:00:00 2001 +Message-Id: <016b5348df8fc1007c08b0d0deec68d923be2e75@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:26:08 +0200 +Subject: [PATCH] cpu_x86: Introduce virCPUx86FeatureFilter*MSR +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This functions may be used as a virCPUDefFeatureFilter callbacks for +virCPUDefCheckFeatures, virCPUDefFilerFeatures, and similar functions to +select (virCPUx86FeatureFilterSelectMSR) or drop +(virCPUx86FeatureFilterDropMSR) features reported via MSR. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit bcfed7f1c84cbff21d129a79cbd675b0cd51613c) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Conflicts: + src/cpu/cpu_x86.h + - downstream did not switch to #pragma once + +Signed-off-by: Jiri Denemark +Message-Id: <1a0fd2733f3aaec22e4ad598086baac0f086bb47.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_x86.c | 57 ++++++++++++++++++++++++++++++++++++++++ + src/cpu/cpu_x86.h | 6 +++++ + src/libvirt_private.syms | 3 ++- + 3 files changed, 65 insertions(+), 1 deletion(-) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index 75527fd28f..ec0e408f98 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -3351,6 +3351,63 @@ virCPUx86DataAddFeature(virCPUDataPtr cpuData, + } + + ++static bool ++virCPUx86FeatureIsMSR(const char *name) ++{ ++ virCPUx86FeaturePtr feature; ++ virCPUx86DataIterator iter; ++ virCPUx86DataItemPtr item; ++ virCPUx86MapPtr map; ++ ++ if (!(map = virCPUx86GetMap())) ++ return false; ++ ++ if (!(feature = x86FeatureFind(map, name)) && ++ !(feature = x86FeatureFindInternal(name))) ++ return false; ++ ++ virCPUx86DataIteratorInit(&iter, &feature->data); ++ while ((item = virCPUx86DataNext(&iter))) { ++ if (item->type == VIR_CPU_X86_DATA_MSR) ++ return true; ++ } ++ ++ return false; ++} ++ ++ ++/** ++ * virCPUx86FeatureFilterSelectMSR: ++ * ++ * This is a callback for functions filtering features in virCPUDef. The result ++ * will contain only MSR features. ++ * ++ * Returns true if @name is an MSR feature, false otherwise. ++ */ ++bool ++virCPUx86FeatureFilterSelectMSR(const char *name, ++ void *opaque ATTRIBUTE_UNUSED) ++{ ++ return virCPUx86FeatureIsMSR(name); ++} ++ ++ ++/** ++ * virCPUx86FeatureFilterDropMSR: ++ * ++ * This is a callback for functions filtering features in virCPUDef. The result ++ * will not contain any MSR feature. ++ * ++ * Returns true if @name is not an MSR feature, false otherwise. ++ */ ++bool ++virCPUx86FeatureFilterDropMSR(const char *name, ++ void *opaque ATTRIBUTE_UNUSED) ++{ ++ return !virCPUx86FeatureIsMSR(name); ++} ++ ++ + struct cpuArchDriver cpuDriverX86 = { + .name = "x86", + .arch = archs, +diff --git a/src/cpu/cpu_x86.h b/src/cpu/cpu_x86.h +index 519024b7c0..5126679985 100644 +--- a/src/cpu/cpu_x86.h ++++ b/src/cpu/cpu_x86.h +@@ -45,4 +45,10 @@ uint32_t virCPUx86DataGetSignature(virCPUDataPtr cpuData, + int virCPUx86DataSetVendor(virCPUDataPtr cpuData, + const char *vendor); + ++bool virCPUx86FeatureFilterSelectMSR(const char *name, ++ void *opaque); ++ ++bool virCPUx86FeatureFilterDropMSR(const char *name, ++ void *opaque); ++ + #endif /* __VIR_CPU_X86_H__ */ +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 0290f960a0..f158a17b49 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -1210,7 +1210,8 @@ virCPUx86DataAdd; + virCPUx86DataGetSignature; + virCPUx86DataSetSignature; + virCPUx86DataSetVendor; +- ++virCPUx86FeatureFilterDropMSR; ++virCPUx86FeatureFilterSelectMSR; + + # datatypes.h + virConnectClass; +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_x86-Log-decoded-CPU-model-and-signatures.patch b/SOURCES/libvirt-cpu_x86-Log-decoded-CPU-model-and-signatures.patch new file mode 100644 index 0000000..2b67e02 --- /dev/null +++ b/SOURCES/libvirt-cpu_x86-Log-decoded-CPU-model-and-signatures.patch @@ -0,0 +1,79 @@ +From 3335b5e0db21375053c5005be9f820f7ba945010 Mon Sep 17 00:00:00 2001 +Message-Id: <3335b5e0db21375053c5005be9f820f7ba945010@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:02 +0200 +Subject: [PATCH] cpu_x86: Log decoded CPU model and signatures +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The log message may be useful when debugging why a specific CPU model +was selected for a given set of CPUID data. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 5ced12decea42f1d588f2cb28b10ca7a5772098e) + +https://bugzilla.redhat.com/show_bug.cgi?id=1686895 + +Signed-off-by: Jiri Denemark +Message-Id: +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_x86.c | 26 ++++++++++++++++++++++++++ + 1 file changed, 26 insertions(+) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index 7bd8119c23..ba14a6097d 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -1769,6 +1769,26 @@ x86ModelHasSignature(virCPUx86ModelPtr model, + } + + ++static char * ++x86FormatSignatures(virCPUx86ModelPtr model) ++{ ++ virBuffer buf = VIR_BUFFER_INITIALIZER; ++ size_t i; ++ ++ for (i = 0; i < model->nsignatures; i++) { ++ virBufferAsprintf(&buf, "%06lx,", ++ (unsigned long)model->signatures[i]); ++ } ++ ++ virBufferTrim(&buf, ",", -1); ++ ++ if (virBufferCheckError(&buf) < 0) ++ return NULL; ++ ++ return virBufferContentAndReset(&buf); ++} ++ ++ + /* + * Checks whether a candidate model is a better fit for the CPU data than the + * current model. +@@ -1892,6 +1912,7 @@ x86Decode(virCPUDefPtr cpu, + virCPUx86Data features = VIR_CPU_X86_DATA_INIT; + virCPUx86VendorPtr vendor; + virDomainCapsCPUModelPtr hvModel = NULL; ++ VIR_AUTOFREE(char *) sigs = NULL; + uint32_t signature; + ssize_t i; + int rc; +@@ -1984,6 +2005,11 @@ x86Decode(virCPUDefPtr cpu, + if (vendor && VIR_STRDUP(cpu->vendor, vendor->name) < 0) + goto cleanup; + ++ sigs = x86FormatSignatures(model); ++ ++ VIR_DEBUG("Using CPU model %s (signatures %s) for CPU with signature %06lx", ++ model->name, NULLSTR(sigs), (unsigned long)signature); ++ + VIR_STEAL_PTR(cpu->model, cpuModel->model); + VIR_STEAL_PTR(cpu->features, cpuModel->features); + cpu->nfeatures = cpuModel->nfeatures; +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_x86-Make-sure-CPU-model-names-are-unique-in-cpu_map.patch b/SOURCES/libvirt-cpu_x86-Make-sure-CPU-model-names-are-unique-in-cpu_map.patch new file mode 100644 index 0000000..fa962ba --- /dev/null +++ b/SOURCES/libvirt-cpu_x86-Make-sure-CPU-model-names-are-unique-in-cpu_map.patch @@ -0,0 +1,49 @@ +From 84ee95b9504d89236078952a44c1a8b7dba148ca Mon Sep 17 00:00:00 2001 +Message-Id: <84ee95b9504d89236078952a44c1a8b7dba148ca@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:24:58 +0200 +Subject: [PATCH] cpu_x86: Make sure CPU model names are unique in cpu_map +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Having multiple CPU model definitions with the same name could result in +unexpected behavior. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 8d7245441a473bc1f73005fd378d4a925870cce6) + +https://bugzilla.redhat.com/show_bug.cgi?id=1686895 + +Signed-off-by: Jiri Denemark +Message-Id: +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_x86.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index 91362198ab..51cb9b7143 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -1291,9 +1291,15 @@ x86ModelParse(xmlXPathContextPtr ctxt, + void *data) + { + virCPUx86MapPtr map = data; +- virCPUx86ModelPtr model; ++ virCPUx86ModelPtr model = NULL; + int ret = -1; + ++ if (x86ModelFind(map, name)) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Multiple definitions of CPU model '%s'"), name); ++ goto cleanup; ++ } ++ + if (!(model = x86ModelNew())) + goto cleanup; + +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_x86-Make-x86cpuidAndBits-more-general.patch b/SOURCES/libvirt-cpu_x86-Make-x86cpuidAndBits-more-general.patch new file mode 100644 index 0000000..5065e64 --- /dev/null +++ b/SOURCES/libvirt-cpu_x86-Make-x86cpuidAndBits-more-general.patch @@ -0,0 +1,64 @@ +From be1b7ab3f5a634de17359376d559d5c312f5623f Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:35 +0200 +Subject: [PATCH] cpu_x86: Make x86cpuidAndBits more general +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The function now works on virCPUx86DataItem and it's renamed as +virCPUx86DataItemAndBits. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit da1efddfa6606520fb5f16622bc522b231484b54) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Signed-off-by: Jiri Denemark +Message-Id: +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_x86.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index 5fbf0294bb..54da9a985c 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -242,16 +242,16 @@ virCPUx86DataItemClearBits(virCPUx86DataItemPtr item, + + + static void +-x86cpuidAndBits(virCPUx86CPUID *cpuid, +- const virCPUx86CPUID *mask) ++virCPUx86DataItemAndBits(virCPUx86DataItemPtr item, ++ const virCPUx86DataItem *mask) + { + if (!mask) + return; + +- cpuid->eax &= mask->eax; +- cpuid->ebx &= mask->ebx; +- cpuid->ecx &= mask->ecx; +- cpuid->edx &= mask->edx; ++ item->cpuid.eax &= mask->cpuid.eax; ++ item->cpuid.ebx &= mask->cpuid.ebx; ++ item->cpuid.ecx &= mask->cpuid.ecx; ++ item->cpuid.edx &= mask->cpuid.edx; + } + + +@@ -447,7 +447,7 @@ x86DataIntersect(virCPUx86Data *data1, + while ((item1 = virCPUx86DataNext(&iter))) { + item2 = virCPUx86DataGet(data2, item1); + if (item2) +- x86cpuidAndBits(&item1->cpuid, &item2->cpuid); ++ virCPUx86DataItemAndBits(item1, item2); + else + virCPUx86DataItemClearBits(item1, item1); + } +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_x86-Make-x86cpuidClearBits-more-general.patch b/SOURCES/libvirt-cpu_x86-Make-x86cpuidClearBits-more-general.patch new file mode 100644 index 0000000..4103fd0 --- /dev/null +++ b/SOURCES/libvirt-cpu_x86-Make-x86cpuidClearBits-more-general.patch @@ -0,0 +1,84 @@ +From e9bc4fcd2c16a80cf564879d154f3083a6766ff9 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:34 +0200 +Subject: [PATCH] cpu_x86: Make x86cpuidClearBits more general +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The parameters changed from virCPUx86CPUID to virCPUx86DataItem and the +function is now called virCPUx86DataItemClearBits. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 4e3cab2d002d5f4cfdf81359467de8ffe4e18682) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Signed-off-by: Jiri Denemark +Message-Id: +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_x86.c | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index e2951ed1b0..5fbf0294bb 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -228,16 +228,16 @@ virCPUx86DataItemSetBits(virCPUx86DataItemPtr item, + + + static void +-x86cpuidClearBits(virCPUx86CPUID *cpuid, +- const virCPUx86CPUID *mask) ++virCPUx86DataItemClearBits(virCPUx86DataItemPtr item, ++ const virCPUx86DataItem *mask) + { + if (!mask) + return; + +- cpuid->eax &= ~mask->eax; +- cpuid->ebx &= ~mask->ebx; +- cpuid->ecx &= ~mask->ecx; +- cpuid->edx &= ~mask->edx; ++ item->cpuid.eax &= ~mask->cpuid.eax; ++ item->cpuid.ebx &= ~mask->cpuid.ebx; ++ item->cpuid.ecx &= ~mask->cpuid.ecx; ++ item->cpuid.edx &= ~mask->cpuid.edx; + } + + +@@ -430,8 +430,8 @@ x86DataSubtract(virCPUx86Data *data1, + virCPUx86DataItemPtr item2; + + while ((item1 = virCPUx86DataNext(&iter))) { +- if ((item2 = virCPUx86DataGet(data2, item1))) +- x86cpuidClearBits(&item1->cpuid, &item2->cpuid); ++ item2 = virCPUx86DataGet(data2, item1); ++ virCPUx86DataItemClearBits(item1, item2); + } + } + +@@ -449,7 +449,7 @@ x86DataIntersect(virCPUx86Data *data1, + if (item2) + x86cpuidAndBits(&item1->cpuid, &item2->cpuid); + else +- x86cpuidClearBits(&item1->cpuid, &item1->cpuid); ++ virCPUx86DataItemClearBits(item1, item1); + } + } + +@@ -516,7 +516,7 @@ x86DataToVendor(const virCPUx86Data *data, + virCPUx86VendorPtr vendor = map->vendors[i]; + if ((item = virCPUx86DataGet(data, &vendor->data)) && + x86cpuidMatchMasked(&item->cpuid, &vendor->data.cpuid)) { +- x86cpuidClearBits(&item->cpuid, &vendor->data.cpuid); ++ virCPUx86DataItemClearBits(item, &vendor->data); + return vendor; + } + } +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_x86-Make-x86cpuidMatch-more-general.patch b/SOURCES/libvirt-cpu_x86-Make-x86cpuidMatch-more-general.patch new file mode 100644 index 0000000..f6fd0fd --- /dev/null +++ b/SOURCES/libvirt-cpu_x86-Make-x86cpuidMatch-more-general.patch @@ -0,0 +1,96 @@ +From 759fe35a1acdccf68577de62752c087aea4b8268 Mon Sep 17 00:00:00 2001 +Message-Id: <759fe35a1acdccf68577de62752c087aea4b8268@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:37 +0200 +Subject: [PATCH] cpu_x86: Make x86cpuidMatch more general +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The function now works on virCPUx86DataItem and it's called +virCPUx86DataItemMatch. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 10b80165dba31f99306f39e348e3a6335feec5ef) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Signed-off-by: Jiri Denemark +Message-Id: <0b829eb945561e54c1fc4d333c59af53759edf19.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_x86.c | 21 ++++++++++----------- + 1 file changed, 10 insertions(+), 11 deletions(-) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index 1bb35ec4e8..11c023ac31 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -41,8 +41,6 @@ VIR_LOG_INIT("cpu.cpu_x86"); + + #define VENDOR_STRING_LENGTH 12 + +-static const virCPUx86CPUID cpuidNull = { 0 }; +- + static const virArch archs[] = { VIR_ARCH_I686, VIR_ARCH_X86_64 }; + + typedef struct _virCPUx86Vendor virCPUx86Vendor; +@@ -192,13 +190,13 @@ struct _virCPUx86DataIterator { + + + static bool +-x86cpuidMatch(const virCPUx86CPUID *cpuid1, +- const virCPUx86CPUID *cpuid2) ++virCPUx86DataItemMatch(const virCPUx86DataItem *item1, ++ const virCPUx86DataItem *item2) + { +- return (cpuid1->eax == cpuid2->eax && +- cpuid1->ebx == cpuid2->ebx && +- cpuid1->ecx == cpuid2->ecx && +- cpuid1->edx == cpuid2->edx); ++ return (item1->cpuid.eax == item2->cpuid.eax && ++ item1->cpuid.ebx == item2->cpuid.ebx && ++ item1->cpuid.ecx == item2->cpuid.ecx && ++ item1->cpuid.edx == item2->cpuid.edx); + } + + +@@ -317,6 +315,7 @@ static virCPUx86DataItemPtr + virCPUx86DataNext(virCPUx86DataIteratorPtr iterator) + { + const virCPUx86Data *data = iterator->data; ++ virCPUx86DataItem zero = { 0 }; + + if (!data) + return NULL; +@@ -324,7 +323,7 @@ virCPUx86DataNext(virCPUx86DataIteratorPtr iterator) + while (++iterator->pos < data->len) { + virCPUx86DataItemPtr item = data->items + iterator->pos; + +- if (!x86cpuidMatch(&item->cpuid, &cpuidNull)) ++ if (!virCPUx86DataItemMatch(item, &zero)) + return item; + } + +@@ -1155,7 +1154,7 @@ x86ModelCompare(virCPUx86ModelPtr model1, + virCPUx86CompareResult match = SUPERSET; + + if ((item2 = virCPUx86DataGet(&model2->data, item1))) { +- if (x86cpuidMatch(&item1->cpuid, &item2->cpuid)) ++ if (virCPUx86DataItemMatch(item1, item2)) + continue; + else if (!virCPUx86DataItemMatchMasked(item1, item2)) + match = SUBSET; +@@ -1171,7 +1170,7 @@ x86ModelCompare(virCPUx86ModelPtr model1, + virCPUx86CompareResult match = SUBSET; + + if ((item1 = virCPUx86DataGet(&model1->data, item2))) { +- if (x86cpuidMatch(&item2->cpuid, &item1->cpuid)) ++ if (virCPUx86DataItemMatch(item2, item1)) + continue; + else if (!virCPUx86DataItemMatchMasked(item2, item1)) + match = SUPERSET; +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_x86-Make-x86cpuidMatchMasked-more-general.patch b/SOURCES/libvirt-cpu_x86-Make-x86cpuidMatchMasked-more-general.patch new file mode 100644 index 0000000..e1c1925 --- /dev/null +++ b/SOURCES/libvirt-cpu_x86-Make-x86cpuidMatchMasked-more-general.patch @@ -0,0 +1,88 @@ +From 920ac610bc68ffd7de1ac14c401c7f8c37f3337e Mon Sep 17 00:00:00 2001 +Message-Id: <920ac610bc68ffd7de1ac14c401c7f8c37f3337e@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:36 +0200 +Subject: [PATCH] cpu_x86: Make x86cpuidMatchMasked more general +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The function is renamed as virCPUx86DataItemMatchMasked to reflect the +change in parameter types. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 2eea67a98eab58b46dbf4275819c06c90bc4c5b6) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Signed-off-by: Jiri Denemark +Message-Id: <7c0a54c618d67d64663eb92d5eeb1d8a2270be16.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_x86.c | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index 54da9a985c..1bb35ec4e8 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -203,13 +203,13 @@ x86cpuidMatch(const virCPUx86CPUID *cpuid1, + + + static bool +-x86cpuidMatchMasked(const virCPUx86CPUID *cpuid, +- const virCPUx86CPUID *mask) ++virCPUx86DataItemMatchMasked(const virCPUx86DataItem *item, ++ const virCPUx86DataItem *mask) + { +- return ((cpuid->eax & mask->eax) == mask->eax && +- (cpuid->ebx & mask->ebx) == mask->ebx && +- (cpuid->ecx & mask->ecx) == mask->ecx && +- (cpuid->edx & mask->edx) == mask->edx); ++ return ((item->cpuid.eax & mask->cpuid.eax) == mask->cpuid.eax && ++ (item->cpuid.ebx & mask->cpuid.ebx) == mask->cpuid.ebx && ++ (item->cpuid.ecx & mask->cpuid.ecx) == mask->cpuid.ecx && ++ (item->cpuid.edx & mask->cpuid.edx) == mask->cpuid.edx); + } + + +@@ -474,7 +474,7 @@ x86DataIsSubset(const virCPUx86Data *data, + + while ((itemSubset = virCPUx86DataNext(&iter))) { + if (!(item = virCPUx86DataGet(data, itemSubset)) || +- !x86cpuidMatchMasked(&item->cpuid, &itemSubset->cpuid)) ++ !virCPUx86DataItemMatchMasked(item, itemSubset)) + return false; + } + +@@ -515,7 +515,7 @@ x86DataToVendor(const virCPUx86Data *data, + for (i = 0; i < map->nvendors; i++) { + virCPUx86VendorPtr vendor = map->vendors[i]; + if ((item = virCPUx86DataGet(data, &vendor->data)) && +- x86cpuidMatchMasked(&item->cpuid, &vendor->data.cpuid)) { ++ virCPUx86DataItemMatchMasked(item, &vendor->data)) { + virCPUx86DataItemClearBits(item, &vendor->data); + return vendor; + } +@@ -1157,7 +1157,7 @@ x86ModelCompare(virCPUx86ModelPtr model1, + if ((item2 = virCPUx86DataGet(&model2->data, item1))) { + if (x86cpuidMatch(&item1->cpuid, &item2->cpuid)) + continue; +- else if (!x86cpuidMatchMasked(&item1->cpuid, &item2->cpuid)) ++ else if (!virCPUx86DataItemMatchMasked(item1, item2)) + match = SUBSET; + } + +@@ -1173,7 +1173,7 @@ x86ModelCompare(virCPUx86ModelPtr model1, + if ((item1 = virCPUx86DataGet(&model1->data, item2))) { + if (x86cpuidMatch(&item2->cpuid, &item1->cpuid)) + continue; +- else if (!x86cpuidMatchMasked(&item2->cpuid, &item1->cpuid)) ++ else if (!virCPUx86DataItemMatchMasked(item2, item1)) + match = SUPERSET; + } + +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_x86-Make-x86cpuidSetBits-more-general.patch b/SOURCES/libvirt-cpu_x86-Make-x86cpuidSetBits-more-general.patch new file mode 100644 index 0000000..642480d --- /dev/null +++ b/SOURCES/libvirt-cpu_x86-Make-x86cpuidSetBits-more-general.patch @@ -0,0 +1,64 @@ +From d32fbe55ad3ee1bbbfe2adc9ab47034c7a5cb884 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:33 +0200 +Subject: [PATCH] cpu_x86: Make x86cpuidSetBits more general +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The function is renamed as virCPUx86DataItemSetBits and it works on +virCPUx86DataItem now. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 9c6f00fc3351800dc8b63472e71b398c180161d8) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Signed-off-by: Jiri Denemark +Message-Id: +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_x86.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index 5a09033d2a..e2951ed1b0 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -214,16 +214,16 @@ x86cpuidMatchMasked(const virCPUx86CPUID *cpuid, + + + static void +-x86cpuidSetBits(virCPUx86CPUID *cpuid, +- const virCPUx86CPUID *mask) ++virCPUx86DataItemSetBits(virCPUx86DataItemPtr item, ++ const virCPUx86DataItem *mask) + { + if (!mask) + return; + +- cpuid->eax |= mask->eax; +- cpuid->ebx |= mask->ebx; +- cpuid->ecx |= mask->ecx; +- cpuid->edx |= mask->edx; ++ item->cpuid.eax |= mask->cpuid.eax; ++ item->cpuid.ebx |= mask->cpuid.ebx; ++ item->cpuid.ecx |= mask->cpuid.ecx; ++ item->cpuid.edx |= mask->cpuid.edx; + } + + +@@ -391,7 +391,7 @@ virCPUx86DataAddItem(virCPUx86Data *data, + virCPUx86DataItemPtr existing; + + if ((existing = virCPUx86DataGet(data, item))) { +- x86cpuidSetBits(&existing->cpuid, &item->cpuid); ++ virCPUx86DataItemSetBits(existing, item); + } else { + if (VIR_APPEND_ELEMENT_COPY(data->items, data->len, + *((virCPUx86DataItemPtr)item)) < 0) +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_x86-Move-CheckFeature-functions.patch b/SOURCES/libvirt-cpu_x86-Move-CheckFeature-functions.patch new file mode 100644 index 0000000..e098b99 --- /dev/null +++ b/SOURCES/libvirt-cpu_x86-Move-CheckFeature-functions.patch @@ -0,0 +1,115 @@ +From dec2ce4345db0d13cff8c639c69afbf894ee593a Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:40 +0200 +Subject: [PATCH] cpu_x86: Move *CheckFeature functions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +They are static and we will need to call them a little bit closer to the +beginning of the file. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit e17d10386bd9abcfb37c7d8b151bbd1071a87fc4) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Signed-off-by: Jiri Denemark +Message-Id: <41d2a36757ed83f70c9dc23e9b984e109e5a81ba.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_x86.c | 69 ++++++++++++++++++++++++----------------------- + 1 file changed, 35 insertions(+), 34 deletions(-) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index 49562944c1..fdc2974a0d 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -2706,6 +2706,41 @@ cpuidSet(uint32_t base, virCPUDataPtr data) + } + + ++static int ++virCPUx86CheckFeature(const virCPUDef *cpu, ++ const char *name) ++{ ++ int ret = -1; ++ virCPUx86MapPtr map; ++ virCPUx86ModelPtr model = NULL; ++ ++ if (!(map = virCPUx86GetMap())) ++ return -1; ++ ++ if (!(model = x86ModelFromCPU(cpu, map, -1))) ++ goto cleanup; ++ ++ ret = x86FeatureInData(name, &model->data, map); ++ ++ cleanup: ++ x86ModelFree(model); ++ return ret; ++} ++ ++ ++static int ++virCPUx86DataCheckFeature(const virCPUData *data, ++ const char *name) ++{ ++ virCPUx86MapPtr map; ++ ++ if (!(map = virCPUx86GetMap())) ++ return -1; ++ ++ return x86FeatureInData(name, &data->data.x86, map); ++} ++ ++ + static int + virCPUx86GetHost(virCPUDefPtr cpu, + virDomainCapsCPUModelsPtr models) +@@ -3062,40 +3097,6 @@ virCPUx86UpdateLive(virCPUDefPtr cpu, + } + + +-static int +-virCPUx86CheckFeature(const virCPUDef *cpu, +- const char *name) +-{ +- int ret = -1; +- virCPUx86MapPtr map; +- virCPUx86ModelPtr model = NULL; +- +- if (!(map = virCPUx86GetMap())) +- return -1; +- +- if (!(model = x86ModelFromCPU(cpu, map, -1))) +- goto cleanup; +- +- ret = x86FeatureInData(name, &model->data, map); +- +- cleanup: +- x86ModelFree(model); +- return ret; +-} +- +- +-static int +-virCPUx86DataCheckFeature(const virCPUData *data, +- const char *name) +-{ +- virCPUx86MapPtr map; +- +- if (!(map = virCPUx86GetMap())) +- return -1; +- +- return x86FeatureInData(name, &data->data.x86, map); +-} +- + static int + virCPUx86GetModels(char ***models) + { +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_x86-Read-CPU-features-from-IA32_ARCH_CAPABILITIES-MSR.patch b/SOURCES/libvirt-cpu_x86-Read-CPU-features-from-IA32_ARCH_CAPABILITIES-MSR.patch new file mode 100644 index 0000000..d583e77 --- /dev/null +++ b/SOURCES/libvirt-cpu_x86-Read-CPU-features-from-IA32_ARCH_CAPABILITIES-MSR.patch @@ -0,0 +1,61 @@ +From 0004d2f3b0c3b21336415a967d70b7e9c2d08f54 Mon Sep 17 00:00:00 2001 +Message-Id: <0004d2f3b0c3b21336415a967d70b7e9c2d08f54@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:26:09 +0200 +Subject: [PATCH] cpu_x86: Read CPU features from IA32_ARCH_CAPABILITIES MSR +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This is used by the host capabilities code to construct host CPU +definition. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 56b254dccc96b7339494812c9df07ccf6af3da95) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Signed-off-by: Jiri Denemark +Message-Id: <58ad207c48e0f2a6c44ff097b0881b649826ecd4.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_x86.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index ec0e408f98..0a520f07ff 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -2771,6 +2771,28 @@ virCPUx86GetHost(virCPUDefPtr cpu, + cpuidSet(CPUX86_EXTENDED, cpuData) < 0) + goto cleanup; + ++ /* Read the IA32_ARCH_CAPABILITIES MSR (0x10a) if supported. ++ * This is best effort since there might be no way to read the MSR ++ * when we are not running as root. */ ++ if (virCPUx86DataCheckFeature(cpuData, "arch-capabilities") == 1) { ++ uint64_t msr; ++ unsigned long index = 0x10a; ++ ++ if (virHostCPUGetMSR(index, &msr) == 0) { ++ virCPUx86DataItem item = { ++ .type = VIR_CPU_X86_DATA_MSR, ++ .data.msr = { ++ .index = index, ++ .eax = msr & 0xffffffff, ++ .edx = msr >> 32, ++ }, ++ }; ++ ++ if (virCPUx86DataAdd(cpuData, &item) < 0) ++ return -1; ++ } ++ } ++ + ret = x86DecodeCPUData(cpu, cpuData, models); + cpu->microcodeVersion = virHostCPUGetMicrocodeVersion(); + +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_x86-Rename-virCPUx86CPUIDSorter.patch b/SOURCES/libvirt-cpu_x86-Rename-virCPUx86CPUIDSorter.patch new file mode 100644 index 0000000..c7e1099 --- /dev/null +++ b/SOURCES/libvirt-cpu_x86-Rename-virCPUx86CPUIDSorter.patch @@ -0,0 +1,50 @@ +From ea8bf8889659145cbf53306e3d16357f40679e4e Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:27 +0200 +Subject: [PATCH] cpu_x86: Rename virCPUx86CPUIDSorter +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +It is called virCPUx86DataSorter since the function will work on any CPU +data type. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 95accfa7fa15b21bf4824b55be666312d11c273a) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Signed-off-by: Jiri Denemark +Message-Id: <4661aa497f1b8d9b5ca1383a91affe24cd54caa9.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_x86.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index 52709f109e..efb2a3bb07 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -286,7 +286,7 @@ x86FeatureFindInternal(const char *name) + + + static int +-virCPUx86CPUIDSorter(const void *a, const void *b) ++virCPUx86DataSorter(const void *a, const void *b) + { + virCPUx86DataItemPtr da = (virCPUx86DataItemPtr) a; + virCPUx86DataItemPtr db = (virCPUx86DataItemPtr) b; +@@ -391,7 +391,7 @@ virCPUx86DataAddCPUIDInt(virCPUx86Data *data, + return -1; + + qsort(data->items, data->len, +- sizeof(virCPUx86DataItem), virCPUx86CPUIDSorter); ++ sizeof(virCPUx86DataItem), virCPUx86DataSorter); + } + + return 0; +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_x86-Rename-virCPUx86DataAddCPUID.patch b/SOURCES/libvirt-cpu_x86-Rename-virCPUx86DataAddCPUID.patch new file mode 100644 index 0000000..8ad7f35 --- /dev/null +++ b/SOURCES/libvirt-cpu_x86-Rename-virCPUx86DataAddCPUID.patch @@ -0,0 +1,274 @@ +From d4df159ee1e489c9afc238f39e6bb52d4f71bce7 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:29 +0200 +Subject: [PATCH] cpu_x86: Rename virCPUx86DataAddCPUID +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +It's called virCPUx86DataAdd now. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 8f1a8ce397d7514bee9f370a1531d668e01ec923) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Signed-off-by: Jiri Denemark +Message-Id: <1be869684ede8249c16fcab128fc6775edda08be.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_x86.c | 46 +++++++++++++++++----------------- + src/cpu/cpu_x86.h | 4 +-- + src/libvirt_private.syms | 2 +- + src/libxl/libxl_capabilities.c | 2 +- + src/qemu/qemu_monitor_json.c | 2 +- + 5 files changed, 28 insertions(+), 28 deletions(-) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index 7e077577d3..6d48c9264c 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -1505,7 +1505,7 @@ virCPUx86DataParse(xmlXPathContextPtr ctxt) + _("failed to parse cpuid[%zu]"), i); + goto error; + } +- if (virCPUx86DataAddCPUID(cpuData, &item) < 0) ++ if (virCPUx86DataAdd(cpuData, &item) < 0) + goto error; + } + +@@ -2153,7 +2153,7 @@ x86Encode(virArch arch, + if (!(data_vendor = virCPUDataNew(arch))) + goto error; + +- if (v && virCPUx86DataAddCPUID(data_vendor, &v->data) < 0) ++ if (v && virCPUx86DataAdd(data_vendor, &v->data) < 0) + goto error; + } + +@@ -2229,13 +2229,13 @@ cpuidSetLeaf4(virCPUDataPtr data, + virCPUx86DataItem item = *subLeaf0; + virCPUx86CPUIDPtr cpuid = &item.cpuid; + +- if (virCPUx86DataAddCPUID(data, subLeaf0) < 0) ++ if (virCPUx86DataAdd(data, subLeaf0) < 0) + return -1; + + while (cpuid->eax & 0x1f) { + cpuid->ecx_in++; + cpuidCall(cpuid); +- if (virCPUx86DataAddCPUID(data, &item) < 0) ++ if (virCPUx86DataAdd(data, &item) < 0) + return -1; + } + return 0; +@@ -2254,13 +2254,13 @@ cpuidSetLeaf7(virCPUDataPtr data, + virCPUx86CPUIDPtr cpuid = &item.cpuid; + uint32_t sub; + +- if (virCPUx86DataAddCPUID(data, subLeaf0) < 0) ++ if (virCPUx86DataAdd(data, subLeaf0) < 0) + return -1; + + for (sub = 1; sub <= subLeaf0->cpuid.eax; sub++) { + cpuid->ecx_in = sub; + cpuidCall(cpuid); +- if (virCPUx86DataAddCPUID(data, &item) < 0) ++ if (virCPUx86DataAdd(data, &item) < 0) + return -1; + } + return 0; +@@ -2282,7 +2282,7 @@ cpuidSetLeafB(virCPUDataPtr data, + virCPUx86CPUIDPtr cpuid = &item.cpuid; + + while (cpuid->ecx & 0xff00) { +- if (virCPUx86DataAddCPUID(data, &item) < 0) ++ if (virCPUx86DataAdd(data, &item) < 0) + return -1; + cpuid->ecx_in++; + cpuidCall(cpuid); +@@ -2309,12 +2309,12 @@ cpuidSetLeafD(virCPUDataPtr data, + virCPUx86CPUID sub1; + uint32_t sub; + +- if (virCPUx86DataAddCPUID(data, subLeaf0) < 0) ++ if (virCPUx86DataAdd(data, subLeaf0) < 0) + return -1; + + cpuid->ecx_in = 1; + cpuidCall(cpuid); +- if (virCPUx86DataAddCPUID(data, &item) < 0) ++ if (virCPUx86DataAdd(data, &item) < 0) + return -1; + + sub0 = subLeaf0->cpuid; +@@ -2331,7 +2331,7 @@ cpuidSetLeafD(virCPUDataPtr data, + + cpuid->ecx_in = sub; + cpuidCall(cpuid); +- if (virCPUx86DataAddCPUID(data, &item) < 0) ++ if (virCPUx86DataAdd(data, &item) < 0) + return -1; + } + return 0; +@@ -2356,7 +2356,7 @@ cpuidSetLeafResID(virCPUDataPtr data, + virCPUx86CPUIDPtr cpuid = &item.cpuid; + uint32_t sub; + +- if (virCPUx86DataAddCPUID(data, subLeaf0) < 0) ++ if (virCPUx86DataAdd(data, subLeaf0) < 0) + return -1; + + for (sub = 1; sub < 32; sub++) { +@@ -2364,7 +2364,7 @@ cpuidSetLeafResID(virCPUDataPtr data, + continue; + cpuid->ecx_in = sub; + cpuidCall(cpuid); +- if (virCPUx86DataAddCPUID(data, &item) < 0) ++ if (virCPUx86DataAdd(data, &item) < 0) + return -1; + } + return 0; +@@ -2388,19 +2388,19 @@ cpuidSetLeaf12(virCPUDataPtr data, + !(leaf7->cpuid.ebx & (1 << 2))) + return 0; + +- if (virCPUx86DataAddCPUID(data, subLeaf0) < 0) ++ if (virCPUx86DataAdd(data, subLeaf0) < 0) + return -1; + + cpuid->eax_in = 0x12; + cpuid->ecx_in = 1; + cpuidCall(cpuid); +- if (virCPUx86DataAddCPUID(data, &item) < 0) ++ if (virCPUx86DataAdd(data, &item) < 0) + return -1; + + cpuid->ecx_in = 2; + cpuidCall(cpuid); + while (cpuid->eax & 0xf) { +- if (virCPUx86DataAddCPUID(data, &item) < 0) ++ if (virCPUx86DataAdd(data, &item) < 0) + return -1; + cpuid->ecx_in++; + cpuidCall(cpuid); +@@ -2421,13 +2421,13 @@ cpuidSetLeaf14(virCPUDataPtr data, + virCPUx86CPUIDPtr cpuid = &item.cpuid; + uint32_t sub; + +- if (virCPUx86DataAddCPUID(data, subLeaf0) < 0) ++ if (virCPUx86DataAdd(data, subLeaf0) < 0) + return -1; + + for (sub = 1; sub <= subLeaf0->cpuid.eax; sub++) { + cpuid->ecx_in = sub; + cpuidCall(cpuid); +- if (virCPUx86DataAddCPUID(data, &item) < 0) ++ if (virCPUx86DataAdd(data, &item) < 0) + return -1; + } + return 0; +@@ -2450,13 +2450,13 @@ cpuidSetLeaf17(virCPUDataPtr data, + if (subLeaf0->cpuid.eax < 3) + return 0; + +- if (virCPUx86DataAddCPUID(data, subLeaf0) < 0) ++ if (virCPUx86DataAdd(data, subLeaf0) < 0) + return -1; + + for (sub = 1; sub <= subLeaf0->cpuid.eax; sub++) { + cpuid->ecx_in = sub; + cpuidCall(cpuid); +- if (virCPUx86DataAddCPUID(data, &item) < 0) ++ if (virCPUx86DataAdd(data, &item) < 0) + return -1; + } + return 0; +@@ -2502,7 +2502,7 @@ cpuidSet(uint32_t base, virCPUDataPtr data) + else if (leaf == 0x17) + rc = cpuidSetLeaf17(data, &item); + else +- rc = virCPUx86DataAddCPUID(data, &item); ++ rc = virCPUx86DataAdd(data, &item); + + if (rc < 0) + return -1; +@@ -3077,8 +3077,8 @@ virCPUx86ValidateFeatures(virCPUDefPtr cpu) + + + int +-virCPUx86DataAddCPUID(virCPUDataPtr cpuData, +- const virCPUx86DataItem *item) ++virCPUx86DataAdd(virCPUDataPtr cpuData, ++ const virCPUx86DataItem *item) + { + return virCPUx86DataAddItem(&cpuData->data.x86, item); + } +@@ -3117,7 +3117,7 @@ virCPUx86DataSetVendor(virCPUDataPtr cpuData, + if (virCPUx86VendorToCPUID(vendor, &item) < 0) + return -1; + +- return virCPUx86DataAddCPUID(cpuData, &item); ++ return virCPUx86DataAdd(cpuData, &item); + } + + +diff --git a/src/cpu/cpu_x86.h b/src/cpu/cpu_x86.h +index 94655746c6..8b51cef9c1 100644 +--- a/src/cpu/cpu_x86.h ++++ b/src/cpu/cpu_x86.h +@@ -29,8 +29,8 @@ + + extern struct cpuArchDriver cpuDriverX86; + +-int virCPUx86DataAddCPUID(virCPUDataPtr cpuData, +- const virCPUx86DataItem *cpuid); ++int virCPUx86DataAdd(virCPUDataPtr cpuData, ++ const virCPUx86DataItem *cpuid); + + int virCPUx86DataSetSignature(virCPUDataPtr cpuData, + unsigned int family, +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index a275fa9aa1..347667b17c 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -1203,7 +1203,7 @@ virCPUValidateFeatures; + + + # cpu/cpu_x86.h +-virCPUx86DataAddCPUID; ++virCPUx86DataAdd; + virCPUx86DataAddFeature; + virCPUx86DataGetSignature; + virCPUx86DataSetSignature; +diff --git a/src/libxl/libxl_capabilities.c b/src/libxl/libxl_capabilities.c +index 231d72669f..2b351fbdde 100644 +--- a/src/libxl/libxl_capabilities.c ++++ b/src/libxl/libxl_capabilities.c +@@ -73,7 +73,7 @@ libxlCapsAddCPUID(virCPUDataPtr data, virCPUx86CPUID *cpuid, ssize_t ncaps) + for (i = 0; i < ncaps; i++) { + item.cpuid = cpuid[i]; + +- if (virCPUx86DataAddCPUID(data, &item) < 0) { ++ if (virCPUx86DataAdd(data, &item) < 0) { + VIR_DEBUG("Failed to add CPUID(%x,%x)", + cpuid[i].eax_in, cpuid[i].ecx_in); + return -1; +diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c +index 0b4dfd70c0..abfaa6e68a 100644 +--- a/src/qemu/qemu_monitor_json.c ++++ b/src/qemu/qemu_monitor_json.c +@@ -7052,7 +7052,7 @@ qemuMonitorJSONParseCPUx86Features(virJSONValuePtr data) + for (i = 0; i < virJSONValueArraySize(data); i++) { + if (qemuMonitorJSONParseCPUx86FeatureWord(virJSONValueArrayGet(data, i), + &item.cpuid) < 0 || +- virCPUx86DataAddCPUID(cpudata, &item) < 0) ++ virCPUx86DataAdd(cpudata, &item) < 0) + goto error; + } + +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_x86-Rename-virCPUx86DataAddCPUIDInt.patch b/SOURCES/libvirt-cpu_x86-Rename-virCPUx86DataAddCPUIDInt.patch new file mode 100644 index 0000000..fda0cf9 --- /dev/null +++ b/SOURCES/libvirt-cpu_x86-Rename-virCPUx86DataAddCPUIDInt.patch @@ -0,0 +1,107 @@ +From 39da1d7fe9d2bd12c10c40de62c36724556797be Mon Sep 17 00:00:00 2001 +Message-Id: <39da1d7fe9d2bd12c10c40de62c36724556797be@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:28 +0200 +Subject: [PATCH] cpu_x86: Rename virCPUx86DataAddCPUIDInt +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The new name is virCPUx86DataAddItem. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit ce42042577ada2616a7b062f890677f9797c7bf9) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Signed-off-by: Jiri Denemark +Message-Id: <631af83ec447522318e8169b0b9ef607b764befa.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_x86.c | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index efb2a3bb07..7e077577d3 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -378,8 +378,8 @@ x86DataCopy(virCPUx86Data *dst, const virCPUx86Data *src) + + + static int +-virCPUx86DataAddCPUIDInt(virCPUx86Data *data, +- const virCPUx86DataItem *item) ++virCPUx86DataAddItem(virCPUx86Data *data, ++ const virCPUx86DataItem *item) + { + virCPUx86DataItemPtr existing; + +@@ -412,7 +412,7 @@ x86DataAdd(virCPUx86Data *data1, + if (item1) { + x86cpuidSetBits(&item1->cpuid, &item2->cpuid); + } else { +- if (virCPUx86DataAddCPUIDInt(data1, item2) < 0) ++ if (virCPUx86DataAddItem(data1, item2) < 0) + return -1; + } + } +@@ -641,7 +641,7 @@ x86DataAddSignature(virCPUx86Data *data, + { + virCPUx86DataItem leaf1 = CPUID(.eax_in = 0x1, .eax = signature); + +- return virCPUx86DataAddCPUIDInt(data, &leaf1); ++ return virCPUx86DataAddItem(data, &leaf1); + } + + +@@ -948,7 +948,7 @@ x86FeatureParse(xmlXPathContextPtr ctxt, + i, feature->name); + goto cleanup; + } +- if (virCPUx86DataAddCPUIDInt(&feature->data, &item)) ++ if (virCPUx86DataAddItem(&feature->data, &item)) + goto cleanup; + } + +@@ -1664,8 +1664,8 @@ x86Compute(virCPUDefPtr host, + goto error; + + if (cpu->vendor && host_model->vendor && +- virCPUx86DataAddCPUIDInt(&guest_model->data, +- &host_model->vendor->data) < 0) ++ virCPUx86DataAddItem(&guest_model->data, ++ &host_model->vendor->data) < 0) + goto error; + + if (host_model->signatures && +@@ -2650,7 +2650,7 @@ virCPUx86Baseline(virCPUDefPtr *cpus, + } + + if (vendor && +- virCPUx86DataAddCPUIDInt(&base_model->data, &vendor->data) < 0) ++ virCPUx86DataAddItem(&base_model->data, &vendor->data) < 0) + goto error; + + if (x86Decode(cpu, &base_model->data, models, modelName, migratable) < 0) +@@ -2949,7 +2949,7 @@ virCPUx86Translate(virCPUDefPtr cpu, + goto cleanup; + + if (model->vendor && +- virCPUx86DataAddCPUIDInt(&model->data, &model->vendor->data) < 0) ++ virCPUx86DataAddItem(&model->data, &model->vendor->data) < 0) + goto cleanup; + + if (model->signatures && +@@ -3080,7 +3080,7 @@ int + virCPUx86DataAddCPUID(virCPUDataPtr cpuData, + const virCPUx86DataItem *item) + { +- return virCPUx86DataAddCPUIDInt(&cpuData->data.x86, item); ++ return virCPUx86DataAddItem(&cpuData->data.x86, item); + } + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_x86-Rename-virCPUx86DataItem-variables.patch b/SOURCES/libvirt-cpu_x86-Rename-virCPUx86DataItem-variables.patch new file mode 100644 index 0000000..f2a826e --- /dev/null +++ b/SOURCES/libvirt-cpu_x86-Rename-virCPUx86DataItem-variables.patch @@ -0,0 +1,328 @@ +From 74ecc2a0c728cf59279c61e1e9837423c72182e9 Mon Sep 17 00:00:00 2001 +Message-Id: <74ecc2a0c728cf59279c61e1e9837423c72182e9@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:24 +0200 +Subject: [PATCH] cpu_x86: Rename virCPUx86DataItem variables +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 6c22b329d5bc592a390bd4d802c55a2a44af750e) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Signed-off-by: Jiri Denemark +Message-Id: <570635ac7fb5f7a6514072ee4b871eb4d08f65bc.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_x86.c | 128 +++++++++++++++++++++++----------------------- + 1 file changed, 64 insertions(+), 64 deletions(-) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index 6e1fb37d20..74f4083aac 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -327,13 +327,13 @@ x86DataCpuidNext(virCPUx86DataIteratorPtr iterator) + + static virCPUx86DataItemPtr + x86DataCpuid(const virCPUx86Data *data, +- const virCPUx86DataItem *cpuid) ++ const virCPUx86DataItem *item) + { + size_t i; + + for (i = 0; i < data->len; i++) { +- if (data->items[i].cpuid.eax_in == cpuid->cpuid.eax_in && +- data->items[i].cpuid.ecx_in == cpuid->cpuid.ecx_in) ++ if (data->items[i].cpuid.eax_in == item->cpuid.eax_in && ++ data->items[i].cpuid.ecx_in == item->cpuid.ecx_in) + return data->items + i; + } + +@@ -379,15 +379,15 @@ x86DataCopy(virCPUx86Data *dst, const virCPUx86Data *src) + + static int + virCPUx86DataAddCPUIDInt(virCPUx86Data *data, +- const virCPUx86DataItem *cpuid) ++ const virCPUx86DataItem *item) + { + virCPUx86DataItemPtr existing; + +- if ((existing = x86DataCpuid(data, cpuid))) { +- x86cpuidSetBits(&existing->cpuid, &cpuid->cpuid); ++ if ((existing = x86DataCpuid(data, item))) { ++ x86cpuidSetBits(&existing->cpuid, &item->cpuid); + } else { + if (VIR_APPEND_ELEMENT_COPY(data->items, data->len, +- *((virCPUx86DataItemPtr)cpuid)) < 0) ++ *((virCPUx86DataItemPtr)item)) < 0) + return -1; + + qsort(data->items, data->len, +@@ -403,16 +403,16 @@ x86DataAdd(virCPUx86Data *data1, + const virCPUx86Data *data2) + { + virCPUx86DataIterator iter = virCPUx86DataIteratorInit(data2); +- virCPUx86DataItemPtr cpuid1; +- virCPUx86DataItemPtr cpuid2; ++ virCPUx86DataItemPtr item1; ++ virCPUx86DataItemPtr item2; + +- while ((cpuid2 = x86DataCpuidNext(&iter))) { +- cpuid1 = x86DataCpuid(data1, cpuid2); ++ while ((item2 = x86DataCpuidNext(&iter))) { ++ item1 = x86DataCpuid(data1, item2); + +- if (cpuid1) { +- x86cpuidSetBits(&cpuid1->cpuid, &cpuid2->cpuid); ++ if (item1) { ++ x86cpuidSetBits(&item1->cpuid, &item2->cpuid); + } else { +- if (virCPUx86DataAddCPUIDInt(data1, cpuid2) < 0) ++ if (virCPUx86DataAddCPUIDInt(data1, item2) < 0) + return -1; + } + } +@@ -426,12 +426,12 @@ x86DataSubtract(virCPUx86Data *data1, + const virCPUx86Data *data2) + { + virCPUx86DataIterator iter = virCPUx86DataIteratorInit(data1); +- virCPUx86DataItemPtr cpuid1; +- virCPUx86DataItemPtr cpuid2; ++ virCPUx86DataItemPtr item1; ++ virCPUx86DataItemPtr item2; + +- while ((cpuid1 = x86DataCpuidNext(&iter))) { +- if ((cpuid2 = x86DataCpuid(data2, cpuid1))) +- x86cpuidClearBits(&cpuid1->cpuid, &cpuid2->cpuid); ++ while ((item1 = x86DataCpuidNext(&iter))) { ++ if ((item2 = x86DataCpuid(data2, item1))) ++ x86cpuidClearBits(&item1->cpuid, &item2->cpuid); + } + } + +@@ -441,15 +441,15 @@ x86DataIntersect(virCPUx86Data *data1, + const virCPUx86Data *data2) + { + virCPUx86DataIterator iter = virCPUx86DataIteratorInit(data1); +- virCPUx86DataItemPtr cpuid1; +- virCPUx86DataItemPtr cpuid2; ++ virCPUx86DataItemPtr item1; ++ virCPUx86DataItemPtr item2; + +- while ((cpuid1 = x86DataCpuidNext(&iter))) { +- cpuid2 = x86DataCpuid(data2, cpuid1); +- if (cpuid2) +- x86cpuidAndBits(&cpuid1->cpuid, &cpuid2->cpuid); ++ while ((item1 = x86DataCpuidNext(&iter))) { ++ item2 = x86DataCpuid(data2, item1); ++ if (item2) ++ x86cpuidAndBits(&item1->cpuid, &item2->cpuid); + else +- x86cpuidClearBits(&cpuid1->cpuid, &cpuid1->cpuid); ++ x86cpuidClearBits(&item1->cpuid, &item1->cpuid); + } + } + +@@ -469,12 +469,12 @@ x86DataIsSubset(const virCPUx86Data *data, + { + + virCPUx86DataIterator iter = virCPUx86DataIteratorInit((virCPUx86Data *)subset); +- const virCPUx86DataItem *cpuid; +- const virCPUx86DataItem *cpuidSubset; ++ const virCPUx86DataItem *item; ++ const virCPUx86DataItem *itemSubset; + +- while ((cpuidSubset = x86DataCpuidNext(&iter))) { +- if (!(cpuid = x86DataCpuid(data, cpuidSubset)) || +- !x86cpuidMatchMasked(&cpuid->cpuid, &cpuidSubset->cpuid)) ++ while ((itemSubset = x86DataCpuidNext(&iter))) { ++ if (!(item = x86DataCpuid(data, itemSubset)) || ++ !x86cpuidMatchMasked(&item->cpuid, &itemSubset->cpuid)) + return false; + } + +@@ -509,14 +509,14 @@ static virCPUx86VendorPtr + x86DataToVendor(const virCPUx86Data *data, + virCPUx86MapPtr map) + { +- virCPUx86DataItemPtr cpuid; ++ virCPUx86DataItemPtr item; + size_t i; + + for (i = 0; i < map->nvendors; i++) { + virCPUx86VendorPtr vendor = map->vendors[i]; +- if ((cpuid = x86DataCpuid(data, &vendor->data)) && +- x86cpuidMatchMasked(&cpuid->cpuid, &vendor->data.cpuid)) { +- x86cpuidClearBits(&cpuid->cpuid, &vendor->data.cpuid); ++ if ((item = x86DataCpuid(data, &vendor->data)) && ++ x86cpuidMatchMasked(&item->cpuid, &vendor->data.cpuid)) { ++ x86cpuidClearBits(&item->cpuid, &vendor->data.cpuid); + return vendor; + } + } +@@ -626,12 +626,12 @@ static uint32_t + x86DataToSignature(const virCPUx86Data *data) + { + virCPUx86DataItem leaf1 = CPUID(.eax_in = 0x1); +- virCPUx86DataItemPtr cpuid; ++ virCPUx86DataItemPtr item; + +- if (!(cpuid = x86DataCpuid(data, &leaf1))) ++ if (!(item = x86DataCpuid(data, &leaf1))) + return 0; + +- return cpuid->cpuid.eax & SIGNATURE_MASK; ++ return item->cpuid.eax & SIGNATURE_MASK; + } + + +@@ -639,9 +639,9 @@ static int + x86DataAddSignature(virCPUx86Data *data, + uint32_t signature) + { +- virCPUx86DataItem cpuid = CPUID(.eax_in = 0x1, .eax = signature); ++ virCPUx86DataItem leaf1 = CPUID(.eax_in = 0x1, .eax = signature); + +- return virCPUx86DataAddCPUIDInt(data, &cpuid); ++ return virCPUx86DataAddCPUIDInt(data, &leaf1); + } + + +@@ -905,7 +905,7 @@ x86FeatureParse(xmlXPathContextPtr ctxt, + virCPUx86MapPtr map = data; + xmlNodePtr *nodes = NULL; + virCPUx86FeaturePtr feature; +- virCPUx86DataItem cpuid; ++ virCPUx86DataItem item; + size_t i; + int n; + char *str = NULL; +@@ -942,13 +942,13 @@ x86FeatureParse(xmlXPathContextPtr ctxt, + + for (i = 0; i < n; i++) { + ctxt->node = nodes[i]; +- if (x86ParseCPUID(ctxt, &cpuid) < 0) { ++ if (x86ParseCPUID(ctxt, &item) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Invalid cpuid[%zu] in %s feature"), + i, feature->name); + goto cleanup; + } +- if (virCPUx86DataAddCPUIDInt(&feature->data, &cpuid)) ++ if (virCPUx86DataAddCPUIDInt(&feature->data, &item)) + goto cleanup; + } + +@@ -1148,16 +1148,16 @@ x86ModelCompare(virCPUx86ModelPtr model1, + virCPUx86CompareResult result = EQUAL; + virCPUx86DataIterator iter1 = virCPUx86DataIteratorInit(&model1->data); + virCPUx86DataIterator iter2 = virCPUx86DataIteratorInit(&model2->data); +- virCPUx86DataItemPtr cpuid1; +- virCPUx86DataItemPtr cpuid2; ++ virCPUx86DataItemPtr item1; ++ virCPUx86DataItemPtr item2; + +- while ((cpuid1 = x86DataCpuidNext(&iter1))) { ++ while ((item1 = x86DataCpuidNext(&iter1))) { + virCPUx86CompareResult match = SUPERSET; + +- if ((cpuid2 = x86DataCpuid(&model2->data, cpuid1))) { +- if (x86cpuidMatch(&cpuid1->cpuid, &cpuid2->cpuid)) ++ if ((item2 = x86DataCpuid(&model2->data, item1))) { ++ if (x86cpuidMatch(&item1->cpuid, &item2->cpuid)) + continue; +- else if (!x86cpuidMatchMasked(&cpuid1->cpuid, &cpuid2->cpuid)) ++ else if (!x86cpuidMatchMasked(&item1->cpuid, &item2->cpuid)) + match = SUBSET; + } + +@@ -1167,13 +1167,13 @@ x86ModelCompare(virCPUx86ModelPtr model1, + return UNRELATED; + } + +- while ((cpuid2 = x86DataCpuidNext(&iter2))) { ++ while ((item2 = x86DataCpuidNext(&iter2))) { + virCPUx86CompareResult match = SUBSET; + +- if ((cpuid1 = x86DataCpuid(&model1->data, cpuid2))) { +- if (x86cpuidMatch(&cpuid2->cpuid, &cpuid1->cpuid)) ++ if ((item1 = x86DataCpuid(&model1->data, item2))) { ++ if (x86cpuidMatch(&item2->cpuid, &item1->cpuid)) + continue; +- else if (!x86cpuidMatchMasked(&cpuid2->cpuid, &cpuid1->cpuid)) ++ else if (!x86cpuidMatchMasked(&item2->cpuid, &item1->cpuid)) + match = SUPERSET; + } + +@@ -1484,7 +1484,7 @@ virCPUx86DataParse(xmlXPathContextPtr ctxt) + { + xmlNodePtr *nodes = NULL; + virCPUDataPtr cpuData = NULL; +- virCPUx86DataItem cpuid; ++ virCPUx86DataItem item; + size_t i; + int n; + +@@ -1500,12 +1500,12 @@ virCPUx86DataParse(xmlXPathContextPtr ctxt) + + for (i = 0; i < n; i++) { + ctxt->node = nodes[i]; +- if (x86ParseCPUID(ctxt, &cpuid) < 0) { ++ if (x86ParseCPUID(ctxt, &item) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("failed to parse cpuid[%zu]"), i); + goto error; + } +- if (virCPUx86DataAddCPUID(cpuData, &cpuid) < 0) ++ if (virCPUx86DataAddCPUID(cpuData, &item) < 0) + goto error; + } + +@@ -2382,10 +2382,10 @@ cpuidSetLeaf12(virCPUDataPtr data, + { + virCPUx86DataItem item = CPUID(.eax_in = 0x7); + virCPUx86CPUIDPtr cpuid = &item.cpuid; +- virCPUx86DataItemPtr cpuid7; ++ virCPUx86DataItemPtr leaf7; + +- if (!(cpuid7 = x86DataCpuid(&data->data.x86, &item)) || +- !(cpuid7->cpuid.ebx & (1 << 2))) ++ if (!(leaf7 = x86DataCpuid(&data->data.x86, &item)) || ++ !(leaf7->cpuid.ebx & (1 << 2))) + return 0; + + if (virCPUx86DataAddCPUID(data, subLeaf0) < 0) +@@ -3078,9 +3078,9 @@ virCPUx86ValidateFeatures(virCPUDefPtr cpu) + + int + virCPUx86DataAddCPUID(virCPUDataPtr cpuData, +- const virCPUx86DataItem *cpuid) ++ const virCPUx86DataItem *item) + { +- return virCPUx86DataAddCPUIDInt(&cpuData->data.x86, cpuid); ++ return virCPUx86DataAddCPUIDInt(&cpuData->data.x86, item); + } + + +@@ -3112,12 +3112,12 @@ int + virCPUx86DataSetVendor(virCPUDataPtr cpuData, + const char *vendor) + { +- virCPUx86DataItem cpuid = CPUID(0); ++ virCPUx86DataItem item = CPUID(0); + +- if (virCPUx86VendorToCPUID(vendor, &cpuid) < 0) ++ if (virCPUx86VendorToCPUID(vendor, &item) < 0) + return -1; + +- return virCPUx86DataAddCPUID(cpuData, &cpuid); ++ return virCPUx86DataAddCPUID(cpuData, &item); + } + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_x86-Rename-virCPUx86Vendor.cpuid.patch b/SOURCES/libvirt-cpu_x86-Rename-virCPUx86Vendor.cpuid.patch new file mode 100644 index 0000000..70186dc --- /dev/null +++ b/SOURCES/libvirt-cpu_x86-Rename-virCPUx86Vendor.cpuid.patch @@ -0,0 +1,99 @@ +From 088d9da6e6c4f3edc0293f78ba7270941d2e7fd0 Mon Sep 17 00:00:00 2001 +Message-Id: <088d9da6e6c4f3edc0293f78ba7270941d2e7fd0@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:23 +0200 +Subject: [PATCH] cpu_x86: Rename virCPUx86Vendor.cpuid +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Although vendor string is always reported by CPUID, the container struct +is used for consistency and thus "cpuid" name is not a good fit anymore. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit c02d70d52efc4b7af09e68847ef72ad47a6bdcf1) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Signed-off-by: Jiri Denemark +Message-Id: <0b6fccb50f2ce2b5d926a75c90a8107a300c8d57.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_x86.c | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index 2e953eaa12..6e1fb37d20 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -49,7 +49,7 @@ typedef struct _virCPUx86Vendor virCPUx86Vendor; + typedef virCPUx86Vendor *virCPUx86VendorPtr; + struct _virCPUx86Vendor { + char *name; +- virCPUx86DataItem cpuid; ++ virCPUx86DataItem data; + }; + + typedef struct _virCPUx86Feature virCPUx86Feature; +@@ -514,9 +514,9 @@ x86DataToVendor(const virCPUx86Data *data, + + for (i = 0; i < map->nvendors; i++) { + virCPUx86VendorPtr vendor = map->vendors[i]; +- if ((cpuid = x86DataCpuid(data, &vendor->cpuid)) && +- x86cpuidMatchMasked(&cpuid->cpuid, &vendor->cpuid.cpuid)) { +- x86cpuidClearBits(&cpuid->cpuid, &vendor->cpuid.cpuid); ++ if ((cpuid = x86DataCpuid(data, &vendor->data)) && ++ x86cpuidMatchMasked(&cpuid->cpuid, &vendor->data.cpuid)) { ++ x86cpuidClearBits(&cpuid->cpuid, &vendor->data.cpuid); + return vendor; + } + } +@@ -759,7 +759,7 @@ x86VendorParse(xmlXPathContextPtr ctxt, + goto cleanup; + } + +- if (virCPUx86VendorToCPUID(string, &vendor->cpuid) < 0) ++ if (virCPUx86VendorToCPUID(string, &vendor->data) < 0) + goto cleanup; + + if (VIR_APPEND_ELEMENT(map->vendors, map->nvendors, vendor) < 0) +@@ -1665,7 +1665,7 @@ x86Compute(virCPUDefPtr host, + + if (cpu->vendor && host_model->vendor && + virCPUx86DataAddCPUIDInt(&guest_model->data, +- &host_model->vendor->cpuid) < 0) ++ &host_model->vendor->data) < 0) + goto error; + + if (host_model->signatures && +@@ -2153,7 +2153,7 @@ x86Encode(virArch arch, + if (!(data_vendor = virCPUDataNew(arch))) + goto error; + +- if (v && virCPUx86DataAddCPUID(data_vendor, &v->cpuid) < 0) ++ if (v && virCPUx86DataAddCPUID(data_vendor, &v->data) < 0) + goto error; + } + +@@ -2650,7 +2650,7 @@ virCPUx86Baseline(virCPUDefPtr *cpus, + } + + if (vendor && +- virCPUx86DataAddCPUIDInt(&base_model->data, &vendor->cpuid) < 0) ++ virCPUx86DataAddCPUIDInt(&base_model->data, &vendor->data) < 0) + goto error; + + if (x86Decode(cpu, &base_model->data, models, modelName, migratable) < 0) +@@ -2949,7 +2949,7 @@ virCPUx86Translate(virCPUDefPtr cpu, + goto cleanup; + + if (model->vendor && +- virCPUx86DataAddCPUIDInt(&model->data, &model->vendor->cpuid) < 0) ++ virCPUx86DataAddCPUIDInt(&model->data, &model->vendor->data) < 0) + goto cleanup; + + if (model->signatures && +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_x86-Rename-virCPUx86VendorToCPUID.patch b/SOURCES/libvirt-cpu_x86-Rename-virCPUx86VendorToCPUID.patch new file mode 100644 index 0000000..59fdc0c --- /dev/null +++ b/SOURCES/libvirt-cpu_x86-Rename-virCPUx86VendorToCPUID.patch @@ -0,0 +1,60 @@ +From c3573dbf60524401d06da6f6c5ce70a780494509 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:30 +0200 +Subject: [PATCH] cpu_x86: Rename virCPUx86VendorToCPUID +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Renamed as virCPUx86VendorToData. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 3eff71a2d5048b30ded73bc6e542cbbd3e5b6193) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Signed-off-by: Jiri Denemark +Message-Id: <01af4e7922b394abeb1ea11856c188cb80ffb9a8.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_x86.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index 6d48c9264c..9c0f39e76d 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -526,8 +526,8 @@ x86DataToVendor(const virCPUx86Data *data, + + + static int +-virCPUx86VendorToCPUID(const char *vendor, +- virCPUx86DataItemPtr data) ++virCPUx86VendorToData(const char *vendor, ++ virCPUx86DataItemPtr data) + { + virCPUx86CPUIDPtr cpuid = &data->cpuid; + +@@ -759,7 +759,7 @@ x86VendorParse(xmlXPathContextPtr ctxt, + goto cleanup; + } + +- if (virCPUx86VendorToCPUID(string, &vendor->data) < 0) ++ if (virCPUx86VendorToData(string, &vendor->data) < 0) + goto cleanup; + + if (VIR_APPEND_ELEMENT(map->vendors, map->nvendors, vendor) < 0) +@@ -3114,7 +3114,7 @@ virCPUx86DataSetVendor(virCPUDataPtr cpuData, + { + virCPUx86DataItem item = CPUID(0); + +- if (virCPUx86VendorToCPUID(vendor, &item) < 0) ++ if (virCPUx86VendorToData(vendor, &item) < 0) + return -1; + + return virCPUx86DataAdd(cpuData, &item); +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_x86-Rename-x86DataCpuid.patch b/SOURCES/libvirt-cpu_x86-Rename-x86DataCpuid.patch new file mode 100644 index 0000000..569167d --- /dev/null +++ b/SOURCES/libvirt-cpu_x86-Rename-x86DataCpuid.patch @@ -0,0 +1,141 @@ +From 99431463aaf37298bc90f82bc6b20b44f4853246 Mon Sep 17 00:00:00 2001 +Message-Id: <99431463aaf37298bc90f82bc6b20b44f4853246@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:26 +0200 +Subject: [PATCH] cpu_x86: Rename x86DataCpuid +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +It is now called virCPUx86DataGet. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 609f467f1377da3418dad23fdd9f7136e462ba5b) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Signed-off-by: Jiri Denemark +Message-Id: <427e52b2993356d0170e2f756526e9d523686a42.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_x86.c | 26 +++++++++++++------------- + 1 file changed, 13 insertions(+), 13 deletions(-) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index d9475e5b4a..52709f109e 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -326,8 +326,8 @@ virCPUx86DataNext(virCPUx86DataIteratorPtr iterator) + + + static virCPUx86DataItemPtr +-x86DataCpuid(const virCPUx86Data *data, +- const virCPUx86DataItem *item) ++virCPUx86DataGet(const virCPUx86Data *data, ++ const virCPUx86DataItem *item) + { + size_t i; + +@@ -383,7 +383,7 @@ virCPUx86DataAddCPUIDInt(virCPUx86Data *data, + { + virCPUx86DataItemPtr existing; + +- if ((existing = x86DataCpuid(data, item))) { ++ if ((existing = virCPUx86DataGet(data, item))) { + x86cpuidSetBits(&existing->cpuid, &item->cpuid); + } else { + if (VIR_APPEND_ELEMENT_COPY(data->items, data->len, +@@ -407,7 +407,7 @@ x86DataAdd(virCPUx86Data *data1, + virCPUx86DataItemPtr item2; + + while ((item2 = virCPUx86DataNext(&iter))) { +- item1 = x86DataCpuid(data1, item2); ++ item1 = virCPUx86DataGet(data1, item2); + + if (item1) { + x86cpuidSetBits(&item1->cpuid, &item2->cpuid); +@@ -430,7 +430,7 @@ x86DataSubtract(virCPUx86Data *data1, + virCPUx86DataItemPtr item2; + + while ((item1 = virCPUx86DataNext(&iter))) { +- if ((item2 = x86DataCpuid(data2, item1))) ++ if ((item2 = virCPUx86DataGet(data2, item1))) + x86cpuidClearBits(&item1->cpuid, &item2->cpuid); + } + } +@@ -445,7 +445,7 @@ x86DataIntersect(virCPUx86Data *data1, + virCPUx86DataItemPtr item2; + + while ((item1 = virCPUx86DataNext(&iter))) { +- item2 = x86DataCpuid(data2, item1); ++ item2 = virCPUx86DataGet(data2, item1); + if (item2) + x86cpuidAndBits(&item1->cpuid, &item2->cpuid); + else +@@ -473,7 +473,7 @@ x86DataIsSubset(const virCPUx86Data *data, + const virCPUx86DataItem *itemSubset; + + while ((itemSubset = virCPUx86DataNext(&iter))) { +- if (!(item = x86DataCpuid(data, itemSubset)) || ++ if (!(item = virCPUx86DataGet(data, itemSubset)) || + !x86cpuidMatchMasked(&item->cpuid, &itemSubset->cpuid)) + return false; + } +@@ -514,7 +514,7 @@ x86DataToVendor(const virCPUx86Data *data, + + for (i = 0; i < map->nvendors; i++) { + virCPUx86VendorPtr vendor = map->vendors[i]; +- if ((item = x86DataCpuid(data, &vendor->data)) && ++ if ((item = virCPUx86DataGet(data, &vendor->data)) && + x86cpuidMatchMasked(&item->cpuid, &vendor->data.cpuid)) { + x86cpuidClearBits(&item->cpuid, &vendor->data.cpuid); + return vendor; +@@ -609,7 +609,7 @@ x86DataToSignatureFull(const virCPUx86Data *data, + + *family = *model = *stepping = 0; + +- if (!(item = x86DataCpuid(data, &leaf1))) ++ if (!(item = virCPUx86DataGet(data, &leaf1))) + return; + + cpuid = &item->cpuid; +@@ -628,7 +628,7 @@ x86DataToSignature(const virCPUx86Data *data) + virCPUx86DataItem leaf1 = CPUID(.eax_in = 0x1); + virCPUx86DataItemPtr item; + +- if (!(item = x86DataCpuid(data, &leaf1))) ++ if (!(item = virCPUx86DataGet(data, &leaf1))) + return 0; + + return item->cpuid.eax & SIGNATURE_MASK; +@@ -1154,7 +1154,7 @@ x86ModelCompare(virCPUx86ModelPtr model1, + while ((item1 = virCPUx86DataNext(&iter1))) { + virCPUx86CompareResult match = SUPERSET; + +- if ((item2 = x86DataCpuid(&model2->data, item1))) { ++ if ((item2 = virCPUx86DataGet(&model2->data, item1))) { + if (x86cpuidMatch(&item1->cpuid, &item2->cpuid)) + continue; + else if (!x86cpuidMatchMasked(&item1->cpuid, &item2->cpuid)) +@@ -1170,7 +1170,7 @@ x86ModelCompare(virCPUx86ModelPtr model1, + while ((item2 = virCPUx86DataNext(&iter2))) { + virCPUx86CompareResult match = SUBSET; + +- if ((item1 = x86DataCpuid(&model1->data, item2))) { ++ if ((item1 = virCPUx86DataGet(&model1->data, item2))) { + if (x86cpuidMatch(&item2->cpuid, &item1->cpuid)) + continue; + else if (!x86cpuidMatchMasked(&item2->cpuid, &item1->cpuid)) +@@ -2384,7 +2384,7 @@ cpuidSetLeaf12(virCPUDataPtr data, + virCPUx86CPUIDPtr cpuid = &item.cpuid; + virCPUx86DataItemPtr leaf7; + +- if (!(leaf7 = x86DataCpuid(&data->data.x86, &item)) || ++ if (!(leaf7 = virCPUx86DataGet(&data->data.x86, &item)) || + !(leaf7->cpuid.ebx & (1 << 2))) + return 0; + +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_x86-Rename-x86DataCpuidNext-function.patch b/SOURCES/libvirt-cpu_x86-Rename-x86DataCpuidNext-function.patch new file mode 100644 index 0000000..6dc883c --- /dev/null +++ b/SOURCES/libvirt-cpu_x86-Rename-x86DataCpuidNext-function.patch @@ -0,0 +1,113 @@ +From ad4abf728510a5fed123d46a223f19f0b8178045 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:25 +0200 +Subject: [PATCH] cpu_x86: Rename x86DataCpuidNext function +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The function is now called virCPUx86DataNext to reflect its purpose: it +is an iterator over CPU data (both CPUID and MSR in the near future). + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 5655b83139e47b6c52d48a7d10640bf3508865eb) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Signed-off-by: Jiri Denemark +Message-Id: +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_x86.c | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index 74f4083aac..d9475e5b4a 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -307,7 +307,7 @@ virCPUx86CPUIDSorter(const void *a, const void *b) + + /* skips all zero CPUID leaves */ + static virCPUx86DataItemPtr +-x86DataCpuidNext(virCPUx86DataIteratorPtr iterator) ++virCPUx86DataNext(virCPUx86DataIteratorPtr iterator) + { + const virCPUx86Data *data = iterator->data; + +@@ -406,7 +406,7 @@ x86DataAdd(virCPUx86Data *data1, + virCPUx86DataItemPtr item1; + virCPUx86DataItemPtr item2; + +- while ((item2 = x86DataCpuidNext(&iter))) { ++ while ((item2 = virCPUx86DataNext(&iter))) { + item1 = x86DataCpuid(data1, item2); + + if (item1) { +@@ -429,7 +429,7 @@ x86DataSubtract(virCPUx86Data *data1, + virCPUx86DataItemPtr item1; + virCPUx86DataItemPtr item2; + +- while ((item1 = x86DataCpuidNext(&iter))) { ++ while ((item1 = virCPUx86DataNext(&iter))) { + if ((item2 = x86DataCpuid(data2, item1))) + x86cpuidClearBits(&item1->cpuid, &item2->cpuid); + } +@@ -444,7 +444,7 @@ x86DataIntersect(virCPUx86Data *data1, + virCPUx86DataItemPtr item1; + virCPUx86DataItemPtr item2; + +- while ((item1 = x86DataCpuidNext(&iter))) { ++ while ((item1 = virCPUx86DataNext(&iter))) { + item2 = x86DataCpuid(data2, item1); + if (item2) + x86cpuidAndBits(&item1->cpuid, &item2->cpuid); +@@ -459,7 +459,7 @@ x86DataIsEmpty(virCPUx86Data *data) + { + virCPUx86DataIterator iter = virCPUx86DataIteratorInit(data); + +- return !x86DataCpuidNext(&iter); ++ return !virCPUx86DataNext(&iter); + } + + +@@ -472,7 +472,7 @@ x86DataIsSubset(const virCPUx86Data *data, + const virCPUx86DataItem *item; + const virCPUx86DataItem *itemSubset; + +- while ((itemSubset = x86DataCpuidNext(&iter))) { ++ while ((itemSubset = virCPUx86DataNext(&iter))) { + if (!(item = x86DataCpuid(data, itemSubset)) || + !x86cpuidMatchMasked(&item->cpuid, &itemSubset->cpuid)) + return false; +@@ -1151,7 +1151,7 @@ x86ModelCompare(virCPUx86ModelPtr model1, + virCPUx86DataItemPtr item1; + virCPUx86DataItemPtr item2; + +- while ((item1 = x86DataCpuidNext(&iter1))) { ++ while ((item1 = virCPUx86DataNext(&iter1))) { + virCPUx86CompareResult match = SUPERSET; + + if ((item2 = x86DataCpuid(&model2->data, item1))) { +@@ -1167,7 +1167,7 @@ x86ModelCompare(virCPUx86ModelPtr model1, + return UNRELATED; + } + +- while ((item2 = x86DataCpuidNext(&iter2))) { ++ while ((item2 = virCPUx86DataNext(&iter2))) { + virCPUx86CompareResult match = SUBSET; + + if ((item1 = x86DataCpuid(&model1->data, item2))) { +@@ -1461,7 +1461,7 @@ virCPUx86DataFormat(const virCPUData *data) + virBuffer buf = VIR_BUFFER_INITIALIZER; + + virBufferAddLit(&buf, "\n"); +- while ((item = x86DataCpuidNext(&iter))) { ++ while ((item = virCPUx86DataNext(&iter))) { + virCPUx86CPUIDPtr cpuid = &item->cpuid; + virBufferAsprintf(&buf, + " +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:19 +0200 +Subject: [PATCH] cpu_x86: Require within in CPU map +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +A feature with no cpuid element is invalid and it should not be silently +treated as a feature with all CPUID bits set to zero. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit dbc04114f3d14b53c999bd89db51276358b1aba3) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Signed-off-by: Jiri Denemark +Message-Id: +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_x86.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index 66aa5a612c..98e8d608d6 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -923,6 +923,13 @@ x86FeatureParse(xmlXPathContextPtr ctxt, + if (n < 0) + goto cleanup; + ++ if (n == 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Missing cpuid for feature %s"), ++ feature->name); ++ goto cleanup; ++ } ++ + for (i = 0; i < n; i++) { + ctxt->node = nodes[i]; + if (x86ParseCPUID(ctxt, &cpuid) < 0) { +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_x86-Separate-ancestor-model-parsing-from-x86ModelParse.patch b/SOURCES/libvirt-cpu_x86-Separate-ancestor-model-parsing-from-x86ModelParse.patch new file mode 100644 index 0000000..0571af1 --- /dev/null +++ b/SOURCES/libvirt-cpu_x86-Separate-ancestor-model-parsing-from-x86ModelParse.patch @@ -0,0 +1,110 @@ +From 4111804c77930ebcda4fa5fae751074f75da4f1c Mon Sep 17 00:00:00 2001 +Message-Id: <4111804c77930ebcda4fa5fae751074f75da4f1c@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:24:54 +0200 +Subject: [PATCH] cpu_x86: Separate ancestor model parsing from x86ModelParse +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The code is separated into a new x86ModelParseAncestor function. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 2e1e2b910c6a9d31f2fb6d388ed72dc8f561b845) + +https://bugzilla.redhat.com/show_bug.cgi?id=1686895 + +Signed-off-by: Jiri Denemark +Message-Id: <0e941dce0077eb7d7a31dffa60f7d647d66b95e6.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_x86.c | 65 +++++++++++++++++++++++++++-------------------- + 1 file changed, 38 insertions(+), 27 deletions(-) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index ce48ca6867..64788d60b3 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -1148,6 +1148,42 @@ x86ModelCompare(virCPUx86ModelPtr model1, + } + + ++static int ++x86ModelParseAncestor(virCPUx86ModelPtr model, ++ xmlXPathContextPtr ctxt, ++ virCPUx86MapPtr map) ++{ ++ VIR_AUTOFREE(char *) name = NULL; ++ virCPUx86ModelPtr ancestor; ++ int rc; ++ ++ if ((rc = virXPathBoolean("boolean(./model)", ctxt)) <= 0) ++ return rc; ++ ++ name = virXPathString("string(./model/@name)", ctxt); ++ if (!name) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Missing ancestor's name in CPU model %s"), ++ model->name); ++ return -1; ++ } ++ ++ if (!(ancestor = x86ModelFind(map, name))) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Ancestor model %s not found for CPU model %s"), ++ name, model->name); ++ return -1; ++ } ++ ++ model->vendor = ancestor->vendor; ++ model->signature = ancestor->signature; ++ if (x86DataCopy(&model->data, &ancestor->data) < 0) ++ return -1; ++ ++ return 0; ++} ++ ++ + static int + x86ModelParse(xmlXPathContextPtr ctxt, + const char *name, +@@ -1167,33 +1203,8 @@ x86ModelParse(xmlXPathContextPtr ctxt, + if (VIR_STRDUP(model->name, name) < 0) + goto cleanup; + +- if (virXPathNode("./model", ctxt)) { +- virCPUx86ModelPtr ancestor; +- char *anname; +- +- anname = virXPathString("string(./model/@name)", ctxt); +- if (!anname) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Missing ancestor's name in CPU model %s"), +- model->name); +- goto cleanup; +- } +- +- if (!(ancestor = x86ModelFind(map, anname))) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Ancestor model %s not found for CPU model %s"), +- anname, model->name); +- VIR_FREE(anname); +- goto cleanup; +- } +- +- VIR_FREE(anname); +- +- model->vendor = ancestor->vendor; +- model->signature = ancestor->signature; +- if (x86DataCopy(&model->data, &ancestor->data) < 0) +- goto cleanup; +- } ++ if (x86ModelParseAncestor(model, ctxt, map) < 0) ++ goto cleanup; + + if (virXPathBoolean("boolean(./signature)", ctxt)) { + unsigned int sigFamily = 0; +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_x86-Separate-feature-list-parsing-from-x86ModelParse.patch b/SOURCES/libvirt-cpu_x86-Separate-feature-list-parsing-from-x86ModelParse.patch new file mode 100644 index 0000000..9c70ab3 --- /dev/null +++ b/SOURCES/libvirt-cpu_x86-Separate-feature-list-parsing-from-x86ModelParse.patch @@ -0,0 +1,129 @@ +From 8d2f5155be8834db501930716e2cd2e1be14785c Mon Sep 17 00:00:00 2001 +Message-Id: <8d2f5155be8834db501930716e2cd2e1be14785c@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:24:57 +0200 +Subject: [PATCH] cpu_x86: Separate feature list parsing from x86ModelParse +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The code is separated into a new x86ModelParseFeatures function. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 8d249df9c917040d180202343e5cf7f70c3e4fe1) + +https://bugzilla.redhat.com/show_bug.cgi?id=1686895 + +Signed-off-by: Jiri Denemark +Message-Id: <5a741350b39394a93aee99a3b98142548936bc2d.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_x86.c | 68 +++++++++++++++++++++++++++-------------------- + 1 file changed, 39 insertions(+), 29 deletions(-) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index 62894cae9b..91362198ab 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -1247,16 +1247,51 @@ x86ModelParseVendor(virCPUx86ModelPtr model, + } + + ++static int ++x86ModelParseFeatures(virCPUx86ModelPtr model, ++ xmlXPathContextPtr ctxt, ++ virCPUx86MapPtr map) ++{ ++ VIR_AUTOFREE(xmlNodePtr *) nodes = NULL; ++ size_t i; ++ int n; ++ ++ if ((n = virXPathNodeSet("./feature", ctxt, &nodes)) <= 0) ++ return n; ++ ++ for (i = 0; i < n; i++) { ++ VIR_AUTOFREE(char *) ftname = NULL; ++ virCPUx86FeaturePtr feature; ++ ++ if (!(ftname = virXMLPropString(nodes[i], "name"))) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Missing feature name for CPU model %s"), ++ model->name); ++ return -1; ++ } ++ ++ if (!(feature = x86FeatureFind(map, ftname))) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Feature %s required by CPU model %s not found"), ++ ftname, model->name); ++ return -1; ++ } ++ ++ if (x86DataAdd(&model->data, &feature->data)) ++ return -1; ++ } ++ ++ return 0; ++} ++ ++ + static int + x86ModelParse(xmlXPathContextPtr ctxt, + const char *name, + void *data) + { + virCPUx86MapPtr map = data; +- xmlNodePtr *nodes = NULL; + virCPUx86ModelPtr model; +- size_t i; +- int n; + int ret = -1; + + if (!(model = x86ModelNew())) +@@ -1274,33 +1309,9 @@ x86ModelParse(xmlXPathContextPtr ctxt, + if (x86ModelParseVendor(model, ctxt, map) < 0) + goto cleanup; + +- n = virXPathNodeSet("./feature", ctxt, &nodes); +- if (n < 0) ++ if (x86ModelParseFeatures(model, ctxt, map) < 0) + goto cleanup; + +- for (i = 0; i < n; i++) { +- virCPUx86FeaturePtr feature; +- char *ftname; +- +- if (!(ftname = virXMLPropString(nodes[i], "name"))) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Missing feature name for CPU model %s"), model->name); +- goto cleanup; +- } +- +- if (!(feature = x86FeatureFind(map, ftname))) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Feature %s required by CPU model %s not found"), +- ftname, model->name); +- VIR_FREE(ftname); +- goto cleanup; +- } +- VIR_FREE(ftname); +- +- if (x86DataAdd(&model->data, &feature->data)) +- goto cleanup; +- } +- + if (VIR_APPEND_ELEMENT(map->models, map->nmodels, model) < 0) + goto cleanup; + +@@ -1308,7 +1319,6 @@ x86ModelParse(xmlXPathContextPtr ctxt, + + cleanup: + x86ModelFree(model); +- VIR_FREE(nodes); + return ret; + } + +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_x86-Separate-signature-parsing-from-x86ModelParse.patch b/SOURCES/libvirt-cpu_x86-Separate-signature-parsing-from-x86ModelParse.patch new file mode 100644 index 0000000..e149723 --- /dev/null +++ b/SOURCES/libvirt-cpu_x86-Separate-signature-parsing-from-x86ModelParse.patch @@ -0,0 +1,103 @@ +From e7b8b38fe1fe7e7d8eb9fab6cb3ded16652f60f8 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:24:55 +0200 +Subject: [PATCH] cpu_x86: Separate signature parsing from x86ModelParse +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The code is separated into a new x86ModelParseSignature function. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit fe78d2fda9f2dd67eb9daa98e48fbffa468d271e) + +https://bugzilla.redhat.com/show_bug.cgi?id=1686895 + +Signed-off-by: Jiri Denemark +Message-Id: <616b60991bfdaa735804b839e258f6f1fa409a7b.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_x86.c | 58 ++++++++++++++++++++++++++++------------------- + 1 file changed, 35 insertions(+), 23 deletions(-) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index 64788d60b3..119ece4758 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -1184,6 +1184,39 @@ x86ModelParseAncestor(virCPUx86ModelPtr model, + } + + ++static int ++x86ModelParseSignature(virCPUx86ModelPtr model, ++ xmlXPathContextPtr ctxt) ++{ ++ ++ if (virXPathBoolean("boolean(./signature)", ctxt)) { ++ unsigned int sigFamily = 0; ++ unsigned int sigModel = 0; ++ int rc; ++ ++ rc = virXPathUInt("string(./signature/@family)", ctxt, &sigFamily); ++ if (rc < 0 || sigFamily == 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Invalid CPU signature family in model %s"), ++ model->name); ++ return -1; ++ } ++ ++ rc = virXPathUInt("string(./signature/@model)", ctxt, &sigModel); ++ if (rc < 0 || sigModel == 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Invalid CPU signature model in model %s"), ++ model->name); ++ return -1; ++ } ++ ++ model->signature = x86MakeSignature(sigFamily, sigModel, 0); ++ } ++ ++ return 0; ++} ++ ++ + static int + x86ModelParse(xmlXPathContextPtr ctxt, + const char *name, +@@ -1206,29 +1239,8 @@ x86ModelParse(xmlXPathContextPtr ctxt, + if (x86ModelParseAncestor(model, ctxt, map) < 0) + goto cleanup; + +- if (virXPathBoolean("boolean(./signature)", ctxt)) { +- unsigned int sigFamily = 0; +- unsigned int sigModel = 0; +- int rc; +- +- rc = virXPathUInt("string(./signature/@family)", ctxt, &sigFamily); +- if (rc < 0 || sigFamily == 0) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Invalid CPU signature family in model %s"), +- model->name); +- goto cleanup; +- } +- +- rc = virXPathUInt("string(./signature/@model)", ctxt, &sigModel); +- if (rc < 0 || sigModel == 0) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Invalid CPU signature model in model %s"), +- model->name); +- goto cleanup; +- } +- +- model->signature = x86MakeSignature(sigFamily, sigModel, 0); +- } ++ if (x86ModelParseSignature(model, ctxt) < 0) ++ goto cleanup; + + if (virXPathBoolean("boolean(./vendor)", ctxt)) { + vendor = virXPathString("string(./vendor/@name)", ctxt); +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_x86-Separate-vendor-parsing-from-x86ModelParse.patch b/SOURCES/libvirt-cpu_x86-Separate-vendor-parsing-from-x86ModelParse.patch new file mode 100644 index 0000000..5e06bc9 --- /dev/null +++ b/SOURCES/libvirt-cpu_x86-Separate-vendor-parsing-from-x86ModelParse.patch @@ -0,0 +1,109 @@ +From e1b42297bc41c8f356693f2756e806a8c7275f4f Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:24:56 +0200 +Subject: [PATCH] cpu_x86: Separate vendor parsing from x86ModelParse +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The code is separated into a new x86ModelParseVendor function. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 232266839c994dcf2958f1efdfe74cfb7973a749) + +https://bugzilla.redhat.com/show_bug.cgi?id=1686895 + +Signed-off-by: Jiri Denemark +Message-Id: +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_x86.c | 50 ++++++++++++++++++++++++++++++----------------- + 1 file changed, 32 insertions(+), 18 deletions(-) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index 119ece4758..62894cae9b 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -1217,6 +1217,36 @@ x86ModelParseSignature(virCPUx86ModelPtr model, + } + + ++static int ++x86ModelParseVendor(virCPUx86ModelPtr model, ++ xmlXPathContextPtr ctxt, ++ virCPUx86MapPtr map) ++{ ++ VIR_AUTOFREE(char *) vendor = NULL; ++ int rc; ++ ++ if ((rc = virXPathBoolean("boolean(./vendor)", ctxt)) <= 0) ++ return rc; ++ ++ vendor = virXPathString("string(./vendor/@name)", ctxt); ++ if (!vendor) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Invalid vendor element in CPU model %s"), ++ model->name); ++ return -1; ++ } ++ ++ if (!(model->vendor = x86VendorFind(map, vendor))) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Unknown vendor %s referenced by CPU model %s"), ++ vendor, model->name); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++ + static int + x86ModelParse(xmlXPathContextPtr ctxt, + const char *name, +@@ -1225,7 +1255,6 @@ x86ModelParse(xmlXPathContextPtr ctxt, + virCPUx86MapPtr map = data; + xmlNodePtr *nodes = NULL; + virCPUx86ModelPtr model; +- char *vendor = NULL; + size_t i; + int n; + int ret = -1; +@@ -1242,22 +1271,8 @@ x86ModelParse(xmlXPathContextPtr ctxt, + if (x86ModelParseSignature(model, ctxt) < 0) + goto cleanup; + +- if (virXPathBoolean("boolean(./vendor)", ctxt)) { +- vendor = virXPathString("string(./vendor/@name)", ctxt); +- if (!vendor) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Invalid vendor element in CPU model %s"), +- model->name); +- goto cleanup; +- } +- +- if (!(model->vendor = x86VendorFind(map, vendor))) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Unknown vendor %s referenced by CPU model %s"), +- vendor, model->name); +- goto cleanup; +- } +- } ++ if (x86ModelParseVendor(model, ctxt, map) < 0) ++ goto cleanup; + + n = virXPathNodeSet("./feature", ctxt, &nodes); + if (n < 0) +@@ -1293,7 +1308,6 @@ x86ModelParse(xmlXPathContextPtr ctxt, + + cleanup: + x86ModelFree(model); +- VIR_FREE(vendor); + VIR_FREE(nodes); + return ret; + } +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_x86-Simplify-x86DataAdd.patch b/SOURCES/libvirt-cpu_x86-Simplify-x86DataAdd.patch new file mode 100644 index 0000000..dea6e6d --- /dev/null +++ b/SOURCES/libvirt-cpu_x86-Simplify-x86DataAdd.patch @@ -0,0 +1,54 @@ +From ed7c9cb6444ec9344ebb253eac417703c5371c2d Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:31 +0200 +Subject: [PATCH] cpu_x86: Simplify x86DataAdd +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The while loop just copied half of virCPUx86DataAddItem. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 0fdc0ad84c7ea27480f6f4edb82389d414584ada) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Signed-off-by: Jiri Denemark +Message-Id: <8ffc18c0ee7c61e5e1ce1af023ee7e6c62726f5a.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_x86.c | 15 ++++----------- + 1 file changed, 4 insertions(+), 11 deletions(-) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index 9c0f39e76d..0582be63e2 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -403,18 +403,11 @@ x86DataAdd(virCPUx86Data *data1, + const virCPUx86Data *data2) + { + virCPUx86DataIterator iter = virCPUx86DataIteratorInit(data2); +- virCPUx86DataItemPtr item1; +- virCPUx86DataItemPtr item2; ++ virCPUx86DataItemPtr item; + +- while ((item2 = virCPUx86DataNext(&iter))) { +- item1 = virCPUx86DataGet(data1, item2); +- +- if (item1) { +- x86cpuidSetBits(&item1->cpuid, &item2->cpuid); +- } else { +- if (virCPUx86DataAddItem(data1, item2) < 0) +- return -1; +- } ++ while ((item = virCPUx86DataNext(&iter))) { ++ if (virCPUx86DataAddItem(data1, item) < 0) ++ return -1; + } + + return 0; +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_x86-Store-CPU-signature-in-an-array.patch b/SOURCES/libvirt-cpu_x86-Store-CPU-signature-in-an-array.patch new file mode 100644 index 0000000..4b951ef --- /dev/null +++ b/SOURCES/libvirt-cpu_x86-Store-CPU-signature-in-an-array.patch @@ -0,0 +1,161 @@ +From c7a8133cbe9d0612db2889038079d260c3a8334f Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:00 +0200 +Subject: [PATCH] cpu_x86: Store CPU signature in an array +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In preparation for storing several CPU signatures in a single CPU model, +we need to turn virCPUx86Model's signature into an array of signatures. + +The parser still hardcodes the number of signatures to 1, but the +following patch will drop this limit. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit b07b8b7750c6a505d4b00bd272e79ea0305cb610) + +https://bugzilla.redhat.com/show_bug.cgi?id=1686895 + +Signed-off-by: Jiri Denemark +Message-Id: <1d24aad1c6b9aa8142a2e882511f52a41fbaff67.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_x86.c | 50 ++++++++++++++++++++++++++++++++++++++--------- + 1 file changed, 41 insertions(+), 9 deletions(-) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index e25bc691ae..f8b8d8a96b 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -145,7 +145,8 @@ typedef virCPUx86Model *virCPUx86ModelPtr; + struct _virCPUx86Model { + char *name; + virCPUx86VendorPtr vendor; +- uint32_t signature; ++ size_t nsignatures; ++ uint32_t *signatures; + virCPUx86Data data; + }; + +@@ -972,6 +973,7 @@ x86ModelFree(virCPUx86ModelPtr model) + return; + + VIR_FREE(model->name); ++ VIR_FREE(model->signatures); + virCPUx86DataClear(&model->data); + VIR_FREE(model); + } +@@ -981,7 +983,14 @@ static int + x86ModelCopySignatures(virCPUx86ModelPtr dst, + virCPUx86ModelPtr src) + { +- dst->signature = src->signature; ++ size_t i; ++ ++ if (VIR_ALLOC_N(dst->signatures, src->nsignatures) < 0) ++ return -1; ++ ++ dst->nsignatures = src->nsignatures; ++ for (i = 0; i < src->nsignatures; i++) ++ dst->signatures[i] = src->signatures[i]; + + return 0; + } +@@ -1198,12 +1207,18 @@ static int + x86ModelParseSignature(virCPUx86ModelPtr model, + xmlXPathContextPtr ctxt) + { ++ /* Remove inherited signatures. */ ++ VIR_FREE(model->signatures); + + if (virXPathBoolean("boolean(./signature)", ctxt)) { + unsigned int sigFamily = 0; + unsigned int sigModel = 0; + int rc; + ++ model->nsignatures = 1; ++ if (VIR_ALLOC_N(model->signatures, 1) < 0) ++ return -1; ++ + rc = virXPathUInt("string(./signature/@family)", ctxt, &sigFamily); + if (rc < 0 || sigFamily == 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, +@@ -1220,7 +1235,7 @@ x86ModelParseSignature(virCPUx86ModelPtr model, + return -1; + } + +- model->signature = x86MakeSignature(sigFamily, sigModel, 0); ++ model->signatures[0] = x86MakeSignature(sigFamily, sigModel, 0); + } + + return 0; +@@ -1621,7 +1636,8 @@ x86Compute(virCPUDefPtr host, + &host_model->vendor->cpuid) < 0) + goto error; + +- if (x86DataAddSignature(&guest_model->data, host_model->signature) < 0) ++ if (host_model->signatures && ++ x86DataAddSignature(&guest_model->data, *host_model->signatures) < 0) + goto error; + + if (cpu->type == VIR_CPU_TYPE_GUEST +@@ -1727,6 +1743,21 @@ virCPUx86Compare(virCPUDefPtr host, + } + + ++static bool ++x86ModelHasSignature(virCPUx86ModelPtr model, ++ uint32_t signature) ++{ ++ size_t i; ++ ++ for (i = 0; i < model->nsignatures; i++) { ++ if (model->signatures[i] == signature) ++ return true; ++ } ++ ++ return false; ++} ++ ++ + /* + * Checks whether a candidate model is a better fit for the CPU data than the + * current model. +@@ -1768,8 +1799,8 @@ x86DecodeUseCandidate(virCPUx86ModelPtr current, + * consider candidates with matching family/model. + */ + if (signature && +- current->signature == signature && +- candidate->signature != signature) { ++ x86ModelHasSignature(current, signature) && ++ !x86ModelHasSignature(candidate, signature)) { + VIR_DEBUG("%s differs in signature from matching %s", + cpuCandidate->model, cpuCurrent->model); + return 0; +@@ -1785,8 +1816,8 @@ x86DecodeUseCandidate(virCPUx86ModelPtr current, + * result in longer list of features. + */ + if (signature && +- candidate->signature == signature && +- current->signature != signature) { ++ x86ModelHasSignature(candidate, signature) && ++ !x86ModelHasSignature(current, signature)) { + VIR_DEBUG("%s provides matching signature", cpuCandidate->model); + return 1; + } +@@ -2854,7 +2885,8 @@ virCPUx86Translate(virCPUDefPtr cpu, + virCPUx86DataAddCPUIDInt(&model->data, &model->vendor->cpuid) < 0) + goto cleanup; + +- if (x86DataAddSignature(&model->data, model->signature) < 0) ++ if (model->signatures && ++ x86DataAddSignature(&model->data, model->signatures[0]) < 0) + goto cleanup; + + if (!(translated = virCPUDefCopyWithoutModel(cpu))) +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_x86-Store-virCPUx86DataItem-content-in-union.patch b/SOURCES/libvirt-cpu_x86-Store-virCPUx86DataItem-content-in-union.patch new file mode 100644 index 0000000..e6a0f2f --- /dev/null +++ b/SOURCES/libvirt-cpu_x86-Store-virCPUx86DataItem-content-in-union.patch @@ -0,0 +1,487 @@ +From c465e315637d0b2cf01d2957de3d816186e0fd0f Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:38 +0200 +Subject: [PATCH] cpu_x86: Store virCPUx86DataItem content in union +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The structure can only be used for CPUID data now. Adding a type +indicator and moving the data into a union will let us store alternative +data types. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 370177e2f6784319b2fc86d8fe7a271248a5982e) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Signed-off-by: Jiri Denemark +Message-Id: <00cf7daca0cde66e9a90f64435182ef430983b2e.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_x86.c | 202 ++++++++++++++++++++++++--------- + src/cpu/cpu_x86_data.h | 10 +- + src/libxl/libxl_capabilities.c | 3 +- + src/qemu/qemu_monitor_json.c | 3 +- + 4 files changed, 160 insertions(+), 58 deletions(-) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index 11c023ac31..e6da974b31 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -59,7 +59,9 @@ struct _virCPUx86Feature { + }; + + +-#define CPUID(...) { .cpuid = {__VA_ARGS__} } ++#define CPUID(...) \ ++ { .type = VIR_CPU_X86_DATA_CPUID, \ ++ .data = { .cpuid = {__VA_ARGS__} } } + + #define KVM_FEATURE_DEF(Name, Eax_in, Eax) \ + static virCPUx86DataItem Name ## _data[] = { \ +@@ -193,10 +195,22 @@ static bool + virCPUx86DataItemMatch(const virCPUx86DataItem *item1, + const virCPUx86DataItem *item2) + { +- return (item1->cpuid.eax == item2->cpuid.eax && +- item1->cpuid.ebx == item2->cpuid.ebx && +- item1->cpuid.ecx == item2->cpuid.ecx && +- item1->cpuid.edx == item2->cpuid.edx); ++ const virCPUx86CPUID *cpuid1; ++ const virCPUx86CPUID *cpuid2; ++ ++ switch (item1->type) { ++ case VIR_CPU_X86_DATA_CPUID: ++ cpuid1 = &item1->data.cpuid; ++ cpuid2 = &item2->data.cpuid; ++ return (cpuid1->eax == cpuid2->eax && ++ cpuid1->ebx == cpuid2->ebx && ++ cpuid1->ecx == cpuid2->ecx && ++ cpuid1->edx == cpuid2->edx); ++ ++ case VIR_CPU_X86_DATA_NONE: ++ default: ++ return false; ++ } + } + + +@@ -204,10 +218,22 @@ static bool + virCPUx86DataItemMatchMasked(const virCPUx86DataItem *item, + const virCPUx86DataItem *mask) + { +- return ((item->cpuid.eax & mask->cpuid.eax) == mask->cpuid.eax && +- (item->cpuid.ebx & mask->cpuid.ebx) == mask->cpuid.ebx && +- (item->cpuid.ecx & mask->cpuid.ecx) == mask->cpuid.ecx && +- (item->cpuid.edx & mask->cpuid.edx) == mask->cpuid.edx); ++ const virCPUx86CPUID *cpuid; ++ const virCPUx86CPUID *cpuidMask; ++ ++ switch (item->type) { ++ case VIR_CPU_X86_DATA_CPUID: ++ cpuid = &item->data.cpuid; ++ cpuidMask = &mask->data.cpuid; ++ return ((cpuid->eax & cpuidMask->eax) == cpuidMask->eax && ++ (cpuid->ebx & cpuidMask->ebx) == cpuidMask->ebx && ++ (cpuid->ecx & cpuidMask->ecx) == cpuidMask->ecx && ++ (cpuid->edx & cpuidMask->edx) == cpuidMask->edx); ++ ++ case VIR_CPU_X86_DATA_NONE: ++ default: ++ return false; ++ } + } + + +@@ -215,13 +241,26 @@ static void + virCPUx86DataItemSetBits(virCPUx86DataItemPtr item, + const virCPUx86DataItem *mask) + { ++ virCPUx86CPUIDPtr cpuid; ++ const virCPUx86CPUID *cpuidMask; ++ + if (!mask) + return; + +- item->cpuid.eax |= mask->cpuid.eax; +- item->cpuid.ebx |= mask->cpuid.ebx; +- item->cpuid.ecx |= mask->cpuid.ecx; +- item->cpuid.edx |= mask->cpuid.edx; ++ switch (item->type) { ++ case VIR_CPU_X86_DATA_CPUID: ++ cpuid = &item->data.cpuid; ++ cpuidMask = &mask->data.cpuid; ++ cpuid->eax |= cpuidMask->eax; ++ cpuid->ebx |= cpuidMask->ebx; ++ cpuid->ecx |= cpuidMask->ecx; ++ cpuid->edx |= cpuidMask->edx; ++ break; ++ ++ case VIR_CPU_X86_DATA_NONE: ++ default: ++ break; ++ } + } + + +@@ -229,13 +268,26 @@ static void + virCPUx86DataItemClearBits(virCPUx86DataItemPtr item, + const virCPUx86DataItem *mask) + { ++ virCPUx86CPUIDPtr cpuid; ++ const virCPUx86CPUID *cpuidMask; ++ + if (!mask) + return; + +- item->cpuid.eax &= ~mask->cpuid.eax; +- item->cpuid.ebx &= ~mask->cpuid.ebx; +- item->cpuid.ecx &= ~mask->cpuid.ecx; +- item->cpuid.edx &= ~mask->cpuid.edx; ++ switch (item->type) { ++ case VIR_CPU_X86_DATA_CPUID: ++ cpuid = &item->data.cpuid; ++ cpuidMask = &mask->data.cpuid; ++ cpuid->eax &= ~cpuidMask->eax; ++ cpuid->ebx &= ~cpuidMask->ebx; ++ cpuid->ecx &= ~cpuidMask->ecx; ++ cpuid->edx &= ~cpuidMask->edx; ++ break; ++ ++ case VIR_CPU_X86_DATA_NONE: ++ default: ++ break; ++ } + } + + +@@ -243,13 +295,26 @@ static void + virCPUx86DataItemAndBits(virCPUx86DataItemPtr item, + const virCPUx86DataItem *mask) + { ++ virCPUx86CPUIDPtr cpuid; ++ const virCPUx86CPUID *cpuidMask; ++ + if (!mask) + return; + +- item->cpuid.eax &= mask->cpuid.eax; +- item->cpuid.ebx &= mask->cpuid.ebx; +- item->cpuid.ecx &= mask->cpuid.ecx; +- item->cpuid.edx &= mask->cpuid.edx; ++ switch (item->type) { ++ case VIR_CPU_X86_DATA_CPUID: ++ cpuid = &item->data.cpuid; ++ cpuidMask = &mask->data.cpuid; ++ cpuid->eax &= cpuidMask->eax; ++ cpuid->ebx &= cpuidMask->ebx; ++ cpuid->ecx &= cpuidMask->ecx; ++ cpuid->edx &= cpuidMask->edx; ++ break; ++ ++ case VIR_CPU_X86_DATA_NONE: ++ default: ++ break; ++ } + } + + +@@ -289,15 +354,29 @@ virCPUx86DataSorter(const void *a, const void *b) + virCPUx86DataItemPtr da = (virCPUx86DataItemPtr) a; + virCPUx86DataItemPtr db = (virCPUx86DataItemPtr) b; + +- if (da->cpuid.eax_in > db->cpuid.eax_in) ++ if (da->type > db->type) + return 1; +- else if (da->cpuid.eax_in < db->cpuid.eax_in) ++ else if (da->type < db->type) + return -1; + +- if (da->cpuid.ecx_in > db->cpuid.ecx_in) +- return 1; +- else if (da->cpuid.ecx_in < db->cpuid.ecx_in) +- return -1; ++ switch (da->type) { ++ case VIR_CPU_X86_DATA_CPUID: ++ if (da->data.cpuid.eax_in > db->data.cpuid.eax_in) ++ return 1; ++ else if (da->data.cpuid.eax_in < db->data.cpuid.eax_in) ++ return -1; ++ ++ if (da->data.cpuid.ecx_in > db->data.cpuid.ecx_in) ++ return 1; ++ else if (da->data.cpuid.ecx_in < db->data.cpuid.ecx_in) ++ return -1; ++ ++ break; ++ ++ case VIR_CPU_X86_DATA_NONE: ++ default: ++ break; ++ } + + return 0; + } +@@ -526,9 +605,9 @@ x86DataToVendor(const virCPUx86Data *data, + + static int + virCPUx86VendorToData(const char *vendor, +- virCPUx86DataItemPtr data) ++ virCPUx86DataItemPtr item) + { +- virCPUx86CPUIDPtr cpuid = &data->cpuid; ++ virCPUx86CPUIDPtr cpuid; + + if (strlen(vendor) != VENDOR_STRING_LENGTH) { + virReportError(VIR_ERR_INTERNAL_ERROR, +@@ -536,6 +615,8 @@ virCPUx86VendorToData(const char *vendor, + return -1; + } + ++ item->type = VIR_CPU_X86_DATA_CPUID; ++ cpuid = &item->data.cpuid; + cpuid->eax_in = 0; + cpuid->ecx_in = 0; + cpuid->ebx = virReadBufInt32LE(vendor); +@@ -611,7 +692,7 @@ x86DataToSignatureFull(const virCPUx86Data *data, + if (!(item = virCPUx86DataGet(data, &leaf1))) + return; + +- cpuid = &item->cpuid; ++ cpuid = &item->data.cpuid; + *family = ((cpuid->eax >> 20) & 0xff) + ((cpuid->eax >> 8) & 0xf); + *model = ((cpuid->eax >> 12) & 0xf0) + ((cpuid->eax >> 4) & 0xf); + *stepping = cpuid->eax & 0xf; +@@ -630,7 +711,7 @@ x86DataToSignature(const virCPUx86Data *data) + if (!(item = virCPUx86DataGet(data, &leaf1))) + return 0; + +- return item->cpuid.eax & SIGNATURE_MASK; ++ return item->data.cpuid.eax & SIGNATURE_MASK; + } + + +@@ -885,7 +966,8 @@ x86ParseCPUID(xmlXPathContextPtr ctxt, + ret_eax == -2 || ret_ebx == -2 || ret_ecx == -2 || ret_edx == -2) + return -1; + +- cpuid = &item->cpuid; ++ item->type = VIR_CPU_X86_DATA_CPUID; ++ cpuid = &item->data.cpuid; + cpuid->eax_in = eax_in; + cpuid->ecx_in = ecx_in; + cpuid->eax = eax; +@@ -1461,13 +1543,23 @@ virCPUx86DataFormat(const virCPUData *data) + + virBufferAddLit(&buf, "\n"); + while ((item = virCPUx86DataNext(&iter))) { +- virCPUx86CPUIDPtr cpuid = &item->cpuid; +- virBufferAsprintf(&buf, +- " \n", +- cpuid->eax_in, cpuid->ecx_in, +- cpuid->eax, cpuid->ebx, cpuid->ecx, cpuid->edx); ++ virCPUx86CPUIDPtr cpuid; ++ ++ switch (item->type) { ++ case VIR_CPU_X86_DATA_CPUID: ++ cpuid = &item->data.cpuid; ++ virBufferAsprintf(&buf, ++ " \n", ++ cpuid->eax_in, cpuid->ecx_in, ++ cpuid->eax, cpuid->ebx, cpuid->ecx, cpuid->edx); ++ break; ++ ++ case VIR_CPU_X86_DATA_NONE: ++ default: ++ break; ++ } + } + virBufferAddLit(&buf, "\n"); + +@@ -2226,7 +2318,7 @@ cpuidSetLeaf4(virCPUDataPtr data, + virCPUx86DataItemPtr subLeaf0) + { + virCPUx86DataItem item = *subLeaf0; +- virCPUx86CPUIDPtr cpuid = &item.cpuid; ++ virCPUx86CPUIDPtr cpuid = &item.data.cpuid; + + if (virCPUx86DataAdd(data, subLeaf0) < 0) + return -1; +@@ -2250,13 +2342,13 @@ cpuidSetLeaf7(virCPUDataPtr data, + virCPUx86DataItemPtr subLeaf0) + { + virCPUx86DataItem item = CPUID(.eax_in = 0x7); +- virCPUx86CPUIDPtr cpuid = &item.cpuid; ++ virCPUx86CPUIDPtr cpuid = &item.data.cpuid; + uint32_t sub; + + if (virCPUx86DataAdd(data, subLeaf0) < 0) + return -1; + +- for (sub = 1; sub <= subLeaf0->cpuid.eax; sub++) { ++ for (sub = 1; sub <= subLeaf0->data.cpuid.eax; sub++) { + cpuid->ecx_in = sub; + cpuidCall(cpuid); + if (virCPUx86DataAdd(data, &item) < 0) +@@ -2278,7 +2370,7 @@ cpuidSetLeafB(virCPUDataPtr data, + virCPUx86DataItemPtr subLeaf0) + { + virCPUx86DataItem item = *subLeaf0; +- virCPUx86CPUIDPtr cpuid = &item.cpuid; ++ virCPUx86CPUIDPtr cpuid = &item.data.cpuid; + + while (cpuid->ecx & 0xff00) { + if (virCPUx86DataAdd(data, &item) < 0) +@@ -2303,7 +2395,7 @@ cpuidSetLeafD(virCPUDataPtr data, + virCPUx86DataItemPtr subLeaf0) + { + virCPUx86DataItem item = CPUID(.eax_in = 0xd); +- virCPUx86CPUIDPtr cpuid = &item.cpuid; ++ virCPUx86CPUIDPtr cpuid = &item.data.cpuid; + virCPUx86CPUID sub0; + virCPUx86CPUID sub1; + uint32_t sub; +@@ -2316,7 +2408,7 @@ cpuidSetLeafD(virCPUDataPtr data, + if (virCPUx86DataAdd(data, &item) < 0) + return -1; + +- sub0 = subLeaf0->cpuid; ++ sub0 = subLeaf0->data.cpuid; + sub1 = *cpuid; + for (sub = 2; sub < 64; sub++) { + if (sub < 32 && +@@ -2351,8 +2443,8 @@ cpuidSetLeafResID(virCPUDataPtr data, + virCPUx86DataItemPtr subLeaf0, + uint32_t res) + { +- virCPUx86DataItem item = CPUID(.eax_in = subLeaf0->cpuid.eax_in); +- virCPUx86CPUIDPtr cpuid = &item.cpuid; ++ virCPUx86DataItem item = CPUID(.eax_in = subLeaf0->data.cpuid.eax_in); ++ virCPUx86CPUIDPtr cpuid = &item.data.cpuid; + uint32_t sub; + + if (virCPUx86DataAdd(data, subLeaf0) < 0) +@@ -2380,11 +2472,11 @@ cpuidSetLeaf12(virCPUDataPtr data, + virCPUx86DataItemPtr subLeaf0) + { + virCPUx86DataItem item = CPUID(.eax_in = 0x7); +- virCPUx86CPUIDPtr cpuid = &item.cpuid; ++ virCPUx86CPUIDPtr cpuid = &item.data.cpuid; + virCPUx86DataItemPtr leaf7; + + if (!(leaf7 = virCPUx86DataGet(&data->data.x86, &item)) || +- !(leaf7->cpuid.ebx & (1 << 2))) ++ !(leaf7->data.cpuid.ebx & (1 << 2))) + return 0; + + if (virCPUx86DataAdd(data, subLeaf0) < 0) +@@ -2417,13 +2509,13 @@ cpuidSetLeaf14(virCPUDataPtr data, + virCPUx86DataItemPtr subLeaf0) + { + virCPUx86DataItem item = CPUID(.eax_in = 0x14); +- virCPUx86CPUIDPtr cpuid = &item.cpuid; ++ virCPUx86CPUIDPtr cpuid = &item.data.cpuid; + uint32_t sub; + + if (virCPUx86DataAdd(data, subLeaf0) < 0) + return -1; + +- for (sub = 1; sub <= subLeaf0->cpuid.eax; sub++) { ++ for (sub = 1; sub <= subLeaf0->data.cpuid.eax; sub++) { + cpuid->ecx_in = sub; + cpuidCall(cpuid); + if (virCPUx86DataAdd(data, &item) < 0) +@@ -2443,16 +2535,16 @@ cpuidSetLeaf17(virCPUDataPtr data, + virCPUx86DataItemPtr subLeaf0) + { + virCPUx86DataItem item = CPUID(.eax_in = 0x17); +- virCPUx86CPUIDPtr cpuid = &item.cpuid; ++ virCPUx86CPUIDPtr cpuid = &item.data.cpuid; + uint32_t sub; + +- if (subLeaf0->cpuid.eax < 3) ++ if (subLeaf0->data.cpuid.eax < 3) + return 0; + + if (virCPUx86DataAdd(data, subLeaf0) < 0) + return -1; + +- for (sub = 1; sub <= subLeaf0->cpuid.eax; sub++) { ++ for (sub = 1; sub <= subLeaf0->data.cpuid.eax; sub++) { + cpuid->ecx_in = sub; + cpuidCall(cpuid); + if (virCPUx86DataAdd(data, &item) < 0) +@@ -2469,7 +2561,7 @@ cpuidSet(uint32_t base, virCPUDataPtr data) + uint32_t max; + uint32_t leaf; + virCPUx86DataItem item = CPUID(.eax_in = base); +- virCPUx86CPUIDPtr cpuid = &item.cpuid; ++ virCPUx86CPUIDPtr cpuid = &item.data.cpuid; + + cpuidCall(cpuid); + max = cpuid->eax; +diff --git a/src/cpu/cpu_x86_data.h b/src/cpu/cpu_x86_data.h +index e93b355cf0..da8e91fe71 100644 +--- a/src/cpu/cpu_x86_data.h ++++ b/src/cpu/cpu_x86_data.h +@@ -71,10 +71,18 @@ struct _virCPUx86CPUID { + + # define VIR_CPU_X86_DATA_INIT { 0 } + ++typedef enum { ++ VIR_CPU_X86_DATA_NONE = 0, ++ VIR_CPU_X86_DATA_CPUID, ++} virCPUx86DataType; ++ + typedef struct _virCPUx86DataItem virCPUx86DataItem; + typedef virCPUx86DataItem *virCPUx86DataItemPtr; + struct _virCPUx86DataItem { +- virCPUx86CPUID cpuid; ++ virCPUx86DataType type; ++ union { ++ virCPUx86CPUID cpuid; ++ } data; + }; + + typedef struct _virCPUx86Data virCPUx86Data; +diff --git a/src/libxl/libxl_capabilities.c b/src/libxl/libxl_capabilities.c +index 2b351fbdde..6630aa2c0b 100644 +--- a/src/libxl/libxl_capabilities.c ++++ b/src/libxl/libxl_capabilities.c +@@ -70,8 +70,9 @@ libxlCapsAddCPUID(virCPUDataPtr data, virCPUx86CPUID *cpuid, ssize_t ncaps) + virCPUx86DataItem item = { 0 }; + size_t i; + ++ item.type = VIR_CPU_X86_DATA_CPUID; + for (i = 0; i < ncaps; i++) { +- item.cpuid = cpuid[i]; ++ item.data.cpuid = cpuid[i]; + + if (virCPUx86DataAdd(data, &item) < 0) { + VIR_DEBUG("Failed to add CPUID(%x,%x)", +diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c +index abfaa6e68a..e6ac82e96b 100644 +--- a/src/qemu/qemu_monitor_json.c ++++ b/src/qemu/qemu_monitor_json.c +@@ -7049,9 +7049,10 @@ qemuMonitorJSONParseCPUx86Features(virJSONValuePtr data) + if (!(cpudata = virCPUDataNew(VIR_ARCH_X86_64))) + goto error; + ++ item.type = VIR_CPU_X86_DATA_CPUID; + for (i = 0; i < virJSONValueArraySize(data); i++) { + if (qemuMonitorJSONParseCPUx86FeatureWord(virJSONValueArrayGet(data, i), +- &item.cpuid) < 0 || ++ &item.data.cpuid) < 0 || + virCPUx86DataAdd(cpudata, &item) < 0) + goto error; + } +-- +2.22.0 + diff --git a/SOURCES/libvirt-cpu_x86-Turn-virCPUx86DataIteratorInit-into-a-function.patch b/SOURCES/libvirt-cpu_x86-Turn-virCPUx86DataIteratorInit-into-a-function.patch new file mode 100644 index 0000000..95ba70d --- /dev/null +++ b/SOURCES/libvirt-cpu_x86-Turn-virCPUx86DataIteratorInit-into-a-function.patch @@ -0,0 +1,147 @@ +From 14c5258d4227930fdadcd0bc9de3cae547b56b70 Mon Sep 17 00:00:00 2001 +Message-Id: <14c5258d4227930fdadcd0bc9de3cae547b56b70@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:26:07 +0200 +Subject: [PATCH] cpu_x86: Turn virCPUx86DataIteratorInit into a function +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Until now, this was a macro usable for direct initialization when a +variable is defined. Turning the macro into a function makes it more +general. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit b8e086a570b14b1f83fc07e25df6da758abe7706) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Conflicts: + src/cpu/cpu_x86.c + - commit c9ed87a6103fd4f09e0714f3a2b94c4c975477cd was not + backported + +Signed-off-by: Jiri Denemark +Message-Id: +Reviewed-by: Ján Tomko +--- + src/cpu/cpu_x86.c | 35 ++++++++++++++++++++++++----------- + 1 file changed, 24 insertions(+), 11 deletions(-) + +diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c +index ead962ae06..75527fd28f 100644 +--- a/src/cpu/cpu_x86.c ++++ b/src/cpu/cpu_x86.c +@@ -187,8 +187,13 @@ struct _virCPUx86DataIterator { + }; + + +-#define virCPUx86DataIteratorInit(data) \ +- { data, -1 } ++static void ++virCPUx86DataIteratorInit(virCPUx86DataIteratorPtr iterator, ++ const virCPUx86Data *data) ++{ ++ virCPUx86DataIterator iter = { data, -1 }; ++ *iterator = iter; ++} + + + static bool +@@ -538,9 +543,10 @@ static int + x86DataAdd(virCPUx86Data *data1, + const virCPUx86Data *data2) + { +- virCPUx86DataIterator iter = virCPUx86DataIteratorInit(data2); ++ virCPUx86DataIterator iter; + virCPUx86DataItemPtr item; + ++ virCPUx86DataIteratorInit(&iter, data2); + while ((item = virCPUx86DataNext(&iter))) { + if (virCPUx86DataAddItem(data1, item) < 0) + return -1; +@@ -554,10 +560,11 @@ static void + x86DataSubtract(virCPUx86Data *data1, + const virCPUx86Data *data2) + { +- virCPUx86DataIterator iter = virCPUx86DataIteratorInit(data1); ++ virCPUx86DataIterator iter; + virCPUx86DataItemPtr item1; + virCPUx86DataItemPtr item2; + ++ virCPUx86DataIteratorInit(&iter, data1); + while ((item1 = virCPUx86DataNext(&iter))) { + item2 = virCPUx86DataGet(data2, item1); + virCPUx86DataItemClearBits(item1, item2); +@@ -569,10 +576,11 @@ static void + x86DataIntersect(virCPUx86Data *data1, + const virCPUx86Data *data2) + { +- virCPUx86DataIterator iter = virCPUx86DataIteratorInit(data1); ++ virCPUx86DataIterator iter; + virCPUx86DataItemPtr item1; + virCPUx86DataItemPtr item2; + ++ virCPUx86DataIteratorInit(&iter, data1); + while ((item1 = virCPUx86DataNext(&iter))) { + item2 = virCPUx86DataGet(data2, item1); + if (item2) +@@ -586,8 +594,9 @@ x86DataIntersect(virCPUx86Data *data1, + static bool + x86DataIsEmpty(virCPUx86Data *data) + { +- virCPUx86DataIterator iter = virCPUx86DataIteratorInit(data); ++ virCPUx86DataIterator iter; + ++ virCPUx86DataIteratorInit(&iter, data); + return !virCPUx86DataNext(&iter); + } + +@@ -596,11 +605,11 @@ static bool + x86DataIsSubset(const virCPUx86Data *data, + const virCPUx86Data *subset) + { +- +- virCPUx86DataIterator iter = virCPUx86DataIteratorInit((virCPUx86Data *)subset); ++ virCPUx86DataIterator iter; + const virCPUx86DataItem *item; + const virCPUx86DataItem *itemSubset; + ++ virCPUx86DataIteratorInit(&iter, subset); + while ((itemSubset = virCPUx86DataNext(&iter))) { + if (!(item = virCPUx86DataGet(data, itemSubset)) || + !virCPUx86DataItemMatchMasked(item, itemSubset)) +@@ -1313,11 +1322,13 @@ x86ModelCompare(virCPUx86ModelPtr model1, + virCPUx86ModelPtr model2) + { + virCPUx86CompareResult result = EQUAL; +- virCPUx86DataIterator iter1 = virCPUx86DataIteratorInit(&model1->data); +- virCPUx86DataIterator iter2 = virCPUx86DataIteratorInit(&model2->data); ++ virCPUx86DataIterator iter1; ++ virCPUx86DataIterator iter2; + virCPUx86DataItemPtr item1; + virCPUx86DataItemPtr item2; + ++ virCPUx86DataIteratorInit(&iter1, &model1->data); ++ virCPUx86DataIteratorInit(&iter2, &model2->data); + while ((item1 = virCPUx86DataNext(&iter1))) { + virCPUx86CompareResult match = SUPERSET; + +@@ -1623,10 +1634,12 @@ virCPUx86GetMap(void) + static char * + virCPUx86DataFormat(const virCPUData *data) + { +- virCPUx86DataIterator iter = virCPUx86DataIteratorInit(&data->data.x86); ++ virCPUx86DataIterator iter; + virCPUx86DataItemPtr item; + virBuffer buf = VIR_BUFFER_INITIALIZER; + ++ virCPUx86DataIteratorInit(&iter, &data->data.x86); ++ + virBufferAddLit(&buf, "\n"); + while ((item = virCPUx86DataNext(&iter))) { + virCPUx86CPUIDPtr cpuid; +-- +2.22.0 + diff --git a/SOURCES/libvirt-cputest-Add-data-for-Intel-R-Core-TM-i7-7600U.patch b/SOURCES/libvirt-cputest-Add-data-for-Intel-R-Core-TM-i7-7600U.patch new file mode 100644 index 0000000..fdfd363 --- /dev/null +++ b/SOURCES/libvirt-cputest-Add-data-for-Intel-R-Core-TM-i7-7600U.patch @@ -0,0 +1,979 @@ +From 7ea297f4cff68e0f5f44f91e1ba1283fce05de6f Mon Sep 17 00:00:00 2001 +Message-Id: <7ea297f4cff68e0f5f44f91e1ba1283fce05de6f@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:24:50 +0200 +Subject: [PATCH] cputest: Add data for Intel(R) Core(TM) i7-7600U +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit cd11ea73d01b256437e25bc635c51d08518c8c77) + +https://bugzilla.redhat.com/show_bug.cgi?id=1686895 + +Signed-off-by: Jiri Denemark +Message-Id: <6a76550993bbc3e13f59daeea8e03ab0a0891997.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + tests/cputest.c | 1 + + .../x86_64-cpuid-Core-i7-7600U-disabled.xml | 6 + + .../x86_64-cpuid-Core-i7-7600U-enabled.xml | 8 + + .../x86_64-cpuid-Core-i7-7600U-guest.xml | 28 + + .../x86_64-cpuid-Core-i7-7600U-host.xml | 29 + + .../x86_64-cpuid-Core-i7-7600U-json.xml | 13 + + .../x86_64-cpuid-Core-i7-7600U.json | 755 ++++++++++++++++++ + .../x86_64-cpuid-Core-i7-7600U.xml | 47 ++ + 8 files changed, 887 insertions(+) + create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-7600U-disabled.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-7600U-enabled.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-7600U-guest.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-7600U-host.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-7600U-json.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-7600U.json + create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-7600U.xml + +diff --git a/tests/cputest.c b/tests/cputest.c +index f43144edc9..28d575a784 100644 +--- a/tests/cputest.c ++++ b/tests/cputest.c +@@ -1176,6 +1176,7 @@ mymain(void) + DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i7-5600U", JSON_HOST); + DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i7-5600U-arat", JSON_HOST); + DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i7-5600U-ibrs", JSON_HOST); ++ DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i7-7600U", JSON_MODELS); + DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i7-7700", JSON_MODELS); + DO_TEST_CPUID(VIR_ARCH_X86_64, "Core2-E6850", JSON_HOST); + DO_TEST_CPUID(VIR_ARCH_X86_64, "Core2-Q9500", JSON_NONE); +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-7600U-disabled.xml b/tests/cputestdata/x86_64-cpuid-Core-i7-7600U-disabled.xml +new file mode 100644 +index 0000000000..0a567bbfae +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-7600U-disabled.xml +@@ -0,0 +1,6 @@ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-7600U-enabled.xml b/tests/cputestdata/x86_64-cpuid-Core-i7-7600U-enabled.xml +new file mode 100644 +index 0000000000..b1cdaa802a +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-7600U-enabled.xml +@@ -0,0 +1,8 @@ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-7600U-guest.xml b/tests/cputestdata/x86_64-cpuid-Core-i7-7600U-guest.xml +new file mode 100644 +index 0000000000..70a0fc3286 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-7600U-guest.xml +@@ -0,0 +1,28 @@ ++ ++ Skylake-Client-IBRS ++ Intel ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-7600U-host.xml b/tests/cputestdata/x86_64-cpuid-Core-i7-7600U-host.xml +new file mode 100644 +index 0000000000..bbdfb6aa61 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-7600U-host.xml +@@ -0,0 +1,29 @@ ++ ++ x86_64 ++ Skylake-Client-IBRS ++ Intel ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-7600U-json.xml b/tests/cputestdata/x86_64-cpuid-Core-i7-7600U-json.xml +new file mode 100644 +index 0000000000..48089c6003 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-7600U-json.xml +@@ -0,0 +1,13 @@ ++ ++ Skylake-Client-IBRS ++ Intel ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-7600U.json b/tests/cputestdata/x86_64-cpuid-Core-i7-7600U.json +new file mode 100644 +index 0000000000..9a258e6be3 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-7600U.json +@@ -0,0 +1,755 @@ ++{ ++ "return": { ++ "model": { ++ "name": "base", ++ "props": { ++ "phys-bits": 0, ++ "core-id": -1, ++ "xlevel": 2147483656, ++ "cmov": true, ++ "ia64": false, ++ "ssb-no": false, ++ "aes": true, ++ "mmx": true, ++ "rdpid": false, ++ "arat": true, ++ "gfni": false, ++ "ibrs-all": false, ++ "pause-filter": false, ++ "xsavec": true, ++ "intel-pt": false, ++ "hv-frequencies": false, ++ "tsc-frequency": 0, ++ "xd": true, ++ "hv-vendor-id": "", ++ "kvm-asyncpf": true, ++ "kvm_asyncpf": true, ++ "perfctr_core": false, ++ "perfctr-core": false, ++ "mpx": true, ++ "pbe": false, ++ "decodeassists": false, ++ "avx512cd": false, ++ "sse4_1": true, ++ "sse4.1": true, ++ "sse4-1": true, ++ "family": 6, ++ "legacy-cache": true, ++ "vmware-cpuid-freq": true, ++ "wbnoinvd": false, ++ "avx512f": false, ++ "msr": true, ++ "mce": true, ++ "mca": true, ++ "hv-runtime": false, ++ "xcrypt": false, ++ "thread-id": -1, ++ "min-level": 13, ++ "xgetbv1": true, ++ "cid": false, ++ "hv-relaxed": false, ++ "hv-crash": false, ++ "ds": false, ++ "fxsr": true, ++ "xsaveopt": true, ++ "xtpr": false, ++ "hv-evmcs": false, ++ "avx512vl": false, ++ "avx512-vpopcntdq": false, ++ "phe": false, ++ "extapic": false, ++ "3dnowprefetch": true, ++ "avx512vbmi2": false, ++ "cr8legacy": false, ++ "cpuid-0xb": true, ++ "xcrypt-en": false, ++ "kvm_pv_eoi": true, ++ "apic-id": 4294967295, ++ "rsba": false, ++ "pn": false, ++ "dca": false, ++ "vendor": "GenuineIntel", ++ "hv-ipi": false, ++ "pku": false, ++ "smx": false, ++ "cmp_legacy": false, ++ "cmp-legacy": false, ++ "node-id": -1, ++ "avx512-4fmaps": false, ++ "vmcb_clean": false, ++ "vmcb-clean": false, ++ "3dnowext": false, ++ "amd-no-ssb": false, ++ "hle": true, ++ "npt": false, ++ "rdctl-no": false, ++ "memory": "/machine/unattached/system[0]", ++ "clwb": false, ++ "lbrv": false, ++ "adx": true, ++ "ss": true, ++ "pni": true, ++ "svm_lock": false, ++ "svm-lock": false, ++ "pfthreshold": false, ++ "smep": true, ++ "smap": true, ++ "x2apic": true, ++ "avx512vbmi": false, ++ "avx512vnni": false, ++ "hv-stimer": false, ++ "x-hv-synic-kvm-only": false, ++ "i64": true, ++ "flushbyasid": false, ++ "f16c": true, ++ "ace2-en": false, ++ "pat": true, ++ "pae": true, ++ "sse": true, ++ "phe-en": false, ++ "kvm_nopiodelay": true, ++ "kvm-nopiodelay": true, ++ "tm": false, ++ "kvmclock-stable-bit": true, ++ "hypervisor": true, ++ "socket-id": -1, ++ "pcommit": false, ++ "syscall": true, ++ "level": 13, ++ "avx512dq": false, ++ "x-migrate-smi-count": true, ++ "svm": false, ++ "full-cpuid-auto-level": true, ++ "hv-reset": false, ++ "invtsc": false, ++ "sse3": true, ++ "sse2": true, ++ "ssbd": true, ++ "est": false, ++ "avx512ifma": false, ++ "tm2": false, ++ "kvm-pv-ipi": true, ++ "kvm-pv-eoi": true, ++ "cx8": true, ++ "cldemote": false, ++ "hv-reenlightenment": false, ++ "kvm_mmu": false, ++ "kvm-mmu": false, ++ "sse4_2": true, ++ "sse4.2": true, ++ "sse4-2": true, ++ "pge": true, ++ "fill-mtrr-mask": true, ++ "avx512bitalg": false, ++ "nodeid_msr": false, ++ "pdcm": false, ++ "movbe": true, ++ "model": 142, ++ "nrip_save": false, ++ "nrip-save": false, ++ "kvm_pv_unhalt": true, ++ "ssse3": true, ++ "sse4a": false, ++ "invpcid": true, ++ "pdpe1gb": true, ++ "tsc-deadline": true, ++ "skip-l1dfl-vmentry": true, ++ "fma": true, ++ "cx16": true, ++ "de": true, ++ "pconfig": false, ++ "enforce": false, ++ "stepping": 9, ++ "xsave": true, ++ "clflush": true, ++ "skinit": false, ++ "tsc": true, ++ "tce": false, ++ "fpu": true, ++ "ibs": false, ++ "ds_cpl": false, ++ "ds-cpl": false, ++ "host-phys-bits": false, ++ "fma4": false, ++ "la57": false, ++ "osvw": false, ++ "check": true, ++ "hv-spinlocks": -1, ++ "pmu": false, ++ "pmm": false, ++ "apic": true, ++ "spec-ctrl": true, ++ "min-xlevel2": 0, ++ "tsc-adjust": true, ++ "tsc_adjust": true, ++ "kvm-steal-time": true, ++ "kvm_steal_time": true, ++ "kvmclock": true, ++ "l3-cache": true, ++ "lwp": false, ++ "amd-ssbd": false, ++ "ibpb": false, ++ "xop": false, ++ "avx": true, ++ "ace2": false, ++ "avx512bw": false, ++ "acpi": false, ++ "hv-vapic": false, ++ "fsgsbase": true, ++ "ht": false, ++ "nx": true, ++ "pclmulqdq": true, ++ "mmxext": false, ++ "vaes": false, ++ "popcnt": true, ++ "xsaves": true, ++ "tcg-cpuid": true, ++ "lm": true, ++ "umip": true, ++ "pse": true, ++ "avx2": true, ++ "sep": true, ++ "pclmuldq": true, ++ "virt-ssbd": false, ++ "x-hv-max-vps": -1, ++ "nodeid-msr": false, ++ "kvm": true, ++ "misalignsse": false, ++ "min-xlevel": 2147483656, ++ "kvm-pv-unhalt": true, ++ "bmi2": true, ++ "bmi1": true, ++ "realized": false, ++ "tsc_scale": false, ++ "tsc-scale": false, ++ "topoext": false, ++ "hv-vpindex": false, ++ "xlevel2": 0, ++ "clflushopt": true, ++ "kvm-no-smi-migration": false, ++ "monitor": false, ++ "avx512er": false, ++ "pmm-en": false, ++ "pcid": true, ++ "arch-capabilities": false, ++ "3dnow": false, ++ "erms": true, ++ "lahf-lm": true, ++ "lahf_lm": true, ++ "vpclmulqdq": false, ++ "fxsr-opt": false, ++ "hv-synic": false, ++ "xstore": false, ++ "fxsr_opt": false, ++ "kvm-hint-dedicated": false, ++ "rtm": true, ++ "lmce": true, ++ "hv-time": false, ++ "perfctr-nb": false, ++ "perfctr_nb": false, ++ "ffxsr": false, ++ "hv-tlbflush": false, ++ "rdrand": true, ++ "rdseed": true, ++ "avx512-4vnniw": false, ++ "vmx": true, ++ "vme": true, ++ "dtes64": false, ++ "mtrr": true, ++ "rdtscp": true, ++ "pse36": true, ++ "kvm-pv-tlb-flush": true, ++ "tbm": false, ++ "wdt": false, ++ "pause_filter": false, ++ "sha-ni": false, ++ "model-id": "Intel(R) Core(TM) i7-7600U CPU @ 2.80GHz", ++ "abm": true, ++ "avx512pf": false, ++ "xstore-en": false ++ } ++ } ++ }, ++ "id": "model-expansion" ++} ++ ++ ++{ ++ "return": [ ++ { ++ "name": "max", ++ "typename": "max-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": false ++ }, ++ { ++ "name": "host", ++ "typename": "host-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": false ++ }, ++ { ++ "name": "base", ++ "typename": "base-x86_64-cpu", ++ "unavailable-features": [], ++ "static": true, ++ "migration-safe": true ++ }, ++ { ++ "name": "qemu64", ++ "typename": "qemu64-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "qemu32", ++ "typename": "qemu32-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "phenom", ++ "typename": "phenom-x86_64-cpu", ++ "unavailable-features": [ ++ "mmxext", ++ "fxsr-opt", ++ "3dnowext", ++ "3dnow", ++ "sse4a", ++ "npt" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "pentium3", ++ "typename": "pentium3-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "pentium2", ++ "typename": "pentium2-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "pentium", ++ "typename": "pentium-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "n270", ++ "typename": "n270-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "kvm64", ++ "typename": "kvm64-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "kvm32", ++ "typename": "kvm32-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "coreduo", ++ "typename": "coreduo-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "core2duo", ++ "typename": "core2duo-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "athlon", ++ "typename": "athlon-x86_64-cpu", ++ "unavailable-features": [ ++ "mmxext", ++ "3dnowext", ++ "3dnow" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Westmere-IBRS", ++ "typename": "Westmere-IBRS-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Westmere", ++ "typename": "Westmere-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Server-IBRS", ++ "typename": "Skylake-Server-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "avx512f", ++ "avx512dq", ++ "clwb", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "pku", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Server", ++ "typename": "Skylake-Server-x86_64-cpu", ++ "unavailable-features": [ ++ "avx512f", ++ "avx512dq", ++ "clwb", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "pku", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Client-IBRS", ++ "typename": "Skylake-Client-IBRS-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Client", ++ "typename": "Skylake-Client-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "SandyBridge-IBRS", ++ "typename": "SandyBridge-IBRS-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "SandyBridge", ++ "typename": "SandyBridge-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Penryn", ++ "typename": "Penryn-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G5", ++ "typename": "Opteron_G5-x86_64-cpu", ++ "unavailable-features": [ ++ "sse4a", ++ "misalignsse", ++ "xop", ++ "fma4", ++ "tbm" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G4", ++ "typename": "Opteron_G4-x86_64-cpu", ++ "unavailable-features": [ ++ "sse4a", ++ "misalignsse", ++ "xop", ++ "fma4" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G3", ++ "typename": "Opteron_G3-x86_64-cpu", ++ "unavailable-features": [ ++ "sse4a", ++ "misalignsse" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G2", ++ "typename": "Opteron_G2-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G1", ++ "typename": "Opteron_G1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Nehalem-IBRS", ++ "typename": "Nehalem-IBRS-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Nehalem", ++ "typename": "Nehalem-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "KnightsMill", ++ "typename": "KnightsMill-x86_64-cpu", ++ "unavailable-features": [ ++ "avx512f", ++ "avx512pf", ++ "avx512er", ++ "avx512cd", ++ "avx512-vpopcntdq", ++ "avx512-4vnniw", ++ "avx512-4fmaps", ++ "avx512f", ++ "avx512f", ++ "avx512f" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "IvyBridge-IBRS", ++ "typename": "IvyBridge-IBRS-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "IvyBridge", ++ "typename": "IvyBridge-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Icelake-Server", ++ "typename": "Icelake-Server-x86_64-cpu", ++ "unavailable-features": [ ++ "avx512f", ++ "avx512dq", ++ "clwb", ++ "intel-pt", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "avx512vbmi", ++ "pku", ++ "", ++ "avx512vbmi2", ++ "gfni", ++ "vaes", ++ "vpclmulqdq", ++ "avx512vnni", ++ "avx512bitalg", ++ "avx512-vpopcntdq", ++ "la57", ++ "pconfig", ++ "wbnoinvd", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Icelake-Client", ++ "typename": "Icelake-Client-x86_64-cpu", ++ "unavailable-features": [ ++ "intel-pt", ++ "avx512vbmi", ++ "pku", ++ "", ++ "avx512vbmi2", ++ "gfni", ++ "vaes", ++ "vpclmulqdq", ++ "avx512vnni", ++ "avx512bitalg", ++ "avx512-vpopcntdq", ++ "wbnoinvd", ++ "pku" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-noTSX-IBRS", ++ "typename": "Haswell-noTSX-IBRS-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-noTSX", ++ "typename": "Haswell-noTSX-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-IBRS", ++ "typename": "Haswell-IBRS-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell", ++ "typename": "Haswell-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "EPYC-IBPB", ++ "typename": "EPYC-IBPB-x86_64-cpu", ++ "unavailable-features": [ ++ "sha-ni", ++ "mmxext", ++ "fxsr-opt", ++ "cr8legacy", ++ "sse4a", ++ "misalignsse", ++ "osvw", ++ "ibpb" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "EPYC", ++ "typename": "EPYC-x86_64-cpu", ++ "unavailable-features": [ ++ "sha-ni", ++ "mmxext", ++ "fxsr-opt", ++ "cr8legacy", ++ "sse4a", ++ "misalignsse", ++ "osvw" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Conroe", ++ "typename": "Conroe-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Cascadelake-Server", ++ "typename": "Cascadelake-Server-x86_64-cpu", ++ "unavailable-features": [ ++ "avx512f", ++ "avx512dq", ++ "clwb", ++ "intel-pt", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "pku", ++ "", ++ "avx512vnni", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-noTSX-IBRS", ++ "typename": "Broadwell-noTSX-IBRS-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-noTSX", ++ "typename": "Broadwell-noTSX-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-IBRS", ++ "typename": "Broadwell-IBRS-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell", ++ "typename": "Broadwell-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "486", ++ "typename": "486-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ } ++ ], ++ "id": "definitions" ++} +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-7600U.xml b/tests/cputestdata/x86_64-cpuid-Core-i7-7600U.xml +new file mode 100644 +index 0000000000..d46811e3d3 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-7600U.xml +@@ -0,0 +1,47 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +-- +2.22.0 + diff --git a/SOURCES/libvirt-cputest-Add-data-for-Intel-R-Core-TM-i7-8700.patch b/SOURCES/libvirt-cputest-Add-data-for-Intel-R-Core-TM-i7-8700.patch new file mode 100644 index 0000000..96b2ce2 --- /dev/null +++ b/SOURCES/libvirt-cputest-Add-data-for-Intel-R-Core-TM-i7-8700.patch @@ -0,0 +1,873 @@ +From 697bcb394816e4880cdbdb211527f057f4aea564 Mon Sep 17 00:00:00 2001 +Message-Id: <697bcb394816e4880cdbdb211527f057f4aea564@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:24:53 +0200 +Subject: [PATCH] cputest: Add data for Intel(R) Core(TM) i7-8700 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 87a46f5d8f8b67b22eab8b25cd30a6b9901d6857) + +https://bugzilla.redhat.com/show_bug.cgi?id=1686895 + +Signed-off-by: Jiri Denemark +Message-Id: <2d5616ba4b88ef12435b52cfd7c90ce3360a83ef.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + tests/cputest.c | 1 + + .../x86_64-cpuid-Core-i7-8700-disabled.xml | 6 + + .../x86_64-cpuid-Core-i7-8700-enabled.xml | 8 + + .../x86_64-cpuid-Core-i7-8700-guest.xml | 28 + + .../x86_64-cpuid-Core-i7-8700-host.xml | 29 + + .../x86_64-cpuid-Core-i7-8700-json.xml | 12 + + .../x86_64-cpuid-Core-i7-8700.json | 650 ++++++++++++++++++ + .../cputestdata/x86_64-cpuid-Core-i7-8700.xml | 47 ++ + 8 files changed, 781 insertions(+) + create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-8700-disabled.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-8700-enabled.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-8700-guest.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-8700-host.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-8700-json.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-8700.json + create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-8700.xml + +diff --git a/tests/cputest.c b/tests/cputest.c +index bcbfe2d08a..9e5f807823 100644 +--- a/tests/cputest.c ++++ b/tests/cputest.c +@@ -1178,6 +1178,7 @@ mymain(void) + DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i7-5600U-ibrs", JSON_HOST); + DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i7-7600U", JSON_MODELS); + DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i7-7700", JSON_MODELS); ++ DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i7-8700", JSON_MODELS); + DO_TEST_CPUID(VIR_ARCH_X86_64, "Core2-E6850", JSON_HOST); + DO_TEST_CPUID(VIR_ARCH_X86_64, "Core2-Q9500", JSON_NONE); + DO_TEST_CPUID(VIR_ARCH_X86_64, "EPYC-7601-32-Core", JSON_HOST); +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-8700-disabled.xml b/tests/cputestdata/x86_64-cpuid-Core-i7-8700-disabled.xml +new file mode 100644 +index 0000000000..6a7de576f1 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-8700-disabled.xml +@@ -0,0 +1,6 @@ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-8700-enabled.xml b/tests/cputestdata/x86_64-cpuid-Core-i7-8700-enabled.xml +new file mode 100644 +index 0000000000..f0727d497b +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-8700-enabled.xml +@@ -0,0 +1,8 @@ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-8700-guest.xml b/tests/cputestdata/x86_64-cpuid-Core-i7-8700-guest.xml +new file mode 100644 +index 0000000000..70a0fc3286 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-8700-guest.xml +@@ -0,0 +1,28 @@ ++ ++ Skylake-Client-IBRS ++ Intel ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-8700-host.xml b/tests/cputestdata/x86_64-cpuid-Core-i7-8700-host.xml +new file mode 100644 +index 0000000000..bbdfb6aa61 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-8700-host.xml +@@ -0,0 +1,29 @@ ++ ++ x86_64 ++ Skylake-Client-IBRS ++ Intel ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-8700-json.xml b/tests/cputestdata/x86_64-cpuid-Core-i7-8700-json.xml +new file mode 100644 +index 0000000000..fd7539f7ce +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-8700-json.xml +@@ -0,0 +1,12 @@ ++ ++ Skylake-Client-IBRS ++ Intel ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-8700.json b/tests/cputestdata/x86_64-cpuid-Core-i7-8700.json +new file mode 100644 +index 0000000000..122a1b2985 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-8700.json +@@ -0,0 +1,650 @@ ++{ ++ "return": { ++ "model": { ++ "name": "base", ++ "props": { ++ "phys-bits": 0, ++ "core-id": -1, ++ "xlevel": 2147483656, ++ "cmov": true, ++ "ia64": false, ++ "aes": true, ++ "mmx": true, ++ "rdpid": false, ++ "arat": true, ++ "gfni": false, ++ "pause-filter": false, ++ "xsavec": true, ++ "intel-pt": false, ++ "osxsave": false, ++ "hv-frequencies": false, ++ "tsc-frequency": 0, ++ "xd": true, ++ "hv-vendor-id": "", ++ "kvm-asyncpf": true, ++ "kvm_asyncpf": true, ++ "perfctr_core": false, ++ "perfctr-core": false, ++ "mpx": true, ++ "pbe": false, ++ "decodeassists": false, ++ "avx512cd": false, ++ "sse4_1": true, ++ "sse4.1": true, ++ "sse4-1": true, ++ "family": 6, ++ "legacy-cache": true, ++ "vmware-cpuid-freq": true, ++ "avx512f": false, ++ "msr": true, ++ "mce": true, ++ "mca": true, ++ "hv-runtime": false, ++ "xcrypt": false, ++ "thread-id": -1, ++ "min-level": 13, ++ "xgetbv1": true, ++ "cid": false, ++ "hv-relaxed": false, ++ "hv-crash": false, ++ "ds": false, ++ "fxsr": true, ++ "xsaveopt": true, ++ "xtpr": false, ++ "avx512vl": false, ++ "avx512-vpopcntdq": false, ++ "phe": false, ++ "extapic": false, ++ "3dnowprefetch": true, ++ "avx512vbmi2": false, ++ "cr8legacy": false, ++ "cpuid-0xb": true, ++ "xcrypt-en": false, ++ "kvm_pv_eoi": true, ++ "apic-id": 4294967295, ++ "pn": false, ++ "dca": false, ++ "vendor": "GenuineIntel", ++ "pku": false, ++ "smx": false, ++ "cmp_legacy": false, ++ "cmp-legacy": false, ++ "node-id": -1, ++ "avx512-4fmaps": false, ++ "vmcb_clean": false, ++ "vmcb-clean": false, ++ "3dnowext": false, ++ "hle": true, ++ "npt": false, ++ "memory": "/machine/unattached/system[0]", ++ "clwb": false, ++ "lbrv": false, ++ "adx": true, ++ "ss": true, ++ "pni": true, ++ "svm_lock": false, ++ "svm-lock": false, ++ "pfthreshold": false, ++ "smep": true, ++ "smap": true, ++ "x2apic": true, ++ "avx512vbmi": false, ++ "avx512vnni": false, ++ "hv-stimer": false, ++ "i64": true, ++ "flushbyasid": false, ++ "f16c": true, ++ "ace2-en": false, ++ "pat": true, ++ "pae": true, ++ "sse": true, ++ "phe-en": false, ++ "kvm_nopiodelay": true, ++ "kvm-nopiodelay": true, ++ "tm": false, ++ "kvmclock-stable-bit": true, ++ "hypervisor": true, ++ "socket-id": -1, ++ "pcommit": false, ++ "syscall": true, ++ "level": 13, ++ "avx512dq": false, ++ "svm": false, ++ "full-cpuid-auto-level": true, ++ "hv-reset": false, ++ "invtsc": false, ++ "sse3": true, ++ "sse2": true, ++ "ssbd": true, ++ "est": false, ++ "avx512ifma": false, ++ "tm2": false, ++ "kvm-pv-eoi": true, ++ "cx8": true, ++ "kvm_mmu": false, ++ "kvm-mmu": false, ++ "sse4_2": true, ++ "sse4.2": true, ++ "sse4-2": true, ++ "pge": true, ++ "fill-mtrr-mask": true, ++ "avx512bitalg": false, ++ "nodeid_msr": false, ++ "pdcm": false, ++ "movbe": true, ++ "model": 158, ++ "nrip_save": false, ++ "nrip-save": false, ++ "kvm_pv_unhalt": true, ++ "ssse3": true, ++ "sse4a": false, ++ "invpcid": true, ++ "pdpe1gb": true, ++ "tsc-deadline": true, ++ "fma": true, ++ "cx16": true, ++ "de": true, ++ "enforce": false, ++ "stepping": 10, ++ "xsave": true, ++ "clflush": true, ++ "skinit": false, ++ "tsc": true, ++ "tce": false, ++ "fpu": true, ++ "ibs": false, ++ "ds_cpl": false, ++ "ds-cpl": false, ++ "host-phys-bits": true, ++ "fma4": false, ++ "la57": false, ++ "osvw": false, ++ "check": true, ++ "hv-spinlocks": -1, ++ "pmu": false, ++ "pmm": false, ++ "apic": true, ++ "spec-ctrl": true, ++ "min-xlevel2": 0, ++ "tsc-adjust": true, ++ "tsc_adjust": true, ++ "kvm-steal-time": true, ++ "kvm_steal_time": true, ++ "kvmclock": true, ++ "l3-cache": true, ++ "lwp": false, ++ "ibpb": false, ++ "xop": false, ++ "avx": true, ++ "ospke": false, ++ "ace2": false, ++ "avx512bw": false, ++ "acpi": false, ++ "hv-vapic": false, ++ "fsgsbase": true, ++ "ht": false, ++ "nx": true, ++ "pclmulqdq": true, ++ "mmxext": false, ++ "vaes": false, ++ "popcnt": true, ++ "xsaves": true, ++ "tcg-cpuid": true, ++ "lm": true, ++ "umip": true, ++ "pse": true, ++ "avx2": true, ++ "sep": true, ++ "pclmuldq": true, ++ "virt-ssbd": false, ++ "x-hv-max-vps": -1, ++ "nodeid-msr": false, ++ "kvm": true, ++ "misalignsse": false, ++ "min-xlevel": 2147483656, ++ "kvm-pv-unhalt": true, ++ "bmi2": true, ++ "bmi1": true, ++ "realized": false, ++ "tsc_scale": false, ++ "tsc-scale": false, ++ "topoext": false, ++ "hv-vpindex": false, ++ "xlevel2": 0, ++ "clflushopt": true, ++ "kvm-no-smi-migration": false, ++ "monitor": false, ++ "avx512er": false, ++ "pmm-en": false, ++ "pcid": true, ++ "3dnow": false, ++ "erms": true, ++ "lahf-lm": true, ++ "lahf_lm": true, ++ "vpclmulqdq": false, ++ "fxsr-opt": false, ++ "hv-synic": false, ++ "xstore": false, ++ "fxsr_opt": false, ++ "kvm-hint-dedicated": false, ++ "rtm": true, ++ "lmce": true, ++ "hv-time": false, ++ "perfctr-nb": false, ++ "perfctr_nb": false, ++ "ffxsr": false, ++ "rdrand": true, ++ "rdseed": true, ++ "avx512-4vnniw": false, ++ "vmx": false, ++ "vme": true, ++ "dtes64": false, ++ "mtrr": true, ++ "rdtscp": true, ++ "pse36": true, ++ "kvm-pv-tlb-flush": true, ++ "tbm": false, ++ "wdt": false, ++ "pause_filter": false, ++ "sha-ni": false, ++ "model-id": "Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz", ++ "abm": true, ++ "avx512pf": false, ++ "xstore-en": false ++ } ++ } ++ }, ++ "id": "model-expansion" ++} ++ ++{ ++ "return": [ ++ { ++ "name": "max", ++ "typename": "max-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": false ++ }, ++ { ++ "name": "host", ++ "typename": "host-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": false ++ }, ++ { ++ "name": "base", ++ "typename": "base-x86_64-cpu", ++ "unavailable-features": [], ++ "static": true, ++ "migration-safe": true ++ }, ++ { ++ "name": "qemu64", ++ "typename": "qemu64-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "qemu32", ++ "typename": "qemu32-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "phenom", ++ "typename": "phenom-x86_64-cpu", ++ "unavailable-features": [ ++ "mmxext", ++ "fxsr-opt", ++ "3dnowext", ++ "3dnow", ++ "sse4a", ++ "npt" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "pentium3", ++ "typename": "pentium3-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "pentium2", ++ "typename": "pentium2-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "pentium", ++ "typename": "pentium-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "n270", ++ "typename": "n270-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "kvm64", ++ "typename": "kvm64-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "kvm32", ++ "typename": "kvm32-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "cpu64-rhel6", ++ "typename": "cpu64-rhel6-x86_64-cpu", ++ "unavailable-features": [ ++ "sse4a" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "coreduo", ++ "typename": "coreduo-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "core2duo", ++ "typename": "core2duo-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "athlon", ++ "typename": "athlon-x86_64-cpu", ++ "unavailable-features": [ ++ "mmxext", ++ "3dnowext", ++ "3dnow" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Westmere", ++ "typename": "Westmere-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Westmere-IBRS", ++ "typename": "Westmere-IBRS-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Server", ++ "typename": "Skylake-Server-x86_64-cpu", ++ "unavailable-features": [ ++ "avx512f", ++ "avx512dq", ++ "clwb", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "avx512f", ++ "avx512f", ++ "avx512f" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Server-IBRS", ++ "typename": "Skylake-Server-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "avx512f", ++ "avx512dq", ++ "clwb", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "avx512f", ++ "avx512f", ++ "avx512f" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Client", ++ "typename": "Skylake-Client-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Client-IBRS", ++ "typename": "Skylake-Client-IBRS-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "SandyBridge", ++ "typename": "SandyBridge-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "SandyBridge-IBRS", ++ "typename": "SandyBridge-IBRS-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Penryn", ++ "typename": "Penryn-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G5", ++ "typename": "Opteron_G5-x86_64-cpu", ++ "unavailable-features": [ ++ "sse4a", ++ "misalignsse", ++ "xop", ++ "fma4", ++ "tbm" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G4", ++ "typename": "Opteron_G4-x86_64-cpu", ++ "unavailable-features": [ ++ "sse4a", ++ "misalignsse", ++ "xop", ++ "fma4" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G3", ++ "typename": "Opteron_G3-x86_64-cpu", ++ "unavailable-features": [ ++ "sse4a", ++ "misalignsse" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G2", ++ "typename": "Opteron_G2-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G1", ++ "typename": "Opteron_G1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Nehalem", ++ "typename": "Nehalem-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Nehalem-IBRS", ++ "typename": "Nehalem-IBRS-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "IvyBridge", ++ "typename": "IvyBridge-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "IvyBridge-IBRS", ++ "typename": "IvyBridge-IBRS-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell", ++ "typename": "Haswell-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-noTSX", ++ "typename": "Haswell-noTSX-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-noTSX-IBRS", ++ "typename": "Haswell-noTSX-IBRS-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-IBRS", ++ "typename": "Haswell-IBRS-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "EPYC", ++ "typename": "EPYC-x86_64-cpu", ++ "unavailable-features": [ ++ "sha-ni", ++ "mmxext", ++ "fxsr-opt", ++ "cr8legacy", ++ "sse4a", ++ "misalignsse", ++ "osvw" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "EPYC-IBPB", ++ "typename": "EPYC-IBPB-x86_64-cpu", ++ "unavailable-features": [ ++ "sha-ni", ++ "mmxext", ++ "fxsr-opt", ++ "cr8legacy", ++ "sse4a", ++ "misalignsse", ++ "osvw", ++ "ibpb" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Conroe", ++ "typename": "Conroe-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell", ++ "typename": "Broadwell-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-noTSX", ++ "typename": "Broadwell-noTSX-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-noTSX-IBRS", ++ "typename": "Broadwell-noTSX-IBRS-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-IBRS", ++ "typename": "Broadwell-IBRS-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "486", ++ "typename": "486-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ } ++ ], ++ "id": "definitions" ++} +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-8700.xml b/tests/cputestdata/x86_64-cpuid-Core-i7-8700.xml +new file mode 100644 +index 0000000000..03ba0a3925 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-8700.xml +@@ -0,0 +1,47 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +-- +2.22.0 + diff --git a/SOURCES/libvirt-cputest-Add-data-for-Intel-R-Xeon-R-CPU-E3-1225-v5.patch b/SOURCES/libvirt-cputest-Add-data-for-Intel-R-Xeon-R-CPU-E3-1225-v5.patch index b42496c..d0b011b 100644 --- a/SOURCES/libvirt-cputest-Add-data-for-Intel-R-Xeon-R-CPU-E3-1225-v5.patch +++ b/SOURCES/libvirt-cputest-Add-data-for-Intel-R-Xeon-R-CPU-E3-1225-v5.patch @@ -1,5 +1,5 @@ -From 7d229030e2ff3a2ca7664497205d3306c8ab6bb0 Mon Sep 17 00:00:00 2001 -Message-Id: <7d229030e2ff3a2ca7664497205d3306c8ab6bb0@dist-git> +From cd7339269704e58b78c1033d46a336448256b4e7 Mon Sep 17 00:00:00 2001 +Message-Id: From: Jiri Denemark Date: Fri, 5 Apr 2019 11:19:30 +0200 Subject: [PATCH] cputest: Add data for Intel(R) Xeon(R) CPU E3-1225 v5 @@ -9,9 +9,9 @@ Content-Transfer-Encoding: 8bit Signed-off-by: Jiri Denemark Reviewed-by: Daniel P. Berrangé -(cherry picked from a private commit) +(cherry picked from commit 5cd9db3ac11e88846cbcf95fad9f6fae9d880dee) -CVE-2018-11091, CVE-2018-12126, CVE-2018-12127, CVE-2018-12130 +CVE-2018-12126, CVE-2018-12127, CVE-2018-12130, CVE-2019-11091 Signed-off-by: Jiri Denemark --- diff --git a/SOURCES/libvirt-cputest-Add-data-for-Intel-R-Xeon-R-CPU-E5-2630-v4.patch b/SOURCES/libvirt-cputest-Add-data-for-Intel-R-Xeon-R-CPU-E5-2630-v4.patch new file mode 100644 index 0000000..63e259a --- /dev/null +++ b/SOURCES/libvirt-cputest-Add-data-for-Intel-R-Xeon-R-CPU-E5-2630-v4.patch @@ -0,0 +1,824 @@ +From 4e22f6ec928e62811db06cd717fc286dd1dfba8e Mon Sep 17 00:00:00 2001 +Message-Id: <4e22f6ec928e62811db06cd717fc286dd1dfba8e@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:24:49 +0200 +Subject: [PATCH] cputest: Add data for Intel(R) Xeon(R) CPU E5-2630 v4 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 8d068f360183ecd55e3213dbe9ba12f7d6470751) + +https://bugzilla.redhat.com/show_bug.cgi?id=1686895 + +Signed-off-by: Jiri Denemark +Message-Id: <5bc8830efc48a09ace38df33a83152ae0cf3a5fe.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + tests/cputest.c | 1 + + .../x86_64-cpuid-Xeon-E5-2630-v4-disabled.xml | 7 + + .../x86_64-cpuid-Xeon-E5-2630-v4-enabled.xml | 8 + + .../x86_64-cpuid-Xeon-E5-2630-v4-guest.xml | 31 + + .../x86_64-cpuid-Xeon-E5-2630-v4-host.xml | 35 + + .../x86_64-cpuid-Xeon-E5-2630-v4-json.xml | 11 + + .../x86_64-cpuid-Xeon-E5-2630-v4.json | 596 ++++++++++++++++++ + .../x86_64-cpuid-Xeon-E5-2630-v4.xml | 43 ++ + 8 files changed, 732 insertions(+) + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4-disabled.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4-enabled.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4-guest.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4-host.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4-json.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4.json + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4.xml + +diff --git a/tests/cputest.c b/tests/cputest.c +index fbb2a86af8..f43144edc9 100644 +--- a/tests/cputest.c ++++ b/tests/cputest.c +@@ -1195,6 +1195,7 @@ mymain(void) + DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-E5-2609-v3", JSON_MODELS); + DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-E5-2623-v4", JSON_MODELS); + DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-E5-2630-v3", JSON_HOST); ++ DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-E5-2630-v4", JSON_MODELS); + DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-E5-2650-v3", JSON_HOST); + DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-E5-2650-v4", JSON_MODELS); + DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-E7-4820", JSON_HOST); +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4-disabled.xml b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4-disabled.xml +new file mode 100644 +index 0000000000..3ffb246167 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4-disabled.xml +@@ -0,0 +1,7 @@ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4-enabled.xml b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4-enabled.xml +new file mode 100644 +index 0000000000..f2d4f2826d +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4-enabled.xml +@@ -0,0 +1,8 @@ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4-guest.xml b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4-guest.xml +new file mode 100644 +index 0000000000..cd7e25b52a +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4-guest.xml +@@ -0,0 +1,31 @@ ++ ++ Skylake-Client ++ Intel ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4-host.xml b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4-host.xml +new file mode 100644 +index 0000000000..5dd8d749de +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4-host.xml +@@ -0,0 +1,35 @@ ++ ++ x86_64 ++ Broadwell ++ Intel ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4-json.xml b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4-json.xml +new file mode 100644 +index 0000000000..5dfce947b2 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4-json.xml +@@ -0,0 +1,11 @@ ++ ++ Skylake-Client ++ Intel ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4.json b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4.json +new file mode 100644 +index 0000000000..ee09950fce +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4.json +@@ -0,0 +1,596 @@ ++{ ++ "return": { ++ "model": { ++ "name": "base", ++ "props": { ++ "phys-bits": 0, ++ "core-id": -1, ++ "xlevel": 2147483656, ++ "cmov": true, ++ "ia64": false, ++ "aes": true, ++ "mmx": true, ++ "arat": true, ++ "rdpid": false, ++ "pause-filter": false, ++ "xsavec": false, ++ "osxsave": false, ++ "tsc-frequency": 0, ++ "xd": true, ++ "hv-vendor-id": "", ++ "kvm-asyncpf": true, ++ "kvm_asyncpf": true, ++ "perfctr_core": false, ++ "perfctr-core": false, ++ "mpx": false, ++ "decodeassists": false, ++ "avx512cd": false, ++ "pbe": false, ++ "sse4_1": true, ++ "sse4.1": true, ++ "sse4-1": true, ++ "family": 6, ++ "vmware-cpuid-freq": true, ++ "avx512f": false, ++ "xcrypt": false, ++ "msr": true, ++ "mce": true, ++ "mca": true, ++ "thread-id": -1, ++ "min-level": 13, ++ "xgetbv1": false, ++ "cid": false, ++ "hv-relaxed": false, ++ "fxsr": true, ++ "ds": false, ++ "hv-crash": false, ++ "xsaveopt": true, ++ "xtpr": false, ++ "avx512-vpopcntdq": false, ++ "phe": false, ++ "avx512vl": false, ++ "extapic": false, ++ "3dnowprefetch": true, ++ "cr8legacy": false, ++ "stibp": false, ++ "cpuid-0xb": true, ++ "xcrypt-en": false, ++ "kvm_pv_eoi": true, ++ "apic-id": 4294967295, ++ "pn": false, ++ "dca": false, ++ "vendor": "GenuineIntel", ++ "pku": false, ++ "smx": false, ++ "cmp-legacy": false, ++ "cmp_legacy": false, ++ "avx512-4fmaps": false, ++ "vmcb-clean": false, ++ "vmcb_clean": false, ++ "3dnowext": false, ++ "hle": true, ++ "npt": false, ++ "memory": "/machine/unattached/system[0]", ++ "clwb": false, ++ "lbrv": false, ++ "adx": true, ++ "ss": true, ++ "pni": true, ++ "svm_lock": false, ++ "svm-lock": false, ++ "smep": true, ++ "pfthreshold": false, ++ "smap": true, ++ "x2apic": true, ++ "avx512vbmi": false, ++ "i64": true, ++ "flushbyasid": false, ++ "f16c": true, ++ "ace2-en": false, ++ "pat": true, ++ "pae": true, ++ "sse": true, ++ "phe-en": false, ++ "kvm-nopiodelay": true, ++ "kvm_nopiodelay": true, ++ "tm": false, ++ "kvmclock-stable-bit": true, ++ "hypervisor": true, ++ "socket-id": -1, ++ "pcommit": false, ++ "syscall": true, ++ "level": 13, ++ "avx512dq": false, ++ "svm": false, ++ "full-cpuid-auto-level": true, ++ "invtsc": false, ++ "sse3": true, ++ "sse2": true, ++ "est": false, ++ "avx512ifma": false, ++ "tm2": false, ++ "kvm-pv-eoi": true, ++ "cx8": true, ++ "kvm-mmu": false, ++ "kvm_mmu": false, ++ "sse4_2": true, ++ "sse4.2": true, ++ "sse4-2": true, ++ "pge": true, ++ "fill-mtrr-mask": true, ++ "pdcm": false, ++ "nodeid_msr": false, ++ "model": 79, ++ "movbe": true, ++ "nrip-save": false, ++ "nrip_save": false, ++ "sse4a": false, ++ "ssse3": true, ++ "kvm_pv_unhalt": true, ++ "invpcid": true, ++ "pdpe1gb": true, ++ "tsc-deadline": true, ++ "fma": true, ++ "cx16": true, ++ "de": true, ++ "enforce": false, ++ "stepping": 1, ++ "xsave": true, ++ "clflush": true, ++ "arch-facilities": false, ++ "skinit": false, ++ "tce": false, ++ "tsc": true, ++ "fpu": true, ++ "ds-cpl": false, ++ "ds_cpl": false, ++ "ibs": false, ++ "host-phys-bits": true, ++ "fma4": false, ++ "la57": false, ++ "osvw": false, ++ "check": true, ++ "hv-spinlocks": -1, ++ "pmm": false, ++ "apic": true, ++ "pmu": false, ++ "spec-ctrl": false, ++ "min-xlevel2": 0, ++ "tsc-adjust": true, ++ "tsc_adjust": true, ++ "kvm-steal-time": true, ++ "kvm_steal_time": true, ++ "kvmclock": true, ++ "l3-cache": true, ++ "lwp": false, ++ "xop": false, ++ "ibpb": false, ++ "avx": true, ++ "ospke": false, ++ "ace2": false, ++ "acpi": false, ++ "avx512bw": false, ++ "hv-vapic": false, ++ "fsgsbase": true, ++ "ht": false, ++ "nx": true, ++ "pclmulqdq": true, ++ "mmxext": false, ++ "popcnt": true, ++ "xsaves": false, ++ "lm": true, ++ "umip": false, ++ "avx2": true, ++ "pse": true, ++ "sep": true, ++ "pclmuldq": true, ++ "nodeid-msr": false, ++ "kvm": true, ++ "misalignsse": false, ++ "min-xlevel": 2147483656, ++ "bmi2": true, ++ "bmi1": true, ++ "kvm-pv-unhalt": true, ++ "realized": false, ++ "tsc-scale": false, ++ "tsc_scale": false, ++ "topoext": false, ++ "xlevel2": 0, ++ "clflushopt": false, ++ "kvm-no-smi-migration": false, ++ "monitor": false, ++ "avx512er": false, ++ "pmm-en": false, ++ "pcid": true, ++ "3dnow": false, ++ "erms": true, ++ "lahf-lm": true, ++ "lahf_lm": true, ++ "xstore": false, ++ "fxsr-opt": false, ++ "fxsr_opt": false, ++ "rtm": true, ++ "lmce": true, ++ "hv-time": false, ++ "perfctr-nb": false, ++ "perfctr_nb": false, ++ "ffxsr": false, ++ "rdrand": true, ++ "rdseed": true, ++ "avx512-4vnniw": false, ++ "vme": true, ++ "vmx": false, ++ "dtes64": false, ++ "mtrr": true, ++ "rdtscp": true, ++ "pse36": true, ++ "tbm": false, ++ "wdt": false, ++ "pause_filter": false, ++ "model-id": "Intel(R) Xeon(R) CPU E5-2630 v4 @ 2.20GHz", ++ "sha-ni": false, ++ "abm": true, ++ "avx512pf": false, ++ "xstore-en": false ++ } ++ } ++ }, ++ "id": "model-expansion" ++} ++ ++ ++{ ++ "return": [ ++ { ++ "name": "max", ++ "typename": "max-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": false ++ }, ++ { ++ "name": "host", ++ "typename": "host-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": false ++ }, ++ { ++ "name": "base", ++ "typename": "base-x86_64-cpu", ++ "unavailable-features": [], ++ "static": true, ++ "migration-safe": true ++ }, ++ { ++ "name": "qemu64", ++ "typename": "qemu64-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "qemu32", ++ "typename": "qemu32-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "phenom", ++ "typename": "phenom-x86_64-cpu", ++ "unavailable-features": [ ++ "mmxext", ++ "fxsr-opt", ++ "3dnowext", ++ "3dnow", ++ "sse4a", ++ "npt" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "pentium3", ++ "typename": "pentium3-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "pentium2", ++ "typename": "pentium2-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "pentium", ++ "typename": "pentium-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "n270", ++ "typename": "n270-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "kvm64", ++ "typename": "kvm64-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "kvm32", ++ "typename": "kvm32-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "cpu64-rhel6", ++ "typename": "cpu64-rhel6-x86_64-cpu", ++ "unavailable-features": [ ++ "sse4a" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "coreduo", ++ "typename": "coreduo-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "core2duo", ++ "typename": "core2duo-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "athlon", ++ "typename": "athlon-x86_64-cpu", ++ "unavailable-features": [ ++ "mmxext", ++ "3dnowext", ++ "3dnow" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Westmere", ++ "typename": "Westmere-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Westmere-IBRS", ++ "typename": "Westmere-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "spec-ctrl" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Client", ++ "typename": "Skylake-Client-x86_64-cpu", ++ "unavailable-features": [ ++ "mpx", ++ "xsavec", ++ "xgetbv1", ++ "mpx", ++ "mpx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Client-IBRS", ++ "typename": "Skylake-Client-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "mpx", ++ "spec-ctrl", ++ "xsavec", ++ "xgetbv1", ++ "mpx", ++ "mpx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "SandyBridge", ++ "typename": "SandyBridge-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "SandyBridge-IBRS", ++ "typename": "SandyBridge-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "spec-ctrl" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Penryn", ++ "typename": "Penryn-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G5", ++ "typename": "Opteron_G5-x86_64-cpu", ++ "unavailable-features": [ ++ "sse4a", ++ "misalignsse", ++ "xop", ++ "fma4", ++ "tbm" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G4", ++ "typename": "Opteron_G4-x86_64-cpu", ++ "unavailable-features": [ ++ "sse4a", ++ "misalignsse", ++ "xop", ++ "fma4" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G3", ++ "typename": "Opteron_G3-x86_64-cpu", ++ "unavailable-features": [ ++ "sse4a", ++ "misalignsse" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G2", ++ "typename": "Opteron_G2-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G1", ++ "typename": "Opteron_G1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Nehalem", ++ "typename": "Nehalem-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Nehalem-IBRS", ++ "typename": "Nehalem-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "spec-ctrl" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "IvyBridge", ++ "typename": "IvyBridge-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "IvyBridge-IBRS", ++ "typename": "IvyBridge-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "spec-ctrl" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell", ++ "typename": "Haswell-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-noTSX", ++ "typename": "Haswell-noTSX-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-noTSX-IBRS", ++ "typename": "Haswell-noTSX-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "spec-ctrl" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-IBRS", ++ "typename": "Haswell-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "spec-ctrl" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Conroe", ++ "typename": "Conroe-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell", ++ "typename": "Broadwell-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-noTSX", ++ "typename": "Broadwell-noTSX-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-noTSX-IBRS", ++ "typename": "Broadwell-noTSX-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "spec-ctrl" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-IBRS", ++ "typename": "Broadwell-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "spec-ctrl" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "486", ++ "typename": "486-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ } ++ ], ++ "id": "definitions" ++} +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4.xml b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4.xml +new file mode 100644 +index 0000000000..d74c207104 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4.xml +@@ -0,0 +1,43 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +-- +2.22.0 + diff --git a/SOURCES/libvirt-cputest-Add-data-for-Intel-R-Xeon-R-CPU-E5-2650.patch b/SOURCES/libvirt-cputest-Add-data-for-Intel-R-Xeon-R-CPU-E5-2650.patch new file mode 100644 index 0000000..eb8dcdb --- /dev/null +++ b/SOURCES/libvirt-cputest-Add-data-for-Intel-R-Xeon-R-CPU-E5-2650.patch @@ -0,0 +1,1144 @@ +From 2afffd01a71c3b2efeeaefed4829a87d46956c8b Mon Sep 17 00:00:00 2001 +Message-Id: <2afffd01a71c3b2efeeaefed4829a87d46956c8b@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:24:52 +0200 +Subject: [PATCH] cputest: Add data for Intel(R) Xeon(R) CPU E5-2650 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 483679d48f6b5fb731bdedca3b5d3b33c011d6a3) + +https://bugzilla.redhat.com/show_bug.cgi?id=1686895 + +Signed-off-by: Jiri Denemark +Message-Id: <944ffeee03d77b02d000ea6c70d98307d850eaad.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + tests/cputest.c | 1 + + .../x86_64-cpuid-Xeon-E5-2650-disabled.xml | 5 + + .../x86_64-cpuid-Xeon-E5-2650-enabled.xml | 8 + + .../x86_64-cpuid-Xeon-E5-2650-guest.xml | 29 + + .../x86_64-cpuid-Xeon-E5-2650-host.xml | 30 + + .../x86_64-cpuid-Xeon-E5-2650-json.xml | 14 + + .../x86_64-cpuid-Xeon-E5-2650.json | 931 ++++++++++++++++++ + .../cputestdata/x86_64-cpuid-Xeon-E5-2650.xml | 34 + + 8 files changed, 1052 insertions(+) + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-disabled.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-enabled.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-guest.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-host.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-json.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2650.json + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2650.xml + +diff --git a/tests/cputest.c b/tests/cputest.c +index e2c7860f3f..bcbfe2d08a 100644 +--- a/tests/cputest.c ++++ b/tests/cputest.c +@@ -1197,6 +1197,7 @@ mymain(void) + DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-E5-2623-v4", JSON_MODELS); + DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-E5-2630-v3", JSON_HOST); + DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-E5-2630-v4", JSON_MODELS); ++ DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-E5-2650", JSON_MODELS); + DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-E5-2650-v3", JSON_HOST); + DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-E5-2650-v4", JSON_MODELS); + DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-E7-4820", JSON_HOST); +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-disabled.xml b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-disabled.xml +new file mode 100644 +index 0000000000..d9538892eb +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-disabled.xml +@@ -0,0 +1,5 @@ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-enabled.xml b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-enabled.xml +new file mode 100644 +index 0000000000..fcc1e84686 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-enabled.xml +@@ -0,0 +1,8 @@ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-guest.xml b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-guest.xml +new file mode 100644 +index 0000000000..e507642df1 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-guest.xml +@@ -0,0 +1,29 @@ ++ ++ SandyBridge-IBRS ++ Intel ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-host.xml b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-host.xml +new file mode 100644 +index 0000000000..80ca6c343f +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-host.xml +@@ -0,0 +1,30 @@ ++ ++ x86_64 ++ SandyBridge-IBRS ++ Intel ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-json.xml b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-json.xml +new file mode 100644 +index 0000000000..bf587d3ffc +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-json.xml +@@ -0,0 +1,14 @@ ++ ++ SandyBridge-IBRS ++ Intel ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650.json b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650.json +new file mode 100644 +index 0000000000..a7a8542203 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650.json +@@ -0,0 +1,931 @@ ++{ ++ "return": { ++ "model": { ++ "name": "base", ++ "props": { ++ "phys-bits": 0, ++ "core-id": -1, ++ "xlevel": 2147483656, ++ "cmov": true, ++ "ia64": false, ++ "aes": true, ++ "mmx": true, ++ "rdpid": false, ++ "arat": true, ++ "gfni": false, ++ "pause-filter": false, ++ "xsavec": false, ++ "intel-pt": false, ++ "osxsave": false, ++ "hv-frequencies": false, ++ "tsc-frequency": 0, ++ "xd": true, ++ "hv-vendor-id": "", ++ "kvm-asyncpf": true, ++ "kvm_asyncpf": true, ++ "perfctr_core": false, ++ "perfctr-core": false, ++ "mpx": false, ++ "pbe": false, ++ "decodeassists": false, ++ "avx512cd": false, ++ "sse4_1": true, ++ "sse4.1": true, ++ "sse4-1": true, ++ "family": 6, ++ "legacy-cache": true, ++ "vmware-cpuid-freq": true, ++ "avx512f": false, ++ "msr": true, ++ "mce": true, ++ "mca": true, ++ "hv-runtime": false, ++ "xcrypt": false, ++ "thread-id": -1, ++ "min-level": 13, ++ "xgetbv1": false, ++ "cid": false, ++ "hv-relaxed": false, ++ "hv-crash": false, ++ "ds": false, ++ "fxsr": true, ++ "xsaveopt": true, ++ "xtpr": false, ++ "avx512vl": false, ++ "avx512-vpopcntdq": false, ++ "phe": false, ++ "extapic": false, ++ "3dnowprefetch": false, ++ "avx512vbmi2": false, ++ "cr8legacy": false, ++ "stibp": true, ++ "cpuid-0xb": true, ++ "xcrypt-en": false, ++ "kvm_pv_eoi": true, ++ "apic-id": 4294967295, ++ "pn": false, ++ "dca": false, ++ "vendor": "GenuineIntel", ++ "pku": false, ++ "smx": false, ++ "cmp_legacy": false, ++ "cmp-legacy": false, ++ "node-id": -1, ++ "avx512-4fmaps": false, ++ "vmcb_clean": false, ++ "vmcb-clean": false, ++ "3dnowext": false, ++ "hle": false, ++ "npt": false, ++ "memory": "/machine/unattached/system[0]", ++ "clwb": false, ++ "lbrv": false, ++ "adx": false, ++ "ss": true, ++ "pni": true, ++ "svm_lock": false, ++ "svm-lock": false, ++ "pfthreshold": false, ++ "smep": false, ++ "smap": false, ++ "x2apic": true, ++ "avx512vbmi": false, ++ "avx512vnni": false, ++ "hv-stimer": false, ++ "i64": true, ++ "flushbyasid": false, ++ "f16c": false, ++ "ace2-en": false, ++ "pat": true, ++ "pae": true, ++ "sse": true, ++ "phe-en": false, ++ "kvm_nopiodelay": true, ++ "kvm-nopiodelay": true, ++ "tm": false, ++ "kvmclock-stable-bit": true, ++ "hypervisor": true, ++ "socket-id": -1, ++ "pcommit": false, ++ "syscall": true, ++ "level": 13, ++ "avx512dq": false, ++ "svm": false, ++ "full-cpuid-auto-level": true, ++ "hv-reset": false, ++ "invtsc": false, ++ "sse3": true, ++ "sse2": true, ++ "ssbd": true, ++ "est": false, ++ "avx512ifma": false, ++ "tm2": false, ++ "kvm-pv-eoi": true, ++ "cx8": true, ++ "kvm_mmu": false, ++ "kvm-mmu": false, ++ "sse4_2": true, ++ "sse4.2": true, ++ "sse4-2": true, ++ "pge": true, ++ "fill-mtrr-mask": true, ++ "avx512bitalg": false, ++ "nodeid_msr": false, ++ "pdcm": false, ++ "movbe": false, ++ "model": 45, ++ "nrip_save": false, ++ "nrip-save": false, ++ "kvm_pv_unhalt": true, ++ "ssse3": true, ++ "sse4a": false, ++ "invpcid": false, ++ "pdpe1gb": true, ++ "tsc-deadline": true, ++ "fma": false, ++ "cx16": true, ++ "de": true, ++ "enforce": false, ++ "stepping": 7, ++ "xsave": true, ++ "clflush": true, ++ "skinit": false, ++ "tsc": true, ++ "tce": false, ++ "fpu": true, ++ "ibs": false, ++ "ds_cpl": false, ++ "ds-cpl": false, ++ "host-phys-bits": true, ++ "fma4": false, ++ "la57": false, ++ "osvw": false, ++ "check": true, ++ "hv-spinlocks": -1, ++ "pmu": false, ++ "pmm": false, ++ "apic": true, ++ "spec-ctrl": true, ++ "min-xlevel2": 0, ++ "tsc-adjust": true, ++ "tsc_adjust": true, ++ "kvm-steal-time": true, ++ "kvm_steal_time": true, ++ "kvmclock": true, ++ "l3-cache": true, ++ "lwp": false, ++ "ibpb": false, ++ "xop": false, ++ "avx": true, ++ "ospke": false, ++ "ace2": false, ++ "avx512bw": false, ++ "acpi": false, ++ "hv-vapic": false, ++ "fsgsbase": false, ++ "ht": false, ++ "nx": true, ++ "pclmulqdq": true, ++ "mmxext": false, ++ "vaes": false, ++ "popcnt": true, ++ "xsaves": false, ++ "tcg-cpuid": true, ++ "lm": true, ++ "umip": false, ++ "pse": true, ++ "avx2": false, ++ "sep": true, ++ "pclmuldq": true, ++ "virt-ssbd": false, ++ "x-hv-max-vps": -1, ++ "nodeid-msr": false, ++ "kvm": true, ++ "misalignsse": false, ++ "min-xlevel": 2147483656, ++ "kvm-pv-unhalt": true, ++ "bmi2": false, ++ "bmi1": false, ++ "realized": false, ++ "tsc_scale": false, ++ "tsc-scale": false, ++ "topoext": false, ++ "hv-vpindex": false, ++ "xlevel2": 0, ++ "clflushopt": false, ++ "kvm-no-smi-migration": false, ++ "monitor": false, ++ "avx512er": false, ++ "pmm-en": false, ++ "pcid": true, ++ "3dnow": false, ++ "erms": false, ++ "lahf-lm": true, ++ "lahf_lm": true, ++ "vpclmulqdq": false, ++ "fxsr-opt": false, ++ "hv-synic": false, ++ "xstore": false, ++ "fxsr_opt": false, ++ "kvm-hint-dedicated": false, ++ "rtm": false, ++ "lmce": true, ++ "hv-time": false, ++ "perfctr-nb": false, ++ "perfctr_nb": false, ++ "ffxsr": false, ++ "rdrand": false, ++ "rdseed": false, ++ "avx512-4vnniw": false, ++ "vmx": false, ++ "vme": true, ++ "dtes64": false, ++ "mtrr": true, ++ "rdtscp": true, ++ "pse36": true, ++ "kvm-pv-tlb-flush": false, ++ "tbm": false, ++ "wdt": false, ++ "pause_filter": false, ++ "sha-ni": false, ++ "model-id": " Intel(R) Xeon(R) CPU E5-2650 0 @ 2.00GHz", ++ "abm": false, ++ "avx512pf": false, ++ "xstore-en": false ++ } ++ } ++ }, ++ "id": "model-expansion" ++} ++ ++{ ++ "return": [ ++ { ++ "name": "max", ++ "typename": "max-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": false ++ }, ++ { ++ "name": "host", ++ "typename": "host-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": false ++ }, ++ { ++ "name": "base", ++ "typename": "base-x86_64-cpu", ++ "unavailable-features": [], ++ "static": true, ++ "migration-safe": true ++ }, ++ { ++ "name": "qemu64", ++ "typename": "qemu64-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "qemu32", ++ "typename": "qemu32-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "phenom", ++ "typename": "phenom-x86_64-cpu", ++ "unavailable-features": [ ++ "mmxext", ++ "fxsr-opt", ++ "3dnowext", ++ "3dnow", ++ "abm", ++ "sse4a", ++ "npt" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "pentium3", ++ "typename": "pentium3-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "pentium2", ++ "typename": "pentium2-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "pentium", ++ "typename": "pentium-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "n270", ++ "typename": "n270-x86_64-cpu", ++ "unavailable-features": [ ++ "movbe" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "kvm64", ++ "typename": "kvm64-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "kvm32", ++ "typename": "kvm32-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "cpu64-rhel6", ++ "typename": "cpu64-rhel6-x86_64-cpu", ++ "unavailable-features": [ ++ "abm", ++ "sse4a" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "coreduo", ++ "typename": "coreduo-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "core2duo", ++ "typename": "core2duo-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "athlon", ++ "typename": "athlon-x86_64-cpu", ++ "unavailable-features": [ ++ "mmxext", ++ "3dnowext", ++ "3dnow" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Westmere", ++ "typename": "Westmere-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Westmere-IBRS", ++ "typename": "Westmere-IBRS-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Server", ++ "typename": "Skylake-Server-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "movbe", ++ "f16c", ++ "rdrand", ++ "fsgsbase", ++ "bmi1", ++ "hle", ++ "avx2", ++ "smep", ++ "bmi2", ++ "erms", ++ "invpcid", ++ "rtm", ++ "mpx", ++ "avx512f", ++ "avx512dq", ++ "rdseed", ++ "adx", ++ "smap", ++ "clflushopt", ++ "clwb", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "abm", ++ "3dnowprefetch", ++ "xsavec", ++ "xgetbv1", ++ "mpx", ++ "mpx", ++ "avx512f", ++ "avx512f", ++ "avx512f" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Server-IBRS", ++ "typename": "Skylake-Server-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "movbe", ++ "f16c", ++ "rdrand", ++ "fsgsbase", ++ "bmi1", ++ "hle", ++ "avx2", ++ "smep", ++ "bmi2", ++ "erms", ++ "invpcid", ++ "rtm", ++ "mpx", ++ "avx512f", ++ "avx512dq", ++ "rdseed", ++ "adx", ++ "smap", ++ "clwb", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "abm", ++ "3dnowprefetch", ++ "xsavec", ++ "xgetbv1", ++ "mpx", ++ "mpx", ++ "avx512f", ++ "avx512f", ++ "avx512f" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Client", ++ "typename": "Skylake-Client-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "movbe", ++ "f16c", ++ "rdrand", ++ "fsgsbase", ++ "bmi1", ++ "hle", ++ "avx2", ++ "smep", ++ "bmi2", ++ "erms", ++ "invpcid", ++ "rtm", ++ "mpx", ++ "rdseed", ++ "adx", ++ "smap", ++ "abm", ++ "3dnowprefetch", ++ "xsavec", ++ "xgetbv1", ++ "mpx", ++ "mpx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Client-IBRS", ++ "typename": "Skylake-Client-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "movbe", ++ "f16c", ++ "rdrand", ++ "fsgsbase", ++ "bmi1", ++ "hle", ++ "avx2", ++ "smep", ++ "bmi2", ++ "erms", ++ "invpcid", ++ "rtm", ++ "mpx", ++ "rdseed", ++ "adx", ++ "smap", ++ "abm", ++ "3dnowprefetch", ++ "xsavec", ++ "xgetbv1", ++ "mpx", ++ "mpx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "SandyBridge", ++ "typename": "SandyBridge-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "SandyBridge-IBRS", ++ "typename": "SandyBridge-IBRS-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Penryn", ++ "typename": "Penryn-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G5", ++ "typename": "Opteron_G5-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "f16c", ++ "abm", ++ "sse4a", ++ "misalignsse", ++ "3dnowprefetch", ++ "xop", ++ "fma4", ++ "tbm" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G4", ++ "typename": "Opteron_G4-x86_64-cpu", ++ "unavailable-features": [ ++ "abm", ++ "sse4a", ++ "misalignsse", ++ "3dnowprefetch", ++ "xop", ++ "fma4" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G3", ++ "typename": "Opteron_G3-x86_64-cpu", ++ "unavailable-features": [ ++ "abm", ++ "sse4a", ++ "misalignsse" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G2", ++ "typename": "Opteron_G2-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G1", ++ "typename": "Opteron_G1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Nehalem", ++ "typename": "Nehalem-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Nehalem-IBRS", ++ "typename": "Nehalem-IBRS-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "IvyBridge", ++ "typename": "IvyBridge-x86_64-cpu", ++ "unavailable-features": [ ++ "f16c", ++ "rdrand", ++ "fsgsbase", ++ "smep", ++ "erms" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "IvyBridge-IBRS", ++ "typename": "IvyBridge-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "f16c", ++ "rdrand", ++ "fsgsbase", ++ "smep", ++ "erms" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell", ++ "typename": "Haswell-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "movbe", ++ "f16c", ++ "rdrand", ++ "fsgsbase", ++ "bmi1", ++ "hle", ++ "avx2", ++ "smep", ++ "bmi2", ++ "erms", ++ "invpcid", ++ "rtm", ++ "abm" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-noTSX", ++ "typename": "Haswell-noTSX-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "movbe", ++ "f16c", ++ "rdrand", ++ "fsgsbase", ++ "bmi1", ++ "avx2", ++ "smep", ++ "bmi2", ++ "erms", ++ "invpcid", ++ "abm" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-noTSX-IBRS", ++ "typename": "Haswell-noTSX-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "movbe", ++ "f16c", ++ "rdrand", ++ "fsgsbase", ++ "bmi1", ++ "avx2", ++ "smep", ++ "bmi2", ++ "erms", ++ "invpcid", ++ "abm" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-IBRS", ++ "typename": "Haswell-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "movbe", ++ "f16c", ++ "rdrand", ++ "fsgsbase", ++ "bmi1", ++ "hle", ++ "avx2", ++ "smep", ++ "bmi2", ++ "erms", ++ "invpcid", ++ "rtm", ++ "abm" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "EPYC", ++ "typename": "EPYC-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "movbe", ++ "f16c", ++ "rdrand", ++ "fsgsbase", ++ "bmi1", ++ "avx2", ++ "smep", ++ "bmi2", ++ "rdseed", ++ "adx", ++ "smap", ++ "clflushopt", ++ "sha-ni", ++ "mmxext", ++ "fxsr-opt", ++ "cr8legacy", ++ "abm", ++ "sse4a", ++ "misalignsse", ++ "3dnowprefetch", ++ "osvw", ++ "xsavec", ++ "xgetbv1" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "EPYC-IBPB", ++ "typename": "EPYC-IBPB-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "movbe", ++ "f16c", ++ "rdrand", ++ "fsgsbase", ++ "bmi1", ++ "avx2", ++ "smep", ++ "bmi2", ++ "rdseed", ++ "adx", ++ "smap", ++ "clflushopt", ++ "sha-ni", ++ "mmxext", ++ "fxsr-opt", ++ "cr8legacy", ++ "abm", ++ "sse4a", ++ "misalignsse", ++ "3dnowprefetch", ++ "osvw", ++ "ibpb", ++ "xsavec", ++ "xgetbv1" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Conroe", ++ "typename": "Conroe-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell", ++ "typename": "Broadwell-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "movbe", ++ "f16c", ++ "rdrand", ++ "fsgsbase", ++ "bmi1", ++ "hle", ++ "avx2", ++ "smep", ++ "bmi2", ++ "erms", ++ "invpcid", ++ "rtm", ++ "rdseed", ++ "adx", ++ "smap", ++ "abm", ++ "3dnowprefetch" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-noTSX", ++ "typename": "Broadwell-noTSX-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "movbe", ++ "f16c", ++ "rdrand", ++ "fsgsbase", ++ "bmi1", ++ "avx2", ++ "smep", ++ "bmi2", ++ "erms", ++ "invpcid", ++ "rdseed", ++ "adx", ++ "smap", ++ "abm", ++ "3dnowprefetch" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-noTSX-IBRS", ++ "typename": "Broadwell-noTSX-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "movbe", ++ "f16c", ++ "rdrand", ++ "fsgsbase", ++ "bmi1", ++ "avx2", ++ "smep", ++ "bmi2", ++ "erms", ++ "invpcid", ++ "rdseed", ++ "adx", ++ "smap", ++ "abm", ++ "3dnowprefetch" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-IBRS", ++ "typename": "Broadwell-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "movbe", ++ "f16c", ++ "rdrand", ++ "fsgsbase", ++ "bmi1", ++ "hle", ++ "avx2", ++ "smep", ++ "bmi2", ++ "erms", ++ "invpcid", ++ "rtm", ++ "rdseed", ++ "adx", ++ "smap", ++ "abm", ++ "3dnowprefetch" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "486", ++ "typename": "486-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ } ++ ], ++ "id": "definitions" ++} +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650.xml b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650.xml +new file mode 100644 +index 0000000000..b7ce0631ca +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650.xml +@@ -0,0 +1,34 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +-- +2.22.0 + diff --git a/SOURCES/libvirt-cputest-Add-data-for-Intel-R-Xeon-R-CPU-E7540.patch b/SOURCES/libvirt-cputest-Add-data-for-Intel-R-Xeon-R-CPU-E7540.patch new file mode 100644 index 0000000..cf8ab88 --- /dev/null +++ b/SOURCES/libvirt-cputest-Add-data-for-Intel-R-Xeon-R-CPU-E7540.patch @@ -0,0 +1,1317 @@ +From 50d3fe22f84e93fec523ae24302deac54db1dcfd Mon Sep 17 00:00:00 2001 +Message-Id: <50d3fe22f84e93fec523ae24302deac54db1dcfd@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:24:51 +0200 +Subject: [PATCH] cputest: Add data for Intel(R) Xeon(R) CPU E7540 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 60046a236583a2f19c0ba6e7ab3a2823d20f177e) + +https://bugzilla.redhat.com/show_bug.cgi?id=1686895 + +Signed-off-by: Jiri Denemark +Message-Id: <7d56c795395ebb6b92d8650f5f956f7ddbb98947.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + tests/cputest.c | 1 + + .../x86_64-cpuid-Xeon-E7540-disabled.xml | 5 + + .../x86_64-cpuid-Xeon-E7540-enabled.xml | 7 + + .../x86_64-cpuid-Xeon-E7540-guest.xml | 25 + + .../x86_64-cpuid-Xeon-E7540-host.xml | 26 + + .../x86_64-cpuid-Xeon-E7540-json.xml | 14 + + .../cputestdata/x86_64-cpuid-Xeon-E7540.json | 1117 +++++++++++++++++ + tests/cputestdata/x86_64-cpuid-Xeon-E7540.xml | 30 + + 8 files changed, 1225 insertions(+) + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E7540-disabled.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E7540-enabled.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E7540-guest.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E7540-host.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E7540-json.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E7540.json + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E7540.xml + +diff --git a/tests/cputest.c b/tests/cputest.c +index 28d575a784..e2c7860f3f 100644 +--- a/tests/cputest.c ++++ b/tests/cputest.c +@@ -1202,6 +1202,7 @@ mymain(void) + DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-E7-4820", JSON_HOST); + DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-E7-4830", JSON_MODELS_REQUIRED); + DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-E7-8890-v3", JSON_MODELS); ++ DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-E7540", JSON_MODELS); + DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-Gold-5115", JSON_MODELS); + DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-Gold-6148", JSON_HOST); + DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-W3520", JSON_HOST); +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E7540-disabled.xml b/tests/cputestdata/x86_64-cpuid-Xeon-E7540-disabled.xml +new file mode 100644 +index 0000000000..49737fbdb1 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E7540-disabled.xml +@@ -0,0 +1,5 @@ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E7540-enabled.xml b/tests/cputestdata/x86_64-cpuid-Xeon-E7540-enabled.xml +new file mode 100644 +index 0000000000..8149ac04f0 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E7540-enabled.xml +@@ -0,0 +1,7 @@ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E7540-guest.xml b/tests/cputestdata/x86_64-cpuid-Xeon-E7540-guest.xml +new file mode 100644 +index 0000000000..fc3e95253b +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E7540-guest.xml +@@ -0,0 +1,25 @@ ++ ++ Nehalem-IBRS ++ Intel ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E7540-host.xml b/tests/cputestdata/x86_64-cpuid-Xeon-E7540-host.xml +new file mode 100644 +index 0000000000..42b43116bd +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E7540-host.xml +@@ -0,0 +1,26 @@ ++ ++ x86_64 ++ Nehalem-IBRS ++ Intel ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E7540-json.xml b/tests/cputestdata/x86_64-cpuid-Xeon-E7540-json.xml +new file mode 100644 +index 0000000000..32cd1000c8 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E7540-json.xml +@@ -0,0 +1,14 @@ ++ ++ Nehalem-IBRS ++ Intel ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E7540.json b/tests/cputestdata/x86_64-cpuid-Xeon-E7540.json +new file mode 100644 +index 0000000000..ac8452509d +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E7540.json +@@ -0,0 +1,1117 @@ ++{ ++ "return": { ++ "model": { ++ "name": "base", ++ "props": { ++ "phys-bits": 0, ++ "core-id": -1, ++ "xlevel": 2147483656, ++ "cmov": true, ++ "ia64": false, ++ "aes": false, ++ "mmx": true, ++ "rdpid": false, ++ "arat": true, ++ "gfni": false, ++ "pause-filter": false, ++ "xsavec": false, ++ "intel-pt": false, ++ "osxsave": false, ++ "hv-frequencies": false, ++ "tsc-frequency": 0, ++ "xd": true, ++ "hv-vendor-id": "", ++ "kvm-asyncpf": true, ++ "kvm_asyncpf": true, ++ "perfctr_core": false, ++ "perfctr-core": false, ++ "mpx": false, ++ "pbe": false, ++ "decodeassists": false, ++ "avx512cd": false, ++ "sse4_1": true, ++ "sse4.1": true, ++ "sse4-1": true, ++ "family": 6, ++ "legacy-cache": true, ++ "vmware-cpuid-freq": true, ++ "avx512f": false, ++ "msr": true, ++ "mce": true, ++ "mca": true, ++ "hv-runtime": false, ++ "xcrypt": false, ++ "thread-id": -1, ++ "min-level": 11, ++ "xgetbv1": false, ++ "cid": false, ++ "hv-relaxed": false, ++ "hv-crash": false, ++ "ds": false, ++ "fxsr": true, ++ "xsaveopt": false, ++ "xtpr": false, ++ "avx512vl": false, ++ "avx512-vpopcntdq": false, ++ "phe": false, ++ "extapic": false, ++ "3dnowprefetch": false, ++ "avx512vbmi2": false, ++ "cr8legacy": false, ++ "stibp": true, ++ "cpuid-0xb": true, ++ "xcrypt-en": false, ++ "kvm_pv_eoi": true, ++ "apic-id": 4294967295, ++ "pn": false, ++ "dca": false, ++ "vendor": "GenuineIntel", ++ "pku": false, ++ "smx": false, ++ "cmp_legacy": false, ++ "cmp-legacy": false, ++ "node-id": -1, ++ "avx512-4fmaps": false, ++ "vmcb_clean": false, ++ "vmcb-clean": false, ++ "3dnowext": false, ++ "hle": false, ++ "npt": false, ++ "memory": "/machine/unattached/system[0]", ++ "clwb": false, ++ "lbrv": false, ++ "adx": false, ++ "ss": true, ++ "pni": true, ++ "svm_lock": false, ++ "svm-lock": false, ++ "pfthreshold": false, ++ "smep": false, ++ "smap": false, ++ "x2apic": true, ++ "avx512vbmi": false, ++ "avx512vnni": false, ++ "hv-stimer": false, ++ "i64": true, ++ "flushbyasid": false, ++ "f16c": false, ++ "ace2-en": false, ++ "pat": true, ++ "pae": true, ++ "sse": true, ++ "phe-en": false, ++ "kvm_nopiodelay": true, ++ "kvm-nopiodelay": true, ++ "tm": false, ++ "kvmclock-stable-bit": true, ++ "hypervisor": true, ++ "socket-id": -1, ++ "pcommit": false, ++ "syscall": true, ++ "level": 11, ++ "avx512dq": false, ++ "svm": false, ++ "full-cpuid-auto-level": true, ++ "hv-reset": false, ++ "invtsc": false, ++ "sse3": true, ++ "sse2": true, ++ "ssbd": true, ++ "est": false, ++ "avx512ifma": false, ++ "tm2": false, ++ "kvm-pv-eoi": true, ++ "cx8": true, ++ "kvm_mmu": false, ++ "kvm-mmu": false, ++ "sse4_2": true, ++ "sse4.2": true, ++ "sse4-2": true, ++ "pge": true, ++ "fill-mtrr-mask": true, ++ "avx512bitalg": false, ++ "nodeid_msr": false, ++ "pdcm": false, ++ "movbe": false, ++ "model": 46, ++ "nrip_save": false, ++ "nrip-save": false, ++ "kvm_pv_unhalt": true, ++ "ssse3": true, ++ "sse4a": false, ++ "invpcid": false, ++ "pdpe1gb": false, ++ "tsc-deadline": true, ++ "fma": false, ++ "cx16": true, ++ "de": true, ++ "enforce": false, ++ "stepping": 6, ++ "xsave": false, ++ "clflush": true, ++ "skinit": false, ++ "tsc": true, ++ "tce": false, ++ "fpu": true, ++ "ibs": false, ++ "ds_cpl": false, ++ "ds-cpl": false, ++ "host-phys-bits": true, ++ "fma4": false, ++ "la57": false, ++ "osvw": false, ++ "check": true, ++ "hv-spinlocks": -1, ++ "pmu": false, ++ "pmm": false, ++ "apic": true, ++ "spec-ctrl": true, ++ "min-xlevel2": 0, ++ "tsc-adjust": true, ++ "tsc_adjust": true, ++ "kvm-steal-time": true, ++ "kvm_steal_time": true, ++ "kvmclock": true, ++ "l3-cache": true, ++ "lwp": false, ++ "ibpb": false, ++ "xop": false, ++ "avx": false, ++ "ospke": false, ++ "ace2": false, ++ "avx512bw": false, ++ "acpi": false, ++ "hv-vapic": false, ++ "fsgsbase": false, ++ "ht": false, ++ "nx": true, ++ "pclmulqdq": false, ++ "mmxext": false, ++ "vaes": false, ++ "popcnt": true, ++ "xsaves": false, ++ "tcg-cpuid": true, ++ "lm": true, ++ "umip": false, ++ "pse": true, ++ "avx2": false, ++ "sep": true, ++ "pclmuldq": false, ++ "virt-ssbd": false, ++ "x-hv-max-vps": -1, ++ "nodeid-msr": false, ++ "kvm": true, ++ "misalignsse": false, ++ "min-xlevel": 2147483656, ++ "kvm-pv-unhalt": true, ++ "bmi2": false, ++ "bmi1": false, ++ "realized": false, ++ "tsc_scale": false, ++ "tsc-scale": false, ++ "topoext": false, ++ "hv-vpindex": false, ++ "xlevel2": 0, ++ "clflushopt": false, ++ "kvm-no-smi-migration": false, ++ "monitor": false, ++ "avx512er": false, ++ "pmm-en": false, ++ "pcid": false, ++ "3dnow": false, ++ "erms": false, ++ "lahf-lm": true, ++ "lahf_lm": true, ++ "vpclmulqdq": false, ++ "fxsr-opt": false, ++ "hv-synic": false, ++ "xstore": false, ++ "fxsr_opt": false, ++ "kvm-hint-dedicated": false, ++ "rtm": false, ++ "lmce": true, ++ "hv-time": false, ++ "perfctr-nb": false, ++ "perfctr_nb": false, ++ "ffxsr": false, ++ "rdrand": false, ++ "rdseed": false, ++ "avx512-4vnniw": false, ++ "vmx": false, ++ "vme": true, ++ "dtes64": false, ++ "mtrr": true, ++ "rdtscp": true, ++ "pse36": true, ++ "kvm-pv-tlb-flush": false, ++ "tbm": false, ++ "wdt": false, ++ "pause_filter": false, ++ "sha-ni": false, ++ "model-id": "Intel(R) Xeon(R) CPU E7540 @ 2.00GHz", ++ "abm": false, ++ "avx512pf": false, ++ "xstore-en": false ++ } ++ } ++ }, ++ "id": "model-expansion" ++} ++ ++ ++{ ++ "return": [ ++ { ++ "name": "max", ++ "typename": "max-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": false ++ }, ++ { ++ "name": "host", ++ "typename": "host-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": false ++ }, ++ { ++ "name": "base", ++ "typename": "base-x86_64-cpu", ++ "unavailable-features": [], ++ "static": true, ++ "migration-safe": true ++ }, ++ { ++ "name": "qemu64", ++ "typename": "qemu64-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "qemu32", ++ "typename": "qemu32-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "phenom", ++ "typename": "phenom-x86_64-cpu", ++ "unavailable-features": [ ++ "mmxext", ++ "fxsr-opt", ++ "pdpe1gb", ++ "3dnowext", ++ "3dnow", ++ "abm", ++ "sse4a", ++ "npt" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "pentium3", ++ "typename": "pentium3-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "pentium2", ++ "typename": "pentium2-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "pentium", ++ "typename": "pentium-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "n270", ++ "typename": "n270-x86_64-cpu", ++ "unavailable-features": [ ++ "movbe" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "kvm64", ++ "typename": "kvm64-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "kvm32", ++ "typename": "kvm32-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "cpu64-rhel6", ++ "typename": "cpu64-rhel6-x86_64-cpu", ++ "unavailable-features": [ ++ "abm", ++ "sse4a" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "coreduo", ++ "typename": "coreduo-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "core2duo", ++ "typename": "core2duo-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "athlon", ++ "typename": "athlon-x86_64-cpu", ++ "unavailable-features": [ ++ "mmxext", ++ "3dnowext", ++ "3dnow" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Westmere", ++ "typename": "Westmere-x86_64-cpu", ++ "unavailable-features": [ ++ "pclmulqdq", ++ "aes" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Westmere-IBRS", ++ "typename": "Westmere-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "pclmulqdq", ++ "aes" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Server", ++ "typename": "Skylake-Server-x86_64-cpu", ++ "unavailable-features": [ ++ "pclmulqdq", ++ "fma", ++ "pcid", ++ "movbe", ++ "aes", ++ "xsave", ++ "avx", ++ "f16c", ++ "rdrand", ++ "fsgsbase", ++ "bmi1", ++ "hle", ++ "avx2", ++ "smep", ++ "bmi2", ++ "erms", ++ "invpcid", ++ "rtm", ++ "mpx", ++ "avx512f", ++ "avx512dq", ++ "rdseed", ++ "adx", ++ "smap", ++ "clflushopt", ++ "clwb", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "pdpe1gb", ++ "abm", ++ "3dnowprefetch", ++ "xsaveopt", ++ "xsavec", ++ "xgetbv1", ++ "xsave", ++ "xsave", ++ "avx", ++ "mpx", ++ "mpx", ++ "avx512f", ++ "avx512f", ++ "avx512f" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Server-IBRS", ++ "typename": "Skylake-Server-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "pclmulqdq", ++ "fma", ++ "pcid", ++ "movbe", ++ "aes", ++ "xsave", ++ "avx", ++ "f16c", ++ "rdrand", ++ "fsgsbase", ++ "bmi1", ++ "hle", ++ "avx2", ++ "smep", ++ "bmi2", ++ "erms", ++ "invpcid", ++ "rtm", ++ "mpx", ++ "avx512f", ++ "avx512dq", ++ "rdseed", ++ "adx", ++ "smap", ++ "clwb", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "pdpe1gb", ++ "abm", ++ "3dnowprefetch", ++ "xsaveopt", ++ "xsavec", ++ "xgetbv1", ++ "xsave", ++ "xsave", ++ "avx", ++ "mpx", ++ "mpx", ++ "avx512f", ++ "avx512f", ++ "avx512f" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Client", ++ "typename": "Skylake-Client-x86_64-cpu", ++ "unavailable-features": [ ++ "pclmulqdq", ++ "fma", ++ "pcid", ++ "movbe", ++ "aes", ++ "xsave", ++ "avx", ++ "f16c", ++ "rdrand", ++ "fsgsbase", ++ "bmi1", ++ "hle", ++ "avx2", ++ "smep", ++ "bmi2", ++ "erms", ++ "invpcid", ++ "rtm", ++ "mpx", ++ "rdseed", ++ "adx", ++ "smap", ++ "abm", ++ "3dnowprefetch", ++ "xsaveopt", ++ "xsavec", ++ "xgetbv1", ++ "xsave", ++ "xsave", ++ "avx", ++ "mpx", ++ "mpx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Client-IBRS", ++ "typename": "Skylake-Client-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "pclmulqdq", ++ "fma", ++ "pcid", ++ "movbe", ++ "aes", ++ "xsave", ++ "avx", ++ "f16c", ++ "rdrand", ++ "fsgsbase", ++ "bmi1", ++ "hle", ++ "avx2", ++ "smep", ++ "bmi2", ++ "erms", ++ "invpcid", ++ "rtm", ++ "mpx", ++ "rdseed", ++ "adx", ++ "smap", ++ "abm", ++ "3dnowprefetch", ++ "xsaveopt", ++ "xsavec", ++ "xgetbv1", ++ "xsave", ++ "xsave", ++ "avx", ++ "mpx", ++ "mpx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "SandyBridge", ++ "typename": "SandyBridge-x86_64-cpu", ++ "unavailable-features": [ ++ "pclmulqdq", ++ "aes", ++ "xsave", ++ "avx", ++ "xsaveopt", ++ "xsave", ++ "xsave", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "SandyBridge-IBRS", ++ "typename": "SandyBridge-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "pclmulqdq", ++ "aes", ++ "xsave", ++ "avx", ++ "xsaveopt", ++ "xsave", ++ "xsave", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Penryn", ++ "typename": "Penryn-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G5", ++ "typename": "Opteron_G5-x86_64-cpu", ++ "unavailable-features": [ ++ "pclmulqdq", ++ "fma", ++ "aes", ++ "xsave", ++ "avx", ++ "f16c", ++ "pdpe1gb", ++ "abm", ++ "sse4a", ++ "misalignsse", ++ "3dnowprefetch", ++ "xop", ++ "fma4", ++ "tbm", ++ "xsave", ++ "xsave", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G4", ++ "typename": "Opteron_G4-x86_64-cpu", ++ "unavailable-features": [ ++ "pclmulqdq", ++ "aes", ++ "xsave", ++ "avx", ++ "pdpe1gb", ++ "abm", ++ "sse4a", ++ "misalignsse", ++ "3dnowprefetch", ++ "xop", ++ "fma4", ++ "xsave", ++ "xsave", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G3", ++ "typename": "Opteron_G3-x86_64-cpu", ++ "unavailable-features": [ ++ "abm", ++ "sse4a", ++ "misalignsse" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G2", ++ "typename": "Opteron_G2-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G1", ++ "typename": "Opteron_G1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Nehalem", ++ "typename": "Nehalem-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Nehalem-IBRS", ++ "typename": "Nehalem-IBRS-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "IvyBridge", ++ "typename": "IvyBridge-x86_64-cpu", ++ "unavailable-features": [ ++ "pclmulqdq", ++ "aes", ++ "xsave", ++ "avx", ++ "f16c", ++ "rdrand", ++ "fsgsbase", ++ "smep", ++ "erms", ++ "xsaveopt", ++ "xsave", ++ "xsave", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "IvyBridge-IBRS", ++ "typename": "IvyBridge-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "pclmulqdq", ++ "aes", ++ "xsave", ++ "avx", ++ "f16c", ++ "rdrand", ++ "fsgsbase", ++ "smep", ++ "erms", ++ "xsaveopt", ++ "xsave", ++ "xsave", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell", ++ "typename": "Haswell-x86_64-cpu", ++ "unavailable-features": [ ++ "pclmulqdq", ++ "fma", ++ "pcid", ++ "movbe", ++ "aes", ++ "xsave", ++ "avx", ++ "f16c", ++ "rdrand", ++ "fsgsbase", ++ "bmi1", ++ "hle", ++ "avx2", ++ "smep", ++ "bmi2", ++ "erms", ++ "invpcid", ++ "rtm", ++ "abm", ++ "xsaveopt", ++ "xsave", ++ "xsave", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-noTSX", ++ "typename": "Haswell-noTSX-x86_64-cpu", ++ "unavailable-features": [ ++ "pclmulqdq", ++ "fma", ++ "pcid", ++ "movbe", ++ "aes", ++ "xsave", ++ "avx", ++ "f16c", ++ "rdrand", ++ "fsgsbase", ++ "bmi1", ++ "avx2", ++ "smep", ++ "bmi2", ++ "erms", ++ "invpcid", ++ "abm", ++ "xsaveopt", ++ "xsave", ++ "xsave", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-noTSX-IBRS", ++ "typename": "Haswell-noTSX-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "pclmulqdq", ++ "fma", ++ "pcid", ++ "movbe", ++ "aes", ++ "xsave", ++ "avx", ++ "f16c", ++ "rdrand", ++ "fsgsbase", ++ "bmi1", ++ "avx2", ++ "smep", ++ "bmi2", ++ "erms", ++ "invpcid", ++ "abm", ++ "xsaveopt", ++ "xsave", ++ "xsave", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-IBRS", ++ "typename": "Haswell-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "pclmulqdq", ++ "fma", ++ "pcid", ++ "movbe", ++ "aes", ++ "xsave", ++ "avx", ++ "f16c", ++ "rdrand", ++ "fsgsbase", ++ "bmi1", ++ "hle", ++ "avx2", ++ "smep", ++ "bmi2", ++ "erms", ++ "invpcid", ++ "rtm", ++ "abm", ++ "xsaveopt", ++ "xsave", ++ "xsave", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "EPYC", ++ "typename": "EPYC-x86_64-cpu", ++ "unavailable-features": [ ++ "pclmulqdq", ++ "fma", ++ "movbe", ++ "aes", ++ "xsave", ++ "avx", ++ "f16c", ++ "rdrand", ++ "fsgsbase", ++ "bmi1", ++ "avx2", ++ "smep", ++ "bmi2", ++ "rdseed", ++ "adx", ++ "smap", ++ "clflushopt", ++ "sha-ni", ++ "mmxext", ++ "fxsr-opt", ++ "pdpe1gb", ++ "cr8legacy", ++ "abm", ++ "sse4a", ++ "misalignsse", ++ "3dnowprefetch", ++ "osvw", ++ "xsaveopt", ++ "xsavec", ++ "xgetbv1", ++ "xsave", ++ "xsave", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "EPYC-IBPB", ++ "typename": "EPYC-IBPB-x86_64-cpu", ++ "unavailable-features": [ ++ "pclmulqdq", ++ "fma", ++ "movbe", ++ "aes", ++ "xsave", ++ "avx", ++ "f16c", ++ "rdrand", ++ "fsgsbase", ++ "bmi1", ++ "avx2", ++ "smep", ++ "bmi2", ++ "rdseed", ++ "adx", ++ "smap", ++ "clflushopt", ++ "sha-ni", ++ "mmxext", ++ "fxsr-opt", ++ "pdpe1gb", ++ "cr8legacy", ++ "abm", ++ "sse4a", ++ "misalignsse", ++ "3dnowprefetch", ++ "osvw", ++ "ibpb", ++ "xsaveopt", ++ "xsavec", ++ "xgetbv1", ++ "xsave", ++ "xsave", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Conroe", ++ "typename": "Conroe-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell", ++ "typename": "Broadwell-x86_64-cpu", ++ "unavailable-features": [ ++ "pclmulqdq", ++ "fma", ++ "pcid", ++ "movbe", ++ "aes", ++ "xsave", ++ "avx", ++ "f16c", ++ "rdrand", ++ "fsgsbase", ++ "bmi1", ++ "hle", ++ "avx2", ++ "smep", ++ "bmi2", ++ "erms", ++ "invpcid", ++ "rtm", ++ "rdseed", ++ "adx", ++ "smap", ++ "abm", ++ "3dnowprefetch", ++ "xsaveopt", ++ "xsave", ++ "xsave", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-noTSX", ++ "typename": "Broadwell-noTSX-x86_64-cpu", ++ "unavailable-features": [ ++ "pclmulqdq", ++ "fma", ++ "pcid", ++ "movbe", ++ "aes", ++ "xsave", ++ "avx", ++ "f16c", ++ "rdrand", ++ "fsgsbase", ++ "bmi1", ++ "avx2", ++ "smep", ++ "bmi2", ++ "erms", ++ "invpcid", ++ "rdseed", ++ "adx", ++ "smap", ++ "abm", ++ "3dnowprefetch", ++ "xsaveopt", ++ "xsave", ++ "xsave", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-noTSX-IBRS", ++ "typename": "Broadwell-noTSX-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "pclmulqdq", ++ "fma", ++ "pcid", ++ "movbe", ++ "aes", ++ "xsave", ++ "avx", ++ "f16c", ++ "rdrand", ++ "fsgsbase", ++ "bmi1", ++ "avx2", ++ "smep", ++ "bmi2", ++ "erms", ++ "invpcid", ++ "rdseed", ++ "adx", ++ "smap", ++ "abm", ++ "3dnowprefetch", ++ "xsaveopt", ++ "xsave", ++ "xsave", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-IBRS", ++ "typename": "Broadwell-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "pclmulqdq", ++ "fma", ++ "pcid", ++ "movbe", ++ "aes", ++ "xsave", ++ "avx", ++ "f16c", ++ "rdrand", ++ "fsgsbase", ++ "bmi1", ++ "hle", ++ "avx2", ++ "smep", ++ "bmi2", ++ "erms", ++ "invpcid", ++ "rtm", ++ "rdseed", ++ "adx", ++ "smap", ++ "abm", ++ "3dnowprefetch", ++ "xsaveopt", ++ "xsave", ++ "xsave", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "486", ++ "typename": "486-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ } ++ ], ++ "id": "definitions" ++} +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E7540.xml b/tests/cputestdata/x86_64-cpuid-Xeon-E7540.xml +new file mode 100644 +index 0000000000..e80694b5e0 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E7540.xml +@@ -0,0 +1,30 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +-- +2.22.0 + diff --git a/SOURCES/libvirt-cputest-Add-data-for-Intel-R-Xeon-R-Platinum-8268-CPU.patch b/SOURCES/libvirt-cputest-Add-data-for-Intel-R-Xeon-R-Platinum-8268-CPU.patch new file mode 100644 index 0000000..97de9d0 --- /dev/null +++ b/SOURCES/libvirt-cputest-Add-data-for-Intel-R-Xeon-R-Platinum-8268-CPU.patch @@ -0,0 +1,968 @@ +From 5a7f0fd05ad3c86dd8f8be7870bd536de2512baa Mon Sep 17 00:00:00 2001 +Message-Id: <5a7f0fd05ad3c86dd8f8be7870bd536de2512baa@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:20 +0200 +Subject: [PATCH] cputest: Add data for Intel(R) Xeon(R) Platinum 8268 CPU +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit e024625735daec9f9f0bc292f06e37d7099805f1) + +https://bugzilla.redhat.com/show_bug.cgi?id=1693433 + +Conflicts: + tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-guest.xml + tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-host.xml + - md-clear feature did not exist at the time of the original + patch, but downstream already has it + +Signed-off-by: Jiri Denemark +Message-Id: <809df143b79b1052ce3e643d9b97926b5bdd7001.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + tests/cputest.c | 1 + + ...6_64-cpuid-Xeon-Platinum-8268-disabled.xml | 7 + + ...86_64-cpuid-Xeon-Platinum-8268-enabled.xml | 8 + + .../x86_64-cpuid-Xeon-Platinum-8268-guest.xml | 36 + + .../x86_64-cpuid-Xeon-Platinum-8268-host.xml | 37 + + .../x86_64-cpuid-Xeon-Platinum-8268-json.xml | 13 + + .../x86_64-cpuid-Xeon-Platinum-8268.json | 702 ++++++++++++++++++ + .../x86_64-cpuid-Xeon-Platinum-8268.sig | 4 + + .../x86_64-cpuid-Xeon-Platinum-8268.xml | 54 ++ + 9 files changed, 862 insertions(+) + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-disabled.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-enabled.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-guest.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-host.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-json.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268.json + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268.xml + +diff --git a/tests/cputest.c b/tests/cputest.c +index 0cb9a57592..e62cda34b7 100644 +--- a/tests/cputest.c ++++ b/tests/cputest.c +@@ -1293,6 +1293,7 @@ mymain(void) + DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-E7540", JSON_MODELS); + DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-Gold-5115", JSON_MODELS); + DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-Gold-6148", JSON_HOST); ++ DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-Platinum-8268", JSON_HOST); + DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-W3520", JSON_HOST); + DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-X5460", JSON_NONE); + +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-disabled.xml b/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-disabled.xml +new file mode 100644 +index 0000000000..32522eb9af +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-disabled.xml +@@ -0,0 +1,7 @@ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-enabled.xml b/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-enabled.xml +new file mode 100644 +index 0000000000..434ac1956a +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-enabled.xml +@@ -0,0 +1,8 @@ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-guest.xml b/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-guest.xml +new file mode 100644 +index 0000000000..2836481454 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-guest.xml +@@ -0,0 +1,36 @@ ++ ++ Skylake-Server-IBRS ++ Intel ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-host.xml b/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-host.xml +new file mode 100644 +index 0000000000..032d8ffeca +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-host.xml +@@ -0,0 +1,37 @@ ++ ++ x86_64 ++ Skylake-Server-IBRS ++ Intel ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-json.xml b/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-json.xml +new file mode 100644 +index 0000000000..12431de213 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268-json.xml +@@ -0,0 +1,13 @@ ++ ++ Skylake-Server-IBRS ++ Intel ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268.json b/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268.json +new file mode 100644 +index 0000000000..71451f893d +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268.json +@@ -0,0 +1,702 @@ ++{ ++ "return": { ++ "model": { ++ "name": "base", ++ "props": { ++ "phys-bits": 0, ++ "core-id": -1, ++ "xlevel": 2147483656, ++ "cmov": true, ++ "ia64": false, ++ "ssb-no": false, ++ "aes": true, ++ "mmx": true, ++ "rdpid": false, ++ "arat": true, ++ "gfni": false, ++ "ibrs-all": true, ++ "pause-filter": false, ++ "xsavec": true, ++ "intel-pt": false, ++ "hv-frequencies": false, ++ "tsc-frequency": 0, ++ "xd": true, ++ "hv-vendor-id": "", ++ "kvm-asyncpf": true, ++ "kvm_asyncpf": true, ++ "perfctr_core": false, ++ "perfctr-core": false, ++ "mpx": true, ++ "pbe": false, ++ "decodeassists": false, ++ "avx512cd": true, ++ "sse4_1": true, ++ "sse4.1": true, ++ "sse4-1": true, ++ "family": 6, ++ "legacy-cache": true, ++ "vmware-cpuid-freq": true, ++ "wbnoinvd": false, ++ "avx512f": true, ++ "msr": true, ++ "mce": true, ++ "mca": true, ++ "hv-runtime": false, ++ "xcrypt": false, ++ "thread-id": -1, ++ "min-level": 13, ++ "xgetbv1": true, ++ "cid": false, ++ "hv-relaxed": false, ++ "hv-crash": false, ++ "ds": false, ++ "fxsr": true, ++ "xsaveopt": true, ++ "xtpr": false, ++ "hv-evmcs": false, ++ "avx512vl": true, ++ "avx512-vpopcntdq": false, ++ "phe": false, ++ "extapic": false, ++ "3dnowprefetch": true, ++ "avx512vbmi2": false, ++ "cr8legacy": false, ++ "cpuid-0xb": true, ++ "xcrypt-en": false, ++ "kvm_pv_eoi": true, ++ "apic-id": 4294967295, ++ "rsba": false, ++ "pn": false, ++ "dca": false, ++ "vendor": "GenuineIntel", ++ "hv-ipi": false, ++ "pku": true, ++ "smx": false, ++ "cmp_legacy": false, ++ "cmp-legacy": false, ++ "node-id": -1, ++ "avx512-4fmaps": false, ++ "vmcb_clean": false, ++ "vmcb-clean": false, ++ "3dnowext": false, ++ "amd-no-ssb": false, ++ "hle": true, ++ "npt": false, ++ "rdctl-no": true, ++ "memory": "/machine/unattached/system[0]", ++ "clwb": true, ++ "lbrv": false, ++ "adx": true, ++ "ss": true, ++ "pni": true, ++ "svm_lock": false, ++ "svm-lock": false, ++ "pfthreshold": false, ++ "smep": true, ++ "smap": true, ++ "x2apic": true, ++ "avx512vbmi": false, ++ "avx512vnni": true, ++ "hv-stimer": false, ++ "x-hv-synic-kvm-only": true, ++ "i64": true, ++ "flushbyasid": false, ++ "f16c": true, ++ "ace2-en": false, ++ "pat": true, ++ "pae": true, ++ "sse": true, ++ "phe-en": false, ++ "kvm_nopiodelay": true, ++ "kvm-nopiodelay": true, ++ "tm": false, ++ "kvmclock-stable-bit": true, ++ "hypervisor": true, ++ "socket-id": -1, ++ "pcommit": false, ++ "syscall": true, ++ "level": 13, ++ "avx512dq": true, ++ "x-migrate-smi-count": false, ++ "svm": false, ++ "full-cpuid-auto-level": true, ++ "hv-reset": false, ++ "invtsc": false, ++ "sse3": true, ++ "sse2": true, ++ "ssbd": true, ++ "est": false, ++ "avx512ifma": false, ++ "tm2": false, ++ "kvm-pv-ipi": true, ++ "kvm-pv-eoi": true, ++ "cx8": true, ++ "cldemote": false, ++ "hv-reenlightenment": false, ++ "kvm_mmu": false, ++ "kvm-mmu": false, ++ "sse4_2": true, ++ "sse4.2": true, ++ "sse4-2": true, ++ "pge": true, ++ "fill-mtrr-mask": true, ++ "avx512bitalg": false, ++ "nodeid_msr": false, ++ "pdcm": false, ++ "movbe": true, ++ "model": 85, ++ "nrip_save": false, ++ "nrip-save": false, ++ "kvm_pv_unhalt": true, ++ "ssse3": true, ++ "sse4a": false, ++ "invpcid": true, ++ "pdpe1gb": true, ++ "tsc-deadline": true, ++ "skip-l1dfl-vmentry": true, ++ "fma": true, ++ "cx16": true, ++ "de": true, ++ "enforce": false, ++ "stepping": 6, ++ "xsave": true, ++ "clflush": true, ++ "skinit": false, ++ "tsc": true, ++ "tce": false, ++ "fpu": true, ++ "ibs": false, ++ "ds_cpl": false, ++ "ds-cpl": false, ++ "host-phys-bits": true, ++ "fma4": false, ++ "la57": false, ++ "osvw": false, ++ "check": true, ++ "hv-spinlocks": -1, ++ "pmu": false, ++ "pmm": false, ++ "apic": true, ++ "spec-ctrl": true, ++ "min-xlevel2": 0, ++ "tsc-adjust": true, ++ "tsc_adjust": true, ++ "kvm-steal-time": true, ++ "kvm_steal_time": true, ++ "kvmclock": true, ++ "l3-cache": true, ++ "lwp": false, ++ "amd-ssbd": false, ++ "ibpb": false, ++ "xop": false, ++ "avx": true, ++ "ace2": false, ++ "avx512bw": true, ++ "acpi": false, ++ "hv-vapic": false, ++ "fsgsbase": true, ++ "ht": false, ++ "nx": true, ++ "pclmulqdq": true, ++ "mmxext": false, ++ "vaes": false, ++ "popcnt": true, ++ "xsaves": true, ++ "tcg-cpuid": true, ++ "lm": true, ++ "umip": true, ++ "pse": true, ++ "avx2": true, ++ "sep": true, ++ "pclmuldq": true, ++ "virt-ssbd": false, ++ "x-hv-max-vps": -1, ++ "nodeid-msr": false, ++ "kvm": true, ++ "misalignsse": false, ++ "min-xlevel": 2147483656, ++ "kvm-pv-unhalt": true, ++ "bmi2": true, ++ "bmi1": true, ++ "realized": false, ++ "tsc_scale": false, ++ "tsc-scale": false, ++ "topoext": false, ++ "hv-vpindex": false, ++ "xlevel2": 0, ++ "clflushopt": true, ++ "kvm-no-smi-migration": false, ++ "monitor": false, ++ "avx512er": false, ++ "pmm-en": false, ++ "pcid": true, ++ "arch-capabilities": false, ++ "3dnow": false, ++ "erms": true, ++ "lahf-lm": true, ++ "lahf_lm": true, ++ "vpclmulqdq": false, ++ "fxsr-opt": false, ++ "hv-synic": false, ++ "xstore": false, ++ "fxsr_opt": false, ++ "kvm-hint-dedicated": false, ++ "rtm": true, ++ "lmce": true, ++ "hv-time": false, ++ "perfctr-nb": false, ++ "perfctr_nb": false, ++ "ffxsr": false, ++ "hv-tlbflush": false, ++ "rdrand": true, ++ "rdseed": true, ++ "avx512-4vnniw": false, ++ "vmx": false, ++ "vme": true, ++ "dtes64": false, ++ "mtrr": true, ++ "rdtscp": true, ++ "pse36": true, ++ "kvm-pv-tlb-flush": true, ++ "tbm": false, ++ "wdt": false, ++ "pause_filter": false, ++ "sha-ni": false, ++ "model-id": "Intel(R) Xeon(R) Platinum 8268 CPU @ 2.90GHz", ++ "abm": true, ++ "avx512pf": false, ++ "xstore-en": false ++ } ++ } ++ }, ++ "id": "model-expansion" ++} ++ ++{ ++ "return": [ ++ { ++ "name": "max", ++ "typename": "max-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": false ++ }, ++ { ++ "name": "host", ++ "typename": "host-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": false ++ }, ++ { ++ "name": "base", ++ "typename": "base-x86_64-cpu", ++ "unavailable-features": [], ++ "static": true, ++ "migration-safe": true ++ }, ++ { ++ "name": "qemu64", ++ "typename": "qemu64-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "qemu32", ++ "typename": "qemu32-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "phenom", ++ "typename": "phenom-x86_64-cpu", ++ "unavailable-features": [ ++ "mmxext", ++ "fxsr-opt", ++ "3dnowext", ++ "3dnow", ++ "sse4a", ++ "npt" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "pentium3", ++ "typename": "pentium3-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "pentium2", ++ "typename": "pentium2-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "pentium", ++ "typename": "pentium-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "n270", ++ "typename": "n270-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "kvm64", ++ "typename": "kvm64-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "kvm32", ++ "typename": "kvm32-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "cpu64-rhel6", ++ "typename": "cpu64-rhel6-x86_64-cpu", ++ "unavailable-features": [ ++ "sse4a" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "coreduo", ++ "typename": "coreduo-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "core2duo", ++ "typename": "core2duo-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "athlon", ++ "typename": "athlon-x86_64-cpu", ++ "unavailable-features": [ ++ "mmxext", ++ "3dnowext", ++ "3dnow" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Westmere-IBRS", ++ "typename": "Westmere-IBRS-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Westmere", ++ "typename": "Westmere-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Server-IBRS", ++ "typename": "Skylake-Server-IBRS-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Server", ++ "typename": "Skylake-Server-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Client-IBRS", ++ "typename": "Skylake-Client-IBRS-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Client", ++ "typename": "Skylake-Client-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "SandyBridge-IBRS", ++ "typename": "SandyBridge-IBRS-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "SandyBridge", ++ "typename": "SandyBridge-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Penryn", ++ "typename": "Penryn-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G5", ++ "typename": "Opteron_G5-x86_64-cpu", ++ "unavailable-features": [ ++ "sse4a", ++ "misalignsse", ++ "xop", ++ "fma4", ++ "tbm" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G4", ++ "typename": "Opteron_G4-x86_64-cpu", ++ "unavailable-features": [ ++ "sse4a", ++ "misalignsse", ++ "xop", ++ "fma4" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G3", ++ "typename": "Opteron_G3-x86_64-cpu", ++ "unavailable-features": [ ++ "sse4a", ++ "misalignsse" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G2", ++ "typename": "Opteron_G2-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G1", ++ "typename": "Opteron_G1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Nehalem-IBRS", ++ "typename": "Nehalem-IBRS-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Nehalem", ++ "typename": "Nehalem-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "KnightsMill", ++ "typename": "KnightsMill-x86_64-cpu", ++ "unavailable-features": [ ++ "avx512pf", ++ "avx512er", ++ "avx512-vpopcntdq", ++ "avx512-4vnniw", ++ "avx512-4fmaps" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "IvyBridge-IBRS", ++ "typename": "IvyBridge-IBRS-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "IvyBridge", ++ "typename": "IvyBridge-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Icelake-Server", ++ "typename": "Icelake-Server-x86_64-cpu", ++ "unavailable-features": [ ++ "avx512vbmi", ++ "", ++ "avx512vbmi2", ++ "gfni", ++ "vaes", ++ "vpclmulqdq", ++ "avx512bitalg", ++ "avx512-vpopcntdq", ++ "la57", ++ "wbnoinvd" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Icelake-Client", ++ "typename": "Icelake-Client-x86_64-cpu", ++ "unavailable-features": [ ++ "avx512vbmi", ++ "", ++ "avx512vbmi2", ++ "gfni", ++ "vaes", ++ "vpclmulqdq", ++ "avx512bitalg", ++ "avx512-vpopcntdq", ++ "wbnoinvd" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-noTSX-IBRS", ++ "typename": "Haswell-noTSX-IBRS-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-noTSX", ++ "typename": "Haswell-noTSX-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-IBRS", ++ "typename": "Haswell-IBRS-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell", ++ "typename": "Haswell-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "EPYC-IBPB", ++ "typename": "EPYC-IBPB-x86_64-cpu", ++ "unavailable-features": [ ++ "sha-ni", ++ "mmxext", ++ "fxsr-opt", ++ "cr8legacy", ++ "sse4a", ++ "misalignsse", ++ "osvw", ++ "ibpb" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "EPYC", ++ "typename": "EPYC-x86_64-cpu", ++ "unavailable-features": [ ++ "sha-ni", ++ "mmxext", ++ "fxsr-opt", ++ "cr8legacy", ++ "sse4a", ++ "misalignsse", ++ "osvw" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Conroe", ++ "typename": "Conroe-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Cascadelake-Server", ++ "typename": "Cascadelake-Server-x86_64-cpu", ++ "unavailable-features": [ ++ "" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-noTSX-IBRS", ++ "typename": "Broadwell-noTSX-IBRS-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-noTSX", ++ "typename": "Broadwell-noTSX-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-IBRS", ++ "typename": "Broadwell-IBRS-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell", ++ "typename": "Broadwell-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "486", ++ "typename": "486-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ } ++ ], ++ "id": "definitions" ++} +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268.sig b/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268.sig +new file mode 100644 +index 0000000000..018161ff52 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268.sig +@@ -0,0 +1,4 @@ ++050656 ++family: 6 (0x06) ++model: 85 (0x55) ++stepping: 6 (0x06) +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268.xml b/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268.xml +new file mode 100644 +index 0000000000..75472d44fe +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268.xml +@@ -0,0 +1,54 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +-- +2.22.0 + diff --git a/SOURCES/libvirt-cputest-Add-support-for-MSR-features-to-cpu-parse.sh.patch b/SOURCES/libvirt-cputest-Add-support-for-MSR-features-to-cpu-parse.sh.patch new file mode 100644 index 0000000..0fae604 --- /dev/null +++ b/SOURCES/libvirt-cputest-Add-support-for-MSR-features-to-cpu-parse.sh.patch @@ -0,0 +1,41 @@ +From 7084115edc91fd3cff8ba35af1fc705c917973cf Mon Sep 17 00:00:00 2001 +Message-Id: <7084115edc91fd3cff8ba35af1fc705c917973cf@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:41 +0200 +Subject: [PATCH] cputest: Add support for MSR features to cpu-parse.sh +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The script just parses whatever cpu-gather.sh printed out. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 8904492e21537f3b820e577964e67ad670fa640b) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Conflicts: + tests/cputestdata/cpu-parse.sh + - no need to update this script downstream + +Signed-off-by: Jiri Denemark +Message-Id: <55c3125aef5a2d7bf7b2d7a6fc5c868af7903447.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268.xml | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268.xml b/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268.xml +index 75472d44fe..f1261da891 100644 +--- a/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268.xml ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-Platinum-8268.xml +@@ -51,4 +51,5 @@ + + + ++ + +-- +2.22.0 + diff --git a/SOURCES/libvirt-cputest-Test-CPU-signatures.patch b/SOURCES/libvirt-cputest-Test-CPU-signatures.patch new file mode 100644 index 0000000..a1923a3 --- /dev/null +++ b/SOURCES/libvirt-cputest-Test-CPU-signatures.patch @@ -0,0 +1,755 @@ +From 58b7dda3dda6a768f465f2b8782ef665bd0d7f72 Mon Sep 17 00:00:00 2001 +Message-Id: <58b7dda3dda6a768f465f2b8782ef665bd0d7f72@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:08 +0200 +Subject: [PATCH] cputest: Test CPU signatures +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The signature computation code is not too complicated and it will likely +never change so testing it is not very important. We do it mostly for a +nice side effect of easily accessible signature numbers for all CPU +data files. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit dd08d27fc205c86961b6d957fbb92da5aead5d1b) + +https://bugzilla.redhat.com/show_bug.cgi?id=1686895 + +Signed-off-by: Jiri Denemark +Message-Id: <24fc3fddd709251f12a12589605c76634af8fb1b.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + tests/cputest.c | 86 +++++++++++++++++++ + tests/cputestdata/x86_64-cpuid-A10-5800K.sig | 4 + + tests/cputestdata/x86_64-cpuid-Atom-D510.sig | 4 + + tests/cputestdata/x86_64-cpuid-Atom-N450.sig | 4 + + .../cputestdata/x86_64-cpuid-Core-i5-2500.sig | 4 + + .../x86_64-cpuid-Core-i5-2540M.sig | 4 + + .../x86_64-cpuid-Core-i5-4670T.sig | 4 + + .../cputestdata/x86_64-cpuid-Core-i5-650.sig | 4 + + .../cputestdata/x86_64-cpuid-Core-i5-6600.sig | 4 + + .../x86_64-cpuid-Core-i7-2600-xsaveopt.sig | 4 + + .../cputestdata/x86_64-cpuid-Core-i7-2600.sig | 4 + + .../x86_64-cpuid-Core-i7-3520M.sig | 4 + + .../x86_64-cpuid-Core-i7-3740QM.sig | 4 + + .../cputestdata/x86_64-cpuid-Core-i7-3770.sig | 4 + + .../x86_64-cpuid-Core-i7-4510U.sig | 4 + + .../x86_64-cpuid-Core-i7-4600U.sig | 4 + + .../x86_64-cpuid-Core-i7-5600U-arat.sig | 4 + + .../x86_64-cpuid-Core-i7-5600U-ibrs.sig | 4 + + .../x86_64-cpuid-Core-i7-5600U.sig | 4 + + .../x86_64-cpuid-Core-i7-7600U.sig | 4 + + .../cputestdata/x86_64-cpuid-Core-i7-7700.sig | 4 + + .../cputestdata/x86_64-cpuid-Core-i7-8700.sig | 4 + + .../cputestdata/x86_64-cpuid-Core2-E6850.sig | 4 + + .../cputestdata/x86_64-cpuid-Core2-Q9500.sig | 4 + + .../x86_64-cpuid-EPYC-7601-32-Core-ibpb.sig | 4 + + .../x86_64-cpuid-EPYC-7601-32-Core.sig | 4 + + tests/cputestdata/x86_64-cpuid-FX-8150.sig | 4 + + .../cputestdata/x86_64-cpuid-Opteron-1352.sig | 4 + + .../cputestdata/x86_64-cpuid-Opteron-2350.sig | 4 + + .../cputestdata/x86_64-cpuid-Opteron-6234.sig | 4 + + .../cputestdata/x86_64-cpuid-Opteron-6282.sig | 4 + + .../x86_64-cpuid-Pentium-P6100.sig | 4 + + tests/cputestdata/x86_64-cpuid-Phenom-B95.sig | 4 + + .../x86_64-cpuid-Ryzen-7-1800X-Eight-Core.sig | 4 + + tests/cputestdata/x86_64-cpuid-Xeon-5110.sig | 4 + + .../x86_64-cpuid-Xeon-E3-1245-v5.sig | 4 + + .../x86_64-cpuid-Xeon-E5-2609-v3.sig | 4 + + .../x86_64-cpuid-Xeon-E5-2623-v4.sig | 4 + + .../x86_64-cpuid-Xeon-E5-2630-v3.sig | 4 + + .../x86_64-cpuid-Xeon-E5-2630-v4.sig | 4 + + .../x86_64-cpuid-Xeon-E5-2650-v3.sig | 4 + + .../x86_64-cpuid-Xeon-E5-2650-v4.sig | 4 + + .../cputestdata/x86_64-cpuid-Xeon-E5-2650.sig | 4 + + .../cputestdata/x86_64-cpuid-Xeon-E7-4820.sig | 4 + + .../cputestdata/x86_64-cpuid-Xeon-E7-4830.sig | 4 + + .../x86_64-cpuid-Xeon-E7-8890-v3.sig | 4 + + tests/cputestdata/x86_64-cpuid-Xeon-E7540.sig | 4 + + .../x86_64-cpuid-Xeon-Gold-5115.sig | 4 + + .../x86_64-cpuid-Xeon-Gold-6148.sig | 4 + + tests/cputestdata/x86_64-cpuid-Xeon-W3520.sig | 4 + + tests/cputestdata/x86_64-cpuid-Xeon-X5460.sig | 4 + + 51 files changed, 286 insertions(+) + create mode 100644 tests/cputestdata/x86_64-cpuid-A10-5800K.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Atom-D510.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Atom-N450.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i5-2500.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i5-2540M.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i5-4670T.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i5-650.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i5-6600.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-2600-xsaveopt.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-2600.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-3520M.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-3740QM.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-3770.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-4510U.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-4600U.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-5600U-arat.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-5600U-ibrs.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-5600U.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-7600U.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-7700.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-8700.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Core2-E6850.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Core2-Q9500.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-FX-8150.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Opteron-1352.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Opteron-2350.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Opteron-6234.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Opteron-6282.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Pentium-P6100.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Phenom-B95.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-5110.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E3-1245-v5.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2609-v3.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2623-v4.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v3.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-v3.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-v4.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2650.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E7-4820.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E7-4830.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E7-8890-v3.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E7540.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-Gold-5115.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-Gold-6148.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-W3520.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-X5460.sig + +diff --git a/tests/cputest.c b/tests/cputest.c +index 9e5f807823..0cb9a57592 100644 +--- a/tests/cputest.c ++++ b/tests/cputest.c +@@ -37,6 +37,7 @@ + #include "testutils.h" + #include "cpu_conf.h" + #include "cpu/cpu.h" ++#include "cpu/cpu_x86.h" + #include "cpu/cpu_map.h" + #include "virstring.h" + +@@ -648,6 +649,62 @@ cpuTestGuestCPUID(const void *arg) + } + + ++static int ++cpuTestCompareSignature(const struct data *data, ++ virCPUDataPtr hostData) ++{ ++ VIR_AUTOFREE(char *) result = NULL; ++ VIR_AUTOFREE(char *) sigStr = NULL; ++ unsigned long signature; ++ unsigned int family; ++ unsigned int model; ++ unsigned int stepping; ++ ++ signature = virCPUx86DataGetSignature(hostData, &family, &model, &stepping); ++ ++ if (virAsprintf(&result, "%s/cputestdata/%s-cpuid-%s.sig", ++ abs_srcdir, virArchToString(data->arch), data->host) < 0) ++ return -1; ++ ++ if (virAsprintf(&sigStr, ++ "%1$06lx\n" ++ "family: %2$3u (0x%2$02x)\n" ++ "model: %3$3u (0x%3$02x)\n" ++ "stepping: %4$3u (0x%4$02x)\n", ++ signature, family, model, stepping) < 0) ++ return -1; ++ ++ return virTestCompareToFile(sigStr, result); ++} ++ ++ ++static int ++cpuTestCPUIDSignature(const void *arg) ++{ ++ const struct data *data = arg; ++ virCPUDataPtr hostData = NULL; ++ char *hostFile = NULL; ++ char *host = NULL; ++ int ret = -1; ++ ++ if (virAsprintf(&hostFile, "%s/cputestdata/%s-cpuid-%s.xml", ++ abs_srcdir, virArchToString(data->arch), data->host) < 0) ++ goto cleanup; ++ ++ if (virTestLoadFile(hostFile, &host) < 0 || ++ !(hostData = virCPUDataParse(host))) ++ goto cleanup; ++ ++ ret = cpuTestCompareSignature(data, hostData); ++ ++ cleanup: ++ virCPUDataFree(hostData); ++ VIR_FREE(hostFile); ++ VIR_FREE(host); ++ return ret; ++} ++ ++ + static int + cpuTestUpdateLiveCompare(virArch arch, + virCPUDefPtr actual, +@@ -869,6 +926,31 @@ cpuTestJSONCPUID(const void *arg) + VIR_FREE(result); + return ret; + } ++ ++ ++static int ++cpuTestJSONSignature(const void *arg) ++{ ++ const struct data *data = arg; ++ virQEMUCapsPtr qemuCaps = NULL; ++ virCPUDataPtr hostData = NULL; ++ qemuMonitorCPUModelInfoPtr modelInfo; ++ int ret = -1; ++ ++ if (!(qemuCaps = cpuTestMakeQEMUCaps(data))) ++ goto cleanup; ++ ++ modelInfo = virQEMUCapsGetCPUModelInfo(qemuCaps, VIR_DOMAIN_VIRT_KVM); ++ if (!(hostData = virQEMUCapsGetCPUModelX86Data(modelInfo, false))) ++ goto cleanup; ++ ++ ret = cpuTestCompareSignature(data, hostData); ++ ++ cleanup: ++ virObjectUnref(qemuCaps); ++ virCPUDataFree(hostData); ++ return ret; ++} + #endif + + +@@ -1014,6 +1096,8 @@ mymain(void) + if (json != JSON_NONE) { \ + DO_TEST(arch, cpuTestJSONCPUID, host, host, \ + NULL, NULL, json, 0); \ ++ DO_TEST(arch, cpuTestJSONSignature, host, host, \ ++ NULL, NULL, 0, 0); \ + } \ + } while (0) + #else +@@ -1026,6 +1110,8 @@ mymain(void) + NULL, NULL, 0, 0); \ + DO_TEST(arch, cpuTestGuestCPUID, host, host, \ + NULL, NULL, json, 0); \ ++ DO_TEST(arch, cpuTestCPUIDSignature, host, host, \ ++ NULL, NULL, 0, 0); \ + DO_TEST_JSON(arch, host, json); \ + if (json != JSON_NONE) { \ + DO_TEST(arch, cpuTestUpdateLive, host, host, \ +diff --git a/tests/cputestdata/x86_64-cpuid-A10-5800K.sig b/tests/cputestdata/x86_64-cpuid-A10-5800K.sig +new file mode 100644 +index 0000000000..8045eda561 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-A10-5800K.sig +@@ -0,0 +1,4 @@ ++610f01 ++family: 21 (0x15) ++model: 16 (0x10) ++stepping: 1 (0x01) +diff --git a/tests/cputestdata/x86_64-cpuid-Atom-D510.sig b/tests/cputestdata/x86_64-cpuid-Atom-D510.sig +new file mode 100644 +index 0000000000..d22d28ff8a +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Atom-D510.sig +@@ -0,0 +1,4 @@ ++0106ca ++family: 6 (0x06) ++model: 28 (0x1c) ++stepping: 10 (0x0a) +diff --git a/tests/cputestdata/x86_64-cpuid-Atom-N450.sig b/tests/cputestdata/x86_64-cpuid-Atom-N450.sig +new file mode 100644 +index 0000000000..d22d28ff8a +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Atom-N450.sig +@@ -0,0 +1,4 @@ ++0106ca ++family: 6 (0x06) ++model: 28 (0x1c) ++stepping: 10 (0x0a) +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i5-2500.sig b/tests/cputestdata/x86_64-cpuid-Core-i5-2500.sig +new file mode 100644 +index 0000000000..9b113c3798 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Core-i5-2500.sig +@@ -0,0 +1,4 @@ ++0206a7 ++family: 6 (0x06) ++model: 42 (0x2a) ++stepping: 7 (0x07) +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i5-2540M.sig b/tests/cputestdata/x86_64-cpuid-Core-i5-2540M.sig +new file mode 100644 +index 0000000000..9b113c3798 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Core-i5-2540M.sig +@@ -0,0 +1,4 @@ ++0206a7 ++family: 6 (0x06) ++model: 42 (0x2a) ++stepping: 7 (0x07) +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i5-4670T.sig b/tests/cputestdata/x86_64-cpuid-Core-i5-4670T.sig +new file mode 100644 +index 0000000000..e2fb6c5dd2 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Core-i5-4670T.sig +@@ -0,0 +1,4 @@ ++0306c3 ++family: 6 (0x06) ++model: 60 (0x3c) ++stepping: 3 (0x03) +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i5-650.sig b/tests/cputestdata/x86_64-cpuid-Core-i5-650.sig +new file mode 100644 +index 0000000000..fc7c566de5 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Core-i5-650.sig +@@ -0,0 +1,4 @@ ++020652 ++family: 6 (0x06) ++model: 37 (0x25) ++stepping: 2 (0x02) +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i5-6600.sig b/tests/cputestdata/x86_64-cpuid-Core-i5-6600.sig +new file mode 100644 +index 0000000000..7e57c2ded6 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Core-i5-6600.sig +@@ -0,0 +1,4 @@ ++0506e3 ++family: 6 (0x06) ++model: 94 (0x5e) ++stepping: 3 (0x03) +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-2600-xsaveopt.sig b/tests/cputestdata/x86_64-cpuid-Core-i7-2600-xsaveopt.sig +new file mode 100644 +index 0000000000..9b113c3798 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-2600-xsaveopt.sig +@@ -0,0 +1,4 @@ ++0206a7 ++family: 6 (0x06) ++model: 42 (0x2a) ++stepping: 7 (0x07) +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-2600.sig b/tests/cputestdata/x86_64-cpuid-Core-i7-2600.sig +new file mode 100644 +index 0000000000..9b113c3798 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-2600.sig +@@ -0,0 +1,4 @@ ++0206a7 ++family: 6 (0x06) ++model: 42 (0x2a) ++stepping: 7 (0x07) +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-3520M.sig b/tests/cputestdata/x86_64-cpuid-Core-i7-3520M.sig +new file mode 100644 +index 0000000000..9c6ea10a83 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-3520M.sig +@@ -0,0 +1,4 @@ ++0306a9 ++family: 6 (0x06) ++model: 58 (0x3a) ++stepping: 9 (0x09) +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-3740QM.sig b/tests/cputestdata/x86_64-cpuid-Core-i7-3740QM.sig +new file mode 100644 +index 0000000000..9c6ea10a83 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-3740QM.sig +@@ -0,0 +1,4 @@ ++0306a9 ++family: 6 (0x06) ++model: 58 (0x3a) ++stepping: 9 (0x09) +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-3770.sig b/tests/cputestdata/x86_64-cpuid-Core-i7-3770.sig +new file mode 100644 +index 0000000000..9c6ea10a83 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-3770.sig +@@ -0,0 +1,4 @@ ++0306a9 ++family: 6 (0x06) ++model: 58 (0x3a) ++stepping: 9 (0x09) +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-4510U.sig b/tests/cputestdata/x86_64-cpuid-Core-i7-4510U.sig +new file mode 100644 +index 0000000000..fd6726a3da +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-4510U.sig +@@ -0,0 +1,4 @@ ++040651 ++family: 6 (0x06) ++model: 69 (0x45) ++stepping: 1 (0x01) +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-4600U.sig b/tests/cputestdata/x86_64-cpuid-Core-i7-4600U.sig +new file mode 100644 +index 0000000000..fd6726a3da +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-4600U.sig +@@ -0,0 +1,4 @@ ++040651 ++family: 6 (0x06) ++model: 69 (0x45) ++stepping: 1 (0x01) +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-arat.sig b/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-arat.sig +new file mode 100644 +index 0000000000..dd18d0f76d +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-arat.sig +@@ -0,0 +1,4 @@ ++0306d4 ++family: 6 (0x06) ++model: 61 (0x3d) ++stepping: 4 (0x04) +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-ibrs.sig b/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-ibrs.sig +new file mode 100644 +index 0000000000..dd18d0f76d +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-5600U-ibrs.sig +@@ -0,0 +1,4 @@ ++0306d4 ++family: 6 (0x06) ++model: 61 (0x3d) ++stepping: 4 (0x04) +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-5600U.sig b/tests/cputestdata/x86_64-cpuid-Core-i7-5600U.sig +new file mode 100644 +index 0000000000..dd18d0f76d +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-5600U.sig +@@ -0,0 +1,4 @@ ++0306d4 ++family: 6 (0x06) ++model: 61 (0x3d) ++stepping: 4 (0x04) +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-7600U.sig b/tests/cputestdata/x86_64-cpuid-Core-i7-7600U.sig +new file mode 100644 +index 0000000000..8f757722bb +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-7600U.sig +@@ -0,0 +1,4 @@ ++0806e9 ++family: 6 (0x06) ++model: 142 (0x8e) ++stepping: 9 (0x09) +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-7700.sig b/tests/cputestdata/x86_64-cpuid-Core-i7-7700.sig +new file mode 100644 +index 0000000000..d4db84a618 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-7700.sig +@@ -0,0 +1,4 @@ ++0906e9 ++family: 6 (0x06) ++model: 158 (0x9e) ++stepping: 9 (0x09) +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-8700.sig b/tests/cputestdata/x86_64-cpuid-Core-i7-8700.sig +new file mode 100644 +index 0000000000..45d6ea29d0 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-8700.sig +@@ -0,0 +1,4 @@ ++0906ea ++family: 6 (0x06) ++model: 158 (0x9e) ++stepping: 10 (0x0a) +diff --git a/tests/cputestdata/x86_64-cpuid-Core2-E6850.sig b/tests/cputestdata/x86_64-cpuid-Core2-E6850.sig +new file mode 100644 +index 0000000000..2382914bc7 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Core2-E6850.sig +@@ -0,0 +1,4 @@ ++0006fb ++family: 6 (0x06) ++model: 15 (0x0f) ++stepping: 11 (0x0b) +diff --git a/tests/cputestdata/x86_64-cpuid-Core2-Q9500.sig b/tests/cputestdata/x86_64-cpuid-Core2-Q9500.sig +new file mode 100644 +index 0000000000..9aec5927d0 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Core2-Q9500.sig +@@ -0,0 +1,4 @@ ++01067a ++family: 6 (0x06) ++model: 23 (0x17) ++stepping: 10 (0x0a) +diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb.sig b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb.sig +new file mode 100644 +index 0000000000..8fe15b7991 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb.sig +@@ -0,0 +1,4 @@ ++800f12 ++family: 23 (0x17) ++model: 1 (0x01) ++stepping: 2 (0x02) +diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core.sig b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core.sig +new file mode 100644 +index 0000000000..8fe15b7991 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core.sig +@@ -0,0 +1,4 @@ ++800f12 ++family: 23 (0x17) ++model: 1 (0x01) ++stepping: 2 (0x02) +diff --git a/tests/cputestdata/x86_64-cpuid-FX-8150.sig b/tests/cputestdata/x86_64-cpuid-FX-8150.sig +new file mode 100644 +index 0000000000..4b6440a315 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-FX-8150.sig +@@ -0,0 +1,4 @@ ++600f12 ++family: 21 (0x15) ++model: 1 (0x01) ++stepping: 2 (0x02) +diff --git a/tests/cputestdata/x86_64-cpuid-Opteron-1352.sig b/tests/cputestdata/x86_64-cpuid-Opteron-1352.sig +new file mode 100644 +index 0000000000..d21535b4b9 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Opteron-1352.sig +@@ -0,0 +1,4 @@ ++100f23 ++family: 16 (0x10) ++model: 2 (0x02) ++stepping: 3 (0x03) +diff --git a/tests/cputestdata/x86_64-cpuid-Opteron-2350.sig b/tests/cputestdata/x86_64-cpuid-Opteron-2350.sig +new file mode 100644 +index 0000000000..d21535b4b9 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Opteron-2350.sig +@@ -0,0 +1,4 @@ ++100f23 ++family: 16 (0x10) ++model: 2 (0x02) ++stepping: 3 (0x03) +diff --git a/tests/cputestdata/x86_64-cpuid-Opteron-6234.sig b/tests/cputestdata/x86_64-cpuid-Opteron-6234.sig +new file mode 100644 +index 0000000000..4b6440a315 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Opteron-6234.sig +@@ -0,0 +1,4 @@ ++600f12 ++family: 21 (0x15) ++model: 1 (0x01) ++stepping: 2 (0x02) +diff --git a/tests/cputestdata/x86_64-cpuid-Opteron-6282.sig b/tests/cputestdata/x86_64-cpuid-Opteron-6282.sig +new file mode 100644 +index 0000000000..4b6440a315 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Opteron-6282.sig +@@ -0,0 +1,4 @@ ++600f12 ++family: 21 (0x15) ++model: 1 (0x01) ++stepping: 2 (0x02) +diff --git a/tests/cputestdata/x86_64-cpuid-Pentium-P6100.sig b/tests/cputestdata/x86_64-cpuid-Pentium-P6100.sig +new file mode 100644 +index 0000000000..8712d34023 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Pentium-P6100.sig +@@ -0,0 +1,4 @@ ++020655 ++family: 6 (0x06) ++model: 37 (0x25) ++stepping: 5 (0x05) +diff --git a/tests/cputestdata/x86_64-cpuid-Phenom-B95.sig b/tests/cputestdata/x86_64-cpuid-Phenom-B95.sig +new file mode 100644 +index 0000000000..c93dbebc45 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Phenom-B95.sig +@@ -0,0 +1,4 @@ ++100f42 ++family: 16 (0x10) ++model: 4 (0x04) ++stepping: 2 (0x02) +diff --git a/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core.sig b/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core.sig +new file mode 100644 +index 0000000000..031bb84902 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core.sig +@@ -0,0 +1,4 @@ ++800f11 ++family: 23 (0x17) ++model: 1 (0x01) ++stepping: 1 (0x01) +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-5110.sig b/tests/cputestdata/x86_64-cpuid-Xeon-5110.sig +new file mode 100644 +index 0000000000..15f8400ca6 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-5110.sig +@@ -0,0 +1,4 @@ ++0006f6 ++family: 6 (0x06) ++model: 15 (0x0f) ++stepping: 6 (0x06) +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E3-1245-v5.sig b/tests/cputestdata/x86_64-cpuid-Xeon-E3-1245-v5.sig +new file mode 100644 +index 0000000000..7e57c2ded6 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E3-1245-v5.sig +@@ -0,0 +1,4 @@ ++0506e3 ++family: 6 (0x06) ++model: 94 (0x5e) ++stepping: 3 (0x03) +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2609-v3.sig b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2609-v3.sig +new file mode 100644 +index 0000000000..2c548c9934 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2609-v3.sig +@@ -0,0 +1,4 @@ ++0306f2 ++family: 6 (0x06) ++model: 63 (0x3f) ++stepping: 2 (0x02) +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2623-v4.sig b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2623-v4.sig +new file mode 100644 +index 0000000000..4d1622a8ef +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2623-v4.sig +@@ -0,0 +1,4 @@ ++0406f1 ++family: 6 (0x06) ++model: 79 (0x4f) ++stepping: 1 (0x01) +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v3.sig b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v3.sig +new file mode 100644 +index 0000000000..2c548c9934 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v3.sig +@@ -0,0 +1,4 @@ ++0306f2 ++family: 6 (0x06) ++model: 63 (0x3f) ++stepping: 2 (0x02) +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4.sig b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4.sig +new file mode 100644 +index 0000000000..4d1622a8ef +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4.sig +@@ -0,0 +1,4 @@ ++0406f1 ++family: 6 (0x06) ++model: 79 (0x4f) ++stepping: 1 (0x01) +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-v3.sig b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-v3.sig +new file mode 100644 +index 0000000000..2c548c9934 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-v3.sig +@@ -0,0 +1,4 @@ ++0306f2 ++family: 6 (0x06) ++model: 63 (0x3f) ++stepping: 2 (0x02) +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-v4.sig b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-v4.sig +new file mode 100644 +index 0000000000..4d1622a8ef +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-v4.sig +@@ -0,0 +1,4 @@ ++0406f1 ++family: 6 (0x06) ++model: 79 (0x4f) ++stepping: 1 (0x01) +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650.sig b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650.sig +new file mode 100644 +index 0000000000..d6493fe186 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E5-2650.sig +@@ -0,0 +1,4 @@ ++0206d7 ++family: 6 (0x06) ++model: 45 (0x2d) ++stepping: 7 (0x07) +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E7-4820.sig b/tests/cputestdata/x86_64-cpuid-Xeon-E7-4820.sig +new file mode 100644 +index 0000000000..8738e95e41 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E7-4820.sig +@@ -0,0 +1,4 @@ ++0206f2 ++family: 6 (0x06) ++model: 47 (0x2f) ++stepping: 2 (0x02) +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E7-4830.sig b/tests/cputestdata/x86_64-cpuid-Xeon-E7-4830.sig +new file mode 100644 +index 0000000000..8738e95e41 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E7-4830.sig +@@ -0,0 +1,4 @@ ++0206f2 ++family: 6 (0x06) ++model: 47 (0x2f) ++stepping: 2 (0x02) +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E7-8890-v3.sig b/tests/cputestdata/x86_64-cpuid-Xeon-E7-8890-v3.sig +new file mode 100644 +index 0000000000..8fb489fac9 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E7-8890-v3.sig +@@ -0,0 +1,4 @@ ++0306f4 ++family: 6 (0x06) ++model: 63 (0x3f) ++stepping: 4 (0x04) +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-E7540.sig b/tests/cputestdata/x86_64-cpuid-Xeon-E7540.sig +new file mode 100644 +index 0000000000..afc150cf82 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-E7540.sig +@@ -0,0 +1,4 @@ ++0206e6 ++family: 6 (0x06) ++model: 46 (0x2e) ++stepping: 6 (0x06) +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-Gold-5115.sig b/tests/cputestdata/x86_64-cpuid-Xeon-Gold-5115.sig +new file mode 100644 +index 0000000000..1a3f3449f0 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-Gold-5115.sig +@@ -0,0 +1,4 @@ ++050654 ++family: 6 (0x06) ++model: 85 (0x55) ++stepping: 4 (0x04) +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-Gold-6148.sig b/tests/cputestdata/x86_64-cpuid-Xeon-Gold-6148.sig +new file mode 100644 +index 0000000000..1a3f3449f0 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-Gold-6148.sig +@@ -0,0 +1,4 @@ ++050654 ++family: 6 (0x06) ++model: 85 (0x55) ++stepping: 4 (0x04) +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-W3520.sig b/tests/cputestdata/x86_64-cpuid-Xeon-W3520.sig +new file mode 100644 +index 0000000000..4b641ba966 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-W3520.sig +@@ -0,0 +1,4 @@ ++0106a5 ++family: 6 (0x06) ++model: 26 (0x1a) ++stepping: 5 (0x05) +diff --git a/tests/cputestdata/x86_64-cpuid-Xeon-X5460.sig b/tests/cputestdata/x86_64-cpuid-Xeon-X5460.sig +new file mode 100644 +index 0000000000..e17253472f +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Xeon-X5460.sig +@@ -0,0 +1,4 @@ ++010676 ++family: 6 (0x06) ++model: 23 (0x17) ++stepping: 6 (0x06) +-- +2.22.0 + diff --git a/SOURCES/libvirt-daemon-Register-secret-driver-before-storage-driver.patch b/SOURCES/libvirt-daemon-Register-secret-driver-before-storage-driver.patch new file mode 100644 index 0000000..3825d3b --- /dev/null +++ b/SOURCES/libvirt-daemon-Register-secret-driver-before-storage-driver.patch @@ -0,0 +1,59 @@ +From 8a9a0815510ef6de1ee34b865a768d0c6fd7b828 Mon Sep 17 00:00:00 2001 +Message-Id: <8a9a0815510ef6de1ee34b865a768d0c6fd7b828@dist-git> +From: Michal Privoznik +Date: Thu, 27 Jun 2019 15:18:14 +0200 +Subject: [PATCH] daemon: Register secret driver before storage driver +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The order in which drivers are registered is important because +their stateInitialize and stateAutoStart callback are called in +that order. Well, stateAutoStart is going away and therefore if +there is some dependency between two drivers (e.g. when +initializing storage driver expects secret driver to be available +already), the registration of such drivers must happen in correct +order. + +Signed-off-by: Michal Privoznik +Reviewed-by: Ján Tomko +(cherry picked from commit c6266ddb0214512200c5043f3196d3ca3e73919d) + +https://bugzilla.redhat.com/show_bug.cgi?id=1685151 + +Signed-off-by: Michal Privoznik +Message-Id: +Reviewed-by: Jiri Denemark +--- + src/remote/remote_daemon.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/remote/remote_daemon.c b/src/remote/remote_daemon.c +index 9f3a5f38ad..4cd6784099 100644 +--- a/src/remote/remote_daemon.c ++++ b/src/remote/remote_daemon.c +@@ -314,6 +314,10 @@ static int daemonInitialize(void) + if (virDriverLoadModule("interface", "interfaceRegister", false) < 0) + return -1; + #endif ++#ifdef WITH_SECRETS ++ if (virDriverLoadModule("secret", "secretRegister", false) < 0) ++ return -1; ++#endif + #ifdef WITH_STORAGE + if (virDriverLoadModule("storage", "storageRegister", false) < 0) + return -1; +@@ -322,10 +326,6 @@ static int daemonInitialize(void) + if (virDriverLoadModule("nodedev", "nodedevRegister", false) < 0) + return -1; + #endif +-#ifdef WITH_SECRETS +- if (virDriverLoadModule("secret", "secretRegister", false) < 0) +- return -1; +-#endif + #ifdef WITH_NWFILTER + if (virDriverLoadModule("nwfilter", "nwfilterRegister", false) < 0) + return -1; +-- +2.22.0 + diff --git a/SOURCES/libvirt-docs-schemas-Decouple-the-virtio-options-from-each-other.patch b/SOURCES/libvirt-docs-schemas-Decouple-the-virtio-options-from-each-other.patch new file mode 100644 index 0000000..fba0e09 --- /dev/null +++ b/SOURCES/libvirt-docs-schemas-Decouple-the-virtio-options-from-each-other.patch @@ -0,0 +1,44 @@ +From eb6fef622ded5762649db2d766c1eb3d876859c9 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Erik Skultety +Date: Mon, 15 Jul 2019 08:52:07 +0200 +Subject: [PATCH] docs: schemas: Decouple the virtio options from each other +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Currently, all of the VirtioOptions are under a single +element, however, neither our parser/formatter or QEMU driver requires +the presence of all the options if only a single one from the set has +been specified, so fix it and silence the schema validator. + +Signed-off-by: Erik Skultety +Reviewed-by: Ján Tomko +(cherry picked from commit 87b4e1cd7e7ec23dc69c8082948cd3bb49e18ff3) + +https://bugzilla.redhat.com/show_bug.cgi?id=1729675 + +Signed-off-by: Erik Skultety +Message-Id: <9d20b6d62248ef82a42128c461ef8c94cbc64e09.1563173480.git.eskultet@redhat.com> +Reviewed-by: Andrea Bolognani +Reviewed-by: Ján Tomko +--- + docs/schemas/domaincommon.rng | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng +index 2b6d4dced6..7d37caa246 100644 +--- a/docs/schemas/domaincommon.rng ++++ b/docs/schemas/domaincommon.rng +@@ -5417,6 +5417,8 @@ + + + ++ ++ + + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-internal-introduce-a-family-of-NULLSTR-macros.patch b/SOURCES/libvirt-internal-introduce-a-family-of-NULLSTR-macros.patch new file mode 100644 index 0000000..e4bf0c4 --- /dev/null +++ b/SOURCES/libvirt-internal-introduce-a-family-of-NULLSTR-macros.patch @@ -0,0 +1,55 @@ +From c93476692d7e0373f147c3ed20761ea1fe836e89 Mon Sep 17 00:00:00 2001 +Message-Id: +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +Date: Mon, 1 Jul 2019 17:08:16 +0200 +Subject: [PATCH] internal: introduce a family of NULLSTR macros +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +NULLSTR_EMPTY, the quiet child, +NULLSTR_STAR, the famous one and +NULLSTR_MINUS, the grumpy one. + +Signed-off-by: Ján Tomko +Reviewed-by: Andrea Bolognani +(cherry picked from commit bd5519deb75e9ff8adcd56d34cbe82dd6a341bcb) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <16722b79dbd931a33ef495b863c5716bb5d6e97c.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/internal.h | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/src/internal.h b/src/internal.h +index 47ff0479d2..a4f6605a50 100644 +--- a/src/internal.h ++++ b/src/internal.h +@@ -244,6 +244,21 @@ + */ + # define EMPTYSTR(s) ((s) ? (s) : "-") + ++/* ++ * Turn a NULL string into an empty string ++ */ ++# define NULLSTR_EMPTY(s) ((s) ? (s) : "") ++ ++/* ++ * Turn a NULL string into a star ++ */ ++# define NULLSTR_STAR(s) ((s) ? (s) : "*") ++ ++/* ++ * Turn a NULL string into a minus sign ++ */ ++# define NULLSTR_MINUS(s) ((s) ? (s) : "-") ++ + /** + * SWAP: + * +-- +2.22.0 + diff --git a/SOURCES/libvirt-lib-Drop-UDEVSETTLE.patch b/SOURCES/libvirt-lib-Drop-UDEVSETTLE.patch new file mode 100644 index 0000000..33c3c7e --- /dev/null +++ b/SOURCES/libvirt-lib-Drop-UDEVSETTLE.patch @@ -0,0 +1,73 @@ +From b5dbb3bd65642516a773a2cdf67efe977cfec4b4 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Michal Privoznik +Date: Thu, 27 Jun 2019 15:55:37 +0200 +Subject: [PATCH] lib: Drop UDEVSETTLE +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The udevsettle binary is no longer used anywhere as it was +replaced by 'udevadm settle'. There's no reason for us to even +check for it in configure. + +Signed-off-by: Michal Privoznik +Reviewed-by: Ján Tomko +(cherry picked from commit 2944dcb2de014a881c3539a43f989c2a723e87ca) + +https://bugzilla.redhat.com/show_bug.cgi?id=1710575 + +Signed-off-by: Michal Privoznik +Message-Id: +Reviewed-by: Ján Tomko +--- + m4/virt-external-programs.m4 | 5 ----- + src/util/virutil.c | 6 +----- + 2 files changed, 1 insertion(+), 10 deletions(-) + +diff --git a/m4/virt-external-programs.m4 b/m4/virt-external-programs.m4 +index ab6149288f..3c915e1a65 100644 +--- a/m4/virt-external-programs.m4 ++++ b/m4/virt-external-programs.m4 +@@ -46,7 +46,6 @@ AC_DEFUN([LIBVIRT_CHECK_EXTERNAL_PROGRAMS], [ + AC_PATH_PROG([RADVD], [radvd], [radvd], [$LIBVIRT_SBIN_PATH]) + AC_PATH_PROG([TC], [tc], [tc], [$LIBVIRT_SBIN_PATH]) + AC_PATH_PROG([UDEVADM], [udevadm], [], [$LIBVIRT_SBIN_PATH]) +- AC_PATH_PROG([UDEVSETTLE], [udevsettle], [], [$LIBVIRT_SBIN_PATH]) + AC_PATH_PROG([MODPROBE], [modprobe], [modprobe], [$LIBVIRT_SBIN_PATH]) + AC_PATH_PROG([RMMOD], [rmmod], [rmmod], [$LIBVIRT_SBIN_PATH]) + AC_PATH_PROG([MMCTL], [mm-ctl], [mm-ctl], [$LIBVIRT_SBIN_PATH]) +@@ -71,10 +70,6 @@ AC_DEFUN([LIBVIRT_CHECK_EXTERNAL_PROGRAMS], [ + AC_DEFINE_UNQUOTED([UDEVADM], ["$UDEVADM"], + [Location or name of the udevadm program]) + fi +- if test -n "$UDEVSETTLE"; then +- AC_DEFINE_UNQUOTED([UDEVSETTLE], ["$UDEVSETTLE"], +- [Location or name of the udevsettle program]) +- fi + if test -n "$MODPROBE"; then + AC_DEFINE_UNQUOTED([MODPROBE], ["$MODPROBE"], + [Location or name of the modprobe program]) +diff --git a/src/util/virutil.c b/src/util/virutil.c +index d37c1ac632..68d3217248 100644 +--- a/src/util/virutil.c ++++ b/src/util/virutil.c +@@ -1621,14 +1621,10 @@ virSetUIDGIDWithCaps(uid_t uid, gid_t gid, gid_t *groups, int ngroups, + #endif + + +-#if defined(UDEVADM) || defined(UDEVSETTLE) ++#if defined(UDEVADM) + void virWaitForDevices(void) + { +-# ifdef UDEVADM + const char *const settleprog[] = { UDEVADM, "settle", NULL }; +-# else +- const char *const settleprog[] = { UDEVSETTLE, NULL }; +-# endif + int exitstatus; + + if (access(settleprog[0], X_OK) != 0) +-- +2.22.0 + diff --git a/SOURCES/libvirt-locking-restrict-sockets-to-mode-0600.patch b/SOURCES/libvirt-locking-restrict-sockets-to-mode-0600.patch index 3d10e58..38abe7f 100644 --- a/SOURCES/libvirt-locking-restrict-sockets-to-mode-0600.patch +++ b/SOURCES/libvirt-locking-restrict-sockets-to-mode-0600.patch @@ -1,5 +1,5 @@ -From df3809f976bf16fd68cf127e1209282bd751186c Mon Sep 17 00:00:00 2001 -Message-Id: +From 0fce9e5a4f4e7f12a5eb2fc0cc44f30f26d83157 Mon Sep 17 00:00:00 2001 +Message-Id: <0fce9e5a4f4e7f12a5eb2fc0cc44f30f26d83157@dist-git> From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Wed, 15 May 2019 21:40:57 +0100 Subject: [PATCH] locking: restrict sockets to mode 0600 @@ -17,7 +17,7 @@ Fixes CVE-2019-10132 Reviewed-by: Ján Tomko Signed-off-by: Daniel P. Berrangé -(cherry picked from a private commit) +(cherry picked from commit f111e09468693909b1f067aa575efdafd9a262a1) Reviewed-by: Jiri Denemark Message-Id: <20190515204058.28077-3-berrange@redhat.com> --- @@ -50,5 +50,5 @@ index 45e0f20235..d701b27516 100644 [Install] WantedBy=sockets.target -- -2.21.0 +2.22.0 diff --git a/SOURCES/libvirt-logging-restrict-sockets-to-mode-0600.patch b/SOURCES/libvirt-logging-restrict-sockets-to-mode-0600.patch index 92d3cb9..cfb4301 100644 --- a/SOURCES/libvirt-logging-restrict-sockets-to-mode-0600.patch +++ b/SOURCES/libvirt-logging-restrict-sockets-to-mode-0600.patch @@ -1,5 +1,5 @@ -From b3feb1b383093fd4964de274bf6c96aade1a6d7e Mon Sep 17 00:00:00 2001 -Message-Id: +From 3988a7d012fc93eaae82961f72f7c53f26763651 Mon Sep 17 00:00:00 2001 +Message-Id: <3988a7d012fc93eaae82961f72f7c53f26763651@dist-git> From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Wed, 15 May 2019 21:40:58 +0100 Subject: [PATCH] logging: restrict sockets to mode 0600 @@ -17,7 +17,7 @@ Fixes CVE-2019-10132 Reviewed-by: Ján Tomko Signed-off-by: Daniel P. Berrangé -(cherry picked from a private commit) +(cherry picked from commit e37bd65f9948c1185456b2cdaa3bd6e875af680f) Reviewed-by: Jiri Denemark Message-Id: <20190515204058.28077-4-berrange@redhat.com> --- @@ -50,5 +50,5 @@ index 22b9360c8d..ae48cdab9a 100644 [Install] WantedBy=sockets.target -- -2.21.0 +2.22.0 diff --git a/SOURCES/libvirt-lxc-Use-virCgroupGetMemoryStat.patch b/SOURCES/libvirt-lxc-Use-virCgroupGetMemoryStat.patch new file mode 100644 index 0000000..8e84f9b --- /dev/null +++ b/SOURCES/libvirt-lxc-Use-virCgroupGetMemoryStat.patch @@ -0,0 +1,100 @@ +From fef35da9603a70a60d29420b9cff0db4fc2f0f82 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:02 +0200 +Subject: [PATCH] lxc: Use virCgroupGetMemoryStat +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit e634c7cd0d3265506198e1f58f1af1fd774f06b1) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <28c2e0f232ee1c3bce10654df15aa212d5f09996.1561993099.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/lxc/lxc_cgroup.c | 65 +++++--------------------------------------- + 1 file changed, 7 insertions(+), 58 deletions(-) + +diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c +index 8e937ec389..d93a19d684 100644 +--- a/src/lxc/lxc_cgroup.c ++++ b/src/lxc/lxc_cgroup.c +@@ -220,64 +220,13 @@ static int virLXCCgroupGetMemTotal(virCgroupPtr cgroup, + static int virLXCCgroupGetMemStat(virCgroupPtr cgroup, + virLXCMeminfoPtr meminfo) + { +- int ret = 0; +- FILE *statfd = NULL; +- char *statFile = NULL; +- char *line = NULL; +- size_t n; +- +- ret = virCgroupPathOfController(cgroup, VIR_CGROUP_CONTROLLER_MEMORY, +- "memory.stat", &statFile); +- if (ret != 0) { +- virReportSystemError(-ret, "%s", +- _("cannot get the path of MEMORY cgroup controller")); +- return ret; +- } +- +- statfd = fopen(statFile, "r"); +- if (statfd == NULL) { +- ret = -errno; +- goto cleanup; +- } +- +- while (getline(&line, &n, statfd) > 0) { +- +- char *value = strchr(line, ' '); +- char *nl = value ? strchr(line, '\n') : NULL; +- unsigned long long stat_value; +- +- if (!value) +- continue; +- +- if (nl) +- *nl = '\0'; +- +- *value = '\0'; +- +- if (virStrToLong_ull(value + 1, NULL, 10, &stat_value) < 0) { +- ret = -EINVAL; +- goto cleanup; +- } +- if (STREQ(line, "cache")) +- meminfo->cached = stat_value >> 10; +- else if (STREQ(line, "inactive_anon")) +- meminfo->inactive_anon = stat_value >> 10; +- else if (STREQ(line, "active_anon")) +- meminfo->active_anon = stat_value >> 10; +- else if (STREQ(line, "inactive_file")) +- meminfo->inactive_file = stat_value >> 10; +- else if (STREQ(line, "active_file")) +- meminfo->active_file = stat_value >> 10; +- else if (STREQ(line, "unevictable")) +- meminfo->unevictable = stat_value >> 10; +- } +- ret = 0; +- +- cleanup: +- VIR_FREE(line); +- VIR_FREE(statFile); +- VIR_FORCE_FCLOSE(statfd); +- return ret; ++ return virCgroupGetMemoryStat(cgroup, ++ &meminfo->cached, ++ &meminfo->inactive_anon, ++ &meminfo->active_anon, ++ &meminfo->inactive_file, ++ &meminfo->active_file, ++ &meminfo->unevictable); + } + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-m4-Drop-needless-string-checks.patch b/SOURCES/libvirt-m4-Drop-needless-string-checks.patch new file mode 100644 index 0000000..887ee23 --- /dev/null +++ b/SOURCES/libvirt-m4-Drop-needless-string-checks.patch @@ -0,0 +1,51 @@ +From 899e80657b58f8ef4c0faf452859fd9649d33b79 Mon Sep 17 00:00:00 2001 +Message-Id: <899e80657b58f8ef4c0faf452859fd9649d33b79@dist-git> +From: Michal Privoznik +Date: Thu, 27 Jun 2019 15:55:39 +0200 +Subject: [PATCH] m4: Drop needless string checks +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We provide default values for both MODPROBE and RMMOD and thus +there is no way that their paths can be empty strings. + +Signed-off-by: Michal Privoznik +Reviewed-by: Ján Tomko +(cherry picked from commit 3c8d5762a9fcf3f7d23a41d0b49def0387ecddf7) + +https://bugzilla.redhat.com/show_bug.cgi?id=1710575 + +Signed-off-by: Michal Privoznik +Message-Id: +Reviewed-by: Ján Tomko +--- + m4/virt-external-programs.m4 | 12 ++++-------- + 1 file changed, 4 insertions(+), 8 deletions(-) + +diff --git a/m4/virt-external-programs.m4 b/m4/virt-external-programs.m4 +index f1ae104b32..0f995998c3 100644 +--- a/m4/virt-external-programs.m4 ++++ b/m4/virt-external-programs.m4 +@@ -67,14 +67,10 @@ AC_DEFUN([LIBVIRT_CHECK_EXTERNAL_PROGRAMS], [ + [Location or name of the ovs-vsctl program]) + AC_DEFINE_UNQUOTED([UDEVADM], ["$UDEVADM"], + [Location or name of the udevadm program]) +- if test -n "$MODPROBE"; then +- AC_DEFINE_UNQUOTED([MODPROBE], ["$MODPROBE"], +- [Location or name of the modprobe program]) +- fi +- if test -n "$RMMOD"; then +- AC_DEFINE_UNQUOTED([RMMOD], ["$RMMOD"], +- [Location or name of the rmmod program]) +- fi ++ AC_DEFINE_UNQUOTED([MODPROBE], ["$MODPROBE"], ++ [Location or name of the modprobe program]) ++ AC_DEFINE_UNQUOTED([RMMOD], ["$RMMOD"], ++ [Location or name of the rmmod program]) + AC_DEFINE_UNQUOTED([SCRUB], ["$SCRUB"], + [Location or name of the scrub program (for wiping algorithms)]) + AC_DEFINE_UNQUOTED([ADDR2LINE], ["$ADDR2LINE"], +-- +2.22.0 + diff --git a/SOURCES/libvirt-m4-Provide-default-value-fore-UDEVADM.patch b/SOURCES/libvirt-m4-Provide-default-value-fore-UDEVADM.patch new file mode 100644 index 0000000..de7a3aa --- /dev/null +++ b/SOURCES/libvirt-m4-Provide-default-value-fore-UDEVADM.patch @@ -0,0 +1,100 @@ +From 1113a43a48b3c15f908a396ec88e9499df10f7b4 Mon Sep 17 00:00:00 2001 +Message-Id: <1113a43a48b3c15f908a396ec88e9499df10f7b4@dist-git> +From: Michal Privoznik +Date: Thu, 27 Jun 2019 15:55:38 +0200 +Subject: [PATCH] m4: Provide default value fore UDEVADM +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +It may happen that the system where libvirt is built at doesn't +have udevadm binary but the one where it runs does have it. +If we change how udevadm is run in virWaitForDevices() then we +can safely pass a default value in m4 macro. + +Signed-off-by: Michal Privoznik +Reviewed-by: Ján Tomko +(cherry picked from commit 523b799d3c356b9b4ea0b117a60cfc3b603eaffa) + +https://bugzilla.redhat.com/show_bug.cgi?id=1710575 + +Difference to the upstream commit is that I had to drop +VIR_AUTOPTR() of virCommand because that does not exist in the +downstream yet. + +Signed-off-by: Michal Privoznik +Message-Id: <3d2deafb1bf06eddd721fceb15961b27c8dbf0cf.1561643698.git.mprivozn@redhat.com> +Reviewed-by: Ján Tomko +--- + m4/virt-external-programs.m4 | 9 +++------ + src/util/virutil.c | 16 ++++++++-------- + 2 files changed, 11 insertions(+), 14 deletions(-) + +diff --git a/m4/virt-external-programs.m4 b/m4/virt-external-programs.m4 +index 3c915e1a65..f1ae104b32 100644 +--- a/m4/virt-external-programs.m4 ++++ b/m4/virt-external-programs.m4 +@@ -45,7 +45,7 @@ AC_DEFUN([LIBVIRT_CHECK_EXTERNAL_PROGRAMS], [ + AC_PATH_PROG([DNSMASQ], [dnsmasq], [dnsmasq], [$LIBVIRT_SBIN_PATH]) + AC_PATH_PROG([RADVD], [radvd], [radvd], [$LIBVIRT_SBIN_PATH]) + AC_PATH_PROG([TC], [tc], [tc], [$LIBVIRT_SBIN_PATH]) +- AC_PATH_PROG([UDEVADM], [udevadm], [], [$LIBVIRT_SBIN_PATH]) ++ AC_PATH_PROG([UDEVADM], [udevadm], [udevadm], [$LIBVIRT_SBIN_PATH]) + AC_PATH_PROG([MODPROBE], [modprobe], [modprobe], [$LIBVIRT_SBIN_PATH]) + AC_PATH_PROG([RMMOD], [rmmod], [rmmod], [$LIBVIRT_SBIN_PATH]) + AC_PATH_PROG([MMCTL], [mm-ctl], [mm-ctl], [$LIBVIRT_SBIN_PATH]) +@@ -65,11 +65,8 @@ AC_DEFUN([LIBVIRT_CHECK_EXTERNAL_PROGRAMS], [ + [Location or name of the mm-ctl program]) + AC_DEFINE_UNQUOTED([OVSVSCTL], ["$OVSVSCTL"], + [Location or name of the ovs-vsctl program]) +- +- if test -n "$UDEVADM"; then +- AC_DEFINE_UNQUOTED([UDEVADM], ["$UDEVADM"], +- [Location or name of the udevadm program]) +- fi ++ AC_DEFINE_UNQUOTED([UDEVADM], ["$UDEVADM"], ++ [Location or name of the udevadm program]) + if test -n "$MODPROBE"; then + AC_DEFINE_UNQUOTED([MODPROBE], ["$MODPROBE"], + [Location or name of the modprobe program]) +diff --git a/src/util/virutil.c b/src/util/virutil.c +index 68d3217248..cd67f54bc2 100644 +--- a/src/util/virutil.c ++++ b/src/util/virutil.c +@@ -1621,25 +1621,25 @@ virSetUIDGIDWithCaps(uid_t uid, gid_t gid, gid_t *groups, int ngroups, + #endif + + +-#if defined(UDEVADM) + void virWaitForDevices(void) + { +- const char *const settleprog[] = { UDEVADM, "settle", NULL }; ++ virCommandPtr cmd = NULL; ++ VIR_AUTOFREE(char *) udev = NULL; + int exitstatus; + +- if (access(settleprog[0], X_OK) != 0) ++ if (!(udev = virFindFileInPath(UDEVADM))) ++ return; ++ ++ if (!(cmd = virCommandNewArgList(udev, "settle", NULL))) + return; + + /* + * NOTE: we ignore errors here; this is just to make sure that any device + * nodes that are being created finish before we try to scan them. + */ +- ignore_value(virRun(settleprog, &exitstatus)); ++ ignore_value(virCommandRun(cmd, &exitstatus)); ++ virCommandFree(cmd); + } +-#else +-void virWaitForDevices(void) +-{} +-#endif + + #if WITH_DEVMAPPER + bool +-- +2.22.0 + diff --git a/SOURCES/libvirt-nwfilter-fix-adding-std-MAC-and-IP-values-to-filter-binding.patch b/SOURCES/libvirt-nwfilter-fix-adding-std-MAC-and-IP-values-to-filter-binding.patch new file mode 100644 index 0000000..aa55e53 --- /dev/null +++ b/SOURCES/libvirt-nwfilter-fix-adding-std-MAC-and-IP-values-to-filter-binding.patch @@ -0,0 +1,164 @@ +From a8234641ad57553aa054bded71ed97c94f3100f1 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Nikolay Shirokovskiy +Date: Wed, 5 Jun 2019 14:51:10 +0200 +Subject: [PATCH] nwfilter: fix adding std MAC and IP values to filter binding +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Commit d1a7c08eb changed filter instantiation code to ignore MAC and IP +variables explicitly specified for filter binding. It just replaces +explicit values with values associated with the binding. Before the +commit virNWFilterCreateVarsFrom was used so that explicit value +take precedence. Let's bring old behavior back. + +This is useful. For example if domain has two interfaces it makes +sense to list both mac adresses in MAC var of every interface +filterref. So that if guest make a bond of these interfaces +and start sending frames with one of the mac adresses from +both interfaces we can pass outgress traffic from both +interfaces too. + +Reviewed-by: Daniel P. Berrangé +Signed-off-by: Nikolay Shirokovskiy +(cherry picked from commit 01e11ebcb6e8f24662b7c67b70134c192785691c) + +https://bugzilla.redhat.com/show_bug.cgi?id=1691356 + +Signed-off-by: Jiri Denemark +Acked-by: Daniel P. Berrangé +--- + src/nwfilter/nwfilter_gentech_driver.c | 92 +++++++++----------------- + 1 file changed, 32 insertions(+), 60 deletions(-) + +diff --git a/src/nwfilter/nwfilter_gentech_driver.c b/src/nwfilter/nwfilter_gentech_driver.c +index e5dea91f83..ece5d28f41 100644 +--- a/src/nwfilter/nwfilter_gentech_driver.c ++++ b/src/nwfilter/nwfilter_gentech_driver.c +@@ -128,60 +128,6 @@ virNWFilterRuleInstFree(virNWFilterRuleInstPtr inst) + } + + +-/** +- * virNWFilterVarHashmapAddStdValues: +- * @tables: pointer to hash tabel to add values to +- * @macaddr: The string of the MAC address to add to the hash table, +- * may be NULL +- * @ipaddr: The string of the IP address to add to the hash table; +- * may be NULL +- * +- * Returns 0 in case of success, -1 in case an error happened with +- * error having been reported. +- * +- * Adds a couple of standard keys (MAC, IP) to the hash table. +- */ +-static int +-virNWFilterVarHashmapAddStdValues(virHashTablePtr table, +- const char *macaddr, +- const virNWFilterVarValue *ipaddr) +-{ +- virNWFilterVarValue *val; +- +- if (macaddr) { +- val = virNWFilterVarValueCreateSimpleCopyValue(macaddr); +- if (!val) +- return -1; +- +- if (virHashUpdateEntry(table, +- NWFILTER_STD_VAR_MAC, +- val) < 0) { +- virNWFilterVarValueFree(val); +- virReportError(VIR_ERR_INTERNAL_ERROR, +- "%s", _("Could not add variable 'MAC' to hashmap")); +- return -1; +- } +- } +- +- if (ipaddr) { +- val = virNWFilterVarValueCopy(ipaddr); +- if (!val) +- return -1; +- +- if (virHashUpdateEntry(table, +- NWFILTER_STD_VAR_IP, +- val) < 0) { +- virNWFilterVarValueFree(val); +- virReportError(VIR_ERR_INTERNAL_ERROR, +- "%s", _("Could not add variable 'IP' to hashmap")); +- return -1; +- } +- } +- +- return 0; +-} +- +- + /** + * Convert a virHashTable into a string of comma-separated + * variable names. +@@ -707,6 +653,28 @@ virNWFilterDoInstantiate(virNWFilterTechDriverPtr techdriver, + } + + ++static int ++virNWFilterVarHashmapAddStdValue(virHashTablePtr table, ++ const char *var, ++ const char *value) ++{ ++ virNWFilterVarValue *val; ++ ++ if (virHashLookup(table, var)) ++ return 0; ++ ++ if (!(val = virNWFilterVarValueCreateSimpleCopyValue(value))) ++ return -1; ++ ++ if (virHashAddEntry(table, var, val) < 0) { ++ virNWFilterVarValueFree(val); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++ + /* + * Call this function while holding the NWFilter filter update lock + */ +@@ -719,7 +687,7 @@ virNWFilterInstantiateFilterUpdate(virNWFilterDriverStatePtr driver, + bool forceWithPendingReq, + bool *foundNewFilter) + { +- int rc; ++ int rc = -1; + const char *drvname = EBIPTABLES_DRIVER_ID; + virNWFilterTechDriverPtr techdriver; + virNWFilterObjPtr obj; +@@ -745,14 +713,18 @@ virNWFilterInstantiateFilterUpdate(virNWFilterDriverStatePtr driver, + return -1; + + virMacAddrFormat(&binding->mac, vmmacaddr); ++ if (virNWFilterVarHashmapAddStdValue(binding->filterparams, ++ NWFILTER_STD_VAR_MAC, ++ vmmacaddr) < 0) ++ goto err_exit; + + ipaddr = virNWFilterIPAddrMapGetIPAddr(binding->portdevname); +- +- if (virNWFilterVarHashmapAddStdValues(binding->filterparams, +- vmmacaddr, ipaddr) < 0) { +- rc = -1; ++ if (ipaddr && ++ virNWFilterVarHashmapAddStdValue(binding->filterparams, ++ NWFILTER_STD_VAR_IP, ++ virNWFilterVarValueGetSimple(ipaddr)) < 0) + goto err_exit; +- } ++ + + filter = virNWFilterObjGetDef(obj); + +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu-Add-APIs-for-translating-CPU-features.patch b/SOURCES/libvirt-qemu-Add-APIs-for-translating-CPU-features.patch new file mode 100644 index 0000000..4879d4d --- /dev/null +++ b/SOURCES/libvirt-qemu-Add-APIs-for-translating-CPU-features.patch @@ -0,0 +1,124 @@ +From cb2374042f3e998b90e6ea025dadfae9333b49cd Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:51 +0200 +Subject: [PATCH] qemu: Add APIs for translating CPU features +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +So far we always used libvirt's name of each CPU feature relying on +backward compatible aliases in QEMU. The new translation table can be +used whenever QEMU mandates or prefers canonical feature names. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 61ee757e2002507d711c195628619b9eff38b57a) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Signed-off-by: Jiri Denemark +Message-Id: <5b080656d143733a77780affc6dd0d322216d6e7.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_capabilities.c | 64 ++++++++++++++++++++++++++++++++++++ + src/qemu/qemu_capabilities.h | 8 +++++ + 2 files changed, 72 insertions(+) + +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index 851cb73cfc..d2a2f7418a 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -2755,6 +2755,70 @@ virQEMUCapsCPUFilterFeatures(const char *name, + } + + ++typedef struct _virQEMUCapsCPUFeatureTranslationTable virQEMUCapsCPUFeatureTranslationTable; ++typedef virQEMUCapsCPUFeatureTranslationTable *virQEMUCapsCPUFeatureTranslationTablePtr; ++struct _virQEMUCapsCPUFeatureTranslationTable { ++ const char *libvirt; ++ const char *qemu; ++}; ++ ++virQEMUCapsCPUFeatureTranslationTable virQEMUCapsCPUFeaturesX86[] = { ++ {"cmp_legacy", "cmp-legacy"}, ++ {"ds_cpl", "ds-cpl"}, ++ {"fxsr_opt", "fxsr-opt"}, ++ {"kvm_pv_eoi", "kvm-pv-eoi"}, ++ {"kvm_pv_unhalt", "kvm-pv-unhalt"}, ++ {"lahf_lm", "lahf-lm"}, ++ {"nodeid_msr", "nodeid-msr"}, ++ {"pclmuldq", "pclmulqdq"}, ++ {"perfctr_core", "perfctr-core"}, ++ {"perfctr_nb", "perfctr-nb"}, ++ {"tsc_adjust", "tsc-adjust"}, ++ {NULL, NULL} ++}; ++ ++ ++static const char * ++virQEMUCapsCPUFeatureTranslate(virQEMUCapsPtr qemuCaps, ++ const char *feature, ++ bool reversed) ++{ ++ virQEMUCapsCPUFeatureTranslationTablePtr table = NULL; ++ virQEMUCapsCPUFeatureTranslationTablePtr entry; ++ ++ if (ARCH_IS_X86(qemuCaps->arch)) ++ table = virQEMUCapsCPUFeaturesX86; ++ ++ if (!table || !feature) ++ return feature; ++ ++ for (entry = table; entry->libvirt; entry++) { ++ const char *key = reversed ? entry->qemu : entry->libvirt; ++ ++ if (STREQ(feature, key)) ++ return reversed ? entry->libvirt : entry->qemu; ++ } ++ ++ return feature; ++} ++ ++ ++const char * ++virQEMUCapsCPUFeatureToQEMU(virQEMUCapsPtr qemuCaps, ++ const char *feature) ++{ ++ return virQEMUCapsCPUFeatureTranslate(qemuCaps, feature, false); ++} ++ ++ ++const char * ++virQEMUCapsCPUFeatureFromQEMU(virQEMUCapsPtr qemuCaps, ++ const char *feature) ++{ ++ return virQEMUCapsCPUFeatureTranslate(qemuCaps, feature, true); ++} ++ ++ + /** + * Returns 0 when host CPU model provided by QEMU was filled in qemuCaps, + * 1 when the caller should fall back to using virCapsPtr->host.cpu, +diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h +index bea4767f3c..8a27acd8a4 100644 +--- a/src/qemu/qemu_capabilities.h ++++ b/src/qemu/qemu_capabilities.h +@@ -628,6 +628,14 @@ bool virQEMUCapsGuestIsNative(virArch host, + bool virQEMUCapsCPUFilterFeatures(const char *name, + void *opaque); + ++const char * ++virQEMUCapsCPUFeatureToQEMU(virQEMUCapsPtr qemuCaps, ++ const char *feature); ++ ++const char * ++virQEMUCapsCPUFeatureFromQEMU(virQEMUCapsPtr qemuCaps, ++ const char *feature); ++ + virSEVCapabilityPtr + virQEMUCapsGetSEVCapabilities(virQEMUCapsPtr qemuCaps); + +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu-Add-ccw-support-for-vhost-vsock.patch b/SOURCES/libvirt-qemu-Add-ccw-support-for-vhost-vsock.patch new file mode 100644 index 0000000..169cc85 --- /dev/null +++ b/SOURCES/libvirt-qemu-Add-ccw-support-for-vhost-vsock.patch @@ -0,0 +1,343 @@ +From 31a61d20cc35f444b2b49deb146d667fb122668d Mon Sep 17 00:00:00 2001 +Message-Id: <31a61d20cc35f444b2b49deb146d667fb122668d@dist-git> +From: Boris Fiuczynski +Date: Wed, 17 Apr 2019 14:46:01 +0200 +Subject: [PATCH] qemu: Add ccw support for vhost-vsock +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add support and tests for vhost-vsock-ccw. + +Signed-off-by: Boris Fiuczynski +(cherry picked from commit 927ef9f2a6ba22213501e99dcf5ecb5f62f8f72d) +Signed-off-by: Ján Tomko + +RHEL 8.1: https://bugzilla.redhat.com/show_bug.cgi?id=1698855 +Message-Id: + +Reviewed-by: Andrea Bolognani +--- + src/qemu/qemu_command.c | 8 +++-- + src/qemu/qemu_domain.c | 10 ++++-- + src/qemu/qemu_domain_address.c | 7 +++- + .../vhost-vsock-ccw-auto.s390x-latest.args | 32 +++++++++++++++++++ + .../qemuxml2argvdata/vhost-vsock-ccw-auto.xml | 25 +++++++++++++++ + .../vhost-vsock-ccw.s390x-latest.args | 32 +++++++++++++++++++ + tests/qemuxml2argvdata/vhost-vsock-ccw.xml | 32 +++++++++++++++++++ + tests/qemuxml2argvtest.c | 2 ++ + .../vhost-vsock-ccw-auto.xml | 32 +++++++++++++++++++ + tests/qemuxml2xmloutdata/vhost-vsock-ccw.xml | 1 + + tests/qemuxml2xmltest.c | 5 +++ + 11 files changed, 181 insertions(+), 5 deletions(-) + create mode 100644 tests/qemuxml2argvdata/vhost-vsock-ccw-auto.s390x-latest.args + create mode 100644 tests/qemuxml2argvdata/vhost-vsock-ccw-auto.xml + create mode 100644 tests/qemuxml2argvdata/vhost-vsock-ccw.s390x-latest.args + create mode 100644 tests/qemuxml2argvdata/vhost-vsock-ccw.xml + create mode 100644 tests/qemuxml2xmloutdata/vhost-vsock-ccw-auto.xml + create mode 120000 tests/qemuxml2xmloutdata/vhost-vsock-ccw.xml + +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index 66abd3fe86..a8c832bad8 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -10219,10 +10219,14 @@ qemuBuildVsockDevStr(virDomainDefPtr def, + { + qemuDomainVsockPrivatePtr priv = (qemuDomainVsockPrivatePtr)vsock->privateData; + virBuffer buf = VIR_BUFFER_INITIALIZER; +- const char *device = "vhost-vsock-pci"; + char *ret = NULL; + +- virBufferAsprintf(&buf, "%s", device); ++ if (vsock->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) { ++ virBufferAddLit(&buf, "vhost-vsock-ccw"); ++ } else { ++ virBufferAddLit(&buf, "vhost-vsock-pci"); ++ } ++ + virBufferAsprintf(&buf, ",id=%s", vsock->info.alias); + virBufferAsprintf(&buf, ",guest-cid=%u", vsock->guest_cid); + virBufferAsprintf(&buf, ",vhostfd=%s%u", fdprefix, priv->vhostfd); +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index c530733e97..be3477bf8a 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -5559,7 +5559,8 @@ qemuDomainDeviceDefValidateMemory(const virDomainMemoryDef *memory ATTRIBUTE_UNU + + + static int +-qemuDomainDeviceDefValidateVsock(const virDomainVsockDef *vsock ATTRIBUTE_UNUSED, ++qemuDomainDeviceDefValidateVsock(const virDomainVsockDef *vsock, ++ const virDomainDef *def, + virQEMUCapsPtr qemuCaps) + { + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VHOST_VSOCK)) { +@@ -5568,6 +5569,11 @@ qemuDomainDeviceDefValidateVsock(const virDomainVsockDef *vsock ATTRIBUTE_UNUSED + "with this QEMU binary")); + return -1; + } ++ ++ if (!qemuDomainCheckCCWS390AddressSupport(def, vsock->info, qemuCaps, ++ "vsock")) ++ return -1; ++ + return 0; + } + +@@ -5715,7 +5721,7 @@ qemuDomainDeviceDefValidate(const virDomainDeviceDef *dev, + break; + + case VIR_DOMAIN_DEVICE_VSOCK: +- ret = qemuDomainDeviceDefValidateVsock(dev->data.vsock, qemuCaps); ++ ret = qemuDomainDeviceDefValidateVsock(dev->data.vsock, def, qemuCaps); + break; + + case VIR_DOMAIN_DEVICE_TPM: +diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c +index 3e50521c11..79d2b9f9c4 100644 +--- a/src/qemu/qemu_domain_address.c ++++ b/src/qemu/qemu_domain_address.c +@@ -310,7 +310,8 @@ qemuDomainPrimeVirtioDeviceAddresses(virDomainDefPtr def, + declare address-less virtio devices to be of address type 'type' + disks, networks, videos, consoles, controllers, memballoon and rng + in this order +- if type is ccw filesystem devices are declared to be of address type ccw ++ if type is ccw filesystem and vsock devices are declared to be of ++ address type ccw + */ + size_t i; + +@@ -377,6 +378,10 @@ qemuDomainPrimeVirtioDeviceAddresses(virDomainDefPtr def, + if (def->fss[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) + def->fss[i]->info.type = type; + } ++ if (def->vsock && ++ def->vsock->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { ++ def->vsock->info.type = type; ++ } + } + } + +diff --git a/tests/qemuxml2argvdata/vhost-vsock-ccw-auto.s390x-latest.args b/tests/qemuxml2argvdata/vhost-vsock-ccw-auto.s390x-latest.args +new file mode 100644 +index 0000000000..6092f8e85c +--- /dev/null ++++ b/tests/qemuxml2argvdata/vhost-vsock-ccw-auto.s390x-latest.args +@@ -0,0 +1,32 @@ ++LC_ALL=C \ ++PATH=/bin \ ++HOME=/home/test \ ++USER=test \ ++LOGNAME=test \ ++QEMU_AUDIO_DRV=none \ ++/usr/bin/qemu-system-s390x \ ++-name guest=QEMUGuest1,debug-threads=on \ ++-S \ ++-object secret,id=masterKey0,format=raw,\ ++file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \ ++-machine s390-ccw-virtio,accel=tcg,usb=off,dump-guest-core=off \ ++-m 214 \ ++-realtime mlock=off \ ++-smp 1,sockets=1,cores=1,threads=1 \ ++-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ ++-display none \ ++-no-user-config \ ++-nodefaults \ ++-chardev socket,id=charmonitor,fd=1729,server,nowait \ ++-mon chardev=charmonitor,id=monitor,mode=control \ ++-rtc base=utc \ ++-no-shutdown \ ++-boot strict=on \ ++-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-virtio-disk0 \ ++-device virtio-blk-ccw,scsi=off,devno=fe.0.0000,drive=drive-virtio-disk0,\ ++id=virtio-disk0,bootindex=1 \ ++-device virtio-balloon-ccw,id=balloon0,devno=fe.0.0001 \ ++-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\ ++resourcecontrol=deny \ ++-device vhost-vsock-ccw,id=vsock0,guest-cid=42,vhostfd=6789,devno=fe.0.0002 \ ++-msg timestamp=on +diff --git a/tests/qemuxml2argvdata/vhost-vsock-ccw-auto.xml b/tests/qemuxml2argvdata/vhost-vsock-ccw-auto.xml +new file mode 100644 +index 0000000000..e5b60765ab +--- /dev/null ++++ b/tests/qemuxml2argvdata/vhost-vsock-ccw-auto.xml +@@ -0,0 +1,25 @@ ++ ++ QEMUGuest1 ++ c7a5fdbd-edaf-9455-926a-d65c16db1809 ++ 219136 ++ 219136 ++ 1 ++ ++ hvm ++ ++ ++ ++ destroy ++ restart ++ destroy ++ ++ /usr/bin/qemu-system-s390x ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/qemuxml2argvdata/vhost-vsock-ccw.s390x-latest.args b/tests/qemuxml2argvdata/vhost-vsock-ccw.s390x-latest.args +new file mode 100644 +index 0000000000..93eb3f3430 +--- /dev/null ++++ b/tests/qemuxml2argvdata/vhost-vsock-ccw.s390x-latest.args +@@ -0,0 +1,32 @@ ++LC_ALL=C \ ++PATH=/bin \ ++HOME=/home/test \ ++USER=test \ ++LOGNAME=test \ ++QEMU_AUDIO_DRV=none \ ++/usr/bin/qemu-system-s390x \ ++-name guest=QEMUGuest1,debug-threads=on \ ++-S \ ++-object secret,id=masterKey0,format=raw,\ ++file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \ ++-machine s390-ccw-virtio,accel=tcg,usb=off,dump-guest-core=off \ ++-m 214 \ ++-realtime mlock=off \ ++-smp 1,sockets=1,cores=1,threads=1 \ ++-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ ++-display none \ ++-no-user-config \ ++-nodefaults \ ++-chardev socket,id=charmonitor,fd=1729,server,nowait \ ++-mon chardev=charmonitor,id=monitor,mode=control \ ++-rtc base=utc \ ++-no-shutdown \ ++-boot strict=on \ ++-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-virtio-disk0 \ ++-device virtio-blk-ccw,scsi=off,devno=fe.0.0000,drive=drive-virtio-disk0,\ ++id=virtio-disk0,bootindex=1 \ ++-device virtio-balloon-ccw,id=balloon0,devno=fe.0.0001 \ ++-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\ ++resourcecontrol=deny \ ++-device vhost-vsock-ccw,id=vsock0,guest-cid=4,vhostfd=6789,devno=fe.0.0003 \ ++-msg timestamp=on +diff --git a/tests/qemuxml2argvdata/vhost-vsock-ccw.xml b/tests/qemuxml2argvdata/vhost-vsock-ccw.xml +new file mode 100644 +index 0000000000..083061c6cc +--- /dev/null ++++ b/tests/qemuxml2argvdata/vhost-vsock-ccw.xml +@@ -0,0 +1,32 @@ ++ ++ QEMUGuest1 ++ c7a5fdbd-edaf-9455-926a-d65c16db1809 ++ 219136 ++ 219136 ++ 1 ++ ++ hvm ++ ++ ++ ++ destroy ++ restart ++ destroy ++ ++ /usr/bin/qemu-system-s390x ++ ++ ++ ++ ++
++ ++ ++
++ ++ ++ ++ ++
++ ++ ++ +diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c +index abb256c913..7f25cccf9d 100644 +--- a/tests/qemuxml2argvtest.c ++++ b/tests/qemuxml2argvtest.c +@@ -2972,6 +2972,8 @@ mymain(void) + + DO_TEST_CAPS_LATEST("vhost-vsock"); + DO_TEST_CAPS_LATEST("vhost-vsock-auto"); ++ DO_TEST_CAPS_ARCH_LATEST("vhost-vsock-ccw", "s390x"); ++ DO_TEST_CAPS_ARCH_LATEST("vhost-vsock-ccw-auto", "s390x"); + + DO_TEST_CAPS_VER("launch-security-sev", "2.12.0"); + +diff --git a/tests/qemuxml2xmloutdata/vhost-vsock-ccw-auto.xml b/tests/qemuxml2xmloutdata/vhost-vsock-ccw-auto.xml +new file mode 100644 +index 0000000000..38a0fb3808 +--- /dev/null ++++ b/tests/qemuxml2xmloutdata/vhost-vsock-ccw-auto.xml +@@ -0,0 +1,32 @@ ++ ++ QEMUGuest1 ++ c7a5fdbd-edaf-9455-926a-d65c16db1809 ++ 219136 ++ 219136 ++ 1 ++ ++ hvm ++ ++ ++ ++ destroy ++ restart ++ destroy ++ ++ /usr/bin/qemu-system-s390x ++ ++ ++ ++ ++
++ ++ ++
++ ++ ++ ++ ++
++ ++ ++ +diff --git a/tests/qemuxml2xmloutdata/vhost-vsock-ccw.xml b/tests/qemuxml2xmloutdata/vhost-vsock-ccw.xml +new file mode 120000 +index 0000000000..e0fa69dba9 +--- /dev/null ++++ b/tests/qemuxml2xmloutdata/vhost-vsock-ccw.xml +@@ -0,0 +1 @@ ++../qemuxml2argvdata/vhost-vsock-ccw.xml +\ No newline at end of file +diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c +index dbac863239..2a2bf01ffa 100644 +--- a/tests/qemuxml2xmltest.c ++++ b/tests/qemuxml2xmltest.c +@@ -1231,6 +1231,11 @@ mymain(void) + + DO_TEST("vhost-vsock", QEMU_CAPS_DEVICE_VHOST_VSOCK); + DO_TEST("vhost-vsock-auto", QEMU_CAPS_DEVICE_VHOST_VSOCK); ++ DO_TEST("vhost-vsock-ccw", QEMU_CAPS_DEVICE_VHOST_VSOCK, ++ QEMU_CAPS_CCW); ++ DO_TEST("vhost-vsock-ccw-auto", QEMU_CAPS_DEVICE_VHOST_VSOCK, ++ QEMU_CAPS_CCW); ++ + + if (getenv("LIBVIRT_SKIP_CLEANUP") == NULL) + virFileDeleteTree(fakerootdir); +-- +2.21.0 + diff --git a/SOURCES/libvirt-qemu-Add-hotpluging-support-for-PCI-devices-on-S390-guests.patch b/SOURCES/libvirt-qemu-Add-hotpluging-support-for-PCI-devices-on-S390-guests.patch new file mode 100644 index 0000000..23ac15d --- /dev/null +++ b/SOURCES/libvirt-qemu-Add-hotpluging-support-for-PCI-devices-on-S390-guests.patch @@ -0,0 +1,316 @@ +From 84d44b33a64b6fd7f77d021249d23dc054243ddf Mon Sep 17 00:00:00 2001 +Message-Id: <84d44b33a64b6fd7f77d021249d23dc054243ddf@dist-git> +From: Yi Min Zhao +Date: Mon, 8 Apr 2019 10:57:29 +0200 +Subject: [PATCH] qemu: Add hotpluging support for PCI devices on S390 guests +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This commit adds hotplug support for PCI devices on S390 guests. +There's no need to implement hot unplug for zPCI as QEMU implements +an unplug callback which will unplug both PCI and zPCI device in a +cascaded way. +Currently, the following PCI devices are supported: + virtio-blk-pci + virtio-net-pci + virtio-rng-pci + virtio-input-host-pci + virtio-keyboard-pci + virtio-mouse-pci + virtio-tablet-pci + vfio-pci + SCSIVhost device + +Signed-off-by: Yi Min Zhao +Reviewed-by: Boris Fiuczynski +Reviewed-by: Stefan Zimmermann +Reviewed-by: Bjoern Walk +Reviewed-by: Ján Tomko +Reviewed-by: Andrea Bolognani + +(cherry picked from commit 1d1e264f13d14ed05838bae2fcec2ffef26671f2) + +https://bugzilla.redhat.com/show_bug.cgi?id=1508149 + +Conflicts: + + * src/qemu/qemu_hotplug.c + + context + - missing 83fe11e950bc + +Signed-off-by: Andrea Bolognani +Message-Id: <20190408085732.28684-13-abologna@redhat.com> +Reviewed-by: Laine Stump +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_hotplug.c | 160 +++++++++++++++++++++++++++++++++++++--- + 1 file changed, 151 insertions(+), 9 deletions(-) + +diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c +index 776cd75474..abe2632556 100644 +--- a/src/qemu/qemu_hotplug.c ++++ b/src/qemu/qemu_hotplug.c +@@ -154,6 +154,80 @@ qemuHotplugPrepareDiskAccess(virQEMUDriverPtr driver, + } + + ++static int ++qemuDomainAttachZPCIDevice(qemuMonitorPtr mon, ++ virDomainDeviceInfoPtr info) ++{ ++ char *devstr_zpci = NULL; ++ int ret = -1; ++ ++ if (!(devstr_zpci = qemuBuildZPCIDevStr(info))) ++ goto cleanup; ++ ++ if (qemuMonitorAddDevice(mon, devstr_zpci) < 0) ++ goto cleanup; ++ ++ ret = 0; ++ ++ cleanup: ++ VIR_FREE(devstr_zpci); ++ return ret; ++} ++ ++ ++static int ++qemuDomainDetachZPCIDevice(qemuMonitorPtr mon, ++ virDomainDeviceInfoPtr info) ++{ ++ char *zpciAlias = NULL; ++ int ret = -1; ++ ++ if (virAsprintf(&zpciAlias, "zpci%d", info->addr.pci.zpci.uid) < 0) ++ goto cleanup; ++ ++ if (qemuMonitorDelDevice(mon, zpciAlias) < 0) ++ goto cleanup; ++ ++ ret = 0; ++ ++ cleanup: ++ VIR_FREE(zpciAlias); ++ return ret; ++} ++ ++ ++static int ++qemuDomainAttachExtensionDevice(qemuMonitorPtr mon, ++ virDomainDeviceInfoPtr info) ++{ ++ if (info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI || ++ info->addr.pci.extFlags == VIR_PCI_ADDRESS_EXTENSION_NONE) { ++ return 0; ++ } ++ ++ if (info->addr.pci.extFlags & VIR_PCI_ADDRESS_EXTENSION_ZPCI) ++ return qemuDomainAttachZPCIDevice(mon, info); ++ ++ return 0; ++} ++ ++ ++static int ++qemuDomainDetachExtensionDevice(qemuMonitorPtr mon, ++ virDomainDeviceInfoPtr info) ++{ ++ if (info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI || ++ info->addr.pci.extFlags == VIR_PCI_ADDRESS_EXTENSION_NONE) { ++ return 0; ++ } ++ ++ if (info->addr.pci.extFlags & VIR_PCI_ADDRESS_EXTENSION_ZPCI) ++ return qemuDomainDetachZPCIDevice(mon, info); ++ ++ return 0; ++} ++ ++ + static int + qemuHotplugWaitForTrayEject(virQEMUDriverPtr driver, + virDomainObjPtr vm, +@@ -403,9 +477,14 @@ qemuDomainAttachDiskGeneric(virQEMUDriverPtr driver, + if (qemuBlockStorageSourceAttachApply(priv->mon, data) < 0) + goto exit_monitor; + +- if (qemuMonitorAddDevice(priv->mon, devstr) < 0) ++ if (qemuDomainAttachExtensionDevice(priv->mon, &disk->info) < 0) + goto exit_monitor; + ++ if (qemuMonitorAddDevice(priv->mon, devstr) < 0) { ++ ignore_value(qemuDomainDetachExtensionDevice(priv->mon, &disk->info)); ++ goto exit_monitor; ++ } ++ + if (qemuDomainObjExitMonitor(driver, vm) < 0) { + ret = -2; + goto error; +@@ -519,7 +598,16 @@ int qemuDomainAttachControllerDevice(virQEMUDriverPtr driver, + goto cleanup; + + qemuDomainObjEnterMonitor(driver, vm); +- ret = qemuMonitorAddDevice(priv->mon, devstr); ++ ++ if ((ret = qemuDomainAttachExtensionDevice(priv->mon, ++ &controller->info)) < 0) { ++ goto exit_monitor; ++ } ++ ++ if ((ret = qemuMonitorAddDevice(priv->mon, devstr)) < 0) ++ ignore_value(qemuDomainDetachExtensionDevice(priv->mon, &controller->info)); ++ ++ exit_monitor: + if (qemuDomainObjExitMonitor(driver, vm) < 0) { + releaseaddr = false; + ret = -1; +@@ -969,6 +1057,7 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver, + } + + if (qemuDomainIsS390CCW(vm->def) && ++ net->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI && + virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_CCW)) { + net->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW; + if (!(ccwaddrs = qemuDomainCCWAddrSetCreateFromDomain(vm->def))) +@@ -1038,7 +1127,15 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver, + goto try_remove; + + qemuDomainObjEnterMonitor(driver, vm); ++ ++ if (qemuDomainAttachExtensionDevice(priv->mon, &net->info) < 0) { ++ ignore_value(qemuDomainObjExitMonitor(driver, vm)); ++ virDomainAuditNet(vm, NULL, net, "attach", false); ++ goto try_remove; ++ } ++ + if (qemuMonitorAddDevice(priv->mon, nicstr) < 0) { ++ ignore_value(qemuDomainDetachExtensionDevice(priv->mon, &net->info)); + ignore_value(qemuDomainObjExitMonitor(driver, vm)); + virDomainAuditNet(vm, NULL, net, "attach", false); + goto try_remove; +@@ -1256,8 +1353,16 @@ qemuDomainAttachHostPCIDevice(virQEMUDriverPtr driver, + goto error; + + qemuDomainObjEnterMonitor(driver, vm); +- ret = qemuMonitorAddDeviceWithFd(priv->mon, devstr, +- configfd, configfd_name); ++ ++ if ((ret = qemuDomainAttachExtensionDevice(priv->mon, hostdev->info)) < 0) ++ goto exit_monitor; ++ ++ if ((ret = qemuMonitorAddDeviceWithFd(priv->mon, devstr, ++ configfd, configfd_name)) < 0) { ++ ignore_value(qemuDomainDetachExtensionDevice(priv->mon, hostdev->info)); ++ } ++ ++ exit_monitor: + if (qemuDomainObjExitMonitor(driver, vm) < 0) + goto error; + +@@ -1913,9 +2018,14 @@ qemuDomainAttachRNGDevice(virQEMUDriverPtr driver, + if (qemuMonitorAddObject(priv->mon, &props, &objAlias) < 0) + goto exit_monitor; + +- if (qemuMonitorAddDevice(priv->mon, devstr) < 0) ++ if (qemuDomainAttachExtensionDevice(priv->mon, &rng->info) < 0) + goto exit_monitor; + ++ if (qemuMonitorAddDevice(priv->mon, devstr) < 0) { ++ ignore_value(qemuDomainDetachExtensionDevice(priv->mon, &rng->info)); ++ goto exit_monitor; ++ } ++ + if (qemuDomainObjExitMonitor(driver, vm) < 0) { + releaseaddr = false; + goto cleanup; +@@ -2407,8 +2517,16 @@ qemuDomainAttachSCSIVHostDevice(virQEMUDriverPtr driver, + + qemuDomainObjEnterMonitor(driver, vm); + +- ret = qemuMonitorAddDeviceWithFd(priv->mon, devstr, vhostfd, vhostfdName); ++ if ((ret = qemuDomainAttachExtensionDevice(priv->mon, hostdev->info)) < 0) ++ goto exit_monitor; + ++ if ((ret = qemuMonitorAddDeviceWithFd(priv->mon, devstr, vhostfd, ++ vhostfdName)) < 0) { ++ ignore_value(qemuDomainDetachExtensionDevice(priv->mon, hostdev->info)); ++ goto exit_monitor; ++ } ++ ++ exit_monitor: + if (qemuDomainObjExitMonitor(driver, vm) < 0 || ret < 0) + goto audit; + +@@ -2653,9 +2771,14 @@ qemuDomainAttachShmemDevice(virQEMUDriverPtr driver, + + release_backing = true; + +- if (qemuMonitorAddDevice(priv->mon, shmstr) < 0) ++ if (qemuDomainAttachExtensionDevice(priv->mon, &shmem->info) < 0) + goto exit_monitor; + ++ if (qemuMonitorAddDevice(priv->mon, shmstr) < 0) { ++ ignore_value(qemuDomainDetachExtensionDevice(priv->mon, &shmem->info)); ++ goto exit_monitor; ++ } ++ + if (qemuDomainObjExitMonitor(driver, vm) < 0) { + release_address = false; + goto cleanup; +@@ -2827,9 +2950,15 @@ qemuDomainAttachInputDevice(virQEMUDriverPtr driver, + goto cleanup; + + qemuDomainObjEnterMonitor(driver, vm); +- if (qemuMonitorAddDevice(priv->mon, devstr) < 0) ++ ++ if (qemuDomainAttachExtensionDevice(priv->mon, &input->info) < 0) + goto exit_monitor; + ++ if (qemuMonitorAddDevice(priv->mon, devstr) < 0) { ++ ignore_value(qemuDomainDetachExtensionDevice(priv->mon, &input->info)); ++ goto exit_monitor; ++ } ++ + if (qemuDomainObjExitMonitor(driver, vm) < 0) { + releaseaddr = false; + goto cleanup; +@@ -2906,9 +3035,15 @@ qemuDomainAttachVsockDevice(virQEMUDriverPtr driver, + goto cleanup; + + qemuDomainObjEnterMonitor(driver, vm); +- if (qemuMonitorAddDeviceWithFd(priv->mon, devstr, vsockPriv->vhostfd, fdname) < 0) ++ ++ if (qemuDomainAttachExtensionDevice(priv->mon, &vsock->info) < 0) + goto exit_monitor; + ++ if (qemuMonitorAddDeviceWithFd(priv->mon, devstr, vsockPriv->vhostfd, fdname) < 0) { ++ ignore_value(qemuDomainDetachExtensionDevice(priv->mon, &vsock->info)); ++ goto exit_monitor; ++ } ++ + if (qemuDomainObjExitMonitor(driver, vm) < 0) { + releaseaddr = false; + goto cleanup; +@@ -4932,10 +5067,17 @@ int qemuDomainDetachControllerDevice(virQEMUDriverPtr driver, + qemuDomainMarkDeviceForRemoval(vm, &detach->info); + + qemuDomainObjEnterMonitor(driver, vm); ++ if (detach->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI && ++ qemuDomainDetachExtensionDevice(priv->mon, &detach->info)) { ++ goto exit_monitor; ++ } ++ + if (qemuMonitorDelDevice(priv->mon, detach->info.alias)) { + ignore_value(qemuDomainObjExitMonitor(driver, vm)); + goto cleanup; + } ++ ++ exit_monitor: + if (qemuDomainObjExitMonitor(driver, vm) < 0) + goto cleanup; + +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu-Add-type-filter-to-qemuMonitorJSONParsePropsList.patch b/SOURCES/libvirt-qemu-Add-type-filter-to-qemuMonitorJSONParsePropsList.patch new file mode 100644 index 0000000..abaeb89 --- /dev/null +++ b/SOURCES/libvirt-qemu-Add-type-filter-to-qemuMonitorJSONParsePropsList.patch @@ -0,0 +1,89 @@ +From 3004a0c300e65777cf888a49eddcfdda8cd59941 Mon Sep 17 00:00:00 2001 +Message-Id: <3004a0c300e65777cf888a49eddcfdda8cd59941@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:26:00 +0200 +Subject: [PATCH] qemu: Add type filter to qemuMonitorJSONParsePropsList +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The function converts a list of QOM properties into a NULL-terminated +array of property names. The new type parameter may be used to limit the +result to properties of a specific type. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 430023e5ee3f7549104f5eb09e3c26563a11882c) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Signed-off-by: Jiri Denemark +Message-Id: +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_monitor_json.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c +index 8fead72ecf..abf952cd34 100644 +--- a/src/qemu/qemu_monitor_json.c ++++ b/src/qemu/qemu_monitor_json.c +@@ -6067,11 +6067,13 @@ int qemuMonitorJSONSetObjectProperty(qemuMonitorPtr mon, + static int + qemuMonitorJSONParsePropsList(virJSONValuePtr cmd, + virJSONValuePtr reply, ++ const char *type, + char ***props) + { + virJSONValuePtr data; + char **proplist = NULL; + size_t n = 0; ++ size_t count = 0; + size_t i; + int ret = -1; + +@@ -6089,17 +6091,21 @@ qemuMonitorJSONParsePropsList(virJSONValuePtr cmd, + virJSONValuePtr child = virJSONValueArrayGet(data, i); + const char *tmp; + ++ if (type && ++ STRNEQ_NULLABLE(virJSONValueObjectGetString(child, "type"), type)) ++ continue; ++ + if (!(tmp = virJSONValueObjectGetString(child, "name"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("reply data was missing 'name'")); + goto cleanup; + } + +- if (VIR_STRDUP(proplist[i], tmp) < 0) ++ if (VIR_STRDUP(proplist[count++], tmp) < 0) + goto cleanup; + } + +- ret = n; ++ ret = count; + *props = proplist; + proplist = NULL; + +@@ -6132,7 +6138,7 @@ int qemuMonitorJSONGetDeviceProps(qemuMonitorPtr mon, + goto cleanup; + } + +- ret = qemuMonitorJSONParsePropsList(cmd, reply, props); ++ ret = qemuMonitorJSONParsePropsList(cmd, reply, NULL, props); + cleanup: + virJSONValueFree(reply); + virJSONValueFree(cmd); +@@ -6164,7 +6170,7 @@ qemuMonitorJSONGetObjectProps(qemuMonitorPtr mon, + goto cleanup; + } + +- ret = qemuMonitorJSONParsePropsList(cmd, reply, props); ++ ret = qemuMonitorJSONParsePropsList(cmd, reply, NULL, props); + cleanup: + virJSONValueFree(reply); + virJSONValueFree(cmd); +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu-Add-zPCI-address-definition-check.patch b/SOURCES/libvirt-qemu-Add-zPCI-address-definition-check.patch new file mode 100644 index 0000000..b88cfa0 --- /dev/null +++ b/SOURCES/libvirt-qemu-Add-zPCI-address-definition-check.patch @@ -0,0 +1,156 @@ +From 9aef6ea4b1d8a79e353bb34ab5559c698cad1eb1 Mon Sep 17 00:00:00 2001 +Message-Id: <9aef6ea4b1d8a79e353bb34ab5559c698cad1eb1@dist-git> +From: Yi Min Zhao +Date: Mon, 8 Apr 2019 10:57:26 +0200 +Subject: [PATCH] qemu: Add zPCI address definition check +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We should ensure that QEMU supports zPCI when a zPCI address is defined +in XML and otherwise report an error. This patch introduces a generic +validation function qemuDomainDeviceDefValidateAddress() which calls +qemuDomainDeviceDefValidateZPCIAddress() if address type is PCI address. + +Signed-off-by: Yi Min Zhao +Reviewed-by: Boris Fiuczynski +Reviewed-by: Andrea Bolognani + +(cherry picked from commit e6565d54db3d52ae38b5934877be4d004c2d5f35) + +https://bugzilla.redhat.com/show_bug.cgi?id=1508149 + +Conflicts: + + * src/qemu/qemu_domain.c + + context + - missing 709f57c25be8 + +Signed-off-by: Andrea Bolognani +Message-Id: <20190408085732.28684-10-abologna@redhat.com> +Reviewed-by: Laine Stump +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_domain.c | 36 +++++++++++++++++++ + .../hostdev-vfio-zpci-wrong-arch.xml | 34 ++++++++++++++++++ + tests/qemuxml2argvtest.c | 2 ++ + 3 files changed, 72 insertions(+) + create mode 100644 tests/qemuxml2argvdata/hostdev-vfio-zpci-wrong-arch.xml + +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index da961f0de9..8604385aa2 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -5681,6 +5681,38 @@ qemuDomainDeviceDefValidateGraphics(const virDomainGraphicsDef *graphics, + } + + ++static int ++qemuDomainDeviceDefValidateZPCIAddress(virDomainDeviceInfoPtr info, ++ virQEMUCapsPtr qemuCaps) ++{ ++ if (!virZPCIDeviceAddressIsEmpty(&info->addr.pci.zpci) && ++ !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_ZPCI)) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, ++ "%s", ++ _("This QEMU binary doesn't support zPCI")); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++ ++static int ++qemuDomainDeviceDefValidateAddress(const virDomainDeviceDef *dev, ++ virQEMUCapsPtr qemuCaps) ++{ ++ virDomainDeviceInfoPtr info; ++ ++ if (!(info = virDomainDeviceGetInfo((virDomainDeviceDef *)dev))) ++ return 0; ++ ++ if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) ++ return qemuDomainDeviceDefValidateZPCIAddress(info, qemuCaps); ++ ++ return 0; ++} ++ ++ + static int + qemuDomainDeviceDefValidate(const virDomainDeviceDef *dev, + const virDomainDef *def, +@@ -5694,6 +5726,9 @@ qemuDomainDeviceDefValidate(const virDomainDeviceDef *dev, + def->emulator))) + return -1; + ++ if ((ret = qemuDomainDeviceDefValidateAddress(dev, qemuCaps)) < 0) ++ goto cleanup; ++ + switch ((virDomainDeviceType)dev->type) { + case VIR_DOMAIN_DEVICE_NET: + ret = qemuDomainDeviceDefValidateNetwork(dev->data.net); +@@ -5769,6 +5804,7 @@ qemuDomainDeviceDefValidate(const virDomainDeviceDef *dev, + break; + } + ++ cleanup: + virObjectUnref(qemuCaps); + return ret; + } +diff --git a/tests/qemuxml2argvdata/hostdev-vfio-zpci-wrong-arch.xml b/tests/qemuxml2argvdata/hostdev-vfio-zpci-wrong-arch.xml +new file mode 100644 +index 0000000000..bfb2f83a3b +--- /dev/null ++++ b/tests/qemuxml2argvdata/hostdev-vfio-zpci-wrong-arch.xml +@@ -0,0 +1,34 @@ ++ ++ QEMUGuest2 ++ c7a5fdbd-edaf-9466-926a-d65c16db1809 ++ 219100 ++ 219100 ++ 1 ++ ++ hvm ++ ++ ++ ++ destroy ++ restart ++ destroy ++ ++ /usr/bin/qemu-system-i686 ++ ++ ++ ++
++ ++ ++ ++ ++ ++
++ ++
++ ++
++ ++ ++ ++ +diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c +index 2eb2505971..1066de8bc4 100644 +--- a/tests/qemuxml2argvtest.c ++++ b/tests/qemuxml2argvtest.c +@@ -1632,6 +1632,8 @@ mymain(void) + DO_TEST_PARSE_ERROR("hostdev-mdev-display-missing-graphics", + QEMU_CAPS_DEVICE_VFIO_PCI, + QEMU_CAPS_VFIO_PCI_DISPLAY); ++ DO_TEST_PARSE_ERROR("hostdev-vfio-zpci-wrong-arch", ++ QEMU_CAPS_DEVICE_VFIO_PCI); + DO_TEST("hostdev-vfio-zpci", + QEMU_CAPS_DEVICE_VFIO_PCI, + QEMU_CAPS_DEVICE_ZPCI); +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu-Allow-creating-ppc64-guests-with-graphics-and-no-USB-mouse.patch b/SOURCES/libvirt-qemu-Allow-creating-ppc64-guests-with-graphics-and-no-USB-mouse.patch new file mode 100644 index 0000000..7a6af43 --- /dev/null +++ b/SOURCES/libvirt-qemu-Allow-creating-ppc64-guests-with-graphics-and-no-USB-mouse.patch @@ -0,0 +1,76 @@ +From 1c58390619bfdd6174b1d24bc5b64caae45487b0 Mon Sep 17 00:00:00 2001 +Message-Id: <1c58390619bfdd6174b1d24bc5b64caae45487b0@dist-git> +From: Andrea Bolognani +Date: Wed, 17 Apr 2019 11:21:25 +0200 +Subject: [PATCH] qemu: Allow creating ppc64 guests with graphics and no USB + mouse + +The existing behavior for ppc64 guests is to always add a USB +keyboard and mouse combo if graphics are present; unfortunately, +this means any attempt to use a USB tablet will cause both pointing +devices to show up in the guest, which in turn will result in poor +user experience. + +We can't just stop adding the USB mouse or start adding a USB tablet +instead, because existing applications and users might rely on the +current behavior; however, we can avoid adding the USB mouse if a USB +tablet is already present, thus allowing users and applications to +create guests that contain a single pointing device. + +https://bugzilla.redhat.com/show_bug.cgi?id=1683681 + +Signed-off-by: Andrea Bolognani +Reviewed-by: Cole Robinson + +(cherry picked from commit 186bb479d0f409dc75175bea48a760838c479a6c) + +Conflicts: + * src/qemu/qemu_domain.c + + context in qemuDomainDefAddDefaultDevices() + - missing 6427bfc8b3bb + +Deleted: + * tests/qemuxml2argvdata/ppc64-pseries-graphics.ppc64-latest.args + + doesn't exist downstream + - missing 4d7ea75e1e73 + +Signed-off-by: Andrea Bolognani +Message-Id: <20190417092125.10277-2-abologna@redhat.com> +--- + src/qemu/qemu_domain.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index be3477bf8a..cc2a896a07 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -3323,6 +3323,26 @@ qemuDomainDefAddDefaultDevices(virDomainDefPtr def, + def->memballoon = memballoon; + } + ++ if (addDefaultUSBMouse) { ++ bool hasUSBTablet = false; ++ size_t j; ++ ++ for (j = 0; j < def->ninputs; j++) { ++ if (def->inputs[j]->type == VIR_DOMAIN_INPUT_TYPE_TABLET && ++ def->inputs[j]->bus == VIR_DOMAIN_INPUT_BUS_USB) { ++ hasUSBTablet = true; ++ break; ++ } ++ } ++ ++ /* Historically, we have automatically added USB keyboard and ++ * mouse to some guests. While the former device is generally ++ * safe to have, adding the latter is undesiderable if a USB ++ * tablet is already present in the guest */ ++ if (hasUSBTablet) ++ addDefaultUSBMouse = false; ++ } ++ + if (addDefaultUSBKBD && + def->ngraphics > 0 && + virDomainDefMaybeAddInput(def, +-- +2.21.0 + diff --git a/SOURCES/libvirt-qemu-Auto-add-pci-root-for-s390-s390x-guests.patch b/SOURCES/libvirt-qemu-Auto-add-pci-root-for-s390-s390x-guests.patch new file mode 100644 index 0000000..98d484f --- /dev/null +++ b/SOURCES/libvirt-qemu-Auto-add-pci-root-for-s390-s390x-guests.patch @@ -0,0 +1,46 @@ +From dc63c5044631d30981960d96568cd2abb3d31ede Mon Sep 17 00:00:00 2001 +Message-Id: +From: Yi Min Zhao +Date: Mon, 8 Apr 2019 10:57:23 +0200 +Subject: [PATCH] qemu: Auto add pci-root for s390/s390x guests +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The pci-root depends on zpci capability. So autogenerate pci-root if +zpci exists. + +Signed-off-by: Yi Min Zhao +Reviewed-by: Boris Fiuczynski +Reviewed-by: Stefan Zimmermann +Reviewed-by: Bjoern Walk +Reviewed-by: Ján Tomko +Reviewed-by: Andrea Bolognani + +(cherry picked from commit d46673913802b65dd7d33562cce41a78cbc85a88) + +https://bugzilla.redhat.com/show_bug.cgi?id=1508149 + +Signed-off-by: Andrea Bolognani +Message-Id: <20190408085732.28684-7-abologna@redhat.com> +Reviewed-by: Laine Stump +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_domain.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index 21f0722495..da961f0de9 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -3228,6 +3228,7 @@ qemuDomainDefAddDefaultDevices(virDomainDefPtr def, + case VIR_ARCH_S390X: + addDefaultUSB = false; + addPanicDevice = true; ++ addPCIRoot = virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_ZPCI); + break; + + case VIR_ARCH_SPARC: +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu-Don-t-cache-microcode-version.patch b/SOURCES/libvirt-qemu-Don-t-cache-microcode-version.patch index 9ca5d90..25c6132 100644 --- a/SOURCES/libvirt-qemu-Don-t-cache-microcode-version.patch +++ b/SOURCES/libvirt-qemu-Don-t-cache-microcode-version.patch @@ -1,5 +1,5 @@ -From b41057952aa267335c7e00380e77952a8b65086a Mon Sep 17 00:00:00 2001 -Message-Id: +From 6832d9d8dd0963f4865801a29e848ff3256b3282 Mon Sep 17 00:00:00 2001 +Message-Id: <6832d9d8dd0963f4865801a29e848ff3256b3282@dist-git> From: Jiri Denemark Date: Fri, 12 Apr 2019 21:21:05 +0200 Subject: [PATCH] qemu: Don't cache microcode version @@ -20,7 +20,7 @@ Signed-off-by: Jiri Denemark Reviewed-by: Ján Tomko (cherry picked from commit 673c62a3b7855a0685d8f116e227c402720b9ee9) -CVE-2018-11091, CVE-2018-12126, CVE-2018-12127, CVE-2018-12130 +CVE-2018-12126, CVE-2018-12127, CVE-2018-12130, CVE-2019-11091 Conflicts: src/qemu/qemu_capabilities.c diff --git a/SOURCES/libvirt-qemu-Don-t-use-full-CPU-model-expansion.patch b/SOURCES/libvirt-qemu-Don-t-use-full-CPU-model-expansion.patch new file mode 100644 index 0000000..e5dd84a --- /dev/null +++ b/SOURCES/libvirt-qemu-Don-t-use-full-CPU-model-expansion.patch @@ -0,0 +1,2643 @@ +From a70b774016d7fa23e415e3c166a6549f257a2339 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:57 +0200 +Subject: [PATCH] qemu: Don't use full CPU model expansion +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We used type=full expansion on the result of previous type=static +expansion to get all possible spellings of CPU features. Since we can +now translate the QEMU's canonical names to our names, we can drop this +magic and do only type=static CPU model expansion. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit a3f2c802d240b6183b037ef4a1ca53b5de440800) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Conflicts: + tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml + - file size based microcode version + + tests/qemucapabilitiesdata/caps_4.1.0.x86_64.replies + - QMP message IDs are different + +Signed-off-by: Jiri Denemark +Message-Id: <27ac93d749ca253f4a45481c656e085be874caa9.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_capabilities.c | 9 +- + .../caps_4.1.0.x86_64.replies | 1964 +---------------- + .../caps_4.1.0.x86_64.xml | 228 +- + 3 files changed, 49 insertions(+), 2152 deletions(-) + +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index 88c651ea7b..78be2d35f4 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -2421,10 +2421,13 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps, + + /* Some x86_64 features defined in cpu_map.xml use spelling which differ + * from the one preferred by QEMU. Static expansion would give us only the +- * preferred spelling, thus we need to do a full expansion on the result of +- * the initial static expansion to get all variants of all features. ++ * preferred spelling. With new QEMU we always use the QEMU's canonical ++ * names of all features and translate between them and our names. But for ++ * older version of QEMU we need to do a full expansion on the result of ++ * the initial static expansion to get all variants of feature names. + */ +- if (ARCH_IS_X86(qemuCaps->arch)) ++ if (ARCH_IS_X86(qemuCaps->arch) && ++ !virQEMUCapsGet(qemuCaps, QEMU_CAPS_CANONICAL_CPU_FEATURES)) + type = QEMU_MONITOR_CPU_MODEL_EXPANSION_STATIC_FULL; + else + type = QEMU_MONITOR_CPU_MODEL_EXPANSION_STATIC; +diff --git a/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.replies b/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.replies +index 5b4d7a8484..300785b8bc 100644 +--- a/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.replies ++++ b/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.replies +@@ -21545,495 +21545,6 @@ + "id": "libvirt-52" + } + +-{ +- "execute": "query-cpu-model-expansion", +- "arguments": { +- "type": "full", +- "model": { +- "name": "base", +- "props": { +- "cmov": true, +- "ia64": false, +- "ssb-no": false, +- "aes": true, +- "mmx": true, +- "rdpid": false, +- "arat": true, +- "gfni": false, +- "ibrs-all": false, +- "pause-filter": false, +- "xsavec": true, +- "intel-pt": false, +- "kvm-asyncpf": true, +- "perfctr-core": false, +- "mpx": true, +- "pbe": false, +- "avx512cd": false, +- "decodeassists": false, +- "sse4.1": true, +- "family": 6, +- "wbnoinvd": false, +- "avx512f": false, +- "msr": true, +- "mce": true, +- "mca": true, +- "xcrypt": false, +- "min-level": 13, +- "xgetbv1": true, +- "cid": false, +- "ds": false, +- "fxsr": true, +- "xsaveopt": true, +- "xtpr": false, +- "avx512vl": false, +- "avx512-vpopcntdq": false, +- "phe": false, +- "extapic": false, +- "3dnowprefetch": true, +- "avx512vbmi2": false, +- "cr8legacy": false, +- "stibp": false, +- "xcrypt-en": false, +- "pn": false, +- "rsba": false, +- "dca": false, +- "vendor": "GenuineIntel", +- "pku": false, +- "smx": false, +- "cmp-legacy": false, +- "avx512-4fmaps": false, +- "vmcb-clean": false, +- "hle": true, +- "3dnowext": false, +- "amd-no-ssb": false, +- "npt": false, +- "rdctl-no": false, +- "clwb": false, +- "lbrv": false, +- "adx": true, +- "ss": true, +- "pni": true, +- "svm-lock": false, +- "smep": true, +- "smap": true, +- "pfthreshold": false, +- "x2apic": true, +- "avx512vbmi": false, +- "avx512vnni": false, +- "flushbyasid": false, +- "f16c": true, +- "ace2-en": false, +- "pae": true, +- "pat": true, +- "sse": true, +- "phe-en": false, +- "kvm-nopiodelay": true, +- "tm": false, +- "kvmclock-stable-bit": true, +- "hypervisor": true, +- "mds-no": false, +- "pcommit": false, +- "syscall": true, +- "avx512dq": false, +- "svm": false, +- "invtsc": false, +- "sse2": true, +- "ssbd": false, +- "est": false, +- "avx512ifma": false, +- "tm2": false, +- "kvm-pv-eoi": true, +- "kvm-pv-ipi": true, +- "cx8": true, +- "cldemote": false, +- "kvm-mmu": false, +- "sse4.2": true, +- "pge": true, +- "avx512bitalg": false, +- "pdcm": false, +- "model": 94, +- "movbe": true, +- "nrip-save": false, +- "ssse3": true, +- "sse4a": false, +- "invpcid": true, +- "pdpe1gb": true, +- "tsc-deadline": true, +- "skip-l1dfl-vmentry": true, +- "fma": true, +- "cx16": true, +- "de": true, +- "stepping": 3, +- "xsave": true, +- "clflush": true, +- "skinit": false, +- "tsc": true, +- "tce": false, +- "fpu": true, +- "ds-cpl": false, +- "ibs": false, +- "fma4": false, +- "la57": false, +- "osvw": false, +- "apic": true, +- "pmm": false, +- "spec-ctrl": false, +- "tsc-adjust": true, +- "kvm-steal-time": true, +- "kvmclock": true, +- "lwp": false, +- "amd-ssbd": false, +- "xop": false, +- "ibpb": false, +- "avx": true, +- "movdiri": false, +- "acpi": false, +- "avx512bw": false, +- "ace2": false, +- "fsgsbase": true, +- "ht": false, +- "nx": true, +- "pclmulqdq": true, +- "mmxext": false, +- "popcnt": true, +- "vaes": false, +- "movdir64b": false, +- "xsaves": true, +- "lm": true, +- "umip": true, +- "pse": true, +- "avx2": true, +- "sep": true, +- "virt-ssbd": false, +- "nodeid-msr": false, +- "md-clear": false, +- "misalignsse": false, +- "min-xlevel": 2147483656, +- "bmi1": true, +- "bmi2": true, +- "kvm-pv-unhalt": true, +- "tsc-scale": false, +- "topoext": false, +- "clflushopt": true, +- "monitor": false, +- "avx512er": false, +- "pmm-en": false, +- "pcid": true, +- "arch-capabilities": true, +- "3dnow": false, +- "erms": true, +- "lahf-lm": true, +- "vpclmulqdq": false, +- "fxsr-opt": false, +- "xstore": false, +- "rtm": true, +- "kvm-hint-dedicated": false, +- "lmce": true, +- "perfctr-nb": false, +- "rdrand": true, +- "rdseed": true, +- "avx512-4vnniw": false, +- "vme": true, +- "vmx": true, +- "dtes64": false, +- "mtrr": true, +- "rdtscp": true, +- "pse36": true, +- "kvm-pv-tlb-flush": true, +- "tbm": false, +- "wdt": false, +- "model-id": "Intel(R) Xeon(R) CPU E3-1245 v5 @ 3.50GHz", +- "sha-ni": false, +- "abm": true, +- "avx512pf": false, +- "xstore-en": false +- } +- } +- }, +- "id": "libvirt-53" +-} +- +-{ +- "return": { +- "model": { +- "name": "base", +- "props": { +- "phys-bits": 0, +- "core-id": -1, +- "xlevel": 2147483656, +- "cmov": true, +- "ia64": false, +- "ssb-no": false, +- "aes": true, +- "mmx": true, +- "rdpid": false, +- "arat": true, +- "gfni": false, +- "ibrs-all": false, +- "pause-filter": false, +- "xsavec": true, +- "intel-pt": false, +- "hv-frequencies": false, +- "tsc-frequency": 0, +- "xd": true, +- "x-intel-pt-auto-level": true, +- "hv-vendor-id": "", +- "kvm-asyncpf": true, +- "kvm_asyncpf": true, +- "perfctr_core": false, +- "perfctr-core": false, +- "mpx": true, +- "pbe": false, +- "decodeassists": false, +- "avx512cd": false, +- "sse4_1": true, +- "sse4.1": true, +- "sse4-1": true, +- "family": 6, +- "legacy-cache": true, +- "host-phys-bits-limit": 0, +- "vmware-cpuid-freq": true, +- "wbnoinvd": false, +- "avx512f": false, +- "msr": true, +- "mce": true, +- "mca": true, +- "hv-runtime": false, +- "xcrypt": false, +- "thread-id": -1, +- "min-level": 13, +- "xgetbv1": true, +- "cid": false, +- "hv-relaxed": false, +- "hv-crash": false, +- "ds": false, +- "fxsr": true, +- "xsaveopt": true, +- "xtpr": false, +- "hv-evmcs": false, +- "avx512vl": false, +- "avx512-vpopcntdq": false, +- "phe": false, +- "extapic": false, +- "3dnowprefetch": true, +- "avx512vbmi2": false, +- "cr8legacy": false, +- "stibp": false, +- "cpuid-0xb": true, +- "xcrypt-en": false, +- "kvm_pv_eoi": true, +- "apic-id": 4294967295, +- "rsba": false, +- "pn": false, +- "dca": false, +- "vendor": "GenuineIntel", +- "hv-ipi": false, +- "pku": false, +- "smx": false, +- "cmp_legacy": false, +- "cmp-legacy": false, +- "node-id": -1, +- "avx512-4fmaps": false, +- "vmcb_clean": false, +- "vmcb-clean": false, +- "3dnowext": false, +- "amd-no-ssb": false, +- "hle": true, +- "npt": false, +- "rdctl-no": false, +- "memory": "/machine/unattached/system[0]", +- "clwb": false, +- "lbrv": false, +- "adx": true, +- "ss": true, +- "pni": true, +- "svm_lock": false, +- "svm-lock": false, +- "pfthreshold": false, +- "smep": true, +- "smap": true, +- "x2apic": true, +- "avx512vbmi": false, +- "avx512vnni": false, +- "hv-stimer": false, +- "x-hv-synic-kvm-only": false, +- "i64": true, +- "flushbyasid": false, +- "f16c": true, +- "ace2-en": false, +- "pat": true, +- "pae": true, +- "sse": true, +- "phe-en": false, +- "kvm_nopiodelay": true, +- "kvm-nopiodelay": true, +- "tm": false, +- "kvmclock-stable-bit": true, +- "hypervisor": true, +- "socket-id": -1, +- "mds-no": false, +- "pcommit": false, +- "syscall": true, +- "level": 13, +- "avx512dq": false, +- "x-migrate-smi-count": true, +- "svm": false, +- "full-cpuid-auto-level": true, +- "hv-reset": false, +- "invtsc": false, +- "sse3": true, +- "sse2": true, +- "ssbd": false, +- "est": false, +- "avx512ifma": false, +- "tm2": false, +- "kvm-pv-ipi": true, +- "kvm-pv-eoi": true, +- "cx8": true, +- "cldemote": false, +- "hv-reenlightenment": false, +- "kvm_mmu": false, +- "kvm-mmu": false, +- "sse4_2": true, +- "sse4.2": true, +- "sse4-2": true, +- "pge": true, +- "fill-mtrr-mask": true, +- "avx512bitalg": false, +- "nodeid_msr": false, +- "pdcm": false, +- "movbe": true, +- "model": 94, +- "nrip_save": false, +- "nrip-save": false, +- "kvm_pv_unhalt": true, +- "ssse3": true, +- "sse4a": false, +- "invpcid": true, +- "pdpe1gb": true, +- "tsc-deadline": true, +- "skip-l1dfl-vmentry": true, +- "fma": true, +- "cx16": true, +- "de": true, +- "enforce": false, +- "stepping": 3, +- "xsave": true, +- "clflush": true, +- "skinit": false, +- "tsc": true, +- "tce": false, +- "fpu": true, +- "ibs": false, +- "ds_cpl": false, +- "ds-cpl": false, +- "host-phys-bits": false, +- "fma4": false, +- "la57": false, +- "osvw": false, +- "check": true, +- "hv-spinlocks": -1, +- "pmm": false, +- "pmu": false, +- "apic": true, +- "spec-ctrl": false, +- "min-xlevel2": 0, +- "tsc-adjust": true, +- "tsc_adjust": true, +- "kvm-steal-time": true, +- "kvm_steal_time": true, +- "kvmclock": true, +- "l3-cache": true, +- "lwp": false, +- "amd-ssbd": false, +- "ibpb": false, +- "xop": false, +- "avx": true, +- "movdiri": false, +- "ace2": false, +- "avx512bw": false, +- "acpi": false, +- "hv-vapic": false, +- "fsgsbase": true, +- "ht": false, +- "nx": true, +- "pclmulqdq": true, +- "mmxext": false, +- "vaes": false, +- "popcnt": true, +- "xsaves": true, +- "movdir64b": false, +- "tcg-cpuid": true, +- "lm": true, +- "umip": true, +- "pse": true, +- "avx2": true, +- "sep": true, +- "pclmuldq": true, +- "virt-ssbd": false, +- "x-hv-max-vps": -1, +- "nodeid-msr": false, +- "md-clear": false, +- "kvm": true, +- "misalignsse": false, +- "min-xlevel": 2147483656, +- "kvm-pv-unhalt": true, +- "bmi2": true, +- "bmi1": true, +- "realized": false, +- "tsc_scale": false, +- "tsc-scale": false, +- "topoext": false, +- "hv-vpindex": false, +- "xlevel2": 0, +- "clflushopt": true, +- "kvm-no-smi-migration": false, +- "monitor": false, +- "avx512er": false, +- "pmm-en": false, +- "pcid": true, +- "arch-capabilities": true, +- "3dnow": false, +- "erms": true, +- "lahf-lm": true, +- "lahf_lm": true, +- "vpclmulqdq": false, +- "fxsr-opt": false, +- "hv-synic": false, +- "xstore": false, +- "fxsr_opt": false, +- "kvm-hint-dedicated": false, +- "rtm": true, +- "lmce": true, +- "hv-time": false, +- "perfctr-nb": false, +- "perfctr_nb": false, +- "ffxsr": false, +- "hv-tlbflush": false, +- "rdrand": true, +- "rdseed": true, +- "avx512-4vnniw": false, +- "vmx": true, +- "vme": true, +- "dtes64": false, +- "mtrr": true, +- "rdtscp": true, +- "pse36": true, +- "kvm-pv-tlb-flush": true, +- "tbm": false, +- "wdt": false, +- "pause_filter": false, +- "sha-ni": false, +- "model-id": "Intel(R) Xeon(R) CPU E3-1245 v5 @ 3.50GHz", +- "abm": true, +- "avx512pf": false, +- "xstore-en": false +- } +- } +- }, +- "id": "libvirt-53" +-} +- + { + "execute": "query-cpu-model-expansion", + "arguments": { +@@ -22045,7 +21556,7 @@ + } + } + }, +- "id": "libvirt-54" ++ "id": "libvirt-53" + } + + { +@@ -22251,496 +21762,7 @@ + } + } + }, +- "id": "libvirt-54" +-} +- +-{ +- "execute": "query-cpu-model-expansion", +- "arguments": { +- "type": "full", +- "model": { +- "name": "base", +- "props": { +- "cmov": true, +- "ia64": false, +- "ssb-no": false, +- "aes": true, +- "mmx": true, +- "rdpid": false, +- "arat": true, +- "gfni": false, +- "ibrs-all": false, +- "pause-filter": false, +- "xsavec": true, +- "intel-pt": false, +- "kvm-asyncpf": true, +- "perfctr-core": false, +- "mpx": true, +- "pbe": false, +- "avx512cd": false, +- "decodeassists": false, +- "sse4.1": true, +- "family": 6, +- "wbnoinvd": false, +- "avx512f": false, +- "msr": true, +- "mce": true, +- "mca": true, +- "xcrypt": false, +- "min-level": 13, +- "xgetbv1": true, +- "cid": false, +- "ds": false, +- "fxsr": true, +- "xsaveopt": true, +- "xtpr": false, +- "avx512vl": false, +- "avx512-vpopcntdq": false, +- "phe": false, +- "extapic": false, +- "3dnowprefetch": true, +- "avx512vbmi2": false, +- "cr8legacy": false, +- "stibp": false, +- "xcrypt-en": false, +- "pn": false, +- "rsba": false, +- "dca": false, +- "vendor": "GenuineIntel", +- "pku": false, +- "smx": false, +- "cmp-legacy": false, +- "avx512-4fmaps": false, +- "vmcb-clean": false, +- "hle": true, +- "3dnowext": false, +- "amd-no-ssb": false, +- "npt": false, +- "rdctl-no": false, +- "clwb": false, +- "lbrv": false, +- "adx": true, +- "ss": true, +- "pni": true, +- "svm-lock": false, +- "smep": true, +- "smap": true, +- "pfthreshold": false, +- "x2apic": true, +- "avx512vbmi": false, +- "avx512vnni": false, +- "flushbyasid": false, +- "f16c": true, +- "ace2-en": false, +- "pae": true, +- "pat": true, +- "sse": true, +- "phe-en": false, +- "kvm-nopiodelay": true, +- "tm": false, +- "kvmclock-stable-bit": true, +- "hypervisor": true, +- "mds-no": false, +- "pcommit": false, +- "syscall": true, +- "avx512dq": false, +- "svm": false, +- "invtsc": false, +- "sse2": true, +- "ssbd": false, +- "est": false, +- "avx512ifma": false, +- "tm2": false, +- "kvm-pv-eoi": true, +- "kvm-pv-ipi": true, +- "cx8": true, +- "cldemote": false, +- "kvm-mmu": false, +- "sse4.2": true, +- "pge": true, +- "avx512bitalg": false, +- "pdcm": false, +- "model": 94, +- "movbe": true, +- "nrip-save": false, +- "ssse3": true, +- "sse4a": false, +- "invpcid": true, +- "pdpe1gb": true, +- "tsc-deadline": true, +- "skip-l1dfl-vmentry": true, +- "fma": true, +- "cx16": true, +- "de": true, +- "stepping": 3, +- "xsave": true, +- "clflush": true, +- "skinit": false, +- "tsc": true, +- "tce": false, +- "fpu": true, +- "ds-cpl": false, +- "ibs": false, +- "fma4": false, +- "la57": false, +- "osvw": false, +- "apic": true, +- "pmm": false, +- "spec-ctrl": false, +- "tsc-adjust": true, +- "kvm-steal-time": true, +- "kvmclock": true, +- "lwp": false, +- "amd-ssbd": false, +- "xop": false, +- "ibpb": false, +- "avx": true, +- "movdiri": false, +- "acpi": false, +- "avx512bw": false, +- "ace2": false, +- "fsgsbase": true, +- "ht": false, +- "nx": true, +- "pclmulqdq": true, +- "mmxext": false, +- "popcnt": true, +- "vaes": false, +- "movdir64b": false, +- "xsaves": true, +- "lm": true, +- "umip": true, +- "pse": true, +- "avx2": true, +- "sep": true, +- "virt-ssbd": false, +- "nodeid-msr": false, +- "md-clear": false, +- "misalignsse": false, +- "min-xlevel": 2147483656, +- "bmi1": true, +- "bmi2": true, +- "kvm-pv-unhalt": true, +- "tsc-scale": false, +- "topoext": false, +- "clflushopt": true, +- "monitor": false, +- "avx512er": false, +- "pmm-en": false, +- "pcid": true, +- "arch-capabilities": true, +- "3dnow": false, +- "erms": true, +- "lahf-lm": true, +- "vpclmulqdq": false, +- "fxsr-opt": false, +- "xstore": false, +- "rtm": true, +- "kvm-hint-dedicated": false, +- "lmce": true, +- "perfctr-nb": false, +- "rdrand": true, +- "rdseed": true, +- "avx512-4vnniw": false, +- "vme": true, +- "vmx": true, +- "dtes64": false, +- "mtrr": true, +- "rdtscp": true, +- "pse36": true, +- "kvm-pv-tlb-flush": true, +- "tbm": false, +- "wdt": false, +- "model-id": "Intel(R) Xeon(R) CPU E3-1245 v5 @ 3.50GHz", +- "sha-ni": false, +- "abm": true, +- "avx512pf": false, +- "xstore-en": false +- } +- } +- }, +- "id": "libvirt-55" +-} +- +-{ +- "return": { +- "model": { +- "name": "base", +- "props": { +- "phys-bits": 0, +- "core-id": -1, +- "xlevel": 2147483656, +- "cmov": true, +- "ia64": false, +- "ssb-no": false, +- "aes": true, +- "mmx": true, +- "rdpid": false, +- "arat": true, +- "gfni": false, +- "ibrs-all": false, +- "pause-filter": false, +- "xsavec": true, +- "intel-pt": false, +- "hv-frequencies": false, +- "tsc-frequency": 0, +- "xd": true, +- "x-intel-pt-auto-level": true, +- "hv-vendor-id": "", +- "kvm-asyncpf": true, +- "kvm_asyncpf": true, +- "perfctr_core": false, +- "perfctr-core": false, +- "mpx": true, +- "pbe": false, +- "decodeassists": false, +- "avx512cd": false, +- "sse4_1": true, +- "sse4.1": true, +- "sse4-1": true, +- "family": 6, +- "legacy-cache": true, +- "host-phys-bits-limit": 0, +- "vmware-cpuid-freq": true, +- "wbnoinvd": false, +- "avx512f": false, +- "msr": true, +- "mce": true, +- "mca": true, +- "hv-runtime": false, +- "xcrypt": false, +- "thread-id": -1, +- "min-level": 13, +- "xgetbv1": true, +- "cid": false, +- "hv-relaxed": false, +- "hv-crash": false, +- "ds": false, +- "fxsr": true, +- "xsaveopt": true, +- "xtpr": false, +- "hv-evmcs": false, +- "avx512vl": false, +- "avx512-vpopcntdq": false, +- "phe": false, +- "extapic": false, +- "3dnowprefetch": true, +- "avx512vbmi2": false, +- "cr8legacy": false, +- "stibp": false, +- "cpuid-0xb": true, +- "xcrypt-en": false, +- "kvm_pv_eoi": true, +- "apic-id": 4294967295, +- "rsba": false, +- "pn": false, +- "dca": false, +- "vendor": "GenuineIntel", +- "hv-ipi": false, +- "pku": false, +- "smx": false, +- "cmp_legacy": false, +- "cmp-legacy": false, +- "node-id": -1, +- "avx512-4fmaps": false, +- "vmcb_clean": false, +- "vmcb-clean": false, +- "3dnowext": false, +- "amd-no-ssb": false, +- "hle": true, +- "npt": false, +- "rdctl-no": false, +- "memory": "/machine/unattached/system[0]", +- "clwb": false, +- "lbrv": false, +- "adx": true, +- "ss": true, +- "pni": true, +- "svm_lock": false, +- "svm-lock": false, +- "pfthreshold": false, +- "smep": true, +- "smap": true, +- "x2apic": true, +- "avx512vbmi": false, +- "avx512vnni": false, +- "hv-stimer": false, +- "x-hv-synic-kvm-only": false, +- "i64": true, +- "flushbyasid": false, +- "f16c": true, +- "ace2-en": false, +- "pat": true, +- "pae": true, +- "sse": true, +- "phe-en": false, +- "kvm_nopiodelay": true, +- "kvm-nopiodelay": true, +- "tm": false, +- "kvmclock-stable-bit": true, +- "hypervisor": true, +- "socket-id": -1, +- "mds-no": false, +- "pcommit": false, +- "syscall": true, +- "level": 13, +- "avx512dq": false, +- "x-migrate-smi-count": true, +- "svm": false, +- "full-cpuid-auto-level": true, +- "hv-reset": false, +- "invtsc": false, +- "sse3": true, +- "sse2": true, +- "ssbd": false, +- "est": false, +- "avx512ifma": false, +- "tm2": false, +- "kvm-pv-ipi": true, +- "kvm-pv-eoi": true, +- "cx8": true, +- "cldemote": false, +- "hv-reenlightenment": false, +- "kvm_mmu": false, +- "kvm-mmu": false, +- "sse4_2": true, +- "sse4.2": true, +- "sse4-2": true, +- "pge": true, +- "fill-mtrr-mask": true, +- "avx512bitalg": false, +- "nodeid_msr": false, +- "pdcm": false, +- "movbe": true, +- "model": 94, +- "nrip_save": false, +- "nrip-save": false, +- "kvm_pv_unhalt": true, +- "ssse3": true, +- "sse4a": false, +- "invpcid": true, +- "pdpe1gb": true, +- "tsc-deadline": true, +- "skip-l1dfl-vmentry": true, +- "fma": true, +- "cx16": true, +- "de": true, +- "enforce": false, +- "stepping": 3, +- "xsave": true, +- "clflush": true, +- "skinit": false, +- "tsc": true, +- "tce": false, +- "fpu": true, +- "ibs": false, +- "ds_cpl": false, +- "ds-cpl": false, +- "host-phys-bits": false, +- "fma4": false, +- "la57": false, +- "osvw": false, +- "check": true, +- "hv-spinlocks": -1, +- "pmm": false, +- "pmu": false, +- "apic": true, +- "spec-ctrl": false, +- "min-xlevel2": 0, +- "tsc-adjust": true, +- "tsc_adjust": true, +- "kvm-steal-time": true, +- "kvm_steal_time": true, +- "kvmclock": true, +- "l3-cache": true, +- "lwp": false, +- "amd-ssbd": false, +- "ibpb": false, +- "xop": false, +- "avx": true, +- "movdiri": false, +- "ace2": false, +- "avx512bw": false, +- "acpi": false, +- "hv-vapic": false, +- "fsgsbase": true, +- "ht": false, +- "nx": true, +- "pclmulqdq": true, +- "mmxext": false, +- "vaes": false, +- "popcnt": true, +- "xsaves": true, +- "movdir64b": false, +- "tcg-cpuid": true, +- "lm": true, +- "umip": true, +- "pse": true, +- "avx2": true, +- "sep": true, +- "pclmuldq": true, +- "virt-ssbd": false, +- "x-hv-max-vps": -1, +- "nodeid-msr": false, +- "md-clear": false, +- "kvm": true, +- "misalignsse": false, +- "min-xlevel": 2147483656, +- "kvm-pv-unhalt": true, +- "bmi2": true, +- "bmi1": true, +- "realized": false, +- "tsc_scale": false, +- "tsc-scale": false, +- "topoext": false, +- "hv-vpindex": false, +- "xlevel2": 0, +- "clflushopt": true, +- "kvm-no-smi-migration": false, +- "monitor": false, +- "avx512er": false, +- "pmm-en": false, +- "pcid": true, +- "arch-capabilities": true, +- "3dnow": false, +- "erms": true, +- "lahf-lm": true, +- "lahf_lm": true, +- "vpclmulqdq": false, +- "fxsr-opt": false, +- "hv-synic": false, +- "xstore": false, +- "fxsr_opt": false, +- "kvm-hint-dedicated": false, +- "rtm": true, +- "lmce": true, +- "hv-time": false, +- "perfctr-nb": false, +- "perfctr_nb": false, +- "ffxsr": false, +- "hv-tlbflush": false, +- "rdrand": true, +- "rdseed": true, +- "avx512-4vnniw": false, +- "vmx": true, +- "vme": true, +- "dtes64": false, +- "mtrr": true, +- "rdtscp": true, +- "pse36": true, +- "kvm-pv-tlb-flush": true, +- "tbm": false, +- "wdt": false, +- "pause_filter": false, +- "sha-ni": false, +- "model-id": "Intel(R) Xeon(R) CPU E3-1245 v5 @ 3.50GHz", +- "abm": true, +- "avx512pf": false, +- "xstore-en": false +- } +- } +- }, +- "id": "libvirt-55" ++ "id": "libvirt-53" + } + + { +@@ -23697,495 +22719,6 @@ + "id": "libvirt-3" + } + +-{ +- "execute": "query-cpu-model-expansion", +- "arguments": { +- "type": "full", +- "model": { +- "name": "base", +- "props": { +- "cmov": true, +- "ia64": false, +- "ssb-no": false, +- "aes": true, +- "mmx": true, +- "rdpid": false, +- "arat": true, +- "gfni": false, +- "ibrs-all": false, +- "pause-filter": false, +- "xsavec": false, +- "intel-pt": false, +- "kvm-asyncpf": false, +- "perfctr-core": false, +- "mpx": true, +- "pbe": false, +- "avx512cd": false, +- "decodeassists": false, +- "sse4.1": true, +- "family": 6, +- "wbnoinvd": false, +- "avx512f": false, +- "msr": true, +- "mce": true, +- "mca": true, +- "xcrypt": false, +- "min-level": 13, +- "xgetbv1": true, +- "cid": false, +- "ds": false, +- "fxsr": true, +- "xsaveopt": true, +- "xtpr": false, +- "avx512vl": false, +- "avx512-vpopcntdq": false, +- "phe": false, +- "extapic": false, +- "3dnowprefetch": false, +- "avx512vbmi2": false, +- "cr8legacy": true, +- "stibp": false, +- "xcrypt-en": false, +- "pn": false, +- "rsba": false, +- "dca": false, +- "vendor": "AuthenticAMD", +- "pku": true, +- "smx": false, +- "cmp-legacy": false, +- "avx512-4fmaps": false, +- "vmcb-clean": false, +- "hle": false, +- "3dnowext": true, +- "amd-no-ssb": false, +- "npt": true, +- "rdctl-no": false, +- "clwb": true, +- "lbrv": false, +- "adx": true, +- "ss": true, +- "pni": true, +- "svm-lock": false, +- "smep": true, +- "smap": true, +- "pfthreshold": false, +- "x2apic": false, +- "avx512vbmi": false, +- "avx512vnni": false, +- "flushbyasid": false, +- "f16c": false, +- "ace2-en": false, +- "pae": true, +- "pat": true, +- "sse": true, +- "phe-en": false, +- "kvm-nopiodelay": false, +- "tm": false, +- "kvmclock-stable-bit": false, +- "hypervisor": true, +- "mds-no": false, +- "pcommit": true, +- "syscall": true, +- "avx512dq": false, +- "svm": true, +- "invtsc": false, +- "sse2": true, +- "ssbd": false, +- "est": false, +- "avx512ifma": false, +- "tm2": false, +- "kvm-pv-eoi": false, +- "kvm-pv-ipi": false, +- "cx8": true, +- "cldemote": false, +- "kvm-mmu": false, +- "sse4.2": true, +- "pge": true, +- "avx512bitalg": false, +- "pdcm": false, +- "model": 6, +- "movbe": true, +- "nrip-save": false, +- "ssse3": true, +- "sse4a": true, +- "invpcid": false, +- "pdpe1gb": true, +- "tsc-deadline": false, +- "skip-l1dfl-vmentry": false, +- "fma": false, +- "cx16": true, +- "de": true, +- "stepping": 3, +- "xsave": true, +- "clflush": true, +- "skinit": false, +- "tsc": true, +- "tce": false, +- "fpu": true, +- "ds-cpl": false, +- "ibs": false, +- "fma4": false, +- "la57": true, +- "osvw": false, +- "apic": true, +- "pmm": false, +- "spec-ctrl": false, +- "tsc-adjust": false, +- "kvm-steal-time": false, +- "kvmclock": false, +- "lwp": false, +- "amd-ssbd": false, +- "xop": false, +- "ibpb": false, +- "avx": false, +- "movdiri": false, +- "acpi": true, +- "avx512bw": false, +- "ace2": false, +- "fsgsbase": true, +- "ht": false, +- "nx": true, +- "pclmulqdq": true, +- "mmxext": true, +- "popcnt": true, +- "vaes": false, +- "movdir64b": false, +- "xsaves": false, +- "lm": true, +- "umip": false, +- "pse": true, +- "avx2": false, +- "sep": true, +- "virt-ssbd": false, +- "nodeid-msr": false, +- "md-clear": false, +- "misalignsse": false, +- "min-xlevel": 2147483658, +- "bmi1": true, +- "bmi2": true, +- "kvm-pv-unhalt": false, +- "tsc-scale": false, +- "topoext": false, +- "clflushopt": true, +- "monitor": true, +- "avx512er": false, +- "pmm-en": false, +- "pcid": false, +- "arch-capabilities": false, +- "3dnow": true, +- "erms": true, +- "lahf-lm": true, +- "vpclmulqdq": false, +- "fxsr-opt": false, +- "xstore": false, +- "rtm": false, +- "kvm-hint-dedicated": false, +- "lmce": false, +- "perfctr-nb": false, +- "rdrand": true, +- "rdseed": false, +- "avx512-4vnniw": false, +- "vme": false, +- "vmx": false, +- "dtes64": false, +- "mtrr": true, +- "rdtscp": true, +- "pse36": true, +- "kvm-pv-tlb-flush": false, +- "tbm": false, +- "wdt": false, +- "model-id": "QEMU TCG CPU version 2.5+", +- "sha-ni": false, +- "abm": true, +- "avx512pf": false, +- "xstore-en": false +- } +- } +- }, +- "id": "libvirt-4" +-} +- +-{ +- "return": { +- "model": { +- "name": "base", +- "props": { +- "phys-bits": 0, +- "core-id": -1, +- "xlevel": 2147483658, +- "cmov": true, +- "ia64": false, +- "ssb-no": false, +- "aes": true, +- "mmx": true, +- "rdpid": false, +- "arat": true, +- "gfni": false, +- "ibrs-all": false, +- "pause-filter": false, +- "xsavec": false, +- "intel-pt": false, +- "hv-frequencies": false, +- "tsc-frequency": 0, +- "xd": true, +- "x-intel-pt-auto-level": true, +- "hv-vendor-id": "", +- "kvm-asyncpf": false, +- "kvm_asyncpf": false, +- "perfctr_core": false, +- "perfctr-core": false, +- "mpx": true, +- "pbe": false, +- "decodeassists": false, +- "avx512cd": false, +- "sse4_1": true, +- "sse4.1": true, +- "sse4-1": true, +- "family": 6, +- "legacy-cache": true, +- "host-phys-bits-limit": 0, +- "vmware-cpuid-freq": true, +- "wbnoinvd": false, +- "avx512f": false, +- "msr": true, +- "mce": true, +- "mca": true, +- "hv-runtime": false, +- "xcrypt": false, +- "thread-id": -1, +- "min-level": 13, +- "xgetbv1": true, +- "cid": false, +- "hv-relaxed": false, +- "hv-crash": false, +- "ds": false, +- "fxsr": true, +- "xsaveopt": true, +- "xtpr": false, +- "hv-evmcs": false, +- "avx512vl": false, +- "avx512-vpopcntdq": false, +- "phe": false, +- "extapic": false, +- "3dnowprefetch": false, +- "avx512vbmi2": false, +- "cr8legacy": true, +- "stibp": false, +- "cpuid-0xb": true, +- "xcrypt-en": false, +- "kvm_pv_eoi": false, +- "apic-id": 4294967295, +- "rsba": false, +- "pn": false, +- "dca": false, +- "vendor": "AuthenticAMD", +- "hv-ipi": false, +- "pku": true, +- "smx": false, +- "cmp_legacy": false, +- "cmp-legacy": false, +- "node-id": -1, +- "avx512-4fmaps": false, +- "vmcb_clean": false, +- "vmcb-clean": false, +- "3dnowext": true, +- "amd-no-ssb": false, +- "hle": false, +- "npt": true, +- "rdctl-no": false, +- "memory": "/machine/unattached/system[0]", +- "clwb": true, +- "lbrv": false, +- "adx": true, +- "ss": true, +- "pni": true, +- "svm_lock": false, +- "svm-lock": false, +- "pfthreshold": false, +- "smep": true, +- "smap": true, +- "x2apic": false, +- "avx512vbmi": false, +- "avx512vnni": false, +- "hv-stimer": false, +- "x-hv-synic-kvm-only": false, +- "i64": true, +- "flushbyasid": false, +- "f16c": false, +- "ace2-en": false, +- "pat": true, +- "pae": true, +- "sse": true, +- "phe-en": false, +- "kvm_nopiodelay": false, +- "kvm-nopiodelay": false, +- "tm": false, +- "kvmclock-stable-bit": false, +- "hypervisor": true, +- "socket-id": -1, +- "mds-no": false, +- "pcommit": true, +- "syscall": true, +- "level": 13, +- "avx512dq": false, +- "x-migrate-smi-count": true, +- "svm": true, +- "full-cpuid-auto-level": true, +- "hv-reset": false, +- "invtsc": false, +- "sse3": true, +- "sse2": true, +- "ssbd": false, +- "est": false, +- "avx512ifma": false, +- "tm2": false, +- "kvm-pv-ipi": false, +- "kvm-pv-eoi": false, +- "cx8": true, +- "cldemote": false, +- "hv-reenlightenment": false, +- "kvm_mmu": false, +- "kvm-mmu": false, +- "sse4_2": true, +- "sse4.2": true, +- "sse4-2": true, +- "pge": true, +- "fill-mtrr-mask": true, +- "avx512bitalg": false, +- "nodeid_msr": false, +- "pdcm": false, +- "movbe": true, +- "model": 6, +- "nrip_save": false, +- "nrip-save": false, +- "kvm_pv_unhalt": false, +- "ssse3": true, +- "sse4a": true, +- "invpcid": false, +- "pdpe1gb": true, +- "tsc-deadline": false, +- "skip-l1dfl-vmentry": false, +- "fma": false, +- "cx16": true, +- "de": true, +- "enforce": false, +- "stepping": 3, +- "xsave": true, +- "clflush": true, +- "skinit": false, +- "tsc": true, +- "tce": false, +- "fpu": true, +- "ibs": false, +- "ds_cpl": false, +- "ds-cpl": false, +- "host-phys-bits": false, +- "fma4": false, +- "la57": true, +- "osvw": false, +- "check": true, +- "hv-spinlocks": -1, +- "pmm": false, +- "pmu": false, +- "apic": true, +- "spec-ctrl": false, +- "min-xlevel2": 0, +- "tsc-adjust": false, +- "tsc_adjust": false, +- "kvm-steal-time": false, +- "kvm_steal_time": false, +- "kvmclock": false, +- "l3-cache": true, +- "lwp": false, +- "amd-ssbd": false, +- "ibpb": false, +- "xop": false, +- "avx": false, +- "movdiri": false, +- "ace2": false, +- "avx512bw": false, +- "acpi": true, +- "hv-vapic": false, +- "fsgsbase": true, +- "ht": false, +- "nx": true, +- "pclmulqdq": true, +- "mmxext": true, +- "vaes": false, +- "popcnt": true, +- "xsaves": false, +- "movdir64b": false, +- "tcg-cpuid": true, +- "lm": true, +- "umip": false, +- "pse": true, +- "avx2": false, +- "sep": true, +- "pclmuldq": true, +- "virt-ssbd": false, +- "x-hv-max-vps": -1, +- "nodeid-msr": false, +- "md-clear": false, +- "kvm": true, +- "misalignsse": false, +- "min-xlevel": 2147483658, +- "kvm-pv-unhalt": false, +- "bmi2": true, +- "bmi1": true, +- "realized": false, +- "tsc_scale": false, +- "tsc-scale": false, +- "topoext": false, +- "hv-vpindex": false, +- "xlevel2": 0, +- "clflushopt": true, +- "kvm-no-smi-migration": false, +- "monitor": true, +- "avx512er": false, +- "pmm-en": false, +- "pcid": false, +- "arch-capabilities": false, +- "3dnow": true, +- "erms": true, +- "lahf-lm": true, +- "lahf_lm": true, +- "vpclmulqdq": false, +- "fxsr-opt": false, +- "hv-synic": false, +- "xstore": false, +- "fxsr_opt": false, +- "kvm-hint-dedicated": false, +- "rtm": false, +- "lmce": false, +- "hv-time": false, +- "perfctr-nb": false, +- "perfctr_nb": false, +- "ffxsr": false, +- "hv-tlbflush": false, +- "rdrand": true, +- "rdseed": false, +- "avx512-4vnniw": false, +- "vmx": false, +- "vme": false, +- "dtes64": false, +- "mtrr": true, +- "rdtscp": true, +- "pse36": true, +- "kvm-pv-tlb-flush": false, +- "tbm": false, +- "wdt": false, +- "pause_filter": false, +- "sha-ni": false, +- "model-id": "QEMU TCG CPU version 2.5+", +- "abm": true, +- "avx512pf": false, +- "xstore-en": false +- } +- } +- }, +- "id": "libvirt-4" +-} +- + { + "execute": "query-cpu-model-expansion", + "arguments": { +@@ -24197,7 +22730,7 @@ + } + } + }, +- "id": "libvirt-5" ++ "id": "libvirt-4" + } + + { +@@ -24403,494 +22936,5 @@ + } + } + }, +- "id": "libvirt-5" +-} +- +-{ +- "execute": "query-cpu-model-expansion", +- "arguments": { +- "type": "full", +- "model": { +- "name": "base", +- "props": { +- "cmov": true, +- "ia64": false, +- "ssb-no": false, +- "aes": true, +- "mmx": true, +- "rdpid": false, +- "arat": true, +- "gfni": false, +- "ibrs-all": false, +- "pause-filter": false, +- "xsavec": false, +- "intel-pt": false, +- "kvm-asyncpf": false, +- "perfctr-core": false, +- "mpx": true, +- "pbe": false, +- "avx512cd": false, +- "decodeassists": false, +- "sse4.1": true, +- "family": 6, +- "wbnoinvd": false, +- "avx512f": false, +- "msr": true, +- "mce": true, +- "mca": true, +- "xcrypt": false, +- "min-level": 13, +- "xgetbv1": true, +- "cid": false, +- "ds": false, +- "fxsr": true, +- "xsaveopt": true, +- "xtpr": false, +- "avx512vl": false, +- "avx512-vpopcntdq": false, +- "phe": false, +- "extapic": false, +- "3dnowprefetch": false, +- "avx512vbmi2": false, +- "cr8legacy": true, +- "stibp": false, +- "xcrypt-en": false, +- "pn": false, +- "rsba": false, +- "dca": false, +- "vendor": "AuthenticAMD", +- "pku": true, +- "smx": false, +- "cmp-legacy": false, +- "avx512-4fmaps": false, +- "vmcb-clean": false, +- "hle": false, +- "3dnowext": true, +- "amd-no-ssb": false, +- "npt": true, +- "rdctl-no": false, +- "clwb": true, +- "lbrv": false, +- "adx": true, +- "ss": true, +- "pni": true, +- "svm-lock": false, +- "smep": true, +- "smap": true, +- "pfthreshold": false, +- "x2apic": false, +- "avx512vbmi": false, +- "avx512vnni": false, +- "flushbyasid": false, +- "f16c": false, +- "ace2-en": false, +- "pae": true, +- "pat": true, +- "sse": true, +- "phe-en": false, +- "kvm-nopiodelay": false, +- "tm": false, +- "kvmclock-stable-bit": false, +- "hypervisor": true, +- "mds-no": false, +- "pcommit": true, +- "syscall": true, +- "avx512dq": false, +- "svm": true, +- "invtsc": false, +- "sse2": true, +- "ssbd": false, +- "est": false, +- "avx512ifma": false, +- "tm2": false, +- "kvm-pv-eoi": false, +- "kvm-pv-ipi": false, +- "cx8": true, +- "cldemote": false, +- "kvm-mmu": false, +- "sse4.2": true, +- "pge": true, +- "avx512bitalg": false, +- "pdcm": false, +- "model": 6, +- "movbe": true, +- "nrip-save": false, +- "ssse3": true, +- "sse4a": true, +- "invpcid": false, +- "pdpe1gb": true, +- "tsc-deadline": false, +- "skip-l1dfl-vmentry": false, +- "fma": false, +- "cx16": true, +- "de": true, +- "stepping": 3, +- "xsave": true, +- "clflush": true, +- "skinit": false, +- "tsc": true, +- "tce": false, +- "fpu": true, +- "ds-cpl": false, +- "ibs": false, +- "fma4": false, +- "la57": true, +- "osvw": false, +- "apic": true, +- "pmm": false, +- "spec-ctrl": false, +- "tsc-adjust": false, +- "kvm-steal-time": false, +- "kvmclock": false, +- "lwp": false, +- "amd-ssbd": false, +- "xop": false, +- "ibpb": false, +- "avx": false, +- "movdiri": false, +- "acpi": true, +- "avx512bw": false, +- "ace2": false, +- "fsgsbase": true, +- "ht": false, +- "nx": true, +- "pclmulqdq": true, +- "mmxext": true, +- "popcnt": true, +- "vaes": false, +- "movdir64b": false, +- "xsaves": false, +- "lm": true, +- "umip": false, +- "pse": true, +- "avx2": false, +- "sep": true, +- "virt-ssbd": false, +- "nodeid-msr": false, +- "md-clear": false, +- "misalignsse": false, +- "min-xlevel": 2147483658, +- "bmi1": true, +- "bmi2": true, +- "kvm-pv-unhalt": false, +- "tsc-scale": false, +- "topoext": false, +- "clflushopt": true, +- "monitor": true, +- "avx512er": false, +- "pmm-en": false, +- "pcid": false, +- "arch-capabilities": false, +- "3dnow": true, +- "erms": true, +- "lahf-lm": true, +- "vpclmulqdq": false, +- "fxsr-opt": false, +- "xstore": false, +- "rtm": false, +- "kvm-hint-dedicated": false, +- "lmce": false, +- "perfctr-nb": false, +- "rdrand": true, +- "rdseed": false, +- "avx512-4vnniw": false, +- "vme": false, +- "vmx": false, +- "dtes64": false, +- "mtrr": true, +- "rdtscp": true, +- "pse36": true, +- "kvm-pv-tlb-flush": false, +- "tbm": false, +- "wdt": false, +- "model-id": "QEMU TCG CPU version 2.5+", +- "sha-ni": false, +- "abm": true, +- "avx512pf": false, +- "xstore-en": false +- } +- } +- }, +- "id": "libvirt-6" +-} +- +-{ +- "return": { +- "model": { +- "name": "base", +- "props": { +- "phys-bits": 0, +- "core-id": -1, +- "xlevel": 2147483658, +- "cmov": true, +- "ia64": false, +- "ssb-no": false, +- "aes": true, +- "mmx": true, +- "rdpid": false, +- "arat": true, +- "gfni": false, +- "ibrs-all": false, +- "pause-filter": false, +- "xsavec": false, +- "intel-pt": false, +- "hv-frequencies": false, +- "tsc-frequency": 0, +- "xd": true, +- "x-intel-pt-auto-level": true, +- "hv-vendor-id": "", +- "kvm-asyncpf": false, +- "kvm_asyncpf": false, +- "perfctr_core": false, +- "perfctr-core": false, +- "mpx": true, +- "pbe": false, +- "decodeassists": false, +- "avx512cd": false, +- "sse4_1": true, +- "sse4.1": true, +- "sse4-1": true, +- "family": 6, +- "legacy-cache": true, +- "host-phys-bits-limit": 0, +- "vmware-cpuid-freq": true, +- "wbnoinvd": false, +- "avx512f": false, +- "msr": true, +- "mce": true, +- "mca": true, +- "hv-runtime": false, +- "xcrypt": false, +- "thread-id": -1, +- "min-level": 13, +- "xgetbv1": true, +- "cid": false, +- "hv-relaxed": false, +- "hv-crash": false, +- "ds": false, +- "fxsr": true, +- "xsaveopt": true, +- "xtpr": false, +- "hv-evmcs": false, +- "avx512vl": false, +- "avx512-vpopcntdq": false, +- "phe": false, +- "extapic": false, +- "3dnowprefetch": false, +- "avx512vbmi2": false, +- "cr8legacy": true, +- "stibp": false, +- "cpuid-0xb": true, +- "xcrypt-en": false, +- "kvm_pv_eoi": false, +- "apic-id": 4294967295, +- "rsba": false, +- "pn": false, +- "dca": false, +- "vendor": "AuthenticAMD", +- "hv-ipi": false, +- "pku": true, +- "smx": false, +- "cmp_legacy": false, +- "cmp-legacy": false, +- "node-id": -1, +- "avx512-4fmaps": false, +- "vmcb_clean": false, +- "vmcb-clean": false, +- "3dnowext": true, +- "amd-no-ssb": false, +- "hle": false, +- "npt": true, +- "rdctl-no": false, +- "memory": "/machine/unattached/system[0]", +- "clwb": true, +- "lbrv": false, +- "adx": true, +- "ss": true, +- "pni": true, +- "svm_lock": false, +- "svm-lock": false, +- "pfthreshold": false, +- "smep": true, +- "smap": true, +- "x2apic": false, +- "avx512vbmi": false, +- "avx512vnni": false, +- "hv-stimer": false, +- "x-hv-synic-kvm-only": false, +- "i64": true, +- "flushbyasid": false, +- "f16c": false, +- "ace2-en": false, +- "pat": true, +- "pae": true, +- "sse": true, +- "phe-en": false, +- "kvm_nopiodelay": false, +- "kvm-nopiodelay": false, +- "tm": false, +- "kvmclock-stable-bit": false, +- "hypervisor": true, +- "socket-id": -1, +- "mds-no": false, +- "pcommit": true, +- "syscall": true, +- "level": 13, +- "avx512dq": false, +- "x-migrate-smi-count": true, +- "svm": true, +- "full-cpuid-auto-level": true, +- "hv-reset": false, +- "invtsc": false, +- "sse3": true, +- "sse2": true, +- "ssbd": false, +- "est": false, +- "avx512ifma": false, +- "tm2": false, +- "kvm-pv-ipi": false, +- "kvm-pv-eoi": false, +- "cx8": true, +- "cldemote": false, +- "hv-reenlightenment": false, +- "kvm_mmu": false, +- "kvm-mmu": false, +- "sse4_2": true, +- "sse4.2": true, +- "sse4-2": true, +- "pge": true, +- "fill-mtrr-mask": true, +- "avx512bitalg": false, +- "nodeid_msr": false, +- "pdcm": false, +- "movbe": true, +- "model": 6, +- "nrip_save": false, +- "nrip-save": false, +- "kvm_pv_unhalt": false, +- "ssse3": true, +- "sse4a": true, +- "invpcid": false, +- "pdpe1gb": true, +- "tsc-deadline": false, +- "skip-l1dfl-vmentry": false, +- "fma": false, +- "cx16": true, +- "de": true, +- "enforce": false, +- "stepping": 3, +- "xsave": true, +- "clflush": true, +- "skinit": false, +- "tsc": true, +- "tce": false, +- "fpu": true, +- "ibs": false, +- "ds_cpl": false, +- "ds-cpl": false, +- "host-phys-bits": false, +- "fma4": false, +- "la57": true, +- "osvw": false, +- "check": true, +- "hv-spinlocks": -1, +- "pmm": false, +- "pmu": false, +- "apic": true, +- "spec-ctrl": false, +- "min-xlevel2": 0, +- "tsc-adjust": false, +- "tsc_adjust": false, +- "kvm-steal-time": false, +- "kvm_steal_time": false, +- "kvmclock": false, +- "l3-cache": true, +- "lwp": false, +- "amd-ssbd": false, +- "ibpb": false, +- "xop": false, +- "avx": false, +- "movdiri": false, +- "ace2": false, +- "avx512bw": false, +- "acpi": true, +- "hv-vapic": false, +- "fsgsbase": true, +- "ht": false, +- "nx": true, +- "pclmulqdq": true, +- "mmxext": true, +- "vaes": false, +- "popcnt": true, +- "xsaves": false, +- "movdir64b": false, +- "tcg-cpuid": true, +- "lm": true, +- "umip": false, +- "pse": true, +- "avx2": false, +- "sep": true, +- "pclmuldq": true, +- "virt-ssbd": false, +- "x-hv-max-vps": -1, +- "nodeid-msr": false, +- "md-clear": false, +- "kvm": true, +- "misalignsse": false, +- "min-xlevel": 2147483658, +- "kvm-pv-unhalt": false, +- "bmi2": true, +- "bmi1": true, +- "realized": false, +- "tsc_scale": false, +- "tsc-scale": false, +- "topoext": false, +- "hv-vpindex": false, +- "xlevel2": 0, +- "clflushopt": true, +- "kvm-no-smi-migration": false, +- "monitor": true, +- "avx512er": false, +- "pmm-en": false, +- "pcid": false, +- "arch-capabilities": false, +- "3dnow": true, +- "erms": true, +- "lahf-lm": true, +- "lahf_lm": true, +- "vpclmulqdq": false, +- "fxsr-opt": false, +- "hv-synic": false, +- "xstore": false, +- "fxsr_opt": false, +- "kvm-hint-dedicated": false, +- "rtm": false, +- "lmce": false, +- "hv-time": false, +- "perfctr-nb": false, +- "perfctr_nb": false, +- "ffxsr": false, +- "hv-tlbflush": false, +- "rdrand": true, +- "rdseed": false, +- "avx512-4vnniw": false, +- "vmx": false, +- "vme": false, +- "dtes64": false, +- "mtrr": true, +- "rdtscp": true, +- "pse36": true, +- "kvm-pv-tlb-flush": false, +- "tbm": false, +- "wdt": false, +- "pause_filter": false, +- "sha-ni": false, +- "model-id": "QEMU TCG CPU version 2.5+", +- "abm": true, +- "avx512pf": false, +- "xstore-en": false +- } +- } +- }, +- "id": "libvirt-6" ++ "id": "libvirt-4" + } +diff --git a/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml +index 9245641df8..33de2ed5a1 100644 +--- a/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml +@@ -219,13 +219,10 @@ + + 4000050 + 0 +- 473743 ++ 424759 + v4.0.0-1173-g9c70209b63 + x86_64 + +- +- +- + + + +@@ -238,44 +235,27 @@ + + + +- +- +- +- +- + +- +- + + + +- + +- ++ + +- + +- +- +- + + + + + +- + +- + + + +- +- + + + + +- + + + +@@ -284,94 +264,67 @@ + + + +- + +- +- +- + ++ + + +- + + +- + +- + +- + ++ + + +- + + +- + + + + + +- + +- + + ++ + + + +- +- +- + + + +- + ++ + + +- + + + + +- + + + +- + +- + +- +- + +- + + + + + +- + ++ + + +- +- + +- + +- + +- + +- + +- + +- ++ + +- + + + +@@ -381,7 +334,6 @@ + + + +- + + + +@@ -389,70 +341,51 @@ + + + +- +- + +- ++ + + + +- +- +- +- + ++ + +- + +- + +- + +- + + +- + ++ + + +- +- + +- ++ ++ + + + + + +- + +- ++ + +- ++ + + + + + +- + +- + + +- + + +- +- + +- +- ++ ++ + + +- +- + +- + + + +@@ -461,25 +394,18 @@ + + + +- + + +- + +- +- + ++ + +- + +- +- +- + + + +- + ++ + + + +@@ -487,17 +413,13 @@ + + + +- +- + ++ + + + + + +- +- +- + + + +@@ -510,44 +432,27 @@ + + + +- +- +- +- +- + +- +- + + + +- + +- ++ + +- + +- +- +- + + + + + +- + +- + + + +- +- + + + + +- + + + +@@ -556,94 +461,67 @@ + + + +- + +- +- +- + ++ + + +- + + +- + +- + +- + ++ + + +- + + +- + + + + + +- + +- + + ++ + + + +- +- +- + + + +- + ++ + + +- + + + + +- + + + +- + +- + +- +- + +- + + + + + +- + ++ + + +- +- + +- + +- + +- + +- + +- + +- ++ + +- + + + +@@ -653,7 +531,6 @@ + + + +- + + + +@@ -661,70 +538,51 @@ + + + +- +- + +- ++ + + + +- +- +- +- + ++ + +- + +- + +- + +- + + +- + ++ + + +- +- + +- ++ ++ + + + + + +- + +- ++ + +- ++ + + + + + +- + +- + + +- + + +- +- + +- +- ++ ++ + + +- +- + +- + + + +@@ -733,25 +591,18 @@ + + + +- + + +- + +- +- + ++ + +- + +- +- +- + + + +- + ++ + + + +@@ -759,9 +610,8 @@ + + + +- +- + ++ + + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu-Don-t-use-mem-prealloc-among-with-.prealloc-yes.patch b/SOURCES/libvirt-qemu-Don-t-use-mem-prealloc-among-with-.prealloc-yes.patch new file mode 100644 index 0000000..9022eec --- /dev/null +++ b/SOURCES/libvirt-qemu-Don-t-use-mem-prealloc-among-with-.prealloc-yes.patch @@ -0,0 +1,200 @@ +From af079d99de7c556c3b9bb10037dae90e0f23f38a Mon Sep 17 00:00:00 2001 +Message-Id: +From: Michal Privoznik +Date: Tue, 18 Dec 2018 11:47:36 +0100 +Subject: [PATCH] qemu: Don't use -mem-prealloc among with .prealloc=yes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +https://bugzilla.redhat.com/show_bug.cgi?id=1624223 + +There are two ways to request memory preallocation on cmd line: +-mem-prealloc and .prealloc attribute for a memory-backend-file. +However, as it turns out it's not safe to use both at the same +time. If -mem-prealloc is used then qemu will fully allocate the +memory (this is done by actually touching every page that has +been allocated). Then, if .prealloc=yes is specified, +mbind(flags = MPOL_MF_STRICT | MPOL_MF_MOVE) is called which: + +a) has to (possibly) move the memory to a different NUMA node, +b) can have no effect when hugepages are in play (thus ignoring user +request to place memory on desired NUMA nodes). + +Prefer -mem-prealloc as it is more backward compatible +compared to switching to "-numa node,memdev= + -object +memory-backend-file". + +Signed-off-by: Michal Privoznik +Reviewed-by: John Ferlan +(cherry picked from commit c658764decf357ef2a064f09235fb6b8bd027f8b) +Signed-off-by: Michal Privoznik + +Conflicts: +src/qemu/qemu_command.c: +src/qemu/qemu_domain.c: +src/qemu/qemu_domain.h: Context mostly, the upstream code + diverged. + +Signed-off-by: Michal Privoznik +Message-Id: <37771aafbb9d1855721efde7ade34c7b98fb1fc7.1545129996.git.mprivozn@redhat.com> +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_command.c | 26 ++++++++++++------- + src/qemu/qemu_domain.c | 7 +++++ + src/qemu/qemu_domain.h | 3 +++ + .../hugepages-numa-default-dimm.args | 2 +- + 4 files changed, 28 insertions(+), 10 deletions(-) + +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index fa2b904239..7ffc4358e3 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -3185,11 +3185,13 @@ qemuBuildMemoryBackendProps(virJSONValuePtr *backendProps, + if (useHugepage) { + if (qemuGetDomainHupageMemPath(def, cfg, pagesize, &memPath) < 0) + goto cleanup; +- prealloc = true; ++ if (!priv->memPrealloc) ++ prealloc = true; + } else if (mem->nvdimmPath) { + if (VIR_STRDUP(memPath, mem->nvdimmPath) < 0) + goto cleanup; +- prealloc = true; ++ if (!priv->memPrealloc) ++ prealloc = true; + } else { + /* We can have both pagesize and mem source. If that's the case, + * prefer hugepages as those are more specific. */ +@@ -7603,7 +7605,8 @@ qemuBuildSmpCommandLine(virCommandPtr cmd, + static int + qemuBuildMemPathStr(virQEMUDriverConfigPtr cfg, + const virDomainDef *def, +- virCommandPtr cmd) ++ virCommandPtr cmd, ++ qemuDomainObjPrivatePtr priv) + { + const long system_page_size = virGetSystemPageSizeKB(); + char *mem_path = NULL; +@@ -7624,8 +7627,10 @@ qemuBuildMemPathStr(virQEMUDriverConfigPtr cfg, + if (qemuGetDomainHupageMemPath(def, cfg, def->mem.hugepages[0].size, &mem_path) < 0) + return -1; + +- if (def->mem.allocation != VIR_DOMAIN_MEMORY_ALLOCATION_IMMEDIATE) ++ if (def->mem.allocation != VIR_DOMAIN_MEMORY_ALLOCATION_IMMEDIATE) { + virCommandAddArgList(cmd, "-mem-prealloc", NULL); ++ priv->memPrealloc = true; ++ } + + virCommandAddArgList(cmd, "-mem-path", mem_path, NULL); + VIR_FREE(mem_path); +@@ -7638,7 +7643,8 @@ static int + qemuBuildMemCommandLine(virCommandPtr cmd, + virQEMUDriverConfigPtr cfg, + const virDomainDef *def, +- virQEMUCapsPtr qemuCaps) ++ virQEMUCapsPtr qemuCaps, ++ qemuDomainObjPrivatePtr priv) + { + if (qemuDomainDefValidateMemoryHotplug(def, qemuCaps, NULL) < 0) + return -1; +@@ -7657,15 +7663,17 @@ qemuBuildMemCommandLine(virCommandPtr cmd, + virDomainDefGetMemoryInitial(def) / 1024); + } + +- if (def->mem.allocation == VIR_DOMAIN_MEMORY_ALLOCATION_IMMEDIATE) ++ if (def->mem.allocation == VIR_DOMAIN_MEMORY_ALLOCATION_IMMEDIATE) { + virCommandAddArgList(cmd, "-mem-prealloc", NULL); ++ priv->memPrealloc = true; ++ } + + /* + * Add '-mem-path' (and '-mem-prealloc') parameter here if + * the hugepages and no numa node is specified. + */ + if (!virDomainNumaGetNodeCount(def->numa) && +- qemuBuildMemPathStr(cfg, def, cmd) < 0) ++ qemuBuildMemPathStr(cfg, def, cmd, priv) < 0) + return -1; + + if (def->mem.locked && !virQEMUCapsGet(qemuCaps, QEMU_CAPS_REALTIME_MLOCK)) { +@@ -7772,7 +7780,7 @@ qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg, + } + + if (!needBackend && +- qemuBuildMemPathStr(cfg, def, cmd) < 0) ++ qemuBuildMemPathStr(cfg, def, cmd, priv) < 0) + goto cleanup; + + for (i = 0; i < ncells; i++) { +@@ -10445,7 +10453,7 @@ qemuBuildCommandLine(virQEMUDriverPtr driver, + if (!migrateURI && !snapshot && qemuDomainAlignMemorySizes(def) < 0) + goto error; + +- if (qemuBuildMemCommandLine(cmd, cfg, def, qemuCaps) < 0) ++ if (qemuBuildMemCommandLine(cmd, cfg, def, qemuCaps, priv) < 0) + goto error; + + if (qemuBuildSmpCommandLine(cmd, def) < 0) +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index 8604385aa2..95b84af78a 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -1936,6 +1936,8 @@ qemuDomainObjPrivateDataClear(qemuDomainObjPrivatePtr priv) + VIR_FREE(priv->libDir); + VIR_FREE(priv->channelTargetDir); + ++ priv->memPrealloc = false; ++ + /* remove automatic pinning data */ + virBitmapFree(priv->autoNodeset); + priv->autoNodeset = NULL; +@@ -2439,6 +2441,9 @@ qemuDomainObjPrivateXMLFormat(virBufferPtr buf, + + qemuDomainObjPrivateXMLFormatPR(buf, priv); + ++ if (priv->memPrealloc) ++ virBufferAddLit(buf, "\n"); ++ + if (qemuDomainObjPrivateXMLFormatBlockjobs(buf, vm) < 0) + return -1; + +@@ -2934,6 +2939,8 @@ qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt, + if (qemuDomainObjPrivateXMLParseBlockjobs(priv, ctxt) < 0) + goto error; + ++ priv->memPrealloc = virXPathBoolean("boolean(./memPrealloc)", ctxt) == 1; ++ + return 0; + + error: +diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h +index cc406e3ca0..8463a8b706 100644 +--- a/src/qemu/qemu_domain.h ++++ b/src/qemu/qemu_domain.h +@@ -367,6 +367,9 @@ struct _qemuDomainObjPrivate { + /* qemuProcessStartCPUs stores the reason for starting vCPUs here for the + * RESUME event handler to use it */ + virDomainRunningReason runningReason; ++ ++ /* true if global -mem-prealloc appears on cmd line */ ++ bool memPrealloc; + }; + + # define QEMU_DOMAIN_PRIVATE(vm) \ +diff --git a/tests/qemuxml2argvdata/hugepages-numa-default-dimm.args b/tests/qemuxml2argvdata/hugepages-numa-default-dimm.args +index 855966a137..e7294a0882 100644 +--- a/tests/qemuxml2argvdata/hugepages-numa-default-dimm.args ++++ b/tests/qemuxml2argvdata/hugepages-numa-default-dimm.args +@@ -13,7 +13,7 @@ QEMU_AUDIO_DRV=none \ + -mem-prealloc \ + -mem-path /dev/hugepages2M/libvirt/qemu/-1-fedora \ + -numa node,nodeid=0,cpus=0-1,mem=1024 \ +--object memory-backend-file,id=memdimm0,prealloc=yes,\ ++-object memory-backend-file,id=memdimm0,\ + mem-path=/dev/hugepages1G/libvirt/qemu/-1-fedora,size=1073741824,\ + host-nodes=1-3,policy=bind \ + -device pc-dimm,node=0,memdev=memdimm0,id=dimm0,slot=0 \ +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu-Drop-MSR-features-from-host-model-with-old-QEMU.patch b/SOURCES/libvirt-qemu-Drop-MSR-features-from-host-model-with-old-QEMU.patch new file mode 100644 index 0000000..da33e42 --- /dev/null +++ b/SOURCES/libvirt-qemu-Drop-MSR-features-from-host-model-with-old-QEMU.patch @@ -0,0 +1,65 @@ +From 360c3ee173809822e9363ec210a8197b66511a03 Mon Sep 17 00:00:00 2001 +Message-Id: <360c3ee173809822e9363ec210a8197b66511a03@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:26:12 +0200 +Subject: [PATCH] qemu: Drop MSR features from host-model with old QEMU +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +With QEMU versions which lack "unavailable-features" we use CPUID based +detection of features which were enabled or disabled once QEMU starts. +Thus using MSR features with host-model would result in all of them +being marked as disabled in the active domain definition even though +QEMU did not actually disable them. + +Let's make sure we add MSR features to host-model only when +"unavailable-features" property is supported by QEMU. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 2674d00ed484091faf2b6e6b1efe58ee9a72b96b) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Conflicts: + tests/domaincapsschemadata/qemu_3.1.0.x86_64.xml + tests/domaincapsschemadata/qemu_4.0.0.x86_64.xml + - missing + +Signed-off-by: Jiri Denemark +Message-Id: +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_capabilities.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index 4be0ec305f..fbfe74d45b 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -3114,6 +3114,21 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps, + goto error; + } + ++ if (ARCH_IS_X86(qemuCaps->arch) && ++ !virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_UNAVAILABLE_FEATURES)) { ++ if (cpu && ++ virCPUDefFilterFeatures(cpu, virCPUx86FeatureFilterDropMSR, NULL) < 0) ++ goto error; ++ ++ if (migCPU && ++ virCPUDefFilterFeatures(migCPU, virCPUx86FeatureFilterDropMSR, NULL) < 0) ++ goto error; ++ ++ if (fullCPU && ++ virCPUDefFilterFeatures(fullCPU, virCPUx86FeatureFilterDropMSR, NULL) < 0) ++ goto error; ++ } ++ + virQEMUCapsSetHostModel(qemuCaps, type, cpu, migCPU, fullCPU); + + cleanup: +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu-Drop-cleanup-label-from-qemuProcessInitCpuAffinity.patch b/SOURCES/libvirt-qemu-Drop-cleanup-label-from-qemuProcessInitCpuAffinity.patch new file mode 100644 index 0000000..1923e7f --- /dev/null +++ b/SOURCES/libvirt-qemu-Drop-cleanup-label-from-qemuProcessInitCpuAffinity.patch @@ -0,0 +1,74 @@ +From fa5cf4f38c5310ac24adf2011777c21827c3a727 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Andrea Bolognani +Date: Tue, 11 Jun 2019 10:55:05 +0200 +Subject: [PATCH] qemu: Drop cleanup label from qemuProcessInitCpuAffinity() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We're using VIR_AUTOPTR() for everything now, plus the +cleanup section was not doing anything useful anyway. + +Signed-off-by: Andrea Bolognani +Reviewed-by: Ján Tomko +(cherry picked from commit de563ebcf9d72e5815933a0d715aa9c462bf50cc) + +https://bugzilla.redhat.com/show_bug.cgi?id=1716908 + +Signed-off-by: Andrea Bolognani +Message-Id: <20190611085506.12564-6-abologna@redhat.com> +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_process.c | 18 ++++++++---------- + 1 file changed, 8 insertions(+), 10 deletions(-) + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 0b2b7964e1..d0945b9c65 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -2356,7 +2356,6 @@ qemuProcessGetAllCpuAffinity(virBitmapPtr *cpumapRet) + static int + qemuProcessInitCpuAffinity(virDomainObjPtr vm) + { +- int ret = -1; + VIR_AUTOPTR(virBitmap) cpumapToSet = NULL; + virDomainNumatuneMemMode mem_mode; + qemuDomainObjPrivatePtr priv = vm->privateData; +@@ -2387,25 +2386,24 @@ qemuProcessInitCpuAffinity(virDomainObjPtr vm) + priv->autoNodeset, + &nodeset, + -1) < 0) +- goto cleanup; ++ return -1; + + if (virNumaNodesetToCPUset(nodeset, &cpumapToSet) < 0) +- goto cleanup; ++ return -1; + } else if (vm->def->cputune.emulatorpin) { + if (virBitmapCopy(cpumapToSet, vm->def->cputune.emulatorpin) < 0) +- goto cleanup; ++ return -1; + } else { + if (qemuProcessGetAllCpuAffinity(&cpumapToSet) < 0) +- goto cleanup; ++ return -1; + } + + if (cpumapToSet && +- virProcessSetAffinity(vm->pid, cpumapToSet) < 0) +- goto cleanup; ++ virProcessSetAffinity(vm->pid, cpumapToSet) < 0) { ++ return -1; ++ } + +- ret = 0; +- cleanup: +- return ret; ++ return 0; + } + + /* set link states to down on interfaces at qemu start */ +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu-Drop-user-prefix-for-guestfwd-netdev.patch b/SOURCES/libvirt-qemu-Drop-user-prefix-for-guestfwd-netdev.patch new file mode 100644 index 0000000..d953baa --- /dev/null +++ b/SOURCES/libvirt-qemu-Drop-user-prefix-for-guestfwd-netdev.patch @@ -0,0 +1,65 @@ +From 582d5e7db59ec7897dc0a2a78823860963be9855 Mon Sep 17 00:00:00 2001 +Message-Id: <582d5e7db59ec7897dc0a2a78823860963be9855@dist-git> +From: Michal Privoznik +Date: Thu, 27 Jun 2019 14:44:45 +0200 +Subject: [PATCH] qemu: Drop "user-" prefix for guestfwd netdev + +Introduced by d86c876a66e3. + +There is no real need to have "user-" prefix for chardev. + +Signed-off-by: Michal Privoznik +Reviewed-by: John Ferlan +(cherry picked from commit 18b8f677456714f04b87525602fa2b62cd4224e1) + +https://bugzilla.redhat.com/show_bug.cgi?id=1624204 + +Signed-off-by: Michal Privoznik +Message-Id: +Reviewed-by: Jiri Denemark +--- + src/qemu/qemu_command.c | 2 +- + tests/qemuxml2argvdata/channel-guestfwd.args | 2 +- + tests/qemuxml2argvdata/name-escape.args | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index b5c0588e3c..2b885e98dd 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -10737,7 +10737,7 @@ qemuBuildChannelChrDeviceStr(char **deviceStr, + port = virSocketAddrGetPort(chr->target.addr); + + if (virAsprintf(deviceStr, +- "user,guestfwd=tcp:%s:%i-chardev:char%s,id=user-%s", ++ "user,guestfwd=tcp:%s:%i-chardev:char%s,id=%s", + addr, port, chr->info.alias, chr->info.alias) < 0) + goto cleanup; + break; +diff --git a/tests/qemuxml2argvdata/channel-guestfwd.args b/tests/qemuxml2argvdata/channel-guestfwd.args +index 6a660f7796..b4c857a6d7 100644 +--- a/tests/qemuxml2argvdata/channel-guestfwd.args ++++ b/tests/qemuxml2argvdata/channel-guestfwd.args +@@ -25,5 +25,5 @@ server,nowait \ + -drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \ + -device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \ + -chardev pipe,id=charchannel0,path=/tmp/guestfwd \ +--netdev user,guestfwd=tcp:10.0.2.1:4600-chardev:charchannel0,id=user-channel0 \ ++-netdev user,guestfwd=tcp:10.0.2.1:4600-chardev:charchannel0,id=channel0 \ + -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 +diff --git a/tests/qemuxml2argvdata/name-escape.args b/tests/qemuxml2argvdata/name-escape.args +index 382b8a1a9e..cbf594e808 100644 +--- a/tests/qemuxml2argvdata/name-escape.args ++++ b/tests/qemuxml2argvdata/name-escape.args +@@ -37,7 +37,7 @@ cert3=cert3,db=/etc/pki/nssdb,,foo,id=smartcard0,bus=ccid0.0 \ + -chardev file,id=charserial1,path=/tmp/serial.log,,foo,append=on \ + -device isa-serial,chardev=charserial1,id=serial1 \ + -chardev pipe,id=charchannel0,path=/tmp/guestfwd,,foo \ +--netdev user,guestfwd=tcp:10.0.2.1:4600-chardev:charchannel0,id=user-channel0 \ ++-netdev user,guestfwd=tcp:10.0.2.1:4600-chardev:charchannel0,id=channel0 \ + -vnc unix:/tmp/lib/domain--1-foo=1,,bar=2/vnc.sock \ + -spice unix,addr=/tmp/lib/domain--1-foo=1,,bar=2/spice.sock,gl=on,\ + rendernode=/dev/dri/foo,,bar \ +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu-Enable-PCI-multi-bus-for-S390-guests.patch b/SOURCES/libvirt-qemu-Enable-PCI-multi-bus-for-S390-guests.patch new file mode 100644 index 0000000..c0f103b --- /dev/null +++ b/SOURCES/libvirt-qemu-Enable-PCI-multi-bus-for-S390-guests.patch @@ -0,0 +1,54 @@ +From 2c4fb8fc19d1dd6ef8fafdfb1e48998020a368cd Mon Sep 17 00:00:00 2001 +Message-Id: <2c4fb8fc19d1dd6ef8fafdfb1e48998020a368cd@dist-git> +From: Yi Min Zhao +Date: Mon, 8 Apr 2019 10:57:20 +0200 +Subject: [PATCH] qemu: Enable PCI multi bus for S390 guests +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +QEMU on s390 supports PCI multibus since forever. + +Signed-off-by: Yi Min Zhao +Reviewed-by: Boris Fiuczynski +Reviewed-by: Stefan Zimmermann +Reviewed-by: Bjoern Walk +Reviewed-by: Ján Tomko +Reviewed-by: Andrea Bolognani + +(cherry picked from commit f49a5e3bf4c275ddb8a60274d6ab941b2f99f553) + +https://bugzilla.redhat.com/show_bug.cgi?id=1508149 + +Conflicts: + + * src/qemu/qemu_capabilities.c + + context + - missing fa95035bd4c9 + +Signed-off-by: Andrea Bolognani +Message-Id: <20190408085732.28684-4-abologna@redhat.com> +Reviewed-by: Laine Stump +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_capabilities.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index 8ca53abf2b..5539d168cd 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -1803,6 +1803,10 @@ bool virQEMUCapsHasPCIMultiBus(virQEMUCapsPtr qemuCaps, + return false; + } + ++ /* S390 supports PCI-multibus. */ ++ if (ARCH_IS_S390(def->os.arch)) ++ return true; ++ + /* If 'virt' supports PCI, it supports multibus. + * No extra conditions here for simplicity. + */ +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu-Fix-NULL-pointer-access-in-qemuProcessInitCpuAffinity.patch b/SOURCES/libvirt-qemu-Fix-NULL-pointer-access-in-qemuProcessInitCpuAffinity.patch new file mode 100644 index 0000000..40014e2 --- /dev/null +++ b/SOURCES/libvirt-qemu-Fix-NULL-pointer-access-in-qemuProcessInitCpuAffinity.patch @@ -0,0 +1,47 @@ +From aa0f66af1237656b217f640a9877d5f1aa31cb41 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Andrea Bolognani +Date: Tue, 11 Jun 2019 10:55:06 +0200 +Subject: [PATCH] qemu: Fix NULL pointer access in qemuProcessInitCpuAffinity() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Commit 2f2254c7f4e5 attempted to fix a memory leak by ensuring +cpumapToSet is always a freshly allocated bitmap, but regrettably +introduced a NULL pointer access while doing so, because it called +virBitmapCopy() without allocating the destination bitmap first. + +Solve the issue by using virBitmapNewCopy() instead. + +Reported-by: John Ferlan +Signed-off-by: Andrea Bolognani +Reviewed-by: Erik Skultety +Reviewed-by: John Ferlan +(cherry picked from commit a84922c09e9e1a0ca4f8fb1e8b4b1c7b55bd79e9) + +https://bugzilla.redhat.com/show_bug.cgi?id=1716908 + +Signed-off-by: Andrea Bolognani +Message-Id: <20190611085506.12564-7-abologna@redhat.com> +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_process.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index d0945b9c65..c220accfaf 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -2391,7 +2391,7 @@ qemuProcessInitCpuAffinity(virDomainObjPtr vm) + if (virNumaNodesetToCPUset(nodeset, &cpumapToSet) < 0) + return -1; + } else if (vm->def->cputune.emulatorpin) { +- if (virBitmapCopy(cpumapToSet, vm->def->cputune.emulatorpin) < 0) ++ if (!(cpumapToSet = virBitmapNewCopy(vm->def->cputune.emulatorpin))) + return -1; + } else { + if (qemuProcessGetAllCpuAffinity(&cpumapToSet) < 0) +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu-Fix-leak-in-qemuProcessInitCpuAffinity.patch b/SOURCES/libvirt-qemu-Fix-leak-in-qemuProcessInitCpuAffinity.patch new file mode 100644 index 0000000..b40ca14 --- /dev/null +++ b/SOURCES/libvirt-qemu-Fix-leak-in-qemuProcessInitCpuAffinity.patch @@ -0,0 +1,65 @@ +From 4c58428a2aebd952f7412ec1f4afa3045a09dff7 Mon Sep 17 00:00:00 2001 +Message-Id: <4c58428a2aebd952f7412ec1f4afa3045a09dff7@dist-git> +From: Andrea Bolognani +Date: Tue, 11 Jun 2019 10:55:04 +0200 +Subject: [PATCH] qemu: Fix leak in qemuProcessInitCpuAffinity() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In two out of three scenarios we are cleaning up properly after +ourselves, but commit 5f2212c062c7 has changed the remaining one +in a way that caused it to start leaking cpumapToSet. + +Refactor the logic so that cpumapToSet is always a freshly +allocated bitmap that gets cleaned up automatically thanks to +VIR_AUTOPTR(); this also allows us to remove the hostcpumap +variable. + +Reported-by: John Ferlan +Signed-off-by: Andrea Bolognani +Reviewed-by: Ján Tomko +(cherry picked from commit 2f2254c7f4e5bff52ea62a77831230bebc076bab) + +https://bugzilla.redhat.com/show_bug.cgi?id=1716908 + +Signed-off-by: Andrea Bolognani +Message-Id: <20190611085506.12564-5-abologna@redhat.com> +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_process.c | 11 +++++------ + 1 file changed, 5 insertions(+), 6 deletions(-) + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index a3b71354e1..0b2b7964e1 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -2357,8 +2357,7 @@ static int + qemuProcessInitCpuAffinity(virDomainObjPtr vm) + { + int ret = -1; +- virBitmapPtr cpumapToSet = NULL; +- VIR_AUTOPTR(virBitmap) hostcpumap = NULL; ++ VIR_AUTOPTR(virBitmap) cpumapToSet = NULL; + virDomainNumatuneMemMode mem_mode; + qemuDomainObjPrivatePtr priv = vm->privateData; + +@@ -2393,11 +2392,11 @@ qemuProcessInitCpuAffinity(virDomainObjPtr vm) + if (virNumaNodesetToCPUset(nodeset, &cpumapToSet) < 0) + goto cleanup; + } else if (vm->def->cputune.emulatorpin) { +- cpumapToSet = vm->def->cputune.emulatorpin; +- } else { +- if (qemuProcessGetAllCpuAffinity(&hostcpumap) < 0) ++ if (virBitmapCopy(cpumapToSet, vm->def->cputune.emulatorpin) < 0) ++ goto cleanup; ++ } else { ++ if (qemuProcessGetAllCpuAffinity(&cpumapToSet) < 0) + goto cleanup; +- cpumapToSet = hostcpumap; + } + + if (cpumapToSet && +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu-Fix-qemuProcessInitCpuAffinity.patch b/SOURCES/libvirt-qemu-Fix-qemuProcessInitCpuAffinity.patch new file mode 100644 index 0000000..23fd6a3 --- /dev/null +++ b/SOURCES/libvirt-qemu-Fix-qemuProcessInitCpuAffinity.patch @@ -0,0 +1,76 @@ +From 607f70a5d24d2df9c63861434c4ba1991226ee34 Mon Sep 17 00:00:00 2001 +Message-Id: <607f70a5d24d2df9c63861434c4ba1991226ee34@dist-git> +From: Andrea Bolognani +Date: Tue, 11 Jun 2019 10:55:03 +0200 +Subject: [PATCH] qemu: Fix qemuProcessInitCpuAffinity() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Ever since the feature was introduced with commit 0f8e7ae33ace, +it has contained a logic error in that it attempted to use a NUMA +node map where a CPU map was expected. + +Because of that, guests using might fail to start: + + # virsh start guest + error: Failed to start domain guest + error: cannot set CPU affinity on process 40055: Invalid argument + +This was particularly easy to trigger on POWER 8 machines, where +secondary threads always show up as offline in the host: having + + + + + +in the guest configuration, for example, would result in libvirt +trying to set the process affinity so that it would prefer +running on CPU 1, but since that's a secondary thread and thus +shows up as offline, the operation would fail, and so would +starting the guest. + +Use the newly introduced virNumaNodesetToCPUset() to convert the +NUMA node map to a CPU map, which in the example above would be +48,56,64,72,80,88 - a valid input for virProcessSetAffinity(). + +https://bugzilla.redhat.com/show_bug.cgi?id=1703661 + +Signed-off-by: Andrea Bolognani +Reviewed-by: Ján Tomko +(cherry picked from commit 5f2212c062c720716b7701fa0a5511311dc6e906) + +https://bugzilla.redhat.com/show_bug.cgi?id=1716908 + +Signed-off-by: Andrea Bolognani +Message-Id: <20190611085506.12564-4-abologna@redhat.com> +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_process.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 8b05cef80c..a3b71354e1 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -2382,11 +2382,16 @@ qemuProcessInitCpuAffinity(virDomainObjPtr vm) + if (virDomainNumaGetNodeCount(vm->def->numa) <= 1 && + virDomainNumatuneGetMode(vm->def->numa, -1, &mem_mode) == 0 && + mem_mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT) { ++ virBitmapPtr nodeset = NULL; ++ + if (virDomainNumatuneMaybeGetNodeset(vm->def->numa, + priv->autoNodeset, +- &cpumapToSet, ++ &nodeset, + -1) < 0) + goto cleanup; ++ ++ if (virNumaNodesetToCPUset(nodeset, &cpumapToSet) < 0) ++ goto cleanup; + } else if (vm->def->cputune.emulatorpin) { + cpumapToSet = vm->def->cputune.emulatorpin; + } else { +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu-Forbid-MSR-features-with-old-QEMU.patch b/SOURCES/libvirt-qemu-Forbid-MSR-features-with-old-QEMU.patch new file mode 100644 index 0000000..9370639 --- /dev/null +++ b/SOURCES/libvirt-qemu-Forbid-MSR-features-with-old-QEMU.patch @@ -0,0 +1,80 @@ +From e4f000025ac57ed4c731ffb0939f2e02bb84d856 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:26:11 +0200 +Subject: [PATCH] qemu: Forbid MSR features with old QEMU +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Without "unavailable-features" CPU property we cannot properly detect +whether a specific MSR feature we asked for (either explicitly or +implicitly via a CPU model) was disabled by QEMU for some reason. +Because this could break migration, snapshots, and save/restore +operaions, it's better to just forbid any use of MSR features with QEMU +which lacks "unavailable-features" CPU property. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 8eb4a89f5f7973f50aa8b6fa0b1a45b825dda208) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Signed-off-by: Jiri Denemark +Message-Id: +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_process.c | 30 +++++++++++++++++++++++++++--- + 1 file changed, 27 insertions(+), 3 deletions(-) + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index d147e524ee..db14d322f5 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -53,6 +53,7 @@ + #include "qemu_extdevice.h" + + #include "cpu/cpu.h" ++#include "cpu/cpu_x86.h" + #include "datatypes.h" + #include "virlog.h" + #include "virerror.h" +@@ -5226,9 +5227,32 @@ qemuProcessStartValidate(virQEMUDriverPtr driver, + if (qemuProcessStartValidateShmem(vm) < 0) + return -1; + +- if (vm->def->cpu && +- virCPUValidateFeatures(vm->def->os.arch, vm->def->cpu) < 0) +- return -1; ++ if (vm->def->cpu) { ++ if (virCPUValidateFeatures(vm->def->os.arch, vm->def->cpu) < 0) ++ return -1; ++ ++ if (ARCH_IS_X86(vm->def->os.arch) && ++ !virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_UNAVAILABLE_FEATURES)) { ++ VIR_AUTOSTRINGLIST features = NULL; ++ int n; ++ ++ if ((n = virCPUDefCheckFeatures(vm->def->cpu, ++ virCPUx86FeatureFilterSelectMSR, ++ NULL, ++ &features)) < 0) ++ return -1; ++ ++ if (n > 0) { ++ VIR_AUTOFREE(char *) str = NULL; ++ ++ str = virStringListJoin((const char **)features, ", "); ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, ++ _("Some features cannot be reliably used " ++ "with this QEMU: %s"), str); ++ return -1; ++ } ++ } ++ } + + if (qemuProcessStartValidateDisks(vm, qemuCaps) < 0) + return -1; +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu-Generate-and-use-zPCI-device-in-QEMU-command-line.patch b/SOURCES/libvirt-qemu-Generate-and-use-zPCI-device-in-QEMU-command-line.patch new file mode 100644 index 0000000..f403a75 --- /dev/null +++ b/SOURCES/libvirt-qemu-Generate-and-use-zPCI-device-in-QEMU-command-line.patch @@ -0,0 +1,834 @@ +From 37f8c26d43550986a8c6467aef4bf9d1ebe3a683 Mon Sep 17 00:00:00 2001 +Message-Id: <37f8c26d43550986a8c6467aef4bf9d1ebe3a683@dist-git> +From: Yi Min Zhao +Date: Mon, 8 Apr 2019 10:57:28 +0200 +Subject: [PATCH] qemu: Generate and use zPCI device in QEMU command line +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add new functions to generate zPCI command string and append it to +QEMU command line. And the related tests are added. + +Signed-off-by: Yi Min Zhao +Reviewed-by: Boris Fiuczynski +Reviewed-by: Stefan Zimmermann +Reviewed-by: Bjoern Walk +Reviewed-by: Ján Tomko +Reviewed-by: Andrea Bolognani + +(cherry picked from commit 9d6be3ff79b4ce7588e2842d4a6c3e713a97a7ec) + +https://bugzilla.redhat.com/show_bug.cgi?id=1508149 + +Conflicts: + + * src/qemu/qemu_command.c + + context in qemuBuildInterfaceCommandLine() + - missing 4de4e4bc9911 + + context in qemuBuildDiskCommandLine() + - missing b8936d265518 + + * tests/qemuxml2argvdata/hostdev-vfio-zpci.args + + no -boot in output + - missing caccbba64aa9 + +Changes + + * tests/qemuxml2argvdata/hostdev-vfio-zpci-autogenerate.args + tests/qemuxml2argvdata/hostdev-vfio-zpci-boundaries.args + tests/qemuxml2argvdata/hostdev-vfio-zpci-multidomain-many.args + + no -boot in output + - missing caccbba64aa9 + +Signed-off-by: Andrea Bolognani +Message-Id: <20190408085732.28684-12-abologna@redhat.com> +Reviewed-by: Laine Stump +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_command.c | 104 ++++++++++++++++++ + src/qemu/qemu_command.h | 2 + + .../disk-virtio-s390-zpci.args | 1 + + .../hostdev-vfio-zpci-autogenerate.args | 26 +++++ + .../hostdev-vfio-zpci-autogenerate.xml | 18 +++ + .../hostdev-vfio-zpci-boundaries.args | 30 +++++ + .../hostdev-vfio-zpci-boundaries.xml | 30 +++++ + .../hostdev-vfio-zpci-multidomain-many.args | 40 +++++++ + .../hostdev-vfio-zpci-multidomain-many.xml | 79 +++++++++++++ + tests/qemuxml2argvdata/hostdev-vfio-zpci.args | 2 + + tests/qemuxml2argvtest.c | 13 +++ + .../hostdev-vfio-zpci-autogenerate.xml | 34 ++++++ + .../hostdev-vfio-zpci-boundaries.xml | 48 ++++++++ + .../hostdev-vfio-zpci-multidomain-many.xml | 97 ++++++++++++++++ + tests/qemuxml2xmltest.c | 11 ++ + 15 files changed, 535 insertions(+) + create mode 100644 tests/qemuxml2argvdata/hostdev-vfio-zpci-autogenerate.args + create mode 100644 tests/qemuxml2argvdata/hostdev-vfio-zpci-autogenerate.xml + create mode 100644 tests/qemuxml2argvdata/hostdev-vfio-zpci-boundaries.args + create mode 100644 tests/qemuxml2argvdata/hostdev-vfio-zpci-boundaries.xml + create mode 100644 tests/qemuxml2argvdata/hostdev-vfio-zpci-multidomain-many.args + create mode 100644 tests/qemuxml2argvdata/hostdev-vfio-zpci-multidomain-many.xml + create mode 100644 tests/qemuxml2xmloutdata/hostdev-vfio-zpci-autogenerate.xml + create mode 100644 tests/qemuxml2xmloutdata/hostdev-vfio-zpci-boundaries.xml + create mode 100644 tests/qemuxml2xmloutdata/hostdev-vfio-zpci-multidomain-many.xml + +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index a8c832bad8..c06f396b44 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -2147,6 +2147,57 @@ qemuBuildDriveDevStr(const virDomainDef *def, + return NULL; + } + ++char * ++qemuBuildZPCIDevStr(virDomainDeviceInfoPtr dev) ++{ ++ virBuffer buf = VIR_BUFFER_INITIALIZER; ++ ++ virBufferAsprintf(&buf, ++ "zpci,uid=%u,fid=%u,target=%s,id=zpci%u", ++ dev->addr.pci.zpci.uid, ++ dev->addr.pci.zpci.fid, ++ dev->alias, ++ dev->addr.pci.zpci.uid); ++ ++ if (virBufferCheckError(&buf) < 0) { ++ virBufferFreeAndReset(&buf); ++ return NULL; ++ } ++ ++ return virBufferContentAndReset(&buf); ++} ++ ++static int ++qemuCommandAddZPCIDevice(virCommandPtr cmd, ++ virDomainDeviceInfoPtr dev) ++{ ++ char *devstr = NULL; ++ ++ virCommandAddArg(cmd, "-device"); ++ ++ if (!(devstr = qemuBuildZPCIDevStr(dev))) ++ return -1; ++ ++ virCommandAddArg(cmd, devstr); ++ ++ VIR_FREE(devstr); ++ return 0; ++} ++ ++static int ++qemuCommandAddExtDevice(virCommandPtr cmd, ++ virDomainDeviceInfoPtr dev) ++{ ++ if (dev->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI || ++ dev->addr.pci.extFlags == VIR_PCI_ADDRESS_EXTENSION_NONE) { ++ return 0; ++ } ++ ++ if (dev->addr.pci.extFlags & VIR_PCI_ADDRESS_EXTENSION_ZPCI) ++ return qemuCommandAddZPCIDevice(cmd, dev); ++ ++ return 0; ++} + + static int + qemuBulildFloppyCommandLineOptions(virCommandPtr cmd, +@@ -2267,6 +2318,9 @@ qemuBuildDiskCommandLine(virCommandPtr cmd, + bootindex) < 0) + return -1; + } else { ++ if (qemuCommandAddExtDevice(cmd, &disk->info) < 0) ++ return -1; ++ + virCommandAddArg(cmd, "-device"); + + if (!(optstr = qemuBuildDriveDevStr(def, disk, bootindex, +@@ -2466,6 +2520,9 @@ qemuBuildFSDevCommandLine(virCommandPtr cmd, + virCommandAddArg(cmd, optstr); + VIR_FREE(optstr); + ++ if (qemuCommandAddExtDevice(cmd, &fs->info) < 0) ++ return -1; ++ + virCommandAddArg(cmd, "-device"); + if (!(optstr = qemuBuildFSDevStr(def, fs, qemuCaps))) + return -1; +@@ -2950,6 +3007,11 @@ qemuBuildControllerDevCommandLine(virCommandPtr cmd, + goto cleanup; + + if (devstr) { ++ if (qemuCommandAddExtDevice(cmd, &cont->info) < 0) { ++ VIR_FREE(devstr); ++ goto cleanup; ++ } ++ + virCommandAddArg(cmd, "-device"); + virCommandAddArg(cmd, devstr); + VIR_FREE(devstr); +@@ -3753,6 +3815,9 @@ qemuBuildWatchdogCommandLine(virCommandPtr cmd, + if (!def->watchdog) + return 0; + ++ if (qemuCommandAddExtDevice(cmd, &def->watchdog->info) < 0) ++ return -1; ++ + virCommandAddArg(cmd, "-device"); + + optstr = qemuBuildWatchdogDevStr(def, watchdog, qemuCaps); +@@ -3837,6 +3902,9 @@ qemuBuildMemballoonCommandLine(virCommandPtr cmd, + if (qemuBuildVirtioOptionsStr(&buf, def->memballoon->virtio, qemuCaps) < 0) + goto error; + ++ if (qemuCommandAddExtDevice(cmd, &def->memballoon->info) < 0) ++ goto error; ++ + virCommandAddArg(cmd, "-device"); + virCommandAddArgBuffer(cmd, &buf); + return 0; +@@ -4059,6 +4127,9 @@ qemuBuildInputCommandLine(virCommandPtr cmd, + virDomainInputDefPtr input = def->inputs[i]; + char *devstr = NULL; + ++ if (qemuCommandAddExtDevice(cmd, &input->info) < 0) ++ return -1; ++ + if (qemuBuildInputDevStr(&devstr, def, input, qemuCaps) < 0) + return -1; + +@@ -4200,6 +4271,9 @@ qemuBuildSoundCommandLine(virCommandPtr cmd, + if (sound->model == VIR_DOMAIN_SOUND_MODEL_PCSPK) { + virCommandAddArgList(cmd, "-soundhw", "pcspk", NULL); + } else { ++ if (qemuCommandAddExtDevice(cmd, &sound->info) < 0) ++ return -1; ++ + virCommandAddArg(cmd, "-device"); + if (!(str = qemuBuildSoundDevStr(def, sound, qemuCaps))) + return -1; +@@ -4439,6 +4513,10 @@ qemuBuildVideoCommandLine(virCommandPtr cmd, + if (video->primary) { + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIDEO_PRIMARY)) { + ++ if (qemuCommandAddExtDevice(cmd, ++ &def->videos[i]->info) < 0) ++ return -1; ++ + virCommandAddArg(cmd, "-device"); + + if (!(str = qemuBuildDeviceVideoStr(def, video, qemuCaps))) +@@ -4451,6 +4529,9 @@ qemuBuildVideoCommandLine(virCommandPtr cmd, + return -1; + } + } else { ++ if (qemuCommandAddExtDevice(cmd, &def->videos[i]->info) < 0) ++ return -1; ++ + virCommandAddArg(cmd, "-device"); + + if (!(str = qemuBuildDeviceVideoStr(def, video, qemuCaps))) +@@ -5328,6 +5409,10 @@ qemuBuildHostdevCommandLine(virCommandPtr cmd, + VIR_COMMAND_PASS_FD_CLOSE_PARENT); + } + } ++ ++ if (qemuCommandAddExtDevice(cmd, hostdev->info) < 0) ++ return -1; ++ + virCommandAddArg(cmd, "-device"); + devstr = qemuBuildPCIHostdevDevStr(def, hostdev, bootIndex, + configfd_name, qemuCaps); +@@ -5802,6 +5887,9 @@ qemuBuildRNGCommandLine(virLogManagerPtr logManager, + virCommandAddArgBuffer(cmd, &buf); + + /* add the device */ ++ if (qemuCommandAddExtDevice(cmd, &rng->info) < 0) ++ return -1; ++ + if (!(tmp = qemuBuildRNGDevStr(def, rng, qemuCaps))) + return -1; + virCommandAddArgList(cmd, "-device", tmp, NULL); +@@ -8654,11 +8742,17 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver, + * New way: -netdev type=tap,id=netdev1 -device e1000,id=netdev1 + */ + if (qemuDomainSupportsNicdev(def, net)) { ++ if (qemuCommandAddExtDevice(cmd, &net->info) < 0) ++ goto cleanup; ++ + if (!(nic = qemuBuildNicDevStr(def, net, bootindex, + vhostfdSize, qemuCaps))) + goto cleanup; + virCommandAddArgList(cmd, "-device", nic, NULL); + } else { ++ if (qemuCommandAddExtDevice(cmd, &net->info) < 0) ++ goto cleanup; ++ + if (!(nic = qemuBuildLegacyNicStr(net))) + goto cleanup; + virCommandAddArgList(cmd, "-net", nic, NULL); +@@ -9105,6 +9199,12 @@ qemuBuildShmemCommandLine(virLogManagerPtr logManager, + + if (!devstr) + return -1; ++ ++ if (qemuCommandAddExtDevice(cmd, &shmem->info) < 0) { ++ VIR_FREE(devstr); ++ return -1; ++ } ++ + virCommandAddArgList(cmd, "-device", devstr, NULL); + VIR_FREE(devstr); + +@@ -10259,6 +10359,10 @@ qemuBuildVsockCommandLine(virCommandPtr cmd, + + virCommandPassFD(cmd, priv->vhostfd, VIR_COMMAND_PASS_FD_CLOSE_PARENT); + priv->vhostfd = -1; ++ ++ if (qemuCommandAddExtDevice(cmd, &vsock->info) < 0) ++ goto cleanup; ++ + virCommandAddArgList(cmd, "-device", devstr, NULL); + + ret = 0; +diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h +index 4f1b360130..e8cd8ed04e 100644 +--- a/src/qemu/qemu_command.h ++++ b/src/qemu/qemu_command.h +@@ -174,6 +174,8 @@ char *qemuBuildRedirdevDevStr(const virDomainDef *def, + virDomainRedirdevDefPtr dev, + virQEMUCapsPtr qemuCaps); + ++char *qemuBuildZPCIDevStr(virDomainDeviceInfoPtr dev); ++ + int qemuNetworkPrepareDevices(virDomainDefPtr def); + + int qemuGetDriveSourceString(virStorageSourcePtr src, +diff --git a/tests/qemuxml2argvdata/disk-virtio-s390-zpci.args b/tests/qemuxml2argvdata/disk-virtio-s390-zpci.args +index 20e63a15b5..ffb5d1597e 100644 +--- a/tests/qemuxml2argvdata/disk-virtio-s390-zpci.args ++++ b/tests/qemuxml2argvdata/disk-virtio-s390-zpci.args +@@ -21,6 +21,7 @@ server,nowait \ + -no-shutdown \ + -boot c \ + -drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-virtio-disk0 \ ++-device zpci,uid=25,fid=31,target=virtio-disk0,id=zpci25 \ + -device virtio-blk-pci,bus=pci.0,addr=0x8,drive=drive-virtio-disk0,\ + id=virtio-disk0 \ + -device virtio-balloon-ccw,id=balloon0,devno=fe.0.0000 +diff --git a/tests/qemuxml2argvdata/hostdev-vfio-zpci-autogenerate.args b/tests/qemuxml2argvdata/hostdev-vfio-zpci-autogenerate.args +new file mode 100644 +index 0000000000..e5987e1053 +--- /dev/null ++++ b/tests/qemuxml2argvdata/hostdev-vfio-zpci-autogenerate.args +@@ -0,0 +1,26 @@ ++LC_ALL=C \ ++PATH=/bin \ ++HOME=/home/test \ ++USER=test \ ++LOGNAME=test \ ++QEMU_AUDIO_DRV=none \ ++/usr/bin/qemu-system-s390x \ ++-name QEMUGuest1 \ ++-S \ ++-machine s390-ccw-virtio,accel=tcg,usb=off,dump-guest-core=off \ ++-m 214 \ ++-smp 1,sockets=1,cores=1,threads=1 \ ++-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ ++-display none \ ++-no-user-config \ ++-nodefaults \ ++-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\ ++server,nowait \ ++-mon chardev=charmonitor,id=monitor,mode=control \ ++-rtc base=utc \ ++-no-shutdown \ ++-boot c \ ++-device zpci,uid=1,fid=0,target=hostdev0,id=zpci1 \ ++-device vfio-pci,host=00:00.0,id=hostdev0,bus=pci.0,addr=0x1 \ ++-device zpci,uid=2,fid=1,target=balloon0,id=zpci2 \ ++-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x2 +diff --git a/tests/qemuxml2argvdata/hostdev-vfio-zpci-autogenerate.xml b/tests/qemuxml2argvdata/hostdev-vfio-zpci-autogenerate.xml +new file mode 100644 +index 0000000000..36161006ab +--- /dev/null ++++ b/tests/qemuxml2argvdata/hostdev-vfio-zpci-autogenerate.xml +@@ -0,0 +1,18 @@ ++ ++ QEMUGuest1 ++ c7a5fdbd-edaf-9455-926a-d65c16db1809 ++ 219100 ++ ++ hvm ++ ++ ++ /usr/bin/qemu-system-s390x ++ ++ ++ ++
++ ++
++ ++ ++ +diff --git a/tests/qemuxml2argvdata/hostdev-vfio-zpci-boundaries.args b/tests/qemuxml2argvdata/hostdev-vfio-zpci-boundaries.args +new file mode 100644 +index 0000000000..dcbb179a7d +--- /dev/null ++++ b/tests/qemuxml2argvdata/hostdev-vfio-zpci-boundaries.args +@@ -0,0 +1,30 @@ ++LC_ALL=C \ ++PATH=/bin \ ++HOME=/home/test \ ++USER=test \ ++LOGNAME=test \ ++QEMU_AUDIO_DRV=none \ ++/usr/bin/qemu-system-s390x \ ++-name QEMUGuest1 \ ++-S \ ++-machine s390-ccw-virtio,accel=tcg,usb=off,dump-guest-core=off \ ++-m 214 \ ++-smp 1,sockets=1,cores=1,threads=1 \ ++-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ ++-display none \ ++-no-user-config \ ++-nodefaults \ ++-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\ ++server,nowait \ ++-mon chardev=charmonitor,id=monitor,mode=control \ ++-rtc base=utc \ ++-no-shutdown \ ++-boot c \ ++-device zpci,uid=3,fid=2,target=pci.1,id=zpci3 \ ++-device pci-bridge,chassis_nr=1,id=pci.1,bus=pci.0,addr=0x1 \ ++-device zpci,uid=65535,fid=4294967295,target=hostdev0,id=zpci65535 \ ++-device vfio-pci,host=ffff:00:00.0,id=hostdev0,bus=pci.1,addr=0x1f \ ++-device zpci,uid=1,fid=0,target=hostdev1,id=zpci1 \ ++-device vfio-pci,host=00:00.0,id=hostdev1,bus=pci.0,addr=0x2 \ ++-device zpci,uid=2,fid=1,target=balloon0,id=zpci2 \ ++-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 +diff --git a/tests/qemuxml2argvdata/hostdev-vfio-zpci-boundaries.xml b/tests/qemuxml2argvdata/hostdev-vfio-zpci-boundaries.xml +new file mode 100644 +index 0000000000..1e6060345b +--- /dev/null ++++ b/tests/qemuxml2argvdata/hostdev-vfio-zpci-boundaries.xml +@@ -0,0 +1,30 @@ ++ ++ QEMUGuest1 ++ c7a5fdbd-edaf-9455-926a-d65c16db1809 ++ 219100 ++ ++ hvm ++ ++ ++ /usr/bin/qemu-system-s390x ++ ++ ++ ++ ++
++ ++
++ ++
++ ++ ++ ++ ++
++ ++
++ ++
++ ++ ++ +diff --git a/tests/qemuxml2argvdata/hostdev-vfio-zpci-multidomain-many.args b/tests/qemuxml2argvdata/hostdev-vfio-zpci-multidomain-many.args +new file mode 100644 +index 0000000000..11a2e50f1e +--- /dev/null ++++ b/tests/qemuxml2argvdata/hostdev-vfio-zpci-multidomain-many.args +@@ -0,0 +1,40 @@ ++LC_ALL=C \ ++PATH=/bin \ ++HOME=/home/test \ ++USER=test \ ++LOGNAME=test \ ++QEMU_AUDIO_DRV=none \ ++/usr/bin/qemu-system-s390x \ ++-name QEMUGuest1 \ ++-S \ ++-machine s390-ccw-virtio,accel=tcg,usb=off,dump-guest-core=off \ ++-m 214 \ ++-smp 1,sockets=1,cores=1,threads=1 \ ++-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ ++-display none \ ++-no-user-config \ ++-nodefaults \ ++-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\ ++server,nowait \ ++-mon chardev=charmonitor,id=monitor,mode=control \ ++-rtc base=utc \ ++-no-shutdown \ ++-boot c \ ++-device zpci,uid=35,fid=63,target=hostdev0,id=zpci35 \ ++-device vfio-pci,host=0001:00:00.0,id=hostdev0,bus=pci.0,addr=0x3 \ ++-device zpci,uid=53,fid=104,target=hostdev1,id=zpci53 \ ++-device vfio-pci,host=0002:00:00.0,id=hostdev1,bus=pci.0,addr=0x1 \ ++-device zpci,uid=1,fid=1,target=hostdev2,id=zpci1 \ ++-device vfio-pci,host=0003:00:00.0,id=hostdev2,bus=pci.0,addr=0x2 \ ++-device zpci,uid=2,fid=2,target=hostdev3,id=zpci2 \ ++-device vfio-pci,host=0004:00:00.0,id=hostdev3,bus=pci.0,addr=0x5 \ ++-device zpci,uid=83,fid=0,target=hostdev4,id=zpci83 \ ++-device vfio-pci,host=0005:00:00.0,id=hostdev4,bus=pci.0,addr=0x7 \ ++-device zpci,uid=3,fid=114,target=hostdev5,id=zpci3 \ ++-device vfio-pci,host=0006:00:00.0,id=hostdev5,bus=pci.0,addr=0x9 \ ++-device zpci,uid=23,fid=3,target=hostdev6,id=zpci23 \ ++-device vfio-pci,host=0007:00:00.0,id=hostdev6,bus=pci.0,addr=0x4 \ ++-device zpci,uid=4,fid=40,target=hostdev7,id=zpci4 \ ++-device vfio-pci,host=0008:00:00.0,id=hostdev7,bus=pci.0,addr=0x6 \ ++-device zpci,uid=5,fid=4,target=balloon0,id=zpci5 \ ++-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x8 +diff --git a/tests/qemuxml2argvdata/hostdev-vfio-zpci-multidomain-many.xml b/tests/qemuxml2argvdata/hostdev-vfio-zpci-multidomain-many.xml +new file mode 100644 +index 0000000000..da8305dd6d +--- /dev/null ++++ b/tests/qemuxml2argvdata/hostdev-vfio-zpci-multidomain-many.xml +@@ -0,0 +1,79 @@ ++ ++ QEMUGuest1 ++ c7a5fdbd-edaf-9455-926a-d65c16db1809 ++ 219100 ++ ++ hvm ++ ++ ++ /usr/bin/qemu-system-s390x ++ ++ ++ ++ ++
++ ++
++ ++
++ ++ ++ ++ ++
++ ++
++ ++
++ ++ ++ ++ ++
++ ++ ++ ++ ++ ++
++ ++
++ ++ ++ ++ ++
++ ++
++ ++
++ ++ ++ ++ ++
++ ++
++ ++
++ ++ ++ ++ ++
++ ++
++ ++
++ ++ ++ ++ ++
++ ++
++ ++
++ ++ ++ +diff --git a/tests/qemuxml2argvdata/hostdev-vfio-zpci.args b/tests/qemuxml2argvdata/hostdev-vfio-zpci.args +index 622c504da0..80de60acaa 100644 +--- a/tests/qemuxml2argvdata/hostdev-vfio-zpci.args ++++ b/tests/qemuxml2argvdata/hostdev-vfio-zpci.args +@@ -20,5 +20,7 @@ server,nowait \ + -rtc base=utc \ + -no-shutdown \ + -boot c \ ++-device zpci,uid=25,fid=31,target=hostdev0,id=zpci25 \ + -device vfio-pci,host=00:00.0,id=hostdev0,bus=pci.0,addr=0x8 \ ++-device zpci,uid=1,fid=0,target=balloon0,id=zpci1 \ + -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x1 +diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c +index 1066de8bc4..9de0cbf7e9 100644 +--- a/tests/qemuxml2argvtest.c ++++ b/tests/qemuxml2argvtest.c +@@ -1637,6 +1637,19 @@ mymain(void) + DO_TEST("hostdev-vfio-zpci", + QEMU_CAPS_DEVICE_VFIO_PCI, + QEMU_CAPS_DEVICE_ZPCI); ++ DO_TEST("hostdev-vfio-zpci-multidomain-many", ++ QEMU_CAPS_DEVICE_VFIO_PCI, ++ QEMU_CAPS_DEVICE_PCI_BRIDGE, ++ QEMU_CAPS_DEVICE_ZPCI); ++ DO_TEST("hostdev-vfio-zpci-autogenerate", ++ QEMU_CAPS_DEVICE_VFIO_PCI, ++ QEMU_CAPS_DEVICE_ZPCI); ++ DO_TEST("hostdev-vfio-zpci-boundaries", ++ QEMU_CAPS_DEVICE_VFIO_PCI, ++ QEMU_CAPS_DEVICE_PCI_BRIDGE, ++ QEMU_CAPS_DEVICE_ZPCI); ++ DO_TEST_PARSE_ERROR("hostdev-vfio-zpci", ++ QEMU_CAPS_DEVICE_VFIO_PCI); + DO_TEST("pci-rom", NONE); + DO_TEST("pci-rom-disabled", NONE); + DO_TEST("pci-rom-disabled-invalid", NONE); +diff --git a/tests/qemuxml2xmloutdata/hostdev-vfio-zpci-autogenerate.xml b/tests/qemuxml2xmloutdata/hostdev-vfio-zpci-autogenerate.xml +new file mode 100644 +index 0000000000..e94e63bd0a +--- /dev/null ++++ b/tests/qemuxml2xmloutdata/hostdev-vfio-zpci-autogenerate.xml +@@ -0,0 +1,34 @@ ++ ++ QEMUGuest1 ++ c7a5fdbd-edaf-9455-926a-d65c16db1809 ++ 219100 ++ 219100 ++ 1 ++ ++ hvm ++ ++ ++ ++ destroy ++ restart ++ destroy ++ ++ /usr/bin/qemu-system-s390x ++ ++ ++ ++ ++
++ ++
++ ++
++ ++ ++
++ ++
++
++ ++ ++ +diff --git a/tests/qemuxml2xmloutdata/hostdev-vfio-zpci-boundaries.xml b/tests/qemuxml2xmloutdata/hostdev-vfio-zpci-boundaries.xml +new file mode 100644 +index 0000000000..81d2146188 +--- /dev/null ++++ b/tests/qemuxml2xmloutdata/hostdev-vfio-zpci-boundaries.xml +@@ -0,0 +1,48 @@ ++ ++ QEMUGuest1 ++ c7a5fdbd-edaf-9455-926a-d65c16db1809 ++ 219100 ++ 219100 ++ 1 ++ ++ hvm ++ ++ ++ ++ destroy ++ restart ++ destroy ++ ++ /usr/bin/qemu-system-s390x ++ ++ ++ ++ ++
++ ++ ++ ++ ++
++ ++
++ ++
++ ++ ++ ++ ++
++ ++
++ ++
++ ++ ++
++ ++
++
++ ++ ++ +diff --git a/tests/qemuxml2xmloutdata/hostdev-vfio-zpci-multidomain-many.xml b/tests/qemuxml2xmloutdata/hostdev-vfio-zpci-multidomain-many.xml +new file mode 100644 +index 0000000000..e56106d103 +--- /dev/null ++++ b/tests/qemuxml2xmloutdata/hostdev-vfio-zpci-multidomain-many.xml +@@ -0,0 +1,97 @@ ++ ++ QEMUGuest1 ++ c7a5fdbd-edaf-9455-926a-d65c16db1809 ++ 219100 ++ 219100 ++ 1 ++ ++ hvm ++ ++ ++ ++ destroy ++ restart ++ destroy ++ ++ /usr/bin/qemu-system-s390x ++ ++ ++ ++ ++
++ ++
++ ++
++ ++ ++ ++ ++
++ ++
++ ++
++ ++ ++ ++ ++
++ ++
++ ++
++ ++ ++ ++ ++
++ ++
++ ++
++ ++ ++ ++ ++
++ ++
++ ++
++ ++ ++ ++ ++
++ ++
++ ++
++ ++ ++ ++ ++
++ ++
++ ++
++ ++ ++ ++ ++
++ ++
++ ++
++ ++ ++
++ ++
++
++ ++ ++ +diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c +index a787f4f4a3..b2afc8a8ba 100644 +--- a/tests/qemuxml2xmltest.c ++++ b/tests/qemuxml2xmltest.c +@@ -488,6 +488,17 @@ mymain(void) + DO_TEST("hostdev-vfio-zpci", + QEMU_CAPS_DEVICE_ZPCI, + QEMU_CAPS_CCW); ++ DO_TEST("hostdev-vfio-zpci-multidomain-many", ++ QEMU_CAPS_DEVICE_VFIO_PCI, ++ QEMU_CAPS_DEVICE_PCI_BRIDGE, ++ QEMU_CAPS_DEVICE_ZPCI); ++ DO_TEST("hostdev-vfio-zpci-autogenerate", ++ QEMU_CAPS_DEVICE_VFIO_PCI, ++ QEMU_CAPS_DEVICE_ZPCI); ++ DO_TEST("hostdev-vfio-zpci-boundaries", ++ QEMU_CAPS_DEVICE_VFIO_PCI, ++ QEMU_CAPS_DEVICE_PCI_BRIDGE, ++ QEMU_CAPS_DEVICE_ZPCI); + DO_TEST("hostdev-mdev-precreated", NONE); + DO_TEST("hostdev-mdev-display", QEMU_CAPS_VFIO_PCI_DISPLAY); + DO_TEST("pci-rom", NONE); +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu-Introduce-generic-qemuMonitorGetGuestCPU.patch b/SOURCES/libvirt-qemu-Introduce-generic-qemuMonitorGetGuestCPU.patch new file mode 100644 index 0000000..39ca791 --- /dev/null +++ b/SOURCES/libvirt-qemu-Introduce-generic-qemuMonitorGetGuestCPU.patch @@ -0,0 +1,323 @@ +From b61b68abeb8c2c93740698b81d59d2030eea8189 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:26:03 +0200 +Subject: [PATCH] qemu: Introduce generic qemuMonitorGetGuestCPU +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Unlike the old version (which is now called qemuMonitorGetGuestCPUx86), +this monitor API checks for individual features by their names rather +than processing CPUID bits. Thus we can get the list of enabled and +disabled features for both CPUID and MSR features. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit cc6d6b3cb995110a1d9da97f31ce68c2290f4332) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Signed-off-by: Jiri Denemark +Message-Id: <29634994c64ffbf3509238ccbe1937b599e55838.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_monitor.c | 36 +++++++ + src/qemu/qemu_monitor.h | 10 ++ + src/qemu/qemu_monitor_json.c | 186 +++++++++++++++++++++++++++++++++++ + src/qemu/qemu_monitor_json.h | 7 ++ + 4 files changed, 239 insertions(+) + +diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c +index b35187b66d..ae666ce633 100644 +--- a/src/qemu/qemu_monitor.c ++++ b/src/qemu/qemu_monitor.c +@@ -4074,6 +4074,42 @@ qemuMonitorGetGuestCPUx86(qemuMonitorPtr mon, + } + + ++/** ++ * qemuMonitorGetGuestCPU: ++ * @mon: Pointer to the monitor ++ * @arch: CPU architecture ++ * @translate: callback for translating CPU feature names from QEMU to libvirt ++ * @opaque: data for @translate callback ++ * @enabled: returns the CPU data for all enabled features ++ * @disabled: returns the CPU data for features which we asked for ++ * (either explicitly or via a named CPU model) but QEMU disabled them ++ * ++ * Retrieve the definition of the guest CPU from a running QEMU instance. ++ * ++ * Returns 0 on success, -1 on error. ++ */ ++int ++qemuMonitorGetGuestCPU(qemuMonitorPtr mon, ++ virArch arch, ++ qemuMonitorCPUFeatureTranslationCallback translate, ++ void *opaque, ++ virCPUDataPtr *enabled, ++ virCPUDataPtr *disabled) ++{ ++ VIR_DEBUG("arch=%s translate=%p opaque=%p enabled=%p disabled=%p", ++ virArchToString(arch), translate, opaque, enabled, disabled); ++ ++ QEMU_CHECK_MONITOR(mon); ++ ++ *enabled = NULL; ++ if (disabled) ++ *disabled = NULL; ++ ++ return qemuMonitorJSONGetGuestCPU(mon, arch, translate, opaque, ++ enabled, disabled); ++} ++ ++ + /** + * qemuMonitorRTCResetReinjection: + * @mon: Pointer to the monitor +diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h +index b4d484c703..8d4f6e6062 100644 +--- a/src/qemu/qemu_monitor.h ++++ b/src/qemu/qemu_monitor.h +@@ -1099,6 +1099,16 @@ int qemuMonitorGetGuestCPUx86(qemuMonitorPtr mon, + virCPUDataPtr *data, + virCPUDataPtr *disabled); + ++typedef const char *(*qemuMonitorCPUFeatureTranslationCallback)(const char *name, ++ void *opaque); ++ ++int qemuMonitorGetGuestCPU(qemuMonitorPtr mon, ++ virArch arch, ++ qemuMonitorCPUFeatureTranslationCallback translate, ++ void *opaque, ++ virCPUDataPtr *enabled, ++ virCPUDataPtr *disabled); ++ + int qemuMonitorRTCResetReinjection(qemuMonitorPtr mon); + + typedef struct _qemuMonitorIOThreadInfo qemuMonitorIOThreadInfo; +diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c +index abf952cd34..00a0578809 100644 +--- a/src/qemu/qemu_monitor_json.c ++++ b/src/qemu/qemu_monitor_json.c +@@ -5998,6 +5998,57 @@ int qemuMonitorJSONGetObjectProperty(qemuMonitorPtr mon, + } + + ++static int ++qemuMonitorJSONGetStringListProperty(qemuMonitorPtr mon, ++ const char *path, ++ const char *property, ++ char ***strList) ++{ ++ VIR_AUTOPTR(virJSONValue) cmd = NULL; ++ VIR_AUTOPTR(virJSONValue) reply = NULL; ++ VIR_AUTOSTRINGLIST list = NULL; ++ virJSONValuePtr data; ++ size_t n; ++ size_t i; ++ ++ *strList = NULL; ++ ++ if (!(cmd = qemuMonitorJSONMakeCommand("qom-get", ++ "s:path", path, ++ "s:property", property, ++ NULL))) ++ return -1; ++ ++ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) ++ return -1; ++ ++ if (qemuMonitorJSONCheckReply(cmd, reply, VIR_JSON_TYPE_ARRAY) < 0) ++ return -1; ++ ++ data = virJSONValueObjectGetArray(reply, "return"); ++ n = virJSONValueArraySize(data); ++ ++ if (VIR_ALLOC_N(list, n + 1) < 0) ++ return -1; ++ ++ for (i = 0; i < n; i++) { ++ virJSONValuePtr item = virJSONValueArrayGet(data, i); ++ ++ if (virJSONValueGetType(item) != VIR_JSON_TYPE_STRING) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("unexpected value in %s array"), property); ++ return -1; ++ } ++ ++ if (VIR_STRDUP(list[i], virJSONValueGetString(item)) < 0) ++ return -1; ++ } ++ ++ VIR_STEAL_PTR(*strList, list); ++ return n; ++} ++ ++ + #define MAKE_SET_CMD(STRING, VALUE) \ + cmd = qemuMonitorJSONMakeCommand("qom-set", \ + "s:path", path, \ +@@ -7207,6 +7258,141 @@ qemuMonitorJSONGetGuestCPUx86(qemuMonitorPtr mon, + return -1; + } + ++ ++static int ++qemuMonitorJSONGetCPUProperties(qemuMonitorPtr mon, ++ char ***props) ++{ ++ VIR_AUTOPTR(virJSONValue) cmd = NULL; ++ VIR_AUTOPTR(virJSONValue) reply = NULL; ++ ++ *props = NULL; ++ ++ if (!(cmd = qemuMonitorJSONMakeCommand("qom-list", ++ "s:path", QOM_CPU_PATH, ++ NULL))) ++ return -1; ++ ++ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) ++ return -1; ++ ++ if (qemuMonitorJSONHasError(reply, "DeviceNotFound")) ++ return 0; ++ ++ return qemuMonitorJSONParsePropsList(cmd, reply, "bool", props); ++} ++ ++ ++static int ++qemuMonitorJSONGetCPUData(qemuMonitorPtr mon, ++ qemuMonitorCPUFeatureTranslationCallback translate, ++ void *opaque, ++ virCPUDataPtr data) ++{ ++ qemuMonitorJSONObjectProperty prop = { .type = QEMU_MONITOR_OBJECT_PROPERTY_BOOLEAN }; ++ VIR_AUTOSTRINGLIST props = NULL; ++ char **p; ++ ++ if (qemuMonitorJSONGetCPUProperties(mon, &props) < 0) ++ return -1; ++ ++ for (p = props; p && *p; p++) { ++ const char *name = *p; ++ ++ if (qemuMonitorJSONGetObjectProperty(mon, QOM_CPU_PATH, name, &prop) < 0) ++ return -1; ++ ++ if (!prop.val.b) ++ continue; ++ ++ if (translate) ++ name = translate(name, opaque); ++ ++ if (virCPUDataAddFeature(data, name) < 0) ++ return -1; ++ } ++ ++ return 0; ++} ++ ++ ++static int ++qemuMonitorJSONGetCPUDataDisabled(qemuMonitorPtr mon, ++ qemuMonitorCPUFeatureTranslationCallback translate, ++ void *opaque, ++ virCPUDataPtr data) ++{ ++ VIR_AUTOSTRINGLIST props = NULL; ++ char **p; ++ ++ if (qemuMonitorJSONGetStringListProperty(mon, QOM_CPU_PATH, ++ "unavailable-features", &props) < 0) ++ return -1; ++ ++ for (p = props; p && *p; p++) { ++ const char *name = *p; ++ ++ if (translate) ++ name = translate(name, opaque); ++ ++ if (virCPUDataAddFeature(data, name) < 0) ++ return -1; ++ } ++ ++ return 0; ++} ++ ++ ++/** ++ * qemuMonitorJSONGetGuestCPU: ++ * @mon: Pointer to the monitor ++ * @arch: CPU architecture ++ * @translate: callback for translating CPU feature names from QEMU to libvirt ++ * @opaque: data for @translate callback ++ * @enabled: returns the CPU data for all enabled features ++ * @disabled: returns the CPU data for features which we asked for ++ * (either explicitly or via a named CPU model) but QEMU disabled them ++ * ++ * Retrieve the definition of the guest CPU from a running QEMU instance. ++ * ++ * Returns 0 on success, -1 on error. ++ */ ++int ++qemuMonitorJSONGetGuestCPU(qemuMonitorPtr mon, ++ virArch arch, ++ qemuMonitorCPUFeatureTranslationCallback translate, ++ void *opaque, ++ virCPUDataPtr *enabled, ++ virCPUDataPtr *disabled) ++{ ++ virCPUDataPtr cpuEnabled = NULL; ++ virCPUDataPtr cpuDisabled = NULL; ++ int ret = -1; ++ ++ if (!(cpuEnabled = virCPUDataNew(arch)) || ++ !(cpuDisabled = virCPUDataNew(arch))) ++ goto cleanup; ++ ++ if (qemuMonitorJSONGetCPUData(mon, translate, opaque, cpuEnabled) < 0) ++ goto cleanup; ++ ++ if (disabled && ++ qemuMonitorJSONGetCPUDataDisabled(mon, translate, opaque, cpuDisabled) < 0) ++ goto cleanup; ++ ++ VIR_STEAL_PTR(*enabled, cpuEnabled); ++ if (disabled) ++ VIR_STEAL_PTR(*disabled, cpuDisabled); ++ ++ ret = 0; ++ ++ cleanup: ++ virCPUDataFree(cpuEnabled); ++ virCPUDataFree(cpuDisabled); ++ return ret; ++} ++ ++ + int + qemuMonitorJSONRTCResetReinjection(qemuMonitorPtr mon) + { +diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h +index 57bed027e2..29b10aad26 100644 +--- a/src/qemu/qemu_monitor_json.h ++++ b/src/qemu/qemu_monitor_json.h +@@ -490,6 +490,13 @@ int qemuMonitorJSONGetGuestCPUx86(qemuMonitorPtr mon, + virCPUDataPtr *data, + virCPUDataPtr *disabled); + ++int qemuMonitorJSONGetGuestCPU(qemuMonitorPtr mon, ++ virArch arch, ++ qemuMonitorCPUFeatureTranslationCallback translate, ++ void *opaque, ++ virCPUDataPtr *enabled, ++ virCPUDataPtr *disabled); ++ + int qemuMonitorJSONRTCResetReinjection(qemuMonitorPtr mon); + + int qemuMonitorJSONGetIOThreads(qemuMonitorPtr mon, +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu-Introduce-zPCI-capability.patch b/SOURCES/libvirt-qemu-Introduce-zPCI-capability.patch new file mode 100644 index 0000000..2bb0270 --- /dev/null +++ b/SOURCES/libvirt-qemu-Introduce-zPCI-capability.patch @@ -0,0 +1,156 @@ +From 3ff9abfcfa6a79c47755a6e8d9da5b1bc4bdd655 Mon Sep 17 00:00:00 2001 +Message-Id: <3ff9abfcfa6a79c47755a6e8d9da5b1bc4bdd655@dist-git> +From: Yi Min Zhao +Date: Mon, 8 Apr 2019 10:57:19 +0200 +Subject: [PATCH] qemu: Introduce zPCI capability +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Let's introduce zPCI capability. + +Signed-off-by: Yi Min Zhao +Reviewed-by: Boris Fiuczynski +Reviewed-by: Stefan Zimmermann +Reviewed-by: Bjoern Walk +Reviewed-by: Ján Tomko +Reviewed-by: Andrea Bolognani + +(cherry-picked from commit 29ad952f7e50bbbd920cbfb009a45b55fdb2f069) + +https://bugzilla.redhat.com/show_bug.cgi?id=1508149 + +Conflicts: + + * src/qemu/qemu_capabilities.c + src/qemu/qemu_capabilities.h + + several capabilities have not been backported + +Removed: + + * tests/qemucapabilitiesdata/caps_3.0.0.s390x.xml + + the file does not exist at all downstream + - missing d7434ae8009f + +Signed-off-by: Andrea Bolognani +Message-Id: <20190408085732.28684-3-abologna@redhat.com> +Reviewed-by: Laine Stump +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_capabilities.c | 2 ++ + src/qemu/qemu_capabilities.h | 1 + + tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml | 1 + + tests/qemucapabilitiesdata/caps_2.11.0.s390x.xml | 1 + + tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml | 1 + + tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml | 1 + + tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml | 1 + + tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml | 1 + + 8 files changed, 9 insertions(+) + +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index 0d6fa02560..8ca53abf2b 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -512,6 +512,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST, + /* 315 */ + "vfio-pci.display", + "vfio-ap", ++ "zpci", + "machine.pseries.cap-nested-hv", + ); + +@@ -1153,6 +1154,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = { + { "mch", QEMU_CAPS_DEVICE_MCH }, + { "sev-guest", QEMU_CAPS_SEV_GUEST }, + { "vfio-ap", QEMU_CAPS_DEVICE_VFIO_AP }, ++ { "zpci", QEMU_CAPS_DEVICE_ZPCI }, + }; + + static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsVirtioBalloon[] = { +diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h +index 9550df2cd5..bea4767f3c 100644 +--- a/src/qemu/qemu_capabilities.h ++++ b/src/qemu/qemu_capabilities.h +@@ -492,6 +492,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ + /* 315 */ + QEMU_CAPS_VFIO_PCI_DISPLAY, /* -device vfio-pci.display */ + QEMU_CAPS_DEVICE_VFIO_AP, /* -device vfio-ap */ ++ QEMU_CAPS_DEVICE_ZPCI, /* -device zpci */ + QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV, /* -machine pseries.cap-nested-hv */ + + QEMU_CAPS_LAST /* this must always be the last item */ +diff --git a/tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml +index 7347f5683f..b46efe880d 100644 +--- a/tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml ++++ b/tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml +@@ -120,6 +120,7 @@ + + + ++ + 2010000 + 0 + 307899 +diff --git a/tests/qemucapabilitiesdata/caps_2.11.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.11.0.s390x.xml +index b359f9a049..3ac1fc941c 100644 +--- a/tests/qemucapabilitiesdata/caps_2.11.0.s390x.xml ++++ b/tests/qemucapabilitiesdata/caps_2.11.0.s390x.xml +@@ -127,6 +127,7 @@ + + + ++ + 2011000 + 0 + 346751 +diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml +index 7121da27a0..184f115fe4 100644 +--- a/tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml ++++ b/tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml +@@ -135,6 +135,7 @@ + + + ++ + 2012000 + 0 + 375999 +diff --git a/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml +index 9ed25178f8..b04a9fbfd5 100644 +--- a/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml ++++ b/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml +@@ -107,6 +107,7 @@ + + + ++ + 2007000 + 0 + 220792 +diff --git a/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml +index 646239ff25..b2b267be8d 100644 +--- a/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml ++++ b/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml +@@ -110,6 +110,7 @@ + + + ++ + 2007093 + 0 + 246206 +diff --git a/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml +index 09d68e1f18..f908ab88f3 100644 +--- a/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml ++++ b/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml +@@ -114,6 +114,7 @@ + + + ++ + 2009000 + 0 + 269625 +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu-Make-qemuMonitorGetGuestCPU-usable-on-x86-only.patch b/SOURCES/libvirt-qemu-Make-qemuMonitorGetGuestCPU-usable-on-x86-only.patch new file mode 100644 index 0000000..5440132 --- /dev/null +++ b/SOURCES/libvirt-qemu-Make-qemuMonitorGetGuestCPU-usable-on-x86-only.patch @@ -0,0 +1,228 @@ +From 53744fa2afeb19f0ce31cb109e0b3c1f1c8b815b Mon Sep 17 00:00:00 2001 +Message-Id: <53744fa2afeb19f0ce31cb109e0b3c1f1c8b815b@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:58 +0200 +Subject: [PATCH] qemu: Make qemuMonitorGetGuestCPU usable on x86 only +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +It was never implemented or used for anything else anyway. Mainly +because it uses CPUID features bits. The function is renamed as +qemuMonitorGetGuestCPUx86 to make this explicit. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 055f8f6bb953a8a489729d6cd62e55dee058b7e6) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Signed-off-by: Jiri Denemark +Message-Id: <8e07e0a4f5f751bacf5e23fcdc6b93265b819359.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_monitor.c | 15 +++++------- + src/qemu/qemu_monitor.h | 7 +++--- + src/qemu/qemu_monitor_json.c | 47 +++++++++++++++--------------------- + src/qemu/qemu_monitor_json.h | 7 +++--- + src/qemu/qemu_process.c | 3 +-- + tests/qemumonitorjsontest.c | 10 +++----- + 6 files changed, 36 insertions(+), 53 deletions(-) + +diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c +index bc116e4e2d..b35187b66d 100644 +--- a/src/qemu/qemu_monitor.c ++++ b/src/qemu/qemu_monitor.c +@@ -4047,9 +4047,8 @@ qemuMonitorSetDomainLog(qemuMonitorPtr mon, + + + /** +- * qemuMonitorJSONGetGuestCPU: ++ * qemuMonitorJSONGetGuestCPUx86: + * @mon: Pointer to the monitor +- * @arch: arch of the guest + * @data: returns the cpu data + * @disabled: returns the CPU data for features which were disabled by QEMU + * +@@ -4059,13 +4058,11 @@ qemuMonitorSetDomainLog(qemuMonitorPtr mon, + * -1 on other errors. + */ + int +-qemuMonitorGetGuestCPU(qemuMonitorPtr mon, +- virArch arch, +- virCPUDataPtr *data, +- virCPUDataPtr *disabled) ++qemuMonitorGetGuestCPUx86(qemuMonitorPtr mon, ++ virCPUDataPtr *data, ++ virCPUDataPtr *disabled) + { +- VIR_DEBUG("arch=%s data=%p disabled=%p", +- virArchToString(arch), data, disabled); ++ VIR_DEBUG("data=%p disabled=%p", data, disabled); + + QEMU_CHECK_MONITOR(mon); + +@@ -4073,7 +4070,7 @@ qemuMonitorGetGuestCPU(qemuMonitorPtr mon, + if (disabled) + *disabled = NULL; + +- return qemuMonitorJSONGetGuestCPU(mon, arch, data, disabled); ++ return qemuMonitorJSONGetGuestCPUx86(mon, data, disabled); + } + + +diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h +index 81474a04f6..b4d484c703 100644 +--- a/src/qemu/qemu_monitor.h ++++ b/src/qemu/qemu_monitor.h +@@ -1095,10 +1095,9 @@ void qemuMonitorSetDomainLog(qemuMonitorPtr mon, + void *opaque, + virFreeCallback destroy); + +-int qemuMonitorGetGuestCPU(qemuMonitorPtr mon, +- virArch arch, +- virCPUDataPtr *data, +- virCPUDataPtr *disabled); ++int qemuMonitorGetGuestCPUx86(qemuMonitorPtr mon, ++ virCPUDataPtr *data, ++ virCPUDataPtr *disabled); + + int qemuMonitorRTCResetReinjection(qemuMonitorPtr mon); + +diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c +index e6ac82e96b..8fead72ecf 100644 +--- a/src/qemu/qemu_monitor_json.c ++++ b/src/qemu/qemu_monitor_json.c +@@ -7157,9 +7157,8 @@ qemuMonitorJSONCheckCPUx86(qemuMonitorPtr mon) + + + /** +- * qemuMonitorJSONGetGuestCPU: ++ * qemuMonitorJSONGetGuestCPUx86: + * @mon: Pointer to the monitor +- * @arch: arch of the guest + * @data: returns the cpu data of the guest + * @disabled: returns the CPU data for features which were disabled by QEMU + * +@@ -7169,40 +7168,32 @@ qemuMonitorJSONCheckCPUx86(qemuMonitorPtr mon) + * -1 on other errors. + */ + int +-qemuMonitorJSONGetGuestCPU(qemuMonitorPtr mon, +- virArch arch, +- virCPUDataPtr *data, +- virCPUDataPtr *disabled) ++qemuMonitorJSONGetGuestCPUx86(qemuMonitorPtr mon, ++ virCPUDataPtr *data, ++ virCPUDataPtr *disabled) + { + virCPUDataPtr cpuEnabled = NULL; + virCPUDataPtr cpuDisabled = NULL; + int rc; + +- if (ARCH_IS_X86(arch)) { +- if ((rc = qemuMonitorJSONCheckCPUx86(mon)) < 0) +- return -1; +- else if (!rc) +- return -2; ++ if ((rc = qemuMonitorJSONCheckCPUx86(mon)) < 0) ++ return -1; ++ else if (!rc) ++ return -2; + +- if (qemuMonitorJSONGetCPUx86Data(mon, "feature-words", +- &cpuEnabled) < 0) +- goto error; ++ if (qemuMonitorJSONGetCPUx86Data(mon, "feature-words", ++ &cpuEnabled) < 0) ++ goto error; + +- if (disabled && +- qemuMonitorJSONGetCPUx86Data(mon, "filtered-features", +- &cpuDisabled) < 0) +- goto error; ++ if (disabled && ++ qemuMonitorJSONGetCPUx86Data(mon, "filtered-features", ++ &cpuDisabled) < 0) ++ goto error; + +- *data = cpuEnabled; +- if (disabled) +- *disabled = cpuDisabled; +- return 0; +- } +- +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("CPU definition retrieval isn't supported for '%s'"), +- virArchToString(arch)); +- return -1; ++ *data = cpuEnabled; ++ if (disabled) ++ *disabled = cpuDisabled; ++ return 0; + + error: + virCPUDataFree(cpuEnabled); +diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h +index 66536ceb97..57bed027e2 100644 +--- a/src/qemu/qemu_monitor_json.h ++++ b/src/qemu/qemu_monitor_json.h +@@ -486,10 +486,9 @@ int qemuMonitorJSONGetCPUx86Data(qemuMonitorPtr mon, + const char *property, + virCPUDataPtr *cpudata); + +-int qemuMonitorJSONGetGuestCPU(qemuMonitorPtr mon, +- virArch arch, +- virCPUDataPtr *data, +- virCPUDataPtr *disabled); ++int qemuMonitorJSONGetGuestCPUx86(qemuMonitorPtr mon, ++ virCPUDataPtr *data, ++ virCPUDataPtr *disabled); + + int qemuMonitorJSONRTCResetReinjection(qemuMonitorPtr mon); + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index bc573f96a4..59a739f262 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -4034,8 +4034,7 @@ qemuProcessFetchGuestCPU(virQEMUDriverPtr driver, + if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) + goto error; + +- rc = qemuMonitorGetGuestCPU(priv->mon, vm->def->os.arch, +- &dataEnabled, &dataDisabled); ++ rc = qemuMonitorGetGuestCPUx86(priv->mon, &dataEnabled, &dataDisabled); + + if (qemuDomainObjExitMonitor(driver, vm) < 0) + goto error; +diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c +index 2eefd06b6e..ef9a549c04 100644 +--- a/tests/qemumonitorjsontest.c ++++ b/tests/qemumonitorjsontest.c +@@ -2437,9 +2437,8 @@ testQemuMonitorJSONGetCPUData(const void *opaque) + if (qemuMonitorTestAddItem(test, "qom-get", jsonStr) < 0) + goto cleanup; + +- if (qemuMonitorJSONGetGuestCPU(qemuMonitorTestGetMonitor(test), +- VIR_ARCH_X86_64, +- &cpuData, NULL) < 0) ++ if (qemuMonitorJSONGetGuestCPUx86(qemuMonitorTestGetMonitor(test), ++ &cpuData, NULL) < 0) + goto cleanup; + + if (!(actual = virCPUDataFormat(cpuData))) +@@ -2480,9 +2479,8 @@ testQemuMonitorJSONGetNonExistingCPUData(const void *opaque) + "}") < 0) + goto cleanup; + +- rv = qemuMonitorJSONGetGuestCPU(qemuMonitorTestGetMonitor(test), +- VIR_ARCH_X86_64, +- &cpuData, NULL); ++ rv = qemuMonitorJSONGetGuestCPUx86(qemuMonitorTestGetMonitor(test), ++ &cpuData, NULL); + if (rv != -2) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "Unexpected return value %d, expecting -2", rv); +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu-Probe-for-max-x86_64-cpu-type.patch b/SOURCES/libvirt-qemu-Probe-for-max-x86_64-cpu-type.patch new file mode 100644 index 0000000..35b0e23 --- /dev/null +++ b/SOURCES/libvirt-qemu-Probe-for-max-x86_64-cpu-type.patch @@ -0,0 +1,155 @@ +From e26a52e067bfeeab95f6cd4bb0717e202ffd7279 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:52 +0200 +Subject: [PATCH] qemu: Probe for max-x86_64-cpu type +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We will use it to check whether QEMU supports a specific CPU property. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 2a4c23210674b453f91569f0f4b9fd5ebe8d7906) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Conflicts: + src/qemu/qemu_capabilities.c + src/qemu/qemu_capabilities.h + tests/qemucapabilitiesdata/caps_2.10.0.x86_64.xml + tests/qemucapabilitiesdata/caps_2.11.0.x86_64.xml + tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml + tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml + tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml + - several capabilities are missing + + tests/qemucapabilitiesdata/caps_3.1.0.x86_64.xml + tests/qemucapabilitiesdata/caps_4.0.0.x86_64.xml + - test files are missing + + tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml + - several capabilities are missing + +Signed-off-by: Jiri Denemark +Message-Id: <5b1c1caf31b481ba608cc850463ff02b2381c382.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_capabilities.c | 2 ++ + src/qemu/qemu_capabilities.h | 1 + + tests/qemucapabilitiesdata/caps_2.10.0.x86_64.xml | 1 + + tests/qemucapabilitiesdata/caps_2.11.0.x86_64.xml | 1 + + tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml | 1 + + tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml | 1 + + tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml | 1 + + tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml | 1 + + 8 files changed, 9 insertions(+) + +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index d2a2f7418a..4515da4b91 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -514,6 +514,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST, + "vfio-ap", + "zpci", + "machine.pseries.cap-nested-hv", ++ "x86-max-cpu", + ); + + +@@ -1155,6 +1156,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = { + { "sev-guest", QEMU_CAPS_SEV_GUEST }, + { "vfio-ap", QEMU_CAPS_DEVICE_VFIO_AP }, + { "zpci", QEMU_CAPS_DEVICE_ZPCI }, ++ { "max-x86_64-cpu", QEMU_CAPS_X86_MAX_CPU }, + }; + + static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsVirtioBalloon[] = { +diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h +index 8a27acd8a4..25ed5064b9 100644 +--- a/src/qemu/qemu_capabilities.h ++++ b/src/qemu/qemu_capabilities.h +@@ -494,6 +494,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ + QEMU_CAPS_DEVICE_VFIO_AP, /* -device vfio-ap */ + QEMU_CAPS_DEVICE_ZPCI, /* -device zpci */ + QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV, /* -machine pseries.cap-nested-hv */ ++ QEMU_CAPS_X86_MAX_CPU, /* max-x86_64-cpu type exists */ + + QEMU_CAPS_LAST /* this must always be the last item */ + } virQEMUCapsFlags; +diff --git a/tests/qemucapabilitiesdata/caps_2.10.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.10.0.x86_64.xml +index d69a148cd2..bb4c2abdeb 100644 +--- a/tests/qemucapabilitiesdata/caps_2.10.0.x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_2.10.0.x86_64.xml +@@ -204,6 +204,7 @@ + + + ++ + 2010000 + 0 + 367995 +diff --git a/tests/qemucapabilitiesdata/caps_2.11.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.11.0.x86_64.xml +index 210f774c4e..32268b29d2 100644 +--- a/tests/qemucapabilitiesdata/caps_2.11.0.x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_2.11.0.x86_64.xml +@@ -208,6 +208,7 @@ + + + ++ + 2011000 + 0 + 371455 +diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml +index f0dc082640..f4416e7b55 100644 +--- a/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml +@@ -213,6 +213,7 @@ + + + ++ + 2011090 + 0 + 416196 +diff --git a/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml +index 31ce52c787..e84d153d9a 100644 +--- a/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml +@@ -198,6 +198,7 @@ + + + ++ + 2009000 + 0 + 343984 +diff --git a/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml +index 8992d645e7..dceb719fcf 100644 +--- a/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml +@@ -215,6 +215,7 @@ + + + ++ + 2012090 + 0 + 438109 +diff --git a/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml +index 93c5da537a..4836dbb8a4 100644 +--- a/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml +@@ -214,6 +214,7 @@ + + + ++ + 4000050 + 0 + 456805 +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu-Probe-for-unavailable-features-CPU-property.patch b/SOURCES/libvirt-qemu-Probe-for-unavailable-features-CPU-property.patch new file mode 100644 index 0000000..76c7619 --- /dev/null +++ b/SOURCES/libvirt-qemu-Probe-for-unavailable-features-CPU-property.patch @@ -0,0 +1,3972 @@ +From 597dd548f0d5a5ddf662ad748f1b1a9f0a456dce Mon Sep 17 00:00:00 2001 +Message-Id: <597dd548f0d5a5ddf662ad748f1b1a9f0a456dce@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:53 +0200 +Subject: [PATCH] qemu: Probe for "unavailable-features" CPU property +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +It is similar to "filtered-features" property, which reports CPUID bits +corresponding to disabled features, but more general. The +"unavailable-features" property supports both CPUID and MSR features by +listing their names. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 0d254bce4ec6fd62c0277d24e28bf018a4c6cb37) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Conflicts: + src/qemu/qemu_capabilities.c + - several capabilities check are missing + + tests/qemucapabilitiesdata/caps_2.12.0.x86_64.replies + tests/qemucapabilitiesdata/caps_3.0.0.x86_64.replies + tests/qemucapabilitiesdata/caps_4.1.0.x86_64.replies + - QMP message IDs are different + + tests/qemucapabilitiesdata/caps_3.1.0.x86_64.replies + tests/qemucapabilitiesdata/caps_4.0.0.x86_64.replies + - missing + + tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml + tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml + tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml + - file size based microcode version + +Signed-off-by: Jiri Denemark +Message-Id: <2cf5c234b2b3e54250f0d8b1e12763d4f8e81247.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_capabilities.c | 8 + + src/qemu/qemu_capabilities.h | 1 + + .../caps_2.12.0.x86_64.replies | 1078 ++++++++++++++- + .../caps_2.12.0.x86_64.xml | 2 +- + .../caps_3.0.0.x86_64.replies | 1116 +++++++++++++++- + .../caps_3.0.0.x86_64.xml | 2 +- + .../caps_4.1.0.x86_64.replies | 1188 ++++++++++++++++- + .../caps_4.1.0.x86_64.xml | 3 +- + 8 files changed, 3317 insertions(+), 81 deletions(-) + +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index 4515da4b91..beec9d1497 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -515,6 +515,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST, + "zpci", + "machine.pseries.cap-nested-hv", + "x86-max-cpu", ++ "cpu-unavailable-features", + ); + + +@@ -1452,6 +1453,10 @@ static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsSPAPRMachine[] = { + { "cap-nested-hv", QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV }, + }; + ++static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsMaxX86CPU[] = { ++ { "unavailable-features", QEMU_CAPS_CPU_UNAVAILABLE_FEATURES }, ++}; ++ + static virQEMUCapsObjectTypeProps virQEMUCapsObjectProps[] = { + { "memory-backend-file", virQEMUCapsObjectPropsMemoryBackendFile, + ARRAY_CARDINALITY(virQEMUCapsObjectPropsMemoryBackendFile), +@@ -1459,6 +1464,9 @@ static virQEMUCapsObjectTypeProps virQEMUCapsObjectProps[] = { + { "spapr-machine", virQEMUCapsObjectPropsSPAPRMachine, + ARRAY_CARDINALITY(virQEMUCapsObjectPropsSPAPRMachine), + -1 }, ++ { "max-x86_64-cpu", virQEMUCapsObjectPropsMaxX86CPU, ++ ARRAY_CARDINALITY(virQEMUCapsObjectPropsMaxX86CPU), ++ QEMU_CAPS_X86_MAX_CPU }, + }; + + static void +diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h +index 25ed5064b9..5aa41efdb0 100644 +--- a/src/qemu/qemu_capabilities.h ++++ b/src/qemu/qemu_capabilities.h +@@ -495,6 +495,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ + QEMU_CAPS_DEVICE_ZPCI, /* -device zpci */ + QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV, /* -machine pseries.cap-nested-hv */ + QEMU_CAPS_X86_MAX_CPU, /* max-x86_64-cpu type exists */ ++ QEMU_CAPS_CPU_UNAVAILABLE_FEATURES, /* "unavailable-features" CPU property */ + + QEMU_CAPS_LAST /* this must always be the last item */ + } virQEMUCapsFlags; +diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.replies b/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.replies +index 6f37e4301e..66a5577e5e 100644 +--- a/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.replies ++++ b/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.replies +@@ -5011,10 +5011,1040 @@ + } + + { +- "execute": "query-machines", ++ "execute": "qom-list-properties", ++ "arguments": { ++ "typename": "max-x86_64-cpu" ++ }, + "id": "libvirt-43" + } + ++{ ++ "return": [ ++ { ++ "name": "min-xlevel2", ++ "type": "uint32" ++ }, ++ { ++ "name": "vendor", ++ "type": "string" ++ }, ++ { ++ "name": "gfni", ++ "type": "bool" ++ }, ++ { ++ "name": "clwb", ++ "type": "bool" ++ }, ++ { ++ "name": "nx", ++ "type": "bool" ++ }, ++ { ++ "name": "x2apic", ++ "type": "bool" ++ }, ++ { ++ "name": "kvmclock-stable-bit", ++ "type": "bool" ++ }, ++ { ++ "name": "vmcb_clean", ++ "type": "bool" ++ }, ++ { ++ "name": "min-level", ++ "type": "uint32" ++ }, ++ { ++ "name": "fxsr-opt", ++ "type": "bool" ++ }, ++ { ++ "name": "skinit", ++ "type": "bool" ++ }, ++ { ++ "name": "avx", ++ "type": "bool" ++ }, ++ { ++ "name": "3dnowext", ++ "type": "bool" ++ }, ++ { ++ "name": "hv-crash", ++ "type": "bool" ++ }, ++ { ++ "name": "nodeid_msr", ++ "type": "bool" ++ }, ++ { ++ "name": "hypervisor", ++ "type": "bool" ++ }, ++ { ++ "name": "enforce", ++ "type": "bool" ++ }, ++ { ++ "name": "stepping", ++ "type": "int" ++ }, ++ { ++ "name": "sse4_2", ++ "type": "bool" ++ }, ++ { ++ "name": "sse4_1", ++ "type": "bool" ++ }, ++ { ++ "name": "x-hv-max-vps", ++ "type": "int32" ++ }, ++ { ++ "name": "hv-frequencies", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm-hint-dedicated", ++ "type": "bool" ++ }, ++ { ++ "name": "cmp_legacy", ++ "type": "bool" ++ }, ++ { ++ "name": "tm2", ++ "type": "bool" ++ }, ++ { ++ "name": "smx", ++ "type": "bool" ++ }, ++ { ++ "name": "host-cache-info", ++ "type": "bool" ++ }, ++ { ++ "name": "hv-vendor-id", ++ "type": "str" ++ }, ++ { ++ "name": "movbe", ++ "type": "bool" ++ }, ++ { ++ "name": "3dnowprefetch", ++ "type": "bool" ++ }, ++ { ++ "name": "mtrr", ++ "type": "bool" ++ }, ++ { ++ "name": "wdt", ++ "type": "bool" ++ }, ++ { ++ "name": "thread-id", ++ "type": "int32" ++ }, ++ { ++ "name": "aes", ++ "type": "bool" ++ }, ++ { ++ "name": "apic-id", ++ "type": "uint32" ++ }, ++ { ++ "name": "lm", ++ "type": "bool" ++ }, ++ { ++ "name": "family", ++ "type": "int" ++ }, ++ { ++ "name": "tsc-adjust", ++ "type": "bool" ++ }, ++ { ++ "name": "pfthreshold", ++ "type": "bool" ++ }, ++ { ++ "name": "ospke", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm-no-smi-migration", ++ "type": "bool" ++ }, ++ { ++ "name": "pse", ++ "type": "bool" ++ }, ++ { ++ "name": "filtered-features", ++ "type": "X86CPUFeatureWordInfo" ++ }, ++ { ++ "name": "hv-vpindex", ++ "type": "bool" ++ }, ++ { ++ "name": "adx", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512bitalg", ++ "type": "bool" ++ }, ++ { ++ "name": "i64", ++ "type": "bool" ++ }, ++ { ++ "name": "vaes", ++ "type": "bool" ++ }, ++ { ++ "name": "ia64", ++ "type": "bool" ++ }, ++ { ++ "name": "nodeid-msr", ++ "type": "bool" ++ }, ++ { ++ "name": "ibpb", ++ "type": "bool" ++ }, ++ { ++ "name": "hv-synic", ++ "type": "bool" ++ }, ++ { ++ "name": "ibs", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm_mmu", ++ "type": "bool" ++ }, ++ { ++ "name": "tcg-cpuid", ++ "type": "bool" ++ }, ++ { ++ "name": "nrip_save", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm_nopiodelay", ++ "type": "bool" ++ }, ++ { ++ "name": "lbrv", ++ "type": "bool" ++ }, ++ { ++ "name": "rdtscp", ++ "type": "bool" ++ }, ++ { ++ "name": "memory", ++ "type": "link" ++ }, ++ { ++ "name": "avx512vbmi2", ++ "type": "bool" ++ }, ++ { ++ "name": "ace2-en", ++ "type": "bool" ++ }, ++ { ++ "name": "invtsc", ++ "type": "bool" ++ }, ++ { ++ "name": "sse4.2", ++ "type": "bool" ++ }, ++ { ++ "name": "sse4.1", ++ "type": "bool" ++ }, ++ { ++ "name": "pbe", ++ "type": "bool" ++ }, ++ { ++ "name": "rdrand", ++ "type": "bool" ++ }, ++ { ++ "name": "socket-id", ++ "type": "int32" ++ }, ++ { ++ "name": "hotpluggable", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm-steal-time", ++ "type": "bool" ++ }, ++ { ++ "name": "l3-cache", ++ "type": "bool" ++ }, ++ { ++ "name": "vmware-cpuid-freq", ++ "type": "bool" ++ }, ++ { ++ "name": "xop", ++ "type": "bool" ++ }, ++ { ++ "name": "tsc-frequency", ++ "type": "int" ++ }, ++ { ++ "name": "fill-mtrr-mask", ++ "type": "bool" ++ }, ++ { ++ "name": "core-id", ++ "type": "int32" ++ }, ++ { ++ "name": "intel-pt", ++ "type": "bool" ++ }, ++ { ++ "name": "pat", ++ "type": "bool" ++ }, ++ { ++ "name": "pcid", ++ "type": "bool" ++ }, ++ { ++ "name": "pclmulqdq", ++ "type": "bool" ++ }, ++ { ++ "name": "sse4-2", ++ "type": "bool" ++ }, ++ { ++ "name": "sse4-1", ++ "type": "bool" ++ }, ++ { ++ "name": "sha-ni", ++ "type": "bool" ++ }, ++ { ++ "name": "cmov", ++ "type": "bool" ++ }, ++ { ++ "name": "pae", ++ "type": "bool" ++ }, ++ { ++ "name": "smep", ++ "type": "bool" ++ }, ++ { ++ "name": "abm", ++ "type": "bool" ++ }, ++ { ++ "name": "xstore", ++ "type": "bool" ++ }, ++ { ++ "name": "tsc_adjust", ++ "type": "bool" ++ }, ++ { ++ "name": "type", ++ "type": "string" ++ }, ++ { ++ "name": "kvm-asyncpf", ++ "type": "bool" ++ }, ++ { ++ "name": "min-xlevel", ++ "type": "uint32" ++ }, ++ { ++ "name": "pdpe1gb", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm-mmu", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm-pv-unhalt", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512f", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512vbmi", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512-4vnniw", ++ "type": "bool" ++ }, ++ { ++ "name": "xd", ++ "type": "bool" ++ }, ++ { ++ "name": "mmxext", ++ "type": "bool" ++ }, ++ { ++ "name": "decodeassists", ++ "type": "bool" ++ }, ++ { ++ "name": "ht", ++ "type": "bool" ++ }, ++ { ++ "name": "xsave", ++ "type": "bool" ++ }, ++ { ++ "name": "perfctr_core", ++ "type": "bool" ++ }, ++ { ++ "name": "feature-words", ++ "type": "X86CPUFeatureWordInfo" ++ }, ++ { ++ "name": "migratable", ++ "type": "bool" ++ }, ++ { ++ "name": "3dnow", ++ "type": "bool" ++ }, ++ { ++ "name": "spec-ctrl", ++ "type": "bool" ++ }, ++ { ++ "name": "model", ++ "type": "int" ++ }, ++ { ++ "name": "nrip-save", ++ "type": "bool" ++ }, ++ { ++ "name": "lwp", ++ "type": "bool" ++ }, ++ { ++ "name": "xstore-en", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512vl", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm_pv_unhalt", ++ "type": "bool" ++ }, ++ { ++ "name": "bmi2", ++ "type": "bool" ++ }, ++ { ++ "name": "bmi1", ++ "type": "bool" ++ }, ++ { ++ "name": "la57", ++ "type": "bool" ++ }, ++ { ++ "name": "ffxsr", ++ "type": "bool" ++ }, ++ { ++ "name": "vmcb-clean", ++ "type": "bool" ++ }, ++ { ++ "name": "pause-filter", ++ "type": "bool" ++ }, ++ { ++ "name": "pni", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm_steal_time", ++ "type": "bool" ++ }, ++ { ++ "name": "svm_lock", ++ "type": "bool" ++ }, ++ { ++ "name": "pse36", ++ "type": "bool" ++ }, ++ { ++ "name": "hv-stimer", ++ "type": "bool" ++ }, ++ { ++ "name": "host-phys-bits", ++ "type": "bool" ++ }, ++ { ++ "name": "extapic", ++ "type": "bool" ++ }, ++ { ++ "name": "hv-spinlocks", ++ "type": "int" ++ }, ++ { ++ "name": "pmu", ++ "type": "bool" ++ }, ++ { ++ "name": "pmm", ++ "type": "bool" ++ }, ++ { ++ "name": "vpclmulqdq", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512-vpopcntdq", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512er", ++ "type": "bool" ++ }, ++ { ++ "name": "pdcm", ++ "type": "bool" ++ }, ++ { ++ "name": "svm", ++ "type": "bool" ++ }, ++ { ++ "name": "apic", ++ "type": "bool" ++ }, ++ { ++ "name": "xcrypt-en", ++ "type": "bool" ++ }, ++ { ++ "name": "cr8legacy", ++ "type": "bool" ++ }, ++ { ++ "name": "fma4", ++ "type": "bool" ++ }, ++ { ++ "name": "erms", ++ "type": "bool" ++ }, ++ { ++ "name": "msr", ++ "type": "bool" ++ }, ++ { ++ "name": "ds_cpl", ++ "type": "bool" ++ }, ++ { ++ "name": "xlevel", ++ "type": "uint32" ++ }, ++ { ++ "name": "hotplugged", ++ "type": "bool" ++ }, ++ { ++ "name": "hv-relaxed", ++ "type": "bool" ++ }, ++ { ++ "name": "perfctr-core", ++ "type": "bool" ++ }, ++ { ++ "name": "sep", ++ "type": "bool" ++ }, ++ { ++ "name": "smap", ++ "type": "bool" ++ }, ++ { ++ "name": "sse3", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512dq", ++ "type": "bool" ++ }, ++ { ++ "name": "ssse3", ++ "type": "bool" ++ }, ++ { ++ "name": "pmm-en", ++ "type": "bool" ++ }, ++ { ++ "name": "npt", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm-pv-tlb-flush", ++ "type": "bool" ++ }, ++ { ++ "name": "tsc", ++ "type": "bool" ++ }, ++ { ++ "name": "monitor", ++ "type": "bool" ++ }, ++ { ++ "name": "f16c", ++ "type": "bool" ++ }, ++ { ++ "name": "sse2", ++ "type": "bool" ++ }, ++ { ++ "name": "rdpid", ++ "type": "bool" ++ }, ++ { ++ "name": "mce", ++ "type": "bool" ++ }, ++ { ++ "name": "full-cpuid-auto-level", ++ "type": "bool" ++ }, ++ { ++ "name": "xtpr", ++ "type": "bool" ++ }, ++ { ++ "name": "mca", ++ "type": "bool" ++ }, ++ { ++ "name": "cid", ++ "type": "bool" ++ }, ++ { ++ "name": "tm", ++ "type": "bool" ++ }, ++ { ++ "name": "pku", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512vnni", ++ "type": "bool" ++ }, ++ { ++ "name": "tce", ++ "type": "bool" ++ }, ++ { ++ "name": "kvmclock", ++ "type": "bool" ++ }, ++ { ++ "name": "sse4a", ++ "type": "bool" ++ }, ++ { ++ "name": "ds", ++ "type": "bool" ++ }, ++ { ++ "name": "lahf-lm", ++ "type": "bool" ++ }, ++ { ++ "name": "xsaves", ++ "type": "bool" ++ }, ++ { ++ "name": "clflushopt", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm", ++ "type": "bool" ++ }, ++ { ++ "name": "ss", ++ "type": "bool" ++ }, ++ { ++ "name": "flushbyasid", ++ "type": "bool" ++ }, ++ { ++ "name": "pause_filter", ++ "type": "bool" ++ }, ++ { ++ "name": "de", ++ "type": "bool" ++ }, ++ { ++ "name": "est", ++ "type": "bool" ++ }, ++ { ++ "name": "check", ++ "type": "bool" ++ }, ++ { ++ "name": "lahf_lm", ++ "type": "bool" ++ }, ++ { ++ "name": "dtes64", ++ "type": "bool" ++ }, ++ { ++ "name": "vmx", ++ "type": "bool" ++ }, ++ { ++ "name": "xsavec", ++ "type": "bool" ++ }, ++ { ++ "name": "svm-lock", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512ifma", ++ "type": "bool" ++ }, ++ { ++ "name": "clflush", ++ "type": "bool" ++ }, ++ { ++ "name": "rdseed", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512cd", ++ "type": "bool" ++ }, ++ { ++ "name": "xsaveopt", ++ "type": "bool" ++ }, ++ { ++ "name": "tbm", ++ "type": "bool" ++ }, ++ { ++ "name": "ace2", ++ "type": "bool" ++ }, ++ { ++ "name": "vme", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm_asyncpf", ++ "type": "bool" ++ }, ++ { ++ "name": "hv-vapic", ++ "type": "bool" ++ }, ++ { ++ "name": "parent_bus", ++ "type": "link" ++ }, ++ { ++ "name": "lmce", ++ "type": "bool" ++ }, ++ { ++ "name": "hv-reset", ++ "type": "bool" ++ }, ++ { ++ "name": "hv-runtime", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512bw", ++ "type": "bool" ++ }, ++ { ++ "name": "xcrypt", ++ "type": "bool" ++ }, ++ { ++ "name": "fpu", ++ "type": "bool" ++ }, ++ { ++ "name": "fxsr", ++ "type": "bool" ++ }, ++ { ++ "name": "ds-cpl", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm-pv-eoi", ++ "type": "bool" ++ }, ++ { ++ "name": "hle", ++ "type": "bool" ++ }, ++ { ++ "name": "cx8", ++ "type": "bool" ++ }, ++ { ++ "name": "mpx", ++ "type": "bool" ++ }, ++ { ++ "name": "invpcid", ++ "type": "bool" ++ }, ++ { ++ "name": "pcommit", ++ "type": "bool" ++ }, ++ { ++ "name": "arat", ++ "type": "bool" ++ }, ++ { ++ "name": "sse", ++ "type": "bool" ++ }, ++ { ++ "name": "syscall", ++ "type": "bool" ++ }, ++ { ++ "name": "tsc_scale", ++ "type": "bool" ++ }, ++ { ++ "name": "xlevel2", ++ "type": "uint32" ++ }, ++ { ++ "name": "hv-time", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm_pv_eoi", ++ "type": "bool" ++ }, ++ { ++ "name": "osvw", ++ "type": "bool" ++ }, ++ { ++ "name": "perfctr-nb", ++ "type": "bool" ++ }, ++ { ++ "name": "rtm", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512-4fmaps", ++ "type": "bool" ++ }, ++ { ++ "name": "avx2", ++ "type": "bool" ++ }, ++ { ++ "name": "perfctr_nb", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm-nopiodelay", ++ "type": "bool" ++ }, ++ { ++ "name": "phys-bits", ++ "type": "uint32" ++ }, ++ { ++ "name": "avx512pf", ++ "type": "bool" ++ }, ++ { ++ "name": "level", ++ "type": "uint32" ++ }, ++ { ++ "name": "osxsave", ++ "type": "bool" ++ }, ++ { ++ "name": "cpuid-0xb", ++ "type": "bool" ++ }, ++ { ++ "name": "tsc-deadline", ++ "type": "bool" ++ }, ++ { ++ "name": "xgetbv1", ++ "type": "bool" ++ }, ++ { ++ "name": "fxsr_opt", ++ "type": "bool" ++ }, ++ { ++ "name": "popcnt", ++ "type": "bool" ++ }, ++ { ++ "name": "umip", ++ "type": "bool" ++ }, ++ { ++ "name": "realized", ++ "type": "bool" ++ }, ++ { ++ "name": "phe", ++ "type": "bool" ++ }, ++ { ++ "name": "cmp-legacy", ++ "type": "bool" ++ }, ++ { ++ "name": "dca", ++ "type": "bool" ++ }, ++ { ++ "name": "acpi", ++ "type": "bool" ++ }, ++ { ++ "name": "pn", ++ "type": "bool" ++ }, ++ { ++ "name": "model-id", ++ "type": "string" ++ }, ++ { ++ "name": "crash-information", ++ "type": "GuestPanicInformation" ++ }, ++ { ++ "name": "tsc-scale", ++ "type": "bool" ++ }, ++ { ++ "name": "node-id", ++ "type": "int32" ++ }, ++ { ++ "name": "cx16", ++ "type": "bool" ++ }, ++ { ++ "name": "mmx", ++ "type": "bool" ++ }, ++ { ++ "name": "topoext", ++ "type": "bool" ++ }, ++ { ++ "name": "pge", ++ "type": "bool" ++ }, ++ { ++ "name": "fsgsbase", ++ "type": "bool" ++ }, ++ { ++ "name": "pclmuldq", ++ "type": "bool" ++ }, ++ { ++ "name": "misalignsse", ++ "type": "bool" ++ }, ++ { ++ "name": "phe-en", ++ "type": "bool" ++ }, ++ { ++ "name": "fma", ++ "type": "bool" ++ } ++ ], ++ "id": "libvirt-43" ++} ++ ++{ ++ "execute": "query-machines", ++ "id": "libvirt-44" ++} ++ + { + "return": [ + { +@@ -5211,12 +6241,12 @@ + "cpu-max": 255 + } + ], +- "id": "libvirt-43" ++ "id": "libvirt-44" + } + + { + "execute": "query-cpu-definitions", +- "id": "libvirt-44" ++ "id": "libvirt-45" + } + + { +@@ -5730,12 +6760,12 @@ + "migration-safe": true + } + ], +- "id": "libvirt-44" ++ "id": "libvirt-45" + } + + { + "execute": "query-tpm-models", +- "id": "libvirt-45" ++ "id": "libvirt-46" + } + + { +@@ -5743,12 +6773,12 @@ + "tpm-crb", + "tpm-tis" + ], +- "id": "libvirt-45" ++ "id": "libvirt-46" + } + + { + "execute": "query-tpm-types", +- "id": "libvirt-46" ++ "id": "libvirt-47" + } + + { +@@ -5756,12 +6786,12 @@ + "passthrough", + "emulator" + ], +- "id": "libvirt-46" ++ "id": "libvirt-47" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-47" ++ "id": "libvirt-48" + } + + { +@@ -7048,12 +8078,12 @@ + "option": "drive" + } + ], +- "id": "libvirt-47" ++ "id": "libvirt-48" + } + + { + "execute": "query-migrate-capabilities", +- "id": "libvirt-48" ++ "id": "libvirt-49" + } + + { +@@ -7115,12 +8145,12 @@ + "capability": "dirty-bitmaps" + } + ], +- "id": "libvirt-48" ++ "id": "libvirt-49" + } + + { + "execute": "query-qmp-schema", +- "id": "libvirt-49" ++ "id": "libvirt-50" + } + + { +@@ -18488,7 +19518,7 @@ + "meta-type": "object" + } + ], +- "id": "libvirt-49" ++ "id": "libvirt-50" + } + + { +@@ -18499,7 +19529,7 @@ + "name": "host" + } + }, +- "id": "libvirt-50" ++ "id": "libvirt-51" + } + + { +@@ -18689,7 +19719,7 @@ + } + } + }, +- "id": "libvirt-50" ++ "id": "libvirt-51" + } + + { +@@ -18881,7 +19911,7 @@ + } + } + }, +- "id": "libvirt-51" ++ "id": "libvirt-52" + } + + { +@@ -19136,7 +20166,7 @@ + } + } + }, +- "id": "libvirt-51" ++ "id": "libvirt-52" + } + + { +@@ -19150,7 +20180,7 @@ + } + } + }, +- "id": "libvirt-52" ++ "id": "libvirt-53" + } + + { +@@ -19340,7 +20370,7 @@ + } + } + }, +- "id": "libvirt-52" ++ "id": "libvirt-53" + } + + { +@@ -19532,7 +20562,7 @@ + } + } + }, +- "id": "libvirt-53" ++ "id": "libvirt-54" + } + + { +@@ -19787,12 +20817,12 @@ + } + } + }, +- "id": "libvirt-53" ++ "id": "libvirt-54" + } + + { + "execute": "query-sev-capabilities", +- "id": "libvirt-54" ++ "id": "libvirt-55" + } + + { +@@ -19802,7 +20832,7 @@ + "cert-chain": "AQAAAAAOAAAAQAAAAAOAAAAQAAAAAOAAAAQAAAAAOAAAAQAAAAAOAAA", + "pdh": "AQAAAAAOAAAAQAAAAAOAAAAQAAAAAOAAAAQAAAAAOAAAAQAAAAAOAAAAQAAAAAOAAA" + }, +- "id": "libvirt-54" ++ "id": "libvirt-55" + } + + { +diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml +index f4416e7b55..a8a82ca110 100644 +--- a/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml +@@ -216,7 +216,7 @@ + + 2011090 + 0 +- 416196 ++ 431483 + v2.12.0-rc0 + x86_64 + +diff --git a/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.replies b/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.replies +index b2f8377248..9f44eb4fae 100644 +--- a/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.replies ++++ b/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.replies +@@ -5123,10 +5123,1072 @@ + } + + { +- "execute": "query-machines", ++ "execute": "qom-list-properties", ++ "arguments": { ++ "typename": "max-x86_64-cpu" ++ }, + "id": "libvirt-43" + } + ++{ ++ "return": [ ++ { ++ "name": "min-xlevel2", ++ "type": "uint32" ++ }, ++ { ++ "name": "amd-ssbd", ++ "type": "bool" ++ }, ++ { ++ "name": "vendor", ++ "type": "string" ++ }, ++ { ++ "name": "gfni", ++ "type": "bool" ++ }, ++ { ++ "name": "clwb", ++ "type": "bool" ++ }, ++ { ++ "name": "nx", ++ "type": "bool" ++ }, ++ { ++ "name": "x2apic", ++ "type": "bool" ++ }, ++ { ++ "name": "kvmclock-stable-bit", ++ "type": "bool" ++ }, ++ { ++ "name": "vmcb_clean", ++ "type": "bool" ++ }, ++ { ++ "name": "min-level", ++ "type": "uint32" ++ }, ++ { ++ "name": "fxsr-opt", ++ "type": "bool" ++ }, ++ { ++ "name": "skinit", ++ "type": "bool" ++ }, ++ { ++ "name": "avx", ++ "type": "bool" ++ }, ++ { ++ "name": "3dnowext", ++ "type": "bool" ++ }, ++ { ++ "name": "nodeid_msr", ++ "type": "bool" ++ }, ++ { ++ "name": "hv-crash", ++ "type": "bool" ++ }, ++ { ++ "name": "hypervisor", ++ "type": "bool" ++ }, ++ { ++ "name": "enforce", ++ "type": "bool" ++ }, ++ { ++ "name": "stepping", ++ "type": "int" ++ }, ++ { ++ "name": "sse4_2", ++ "type": "bool" ++ }, ++ { ++ "name": "sse4_1", ++ "type": "bool" ++ }, ++ { ++ "name": "x-hv-max-vps", ++ "type": "int32" ++ }, ++ { ++ "name": "hv-frequencies", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm-hint-dedicated", ++ "type": "bool" ++ }, ++ { ++ "name": "cmp_legacy", ++ "type": "bool" ++ }, ++ { ++ "name": "tm2", ++ "type": "bool" ++ }, ++ { ++ "name": "smx", ++ "type": "bool" ++ }, ++ { ++ "name": "host-cache-info", ++ "type": "bool" ++ }, ++ { ++ "name": "hv-vendor-id", ++ "type": "str" ++ }, ++ { ++ "name": "movbe", ++ "type": "bool" ++ }, ++ { ++ "name": "3dnowprefetch", ++ "type": "bool" ++ }, ++ { ++ "name": "mtrr", ++ "type": "bool" ++ }, ++ { ++ "name": "wdt", ++ "type": "bool" ++ }, ++ { ++ "name": "thread-id", ++ "type": "int32" ++ }, ++ { ++ "name": "aes", ++ "type": "bool" ++ }, ++ { ++ "name": "apic-id", ++ "type": "uint32" ++ }, ++ { ++ "name": "lm", ++ "type": "bool" ++ }, ++ { ++ "name": "family", ++ "type": "int" ++ }, ++ { ++ "name": "tsc-adjust", ++ "type": "bool" ++ }, ++ { ++ "name": "pfthreshold", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm-no-smi-migration", ++ "type": "bool" ++ }, ++ { ++ "name": "amd-no-ssb", ++ "type": "bool" ++ }, ++ { ++ "name": "pse", ++ "type": "bool" ++ }, ++ { ++ "name": "filtered-features", ++ "type": "X86CPUFeatureWordInfo" ++ }, ++ { ++ "name": "hv-vpindex", ++ "type": "bool" ++ }, ++ { ++ "name": "adx", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512bitalg", ++ "type": "bool" ++ }, ++ { ++ "name": "i64", ++ "type": "bool" ++ }, ++ { ++ "name": "vaes", ++ "type": "bool" ++ }, ++ { ++ "name": "ia64", ++ "type": "bool" ++ }, ++ { ++ "name": "nodeid-msr", ++ "type": "bool" ++ }, ++ { ++ "name": "ibpb", ++ "type": "bool" ++ }, ++ { ++ "name": "hv-synic", ++ "type": "bool" ++ }, ++ { ++ "name": "ibs", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm_mmu", ++ "type": "bool" ++ }, ++ { ++ "name": "tcg-cpuid", ++ "type": "bool" ++ }, ++ { ++ "name": "nrip_save", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm_nopiodelay", ++ "type": "bool" ++ }, ++ { ++ "name": "lbrv", ++ "type": "bool" ++ }, ++ { ++ "name": "rdtscp", ++ "type": "bool" ++ }, ++ { ++ "name": "memory", ++ "type": "link" ++ }, ++ { ++ "name": "avx512vbmi2", ++ "type": "bool" ++ }, ++ { ++ "name": "ace2-en", ++ "type": "bool" ++ }, ++ { ++ "name": "invtsc", ++ "type": "bool" ++ }, ++ { ++ "name": "sse4.2", ++ "type": "bool" ++ }, ++ { ++ "name": "sse4.1", ++ "type": "bool" ++ }, ++ { ++ "name": "pbe", ++ "type": "bool" ++ }, ++ { ++ "name": "rdrand", ++ "type": "bool" ++ }, ++ { ++ "name": "socket-id", ++ "type": "int32" ++ }, ++ { ++ "name": "hotpluggable", ++ "type": "bool" ++ }, ++ { ++ "name": "l3-cache", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm-steal-time", ++ "type": "bool" ++ }, ++ { ++ "name": "vmware-cpuid-freq", ++ "type": "bool" ++ }, ++ { ++ "name": "legacy-cache", ++ "type": "bool" ++ }, ++ { ++ "name": "xop", ++ "type": "bool" ++ }, ++ { ++ "name": "tsc-frequency", ++ "type": "int" ++ }, ++ { ++ "name": "fill-mtrr-mask", ++ "type": "bool" ++ }, ++ { ++ "name": "core-id", ++ "type": "int32" ++ }, ++ { ++ "name": "intel-pt", ++ "type": "bool" ++ }, ++ { ++ "name": "pat", ++ "type": "bool" ++ }, ++ { ++ "name": "pcid", ++ "type": "bool" ++ }, ++ { ++ "name": "pclmulqdq", ++ "type": "bool" ++ }, ++ { ++ "name": "sse4-2", ++ "type": "bool" ++ }, ++ { ++ "name": "sse4-1", ++ "type": "bool" ++ }, ++ { ++ "name": "sha-ni", ++ "type": "bool" ++ }, ++ { ++ "name": "cmov", ++ "type": "bool" ++ }, ++ { ++ "name": "pae", ++ "type": "bool" ++ }, ++ { ++ "name": "smep", ++ "type": "bool" ++ }, ++ { ++ "name": "virt-ssbd", ++ "type": "bool" ++ }, ++ { ++ "name": "abm", ++ "type": "bool" ++ }, ++ { ++ "name": "xstore", ++ "type": "bool" ++ }, ++ { ++ "name": "tsc_adjust", ++ "type": "bool" ++ }, ++ { ++ "name": "type", ++ "type": "string" ++ }, ++ { ++ "name": "kvm-asyncpf", ++ "type": "bool" ++ }, ++ { ++ "name": "pdpe1gb", ++ "type": "bool" ++ }, ++ { ++ "name": "min-xlevel", ++ "type": "uint32" ++ }, ++ { ++ "name": "kvm-mmu", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm-pv-unhalt", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512f", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512vbmi", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512-4vnniw", ++ "type": "bool" ++ }, ++ { ++ "name": "xd", ++ "type": "bool" ++ }, ++ { ++ "name": "mmxext", ++ "type": "bool" ++ }, ++ { ++ "name": "decodeassists", ++ "type": "bool" ++ }, ++ { ++ "name": "ht", ++ "type": "bool" ++ }, ++ { ++ "name": "xsave", ++ "type": "bool" ++ }, ++ { ++ "name": "perfctr_core", ++ "type": "bool" ++ }, ++ { ++ "name": "feature-words", ++ "type": "X86CPUFeatureWordInfo" ++ }, ++ { ++ "name": "migratable", ++ "type": "bool" ++ }, ++ { ++ "name": "3dnow", ++ "type": "bool" ++ }, ++ { ++ "name": "spec-ctrl", ++ "type": "bool" ++ }, ++ { ++ "name": "model", ++ "type": "int" ++ }, ++ { ++ "name": "nrip-save", ++ "type": "bool" ++ }, ++ { ++ "name": "lwp", ++ "type": "bool" ++ }, ++ { ++ "name": "xstore-en", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512vl", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm_pv_unhalt", ++ "type": "bool" ++ }, ++ { ++ "name": "bmi2", ++ "type": "bool" ++ }, ++ { ++ "name": "bmi1", ++ "type": "bool" ++ }, ++ { ++ "name": "la57", ++ "type": "bool" ++ }, ++ { ++ "name": "ffxsr", ++ "type": "bool" ++ }, ++ { ++ "name": "vmcb-clean", ++ "type": "bool" ++ }, ++ { ++ "name": "pause-filter", ++ "type": "bool" ++ }, ++ { ++ "name": "pni", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm_steal_time", ++ "type": "bool" ++ }, ++ { ++ "name": "svm_lock", ++ "type": "bool" ++ }, ++ { ++ "name": "pse36", ++ "type": "bool" ++ }, ++ { ++ "name": "hv-stimer", ++ "type": "bool" ++ }, ++ { ++ "name": "host-phys-bits", ++ "type": "bool" ++ }, ++ { ++ "name": "extapic", ++ "type": "bool" ++ }, ++ { ++ "name": "hv-spinlocks", ++ "type": "int" ++ }, ++ { ++ "name": "pmu", ++ "type": "bool" ++ }, ++ { ++ "name": "pmm", ++ "type": "bool" ++ }, ++ { ++ "name": "vpclmulqdq", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512-vpopcntdq", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512er", ++ "type": "bool" ++ }, ++ { ++ "name": "pdcm", ++ "type": "bool" ++ }, ++ { ++ "name": "svm", ++ "type": "bool" ++ }, ++ { ++ "name": "apic", ++ "type": "bool" ++ }, ++ { ++ "name": "xcrypt-en", ++ "type": "bool" ++ }, ++ { ++ "name": "cr8legacy", ++ "type": "bool" ++ }, ++ { ++ "name": "fma4", ++ "type": "bool" ++ }, ++ { ++ "name": "erms", ++ "type": "bool" ++ }, ++ { ++ "name": "msr", ++ "type": "bool" ++ }, ++ { ++ "name": "ds_cpl", ++ "type": "bool" ++ }, ++ { ++ "name": "xlevel", ++ "type": "uint32" ++ }, ++ { ++ "name": "sep", ++ "type": "bool" ++ }, ++ { ++ "name": "hotplugged", ++ "type": "bool" ++ }, ++ { ++ "name": "hv-relaxed", ++ "type": "bool" ++ }, ++ { ++ "name": "cldemote", ++ "type": "bool" ++ }, ++ { ++ "name": "perfctr-core", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512vnni", ++ "type": "bool" ++ }, ++ { ++ "name": "smap", ++ "type": "bool" ++ }, ++ { ++ "name": "sse3", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512dq", ++ "type": "bool" ++ }, ++ { ++ "name": "ssse3", ++ "type": "bool" ++ }, ++ { ++ "name": "pmm-en", ++ "type": "bool" ++ }, ++ { ++ "name": "npt", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm-pv-tlb-flush", ++ "type": "bool" ++ }, ++ { ++ "name": "tsc", ++ "type": "bool" ++ }, ++ { ++ "name": "monitor", ++ "type": "bool" ++ }, ++ { ++ "name": "f16c", ++ "type": "bool" ++ }, ++ { ++ "name": "sse2", ++ "type": "bool" ++ }, ++ { ++ "name": "rdpid", ++ "type": "bool" ++ }, ++ { ++ "name": "mce", ++ "type": "bool" ++ }, ++ { ++ "name": "full-cpuid-auto-level", ++ "type": "bool" ++ }, ++ { ++ "name": "xtpr", ++ "type": "bool" ++ }, ++ { ++ "name": "mca", ++ "type": "bool" ++ }, ++ { ++ "name": "cid", ++ "type": "bool" ++ }, ++ { ++ "name": "tm", ++ "type": "bool" ++ }, ++ { ++ "name": "pku", ++ "type": "bool" ++ }, ++ { ++ "name": "hv-tlbflush", ++ "type": "bool" ++ }, ++ { ++ "name": "ds", ++ "type": "bool" ++ }, ++ { ++ "name": "kvmclock", ++ "type": "bool" ++ }, ++ { ++ "name": "tce", ++ "type": "bool" ++ }, ++ { ++ "name": "sse4a", ++ "type": "bool" ++ }, ++ { ++ "name": "lahf-lm", ++ "type": "bool" ++ }, ++ { ++ "name": "xsaves", ++ "type": "bool" ++ }, ++ { ++ "name": "clflushopt", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm", ++ "type": "bool" ++ }, ++ { ++ "name": "ss", ++ "type": "bool" ++ }, ++ { ++ "name": "flushbyasid", ++ "type": "bool" ++ }, ++ { ++ "name": "md-clear", ++ "type": "bool" ++ }, ++ { ++ "name": "pause_filter", ++ "type": "bool" ++ }, ++ { ++ "name": "de", ++ "type": "bool" ++ }, ++ { ++ "name": "est", ++ "type": "bool" ++ }, ++ { ++ "name": "check", ++ "type": "bool" ++ }, ++ { ++ "name": "lahf_lm", ++ "type": "bool" ++ }, ++ { ++ "name": "dtes64", ++ "type": "bool" ++ }, ++ { ++ "name": "vmx", ++ "type": "bool" ++ }, ++ { ++ "name": "xsavec", ++ "type": "bool" ++ }, ++ { ++ "name": "svm-lock", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512ifma", ++ "type": "bool" ++ }, ++ { ++ "name": "clflush", ++ "type": "bool" ++ }, ++ { ++ "name": "rdseed", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512cd", ++ "type": "bool" ++ }, ++ { ++ "name": "xsaveopt", ++ "type": "bool" ++ }, ++ { ++ "name": "tbm", ++ "type": "bool" ++ }, ++ { ++ "name": "ace2", ++ "type": "bool" ++ }, ++ { ++ "name": "vme", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm_asyncpf", ++ "type": "bool" ++ }, ++ { ++ "name": "hv-vapic", ++ "type": "bool" ++ }, ++ { ++ "name": "parent_bus", ++ "type": "link" ++ }, ++ { ++ "name": "lmce", ++ "type": "bool" ++ }, ++ { ++ "name": "x-migrate-smi-count", ++ "type": "bool" ++ }, ++ { ++ "name": "hv-reset", ++ "type": "bool" ++ }, ++ { ++ "name": "hv-runtime", ++ "type": "bool" ++ }, ++ { ++ "name": "ssbd", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512bw", ++ "type": "bool" ++ }, ++ { ++ "name": "xcrypt", ++ "type": "bool" ++ }, ++ { ++ "name": "fpu", ++ "type": "bool" ++ }, ++ { ++ "name": "fxsr", ++ "type": "bool" ++ }, ++ { ++ "name": "ds-cpl", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm-pv-eoi", ++ "type": "bool" ++ }, ++ { ++ "name": "hle", ++ "type": "bool" ++ }, ++ { ++ "name": "cx8", ++ "type": "bool" ++ }, ++ { ++ "name": "mpx", ++ "type": "bool" ++ }, ++ { ++ "name": "invpcid", ++ "type": "bool" ++ }, ++ { ++ "name": "pcommit", ++ "type": "bool" ++ }, ++ { ++ "name": "arat", ++ "type": "bool" ++ }, ++ { ++ "name": "sse", ++ "type": "bool" ++ }, ++ { ++ "name": "syscall", ++ "type": "bool" ++ }, ++ { ++ "name": "tsc_scale", ++ "type": "bool" ++ }, ++ { ++ "name": "xlevel2", ++ "type": "uint32" ++ }, ++ { ++ "name": "hv-time", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm_pv_eoi", ++ "type": "bool" ++ }, ++ { ++ "name": "osvw", ++ "type": "bool" ++ }, ++ { ++ "name": "perfctr-nb", ++ "type": "bool" ++ }, ++ { ++ "name": "rtm", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512-4fmaps", ++ "type": "bool" ++ }, ++ { ++ "name": "avx2", ++ "type": "bool" ++ }, ++ { ++ "name": "perfctr_nb", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm-nopiodelay", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512pf", ++ "type": "bool" ++ }, ++ { ++ "name": "level", ++ "type": "uint32" ++ }, ++ { ++ "name": "phys-bits", ++ "type": "uint32" ++ }, ++ { ++ "name": "cpuid-0xb", ++ "type": "bool" ++ }, ++ { ++ "name": "tsc-deadline", ++ "type": "bool" ++ }, ++ { ++ "name": "fxsr_opt", ++ "type": "bool" ++ }, ++ { ++ "name": "xgetbv1", ++ "type": "bool" ++ }, ++ { ++ "name": "popcnt", ++ "type": "bool" ++ }, ++ { ++ "name": "umip", ++ "type": "bool" ++ }, ++ { ++ "name": "realized", ++ "type": "bool" ++ }, ++ { ++ "name": "phe", ++ "type": "bool" ++ }, ++ { ++ "name": "cmp-legacy", ++ "type": "bool" ++ }, ++ { ++ "name": "dca", ++ "type": "bool" ++ }, ++ { ++ "name": "acpi", ++ "type": "bool" ++ }, ++ { ++ "name": "pn", ++ "type": "bool" ++ }, ++ { ++ "name": "model-id", ++ "type": "string" ++ }, ++ { ++ "name": "crash-information", ++ "type": "GuestPanicInformation" ++ }, ++ { ++ "name": "tsc-scale", ++ "type": "bool" ++ }, ++ { ++ "name": "node-id", ++ "type": "int32" ++ }, ++ { ++ "name": "hv-reenlightenment", ++ "type": "bool" ++ }, ++ { ++ "name": "cx16", ++ "type": "bool" ++ }, ++ { ++ "name": "mmx", ++ "type": "bool" ++ }, ++ { ++ "name": "topoext", ++ "type": "bool" ++ }, ++ { ++ "name": "pge", ++ "type": "bool" ++ }, ++ { ++ "name": "fsgsbase", ++ "type": "bool" ++ }, ++ { ++ "name": "pclmuldq", ++ "type": "bool" ++ }, ++ { ++ "name": "misalignsse", ++ "type": "bool" ++ }, ++ { ++ "name": "phe-en", ++ "type": "bool" ++ }, ++ { ++ "name": "fma", ++ "type": "bool" ++ } ++ ], ++ "id": "libvirt-43" ++} ++ ++{ ++ "execute": "query-machines", ++ "id": "libvirt-44" ++} ++ + { + "return": [ + { +@@ -5333,12 +6395,12 @@ + "cpu-max": 255 + } + ], +- "id": "libvirt-43" ++ "id": "libvirt-44" + } + + { + "execute": "query-cpu-definitions", +- "id": "libvirt-44" ++ "id": "libvirt-45" + } + + { +@@ -5775,12 +6837,12 @@ + "migration-safe": true + } + ], +- "id": "libvirt-44" ++ "id": "libvirt-45" + } + + { + "execute": "query-tpm-models", +- "id": "libvirt-45" ++ "id": "libvirt-46" + } + + { +@@ -5788,12 +6850,12 @@ + "tpm-crb", + "tpm-tis" + ], +- "id": "libvirt-45" ++ "id": "libvirt-46" + } + + { + "execute": "query-tpm-types", +- "id": "libvirt-46" ++ "id": "libvirt-47" + } + + { +@@ -5801,12 +6863,12 @@ + "passthrough", + "emulator" + ], +- "id": "libvirt-46" ++ "id": "libvirt-47" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-47" ++ "id": "libvirt-48" + } + + { +@@ -7105,12 +8167,12 @@ + "option": "drive" + } + ], +- "id": "libvirt-47" ++ "id": "libvirt-48" + } + + { + "execute": "query-migrate-capabilities", +- "id": "libvirt-48" ++ "id": "libvirt-49" + } + + { +@@ -7180,12 +8242,12 @@ + "capability": "late-block-activate" + } + ], +- "id": "libvirt-48" ++ "id": "libvirt-49" + } + + { + "execute": "query-qmp-schema", +- "id": "libvirt-49" ++ "id": "libvirt-50" + } + + { +@@ -19425,7 +20487,7 @@ + "meta-type": "object" + } + ], +- "id": "libvirt-49" ++ "id": "libvirt-50" + } + + { +@@ -19436,7 +20498,7 @@ + "name": "host" + } + }, +- "id": "libvirt-50" ++ "id": "libvirt-51" + } + + { +@@ -19629,7 +20691,7 @@ + } + } + }, +- "id": "libvirt-50" ++ "id": "libvirt-51" + } + + { +@@ -19824,7 +20886,7 @@ + } + } + }, +- "id": "libvirt-51" ++ "id": "libvirt-52" + } + + { +@@ -20086,7 +21148,7 @@ + } + } + }, +- "id": "libvirt-51" ++ "id": "libvirt-52" + } + + { +@@ -20100,7 +21162,7 @@ + } + } + }, +- "id": "libvirt-52" ++ "id": "libvirt-53" + } + + { +@@ -20293,7 +21355,7 @@ + } + } + }, +- "id": "libvirt-52" ++ "id": "libvirt-53" + } + + { +@@ -20488,7 +21550,7 @@ + } + } + }, +- "id": "libvirt-53" ++ "id": "libvirt-54" + } + + { +@@ -20750,16 +21812,16 @@ + } + } + }, +- "id": "libvirt-53" +-} +- +-{ +- "execute": "query-sev-capabilities", + "id": "libvirt-54" + } + + { +- "id": "libvirt-54", ++ "execute": "query-sev-capabilities", ++ "id": "libvirt-55" ++} ++ ++{ ++ "id": "libvirt-55", + "error": { + "class": "GenericError", + "desc": "SEV feature is not available" +diff --git a/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml +index dceb719fcf..22dc60d13e 100644 +--- a/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml +@@ -218,7 +218,7 @@ + + 2012090 + 0 +- 438109 ++ 453907 + v3.0.0-rc0-31-g633e824037 + x86_64 + +diff --git a/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.replies b/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.replies +index ab0ac1e7bf..82b320b1d0 100644 +--- a/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.replies ++++ b/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.replies +@@ -5510,10 +5510,1144 @@ + } + + { +- "execute": "query-machines", ++ "execute": "qom-list-properties", ++ "arguments": { ++ "typename": "max-x86_64-cpu" ++ }, + "id": "libvirt-43" + } + ++{ ++ "return": [ ++ { ++ "name": "type", ++ "type": "string" ++ }, ++ { ++ "name": "min-xlevel2", ++ "type": "uint32" ++ }, ++ { ++ "name": "amd-ssbd", ++ "type": "bool" ++ }, ++ { ++ "name": "vendor", ++ "type": "string" ++ }, ++ { ++ "name": "gfni", ++ "type": "bool" ++ }, ++ { ++ "name": "clwb", ++ "type": "bool" ++ }, ++ { ++ "name": "nx", ++ "type": "bool" ++ }, ++ { ++ "name": "x2apic", ++ "type": "bool" ++ }, ++ { ++ "name": "mds-no", ++ "type": "bool" ++ }, ++ { ++ "name": "kvmclock-stable-bit", ++ "type": "bool" ++ }, ++ { ++ "name": "vmcb_clean", ++ "type": "bool" ++ }, ++ { ++ "name": "min-level", ++ "type": "uint32" ++ }, ++ { ++ "name": "fxsr-opt", ++ "type": "bool" ++ }, ++ { ++ "name": "skinit", ++ "type": "bool" ++ }, ++ { ++ "name": "avx", ++ "type": "bool" ++ }, ++ { ++ "name": "unavailable-features", ++ "type": "strList" ++ }, ++ { ++ "name": "3dnowext", ++ "type": "bool" ++ }, ++ { ++ "name": "nodeid_msr", ++ "type": "bool" ++ }, ++ { ++ "name": "hv-crash", ++ "type": "bool" ++ }, ++ { ++ "name": "hypervisor", ++ "type": "bool" ++ }, ++ { ++ "name": "enforce", ++ "type": "bool" ++ }, ++ { ++ "name": "stepping", ++ "type": "int" ++ }, ++ { ++ "name": "sse4_2", ++ "type": "bool" ++ }, ++ { ++ "name": "sse4_1", ++ "type": "bool" ++ }, ++ { ++ "name": "x-hv-max-vps", ++ "type": "int32" ++ }, ++ { ++ "name": "hv-frequencies", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm-hint-dedicated", ++ "type": "bool" ++ }, ++ { ++ "name": "cmp_legacy", ++ "type": "bool" ++ }, ++ { ++ "name": "tm2", ++ "type": "bool" ++ }, ++ { ++ "name": "smx", ++ "type": "bool" ++ }, ++ { ++ "name": "host-cache-info", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm-pv-ipi", ++ "type": "bool" ++ }, ++ { ++ "name": "hv-vendor-id", ++ "type": "str" ++ }, ++ { ++ "name": "movbe", ++ "type": "bool" ++ }, ++ { ++ "name": "3dnowprefetch", ++ "type": "bool" ++ }, ++ { ++ "name": "mtrr", ++ "type": "bool" ++ }, ++ { ++ "name": "wdt", ++ "type": "bool" ++ }, ++ { ++ "name": "thread-id", ++ "type": "int32" ++ }, ++ { ++ "name": "aes", ++ "type": "bool" ++ }, ++ { ++ "name": "apic-id", ++ "type": "uint32" ++ }, ++ { ++ "name": "lm", ++ "type": "bool" ++ }, ++ { ++ "name": "family", ++ "type": "int" ++ }, ++ { ++ "name": "tsc-adjust", ++ "type": "bool" ++ }, ++ { ++ "name": "pfthreshold", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm-no-smi-migration", ++ "type": "bool" ++ }, ++ { ++ "name": "amd-no-ssb", ++ "type": "bool" ++ }, ++ { ++ "name": "pse", ++ "type": "bool" ++ }, ++ { ++ "name": "filtered-features", ++ "type": "X86CPUFeatureWordInfo" ++ }, ++ { ++ "name": "hv-evmcs", ++ "type": "bool" ++ }, ++ { ++ "name": "hv-vpindex", ++ "type": "bool" ++ }, ++ { ++ "name": "i64", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512bitalg", ++ "type": "bool" ++ }, ++ { ++ "name": "adx", ++ "type": "bool" ++ }, ++ { ++ "name": "vaes", ++ "type": "bool" ++ }, ++ { ++ "name": "ia64", ++ "type": "bool" ++ }, ++ { ++ "name": "nodeid-msr", ++ "type": "bool" ++ }, ++ { ++ "name": "ibpb", ++ "type": "bool" ++ }, ++ { ++ "name": "hv-synic", ++ "type": "bool" ++ }, ++ { ++ "name": "ibs", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm_mmu", ++ "type": "bool" ++ }, ++ { ++ "name": "tcg-cpuid", ++ "type": "bool" ++ }, ++ { ++ "name": "nrip_save", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm_nopiodelay", ++ "type": "bool" ++ }, ++ { ++ "name": "lbrv", ++ "type": "bool" ++ }, ++ { ++ "name": "rdtscp", ++ "type": "bool" ++ }, ++ { ++ "name": "memory", ++ "type": "link" ++ }, ++ { ++ "name": "avx512vbmi2", ++ "type": "bool" ++ }, ++ { ++ "name": "ace2-en", ++ "type": "bool" ++ }, ++ { ++ "name": "invtsc", ++ "type": "bool" ++ }, ++ { ++ "name": "sse4.2", ++ "type": "bool" ++ }, ++ { ++ "name": "sse4.1", ++ "type": "bool" ++ }, ++ { ++ "name": "pbe", ++ "type": "bool" ++ }, ++ { ++ "name": "rdrand", ++ "type": "bool" ++ }, ++ { ++ "name": "socket-id", ++ "type": "int32" ++ }, ++ { ++ "name": "hotpluggable", ++ "type": "bool" ++ }, ++ { ++ "name": "l3-cache", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm-steal-time", ++ "type": "bool" ++ }, ++ { ++ "name": "vmware-cpuid-freq", ++ "type": "bool" ++ }, ++ { ++ "name": "legacy-cache", ++ "type": "bool" ++ }, ++ { ++ "name": "xop", ++ "type": "bool" ++ }, ++ { ++ "name": "tsc-frequency", ++ "type": "int" ++ }, ++ { ++ "name": "fill-mtrr-mask", ++ "type": "bool" ++ }, ++ { ++ "name": "core-id", ++ "type": "int32" ++ }, ++ { ++ "name": "intel-pt", ++ "type": "bool" ++ }, ++ { ++ "name": "pat", ++ "type": "bool" ++ }, ++ { ++ "name": "pcid", ++ "type": "bool" ++ }, ++ { ++ "name": "rsba", ++ "type": "bool" ++ }, ++ { ++ "name": "sse4-2", ++ "type": "bool" ++ }, ++ { ++ "name": "sse4-1", ++ "type": "bool" ++ }, ++ { ++ "name": "pclmulqdq", ++ "type": "bool" ++ }, ++ { ++ "name": "sha-ni", ++ "type": "bool" ++ }, ++ { ++ "name": "cmov", ++ "type": "bool" ++ }, ++ { ++ "name": "pae", ++ "type": "bool" ++ }, ++ { ++ "name": "smep", ++ "type": "bool" ++ }, ++ { ++ "name": "arch-capabilities", ++ "type": "bool" ++ }, ++ { ++ "name": "virt-ssbd", ++ "type": "bool" ++ }, ++ { ++ "name": "abm", ++ "type": "bool" ++ }, ++ { ++ "name": "xstore", ++ "type": "bool" ++ }, ++ { ++ "name": "tsc_adjust", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm-asyncpf", ++ "type": "bool" ++ }, ++ { ++ "name": "pdpe1gb", ++ "type": "bool" ++ }, ++ { ++ "name": "min-xlevel", ++ "type": "uint32" ++ }, ++ { ++ "name": "kvm-mmu", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm-pv-unhalt", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512f", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512vbmi", ++ "type": "bool" ++ }, ++ { ++ "name": "xd", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512-4vnniw", ++ "type": "bool" ++ }, ++ { ++ "name": "mmxext", ++ "type": "bool" ++ }, ++ { ++ "name": "decodeassists", ++ "type": "bool" ++ }, ++ { ++ "name": "ht", ++ "type": "bool" ++ }, ++ { ++ "name": "xsave", ++ "type": "bool" ++ }, ++ { ++ "name": "perfctr_core", ++ "type": "bool" ++ }, ++ { ++ "name": "feature-words", ++ "type": "X86CPUFeatureWordInfo" ++ }, ++ { ++ "name": "migratable", ++ "type": "bool" ++ }, ++ { ++ "name": "3dnow", ++ "type": "bool" ++ }, ++ { ++ "name": "spec-ctrl", ++ "type": "bool" ++ }, ++ { ++ "name": "model", ++ "type": "int" ++ }, ++ { ++ "name": "nrip-save", ++ "type": "bool" ++ }, ++ { ++ "name": "lwp", ++ "type": "bool" ++ }, ++ { ++ "name": "xstore-en", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512vl", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm_pv_unhalt", ++ "type": "bool" ++ }, ++ { ++ "name": "bmi2", ++ "type": "bool" ++ }, ++ { ++ "name": "bmi1", ++ "type": "bool" ++ }, ++ { ++ "name": "la57", ++ "type": "bool" ++ }, ++ { ++ "name": "ffxsr", ++ "type": "bool" ++ }, ++ { ++ "name": "stibp", ++ "type": "bool" ++ }, ++ { ++ "name": "vmcb-clean", ++ "type": "bool" ++ }, ++ { ++ "name": "wbnoinvd", ++ "type": "bool" ++ }, ++ { ++ "name": "pause-filter", ++ "type": "bool" ++ }, ++ { ++ "name": "pni", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm_steal_time", ++ "type": "bool" ++ }, ++ { ++ "name": "rdctl-no", ++ "type": "bool" ++ }, ++ { ++ "name": "svm_lock", ++ "type": "bool" ++ }, ++ { ++ "name": "ibrs-all", ++ "type": "bool" ++ }, ++ { ++ "name": "pse36", ++ "type": "bool" ++ }, ++ { ++ "name": "hv-stimer", ++ "type": "bool" ++ }, ++ { ++ "name": "host-phys-bits", ++ "type": "bool" ++ }, ++ { ++ "name": "extapic", ++ "type": "bool" ++ }, ++ { ++ "name": "skip-l1dfl-vmentry", ++ "type": "bool" ++ }, ++ { ++ "name": "hv-spinlocks", ++ "type": "int" ++ }, ++ { ++ "name": "pmu", ++ "type": "bool" ++ }, ++ { ++ "name": "pmm", ++ "type": "bool" ++ }, ++ { ++ "name": "vpclmulqdq", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512-vpopcntdq", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512er", ++ "type": "bool" ++ }, ++ { ++ "name": "pdcm", ++ "type": "bool" ++ }, ++ { ++ "name": "svm", ++ "type": "bool" ++ }, ++ { ++ "name": "apic", ++ "type": "bool" ++ }, ++ { ++ "name": "xcrypt-en", ++ "type": "bool" ++ }, ++ { ++ "name": "cr8legacy", ++ "type": "bool" ++ }, ++ { ++ "name": "fma4", ++ "type": "bool" ++ }, ++ { ++ "name": "host-phys-bits-limit", ++ "type": "uint8" ++ }, ++ { ++ "name": "erms", ++ "type": "bool" ++ }, ++ { ++ "name": "msr", ++ "type": "bool" ++ }, ++ { ++ "name": "ds_cpl", ++ "type": "bool" ++ }, ++ { ++ "name": "xlevel", ++ "type": "uint32" ++ }, ++ { ++ "name": "xsaves", ++ "type": "bool" ++ }, ++ { ++ "name": "hotplugged", ++ "type": "bool" ++ }, ++ { ++ "name": "hv-relaxed", ++ "type": "bool" ++ }, ++ { ++ "name": "pause_filter", ++ "type": "bool" ++ }, ++ { ++ "name": "cldemote", ++ "type": "bool" ++ }, ++ { ++ "name": "perfctr-core", ++ "type": "bool" ++ }, ++ { ++ "name": "hv-ipi", ++ "type": "bool" ++ }, ++ { ++ "name": "smap", ++ "type": "bool" ++ }, ++ { ++ "name": "sse3", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512dq", ++ "type": "bool" ++ }, ++ { ++ "name": "ssse3", ++ "type": "bool" ++ }, ++ { ++ "name": "pmm-en", ++ "type": "bool" ++ }, ++ { ++ "name": "npt", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm-pv-tlb-flush", ++ "type": "bool" ++ }, ++ { ++ "name": "tsc", ++ "type": "bool" ++ }, ++ { ++ "name": "monitor", ++ "type": "bool" ++ }, ++ { ++ "name": "f16c", ++ "type": "bool" ++ }, ++ { ++ "name": "sse2", ++ "type": "bool" ++ }, ++ { ++ "name": "rdpid", ++ "type": "bool" ++ }, ++ { ++ "name": "mce", ++ "type": "bool" ++ }, ++ { ++ "name": "full-cpuid-auto-level", ++ "type": "bool" ++ }, ++ { ++ "name": "xtpr", ++ "type": "bool" ++ }, ++ { ++ "name": "mca", ++ "type": "bool" ++ }, ++ { ++ "name": "cid", ++ "type": "bool" ++ }, ++ { ++ "name": "tm", ++ "type": "bool" ++ }, ++ { ++ "name": "sep", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512vnni", ++ "type": "bool" ++ }, ++ { ++ "name": "ds", ++ "type": "bool" ++ }, ++ { ++ "name": "pku", ++ "type": "bool" ++ }, ++ { ++ "name": "tce", ++ "type": "bool" ++ }, ++ { ++ "name": "sse4a", ++ "type": "bool" ++ }, ++ { ++ "name": "kvmclock", ++ "type": "bool" ++ }, ++ { ++ "name": "lahf-lm", ++ "type": "bool" ++ }, ++ { ++ "name": "clflushopt", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm", ++ "type": "bool" ++ }, ++ { ++ "name": "ss", ++ "type": "bool" ++ }, ++ { ++ "name": "flushbyasid", ++ "type": "bool" ++ }, ++ { ++ "name": "hv-tlbflush", ++ "type": "bool" ++ }, ++ { ++ "name": "lahf_lm", ++ "type": "bool" ++ }, ++ { ++ "name": "de", ++ "type": "bool" ++ }, ++ { ++ "name": "xsavec", ++ "type": "bool" ++ }, ++ { ++ "name": "est", ++ "type": "bool" ++ }, ++ { ++ "name": "check", ++ "type": "bool" ++ }, ++ { ++ "name": "movdir64b", ++ "type": "bool" ++ }, ++ { ++ "name": "dtes64", ++ "type": "bool" ++ }, ++ { ++ "name": "md-clear", ++ "type": "bool" ++ }, ++ { ++ "name": "vmx", ++ "type": "bool" ++ }, ++ { ++ "name": "svm-lock", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512ifma", ++ "type": "bool" ++ }, ++ { ++ "name": "clflush", ++ "type": "bool" ++ }, ++ { ++ "name": "rdseed", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512cd", ++ "type": "bool" ++ }, ++ { ++ "name": "xsaveopt", ++ "type": "bool" ++ }, ++ { ++ "name": "tbm", ++ "type": "bool" ++ }, ++ { ++ "name": "ace2", ++ "type": "bool" ++ }, ++ { ++ "name": "vme", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm_asyncpf", ++ "type": "bool" ++ }, ++ { ++ "name": "hv-vapic", ++ "type": "bool" ++ }, ++ { ++ "name": "parent_bus", ++ "type": "link" ++ }, ++ { ++ "name": "lmce", ++ "type": "bool" ++ }, ++ { ++ "name": "x-migrate-smi-count", ++ "type": "bool" ++ }, ++ { ++ "name": "hv-reset", ++ "type": "bool" ++ }, ++ { ++ "name": "hv-runtime", ++ "type": "bool" ++ }, ++ { ++ "name": "ssbd", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512bw", ++ "type": "bool" ++ }, ++ { ++ "name": "xcrypt", ++ "type": "bool" ++ }, ++ { ++ "name": "fpu", ++ "type": "bool" ++ }, ++ { ++ "name": "arat", ++ "type": "bool" ++ }, ++ { ++ "name": "fxsr", ++ "type": "bool" ++ }, ++ { ++ "name": "ds-cpl", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm-pv-eoi", ++ "type": "bool" ++ }, ++ { ++ "name": "hle", ++ "type": "bool" ++ }, ++ { ++ "name": "mpx", ++ "type": "bool" ++ }, ++ { ++ "name": "invpcid", ++ "type": "bool" ++ }, ++ { ++ "name": "cx8", ++ "type": "bool" ++ }, ++ { ++ "name": "pcommit", ++ "type": "bool" ++ }, ++ { ++ "name": "sse", ++ "type": "bool" ++ }, ++ { ++ "name": "syscall", ++ "type": "bool" ++ }, ++ { ++ "name": "tsc_scale", ++ "type": "bool" ++ }, ++ { ++ "name": "movdiri", ++ "type": "bool" ++ }, ++ { ++ "name": "ssb-no", ++ "type": "bool" ++ }, ++ { ++ "name": "xlevel2", ++ "type": "uint32" ++ }, ++ { ++ "name": "hv-time", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm_pv_eoi", ++ "type": "bool" ++ }, ++ { ++ "name": "osvw", ++ "type": "bool" ++ }, ++ { ++ "name": "perfctr-nb", ++ "type": "bool" ++ }, ++ { ++ "name": "rtm", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512-4fmaps", ++ "type": "bool" ++ }, ++ { ++ "name": "avx2", ++ "type": "bool" ++ }, ++ { ++ "name": "perfctr_nb", ++ "type": "bool" ++ }, ++ { ++ "name": "kvm-nopiodelay", ++ "type": "bool" ++ }, ++ { ++ "name": "avx512pf", ++ "type": "bool" ++ }, ++ { ++ "name": "level", ++ "type": "uint32" ++ }, ++ { ++ "name": "phys-bits", ++ "type": "uint32" ++ }, ++ { ++ "name": "cpuid-0xb", ++ "type": "bool" ++ }, ++ { ++ "name": "tsc-deadline", ++ "type": "bool" ++ }, ++ { ++ "name": "fxsr_opt", ++ "type": "bool" ++ }, ++ { ++ "name": "xgetbv1", ++ "type": "bool" ++ }, ++ { ++ "name": "popcnt", ++ "type": "bool" ++ }, ++ { ++ "name": "umip", ++ "type": "bool" ++ }, ++ { ++ "name": "realized", ++ "type": "bool" ++ }, ++ { ++ "name": "phe", ++ "type": "bool" ++ }, ++ { ++ "name": "cmp-legacy", ++ "type": "bool" ++ }, ++ { ++ "name": "dca", ++ "type": "bool" ++ }, ++ { ++ "name": "acpi", ++ "type": "bool" ++ }, ++ { ++ "name": "pn", ++ "type": "bool" ++ }, ++ { ++ "name": "model-id", ++ "type": "string" ++ }, ++ { ++ "name": "crash-information", ++ "type": "GuestPanicInformation" ++ }, ++ { ++ "name": "x-intel-pt-auto-level", ++ "type": "bool" ++ }, ++ { ++ "name": "x-hv-synic-kvm-only", ++ "type": "bool" ++ }, ++ { ++ "name": "tsc-scale", ++ "type": "bool" ++ }, ++ { ++ "name": "node-id", ++ "type": "int32" ++ }, ++ { ++ "name": "hv-reenlightenment", ++ "type": "bool" ++ }, ++ { ++ "name": "cx16", ++ "type": "bool" ++ }, ++ { ++ "name": "mmx", ++ "type": "bool" ++ }, ++ { ++ "name": "topoext", ++ "type": "bool" ++ }, ++ { ++ "name": "pge", ++ "type": "bool" ++ }, ++ { ++ "name": "fsgsbase", ++ "type": "bool" ++ }, ++ { ++ "name": "pclmuldq", ++ "type": "bool" ++ }, ++ { ++ "name": "misalignsse", ++ "type": "bool" ++ }, ++ { ++ "name": "phe-en", ++ "type": "bool" ++ }, ++ { ++ "name": "fma", ++ "type": "bool" ++ } ++ ], ++ "id": "libvirt-43" ++} ++ ++{ ++ "execute": "query-machines", ++ "id": "libvirt-44" ++} ++ + { + "return": [ + { +@@ -5755,12 +6889,12 @@ + "alias": "q35" + } + ], +- "id": "libvirt-43" ++ "id": "libvirt-44" + } + + { + "execute": "query-cpu-definitions", +- "id": "libvirt-44" ++ "id": "libvirt-45" + } + + { +@@ -6310,12 +7444,12 @@ + "migration-safe": true + } + ], +- "id": "libvirt-44" ++ "id": "libvirt-45" + } + + { + "execute": "query-tpm-models", +- "id": "libvirt-45" ++ "id": "libvirt-46" + } + + { +@@ -6323,12 +7457,12 @@ + "tpm-crb", + "tpm-tis" + ], +- "id": "libvirt-45" ++ "id": "libvirt-46" + } + + { + "execute": "query-tpm-types", +- "id": "libvirt-46" ++ "id": "libvirt-47" + } + + { +@@ -6336,12 +7470,12 @@ + "passthrough", + "emulator" + ], +- "id": "libvirt-46" ++ "id": "libvirt-47" + } + + { + "execute": "query-command-line-options", +- "id": "libvirt-47" ++ "id": "libvirt-48" + } + + { +@@ -7611,12 +8745,12 @@ + "option": "drive" + } + ], +- "id": "libvirt-47" ++ "id": "libvirt-48" + } + + { + "execute": "query-migrate-capabilities", +- "id": "libvirt-48" ++ "id": "libvirt-49" + } + + { +@@ -7690,12 +8824,12 @@ + "capability": "x-ignore-shared" + } + ], +- "id": "libvirt-48" ++ "id": "libvirt-49" + } + + { + "execute": "query-qmp-schema", +- "id": "libvirt-49" ++ "id": "libvirt-50" + } + + { +@@ -20178,7 +21312,7 @@ + ] + } + ], +- "id": "libvirt-49" ++ "id": "libvirt-50" + } + + { +@@ -20189,7 +21323,7 @@ + "name": "host" + } + }, +- "id": "libvirt-50" ++ "id": "libvirt-51" + } + + { +@@ -20395,7 +21529,7 @@ + } + } + }, +- "id": "libvirt-50" ++ "id": "libvirt-51" + } + + { +@@ -20603,7 +21737,7 @@ + } + } + }, +- "id": "libvirt-51" ++ "id": "libvirt-52" + } + + { +@@ -20884,7 +22018,7 @@ + } + } + }, +- "id": "libvirt-51" ++ "id": "libvirt-52" + } + + { +@@ -20898,7 +22032,7 @@ + } + } + }, +- "id": "libvirt-52" ++ "id": "libvirt-53" + } + + { +@@ -21104,7 +22238,7 @@ + } + } + }, +- "id": "libvirt-52" ++ "id": "libvirt-53" + } + + { +@@ -21312,7 +22446,7 @@ + } + } + }, +- "id": "libvirt-53" ++ "id": "libvirt-54" + } + + { +@@ -21593,16 +22727,16 @@ + } + } + }, +- "id": "libvirt-53" +-} +- +-{ +- "execute": "query-sev-capabilities", + "id": "libvirt-54" + } + + { +- "id": "libvirt-54", ++ "execute": "query-sev-capabilities", ++ "id": "libvirt-55" ++} ++ ++{ ++ "id": "libvirt-55", + "error": { + "class": "GenericError", + "desc": "SEV feature is not available" +diff --git a/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml +index 4836dbb8a4..95d26dfce8 100644 +--- a/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml +@@ -215,9 +215,10 @@ + + + ++ + 4000050 + 0 +- 456805 ++ 473743 + v4.0.0-1173-g9c70209b63 + x86_64 + +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu-Probe-host-CPU-after-capabilities.patch b/SOURCES/libvirt-qemu-Probe-host-CPU-after-capabilities.patch new file mode 100644 index 0000000..6229e6b --- /dev/null +++ b/SOURCES/libvirt-qemu-Probe-host-CPU-after-capabilities.patch @@ -0,0 +1,403 @@ +From d2ef598bb59e613ce4a8b969ab9836604bd72727 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:54 +0200 +Subject: [PATCH] qemu: Probe host CPU after capabilities +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The way we call query-cpu-model-expansion will rely on some capabilities +bits. Let's make sure all capabilities are set before probing host CPU. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 6f6401fbae384c66ce6043ced30591050729a4ac) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Conflicts: + src/qemu/qemu_capabilities.c + - various refactors were not backported + + tests/qemucapabilitiesdata/caps_2.12.0.x86_64.replies + tests/qemucapabilitiesdata/caps_3.0.0.x86_64.replies + - QMP message IDs are different + + tests/qemucapabilitiesdata/caps_3.1.0.x86_64.replies + tests/qemucapabilitiesdata/caps_4.0.0.x86_64.replies + - missing + + tests/qemucapabilitiesdata/caps_4.1.0.x86_64.replies + - QMP message IDs are different + +Signed-off-by: Jiri Denemark +Message-Id: +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_capabilities.c | 8 +++- + .../caps_2.12.0.x86_64.replies | 44 +++++++++---------- + .../caps_3.0.0.x86_64.replies | 40 ++++++++--------- + .../caps_4.1.0.x86_64.replies | 40 ++++++++--------- + 4 files changed, 68 insertions(+), 64 deletions(-) + +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index beec9d1497..fb260eae96 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -4343,8 +4343,6 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps, + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_QMP_SCHEMA) && + virQEMUCapsProbeQMPSchemaCapabilities(qemuCaps, mon) < 0) + goto cleanup; +- if (virQEMUCapsProbeQMPHostCPU(qemuCaps, mon, false) < 0) +- goto cleanup; + + /* 'intel-iommu' shows up as a device since 2.2.0, but can + * not be used with -device until 2.7.0. Before that it +@@ -4394,6 +4392,12 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps, + virQEMUCapsClear(qemuCaps, QEMU_CAPS_SEV_GUEST); + } + ++ /* The following probes rely on other previously probed capabilities. ++ * No capabilities bits should be set below this point. */ ++ ++ if (virQEMUCapsProbeQMPHostCPU(qemuCaps, mon, false) < 0) ++ goto cleanup; ++ + ret = 0; + cleanup: + return ret; +diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.replies b/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.replies +index 66a5577e5e..ecfe3386c4 100644 +--- a/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.replies ++++ b/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.replies +@@ -19521,6 +19521,21 @@ + "id": "libvirt-50" + } + ++{ ++ "execute": "query-sev-capabilities", ++ "id": "libvirt-51" ++} ++ ++{ ++ "return": { ++ "reduced-phys-bits": 1, ++ "cbitpos": 47, ++ "cert-chain": "AQAAAAAOAAAAQAAAAAOAAAAQAAAAAOAAAAQAAAAAOAAAAQAAAAAOAAA", ++ "pdh": "AQAAAAAOAAAAQAAAAAOAAAAQAAAAAOAAAAQAAAAAOAAAAQAAAAAOAAAAQAAAAAOAAA" ++ }, ++ "id": "libvirt-51" ++} ++ + { + "execute": "query-cpu-model-expansion", + "arguments": { +@@ -19529,7 +19544,7 @@ + "name": "host" + } + }, +- "id": "libvirt-51" ++ "id": "libvirt-52" + } + + { +@@ -19719,7 +19734,7 @@ + } + } + }, +- "id": "libvirt-51" ++ "id": "libvirt-52" + } + + { +@@ -19911,7 +19926,7 @@ + } + } + }, +- "id": "libvirt-52" ++ "id": "libvirt-53" + } + + { +@@ -20166,7 +20181,7 @@ + } + } + }, +- "id": "libvirt-52" ++ "id": "libvirt-53" + } + + { +@@ -20180,7 +20195,7 @@ + } + } + }, +- "id": "libvirt-53" ++ "id": "libvirt-54" + } + + { +@@ -20370,7 +20385,7 @@ + } + } + }, +- "id": "libvirt-53" ++ "id": "libvirt-54" + } + + { +@@ -20562,7 +20577,7 @@ + } + } + }, +- "id": "libvirt-54" ++ "id": "libvirt-55" + } + + { +@@ -20817,21 +20832,6 @@ + } + } + }, +- "id": "libvirt-54" +-} +- +-{ +- "execute": "query-sev-capabilities", +- "id": "libvirt-55" +-} +- +-{ +- "return": { +- "reduced-phys-bits": 1, +- "cbitpos": 47, +- "cert-chain": "AQAAAAAOAAAAQAAAAAOAAAAQAAAAAOAAAAQAAAAAOAAAAQAAAAAOAAA", +- "pdh": "AQAAAAAOAAAAQAAAAAOAAAAQAAAAAOAAAAQAAAAAOAAAAQAAAAAOAAAAQAAAAAOAAA" +- }, + "id": "libvirt-55" + } + +diff --git a/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.replies b/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.replies +index 9f44eb4fae..7fea8587fd 100644 +--- a/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.replies ++++ b/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.replies +@@ -20490,6 +20490,19 @@ + "id": "libvirt-50" + } + ++{ ++ "execute": "query-sev-capabilities", ++ "id": "libvirt-51" ++} ++ ++{ ++ "id": "libvirt-51", ++ "error": { ++ "class": "GenericError", ++ "desc": "SEV feature is not available" ++ } ++} ++ + { + "execute": "query-cpu-model-expansion", + "arguments": { +@@ -20498,7 +20511,7 @@ + "name": "host" + } + }, +- "id": "libvirt-51" ++ "id": "libvirt-52" + } + + { +@@ -20691,7 +20704,7 @@ + } + } + }, +- "id": "libvirt-51" ++ "id": "libvirt-52" + } + + { +@@ -20886,7 +20899,7 @@ + } + } + }, +- "id": "libvirt-52" ++ "id": "libvirt-53" + } + + { +@@ -21148,7 +21161,7 @@ + } + } + }, +- "id": "libvirt-52" ++ "id": "libvirt-53" + } + + { +@@ -21162,7 +21175,7 @@ + } + } + }, +- "id": "libvirt-53" ++ "id": "libvirt-54" + } + + { +@@ -21355,7 +21368,7 @@ + } + } + }, +- "id": "libvirt-53" ++ "id": "libvirt-54" + } + + { +@@ -21550,7 +21563,7 @@ + } + } + }, +- "id": "libvirt-54" ++ "id": "libvirt-55" + } + + { +@@ -21812,22 +21825,9 @@ + } + } + }, +- "id": "libvirt-54" +-} +- +-{ +- "execute": "query-sev-capabilities", + "id": "libvirt-55" + } + +-{ +- "id": "libvirt-55", +- "error": { +- "class": "GenericError", +- "desc": "SEV feature is not available" +- } +-} +- + { + "execute": "qmp_capabilities", + "id": "libvirt-1" +diff --git a/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.replies b/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.replies +index 82b320b1d0..5b4d7a8484 100644 +--- a/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.replies ++++ b/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.replies +@@ -21315,6 +21315,19 @@ + "id": "libvirt-50" + } + ++{ ++ "execute": "query-sev-capabilities", ++ "id": "libvirt-51" ++} ++ ++{ ++ "id": "libvirt-51", ++ "error": { ++ "class": "GenericError", ++ "desc": "SEV feature is not available" ++ } ++} ++ + { + "execute": "query-cpu-model-expansion", + "arguments": { +@@ -21323,7 +21336,7 @@ + "name": "host" + } + }, +- "id": "libvirt-51" ++ "id": "libvirt-52" + } + + { +@@ -21529,7 +21542,7 @@ + } + } + }, +- "id": "libvirt-51" ++ "id": "libvirt-52" + } + + { +@@ -21737,7 +21750,7 @@ + } + } + }, +- "id": "libvirt-52" ++ "id": "libvirt-53" + } + + { +@@ -22018,7 +22031,7 @@ + } + } + }, +- "id": "libvirt-52" ++ "id": "libvirt-53" + } + + { +@@ -22032,7 +22045,7 @@ + } + } + }, +- "id": "libvirt-53" ++ "id": "libvirt-54" + } + + { +@@ -22238,7 +22251,7 @@ + } + } + }, +- "id": "libvirt-53" ++ "id": "libvirt-54" + } + + { +@@ -22446,7 +22459,7 @@ + } + } + }, +- "id": "libvirt-54" ++ "id": "libvirt-55" + } + + { +@@ -22727,22 +22740,9 @@ + } + } + }, +- "id": "libvirt-54" +-} +- +-{ +- "execute": "query-sev-capabilities", + "id": "libvirt-55" + } + +-{ +- "id": "libvirt-55", +- "error": { +- "class": "GenericError", +- "desc": "SEV feature is not available" +- } +-} +- + { + "execute": "qmp_capabilities", + "id": "libvirt-1" +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu-Rework-setting-process-affinity.patch b/SOURCES/libvirt-qemu-Rework-setting-process-affinity.patch new file mode 100644 index 0000000..d86ed56 --- /dev/null +++ b/SOURCES/libvirt-qemu-Rework-setting-process-affinity.patch @@ -0,0 +1,265 @@ +From dc27c829fd5909394e69ed253979f19b47644569 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Michal Privoznik +Date: Wed, 5 Jun 2019 11:33:28 +0200 +Subject: [PATCH] qemu: Rework setting process affinity +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +https://bugzilla.redhat.com/show_bug.cgi?id=1503284 + +The way we currently start qemu from CPU affinity POV is as +follows: + + 1) the child process is set affinity to all online CPUs (unless + some vcpu pinning was given in the domain XML) + + 2) Once qemu is running, cpuset cgroup is configured taking + memory pinning into account + +Problem is that we let qemu allocate its memory just anywhere in +1) and then rely in 2) to be able to move the memory to +configured NUMA nodes. This might not be always possible (e.g. +qemu might lock some parts of its memory) and is very suboptimal +(copying large memory between NUMA nodes takes significant amount +of time). + +The solution is to set affinity to one of (in priority order): + - The CPUs associated with NUMA memory affinity mask + - The CPUs associated with emulator pinning + - All online host CPUs + +Later (once QEMU has allocated its memory) we then change this +again to (again in priority order): + - The CPUs associated with emulator pinning + - The CPUs returned by numad + - The CPUs associated with vCPU pinning + - All online host CPUs + +Signed-off-by: Michal Privoznik +Reviewed-by: Daniel P. Berrangé +(cherry picked from commit f136b83139c63f20de0df3285d9e82df2fb97bfc) + +RHEL-8.1.0: https://bugzilla.redhat.com/show_bug.cgi?id=1716943 + +Signed-off-by: Michal Privoznik +Message-Id: +Reviewed-by: Andrea Bolognani +--- + src/qemu/qemu_process.c | 132 +++++++++++++++++++--------------------- + 1 file changed, 63 insertions(+), 69 deletions(-) + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 2d2954ba18..6071b3ba3d 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -2335,6 +2335,21 @@ qemuProcessDetectIOThreadPIDs(virQEMUDriverPtr driver, + } + + ++static int ++qemuProcessGetAllCpuAffinity(virBitmapPtr *cpumapRet) ++{ ++ *cpumapRet = NULL; ++ ++ if (!virHostCPUHasBitmap()) ++ return 0; ++ ++ if (!(*cpumapRet = virHostCPUGetOnlineBitmap())) ++ return -1; ++ ++ return 0; ++} ++ ++ + /* + * To be run between fork/exec of QEMU only + */ +@@ -2342,9 +2357,9 @@ static int + qemuProcessInitCpuAffinity(virDomainObjPtr vm) + { + int ret = -1; +- virBitmapPtr cpumap = NULL; + virBitmapPtr cpumapToSet = NULL; +- virBitmapPtr hostcpumap = NULL; ++ VIR_AUTOPTR(virBitmap) hostcpumap = NULL; ++ virDomainNumatuneMemMode mem_mode; + qemuDomainObjPrivatePtr priv = vm->privateData; + + if (!vm->pid) { +@@ -2353,59 +2368,39 @@ qemuProcessInitCpuAffinity(virDomainObjPtr vm) + return -1; + } + +- if (vm->def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) { +- VIR_DEBUG("Set CPU affinity with advisory nodeset from numad"); +- cpumapToSet = priv->autoCpuset; ++ /* Here is the deal, we can't set cpuset.mems before qemu is ++ * started as it clashes with KVM allocation. Therefore, we ++ * used to let qemu allocate its memory anywhere as we would ++ * then move the memory to desired NUMA node via CGroups. ++ * However, that might not be always possible because qemu ++ * might lock some parts of its memory (e.g. due to VFIO). ++ * Even if it possible, memory has to be copied between NUMA ++ * nodes which is suboptimal. ++ * Solution is to set affinity that matches the best what we ++ * would have set in CGroups and then fix it later, once qemu ++ * is already running. */ ++ if (virDomainNumaGetNodeCount(vm->def->numa) <= 1 && ++ virDomainNumatuneGetMode(vm->def->numa, -1, &mem_mode) == 0 && ++ mem_mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT) { ++ if (virDomainNumatuneMaybeGetNodeset(vm->def->numa, ++ priv->autoNodeset, ++ &cpumapToSet, ++ -1) < 0) ++ goto cleanup; ++ } else if (vm->def->cputune.emulatorpin) { ++ cpumapToSet = vm->def->cputune.emulatorpin; + } else { +- VIR_DEBUG("Set CPU affinity with specified cpuset"); +- if (vm->def->cpumask) { +- cpumapToSet = vm->def->cpumask; +- } else { +- /* You may think this is redundant, but we can't assume libvirtd +- * itself is running on all pCPUs, so we need to explicitly set +- * the spawned QEMU instance to all pCPUs if no map is given in +- * its config file */ +- int hostcpus; +- +- if (virHostCPUHasBitmap()) { +- hostcpumap = virHostCPUGetOnlineBitmap(); +- cpumap = virProcessGetAffinity(vm->pid); +- } +- +- if (hostcpumap && cpumap && virBitmapEqual(hostcpumap, cpumap)) { +- /* we're using all available CPUs, no reason to set +- * mask. If libvirtd is running without explicit +- * affinity, we can use hotplugged CPUs for this VM */ +- ret = 0; +- goto cleanup; +- } else { +- /* setaffinity fails if you set bits for CPUs which +- * aren't present, so we have to limit ourselves */ +- if ((hostcpus = virHostCPUGetCount()) < 0) +- goto cleanup; +- +- if (hostcpus > QEMUD_CPUMASK_LEN) +- hostcpus = QEMUD_CPUMASK_LEN; +- +- virBitmapFree(cpumap); +- if (!(cpumap = virBitmapNew(hostcpus))) +- goto cleanup; +- +- virBitmapSetAll(cpumap); +- +- cpumapToSet = cpumap; +- } +- } ++ if (qemuProcessGetAllCpuAffinity(&hostcpumap) < 0) ++ goto cleanup; ++ cpumapToSet = hostcpumap; + } + +- if (virProcessSetAffinity(vm->pid, cpumapToSet) < 0) ++ if (cpumapToSet && ++ virProcessSetAffinity(vm->pid, cpumapToSet) < 0) + goto cleanup; + + ret = 0; +- + cleanup: +- virBitmapFree(cpumap); +- virBitmapFree(hostcpumap); + return ret; + } + +@@ -2478,7 +2473,8 @@ qemuProcessSetupPid(virDomainObjPtr vm, + qemuDomainObjPrivatePtr priv = vm->privateData; + virDomainNumatuneMemMode mem_mode; + virCgroupPtr cgroup = NULL; +- virBitmapPtr use_cpumask; ++ virBitmapPtr use_cpumask = NULL; ++ VIR_AUTOPTR(virBitmap) hostcpumap = NULL; + char *mem_mask = NULL; + int ret = -1; + +@@ -2490,12 +2486,21 @@ qemuProcessSetupPid(virDomainObjPtr vm, + } + + /* Infer which cpumask shall be used. */ +- if (cpumask) ++ if (cpumask) { + use_cpumask = cpumask; +- else if (vm->def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) ++ } else if (vm->def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) { + use_cpumask = priv->autoCpuset; +- else ++ } else if (vm->def->cpumask) { + use_cpumask = vm->def->cpumask; ++ } else { ++ /* You may think this is redundant, but we can't assume libvirtd ++ * itself is running on all pCPUs, so we need to explicitly set ++ * the spawned QEMU instance to all pCPUs if no map is given in ++ * its config file */ ++ if (qemuProcessGetAllCpuAffinity(&hostcpumap) < 0) ++ goto cleanup; ++ use_cpumask = hostcpumap; ++ } + + /* + * If CPU cgroup controller is not initialized here, then we need +@@ -2520,13 +2525,7 @@ qemuProcessSetupPid(virDomainObjPtr vm, + qemuSetupCgroupCpusetCpus(cgroup, use_cpumask) < 0) + goto cleanup; + +- /* +- * Don't setup cpuset.mems for the emulator, they need to +- * be set up after initialization in order for kvm +- * allocations to succeed. +- */ +- if (nameval != VIR_CGROUP_THREAD_EMULATOR && +- mem_mask && virCgroupSetCpusetMems(cgroup, mem_mask) < 0) ++ if (mem_mask && virCgroupSetCpusetMems(cgroup, mem_mask) < 0) + goto cleanup; + + } +@@ -6440,12 +6439,7 @@ qemuProcessLaunch(virConnectPtr conn, + + /* This must be done after cgroup placement to avoid resetting CPU + * affinity */ +- if (!vm->def->cputune.emulatorpin && +- qemuProcessInitCpuAffinity(vm) < 0) +- goto cleanup; +- +- VIR_DEBUG("Setting emulator tuning/settings"); +- if (qemuProcessSetupEmulator(vm) < 0) ++ if (qemuProcessInitCpuAffinity(vm) < 0) + goto cleanup; + + VIR_DEBUG("Setting cgroup for external devices (if required)"); +@@ -6514,10 +6508,6 @@ qemuProcessLaunch(virConnectPtr conn, + if (qemuProcessUpdateAndVerifyCPU(driver, vm, asyncJob) < 0) + goto cleanup; + +- VIR_DEBUG("Setting up post-init cgroup restrictions"); +- if (qemuSetupCpusetMems(vm) < 0) +- goto cleanup; +- + VIR_DEBUG("setting up hotpluggable cpus"); + if (qemuDomainHasHotpluggableStartupVcpus(vm->def)) { + if (qemuDomainRefreshVcpuInfo(driver, vm, asyncJob, false) < 0) +@@ -6543,6 +6533,10 @@ qemuProcessLaunch(virConnectPtr conn, + if (qemuProcessDetectIOThreadPIDs(driver, vm, asyncJob) < 0) + goto cleanup; + ++ VIR_DEBUG("Setting emulator tuning/settings"); ++ if (qemuProcessSetupEmulator(vm) < 0) ++ goto cleanup; ++ + VIR_DEBUG("Setting global CPU cgroup (if required)"); + if (qemuSetupGlobalCpuCgroup(vm) < 0) + goto cleanup; +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu-Set-up-EMULATOR-thread-and-cpuset.mems-before-exec-ing-qemu.patch b/SOURCES/libvirt-qemu-Set-up-EMULATOR-thread-and-cpuset.mems-before-exec-ing-qemu.patch new file mode 100644 index 0000000..3605c9b --- /dev/null +++ b/SOURCES/libvirt-qemu-Set-up-EMULATOR-thread-and-cpuset.mems-before-exec-ing-qemu.patch @@ -0,0 +1,70 @@ +From ac89574e251dfecf34606083e402194ded63dba2 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Michal Privoznik +Date: Wed, 5 Jun 2019 11:33:29 +0200 +Subject: [PATCH] qemu: Set up EMULATOR thread and cpuset.mems before + exec()-ing qemu + +It's funny how this went unnoticed for such a long time. Long +story short, if a domain is configured with +VIR_DOMAIN_NUMATUNE_MEM_STRICT libvirt doesn't really honour +that. This is because of 7e72ac787848 after which libvirt allowed +qemu to allocate memory just anywhere and only after that it used +some magic involving cpuset.memory_migrate and cpuset.mems to +move the memory to desired NUMA nodes. This was done in order to +work around some KVM bug where KVM would fail if there wasn't a +DMA zone available on the NUMA node. Well, while the work around +might stopped libvirt tickling the KVM bug it also caused a bug +on libvirt side: if there is not enough memory on configured NUMA +node(s) then any attempt to start a domain must fail. Because of +the way we play with guest memory domains can start just happily. + +The solution is to move the child we've just forked into emulator +cgroup, set up cpuset.mems and exec() qemu only after that. + +This basically reverts 7e72ac787848b7434c9 which was a workaround +for kernel bug. This bug was apparently fixed because I've tested +this successfully with recent kernel. + +Signed-off-by: Michal Privoznik +Reviewed-by: Martin Kletzander +(cherry picked from commit 0eaa4716e1b8f6eb59d77049aed3735c3b5fbdd6) + +https://bugzilla.redhat.com/show_bug.cgi?id=1716943 + +Signed-off-by: Michal Privoznik +Message-Id: +Reviewed-by: Andrea Bolognani +--- + src/qemu/qemu_process.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 6071b3ba3d..8b05cef80c 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -6442,6 +6442,10 @@ qemuProcessLaunch(virConnectPtr conn, + if (qemuProcessInitCpuAffinity(vm) < 0) + goto cleanup; + ++ VIR_DEBUG("Setting emulator tuning/settings"); ++ if (qemuProcessSetupEmulator(vm) < 0) ++ goto cleanup; ++ + VIR_DEBUG("Setting cgroup for external devices (if required)"); + if (qemuSetupCgroupForExtDevices(vm, driver) < 0) + goto cleanup; +@@ -6533,10 +6537,6 @@ qemuProcessLaunch(virConnectPtr conn, + if (qemuProcessDetectIOThreadPIDs(driver, vm, asyncJob) < 0) + goto cleanup; + +- VIR_DEBUG("Setting emulator tuning/settings"); +- if (qemuProcessSetupEmulator(vm) < 0) +- goto cleanup; +- + VIR_DEBUG("Setting global CPU cgroup (if required)"); + if (qemuSetupGlobalCpuCgroup(vm) < 0) + goto cleanup; +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu-Translate-feature-names-from-query-cpu-model-expansion.patch b/SOURCES/libvirt-qemu-Translate-feature-names-from-query-cpu-model-expansion.patch new file mode 100644 index 0000000..757e07d --- /dev/null +++ b/SOURCES/libvirt-qemu-Translate-feature-names-from-query-cpu-model-expansion.patch @@ -0,0 +1,133 @@ +From f047006a60d92f9c5e66ac9c2c532f8ac4c2ba28 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:56 +0200 +Subject: [PATCH] qemu: Translate feature names from query-cpu-model-expansion +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +By default query-cpu-model-expansion only reports canonical names of all +CPU features. We do some magic and call the command twice to get all +possible spellings of the features, but being able to consume canonical +names will allow us to drop this magic. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit ec232c5ddc3cc47651a815dcf4cff7cd31910b3e) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Signed-off-by: Jiri Denemark +Message-Id: <5a50943665bc9df69bb99c25763f0b99a7364d8c.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_capabilities.c | 19 +++++++++++-------- + src/qemu/qemu_capspriv.h | 3 ++- + tests/cputest.c | 2 +- + 3 files changed, 14 insertions(+), 10 deletions(-) + +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index c48d66b39b..88c651ea7b 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -2868,11 +2868,12 @@ virQEMUCapsInitCPUModelS390(virQEMUCapsPtr qemuCaps, + for (i = 0; i < modelInfo->nprops; i++) { + virCPUFeatureDefPtr feature = cpu->features + cpu->nfeatures; + qemuMonitorCPUPropertyPtr prop = modelInfo->props + i; ++ const char *name = virQEMUCapsCPUFeatureFromQEMU(qemuCaps, prop->name); + + if (prop->type != QEMU_MONITOR_CPU_PROPERTY_BOOLEAN) + continue; + +- if (VIR_STRDUP(feature->name, prop->name) < 0) ++ if (VIR_STRDUP(feature->name, name) < 0) + return -1; + + if (!prop->value.boolean || +@@ -2888,7 +2889,8 @@ virQEMUCapsInitCPUModelS390(virQEMUCapsPtr qemuCaps, + + + virCPUDataPtr +-virQEMUCapsGetCPUModelX86Data(qemuMonitorCPUModelInfoPtr model, ++virQEMUCapsGetCPUModelX86Data(virQEMUCapsPtr qemuCaps, ++ qemuMonitorCPUModelInfoPtr model, + bool migratable) + { + unsigned long long sigFamily = 0; +@@ -2903,6 +2905,7 @@ virQEMUCapsGetCPUModelX86Data(qemuMonitorCPUModelInfoPtr model, + + for (i = 0; i < model->nprops; i++) { + qemuMonitorCPUPropertyPtr prop = model->props + i; ++ const char *name = virQEMUCapsCPUFeatureFromQEMU(qemuCaps, prop->name); + + switch (prop->type) { + case QEMU_MONITOR_CPU_PROPERTY_BOOLEAN: +@@ -2910,23 +2913,23 @@ virQEMUCapsGetCPUModelX86Data(qemuMonitorCPUModelInfoPtr model, + (migratable && prop->migratable == VIR_TRISTATE_BOOL_NO)) + continue; + +- if (virCPUx86DataAddFeature(data, prop->name) < 0) ++ if (virCPUx86DataAddFeature(data, name) < 0) + goto cleanup; + + break; + + case QEMU_MONITOR_CPU_PROPERTY_STRING: +- if (STREQ(prop->name, "vendor") && ++ if (STREQ(name, "vendor") && + virCPUx86DataSetVendor(data, prop->value.string) < 0) + goto cleanup; + break; + + case QEMU_MONITOR_CPU_PROPERTY_NUMBER: +- if (STREQ(prop->name, "family")) ++ if (STREQ(name, "family")) + sigFamily = prop->value.number; +- else if (STREQ(prop->name, "model")) ++ else if (STREQ(name, "model")) + sigModel = prop->value.number; +- else if (STREQ(prop->name, "stepping")) ++ else if (STREQ(name, "stepping")) + sigStepping = prop->value.number; + break; + +@@ -2964,7 +2967,7 @@ virQEMUCapsInitCPUModelX86(virQEMUCapsPtr qemuCaps, + if (!model) + return 1; + +- if (!(data = virQEMUCapsGetCPUModelX86Data(model, migratable))) ++ if (!(data = virQEMUCapsGetCPUModelX86Data(qemuCaps, model, migratable))) + goto cleanup; + + if (cpuDecode(cpu, data, virQEMUCapsGetCPUDefinitions(qemuCaps, type)) < 0) +diff --git a/src/qemu/qemu_capspriv.h b/src/qemu/qemu_capspriv.h +index c3b7f934a9..b17deb01d7 100644 +--- a/src/qemu/qemu_capspriv.h ++++ b/src/qemu/qemu_capspriv.h +@@ -85,7 +85,8 @@ virQEMUCapsSetCPUModelInfo(virQEMUCapsPtr qemuCaps, + qemuMonitorCPUModelInfoPtr modelInfo); + + virCPUDataPtr +-virQEMUCapsGetCPUModelX86Data(qemuMonitorCPUModelInfoPtr model, ++virQEMUCapsGetCPUModelX86Data(virQEMUCapsPtr qemuCaps, ++ qemuMonitorCPUModelInfoPtr model, + bool migratable); + + virCPUDefPtr +diff --git a/tests/cputest.c b/tests/cputest.c +index e62cda34b7..1ce50caccd 100644 +--- a/tests/cputest.c ++++ b/tests/cputest.c +@@ -941,7 +941,7 @@ cpuTestJSONSignature(const void *arg) + goto cleanup; + + modelInfo = virQEMUCapsGetCPUModelInfo(qemuCaps, VIR_DOMAIN_VIRT_KVM); +- if (!(hostData = virQEMUCapsGetCPUModelX86Data(modelInfo, false))) ++ if (!(hostData = virQEMUCapsGetCPUModelX86Data(qemuCaps, modelInfo, false))) + goto cleanup; + + ret = cpuTestCompareSignature(data, hostData); +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu-Use-tmpChr-in-qemuDomainDetachChrDevice-to-build-device-string.patch b/SOURCES/libvirt-qemu-Use-tmpChr-in-qemuDomainDetachChrDevice-to-build-device-string.patch new file mode 100644 index 0000000..ca4f86b --- /dev/null +++ b/SOURCES/libvirt-qemu-Use-tmpChr-in-qemuDomainDetachChrDevice-to-build-device-string.patch @@ -0,0 +1,43 @@ +From cdb5af98d3801255903c4237269ca5723abc36c1 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Michal Privoznik +Date: Thu, 27 Jun 2019 14:44:44 +0200 +Subject: [PATCH] qemu: Use @tmpChr in qemuDomainDetachChrDevice to build + device string + +So far we are passing @chr to qemuBuildChrDeviceStr. This is +suboptimal (in fact wrong) because @chr is just parsed XML +definition provided by user which by definition may lack some +information. On the other hand, @tmpChr is the one that was found +using @chr in domain definition so it contains the same amount of +information or more. + +Signed-off-by: Michal Privoznik +Reviewed-by: John Ferlan +(cherry picked from commit f538f5ed3a876c3cb67ae5b7a01f133f192aca13) + +https://bugzilla.redhat.com/show_bug.cgi?id=1624204 + +Signed-off-by: Michal Privoznik +Message-Id: <75600f93c5e22f43762635ac97f5a0acef1cf465.1561639408.git.mprivozn@redhat.com> +Reviewed-by: Jiri Denemark +--- + src/qemu/qemu_hotplug.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c +index 5b9a5683bb..da9d56ffb1 100644 +--- a/src/qemu/qemu_hotplug.c ++++ b/src/qemu/qemu_hotplug.c +@@ -5753,7 +5753,7 @@ int qemuDomainDetachChrDevice(virQEMUDriverPtr driver, + + sa_assert(tmpChr->info.alias); + +- if (qemuBuildChrDeviceStr(&devstr, vmdef, chr, priv->qemuCaps) < 0) ++ if (qemuBuildChrDeviceStr(&devstr, vmdef, tmpChr, priv->qemuCaps) < 0) + goto cleanup; + + if (!async) +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu-domain-Simplify-non-VFIO-memLockLimit-calculation-for-PPC64.patch b/SOURCES/libvirt-qemu-domain-Simplify-non-VFIO-memLockLimit-calculation-for-PPC64.patch new file mode 100644 index 0000000..6931e00 --- /dev/null +++ b/SOURCES/libvirt-qemu-domain-Simplify-non-VFIO-memLockLimit-calculation-for-PPC64.patch @@ -0,0 +1,66 @@ +From 18f38f4aee3a3472f5e50786ee221d8d397bc6a8 Mon Sep 17 00:00:00 2001 +Message-Id: <18f38f4aee3a3472f5e50786ee221d8d397bc6a8@dist-git> +From: Daniel Henrique Barboza +Date: Fri, 3 May 2019 13:54:50 +0200 +Subject: [PATCH] qemu: domain: Simplify non-VFIO memLockLimit calculation for + PPC64 + +@passthroughLimit is being calculated even if @usesVFIO is false. After +that, an if-else conditional is used to check if we're going to sum it +up with @baseLimit. + +This patch initializes @passthroughLimit to zero and always returns +@memKB = @baseLimit + @passthroughLimit. The conditional is then used to +calculate @passthroughLimit if @usesVFIO == true. This results in some +cycles being spared for the @usesVFIO == false scenario, but the real +motivation is to make the code simpler to add an alternative formula to +calculate @passthroughLimit for NVLink2. + +Signed-off-by: Daniel Henrique Barboza +Reviewed-by: Erik Skultety +(cherry picked from commit cf7c5212876b2403de5b0fafedec33af4439526e) + +https: //bugzilla.redhat.com/show_bug.cgi?id=1505998 +Signed-off-by: Erik Skultety +Message-Id: +Reviewed-by: Andrea Bolognani +--- + src/qemu/qemu_domain.c | 13 +++++-------- + 1 file changed, 5 insertions(+), 8 deletions(-) + +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index cc2a896a07..d936090d87 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -9840,7 +9840,7 @@ qemuDomainGetMemLockLimitBytes(virDomainDefPtr def) + unsigned long long maxMemory; + unsigned long long memory; + unsigned long long baseLimit; +- unsigned long long passthroughLimit; ++ unsigned long long passthroughLimit = 0; + size_t nPCIHostBridges = 0; + bool usesVFIO = false; + +@@ -9906,15 +9906,12 @@ qemuDomainGetMemLockLimitBytes(virDomainDefPtr def) + * kiB pages, less still if the guest is mapped with hugepages (unlike + * the default 32-bit DMA window, DDW windows can use large IOMMU + * pages). 8 MiB is for second and further level overheads, like (b) */ +- passthroughLimit = MAX(2 * 1024 * 1024 * nPCIHostBridges, +- memory + +- memory / 512 * nPCIHostBridges + 8192); +- + if (usesVFIO) +- memKB = baseLimit + passthroughLimit; +- else +- memKB = baseLimit; ++ passthroughLimit = MAX(2 * 1024 * 1024 * nPCIHostBridges, ++ memory + ++ memory / 512 * nPCIHostBridges + 8192); + ++ memKB = baseLimit + passthroughLimit; + goto done; + } + +-- +2.21.0 + diff --git a/SOURCES/libvirt-qemu-process-SEV-Assume-libDir-to-be-the-directory-to-create-files-in.patch b/SOURCES/libvirt-qemu-process-SEV-Assume-libDir-to-be-the-directory-to-create-files-in.patch new file mode 100644 index 0000000..2020e7f --- /dev/null +++ b/SOURCES/libvirt-qemu-process-SEV-Assume-libDir-to-be-the-directory-to-create-files-in.patch @@ -0,0 +1,66 @@ +From 0e97054a08adcd9648d006a8b03effa7f7cf2e94 Mon Sep 17 00:00:00 2001 +Message-Id: <0e97054a08adcd9648d006a8b03effa7f7cf2e94@dist-git> +From: Erik Skultety +Date: Thu, 3 Jan 2019 10:03:45 +0100 +Subject: [PATCH] qemu: process: SEV: Assume libDir to be the directory to + create files in + +Since SEV operates on a per domain basis, it's very likely that all +SEV launch-related data will be created under +/var/lib/libvirt/qemu/. Therefore, when calling into +qemuProcessSEVCreateFile we can assume @libDir as the directory prefix +rather than passing it explicitly. + +Signed-off-by: Erik Skultety +Acked-by: Michal Privoznik +(cherry picked from commit 2c4c7de1595330a828015dd750b5ef3874f289d1) + +https://bugzilla.redhat.com/show_bug.cgi?id=1658112 + +Signed-off-by: Erik Skultety +Message-Id: <0f59cc4873d5faab4339e79714377da9f889703c.1546506016.git.eskultet@redhat.com> +Reviewed-by: Jiri Denemark +--- + src/qemu/qemu_process.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index c0f95dd5f1..757e2d33a4 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -5985,14 +5985,15 @@ qemuProcessPrepareDomain(virQEMUDriverPtr driver, + + + static int +-qemuProcessSEVCreateFile(const char *configDir, ++qemuProcessSEVCreateFile(virDomainObjPtr vm, + const char *name, + const char *data) + { ++ qemuDomainObjPrivatePtr priv = vm->privateData; + char *configFile; + int ret = -1; + +- if (!(configFile = virFileBuildPath(configDir, name, ".base64"))) ++ if (!(configFile = virFileBuildPath(priv->libDir, name, ".base64"))) + return -1; + + if (virFileRewriteStr(configFile, S_IRUSR | S_IWUSR, data) < 0) { +@@ -6029,12 +6030,12 @@ qemuProcessPrepareSEVGuestInput(virDomainObjPtr vm) + } + + if (sev->dh_cert) { +- if (qemuProcessSEVCreateFile(priv->libDir, "dh_cert", sev->dh_cert) < 0) ++ if (qemuProcessSEVCreateFile(vm, "dh_cert", sev->dh_cert) < 0) + return -1; + } + + if (sev->session) { +- if (qemuProcessSEVCreateFile(priv->libDir, "session", sev->session) < 0) ++ if (qemuProcessSEVCreateFile(vm, "session", sev->session) < 0) + return -1; + } + +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu-process-SEV-Relabel-guest-owner-s-SEV-files-created-before-start.patch b/SOURCES/libvirt-qemu-process-SEV-Relabel-guest-owner-s-SEV-files-created-before-start.patch new file mode 100644 index 0000000..c1e0647 --- /dev/null +++ b/SOURCES/libvirt-qemu-process-SEV-Relabel-guest-owner-s-SEV-files-created-before-start.patch @@ -0,0 +1,51 @@ +From dc905fbc1f420a8d7856d9ff7f27b3faae352098 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Erik Skultety +Date: Thu, 3 Jan 2019 10:03:46 +0100 +Subject: [PATCH] qemu: process: SEV: Relabel guest owner's SEV files created + before start + +Before launching a SEV guest we take the base64-encoded guest owner's +data specified in launchSecurity and create files with the same content +under /var/lib/libvirt/qemu/. The reason for this is that we +need to pass these files on to QEMU which then uses them to communicate +with the SEV firmware, except when it doesn't have permissions to open +those files since we don't relabel them. + +https://bugzilla.redhat.com/show_bug.cgi?id=1658112 + +Signed-off-by: Erik Skultety +Acked-by: Michal Privoznik +(cherry picked from commit 7dc31fe503e540d5b4ee4f94d61842aa6e302e94) +Signed-off-by: Erik Skultety +Message-Id: <6bde21a3bda257a042d6f6c1d78ab1bf12c196d3.1546506016.git.eskultet@redhat.com> +Reviewed-by: Jiri Denemark +--- + src/qemu/qemu_process.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 757e2d33a4..bc573f96a4 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -5990,6 +5990,7 @@ qemuProcessSEVCreateFile(virDomainObjPtr vm, + const char *data) + { + qemuDomainObjPrivatePtr priv = vm->privateData; ++ virQEMUDriverPtr driver = priv->driver; + char *configFile; + int ret = -1; + +@@ -6002,6 +6003,9 @@ qemuProcessSEVCreateFile(virDomainObjPtr vm, + goto cleanup; + } + ++ if (qemuSecurityDomainSetPathLabel(driver, vm, configFile, true) < 0) ++ goto cleanup; ++ + ret = 0; + cleanup: + VIR_FREE(configFile); +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemuBuildMemoryBackendProps-Pass-priv-instead-of-its-individual-members.patch b/SOURCES/libvirt-qemuBuildMemoryBackendProps-Pass-priv-instead-of-its-individual-members.patch new file mode 100644 index 0000000..778d3b0 --- /dev/null +++ b/SOURCES/libvirt-qemuBuildMemoryBackendProps-Pass-priv-instead-of-its-individual-members.patch @@ -0,0 +1,172 @@ +From c59ebd3e7bd1307ef6907a830dc9617eb6fe39b2 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Michal Privoznik +Date: Tue, 18 Dec 2018 11:47:35 +0100 +Subject: [PATCH] qemuBuildMemoryBackendProps: Pass @priv instead of its + individual members +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +https://bugzilla.redhat.com/show_bug.cgi?id=1624223 + +So far we have two arguments that we are passing to +qemuBuildMemoryBackendProps() and that are taken from domain +private data: @qemuCaps and @autoNodeset. In the next commit I +will use one more item from there. Therefore, instead of having +it as yet another argument to the function, pass pointer to the +private data object. + +There is one change in qemuDomainAttachMemory() where previously +@autoNodeset was NULL but now is priv->autoNodeset (which may be +set). This is safe to do as @autoNodeset is advisory only. + +Signed-off-by: Michal Privoznik +Reviewed-by: John Ferlan +(cherry picked from commit 9923584c628e160705124ad81d782a7214aac8d3) +Signed-off-by: Michal Privoznik + +Conflicts: +src/qemu/qemu_command.c: Context mostly, as memfd backend is not + backported (24b74d187ca). + +Signed-off-by: Michal Privoznik +Message-Id: <71d56cdc7e5cdd0c9b664ded2a4cf93e3e9d38b0.1545129996.git.mprivozn@redhat.com> +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_command.c | 28 +++++++++++++--------------- + src/qemu/qemu_command.h | 3 +-- + src/qemu/qemu_hotplug.c | 2 +- + 3 files changed, 15 insertions(+), 18 deletions(-) + +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index c06f396b44..fa2b904239 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -3041,22 +3041,21 @@ qemuBuildControllerDevCommandLine(virCommandPtr cmd, + * @backendProps: [out] constructed object + * @alias: alias of the device + * @cfg: qemu driver config object +- * @qemuCaps: qemu capabilities object ++ * @priv: pointer to domain private object + * @def: domain definition object + * @mem: memory definition object +- * @autoNodeset: fallback nodeset in case of automatic NUMA placement + * @force: forcibly use one of the backends + * + * Creates a configuration object that represents memory backend of given guest +- * NUMA node (domain @def and @mem). Use @autoNodeset to fine tune the ++ * NUMA node (domain @def and @mem). Use @priv->autoNodeset to fine tune the + * placement of the memory on the host NUMA nodes. + * + * By default, if no memory-backend-* object is necessary to fulfil the guest + * configuration value of 1 is returned. This behaviour can be suppressed by + * setting @force to true in which case 0 would be returned. + * +- * Then, if one of the two memory-backend-* should be used, the @qemuCaps is +- * consulted to check if qemu does support it. ++ * Then, if one of the two memory-backend-* should be used, the @priv->qemuCaps ++ * is consulted to check if qemu does support it. + * + * Returns: 0 on success, + * 1 on success and if there's no need to use memory-backend-* +@@ -3066,10 +3065,9 @@ int + qemuBuildMemoryBackendProps(virJSONValuePtr *backendProps, + const char *alias, + virQEMUDriverConfigPtr cfg, +- virQEMUCapsPtr qemuCaps, ++ qemuDomainObjPrivatePtr priv, + virDomainDefPtr def, + virDomainMemoryDefPtr mem, +- virBitmapPtr autoNodeset, + bool force) + { + const char *backendType = "memory-backend-file"; +@@ -3207,7 +3205,7 @@ qemuBuildMemoryBackendProps(virJSONValuePtr *backendProps, + + if (!mem->nvdimmPath && + discard == VIR_TRISTATE_BOOL_YES) { +- if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE_DISCARD)) { ++ if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE_DISCARD)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("this QEMU doesn't support memory discard")); + goto cleanup; +@@ -3244,7 +3242,7 @@ qemuBuildMemoryBackendProps(virJSONValuePtr *backendProps, + if (mem->sourceNodes) { + nodemask = mem->sourceNodes; + } else { +- if (virDomainNumatuneMaybeGetNodeset(def->numa, autoNodeset, ++ if (virDomainNumatuneMaybeGetNodeset(def->numa, priv->autoNodeset, + &nodemask, mem->targetNode) < 0) + goto cleanup; + } +@@ -3270,13 +3268,13 @@ qemuBuildMemoryBackendProps(virJSONValuePtr *backendProps, + } else { + /* otherwise check the required capability */ + if (STREQ(backendType, "memory-backend-file") && +- !virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE)) { ++ !virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("this qemu doesn't support the " + "memory-backend-file object")); + goto cleanup; + } else if (STREQ(backendType, "memory-backend-ram") && +- !virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_RAM)) { ++ !virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_OBJECT_MEMORY_RAM)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("this qemu doesn't support the " + "memory-backend-ram object")); +@@ -3319,8 +3317,8 @@ qemuBuildMemoryCellBackendStr(virDomainDefPtr def, + mem.targetNode = cell; + mem.info.alias = alias; + +- if ((rc = qemuBuildMemoryBackendProps(&props, alias, cfg, priv->qemuCaps, +- def, &mem, priv->autoNodeset, false)) < 0) ++ if ((rc = qemuBuildMemoryBackendProps(&props, alias, cfg, ++ priv, def, &mem, false)) < 0) + goto cleanup; + + if (virQEMUBuildObjectCommandlineFromJSON(buf, props) < 0) +@@ -3356,8 +3354,8 @@ qemuBuildMemoryDimmBackendStr(virBufferPtr buf, + if (virAsprintf(&alias, "mem%s", mem->info.alias) < 0) + goto cleanup; + +- if (qemuBuildMemoryBackendProps(&props, alias, cfg, priv->qemuCaps, +- def, mem, priv->autoNodeset, true) < 0) ++ if (qemuBuildMemoryBackendProps(&props, alias, cfg, ++ priv, def, mem, true) < 0) + goto cleanup; + + if (virQEMUBuildObjectCommandlineFromJSON(buf, props) < 0) +diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h +index e8cd8ed04e..bf46bde48f 100644 +--- a/src/qemu/qemu_command.h ++++ b/src/qemu/qemu_command.h +@@ -125,10 +125,9 @@ int qemuBuildControllerDevStr(const virDomainDef *domainDef, + int qemuBuildMemoryBackendProps(virJSONValuePtr *backendProps, + const char *alias, + virQEMUDriverConfigPtr cfg, +- virQEMUCapsPtr qemuCaps, ++ qemuDomainObjPrivatePtr priv, + virDomainDefPtr def, + virDomainMemoryDefPtr mem, +- virBitmapPtr autoNodeset, + bool force); + + char *qemuBuildMemoryDeviceStr(virDomainMemoryDefPtr mem); +diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c +index 410cdca3c5..5b9a5683bb 100644 +--- a/src/qemu/qemu_hotplug.c ++++ b/src/qemu/qemu_hotplug.c +@@ -2121,7 +2121,7 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver, + goto cleanup; + + if (qemuBuildMemoryBackendProps(&props, objalias, cfg, +- priv->qemuCaps, vm->def, mem, NULL, true) < 0) ++ priv, vm->def, mem, true) < 0) + goto cleanup; + + if (qemuProcessBuildDestroyMemoryPaths(driver, vm, mem, true) < 0) +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemuDomainRemoveRNGDevice-Remove-associated-chardev-too.patch b/SOURCES/libvirt-qemuDomainRemoveRNGDevice-Remove-associated-chardev-too.patch new file mode 100644 index 0000000..61af820 --- /dev/null +++ b/SOURCES/libvirt-qemuDomainRemoveRNGDevice-Remove-associated-chardev-too.patch @@ -0,0 +1,76 @@ +From d50cf2d60114e7e33c2bd25fb67566a889057b77 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Michal Privoznik +Date: Mon, 8 Apr 2019 10:57:30 +0200 +Subject: [PATCH] qemuDomainRemoveRNGDevice: Remove associated chardev too +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +https://bugzilla.redhat.com/show_bug.cgi?id=1656014 + +An RNG device can consists of more devices than RND device +itself. For instance, in case of EGD there is a chardev that +connects to EGD daemon and feeds the qemu with random data. When +doing RNG device removal we have to remove the associated chardev +as well. + +Signed-off-by: Michal Privoznik +Reviewed-by: Ján Tomko + +(cherry picked from commit 7730a2ead4279e3a11771e1069096747988410cf) + +https://bugzilla.redhat.com/show_bug.cgi?id=1508149 + +Signed-off-by: Andrea Bolognani +Message-Id: <20190408085732.28684-14-abologna@redhat.com> +Reviewed-by: Laine Stump +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_hotplug.c | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c +index abe2632556..8394efa739 100644 +--- a/src/qemu/qemu_hotplug.c ++++ b/src/qemu/qemu_hotplug.c +@@ -4408,7 +4408,7 @@ qemuDomainRemoveRNGDevice(virQEMUDriverPtr driver, + qemuDomainObjPrivatePtr priv = vm->privateData; + ssize_t idx; + int ret = -1; +- int rc; ++ int rc = 0; + + VIR_DEBUG("Removing RNG device %s from domain %p %s", + rng->info.alias, vm, vm->def->name); +@@ -4422,7 +4422,17 @@ qemuDomainRemoveRNGDevice(virQEMUDriverPtr driver, + + qemuDomainObjEnterMonitor(driver, vm); + +- rc = qemuMonitorDelObject(priv->mon, objAlias); ++ if (qemuDomainDetachExtensionDevice(priv->mon, &rng->info) < 0) ++ rc = -1; ++ ++ if (rc == 0 && ++ qemuMonitorDelObject(priv->mon, objAlias) < 0) ++ rc = -1; ++ ++ if (rng->backend == VIR_DOMAIN_RNG_BACKEND_EGD && ++ rc == 0 && ++ qemuMonitorDetachCharDev(priv->mon, charAlias) < 0) ++ rc = -1; + + if (qemuDomainObjExitMonitor(driver, vm) < 0) + goto cleanup; +@@ -4431,7 +4441,7 @@ qemuDomainRemoveRNGDevice(virQEMUDriverPtr driver, + rc == 0 && + qemuDomainDelChardevTLSObjects(driver, vm, rng->source.chardev, + charAlias) < 0) +- goto cleanup; ++ rc = -1; + + virDomainAuditRNG(vm, rng, NULL, "detach", rc == 0); + +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemuProcessBuildDestroyMemoryPathsImpl-Don-t-overwrite-error.patch b/SOURCES/libvirt-qemuProcessBuildDestroyMemoryPathsImpl-Don-t-overwrite-error.patch new file mode 100644 index 0000000..0329ea3 --- /dev/null +++ b/SOURCES/libvirt-qemuProcessBuildDestroyMemoryPathsImpl-Don-t-overwrite-error.patch @@ -0,0 +1,45 @@ +From ab0cc413165b8a80d68b30b7e69c611f7087a29b Mon Sep 17 00:00:00 2001 +Message-Id: +From: Michal Privoznik +Date: Thu, 3 Jan 2019 10:03:43 +0100 +Subject: [PATCH] qemuProcessBuildDestroyMemoryPathsImpl: Don't overwrite error +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The qemuSecurityDomainSetPathLabel() function reports perfect +error itself. Do not overwrite it to something less meaningful. + +Signed-off-by: Michal Privoznik +Reviewed-by: Ján Tomko +(cherry picked from commit 577e68dff90e617a20165dfede0390faa1e24031) + +https://bugzilla.redhat.com/show_bug.cgi?id=1658112 + +Signed-off-by: Erik Skultety +Message-Id: <7ca28756d9a136d67b01df15efe1271266017164.1546506016.git.eskultet@redhat.com> +Reviewed-by: Jiri Denemark +--- + src/qemu/qemu_process.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index c220accfaf..34aac69afc 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -3672,11 +3672,8 @@ qemuProcessBuildDestroyMemoryPathsImpl(virQEMUDriverPtr driver, + } + + if (qemuSecurityDomainSetPathLabel(driver->securityManager, +- def, path, true) < 0) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Unable to label %s"), path); ++ def, path, true) < 0) + return -1; +- } + } else { + if (virFileDeleteTree(path) < 0) + return -1; +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu_capabilities-Inroduce-virQEMUCapsGetCPUModelX86Data.patch b/SOURCES/libvirt-qemu_capabilities-Inroduce-virQEMUCapsGetCPUModelX86Data.patch new file mode 100644 index 0000000..4ad6900 --- /dev/null +++ b/SOURCES/libvirt-qemu_capabilities-Inroduce-virQEMUCapsGetCPUModelX86Data.patch @@ -0,0 +1,120 @@ +From 2d8d4379690e55d8d9a0b194ddef33d073154c7b Mon Sep 17 00:00:00 2001 +Message-Id: <2d8d4379690e55d8d9a0b194ddef33d073154c7b@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:03 +0200 +Subject: [PATCH] qemu_capabilities: Inroduce virQEMUCapsGetCPUModelX86Data +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The code for transforming qemuMonitorCPUModelInfo data from QEMU into +virCPUDefPtr consumable by virCPU* APIs was hidden inside +virQEMUCapsInitCPUModelX86. This patch moves it into a new function to +make it usable in tests. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 30e4faac2f3e72aec29be9963d7a5394153e812f) + +https://bugzilla.redhat.com/show_bug.cgi?id=1686895 + +Signed-off-by: Jiri Denemark +Message-Id: +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_capabilities.c | 50 ++++++++++++++++++++++++------------ + src/qemu/qemu_capspriv.h | 4 +++ + 2 files changed, 38 insertions(+), 16 deletions(-) + +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index 5539d168cd..5a7160d02e 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -2812,28 +2812,17 @@ virQEMUCapsInitCPUModelS390(virQEMUCapsPtr qemuCaps, + } + + +-/** +- * Returns 0 when host CPU model provided by QEMU was filled in qemuCaps, +- * 1 when the caller should fall back to using virCapsPtr->host.cpu, +- * -1 on error. +- */ +-static int +-virQEMUCapsInitCPUModelX86(virQEMUCapsPtr qemuCaps, +- virDomainVirtType type, +- qemuMonitorCPUModelInfoPtr model, +- virCPUDefPtr cpu, +- bool migratable) ++virCPUDataPtr ++virQEMUCapsGetCPUModelX86Data(qemuMonitorCPUModelInfoPtr model, ++ bool migratable) + { +- virCPUDataPtr data = NULL; + unsigned long long sigFamily = 0; + unsigned long long sigModel = 0; + unsigned long long sigStepping = 0; +- int ret = -1; ++ virCPUDataPtr data = NULL; ++ virCPUDataPtr ret = NULL; + size_t i; + +- if (!model) +- return 1; +- + if (!(data = virCPUDataNew(VIR_ARCH_X86_64))) + goto cleanup; + +@@ -2874,6 +2863,35 @@ virQEMUCapsInitCPUModelX86(virQEMUCapsPtr qemuCaps, + if (virCPUx86DataSetSignature(data, sigFamily, sigModel, sigStepping) < 0) + goto cleanup; + ++ VIR_STEAL_PTR(ret, data); ++ ++ cleanup: ++ virCPUDataFree(data); ++ return ret; ++} ++ ++ ++/** ++ * Returns 0 when host CPU model provided by QEMU was filled in qemuCaps, ++ * 1 when the caller should fall back to using virCapsPtr->host.cpu, ++ * -1 on error. ++ */ ++static int ++virQEMUCapsInitCPUModelX86(virQEMUCapsPtr qemuCaps, ++ virDomainVirtType type, ++ qemuMonitorCPUModelInfoPtr model, ++ virCPUDefPtr cpu, ++ bool migratable) ++{ ++ virCPUDataPtr data = NULL; ++ int ret = -1; ++ ++ if (!model) ++ return 1; ++ ++ if (!(data = virQEMUCapsGetCPUModelX86Data(model, migratable))) ++ goto cleanup; ++ + if (cpuDecode(cpu, data, virQEMUCapsGetCPUDefinitions(qemuCaps, type)) < 0) + goto cleanup; + +diff --git a/src/qemu/qemu_capspriv.h b/src/qemu/qemu_capspriv.h +index cb5e0dd9a9..70cdbbc504 100644 +--- a/src/qemu/qemu_capspriv.h ++++ b/src/qemu/qemu_capspriv.h +@@ -80,6 +80,10 @@ virQEMUCapsSetCPUModelInfo(virQEMUCapsPtr qemuCaps, + virDomainVirtType type, + qemuMonitorCPUModelInfoPtr modelInfo); + ++virCPUDataPtr ++virQEMUCapsGetCPUModelX86Data(qemuMonitorCPUModelInfoPtr model, ++ bool migratable); ++ + virCPUDefPtr + virQEMUCapsProbeHostCPUForEmulator(virArch hostArch, + virQEMUCapsPtr qemuCaps, +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu_capabilities-Introduce-virQEMUCapsGetCPUModelInfo.patch b/SOURCES/libvirt-qemu_capabilities-Introduce-virQEMUCapsGetCPUModelInfo.patch new file mode 100644 index 0000000..e28993f --- /dev/null +++ b/SOURCES/libvirt-qemu_capabilities-Introduce-virQEMUCapsGetCPUModelInfo.patch @@ -0,0 +1,65 @@ +From 161668ec1a5e6b5cba0136ef50926b5c53802941 Mon Sep 17 00:00:00 2001 +Message-Id: <161668ec1a5e6b5cba0136ef50926b5c53802941@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:04 +0200 +Subject: [PATCH] qemu_capabilities: Introduce virQEMUCapsGetCPUModelInfo +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This is a simple wrapper around virQEMUCapsGetHostCPUData usable in +tests for getting qemuMonitorCPUModelInfoPtr from QEMU caps. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 8aa47cc072fb9a3a8e8b15c6509aae648f5c24e0) + +https://bugzilla.redhat.com/show_bug.cgi?id=1686895 + +Signed-off-by: Jiri Denemark +Message-Id: <4e467c308f24313e69e21c637663f6744482b266.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_capabilities.c | 10 ++++++++++ + src/qemu/qemu_capspriv.h | 4 ++++ + 2 files changed, 14 insertions(+) + +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index 5a7160d02e..942cbf272d 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -3049,6 +3049,16 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps, + } + + ++qemuMonitorCPUModelInfoPtr ++virQEMUCapsGetCPUModelInfo(virQEMUCapsPtr qemuCaps, ++ virDomainVirtType type) ++{ ++ virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type); ++ ++ return cpuData->info; ++} ++ ++ + void + virQEMUCapsSetCPUModelInfo(virQEMUCapsPtr qemuCaps, + virDomainVirtType type, +diff --git a/src/qemu/qemu_capspriv.h b/src/qemu/qemu_capspriv.h +index 70cdbbc504..c3b7f934a9 100644 +--- a/src/qemu/qemu_capspriv.h ++++ b/src/qemu/qemu_capspriv.h +@@ -75,6 +75,10 @@ virQEMUCapsInitCPUModel(virQEMUCapsPtr qemuCaps, + void + virQEMUCapsInitQMPBasicArch(virQEMUCapsPtr qemuCaps); + ++qemuMonitorCPUModelInfoPtr ++virQEMUCapsGetCPUModelInfo(virQEMUCapsPtr qemuCaps, ++ virDomainVirtType type); ++ + void + virQEMUCapsSetCPUModelInfo(virQEMUCapsPtr qemuCaps, + virDomainVirtType type, +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu_capabilities-Use-virQEMUCapsGetCPUModelInfo.patch b/SOURCES/libvirt-qemu_capabilities-Use-virQEMUCapsGetCPUModelInfo.patch new file mode 100644 index 0000000..d3429bd --- /dev/null +++ b/SOURCES/libvirt-qemu_capabilities-Use-virQEMUCapsGetCPUModelInfo.patch @@ -0,0 +1,132 @@ +From deeb15a330b987612c8f50df1de8b2acfc2ed703 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:05 +0200 +Subject: [PATCH] qemu_capabilities: Use virQEMUCapsGetCPUModelInfo +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Most places in qemu_capabilities.c which call virQEMUCapsGetHostCPUData +actually need qemuMonitorCPUModelInfoPtr from QEMU caps. Let's use the +wrapper introduced in the previous commit instead. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 793a9293caabc9876bf7734150ba3acdd85d1649) + +https://bugzilla.redhat.com/show_bug.cgi?id=1686895 + +Signed-off-by: Jiri Denemark +Message-Id: <6d9804c79ffda5aed3e1ac772b7cc003e930490d.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_capabilities.c | 31 ++++++++++++++----------------- + 1 file changed, 14 insertions(+), 17 deletions(-) + +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index 942cbf272d..851cb73cfc 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -2395,7 +2395,6 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps, + const char *model; + qemuMonitorCPUModelExpansionType type; + virDomainVirtType virtType; +- virQEMUCapsHostCPUDataPtr cpuData; + int ret = -1; + + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION)) +@@ -2409,8 +2408,6 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps, + model = "host"; + } + +- cpuData = virQEMUCapsGetHostCPUData(qemuCaps, virtType); +- + /* Some x86_64 features defined in cpu_map.xml use spelling which differ + * from the one preferred by QEMU. Static expansion would give us only the + * preferred spelling, thus we need to do a full expansion on the result of +@@ -2462,7 +2459,8 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps, + modelInfo->migratability = true; + } + +- VIR_STEAL_PTR(cpuData->info, modelInfo); ++ virQEMUCapsSetCPUModelInfo(qemuCaps, virtType, modelInfo); ++ modelInfo = NULL; + ret = 0; + + cleanup: +@@ -2487,24 +2485,24 @@ virQEMUCapsGetCPUFeatures(virQEMUCapsPtr qemuCaps, + bool migratable, + char ***features) + { +- virQEMUCapsHostCPUDataPtr data; ++ qemuMonitorCPUModelInfoPtr modelInfo; + char **list; + size_t i; + size_t n; + int ret = -1; + + *features = NULL; +- data = virQEMUCapsGetHostCPUData(qemuCaps, virtType); ++ modelInfo = virQEMUCapsGetCPUModelInfo(qemuCaps, virtType); + +- if (!data->info) ++ if (!modelInfo) + return 0; + +- if (VIR_ALLOC_N(list, data->info->nprops + 1) < 0) ++ if (VIR_ALLOC_N(list, modelInfo->nprops + 1) < 0) + return -1; + + n = 0; +- for (i = 0; i < data->info->nprops; i++) { +- qemuMonitorCPUPropertyPtr prop = data->info->props + i; ++ for (i = 0; i < modelInfo->nprops; i++) { ++ qemuMonitorCPUPropertyPtr prop = modelInfo->props + i; + + if (migratable && prop->migratable == VIR_TRISTATE_BOOL_NO) + continue; +@@ -2514,7 +2512,7 @@ virQEMUCapsGetCPUFeatures(virQEMUCapsPtr qemuCaps, + } + + VIR_STEAL_PTR(*features, list); +- if (migratable && !data->info->migratability) ++ if (migratable && !modelInfo->migratability) + ret = 1; + else + ret = 0; +@@ -2915,17 +2913,17 @@ virQEMUCapsInitCPUModel(virQEMUCapsPtr qemuCaps, + virCPUDefPtr cpu, + bool migratable) + { +- virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type); ++ qemuMonitorCPUModelInfoPtr modelInfo = virQEMUCapsGetCPUModelInfo(qemuCaps, type); + int ret = 1; + +- if (migratable && cpuData->info && !cpuData->info->migratability) ++ if (migratable && modelInfo && !modelInfo->migratability) + return 1; + + if (ARCH_IS_S390(qemuCaps->arch)) { +- ret = virQEMUCapsInitCPUModelS390(qemuCaps, type, cpuData->info, ++ ret = virQEMUCapsInitCPUModelS390(qemuCaps, type, modelInfo, + cpu, migratable); + } else if (ARCH_IS_X86(qemuCaps->arch)) { +- ret = virQEMUCapsInitCPUModelX86(qemuCaps, type, cpuData->info, ++ ret = virQEMUCapsInitCPUModelX86(qemuCaps, type, modelInfo, + cpu, migratable); + } + +@@ -3655,8 +3653,7 @@ virQEMUCapsFormatHostCPUModelInfo(virQEMUCapsPtr qemuCaps, + virBufferPtr buf, + virDomainVirtType type) + { +- virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type); +- qemuMonitorCPUModelInfoPtr model = cpuData->info; ++ qemuMonitorCPUModelInfoPtr model = virQEMUCapsGetCPUModelInfo(qemuCaps, type); + const char *typeStr = type == VIR_DOMAIN_VIRT_KVM ? "kvm" : "tcg"; + size_t i; + +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu_command-Use-canonical-names-of-CPU-features.patch b/SOURCES/libvirt-qemu_command-Use-canonical-names-of-CPU-features.patch new file mode 100644 index 0000000..64028b2 --- /dev/null +++ b/SOURCES/libvirt-qemu_command-Use-canonical-names-of-CPU-features.patch @@ -0,0 +1,137 @@ +From 243a37dbf1a42f75a2529b954dac40bb0dd4059e Mon Sep 17 00:00:00 2001 +Message-Id: <243a37dbf1a42f75a2529b954dac40bb0dd4059e@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:55 +0200 +Subject: [PATCH] qemu_command: Use canonical names of CPU features +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When building QEMU command line, we should use the preferred spelling of +each CPU feature without relying on compatibility aliases (which may be +removed at some point). + +The "unavailable-features" CPU property is used as a witness for the +correct names of the features in our translation table. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 5030a7450b0f0117a7903303572c6bda6c012327) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Conflicts: + src/qemu/qemu_capabilities.c + - several refactors are missing + + tests/qemuxml2argvdata/eoi-disabled.x86_64-latest.args + tests/qemuxml2argvdata/eoi-enabled.x86_64-latest.args + tests/qemuxml2argvdata/kvmclock+eoi-disabled.x86_64-latest.args + tests/qemuxml2argvdata/pv-spinlock-disabled.x86_64-latest.args + tests/qemuxml2argvdata/pv-spinlock-enabled.x86_64-latest.args + - these were not backported + + tests/qemuxml2argvdata/cpu-translation.x86_64-latest.args + - downstream patch to add rtm=on and hle=on for Haswell + +Signed-off-by: Jiri Denemark +Message-Id: <5d34d0b9087230e4dc0f0936b34e73b5f1781832.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_capabilities.c | 8 +++++++- + src/qemu/qemu_capabilities.h | 1 + + src/qemu/qemu_command.c | 2 ++ + tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml | 1 + + tests/qemuxml2argvdata/cpu-translation.x86_64-latest.args | 6 +++--- + 5 files changed, 14 insertions(+), 4 deletions(-) + +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index fb260eae96..c48d66b39b 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -516,6 +516,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST, + "machine.pseries.cap-nested-hv", + "x86-max-cpu", + "cpu-unavailable-features", ++ "canonical-cpu-features", + ); + + +@@ -2799,7 +2800,9 @@ virQEMUCapsCPUFeatureTranslate(virQEMUCapsPtr qemuCaps, + if (ARCH_IS_X86(qemuCaps->arch)) + table = virQEMUCapsCPUFeaturesX86; + +- if (!table || !feature) ++ if (!table || ++ !feature || ++ !virQEMUCapsGet(qemuCaps, QEMU_CAPS_CANONICAL_CPU_FEATURES)) + return feature; + + for (entry = table; entry->libvirt; entry++) { +@@ -4381,6 +4384,9 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps, + virQEMUCapsClear(qemuCaps, QEMU_CAPS_DEVICE_VFIO_CCW); + } + ++ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_UNAVAILABLE_FEATURES)) ++ virQEMUCapsSet(qemuCaps, QEMU_CAPS_CANONICAL_CPU_FEATURES); ++ + /* Probe for SEV capabilities */ + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SEV_GUEST)) { + int rc = virQEMUCapsProbeQMPSEVCapabilities(qemuCaps, mon); +diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h +index 5aa41efdb0..1767b2ab6c 100644 +--- a/src/qemu/qemu_capabilities.h ++++ b/src/qemu/qemu_capabilities.h +@@ -496,6 +496,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ + QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV, /* -machine pseries.cap-nested-hv */ + QEMU_CAPS_X86_MAX_CPU, /* max-x86_64-cpu type exists */ + QEMU_CAPS_CPU_UNAVAILABLE_FEATURES, /* "unavailable-features" CPU property */ ++ QEMU_CAPS_CANONICAL_CPU_FEATURES, /* avoid CPU feature aliases */ + + QEMU_CAPS_LAST /* this must always be the last item */ + } virQEMUCapsFlags; +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index bea9a208e5..b5c0588e3c 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -6819,6 +6819,8 @@ qemuBuildCpuFeature(virQEMUCapsPtr qemuCaps, + const char *name, + bool state) + { ++ name = virQEMUCapsCPUFeatureToQEMU(qemuCaps, name); ++ + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION)) + virBufferAsprintf(buf, ",%s=%s", name, state ? "on" : "off"); + else +diff --git a/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml +index 95d26dfce8..9245641df8 100644 +--- a/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml +@@ -216,6 +216,7 @@ + + + ++ + 4000050 + 0 + 473743 +diff --git a/tests/qemuxml2argvdata/cpu-translation.x86_64-latest.args b/tests/qemuxml2argvdata/cpu-translation.x86_64-latest.args +index 898b987086..6bc88bbe86 100644 +--- a/tests/qemuxml2argvdata/cpu-translation.x86_64-latest.args ++++ b/tests/qemuxml2argvdata/cpu-translation.x86_64-latest.args +@@ -10,9 +10,9 @@ QEMU_AUDIO_DRV=none \ + -object secret,id=masterKey0,format=raw,\ + file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \ + -machine pc,accel=tcg,usb=off,dump-guest-core=off \ +--cpu Haswell,pclmuldq=on,ds_cpl=on,tsc_adjust=on,fxsr_opt=on,lahf_lm=on,\ +-cmp_legacy=on,nodeid_msr=on,perfctr_core=on,perfctr_nb=on,rtm=on,hle=on,\ +-kvm_pv_eoi=on,kvm_pv_unhalt=on \ ++-cpu Haswell,pclmulqdq=on,ds-cpl=on,tsc-adjust=on,fxsr-opt=on,lahf-lm=on,\ ++cmp-legacy=on,nodeid-msr=on,perfctr-core=on,perfctr-nb=on,rtm=on,hle=on,\ ++kvm-pv-eoi=on,kvm-pv-unhalt=on \ + -m 214 \ + -realtime mlock=off \ + -smp 1,sockets=1,cores=1,threads=1 \ +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu_command-Use-consistent-syntax-for-CPU-features.patch b/SOURCES/libvirt-qemu_command-Use-consistent-syntax-for-CPU-features.patch new file mode 100644 index 0000000..4c375b5 --- /dev/null +++ b/SOURCES/libvirt-qemu_command-Use-consistent-syntax-for-CPU-features.patch @@ -0,0 +1,121 @@ +From b3f714b0907ff1a906d8725efb26733caa913b01 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:47 +0200 +Subject: [PATCH] qemu_command: Use consistent syntax for CPU features +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Normal CPU features use modern -cpu ...,feature=on|off syntax when +available, but kvm features kept using the old +feature or -feature. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit e1ba4073961091522b1560472c5559124bd3c034) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Conflicts: + tests/qemuxml2argvdata/eoi-disabled.x86_64-latest.args + tests/qemuxml2argvdata/eoi-enabled.x86_64-latest.args + tests/qemuxml2argvdata/kvmclock+eoi-disabled.x86_64-latest.args + tests/qemuxml2argvdata/pv-spinlock-disabled.x86_64-latest.args + tests/qemuxml2argvdata/pv-spinlock-enabled.x86_64-latest.args + - not backported + +Signed-off-by: Jiri Denemark +Message-Id: +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_command.c | 46 +++++++++++++++++++---------------------- + 1 file changed, 21 insertions(+), 25 deletions(-) + +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index 7ffc4358e3..bea9a208e5 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -6813,6 +6813,19 @@ qemuBuildGlobalControllerCommandLine(virCommandPtr cmd, + } + + ++static void ++qemuBuildCpuFeature(virQEMUCapsPtr qemuCaps, ++ virBufferPtr buf, ++ const char *name, ++ bool state) ++{ ++ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION)) ++ virBufferAsprintf(buf, ",%s=%s", name, state ? "on" : "off"); ++ else ++ virBufferAsprintf(buf, ",%c%s", state ? '+' : '-', name); ++} ++ ++ + static int + qemuBuildCpuModelArgStr(virQEMUDriverPtr driver, + const virDomainDef *def, +@@ -6890,18 +6903,12 @@ qemuBuildCpuModelArgStr(virQEMUDriverPtr driver, + switch ((virCPUFeaturePolicy) cpu->features[i].policy) { + case VIR_CPU_FEATURE_FORCE: + case VIR_CPU_FEATURE_REQUIRE: +- if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION)) +- virBufferAsprintf(buf, ",%s=on", cpu->features[i].name); +- else +- virBufferAsprintf(buf, ",+%s", cpu->features[i].name); ++ qemuBuildCpuFeature(qemuCaps, buf, cpu->features[i].name, true); + break; + + case VIR_CPU_FEATURE_DISABLE: + case VIR_CPU_FEATURE_FORBID: +- if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION)) +- virBufferAsprintf(buf, ",%s=off", cpu->features[i].name); +- else +- virBufferAsprintf(buf, ",-%s", cpu->features[i].name); ++ qemuBuildCpuFeature(qemuCaps, buf, cpu->features[i].name, false); + break; + + case VIR_CPU_FEATURE_OPTIONAL: +@@ -6982,8 +6989,8 @@ qemuBuildCpuCommandLine(virCommandPtr cmd, + + if (timer->name == VIR_DOMAIN_TIMER_NAME_KVMCLOCK && + timer->present != -1) { +- virBufferAsprintf(&buf, ",%ckvmclock", +- timer->present ? '+' : '-'); ++ qemuBuildCpuFeature(qemuCaps, &buf, "kvmclock", ++ !!timer->present); + } else if (timer->name == VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK && + timer->present == 1) { + virBufferAddLit(&buf, ",hv_time"); +@@ -6994,24 +7001,13 @@ qemuBuildCpuCommandLine(virCommandPtr cmd, + } + + if (def->apic_eoi) { +- char sign; +- if (def->apic_eoi == VIR_TRISTATE_SWITCH_ON) +- sign = '+'; +- else +- sign = '-'; +- +- virBufferAsprintf(&buf, ",%ckvm_pv_eoi", sign); ++ qemuBuildCpuFeature(qemuCaps, &buf, "kvm_pv_eoi", ++ def->apic_eoi == VIR_TRISTATE_SWITCH_ON); + } + + if (def->features[VIR_DOMAIN_FEATURE_PVSPINLOCK]) { +- char sign; +- if (def->features[VIR_DOMAIN_FEATURE_PVSPINLOCK] == +- VIR_TRISTATE_SWITCH_ON) +- sign = '+'; +- else +- sign = '-'; +- +- virBufferAsprintf(&buf, ",%ckvm_pv_unhalt", sign); ++ qemuBuildCpuFeature(qemuCaps, &buf, "kvm_pv_unhalt", ++ def->features[VIR_DOMAIN_FEATURE_PVSPINLOCK] == VIR_TRISTATE_SWITCH_ON); + } + + if (def->features[VIR_DOMAIN_FEATURE_HYPERV] == VIR_TRISTATE_SWITCH_ON) { +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu_domain-NVLink2-bridge-detection-function-for-PPC64.patch b/SOURCES/libvirt-qemu_domain-NVLink2-bridge-detection-function-for-PPC64.patch new file mode 100644 index 0000000..6722b86 --- /dev/null +++ b/SOURCES/libvirt-qemu_domain-NVLink2-bridge-detection-function-for-PPC64.patch @@ -0,0 +1,85 @@ +From 8996236421b4adf090ac721e8d525953deb9687a Mon Sep 17 00:00:00 2001 +Message-Id: <8996236421b4adf090ac721e8d525953deb9687a@dist-git> +From: Daniel Henrique Barboza +Date: Fri, 3 May 2019 13:54:52 +0200 +Subject: [PATCH] qemu_domain: NVLink2 bridge detection function for PPC64 + +The NVLink2 support in QEMU implements the detection of NVLink2 +capable devices by verifying the attributes of the VFIO mem region +QEMU allocates for the NVIDIA GPUs. To properly allocate an +adequate amount of memLock, Libvirt needs this information before +a QEMU instance is even created, thus querying QEMU is not +possible and opening a VFIO window is too much. + +An alternative is presented in this patch. Making the following +assumptions: + +- if we want GPU RAM to be available in the guest, an NVLink2 bridge +must be passed through; + +- an unknown PCI device can be classified as a NVLink2 bridge +if its device tree node has 'ibm,gpu', 'ibm,nvlink', +'ibm,nvlink-speed' and 'memory-region'. + +This patch introduces a helper called @ppc64VFIODeviceIsNV2Bridge +that checks the device tree node of a given PCI device and +check if it meets the criteria to be a NVLink2 bridge. This +new function will be used in a follow-up patch that, using the +first assumption, will set up the rlimits of the guest +accordingly. + +Signed-off-by: Daniel Henrique Barboza +(cherry picked from commit cc9f03801c2618102027ddc4a988193ae290b651) + +https: //bugzilla.redhat.com/show_bug.cgi?id=1505998 +Signed-off-by: Erik Skultety +Message-Id: <99efa386adcf68789b7c8cffda2ef24f5f47f0c4.1556884443.git.eskultet@redhat.com> +Reviewed-by: Andrea Bolognani +--- + src/qemu/qemu_domain.c | 30 ++++++++++++++++++++++++++++++ + 1 file changed, 30 insertions(+) + +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index f91de0b743..a8bc618389 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -9805,6 +9805,36 @@ qemuDomainUpdateCurrentMemorySize(virQEMUDriverPtr driver, + } + + ++/** ++ * ppc64VFIODeviceIsNV2Bridge: ++ * @device: string with the PCI device address ++ * ++ * This function receives a string that represents a PCI device, ++ * such as '0004:04:00.0', and tells if the device is a NVLink2 ++ * bridge. ++ */ ++static ATTRIBUTE_UNUSED bool ++ppc64VFIODeviceIsNV2Bridge(const char *device) ++{ ++ const char *nvlink2Files[] = {"ibm,gpu", "ibm,nvlink", ++ "ibm,nvlink-speed", "memory-region"}; ++ size_t i; ++ ++ for (i = 0; i < ARRAY_CARDINALITY(nvlink2Files); i++) { ++ VIR_AUTOFREE(char *) file = NULL; ++ ++ if ((virAsprintf(&file, "/sys/bus/pci/devices/%s/of_node/%s", ++ device, nvlink2Files[i])) < 0) ++ return false; ++ ++ if (!virFileExists(file)) ++ return false; ++ } ++ ++ return true; ++} ++ ++ + /** + * getPPC64MemLockLimitBytes: + * @def: domain definition +-- +2.21.0 + diff --git a/SOURCES/libvirt-qemu_domain-add-a-PPC64-memLockLimit-helper.patch b/SOURCES/libvirt-qemu_domain-add-a-PPC64-memLockLimit-helper.patch new file mode 100644 index 0000000..82280d5 --- /dev/null +++ b/SOURCES/libvirt-qemu_domain-add-a-PPC64-memLockLimit-helper.patch @@ -0,0 +1,219 @@ +From 051451a1b9cefa42ecfd6d27dcb6a12ef49de072 Mon Sep 17 00:00:00 2001 +Message-Id: <051451a1b9cefa42ecfd6d27dcb6a12ef49de072@dist-git> +From: Daniel Henrique Barboza +Date: Fri, 3 May 2019 13:54:51 +0200 +Subject: [PATCH] qemu_domain: add a PPC64 memLockLimit helper + +There is a lot of documentation in the comments about how PPC64 handles +passthrough VFIO devices to calculate the @memLockLimit. And more will +be added with the PPC64 NVLink2 support code. + +Let's remove the PPC64 code from qemuDomainGetMemLockLimitBytes() +body and put it into a helper function. This will simplify the +flow of qemuDomainGetMemLockLimitBytes() that handles all the other +platforms and improves readability of the PPC64 specifics. + +Signed-off-by: Daniel Henrique Barboza +Reviewed-by: Erik Skultety +(cherry picked from commit 7a686fd2eae8d5674bb1213d8517dc5814fa6bf3) + +https: //bugzilla.redhat.com/show_bug.cgi?id=1505998 +Signed-off-by: Erik Skultety +Message-Id: +Reviewed-by: Andrea Bolognani +--- + src/qemu/qemu_domain.c | 171 ++++++++++++++++++++++------------------- + 1 file changed, 93 insertions(+), 78 deletions(-) + +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index d936090d87..f91de0b743 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -9805,6 +9805,97 @@ qemuDomainUpdateCurrentMemorySize(virQEMUDriverPtr driver, + } + + ++/** ++ * getPPC64MemLockLimitBytes: ++ * @def: domain definition ++ * ++ * A PPC64 helper that calculates the memory locking limit in order for ++ * the guest to operate properly. ++ */ ++static unsigned long long ++getPPC64MemLockLimitBytes(virDomainDefPtr def) ++{ ++ unsigned long long memKB = 0; ++ unsigned long long baseLimit = 0; ++ unsigned long long memory = 0; ++ unsigned long long maxMemory = 0; ++ unsigned long long passthroughLimit = 0; ++ size_t i, nPCIHostBridges = 0; ++ bool usesVFIO = false; ++ ++ for (i = 0; i < def->ncontrollers; i++) { ++ virDomainControllerDefPtr cont = def->controllers[i]; ++ ++ if (!virDomainControllerIsPSeriesPHB(cont)) ++ continue; ++ ++ nPCIHostBridges++; ++ } ++ ++ for (i = 0; i < def->nhostdevs; i++) { ++ virDomainHostdevDefPtr dev = def->hostdevs[i]; ++ ++ if (dev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && ++ dev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI && ++ dev->source.subsys.u.pci.backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) { ++ usesVFIO = true; ++ break; ++ } ++ } ++ ++ memory = virDomainDefGetMemoryTotal(def); ++ ++ if (def->mem.max_memory) ++ maxMemory = def->mem.max_memory; ++ else ++ maxMemory = memory; ++ ++ /* baseLimit := maxMemory / 128 (a) ++ * + 4 MiB * #PHBs + 8 MiB (b) ++ * ++ * (a) is the hash table ++ * ++ * (b) is accounting for the 32-bit DMA window - it could be either the ++ * KVM accelerated TCE tables for emulated devices, or the VFIO ++ * userspace view. The 4 MiB per-PHB (including the default one) covers ++ * a 2GiB DMA window: default is 1GiB, but it's possible it'll be ++ * increased to help performance. The 8 MiB extra should be plenty for ++ * the TCE table index for any reasonable number of PHBs and several ++ * spapr-vlan or spapr-vscsi devices (512kB + a tiny bit each) */ ++ baseLimit = maxMemory / 128 + ++ 4096 * nPCIHostBridges + ++ 8192; ++ ++ /* passthroughLimit := max( 2 GiB * #PHBs, (c) ++ * memory (d) ++ * + memory * 1/512 * #PHBs + 8 MiB ) (e) ++ * ++ * (c) is the pre-DDW VFIO DMA window accounting. We're allowing 2 GiB ++ * rather than 1 GiB ++ * ++ * (d) is the with-DDW (and memory pre-registration and related ++ * features) DMA window accounting - assuming that we only account RAM ++ * once, even if mapped to multiple PHBs ++ * ++ * (e) is the with-DDW userspace view and overhead for the 64-bit DMA ++ * window. This is based a bit on expected guest behaviour, but there ++ * really isn't a way to completely avoid that. We assume the guest ++ * requests a 64-bit DMA window (per PHB) just big enough to map all ++ * its RAM. 4 kiB page size gives the 1/512; it will be less with 64 ++ * kiB pages, less still if the guest is mapped with hugepages (unlike ++ * the default 32-bit DMA window, DDW windows can use large IOMMU ++ * pages). 8 MiB is for second and further level overheads, like (b) */ ++ if (usesVFIO) ++ passthroughLimit = MAX(2 * 1024 * 1024 * nPCIHostBridges, ++ memory + ++ memory / 512 * nPCIHostBridges + 8192); ++ ++ memKB = baseLimit + passthroughLimit; ++ ++ return memKB << 10; ++} ++ ++ + /** + * qemuDomainGetMemLockLimitBytes: + * @def: domain definition +@@ -9836,84 +9927,8 @@ qemuDomainGetMemLockLimitBytes(virDomainDefPtr def) + if (def->mem.locked) + return VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; + +- if (ARCH_IS_PPC64(def->os.arch) && def->virtType == VIR_DOMAIN_VIRT_KVM) { +- unsigned long long maxMemory; +- unsigned long long memory; +- unsigned long long baseLimit; +- unsigned long long passthroughLimit = 0; +- size_t nPCIHostBridges = 0; +- bool usesVFIO = false; +- +- for (i = 0; i < def->ncontrollers; i++) { +- virDomainControllerDefPtr cont = def->controllers[i]; +- +- if (!virDomainControllerIsPSeriesPHB(cont)) +- continue; +- +- nPCIHostBridges++; +- } +- +- for (i = 0; i < def->nhostdevs; i++) { +- virDomainHostdevDefPtr dev = def->hostdevs[i]; +- +- if (dev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && +- dev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI && +- dev->source.subsys.u.pci.backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) { +- usesVFIO = true; +- break; +- } +- } +- +- memory = virDomainDefGetMemoryTotal(def); +- +- if (def->mem.max_memory) +- maxMemory = def->mem.max_memory; +- else +- maxMemory = memory; +- +- /* baseLimit := maxMemory / 128 (a) +- * + 4 MiB * #PHBs + 8 MiB (b) +- * +- * (a) is the hash table +- * +- * (b) is accounting for the 32-bit DMA window - it could be either the +- * KVM accelerated TCE tables for emulated devices, or the VFIO +- * userspace view. The 4 MiB per-PHB (including the default one) covers +- * a 2GiB DMA window: default is 1GiB, but it's possible it'll be +- * increased to help performance. The 8 MiB extra should be plenty for +- * the TCE table index for any reasonable number of PHBs and several +- * spapr-vlan or spapr-vscsi devices (512kB + a tiny bit each) */ +- baseLimit = maxMemory / 128 + +- 4096 * nPCIHostBridges + +- 8192; +- +- /* passthroughLimit := max( 2 GiB * #PHBs, (c) +- * memory (d) +- * + memory * 1/512 * #PHBs + 8 MiB ) (e) +- * +- * (c) is the pre-DDW VFIO DMA window accounting. We're allowing 2 GiB +- * rather than 1 GiB +- * +- * (d) is the with-DDW (and memory pre-registration and related +- * features) DMA window accounting - assuming that we only account RAM +- * once, even if mapped to multiple PHBs +- * +- * (e) is the with-DDW userspace view and overhead for the 64-bit DMA +- * window. This is based a bit on expected guest behaviour, but there +- * really isn't a way to completely avoid that. We assume the guest +- * requests a 64-bit DMA window (per PHB) just big enough to map all +- * its RAM. 4 kiB page size gives the 1/512; it will be less with 64 +- * kiB pages, less still if the guest is mapped with hugepages (unlike +- * the default 32-bit DMA window, DDW windows can use large IOMMU +- * pages). 8 MiB is for second and further level overheads, like (b) */ +- if (usesVFIO) +- passthroughLimit = MAX(2 * 1024 * 1024 * nPCIHostBridges, +- memory + +- memory / 512 * nPCIHostBridges + 8192); +- +- memKB = baseLimit + passthroughLimit; +- goto done; +- } ++ if (ARCH_IS_PPC64(def->os.arch) && def->virtType == VIR_DOMAIN_VIRT_KVM) ++ return getPPC64MemLockLimitBytes(def); + + /* For device passthrough using VFIO the guest memory and MMIO memory + * regions need to be locked persistent in order to allow DMA. +-- +2.21.0 + diff --git a/SOURCES/libvirt-qemu_hotplug-Attach-guestfwd-using-netdev_add.patch b/SOURCES/libvirt-qemu_hotplug-Attach-guestfwd-using-netdev_add.patch new file mode 100644 index 0000000..7d56c49 --- /dev/null +++ b/SOURCES/libvirt-qemu_hotplug-Attach-guestfwd-using-netdev_add.patch @@ -0,0 +1,65 @@ +From c120b5738e38dfa06bcd958d65c18308cab977b2 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Michal Privoznik +Date: Thu, 27 Jun 2019 14:44:46 +0200 +Subject: [PATCH] qemu_hotplug: Attach guestfwd using netdev_add + +https://bugzilla.redhat.com/show_bug.cgi?id=1624204 + +The guestfwd channels are -netdevs really. Hotplug them as such. + +Signed-off-by: Michal Privoznik +Reviewed-by: John Ferlan +(cherry picked from commit 903315dc8ffeb2af651207f090a53526decabc92) + +https://bugzilla.redhat.com/show_bug.cgi?id=1624204 + +Signed-off-by: Michal Privoznik +Message-Id: <16a7ca67708755fe216f78295c56eae44275f5b1.1561639408.git.mprivozn@redhat.com> +Reviewed-by: Jiri Denemark +--- + src/qemu/qemu_hotplug.c | 20 +++++++++++++++----- + 1 file changed, 15 insertions(+), 5 deletions(-) + +diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c +index da9d56ffb1..468389fa7a 100644 +--- a/src/qemu/qemu_hotplug.c ++++ b/src/qemu/qemu_hotplug.c +@@ -1864,10 +1864,14 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver, + char *tlsAlias = NULL; + const char *secAlias = NULL; + bool need_release = false; ++ bool guestfwd = false; + +- if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL && +- qemuDomainPrepareChannel(chr, priv->channelTargetDir) < 0) +- goto cleanup; ++ if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL) { ++ guestfwd = chr->targetType == VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_GUESTFWD; ++ ++ if (qemuDomainPrepareChannel(chr, priv->channelTargetDir) < 0) ++ goto cleanup; ++ } + + if (qemuAssignDeviceChrAlias(vmdef, chr, -1) < 0) + goto cleanup; +@@ -1909,8 +1913,14 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver, + goto exit_monitor; + chardevAttached = true; + +- if (qemuMonitorAddDevice(priv->mon, devstr) < 0) +- goto exit_monitor; ++ if (guestfwd) { ++ if (qemuMonitorAddNetdev(priv->mon, devstr, ++ NULL, NULL, 0, NULL, NULL, 0) < 0) ++ goto exit_monitor; ++ } else { ++ if (qemuMonitorAddDevice(priv->mon, devstr) < 0) ++ goto exit_monitor; ++ } + + if (qemuDomainObjExitMonitor(driver, vm) < 0) + goto audit; +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu_hotplug-Check-for-duplicate-drive-addresses.patch b/SOURCES/libvirt-qemu_hotplug-Check-for-duplicate-drive-addresses.patch new file mode 100644 index 0000000..bc3d90e --- /dev/null +++ b/SOURCES/libvirt-qemu_hotplug-Check-for-duplicate-drive-addresses.patch @@ -0,0 +1,43 @@ +From 6402d8133b33af901247afccdc78b332b453ff11 Mon Sep 17 00:00:00 2001 +Message-Id: <6402d8133b33af901247afccdc78b332b453ff11@dist-git> +From: Michal Privoznik +Date: Thu, 18 Apr 2019 19:36:33 +0200 +Subject: [PATCH] qemu_hotplug: Check for duplicate drive addresses + +RHEL-7.7: https://bugzilla.redhat.com/show_bug.cgi?id=1692296 +RHEL-8.1.0: https://bugzilla.redhat.com/show_bug.cgi?id=1692354 + +This tries to fix the same problem as f1d65853000 but it's doing +so in a less invasive way. + +Signed-off-by: Michal Privoznik +Tested-by: Daniel Henrique Barboza +Reviewed-by: Jim Fehlig +(cherry picked from commit ddc72f99027b063feaf34e5fda89916b6b2c8943) +Signed-off-by: Michal Privoznik +Message-Id: +Reviewed-by: Jiri Denemark +--- + src/qemu/qemu_hotplug.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c +index 397a2bdde2..776cd75474 100644 +--- a/src/qemu/qemu_hotplug.c ++++ b/src/qemu/qemu_hotplug.c +@@ -612,6 +612,12 @@ qemuDomainAttachSCSIDisk(virQEMUDriverPtr driver, + return -1; + } + ++ if (virDomainSCSIDriveAddressIsUsed(vm->def, &disk->info.addr.drive)) { ++ virReportError(VIR_ERR_OPERATION_INVALID, "%s", ++ _("Domain already contains a disk with that address")); ++ return -1; ++ } ++ + /* Let's make sure the disk has a controller defined and loaded before + * trying to add it. The controller used by the disk must exist before a + * qemu command line string is generated. +-- +2.21.0 + diff --git a/SOURCES/libvirt-qemu_hotplug-Detach-guestfwd-using-netdev_del.patch b/SOURCES/libvirt-qemu_hotplug-Detach-guestfwd-using-netdev_del.patch new file mode 100644 index 0000000..8930cf3 --- /dev/null +++ b/SOURCES/libvirt-qemu_hotplug-Detach-guestfwd-using-netdev_del.patch @@ -0,0 +1,137 @@ +From a86cb3601add390b718377be021128fc18e4c9b2 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Michal Privoznik +Date: Thu, 27 Jun 2019 14:44:47 +0200 +Subject: [PATCH] qemu_hotplug: Detach guestfwd using netdev_del + +The guestfwd channels are -netdevs really. Hotunplug them as +such. Also, DEVICE_DELETED event is not triggered (surprisingly, +since we're not issuing device_del rather than netdev_del) and +associated chardev is removed automagically too. This means that +we need to do qemuDomainRemoveChrDevice() minus monitor call to +remove the chardev. + +Signed-off-by: Michal Privoznik +Reviewed-by: John Ferlan +(cherry picked from commit 112f3a8d0f324c0705326957cca4508602b25eba) + +https://bugzilla.redhat.com/show_bug.cgi?id=1624204 + +Signed-off-by: Michal Privoznik +Message-Id: +Reviewed-by: Jiri Denemark +--- + src/qemu/qemu_hotplug.c | 48 ++++++++++++++++++++++++++++------------- + 1 file changed, 33 insertions(+), 15 deletions(-) + +diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c +index 468389fa7a..05489cf116 100644 +--- a/src/qemu/qemu_hotplug.c ++++ b/src/qemu/qemu_hotplug.c +@@ -4355,25 +4355,28 @@ qemuDomainRemoveNetDevice(virQEMUDriverPtr driver, + static int + qemuDomainRemoveChrDevice(virQEMUDriverPtr driver, + virDomainObjPtr vm, +- virDomainChrDefPtr chr) ++ virDomainChrDefPtr chr, ++ bool monitor) + { + virObjectEventPtr event; + char *charAlias = NULL; + qemuDomainObjPrivatePtr priv = vm->privateData; + int ret = -1; +- int rc; ++ int rc = 0; + + VIR_DEBUG("Removing character device %s from domain %p %s", + chr->info.alias, vm, vm->def->name); + +- if (!(charAlias = qemuAliasChardevFromDevAlias(chr->info.alias))) +- goto cleanup; ++ if (monitor) { ++ if (!(charAlias = qemuAliasChardevFromDevAlias(chr->info.alias))) ++ goto cleanup; + +- qemuDomainObjEnterMonitor(driver, vm); +- rc = qemuMonitorDetachCharDev(priv->mon, charAlias); ++ qemuDomainObjEnterMonitor(driver, vm); ++ rc = qemuMonitorDetachCharDev(priv->mon, charAlias); + +- if (qemuDomainObjExitMonitor(driver, vm) < 0) +- goto cleanup; ++ if (qemuDomainObjExitMonitor(driver, vm) < 0) ++ goto cleanup; ++ } + + if (rc == 0 && + qemuDomainDelChardevTLSObjects(driver, vm, chr->source, charAlias) < 0) +@@ -4674,7 +4677,7 @@ qemuDomainRemoveDevice(virQEMUDriverPtr driver, + break; + + case VIR_DOMAIN_DEVICE_CHR: +- ret = qemuDomainRemoveChrDevice(driver, vm, dev->data.chr); ++ ret = qemuDomainRemoveChrDevice(driver, vm, dev->data.chr, true); + break; + case VIR_DOMAIN_DEVICE_RNG: + ret = qemuDomainRemoveRNGDevice(driver, vm, dev->data.rng); +@@ -5749,6 +5752,7 @@ int qemuDomainDetachChrDevice(virQEMUDriverPtr driver, + virDomainDefPtr vmdef = vm->def; + virDomainChrDefPtr tmpChr; + char *devstr = NULL; ++ bool guestfwd = false; + + if (!(tmpChr = virDomainChrFind(vmdef, chr))) { + virReportError(VIR_ERR_DEVICE_MISSING, +@@ -5758,6 +5762,11 @@ int qemuDomainDetachChrDevice(virQEMUDriverPtr driver, + goto cleanup; + } + ++ /* guestfwd channels are not really -device rather than ++ * -netdev. We need to treat them slightly differently. */ ++ guestfwd = tmpChr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL && ++ tmpChr->targetType == VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_GUESTFWD; ++ + if (!tmpChr->info.alias && qemuAssignDeviceChrAlias(vmdef, tmpChr, -1) < 0) + goto cleanup; + +@@ -5766,22 +5775,31 @@ int qemuDomainDetachChrDevice(virQEMUDriverPtr driver, + if (qemuBuildChrDeviceStr(&devstr, vmdef, tmpChr, priv->qemuCaps) < 0) + goto cleanup; + +- if (!async) ++ if (!async && !guestfwd) + qemuDomainMarkDeviceForRemoval(vm, &tmpChr->info); + + qemuDomainObjEnterMonitor(driver, vm); +- if (devstr && qemuMonitorDelDevice(priv->mon, tmpChr->info.alias) < 0) { +- ignore_value(qemuDomainObjExitMonitor(driver, vm)); +- goto cleanup; ++ if (guestfwd) { ++ if (qemuMonitorRemoveNetdev(priv->mon, tmpChr->info.alias) < 0) { ++ ignore_value(qemuDomainObjExitMonitor(driver, vm)); ++ goto cleanup; ++ } ++ } else { ++ if (devstr && qemuMonitorDelDevice(priv->mon, tmpChr->info.alias) < 0) { ++ ignore_value(qemuDomainObjExitMonitor(driver, vm)); ++ goto cleanup; ++ } + } + if (qemuDomainObjExitMonitor(driver, vm) < 0) + goto cleanup; + +- if (async) { ++ if (guestfwd) { ++ ret = qemuDomainRemoveChrDevice(driver, vm, tmpChr, false); ++ } else if (async) { + ret = 0; + } else { + if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) +- ret = qemuDomainRemoveChrDevice(driver, vm, tmpChr); ++ ret = qemuDomainRemoveChrDevice(driver, vm, tmpChr, true); + } + + cleanup: +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu_hotplug-remove-another-erroneous-qemuDomainDetachExtensionDevice-call.patch b/SOURCES/libvirt-qemu_hotplug-remove-another-erroneous-qemuDomainDetachExtensionDevice-call.patch new file mode 100644 index 0000000..9b5bd21 --- /dev/null +++ b/SOURCES/libvirt-qemu_hotplug-remove-another-erroneous-qemuDomainDetachExtensionDevice-call.patch @@ -0,0 +1,52 @@ +From 0ca4828af101259cf2cbe30004c68f2081394f91 Mon Sep 17 00:00:00 2001 +Message-Id: <0ca4828af101259cf2cbe30004c68f2081394f91@dist-git> +From: Laine Stump +Date: Mon, 8 Apr 2019 10:57:32 +0200 +Subject: [PATCH] qemu_hotplug: remove another erroneous + qemuDomainDetachExtensionDevice() call +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +qemuDomainRemoveRNGDevice() calls qemuDomainDetachExtensionDevice(). +According to commit 1d1e264f1 that added this code, it should not be +necessary to explicitly remove the zPCI extension device for a PCI +device during unplug, because "QEMU implements an unplug callback +which will unplug both PCI and zPCI device in a cascaded way". In +fact, no other devices call qemuDomainDetachExtensionDevice() during +their qemuDomainRemove*Device() function, so it should be removed from +qemuDomainRemoveRNGDevice as well. + +Signed-off-by: Laine Stump +Reviewed-by: Ján Tomko +Reviewed-by: Boris Fiuczynski + +(cherry picked from commit e18e9b72a99f93cd4b14f39c60baa7c5ea35e5db) + +https://bugzilla.redhat.com/show_bug.cgi?id=1508149 + +Signed-off-by: Andrea Bolognani +Message-Id: <20190408085732.28684-16-abologna@redhat.com> +Reviewed-by: Laine Stump +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_hotplug.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c +index f16213c6e0..410cdca3c5 100644 +--- a/src/qemu/qemu_hotplug.c ++++ b/src/qemu/qemu_hotplug.c +@@ -4422,9 +4422,6 @@ qemuDomainRemoveRNGDevice(virQEMUDriverPtr driver, + + qemuDomainObjEnterMonitor(driver, vm); + +- if (qemuDomainDetachExtensionDevice(priv->mon, &rng->info) < 0) +- rc = -1; +- + if (rc == 0 && + qemuMonitorDelObject(priv->mon, objAlias) < 0) + rc = -1; +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu_hotplug-remove-erroneous-call-to-qemuDomainDetachExtensionDevice.patch b/SOURCES/libvirt-qemu_hotplug-remove-erroneous-call-to-qemuDomainDetachExtensionDevice.patch new file mode 100644 index 0000000..b026299 --- /dev/null +++ b/SOURCES/libvirt-qemu_hotplug-remove-erroneous-call-to-qemuDomainDetachExtensionDevice.patch @@ -0,0 +1,99 @@ +From 77404a4f0ff85fbc0a2c24afc736ffbd8b82ef4d Mon Sep 17 00:00:00 2001 +Message-Id: <77404a4f0ff85fbc0a2c24afc736ffbd8b82ef4d@dist-git> +From: Laine Stump +Date: Mon, 8 Apr 2019 10:57:31 +0200 +Subject: [PATCH] qemu_hotplug: remove erroneous call to + qemuDomainDetachExtensionDevice() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +qemuDomainDetachControllerDevice() calls +qemuDomainDetachExtensionDevice() when the controller type is +PCI. This is incorrect in multiple ways: + +* Any code that tears down a device should be in the + qemuDomainRemove*Device() function (which is called after libvirt + gets a DEVICE_DELETED event from qemu indicating that the guest is + finished with the device on its end. The qemuDomainDetach*Device() + functions should only contain code that ensures the requested + operation is valid, and sends the command to qemu to initiate the + unplug. + +* qemuDomainDetachExtensionDevice() is a function that applies to + devices that plug into a PCI slot, *not* necessarily PCI controllers + (which is what's being checked in the offending code). The proper + way to check for this would be to see if the DeviceInfo for the + controller device had a PCI address, not to check if the controller + is a PCI controller (the code being removed was doing the latter). + +* According to commit 1d1e264f1 that added this code (and other + support for hotplugging zPCI devices on s390), it's not necessary to + explicitly detach the zPCI device when unplugging a PCI device. To + quote: + + There's no need to implement hot unplug for zPCI as QEMU + implements an unplug callback which will unplug both PCI and + zPCI device in a cascaded way. + + and the evidence bears this out - all the other uses of + qemuDomainDetachExtensionDevice() (except one, which I believe is + also in error, and is being removed in a separate patch) are only to + remove the zPCI extension device in cases where it was successfully + added, but there was some other failure later in the hotplug process + (so there was no regular PCI device to remove and trigger removal of + the zPCI extension device). + +* PCI controllers are not hot pluggable, so this is dead code + anyway. (The only controllers that can currently be + hotplugged/unplugged are SCSI controllers). + +Signed-off-by: Laine Stump +Reviewed-by: Ján Tomko +Reviewed-by: Boris Fiuczynski + +(cherry picked from commit 143291698358f5a1e693c768893d89038420af25) + +https://bugzilla.redhat.com/show_bug.cgi?id=1508149 + +Conflicts: + + * src/qemu/qemu_hotplug.c + + the code dealing with entering and exiting the monitor is + quite a bit different because we don't have backported + qemuDomainDeleteDevice() downstream + - missing 4cd13478ac33 + +Signed-off-by: Andrea Bolognani +Message-Id: <20190408085732.28684-15-abologna@redhat.com> +Reviewed-by: Laine Stump +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_hotplug.c | 6 ------ + 1 file changed, 6 deletions(-) + +diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c +index 8394efa739..f16213c6e0 100644 +--- a/src/qemu/qemu_hotplug.c ++++ b/src/qemu/qemu_hotplug.c +@@ -5077,17 +5077,11 @@ int qemuDomainDetachControllerDevice(virQEMUDriverPtr driver, + qemuDomainMarkDeviceForRemoval(vm, &detach->info); + + qemuDomainObjEnterMonitor(driver, vm); +- if (detach->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI && +- qemuDomainDetachExtensionDevice(priv->mon, &detach->info)) { +- goto exit_monitor; +- } +- + if (qemuMonitorDelDevice(priv->mon, detach->info.alias)) { + ignore_value(qemuDomainObjExitMonitor(driver, vm)); + goto cleanup; + } + +- exit_monitor: + if (qemuDomainObjExitMonitor(driver, vm) < 0) + goto cleanup; + +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu_process-Prefer-generic-qemuMonitorGetGuestCPU.patch b/SOURCES/libvirt-qemu_process-Prefer-generic-qemuMonitorGetGuestCPU.patch new file mode 100644 index 0000000..881c87c --- /dev/null +++ b/SOURCES/libvirt-qemu_process-Prefer-generic-qemuMonitorGetGuestCPU.patch @@ -0,0 +1,81 @@ +From 894b1e28647f0fd46da3ffc64afc358d438153f9 Mon Sep 17 00:00:00 2001 +Message-Id: <894b1e28647f0fd46da3ffc64afc358d438153f9@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:26:04 +0200 +Subject: [PATCH] qemu_process: Prefer generic qemuMonitorGetGuestCPU +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When updating guest CPU definition according to the vCPU actually +created by QEMU, we want to use the generic qemuMonitorGetGuestCPU to +get both CPUID and MSR features. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 63acb7bfd56f117309e4fcaf438639d4d7bc7dcb) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Signed-off-by: Jiri Denemark +Message-Id: <711a363fde6df79fe9a26b6b4cb0a185cc5ad3cb.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_process.c | 24 ++++++++++++++++++++++-- + 1 file changed, 22 insertions(+), 2 deletions(-) + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 59a739f262..d147e524ee 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -4013,6 +4013,16 @@ qemuProcessVerifyCPUFeatures(virDomainDefPtr def, + } + + ++static const char * ++qemuProcessTranslateCPUFeatures(const char *name, ++ void *opaque) ++{ ++ virQEMUCapsPtr qemuCaps = opaque; ++ ++ return virQEMUCapsCPUFeatureFromQEMU(qemuCaps, name); ++} ++ ++ + static int + qemuProcessFetchGuestCPU(virQEMUDriverPtr driver, + virDomainObjPtr vm, +@@ -4023,18 +4033,28 @@ qemuProcessFetchGuestCPU(virQEMUDriverPtr driver, + qemuDomainObjPrivatePtr priv = vm->privateData; + virCPUDataPtr dataEnabled = NULL; + virCPUDataPtr dataDisabled = NULL; ++ bool generic; + int rc; + + *enabled = NULL; + *disabled = NULL; + +- if (!ARCH_IS_X86(vm->def->os.arch)) ++ generic = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_CPU_UNAVAILABLE_FEATURES); ++ ++ if (!generic && !ARCH_IS_X86(vm->def->os.arch)) + return 0; + + if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) + goto error; + +- rc = qemuMonitorGetGuestCPUx86(priv->mon, &dataEnabled, &dataDisabled); ++ if (generic) { ++ rc = qemuMonitorGetGuestCPU(priv->mon, ++ vm->def->os.arch, ++ qemuProcessTranslateCPUFeatures, priv->qemuCaps, ++ &dataEnabled, &dataDisabled); ++ } else { ++ rc = qemuMonitorGetGuestCPUx86(priv->mon, &dataEnabled, &dataDisabled); ++ } + + if (qemuDomainObjExitMonitor(driver, vm) < 0) + goto error; +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemu_security-Fully-implement-qemuSecurityDomainSetPathLabel.patch b/SOURCES/libvirt-qemu_security-Fully-implement-qemuSecurityDomainSetPathLabel.patch new file mode 100644 index 0000000..49f1358 --- /dev/null +++ b/SOURCES/libvirt-qemu_security-Fully-implement-qemuSecurityDomainSetPathLabel.patch @@ -0,0 +1,166 @@ +From 86f741bf77f39d4af3698b71797e430c2a6989c3 Mon Sep 17 00:00:00 2001 +Message-Id: <86f741bf77f39d4af3698b71797e430c2a6989c3@dist-git> +From: Michal Privoznik +Date: Thu, 3 Jan 2019 10:03:44 +0100 +Subject: [PATCH] qemu_security: Fully implement qemuSecurityDomainSetPathLabel + +Even though the current use of the function does not require full +implementation with transactions (none of the callers pass a path +somewhere under /dev), it doesn't hurt either. Moreover, in +future patches the paradigm is going to shift so that any API +that touches a file is required to use transactions. + +Signed-off-by: Michal Privoznik +Reviewed-by: John Ferlan +(cherry picked from commit da24db2d30352c094f76dffb523e7f344ff8e30d) + +https://bugzilla.redhat.com/show_bug.cgi?id=1658112 + +Signed-off-by: Erik Skultety +Message-Id: <4de2beabd9868259f1856f7eafcc835b5b2a3d6b.1546506016.git.eskultet@redhat.com> +Reviewed-by: Jiri Denemark +--- + src/qemu/qemu_domain.c | 3 +-- + src/qemu/qemu_process.c | 15 ++++++--------- + src/qemu/qemu_security.c | 30 ++++++++++++++++++++++++++++++ + src/qemu/qemu_security.h | 6 +++++- + 4 files changed, 42 insertions(+), 12 deletions(-) + +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index 95b84af78a..c9899b9e6d 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -801,8 +801,7 @@ qemuDomainWriteMasterKeyFile(virQEMUDriverPtr driver, + goto cleanup; + } + +- if (qemuSecurityDomainSetPathLabel(driver->securityManager, +- vm->def, path, false) < 0) ++ if (qemuSecurityDomainSetPathLabel(driver, vm, path, false) < 0) + goto cleanup; + + ret = 0; +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 34aac69afc..c0f95dd5f1 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -2778,8 +2778,7 @@ qemuProcessStartManagedPRDaemon(virDomainObjPtr vm) + virCgroupAddMachineTask(priv->cgroup, cpid) < 0) + goto cleanup; + +- if (qemuSecurityDomainSetPathLabel(driver->securityManager, +- vm->def, socketPath, true) < 0) ++ if (qemuSecurityDomainSetPathLabel(driver, vm, socketPath, true) < 0) + goto cleanup; + + priv->prDaemonRunning = true; +@@ -3656,7 +3655,7 @@ qemuProcessNeedMemoryBackingPath(virDomainDefPtr def, + + static int + qemuProcessBuildDestroyMemoryPathsImpl(virQEMUDriverPtr driver, +- virDomainDefPtr def, ++ virDomainObjPtr vm, + const char *path, + bool build) + { +@@ -3671,8 +3670,7 @@ qemuProcessBuildDestroyMemoryPathsImpl(virQEMUDriverPtr driver, + return -1; + } + +- if (qemuSecurityDomainSetPathLabel(driver->securityManager, +- def, path, true) < 0) ++ if (qemuSecurityDomainSetPathLabel(driver, vm, path, true) < 0) + return -1; + } else { + if (virFileDeleteTree(path) < 0) +@@ -3708,7 +3706,7 @@ qemuProcessBuildDestroyMemoryPaths(virQEMUDriverPtr driver, + if (!path) + goto cleanup; + +- if (qemuProcessBuildDestroyMemoryPathsImpl(driver, vm->def, ++ if (qemuProcessBuildDestroyMemoryPathsImpl(driver, vm, + path, build) < 0) + goto cleanup; + +@@ -3720,7 +3718,7 @@ qemuProcessBuildDestroyMemoryPaths(virQEMUDriverPtr driver, + if (qemuGetMemoryBackingDomainPath(vm->def, cfg, &path) < 0) + goto cleanup; + +- if (qemuProcessBuildDestroyMemoryPathsImpl(driver, vm->def, ++ if (qemuProcessBuildDestroyMemoryPathsImpl(driver, vm, + path, build) < 0) + goto cleanup; + +@@ -4904,8 +4902,7 @@ qemuProcessMakeDir(virQEMUDriverPtr driver, + goto cleanup; + } + +- if (qemuSecurityDomainSetPathLabel(driver->securityManager, +- vm->def, path, true) < 0) ++ if (qemuSecurityDomainSetPathLabel(driver, vm, path, true) < 0) + goto cleanup; + + ret = 0; +diff --git a/src/qemu/qemu_security.c b/src/qemu/qemu_security.c +index af3be42854..268def309a 100644 +--- a/src/qemu/qemu_security.c ++++ b/src/qemu/qemu_security.c +@@ -493,3 +493,33 @@ qemuSecurityCleanupTPMEmulator(virQEMUDriverPtr driver, + { + virSecurityManagerRestoreTPMLabels(driver->securityManager, def); + } ++ ++ ++int ++qemuSecurityDomainSetPathLabel(virQEMUDriverPtr driver, ++ virDomainObjPtr vm, ++ const char *path, ++ bool allowSubtree) ++{ ++ int ret = -1; ++ ++ if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT) && ++ virSecurityManagerTransactionStart(driver->securityManager) < 0) ++ goto cleanup; ++ ++ if (virSecurityManagerDomainSetPathLabel(driver->securityManager, ++ vm->def, ++ path, ++ allowSubtree) < 0) ++ goto cleanup; ++ ++ if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT) && ++ virSecurityManagerTransactionCommit(driver->securityManager, ++ vm->pid) < 0) ++ goto cleanup; ++ ++ ret = 0; ++ cleanup: ++ virSecurityManagerTransactionAbort(driver->securityManager); ++ return ret; ++} +diff --git a/src/qemu/qemu_security.h b/src/qemu/qemu_security.h +index a189b63828..fd11fbdd9d 100644 +--- a/src/qemu/qemu_security.h ++++ b/src/qemu/qemu_security.h +@@ -95,12 +95,16 @@ int qemuSecurityStartTPMEmulator(virQEMUDriverPtr driver, + void qemuSecurityCleanupTPMEmulator(virQEMUDriverPtr driver, + virDomainDefPtr def); + ++int qemuSecurityDomainSetPathLabel(virQEMUDriverPtr driver, ++ virDomainObjPtr vm, ++ const char *path, ++ bool allowSubtree); ++ + /* Please note that for these APIs there is no wrapper yet. Do NOT blindly add + * new APIs here. If an API can touch a /dev file add a proper wrapper instead. + */ + # define qemuSecurityCheckAllLabel virSecurityManagerCheckAllLabel + # define qemuSecurityClearSocketLabel virSecurityManagerClearSocketLabel +-# define qemuSecurityDomainSetPathLabel virSecurityManagerDomainSetPathLabel + # define qemuSecurityGenLabel virSecurityManagerGenLabel + # define qemuSecurityGetBaseLabel virSecurityManagerGetBaseLabel + # define qemuSecurityGetDOI virSecurityManagerGetDOI +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemuhotplugtest-Don-t-plug-a-SCSI-disk-at-unit-7.patch b/SOURCES/libvirt-qemuhotplugtest-Don-t-plug-a-SCSI-disk-at-unit-7.patch new file mode 100644 index 0000000..ec69f83 --- /dev/null +++ b/SOURCES/libvirt-qemuhotplugtest-Don-t-plug-a-SCSI-disk-at-unit-7.patch @@ -0,0 +1,71 @@ +From 310eeaa9bedbbe58a6cdbdbc2e057fc6d6c66586 Mon Sep 17 00:00:00 2001 +Message-Id: <310eeaa9bedbbe58a6cdbdbc2e057fc6d6c66586@dist-git> +From: Michal Privoznik +Date: Thu, 18 Apr 2019 19:36:32 +0200 +Subject: [PATCH] qemuhotplugtest: Don't plug a SCSI disk at unit 7 + +RHEL-7.7: https://bugzilla.redhat.com/show_bug.cgi?id=1692296 +RHEL-8.1.0: https://bugzilla.redhat.com/show_bug.cgi?id=1692354 + +Unit number 7 is kind of special. It's reserved for SCSI +controller. The comment in virDomainSCSIDriveAddressIsUsed() +summarizes that pretty nicely. Libvirt would never generate +such address. + +Signed-off-by: Michal Privoznik +Tested-by: Daniel Henrique Barboza +Reviewed-by: Jim Fehlig +(cherry picked from commit ee2c5ef39fd91345893904433c6f458685543af5) +Signed-off-by: Michal Privoznik +Message-Id: +Reviewed-by: Jiri Denemark +--- + tests/qemuhotplugtest.c | 2 +- + tests/qemuhotplugtestdevices/qemuhotplug-disk-scsi-2.xml | 2 +- + ...uhotplug-base-without-scsi-controller-live+disk-scsi-2.xml | 4 ++-- + 3 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c +index 663e33ed00..8e0086a269 100644 +--- a/tests/qemuhotplugtest.c ++++ b/tests/qemuhotplugtest.c +@@ -761,7 +761,7 @@ mymain(void) + "device_del", QMP_OK, + "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, ++ "device_del", QMP_DEVICE_DELETED("scsi3-0-5-6") QMP_OK, + "human-monitor-command", HMP("")); + + DO_TEST_ATTACH("base-live", "qemu-agent", false, true, +diff --git a/tests/qemuhotplugtestdevices/qemuhotplug-disk-scsi-2.xml b/tests/qemuhotplugtestdevices/qemuhotplug-disk-scsi-2.xml +index 3a847fbda6..876afb182f 100644 +--- a/tests/qemuhotplugtestdevices/qemuhotplug-disk-scsi-2.xml ++++ b/tests/qemuhotplugtestdevices/qemuhotplug-disk-scsi-2.xml +@@ -2,7 +2,7 @@ + + + +-
++
+ + + +diff --git a/tests/qemuhotplugtestdomains/qemuhotplug-base-without-scsi-controller-live+disk-scsi-2.xml b/tests/qemuhotplugtestdomains/qemuhotplug-base-without-scsi-controller-live+disk-scsi-2.xml +index d35fea6f5f..72b5174825 100644 +--- a/tests/qemuhotplugtestdomains/qemuhotplug-base-without-scsi-controller-live+disk-scsi-2.xml ++++ b/tests/qemuhotplugtestdomains/qemuhotplug-base-without-scsi-controller-live+disk-scsi-2.xml +@@ -26,8 +26,8 @@ + + + +- +-
++ ++
+ + + +-- +2.21.0 + diff --git a/SOURCES/libvirt-qemuhotplugtest-Test-guestfwd-attach-and-detach.patch b/SOURCES/libvirt-qemuhotplugtest-Test-guestfwd-attach-and-detach.patch new file mode 100644 index 0000000..291a266 --- /dev/null +++ b/SOURCES/libvirt-qemuhotplugtest-Test-guestfwd-attach-and-detach.patch @@ -0,0 +1,117 @@ +From 37dbf9fd0da8345ad03948543b9ae64954d219e1 Mon Sep 17 00:00:00 2001 +Message-Id: <37dbf9fd0da8345ad03948543b9ae64954d219e1@dist-git> +From: Michal Privoznik +Date: Thu, 27 Jun 2019 14:44:48 +0200 +Subject: [PATCH] qemuhotplugtest: Test guestfwd attach and detach + +Previous two commits demonstrate a hole in our test scenario. +Fix that. + +Signed-off-by: Michal Privoznik +Reviewed-by: John Ferlan +(cherry picked from commit 17ddfd420a0dbcdd3f76fbecf7428acb301db188) + +https://bugzilla.redhat.com/show_bug.cgi?id=1624204 + +Signed-off-by: Michal Privoznik +Message-Id: <08fcf2bbdefa193065ecb3c28f8d5a5a61cfeb69.1561639408.git.mprivozn@redhat.com> +Reviewed-by: Jiri Denemark +--- + tests/qemuhotplugtest.c | 6 ++ + .../qemuhotplug-guestfwd.xml | 4 ++ + .../qemuhotplug-base-live+guestfwd.xml | 55 +++++++++++++++++++ + 3 files changed, 65 insertions(+) + create mode 100644 tests/qemuhotplugtestdevices/qemuhotplug-guestfwd.xml + create mode 100644 tests/qemuhotplugtestdomains/qemuhotplug-base-live+guestfwd.xml + +diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c +index 8e0086a269..aaa3492d4c 100644 +--- a/tests/qemuhotplugtest.c ++++ b/tests/qemuhotplugtest.c +@@ -836,6 +836,12 @@ mymain(void) + DO_TEST_DETACH("base-live", "watchdog-user-alias-full", false, false, + "device_del", QMP_OK); + ++ DO_TEST_ATTACH("base-live", "guestfwd", false, true, ++ "chardev-add", QMP_OK, ++ "netdev_add", QMP_OK); ++ DO_TEST_DETACH("base-live", "guestfwd", false, false, ++ "netdev_del", QMP_OK); ++ + #define DO_TEST_CPU_GROUP(prefix, vcpus, modernhp, expectfail) \ + do { \ + cpudata.test = prefix; \ +diff --git a/tests/qemuhotplugtestdevices/qemuhotplug-guestfwd.xml b/tests/qemuhotplugtestdevices/qemuhotplug-guestfwd.xml +new file mode 100644 +index 0000000000..c67dbdb8df +--- /dev/null ++++ b/tests/qemuhotplugtestdevices/qemuhotplug-guestfwd.xml +@@ -0,0 +1,4 @@ ++ ++ ++ ++ +diff --git a/tests/qemuhotplugtestdomains/qemuhotplug-base-live+guestfwd.xml b/tests/qemuhotplugtestdomains/qemuhotplug-base-live+guestfwd.xml +new file mode 100644 +index 0000000000..8d7294123b +--- /dev/null ++++ b/tests/qemuhotplugtestdomains/qemuhotplug-base-live+guestfwd.xml +@@ -0,0 +1,55 @@ ++ ++ hotplug ++ d091ea82-29e6-2e34-3005-f02617b36e87 ++ 4194304 ++ 4194304 ++ 4 ++ ++ hvm ++ ++ ++ ++ ++ ++ ++ ++ ++ destroy ++ restart ++ restart ++ ++ /usr/bin/qemu-system-x86_64 ++ ++ ++
++ ++ ++ ++
++ ++ ++ ++
++ ++ ++ ++ ++ ++ ++
++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +-- +2.22.0 + diff --git a/SOURCES/libvirt-qemuxml2argvtest-Add-test-for-CPU-features-translation.patch b/SOURCES/libvirt-qemuxml2argvtest-Add-test-for-CPU-features-translation.patch new file mode 100644 index 0000000..de15331 --- /dev/null +++ b/SOURCES/libvirt-qemuxml2argvtest-Add-test-for-CPU-features-translation.patch @@ -0,0 +1,134 @@ +From 3ddc4c63f770fa6e2b2e37915c3f70598aa59d97 Mon Sep 17 00:00:00 2001 +Message-Id: <3ddc4c63f770fa6e2b2e37915c3f70598aa59d97@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:50 +0200 +Subject: [PATCH] qemuxml2argvtest: Add test for CPU features translation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This should cover all CPU features for which QEMU prefers spelling that +differs from the one used by libvirt. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 24aa210d90770a6ea2313ebf2047c0a802932dca) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Conflicts: + tests/qemuxml2argvdata/cpu-translation.x86_64-latest.args + - old command line + - downstream patch to add rtm=on and hle=on for Haswell + + tests/qemuxml2argvdata/cpu-translation.x86_64-4.0.0.args + - dropped as there are no 4.0.0 capabilities downstream + + tests/qemuxml2argvtest.c + - dropped cpu-translation test with QEMU 4.0.0 + +Signed-off-by: Jiri Denemark +Message-Id: <6ce0d74bdf9a66c0908fd8162902b1f75870189b.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + .../cpu-translation.x86_64-latest.args | 33 ++++++++++++++++++ + tests/qemuxml2argvdata/cpu-translation.xml | 34 +++++++++++++++++++ + tests/qemuxml2argvtest.c | 1 + + 3 files changed, 68 insertions(+) + create mode 100644 tests/qemuxml2argvdata/cpu-translation.x86_64-latest.args + create mode 100644 tests/qemuxml2argvdata/cpu-translation.xml + +diff --git a/tests/qemuxml2argvdata/cpu-translation.x86_64-latest.args b/tests/qemuxml2argvdata/cpu-translation.x86_64-latest.args +new file mode 100644 +index 0000000000..898b987086 +--- /dev/null ++++ b/tests/qemuxml2argvdata/cpu-translation.x86_64-latest.args +@@ -0,0 +1,33 @@ ++LC_ALL=C \ ++PATH=/bin \ ++HOME=/home/test \ ++USER=test \ ++LOGNAME=test \ ++QEMU_AUDIO_DRV=none \ ++/usr/bin/qemu-system-x86_64 \ ++-name guest=QEMUGuest1,debug-threads=on \ ++-S \ ++-object secret,id=masterKey0,format=raw,\ ++file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \ ++-machine pc,accel=tcg,usb=off,dump-guest-core=off \ ++-cpu Haswell,pclmuldq=on,ds_cpl=on,tsc_adjust=on,fxsr_opt=on,lahf_lm=on,\ ++cmp_legacy=on,nodeid_msr=on,perfctr_core=on,perfctr_nb=on,rtm=on,hle=on,\ ++kvm_pv_eoi=on,kvm_pv_unhalt=on \ ++-m 214 \ ++-realtime mlock=off \ ++-smp 1,sockets=1,cores=1,threads=1 \ ++-uuid c7a5fdbd-fade-9455-926a-d65c16db1809 \ ++-display none \ ++-no-user-config \ ++-nodefaults \ ++-chardev socket,id=charmonitor,fd=1729,server,nowait \ ++-mon chardev=charmonitor,id=monitor,mode=control \ ++-rtc base=utc \ ++-no-shutdown \ ++-no-acpi \ ++-boot strict=on \ ++-device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \ ++-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x2 \ ++-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\ ++resourcecontrol=deny \ ++-msg timestamp=on +diff --git a/tests/qemuxml2argvdata/cpu-translation.xml b/tests/qemuxml2argvdata/cpu-translation.xml +new file mode 100644 +index 0000000000..4054f3d3be +--- /dev/null ++++ b/tests/qemuxml2argvdata/cpu-translation.xml +@@ -0,0 +1,34 @@ ++ ++ QEMUGuest1 ++ c7a5fdbd-fade-9455-926a-d65c16db1809 ++ 219100 ++ 219100 ++ 1 ++ ++ hvm ++ ++ ++ ++ ++ ++ ++ ++ Haswell ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ destroy ++ restart ++ destroy ++ ++ /usr/bin/qemu-system-x86_64 ++ ++ +diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c +index 9de0cbf7e9..03d6a60736 100644 +--- a/tests/qemuxml2argvtest.c ++++ b/tests/qemuxml2argvtest.c +@@ -1741,6 +1741,7 @@ mymain(void) + DO_TEST("cpu-Haswell-noTSX", QEMU_CAPS_KVM); + DO_TEST("cpu-host-model-cmt", NONE); + DO_TEST("cpu-tsc-frequency", QEMU_CAPS_KVM); ++ DO_TEST_CAPS_LATEST("cpu-translation"); + qemuTestSetHostCPU(driver.caps, NULL); + + DO_TEST("encrypted-disk", QEMU_CAPS_QCOW2_LUKS, QEMU_CAPS_OBJECT_SECRET); +-- +2.22.0 + diff --git a/SOURCES/libvirt-rpc-virnetlibsshsession-update-deprecated-functions.patch b/SOURCES/libvirt-rpc-virnetlibsshsession-update-deprecated-functions.patch new file mode 100644 index 0000000..a846323 --- /dev/null +++ b/SOURCES/libvirt-rpc-virnetlibsshsession-update-deprecated-functions.patch @@ -0,0 +1,63 @@ +From aa46a438d03839963badb7bdd2904a71f0662942 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Fri, 21 Jun 2019 09:30:36 +0200 +Subject: [PATCH] rpc: virnetlibsshsession: update deprecated functions + +In libssh 0.9.0 functions ssh_is_server_known and ssh_write_knownhost +are marked as deprecated. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1722735 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Jiri Denemark +--- + m4/virt-libssh.m4 | 8 ++++++++ + src/rpc/virnetlibsshsession.c | 4 ++-- + 2 files changed, 10 insertions(+), 2 deletions(-) + +diff --git a/m4/virt-libssh.m4 b/m4/virt-libssh.m4 +index 01c3b75c72..132447da16 100644 +--- a/m4/virt-libssh.m4 ++++ b/m4/virt-libssh.m4 +@@ -33,6 +33,14 @@ AC_DEFUN([LIBVIRT_CHECK_LIBSSH],[ + [], + [AC_DEFINE_UNQUOTED([ssh_get_server_publickey], [ssh_get_publickey], + [ssh_get_publickey is deprecated and replaced by ssh_get_server_publickey.])]) ++ AC_CHECK_FUNC([ssh_session_is_known_server], ++ [], ++ [AC_DEFINE_UNQUOTED([ssh_session_is_known_server], [ssh_is_server_known], ++ [ssh_is_server_known is deprecated and replaced by ssh_session_is_known_server.])]) ++ AC_CHECK_FUNC([ssh_session_update_known_hosts], ++ [], ++ [AC_DEFINE_UNQUOTED([ssh_session_update_known_hosts], [ssh_write_knownhost], ++ [ssh_write_knownhost is deprecated and replaced by ssh_session_update_known_hosts.])]) + CFLAGS="$old_CFLAGS" + LIBS="$old_LIBS" + fi +diff --git a/src/rpc/virnetlibsshsession.c b/src/rpc/virnetlibsshsession.c +index df819f6169..7bc2bd33ee 100644 +--- a/src/rpc/virnetlibsshsession.c ++++ b/src/rpc/virnetlibsshsession.c +@@ -287,7 +287,7 @@ virNetLibsshCheckHostKey(virNetLibsshSessionPtr sess) + if (sess->hostKeyVerify == VIR_NET_LIBSSH_HOSTKEY_VERIFY_IGNORE) + return 0; + +- state = ssh_is_server_known(sess->session); ++ state = ssh_session_is_known_server(sess->session); + + switch (state) { + case SSH_SERVER_KNOWN_OK: +@@ -381,7 +381,7 @@ virNetLibsshCheckHostKey(virNetLibsshSessionPtr sess) + + /* write the host key file, if specified */ + if (sess->knownHostsFile) { +- if (ssh_write_knownhost(sess->session) < 0) { ++ if (ssh_session_update_known_hosts(sess->session) < 0) { + errmsg = ssh_get_error(sess->session); + virReportError(VIR_ERR_LIBSSH, + _("failed to write known_host file '%s': %s"), +-- +2.22.0 + diff --git a/SOURCES/libvirt-test-Introduce-virnetdevopenvswitchtest.patch b/SOURCES/libvirt-test-Introduce-virnetdevopenvswitchtest.patch new file mode 100644 index 0000000..b270449 --- /dev/null +++ b/SOURCES/libvirt-test-Introduce-virnetdevopenvswitchtest.patch @@ -0,0 +1,356 @@ +From e1699c1bb0cbf20ea24db8607492a8f418ee8f95 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Michal Privoznik +Date: Tue, 30 Jul 2019 15:30:52 +0200 +Subject: [PATCH] test: Introduce virnetdevopenvswitchtest +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Test if our parsing of interface stats as returned by ovs-vsctl +works as expected. To achieve this without having to mock +virCommand* I'm separating parsing of stats into a separate +function. + +Signed-off-by: Michal Privoznik +Reviewed-by: Ján Tomko +(cherry picked from commit cc34260f5a8715d208ee45a6ebaa79e5264cbe68) + +Conflicts: +- src/libvirt_private.syms: Context, no + virNetDevOpenvswitchInterfaceGetMaster() +- src/util/virnetdevopenvswitch.c: Unknown, conflict in a + comment, the diff looks the same to me. +- tests/Makefile.am: Context, no virnetworkportxml2xmldata in + EXTRA_DIST + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1721434 + +Signed-off-by: Michal Privoznik +Message-Id: +Reviewed-by: Ján Tomko +--- + src/libvirt_private.syms | 1 + + src/util/virnetdevopenvswitch.c | 93 ++++++++++++------- + src/util/virnetdevopenvswitch.h | 4 + + tests/Makefile.am | 13 ++- + tests/virnetdevopenvswitchdata/stats1.json | 1 + + tests/virnetdevopenvswitchdata/stats2.json | 1 + + tests/virnetdevopenvswitchtest.c | 101 +++++++++++++++++++++ + 7 files changed, 177 insertions(+), 37 deletions(-) + create mode 100644 tests/virnetdevopenvswitchdata/stats1.json + create mode 100644 tests/virnetdevopenvswitchdata/stats2.json + create mode 100644 tests/virnetdevopenvswitchtest.c + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 8132f9664b..f4b54cee0b 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -2422,6 +2422,7 @@ virNetDevMidonetUnbindPort; + virNetDevOpenvswitchAddPort; + virNetDevOpenvswitchGetMigrateData; + virNetDevOpenvswitchGetVhostuserIfname; ++virNetDevOpenvswitchInterfaceParseStats; + virNetDevOpenvswitchInterfaceStats; + virNetDevOpenvswitchRemovePort; + virNetDevOpenvswitchSetMigrateData; +diff --git a/src/util/virnetdevopenvswitch.c b/src/util/virnetdevopenvswitch.c +index dbd832053b..ac8ec09b65 100644 +--- a/src/util/virnetdevopenvswitch.c ++++ b/src/util/virnetdevopenvswitch.c +@@ -306,49 +306,30 @@ int virNetDevOpenvswitchSetMigrateData(char *migrate, const char *ifname) + return 0; + } + ++ + /** +- * virNetDevOpenvswitchInterfaceStats: +- * @ifname: the name of the interface +- * @stats: the retreived domain interface stat ++ * virNetDevOpenvswitchInterfaceParseStats: ++ * @json: Input string in JSON format ++ * @stats: parsed stats + * +- * Retrieves the OVS interfaces stats ++ * For given input string @json parse interface statistics and store them into ++ * @stats. + * +- * Returns 0 in case of success or -1 in case of failure ++ * Returns: 0 on success, ++ * -1 otherwise (with error reported). + */ + int +-virNetDevOpenvswitchInterfaceStats(const char *ifname, +- virDomainInterfaceStatsPtr stats) ++virNetDevOpenvswitchInterfaceParseStats(const char *json, ++ virDomainInterfaceStatsPtr stats) + { +- VIR_AUTOPTR(virCommand) cmd = NULL; +- VIR_AUTOFREE(char *) output = NULL; + VIR_AUTOPTR(virJSONValue) jsonStats = NULL; + virJSONValuePtr jsonMap = NULL; + size_t i; + +- cmd = virCommandNew(OVSVSCTL); +- virNetDevOpenvswitchAddTimeout(cmd); +- virCommandAddArgList(cmd, "--if-exists", "--format=list", "--data=json", +- "--no-headings", "--columns=statistics", "list", +- "Interface", ifname, NULL); +- virCommandSetOutputBuffer(cmd, &output); ++ stats->rx_bytes = stats->rx_packets = stats->rx_errs = stats->rx_drop = -1; ++ stats->tx_bytes = stats->tx_packets = stats->tx_errs = stats->tx_drop = -1; + +- /* The above command returns either: +- * 1) empty string if @ifname doesn't exist, or +- * 2) a JSON array, for instance: +- * ["map",[["collisions",0],["rx_bytes",0],["rx_crc_err",0],["rx_dropped",0], +- * ["rx_errors",0],["rx_frame_err",0],["rx_over_err",0],["rx_packets",0], +- * ["tx_bytes",12406],["tx_dropped",0],["tx_errors",0],["tx_packets",173]]] +- */ +- +- if (virCommandRun(cmd, NULL) < 0 || +- STREQ_NULLABLE(output, "")) { +- /* no ovs-vsctl or interface 'ifname' doesn't exists in ovs */ +- virReportError(VIR_ERR_INTERNAL_ERROR, "%s", +- _("Interface not found")); +- return -1; +- } +- +- if (!(jsonStats = virJSONValueFromString(output)) || ++ if (!(jsonStats = virJSONValueFromString(json)) || + !virJSONValueIsArray(jsonStats) || + !(jsonMap = virJSONValueArrayGet(jsonStats, 1))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", +@@ -356,9 +337,6 @@ virNetDevOpenvswitchInterfaceStats(const char *ifname, + return -1; + } + +- stats->rx_bytes = stats->rx_packets = stats->rx_errs = stats->rx_drop = -1; +- stats->tx_bytes = stats->tx_packets = stats->tx_errs = stats->tx_drop = -1; +- + for (i = 0; i < virJSONValueArraySize(jsonMap); i++) { + virJSONValuePtr item = virJSONValueArrayGet(jsonMap, i); + virJSONValuePtr jsonKey; +@@ -399,6 +377,51 @@ virNetDevOpenvswitchInterfaceStats(const char *ifname, + } + } + ++ return 0; ++} ++ ++/** ++ * virNetDevOpenvswitchInterfaceStats: ++ * @ifname: the name of the interface ++ * @stats: the retrieved domain interface stat ++ * ++ * Retrieves the OVS interfaces stats ++ * ++ * Returns 0 in case of success or -1 in case of failure ++ */ ++int ++virNetDevOpenvswitchInterfaceStats(const char *ifname, ++ virDomainInterfaceStatsPtr stats) ++{ ++ VIR_AUTOPTR(virCommand) cmd = NULL; ++ VIR_AUTOFREE(char *) output = NULL; ++ ++ cmd = virCommandNew(OVSVSCTL); ++ virNetDevOpenvswitchAddTimeout(cmd); ++ virCommandAddArgList(cmd, "--if-exists", "--format=list", "--data=json", ++ "--no-headings", "--columns=statistics", "list", ++ "Interface", ifname, NULL); ++ virCommandSetOutputBuffer(cmd, &output); ++ ++ /* The above command returns either: ++ * 1) empty string if @ifname doesn't exist, or ++ * 2) a JSON array, for instance: ++ * ["map",[["collisions",0],["rx_bytes",0],["rx_crc_err",0],["rx_dropped",0], ++ * ["rx_errors",0],["rx_frame_err",0],["rx_over_err",0],["rx_packets",0], ++ * ["tx_bytes",12406],["tx_dropped",0],["tx_errors",0],["tx_packets",173]]] ++ */ ++ ++ if (virCommandRun(cmd, NULL) < 0 || ++ STREQ_NULLABLE(output, "")) { ++ /* no ovs-vsctl or interface 'ifname' doesn't exists in ovs */ ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("Interface not found")); ++ return -1; ++ } ++ ++ if (virNetDevOpenvswitchInterfaceParseStats(output, stats) < 0) ++ return -1; ++ + if (stats->rx_bytes == -1 && + stats->rx_packets == -1 && + stats->rx_errs == -1 && +diff --git a/src/util/virnetdevopenvswitch.h b/src/util/virnetdevopenvswitch.h +index 6f6e620c22..c1a211dec1 100644 +--- a/src/util/virnetdevopenvswitch.h ++++ b/src/util/virnetdevopenvswitch.h +@@ -53,6 +53,10 @@ int virNetDevOpenvswitchGetMigrateData(char **migrate, const char *ifname) + int virNetDevOpenvswitchSetMigrateData(char *migrate, const char *ifname) + ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; + ++int virNetDevOpenvswitchInterfaceParseStats(const char *json, ++ virDomainInterfaceStatsPtr stats) ++ ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; ++ + int virNetDevOpenvswitchInterfaceStats(const char *ifname, + virDomainInterfaceStatsPtr stats) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +diff --git a/tests/Makefile.am b/tests/Makefile.am +index c0337ea10c..201de1d37d 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -157,6 +157,7 @@ EXTRA_DIST = \ + virmock.h \ + virnetdaemondata \ + virnetdevtestdata \ ++ virnetdevopenvswitchdata \ + virnwfilterbindingxml2xmldata \ + virpcitestdata \ + virscsidata \ +@@ -1230,9 +1231,17 @@ virmacmaptest_SOURCES = \ + virmacmaptest.c testutils.h testutils.c + virmacmaptest_LDADD = $(LDADDS) + +-test_programs += virmacmaptest ++virnetdevopenvswitchtest_SOURCES = \ ++ virnetdevopenvswitchtest.c testutils.h testutils.c ++virnetdevopenvswitchtest_LDADD = $(LDADDS) ++ ++test_programs += \ ++ virmacmaptest \ ++ virnetdevopenvswitchtest + else ! WITH_YAJL +-EXTRA_DIST += virmacmaptest.c ++EXTRA_DIST += \ ++ virmacmaptest.c \ ++ virnetdevopenvswitchtest.c + endif ! WITH_YAJL + + virnetdevtest_SOURCES = \ +diff --git a/tests/virnetdevopenvswitchdata/stats1.json b/tests/virnetdevopenvswitchdata/stats1.json +new file mode 100644 +index 0000000000..1138c6271e +--- /dev/null ++++ b/tests/virnetdevopenvswitchdata/stats1.json +@@ -0,0 +1 @@ ++["map",[["collisions",1],["rx_bytes",2],["rx_crc_err",3],["rx_dropped",4],["rx_errors",5],["rx_frame_err",6],["rx_over_err",7],["rx_packets",8],["tx_bytes",9],["tx_dropped",10],["tx_errors",11],["tx_packets",12]]] +diff --git a/tests/virnetdevopenvswitchdata/stats2.json b/tests/virnetdevopenvswitchdata/stats2.json +new file mode 100644 +index 0000000000..d84be7e011 +--- /dev/null ++++ b/tests/virnetdevopenvswitchdata/stats2.json +@@ -0,0 +1 @@ ++["map",[["collisions",0],["rx_bytes",0],["rx_crc_err",0],["rx_dropped",0],["rx_errors",0],["rx_frame_err",0],["rx_over_err",0],["rx_packets",0],["tx_bytes",12406],["tx_dropped",0],["tx_errors",0],["tx_packets",173]]] +diff --git a/tests/virnetdevopenvswitchtest.c b/tests/virnetdevopenvswitchtest.c +new file mode 100644 +index 0000000000..f01e77cbba +--- /dev/null ++++ b/tests/virnetdevopenvswitchtest.c +@@ -0,0 +1,101 @@ ++/* ++ * Copyright (C) 2019 Red Hat, Inc. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library. If not, see ++ * . ++ */ ++ ++#include ++ ++#include "testutils.h" ++#include "virnetdevopenvswitch.h" ++ ++#define VIR_FROM_THIS VIR_FROM_NONE ++ ++typedef struct _InterfaceParseStatsData InterfaceParseStatsData; ++struct _InterfaceParseStatsData { ++ const char *filename; ++ const virDomainInterfaceStatsStruct stats; ++}; ++ ++ ++static int ++testInterfaceParseStats(const void *opaque) ++{ ++ const InterfaceParseStatsData *data = opaque; ++ VIR_AUTOFREE(char *) filename = NULL; ++ VIR_AUTOFREE(char *) buf = NULL; ++ virDomainInterfaceStatsStruct actual; ++ ++ if (virAsprintf(&filename, "%s/virnetdevopenvswitchdata/%s", ++ abs_srcdir, data->filename) < 0) ++ return -1; ++ ++ if (virFileReadAll(filename, 1024, &buf) < 0) ++ return -1; ++ ++ if (virNetDevOpenvswitchInterfaceParseStats(buf, &actual) < 0) ++ return -1; ++ ++ if (memcmp(&actual, &data->stats, sizeof(actual)) != 0) { ++ fprintf(stderr, ++ "Expected stats: %lld %lld %lld %lld %lld %lld %lld %lld\n" ++ "Actual stats: %lld %lld %lld %lld %lld %lld %lld %lld", ++ data->stats.rx_bytes, ++ data->stats.rx_packets, ++ data->stats.rx_errs, ++ data->stats.rx_drop, ++ data->stats.tx_bytes, ++ data->stats.tx_packets, ++ data->stats.tx_errs, ++ data->stats.tx_drop, ++ actual.rx_bytes, ++ actual.rx_packets, ++ actual.rx_errs, ++ actual.rx_drop, ++ actual.tx_bytes, ++ actual.tx_packets, ++ actual.tx_errs, ++ actual.tx_drop); ++ ++ return -1; ++ } ++ ++ return 0; ++} ++ ++ ++static int ++mymain(void) ++{ ++ int ret = 0; ++ ++#define TEST_INTERFACE_STATS(file, \ ++ rxBytes, rxPackets, rxErrs, rxDrop, \ ++ txBytes, txPackets, txErrs, txDrop) \ ++ do { \ ++ const InterfaceParseStatsData data = {.filename = file, .stats = { \ ++ rxBytes, rxPackets, rxErrs, rxDrop, \ ++ txBytes, txPackets, txErrs, txDrop}}; \ ++ if (virTestRun("Interface stats " file, testInterfaceParseStats, &data) < 0) \ ++ ret = -1; \ ++ } while (0) ++ ++ TEST_INTERFACE_STATS("stats1.json", 9, 12, 11, 10, 2, 8, 5, 4); ++ TEST_INTERFACE_STATS("stats2.json", 12406, 173, 0, 0, 0, 0, 0, 0); ++ ++ return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; ++} ++ ++VIR_TEST_MAIN(mymain); +-- +2.22.0 + diff --git a/SOURCES/libvirt-tests-Add-QEMU-caps-data-for-future-4.1.0.patch b/SOURCES/libvirt-tests-Add-QEMU-caps-data-for-future-4.1.0.patch new file mode 100644 index 0000000..3334ae5 --- /dev/null +++ b/SOURCES/libvirt-tests-Add-QEMU-caps-data-for-future-4.1.0.patch @@ -0,0 +1,25247 @@ +From e4ded1e96b54db8f56af824a1e3e1acdf2f84e71 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:48 +0200 +Subject: [PATCH] tests: Add QEMU caps data for future 4.1.0 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit fb5bde121fcc0dc99926fe71c17a0ff668003250) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Conflicts: + tests/qemucapabilitiesdata/caps_4.1.0.x86_64.replies + tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml + - different set of probed capabilities + + tests/qemucapabilitiestest.c + - upstream uses testQemuCapsIterate + +Signed-off-by: Jiri Denemark +Message-Id: +Reviewed-by: Ján Tomko +--- + .../caps_4.1.0.x86_64.replies | 23762 ++++++++++++++++ + .../caps_4.1.0.x86_64.xml | 1424 + + tests/qemucapabilitiestest.c | 1 + + 3 files changed, 25187 insertions(+) + create mode 100644 tests/qemucapabilitiesdata/caps_4.1.0.x86_64.replies + create mode 100644 tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml + +diff --git a/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.replies b/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.replies +new file mode 100644 +index 0000000000..ab0ac1e7bf +--- /dev/null ++++ b/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.replies +@@ -0,0 +1,23762 @@ ++{ ++ "execute": "qmp_capabilities", ++ "id": "libvirt-1" ++} ++ ++{ ++ "return": { ++ }, ++ "id": "libvirt-1" ++} ++ ++{ ++ "execute": "query-version", ++ "id": "libvirt-2" ++} ++ ++{ ++ "return": { ++ "qemu": { ++ "micro": 50, ++ "minor": 0, ++ "major": 4 ++ }, ++ "package": "v4.0.0-1173-g9c70209b63" ++ }, ++ "id": "libvirt-2" ++} ++ ++{ ++ "execute": "query-target", ++ "id": "libvirt-3" ++} ++ ++{ ++ "return": { ++ "arch": "x86_64" ++ }, ++ "id": "libvirt-3" ++} ++ ++{ ++ "execute": "query-commands", ++ "id": "libvirt-4" ++} ++ ++{ ++ "return": [ ++ { ++ "name": "netdev_add" ++ }, ++ { ++ "name": "device_add" ++ }, ++ { ++ "name": "query-qmp-schema" ++ }, ++ { ++ "name": "query-cpu-definitions" ++ }, ++ { ++ "name": "query-cpu-model-expansion" ++ }, ++ { ++ "name": "query-sev-capabilities" ++ }, ++ { ++ "name": "query-sev-launch-measure" ++ }, ++ { ++ "name": "query-sev" ++ }, ++ { ++ "name": "rtc-reset-reinjection" ++ }, ++ { ++ "name": "set-numa-node" ++ }, ++ { ++ "name": "query-vm-generation-id" ++ }, ++ { ++ "name": "query-hotpluggable-cpus" ++ }, ++ { ++ "name": "xen-load-devices-state" ++ }, ++ { ++ "name": "query-acpi-ospm-status" ++ }, ++ { ++ "name": "query-memory-devices" ++ }, ++ { ++ "name": "query-memdev" ++ }, ++ { ++ "name": "query-command-line-options" ++ }, ++ { ++ "name": "query-target" ++ }, ++ { ++ "name": "query-fdsets" ++ }, ++ { ++ "name": "remove-fd" ++ }, ++ { ++ "name": "add-fd" ++ }, ++ { ++ "name": "query-memory-size-summary" ++ }, ++ { ++ "name": "query-current-machine" ++ }, ++ { ++ "name": "query-machines" ++ }, ++ { ++ "name": "closefd" ++ }, ++ { ++ "name": "getfd" ++ }, ++ { ++ "name": "object-del" ++ }, ++ { ++ "name": "object-add" ++ }, ++ { ++ "name": "query-dump-guest-memory-capability" ++ }, ++ { ++ "name": "query-dump" ++ }, ++ { ++ "name": "dump-guest-memory" ++ }, ++ { ++ "name": "device_del" ++ }, ++ { ++ "name": "xen-set-global-dirty-log" ++ }, ++ { ++ "name": "qom-list-properties" ++ }, ++ { ++ "name": "device-list-properties" ++ }, ++ { ++ "name": "qom-list-types" ++ }, ++ { ++ "name": "change" ++ }, ++ { ++ "name": "qom-set" ++ }, ++ { ++ "name": "qom-get" ++ }, ++ { ++ "name": "qom-list" ++ }, ++ { ++ "name": "human-monitor-command" ++ }, ++ { ++ "name": "balloon" ++ }, ++ { ++ "name": "inject-nmi" ++ }, ++ { ++ "name": "system_wakeup" ++ }, ++ { ++ "name": "x-exit-preconfig" ++ }, ++ { ++ "name": "cont" ++ }, ++ { ++ "name": "pmemsave" ++ }, ++ { ++ "name": "memsave" ++ }, ++ { ++ "name": "cpu-add" ++ }, ++ { ++ "name": "system_powerdown" ++ }, ++ { ++ "name": "system_reset" ++ }, ++ { ++ "name": "stop" ++ }, ++ { ++ "name": "quit" ++ }, ++ { ++ "name": "query-pci" ++ }, ++ { ++ "name": "query-balloon" ++ }, ++ { ++ "name": "query-iothreads" ++ }, ++ { ++ "name": "query-cpus-fast" ++ }, ++ { ++ "name": "query-cpus" ++ }, ++ { ++ "name": "query-events" ++ }, ++ { ++ "name": "query-uuid" ++ }, ++ { ++ "name": "query-kvm" ++ }, ++ { ++ "name": "query-name" ++ }, ++ { ++ "name": "add_client" ++ }, ++ { ++ "name": "query-commands" ++ }, ++ { ++ "name": "query-version" ++ }, ++ { ++ "name": "qmp_capabilities" ++ }, ++ { ++ "name": "trace-event-set-state" ++ }, ++ { ++ "name": "trace-event-get-state" ++ }, ++ { ++ "name": "transaction" ++ }, ++ { ++ "name": "migrate-pause" ++ }, ++ { ++ "name": "migrate-recover" ++ }, ++ { ++ "name": "query-colo-status" ++ }, ++ { ++ "name": "xen-colo-do-checkpoint" ++ }, ++ { ++ "name": "query-xen-replication-status" ++ }, ++ { ++ "name": "xen-set-replication" ++ }, ++ { ++ "name": "xen-save-devices-state" ++ }, ++ { ++ "name": "migrate-incoming" ++ }, ++ { ++ "name": "migrate" ++ }, ++ { ++ "name": "query-migrate-cache-size" ++ }, ++ { ++ "name": "migrate-set-cache-size" ++ }, ++ { ++ "name": "migrate_set_speed" ++ }, ++ { ++ "name": "migrate_set_downtime" ++ }, ++ { ++ "name": "migrate-continue" ++ }, ++ { ++ "name": "migrate_cancel" ++ }, ++ { ++ "name": "x-colo-lost-heartbeat" ++ }, ++ { ++ "name": "migrate-start-postcopy" ++ }, ++ { ++ "name": "client_migrate_info" ++ }, ++ { ++ "name": "query-migrate-parameters" ++ }, ++ { ++ "name": "migrate-set-parameters" ++ }, ++ { ++ "name": "query-migrate-capabilities" ++ }, ++ { ++ "name": "migrate-set-capabilities" ++ }, ++ { ++ "name": "query-migrate" ++ }, ++ { ++ "name": "query-display-options" ++ }, ++ { ++ "name": "input-send-event" ++ }, ++ { ++ "name": "send-key" ++ }, ++ { ++ "name": "query-mice" ++ }, ++ { ++ "name": "change-vnc-password" ++ }, ++ { ++ "name": "query-vnc-servers" ++ }, ++ { ++ "name": "query-vnc" ++ }, ++ { ++ "name": "query-spice" ++ }, ++ { ++ "name": "screendump" ++ }, ++ { ++ "name": "expire_password" ++ }, ++ { ++ "name": "set_password" ++ }, ++ { ++ "name": "query-tpm" ++ }, ++ { ++ "name": "query-tpm-types" ++ }, ++ { ++ "name": "query-tpm-models" ++ }, ++ { ++ "name": "query-rocker-of-dpa-groups" ++ }, ++ { ++ "name": "query-rocker-of-dpa-flows" ++ }, ++ { ++ "name": "query-rocker-ports" ++ }, ++ { ++ "name": "query-rocker" ++ }, ++ { ++ "name": "announce-self" ++ }, ++ { ++ "name": "query-rx-filter" ++ }, ++ { ++ "name": "netdev_del" ++ }, ++ { ++ "name": "set_link" ++ }, ++ { ++ "name": "chardev-send-break" ++ }, ++ { ++ "name": "chardev-remove" ++ }, ++ { ++ "name": "chardev-change" ++ }, ++ { ++ "name": "chardev-add" ++ }, ++ { ++ "name": "ringbuf-read" ++ }, ++ { ++ "name": "ringbuf-write" ++ }, ++ { ++ "name": "query-chardev-backends" ++ }, ++ { ++ "name": "query-chardev" ++ }, ++ { ++ "name": "nbd-server-stop" ++ }, ++ { ++ "name": "nbd-server-remove" ++ }, ++ { ++ "name": "nbd-server-add" ++ }, ++ { ++ "name": "nbd-server-start" ++ }, ++ { ++ "name": "eject" ++ }, ++ { ++ "name": "blockdev-snapshot-delete-internal-sync" ++ }, ++ { ++ "name": "blockdev-snapshot-internal-sync" ++ }, ++ { ++ "name": "query-pr-managers" ++ }, ++ { ++ "name": "x-blockdev-set-iothread" ++ }, ++ { ++ "name": "x-blockdev-change" ++ }, ++ { ++ "name": "block-set-write-threshold" ++ }, ++ { ++ "name": "blockdev-change-medium" ++ }, ++ { ++ "name": "blockdev-insert-medium" ++ }, ++ { ++ "name": "blockdev-remove-medium" ++ }, ++ { ++ "name": "blockdev-close-tray" ++ }, ++ { ++ "name": "blockdev-open-tray" ++ }, ++ { ++ "name": "blockdev-create" ++ }, ++ { ++ "name": "blockdev-del" ++ }, ++ { ++ "name": "x-blockdev-reopen" ++ }, ++ { ++ "name": "blockdev-add" ++ }, ++ { ++ "name": "block-job-finalize" ++ }, ++ { ++ "name": "block-job-dismiss" ++ }, ++ { ++ "name": "block-job-complete" ++ }, ++ { ++ "name": "block-job-resume" ++ }, ++ { ++ "name": "block-job-pause" ++ }, ++ { ++ "name": "block-job-cancel" ++ }, ++ { ++ "name": "block-job-set-speed" ++ }, ++ { ++ "name": "block-stream" ++ }, ++ { ++ "name": "block_set_io_throttle" ++ }, ++ { ++ "name": "blockdev-mirror" ++ }, ++ { ++ "name": "x-debug-block-dirty-bitmap-sha256" ++ }, ++ { ++ "name": "block-dirty-bitmap-merge" ++ }, ++ { ++ "name": "block-dirty-bitmap-disable" ++ }, ++ { ++ "name": "block-dirty-bitmap-enable" ++ }, ++ { ++ "name": "block-dirty-bitmap-clear" ++ }, ++ { ++ "name": "block-dirty-bitmap-remove" ++ }, ++ { ++ "name": "block-dirty-bitmap-add" ++ }, ++ { ++ "name": "drive-mirror" ++ }, ++ { ++ "name": "x-debug-query-block-graph" ++ }, ++ { ++ "name": "query-named-block-nodes" ++ }, ++ { ++ "name": "blockdev-backup" ++ }, ++ { ++ "name": "drive-backup" ++ }, ++ { ++ "name": "block-commit" ++ }, ++ { ++ "name": "change-backing-file" ++ }, ++ { ++ "name": "blockdev-snapshot" ++ }, ++ { ++ "name": "blockdev-snapshot-sync" ++ }, ++ { ++ "name": "block_resize" ++ }, ++ { ++ "name": "block_passwd" ++ }, ++ { ++ "name": "query-block-jobs" ++ }, ++ { ++ "name": "query-blockstats" ++ }, ++ { ++ "name": "query-block" ++ }, ++ { ++ "name": "block-latency-histogram-set" ++ }, ++ { ++ "name": "query-jobs" ++ }, ++ { ++ "name": "job-finalize" ++ }, ++ { ++ "name": "job-dismiss" ++ }, ++ { ++ "name": "job-complete" ++ }, ++ { ++ "name": "job-cancel" ++ }, ++ { ++ "name": "job-resume" ++ }, ++ { ++ "name": "job-pause" ++ }, ++ { ++ "name": "watchdog-set-action" ++ }, ++ { ++ "name": "query-status" ++ } ++ ], ++ "id": "libvirt-4" ++} ++ ++{ ++ "execute": "add-fd", ++ "arguments": { ++ "fdset-id": 0, ++ "opaque": "/dev/null" ++ }, ++ "id": "libvirt-5" ++} ++ ++{ ++ "return": { ++ "fd": 18, ++ "fdset-id": 0 ++ }, ++ "id": "libvirt-5" ++} ++ ++{ ++ "execute": "block-commit", ++ "arguments": { ++ "device": "bogus" ++ }, ++ "id": "libvirt-6" ++} ++ ++{ ++ "id": "libvirt-6", ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "Device 'bogus' not found" ++ } ++} ++ ++{ ++ "execute": "query-kvm", ++ "id": "libvirt-7" ++} ++ ++{ ++ "return": { ++ "enabled": true, ++ "present": true ++ }, ++ "id": "libvirt-7" ++} ++ ++{ ++ "execute": "query-events", ++ "id": "libvirt-8" ++} ++ ++{ ++ "return": [ ++ { ++ "name": "RTC_CHANGE" ++ }, ++ { ++ "name": "ACPI_DEVICE_OST" ++ }, ++ { ++ "name": "MEM_UNPLUG_ERROR" ++ }, ++ { ++ "name": "DUMP_COMPLETED" ++ }, ++ { ++ "name": "DEVICE_DELETED" ++ }, ++ { ++ "name": "BALLOON_CHANGE" ++ }, ++ { ++ "name": "COLO_EXIT" ++ }, ++ { ++ "name": "MIGRATION_PASS" ++ }, ++ { ++ "name": "MIGRATION" ++ }, ++ { ++ "name": "VNC_DISCONNECTED" ++ }, ++ { ++ "name": "VNC_INITIALIZED" ++ }, ++ { ++ "name": "VNC_CONNECTED" ++ }, ++ { ++ "name": "SPICE_MIGRATE_COMPLETED" ++ }, ++ { ++ "name": "SPICE_DISCONNECTED" ++ }, ++ { ++ "name": "SPICE_INITIALIZED" ++ }, ++ { ++ "name": "SPICE_CONNECTED" ++ }, ++ { ++ "name": "RDMA_GID_STATUS_CHANGED" ++ }, ++ { ++ "name": "NIC_RX_FILTER_CHANGED" ++ }, ++ { ++ "name": "VSERPORT_CHANGE" ++ }, ++ { ++ "name": "QUORUM_REPORT_BAD" ++ }, ++ { ++ "name": "QUORUM_FAILURE" ++ }, ++ { ++ "name": "PR_MANAGER_STATUS_CHANGED" ++ }, ++ { ++ "name": "DEVICE_TRAY_MOVED" ++ }, ++ { ++ "name": "BLOCK_WRITE_THRESHOLD" ++ }, ++ { ++ "name": "BLOCK_JOB_PENDING" ++ }, ++ { ++ "name": "BLOCK_JOB_READY" ++ }, ++ { ++ "name": "BLOCK_JOB_ERROR" ++ }, ++ { ++ "name": "BLOCK_JOB_CANCELLED" ++ }, ++ { ++ "name": "BLOCK_JOB_COMPLETED" ++ }, ++ { ++ "name": "BLOCK_IO_ERROR" ++ }, ++ { ++ "name": "BLOCK_IMAGE_CORRUPTED" ++ }, ++ { ++ "name": "JOB_STATUS_CHANGE" ++ }, ++ { ++ "name": "GUEST_PANICKED" ++ }, ++ { ++ "name": "WATCHDOG" ++ }, ++ { ++ "name": "WAKEUP" ++ }, ++ { ++ "name": "SUSPEND_DISK" ++ }, ++ { ++ "name": "SUSPEND" ++ }, ++ { ++ "name": "RESUME" ++ }, ++ { ++ "name": "STOP" ++ }, ++ { ++ "name": "RESET" ++ }, ++ { ++ "name": "POWERDOWN" ++ }, ++ { ++ "name": "SHUTDOWN" ++ } ++ ], ++ "id": "libvirt-8" ++} ++ ++{ ++ "execute": "qom-list-types", ++ "id": "libvirt-9" ++} ++ ++{ ++ "return": [ ++ { ++ "name": "vhost-vsock-pci", ++ "parent": "vhost-vsock-pci-base" ++ }, ++ { ++ "name": "scsi-generic", ++ "parent": "scsi-device" ++ }, ++ { ++ "name": "qio-channel-tls", ++ "parent": "qio-channel" ++ }, ++ { ++ "name": "scsi-hd", ++ "parent": "scsi-disk-base" ++ }, ++ { ++ "name": "usb-bot", ++ "parent": "usb-storage-dev" ++ }, ++ { ++ "name": "chardev-null", ++ "parent": "chardev" ++ }, ++ { ++ "name": "chardev-parallel", ++ "parent": "chardev" ++ }, ++ { ++ "name": "qemu-xhci", ++ "parent": "base-xhci" ++ }, ++ { ++ "name": "lsi53c895a", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "kvm-ioapic", ++ "parent": "ioapic-common" ++ }, ++ { ++ "name": "cpu-cluster", ++ "parent": "device" ++ }, ++ { ++ "name": "virtio-keyboard-pci", ++ "parent": "virtio-input-hid-pci" ++ }, ++ { ++ "name": "xen-sysbus", ++ "parent": "bus" ++ }, ++ { ++ "name": "xen-bus", ++ "parent": "bus" ++ }, ++ { ++ "name": "i440FX", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "ide-hd", ++ "parent": "ide-device" ++ }, ++ { ++ "name": "Opteron_G1-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "kvm64-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "vhost-scsi-pci-non-transitional", ++ "parent": "vhost-scsi-pci-base" ++ }, ++ { ++ "name": "virtio-net-device", ++ "parent": "virtio-device" ++ }, ++ { ++ "name": "kvm-i8259", ++ "parent": "pic-common" ++ }, ++ { ++ "name": "virtio-9p-pci-non-transitional", ++ "parent": "virtio-9p-pci-base" ++ }, ++ { ++ "name": "chardev-pty", ++ "parent": "chardev" ++ }, ++ { ++ "name": "xen-apic", ++ "parent": "apic-common" ++ }, ++ { ++ "name": "SUNW,fdtwo", ++ "parent": "base-sysbus-fdc" ++ }, ++ { ++ "name": "isa-pcspk", ++ "parent": "isa-device" ++ }, ++ { ++ "name": "Haswell-IBRS-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "pc-q35-4.1-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "loader", ++ "parent": "device" ++ }, ++ { ++ "name": "filter-rewriter", ++ "parent": "netfilter" ++ }, ++ { ++ "name": "pc-q35-4.0-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "virtio-serial-pci", ++ "parent": "virtio-serial-pci-base" ++ }, ++ { ++ "name": "Nehalem-IBRS-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "pc-0.12-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "pcie-root-port", ++ "parent": "pcie-root-port-base" ++ }, ++ { ++ "name": "virtio-crypto-device", ++ "parent": "virtio-device" ++ }, ++ { ++ "name": "usb-host", ++ "parent": "usb-device" ++ }, ++ { ++ "name": "Icelake-Client-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "usb-bt-dongle", ++ "parent": "usb-device" ++ }, ++ { ++ "name": "igd-passthrough-isa-bridge", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "usb-mtp", ++ "parent": "usb-device" ++ }, ++ { ++ "name": "qemu64-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "virtio-input-host-pci", ++ "parent": "virtio-input-pci" ++ }, ++ { ++ "name": "pc-i440fx-2.10-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "phenom-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "e1000", ++ "parent": "e1000-base" ++ }, ++ { ++ "name": "PIIX3-xen", ++ "parent": "pci-piix3" ++ }, ++ { ++ "name": "sysbus-ahci", ++ "parent": "sys-bus-device" ++ }, ++ { ++ "name": "ccid-card-emulated", ++ "parent": "ccid-card" ++ }, ++ { ++ "name": "ich9-usb-uhci5", ++ "parent": "pci-uhci-usb" ++ }, ++ { ++ "name": "pc-i440fx-1.4-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "ICH9-LPC", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "pc-q35-2.6-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "ich9-usb-uhci6", ++ "parent": "pci-uhci-usb" ++ }, ++ { ++ "name": "ich9-usb-uhci4", ++ "parent": "pci-uhci-usb" ++ }, ++ { ++ "name": "chardev-spicevmc", ++ "parent": "chardev-spice" ++ }, ++ { ++ "name": "ich9-usb-uhci3", ++ "parent": "pci-uhci-usb" ++ }, ++ { ++ "name": "ich9-usb-uhci2", ++ "parent": "pci-uhci-usb" ++ }, ++ { ++ "name": "ich9-usb-uhci1", ++ "parent": "pci-uhci-usb" ++ }, ++ { ++ "name": "tls-creds-psk", ++ "parent": "tls-creds" ++ }, ++ { ++ "name": "tpci200", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "memory-backend-file", ++ "parent": "memory-backend" ++ }, ++ { ++ "name": "pc-q35-2.5-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "AMDVI-PCI", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "filter-redirector", ++ "parent": "netfilter" ++ }, ++ { ++ "name": "rtl8139", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "chardev-hci", ++ "parent": "chardev" ++ }, ++ { ++ "name": "pc-q35-2.4-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "container", ++ "parent": "object" ++ }, ++ { ++ "name": "pc-i440fx-3.1-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "megasas", ++ "parent": "megasas-base" ++ }, ++ { ++ "name": "base-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "virtio-balloon-pci-non-transitional", ++ "parent": "virtio-balloon-pci-base" ++ }, ++ { ++ "name": "qxl-vga", ++ "parent": "pci-qxl" ++ }, ++ { ++ "name": "scsi-block", ++ "parent": "scsi-disk-base" ++ }, ++ { ++ "name": "Opteron_G2-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "unimplemented-device", ++ "parent": "sys-bus-device" ++ }, ++ { ++ "name": "vhost-user-input", ++ "parent": "virtio-input-device" ++ }, ++ { ++ "name": "tls-creds-anon", ++ "parent": "tls-creds" ++ }, ++ { ++ "name": "pc-i440fx-3.0-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "scsi-cd", ++ "parent": "scsi-disk-base" ++ }, ++ { ++ "name": "pxb-bus", ++ "parent": "PCI" ++ }, ++ { ++ "name": "pc-0.14-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "accel", ++ "parent": "object" ++ }, ++ { ++ "name": "floppy-bus", ++ "parent": "bus" ++ }, ++ { ++ "name": "usb-audio", ++ "parent": "usb-device" ++ }, ++ { ++ "name": "virtio-vga", ++ "parent": "virtio-vga-base" ++ }, ++ { ++ "name": "pc-i440fx-2.12-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "vmware-svga", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "pc-0.13-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "isa-serial", ++ "parent": "isa-device" ++ }, ++ { ++ "name": "virtio-serial-device", ++ "parent": "virtio-device" ++ }, ++ { ++ "name": "isa-debug-exit", ++ "parent": "isa-device" ++ }, ++ { ++ "name": "vhost-scsi-pci", ++ "parent": "vhost-scsi-pci-base" ++ }, ++ { ++ "name": "chardev-gdb", ++ "parent": "chardev" ++ }, ++ { ++ "name": "fdc37m81x-superio", ++ "parent": "isa-superio" ++ }, ++ { ++ "name": "pc-testdev", ++ "parent": "isa-device" ++ }, ++ { ++ "name": "xen-backend", ++ "parent": "xen-sysdev" ++ }, ++ { ++ "name": "Haswell-noTSX-IBRS-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "pr-manager-helper", ++ "parent": "pr-manager" ++ }, ++ { ++ "name": "fw_cfg_mem", ++ "parent": "fw_cfg" ++ }, ++ { ++ "name": "virtio-scsi-pci-transitional", ++ "parent": "virtio-scsi-pci-base" ++ }, ++ { ++ "name": "usb-uas", ++ "parent": "usb-device" ++ }, ++ { ++ "name": "ide-cd", ++ "parent": "ide-device" ++ }, ++ { ++ "name": "pc-q35-2.8-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "pc-i440fx-2.11-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "pc-i440fx-1.6-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "virtio-balloon-pci", ++ "parent": "virtio-balloon-pci-base" ++ }, ++ { ++ "name": "chardev-socket", ++ "parent": "chardev" ++ }, ++ { ++ "name": "iothread", ++ "parent": "object" ++ }, ++ { ++ "name": "sb16", ++ "parent": "isa-device" ++ }, ++ { ++ "name": "chardev-mux", ++ "parent": "chardev" ++ }, ++ { ++ "name": "pc-q35-2.7-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "pc-i440fx-1.5-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "486-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "bochs-display", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "usb-ccid", ++ "parent": "usb-device" ++ }, ++ { ++ "name": "isa-cirrus-vga", ++ "parent": "isa-device" ++ }, ++ { ++ "name": "qio-channel-rdma", ++ "parent": "qio-channel" ++ }, ++ { ++ "name": "vhost-vsock-device", ++ "parent": "virtio-device" ++ }, ++ { ++ "name": "sdhci-pci", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "virtio-input-host-device", ++ "parent": "virtio-input-device" ++ }, ++ { ++ "name": "i82559er", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "pci-bridge", ++ "parent": "base-pci-bridge" ++ }, ++ { ++ "name": "cs4231a", ++ "parent": "isa-device" ++ }, ++ { ++ "name": "ivshmem-doorbell", ++ "parent": "ivshmem-common" ++ }, ++ { ++ "name": "chardev-udp", ++ "parent": "chardev" ++ }, ++ { ++ "name": "virtio-rng-device", ++ "parent": "virtio-device" ++ }, ++ { ++ "name": "isa-parallel", ++ "parent": "isa-device" ++ }, ++ { ++ "name": "piix4-ide", ++ "parent": "pci-ide" ++ }, ++ { ++ "name": "adlib", ++ "parent": "isa-device" ++ }, ++ { ++ "name": "pc-0.15-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "authz-list-file", ++ "parent": "authz" ++ }, ++ { ++ "name": "kvmvapic", ++ "parent": "sys-bus-device" ++ }, ++ { ++ "name": "hda-micro", ++ "parent": "hda-audio" ++ }, ++ { ++ "name": "pci-bridge-seat", ++ "parent": "pci-bridge" ++ }, ++ { ++ "name": "dc390", ++ "parent": "am53c974" ++ }, ++ { ++ "name": "chardev-pipe", ++ "parent": "chardev-fd" ++ }, ++ { ++ "name": "qemu,register", ++ "parent": "device" ++ }, ++ { ++ "name": "IDE", ++ "parent": "bus" ++ }, ++ { ++ "name": "fw_cfg_io", ++ "parent": "fw_cfg" ++ }, ++ { ++ "name": "tpm-crb", ++ "parent": "device" ++ }, ++ { ++ "name": "am53c974", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "memory-backend-ram", ++ "parent": "memory-backend" ++ }, ++ { ++ "name": "xen-cdrom", ++ "parent": "xen-block" ++ }, ++ { ++ "name": "virtio-blk-device", ++ "parent": "virtio-device" ++ }, ++ { ++ "name": "pc-q35-2.9-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "nvdimm", ++ "parent": "pc-dimm" ++ }, ++ { ++ "name": "mc146818rtc", ++ "parent": "isa-device" ++ }, ++ { ++ "name": "qio-channel-websock", ++ "parent": "qio-channel" ++ }, ++ { ++ "name": "qio-channel-file", ++ "parent": "qio-channel" ++ }, ++ { ++ "name": "chardev-msmouse", ++ "parent": "chardev" ++ }, ++ { ++ "name": "pc-i440fx-1.7-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "pc-q35-4.0.1-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "cryptodev-backend-builtin", ++ "parent": "cryptodev-backend" ++ }, ++ { ++ "name": "hda-output", ++ "parent": "hda-audio" ++ }, ++ { ++ "name": "KnightsMill-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "chardev-spiceport", ++ "parent": "chardev-spice" ++ }, ++ { ++ "name": "VGA", ++ "parent": "pci-vga" ++ }, ++ { ++ "name": "vfio-pci-nohotplug", ++ "parent": "vfio-pci" ++ }, ++ { ++ "name": "sga", ++ "parent": "isa-device" ++ }, ++ { ++ "name": "i8257", ++ "parent": "isa-device" ++ }, ++ { ++ "name": "qio-net-listener", ++ "parent": "object" ++ }, ++ { ++ "name": "port92", ++ "parent": "isa-device" ++ }, ++ { ++ "name": "mptsas1068", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "edu", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "Dhyana-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "virtio-mouse-pci", ++ "parent": "virtio-input-hid-pci" ++ }, ++ { ++ "name": "Skylake-Client-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "ICH9 SMB", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "Broadwell-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "vfio-pci-igd-lpc-bridge", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "HDA", ++ "parent": "bus" ++ }, ++ { ++ "name": "n270-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "usb-redir", ++ "parent": "usb-device" ++ }, ++ { ++ "name": "pcm3680_pci", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "floppy", ++ "parent": "device" ++ }, ++ { ++ "name": "qemu:memory-region", ++ "parent": "object" ++ }, ++ { ++ "name": "mioe3680_pci", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "sysbus-ohci", ++ "parent": "sys-bus-device" ++ }, ++ { ++ "name": "chardev-ringbuf", ++ "parent": "chardev" ++ }, ++ { ++ "name": "max-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "can-bus", ++ "parent": "object" ++ }, ++ { ++ "name": "qtest-accel", ++ "parent": "accel" ++ }, ++ { ++ "name": "qio-channel-command", ++ "parent": "qio-channel" ++ }, ++ { ++ "name": "pxb-host", ++ "parent": "pci-host-bridge" ++ }, ++ { ++ "name": "IvyBridge-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "vhost-user-gpu", ++ "parent": "virtio-gpu-base" ++ }, ++ { ++ "name": "xio3130-downstream", ++ "parent": "pcie-slot" ++ }, ++ { ++ "name": "virtio-gpu-device", ++ "parent": "virtio-gpu-base" ++ }, ++ { ++ "name": "virtio-blk-pci", ++ "parent": "virtio-blk-pci-base" ++ }, ++ { ++ "name": "cirrus-vga", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "isa-ipmi-kcs", ++ "parent": "isa-device" ++ }, ++ { ++ "name": "kvmclock", ++ "parent": "sys-bus-device" ++ }, ++ { ++ "name": "cryptodev-vhost-user", ++ "parent": "cryptodev-backend" ++ }, ++ { ++ "name": "Opteron_G3-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "lsi53c810", ++ "parent": "lsi53c895a" ++ }, ++ { ++ "name": "System", ++ "parent": "bus" ++ }, ++ { ++ "name": "Westmere-IBRS-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "usb-serial", ++ "parent": "usb-serial-dev" ++ }, ++ { ++ "name": "Cascadelake-Server-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "vt82c686b-usb-uhci", ++ "parent": "pci-uhci-usb" ++ }, ++ { ++ "name": "chardev-braille", ++ "parent": "chardev" ++ }, ++ { ++ "name": "chardev-file", ++ "parent": "chardev-fd" ++ }, ++ { ++ "name": "vhost-user-scsi-pci-non-transitional", ++ "parent": "vhost-user-scsi-pci-base" ++ }, ++ { ++ "name": "xen-sysdev", ++ "parent": "sys-bus-device" ++ }, ++ { ++ "name": "intel-iommu", ++ "parent": "x86-iommu" ++ }, ++ { ++ "name": "pc-q35-2.10-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "tpm-tis", ++ "parent": "isa-device" ++ }, ++ { ++ "name": "PCIE", ++ "parent": "PCI" ++ }, ++ { ++ "name": "pcie-pci-bridge", ++ "parent": "base-pci-bridge" ++ }, ++ { ++ "name": "ccid-card-passthru", ++ "parent": "ccid-card" ++ }, ++ { ++ "name": "qio-dns-resolver", ++ "parent": "object" ++ }, ++ { ++ "name": "vhost-user-blk-pci", ++ "parent": "vhost-user-blk-pci-base" ++ }, ++ { ++ "name": "virtio-net-pci-transitional", ++ "parent": "virtio-net-pci-base" ++ }, ++ { ++ "name": "virtio-serial-bus", ++ "parent": "bus" ++ }, ++ { ++ "name": "kvm-pit", ++ "parent": "pit-common" ++ }, ++ { ++ "name": "secondary-vga", ++ "parent": "pci-vga" ++ }, ++ { ++ "name": "vhost-scsi", ++ "parent": "vhost-scsi-common" ++ }, ++ { ++ "name": "pci-ohci", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "cfi.pflash01", ++ "parent": "sys-bus-device" ++ }, ++ { ++ "name": "usb-hub", ++ "parent": "usb-device" ++ }, ++ { ++ "name": "ccid-bus", ++ "parent": "bus" ++ }, ++ { ++ "name": "xenpv-machine", ++ "parent": "machine" ++ }, ++ { ++ "name": "EPYC-IBPB-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "input-linux", ++ "parent": "object" ++ }, ++ { ++ "name": "piix3-ide-xen", ++ "parent": "pci-ide" ++ }, ++ { ++ "name": "vmgenid", ++ "parent": "device" ++ }, ++ { ++ "name": "virtio-rng-pci-transitional", ++ "parent": "virtio-rng-pci-base" ++ }, ++ { ++ "name": "virtio-serial-pci-transitional", ++ "parent": "virtio-serial-pci-base" ++ }, ++ { ++ "name": "ati-vga", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "pc-q35-3.0-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "pci-serial", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "vmport", ++ "parent": "isa-device" ++ }, ++ { ++ "name": "vhost-user-scsi-pci", ++ "parent": "vhost-user-scsi-pci-base" ++ }, ++ { ++ "name": "ipmi-bmc-extern", ++ "parent": "ipmi-bmc" ++ }, ++ { ++ "name": "PIIX4_PM", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "i8042", ++ "parent": "isa-device" ++ }, ++ { ++ "name": "coreduo-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "i82559c", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "i82559b", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "i82559a", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "virtio-blk-pci-non-transitional", ++ "parent": "virtio-blk-pci-base" ++ }, ++ { ++ "name": "pc-q35-2.12-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "SCSI", ++ "parent": "bus" ++ }, ++ { ++ "name": "rocker", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "pcnet", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "rng-egd", ++ "parent": "rng-backend" ++ }, ++ { ++ "name": "Skylake-Server-IBRS-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "Opteron_G4-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "pc-q35-2.11-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "chardev-testdev", ++ "parent": "chardev" ++ }, ++ { ++ "name": "PIIX3", ++ "parent": "pci-piix3" ++ }, ++ { ++ "name": "filter-dump", ++ "parent": "netfilter" ++ }, ++ { ++ "name": "migration", ++ "parent": "device" ++ }, ++ { ++ "name": "vmmouse", ++ "parent": "isa-device" ++ }, ++ { ++ "name": "i82558b", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "i82558a", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "ioapic", ++ "parent": "ioapic-common" ++ }, ++ { ++ "name": "smbus-eeprom", ++ "parent": "smbus-device" ++ }, ++ { ++ "name": "Haswell-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "i82801", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "tls-creds-x509", ++ "parent": "tls-creds" ++ }, ++ { ++ "name": "virtio-net-pci", ++ "parent": "virtio-net-pci-base" ++ }, ++ { ++ "name": "virtio-keyboard-device", ++ "parent": "virtio-input-hid-device" ++ }, ++ { ++ "name": "i82562", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "Haswell-noTSX-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "usb-net", ++ "parent": "usb-device" ++ }, ++ { ++ "name": "tpm-passthrough", ++ "parent": "tpm-backend" ++ }, ++ { ++ "name": "q35-pcihost", ++ "parent": "pcie-host-bridge" ++ }, ++ { ++ "name": "amd-iommu", ++ "parent": "x86-iommu" ++ }, ++ { ++ "name": "i440FX-pcihost", ++ "parent": "pci-host-bridge" ++ }, ++ { ++ "name": "i82557c", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "i82557b", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "i82557a", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "chardev-memory", ++ "parent": "chardev-ringbuf" ++ }, ++ { ++ "name": "isa-i8259", ++ "parent": "pic-common" ++ }, ++ { ++ "name": "virtio-gpu-pci", ++ "parent": "virtio-gpu-pci-base" ++ }, ++ { ++ "name": "pc-i440fx-2.0-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "SandyBridge-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "split-irq", ++ "parent": "device" ++ }, ++ { ++ "name": "usb-mouse", ++ "parent": "usb-hid" ++ }, ++ { ++ "name": "i82551", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "sdhci-bus", ++ "parent": "sd-bus" ++ }, ++ { ++ "name": "i82550", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "pc-q35-3.1-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "host-x86_64-cpu", ++ "parent": "max-x86_64-cpu" ++ }, ++ { ++ "name": "virtio-crypto-pci", ++ "parent": "virtio-pci" ++ }, ++ { ++ "name": "ich9-usb-ehci2", ++ "parent": "pci-ehci-usb" ++ }, ++ { ++ "name": "vfio-pci", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "ich9-usb-ehci1", ++ "parent": "pci-ehci-usb" ++ }, ++ { ++ "name": "filter-mirror", ++ "parent": "netfilter" ++ }, ++ { ++ "name": "xen-disk", ++ "parent": "xen-block" ++ }, ++ { ++ "name": "isa-ide", ++ "parent": "isa-device" ++ }, ++ { ++ "name": "irq", ++ "parent": "object" ++ }, ++ { ++ "name": "throttle-group", ++ "parent": "object" ++ }, ++ { ++ "name": "IvyBridge-IBRS-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "memory-backend-memfd", ++ "parent": "memory-backend" ++ }, ++ { ++ "name": "can-host-socketcan", ++ "parent": "can-host" ++ }, ++ { ++ "name": "qio-channel-socket", ++ "parent": "qio-channel" ++ }, ++ { ++ "name": "nec-usb-xhci", ++ "parent": "base-xhci" ++ }, ++ { ++ "name": "virtio-serial-pci-non-transitional", ++ "parent": "virtio-serial-pci-base" ++ }, ++ { ++ "name": "virtio-rng-pci-non-transitional", ++ "parent": "virtio-rng-pci-base" ++ }, ++ { ++ "name": "piix3-usb-uhci", ++ "parent": "pci-uhci-usb" ++ }, ++ { ++ "name": "virtserialport", ++ "parent": "virtio-serial-port" ++ }, ++ { ++ "name": "pvscsi", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "sd-bus", ++ "parent": "bus" ++ }, ++ { ++ "name": "Opteron_G5-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "ich9-ahci", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "chardev-stdio", ++ "parent": "chardev-fd" ++ }, ++ { ++ "name": "Skylake-Client-IBRS-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "pc-dimm", ++ "parent": "device" ++ }, ++ { ++ "name": "gus", ++ "parent": "isa-device" ++ }, ++ { ++ "name": "vhost-vsock-pci-non-transitional", ++ "parent": "vhost-vsock-pci-base" ++ }, ++ { ++ "name": "hyperv-testdev", ++ "parent": "isa-device" ++ }, ++ { ++ "name": "isa-vga", ++ "parent": "isa-device" ++ }, ++ { ++ "name": "pc-i440fx-2.2-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "xen-pci-passthrough", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "cryptodev-backend", ++ "parent": "object" ++ }, ++ { ++ "name": "IndustryPack", ++ "parent": "bus" ++ }, ++ { ++ "name": "pc-i440fx-2.1-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "pc-i440fx-4.0-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "Icelake-Server-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "or-irq", ++ "parent": "device" ++ }, ++ { ++ "name": "ipmi-bmc-sim", ++ "parent": "ipmi-bmc" ++ }, ++ { ++ "name": "Broadwell-noTSX-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "usb-ehci", ++ "parent": "pci-ehci-usb" ++ }, ++ { ++ "name": "pentium2-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "chardev-vc", ++ "parent": "chardev" ++ }, ++ { ++ "name": "virtio-rng-pci", ++ "parent": "virtio-rng-pci-base" ++ }, ++ { ++ "name": "filter-replay", ++ "parent": "netfilter" ++ }, ++ { ++ "name": "vhost-user-vga", ++ "parent": "virtio-vga-base" ++ }, ++ { ++ "name": "vhost-user-blk-pci-transitional", ++ "parent": "vhost-user-blk-pci-base" ++ }, ++ { ++ "name": "e1000-82545em", ++ "parent": "e1000-base" ++ }, ++ { ++ "name": "chardev-wctablet", ++ "parent": "chardev" ++ }, ++ { ++ "name": "vhost-user-gpu-pci", ++ "parent": "virtio-gpu-pci-base" ++ }, ++ { ++ "name": "hyperv-synic", ++ "parent": "device" ++ }, ++ { ++ "name": "pc-i440fx-2.5-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "e1000-82544gc", ++ "parent": "e1000-base" ++ }, ++ { ++ "name": "hpet", ++ "parent": "sys-bus-device" ++ }, ++ { ++ "name": "Broadwell-noTSX-IBRS-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "ioh3420", ++ "parent": "pcie-root-port-base" ++ }, ++ { ++ "name": "pc-i440fx-2.4-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "virtio-9p-pci", ++ "parent": "virtio-9p-pci-base" ++ }, ++ { ++ "name": "vmcoreinfo", ++ "parent": "device" ++ }, ++ { ++ "name": "filter-buffer", ++ "parent": "netfilter" ++ }, ++ { ++ "name": "pci-serial-4x", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "athlon-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "ich9-intel-hda", ++ "parent": "intel-hda-generic" ++ }, ++ { ++ "name": "pc-i440fx-2.3-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "virtio-9p-device", ++ "parent": "virtio-device" ++ }, ++ { ++ "name": "imx-usdhc", ++ "parent": "generic-sdhci" ++ }, ++ { ++ "name": "pc-i440fx-4.1-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "vhost-user-blk-pci-non-transitional", ++ "parent": "vhost-user-blk-pci-base" ++ }, ++ { ++ "name": "xen-bridge", ++ "parent": "sys-bus-device" ++ }, ++ { ++ "name": "vhost-user-backend", ++ "parent": "object" ++ }, ++ { ++ "name": "isa-ipmi-bt", ++ "parent": "isa-device" ++ }, ++ { ++ "name": "ipoctal232", ++ "parent": "ipack-device" ++ }, ++ { ++ "name": "virtio-tablet-device", ++ "parent": "virtio-input-hid-device" ++ }, ++ { ++ "name": "virtio-scsi-pci", ++ "parent": "virtio-scsi-pci-base" ++ }, ++ { ++ "name": "piix3-ide", ++ "parent": "pci-ide" ++ }, ++ { ++ "name": "virtio-pci-bus", ++ "parent": "virtio-bus" ++ }, ++ { ++ "name": "xen-pvdevice", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "ES1370", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "x3130-upstream", ++ "parent": "pcie-port" ++ }, ++ { ++ "name": "xenfv-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "pci-testdev", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "qemu-console", ++ "parent": "object" ++ }, ++ { ++ "name": "ISA", ++ "parent": "bus" ++ }, ++ { ++ "name": "piix4-usb-uhci", ++ "parent": "pci-uhci-usb" ++ }, ++ { ++ "name": "virtio-balloon-pci-transitional", ++ "parent": "virtio-balloon-pci-base" ++ }, ++ { ++ "name": "pc-i440fx-2.7-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "tcg-accel", ++ "parent": "accel" ++ }, ++ { ++ "name": "virtconsole", ++ "parent": "virtserialport" ++ }, ++ { ++ "name": "pci-serial-2x", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "pentium3-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "vhost-user-scsi-pci-transitional", ++ "parent": "vhost-user-scsi-pci-base" ++ }, ++ { ++ "name": "ne2k_isa", ++ "parent": "isa-device" ++ }, ++ { ++ "name": "isa-fdc", ++ "parent": "isa-device" ++ }, ++ { ++ "name": "Nehalem-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "pc-i440fx-2.6-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "xen-platform", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "chardev-serial", ++ "parent": "chardev-fd" ++ }, ++ { ++ "name": "authz-pam", ++ "parent": "authz" ++ }, ++ { ++ "name": "igd-passthrough-i440FX", ++ "parent": "i440FX" ++ }, ++ { ++ "name": "colo-compare", ++ "parent": "object" ++ }, ++ { ++ "name": "virtio-tablet-pci", ++ "parent": "virtio-input-hid-pci" ++ }, ++ { ++ "name": "e1000e", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "usb-bus", ++ "parent": "bus" ++ }, ++ { ++ "name": "i82801b11-bridge", ++ "parent": "base-pci-bridge" ++ }, ++ { ++ "name": "PCI", ++ "parent": "bus" ++ }, ++ { ++ "name": "usb-storage", ++ "parent": "usb-storage-dev" ++ }, ++ { ++ "name": "vhost-user-scsi", ++ "parent": "vhost-scsi-common" ++ }, ++ { ++ "name": "mch", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "ib700", ++ "parent": "isa-device" ++ }, ++ { ++ "name": "tpm-emulator", ++ "parent": "tpm-backend" ++ }, ++ { ++ "name": "esp", ++ "parent": "sys-bus-device" ++ }, ++ { ++ "name": "isabus-bridge", ++ "parent": "sys-bus-device" ++ }, ++ { ++ "name": "qemu32-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "ne2k_pci", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "Broadwell-IBRS-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "vhost-user-blk", ++ "parent": "virtio-device" ++ }, ++ { ++ "name": "ivshmem-plain", ++ "parent": "ivshmem-common" ++ }, ++ { ++ "name": "usb-kbd", ++ "parent": "usb-hid" ++ }, ++ { ++ "name": "isa-applesmc", ++ "parent": "isa-device" ++ }, ++ { ++ "name": "xen-accel", ++ "parent": "accel" ++ }, ++ { ++ "name": "secret", ++ "parent": "object" ++ }, ++ { ++ "name": "hda-duplex", ++ "parent": "hda-audio" ++ }, ++ { ++ "name": "authz-simple", ++ "parent": "authz" ++ }, ++ { ++ "name": "kvm32-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "virtio-9p-pci-transitional", ++ "parent": "virtio-9p-pci-base" ++ }, ++ { ++ "name": "pc-i440fx-2.9-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "kvm-apic", ++ "parent": "apic-common" ++ }, ++ { ++ "name": "sev-guest", ++ "parent": "object" ++ }, ++ { ++ "name": "virtio-balloon-device", ++ "parent": "virtio-device" ++ }, ++ { ++ "name": "none-machine", ++ "parent": "machine" ++ }, ++ { ++ "name": "sysbus-fdc", ++ "parent": "base-sysbus-fdc" ++ }, ++ { ++ "name": "ramfb", ++ "parent": "sys-bus-device" ++ }, ++ { ++ "name": "megasas-gen2", ++ "parent": "megasas-base" ++ }, ++ { ++ "name": "usb-tablet", ++ "parent": "usb-hid" ++ }, ++ { ++ "name": "pc-1.0-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "vhost-scsi-pci-transitional", ++ "parent": "vhost-scsi-pci-base" ++ }, ++ { ++ "name": "core2duo-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "qxl", ++ "parent": "pci-qxl" ++ }, ++ { ++ "name": "isa-debugcon", ++ "parent": "isa-device" ++ }, ++ { ++ "name": "pc-i440fx-2.8-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "nvme", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "SandyBridge-IBRS-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "Skylake-Server-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "pentium-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "vhost-user-input-pci", ++ "parent": "virtio-input-pci" ++ }, ++ { ++ "name": "usb-braille", ++ "parent": "usb-serial-dev" ++ }, ++ { ++ "name": "qio-channel-buffer", ++ "parent": "qio-channel" ++ }, ++ { ++ "name": "scsi-disk", ++ "parent": "scsi-disk-base" ++ }, ++ { ++ "name": "intel-hda", ++ "parent": "intel-hda-generic" ++ }, ++ { ++ "name": "kvm-accel", ++ "parent": "accel" ++ }, ++ { ++ "name": "pxb-pcie-bus", ++ "parent": "PCIE" ++ }, ++ { ++ "name": "virtio-scsi-device", ++ "parent": "virtio-scsi-common" ++ }, ++ { ++ "name": "AC97", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "usb-wacom-tablet", ++ "parent": "usb-device" ++ }, ++ { ++ "name": "virtio-blk-pci-transitional", ++ "parent": "virtio-blk-pci-base" ++ }, ++ { ++ "name": "i2c-bus", ++ "parent": "bus" ++ }, ++ { ++ "name": "EPYC-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "virtio-mouse-device", ++ "parent": "virtio-input-hid-device" ++ }, ++ { ++ "name": "Conroe-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "pxb-pcie", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "pc-1.3-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "authz-list", ++ "parent": "authz" ++ }, ++ { ++ "name": "ide-drive", ++ "parent": "ide-device" ++ }, ++ { ++ "name": "generic-sdhci", ++ "parent": "sys-bus-device" ++ }, ++ { ++ "name": "pvrdma", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "pc-1.2-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "isa-pit", ++ "parent": "pit-common" ++ }, ++ { ++ "name": "pxb", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "virtio-net-pci-non-transitional", ++ "parent": "virtio-net-pci-base" ++ }, ++ { ++ "name": "virtio-scsi-pci-non-transitional", ++ "parent": "virtio-scsi-pci-base" ++ }, ++ { ++ "name": "intel-iommu-iommu-memory-region", ++ "parent": "qemu:iommu-memory-region" ++ }, ++ { ++ "name": "pc-1.1-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "sd-card", ++ "parent": "device" ++ }, ++ { ++ "name": "kvaser_pci", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "vmxnet3", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "i6300esb", ++ "parent": "pci-device" ++ }, ++ { ++ "name": "Westmere-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "amd-iommu-iommu-memory-region", ++ "parent": "qemu:iommu-memory-region" ++ }, ++ { ++ "name": "pvpanic", ++ "parent": "isa-device" ++ }, ++ { ++ "name": "Penryn-x86_64-cpu", ++ "parent": "x86_64-cpu" ++ }, ++ { ++ "name": "vhost-vsock-pci-transitional", ++ "parent": "vhost-vsock-pci-base" ++ }, ++ { ++ "name": "apic", ++ "parent": "apic-common" ++ }, ++ { ++ "name": "isapc-machine", ++ "parent": "generic-pc-machine" ++ }, ++ { ++ "name": "rng-random", ++ "parent": "rng-backend" ++ } ++ ], ++ "id": "libvirt-9" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "virtio-blk-pci" ++ }, ++ "id": "libvirt-10" ++} ++ ++{ ++ "return": [ ++ { ++ "name": "iothread", ++ "type": "link" ++ }, ++ { ++ "name": "notify_on_empty", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "request-merging", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "secs", ++ "type": "uint32" ++ }, ++ { ++ "name": "min_io_size", ++ "type": "uint16" ++ }, ++ { ++ "name": "event_idx", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "serial", ++ "type": "str" ++ }, ++ { ++ "name": "heads", ++ "type": "uint32" ++ }, ++ { ++ "name": "ioeventfd", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "multifunction", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "rombar", ++ "type": "uint32" ++ }, ++ { ++ "name": "write-zeroes", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "scsi", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "cyls", ++ "type": "uint32" ++ }, ++ { ++ "name": "x-disable-pcie", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "logical_block_size", ++ "description": "A power of two between 512 and 32768", ++ "type": "uint16" ++ }, ++ { ++ "name": "bootindex", ++ "type": "int32" ++ }, ++ { ++ "name": "indirect_desc", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "max-write-zeroes-sectors", ++ "type": "uint32" ++ }, ++ { ++ "name": "queue-size", ++ "type": "uint16" ++ }, ++ { ++ "name": "disable-modern", ++ "type": "bool" ++ }, ++ { ++ "name": "drive", ++ "description": "Node name or ID of a block device to use as a backend", ++ "type": "str" ++ }, ++ { ++ "name": "x-pcie-lnkctl-init", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "disable-legacy", ++ "description": "on/off/auto", ++ "type": "OnOffAuto" ++ }, ++ { ++ "name": "command_serr_enable", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "werror", ++ "description": "Error handling policy, report/ignore/enospc/stop/auto", ++ "type": "BlockdevOnError" ++ }, ++ { ++ "name": "any_layout", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "discard_granularity", ++ "type": "uint32" ++ }, ++ { ++ "name": "rerror", ++ "description": "Error handling policy, report/ignore/enospc/stop/auto", ++ "type": "BlockdevOnError" ++ }, ++ { ++ "name": "page-per-vq", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "x-pcie-deverr-init", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "x-pcie-pm-init", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "max-discard-sectors", ++ "type": "uint32" ++ }, ++ { ++ "name": "x-pcie-lnksta-dllla", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "share-rw", ++ "type": "bool" ++ }, ++ { ++ "name": "physical_block_size", ++ "description": "A power of two between 512 and 32768", ++ "type": "uint16" ++ }, ++ { ++ "name": "config-wce", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "class", ++ "type": "uint32" ++ }, ++ { ++ "name": "addr", ++ "description": "Slot and optional function number, example: 06.0 or 06", ++ "type": "int32" ++ }, ++ { ++ "name": "migrate-extra", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "modern-pio-notify", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "vectors", ++ "type": "uint32" ++ }, ++ { ++ "name": "iommu_platform", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "x-pcie-extcap-init", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "virtio-backend", ++ "type": "child" ++ }, ++ { ++ "name": "x-ignore-backend-features", ++ "type": "bool" ++ }, ++ { ++ "name": "discard", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "write-cache", ++ "description": "on/off/auto", ++ "type": "OnOffAuto" ++ }, ++ { ++ "name": "num-queues", ++ "type": "uint16" ++ }, ++ { ++ "name": "opt_io_size", ++ "type": "uint32" ++ }, ++ { ++ "name": "ats", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "romfile", ++ "type": "str" ++ }, ++ { ++ "name": "virtio-pci-bus-master-bug-migration", ++ "description": "on/off", ++ "type": "bool" ++ } ++ ], ++ "id": "libvirt-10" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "virtio-net-pci" ++ }, ++ "id": "libvirt-11" ++} ++ ++{ ++ "return": [ ++ { ++ "name": "ctrl_mac_addr", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "romfile", ++ "type": "str" ++ }, ++ { ++ "name": "x-pcie-lnksta-dllla", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "status", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "notify_on_empty", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "command_serr_enable", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "indirect_desc", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "x-pcie-pm-init", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "rsc_interval", ++ "type": "uint32" ++ }, ++ { ++ "name": "guest_csum", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "speed", ++ "type": "int32" ++ }, ++ { ++ "name": "ctrl_rx", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "ctrl_vq", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "bootindex", ++ "type": "int32" ++ }, ++ { ++ "name": "multifunction", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "disable-modern", ++ "type": "bool" ++ }, ++ { ++ "name": "mrg_rxbuf", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "host_tso6", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "x-txtimer", ++ "type": "uint32" ++ }, ++ { ++ "name": "host_tso4", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "rombar", ++ "type": "uint32" ++ }, ++ { ++ "name": "ctrl_rx_extra", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "gso", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "page-per-vq", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "x-disable-pcie", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "x-ignore-backend-features", ++ "type": "bool" ++ }, ++ { ++ "name": "x-txburst", ++ "type": "int32" ++ }, ++ { ++ "name": "iommu_platform", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "x-pcie-lnkctl-init", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "host_mtu", ++ "type": "uint16" ++ }, ++ { ++ "name": "ctrl_vlan", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "guest_tso4", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "virtio-backend", ++ "type": "child" ++ }, ++ { ++ "name": "event_idx", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "vectors", ++ "type": "uint32" ++ }, ++ { ++ "name": "guest_announce", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "host_ecn", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "addr", ++ "description": "Slot and optional function number, example: 06.0 or 06", ++ "type": "int32" ++ }, ++ { ++ "name": "ats", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "host_ufo", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "duplex", ++ "type": "str" ++ }, ++ { ++ "name": "guest_tso6", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "ctrl_guest_offloads", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "csum", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "modern-pio-notify", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "ioeventfd", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "mq", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "any_layout", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "guest_ecn", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "guest_ufo", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "virtio-pci-bus-master-bug-migration", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "mac", ++ "description": "Ethernet 6-byte MAC Address, example: 52:54:00:12:34:56", ++ "type": "str" ++ }, ++ { ++ "name": "tx_queue_size", ++ "type": "uint16" ++ }, ++ { ++ "name": "disable-legacy", ++ "description": "on/off/auto", ++ "type": "OnOffAuto" ++ }, ++ { ++ "name": "tx", ++ "type": "str" ++ }, ++ { ++ "name": "x-pcie-extcap-init", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "x-mtu-bypass-backend", ++ "type": "bool" ++ }, ++ { ++ "name": "x-pcie-deverr-init", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "netdev", ++ "description": "ID of a netdev to use as a backend", ++ "type": "str" ++ }, ++ { ++ "name": "migrate-extra", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "guest_rsc_ext", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "rx_queue_size", ++ "type": "uint16" ++ } ++ ], ++ "id": "libvirt-11" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "virtio-scsi-pci" ++ }, ++ "id": "libvirt-12" ++} ++ ++{ ++ "return": [ ++ { ++ "name": "event_idx", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "ioeventfd", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "multifunction", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "rombar", ++ "type": "uint32" ++ }, ++ { ++ "name": "virtqueue_size", ++ "type": "uint32" ++ }, ++ { ++ "name": "x-disable-pcie", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "indirect_desc", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "x-pcie-lnkctl-init", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "disable-modern", ++ "type": "bool" ++ }, ++ { ++ "name": "num_queues", ++ "type": "uint32" ++ }, ++ { ++ "name": "cmd_per_lun", ++ "type": "uint32" ++ }, ++ { ++ "name": "disable-legacy", ++ "description": "on/off/auto", ++ "type": "OnOffAuto" ++ }, ++ { ++ "name": "command_serr_enable", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "hotplug", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "page-per-vq", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "x-pcie-deverr-init", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "x-pcie-pm-init", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "x-pcie-lnksta-dllla", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "max_sectors", ++ "type": "uint32" ++ }, ++ { ++ "name": "param_change", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "any_layout", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "iothread", ++ "type": "link" ++ }, ++ { ++ "name": "addr", ++ "description": "Slot and optional function number, example: 06.0 or 06", ++ "type": "int32" ++ }, ++ { ++ "name": "migrate-extra", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "modern-pio-notify", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "vectors", ++ "type": "uint32" ++ }, ++ { ++ "name": "x-pcie-extcap-init", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "virtio-backend", ++ "type": "child" ++ }, ++ { ++ "name": "x-ignore-backend-features", ++ "type": "bool" ++ }, ++ { ++ "name": "notify_on_empty", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "iommu_platform", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "ats", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "romfile", ++ "type": "str" ++ }, ++ { ++ "name": "virtio-pci-bus-master-bug-migration", ++ "description": "on/off", ++ "type": "bool" ++ } ++ ], ++ "id": "libvirt-12" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "virtio-net-ccw" ++ }, ++ "id": "libvirt-13" ++} ++ ++{ ++ "id": "libvirt-13", ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "Device 'virtio-net-ccw' not found" ++ } ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "virtio-scsi-ccw" ++ }, ++ "id": "libvirt-14" ++} ++ ++{ ++ "id": "libvirt-14", ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "Device 'virtio-scsi-ccw' not found" ++ } ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "virtio-net-s390" ++ }, ++ "id": "libvirt-15" ++} ++ ++{ ++ "id": "libvirt-15", ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "Device 'virtio-net-s390' not found" ++ } ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "pci-assign" ++ }, ++ "id": "libvirt-16" ++} ++ ++{ ++ "id": "libvirt-16", ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "Device 'pci-assign' not found" ++ } ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "kvm-pci-assign" ++ }, ++ "id": "libvirt-17" ++} ++ ++{ ++ "id": "libvirt-17", ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "Device 'kvm-pci-assign' not found" ++ } ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "vfio-pci" ++ }, ++ "id": "libvirt-18" ++} ++ ++{ ++ "return": [ ++ { ++ "name": "x-igd-opregion", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "x-pci-vendor-id", ++ "type": "uint32" ++ }, ++ { ++ "name": "yres", ++ "type": "uint32" ++ }, ++ { ++ "name": "x-pci-sub-device-id", ++ "type": "uint32" ++ }, ++ { ++ "name": "x-no-kvm-ioeventfd", ++ "type": "bool" ++ }, ++ { ++ "name": "multifunction", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "rombar", ++ "type": "uint32" ++ }, ++ { ++ "name": "x-no-kvm-msi", ++ "type": "bool" ++ }, ++ { ++ "name": "x-req", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "xres", ++ "type": "uint32" ++ }, ++ { ++ "name": "x-no-vfio-ioeventfd", ++ "type": "bool" ++ }, ++ { ++ "name": "x-no-kvm-intx", ++ "type": "bool" ++ }, ++ { ++ "name": "host", ++ "description": "Address (bus/device/function) of the host device, example: 04:10.0", ++ "type": "str" ++ }, ++ { ++ "name": "x-no-kvm-msix", ++ "type": "bool" ++ }, ++ { ++ "name": "command_serr_enable", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "x-balloon-allowed", ++ "type": "bool" ++ }, ++ { ++ "name": "x-pcie-lnksta-dllla", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "x-pci-sub-vendor-id", ++ "type": "uint32" ++ }, ++ { ++ "name": "x-pci-device-id", ++ "type": "uint32" ++ }, ++ { ++ "name": "x-no-geforce-quirks", ++ "type": "bool" ++ }, ++ { ++ "name": "display", ++ "description": "on/off/auto", ++ "type": "OnOffAuto" ++ }, ++ { ++ "name": "x-nv-gpudirect-clique", ++ "description": "NVIDIA GPUDirect Clique ID (0 - 15)", ++ "type": "uint4" ++ }, ++ { ++ "name": "x-igd-gms", ++ "type": "uint32" ++ }, ++ { ++ "name": "addr", ++ "description": "Slot and optional function number, example: 06.0 or 06", ++ "type": "int32" ++ }, ++ { ++ "name": "x-msix-relocation", ++ "description": "off/auto/bar0/bar1/bar2/bar3/bar4/bar5", ++ "type": "OffAutoPCIBAR" ++ }, ++ { ++ "name": "x-intx-mmap-timeout-ms", ++ "type": "uint32" ++ }, ++ { ++ "name": "x-pcie-extcap-init", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "x-no-mmap", ++ "type": "bool" ++ }, ++ { ++ "name": "bootindex", ++ "type": "int32" ++ }, ++ { ++ "name": "sysfsdev", ++ "type": "str" ++ }, ++ { ++ "name": "x-vga", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "romfile", ++ "type": "str" ++ } ++ ], ++ "id": "libvirt-18" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-disk" ++ }, ++ "id": "libvirt-19" ++} ++ ++{ ++ "return": [ ++ { ++ "name": "min_io_size", ++ "type": "uint16" ++ }, ++ { ++ "name": "secs", ++ "type": "uint32" ++ }, ++ { ++ "name": "removable", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "channel", ++ "type": "uint32" ++ }, ++ { ++ "name": "heads", ++ "type": "uint32" ++ }, ++ { ++ "name": "lun", ++ "type": "uint32" ++ }, ++ { ++ "name": "dpofua", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "ver", ++ "type": "str" ++ }, ++ { ++ "name": "scsi-id", ++ "type": "uint32" ++ }, ++ { ++ "name": "cyls", ++ "type": "uint32" ++ }, ++ { ++ "name": "logical_block_size", ++ "description": "A power of two between 512 and 32768", ++ "type": "uint16" ++ }, ++ { ++ "name": "rotation_rate", ++ "type": "uint16" ++ }, ++ { ++ "name": "drive", ++ "description": "Node name or ID of a block device to use as a backend", ++ "type": "str" ++ }, ++ { ++ "name": "scsi_version", ++ "type": "int32" ++ }, ++ { ++ "name": "werror", ++ "description": "Error handling policy, report/ignore/enospc/stop/auto", ++ "type": "BlockdevOnError" ++ }, ++ { ++ "name": "discard_granularity", ++ "type": "uint32" ++ }, ++ { ++ "name": "port_wwn", ++ "type": "uint64" ++ }, ++ { ++ "name": "max_unmap_size", ++ "type": "uint64" ++ }, ++ { ++ "name": "rerror", ++ "description": "Error handling policy, report/ignore/enospc/stop/auto", ++ "type": "BlockdevOnError" ++ }, ++ { ++ "name": "max_io_size", ++ "type": "uint64" ++ }, ++ { ++ "name": "device_id", ++ "type": "str" ++ }, ++ { ++ "name": "wwn", ++ "type": "uint64" ++ }, ++ { ++ "name": "share-rw", ++ "type": "bool" ++ }, ++ { ++ "name": "product", ++ "type": "str" ++ }, ++ { ++ "name": "vendor", ++ "type": "str" ++ }, ++ { ++ "name": "physical_block_size", ++ "description": "A power of two between 512 and 32768", ++ "type": "uint16" ++ }, ++ { ++ "name": "port_index", ++ "type": "uint16" ++ }, ++ { ++ "name": "bootindex", ++ "type": "int32" ++ }, ++ { ++ "name": "serial", ++ "type": "str" ++ }, ++ { ++ "name": "write-cache", ++ "description": "on/off/auto", ++ "type": "OnOffAuto" ++ }, ++ { ++ "name": "opt_io_size", ++ "type": "uint32" ++ } ++ ], ++ "id": "libvirt-19" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "ide-drive" ++ }, ++ "id": "libvirt-20" ++} ++ ++{ ++ "return": [ ++ { ++ "name": "serial", ++ "type": "str" ++ }, ++ { ++ "name": "secs", ++ "type": "uint32" ++ }, ++ { ++ "name": "logical_block_size", ++ "description": "A power of two between 512 and 32768", ++ "type": "uint16" ++ }, ++ { ++ "name": "discard_granularity", ++ "type": "uint32" ++ }, ++ { ++ "name": "bootindex", ++ "type": "int32" ++ }, ++ { ++ "name": "rotation_rate", ++ "type": "uint16" ++ }, ++ { ++ "name": "drive", ++ "description": "Node name or ID of a block device to use as a backend", ++ "type": "str" ++ }, ++ { ++ "name": "heads", ++ "type": "uint32" ++ }, ++ { ++ "name": "write-cache", ++ "description": "on/off/auto", ++ "type": "OnOffAuto" ++ }, ++ { ++ "name": "share-rw", ++ "type": "bool" ++ }, ++ { ++ "name": "min_io_size", ++ "type": "uint16" ++ }, ++ { ++ "name": "opt_io_size", ++ "type": "uint32" ++ }, ++ { ++ "name": "bios-chs-trans", ++ "description": "Logical CHS translation algorithm, auto/none/lba/large/rechs", ++ "type": "BiosAtaTranslation" ++ }, ++ { ++ "name": "unit", ++ "type": "uint32" ++ }, ++ { ++ "name": "wwn", ++ "type": "uint64" ++ }, ++ { ++ "name": "werror", ++ "description": "Error handling policy, report/ignore/enospc/stop/auto", ++ "type": "BlockdevOnError" ++ }, ++ { ++ "name": "model", ++ "type": "str" ++ }, ++ { ++ "name": "rerror", ++ "description": "Error handling policy, report/ignore/enospc/stop/auto", ++ "type": "BlockdevOnError" ++ }, ++ { ++ "name": "ver", ++ "type": "str" ++ }, ++ { ++ "name": "physical_block_size", ++ "description": "A power of two between 512 and 32768", ++ "type": "uint16" ++ }, ++ { ++ "name": "cyls", ++ "type": "uint32" ++ } ++ ], ++ "id": "libvirt-20" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "PIIX4_PM" ++ }, ++ "id": "libvirt-21" ++} ++ ++{ ++ "return": [ ++ { ++ "name": "memory-hotplug-support", ++ "type": "bool" ++ }, ++ { ++ "name": "rombar", ++ "type": "uint32" ++ }, ++ { ++ "name": "x-pcie-lnksta-dllla", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "acpi-pci-hotplug-with-bridge-support", ++ "type": "bool" ++ }, ++ { ++ "name": "multifunction", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "romfile", ++ "type": "str" ++ }, ++ { ++ "name": "disable_s4", ++ "type": "uint8" ++ }, ++ { ++ "name": "disable_s3", ++ "type": "uint8" ++ }, ++ { ++ "name": "x-pcie-extcap-init", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "command_serr_enable", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "s4_val", ++ "type": "uint8" ++ }, ++ { ++ "name": "smb_io_base", ++ "type": "uint32" ++ }, ++ { ++ "name": "addr", ++ "description": "Slot and optional function number, example: 06.0 or 06", ++ "type": "int32" ++ } ++ ], ++ "id": "libvirt-21" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "usb-redir" ++ }, ++ "id": "libvirt-22" ++} ++ ++{ ++ "return": [ ++ { ++ "name": "filter", ++ "type": "str" ++ }, ++ { ++ "name": "msos-desc", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "serial", ++ "type": "str" ++ }, ++ { ++ "name": "bootindex", ++ "type": "int32" ++ }, ++ { ++ "name": "port", ++ "type": "str" ++ }, ++ { ++ "name": "debug", ++ "type": "uint8" ++ }, ++ { ++ "name": "streams", ++ "type": "bool" ++ }, ++ { ++ "name": "chardev", ++ "description": "ID of a chardev to use as a backend", ++ "type": "str" ++ }, ++ { ++ "name": "full-path", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "attached", ++ "type": "bool" ++ } ++ ], ++ "id": "libvirt-22" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "usb-host" ++ }, ++ "id": "libvirt-23" ++} ++ ++{ ++ "return": [ ++ { ++ "name": "isobufs", ++ "type": "uint32" ++ }, ++ { ++ "name": "hostaddr", ++ "type": "uint32" ++ }, ++ { ++ "name": "msos-desc", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "productid", ++ "type": "uint32" ++ }, ++ { ++ "name": "serial", ++ "type": "str" ++ }, ++ { ++ "name": "bootindex", ++ "type": "int32" ++ }, ++ { ++ "name": "guest-reset", ++ "type": "bool" ++ }, ++ { ++ "name": "isobsize", ++ "type": "uint32" ++ }, ++ { ++ "name": "port", ++ "type": "str" ++ }, ++ { ++ "name": "vendorid", ++ "type": "uint32" ++ }, ++ { ++ "name": "pipeline", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "attached", ++ "type": "bool" ++ }, ++ { ++ "name": "hostport", ++ "type": "str" ++ }, ++ { ++ "name": "full-path", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "loglevel", ++ "type": "uint32" ++ }, ++ { ++ "name": "hostbus", ++ "type": "uint32" ++ } ++ ], ++ "id": "libvirt-23" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "scsi-generic" ++ }, ++ "id": "libvirt-24" ++} ++ ++{ ++ "return": [ ++ { ++ "name": "bootindex", ++ "type": "int32" ++ }, ++ { ++ "name": "drive", ++ "description": "Node name or ID of a block device to use as a backend", ++ "type": "str" ++ }, ++ { ++ "name": "lun", ++ "type": "uint32" ++ }, ++ { ++ "name": "share-rw", ++ "type": "bool" ++ }, ++ { ++ "name": "channel", ++ "type": "uint32" ++ }, ++ { ++ "name": "scsi-id", ++ "type": "uint32" ++ } ++ ], ++ "id": "libvirt-24" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "i440FX-pcihost" ++ }, ++ "id": "libvirt-25" ++} ++ ++{ ++ "return": [ ++ { ++ "name": "short_root_bus", ++ "type": "uint32" ++ }, ++ { ++ "name": "pci-conf-idx[0]", ++ "type": "child" ++ }, ++ { ++ "name": "pci-hole64-end", ++ "type": "uint64" ++ }, ++ { ++ "name": "pci-hole-end", ++ "type": "uint32" ++ }, ++ { ++ "name": "pci-hole-start", ++ "type": "uint32" ++ }, ++ { ++ "name": "pci-hole64-start", ++ "type": "uint64" ++ }, ++ { ++ "name": "pci-hole64-size", ++ "type": "size" ++ }, ++ { ++ "name": "pci-conf-data[0]", ++ "type": "child" ++ }, ++ { ++ "name": "x-pci-hole64-fix", ++ "type": "bool" ++ } ++ ], ++ "id": "libvirt-25" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "q35-pcihost" ++ }, ++ "id": "libvirt-26" ++} ++ ++{ ++ "return": [ ++ { ++ "name": "short_root_bus", ++ "type": "uint32" ++ }, ++ { ++ "name": "system-mem", ++ "type": "link" ++ }, ++ { ++ "name": "pci-conf-idx[0]", ++ "type": "child" ++ }, ++ { ++ "name": "pcie-mmcfg-mmio[0]", ++ "type": "child" ++ }, ++ { ++ "name": "pci-hole64-start", ++ "type": "uint64" ++ }, ++ { ++ "name": "io-mem", ++ "type": "link" ++ }, ++ { ++ "name": "pci-hole64-end", ++ "type": "uint64" ++ }, ++ { ++ "name": "pci-hole-end", ++ "type": "uint32" ++ }, ++ { ++ "name": "above-4g-mem-size", ++ "type": "size" ++ }, ++ { ++ "name": "below-4g-mem-size", ++ "type": "size" ++ }, ++ { ++ "name": "ram-mem", ++ "type": "link" ++ }, ++ { ++ "name": "pci-hole-start", ++ "type": "uint32" ++ }, ++ { ++ "name": "MCFG", ++ "type": "uint64" ++ }, ++ { ++ "name": "mch", ++ "type": "child" ++ }, ++ { ++ "name": "pci-hole64-size", ++ "type": "size" ++ }, ++ { ++ "name": "pci-mem", ++ "type": "link" ++ }, ++ { ++ "name": "pci-conf-data[0]", ++ "type": "child" ++ }, ++ { ++ "name": "x-pci-hole64-fix", ++ "type": "bool" ++ }, ++ { ++ "name": "mcfg_size", ++ "type": "uint64" ++ } ++ ], ++ "id": "libvirt-26" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "usb-storage" ++ }, ++ "id": "libvirt-27" ++} ++ ++{ ++ "return": [ ++ { ++ "name": "serial", ++ "type": "str" ++ }, ++ { ++ "name": "msos-desc", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "logical_block_size", ++ "description": "A power of two between 512 and 32768", ++ "type": "uint16" ++ }, ++ { ++ "name": "discard_granularity", ++ "type": "uint32" ++ }, ++ { ++ "name": "drive", ++ "description": "Node name or ID of a block device to use as a backend", ++ "type": "str" ++ }, ++ { ++ "name": "bootindex", ++ "type": "int32" ++ }, ++ { ++ "name": "write-cache", ++ "description": "on/off/auto", ++ "type": "OnOffAuto" ++ }, ++ { ++ "name": "share-rw", ++ "type": "bool" ++ }, ++ { ++ "name": "min_io_size", ++ "type": "uint16" ++ }, ++ { ++ "name": "opt_io_size", ++ "type": "uint32" ++ }, ++ { ++ "name": "port", ++ "type": "str" ++ }, ++ { ++ "name": "attached", ++ "type": "bool" ++ }, ++ { ++ "name": "werror", ++ "description": "Error handling policy, report/ignore/enospc/stop/auto", ++ "type": "BlockdevOnError" ++ }, ++ { ++ "name": "full-path", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "rerror", ++ "description": "Error handling policy, report/ignore/enospc/stop/auto", ++ "type": "BlockdevOnError" ++ }, ++ { ++ "name": "removable", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "physical_block_size", ++ "description": "A power of two between 512 and 32768", ++ "type": "uint16" ++ } ++ ], ++ "id": "libvirt-27" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "kvm-pit" ++ }, ++ "id": "libvirt-28" ++} ++ ++{ ++ "return": [ ++ { ++ "name": "iobase", ++ "type": "uint32" ++ }, ++ { ++ "name": "lost_tick_policy", ++ "type": "LostTickPolicy" ++ } ++ ], ++ "id": "libvirt-28" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "VGA" ++ }, ++ "id": "libvirt-29" ++} ++ ++{ ++ "return": [ ++ { ++ "name": "rombar", ++ "type": "uint32" ++ }, ++ { ++ "name": "x-pcie-lnksta-dllla", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "mmio", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "multifunction", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "qemu-extended-regs", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "big-endian-framebuffer", ++ "type": "bool" ++ }, ++ { ++ "name": "command_serr_enable", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "romfile", ++ "type": "str" ++ }, ++ { ++ "name": "yres", ++ "type": "uint32" ++ }, ++ { ++ "name": "vgamem_mb", ++ "type": "uint32" ++ }, ++ { ++ "name": "x-pcie-extcap-init", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "addr", ++ "description": "Slot and optional function number, example: 06.0 or 06", ++ "type": "int32" ++ }, ++ { ++ "name": "global-vmstate", ++ "type": "bool" ++ }, ++ { ++ "name": "edid", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "xres", ++ "type": "uint32" ++ } ++ ], ++ "id": "libvirt-29" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "vmware-svga" ++ }, ++ "id": "libvirt-30" ++} ++ ++{ ++ "return": [ ++ { ++ "name": "rombar", ++ "type": "uint32" ++ }, ++ { ++ "name": "x-pcie-lnksta-dllla", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "multifunction", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "romfile", ++ "type": "str" ++ }, ++ { ++ "name": "vgamem_mb", ++ "type": "uint32" ++ }, ++ { ++ "name": "x-pcie-extcap-init", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "command_serr_enable", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "addr", ++ "description": "Slot and optional function number, example: 06.0 or 06", ++ "type": "int32" ++ }, ++ { ++ "name": "global-vmstate", ++ "type": "bool" ++ } ++ ], ++ "id": "libvirt-30" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "qxl" ++ }, ++ "id": "libvirt-31" ++} ++ ++{ ++ "return": [ ++ { ++ "name": "command_serr_enable", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "rombar", ++ "type": "uint32" ++ }, ++ { ++ "name": "x-pcie-lnksta-dllla", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "yres", ++ "type": "uint32" ++ }, ++ { ++ "name": "ram_size_mb", ++ "type": "uint32" ++ }, ++ { ++ "name": "global-vmstate", ++ "type": "bool" ++ }, ++ { ++ "name": "multifunction", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "vgamem_mb", ++ "type": "uint32" ++ }, ++ { ++ "name": "romfile", ++ "type": "str" ++ }, ++ { ++ "name": "addr", ++ "description": "Slot and optional function number, example: 06.0 or 06", ++ "type": "int32" ++ }, ++ { ++ "name": "debug", ++ "type": "uint32" ++ }, ++ { ++ "name": "vram_size_mb", ++ "type": "uint32" ++ }, ++ { ++ "name": "revision", ++ "type": "uint32" ++ }, ++ { ++ "name": "ram_size", ++ "type": "uint32" ++ }, ++ { ++ "name": "vram64_size_mb", ++ "type": "uint32" ++ }, ++ { ++ "name": "x-pcie-extcap-init", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "guestdebug", ++ "type": "uint32" ++ }, ++ { ++ "name": "vram_size", ++ "type": "uint64" ++ }, ++ { ++ "name": "surfaces", ++ "type": "int32" ++ }, ++ { ++ "name": "max_outputs", ++ "type": "uint16" ++ }, ++ { ++ "name": "xres", ++ "type": "uint32" ++ }, ++ { ++ "name": "cmdlog", ++ "type": "uint32" ++ } ++ ], ++ "id": "libvirt-31" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "virtio-gpu-pci" ++ }, ++ "id": "libvirt-32" ++} ++ ++{ ++ "return": [ ++ { ++ "name": "event_idx", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "yres", ++ "type": "uint32" ++ }, ++ { ++ "name": "ioeventfd", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "multifunction", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "rombar", ++ "type": "uint32" ++ }, ++ { ++ "name": "xres", ++ "type": "uint32" ++ }, ++ { ++ "name": "x-disable-pcie", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "indirect_desc", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "disable-modern", ++ "type": "bool" ++ }, ++ { ++ "name": "x-pcie-lnkctl-init", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "disable-legacy", ++ "description": "on/off/auto", ++ "type": "OnOffAuto" ++ }, ++ { ++ "name": "command_serr_enable", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "page-per-vq", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "x-pcie-deverr-init", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "max_outputs", ++ "type": "uint32" ++ }, ++ { ++ "name": "x-pcie-pm-init", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "x-pcie-lnksta-dllla", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "any_layout", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "addr", ++ "description": "Slot and optional function number, example: 06.0 or 06", ++ "type": "int32" ++ }, ++ { ++ "name": "edid", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "migrate-extra", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "modern-pio-notify", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "vectors", ++ "type": "uint32" ++ }, ++ { ++ "name": "iommu_platform", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "x-pcie-extcap-init", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "max_hostmem", ++ "type": "size" ++ }, ++ { ++ "name": "virtio-backend", ++ "type": "child" ++ }, ++ { ++ "name": "x-ignore-backend-features", ++ "type": "bool" ++ }, ++ { ++ "name": "stats", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "notify_on_empty", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "virgl", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "ats", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "romfile", ++ "type": "str" ++ }, ++ { ++ "name": "virtio-pci-bus-master-bug-migration", ++ "description": "on/off", ++ "type": "bool" ++ } ++ ], ++ "id": "libvirt-32" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "virtio-gpu-device" ++ }, ++ "id": "libvirt-33" ++} ++ ++{ ++ "return": [ ++ { ++ "name": "notify_on_empty", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "any_layout", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "indirect_desc", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "event_idx", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "yres", ++ "type": "uint32" ++ }, ++ { ++ "name": "stats", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "iommu_platform", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "virgl", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "edid", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "max_outputs", ++ "type": "uint32" ++ }, ++ { ++ "name": "max_hostmem", ++ "type": "size" ++ }, ++ { ++ "name": "xres", ++ "type": "uint32" ++ } ++ ], ++ "id": "libvirt-33" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "ICH9-LPC" ++ }, ++ "id": "libvirt-34" ++} ++ ++{ ++ "return": [ ++ { ++ "name": "memory-hotplug-support", ++ "type": "bool" ++ }, ++ { ++ "name": "rombar", ++ "type": "uint32" ++ }, ++ { ++ "name": "sci_int", ++ "type": "uint32" ++ }, ++ { ++ "name": "x-pcie-lnksta-dllla", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "gpe0_blk_len", ++ "type": "uint32" ++ }, ++ { ++ "name": "pm_io_base", ++ "type": "uint32" ++ }, ++ { ++ "name": "noreboot", ++ "type": "bool" ++ }, ++ { ++ "name": "multifunction", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "cpu-hotplug-legacy", ++ "type": "bool" ++ }, ++ { ++ "name": "acpi_disable_cmd", ++ "type": "uint8" ++ }, ++ { ++ "name": "x-smi-broadcast", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "romfile", ++ "type": "str" ++ }, ++ { ++ "name": "disable_s3", ++ "type": "uint8" ++ }, ++ { ++ "name": "s4_val", ++ "type": "uint8" ++ }, ++ { ++ "name": "x-pcie-extcap-init", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "command_serr_enable", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "addr", ++ "description": "Slot and optional function number, example: 06.0 or 06", ++ "type": "int32" ++ }, ++ { ++ "name": "acpi_enable_cmd", ++ "type": "uint8" ++ }, ++ { ++ "name": "enable_tco", ++ "type": "bool" ++ }, ++ { ++ "name": "disable_s4", ++ "type": "uint8" ++ }, ++ { ++ "name": "gpe0_blk", ++ "type": "uint32" ++ } ++ ], ++ "id": "libvirt-34" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "virtio-balloon-pci" ++ }, ++ "id": "libvirt-35" ++} ++ ++{ ++ "return": [ ++ { ++ "name": "guest-stats-polling-interval", ++ "type": "int" ++ }, ++ { ++ "name": "event_idx", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "multifunction", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "rombar", ++ "type": "uint32" ++ }, ++ { ++ "name": "x-disable-pcie", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "indirect_desc", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "x-pcie-lnkctl-init", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "disable-modern", ++ "type": "bool" ++ }, ++ { ++ "name": "free-page-hint", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "disable-legacy", ++ "description": "on/off/auto", ++ "type": "OnOffAuto" ++ }, ++ { ++ "name": "command_serr_enable", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "guest-stats", ++ "type": "guest statistics" ++ }, ++ { ++ "name": "deflate-on-oom", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "page-per-vq", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "x-pcie-deverr-init", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "x-pcie-pm-init", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "x-pcie-lnksta-dllla", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "any_layout", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "iothread", ++ "type": "link" ++ }, ++ { ++ "name": "class", ++ "type": "uint32" ++ }, ++ { ++ "name": "addr", ++ "description": "Slot and optional function number, example: 06.0 or 06", ++ "type": "int32" ++ }, ++ { ++ "name": "migrate-extra", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "modern-pio-notify", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "x-pcie-extcap-init", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "virtio-backend", ++ "type": "child" ++ }, ++ { ++ "name": "x-ignore-backend-features", ++ "type": "bool" ++ }, ++ { ++ "name": "notify_on_empty", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "iommu_platform", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "ats", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "virtio-pci-bus-master-bug-migration", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "romfile", ++ "type": "str" ++ } ++ ], ++ "id": "libvirt-35" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "virtio-balloon-ccw" ++ }, ++ "id": "libvirt-36" ++} ++ ++{ ++ "id": "libvirt-36", ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "Device 'virtio-balloon-ccw' not found" ++ } ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "virtio-balloon-device" ++ }, ++ "id": "libvirt-37" ++} ++ ++{ ++ "return": [ ++ { ++ "name": "notify_on_empty", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "any_layout", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "indirect_desc", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "guest-stats", ++ "type": "guest statistics" ++ }, ++ { ++ "name": "guest-stats-polling-interval", ++ "type": "int" ++ }, ++ { ++ "name": "iothread", ++ "type": "link" ++ }, ++ { ++ "name": "event_idx", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "free-page-hint", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "iommu_platform", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "deflate-on-oom", ++ "description": "on/off", ++ "type": "bool" ++ } ++ ], ++ "id": "libvirt-37" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "nec-usb-xhci" ++ }, ++ "id": "libvirt-38" ++} ++ ++{ ++ "return": [ ++ { ++ "name": "rombar", ++ "type": "uint32" ++ }, ++ { ++ "name": "intrs", ++ "type": "uint32" ++ }, ++ { ++ "name": "x-pcie-lnksta-dllla", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "msix", ++ "description": "on/off/auto", ++ "type": "OnOffAuto" ++ }, ++ { ++ "name": "multifunction", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "msi", ++ "description": "on/off/auto", ++ "type": "OnOffAuto" ++ }, ++ { ++ "name": "superspeed-ports-first", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "streams", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "romfile", ++ "type": "str" ++ }, ++ { ++ "name": "force-pcie-endcap", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "x-pcie-extcap-init", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "command_serr_enable", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "addr", ++ "description": "Slot and optional function number, example: 06.0 or 06", ++ "type": "int32" ++ }, ++ { ++ "name": "p3", ++ "type": "uint32" ++ }, ++ { ++ "name": "p2", ++ "type": "uint32" ++ }, ++ { ++ "name": "slots", ++ "type": "uint32" ++ } ++ ], ++ "id": "libvirt-38" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "intel-iommu" ++ }, ++ "id": "libvirt-39" ++} ++ ++{ ++ "return": [ ++ { ++ "name": "eim", ++ "description": "on/off/auto", ++ "type": "OnOffAuto" ++ }, ++ { ++ "name": "caching-mode", ++ "type": "bool" ++ }, ++ { ++ "name": "x-buggy-eim", ++ "type": "bool" ++ }, ++ { ++ "name": "intremap", ++ "description": "on/off/auto", ++ "type": "OnOffAuto" ++ }, ++ { ++ "name": "version", ++ "type": "uint32" ++ }, ++ { ++ "name": "x-scalable-mode", ++ "type": "bool" ++ }, ++ { ++ "name": "dma-drain", ++ "type": "bool" ++ }, ++ { ++ "name": "pt", ++ "type": "bool" ++ }, ++ { ++ "name": "device-iotlb", ++ "type": "bool" ++ }, ++ { ++ "name": "aw-bits", ++ "type": "uint8" ++ } ++ ], ++ "id": "libvirt-39" ++} ++ ++{ ++ "execute": "device-list-properties", ++ "arguments": { ++ "typename": "mch" ++ }, ++ "id": "libvirt-40" ++} ++ ++{ ++ "return": [ ++ { ++ "name": "rombar", ++ "type": "uint32" ++ }, ++ { ++ "name": "x-pcie-lnksta-dllla", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "multifunction", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "extended-tseg-mbytes", ++ "type": "uint16" ++ }, ++ { ++ "name": "romfile", ++ "type": "str" ++ }, ++ { ++ "name": "x-pcie-extcap-init", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "command_serr_enable", ++ "description": "on/off", ++ "type": "bool" ++ }, ++ { ++ "name": "addr", ++ "description": "Slot and optional function number, example: 06.0 or 06", ++ "type": "int32" ++ } ++ ], ++ "id": "libvirt-40" ++} ++ ++{ ++ "execute": "qom-list-properties", ++ "arguments": { ++ "typename": "memory-backend-file" ++ }, ++ "id": "libvirt-41" ++} ++ ++{ ++ "return": [ ++ { ++ "name": "type", ++ "type": "string" ++ }, ++ { ++ "name": "policy", ++ "description": "Set the NUMA policy", ++ "type": "HostMemPolicy" ++ }, ++ { ++ "name": "dump", ++ "description": "Set to 'off' to exclude from core dump", ++ "type": "bool" ++ }, ++ { ++ "name": "share", ++ "description": "Mark the memory as private to QEMU or shared", ++ "type": "bool" ++ }, ++ { ++ "name": "prealloc", ++ "description": "Preallocate memory", ++ "type": "bool" ++ }, ++ { ++ "name": "size", ++ "description": "Size of the memory region (ex: 500M)", ++ "type": "int" ++ }, ++ { ++ "name": "x-use-canonical-path-for-ramblock-id", ++ "type": "bool" ++ }, ++ { ++ "name": "host-nodes", ++ "description": "Binds memory to the list of NUMA host nodes", ++ "type": "int" ++ }, ++ { ++ "name": "merge", ++ "description": "Mark memory as mergeable", ++ "type": "bool" ++ }, ++ { ++ "name": "pmem", ++ "type": "bool" ++ }, ++ { ++ "name": "align", ++ "type": "int" ++ }, ++ { ++ "name": "mem-path", ++ "type": "string" ++ }, ++ { ++ "name": "discard-data", ++ "type": "bool" ++ } ++ ], ++ "id": "libvirt-41" ++} ++ ++{ ++ "execute": "qom-list-properties", ++ "arguments": { ++ "typename": "spapr-machine" ++ }, ++ "id": "libvirt-42" ++} ++ ++{ ++ "id": "libvirt-42", ++ "error": { ++ "class": "DeviceNotFound", ++ "desc": "Class 'spapr-machine' not found" ++ } ++} ++ ++{ ++ "execute": "query-machines", ++ "id": "libvirt-43" ++} ++ ++{ ++ "return": [ ++ { ++ "hotpluggable-cpus": true, ++ "name": "isapc", ++ "cpu-max": 1 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-1.1", ++ "cpu-max": 255 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-1.2", ++ "cpu-max": 255 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-1.3", ++ "cpu-max": 255 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-i440fx-2.8", ++ "cpu-max": 255 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-1.0", ++ "cpu-max": 255 ++ }, ++ { ++ "hotpluggable-cpus": false, ++ "name": "none", ++ "cpu-max": 1 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-i440fx-2.9", ++ "cpu-max": 255 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-i440fx-2.6", ++ "cpu-max": 255 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-i440fx-2.7", ++ "cpu-max": 255 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "xenfv", ++ "cpu-max": 128 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-i440fx-4.1", ++ "is-default": true, ++ "cpu-max": 255, ++ "alias": "pc" ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-i440fx-2.3", ++ "cpu-max": 255 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-i440fx-2.4", ++ "cpu-max": 255 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-i440fx-2.5", ++ "cpu-max": 255 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-i440fx-4.0", ++ "cpu-max": 255 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-i440fx-2.1", ++ "cpu-max": 255 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-i440fx-2.2", ++ "cpu-max": 255 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-q35-3.1", ++ "cpu-max": 288 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-i440fx-2.0", ++ "cpu-max": 255 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-q35-2.11", ++ "cpu-max": 288 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-q35-2.12", ++ "cpu-max": 288 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-q35-3.0", ++ "cpu-max": 288 ++ }, ++ { ++ "hotpluggable-cpus": false, ++ "name": "xenpv", ++ "cpu-max": 1 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-q35-2.10", ++ "cpu-max": 288 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-q35-4.0.1", ++ "cpu-max": 288 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-i440fx-1.7", ++ "cpu-max": 255 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-q35-2.9", ++ "cpu-max": 288 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-0.15", ++ "cpu-max": 255 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-i440fx-1.5", ++ "cpu-max": 255 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-q35-2.7", ++ "cpu-max": 255 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-i440fx-1.6", ++ "cpu-max": 255 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-i440fx-2.11", ++ "cpu-max": 255 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-q35-2.8", ++ "cpu-max": 288 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-0.13", ++ "cpu-max": 255 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-i440fx-2.12", ++ "cpu-max": 255 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-0.14", ++ "cpu-max": 255 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-i440fx-3.0", ++ "cpu-max": 255 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-i440fx-3.1", ++ "cpu-max": 255 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-q35-2.4", ++ "cpu-max": 255 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-q35-2.5", ++ "cpu-max": 255 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-q35-2.6", ++ "cpu-max": 255 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-i440fx-1.4", ++ "cpu-max": 255 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-i440fx-2.10", ++ "cpu-max": 255 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-0.12", ++ "cpu-max": 255 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-q35-4.0", ++ "cpu-max": 288 ++ }, ++ { ++ "hotpluggable-cpus": true, ++ "name": "pc-q35-4.1", ++ "cpu-max": 288, ++ "alias": "q35" ++ } ++ ], ++ "id": "libvirt-43" ++} ++ ++{ ++ "execute": "query-cpu-definitions", ++ "id": "libvirt-44" ++} ++ ++{ ++ "return": [ ++ { ++ "name": "max", ++ "typename": "max-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": false ++ }, ++ { ++ "name": "host", ++ "typename": "host-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": false ++ }, ++ { ++ "name": "base", ++ "typename": "base-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": true, ++ "migration-safe": true ++ }, ++ { ++ "name": "qemu64", ++ "typename": "qemu64-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "qemu32", ++ "typename": "qemu32-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "phenom", ++ "typename": "phenom-x86_64-cpu", ++ "unavailable-features": [ ++ "mmxext", ++ "fxsr-opt", ++ "3dnowext", ++ "3dnow", ++ "sse4a", ++ "npt" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "pentium3", ++ "typename": "pentium3-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "pentium2", ++ "typename": "pentium2-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "pentium", ++ "typename": "pentium-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "n270", ++ "typename": "n270-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "kvm64", ++ "typename": "kvm64-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "kvm32", ++ "typename": "kvm32-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "coreduo", ++ "typename": "coreduo-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "core2duo", ++ "typename": "core2duo-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "athlon", ++ "typename": "athlon-x86_64-cpu", ++ "unavailable-features": [ ++ "mmxext", ++ "3dnowext", ++ "3dnow" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Westmere-IBRS", ++ "typename": "Westmere-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "spec-ctrl" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Westmere", ++ "typename": "Westmere-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Server-IBRS", ++ "typename": "Skylake-Server-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "avx512f", ++ "avx512dq", ++ "clwb", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "pku", ++ "spec-ctrl", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Server", ++ "typename": "Skylake-Server-x86_64-cpu", ++ "unavailable-features": [ ++ "avx512f", ++ "avx512dq", ++ "clwb", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "pku", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Client-IBRS", ++ "typename": "Skylake-Client-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "spec-ctrl" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Client", ++ "typename": "Skylake-Client-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "SandyBridge-IBRS", ++ "typename": "SandyBridge-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "spec-ctrl" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "SandyBridge", ++ "typename": "SandyBridge-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Penryn", ++ "typename": "Penryn-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G5", ++ "typename": "Opteron_G5-x86_64-cpu", ++ "unavailable-features": [ ++ "sse4a", ++ "misalignsse", ++ "xop", ++ "fma4", ++ "tbm", ++ "npt", ++ "nrip-save" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G4", ++ "typename": "Opteron_G4-x86_64-cpu", ++ "unavailable-features": [ ++ "sse4a", ++ "misalignsse", ++ "xop", ++ "fma4", ++ "npt", ++ "nrip-save" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G3", ++ "typename": "Opteron_G3-x86_64-cpu", ++ "unavailable-features": [ ++ "sse4a", ++ "misalignsse" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G2", ++ "typename": "Opteron_G2-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G1", ++ "typename": "Opteron_G1-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Nehalem-IBRS", ++ "typename": "Nehalem-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "spec-ctrl" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Nehalem", ++ "typename": "Nehalem-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "KnightsMill", ++ "typename": "KnightsMill-x86_64-cpu", ++ "unavailable-features": [ ++ "avx512f", ++ "avx512pf", ++ "avx512er", ++ "avx512cd", ++ "avx512-vpopcntdq", ++ "avx512-4vnniw", ++ "avx512-4fmaps", ++ "avx512f", ++ "avx512f", ++ "avx512f" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "IvyBridge-IBRS", ++ "typename": "IvyBridge-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "spec-ctrl" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "IvyBridge", ++ "typename": "IvyBridge-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Icelake-Server", ++ "typename": "Icelake-Server-x86_64-cpu", ++ "unavailable-features": [ ++ "avx512f", ++ "avx512dq", ++ "clwb", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "avx512vbmi", ++ "pku", ++ "avx512vbmi2", ++ "gfni", ++ "vaes", ++ "vpclmulqdq", ++ "avx512vnni", ++ "avx512bitalg", ++ "avx512-vpopcntdq", ++ "la57", ++ "spec-ctrl", ++ "ssbd", ++ "wbnoinvd", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Icelake-Client", ++ "typename": "Icelake-Client-x86_64-cpu", ++ "unavailable-features": [ ++ "avx512vbmi", ++ "pku", ++ "avx512vbmi2", ++ "gfni", ++ "vaes", ++ "vpclmulqdq", ++ "avx512vnni", ++ "avx512bitalg", ++ "avx512-vpopcntdq", ++ "spec-ctrl", ++ "ssbd", ++ "wbnoinvd", ++ "pku" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-noTSX-IBRS", ++ "typename": "Haswell-noTSX-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "spec-ctrl" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-noTSX", ++ "typename": "Haswell-noTSX-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-IBRS", ++ "typename": "Haswell-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "spec-ctrl" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell", ++ "typename": "Haswell-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "EPYC-IBPB", ++ "typename": "EPYC-IBPB-x86_64-cpu", ++ "unavailable-features": [ ++ "sha-ni", ++ "mmxext", ++ "fxsr-opt", ++ "cr8legacy", ++ "sse4a", ++ "misalignsse", ++ "osvw", ++ "ibpb", ++ "npt", ++ "nrip-save" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "EPYC", ++ "typename": "EPYC-x86_64-cpu", ++ "unavailable-features": [ ++ "sha-ni", ++ "mmxext", ++ "fxsr-opt", ++ "cr8legacy", ++ "sse4a", ++ "misalignsse", ++ "osvw", ++ "npt", ++ "nrip-save" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Dhyana", ++ "typename": "Dhyana-x86_64-cpu", ++ "unavailable-features": [ ++ "mmxext", ++ "fxsr-opt", ++ "cr8legacy", ++ "sse4a", ++ "misalignsse", ++ "osvw", ++ "ibpb", ++ "npt", ++ "nrip-save" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Conroe", ++ "typename": "Conroe-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Cascadelake-Server", ++ "typename": "Cascadelake-Server-x86_64-cpu", ++ "unavailable-features": [ ++ "avx512f", ++ "avx512dq", ++ "clwb", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "pku", ++ "avx512vnni", ++ "spec-ctrl", ++ "ssbd", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-noTSX-IBRS", ++ "typename": "Broadwell-noTSX-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "spec-ctrl" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-noTSX", ++ "typename": "Broadwell-noTSX-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-IBRS", ++ "typename": "Broadwell-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "spec-ctrl" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell", ++ "typename": "Broadwell-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "486", ++ "typename": "486-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ } ++ ], ++ "id": "libvirt-44" ++} ++ ++{ ++ "execute": "query-tpm-models", ++ "id": "libvirt-45" ++} ++ ++{ ++ "return": [ ++ "tpm-crb", ++ "tpm-tis" ++ ], ++ "id": "libvirt-45" ++} ++ ++{ ++ "execute": "query-tpm-types", ++ "id": "libvirt-46" ++} ++ ++{ ++ "return": [ ++ "passthrough", ++ "emulator" ++ ], ++ "id": "libvirt-46" ++} ++ ++{ ++ "execute": "query-command-line-options", ++ "id": "libvirt-47" ++} ++ ++{ ++ "return": [ ++ { ++ "parameters": [ ++ { ++ "name": "timeout", ++ "help": "Request timeout in seconds (default 0 = no timeout)", ++ "type": "number" ++ }, ++ { ++ "name": "initiator-name", ++ "help": "Initiator iqn name to use when connecting", ++ "type": "string" ++ }, ++ { ++ "name": "header-digest", ++ "help": "HeaderDigest setting. {CRC32C|CRC32C-NONE|NONE-CRC32C|NONE}", ++ "type": "string" ++ }, ++ { ++ "name": "password-secret", ++ "help": "ID of the secret providing password for CHAP authentication to target", ++ "type": "string" ++ }, ++ { ++ "name": "password", ++ "help": "password for CHAP authentication to target", ++ "type": "string" ++ }, ++ { ++ "name": "user", ++ "help": "username for CHAP authentication to target", ++ "type": "string" ++ } ++ ], ++ "option": "iscsi" ++ }, ++ { ++ "parameters": [ ++ { ++ "name": "non-adaptive", ++ "type": "boolean" ++ }, ++ { ++ "name": "lossy", ++ "type": "boolean" ++ }, ++ { ++ "name": "sasl-authz", ++ "type": "string" ++ }, ++ { ++ "name": "tls-authz", ++ "type": "string" ++ }, ++ { ++ "name": "acl", ++ "type": "boolean" ++ }, ++ { ++ "name": "sasl", ++ "type": "boolean" ++ }, ++ { ++ "name": "key-delay-ms", ++ "type": "number" ++ }, ++ { ++ "name": "lock-key-sync", ++ "type": "boolean" ++ }, ++ { ++ "name": "reverse", ++ "type": "boolean" ++ }, ++ { ++ "name": "password", ++ "type": "boolean" ++ }, ++ { ++ "name": "ipv6", ++ "type": "boolean" ++ }, ++ { ++ "name": "ipv4", ++ "type": "boolean" ++ }, ++ { ++ "name": "to", ++ "type": "number" ++ }, ++ { ++ "name": "connections", ++ "type": "number" ++ }, ++ { ++ "name": "head", ++ "type": "number" ++ }, ++ { ++ "name": "display", ++ "type": "string" ++ }, ++ { ++ "name": "share", ++ "type": "string" ++ }, ++ { ++ "name": "tls-creds", ++ "type": "string" ++ }, ++ { ++ "name": "websocket", ++ "type": "string" ++ }, ++ { ++ "name": "vnc", ++ "type": "string" ++ } ++ ], ++ "option": "vnc" ++ }, ++ { ++ "parameters": [ ++ { ++ "name": "rendernode", ++ "type": "string" ++ }, ++ { ++ "name": "gl", ++ "type": "boolean" ++ }, ++ { ++ "name": "head", ++ "type": "number" ++ }, ++ { ++ "name": "display", ++ "type": "string" ++ }, ++ { ++ "name": "seamless-migration", ++ "type": "boolean" ++ }, ++ { ++ "name": "playback-compression", ++ "type": "boolean" ++ }, ++ { ++ "name": "agent-mouse", ++ "type": "boolean" ++ }, ++ { ++ "name": "streaming-video", ++ "type": "string" ++ }, ++ { ++ "name": "zlib-glz-wan-compression", ++ "type": "string" ++ }, ++ { ++ "name": "jpeg-wan-compression", ++ "type": "string" ++ }, ++ { ++ "name": "image-compression", ++ "type": "string" ++ }, ++ { ++ "name": "plaintext-channel", ++ "type": "string" ++ }, ++ { ++ "name": "tls-channel", ++ "type": "string" ++ }, ++ { ++ "name": "tls-ciphers", ++ "type": "string" ++ }, ++ { ++ "name": "x509-dh-key-file", ++ "type": "string" ++ }, ++ { ++ "name": "x509-cacert-file", ++ "type": "string" ++ }, ++ { ++ "name": "x509-cert-file", ++ "type": "string" ++ }, ++ { ++ "name": "x509-key-password", ++ "type": "string" ++ }, ++ { ++ "name": "x509-key-file", ++ "type": "string" ++ }, ++ { ++ "name": "x509-dir", ++ "type": "string" ++ }, ++ { ++ "name": "sasl", ++ "type": "boolean" ++ }, ++ { ++ "name": "disable-agent-file-xfer", ++ "type": "boolean" ++ }, ++ { ++ "name": "disable-copy-paste", ++ "type": "boolean" ++ }, ++ { ++ "name": "disable-ticketing", ++ "type": "boolean" ++ }, ++ { ++ "name": "password", ++ "type": "string" ++ }, ++ { ++ "name": "unix", ++ "type": "boolean" ++ }, ++ { ++ "name": "ipv6", ++ "type": "boolean" ++ }, ++ { ++ "name": "ipv4", ++ "type": "boolean" ++ }, ++ { ++ "name": "addr", ++ "type": "string" ++ }, ++ { ++ "name": "tls-port", ++ "type": "number" ++ }, ++ { ++ "name": "port", ++ "type": "number" ++ } ++ ], ++ "option": "spice" ++ }, ++ { ++ "parameters": [ ++ ], ++ "option": "smbios" ++ }, ++ { ++ "parameters": [ ++ ], ++ "option": "acpi" ++ }, ++ { ++ "parameters": [ ++ { ++ "name": "dmode", ++ "type": "number" ++ }, ++ { ++ "name": "fmode", ++ "type": "number" ++ }, ++ { ++ "name": "sock_fd", ++ "type": "number" ++ }, ++ { ++ "name": "socket", ++ "type": "string" ++ }, ++ { ++ "name": "readonly", ++ "type": "boolean" ++ }, ++ { ++ "name": "writeout", ++ "type": "string" ++ }, ++ { ++ "name": "security_model", ++ "type": "string" ++ }, ++ { ++ "name": "mount_tag", ++ "type": "string" ++ }, ++ { ++ "name": "path", ++ "type": "string" ++ }, ++ { ++ "name": "fsdriver", ++ "type": "string" ++ } ++ ], ++ "option": "virtfs" ++ }, ++ { ++ "parameters": [ ++ { ++ "name": "throttling.iops-size", ++ "help": "when limiting by iops max size of an I/O in bytes", ++ "type": "number" ++ }, ++ { ++ "name": "throttling.bps-write-max-length", ++ "help": "length of the bps-write-max burst period, in seconds", ++ "type": "number" ++ }, ++ { ++ "name": "throttling.bps-read-max-length", ++ "help": "length of the bps-read-max burst period, in seconds", ++ "type": "number" ++ }, ++ { ++ "name": "throttling.bps-total-max-length", ++ "help": "length of the bps-total-max burst period, in seconds", ++ "type": "number" ++ }, ++ { ++ "name": "throttling.iops-write-max-length", ++ "help": "length of the iops-write-max burst period, in seconds", ++ "type": "number" ++ }, ++ { ++ "name": "throttling.iops-read-max-length", ++ "help": "length of the iops-read-max burst period, in seconds", ++ "type": "number" ++ }, ++ { ++ "name": "throttling.iops-total-max-length", ++ "help": "length of the iops-total-max burst period, in seconds", ++ "type": "number" ++ }, ++ { ++ "name": "throttling.bps-write-max", ++ "help": "total bytes write burst", ++ "type": "number" ++ }, ++ { ++ "name": "throttling.bps-read-max", ++ "help": "total bytes read burst", ++ "type": "number" ++ }, ++ { ++ "name": "throttling.bps-total-max", ++ "help": "total bytes burst", ++ "type": "number" ++ }, ++ { ++ "name": "throttling.iops-write-max", ++ "help": "I/O operations write burst", ++ "type": "number" ++ }, ++ { ++ "name": "throttling.iops-read-max", ++ "help": "I/O operations read burst", ++ "type": "number" ++ }, ++ { ++ "name": "throttling.iops-total-max", ++ "help": "I/O operations burst", ++ "type": "number" ++ }, ++ { ++ "name": "throttling.bps-write", ++ "help": "limit write bytes per second", ++ "type": "number" ++ }, ++ { ++ "name": "throttling.bps-read", ++ "help": "limit read bytes per second", ++ "type": "number" ++ }, ++ { ++ "name": "throttling.bps-total", ++ "help": "limit total bytes per second", ++ "type": "number" ++ }, ++ { ++ "name": "throttling.iops-write", ++ "help": "limit write operations per second", ++ "type": "number" ++ }, ++ { ++ "name": "throttling.iops-read", ++ "help": "limit read operations per second", ++ "type": "number" ++ }, ++ { ++ "name": "throttling.iops-total", ++ "help": "limit total I/O operations per second", ++ "type": "number" ++ }, ++ { ++ "name": "dmode", ++ "type": "number" ++ }, ++ { ++ "name": "fmode", ++ "type": "number" ++ }, ++ { ++ "name": "sock_fd", ++ "type": "number" ++ }, ++ { ++ "name": "socket", ++ "type": "string" ++ }, ++ { ++ "name": "readonly", ++ "type": "boolean" ++ }, ++ { ++ "name": "writeout", ++ "type": "string" ++ }, ++ { ++ "name": "security_model", ++ "type": "string" ++ }, ++ { ++ "name": "path", ++ "type": "string" ++ }, ++ { ++ "name": "fsdriver", ++ "type": "string" ++ } ++ ], ++ "option": "fsdev" ++ }, ++ { ++ "parameters": [ ++ { ++ "name": "resourcecontrol", ++ "type": "string" ++ }, ++ { ++ "name": "spawn", ++ "type": "string" ++ }, ++ { ++ "name": "elevateprivileges", ++ "type": "string" ++ }, ++ { ++ "name": "obsolete", ++ "type": "string" ++ }, ++ { ++ "name": "enable", ++ "type": "boolean" ++ } ++ ], ++ "option": "sandbox" ++ }, ++ { ++ "parameters": [ ++ { ++ "name": "string", ++ "help": "Sets content of the blob to be inserted from a string", ++ "type": "string" ++ }, ++ { ++ "name": "file", ++ "help": "Sets the name of the file from which the fw_cfg blob will be loaded", ++ "type": "string" ++ }, ++ { ++ "name": "name", ++ "help": "Sets the fw_cfg name of the blob to be inserted", ++ "type": "string" ++ } ++ ], ++ "option": "fw_cfg" ++ }, ++ { ++ "parameters": [ ++ ], ++ "option": "" ++ }, ++ { ++ "parameters": [ ++ { ++ "name": "rrsnapshot", ++ "type": "string" ++ }, ++ { ++ "name": "rrfile", ++ "type": "string" ++ }, ++ { ++ "name": "rr", ++ "type": "string" ++ }, ++ { ++ "name": "sleep", ++ "type": "boolean" ++ }, ++ { ++ "name": "align", ++ "type": "boolean" ++ }, ++ { ++ "name": "shift", ++ "type": "string" ++ } ++ ], ++ "option": "icount" ++ }, ++ { ++ "parameters": [ ++ ], ++ "option": "numa" ++ }, ++ { ++ "parameters": [ ++ { ++ "name": "debug-threads", ++ "help": "When enabled, name the individual threads; defaults off.\nNOTE: The thread names are for debugging and not a\nstable API.", ++ "type": "boolean" ++ }, ++ { ++ "name": "process", ++ "help": "Sets the name of the QEMU process, as shown in top etc", ++ "type": "string" ++ }, ++ { ++ "name": "guest", ++ "help": "Sets the name of the guest.\nThis name will be displayed in the SDL window caption.\nThe name will also be used for the VNC server", ++ "type": "string" ++ } ++ ], ++ "option": "name" ++ }, ++ { ++ "parameters": [ ++ { ++ "name": "timestamp", ++ "type": "boolean" ++ } ++ ], ++ "option": "msg" ++ }, ++ { ++ "parameters": [ ++ { ++ "name": "cpu-pm", ++ "type": "boolean" ++ }, ++ { ++ "name": "mem-lock", ++ "type": "boolean" ++ } ++ ], ++ "option": "overcommit" ++ }, ++ { ++ "parameters": [ ++ { ++ "name": "mlock", ++ "type": "boolean" ++ } ++ ], ++ "option": "realtime" ++ }, ++ { ++ "parameters": [ ++ ], ++ "option": "tpmdev" ++ }, ++ { ++ "parameters": [ ++ ], ++ "option": "object" ++ }, ++ { ++ "parameters": [ ++ { ++ "name": "opaque", ++ "help": "free-form string used to describe fd", ++ "type": "string" ++ }, ++ { ++ "name": "set", ++ "help": "ID of the fd set to add fd to", ++ "type": "number" ++ }, ++ { ++ "name": "fd", ++ "help": "file descriptor of which a duplicate is added to fd set", ++ "type": "number" ++ } ++ ], ++ "option": "add-fd" ++ }, ++ { ++ "parameters": [ ++ { ++ "name": "strict", ++ "type": "boolean" ++ }, ++ { ++ "name": "reboot-timeout", ++ "type": "number" ++ }, ++ { ++ "name": "splash-time", ++ "type": "number" ++ }, ++ { ++ "name": "splash", ++ "type": "string" ++ }, ++ { ++ "name": "menu", ++ "type": "boolean" ++ }, ++ { ++ "name": "once", ++ "type": "string" ++ }, ++ { ++ "name": "order", ++ "type": "string" ++ } ++ ], ++ "option": "boot-opts" ++ }, ++ { ++ "parameters": [ ++ { ++ "name": "maxcpus", ++ "type": "number" ++ }, ++ { ++ "name": "threads", ++ "type": "number" ++ }, ++ { ++ "name": "cores", ++ "type": "number" ++ }, ++ { ++ "name": "sockets", ++ "type": "number" ++ }, ++ { ++ "name": "cpus", ++ "type": "number" ++ } ++ ], ++ "option": "smp-opts" ++ }, ++ { ++ "parameters": [ ++ { ++ "name": "maxmem", ++ "type": "size" ++ }, ++ { ++ "name": "slots", ++ "type": "number" ++ }, ++ { ++ "name": "size", ++ "type": "size" ++ } ++ ], ++ "option": "memory" ++ }, ++ { ++ "parameters": [ ++ { ++ "name": "thread", ++ "help": "Enable/disable multi-threaded TCG", ++ "type": "string" ++ }, ++ { ++ "name": "accel", ++ "help": "Select the type of accelerator", ++ "type": "string" ++ } ++ ], ++ "option": "accel" ++ }, ++ { ++ "parameters": [ ++ { ++ "name": "loadparm", ++ "help": "Up to 8 chars in set of [A-Za-z0-9. ](lower case chars converted to upper case) to pass to machine loader, boot manager, and guest kernel", ++ "type": "string" ++ }, ++ { ++ "name": "dea-key-wrap", ++ "help": "enable/disable DEA key wrapping using the CPACF wrapping key", ++ "type": "boolean" ++ }, ++ { ++ "name": "aes-key-wrap", ++ "help": "enable/disable AES key wrapping using the CPACF wrapping key", ++ "type": "boolean" ++ }, ++ { ++ "name": "suppress-vmdesc", ++ "help": "Set on to disable self-describing migration", ++ "type": "boolean" ++ }, ++ { ++ "name": "iommu", ++ "help": "Set on/off to enable/disable Intel IOMMU (VT-d)", ++ "type": "boolean" ++ }, ++ { ++ "name": "firmware", ++ "help": "firmware image", ++ "type": "string" ++ }, ++ { ++ "name": "usb", ++ "help": "Set on/off to enable/disable usb", ++ "type": "boolean" ++ }, ++ { ++ "name": "mem-merge", ++ "help": "enable/disable memory merge support", ++ "type": "boolean" ++ }, ++ { ++ "name": "dump-guest-core", ++ "help": "Include guest memory in a core dump", ++ "type": "boolean" ++ }, ++ { ++ "name": "dt_compatible", ++ "help": "Overrides the \"compatible\" property of the dt root node", ++ "type": "string" ++ }, ++ { ++ "name": "phandle_start", ++ "help": "The first phandle ID we may generate dynamically", ++ "type": "number" ++ }, ++ { ++ "name": "dumpdtb", ++ "help": "Dump current dtb to a file and quit", ++ "type": "string" ++ }, ++ { ++ "name": "dtb", ++ "help": "Linux kernel device tree file", ++ "type": "string" ++ }, ++ { ++ "name": "append", ++ "help": "Linux kernel command line", ++ "type": "string" ++ }, ++ { ++ "name": "initrd", ++ "help": "Linux initial ramdisk file", ++ "type": "string" ++ }, ++ { ++ "name": "kernel", ++ "help": "Linux kernel image file", ++ "type": "string" ++ }, ++ { ++ "name": "kvm_shadow_mem", ++ "help": "KVM shadow MMU size", ++ "type": "size" ++ }, ++ { ++ "name": "kernel_irqchip", ++ "help": "use KVM in-kernel irqchip", ++ "type": "boolean" ++ }, ++ { ++ "name": "accel", ++ "help": "accelerator list", ++ "type": "string" ++ }, ++ { ++ "name": "type", ++ "help": "emulated machine", ++ "type": "string" ++ } ++ ], ++ "option": "machine" ++ }, ++ { ++ "parameters": [ ++ { ++ "name": "romfile", ++ "type": "string" ++ }, ++ { ++ "name": "bootindex", ++ "type": "number" ++ } ++ ], ++ "option": "option-rom" ++ }, ++ { ++ "parameters": [ ++ { ++ "name": "file", ++ "type": "string" ++ }, ++ { ++ "name": "events", ++ "type": "string" ++ }, ++ { ++ "name": "enable", ++ "type": "string" ++ } ++ ], ++ "option": "trace" ++ }, ++ { ++ "parameters": [ ++ { ++ "name": "pretty", ++ "type": "boolean" ++ }, ++ { ++ "name": "chardev", ++ "type": "string" ++ }, ++ { ++ "name": "mode", ++ "type": "string" ++ } ++ ], ++ "option": "mon" ++ }, ++ { ++ "parameters": [ ++ { ++ "name": "value", ++ "type": "string" ++ }, ++ { ++ "name": "property", ++ "type": "string" ++ }, ++ { ++ "name": "driver", ++ "type": "string" ++ } ++ ], ++ "option": "global" ++ }, ++ { ++ "parameters": [ ++ { ++ "name": "driftfix", ++ "type": "string" ++ }, ++ { ++ "name": "clock", ++ "type": "string" ++ }, ++ { ++ "name": "base", ++ "type": "string" ++ } ++ ], ++ "option": "rtc" ++ }, ++ { ++ "parameters": [ ++ ], ++ "option": "net" ++ }, ++ { ++ "parameters": [ ++ ], ++ "option": "nic" ++ }, ++ { ++ "parameters": [ ++ ], ++ "option": "netdev" ++ }, ++ { ++ "parameters": [ ++ ], ++ "option": "device" ++ }, ++ { ++ "parameters": [ ++ { ++ "name": "logappend", ++ "type": "boolean" ++ }, ++ { ++ "name": "logfile", ++ "type": "string" ++ }, ++ { ++ "name": "append", ++ "type": "boolean" ++ }, ++ { ++ "name": "chardev", ++ "type": "string" ++ }, ++ { ++ "name": "size", ++ "type": "size" ++ }, ++ { ++ "name": "debug", ++ "type": "number" ++ }, ++ { ++ "name": "name", ++ "type": "string" ++ }, ++ { ++ "name": "signal", ++ "type": "boolean" ++ }, ++ { ++ "name": "mux", ++ "type": "boolean" ++ }, ++ { ++ "name": "rows", ++ "type": "number" ++ }, ++ { ++ "name": "cols", ++ "type": "number" ++ }, ++ { ++ "name": "height", ++ "type": "number" ++ }, ++ { ++ "name": "width", ++ "type": "number" ++ }, ++ { ++ "name": "websocket", ++ "type": "boolean" ++ }, ++ { ++ "name": "tls-authz", ++ "type": "string" ++ }, ++ { ++ "name": "tls-creds", ++ "type": "string" ++ }, ++ { ++ "name": "tn3270", ++ "type": "boolean" ++ }, ++ { ++ "name": "telnet", ++ "type": "boolean" ++ }, ++ { ++ "name": "reconnect", ++ "type": "number" ++ }, ++ { ++ "name": "delay", ++ "type": "boolean" ++ }, ++ { ++ "name": "server", ++ "type": "boolean" ++ }, ++ { ++ "name": "wait", ++ "type": "boolean" ++ }, ++ { ++ "name": "ipv6", ++ "type": "boolean" ++ }, ++ { ++ "name": "ipv4", ++ "type": "boolean" ++ }, ++ { ++ "name": "to", ++ "type": "number" ++ }, ++ { ++ "name": "localport", ++ "type": "string" ++ }, ++ { ++ "name": "localaddr", ++ "type": "string" ++ }, ++ { ++ "name": "fd", ++ "type": "string" ++ }, ++ { ++ "name": "port", ++ "type": "string" ++ }, ++ { ++ "name": "host", ++ "type": "string" ++ }, ++ { ++ "name": "path", ++ "type": "string" ++ }, ++ { ++ "name": "backend", ++ "type": "string" ++ } ++ ], ++ "option": "chardev" ++ }, ++ { ++ "parameters": [ ++ { ++ "name": "copy-on-read", ++ "help": "copy read data from backing file into image file", ++ "type": "boolean" ++ }, ++ { ++ "name": "werror", ++ "help": "write error action", ++ "type": "string" ++ }, ++ { ++ "name": "rerror", ++ "help": "read error action", ++ "type": "string" ++ }, ++ { ++ "name": "read-only", ++ "help": "open drive file as read-only", ++ "type": "boolean" ++ }, ++ { ++ "name": "file", ++ "help": "file name", ++ "type": "string" ++ }, ++ { ++ "name": "if", ++ "help": "interface (ide, scsi, sd, mtd, floppy, pflash, virtio)", ++ "type": "string" ++ }, ++ { ++ "name": "media", ++ "help": "media type (disk, cdrom)", ++ "type": "string" ++ }, ++ { ++ "name": "index", ++ "help": "index number", ++ "type": "number" ++ }, ++ { ++ "name": "unit", ++ "help": "unit number (i.e. lun for scsi)", ++ "type": "number" ++ }, ++ { ++ "name": "bus", ++ "help": "bus number", ++ "type": "number" ++ }, ++ { ++ "name": "stats-account-failed", ++ "help": "whether to account for failed I/O operations in the statistics", ++ "type": "boolean" ++ }, ++ { ++ "name": "stats-account-invalid", ++ "help": "whether to account for invalid I/O operations in the statistics", ++ "type": "boolean" ++ }, ++ { ++ "name": "detect-zeroes", ++ "help": "try to optimize zero writes (off, on, unmap)", ++ "type": "string" ++ }, ++ { ++ "name": "throttling.group", ++ "help": "name of the block throttling group", ++ "type": "string" ++ }, ++ { ++ "name": "throttling.iops-size", ++ "help": "when limiting by iops max size of an I/O in bytes", ++ "type": "number" ++ }, ++ { ++ "name": "throttling.bps-write-max-length", ++ "help": "length of the bps-write-max burst period, in seconds", ++ "type": "number" ++ }, ++ { ++ "name": "throttling.bps-read-max-length", ++ "help": "length of the bps-read-max burst period, in seconds", ++ "type": "number" ++ }, ++ { ++ "name": "throttling.bps-total-max-length", ++ "help": "length of the bps-total-max burst period, in seconds", ++ "type": "number" ++ }, ++ { ++ "name": "throttling.iops-write-max-length", ++ "help": "length of the iops-write-max burst period, in seconds", ++ "type": "number" ++ }, ++ { ++ "name": "throttling.iops-read-max-length", ++ "help": "length of the iops-read-max burst period, in seconds", ++ "type": "number" ++ }, ++ { ++ "name": "throttling.iops-total-max-length", ++ "help": "length of the iops-total-max burst period, in seconds", ++ "type": "number" ++ }, ++ { ++ "name": "throttling.bps-write-max", ++ "help": "total bytes write burst", ++ "type": "number" ++ }, ++ { ++ "name": "throttling.bps-read-max", ++ "help": "total bytes read burst", ++ "type": "number" ++ }, ++ { ++ "name": "throttling.bps-total-max", ++ "help": "total bytes burst", ++ "type": "number" ++ }, ++ { ++ "name": "throttling.iops-write-max", ++ "help": "I/O operations write burst", ++ "type": "number" ++ }, ++ { ++ "name": "throttling.iops-read-max", ++ "help": "I/O operations read burst", ++ "type": "number" ++ }, ++ { ++ "name": "throttling.iops-total-max", ++ "help": "I/O operations burst", ++ "type": "number" ++ }, ++ { ++ "name": "throttling.bps-write", ++ "help": "limit write bytes per second", ++ "type": "number" ++ }, ++ { ++ "name": "throttling.bps-read", ++ "help": "limit read bytes per second", ++ "type": "number" ++ }, ++ { ++ "name": "throttling.bps-total", ++ "help": "limit total bytes per second", ++ "type": "number" ++ }, ++ { ++ "name": "throttling.iops-write", ++ "help": "limit write operations per second", ++ "type": "number" ++ }, ++ { ++ "name": "throttling.iops-read", ++ "help": "limit read operations per second", ++ "type": "number" ++ }, ++ { ++ "name": "throttling.iops-total", ++ "help": "limit total I/O operations per second", ++ "type": "number" ++ }, ++ { ++ "name": "werror", ++ "help": "write error action", ++ "type": "string" ++ }, ++ { ++ "name": "format", ++ "help": "disk format (raw, qcow2, ...)", ++ "type": "string" ++ }, ++ { ++ "name": "cache.writeback", ++ "help": "Enable writeback mode", ++ "type": "boolean" ++ }, ++ { ++ "name": "aio", ++ "help": "host AIO implementation (threads, native)", ++ "type": "string" ++ }, ++ { ++ "name": "snapshot", ++ "help": "enable/disable snapshot mode", ++ "type": "boolean" ++ }, ++ { ++ "name": "force-share", ++ "help": "always accept other writers (default: off)", ++ "type": "boolean" ++ }, ++ { ++ "name": "discard", ++ "help": "discard operation (ignore/off, unmap/on)", ++ "type": "string" ++ }, ++ { ++ "name": "auto-read-only", ++ "help": "Node can become read-only if opening read-write fails", ++ "type": "boolean" ++ }, ++ { ++ "name": "cache.no-flush", ++ "help": "Ignore flush requests", ++ "type": "boolean" ++ }, ++ { ++ "name": "cache.direct", ++ "help": "Bypass software writeback cache on the host", ++ "type": "boolean" ++ }, ++ { ++ "name": "driver", ++ "help": "Block driver to use for the node", ++ "type": "string" ++ }, ++ { ++ "name": "node-name", ++ "help": "Node name of the block device node", ++ "type": "string" ++ } ++ ], ++ "option": "drive" ++ } ++ ], ++ "id": "libvirt-47" ++} ++ ++{ ++ "execute": "query-migrate-capabilities", ++ "id": "libvirt-48" ++} ++ ++{ ++ "return": [ ++ { ++ "state": false, ++ "capability": "xbzrle" ++ }, ++ { ++ "state": false, ++ "capability": "rdma-pin-all" ++ }, ++ { ++ "state": false, ++ "capability": "auto-converge" ++ }, ++ { ++ "state": false, ++ "capability": "zero-blocks" ++ }, ++ { ++ "state": false, ++ "capability": "compress" ++ }, ++ { ++ "state": false, ++ "capability": "events" ++ }, ++ { ++ "state": false, ++ "capability": "postcopy-ram" ++ }, ++ { ++ "state": false, ++ "capability": "x-colo" ++ }, ++ { ++ "state": false, ++ "capability": "release-ram" ++ }, ++ { ++ "state": false, ++ "capability": "block" ++ }, ++ { ++ "state": false, ++ "capability": "return-path" ++ }, ++ { ++ "state": false, ++ "capability": "pause-before-switchover" ++ }, ++ { ++ "state": false, ++ "capability": "multifd" ++ }, ++ { ++ "state": false, ++ "capability": "dirty-bitmaps" ++ }, ++ { ++ "state": false, ++ "capability": "postcopy-blocktime" ++ }, ++ { ++ "state": false, ++ "capability": "late-block-activate" ++ }, ++ { ++ "state": false, ++ "capability": "x-ignore-shared" ++ } ++ ], ++ "id": "libvirt-48" ++} ++ ++{ ++ "execute": "query-qmp-schema", ++ "id": "libvirt-49" ++} ++ ++{ ++ "return": [ ++ { ++ "name": "query-status", ++ "ret-type": "1", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "SHUTDOWN", ++ "meta-type": "event", ++ "arg-type": "2" ++ }, ++ { ++ "name": "POWERDOWN", ++ "meta-type": "event", ++ "arg-type": "0" ++ }, ++ { ++ "name": "RESET", ++ "meta-type": "event", ++ "arg-type": "3" ++ }, ++ { ++ "name": "STOP", ++ "meta-type": "event", ++ "arg-type": "0" ++ }, ++ { ++ "name": "RESUME", ++ "meta-type": "event", ++ "arg-type": "0" ++ }, ++ { ++ "name": "SUSPEND", ++ "meta-type": "event", ++ "arg-type": "0" ++ }, ++ { ++ "name": "SUSPEND_DISK", ++ "meta-type": "event", ++ "arg-type": "0" ++ }, ++ { ++ "name": "WAKEUP", ++ "meta-type": "event", ++ "arg-type": "0" ++ }, ++ { ++ "name": "WATCHDOG", ++ "meta-type": "event", ++ "arg-type": "4" ++ }, ++ { ++ "name": "watchdog-set-action", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "5" ++ }, ++ { ++ "name": "GUEST_PANICKED", ++ "meta-type": "event", ++ "arg-type": "6" ++ }, ++ { ++ "name": "JOB_STATUS_CHANGE", ++ "meta-type": "event", ++ "arg-type": "7" ++ }, ++ { ++ "name": "job-pause", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "8" ++ }, ++ { ++ "name": "job-resume", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "9" ++ }, ++ { ++ "name": "job-cancel", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "10" ++ }, ++ { ++ "name": "job-complete", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "11" ++ }, ++ { ++ "name": "job-dismiss", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "12" ++ }, ++ { ++ "name": "job-finalize", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "13" ++ }, ++ { ++ "name": "query-jobs", ++ "ret-type": "[14]", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "block-latency-histogram-set", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "15" ++ }, ++ { ++ "name": "query-block", ++ "ret-type": "[16]", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "query-blockstats", ++ "ret-type": "[18]", ++ "meta-type": "command", ++ "arg-type": "17" ++ }, ++ { ++ "name": "query-block-jobs", ++ "ret-type": "[19]", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "block_passwd", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "20" ++ }, ++ { ++ "name": "block_resize", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "21" ++ }, ++ { ++ "name": "blockdev-snapshot-sync", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "22" ++ }, ++ { ++ "name": "blockdev-snapshot", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "23" ++ }, ++ { ++ "name": "change-backing-file", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "24" ++ }, ++ { ++ "name": "block-commit", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "25" ++ }, ++ { ++ "name": "drive-backup", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "26" ++ }, ++ { ++ "name": "blockdev-backup", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "27" ++ }, ++ { ++ "name": "query-named-block-nodes", ++ "ret-type": "[28]", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "x-debug-query-block-graph", ++ "ret-type": "29", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "drive-mirror", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "30" ++ }, ++ { ++ "name": "block-dirty-bitmap-add", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "31" ++ }, ++ { ++ "name": "block-dirty-bitmap-remove", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "32" ++ }, ++ { ++ "name": "block-dirty-bitmap-clear", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "32" ++ }, ++ { ++ "name": "block-dirty-bitmap-enable", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "32" ++ }, ++ { ++ "name": "block-dirty-bitmap-disable", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "32" ++ }, ++ { ++ "name": "block-dirty-bitmap-merge", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "33" ++ }, ++ { ++ "name": "x-debug-block-dirty-bitmap-sha256", ++ "ret-type": "34", ++ "meta-type": "command", ++ "arg-type": "32" ++ }, ++ { ++ "name": "blockdev-mirror", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "35" ++ }, ++ { ++ "name": "block_set_io_throttle", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "36" ++ }, ++ { ++ "name": "block-stream", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "37" ++ }, ++ { ++ "name": "block-job-set-speed", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "38" ++ }, ++ { ++ "name": "block-job-cancel", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "39" ++ }, ++ { ++ "name": "block-job-pause", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "40" ++ }, ++ { ++ "name": "block-job-resume", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "41" ++ }, ++ { ++ "name": "block-job-complete", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "42" ++ }, ++ { ++ "name": "block-job-dismiss", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "43" ++ }, ++ { ++ "name": "block-job-finalize", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "44" ++ }, ++ { ++ "name": "blockdev-add", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "45" ++ }, ++ { ++ "name": "x-blockdev-reopen", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "45" ++ }, ++ { ++ "name": "blockdev-del", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "46" ++ }, ++ { ++ "name": "blockdev-create", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "47" ++ }, ++ { ++ "name": "blockdev-open-tray", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "48" ++ }, ++ { ++ "name": "blockdev-close-tray", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "49" ++ }, ++ { ++ "name": "blockdev-remove-medium", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "50" ++ }, ++ { ++ "name": "blockdev-insert-medium", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "51" ++ }, ++ { ++ "name": "blockdev-change-medium", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "52" ++ }, ++ { ++ "name": "BLOCK_IMAGE_CORRUPTED", ++ "meta-type": "event", ++ "arg-type": "53" ++ }, ++ { ++ "name": "BLOCK_IO_ERROR", ++ "meta-type": "event", ++ "arg-type": "54" ++ }, ++ { ++ "name": "BLOCK_JOB_COMPLETED", ++ "meta-type": "event", ++ "arg-type": "55" ++ }, ++ { ++ "name": "BLOCK_JOB_CANCELLED", ++ "meta-type": "event", ++ "arg-type": "56" ++ }, ++ { ++ "name": "BLOCK_JOB_ERROR", ++ "meta-type": "event", ++ "arg-type": "57" ++ }, ++ { ++ "name": "BLOCK_JOB_READY", ++ "meta-type": "event", ++ "arg-type": "58" ++ }, ++ { ++ "name": "BLOCK_JOB_PENDING", ++ "meta-type": "event", ++ "arg-type": "59" ++ }, ++ { ++ "name": "BLOCK_WRITE_THRESHOLD", ++ "meta-type": "event", ++ "arg-type": "60" ++ }, ++ { ++ "name": "block-set-write-threshold", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "61" ++ }, ++ { ++ "name": "x-blockdev-change", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "62" ++ }, ++ { ++ "name": "x-blockdev-set-iothread", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "63" ++ }, ++ { ++ "name": "query-pr-managers", ++ "ret-type": "[64]", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "blockdev-snapshot-internal-sync", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "65" ++ }, ++ { ++ "name": "blockdev-snapshot-delete-internal-sync", ++ "ret-type": "67", ++ "meta-type": "command", ++ "arg-type": "66" ++ }, ++ { ++ "name": "eject", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "68" ++ }, ++ { ++ "name": "nbd-server-start", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "69" ++ }, ++ { ++ "name": "nbd-server-add", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "70" ++ }, ++ { ++ "name": "nbd-server-remove", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "71" ++ }, ++ { ++ "name": "nbd-server-stop", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "DEVICE_TRAY_MOVED", ++ "meta-type": "event", ++ "arg-type": "72" ++ }, ++ { ++ "name": "PR_MANAGER_STATUS_CHANGED", ++ "meta-type": "event", ++ "arg-type": "73" ++ }, ++ { ++ "name": "QUORUM_FAILURE", ++ "meta-type": "event", ++ "arg-type": "74" ++ }, ++ { ++ "name": "QUORUM_REPORT_BAD", ++ "meta-type": "event", ++ "arg-type": "75" ++ }, ++ { ++ "name": "query-chardev", ++ "ret-type": "[76]", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "query-chardev-backends", ++ "ret-type": "[77]", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "ringbuf-write", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "78" ++ }, ++ { ++ "name": "ringbuf-read", ++ "ret-type": "str", ++ "meta-type": "command", ++ "arg-type": "79" ++ }, ++ { ++ "name": "chardev-add", ++ "ret-type": "81", ++ "meta-type": "command", ++ "arg-type": "80" ++ }, ++ { ++ "name": "chardev-change", ++ "ret-type": "81", ++ "meta-type": "command", ++ "arg-type": "82" ++ }, ++ { ++ "name": "chardev-remove", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "83" ++ }, ++ { ++ "name": "chardev-send-break", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "84" ++ }, ++ { ++ "name": "VSERPORT_CHANGE", ++ "meta-type": "event", ++ "arg-type": "85" ++ }, ++ { ++ "name": "set_link", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "86" ++ }, ++ { ++ "name": "netdev_add", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "87" ++ }, ++ { ++ "name": "netdev_del", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "88" ++ }, ++ { ++ "name": "query-rx-filter", ++ "ret-type": "[90]", ++ "meta-type": "command", ++ "arg-type": "89" ++ }, ++ { ++ "name": "NIC_RX_FILTER_CHANGED", ++ "meta-type": "event", ++ "arg-type": "91" ++ }, ++ { ++ "name": "announce-self", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "92" ++ }, ++ { ++ "name": "RDMA_GID_STATUS_CHANGED", ++ "meta-type": "event", ++ "arg-type": "93" ++ }, ++ { ++ "name": "query-rocker", ++ "ret-type": "95", ++ "meta-type": "command", ++ "arg-type": "94" ++ }, ++ { ++ "name": "query-rocker-ports", ++ "ret-type": "[97]", ++ "meta-type": "command", ++ "arg-type": "96" ++ }, ++ { ++ "name": "query-rocker-of-dpa-flows", ++ "ret-type": "[99]", ++ "meta-type": "command", ++ "arg-type": "98" ++ }, ++ { ++ "name": "query-rocker-of-dpa-groups", ++ "ret-type": "[101]", ++ "meta-type": "command", ++ "arg-type": "100" ++ }, ++ { ++ "name": "query-tpm-models", ++ "ret-type": "[102]", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "query-tpm-types", ++ "ret-type": "[103]", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "query-tpm", ++ "ret-type": "[104]", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "set_password", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "105" ++ }, ++ { ++ "name": "expire_password", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "106" ++ }, ++ { ++ "name": "screendump", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "107" ++ }, ++ { ++ "name": "query-spice", ++ "ret-type": "108", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "SPICE_CONNECTED", ++ "meta-type": "event", ++ "arg-type": "109" ++ }, ++ { ++ "name": "SPICE_INITIALIZED", ++ "meta-type": "event", ++ "arg-type": "110" ++ }, ++ { ++ "name": "SPICE_DISCONNECTED", ++ "meta-type": "event", ++ "arg-type": "111" ++ }, ++ { ++ "name": "SPICE_MIGRATE_COMPLETED", ++ "meta-type": "event", ++ "arg-type": "0" ++ }, ++ { ++ "name": "query-vnc", ++ "ret-type": "112", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "query-vnc-servers", ++ "ret-type": "[113]", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "change-vnc-password", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "114" ++ }, ++ { ++ "name": "VNC_CONNECTED", ++ "meta-type": "event", ++ "arg-type": "115" ++ }, ++ { ++ "name": "VNC_INITIALIZED", ++ "meta-type": "event", ++ "arg-type": "116" ++ }, ++ { ++ "name": "VNC_DISCONNECTED", ++ "meta-type": "event", ++ "arg-type": "117" ++ }, ++ { ++ "name": "query-mice", ++ "ret-type": "[118]", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "send-key", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "119" ++ }, ++ { ++ "name": "input-send-event", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "120" ++ }, ++ { ++ "name": "query-display-options", ++ "ret-type": "121", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "query-migrate", ++ "ret-type": "122", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "migrate-set-capabilities", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "123" ++ }, ++ { ++ "name": "query-migrate-capabilities", ++ "ret-type": "[124]", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "migrate-set-parameters", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "125" ++ }, ++ { ++ "name": "query-migrate-parameters", ++ "ret-type": "126", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "client_migrate_info", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "127" ++ }, ++ { ++ "name": "migrate-start-postcopy", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "MIGRATION", ++ "meta-type": "event", ++ "arg-type": "128" ++ }, ++ { ++ "name": "MIGRATION_PASS", ++ "meta-type": "event", ++ "arg-type": "129" ++ }, ++ { ++ "name": "COLO_EXIT", ++ "meta-type": "event", ++ "arg-type": "130" ++ }, ++ { ++ "name": "x-colo-lost-heartbeat", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "migrate_cancel", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "migrate-continue", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "131" ++ }, ++ { ++ "name": "migrate_set_downtime", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "132" ++ }, ++ { ++ "name": "migrate_set_speed", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "133" ++ }, ++ { ++ "name": "migrate-set-cache-size", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "134" ++ }, ++ { ++ "name": "query-migrate-cache-size", ++ "ret-type": "int", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "migrate", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "135" ++ }, ++ { ++ "name": "migrate-incoming", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "136" ++ }, ++ { ++ "name": "xen-save-devices-state", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "137" ++ }, ++ { ++ "name": "xen-set-replication", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "138" ++ }, ++ { ++ "name": "query-xen-replication-status", ++ "ret-type": "139", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "xen-colo-do-checkpoint", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "query-colo-status", ++ "ret-type": "140", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "migrate-recover", ++ "ret-type": "0", ++ "allow-oob": true, ++ "meta-type": "command", ++ "arg-type": "141" ++ }, ++ { ++ "name": "migrate-pause", ++ "ret-type": "0", ++ "allow-oob": true, ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "transaction", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "142" ++ }, ++ { ++ "name": "trace-event-get-state", ++ "ret-type": "[144]", ++ "meta-type": "command", ++ "arg-type": "143" ++ }, ++ { ++ "name": "trace-event-set-state", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "145" ++ }, ++ { ++ "name": "query-qmp-schema", ++ "ret-type": "[146]", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "qmp_capabilities", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "147" ++ }, ++ { ++ "name": "query-version", ++ "ret-type": "148", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "query-commands", ++ "ret-type": "[149]", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "add_client", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "150" ++ }, ++ { ++ "name": "query-name", ++ "ret-type": "151", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "query-kvm", ++ "ret-type": "152", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "query-uuid", ++ "ret-type": "153", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "query-events", ++ "ret-type": "[154]", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "query-cpus", ++ "ret-type": "[155]", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "query-cpus-fast", ++ "ret-type": "[156]", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "query-iothreads", ++ "ret-type": "[157]", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "query-balloon", ++ "ret-type": "158", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "BALLOON_CHANGE", ++ "meta-type": "event", ++ "arg-type": "159" ++ }, ++ { ++ "name": "query-pci", ++ "ret-type": "[160]", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "quit", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "stop", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "system_reset", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "system_powerdown", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "cpu-add", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "161" ++ }, ++ { ++ "name": "memsave", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "162" ++ }, ++ { ++ "name": "pmemsave", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "163" ++ }, ++ { ++ "name": "cont", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "x-exit-preconfig", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "system_wakeup", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "inject-nmi", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "balloon", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "164" ++ }, ++ { ++ "name": "human-monitor-command", ++ "ret-type": "str", ++ "meta-type": "command", ++ "arg-type": "165" ++ }, ++ { ++ "name": "qom-list", ++ "ret-type": "[167]", ++ "meta-type": "command", ++ "arg-type": "166" ++ }, ++ { ++ "name": "qom-get", ++ "ret-type": "any", ++ "meta-type": "command", ++ "arg-type": "168" ++ }, ++ { ++ "name": "qom-set", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "169" ++ }, ++ { ++ "name": "change", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "170" ++ }, ++ { ++ "name": "qom-list-types", ++ "ret-type": "[172]", ++ "meta-type": "command", ++ "arg-type": "171" ++ }, ++ { ++ "name": "device-list-properties", ++ "ret-type": "[167]", ++ "meta-type": "command", ++ "arg-type": "173" ++ }, ++ { ++ "name": "qom-list-properties", ++ "ret-type": "[167]", ++ "meta-type": "command", ++ "arg-type": "174" ++ }, ++ { ++ "name": "xen-set-global-dirty-log", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "175" ++ }, ++ { ++ "name": "device_add", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "176" ++ }, ++ { ++ "name": "device_del", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "177" ++ }, ++ { ++ "name": "DEVICE_DELETED", ++ "meta-type": "event", ++ "arg-type": "178" ++ }, ++ { ++ "name": "dump-guest-memory", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "179" ++ }, ++ { ++ "name": "query-dump", ++ "ret-type": "180", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "DUMP_COMPLETED", ++ "meta-type": "event", ++ "arg-type": "181" ++ }, ++ { ++ "name": "query-dump-guest-memory-capability", ++ "ret-type": "182", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "object-add", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "183" ++ }, ++ { ++ "name": "object-del", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "184" ++ }, ++ { ++ "name": "getfd", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "185" ++ }, ++ { ++ "name": "closefd", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "186" ++ }, ++ { ++ "name": "query-machines", ++ "ret-type": "[187]", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "query-current-machine", ++ "ret-type": "188", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "query-memory-size-summary", ++ "ret-type": "189", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "add-fd", ++ "ret-type": "191", ++ "meta-type": "command", ++ "arg-type": "190" ++ }, ++ { ++ "name": "remove-fd", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "192" ++ }, ++ { ++ "name": "query-fdsets", ++ "ret-type": "[193]", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "query-target", ++ "ret-type": "194", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "query-command-line-options", ++ "ret-type": "[196]", ++ "meta-type": "command", ++ "arg-type": "195" ++ }, ++ { ++ "name": "query-memdev", ++ "ret-type": "[197]", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "query-memory-devices", ++ "ret-type": "[198]", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "MEM_UNPLUG_ERROR", ++ "meta-type": "event", ++ "arg-type": "199" ++ }, ++ { ++ "name": "query-acpi-ospm-status", ++ "ret-type": "[200]", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "ACPI_DEVICE_OST", ++ "meta-type": "event", ++ "arg-type": "201" ++ }, ++ { ++ "name": "xen-load-devices-state", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "202" ++ }, ++ { ++ "name": "query-hotpluggable-cpus", ++ "ret-type": "[203]", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "query-vm-generation-id", ++ "ret-type": "204", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "set-numa-node", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "205" ++ }, ++ { ++ "name": "RTC_CHANGE", ++ "meta-type": "event", ++ "arg-type": "206" ++ }, ++ { ++ "name": "rtc-reset-reinjection", ++ "ret-type": "0", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "query-sev", ++ "ret-type": "207", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "query-sev-launch-measure", ++ "ret-type": "208", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "query-sev-capabilities", ++ "ret-type": "209", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "query-cpu-model-expansion", ++ "ret-type": "217", ++ "meta-type": "command", ++ "arg-type": "216" ++ }, ++ { ++ "name": "query-cpu-definitions", ++ "ret-type": "[218]", ++ "meta-type": "command", ++ "arg-type": "0" ++ }, ++ { ++ "name": "0", ++ "members": [ ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "1", ++ "members": [ ++ { ++ "name": "running", ++ "type": "bool" ++ }, ++ { ++ "name": "singlestep", ++ "type": "bool" ++ }, ++ { ++ "name": "status", ++ "type": "219" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "2", ++ "members": [ ++ { ++ "name": "guest", ++ "type": "bool" ++ }, ++ { ++ "name": "reason", ++ "type": "220" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "3", ++ "members": [ ++ { ++ "name": "guest", ++ "type": "bool" ++ }, ++ { ++ "name": "reason", ++ "type": "220" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "4", ++ "members": [ ++ { ++ "name": "action", ++ "type": "221" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "5", ++ "members": [ ++ { ++ "name": "action", ++ "type": "221" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "6", ++ "members": [ ++ { ++ "name": "action", ++ "type": "222" ++ }, ++ { ++ "name": "info", ++ "default": null, ++ "type": "223" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "7", ++ "members": [ ++ { ++ "name": "id", ++ "type": "str" ++ }, ++ { ++ "name": "status", ++ "type": "224" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "8", ++ "members": [ ++ { ++ "name": "id", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "9", ++ "members": [ ++ { ++ "name": "id", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "10", ++ "members": [ ++ { ++ "name": "id", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "11", ++ "members": [ ++ { ++ "name": "id", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "12", ++ "members": [ ++ { ++ "name": "id", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "13", ++ "members": [ ++ { ++ "name": "id", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[14]", ++ "element-type": "14", ++ "meta-type": "array" ++ }, ++ { ++ "name": "14", ++ "members": [ ++ { ++ "name": "id", ++ "type": "str" ++ }, ++ { ++ "name": "type", ++ "type": "225" ++ }, ++ { ++ "name": "status", ++ "type": "224" ++ }, ++ { ++ "name": "current-progress", ++ "type": "int" ++ }, ++ { ++ "name": "total-progress", ++ "type": "int" ++ }, ++ { ++ "name": "error", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "15", ++ "members": [ ++ { ++ "name": "id", ++ "type": "str" ++ }, ++ { ++ "name": "boundaries", ++ "default": null, ++ "type": "[int]" ++ }, ++ { ++ "name": "boundaries-read", ++ "default": null, ++ "type": "[int]" ++ }, ++ { ++ "name": "boundaries-write", ++ "default": null, ++ "type": "[int]" ++ }, ++ { ++ "name": "boundaries-flush", ++ "default": null, ++ "type": "[int]" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[16]", ++ "element-type": "16", ++ "meta-type": "array" ++ }, ++ { ++ "name": "16", ++ "members": [ ++ { ++ "name": "device", ++ "type": "str" ++ }, ++ { ++ "name": "qdev", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "type", ++ "type": "str" ++ }, ++ { ++ "name": "removable", ++ "type": "bool" ++ }, ++ { ++ "name": "locked", ++ "type": "bool" ++ }, ++ { ++ "name": "inserted", ++ "default": null, ++ "type": "28" ++ }, ++ { ++ "name": "tray_open", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "io-status", ++ "default": null, ++ "type": "226" ++ }, ++ { ++ "name": "dirty-bitmaps", ++ "default": null, ++ "type": "[227]" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "17", ++ "members": [ ++ { ++ "name": "query-nodes", ++ "default": null, ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[18]", ++ "element-type": "18", ++ "meta-type": "array" ++ }, ++ { ++ "name": "18", ++ "members": [ ++ { ++ "name": "device", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "qdev", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "node-name", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "stats", ++ "type": "228" ++ }, ++ { ++ "name": "parent", ++ "default": null, ++ "type": "18" ++ }, ++ { ++ "name": "backing", ++ "default": null, ++ "type": "18" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[19]", ++ "element-type": "19", ++ "meta-type": "array" ++ }, ++ { ++ "name": "19", ++ "members": [ ++ { ++ "name": "type", ++ "type": "str" ++ }, ++ { ++ "name": "device", ++ "type": "str" ++ }, ++ { ++ "name": "len", ++ "type": "int" ++ }, ++ { ++ "name": "offset", ++ "type": "int" ++ }, ++ { ++ "name": "busy", ++ "type": "bool" ++ }, ++ { ++ "name": "paused", ++ "type": "bool" ++ }, ++ { ++ "name": "speed", ++ "type": "int" ++ }, ++ { ++ "name": "io-status", ++ "type": "226" ++ }, ++ { ++ "name": "ready", ++ "type": "bool" ++ }, ++ { ++ "name": "status", ++ "type": "224" ++ }, ++ { ++ "name": "auto-finalize", ++ "type": "bool" ++ }, ++ { ++ "name": "auto-dismiss", ++ "type": "bool" ++ }, ++ { ++ "name": "error", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "20", ++ "members": [ ++ { ++ "name": "device", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "node-name", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "password", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "21", ++ "members": [ ++ { ++ "name": "device", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "node-name", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "size", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "22", ++ "members": [ ++ { ++ "name": "device", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "node-name", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "snapshot-file", ++ "type": "str" ++ }, ++ { ++ "name": "snapshot-node-name", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "format", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "mode", ++ "default": null, ++ "type": "229" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "23", ++ "members": [ ++ { ++ "name": "node", ++ "type": "str" ++ }, ++ { ++ "name": "overlay", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "24", ++ "members": [ ++ { ++ "name": "device", ++ "type": "str" ++ }, ++ { ++ "name": "image-node-name", ++ "type": "str" ++ }, ++ { ++ "name": "backing-file", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "25", ++ "members": [ ++ { ++ "name": "job-id", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "device", ++ "type": "str" ++ }, ++ { ++ "name": "base-node", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "base", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "top-node", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "top", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "backing-file", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "speed", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "filter-node-name", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "auto-finalize", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "auto-dismiss", ++ "default": null, ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "26", ++ "members": [ ++ { ++ "name": "job-id", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "device", ++ "type": "str" ++ }, ++ { ++ "name": "target", ++ "type": "str" ++ }, ++ { ++ "name": "format", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "sync", ++ "type": "230" ++ }, ++ { ++ "name": "mode", ++ "default": null, ++ "type": "229" ++ }, ++ { ++ "name": "speed", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "bitmap", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "compress", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "on-source-error", ++ "default": null, ++ "type": "231" ++ }, ++ { ++ "name": "on-target-error", ++ "default": null, ++ "type": "231" ++ }, ++ { ++ "name": "auto-finalize", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "auto-dismiss", ++ "default": null, ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "27", ++ "members": [ ++ { ++ "name": "job-id", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "device", ++ "type": "str" ++ }, ++ { ++ "name": "target", ++ "type": "str" ++ }, ++ { ++ "name": "sync", ++ "type": "230" ++ }, ++ { ++ "name": "speed", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "bitmap", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "compress", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "on-source-error", ++ "default": null, ++ "type": "231" ++ }, ++ { ++ "name": "on-target-error", ++ "default": null, ++ "type": "231" ++ }, ++ { ++ "name": "auto-finalize", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "auto-dismiss", ++ "default": null, ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[28]", ++ "element-type": "28", ++ "meta-type": "array" ++ }, ++ { ++ "name": "28", ++ "members": [ ++ { ++ "name": "file", ++ "type": "str" ++ }, ++ { ++ "name": "node-name", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "ro", ++ "type": "bool" ++ }, ++ { ++ "name": "drv", ++ "type": "str" ++ }, ++ { ++ "name": "backing_file", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "backing_file_depth", ++ "type": "int" ++ }, ++ { ++ "name": "encrypted", ++ "type": "bool" ++ }, ++ { ++ "name": "encryption_key_missing", ++ "type": "bool" ++ }, ++ { ++ "name": "detect_zeroes", ++ "type": "232" ++ }, ++ { ++ "name": "bps", ++ "type": "int" ++ }, ++ { ++ "name": "bps_rd", ++ "type": "int" ++ }, ++ { ++ "name": "bps_wr", ++ "type": "int" ++ }, ++ { ++ "name": "iops", ++ "type": "int" ++ }, ++ { ++ "name": "iops_rd", ++ "type": "int" ++ }, ++ { ++ "name": "iops_wr", ++ "type": "int" ++ }, ++ { ++ "name": "image", ++ "type": "233" ++ }, ++ { ++ "name": "bps_max", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "bps_rd_max", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "bps_wr_max", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "iops_max", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "iops_rd_max", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "iops_wr_max", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "bps_max_length", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "bps_rd_max_length", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "bps_wr_max_length", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "iops_max_length", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "iops_rd_max_length", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "iops_wr_max_length", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "iops_size", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "group", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "cache", ++ "type": "234" ++ }, ++ { ++ "name": "write_threshold", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "29", ++ "members": [ ++ { ++ "name": "nodes", ++ "type": "[235]" ++ }, ++ { ++ "name": "edges", ++ "type": "[236]" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "30", ++ "members": [ ++ { ++ "name": "job-id", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "device", ++ "type": "str" ++ }, ++ { ++ "name": "target", ++ "type": "str" ++ }, ++ { ++ "name": "format", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "node-name", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "replaces", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "sync", ++ "type": "230" ++ }, ++ { ++ "name": "mode", ++ "default": null, ++ "type": "229" ++ }, ++ { ++ "name": "speed", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "granularity", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "buf-size", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "on-source-error", ++ "default": null, ++ "type": "231" ++ }, ++ { ++ "name": "on-target-error", ++ "default": null, ++ "type": "231" ++ }, ++ { ++ "name": "unmap", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "copy-mode", ++ "default": null, ++ "type": "237" ++ }, ++ { ++ "name": "auto-finalize", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "auto-dismiss", ++ "default": null, ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "31", ++ "members": [ ++ { ++ "name": "node", ++ "type": "str" ++ }, ++ { ++ "name": "name", ++ "type": "str" ++ }, ++ { ++ "name": "granularity", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "persistent", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "autoload", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "disabled", ++ "default": null, ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "32", ++ "members": [ ++ { ++ "name": "node", ++ "type": "str" ++ }, ++ { ++ "name": "name", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "33", ++ "members": [ ++ { ++ "name": "node", ++ "type": "str" ++ }, ++ { ++ "name": "target", ++ "type": "str" ++ }, ++ { ++ "name": "bitmaps", ++ "type": "[238]" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "34", ++ "members": [ ++ { ++ "name": "sha256", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "35", ++ "members": [ ++ { ++ "name": "job-id", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "device", ++ "type": "str" ++ }, ++ { ++ "name": "target", ++ "type": "str" ++ }, ++ { ++ "name": "replaces", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "sync", ++ "type": "230" ++ }, ++ { ++ "name": "speed", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "granularity", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "buf-size", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "on-source-error", ++ "default": null, ++ "type": "231" ++ }, ++ { ++ "name": "on-target-error", ++ "default": null, ++ "type": "231" ++ }, ++ { ++ "name": "filter-node-name", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "copy-mode", ++ "default": null, ++ "type": "237" ++ }, ++ { ++ "name": "auto-finalize", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "auto-dismiss", ++ "default": null, ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "36", ++ "members": [ ++ { ++ "name": "device", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "id", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "bps", ++ "type": "int" ++ }, ++ { ++ "name": "bps_rd", ++ "type": "int" ++ }, ++ { ++ "name": "bps_wr", ++ "type": "int" ++ }, ++ { ++ "name": "iops", ++ "type": "int" ++ }, ++ { ++ "name": "iops_rd", ++ "type": "int" ++ }, ++ { ++ "name": "iops_wr", ++ "type": "int" ++ }, ++ { ++ "name": "bps_max", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "bps_rd_max", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "bps_wr_max", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "iops_max", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "iops_rd_max", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "iops_wr_max", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "bps_max_length", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "bps_rd_max_length", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "bps_wr_max_length", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "iops_max_length", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "iops_rd_max_length", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "iops_wr_max_length", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "iops_size", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "group", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "37", ++ "members": [ ++ { ++ "name": "job-id", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "device", ++ "type": "str" ++ }, ++ { ++ "name": "base", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "base-node", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "backing-file", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "speed", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "on-error", ++ "default": null, ++ "type": "231" ++ }, ++ { ++ "name": "auto-finalize", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "auto-dismiss", ++ "default": null, ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "38", ++ "members": [ ++ { ++ "name": "device", ++ "type": "str" ++ }, ++ { ++ "name": "speed", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "39", ++ "members": [ ++ { ++ "name": "device", ++ "type": "str" ++ }, ++ { ++ "name": "force", ++ "default": null, ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "40", ++ "members": [ ++ { ++ "name": "device", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "41", ++ "members": [ ++ { ++ "name": "device", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "42", ++ "members": [ ++ { ++ "name": "device", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "43", ++ "members": [ ++ { ++ "name": "id", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "44", ++ "members": [ ++ { ++ "name": "id", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "45", ++ "tag": "driver", ++ "variants": [ ++ { ++ "case": "blkdebug", ++ "type": "242" ++ }, ++ { ++ "case": "blklogwrites", ++ "type": "243" ++ }, ++ { ++ "case": "blkverify", ++ "type": "244" ++ }, ++ { ++ "case": "bochs", ++ "type": "245" ++ }, ++ { ++ "case": "cloop", ++ "type": "245" ++ }, ++ { ++ "case": "copy-on-read", ++ "type": "245" ++ }, ++ { ++ "case": "dmg", ++ "type": "245" ++ }, ++ { ++ "case": "file", ++ "type": "246" ++ }, ++ { ++ "case": "ftp", ++ "type": "247" ++ }, ++ { ++ "case": "ftps", ++ "type": "248" ++ }, ++ { ++ "case": "gluster", ++ "type": "249" ++ }, ++ { ++ "case": "host_cdrom", ++ "type": "246" ++ }, ++ { ++ "case": "host_device", ++ "type": "246" ++ }, ++ { ++ "case": "http", ++ "type": "250" ++ }, ++ { ++ "case": "https", ++ "type": "251" ++ }, ++ { ++ "case": "iscsi", ++ "type": "252" ++ }, ++ { ++ "case": "luks", ++ "type": "253" ++ }, ++ { ++ "case": "nbd", ++ "type": "254" ++ }, ++ { ++ "case": "nfs", ++ "type": "255" ++ }, ++ { ++ "case": "null-aio", ++ "type": "256" ++ }, ++ { ++ "case": "null-co", ++ "type": "256" ++ }, ++ { ++ "case": "nvme", ++ "type": "257" ++ }, ++ { ++ "case": "parallels", ++ "type": "245" ++ }, ++ { ++ "case": "qcow2", ++ "type": "258" ++ }, ++ { ++ "case": "qcow", ++ "type": "259" ++ }, ++ { ++ "case": "qed", ++ "type": "260" ++ }, ++ { ++ "case": "quorum", ++ "type": "261" ++ }, ++ { ++ "case": "raw", ++ "type": "262" ++ }, ++ { ++ "case": "rbd", ++ "type": "263" ++ }, ++ { ++ "case": "replication", ++ "type": "264" ++ }, ++ { ++ "case": "sheepdog", ++ "type": "265" ++ }, ++ { ++ "case": "ssh", ++ "type": "266" ++ }, ++ { ++ "case": "throttle", ++ "type": "267" ++ }, ++ { ++ "case": "vdi", ++ "type": "245" ++ }, ++ { ++ "case": "vhdx", ++ "type": "245" ++ }, ++ { ++ "case": "vmdk", ++ "type": "260" ++ }, ++ { ++ "case": "vpc", ++ "type": "245" ++ }, ++ { ++ "case": "vvfat", ++ "type": "268" ++ }, ++ { ++ "case": "vxhs", ++ "type": "269" ++ } ++ ], ++ "members": [ ++ { ++ "name": "driver", ++ "type": "239" ++ }, ++ { ++ "name": "node-name", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "discard", ++ "default": null, ++ "type": "240" ++ }, ++ { ++ "name": "cache", ++ "default": null, ++ "type": "241" ++ }, ++ { ++ "name": "read-only", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "auto-read-only", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "force-share", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "detect-zeroes", ++ "default": null, ++ "type": "232" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "46", ++ "members": [ ++ { ++ "name": "node-name", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "47", ++ "members": [ ++ { ++ "name": "job-id", ++ "type": "str" ++ }, ++ { ++ "name": "options", ++ "type": "270" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "48", ++ "members": [ ++ { ++ "name": "device", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "id", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "force", ++ "default": null, ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "49", ++ "members": [ ++ { ++ "name": "device", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "id", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "50", ++ "members": [ ++ { ++ "name": "id", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "51", ++ "members": [ ++ { ++ "name": "id", ++ "type": "str" ++ }, ++ { ++ "name": "node-name", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "52", ++ "members": [ ++ { ++ "name": "device", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "id", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "filename", ++ "type": "str" ++ }, ++ { ++ "name": "format", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "read-only-mode", ++ "default": null, ++ "type": "271" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "53", ++ "members": [ ++ { ++ "name": "device", ++ "type": "str" ++ }, ++ { ++ "name": "node-name", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "msg", ++ "type": "str" ++ }, ++ { ++ "name": "offset", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "size", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "fatal", ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "54", ++ "members": [ ++ { ++ "name": "device", ++ "type": "str" ++ }, ++ { ++ "name": "node-name", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "operation", ++ "type": "272" ++ }, ++ { ++ "name": "action", ++ "type": "273" ++ }, ++ { ++ "name": "nospace", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "reason", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "55", ++ "members": [ ++ { ++ "name": "type", ++ "type": "225" ++ }, ++ { ++ "name": "device", ++ "type": "str" ++ }, ++ { ++ "name": "len", ++ "type": "int" ++ }, ++ { ++ "name": "offset", ++ "type": "int" ++ }, ++ { ++ "name": "speed", ++ "type": "int" ++ }, ++ { ++ "name": "error", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "56", ++ "members": [ ++ { ++ "name": "type", ++ "type": "225" ++ }, ++ { ++ "name": "device", ++ "type": "str" ++ }, ++ { ++ "name": "len", ++ "type": "int" ++ }, ++ { ++ "name": "offset", ++ "type": "int" ++ }, ++ { ++ "name": "speed", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "57", ++ "members": [ ++ { ++ "name": "device", ++ "type": "str" ++ }, ++ { ++ "name": "operation", ++ "type": "272" ++ }, ++ { ++ "name": "action", ++ "type": "273" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "58", ++ "members": [ ++ { ++ "name": "type", ++ "type": "225" ++ }, ++ { ++ "name": "device", ++ "type": "str" ++ }, ++ { ++ "name": "len", ++ "type": "int" ++ }, ++ { ++ "name": "offset", ++ "type": "int" ++ }, ++ { ++ "name": "speed", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "59", ++ "members": [ ++ { ++ "name": "type", ++ "type": "225" ++ }, ++ { ++ "name": "id", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "60", ++ "members": [ ++ { ++ "name": "node-name", ++ "type": "str" ++ }, ++ { ++ "name": "amount-exceeded", ++ "type": "int" ++ }, ++ { ++ "name": "write-threshold", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "61", ++ "members": [ ++ { ++ "name": "node-name", ++ "type": "str" ++ }, ++ { ++ "name": "write-threshold", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "62", ++ "members": [ ++ { ++ "name": "parent", ++ "type": "str" ++ }, ++ { ++ "name": "child", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "node", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "63", ++ "members": [ ++ { ++ "name": "node-name", ++ "type": "str" ++ }, ++ { ++ "name": "iothread", ++ "type": "274" ++ }, ++ { ++ "name": "force", ++ "default": null, ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[64]", ++ "element-type": "64", ++ "meta-type": "array" ++ }, ++ { ++ "name": "64", ++ "members": [ ++ { ++ "name": "id", ++ "type": "str" ++ }, ++ { ++ "name": "connected", ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "65", ++ "members": [ ++ { ++ "name": "device", ++ "type": "str" ++ }, ++ { ++ "name": "name", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "66", ++ "members": [ ++ { ++ "name": "device", ++ "type": "str" ++ }, ++ { ++ "name": "id", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "name", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "67", ++ "members": [ ++ { ++ "name": "id", ++ "type": "str" ++ }, ++ { ++ "name": "name", ++ "type": "str" ++ }, ++ { ++ "name": "vm-state-size", ++ "type": "int" ++ }, ++ { ++ "name": "date-sec", ++ "type": "int" ++ }, ++ { ++ "name": "date-nsec", ++ "type": "int" ++ }, ++ { ++ "name": "vm-clock-sec", ++ "type": "int" ++ }, ++ { ++ "name": "vm-clock-nsec", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "68", ++ "members": [ ++ { ++ "name": "device", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "id", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "force", ++ "default": null, ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "69", ++ "members": [ ++ { ++ "name": "addr", ++ "type": "275" ++ }, ++ { ++ "name": "tls-creds", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "tls-authz", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "70", ++ "members": [ ++ { ++ "name": "device", ++ "type": "str" ++ }, ++ { ++ "name": "name", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "writable", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "bitmap", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "71", ++ "members": [ ++ { ++ "name": "name", ++ "type": "str" ++ }, ++ { ++ "name": "mode", ++ "default": null, ++ "type": "276" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "72", ++ "members": [ ++ { ++ "name": "device", ++ "type": "str" ++ }, ++ { ++ "name": "id", ++ "type": "str" ++ }, ++ { ++ "name": "tray-open", ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "73", ++ "members": [ ++ { ++ "name": "id", ++ "type": "str" ++ }, ++ { ++ "name": "connected", ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "74", ++ "members": [ ++ { ++ "name": "reference", ++ "type": "str" ++ }, ++ { ++ "name": "sector-num", ++ "type": "int" ++ }, ++ { ++ "name": "sectors-count", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "75", ++ "members": [ ++ { ++ "name": "type", ++ "type": "277" ++ }, ++ { ++ "name": "error", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "node-name", ++ "type": "str" ++ }, ++ { ++ "name": "sector-num", ++ "type": "int" ++ }, ++ { ++ "name": "sectors-count", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[76]", ++ "element-type": "76", ++ "meta-type": "array" ++ }, ++ { ++ "name": "76", ++ "members": [ ++ { ++ "name": "label", ++ "type": "str" ++ }, ++ { ++ "name": "filename", ++ "type": "str" ++ }, ++ { ++ "name": "frontend-open", ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[77]", ++ "element-type": "77", ++ "meta-type": "array" ++ }, ++ { ++ "name": "77", ++ "members": [ ++ { ++ "name": "name", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "78", ++ "members": [ ++ { ++ "name": "device", ++ "type": "str" ++ }, ++ { ++ "name": "data", ++ "type": "str" ++ }, ++ { ++ "name": "format", ++ "default": null, ++ "type": "278" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "79", ++ "members": [ ++ { ++ "name": "device", ++ "type": "str" ++ }, ++ { ++ "name": "size", ++ "type": "int" ++ }, ++ { ++ "name": "format", ++ "default": null, ++ "type": "278" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "str", ++ "json-type": "string", ++ "meta-type": "builtin" ++ }, ++ { ++ "name": "80", ++ "members": [ ++ { ++ "name": "id", ++ "type": "str" ++ }, ++ { ++ "name": "backend", ++ "type": "279" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "81", ++ "members": [ ++ { ++ "name": "pty", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "82", ++ "members": [ ++ { ++ "name": "id", ++ "type": "str" ++ }, ++ { ++ "name": "backend", ++ "type": "279" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "83", ++ "members": [ ++ { ++ "name": "id", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "84", ++ "members": [ ++ { ++ "name": "id", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "85", ++ "members": [ ++ { ++ "name": "id", ++ "type": "str" ++ }, ++ { ++ "name": "open", ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "86", ++ "members": [ ++ { ++ "name": "name", ++ "type": "str" ++ }, ++ { ++ "name": "up", ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "87", ++ "members": [ ++ { ++ "name": "type", ++ "type": "str" ++ }, ++ { ++ "name": "id", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "88", ++ "members": [ ++ { ++ "name": "id", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "89", ++ "members": [ ++ { ++ "name": "name", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[90]", ++ "element-type": "90", ++ "meta-type": "array" ++ }, ++ { ++ "name": "90", ++ "members": [ ++ { ++ "name": "name", ++ "type": "str" ++ }, ++ { ++ "name": "promiscuous", ++ "type": "bool" ++ }, ++ { ++ "name": "multicast", ++ "type": "280" ++ }, ++ { ++ "name": "unicast", ++ "type": "280" ++ }, ++ { ++ "name": "vlan", ++ "type": "280" ++ }, ++ { ++ "name": "broadcast-allowed", ++ "type": "bool" ++ }, ++ { ++ "name": "multicast-overflow", ++ "type": "bool" ++ }, ++ { ++ "name": "unicast-overflow", ++ "type": "bool" ++ }, ++ { ++ "name": "main-mac", ++ "type": "str" ++ }, ++ { ++ "name": "vlan-table", ++ "type": "[int]" ++ }, ++ { ++ "name": "unicast-table", ++ "type": "[str]" ++ }, ++ { ++ "name": "multicast-table", ++ "type": "[str]" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "91", ++ "members": [ ++ { ++ "name": "name", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "path", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "92", ++ "members": [ ++ { ++ "name": "initial", ++ "type": "int" ++ }, ++ { ++ "name": "max", ++ "type": "int" ++ }, ++ { ++ "name": "rounds", ++ "type": "int" ++ }, ++ { ++ "name": "step", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "93", ++ "members": [ ++ { ++ "name": "netdev", ++ "type": "str" ++ }, ++ { ++ "name": "gid-status", ++ "type": "bool" ++ }, ++ { ++ "name": "subnet-prefix", ++ "type": "int" ++ }, ++ { ++ "name": "interface-id", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "94", ++ "members": [ ++ { ++ "name": "name", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "95", ++ "members": [ ++ { ++ "name": "name", ++ "type": "str" ++ }, ++ { ++ "name": "id", ++ "type": "int" ++ }, ++ { ++ "name": "ports", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "96", ++ "members": [ ++ { ++ "name": "name", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[97]", ++ "element-type": "97", ++ "meta-type": "array" ++ }, ++ { ++ "name": "97", ++ "members": [ ++ { ++ "name": "name", ++ "type": "str" ++ }, ++ { ++ "name": "enabled", ++ "type": "bool" ++ }, ++ { ++ "name": "link-up", ++ "type": "bool" ++ }, ++ { ++ "name": "speed", ++ "type": "int" ++ }, ++ { ++ "name": "duplex", ++ "type": "281" ++ }, ++ { ++ "name": "autoneg", ++ "type": "282" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "98", ++ "members": [ ++ { ++ "name": "name", ++ "type": "str" ++ }, ++ { ++ "name": "tbl-id", ++ "default": null, ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[99]", ++ "element-type": "99", ++ "meta-type": "array" ++ }, ++ { ++ "name": "99", ++ "members": [ ++ { ++ "name": "cookie", ++ "type": "int" ++ }, ++ { ++ "name": "hits", ++ "type": "int" ++ }, ++ { ++ "name": "key", ++ "type": "283" ++ }, ++ { ++ "name": "mask", ++ "type": "284" ++ }, ++ { ++ "name": "action", ++ "type": "285" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "100", ++ "members": [ ++ { ++ "name": "name", ++ "type": "str" ++ }, ++ { ++ "name": "type", ++ "default": null, ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[101]", ++ "element-type": "101", ++ "meta-type": "array" ++ }, ++ { ++ "name": "101", ++ "members": [ ++ { ++ "name": "id", ++ "type": "int" ++ }, ++ { ++ "name": "type", ++ "type": "int" ++ }, ++ { ++ "name": "vlan-id", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "pport", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "index", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "out-pport", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "group-id", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "set-vlan-id", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "pop-vlan", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "group-ids", ++ "default": null, ++ "type": "[int]" ++ }, ++ { ++ "name": "set-eth-src", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "set-eth-dst", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "ttl-check", ++ "default": null, ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[102]", ++ "element-type": "102", ++ "meta-type": "array" ++ }, ++ { ++ "name": "102", ++ "meta-type": "enum", ++ "values": [ ++ "tpm-tis", ++ "tpm-crb" ++ ] ++ }, ++ { ++ "name": "[103]", ++ "element-type": "103", ++ "meta-type": "array" ++ }, ++ { ++ "name": "103", ++ "meta-type": "enum", ++ "values": [ ++ "passthrough", ++ "emulator" ++ ] ++ }, ++ { ++ "name": "[104]", ++ "element-type": "104", ++ "meta-type": "array" ++ }, ++ { ++ "name": "104", ++ "members": [ ++ { ++ "name": "id", ++ "type": "str" ++ }, ++ { ++ "name": "model", ++ "type": "102" ++ }, ++ { ++ "name": "options", ++ "type": "286" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "105", ++ "members": [ ++ { ++ "name": "protocol", ++ "type": "str" ++ }, ++ { ++ "name": "password", ++ "type": "str" ++ }, ++ { ++ "name": "connected", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "106", ++ "members": [ ++ { ++ "name": "protocol", ++ "type": "str" ++ }, ++ { ++ "name": "time", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "107", ++ "members": [ ++ { ++ "name": "filename", ++ "type": "str" ++ }, ++ { ++ "name": "device", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "head", ++ "default": null, ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "108", ++ "members": [ ++ { ++ "name": "enabled", ++ "type": "bool" ++ }, ++ { ++ "name": "migrated", ++ "type": "bool" ++ }, ++ { ++ "name": "host", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "port", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "tls-port", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "auth", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "compiled-version", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "mouse-mode", ++ "type": "287" ++ }, ++ { ++ "name": "channels", ++ "default": null, ++ "type": "[288]" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "109", ++ "members": [ ++ { ++ "name": "server", ++ "type": "289" ++ }, ++ { ++ "name": "client", ++ "type": "289" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "110", ++ "members": [ ++ { ++ "name": "server", ++ "type": "290" ++ }, ++ { ++ "name": "client", ++ "type": "288" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "111", ++ "members": [ ++ { ++ "name": "server", ++ "type": "289" ++ }, ++ { ++ "name": "client", ++ "type": "289" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "112", ++ "members": [ ++ { ++ "name": "enabled", ++ "type": "bool" ++ }, ++ { ++ "name": "host", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "family", ++ "default": null, ++ "type": "291" ++ }, ++ { ++ "name": "service", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "auth", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "clients", ++ "default": null, ++ "type": "[292]" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[113]", ++ "element-type": "113", ++ "meta-type": "array" ++ }, ++ { ++ "name": "113", ++ "members": [ ++ { ++ "name": "id", ++ "type": "str" ++ }, ++ { ++ "name": "server", ++ "type": "[293]" ++ }, ++ { ++ "name": "clients", ++ "type": "[292]" ++ }, ++ { ++ "name": "auth", ++ "type": "294" ++ }, ++ { ++ "name": "vencrypt", ++ "default": null, ++ "type": "295" ++ }, ++ { ++ "name": "display", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "114", ++ "members": [ ++ { ++ "name": "password", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "115", ++ "members": [ ++ { ++ "name": "server", ++ "type": "296" ++ }, ++ { ++ "name": "client", ++ "type": "297" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "116", ++ "members": [ ++ { ++ "name": "server", ++ "type": "296" ++ }, ++ { ++ "name": "client", ++ "type": "292" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "117", ++ "members": [ ++ { ++ "name": "server", ++ "type": "296" ++ }, ++ { ++ "name": "client", ++ "type": "292" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[118]", ++ "element-type": "118", ++ "meta-type": "array" ++ }, ++ { ++ "name": "118", ++ "members": [ ++ { ++ "name": "name", ++ "type": "str" ++ }, ++ { ++ "name": "index", ++ "type": "int" ++ }, ++ { ++ "name": "current", ++ "type": "bool" ++ }, ++ { ++ "name": "absolute", ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "119", ++ "members": [ ++ { ++ "name": "keys", ++ "type": "[298]" ++ }, ++ { ++ "name": "hold-time", ++ "default": null, ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "120", ++ "members": [ ++ { ++ "name": "device", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "head", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "events", ++ "type": "[299]" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "121", ++ "tag": "type", ++ "variants": [ ++ { ++ "case": "gtk", ++ "type": "302" ++ }, ++ { ++ "case": "curses", ++ "type": "303" ++ }, ++ { ++ "case": "egl-headless", ++ "type": "304" ++ }, ++ { ++ "case": "default", ++ "type": "0" ++ }, ++ { ++ "case": "none", ++ "type": "0" ++ }, ++ { ++ "case": "sdl", ++ "type": "0" ++ }, ++ { ++ "case": "cocoa", ++ "type": "0" ++ }, ++ { ++ "case": "spice-app", ++ "type": "0" ++ } ++ ], ++ "members": [ ++ { ++ "name": "type", ++ "type": "300" ++ }, ++ { ++ "name": "full-screen", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "window-close", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "gl", ++ "default": null, ++ "type": "301" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "122", ++ "members": [ ++ { ++ "name": "status", ++ "default": null, ++ "type": "305" ++ }, ++ { ++ "name": "ram", ++ "default": null, ++ "type": "306" ++ }, ++ { ++ "name": "disk", ++ "default": null, ++ "type": "306" ++ }, ++ { ++ "name": "xbzrle-cache", ++ "default": null, ++ "type": "307" ++ }, ++ { ++ "name": "total-time", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "expected-downtime", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "downtime", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "setup-time", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "cpu-throttle-percentage", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "error-desc", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "postcopy-blocktime", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "postcopy-vcpu-blocktime", ++ "default": null, ++ "type": "[int]" ++ }, ++ { ++ "name": "compression", ++ "default": null, ++ "type": "308" ++ }, ++ { ++ "name": "socket-address", ++ "default": null, ++ "type": "[309]" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "123", ++ "members": [ ++ { ++ "name": "capabilities", ++ "type": "[124]" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[124]", ++ "element-type": "124", ++ "meta-type": "array" ++ }, ++ { ++ "name": "124", ++ "members": [ ++ { ++ "name": "capability", ++ "type": "310" ++ }, ++ { ++ "name": "state", ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "125", ++ "members": [ ++ { ++ "name": "announce-initial", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "announce-max", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "announce-rounds", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "announce-step", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "compress-level", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "compress-threads", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "compress-wait-thread", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "decompress-threads", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "cpu-throttle-initial", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "cpu-throttle-increment", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "tls-creds", ++ "default": null, ++ "type": "274" ++ }, ++ { ++ "name": "tls-hostname", ++ "default": null, ++ "type": "274" ++ }, ++ { ++ "name": "tls-authz", ++ "default": null, ++ "type": "274" ++ }, ++ { ++ "name": "max-bandwidth", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "downtime-limit", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "x-checkpoint-delay", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "block-incremental", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "multifd-channels", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "xbzrle-cache-size", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "max-postcopy-bandwidth", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "max-cpu-throttle", ++ "default": null, ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "126", ++ "members": [ ++ { ++ "name": "announce-initial", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "announce-max", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "announce-rounds", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "announce-step", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "compress-level", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "compress-threads", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "compress-wait-thread", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "decompress-threads", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "cpu-throttle-initial", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "cpu-throttle-increment", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "tls-creds", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "tls-hostname", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "tls-authz", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "max-bandwidth", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "downtime-limit", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "x-checkpoint-delay", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "block-incremental", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "multifd-channels", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "xbzrle-cache-size", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "max-postcopy-bandwidth", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "max-cpu-throttle", ++ "default": null, ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "127", ++ "members": [ ++ { ++ "name": "protocol", ++ "type": "str" ++ }, ++ { ++ "name": "hostname", ++ "type": "str" ++ }, ++ { ++ "name": "port", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "tls-port", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "cert-subject", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "128", ++ "members": [ ++ { ++ "name": "status", ++ "type": "305" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "129", ++ "members": [ ++ { ++ "name": "pass", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "130", ++ "members": [ ++ { ++ "name": "mode", ++ "type": "311" ++ }, ++ { ++ "name": "reason", ++ "type": "312" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "131", ++ "members": [ ++ { ++ "name": "state", ++ "type": "305" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "132", ++ "members": [ ++ { ++ "name": "value", ++ "type": "number" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "133", ++ "members": [ ++ { ++ "name": "value", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "134", ++ "members": [ ++ { ++ "name": "value", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "int", ++ "json-type": "int", ++ "meta-type": "builtin" ++ }, ++ { ++ "name": "135", ++ "members": [ ++ { ++ "name": "uri", ++ "type": "str" ++ }, ++ { ++ "name": "blk", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "inc", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "detach", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "resume", ++ "default": null, ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "136", ++ "members": [ ++ { ++ "name": "uri", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "137", ++ "members": [ ++ { ++ "name": "filename", ++ "type": "str" ++ }, ++ { ++ "name": "live", ++ "default": null, ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "138", ++ "members": [ ++ { ++ "name": "enable", ++ "type": "bool" ++ }, ++ { ++ "name": "primary", ++ "type": "bool" ++ }, ++ { ++ "name": "failover", ++ "default": null, ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "139", ++ "members": [ ++ { ++ "name": "error", ++ "type": "bool" ++ }, ++ { ++ "name": "desc", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "140", ++ "members": [ ++ { ++ "name": "mode", ++ "type": "311" ++ }, ++ { ++ "name": "last-mode", ++ "type": "311" ++ }, ++ { ++ "name": "reason", ++ "type": "312" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "141", ++ "members": [ ++ { ++ "name": "uri", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "142", ++ "members": [ ++ { ++ "name": "actions", ++ "type": "[313]" ++ }, ++ { ++ "name": "properties", ++ "default": null, ++ "type": "314" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "143", ++ "members": [ ++ { ++ "name": "name", ++ "type": "str" ++ }, ++ { ++ "name": "vcpu", ++ "default": null, ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[144]", ++ "element-type": "144", ++ "meta-type": "array" ++ }, ++ { ++ "name": "144", ++ "members": [ ++ { ++ "name": "name", ++ "type": "str" ++ }, ++ { ++ "name": "state", ++ "type": "315" ++ }, ++ { ++ "name": "vcpu", ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "145", ++ "members": [ ++ { ++ "name": "name", ++ "type": "str" ++ }, ++ { ++ "name": "enable", ++ "type": "bool" ++ }, ++ { ++ "name": "ignore-unavailable", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "vcpu", ++ "default": null, ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[146]", ++ "element-type": "146", ++ "meta-type": "array" ++ }, ++ { ++ "name": "146", ++ "tag": "meta-type", ++ "variants": [ ++ { ++ "case": "builtin", ++ "type": "317" ++ }, ++ { ++ "case": "enum", ++ "type": "318" ++ }, ++ { ++ "case": "array", ++ "type": "319" ++ }, ++ { ++ "case": "object", ++ "type": "320" ++ }, ++ { ++ "case": "alternate", ++ "type": "321" ++ }, ++ { ++ "case": "command", ++ "type": "322" ++ }, ++ { ++ "case": "event", ++ "type": "323" ++ } ++ ], ++ "members": [ ++ { ++ "name": "name", ++ "type": "str" ++ }, ++ { ++ "name": "meta-type", ++ "type": "316" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "147", ++ "members": [ ++ { ++ "name": "enable", ++ "default": null, ++ "type": "[324]" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "148", ++ "members": [ ++ { ++ "name": "qemu", ++ "type": "325" ++ }, ++ { ++ "name": "package", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[149]", ++ "element-type": "149", ++ "meta-type": "array" ++ }, ++ { ++ "name": "149", ++ "members": [ ++ { ++ "name": "name", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "150", ++ "members": [ ++ { ++ "name": "protocol", ++ "type": "str" ++ }, ++ { ++ "name": "fdname", ++ "type": "str" ++ }, ++ { ++ "name": "skipauth", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "tls", ++ "default": null, ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "151", ++ "members": [ ++ { ++ "name": "name", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "152", ++ "members": [ ++ { ++ "name": "enabled", ++ "type": "bool" ++ }, ++ { ++ "name": "present", ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "153", ++ "members": [ ++ { ++ "name": "UUID", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[154]", ++ "element-type": "154", ++ "meta-type": "array" ++ }, ++ { ++ "name": "154", ++ "members": [ ++ { ++ "name": "name", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[155]", ++ "element-type": "155", ++ "meta-type": "array" ++ }, ++ { ++ "name": "155", ++ "tag": "arch", ++ "variants": [ ++ { ++ "case": "x86", ++ "type": "328" ++ }, ++ { ++ "case": "sparc", ++ "type": "329" ++ }, ++ { ++ "case": "ppc", ++ "type": "330" ++ }, ++ { ++ "case": "mips", ++ "type": "331" ++ }, ++ { ++ "case": "tricore", ++ "type": "332" ++ }, ++ { ++ "case": "s390", ++ "type": "333" ++ }, ++ { ++ "case": "riscv", ++ "type": "334" ++ }, ++ { ++ "case": "other", ++ "type": "0" ++ } ++ ], ++ "members": [ ++ { ++ "name": "CPU", ++ "type": "int" ++ }, ++ { ++ "name": "current", ++ "type": "bool" ++ }, ++ { ++ "name": "halted", ++ "type": "bool" ++ }, ++ { ++ "name": "qom_path", ++ "type": "str" ++ }, ++ { ++ "name": "thread_id", ++ "type": "int" ++ }, ++ { ++ "name": "props", ++ "default": null, ++ "type": "326" ++ }, ++ { ++ "name": "arch", ++ "type": "327" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[156]", ++ "element-type": "156", ++ "meta-type": "array" ++ }, ++ { ++ "name": "156", ++ "tag": "target", ++ "variants": [ ++ { ++ "case": "s390x", ++ "type": "333" ++ }, ++ { ++ "case": "aarch64", ++ "type": "0" ++ }, ++ { ++ "case": "alpha", ++ "type": "0" ++ }, ++ { ++ "case": "arm", ++ "type": "0" ++ }, ++ { ++ "case": "cris", ++ "type": "0" ++ }, ++ { ++ "case": "hppa", ++ "type": "0" ++ }, ++ { ++ "case": "i386", ++ "type": "0" ++ }, ++ { ++ "case": "lm32", ++ "type": "0" ++ }, ++ { ++ "case": "m68k", ++ "type": "0" ++ }, ++ { ++ "case": "microblaze", ++ "type": "0" ++ }, ++ { ++ "case": "microblazeel", ++ "type": "0" ++ }, ++ { ++ "case": "mips", ++ "type": "0" ++ }, ++ { ++ "case": "mips64", ++ "type": "0" ++ }, ++ { ++ "case": "mips64el", ++ "type": "0" ++ }, ++ { ++ "case": "mipsel", ++ "type": "0" ++ }, ++ { ++ "case": "moxie", ++ "type": "0" ++ }, ++ { ++ "case": "nios2", ++ "type": "0" ++ }, ++ { ++ "case": "or1k", ++ "type": "0" ++ }, ++ { ++ "case": "ppc", ++ "type": "0" ++ }, ++ { ++ "case": "ppc64", ++ "type": "0" ++ }, ++ { ++ "case": "riscv32", ++ "type": "0" ++ }, ++ { ++ "case": "riscv64", ++ "type": "0" ++ }, ++ { ++ "case": "sh4", ++ "type": "0" ++ }, ++ { ++ "case": "sh4eb", ++ "type": "0" ++ }, ++ { ++ "case": "sparc", ++ "type": "0" ++ }, ++ { ++ "case": "sparc64", ++ "type": "0" ++ }, ++ { ++ "case": "tricore", ++ "type": "0" ++ }, ++ { ++ "case": "unicore32", ++ "type": "0" ++ }, ++ { ++ "case": "x86_64", ++ "type": "0" ++ }, ++ { ++ "case": "xtensa", ++ "type": "0" ++ }, ++ { ++ "case": "xtensaeb", ++ "type": "0" ++ } ++ ], ++ "members": [ ++ { ++ "name": "cpu-index", ++ "type": "int" ++ }, ++ { ++ "name": "qom-path", ++ "type": "str" ++ }, ++ { ++ "name": "thread-id", ++ "type": "int" ++ }, ++ { ++ "name": "props", ++ "default": null, ++ "type": "326" ++ }, ++ { ++ "name": "arch", ++ "type": "327" ++ }, ++ { ++ "name": "target", ++ "type": "335" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[157]", ++ "element-type": "157", ++ "meta-type": "array" ++ }, ++ { ++ "name": "157", ++ "members": [ ++ { ++ "name": "id", ++ "type": "str" ++ }, ++ { ++ "name": "thread-id", ++ "type": "int" ++ }, ++ { ++ "name": "poll-max-ns", ++ "type": "int" ++ }, ++ { ++ "name": "poll-grow", ++ "type": "int" ++ }, ++ { ++ "name": "poll-shrink", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "158", ++ "members": [ ++ { ++ "name": "actual", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "159", ++ "members": [ ++ { ++ "name": "actual", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[160]", ++ "element-type": "160", ++ "meta-type": "array" ++ }, ++ { ++ "name": "160", ++ "members": [ ++ { ++ "name": "bus", ++ "type": "int" ++ }, ++ { ++ "name": "devices", ++ "type": "[336]" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "161", ++ "members": [ ++ { ++ "name": "id", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "162", ++ "members": [ ++ { ++ "name": "val", ++ "type": "int" ++ }, ++ { ++ "name": "size", ++ "type": "int" ++ }, ++ { ++ "name": "filename", ++ "type": "str" ++ }, ++ { ++ "name": "cpu-index", ++ "default": null, ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "163", ++ "members": [ ++ { ++ "name": "val", ++ "type": "int" ++ }, ++ { ++ "name": "size", ++ "type": "int" ++ }, ++ { ++ "name": "filename", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "164", ++ "members": [ ++ { ++ "name": "value", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "165", ++ "members": [ ++ { ++ "name": "command-line", ++ "type": "str" ++ }, ++ { ++ "name": "cpu-index", ++ "default": null, ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "166", ++ "members": [ ++ { ++ "name": "path", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[167]", ++ "element-type": "167", ++ "meta-type": "array" ++ }, ++ { ++ "name": "167", ++ "members": [ ++ { ++ "name": "name", ++ "type": "str" ++ }, ++ { ++ "name": "type", ++ "type": "str" ++ }, ++ { ++ "name": "description", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "168", ++ "members": [ ++ { ++ "name": "path", ++ "type": "str" ++ }, ++ { ++ "name": "property", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "any", ++ "json-type": "value", ++ "meta-type": "builtin" ++ }, ++ { ++ "name": "169", ++ "members": [ ++ { ++ "name": "path", ++ "type": "str" ++ }, ++ { ++ "name": "property", ++ "type": "str" ++ }, ++ { ++ "name": "value", ++ "type": "any" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "170", ++ "members": [ ++ { ++ "name": "device", ++ "type": "str" ++ }, ++ { ++ "name": "target", ++ "type": "str" ++ }, ++ { ++ "name": "arg", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "171", ++ "members": [ ++ { ++ "name": "implements", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "abstract", ++ "default": null, ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[172]", ++ "element-type": "172", ++ "meta-type": "array" ++ }, ++ { ++ "name": "172", ++ "members": [ ++ { ++ "name": "name", ++ "type": "str" ++ }, ++ { ++ "name": "abstract", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "parent", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "173", ++ "members": [ ++ { ++ "name": "typename", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "174", ++ "members": [ ++ { ++ "name": "typename", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "175", ++ "members": [ ++ { ++ "name": "enable", ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "176", ++ "members": [ ++ { ++ "name": "driver", ++ "type": "str" ++ }, ++ { ++ "name": "bus", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "id", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "177", ++ "members": [ ++ { ++ "name": "id", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "178", ++ "members": [ ++ { ++ "name": "device", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "path", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "179", ++ "members": [ ++ { ++ "name": "paging", ++ "type": "bool" ++ }, ++ { ++ "name": "protocol", ++ "type": "str" ++ }, ++ { ++ "name": "detach", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "begin", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "length", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "format", ++ "default": null, ++ "type": "337" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "180", ++ "members": [ ++ { ++ "name": "status", ++ "type": "338" ++ }, ++ { ++ "name": "completed", ++ "type": "int" ++ }, ++ { ++ "name": "total", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "181", ++ "members": [ ++ { ++ "name": "result", ++ "type": "180" ++ }, ++ { ++ "name": "error", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "182", ++ "members": [ ++ { ++ "name": "formats", ++ "type": "[337]" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "183", ++ "members": [ ++ { ++ "name": "qom-type", ++ "type": "str" ++ }, ++ { ++ "name": "id", ++ "type": "str" ++ }, ++ { ++ "name": "props", ++ "default": null, ++ "type": "any" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "184", ++ "members": [ ++ { ++ "name": "id", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "185", ++ "members": [ ++ { ++ "name": "fdname", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "186", ++ "members": [ ++ { ++ "name": "fdname", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[187]", ++ "element-type": "187", ++ "meta-type": "array" ++ }, ++ { ++ "name": "187", ++ "members": [ ++ { ++ "name": "name", ++ "type": "str" ++ }, ++ { ++ "name": "alias", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "is-default", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "cpu-max", ++ "type": "int" ++ }, ++ { ++ "name": "hotpluggable-cpus", ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "188", ++ "members": [ ++ { ++ "name": "wakeup-suspend-support", ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "189", ++ "members": [ ++ { ++ "name": "base-memory", ++ "type": "int" ++ }, ++ { ++ "name": "plugged-memory", ++ "default": null, ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "190", ++ "members": [ ++ { ++ "name": "fdset-id", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "opaque", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "191", ++ "members": [ ++ { ++ "name": "fdset-id", ++ "type": "int" ++ }, ++ { ++ "name": "fd", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "192", ++ "members": [ ++ { ++ "name": "fdset-id", ++ "type": "int" ++ }, ++ { ++ "name": "fd", ++ "default": null, ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[193]", ++ "element-type": "193", ++ "meta-type": "array" ++ }, ++ { ++ "name": "193", ++ "members": [ ++ { ++ "name": "fdset-id", ++ "type": "int" ++ }, ++ { ++ "name": "fds", ++ "type": "[339]" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "194", ++ "members": [ ++ { ++ "name": "arch", ++ "type": "335" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "195", ++ "members": [ ++ { ++ "name": "option", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[196]", ++ "element-type": "196", ++ "meta-type": "array" ++ }, ++ { ++ "name": "196", ++ "members": [ ++ { ++ "name": "option", ++ "type": "str" ++ }, ++ { ++ "name": "parameters", ++ "type": "[340]" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[197]", ++ "element-type": "197", ++ "meta-type": "array" ++ }, ++ { ++ "name": "197", ++ "members": [ ++ { ++ "name": "id", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "size", ++ "type": "int" ++ }, ++ { ++ "name": "merge", ++ "type": "bool" ++ }, ++ { ++ "name": "dump", ++ "type": "bool" ++ }, ++ { ++ "name": "prealloc", ++ "type": "bool" ++ }, ++ { ++ "name": "host-nodes", ++ "type": "[int]" ++ }, ++ { ++ "name": "policy", ++ "type": "341" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[198]", ++ "element-type": "198", ++ "meta-type": "array" ++ }, ++ { ++ "name": "198", ++ "tag": "type", ++ "variants": [ ++ { ++ "case": "dimm", ++ "type": "343" ++ }, ++ { ++ "case": "nvdimm", ++ "type": "343" ++ } ++ ], ++ "members": [ ++ { ++ "name": "type", ++ "type": "342" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "199", ++ "members": [ ++ { ++ "name": "device", ++ "type": "str" ++ }, ++ { ++ "name": "msg", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[200]", ++ "element-type": "200", ++ "meta-type": "array" ++ }, ++ { ++ "name": "200", ++ "members": [ ++ { ++ "name": "device", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "slot", ++ "type": "str" ++ }, ++ { ++ "name": "slot-type", ++ "type": "344" ++ }, ++ { ++ "name": "source", ++ "type": "int" ++ }, ++ { ++ "name": "status", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "201", ++ "members": [ ++ { ++ "name": "info", ++ "type": "200" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "202", ++ "members": [ ++ { ++ "name": "filename", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[203]", ++ "element-type": "203", ++ "meta-type": "array" ++ }, ++ { ++ "name": "203", ++ "members": [ ++ { ++ "name": "type", ++ "type": "str" ++ }, ++ { ++ "name": "vcpus-count", ++ "type": "int" ++ }, ++ { ++ "name": "props", ++ "type": "326" ++ }, ++ { ++ "name": "qom-path", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "204", ++ "members": [ ++ { ++ "name": "guid", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "205", ++ "tag": "type", ++ "variants": [ ++ { ++ "case": "node", ++ "type": "346" ++ }, ++ { ++ "case": "dist", ++ "type": "347" ++ }, ++ { ++ "case": "cpu", ++ "type": "348" ++ } ++ ], ++ "members": [ ++ { ++ "name": "type", ++ "type": "345" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "206", ++ "members": [ ++ { ++ "name": "offset", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "207", ++ "members": [ ++ { ++ "name": "enabled", ++ "type": "bool" ++ }, ++ { ++ "name": "api-major", ++ "type": "int" ++ }, ++ { ++ "name": "api-minor", ++ "type": "int" ++ }, ++ { ++ "name": "build-id", ++ "type": "int" ++ }, ++ { ++ "name": "policy", ++ "type": "int" ++ }, ++ { ++ "name": "state", ++ "type": "349" ++ }, ++ { ++ "name": "handle", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "208", ++ "members": [ ++ { ++ "name": "data", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "209", ++ "members": [ ++ { ++ "name": "pdh", ++ "type": "str" ++ }, ++ { ++ "name": "cert-chain", ++ "type": "str" ++ }, ++ { ++ "name": "cbitpos", ++ "type": "int" ++ }, ++ { ++ "name": "reduced-phys-bits", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "216", ++ "members": [ ++ { ++ "name": "type", ++ "type": "352" ++ }, ++ { ++ "name": "model", ++ "type": "350" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "217", ++ "members": [ ++ { ++ "name": "model", ++ "type": "350" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[218]", ++ "element-type": "218", ++ "meta-type": "array" ++ }, ++ { ++ "name": "218", ++ "members": [ ++ { ++ "name": "name", ++ "type": "str" ++ }, ++ { ++ "name": "migration-safe", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "static", ++ "type": "bool" ++ }, ++ { ++ "name": "unavailable-features", ++ "default": null, ++ "type": "[str]" ++ }, ++ { ++ "name": "typename", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "bool", ++ "json-type": "boolean", ++ "meta-type": "builtin" ++ }, ++ { ++ "name": "219", ++ "meta-type": "enum", ++ "values": [ ++ "debug", ++ "inmigrate", ++ "internal-error", ++ "io-error", ++ "paused", ++ "postmigrate", ++ "prelaunch", ++ "finish-migrate", ++ "restore-vm", ++ "running", ++ "save-vm", ++ "shutdown", ++ "suspended", ++ "watchdog", ++ "guest-panicked", ++ "colo", ++ "preconfig" ++ ] ++ }, ++ { ++ "name": "220", ++ "meta-type": "enum", ++ "values": [ ++ "none", ++ "host-error", ++ "host-qmp-quit", ++ "host-qmp-system-reset", ++ "host-signal", ++ "host-ui", ++ "guest-shutdown", ++ "guest-reset", ++ "guest-panic", ++ "subsystem-reset" ++ ] ++ }, ++ { ++ "name": "221", ++ "meta-type": "enum", ++ "values": [ ++ "reset", ++ "shutdown", ++ "poweroff", ++ "pause", ++ "debug", ++ "none", ++ "inject-nmi" ++ ] ++ }, ++ { ++ "name": "222", ++ "meta-type": "enum", ++ "values": [ ++ "pause", ++ "poweroff" ++ ] ++ }, ++ { ++ "name": "223", ++ "tag": "type", ++ "variants": [ ++ { ++ "case": "hyper-v", ++ "type": "354" ++ }, ++ { ++ "case": "s390", ++ "type": "355" ++ } ++ ], ++ "members": [ ++ { ++ "name": "type", ++ "type": "353" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "224", ++ "meta-type": "enum", ++ "values": [ ++ "undefined", ++ "created", ++ "running", ++ "paused", ++ "ready", ++ "standby", ++ "waiting", ++ "pending", ++ "aborting", ++ "concluded", ++ "null" ++ ] ++ }, ++ { ++ "name": "225", ++ "meta-type": "enum", ++ "values": [ ++ "commit", ++ "stream", ++ "mirror", ++ "backup", ++ "create" ++ ] ++ }, ++ { ++ "name": "[int]", ++ "element-type": "int", ++ "meta-type": "array" ++ }, ++ { ++ "name": "226", ++ "meta-type": "enum", ++ "values": [ ++ "ok", ++ "failed", ++ "nospace" ++ ] ++ }, ++ { ++ "name": "[227]", ++ "element-type": "227", ++ "meta-type": "array" ++ }, ++ { ++ "name": "227", ++ "members": [ ++ { ++ "name": "name", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "count", ++ "type": "int" ++ }, ++ { ++ "name": "granularity", ++ "type": "int" ++ }, ++ { ++ "name": "recording", ++ "type": "bool" ++ }, ++ { ++ "name": "busy", ++ "type": "bool" ++ }, ++ { ++ "name": "status", ++ "type": "356" ++ }, ++ { ++ "name": "persistent", ++ "type": "bool" ++ }, ++ { ++ "name": "inconsistent", ++ "default": null, ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "228", ++ "members": [ ++ { ++ "name": "rd_bytes", ++ "type": "int" ++ }, ++ { ++ "name": "wr_bytes", ++ "type": "int" ++ }, ++ { ++ "name": "rd_operations", ++ "type": "int" ++ }, ++ { ++ "name": "wr_operations", ++ "type": "int" ++ }, ++ { ++ "name": "flush_operations", ++ "type": "int" ++ }, ++ { ++ "name": "flush_total_time_ns", ++ "type": "int" ++ }, ++ { ++ "name": "wr_total_time_ns", ++ "type": "int" ++ }, ++ { ++ "name": "rd_total_time_ns", ++ "type": "int" ++ }, ++ { ++ "name": "wr_highest_offset", ++ "type": "int" ++ }, ++ { ++ "name": "rd_merged", ++ "type": "int" ++ }, ++ { ++ "name": "wr_merged", ++ "type": "int" ++ }, ++ { ++ "name": "idle_time_ns", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "failed_rd_operations", ++ "type": "int" ++ }, ++ { ++ "name": "failed_wr_operations", ++ "type": "int" ++ }, ++ { ++ "name": "failed_flush_operations", ++ "type": "int" ++ }, ++ { ++ "name": "invalid_rd_operations", ++ "type": "int" ++ }, ++ { ++ "name": "invalid_wr_operations", ++ "type": "int" ++ }, ++ { ++ "name": "invalid_flush_operations", ++ "type": "int" ++ }, ++ { ++ "name": "account_invalid", ++ "type": "bool" ++ }, ++ { ++ "name": "account_failed", ++ "type": "bool" ++ }, ++ { ++ "name": "timed_stats", ++ "type": "[357]" ++ }, ++ { ++ "name": "rd_latency_histogram", ++ "default": null, ++ "type": "358" ++ }, ++ { ++ "name": "wr_latency_histogram", ++ "default": null, ++ "type": "358" ++ }, ++ { ++ "name": "flush_latency_histogram", ++ "default": null, ++ "type": "358" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "229", ++ "meta-type": "enum", ++ "values": [ ++ "existing", ++ "absolute-paths" ++ ] ++ }, ++ { ++ "name": "230", ++ "meta-type": "enum", ++ "values": [ ++ "top", ++ "full", ++ "none", ++ "incremental" ++ ] ++ }, ++ { ++ "name": "231", ++ "meta-type": "enum", ++ "values": [ ++ "report", ++ "ignore", ++ "enospc", ++ "stop", ++ "auto" ++ ] ++ }, ++ { ++ "name": "232", ++ "meta-type": "enum", ++ "values": [ ++ "off", ++ "on", ++ "unmap" ++ ] ++ }, ++ { ++ "name": "233", ++ "members": [ ++ { ++ "name": "filename", ++ "type": "str" ++ }, ++ { ++ "name": "format", ++ "type": "str" ++ }, ++ { ++ "name": "dirty-flag", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "actual-size", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "virtual-size", ++ "type": "int" ++ }, ++ { ++ "name": "cluster-size", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "encrypted", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "compressed", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "backing-filename", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "full-backing-filename", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "backing-filename-format", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "snapshots", ++ "default": null, ++ "type": "[67]" ++ }, ++ { ++ "name": "backing-image", ++ "default": null, ++ "type": "233" ++ }, ++ { ++ "name": "format-specific", ++ "default": null, ++ "type": "359" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "234", ++ "members": [ ++ { ++ "name": "writeback", ++ "type": "bool" ++ }, ++ { ++ "name": "direct", ++ "type": "bool" ++ }, ++ { ++ "name": "no-flush", ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[235]", ++ "element-type": "235", ++ "meta-type": "array" ++ }, ++ { ++ "name": "235", ++ "members": [ ++ { ++ "name": "id", ++ "type": "int" ++ }, ++ { ++ "name": "type", ++ "type": "360" ++ }, ++ { ++ "name": "name", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[236]", ++ "element-type": "236", ++ "meta-type": "array" ++ }, ++ { ++ "name": "236", ++ "members": [ ++ { ++ "name": "parent", ++ "type": "int" ++ }, ++ { ++ "name": "child", ++ "type": "int" ++ }, ++ { ++ "name": "name", ++ "type": "str" ++ }, ++ { ++ "name": "perm", ++ "type": "[361]" ++ }, ++ { ++ "name": "shared-perm", ++ "type": "[361]" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "237", ++ "meta-type": "enum", ++ "values": [ ++ "background", ++ "write-blocking" ++ ] ++ }, ++ { ++ "name": "[238]", ++ "element-type": "238", ++ "meta-type": "array" ++ }, ++ { ++ "name": "238", ++ "members": [ ++ { ++ "type": "str" ++ }, ++ { ++ "type": "32" ++ } ++ ], ++ "meta-type": "alternate" ++ }, ++ { ++ "name": "239", ++ "meta-type": "enum", ++ "values": [ ++ "blkdebug", ++ "blklogwrites", ++ "blkverify", ++ "bochs", ++ "cloop", ++ "copy-on-read", ++ "dmg", ++ "file", ++ "ftp", ++ "ftps", ++ "gluster", ++ "host_cdrom", ++ "host_device", ++ "http", ++ "https", ++ "iscsi", ++ "luks", ++ "nbd", ++ "nfs", ++ "null-aio", ++ "null-co", ++ "nvme", ++ "parallels", ++ "qcow", ++ "qcow2", ++ "qed", ++ "quorum", ++ "raw", ++ "rbd", ++ "replication", ++ "sheepdog", ++ "ssh", ++ "throttle", ++ "vdi", ++ "vhdx", ++ "vmdk", ++ "vpc", ++ "vvfat", ++ "vxhs" ++ ] ++ }, ++ { ++ "name": "240", ++ "meta-type": "enum", ++ "values": [ ++ "ignore", ++ "unmap" ++ ] ++ }, ++ { ++ "name": "241", ++ "members": [ ++ { ++ "name": "direct", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "no-flush", ++ "default": null, ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "242", ++ "members": [ ++ { ++ "name": "image", ++ "type": "362" ++ }, ++ { ++ "name": "config", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "align", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "max-transfer", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "opt-write-zero", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "max-write-zero", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "opt-discard", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "max-discard", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "inject-error", ++ "default": null, ++ "type": "[363]" ++ }, ++ { ++ "name": "set-state", ++ "default": null, ++ "type": "[364]" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "243", ++ "members": [ ++ { ++ "name": "file", ++ "type": "362" ++ }, ++ { ++ "name": "log", ++ "type": "362" ++ }, ++ { ++ "name": "log-sector-size", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "log-append", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "log-super-update-interval", ++ "default": null, ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "244", ++ "members": [ ++ { ++ "name": "test", ++ "type": "362" ++ }, ++ { ++ "name": "raw", ++ "type": "362" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "245", ++ "members": [ ++ { ++ "name": "file", ++ "type": "362" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "246", ++ "members": [ ++ { ++ "name": "filename", ++ "type": "str" ++ }, ++ { ++ "name": "pr-manager", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "locking", ++ "default": null, ++ "type": "365" ++ }, ++ { ++ "name": "aio", ++ "default": null, ++ "type": "366" ++ }, ++ { ++ "name": "drop-cache", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "x-check-cache-dropped", ++ "default": null, ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "247", ++ "members": [ ++ { ++ "name": "url", ++ "type": "str" ++ }, ++ { ++ "name": "readahead", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "timeout", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "username", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "password-secret", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "proxy-username", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "proxy-password-secret", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "248", ++ "members": [ ++ { ++ "name": "url", ++ "type": "str" ++ }, ++ { ++ "name": "readahead", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "timeout", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "username", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "password-secret", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "proxy-username", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "proxy-password-secret", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "sslverify", ++ "default": null, ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "249", ++ "members": [ ++ { ++ "name": "volume", ++ "type": "str" ++ }, ++ { ++ "name": "path", ++ "type": "str" ++ }, ++ { ++ "name": "server", ++ "type": "[309]" ++ }, ++ { ++ "name": "debug", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "logfile", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "250", ++ "members": [ ++ { ++ "name": "url", ++ "type": "str" ++ }, ++ { ++ "name": "readahead", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "timeout", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "username", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "password-secret", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "proxy-username", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "proxy-password-secret", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "cookie", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "cookie-secret", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "251", ++ "members": [ ++ { ++ "name": "url", ++ "type": "str" ++ }, ++ { ++ "name": "readahead", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "timeout", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "username", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "password-secret", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "proxy-username", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "proxy-password-secret", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "cookie", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "sslverify", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "cookie-secret", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "252", ++ "members": [ ++ { ++ "name": "transport", ++ "type": "367" ++ }, ++ { ++ "name": "portal", ++ "type": "str" ++ }, ++ { ++ "name": "target", ++ "type": "str" ++ }, ++ { ++ "name": "lun", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "user", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "password-secret", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "initiator-name", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "header-digest", ++ "default": null, ++ "type": "368" ++ }, ++ { ++ "name": "timeout", ++ "default": null, ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "253", ++ "members": [ ++ { ++ "name": "file", ++ "type": "362" ++ }, ++ { ++ "name": "key-secret", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "254", ++ "members": [ ++ { ++ "name": "server", ++ "type": "309" ++ }, ++ { ++ "name": "export", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "tls-creds", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "x-dirty-bitmap", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "255", ++ "members": [ ++ { ++ "name": "server", ++ "type": "369" ++ }, ++ { ++ "name": "path", ++ "type": "str" ++ }, ++ { ++ "name": "user", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "group", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "tcp-syn-count", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "readahead-size", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "page-cache-size", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "debug", ++ "default": null, ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "256", ++ "members": [ ++ { ++ "name": "size", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "latency-ns", ++ "default": null, ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "257", ++ "members": [ ++ { ++ "name": "device", ++ "type": "str" ++ }, ++ { ++ "name": "namespace", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "258", ++ "members": [ ++ { ++ "name": "file", ++ "type": "362" ++ }, ++ { ++ "name": "backing", ++ "default": null, ++ "type": "370" ++ }, ++ { ++ "name": "lazy-refcounts", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "pass-discard-request", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "pass-discard-snapshot", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "pass-discard-other", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "overlap-check", ++ "default": null, ++ "type": "371" ++ }, ++ { ++ "name": "cache-size", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "l2-cache-size", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "l2-cache-entry-size", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "refcount-cache-size", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "cache-clean-interval", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "encrypt", ++ "default": null, ++ "type": "372" ++ }, ++ { ++ "name": "data-file", ++ "default": null, ++ "type": "362" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "259", ++ "members": [ ++ { ++ "name": "file", ++ "type": "362" ++ }, ++ { ++ "name": "backing", ++ "default": null, ++ "type": "370" ++ }, ++ { ++ "name": "encrypt", ++ "default": null, ++ "type": "373" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "260", ++ "members": [ ++ { ++ "name": "file", ++ "type": "362" ++ }, ++ { ++ "name": "backing", ++ "default": null, ++ "type": "370" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "261", ++ "members": [ ++ { ++ "name": "blkverify", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "children", ++ "type": "[362]" ++ }, ++ { ++ "name": "vote-threshold", ++ "type": "int" ++ }, ++ { ++ "name": "rewrite-corrupted", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "read-pattern", ++ "default": null, ++ "type": "374" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "262", ++ "members": [ ++ { ++ "name": "file", ++ "type": "362" ++ }, ++ { ++ "name": "offset", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "size", ++ "default": null, ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "263", ++ "members": [ ++ { ++ "name": "pool", ++ "type": "str" ++ }, ++ { ++ "name": "image", ++ "type": "str" ++ }, ++ { ++ "name": "conf", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "snapshot", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "user", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "auth-client-required", ++ "default": null, ++ "type": "[375]" ++ }, ++ { ++ "name": "key-secret", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "server", ++ "default": null, ++ "type": "[376]" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "264", ++ "members": [ ++ { ++ "name": "file", ++ "type": "362" ++ }, ++ { ++ "name": "mode", ++ "type": "377" ++ }, ++ { ++ "name": "top-id", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "265", ++ "members": [ ++ { ++ "name": "server", ++ "type": "309" ++ }, ++ { ++ "name": "vdi", ++ "type": "str" ++ }, ++ { ++ "name": "snap-id", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "tag", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "266", ++ "members": [ ++ { ++ "name": "server", ++ "type": "378" ++ }, ++ { ++ "name": "path", ++ "type": "str" ++ }, ++ { ++ "name": "user", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "host-key-check", ++ "default": null, ++ "type": "379" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "267", ++ "members": [ ++ { ++ "name": "throttle-group", ++ "type": "str" ++ }, ++ { ++ "name": "file", ++ "type": "362" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "268", ++ "members": [ ++ { ++ "name": "dir", ++ "type": "str" ++ }, ++ { ++ "name": "fat-type", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "floppy", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "label", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "rw", ++ "default": null, ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "269", ++ "members": [ ++ { ++ "name": "vdisk-id", ++ "type": "str" ++ }, ++ { ++ "name": "server", ++ "type": "376" ++ }, ++ { ++ "name": "tls-creds", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "270", ++ "tag": "driver", ++ "variants": [ ++ { ++ "case": "file", ++ "type": "380" ++ }, ++ { ++ "case": "gluster", ++ "type": "381" ++ }, ++ { ++ "case": "luks", ++ "type": "382" ++ }, ++ { ++ "case": "nfs", ++ "type": "383" ++ }, ++ { ++ "case": "parallels", ++ "type": "384" ++ }, ++ { ++ "case": "qcow", ++ "type": "385" ++ }, ++ { ++ "case": "qcow2", ++ "type": "386" ++ }, ++ { ++ "case": "qed", ++ "type": "387" ++ }, ++ { ++ "case": "rbd", ++ "type": "388" ++ }, ++ { ++ "case": "sheepdog", ++ "type": "389" ++ }, ++ { ++ "case": "ssh", ++ "type": "390" ++ }, ++ { ++ "case": "vdi", ++ "type": "391" ++ }, ++ { ++ "case": "vhdx", ++ "type": "392" ++ }, ++ { ++ "case": "vmdk", ++ "type": "393" ++ }, ++ { ++ "case": "vpc", ++ "type": "394" ++ }, ++ { ++ "case": "blkdebug", ++ "type": "0" ++ }, ++ { ++ "case": "blklogwrites", ++ "type": "0" ++ }, ++ { ++ "case": "blkverify", ++ "type": "0" ++ }, ++ { ++ "case": "bochs", ++ "type": "0" ++ }, ++ { ++ "case": "cloop", ++ "type": "0" ++ }, ++ { ++ "case": "copy-on-read", ++ "type": "0" ++ }, ++ { ++ "case": "dmg", ++ "type": "0" ++ }, ++ { ++ "case": "ftp", ++ "type": "0" ++ }, ++ { ++ "case": "ftps", ++ "type": "0" ++ }, ++ { ++ "case": "host_cdrom", ++ "type": "0" ++ }, ++ { ++ "case": "host_device", ++ "type": "0" ++ }, ++ { ++ "case": "http", ++ "type": "0" ++ }, ++ { ++ "case": "https", ++ "type": "0" ++ }, ++ { ++ "case": "iscsi", ++ "type": "0" ++ }, ++ { ++ "case": "nbd", ++ "type": "0" ++ }, ++ { ++ "case": "null-aio", ++ "type": "0" ++ }, ++ { ++ "case": "null-co", ++ "type": "0" ++ }, ++ { ++ "case": "nvme", ++ "type": "0" ++ }, ++ { ++ "case": "quorum", ++ "type": "0" ++ }, ++ { ++ "case": "raw", ++ "type": "0" ++ }, ++ { ++ "case": "replication", ++ "type": "0" ++ }, ++ { ++ "case": "throttle", ++ "type": "0" ++ }, ++ { ++ "case": "vvfat", ++ "type": "0" ++ }, ++ { ++ "case": "vxhs", ++ "type": "0" ++ } ++ ], ++ "members": [ ++ { ++ "name": "driver", ++ "type": "239" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "271", ++ "meta-type": "enum", ++ "values": [ ++ "retain", ++ "read-only", ++ "read-write" ++ ] ++ }, ++ { ++ "name": "272", ++ "meta-type": "enum", ++ "values": [ ++ "read", ++ "write" ++ ] ++ }, ++ { ++ "name": "273", ++ "meta-type": "enum", ++ "values": [ ++ "ignore", ++ "report", ++ "stop" ++ ] ++ }, ++ { ++ "name": "274", ++ "members": [ ++ { ++ "type": "str" ++ }, ++ { ++ "type": "null" ++ } ++ ], ++ "meta-type": "alternate" ++ }, ++ { ++ "name": "275", ++ "tag": "type", ++ "variants": [ ++ { ++ "case": "inet", ++ "type": "396" ++ }, ++ { ++ "case": "unix", ++ "type": "397" ++ }, ++ { ++ "case": "vsock", ++ "type": "398" ++ }, ++ { ++ "case": "fd", ++ "type": "399" ++ } ++ ], ++ "members": [ ++ { ++ "name": "type", ++ "type": "395" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "276", ++ "meta-type": "enum", ++ "values": [ ++ "safe", ++ "hard" ++ ] ++ }, ++ { ++ "name": "277", ++ "meta-type": "enum", ++ "values": [ ++ "read", ++ "write", ++ "flush" ++ ] ++ }, ++ { ++ "name": "278", ++ "meta-type": "enum", ++ "values": [ ++ "utf8", ++ "base64" ++ ] ++ }, ++ { ++ "name": "279", ++ "tag": "type", ++ "variants": [ ++ { ++ "case": "file", ++ "type": "401" ++ }, ++ { ++ "case": "serial", ++ "type": "402" ++ }, ++ { ++ "case": "parallel", ++ "type": "402" ++ }, ++ { ++ "case": "pipe", ++ "type": "402" ++ }, ++ { ++ "case": "socket", ++ "type": "403" ++ }, ++ { ++ "case": "udp", ++ "type": "404" ++ }, ++ { ++ "case": "pty", ++ "type": "405" ++ }, ++ { ++ "case": "null", ++ "type": "405" ++ }, ++ { ++ "case": "mux", ++ "type": "406" ++ }, ++ { ++ "case": "msmouse", ++ "type": "405" ++ }, ++ { ++ "case": "wctablet", ++ "type": "405" ++ }, ++ { ++ "case": "braille", ++ "type": "405" ++ }, ++ { ++ "case": "testdev", ++ "type": "405" ++ }, ++ { ++ "case": "stdio", ++ "type": "407" ++ }, ++ { ++ "case": "console", ++ "type": "405" ++ }, ++ { ++ "case": "spicevmc", ++ "type": "408" ++ }, ++ { ++ "case": "spiceport", ++ "type": "409" ++ }, ++ { ++ "case": "vc", ++ "type": "410" ++ }, ++ { ++ "case": "ringbuf", ++ "type": "411" ++ }, ++ { ++ "case": "memory", ++ "type": "411" ++ } ++ ], ++ "members": [ ++ { ++ "name": "type", ++ "type": "400" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "280", ++ "meta-type": "enum", ++ "values": [ ++ "normal", ++ "none", ++ "all" ++ ] ++ }, ++ { ++ "name": "[str]", ++ "element-type": "str", ++ "meta-type": "array" ++ }, ++ { ++ "name": "281", ++ "meta-type": "enum", ++ "values": [ ++ "half", ++ "full" ++ ] ++ }, ++ { ++ "name": "282", ++ "meta-type": "enum", ++ "values": [ ++ "off", ++ "on" ++ ] ++ }, ++ { ++ "name": "283", ++ "members": [ ++ { ++ "name": "priority", ++ "type": "int" ++ }, ++ { ++ "name": "tbl-id", ++ "type": "int" ++ }, ++ { ++ "name": "in-pport", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "tunnel-id", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "vlan-id", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "eth-type", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "eth-src", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "eth-dst", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "ip-proto", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "ip-tos", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "ip-dst", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "284", ++ "members": [ ++ { ++ "name": "in-pport", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "tunnel-id", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "vlan-id", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "eth-src", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "eth-dst", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "ip-proto", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "ip-tos", ++ "default": null, ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "285", ++ "members": [ ++ { ++ "name": "goto-tbl", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "group-id", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "tunnel-lport", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "vlan-id", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "new-vlan-id", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "out-pport", ++ "default": null, ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "286", ++ "tag": "type", ++ "variants": [ ++ { ++ "case": "passthrough", ++ "type": "413" ++ }, ++ { ++ "case": "emulator", ++ "type": "414" ++ } ++ ], ++ "members": [ ++ { ++ "name": "type", ++ "type": "412" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "287", ++ "meta-type": "enum", ++ "values": [ ++ "client", ++ "server", ++ "unknown" ++ ] ++ }, ++ { ++ "name": "[288]", ++ "element-type": "288", ++ "meta-type": "array" ++ }, ++ { ++ "name": "288", ++ "members": [ ++ { ++ "name": "host", ++ "type": "str" ++ }, ++ { ++ "name": "port", ++ "type": "str" ++ }, ++ { ++ "name": "family", ++ "type": "291" ++ }, ++ { ++ "name": "connection-id", ++ "type": "int" ++ }, ++ { ++ "name": "channel-type", ++ "type": "int" ++ }, ++ { ++ "name": "channel-id", ++ "type": "int" ++ }, ++ { ++ "name": "tls", ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "289", ++ "members": [ ++ { ++ "name": "host", ++ "type": "str" ++ }, ++ { ++ "name": "port", ++ "type": "str" ++ }, ++ { ++ "name": "family", ++ "type": "291" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "290", ++ "members": [ ++ { ++ "name": "host", ++ "type": "str" ++ }, ++ { ++ "name": "port", ++ "type": "str" ++ }, ++ { ++ "name": "family", ++ "type": "291" ++ }, ++ { ++ "name": "auth", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "291", ++ "meta-type": "enum", ++ "values": [ ++ "ipv4", ++ "ipv6", ++ "unix", ++ "vsock", ++ "unknown" ++ ] ++ }, ++ { ++ "name": "[292]", ++ "element-type": "292", ++ "meta-type": "array" ++ }, ++ { ++ "name": "292", ++ "members": [ ++ { ++ "name": "host", ++ "type": "str" ++ }, ++ { ++ "name": "service", ++ "type": "str" ++ }, ++ { ++ "name": "family", ++ "type": "291" ++ }, ++ { ++ "name": "websocket", ++ "type": "bool" ++ }, ++ { ++ "name": "x509_dname", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "sasl_username", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[293]", ++ "element-type": "293", ++ "meta-type": "array" ++ }, ++ { ++ "name": "293", ++ "members": [ ++ { ++ "name": "host", ++ "type": "str" ++ }, ++ { ++ "name": "service", ++ "type": "str" ++ }, ++ { ++ "name": "family", ++ "type": "291" ++ }, ++ { ++ "name": "websocket", ++ "type": "bool" ++ }, ++ { ++ "name": "auth", ++ "type": "294" ++ }, ++ { ++ "name": "vencrypt", ++ "default": null, ++ "type": "295" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "294", ++ "meta-type": "enum", ++ "values": [ ++ "none", ++ "vnc", ++ "ra2", ++ "ra2ne", ++ "tight", ++ "ultra", ++ "tls", ++ "vencrypt", ++ "sasl" ++ ] ++ }, ++ { ++ "name": "295", ++ "meta-type": "enum", ++ "values": [ ++ "plain", ++ "tls-none", ++ "x509-none", ++ "tls-vnc", ++ "x509-vnc", ++ "tls-plain", ++ "x509-plain", ++ "tls-sasl", ++ "x509-sasl" ++ ] ++ }, ++ { ++ "name": "296", ++ "members": [ ++ { ++ "name": "host", ++ "type": "str" ++ }, ++ { ++ "name": "service", ++ "type": "str" ++ }, ++ { ++ "name": "family", ++ "type": "291" ++ }, ++ { ++ "name": "websocket", ++ "type": "bool" ++ }, ++ { ++ "name": "auth", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "297", ++ "members": [ ++ { ++ "name": "host", ++ "type": "str" ++ }, ++ { ++ "name": "service", ++ "type": "str" ++ }, ++ { ++ "name": "family", ++ "type": "291" ++ }, ++ { ++ "name": "websocket", ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[298]", ++ "element-type": "298", ++ "meta-type": "array" ++ }, ++ { ++ "name": "298", ++ "tag": "type", ++ "variants": [ ++ { ++ "case": "number", ++ "type": "416" ++ }, ++ { ++ "case": "qcode", ++ "type": "417" ++ } ++ ], ++ "members": [ ++ { ++ "name": "type", ++ "type": "415" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[299]", ++ "element-type": "299", ++ "meta-type": "array" ++ }, ++ { ++ "name": "299", ++ "tag": "type", ++ "variants": [ ++ { ++ "case": "key", ++ "type": "419" ++ }, ++ { ++ "case": "btn", ++ "type": "420" ++ }, ++ { ++ "case": "rel", ++ "type": "421" ++ }, ++ { ++ "case": "abs", ++ "type": "421" ++ } ++ ], ++ "members": [ ++ { ++ "name": "type", ++ "type": "418" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "300", ++ "meta-type": "enum", ++ "values": [ ++ "default", ++ "none", ++ "gtk", ++ "sdl", ++ "egl-headless", ++ "curses", ++ "cocoa", ++ "spice-app" ++ ] ++ }, ++ { ++ "name": "301", ++ "meta-type": "enum", ++ "values": [ ++ "off", ++ "on", ++ "core", ++ "es" ++ ] ++ }, ++ { ++ "name": "302", ++ "members": [ ++ { ++ "name": "grab-on-hover", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "zoom-to-fit", ++ "default": null, ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "303", ++ "members": [ ++ { ++ "name": "charset", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "304", ++ "members": [ ++ { ++ "name": "rendernode", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "305", ++ "meta-type": "enum", ++ "values": [ ++ "none", ++ "setup", ++ "cancelling", ++ "cancelled", ++ "active", ++ "postcopy-active", ++ "postcopy-paused", ++ "postcopy-recover", ++ "completed", ++ "failed", ++ "colo", ++ "pre-switchover", ++ "device" ++ ] ++ }, ++ { ++ "name": "306", ++ "members": [ ++ { ++ "name": "transferred", ++ "type": "int" ++ }, ++ { ++ "name": "remaining", ++ "type": "int" ++ }, ++ { ++ "name": "total", ++ "type": "int" ++ }, ++ { ++ "name": "duplicate", ++ "type": "int" ++ }, ++ { ++ "name": "skipped", ++ "type": "int" ++ }, ++ { ++ "name": "normal", ++ "type": "int" ++ }, ++ { ++ "name": "normal-bytes", ++ "type": "int" ++ }, ++ { ++ "name": "dirty-pages-rate", ++ "type": "int" ++ }, ++ { ++ "name": "mbps", ++ "type": "number" ++ }, ++ { ++ "name": "dirty-sync-count", ++ "type": "int" ++ }, ++ { ++ "name": "postcopy-requests", ++ "type": "int" ++ }, ++ { ++ "name": "page-size", ++ "type": "int" ++ }, ++ { ++ "name": "multifd-bytes", ++ "type": "int" ++ }, ++ { ++ "name": "pages-per-second", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "307", ++ "members": [ ++ { ++ "name": "cache-size", ++ "type": "int" ++ }, ++ { ++ "name": "bytes", ++ "type": "int" ++ }, ++ { ++ "name": "pages", ++ "type": "int" ++ }, ++ { ++ "name": "cache-miss", ++ "type": "int" ++ }, ++ { ++ "name": "cache-miss-rate", ++ "type": "number" ++ }, ++ { ++ "name": "overflow", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "308", ++ "members": [ ++ { ++ "name": "pages", ++ "type": "int" ++ }, ++ { ++ "name": "busy", ++ "type": "int" ++ }, ++ { ++ "name": "busy-rate", ++ "type": "number" ++ }, ++ { ++ "name": "compressed-size", ++ "type": "int" ++ }, ++ { ++ "name": "compression-rate", ++ "type": "number" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[309]", ++ "element-type": "309", ++ "meta-type": "array" ++ }, ++ { ++ "name": "309", ++ "tag": "type", ++ "variants": [ ++ { ++ "case": "inet", ++ "type": "378" ++ }, ++ { ++ "case": "unix", ++ "type": "423" ++ }, ++ { ++ "case": "vsock", ++ "type": "424" ++ }, ++ { ++ "case": "fd", ++ "type": "425" ++ } ++ ], ++ "members": [ ++ { ++ "name": "type", ++ "type": "422" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "310", ++ "meta-type": "enum", ++ "values": [ ++ "xbzrle", ++ "rdma-pin-all", ++ "auto-converge", ++ "zero-blocks", ++ "compress", ++ "events", ++ "postcopy-ram", ++ "x-colo", ++ "release-ram", ++ "block", ++ "return-path", ++ "pause-before-switchover", ++ "multifd", ++ "dirty-bitmaps", ++ "postcopy-blocktime", ++ "late-block-activate", ++ "x-ignore-shared" ++ ] ++ }, ++ { ++ "name": "311", ++ "meta-type": "enum", ++ "values": [ ++ "none", ++ "primary", ++ "secondary" ++ ] ++ }, ++ { ++ "name": "312", ++ "meta-type": "enum", ++ "values": [ ++ "none", ++ "request", ++ "error", ++ "processing" ++ ] ++ }, ++ { ++ "name": "number", ++ "json-type": "number", ++ "meta-type": "builtin" ++ }, ++ { ++ "name": "[313]", ++ "element-type": "313", ++ "meta-type": "array" ++ }, ++ { ++ "name": "313", ++ "tag": "type", ++ "variants": [ ++ { ++ "case": "abort", ++ "type": "427" ++ }, ++ { ++ "case": "block-dirty-bitmap-add", ++ "type": "428" ++ }, ++ { ++ "case": "block-dirty-bitmap-clear", ++ "type": "429" ++ }, ++ { ++ "case": "block-dirty-bitmap-enable", ++ "type": "429" ++ }, ++ { ++ "case": "block-dirty-bitmap-disable", ++ "type": "429" ++ }, ++ { ++ "case": "block-dirty-bitmap-merge", ++ "type": "430" ++ }, ++ { ++ "case": "blockdev-backup", ++ "type": "431" ++ }, ++ { ++ "case": "blockdev-snapshot", ++ "type": "432" ++ }, ++ { ++ "case": "blockdev-snapshot-internal-sync", ++ "type": "433" ++ }, ++ { ++ "case": "blockdev-snapshot-sync", ++ "type": "434" ++ }, ++ { ++ "case": "drive-backup", ++ "type": "435" ++ } ++ ], ++ "members": [ ++ { ++ "name": "type", ++ "type": "426" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "314", ++ "members": [ ++ { ++ "name": "completion-mode", ++ "default": null, ++ "type": "436" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "315", ++ "meta-type": "enum", ++ "values": [ ++ "unavailable", ++ "disabled", ++ "enabled" ++ ] ++ }, ++ { ++ "name": "316", ++ "meta-type": "enum", ++ "values": [ ++ "builtin", ++ "enum", ++ "array", ++ "object", ++ "alternate", ++ "command", ++ "event" ++ ] ++ }, ++ { ++ "name": "317", ++ "members": [ ++ { ++ "name": "json-type", ++ "type": "437" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "318", ++ "members": [ ++ { ++ "name": "values", ++ "type": "[str]" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "319", ++ "members": [ ++ { ++ "name": "element-type", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "320", ++ "members": [ ++ { ++ "name": "members", ++ "type": "[438]" ++ }, ++ { ++ "name": "tag", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "variants", ++ "default": null, ++ "type": "[439]" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "321", ++ "members": [ ++ { ++ "name": "members", ++ "type": "[440]" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "322", ++ "members": [ ++ { ++ "name": "arg-type", ++ "type": "str" ++ }, ++ { ++ "name": "ret-type", ++ "type": "str" ++ }, ++ { ++ "name": "allow-oob", ++ "default": null, ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "323", ++ "members": [ ++ { ++ "name": "arg-type", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[324]", ++ "element-type": "324", ++ "meta-type": "array" ++ }, ++ { ++ "name": "324", ++ "meta-type": "enum", ++ "values": [ ++ "oob" ++ ] ++ }, ++ { ++ "name": "325", ++ "members": [ ++ { ++ "name": "major", ++ "type": "int" ++ }, ++ { ++ "name": "minor", ++ "type": "int" ++ }, ++ { ++ "name": "micro", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "326", ++ "members": [ ++ { ++ "name": "node-id", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "socket-id", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "core-id", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "thread-id", ++ "default": null, ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "327", ++ "meta-type": "enum", ++ "values": [ ++ "x86", ++ "sparc", ++ "ppc", ++ "mips", ++ "tricore", ++ "s390", ++ "riscv", ++ "other" ++ ] ++ }, ++ { ++ "name": "328", ++ "members": [ ++ { ++ "name": "pc", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "329", ++ "members": [ ++ { ++ "name": "pc", ++ "type": "int" ++ }, ++ { ++ "name": "npc", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "330", ++ "members": [ ++ { ++ "name": "nip", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "331", ++ "members": [ ++ { ++ "name": "PC", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "332", ++ "members": [ ++ { ++ "name": "PC", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "333", ++ "members": [ ++ { ++ "name": "cpu-state", ++ "type": "441" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "334", ++ "members": [ ++ { ++ "name": "pc", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "335", ++ "meta-type": "enum", ++ "values": [ ++ "aarch64", ++ "alpha", ++ "arm", ++ "cris", ++ "hppa", ++ "i386", ++ "lm32", ++ "m68k", ++ "microblaze", ++ "microblazeel", ++ "mips", ++ "mips64", ++ "mips64el", ++ "mipsel", ++ "moxie", ++ "nios2", ++ "or1k", ++ "ppc", ++ "ppc64", ++ "riscv32", ++ "riscv64", ++ "s390x", ++ "sh4", ++ "sh4eb", ++ "sparc", ++ "sparc64", ++ "tricore", ++ "unicore32", ++ "x86_64", ++ "xtensa", ++ "xtensaeb" ++ ] ++ }, ++ { ++ "name": "[336]", ++ "element-type": "336", ++ "meta-type": "array" ++ }, ++ { ++ "name": "336", ++ "members": [ ++ { ++ "name": "bus", ++ "type": "int" ++ }, ++ { ++ "name": "slot", ++ "type": "int" ++ }, ++ { ++ "name": "function", ++ "type": "int" ++ }, ++ { ++ "name": "class_info", ++ "type": "442" ++ }, ++ { ++ "name": "id", ++ "type": "443" ++ }, ++ { ++ "name": "irq", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "qdev_id", ++ "type": "str" ++ }, ++ { ++ "name": "pci_bridge", ++ "default": null, ++ "type": "444" ++ }, ++ { ++ "name": "regions", ++ "type": "[445]" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "337", ++ "meta-type": "enum", ++ "values": [ ++ "elf", ++ "kdump-zlib", ++ "kdump-lzo", ++ "kdump-snappy", ++ "win-dmp" ++ ] ++ }, ++ { ++ "name": "338", ++ "meta-type": "enum", ++ "values": [ ++ "none", ++ "active", ++ "completed", ++ "failed" ++ ] ++ }, ++ { ++ "name": "[337]", ++ "element-type": "337", ++ "meta-type": "array" ++ }, ++ { ++ "name": "[339]", ++ "element-type": "339", ++ "meta-type": "array" ++ }, ++ { ++ "name": "339", ++ "members": [ ++ { ++ "name": "fd", ++ "type": "int" ++ }, ++ { ++ "name": "opaque", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[340]", ++ "element-type": "340", ++ "meta-type": "array" ++ }, ++ { ++ "name": "340", ++ "members": [ ++ { ++ "name": "name", ++ "type": "str" ++ }, ++ { ++ "name": "type", ++ "type": "446" ++ }, ++ { ++ "name": "help", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "default", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "341", ++ "meta-type": "enum", ++ "values": [ ++ "default", ++ "preferred", ++ "bind", ++ "interleave" ++ ] ++ }, ++ { ++ "name": "342", ++ "meta-type": "enum", ++ "values": [ ++ "dimm", ++ "nvdimm" ++ ] ++ }, ++ { ++ "name": "343", ++ "members": [ ++ { ++ "name": "data", ++ "type": "447" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "344", ++ "meta-type": "enum", ++ "values": [ ++ "DIMM", ++ "CPU" ++ ] ++ }, ++ { ++ "name": "345", ++ "meta-type": "enum", ++ "values": [ ++ "node", ++ "dist", ++ "cpu" ++ ] ++ }, ++ { ++ "name": "346", ++ "members": [ ++ { ++ "name": "nodeid", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "cpus", ++ "default": null, ++ "type": "[int]" ++ }, ++ { ++ "name": "mem", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "memdev", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "347", ++ "members": [ ++ { ++ "name": "src", ++ "type": "int" ++ }, ++ { ++ "name": "dst", ++ "type": "int" ++ }, ++ { ++ "name": "val", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "348", ++ "members": [ ++ { ++ "name": "node-id", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "socket-id", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "core-id", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "thread-id", ++ "default": null, ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "349", ++ "meta-type": "enum", ++ "values": [ ++ "uninit", ++ "launch-update", ++ "launch-secret", ++ "running", ++ "send-update", ++ "receive-update" ++ ] ++ }, ++ { ++ "name": "350", ++ "members": [ ++ { ++ "name": "name", ++ "type": "str" ++ }, ++ { ++ "name": "props", ++ "default": null, ++ "type": "any" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "351", ++ "meta-type": "enum", ++ "values": [ ++ "incompatible", ++ "identical", ++ "superset", ++ "subset" ++ ] ++ }, ++ { ++ "name": "352", ++ "meta-type": "enum", ++ "values": [ ++ "static", ++ "full" ++ ] ++ }, ++ { ++ "name": "353", ++ "meta-type": "enum", ++ "values": [ ++ "hyper-v", ++ "s390" ++ ] ++ }, ++ { ++ "name": "354", ++ "members": [ ++ { ++ "name": "arg1", ++ "type": "int" ++ }, ++ { ++ "name": "arg2", ++ "type": "int" ++ }, ++ { ++ "name": "arg3", ++ "type": "int" ++ }, ++ { ++ "name": "arg4", ++ "type": "int" ++ }, ++ { ++ "name": "arg5", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "355", ++ "members": [ ++ { ++ "name": "core", ++ "type": "int" ++ }, ++ { ++ "name": "psw-mask", ++ "type": "int" ++ }, ++ { ++ "name": "psw-addr", ++ "type": "int" ++ }, ++ { ++ "name": "reason", ++ "type": "448" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "356", ++ "meta-type": "enum", ++ "values": [ ++ "active", ++ "disabled", ++ "frozen", ++ "locked", ++ "inconsistent" ++ ] ++ }, ++ { ++ "name": "[357]", ++ "element-type": "357", ++ "meta-type": "array" ++ }, ++ { ++ "name": "357", ++ "members": [ ++ { ++ "name": "interval_length", ++ "type": "int" ++ }, ++ { ++ "name": "min_rd_latency_ns", ++ "type": "int" ++ }, ++ { ++ "name": "max_rd_latency_ns", ++ "type": "int" ++ }, ++ { ++ "name": "avg_rd_latency_ns", ++ "type": "int" ++ }, ++ { ++ "name": "min_wr_latency_ns", ++ "type": "int" ++ }, ++ { ++ "name": "max_wr_latency_ns", ++ "type": "int" ++ }, ++ { ++ "name": "avg_wr_latency_ns", ++ "type": "int" ++ }, ++ { ++ "name": "min_flush_latency_ns", ++ "type": "int" ++ }, ++ { ++ "name": "max_flush_latency_ns", ++ "type": "int" ++ }, ++ { ++ "name": "avg_flush_latency_ns", ++ "type": "int" ++ }, ++ { ++ "name": "avg_rd_queue_depth", ++ "type": "number" ++ }, ++ { ++ "name": "avg_wr_queue_depth", ++ "type": "number" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "358", ++ "members": [ ++ { ++ "name": "boundaries", ++ "type": "[int]" ++ }, ++ { ++ "name": "bins", ++ "type": "[int]" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[67]", ++ "element-type": "67", ++ "meta-type": "array" ++ }, ++ { ++ "name": "359", ++ "tag": "type", ++ "variants": [ ++ { ++ "case": "qcow2", ++ "type": "450" ++ }, ++ { ++ "case": "vmdk", ++ "type": "451" ++ }, ++ { ++ "case": "luks", ++ "type": "452" ++ } ++ ], ++ "members": [ ++ { ++ "name": "type", ++ "type": "449" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "360", ++ "meta-type": "enum", ++ "values": [ ++ "block-backend", ++ "block-job", ++ "block-driver" ++ ] ++ }, ++ { ++ "name": "[361]", ++ "element-type": "361", ++ "meta-type": "array" ++ }, ++ { ++ "name": "361", ++ "meta-type": "enum", ++ "values": [ ++ "consistent-read", ++ "write", ++ "write-unchanged", ++ "resize", ++ "graph-mod" ++ ] ++ }, ++ { ++ "name": "362", ++ "members": [ ++ { ++ "type": "45" ++ }, ++ { ++ "type": "str" ++ } ++ ], ++ "meta-type": "alternate" ++ }, ++ { ++ "name": "[363]", ++ "element-type": "363", ++ "meta-type": "array" ++ }, ++ { ++ "name": "363", ++ "members": [ ++ { ++ "name": "event", ++ "type": "453" ++ }, ++ { ++ "name": "state", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "errno", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "sector", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "once", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "immediately", ++ "default": null, ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[364]", ++ "element-type": "364", ++ "meta-type": "array" ++ }, ++ { ++ "name": "364", ++ "members": [ ++ { ++ "name": "event", ++ "type": "453" ++ }, ++ { ++ "name": "state", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "new_state", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "365", ++ "meta-type": "enum", ++ "values": [ ++ "auto", ++ "on", ++ "off" ++ ] ++ }, ++ { ++ "name": "366", ++ "meta-type": "enum", ++ "values": [ ++ "threads", ++ "native" ++ ] ++ }, ++ { ++ "name": "367", ++ "meta-type": "enum", ++ "values": [ ++ "tcp", ++ "iser" ++ ] ++ }, ++ { ++ "name": "368", ++ "meta-type": "enum", ++ "values": [ ++ "crc32c", ++ "none", ++ "crc32c-none", ++ "none-crc32c" ++ ] ++ }, ++ { ++ "name": "369", ++ "members": [ ++ { ++ "name": "type", ++ "type": "454" ++ }, ++ { ++ "name": "host", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "370", ++ "members": [ ++ { ++ "type": "45" ++ }, ++ { ++ "type": "str" ++ }, ++ { ++ "type": "null" ++ } ++ ], ++ "meta-type": "alternate" ++ }, ++ { ++ "name": "371", ++ "members": [ ++ { ++ "type": "455" ++ }, ++ { ++ "type": "456" ++ } ++ ], ++ "meta-type": "alternate" ++ }, ++ { ++ "name": "372", ++ "tag": "format", ++ "variants": [ ++ { ++ "case": "aes", ++ "type": "458" ++ }, ++ { ++ "case": "luks", ++ "type": "459" ++ } ++ ], ++ "members": [ ++ { ++ "name": "format", ++ "type": "457" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "373", ++ "tag": "format", ++ "variants": [ ++ { ++ "case": "aes", ++ "type": "458" ++ } ++ ], ++ "members": [ ++ { ++ "name": "format", ++ "type": "460" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[362]", ++ "element-type": "362", ++ "meta-type": "array" ++ }, ++ { ++ "name": "374", ++ "meta-type": "enum", ++ "values": [ ++ "quorum", ++ "fifo" ++ ] ++ }, ++ { ++ "name": "[375]", ++ "element-type": "375", ++ "meta-type": "array" ++ }, ++ { ++ "name": "375", ++ "meta-type": "enum", ++ "values": [ ++ "cephx", ++ "none" ++ ] ++ }, ++ { ++ "name": "[376]", ++ "element-type": "376", ++ "meta-type": "array" ++ }, ++ { ++ "name": "376", ++ "members": [ ++ { ++ "name": "host", ++ "type": "str" ++ }, ++ { ++ "name": "port", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "377", ++ "meta-type": "enum", ++ "values": [ ++ "primary", ++ "secondary" ++ ] ++ }, ++ { ++ "name": "378", ++ "members": [ ++ { ++ "name": "host", ++ "type": "str" ++ }, ++ { ++ "name": "port", ++ "type": "str" ++ }, ++ { ++ "name": "numeric", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "to", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "ipv4", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "ipv6", ++ "default": null, ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "379", ++ "tag": "mode", ++ "variants": [ ++ { ++ "case": "hash", ++ "type": "462" ++ }, ++ { ++ "case": "none", ++ "type": "0" ++ }, ++ { ++ "case": "known_hosts", ++ "type": "0" ++ } ++ ], ++ "members": [ ++ { ++ "name": "mode", ++ "type": "461" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "380", ++ "members": [ ++ { ++ "name": "filename", ++ "type": "str" ++ }, ++ { ++ "name": "size", ++ "type": "int" ++ }, ++ { ++ "name": "preallocation", ++ "default": null, ++ "type": "463" ++ }, ++ { ++ "name": "nocow", ++ "default": null, ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "381", ++ "members": [ ++ { ++ "name": "location", ++ "type": "249" ++ }, ++ { ++ "name": "size", ++ "type": "int" ++ }, ++ { ++ "name": "preallocation", ++ "default": null, ++ "type": "463" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "382", ++ "members": [ ++ { ++ "name": "key-secret", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "cipher-alg", ++ "default": null, ++ "type": "464" ++ }, ++ { ++ "name": "cipher-mode", ++ "default": null, ++ "type": "465" ++ }, ++ { ++ "name": "ivgen-alg", ++ "default": null, ++ "type": "466" ++ }, ++ { ++ "name": "ivgen-hash-alg", ++ "default": null, ++ "type": "467" ++ }, ++ { ++ "name": "hash-alg", ++ "default": null, ++ "type": "467" ++ }, ++ { ++ "name": "iter-time", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "file", ++ "type": "362" ++ }, ++ { ++ "name": "size", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "383", ++ "members": [ ++ { ++ "name": "location", ++ "type": "255" ++ }, ++ { ++ "name": "size", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "384", ++ "members": [ ++ { ++ "name": "file", ++ "type": "362" ++ }, ++ { ++ "name": "size", ++ "type": "int" ++ }, ++ { ++ "name": "cluster-size", ++ "default": null, ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "385", ++ "members": [ ++ { ++ "name": "file", ++ "type": "362" ++ }, ++ { ++ "name": "size", ++ "type": "int" ++ }, ++ { ++ "name": "backing-file", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "encrypt", ++ "default": null, ++ "type": "468" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "386", ++ "members": [ ++ { ++ "name": "file", ++ "type": "362" ++ }, ++ { ++ "name": "data-file", ++ "default": null, ++ "type": "362" ++ }, ++ { ++ "name": "data-file-raw", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "size", ++ "type": "int" ++ }, ++ { ++ "name": "version", ++ "default": null, ++ "type": "469" ++ }, ++ { ++ "name": "backing-file", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "backing-fmt", ++ "default": null, ++ "type": "239" ++ }, ++ { ++ "name": "encrypt", ++ "default": null, ++ "type": "468" ++ }, ++ { ++ "name": "cluster-size", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "preallocation", ++ "default": null, ++ "type": "463" ++ }, ++ { ++ "name": "lazy-refcounts", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "refcount-bits", ++ "default": null, ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "387", ++ "members": [ ++ { ++ "name": "file", ++ "type": "362" ++ }, ++ { ++ "name": "size", ++ "type": "int" ++ }, ++ { ++ "name": "backing-file", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "backing-fmt", ++ "default": null, ++ "type": "239" ++ }, ++ { ++ "name": "cluster-size", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "table-size", ++ "default": null, ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "388", ++ "members": [ ++ { ++ "name": "location", ++ "type": "263" ++ }, ++ { ++ "name": "size", ++ "type": "int" ++ }, ++ { ++ "name": "cluster-size", ++ "default": null, ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "389", ++ "members": [ ++ { ++ "name": "location", ++ "type": "265" ++ }, ++ { ++ "name": "size", ++ "type": "int" ++ }, ++ { ++ "name": "backing-file", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "preallocation", ++ "default": null, ++ "type": "463" ++ }, ++ { ++ "name": "redundancy", ++ "default": null, ++ "type": "470" ++ }, ++ { ++ "name": "object-size", ++ "default": null, ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "390", ++ "members": [ ++ { ++ "name": "location", ++ "type": "266" ++ }, ++ { ++ "name": "size", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "391", ++ "members": [ ++ { ++ "name": "file", ++ "type": "362" ++ }, ++ { ++ "name": "size", ++ "type": "int" ++ }, ++ { ++ "name": "preallocation", ++ "default": null, ++ "type": "463" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "392", ++ "members": [ ++ { ++ "name": "file", ++ "type": "362" ++ }, ++ { ++ "name": "size", ++ "type": "int" ++ }, ++ { ++ "name": "log-size", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "block-size", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "subformat", ++ "default": null, ++ "type": "471" ++ }, ++ { ++ "name": "block-state-zero", ++ "default": null, ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "393", ++ "members": [ ++ { ++ "name": "file", ++ "type": "362" ++ }, ++ { ++ "name": "size", ++ "type": "int" ++ }, ++ { ++ "name": "extents", ++ "default": null, ++ "type": "[362]" ++ }, ++ { ++ "name": "subformat", ++ "default": null, ++ "type": "472" ++ }, ++ { ++ "name": "backing-file", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "adapter-type", ++ "default": null, ++ "type": "473" ++ }, ++ { ++ "name": "hwversion", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "zeroed-grain", ++ "default": null, ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "394", ++ "members": [ ++ { ++ "name": "file", ++ "type": "362" ++ }, ++ { ++ "name": "size", ++ "type": "int" ++ }, ++ { ++ "name": "subformat", ++ "default": null, ++ "type": "474" ++ }, ++ { ++ "name": "force-size", ++ "default": null, ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "null", ++ "json-type": "null", ++ "meta-type": "builtin" ++ }, ++ { ++ "name": "395", ++ "meta-type": "enum", ++ "values": [ ++ "inet", ++ "unix", ++ "vsock", ++ "fd" ++ ] ++ }, ++ { ++ "name": "396", ++ "members": [ ++ { ++ "name": "data", ++ "type": "378" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "397", ++ "members": [ ++ { ++ "name": "data", ++ "type": "423" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "398", ++ "members": [ ++ { ++ "name": "data", ++ "type": "424" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "399", ++ "members": [ ++ { ++ "name": "data", ++ "type": "425" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "400", ++ "meta-type": "enum", ++ "values": [ ++ "file", ++ "serial", ++ "parallel", ++ "pipe", ++ "socket", ++ "udp", ++ "pty", ++ "null", ++ "mux", ++ "msmouse", ++ "wctablet", ++ "braille", ++ "testdev", ++ "stdio", ++ "console", ++ "spicevmc", ++ "spiceport", ++ "vc", ++ "ringbuf", ++ "memory" ++ ] ++ }, ++ { ++ "name": "401", ++ "members": [ ++ { ++ "name": "data", ++ "type": "475" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "402", ++ "members": [ ++ { ++ "name": "data", ++ "type": "476" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "403", ++ "members": [ ++ { ++ "name": "data", ++ "type": "477" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "404", ++ "members": [ ++ { ++ "name": "data", ++ "type": "478" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "405", ++ "members": [ ++ { ++ "name": "data", ++ "type": "479" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "406", ++ "members": [ ++ { ++ "name": "data", ++ "type": "480" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "407", ++ "members": [ ++ { ++ "name": "data", ++ "type": "481" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "408", ++ "members": [ ++ { ++ "name": "data", ++ "type": "482" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "409", ++ "members": [ ++ { ++ "name": "data", ++ "type": "483" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "410", ++ "members": [ ++ { ++ "name": "data", ++ "type": "484" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "411", ++ "members": [ ++ { ++ "name": "data", ++ "type": "485" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "412", ++ "meta-type": "enum", ++ "values": [ ++ "passthrough", ++ "emulator" ++ ] ++ }, ++ { ++ "name": "413", ++ "members": [ ++ { ++ "name": "data", ++ "type": "486" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "414", ++ "members": [ ++ { ++ "name": "data", ++ "type": "487" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "415", ++ "meta-type": "enum", ++ "values": [ ++ "number", ++ "qcode" ++ ] ++ }, ++ { ++ "name": "416", ++ "members": [ ++ { ++ "name": "data", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "417", ++ "members": [ ++ { ++ "name": "data", ++ "type": "488" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "418", ++ "meta-type": "enum", ++ "values": [ ++ "key", ++ "btn", ++ "rel", ++ "abs" ++ ] ++ }, ++ { ++ "name": "419", ++ "members": [ ++ { ++ "name": "data", ++ "type": "489" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "420", ++ "members": [ ++ { ++ "name": "data", ++ "type": "490" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "421", ++ "members": [ ++ { ++ "name": "data", ++ "type": "491" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "422", ++ "meta-type": "enum", ++ "values": [ ++ "inet", ++ "unix", ++ "vsock", ++ "fd" ++ ] ++ }, ++ { ++ "name": "423", ++ "members": [ ++ { ++ "name": "path", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "424", ++ "members": [ ++ { ++ "name": "cid", ++ "type": "str" ++ }, ++ { ++ "name": "port", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "425", ++ "members": [ ++ { ++ "name": "str", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "426", ++ "meta-type": "enum", ++ "values": [ ++ "abort", ++ "block-dirty-bitmap-add", ++ "block-dirty-bitmap-clear", ++ "block-dirty-bitmap-enable", ++ "block-dirty-bitmap-disable", ++ "block-dirty-bitmap-merge", ++ "blockdev-backup", ++ "blockdev-snapshot", ++ "blockdev-snapshot-internal-sync", ++ "blockdev-snapshot-sync", ++ "drive-backup" ++ ] ++ }, ++ { ++ "name": "427", ++ "members": [ ++ { ++ "name": "data", ++ "type": "492" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "428", ++ "members": [ ++ { ++ "name": "data", ++ "type": "31" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "429", ++ "members": [ ++ { ++ "name": "data", ++ "type": "32" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "430", ++ "members": [ ++ { ++ "name": "data", ++ "type": "33" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "431", ++ "members": [ ++ { ++ "name": "data", ++ "type": "27" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "432", ++ "members": [ ++ { ++ "name": "data", ++ "type": "23" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "433", ++ "members": [ ++ { ++ "name": "data", ++ "type": "65" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "434", ++ "members": [ ++ { ++ "name": "data", ++ "type": "22" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "435", ++ "members": [ ++ { ++ "name": "data", ++ "type": "26" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "436", ++ "meta-type": "enum", ++ "values": [ ++ "individual", ++ "grouped" ++ ] ++ }, ++ { ++ "name": "437", ++ "meta-type": "enum", ++ "values": [ ++ "string", ++ "number", ++ "int", ++ "boolean", ++ "null", ++ "object", ++ "array", ++ "value" ++ ] ++ }, ++ { ++ "name": "[438]", ++ "element-type": "438", ++ "meta-type": "array" ++ }, ++ { ++ "name": "438", ++ "members": [ ++ { ++ "name": "name", ++ "type": "str" ++ }, ++ { ++ "name": "type", ++ "type": "str" ++ }, ++ { ++ "name": "default", ++ "default": null, ++ "type": "any" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[439]", ++ "element-type": "439", ++ "meta-type": "array" ++ }, ++ { ++ "name": "439", ++ "members": [ ++ { ++ "name": "case", ++ "type": "str" ++ }, ++ { ++ "name": "type", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[440]", ++ "element-type": "440", ++ "meta-type": "array" ++ }, ++ { ++ "name": "440", ++ "members": [ ++ { ++ "name": "type", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "441", ++ "meta-type": "enum", ++ "values": [ ++ "uninitialized", ++ "stopped", ++ "check-stop", ++ "operating", ++ "load" ++ ] ++ }, ++ { ++ "name": "442", ++ "members": [ ++ { ++ "name": "desc", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "class", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "443", ++ "members": [ ++ { ++ "name": "device", ++ "type": "int" ++ }, ++ { ++ "name": "vendor", ++ "type": "int" ++ }, ++ { ++ "name": "subsystem", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "subsystem-vendor", ++ "default": null, ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "444", ++ "members": [ ++ { ++ "name": "bus", ++ "type": "493" ++ }, ++ { ++ "name": "devices", ++ "default": null, ++ "type": "[336]" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[445]", ++ "element-type": "445", ++ "meta-type": "array" ++ }, ++ { ++ "name": "445", ++ "members": [ ++ { ++ "name": "bar", ++ "type": "int" ++ }, ++ { ++ "name": "type", ++ "type": "str" ++ }, ++ { ++ "name": "address", ++ "type": "int" ++ }, ++ { ++ "name": "size", ++ "type": "int" ++ }, ++ { ++ "name": "prefetch", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "mem_type_64", ++ "default": null, ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "446", ++ "meta-type": "enum", ++ "values": [ ++ "string", ++ "boolean", ++ "number", ++ "size" ++ ] ++ }, ++ { ++ "name": "447", ++ "members": [ ++ { ++ "name": "id", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "addr", ++ "type": "int" ++ }, ++ { ++ "name": "size", ++ "type": "int" ++ }, ++ { ++ "name": "slot", ++ "type": "int" ++ }, ++ { ++ "name": "node", ++ "type": "int" ++ }, ++ { ++ "name": "memdev", ++ "type": "str" ++ }, ++ { ++ "name": "hotplugged", ++ "type": "bool" ++ }, ++ { ++ "name": "hotpluggable", ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "448", ++ "meta-type": "enum", ++ "values": [ ++ "unknown", ++ "disabled-wait", ++ "extint-loop", ++ "pgmint-loop", ++ "opint-loop" ++ ] ++ }, ++ { ++ "name": "449", ++ "meta-type": "enum", ++ "values": [ ++ "qcow2", ++ "vmdk", ++ "luks" ++ ] ++ }, ++ { ++ "name": "450", ++ "members": [ ++ { ++ "name": "data", ++ "type": "494" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "451", ++ "members": [ ++ { ++ "name": "data", ++ "type": "495" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "452", ++ "members": [ ++ { ++ "name": "data", ++ "type": "496" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "453", ++ "meta-type": "enum", ++ "values": [ ++ "l1_update", ++ "l1_grow_alloc_table", ++ "l1_grow_write_table", ++ "l1_grow_activate_table", ++ "l2_load", ++ "l2_update", ++ "l2_update_compressed", ++ "l2_alloc_cow_read", ++ "l2_alloc_write", ++ "read_aio", ++ "read_backing_aio", ++ "read_compressed", ++ "write_aio", ++ "write_compressed", ++ "vmstate_load", ++ "vmstate_save", ++ "cow_read", ++ "cow_write", ++ "reftable_load", ++ "reftable_grow", ++ "reftable_update", ++ "refblock_load", ++ "refblock_update", ++ "refblock_update_part", ++ "refblock_alloc", ++ "refblock_alloc_hookup", ++ "refblock_alloc_write", ++ "refblock_alloc_write_blocks", ++ "refblock_alloc_write_table", ++ "refblock_alloc_switch_table", ++ "cluster_alloc", ++ "cluster_alloc_bytes", ++ "cluster_free", ++ "flush_to_os", ++ "flush_to_disk", ++ "pwritev_rmw_head", ++ "pwritev_rmw_after_head", ++ "pwritev_rmw_tail", ++ "pwritev_rmw_after_tail", ++ "pwritev", ++ "pwritev_zero", ++ "pwritev_done", ++ "empty_image_prepare", ++ "l1_shrink_write_table", ++ "l1_shrink_free_l2_clusters", ++ "cor_write", ++ "cluster_alloc_space" ++ ] ++ }, ++ { ++ "name": "454", ++ "meta-type": "enum", ++ "values": [ ++ "inet" ++ ] ++ }, ++ { ++ "name": "455", ++ "members": [ ++ { ++ "name": "template", ++ "default": null, ++ "type": "456" ++ }, ++ { ++ "name": "main-header", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "active-l1", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "active-l2", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "refcount-table", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "refcount-block", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "snapshot-table", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "inactive-l1", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "inactive-l2", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "bitmap-directory", ++ "default": null, ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "456", ++ "meta-type": "enum", ++ "values": [ ++ "none", ++ "constant", ++ "cached", ++ "all" ++ ] ++ }, ++ { ++ "name": "457", ++ "meta-type": "enum", ++ "values": [ ++ "aes", ++ "luks" ++ ] ++ }, ++ { ++ "name": "458", ++ "members": [ ++ { ++ "name": "key-secret", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "459", ++ "members": [ ++ { ++ "name": "key-secret", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "460", ++ "meta-type": "enum", ++ "values": [ ++ "aes" ++ ] ++ }, ++ { ++ "name": "461", ++ "meta-type": "enum", ++ "values": [ ++ "none", ++ "hash", ++ "known_hosts" ++ ] ++ }, ++ { ++ "name": "462", ++ "members": [ ++ { ++ "name": "type", ++ "type": "497" ++ }, ++ { ++ "name": "hash", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "463", ++ "meta-type": "enum", ++ "values": [ ++ "off", ++ "metadata", ++ "falloc", ++ "full" ++ ] ++ }, ++ { ++ "name": "464", ++ "meta-type": "enum", ++ "values": [ ++ "aes-128", ++ "aes-192", ++ "aes-256", ++ "des-rfb", ++ "3des", ++ "cast5-128", ++ "serpent-128", ++ "serpent-192", ++ "serpent-256", ++ "twofish-128", ++ "twofish-192", ++ "twofish-256" ++ ] ++ }, ++ { ++ "name": "465", ++ "meta-type": "enum", ++ "values": [ ++ "ecb", ++ "cbc", ++ "xts", ++ "ctr" ++ ] ++ }, ++ { ++ "name": "466", ++ "meta-type": "enum", ++ "values": [ ++ "plain", ++ "plain64", ++ "essiv" ++ ] ++ }, ++ { ++ "name": "467", ++ "meta-type": "enum", ++ "values": [ ++ "md5", ++ "sha1", ++ "sha224", ++ "sha256", ++ "sha384", ++ "sha512", ++ "ripemd160" ++ ] ++ }, ++ { ++ "name": "468", ++ "tag": "format", ++ "variants": [ ++ { ++ "case": "qcow", ++ "type": "458" ++ }, ++ { ++ "case": "luks", ++ "type": "499" ++ } ++ ], ++ "members": [ ++ { ++ "name": "format", ++ "type": "498" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "469", ++ "meta-type": "enum", ++ "values": [ ++ "v2", ++ "v3" ++ ] ++ }, ++ { ++ "name": "470", ++ "tag": "type", ++ "variants": [ ++ { ++ "case": "full", ++ "type": "501" ++ }, ++ { ++ "case": "erasure-coded", ++ "type": "502" ++ } ++ ], ++ "members": [ ++ { ++ "name": "type", ++ "type": "500" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "471", ++ "meta-type": "enum", ++ "values": [ ++ "dynamic", ++ "fixed" ++ ] ++ }, ++ { ++ "name": "472", ++ "meta-type": "enum", ++ "values": [ ++ "monolithicSparse", ++ "monolithicFlat", ++ "twoGbMaxExtentSparse", ++ "twoGbMaxExtentFlat", ++ "streamOptimized" ++ ] ++ }, ++ { ++ "name": "473", ++ "meta-type": "enum", ++ "values": [ ++ "ide", ++ "buslogic", ++ "lsilogic", ++ "legacyESX" ++ ] ++ }, ++ { ++ "name": "474", ++ "meta-type": "enum", ++ "values": [ ++ "dynamic", ++ "fixed" ++ ] ++ }, ++ { ++ "name": "475", ++ "members": [ ++ { ++ "name": "logfile", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "logappend", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "in", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "out", ++ "type": "str" ++ }, ++ { ++ "name": "append", ++ "default": null, ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "476", ++ "members": [ ++ { ++ "name": "logfile", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "logappend", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "device", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "477", ++ "members": [ ++ { ++ "name": "logfile", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "logappend", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "addr", ++ "type": "275" ++ }, ++ { ++ "name": "tls-creds", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "tls-authz", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "server", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "wait", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "nodelay", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "telnet", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "tn3270", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "websocket", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "reconnect", ++ "default": null, ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "478", ++ "members": [ ++ { ++ "name": "logfile", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "logappend", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "remote", ++ "type": "275" ++ }, ++ { ++ "name": "local", ++ "default": null, ++ "type": "275" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "479", ++ "members": [ ++ { ++ "name": "logfile", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "logappend", ++ "default": null, ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "480", ++ "members": [ ++ { ++ "name": "logfile", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "logappend", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "chardev", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "481", ++ "members": [ ++ { ++ "name": "logfile", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "logappend", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "signal", ++ "default": null, ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "482", ++ "members": [ ++ { ++ "name": "logfile", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "logappend", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "type", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "483", ++ "members": [ ++ { ++ "name": "logfile", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "logappend", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "fqdn", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "484", ++ "members": [ ++ { ++ "name": "logfile", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "logappend", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "width", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "height", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "cols", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "rows", ++ "default": null, ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "485", ++ "members": [ ++ { ++ "name": "logfile", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "logappend", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "size", ++ "default": null, ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "486", ++ "members": [ ++ { ++ "name": "path", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "cancel-path", ++ "default": null, ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "487", ++ "members": [ ++ { ++ "name": "chardev", ++ "type": "str" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "488", ++ "meta-type": "enum", ++ "values": [ ++ "unmapped", ++ "shift", ++ "shift_r", ++ "alt", ++ "alt_r", ++ "ctrl", ++ "ctrl_r", ++ "menu", ++ "esc", ++ "1", ++ "2", ++ "3", ++ "4", ++ "5", ++ "6", ++ "7", ++ "8", ++ "9", ++ "0", ++ "minus", ++ "equal", ++ "backspace", ++ "tab", ++ "q", ++ "w", ++ "e", ++ "r", ++ "t", ++ "y", ++ "u", ++ "i", ++ "o", ++ "p", ++ "bracket_left", ++ "bracket_right", ++ "ret", ++ "a", ++ "s", ++ "d", ++ "f", ++ "g", ++ "h", ++ "j", ++ "k", ++ "l", ++ "semicolon", ++ "apostrophe", ++ "grave_accent", ++ "backslash", ++ "z", ++ "x", ++ "c", ++ "v", ++ "b", ++ "n", ++ "m", ++ "comma", ++ "dot", ++ "slash", ++ "asterisk", ++ "spc", ++ "caps_lock", ++ "f1", ++ "f2", ++ "f3", ++ "f4", ++ "f5", ++ "f6", ++ "f7", ++ "f8", ++ "f9", ++ "f10", ++ "num_lock", ++ "scroll_lock", ++ "kp_divide", ++ "kp_multiply", ++ "kp_subtract", ++ "kp_add", ++ "kp_enter", ++ "kp_decimal", ++ "sysrq", ++ "kp_0", ++ "kp_1", ++ "kp_2", ++ "kp_3", ++ "kp_4", ++ "kp_5", ++ "kp_6", ++ "kp_7", ++ "kp_8", ++ "kp_9", ++ "less", ++ "f11", ++ "f12", ++ "print", ++ "home", ++ "pgup", ++ "pgdn", ++ "end", ++ "left", ++ "up", ++ "down", ++ "right", ++ "insert", ++ "delete", ++ "stop", ++ "again", ++ "props", ++ "undo", ++ "front", ++ "copy", ++ "open", ++ "paste", ++ "find", ++ "cut", ++ "lf", ++ "help", ++ "meta_l", ++ "meta_r", ++ "compose", ++ "pause", ++ "ro", ++ "hiragana", ++ "henkan", ++ "yen", ++ "muhenkan", ++ "katakanahiragana", ++ "kp_comma", ++ "kp_equals", ++ "power", ++ "sleep", ++ "wake", ++ "audionext", ++ "audioprev", ++ "audiostop", ++ "audioplay", ++ "audiomute", ++ "volumeup", ++ "volumedown", ++ "mediaselect", ++ "mail", ++ "calculator", ++ "computer", ++ "ac_home", ++ "ac_back", ++ "ac_forward", ++ "ac_refresh", ++ "ac_bookmarks" ++ ] ++ }, ++ { ++ "name": "489", ++ "members": [ ++ { ++ "name": "key", ++ "type": "298" ++ }, ++ { ++ "name": "down", ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "490", ++ "members": [ ++ { ++ "name": "button", ++ "type": "503" ++ }, ++ { ++ "name": "down", ++ "type": "bool" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "491", ++ "members": [ ++ { ++ "name": "axis", ++ "type": "504" ++ }, ++ { ++ "name": "value", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "492", ++ "members": [ ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "493", ++ "members": [ ++ { ++ "name": "number", ++ "type": "int" ++ }, ++ { ++ "name": "secondary", ++ "type": "int" ++ }, ++ { ++ "name": "subordinate", ++ "type": "int" ++ }, ++ { ++ "name": "io_range", ++ "type": "505" ++ }, ++ { ++ "name": "memory_range", ++ "type": "505" ++ }, ++ { ++ "name": "prefetchable_range", ++ "type": "505" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "494", ++ "members": [ ++ { ++ "name": "compat", ++ "type": "str" ++ }, ++ { ++ "name": "data-file", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "data-file-raw", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "lazy-refcounts", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "corrupt", ++ "default": null, ++ "type": "bool" ++ }, ++ { ++ "name": "refcount-bits", ++ "type": "int" ++ }, ++ { ++ "name": "encrypt", ++ "default": null, ++ "type": "506" ++ }, ++ { ++ "name": "bitmaps", ++ "default": null, ++ "type": "[507]" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "495", ++ "members": [ ++ { ++ "name": "create-type", ++ "type": "str" ++ }, ++ { ++ "name": "cid", ++ "type": "int" ++ }, ++ { ++ "name": "parent-cid", ++ "type": "int" ++ }, ++ { ++ "name": "extents", ++ "type": "[233]" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "496", ++ "members": [ ++ { ++ "name": "cipher-alg", ++ "type": "464" ++ }, ++ { ++ "name": "cipher-mode", ++ "type": "465" ++ }, ++ { ++ "name": "ivgen-alg", ++ "type": "466" ++ }, ++ { ++ "name": "ivgen-hash-alg", ++ "default": null, ++ "type": "467" ++ }, ++ { ++ "name": "hash-alg", ++ "type": "467" ++ }, ++ { ++ "name": "payload-offset", ++ "type": "int" ++ }, ++ { ++ "name": "master-key-iters", ++ "type": "int" ++ }, ++ { ++ "name": "uuid", ++ "type": "str" ++ }, ++ { ++ "name": "slots", ++ "type": "[508]" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "497", ++ "meta-type": "enum", ++ "values": [ ++ "md5", ++ "sha1" ++ ] ++ }, ++ { ++ "name": "498", ++ "meta-type": "enum", ++ "values": [ ++ "qcow", ++ "luks" ++ ] ++ }, ++ { ++ "name": "499", ++ "members": [ ++ { ++ "name": "key-secret", ++ "default": null, ++ "type": "str" ++ }, ++ { ++ "name": "cipher-alg", ++ "default": null, ++ "type": "464" ++ }, ++ { ++ "name": "cipher-mode", ++ "default": null, ++ "type": "465" ++ }, ++ { ++ "name": "ivgen-alg", ++ "default": null, ++ "type": "466" ++ }, ++ { ++ "name": "ivgen-hash-alg", ++ "default": null, ++ "type": "467" ++ }, ++ { ++ "name": "hash-alg", ++ "default": null, ++ "type": "467" ++ }, ++ { ++ "name": "iter-time", ++ "default": null, ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "500", ++ "meta-type": "enum", ++ "values": [ ++ "full", ++ "erasure-coded" ++ ] ++ }, ++ { ++ "name": "501", ++ "members": [ ++ { ++ "name": "copies", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "502", ++ "members": [ ++ { ++ "name": "data-strips", ++ "type": "int" ++ }, ++ { ++ "name": "parity-strips", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "503", ++ "meta-type": "enum", ++ "values": [ ++ "left", ++ "middle", ++ "right", ++ "wheel-up", ++ "wheel-down", ++ "side", ++ "extra" ++ ] ++ }, ++ { ++ "name": "504", ++ "meta-type": "enum", ++ "values": [ ++ "x", ++ "y" ++ ] ++ }, ++ { ++ "name": "505", ++ "members": [ ++ { ++ "name": "base", ++ "type": "int" ++ }, ++ { ++ "name": "limit", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "506", ++ "tag": "format", ++ "variants": [ ++ { ++ "case": "luks", ++ "type": "496" ++ }, ++ { ++ "case": "aes", ++ "type": "0" ++ } ++ ], ++ "members": [ ++ { ++ "name": "format", ++ "type": "457" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[507]", ++ "element-type": "507", ++ "meta-type": "array" ++ }, ++ { ++ "name": "507", ++ "members": [ ++ { ++ "name": "name", ++ "type": "str" ++ }, ++ { ++ "name": "granularity", ++ "type": "int" ++ }, ++ { ++ "name": "flags", ++ "type": "[509]" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[233]", ++ "element-type": "233", ++ "meta-type": "array" ++ }, ++ { ++ "name": "[508]", ++ "element-type": "508", ++ "meta-type": "array" ++ }, ++ { ++ "name": "508", ++ "members": [ ++ { ++ "name": "active", ++ "type": "bool" ++ }, ++ { ++ "name": "iters", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "stripes", ++ "default": null, ++ "type": "int" ++ }, ++ { ++ "name": "key-offset", ++ "type": "int" ++ } ++ ], ++ "meta-type": "object" ++ }, ++ { ++ "name": "[509]", ++ "element-type": "509", ++ "meta-type": "array" ++ }, ++ { ++ "name": "509", ++ "meta-type": "enum", ++ "values": [ ++ "in-use", ++ "auto" ++ ] ++ } ++ ], ++ "id": "libvirt-49" ++} ++ ++{ ++ "execute": "query-cpu-model-expansion", ++ "arguments": { ++ "type": "static", ++ "model": { ++ "name": "host" ++ } ++ }, ++ "id": "libvirt-50" ++} ++ ++{ ++ "return": { ++ "model": { ++ "name": "base", ++ "props": { ++ "cmov": true, ++ "ia64": false, ++ "ssb-no": false, ++ "aes": true, ++ "mmx": true, ++ "rdpid": false, ++ "arat": true, ++ "gfni": false, ++ "ibrs-all": false, ++ "pause-filter": false, ++ "xsavec": true, ++ "intel-pt": false, ++ "kvm-asyncpf": true, ++ "perfctr-core": false, ++ "mpx": true, ++ "pbe": false, ++ "avx512cd": false, ++ "decodeassists": false, ++ "sse4.1": true, ++ "family": 6, ++ "wbnoinvd": false, ++ "avx512f": false, ++ "msr": true, ++ "mce": true, ++ "mca": true, ++ "xcrypt": false, ++ "min-level": 13, ++ "xgetbv1": true, ++ "cid": false, ++ "ds": false, ++ "fxsr": true, ++ "xsaveopt": true, ++ "xtpr": false, ++ "avx512vl": false, ++ "avx512-vpopcntdq": false, ++ "phe": false, ++ "extapic": false, ++ "3dnowprefetch": true, ++ "avx512vbmi2": false, ++ "cr8legacy": false, ++ "stibp": false, ++ "xcrypt-en": false, ++ "pn": false, ++ "rsba": false, ++ "dca": false, ++ "vendor": "GenuineIntel", ++ "pku": false, ++ "smx": false, ++ "cmp-legacy": false, ++ "avx512-4fmaps": false, ++ "vmcb-clean": false, ++ "hle": true, ++ "3dnowext": false, ++ "amd-no-ssb": false, ++ "npt": false, ++ "rdctl-no": false, ++ "clwb": false, ++ "lbrv": false, ++ "adx": true, ++ "ss": true, ++ "pni": true, ++ "svm-lock": false, ++ "smep": true, ++ "smap": true, ++ "pfthreshold": false, ++ "x2apic": true, ++ "avx512vbmi": false, ++ "avx512vnni": false, ++ "flushbyasid": false, ++ "f16c": true, ++ "ace2-en": false, ++ "pae": true, ++ "pat": true, ++ "sse": true, ++ "phe-en": false, ++ "kvm-nopiodelay": true, ++ "tm": false, ++ "kvmclock-stable-bit": true, ++ "hypervisor": true, ++ "mds-no": false, ++ "pcommit": false, ++ "syscall": true, ++ "avx512dq": false, ++ "svm": false, ++ "invtsc": false, ++ "sse2": true, ++ "ssbd": false, ++ "est": false, ++ "avx512ifma": false, ++ "tm2": false, ++ "kvm-pv-eoi": true, ++ "kvm-pv-ipi": true, ++ "cx8": true, ++ "cldemote": false, ++ "kvm-mmu": false, ++ "sse4.2": true, ++ "pge": true, ++ "avx512bitalg": false, ++ "pdcm": false, ++ "model": 94, ++ "movbe": true, ++ "nrip-save": false, ++ "ssse3": true, ++ "sse4a": false, ++ "invpcid": true, ++ "pdpe1gb": true, ++ "tsc-deadline": true, ++ "skip-l1dfl-vmentry": true, ++ "fma": true, ++ "cx16": true, ++ "de": true, ++ "stepping": 3, ++ "xsave": true, ++ "clflush": true, ++ "skinit": false, ++ "tsc": true, ++ "tce": false, ++ "fpu": true, ++ "ds-cpl": false, ++ "ibs": false, ++ "fma4": false, ++ "la57": false, ++ "osvw": false, ++ "apic": true, ++ "pmm": false, ++ "spec-ctrl": false, ++ "tsc-adjust": true, ++ "kvm-steal-time": true, ++ "kvmclock": true, ++ "lwp": false, ++ "amd-ssbd": false, ++ "xop": false, ++ "ibpb": false, ++ "avx": true, ++ "movdiri": false, ++ "acpi": false, ++ "avx512bw": false, ++ "ace2": false, ++ "fsgsbase": true, ++ "ht": false, ++ "nx": true, ++ "pclmulqdq": true, ++ "mmxext": false, ++ "popcnt": true, ++ "vaes": false, ++ "movdir64b": false, ++ "xsaves": true, ++ "lm": true, ++ "umip": true, ++ "pse": true, ++ "avx2": true, ++ "sep": true, ++ "virt-ssbd": false, ++ "nodeid-msr": false, ++ "md-clear": false, ++ "misalignsse": false, ++ "min-xlevel": 2147483656, ++ "bmi1": true, ++ "bmi2": true, ++ "kvm-pv-unhalt": true, ++ "tsc-scale": false, ++ "topoext": false, ++ "clflushopt": true, ++ "monitor": false, ++ "avx512er": false, ++ "pmm-en": false, ++ "pcid": true, ++ "arch-capabilities": true, ++ "3dnow": false, ++ "erms": true, ++ "lahf-lm": true, ++ "vpclmulqdq": false, ++ "fxsr-opt": false, ++ "xstore": false, ++ "rtm": true, ++ "kvm-hint-dedicated": false, ++ "lmce": true, ++ "perfctr-nb": false, ++ "rdrand": true, ++ "rdseed": true, ++ "avx512-4vnniw": false, ++ "vme": true, ++ "vmx": true, ++ "dtes64": false, ++ "mtrr": true, ++ "rdtscp": true, ++ "pse36": true, ++ "kvm-pv-tlb-flush": true, ++ "tbm": false, ++ "wdt": false, ++ "model-id": "Intel(R) Xeon(R) CPU E3-1245 v5 @ 3.50GHz", ++ "sha-ni": false, ++ "abm": true, ++ "avx512pf": false, ++ "xstore-en": false ++ } ++ } ++ }, ++ "id": "libvirt-50" ++} ++ ++{ ++ "execute": "query-cpu-model-expansion", ++ "arguments": { ++ "type": "full", ++ "model": { ++ "name": "base", ++ "props": { ++ "cmov": true, ++ "ia64": false, ++ "ssb-no": false, ++ "aes": true, ++ "mmx": true, ++ "rdpid": false, ++ "arat": true, ++ "gfni": false, ++ "ibrs-all": false, ++ "pause-filter": false, ++ "xsavec": true, ++ "intel-pt": false, ++ "kvm-asyncpf": true, ++ "perfctr-core": false, ++ "mpx": true, ++ "pbe": false, ++ "avx512cd": false, ++ "decodeassists": false, ++ "sse4.1": true, ++ "family": 6, ++ "wbnoinvd": false, ++ "avx512f": false, ++ "msr": true, ++ "mce": true, ++ "mca": true, ++ "xcrypt": false, ++ "min-level": 13, ++ "xgetbv1": true, ++ "cid": false, ++ "ds": false, ++ "fxsr": true, ++ "xsaveopt": true, ++ "xtpr": false, ++ "avx512vl": false, ++ "avx512-vpopcntdq": false, ++ "phe": false, ++ "extapic": false, ++ "3dnowprefetch": true, ++ "avx512vbmi2": false, ++ "cr8legacy": false, ++ "stibp": false, ++ "xcrypt-en": false, ++ "pn": false, ++ "rsba": false, ++ "dca": false, ++ "vendor": "GenuineIntel", ++ "pku": false, ++ "smx": false, ++ "cmp-legacy": false, ++ "avx512-4fmaps": false, ++ "vmcb-clean": false, ++ "hle": true, ++ "3dnowext": false, ++ "amd-no-ssb": false, ++ "npt": false, ++ "rdctl-no": false, ++ "clwb": false, ++ "lbrv": false, ++ "adx": true, ++ "ss": true, ++ "pni": true, ++ "svm-lock": false, ++ "smep": true, ++ "smap": true, ++ "pfthreshold": false, ++ "x2apic": true, ++ "avx512vbmi": false, ++ "avx512vnni": false, ++ "flushbyasid": false, ++ "f16c": true, ++ "ace2-en": false, ++ "pae": true, ++ "pat": true, ++ "sse": true, ++ "phe-en": false, ++ "kvm-nopiodelay": true, ++ "tm": false, ++ "kvmclock-stable-bit": true, ++ "hypervisor": true, ++ "mds-no": false, ++ "pcommit": false, ++ "syscall": true, ++ "avx512dq": false, ++ "svm": false, ++ "invtsc": false, ++ "sse2": true, ++ "ssbd": false, ++ "est": false, ++ "avx512ifma": false, ++ "tm2": false, ++ "kvm-pv-eoi": true, ++ "kvm-pv-ipi": true, ++ "cx8": true, ++ "cldemote": false, ++ "kvm-mmu": false, ++ "sse4.2": true, ++ "pge": true, ++ "avx512bitalg": false, ++ "pdcm": false, ++ "model": 94, ++ "movbe": true, ++ "nrip-save": false, ++ "ssse3": true, ++ "sse4a": false, ++ "invpcid": true, ++ "pdpe1gb": true, ++ "tsc-deadline": true, ++ "skip-l1dfl-vmentry": true, ++ "fma": true, ++ "cx16": true, ++ "de": true, ++ "stepping": 3, ++ "xsave": true, ++ "clflush": true, ++ "skinit": false, ++ "tsc": true, ++ "tce": false, ++ "fpu": true, ++ "ds-cpl": false, ++ "ibs": false, ++ "fma4": false, ++ "la57": false, ++ "osvw": false, ++ "apic": true, ++ "pmm": false, ++ "spec-ctrl": false, ++ "tsc-adjust": true, ++ "kvm-steal-time": true, ++ "kvmclock": true, ++ "lwp": false, ++ "amd-ssbd": false, ++ "xop": false, ++ "ibpb": false, ++ "avx": true, ++ "movdiri": false, ++ "acpi": false, ++ "avx512bw": false, ++ "ace2": false, ++ "fsgsbase": true, ++ "ht": false, ++ "nx": true, ++ "pclmulqdq": true, ++ "mmxext": false, ++ "popcnt": true, ++ "vaes": false, ++ "movdir64b": false, ++ "xsaves": true, ++ "lm": true, ++ "umip": true, ++ "pse": true, ++ "avx2": true, ++ "sep": true, ++ "virt-ssbd": false, ++ "nodeid-msr": false, ++ "md-clear": false, ++ "misalignsse": false, ++ "min-xlevel": 2147483656, ++ "bmi1": true, ++ "bmi2": true, ++ "kvm-pv-unhalt": true, ++ "tsc-scale": false, ++ "topoext": false, ++ "clflushopt": true, ++ "monitor": false, ++ "avx512er": false, ++ "pmm-en": false, ++ "pcid": true, ++ "arch-capabilities": true, ++ "3dnow": false, ++ "erms": true, ++ "lahf-lm": true, ++ "vpclmulqdq": false, ++ "fxsr-opt": false, ++ "xstore": false, ++ "rtm": true, ++ "kvm-hint-dedicated": false, ++ "lmce": true, ++ "perfctr-nb": false, ++ "rdrand": true, ++ "rdseed": true, ++ "avx512-4vnniw": false, ++ "vme": true, ++ "vmx": true, ++ "dtes64": false, ++ "mtrr": true, ++ "rdtscp": true, ++ "pse36": true, ++ "kvm-pv-tlb-flush": true, ++ "tbm": false, ++ "wdt": false, ++ "model-id": "Intel(R) Xeon(R) CPU E3-1245 v5 @ 3.50GHz", ++ "sha-ni": false, ++ "abm": true, ++ "avx512pf": false, ++ "xstore-en": false ++ } ++ } ++ }, ++ "id": "libvirt-51" ++} ++ ++{ ++ "return": { ++ "model": { ++ "name": "base", ++ "props": { ++ "phys-bits": 0, ++ "core-id": -1, ++ "xlevel": 2147483656, ++ "cmov": true, ++ "ia64": false, ++ "ssb-no": false, ++ "aes": true, ++ "mmx": true, ++ "rdpid": false, ++ "arat": true, ++ "gfni": false, ++ "ibrs-all": false, ++ "pause-filter": false, ++ "xsavec": true, ++ "intel-pt": false, ++ "hv-frequencies": false, ++ "tsc-frequency": 0, ++ "xd": true, ++ "x-intel-pt-auto-level": true, ++ "hv-vendor-id": "", ++ "kvm-asyncpf": true, ++ "kvm_asyncpf": true, ++ "perfctr_core": false, ++ "perfctr-core": false, ++ "mpx": true, ++ "pbe": false, ++ "decodeassists": false, ++ "avx512cd": false, ++ "sse4_1": true, ++ "sse4.1": true, ++ "sse4-1": true, ++ "family": 6, ++ "legacy-cache": true, ++ "host-phys-bits-limit": 0, ++ "vmware-cpuid-freq": true, ++ "wbnoinvd": false, ++ "avx512f": false, ++ "msr": true, ++ "mce": true, ++ "mca": true, ++ "hv-runtime": false, ++ "xcrypt": false, ++ "thread-id": -1, ++ "min-level": 13, ++ "xgetbv1": true, ++ "cid": false, ++ "hv-relaxed": false, ++ "hv-crash": false, ++ "ds": false, ++ "fxsr": true, ++ "xsaveopt": true, ++ "xtpr": false, ++ "hv-evmcs": false, ++ "avx512vl": false, ++ "avx512-vpopcntdq": false, ++ "phe": false, ++ "extapic": false, ++ "3dnowprefetch": true, ++ "avx512vbmi2": false, ++ "cr8legacy": false, ++ "stibp": false, ++ "cpuid-0xb": true, ++ "xcrypt-en": false, ++ "kvm_pv_eoi": true, ++ "apic-id": 4294967295, ++ "rsba": false, ++ "pn": false, ++ "dca": false, ++ "vendor": "GenuineIntel", ++ "hv-ipi": false, ++ "pku": false, ++ "smx": false, ++ "cmp_legacy": false, ++ "cmp-legacy": false, ++ "node-id": -1, ++ "avx512-4fmaps": false, ++ "vmcb_clean": false, ++ "vmcb-clean": false, ++ "3dnowext": false, ++ "amd-no-ssb": false, ++ "hle": true, ++ "npt": false, ++ "rdctl-no": false, ++ "memory": "/machine/unattached/system[0]", ++ "clwb": false, ++ "lbrv": false, ++ "adx": true, ++ "ss": true, ++ "pni": true, ++ "svm_lock": false, ++ "svm-lock": false, ++ "pfthreshold": false, ++ "smep": true, ++ "smap": true, ++ "x2apic": true, ++ "avx512vbmi": false, ++ "avx512vnni": false, ++ "hv-stimer": false, ++ "x-hv-synic-kvm-only": false, ++ "i64": true, ++ "flushbyasid": false, ++ "f16c": true, ++ "ace2-en": false, ++ "pat": true, ++ "pae": true, ++ "sse": true, ++ "phe-en": false, ++ "kvm_nopiodelay": true, ++ "kvm-nopiodelay": true, ++ "tm": false, ++ "kvmclock-stable-bit": true, ++ "hypervisor": true, ++ "socket-id": -1, ++ "mds-no": false, ++ "pcommit": false, ++ "syscall": true, ++ "level": 13, ++ "avx512dq": false, ++ "x-migrate-smi-count": true, ++ "svm": false, ++ "full-cpuid-auto-level": true, ++ "hv-reset": false, ++ "invtsc": false, ++ "sse3": true, ++ "sse2": true, ++ "ssbd": false, ++ "est": false, ++ "avx512ifma": false, ++ "tm2": false, ++ "kvm-pv-ipi": true, ++ "kvm-pv-eoi": true, ++ "cx8": true, ++ "cldemote": false, ++ "hv-reenlightenment": false, ++ "kvm_mmu": false, ++ "kvm-mmu": false, ++ "sse4_2": true, ++ "sse4.2": true, ++ "sse4-2": true, ++ "pge": true, ++ "fill-mtrr-mask": true, ++ "avx512bitalg": false, ++ "nodeid_msr": false, ++ "pdcm": false, ++ "movbe": true, ++ "model": 94, ++ "nrip_save": false, ++ "nrip-save": false, ++ "kvm_pv_unhalt": true, ++ "ssse3": true, ++ "sse4a": false, ++ "invpcid": true, ++ "pdpe1gb": true, ++ "tsc-deadline": true, ++ "skip-l1dfl-vmentry": true, ++ "fma": true, ++ "cx16": true, ++ "de": true, ++ "enforce": false, ++ "stepping": 3, ++ "xsave": true, ++ "clflush": true, ++ "skinit": false, ++ "tsc": true, ++ "tce": false, ++ "fpu": true, ++ "ibs": false, ++ "ds_cpl": false, ++ "ds-cpl": false, ++ "host-phys-bits": false, ++ "fma4": false, ++ "la57": false, ++ "osvw": false, ++ "check": true, ++ "hv-spinlocks": -1, ++ "pmm": false, ++ "pmu": false, ++ "apic": true, ++ "spec-ctrl": false, ++ "min-xlevel2": 0, ++ "tsc-adjust": true, ++ "tsc_adjust": true, ++ "kvm-steal-time": true, ++ "kvm_steal_time": true, ++ "kvmclock": true, ++ "l3-cache": true, ++ "lwp": false, ++ "amd-ssbd": false, ++ "ibpb": false, ++ "xop": false, ++ "avx": true, ++ "movdiri": false, ++ "ace2": false, ++ "avx512bw": false, ++ "acpi": false, ++ "hv-vapic": false, ++ "fsgsbase": true, ++ "ht": false, ++ "nx": true, ++ "pclmulqdq": true, ++ "mmxext": false, ++ "vaes": false, ++ "popcnt": true, ++ "xsaves": true, ++ "movdir64b": false, ++ "tcg-cpuid": true, ++ "lm": true, ++ "umip": true, ++ "pse": true, ++ "avx2": true, ++ "sep": true, ++ "pclmuldq": true, ++ "virt-ssbd": false, ++ "x-hv-max-vps": -1, ++ "nodeid-msr": false, ++ "md-clear": false, ++ "kvm": true, ++ "misalignsse": false, ++ "min-xlevel": 2147483656, ++ "kvm-pv-unhalt": true, ++ "bmi2": true, ++ "bmi1": true, ++ "realized": false, ++ "tsc_scale": false, ++ "tsc-scale": false, ++ "topoext": false, ++ "hv-vpindex": false, ++ "xlevel2": 0, ++ "clflushopt": true, ++ "kvm-no-smi-migration": false, ++ "monitor": false, ++ "avx512er": false, ++ "pmm-en": false, ++ "pcid": true, ++ "arch-capabilities": true, ++ "3dnow": false, ++ "erms": true, ++ "lahf-lm": true, ++ "lahf_lm": true, ++ "vpclmulqdq": false, ++ "fxsr-opt": false, ++ "hv-synic": false, ++ "xstore": false, ++ "fxsr_opt": false, ++ "kvm-hint-dedicated": false, ++ "rtm": true, ++ "lmce": true, ++ "hv-time": false, ++ "perfctr-nb": false, ++ "perfctr_nb": false, ++ "ffxsr": false, ++ "hv-tlbflush": false, ++ "rdrand": true, ++ "rdseed": true, ++ "avx512-4vnniw": false, ++ "vmx": true, ++ "vme": true, ++ "dtes64": false, ++ "mtrr": true, ++ "rdtscp": true, ++ "pse36": true, ++ "kvm-pv-tlb-flush": true, ++ "tbm": false, ++ "wdt": false, ++ "pause_filter": false, ++ "sha-ni": false, ++ "model-id": "Intel(R) Xeon(R) CPU E3-1245 v5 @ 3.50GHz", ++ "abm": true, ++ "avx512pf": false, ++ "xstore-en": false ++ } ++ } ++ }, ++ "id": "libvirt-51" ++} ++ ++{ ++ "execute": "query-cpu-model-expansion", ++ "arguments": { ++ "type": "static", ++ "model": { ++ "name": "host", ++ "props": { ++ "migratable": false ++ } ++ } ++ }, ++ "id": "libvirt-52" ++} ++ ++{ ++ "return": { ++ "model": { ++ "name": "base", ++ "props": { ++ "cmov": true, ++ "ia64": false, ++ "ssb-no": false, ++ "aes": true, ++ "mmx": true, ++ "rdpid": false, ++ "arat": true, ++ "gfni": false, ++ "ibrs-all": false, ++ "pause-filter": false, ++ "xsavec": true, ++ "intel-pt": false, ++ "kvm-asyncpf": true, ++ "perfctr-core": false, ++ "mpx": true, ++ "pbe": false, ++ "avx512cd": false, ++ "decodeassists": false, ++ "sse4.1": true, ++ "family": 6, ++ "wbnoinvd": false, ++ "avx512f": false, ++ "msr": true, ++ "mce": true, ++ "mca": true, ++ "xcrypt": false, ++ "min-level": 13, ++ "xgetbv1": true, ++ "cid": false, ++ "ds": false, ++ "fxsr": true, ++ "xsaveopt": true, ++ "xtpr": false, ++ "avx512vl": false, ++ "avx512-vpopcntdq": false, ++ "phe": false, ++ "extapic": false, ++ "3dnowprefetch": true, ++ "avx512vbmi2": false, ++ "cr8legacy": false, ++ "stibp": false, ++ "xcrypt-en": false, ++ "pn": false, ++ "rsba": false, ++ "dca": false, ++ "vendor": "GenuineIntel", ++ "pku": false, ++ "smx": false, ++ "cmp-legacy": false, ++ "avx512-4fmaps": false, ++ "vmcb-clean": false, ++ "hle": true, ++ "3dnowext": false, ++ "amd-no-ssb": false, ++ "npt": false, ++ "rdctl-no": false, ++ "clwb": false, ++ "lbrv": false, ++ "adx": true, ++ "ss": true, ++ "pni": true, ++ "svm-lock": false, ++ "smep": true, ++ "smap": true, ++ "pfthreshold": false, ++ "x2apic": true, ++ "avx512vbmi": false, ++ "avx512vnni": false, ++ "flushbyasid": false, ++ "f16c": true, ++ "ace2-en": false, ++ "pae": true, ++ "pat": true, ++ "sse": true, ++ "phe-en": false, ++ "kvm-nopiodelay": true, ++ "tm": false, ++ "kvmclock-stable-bit": true, ++ "hypervisor": true, ++ "mds-no": false, ++ "pcommit": false, ++ "syscall": true, ++ "avx512dq": false, ++ "svm": false, ++ "invtsc": false, ++ "sse2": true, ++ "ssbd": false, ++ "est": false, ++ "avx512ifma": false, ++ "tm2": false, ++ "kvm-pv-eoi": true, ++ "kvm-pv-ipi": true, ++ "cx8": true, ++ "cldemote": false, ++ "kvm-mmu": false, ++ "sse4.2": true, ++ "pge": true, ++ "avx512bitalg": false, ++ "pdcm": false, ++ "model": 94, ++ "movbe": true, ++ "nrip-save": false, ++ "ssse3": true, ++ "sse4a": false, ++ "invpcid": true, ++ "pdpe1gb": true, ++ "tsc-deadline": true, ++ "skip-l1dfl-vmentry": true, ++ "fma": true, ++ "cx16": true, ++ "de": true, ++ "stepping": 3, ++ "xsave": true, ++ "clflush": true, ++ "skinit": false, ++ "tsc": true, ++ "tce": false, ++ "fpu": true, ++ "ds-cpl": false, ++ "ibs": false, ++ "fma4": false, ++ "la57": false, ++ "osvw": false, ++ "apic": true, ++ "pmm": false, ++ "spec-ctrl": false, ++ "tsc-adjust": true, ++ "kvm-steal-time": true, ++ "kvmclock": true, ++ "lwp": false, ++ "amd-ssbd": false, ++ "xop": false, ++ "ibpb": false, ++ "avx": true, ++ "movdiri": false, ++ "acpi": false, ++ "avx512bw": false, ++ "ace2": false, ++ "fsgsbase": true, ++ "ht": false, ++ "nx": true, ++ "pclmulqdq": true, ++ "mmxext": false, ++ "popcnt": true, ++ "vaes": false, ++ "movdir64b": false, ++ "xsaves": true, ++ "lm": true, ++ "umip": true, ++ "pse": true, ++ "avx2": true, ++ "sep": true, ++ "virt-ssbd": false, ++ "nodeid-msr": false, ++ "md-clear": false, ++ "misalignsse": false, ++ "min-xlevel": 2147483656, ++ "bmi1": true, ++ "bmi2": true, ++ "kvm-pv-unhalt": true, ++ "tsc-scale": false, ++ "topoext": false, ++ "clflushopt": true, ++ "monitor": false, ++ "avx512er": false, ++ "pmm-en": false, ++ "pcid": true, ++ "arch-capabilities": true, ++ "3dnow": false, ++ "erms": true, ++ "lahf-lm": true, ++ "vpclmulqdq": false, ++ "fxsr-opt": false, ++ "xstore": false, ++ "rtm": true, ++ "kvm-hint-dedicated": false, ++ "lmce": true, ++ "perfctr-nb": false, ++ "rdrand": true, ++ "rdseed": true, ++ "avx512-4vnniw": false, ++ "vme": true, ++ "vmx": true, ++ "dtes64": false, ++ "mtrr": true, ++ "rdtscp": true, ++ "pse36": true, ++ "kvm-pv-tlb-flush": true, ++ "tbm": false, ++ "wdt": false, ++ "model-id": "Intel(R) Xeon(R) CPU E3-1245 v5 @ 3.50GHz", ++ "sha-ni": false, ++ "abm": true, ++ "avx512pf": false, ++ "xstore-en": false ++ } ++ } ++ }, ++ "id": "libvirt-52" ++} ++ ++{ ++ "execute": "query-cpu-model-expansion", ++ "arguments": { ++ "type": "full", ++ "model": { ++ "name": "base", ++ "props": { ++ "cmov": true, ++ "ia64": false, ++ "ssb-no": false, ++ "aes": true, ++ "mmx": true, ++ "rdpid": false, ++ "arat": true, ++ "gfni": false, ++ "ibrs-all": false, ++ "pause-filter": false, ++ "xsavec": true, ++ "intel-pt": false, ++ "kvm-asyncpf": true, ++ "perfctr-core": false, ++ "mpx": true, ++ "pbe": false, ++ "avx512cd": false, ++ "decodeassists": false, ++ "sse4.1": true, ++ "family": 6, ++ "wbnoinvd": false, ++ "avx512f": false, ++ "msr": true, ++ "mce": true, ++ "mca": true, ++ "xcrypt": false, ++ "min-level": 13, ++ "xgetbv1": true, ++ "cid": false, ++ "ds": false, ++ "fxsr": true, ++ "xsaveopt": true, ++ "xtpr": false, ++ "avx512vl": false, ++ "avx512-vpopcntdq": false, ++ "phe": false, ++ "extapic": false, ++ "3dnowprefetch": true, ++ "avx512vbmi2": false, ++ "cr8legacy": false, ++ "stibp": false, ++ "xcrypt-en": false, ++ "pn": false, ++ "rsba": false, ++ "dca": false, ++ "vendor": "GenuineIntel", ++ "pku": false, ++ "smx": false, ++ "cmp-legacy": false, ++ "avx512-4fmaps": false, ++ "vmcb-clean": false, ++ "hle": true, ++ "3dnowext": false, ++ "amd-no-ssb": false, ++ "npt": false, ++ "rdctl-no": false, ++ "clwb": false, ++ "lbrv": false, ++ "adx": true, ++ "ss": true, ++ "pni": true, ++ "svm-lock": false, ++ "smep": true, ++ "smap": true, ++ "pfthreshold": false, ++ "x2apic": true, ++ "avx512vbmi": false, ++ "avx512vnni": false, ++ "flushbyasid": false, ++ "f16c": true, ++ "ace2-en": false, ++ "pae": true, ++ "pat": true, ++ "sse": true, ++ "phe-en": false, ++ "kvm-nopiodelay": true, ++ "tm": false, ++ "kvmclock-stable-bit": true, ++ "hypervisor": true, ++ "mds-no": false, ++ "pcommit": false, ++ "syscall": true, ++ "avx512dq": false, ++ "svm": false, ++ "invtsc": false, ++ "sse2": true, ++ "ssbd": false, ++ "est": false, ++ "avx512ifma": false, ++ "tm2": false, ++ "kvm-pv-eoi": true, ++ "kvm-pv-ipi": true, ++ "cx8": true, ++ "cldemote": false, ++ "kvm-mmu": false, ++ "sse4.2": true, ++ "pge": true, ++ "avx512bitalg": false, ++ "pdcm": false, ++ "model": 94, ++ "movbe": true, ++ "nrip-save": false, ++ "ssse3": true, ++ "sse4a": false, ++ "invpcid": true, ++ "pdpe1gb": true, ++ "tsc-deadline": true, ++ "skip-l1dfl-vmentry": true, ++ "fma": true, ++ "cx16": true, ++ "de": true, ++ "stepping": 3, ++ "xsave": true, ++ "clflush": true, ++ "skinit": false, ++ "tsc": true, ++ "tce": false, ++ "fpu": true, ++ "ds-cpl": false, ++ "ibs": false, ++ "fma4": false, ++ "la57": false, ++ "osvw": false, ++ "apic": true, ++ "pmm": false, ++ "spec-ctrl": false, ++ "tsc-adjust": true, ++ "kvm-steal-time": true, ++ "kvmclock": true, ++ "lwp": false, ++ "amd-ssbd": false, ++ "xop": false, ++ "ibpb": false, ++ "avx": true, ++ "movdiri": false, ++ "acpi": false, ++ "avx512bw": false, ++ "ace2": false, ++ "fsgsbase": true, ++ "ht": false, ++ "nx": true, ++ "pclmulqdq": true, ++ "mmxext": false, ++ "popcnt": true, ++ "vaes": false, ++ "movdir64b": false, ++ "xsaves": true, ++ "lm": true, ++ "umip": true, ++ "pse": true, ++ "avx2": true, ++ "sep": true, ++ "virt-ssbd": false, ++ "nodeid-msr": false, ++ "md-clear": false, ++ "misalignsse": false, ++ "min-xlevel": 2147483656, ++ "bmi1": true, ++ "bmi2": true, ++ "kvm-pv-unhalt": true, ++ "tsc-scale": false, ++ "topoext": false, ++ "clflushopt": true, ++ "monitor": false, ++ "avx512er": false, ++ "pmm-en": false, ++ "pcid": true, ++ "arch-capabilities": true, ++ "3dnow": false, ++ "erms": true, ++ "lahf-lm": true, ++ "vpclmulqdq": false, ++ "fxsr-opt": false, ++ "xstore": false, ++ "rtm": true, ++ "kvm-hint-dedicated": false, ++ "lmce": true, ++ "perfctr-nb": false, ++ "rdrand": true, ++ "rdseed": true, ++ "avx512-4vnniw": false, ++ "vme": true, ++ "vmx": true, ++ "dtes64": false, ++ "mtrr": true, ++ "rdtscp": true, ++ "pse36": true, ++ "kvm-pv-tlb-flush": true, ++ "tbm": false, ++ "wdt": false, ++ "model-id": "Intel(R) Xeon(R) CPU E3-1245 v5 @ 3.50GHz", ++ "sha-ni": false, ++ "abm": true, ++ "avx512pf": false, ++ "xstore-en": false ++ } ++ } ++ }, ++ "id": "libvirt-53" ++} ++ ++{ ++ "return": { ++ "model": { ++ "name": "base", ++ "props": { ++ "phys-bits": 0, ++ "core-id": -1, ++ "xlevel": 2147483656, ++ "cmov": true, ++ "ia64": false, ++ "ssb-no": false, ++ "aes": true, ++ "mmx": true, ++ "rdpid": false, ++ "arat": true, ++ "gfni": false, ++ "ibrs-all": false, ++ "pause-filter": false, ++ "xsavec": true, ++ "intel-pt": false, ++ "hv-frequencies": false, ++ "tsc-frequency": 0, ++ "xd": true, ++ "x-intel-pt-auto-level": true, ++ "hv-vendor-id": "", ++ "kvm-asyncpf": true, ++ "kvm_asyncpf": true, ++ "perfctr_core": false, ++ "perfctr-core": false, ++ "mpx": true, ++ "pbe": false, ++ "decodeassists": false, ++ "avx512cd": false, ++ "sse4_1": true, ++ "sse4.1": true, ++ "sse4-1": true, ++ "family": 6, ++ "legacy-cache": true, ++ "host-phys-bits-limit": 0, ++ "vmware-cpuid-freq": true, ++ "wbnoinvd": false, ++ "avx512f": false, ++ "msr": true, ++ "mce": true, ++ "mca": true, ++ "hv-runtime": false, ++ "xcrypt": false, ++ "thread-id": -1, ++ "min-level": 13, ++ "xgetbv1": true, ++ "cid": false, ++ "hv-relaxed": false, ++ "hv-crash": false, ++ "ds": false, ++ "fxsr": true, ++ "xsaveopt": true, ++ "xtpr": false, ++ "hv-evmcs": false, ++ "avx512vl": false, ++ "avx512-vpopcntdq": false, ++ "phe": false, ++ "extapic": false, ++ "3dnowprefetch": true, ++ "avx512vbmi2": false, ++ "cr8legacy": false, ++ "stibp": false, ++ "cpuid-0xb": true, ++ "xcrypt-en": false, ++ "kvm_pv_eoi": true, ++ "apic-id": 4294967295, ++ "rsba": false, ++ "pn": false, ++ "dca": false, ++ "vendor": "GenuineIntel", ++ "hv-ipi": false, ++ "pku": false, ++ "smx": false, ++ "cmp_legacy": false, ++ "cmp-legacy": false, ++ "node-id": -1, ++ "avx512-4fmaps": false, ++ "vmcb_clean": false, ++ "vmcb-clean": false, ++ "3dnowext": false, ++ "amd-no-ssb": false, ++ "hle": true, ++ "npt": false, ++ "rdctl-no": false, ++ "memory": "/machine/unattached/system[0]", ++ "clwb": false, ++ "lbrv": false, ++ "adx": true, ++ "ss": true, ++ "pni": true, ++ "svm_lock": false, ++ "svm-lock": false, ++ "pfthreshold": false, ++ "smep": true, ++ "smap": true, ++ "x2apic": true, ++ "avx512vbmi": false, ++ "avx512vnni": false, ++ "hv-stimer": false, ++ "x-hv-synic-kvm-only": false, ++ "i64": true, ++ "flushbyasid": false, ++ "f16c": true, ++ "ace2-en": false, ++ "pat": true, ++ "pae": true, ++ "sse": true, ++ "phe-en": false, ++ "kvm_nopiodelay": true, ++ "kvm-nopiodelay": true, ++ "tm": false, ++ "kvmclock-stable-bit": true, ++ "hypervisor": true, ++ "socket-id": -1, ++ "mds-no": false, ++ "pcommit": false, ++ "syscall": true, ++ "level": 13, ++ "avx512dq": false, ++ "x-migrate-smi-count": true, ++ "svm": false, ++ "full-cpuid-auto-level": true, ++ "hv-reset": false, ++ "invtsc": false, ++ "sse3": true, ++ "sse2": true, ++ "ssbd": false, ++ "est": false, ++ "avx512ifma": false, ++ "tm2": false, ++ "kvm-pv-ipi": true, ++ "kvm-pv-eoi": true, ++ "cx8": true, ++ "cldemote": false, ++ "hv-reenlightenment": false, ++ "kvm_mmu": false, ++ "kvm-mmu": false, ++ "sse4_2": true, ++ "sse4.2": true, ++ "sse4-2": true, ++ "pge": true, ++ "fill-mtrr-mask": true, ++ "avx512bitalg": false, ++ "nodeid_msr": false, ++ "pdcm": false, ++ "movbe": true, ++ "model": 94, ++ "nrip_save": false, ++ "nrip-save": false, ++ "kvm_pv_unhalt": true, ++ "ssse3": true, ++ "sse4a": false, ++ "invpcid": true, ++ "pdpe1gb": true, ++ "tsc-deadline": true, ++ "skip-l1dfl-vmentry": true, ++ "fma": true, ++ "cx16": true, ++ "de": true, ++ "enforce": false, ++ "stepping": 3, ++ "xsave": true, ++ "clflush": true, ++ "skinit": false, ++ "tsc": true, ++ "tce": false, ++ "fpu": true, ++ "ibs": false, ++ "ds_cpl": false, ++ "ds-cpl": false, ++ "host-phys-bits": false, ++ "fma4": false, ++ "la57": false, ++ "osvw": false, ++ "check": true, ++ "hv-spinlocks": -1, ++ "pmm": false, ++ "pmu": false, ++ "apic": true, ++ "spec-ctrl": false, ++ "min-xlevel2": 0, ++ "tsc-adjust": true, ++ "tsc_adjust": true, ++ "kvm-steal-time": true, ++ "kvm_steal_time": true, ++ "kvmclock": true, ++ "l3-cache": true, ++ "lwp": false, ++ "amd-ssbd": false, ++ "ibpb": false, ++ "xop": false, ++ "avx": true, ++ "movdiri": false, ++ "ace2": false, ++ "avx512bw": false, ++ "acpi": false, ++ "hv-vapic": false, ++ "fsgsbase": true, ++ "ht": false, ++ "nx": true, ++ "pclmulqdq": true, ++ "mmxext": false, ++ "vaes": false, ++ "popcnt": true, ++ "xsaves": true, ++ "movdir64b": false, ++ "tcg-cpuid": true, ++ "lm": true, ++ "umip": true, ++ "pse": true, ++ "avx2": true, ++ "sep": true, ++ "pclmuldq": true, ++ "virt-ssbd": false, ++ "x-hv-max-vps": -1, ++ "nodeid-msr": false, ++ "md-clear": false, ++ "kvm": true, ++ "misalignsse": false, ++ "min-xlevel": 2147483656, ++ "kvm-pv-unhalt": true, ++ "bmi2": true, ++ "bmi1": true, ++ "realized": false, ++ "tsc_scale": false, ++ "tsc-scale": false, ++ "topoext": false, ++ "hv-vpindex": false, ++ "xlevel2": 0, ++ "clflushopt": true, ++ "kvm-no-smi-migration": false, ++ "monitor": false, ++ "avx512er": false, ++ "pmm-en": false, ++ "pcid": true, ++ "arch-capabilities": true, ++ "3dnow": false, ++ "erms": true, ++ "lahf-lm": true, ++ "lahf_lm": true, ++ "vpclmulqdq": false, ++ "fxsr-opt": false, ++ "hv-synic": false, ++ "xstore": false, ++ "fxsr_opt": false, ++ "kvm-hint-dedicated": false, ++ "rtm": true, ++ "lmce": true, ++ "hv-time": false, ++ "perfctr-nb": false, ++ "perfctr_nb": false, ++ "ffxsr": false, ++ "hv-tlbflush": false, ++ "rdrand": true, ++ "rdseed": true, ++ "avx512-4vnniw": false, ++ "vmx": true, ++ "vme": true, ++ "dtes64": false, ++ "mtrr": true, ++ "rdtscp": true, ++ "pse36": true, ++ "kvm-pv-tlb-flush": true, ++ "tbm": false, ++ "wdt": false, ++ "pause_filter": false, ++ "sha-ni": false, ++ "model-id": "Intel(R) Xeon(R) CPU E3-1245 v5 @ 3.50GHz", ++ "abm": true, ++ "avx512pf": false, ++ "xstore-en": false ++ } ++ } ++ }, ++ "id": "libvirt-53" ++} ++ ++{ ++ "execute": "query-sev-capabilities", ++ "id": "libvirt-54" ++} ++ ++{ ++ "id": "libvirt-54", ++ "error": { ++ "class": "GenericError", ++ "desc": "SEV feature is not available" ++ } ++} ++ ++{ ++ "execute": "qmp_capabilities", ++ "id": "libvirt-1" ++} ++ ++{ ++ "return": { ++ }, ++ "id": "libvirt-1" ++} ++ ++{ ++ "execute": "query-cpu-definitions", ++ "id": "libvirt-2" ++} ++ ++{ ++ "return": [ ++ { ++ "name": "max", ++ "typename": "max-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": false ++ }, ++ { ++ "name": "host", ++ "typename": "host-x86_64-cpu", ++ "unavailable-features": [ ++ "kvm" ++ ], ++ "static": false, ++ "migration-safe": false ++ }, ++ { ++ "name": "base", ++ "typename": "base-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": true, ++ "migration-safe": true ++ }, ++ { ++ "name": "qemu64", ++ "typename": "qemu64-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "qemu32", ++ "typename": "qemu32-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "phenom", ++ "typename": "phenom-x86_64-cpu", ++ "unavailable-features": [ ++ "fxsr-opt" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "pentium3", ++ "typename": "pentium3-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "pentium2", ++ "typename": "pentium2-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "pentium", ++ "typename": "pentium-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "n270", ++ "typename": "n270-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "kvm64", ++ "typename": "kvm64-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "kvm32", ++ "typename": "kvm32-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "coreduo", ++ "typename": "coreduo-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "core2duo", ++ "typename": "core2duo-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "athlon", ++ "typename": "athlon-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Westmere-IBRS", ++ "typename": "Westmere-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "spec-ctrl" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Westmere", ++ "typename": "Westmere-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Server-IBRS", ++ "typename": "Skylake-Server-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "x2apic", ++ "tsc-deadline", ++ "avx", ++ "f16c", ++ "hle", ++ "avx2", ++ "invpcid", ++ "rtm", ++ "avx512f", ++ "avx512dq", ++ "rdseed", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "spec-ctrl", ++ "3dnowprefetch", ++ "xsavec" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Server", ++ "typename": "Skylake-Server-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "x2apic", ++ "tsc-deadline", ++ "avx", ++ "f16c", ++ "hle", ++ "avx2", ++ "invpcid", ++ "rtm", ++ "avx512f", ++ "avx512dq", ++ "rdseed", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "3dnowprefetch", ++ "xsavec" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Client-IBRS", ++ "typename": "Skylake-Client-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "x2apic", ++ "tsc-deadline", ++ "avx", ++ "f16c", ++ "hle", ++ "avx2", ++ "invpcid", ++ "rtm", ++ "rdseed", ++ "spec-ctrl", ++ "3dnowprefetch", ++ "xsavec" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Client", ++ "typename": "Skylake-Client-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "x2apic", ++ "tsc-deadline", ++ "avx", ++ "f16c", ++ "hle", ++ "avx2", ++ "invpcid", ++ "rtm", ++ "rdseed", ++ "3dnowprefetch", ++ "xsavec" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "SandyBridge-IBRS", ++ "typename": "SandyBridge-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "x2apic", ++ "tsc-deadline", ++ "avx", ++ "spec-ctrl" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "SandyBridge", ++ "typename": "SandyBridge-x86_64-cpu", ++ "unavailable-features": [ ++ "x2apic", ++ "tsc-deadline", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Penryn", ++ "typename": "Penryn-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G5", ++ "typename": "Opteron_G5-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "avx", ++ "f16c", ++ "misalignsse", ++ "3dnowprefetch", ++ "xop", ++ "fma4", ++ "tbm", ++ "nrip-save" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G4", ++ "typename": "Opteron_G4-x86_64-cpu", ++ "unavailable-features": [ ++ "avx", ++ "misalignsse", ++ "3dnowprefetch", ++ "xop", ++ "fma4", ++ "nrip-save" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G3", ++ "typename": "Opteron_G3-x86_64-cpu", ++ "unavailable-features": [ ++ "misalignsse" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G2", ++ "typename": "Opteron_G2-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G1", ++ "typename": "Opteron_G1-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Nehalem-IBRS", ++ "typename": "Nehalem-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "spec-ctrl" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Nehalem", ++ "typename": "Nehalem-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "KnightsMill", ++ "typename": "KnightsMill-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "x2apic", ++ "tsc-deadline", ++ "avx", ++ "f16c", ++ "avx2", ++ "avx512f", ++ "rdseed", ++ "avx512pf", ++ "avx512er", ++ "avx512cd", ++ "avx512-vpopcntdq", ++ "avx512-4vnniw", ++ "avx512-4fmaps", ++ "3dnowprefetch" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "IvyBridge-IBRS", ++ "typename": "IvyBridge-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "x2apic", ++ "tsc-deadline", ++ "avx", ++ "f16c", ++ "spec-ctrl" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "IvyBridge", ++ "typename": "IvyBridge-x86_64-cpu", ++ "unavailable-features": [ ++ "x2apic", ++ "tsc-deadline", ++ "avx", ++ "f16c" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Icelake-Server", ++ "typename": "Icelake-Server-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "x2apic", ++ "tsc-deadline", ++ "avx", ++ "f16c", ++ "hle", ++ "avx2", ++ "invpcid", ++ "rtm", ++ "avx512f", ++ "avx512dq", ++ "rdseed", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "avx512vbmi", ++ "umip", ++ "avx512vbmi2", ++ "gfni", ++ "vaes", ++ "vpclmulqdq", ++ "avx512vnni", ++ "avx512bitalg", ++ "avx512-vpopcntdq", ++ "spec-ctrl", ++ "ssbd", ++ "3dnowprefetch", ++ "wbnoinvd", ++ "xsavec" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Icelake-Client", ++ "typename": "Icelake-Client-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "x2apic", ++ "tsc-deadline", ++ "avx", ++ "f16c", ++ "hle", ++ "avx2", ++ "invpcid", ++ "rtm", ++ "rdseed", ++ "avx512vbmi", ++ "umip", ++ "avx512vbmi2", ++ "gfni", ++ "vaes", ++ "vpclmulqdq", ++ "avx512vnni", ++ "avx512bitalg", ++ "avx512-vpopcntdq", ++ "spec-ctrl", ++ "ssbd", ++ "3dnowprefetch", ++ "wbnoinvd", ++ "xsavec" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-noTSX-IBRS", ++ "typename": "Haswell-noTSX-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "x2apic", ++ "tsc-deadline", ++ "avx", ++ "f16c", ++ "avx2", ++ "invpcid", ++ "spec-ctrl" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-noTSX", ++ "typename": "Haswell-noTSX-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "x2apic", ++ "tsc-deadline", ++ "avx", ++ "f16c", ++ "avx2", ++ "invpcid" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-IBRS", ++ "typename": "Haswell-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "x2apic", ++ "tsc-deadline", ++ "avx", ++ "f16c", ++ "hle", ++ "avx2", ++ "invpcid", ++ "rtm", ++ "spec-ctrl" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell", ++ "typename": "Haswell-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "x2apic", ++ "tsc-deadline", ++ "avx", ++ "f16c", ++ "hle", ++ "avx2", ++ "invpcid", ++ "rtm" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "EPYC-IBPB", ++ "typename": "EPYC-IBPB-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "avx", ++ "f16c", ++ "avx2", ++ "rdseed", ++ "sha-ni", ++ "fxsr-opt", ++ "misalignsse", ++ "3dnowprefetch", ++ "osvw", ++ "topoext", ++ "ibpb", ++ "nrip-save", ++ "xsavec" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "EPYC", ++ "typename": "EPYC-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "avx", ++ "f16c", ++ "avx2", ++ "rdseed", ++ "sha-ni", ++ "fxsr-opt", ++ "misalignsse", ++ "3dnowprefetch", ++ "osvw", ++ "topoext", ++ "nrip-save", ++ "xsavec" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Dhyana", ++ "typename": "Dhyana-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "avx", ++ "f16c", ++ "avx2", ++ "rdseed", ++ "fxsr-opt", ++ "misalignsse", ++ "3dnowprefetch", ++ "osvw", ++ "topoext", ++ "ibpb", ++ "nrip-save", ++ "xsavec" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Conroe", ++ "typename": "Conroe-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Cascadelake-Server", ++ "typename": "Cascadelake-Server-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "x2apic", ++ "tsc-deadline", ++ "avx", ++ "f16c", ++ "hle", ++ "avx2", ++ "invpcid", ++ "rtm", ++ "avx512f", ++ "avx512dq", ++ "rdseed", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "avx512vnni", ++ "spec-ctrl", ++ "ssbd", ++ "3dnowprefetch", ++ "xsavec" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-noTSX-IBRS", ++ "typename": "Broadwell-noTSX-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "x2apic", ++ "tsc-deadline", ++ "avx", ++ "f16c", ++ "avx2", ++ "invpcid", ++ "rdseed", ++ "spec-ctrl", ++ "3dnowprefetch" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-noTSX", ++ "typename": "Broadwell-noTSX-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "x2apic", ++ "tsc-deadline", ++ "avx", ++ "f16c", ++ "avx2", ++ "invpcid", ++ "rdseed", ++ "3dnowprefetch" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-IBRS", ++ "typename": "Broadwell-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "x2apic", ++ "tsc-deadline", ++ "avx", ++ "f16c", ++ "hle", ++ "avx2", ++ "invpcid", ++ "rtm", ++ "rdseed", ++ "spec-ctrl", ++ "3dnowprefetch" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell", ++ "typename": "Broadwell-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "x2apic", ++ "tsc-deadline", ++ "avx", ++ "f16c", ++ "hle", ++ "avx2", ++ "invpcid", ++ "rtm", ++ "rdseed", ++ "3dnowprefetch" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "486", ++ "typename": "486-x86_64-cpu", ++ "unavailable-features": [ ++ ], ++ "static": false, ++ "migration-safe": true ++ } ++ ], ++ "id": "libvirt-2" ++} ++ ++{ ++ "execute": "query-cpu-model-expansion", ++ "arguments": { ++ "type": "static", ++ "model": { ++ "name": "max" ++ } ++ }, ++ "id": "libvirt-3" ++} ++ ++{ ++ "return": { ++ "model": { ++ "name": "base", ++ "props": { ++ "cmov": true, ++ "ia64": false, ++ "ssb-no": false, ++ "aes": true, ++ "mmx": true, ++ "rdpid": false, ++ "arat": true, ++ "gfni": false, ++ "ibrs-all": false, ++ "pause-filter": false, ++ "xsavec": false, ++ "intel-pt": false, ++ "kvm-asyncpf": false, ++ "perfctr-core": false, ++ "mpx": true, ++ "pbe": false, ++ "avx512cd": false, ++ "decodeassists": false, ++ "sse4.1": true, ++ "family": 6, ++ "wbnoinvd": false, ++ "avx512f": false, ++ "msr": true, ++ "mce": true, ++ "mca": true, ++ "xcrypt": false, ++ "min-level": 13, ++ "xgetbv1": true, ++ "cid": false, ++ "ds": false, ++ "fxsr": true, ++ "xsaveopt": true, ++ "xtpr": false, ++ "avx512vl": false, ++ "avx512-vpopcntdq": false, ++ "phe": false, ++ "extapic": false, ++ "3dnowprefetch": false, ++ "avx512vbmi2": false, ++ "cr8legacy": true, ++ "stibp": false, ++ "xcrypt-en": false, ++ "pn": false, ++ "rsba": false, ++ "dca": false, ++ "vendor": "AuthenticAMD", ++ "pku": true, ++ "smx": false, ++ "cmp-legacy": false, ++ "avx512-4fmaps": false, ++ "vmcb-clean": false, ++ "hle": false, ++ "3dnowext": true, ++ "amd-no-ssb": false, ++ "npt": true, ++ "rdctl-no": false, ++ "clwb": true, ++ "lbrv": false, ++ "adx": true, ++ "ss": true, ++ "pni": true, ++ "svm-lock": false, ++ "smep": true, ++ "smap": true, ++ "pfthreshold": false, ++ "x2apic": false, ++ "avx512vbmi": false, ++ "avx512vnni": false, ++ "flushbyasid": false, ++ "f16c": false, ++ "ace2-en": false, ++ "pae": true, ++ "pat": true, ++ "sse": true, ++ "phe-en": false, ++ "kvm-nopiodelay": false, ++ "tm": false, ++ "kvmclock-stable-bit": false, ++ "hypervisor": true, ++ "mds-no": false, ++ "pcommit": true, ++ "syscall": true, ++ "avx512dq": false, ++ "svm": true, ++ "invtsc": false, ++ "sse2": true, ++ "ssbd": false, ++ "est": false, ++ "avx512ifma": false, ++ "tm2": false, ++ "kvm-pv-eoi": false, ++ "kvm-pv-ipi": false, ++ "cx8": true, ++ "cldemote": false, ++ "kvm-mmu": false, ++ "sse4.2": true, ++ "pge": true, ++ "avx512bitalg": false, ++ "pdcm": false, ++ "model": 6, ++ "movbe": true, ++ "nrip-save": false, ++ "ssse3": true, ++ "sse4a": true, ++ "invpcid": false, ++ "pdpe1gb": true, ++ "tsc-deadline": false, ++ "skip-l1dfl-vmentry": false, ++ "fma": false, ++ "cx16": true, ++ "de": true, ++ "stepping": 3, ++ "xsave": true, ++ "clflush": true, ++ "skinit": false, ++ "tsc": true, ++ "tce": false, ++ "fpu": true, ++ "ds-cpl": false, ++ "ibs": false, ++ "fma4": false, ++ "la57": true, ++ "osvw": false, ++ "apic": true, ++ "pmm": false, ++ "spec-ctrl": false, ++ "tsc-adjust": false, ++ "kvm-steal-time": false, ++ "kvmclock": false, ++ "lwp": false, ++ "amd-ssbd": false, ++ "xop": false, ++ "ibpb": false, ++ "avx": false, ++ "movdiri": false, ++ "acpi": true, ++ "avx512bw": false, ++ "ace2": false, ++ "fsgsbase": true, ++ "ht": false, ++ "nx": true, ++ "pclmulqdq": true, ++ "mmxext": true, ++ "popcnt": true, ++ "vaes": false, ++ "movdir64b": false, ++ "xsaves": false, ++ "lm": true, ++ "umip": false, ++ "pse": true, ++ "avx2": false, ++ "sep": true, ++ "virt-ssbd": false, ++ "nodeid-msr": false, ++ "md-clear": false, ++ "misalignsse": false, ++ "min-xlevel": 2147483658, ++ "bmi1": true, ++ "bmi2": true, ++ "kvm-pv-unhalt": false, ++ "tsc-scale": false, ++ "topoext": false, ++ "clflushopt": true, ++ "monitor": true, ++ "avx512er": false, ++ "pmm-en": false, ++ "pcid": false, ++ "arch-capabilities": false, ++ "3dnow": true, ++ "erms": true, ++ "lahf-lm": true, ++ "vpclmulqdq": false, ++ "fxsr-opt": false, ++ "xstore": false, ++ "rtm": false, ++ "kvm-hint-dedicated": false, ++ "lmce": false, ++ "perfctr-nb": false, ++ "rdrand": true, ++ "rdseed": false, ++ "avx512-4vnniw": false, ++ "vme": false, ++ "vmx": false, ++ "dtes64": false, ++ "mtrr": true, ++ "rdtscp": true, ++ "pse36": true, ++ "kvm-pv-tlb-flush": false, ++ "tbm": false, ++ "wdt": false, ++ "model-id": "QEMU TCG CPU version 2.5+", ++ "sha-ni": false, ++ "abm": true, ++ "avx512pf": false, ++ "xstore-en": false ++ } ++ } ++ }, ++ "id": "libvirt-3" ++} ++ ++{ ++ "execute": "query-cpu-model-expansion", ++ "arguments": { ++ "type": "full", ++ "model": { ++ "name": "base", ++ "props": { ++ "cmov": true, ++ "ia64": false, ++ "ssb-no": false, ++ "aes": true, ++ "mmx": true, ++ "rdpid": false, ++ "arat": true, ++ "gfni": false, ++ "ibrs-all": false, ++ "pause-filter": false, ++ "xsavec": false, ++ "intel-pt": false, ++ "kvm-asyncpf": false, ++ "perfctr-core": false, ++ "mpx": true, ++ "pbe": false, ++ "avx512cd": false, ++ "decodeassists": false, ++ "sse4.1": true, ++ "family": 6, ++ "wbnoinvd": false, ++ "avx512f": false, ++ "msr": true, ++ "mce": true, ++ "mca": true, ++ "xcrypt": false, ++ "min-level": 13, ++ "xgetbv1": true, ++ "cid": false, ++ "ds": false, ++ "fxsr": true, ++ "xsaveopt": true, ++ "xtpr": false, ++ "avx512vl": false, ++ "avx512-vpopcntdq": false, ++ "phe": false, ++ "extapic": false, ++ "3dnowprefetch": false, ++ "avx512vbmi2": false, ++ "cr8legacy": true, ++ "stibp": false, ++ "xcrypt-en": false, ++ "pn": false, ++ "rsba": false, ++ "dca": false, ++ "vendor": "AuthenticAMD", ++ "pku": true, ++ "smx": false, ++ "cmp-legacy": false, ++ "avx512-4fmaps": false, ++ "vmcb-clean": false, ++ "hle": false, ++ "3dnowext": true, ++ "amd-no-ssb": false, ++ "npt": true, ++ "rdctl-no": false, ++ "clwb": true, ++ "lbrv": false, ++ "adx": true, ++ "ss": true, ++ "pni": true, ++ "svm-lock": false, ++ "smep": true, ++ "smap": true, ++ "pfthreshold": false, ++ "x2apic": false, ++ "avx512vbmi": false, ++ "avx512vnni": false, ++ "flushbyasid": false, ++ "f16c": false, ++ "ace2-en": false, ++ "pae": true, ++ "pat": true, ++ "sse": true, ++ "phe-en": false, ++ "kvm-nopiodelay": false, ++ "tm": false, ++ "kvmclock-stable-bit": false, ++ "hypervisor": true, ++ "mds-no": false, ++ "pcommit": true, ++ "syscall": true, ++ "avx512dq": false, ++ "svm": true, ++ "invtsc": false, ++ "sse2": true, ++ "ssbd": false, ++ "est": false, ++ "avx512ifma": false, ++ "tm2": false, ++ "kvm-pv-eoi": false, ++ "kvm-pv-ipi": false, ++ "cx8": true, ++ "cldemote": false, ++ "kvm-mmu": false, ++ "sse4.2": true, ++ "pge": true, ++ "avx512bitalg": false, ++ "pdcm": false, ++ "model": 6, ++ "movbe": true, ++ "nrip-save": false, ++ "ssse3": true, ++ "sse4a": true, ++ "invpcid": false, ++ "pdpe1gb": true, ++ "tsc-deadline": false, ++ "skip-l1dfl-vmentry": false, ++ "fma": false, ++ "cx16": true, ++ "de": true, ++ "stepping": 3, ++ "xsave": true, ++ "clflush": true, ++ "skinit": false, ++ "tsc": true, ++ "tce": false, ++ "fpu": true, ++ "ds-cpl": false, ++ "ibs": false, ++ "fma4": false, ++ "la57": true, ++ "osvw": false, ++ "apic": true, ++ "pmm": false, ++ "spec-ctrl": false, ++ "tsc-adjust": false, ++ "kvm-steal-time": false, ++ "kvmclock": false, ++ "lwp": false, ++ "amd-ssbd": false, ++ "xop": false, ++ "ibpb": false, ++ "avx": false, ++ "movdiri": false, ++ "acpi": true, ++ "avx512bw": false, ++ "ace2": false, ++ "fsgsbase": true, ++ "ht": false, ++ "nx": true, ++ "pclmulqdq": true, ++ "mmxext": true, ++ "popcnt": true, ++ "vaes": false, ++ "movdir64b": false, ++ "xsaves": false, ++ "lm": true, ++ "umip": false, ++ "pse": true, ++ "avx2": false, ++ "sep": true, ++ "virt-ssbd": false, ++ "nodeid-msr": false, ++ "md-clear": false, ++ "misalignsse": false, ++ "min-xlevel": 2147483658, ++ "bmi1": true, ++ "bmi2": true, ++ "kvm-pv-unhalt": false, ++ "tsc-scale": false, ++ "topoext": false, ++ "clflushopt": true, ++ "monitor": true, ++ "avx512er": false, ++ "pmm-en": false, ++ "pcid": false, ++ "arch-capabilities": false, ++ "3dnow": true, ++ "erms": true, ++ "lahf-lm": true, ++ "vpclmulqdq": false, ++ "fxsr-opt": false, ++ "xstore": false, ++ "rtm": false, ++ "kvm-hint-dedicated": false, ++ "lmce": false, ++ "perfctr-nb": false, ++ "rdrand": true, ++ "rdseed": false, ++ "avx512-4vnniw": false, ++ "vme": false, ++ "vmx": false, ++ "dtes64": false, ++ "mtrr": true, ++ "rdtscp": true, ++ "pse36": true, ++ "kvm-pv-tlb-flush": false, ++ "tbm": false, ++ "wdt": false, ++ "model-id": "QEMU TCG CPU version 2.5+", ++ "sha-ni": false, ++ "abm": true, ++ "avx512pf": false, ++ "xstore-en": false ++ } ++ } ++ }, ++ "id": "libvirt-4" ++} ++ ++{ ++ "return": { ++ "model": { ++ "name": "base", ++ "props": { ++ "phys-bits": 0, ++ "core-id": -1, ++ "xlevel": 2147483658, ++ "cmov": true, ++ "ia64": false, ++ "ssb-no": false, ++ "aes": true, ++ "mmx": true, ++ "rdpid": false, ++ "arat": true, ++ "gfni": false, ++ "ibrs-all": false, ++ "pause-filter": false, ++ "xsavec": false, ++ "intel-pt": false, ++ "hv-frequencies": false, ++ "tsc-frequency": 0, ++ "xd": true, ++ "x-intel-pt-auto-level": true, ++ "hv-vendor-id": "", ++ "kvm-asyncpf": false, ++ "kvm_asyncpf": false, ++ "perfctr_core": false, ++ "perfctr-core": false, ++ "mpx": true, ++ "pbe": false, ++ "decodeassists": false, ++ "avx512cd": false, ++ "sse4_1": true, ++ "sse4.1": true, ++ "sse4-1": true, ++ "family": 6, ++ "legacy-cache": true, ++ "host-phys-bits-limit": 0, ++ "vmware-cpuid-freq": true, ++ "wbnoinvd": false, ++ "avx512f": false, ++ "msr": true, ++ "mce": true, ++ "mca": true, ++ "hv-runtime": false, ++ "xcrypt": false, ++ "thread-id": -1, ++ "min-level": 13, ++ "xgetbv1": true, ++ "cid": false, ++ "hv-relaxed": false, ++ "hv-crash": false, ++ "ds": false, ++ "fxsr": true, ++ "xsaveopt": true, ++ "xtpr": false, ++ "hv-evmcs": false, ++ "avx512vl": false, ++ "avx512-vpopcntdq": false, ++ "phe": false, ++ "extapic": false, ++ "3dnowprefetch": false, ++ "avx512vbmi2": false, ++ "cr8legacy": true, ++ "stibp": false, ++ "cpuid-0xb": true, ++ "xcrypt-en": false, ++ "kvm_pv_eoi": false, ++ "apic-id": 4294967295, ++ "rsba": false, ++ "pn": false, ++ "dca": false, ++ "vendor": "AuthenticAMD", ++ "hv-ipi": false, ++ "pku": true, ++ "smx": false, ++ "cmp_legacy": false, ++ "cmp-legacy": false, ++ "node-id": -1, ++ "avx512-4fmaps": false, ++ "vmcb_clean": false, ++ "vmcb-clean": false, ++ "3dnowext": true, ++ "amd-no-ssb": false, ++ "hle": false, ++ "npt": true, ++ "rdctl-no": false, ++ "memory": "/machine/unattached/system[0]", ++ "clwb": true, ++ "lbrv": false, ++ "adx": true, ++ "ss": true, ++ "pni": true, ++ "svm_lock": false, ++ "svm-lock": false, ++ "pfthreshold": false, ++ "smep": true, ++ "smap": true, ++ "x2apic": false, ++ "avx512vbmi": false, ++ "avx512vnni": false, ++ "hv-stimer": false, ++ "x-hv-synic-kvm-only": false, ++ "i64": true, ++ "flushbyasid": false, ++ "f16c": false, ++ "ace2-en": false, ++ "pat": true, ++ "pae": true, ++ "sse": true, ++ "phe-en": false, ++ "kvm_nopiodelay": false, ++ "kvm-nopiodelay": false, ++ "tm": false, ++ "kvmclock-stable-bit": false, ++ "hypervisor": true, ++ "socket-id": -1, ++ "mds-no": false, ++ "pcommit": true, ++ "syscall": true, ++ "level": 13, ++ "avx512dq": false, ++ "x-migrate-smi-count": true, ++ "svm": true, ++ "full-cpuid-auto-level": true, ++ "hv-reset": false, ++ "invtsc": false, ++ "sse3": true, ++ "sse2": true, ++ "ssbd": false, ++ "est": false, ++ "avx512ifma": false, ++ "tm2": false, ++ "kvm-pv-ipi": false, ++ "kvm-pv-eoi": false, ++ "cx8": true, ++ "cldemote": false, ++ "hv-reenlightenment": false, ++ "kvm_mmu": false, ++ "kvm-mmu": false, ++ "sse4_2": true, ++ "sse4.2": true, ++ "sse4-2": true, ++ "pge": true, ++ "fill-mtrr-mask": true, ++ "avx512bitalg": false, ++ "nodeid_msr": false, ++ "pdcm": false, ++ "movbe": true, ++ "model": 6, ++ "nrip_save": false, ++ "nrip-save": false, ++ "kvm_pv_unhalt": false, ++ "ssse3": true, ++ "sse4a": true, ++ "invpcid": false, ++ "pdpe1gb": true, ++ "tsc-deadline": false, ++ "skip-l1dfl-vmentry": false, ++ "fma": false, ++ "cx16": true, ++ "de": true, ++ "enforce": false, ++ "stepping": 3, ++ "xsave": true, ++ "clflush": true, ++ "skinit": false, ++ "tsc": true, ++ "tce": false, ++ "fpu": true, ++ "ibs": false, ++ "ds_cpl": false, ++ "ds-cpl": false, ++ "host-phys-bits": false, ++ "fma4": false, ++ "la57": true, ++ "osvw": false, ++ "check": true, ++ "hv-spinlocks": -1, ++ "pmm": false, ++ "pmu": false, ++ "apic": true, ++ "spec-ctrl": false, ++ "min-xlevel2": 0, ++ "tsc-adjust": false, ++ "tsc_adjust": false, ++ "kvm-steal-time": false, ++ "kvm_steal_time": false, ++ "kvmclock": false, ++ "l3-cache": true, ++ "lwp": false, ++ "amd-ssbd": false, ++ "ibpb": false, ++ "xop": false, ++ "avx": false, ++ "movdiri": false, ++ "ace2": false, ++ "avx512bw": false, ++ "acpi": true, ++ "hv-vapic": false, ++ "fsgsbase": true, ++ "ht": false, ++ "nx": true, ++ "pclmulqdq": true, ++ "mmxext": true, ++ "vaes": false, ++ "popcnt": true, ++ "xsaves": false, ++ "movdir64b": false, ++ "tcg-cpuid": true, ++ "lm": true, ++ "umip": false, ++ "pse": true, ++ "avx2": false, ++ "sep": true, ++ "pclmuldq": true, ++ "virt-ssbd": false, ++ "x-hv-max-vps": -1, ++ "nodeid-msr": false, ++ "md-clear": false, ++ "kvm": true, ++ "misalignsse": false, ++ "min-xlevel": 2147483658, ++ "kvm-pv-unhalt": false, ++ "bmi2": true, ++ "bmi1": true, ++ "realized": false, ++ "tsc_scale": false, ++ "tsc-scale": false, ++ "topoext": false, ++ "hv-vpindex": false, ++ "xlevel2": 0, ++ "clflushopt": true, ++ "kvm-no-smi-migration": false, ++ "monitor": true, ++ "avx512er": false, ++ "pmm-en": false, ++ "pcid": false, ++ "arch-capabilities": false, ++ "3dnow": true, ++ "erms": true, ++ "lahf-lm": true, ++ "lahf_lm": true, ++ "vpclmulqdq": false, ++ "fxsr-opt": false, ++ "hv-synic": false, ++ "xstore": false, ++ "fxsr_opt": false, ++ "kvm-hint-dedicated": false, ++ "rtm": false, ++ "lmce": false, ++ "hv-time": false, ++ "perfctr-nb": false, ++ "perfctr_nb": false, ++ "ffxsr": false, ++ "hv-tlbflush": false, ++ "rdrand": true, ++ "rdseed": false, ++ "avx512-4vnniw": false, ++ "vmx": false, ++ "vme": false, ++ "dtes64": false, ++ "mtrr": true, ++ "rdtscp": true, ++ "pse36": true, ++ "kvm-pv-tlb-flush": false, ++ "tbm": false, ++ "wdt": false, ++ "pause_filter": false, ++ "sha-ni": false, ++ "model-id": "QEMU TCG CPU version 2.5+", ++ "abm": true, ++ "avx512pf": false, ++ "xstore-en": false ++ } ++ } ++ }, ++ "id": "libvirt-4" ++} ++ ++{ ++ "execute": "query-cpu-model-expansion", ++ "arguments": { ++ "type": "static", ++ "model": { ++ "name": "max", ++ "props": { ++ "migratable": false ++ } ++ } ++ }, ++ "id": "libvirt-5" ++} ++ ++{ ++ "return": { ++ "model": { ++ "name": "base", ++ "props": { ++ "cmov": true, ++ "ia64": false, ++ "ssb-no": false, ++ "aes": true, ++ "mmx": true, ++ "rdpid": false, ++ "arat": true, ++ "gfni": false, ++ "ibrs-all": false, ++ "pause-filter": false, ++ "xsavec": false, ++ "intel-pt": false, ++ "kvm-asyncpf": false, ++ "perfctr-core": false, ++ "mpx": true, ++ "pbe": false, ++ "avx512cd": false, ++ "decodeassists": false, ++ "sse4.1": true, ++ "family": 6, ++ "wbnoinvd": false, ++ "avx512f": false, ++ "msr": true, ++ "mce": true, ++ "mca": true, ++ "xcrypt": false, ++ "min-level": 13, ++ "xgetbv1": true, ++ "cid": false, ++ "ds": false, ++ "fxsr": true, ++ "xsaveopt": true, ++ "xtpr": false, ++ "avx512vl": false, ++ "avx512-vpopcntdq": false, ++ "phe": false, ++ "extapic": false, ++ "3dnowprefetch": false, ++ "avx512vbmi2": false, ++ "cr8legacy": true, ++ "stibp": false, ++ "xcrypt-en": false, ++ "pn": false, ++ "rsba": false, ++ "dca": false, ++ "vendor": "AuthenticAMD", ++ "pku": true, ++ "smx": false, ++ "cmp-legacy": false, ++ "avx512-4fmaps": false, ++ "vmcb-clean": false, ++ "hle": false, ++ "3dnowext": true, ++ "amd-no-ssb": false, ++ "npt": true, ++ "rdctl-no": false, ++ "clwb": true, ++ "lbrv": false, ++ "adx": true, ++ "ss": true, ++ "pni": true, ++ "svm-lock": false, ++ "smep": true, ++ "smap": true, ++ "pfthreshold": false, ++ "x2apic": false, ++ "avx512vbmi": false, ++ "avx512vnni": false, ++ "flushbyasid": false, ++ "f16c": false, ++ "ace2-en": false, ++ "pae": true, ++ "pat": true, ++ "sse": true, ++ "phe-en": false, ++ "kvm-nopiodelay": false, ++ "tm": false, ++ "kvmclock-stable-bit": false, ++ "hypervisor": true, ++ "mds-no": false, ++ "pcommit": true, ++ "syscall": true, ++ "avx512dq": false, ++ "svm": true, ++ "invtsc": false, ++ "sse2": true, ++ "ssbd": false, ++ "est": false, ++ "avx512ifma": false, ++ "tm2": false, ++ "kvm-pv-eoi": false, ++ "kvm-pv-ipi": false, ++ "cx8": true, ++ "cldemote": false, ++ "kvm-mmu": false, ++ "sse4.2": true, ++ "pge": true, ++ "avx512bitalg": false, ++ "pdcm": false, ++ "model": 6, ++ "movbe": true, ++ "nrip-save": false, ++ "ssse3": true, ++ "sse4a": true, ++ "invpcid": false, ++ "pdpe1gb": true, ++ "tsc-deadline": false, ++ "skip-l1dfl-vmentry": false, ++ "fma": false, ++ "cx16": true, ++ "de": true, ++ "stepping": 3, ++ "xsave": true, ++ "clflush": true, ++ "skinit": false, ++ "tsc": true, ++ "tce": false, ++ "fpu": true, ++ "ds-cpl": false, ++ "ibs": false, ++ "fma4": false, ++ "la57": true, ++ "osvw": false, ++ "apic": true, ++ "pmm": false, ++ "spec-ctrl": false, ++ "tsc-adjust": false, ++ "kvm-steal-time": false, ++ "kvmclock": false, ++ "lwp": false, ++ "amd-ssbd": false, ++ "xop": false, ++ "ibpb": false, ++ "avx": false, ++ "movdiri": false, ++ "acpi": true, ++ "avx512bw": false, ++ "ace2": false, ++ "fsgsbase": true, ++ "ht": false, ++ "nx": true, ++ "pclmulqdq": true, ++ "mmxext": true, ++ "popcnt": true, ++ "vaes": false, ++ "movdir64b": false, ++ "xsaves": false, ++ "lm": true, ++ "umip": false, ++ "pse": true, ++ "avx2": false, ++ "sep": true, ++ "virt-ssbd": false, ++ "nodeid-msr": false, ++ "md-clear": false, ++ "misalignsse": false, ++ "min-xlevel": 2147483658, ++ "bmi1": true, ++ "bmi2": true, ++ "kvm-pv-unhalt": false, ++ "tsc-scale": false, ++ "topoext": false, ++ "clflushopt": true, ++ "monitor": true, ++ "avx512er": false, ++ "pmm-en": false, ++ "pcid": false, ++ "arch-capabilities": false, ++ "3dnow": true, ++ "erms": true, ++ "lahf-lm": true, ++ "vpclmulqdq": false, ++ "fxsr-opt": false, ++ "xstore": false, ++ "rtm": false, ++ "kvm-hint-dedicated": false, ++ "lmce": false, ++ "perfctr-nb": false, ++ "rdrand": true, ++ "rdseed": false, ++ "avx512-4vnniw": false, ++ "vme": false, ++ "vmx": false, ++ "dtes64": false, ++ "mtrr": true, ++ "rdtscp": true, ++ "pse36": true, ++ "kvm-pv-tlb-flush": false, ++ "tbm": false, ++ "wdt": false, ++ "model-id": "QEMU TCG CPU version 2.5+", ++ "sha-ni": false, ++ "abm": true, ++ "avx512pf": false, ++ "xstore-en": false ++ } ++ } ++ }, ++ "id": "libvirt-5" ++} ++ ++{ ++ "execute": "query-cpu-model-expansion", ++ "arguments": { ++ "type": "full", ++ "model": { ++ "name": "base", ++ "props": { ++ "cmov": true, ++ "ia64": false, ++ "ssb-no": false, ++ "aes": true, ++ "mmx": true, ++ "rdpid": false, ++ "arat": true, ++ "gfni": false, ++ "ibrs-all": false, ++ "pause-filter": false, ++ "xsavec": false, ++ "intel-pt": false, ++ "kvm-asyncpf": false, ++ "perfctr-core": false, ++ "mpx": true, ++ "pbe": false, ++ "avx512cd": false, ++ "decodeassists": false, ++ "sse4.1": true, ++ "family": 6, ++ "wbnoinvd": false, ++ "avx512f": false, ++ "msr": true, ++ "mce": true, ++ "mca": true, ++ "xcrypt": false, ++ "min-level": 13, ++ "xgetbv1": true, ++ "cid": false, ++ "ds": false, ++ "fxsr": true, ++ "xsaveopt": true, ++ "xtpr": false, ++ "avx512vl": false, ++ "avx512-vpopcntdq": false, ++ "phe": false, ++ "extapic": false, ++ "3dnowprefetch": false, ++ "avx512vbmi2": false, ++ "cr8legacy": true, ++ "stibp": false, ++ "xcrypt-en": false, ++ "pn": false, ++ "rsba": false, ++ "dca": false, ++ "vendor": "AuthenticAMD", ++ "pku": true, ++ "smx": false, ++ "cmp-legacy": false, ++ "avx512-4fmaps": false, ++ "vmcb-clean": false, ++ "hle": false, ++ "3dnowext": true, ++ "amd-no-ssb": false, ++ "npt": true, ++ "rdctl-no": false, ++ "clwb": true, ++ "lbrv": false, ++ "adx": true, ++ "ss": true, ++ "pni": true, ++ "svm-lock": false, ++ "smep": true, ++ "smap": true, ++ "pfthreshold": false, ++ "x2apic": false, ++ "avx512vbmi": false, ++ "avx512vnni": false, ++ "flushbyasid": false, ++ "f16c": false, ++ "ace2-en": false, ++ "pae": true, ++ "pat": true, ++ "sse": true, ++ "phe-en": false, ++ "kvm-nopiodelay": false, ++ "tm": false, ++ "kvmclock-stable-bit": false, ++ "hypervisor": true, ++ "mds-no": false, ++ "pcommit": true, ++ "syscall": true, ++ "avx512dq": false, ++ "svm": true, ++ "invtsc": false, ++ "sse2": true, ++ "ssbd": false, ++ "est": false, ++ "avx512ifma": false, ++ "tm2": false, ++ "kvm-pv-eoi": false, ++ "kvm-pv-ipi": false, ++ "cx8": true, ++ "cldemote": false, ++ "kvm-mmu": false, ++ "sse4.2": true, ++ "pge": true, ++ "avx512bitalg": false, ++ "pdcm": false, ++ "model": 6, ++ "movbe": true, ++ "nrip-save": false, ++ "ssse3": true, ++ "sse4a": true, ++ "invpcid": false, ++ "pdpe1gb": true, ++ "tsc-deadline": false, ++ "skip-l1dfl-vmentry": false, ++ "fma": false, ++ "cx16": true, ++ "de": true, ++ "stepping": 3, ++ "xsave": true, ++ "clflush": true, ++ "skinit": false, ++ "tsc": true, ++ "tce": false, ++ "fpu": true, ++ "ds-cpl": false, ++ "ibs": false, ++ "fma4": false, ++ "la57": true, ++ "osvw": false, ++ "apic": true, ++ "pmm": false, ++ "spec-ctrl": false, ++ "tsc-adjust": false, ++ "kvm-steal-time": false, ++ "kvmclock": false, ++ "lwp": false, ++ "amd-ssbd": false, ++ "xop": false, ++ "ibpb": false, ++ "avx": false, ++ "movdiri": false, ++ "acpi": true, ++ "avx512bw": false, ++ "ace2": false, ++ "fsgsbase": true, ++ "ht": false, ++ "nx": true, ++ "pclmulqdq": true, ++ "mmxext": true, ++ "popcnt": true, ++ "vaes": false, ++ "movdir64b": false, ++ "xsaves": false, ++ "lm": true, ++ "umip": false, ++ "pse": true, ++ "avx2": false, ++ "sep": true, ++ "virt-ssbd": false, ++ "nodeid-msr": false, ++ "md-clear": false, ++ "misalignsse": false, ++ "min-xlevel": 2147483658, ++ "bmi1": true, ++ "bmi2": true, ++ "kvm-pv-unhalt": false, ++ "tsc-scale": false, ++ "topoext": false, ++ "clflushopt": true, ++ "monitor": true, ++ "avx512er": false, ++ "pmm-en": false, ++ "pcid": false, ++ "arch-capabilities": false, ++ "3dnow": true, ++ "erms": true, ++ "lahf-lm": true, ++ "vpclmulqdq": false, ++ "fxsr-opt": false, ++ "xstore": false, ++ "rtm": false, ++ "kvm-hint-dedicated": false, ++ "lmce": false, ++ "perfctr-nb": false, ++ "rdrand": true, ++ "rdseed": false, ++ "avx512-4vnniw": false, ++ "vme": false, ++ "vmx": false, ++ "dtes64": false, ++ "mtrr": true, ++ "rdtscp": true, ++ "pse36": true, ++ "kvm-pv-tlb-flush": false, ++ "tbm": false, ++ "wdt": false, ++ "model-id": "QEMU TCG CPU version 2.5+", ++ "sha-ni": false, ++ "abm": true, ++ "avx512pf": false, ++ "xstore-en": false ++ } ++ } ++ }, ++ "id": "libvirt-6" ++} ++ ++{ ++ "return": { ++ "model": { ++ "name": "base", ++ "props": { ++ "phys-bits": 0, ++ "core-id": -1, ++ "xlevel": 2147483658, ++ "cmov": true, ++ "ia64": false, ++ "ssb-no": false, ++ "aes": true, ++ "mmx": true, ++ "rdpid": false, ++ "arat": true, ++ "gfni": false, ++ "ibrs-all": false, ++ "pause-filter": false, ++ "xsavec": false, ++ "intel-pt": false, ++ "hv-frequencies": false, ++ "tsc-frequency": 0, ++ "xd": true, ++ "x-intel-pt-auto-level": true, ++ "hv-vendor-id": "", ++ "kvm-asyncpf": false, ++ "kvm_asyncpf": false, ++ "perfctr_core": false, ++ "perfctr-core": false, ++ "mpx": true, ++ "pbe": false, ++ "decodeassists": false, ++ "avx512cd": false, ++ "sse4_1": true, ++ "sse4.1": true, ++ "sse4-1": true, ++ "family": 6, ++ "legacy-cache": true, ++ "host-phys-bits-limit": 0, ++ "vmware-cpuid-freq": true, ++ "wbnoinvd": false, ++ "avx512f": false, ++ "msr": true, ++ "mce": true, ++ "mca": true, ++ "hv-runtime": false, ++ "xcrypt": false, ++ "thread-id": -1, ++ "min-level": 13, ++ "xgetbv1": true, ++ "cid": false, ++ "hv-relaxed": false, ++ "hv-crash": false, ++ "ds": false, ++ "fxsr": true, ++ "xsaveopt": true, ++ "xtpr": false, ++ "hv-evmcs": false, ++ "avx512vl": false, ++ "avx512-vpopcntdq": false, ++ "phe": false, ++ "extapic": false, ++ "3dnowprefetch": false, ++ "avx512vbmi2": false, ++ "cr8legacy": true, ++ "stibp": false, ++ "cpuid-0xb": true, ++ "xcrypt-en": false, ++ "kvm_pv_eoi": false, ++ "apic-id": 4294967295, ++ "rsba": false, ++ "pn": false, ++ "dca": false, ++ "vendor": "AuthenticAMD", ++ "hv-ipi": false, ++ "pku": true, ++ "smx": false, ++ "cmp_legacy": false, ++ "cmp-legacy": false, ++ "node-id": -1, ++ "avx512-4fmaps": false, ++ "vmcb_clean": false, ++ "vmcb-clean": false, ++ "3dnowext": true, ++ "amd-no-ssb": false, ++ "hle": false, ++ "npt": true, ++ "rdctl-no": false, ++ "memory": "/machine/unattached/system[0]", ++ "clwb": true, ++ "lbrv": false, ++ "adx": true, ++ "ss": true, ++ "pni": true, ++ "svm_lock": false, ++ "svm-lock": false, ++ "pfthreshold": false, ++ "smep": true, ++ "smap": true, ++ "x2apic": false, ++ "avx512vbmi": false, ++ "avx512vnni": false, ++ "hv-stimer": false, ++ "x-hv-synic-kvm-only": false, ++ "i64": true, ++ "flushbyasid": false, ++ "f16c": false, ++ "ace2-en": false, ++ "pat": true, ++ "pae": true, ++ "sse": true, ++ "phe-en": false, ++ "kvm_nopiodelay": false, ++ "kvm-nopiodelay": false, ++ "tm": false, ++ "kvmclock-stable-bit": false, ++ "hypervisor": true, ++ "socket-id": -1, ++ "mds-no": false, ++ "pcommit": true, ++ "syscall": true, ++ "level": 13, ++ "avx512dq": false, ++ "x-migrate-smi-count": true, ++ "svm": true, ++ "full-cpuid-auto-level": true, ++ "hv-reset": false, ++ "invtsc": false, ++ "sse3": true, ++ "sse2": true, ++ "ssbd": false, ++ "est": false, ++ "avx512ifma": false, ++ "tm2": false, ++ "kvm-pv-ipi": false, ++ "kvm-pv-eoi": false, ++ "cx8": true, ++ "cldemote": false, ++ "hv-reenlightenment": false, ++ "kvm_mmu": false, ++ "kvm-mmu": false, ++ "sse4_2": true, ++ "sse4.2": true, ++ "sse4-2": true, ++ "pge": true, ++ "fill-mtrr-mask": true, ++ "avx512bitalg": false, ++ "nodeid_msr": false, ++ "pdcm": false, ++ "movbe": true, ++ "model": 6, ++ "nrip_save": false, ++ "nrip-save": false, ++ "kvm_pv_unhalt": false, ++ "ssse3": true, ++ "sse4a": true, ++ "invpcid": false, ++ "pdpe1gb": true, ++ "tsc-deadline": false, ++ "skip-l1dfl-vmentry": false, ++ "fma": false, ++ "cx16": true, ++ "de": true, ++ "enforce": false, ++ "stepping": 3, ++ "xsave": true, ++ "clflush": true, ++ "skinit": false, ++ "tsc": true, ++ "tce": false, ++ "fpu": true, ++ "ibs": false, ++ "ds_cpl": false, ++ "ds-cpl": false, ++ "host-phys-bits": false, ++ "fma4": false, ++ "la57": true, ++ "osvw": false, ++ "check": true, ++ "hv-spinlocks": -1, ++ "pmm": false, ++ "pmu": false, ++ "apic": true, ++ "spec-ctrl": false, ++ "min-xlevel2": 0, ++ "tsc-adjust": false, ++ "tsc_adjust": false, ++ "kvm-steal-time": false, ++ "kvm_steal_time": false, ++ "kvmclock": false, ++ "l3-cache": true, ++ "lwp": false, ++ "amd-ssbd": false, ++ "ibpb": false, ++ "xop": false, ++ "avx": false, ++ "movdiri": false, ++ "ace2": false, ++ "avx512bw": false, ++ "acpi": true, ++ "hv-vapic": false, ++ "fsgsbase": true, ++ "ht": false, ++ "nx": true, ++ "pclmulqdq": true, ++ "mmxext": true, ++ "vaes": false, ++ "popcnt": true, ++ "xsaves": false, ++ "movdir64b": false, ++ "tcg-cpuid": true, ++ "lm": true, ++ "umip": false, ++ "pse": true, ++ "avx2": false, ++ "sep": true, ++ "pclmuldq": true, ++ "virt-ssbd": false, ++ "x-hv-max-vps": -1, ++ "nodeid-msr": false, ++ "md-clear": false, ++ "kvm": true, ++ "misalignsse": false, ++ "min-xlevel": 2147483658, ++ "kvm-pv-unhalt": false, ++ "bmi2": true, ++ "bmi1": true, ++ "realized": false, ++ "tsc_scale": false, ++ "tsc-scale": false, ++ "topoext": false, ++ "hv-vpindex": false, ++ "xlevel2": 0, ++ "clflushopt": true, ++ "kvm-no-smi-migration": false, ++ "monitor": true, ++ "avx512er": false, ++ "pmm-en": false, ++ "pcid": false, ++ "arch-capabilities": false, ++ "3dnow": true, ++ "erms": true, ++ "lahf-lm": true, ++ "lahf_lm": true, ++ "vpclmulqdq": false, ++ "fxsr-opt": false, ++ "hv-synic": false, ++ "xstore": false, ++ "fxsr_opt": false, ++ "kvm-hint-dedicated": false, ++ "rtm": false, ++ "lmce": false, ++ "hv-time": false, ++ "perfctr-nb": false, ++ "perfctr_nb": false, ++ "ffxsr": false, ++ "hv-tlbflush": false, ++ "rdrand": true, ++ "rdseed": false, ++ "avx512-4vnniw": false, ++ "vmx": false, ++ "vme": false, ++ "dtes64": false, ++ "mtrr": true, ++ "rdtscp": true, ++ "pse36": true, ++ "kvm-pv-tlb-flush": false, ++ "tbm": false, ++ "wdt": false, ++ "pause_filter": false, ++ "sha-ni": false, ++ "model-id": "QEMU TCG CPU version 2.5+", ++ "abm": true, ++ "avx512pf": false, ++ "xstore-en": false ++ } ++ } ++ }, ++ "id": "libvirt-6" ++} +diff --git a/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml +new file mode 100644 +index 0000000000..93c5da537a +--- /dev/null ++++ b/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml +@@ -0,0 +1,1424 @@ ++ ++ 0 ++ 0 ++ 0 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ 4000050 ++ 0 ++ 456805 ++ v4.0.0-1173-g9c70209b63 ++ x86_64 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/qemucapabilitiestest.c b/tests/qemucapabilitiestest.c +index ccc4e45817..775f78e16f 100644 +--- a/tests/qemucapabilitiestest.c ++++ b/tests/qemucapabilitiestest.c +@@ -178,6 +178,7 @@ mymain(void) + DO_TEST("x86_64", "caps_2.11.0"); + DO_TEST("x86_64", "caps_2.12.0"); + DO_TEST("x86_64", "caps_3.0.0"); ++ DO_TEST("x86_64", "caps_4.1.0"); + DO_TEST("aarch64", "caps_2.6.0"); + DO_TEST("aarch64", "caps_2.10.0"); + DO_TEST("aarch64", "caps_2.12.0"); +-- +2.22.0 + diff --git a/SOURCES/libvirt-tests-Add-domain-capabilities-case-for-QEMU-4.1.0.patch b/SOURCES/libvirt-tests-Add-domain-capabilities-case-for-QEMU-4.1.0.patch new file mode 100644 index 0000000..c38fdc0 --- /dev/null +++ b/SOURCES/libvirt-tests-Add-domain-capabilities-case-for-QEMU-4.1.0.patch @@ -0,0 +1,203 @@ +From d5a656f2fe0e7aea8f56a4b4c59dcc3d5e906411 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:49 +0200 +Subject: [PATCH] tests: Add domain capabilities case for QEMU 4.1.0 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 9ceee2f4bb5d6cefa24c3aedcb7addbe7907c60b) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Conflicts: + tests/domaincapstest.c + - several cases are missing + + tests/domaincapsschemadata/qemu_4.1.0.x86_64.xml + - some capabilities are not reported in domaincaps + +Signed-off-by: Jiri Denemark +Message-Id: <87edadf46f7d4d7ad161b2ab433632f9d0f66920.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + .../qemu_4.1.0.x86_64.xml | 148 ++++++++++++++++++ + tests/domaincapstest.c | 4 + + 2 files changed, 152 insertions(+) + create mode 100644 tests/domaincapsschemadata/qemu_4.1.0.x86_64.xml + +diff --git a/tests/domaincapsschemadata/qemu_4.1.0.x86_64.xml b/tests/domaincapsschemadata/qemu_4.1.0.x86_64.xml +new file mode 100644 +index 0000000000..47aed6a43a +--- /dev/null ++++ b/tests/domaincapsschemadata/qemu_4.1.0.x86_64.xml +@@ -0,0 +1,148 @@ ++ ++ /usr/bin/qemu-system-x86_64 ++ kvm ++ pc-i440fx-4.1 ++ x86_64 ++ ++ ++ ++ ++ /usr/share/AAVMF/AAVMF_CODE.fd ++ /usr/share/AAVMF/AAVMF32_CODE.fd ++ /usr/share/OVMF/OVMF_CODE.fd ++ ++ rom ++ pflash ++ ++ ++ yes ++ no ++ ++ ++ ++ ++ ++ ++ Skylake-Client ++ Intel ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ qemu64 ++ qemu32 ++ phenom ++ pentium3 ++ pentium2 ++ pentium ++ n270 ++ kvm64 ++ kvm32 ++ coreduo ++ core2duo ++ athlon ++ Westmere-IBRS ++ Westmere ++ Skylake-Server-IBRS ++ Skylake-Server ++ Skylake-Client-IBRS ++ Skylake-Client ++ SandyBridge-IBRS ++ SandyBridge ++ Penryn ++ Opteron_G5 ++ Opteron_G4 ++ Opteron_G3 ++ Opteron_G2 ++ Opteron_G1 ++ Nehalem-IBRS ++ Nehalem ++ IvyBridge-IBRS ++ IvyBridge ++ Icelake-Server ++ Icelake-Client ++ Haswell-noTSX-IBRS ++ Haswell-noTSX ++ Haswell-IBRS ++ Haswell ++ EPYC-IBPB ++ EPYC ++ Conroe ++ Cascadelake-Server ++ Broadwell-noTSX-IBRS ++ Broadwell-noTSX ++ Broadwell-IBRS ++ Broadwell ++ 486 ++ ++ ++ ++ ++ ++ disk ++ cdrom ++ floppy ++ lun ++ ++ ++ ide ++ fdc ++ scsi ++ virtio ++ usb ++ sata ++ ++ ++ ++ ++ sdl ++ vnc ++ spice ++ ++ ++ ++ ++ ++ subsystem ++ ++ ++ default ++ mandatory ++ requisite ++ optional ++ ++ ++ usb ++ pci ++ scsi ++ ++ ++ ++ default ++ kvm ++ vfio ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/domaincapstest.c b/tests/domaincapstest.c +index 06e77fd586..30e7eea3cb 100644 +--- a/tests/domaincapstest.c ++++ b/tests/domaincapstest.c +@@ -504,6 +504,10 @@ mymain(void) + "/usr/bin/qemu-system-s390x", NULL, + "s390x", VIR_DOMAIN_VIRT_KVM); + ++ DO_TEST_QEMU("4.1.0", "caps_4.1.0", ++ "/usr/bin/qemu-system-x86_64", NULL, ++ "x86_64", VIR_DOMAIN_VIRT_KVM); ++ + virObjectUnref(cfg); + + #endif /* WITH_QEMU */ +-- +2.22.0 + diff --git a/SOURCES/libvirt-tests-Augment-vcgrouptest-to-add-virCgroupGetMemoryStat.patch b/SOURCES/libvirt-tests-Augment-vcgrouptest-to-add-virCgroupGetMemoryStat.patch new file mode 100644 index 0000000..ea4446e --- /dev/null +++ b/SOURCES/libvirt-tests-Augment-vcgrouptest-to-add-virCgroupGetMemoryStat.patch @@ -0,0 +1,112 @@ +From 356b50b2014aafc7c1555e11cf93650dad39f03a Mon Sep 17 00:00:00 2001 +Message-Id: <356b50b2014aafc7c1555e11cf93650dad39f03a@dist-git> +From: John Ferlan +Date: Mon, 1 Jul 2019 17:08:08 +0200 +Subject: [PATCH] tests: Augment vcgrouptest to add virCgroupGetMemoryStat +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add a test to fetch the GetMemoryStat output. This only gets +data for v1 only right now since the v2 data from commit 61ff6021 +is rather useless returning all 0's. The v1 data was originally +added in commit d1452470. + +Signed-off-by: John Ferlan +Reviewed-by: Pavel Hrdina +(cherry picked from commit 99b8ef7a98d6ad4a01549204195f5e17ee1984ee) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <3c217939ce31a379e149865bc0f3342fc334ba42.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + tests/vircgrouptest.c | 64 +++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 64 insertions(+) + +diff --git a/tests/vircgrouptest.c b/tests/vircgrouptest.c +index 118b1bc246..e9cf792bdd 100644 +--- a/tests/vircgrouptest.c ++++ b/tests/vircgrouptest.c +@@ -803,6 +803,67 @@ static int testCgroupGetMemoryUsage(const void *args ATTRIBUTE_UNUSED) + return ret; + } + ++ ++static int ++testCgroupGetMemoryStat(const void *args ATTRIBUTE_UNUSED) ++{ ++ virCgroupPtr cgroup = NULL; ++ int rv; ++ int ret = -1; ++ size_t i; ++ ++ const unsigned long long expected_values[] = { ++ 1336619008ULL, ++ 67100672ULL, ++ 145887232ULL, ++ 661872640ULL, ++ 627400704UL, ++ 3690496ULL ++ }; ++ const char* names[] = { ++ "cache", ++ "active_anon", ++ "inactive_anon", ++ "active_file", ++ "inactive_file", ++ "unevictable" ++ }; ++ unsigned long long values[ARRAY_CARDINALITY(expected_values)]; ++ ++ if ((rv = virCgroupNewPartition("/virtualmachines", true, ++ (1 << VIR_CGROUP_CONTROLLER_MEMORY), ++ &cgroup)) < 0) { ++ fprintf(stderr, "Could not create /virtualmachines cgroup: %d\n", -rv); ++ goto cleanup; ++ } ++ ++ if ((rv = virCgroupGetMemoryStat(cgroup, &values[0], ++ &values[1], &values[2], ++ &values[3], &values[4], ++ &values[5])) < 0) { ++ fprintf(stderr, "Could not retrieve GetMemoryStat for /virtualmachines cgroup: %d\n", -rv); ++ goto cleanup; ++ } ++ ++ for (i = 0; i < ARRAY_CARDINALITY(expected_values); i++) { ++ /* NB: virCgroupGetMemoryStat returns a KiB scaled value */ ++ if ((expected_values[i] >> 10) != values[i]) { ++ fprintf(stderr, ++ "Wrong value (%llu) for %s from virCgroupGetMemoryStat " ++ "(expected %llu)\n", ++ values[i], names[i], (expected_values[i] >> 10)); ++ goto cleanup; ++ } ++ } ++ ++ ret = 0; ++ ++ cleanup: ++ virCgroupFree(&cgroup); ++ return ret; ++} ++ ++ + static int testCgroupGetBlkioIoServiced(const void *args ATTRIBUTE_UNUSED) + { + virCgroupPtr cgroup = NULL; +@@ -1036,6 +1097,9 @@ mymain(void) + if (virTestRun("virCgroupGetMemoryUsage works", testCgroupGetMemoryUsage, NULL) < 0) + ret = -1; + ++ if (virTestRun("virCgroupGetMemoryStat works", testCgroupGetMemoryStat, NULL) < 0) ++ ret = -1; ++ + if (virTestRun("virCgroupGetPercpuStats works", testCgroupGetPercpuStats, NULL) < 0) + ret = -1; + cleanupFakeFS(fakerootdir); +-- +2.22.0 + diff --git a/SOURCES/libvirt-tests-Resolve-possible-overrun.patch b/SOURCES/libvirt-tests-Resolve-possible-overrun.patch new file mode 100644 index 0000000..097fd9c --- /dev/null +++ b/SOURCES/libvirt-tests-Resolve-possible-overrun.patch @@ -0,0 +1,84 @@ +From c8e10c7f4644646194bbcb1514bbf110ec7374ad Mon Sep 17 00:00:00 2001 +Message-Id: +From: John Ferlan +Date: Mon, 1 Jul 2019 17:06:11 +0200 +Subject: [PATCH] tests: Resolve possible overrun +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Coverity noted that each of the fmemopen called used the strlen value +in order to allocate space, but that neglected space for terminating +null string. So just add 1 to the strlen. + +Signed-off-by: John Ferlan +Reviewed-by: Erik Skultety +(cherry picked from commit 7eb56dcd9ef4c21f8f4bc5e639dc4dd01e6d572a) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + tests/vircgroupmock.c | 21 ++++++++++++--------- + 1 file changed, 12 insertions(+), 9 deletions(-) + +diff --git a/tests/vircgroupmock.c b/tests/vircgroupmock.c +index 51861be38e..bae8304f6c 100644 +--- a/tests/vircgroupmock.c ++++ b/tests/vircgroupmock.c +@@ -468,12 +468,13 @@ FILE *fopen(const char *path, const char *mode) + if (STREQ(mode, "r")) { + if (allinone) + return fmemopen((void *)procmountsallinone, +- strlen(procmountsallinone), mode); ++ strlen(procmountsallinone) + 1, mode); + else if (logind) + return fmemopen((void *)procmountslogind, +- strlen(procmountslogind), mode); ++ strlen(procmountslogind) + 1, mode); + else +- return fmemopen((void *)procmounts, strlen(procmounts), mode); ++ return fmemopen((void *)procmounts, ++ strlen(procmounts) + 1, mode); + } else { + errno = EACCES; + return NULL; +@@ -483,12 +484,13 @@ FILE *fopen(const char *path, const char *mode) + if (STREQ(mode, "r")) { + if (allinone) + return fmemopen((void *)proccgroupsallinone, +- strlen(proccgroupsallinone), mode); ++ strlen(proccgroupsallinone) + 1, mode); + else if (logind) + return fmemopen((void *)proccgroupslogind, +- strlen(proccgroupslogind), mode); ++ strlen(proccgroupslogind) + 1, mode); + else +- return fmemopen((void *)proccgroups, strlen(proccgroups), mode); ++ return fmemopen((void *)proccgroups, ++ strlen(proccgroups) + 1, mode); + } else { + errno = EACCES; + return NULL; +@@ -498,12 +500,13 @@ FILE *fopen(const char *path, const char *mode) + if (STREQ(mode, "r")) { + if (allinone) + return fmemopen((void *)procselfcgroupsallinone, +- strlen(procselfcgroupsallinone), mode); ++ strlen(procselfcgroupsallinone) + 1, mode); + else if (logind) + return fmemopen((void *)procselfcgroupslogind, +- strlen(procselfcgroupslogind), mode); ++ strlen(procselfcgroupslogind) + 1, mode); + else +- return fmemopen((void *)procselfcgroups, strlen(procselfcgroups), mode); ++ return fmemopen((void *)procselfcgroups, ++ strlen(procselfcgroups) + 1, mode); + } else { + errno = EACCES; + return NULL; +-- +2.22.0 + diff --git a/SOURCES/libvirt-tests-Use-correct-function-name-in-error-path.patch b/SOURCES/libvirt-tests-Use-correct-function-name-in-error-path.patch new file mode 100644 index 0000000..73e3d8a --- /dev/null +++ b/SOURCES/libvirt-tests-Use-correct-function-name-in-error-path.patch @@ -0,0 +1,40 @@ +From ef6054cc51d7a847e1d34b74b28b76fd1c1bb6da Mon Sep 17 00:00:00 2001 +Message-Id: +From: John Ferlan +Date: Mon, 1 Jul 2019 17:08:06 +0200 +Subject: [PATCH] tests: Use correct function name in error path +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Commit id 5eb61e6846 neglected to change the name in the wrong value +output to virCgroupGetPercpuStats from virCgroupGetMemoryUsage. + +Signed-off-by: John Ferlan +(cherry picked from commit 4608af30f9f9a4089b530d85d9b11c2f88424a09) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + tests/vircgrouptest.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tests/vircgrouptest.c b/tests/vircgrouptest.c +index 7fde50b463..118b1bc246 100644 +--- a/tests/vircgrouptest.c ++++ b/tests/vircgrouptest.c +@@ -757,7 +757,7 @@ static int testCgroupGetPercpuStats(const void *args ATTRIBUTE_UNUSED) + + if (params[i].value.ul != expected[i]) { + fprintf(stderr, +- "Wrong value from virCgroupGetMemoryUsage at %zu (expected %llu)\n", ++ "Wrong value from virCgroupGetPercpuStats at %zu (expected %llu)\n", + i, params[i].value.ul); + goto cleanup; + } +-- +2.22.0 + diff --git a/SOURCES/libvirt-tests-qemuxml2argv-add-CAPS_ARCH_LATEST-macro.patch b/SOURCES/libvirt-tests-qemuxml2argv-add-CAPS_ARCH_LATEST-macro.patch new file mode 100644 index 0000000..050e8f3 --- /dev/null +++ b/SOURCES/libvirt-tests-qemuxml2argv-add-CAPS_ARCH_LATEST-macro.patch @@ -0,0 +1,99 @@ +From d87b6566d14526883e9439ebd3f922fc7ed22abb Mon Sep 17 00:00:00 2001 +Message-Id: +From: Bjoern Walk +Date: Wed, 17 Apr 2019 14:46:00 +0200 +Subject: [PATCH] tests: qemuxml2argv: add CAPS_ARCH_LATEST macro +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Testing with the latest capabilities is possible with the x86_64 centric +implemented macro CAPS_LATEST. The new macro CAPS_ARCH_LATEST provides +the user the ability to specify the desired architecture when testing with +the latest capabilities. + +Signed-off-by: Bjoern Walk +Reviewed-by: Boris Fiuczynski +(cherry picked from commit bc4c83838d51f42b86d189280c9011494ef435f0) +Signed-off-by: Ján Tomko + +RHEL 8.1: https://bugzilla.redhat.com/show_bug.cgi?id=1698855 +Message-Id: + +Reviewed-by: Andrea Bolognani +--- + tests/qemuxml2argvtest.c | 31 +++++++++++++++++++++++-------- + 1 file changed, 23 insertions(+), 8 deletions(-) + +diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c +index 690a39054e..abb256c913 100644 +--- a/tests/qemuxml2argvtest.c ++++ b/tests/qemuxml2argvtest.c +@@ -623,10 +623,11 @@ testCompareXMLToArgv(const void *data) + static int + mymain(void) + { +- int ret = 0; ++ int ret = 0, i; + char *fakerootdir; + bool skipLegacyCPUs = false; +- char *capslatest_x86_64 = NULL; ++ const char *archs[] = { "x86_64", "s390x" }; ++ virHashTablePtr capslatest = NULL; + + if (VIR_STRDUP_QUIET(fakerootdir, FAKEROOTDIRTEMPLATE) < 0) { + fprintf(stderr, "Out of memory\n"); +@@ -695,12 +696,23 @@ mymain(void) + if (VIR_STRDUP_QUIET(driver.config->memoryBackingDir, "/var/lib/libvirt/qemu/ram") < 0) + return EXIT_FAILURE; + +- if (!(capslatest_x86_64 = testQemuGetLatestCapsForArch(abs_srcdir "/qemucapabilitiesdata", +- "x86_64", "xml"))) ++ capslatest = virHashCreate(4, virHashValueFree); ++ if (!capslatest) + return EXIT_FAILURE; + +- VIR_TEST_VERBOSE("\nlatest caps x86_64: %s\n", capslatest_x86_64); ++ VIR_TEST_VERBOSE("\n"); + ++ for (i = 0; i < ARRAY_CARDINALITY(archs); ++i) { ++ char *cap = testQemuGetLatestCapsForArch(abs_srcdir "/qemucapabilitiesdata", ++ archs[i], "xml"); ++ ++ if (!cap || virHashAddEntry(capslatest, archs[i], cap) < 0) ++ return EXIT_FAILURE; ++ ++ VIR_TEST_VERBOSE("latest caps for %s: %s\n", archs[i], cap); ++ } ++ ++ VIR_TEST_VERBOSE("\n"); + + /** + * The following set of macros allows testing of XML -> argv conversion with a +@@ -748,9 +760,12 @@ mymain(void) + # define DO_TEST_CAPS_VER(name, ver) \ + DO_TEST_CAPS_ARCH_VER(name, "x86_64", ver) + ++# define DO_TEST_CAPS_ARCH_LATEST(name, arch) \ ++ DO_TEST_CAPS_INTERNAL(name, arch "-latest", NULL, 0, 0, arch, \ ++ virHashLookup(capslatest, arch), true) ++ + # define DO_TEST_CAPS_LATEST(name) \ +- DO_TEST_CAPS_INTERNAL(name, "x86_64-latest", NULL, 0, 0, "x86_64", \ +- capslatest_x86_64, true) ++ DO_TEST_CAPS_ARCH_LATEST(name, "x86_64") + + /** + * The following test macros should be used only in cases when the tests require +@@ -2966,7 +2981,7 @@ mymain(void) + VIR_FREE(driver.config->nbdTLSx509certdir); + qemuTestDriverFree(&driver); + VIR_FREE(fakerootdir); +- VIR_FREE(capslatest_x86_64); ++ virHashFree(capslatest); + + return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; + } +-- +2.21.0 + diff --git a/SOURCES/libvirt-util-Avoid-possible-error-in-virCommandMassClose.patch b/SOURCES/libvirt-util-Avoid-possible-error-in-virCommandMassClose.patch new file mode 100644 index 0000000..9806fc9 --- /dev/null +++ b/SOURCES/libvirt-util-Avoid-possible-error-in-virCommandMassClose.patch @@ -0,0 +1,47 @@ +From abf1be5d4639ca4b58d56633129a7cf1389b97f3 Mon Sep 17 00:00:00 2001 +Message-Id: +From: John Ferlan +Date: Tue, 30 Jul 2019 16:04:52 +0200 +Subject: [PATCH] util: Avoid possible error in virCommandMassClose +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Avoid the chance that sysconf(_SC_OPEN_MAX) returns -1 and thus +would cause virBitmapNew would attempt to allocate a very large +bitmap. + +Found by Coverity + +Signed-off-by: John Ferlan +ACKed-by: Peter Krempa +(cherry picked from commit 6ae4f4a4ceb123417b732e869d53099983ae8d3f) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1721434 + +Signed-off-by: Michal Privoznik +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircommand.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/util/vircommand.c b/src/util/vircommand.c +index dfc7e5428b..c53e3f47db 100644 +--- a/src/util/vircommand.c ++++ b/src/util/vircommand.c +@@ -560,6 +560,11 @@ virCommandMassClose(virCommandPtr cmd, + * Therefore we can safely allocate memory here (and transitively call + * opendir/readdir) without a deadlock. */ + ++ if (openmax < 0) { ++ virReportSystemError(errno, "%s", _("sysconf(_SC_OPEN_MAX) failed")); ++ return -1; ++ } ++ + if (!(fds = virBitmapNew(openmax))) + return -1; + +-- +2.22.0 + diff --git a/SOURCES/libvirt-util-Fix-virCgroupGetMemoryStat.patch b/SOURCES/libvirt-util-Fix-virCgroupGetMemoryStat.patch new file mode 100644 index 0000000..2e3e9f5 --- /dev/null +++ b/SOURCES/libvirt-util-Fix-virCgroupGetMemoryStat.patch @@ -0,0 +1,89 @@ +From bab2adc524f6a9a10a89a1055d8a15ed85e1df5a Mon Sep 17 00:00:00 2001 +Message-Id: +From: Peter Chubb +Date: Mon, 1 Jul 2019 17:08:07 +0200 +Subject: [PATCH] util: Fix virCgroupGetMemoryStat +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Commit 901d2b9c introduced virCgroupGetMemoryStat and replaced +the LXC virLXCCgroupGetMemStat logic in commit e634c7cd0. However, +in doing so the replacement wasn't exact as the LXC logic used +getline() to process the cgroup controller data, while the new +virCgroupGetMemoryStat used "memory.stat" manual buffer read/ +processing which neglected to forward through @line in order +to read each line in the output. + +To fix that, we should be sure to carry forward the @line value +for each line read updating it beyond that current @newLine value +once we've calculated the values that we want. + +Signed-off-by: Peter Chubb +Reviewed-by: John Ferlan +Reviewed-by: Pavel Hrdina +(cherry picked from commit b8176d6eaa943bc9825ecc99d86c0c301e688dd0) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv1.c | 7 ++++++- + src/util/vircgroupv2.c | 7 ++++++- + 2 files changed, 12 insertions(+), 2 deletions(-) + +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 97d108d3ac..3147084f21 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -1477,7 +1477,7 @@ virCgroupV1GetMemoryStat(virCgroupPtr group, + + line = stat; + +- while (line) { ++ while (*line) { + char *newLine = strchr(line, '\n'); + char *valueStr = strchr(line, ' '); + unsigned long long value; +@@ -1507,6 +1507,11 @@ virCgroupV1GetMemoryStat(virCgroupPtr group, + inactiveFileVal = value >> 10; + else if (STREQ(line, "unevictable")) + unevictableVal = value >> 10; ++ ++ if (newLine) ++ line = newLine + 1; ++ else ++ break; + } + + *cache = cacheVal; +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index d6362e2b05..bff2f78d7e 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -1069,7 +1069,7 @@ virCgroupV2GetMemoryStat(virCgroupPtr group, + + line = stat; + +- while (line) { ++ while (*line) { + char *newLine = strchr(line, '\n'); + char *valueStr = strchr(line, ' '); + unsigned long long value; +@@ -1103,6 +1103,11 @@ virCgroupV2GetMemoryStat(virCgroupPtr group, + inactiveFileVal = value >> 10; + else if (STREQ(line, "unevictable")) + unevictableVal = value >> 10; ++ ++ if (newLine) ++ line = newLine + 1; ++ else ++ break; + } + + *cache = cacheVal; +-- +2.22.0 + diff --git a/SOURCES/libvirt-util-Introduce-virBitmapUnion.patch b/SOURCES/libvirt-util-Introduce-virBitmapUnion.patch new file mode 100644 index 0000000..d2895be --- /dev/null +++ b/SOURCES/libvirt-util-Introduce-virBitmapUnion.patch @@ -0,0 +1,149 @@ +From 6ee2c599db989189e639c3de88d20045c62a1d2c Mon Sep 17 00:00:00 2001 +Message-Id: <6ee2c599db989189e639c3de88d20045c62a1d2c@dist-git> +From: Andrea Bolognani +Date: Tue, 11 Jun 2019 10:55:01 +0200 +Subject: [PATCH] util: Introduce virBitmapUnion() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Andrea Bolognani +Reviewed-by: Ján Tomko +(cherry picked from commit 1b2ac8010cc1fe871f538b3f48c5e48213c5c074) + +https://bugzilla.redhat.com/show_bug.cgi?id=1716908 + +Signed-off-by: Andrea Bolognani +Message-Id: <20190611085506.12564-2-abologna@redhat.com> +Reviewed-by: Ján Tomko +--- + src/libvirt_private.syms | 1 + + src/util/virbitmap.c | 27 +++++++++++++++++++++++++++ + src/util/virbitmap.h | 4 ++++ + tests/virbitmaptest.c | 38 ++++++++++++++++++++++++++++++++++++++ + 4 files changed, 70 insertions(+) + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index ee7625b0f3..05c96c29e2 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -1476,6 +1476,7 @@ virBitmapSubtract; + virBitmapToData; + virBitmapToDataBuf; + virBitmapToString; ++virBitmapUnion; + + + # util/virbuffer.h +diff --git a/src/util/virbitmap.c b/src/util/virbitmap.c +index ef18dad255..49e542a4e6 100644 +--- a/src/util/virbitmap.c ++++ b/src/util/virbitmap.c +@@ -1265,6 +1265,33 @@ virBitmapIntersect(virBitmapPtr a, + } + + ++/** ++ * virBitmapUnion: ++ * @a: bitmap, modified to contain result ++ * @b: other bitmap ++ * ++ * Performs union of two bitmaps: a = union(a, b) ++ * ++ * Returns 0 on success, <0 on failure. ++ */ ++int ++virBitmapUnion(virBitmapPtr a, ++ const virBitmap *b) ++{ ++ size_t i; ++ ++ if (a->nbits < b->nbits && ++ virBitmapExpand(a, b->nbits - 1) < 0) { ++ return -1; ++ } ++ ++ for (i = 0; i < b->map_len; i++) ++ a->map[i] |= b->map[i]; ++ ++ return 0; ++} ++ ++ + /** + * virBitmapSubtract: + * @a: minuend/result +diff --git a/src/util/virbitmap.h b/src/util/virbitmap.h +index 312e7e2933..5934508d11 100644 +--- a/src/util/virbitmap.h ++++ b/src/util/virbitmap.h +@@ -151,6 +151,10 @@ bool virBitmapOverlaps(virBitmapPtr b1, + void virBitmapIntersect(virBitmapPtr a, virBitmapPtr b) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + ++int virBitmapUnion(virBitmapPtr a, ++ const virBitmap *b) ++ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); ++ + void virBitmapSubtract(virBitmapPtr a, virBitmapPtr b) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + +diff --git a/tests/virbitmaptest.c b/tests/virbitmaptest.c +index 2fbafc0a76..cafe865dde 100644 +--- a/tests/virbitmaptest.c ++++ b/tests/virbitmaptest.c +@@ -740,6 +740,34 @@ test14(const void *opaque) + return ret; + } + ++/* virBitmapUnion() */ ++static int ++test15(const void *opaque) ++{ ++ const struct testBinaryOpData *data = opaque; ++ VIR_AUTOPTR(virBitmap) amap = NULL; ++ VIR_AUTOPTR(virBitmap) bmap = NULL; ++ VIR_AUTOPTR(virBitmap) resmap = NULL; ++ ++ if (!(amap = virBitmapParseUnlimited(data->a)) || ++ !(bmap = virBitmapParseUnlimited(data->b)) || ++ !(resmap = virBitmapParseUnlimited(data->res))) { ++ return -1; ++ } ++ ++ if (virBitmapUnion(amap, bmap) < 0) ++ return -1; ++ ++ if (!virBitmapEqual(amap, resmap)) { ++ fprintf(stderr, ++ "\n bitmap union failed: union('%s', '%s') != '%s'\n", ++ data->a, data->b, data->res); ++ return -1; ++ } ++ ++ return 0; ++} ++ + + #define TESTBINARYOP(A, B, RES, FUNC) \ + testBinaryOpData.a = A; \ +@@ -798,6 +826,16 @@ mymain(void) + TESTBINARYOP("0-3", "0,^0", "0-3", test14); + TESTBINARYOP("0,2", "1,3", "0,2", test14); + ++ /* virBitmapUnion() */ ++ virTestCounterReset("test15-"); ++ TESTBINARYOP("0-1", "0-1", "0-1", test15); ++ TESTBINARYOP("0", "1", "0-1", test15); ++ TESTBINARYOP("0-1", "2-3", "0-3", test15); ++ TESTBINARYOP("0-3", "1-2", "0-3", test15); ++ TESTBINARYOP("0,^0", "12345", "12345", test15); ++ TESTBINARYOP("12345", "0,^0", "12345", test15); ++ TESTBINARYOP("0,^0", "0,^0", "0,^0", test15); ++ + return ret; + } + +-- +2.22.0 + diff --git a/SOURCES/libvirt-util-Introduce-virNumaNodesetToCPUset.patch b/SOURCES/libvirt-util-Introduce-virNumaNodesetToCPUset.patch new file mode 100644 index 0000000..f35c94e --- /dev/null +++ b/SOURCES/libvirt-util-Introduce-virNumaNodesetToCPUset.patch @@ -0,0 +1,128 @@ +From e624d2040a5a8e16e670accc52e110393d9fb2b8 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Andrea Bolognani +Date: Tue, 11 Jun 2019 10:55:02 +0200 +Subject: [PATCH] util: Introduce virNumaNodesetToCPUset() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This helper converts a set of NUMA node to the set of CPUs +they contain. + +Signed-off-by: Andrea Bolognani +Reviewed-by: Ján Tomko +(cherry picked from commit 2d2b26f96fed1e95dd4495168cee73c5c4092634) + +https://bugzilla.redhat.com/show_bug.cgi?id=1716908 + +Signed-off-by: Andrea Bolognani +Message-Id: <20190611085506.12564-3-abologna@redhat.com> +Reviewed-by: Ján Tomko +--- + src/libvirt_private.syms | 1 + + src/util/virnuma.c | 55 ++++++++++++++++++++++++++++++++++++++++ + src/util/virnuma.h | 2 ++ + 3 files changed, 58 insertions(+) + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 05c96c29e2..7c48908a54 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -2485,6 +2485,7 @@ virNumaGetPages; + virNumaIsAvailable; + virNumaNodeIsAvailable; + virNumaNodesetIsAvailable; ++virNumaNodesetToCPUset; + virNumaSetPagePoolSize; + virNumaSetupMemoryPolicy; + +diff --git a/src/util/virnuma.c b/src/util/virnuma.c +index fd15714553..75f80dcd30 100644 +--- a/src/util/virnuma.c ++++ b/src/util/virnuma.c +@@ -311,6 +311,49 @@ virNumaGetNodeCPUs(int node, + # undef MASK_CPU_ISSET + # undef n_bits + ++/** ++ * virNumaNodesetToCPUset: ++ * @nodeset: bitmap containing a set of NUMA nodes ++ * @cpuset: return location for a bitmap containing a set of CPUs ++ * ++ * Convert a set of NUMA node to the set of CPUs they contain. ++ * ++ * Returns 0 on success, <0 on failure. ++ */ ++int ++virNumaNodesetToCPUset(virBitmapPtr nodeset, ++ virBitmapPtr *cpuset) ++{ ++ VIR_AUTOPTR(virBitmap) allNodesCPUs = NULL; ++ size_t nodesetSize; ++ size_t i; ++ ++ *cpuset = NULL; ++ ++ if (!nodeset) ++ return 0; ++ ++ allNodesCPUs = virBitmapNewEmpty(); ++ nodesetSize = virBitmapSize(nodeset); ++ ++ for (i = 0; i < nodesetSize; i++) { ++ VIR_AUTOPTR(virBitmap) nodeCPUs = NULL; ++ ++ if (!virBitmapIsBitSet(nodeset, i)) ++ continue; ++ ++ if (virNumaGetNodeCPUs(i, &nodeCPUs) < 0) ++ return -1; ++ ++ if (virBitmapUnion(allNodesCPUs, nodeCPUs) < 0) ++ return -1; ++ } ++ ++ VIR_STEAL_PTR(*cpuset, allNodesCPUs); ++ ++ return 0; ++} ++ + #else /* !WITH_NUMACTL */ + + int +@@ -365,6 +408,18 @@ virNumaGetNodeCPUs(int node ATTRIBUTE_UNUSED, + _("NUMA isn't available on this host")); + return -1; + } ++ ++int ++virNumaNodesetToCPUset(virBitmapPtr nodeset ATTRIBUTE_UNUSED, ++ virBitmapPtr *cpuset) ++{ ++ *cpuset = NULL; ++ ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("NUMA isn't available on this host")); ++ return -1; ++} ++ + #endif /* !WITH_NUMACTL */ + + /** +diff --git a/src/util/virnuma.h b/src/util/virnuma.h +index a3ffb6d6c7..df7911db4e 100644 +--- a/src/util/virnuma.h ++++ b/src/util/virnuma.h +@@ -48,6 +48,8 @@ int virNumaGetNodeMemory(int node, + unsigned int virNumaGetMaxCPUs(void); + + int virNumaGetNodeCPUs(int node, virBitmapPtr *cpus) ATTRIBUTE_NOINLINE; ++int virNumaNodesetToCPUset(virBitmapPtr nodeset, ++ virBitmapPtr *cpuset); + + int virNumaGetPageInfo(int node, + unsigned int page_size, +-- +2.22.0 + diff --git a/SOURCES/libvirt-util-Propagate-numad-failures-correctly.patch b/SOURCES/libvirt-util-Propagate-numad-failures-correctly.patch new file mode 100644 index 0000000..6414f96 --- /dev/null +++ b/SOURCES/libvirt-util-Propagate-numad-failures-correctly.patch @@ -0,0 +1,63 @@ +From 8722ee949b2099c4a4ac246fba868ae47cb828d2 Mon Sep 17 00:00:00 2001 +Message-Id: <8722ee949b2099c4a4ac246fba868ae47cb828d2@dist-git> +From: Andrea Bolognani +Date: Tue, 11 Jun 2019 10:13:50 +0200 +Subject: [PATCH] util: Propagate numad failures correctly +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Right now, if numad fails, we raise an error but return an +empty string to the caller instead of a NULL pointer, which +means processing will continue and the user will see + + # virsh start guest + error: Failed to start domain guest + error: invalid argument: Failed to parse bitmap '' + +instead of a more reasonable + + # virsh start guest + error: Failed to start domain guest + error: operation failed: Failed to query numad for the advisory nodeset + +Make sure the user gets a better error message. + +https://bugzilla.redhat.com/show_bug.cgi?id=1716387 + +Signed-off-by: Andrea Bolognani +Reviewed-by: Daniel Henrique Barboza +Reviewed-by: Ján Tomko +(cherry picked from commit b34fb1fb6f99628932ad68db1ce4985a06def17f) + +https://bugzilla.redhat.com/show_bug.cgi?id=1716907 + +Signed-off-by: Andrea Bolognani +Message-Id: <20190611081350.6476-2-abologna@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/virnuma.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/src/util/virnuma.c b/src/util/virnuma.c +index 784db0a7ce..fd15714553 100644 +--- a/src/util/virnuma.c ++++ b/src/util/virnuma.c +@@ -66,10 +66,12 @@ virNumaGetAutoPlacementAdvice(unsigned short vcpus, + + virCommandSetOutputBuffer(cmd, &output); + +- if (virCommandRun(cmd, NULL) < 0) +- virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ if (virCommandRun(cmd, NULL) < 0) { ++ virReportError(VIR_ERR_OPERATION_FAILED, "%s", + _("Failed to query numad for the " + "advisory nodeset")); ++ VIR_FREE(output); ++ } + + virCommandFree(cmd); + return output; +-- +2.22.0 + diff --git a/SOURCES/libvirt-util-Rework-virStringListAdd.patch b/SOURCES/libvirt-util-Rework-virStringListAdd.patch new file mode 100644 index 0000000..1fcd4d1 --- /dev/null +++ b/SOURCES/libvirt-util-Rework-virStringListAdd.patch @@ -0,0 +1,145 @@ +From e7d53ee08ec9929974fb4159be8359c4ba88f5b2 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Michal Privoznik +Date: Fri, 21 Jun 2019 09:26:05 +0200 +Subject: [PATCH] util: Rework virStringListAdd +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +So every caller does the same: they use virStringListAdd() to add +new item into the list and then free the old copy to replace it +with new list. It's not very memory effective, nor environmental +friendly. + +Signed-off-by: Michal Privoznik +Reviewed-by: Erik Skultety +(cherry picked from commit 71a390e0fdb4e6cbeaef4c9045a501a6c8de5412) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Signed-off-by: Jiri Denemark +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/virmacmap.c | 8 ++------ + src/util/virstring.c | 33 ++++++++++++--------------------- + src/util/virstring.h | 4 ++-- + tests/virstringtest.c | 6 +----- + 4 files changed, 17 insertions(+), 34 deletions(-) + +diff --git a/src/util/virmacmap.c b/src/util/virmacmap.c +index 88ca9b3f36..c7b700fa05 100644 +--- a/src/util/virmacmap.c ++++ b/src/util/virmacmap.c +@@ -90,7 +90,6 @@ virMacMapAddLocked(virMacMapPtr mgr, + { + int ret = -1; + char **macsList = NULL; +- char **newMacsList = NULL; + + if ((macsList = virHashLookup(mgr->macs, domain)) && + virStringListHasString((const char**) macsList, mac)) { +@@ -98,15 +97,12 @@ virMacMapAddLocked(virMacMapPtr mgr, + goto cleanup; + } + +- if (!(newMacsList = virStringListAdd((const char **) macsList, mac)) || +- virHashUpdateEntry(mgr->macs, domain, newMacsList) < 0) ++ if (virStringListAdd(&macsList, mac) < 0 || ++ virHashUpdateEntry(mgr->macs, domain, macsList) < 0) + goto cleanup; +- newMacsList = NULL; +- virStringListFree(macsList); + + ret = 0; + cleanup: +- virStringListFree(newMacsList); + return ret; + } + +diff --git a/src/util/virstring.c b/src/util/virstring.c +index 0f13b6c664..74fa2f6a94 100644 +--- a/src/util/virstring.c ++++ b/src/util/virstring.c +@@ -175,32 +175,23 @@ char *virStringListJoin(const char **strings, + * @strings: a NULL-terminated array of strings + * @item: string to add + * +- * Creates new strings list with all strings duplicated and @item +- * at the end of the list. Callers is responsible for freeing +- * both @strings and returned list. ++ * Appends @item into string list @strings. If *@strings is not ++ * allocated yet new string list is created. ++ * ++ * Returns: 0 on success, ++ * -1 otherwise + */ +-char ** +-virStringListAdd(const char **strings, ++int ++virStringListAdd(char ***strings, + const char *item) + { +- char **ret = NULL; +- size_t i = virStringListLength(strings); ++ size_t i = virStringListLength((const char **) *strings); + +- if (VIR_ALLOC_N(ret, i + 2) < 0) +- goto error; ++ if (VIR_EXPAND_N(*strings, i, 2) < 0 || ++ VIR_STRDUP((*strings)[i - 2], item) < 0) ++ return -1; + +- for (i = 0; strings && strings[i]; i++) { +- if (VIR_STRDUP(ret[i], strings[i]) < 0) +- goto error; +- } +- +- if (VIR_STRDUP(ret[i], item) < 0) +- goto error; +- +- return ret; +- error: +- virStringListFree(ret); +- return NULL; ++ return 0; + } + + +diff --git a/src/util/virstring.h b/src/util/virstring.h +index e68b9eec79..a3db08ce58 100644 +--- a/src/util/virstring.h ++++ b/src/util/virstring.h +@@ -41,8 +41,8 @@ char *virStringListJoin(const char **strings, + const char *delim) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + +-char **virStringListAdd(const char **strings, +- const char *item); ++int virStringListAdd(char ***strings, ++ const char *item); + void virStringListRemove(char ***strings, + const char *item); + +diff --git a/tests/virstringtest.c b/tests/virstringtest.c +index 1230aba5b7..1a1e6364d1 100644 +--- a/tests/virstringtest.c ++++ b/tests/virstringtest.c +@@ -179,12 +179,8 @@ static int testAdd(const void *args) + size_t i; + + for (i = 0; data->tokens[i]; i++) { +- char **tmp = virStringListAdd((const char **)list, data->tokens[i]); +- if (!tmp) ++ if (virStringListAdd(&list, data->tokens[i]) < 0) + goto cleanup; +- virStringListFree(list); +- list = tmp; +- tmp = NULL; + } + + if (!list && +-- +2.22.0 + diff --git a/SOURCES/libvirt-util-alloc-add-macros-for-implementing-automatic-cleanup-functionality.patch b/SOURCES/libvirt-util-alloc-add-macros-for-implementing-automatic-cleanup-functionality.patch new file mode 100644 index 0000000..8d9fb2c --- /dev/null +++ b/SOURCES/libvirt-util-alloc-add-macros-for-implementing-automatic-cleanup-functionality.patch @@ -0,0 +1,78 @@ +From 78f99c03b31dd7850a2eeebbf88e47e391376293 Mon Sep 17 00:00:00 2001 +Message-Id: <78f99c03b31dd7850a2eeebbf88e47e391376293@dist-git> +From: Sukrit Bhatnagar +Date: Fri, 3 May 2019 13:54:30 +0200 +Subject: [PATCH] util: alloc: add macros for implementing automatic cleanup + functionality + +New macros are introduced which help in adding GNU C's cleanup +attribute to variable declarations. Variables declared with these +macros will have their allocated memory freed automatically when +they go out of scope. + +Signed-off-by: Sukrit Bhatnagar +Reviewed-by: Erik Skultety +(cherry picked from commit dcec13f5a2ba17223d403ff9e9fed916a4dd9c04) + +https: //bugzilla.redhat.com/show_bug.cgi?id=1505998 +Signed-off-by: Erik Skultety +Message-Id: <7ca85d7157eda723aac994f7c9f0f04ed9a35ab5.1556884442.git.eskultet@redhat.com> +Reviewed-by: Andrea Bolognani +--- + src/util/viralloc.h | 42 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 42 insertions(+) + +diff --git a/src/util/viralloc.h b/src/util/viralloc.h +index 69d0f904f1..a23aa188bb 100644 +--- a/src/util/viralloc.h ++++ b/src/util/viralloc.h +@@ -596,4 +596,46 @@ void virAllocTestInit(void); + int virAllocTestCount(void); + void virAllocTestOOM(int n, int m); + void virAllocTestHook(void (*func)(int, void*), void *data); ++ ++# define VIR_AUTOPTR_FUNC_NAME(type) type##AutoPtrFree ++ ++/** ++ * VIR_DEFINE_AUTOPTR_FUNC: ++ * @type: type of the variable to be freed automatically ++ * @func: cleanup function to be automatically called ++ * ++ * This macro defines a function for automatic freeing of ++ * resources allocated to a variable of type @type. This newly ++ * defined function works as a necessary wrapper around @func. ++ */ ++# define VIR_DEFINE_AUTOPTR_FUNC(type, func) \ ++ static inline void VIR_AUTOPTR_FUNC_NAME(type)(type **_ptr) \ ++ { \ ++ if (*_ptr) \ ++ (func)(*_ptr); \ ++ *_ptr = NULL; \ ++ } \ ++ ++/** ++ * VIR_AUTOFREE: ++ * @type: type of the variable to be freed automatically ++ * ++ * Macro to automatically free the memory allocated to ++ * the variable declared with it by calling virFree ++ * when the variable goes out of scope. ++ */ ++# define VIR_AUTOFREE(type) __attribute__((cleanup(virFree))) type ++ ++/** ++ * VIR_AUTOPTR: ++ * @type: type of the variable to be freed automatically ++ * ++ * Macro to automatically free the memory allocated to ++ * the variable declared with it by calling the function ++ * defined by VIR_DEFINE_AUTOPTR_FUNC when the variable ++ * goes out of scope. ++ */ ++# define VIR_AUTOPTR(type) \ ++ __attribute__((cleanup(VIR_AUTOPTR_FUNC_NAME(type)))) type * ++ + #endif /* __VIR_MEMORY_H_ */ +-- +2.21.0 + diff --git a/SOURCES/libvirt-util-bitmap-define-cleanup-function-using-VIR_DEFINE_AUTOPTR_FUNC.patch b/SOURCES/libvirt-util-bitmap-define-cleanup-function-using-VIR_DEFINE_AUTOPTR_FUNC.patch new file mode 100644 index 0000000..278fe5f --- /dev/null +++ b/SOURCES/libvirt-util-bitmap-define-cleanup-function-using-VIR_DEFINE_AUTOPTR_FUNC.patch @@ -0,0 +1,66 @@ +From 2fe1b73a5dbbfd79c3a1a8c48747a68846785e3b Mon Sep 17 00:00:00 2001 +Message-Id: <2fe1b73a5dbbfd79c3a1a8c48747a68846785e3b@dist-git> +From: Sukrit Bhatnagar +Date: Wed, 5 Jun 2019 11:33:27 +0200 +Subject: [PATCH] util: bitmap: define cleanup function using + VIR_DEFINE_AUTOPTR_FUNC + +Using the new VIR_DEFINE_AUTOPTR_FUNC macro defined in +src/util/viralloc.h, define a new wrapper around an existing +cleanup function which will be called when a variable declared +with VIR_AUTOPTR macro goes out of scope. Also, drop the redundant +viralloc.h include, since that has moved from the source module into the +header. + +When a variable of type virBitmapPtr is declared using +VIR_AUTOPTR, the function virBitmapFree will be run +automatically on it when it goes out of scope. + +Signed-off-by: Sukrit Bhatnagar +Reviewed-by: Erik Skultety +(cherry picked from commit a3c915e662f8c25cac683e20bbc419b497555e13) + +https://bugzilla.redhat.com/show_bug.cgi?id=1716943 + +Signed-off-by: Michal Privoznik +Message-Id: +Reviewed-by: Andrea Bolognani +--- + src/util/virbitmap.c | 1 - + src/util/virbitmap.h | 3 +++ + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/util/virbitmap.c b/src/util/virbitmap.c +index 0cc5292d8c..ef18dad255 100644 +--- a/src/util/virbitmap.c ++++ b/src/util/virbitmap.c +@@ -31,7 +31,6 @@ + #include + + #include "virbitmap.h" +-#include "viralloc.h" + #include "virbuffer.h" + #include "c-ctype.h" + #include "count-one-bits.h" +diff --git a/src/util/virbitmap.h b/src/util/virbitmap.h +index 2464814055..312e7e2933 100644 +--- a/src/util/virbitmap.h ++++ b/src/util/virbitmap.h +@@ -25,6 +25,7 @@ + # define __BITMAP_H__ + + # include "internal.h" ++# include "viralloc.h" + + # include + +@@ -155,4 +156,6 @@ void virBitmapSubtract(virBitmapPtr a, virBitmapPtr b) + + void virBitmapShrink(virBitmapPtr map, size_t b); + ++VIR_DEFINE_AUTOPTR_FUNC(virBitmap, virBitmapFree) ++ + #endif +-- +2.22.0 + diff --git a/SOURCES/libvirt-util-cgroup-use-VIR_AUTOFREE-instead-of-VIR_FREE-for-scalar-types.patch b/SOURCES/libvirt-util-cgroup-use-VIR_AUTOFREE-instead-of-VIR_FREE-for-scalar-types.patch new file mode 100644 index 0000000..bfe6577 --- /dev/null +++ b/SOURCES/libvirt-util-cgroup-use-VIR_AUTOFREE-instead-of-VIR_FREE-for-scalar-types.patch @@ -0,0 +1,1528 @@ +From 02e35feddf3a72cfd52db8485f3de637b7f518ea Mon Sep 17 00:00:00 2001 +Message-Id: <02e35feddf3a72cfd52db8485f3de637b7f518ea@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:05:47 +0200 +Subject: [PATCH] util: cgroup: use VIR_AUTOFREE instead of VIR_FREE for scalar + types +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +By making use of GNU C's cleanup attribute handled by the +VIR_AUTOFREE macro for declaring scalar variables, majority +of the VIR_FREE calls can be dropped, which in turn leads to +getting rid of most of our cleanup sections. + +Signed-off-by: Sukrit Bhatnagar +Reviewed-by: Erik Skultety +(cherry picked from commit 94f1855f099445d4a18d5e5f114b60b7c58798ad) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <97a6e61acf698facf2554b05d03cd490ecc25f7e.1561993099.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 528 +++++++++++++++---------------------------- + 1 file changed, 181 insertions(+), 347 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index e810a3d81d..6bf4e88da1 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -163,7 +163,7 @@ virCgroupPartitionNeedsEscaping(const char *path) + { + FILE *fp = NULL; + int ret = 0; +- char *line = NULL; ++ VIR_AUTOFREE(char *) line = NULL; + size_t buflen; + + /* If it starts with 'cgroup.' or a '_' of any +@@ -223,7 +223,6 @@ virCgroupPartitionNeedsEscaping(const char *path) + } + + cleanup: +- VIR_FREE(line); + VIR_FORCE_FCLOSE(fp); + return ret; + } +@@ -256,41 +255,40 @@ virCgroupValidateMachineGroup(virCgroupPtr group, + const char *machinename) + { + size_t i; +- bool valid = false; +- char *partname = NULL; +- char *scopename_old = NULL; +- char *scopename_new = NULL; +- char *partmachinename = NULL; ++ VIR_AUTOFREE(char *) partname = NULL; ++ VIR_AUTOFREE(char *) scopename_old = NULL; ++ VIR_AUTOFREE(char *) scopename_new = NULL; ++ VIR_AUTOFREE(char *) partmachinename = NULL; + + if (virAsprintf(&partname, "%s.libvirt-%s", + name, drivername) < 0) +- goto cleanup; ++ return false; + + if (virCgroupPartitionEscape(&partname) < 0) +- goto cleanup; ++ return false; + + if (machinename && + (virAsprintf(&partmachinename, "%s.libvirt-%s", + machinename, drivername) < 0 || + virCgroupPartitionEscape(&partmachinename) < 0)) +- goto cleanup; ++ return false; + + if (!(scopename_old = virSystemdMakeScopeName(name, drivername, true))) +- goto cleanup; ++ return false; + + /* We should keep trying even if this failed */ + if (!machinename) + virResetLastError(); + else if (!(scopename_new = virSystemdMakeScopeName(machinename, + drivername, false))) +- goto cleanup; ++ return false; + + if (virCgroupPartitionEscape(&scopename_old) < 0) +- goto cleanup; ++ return false; + + if (scopename_new && + virCgroupPartitionEscape(&scopename_new) < 0) +- goto cleanup; ++ return false; + + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { + char *tmp; +@@ -303,7 +301,7 @@ virCgroupValidateMachineGroup(virCgroupPtr group, + + tmp = strrchr(group->controllers[i].placement, '/'); + if (!tmp) +- goto cleanup; ++ return false; + + if (stripEmulatorSuffix && + (i == VIR_CGROUP_CONTROLLER_CPU || +@@ -313,7 +311,7 @@ virCgroupValidateMachineGroup(virCgroupPtr group, + *tmp = '\0'; + tmp = strrchr(group->controllers[i].placement, '/'); + if (!tmp) +- goto cleanup; ++ return false; + } + + tmp++; +@@ -329,18 +327,11 @@ virCgroupValidateMachineGroup(virCgroupPtr group, + tmp, virCgroupControllerTypeToString(i), + name, NULLSTR(machinename), partname, + scopename_old, NULLSTR(scopename_new)); +- goto cleanup; ++ return false; + } + } + +- valid = true; +- +- cleanup: +- VIR_FREE(partmachinename); +- VIR_FREE(partname); +- VIR_FREE(scopename_old); +- VIR_FREE(scopename_new); +- return valid; ++ return true; + } + + +@@ -378,7 +369,6 @@ virCgroupDetectMountsFromFile(virCgroupPtr group, + FILE *mounts = NULL; + struct mntent entry; + char buf[CGROUP_MAX_VAL]; +- char *linksrc = NULL; + int ret = -1; + + mounts = fopen(path, "r"); +@@ -433,8 +423,9 @@ virCgroupDetectMountsFromFile(virCgroupPtr group, + /* If it is a co-mount it has a filename like "cpu,cpuacct" + * and we must identify the symlink path */ + if (checkLinks && strchr(tmp2 + 1, ',')) { ++ VIR_AUTOFREE(char *) linksrc = NULL; ++ + *tmp2 = '\0'; +- VIR_FREE(linksrc); + if (virAsprintf(&linksrc, "%s/%s", + entry.mnt_dir, typestr) < 0) + goto cleanup; +@@ -468,7 +459,6 @@ virCgroupDetectMountsFromFile(virCgroupPtr group, + + ret = 0; + cleanup: +- VIR_FREE(linksrc); + VIR_FORCE_FCLOSE(mounts); + return ret; + } +@@ -547,7 +537,7 @@ virCgroupDetectPlacement(virCgroupPtr group, + FILE *mapping = NULL; + char line[1024]; + int ret = -1; +- char *procfile; ++ VIR_AUTOFREE(char *) procfile = NULL; + + VIR_DEBUG("Detecting placement for pid %lld path %s", + (long long) pid, path); +@@ -628,9 +618,7 @@ virCgroupDetectPlacement(virCgroupPtr group, + ret = 0; + + cleanup: +- VIR_FREE(procfile); + VIR_FORCE_FCLOSE(mapping); +- + return ret; + } + +@@ -786,8 +774,7 @@ virCgroupSetValueStr(virCgroupPtr group, + const char *key, + const char *value) + { +- int ret = -1; +- char *keypath = NULL; ++ VIR_AUTOFREE(char *) keypath = NULL; + char *tmp = NULL; + + if (virCgroupPathOfController(group, controller, key, &keypath) < 0) +@@ -800,18 +787,14 @@ virCgroupSetValueStr(virCgroupPtr group, + virReportSystemError(errno, + _("Invalid value '%s' for '%s'"), + value, tmp + 1); +- goto cleanup; ++ return -1; + } + virReportSystemError(errno, + _("Unable to write to '%s'"), keypath); +- goto cleanup; ++ return -1; + } + +- ret = 0; +- +- cleanup: +- VIR_FREE(keypath); +- return ret; ++ return 0; + } + + +@@ -821,8 +804,8 @@ virCgroupGetValueStr(virCgroupPtr group, + const char *key, + char **value) + { +- char *keypath = NULL; +- int ret = -1, rc; ++ VIR_AUTOFREE(char *) keypath = NULL; ++ int rc; + + *value = NULL; + +@@ -834,18 +817,14 @@ virCgroupGetValueStr(virCgroupPtr group, + if ((rc = virFileReadAll(keypath, 1024*1024, value)) < 0) { + virReportSystemError(errno, + _("Unable to read from '%s'"), keypath); +- goto cleanup; ++ return -1; + } + + /* Terminated with '\n' has sometimes harmful effects to the caller */ + if (rc > 0 && (*value)[rc - 1] == '\n') + (*value)[rc - 1] = '\0'; + +- ret = 0; +- +- cleanup: +- VIR_FREE(keypath); +- return ret; ++ return 0; + } + + +@@ -856,8 +835,8 @@ virCgroupGetValueForBlkDev(virCgroupPtr group, + const char *path, + char **value) + { +- char *prefix = NULL; +- char *str = NULL; ++ VIR_AUTOFREE(char *) prefix = NULL; ++ VIR_AUTOFREE(char *) str = NULL; + char **lines = NULL; + int ret = -1; + +@@ -875,8 +854,6 @@ virCgroupGetValueForBlkDev(virCgroupPtr group, + + ret = 0; + error: +- VIR_FREE(str); +- VIR_FREE(prefix); + virStringListFree(lines); + return ret; + } +@@ -888,17 +865,12 @@ virCgroupSetValueU64(virCgroupPtr group, + const char *key, + unsigned long long int value) + { +- char *strval = NULL; +- int ret; ++ VIR_AUTOFREE(char *) strval = NULL; + + if (virAsprintf(&strval, "%llu", value) < 0) + return -1; + +- ret = virCgroupSetValueStr(group, controller, key, strval); +- +- VIR_FREE(strval); +- +- return ret; ++ return virCgroupSetValueStr(group, controller, key, strval); + } + + +@@ -908,17 +880,12 @@ virCgroupSetValueI64(virCgroupPtr group, + const char *key, + long long int value) + { +- char *strval = NULL; +- int ret; ++ VIR_AUTOFREE(char *) strval = NULL; + + if (virAsprintf(&strval, "%lld", value) < 0) + return -1; + +- ret = virCgroupSetValueStr(group, controller, key, strval); +- +- VIR_FREE(strval); +- +- return ret; ++ return virCgroupSetValueStr(group, controller, key, strval); + } + + +@@ -928,24 +895,19 @@ virCgroupGetValueI64(virCgroupPtr group, + const char *key, + long long int *value) + { +- char *strval = NULL; +- int ret = -1; ++ VIR_AUTOFREE(char *) strval = NULL; + + if (virCgroupGetValueStr(group, controller, key, &strval) < 0) +- goto cleanup; ++ return -1; + + if (virStrToLong_ll(strval, NULL, 10, value) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to parse '%s' as an integer"), + strval); +- goto cleanup; ++ return -1; + } + +- ret = 0; +- +- cleanup: +- VIR_FREE(strval); +- return ret; ++ return 0; + } + + +@@ -955,24 +917,19 @@ virCgroupGetValueU64(virCgroupPtr group, + const char *key, + unsigned long long int *value) + { +- char *strval = NULL; +- int ret = -1; ++ VIR_AUTOFREE(char *) strval = NULL; + + if (virCgroupGetValueStr(group, controller, key, &strval) < 0) +- goto cleanup; ++ return -1; + + if (virStrToLong_ull(strval, NULL, 10, value) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to parse '%s' as an integer"), + strval); +- goto cleanup; ++ return -1; + } + +- ret = 0; +- +- cleanup: +- VIR_FREE(strval); +- return ret; ++ return 0; + } + + +@@ -988,7 +945,7 @@ virCgroupCpuSetInherit(virCgroupPtr parent, virCgroupPtr group) + + VIR_DEBUG("Setting up inheritance %s -> %s", parent->path, group->path); + for (i = 0; i < ARRAY_CARDINALITY(inherit_values); i++) { +- char *value; ++ VIR_AUTOFREE(char *) value = NULL; + + if (virCgroupGetValueStr(parent, + VIR_CGROUP_CONTROLLER_CPUSET, +@@ -1001,11 +958,8 @@ virCgroupCpuSetInherit(virCgroupPtr parent, virCgroupPtr group) + if (virCgroupSetValueStr(group, + VIR_CGROUP_CONTROLLER_CPUSET, + inherit_values[i], +- value) < 0) { +- VIR_FREE(value); ++ value) < 0) + return -1; +- } +- VIR_FREE(value); + } + + return 0; +@@ -1044,11 +998,10 @@ virCgroupMakeGroup(virCgroupPtr parent, + unsigned int flags) + { + size_t i; +- int ret = -1; + + VIR_DEBUG("Make group %s", group->path); + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { +- char *path = NULL; ++ VIR_AUTOFREE(char *) path = NULL; + + /* We must never mkdir() in systemd's hierarchy */ + if (i == VIR_CGROUP_CONTROLLER_SYSTEMD) { +@@ -1074,10 +1027,8 @@ virCgroupMakeGroup(virCgroupPtr parent, + if (!virFileExists(path)) { + if (!create || + mkdir(path, 0755) < 0) { +- if (errno == EEXIST) { +- VIR_FREE(path); ++ if (errno == EEXIST) + continue; +- } + /* With a kernel that doesn't support multi-level directory + * for blkio controller, libvirt will fail and disable all + * other controllers even though they are available. So +@@ -1085,24 +1036,20 @@ virCgroupMakeGroup(virCgroupPtr parent, + if (i == VIR_CGROUP_CONTROLLER_BLKIO) { + VIR_DEBUG("Ignoring mkdir failure with blkio controller. Kernel probably too old"); + VIR_FREE(group->controllers[i].mountPoint); +- VIR_FREE(path); + continue; + } else { + virReportSystemError(errno, + _("Failed to create controller %s for group"), + virCgroupControllerTypeToString(i)); +- VIR_FREE(path); +- goto cleanup; ++ return -1; + } + } + if (group->controllers[VIR_CGROUP_CONTROLLER_CPUSET].mountPoint != NULL && + (i == VIR_CGROUP_CONTROLLER_CPUSET || + STREQ(group->controllers[i].mountPoint, + group->controllers[VIR_CGROUP_CONTROLLER_CPUSET].mountPoint))) { +- if (virCgroupCpuSetInherit(parent, group) < 0) { +- VIR_FREE(path); +- goto cleanup; +- } ++ if (virCgroupCpuSetInherit(parent, group) < 0) ++ return -1; + } + /* + * Note that virCgroupSetMemoryUseHierarchy should always be +@@ -1113,21 +1060,14 @@ virCgroupMakeGroup(virCgroupPtr parent, + (i == VIR_CGROUP_CONTROLLER_MEMORY || + STREQ(group->controllers[i].mountPoint, + group->controllers[VIR_CGROUP_CONTROLLER_MEMORY].mountPoint))) { +- if (virCgroupSetMemoryUseHierarchy(group) < 0) { +- VIR_FREE(path); +- goto cleanup; +- } ++ if (virCgroupSetMemoryUseHierarchy(group) < 0) ++ return -1; + } + } +- +- VIR_FREE(path); + } + + VIR_DEBUG("Done making controllers for group"); +- ret = 0; +- +- cleanup: +- return ret; ++ return 0; + } + + +@@ -1339,9 +1279,9 @@ virCgroupNewPartition(const char *path, + virCgroupPtr *group) + { + int ret = -1; +- char *parentPath = NULL; ++ VIR_AUTOFREE(char *) parentPath = NULL; ++ VIR_AUTOFREE(char *) newPath = NULL; + virCgroupPtr parent = NULL; +- char *newPath = NULL; + VIR_DEBUG("path=%s create=%d controllers=%x", + path, create, controllers); + +@@ -1381,8 +1321,6 @@ virCgroupNewPartition(const char *path, + if (ret != 0) + virCgroupFree(group); + virCgroupFree(&parent); +- VIR_FREE(parentPath); +- VIR_FREE(newPath); + return ret; + } + +@@ -1421,18 +1359,17 @@ virCgroupNewDomainPartition(virCgroupPtr partition, + bool create, + virCgroupPtr *group) + { +- int ret = -1; +- char *grpname = NULL; ++ VIR_AUTOFREE(char *)grpname = NULL; + + if (virAsprintf(&grpname, "%s.libvirt-%s", + name, driver) < 0) +- goto cleanup; ++ return -1; + + if (virCgroupPartitionEscape(&grpname) < 0) +- goto cleanup; ++ return -1; + + if (virCgroupNew(-1, grpname, partition, -1, group) < 0) +- goto cleanup; ++ return -1; + + /* + * Create a cgroup with memory.use_hierarchy enabled to +@@ -1448,14 +1385,10 @@ virCgroupNewDomainPartition(virCgroupPtr partition, + VIR_CGROUP_MEM_HIERACHY) < 0) { + virCgroupRemove(*group); + virCgroupFree(group); +- goto cleanup; ++ return -1; + } + +- ret = 0; +- +- cleanup: +- VIR_FREE(grpname); +- return ret; ++ return 0; + } + + +@@ -1477,27 +1410,26 @@ virCgroupNewThread(virCgroupPtr domain, + bool create, + virCgroupPtr *group) + { +- int ret = -1; +- char *name = NULL; ++ VIR_AUTOFREE(char *) name = NULL; + int controllers; + + switch (nameval) { + case VIR_CGROUP_THREAD_VCPU: + if (virAsprintf(&name, "vcpu%d", id) < 0) +- goto cleanup; ++ return -1; + break; + case VIR_CGROUP_THREAD_EMULATOR: + if (VIR_STRDUP(name, "emulator") < 0) +- goto cleanup; ++ return -1; + break; + case VIR_CGROUP_THREAD_IOTHREAD: + if (virAsprintf(&name, "iothread%d", id) < 0) +- goto cleanup; ++ return -1; + break; + case VIR_CGROUP_THREAD_LAST: + virReportError(VIR_ERR_INTERNAL_ERROR, + _("unexpected name value %d"), nameval); +- goto cleanup; ++ return -1; + } + + controllers = ((1 << VIR_CGROUP_CONTROLLER_CPU) | +@@ -1505,18 +1437,15 @@ virCgroupNewThread(virCgroupPtr domain, + (1 << VIR_CGROUP_CONTROLLER_CPUSET)); + + if (virCgroupNew(-1, name, domain, controllers, group) < 0) +- goto cleanup; ++ return -1; + + if (virCgroupMakeGroup(domain, *group, create, VIR_CGROUP_NONE) < 0) { + virCgroupRemove(*group); + virCgroupFree(group); +- goto cleanup; ++ return -1; + } + +- ret = 0; +- cleanup: +- VIR_FREE(name); +- return ret; ++ return 0; + } + + +@@ -1577,7 +1506,7 @@ virCgroupNewMachineSystemd(const char *name, + int ret = -1; + int rv; + virCgroupPtr init, parent = NULL; +- char *path = NULL; ++ VIR_AUTOFREE(char *) path = NULL; + char *offset; + + VIR_DEBUG("Trying to setup machine '%s' via systemd", name); +@@ -1662,7 +1591,6 @@ virCgroupNewMachineSystemd(const char *name, + ret = 0; + cleanup: + virCgroupFree(&parent); +- VIR_FREE(path); + return ret; + } + +@@ -1894,9 +1822,11 @@ virCgroupGetBlkioIoServiced(virCgroupPtr group, + long long *requests_write) + { + long long stats_val; +- char *str1 = NULL, *str2 = NULL, *p1, *p2; ++ VIR_AUTOFREE(char *) str1 = NULL; ++ VIR_AUTOFREE(char *) str2 = NULL; ++ char *p1 = NULL; ++ char *p2 = NULL; + size_t i; +- int ret = -1; + + const char *value_names[] = { + "Read ", +@@ -1919,12 +1849,12 @@ virCgroupGetBlkioIoServiced(virCgroupPtr group, + if (virCgroupGetValueStr(group, + VIR_CGROUP_CONTROLLER_BLKIO, + "blkio.throttle.io_service_bytes", &str1) < 0) +- goto cleanup; ++ return -1; + + if (virCgroupGetValueStr(group, + VIR_CGROUP_CONTROLLER_BLKIO, + "blkio.throttle.io_serviced", &str2) < 0) +- goto cleanup; ++ return -1; + + /* sum up all entries of the same kind, from all devices */ + for (i = 0; i < ARRAY_CARDINALITY(value_names); i++) { +@@ -1938,7 +1868,7 @@ virCgroupGetBlkioIoServiced(virCgroupPtr group, + _("Cannot parse byte %sstat '%s'"), + value_names[i], + p1); +- goto cleanup; ++ return -1; + } + + if (stats_val < 0 || +@@ -1947,7 +1877,7 @@ virCgroupGetBlkioIoServiced(virCgroupPtr group, + virReportError(VIR_ERR_OVERFLOW, + _("Sum of byte %sstat overflows"), + value_names[i]); +- goto cleanup; ++ return -1; + } + *bytes_ptrs[i] += stats_val; + } +@@ -1959,7 +1889,7 @@ virCgroupGetBlkioIoServiced(virCgroupPtr group, + _("Cannot parse %srequest stat '%s'"), + value_names[i], + p2); +- goto cleanup; ++ return -1; + } + + if (stats_val < 0 || +@@ -1968,18 +1898,13 @@ virCgroupGetBlkioIoServiced(virCgroupPtr group, + virReportError(VIR_ERR_OVERFLOW, + _("Sum of %srequest stat overflows"), + value_names[i]); +- goto cleanup; ++ return -1; + } + *requests_ptrs[i] += stats_val; + } + } + +- ret = 0; +- +- cleanup: +- VIR_FREE(str2); +- VIR_FREE(str1); +- return ret; ++ return 0; + } + + +@@ -2003,9 +1928,12 @@ virCgroupGetBlkioIoDeviceServiced(virCgroupPtr group, + long long *requests_read, + long long *requests_write) + { +- char *str1 = NULL, *str2 = NULL, *str3 = NULL, *p1, *p2; ++ VIR_AUTOFREE(char *) str1 = NULL; ++ VIR_AUTOFREE(char *) str2 = NULL; ++ VIR_AUTOFREE(char *) str3 = NULL; ++ char *p1 = NULL; ++ char *p2 = NULL; + size_t i; +- int ret = -1; + + const char *value_names[] = { + "Read ", +@@ -2023,28 +1951,28 @@ virCgroupGetBlkioIoDeviceServiced(virCgroupPtr group, + if (virCgroupGetValueStr(group, + VIR_CGROUP_CONTROLLER_BLKIO, + "blkio.throttle.io_service_bytes", &str1) < 0) +- goto cleanup; ++ return -1; + + if (virCgroupGetValueStr(group, + VIR_CGROUP_CONTROLLER_BLKIO, + "blkio.throttle.io_serviced", &str2) < 0) +- goto cleanup; ++ return -1; + + if (!(str3 = virCgroupGetBlockDevString(path))) +- goto cleanup; ++ return -1; + + if (!(p1 = strstr(str1, str3))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Cannot find byte stats for block device '%s'"), + str3); +- goto cleanup; ++ return -1; + } + + if (!(p2 = strstr(str2, str3))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Cannot find request stats for block device '%s'"), + str3); +- goto cleanup; ++ return -1; + } + + for (i = 0; i < ARRAY_CARDINALITY(value_names); i++) { +@@ -2052,38 +1980,32 @@ virCgroupGetBlkioIoDeviceServiced(virCgroupPtr group, + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Cannot find byte %sstats for block device '%s'"), + value_names[i], str3); +- goto cleanup; ++ return -1; + } + + if (virStrToLong_ll(p1 + strlen(value_names[i]), &p1, 10, bytes_ptrs[i]) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Cannot parse %sstat '%s'"), + value_names[i], p1 + strlen(value_names[i])); +- goto cleanup; ++ return -1; + } + + if (!(p2 = strstr(p2, value_names[i]))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Cannot find request %sstats for block device '%s'"), + value_names[i], str3); +- goto cleanup; ++ return -1; + } + + if (virStrToLong_ll(p2 + strlen(value_names[i]), &p2, 10, requests_ptrs[i]) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Cannot parse %sstat '%s'"), + value_names[i], p2 + strlen(value_names[i])); +- goto cleanup; ++ return -1; + } + } + +- ret = 0; +- +- cleanup: +- VIR_FREE(str3); +- VIR_FREE(str2); +- VIR_FREE(str1); +- return ret; ++ return 0; + } + + +@@ -2139,24 +2061,19 @@ virCgroupSetBlkioDeviceReadIops(virCgroupPtr group, + const char *path, + unsigned int riops) + { +- char *str = NULL; +- char *blkstr = NULL; +- int ret = -1; ++ VIR_AUTOFREE(char *) str = NULL; ++ VIR_AUTOFREE(char *) blkstr = NULL; + + if (!(blkstr = virCgroupGetBlockDevString(path))) + return -1; + + if (virAsprintf(&str, "%s%u", blkstr, riops) < 0) +- goto error; ++ return -1; + +- ret = virCgroupSetValueStr(group, ++ return virCgroupSetValueStr(group, + VIR_CGROUP_CONTROLLER_BLKIO, + "blkio.throttle.read_iops_device", + str); +- error: +- VIR_FREE(blkstr); +- VIR_FREE(str); +- return ret; + } + + +@@ -2173,24 +2090,19 @@ virCgroupSetBlkioDeviceWriteIops(virCgroupPtr group, + const char *path, + unsigned int wiops) + { +- char *str = NULL; +- char *blkstr = NULL; +- int ret = -1; ++ VIR_AUTOFREE(char *) str = NULL; ++ VIR_AUTOFREE(char *) blkstr = NULL; + + if (!(blkstr = virCgroupGetBlockDevString(path))) + return -1; + + if (virAsprintf(&str, "%s%u", blkstr, wiops) < 0) +- goto error; ++ return -1; + +- ret = virCgroupSetValueStr(group, ++ return virCgroupSetValueStr(group, + VIR_CGROUP_CONTROLLER_BLKIO, + "blkio.throttle.write_iops_device", + str); +- error: +- VIR_FREE(blkstr); +- VIR_FREE(str); +- return ret; + } + + +@@ -2207,24 +2119,19 @@ virCgroupSetBlkioDeviceReadBps(virCgroupPtr group, + const char *path, + unsigned long long rbps) + { +- char *str = NULL; +- char *blkstr = NULL; +- int ret = -1; ++ VIR_AUTOFREE(char *) str = NULL; ++ VIR_AUTOFREE(char *) blkstr = NULL; + + if (!(blkstr = virCgroupGetBlockDevString(path))) + return -1; + + if (virAsprintf(&str, "%s%llu", blkstr, rbps) < 0) +- goto error; ++ return -1; + +- ret = virCgroupSetValueStr(group, ++ return virCgroupSetValueStr(group, + VIR_CGROUP_CONTROLLER_BLKIO, + "blkio.throttle.read_bps_device", + str); +- error: +- VIR_FREE(blkstr); +- VIR_FREE(str); +- return ret; + } + + /** +@@ -2240,24 +2147,19 @@ virCgroupSetBlkioDeviceWriteBps(virCgroupPtr group, + const char *path, + unsigned long long wbps) + { +- char *str = NULL; +- char *blkstr = NULL; +- int ret = -1; ++ VIR_AUTOFREE(char *) str = NULL; ++ VIR_AUTOFREE(char *) blkstr = NULL; + + if (!(blkstr = virCgroupGetBlockDevString(path))) + return -1; + + if (virAsprintf(&str, "%s%llu", blkstr, wbps) < 0) +- goto error; ++ return -1; + +- ret = virCgroupSetValueStr(group, ++ return virCgroupSetValueStr(group, + VIR_CGROUP_CONTROLLER_BLKIO, + "blkio.throttle.write_bps_device", + str); +- error: +- VIR_FREE(blkstr); +- VIR_FREE(str); +- return ret; + } + + +@@ -2275,24 +2177,19 @@ virCgroupSetBlkioDeviceWeight(virCgroupPtr group, + const char *path, + unsigned int weight) + { +- char *str = NULL; +- char *blkstr = NULL; +- int ret = -1; ++ VIR_AUTOFREE(char *) str = NULL; ++ VIR_AUTOFREE(char *) blkstr = NULL; + + if (!(blkstr = virCgroupGetBlockDevString(path))) + return -1; + + if (virAsprintf(&str, "%s%d", blkstr, weight) < 0) +- goto error; ++ return -1; + +- ret = virCgroupSetValueStr(group, ++ return virCgroupSetValueStr(group, + VIR_CGROUP_CONTROLLER_BLKIO, + "blkio.weight_device", + str); +- error: +- VIR_FREE(blkstr); +- VIR_FREE(str); +- return ret; + } + + /** +@@ -2308,15 +2205,14 @@ virCgroupGetBlkioDeviceReadIops(virCgroupPtr group, + const char *path, + unsigned int *riops) + { +- char *str = NULL; +- int ret = -1; ++ VIR_AUTOFREE(char *) str = NULL; + + if (virCgroupGetValueForBlkDev(group, + VIR_CGROUP_CONTROLLER_BLKIO, + "blkio.throttle.read_iops_device", + path, + &str) < 0) +- goto error; ++ return -1; + + if (!str) { + *riops = 0; +@@ -2324,13 +2220,10 @@ virCgroupGetBlkioDeviceReadIops(virCgroupPtr group, + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to parse '%s' as an integer"), + str); +- goto error; ++ return -1; + } + +- ret = 0; +- error: +- VIR_FREE(str); +- return ret; ++ return 0; + } + + /** +@@ -2346,15 +2239,14 @@ virCgroupGetBlkioDeviceWriteIops(virCgroupPtr group, + const char *path, + unsigned int *wiops) + { +- char *str = NULL; +- int ret = -1; ++ VIR_AUTOFREE(char *) str = NULL; + + if (virCgroupGetValueForBlkDev(group, + VIR_CGROUP_CONTROLLER_BLKIO, + "blkio.throttle.write_iops_device", + path, + &str) < 0) +- goto error; ++ return -1; + + if (!str) { + *wiops = 0; +@@ -2362,13 +2254,10 @@ virCgroupGetBlkioDeviceWriteIops(virCgroupPtr group, + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to parse '%s' as an integer"), + str); +- goto error; ++ return -1; + } + +- ret = 0; +- error: +- VIR_FREE(str); +- return ret; ++ return 0; + } + + /** +@@ -2384,15 +2273,14 @@ virCgroupGetBlkioDeviceReadBps(virCgroupPtr group, + const char *path, + unsigned long long *rbps) + { +- char *str = NULL; +- int ret = -1; ++ VIR_AUTOFREE(char *) str = NULL; + + if (virCgroupGetValueForBlkDev(group, + VIR_CGROUP_CONTROLLER_BLKIO, + "blkio.throttle.read_bps_device", + path, + &str) < 0) +- goto error; ++ return -1; + + if (!str) { + *rbps = 0; +@@ -2400,13 +2288,10 @@ virCgroupGetBlkioDeviceReadBps(virCgroupPtr group, + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to parse '%s' as an integer"), + str); +- goto error; ++ return -1; + } + +- ret = 0; +- error: +- VIR_FREE(str); +- return ret; ++ return 0; + } + + /** +@@ -2422,15 +2307,14 @@ virCgroupGetBlkioDeviceWriteBps(virCgroupPtr group, + const char *path, + unsigned long long *wbps) + { +- char *str = NULL; +- int ret = -1; ++ VIR_AUTOFREE(char *) str = NULL; + + if (virCgroupGetValueForBlkDev(group, + VIR_CGROUP_CONTROLLER_BLKIO, + "blkio.throttle.write_bps_device", + path, + &str) < 0) +- goto error; ++ return -1; + + if (!str) { + *wbps = 0; +@@ -2438,13 +2322,10 @@ virCgroupGetBlkioDeviceWriteBps(virCgroupPtr group, + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to parse '%s' as an integer"), + str); +- goto error; ++ return -1; + } + +- ret = 0; +- error: +- VIR_FREE(str); +- return ret; ++ return 0; + } + + /** +@@ -2460,15 +2341,14 @@ virCgroupGetBlkioDeviceWeight(virCgroupPtr group, + const char *path, + unsigned int *weight) + { +- char *str = NULL; +- int ret = -1; ++ VIR_AUTOFREE(char *) str = NULL; + + if (virCgroupGetValueForBlkDev(group, + VIR_CGROUP_CONTROLLER_BLKIO, + "blkio.weight_device", + path, + &str) < 0) +- goto error; ++ return -1; + + if (!str) { + *weight = 0; +@@ -2476,13 +2356,10 @@ virCgroupGetBlkioDeviceWeight(virCgroupPtr group, + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to parse '%s' as an integer"), + str); +- goto error; ++ return -1; + } + +- ret = 0; +- error: +- VIR_FREE(str); +- return ret; ++ return 0; + } + + +@@ -2941,36 +2818,29 @@ int + virCgroupAllowDevice(virCgroupPtr group, char type, int major, int minor, + int perms) + { +- int ret = -1; +- char *devstr = NULL; +- char *majorstr = NULL; +- char *minorstr = NULL; ++ VIR_AUTOFREE(char *) devstr = NULL; ++ VIR_AUTOFREE(char *) majorstr = NULL; ++ VIR_AUTOFREE(char *) minorstr = NULL; + + if ((major < 0 && VIR_STRDUP(majorstr, "*") < 0) || + (major >= 0 && virAsprintf(&majorstr, "%i", major) < 0)) +- goto cleanup; ++ return -1; + + if ((minor < 0 && VIR_STRDUP(minorstr, "*") < 0) || + (minor >= 0 && virAsprintf(&minorstr, "%i", minor) < 0)) +- goto cleanup; ++ return -1; + + if (virAsprintf(&devstr, "%c %s:%s %s", type, majorstr, minorstr, + virCgroupGetDevicePermsString(perms)) < 0) +- goto cleanup; ++ return -1; + + if (virCgroupSetValueStr(group, + VIR_CGROUP_CONTROLLER_DEVICES, + "devices.allow", + devstr) < 0) +- goto cleanup; ++ return -1; + +- ret = 0; +- +- cleanup: +- VIR_FREE(devstr); +- VIR_FREE(majorstr); +- VIR_FREE(minorstr); +- return ret; ++ return 0; + } + + +@@ -3032,36 +2902,29 @@ int + virCgroupDenyDevice(virCgroupPtr group, char type, int major, int minor, + int perms) + { +- int ret = -1; +- char *devstr = NULL; +- char *majorstr = NULL; +- char *minorstr = NULL; ++ VIR_AUTOFREE(char *) devstr = NULL; ++ VIR_AUTOFREE(char *) majorstr = NULL; ++ VIR_AUTOFREE(char *) minorstr = NULL; + + if ((major < 0 && VIR_STRDUP(majorstr, "*") < 0) || + (major >= 0 && virAsprintf(&majorstr, "%i", major) < 0)) +- goto cleanup; ++ return -1; + + if ((minor < 0 && VIR_STRDUP(minorstr, "*") < 0) || + (minor >= 0 && virAsprintf(&minorstr, "%i", minor) < 0)) +- goto cleanup; ++ return -1; + + if (virAsprintf(&devstr, "%c %s:%s %s", type, majorstr, minorstr, + virCgroupGetDevicePermsString(perms)) < 0) +- goto cleanup; ++ return -1; + + if (virCgroupSetValueStr(group, + VIR_CGROUP_CONTROLLER_DEVICES, + "devices.deny", + devstr) < 0) +- goto cleanup; ++ return -1; + +- ret = 0; +- +- cleanup: +- VIR_FREE(devstr); +- VIR_FREE(majorstr); +- VIR_FREE(minorstr); +- return ret; ++ return 0; + } + + +@@ -3131,10 +2994,10 @@ virCgroupGetPercpuVcpuSum(virCgroupPtr group, + { + int ret = -1; + ssize_t i = -1; +- char *buf = NULL; + virCgroupPtr group_vcpu = NULL; + + while ((i = virBitmapNextSetBit(guestvcpus, i)) >= 0) { ++ VIR_AUTOFREE(char *) buf = NULL; + char *pos; + unsigned long long tmp; + ssize_t j; +@@ -3159,13 +3022,11 @@ virCgroupGetPercpuVcpuSum(virCgroupPtr group, + } + + virCgroupFree(&group_vcpu); +- VIR_FREE(buf); + } + + ret = 0; + cleanup: + virCgroupFree(&group_vcpu); +- VIR_FREE(buf); + return ret; + } + +@@ -3202,8 +3063,8 @@ virCgroupGetPercpuStats(virCgroupPtr group, + size_t i; + int need_cpus, total_cpus; + char *pos; +- char *buf = NULL; +- unsigned long long *sum_cpu_time = NULL; ++ VIR_AUTOFREE(char *) buf = NULL; ++ VIR_AUTOFREE(unsigned long long *) sum_cpu_time = NULL; + virTypedParameterPtr ent; + int param_idx; + unsigned long long cpu_time; +@@ -3289,8 +3150,6 @@ virCgroupGetPercpuStats(virCgroupPtr group, + + cleanup: + virBitmapFree(cpumap); +- VIR_FREE(sum_cpu_time); +- VIR_FREE(buf); + return ret; + } + +@@ -3461,7 +3320,7 @@ virCgroupRemoveRecursively(char *grppath) + /* This is best-effort cleanup: we want to log failures with just + * VIR_ERROR instead of normal virReportError */ + while ((direrr = virDirRead(grpdir, &ent, NULL)) > 0) { +- char *path; ++ VIR_AUTOFREE(char *) path = NULL; + + if (ent->d_type != DT_DIR) continue; + +@@ -3470,7 +3329,6 @@ virCgroupRemoveRecursively(char *grppath) + break; + } + rc = virCgroupRemoveRecursively(path); +- VIR_FREE(path); + if (rc != 0) + break; + } +@@ -3508,10 +3366,11 @@ virCgroupRemove(virCgroupPtr group) + { + int rc = 0; + size_t i; +- char *grppath = NULL; + + VIR_DEBUG("Removing cgroup %s", group->path); + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { ++ VIR_AUTOFREE(char *) grppath = NULL; ++ + /* Skip over controllers not mounted */ + if (!group->controllers[i].mountPoint) + continue; +@@ -3533,7 +3392,6 @@ virCgroupRemove(virCgroupPtr group) + + VIR_DEBUG("Removing cgroup %s and all child cgroups", grppath); + rc = virCgroupRemoveRecursively(grppath); +- VIR_FREE(grppath); + } + VIR_DEBUG("Done removing cgroup %s", group->path); + +@@ -3549,7 +3407,7 @@ virCgroupKillInternal(virCgroupPtr group, int signum, virHashTablePtr pids) + { + int ret = -1; + bool killedAny = false; +- char *keypath = NULL; ++ VIR_AUTOFREE(char *) keypath = NULL; + bool done = false; + FILE *fp = NULL; + VIR_DEBUG("group=%p path=%s signum=%d pids=%p", +@@ -3613,7 +3471,6 @@ virCgroupKillInternal(virCgroupPtr group, int signum, virHashTablePtr pids) + ret = killedAny ? 1 : 0; + + cleanup: +- VIR_FREE(keypath); + VIR_FORCE_FCLOSE(fp); + + return ret; +@@ -3678,7 +3535,7 @@ virCgroupKillRecursiveInternal(virCgroupPtr group, + int ret = -1; + int rc; + bool killedAny = false; +- char *keypath = NULL; ++ VIR_AUTOFREE(char *) keypath = NULL; + DIR *dp = NULL; + virCgroupPtr subgroup = NULL; + struct dirent *ent; +@@ -3732,7 +3589,6 @@ virCgroupKillRecursiveInternal(virCgroupPtr group, + + cleanup: + virCgroupFree(&subgroup); +- VIR_FREE(keypath); + VIR_DIR_CLOSE(dp); + return ret; + } +@@ -3846,9 +3702,8 @@ int + virCgroupGetCpuacctStat(virCgroupPtr group, unsigned long long *user, + unsigned long long *sys) + { +- char *str; ++ VIR_AUTOFREE(char *) str = NULL; + char *p; +- int ret = -1; + static double scale = -1.0; + + if (virCgroupGetValueStr(group, VIR_CGROUP_CONTROLLER_CPUACCT, +@@ -3860,14 +3715,14 @@ virCgroupGetCpuacctStat(virCgroupPtr group, unsigned long long *user, + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Cannot parse user stat '%s'"), + p); +- goto cleanup; ++ return -1; + } + if (!(p = STRSKIP(p, "\nsystem ")) || + virStrToLong_ull(p, NULL, 10, sys) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Cannot parse sys stat '%s'"), + p); +- goto cleanup; ++ return -1; + } + /* times reported are in system ticks (generally 100 Hz), but that + * rate can theoretically vary between machines. Scale things +@@ -3877,17 +3732,14 @@ virCgroupGetCpuacctStat(virCgroupPtr group, unsigned long long *user, + if (ticks_per_sec == -1) { + virReportSystemError(errno, "%s", + _("Cannot determine system clock HZ")); +- goto cleanup; ++ return -1; + } + scale = 1000000000.0 / ticks_per_sec; + } + *user *= scale; + *sys *= scale; + +- ret = 0; +- cleanup: +- VIR_FREE(str); +- return ret; ++ return 0; + } + + +@@ -3913,10 +3765,9 @@ int + virCgroupBindMount(virCgroupPtr group, const char *oldroot, + const char *mountopts) + { +- int ret = -1; + size_t i; +- char *opts = NULL; +- char *root = NULL; ++ VIR_AUTOFREE(char *) opts = NULL; ++ VIR_AUTOFREE(char *) root = NULL; + + if (!(root = virCgroupIdentifyRoot(group))) + return -1; +@@ -3927,18 +3778,18 @@ virCgroupBindMount(virCgroupPtr group, const char *oldroot, + virReportSystemError(errno, + _("Unable to create directory %s"), + root); +- goto cleanup; ++ return -1; + } + + if (virAsprintf(&opts, + "mode=755,size=65536%s", mountopts) < 0) +- goto cleanup; ++ return -1; + + if (mount("tmpfs", root, "tmpfs", MS_NOSUID|MS_NODEV|MS_NOEXEC, opts) < 0) { + virReportSystemError(errno, + _("Failed to mount %s on %s type %s"), + "tmpfs", root, "tmpfs"); +- goto cleanup; ++ return -1; + } + + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { +@@ -3946,11 +3797,11 @@ virCgroupBindMount(virCgroupPtr group, const char *oldroot, + continue; + + if (!virFileExists(group->controllers[i].mountPoint)) { +- char *src; ++ VIR_AUTOFREE(char *) src = NULL; + if (virAsprintf(&src, "%s%s", + oldroot, + group->controllers[i].mountPoint) < 0) +- goto cleanup; ++ return -1; + + VIR_DEBUG("Create mount point '%s'", + group->controllers[i].mountPoint); +@@ -3958,8 +3809,7 @@ virCgroupBindMount(virCgroupPtr group, const char *oldroot, + virReportSystemError(errno, + _("Unable to create directory %s"), + group->controllers[i].mountPoint); +- VIR_FREE(src); +- goto cleanup; ++ return -1; + } + + if (mount(src, group->controllers[i].mountPoint, "none", MS_BIND, +@@ -3967,11 +3817,8 @@ virCgroupBindMount(virCgroupPtr group, const char *oldroot, + virReportSystemError(errno, + _("Failed to bind cgroup '%s' on '%s'"), + src, group->controllers[i].mountPoint); +- VIR_FREE(src); +- goto cleanup; ++ return -1; + } +- +- VIR_FREE(src); + } + + if (group->controllers[i].linkPoint) { +@@ -3984,16 +3831,12 @@ virCgroupBindMount(virCgroupPtr group, const char *oldroot, + _("Unable to symlink directory %s to %s"), + group->controllers[i].mountPoint, + group->controllers[i].linkPoint); +- goto cleanup; ++ return -1; + } + } + } +- ret = 0; + +- cleanup: +- VIR_FREE(root); +- VIR_FREE(opts); +- return ret; ++ return 0; + } + + +@@ -4004,11 +3847,11 @@ int virCgroupSetOwner(virCgroupPtr cgroup, + { + int ret = -1; + size_t i; +- char *base = NULL, *entry = NULL; + DIR *dh = NULL; + int direrr; + + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { ++ VIR_AUTOFREE(char *) base = NULL; + struct dirent *de; + + if (!((1 << i) & controllers)) +@@ -4025,6 +3868,8 @@ int virCgroupSetOwner(virCgroupPtr cgroup, + goto cleanup; + + while ((direrr = virDirRead(dh, &de, base)) > 0) { ++ VIR_AUTOFREE(char *) entry = NULL; ++ + if (virAsprintf(&entry, "%s/%s", base, de->d_name) < 0) + goto cleanup; + +@@ -4034,8 +3879,6 @@ int virCgroupSetOwner(virCgroupPtr cgroup, + entry, uid, gid); + goto cleanup; + } +- +- VIR_FREE(entry); + } + if (direrr < 0) + goto cleanup; +@@ -4047,7 +3890,6 @@ int virCgroupSetOwner(virCgroupPtr cgroup, + goto cleanup; + } + +- VIR_FREE(base); + VIR_DIR_CLOSE(dh); + } + +@@ -4055,8 +3897,6 @@ int virCgroupSetOwner(virCgroupPtr cgroup, + + cleanup: + VIR_DIR_CLOSE(dh); +- VIR_FREE(entry); +- VIR_FREE(base); + return ret; + } + +@@ -4071,8 +3911,7 @@ int virCgroupSetOwner(virCgroupPtr cgroup, + bool + virCgroupSupportsCpuBW(virCgroupPtr cgroup) + { +- char *path = NULL; +- bool ret = false; ++ VIR_AUTOFREE(char *) path = NULL; + + if (!cgroup) + return false; +@@ -4080,21 +3919,17 @@ virCgroupSupportsCpuBW(virCgroupPtr cgroup) + if (virCgroupPathOfController(cgroup, VIR_CGROUP_CONTROLLER_CPU, + "cpu.cfs_period_us", &path) < 0) { + virResetLastError(); +- goto cleanup; ++ return false; + } + +- ret = virFileExists(path); +- +- cleanup: +- VIR_FREE(path); +- return ret; ++ return virFileExists(path); + } + + int + virCgroupHasEmptyTasks(virCgroupPtr cgroup, int controller) + { + int ret = -1; +- char *content = NULL; ++ VIR_AUTOFREE(char *) content = NULL; + + if (!cgroup) + return -1; +@@ -4104,7 +3939,6 @@ virCgroupHasEmptyTasks(virCgroupPtr cgroup, int controller) + if (ret == 0 && content[0] == '\0') + ret = 1; + +- VIR_FREE(content); + return ret; + } + +-- +2.22.0 + diff --git a/SOURCES/libvirt-util-command-Ignore-bitmap-errors-when-enumerating-file-descriptors-to-close.patch b/SOURCES/libvirt-util-command-Ignore-bitmap-errors-when-enumerating-file-descriptors-to-close.patch new file mode 100644 index 0000000..05e45db --- /dev/null +++ b/SOURCES/libvirt-util-command-Ignore-bitmap-errors-when-enumerating-file-descriptors-to-close.patch @@ -0,0 +1,62 @@ +From 2544ab6ac5b788d2df319afaef8d495409aa7b32 Mon Sep 17 00:00:00 2001 +Message-Id: <2544ab6ac5b788d2df319afaef8d495409aa7b32@dist-git> +From: Peter Krempa +Date: Tue, 30 Jul 2019 16:04:51 +0200 +Subject: [PATCH] util: command: Ignore bitmap errors when enumerating file + descriptors to close +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +virCommandMassCloseGetFDsLinux fails when running libvird on valgrind +with the following message: + +libvirt: error : internal error: unable to set FD as open: 1024 + +This is because valgrind opens few file descriptors beyond the limit: + +65701125 lr-x------. 1 root root 64 Jul 18 14:48 1024 -> /home/pipo/build/libvirt/gcc/src/.libs/libvirtd +65701126 lrwx------. 1 root root 64 Jul 18 14:48 1025 -> '/tmp/valgrind_proc_3849_cmdline_186612e3 (deleted)' +65701127 lrwx------. 1 root root 64 Jul 18 14:48 1026 -> '/tmp/valgrind_proc_3849_auxv_186612e3 (deleted)' +65701128 lrwx------. 1 root root 64 Jul 18 14:48 1027 -> /dev/pts/11 +65701129 lr-x------. 1 root root 64 Jul 18 14:48 1028 -> 'pipe:[65689522]' +65701130 l-wx------. 1 root root 64 Jul 18 14:48 1029 -> 'pipe:[65689522]' +65701131 lr-x------. 1 root root 64 Jul 18 14:48 1030 -> /tmp/vgdb-pipe-from-vgdb-to-3849-by-root-on-angien + +Ignore bitmap errors in this case since we'd leak those FD's anyways in +the previous scenario. + +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +(cherry picked from commit 728343983787cbd4d7ae8fa2007a157bb140f02a) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1721434 + +Signed-off-by: Michal Privoznik +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircommand.c | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +diff --git a/src/util/vircommand.c b/src/util/vircommand.c +index 2353a4a554..dfc7e5428b 100644 +--- a/src/util/vircommand.c ++++ b/src/util/vircommand.c +@@ -519,12 +519,7 @@ virCommandMassCloseGetFDsLinux(virCommandPtr cmd ATTRIBUTE_UNUSED, + goto cleanup; + } + +- if (virBitmapSetBit(fds, fd) < 0) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("unable to set FD as open: %d"), +- fd); +- goto cleanup; +- } ++ ignore_value(virBitmapSetBit(fds, fd)); + } + + if (rc < 0) +-- +2.22.0 + diff --git a/SOURCES/libvirt-util-command-define-cleanup-function-using-VIR_DEFINE_AUTOPTR_FUNC.patch b/SOURCES/libvirt-util-command-define-cleanup-function-using-VIR_DEFINE_AUTOPTR_FUNC.patch new file mode 100644 index 0000000..ff97244 --- /dev/null +++ b/SOURCES/libvirt-util-command-define-cleanup-function-using-VIR_DEFINE_AUTOPTR_FUNC.patch @@ -0,0 +1,69 @@ +From 47babc4b1ad1c615df10385bbaafdd30d9359b7a Mon Sep 17 00:00:00 2001 +Message-Id: <47babc4b1ad1c615df10385bbaafdd30d9359b7a@dist-git> +From: Sukrit Bhatnagar +Date: Tue, 30 Jul 2019 15:30:46 +0200 +Subject: [PATCH] util: command: define cleanup function using + VIR_DEFINE_AUTOPTR_FUNC +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Using the new VIR_DEFINE_AUTOPTR_FUNC macro defined in +src/util/viralloc.h, define a new wrapper around an existing +cleanup function which will be called when a variable declared +with VIR_AUTOPTR macro goes out of scope. Also, drop the redundant +viralloc.h include, since that has moved from the source module into the +header. + +When a variable of type virCommandPtr is declared using VIR_AUTOPTR, +the function virCommandFree will be run automatically on it when it +goes out of scope. + +Signed-off-by: Sukrit Bhatnagar +Reviewed-by: Erik Skultety +(cherry picked from commit 7e343758920cc954d448b6b14df5707bcd0dbd20) + +Prerequisite of: https://bugzilla.redhat.com/show_bug.cgi?id=1721434 + +Signed-off-by: Michal Privoznik +Message-Id: <40a1fc21abc06c057574a4616eef9981dbfb25dd.1564493409.git.mprivozn@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircommand.c | 1 - + src/util/vircommand.h | 2 ++ + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/util/vircommand.c b/src/util/vircommand.c +index c2b8a1a3c3..d328431373 100644 +--- a/src/util/vircommand.c ++++ b/src/util/vircommand.c +@@ -44,7 +44,6 @@ + + #define __VIR_COMMAND_PRIV_H_ALLOW__ + #include "vircommandpriv.h" +-#include "viralloc.h" + #include "virerror.h" + #include "virutil.h" + #include "virlog.h" +diff --git a/src/util/vircommand.h b/src/util/vircommand.h +index 883e212959..90bcc6c89d 100644 +--- a/src/util/vircommand.h ++++ b/src/util/vircommand.h +@@ -24,6 +24,7 @@ + + # include "internal.h" + # include "virbuffer.h" ++# include "viralloc.h" + + typedef struct _virCommand virCommand; + typedef virCommand *virCommandPtr; +@@ -218,5 +219,6 @@ int virCommandRunNul(virCommandPtr cmd, + virCommandRunNulFunc func, + void *data); + ++VIR_DEFINE_AUTOPTR_FUNC(virCommand, virCommandFree) + + #endif /* __VIR_COMMAND_H__ */ +-- +2.22.0 + diff --git a/SOURCES/libvirt-util-command-use-VIR_AUTOFREE-instead-of-VIR_FREE-for-scalar-types.patch b/SOURCES/libvirt-util-command-use-VIR_AUTOFREE-instead-of-VIR_FREE-for-scalar-types.patch new file mode 100644 index 0000000..4e000f4 --- /dev/null +++ b/SOURCES/libvirt-util-command-use-VIR_AUTOFREE-instead-of-VIR_FREE-for-scalar-types.patch @@ -0,0 +1,194 @@ +From 63fe889c0e3d5c9cf44ab030fb63baee3646cb9f Mon Sep 17 00:00:00 2001 +Message-Id: <63fe889c0e3d5c9cf44ab030fb63baee3646cb9f@dist-git> +From: Sukrit Bhatnagar +Date: Tue, 30 Jul 2019 15:30:45 +0200 +Subject: [PATCH] util: command: use VIR_AUTOFREE instead of VIR_FREE for + scalar types +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +By making use of GNU C's cleanup attribute handled by the +VIR_AUTOFREE macro for declaring scalar variables, majority +of the VIR_FREE calls can be dropped, which in turn leads to +getting rid of most of our cleanup sections. + +Signed-off-by: Sukrit Bhatnagar +Reviewed-by: Erik Skultety +(cherry picked from commit 46a1f0bb648dec58d6ce4b0eccbb59be435d9073) + +Prerequisite of: https://bugzilla.redhat.com/show_bug.cgi?id=1721434 + +Signed-off-by: Michal Privoznik +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircommand.c | 40 ++++++++++++---------------------------- + 1 file changed, 12 insertions(+), 28 deletions(-) + +diff --git a/src/util/vircommand.c b/src/util/vircommand.c +index 6dab105f56..c2b8a1a3c3 100644 +--- a/src/util/vircommand.c ++++ b/src/util/vircommand.c +@@ -508,11 +508,11 @@ virExec(virCommandPtr cmd) + int childout = -1; + int childerr = -1; + int tmpfd; +- char *binarystr = NULL; ++ VIR_AUTOFREE(char *) binarystr = NULL; + const char *binary = NULL; + int ret; + struct sigaction waxon, waxoff; +- gid_t *groups = NULL; ++ VIR_AUTOFREE(gid_t *) groups = NULL; + int ngroups; + + if (cmd->args[0][0] != '/') { +@@ -605,9 +605,6 @@ virExec(virCommandPtr cmd) + + cmd->pid = pid; + +- VIR_FREE(groups); +- VIR_FREE(binarystr); +- + return 0; + } + +@@ -797,9 +794,6 @@ virExec(virCommandPtr cmd) + /* This is cleanup of parent process only - child + should never jump here on error */ + +- VIR_FREE(binarystr); +- VIR_FREE(groups); +- + /* NB we don't virReportError() on any failures here + because the code which jumped here already raised + an error condition which we must not overwrite */ +@@ -2387,7 +2381,7 @@ int + virCommandRunAsync(virCommandPtr cmd, pid_t *pid) + { + int ret = -1; +- char *str = NULL; ++ VIR_AUTOFREE(char *) str = NULL; + size_t i; + bool synchronous = false; + int infd[2] = {-1, -1}; +@@ -2512,7 +2506,6 @@ virCommandRunAsync(virCommandPtr cmd, pid_t *pid) + VIR_FORCE_CLOSE(cmd->infd); + VIR_FORCE_CLOSE(cmd->inpipe); + } +- VIR_FREE(str); + return ret; + } + +@@ -2589,8 +2582,8 @@ virCommandWait(virCommandPtr cmd, int *exitstatus) + if (exitstatus && (cmd->rawStatus || WIFEXITED(status))) { + *exitstatus = cmd->rawStatus ? status : WEXITSTATUS(status); + } else if (status) { +- char *str = virCommandToString(cmd); +- char *st = virProcessTranslateStatus(status); ++ VIR_AUTOFREE(char *) str = virCommandToString(cmd); ++ VIR_AUTOFREE(char *) st = virProcessTranslateStatus(status); + bool haveErrMsg = cmd->errbuf && *cmd->errbuf && (*cmd->errbuf)[0]; + + virReportError(VIR_ERR_INTERNAL_ERROR, +@@ -2598,8 +2591,6 @@ virCommandWait(virCommandPtr cmd, int *exitstatus) + str ? str : cmd->args[0], NULLSTR(st), + haveErrMsg ? ": " : "", + haveErrMsg ? *cmd->errbuf : ""); +- VIR_FREE(str); +- VIR_FREE(st); + return -1; + } + } +@@ -2719,7 +2710,7 @@ int virCommandHandshakeWait(virCommandPtr cmd) + return -1; + } + if (c != '1') { +- char *msg; ++ VIR_AUTOFREE(char *) msg = NULL; + ssize_t len; + if (VIR_ALLOC_N(msg, 1024) < 0) { + VIR_FORCE_CLOSE(cmd->handshakeWait[0]); +@@ -2732,7 +2723,6 @@ int virCommandHandshakeWait(virCommandPtr cmd) + + if ((len = saferead(cmd->handshakeWait[0], msg, 1024)) < 0) { + VIR_FORCE_CLOSE(cmd->handshakeWait[0]); +- VIR_FREE(msg); + virReportSystemError(errno, "%s", + _("No error message from child failure")); + return -1; +@@ -2740,7 +2730,6 @@ int virCommandHandshakeWait(virCommandPtr cmd) + VIR_FORCE_CLOSE(cmd->handshakeWait[0]); + msg[len-1] = '\0'; + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", msg); +- VIR_FREE(msg); + return -1; + } + VIR_FORCE_CLOSE(cmd->handshakeWait[0]); +@@ -2854,8 +2843,8 @@ virCommandFree(virCommandPtr cmd) + * This requests asynchronous string IO on @cmd. It is useful in + * combination with virCommandRunAsync(): + * +- * virCommandPtr cmd = virCommandNew*(...); +- * char *buf = NULL; ++ * VIR_AUTOPTR(virCommand) cmd = virCommandNew*(...); ++ * VIR_AUTOFREE(char *) buf = NULL; + * + * ... + * +@@ -2863,21 +2852,18 @@ virCommandFree(virCommandPtr cmd) + * virCommandDoAsyncIO(cmd); + * + * if (virCommandRunAsync(cmd, NULL) < 0) +- * goto cleanup; ++ * return; + * + * ... + * + * if (virCommandWait(cmd, NULL) < 0) +- * goto cleanup; ++ * return; + * + * // @buf now contains @cmd's stdout + * VIR_DEBUG("STDOUT: %s", NULLSTR(buf)); + * + * ... + * +- * cleanup: +- * VIR_FREE(buf); +- * virCommandFree(cmd); + * + * The libvirt's event loop is used for handling stdios of @cmd. + * Since current implementation uses strlen to determine length +@@ -2970,11 +2956,11 @@ virCommandRunRegex(virCommandPtr cmd, + { + int err; + regex_t *reg; +- regmatch_t *vars = NULL; ++ VIR_AUTOFREE(regmatch_t *) vars = NULL; + size_t i, j, k; + int totgroups = 0, ngroup = 0, maxvars = 0; + char **groups; +- char *outbuf = NULL; ++ VIR_AUTOFREE(char *) outbuf = NULL; + char **lines = NULL; + int ret = -1; + +@@ -3055,13 +3041,11 @@ virCommandRunRegex(virCommandPtr cmd, + ret = 0; + cleanup: + virStringListFree(lines); +- VIR_FREE(outbuf); + if (groups) { + for (j = 0; j < totgroups; j++) + VIR_FREE(groups[j]); + VIR_FREE(groups); + } +- VIR_FREE(vars); + + for (i = 0; i < nregex; i++) + regfree(®[i]); +-- +2.22.0 + diff --git a/SOURCES/libvirt-util-enable-cgroups-v2-cpuset-controller-for-threads.patch b/SOURCES/libvirt-util-enable-cgroups-v2-cpuset-controller-for-threads.patch new file mode 100644 index 0000000..4da907c --- /dev/null +++ b/SOURCES/libvirt-util-enable-cgroups-v2-cpuset-controller-for-threads.patch @@ -0,0 +1,44 @@ +From 77eb53c13d2d9a641143cc374f8262c2cb004120 Mon Sep 17 00:00:00 2001 +Message-Id: <77eb53c13d2d9a641143cc374f8262c2cb004120@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:08:14 +0200 +Subject: [PATCH] util: enable cgroups v2 cpuset controller for threads +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When we create cgroup for qemu threads we need to enable cpuset +controller in order to use it. + +Signed-off-by: Pavel Hrdina +(cherry picked from commit a6aedcf39bd3212a3cd624b765bb724fd36d6a8a) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <1dfb136ea7a417fdcc03b84c59bb364a75e24d52.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index ef1f286726..04638c4e50 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -401,6 +401,12 @@ virCgroupV2MakeGroup(virCgroupPtr parent ATTRIBUTE_UNUSED, + VIR_CGROUP_CONTROLLER_CPU) < 0) { + return -1; + } ++ ++ if (virCgroupV2HasController(parent, VIR_CGROUP_CONTROLLER_CPUSET) && ++ virCgroupV2EnableController(parent, ++ VIR_CGROUP_CONTROLLER_CPUSET) < 0) { ++ return -1; ++ } + } else { + size_t i; + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { +-- +2.22.0 + diff --git a/SOURCES/libvirt-util-file-introduce-VIR_AUTOCLOSE-macro-to-close-fd-of-the-file-automatically.patch b/SOURCES/libvirt-util-file-introduce-VIR_AUTOCLOSE-macro-to-close-fd-of-the-file-automatically.patch new file mode 100644 index 0000000..10b3612 --- /dev/null +++ b/SOURCES/libvirt-util-file-introduce-VIR_AUTOCLOSE-macro-to-close-fd-of-the-file-automatically.patch @@ -0,0 +1,68 @@ +From 3d08d15b8fb214233e6b426bffe8f8b89969529a Mon Sep 17 00:00:00 2001 +Message-Id: <3d08d15b8fb214233e6b426bffe8f8b89969529a@dist-git> +From: Shi Lei +Date: Fri, 21 Jun 2019 09:25:42 +0200 +Subject: [PATCH] util: file: introduce VIR_AUTOCLOSE macro to close fd of the + file automatically +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Shi Lei +(cherry picked from commit 09d35afd2c3058688290d5d818343d0f6aa2dd6e) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Signed-off-by: Jiri Denemark +Message-Id: <93cb7516e852b96a82eac8dd71acdccc81ef13f9.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/virfile.h | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +diff --git a/src/util/virfile.h b/src/util/virfile.h +index 51c221e069..fa03269289 100644 +--- a/src/util/virfile.h ++++ b/src/util/virfile.h +@@ -53,6 +53,11 @@ int virFileClose(int *fdptr, virFileCloseFlags flags) + int virFileFclose(FILE **file, bool preserve_errno) ATTRIBUTE_RETURN_CHECK; + FILE *virFileFdopen(int *fdptr, const char *mode) ATTRIBUTE_RETURN_CHECK; + ++static inline void virForceCloseHelper(int *fd) ++{ ++ ignore_value(virFileClose(fd, VIR_FILE_CLOSE_PRESERVE_ERRNO)); ++} ++ + /* For use on normal paths; caller must check return value, + and failure sets errno per close. */ + # define VIR_CLOSE(FD) virFileClose(&(FD), 0) +@@ -63,8 +68,7 @@ FILE *virFileFdopen(int *fdptr, const char *mode) ATTRIBUTE_RETURN_CHECK; + + /* For use on cleanup paths; errno is unaffected by close, + and no return value to worry about. */ +-# define VIR_FORCE_CLOSE(FD) \ +- ignore_value(virFileClose(&(FD), VIR_FILE_CLOSE_PRESERVE_ERRNO)) ++# define VIR_FORCE_CLOSE(FD) virForceCloseHelper(&(FD)) + # define VIR_FORCE_FCLOSE(FILE) ignore_value(virFileFclose(&(FILE), true)) + + /* Similar VIR_FORCE_CLOSE() but ignores EBADF errors since they are expected +@@ -79,6 +83,16 @@ FILE *virFileFdopen(int *fdptr, const char *mode) ATTRIBUTE_RETURN_CHECK; + VIR_FILE_CLOSE_PRESERVE_ERRNO | \ + VIR_FILE_CLOSE_DONT_LOG)) + ++/** ++ * VIR_AUTOCLOSE: ++ * ++ * Macro to automatically force close the fd by calling virForceCloseHelper ++ * when the fd goes out of scope. It's used to eliminate VIR_FORCE_CLOSE ++ * in cleanup sections. ++ */ ++# define VIR_AUTOCLOSE __attribute__((cleanup(virForceCloseHelper))) int ++ ++ + /* Opaque type for managing a wrapper around a fd. */ + struct _virFileWrapperFd; + +-- +2.22.0 + diff --git a/SOURCES/libvirt-util-implement-virCgroupV2-Set-Get-CpusetCpus.patch b/SOURCES/libvirt-util-implement-virCgroupV2-Set-Get-CpusetCpus.patch new file mode 100644 index 0000000..153d769 --- /dev/null +++ b/SOURCES/libvirt-util-implement-virCgroupV2-Set-Get-CpusetCpus.patch @@ -0,0 +1,66 @@ +From 40020f9a96747e4e4b108c3cbef32222174bc2ab Mon Sep 17 00:00:00 2001 +Message-Id: <40020f9a96747e4e4b108c3cbef32222174bc2ab@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:08:13 +0200 +Subject: [PATCH] util: implement virCgroupV2(Set|Get)CpusetCpus +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 3b72c84ff1c1b8b393ba9c2ccb004f8eb1ebda95) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <6146318ef3b9ca769029e33c4617056cdb652844.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index bc6ced2367..ef1f286726 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -1601,6 +1601,28 @@ virCgroupV2GetCpusetMemoryMigrate(virCgroupPtr group ATTRIBUTE_UNUSED, + } + + ++static int ++virCgroupV2SetCpusetCpus(virCgroupPtr group, ++ const char *cpus) ++{ ++ return virCgroupSetValueStr(group, ++ VIR_CGROUP_CONTROLLER_CPUSET, ++ "cpuset.cpus", ++ cpus); ++} ++ ++ ++static int ++virCgroupV2GetCpusetCpus(virCgroupPtr group, ++ char **cpus) ++{ ++ return virCgroupGetValueStr(group, ++ VIR_CGROUP_CONTROLLER_CPUSET, ++ "cpuset.cpus", ++ cpus); ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -1665,6 +1687,8 @@ virCgroupBackend virCgroupV2Backend = { + .getCpusetMems = virCgroupV2GetCpusetMems, + .setCpusetMemoryMigrate = virCgroupV2SetCpusetMemoryMigrate, + .getCpusetMemoryMigrate = virCgroupV2GetCpusetMemoryMigrate, ++ .setCpusetCpus = virCgroupV2SetCpusetCpus, ++ .getCpusetCpus = virCgroupV2GetCpusetCpus, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-util-implement-virCgroupV2-Set-Get-CpusetMemoryMigrate.patch b/SOURCES/libvirt-util-implement-virCgroupV2-Set-Get-CpusetMemoryMigrate.patch new file mode 100644 index 0000000..39314e1 --- /dev/null +++ b/SOURCES/libvirt-util-implement-virCgroupV2-Set-Get-CpusetMemoryMigrate.patch @@ -0,0 +1,64 @@ +From 0cde517cd560d47824e0e98fab32b62cbd0f89ea Mon Sep 17 00:00:00 2001 +Message-Id: <0cde517cd560d47824e0e98fab32b62cbd0f89ea@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:08:12 +0200 +Subject: [PATCH] util: implement virCgroupV2(Set|Get)CpusetMemoryMigrate +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Cgroups v2 don't have memory_migrate interface and the migration is +enabled by default. + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 77c1cf4da2f761a91756c09fa4fd37ae1802e650) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 59b8c4ad2c..bc6ced2367 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -1584,6 +1584,23 @@ virCgroupV2GetCpusetMems(virCgroupPtr group, + } + + ++static int ++virCgroupV2SetCpusetMemoryMigrate(virCgroupPtr group ATTRIBUTE_UNUSED, ++ bool migrate ATTRIBUTE_UNUSED) ++{ ++ return 0; ++} ++ ++ ++static int ++virCgroupV2GetCpusetMemoryMigrate(virCgroupPtr group ATTRIBUTE_UNUSED, ++ bool *migrate) ++{ ++ *migrate = true; ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -1646,6 +1663,8 @@ virCgroupBackend virCgroupV2Backend = { + + .setCpusetMems = virCgroupV2SetCpusetMems, + .getCpusetMems = virCgroupV2GetCpusetMems, ++ .setCpusetMemoryMigrate = virCgroupV2SetCpusetMemoryMigrate, ++ .getCpusetMemoryMigrate = virCgroupV2GetCpusetMemoryMigrate, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-util-implement-virCgroupV2-Set-Get-CpusetMems.patch b/SOURCES/libvirt-util-implement-virCgroupV2-Set-Get-CpusetMems.patch new file mode 100644 index 0000000..ec50860 --- /dev/null +++ b/SOURCES/libvirt-util-implement-virCgroupV2-Set-Get-CpusetMems.patch @@ -0,0 +1,67 @@ +From df01b3c361e5bdcd8505798336b15b862e9c6bea Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:08:11 +0200 +Subject: [PATCH] util: implement virCgroupV2(Set|Get)CpusetMems +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 74e7da060543a87610b42fc6ba26a45b0a6e3974) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <2bb5ec423c37893ebbf2f882da13cc4e55b23941.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 25 +++++++++++++++++++++++++ + 1 file changed, 25 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 8658454d8b..59b8c4ad2c 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -1562,6 +1562,28 @@ virCgroupV2GetCpuacctStat(virCgroupPtr group, + } + + ++static int ++virCgroupV2SetCpusetMems(virCgroupPtr group, ++ const char *mems) ++{ ++ return virCgroupSetValueStr(group, ++ VIR_CGROUP_CONTROLLER_CPUSET, ++ "cpuset.mems", ++ mems); ++} ++ ++ ++static int ++virCgroupV2GetCpusetMems(virCgroupPtr group, ++ char **mems) ++{ ++ return virCgroupGetValueStr(group, ++ VIR_CGROUP_CONTROLLER_CPUSET, ++ "cpuset.mems", ++ mems); ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -1621,6 +1643,9 @@ virCgroupBackend virCgroupV2Backend = { + + .getCpuacctUsage = virCgroupV2GetCpuacctUsage, + .getCpuacctStat = virCgroupV2GetCpuacctStat, ++ ++ .setCpusetMems = virCgroupV2SetCpusetMems, ++ .getCpusetMems = virCgroupV2GetCpusetMems, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-util-introduce-cgroup-v2-files.patch b/SOURCES/libvirt-util-introduce-cgroup-v2-files.patch new file mode 100644 index 0000000..4234cdc --- /dev/null +++ b/SOURCES/libvirt-util-introduce-cgroup-v2-files.patch @@ -0,0 +1,256 @@ +From 04bdbfa106768447822f3e8eeb2946e1f7bfb2b5 Mon Sep 17 00:00:00 2001 +Message-Id: <04bdbfa106768447822f3e8eeb2946e1f7bfb2b5@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:12 +0200 +Subject: [PATCH] util: introduce cgroup v2 files +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Place cgroup v2 backend type before cgroup v1 to make it obvious +that cgroup v2 is preferred implementation. + +Following patches will introduce support for hybrid configuration +which will allow us to use both at the same time, but we should +prefer cgroup v2 regardless. + +Signed-off-by: Pavel Hrdina +(cherry picked from commit b4ddf5ae62ee3a50c7ead1e00914a141e5798096) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/Makefile.am | 1 + + src/libvirt_private.syms | 3 ++ + src/util/Makefile.inc.am | 2 ++ + src/util/vircgroup.c | 3 ++ + src/util/vircgroupbackend.c | 2 ++ + src/util/vircgroupbackend.h | 3 +- + src/util/vircgrouppriv.h | 9 ++++++ + src/util/vircgroupv2.c | 63 +++++++++++++++++++++++++++++++++++++ + src/util/vircgroupv2.h | 27 ++++++++++++++++ + 9 files changed, 112 insertions(+), 1 deletion(-) + create mode 100644 src/util/vircgroupv2.c + create mode 100644 src/util/vircgroupv2.h + +diff --git a/src/Makefile.am b/src/Makefile.am +index 0def0a3b19..cc8e29a45a 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -680,6 +680,7 @@ libvirt_setuid_rpc_client_la_SOURCES = \ + util/vircgroup.c \ + util/vircgroupbackend.c \ + util/vircgroupv1.c \ ++ util/vircgroupv2.c \ + util/vircommand.c \ + util/virconf.c \ + util/virdbus.c \ +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index b144955154..8132f9664b 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -1598,6 +1598,9 @@ virCgroupBackendRegister; + # util/vircgroupv1.h + virCgroupV1Register; + ++# util/vircgroupv2.h ++virCgroupV2Register; ++ + # util/virclosecallbacks.h + virCloseCallbacksGet; + virCloseCallbacksGetConn; +diff --git a/src/util/Makefile.inc.am b/src/util/Makefile.inc.am +index 725ece98e9..24a98632a3 100644 +--- a/src/util/Makefile.inc.am ++++ b/src/util/Makefile.inc.am +@@ -27,6 +27,8 @@ UTIL_SOURCES = \ + util/vircgroupbackend.h \ + util/vircgroupv1.c \ + util/vircgroupv1.h \ ++ util/vircgroupv2.c \ ++ util/vircgroupv2.h \ + util/virclosecallbacks.c \ + util/virclosecallbacks.h \ + util/vircommand.c \ +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 7ec1399bc6..42930582db 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -1240,6 +1240,9 @@ virCgroupFree(virCgroupPtr *group) + VIR_FREE((*group)->legacy[i].placement); + } + ++ VIR_FREE((*group)->unified.mountPoint); ++ VIR_FREE((*group)->unified.placement); ++ + VIR_FREE((*group)->path); + VIR_FREE(*group); + } +diff --git a/src/util/vircgroupbackend.c b/src/util/vircgroupbackend.c +index d854c9711d..79fe6cb73d 100644 +--- a/src/util/vircgroupbackend.c ++++ b/src/util/vircgroupbackend.c +@@ -21,6 +21,7 @@ + + #include "vircgroupbackend.h" + #include "vircgroupv1.h" ++#include "vircgroupv2.h" + #include "virerror.h" + #include "virthread.h" + +@@ -28,6 +29,7 @@ + + VIR_ENUM_DECL(virCgroupBackend); + VIR_ENUM_IMPL(virCgroupBackend, VIR_CGROUP_BACKEND_TYPE_LAST, ++ "cgroup V2", + "cgroup V1"); + + static virOnceControl virCgroupBackendOnce = VIR_ONCE_CONTROL_INITIALIZER; +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index 1c5744ef76..b1f19233e4 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -50,7 +50,8 @@ typedef enum { + } virCgroupBackendTaskFlags; + + typedef enum { +- VIR_CGROUP_BACKEND_TYPE_V1 = 0, ++ VIR_CGROUP_BACKEND_TYPE_V2 = 0, ++ VIR_CGROUP_BACKEND_TYPE_V1, + VIR_CGROUP_BACKEND_TYPE_LAST, + } virCgroupBackendType; + +diff --git a/src/util/vircgrouppriv.h b/src/util/vircgrouppriv.h +index c50a25f195..4a0d75ddbc 100644 +--- a/src/util/vircgrouppriv.h ++++ b/src/util/vircgrouppriv.h +@@ -45,12 +45,21 @@ struct _virCgroupV1Controller { + typedef struct _virCgroupV1Controller virCgroupV1Controller; + typedef virCgroupV1Controller *virCgroupV1ControllerPtr; + ++struct _virCgroupV2Controller { ++ int controllers; ++ char *mountPoint; ++ char *placement; ++}; ++typedef struct _virCgroupV2Controller virCgroupV2Controller; ++typedef virCgroupV2Controller *virCgroupV2ControllerPtr; ++ + struct _virCgroup { + char *path; + + virCgroupBackendPtr backend; + + virCgroupV1Controller legacy[VIR_CGROUP_CONTROLLER_LAST]; ++ virCgroupV2Controller unified; + }; + + int virCgroupSetValueStr(virCgroupPtr group, +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +new file mode 100644 +index 0000000000..23bf81dae2 +--- /dev/null ++++ b/src/util/vircgroupv2.c +@@ -0,0 +1,63 @@ ++/* ++ * vircgroupv2.c: methods for cgroups v2 backend ++ * ++ * Copyright (C) 2018 Red Hat, Inc. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library. If not, see ++ * . ++ */ ++#include ++ ++#include "internal.h" ++ ++#define __VIR_CGROUP_ALLOW_INCLUDE_PRIV_H__ ++#include "vircgrouppriv.h" ++#undef __VIR_CGROUP_ALLOW_INCLUDE_PRIV_H__ ++ ++#include "vircgroup.h" ++#include "vircgroupbackend.h" ++#include "vircgroupv2.h" ++#include "virlog.h" ++ ++VIR_LOG_INIT("util.cgroup"); ++ ++#define VIR_FROM_THIS VIR_FROM_CGROUP ++ ++VIR_ENUM_DECL(virCgroupV2Controller); ++VIR_ENUM_IMPL(virCgroupV2Controller, VIR_CGROUP_CONTROLLER_LAST, ++ "cpu", "cpuacct", "cpuset", "memory", "devices", ++ "freezer", "io", "net_cls", "perf_event", "name=systemd"); ++ ++#ifdef __linux__ ++ ++virCgroupBackend virCgroupV2Backend = { ++ .type = VIR_CGROUP_BACKEND_TYPE_V2, ++}; ++ ++ ++void ++virCgroupV2Register(void) ++{ ++ virCgroupBackendRegister(&virCgroupV2Backend); ++} ++ ++#else /* !__linux__ */ ++ ++void ++virCgroupV2Register(void) ++{ ++ VIR_INFO("Control groups not supported on this platform"); ++} ++ ++#endif /* !__linux__ */ +diff --git a/src/util/vircgroupv2.h b/src/util/vircgroupv2.h +new file mode 100644 +index 0000000000..a5d0bd0978 +--- /dev/null ++++ b/src/util/vircgroupv2.h +@@ -0,0 +1,27 @@ ++/* ++ * vircgroupv2.h: methods for cgroups v2 backend ++ * ++ * Copyright (C) 2018 Red Hat, Inc. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library. If not, see ++ * . ++ */ ++ ++#ifndef __VIR_CGROUP_V2_H__ ++# define __VIR_CGROUP_V2_H__ ++ ++void ++virCgroupV2Register(void); ++ ++#endif /* __VIR_CGROUP_V2_H__ */ +-- +2.22.0 + diff --git a/SOURCES/libvirt-util-introduce-vircgroupbackend-files.patch b/SOURCES/libvirt-util-introduce-vircgroupbackend-files.patch new file mode 100644 index 0000000..78471e2 --- /dev/null +++ b/SOURCES/libvirt-util-introduce-vircgroupbackend-files.patch @@ -0,0 +1,197 @@ +From 2396295b2654156d62165bc1d94e2a3f4d1e4733 Mon Sep 17 00:00:00 2001 +Message-Id: <2396295b2654156d62165bc1d94e2a3f4d1e4733@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:21 +0200 +Subject: [PATCH] util: introduce vircgroupbackend files +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We will need to extract current cgroup v1 implementation into separate +backend because there will be new cgroup v2 implementation and both will +have to co-exist. + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 1a2dbb5595871efa8de1ed258d94f0b60561a040) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/Makefile.am | 1 + + src/libvirt_private.syms | 3 ++ + src/util/Makefile.inc.am | 2 ++ + src/util/vircgroupbackend.c | 64 +++++++++++++++++++++++++++++++++++++ + src/util/vircgroupbackend.h | 46 ++++++++++++++++++++++++++ + 5 files changed, 116 insertions(+) + create mode 100644 src/util/vircgroupbackend.c + create mode 100644 src/util/vircgroupbackend.h + +diff --git a/src/Makefile.am b/src/Makefile.am +index db8c8ebd1a..c4e797f5a2 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -678,6 +678,7 @@ libvirt_setuid_rpc_client_la_SOURCES = \ + util/virbitmap.c \ + util/virbuffer.c \ + util/vircgroup.c \ ++ util/vircgroupbackend.c \ + util/vircommand.c \ + util/virconf.c \ + util/virdbus.c \ +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 8c4be84fd5..627eb5e587 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -1591,6 +1591,9 @@ virCgroupSetOwner; + virCgroupSupportsCpuBW; + virCgroupTerminateMachine; + ++# util/vircgroupbackend.h ++virCgroupBackendGetAll; ++virCgroupBackendRegister; + + # util/virclosecallbacks.h + virCloseCallbacksGet; +diff --git a/src/util/Makefile.inc.am b/src/util/Makefile.inc.am +index 2cef465208..a9185bd7b7 100644 +--- a/src/util/Makefile.inc.am ++++ b/src/util/Makefile.inc.am +@@ -23,6 +23,8 @@ UTIL_SOURCES = \ + util/virperf.h \ + util/vircgroup.c \ + util/vircgroup.h util/vircgrouppriv.h \ ++ util/vircgroupbackend.c \ ++ util/vircgroupbackend.h \ + util/virclosecallbacks.c \ + util/virclosecallbacks.h \ + util/vircommand.c \ +diff --git a/src/util/vircgroupbackend.c b/src/util/vircgroupbackend.c +new file mode 100644 +index 0000000000..e014bfc0e6 +--- /dev/null ++++ b/src/util/vircgroupbackend.c +@@ -0,0 +1,64 @@ ++/* ++ * vircgroupbackend.c: methods for cgroups backend ++ * ++ * Copyright (C) 2018 Red Hat, Inc. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library. If not, see ++ * . ++ */ ++#include ++ ++#include "vircgroupbackend.h" ++#include "virerror.h" ++#include "virthread.h" ++ ++#define VIR_FROM_THIS VIR_FROM_CGROUP ++ ++VIR_ENUM_DECL(virCgroupBackend); ++VIR_ENUM_IMPL(virCgroupBackend, VIR_CGROUP_BACKEND_TYPE_LAST, ++ "cgroup V1"); ++ ++static virOnceControl virCgroupBackendOnce = VIR_ONCE_CONTROL_INITIALIZER; ++static virCgroupBackendPtr virCgroupBackends[VIR_CGROUP_BACKEND_TYPE_LAST] = { 0 }; ++ ++void ++virCgroupBackendRegister(virCgroupBackendPtr backend) ++{ ++ if (virCgroupBackends[backend->type]) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Cgroup backend '%s' already registered."), ++ virCgroupBackendTypeToString(backend->type)); ++ return; ++ } ++ ++ virCgroupBackends[backend->type] = backend; ++} ++ ++ ++static void ++virCgroupBackendOnceInit(void) ++{ ++} ++ ++ ++virCgroupBackendPtr * ++virCgroupBackendGetAll(void) ++{ ++ if (virOnce(&virCgroupBackendOnce, virCgroupBackendOnceInit) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("Failed to initialize cgroup backend.")); ++ return NULL; ++ } ++ return virCgroupBackends; ++} +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +new file mode 100644 +index 0000000000..db052485a8 +--- /dev/null ++++ b/src/util/vircgroupbackend.h +@@ -0,0 +1,46 @@ ++/* ++ * vircgroupbackend.h: methods for cgroups backend ++ * ++ * Copyright (C) 2018 Red Hat, Inc. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library. If not, see ++ * . ++ */ ++ ++#ifndef __VIR_CGROUP_BACKEND_H__ ++# define __VIR_CGROUP_BACKEND_H__ ++ ++# include "internal.h" ++ ++# include "vircgroup.h" ++ ++ ++typedef enum { ++ VIR_CGROUP_BACKEND_TYPE_V1 = 0, ++ VIR_CGROUP_BACKEND_TYPE_LAST, ++} virCgroupBackendType; ++ ++struct _virCgroupBackend { ++ virCgroupBackendType type; ++}; ++typedef struct _virCgroupBackend virCgroupBackend; ++typedef virCgroupBackend *virCgroupBackendPtr; ++ ++void ++virCgroupBackendRegister(virCgroupBackendPtr backend); ++ ++virCgroupBackendPtr * ++virCgroupBackendGetAll(void); ++ ++#endif /* __VIR_CGROUP_BACKEND_H__ */ +-- +2.22.0 + diff --git a/SOURCES/libvirt-util-json-define-cleanup-function-using-VIR_DEFINE_AUTOPTR_FUNC.patch b/SOURCES/libvirt-util-json-define-cleanup-function-using-VIR_DEFINE_AUTOPTR_FUNC.patch new file mode 100644 index 0000000..2b9884b --- /dev/null +++ b/SOURCES/libvirt-util-json-define-cleanup-function-using-VIR_DEFINE_AUTOPTR_FUNC.patch @@ -0,0 +1,69 @@ +From 25ceaef5ff5e392dace991db3e737dbdb50a6bba Mon Sep 17 00:00:00 2001 +Message-Id: <25ceaef5ff5e392dace991db3e737dbdb50a6bba@dist-git> +From: Sukrit Bhatnagar +Date: Fri, 21 Jun 2019 09:26:02 +0200 +Subject: [PATCH] util: json: define cleanup function using + VIR_DEFINE_AUTOPTR_FUNC +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Using the new VIR_DEFINE_AUTOPTR_FUNC macro defined in +src/util/viralloc.h, define a new wrapper around an existing +cleanup function which will be called when a variable declared +with VIR_AUTOPTR macro goes out of scope. Also, drop the redundant +viralloc.h include, since that has moved from the source module into the +header. + +When a variable of type virJSONValuePtr is declared using +VIR_AUTOPTR, the function virJSONValueFree will be run +automatically on it when it goes out of scope. + +Signed-off-by: Sukrit Bhatnagar +Reviewed-by: Erik Skultety +(cherry picked from commit b5b5cdd69ca1c954635f9f6dda05d6b15b01cc8a) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Signed-off-by: Jiri Denemark +Message-Id: <4dd72d7d93725d77a2bd89fbd890fe3d774f29d2.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/virjson.c | 1 - + src/util/virjson.h | 3 +++ + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/util/virjson.c b/src/util/virjson.c +index 0559d40b64..92f3994e92 100644 +--- a/src/util/virjson.c ++++ b/src/util/virjson.c +@@ -24,7 +24,6 @@ + #include + + #include "virjson.h" +-#include "viralloc.h" + #include "virerror.h" + #include "virlog.h" + #include "virstring.h" +diff --git a/src/util/virjson.h b/src/util/virjson.h +index e4a82bdbc8..75f7f17b44 100644 +--- a/src/util/virjson.h ++++ b/src/util/virjson.h +@@ -26,6 +26,7 @@ + + # include "internal.h" + # include "virbitmap.h" ++# include "viralloc.h" + + # include + +@@ -156,4 +157,6 @@ char *virJSONStringReformat(const char *jsonstr, bool pretty); + + virJSONValuePtr virJSONValueObjectDeflatten(virJSONValuePtr json); + ++VIR_DEFINE_AUTOPTR_FUNC(virJSONValue, virJSONValueFree) ++ + #endif /* __VIR_JSON_H_ */ +-- +2.22.0 + diff --git a/SOURCES/libvirt-util-moving-type-argument-to-avoid-issues-with-mount-syscall.patch b/SOURCES/libvirt-util-moving-type-argument-to-avoid-issues-with-mount-syscall.patch new file mode 100644 index 0000000..a70a5d7 --- /dev/null +++ b/SOURCES/libvirt-util-moving-type-argument-to-avoid-issues-with-mount-syscall.patch @@ -0,0 +1,43 @@ +From bb4d2abe30f8ad3de4f7f3201de897440cdd545c Mon Sep 17 00:00:00 2001 +Message-Id: +From: Julio Faracco +Date: Mon, 1 Jul 2019 17:05:46 +0200 +Subject: [PATCH] util: moving 'type' argument to avoid issues with mount() + syscall. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This commit fixes a mount call inside virgroup.c file. The NULL value +into 'type' argument is causing a valgrind issue. See commit 794b576c +for more details. The best approach to fix it is moving NULL to "none" +filesytem. + +Signed-off-by: Julio Faracco +(cherry picked from commit 4539301bc84ee65558a48c1c3c22aa04f458dbe0) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <006a95f4385f575718eee431fc905702cff3e848.1561993099.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 0a31947b0d..e810a3d81d 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -3962,7 +3962,7 @@ virCgroupBindMount(virCgroupPtr group, const char *oldroot, + goto cleanup; + } + +- if (mount(src, group->controllers[i].mountPoint, NULL, MS_BIND, ++ if (mount(src, group->controllers[i].mountPoint, "none", MS_BIND, + NULL) < 0) { + virReportSystemError(errno, + _("Failed to bind cgroup '%s' on '%s'"), +-- +2.22.0 + diff --git a/SOURCES/libvirt-util-netdevopenvswitch-use-VIR_AUTOFREE-instead-of-VIR_FREE-for-scalar-types.patch b/SOURCES/libvirt-util-netdevopenvswitch-use-VIR_AUTOFREE-instead-of-VIR_FREE-for-scalar-types.patch new file mode 100644 index 0000000..2d6c088 --- /dev/null +++ b/SOURCES/libvirt-util-netdevopenvswitch-use-VIR_AUTOFREE-instead-of-VIR_FREE-for-scalar-types.patch @@ -0,0 +1,98 @@ +From ca441a9e1e6d757cd1aa7dfb84c0e37cb1924b87 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Sukrit Bhatnagar +Date: Tue, 30 Jul 2019 15:30:47 +0200 +Subject: [PATCH] util: netdevopenvswitch: use VIR_AUTOFREE instead of VIR_FREE + for scalar types +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +By making use of GNU C's cleanup attribute handled by the +VIR_AUTOFREE macro for declaring scalar variables, majority +of the VIR_FREE calls can be dropped, which in turn leads to +getting rid of most of our cleanup sections. + +Signed-off-by: Sukrit Bhatnagar +Reviewed-by: Erik Skultety +(cherry picked from commit 2d9be4d8b4cfea2a85a8ebe21ffadf4b3101a09b) + +Prerequisite of: https://bugzilla.redhat.com/show_bug.cgi?id=1721434 + +Signed-off-by: Michal Privoznik +Message-Id: <56656242ad6da70744bfda6d0757125eea669751.1564493409.git.mprivozn@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/virnetdevopenvswitch.c | 18 ++++++------------ + 1 file changed, 6 insertions(+), 12 deletions(-) + +diff --git a/src/util/virnetdevopenvswitch.c b/src/util/virnetdevopenvswitch.c +index f86f698430..36c587efdb 100644 +--- a/src/util/virnetdevopenvswitch.c ++++ b/src/util/virnetdevopenvswitch.c +@@ -149,10 +149,10 @@ int virNetDevOpenvswitchAddPort(const char *brname, const char *ifname, + char macaddrstr[VIR_MAC_STRING_BUFLEN]; + char ifuuidstr[VIR_UUID_STRING_BUFLEN]; + char vmuuidstr[VIR_UUID_STRING_BUFLEN]; +- char *attachedmac_ex_id = NULL; +- char *ifaceid_ex_id = NULL; +- char *profile_ex_id = NULL; +- char *vmid_ex_id = NULL; ++ VIR_AUTOFREE(char *) attachedmac_ex_id = NULL; ++ VIR_AUTOFREE(char *) ifaceid_ex_id = NULL; ++ VIR_AUTOFREE(char *) profile_ex_id = NULL; ++ VIR_AUTOFREE(char *) vmid_ex_id = NULL; + + virMacAddrFormat(macaddr, macaddrstr); + virUUIDFormat(ovsport->interfaceID, ifuuidstr); +@@ -209,10 +209,6 @@ int virNetDevOpenvswitchAddPort(const char *brname, const char *ifname, + + ret = 0; + cleanup: +- VIR_FREE(attachedmac_ex_id); +- VIR_FREE(ifaceid_ex_id); +- VIR_FREE(vmid_ex_id); +- VIR_FREE(profile_ex_id); + virCommandFree(cmd); + return ret; + } +@@ -339,10 +335,10 @@ virNetDevOpenvswitchInterfaceStats(const char *ifname, + virDomainInterfaceStatsPtr stats) + { + virCommandPtr cmd = NULL; +- char *output; + char *tmp; + bool gotStats = false; + int ret = -1; ++ VIR_AUTOFREE(char *) output = NULL; + + /* Just ensure the interface exists in ovs */ + cmd = virCommandNew(OVSVSCTL); +@@ -399,7 +395,6 @@ virNetDevOpenvswitchInterfaceStats(const char *ifname, + ret = 0; + + cleanup: +- VIR_FREE(output); + virCommandFree(cmd); + return ret; + } +@@ -425,7 +420,7 @@ virNetDevOpenvswitchGetVhostuserIfname(const char *path, + size_t ntokens = 0; + int status; + int ret = -1; +- char *ovs_timeout = NULL; ++ VIR_AUTOFREE(char *) ovs_timeout = NULL; + + /* Openvswitch vhostuser path are hardcoded to + * //openvswitch/ +@@ -457,7 +452,6 @@ virNetDevOpenvswitchGetVhostuserIfname(const char *path, + cleanup: + virStringListFreeCount(tokens, ntokens); + virCommandFree(cmd); +- VIR_FREE(ovs_timeout); + return ret; + } + +-- +2.22.0 + diff --git a/SOURCES/libvirt-util-netdevopenvswitch-use-VIR_AUTOPTR-for-aggregate-types.patch b/SOURCES/libvirt-util-netdevopenvswitch-use-VIR_AUTOPTR-for-aggregate-types.patch new file mode 100644 index 0000000..2618401 --- /dev/null +++ b/SOURCES/libvirt-util-netdevopenvswitch-use-VIR_AUTOPTR-for-aggregate-types.patch @@ -0,0 +1,277 @@ +From d808105a19611b7561c7ab0e4b128fbabebc88e2 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Sukrit Bhatnagar +Date: Tue, 30 Jul 2019 15:30:49 +0200 +Subject: [PATCH] util: netdevopenvswitch: use VIR_AUTOPTR for aggregate types +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +By making use of GNU C's cleanup attribute handled by the +VIR_AUTOPTR macro for declaring aggregate pointer variables, +majority of the calls to *Free functions can be dropped, which +in turn leads to getting rid of most of our cleanup sections. + +Signed-off-by: Sukrit Bhatnagar +Reviewed-by: Erik Skultety +(cherry picked from commit 1077b46de6730eea76884b921bed1ece65be26ef) + +Prerequisite of: https://bugzilla.redhat.com/show_bug.cgi?id=1721434 + +Signed-off-by: Michal Privoznik +Message-Id: <1b5f75ad2258bb10ea75fe646271e9625d49f998.1564493409.git.mprivozn@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/virnetdevopenvswitch.c | 80 +++++++++++---------------------- + 1 file changed, 27 insertions(+), 53 deletions(-) + +diff --git a/src/util/virnetdevopenvswitch.c b/src/util/virnetdevopenvswitch.c +index 0dcd49d40f..2f5c7ac789 100644 +--- a/src/util/virnetdevopenvswitch.c ++++ b/src/util/virnetdevopenvswitch.c +@@ -144,11 +144,10 @@ int virNetDevOpenvswitchAddPort(const char *brname, const char *ifname, + virNetDevVPortProfilePtr ovsport, + virNetDevVlanPtr virtVlan) + { +- int ret = -1; +- virCommandPtr cmd = NULL; + char macaddrstr[VIR_MAC_STRING_BUFLEN]; + char ifuuidstr[VIR_UUID_STRING_BUFLEN]; + char vmuuidstr[VIR_UUID_STRING_BUFLEN]; ++ VIR_AUTOPTR(virCommand) cmd = NULL; + VIR_AUTOFREE(char *) attachedmac_ex_id = NULL; + VIR_AUTOFREE(char *) ifaceid_ex_id = NULL; + VIR_AUTOFREE(char *) profile_ex_id = NULL; +@@ -160,17 +159,17 @@ int virNetDevOpenvswitchAddPort(const char *brname, const char *ifname, + + if (virAsprintf(&attachedmac_ex_id, "external-ids:attached-mac=\"%s\"", + macaddrstr) < 0) +- goto cleanup; ++ return -1; + if (virAsprintf(&ifaceid_ex_id, "external-ids:iface-id=\"%s\"", + ifuuidstr) < 0) +- goto cleanup; ++ return -1; + if (virAsprintf(&vmid_ex_id, "external-ids:vm-id=\"%s\"", + vmuuidstr) < 0) +- goto cleanup; ++ return -1; + if (ovsport->profileID[0] != '\0') { + if (virAsprintf(&profile_ex_id, "external-ids:port-profile=\"%s\"", + ovsport->profileID) < 0) +- goto cleanup; ++ return -1; + } + + cmd = virCommandNew(OVSVSCTL); +@@ -179,7 +178,7 @@ int virNetDevOpenvswitchAddPort(const char *brname, const char *ifname, + ifname, "--", "add-port", brname, ifname, NULL); + + if (virNetDevOpenvswitchConstructVlans(cmd, virtVlan) < 0) +- goto cleanup; ++ return -1; + + if (ovsport->profileID[0] == '\0') { + virCommandAddArgList(cmd, +@@ -204,13 +203,10 @@ int virNetDevOpenvswitchAddPort(const char *brname, const char *ifname, + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to add port %s to OVS bridge %s"), + ifname, brname); +- goto cleanup; ++ return -1; + } + +- ret = 0; +- cleanup: +- virCommandFree(cmd); +- return ret; ++ return 0; + } + + /** +@@ -223,8 +219,7 @@ int virNetDevOpenvswitchAddPort(const char *brname, const char *ifname, + */ + int virNetDevOpenvswitchRemovePort(const char *brname ATTRIBUTE_UNUSED, const char *ifname) + { +- int ret = -1; +- virCommandPtr cmd = NULL; ++ VIR_AUTOPTR(virCommand) cmd = NULL; + + cmd = virCommandNew(OVSVSCTL); + virNetDevOpenvswitchAddTimeout(cmd); +@@ -233,13 +228,10 @@ int virNetDevOpenvswitchRemovePort(const char *brname ATTRIBUTE_UNUSED, const ch + if (virCommandRun(cmd, NULL) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to delete port %s from OVS"), ifname); +- goto cleanup; ++ return -1; + } + +- ret = 0; +- cleanup: +- virCommandFree(cmd); +- return ret; ++ return 0; + } + + /** +@@ -253,9 +245,8 @@ int virNetDevOpenvswitchRemovePort(const char *brname ATTRIBUTE_UNUSED, const ch + */ + int virNetDevOpenvswitchGetMigrateData(char **migrate, const char *ifname) + { +- virCommandPtr cmd = NULL; + size_t len; +- int ret = -1; ++ VIR_AUTOPTR(virCommand) cmd = NULL; + + cmd = virCommandNew(OVSVSCTL); + virNetDevOpenvswitchAddTimeout(cmd); +@@ -269,7 +260,7 @@ int virNetDevOpenvswitchGetMigrateData(char **migrate, const char *ifname) + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to run command to get OVS port data for " + "interface %s"), ifname); +- goto cleanup; ++ return -1; + } + + /* Wipeout the newline, if it exists */ +@@ -277,10 +268,7 @@ int virNetDevOpenvswitchGetMigrateData(char **migrate, const char *ifname) + if (len > 0) + (*migrate)[len - 1] = '\0'; + +- ret = 0; +- cleanup: +- virCommandFree(cmd); +- return ret; ++ return 0; + } + + /** +@@ -294,8 +282,7 @@ int virNetDevOpenvswitchGetMigrateData(char **migrate, const char *ifname) + */ + int virNetDevOpenvswitchSetMigrateData(char *migrate, const char *ifname) + { +- virCommandPtr cmd = NULL; +- int ret = -1; ++ VIR_AUTOPTR(virCommand) cmd = NULL; + + if (!migrate) { + VIR_DEBUG("No OVS port data for interface %s", ifname); +@@ -312,13 +299,10 @@ int virNetDevOpenvswitchSetMigrateData(char *migrate, const char *ifname) + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to run command to set OVS port data for " + "interface %s"), ifname); +- goto cleanup; ++ return -1; + } + +- ret = 0; +- cleanup: +- virCommandFree(cmd); +- return ret; ++ return 0; + } + + /** +@@ -334,10 +318,9 @@ int + virNetDevOpenvswitchInterfaceStats(const char *ifname, + virDomainInterfaceStatsPtr stats) + { +- virCommandPtr cmd = NULL; + char *tmp; + bool gotStats = false; +- int ret = -1; ++ VIR_AUTOPTR(virCommand) cmd = NULL; + VIR_AUTOFREE(char *) output = NULL; + + /* Just ensure the interface exists in ovs */ +@@ -350,7 +333,7 @@ virNetDevOpenvswitchInterfaceStats(const char *ifname, + /* no ovs-vsctl or interface 'ifname' doesn't exists in ovs */ + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Interface not found")); +- goto cleanup; ++ return -1; + } + + #define GET_STAT(name, member) \ +@@ -369,7 +352,7 @@ virNetDevOpenvswitchInterfaceStats(const char *ifname, + *tmp != '\n') { \ + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", \ + _("Fail to parse ovs-vsctl output")); \ +- goto cleanup; \ ++ return -1; \ + } \ + gotStats = true; \ + } \ +@@ -389,14 +372,10 @@ virNetDevOpenvswitchInterfaceStats(const char *ifname, + if (!gotStats) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Interface doesn't have any statistics")); +- goto cleanup; ++ return -1; + } + +- ret = 0; +- +- cleanup: +- virCommandFree(cmd); +- return ret; ++ return 0; + } + + /** +@@ -414,12 +393,12 @@ int + virNetDevOpenvswitchGetVhostuserIfname(const char *path, + char **ifname) + { +- virCommandPtr cmd = NULL; + char *tmpIfname = NULL; + char **tokens = NULL; + size_t ntokens = 0; + int status; + int ret = -1; ++ VIR_AUTOPTR(virCommand) cmd = NULL; + + /* Openvswitch vhostuser path are hardcoded to + * //openvswitch/ +@@ -450,7 +429,6 @@ virNetDevOpenvswitchGetVhostuserIfname(const char *path, + + cleanup: + virStringListFreeCount(tokens, ntokens); +- virCommandFree(cmd); + return ret; + } + +@@ -466,8 +444,7 @@ virNetDevOpenvswitchGetVhostuserIfname(const char *path, + int virNetDevOpenvswitchUpdateVlan(const char *ifname, + virNetDevVlanPtr virtVlan) + { +- int ret = -1; +- virCommandPtr cmd = NULL; ++ VIR_AUTOPTR(virCommand) cmd = NULL; + + cmd = virCommandNew(OVSVSCTL); + virNetDevOpenvswitchAddTimeout(cmd); +@@ -478,16 +455,13 @@ int virNetDevOpenvswitchUpdateVlan(const char *ifname, + "--", "--if-exists", "set", "Port", ifname, NULL); + + if (virNetDevOpenvswitchConstructVlans(cmd, virtVlan) < 0) +- goto cleanup; ++ return -1; + + if (virCommandRun(cmd, NULL) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to set vlan configuration on port %s"), ifname); +- goto cleanup; ++ return -1; + } + +- ret = 0; +- cleanup: +- virCommandFree(cmd); +- return ret; ++ return 0; + } +-- +2.22.0 + diff --git a/SOURCES/libvirt-util-skip-RDMA-detection-for-non-PCI-network-devices.patch b/SOURCES/libvirt-util-skip-RDMA-detection-for-non-PCI-network-devices.patch new file mode 100644 index 0000000..356bb43 --- /dev/null +++ b/SOURCES/libvirt-util-skip-RDMA-detection-for-non-PCI-network-devices.patch @@ -0,0 +1,51 @@ +From dce9613ddab9d780ce9aabeb9a084ffec307899c Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 20 May 2019 10:12:55 +0200 +Subject: [PATCH] util: skip RDMA detection for non-PCI network devices + +Only PCI devices have '/sys/class/net//device/resource' so we +need to skip this check for all other network devices. + +Without this patch and RDMA enabled libvirt will not detect any network +device that doesn't have the path above which includes 'lo', 'virbr', +'tun', etc. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1639258 + +Reviewed-by: Andrea Bolognani +Signed-off-by: Pavel Hrdina +(cherry picked from commit f38ef0fac0582ac0cbb749af9d3f8ba515a6084a) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1693299 + +Signed-off-by: Pavel Hrdina +Message-Id: <5d2c32fd3f2d7e3f9664d395c00cdfc942c738ce.1558339954.git.phrdina@redhat.com> +Reviewed-by: Andrea Bolognani +--- + src/util/virnetdev.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c +index b250af9e2c..9ca3ce69bc 100644 +--- a/src/util/virnetdev.c ++++ b/src/util/virnetdev.c +@@ -3016,8 +3016,14 @@ virNetDevRDMAFeature(const char *ifname, + + if (virAsprintf(ð_devpath, SYSFS_NET_DIR "%s/device/resource", ifname) < 0) + goto cleanup; +- if (!virFileExists(eth_devpath)) ++ ++ /* If /sys/class/net//device/resource doesn't exist it is not a PCI ++ * device and therefore it will not have RDMA. */ ++ if (!virFileExists(eth_devpath)) { ++ ret = 0; + goto cleanup; ++ } ++ + if (virFileReadAll(eth_devpath, RESOURCE_FILE_LEN, ð_res_buf) < 0) + goto cleanup; + +-- +2.22.0 + diff --git a/SOURCES/libvirt-util-string-Introduce-macro-for-automatic-string-lists.patch b/SOURCES/libvirt-util-string-Introduce-macro-for-automatic-string-lists.patch new file mode 100644 index 0000000..9c99563 --- /dev/null +++ b/SOURCES/libvirt-util-string-Introduce-macro-for-automatic-string-lists.patch @@ -0,0 +1,94 @@ +From b9490d128b1a65d4d1ca273ddd54c696fa62ad73 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Peter Krempa +Date: Fri, 21 Jun 2019 09:26:01 +0200 +Subject: [PATCH] util: string: Introduce macro for automatic string lists +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Similar to VIR_AUTOPTR, VIR_AUTOSTRINGLIST defines a list of strings +which will be freed if the pointer is leaving scope. + +Signed-off-by: Peter Krempa +Reviewed-by: Erik Skultety +(cherry picked from commit daefda165b28b399478137c75b5466f865c65be5) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Conflicts: + src/util/virstring.h + - different header file guard + - no AUTOPTR for string lists + +Signed-off-by: Jiri Denemark +Message-Id: <7f1e7edf9c9a096fde1a2adf37090f8190e99be2.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/libvirt_private.syms | 1 + + src/util/virstring.c | 10 ++++++++++ + src/util/virstring.h | 10 ++++++++++ + 3 files changed, 21 insertions(+) + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index a20e0593f0..06374deaae 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -2923,6 +2923,7 @@ virStringHasControlChars; + virStringIsEmpty; + virStringIsPrintable; + virStringListAdd; ++virStringListAutoFree; + virStringListFree; + virStringListFreeCount; + virStringListGetFirstWithPrefix; +diff --git a/src/util/virstring.c b/src/util/virstring.c +index 15f367af7c..0f13b6c664 100644 +--- a/src/util/virstring.c ++++ b/src/util/virstring.c +@@ -332,6 +332,16 @@ void virStringListFree(char **strings) + } + + ++void virStringListAutoFree(char ***strings) ++{ ++ if (!*strings) ++ return; ++ ++ virStringListFree(*strings); ++ *strings = NULL; ++} ++ ++ + /** + * virStringListFreeCount: + * @strings: array of strings to free +diff --git a/src/util/virstring.h b/src/util/virstring.h +index 607ae66e99..e68b9eec79 100644 +--- a/src/util/virstring.h ++++ b/src/util/virstring.h +@@ -53,6 +53,7 @@ int virStringListCopy(char ***dst, + const char **src); + + void virStringListFree(char **strings); ++void virStringListAutoFree(char ***strings); + void virStringListFreeCount(char **strings, + size_t count); + +@@ -309,4 +310,13 @@ int virStringParsePort(const char *str, + unsigned int *port) + ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; + ++/** ++ * VIR_AUTOSTRINGLIST: ++ * ++ * Declares a NULL-terminated list of strings which will be automatically freed ++ * when the pointer goes out of scope. ++ */ ++# define VIR_AUTOSTRINGLIST \ ++ __attribute__((cleanup(virStringListAutoFree))) char ** ++ + #endif /* __VIR_STRING_H__ */ +-- +2.22.0 + diff --git a/SOURCES/libvirt-util-suppress-unimportant-ovs-vsctl-errors-when-getting-interface-stats.patch b/SOURCES/libvirt-util-suppress-unimportant-ovs-vsctl-errors-when-getting-interface-stats.patch new file mode 100644 index 0000000..7f450bc --- /dev/null +++ b/SOURCES/libvirt-util-suppress-unimportant-ovs-vsctl-errors-when-getting-interface-stats.patch @@ -0,0 +1,55 @@ +From 53282d1e7f34724c6be7704ec56324c507894397 Mon Sep 17 00:00:00 2001 +Message-Id: <53282d1e7f34724c6be7704ec56324c507894397@dist-git> +From: Laine Stump +Date: Tue, 30 Jul 2019 15:30:50 +0200 +Subject: [PATCH] util: suppress unimportant ovs-vsctl errors when getting + interface stats +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit edaf13565 modified the stats retrieval for OVS interfaces to +not fail when one of the fields was unrecognized by the ovs-vsctl +command, but ovs-vsctl was still returning an error, and libvirt was +cluttering the logs with these inconsequential error messages. + +This patch modifies the GET_STAT macro to add "--if-exists" to the +ovs-vsctl command, which causes it to return an empty string (and exit +with success) if the requested statistic isn't in its database, thus +eliminating the ugly error messages from the log. + +Resolves: https://bugzilla.redhat.com/1683175 + +Signed-off-by: Laine Stump +(cherry picked from commit 3f7cba3f5ea1731b9028b89b671cbd7e7d5e0421) + +Prerequisite of: https://bugzilla.redhat.com/show_bug.cgi?id=1721434 + +Signed-off-by: Michal Privoznik +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/virnetdevopenvswitch.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/util/virnetdevopenvswitch.c b/src/util/virnetdevopenvswitch.c +index 2f5c7ac789..cb403aaf2e 100644 +--- a/src/util/virnetdevopenvswitch.c ++++ b/src/util/virnetdevopenvswitch.c +@@ -342,10 +342,10 @@ virNetDevOpenvswitchInterfaceStats(const char *ifname, + virCommandFree(cmd); \ + cmd = virCommandNew(OVSVSCTL); \ + virNetDevOpenvswitchAddTimeout(cmd); \ +- virCommandAddArgList(cmd, "get", "Interface", ifname, \ +- "statistics:" name, NULL); \ ++ virCommandAddArgList(cmd, "--if-exists", "get", "Interface", \ ++ ifname, "statistics:" name, NULL); \ + virCommandSetOutputBuffer(cmd, &output); \ +- if (virCommandRun(cmd, NULL) < 0) { \ ++ if (virCommandRun(cmd, NULL) < 0 || !output || !*output || *output == '\n') { \ + stats->member = -1; \ + } else { \ + if (virStrToLong_ll(output, &tmp, 10, &stats->member) < 0 || \ +-- +2.22.0 + diff --git a/SOURCES/libvirt-util-vircgroup-improve-controller-detection.patch b/SOURCES/libvirt-util-vircgroup-improve-controller-detection.patch new file mode 100644 index 0000000..ad2ca4c --- /dev/null +++ b/SOURCES/libvirt-util-vircgroup-improve-controller-detection.patch @@ -0,0 +1,117 @@ +From 8c784cd15bbac88334271f95d14a9770c1b2d864 Mon Sep 17 00:00:00 2001 +Message-Id: <8c784cd15bbac88334271f95d14a9770c1b2d864@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:08:17 +0200 +Subject: [PATCH] util: vircgroup: improve controller detection +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This affects only cgroups v2 where enabled controllers are not based on +available mount points but on the list provided in cgroup.controllers +file. However, moving it will fill in placement as well, so it needs +to be freed together with mount point if we don't need that controller. + +Before this patch we were assuming that all controllers available in +root cgroup where available in all other sub-cgroups which was wrong. + +In order to fix it we need to move the cgroup controllers detection +after cgroup placement was prepared in order to build correct path for +cgroup.controllers file. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Peter Krempa +(cherry picked from commit d3007c844d8aa0caa0328ab18275be375f597704) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 32 ++++++++++++++++---------------- + src/util/vircgroupv1.c | 1 + + src/util/vircgroupv2.c | 5 +++-- + 3 files changed, 20 insertions(+), 18 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 4f71a1d197..ff2a0b75b5 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -386,22 +386,6 @@ virCgroupDetect(virCgroupPtr group, + return -1; + } + +- for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) { +- if (group->backends[i]) { +- int rc = group->backends[i]->detectControllers(group, controllers, parent); +- if (rc < 0) +- return -1; +- controllersAvailable |= rc; +- } +- } +- +- /* Check that at least 1 controller is available */ +- if (controllersAvailable == 0) { +- virReportSystemError(ENXIO, "%s", +- _("At least one cgroup controller is required")); +- return -1; +- } +- + /* In some cases we can copy part of the placement info + * based on the parent cgroup... + */ +@@ -426,6 +410,22 @@ virCgroupDetect(virCgroupPtr group, + } + } + ++ for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) { ++ if (group->backends[i]) { ++ int rc = group->backends[i]->detectControllers(group, controllers, parent); ++ if (rc < 0) ++ return -1; ++ controllersAvailable |= rc; ++ } ++ } ++ ++ /* Check that at least 1 controller is available */ ++ if (controllersAvailable == 0) { ++ virReportSystemError(ENXIO, "%s", ++ _("At least one cgroup controller is required")); ++ return -1; ++ } ++ + return 0; + } + +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 784a963b79..5b218c7f78 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -463,6 +463,7 @@ virCgroupV1DetectControllers(virCgroupPtr group, + } + } + VIR_FREE(group->legacy[i].mountPoint); ++ VIR_FREE(group->legacy[i].placement); + } + } + } else { +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 60598712c8..10f8a9bbdf 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -249,8 +249,9 @@ virCgroupV2ParseControllersFile(virCgroupPtr group) + char **contList = NULL; + char **tmp; + +- if (virAsprintf(&contFile, "%s/cgroup.controllers", +- group->unified.mountPoint) < 0) ++ if (virAsprintf(&contFile, "%s%s/cgroup.controllers", ++ group->unified.mountPoint, ++ NULLSTR_EMPTY(group->unified.placement)) < 0) + return -1; + + rc = virFileReadAll(contFile, 1024 * 1024, &contStr); +-- +2.22.0 + diff --git a/SOURCES/libvirt-util-vircgroup-introduce-virCgroup-Get-Set-ValueRaw.patch b/SOURCES/libvirt-util-vircgroup-introduce-virCgroup-Get-Set-ValueRaw.patch new file mode 100644 index 0000000..de8b405 --- /dev/null +++ b/SOURCES/libvirt-util-vircgroup-introduce-virCgroup-Get-Set-ValueRaw.patch @@ -0,0 +1,161 @@ +From 7ff748b22516848e8432d56ffa25a20452569648 Mon Sep 17 00:00:00 2001 +Message-Id: <7ff748b22516848e8432d56ffa25a20452569648@dist-git> +From: Pavel Hrdina +Date: Tue, 2 Jul 2019 15:13:24 +0200 +Subject: [PATCH] util: vircgroup: introduce virCgroup(Get|Set)ValueRaw +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If we need to get a path of specific file and we need to check its +existence before we use it then we can reuse that path to get/set +values instead of calling the existing get/set value functions which +would be building the path again. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Ján Tomko +(cherry picked from commit 3f741f9ace878e8aa9f537992b877a1e059d53a9) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1658890 + +Signed-off-by: Pavel Hrdina +Message-Id: <176473826dad107b8880a33355b59dcefcb75e63.1562073117.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 74 +++++++++++++++++++++++++--------------- + src/util/vircgrouppriv.h | 6 ++++ + 2 files changed, 52 insertions(+), 28 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 3c99934b25..769e23a523 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -460,28 +460,22 @@ virCgroupGetBlockDevString(const char *path) + + + int +-virCgroupSetValueStr(virCgroupPtr group, +- int controller, +- const char *key, ++virCgroupSetValueRaw(const char *path, + const char *value) + { +- VIR_AUTOFREE(char *) keypath = NULL; +- char *tmp = NULL; ++ char *tmp; + +- if (virCgroupPathOfController(group, controller, key, &keypath) < 0) +- return -1; +- +- VIR_DEBUG("Set value '%s' to '%s'", keypath, value); +- if (virFileWriteStr(keypath, value, 0) < 0) { ++ VIR_DEBUG("Set value '%s' to '%s'", path, value); ++ if (virFileWriteStr(path, value, 0) < 0) { + if (errno == EINVAL && +- (tmp = strrchr(keypath, '/'))) { ++ (tmp = strrchr(path, '/'))) { + virReportSystemError(errno, + _("Invalid value '%s' for '%s'"), + value, tmp + 1); + return -1; + } + virReportSystemError(errno, +- _("Unable to write to '%s'"), keypath); ++ _("Unable to write to '%s'"), path); + return -1; + } + +@@ -489,6 +483,45 @@ virCgroupSetValueStr(virCgroupPtr group, + } + + ++int ++virCgroupGetValueRaw(const char *path, ++ char **value) ++{ ++ int rc; ++ ++ *value = NULL; ++ ++ VIR_DEBUG("Get value %s", path); ++ ++ if ((rc = virFileReadAll(path, 1024*1024, value)) < 0) { ++ virReportSystemError(errno, ++ _("Unable to read from '%s'"), path); ++ return -1; ++ } ++ ++ /* Terminated with '\n' has sometimes harmful effects to the caller */ ++ if (rc > 0 && (*value)[rc - 1] == '\n') ++ (*value)[rc - 1] = '\0'; ++ ++ return 0; ++} ++ ++ ++int ++virCgroupSetValueStr(virCgroupPtr group, ++ int controller, ++ const char *key, ++ const char *value) ++{ ++ VIR_AUTOFREE(char *) keypath = NULL; ++ ++ if (virCgroupPathOfController(group, controller, key, &keypath) < 0) ++ return -1; ++ ++ return virCgroupSetValueRaw(keypath, value); ++} ++ ++ + int + virCgroupGetValueStr(virCgroupPtr group, + int controller, +@@ -496,26 +529,11 @@ virCgroupGetValueStr(virCgroupPtr group, + char **value) + { + VIR_AUTOFREE(char *) keypath = NULL; +- int rc; +- +- *value = NULL; + + if (virCgroupPathOfController(group, controller, key, &keypath) < 0) + return -1; + +- VIR_DEBUG("Get value %s", keypath); +- +- if ((rc = virFileReadAll(keypath, 1024*1024, value)) < 0) { +- virReportSystemError(errno, +- _("Unable to read from '%s'"), keypath); +- return -1; +- } +- +- /* Terminated with '\n' has sometimes harmful effects to the caller */ +- if (rc > 0 && (*value)[rc - 1] == '\n') +- (*value)[rc - 1] = '\0'; +- +- return 0; ++ return virCgroupGetValueRaw(keypath, value); + } + + +diff --git a/src/util/vircgrouppriv.h b/src/util/vircgrouppriv.h +index 6067f5cdc8..bdb3d493b1 100644 +--- a/src/util/vircgrouppriv.h ++++ b/src/util/vircgrouppriv.h +@@ -62,6 +62,12 @@ struct _virCgroup { + virCgroupV2Controller unified; + }; + ++int virCgroupSetValueRaw(const char *path, ++ const char *value); ++ ++int virCgroupGetValueRaw(const char *path, ++ char **value); ++ + int virCgroupSetValueStr(virCgroupPtr group, + int controller, + const char *key, +-- +2.22.0 + diff --git a/SOURCES/libvirt-util-vircgroup-move-virCgroupGetValueStr-out-of-virCgroupGetValueForBlkDev.patch b/SOURCES/libvirt-util-vircgroup-move-virCgroupGetValueStr-out-of-virCgroupGetValueForBlkDev.patch new file mode 100644 index 0000000..6484836 --- /dev/null +++ b/SOURCES/libvirt-util-vircgroup-move-virCgroupGetValueStr-out-of-virCgroupGetValueForBlkDev.patch @@ -0,0 +1,323 @@ +From 10bd6c74aa383403fae5ef7f4aec98d28246d972 Mon Sep 17 00:00:00 2001 +Message-Id: <10bd6c74aa383403fae5ef7f4aec98d28246d972@dist-git> +From: Pavel Hrdina +Date: Tue, 2 Jul 2019 15:13:25 +0200 +Subject: [PATCH] util: vircgroup: move virCgroupGetValueStr out of + virCgroupGetValueForBlkDev +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If we need to get a path of specific file and we need to check its +existence before we use it then we can reuse that path to get value +for specific device. This way we will not build the path again in +virCgroupGetValueForBlkDev. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Ján Tomko +(cherry picked from commit c23829f18a9b104466af88eb909a3fd9660b9cbe) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1658890 + +Signed-off-by: Pavel Hrdina +Message-Id: <72fe6534d0e19e271bac2aeb35bac028e67cfac2.1562073117.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 8 +---- + src/util/vircgrouppriv.h | 6 ++-- + src/util/vircgroupv1.c | 70 ++++++++++++++++++++++++++-------------- + src/util/vircgroupv2.c | 65 +++++++++++++++++++++++-------------- + 4 files changed, 88 insertions(+), 61 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 769e23a523..37f6def08d 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -538,20 +538,14 @@ virCgroupGetValueStr(virCgroupPtr group, + + + int +-virCgroupGetValueForBlkDev(virCgroupPtr group, +- int controller, +- const char *key, ++virCgroupGetValueForBlkDev(const char *str, + const char *path, + char **value) + { + VIR_AUTOFREE(char *) prefix = NULL; +- VIR_AUTOFREE(char *) str = NULL; + char **lines = NULL; + int ret = -1; + +- if (virCgroupGetValueStr(group, controller, key, &str) < 0) +- goto error; +- + if (!(prefix = virCgroupGetBlockDevString(path))) + goto error; + +diff --git a/src/util/vircgrouppriv.h b/src/util/vircgrouppriv.h +index bdb3d493b1..aec38e2ac5 100644 +--- a/src/util/vircgrouppriv.h ++++ b/src/util/vircgrouppriv.h +@@ -102,10 +102,8 @@ int virCgroupPartitionEscape(char **path); + + char *virCgroupGetBlockDevString(const char *path); + +-int virCgroupGetValueForBlkDev(virCgroupPtr group, +- int controller, +- const char *key, +- const char *path, ++int virCgroupGetValueForBlkDev(const char *str, ++ const char *devPath, + char **value); + + int virCgroupNew(pid_t pid, +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 58bd20d636..e51db6ee1f 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -1181,12 +1181,16 @@ virCgroupV1GetBlkioDeviceWeight(virCgroupPtr group, + unsigned int *weight) + { + VIR_AUTOFREE(char *) str = NULL; ++ VIR_AUTOFREE(char *) value = NULL; + +- if (virCgroupGetValueForBlkDev(group, +- VIR_CGROUP_CONTROLLER_BLKIO, +- "blkio.weight_device", +- path, +- &str) < 0) ++ if (virCgroupGetValueStr(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "blkio.weight_device", ++ &value) < 0) { ++ return -1; ++ } ++ ++ if (virCgroupGetValueForBlkDev(value, path, &str) < 0) + return -1; + + if (!str) { +@@ -1229,12 +1233,16 @@ virCgroupV1GetBlkioDeviceReadIops(virCgroupPtr group, + unsigned int *riops) + { + VIR_AUTOFREE(char *) str = NULL; ++ VIR_AUTOFREE(char *) value = NULL; + +- if (virCgroupGetValueForBlkDev(group, +- VIR_CGROUP_CONTROLLER_BLKIO, +- "blkio.throttle.read_iops_device", +- path, +- &str) < 0) ++ if (virCgroupGetValueStr(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "blkio.throttle.read_iops_device", ++ &value) < 0) { ++ return -1; ++ } ++ ++ if (virCgroupGetValueForBlkDev(value, path, &str) < 0) + return -1; + + if (!str) { +@@ -1277,12 +1285,16 @@ virCgroupV1GetBlkioDeviceWriteIops(virCgroupPtr group, + unsigned int *wiops) + { + VIR_AUTOFREE(char *) str = NULL; ++ VIR_AUTOFREE(char *) value = NULL; + +- if (virCgroupGetValueForBlkDev(group, +- VIR_CGROUP_CONTROLLER_BLKIO, +- "blkio.throttle.write_iops_device", +- path, +- &str) < 0) ++ if (virCgroupGetValueStr(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "blkio.throttle.write_iops_device", ++ &value) < 0) { ++ return -1; ++ } ++ ++ if (virCgroupGetValueForBlkDev(value, path, &str) < 0) + return -1; + + if (!str) { +@@ -1325,12 +1337,16 @@ virCgroupV1GetBlkioDeviceReadBps(virCgroupPtr group, + unsigned long long *rbps) + { + VIR_AUTOFREE(char *) str = NULL; ++ VIR_AUTOFREE(char *) value = NULL; + +- if (virCgroupGetValueForBlkDev(group, +- VIR_CGROUP_CONTROLLER_BLKIO, +- "blkio.throttle.read_bps_device", +- path, +- &str) < 0) ++ if (virCgroupGetValueStr(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "blkio.throttle.read_bps_device", ++ &value) < 0) { ++ return -1; ++ } ++ ++ if (virCgroupGetValueForBlkDev(value, path, &str) < 0) + return -1; + + if (!str) { +@@ -1373,12 +1389,16 @@ virCgroupV1GetBlkioDeviceWriteBps(virCgroupPtr group, + unsigned long long *wbps) + { + VIR_AUTOFREE(char *) str = NULL; ++ VIR_AUTOFREE(char *) value = NULL; + +- if (virCgroupGetValueForBlkDev(group, +- VIR_CGROUP_CONTROLLER_BLKIO, +- "blkio.throttle.write_bps_device", +- path, +- &str) < 0) ++ if (virCgroupGetValueStr(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "blkio.throttle.write_bps_device", ++ &value) < 0) { ++ return -1; ++ } ++ ++ if (virCgroupGetValueForBlkDev(value, path, &str) < 0) + return -1; + + if (!str) { +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 749efa199b..e9bb331dd4 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -787,15 +787,18 @@ virCgroupV2GetBlkioDeviceWeight(virCgroupPtr group, + unsigned int *weight) + { + VIR_AUTOFREE(char *) str = NULL; ++ VIR_AUTOFREE(char *) value = NULL; + +- if (virCgroupGetValueForBlkDev(group, +- VIR_CGROUP_CONTROLLER_BLKIO, +- "io.weight", +- path, +- &str) < 0) { ++ if (virCgroupGetValueStr(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "io.weight", ++ &value) < 0) { + return -1; + } + ++ if (virCgroupGetValueForBlkDev(value, path, &str) < 0) ++ return -1; ++ + if (!str) { + *weight = 0; + } else if (virStrToLong_ui(str, NULL, 10, weight) < 0) { +@@ -841,17 +844,20 @@ virCgroupV2GetBlkioDeviceReadIops(virCgroupPtr group, + unsigned int *riops) + { + VIR_AUTOFREE(char *) str = NULL; ++ VIR_AUTOFREE(char *) value = NULL; + const char *name = "riops="; + char *tmp; + +- if (virCgroupGetValueForBlkDev(group, +- VIR_CGROUP_CONTROLLER_BLKIO, +- "io.max", +- path, +- &str) < 0) { ++ if (virCgroupGetValueStr(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "io.max", ++ &value) < 0) { + return -1; + } + ++ if (virCgroupGetValueForBlkDev(value, path, &str) < 0) ++ return -1; ++ + if (!str) { + *riops = 0; + } else { +@@ -909,17 +915,20 @@ virCgroupV2GetBlkioDeviceWriteIops(virCgroupPtr group, + unsigned int *wiops) + { + VIR_AUTOFREE(char *) str = NULL; ++ VIR_AUTOFREE(char *) value = NULL; + const char *name = "wiops="; + char *tmp; + +- if (virCgroupGetValueForBlkDev(group, +- VIR_CGROUP_CONTROLLER_BLKIO, +- "io.max", +- path, +- &str) < 0) { ++ if (virCgroupGetValueStr(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "io.max", ++ &value) < 0) { + return -1; + } + ++ if (virCgroupGetValueForBlkDev(value, path, &str) < 0) ++ return -1; ++ + if (!str) { + *wiops = 0; + } else { +@@ -977,17 +986,20 @@ virCgroupV2GetBlkioDeviceReadBps(virCgroupPtr group, + unsigned long long *rbps) + { + VIR_AUTOFREE(char *) str = NULL; ++ VIR_AUTOFREE(char *) value = NULL; + const char *name = "rbps="; + char *tmp; + +- if (virCgroupGetValueForBlkDev(group, +- VIR_CGROUP_CONTROLLER_BLKIO, +- "io.max", +- path, +- &str) < 0) { ++ if (virCgroupGetValueStr(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "io.max", ++ &value) < 0) { + return -1; + } + ++ if (virCgroupGetValueForBlkDev(value, path, &str) < 0) ++ return -1; ++ + if (!str) { + *rbps = 0; + } else { +@@ -1045,17 +1057,20 @@ virCgroupV2GetBlkioDeviceWriteBps(virCgroupPtr group, + unsigned long long *wbps) + { + VIR_AUTOFREE(char *) str = NULL; ++ VIR_AUTOFREE(char *) value = NULL; + const char *name = "wbps="; + char *tmp; + +- if (virCgroupGetValueForBlkDev(group, +- VIR_CGROUP_CONTROLLER_BLKIO, +- "io.max", +- path, +- &str) < 0) { ++ if (virCgroupGetValueStr(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "io.max", ++ &value) < 0) { + return -1; + } + ++ if (virCgroupGetValueForBlkDev(value, path, &str) < 0) ++ return -1; ++ + if (!str) { + *wbps = 0; + } else { +-- +2.22.0 + diff --git a/SOURCES/libvirt-util-vircgroup-pass-parent-cgroup-into-virCgroupDetectControllersCB.patch b/SOURCES/libvirt-util-vircgroup-pass-parent-cgroup-into-virCgroupDetectControllersCB.patch new file mode 100644 index 0000000..e184088 --- /dev/null +++ b/SOURCES/libvirt-util-vircgroup-pass-parent-cgroup-into-virCgroupDetectControllersCB.patch @@ -0,0 +1,105 @@ +From 6403a3028222b103d7ef8ecf89aabe92242667da Mon Sep 17 00:00:00 2001 +Message-Id: <6403a3028222b103d7ef8ecf89aabe92242667da@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:08:15 +0200 +Subject: [PATCH] util: vircgroup: pass parent cgroup into + virCgroupDetectControllersCB +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In cgroups v2 we don't have to detect available controllers every single +time if we are creating a new cgroup based on parent cgroup. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Ján Tomko +(cherry picked from commit 7bca1c9bdc85247446129f856e27c80a32819e17) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 2 +- + src/util/vircgroupbackend.h | 3 ++- + src/util/vircgroupv1.c | 3 ++- + src/util/vircgroupv2.c | 17 +++++++++++------ + 4 files changed, 16 insertions(+), 9 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 736b5043a8..4f71a1d197 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -388,7 +388,7 @@ virCgroupDetect(virCgroupPtr group, + + for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) { + if (group->backends[i]) { +- int rc = group->backends[i]->detectControllers(group, controllers); ++ int rc = group->backends[i]->detectControllers(group, controllers, parent); + if (rc < 0) + return -1; + controllersAvailable |= rc; +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index a825dc4be7..05af118ec1 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -96,7 +96,8 @@ typedef char * + + typedef int + (*virCgroupDetectControllersCB)(virCgroupPtr group, +- int controllers); ++ int controllers, ++ virCgroupPtr parent); + + typedef bool + (*virCgroupHasControllerCB)(virCgroupPtr cgroup, +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 7098dc5644..784a963b79 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -419,7 +419,8 @@ virCgroupV1StealPlacement(virCgroupPtr group) + + static int + virCgroupV1DetectControllers(virCgroupPtr group, +- int controllers) ++ int controllers, ++ virCgroupPtr parent ATTRIBUTE_UNUSED) + { + size_t i; + size_t j; +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 04638c4e50..60598712c8 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -284,16 +284,21 @@ virCgroupV2ParseControllersFile(virCgroupPtr group) + + static int + virCgroupV2DetectControllers(virCgroupPtr group, +- int controllers) ++ int controllers, ++ virCgroupPtr parent) + { + size_t i; + +- if (virCgroupV2ParseControllersFile(group) < 0) +- return -1; ++ if (parent) { ++ group->unified.controllers = parent->unified.controllers; ++ } else { ++ if (virCgroupV2ParseControllersFile(group) < 0) ++ return -1; + +- /* In cgroup v2 there is no cpuacct controller, the cpu.stat file always +- * exists with usage stats. */ +- group->unified.controllers |= 1 << VIR_CGROUP_CONTROLLER_CPUACCT; ++ /* In cgroup v2 there is no cpuacct controller, the cpu.stat file always ++ * exists with usage stats. */ ++ group->unified.controllers |= 1 << VIR_CGROUP_CONTROLLER_CPUACCT; ++ } + + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) + VIR_DEBUG("Controller '%s' present=%s", +-- +2.22.0 + diff --git a/SOURCES/libvirt-util-vircgroupv1-add-support-for-BFQ-blkio-files.patch b/SOURCES/libvirt-util-vircgroupv1-add-support-for-BFQ-blkio-files.patch new file mode 100644 index 0000000..894ba09 --- /dev/null +++ b/SOURCES/libvirt-util-vircgroupv1-add-support-for-BFQ-blkio-files.patch @@ -0,0 +1,202 @@ +From a6c731357b9c74e5cc298f04267312ad3bb635fa Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Tue, 2 Jul 2019 15:13:26 +0200 +Subject: [PATCH] util: vircgroupv1: add support for BFQ blkio files +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In kernel 4.12 there was introduced new BFQ scheduler and in kernel +5.0 the old CFQ scheduler was removed. This has an implication on +the cgroups file names. + +If the CFQ controller is enabled we use these two files: + + blkio.weight + blkio.weight_device + +The new BFQ controller expose only one file with different name: + + blkio.bfq.weight + +The reason is that BFQ controller doesn't support per-device weight. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Ján Tomko +(cherry picked from commit 035ebe9390a630964f391816f05c9cc7792212ad) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1658890 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv1.c | 114 ++++++++++++++++++++++++++++++++--------- + 1 file changed, 90 insertions(+), 24 deletions(-) + +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index e51db6ee1f..a7d6c92e4c 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -949,10 +949,33 @@ static int + virCgroupV1SetBlkioWeight(virCgroupPtr group, + unsigned int weight) + { +- return virCgroupSetValueU64(group, +- VIR_CGROUP_CONTROLLER_BLKIO, +- "blkio.weight", +- weight); ++ VIR_AUTOFREE(char *) path = NULL; ++ VIR_AUTOFREE(char *) value = NULL; ++ ++ if (virCgroupV1PathOfController(group, VIR_CGROUP_CONTROLLER_BLKIO, ++ "blkio.bfq.weight", &path) < 0) { ++ return -1; ++ } ++ ++ if (!virFileExists(path)) { ++ VIR_FREE(path); ++ ++ if (virCgroupV1PathOfController(group, VIR_CGROUP_CONTROLLER_BLKIO, ++ "blkio.weight", &path) < 0) { ++ return -1; ++ } ++ } ++ ++ if (!virFileExists(path)) { ++ virReportError(VIR_ERR_OPERATION_INVALID, "%s", ++ _("blkio device weight is valid only for bfq or cfq scheduler")); ++ return -1; ++ } ++ ++ if (virAsprintf(&value, "%u", weight) < 0) ++ return -1; ++ ++ return virCgroupSetValueRaw(path, value); + } + + +@@ -960,14 +983,40 @@ static int + virCgroupV1GetBlkioWeight(virCgroupPtr group, + unsigned int *weight) + { +- unsigned long long tmp; +- int ret; +- ret = virCgroupGetValueU64(group, +- VIR_CGROUP_CONTROLLER_BLKIO, +- "blkio.weight", &tmp); +- if (ret == 0) +- *weight = tmp; +- return ret; ++ VIR_AUTOFREE(char *) path = NULL; ++ VIR_AUTOFREE(char *) value = NULL; ++ ++ if (virCgroupV1PathOfController(group, VIR_CGROUP_CONTROLLER_BLKIO, ++ "blkio.bfq.weight", &path) < 0) { ++ return -1; ++ } ++ ++ if (!virFileExists(path)) { ++ VIR_FREE(path); ++ ++ if (virCgroupV1PathOfController(group, VIR_CGROUP_CONTROLLER_BLKIO, ++ "blkio.weight", &path) < 0) { ++ return -1; ++ } ++ } ++ ++ if (!virFileExists(path)) { ++ virReportError(VIR_ERR_OPERATION_INVALID, "%s", ++ _("blkio device weight is valid only for bfq or cfq scheduler")); ++ return -1; ++ } ++ ++ if (virCgroupGetValueRaw(path, &value) < 0) ++ return -1; ++ ++ if (virStrToLong_ui(value, NULL, 10, weight) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Unable to parse '%s' as an integer"), ++ value); ++ return -1; ++ } ++ ++ return 0; + } + + +@@ -1156,41 +1205,58 @@ virCgroupV1GetBlkioIoDeviceServiced(virCgroupPtr group, + + static int + virCgroupV1SetBlkioDeviceWeight(virCgroupPtr group, +- const char *path, ++ const char *devPath, + unsigned int weight) + { + VIR_AUTOFREE(char *) str = NULL; + VIR_AUTOFREE(char *) blkstr = NULL; ++ VIR_AUTOFREE(char *) path = NULL; + +- if (!(blkstr = virCgroupGetBlockDevString(path))) ++ if (!(blkstr = virCgroupGetBlockDevString(devPath))) + return -1; + + if (virAsprintf(&str, "%s%d", blkstr, weight) < 0) + return -1; + +- return virCgroupSetValueStr(group, +- VIR_CGROUP_CONTROLLER_BLKIO, +- "blkio.weight_device", +- str); ++ if (virCgroupV1PathOfController(group, VIR_CGROUP_CONTROLLER_BLKIO, ++ "blkio.weight_device", &path) < 0) { ++ return -1; ++ } ++ ++ if (!virFileExists(path)) { ++ virReportError(VIR_ERR_OPERATION_INVALID, "%s", ++ _("blkio device weight is valid only for cfq scheduler")); ++ return -1; ++ } ++ ++ return virCgroupSetValueRaw(path, str); + } + + + static int + virCgroupV1GetBlkioDeviceWeight(virCgroupPtr group, +- const char *path, ++ const char *devPath, + unsigned int *weight) + { + VIR_AUTOFREE(char *) str = NULL; + VIR_AUTOFREE(char *) value = NULL; ++ VIR_AUTOFREE(char *) path = NULL; + +- if (virCgroupGetValueStr(group, +- VIR_CGROUP_CONTROLLER_BLKIO, +- "blkio.weight_device", +- &value) < 0) { ++ if (virCgroupV1PathOfController(group, VIR_CGROUP_CONTROLLER_BLKIO, ++ "blkio.weight_device", &path) < 0) { + return -1; + } + +- if (virCgroupGetValueForBlkDev(value, path, &str) < 0) ++ if (!virFileExists(path)) { ++ virReportError(VIR_ERR_OPERATION_INVALID, "%s", ++ _("blkio device weight is valid only for cfq scheduler")); ++ return -1; ++ } ++ ++ if (virCgroupGetValueRaw(path, &value) < 0) ++ return -1; ++ ++ if (virCgroupGetValueForBlkDev(value, devPath, &str) < 0) + return -1; + + if (!str) { +-- +2.22.0 + diff --git a/SOURCES/libvirt-util-vircgroupv2-add-support-for-BFQ-files.patch b/SOURCES/libvirt-util-vircgroupv2-add-support-for-BFQ-files.patch new file mode 100644 index 0000000..9ece80d --- /dev/null +++ b/SOURCES/libvirt-util-vircgroupv2-add-support-for-BFQ-files.patch @@ -0,0 +1,211 @@ +From 785b8c27bef20182789d1715d0b3c1d3fe28a9f9 Mon Sep 17 00:00:00 2001 +Message-Id: <785b8c27bef20182789d1715d0b3c1d3fe28a9f9@dist-git> +From: Pavel Hrdina +Date: Tue, 2 Jul 2019 15:13:27 +0200 +Subject: [PATCH] util: vircgroupv2: add support for BFQ files +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In kernel 4.12 there was introduced new BFQ scheduler and in kernel +5.0 the old CFQ scheduler was removed. This has an implication on +the cgroups file names. + +If the CFQ controller is enabled we use one file: + + io.weight + +The new BFQ controller expose one file with different name: + + io.bfq.weight + +Except for different name they have different syntax. + +io.weight: + + default $val + major:minor $val + +io.bfq.weight: + + $val + +The difference is that BFQ doesn't support per-device weight. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Ján Tomko +(cherry picked from commit 7e8a1a6e21cee67f6fa5bd2126ec17f96e5857d6) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1658890 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 101 +++++++++++++++++++++++++++++++---------- + 1 file changed, 78 insertions(+), 23 deletions(-) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index e9bb331dd4..b4e90ed46d 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -591,15 +591,35 @@ static int + virCgroupV2SetBlkioWeight(virCgroupPtr group, + unsigned int weight) + { ++ VIR_AUTOFREE(char *) path = NULL; + VIR_AUTOFREE(char *) value = NULL; ++ const char *format = "%u"; + +- if (virAsprintf(&value, "default %u", weight) < 0) ++ if (virCgroupV2PathOfController(group, VIR_CGROUP_CONTROLLER_BLKIO, ++ "io.bfq.weight", &path) < 0) { ++ return -1; ++ } ++ ++ if (!virFileExists(path)) { ++ VIR_FREE(path); ++ format = "default %u"; ++ ++ if (virCgroupV2PathOfController(group, VIR_CGROUP_CONTROLLER_BLKIO, ++ "io.weight", &path) < 0) { ++ return -1; ++ } ++ } ++ ++ if (!virFileExists(path)) { ++ virReportError(VIR_ERR_OPERATION_INVALID, "%s", ++ _("blkio weight is valid only for bfq or cfq scheduler")); ++ return -1; ++ } ++ ++ if (virAsprintf(&value, format, weight) < 0) + return -1; + +- return virCgroupSetValueStr(group, +- VIR_CGROUP_CONTROLLER_BLKIO, +- "io.weight", +- value); ++ return virCgroupSetValueRaw(path, value); + } + + +@@ -607,20 +627,38 @@ static int + virCgroupV2GetBlkioWeight(virCgroupPtr group, + unsigned int *weight) + { ++ VIR_AUTOFREE(char *) path = NULL; + VIR_AUTOFREE(char *) value = NULL; + char *tmp; + +- if (virCgroupGetValueStr(group, VIR_CGROUP_CONTROLLER_BLKIO, +- "io.weight", &value) < 0) { ++ if (virCgroupV2PathOfController(group, VIR_CGROUP_CONTROLLER_BLKIO, ++ "io.bfq.weight", &path) < 0) { + return -1; + } + +- if (!(tmp = strstr(value, "default "))) { +- virReportError(VIR_ERR_INTERNAL_ERROR, "%s", +- _("Cannot find default io weight.")); ++ if (!virFileExists(path)) { ++ VIR_FREE(path); ++ ++ if (virCgroupV2PathOfController(group, VIR_CGROUP_CONTROLLER_BLKIO, ++ "io.weight", &path) < 0) { ++ return -1; ++ } ++ } ++ ++ if (!virFileExists(path)) { ++ virReportError(VIR_ERR_OPERATION_INVALID, "%s", ++ _("blkio weight is valid only for bfq or cfq scheduler")); + return -1; + } +- tmp += strlen("default "); ++ ++ if (virCgroupGetValueRaw(path, &value) < 0) ++ return -1; ++ ++ if ((tmp = strstr(value, "default "))) { ++ tmp += strlen("default "); ++ } else { ++ tmp = value; ++ } + + if (virStrToLong_ui(tmp, NULL, 10, weight) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, +@@ -762,41 +800,58 @@ virCgroupV2GetBlkioIoDeviceServiced(virCgroupPtr group, + + static int + virCgroupV2SetBlkioDeviceWeight(virCgroupPtr group, +- const char *path, ++ const char *devPath, + unsigned int weight) + { ++ VIR_AUTOFREE(char *) path = NULL; + VIR_AUTOFREE(char *) str = NULL; + VIR_AUTOFREE(char *) blkstr = NULL; + +- if (!(blkstr = virCgroupGetBlockDevString(path))) ++ if (!(blkstr = virCgroupGetBlockDevString(devPath))) + return -1; + + if (virAsprintf(&str, "%s%d", blkstr, weight) < 0) + return -1; + +- return virCgroupSetValueStr(group, +- VIR_CGROUP_CONTROLLER_BLKIO, +- "io.weight", +- str); ++ if (virCgroupV2PathOfController(group, VIR_CGROUP_CONTROLLER_BLKIO, ++ "io.weight", &path) < 0) { ++ return -1; ++ } ++ ++ if (!virFileExists(path)) { ++ virReportError(VIR_ERR_OPERATION_INVALID, "%s", ++ _("blkio device weight is valid only for cfq scheduler")); ++ return -1; ++ } ++ ++ return virCgroupSetValueRaw(path, str); + } + + + static int + virCgroupV2GetBlkioDeviceWeight(virCgroupPtr group, +- const char *path, ++ const char *devPath, + unsigned int *weight) + { ++ VIR_AUTOFREE(char *) path = NULL; + VIR_AUTOFREE(char *) str = NULL; + VIR_AUTOFREE(char *) value = NULL; + +- if (virCgroupGetValueStr(group, +- VIR_CGROUP_CONTROLLER_BLKIO, +- "io.weight", +- &value) < 0) { ++ if (virCgroupV2PathOfController(group, VIR_CGROUP_CONTROLLER_BLKIO, ++ "io.weight", &path) < 0) { + return -1; + } + +- if (virCgroupGetValueForBlkDev(value, path, &str) < 0) ++ if (!virFileExists(path)) { ++ virReportError(VIR_ERR_OPERATION_INVALID, "%s", ++ _("blkio device weight is valid only for cfq scheduler")); ++ return -1; ++ } ++ ++ if (virCgroupGetValueRaw(path, &value) < 0) ++ return -1; ++ ++ if (virCgroupGetValueForBlkDev(value, devPath, &str) < 0) + return -1; + + if (!str) { +-- +2.22.0 + diff --git a/SOURCES/libvirt-util-vircgroupv2-don-t-error-out-if-enabling-controller-fails.patch b/SOURCES/libvirt-util-vircgroupv2-don-t-error-out-if-enabling-controller-fails.patch new file mode 100644 index 0000000..d7545c6 --- /dev/null +++ b/SOURCES/libvirt-util-vircgroupv2-don-t-error-out-if-enabling-controller-fails.patch @@ -0,0 +1,64 @@ +From 02b2342b6b5e45e3f41cb145521f53118ba8430f Mon Sep 17 00:00:00 2001 +Message-Id: <02b2342b6b5e45e3f41cb145521f53118ba8430f@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:08:21 +0200 +Subject: [PATCH] util: vircgroupv2: don't error out if enabling controller + fails +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Currently CPU controller cannot be enabled if there is any real-time +task running and is assigned to non-root cgroup which is the case on +several distributions with graphical environment. + +Instead of erroring out treat it as the controller is not available. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Peter Krempa +(cherry picked from commit 1d49cdcd116186e079db5668893da17f56141652) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <4a10dec59ca8cf5a2f81acf70d43f48b0a3bfd82.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index a67d5cfe04..e1ab1849ba 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -437,6 +437,8 @@ virCgroupV2MakeGroup(virCgroupPtr parent ATTRIBUTE_UNUSED, + } else { + size_t i; + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { ++ int rc; ++ + if (!virCgroupV2HasController(parent, i)) + continue; + +@@ -444,8 +446,17 @@ virCgroupV2MakeGroup(virCgroupPtr parent ATTRIBUTE_UNUSED, + if (i == VIR_CGROUP_CONTROLLER_CPUACCT) + continue; + +- if (virCgroupV2EnableController(parent, i, true) < 0) ++ rc = virCgroupV2EnableController(parent, i, false); ++ if (rc < 0) { ++ if (rc == -2) { ++ virResetLastError(); ++ VIR_DEBUG("failed to enable '%s' controller, skipping", ++ virCgroupV2ControllerTypeToString(i)); ++ group->unified.controllers &= ~(1 << i); ++ continue; ++ } + return -1; ++ } + } + } + } +-- +2.22.0 + diff --git a/SOURCES/libvirt-util-vircgroupv2-enable-CPU-controller-only-if-it-s-available.patch b/SOURCES/libvirt-util-vircgroupv2-enable-CPU-controller-only-if-it-s-available.patch new file mode 100644 index 0000000..e8f69c6 --- /dev/null +++ b/SOURCES/libvirt-util-vircgroupv2-enable-CPU-controller-only-if-it-s-available.patch @@ -0,0 +1,44 @@ +From aa699de198c52868d08679176dd8355deb24ef82 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:08:19 +0200 +Subject: [PATCH] util: vircgroupv2: enable CPU controller only if it's + available +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +It might happen that we are not able to enable CPU controller so we +can enable it for thread sub-cgroups only if it's available in parent +cgroup. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Ján Tomko +(cherry picked from commit f9d1c08557ddb981a0d889200431185a9c4920e0) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <2a13e05dfbbe52f05541c881964ce92709e5d36a.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 04cbadd6a6..98d313bf82 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -403,7 +403,8 @@ virCgroupV2MakeGroup(virCgroupPtr parent ATTRIBUTE_UNUSED, + return -1; + } + +- if (virCgroupV2EnableController(parent, ++ if (virCgroupV2HasController(parent, VIR_CGROUP_CONTROLLER_CPU) && ++ virCgroupV2EnableController(parent, + VIR_CGROUP_CONTROLLER_CPU) < 0) { + return -1; + } +-- +2.22.0 + diff --git a/SOURCES/libvirt-util-vircgroupv2-mark-only-requested-controllers-as-available.patch b/SOURCES/libvirt-util-vircgroupv2-mark-only-requested-controllers-as-available.patch new file mode 100644 index 0000000..e055eca --- /dev/null +++ b/SOURCES/libvirt-util-vircgroupv2-mark-only-requested-controllers-as-available.patch @@ -0,0 +1,53 @@ +From 54d26cd3d6839c67970d19559aaa13294c55f9a0 Mon Sep 17 00:00:00 2001 +Message-Id: <54d26cd3d6839c67970d19559aaa13294c55f9a0@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:08:22 +0200 +Subject: [PATCH] util: vircgroupv2: mark only requested controllers as + available +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When detecting available controllers on host we can be limited by list +of controllers from qemu.conf file. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Peter Krempa +(cherry picked from commit 05807e5d42f23832ab7dab17fb7e51b48b0a7c7b) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <40e05984144af026205a123c5b0f9cb841dcec67.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index e1ab1849ba..bdeab397a3 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -301,15 +301,15 @@ virCgroupV2DetectControllers(virCgroupPtr group, + group->unified.controllers |= 1 << VIR_CGROUP_CONTROLLER_CPUACCT; + } + ++ if (controllers >= 0) ++ group->unified.controllers &= controllers; ++ + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) + VIR_DEBUG("Controller '%s' present=%s", + virCgroupV2ControllerTypeToString(i), + (group->unified.controllers & 1 << i) ? "yes" : "no"); + +- if (controllers >= 0) +- return controllers & group->unified.controllers; +- else +- return group->unified.controllers; ++ return group->unified.controllers; + } + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-util-vircgroupv2-separate-return-values-of-virCgroupV2EnableController.patch b/SOURCES/libvirt-util-vircgroupv2-separate-return-values-of-virCgroupV2EnableController.patch new file mode 100644 index 0000000..fad981f --- /dev/null +++ b/SOURCES/libvirt-util-vircgroupv2-separate-return-values-of-virCgroupV2EnableController.patch @@ -0,0 +1,104 @@ +From 3980cde103a2804abc62a2eb3bcea39cccf20286 Mon Sep 17 00:00:00 2001 +Message-Id: <3980cde103a2804abc62a2eb3bcea39cccf20286@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:08:20 +0200 +Subject: [PATCH] util: vircgroupv2: separate return values of + virCgroupV2EnableController +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In order to skip controllers that we are not able to activate we need +to return different return value so the caller can decide what to do. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Peter Krempa +(cherry picked from commit 29a94a3fefeea0fb29b0b9f485c83c49b5bdae71) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 32 ++++++++++++++++++++++++++------ + 1 file changed, 26 insertions(+), 6 deletions(-) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 98d313bf82..a67d5cfe04 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -352,22 +352,40 @@ virCgroupV2PathOfController(virCgroupPtr group, + } + + ++/** ++ * virCgroupV2EnableController: ++ * ++ * Returns: -1 on fatal error ++ * -2 if we failed to write into cgroup.subtree_control ++ * 0 on success ++ */ + static int + virCgroupV2EnableController(virCgroupPtr parent, +- int controller) ++ int controller, ++ bool report) + { + VIR_AUTOFREE(char *) val = NULL; ++ VIR_AUTOFREE(char *) path = NULL; + + if (virAsprintf(&val, "+%s", + virCgroupV2ControllerTypeToString(controller)) < 0) { + return -1; + } + +- if (virCgroupSetValueStr(parent, controller, +- "cgroup.subtree_control", val) < 0) { ++ if (virCgroupPathOfController(parent, controller, ++ "cgroup.subtree_control", &path) < 0) { + return -1; + } + ++ if (virFileWriteStr(path, val, 0) < 0) { ++ if (report) { ++ virReportSystemError(errno, ++ _("Failed to enable controller '%s' for '%s'"), ++ val, path); ++ } ++ return -2; ++ } ++ + return 0; + } + +@@ -405,13 +423,15 @@ virCgroupV2MakeGroup(virCgroupPtr parent ATTRIBUTE_UNUSED, + + if (virCgroupV2HasController(parent, VIR_CGROUP_CONTROLLER_CPU) && + virCgroupV2EnableController(parent, +- VIR_CGROUP_CONTROLLER_CPU) < 0) { ++ VIR_CGROUP_CONTROLLER_CPU, ++ true) < 0) { + return -1; + } + + if (virCgroupV2HasController(parent, VIR_CGROUP_CONTROLLER_CPUSET) && + virCgroupV2EnableController(parent, +- VIR_CGROUP_CONTROLLER_CPUSET) < 0) { ++ VIR_CGROUP_CONTROLLER_CPUSET, ++ true) < 0) { + return -1; + } + } else { +@@ -424,7 +444,7 @@ virCgroupV2MakeGroup(virCgroupPtr parent ATTRIBUTE_UNUSED, + if (i == VIR_CGROUP_CONTROLLER_CPUACCT) + continue; + +- if (virCgroupV2EnableController(parent, i) < 0) ++ if (virCgroupV2EnableController(parent, i, true) < 0) + return -1; + } + } +-- +2.22.0 + diff --git a/SOURCES/libvirt-util-vircgroupv2-stop-enabling-missing-controllers-with-systemd.patch b/SOURCES/libvirt-util-vircgroupv2-stop-enabling-missing-controllers-with-systemd.patch new file mode 100644 index 0000000..f724143 --- /dev/null +++ b/SOURCES/libvirt-util-vircgroupv2-stop-enabling-missing-controllers-with-systemd.patch @@ -0,0 +1,80 @@ +From c06173bae3630cd1f953e69c4dd8df98904892a5 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:08:24 +0200 +Subject: [PATCH] util: vircgroupv2: stop enabling missing controllers with + systemd +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Because of a systemd delegation policy [1] we should not write to any +cgroups files owned by systemd which in case of cgroups v2 includes +'cgroups.subtree_control'. + +systemd will enable controllers automatically for us to have them +available for VM cgroups. + +[1] + +Signed-off-by: Pavel Hrdina +Reviewed-by: Ján Tomko +(cherry picked from commit 62dd4d25a2bc5ee33ed22728dc79a5da99906748) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <273d20b3ced7f8b3ea0cc761cff25601f03e318f.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 2 +- + src/util/vircgroupbackend.h | 3 +++ + src/util/vircgroupv2.c | 5 +++++ + 3 files changed, 9 insertions(+), 1 deletion(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index a7fb595bce..3c99934b25 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -1075,7 +1075,7 @@ virCgroupEnableMissingControllers(char *path, + &tmp) < 0) + goto cleanup; + +- if (virCgroupMakeGroup(parent, tmp, true, VIR_CGROUP_NONE) < 0) { ++ if (virCgroupMakeGroup(parent, tmp, true, VIR_CGROUP_SYSTEMD) < 0) { + virCgroupFree(&tmp); + goto cleanup; + } +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index a825dc4be7..2b5be21a76 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -35,6 +35,9 @@ typedef enum { + * attaching tasks + */ + VIR_CGROUP_THREAD = 1 << 1, /* cgroup v2 handles threads differently */ ++ VIR_CGROUP_SYSTEMD = 1 << 2, /* with systemd and cgroups v2 we cannot ++ * manually enable controllers that systemd ++ * doesn't know how to delegate */ + } virCgroupBackendFlags; + + typedef enum { +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index b0ed889cc8..749efa199b 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -394,6 +394,11 @@ virCgroupV2MakeGroup(virCgroupPtr parent ATTRIBUTE_UNUSED, + VIR_AUTOFREE(char *) path = NULL; + int controller; + ++ if (flags & VIR_CGROUP_SYSTEMD) { ++ VIR_DEBUG("Running with systemd so we should not create cgroups ourselves."); ++ return 0; ++ } ++ + VIR_DEBUG("Make group %s", group->path); + + controller = virCgroupV2GetAnyController(group); +-- +2.22.0 + diff --git a/SOURCES/libvirt-util-vircgroupv2-use-any-controller-to-create-thread-directory.patch b/SOURCES/libvirt-util-vircgroupv2-use-any-controller-to-create-thread-directory.patch new file mode 100644 index 0000000..40b3ee5 --- /dev/null +++ b/SOURCES/libvirt-util-vircgroupv2-use-any-controller-to-create-thread-directory.patch @@ -0,0 +1,42 @@ +From 281c86a0556bd04ad2b3d7264f36c109c646a692 Mon Sep 17 00:00:00 2001 +Message-Id: <281c86a0556bd04ad2b3d7264f36c109c646a692@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:08:18 +0200 +Subject: [PATCH] util: vircgroupv2: use any controller to create thread + directory +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The assumption that CPU controller would be always enabled is wrong, we +should use any available controller to create a new sub-cgroup. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Ján Tomko +(cherry picked from commit 535bdf83c0b0372e725650c56b4996ff83406254) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 10f8a9bbdf..04cbadd6a6 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -398,7 +398,7 @@ virCgroupV2MakeGroup(virCgroupPtr parent ATTRIBUTE_UNUSED, + + if (create) { + if (flags & VIR_CGROUP_THREAD) { +- if (virCgroupSetValueStr(group, VIR_CGROUP_CONTROLLER_CPU, ++ if (virCgroupSetValueStr(group, controller, + "cgroup.type", "threaded") < 0) { + return -1; + } +-- +2.22.0 + diff --git a/SOURCES/libvirt-util-virnetdevopenvswitch-Drop-an-unused-variable-ovs_timeout.patch b/SOURCES/libvirt-util-virnetdevopenvswitch-Drop-an-unused-variable-ovs_timeout.patch new file mode 100644 index 0000000..f5032da --- /dev/null +++ b/SOURCES/libvirt-util-virnetdevopenvswitch-Drop-an-unused-variable-ovs_timeout.patch @@ -0,0 +1,42 @@ +From bf73e16686f339b35637aa6fd401d0ed8d9e191a Mon Sep 17 00:00:00 2001 +Message-Id: +From: Erik Skultety +Date: Tue, 30 Jul 2019 15:30:48 +0200 +Subject: [PATCH] util: virnetdevopenvswitch: Drop an unused variable + @ovs_timeout +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Technically, it was never used ever since commit @f4d06ca8fd9 introduced +it, but the fact that we called VIR_FREE on it was enough for Clang to +never complain about it. + +Signed-off-by: Erik Skultety +Reviewed-by: Ján Tomko +(cherry picked from commit cc4d44ab31ffb2500cf52081e87b137385ec76e6) + +Prerequisite of: https://bugzilla.redhat.com/show_bug.cgi?id=1721434 + +Signed-off-by: Michal Privoznik +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/virnetdevopenvswitch.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/src/util/virnetdevopenvswitch.c b/src/util/virnetdevopenvswitch.c +index 36c587efdb..0dcd49d40f 100644 +--- a/src/util/virnetdevopenvswitch.c ++++ b/src/util/virnetdevopenvswitch.c +@@ -420,7 +420,6 @@ virNetDevOpenvswitchGetVhostuserIfname(const char *path, + size_t ntokens = 0; + int status; + int ret = -1; +- VIR_AUTOFREE(char *) ovs_timeout = NULL; + + /* Openvswitch vhostuser path are hardcoded to + * //openvswitch/ +-- +2.22.0 + diff --git a/SOURCES/libvirt-virCommand-use-procfs-to-learn-opened-FDs.patch b/SOURCES/libvirt-virCommand-use-procfs-to-learn-opened-FDs.patch new file mode 100644 index 0000000..57a022d --- /dev/null +++ b/SOURCES/libvirt-virCommand-use-procfs-to-learn-opened-FDs.patch @@ -0,0 +1,145 @@ +From 53d2fa1d52ddc8d1d219a6882f84241a996ea752 Mon Sep 17 00:00:00 2001 +Message-Id: <53d2fa1d52ddc8d1d219a6882f84241a996ea752@dist-git> +From: Michal Privoznik +Date: Tue, 30 Jul 2019 15:30:54 +0200 +Subject: [PATCH] virCommand: use procfs to learn opened FDs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When spawning a child process, between fork() and exec() we close +all file descriptors and keep only those the caller wants us to +pass onto the child. The problem is how we do that. Currently, we +get the limit of opened files and then iterate through each one +of them and either close() it or make it survive exec(). This +approach is suboptimal (although, not that much in default +configurations where the limit is pretty low - 1024). We have +/proc where we can learn what FDs we hold open and thus we can +selectively close only those. + +Signed-off-by: Michal Privoznik +Reviewed-by: Ján Tomko +(cherry picked from commit 432faf259b696043ee5d7e8f657d855419a9a3fa) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1721434 + +Signed-off-by: Michal Privoznik +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircommand.c | 86 +++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 78 insertions(+), 8 deletions(-) + +diff --git a/src/util/vircommand.c b/src/util/vircommand.c +index 8ae9a952a3..2353a4a554 100644 +--- a/src/util/vircommand.c ++++ b/src/util/vircommand.c +@@ -491,27 +491,97 @@ virExecCommon(virCommandPtr cmd, gid_t *groups, int ngroups) + return ret; + } + ++# ifdef __linux__ ++/* On Linux, we can utilize procfs and read the table of opened ++ * FDs and selectively close only those FDs we don't want to pass ++ * onto child process (well, the one we will exec soon since this ++ * is called from the child). */ ++static int ++virCommandMassCloseGetFDsLinux(virCommandPtr cmd ATTRIBUTE_UNUSED, ++ virBitmapPtr fds) ++{ ++ DIR *dp = NULL; ++ struct dirent *entry; ++ const char *dirName = "/proc/self/fd"; ++ int rc; ++ int ret = -1; ++ ++ if (virDirOpen(&dp, dirName) < 0) ++ return -1; ++ ++ while ((rc = virDirRead(dp, &entry, dirName)) > 0) { ++ int fd; ++ ++ if (virStrToLong_i(entry->d_name, NULL, 10, &fd) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("unable to parse FD: %s"), ++ entry->d_name); ++ goto cleanup; ++ } ++ ++ if (virBitmapSetBit(fds, fd) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("unable to set FD as open: %d"), ++ fd); ++ goto cleanup; ++ } ++ } ++ ++ if (rc < 0) ++ goto cleanup; ++ ++ ret = 0; ++ cleanup: ++ VIR_DIR_CLOSE(dp); ++ return ret; ++} ++ ++# else /* !__linux__ */ ++ ++static int ++virCommandMassCloseGetFDsGeneric(virCommandPtr cmd ATTRIBUTE_UNUSED, ++ virBitmapPtr fds) ++{ ++ virBitmapSetAll(fds); ++ return 0; ++} ++# endif /* !__linux__ */ ++ + static int + virCommandMassClose(virCommandPtr cmd, + int childin, + int childout, + int childerr) + { ++ VIR_AUTOPTR(virBitmap) fds = NULL; + int openmax = sysconf(_SC_OPEN_MAX); +- int fd; +- int tmpfd; ++ int fd = -1; + +- if (openmax < 0) { +- virReportSystemError(errno, "%s", +- _("sysconf(_SC_OPEN_MAX) failed")); ++ /* In general, it is not safe to call malloc() between fork() and exec() ++ * because the child might have forked at the worst possible time, i.e. ++ * when another thread was in malloc() and thus held its lock. That is to ++ * say, POSIX does not mandate malloc() to be async-safe. Fortunately, ++ * glibc developers are aware of this and made malloc() async-safe. ++ * Therefore we can safely allocate memory here (and transitively call ++ * opendir/readdir) without a deadlock. */ ++ ++ if (!(fds = virBitmapNew(openmax))) + return -1; +- } + +- for (fd = 3; fd < openmax; fd++) { ++# ifdef __linux__ ++ if (virCommandMassCloseGetFDsLinux(cmd, fds) < 0) ++ return -1; ++# else ++ if (virCommandMassCloseGetFDsGeneric(cmd, fds) < 0) ++ return -1; ++# endif ++ ++ fd = virBitmapNextSetBit(fds, 2); ++ for (; fd >= 0; fd = virBitmapNextSetBit(fds, fd)) { + if (fd == childin || fd == childout || fd == childerr) + continue; + if (!virCommandFDIsSet(cmd, fd)) { +- tmpfd = fd; ++ int tmpfd = fd; + VIR_MASS_CLOSE(tmpfd); + } else if (virSetInherit(fd, true) < 0) { + virReportSystemError(errno, _("failed to preserve fd %d"), fd); +-- +2.22.0 + diff --git a/SOURCES/libvirt-virDomainObjListAddLocked-Produce-better-error-message-than-Duplicate-key.patch b/SOURCES/libvirt-virDomainObjListAddLocked-Produce-better-error-message-than-Duplicate-key.patch new file mode 100644 index 0000000..674e3b6 --- /dev/null +++ b/SOURCES/libvirt-virDomainObjListAddLocked-Produce-better-error-message-than-Duplicate-key.patch @@ -0,0 +1,123 @@ +From 874617d278b58554feee567b2e79d208aaef214c Mon Sep 17 00:00:00 2001 +Message-Id: <874617d278b58554feee567b2e79d208aaef214c@dist-git> +From: Michal Privoznik +Date: Tue, 6 Aug 2019 13:29:22 +0200 +Subject: [PATCH] virDomainObjListAddLocked: Produce better error message than + 'Duplicate key' +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If there are two concurrent threads, one of which is removing a +domain from the list and the other is trying to add it back they +may serialize in the following order: + +1) vm->removing is set and @vm is unlocked. +2) The tread that's trying to add the domain onto the list locks + the list and tries to find, if the domain already exists. +3) Our lookup functions say it doesn't, so the thread proceeds to + virHashAddEntry() which fails with 'Duplicate key' error. + +This is obviously not helpful error message at all. + +The problem lies in our lookup functions +(virDomainObjListFindByUUIDLocked() and +virDomainObjListFindByNameLocked()) which return NULL even if the +object is still on the list. They do this so that the object is +not mistakenly looked up by some driver. The fix consists of +moving 'removing' check one level up and thus allowing +virDomainObjListAddLocked() to produce meaningful error message. + +Signed-off-by: Michal Privoznik +Reviewed-by: Cole Robinson +(cherry picked from commit a5c71129bf2c12a827f1bc00149acd1c572ffe9c) + +Signed-off-by: Ján Tomko +RHEL-8.1.0: https://bugzilla.redhat.com/show_bug.cgi?id=1737790 +Message-Id: +Reviewed-by: Michal Privoznik +--- + src/conf/virdomainobjlist.c | 35 +++++++++++++++++++++-------------- + 1 file changed, 21 insertions(+), 14 deletions(-) + +diff --git a/src/conf/virdomainobjlist.c b/src/conf/virdomainobjlist.c +index e7c3e326ca..3b388e2ba2 100644 +--- a/src/conf/virdomainobjlist.c ++++ b/src/conf/virdomainobjlist.c +@@ -142,14 +142,9 @@ virDomainObjListFindByUUIDLocked(virDomainObjListPtr doms, + + virUUIDFormat(uuid, uuidstr); + obj = virHashLookup(doms->objs, uuidstr); +- virObjectRef(obj); + if (obj) { ++ virObjectRef(obj); + virObjectLock(obj); +- if (obj->removing) { +- virObjectUnlock(obj); +- virObjectUnref(obj); +- obj = NULL; +- } + } + return obj; + } +@@ -173,6 +168,12 @@ virDomainObjListFindByUUID(virDomainObjListPtr doms, + obj = virDomainObjListFindByUUIDLocked(doms, uuid); + virObjectRWUnlock(doms); + ++ if (obj && obj->removing) { ++ virObjectUnlock(obj); ++ virObjectUnref(obj); ++ obj = NULL; ++ } ++ + return obj; + } + +@@ -184,14 +185,9 @@ virDomainObjListFindByNameLocked(virDomainObjListPtr doms, + virDomainObjPtr obj; + + obj = virHashLookup(doms->objsName, name); +- virObjectRef(obj); + if (obj) { ++ virObjectRef(obj); + virObjectLock(obj); +- if (obj->removing) { +- virObjectUnlock(obj); +- virObjectUnref(obj); +- obj = NULL; +- } + } + return obj; + } +@@ -215,6 +211,12 @@ virDomainObjListFindByName(virDomainObjListPtr doms, + obj = virDomainObjListFindByNameLocked(doms, name); + virObjectRWUnlock(doms); + ++ if (obj && obj->removing) { ++ virObjectUnlock(obj); ++ virObjectUnref(obj); ++ obj = NULL; ++ } ++ + return obj; + } + +@@ -286,8 +288,13 @@ virDomainObjListAddLocked(virDomainObjListPtr doms, + + /* See if a VM with matching UUID already exists */ + if ((vm = virDomainObjListFindByUUIDLocked(doms, def->uuid))) { +- /* UUID matches, but if names don't match, refuse it */ +- if (STRNEQ(vm->def->name, def->name)) { ++ if (vm->removing) { ++ virReportError(VIR_ERR_OPERATION_FAILED, ++ _("domain '%s' is already being removed"), ++ vm->def->name); ++ goto error; ++ } else if (STRNEQ(vm->def->name, def->name)) { ++ /* UUID matches, but if names don't match, refuse it */ + virUUIDFormat(vm->def->uuid, uuidstr); + virReportError(VIR_ERR_OPERATION_FAILED, + _("domain '%s' is already defined with uuid %s"), +-- +2.22.1 + diff --git a/SOURCES/libvirt-virDomainObjListAddLocked-fix-double-free.patch b/SOURCES/libvirt-virDomainObjListAddLocked-fix-double-free.patch new file mode 100644 index 0000000..0f08e90 --- /dev/null +++ b/SOURCES/libvirt-virDomainObjListAddLocked-fix-double-free.patch @@ -0,0 +1,64 @@ +From ad3f8f1d128f726d1504079ec34b68f6db297d3a Mon Sep 17 00:00:00 2001 +Message-Id: +From: Marc Hartmayer +Date: Wed, 10 Jul 2019 11:49:45 +0200 +Subject: [PATCH] virDomainObjListAddLocked: fix double free +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If @vm has flagged as "to be removed" virDomainObjListFindByNameLocked +returns NULL (although the definition actually exists). Therefore, the +possibility exits that "virHashAddEntry" will raise the error +"Duplicate key" => virDomainObjListAddObjLocked fails => +virDomainObjEndAPI(&vm) is called and this leads to a freeing of @def +since @def is already assigned to vm->def. But actually this leads to +a double free since the common usage pattern is that the caller of +virDomainObjListAdd(Locked) is responsible for freeing @def in case of +an error. + +Let's fix this by setting vm->def to NULL in case of an error. + +Backtrace: + + ➤ bt + #0 virFree (ptrptr=0x7575757575757575) + #1 0x000003ffb5b25b3e in virDomainResourceDefFree + #2 0x000003ffb5b37c34 in virDomainDefFree + #3 0x000003ff9123f734 in qemuDomainDefineXMLFlags + #4 0x000003ff9123f7f4 in qemuDomainDefineXML + #5 0x000003ffb5cd2c84 in virDomainDefineXML + #6 0x000000011745aa82 in remoteDispatchDomainDefineXML + ... + +Reviewed-by: Bjoern Walk +Signed-off-by: Marc Hartmayer +(cherry picked from commit 7e760f61577e6c4adbb0b015f8f7ac1796570cdd) +Signed-off-by: Ján Tomko + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1728530 +Message-Id: +Reviewed-by: Andrea Bolognani +--- + src/conf/virdomainobjlist.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/conf/virdomainobjlist.c b/src/conf/virdomainobjlist.c +index 72064d7c66..e7c3e326ca 100644 +--- a/src/conf/virdomainobjlist.c ++++ b/src/conf/virdomainobjlist.c +@@ -329,8 +329,10 @@ virDomainObjListAddLocked(virDomainObjListPtr doms, + goto cleanup; + vm->def = def; + +- if (virDomainObjListAddObjLocked(doms, vm) < 0) ++ if (virDomainObjListAddObjLocked(doms, vm) < 0) { ++ vm->def = NULL; + goto error; ++ } + } + cleanup: + return vm; +-- +2.22.0 + diff --git a/SOURCES/libvirt-virNetDevOpenvswitchInterfaceStats-Optimize-for-speed.patch b/SOURCES/libvirt-virNetDevOpenvswitchInterfaceStats-Optimize-for-speed.patch new file mode 100644 index 0000000..5b105e6 --- /dev/null +++ b/SOURCES/libvirt-virNetDevOpenvswitchInterfaceStats-Optimize-for-speed.patch @@ -0,0 +1,175 @@ +From dbcd08b082f3e96cf09328041549c0f1dc4e1335 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Michal Privoznik +Date: Tue, 30 Jul 2019 15:30:51 +0200 +Subject: [PATCH] virNetDevOpenvswitchInterfaceStats: Optimize for speed +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We run 'ovs-vsctl' nine times (first to find if interface is +there and then eight times = for each stats member separately). +This is very inefficient. I've found a way to run it once and +with a bit of help from virJSON module we can parse out stats +we need. + +Signed-off-by: Michal Privoznik +Reviewed-by: Ján Tomko +(cherry picked from commit c297eab52599c91a4cb26b66dbdfe9d07c3142d3) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1721434 + +Signed-off-by: Michal Privoznik +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/virnetdevopenvswitch.c | 111 +++++++++++++++++++++----------- + 1 file changed, 74 insertions(+), 37 deletions(-) + +diff --git a/src/util/virnetdevopenvswitch.c b/src/util/virnetdevopenvswitch.c +index cb403aaf2e..dbd832053b 100644 +--- a/src/util/virnetdevopenvswitch.c ++++ b/src/util/virnetdevopenvswitch.c +@@ -35,6 +35,7 @@ + #include "virmacaddr.h" + #include "virstring.h" + #include "virlog.h" ++#include "virjson.h" + + #define VIR_FROM_THIS VIR_FROM_NONE + +@@ -318,58 +319,94 @@ int + virNetDevOpenvswitchInterfaceStats(const char *ifname, + virDomainInterfaceStatsPtr stats) + { +- char *tmp; +- bool gotStats = false; + VIR_AUTOPTR(virCommand) cmd = NULL; + VIR_AUTOFREE(char *) output = NULL; ++ VIR_AUTOPTR(virJSONValue) jsonStats = NULL; ++ virJSONValuePtr jsonMap = NULL; ++ size_t i; + +- /* Just ensure the interface exists in ovs */ + cmd = virCommandNew(OVSVSCTL); + virNetDevOpenvswitchAddTimeout(cmd); +- virCommandAddArgList(cmd, "get", "Interface", ifname, "name", NULL); ++ virCommandAddArgList(cmd, "--if-exists", "--format=list", "--data=json", ++ "--no-headings", "--columns=statistics", "list", ++ "Interface", ifname, NULL); + virCommandSetOutputBuffer(cmd, &output); + +- if (virCommandRun(cmd, NULL) < 0) { ++ /* The above command returns either: ++ * 1) empty string if @ifname doesn't exist, or ++ * 2) a JSON array, for instance: ++ * ["map",[["collisions",0],["rx_bytes",0],["rx_crc_err",0],["rx_dropped",0], ++ * ["rx_errors",0],["rx_frame_err",0],["rx_over_err",0],["rx_packets",0], ++ * ["tx_bytes",12406],["tx_dropped",0],["tx_errors",0],["tx_packets",173]]] ++ */ ++ ++ if (virCommandRun(cmd, NULL) < 0 || ++ STREQ_NULLABLE(output, "")) { + /* no ovs-vsctl or interface 'ifname' doesn't exists in ovs */ + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Interface not found")); + return -1; + } + +-#define GET_STAT(name, member) \ +- do { \ +- VIR_FREE(output); \ +- virCommandFree(cmd); \ +- cmd = virCommandNew(OVSVSCTL); \ +- virNetDevOpenvswitchAddTimeout(cmd); \ +- virCommandAddArgList(cmd, "--if-exists", "get", "Interface", \ +- ifname, "statistics:" name, NULL); \ +- virCommandSetOutputBuffer(cmd, &output); \ +- if (virCommandRun(cmd, NULL) < 0 || !output || !*output || *output == '\n') { \ +- stats->member = -1; \ +- } else { \ +- if (virStrToLong_ll(output, &tmp, 10, &stats->member) < 0 || \ +- *tmp != '\n') { \ +- virReportError(VIR_ERR_INTERNAL_ERROR, "%s", \ +- _("Fail to parse ovs-vsctl output")); \ +- return -1; \ +- } \ +- gotStats = true; \ +- } \ +- } while (0) ++ if (!(jsonStats = virJSONValueFromString(output)) || ++ !virJSONValueIsArray(jsonStats) || ++ !(jsonMap = virJSONValueArrayGet(jsonStats, 1))) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("Unable to parse ovs-vsctl output")); ++ return -1; ++ } + +- /* The TX/RX fields appear to be swapped here +- * because this is the host view. */ +- GET_STAT("rx_bytes", tx_bytes); +- GET_STAT("rx_packets", tx_packets); +- GET_STAT("rx_errors", tx_errs); +- GET_STAT("rx_dropped", tx_drop); +- GET_STAT("tx_bytes", rx_bytes); +- GET_STAT("tx_packets", rx_packets); +- GET_STAT("tx_errors", rx_errs); +- GET_STAT("tx_dropped", rx_drop); ++ stats->rx_bytes = stats->rx_packets = stats->rx_errs = stats->rx_drop = -1; ++ stats->tx_bytes = stats->tx_packets = stats->tx_errs = stats->tx_drop = -1; + +- if (!gotStats) { ++ for (i = 0; i < virJSONValueArraySize(jsonMap); i++) { ++ virJSONValuePtr item = virJSONValueArrayGet(jsonMap, i); ++ virJSONValuePtr jsonKey; ++ virJSONValuePtr jsonVal; ++ const char *key; ++ long long val; ++ ++ if (!item || ++ (!(jsonKey = virJSONValueArrayGet(item, 0))) || ++ (!(jsonVal = virJSONValueArrayGet(item, 1))) || ++ (!(key = virJSONValueGetString(jsonKey))) || ++ (virJSONValueGetNumberLong(jsonVal, &val) < 0)) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("Malformed ovs-vsctl output")); ++ return -1; ++ } ++ ++ /* The TX/RX fields appear to be swapped here ++ * because this is the host view. */ ++ if (STREQ(key, "rx_bytes")) { ++ stats->tx_bytes = val; ++ } else if (STREQ(key, "rx_packets")) { ++ stats->tx_packets = val; ++ } else if (STREQ(key, "rx_errors")) { ++ stats->tx_errs = val; ++ } else if (STREQ(key, "rx_dropped")) { ++ stats->tx_drop = val; ++ } else if (STREQ(key, "tx_bytes")) { ++ stats->rx_bytes = val; ++ } else if (STREQ(key, "tx_packets")) { ++ stats->rx_packets = val; ++ } else if (STREQ(key, "tx_errors")) { ++ stats->rx_errs = val; ++ } else if (STREQ(key, "tx_dropped")) { ++ stats->rx_drop = val; ++ } else { ++ VIR_DEBUG("Unused ovs-vsctl stat key=%s val=%lld", key, val); ++ } ++ } ++ ++ if (stats->rx_bytes == -1 && ++ stats->rx_packets == -1 && ++ stats->rx_errs == -1 && ++ stats->rx_drop == -1 && ++ stats->tx_bytes == -1 && ++ stats->tx_packets == -1 && ++ stats->tx_errs == -1 && ++ stats->tx_drop == -1) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Interface doesn't have any statistics")); + return -1; +-- +2.22.0 + diff --git a/SOURCES/libvirt-virWaitForDevices-Drop-confusing-part-of-comment.patch b/SOURCES/libvirt-virWaitForDevices-Drop-confusing-part-of-comment.patch new file mode 100644 index 0000000..40d598d --- /dev/null +++ b/SOURCES/libvirt-virWaitForDevices-Drop-confusing-part-of-comment.patch @@ -0,0 +1,41 @@ +From a72b338a9127075ea9ededcdc201dc87b65fe731 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Michal Privoznik +Date: Thu, 27 Jun 2019 15:55:36 +0200 +Subject: [PATCH] virWaitForDevices: Drop confusing part of comment +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +It's not true that there is a backup loop. There isn't. Drop this +part of the comment to not confuse anybody. + +Signed-off-by: Michal Privoznik +Reviewed-by: Ján Tomko +(cherry picked from commit 0cabcd98f1ef82588016a692afbe5a47a4a0b42e) + +https://bugzilla.redhat.com/show_bug.cgi?id=1710575 + +Signed-off-by: Michal Privoznik +Message-Id: <3faa00d11315ede9c72b32b1aa1f8797e1638dfe.1561643698.git.mprivozn@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/virutil.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/src/util/virutil.c b/src/util/virutil.c +index 88e17e2c0f..d37c1ac632 100644 +--- a/src/util/virutil.c ++++ b/src/util/virutil.c +@@ -1637,8 +1637,6 @@ void virWaitForDevices(void) + /* + * NOTE: we ignore errors here; this is just to make sure that any device + * nodes that are being created finish before we try to scan them. +- * If this fails for any reason, we still have the backup of polling for +- * 5 seconds for device nodes. + */ + ignore_value(virRun(settleprog, &exitstatus)); + } +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-Call-virCgroupRemove-inside-virCgroupMakeGroup.patch b/SOURCES/libvirt-vircgroup-Call-virCgroupRemove-inside-virCgroupMakeGroup.patch new file mode 100644 index 0000000..cebbe6b --- /dev/null +++ b/SOURCES/libvirt-vircgroup-Call-virCgroupRemove-inside-virCgroupMakeGroup.patch @@ -0,0 +1,106 @@ +From 9831bda48172881b14f3c473b625ce5ddbd04300 Mon Sep 17 00:00:00 2001 +Message-Id: <9831bda48172881b14f3c473b625ce5ddbd04300@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:08 +0200 +Subject: [PATCH] vircgroup: Call virCgroupRemove inside virCgroupMakeGroup +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This fixes virCgroupEnableMissingControllers where virCgroupRemove +was not called in case virCgroupMakeGroup failed. + +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit b013bdfd797489e6c254917da299842fe051d058) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <09accbd84f3da1d7c6682357cf6c9a720631a247.1561993099.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 8646a4a479..dde9ed21a2 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -1052,7 +1052,7 @@ virCgroupMakeGroup(virCgroupPtr parent, + } + + if (virCgroupPathOfController(group, i, "", &path) < 0) +- return -1; ++ goto error; + + /* As of Feb 2011, clang can't see that the above function + * call did not modify group. */ +@@ -1076,7 +1076,7 @@ virCgroupMakeGroup(virCgroupPtr parent, + virReportSystemError(errno, + _("Failed to create controller %s for group"), + virCgroupControllerTypeToString(i)); +- return -1; ++ goto error; + } + } + if (group->controllers[VIR_CGROUP_CONTROLLER_CPUSET].mountPoint != NULL && +@@ -1084,7 +1084,7 @@ virCgroupMakeGroup(virCgroupPtr parent, + STREQ(group->controllers[i].mountPoint, + group->controllers[VIR_CGROUP_CONTROLLER_CPUSET].mountPoint))) { + if (virCgroupCpuSetInherit(parent, group) < 0) +- return -1; ++ goto error; + } + /* + * Note that virCgroupSetMemoryUseHierarchy should always be +@@ -1096,13 +1096,17 @@ virCgroupMakeGroup(virCgroupPtr parent, + STREQ(group->controllers[i].mountPoint, + group->controllers[VIR_CGROUP_CONTROLLER_MEMORY].mountPoint))) { + if (virCgroupSetMemoryUseHierarchy(group) < 0) +- return -1; ++ goto error; + } + } + } + + VIR_DEBUG("Done making controllers for group"); + return 0; ++ ++ error: ++ virCgroupRemove(group); ++ return -1; + } + + +@@ -1316,10 +1320,8 @@ virCgroupNewPartition(const char *path, + if (virCgroupNew(-1, parentPath, NULL, controllers, &parent) < 0) + goto cleanup; + +- if (virCgroupMakeGroup(parent, *group, create, VIR_CGROUP_NONE) < 0) { +- virCgroupRemove(*group); ++ if (virCgroupMakeGroup(parent, *group, create, VIR_CGROUP_NONE) < 0) + goto cleanup; +- } + } + + ret = 0; +@@ -1389,7 +1391,6 @@ virCgroupNewDomainPartition(virCgroupPtr partition, + */ + if (virCgroupMakeGroup(partition, *group, create, + VIR_CGROUP_MEM_HIERACHY) < 0) { +- virCgroupRemove(*group); + virCgroupFree(group); + return -1; + } +@@ -1446,7 +1447,6 @@ virCgroupNewThread(virCgroupPtr domain, + return -1; + + if (virCgroupMakeGroup(domain, *group, create, VIR_CGROUP_NONE) < 0) { +- virCgroupRemove(*group); + virCgroupFree(group); + return -1; + } +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-Duplicate-string-before-modifying.patch b/SOURCES/libvirt-vircgroup-Duplicate-string-before-modifying.patch new file mode 100644 index 0000000..9e0a069 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-Duplicate-string-before-modifying.patch @@ -0,0 +1,75 @@ +From d0add5355b434df64c5f9fb28b9ab4bdd86f93f2 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:04 +0200 +Subject: [PATCH] vircgroup: Duplicate string before modifying +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The 'mntDir' is part of 'struct mntent' as a result of getmntent_r +therefore we should not mangle with it. + +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 4b2fb60777bdad70df2871dad1d0e604cda078c6) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index df38bb77e0..45b854e864 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -350,18 +350,22 @@ virCgroupCopyMounts(virCgroupPtr group, + + + static int +-virCgroupResolveMountLink(char *mntDir, ++virCgroupResolveMountLink(const char *mntDir, + const char *typeStr, + virCgroupControllerPtr controller) + { + VIR_AUTOFREE(char *) linkSrc = NULL; ++ VIR_AUTOFREE(char *) tmp = NULL; + char *dirName; + struct stat sb; + +- dirName = strrchr(mntDir, '/'); ++ if (VIR_STRDUP(tmp, mntDir) < 0) ++ return -1; ++ ++ dirName = strrchr(tmp, '/'); + if (!dirName) { + virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Missing '/' separator in cgroup mount '%s'"), mntDir); ++ _("Missing '/' separator in cgroup mount '%s'"), tmp); + return -1; + } + +@@ -369,14 +373,14 @@ virCgroupResolveMountLink(char *mntDir, + return 0; + + *dirName = '\0'; +- if (virAsprintf(&linkSrc, "%s/%s", mntDir, typeStr) < 0) ++ if (virAsprintf(&linkSrc, "%s/%s", tmp, typeStr) < 0) + return -1; + *dirName = '/'; + + if (lstat(linkSrc, &sb) < 0) { + if (errno == ENOENT) { + VIR_WARN("Controller %s co-mounted at %s is missing symlink at %s", +- typeStr, mntDir, linkSrc); ++ typeStr, tmp, linkSrc); + } else { + virReportSystemError(errno, _("Cannot stat %s"), linkSrc); + return -1; +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-Extract-controller-detection-into-function.patch b/SOURCES/libvirt-vircgroup-Extract-controller-detection-into-function.patch new file mode 100644 index 0000000..e6a7b90 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-Extract-controller-detection-into-function.patch @@ -0,0 +1,95 @@ +From 931ae6bf56044020c057716e1db59288beca2bc8 Mon Sep 17 00:00:00 2001 +Message-Id: <931ae6bf56044020c057716e1db59288beca2bc8@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:05 +0200 +Subject: [PATCH] vircgroup: Extract controller detection into function +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit bddf975c7615a30da0709b6c1509b43440d72393) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <484f007f9f43d727b829bb18fa4ad2f116a7fae1.1561993099.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 48 +++++++++++++++++++++++++++++--------------- + 1 file changed, 32 insertions(+), 16 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 45b854e864..6f27c50cbd 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -631,24 +631,11 @@ virCgroupDetectPlacement(virCgroupPtr group, + + + static int +-virCgroupDetect(virCgroupPtr group, +- pid_t pid, +- int controllers, +- const char *path, +- virCgroupPtr parent) ++virCgroupDetectControllers(virCgroupPtr group, ++ int controllers) + { + size_t i; + size_t j; +- VIR_DEBUG("group=%p controllers=%d path=%s parent=%p", +- group, controllers, path, parent); +- +- if (parent) { +- if (virCgroupCopyMounts(group, parent) < 0) +- return -1; +- } else { +- if (virCgroupDetectMounts(group) < 0) +- return -1; +- } + + if (controllers >= 0) { + VIR_DEBUG("Filtering controllers %d", controllers); +@@ -703,8 +690,37 @@ virCgroupDetect(virCgroupPtr group, + } + } + ++ return controllers; ++} ++ ++ ++static int ++virCgroupDetect(virCgroupPtr group, ++ pid_t pid, ++ int controllers, ++ const char *path, ++ virCgroupPtr parent) ++{ ++ size_t i; ++ int rc; ++ ++ VIR_DEBUG("group=%p controllers=%d path=%s parent=%p", ++ group, controllers, path, parent); ++ ++ if (parent) { ++ if (virCgroupCopyMounts(group, parent) < 0) ++ return -1; ++ } else { ++ if (virCgroupDetectMounts(group) < 0) ++ return -1; ++ } ++ ++ rc = virCgroupDetectControllers(group, controllers); ++ if (rc < 0) ++ return -1; ++ + /* Check that at least 1 controller is available */ +- if (!controllers) { ++ if (rc == 0) { + virReportSystemError(ENXIO, "%s", + _("At least one cgroup controller is required")); + return -1; +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-Extract-file-link-resolving-into-separate-function.patch b/SOURCES/libvirt-vircgroup-Extract-file-link-resolving-into-separate-function.patch new file mode 100644 index 0000000..65a6823 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-Extract-file-link-resolving-into-separate-function.patch @@ -0,0 +1,137 @@ +From d7a8cd2fdafd168eb1672e7ecde1700463792518 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:05:50 +0200 +Subject: [PATCH] vircgroup: Extract file link resolving into separate function +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 00a0085aa17677003e89cdafceb6a0260af43fb8) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <6d3c5594a53824ceac258a0f54162ec8af5aef37.1561993099.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 85 +++++++++++++++++++++++++------------------- + 1 file changed, 48 insertions(+), 37 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 5144b33d43..8ddedbfe7c 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -356,6 +356,51 @@ virCgroupCopyMounts(virCgroupPtr group, + } + + ++static int ++virCgroupResolveMountLink(char *mntDir, ++ const char *typeStr, ++ virCgroupControllerPtr controller) ++{ ++ VIR_AUTOFREE(char *) linkSrc = NULL; ++ char *dirName; ++ struct stat sb; ++ ++ dirName = strrchr(mntDir, '/'); ++ if (!dirName) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Missing '/' separator in cgroup mount '%s'"), mntDir); ++ return -1; ++ } ++ ++ if (!strchr(dirName + 1, ',')) ++ return 0; ++ ++ *dirName = '\0'; ++ if (virAsprintf(&linkSrc, "%s/%s", mntDir, typeStr) < 0) ++ return -1; ++ *dirName = '/'; ++ ++ if (lstat(linkSrc, &sb) < 0) { ++ if (errno == ENOENT) { ++ VIR_WARN("Controller %s co-mounted at %s is missing symlink at %s", ++ typeStr, mntDir, linkSrc); ++ } else { ++ virReportSystemError(errno, _("Cannot stat %s"), linkSrc); ++ return -1; ++ } ++ } else { ++ if (!S_ISLNK(sb.st_mode)) { ++ VIR_WARN("Expecting a symlink at %s for controller %s", ++ linkSrc, typeStr); ++ } else { ++ VIR_STEAL_PTR(controller->linkPoint, linkSrc); ++ } ++ } ++ ++ return 0; ++} ++ ++ + /* + * Process /proc/mounts figuring out what controllers are + * mounted and where +@@ -397,8 +442,6 @@ virCgroupDetectMountsFromFile(virCgroupPtr group, + } + + if (typelen == len && STREQLEN(typestr, tmp, len)) { +- struct stat sb; +- char *tmp2; + + /* Note that the lines in /proc/mounts have the same + * order than the mount operations, and that there may +@@ -412,44 +455,12 @@ virCgroupDetectMountsFromFile(virCgroupPtr group, + if (VIR_STRDUP(controller->mountPoint, entry.mnt_dir) < 0) + goto cleanup; + +- tmp2 = strrchr(entry.mnt_dir, '/'); +- if (!tmp2) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Missing '/' separator in cgroup mount '%s'"), +- entry.mnt_dir); +- goto cleanup; +- } +- + /* If it is a co-mount it has a filename like "cpu,cpuacct" + * and we must identify the symlink path */ +- if (checkLinks && strchr(tmp2 + 1, ',')) { +- VIR_AUTOFREE(char *) linksrc = NULL; +- +- *tmp2 = '\0'; +- if (virAsprintf(&linksrc, "%s/%s", +- entry.mnt_dir, typestr) < 0) ++ if (checkLinks && ++ virCgroupResolveMountLink(entry.mnt_dir, typestr, ++ controller) < 0) { + goto cleanup; +- *tmp2 = '/'; +- +- if (lstat(linksrc, &sb) < 0) { +- if (errno == ENOENT) { +- VIR_WARN("Controller %s co-mounted at %s is missing symlink at %s", +- typestr, entry.mnt_dir, linksrc); +- } else { +- virReportSystemError(errno, +- _("Cannot stat %s"), +- linksrc); +- goto cleanup; +- } +- } else { +- if (!S_ISLNK(sb.st_mode)) { +- VIR_WARN("Expecting a symlink at %s for controller %s", +- linksrc, typestr); +- } else { +- controller->linkPoint = linksrc; +- linksrc = NULL; +- } +- } + } + } + tmp = next; +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-Extract-mount-options-matching-into-function.patch b/SOURCES/libvirt-vircgroup-Extract-mount-options-matching-into-function.patch new file mode 100644 index 0000000..c513497 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-Extract-mount-options-matching-into-function.patch @@ -0,0 +1,127 @@ +From 75f8c320bb6a09f111db513c52c71bbb5b3b7b9f Mon Sep 17 00:00:00 2001 +Message-Id: <75f8c320bb6a09f111db513c52c71bbb5b3b7b9f@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:05:56 +0200 +Subject: [PATCH] vircgroup: Extract mount options matching into function +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 6d5b91f0f5527ed79b39f1f1a375a35869e75356) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <6c5aa678b08ceb1efd6d1bda2350a979ca59035b.1561993099.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 84 ++++++++++++++++++++++++++------------------ + 1 file changed, 49 insertions(+), 35 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 9032bcbb63..ec9994780a 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -399,6 +399,33 @@ virCgroupResolveMountLink(char *mntDir, + } + + ++static bool ++virCgroupMountOptsMatchController(const char *mntOpts, ++ const char *typeStr) ++{ ++ const char *tmp = mntOpts; ++ int typeLen = strlen(typeStr); ++ ++ while (tmp) { ++ const char *next = strchr(tmp, ','); ++ int len; ++ if (next) { ++ len = next - tmp; ++ next++; ++ } else { ++ len = strlen(tmp); ++ } ++ ++ if (typeLen == len && STREQLEN(typeStr, tmp, len)) ++ return true; ++ ++ tmp = next; ++ } ++ ++ return false; ++} ++ ++ + /* + * Process /proc/mounts figuring out what controllers are + * mounted and where +@@ -426,42 +453,29 @@ virCgroupDetectMountsFromFile(virCgroupPtr group, + + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { + const char *typestr = virCgroupControllerTypeToString(i); +- int typelen = strlen(typestr); +- char *tmp = entry.mnt_opts; +- virCgroupControllerPtr controller = &group->controllers[i]; +- while (tmp) { +- char *next = strchr(tmp, ','); +- int len; +- if (next) { +- len = next-tmp; +- next++; +- } else { +- len = strlen(tmp); ++ ++ if (virCgroupMountOptsMatchController(entry.mnt_opts, typestr)) { ++ /* Note that the lines in /proc/mounts have the same ++ * order than the mount operations, and that there may ++ * be duplicates due to bind mounts. This means ++ * that the same mount point may be processed more than ++ * once. We need to save the results of the last one, ++ * and we need to be careful to release the memory used ++ * by previous processing. */ ++ virCgroupControllerPtr controller = &group->controllers[i]; ++ ++ VIR_FREE(controller->mountPoint); ++ VIR_FREE(controller->linkPoint); ++ if (VIR_STRDUP(controller->mountPoint, entry.mnt_dir) < 0) ++ goto cleanup; ++ ++ /* If it is a co-mount it has a filename like "cpu,cpuacct" ++ * and we must identify the symlink path */ ++ if (checkLinks && ++ virCgroupResolveMountLink(entry.mnt_dir, typestr, ++ controller) < 0) { ++ goto cleanup; + } +- +- if (typelen == len && STREQLEN(typestr, tmp, len)) { +- +- /* Note that the lines in /proc/mounts have the same +- * order than the mount operations, and that there may +- * be duplicates due to bind mounts. This means +- * that the same mount point may be processed more than +- * once. We need to save the results of the last one, +- * and we need to be careful to release the memory used +- * by previous processing. */ +- VIR_FREE(controller->mountPoint); +- VIR_FREE(controller->linkPoint); +- if (VIR_STRDUP(controller->mountPoint, entry.mnt_dir) < 0) +- goto cleanup; +- +- /* If it is a co-mount it has a filename like "cpu,cpuacct" +- * and we must identify the symlink path */ +- if (checkLinks && +- virCgroupResolveMountLink(entry.mnt_dir, typestr, +- controller) < 0) { +- goto cleanup; +- } +- } +- tmp = next; + } + } + } +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-Extract-placement-validation-into-function.patch b/SOURCES/libvirt-vircgroup-Extract-placement-validation-into-function.patch new file mode 100644 index 0000000..8513ce4 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-Extract-placement-validation-into-function.patch @@ -0,0 +1,102 @@ +From 489202ad9fe2dd9e417335c7274ba522adfc490b Mon Sep 17 00:00:00 2001 +Message-Id: <489202ad9fe2dd9e417335c7274ba522adfc490b@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:06 +0200 +Subject: [PATCH] vircgroup: Extract placement validation into function +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 3ae7b99094dc72616f902289afc407df738c9ce9) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <5728512c8e969952c0502fb4119f2930ae4bc49c.1561993099.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 52 +++++++++++++++++++++++++++----------------- + 1 file changed, 32 insertions(+), 20 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 6f27c50cbd..2bc4febf23 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -630,6 +630,36 @@ virCgroupDetectPlacement(virCgroupPtr group, + } + + ++static int ++virCgroupValidatePlacement(virCgroupPtr group, ++ pid_t pid) ++{ ++ size_t i; ++ ++ for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { ++ if (!group->controllers[i].mountPoint) ++ continue; ++ ++ if (!group->controllers[i].placement) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Could not find placement for controller %s at %s"), ++ virCgroupControllerTypeToString(i), ++ group->controllers[i].placement); ++ return -1; ++ } ++ ++ VIR_DEBUG("Detected mount/mapping %zu:%s at %s in %s for pid %lld", ++ i, ++ virCgroupControllerTypeToString(i), ++ group->controllers[i].mountPoint, ++ group->controllers[i].placement, ++ (long long) pid); ++ } ++ ++ return 0; ++} ++ ++ + static int + virCgroupDetectControllers(virCgroupPtr group, + int controllers) +@@ -701,7 +731,6 @@ virCgroupDetect(virCgroupPtr group, + const char *path, + virCgroupPtr parent) + { +- size_t i; + int rc; + + VIR_DEBUG("group=%p controllers=%d path=%s parent=%p", +@@ -738,25 +767,8 @@ virCgroupDetect(virCgroupPtr group, + return -1; + + /* Check that for every mounted controller, we found our placement */ +- for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { +- if (!group->controllers[i].mountPoint) +- continue; +- +- if (!group->controllers[i].placement) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Could not find placement for controller %s at %s"), +- virCgroupControllerTypeToString(i), +- group->controllers[i].placement); +- return -1; +- } +- +- VIR_DEBUG("Detected mount/mapping %zu:%s at %s in %s for pid %lld", +- i, +- virCgroupControllerTypeToString(i), +- group->controllers[i].mountPoint, +- group->controllers[i].placement, +- (long long) pid); +- } ++ if (virCgroupValidatePlacement(group, pid) < 0) ++ return -1; + + return 0; + } +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-Introduce-standard-set-of-typedefs-and-use-them.patch b/SOURCES/libvirt-vircgroup-Introduce-standard-set-of-typedefs-and-use-them.patch new file mode 100644 index 0000000..d57c77a --- /dev/null +++ b/SOURCES/libvirt-vircgroup-Introduce-standard-set-of-typedefs-and-use-them.patch @@ -0,0 +1,72 @@ +From aeec7565df4f246c937f494c99a8d2d1ff03168d Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:05:49 +0200 +Subject: [PATCH] vircgroup: Introduce standard set of typedefs and use them +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit cd77242504c8f3ba8d4ff7d1a7d4234f0aa5ede3) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <7e482b4826c05db78d1136bfa6091ab5d3097f47.1561993099.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 2 +- + src/util/vircgroup.h | 3 ++- + src/util/vircgrouppriv.h | 4 +++- + 3 files changed, 6 insertions(+), 3 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 7602641713..5144b33d43 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -385,7 +385,7 @@ virCgroupDetectMountsFromFile(virCgroupPtr group, + const char *typestr = virCgroupControllerTypeToString(i); + int typelen = strlen(typestr); + char *tmp = entry.mnt_opts; +- struct _virCgroupController *controller = &group->controllers[i]; ++ virCgroupControllerPtr controller = &group->controllers[i]; + while (tmp) { + char *next = strchr(tmp, ','); + int len; +diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h +index cfa69b67cb..af93316197 100644 +--- a/src/util/vircgroup.h ++++ b/src/util/vircgroup.h +@@ -29,7 +29,8 @@ + # include "virbitmap.h" + + struct _virCgroup; +-typedef struct _virCgroup *virCgroupPtr; ++typedef struct _virCgroup virCgroup; ++typedef virCgroup *virCgroupPtr; + + enum { + VIR_CGROUP_CONTROLLER_CPU, +diff --git a/src/util/vircgrouppriv.h b/src/util/vircgrouppriv.h +index 71788639d6..1b47d3b858 100644 +--- a/src/util/vircgrouppriv.h ++++ b/src/util/vircgrouppriv.h +@@ -41,11 +41,13 @@ struct _virCgroupController { + char *linkPoint; + char *placement; + }; ++typedef struct _virCgroupController virCgroupController; ++typedef virCgroupController *virCgroupControllerPtr; + + struct _virCgroup { + char *path; + +- struct _virCgroupController controllers[VIR_CGROUP_CONTROLLER_LAST]; ++ virCgroupController controllers[VIR_CGROUP_CONTROLLER_LAST]; + }; + + int virCgroupDetectMountsFromFile(virCgroupPtr group, +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-Introduce-virCgroupEnableMissingControllers.patch b/SOURCES/libvirt-vircgroup-Introduce-virCgroupEnableMissingControllers.patch new file mode 100644 index 0000000..fa468a2 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-Introduce-virCgroupEnableMissingControllers.patch @@ -0,0 +1,185 @@ +From cef7b5074c5638c67828d44357809fae84354000 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:05:58 +0200 +Subject: [PATCH] vircgroup: Introduce virCgroupEnableMissingControllers +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit fc221c053ba3a0f5b9ce609936e010180bbda64f) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 127 ++++++++++++++++++++++++------------------- + 1 file changed, 70 insertions(+), 57 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 7888dab716..a2c971fbf4 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -1494,68 +1494,22 @@ virCgroupNewDetectMachine(const char *name, + } + + +-/* +- * Returns 0 on success, -1 on fatal error, -2 on systemd not available +- */ + static int +-virCgroupNewMachineSystemd(const char *name, +- const char *drivername, +- const unsigned char *uuid, +- const char *rootdir, +- pid_t pidleader, +- bool isContainer, +- size_t nnicindexes, +- int *nicindexes, +- const char *partition, +- int controllers, +- virCgroupPtr *group) ++virCgroupEnableMissingControllers(char *path, ++ pid_t pidleader, ++ int controllers, ++ virCgroupPtr *group) + { ++ virCgroupPtr parent = NULL; ++ char *offset = path; + int ret = -1; +- int rv; +- virCgroupPtr init, parent = NULL; +- VIR_AUTOFREE(char *) path = NULL; +- char *offset; +- +- VIR_DEBUG("Trying to setup machine '%s' via systemd", name); +- if ((rv = virSystemdCreateMachine(name, +- drivername, +- uuid, +- rootdir, +- pidleader, +- isContainer, +- nnicindexes, +- nicindexes, +- partition)) < 0) +- return rv; +- +- if (controllers != -1) +- controllers |= (1 << VIR_CGROUP_CONTROLLER_SYSTEMD); +- +- VIR_DEBUG("Detecting systemd placement"); +- if (virCgroupNewDetect(pidleader, +- controllers, +- &init) < 0) +- return -1; +- +- path = init->controllers[VIR_CGROUP_CONTROLLER_SYSTEMD].placement; +- init->controllers[VIR_CGROUP_CONTROLLER_SYSTEMD].placement = NULL; +- virCgroupFree(&init); +- +- if (!path || STREQ(path, "/") || path[0] != '/') { +- VIR_DEBUG("Systemd didn't setup its controller"); +- ret = -2; +- goto cleanup; +- } +- +- offset = path; + + if (virCgroupNew(pidleader, + "", + NULL, + controllers, + &parent) < 0) +- goto cleanup; +- ++ return ret; + + for (;;) { + virCgroupPtr tmp; +@@ -1585,6 +1539,68 @@ virCgroupNewMachineSystemd(const char *name, + } + } + ++ ret = 0; ++ cleanup: ++ virCgroupFree(&parent); ++ return ret; ++} ++ ++ ++/* ++ * Returns 0 on success, -1 on fatal error, -2 on systemd not available ++ */ ++static int ++virCgroupNewMachineSystemd(const char *name, ++ const char *drivername, ++ const unsigned char *uuid, ++ const char *rootdir, ++ pid_t pidleader, ++ bool isContainer, ++ size_t nnicindexes, ++ int *nicindexes, ++ const char *partition, ++ int controllers, ++ virCgroupPtr *group) ++{ ++ int rv; ++ virCgroupPtr init; ++ VIR_AUTOFREE(char *) path = NULL; ++ ++ VIR_DEBUG("Trying to setup machine '%s' via systemd", name); ++ if ((rv = virSystemdCreateMachine(name, ++ drivername, ++ uuid, ++ rootdir, ++ pidleader, ++ isContainer, ++ nnicindexes, ++ nicindexes, ++ partition)) < 0) ++ return rv; ++ ++ if (controllers != -1) ++ controllers |= (1 << VIR_CGROUP_CONTROLLER_SYSTEMD); ++ ++ VIR_DEBUG("Detecting systemd placement"); ++ if (virCgroupNewDetect(pidleader, ++ controllers, ++ &init) < 0) ++ return -1; ++ ++ path = init->controllers[VIR_CGROUP_CONTROLLER_SYSTEMD].placement; ++ init->controllers[VIR_CGROUP_CONTROLLER_SYSTEMD].placement = NULL; ++ virCgroupFree(&init); ++ ++ if (!path || STREQ(path, "/") || path[0] != '/') { ++ VIR_DEBUG("Systemd didn't setup its controller"); ++ return -2; ++ } ++ ++ if (virCgroupEnableMissingControllers(path, pidleader, ++ controllers, group) < 0) { ++ return -1; ++ } ++ + if (virCgroupAddTask(*group, pidleader) < 0) { + virErrorPtr saved = virSaveLastError(); + virCgroupRemove(*group); +@@ -1595,10 +1611,7 @@ virCgroupNewMachineSystemd(const char *name, + } + } + +- ret = 0; +- cleanup: +- virCgroupFree(&parent); +- return ret; ++ return 0; + } + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-Introduce-virCgroupGetMemoryStat.patch b/SOURCES/libvirt-vircgroup-Introduce-virCgroupGetMemoryStat.patch new file mode 100644 index 0000000..903d5ac --- /dev/null +++ b/SOURCES/libvirt-vircgroup-Introduce-virCgroupGetMemoryStat.patch @@ -0,0 +1,155 @@ +From d91df2c6090f79ef0135f2240181b8dbf87597b0 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:01 +0200 +Subject: [PATCH] vircgroup: Introduce virCgroupGetMemoryStat +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 901d2b9c8716f2717439d5843cab412ab8d7b247) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/libvirt_private.syms | 1 + + src/util/vircgroup.c | 88 ++++++++++++++++++++++++++++++++++++++++ + src/util/vircgroup.h | 7 ++++ + 3 files changed, 96 insertions(+) + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 47695eb507..2ec9d8f4bf 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -1551,6 +1551,7 @@ virCgroupGetDomainTotalCpuStats; + virCgroupGetFreezerState; + virCgroupGetMemoryHardLimit; + virCgroupGetMemorySoftLimit; ++virCgroupGetMemoryStat; + virCgroupGetMemoryUsage; + virCgroupGetMemSwapHardLimit; + virCgroupGetMemSwapUsage; +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index a94f958d75..0ed83932ac 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -2427,6 +2427,94 @@ virCgroupSetMemory(virCgroupPtr group, unsigned long long kb) + } + + ++/** ++ * virCgroupGetMemoryStat: ++ * ++ * @group: The cgroup to change memory for ++ * @cache: page cache memory in KiB ++ * @activeAnon: anonymous and swap cache memory in KiB ++ * @inactiveAnon: anonymous and swap cache memory in KiB ++ * @activeFile: file-backed memory in KiB ++ * @inactiveFile: file-backed memory in KiB ++ * @unevictable: memory that cannot be reclaimed KiB ++ * ++ * Returns: 0 on success, -1 on error ++ */ ++int ++virCgroupGetMemoryStat(virCgroupPtr group, ++ unsigned long long *cache, ++ unsigned long long *activeAnon, ++ unsigned long long *inactiveAnon, ++ unsigned long long *activeFile, ++ unsigned long long *inactiveFile, ++ unsigned long long *unevictable) ++{ ++ int ret = -1; ++ char *stat = NULL; ++ char *line = NULL; ++ unsigned long long cacheVal = 0; ++ unsigned long long activeAnonVal = 0; ++ unsigned long long inactiveAnonVal = 0; ++ unsigned long long activeFileVal = 0; ++ unsigned long long inactiveFileVal = 0; ++ unsigned long long unevictableVal = 0; ++ ++ if (virCgroupGetValueStr(group, ++ VIR_CGROUP_CONTROLLER_MEMORY, ++ "memory.stat", ++ &stat) < 0) { ++ return -1; ++ } ++ ++ line = stat; ++ ++ while (line) { ++ char *newLine = strchr(line, '\n'); ++ char *valueStr = strchr(line, ' '); ++ unsigned long long value; ++ ++ if (newLine) ++ *newLine = '\0'; ++ ++ if (!valueStr) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("Cannot parse 'memory.stat' cgroup file.")); ++ goto cleanup; ++ } ++ *valueStr = '\0'; ++ ++ if (virStrToLong_ull(valueStr + 1, NULL, 10, &value) < 0) ++ goto cleanup; ++ ++ if (STREQ(line, "cache")) ++ cacheVal = value >> 10; ++ else if (STREQ(line, "active_anon")) ++ activeAnonVal = value >> 10; ++ else if (STREQ(line, "inactive_anon")) ++ inactiveAnonVal = value >> 10; ++ else if (STREQ(line, "active_file")) ++ activeFileVal = value >> 10; ++ else if (STREQ(line, "inactive_file")) ++ inactiveFileVal = value >> 10; ++ else if (STREQ(line, "unevictable")) ++ unevictableVal = value >> 10; ++ } ++ ++ *cache = cacheVal; ++ *activeAnon = activeAnonVal; ++ *inactiveAnon = inactiveAnonVal; ++ *activeFile = activeFileVal; ++ *inactiveFile = inactiveFileVal; ++ *unevictable = unevictableVal; ++ ++ ret = 0; ++ ++ cleanup: ++ VIR_FREE(stat); ++ return ret; ++} ++ ++ + /** + * virCgroupGetMemoryUsage: + * +diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h +index 48be077aba..c7fdaaede4 100644 +--- a/src/util/vircgroup.h ++++ b/src/util/vircgroup.h +@@ -177,6 +177,13 @@ int virCgroupGetBlkioDeviceWriteBps(virCgroupPtr group, + unsigned long long *wbps); + + int virCgroupSetMemory(virCgroupPtr group, unsigned long long kb); ++int virCgroupGetMemoryStat(virCgroupPtr group, ++ unsigned long long *cache, ++ unsigned long long *activeAnon, ++ unsigned long long *inactiveAnon, ++ unsigned long long *activeFile, ++ unsigned long long *inactiveFile, ++ unsigned long long *unevictable); + int virCgroupGetMemoryUsage(virCgroupPtr group, unsigned long *kb); + + int virCgroupSetMemoryHardLimit(virCgroupPtr group, unsigned long long kb); +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-Move-function-used-in-tests-into-vircgrouppriv.h.patch b/SOURCES/libvirt-vircgroup-Move-function-used-in-tests-into-vircgrouppriv.h.patch new file mode 100644 index 0000000..73f8b2d --- /dev/null +++ b/SOURCES/libvirt-vircgroup-Move-function-used-in-tests-into-vircgrouppriv.h.patch @@ -0,0 +1,74 @@ +From 0a488720d9702ccedf9e37f639772f67e0180d33 Mon Sep 17 00:00:00 2001 +Message-Id: <0a488720d9702ccedf9e37f639772f67e0180d33@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:05:54 +0200 +Subject: [PATCH] vircgroup: Move function used in tests into vircgrouppriv.h +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 8ea2d5a6cbe9d14f30ffb8dbe0922945f0f490cb) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <2f8afe33e9c7db8173b360eeaac3ae2e2385eda5.1561993099.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.h | 13 ------------- + src/util/vircgrouppriv.h | 13 +++++++++++++ + 2 files changed, 13 insertions(+), 13 deletions(-) + +diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h +index 138bb3c076..48be077aba 100644 +--- a/src/util/vircgroup.h ++++ b/src/util/vircgroup.h +@@ -64,22 +64,9 @@ typedef enum { + + bool virCgroupAvailable(void); + +-int virCgroupNewPartition(const char *path, +- bool create, +- int controllers, +- virCgroupPtr *group) +- ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(4); +- + int virCgroupNewSelf(virCgroupPtr *group) + ATTRIBUTE_NONNULL(1); + +-int virCgroupNewDomainPartition(virCgroupPtr partition, +- const char *driver, +- const char *name, +- bool create, +- virCgroupPtr *group) +- ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(5); +- + int virCgroupNewThread(virCgroupPtr domain, + virCgroupThreadName nameval, + int id, +diff --git a/src/util/vircgrouppriv.h b/src/util/vircgrouppriv.h +index 1b47d3b858..a0034f3889 100644 +--- a/src/util/vircgrouppriv.h ++++ b/src/util/vircgrouppriv.h +@@ -54,4 +54,17 @@ int virCgroupDetectMountsFromFile(virCgroupPtr group, + const char *path, + bool checkLinks); + ++int virCgroupNewPartition(const char *path, ++ bool create, ++ int controllers, ++ virCgroupPtr *group) ++ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(4); ++ ++int virCgroupNewDomainPartition(virCgroupPtr partition, ++ const char *driver, ++ const char *name, ++ bool create, ++ virCgroupPtr *group) ++ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(5); ++ + #endif /* __VIR_CGROUP_PRIV_H__ */ +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-Remove-obsolete-sa_assert.patch b/SOURCES/libvirt-vircgroup-Remove-obsolete-sa_assert.patch new file mode 100644 index 0000000..5dca2d2 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-Remove-obsolete-sa_assert.patch @@ -0,0 +1,40 @@ +From 45fd4b2e1b694ca15bfd124f6b5e24e79a670a47 Mon Sep 17 00:00:00 2001 +Message-Id: <45fd4b2e1b694ca15bfd124f6b5e24e79a670a47@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:10 +0200 +Subject: [PATCH] vircgroup: Remove obsolete sa_assert +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit b14b88b74c10c9e20f87218c5994681fc35c2c57) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <3e004259ee462b47a9e1069ac2f4e9d67a914f6e.1561993099.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 02de33f74f..64507bf8aa 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -1054,10 +1054,6 @@ virCgroupMakeGroup(virCgroupPtr parent, + if (virCgroupPathOfController(group, i, "", &path) < 0) + goto error; + +- /* As of Feb 2011, clang can't see that the above function +- * call did not modify group. */ +- sa_assert(group->controllers[i].mountPoint); +- + VIR_DEBUG("Make controller %s", path); + if (!virFileExists(path)) { + if (!create || +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-Remove-pointless-bool-parameter.patch b/SOURCES/libvirt-vircgroup-Remove-pointless-bool-parameter.patch new file mode 100644 index 0000000..675d861 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-Remove-pointless-bool-parameter.patch @@ -0,0 +1,60 @@ +From 7191b04edf95dd3180657ec45aec17c80dfdf083 Mon Sep 17 00:00:00 2001 +Message-Id: <7191b04edf95dd3180657ec45aec17c80dfdf083@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:05:55 +0200 +Subject: [PATCH] vircgroup: Remove pointless bool parameter +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 0490a74aa11a2d993c50da266b8c2234c5a447ca) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <19e5a131d50721e94d43b37e139dda8dd9994df3.1561993099.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 11 ++++------- + 1 file changed, 4 insertions(+), 7 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 7d8bf3419a..9032bcbb63 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -251,7 +251,6 @@ static bool + virCgroupValidateMachineGroup(virCgroupPtr group, + const char *name, + const char *drivername, +- bool stripEmulatorSuffix, + const char *machinename) + { + size_t i; +@@ -303,10 +302,9 @@ virCgroupValidateMachineGroup(virCgroupPtr group, + if (!tmp) + return false; + +- if (stripEmulatorSuffix && +- (i == VIR_CGROUP_CONTROLLER_CPU || +- i == VIR_CGROUP_CONTROLLER_CPUACCT || +- i == VIR_CGROUP_CONTROLLER_CPUSET)) { ++ if (i == VIR_CGROUP_CONTROLLER_CPU || ++ i == VIR_CGROUP_CONTROLLER_CPUACCT || ++ i == VIR_CGROUP_CONTROLLER_CPUSET) { + if (STREQ(tmp, "/emulator")) + *tmp = '\0'; + tmp = strrchr(group->controllers[i].placement, '/'); +@@ -1486,8 +1484,7 @@ virCgroupNewDetectMachine(const char *name, + return -1; + } + +- if (!virCgroupValidateMachineGroup(*group, name, drivername, +- true, machinename)) { ++ if (!virCgroupValidateMachineGroup(*group, name, drivername, machinename)) { + VIR_DEBUG("Failed to validate machine name for '%s' driver '%s'", + name, drivername); + virCgroupFree(group); +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-Remove-unused-function-virCgroupKill.patch b/SOURCES/libvirt-vircgroup-Remove-unused-function-virCgroupKill.patch new file mode 100644 index 0000000..eb61496 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-Remove-unused-function-virCgroupKill.patch @@ -0,0 +1,105 @@ +From a4ed662c80b9241f4bc599fded59ace585db25c9 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:05:51 +0200 +Subject: [PATCH] vircgroup: Remove unused function virCgroupKill() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit c8b1ae607d638b958dc51ba2041bd87ea72683de) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <9f04fae641e673c68253864c858e2123c2252296.1561993099.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/libvirt_private.syms | 1 - + src/util/vircgroup.c | 37 ------------------------------------- + src/util/vircgroup.h | 1 - + 3 files changed, 39 deletions(-) + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index f158a17b49..3117c8009a 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -1558,7 +1558,6 @@ virCgroupGetMemSwapUsage; + virCgroupGetPercpuStats; + virCgroupHasController; + virCgroupHasEmptyTasks; +-virCgroupKill; + virCgroupKillPainfully; + virCgroupKillRecursive; + virCgroupNewDetect; +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 8ddedbfe7c..5f949edec8 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -3510,33 +3510,6 @@ virCgroupPidCopy(const void *name) + } + + +-/* +- * Returns 1 if some PIDs are killed, 0 if none are killed, or -1 on error +- */ +-int +-virCgroupKill(virCgroupPtr group, int signum) +-{ +- VIR_DEBUG("group=%p path=%s signum=%d", group, group->path, signum); +- int ret; +- /* The 'tasks' file in cgroups can contain duplicated +- * pids, so we use a hash to track which we've already +- * killed. +- */ +- virHashTablePtr pids = virHashCreateFull(100, +- NULL, +- virCgroupPidCode, +- virCgroupPidEqual, +- virCgroupPidCopy, +- NULL); +- +- ret = virCgroupKillInternal(group, signum, pids); +- +- virHashFree(pids); +- +- return ret; +-} +- +- + static int + virCgroupKillRecursiveInternal(virCgroupPtr group, + int signum, +@@ -4585,16 +4558,6 @@ virCgroupRemove(virCgroupPtr group ATTRIBUTE_UNUSED) + } + + +-int +-virCgroupKill(virCgroupPtr group ATTRIBUTE_UNUSED, +- int signum ATTRIBUTE_UNUSED) +-{ +- virReportSystemError(ENOSYS, "%s", +- _("Control groups not supported on this platform")); +- return -1; +-} +- +- + int + virCgroupKillRecursive(virCgroupPtr group ATTRIBUTE_UNUSED, + int signum ATTRIBUTE_UNUSED) +diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h +index af93316197..a23a491d95 100644 +--- a/src/util/vircgroup.h ++++ b/src/util/vircgroup.h +@@ -280,7 +280,6 @@ int virCgroupGetCpusetCpus(virCgroupPtr group, char **cpus); + int virCgroupRemoveRecursively(char *grppath); + int virCgroupRemove(virCgroupPtr group); + +-int virCgroupKill(virCgroupPtr group, int signum); + int virCgroupKillRecursive(virCgroupPtr group, int signum); + int virCgroupKillPainfully(virCgroupPtr group); + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-Remove-virCgroupAddTaskController.patch b/SOURCES/libvirt-vircgroup-Remove-virCgroupAddTaskController.patch new file mode 100644 index 0000000..ed026fa --- /dev/null +++ b/SOURCES/libvirt-vircgroup-Remove-virCgroupAddTaskController.patch @@ -0,0 +1,76 @@ +From 88322908f3dfad6217b1c2a2a0f8968b079d0795 Mon Sep 17 00:00:00 2001 +Message-Id: <88322908f3dfad6217b1c2a2a0f8968b079d0795@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:00 +0200 +Subject: [PATCH] vircgroup: Remove virCgroupAddTaskController +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +There is no need for this function, both of the checks are done +later by virCgroupGetControllerPath. + +Signed-off-by: Pavel Hrdina +(cherry picked from commit db868852fdb32c76955c925dcbd92b2d6d9bfeb2) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 31 +------------------------------ + 1 file changed, 1 insertion(+), 30 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 5adf9d3c11..a94f958d75 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -1128,35 +1128,6 @@ virCgroupNew(pid_t pid, + } + + +-/** +- * virCgroupAddTaskController: +- * +- * @group: The cgroup to add a task to +- * @pid: The pid of the task to add +- * @controller: The cgroup controller to be operated on +- * +- * Returns: 0 on success or -1 on error +- */ +-static int +-virCgroupAddTaskController(virCgroupPtr group, pid_t pid, int controller) +-{ +- if (controller < 0 || controller >= VIR_CGROUP_CONTROLLER_LAST) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Controller %d out of range"), controller); +- return -1; +- } +- +- if (!group->controllers[controller].mountPoint) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Controller '%s' not mounted"), +- virCgroupControllerTypeToString(controller)); +- return -1; +- } +- +- return virCgroupSetValueI64(group, controller, "tasks", pid); +-} +- +- + static int + virCgroupAddTaskInternal(virCgroupPtr group, pid_t pid, bool withSystemd) + { +@@ -1174,7 +1145,7 @@ virCgroupAddTaskInternal(virCgroupPtr group, pid_t pid, bool withSystemd) + if (i == VIR_CGROUP_CONTROLLER_SYSTEMD && !withSystemd) + continue; + +- if (virCgroupAddTaskController(group, pid, i) < 0) ++ if (virCgroupSetValueI64(group, i, "tasks", pid) < 0) + goto cleanup; + } + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-Rename-structs-to-start-with-underscore.patch b/SOURCES/libvirt-vircgroup-Rename-structs-to-start-with-underscore.patch new file mode 100644 index 0000000..870aba6 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-Rename-structs-to-start-with-underscore.patch @@ -0,0 +1,80 @@ +From b47ae363dedecaf569906aa3a1349f6e32f4b520 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:05:48 +0200 +Subject: [PATCH] vircgroup: Rename structs to start with underscore +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 70dc671a276ba90099bd1c8ba05e450f092244ff) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <49ff9517362f541da5580fe9acc132319872e732.1561993099.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 2 +- + src/util/vircgroup.h | 4 ++-- + src/util/vircgrouppriv.h | 6 +++--- + 3 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 6bf4e88da1..7602641713 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -385,7 +385,7 @@ virCgroupDetectMountsFromFile(virCgroupPtr group, + const char *typestr = virCgroupControllerTypeToString(i); + int typelen = strlen(typestr); + char *tmp = entry.mnt_opts; +- struct virCgroupController *controller = &group->controllers[i]; ++ struct _virCgroupController *controller = &group->controllers[i]; + while (tmp) { + char *next = strchr(tmp, ','); + int len; +diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h +index d833927678..cfa69b67cb 100644 +--- a/src/util/vircgroup.h ++++ b/src/util/vircgroup.h +@@ -28,8 +28,8 @@ + # include "virutil.h" + # include "virbitmap.h" + +-struct virCgroup; +-typedef struct virCgroup *virCgroupPtr; ++struct _virCgroup; ++typedef struct _virCgroup *virCgroupPtr; + + enum { + VIR_CGROUP_CONTROLLER_CPU, +diff --git a/src/util/vircgrouppriv.h b/src/util/vircgrouppriv.h +index 722863e5b6..71788639d6 100644 +--- a/src/util/vircgrouppriv.h ++++ b/src/util/vircgrouppriv.h +@@ -31,7 +31,7 @@ + + # include "vircgroup.h" + +-struct virCgroupController { ++struct _virCgroupController { + int type; + char *mountPoint; + /* If mountPoint holds several controllers co-mounted, +@@ -42,10 +42,10 @@ struct virCgroupController { + char *placement; + }; + +-struct virCgroup { ++struct _virCgroup { + char *path; + +- struct virCgroupController controllers[VIR_CGROUP_CONTROLLER_LAST]; ++ struct _virCgroupController controllers[VIR_CGROUP_CONTROLLER_LAST]; + }; + + int virCgroupDetectMountsFromFile(virCgroupPtr group, +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-Simplify-if-conditions-in-virCgroupMakeGroup.patch b/SOURCES/libvirt-vircgroup-Simplify-if-conditions-in-virCgroupMakeGroup.patch new file mode 100644 index 0000000..27c69fb --- /dev/null +++ b/SOURCES/libvirt-vircgroup-Simplify-if-conditions-in-virCgroupMakeGroup.patch @@ -0,0 +1,62 @@ +From af1714ac39a383b8a8fb0bc577fbe5e85fd8be10 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:09 +0200 +Subject: [PATCH] vircgroup: Simplify if conditions in virCgroupMakeGroup +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 0ec8416f04460f3bbf7907231b28028c3daed7e7) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 20 ++++++++------------ + 1 file changed, 8 insertions(+), 12 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index dde9ed21a2..02de33f74f 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -1079,24 +1079,20 @@ virCgroupMakeGroup(virCgroupPtr parent, + goto error; + } + } +- if (group->controllers[VIR_CGROUP_CONTROLLER_CPUSET].mountPoint != NULL && +- (i == VIR_CGROUP_CONTROLLER_CPUSET || +- STREQ(group->controllers[i].mountPoint, +- group->controllers[VIR_CGROUP_CONTROLLER_CPUSET].mountPoint))) { +- if (virCgroupCpuSetInherit(parent, group) < 0) +- goto error; ++ if (i == VIR_CGROUP_CONTROLLER_CPUSET && ++ group->controllers[i].mountPoint != NULL && ++ virCgroupCpuSetInherit(parent, group) < 0) { ++ goto error; + } + /* + * Note that virCgroupSetMemoryUseHierarchy should always be + * called prior to creating subcgroups and attaching tasks. + */ + if ((flags & VIR_CGROUP_MEM_HIERACHY) && +- (group->controllers[VIR_CGROUP_CONTROLLER_MEMORY].mountPoint != NULL) && +- (i == VIR_CGROUP_CONTROLLER_MEMORY || +- STREQ(group->controllers[i].mountPoint, +- group->controllers[VIR_CGROUP_CONTROLLER_MEMORY].mountPoint))) { +- if (virCgroupSetMemoryUseHierarchy(group) < 0) +- goto error; ++ i == VIR_CGROUP_CONTROLLER_MEMORY && ++ group->controllers[i].mountPoint != NULL && ++ virCgroupSetMemoryUseHierarchy(group) < 0) { ++ goto error; + } + } + } +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-Split-virCgroupPathOfController-into-two-functions.patch b/SOURCES/libvirt-vircgroup-Split-virCgroupPathOfController-into-two-functions.patch new file mode 100644 index 0000000..6ec3520 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-Split-virCgroupPathOfController-into-two-functions.patch @@ -0,0 +1,138 @@ +From 51e0205bf57346f381143b498cfe0a77852a8da1 Mon Sep 17 00:00:00 2001 +Message-Id: <51e0205bf57346f381143b498cfe0a77852a8da1@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:07 +0200 +Subject: [PATCH] vircgroup: Split virCgroupPathOfController into two functions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The case where we need path of any controller is only for internal use +so move it out to a different function. + +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 998658bd1ebdc5fd9ec43131c381cece1a3893cf) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <7578336183563ecf49d686f6705724db25037191.1561993099.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 54 ++++++++++++++++++++++++++------------------ + src/util/vircgroup.h | 2 +- + 2 files changed, 33 insertions(+), 23 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 2bc4febf23..8646a4a479 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -1772,28 +1772,13 @@ virCgroupHasController(virCgroupPtr cgroup, int controller) + + int + virCgroupPathOfController(virCgroupPtr group, +- int controller, ++ unsigned int controller, + const char *key, + char **path) + { +- if (controller == -1) { +- size_t i; +- for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { +- /* Reject any controller with a placement +- * of '/' to avoid doing bad stuff to the root +- * cgroup +- */ +- if (group->controllers[i].mountPoint && +- group->controllers[i].placement && +- STRNEQ(group->controllers[i].placement, "/")) { +- controller = i; +- break; +- } +- } +- } +- if (controller == -1) { +- virReportSystemError(ENOSYS, "%s", +- _("No controllers are mounted")); ++ if (controller >= VIR_CGROUP_CONTROLLER_LAST) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Invalid controller id '%d'"), controller); + return -1; + } + +@@ -3505,6 +3490,31 @@ virCgroupRemove(virCgroupPtr group) + } + + ++static int ++virCgroupPathOfAnyController(virCgroupPtr group, ++ const char *name, ++ char **keypath) ++{ ++ size_t i; ++ ++ for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { ++ /* Reject any controller with a placement ++ * of '/' to avoid doing bad stuff to the root ++ * cgroup ++ */ ++ if (group->controllers[i].mountPoint && ++ group->controllers[i].placement && ++ STRNEQ(group->controllers[i].placement, "/")) { ++ return virCgroupPathOfController(group, i, name, keypath); ++ } ++ } ++ ++ virReportSystemError(ENOSYS, "%s", ++ _("No controllers are mounted")); ++ return -1; ++} ++ ++ + /* + * Returns 1 if some PIDs are killed, 0 if none are killed, or -1 on error + */ +@@ -3519,7 +3529,7 @@ virCgroupKillInternal(virCgroupPtr group, int signum, virHashTablePtr pids) + VIR_DEBUG("group=%p path=%s signum=%d pids=%p", + group, group->path, signum, pids); + +- if (virCgroupPathOfController(group, -1, "tasks", &keypath) < 0) ++ if (virCgroupPathOfAnyController(group, "tasks", &keypath) < 0) + return -1; + + /* PIDs may be forking as we kill them, so loop +@@ -3622,7 +3632,7 @@ virCgroupKillRecursiveInternal(virCgroupPtr group, + VIR_DEBUG("group=%p path=%s signum=%d pids=%p", + group, group->path, signum, pids); + +- if (virCgroupPathOfController(group, -1, "", &keypath) < 0) ++ if (virCgroupPathOfAnyController(group, "", &keypath) < 0) + return -1; + + if ((rc = virCgroupKillInternal(group, signum, pids)) < 0) +@@ -4180,7 +4190,7 @@ virCgroupHasController(virCgroupPtr cgroup ATTRIBUTE_UNUSED, + + int + virCgroupPathOfController(virCgroupPtr group ATTRIBUTE_UNUSED, +- int controller ATTRIBUTE_UNUSED, ++ unsigned int controller ATTRIBUTE_UNUSED, + const char *key ATTRIBUTE_UNUSED, + char **path ATTRIBUTE_UNUSED) + { +diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h +index c7fdaaede4..ee3b7c7222 100644 +--- a/src/util/vircgroup.h ++++ b/src/util/vircgroup.h +@@ -114,7 +114,7 @@ void virCgroupFree(virCgroupPtr *group); + + bool virCgroupHasController(virCgroupPtr cgroup, int controller); + int virCgroupPathOfController(virCgroupPtr group, +- int controller, ++ unsigned int controller, + const char *key, + char **path); + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-Unexport-unused-function-virCgroupAddTaskController.patch b/SOURCES/libvirt-vircgroup-Unexport-unused-function-virCgroupAddTaskController.patch new file mode 100644 index 0000000..509f992 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-Unexport-unused-function-virCgroupAddTaskController.patch @@ -0,0 +1,148 @@ +From 7dd9c146f4713fd15b6d6642b910af29846d96e2 Mon Sep 17 00:00:00 2001 +Message-Id: <7dd9c146f4713fd15b6d6642b910af29846d96e2@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:05:52 +0200 +Subject: [PATCH] vircgroup: Unexport unused function + virCgroupAddTaskController() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 0aaac42a6eb3fb8b5aa412d5153e0d6ae459c631) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <30f7f52a9e7d0b9ce838a2d32cc6ec0a0cf97788.1561993099.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/libvirt_private.syms | 1 - + src/util/vircgroup.c | 69 +++++++++++++++++----------------------- + src/util/vircgroup.h | 4 --- + 3 files changed, 29 insertions(+), 45 deletions(-) + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 3117c8009a..41fca88d09 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -1515,7 +1515,6 @@ virBufferVasprintf; + # util/vircgroup.h + virCgroupAddMachineTask; + virCgroupAddTask; +-virCgroupAddTaskController; + virCgroupAllowAllDevices; + virCgroupAllowDevice; + virCgroupAllowDevicePath; +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 5f949edec8..8ef6fb5e1a 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -1136,6 +1136,35 @@ virCgroupNew(pid_t pid, + } + + ++/** ++ * virCgroupAddTaskController: ++ * ++ * @group: The cgroup to add a task to ++ * @pid: The pid of the task to add ++ * @controller: The cgroup controller to be operated on ++ * ++ * Returns: 0 on success or -1 on error ++ */ ++static int ++virCgroupAddTaskController(virCgroupPtr group, pid_t pid, int controller) ++{ ++ if (controller < 0 || controller >= VIR_CGROUP_CONTROLLER_LAST) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Controller %d out of range"), controller); ++ return -1; ++ } ++ ++ if (!group->controllers[controller].mountPoint) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Controller '%s' not mounted"), ++ virCgroupControllerTypeToString(controller)); ++ return -1; ++ } ++ ++ return virCgroupSetValueI64(group, controller, "tasks", pid); ++} ++ ++ + static int + virCgroupAddTaskInternal(virCgroupPtr group, pid_t pid, bool withSystemd) + { +@@ -1197,35 +1226,6 @@ virCgroupAddMachineTask(virCgroupPtr group, pid_t pid) + } + + +-/** +- * virCgroupAddTaskController: +- * +- * @group: The cgroup to add a task to +- * @pid: The pid of the task to add +- * @controller: The cgroup controller to be operated on +- * +- * Returns: 0 on success or -1 on error +- */ +-int +-virCgroupAddTaskController(virCgroupPtr group, pid_t pid, int controller) +-{ +- if (controller < 0 || controller >= VIR_CGROUP_CONTROLLER_LAST) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Controller %d out of range"), controller); +- return -1; +- } +- +- if (!group->controllers[controller].mountPoint) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Controller '%s' not mounted"), +- virCgroupControllerTypeToString(controller)); +- return -1; +- } +- +- return virCgroupSetValueI64(group, controller, "tasks", pid); +-} +- +- + static int + virCgroupSetPartitionSuffix(const char *path, char **res) + { +@@ -4115,17 +4115,6 @@ virCgroupAddMachineTask(virCgroupPtr group ATTRIBUTE_UNUSED, + } + + +-int +-virCgroupAddTaskController(virCgroupPtr group ATTRIBUTE_UNUSED, +- pid_t pid ATTRIBUTE_UNUSED, +- int controller ATTRIBUTE_UNUSED) +-{ +- virReportSystemError(ENXIO, "%s", +- _("Control groups not supported on this platform")); +- return -1; +-} +- +- + int + virCgroupGetBlkioIoServiced(virCgroupPtr group ATTRIBUTE_UNUSED, + long long *bytes_read ATTRIBUTE_UNUSED, +diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h +index a23a491d95..74c7dbcccc 100644 +--- a/src/util/vircgroup.h ++++ b/src/util/vircgroup.h +@@ -134,10 +134,6 @@ int virCgroupPathOfController(virCgroupPtr group, + int virCgroupAddTask(virCgroupPtr group, pid_t pid); + int virCgroupAddMachineTask(virCgroupPtr group, pid_t pid); + +-int virCgroupAddTaskController(virCgroupPtr group, +- pid_t pid, +- int controller); +- + int virCgroupSetBlkioWeight(virCgroupPtr group, unsigned int weight); + int virCgroupGetBlkioWeight(virCgroupPtr group, unsigned int *weight); + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-Unexport-unused-function-virCgroupRemoveRecursively.patch b/SOURCES/libvirt-vircgroup-Unexport-unused-function-virCgroupRemoveRecursively.patch new file mode 100644 index 0000000..efe0168 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-Unexport-unused-function-virCgroupRemoveRecursively.patch @@ -0,0 +1,80 @@ +From 6ee7a399fe93348c24c4535a2ada43ea67144a22 Mon Sep 17 00:00:00 2001 +Message-Id: <6ee7a399fe93348c24c4535a2ada43ea67144a22@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:05:53 +0200 +Subject: [PATCH] vircgroup: Unexport unused function + virCgroupRemoveRecursively +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 32686849fcdc2faca8735869eaa8d5453283a84c) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <0e830b8383a92e496cd492d8b91b26172dd0e667.1561993099.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/libvirt_private.syms | 1 - + src/util/vircgroup.c | 11 +---------- + src/util/vircgroup.h | 1 - + 3 files changed, 1 insertion(+), 12 deletions(-) + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 41fca88d09..47695eb507 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -1569,7 +1569,6 @@ virCgroupNewSelf; + virCgroupNewThread; + virCgroupPathOfController; + virCgroupRemove; +-virCgroupRemoveRecursively; + virCgroupSetBlkioDeviceReadBps; + virCgroupSetBlkioDeviceReadIops; + virCgroupSetBlkioDeviceWeight; +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 8ef6fb5e1a..7d8bf3419a 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -3312,7 +3312,7 @@ virCgroupGetCpuacctPercpuUsage(virCgroupPtr group, char **usage) + } + + +-int ++static int + virCgroupRemoveRecursively(char *grppath) + { + DIR *grpdir; +@@ -4529,15 +4529,6 @@ virCgroupSetCpuCfsQuota(virCgroupPtr group ATTRIBUTE_UNUSED, + } + + +-int +-virCgroupRemoveRecursively(char *grppath ATTRIBUTE_UNUSED) +-{ +- virReportSystemError(ENXIO, "%s", +- _("Control groups not supported on this platform")); +- return -1; +-} +- +- + int + virCgroupRemove(virCgroupPtr group ATTRIBUTE_UNUSED) + { +diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h +index 74c7dbcccc..138bb3c076 100644 +--- a/src/util/vircgroup.h ++++ b/src/util/vircgroup.h +@@ -273,7 +273,6 @@ int virCgroupGetCpusetMemoryMigrate(virCgroupPtr group, bool *migrate); + int virCgroupSetCpusetCpus(virCgroupPtr group, const char *cpus); + int virCgroupGetCpusetCpus(virCgroupPtr group, char **cpus); + +-int virCgroupRemoveRecursively(char *grppath); + int virCgroupRemove(virCgroupPtr group); + + int virCgroupKillRecursive(virCgroupPtr group, int signum); +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-Use-virCgroupMountOptsMatchController-in-virCgroupDetectPlacement.patch b/SOURCES/libvirt-vircgroup-Use-virCgroupMountOptsMatchController-in-virCgroupDetectPlacement.patch new file mode 100644 index 0000000..4e1ce1e --- /dev/null +++ b/SOURCES/libvirt-vircgroup-Use-virCgroupMountOptsMatchController-in-virCgroupDetectPlacement.patch @@ -0,0 +1,86 @@ +From dc8f41bf6bb689d86bc91d5aca7fb854a5ef847f Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:05:57 +0200 +Subject: [PATCH] vircgroup: Use virCgroupMountOptsMatchController in + virCgroupDetectPlacement +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 801d95d2597572612c346508446320a33aebc50d) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <9c2bb230e14ced391b0731bc2964155960025aa5.1561993099.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 43 ++++++++++++++----------------------------- + 1 file changed, 14 insertions(+), 29 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index ec9994780a..7888dab716 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -598,42 +598,27 @@ virCgroupDetectPlacement(virCgroupPtr group, + + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { + const char *typestr = virCgroupControllerTypeToString(i); +- int typelen = strlen(typestr); +- char *tmp = controllers; +- +- while (tmp) { +- char *next = strchr(tmp, ','); +- int len; +- if (next) { +- len = next - tmp; +- next++; +- } else { +- len = strlen(tmp); +- } + ++ if (virCgroupMountOptsMatchController(controllers, typestr) && ++ group->controllers[i].mountPoint != NULL && ++ group->controllers[i].placement == NULL) { + /* + * selfpath == "/" + path="" -> "/" + * selfpath == "/libvirt.service" + path == "" -> "/libvirt.service" + * selfpath == "/libvirt.service" + path == "foo" -> "/libvirt.service/foo" + */ +- if (typelen == len && STREQLEN(typestr, tmp, len) && +- group->controllers[i].mountPoint != NULL && +- group->controllers[i].placement == NULL) { +- if (i == VIR_CGROUP_CONTROLLER_SYSTEMD) { +- if (VIR_STRDUP(group->controllers[i].placement, +- selfpath) < 0) +- goto cleanup; +- } else { +- if (virAsprintf(&group->controllers[i].placement, +- "%s%s%s", selfpath, +- (STREQ(selfpath, "/") || +- STREQ(path, "") ? "" : "/"), +- path) < 0) +- goto cleanup; +- } ++ if (i == VIR_CGROUP_CONTROLLER_SYSTEMD) { ++ if (VIR_STRDUP(group->controllers[i].placement, ++ selfpath) < 0) ++ goto cleanup; ++ } else { ++ if (virAsprintf(&group->controllers[i].placement, ++ "%s%s%s", selfpath, ++ (STREQ(selfpath, "/") || ++ STREQ(path, "") ? "" : "/"), ++ path) < 0) ++ goto cleanup; + } +- +- tmp = next; + } + } + } +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-add-support-for-hybrid-configuration.patch b/SOURCES/libvirt-vircgroup-add-support-for-hybrid-configuration.patch new file mode 100644 index 0000000..413c5a0 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-add-support-for-hybrid-configuration.patch @@ -0,0 +1,985 @@ +From 50c5a71ce4a4400d08deff481c8781f3fca755c8 Mon Sep 17 00:00:00 2001 +Message-Id: <50c5a71ce4a4400d08deff481c8781f3fca755c8@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:53 +0200 +Subject: [PATCH] vircgroup: add support for hybrid configuration +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This enables to use both cgroup v1 and v2 at the same time together +with libvirt. It is supported by kernel and there is valid use-case, +not all controllers are implemented in cgroup v2 so there might be +configurations where administrator would enable these missing +controllers in cgroup v1. + +Signed-off-by: Pavel Hrdina +(cherry picked from commit b79d858518ed15b1a4271457fc9f39463dd99230) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 351 ++++++++++++++++++++++++++---------- + src/util/vircgroupbackend.c | 20 ++ + src/util/vircgroupbackend.h | 16 +- + src/util/vircgrouppriv.h | 2 +- + 4 files changed, 291 insertions(+), 98 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index a859628241..069f1ae396 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -232,6 +232,7 @@ virCgroupDetectMounts(virCgroupPtr group) + struct mntent entry; + char buf[CGROUP_MAX_VAL]; + int ret = -1; ++ size_t i; + + mounts = fopen("/proc/mounts", "r"); + if (mounts == NULL) { +@@ -240,11 +241,14 @@ virCgroupDetectMounts(virCgroupPtr group) + } + + while (getmntent_r(mounts, &entry, buf, sizeof(buf)) != NULL) { +- if (group->backend->detectMounts(group, +- entry.mnt_type, +- entry.mnt_opts, +- entry.mnt_dir) < 0) { +- goto cleanup; ++ for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) { ++ if (group->backends[i] && ++ group->backends[i]->detectMounts(group, ++ entry.mnt_type, ++ entry.mnt_opts, ++ entry.mnt_dir) < 0) { ++ goto cleanup; ++ } + } + } + +@@ -307,6 +311,7 @@ virCgroupDetectPlacement(virCgroupPtr group, + } + + while (fgets(line, sizeof(line), mapping) != NULL) { ++ size_t i; + char *controllers = strchr(line, ':'); + char *selfpath = controllers ? strchr(controllers + 1, ':') : NULL; + char *nl = selfpath ? strchr(selfpath, '\n') : NULL; +@@ -321,9 +326,12 @@ virCgroupDetectPlacement(virCgroupPtr group, + controllers++; + selfpath++; + +- if (group->backend->detectPlacement(group, path, controllers, +- selfpath) < 0) { +- goto cleanup; ++ for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) { ++ if (group->backends[i] && ++ group->backends[i]->detectPlacement(group, path, controllers, ++ selfpath) < 0) { ++ goto cleanup; ++ } + } + } + +@@ -342,8 +350,9 @@ virCgroupDetect(virCgroupPtr group, + const char *path, + virCgroupPtr parent) + { +- int rc; + size_t i; ++ bool backendAvailable = false; ++ int controllersAvailable = 0; + virCgroupBackendPtr *backends = virCgroupBackendGetAll(); + + VIR_DEBUG("group=%p controllers=%d path=%s parent=%p", +@@ -354,31 +363,40 @@ virCgroupDetect(virCgroupPtr group, + + for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) { + if (backends[i] && backends[i]->available()) { +- group->backend = backends[i]; +- break; ++ group->backends[i] = backends[i]; ++ backendAvailable = true; + } + } + +- if (!group->backend) { ++ if (!backendAvailable) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("no cgroup backend available")); + return -1; + } + + if (parent) { +- if (group->backend->copyMounts(group, parent) < 0) +- return -1; ++ for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) { ++ if (group->backends[i] && ++ group->backends[i]->copyMounts(group, parent) < 0) { ++ return -1; ++ } ++ } + } else { + if (virCgroupDetectMounts(group) < 0) + return -1; + } + +- rc = group->backend->detectControllers(group, controllers); +- if (rc < 0) +- return -1; ++ for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) { ++ if (group->backends[i]) { ++ int rc = group->backends[i]->detectControllers(group, controllers); ++ if (rc < 0) ++ return -1; ++ controllersAvailable |= rc; ++ } ++ } + + /* Check that at least 1 controller is available */ +- if (rc == 0) { ++ if (controllersAvailable == 0) { + virReportSystemError(ENXIO, "%s", + _("At least one cgroup controller is required")); + return -1; +@@ -387,17 +405,26 @@ virCgroupDetect(virCgroupPtr group, + /* In some cases we can copy part of the placement info + * based on the parent cgroup... + */ +- if ((parent || path[0] == '/') && +- group->backend->copyPlacement(group, path, parent) < 0) +- return -1; ++ if (parent || path[0] == '/') { ++ for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) { ++ if (group->backends[i] && ++ group->backends[i]->copyPlacement(group, path, parent) < 0) { ++ return -1; ++ } ++ } ++ } + + /* ... but use /proc/cgroups to fill in the rest */ + if (virCgroupDetectPlacement(group, pid, path) < 0) + return -1; + + /* Check that for every mounted controller, we found our placement */ +- if (group->backend->validatePlacement(group, pid) < 0) +- return -1; ++ for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) { ++ if (group->backends[i] && ++ group->backends[i]->validatePlacement(group, pid) < 0) { ++ return -1; ++ } ++ } + + return 0; + } +@@ -603,9 +630,14 @@ virCgroupMakeGroup(virCgroupPtr parent, + bool create, + unsigned int flags) + { +- if (group->backend->makeGroup(parent, group, create, flags) < 0) { +- virCgroupRemove(group); +- return -1; ++ size_t i; ++ ++ for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) { ++ if (group->backends[i] && ++ group->backends[i]->makeGroup(parent, group, create, flags) < 0) { ++ virCgroupRemove(group); ++ return -1; ++ } + } + + return 0; +@@ -666,6 +698,24 @@ virCgroupNew(pid_t pid, + } + + ++static int ++virCgroupAddTaskInternal(virCgroupPtr group, ++ pid_t pid, ++ unsigned int flags) ++{ ++ size_t i; ++ ++ for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) { ++ if (group->backends[i] && ++ group->backends[i]->addTask(group, pid, flags) < 0) { ++ return -1; ++ } ++ } ++ ++ return 0; ++} ++ ++ + /** + * virCgroupAddProcess: + * +@@ -680,7 +730,7 @@ virCgroupNew(pid_t pid, + int + virCgroupAddProcess(virCgroupPtr group, pid_t pid) + { +- return group->backend->addTask(group, pid, VIR_CGROUP_TASK_PROCESS); ++ return virCgroupAddTaskInternal(group, pid, VIR_CGROUP_TASK_PROCESS); + } + + /** +@@ -697,9 +747,9 @@ virCgroupAddProcess(virCgroupPtr group, pid_t pid) + int + virCgroupAddMachineProcess(virCgroupPtr group, pid_t pid) + { +- return group->backend->addTask(group, pid, +- VIR_CGROUP_TASK_PROCESS | +- VIR_CGROUP_TASK_SYSTEMD); ++ return virCgroupAddTaskInternal(group, pid, ++ VIR_CGROUP_TASK_PROCESS | ++ VIR_CGROUP_TASK_SYSTEMD); + } + + /** +@@ -717,7 +767,7 @@ int + virCgroupAddThread(virCgroupPtr group, + pid_t pid) + { +- return group->backend->addTask(group, pid, VIR_CGROUP_TASK_THREAD); ++ return virCgroupAddTaskInternal(group, pid, VIR_CGROUP_TASK_THREAD); + } + + +@@ -971,17 +1021,24 @@ virCgroupNewDetectMachine(const char *name, + char *machinename, + virCgroupPtr *group) + { ++ size_t i; ++ + if (virCgroupNewDetect(pid, controllers, group) < 0) { + if (virCgroupNewIgnoreError()) + return 0; + return -1; + } + +- if (!(*group)->backend->validateMachineGroup(*group, name, drivername, machinename)) { +- VIR_DEBUG("Failed to validate machine name for '%s' driver '%s'", +- name, drivername); +- virCgroupFree(group); +- return 0; ++ for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) { ++ if ((*group)->backends[i] && ++ !(*group)->backends[i]->validateMachineGroup(*group, name, ++ drivername, ++ machinename)) { ++ VIR_DEBUG("Failed to validate machine name for '%s' driver '%s'", ++ name, drivername); ++ virCgroupFree(group); ++ return 0; ++ } + } + + return 0; +@@ -1059,6 +1116,7 @@ virCgroupNewMachineSystemd(const char *name, + int rv; + virCgroupPtr init; + VIR_AUTOFREE(char *) path = NULL; ++ size_t i; + + VIR_DEBUG("Trying to setup machine '%s' via systemd", name); + if ((rv = virSystemdCreateMachine(name, +@@ -1081,7 +1139,12 @@ virCgroupNewMachineSystemd(const char *name, + &init) < 0) + return -1; + +- path = init->backend->stealPlacement(init); ++ for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) { ++ if (init->backends[i] && ++ (path = init->backends[i]->stealPlacement(init))) { ++ break; ++ } ++ } + virCgroupFree(&init); + + if (!path || STREQ(path, "/") || path[0] != '/') { +@@ -1260,12 +1323,21 @@ virCgroupFree(virCgroupPtr *group) + bool + virCgroupHasController(virCgroupPtr cgroup, int controller) + { ++ size_t i; ++ + if (!cgroup) + return false; + if (controller < 0 || controller >= VIR_CGROUP_CONTROLLER_LAST) + return false; + +- return cgroup->backend->hasController(cgroup, controller); ++ for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) { ++ if (cgroup->backends[i] && ++ cgroup->backends[i]->hasController(cgroup, controller)) { ++ return true; ++ } ++ } ++ ++ return false; + } + + +@@ -1281,7 +1353,8 @@ virCgroupPathOfController(virCgroupPtr group, + return -1; + } + +- return group->backend->pathOfController(group, controller, key, path); ++ VIR_CGROUP_BACKEND_CALL(group, controller, pathOfController, -1, ++ controller, key, path); + } + + +@@ -1303,7 +1376,8 @@ virCgroupGetBlkioIoServiced(virCgroupPtr group, + long long *requests_read, + long long *requests_write) + { +- VIR_CGROUP_BACKEND_CALL(group, getBlkioIoServiced, -1, ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO, ++ getBlkioIoServiced, -1, + bytes_read, bytes_write, + requests_read, requests_write); + } +@@ -1329,7 +1403,8 @@ virCgroupGetBlkioIoDeviceServiced(virCgroupPtr group, + long long *requests_read, + long long *requests_write) + { +- VIR_CGROUP_BACKEND_CALL(group, getBlkioIoDeviceServiced, -1, ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO, ++ getBlkioIoDeviceServiced, -1, + path, bytes_read, bytes_write, + requests_read, requests_write); + } +@@ -1346,7 +1421,8 @@ virCgroupGetBlkioIoDeviceServiced(virCgroupPtr group, + int + virCgroupSetBlkioWeight(virCgroupPtr group, unsigned int weight) + { +- VIR_CGROUP_BACKEND_CALL(group, setBlkioWeight, -1, weight); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO, ++ setBlkioWeight, -1, weight); + } + + +@@ -1361,7 +1437,8 @@ virCgroupSetBlkioWeight(virCgroupPtr group, unsigned int weight) + int + virCgroupGetBlkioWeight(virCgroupPtr group, unsigned int *weight) + { +- VIR_CGROUP_BACKEND_CALL(group, getBlkioWeight, -1, weight); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO, ++ getBlkioWeight, -1, weight); + } + + /** +@@ -1377,7 +1454,8 @@ virCgroupSetBlkioDeviceReadIops(virCgroupPtr group, + const char *path, + unsigned int riops) + { +- VIR_CGROUP_BACKEND_CALL(group, setBlkioDeviceReadIops, -1, path, riops); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO, ++ setBlkioDeviceReadIops, -1, path, riops); + } + + +@@ -1394,7 +1472,8 @@ virCgroupSetBlkioDeviceWriteIops(virCgroupPtr group, + const char *path, + unsigned int wiops) + { +- VIR_CGROUP_BACKEND_CALL(group, setBlkioDeviceWriteIops, -1, path, wiops); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO, ++ setBlkioDeviceWriteIops, -1, path, wiops); + } + + +@@ -1411,7 +1490,8 @@ virCgroupSetBlkioDeviceReadBps(virCgroupPtr group, + const char *path, + unsigned long long rbps) + { +- VIR_CGROUP_BACKEND_CALL(group, setBlkioDeviceReadBps, -1, path, rbps); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO, ++ setBlkioDeviceReadBps, -1, path, rbps); + } + + /** +@@ -1427,7 +1507,8 @@ virCgroupSetBlkioDeviceWriteBps(virCgroupPtr group, + const char *path, + unsigned long long wbps) + { +- VIR_CGROUP_BACKEND_CALL(group, setBlkioDeviceWriteBps, -1, path, wbps); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO, ++ setBlkioDeviceWriteBps, -1, path, wbps); + } + + +@@ -1445,7 +1526,8 @@ virCgroupSetBlkioDeviceWeight(virCgroupPtr group, + const char *path, + unsigned int weight) + { +- VIR_CGROUP_BACKEND_CALL(group, setBlkioDeviceWeight, -1, path, weight); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO, ++ setBlkioDeviceWeight, -1, path, weight); + } + + /** +@@ -1461,7 +1543,8 @@ virCgroupGetBlkioDeviceReadIops(virCgroupPtr group, + const char *path, + unsigned int *riops) + { +- VIR_CGROUP_BACKEND_CALL(group, getBlkioDeviceReadIops, -1, path, riops); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO, ++ getBlkioDeviceReadIops, -1, path, riops); + } + + /** +@@ -1477,7 +1560,8 @@ virCgroupGetBlkioDeviceWriteIops(virCgroupPtr group, + const char *path, + unsigned int *wiops) + { +- VIR_CGROUP_BACKEND_CALL(group, getBlkioDeviceWriteIops, -1, path, wiops); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO, ++ getBlkioDeviceWriteIops, -1, path, wiops); + } + + /** +@@ -1493,7 +1577,8 @@ virCgroupGetBlkioDeviceReadBps(virCgroupPtr group, + const char *path, + unsigned long long *rbps) + { +- VIR_CGROUP_BACKEND_CALL(group, getBlkioDeviceReadBps, -1, path, rbps); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO, ++ getBlkioDeviceReadBps, -1, path, rbps); + } + + /** +@@ -1509,7 +1594,8 @@ virCgroupGetBlkioDeviceWriteBps(virCgroupPtr group, + const char *path, + unsigned long long *wbps) + { +- VIR_CGROUP_BACKEND_CALL(group, getBlkioDeviceWriteBps, -1, path, wbps); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO, ++ getBlkioDeviceWriteBps, -1, path, wbps); + } + + /** +@@ -1525,7 +1611,8 @@ virCgroupGetBlkioDeviceWeight(virCgroupPtr group, + const char *path, + unsigned int *weight) + { +- VIR_CGROUP_BACKEND_CALL(group, getBlkioDeviceWeight, -1, path, weight); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO, ++ getBlkioDeviceWeight, -1, path, weight); + } + + +@@ -1540,7 +1627,8 @@ virCgroupGetBlkioDeviceWeight(virCgroupPtr group, + int + virCgroupSetMemory(virCgroupPtr group, unsigned long long kb) + { +- VIR_CGROUP_BACKEND_CALL(group, setMemory, -1, kb); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY, ++ setMemory, -1, kb); + } + + +@@ -1566,7 +1654,8 @@ virCgroupGetMemoryStat(virCgroupPtr group, + unsigned long long *inactiveFile, + unsigned long long *unevictable) + { +- VIR_CGROUP_BACKEND_CALL(group, getMemoryStat, -1, cache, ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY, ++ getMemoryStat, -1, cache, + activeAnon, inactiveAnon, + activeFile, inactiveFile, + unevictable); +@@ -1584,7 +1673,8 @@ virCgroupGetMemoryStat(virCgroupPtr group, + int + virCgroupGetMemoryUsage(virCgroupPtr group, unsigned long *kb) + { +- VIR_CGROUP_BACKEND_CALL(group, getMemoryUsage, -1, kb); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY, ++ getMemoryUsage, -1, kb); + } + + +@@ -1599,7 +1689,8 @@ virCgroupGetMemoryUsage(virCgroupPtr group, unsigned long *kb) + int + virCgroupSetMemoryHardLimit(virCgroupPtr group, unsigned long long kb) + { +- VIR_CGROUP_BACKEND_CALL(group, setMemoryHardLimit, -1, kb); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY, ++ setMemoryHardLimit, -1, kb); + } + + +@@ -1614,7 +1705,8 @@ virCgroupSetMemoryHardLimit(virCgroupPtr group, unsigned long long kb) + int + virCgroupGetMemoryHardLimit(virCgroupPtr group, unsigned long long *kb) + { +- VIR_CGROUP_BACKEND_CALL(group, getMemoryHardLimit, -1, kb); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY, ++ getMemoryHardLimit, -1, kb); + } + + +@@ -1629,7 +1721,8 @@ virCgroupGetMemoryHardLimit(virCgroupPtr group, unsigned long long *kb) + int + virCgroupSetMemorySoftLimit(virCgroupPtr group, unsigned long long kb) + { +- VIR_CGROUP_BACKEND_CALL(group, setMemorySoftLimit, -1, kb); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY, ++ setMemorySoftLimit, -1, kb); + } + + +@@ -1644,7 +1737,8 @@ virCgroupSetMemorySoftLimit(virCgroupPtr group, unsigned long long kb) + int + virCgroupGetMemorySoftLimit(virCgroupPtr group, unsigned long long *kb) + { +- VIR_CGROUP_BACKEND_CALL(group, getMemorySoftLimit, -1, kb); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY, ++ getMemorySoftLimit, -1, kb); + } + + +@@ -1659,7 +1753,8 @@ virCgroupGetMemorySoftLimit(virCgroupPtr group, unsigned long long *kb) + int + virCgroupSetMemSwapHardLimit(virCgroupPtr group, unsigned long long kb) + { +- VIR_CGROUP_BACKEND_CALL(group, setMemSwapHardLimit, -1, kb); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY, ++ setMemSwapHardLimit, -1, kb); + } + + +@@ -1674,7 +1769,8 @@ virCgroupSetMemSwapHardLimit(virCgroupPtr group, unsigned long long kb) + int + virCgroupGetMemSwapHardLimit(virCgroupPtr group, unsigned long long *kb) + { +- VIR_CGROUP_BACKEND_CALL(group, getMemSwapHardLimit, -1, kb); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY, ++ getMemSwapHardLimit, -1, kb); + } + + +@@ -1689,7 +1785,8 @@ virCgroupGetMemSwapHardLimit(virCgroupPtr group, unsigned long long *kb) + int + virCgroupGetMemSwapUsage(virCgroupPtr group, unsigned long long *kb) + { +- VIR_CGROUP_BACKEND_CALL(group, getMemSwapUsage, -1, kb); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY, ++ getMemSwapUsage, -1, kb); + } + + +@@ -1704,7 +1801,8 @@ virCgroupGetMemSwapUsage(virCgroupPtr group, unsigned long long *kb) + int + virCgroupSetCpusetMems(virCgroupPtr group, const char *mems) + { +- VIR_CGROUP_BACKEND_CALL(group, setCpusetMems, -1, mems); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPUSET, ++ setCpusetMems, -1, mems); + } + + +@@ -1719,7 +1817,8 @@ virCgroupSetCpusetMems(virCgroupPtr group, const char *mems) + int + virCgroupGetCpusetMems(virCgroupPtr group, char **mems) + { +- VIR_CGROUP_BACKEND_CALL(group, getCpusetMems, -1, mems); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPUSET, ++ getCpusetMems, -1, mems); + } + + +@@ -1734,7 +1833,8 @@ virCgroupGetCpusetMems(virCgroupPtr group, char **mems) + int + virCgroupSetCpusetMemoryMigrate(virCgroupPtr group, bool migrate) + { +- VIR_CGROUP_BACKEND_CALL(group, setCpusetMemoryMigrate, -1, migrate); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPUSET, ++ setCpusetMemoryMigrate, -1, migrate); + } + + +@@ -1749,7 +1849,8 @@ virCgroupSetCpusetMemoryMigrate(virCgroupPtr group, bool migrate) + int + virCgroupGetCpusetMemoryMigrate(virCgroupPtr group, bool *migrate) + { +- VIR_CGROUP_BACKEND_CALL(group, getCpusetMemoryMigrate, -1, migrate); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPUSET, ++ getCpusetMemoryMigrate, -1, migrate); + } + + +@@ -1764,7 +1865,8 @@ virCgroupGetCpusetMemoryMigrate(virCgroupPtr group, bool *migrate) + int + virCgroupSetCpusetCpus(virCgroupPtr group, const char *cpus) + { +- VIR_CGROUP_BACKEND_CALL(group, setCpusetCpus, -1, cpus); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPUSET, ++ setCpusetCpus, -1, cpus); + } + + +@@ -1779,7 +1881,8 @@ virCgroupSetCpusetCpus(virCgroupPtr group, const char *cpus) + int + virCgroupGetCpusetCpus(virCgroupPtr group, char **cpus) + { +- VIR_CGROUP_BACKEND_CALL(group, getCpusetCpus, -1, cpus); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPUSET, ++ getCpusetCpus, -1, cpus); + } + + +@@ -1793,7 +1896,8 @@ virCgroupGetCpusetCpus(virCgroupPtr group, char **cpus) + int + virCgroupDenyAllDevices(virCgroupPtr group) + { +- VIR_CGROUP_BACKEND_CALL(group, denyAllDevices, -1); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_DEVICES, ++ denyAllDevices, -1); + } + + /** +@@ -1813,7 +1917,8 @@ virCgroupDenyAllDevices(virCgroupPtr group) + int + virCgroupAllowAllDevices(virCgroupPtr group, int perms) + { +- VIR_CGROUP_BACKEND_CALL(group, allowAllDevices, -1, perms); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_DEVICES, ++ allowAllDevices, -1, perms); + } + + +@@ -1832,7 +1937,8 @@ int + virCgroupAllowDevice(virCgroupPtr group, char type, int major, int minor, + int perms) + { +- VIR_CGROUP_BACKEND_CALL(group, allowDevice, -1, type, major, minor, perms); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_DEVICES, ++ allowDevice, -1, type, major, minor, perms); + } + + +@@ -1871,7 +1977,8 @@ virCgroupAllowDevicePath(virCgroupPtr group, + if (!S_ISCHR(sb.st_mode) && !S_ISBLK(sb.st_mode)) + return 1; + +- VIR_CGROUP_BACKEND_CALL(group, allowDevice, -1, ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_DEVICES, ++ allowDevice, -1, + S_ISCHR(sb.st_mode) ? 'c' : 'b', + major(sb.st_rdev), + minor(sb.st_rdev), +@@ -1894,7 +2001,8 @@ int + virCgroupDenyDevice(virCgroupPtr group, char type, int major, int minor, + int perms) + { +- VIR_CGROUP_BACKEND_CALL(group, denyDevice, -1, type, major, minor, perms); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_DEVICES, ++ denyDevice, -1, type, major, minor, perms); + } + + +@@ -1933,7 +2041,8 @@ virCgroupDenyDevicePath(virCgroupPtr group, + if (!S_ISCHR(sb.st_mode) && !S_ISBLK(sb.st_mode)) + return 1; + +- VIR_CGROUP_BACKEND_CALL(group, denyDevice, -1, ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_DEVICES, ++ denyDevice, -1, + S_ISCHR(sb.st_mode) ? 'c' : 'b', + major(sb.st_rdev), + minor(sb.st_rdev), +@@ -2176,14 +2285,16 @@ virCgroupGetDomainTotalCpuStats(virCgroupPtr group, + int + virCgroupSetCpuShares(virCgroupPtr group, unsigned long long shares) + { +- VIR_CGROUP_BACKEND_CALL(group, setCpuShares, -1, shares); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPU, ++ setCpuShares, -1, shares); + } + + + int + virCgroupGetCpuShares(virCgroupPtr group, unsigned long long *shares) + { +- VIR_CGROUP_BACKEND_CALL(group, getCpuShares, -1, shares); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPU, ++ getCpuShares, -1, shares); + } + + +@@ -2198,7 +2309,8 @@ virCgroupGetCpuShares(virCgroupPtr group, unsigned long long *shares) + int + virCgroupSetCpuCfsPeriod(virCgroupPtr group, unsigned long long cfs_period) + { +- VIR_CGROUP_BACKEND_CALL(group, setCpuCfsPeriod, -1, cfs_period); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPU, ++ setCpuCfsPeriod, -1, cfs_period); + } + + +@@ -2213,7 +2325,8 @@ virCgroupSetCpuCfsPeriod(virCgroupPtr group, unsigned long long cfs_period) + int + virCgroupGetCpuCfsPeriod(virCgroupPtr group, unsigned long long *cfs_period) + { +- VIR_CGROUP_BACKEND_CALL(group, getCpuCfsPeriod, -1, cfs_period); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPU, ++ getCpuCfsPeriod, -1, cfs_period); + } + + +@@ -2229,14 +2342,16 @@ virCgroupGetCpuCfsPeriod(virCgroupPtr group, unsigned long long *cfs_period) + int + virCgroupSetCpuCfsQuota(virCgroupPtr group, long long cfs_quota) + { +- VIR_CGROUP_BACKEND_CALL(group, setCpuCfsQuota, -1, cfs_quota); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPU, ++ setCpuCfsQuota, -1, cfs_quota); + } + + + int + virCgroupGetCpuacctPercpuUsage(virCgroupPtr group, char **usage) + { +- VIR_CGROUP_BACKEND_CALL(group, getCpuacctPercpuUsage, -1, usage); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPUACCT, ++ getCpuacctPercpuUsage, -1, usage); + } + + +@@ -2303,7 +2418,16 @@ virCgroupRemoveRecursively(char *grppath) + int + virCgroupRemove(virCgroupPtr group) + { +- return group->backend->remove(group); ++ size_t i; ++ ++ for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) { ++ if (group->backends[i] && ++ group->backends[i]->remove(group) < 0) { ++ return -1; ++ } ++ } ++ ++ return 0; + } + + +@@ -2312,11 +2436,16 @@ virCgroupPathOfAnyController(virCgroupPtr group, + const char *name, + char **keypath) + { ++ size_t i; + int controller; + +- controller = group->backend->getAnyController(group); +- if (controller >= 0) +- return virCgroupPathOfController(group, controller, name, keypath); ++ for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) { ++ if (group->backends[i]) { ++ controller = group->backends[i]->getAnyController(group); ++ if (controller >= 0) ++ return virCgroupPathOfController(group, controller, name, keypath); ++ } ++ } + + virReportSystemError(ENOSYS, "%s", + _("No controllers are mounted")); +@@ -2552,14 +2681,16 @@ virCgroupKillPainfully(virCgroupPtr group) + int + virCgroupGetCpuCfsQuota(virCgroupPtr group, long long *cfs_quota) + { +- VIR_CGROUP_BACKEND_CALL(group, getCpuCfsQuota, -1, cfs_quota); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPU, ++ getCpuCfsQuota, -1, cfs_quota); + } + + + int + virCgroupGetCpuacctUsage(virCgroupPtr group, unsigned long long *usage) + { +- VIR_CGROUP_BACKEND_CALL(group, getCpuacctUsage, -1, usage); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPUACCT, ++ getCpuacctUsage, -1, usage); + } + + +@@ -2567,21 +2698,24 @@ int + virCgroupGetCpuacctStat(virCgroupPtr group, unsigned long long *user, + unsigned long long *sys) + { +- VIR_CGROUP_BACKEND_CALL(group, getCpuacctStat, -1, user, sys); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPUACCT, ++ getCpuacctStat, -1, user, sys); + } + + + int + virCgroupSetFreezerState(virCgroupPtr group, const char *state) + { +- VIR_CGROUP_BACKEND_CALL(group, setFreezerState, -1, state); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_FREEZER, ++ setFreezerState, -1, state); + } + + + int + virCgroupGetFreezerState(virCgroupPtr group, char **state) + { +- VIR_CGROUP_BACKEND_CALL(group, getFreezerState, -1, state); ++ VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_FREEZER, ++ getFreezerState, -1, state); + } + + +@@ -2589,7 +2723,16 @@ int + virCgroupBindMount(virCgroupPtr group, const char *oldroot, + const char *mountopts) + { +- return group->backend->bindMount(group, oldroot, mountopts); ++ size_t i; ++ ++ for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) { ++ if (group->backends[i] && ++ group->backends[i]->bindMount(group, oldroot, mountopts) < 0) { ++ return -1; ++ } ++ } ++ ++ return 0; + } + + +@@ -2598,7 +2741,16 @@ int virCgroupSetOwner(virCgroupPtr cgroup, + gid_t gid, + int controllers) + { +- return cgroup->backend->setOwner(cgroup, uid, gid, controllers); ++ size_t i; ++ ++ for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) { ++ if (cgroup->backends[i] && ++ cgroup->backends[i]->setOwner(cgroup, uid, gid, controllers) < 0) { ++ return -1; ++ } ++ } ++ ++ return 0; + } + + +@@ -2612,13 +2764,24 @@ int virCgroupSetOwner(virCgroupPtr cgroup, + bool + virCgroupSupportsCpuBW(virCgroupPtr cgroup) + { +- VIR_CGROUP_BACKEND_CALL(cgroup, supportsCpuBW, false); ++ VIR_CGROUP_BACKEND_CALL(cgroup, VIR_CGROUP_CONTROLLER_CPU, ++ supportsCpuBW, false); + } + + int + virCgroupHasEmptyTasks(virCgroupPtr cgroup, int controller) + { +- return cgroup->backend->hasEmptyTasks(cgroup, controller); ++ size_t i; ++ ++ for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) { ++ if (cgroup->backends[i]) { ++ int rc = cgroup->backends[i]->hasEmptyTasks(cgroup, controller); ++ if (rc <= 0) ++ return rc; ++ } ++ } ++ ++ return 1; + } + + bool +diff --git a/src/util/vircgroupbackend.c b/src/util/vircgroupbackend.c +index 7ee39ac8ca..2e90781dc3 100644 +--- a/src/util/vircgroupbackend.c ++++ b/src/util/vircgroupbackend.c +@@ -20,6 +20,9 @@ + #include + + #include "vircgroupbackend.h" ++#define __VIR_CGROUP_ALLOW_INCLUDE_PRIV_H__ ++#include "vircgrouppriv.h" ++#undef __VIR_CGROUP_ALLOW_INCLUDE_PRIV_H__ + #include "vircgroupv1.h" + #include "vircgroupv2.h" + #include "virerror.h" +@@ -67,3 +70,20 @@ virCgroupBackendGetAll(void) + } + return virCgroupBackends; + } ++ ++ ++virCgroupBackendPtr ++virCgroupBackendForController(virCgroupPtr group, ++ unsigned int controller) ++{ ++ size_t i; ++ ++ for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) { ++ if (group->backends[i] && ++ group->backends[i]->hasController(group, controller)) { ++ return group->backends[i]; ++ } ++ } ++ ++ return NULL; ++} +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index 86d1539e07..bc60b44643 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -436,12 +436,22 @@ virCgroupBackendRegister(virCgroupBackendPtr backend); + virCgroupBackendPtr * + virCgroupBackendGetAll(void); + +-# define VIR_CGROUP_BACKEND_CALL(group, func, ret, ...) \ +- if (!group->backend->func) { \ ++virCgroupBackendPtr ++virCgroupBackendForController(virCgroupPtr group, ++ unsigned int controller); ++ ++# define VIR_CGROUP_BACKEND_CALL(group, controller, func, ret, ...) \ ++ virCgroupBackendPtr backend = virCgroupBackendForController(group, controller); \ ++ if (!backend) { \ ++ virReportError(VIR_ERR_INTERNAL_ERROR, \ ++ _("failed to get cgroup backend for '%s'"), #func); \ ++ return ret; \ ++ } \ ++ if (!backend->func) { \ + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, \ + _("operation '%s' not supported"), #func); \ + return ret; \ + } \ +- return group->backend->func(group, ##__VA_ARGS__); ++ return backend->func(group, ##__VA_ARGS__); + + #endif /* __VIR_CGROUP_BACKEND_H__ */ +diff --git a/src/util/vircgrouppriv.h b/src/util/vircgrouppriv.h +index 4a0d75ddbc..8f24b0891e 100644 +--- a/src/util/vircgrouppriv.h ++++ b/src/util/vircgrouppriv.h +@@ -56,7 +56,7 @@ typedef virCgroupV2Controller *virCgroupV2ControllerPtr; + struct _virCgroup { + char *path; + +- virCgroupBackendPtr backend; ++ virCgroupBackendPtr backends[VIR_CGROUP_BACKEND_TYPE_LAST]; + + virCgroupV1Controller legacy[VIR_CGROUP_CONTROLLER_LAST]; + virCgroupV2Controller unified; +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-cleanup-controllers-not-managed-by-systemd-on-error.patch b/SOURCES/libvirt-vircgroup-cleanup-controllers-not-managed-by-systemd-on-error.patch new file mode 100644 index 0000000..ac36ae5 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-cleanup-controllers-not-managed-by-systemd-on-error.patch @@ -0,0 +1,77 @@ +From b77a6e6821bc45e4761fc7b23665f585761570ca Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:12 +0200 +Subject: [PATCH] vircgroup: cleanup controllers not managed by systemd on + error +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If virCgroupEnableMissingControllers() fails it could have already +created some directories, we should clean it up as well. + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 1602aa28f820ada66f707cef3e536e8572fbda1e) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 25 +++++++++++++++---------- + 1 file changed, 15 insertions(+), 10 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 64507bf8aa..6aa30a82be 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -1555,6 +1555,7 @@ virCgroupNewMachineSystemd(const char *name, + int rv; + virCgroupPtr init; + VIR_AUTOFREE(char *) path = NULL; ++ virErrorPtr saved = NULL; + + VIR_DEBUG("Trying to setup machine '%s' via systemd", name); + if ((rv = virSystemdCreateMachine(name, +@@ -1588,20 +1589,24 @@ virCgroupNewMachineSystemd(const char *name, + + if (virCgroupEnableMissingControllers(path, pidleader, + controllers, group) < 0) { +- return -1; ++ goto error; + } + +- if (virCgroupAddTask(*group, pidleader) < 0) { +- virErrorPtr saved = virSaveLastError(); +- virCgroupRemove(*group); +- virCgroupFree(group); +- if (saved) { +- virSetError(saved); +- virFreeError(saved); +- } +- } ++ if (virCgroupAddTask(*group, pidleader) < 0) ++ goto error; + + return 0; ++ ++ error: ++ saved = virSaveLastError(); ++ virCgroupRemove(*group); ++ virCgroupFree(group); ++ if (saved) { ++ virSetError(saved); ++ virFreeError(saved); ++ } ++ ++ return -1; + } + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-detect-available-backend-for-cgroup.patch b/SOURCES/libvirt-vircgroup-detect-available-backend-for-cgroup.patch new file mode 100644 index 0000000..790edb2 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-detect-available-backend-for-cgroup.patch @@ -0,0 +1,151 @@ +From 81bf1dade08ee40a9ecc32f5d384fdf35e3edbf3 Mon Sep 17 00:00:00 2001 +Message-Id: <81bf1dade08ee40a9ecc32f5d384fdf35e3edbf3@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:24 +0200 +Subject: [PATCH] vircgroup: detect available backend for cgroup +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We need to update one test-case because now new cgroup object will be +created only if there is any cgroup backend available. + +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit f60af21594801088fff217aebf33b58825bd8a80) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <2815d54d5cffdef81bf9a41136b2d6a7e1d75b55.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 18 ++++++++++++++++++ + src/util/vircgrouppriv.h | 3 +++ + tests/vircgrouptest.c | 38 +++----------------------------------- + 3 files changed, 24 insertions(+), 35 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 47a3b9ed58..15d0cb65ac 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -711,10 +711,28 @@ virCgroupDetect(virCgroupPtr group, + virCgroupPtr parent) + { + int rc; ++ size_t i; ++ virCgroupBackendPtr *backends = virCgroupBackendGetAll(); + + VIR_DEBUG("group=%p controllers=%d path=%s parent=%p", + group, controllers, path, parent); + ++ if (!backends) ++ return -1; ++ ++ for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) { ++ if (backends[i] && backends[i]->available()) { ++ group->backend = backends[i]; ++ break; ++ } ++ } ++ ++ if (!group->backend) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("no cgroup backend available")); ++ return -1; ++ } ++ + if (parent) { + if (virCgroupCopyMounts(group, parent) < 0) + return -1; +diff --git a/src/util/vircgrouppriv.h b/src/util/vircgrouppriv.h +index 046c96c52c..2caa966fee 100644 +--- a/src/util/vircgrouppriv.h ++++ b/src/util/vircgrouppriv.h +@@ -30,6 +30,7 @@ + # define __VIR_CGROUP_PRIV_H__ + + # include "vircgroup.h" ++# include "vircgroupbackend.h" + + struct _virCgroupController { + int type; +@@ -47,6 +48,8 @@ typedef virCgroupController *virCgroupControllerPtr; + struct _virCgroup { + char *path; + ++ virCgroupBackendPtr backend; ++ + virCgroupController controllers[VIR_CGROUP_CONTROLLER_LAST]; + }; + +diff --git a/tests/vircgrouptest.c b/tests/vircgrouptest.c +index 5031a2973d..588a6e824d 100644 +--- a/tests/vircgrouptest.c ++++ b/tests/vircgrouptest.c +@@ -114,16 +114,6 @@ const char *mountsAllInOne[VIR_CGROUP_CONTROLLER_LAST] = { + [VIR_CGROUP_CONTROLLER_BLKIO] = "/not/really/sys/fs/cgroup", + [VIR_CGROUP_CONTROLLER_SYSTEMD] = NULL, + }; +-const char *mountsLogind[VIR_CGROUP_CONTROLLER_LAST] = { +- [VIR_CGROUP_CONTROLLER_CPU] = NULL, +- [VIR_CGROUP_CONTROLLER_CPUACCT] = NULL, +- [VIR_CGROUP_CONTROLLER_CPUSET] = NULL, +- [VIR_CGROUP_CONTROLLER_MEMORY] = NULL, +- [VIR_CGROUP_CONTROLLER_DEVICES] = NULL, +- [VIR_CGROUP_CONTROLLER_FREEZER] = NULL, +- [VIR_CGROUP_CONTROLLER_BLKIO] = NULL, +- [VIR_CGROUP_CONTROLLER_SYSTEMD] = "/not/really/sys/fs/cgroup/systemd", +-}; + + const char *links[VIR_CGROUP_CONTROLLER_LAST] = { + [VIR_CGROUP_CONTROLLER_CPU] = "/not/really/sys/fs/cgroup/cpu", +@@ -147,17 +137,6 @@ const char *linksAllInOne[VIR_CGROUP_CONTROLLER_LAST] = { + [VIR_CGROUP_CONTROLLER_SYSTEMD] = NULL, + }; + +-const char *linksLogind[VIR_CGROUP_CONTROLLER_LAST] = { +- [VIR_CGROUP_CONTROLLER_CPU] = NULL, +- [VIR_CGROUP_CONTROLLER_CPUACCT] = NULL, +- [VIR_CGROUP_CONTROLLER_CPUSET] = NULL, +- [VIR_CGROUP_CONTROLLER_MEMORY] = NULL, +- [VIR_CGROUP_CONTROLLER_DEVICES] = NULL, +- [VIR_CGROUP_CONTROLLER_FREEZER] = NULL, +- [VIR_CGROUP_CONTROLLER_BLKIO] = NULL, +- [VIR_CGROUP_CONTROLLER_SYSTEMD] = NULL, +-}; +- + + struct _detectMountsData { + const char *file; +@@ -555,24 +534,13 @@ static int testCgroupNewForSelfLogind(const void *args ATTRIBUTE_UNUSED) + { + virCgroupPtr cgroup = NULL; + int ret = -1; +- const char *placement[VIR_CGROUP_CONTROLLER_LAST] = { +- [VIR_CGROUP_CONTROLLER_CPU] = NULL, +- [VIR_CGROUP_CONTROLLER_CPUACCT] = NULL, +- [VIR_CGROUP_CONTROLLER_CPUSET] = NULL, +- [VIR_CGROUP_CONTROLLER_MEMORY] = NULL, +- [VIR_CGROUP_CONTROLLER_DEVICES] = NULL, +- [VIR_CGROUP_CONTROLLER_FREEZER] = NULL, +- [VIR_CGROUP_CONTROLLER_BLKIO] = NULL, +- [VIR_CGROUP_CONTROLLER_SYSTEMD] = "/", +- }; + +- if (virCgroupNewSelf(&cgroup) < 0) { +- fprintf(stderr, "Cannot create cgroup for self\n"); ++ if (virCgroupNewSelf(&cgroup) == 0) { ++ fprintf(stderr, "Expected cgroup creation to fail.\n"); + goto cleanup; + } + +- ret = validateCgroup(cgroup, "", mountsLogind, linksLogind, placement); +- ++ ret = 0; + cleanup: + virCgroupFree(&cgroup); + return ret; +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-v1-detect-functions.patch b/SOURCES/libvirt-vircgroup-extract-v1-detect-functions.patch new file mode 100644 index 0000000..845153a --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-v1-detect-functions.patch @@ -0,0 +1,426 @@ +From e1184bde63a7ed92fb99fc4eba4b4abdf6a01815 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:27 +0200 +Subject: [PATCH] vircgroup: extract v1 detect functions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 42a3fcc02bcaec4a0c037a5c59ca63f3fc90e90f) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <3a918fc4eda51c5e9aff5efc93fe14886470578e.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 138 ++----------------------------- + src/util/vircgroupbackend.h | 14 ++++ + src/util/vircgroupv1.c | 158 ++++++++++++++++++++++++++++++++++++ + 3 files changed, 180 insertions(+), 130 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 9d644d37d1..10c99a66fd 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -235,82 +235,6 @@ virCgroupPartitionEscape(char **path) + } + + +-static int +-virCgroupResolveMountLink(const char *mntDir, +- const char *typeStr, +- virCgroupControllerPtr controller) +-{ +- VIR_AUTOFREE(char *) linkSrc = NULL; +- VIR_AUTOFREE(char *) tmp = NULL; +- char *dirName; +- struct stat sb; +- +- if (VIR_STRDUP(tmp, mntDir) < 0) +- return -1; +- +- dirName = strrchr(tmp, '/'); +- if (!dirName) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Missing '/' separator in cgroup mount '%s'"), tmp); +- return -1; +- } +- +- if (!strchr(dirName + 1, ',')) +- return 0; +- +- *dirName = '\0'; +- if (virAsprintf(&linkSrc, "%s/%s", tmp, typeStr) < 0) +- return -1; +- *dirName = '/'; +- +- if (lstat(linkSrc, &sb) < 0) { +- if (errno == ENOENT) { +- VIR_WARN("Controller %s co-mounted at %s is missing symlink at %s", +- typeStr, tmp, linkSrc); +- } else { +- virReportSystemError(errno, _("Cannot stat %s"), linkSrc); +- return -1; +- } +- } else { +- if (!S_ISLNK(sb.st_mode)) { +- VIR_WARN("Expecting a symlink at %s for controller %s", +- linkSrc, typeStr); +- } else { +- VIR_STEAL_PTR(controller->linkPoint, linkSrc); +- } +- } +- +- return 0; +-} +- +- +-static bool +-virCgroupMountOptsMatchController(const char *mntOpts, +- const char *typeStr) +-{ +- const char *tmp = mntOpts; +- int typeLen = strlen(typeStr); +- +- while (tmp) { +- const char *next = strchr(tmp, ','); +- int len; +- if (next) { +- len = next - tmp; +- next++; +- } else { +- len = strlen(tmp); +- } +- +- if (typeLen == len && STREQLEN(typeStr, tmp, len)) +- return true; +- +- tmp = next; +- } +- +- return false; +-} +- +- + /* + * Process /proc/mounts figuring out what controllers are + * mounted and where +@@ -318,7 +242,6 @@ virCgroupMountOptsMatchController(const char *mntOpts, + static int + virCgroupDetectMounts(virCgroupPtr group) + { +- size_t i; + FILE *mounts = NULL; + struct mntent entry; + char buf[CGROUP_MAX_VAL]; +@@ -331,34 +254,11 @@ virCgroupDetectMounts(virCgroupPtr group) + } + + while (getmntent_r(mounts, &entry, buf, sizeof(buf)) != NULL) { +- if (STRNEQ(entry.mnt_type, "cgroup")) +- continue; +- +- for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { +- const char *typestr = virCgroupControllerTypeToString(i); +- +- if (virCgroupMountOptsMatchController(entry.mnt_opts, typestr)) { +- /* Note that the lines in /proc/mounts have the same +- * order than the mount operations, and that there may +- * be duplicates due to bind mounts. This means +- * that the same mount point may be processed more than +- * once. We need to save the results of the last one, +- * and we need to be careful to release the memory used +- * by previous processing. */ +- virCgroupControllerPtr controller = &group->controllers[i]; +- +- VIR_FREE(controller->mountPoint); +- VIR_FREE(controller->linkPoint); +- if (VIR_STRDUP(controller->mountPoint, entry.mnt_dir) < 0) +- goto cleanup; +- +- /* If it is a co-mount it has a filename like "cpu,cpuacct" +- * and we must identify the symlink path */ +- if (virCgroupResolveMountLink(entry.mnt_dir, typestr, +- controller) < 0) { +- goto cleanup; +- } +- } ++ if (group->backend->detectMounts(group, ++ entry.mnt_type, ++ entry.mnt_opts, ++ entry.mnt_dir) < 0) { ++ goto cleanup; + } + } + +@@ -432,7 +332,6 @@ virCgroupDetectPlacement(virCgroupPtr group, + pid_t pid, + const char *path) + { +- size_t i; + FILE *mapping = NULL; + char line[1024]; + int ret = -1; +@@ -472,30 +371,9 @@ virCgroupDetectPlacement(virCgroupPtr group, + controllers++; + selfpath++; + +- for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { +- const char *typestr = virCgroupControllerTypeToString(i); +- +- if (virCgroupMountOptsMatchController(controllers, typestr) && +- group->controllers[i].mountPoint != NULL && +- group->controllers[i].placement == NULL) { +- /* +- * selfpath == "/" + path="" -> "/" +- * selfpath == "/libvirt.service" + path == "" -> "/libvirt.service" +- * selfpath == "/libvirt.service" + path == "foo" -> "/libvirt.service/foo" +- */ +- if (i == VIR_CGROUP_CONTROLLER_SYSTEMD) { +- if (VIR_STRDUP(group->controllers[i].placement, +- selfpath) < 0) +- goto cleanup; +- } else { +- if (virAsprintf(&group->controllers[i].placement, +- "%s%s%s", selfpath, +- (STREQ(selfpath, "/") || +- STREQ(path, "") ? "" : "/"), +- path) < 0) +- goto cleanup; +- } +- } ++ if (group->backend->detectPlacement(group, path, controllers, ++ selfpath) < 0) { ++ goto cleanup; + } + } + +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index 81ee597fc8..fadc7efdcf 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -45,6 +45,18 @@ typedef int + (*virCgroupCopyMountsCB)(virCgroupPtr group, + virCgroupPtr parent); + ++typedef int ++(*virCgroupDetectMountsCB)(virCgroupPtr group, ++ const char *mntType, ++ const char *mntOpts, ++ const char *mntDir); ++ ++typedef int ++(*virCgroupDetectPlacementCB)(virCgroupPtr group, ++ const char *path, ++ const char *controllers, ++ const char *selfpath); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -52,6 +64,8 @@ struct _virCgroupBackend { + virCgroupAvailableCB available; + virCgroupValidateMachineGroupCB validateMachineGroup; + virCgroupCopyMountsCB copyMounts; ++ virCgroupDetectMountsCB detectMounts; ++ virCgroupDetectPlacementCB detectPlacement; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 50b58ab413..bd9f28f6e9 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -23,6 +23,7 @@ + #if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R + # include + #endif ++#include + + #include "internal.h" + +@@ -38,6 +39,7 @@ + #include "virlog.h" + #include "virstring.h" + #include "virsystemd.h" ++#include "virerror.h" + + VIR_LOG_INIT("util.cgroup"); + +@@ -181,12 +183,168 @@ virCgroupV1CopyMounts(virCgroupPtr group, + } + + ++static int ++virCgroupV1ResolveMountLink(const char *mntDir, ++ const char *typeStr, ++ virCgroupControllerPtr controller) ++{ ++ VIR_AUTOFREE(char *) linkSrc = NULL; ++ VIR_AUTOFREE(char *) tmp = NULL; ++ char *dirName; ++ struct stat sb; ++ ++ if (VIR_STRDUP(tmp, mntDir) < 0) ++ return -1; ++ ++ dirName = strrchr(tmp, '/'); ++ if (!dirName) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Missing '/' separator in cgroup mount '%s'"), tmp); ++ return -1; ++ } ++ ++ if (!strchr(dirName + 1, ',')) ++ return 0; ++ ++ *dirName = '\0'; ++ if (virAsprintf(&linkSrc, "%s/%s", tmp, typeStr) < 0) ++ return -1; ++ *dirName = '/'; ++ ++ if (lstat(linkSrc, &sb) < 0) { ++ if (errno == ENOENT) { ++ VIR_WARN("Controller %s co-mounted at %s is missing symlink at %s", ++ typeStr, tmp, linkSrc); ++ } else { ++ virReportSystemError(errno, _("Cannot stat %s"), linkSrc); ++ return -1; ++ } ++ } else { ++ if (!S_ISLNK(sb.st_mode)) { ++ VIR_WARN("Expecting a symlink at %s for controller %s", ++ linkSrc, typeStr); ++ } else { ++ VIR_STEAL_PTR(controller->linkPoint, linkSrc); ++ } ++ } ++ ++ return 0; ++} ++ ++ ++static bool ++virCgroupV1MountOptsMatchController(const char *mntOpts, ++ const char *typeStr) ++{ ++ const char *tmp = mntOpts; ++ int typeLen = strlen(typeStr); ++ ++ while (tmp) { ++ const char *next = strchr(tmp, ','); ++ int len; ++ if (next) { ++ len = next - tmp; ++ next++; ++ } else { ++ len = strlen(tmp); ++ } ++ ++ if (typeLen == len && STREQLEN(typeStr, tmp, len)) ++ return true; ++ ++ tmp = next; ++ } ++ ++ return false; ++} ++ ++ ++static int ++virCgroupV1DetectMounts(virCgroupPtr group, ++ const char *mntType, ++ const char *mntOpts, ++ const char *mntDir) ++{ ++ size_t i; ++ ++ if (STRNEQ(mntType, "cgroup")) ++ return 0; ++ ++ for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { ++ const char *typestr = virCgroupV1ControllerTypeToString(i); ++ ++ if (virCgroupV1MountOptsMatchController(mntOpts, typestr)) { ++ /* Note that the lines in /proc/mounts have the same ++ * order than the mount operations, and that there may ++ * be duplicates due to bind mounts. This means ++ * that the same mount point may be processed more than ++ * once. We need to save the results of the last one, ++ * and we need to be careful to release the memory used ++ * by previous processing. */ ++ virCgroupControllerPtr controller = &group->controllers[i]; ++ ++ VIR_FREE(controller->mountPoint); ++ VIR_FREE(controller->linkPoint); ++ if (VIR_STRDUP(controller->mountPoint, mntDir) < 0) ++ return -1; ++ ++ /* If it is a co-mount it has a filename like "cpu,cpuacct" ++ * and we must identify the symlink path */ ++ if (virCgroupV1ResolveMountLink(mntDir, typestr, controller) < 0) ++ return -1; ++ } ++ } ++ ++ return 0; ++} ++ ++ ++static int ++virCgroupV1DetectPlacement(virCgroupPtr group, ++ const char *path, ++ const char *controllers, ++ const char *selfpath) ++{ ++ size_t i; ++ ++ for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { ++ const char *typestr = virCgroupV1ControllerTypeToString(i); ++ ++ if (virCgroupV1MountOptsMatchController(controllers, typestr) && ++ group->controllers[i].mountPoint != NULL && ++ group->controllers[i].placement == NULL) { ++ /* ++ * selfpath == "/" + path="" -> "/" ++ * selfpath == "/libvirt.service" + path == "" -> "/libvirt.service" ++ * selfpath == "/libvirt.service" + path == "foo" -> "/libvirt.service/foo" ++ */ ++ if (i == VIR_CGROUP_CONTROLLER_SYSTEMD) { ++ if (VIR_STRDUP(group->controllers[i].placement, ++ selfpath) < 0) ++ return -1; ++ } else { ++ if (virAsprintf(&group->controllers[i].placement, ++ "%s%s%s", selfpath, ++ (STREQ(selfpath, "/") || ++ STREQ(path, "") ? "" : "/"), ++ path) < 0) ++ return -1; ++ } ++ } ++ } ++ ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + + .available = virCgroupV1Available, + .validateMachineGroup = virCgroupV1ValidateMachineGroup, + .copyMounts = virCgroupV1CopyMounts, ++ .detectMounts = virCgroupV1DetectMounts, ++ .detectPlacement = virCgroupV1DetectPlacement, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Allow-Deny-AllDevices.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Allow-Deny-AllDevices.patch new file mode 100644 index 0000000..d4dbcdf --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Allow-Deny-AllDevices.patch @@ -0,0 +1,140 @@ +From 4cf3b3d335b83b5feb49e71775b6a8f1fddbbce9 Mon Sep 17 00:00:00 2001 +Message-Id: <4cf3b3d335b83b5feb49e71775b6a8f1fddbbce9@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:55 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1(Allow|Deny)AllDevices +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit fd9a0368b91c425f860115c0451067ee917574d1) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 18 ++---------------- + src/util/vircgroupbackend.h | 9 +++++++++ + src/util/vircgroupv1.c | 31 +++++++++++++++++++++++++++++++ + 3 files changed, 42 insertions(+), 16 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index a30fc6241d..67c68f3dc6 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -1822,10 +1822,7 @@ virCgroupGetCpusetCpus(virCgroupPtr group, char **cpus) + int + virCgroupDenyAllDevices(virCgroupPtr group) + { +- return virCgroupSetValueStr(group, +- VIR_CGROUP_CONTROLLER_DEVICES, +- "devices.deny", +- "a"); ++ VIR_CGROUP_BACKEND_CALL(group, denyAllDevices, -1); + } + + /** +@@ -1845,18 +1842,7 @@ virCgroupDenyAllDevices(virCgroupPtr group) + int + virCgroupAllowAllDevices(virCgroupPtr group, int perms) + { +- int ret = -1; +- +- if (virCgroupAllowDevice(group, 'b', -1, -1, perms) < 0) +- goto cleanup; +- +- if (virCgroupAllowDevice(group, 'c', -1, -1, perms) < 0) +- goto cleanup; +- +- ret = 0; +- +- cleanup: +- return ret; ++ VIR_CGROUP_BACKEND_CALL(group, allowAllDevices, -1, perms); + } + + +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index 04897b5895..436c83f6fa 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -269,6 +269,13 @@ typedef int + int minor, + int perms); + ++typedef int ++(*virCgroupAllowAllDevicesCB)(virCgroupPtr group, ++ int perms); ++ ++typedef int ++(*virCgroupDenyAllDevicesCB)(virCgroupPtr group); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -321,6 +328,8 @@ struct _virCgroupBackend { + + virCgroupAllowDeviceCB allowDevice; + virCgroupDenyDeviceCB denyDevice; ++ virCgroupAllowAllDevicesCB allowAllDevices; ++ virCgroupDenyAllDevicesCB denyAllDevices; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 02cd7ab956..34393812d2 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -1737,6 +1737,35 @@ virCgroupV1DenyDevice(virCgroupPtr group, + } + + ++static int ++virCgroupV1AllowAllDevices(virCgroupPtr group, ++ int perms) ++{ ++ int ret = -1; ++ ++ if (virCgroupV1AllowDevice(group, 'b', -1, -1, perms) < 0) ++ goto cleanup; ++ ++ if (virCgroupV1AllowDevice(group, 'c', -1, -1, perms) < 0) ++ goto cleanup; ++ ++ ret = 0; ++ ++ cleanup: ++ return ret; ++} ++ ++ ++static int ++virCgroupV1DenyAllDevices(virCgroupPtr group) ++{ ++ return virCgroupSetValueStr(group, ++ VIR_CGROUP_CONTROLLER_DEVICES, ++ "devices.deny", ++ "a"); ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + +@@ -1787,6 +1816,8 @@ virCgroupBackend virCgroupV1Backend = { + + .allowDevice = virCgroupV1AllowDevice, + .denyDevice = virCgroupV1DenyDevice, ++ .allowAllDevices = virCgroupV1AllowAllDevices, ++ .denyAllDevices = virCgroupV1DenyAllDevices, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Allow-Deny-Device.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Allow-Deny-Device.patch new file mode 100644 index 0000000..234d5f8 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Allow-Deny-Device.patch @@ -0,0 +1,250 @@ +From 43695c7877a99d12bab96ec17c7d7de250ffc39a Mon Sep 17 00:00:00 2001 +Message-Id: <43695c7877a99d12bab96ec17c7d7de250ffc39a@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:54 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1(Allow|Deny)Device +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 8cbb0c76ba24878229830c8d53b365cf4dc1b54d) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <9a4073085dbeb674b24544aa253960bb2b1b53dc.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 68 +++++++----------------------------- + src/util/vircgroupbackend.h | 17 +++++++++ + src/util/vircgroupv1.c | 69 +++++++++++++++++++++++++++++++++++++ + 3 files changed, 98 insertions(+), 56 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 088e97cb3f..a30fc6241d 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -1875,29 +1875,7 @@ int + virCgroupAllowDevice(virCgroupPtr group, char type, int major, int minor, + int perms) + { +- VIR_AUTOFREE(char *) devstr = NULL; +- VIR_AUTOFREE(char *) majorstr = NULL; +- VIR_AUTOFREE(char *) minorstr = NULL; +- +- if ((major < 0 && VIR_STRDUP(majorstr, "*") < 0) || +- (major >= 0 && virAsprintf(&majorstr, "%i", major) < 0)) +- return -1; +- +- if ((minor < 0 && VIR_STRDUP(minorstr, "*") < 0) || +- (minor >= 0 && virAsprintf(&minorstr, "%i", minor) < 0)) +- return -1; +- +- if (virAsprintf(&devstr, "%c %s:%s %s", type, majorstr, minorstr, +- virCgroupGetDevicePermsString(perms)) < 0) +- return -1; +- +- if (virCgroupSetValueStr(group, +- VIR_CGROUP_CONTROLLER_DEVICES, +- "devices.allow", +- devstr) < 0) +- return -1; +- +- return 0; ++ VIR_CGROUP_BACKEND_CALL(group, allowDevice, -1, type, major, minor, perms); + } + + +@@ -1936,11 +1914,11 @@ virCgroupAllowDevicePath(virCgroupPtr group, + if (!S_ISCHR(sb.st_mode) && !S_ISBLK(sb.st_mode)) + return 1; + +- return virCgroupAllowDevice(group, +- S_ISCHR(sb.st_mode) ? 'c' : 'b', +- major(sb.st_rdev), +- minor(sb.st_rdev), +- perms); ++ VIR_CGROUP_BACKEND_CALL(group, allowDevice, -1, ++ S_ISCHR(sb.st_mode) ? 'c' : 'b', ++ major(sb.st_rdev), ++ minor(sb.st_rdev), ++ perms); + } + + +@@ -1959,29 +1937,7 @@ int + virCgroupDenyDevice(virCgroupPtr group, char type, int major, int minor, + int perms) + { +- VIR_AUTOFREE(char *) devstr = NULL; +- VIR_AUTOFREE(char *) majorstr = NULL; +- VIR_AUTOFREE(char *) minorstr = NULL; +- +- if ((major < 0 && VIR_STRDUP(majorstr, "*") < 0) || +- (major >= 0 && virAsprintf(&majorstr, "%i", major) < 0)) +- return -1; +- +- if ((minor < 0 && VIR_STRDUP(minorstr, "*") < 0) || +- (minor >= 0 && virAsprintf(&minorstr, "%i", minor) < 0)) +- return -1; +- +- if (virAsprintf(&devstr, "%c %s:%s %s", type, majorstr, minorstr, +- virCgroupGetDevicePermsString(perms)) < 0) +- return -1; +- +- if (virCgroupSetValueStr(group, +- VIR_CGROUP_CONTROLLER_DEVICES, +- "devices.deny", +- devstr) < 0) +- return -1; +- +- return 0; ++ VIR_CGROUP_BACKEND_CALL(group, denyDevice, -1, type, major, minor, perms); + } + + +@@ -2020,11 +1976,11 @@ virCgroupDenyDevicePath(virCgroupPtr group, + if (!S_ISCHR(sb.st_mode) && !S_ISBLK(sb.st_mode)) + return 1; + +- return virCgroupDenyDevice(group, +- S_ISCHR(sb.st_mode) ? 'c' : 'b', +- major(sb.st_rdev), +- minor(sb.st_rdev), +- perms); ++ VIR_CGROUP_BACKEND_CALL(group, denyDevice, -1, ++ S_ISCHR(sb.st_mode) ? 'c' : 'b', ++ major(sb.st_rdev), ++ minor(sb.st_rdev), ++ perms); + } + + +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index 27e6b18ea2..04897b5895 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -255,6 +255,20 @@ typedef int + (*virCgroupGetMemSwapUsageCB)(virCgroupPtr group, + unsigned long long *kb); + ++typedef int ++(*virCgroupAllowDeviceCB)(virCgroupPtr group, ++ char type, ++ int major, ++ int minor, ++ int perms); ++ ++typedef int ++(*virCgroupDenyDeviceCB)(virCgroupPtr group, ++ char type, ++ int major, ++ int minor, ++ int perms); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -304,6 +318,9 @@ struct _virCgroupBackend { + virCgroupSetMemSwapHardLimitCB setMemSwapHardLimit; + virCgroupGetMemSwapHardLimitCB getMemSwapHardLimit; + virCgroupGetMemSwapUsageCB getMemSwapUsage; ++ ++ virCgroupAllowDeviceCB allowDevice; ++ virCgroupDenyDeviceCB denyDevice; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 55b1d3ebd0..02cd7ab956 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -1671,6 +1671,72 @@ virCgroupV1GetMemSwapUsage(virCgroupPtr group, + } + + ++static int ++virCgroupV1AllowDevice(virCgroupPtr group, ++ char type, ++ int major, ++ int minor, ++ int perms) ++{ ++ VIR_AUTOFREE(char *) devstr = NULL; ++ VIR_AUTOFREE(char *) majorstr = NULL; ++ VIR_AUTOFREE(char *) minorstr = NULL; ++ ++ if ((major < 0 && VIR_STRDUP(majorstr, "*") < 0) || ++ (major >= 0 && virAsprintf(&majorstr, "%i", major) < 0)) ++ return -1; ++ ++ if ((minor < 0 && VIR_STRDUP(minorstr, "*") < 0) || ++ (minor >= 0 && virAsprintf(&minorstr, "%i", minor) < 0)) ++ return -1; ++ ++ if (virAsprintf(&devstr, "%c %s:%s %s", type, majorstr, minorstr, ++ virCgroupGetDevicePermsString(perms)) < 0) ++ return -1; ++ ++ if (virCgroupSetValueStr(group, ++ VIR_CGROUP_CONTROLLER_DEVICES, ++ "devices.allow", ++ devstr) < 0) ++ return -1; ++ ++ return 0; ++} ++ ++ ++static int ++virCgroupV1DenyDevice(virCgroupPtr group, ++ char type, ++ int major, ++ int minor, ++ int perms) ++{ ++ VIR_AUTOFREE(char *) devstr = NULL; ++ VIR_AUTOFREE(char *) majorstr = NULL; ++ VIR_AUTOFREE(char *) minorstr = NULL; ++ ++ if ((major < 0 && VIR_STRDUP(majorstr, "*") < 0) || ++ (major >= 0 && virAsprintf(&majorstr, "%i", major) < 0)) ++ return -1; ++ ++ if ((minor < 0 && VIR_STRDUP(minorstr, "*") < 0) || ++ (minor >= 0 && virAsprintf(&minorstr, "%i", minor) < 0)) ++ return -1; ++ ++ if (virAsprintf(&devstr, "%c %s:%s %s", type, majorstr, minorstr, ++ virCgroupGetDevicePermsString(perms)) < 0) ++ return -1; ++ ++ if (virCgroupSetValueStr(group, ++ VIR_CGROUP_CONTROLLER_DEVICES, ++ "devices.deny", ++ devstr) < 0) ++ return -1; ++ ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + +@@ -1718,6 +1784,9 @@ virCgroupBackend virCgroupV1Backend = { + .setMemSwapHardLimit = virCgroupV1SetMemSwapHardLimit, + .getMemSwapHardLimit = virCgroupV1GetMemSwapHardLimit, + .getMemSwapUsage = virCgroupV1GetMemSwapUsage, ++ ++ .allowDevice = virCgroupV1AllowDevice, ++ .denyDevice = virCgroupV1DenyDevice, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-BlkioDeviceReadBps.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-BlkioDeviceReadBps.patch new file mode 100644 index 0000000..13c3c14 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-BlkioDeviceReadBps.patch @@ -0,0 +1,181 @@ +From d18c1d955b505493213e540d427868cc74e03c64 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:47 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1(Set|Get)BlkioDeviceReadBps +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 32f199250bd52fe52cba6bfbc3ee6a7f6c88c2ff) + +Conflicts: + src/util/vircgroup.c - missing commit 34e9c29357 + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <562851da4866890cef588cf7f6f890118f3f81f4.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 34 ++----------------------- + src/util/vircgroupbackend.h | 12 +++++++++ + src/util/vircgroupv1.c | 50 +++++++++++++++++++++++++++++++++++++ + 3 files changed, 64 insertions(+), 32 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 4b682d72d7..ab587ea306 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -1419,19 +1419,7 @@ virCgroupSetBlkioDeviceReadBps(virCgroupPtr group, + const char *path, + unsigned long long rbps) + { +- VIR_AUTOFREE(char *) str = NULL; +- VIR_AUTOFREE(char *) blkstr = NULL; +- +- if (!(blkstr = virCgroupGetBlockDevString(path))) +- return -1; +- +- if (virAsprintf(&str, "%s%llu", blkstr, rbps) < 0) +- return -1; +- +- return virCgroupSetValueStr(group, +- VIR_CGROUP_CONTROLLER_BLKIO, +- "blkio.throttle.read_bps_device", +- str); ++ VIR_CGROUP_BACKEND_CALL(group, setBlkioDeviceReadBps, -1, path, rbps); + } + + /** +@@ -1525,25 +1513,7 @@ virCgroupGetBlkioDeviceReadBps(virCgroupPtr group, + const char *path, + unsigned long long *rbps) + { +- VIR_AUTOFREE(char *) str = NULL; +- +- if (virCgroupGetValueForBlkDev(group, +- VIR_CGROUP_CONTROLLER_BLKIO, +- "blkio.throttle.read_bps_device", +- path, +- &str) < 0) +- return -1; +- +- if (!str) { +- *rbps = 0; +- } else if (virStrToLong_ull(str, NULL, 10, rbps) < 0) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Unable to parse '%s' as an integer"), +- str); +- return -1; +- } +- +- return 0; ++ VIR_CGROUP_BACKEND_CALL(group, getBlkioDeviceReadBps, -1, path, rbps); + } + + /** +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index 58e1828e01..3f1055a5d8 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -190,6 +190,16 @@ typedef int + const char *path, + unsigned int *wiops); + ++typedef int ++(*virCgroupSetBlkioDeviceReadBpsCB)(virCgroupPtr group, ++ const char *path, ++ unsigned long long rbps); ++ ++typedef int ++(*virCgroupGetBlkioDeviceReadBpsCB)(virCgroupPtr group, ++ const char *path, ++ unsigned long long *rbps); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -224,6 +234,8 @@ struct _virCgroupBackend { + virCgroupGetBlkioDeviceReadIopsCB getBlkioDeviceReadIops; + virCgroupSetBlkioDeviceWriteIopsCB setBlkioDeviceWriteIops; + virCgroupGetBlkioDeviceWriteIopsCB getBlkioDeviceWriteIops; ++ virCgroupSetBlkioDeviceReadBpsCB setBlkioDeviceReadBps; ++ virCgroupGetBlkioDeviceReadBpsCB getBlkioDeviceReadBps; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 5b0199a89f..e5663ccfb9 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -1282,6 +1282,54 @@ virCgroupV1GetBlkioDeviceWriteIops(virCgroupPtr group, + } + + ++static int ++virCgroupV1SetBlkioDeviceReadBps(virCgroupPtr group, ++ const char *path, ++ unsigned long long rbps) ++{ ++ VIR_AUTOFREE(char *) str = NULL; ++ VIR_AUTOFREE(char *) blkstr = NULL; ++ ++ if (!(blkstr = virCgroupGetBlockDevString(path))) ++ return -1; ++ ++ if (virAsprintf(&str, "%s%llu", blkstr, rbps) < 0) ++ return -1; ++ ++ return virCgroupSetValueStr(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "blkio.throttle.read_bps_device", ++ str); ++} ++ ++ ++static int ++virCgroupV1GetBlkioDeviceReadBps(virCgroupPtr group, ++ const char *path, ++ unsigned long long *rbps) ++{ ++ VIR_AUTOFREE(char *) str = NULL; ++ ++ if (virCgroupGetValueForBlkDev(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "blkio.throttle.read_bps_device", ++ path, ++ &str) < 0) ++ return -1; ++ ++ if (!str) { ++ *rbps = 0; ++ } else if (virStrToLong_ull(str, NULL, 10, rbps) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Unable to parse '%s' as an integer"), ++ str); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + +@@ -1314,6 +1362,8 @@ virCgroupBackend virCgroupV1Backend = { + .getBlkioDeviceReadIops = virCgroupV1GetBlkioDeviceReadIops, + .setBlkioDeviceWriteIops = virCgroupV1SetBlkioDeviceWriteIops, + .getBlkioDeviceWriteIops = virCgroupV1GetBlkioDeviceWriteIops, ++ .setBlkioDeviceReadBps = virCgroupV1SetBlkioDeviceReadBps, ++ .getBlkioDeviceReadBps = virCgroupV1GetBlkioDeviceReadBps, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-BlkioDeviceReadIops.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-BlkioDeviceReadIops.patch new file mode 100644 index 0000000..878a5cd --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-BlkioDeviceReadIops.patch @@ -0,0 +1,181 @@ +From 0528d90148bcacba3fdbaa831ba89e043da94790 Mon Sep 17 00:00:00 2001 +Message-Id: <0528d90148bcacba3fdbaa831ba89e043da94790@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:45 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1(Set|Get)BlkioDeviceReadIops +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit dfaf5c6de1afa04fee1d9d97e79925fcc63682de) + +Conflicts: + src/util/vircgroup.c - missing commit 34e9c29357 + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <52a494fa2de2835abd887d804f4047febc87bb60.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 34 ++----------------------- + src/util/vircgroupbackend.h | 12 +++++++++ + src/util/vircgroupv1.c | 50 +++++++++++++++++++++++++++++++++++++ + 3 files changed, 64 insertions(+), 32 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 83ceb3a9cb..b8cbd95e0c 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -1385,19 +1385,7 @@ virCgroupSetBlkioDeviceReadIops(virCgroupPtr group, + const char *path, + unsigned int riops) + { +- VIR_AUTOFREE(char *) str = NULL; +- VIR_AUTOFREE(char *) blkstr = NULL; +- +- if (!(blkstr = virCgroupGetBlockDevString(path))) +- return -1; +- +- if (virAsprintf(&str, "%s%u", blkstr, riops) < 0) +- return -1; +- +- return virCgroupSetValueStr(group, +- VIR_CGROUP_CONTROLLER_BLKIO, +- "blkio.throttle.read_iops_device", +- str); ++ VIR_CGROUP_BACKEND_CALL(group, setBlkioDeviceReadIops, -1, path, riops); + } + + +@@ -1517,25 +1505,7 @@ virCgroupGetBlkioDeviceReadIops(virCgroupPtr group, + const char *path, + unsigned int *riops) + { +- VIR_AUTOFREE(char *) str = NULL; +- +- if (virCgroupGetValueForBlkDev(group, +- VIR_CGROUP_CONTROLLER_BLKIO, +- "blkio.throttle.read_iops_device", +- path, +- &str) < 0) +- return -1; +- +- if (!str) { +- *riops = 0; +- } else if (virStrToLong_ui(str, NULL, 10, riops) < 0) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Unable to parse '%s' as an integer"), +- str); +- return -1; +- } +- +- return 0; ++ VIR_CGROUP_BACKEND_CALL(group, getBlkioDeviceReadIops, -1, path, riops); + } + + /** +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index aef2a87c61..0b7b4db1a4 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -170,6 +170,16 @@ typedef int + const char *path, + unsigned int *weight); + ++typedef int ++(*virCgroupSetBlkioDeviceReadIopsCB)(virCgroupPtr group, ++ const char *path, ++ unsigned int riops); ++ ++typedef int ++(*virCgroupGetBlkioDeviceReadIopsCB)(virCgroupPtr group, ++ const char *path, ++ unsigned int *riops); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -200,6 +210,8 @@ struct _virCgroupBackend { + virCgroupGetBlkioIoDeviceServicedCB getBlkioIoDeviceServiced; + virCgroupSetBlkioDeviceWeightCB setBlkioDeviceWeight; + virCgroupGetBlkioDeviceWeightCB getBlkioDeviceWeight; ++ virCgroupSetBlkioDeviceReadIopsCB setBlkioDeviceReadIops; ++ virCgroupGetBlkioDeviceReadIopsCB getBlkioDeviceReadIops; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 1e5f38a2ee..47b0c13f38 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -1186,6 +1186,54 @@ virCgroupV1GetBlkioDeviceWeight(virCgroupPtr group, + } + + ++static int ++virCgroupV1SetBlkioDeviceReadIops(virCgroupPtr group, ++ const char *path, ++ unsigned int riops) ++{ ++ VIR_AUTOFREE(char *) str = NULL; ++ VIR_AUTOFREE(char *) blkstr = NULL; ++ ++ if (!(blkstr = virCgroupGetBlockDevString(path))) ++ return -1; ++ ++ if (virAsprintf(&str, "%s%u", blkstr, riops) < 0) ++ return -1; ++ ++ return virCgroupSetValueStr(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "blkio.throttle.read_iops_device", ++ str); ++} ++ ++ ++static int ++virCgroupV1GetBlkioDeviceReadIops(virCgroupPtr group, ++ const char *path, ++ unsigned int *riops) ++{ ++ VIR_AUTOFREE(char *) str = NULL; ++ ++ if (virCgroupGetValueForBlkDev(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "blkio.throttle.read_iops_device", ++ path, ++ &str) < 0) ++ return -1; ++ ++ if (!str) { ++ *riops = 0; ++ } else if (virStrToLong_ui(str, NULL, 10, riops) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Unable to parse '%s' as an integer"), ++ str); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + +@@ -1214,6 +1262,8 @@ virCgroupBackend virCgroupV1Backend = { + .getBlkioIoDeviceServiced = virCgroupV1GetBlkioIoDeviceServiced, + .setBlkioDeviceWeight = virCgroupV1SetBlkioDeviceWeight, + .getBlkioDeviceWeight = virCgroupV1GetBlkioDeviceWeight, ++ .setBlkioDeviceReadIops = virCgroupV1SetBlkioDeviceReadIops, ++ .getBlkioDeviceReadIops = virCgroupV1GetBlkioDeviceReadIops, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-BlkioDeviceWeight.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-BlkioDeviceWeight.patch new file mode 100644 index 0000000..7d870b2 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-BlkioDeviceWeight.patch @@ -0,0 +1,208 @@ +From af26c5b793fcd0206a105e75c6583ddfe57557c2 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:44 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1(Set|Get)BlkioDeviceWeight +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 8f50f9ca24596c838082c7d8da4ffe7104d22b23) + +Conflicts: + src/util/vircgroup.c - missing commit 34e9c29357 + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <1ad5f481f00748a6808760b50f4d1d0116191073.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 36 +++----------------------- + src/util/vircgroupbackend.h | 12 +++++++++ + src/util/vircgrouppriv.h | 6 +++++ + src/util/vircgroupv1.c | 50 +++++++++++++++++++++++++++++++++++++ + 4 files changed, 71 insertions(+), 33 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index fd39144ed2..83ceb3a9cb 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -498,7 +498,7 @@ virCgroupGetValueStr(virCgroupPtr group, + } + + +-static int ++int + virCgroupGetValueForBlkDev(virCgroupPtr group, + int controller, + const char *key, +@@ -1501,19 +1501,7 @@ virCgroupSetBlkioDeviceWeight(virCgroupPtr group, + const char *path, + unsigned int weight) + { +- VIR_AUTOFREE(char *) str = NULL; +- VIR_AUTOFREE(char *) blkstr = NULL; +- +- if (!(blkstr = virCgroupGetBlockDevString(path))) +- return -1; +- +- if (virAsprintf(&str, "%s%d", blkstr, weight) < 0) +- return -1; +- +- return virCgroupSetValueStr(group, +- VIR_CGROUP_CONTROLLER_BLKIO, +- "blkio.weight_device", +- str); ++ VIR_CGROUP_BACKEND_CALL(group, setBlkioDeviceWeight, -1, path, weight); + } + + /** +@@ -1665,25 +1653,7 @@ virCgroupGetBlkioDeviceWeight(virCgroupPtr group, + const char *path, + unsigned int *weight) + { +- VIR_AUTOFREE(char *) str = NULL; +- +- if (virCgroupGetValueForBlkDev(group, +- VIR_CGROUP_CONTROLLER_BLKIO, +- "blkio.weight_device", +- path, +- &str) < 0) +- return -1; +- +- if (!str) { +- *weight = 0; +- } else if (virStrToLong_ui(str, NULL, 10, weight) < 0) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Unable to parse '%s' as an integer"), +- str); +- return -1; +- } +- +- return 0; ++ VIR_CGROUP_BACKEND_CALL(group, getBlkioDeviceWeight, -1, path, weight); + } + + +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index e16d631a0f..aef2a87c61 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -160,6 +160,16 @@ typedef int + long long *requests_read, + long long *requests_write); + ++typedef int ++(*virCgroupSetBlkioDeviceWeightCB)(virCgroupPtr group, ++ const char *path, ++ unsigned int weight); ++ ++typedef int ++(*virCgroupGetBlkioDeviceWeightCB)(virCgroupPtr group, ++ const char *path, ++ unsigned int *weight); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -188,6 +198,8 @@ struct _virCgroupBackend { + virCgroupGetBlkioWeightCB getBlkioWeight; + virCgroupGetBlkioIoServicedCB getBlkioIoServiced; + virCgroupGetBlkioIoDeviceServicedCB getBlkioIoDeviceServiced; ++ virCgroupSetBlkioDeviceWeightCB setBlkioDeviceWeight; ++ virCgroupGetBlkioDeviceWeightCB getBlkioDeviceWeight; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgrouppriv.h b/src/util/vircgrouppriv.h +index 525c288a9a..3a968c1ce2 100644 +--- a/src/util/vircgrouppriv.h ++++ b/src/util/vircgrouppriv.h +@@ -82,6 +82,12 @@ int virCgroupPartitionEscape(char **path); + + char *virCgroupGetBlockDevString(const char *path); + ++int virCgroupGetValueForBlkDev(virCgroupPtr group, ++ int controller, ++ const char *key, ++ const char *path, ++ char **value); ++ + int virCgroupNewPartition(const char *path, + bool create, + int controllers, +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 79c4812aef..1e5f38a2ee 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -1138,6 +1138,54 @@ virCgroupV1GetBlkioIoDeviceServiced(virCgroupPtr group, + } + + ++static int ++virCgroupV1SetBlkioDeviceWeight(virCgroupPtr group, ++ const char *path, ++ unsigned int weight) ++{ ++ VIR_AUTOFREE(char *) str = NULL; ++ VIR_AUTOFREE(char *) blkstr = NULL; ++ ++ if (!(blkstr = virCgroupGetBlockDevString(path))) ++ return -1; ++ ++ if (virAsprintf(&str, "%s%d", blkstr, weight) < 0) ++ return -1; ++ ++ return virCgroupSetValueStr(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "blkio.weight_device", ++ str); ++} ++ ++ ++static int ++virCgroupV1GetBlkioDeviceWeight(virCgroupPtr group, ++ const char *path, ++ unsigned int *weight) ++{ ++ VIR_AUTOFREE(char *) str = NULL; ++ ++ if (virCgroupGetValueForBlkDev(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "blkio.weight_device", ++ path, ++ &str) < 0) ++ return -1; ++ ++ if (!str) { ++ *weight = 0; ++ } else if (virStrToLong_ui(str, NULL, 10, weight) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Unable to parse '%s' as an integer"), ++ str); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + +@@ -1164,6 +1212,8 @@ virCgroupBackend virCgroupV1Backend = { + .getBlkioWeight = virCgroupV1GetBlkioWeight, + .getBlkioIoServiced = virCgroupV1GetBlkioIoServiced, + .getBlkioIoDeviceServiced = virCgroupV1GetBlkioIoDeviceServiced, ++ .setBlkioDeviceWeight = virCgroupV1SetBlkioDeviceWeight, ++ .getBlkioDeviceWeight = virCgroupV1GetBlkioDeviceWeight, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-BlkioDeviceWriteBps.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-BlkioDeviceWriteBps.patch new file mode 100644 index 0000000..273253a --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-BlkioDeviceWriteBps.patch @@ -0,0 +1,181 @@ +From a9c415edc1bc386ac6f4be91e98fe23469b62011 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:48 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1(Set|Get)BlkioDeviceWriteBps +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 02fe32d3aa965b21342bc2dee245e6e8e5ca8bf7) + +Conflicts: + src/util/vircgroup.c - missing commit 34e9c29357 + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <3bbdc28fe71070c8e351679a17d6889b866b46fd.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 34 ++----------------------- + src/util/vircgroupbackend.h | 12 +++++++++ + src/util/vircgroupv1.c | 50 +++++++++++++++++++++++++++++++++++++ + 3 files changed, 64 insertions(+), 32 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index ab587ea306..684bce4997 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -1435,19 +1435,7 @@ virCgroupSetBlkioDeviceWriteBps(virCgroupPtr group, + const char *path, + unsigned long long wbps) + { +- VIR_AUTOFREE(char *) str = NULL; +- VIR_AUTOFREE(char *) blkstr = NULL; +- +- if (!(blkstr = virCgroupGetBlockDevString(path))) +- return -1; +- +- if (virAsprintf(&str, "%s%llu", blkstr, wbps) < 0) +- return -1; +- +- return virCgroupSetValueStr(group, +- VIR_CGROUP_CONTROLLER_BLKIO, +- "blkio.throttle.write_bps_device", +- str); ++ VIR_CGROUP_BACKEND_CALL(group, setBlkioDeviceWriteBps, -1, path, wbps); + } + + +@@ -1529,25 +1517,7 @@ virCgroupGetBlkioDeviceWriteBps(virCgroupPtr group, + const char *path, + unsigned long long *wbps) + { +- VIR_AUTOFREE(char *) str = NULL; +- +- if (virCgroupGetValueForBlkDev(group, +- VIR_CGROUP_CONTROLLER_BLKIO, +- "blkio.throttle.write_bps_device", +- path, +- &str) < 0) +- return -1; +- +- if (!str) { +- *wbps = 0; +- } else if (virStrToLong_ull(str, NULL, 10, wbps) < 0) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Unable to parse '%s' as an integer"), +- str); +- return -1; +- } +- +- return 0; ++ VIR_CGROUP_BACKEND_CALL(group, getBlkioDeviceWriteBps, -1, path, wbps); + } + + /** +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index 3f1055a5d8..67e795a2b7 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -200,6 +200,16 @@ typedef int + const char *path, + unsigned long long *rbps); + ++typedef int ++(*virCgroupSetBlkioDeviceWriteBpsCB)(virCgroupPtr group, ++ const char *path, ++ unsigned long long wbps); ++ ++typedef int ++(*virCgroupGetBlkioDeviceWriteBpsCB)(virCgroupPtr group, ++ const char *path, ++ unsigned long long *wbps); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -236,6 +246,8 @@ struct _virCgroupBackend { + virCgroupGetBlkioDeviceWriteIopsCB getBlkioDeviceWriteIops; + virCgroupSetBlkioDeviceReadBpsCB setBlkioDeviceReadBps; + virCgroupGetBlkioDeviceReadBpsCB getBlkioDeviceReadBps; ++ virCgroupSetBlkioDeviceWriteBpsCB setBlkioDeviceWriteBps; ++ virCgroupGetBlkioDeviceWriteBpsCB getBlkioDeviceWriteBps; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index e5663ccfb9..c044414dfd 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -1330,6 +1330,54 @@ virCgroupV1GetBlkioDeviceReadBps(virCgroupPtr group, + } + + ++static int ++virCgroupV1SetBlkioDeviceWriteBps(virCgroupPtr group, ++ const char *path, ++ unsigned long long wbps) ++{ ++ VIR_AUTOFREE(char *) str = NULL; ++ VIR_AUTOFREE(char *) blkstr = NULL; ++ ++ if (!(blkstr = virCgroupGetBlockDevString(path))) ++ return -1; ++ ++ if (virAsprintf(&str, "%s%llu", blkstr, wbps) < 0) ++ return -1; ++ ++ return virCgroupSetValueStr(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "blkio.throttle.write_bps_device", ++ str); ++} ++ ++ ++static int ++virCgroupV1GetBlkioDeviceWriteBps(virCgroupPtr group, ++ const char *path, ++ unsigned long long *wbps) ++{ ++ VIR_AUTOFREE(char *) str = NULL; ++ ++ if (virCgroupGetValueForBlkDev(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "blkio.throttle.write_bps_device", ++ path, ++ &str) < 0) ++ return -1; ++ ++ if (!str) { ++ *wbps = 0; ++ } else if (virStrToLong_ull(str, NULL, 10, wbps) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Unable to parse '%s' as an integer"), ++ str); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + +@@ -1364,6 +1412,8 @@ virCgroupBackend virCgroupV1Backend = { + .getBlkioDeviceWriteIops = virCgroupV1GetBlkioDeviceWriteIops, + .setBlkioDeviceReadBps = virCgroupV1SetBlkioDeviceReadBps, + .getBlkioDeviceReadBps = virCgroupV1GetBlkioDeviceReadBps, ++ .setBlkioDeviceWriteBps = virCgroupV1SetBlkioDeviceWriteBps, ++ .getBlkioDeviceWriteBps = virCgroupV1GetBlkioDeviceWriteBps, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-BlkioDeviceWriteIops.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-BlkioDeviceWriteIops.patch new file mode 100644 index 0000000..caffe32 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-BlkioDeviceWriteIops.patch @@ -0,0 +1,181 @@ +From b80aeea66090c760fb2863d8bb7d682ff40a8361 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:46 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1(Set|Get)BlkioDeviceWriteIops +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 2edd0bcda65122ba16f92c2b95f06ae7dad072ba) + +Conflicts: + src/util/vircgroup.c - missing commit 34e9c29357 + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <10671a59ba137b61325a9d5a730f53a2032dd49b.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 34 ++----------------------- + src/util/vircgroupbackend.h | 12 +++++++++ + src/util/vircgroupv1.c | 50 +++++++++++++++++++++++++++++++++++++ + 3 files changed, 64 insertions(+), 32 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index b8cbd95e0c..4b682d72d7 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -1402,19 +1402,7 @@ virCgroupSetBlkioDeviceWriteIops(virCgroupPtr group, + const char *path, + unsigned int wiops) + { +- VIR_AUTOFREE(char *) str = NULL; +- VIR_AUTOFREE(char *) blkstr = NULL; +- +- if (!(blkstr = virCgroupGetBlockDevString(path))) +- return -1; +- +- if (virAsprintf(&str, "%s%u", blkstr, wiops) < 0) +- return -1; +- +- return virCgroupSetValueStr(group, +- VIR_CGROUP_CONTROLLER_BLKIO, +- "blkio.throttle.write_iops_device", +- str); ++ VIR_CGROUP_BACKEND_CALL(group, setBlkioDeviceWriteIops, -1, path, wiops); + } + + +@@ -1521,25 +1509,7 @@ virCgroupGetBlkioDeviceWriteIops(virCgroupPtr group, + const char *path, + unsigned int *wiops) + { +- VIR_AUTOFREE(char *) str = NULL; +- +- if (virCgroupGetValueForBlkDev(group, +- VIR_CGROUP_CONTROLLER_BLKIO, +- "blkio.throttle.write_iops_device", +- path, +- &str) < 0) +- return -1; +- +- if (!str) { +- *wiops = 0; +- } else if (virStrToLong_ui(str, NULL, 10, wiops) < 0) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Unable to parse '%s' as an integer"), +- str); +- return -1; +- } +- +- return 0; ++ VIR_CGROUP_BACKEND_CALL(group, getBlkioDeviceWriteIops, -1, path, wiops); + } + + /** +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index 0b7b4db1a4..58e1828e01 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -180,6 +180,16 @@ typedef int + const char *path, + unsigned int *riops); + ++typedef int ++(*virCgroupSetBlkioDeviceWriteIopsCB)(virCgroupPtr group, ++ const char *path, ++ unsigned int wiops); ++ ++typedef int ++(*virCgroupGetBlkioDeviceWriteIopsCB)(virCgroupPtr group, ++ const char *path, ++ unsigned int *wiops); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -212,6 +222,8 @@ struct _virCgroupBackend { + virCgroupGetBlkioDeviceWeightCB getBlkioDeviceWeight; + virCgroupSetBlkioDeviceReadIopsCB setBlkioDeviceReadIops; + virCgroupGetBlkioDeviceReadIopsCB getBlkioDeviceReadIops; ++ virCgroupSetBlkioDeviceWriteIopsCB setBlkioDeviceWriteIops; ++ virCgroupGetBlkioDeviceWriteIopsCB getBlkioDeviceWriteIops; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 47b0c13f38..5b0199a89f 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -1234,6 +1234,54 @@ virCgroupV1GetBlkioDeviceReadIops(virCgroupPtr group, + } + + ++static int ++virCgroupV1SetBlkioDeviceWriteIops(virCgroupPtr group, ++ const char *path, ++ unsigned int wiops) ++{ ++ VIR_AUTOFREE(char *) str = NULL; ++ VIR_AUTOFREE(char *) blkstr = NULL; ++ ++ if (!(blkstr = virCgroupGetBlockDevString(path))) ++ return -1; ++ ++ if (virAsprintf(&str, "%s%u", blkstr, wiops) < 0) ++ return -1; ++ ++ return virCgroupSetValueStr(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "blkio.throttle.write_iops_device", ++ str); ++} ++ ++ ++static int ++virCgroupV1GetBlkioDeviceWriteIops(virCgroupPtr group, ++ const char *path, ++ unsigned int *wiops) ++{ ++ VIR_AUTOFREE(char *) str = NULL; ++ ++ if (virCgroupGetValueForBlkDev(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "blkio.throttle.write_iops_device", ++ path, ++ &str) < 0) ++ return -1; ++ ++ if (!str) { ++ *wiops = 0; ++ } else if (virStrToLong_ui(str, NULL, 10, wiops) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Unable to parse '%s' as an integer"), ++ str); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + +@@ -1264,6 +1312,8 @@ virCgroupBackend virCgroupV1Backend = { + .getBlkioDeviceWeight = virCgroupV1GetBlkioDeviceWeight, + .setBlkioDeviceReadIops = virCgroupV1SetBlkioDeviceReadIops, + .getBlkioDeviceReadIops = virCgroupV1GetBlkioDeviceReadIops, ++ .setBlkioDeviceWriteIops = virCgroupV1SetBlkioDeviceWriteIops, ++ .getBlkioDeviceWriteIops = virCgroupV1GetBlkioDeviceWriteIops, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-BlkioWeight.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-BlkioWeight.patch new file mode 100644 index 0000000..e58c368 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-BlkioWeight.patch @@ -0,0 +1,150 @@ +From 7fae41a63cd97501e3a4bf8fade48949d754f738 Mon Sep 17 00:00:00 2001 +Message-Id: <7fae41a63cd97501e3a4bf8fade48949d754f738@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:41 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1(Set|Get)BlkioWeight +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit c57b0be0cc200abb21cbe0473d96f447fd37b27d) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <23b514919f71ed2a44c04d7f62a031c4edc14365.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 14 ++------------ + src/util/vircgroupbackend.h | 20 ++++++++++++++++++++ + src/util/vircgroupv1.c | 29 +++++++++++++++++++++++++++++ + 3 files changed, 51 insertions(+), 12 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index e57aecb08a..d2ffa8aefe 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -1510,10 +1510,7 @@ virCgroupGetBlkioIoDeviceServiced(virCgroupPtr group, + int + virCgroupSetBlkioWeight(virCgroupPtr group, unsigned int weight) + { +- return virCgroupSetValueU64(group, +- VIR_CGROUP_CONTROLLER_BLKIO, +- "blkio.weight", +- weight); ++ VIR_CGROUP_BACKEND_CALL(group, setBlkioWeight, -1, weight); + } + + +@@ -1528,14 +1525,7 @@ virCgroupSetBlkioWeight(virCgroupPtr group, unsigned int weight) + int + virCgroupGetBlkioWeight(virCgroupPtr group, unsigned int *weight) + { +- unsigned long long tmp; +- int ret; +- ret = virCgroupGetValueU64(group, +- VIR_CGROUP_CONTROLLER_BLKIO, +- "blkio.weight", &tmp); +- if (ret == 0) +- *weight = tmp; +- return ret; ++ VIR_CGROUP_BACKEND_CALL(group, getBlkioWeight, -1, weight); + } + + /** +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index 74af796c2f..ccce65f1e2 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -137,6 +137,14 @@ typedef int + gid_t gid, + int controllers); + ++typedef int ++(*virCgroupSetBlkioWeightCB)(virCgroupPtr group, ++ unsigned int weight); ++ ++typedef int ++(*virCgroupGetBlkioWeightCB)(virCgroupPtr group, ++ unsigned int *weight); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -159,6 +167,10 @@ struct _virCgroupBackend { + virCgroupHasEmptyTasksCB hasEmptyTasks; + virCgroupBindMountCB bindMount; + virCgroupSetOwnerCB setOwner; ++ ++ /* Optional cgroup controller specific callbacks. */ ++ virCgroupSetBlkioWeightCB setBlkioWeight; ++ virCgroupGetBlkioWeightCB getBlkioWeight; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +@@ -169,4 +181,12 @@ virCgroupBackendRegister(virCgroupBackendPtr backend); + virCgroupBackendPtr * + virCgroupBackendGetAll(void); + ++# define VIR_CGROUP_BACKEND_CALL(group, func, ret, ...) \ ++ if (!group->backend->func) { \ ++ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, \ ++ _("operation '%s' not supported"), #func); \ ++ return ret; \ ++ } \ ++ return group->backend->func(group, ##__VA_ARGS__); ++ + #endif /* __VIR_CGROUP_BACKEND_H__ */ +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index c1e2583912..d67b3164ce 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -929,6 +929,32 @@ virCgroupV1SetOwner(virCgroupPtr cgroup, + } + + ++static int ++virCgroupV1SetBlkioWeight(virCgroupPtr group, ++ unsigned int weight) ++{ ++ return virCgroupSetValueU64(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "blkio.weight", ++ weight); ++} ++ ++ ++static int ++virCgroupV1GetBlkioWeight(virCgroupPtr group, ++ unsigned int *weight) ++{ ++ unsigned long long tmp; ++ int ret; ++ ret = virCgroupGetValueU64(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "blkio.weight", &tmp); ++ if (ret == 0) ++ *weight = tmp; ++ return ret; ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + +@@ -950,6 +976,9 @@ virCgroupBackend virCgroupV1Backend = { + .hasEmptyTasks = virCgroupV1HasEmptyTasks, + .bindMount = virCgroupV1BindMount, + .setOwner = virCgroupV1SetOwner, ++ ++ .setBlkioWeight = virCgroupV1SetBlkioWeight, ++ .getBlkioWeight = virCgroupV1GetBlkioWeight, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-CpuCfsPeriod.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-CpuCfsPeriod.patch new file mode 100644 index 0000000..eeb8623 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-CpuCfsPeriod.patch @@ -0,0 +1,142 @@ +From 39640f2e78035b667588513395187a96ae71d6c4 Mon Sep 17 00:00:00 2001 +Message-Id: <39640f2e78035b667588513395187a96ae71d6c4@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:57 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1(Set|Get)CpuCfsPeriod +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit c840448ebbeb3d4c34eafecf9c9c31c86f2f020f) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <93321a564a636498ef3e4144af737bcfc6e0f07a.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 18 ++---------------- + src/util/vircgroupbackend.h | 10 ++++++++++ + src/util/vircgroupv1.c | 32 ++++++++++++++++++++++++++++++++ + 3 files changed, 44 insertions(+), 16 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 953e353ec3..f4d995b22a 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -2227,19 +2227,7 @@ virCgroupGetCpuShares(virCgroupPtr group, unsigned long long *shares) + int + virCgroupSetCpuCfsPeriod(virCgroupPtr group, unsigned long long cfs_period) + { +- /* The cfs_period should be greater or equal than 1ms, and less or equal +- * than 1s. +- */ +- if (cfs_period < 1000 || cfs_period > 1000000) { +- virReportError(VIR_ERR_INVALID_ARG, +- _("cfs_period '%llu' must be in range (1000, 1000000)"), +- cfs_period); +- return -1; +- } +- +- return virCgroupSetValueU64(group, +- VIR_CGROUP_CONTROLLER_CPU, +- "cpu.cfs_period_us", cfs_period); ++ VIR_CGROUP_BACKEND_CALL(group, setCpuCfsPeriod, -1, cfs_period); + } + + +@@ -2254,9 +2242,7 @@ virCgroupSetCpuCfsPeriod(virCgroupPtr group, unsigned long long cfs_period) + int + virCgroupGetCpuCfsPeriod(virCgroupPtr group, unsigned long long *cfs_period) + { +- return virCgroupGetValueU64(group, +- VIR_CGROUP_CONTROLLER_CPU, +- "cpu.cfs_period_us", cfs_period); ++ VIR_CGROUP_BACKEND_CALL(group, getCpuCfsPeriod, -1, cfs_period); + } + + +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index 54fbead8a2..7dc1f77bfd 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -284,6 +284,14 @@ typedef int + (*virCgroupGetCpuSharesCB)(virCgroupPtr group, + unsigned long long *shares); + ++typedef int ++(*virCgroupSetCpuCfsPeriodCB)(virCgroupPtr group, ++ unsigned long long cfs_period); ++ ++typedef int ++(*virCgroupGetCpuCfsPeriodCB)(virCgroupPtr group, ++ unsigned long long *cfs_period); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -341,6 +349,8 @@ struct _virCgroupBackend { + + virCgroupSetCpuSharesCB setCpuShares; + virCgroupGetCpuSharesCB getCpuShares; ++ virCgroupSetCpuCfsPeriodCB setCpuCfsPeriod; ++ virCgroupGetCpuCfsPeriodCB getCpuCfsPeriod; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 537845bafe..dc4cf1e9db 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -1786,6 +1786,36 @@ virCgroupV1GetCpuShares(virCgroupPtr group, + } + + ++static int ++virCgroupV1SetCpuCfsPeriod(virCgroupPtr group, ++ unsigned long long cfs_period) ++{ ++ /* The cfs_period should be greater or equal than 1ms, and less or equal ++ * than 1s. ++ */ ++ if (cfs_period < 1000 || cfs_period > 1000000) { ++ virReportError(VIR_ERR_INVALID_ARG, ++ _("cfs_period '%llu' must be in range (1000, 1000000)"), ++ cfs_period); ++ return -1; ++ } ++ ++ return virCgroupSetValueU64(group, ++ VIR_CGROUP_CONTROLLER_CPU, ++ "cpu.cfs_period_us", cfs_period); ++} ++ ++ ++static int ++virCgroupV1GetCpuCfsPeriod(virCgroupPtr group, ++ unsigned long long *cfs_period) ++{ ++ return virCgroupGetValueU64(group, ++ VIR_CGROUP_CONTROLLER_CPU, ++ "cpu.cfs_period_us", cfs_period); ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + +@@ -1841,6 +1871,8 @@ virCgroupBackend virCgroupV1Backend = { + + .setCpuShares = virCgroupV1SetCpuShares, + .getCpuShares = virCgroupV1GetCpuShares, ++ .setCpuCfsPeriod = virCgroupV1SetCpuCfsPeriod, ++ .getCpuCfsPeriod = virCgroupV1GetCpuCfsPeriod, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-CpuCfsQuota.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-CpuCfsQuota.patch new file mode 100644 index 0000000..6782693 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-CpuCfsQuota.patch @@ -0,0 +1,168 @@ +From 1ae8ce96561e368af7e68d3837d9e794b023c530 Mon Sep 17 00:00:00 2001 +Message-Id: <1ae8ce96561e368af7e68d3837d9e794b023c530@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:58 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1(Set|Get)CpuCfsQuota +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 5436fd75d808ad7b595a06bfd727e8de3283ef1a) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 20 +++----------------- + src/util/vircgroupbackend.h | 10 ++++++++++ + src/util/vircgrouppriv.h | 5 +++++ + src/util/vircgroupv1.c | 32 ++++++++++++++++++++++++++++++++ + 4 files changed, 50 insertions(+), 17 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index f4d995b22a..a3e7954d03 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -559,7 +559,7 @@ virCgroupSetValueI64(virCgroupPtr group, + } + + +-static int ++int + virCgroupGetValueI64(virCgroupPtr group, + int controller, + const char *key, +@@ -2258,19 +2258,7 @@ virCgroupGetCpuCfsPeriod(virCgroupPtr group, unsigned long long *cfs_period) + int + virCgroupSetCpuCfsQuota(virCgroupPtr group, long long cfs_quota) + { +- /* The cfs_quota should be greater or equal than 1ms */ +- if (cfs_quota >= 0 && +- (cfs_quota < 1000 || +- cfs_quota > ULLONG_MAX / 1000)) { +- virReportError(VIR_ERR_INVALID_ARG, +- _("cfs_quota '%lld' must be in range (1000, %llu)"), +- cfs_quota, ULLONG_MAX / 1000); +- return -1; +- } +- +- return virCgroupSetValueI64(group, +- VIR_CGROUP_CONTROLLER_CPU, +- "cpu.cfs_quota_us", cfs_quota); ++ VIR_CGROUP_BACKEND_CALL(group, setCpuCfsQuota, -1, cfs_quota); + } + + +@@ -2594,9 +2582,7 @@ virCgroupKillPainfully(virCgroupPtr group) + int + virCgroupGetCpuCfsQuota(virCgroupPtr group, long long *cfs_quota) + { +- return virCgroupGetValueI64(group, +- VIR_CGROUP_CONTROLLER_CPU, +- "cpu.cfs_quota_us", cfs_quota); ++ VIR_CGROUP_BACKEND_CALL(group, getCpuCfsQuota, -1, cfs_quota); + } + + +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index 7dc1f77bfd..f7c230db76 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -292,6 +292,14 @@ typedef int + (*virCgroupGetCpuCfsPeriodCB)(virCgroupPtr group, + unsigned long long *cfs_period); + ++typedef int ++(*virCgroupSetCpuCfsQuotaCB)(virCgroupPtr group, ++ long long cfs_quota); ++ ++typedef int ++(*virCgroupGetCpuCfsQuotaCB)(virCgroupPtr group, ++ long long *cfs_quota); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -351,6 +359,8 @@ struct _virCgroupBackend { + virCgroupGetCpuSharesCB getCpuShares; + virCgroupSetCpuCfsPeriodCB setCpuCfsPeriod; + virCgroupGetCpuCfsPeriodCB getCpuCfsPeriod; ++ virCgroupSetCpuCfsQuotaCB setCpuCfsQuota; ++ virCgroupGetCpuCfsQuotaCB getCpuCfsQuota; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgrouppriv.h b/src/util/vircgrouppriv.h +index 7b985280e1..38c911e8ed 100644 +--- a/src/util/vircgrouppriv.h ++++ b/src/util/vircgrouppriv.h +@@ -78,6 +78,11 @@ int virCgroupSetValueI64(virCgroupPtr group, + const char *key, + long long int value); + ++int virCgroupGetValueI64(virCgroupPtr group, ++ int controller, ++ const char *key, ++ long long int *value); ++ + int virCgroupPartitionEscape(char **path); + + char *virCgroupGetBlockDevString(const char *path); +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index dc4cf1e9db..25f7376026 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -1816,6 +1816,36 @@ virCgroupV1GetCpuCfsPeriod(virCgroupPtr group, + } + + ++static int ++virCgroupV1SetCpuCfsQuota(virCgroupPtr group, ++ long long cfs_quota) ++{ ++ /* The cfs_quota should be greater or equal than 1ms */ ++ if (cfs_quota >= 0 && ++ (cfs_quota < 1000 || ++ cfs_quota > ULLONG_MAX / 1000)) { ++ virReportError(VIR_ERR_INVALID_ARG, ++ _("cfs_quota '%lld' must be in range (1000, %llu)"), ++ cfs_quota, ULLONG_MAX / 1000); ++ return -1; ++ } ++ ++ return virCgroupSetValueI64(group, ++ VIR_CGROUP_CONTROLLER_CPU, ++ "cpu.cfs_quota_us", cfs_quota); ++} ++ ++ ++static int ++virCgroupV1GetCpuCfsQuota(virCgroupPtr group, ++ long long *cfs_quota) ++{ ++ return virCgroupGetValueI64(group, ++ VIR_CGROUP_CONTROLLER_CPU, ++ "cpu.cfs_quota_us", cfs_quota); ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + +@@ -1873,6 +1903,8 @@ virCgroupBackend virCgroupV1Backend = { + .getCpuShares = virCgroupV1GetCpuShares, + .setCpuCfsPeriod = virCgroupV1SetCpuCfsPeriod, + .getCpuCfsPeriod = virCgroupV1GetCpuCfsPeriod, ++ .setCpuCfsQuota = virCgroupV1SetCpuCfsQuota, ++ .getCpuCfsQuota = virCgroupV1GetCpuCfsQuota, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-CpuShares.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-CpuShares.patch new file mode 100644 index 0000000..7ca2ec0 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-CpuShares.patch @@ -0,0 +1,123 @@ +From 86865e9638ec63808b1f68e4bd9b4896b5438ece Mon Sep 17 00:00:00 2001 +Message-Id: <86865e9638ec63808b1f68e4bd9b4896b5438ece@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:56 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1(Set|Get)CpuShares +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 857aac1f55bc1c44be4c03c4b721632caedd2a23) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 8 ++------ + src/util/vircgroupbackend.h | 11 +++++++++++ + src/util/vircgroupv1.c | 23 +++++++++++++++++++++++ + 3 files changed, 36 insertions(+), 6 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 67c68f3dc6..953e353ec3 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -2205,18 +2205,14 @@ virCgroupGetDomainTotalCpuStats(virCgroupPtr group, + int + virCgroupSetCpuShares(virCgroupPtr group, unsigned long long shares) + { +- return virCgroupSetValueU64(group, +- VIR_CGROUP_CONTROLLER_CPU, +- "cpu.shares", shares); ++ VIR_CGROUP_BACKEND_CALL(group, setCpuShares, -1, shares); + } + + + int + virCgroupGetCpuShares(virCgroupPtr group, unsigned long long *shares) + { +- return virCgroupGetValueU64(group, +- VIR_CGROUP_CONTROLLER_CPU, +- "cpu.shares", shares); ++ VIR_CGROUP_BACKEND_CALL(group, getCpuShares, -1, shares); + } + + +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index 436c83f6fa..54fbead8a2 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -276,6 +276,14 @@ typedef int + typedef int + (*virCgroupDenyAllDevicesCB)(virCgroupPtr group); + ++typedef int ++(*virCgroupSetCpuSharesCB)(virCgroupPtr group, ++ unsigned long long shares); ++ ++typedef int ++(*virCgroupGetCpuSharesCB)(virCgroupPtr group, ++ unsigned long long *shares); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -330,6 +338,9 @@ struct _virCgroupBackend { + virCgroupDenyDeviceCB denyDevice; + virCgroupAllowAllDevicesCB allowAllDevices; + virCgroupDenyAllDevicesCB denyAllDevices; ++ ++ virCgroupSetCpuSharesCB setCpuShares; ++ virCgroupGetCpuSharesCB getCpuShares; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 34393812d2..537845bafe 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -1766,6 +1766,26 @@ virCgroupV1DenyAllDevices(virCgroupPtr group) + } + + ++static int ++virCgroupV1SetCpuShares(virCgroupPtr group, ++ unsigned long long shares) ++{ ++ return virCgroupSetValueU64(group, ++ VIR_CGROUP_CONTROLLER_CPU, ++ "cpu.shares", shares); ++} ++ ++ ++static int ++virCgroupV1GetCpuShares(virCgroupPtr group, ++ unsigned long long *shares) ++{ ++ return virCgroupGetValueU64(group, ++ VIR_CGROUP_CONTROLLER_CPU, ++ "cpu.shares", shares); ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + +@@ -1818,6 +1838,9 @@ virCgroupBackend virCgroupV1Backend = { + .denyDevice = virCgroupV1DenyDevice, + .allowAllDevices = virCgroupV1AllowAllDevices, + .denyAllDevices = virCgroupV1DenyAllDevices, ++ ++ .setCpuShares = virCgroupV1SetCpuShares, ++ .getCpuShares = virCgroupV1GetCpuShares, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-CpusetCpus.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-CpusetCpus.patch new file mode 100644 index 0000000..0f05e83 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-CpusetCpus.patch @@ -0,0 +1,126 @@ +From d45a116567b6ad1cc87060651a4d1c8d83384ba8 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:05 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1(Set|Get)CpusetCpus +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 2b09065e0fb4b40e05a46f0592d978d3cb72278f) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 10 ++-------- + src/util/vircgroupbackend.h | 10 ++++++++++ + src/util/vircgroupv1.c | 24 ++++++++++++++++++++++++ + 3 files changed, 36 insertions(+), 8 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 1a5ed472df..b159bda1bb 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -1772,10 +1772,7 @@ virCgroupGetCpusetMemoryMigrate(virCgroupPtr group, bool *migrate) + int + virCgroupSetCpusetCpus(virCgroupPtr group, const char *cpus) + { +- return virCgroupSetValueStr(group, +- VIR_CGROUP_CONTROLLER_CPUSET, +- "cpuset.cpus", +- cpus); ++ VIR_CGROUP_BACKEND_CALL(group, setCpusetCpus, -1, cpus); + } + + +@@ -1790,10 +1787,7 @@ virCgroupSetCpusetCpus(virCgroupPtr group, const char *cpus) + int + virCgroupGetCpusetCpus(virCgroupPtr group, char **cpus) + { +- return virCgroupGetValueStr(group, +- VIR_CGROUP_CONTROLLER_CPUSET, +- "cpuset.cpus", +- cpus); ++ VIR_CGROUP_BACKEND_CALL(group, getCpusetCpus, -1, cpus); + } + + +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index d4e4c4a6cc..1c5744ef76 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -340,6 +340,14 @@ typedef int + (*virCgroupGetCpusetMemoryMigrateCB)(virCgroupPtr group, + bool *migrate); + ++typedef int ++(*virCgroupSetCpusetCpusCB)(virCgroupPtr group, ++ const char *cpus); ++ ++typedef int ++(*virCgroupGetCpusetCpusCB)(virCgroupPtr group, ++ char **cpus); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -414,6 +422,8 @@ struct _virCgroupBackend { + virCgroupGetCpusetMemsCB getCpusetMems; + virCgroupSetCpusetMemoryMigrateCB setCpusetMemoryMigrate; + virCgroupGetCpusetMemoryMigrateCB getCpusetMemoryMigrate; ++ virCgroupSetCpusetCpusCB setCpusetCpus; ++ virCgroupGetCpusetCpusCB getCpusetCpus; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 3a41899dd8..54e7d6ea9a 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -1996,6 +1996,28 @@ virCgroupV1GetCpusetMemoryMigrate(virCgroupPtr group, + } + + ++static int ++virCgroupV1SetCpusetCpus(virCgroupPtr group, ++ const char *cpus) ++{ ++ return virCgroupSetValueStr(group, ++ VIR_CGROUP_CONTROLLER_CPUSET, ++ "cpuset.cpus", ++ cpus); ++} ++ ++ ++static int ++virCgroupV1GetCpusetCpus(virCgroupPtr group, ++ char **cpus) ++{ ++ return virCgroupGetValueStr(group, ++ VIR_CGROUP_CONTROLLER_CPUSET, ++ "cpuset.cpus", ++ cpus); ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + +@@ -2068,6 +2090,8 @@ virCgroupBackend virCgroupV1Backend = { + .getCpusetMems = virCgroupV1GetCpusetMems, + .setCpusetMemoryMigrate = virCgroupV1SetCpusetMemoryMigrate, + .getCpusetMemoryMigrate = virCgroupV1GetCpusetMemoryMigrate, ++ .setCpusetCpus = virCgroupV1SetCpusetCpus, ++ .getCpusetCpus = virCgroupV1GetCpusetCpus, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-CpusetMemoryMigrate.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-CpusetMemoryMigrate.patch new file mode 100644 index 0000000..0b0a5c9 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-CpusetMemoryMigrate.patch @@ -0,0 +1,132 @@ +From e8af2c7b172894ae3cfacd6de98b01af63947b05 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:04 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1(Set|Get)CpusetMemoryMigrate +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 7f3aedacac33fd4775d7def3734422108d6cd93e) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <0067ed0a20d90451ab63112dc273ddb8344569ca.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 13 ++----------- + src/util/vircgroupbackend.h | 10 ++++++++++ + src/util/vircgroupv1.c | 27 +++++++++++++++++++++++++++ + 3 files changed, 39 insertions(+), 11 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 700e597157..1a5ed472df 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -1742,10 +1742,7 @@ virCgroupGetCpusetMems(virCgroupPtr group, char **mems) + int + virCgroupSetCpusetMemoryMigrate(virCgroupPtr group, bool migrate) + { +- return virCgroupSetValueStr(group, +- VIR_CGROUP_CONTROLLER_CPUSET, +- "cpuset.memory_migrate", +- migrate ? "1" : "0"); ++ VIR_CGROUP_BACKEND_CALL(group, setCpusetMemoryMigrate, -1, migrate); + } + + +@@ -1760,13 +1757,7 @@ virCgroupSetCpusetMemoryMigrate(virCgroupPtr group, bool migrate) + int + virCgroupGetCpusetMemoryMigrate(virCgroupPtr group, bool *migrate) + { +- unsigned long long value = 0; +- int ret = virCgroupGetValueU64(group, +- VIR_CGROUP_CONTROLLER_CPUSET, +- "cpuset.memory_migrate", +- &value); +- *migrate = !!value; +- return ret; ++ VIR_CGROUP_BACKEND_CALL(group, getCpusetMemoryMigrate, -1, migrate); + } + + +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index 35221e90df..d4e4c4a6cc 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -332,6 +332,14 @@ typedef int + (*virCgroupGetCpusetMemsCB)(virCgroupPtr group, + char **mems); + ++typedef int ++(*virCgroupSetCpusetMemoryMigrateCB)(virCgroupPtr group, ++ bool migrate); ++ ++typedef int ++(*virCgroupGetCpusetMemoryMigrateCB)(virCgroupPtr group, ++ bool *migrate); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -404,6 +412,8 @@ struct _virCgroupBackend { + + virCgroupSetCpusetMemsCB setCpusetMems; + virCgroupGetCpusetMemsCB getCpusetMems; ++ virCgroupSetCpusetMemoryMigrateCB setCpusetMemoryMigrate; ++ virCgroupGetCpusetMemoryMigrateCB getCpusetMemoryMigrate; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index be9a6b82b4..3a41899dd8 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -1971,6 +1971,31 @@ virCgroupV1GetCpusetMems(virCgroupPtr group, + } + + ++static int ++virCgroupV1SetCpusetMemoryMigrate(virCgroupPtr group, ++ bool migrate) ++{ ++ return virCgroupSetValueStr(group, ++ VIR_CGROUP_CONTROLLER_CPUSET, ++ "cpuset.memory_migrate", ++ migrate ? "1" : "0"); ++} ++ ++ ++static int ++virCgroupV1GetCpusetMemoryMigrate(virCgroupPtr group, ++ bool *migrate) ++{ ++ unsigned long long value = 0; ++ int ret = virCgroupGetValueU64(group, ++ VIR_CGROUP_CONTROLLER_CPUSET, ++ "cpuset.memory_migrate", ++ &value); ++ *migrate = !!value; ++ return ret; ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + +@@ -2041,6 +2066,8 @@ virCgroupBackend virCgroupV1Backend = { + + .setCpusetMems = virCgroupV1SetCpusetMems, + .getCpusetMems = virCgroupV1GetCpusetMems, ++ .setCpusetMemoryMigrate = virCgroupV1SetCpusetMemoryMigrate, ++ .getCpusetMemoryMigrate = virCgroupV1GetCpusetMemoryMigrate, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-CpusetMems.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-CpusetMems.patch new file mode 100644 index 0000000..4577480 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-CpusetMems.patch @@ -0,0 +1,128 @@ +From 1f5aa6a591ba44492813f5a1a92d0fd2480ae3e7 Mon Sep 17 00:00:00 2001 +Message-Id: <1f5aa6a591ba44492813f5a1a92d0fd2480ae3e7@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:03 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1(Set|Get)CpusetMems +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 41510b1b74b9d15a64aaefa83826ddf00c999fe0) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <163d30216cc48d77abac54b014faa779c64aa629.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 10 ++-------- + src/util/vircgroupbackend.h | 11 +++++++++++ + src/util/vircgroupv1.c | 25 +++++++++++++++++++++++++ + 3 files changed, 38 insertions(+), 8 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 8b14c053e9..700e597157 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -1712,10 +1712,7 @@ virCgroupGetMemSwapUsage(virCgroupPtr group, unsigned long long *kb) + int + virCgroupSetCpusetMems(virCgroupPtr group, const char *mems) + { +- return virCgroupSetValueStr(group, +- VIR_CGROUP_CONTROLLER_CPUSET, +- "cpuset.mems", +- mems); ++ VIR_CGROUP_BACKEND_CALL(group, setCpusetMems, -1, mems); + } + + +@@ -1730,10 +1727,7 @@ virCgroupSetCpusetMems(virCgroupPtr group, const char *mems) + int + virCgroupGetCpusetMems(virCgroupPtr group, char **mems) + { +- return virCgroupGetValueStr(group, +- VIR_CGROUP_CONTROLLER_CPUSET, +- "cpuset.mems", +- mems); ++ VIR_CGROUP_BACKEND_CALL(group, getCpusetMems, -1, mems); + } + + +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index 2c16706c96..35221e90df 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -324,6 +324,14 @@ typedef int + (*virCgroupGetFreezerStateCB)(virCgroupPtr group, + char **state); + ++typedef int ++(*virCgroupSetCpusetMemsCB)(virCgroupPtr group, ++ const char *mems); ++ ++typedef int ++(*virCgroupGetCpusetMemsCB)(virCgroupPtr group, ++ char **mems); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -393,6 +401,9 @@ struct _virCgroupBackend { + + virCgroupSetFreezerStateCB setFreezerState; + virCgroupGetFreezerStateCB getFreezerState; ++ ++ virCgroupSetCpusetMemsCB setCpusetMems; ++ virCgroupGetCpusetMemsCB getCpusetMems; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 7580f8b756..be9a6b82b4 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -1949,6 +1949,28 @@ virCgroupV1GetFreezerState(virCgroupPtr group, + } + + ++static int ++virCgroupV1SetCpusetMems(virCgroupPtr group, ++ const char *mems) ++{ ++ return virCgroupSetValueStr(group, ++ VIR_CGROUP_CONTROLLER_CPUSET, ++ "cpuset.mems", ++ mems); ++} ++ ++ ++static int ++virCgroupV1GetCpusetMems(virCgroupPtr group, ++ char **mems) ++{ ++ return virCgroupGetValueStr(group, ++ VIR_CGROUP_CONTROLLER_CPUSET, ++ "cpuset.mems", ++ mems); ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + +@@ -2016,6 +2038,9 @@ virCgroupBackend virCgroupV1Backend = { + + .setFreezerState = virCgroupV1SetFreezerState, + .getFreezerState = virCgroupV1GetFreezerState, ++ ++ .setCpusetMems = virCgroupV1SetCpusetMems, ++ .getCpusetMems = virCgroupV1GetCpusetMems, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-FreezerState.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-FreezerState.patch new file mode 100644 index 0000000..c2bf1c6 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-FreezerState.patch @@ -0,0 +1,123 @@ +From c68fdfdc5432ec922ca9ead1e3a0880a6112fea6 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:02 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1(Set|Get)FreezerState +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 269a8e2718f96d5c015ad5d792fdf6759b7faee5) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 8 ++------ + src/util/vircgroupbackend.h | 11 +++++++++++ + src/util/vircgroupv1.c | 23 +++++++++++++++++++++++ + 3 files changed, 36 insertions(+), 6 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 090fe140bb..8b14c053e9 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -2603,18 +2603,14 @@ virCgroupGetCpuacctStat(virCgroupPtr group, unsigned long long *user, + int + virCgroupSetFreezerState(virCgroupPtr group, const char *state) + { +- return virCgroupSetValueStr(group, +- VIR_CGROUP_CONTROLLER_FREEZER, +- "freezer.state", state); ++ VIR_CGROUP_BACKEND_CALL(group, setFreezerState, -1, state); + } + + + int + virCgroupGetFreezerState(virCgroupPtr group, char **state) + { +- return virCgroupGetValueStr(group, +- VIR_CGROUP_CONTROLLER_FREEZER, +- "freezer.state", state); ++ VIR_CGROUP_BACKEND_CALL(group, getFreezerState, -1, state); + } + + +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index 3e3a73777d..2c16706c96 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -316,6 +316,14 @@ typedef int + unsigned long long *user, + unsigned long long *sys); + ++typedef int ++(*virCgroupSetFreezerStateCB)(virCgroupPtr group, ++ const char *state); ++ ++typedef int ++(*virCgroupGetFreezerStateCB)(virCgroupPtr group, ++ char **state); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -382,6 +390,9 @@ struct _virCgroupBackend { + virCgroupGetCpuacctUsageCB getCpuacctUsage; + virCgroupGetCpuacctPercpuUsageCB getCpuacctPercpuUsage; + virCgroupGetCpuacctStatCB getCpuacctStat; ++ ++ virCgroupSetFreezerStateCB setFreezerState; ++ virCgroupGetFreezerStateCB getFreezerState; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 23a91adf60..7580f8b756 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -1929,6 +1929,26 @@ virCgroupV1GetCpuacctStat(virCgroupPtr group, + } + + ++static int ++virCgroupV1SetFreezerState(virCgroupPtr group, ++ const char *state) ++{ ++ return virCgroupSetValueStr(group, ++ VIR_CGROUP_CONTROLLER_FREEZER, ++ "freezer.state", state); ++} ++ ++ ++static int ++virCgroupV1GetFreezerState(virCgroupPtr group, ++ char **state) ++{ ++ return virCgroupGetValueStr(group, ++ VIR_CGROUP_CONTROLLER_FREEZER, ++ "freezer.state", state); ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + +@@ -1993,6 +2013,9 @@ virCgroupBackend virCgroupV1Backend = { + .getCpuacctUsage = virCgroupV1GetCpuacctUsage, + .getCpuacctPercpuUsage = virCgroupV1GetCpuacctPercpuUsage, + .getCpuacctStat = virCgroupV1GetCpuacctStat, ++ ++ .setFreezerState = virCgroupV1SetFreezerState, ++ .getFreezerState = virCgroupV1GetFreezerState, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-Memory-Limit.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-Memory-Limit.patch new file mode 100644 index 0000000..c316c2d --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1-Set-Get-Memory-Limit.patch @@ -0,0 +1,478 @@ +From 5101d214a63b31847f80048d4ee34b5e62176ddd Mon Sep 17 00:00:00 2001 +Message-Id: <5101d214a63b31847f80048d4ee34b5e62176ddd@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:52 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1(Set|Get)Memory*Limit +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +They all need virCgroupV1GetMemoryUnlimitedKB() so it's easier to +move them in one commit. + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 900c58b7f963d5054921e31bbd0b6005155b284a) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 128 ++------------------------- + src/util/vircgroupbackend.h | 30 +++++++ + src/util/vircgrouppriv.h | 6 ++ + src/util/vircgroupv1.c | 168 ++++++++++++++++++++++++++++++++++++ + 4 files changed, 211 insertions(+), 121 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index ed7252243c..6708eef0da 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -634,7 +634,7 @@ virCgroupMakeGroup(virCgroupPtr parent, + * + * Returns 0 on success, -1 on error + */ +-static int ++int + virCgroupNew(pid_t pid, + const char *path, + virCgroupPtr parent, +@@ -1537,51 +1537,6 @@ virCgroupGetBlkioDeviceWeight(virCgroupPtr group, + } + + +-/* +- * Retrieve the "memory.limit_in_bytes" value from the memory controller +- * root dir. This value cannot be modified by userspace and therefore +- * is the maximum limit value supported by cgroups on the local system. +- * Returns this value scaled to KB or falls back to the original +- * VIR_DOMAIN_MEMORY_PARAM_UNLIMITED. Either way, remember the return +- * value to avoid unnecessary cgroup filesystem access. +- */ +-static unsigned long long int virCgroupMemoryUnlimitedKB; +-static virOnceControl virCgroupMemoryOnce = VIR_ONCE_CONTROL_INITIALIZER; +- +-static void +-virCgroupMemoryOnceInit(void) +-{ +- virCgroupPtr group; +- unsigned long long int mem_unlimited = 0ULL; +- +- if (virCgroupNew(-1, "/", NULL, -1, &group) < 0) +- goto cleanup; +- +- if (!virCgroupHasController(group, VIR_CGROUP_CONTROLLER_MEMORY)) +- goto cleanup; +- +- ignore_value(virCgroupGetValueU64(group, +- VIR_CGROUP_CONTROLLER_MEMORY, +- "memory.limit_in_bytes", +- &mem_unlimited)); +- cleanup: +- virCgroupFree(&group); +- virCgroupMemoryUnlimitedKB = mem_unlimited >> 10; +-} +- +-static unsigned long long int +-virCgroupGetMemoryUnlimitedKB(void) +-{ +- if (virOnce(&virCgroupMemoryOnce, virCgroupMemoryOnceInit) < 0) +- VIR_DEBUG("Init failed, will fall back to defaults."); +- +- if (virCgroupMemoryUnlimitedKB) +- return virCgroupMemoryUnlimitedKB; +- else +- return VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; +-} +- +- + /** + * virCgroupSetMemory: + * +@@ -1652,7 +1607,7 @@ virCgroupGetMemoryUsage(virCgroupPtr group, unsigned long *kb) + int + virCgroupSetMemoryHardLimit(virCgroupPtr group, unsigned long long kb) + { +- return virCgroupSetMemory(group, kb); ++ VIR_CGROUP_BACKEND_CALL(group, setMemoryHardLimit, -1, kb); + } + + +@@ -1667,18 +1622,7 @@ virCgroupSetMemoryHardLimit(virCgroupPtr group, unsigned long long kb) + int + virCgroupGetMemoryHardLimit(virCgroupPtr group, unsigned long long *kb) + { +- long long unsigned int limit_in_bytes; +- +- if (virCgroupGetValueU64(group, +- VIR_CGROUP_CONTROLLER_MEMORY, +- "memory.limit_in_bytes", &limit_in_bytes) < 0) +- return -1; +- +- *kb = limit_in_bytes >> 10; +- if (*kb >= virCgroupGetMemoryUnlimitedKB()) +- *kb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; +- +- return 0; ++ VIR_CGROUP_BACKEND_CALL(group, getMemoryHardLimit, -1, kb); + } + + +@@ -1693,25 +1637,7 @@ virCgroupGetMemoryHardLimit(virCgroupPtr group, unsigned long long *kb) + int + virCgroupSetMemorySoftLimit(virCgroupPtr group, unsigned long long kb) + { +- unsigned long long maxkb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; +- +- if (kb > maxkb) { +- virReportError(VIR_ERR_INVALID_ARG, +- _("Memory '%llu' must be less than %llu"), +- kb, maxkb); +- return -1; +- } +- +- if (kb == maxkb) +- return virCgroupSetValueI64(group, +- VIR_CGROUP_CONTROLLER_MEMORY, +- "memory.soft_limit_in_bytes", +- -1); +- else +- return virCgroupSetValueU64(group, +- VIR_CGROUP_CONTROLLER_MEMORY, +- "memory.soft_limit_in_bytes", +- kb << 10); ++ VIR_CGROUP_BACKEND_CALL(group, setMemorySoftLimit, -1, kb); + } + + +@@ -1726,18 +1652,7 @@ virCgroupSetMemorySoftLimit(virCgroupPtr group, unsigned long long kb) + int + virCgroupGetMemorySoftLimit(virCgroupPtr group, unsigned long long *kb) + { +- long long unsigned int limit_in_bytes; +- +- if (virCgroupGetValueU64(group, +- VIR_CGROUP_CONTROLLER_MEMORY, +- "memory.soft_limit_in_bytes", &limit_in_bytes) < 0) +- return -1; +- +- *kb = limit_in_bytes >> 10; +- if (*kb >= virCgroupGetMemoryUnlimitedKB()) +- *kb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; +- +- return 0; ++ VIR_CGROUP_BACKEND_CALL(group, getMemorySoftLimit, -1, kb); + } + + +@@ -1752,25 +1667,7 @@ virCgroupGetMemorySoftLimit(virCgroupPtr group, unsigned long long *kb) + int + virCgroupSetMemSwapHardLimit(virCgroupPtr group, unsigned long long kb) + { +- unsigned long long maxkb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; +- +- if (kb > maxkb) { +- virReportError(VIR_ERR_INVALID_ARG, +- _("Memory '%llu' must be less than %llu"), +- kb, maxkb); +- return -1; +- } +- +- if (kb == maxkb) +- return virCgroupSetValueI64(group, +- VIR_CGROUP_CONTROLLER_MEMORY, +- "memory.memsw.limit_in_bytes", +- -1); +- else +- return virCgroupSetValueU64(group, +- VIR_CGROUP_CONTROLLER_MEMORY, +- "memory.memsw.limit_in_bytes", +- kb << 10); ++ VIR_CGROUP_BACKEND_CALL(group, setMemSwapHardLimit, -1, kb); + } + + +@@ -1785,18 +1682,7 @@ virCgroupSetMemSwapHardLimit(virCgroupPtr group, unsigned long long kb) + int + virCgroupGetMemSwapHardLimit(virCgroupPtr group, unsigned long long *kb) + { +- long long unsigned int limit_in_bytes; +- +- if (virCgroupGetValueU64(group, +- VIR_CGROUP_CONTROLLER_MEMORY, +- "memory.memsw.limit_in_bytes", &limit_in_bytes) < 0) +- return -1; +- +- *kb = limit_in_bytes >> 10; +- if (*kb >= virCgroupGetMemoryUnlimitedKB()) +- *kb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; +- +- return 0; ++ VIR_CGROUP_BACKEND_CALL(group, getMemSwapHardLimit, -1, kb); + } + + +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index 8bdfc5c835..cdbca4b907 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -227,6 +227,30 @@ typedef int + (*virCgroupGetMemoryUsageCB)(virCgroupPtr group, + unsigned long *kb); + ++typedef int ++(*virCgroupSetMemoryHardLimitCB)(virCgroupPtr group, ++ unsigned long long kb); ++ ++typedef int ++(*virCgroupGetMemoryHardLimitCB)(virCgroupPtr group, ++ unsigned long long *kb); ++ ++typedef int ++(*virCgroupSetMemorySoftLimitCB)(virCgroupPtr group, ++ unsigned long long kb); ++ ++typedef int ++(*virCgroupGetMemorySoftLimitCB)(virCgroupPtr group, ++ unsigned long long *kb); ++ ++typedef int ++(*virCgroupSetMemSwapHardLimitCB)(virCgroupPtr group, ++ unsigned long long kb); ++ ++typedef int ++(*virCgroupGetMemSwapHardLimitCB)(virCgroupPtr group, ++ unsigned long long *kb); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -269,6 +293,12 @@ struct _virCgroupBackend { + virCgroupSetMemoryCB setMemory; + virCgroupGetMemoryStatCB getMemoryStat; + virCgroupGetMemoryUsageCB getMemoryUsage; ++ virCgroupSetMemoryHardLimitCB setMemoryHardLimit; ++ virCgroupGetMemoryHardLimitCB getMemoryHardLimit; ++ virCgroupSetMemorySoftLimitCB setMemorySoftLimit; ++ virCgroupGetMemorySoftLimitCB getMemorySoftLimit; ++ virCgroupSetMemSwapHardLimitCB setMemSwapHardLimit; ++ virCgroupGetMemSwapHardLimitCB getMemSwapHardLimit; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgrouppriv.h b/src/util/vircgrouppriv.h +index 3a968c1ce2..7b985280e1 100644 +--- a/src/util/vircgrouppriv.h ++++ b/src/util/vircgrouppriv.h +@@ -88,6 +88,12 @@ int virCgroupGetValueForBlkDev(virCgroupPtr group, + const char *path, + char **value); + ++int virCgroupNew(pid_t pid, ++ const char *path, ++ virCgroupPtr parent, ++ int controllers, ++ virCgroupPtr *group); ++ + int virCgroupNewPartition(const char *path, + bool create, + int controllers, +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 4f1d79a758..779288fb97 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -1378,6 +1378,51 @@ virCgroupV1GetBlkioDeviceWriteBps(virCgroupPtr group, + } + + ++/* ++ * Retrieve the "memory.limit_in_bytes" value from the memory controller ++ * root dir. This value cannot be modified by userspace and therefore ++ * is the maximum limit value supported by cgroups on the local system. ++ * Returns this value scaled to KB or falls back to the original ++ * VIR_DOMAIN_MEMORY_PARAM_UNLIMITED. Either way, remember the return ++ * value to avoid unnecessary cgroup filesystem access. ++ */ ++static unsigned long long int virCgroupV1MemoryUnlimitedKB; ++static virOnceControl virCgroupV1MemoryOnce = VIR_ONCE_CONTROL_INITIALIZER; ++ ++static void ++virCgroupV1MemoryOnceInit(void) ++{ ++ virCgroupPtr group; ++ unsigned long long int mem_unlimited = 0ULL; ++ ++ if (virCgroupNew(-1, "/", NULL, -1, &group) < 0) ++ goto cleanup; ++ ++ if (!virCgroupV1HasController(group, VIR_CGROUP_CONTROLLER_MEMORY)) ++ goto cleanup; ++ ++ ignore_value(virCgroupGetValueU64(group, ++ VIR_CGROUP_CONTROLLER_MEMORY, ++ "memory.limit_in_bytes", ++ &mem_unlimited)); ++ cleanup: ++ virCgroupFree(&group); ++ virCgroupV1MemoryUnlimitedKB = mem_unlimited >> 10; ++} ++ ++static unsigned long long int ++virCgroupV1GetMemoryUnlimitedKB(void) ++{ ++ if (virOnce(&virCgroupV1MemoryOnce, virCgroupV1MemoryOnceInit) < 0) ++ VIR_DEBUG("Init failed, will fall back to defaults."); ++ ++ if (virCgroupV1MemoryUnlimitedKB) ++ return virCgroupV1MemoryUnlimitedKB; ++ else ++ return VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; ++} ++ ++ + static int + virCgroupV1SetMemory(virCgroupPtr group, + unsigned long long kb) +@@ -1494,6 +1539,123 @@ virCgroupV1GetMemoryUsage(virCgroupPtr group, + } + + ++static int ++virCgroupV1SetMemoryHardLimit(virCgroupPtr group, ++ unsigned long long kb) ++{ ++ return virCgroupV1SetMemory(group, kb); ++} ++ ++ ++static int ++virCgroupV1GetMemoryHardLimit(virCgroupPtr group, ++ unsigned long long *kb) ++{ ++ long long unsigned int limit_in_bytes; ++ ++ if (virCgroupGetValueU64(group, ++ VIR_CGROUP_CONTROLLER_MEMORY, ++ "memory.limit_in_bytes", &limit_in_bytes) < 0) ++ return -1; ++ ++ *kb = limit_in_bytes >> 10; ++ if (*kb >= virCgroupV1GetMemoryUnlimitedKB()) ++ *kb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; ++ ++ return 0; ++} ++ ++ ++static int ++virCgroupV1SetMemorySoftLimit(virCgroupPtr group, ++ unsigned long long kb) ++{ ++ unsigned long long maxkb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; ++ ++ if (kb > maxkb) { ++ virReportError(VIR_ERR_INVALID_ARG, ++ _("Memory '%llu' must be less than %llu"), ++ kb, maxkb); ++ return -1; ++ } ++ ++ if (kb == maxkb) ++ return virCgroupSetValueI64(group, ++ VIR_CGROUP_CONTROLLER_MEMORY, ++ "memory.soft_limit_in_bytes", ++ -1); ++ else ++ return virCgroupSetValueU64(group, ++ VIR_CGROUP_CONTROLLER_MEMORY, ++ "memory.soft_limit_in_bytes", ++ kb << 10); ++} ++ ++ ++static int ++virCgroupV1GetMemorySoftLimit(virCgroupPtr group, ++ unsigned long long *kb) ++{ ++ long long unsigned int limit_in_bytes; ++ ++ if (virCgroupGetValueU64(group, ++ VIR_CGROUP_CONTROLLER_MEMORY, ++ "memory.soft_limit_in_bytes", &limit_in_bytes) < 0) ++ return -1; ++ ++ *kb = limit_in_bytes >> 10; ++ if (*kb >= virCgroupV1GetMemoryUnlimitedKB()) ++ *kb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; ++ ++ return 0; ++} ++ ++ ++static int ++virCgroupV1SetMemSwapHardLimit(virCgroupPtr group, ++ unsigned long long kb) ++{ ++ unsigned long long maxkb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; ++ ++ if (kb > maxkb) { ++ virReportError(VIR_ERR_INVALID_ARG, ++ _("Memory '%llu' must be less than %llu"), ++ kb, maxkb); ++ return -1; ++ } ++ ++ if (kb == maxkb) ++ return virCgroupSetValueI64(group, ++ VIR_CGROUP_CONTROLLER_MEMORY, ++ "memory.memsw.limit_in_bytes", ++ -1); ++ else ++ return virCgroupSetValueU64(group, ++ VIR_CGROUP_CONTROLLER_MEMORY, ++ "memory.memsw.limit_in_bytes", ++ kb << 10); ++} ++ ++ ++static int ++virCgroupV1GetMemSwapHardLimit(virCgroupPtr group, ++ unsigned long long *kb) ++{ ++ long long unsigned int limit_in_bytes; ++ ++ if (virCgroupGetValueU64(group, ++ VIR_CGROUP_CONTROLLER_MEMORY, ++ "memory.memsw.limit_in_bytes", &limit_in_bytes) < 0) ++ return -1; ++ ++ *kb = limit_in_bytes >> 10; ++ if (*kb >= virCgroupV1GetMemoryUnlimitedKB()) ++ *kb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; ++ ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + +@@ -1534,6 +1696,12 @@ virCgroupBackend virCgroupV1Backend = { + .setMemory = virCgroupV1SetMemory, + .getMemoryStat = virCgroupV1GetMemoryStat, + .getMemoryUsage = virCgroupV1GetMemoryUsage, ++ .setMemoryHardLimit = virCgroupV1SetMemoryHardLimit, ++ .getMemoryHardLimit = virCgroupV1GetMemoryHardLimit, ++ .setMemorySoftLimit = virCgroupV1SetMemorySoftLimit, ++ .getMemorySoftLimit = virCgroupV1GetMemorySoftLimit, ++ .setMemSwapHardLimit = virCgroupV1SetMemSwapHardLimit, ++ .getMemSwapHardLimit = virCgroupV1GetMemSwapHardLimit, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1AddTask.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1AddTask.patch new file mode 100644 index 0000000..ca3e8d8 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1AddTask.patch @@ -0,0 +1,234 @@ +From a756729403915485dbd3cbdf4f252806318c227c Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:37 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1AddTask +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 064024e70afd6ad08993444b3839eb3ba67426f2) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <558f1a90ce9b0fc5a9688c5a44bf85dd523c37e5.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 56 ++++--------------------------------- + src/util/vircgroupbackend.h | 20 +++++++++++++ + src/util/vircgrouppriv.h | 5 ++++ + src/util/vircgroupv1.c | 31 ++++++++++++++++++++ + 4 files changed, 62 insertions(+), 50 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 33d34d6eda..a5076cb554 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -544,7 +544,7 @@ virCgroupSetValueU64(virCgroupPtr group, + } + + +-static int ++int + virCgroupSetValueI64(virCgroupPtr group, + int controller, + const char *key, +@@ -672,50 +672,6 @@ virCgroupNew(pid_t pid, + } + + +-typedef enum { +- /* Adds a whole process with all threads to specific cgroup except +- * to systemd named controller. */ +- VIR_CGROUP_TASK_PROCESS = 1 << 0, +- +- /* Same as VIR_CGROUP_TASK_PROCESS but it also adds the task to systemd +- * named controller. */ +- VIR_CGROUP_TASK_SYSTEMD = 1 << 1, +- +- /* Moves only specific thread into cgroup except to systemd +- * named controller. */ +- VIR_CGROUP_TASK_THREAD = 1 << 2, +-} virCgroupTaskFlags; +- +- +-static int +-virCgroupAddTaskInternal(virCgroupPtr group, +- pid_t pid, +- unsigned int flags) +-{ +- int ret = -1; +- size_t i; +- +- for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { +- /* Skip over controllers not mounted */ +- if (!group->controllers[i].mountPoint) +- continue; +- +- /* We must never add tasks in systemd's hierarchy +- * unless we're intentionally trying to move a +- * task into a systemd machine scope */ +- if (i == VIR_CGROUP_CONTROLLER_SYSTEMD && +- !(flags & VIR_CGROUP_TASK_SYSTEMD)) +- continue; +- +- if (virCgroupSetValueI64(group, i, "tasks", pid) < 0) +- goto cleanup; +- } +- +- ret = 0; +- cleanup: +- return ret; +-} +- + /** + * virCgroupAddProcess: + * +@@ -730,7 +686,7 @@ virCgroupAddTaskInternal(virCgroupPtr group, + int + virCgroupAddProcess(virCgroupPtr group, pid_t pid) + { +- return virCgroupAddTaskInternal(group, pid, VIR_CGROUP_TASK_PROCESS); ++ return group->backend->addTask(group, pid, VIR_CGROUP_TASK_PROCESS); + } + + /** +@@ -747,9 +703,9 @@ virCgroupAddProcess(virCgroupPtr group, pid_t pid) + int + virCgroupAddMachineProcess(virCgroupPtr group, pid_t pid) + { +- return virCgroupAddTaskInternal(group, pid, +- VIR_CGROUP_TASK_PROCESS | +- VIR_CGROUP_TASK_SYSTEMD); ++ return group->backend->addTask(group, pid, ++ VIR_CGROUP_TASK_PROCESS | ++ VIR_CGROUP_TASK_SYSTEMD); + } + + /** +@@ -767,7 +723,7 @@ int + virCgroupAddThread(virCgroupPtr group, + pid_t pid) + { +- return virCgroupAddTaskInternal(group, pid, VIR_CGROUP_TASK_THREAD); ++ return group->backend->addTask(group, pid, VIR_CGROUP_TASK_THREAD); + } + + +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index 1f28c51c49..bff1f8938e 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -35,6 +35,20 @@ typedef enum { + */ + } virCgroupBackendFlags; + ++typedef enum { ++ /* Adds a whole process with all threads to specific cgroup except ++ * to systemd named controller. */ ++ VIR_CGROUP_TASK_PROCESS = 1 << 0, ++ ++ /* Same as VIR_CGROUP_TASK_PROCESS but it also adds the task to systemd ++ * named controller. */ ++ VIR_CGROUP_TASK_SYSTEMD = 1 << 1, ++ ++ /* Moves only specific thread into cgroup except to systemd ++ * named controller. */ ++ VIR_CGROUP_TASK_THREAD = 1 << 2, ++} virCgroupBackendTaskFlags; ++ + typedef enum { + VIR_CGROUP_BACKEND_TYPE_V1 = 0, + VIR_CGROUP_BACKEND_TYPE_LAST, +@@ -103,6 +117,11 @@ typedef int + typedef int + (*virCgroupRemoveCB)(virCgroupPtr group); + ++typedef int ++(*virCgroupAddTaskCB)(virCgroupPtr group, ++ pid_t pid, ++ unsigned int flags); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -121,6 +140,7 @@ struct _virCgroupBackend { + virCgroupPathOfControllerCB pathOfController; + virCgroupMakeGroupCB makeGroup; + virCgroupRemoveCB remove; ++ virCgroupAddTaskCB addTask; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgrouppriv.h b/src/util/vircgrouppriv.h +index a760b9bcfd..01714370be 100644 +--- a/src/util/vircgrouppriv.h ++++ b/src/util/vircgrouppriv.h +@@ -73,6 +73,11 @@ int virCgroupGetValueU64(virCgroupPtr group, + const char *key, + unsigned long long int *value); + ++int virCgroupSetValueI64(virCgroupPtr group, ++ int controller, ++ const char *key, ++ long long int value); ++ + int virCgroupPartitionEscape(char **path); + + int virCgroupNewPartition(const char *path, +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 4d4b51094a..fda2c43eef 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -706,6 +706,36 @@ virCgroupV1Remove(virCgroupPtr group) + } + + ++static int ++virCgroupV1AddTask(virCgroupPtr group, ++ pid_t pid, ++ unsigned int flags) ++{ ++ int ret = -1; ++ size_t i; ++ ++ for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { ++ /* Skip over controllers not mounted */ ++ if (!group->controllers[i].mountPoint) ++ continue; ++ ++ /* We must never add tasks in systemd's hierarchy ++ * unless we're intentionally trying to move a ++ * task into a systemd machine scope */ ++ if (i == VIR_CGROUP_CONTROLLER_SYSTEMD && ++ !(flags & VIR_CGROUP_TASK_SYSTEMD)) ++ continue; ++ ++ if (virCgroupSetValueI64(group, i, "tasks", pid) < 0) ++ goto cleanup; ++ } ++ ++ ret = 0; ++ cleanup: ++ return ret; ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + +@@ -723,6 +753,7 @@ virCgroupBackend virCgroupV1Backend = { + .pathOfController = virCgroupV1PathOfController, + .makeGroup = virCgroupV1MakeGroup, + .remove = virCgroupV1Remove, ++ .addTask = virCgroupV1AddTask, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1Available.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1Available.patch new file mode 100644 index 0000000..a8f932f --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1Available.patch @@ -0,0 +1,173 @@ +From 0dcb8bdc63970be07228108f602a7425612bd1fe Mon Sep 17 00:00:00 2001 +Message-Id: <0dcb8bdc63970be07228108f602a7425612bd1fe@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:23 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1Available +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 57d35b72c9049348b36382ce88bee32553e0fae5) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 28 ++++++++-------------------- + src/util/vircgroupbackend.h | 7 +++++++ + src/util/vircgroupv1.c | 35 +++++++++++++++++++++++++++++++++++ + 3 files changed, 50 insertions(+), 20 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index d55f411daa..47a3b9ed58 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -51,6 +51,7 @@ + + #include "virutil.h" + #include "viralloc.h" ++#include "vircgroupbackend.h" + #include "virerror.h" + #include "virlog.h" + #include "virfile.h" +@@ -64,8 +65,6 @@ + + VIR_LOG_INIT("util.cgroup"); + +-#define CGROUP_MAX_VAL 512 +- + #define VIR_FROM_THIS VIR_FROM_CGROUP + + #define CGROUP_NB_TOTAL_CPU_STAT_PARAM 3 +@@ -132,29 +131,18 @@ virCgroupGetDevicePermsString(int perms) + bool + virCgroupAvailable(void) + { +- bool ret = false; +- FILE *mounts = NULL; +- struct mntent entry; +- char buf[CGROUP_MAX_VAL]; ++ size_t i; ++ virCgroupBackendPtr *backends = virCgroupBackendGetAll(); + +- if (!virFileExists("/proc/cgroups")) ++ if (!backends) + return false; + +- if (!(mounts = fopen("/proc/mounts", "r"))) +- return false; +- +- while (getmntent_r(mounts, &entry, buf, sizeof(buf)) != NULL) { +- /* We're looking for at least one 'cgroup' fs mount, +- * which is *not* a named mount. */ +- if (STREQ(entry.mnt_type, "cgroup") && +- !strstr(entry.mnt_opts, "name=")) { +- ret = true; +- break; +- } ++ for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) { ++ if (backends[i] && backends[i]->available()) ++ return true; + } + +- VIR_FORCE_FCLOSE(mounts); +- return ret; ++ return false; + } + + +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index db052485a8..88f51416b0 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -25,14 +25,21 @@ + + # include "vircgroup.h" + ++# define CGROUP_MAX_VAL 512 + + typedef enum { + VIR_CGROUP_BACKEND_TYPE_V1 = 0, + VIR_CGROUP_BACKEND_TYPE_LAST, + } virCgroupBackendType; + ++typedef bool ++(*virCgroupAvailableCB)(void); ++ + struct _virCgroupBackend { + virCgroupBackendType type; ++ ++ /* Mandatory callbacks that need to be implemented for every backend. */ ++ virCgroupAvailableCB available; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 4dda7865f1..73045b1109 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -20,6 +20,10 @@ + */ + #include + ++#if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R ++# include ++#endif ++ + #include "internal.h" + + #define __VIR_CGROUP_ALLOW_INCLUDE_PRIV_H__ +@@ -29,6 +33,7 @@ + #include "vircgroup.h" + #include "vircgroupbackend.h" + #include "vircgroupv1.h" ++#include "virfile.h" + #include "virlog.h" + + VIR_LOG_INIT("util.cgroup"); +@@ -43,8 +48,38 @@ VIR_ENUM_IMPL(virCgroupV1Controller, VIR_CGROUP_CONTROLLER_LAST, + "name=systemd"); + + ++/* We're looking for at least one 'cgroup' fs mount, ++ * which is *not* a named mount. */ ++static bool ++virCgroupV1Available(void) ++{ ++ bool ret = false; ++ FILE *mounts = NULL; ++ struct mntent entry; ++ char buf[CGROUP_MAX_VAL]; ++ ++ if (!virFileExists("/proc/cgroups")) ++ return false; ++ ++ if (!(mounts = fopen("/proc/mounts", "r"))) ++ return false; ++ ++ while (getmntent_r(mounts, &entry, buf, sizeof(buf)) != NULL) { ++ if (STREQ(entry.mnt_type, "cgroup") && !strstr(entry.mnt_opts, "name=")) { ++ ret = true; ++ break; ++ } ++ } ++ ++ VIR_FORCE_FCLOSE(mounts); ++ return ret; ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, ++ ++ .available = virCgroupV1Available, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1BindMount.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1BindMount.patch new file mode 100644 index 0000000..9528463 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1BindMount.patch @@ -0,0 +1,310 @@ +From 7ee971869f488f806a728eead8be82c287a35fc4 Mon Sep 17 00:00:00 2001 +Message-Id: <7ee971869f488f806a728eead8be82c287a35fc4@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:39 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1BindMount +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 8dc1b6ce50a6c007c0d2149ac7106221c99beb6f) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <71e4dbba49af93bcc36eefc92725e493a0447214.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 102 +------------------------------- + src/util/vircgroupbackend.h | 6 ++ + src/util/vircgroupv1.c | 113 ++++++++++++++++++++++++++++++++++++ + 3 files changed, 120 insertions(+), 101 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index d4d02d8f5b..7789966472 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -3179,35 +3179,6 @@ virCgroupKillPainfully(virCgroupPtr group) + } + + +-static char * +-virCgroupIdentifyRoot(virCgroupPtr group) +-{ +- char *ret = NULL; +- size_t i; +- +- for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { +- char *tmp; +- if (!group->controllers[i].mountPoint) +- continue; +- if (!(tmp = strrchr(group->controllers[i].mountPoint, '/'))) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Could not find directory separator in %s"), +- group->controllers[i].mountPoint); +- return NULL; +- } +- +- if (VIR_STRNDUP(ret, group->controllers[i].mountPoint, +- tmp - group->controllers[i].mountPoint) < 0) +- return NULL; +- return ret; +- } +- +- virReportError(VIR_ERR_INTERNAL_ERROR, "%s", +- _("Could not find any mounted controllers")); +- return NULL; +-} +- +- + /** + * virCgroupGetCpuCfsQuota: + * +@@ -3302,78 +3273,7 @@ int + virCgroupBindMount(virCgroupPtr group, const char *oldroot, + const char *mountopts) + { +- size_t i; +- VIR_AUTOFREE(char *) opts = NULL; +- VIR_AUTOFREE(char *) root = NULL; +- +- if (!(root = virCgroupIdentifyRoot(group))) +- return -1; +- +- VIR_DEBUG("Mounting cgroups at '%s'", root); +- +- if (virFileMakePath(root) < 0) { +- virReportSystemError(errno, +- _("Unable to create directory %s"), +- root); +- return -1; +- } +- +- if (virAsprintf(&opts, +- "mode=755,size=65536%s", mountopts) < 0) +- return -1; +- +- if (mount("tmpfs", root, "tmpfs", MS_NOSUID|MS_NODEV|MS_NOEXEC, opts) < 0) { +- virReportSystemError(errno, +- _("Failed to mount %s on %s type %s"), +- "tmpfs", root, "tmpfs"); +- return -1; +- } +- +- for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { +- if (!group->controllers[i].mountPoint) +- continue; +- +- if (!virFileExists(group->controllers[i].mountPoint)) { +- VIR_AUTOFREE(char *) src = NULL; +- if (virAsprintf(&src, "%s%s", +- oldroot, +- group->controllers[i].mountPoint) < 0) +- return -1; +- +- VIR_DEBUG("Create mount point '%s'", +- group->controllers[i].mountPoint); +- if (virFileMakePath(group->controllers[i].mountPoint) < 0) { +- virReportSystemError(errno, +- _("Unable to create directory %s"), +- group->controllers[i].mountPoint); +- return -1; +- } +- +- if (mount(src, group->controllers[i].mountPoint, "none", MS_BIND, +- NULL) < 0) { +- virReportSystemError(errno, +- _("Failed to bind cgroup '%s' on '%s'"), +- src, group->controllers[i].mountPoint); +- return -1; +- } +- } +- +- if (group->controllers[i].linkPoint) { +- VIR_DEBUG("Link mount point '%s' to '%s'", +- group->controllers[i].mountPoint, +- group->controllers[i].linkPoint); +- if (symlink(group->controllers[i].mountPoint, +- group->controllers[i].linkPoint) < 0) { +- virReportSystemError(errno, +- _("Unable to symlink directory %s to %s"), +- group->controllers[i].mountPoint, +- group->controllers[i].linkPoint); +- return -1; +- } +- } +- } +- +- return 0; ++ return group->backend->bindMount(group, oldroot, mountopts); + } + + +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index 3e0f6d01f4..caeec3de60 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -126,6 +126,11 @@ typedef int + (*virCgroupHasEmptyTasksCB)(virCgroupPtr cgroup, + int controller); + ++typedef int ++(*virCgroupBindMountCB)(virCgroupPtr group, ++ const char *oldroot, ++ const char *mountopts); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -146,6 +151,7 @@ struct _virCgroupBackend { + virCgroupRemoveCB remove; + virCgroupAddTaskCB addTask; + virCgroupHasEmptyTasksCB hasEmptyTasks; ++ virCgroupBindMountCB bindMount; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index b057cdfd9e..d63525dfb0 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -24,6 +24,9 @@ + # include + #endif + #include ++#if defined HAVE_SYS_MOUNT_H ++# include ++#endif + + #include "internal.h" + +@@ -755,6 +758,115 @@ virCgroupV1HasEmptyTasks(virCgroupPtr cgroup, + } + + ++static char * ++virCgroupV1IdentifyRoot(virCgroupPtr group) ++{ ++ char *ret = NULL; ++ size_t i; ++ ++ for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { ++ char *tmp; ++ if (!group->controllers[i].mountPoint) ++ continue; ++ if (!(tmp = strrchr(group->controllers[i].mountPoint, '/'))) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Could not find directory separator in %s"), ++ group->controllers[i].mountPoint); ++ return NULL; ++ } ++ ++ if (VIR_STRNDUP(ret, group->controllers[i].mountPoint, ++ tmp - group->controllers[i].mountPoint) < 0) ++ return NULL; ++ return ret; ++ } ++ ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("Could not find any mounted v1 controllers")); ++ return NULL; ++} ++ ++ ++static int ++virCgroupV1BindMount(virCgroupPtr group, ++ const char *oldroot, ++ const char *mountopts) ++{ ++ size_t i; ++ VIR_AUTOFREE(char *) opts = NULL; ++ VIR_AUTOFREE(char *) root = NULL; ++ ++ if (!(root = virCgroupV1IdentifyRoot(group))) ++ return -1; ++ ++ VIR_DEBUG("Mounting cgroups at '%s'", root); ++ ++ if (virFileMakePath(root) < 0) { ++ virReportSystemError(errno, ++ _("Unable to create directory %s"), ++ root); ++ return -1; ++ } ++ ++ if (virAsprintf(&opts, ++ "mode=755,size=65536%s", mountopts) < 0) ++ return -1; ++ ++ if (mount("tmpfs", root, "tmpfs", MS_NOSUID|MS_NODEV|MS_NOEXEC, opts) < 0) { ++ virReportSystemError(errno, ++ _("Failed to mount %s on %s type %s"), ++ "tmpfs", root, "tmpfs"); ++ return -1; ++ } ++ ++ for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { ++ if (!group->controllers[i].mountPoint) ++ continue; ++ ++ if (!virFileExists(group->controllers[i].mountPoint)) { ++ VIR_AUTOFREE(char *) src = NULL; ++ if (virAsprintf(&src, "%s%s", ++ oldroot, ++ group->controllers[i].mountPoint) < 0) ++ return -1; ++ ++ VIR_DEBUG("Create mount point '%s'", ++ group->controllers[i].mountPoint); ++ if (virFileMakePath(group->controllers[i].mountPoint) < 0) { ++ virReportSystemError(errno, ++ _("Unable to create directory %s"), ++ group->controllers[i].mountPoint); ++ return -1; ++ } ++ ++ if (mount(src, group->controllers[i].mountPoint, "none", MS_BIND, ++ NULL) < 0) { ++ virReportSystemError(errno, ++ _("Failed to bind cgroup '%s' on '%s'"), ++ src, group->controllers[i].mountPoint); ++ return -1; ++ } ++ } ++ ++ if (group->controllers[i].linkPoint) { ++ VIR_DEBUG("Link mount point '%s' to '%s'", ++ group->controllers[i].mountPoint, ++ group->controllers[i].linkPoint); ++ if (symlink(group->controllers[i].mountPoint, ++ group->controllers[i].linkPoint) < 0) { ++ virReportSystemError(errno, ++ _("Unable to symlink directory %s to %s"), ++ group->controllers[i].mountPoint, ++ group->controllers[i].linkPoint); ++ return -1; ++ } ++ } ++ } ++ ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + +@@ -774,6 +886,7 @@ virCgroupBackend virCgroupV1Backend = { + .remove = virCgroupV1Remove, + .addTask = virCgroupV1AddTask, + .hasEmptyTasks = virCgroupV1HasEmptyTasks, ++ .bindMount = virCgroupV1BindMount, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1CopyMounts.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1CopyMounts.patch new file mode 100644 index 0000000..08ce542 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1CopyMounts.patch @@ -0,0 +1,129 @@ +From ac37b7c9693d27c9c20f87b3fd077bf55ac1d34f Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:26 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1CopyMounts +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 47941ea7f52be44f609a6b6acc8895644039e617) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 23 +---------------------- + src/util/vircgroupbackend.h | 5 +++++ + src/util/vircgroupv1.c | 22 ++++++++++++++++++++++ + 3 files changed, 28 insertions(+), 22 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 6825623478..9d644d37d1 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -235,27 +235,6 @@ virCgroupPartitionEscape(char **path) + } + + +-static int +-virCgroupCopyMounts(virCgroupPtr group, +- virCgroupPtr parent) +-{ +- size_t i; +- for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { +- if (!parent->controllers[i].mountPoint) +- continue; +- +- if (VIR_STRDUP(group->controllers[i].mountPoint, +- parent->controllers[i].mountPoint) < 0) +- return -1; +- +- if (VIR_STRDUP(group->controllers[i].linkPoint, +- parent->controllers[i].linkPoint) < 0) +- return -1; +- } +- return 0; +-} +- +- + static int + virCgroupResolveMountLink(const char *mntDir, + const char *typeStr, +@@ -653,7 +632,7 @@ virCgroupDetect(virCgroupPtr group, + } + + if (parent) { +- if (virCgroupCopyMounts(group, parent) < 0) ++ if (group->backend->copyMounts(group, parent) < 0) + return -1; + } else { + if (virCgroupDetectMounts(group) < 0) +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index daf47bac09..81ee597fc8 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -41,12 +41,17 @@ typedef bool + const char *drivername, + const char *machinename); + ++typedef int ++(*virCgroupCopyMountsCB)(virCgroupPtr group, ++ virCgroupPtr parent); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + + /* Mandatory callbacks that need to be implemented for every backend. */ + virCgroupAvailableCB available; + virCgroupValidateMachineGroupCB validateMachineGroup; ++ virCgroupCopyMountsCB copyMounts; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index b78cdcab53..50b58ab413 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -160,11 +160,33 @@ virCgroupV1ValidateMachineGroup(virCgroupPtr group, + } + + ++static int ++virCgroupV1CopyMounts(virCgroupPtr group, ++ virCgroupPtr parent) ++{ ++ size_t i; ++ for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { ++ if (!parent->controllers[i].mountPoint) ++ continue; ++ ++ if (VIR_STRDUP(group->controllers[i].mountPoint, ++ parent->controllers[i].mountPoint) < 0) ++ return -1; ++ ++ if (VIR_STRDUP(group->controllers[i].linkPoint, ++ parent->controllers[i].linkPoint) < 0) ++ return -1; ++ } ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + + .available = virCgroupV1Available, + .validateMachineGroup = virCgroupV1ValidateMachineGroup, ++ .copyMounts = virCgroupV1CopyMounts, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1CopyPlacement.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1CopyPlacement.patch new file mode 100644 index 0000000..dacd6d8 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1CopyPlacement.patch @@ -0,0 +1,163 @@ +From b246f8418526ea154fe2f0223f6f34ea86b90ea4 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:28 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1CopyPlacement +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 229a8b5d3504efdbe8cd25bb3a127ec74ab4bbd3) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <9a9b8e24c5574e7b61e19a46d9978bf0dc1b32d3.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 38 +------------------------------------ + src/util/vircgroupbackend.h | 6 ++++++ + src/util/vircgroupv1.c | 37 ++++++++++++++++++++++++++++++++++++ + 3 files changed, 44 insertions(+), 37 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 10c99a66fd..b63321ca33 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -269,42 +269,6 @@ virCgroupDetectMounts(virCgroupPtr group) + } + + +-static int +-virCgroupCopyPlacement(virCgroupPtr group, +- const char *path, +- virCgroupPtr parent) +-{ +- size_t i; +- for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { +- if (!group->controllers[i].mountPoint) +- continue; +- +- if (i == VIR_CGROUP_CONTROLLER_SYSTEMD) +- continue; +- +- if (path[0] == '/') { +- if (VIR_STRDUP(group->controllers[i].placement, path) < 0) +- return -1; +- } else { +- /* +- * parent == "/" + path="" => "/" +- * parent == "/libvirt.service" + path == "" => "/libvirt.service" +- * parent == "/libvirt.service" + path == "foo" => "/libvirt.service/foo" +- */ +- if (virAsprintf(&group->controllers[i].placement, +- "%s%s%s", +- parent->controllers[i].placement, +- (STREQ(parent->controllers[i].placement, "/") || +- STREQ(path, "") ? "" : "/"), +- path) < 0) +- return -1; +- } +- } +- +- return 0; +-} +- +- + /* + * virCgroupDetectPlacement: + * @group: the group to process +@@ -532,7 +496,7 @@ virCgroupDetect(virCgroupPtr group, + * based on the parent cgroup... + */ + if ((parent || path[0] == '/') && +- virCgroupCopyPlacement(group, path, parent) < 0) ++ group->backend->copyPlacement(group, path, parent) < 0) + return -1; + + /* ... but use /proc/cgroups to fill in the rest */ +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index fadc7efdcf..85906e7191 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -45,6 +45,11 @@ typedef int + (*virCgroupCopyMountsCB)(virCgroupPtr group, + virCgroupPtr parent); + ++typedef int ++(*virCgroupCopyPlacementCB)(virCgroupPtr group, ++ const char *path, ++ virCgroupPtr parent); ++ + typedef int + (*virCgroupDetectMountsCB)(virCgroupPtr group, + const char *mntType, +@@ -64,6 +69,7 @@ struct _virCgroupBackend { + virCgroupAvailableCB available; + virCgroupValidateMachineGroupCB validateMachineGroup; + virCgroupCopyMountsCB copyMounts; ++ virCgroupCopyPlacementCB copyPlacement; + virCgroupDetectMountsCB detectMounts; + virCgroupDetectPlacementCB detectPlacement; + }; +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index bd9f28f6e9..68bb1c6f5d 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -183,6 +183,42 @@ virCgroupV1CopyMounts(virCgroupPtr group, + } + + ++static int ++virCgroupV1CopyPlacement(virCgroupPtr group, ++ const char *path, ++ virCgroupPtr parent) ++{ ++ size_t i; ++ for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { ++ if (!group->controllers[i].mountPoint) ++ continue; ++ ++ if (i == VIR_CGROUP_CONTROLLER_SYSTEMD) ++ continue; ++ ++ if (path[0] == '/') { ++ if (VIR_STRDUP(group->controllers[i].placement, path) < 0) ++ return -1; ++ } else { ++ /* ++ * parent == "/" + path="" => "/" ++ * parent == "/libvirt.service" + path == "" => "/libvirt.service" ++ * parent == "/libvirt.service" + path == "foo" => "/libvirt.service/foo" ++ */ ++ if (virAsprintf(&group->controllers[i].placement, ++ "%s%s%s", ++ parent->controllers[i].placement, ++ (STREQ(parent->controllers[i].placement, "/") || ++ STREQ(path, "") ? "" : "/"), ++ path) < 0) ++ return -1; ++ } ++ } ++ ++ return 0; ++} ++ ++ + static int + virCgroupV1ResolveMountLink(const char *mntDir, + const char *typeStr, +@@ -343,6 +379,7 @@ virCgroupBackend virCgroupV1Backend = { + .available = virCgroupV1Available, + .validateMachineGroup = virCgroupV1ValidateMachineGroup, + .copyMounts = virCgroupV1CopyMounts, ++ .copyPlacement = virCgroupV1CopyPlacement, + .detectMounts = virCgroupV1DetectMounts, + .detectPlacement = virCgroupV1DetectPlacement, + }; +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1DetectControllers.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1DetectControllers.patch new file mode 100644 index 0000000..dbf60ef --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1DetectControllers.patch @@ -0,0 +1,218 @@ +From c5ff4dbe89d9a57da51bb92389ebd9e5af4dd8dc Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:31 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1DetectControllers +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit d7f77dd6d5bcf91c3422a15842c2b7c2714510af) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 66 +------------------------------------ + src/util/vircgroupbackend.h | 5 +++ + src/util/vircgroupv1.c | 65 ++++++++++++++++++++++++++++++++++++ + 3 files changed, 71 insertions(+), 65 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 0e64ad67f4..2e74cbbff4 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -349,70 +349,6 @@ virCgroupDetectPlacement(virCgroupPtr group, + } + + +-static int +-virCgroupDetectControllers(virCgroupPtr group, +- int controllers) +-{ +- size_t i; +- size_t j; +- +- if (controllers >= 0) { +- VIR_DEBUG("Filtering controllers %d", controllers); +- /* First mark requested but non-existing controllers to be ignored */ +- for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { +- if (((1 << i) & controllers)) { +- /* Remove non-existent controllers */ +- if (!group->controllers[i].mountPoint) { +- VIR_DEBUG("Requested controller '%s' not mounted, ignoring", +- virCgroupControllerTypeToString(i)); +- controllers &= ~(1 << i); +- } +- } +- } +- for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { +- VIR_DEBUG("Controller '%s' wanted=%s, mount='%s'", +- virCgroupControllerTypeToString(i), +- (1 << i) & controllers ? "yes" : "no", +- NULLSTR(group->controllers[i].mountPoint)); +- if (!((1 << i) & controllers) && +- group->controllers[i].mountPoint) { +- /* Check whether a request to disable a controller +- * clashes with co-mounting of controllers */ +- for (j = 0; j < VIR_CGROUP_CONTROLLER_LAST; j++) { +- if (j == i) +- continue; +- if (!((1 << j) & controllers)) +- continue; +- +- if (STREQ_NULLABLE(group->controllers[i].mountPoint, +- group->controllers[j].mountPoint)) { +- virReportSystemError(EINVAL, +- _("Controller '%s' is not wanted, but '%s' is co-mounted"), +- virCgroupControllerTypeToString(i), +- virCgroupControllerTypeToString(j)); +- return -1; +- } +- } +- VIR_FREE(group->controllers[i].mountPoint); +- } +- } +- } else { +- VIR_DEBUG("Auto-detecting controllers"); +- controllers = 0; +- for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { +- VIR_DEBUG("Controller '%s' present=%s", +- virCgroupControllerTypeToString(i), +- group->controllers[i].mountPoint ? "yes" : "no"); +- if (group->controllers[i].mountPoint == NULL) +- continue; +- controllers |= (1 << i); +- } +- } +- +- return controllers; +-} +- +- + static int + virCgroupDetect(virCgroupPtr group, + pid_t pid, +@@ -451,7 +387,7 @@ virCgroupDetect(virCgroupPtr group, + return -1; + } + +- rc = virCgroupDetectControllers(group, controllers); ++ rc = group->backend->detectControllers(group, controllers); + if (rc < 0) + return -1; + +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index 9c0bd89793..011d1b00da 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -69,6 +69,10 @@ typedef int + typedef char * + (*virCgroupStealPlacementCB)(virCgroupPtr group); + ++typedef int ++(*virCgroupDetectControllersCB)(virCgroupPtr group, ++ int controllers); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -81,6 +85,7 @@ struct _virCgroupBackend { + virCgroupDetectPlacementCB detectPlacement; + virCgroupValidatePlacementCB validatePlacement; + virCgroupStealPlacementCB stealPlacement; ++ virCgroupDetectControllersCB detectControllers; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 446546fd58..11a86c061a 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -414,6 +414,70 @@ virCgroupV1StealPlacement(virCgroupPtr group) + } + + ++static int ++virCgroupV1DetectControllers(virCgroupPtr group, ++ int controllers) ++{ ++ size_t i; ++ size_t j; ++ ++ if (controllers >= 0) { ++ VIR_DEBUG("Filtering controllers %d", controllers); ++ /* First mark requested but non-existing controllers to be ignored */ ++ for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { ++ if (((1 << i) & controllers)) { ++ /* Remove non-existent controllers */ ++ if (!group->controllers[i].mountPoint) { ++ VIR_DEBUG("Requested controller '%s' not mounted, ignoring", ++ virCgroupV1ControllerTypeToString(i)); ++ controllers &= ~(1 << i); ++ } ++ } ++ } ++ for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { ++ VIR_DEBUG("Controller '%s' wanted=%s, mount='%s'", ++ virCgroupV1ControllerTypeToString(i), ++ (1 << i) & controllers ? "yes" : "no", ++ NULLSTR(group->controllers[i].mountPoint)); ++ if (!((1 << i) & controllers) && ++ group->controllers[i].mountPoint) { ++ /* Check whether a request to disable a controller ++ * clashes with co-mounting of controllers */ ++ for (j = 0; j < VIR_CGROUP_CONTROLLER_LAST; j++) { ++ if (j == i) ++ continue; ++ if (!((1 << j) & controllers)) ++ continue; ++ ++ if (STREQ_NULLABLE(group->controllers[i].mountPoint, ++ group->controllers[j].mountPoint)) { ++ virReportSystemError(EINVAL, ++ _("V1 controller '%s' is not wanted, but '%s' is co-mounted"), ++ virCgroupV1ControllerTypeToString(i), ++ virCgroupV1ControllerTypeToString(j)); ++ return -1; ++ } ++ } ++ VIR_FREE(group->controllers[i].mountPoint); ++ } ++ } ++ } else { ++ VIR_DEBUG("Auto-detecting controllers"); ++ controllers = 0; ++ for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { ++ VIR_DEBUG("Controller '%s' present=%s", ++ virCgroupV1ControllerTypeToString(i), ++ group->controllers[i].mountPoint ? "yes" : "no"); ++ if (group->controllers[i].mountPoint == NULL) ++ continue; ++ controllers |= (1 << i); ++ } ++ } ++ ++ return controllers; ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + +@@ -425,6 +489,7 @@ virCgroupBackend virCgroupV1Backend = { + .detectPlacement = virCgroupV1DetectPlacement, + .validatePlacement = virCgroupV1ValidatePlacement, + .stealPlacement = virCgroupV1StealPlacement, ++ .detectControllers = virCgroupV1DetectControllers, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1GetAnyController.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1GetAnyController.patch new file mode 100644 index 0000000..5e7acc3 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1GetAnyController.patch @@ -0,0 +1,118 @@ +From 98be75680dd7026b7156b3f9a0bd220f00714387 Mon Sep 17 00:00:00 2001 +Message-Id: <98be75680dd7026b7156b3f9a0bd220f00714387@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:33 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1GetAnyController +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit d6564037e8161bbdd270a822f5a2aafd90c7df10) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 16 ++++------------ + src/util/vircgroupbackend.h | 4 ++++ + src/util/vircgroupv1.c | 22 ++++++++++++++++++++++ + 3 files changed, 30 insertions(+), 12 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 5bbe42b699..a6f529accd 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -3173,19 +3173,11 @@ virCgroupPathOfAnyController(virCgroupPtr group, + const char *name, + char **keypath) + { +- size_t i; ++ int controller; + +- for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { +- /* Reject any controller with a placement +- * of '/' to avoid doing bad stuff to the root +- * cgroup +- */ +- if (group->controllers[i].mountPoint && +- group->controllers[i].placement && +- STRNEQ(group->controllers[i].placement, "/")) { +- return virCgroupPathOfController(group, i, name, keypath); +- } +- } ++ controller = group->backend->getAnyController(group); ++ if (controller >= 0) ++ return virCgroupPathOfController(group, controller, name, keypath); + + virReportSystemError(ENOSYS, "%s", + _("No controllers are mounted")); +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index 29b2fd119f..b4eaa89021 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -77,6 +77,9 @@ typedef bool + (*virCgroupHasControllerCB)(virCgroupPtr cgroup, + int controller); + ++typedef int ++(*virCgroupGetAnyControllerCB)(virCgroupPtr group); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -91,6 +94,7 @@ struct _virCgroupBackend { + virCgroupStealPlacementCB stealPlacement; + virCgroupDetectControllersCB detectControllers; + virCgroupHasControllerCB hasController; ++ virCgroupGetAnyControllerCB getAnyController; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 0638f48d50..bae16b8294 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -486,6 +486,27 @@ virCgroupV1HasController(virCgroupPtr group, + } + + ++static int ++virCgroupV1GetAnyController(virCgroupPtr group) ++{ ++ size_t i; ++ ++ for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { ++ /* Reject any controller with a placement ++ * of '/' to avoid doing bad stuff to the root ++ * cgroup ++ */ ++ if (group->controllers[i].mountPoint && ++ group->controllers[i].placement && ++ STRNEQ(group->controllers[i].placement, "/")) { ++ return i; ++ } ++ } ++ ++ return -1; ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + +@@ -499,6 +520,7 @@ virCgroupBackend virCgroupV1Backend = { + .stealPlacement = virCgroupV1StealPlacement, + .detectControllers = virCgroupV1DetectControllers, + .hasController = virCgroupV1HasController, ++ .getAnyController = virCgroupV1GetAnyController, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1GetBlkioIoDeviceServiced.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1GetBlkioIoDeviceServiced.patch new file mode 100644 index 0000000..7617d08 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1GetBlkioIoDeviceServiced.patch @@ -0,0 +1,278 @@ +From 0418e750369292b3bb7a855b998344042a87622c Mon Sep 17 00:00:00 2001 +Message-Id: <0418e750369292b3bb7a855b998344042a87622c@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:43 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1GetBlkioIoDeviceServiced +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 44809a28ecfe6f79d18abb55685024128228c7ad) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 83 ++-------------------------------- + src/util/vircgroupbackend.h | 9 ++++ + src/util/vircgrouppriv.h | 2 + + src/util/vircgroupv1.c | 90 +++++++++++++++++++++++++++++++++++++ + 4 files changed, 105 insertions(+), 79 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 8e46777920..fd39144ed2 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -409,7 +409,7 @@ virCgroupDetect(virCgroupPtr group, + } + + +-static char * ++char * + virCgroupGetBlockDevString(const char *path) + { + char *ret = NULL; +@@ -1337,84 +1337,9 @@ virCgroupGetBlkioIoDeviceServiced(virCgroupPtr group, + long long *requests_read, + long long *requests_write) + { +- VIR_AUTOFREE(char *) str1 = NULL; +- VIR_AUTOFREE(char *) str2 = NULL; +- VIR_AUTOFREE(char *) str3 = NULL; +- char *p1 = NULL; +- char *p2 = NULL; +- size_t i; +- +- const char *value_names[] = { +- "Read ", +- "Write " +- }; +- long long *bytes_ptrs[] = { +- bytes_read, +- bytes_write +- }; +- long long *requests_ptrs[] = { +- requests_read, +- requests_write +- }; +- +- if (virCgroupGetValueStr(group, +- VIR_CGROUP_CONTROLLER_BLKIO, +- "blkio.throttle.io_service_bytes", &str1) < 0) +- return -1; +- +- if (virCgroupGetValueStr(group, +- VIR_CGROUP_CONTROLLER_BLKIO, +- "blkio.throttle.io_serviced", &str2) < 0) +- return -1; +- +- if (!(str3 = virCgroupGetBlockDevString(path))) +- return -1; +- +- if (!(p1 = strstr(str1, str3))) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Cannot find byte stats for block device '%s'"), +- str3); +- return -1; +- } +- +- if (!(p2 = strstr(str2, str3))) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Cannot find request stats for block device '%s'"), +- str3); +- return -1; +- } +- +- for (i = 0; i < ARRAY_CARDINALITY(value_names); i++) { +- if (!(p1 = strstr(p1, value_names[i]))) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Cannot find byte %sstats for block device '%s'"), +- value_names[i], str3); +- return -1; +- } +- +- if (virStrToLong_ll(p1 + strlen(value_names[i]), &p1, 10, bytes_ptrs[i]) < 0) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Cannot parse %sstat '%s'"), +- value_names[i], p1 + strlen(value_names[i])); +- return -1; +- } +- +- if (!(p2 = strstr(p2, value_names[i]))) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Cannot find request %sstats for block device '%s'"), +- value_names[i], str3); +- return -1; +- } +- +- if (virStrToLong_ll(p2 + strlen(value_names[i]), &p2, 10, requests_ptrs[i]) < 0) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Cannot parse %sstat '%s'"), +- value_names[i], p2 + strlen(value_names[i])); +- return -1; +- } +- } +- +- return 0; ++ VIR_CGROUP_BACKEND_CALL(group, getBlkioIoDeviceServiced, -1, ++ path, bytes_read, bytes_write, ++ requests_read, requests_write); + } + + +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index 585a2eb353..e16d631a0f 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -152,6 +152,14 @@ typedef int + long long *requests_read, + long long *requests_write); + ++typedef int ++(*virCgroupGetBlkioIoDeviceServicedCB)(virCgroupPtr group, ++ const char *path, ++ long long *bytes_read, ++ long long *bytes_write, ++ long long *requests_read, ++ long long *requests_write); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -179,6 +187,7 @@ struct _virCgroupBackend { + virCgroupSetBlkioWeightCB setBlkioWeight; + virCgroupGetBlkioWeightCB getBlkioWeight; + virCgroupGetBlkioIoServicedCB getBlkioIoServiced; ++ virCgroupGetBlkioIoDeviceServicedCB getBlkioIoDeviceServiced; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgrouppriv.h b/src/util/vircgrouppriv.h +index 01714370be..525c288a9a 100644 +--- a/src/util/vircgrouppriv.h ++++ b/src/util/vircgrouppriv.h +@@ -80,6 +80,8 @@ int virCgroupSetValueI64(virCgroupPtr group, + + int virCgroupPartitionEscape(char **path); + ++char *virCgroupGetBlockDevString(const char *path); ++ + int virCgroupNewPartition(const char *path, + bool create, + int controllers, +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 1afdad4afc..79c4812aef 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -1049,6 +1049,95 @@ virCgroupV1GetBlkioIoServiced(virCgroupPtr group, + } + + ++static int ++virCgroupV1GetBlkioIoDeviceServiced(virCgroupPtr group, ++ const char *path, ++ long long *bytes_read, ++ long long *bytes_write, ++ long long *requests_read, ++ long long *requests_write) ++{ ++ VIR_AUTOFREE(char *) str1 = NULL; ++ VIR_AUTOFREE(char *) str2 = NULL; ++ VIR_AUTOFREE(char *) str3 = NULL; ++ char *p1 = NULL; ++ char *p2 = NULL; ++ size_t i; ++ ++ const char *value_names[] = { ++ "Read ", ++ "Write " ++ }; ++ long long *bytes_ptrs[] = { ++ bytes_read, ++ bytes_write ++ }; ++ long long *requests_ptrs[] = { ++ requests_read, ++ requests_write ++ }; ++ ++ if (virCgroupGetValueStr(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "blkio.throttle.io_service_bytes", &str1) < 0) ++ return -1; ++ ++ if (virCgroupGetValueStr(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "blkio.throttle.io_serviced", &str2) < 0) ++ return -1; ++ ++ if (!(str3 = virCgroupGetBlockDevString(path))) ++ return -1; ++ ++ if (!(p1 = strstr(str1, str3))) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Cannot find byte stats for block device '%s'"), ++ str3); ++ return -1; ++ } ++ ++ if (!(p2 = strstr(str2, str3))) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Cannot find request stats for block device '%s'"), ++ str3); ++ return -1; ++ } ++ ++ for (i = 0; i < ARRAY_CARDINALITY(value_names); i++) { ++ if (!(p1 = strstr(p1, value_names[i]))) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Cannot find byte %sstats for block device '%s'"), ++ value_names[i], str3); ++ return -1; ++ } ++ ++ if (virStrToLong_ll(p1 + strlen(value_names[i]), &p1, 10, bytes_ptrs[i]) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Cannot parse %sstat '%s'"), ++ value_names[i], p1 + strlen(value_names[i])); ++ return -1; ++ } ++ ++ if (!(p2 = strstr(p2, value_names[i]))) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Cannot find request %sstats for block device '%s'"), ++ value_names[i], str3); ++ return -1; ++ } ++ ++ if (virStrToLong_ll(p2 + strlen(value_names[i]), &p2, 10, requests_ptrs[i]) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Cannot parse %sstat '%s'"), ++ value_names[i], p2 + strlen(value_names[i])); ++ return -1; ++ } ++ } ++ ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + +@@ -1074,6 +1163,7 @@ virCgroupBackend virCgroupV1Backend = { + .setBlkioWeight = virCgroupV1SetBlkioWeight, + .getBlkioWeight = virCgroupV1GetBlkioWeight, + .getBlkioIoServiced = virCgroupV1GetBlkioIoServiced, ++ .getBlkioIoDeviceServiced = virCgroupV1GetBlkioIoDeviceServiced, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1GetBlkioIoServiced.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1GetBlkioIoServiced.patch new file mode 100644 index 0000000..660292e --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1GetBlkioIoServiced.patch @@ -0,0 +1,265 @@ +From 3cb8992be4013fb3ae978c62f6a433080e74130a Mon Sep 17 00:00:00 2001 +Message-Id: <3cb8992be4013fb3ae978c62f6a433080e74130a@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:42 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1GetBlkioIoServiced +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 4baa08ace12d2db7e7023b2abe915360bc7dcddf) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 87 ++------------------------------- + src/util/vircgroupbackend.h | 8 ++++ + src/util/vircgroupv1.c | 95 +++++++++++++++++++++++++++++++++++++ + 3 files changed, 106 insertions(+), 84 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index d2ffa8aefe..8e46777920 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -1311,90 +1311,9 @@ virCgroupGetBlkioIoServiced(virCgroupPtr group, + long long *requests_read, + long long *requests_write) + { +- long long stats_val; +- VIR_AUTOFREE(char *) str1 = NULL; +- VIR_AUTOFREE(char *) str2 = NULL; +- char *p1 = NULL; +- char *p2 = NULL; +- size_t i; +- +- const char *value_names[] = { +- "Read ", +- "Write " +- }; +- long long *bytes_ptrs[] = { +- bytes_read, +- bytes_write +- }; +- long long *requests_ptrs[] = { +- requests_read, +- requests_write +- }; +- +- *bytes_read = 0; +- *bytes_write = 0; +- *requests_read = 0; +- *requests_write = 0; +- +- if (virCgroupGetValueStr(group, +- VIR_CGROUP_CONTROLLER_BLKIO, +- "blkio.throttle.io_service_bytes", &str1) < 0) +- return -1; +- +- if (virCgroupGetValueStr(group, +- VIR_CGROUP_CONTROLLER_BLKIO, +- "blkio.throttle.io_serviced", &str2) < 0) +- return -1; +- +- /* sum up all entries of the same kind, from all devices */ +- for (i = 0; i < ARRAY_CARDINALITY(value_names); i++) { +- p1 = str1; +- p2 = str2; +- +- while ((p1 = strstr(p1, value_names[i]))) { +- p1 += strlen(value_names[i]); +- if (virStrToLong_ll(p1, &p1, 10, &stats_val) < 0) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Cannot parse byte %sstat '%s'"), +- value_names[i], +- p1); +- return -1; +- } +- +- if (stats_val < 0 || +- (stats_val > 0 && *bytes_ptrs[i] > (LLONG_MAX - stats_val))) +- { +- virReportError(VIR_ERR_OVERFLOW, +- _("Sum of byte %sstat overflows"), +- value_names[i]); +- return -1; +- } +- *bytes_ptrs[i] += stats_val; +- } +- +- while ((p2 = strstr(p2, value_names[i]))) { +- p2 += strlen(value_names[i]); +- if (virStrToLong_ll(p2, &p2, 10, &stats_val) < 0) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Cannot parse %srequest stat '%s'"), +- value_names[i], +- p2); +- return -1; +- } +- +- if (stats_val < 0 || +- (stats_val > 0 && *requests_ptrs[i] > (LLONG_MAX - stats_val))) +- { +- virReportError(VIR_ERR_OVERFLOW, +- _("Sum of %srequest stat overflows"), +- value_names[i]); +- return -1; +- } +- *requests_ptrs[i] += stats_val; +- } +- } +- +- return 0; ++ VIR_CGROUP_BACKEND_CALL(group, getBlkioIoServiced, -1, ++ bytes_read, bytes_write, ++ requests_read, requests_write); + } + + +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index ccce65f1e2..585a2eb353 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -145,6 +145,13 @@ typedef int + (*virCgroupGetBlkioWeightCB)(virCgroupPtr group, + unsigned int *weight); + ++typedef int ++(*virCgroupGetBlkioIoServicedCB)(virCgroupPtr group, ++ long long *bytes_read, ++ long long *bytes_write, ++ long long *requests_read, ++ long long *requests_write); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -171,6 +178,7 @@ struct _virCgroupBackend { + /* Optional cgroup controller specific callbacks. */ + virCgroupSetBlkioWeightCB setBlkioWeight; + virCgroupGetBlkioWeightCB getBlkioWeight; ++ virCgroupGetBlkioIoServicedCB getBlkioIoServiced; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index d67b3164ce..1afdad4afc 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -955,6 +955,100 @@ virCgroupV1GetBlkioWeight(virCgroupPtr group, + } + + ++static int ++virCgroupV1GetBlkioIoServiced(virCgroupPtr group, ++ long long *bytes_read, ++ long long *bytes_write, ++ long long *requests_read, ++ long long *requests_write) ++{ ++ long long stats_val; ++ VIR_AUTOFREE(char *) str1 = NULL; ++ VIR_AUTOFREE(char *) str2 = NULL; ++ char *p1 = NULL; ++ char *p2 = NULL; ++ size_t i; ++ ++ const char *value_names[] = { ++ "Read ", ++ "Write " ++ }; ++ long long *bytes_ptrs[] = { ++ bytes_read, ++ bytes_write ++ }; ++ long long *requests_ptrs[] = { ++ requests_read, ++ requests_write ++ }; ++ ++ *bytes_read = 0; ++ *bytes_write = 0; ++ *requests_read = 0; ++ *requests_write = 0; ++ ++ if (virCgroupGetValueStr(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "blkio.throttle.io_service_bytes", &str1) < 0) ++ return -1; ++ ++ if (virCgroupGetValueStr(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "blkio.throttle.io_serviced", &str2) < 0) ++ return -1; ++ ++ /* sum up all entries of the same kind, from all devices */ ++ for (i = 0; i < ARRAY_CARDINALITY(value_names); i++) { ++ p1 = str1; ++ p2 = str2; ++ ++ while ((p1 = strstr(p1, value_names[i]))) { ++ p1 += strlen(value_names[i]); ++ if (virStrToLong_ll(p1, &p1, 10, &stats_val) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Cannot parse byte %sstat '%s'"), ++ value_names[i], ++ p1); ++ return -1; ++ } ++ ++ if (stats_val < 0 || ++ (stats_val > 0 && *bytes_ptrs[i] > (LLONG_MAX - stats_val))) ++ { ++ virReportError(VIR_ERR_OVERFLOW, ++ _("Sum of byte %sstat overflows"), ++ value_names[i]); ++ return -1; ++ } ++ *bytes_ptrs[i] += stats_val; ++ } ++ ++ while ((p2 = strstr(p2, value_names[i]))) { ++ p2 += strlen(value_names[i]); ++ if (virStrToLong_ll(p2, &p2, 10, &stats_val) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Cannot parse %srequest stat '%s'"), ++ value_names[i], ++ p2); ++ return -1; ++ } ++ ++ if (stats_val < 0 || ++ (stats_val > 0 && *requests_ptrs[i] > (LLONG_MAX - stats_val))) ++ { ++ virReportError(VIR_ERR_OVERFLOW, ++ _("Sum of %srequest stat overflows"), ++ value_names[i]); ++ return -1; ++ } ++ *requests_ptrs[i] += stats_val; ++ } ++ } ++ ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + +@@ -979,6 +1073,7 @@ virCgroupBackend virCgroupV1Backend = { + + .setBlkioWeight = virCgroupV1SetBlkioWeight, + .getBlkioWeight = virCgroupV1GetBlkioWeight, ++ .getBlkioIoServiced = virCgroupV1GetBlkioIoServiced, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1GetCpuacct-Usage.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1GetCpuacct-Usage.patch new file mode 100644 index 0000000..ac8db97 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1GetCpuacct-Usage.patch @@ -0,0 +1,122 @@ +From 1d91616a1f70531a38695b1634e5538e1699b648 Mon Sep 17 00:00:00 2001 +Message-Id: <1d91616a1f70531a38695b1634e5538e1699b648@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:00 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1GetCpuacct*Usage +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 83704663234b894251eb197638e81b652674103e) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 7 ++----- + src/util/vircgroupbackend.h | 11 +++++++++++ + src/util/vircgroupv1.c | 22 ++++++++++++++++++++++ + 3 files changed, 35 insertions(+), 5 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index fa9fa52019..4f791204d3 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -2265,8 +2265,7 @@ virCgroupSetCpuCfsQuota(virCgroupPtr group, long long cfs_quota) + int + virCgroupGetCpuacctPercpuUsage(virCgroupPtr group, char **usage) + { +- return virCgroupGetValueStr(group, VIR_CGROUP_CONTROLLER_CPUACCT, +- "cpuacct.usage_percpu", usage); ++ VIR_CGROUP_BACKEND_CALL(group, getCpuacctPercpuUsage, -1, usage); + } + + +@@ -2589,9 +2588,7 @@ virCgroupGetCpuCfsQuota(virCgroupPtr group, long long *cfs_quota) + int + virCgroupGetCpuacctUsage(virCgroupPtr group, unsigned long long *usage) + { +- return virCgroupGetValueU64(group, +- VIR_CGROUP_CONTROLLER_CPUACCT, +- "cpuacct.usage", usage); ++ VIR_CGROUP_BACKEND_CALL(group, getCpuacctUsage, -1, usage); + } + + +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index d3d5e7c222..39a75a69f4 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -303,6 +303,14 @@ typedef int + typedef bool + (*virCgroupSupportsCpuBWCB)(virCgroupPtr cgroup); + ++typedef int ++(*virCgroupGetCpuacctUsageCB)(virCgroupPtr group, ++ unsigned long long *usage); ++ ++typedef int ++(*virCgroupGetCpuacctPercpuUsageCB)(virCgroupPtr group, ++ char **usage); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -365,6 +373,9 @@ struct _virCgroupBackend { + virCgroupSetCpuCfsQuotaCB setCpuCfsQuota; + virCgroupGetCpuCfsQuotaCB getCpuCfsQuota; + virCgroupSupportsCpuBWCB supportsCpuBW; ++ ++ virCgroupGetCpuacctUsageCB getCpuacctUsage; ++ virCgroupGetCpuacctPercpuUsageCB getCpuacctPercpuUsage; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index f2a8839f6e..9fb0c5cb96 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -1864,6 +1864,25 @@ virCgroupV1SupportsCpuBW(virCgroupPtr cgroup) + } + + ++static int ++virCgroupV1GetCpuacctUsage(virCgroupPtr group, ++ unsigned long long *usage) ++{ ++ return virCgroupGetValueU64(group, ++ VIR_CGROUP_CONTROLLER_CPUACCT, ++ "cpuacct.usage", usage); ++} ++ ++ ++static int ++virCgroupV1GetCpuacctPercpuUsage(virCgroupPtr group, ++ char **usage) ++{ ++ return virCgroupGetValueStr(group, VIR_CGROUP_CONTROLLER_CPUACCT, ++ "cpuacct.usage_percpu", usage); ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + +@@ -1924,6 +1943,9 @@ virCgroupBackend virCgroupV1Backend = { + .setCpuCfsQuota = virCgroupV1SetCpuCfsQuota, + .getCpuCfsQuota = virCgroupV1GetCpuCfsQuota, + .supportsCpuBW = virCgroupV1SupportsCpuBW, ++ ++ .getCpuacctUsage = virCgroupV1GetCpuacctUsage, ++ .getCpuacctPercpuUsage = virCgroupV1GetCpuacctPercpuUsage, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1GetCpuacctStat.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1GetCpuacctStat.patch new file mode 100644 index 0000000..7dbc0b4 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1GetCpuacctStat.patch @@ -0,0 +1,167 @@ +From 97f3e1cef9707ac7b1e744aef51880d4538e286a Mon Sep 17 00:00:00 2001 +Message-Id: <97f3e1cef9707ac7b1e744aef51880d4538e286a@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:01 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1GetCpuacctStat +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit e294615f9d849ee4923621db2224fce713018458) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <06921474355374c68d49725851f915e9bf44feeb.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 39 +----------------------------- + src/util/vircgroupbackend.h | 6 +++++ + src/util/vircgroupv1.c | 47 +++++++++++++++++++++++++++++++++++++ + 3 files changed, 54 insertions(+), 38 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 4f791204d3..090fe140bb 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -2596,44 +2596,7 @@ int + virCgroupGetCpuacctStat(virCgroupPtr group, unsigned long long *user, + unsigned long long *sys) + { +- VIR_AUTOFREE(char *) str = NULL; +- char *p; +- static double scale = -1.0; +- +- if (virCgroupGetValueStr(group, VIR_CGROUP_CONTROLLER_CPUACCT, +- "cpuacct.stat", &str) < 0) +- return -1; +- +- if (!(p = STRSKIP(str, "user ")) || +- virStrToLong_ull(p, &p, 10, user) < 0) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Cannot parse user stat '%s'"), +- p); +- return -1; +- } +- if (!(p = STRSKIP(p, "\nsystem ")) || +- virStrToLong_ull(p, NULL, 10, sys) < 0) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Cannot parse sys stat '%s'"), +- p); +- return -1; +- } +- /* times reported are in system ticks (generally 100 Hz), but that +- * rate can theoretically vary between machines. Scale things +- * into approximate nanoseconds. */ +- if (scale < 0) { +- long ticks_per_sec = sysconf(_SC_CLK_TCK); +- if (ticks_per_sec == -1) { +- virReportSystemError(errno, "%s", +- _("Cannot determine system clock HZ")); +- return -1; +- } +- scale = 1000000000.0 / ticks_per_sec; +- } +- *user *= scale; +- *sys *= scale; +- +- return 0; ++ VIR_CGROUP_BACKEND_CALL(group, getCpuacctStat, -1, user, sys); + } + + +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index 39a75a69f4..3e3a73777d 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -311,6 +311,11 @@ typedef int + (*virCgroupGetCpuacctPercpuUsageCB)(virCgroupPtr group, + char **usage); + ++typedef int ++(*virCgroupGetCpuacctStatCB)(virCgroupPtr group, ++ unsigned long long *user, ++ unsigned long long *sys); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -376,6 +381,7 @@ struct _virCgroupBackend { + + virCgroupGetCpuacctUsageCB getCpuacctUsage; + virCgroupGetCpuacctPercpuUsageCB getCpuacctPercpuUsage; ++ virCgroupGetCpuacctStatCB getCpuacctStat; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 9fb0c5cb96..23a91adf60 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -1883,6 +1883,52 @@ virCgroupV1GetCpuacctPercpuUsage(virCgroupPtr group, + } + + ++static int ++virCgroupV1GetCpuacctStat(virCgroupPtr group, ++ unsigned long long *user, ++ unsigned long long *sys) ++{ ++ VIR_AUTOFREE(char *) str = NULL; ++ char *p; ++ static double scale = -1.0; ++ ++ if (virCgroupGetValueStr(group, VIR_CGROUP_CONTROLLER_CPUACCT, ++ "cpuacct.stat", &str) < 0) ++ return -1; ++ ++ if (!(p = STRSKIP(str, "user ")) || ++ virStrToLong_ull(p, &p, 10, user) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Cannot parse user stat '%s'"), ++ p); ++ return -1; ++ } ++ if (!(p = STRSKIP(p, "\nsystem ")) || ++ virStrToLong_ull(p, NULL, 10, sys) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Cannot parse sys stat '%s'"), ++ p); ++ return -1; ++ } ++ /* times reported are in system ticks (generally 100 Hz), but that ++ * rate can theoretically vary between machines. Scale things ++ * into approximate nanoseconds. */ ++ if (scale < 0) { ++ long ticks_per_sec = sysconf(_SC_CLK_TCK); ++ if (ticks_per_sec == -1) { ++ virReportSystemError(errno, "%s", ++ _("Cannot determine system clock HZ")); ++ return -1; ++ } ++ scale = 1000000000.0 / ticks_per_sec; ++ } ++ *user *= scale; ++ *sys *= scale; ++ ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + +@@ -1946,6 +1992,7 @@ virCgroupBackend virCgroupV1Backend = { + + .getCpuacctUsage = virCgroupV1GetCpuacctUsage, + .getCpuacctPercpuUsage = virCgroupV1GetCpuacctPercpuUsage, ++ .getCpuacctStat = virCgroupV1GetCpuacctStat, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1GetMemSwapUsage.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1GetMemSwapUsage.patch new file mode 100644 index 0000000..bf8d146 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1GetMemSwapUsage.patch @@ -0,0 +1,105 @@ +From 3e61b08bd5d925b262e3ca84d234670917604fda Mon Sep 17 00:00:00 2001 +Message-Id: <3e61b08bd5d925b262e3ca84d234670917604fda@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:53 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1GetMemSwapUsage +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 87d9fc5b3bfbe217af1a5316af4392540f676657) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 9 +-------- + src/util/vircgroupbackend.h | 5 +++++ + src/util/vircgroupv1.c | 16 ++++++++++++++++ + 3 files changed, 22 insertions(+), 8 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 6708eef0da..088e97cb3f 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -1697,14 +1697,7 @@ virCgroupGetMemSwapHardLimit(virCgroupPtr group, unsigned long long *kb) + int + virCgroupGetMemSwapUsage(virCgroupPtr group, unsigned long long *kb) + { +- long long unsigned int usage_in_bytes; +- int ret; +- ret = virCgroupGetValueU64(group, +- VIR_CGROUP_CONTROLLER_MEMORY, +- "memory.memsw.usage_in_bytes", &usage_in_bytes); +- if (ret == 0) +- *kb = usage_in_bytes >> 10; +- return ret; ++ VIR_CGROUP_BACKEND_CALL(group, getMemSwapUsage, -1, kb); + } + + +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index cdbca4b907..27e6b18ea2 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -251,6 +251,10 @@ typedef int + (*virCgroupGetMemSwapHardLimitCB)(virCgroupPtr group, + unsigned long long *kb); + ++typedef int ++(*virCgroupGetMemSwapUsageCB)(virCgroupPtr group, ++ unsigned long long *kb); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -299,6 +303,7 @@ struct _virCgroupBackend { + virCgroupGetMemorySoftLimitCB getMemorySoftLimit; + virCgroupSetMemSwapHardLimitCB setMemSwapHardLimit; + virCgroupGetMemSwapHardLimitCB getMemSwapHardLimit; ++ virCgroupGetMemSwapUsageCB getMemSwapUsage; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 779288fb97..55b1d3ebd0 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -1656,6 +1656,21 @@ virCgroupV1GetMemSwapHardLimit(virCgroupPtr group, + } + + ++static int ++virCgroupV1GetMemSwapUsage(virCgroupPtr group, ++ unsigned long long *kb) ++{ ++ long long unsigned int usage_in_bytes; ++ int ret; ++ ret = virCgroupGetValueU64(group, ++ VIR_CGROUP_CONTROLLER_MEMORY, ++ "memory.memsw.usage_in_bytes", &usage_in_bytes); ++ if (ret == 0) ++ *kb = usage_in_bytes >> 10; ++ return ret; ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + +@@ -1702,6 +1717,7 @@ virCgroupBackend virCgroupV1Backend = { + .getMemorySoftLimit = virCgroupV1GetMemorySoftLimit, + .setMemSwapHardLimit = virCgroupV1SetMemSwapHardLimit, + .getMemSwapHardLimit = virCgroupV1GetMemSwapHardLimit, ++ .getMemSwapUsage = virCgroupV1GetMemSwapUsage, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1GetMemoryStat.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1GetMemoryStat.patch new file mode 100644 index 0000000..4f408fc --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1GetMemoryStat.patch @@ -0,0 +1,228 @@ +From 22e8736edafd1ac369adead17d924bd6b9536817 Mon Sep 17 00:00:00 2001 +Message-Id: <22e8736edafd1ac369adead17d924bd6b9536817@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:50 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1GetMemoryStat +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 64bfbd7ceb328d27becf98e0539d0ab4bcda8163) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 67 ++------------------------------ + src/util/vircgroupbackend.h | 10 +++++ + src/util/vircgroupv1.c | 76 +++++++++++++++++++++++++++++++++++++ + 3 files changed, 90 insertions(+), 63 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 4053c65939..786034d555 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -1619,69 +1619,10 @@ virCgroupGetMemoryStat(virCgroupPtr group, + unsigned long long *inactiveFile, + unsigned long long *unevictable) + { +- int ret = -1; +- char *stat = NULL; +- char *line = NULL; +- unsigned long long cacheVal = 0; +- unsigned long long activeAnonVal = 0; +- unsigned long long inactiveAnonVal = 0; +- unsigned long long activeFileVal = 0; +- unsigned long long inactiveFileVal = 0; +- unsigned long long unevictableVal = 0; +- +- if (virCgroupGetValueStr(group, +- VIR_CGROUP_CONTROLLER_MEMORY, +- "memory.stat", +- &stat) < 0) { +- return -1; +- } +- +- line = stat; +- +- while (line) { +- char *newLine = strchr(line, '\n'); +- char *valueStr = strchr(line, ' '); +- unsigned long long value; +- +- if (newLine) +- *newLine = '\0'; +- +- if (!valueStr) { +- virReportError(VIR_ERR_INTERNAL_ERROR, "%s", +- _("Cannot parse 'memory.stat' cgroup file.")); +- goto cleanup; +- } +- *valueStr = '\0'; +- +- if (virStrToLong_ull(valueStr + 1, NULL, 10, &value) < 0) +- goto cleanup; +- +- if (STREQ(line, "cache")) +- cacheVal = value >> 10; +- else if (STREQ(line, "active_anon")) +- activeAnonVal = value >> 10; +- else if (STREQ(line, "inactive_anon")) +- inactiveAnonVal = value >> 10; +- else if (STREQ(line, "active_file")) +- activeFileVal = value >> 10; +- else if (STREQ(line, "inactive_file")) +- inactiveFileVal = value >> 10; +- else if (STREQ(line, "unevictable")) +- unevictableVal = value >> 10; +- } +- +- *cache = cacheVal; +- *activeAnon = activeAnonVal; +- *inactiveAnon = inactiveAnonVal; +- *activeFile = activeFileVal; +- *inactiveFile = inactiveFileVal; +- *unevictable = unevictableVal; +- +- ret = 0; +- +- cleanup: +- VIR_FREE(stat); +- return ret; ++ VIR_CGROUP_BACKEND_CALL(group, getMemoryStat, -1, cache, ++ activeAnon, inactiveAnon, ++ activeFile, inactiveFile, ++ unevictable); + } + + +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index e1f75c5c31..99754a6310 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -214,6 +214,15 @@ typedef int + (*virCgroupSetMemoryCB)(virCgroupPtr group, + unsigned long long kb); + ++typedef int ++(*virCgroupGetMemoryStatCB)(virCgroupPtr group, ++ unsigned long long *cache, ++ unsigned long long *activeAnon, ++ unsigned long long *inactiveAnon, ++ unsigned long long *activeFile, ++ unsigned long long *inactiveFile, ++ unsigned long long *unevictable); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -254,6 +263,7 @@ struct _virCgroupBackend { + virCgroupGetBlkioDeviceWriteBpsCB getBlkioDeviceWriteBps; + + virCgroupSetMemoryCB setMemory; ++ virCgroupGetMemoryStatCB getMemoryStat; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 17a4d67972..fcb2607e26 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -1404,6 +1404,81 @@ virCgroupV1SetMemory(virCgroupPtr group, + } + + ++static int ++virCgroupV1GetMemoryStat(virCgroupPtr group, ++ unsigned long long *cache, ++ unsigned long long *activeAnon, ++ unsigned long long *inactiveAnon, ++ unsigned long long *activeFile, ++ unsigned long long *inactiveFile, ++ unsigned long long *unevictable) ++{ ++ int ret = -1; ++ char *stat = NULL; ++ char *line = NULL; ++ unsigned long long cacheVal = 0; ++ unsigned long long activeAnonVal = 0; ++ unsigned long long inactiveAnonVal = 0; ++ unsigned long long activeFileVal = 0; ++ unsigned long long inactiveFileVal = 0; ++ unsigned long long unevictableVal = 0; ++ ++ if (virCgroupGetValueStr(group, ++ VIR_CGROUP_CONTROLLER_MEMORY, ++ "memory.stat", ++ &stat) < 0) { ++ return -1; ++ } ++ ++ line = stat; ++ ++ while (line) { ++ char *newLine = strchr(line, '\n'); ++ char *valueStr = strchr(line, ' '); ++ unsigned long long value; ++ ++ if (newLine) ++ *newLine = '\0'; ++ ++ if (!valueStr) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("Cannot parse 'memory.stat' cgroup file.")); ++ goto cleanup; ++ } ++ *valueStr = '\0'; ++ ++ if (virStrToLong_ull(valueStr + 1, NULL, 10, &value) < 0) ++ goto cleanup; ++ ++ if (STREQ(line, "cache")) ++ cacheVal = value >> 10; ++ else if (STREQ(line, "active_anon")) ++ activeAnonVal = value >> 10; ++ else if (STREQ(line, "inactive_anon")) ++ inactiveAnonVal = value >> 10; ++ else if (STREQ(line, "active_file")) ++ activeFileVal = value >> 10; ++ else if (STREQ(line, "inactive_file")) ++ inactiveFileVal = value >> 10; ++ else if (STREQ(line, "unevictable")) ++ unevictableVal = value >> 10; ++ } ++ ++ *cache = cacheVal; ++ *activeAnon = activeAnonVal; ++ *inactiveAnon = inactiveAnonVal; ++ *activeFile = activeFileVal; ++ *inactiveFile = inactiveFileVal; ++ *unevictable = unevictableVal; ++ ++ ret = 0; ++ ++ cleanup: ++ VIR_FREE(stat); ++ return ret; ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + +@@ -1442,6 +1517,7 @@ virCgroupBackend virCgroupV1Backend = { + .getBlkioDeviceWriteBps = virCgroupV1GetBlkioDeviceWriteBps, + + .setMemory = virCgroupV1SetMemory, ++ .getMemoryStat = virCgroupV1GetMemoryStat, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1GetMemoryUsage.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1GetMemoryUsage.patch new file mode 100644 index 0000000..8fc79e2 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1GetMemoryUsage.patch @@ -0,0 +1,105 @@ +From fadcb498572cd664d45d31039f2bd34e22cc02b3 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:51 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1GetMemoryUsage +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit e92f8bad6681439d50251e7ac13e5f9f1bef62d5) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 9 +-------- + src/util/vircgroupbackend.h | 5 +++++ + src/util/vircgroupv1.c | 16 ++++++++++++++++ + 3 files changed, 22 insertions(+), 8 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 786034d555..ed7252243c 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -1637,14 +1637,7 @@ virCgroupGetMemoryStat(virCgroupPtr group, + int + virCgroupGetMemoryUsage(virCgroupPtr group, unsigned long *kb) + { +- long long unsigned int usage_in_bytes; +- int ret; +- ret = virCgroupGetValueU64(group, +- VIR_CGROUP_CONTROLLER_MEMORY, +- "memory.usage_in_bytes", &usage_in_bytes); +- if (ret == 0) +- *kb = (unsigned long) usage_in_bytes >> 10; +- return ret; ++ VIR_CGROUP_BACKEND_CALL(group, getMemoryUsage, -1, kb); + } + + +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index 99754a6310..8bdfc5c835 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -223,6 +223,10 @@ typedef int + unsigned long long *inactiveFile, + unsigned long long *unevictable); + ++typedef int ++(*virCgroupGetMemoryUsageCB)(virCgroupPtr group, ++ unsigned long *kb); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -264,6 +268,7 @@ struct _virCgroupBackend { + + virCgroupSetMemoryCB setMemory; + virCgroupGetMemoryStatCB getMemoryStat; ++ virCgroupGetMemoryUsageCB getMemoryUsage; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index fcb2607e26..4f1d79a758 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -1479,6 +1479,21 @@ virCgroupV1GetMemoryStat(virCgroupPtr group, + } + + ++static int ++virCgroupV1GetMemoryUsage(virCgroupPtr group, ++ unsigned long *kb) ++{ ++ long long unsigned int usage_in_bytes; ++ int ret; ++ ret = virCgroupGetValueU64(group, ++ VIR_CGROUP_CONTROLLER_MEMORY, ++ "memory.usage_in_bytes", &usage_in_bytes); ++ if (ret == 0) ++ *kb = (unsigned long) usage_in_bytes >> 10; ++ return ret; ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + +@@ -1518,6 +1533,7 @@ virCgroupBackend virCgroupV1Backend = { + + .setMemory = virCgroupV1SetMemory, + .getMemoryStat = virCgroupV1GetMemoryStat, ++ .getMemoryUsage = virCgroupV1GetMemoryUsage, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1HasController.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1HasController.patch new file mode 100644 index 0000000..7865a7d --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1HasController.patch @@ -0,0 +1,92 @@ +From 784cb29187b72cd44c528b1435b27ca5f0a36f33 Mon Sep 17 00:00:00 2001 +Message-Id: <784cb29187b72cd44c528b1435b27ca5f0a36f33@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:32 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1HasController +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 5e2df3d07f63128259a9677acdbbbcd983069110) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 3 ++- + src/util/vircgroupbackend.h | 5 +++++ + src/util/vircgroupv1.c | 9 +++++++++ + 3 files changed, 16 insertions(+), 1 deletion(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 2e74cbbff4..5bbe42b699 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -1443,7 +1443,8 @@ virCgroupHasController(virCgroupPtr cgroup, int controller) + return false; + if (controller < 0 || controller >= VIR_CGROUP_CONTROLLER_LAST) + return false; +- return cgroup->controllers[controller].mountPoint != NULL; ++ ++ return cgroup->backend->hasController(cgroup, controller); + } + + +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index 011d1b00da..29b2fd119f 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -73,6 +73,10 @@ typedef int + (*virCgroupDetectControllersCB)(virCgroupPtr group, + int controllers); + ++typedef bool ++(*virCgroupHasControllerCB)(virCgroupPtr cgroup, ++ int controller); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -86,6 +90,7 @@ struct _virCgroupBackend { + virCgroupValidatePlacementCB validatePlacement; + virCgroupStealPlacementCB stealPlacement; + virCgroupDetectControllersCB detectControllers; ++ virCgroupHasControllerCB hasController; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 11a86c061a..0638f48d50 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -478,6 +478,14 @@ virCgroupV1DetectControllers(virCgroupPtr group, + } + + ++static bool ++virCgroupV1HasController(virCgroupPtr group, ++ int controller) ++{ ++ return group->controllers[controller].mountPoint != NULL; ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + +@@ -490,6 +498,7 @@ virCgroupBackend virCgroupV1Backend = { + .validatePlacement = virCgroupV1ValidatePlacement, + .stealPlacement = virCgroupV1StealPlacement, + .detectControllers = virCgroupV1DetectControllers, ++ .hasController = virCgroupV1HasController, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1HasEmptyTasks.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1HasEmptyTasks.patch new file mode 100644 index 0000000..b040247 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1HasEmptyTasks.patch @@ -0,0 +1,113 @@ +From 272c540c20234508b31dcb9a7c3b548e2e328656 Mon Sep 17 00:00:00 2001 +Message-Id: <272c540c20234508b31dcb9a7c3b548e2e328656@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:38 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1HasEmptyTasks +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit c4047141a0af36c5d428bfcc1f14d012f8352a11) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 13 +------------ + src/util/vircgroupbackend.h | 5 +++++ + src/util/vircgroupv1.c | 20 ++++++++++++++++++++ + 3 files changed, 26 insertions(+), 12 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index a5076cb554..d4d02d8f5b 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -3465,18 +3465,7 @@ virCgroupSupportsCpuBW(virCgroupPtr cgroup) + int + virCgroupHasEmptyTasks(virCgroupPtr cgroup, int controller) + { +- int ret = -1; +- VIR_AUTOFREE(char *) content = NULL; +- +- if (!cgroup) +- return -1; +- +- ret = virCgroupGetValueStr(cgroup, controller, "tasks", &content); +- +- if (ret == 0 && content[0] == '\0') +- ret = 1; +- +- return ret; ++ return cgroup->backend->hasEmptyTasks(cgroup, controller); + } + + bool +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index bff1f8938e..3e0f6d01f4 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -122,6 +122,10 @@ typedef int + pid_t pid, + unsigned int flags); + ++typedef int ++(*virCgroupHasEmptyTasksCB)(virCgroupPtr cgroup, ++ int controller); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -141,6 +145,7 @@ struct _virCgroupBackend { + virCgroupMakeGroupCB makeGroup; + virCgroupRemoveCB remove; + virCgroupAddTaskCB addTask; ++ virCgroupHasEmptyTasksCB hasEmptyTasks; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index fda2c43eef..b057cdfd9e 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -736,6 +736,25 @@ virCgroupV1AddTask(virCgroupPtr group, + } + + ++static int ++virCgroupV1HasEmptyTasks(virCgroupPtr cgroup, ++ int controller) ++{ ++ int ret = -1; ++ VIR_AUTOFREE(char *) content = NULL; ++ ++ if (!cgroup) ++ return -1; ++ ++ ret = virCgroupGetValueStr(cgroup, controller, "tasks", &content); ++ ++ if (ret == 0 && content[0] == '\0') ++ ret = 1; ++ ++ return ret; ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + +@@ -754,6 +773,7 @@ virCgroupBackend virCgroupV1Backend = { + .makeGroup = virCgroupV1MakeGroup, + .remove = virCgroupV1Remove, + .addTask = virCgroupV1AddTask, ++ .hasEmptyTasks = virCgroupV1HasEmptyTasks, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1MakeGroup.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1MakeGroup.patch new file mode 100644 index 0000000..1ddd66d --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1MakeGroup.patch @@ -0,0 +1,446 @@ +From d72932998be48ff4eeb1b9d73d6f5d60560be031 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:35 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1MakeGroup +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 152c0f0bf52d4f727e09f388fef5c836c3c94db4) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 141 ++---------------------------------- + src/util/vircgroupbackend.h | 15 ++++ + src/util/vircgrouppriv.h | 20 +++++ + src/util/vircgroupv1.c | 132 +++++++++++++++++++++++++++++++++ + 4 files changed, 174 insertions(+), 134 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 438d9b4e70..8f0ea4de9a 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -80,14 +80,6 @@ VIR_ENUM_IMPL(virCgroupController, VIR_CGROUP_CONTROLLER_LAST, + "freezer", "blkio", "net_cls", "perf_event", + "name=systemd"); + +-typedef enum { +- VIR_CGROUP_NONE = 0, /* create subdir under each cgroup if possible. */ +- VIR_CGROUP_MEM_HIERACHY = 1 << 0, /* call virCgroupSetMemoryUseHierarchy +- * before creating subcgroups and +- * attaching tasks +- */ +-} virCgroupFlags; +- + + /** + * virCgroupGetDevicePermsString: +@@ -446,7 +438,7 @@ virCgroupGetBlockDevString(const char *path) + } + + +-static int ++int + virCgroupSetValueStr(virCgroupPtr group, + int controller, + const char *key, +@@ -476,7 +468,7 @@ virCgroupSetValueStr(virCgroupPtr group, + } + + +-static int ++int + virCgroupGetValueStr(virCgroupPtr group, + int controller, + const char *key, +@@ -537,7 +529,7 @@ virCgroupGetValueForBlkDev(virCgroupPtr group, + } + + +-static int ++int + virCgroupSetValueU64(virCgroupPtr group, + int controller, + const char *key, +@@ -589,7 +581,7 @@ virCgroupGetValueI64(virCgroupPtr group, + } + + +-static int ++int + virCgroupGetValueU64(virCgroupPtr group, + int controller, + const char *key, +@@ -611,137 +603,18 @@ virCgroupGetValueU64(virCgroupPtr group, + } + + +-static int +-virCgroupCpuSetInherit(virCgroupPtr parent, virCgroupPtr group) +-{ +- size_t i; +- const char *inherit_values[] = { +- "cpuset.cpus", +- "cpuset.mems", +- "cpuset.memory_migrate", +- }; +- +- VIR_DEBUG("Setting up inheritance %s -> %s", parent->path, group->path); +- for (i = 0; i < ARRAY_CARDINALITY(inherit_values); i++) { +- VIR_AUTOFREE(char *) value = NULL; +- +- if (virCgroupGetValueStr(parent, +- VIR_CGROUP_CONTROLLER_CPUSET, +- inherit_values[i], +- &value) < 0) +- return -1; +- +- VIR_DEBUG("Inherit %s = %s", inherit_values[i], value); +- +- if (virCgroupSetValueStr(group, +- VIR_CGROUP_CONTROLLER_CPUSET, +- inherit_values[i], +- value) < 0) +- return -1; +- } +- +- return 0; +-} +- +- +-static int +-virCgroupSetMemoryUseHierarchy(virCgroupPtr group) +-{ +- unsigned long long value; +- const char *filename = "memory.use_hierarchy"; +- +- if (virCgroupGetValueU64(group, +- VIR_CGROUP_CONTROLLER_MEMORY, +- filename, &value) < 0) +- return -1; +- +- /* Setting twice causes error, so if already enabled, skip setting */ +- if (value == 1) +- return 0; +- +- VIR_DEBUG("Setting up %s/%s", group->path, filename); +- if (virCgroupSetValueU64(group, +- VIR_CGROUP_CONTROLLER_MEMORY, +- filename, 1) < 0) +- return -1; +- +- return 0; +-} +- +- + static int + virCgroupMakeGroup(virCgroupPtr parent, + virCgroupPtr group, + bool create, + unsigned int flags) + { +- size_t i; +- +- VIR_DEBUG("Make group %s", group->path); +- for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { +- VIR_AUTOFREE(char *) path = NULL; +- +- /* We must never mkdir() in systemd's hierarchy */ +- if (i == VIR_CGROUP_CONTROLLER_SYSTEMD) { +- VIR_DEBUG("Not creating systemd controller group"); +- continue; +- } +- +- /* Skip over controllers that aren't mounted */ +- if (!group->controllers[i].mountPoint) { +- VIR_DEBUG("Skipping unmounted controller %s", +- virCgroupControllerTypeToString(i)); +- continue; +- } +- +- if (virCgroupPathOfController(group, i, "", &path) < 0) +- goto error; +- +- VIR_DEBUG("Make controller %s", path); +- if (!virFileExists(path)) { +- if (!create || +- mkdir(path, 0755) < 0) { +- if (errno == EEXIST) +- continue; +- /* With a kernel that doesn't support multi-level directory +- * for blkio controller, libvirt will fail and disable all +- * other controllers even though they are available. So +- * treat blkio as unmounted if mkdir fails. */ +- if (i == VIR_CGROUP_CONTROLLER_BLKIO) { +- VIR_DEBUG("Ignoring mkdir failure with blkio controller. Kernel probably too old"); +- VIR_FREE(group->controllers[i].mountPoint); +- continue; +- } else { +- virReportSystemError(errno, +- _("Failed to create controller %s for group"), +- virCgroupControllerTypeToString(i)); +- goto error; +- } +- } +- if (i == VIR_CGROUP_CONTROLLER_CPUSET && +- group->controllers[i].mountPoint != NULL && +- virCgroupCpuSetInherit(parent, group) < 0) { +- goto error; +- } +- /* +- * Note that virCgroupSetMemoryUseHierarchy should always be +- * called prior to creating subcgroups and attaching tasks. +- */ +- if ((flags & VIR_CGROUP_MEM_HIERACHY) && +- i == VIR_CGROUP_CONTROLLER_MEMORY && +- group->controllers[i].mountPoint != NULL && +- virCgroupSetMemoryUseHierarchy(group) < 0) { +- goto error; +- } +- } ++ if (group->backend->makeGroup(parent, group, create, flags) < 0) { ++ virCgroupRemove(group); ++ return -1; + } + +- VIR_DEBUG("Done making controllers for group"); + return 0; +- +- error: +- virCgroupRemove(group); +- return -1; + } + + +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index 916227ba6a..b2848c2076 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -27,6 +27,14 @@ + + # define CGROUP_MAX_VAL 512 + ++typedef enum { ++ VIR_CGROUP_NONE = 0, /* create subdir under each cgroup if possible. */ ++ VIR_CGROUP_MEM_HIERACHY = 1 << 0, /* call virCgroupSetMemoryUseHierarchy ++ * before creating subcgroups and ++ * attaching tasks ++ */ ++} virCgroupBackendFlags; ++ + typedef enum { + VIR_CGROUP_BACKEND_TYPE_V1 = 0, + VIR_CGROUP_BACKEND_TYPE_LAST, +@@ -86,6 +94,12 @@ typedef int + const char *key, + char **path); + ++typedef int ++(*virCgroupMakeGroupCB)(virCgroupPtr parent, ++ virCgroupPtr group, ++ bool create, ++ unsigned int flags); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -102,6 +116,7 @@ struct _virCgroupBackend { + virCgroupHasControllerCB hasController; + virCgroupGetAnyControllerCB getAnyController; + virCgroupPathOfControllerCB pathOfController; ++ virCgroupMakeGroupCB makeGroup; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgrouppriv.h b/src/util/vircgrouppriv.h +index e7f4a1f0fc..2e731458d5 100644 +--- a/src/util/vircgrouppriv.h ++++ b/src/util/vircgrouppriv.h +@@ -53,6 +53,26 @@ struct _virCgroup { + virCgroupController controllers[VIR_CGROUP_CONTROLLER_LAST]; + }; + ++int virCgroupSetValueStr(virCgroupPtr group, ++ int controller, ++ const char *key, ++ const char *value); ++ ++int virCgroupGetValueStr(virCgroupPtr group, ++ int controller, ++ const char *key, ++ char **value); ++ ++int virCgroupSetValueU64(virCgroupPtr group, ++ int controller, ++ const char *key, ++ unsigned long long int value); ++ ++int virCgroupGetValueU64(virCgroupPtr group, ++ int controller, ++ const char *key, ++ unsigned long long int *value); ++ + int virCgroupPartitionEscape(char **path); + + int virCgroupNewPartition(const char *path, +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index a6302d71b1..653e848a83 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -537,6 +537,137 @@ virCgroupV1PathOfController(virCgroupPtr group, + } + + ++static int ++virCgroupV1CpuSetInherit(virCgroupPtr parent, ++ virCgroupPtr group) ++{ ++ size_t i; ++ const char *inherit_values[] = { ++ "cpuset.cpus", ++ "cpuset.mems", ++ "cpuset.memory_migrate", ++ }; ++ ++ VIR_DEBUG("Setting up inheritance %s -> %s", parent->path, group->path); ++ for (i = 0; i < ARRAY_CARDINALITY(inherit_values); i++) { ++ VIR_AUTOFREE(char *) value = NULL; ++ ++ if (virCgroupGetValueStr(parent, ++ VIR_CGROUP_CONTROLLER_CPUSET, ++ inherit_values[i], ++ &value) < 0) ++ return -1; ++ ++ VIR_DEBUG("Inherit %s = %s", inherit_values[i], value); ++ ++ if (virCgroupSetValueStr(group, ++ VIR_CGROUP_CONTROLLER_CPUSET, ++ inherit_values[i], ++ value) < 0) ++ return -1; ++ } ++ ++ return 0; ++} ++ ++ ++static int ++virCgroupV1SetMemoryUseHierarchy(virCgroupPtr group) ++{ ++ unsigned long long value; ++ const char *filename = "memory.use_hierarchy"; ++ ++ if (virCgroupGetValueU64(group, ++ VIR_CGROUP_CONTROLLER_MEMORY, ++ filename, &value) < 0) ++ return -1; ++ ++ /* Setting twice causes error, so if already enabled, skip setting */ ++ if (value == 1) ++ return 0; ++ ++ VIR_DEBUG("Setting up %s/%s", group->path, filename); ++ if (virCgroupSetValueU64(group, ++ VIR_CGROUP_CONTROLLER_MEMORY, ++ filename, 1) < 0) ++ return -1; ++ ++ return 0; ++} ++ ++ ++static int ++virCgroupV1MakeGroup(virCgroupPtr parent, ++ virCgroupPtr group, ++ bool create, ++ unsigned int flags) ++{ ++ size_t i; ++ ++ VIR_DEBUG("Make group %s", group->path); ++ for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { ++ VIR_AUTOFREE(char *) path = NULL; ++ ++ /* We must never mkdir() in systemd's hierarchy */ ++ if (i == VIR_CGROUP_CONTROLLER_SYSTEMD) { ++ VIR_DEBUG("Not creating systemd controller group"); ++ continue; ++ } ++ ++ /* Skip over controllers that aren't mounted */ ++ if (!group->controllers[i].mountPoint) { ++ VIR_DEBUG("Skipping unmounted controller %s", ++ virCgroupV1ControllerTypeToString(i)); ++ continue; ++ } ++ ++ if (virCgroupV1PathOfController(group, i, "", &path) < 0) ++ return -1; ++ ++ VIR_DEBUG("Make controller %s", path); ++ if (!virFileExists(path)) { ++ if (!create || ++ mkdir(path, 0755) < 0) { ++ if (errno == EEXIST) ++ continue; ++ /* With a kernel that doesn't support multi-level directory ++ * for blkio controller, libvirt will fail and disable all ++ * other controllers even though they are available. So ++ * treat blkio as unmounted if mkdir fails. */ ++ if (i == VIR_CGROUP_CONTROLLER_BLKIO) { ++ VIR_DEBUG("Ignoring mkdir failure with blkio controller. Kernel probably too old"); ++ VIR_FREE(group->controllers[i].mountPoint); ++ continue; ++ } else { ++ virReportSystemError(errno, ++ _("Failed to create v1 controller %s for group"), ++ virCgroupV1ControllerTypeToString(i)); ++ return -1; ++ } ++ } ++ if (i == VIR_CGROUP_CONTROLLER_CPUSET && ++ group->controllers[i].mountPoint != NULL && ++ virCgroupV1CpuSetInherit(parent, group) < 0) { ++ return -1; ++ } ++ /* ++ * Note that virCgroupV1SetMemoryUseHierarchy should always be ++ * called prior to creating subcgroups and attaching tasks. ++ */ ++ if ((flags & VIR_CGROUP_MEM_HIERACHY) && ++ i == VIR_CGROUP_CONTROLLER_MEMORY && ++ group->controllers[i].mountPoint != NULL && ++ virCgroupV1SetMemoryUseHierarchy(group) < 0) { ++ return -1; ++ } ++ } ++ } ++ ++ VIR_DEBUG("Done making controllers for group"); ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + +@@ -552,6 +683,7 @@ virCgroupBackend virCgroupV1Backend = { + .hasController = virCgroupV1HasController, + .getAnyController = virCgroupV1GetAnyController, + .pathOfController = virCgroupV1PathOfController, ++ .makeGroup = virCgroupV1MakeGroup, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1PathOfController.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1PathOfController.patch new file mode 100644 index 0000000..d0dc80a --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1PathOfController.patch @@ -0,0 +1,135 @@ +From 66611194a3195560a9aea899b9da724154a03609 Mon Sep 17 00:00:00 2001 +Message-Id: <66611194a3195560a9aea899b9da724154a03609@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:34 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1PathOfController +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 57890b2ab49b27ca9dc8a3922fe61e586aca8f77) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <0867ff8a5f46a8909e621bfb730942cfac3b2cdb.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 22 +--------------------- + src/util/vircgroupbackend.h | 7 +++++++ + src/util/vircgroupv1.c | 31 +++++++++++++++++++++++++++++++ + 3 files changed, 39 insertions(+), 21 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index a6f529accd..438d9b4e70 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -1460,27 +1460,7 @@ virCgroupPathOfController(virCgroupPtr group, + return -1; + } + +- if (group->controllers[controller].mountPoint == NULL) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Controller '%s' is not mounted"), +- virCgroupControllerTypeToString(controller)); +- return -1; +- } +- +- if (group->controllers[controller].placement == NULL) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Controller '%s' is not enabled for group"), +- virCgroupControllerTypeToString(controller)); +- return -1; +- } +- +- if (virAsprintf(path, "%s%s/%s", +- group->controllers[controller].mountPoint, +- group->controllers[controller].placement, +- key ? key : "") < 0) +- return -1; +- +- return 0; ++ return group->backend->pathOfController(group, controller, key, path); + } + + +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index b4eaa89021..916227ba6a 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -80,6 +80,12 @@ typedef bool + typedef int + (*virCgroupGetAnyControllerCB)(virCgroupPtr group); + ++typedef int ++(*virCgroupPathOfControllerCB)(virCgroupPtr group, ++ int controller, ++ const char *key, ++ char **path); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -95,6 +101,7 @@ struct _virCgroupBackend { + virCgroupDetectControllersCB detectControllers; + virCgroupHasControllerCB hasController; + virCgroupGetAnyControllerCB getAnyController; ++ virCgroupPathOfControllerCB pathOfController; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index bae16b8294..a6302d71b1 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -507,6 +507,36 @@ virCgroupV1GetAnyController(virCgroupPtr group) + } + + ++static int ++virCgroupV1PathOfController(virCgroupPtr group, ++ int controller, ++ const char *key, ++ char **path) ++{ ++ if (group->controllers[controller].mountPoint == NULL) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("v1 controller '%s' is not mounted"), ++ virCgroupV1ControllerTypeToString(controller)); ++ return -1; ++ } ++ ++ if (group->controllers[controller].placement == NULL) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("v1 controller '%s' is not enabled for group"), ++ virCgroupV1ControllerTypeToString(controller)); ++ return -1; ++ } ++ ++ if (virAsprintf(path, "%s%s/%s", ++ group->controllers[controller].mountPoint, ++ group->controllers[controller].placement, ++ key ? key : "") < 0) ++ return -1; ++ ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + +@@ -521,6 +551,7 @@ virCgroupBackend virCgroupV1Backend = { + .detectControllers = virCgroupV1DetectControllers, + .hasController = virCgroupV1HasController, + .getAnyController = virCgroupV1GetAnyController, ++ .pathOfController = virCgroupV1PathOfController, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1Remove.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1Remove.patch new file mode 100644 index 0000000..6dfd27d --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1Remove.patch @@ -0,0 +1,172 @@ +From 251261233d1dcfe086230f6b079c8b3b6518d60f Mon Sep 17 00:00:00 2001 +Message-Id: <251261233d1dcfe086230f6b079c8b3b6518d60f@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:36 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1Remove +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit b148d080495a989db6960ad4ac7e83e576957dfe) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 35 ++------------------------------- + src/util/vircgroupbackend.h | 4 ++++ + src/util/vircgrouppriv.h | 2 ++ + src/util/vircgroupv1.c | 39 +++++++++++++++++++++++++++++++++++++ + 4 files changed, 47 insertions(+), 33 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 8f0ea4de9a..33d34d6eda 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -2923,7 +2923,7 @@ virCgroupGetCpuacctPercpuUsage(virCgroupPtr group, char **usage) + } + + +-static int ++int + virCgroupRemoveRecursively(char *grppath) + { + DIR *grpdir; +@@ -2986,38 +2986,7 @@ virCgroupRemoveRecursively(char *grppath) + int + virCgroupRemove(virCgroupPtr group) + { +- int rc = 0; +- size_t i; +- +- VIR_DEBUG("Removing cgroup %s", group->path); +- for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { +- VIR_AUTOFREE(char *) grppath = NULL; +- +- /* Skip over controllers not mounted */ +- if (!group->controllers[i].mountPoint) +- continue; +- +- /* We must never rmdir() in systemd's hierarchy */ +- if (i == VIR_CGROUP_CONTROLLER_SYSTEMD) +- continue; +- +- /* Don't delete the root group, if we accidentally +- ended up in it for some reason */ +- if (STREQ(group->controllers[i].placement, "/")) +- continue; +- +- if (virCgroupPathOfController(group, +- i, +- NULL, +- &grppath) != 0) +- continue; +- +- VIR_DEBUG("Removing cgroup %s and all child cgroups", grppath); +- rc = virCgroupRemoveRecursively(grppath); +- } +- VIR_DEBUG("Done removing cgroup %s", group->path); +- +- return rc; ++ return group->backend->remove(group); + } + + +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index b2848c2076..1f28c51c49 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -100,6 +100,9 @@ typedef int + bool create, + unsigned int flags); + ++typedef int ++(*virCgroupRemoveCB)(virCgroupPtr group); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -117,6 +120,7 @@ struct _virCgroupBackend { + virCgroupGetAnyControllerCB getAnyController; + virCgroupPathOfControllerCB pathOfController; + virCgroupMakeGroupCB makeGroup; ++ virCgroupRemoveCB remove; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgrouppriv.h b/src/util/vircgrouppriv.h +index 2e731458d5..a760b9bcfd 100644 +--- a/src/util/vircgrouppriv.h ++++ b/src/util/vircgrouppriv.h +@@ -88,4 +88,6 @@ int virCgroupNewDomainPartition(virCgroupPtr partition, + virCgroupPtr *group) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(5); + ++int virCgroupRemoveRecursively(char *grppath); ++ + #endif /* __VIR_CGROUP_PRIV_H__ */ +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 653e848a83..4d4b51094a 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -668,6 +668,44 @@ virCgroupV1MakeGroup(virCgroupPtr parent, + } + + ++static int ++virCgroupV1Remove(virCgroupPtr group) ++{ ++ int rc = 0; ++ size_t i; ++ ++ VIR_DEBUG("Removing cgroup %s", group->path); ++ for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { ++ VIR_AUTOFREE(char *) grppath = NULL; ++ ++ /* Skip over controllers not mounted */ ++ if (!group->controllers[i].mountPoint) ++ continue; ++ ++ /* We must never rmdir() in systemd's hierarchy */ ++ if (i == VIR_CGROUP_CONTROLLER_SYSTEMD) ++ continue; ++ ++ /* Don't delete the root group, if we accidentally ++ ended up in it for some reason */ ++ if (STREQ(group->controllers[i].placement, "/")) ++ continue; ++ ++ if (virCgroupV1PathOfController(group, ++ i, ++ NULL, ++ &grppath) != 0) ++ continue; ++ ++ VIR_DEBUG("Removing cgroup %s and all child cgroups", grppath); ++ rc = virCgroupRemoveRecursively(grppath); ++ } ++ VIR_DEBUG("Done removing cgroup %s", group->path); ++ ++ return rc; ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + +@@ -684,6 +722,7 @@ virCgroupBackend virCgroupV1Backend = { + .getAnyController = virCgroupV1GetAnyController, + .pathOfController = virCgroupV1PathOfController, + .makeGroup = virCgroupV1MakeGroup, ++ .remove = virCgroupV1Remove, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1SetMemory.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1SetMemory.patch new file mode 100644 index 0000000..975964c --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1SetMemory.patch @@ -0,0 +1,129 @@ +From 75e53d9323c069ece39b40a99675425967ac2d62 Mon Sep 17 00:00:00 2001 +Message-Id: <75e53d9323c069ece39b40a99675425967ac2d62@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:49 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1SetMemory +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 53f43deb0dfa666cb8c614cabbf5add075ccc33f) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 20 +------------------- + src/util/vircgroupbackend.h | 6 ++++++ + src/util/vircgroupv1.c | 28 ++++++++++++++++++++++++++++ + 3 files changed, 35 insertions(+), 19 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 684bce4997..4053c65939 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -1593,25 +1593,7 @@ virCgroupGetMemoryUnlimitedKB(void) + int + virCgroupSetMemory(virCgroupPtr group, unsigned long long kb) + { +- unsigned long long maxkb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; +- +- if (kb > maxkb) { +- virReportError(VIR_ERR_INVALID_ARG, +- _("Memory '%llu' must be less than %llu"), +- kb, maxkb); +- return -1; +- } +- +- if (kb == maxkb) +- return virCgroupSetValueI64(group, +- VIR_CGROUP_CONTROLLER_MEMORY, +- "memory.limit_in_bytes", +- -1); +- else +- return virCgroupSetValueU64(group, +- VIR_CGROUP_CONTROLLER_MEMORY, +- "memory.limit_in_bytes", +- kb << 10); ++ VIR_CGROUP_BACKEND_CALL(group, setMemory, -1, kb); + } + + +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index 67e795a2b7..e1f75c5c31 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -210,6 +210,10 @@ typedef int + const char *path, + unsigned long long *wbps); + ++typedef int ++(*virCgroupSetMemoryCB)(virCgroupPtr group, ++ unsigned long long kb); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -248,6 +252,8 @@ struct _virCgroupBackend { + virCgroupGetBlkioDeviceReadBpsCB getBlkioDeviceReadBps; + virCgroupSetBlkioDeviceWriteBpsCB setBlkioDeviceWriteBps; + virCgroupGetBlkioDeviceWriteBpsCB getBlkioDeviceWriteBps; ++ ++ virCgroupSetMemoryCB setMemory; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index c044414dfd..17a4d67972 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -1378,6 +1378,32 @@ virCgroupV1GetBlkioDeviceWriteBps(virCgroupPtr group, + } + + ++static int ++virCgroupV1SetMemory(virCgroupPtr group, ++ unsigned long long kb) ++{ ++ unsigned long long maxkb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; ++ ++ if (kb > maxkb) { ++ virReportError(VIR_ERR_INVALID_ARG, ++ _("Memory '%llu' must be less than %llu"), ++ kb, maxkb); ++ return -1; ++ } ++ ++ if (kb == maxkb) ++ return virCgroupSetValueI64(group, ++ VIR_CGROUP_CONTROLLER_MEMORY, ++ "memory.limit_in_bytes", ++ -1); ++ else ++ return virCgroupSetValueU64(group, ++ VIR_CGROUP_CONTROLLER_MEMORY, ++ "memory.limit_in_bytes", ++ kb << 10); ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + +@@ -1414,6 +1440,8 @@ virCgroupBackend virCgroupV1Backend = { + .getBlkioDeviceReadBps = virCgroupV1GetBlkioDeviceReadBps, + .setBlkioDeviceWriteBps = virCgroupV1SetBlkioDeviceWriteBps, + .getBlkioDeviceWriteBps = virCgroupV1GetBlkioDeviceWriteBps, ++ ++ .setMemory = virCgroupV1SetMemory, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1SetOwner.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1SetOwner.patch new file mode 100644 index 0000000..975b387 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1SetOwner.patch @@ -0,0 +1,198 @@ +From 955ac573d3291bfb069664e2df9f4edb0ed09313 Mon Sep 17 00:00:00 2001 +Message-Id: <955ac573d3291bfb069664e2df9f4edb0ed09313@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:40 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1SetOwner +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit dad061101d34a8e4b76ec3c03253ed3e83b50b2a) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <644b2434def24cbb7834a7950595c110d5438166.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 54 +------------------------------ + src/util/vircgroupbackend.h | 7 +++++ + src/util/vircgroupv1.c | 63 +++++++++++++++++++++++++++++++++++++ + 3 files changed, 71 insertions(+), 53 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 7789966472..e57aecb08a 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -3282,59 +3282,7 @@ int virCgroupSetOwner(virCgroupPtr cgroup, + gid_t gid, + int controllers) + { +- int ret = -1; +- size_t i; +- DIR *dh = NULL; +- int direrr; +- +- for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { +- VIR_AUTOFREE(char *) base = NULL; +- struct dirent *de; +- +- if (!((1 << i) & controllers)) +- continue; +- +- if (!cgroup->controllers[i].mountPoint) +- continue; +- +- if (virAsprintf(&base, "%s%s", cgroup->controllers[i].mountPoint, +- cgroup->controllers[i].placement) < 0) +- goto cleanup; +- +- if (virDirOpen(&dh, base) < 0) +- goto cleanup; +- +- while ((direrr = virDirRead(dh, &de, base)) > 0) { +- VIR_AUTOFREE(char *) entry = NULL; +- +- if (virAsprintf(&entry, "%s/%s", base, de->d_name) < 0) +- goto cleanup; +- +- if (chown(entry, uid, gid) < 0) { +- virReportSystemError(errno, +- _("cannot chown '%s' to (%u, %u)"), +- entry, uid, gid); +- goto cleanup; +- } +- } +- if (direrr < 0) +- goto cleanup; +- +- if (chown(base, uid, gid) < 0) { +- virReportSystemError(errno, +- _("cannot chown '%s' to (%u, %u)"), +- base, uid, gid); +- goto cleanup; +- } +- +- VIR_DIR_CLOSE(dh); +- } +- +- ret = 0; +- +- cleanup: +- VIR_DIR_CLOSE(dh); +- return ret; ++ return cgroup->backend->setOwner(cgroup, uid, gid, controllers); + } + + +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index caeec3de60..74af796c2f 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -131,6 +131,12 @@ typedef int + const char *oldroot, + const char *mountopts); + ++typedef int ++(*virCgroupSetOwnerCB)(virCgroupPtr cgroup, ++ uid_t uid, ++ gid_t gid, ++ int controllers); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -152,6 +158,7 @@ struct _virCgroupBackend { + virCgroupAddTaskCB addTask; + virCgroupHasEmptyTasksCB hasEmptyTasks; + virCgroupBindMountCB bindMount; ++ virCgroupSetOwnerCB setOwner; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index d63525dfb0..c1e2583912 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -867,6 +867,68 @@ virCgroupV1BindMount(virCgroupPtr group, + } + + ++static int ++virCgroupV1SetOwner(virCgroupPtr cgroup, ++ uid_t uid, ++ gid_t gid, ++ int controllers) ++{ ++ int ret = -1; ++ size_t i; ++ DIR *dh = NULL; ++ int direrr; ++ ++ for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { ++ VIR_AUTOFREE(char *) base = NULL; ++ struct dirent *de; ++ ++ if (!((1 << i) & controllers)) ++ continue; ++ ++ if (!cgroup->controllers[i].mountPoint) ++ continue; ++ ++ if (virAsprintf(&base, "%s%s", cgroup->controllers[i].mountPoint, ++ cgroup->controllers[i].placement) < 0) ++ goto cleanup; ++ ++ if (virDirOpen(&dh, base) < 0) ++ goto cleanup; ++ ++ while ((direrr = virDirRead(dh, &de, base)) > 0) { ++ VIR_AUTOFREE(char *) entry = NULL; ++ ++ if (virAsprintf(&entry, "%s/%s", base, de->d_name) < 0) ++ goto cleanup; ++ ++ if (chown(entry, uid, gid) < 0) { ++ virReportSystemError(errno, ++ _("cannot chown '%s' to (%u, %u)"), ++ entry, uid, gid); ++ goto cleanup; ++ } ++ } ++ if (direrr < 0) ++ goto cleanup; ++ ++ if (chown(base, uid, gid) < 0) { ++ virReportSystemError(errno, ++ _("cannot chown '%s' to (%u, %u)"), ++ base, uid, gid); ++ goto cleanup; ++ } ++ ++ VIR_DIR_CLOSE(dh); ++ } ++ ++ ret = 0; ++ ++ cleanup: ++ VIR_DIR_CLOSE(dh); ++ return ret; ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + +@@ -887,6 +949,7 @@ virCgroupBackend virCgroupV1Backend = { + .addTask = virCgroupV1AddTask, + .hasEmptyTasks = virCgroupV1HasEmptyTasks, + .bindMount = virCgroupV1BindMount, ++ .setOwner = virCgroupV1SetOwner, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1StealPlacement.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1StealPlacement.patch new file mode 100644 index 0000000..11e2ff4 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1StealPlacement.patch @@ -0,0 +1,94 @@ +From 6f37c631f12c0e9b7e9fe8ade5b5a98392090cfb Mon Sep 17 00:00:00 2001 +Message-Id: <6f37c631f12c0e9b7e9fe8ade5b5a98392090cfb@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:30 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1StealPlacement +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 12264c12c819259edeb3e5adb59281906b673ca7) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <5f083ec4400455a10608945377f943a071e36c43.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 3 +-- + src/util/vircgroupbackend.h | 4 ++++ + src/util/vircgroupv1.c | 12 ++++++++++++ + 3 files changed, 17 insertions(+), 2 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index b17a1dcbb7..0e64ad67f4 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -1323,8 +1323,7 @@ virCgroupNewMachineSystemd(const char *name, + &init) < 0) + return -1; + +- path = init->controllers[VIR_CGROUP_CONTROLLER_SYSTEMD].placement; +- init->controllers[VIR_CGROUP_CONTROLLER_SYSTEMD].placement = NULL; ++ path = init->backend->stealPlacement(init); + virCgroupFree(&init); + + if (!path || STREQ(path, "/") || path[0] != '/') { +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index 086cfb8090..9c0bd89793 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -66,6 +66,9 @@ typedef int + (*virCgroupValidatePlacementCB)(virCgroupPtr group, + pid_t pid); + ++typedef char * ++(*virCgroupStealPlacementCB)(virCgroupPtr group); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -77,6 +80,7 @@ struct _virCgroupBackend { + virCgroupDetectMountsCB detectMounts; + virCgroupDetectPlacementCB detectPlacement; + virCgroupValidatePlacementCB validatePlacement; ++ virCgroupStealPlacementCB stealPlacement; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 2c905a832a..446546fd58 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -403,6 +403,17 @@ virCgroupV1ValidatePlacement(virCgroupPtr group, + } + + ++static char * ++virCgroupV1StealPlacement(virCgroupPtr group) ++{ ++ char *ret = NULL; ++ ++ VIR_STEAL_PTR(ret, group->controllers[VIR_CGROUP_CONTROLLER_SYSTEMD].placement); ++ ++ return ret; ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + +@@ -413,6 +424,7 @@ virCgroupBackend virCgroupV1Backend = { + .detectMounts = virCgroupV1DetectMounts, + .detectPlacement = virCgroupV1DetectPlacement, + .validatePlacement = virCgroupV1ValidatePlacement, ++ .stealPlacement = virCgroupV1StealPlacement, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1SupportsCpuBW.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1SupportsCpuBW.patch new file mode 100644 index 0000000..18f0dc8 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1SupportsCpuBW.patch @@ -0,0 +1,111 @@ +From 36f035a5d6620f5f39f4aec45d4ec1ec0fa7ccbc Mon Sep 17 00:00:00 2001 +Message-Id: <36f035a5d6620f5f39f4aec45d4ec1ec0fa7ccbc@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:59 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1SupportsCpuBW +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit d182fac0bb07ff06ca938b40030849f86dfa24f1) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <679862bf39de7fbd81ab5b1e65c61cf578abb944.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 13 +------------ + src/util/vircgroupbackend.h | 4 ++++ + src/util/vircgroupv1.c | 19 +++++++++++++++++++ + 3 files changed, 24 insertions(+), 12 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index a3e7954d03..fa9fa52019 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -2685,18 +2685,7 @@ int virCgroupSetOwner(virCgroupPtr cgroup, + bool + virCgroupSupportsCpuBW(virCgroupPtr cgroup) + { +- VIR_AUTOFREE(char *) path = NULL; +- +- if (!cgroup) +- return false; +- +- if (virCgroupPathOfController(cgroup, VIR_CGROUP_CONTROLLER_CPU, +- "cpu.cfs_period_us", &path) < 0) { +- virResetLastError(); +- return false; +- } +- +- return virFileExists(path); ++ VIR_CGROUP_BACKEND_CALL(cgroup, supportsCpuBW, false); + } + + int +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index f7c230db76..d3d5e7c222 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -300,6 +300,9 @@ typedef int + (*virCgroupGetCpuCfsQuotaCB)(virCgroupPtr group, + long long *cfs_quota); + ++typedef bool ++(*virCgroupSupportsCpuBWCB)(virCgroupPtr cgroup); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -361,6 +364,7 @@ struct _virCgroupBackend { + virCgroupGetCpuCfsPeriodCB getCpuCfsPeriod; + virCgroupSetCpuCfsQuotaCB setCpuCfsQuota; + virCgroupGetCpuCfsQuotaCB getCpuCfsQuota; ++ virCgroupSupportsCpuBWCB supportsCpuBW; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 25f7376026..f2a8839f6e 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -1846,6 +1846,24 @@ virCgroupV1GetCpuCfsQuota(virCgroupPtr group, + } + + ++static bool ++virCgroupV1SupportsCpuBW(virCgroupPtr cgroup) ++{ ++ VIR_AUTOFREE(char *) path = NULL; ++ ++ if (!cgroup) ++ return false; ++ ++ if (virCgroupV1PathOfController(cgroup, VIR_CGROUP_CONTROLLER_CPU, ++ "cpu.cfs_period_us", &path) < 0) { ++ virResetLastError(); ++ return false; ++ } ++ ++ return virFileExists(path); ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + +@@ -1905,6 +1923,7 @@ virCgroupBackend virCgroupV1Backend = { + .getCpuCfsPeriod = virCgroupV1GetCpuCfsPeriod, + .setCpuCfsQuota = virCgroupV1SetCpuCfsQuota, + .getCpuCfsQuota = virCgroupV1GetCpuCfsQuota, ++ .supportsCpuBW = virCgroupV1SupportsCpuBW, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1ValidateMachineGroup.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1ValidateMachineGroup.patch new file mode 100644 index 0000000..a8bbadb --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1ValidateMachineGroup.patch @@ -0,0 +1,290 @@ +From e950a43b63a79cf68e835d800688d759ba408178 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:25 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1ValidateMachineGroup +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 61629d5be3a4809fe05feb15adbc8f2c27916702) + +Conflicts: + src/util/vircgroupv1.c: missing commit c0abcca417 + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 85 +------------------------------------ + src/util/vircgroupbackend.h | 7 +++ + src/util/vircgrouppriv.h | 2 + + src/util/vircgroupv1.c | 85 +++++++++++++++++++++++++++++++++++++ + 4 files changed, 96 insertions(+), 83 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 15d0cb65ac..6825623478 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -216,7 +216,7 @@ virCgroupPartitionNeedsEscaping(const char *path) + } + + +-static int ++int + virCgroupPartitionEscape(char **path) + { + int rc; +@@ -235,87 +235,6 @@ virCgroupPartitionEscape(char **path) + } + + +-static bool +-virCgroupValidateMachineGroup(virCgroupPtr group, +- const char *name, +- const char *drivername, +- const char *machinename) +-{ +- size_t i; +- VIR_AUTOFREE(char *) partname = NULL; +- VIR_AUTOFREE(char *) scopename_old = NULL; +- VIR_AUTOFREE(char *) scopename_new = NULL; +- VIR_AUTOFREE(char *) partmachinename = NULL; +- +- if (virAsprintf(&partname, "%s.libvirt-%s", +- name, drivername) < 0) +- return false; +- +- if (virCgroupPartitionEscape(&partname) < 0) +- return false; +- +- if (virAsprintf(&partmachinename, "%s.libvirt-%s", +- machinename, drivername) < 0 || +- virCgroupPartitionEscape(&partmachinename) < 0) +- return false; +- +- if (!(scopename_old = virSystemdMakeScopeName(name, drivername, true))) +- return false; +- +- if (!(scopename_new = virSystemdMakeScopeName(machinename, +- drivername, false))) +- return false; +- +- if (virCgroupPartitionEscape(&scopename_old) < 0) +- return false; +- +- if (virCgroupPartitionEscape(&scopename_new) < 0) +- return false; +- +- for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { +- char *tmp; +- +- if (i == VIR_CGROUP_CONTROLLER_SYSTEMD) +- continue; +- +- if (!group->controllers[i].placement) +- continue; +- +- tmp = strrchr(group->controllers[i].placement, '/'); +- if (!tmp) +- return false; +- +- if (i == VIR_CGROUP_CONTROLLER_CPU || +- i == VIR_CGROUP_CONTROLLER_CPUACCT || +- i == VIR_CGROUP_CONTROLLER_CPUSET) { +- if (STREQ(tmp, "/emulator")) +- *tmp = '\0'; +- tmp = strrchr(group->controllers[i].placement, '/'); +- if (!tmp) +- return false; +- } +- +- tmp++; +- +- if (STRNEQ(tmp, name) && +- STRNEQ(tmp, machinename) && +- STRNEQ(tmp, partname) && +- STRNEQ(tmp, partmachinename) && +- STRNEQ(tmp, scopename_old) && +- STRNEQ(tmp, scopename_new)) { +- VIR_DEBUG("Name '%s' for controller '%s' does not match " +- "'%s', '%s', '%s', '%s' or '%s'", +- tmp, virCgroupControllerTypeToString(i), +- name, machinename, partname, +- scopename_old, scopename_new); +- return false; +- } +- } +- +- return true; +-} +- +- + static int + virCgroupCopyMounts(virCgroupPtr group, + virCgroupPtr parent) +@@ -1508,7 +1427,7 @@ virCgroupNewDetectMachine(const char *name, + return -1; + } + +- if (!virCgroupValidateMachineGroup(*group, name, drivername, machinename)) { ++ if (!(*group)->backend->validateMachineGroup(*group, name, drivername, machinename)) { + VIR_DEBUG("Failed to validate machine name for '%s' driver '%s'", + name, drivername); + virCgroupFree(group); +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index 88f51416b0..daf47bac09 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -35,11 +35,18 @@ typedef enum { + typedef bool + (*virCgroupAvailableCB)(void); + ++typedef bool ++(*virCgroupValidateMachineGroupCB)(virCgroupPtr group, ++ const char *name, ++ const char *drivername, ++ const char *machinename); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + + /* Mandatory callbacks that need to be implemented for every backend. */ + virCgroupAvailableCB available; ++ virCgroupValidateMachineGroupCB validateMachineGroup; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgrouppriv.h b/src/util/vircgrouppriv.h +index 2caa966fee..e7f4a1f0fc 100644 +--- a/src/util/vircgrouppriv.h ++++ b/src/util/vircgrouppriv.h +@@ -53,6 +53,8 @@ struct _virCgroup { + virCgroupController controllers[VIR_CGROUP_CONTROLLER_LAST]; + }; + ++int virCgroupPartitionEscape(char **path); ++ + int virCgroupNewPartition(const char *path, + bool create, + int controllers, +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 73045b1109..b78cdcab53 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -30,11 +30,14 @@ + #include "vircgrouppriv.h" + #undef __VIR_CGROUP_ALLOW_INCLUDE_PRIV_H__ + ++#include "viralloc.h" + #include "vircgroup.h" + #include "vircgroupbackend.h" + #include "vircgroupv1.h" + #include "virfile.h" + #include "virlog.h" ++#include "virstring.h" ++#include "virsystemd.h" + + VIR_LOG_INIT("util.cgroup"); + +@@ -76,10 +79,92 @@ virCgroupV1Available(void) + } + + ++static bool ++virCgroupV1ValidateMachineGroup(virCgroupPtr group, ++ const char *name, ++ const char *drivername, ++ const char *machinename) ++{ ++ size_t i; ++ VIR_AUTOFREE(char *) partname = NULL; ++ VIR_AUTOFREE(char *) scopename_old = NULL; ++ VIR_AUTOFREE(char *) scopename_new = NULL; ++ VIR_AUTOFREE(char *) partmachinename = NULL; ++ ++ if (virAsprintf(&partname, "%s.libvirt-%s", ++ name, drivername) < 0) ++ return false; ++ ++ if (virCgroupPartitionEscape(&partname) < 0) ++ return false; ++ ++ if (virAsprintf(&partmachinename, "%s.libvirt-%s", ++ machinename, drivername) < 0 || ++ virCgroupPartitionEscape(&partmachinename) < 0) ++ return false; ++ ++ if (!(scopename_old = virSystemdMakeScopeName(name, drivername, true))) ++ return false; ++ ++ if (!(scopename_new = virSystemdMakeScopeName(machinename, ++ drivername, false))) ++ return false; ++ ++ if (virCgroupPartitionEscape(&scopename_old) < 0) ++ return false; ++ ++ if (virCgroupPartitionEscape(&scopename_new) < 0) ++ return false; ++ ++ for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { ++ char *tmp; ++ ++ if (i == VIR_CGROUP_CONTROLLER_SYSTEMD) ++ continue; ++ ++ if (!group->controllers[i].placement) ++ continue; ++ ++ tmp = strrchr(group->controllers[i].placement, '/'); ++ if (!tmp) ++ return false; ++ ++ if (i == VIR_CGROUP_CONTROLLER_CPU || ++ i == VIR_CGROUP_CONTROLLER_CPUACCT || ++ i == VIR_CGROUP_CONTROLLER_CPUSET) { ++ if (STREQ(tmp, "/emulator")) ++ *tmp = '\0'; ++ tmp = strrchr(group->controllers[i].placement, '/'); ++ if (!tmp) ++ return false; ++ } ++ ++ tmp++; ++ ++ if (STRNEQ(tmp, name) && ++ STRNEQ(tmp, machinename) && ++ STRNEQ(tmp, partname) && ++ STRNEQ(tmp, partmachinename) && ++ STRNEQ(tmp, scopename_old) && ++ STRNEQ(tmp, scopename_new)) { ++ VIR_DEBUG("Name '%s' for controller '%s' does not match " ++ "'%s', '%s', '%s', '%s' or '%s'", ++ tmp, virCgroupV1ControllerTypeToString(i), ++ name, machinename, partname, ++ scopename_old, scopename_new); ++ return false; ++ } ++ } ++ ++ return true; ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + + .available = virCgroupV1Available, ++ .validateMachineGroup = virCgroupV1ValidateMachineGroup, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-extract-virCgroupV1ValidatePlacement.patch b/SOURCES/libvirt-vircgroup-extract-virCgroupV1ValidatePlacement.patch new file mode 100644 index 0000000..ddd9afb --- /dev/null +++ b/SOURCES/libvirt-vircgroup-extract-virCgroupV1ValidatePlacement.patch @@ -0,0 +1,150 @@ +From a4fad1d74b1af03d7bd89d4ef1bc1be4d7c9feca Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:29 +0200 +Subject: [PATCH] vircgroup: extract virCgroupV1ValidatePlacement +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit b549a66edf46ced7c2b922408f3c7cdad2539e0b) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <0fac794a48f75788ccfab8614ac8e7f051df2719.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 32 +------------------------------- + src/util/vircgroupbackend.h | 5 +++++ + src/util/vircgroupv1.c | 31 +++++++++++++++++++++++++++++++ + 3 files changed, 37 insertions(+), 31 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index b63321ca33..b17a1dcbb7 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -349,36 +349,6 @@ virCgroupDetectPlacement(virCgroupPtr group, + } + + +-static int +-virCgroupValidatePlacement(virCgroupPtr group, +- pid_t pid) +-{ +- size_t i; +- +- for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { +- if (!group->controllers[i].mountPoint) +- continue; +- +- if (!group->controllers[i].placement) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Could not find placement for controller %s at %s"), +- virCgroupControllerTypeToString(i), +- group->controllers[i].placement); +- return -1; +- } +- +- VIR_DEBUG("Detected mount/mapping %zu:%s at %s in %s for pid %lld", +- i, +- virCgroupControllerTypeToString(i), +- group->controllers[i].mountPoint, +- group->controllers[i].placement, +- (long long) pid); +- } +- +- return 0; +-} +- +- + static int + virCgroupDetectControllers(virCgroupPtr group, + int controllers) +@@ -504,7 +474,7 @@ virCgroupDetect(virCgroupPtr group, + return -1; + + /* Check that for every mounted controller, we found our placement */ +- if (virCgroupValidatePlacement(group, pid) < 0) ++ if (group->backend->validatePlacement(group, pid) < 0) + return -1; + + return 0; +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index 85906e7191..086cfb8090 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -62,6 +62,10 @@ typedef int + const char *controllers, + const char *selfpath); + ++typedef int ++(*virCgroupValidatePlacementCB)(virCgroupPtr group, ++ pid_t pid); ++ + struct _virCgroupBackend { + virCgroupBackendType type; + +@@ -72,6 +76,7 @@ struct _virCgroupBackend { + virCgroupCopyPlacementCB copyPlacement; + virCgroupDetectMountsCB detectMounts; + virCgroupDetectPlacementCB detectPlacement; ++ virCgroupValidatePlacementCB validatePlacement; + }; + typedef struct _virCgroupBackend virCgroupBackend; + typedef virCgroupBackend *virCgroupBackendPtr; +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 68bb1c6f5d..2c905a832a 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -373,6 +373,36 @@ virCgroupV1DetectPlacement(virCgroupPtr group, + } + + ++static int ++virCgroupV1ValidatePlacement(virCgroupPtr group, ++ pid_t pid) ++{ ++ size_t i; ++ ++ for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { ++ if (!group->controllers[i].mountPoint) ++ continue; ++ ++ if (!group->controllers[i].placement) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Could not find placement for v1 controller %s at %s"), ++ virCgroupV1ControllerTypeToString(i), ++ group->controllers[i].placement); ++ return -1; ++ } ++ ++ VIR_DEBUG("Detected mount/mapping %zu:%s at %s in %s for pid %lld", ++ i, ++ virCgroupV1ControllerTypeToString(i), ++ group->controllers[i].mountPoint, ++ group->controllers[i].placement, ++ (long long) pid); ++ } ++ ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV1Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V1, + +@@ -382,6 +412,7 @@ virCgroupBackend virCgroupV1Backend = { + .copyPlacement = virCgroupV1CopyPlacement, + .detectMounts = virCgroupV1DetectMounts, + .detectPlacement = virCgroupV1DetectPlacement, ++ .validatePlacement = virCgroupV1ValidatePlacement, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-fix-MinGW-build.patch b/SOURCES/libvirt-vircgroup-fix-MinGW-build.patch new file mode 100644 index 0000000..8f34771 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-fix-MinGW-build.patch @@ -0,0 +1,52 @@ +From 86426efffd910c22c9cfadc50516883b606c6946 Mon Sep 17 00:00:00 2001 +Message-Id: <86426efffd910c22c9cfadc50516883b606c6946@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:03 +0200 +Subject: [PATCH] vircgroup: fix MinGW build +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Broken by commit <901d2b9c87>. + +Signed-off-by: Pavel Hrdina +(cherry picked from commit baebd9f3d84b5cb86c7c6f35eb41cf9fb7e9b624) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 0ed83932ac..df38bb77e0 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -4335,6 +4335,21 @@ virCgroupSetMemory(virCgroupPtr group ATTRIBUTE_UNUSED, + } + + ++int ++virCgroupGetMemoryStat(virCgroupPtr group ATTRIBUTE_UNUSED, ++ unsigned long long *cache ATTRIBUTE_UNUSED, ++ unsigned long long *activeAnon ATTRIBUTE_UNUSED, ++ unsigned long long *inactiveAnon ATTRIBUTE_UNUSED, ++ unsigned long long *activeFile ATTRIBUTE_UNUSED, ++ unsigned long long *inactiveFile ATTRIBUTE_UNUSED, ++ unsigned long long *unevictable ATTRIBUTE_UNUSED) ++{ ++ virReportSystemError(ENOSYS, "%s", ++ _("Control groups not supported on this platform")); ++ return -1; ++} ++ ++ + int + virCgroupGetMemoryUsage(virCgroupPtr group ATTRIBUTE_UNUSED, + unsigned long *kb ATTRIBUTE_UNUSED) +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-fix-bug-in-virCgroupEnableMissingControllers.patch b/SOURCES/libvirt-vircgroup-fix-bug-in-virCgroupEnableMissingControllers.patch new file mode 100644 index 0000000..18175d4 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-fix-bug-in-virCgroupEnableMissingControllers.patch @@ -0,0 +1,50 @@ +From 5abd9049c8bdea6170dc455033e37811ba875db8 Mon Sep 17 00:00:00 2001 +Message-Id: <5abd9049c8bdea6170dc455033e37811ba875db8@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:13 +0200 +Subject: [PATCH] vircgroup: fix bug in virCgroupEnableMissingControllers +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If we are on host with systemd we need to build cgroup hierarchy +ourselves for controllers that are not managed by systemd. + +As a starting parent we need to force root group because +virCgroupMakeGroup() takes that parent in order to inherit values +for cpuset controller. + +By default cpuset controller is managed by systemd so we will never +hit the issue but for v2 cgroups we need to use parent cgroup every +time. + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 63b4ed0dd3e1555b4c9d82ef0ca0648493f75af2) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 6aa30a82be..2328957818 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -1495,7 +1495,7 @@ virCgroupEnableMissingControllers(char *path, + int ret = -1; + + if (virCgroupNew(pidleader, +- "", ++ "/", + NULL, + controllers, + &parent) < 0) +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-fix-cgroups-v2-controllers-detection.patch b/SOURCES/libvirt-vircgroup-fix-cgroups-v2-controllers-detection.patch new file mode 100644 index 0000000..e7f4d03 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-fix-cgroups-v2-controllers-detection.patch @@ -0,0 +1,128 @@ +From b220fdba77897f65f3e7e963868f22d7ace58724 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Thu, 25 Jul 2019 13:37:01 +0200 +Subject: [PATCH] vircgroup: fix cgroups v2 controllers detection +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When creating new group for cgroups v2 the we cannot check +cgroups.controllers for that cgroup because the directory is created +later. In that case we should check cgroups.subtree_control of parent +group to get list of controllers enabled for child cgroups. + +In order to achieve that we will prefer the parent group if it exists, +the current group will be used only for root group. + +Signed-off-by: Pavel Hrdina +Acked-by: Peter Krempa +(cherry picked from commit 7b77f3a11e9ae3e3cf0ccb71bd72d4a865b7c71e) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 2 +- + src/util/vircgroupbackend.h | 3 ++- + src/util/vircgroupv1.c | 3 ++- + src/util/vircgroupv2.c | 23 ++++++++++++++++------- + 4 files changed, 21 insertions(+), 10 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 37f6def08d..2c067edc5c 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -412,7 +412,7 @@ virCgroupDetect(virCgroupPtr group, + + for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) { + if (group->backends[i]) { +- int rc = group->backends[i]->detectControllers(group, controllers); ++ int rc = group->backends[i]->detectControllers(group, controllers, parent); + if (rc < 0) + return -1; + controllersAvailable |= rc; +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index 2b5be21a76..b97f686368 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -99,7 +99,8 @@ typedef char * + + typedef int + (*virCgroupDetectControllersCB)(virCgroupPtr group, +- int controllers); ++ int controllers, ++ virCgroupPtr parent); + + typedef bool + (*virCgroupHasControllerCB)(virCgroupPtr cgroup, +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index a7d6c92e4c..925e8ee1c1 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -419,7 +419,8 @@ virCgroupV1StealPlacement(virCgroupPtr group) + + static int + virCgroupV1DetectControllers(virCgroupPtr group, +- int controllers) ++ int controllers, ++ virCgroupPtr parent ATTRIBUTE_UNUSED) + { + size_t i; + size_t j; +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index b4e90ed46d..7b3cd64cc5 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -241,7 +241,8 @@ virCgroupV2StealPlacement(virCgroupPtr group) + + + static int +-virCgroupV2ParseControllersFile(virCgroupPtr group) ++virCgroupV2ParseControllersFile(virCgroupPtr group, ++ virCgroupPtr parent) + { + int rc; + VIR_AUTOFREE(char *) contStr = NULL; +@@ -249,10 +250,17 @@ virCgroupV2ParseControllersFile(virCgroupPtr group) + char **contList = NULL; + char **tmp; + +- if (virAsprintf(&contFile, "%s%s/cgroup.controllers", +- group->unified.mountPoint, +- NULLSTR_EMPTY(group->unified.placement)) < 0) +- return -1; ++ if (parent) { ++ if (virAsprintf(&contFile, "%s%s/cgroup.subtree_control", ++ parent->unified.mountPoint, ++ NULLSTR_EMPTY(parent->unified.placement)) < 0) ++ return -1; ++ } else { ++ if (virAsprintf(&contFile, "%s%s/cgroup.controllers", ++ group->unified.mountPoint, ++ NULLSTR_EMPTY(group->unified.placement)) < 0) ++ return -1; ++ } + + rc = virFileReadAll(contFile, 1024 * 1024, &contStr); + if (rc < 0) { +@@ -285,11 +293,12 @@ virCgroupV2ParseControllersFile(virCgroupPtr group) + + static int + virCgroupV2DetectControllers(virCgroupPtr group, +- int controllers) ++ int controllers, ++ virCgroupPtr parent) + { + size_t i; + +- if (virCgroupV2ParseControllersFile(group) < 0) ++ if (virCgroupV2ParseControllersFile(group, parent) < 0) + return -1; + + /* In cgroup v2 there is no cpuacct controller, the cpu.stat file always +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-include-system-headers-only-on-linux.patch b/SOURCES/libvirt-vircgroup-include-system-headers-only-on-linux.patch new file mode 100644 index 0000000..436ee86 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-include-system-headers-only-on-linux.patch @@ -0,0 +1,83 @@ +From 05df743686ad42fa006877341b7719ff4a890a70 Mon Sep 17 00:00:00 2001 +Message-Id: <05df743686ad42fa006877341b7719ff4a890a70@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:09 +0200 +Subject: [PATCH] vircgroup: include system headers only on linux +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +All the system headers are used only if we are compiling on linux +and they all are present otherwise we would have seen build errors +because in our tests/vircgrouptest.c we use only __linux__ to check +whether to skip the cgroup tests or not. + +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 6ef37ed3b8e7cc5fd83ff2b84bf08deea62d3bd0) + +Conflicts: + src/util/vircgroup.c - missing commits 9403b63102 5165ff0971 + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <78f1905b381e5d9dce9daeabcf157e2fe65ddffe.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 35 +++++++++++++++++------------------ + 1 file changed, 17 insertions(+), 18 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index f1ecb1dbeb..a376b9b89a 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -23,28 +23,27 @@ + */ + #include + +-#include +-#if defined HAVE_MNTENT_H && defined HAVE_SYS_MOUNT_H \ +- && defined HAVE_GETMNTENT_R ++#ifdef __linux__ ++# include + # include + # include +-#endif +-#include +-#include +-#include +-#include +-#include ++# include ++# include ++# include ++# include ++# include + +-#ifdef MAJOR_IN_MKDEV +-# include +-#elif MAJOR_IN_SYSMACROS +-# include +-#endif ++# ifdef MAJOR_IN_MKDEV ++# include ++# elif MAJOR_IN_SYSMACROS ++# include ++# endif + +-#include +-#include +-#include +-#include ++# include ++# include ++# include ++# include ++#endif /* __linux__ */ + + #define __VIR_CGROUP_ALLOW_INCLUDE_PRIV_H__ + #include "vircgrouppriv.h" +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-cgroup-v1-backend-files.patch b/SOURCES/libvirt-vircgroup-introduce-cgroup-v1-backend-files.patch new file mode 100644 index 0000000..8a6dd5d --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-cgroup-v1-backend-files.patch @@ -0,0 +1,186 @@ +From d1b618c627d848ed4549912d83be397f969935d2 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:22 +0200 +Subject: [PATCH] vircgroup: introduce cgroup v1 backend files +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 1f221d610dc510b82f17407a81a0acd56d9efc5b) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/Makefile.am | 1 + + src/libvirt_private.syms | 3 ++ + src/util/Makefile.inc.am | 2 ++ + src/util/vircgroupbackend.c | 2 ++ + src/util/vircgroupv1.c | 55 +++++++++++++++++++++++++++++++++++++ + src/util/vircgroupv1.h | 27 ++++++++++++++++++ + 6 files changed, 90 insertions(+) + create mode 100644 src/util/vircgroupv1.c + create mode 100644 src/util/vircgroupv1.h + +diff --git a/src/Makefile.am b/src/Makefile.am +index c4e797f5a2..0def0a3b19 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -679,6 +679,7 @@ libvirt_setuid_rpc_client_la_SOURCES = \ + util/virbuffer.c \ + util/vircgroup.c \ + util/vircgroupbackend.c \ ++ util/vircgroupv1.c \ + util/vircommand.c \ + util/virconf.c \ + util/virdbus.c \ +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 627eb5e587..b144955154 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -1595,6 +1595,9 @@ virCgroupTerminateMachine; + virCgroupBackendGetAll; + virCgroupBackendRegister; + ++# util/vircgroupv1.h ++virCgroupV1Register; ++ + # util/virclosecallbacks.h + virCloseCallbacksGet; + virCloseCallbacksGetConn; +diff --git a/src/util/Makefile.inc.am b/src/util/Makefile.inc.am +index a9185bd7b7..725ece98e9 100644 +--- a/src/util/Makefile.inc.am ++++ b/src/util/Makefile.inc.am +@@ -25,6 +25,8 @@ UTIL_SOURCES = \ + util/vircgroup.h util/vircgrouppriv.h \ + util/vircgroupbackend.c \ + util/vircgroupbackend.h \ ++ util/vircgroupv1.c \ ++ util/vircgroupv1.h \ + util/virclosecallbacks.c \ + util/virclosecallbacks.h \ + util/vircommand.c \ +diff --git a/src/util/vircgroupbackend.c b/src/util/vircgroupbackend.c +index e014bfc0e6..d854c9711d 100644 +--- a/src/util/vircgroupbackend.c ++++ b/src/util/vircgroupbackend.c +@@ -20,6 +20,7 @@ + #include + + #include "vircgroupbackend.h" ++#include "vircgroupv1.h" + #include "virerror.h" + #include "virthread.h" + +@@ -49,6 +50,7 @@ virCgroupBackendRegister(virCgroupBackendPtr backend) + static void + virCgroupBackendOnceInit(void) + { ++ virCgroupV1Register(); + } + + +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +new file mode 100644 +index 0000000000..4dda7865f1 +--- /dev/null ++++ b/src/util/vircgroupv1.c +@@ -0,0 +1,55 @@ ++/* ++ * vircgroupv1.c: methods for cgroups v1 backend ++ * ++ * Copyright (C) 2010-2015,2018 Red Hat, Inc. ++ * Copyright IBM Corp. 2008 ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library. If not, see ++ * . ++ */ ++#include ++ ++#include "internal.h" ++ ++#define __VIR_CGROUP_ALLOW_INCLUDE_PRIV_H__ ++#include "vircgrouppriv.h" ++#undef __VIR_CGROUP_ALLOW_INCLUDE_PRIV_H__ ++ ++#include "vircgroup.h" ++#include "vircgroupbackend.h" ++#include "vircgroupv1.h" ++#include "virlog.h" ++ ++VIR_LOG_INIT("util.cgroup"); ++ ++#define VIR_FROM_THIS VIR_FROM_CGROUP ++ ++ ++VIR_ENUM_DECL(virCgroupV1Controller); ++VIR_ENUM_IMPL(virCgroupV1Controller, VIR_CGROUP_CONTROLLER_LAST, ++ "cpu", "cpuacct", "cpuset", "memory", "devices", ++ "freezer", "blkio", "net_cls", "perf_event", ++ "name=systemd"); ++ ++ ++virCgroupBackend virCgroupV1Backend = { ++ .type = VIR_CGROUP_BACKEND_TYPE_V1, ++}; ++ ++ ++void ++virCgroupV1Register(void) ++{ ++ virCgroupBackendRegister(&virCgroupV1Backend); ++} +diff --git a/src/util/vircgroupv1.h b/src/util/vircgroupv1.h +new file mode 100644 +index 0000000000..517517c109 +--- /dev/null ++++ b/src/util/vircgroupv1.h +@@ -0,0 +1,27 @@ ++/* ++ * vircgroupv1.h: methods for cgroups v1 backend ++ * ++ * Copyright (C) 2018 Red Hat, Inc. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library. If not, see ++ * . ++ */ ++ ++#ifndef __VIR_CGROUP_V1_H__ ++# define __VIR_CGROUP_V1_H__ ++ ++void ++virCgroupV1Register(void); ++ ++#endif /* __VIR_CGROUP_V1_H__ */ +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupAddThread.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupAddThread.patch new file mode 100644 index 0000000..5203d96 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupAddThread.patch @@ -0,0 +1,126 @@ +From 83b13b08025476233d7acc7d37297abda861be32 Mon Sep 17 00:00:00 2001 +Message-Id: <83b13b08025476233d7acc7d37297abda861be32@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:16 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupAddThread +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Once we introduce cgroup v2 support we need to handle processes and +threads differently. + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 7b526ea57c8ca02e49f6a8cc71a6910f56803bde) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/libvirt_private.syms | 1 + + src/qemu/qemu_process.c | 2 +- + src/util/vircgroup.c | 32 ++++++++++++++++++++++++++++++++ + src/util/vircgroup.h | 1 + + 4 files changed, 35 insertions(+), 1 deletion(-) + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 5dd24e2e66..f8c1a0df16 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -1515,6 +1515,7 @@ virBufferVasprintf; + # util/vircgroup.h + virCgroupAddMachineProcess; + virCgroupAddProcess; ++virCgroupAddThread; + virCgroupAllowAllDevices; + virCgroupAllowDevice; + virCgroupAllowDevicePath; +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index c21586fa12..0cd61f02bb 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -2538,7 +2538,7 @@ qemuProcessSetupPid(virDomainObjPtr vm, + goto cleanup; + + /* Move the thread to the sub dir */ +- if (virCgroupAddProcess(cgroup, pid) < 0) ++ if (virCgroupAddThread(cgroup, pid) < 0) + goto cleanup; + + } +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 5aa8596b9c..f08fe3600e 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -1164,6 +1164,10 @@ typedef enum { + /* Same as VIR_CGROUP_TASK_PROCESS but it also adds the task to systemd + * named controller. */ + VIR_CGROUP_TASK_SYSTEMD = 1 << 1, ++ ++ /* Moves only specific thread into cgroup except to systemd ++ * named controller. */ ++ VIR_CGROUP_TASK_THREAD = 1 << 2, + } virCgroupTaskFlags; + + +@@ -1232,6 +1236,24 @@ virCgroupAddMachineProcess(virCgroupPtr group, pid_t pid) + VIR_CGROUP_TASK_SYSTEMD); + } + ++/** ++ * virCgroupAddThread: ++ * ++ * @group: The cgroup to add a thread to ++ * @pid: The pid of the thread to add ++ * ++ * Will add the thread to all controllers, except the ++ * systemd unit controller. ++ * ++ * Returns: 0 on success, -1 on error ++ */ ++int ++virCgroupAddThread(virCgroupPtr group, ++ pid_t pid) ++{ ++ return virCgroupAddTaskInternal(group, pid, VIR_CGROUP_TASK_THREAD); ++} ++ + + static int + virCgroupSetPartitionSuffix(const char *path, char **res) +@@ -4233,6 +4255,16 @@ virCgroupAddMachineProcess(virCgroupPtr group ATTRIBUTE_UNUSED, + } + + ++int ++virCgroupAddThread(virCgroupPtr group ATTRIBUTE_UNUSED, ++ pid_t pid ATTRIBUTE_UNUSED) ++{ ++ virReportSystemError(ENXIO, "%s", ++ _("Control groups not supported on this platform")); ++ return -1; ++} ++ ++ + int + virCgroupGetBlkioIoServiced(virCgroupPtr group ATTRIBUTE_UNUSED, + long long *bytes_read ATTRIBUTE_UNUSED, +diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h +index bbd4c2ed57..1f676f21c3 100644 +--- a/src/util/vircgroup.h ++++ b/src/util/vircgroup.h +@@ -120,6 +120,7 @@ int virCgroupPathOfController(virCgroupPtr group, + + int virCgroupAddProcess(virCgroupPtr group, pid_t pid); + int virCgroupAddMachineProcess(virCgroupPtr group, pid_t pid); ++int virCgroupAddThread(virCgroupPtr group, pid_t pid); + + int virCgroupSetBlkioWeight(virCgroupPtr group, unsigned int weight); + int virCgroupGetBlkioWeight(virCgroupPtr group, unsigned int *weight); +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupKillRecursiveCB.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupKillRecursiveCB.patch new file mode 100644 index 0000000..cd77f04 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupKillRecursiveCB.patch @@ -0,0 +1,286 @@ +From 8b35858852e5c170410d4462fdf2bb19659b8894 Mon Sep 17 00:00:00 2001 +Message-Id: <8b35858852e5c170410d4462fdf2bb19659b8894@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:08:09 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupKillRecursiveCB +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The rewrite to support cgroup v2 missed this function. In cgroup v2 +we have different files to track tasks. + +We would fail to remove cgroup on non-systemd OSes if there is any +extra process assigned to guest cgroup because we would not kill any +process form the guest cgroup. + +Signed-off-by: Pavel Hrdina +(cherry picked from commit b532546823fde032fe827d41735a0d591c3bc0b8) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <2414a178eb8aba977e7369bba0b37a18cdfec654.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 69 ++++++++++++++++++++----------------- + src/util/vircgroupbackend.h | 7 ++++ + src/util/vircgrouppriv.h | 8 +++++ + src/util/vircgroupv1.c | 16 +++++++++ + src/util/vircgroupv2.c | 16 +++++++++ + 5 files changed, 84 insertions(+), 32 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 069f1ae396..736b5043a8 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -2431,33 +2431,15 @@ virCgroupRemove(virCgroupPtr group) + } + + +-static int +-virCgroupPathOfAnyController(virCgroupPtr group, +- const char *name, +- char **keypath) +-{ +- size_t i; +- int controller; +- +- for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) { +- if (group->backends[i]) { +- controller = group->backends[i]->getAnyController(group); +- if (controller >= 0) +- return virCgroupPathOfController(group, controller, name, keypath); +- } +- } +- +- virReportSystemError(ENOSYS, "%s", +- _("No controllers are mounted")); +- return -1; +-} +- +- + /* + * Returns 1 if some PIDs are killed, 0 if none are killed, or -1 on error + */ + static int +-virCgroupKillInternal(virCgroupPtr group, int signum, virHashTablePtr pids) ++virCgroupKillInternal(virCgroupPtr group, ++ int signum, ++ virHashTablePtr pids, ++ int controller, ++ const char *taskFile) + { + int ret = -1; + bool killedAny = false; +@@ -2467,7 +2449,7 @@ virCgroupKillInternal(virCgroupPtr group, int signum, virHashTablePtr pids) + VIR_DEBUG("group=%p path=%s signum=%d pids=%p", + group, group->path, signum, pids); + +- if (virCgroupPathOfAnyController(group, "tasks", &keypath) < 0) ++ if (virCgroupPathOfController(group, controller, taskFile, &keypath) < 0) + return -1; + + /* PIDs may be forking as we kill them, so loop +@@ -2553,10 +2535,12 @@ virCgroupPidCopy(const void *name) + } + + +-static int ++int + virCgroupKillRecursiveInternal(virCgroupPtr group, + int signum, + virHashTablePtr pids, ++ int controller, ++ const char *taskFile, + bool dormdir) + { + int ret = -1; +@@ -2570,11 +2554,13 @@ virCgroupKillRecursiveInternal(virCgroupPtr group, + VIR_DEBUG("group=%p path=%s signum=%d pids=%p", + group, group->path, signum, pids); + +- if (virCgroupPathOfAnyController(group, "", &keypath) < 0) ++ if (virCgroupPathOfController(group, controller, "", &keypath) < 0) + return -1; + +- if ((rc = virCgroupKillInternal(group, signum, pids)) < 0) ++ if ((rc = virCgroupKillInternal(group, signum, pids, ++ controller, taskFile)) < 0) { + goto cleanup; ++ } + if (rc == 1) + killedAny = true; + +@@ -2598,7 +2584,7 @@ virCgroupKillRecursiveInternal(virCgroupPtr group, + goto cleanup; + + if ((rc = virCgroupKillRecursiveInternal(subgroup, signum, pids, +- true)) < 0) ++ controller, taskFile, true)) < 0) + goto cleanup; + if (rc == 1) + killedAny = true; +@@ -2624,8 +2610,10 @@ virCgroupKillRecursiveInternal(virCgroupPtr group, + int + virCgroupKillRecursive(virCgroupPtr group, int signum) + { +- int ret; +- VIR_DEBUG("group=%p path=%s signum=%d", group, group->path, signum); ++ int ret = 0; ++ int rc; ++ size_t i; ++ virCgroupBackendPtr *backends = virCgroupBackendGetAll(); + virHashTablePtr pids = virHashCreateFull(100, + NULL, + virCgroupPidCode, +@@ -2633,10 +2621,27 @@ virCgroupKillRecursive(virCgroupPtr group, int signum) + virCgroupPidCopy, + NULL); + +- ret = virCgroupKillRecursiveInternal(group, signum, pids, false); ++ VIR_DEBUG("group=%p path=%s signum=%d", group, group->path, signum); + ++ if (!backends) { ++ ret = -1; ++ goto cleanup; ++ } ++ ++ for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) { ++ if (backends[i]) { ++ rc = backends[i]->killRecursive(group, signum, pids); ++ if (rc < 0) { ++ ret = -1; ++ goto cleanup; ++ } ++ if (rc > 0) ++ ret = rc; ++ } ++ } ++ ++ cleanup: + virHashFree(pids); +- + return ret; + } + +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index bc60b44643..a825dc4be7 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -24,6 +24,7 @@ + # include "internal.h" + + # include "vircgroup.h" ++# include "virhash.h" + + # define CGROUP_MAX_VAL 512 + +@@ -128,6 +129,11 @@ typedef int + (*virCgroupHasEmptyTasksCB)(virCgroupPtr cgroup, + int controller); + ++typedef int ++(*virCgroupKillRecursiveCB)(virCgroupPtr group, ++ int signum, ++ virHashTablePtr pids); ++ + typedef int + (*virCgroupBindMountCB)(virCgroupPtr group, + const char *oldroot, +@@ -370,6 +376,7 @@ struct _virCgroupBackend { + virCgroupRemoveCB remove; + virCgroupAddTaskCB addTask; + virCgroupHasEmptyTasksCB hasEmptyTasks; ++ virCgroupKillRecursiveCB killRecursive; + virCgroupBindMountCB bindMount; + virCgroupSetOwnerCB setOwner; + +diff --git a/src/util/vircgrouppriv.h b/src/util/vircgrouppriv.h +index 8f24b0891e..6067f5cdc8 100644 +--- a/src/util/vircgrouppriv.h ++++ b/src/util/vircgrouppriv.h +@@ -123,4 +123,12 @@ int virCgroupNewDomainPartition(virCgroupPtr partition, + + int virCgroupRemoveRecursively(char *grppath); + ++ ++int virCgroupKillRecursiveInternal(virCgroupPtr group, ++ int signum, ++ virHashTablePtr pids, ++ int controller, ++ const char *taskFile, ++ bool dormdir); ++ + #endif /* __VIR_CGROUP_PRIV_H__ */ +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 3147084f21..7098dc5644 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -758,6 +758,21 @@ virCgroupV1HasEmptyTasks(virCgroupPtr cgroup, + } + + ++static int ++virCgroupV1KillRecursive(virCgroupPtr group, ++ int signum, ++ virHashTablePtr pids) ++{ ++ int controller = virCgroupV1GetAnyController(group); ++ ++ if (controller < 0) ++ return -1; ++ ++ return virCgroupKillRecursiveInternal(group, signum, pids, controller, ++ "tasks", false); ++} ++ ++ + static char * + virCgroupV1IdentifyRoot(virCgroupPtr group) + { +@@ -2042,6 +2057,7 @@ virCgroupBackend virCgroupV1Backend = { + .remove = virCgroupV1Remove, + .addTask = virCgroupV1AddTask, + .hasEmptyTasks = virCgroupV1HasEmptyTasks, ++ .killRecursive = virCgroupV1KillRecursive, + .bindMount = virCgroupV1BindMount, + .setOwner = virCgroupV1SetOwner, + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index bff2f78d7e..5652fcfffb 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -463,6 +463,21 @@ virCgroupV2HasEmptyTasks(virCgroupPtr cgroup, + } + + ++static int ++virCgroupV2KillRecursive(virCgroupPtr group, ++ int signum, ++ virHashTablePtr pids) ++{ ++ int controller = virCgroupV2GetAnyController(group); ++ ++ if (controller < 0) ++ return -1; ++ ++ return virCgroupKillRecursiveInternal(group, signum, pids, controller, ++ "cgroup.threads", false); ++} ++ ++ + static int + virCgroupV2BindMount(virCgroupPtr group, + const char *oldroot, +@@ -1559,6 +1574,7 @@ virCgroupBackend virCgroupV2Backend = { + .remove = virCgroupV2Remove, + .addTask = virCgroupV2AddTask, + .hasEmptyTasks = virCgroupV2HasEmptyTasks, ++ .killRecursive = virCgroupV2KillRecursive, + .bindMount = virCgroupV2BindMount, + .setOwner = virCgroupV2SetOwner, + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupTaskFlags.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupTaskFlags.patch new file mode 100644 index 0000000..4677c8b --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupTaskFlags.patch @@ -0,0 +1,86 @@ +From 482d6964af9e1f8a4d52253e6474ce11f4a1ca5f Mon Sep 17 00:00:00 2001 +Message-Id: <482d6964af9e1f8a4d52253e6474ce11f4a1ca5f@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:15 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupTaskFlags +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Use flags in virCgroupAddTaskInternal instead of boolean parameter. +Following patch will add new flag to indicate thread instead of process. + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 36c5989c54cf335b365f4e179a4d7ab7d174bd6e) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 24 ++++++++++++++++++++---- + 1 file changed, 20 insertions(+), 4 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index cf510fb019..5aa8596b9c 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -1156,8 +1156,21 @@ virCgroupNew(pid_t pid, + } + + ++typedef enum { ++ /* Adds a whole process with all threads to specific cgroup except ++ * to systemd named controller. */ ++ VIR_CGROUP_TASK_PROCESS = 1 << 0, ++ ++ /* Same as VIR_CGROUP_TASK_PROCESS but it also adds the task to systemd ++ * named controller. */ ++ VIR_CGROUP_TASK_SYSTEMD = 1 << 1, ++} virCgroupTaskFlags; ++ ++ + static int +-virCgroupAddTaskInternal(virCgroupPtr group, pid_t pid, bool withSystemd) ++virCgroupAddTaskInternal(virCgroupPtr group, ++ pid_t pid, ++ unsigned int flags) + { + int ret = -1; + size_t i; +@@ -1170,7 +1183,8 @@ virCgroupAddTaskInternal(virCgroupPtr group, pid_t pid, bool withSystemd) + /* We must never add tasks in systemd's hierarchy + * unless we're intentionally trying to move a + * task into a systemd machine scope */ +- if (i == VIR_CGROUP_CONTROLLER_SYSTEMD && !withSystemd) ++ if (i == VIR_CGROUP_CONTROLLER_SYSTEMD && ++ !(flags & VIR_CGROUP_TASK_SYSTEMD)) + continue; + + if (virCgroupSetValueI64(group, i, "tasks", pid) < 0) +@@ -1196,7 +1210,7 @@ virCgroupAddTaskInternal(virCgroupPtr group, pid_t pid, bool withSystemd) + int + virCgroupAddProcess(virCgroupPtr group, pid_t pid) + { +- return virCgroupAddTaskInternal(group, pid, false); ++ return virCgroupAddTaskInternal(group, pid, VIR_CGROUP_TASK_PROCESS); + } + + /** +@@ -1213,7 +1227,9 @@ virCgroupAddProcess(virCgroupPtr group, pid_t pid) + int + virCgroupAddMachineProcess(virCgroupPtr group, pid_t pid) + { +- return virCgroupAddTaskInternal(group, pid, true); ++ return virCgroupAddTaskInternal(group, pid, ++ VIR_CGROUP_TASK_PROCESS | ++ VIR_CGROUP_TASK_SYSTEMD); + } + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2-Set-Get-BlkioDeviceReadBps.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2-Set-Get-BlkioDeviceReadBps.patch new file mode 100644 index 0000000..5b44c95 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2-Set-Get-BlkioDeviceReadBps.patch @@ -0,0 +1,112 @@ +From 7ca4f79d91300d6d6da1ac31d745852e35d4220f Mon Sep 17 00:00:00 2001 +Message-Id: <7ca4f79d91300d6d6da1ac31d745852e35d4220f@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:37 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2(Set|Get)BlkioDeviceReadBps +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 353ce9453e836da1d42993e71c88011f8515e538) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <5fedf92d6740e387df3e88e3abf6b711d79f3dbe.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 70 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 70 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 1d25c0ae1f..b303e9cb10 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -879,6 +879,74 @@ virCgroupV2GetBlkioDeviceWriteIops(virCgroupPtr group, + } + + ++static int ++virCgroupV2SetBlkioDeviceReadBps(virCgroupPtr group, ++ const char *path, ++ unsigned long long rbps) ++{ ++ VIR_AUTOFREE(char *) str = NULL; ++ VIR_AUTOFREE(char *) blkstr = NULL; ++ ++ if (!(blkstr = virCgroupGetBlockDevString(path))) ++ return -1; ++ ++ if (rbps == 0) { ++ if (virAsprintf(&str, "%srbps=max", blkstr) < 0) ++ return -1; ++ } else { ++ if (virAsprintf(&str, "%srbps=%llu", blkstr, rbps) < 0) ++ return -1; ++ } ++ ++ return virCgroupSetValueStr(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "io.max", ++ str); ++} ++ ++ ++static int ++virCgroupV2GetBlkioDeviceReadBps(virCgroupPtr group, ++ const char *path, ++ unsigned long long *rbps) ++{ ++ VIR_AUTOFREE(char *) str = NULL; ++ const char *name = "rbps="; ++ char *tmp; ++ ++ if (virCgroupGetValueForBlkDev(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "io.max", ++ path, ++ &str) < 0) { ++ return -1; ++ } ++ ++ if (!str) { ++ *rbps = 0; ++ } else { ++ if (!(tmp = strstr(str, name))) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Unable to find '%s' limit for block device '%s'"), ++ name, path); ++ return -1; ++ } ++ tmp += strlen(name); ++ ++ if (STREQLEN(tmp, "max", 3)) { ++ *rbps = 0; ++ } else if (virStrToLong_ull(tmp, NULL, 10, rbps) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Unable to parse '%s' as an integer"), ++ str); ++ return -1; ++ } ++ } ++ ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -911,6 +979,8 @@ virCgroupBackend virCgroupV2Backend = { + .getBlkioDeviceReadIops = virCgroupV2GetBlkioDeviceReadIops, + .setBlkioDeviceWriteIops = virCgroupV2SetBlkioDeviceWriteIops, + .getBlkioDeviceWriteIops = virCgroupV2GetBlkioDeviceWriteIops, ++ .setBlkioDeviceReadBps = virCgroupV2SetBlkioDeviceReadBps, ++ .getBlkioDeviceReadBps = virCgroupV2GetBlkioDeviceReadBps, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2-Set-Get-BlkioDeviceReadIops.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2-Set-Get-BlkioDeviceReadIops.patch new file mode 100644 index 0000000..500aa29 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2-Set-Get-BlkioDeviceReadIops.patch @@ -0,0 +1,112 @@ +From 87e723cfed87955b7d23e0d2ea7bac61b57daf21 Mon Sep 17 00:00:00 2001 +Message-Id: <87e723cfed87955b7d23e0d2ea7bac61b57daf21@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:35 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2(Set|Get)BlkioDeviceReadIops +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 862f630825a74a2605fca52bb66d8f04edefa75b) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <4afdb39491c625603a7b9963648d20148477cc33.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 70 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 70 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 86b3fc127a..8cecc43f76 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -743,6 +743,74 @@ virCgroupV2GetBlkioDeviceWeight(virCgroupPtr group, + } + + ++static int ++virCgroupV2SetBlkioDeviceReadIops(virCgroupPtr group, ++ const char *path, ++ unsigned int riops) ++{ ++ VIR_AUTOFREE(char *) str = NULL; ++ VIR_AUTOFREE(char *) blkstr = NULL; ++ ++ if (!(blkstr = virCgroupGetBlockDevString(path))) ++ return -1; ++ ++ if (riops == 0) { ++ if (virAsprintf(&str, "%sriops=max", blkstr) < 0) ++ return -1; ++ } else { ++ if (virAsprintf(&str, "%sriops=%u", blkstr, riops) < 0) ++ return -1; ++ } ++ ++ return virCgroupSetValueStr(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "io.max", ++ str); ++} ++ ++ ++static int ++virCgroupV2GetBlkioDeviceReadIops(virCgroupPtr group, ++ const char *path, ++ unsigned int *riops) ++{ ++ VIR_AUTOFREE(char *) str = NULL; ++ const char *name = "riops="; ++ char *tmp; ++ ++ if (virCgroupGetValueForBlkDev(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "io.max", ++ path, ++ &str) < 0) { ++ return -1; ++ } ++ ++ if (!str) { ++ *riops = 0; ++ } else { ++ if (!(tmp = strstr(str, name))) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Unable to find '%s' limit for block device '%s'"), ++ name, path); ++ return -1; ++ } ++ tmp += strlen(name); ++ ++ if (STREQLEN(tmp, "max", 3)) { ++ *riops = 0; ++ } else if (virStrToLong_ui(tmp, NULL, 10, riops) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Unable to parse '%s' as an integer"), ++ str); ++ return -1; ++ } ++ } ++ ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -771,6 +839,8 @@ virCgroupBackend virCgroupV2Backend = { + .getBlkioIoDeviceServiced = virCgroupV2GetBlkioIoDeviceServiced, + .setBlkioDeviceWeight = virCgroupV2SetBlkioDeviceWeight, + .getBlkioDeviceWeight = virCgroupV2GetBlkioDeviceWeight, ++ .setBlkioDeviceReadIops = virCgroupV2SetBlkioDeviceReadIops, ++ .getBlkioDeviceReadIops = virCgroupV2GetBlkioDeviceReadIops, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2-Set-Get-BlkioDeviceWeight.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2-Set-Get-BlkioDeviceWeight.patch new file mode 100644 index 0000000..a73e4a7 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2-Set-Get-BlkioDeviceWeight.patch @@ -0,0 +1,93 @@ +From 39b7d11c4b75b3213054f7730887acca90f62969 Mon Sep 17 00:00:00 2001 +Message-Id: <39b7d11c4b75b3213054f7730887acca90f62969@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:34 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2(Set|Get)BlkioDeviceWeight +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 568f746eafce1194dc10cc91a41c91bf08fadd53) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <5dd74b70bcec7b3cd7186b53e76857dcf1d21c6f.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 51 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 51 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index fcf39406e1..86b3fc127a 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -694,6 +694,55 @@ virCgroupV2GetBlkioIoDeviceServiced(virCgroupPtr group, + } + + ++static int ++virCgroupV2SetBlkioDeviceWeight(virCgroupPtr group, ++ const char *path, ++ unsigned int weight) ++{ ++ VIR_AUTOFREE(char *) str = NULL; ++ VIR_AUTOFREE(char *) blkstr = NULL; ++ ++ if (!(blkstr = virCgroupGetBlockDevString(path))) ++ return -1; ++ ++ if (virAsprintf(&str, "%s%d", blkstr, weight) < 0) ++ return -1; ++ ++ return virCgroupSetValueStr(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "io.weight", ++ str); ++} ++ ++ ++static int ++virCgroupV2GetBlkioDeviceWeight(virCgroupPtr group, ++ const char *path, ++ unsigned int *weight) ++{ ++ VIR_AUTOFREE(char *) str = NULL; ++ ++ if (virCgroupGetValueForBlkDev(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "io.weight", ++ path, ++ &str) < 0) { ++ return -1; ++ } ++ ++ if (!str) { ++ *weight = 0; ++ } else if (virStrToLong_ui(str, NULL, 10, weight) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Unable to parse '%s' as an integer"), ++ str); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -720,6 +769,8 @@ virCgroupBackend virCgroupV2Backend = { + .getBlkioWeight = virCgroupV2GetBlkioWeight, + .getBlkioIoServiced = virCgroupV2GetBlkioIoServiced, + .getBlkioIoDeviceServiced = virCgroupV2GetBlkioIoDeviceServiced, ++ .setBlkioDeviceWeight = virCgroupV2SetBlkioDeviceWeight, ++ .getBlkioDeviceWeight = virCgroupV2GetBlkioDeviceWeight, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2-Set-Get-BlkioDeviceWriteBps.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2-Set-Get-BlkioDeviceWriteBps.patch new file mode 100644 index 0000000..0012244 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2-Set-Get-BlkioDeviceWriteBps.patch @@ -0,0 +1,112 @@ +From b5ce0e989440de2c3d4bfb8b325d85ca25ace4ca Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:38 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2(Set|Get)BlkioDeviceWriteBps +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 91756fb64a370e48a6bcdd1973126a8c7a36e4f7) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <3d70ebb985fa8132e45ba12bbb8e78ac80557a78.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 70 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 70 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index b303e9cb10..52d31925c2 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -947,6 +947,74 @@ virCgroupV2GetBlkioDeviceReadBps(virCgroupPtr group, + } + + ++static int ++virCgroupV2SetBlkioDeviceWriteBps(virCgroupPtr group, ++ const char *path, ++ unsigned long long wbps) ++{ ++ VIR_AUTOFREE(char *) str = NULL; ++ VIR_AUTOFREE(char *) blkstr = NULL; ++ ++ if (!(blkstr = virCgroupGetBlockDevString(path))) ++ return -1; ++ ++ if (wbps == 0) { ++ if (virAsprintf(&str, "%swbps=max", blkstr) < 0) ++ return -1; ++ } else { ++ if (virAsprintf(&str, "%swbps=%llu", blkstr, wbps) < 0) ++ return -1; ++ } ++ ++ return virCgroupSetValueStr(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "io.max", ++ str); ++} ++ ++ ++static int ++virCgroupV2GetBlkioDeviceWriteBps(virCgroupPtr group, ++ const char *path, ++ unsigned long long *wbps) ++{ ++ VIR_AUTOFREE(char *) str = NULL; ++ const char *name = "wbps="; ++ char *tmp; ++ ++ if (virCgroupGetValueForBlkDev(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "io.max", ++ path, ++ &str) < 0) { ++ return -1; ++ } ++ ++ if (!str) { ++ *wbps = 0; ++ } else { ++ if (!(tmp = strstr(str, name))) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Unable to find '%s' limit for block device '%s'"), ++ name, path); ++ return -1; ++ } ++ tmp += strlen(name); ++ ++ if (STREQLEN(tmp, "max", 3)) { ++ *wbps = 0; ++ } else if (virStrToLong_ull(tmp, NULL, 10, wbps) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Unable to parse '%s' as an integer"), ++ str); ++ return -1; ++ } ++ } ++ ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -981,6 +1049,8 @@ virCgroupBackend virCgroupV2Backend = { + .getBlkioDeviceWriteIops = virCgroupV2GetBlkioDeviceWriteIops, + .setBlkioDeviceReadBps = virCgroupV2SetBlkioDeviceReadBps, + .getBlkioDeviceReadBps = virCgroupV2GetBlkioDeviceReadBps, ++ .setBlkioDeviceWriteBps = virCgroupV2SetBlkioDeviceWriteBps, ++ .getBlkioDeviceWriteBps = virCgroupV2GetBlkioDeviceWriteBps, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2-Set-Get-BlkioDeviceWriteIops.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2-Set-Get-BlkioDeviceWriteIops.patch new file mode 100644 index 0000000..2d15aac --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2-Set-Get-BlkioDeviceWriteIops.patch @@ -0,0 +1,112 @@ +From eca0f75e6f67ec9e445b90685143992b6929cef0 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:36 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2(Set|Get)BlkioDeviceWriteIops +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 438587033bdaf714238a98703c9efc7b0dada51f) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <7937bd2aa5da315f8351e3f312f5aee71b682c30.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 70 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 70 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 8cecc43f76..1d25c0ae1f 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -811,6 +811,74 @@ virCgroupV2GetBlkioDeviceReadIops(virCgroupPtr group, + } + + ++static int ++virCgroupV2SetBlkioDeviceWriteIops(virCgroupPtr group, ++ const char *path, ++ unsigned int wiops) ++{ ++ VIR_AUTOFREE(char *) str = NULL; ++ VIR_AUTOFREE(char *) blkstr = NULL; ++ ++ if (!(blkstr = virCgroupGetBlockDevString(path))) ++ return -1; ++ ++ if (wiops == 0) { ++ if (virAsprintf(&str, "%swiops=max", blkstr) < 0) ++ return -1; ++ } else { ++ if (virAsprintf(&str, "%swiops=%u", blkstr, wiops) < 0) ++ return -1; ++ } ++ ++ return virCgroupSetValueStr(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "io.max", ++ str); ++} ++ ++ ++static int ++virCgroupV2GetBlkioDeviceWriteIops(virCgroupPtr group, ++ const char *path, ++ unsigned int *wiops) ++{ ++ VIR_AUTOFREE(char *) str = NULL; ++ const char *name = "wiops="; ++ char *tmp; ++ ++ if (virCgroupGetValueForBlkDev(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "io.max", ++ path, ++ &str) < 0) { ++ return -1; ++ } ++ ++ if (!str) { ++ *wiops = 0; ++ } else { ++ if (!(tmp = strstr(str, name))) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Unable to find '%s' limit for block device '%s'"), ++ name, path); ++ return -1; ++ } ++ tmp += strlen(name); ++ ++ if (STREQLEN(tmp, "max", 3)) { ++ *wiops = 0; ++ } else if (virStrToLong_ui(tmp, NULL, 10, wiops) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Unable to parse '%s' as an integer"), ++ str); ++ return -1; ++ } ++ } ++ ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -841,6 +909,8 @@ virCgroupBackend virCgroupV2Backend = { + .getBlkioDeviceWeight = virCgroupV2GetBlkioDeviceWeight, + .setBlkioDeviceReadIops = virCgroupV2SetBlkioDeviceReadIops, + .getBlkioDeviceReadIops = virCgroupV2GetBlkioDeviceReadIops, ++ .setBlkioDeviceWriteIops = virCgroupV2SetBlkioDeviceWriteIops, ++ .getBlkioDeviceWriteIops = virCgroupV2GetBlkioDeviceWriteIops, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2-Set-Get-BlkioWeight.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2-Set-Get-BlkioWeight.patch new file mode 100644 index 0000000..755c0a1 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2-Set-Get-BlkioWeight.patch @@ -0,0 +1,91 @@ +From ba7babc00b91a08c7c62858b6c34f1f0c77af0ce Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:31 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2(Set|Get)BlkioWeight +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 11bb7f1561be311b71f3899332dfabe61c55a793) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <8e485d7c092d35f80e10da00af74fd30554b43bf.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 49 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 49 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 27519d80e3..f7863a5690 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -521,6 +521,52 @@ virCgroupV2SetOwner(virCgroupPtr cgroup, + } + + ++static int ++virCgroupV2SetBlkioWeight(virCgroupPtr group, ++ unsigned int weight) ++{ ++ VIR_AUTOFREE(char *) value = NULL; ++ ++ if (virAsprintf(&value, "default %u", weight) < 0) ++ return -1; ++ ++ return virCgroupSetValueStr(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "io.weight", ++ value); ++} ++ ++ ++static int ++virCgroupV2GetBlkioWeight(virCgroupPtr group, ++ unsigned int *weight) ++{ ++ VIR_AUTOFREE(char *) value = NULL; ++ char *tmp; ++ ++ if (virCgroupGetValueStr(group, VIR_CGROUP_CONTROLLER_BLKIO, ++ "io.weight", &value) < 0) { ++ return -1; ++ } ++ ++ if (!(tmp = strstr(value, "default "))) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("Cannot find default io weight.")); ++ return -1; ++ } ++ tmp += strlen("default "); ++ ++ if (virStrToLong_ui(tmp, NULL, 10, weight) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Unable to parse '%s' as an integer"), ++ tmp); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -542,6 +588,9 @@ virCgroupBackend virCgroupV2Backend = { + .hasEmptyTasks = virCgroupV2HasEmptyTasks, + .bindMount = virCgroupV2BindMount, + .setOwner = virCgroupV2SetOwner, ++ ++ .setBlkioWeight = virCgroupV2SetBlkioWeight, ++ .getBlkioWeight = virCgroupV2GetBlkioWeight, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2-Set-Get-CpuCfsPeriod.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2-Set-Get-CpuCfsPeriod.patch new file mode 100644 index 0000000..bfece79 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2-Set-Get-CpuCfsPeriod.patch @@ -0,0 +1,116 @@ +From 05610561d752380d3f75780056fea927d723b53b Mon Sep 17 00:00:00 2001 +Message-Id: <05610561d752380d3f75780056fea927d723b53b@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:47 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2(Set|Get)CpuCfsPeriod +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In order to set CPU cfs period using cgroup v2 'cpu.max' interface +we need to load the current value of CPU cfs quota first because +format of 'cpu.max' interface is '$quota $period' and in order to +change 'period' we need to write 'quota' as well. Writing only one +number changes only 'quota'. + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 832422457214421211304bfb0c92b00546dcec53) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <21d457977390fd50b26a2ea5f7f904946578accb.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 68 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 68 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index cb9dd3d8e8..876785e4e1 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -1325,6 +1325,72 @@ virCgroupV2GetCpuShares(virCgroupPtr group, + } + + ++static int ++virCgroupV2SetCpuCfsPeriod(virCgroupPtr group, ++ unsigned long long cfs_period) ++{ ++ VIR_AUTOFREE(char *) value = NULL; ++ VIR_AUTOFREE(char *) str = NULL; ++ char *tmp; ++ ++ /* The cfs_period should be greater or equal than 1ms, and less or equal ++ * than 1s. ++ */ ++ if (cfs_period < 1000 || cfs_period > 1000000) { ++ virReportError(VIR_ERR_INVALID_ARG, ++ _("cfs_period '%llu' must be in range (1000, 1000000)"), ++ cfs_period); ++ return -1; ++ } ++ ++ if (virCgroupGetValueStr(group, VIR_CGROUP_CONTROLLER_CPU, ++ "cpu.max", &str) < 0) { ++ return -1; ++ } ++ ++ if (!(tmp = strchr(str, ' '))) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("Invalid 'cpu.max' data.")); ++ return -1; ++ } ++ *tmp = '\n'; ++ ++ if (virAsprintf(&value, "%s %llu", str, cfs_period) < 0) ++ return -1; ++ ++ return virCgroupSetValueStr(group, VIR_CGROUP_CONTROLLER_CPU, ++ "cpu.max", value); ++} ++ ++ ++static int ++virCgroupV2GetCpuCfsPeriod(virCgroupPtr group, ++ unsigned long long *cfs_period) ++{ ++ VIR_AUTOFREE(char *) str = NULL; ++ char *tmp; ++ ++ if (virCgroupGetValueStr(group, VIR_CGROUP_CONTROLLER_CPU, ++ "cpu.max", &str) < 0) { ++ return -1; ++ } ++ ++ if (!(tmp = strchr(str, ' '))) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("Invalid 'cpu.max' data.")); ++ return -1; ++ } ++ ++ if (virStrToLong_ull(tmp, NULL, 10, cfs_period) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Failed to parse value '%s' from cpu.max."), str); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -1375,6 +1441,8 @@ virCgroupBackend virCgroupV2Backend = { + + .setCpuShares = virCgroupV2SetCpuShares, + .getCpuShares = virCgroupV2GetCpuShares, ++ .setCpuCfsPeriod = virCgroupV2SetCpuCfsPeriod, ++ .getCpuCfsPeriod = virCgroupV2GetCpuCfsPeriod, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2-Set-Get-CpuCfsQuota.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2-Set-Get-CpuCfsQuota.patch new file mode 100644 index 0000000..118afd2 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2-Set-Get-CpuCfsQuota.patch @@ -0,0 +1,94 @@ +From 518ed664601680039546889ea3ebb9a957f26e16 Mon Sep 17 00:00:00 2001 +Message-Id: <518ed664601680039546889ea3ebb9a957f26e16@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:48 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2(Set|Get)CpuCfsQuota +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 8e2c887ffa552b59a3dd80fa73ee60791c960565) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <7fe344c65f7394026a2d9feb45920cd177f5f71c.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 52 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 52 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 876785e4e1..a0a7e55493 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -1391,6 +1391,56 @@ virCgroupV2GetCpuCfsPeriod(virCgroupPtr group, + } + + ++static int ++virCgroupV2SetCpuCfsQuota(virCgroupPtr group, ++ long long cfs_quota) ++{ ++ /* The cfs_quota should be greater or equal than 1ms */ ++ if (cfs_quota >= 0 && ++ (cfs_quota < 1000 || ++ cfs_quota > ULLONG_MAX / 1000)) { ++ virReportError(VIR_ERR_INVALID_ARG, ++ _("cfs_quota '%lld' must be in range (1000, %llu)"), ++ cfs_quota, ULLONG_MAX / 1000); ++ return -1; ++ } ++ ++ if (cfs_quota == ULLONG_MAX / 1000) { ++ return virCgroupSetValueStr(group, ++ VIR_CGROUP_CONTROLLER_CPU, ++ "cpu.max", "max"); ++ } ++ ++ return virCgroupSetValueI64(group, ++ VIR_CGROUP_CONTROLLER_CPU, ++ "cpu.max", cfs_quota); ++} ++ ++ ++static int ++virCgroupV2GetCpuCfsQuota(virCgroupPtr group, ++ long long *cfs_quota) ++{ ++ VIR_AUTOFREE(char *) str = NULL; ++ ++ if (virCgroupGetValueStr(group, VIR_CGROUP_CONTROLLER_CPU, ++ "cpu.max", &str) < 0) { ++ return -1; ++ } ++ ++ if (STREQLEN(str, "max", 3)) ++ *cfs_quota = ULLONG_MAX / 1000; ++ ++ if (virStrToLong_ll(str, NULL, 10, cfs_quota) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Failed to parse value '%s' from cpu.max."), str); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -1443,6 +1493,8 @@ virCgroupBackend virCgroupV2Backend = { + .getCpuShares = virCgroupV2GetCpuShares, + .setCpuCfsPeriod = virCgroupV2SetCpuCfsPeriod, + .getCpuCfsPeriod = virCgroupV2GetCpuCfsPeriod, ++ .setCpuCfsQuota = virCgroupV2SetCpuCfsQuota, ++ .getCpuCfsQuota = virCgroupV2GetCpuCfsQuota, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2-Set-Get-CpuShares.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2-Set-Get-CpuShares.patch new file mode 100644 index 0000000..16317e9 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2-Set-Get-CpuShares.patch @@ -0,0 +1,65 @@ +From aa652c60bb88208f8a73b8d5ae87eab7cb24d23c Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:46 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2(Set|Get)CpuShares +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit b8ca5afc22b4d3af3c8637573f1c3d12887fbb0a) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <5b6c973caaa4b82333949366f034eccaec24277c.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 8d184bd963..cb9dd3d8e8 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -1305,6 +1305,26 @@ virCgroupV2GetMemSwapUsage(virCgroupPtr group, + } + + ++static int ++virCgroupV2SetCpuShares(virCgroupPtr group, ++ unsigned long long shares) ++{ ++ return virCgroupSetValueU64(group, ++ VIR_CGROUP_CONTROLLER_CPU, ++ "cpu.weight", shares); ++} ++ ++ ++static int ++virCgroupV2GetCpuShares(virCgroupPtr group, ++ unsigned long long *shares) ++{ ++ return virCgroupGetValueU64(group, ++ VIR_CGROUP_CONTROLLER_CPU, ++ "cpu.weight", shares); ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -1352,6 +1372,9 @@ virCgroupBackend virCgroupV2Backend = { + .setMemSwapHardLimit = virCgroupV2SetMemSwapHardLimit, + .getMemSwapHardLimit = virCgroupV2GetMemSwapHardLimit, + .getMemSwapUsage = virCgroupV2GetMemSwapUsage, ++ ++ .setCpuShares = virCgroupV2SetCpuShares, ++ .getCpuShares = virCgroupV2GetCpuShares, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2-Set-Get-MemSwapHardLimit.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2-Set-Get-MemSwapHardLimit.patch new file mode 100644 index 0000000..cfdad31 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2-Set-Get-MemSwapHardLimit.patch @@ -0,0 +1,104 @@ +From 86212853c9f16bbed77c2310aed1795fdb04f59d Mon Sep 17 00:00:00 2001 +Message-Id: <86212853c9f16bbed77c2310aed1795fdb04f59d@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:44 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2(Set|Get)MemSwapHardLimit +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit df63fd1f8f17354c5f81c991ff1bb7d12f96d986) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <39af05bcaea91a81740ba6d0b766f773f0e8580b.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 62 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 62 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index d8a1d7712f..fed6792e16 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -1230,6 +1230,66 @@ virCgroupV2GetMemorySoftLimit(virCgroupPtr group, + } + + ++static int ++virCgroupV2SetMemSwapHardLimit(virCgroupPtr group, ++ unsigned long long kb) ++{ ++ unsigned long long maxkb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; ++ ++ if (kb > maxkb) { ++ virReportError(VIR_ERR_INVALID_ARG, ++ _("Memory '%llu' must be less than %llu"), ++ kb, maxkb); ++ return -1; ++ } ++ ++ if (kb == maxkb) { ++ return virCgroupSetValueStr(group, ++ VIR_CGROUP_CONTROLLER_MEMORY, ++ "memory.swap.max", ++ "max"); ++ } else { ++ return virCgroupSetValueU64(group, ++ VIR_CGROUP_CONTROLLER_MEMORY, ++ "memory.swap.max", ++ kb << 10); ++ } ++} ++ ++ ++static int ++virCgroupV2GetMemSwapHardLimit(virCgroupPtr group, ++ unsigned long long *kb) ++{ ++ VIR_AUTOFREE(char *) value = NULL; ++ unsigned long long max; ++ ++ if (virCgroupGetValueStr(group, ++ VIR_CGROUP_CONTROLLER_MEMORY, ++ "memory.swap.max", &value) < 0) { ++ return -1; ++ } ++ ++ if (STREQ(value, "max")) { ++ *kb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; ++ return 0; ++ } ++ ++ if (virStrToLong_ull(value, NULL, 10, &max) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Failed to parse value '%s' as number."), ++ value); ++ return -1; ++ } ++ ++ *kb = max >> 10; ++ if (*kb >= VIR_DOMAIN_MEMORY_PARAM_UNLIMITED) ++ *kb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; ++ ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -1274,6 +1334,8 @@ virCgroupBackend virCgroupV2Backend = { + .getMemoryHardLimit = virCgroupV2GetMemoryHardLimit, + .setMemorySoftLimit = virCgroupV2SetMemorySoftLimit, + .getMemorySoftLimit = virCgroupV2GetMemorySoftLimit, ++ .setMemSwapHardLimit = virCgroupV2SetMemSwapHardLimit, ++ .getMemSwapHardLimit = virCgroupV2GetMemSwapHardLimit, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2-Set-Get-MemoryHardLimit.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2-Set-Get-MemoryHardLimit.patch new file mode 100644 index 0000000..ea250c2 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2-Set-Get-MemoryHardLimit.patch @@ -0,0 +1,85 @@ +From d9dca0b3b1ad64bcde8d96b05538d4656ca93af3 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:42 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2(Set|Get)MemoryHardLimit +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 2aa5385c58d50270d7084f8d11a22ac993275dc0) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 43 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 43 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 87d357b0a7..81a577d28f 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -1130,6 +1130,47 @@ virCgroupV2GetMemoryUsage(virCgroupPtr group, + } + + ++static int ++virCgroupV2SetMemoryHardLimit(virCgroupPtr group, ++ unsigned long long kb) ++{ ++ return virCgroupV2SetMemory(group, kb); ++} ++ ++ ++static int ++virCgroupV2GetMemoryHardLimit(virCgroupPtr group, ++ unsigned long long *kb) ++{ ++ VIR_AUTOFREE(char *) value = NULL; ++ unsigned long long max; ++ ++ if (virCgroupGetValueStr(group, ++ VIR_CGROUP_CONTROLLER_MEMORY, ++ "memory.max", &value) < 0) { ++ return -1; ++ } ++ ++ if (STREQ(value, "max")) { ++ *kb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; ++ return 0; ++ } ++ ++ if (virStrToLong_ull(value, NULL, 10, &max) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Failed to parse value '%s' as number."), ++ value); ++ return -1; ++ } ++ ++ *kb = max >> 10; ++ if (*kb >= VIR_DOMAIN_MEMORY_PARAM_UNLIMITED) ++ *kb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; ++ ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -1170,6 +1211,8 @@ virCgroupBackend virCgroupV2Backend = { + .setMemory = virCgroupV2SetMemory, + .getMemoryStat = virCgroupV2GetMemoryStat, + .getMemoryUsage = virCgroupV2GetMemoryUsage, ++ .setMemoryHardLimit = virCgroupV2SetMemoryHardLimit, ++ .getMemoryHardLimit = virCgroupV2GetMemoryHardLimit, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2-Set-Get-MemorySoftLimit.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2-Set-Get-MemorySoftLimit.patch new file mode 100644 index 0000000..294f6e6 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2-Set-Get-MemorySoftLimit.patch @@ -0,0 +1,103 @@ +From 6a1f3fdcf13ff1fdcbd1f63443a1e5d05b2ddd1c Mon Sep 17 00:00:00 2001 +Message-Id: <6a1f3fdcf13ff1fdcbd1f63443a1e5d05b2ddd1c@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:43 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2(Set|Get)MemorySoftLimit +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 94db4bf86ea10e9853f62c4ea079a432482a58df) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 61 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 61 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 81a577d28f..d8a1d7712f 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -1171,6 +1171,65 @@ virCgroupV2GetMemoryHardLimit(virCgroupPtr group, + } + + ++static int ++virCgroupV2SetMemorySoftLimit(virCgroupPtr group, ++ unsigned long long kb) ++{ ++ unsigned long long maxkb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; ++ ++ if (kb > maxkb) { ++ virReportError(VIR_ERR_INVALID_ARG, ++ _("Memory '%llu' must be less than %llu"), ++ kb, maxkb); ++ return -1; ++ } ++ ++ if (kb == maxkb) { ++ return virCgroupSetValueStr(group, ++ VIR_CGROUP_CONTROLLER_MEMORY, ++ "memory.high", ++ "max"); ++ } else { ++ return virCgroupSetValueU64(group, ++ VIR_CGROUP_CONTROLLER_MEMORY, ++ "memory.high", ++ kb << 10); ++ } ++} ++ ++ ++static int ++virCgroupV2GetMemorySoftLimit(virCgroupPtr group, ++ unsigned long long *kb) ++{ ++ VIR_AUTOFREE(char *) value = NULL; ++ unsigned long long high; ++ ++ if (virCgroupGetValueStr(group, ++ VIR_CGROUP_CONTROLLER_MEMORY, ++ "memory.high", &value) < 0) ++ return -1; ++ ++ if (STREQ(value, "max")) { ++ *kb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; ++ return 0; ++ } ++ ++ if (virStrToLong_ull(value, NULL, 10, &high) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Failed to parse value '%s' as number."), ++ value); ++ return -1; ++ } ++ ++ *kb = high >> 10; ++ if (*kb >= VIR_DOMAIN_MEMORY_PARAM_UNLIMITED) ++ *kb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; ++ ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -1213,6 +1272,8 @@ virCgroupBackend virCgroupV2Backend = { + .getMemoryUsage = virCgroupV2GetMemoryUsage, + .setMemoryHardLimit = virCgroupV2SetMemoryHardLimit, + .getMemoryHardLimit = virCgroupV2GetMemoryHardLimit, ++ .setMemorySoftLimit = virCgroupV2SetMemorySoftLimit, ++ .getMemorySoftLimit = virCgroupV2GetMemorySoftLimit, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2AddTask.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2AddTask.patch new file mode 100644 index 0000000..8d2d50f --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2AddTask.patch @@ -0,0 +1,67 @@ +From cb154a1d153edf2c399493a4336aebdccdc628f5 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:27 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2AddTask +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In cgroups v2 we need to handle threads and processes differently. +If you need to move a process you need to write its pid into +cgrou.procs file and it will move the process with all its threads +as well. The whole process will be moved if you use tid of any thread. + +In order to move only threads at first we need to create threaded group +and after that we can write the relevant thread tids into cgroup.threads +file. Threads can be moved only into cgroups that are children of +cgroup of its process. + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 48572f8825f2bbd7dabb5afb34efbf7afa2f7302) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index b5fad47ca0..6ffb5ce786 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -432,6 +432,20 @@ virCgroupV2Remove(virCgroupPtr group) + } + + ++static int ++virCgroupV2AddTask(virCgroupPtr group, ++ pid_t pid, ++ unsigned int flags) ++{ ++ int controller = virCgroupV2GetAnyController(group); ++ ++ if (flags & VIR_CGROUP_TASK_THREAD) ++ return virCgroupSetValueI64(group, controller, "cgroup.threads", pid); ++ else ++ return virCgroupSetValueI64(group, controller, "cgroup.procs", pid); ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -449,6 +463,7 @@ virCgroupBackend virCgroupV2Backend = { + .pathOfController = virCgroupV2PathOfController, + .makeGroup = virCgroupV2MakeGroup, + .remove = virCgroupV2Remove, ++ .addTask = virCgroupV2AddTask, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2Available.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2Available.patch new file mode 100644 index 0000000..db453d3 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2Available.patch @@ -0,0 +1,116 @@ +From 4551f704f56b289735ed17f3b9ee0f9663183d09 Mon Sep 17 00:00:00 2001 +Message-Id: <4551f704f56b289735ed17f3b9ee0f9663183d09@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:13 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2Available +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We cannot detect only mount points to figure out whether cgroup v2 +is available because systemd uses cgroup v2 for process tracking and +all controllers are mounted as cgroup v1 controllers. + +To make sure that this is no the situation we need to check +'cgroup.controllers' file if it's not empty to make sure that cgroup +v2 is not mounted only for process tracking. + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 034ef217d73aa240340dd22590402bb9636648b5) + +Conflicts: + src/util/vircgroupv2.c: missing commit c0abcca417 + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <46bcb2f86e4ca5f029f67be5385770d725ef5c42.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 51 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 51 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 23bf81dae2..4ab9f2b792 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -19,16 +19,23 @@ + */ + #include + ++#ifdef __linux__ ++# include ++#endif /* __linux__ */ ++ + #include "internal.h" + + #define __VIR_CGROUP_ALLOW_INCLUDE_PRIV_H__ + #include "vircgrouppriv.h" + #undef __VIR_CGROUP_ALLOW_INCLUDE_PRIV_H__ + ++#include "viralloc.h" + #include "vircgroup.h" + #include "vircgroupbackend.h" + #include "vircgroupv2.h" ++#include "virfile.h" + #include "virlog.h" ++#include "virstring.h" + + VIR_LOG_INIT("util.cgroup"); + +@@ -41,8 +48,52 @@ VIR_ENUM_IMPL(virCgroupV2Controller, VIR_CGROUP_CONTROLLER_LAST, + + #ifdef __linux__ + ++/* We're looking for one 'cgroup2' fs mount which has some ++ * controllers enabled. */ ++static bool ++virCgroupV2Available(void) ++{ ++ bool ret = false; ++ FILE *mounts = NULL; ++ struct mntent entry; ++ char buf[CGROUP_MAX_VAL]; ++ ++ if (!(mounts = fopen("/proc/mounts", "r"))) ++ return false; ++ ++ while (getmntent_r(mounts, &entry, buf, sizeof(buf)) != NULL) { ++ VIR_AUTOFREE(char *) contFile = NULL; ++ VIR_AUTOFREE(char *) contStr = NULL; ++ ++ if (STRNEQ(entry.mnt_type, "cgroup2")) ++ continue; ++ ++ /* Systemd uses cgroup v2 for process tracking but no controller is ++ * available. We should consider this configuration as cgroup v2 is ++ * not available. */ ++ if (virAsprintf(&contFile, "%s/cgroup.controllers", entry.mnt_dir) < 0) ++ goto cleanup; ++ ++ if (virFileReadAll(contFile, 1024 * 1024, &contStr) < 0) ++ goto cleanup; ++ ++ if (STREQ(contStr, "")) ++ continue; ++ ++ ret = true; ++ break; ++ } ++ ++ cleanup: ++ VIR_FORCE_FCLOSE(mounts); ++ return ret; ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, ++ ++ .available = virCgroupV2Available, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2BindMount.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2BindMount.patch new file mode 100644 index 0000000..a9373eb --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2BindMount.patch @@ -0,0 +1,83 @@ +From 583928aa5c4d1b28304aa6484ad20cd2036407ae Mon Sep 17 00:00:00 2001 +Message-Id: <583928aa5c4d1b28304aa6484ad20cd2036407ae@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:29 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2BindMount +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit cda8ed0646d82f95d4424cfadfb9233037b1d815) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 34 ++++++++++++++++++++++++++++++++++ + 1 file changed, 34 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 074e6ec110..90ce660908 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -21,6 +21,7 @@ + + #ifdef __linux__ + # include ++# include + #endif /* __linux__ */ + + #include "internal.h" +@@ -462,6 +463,38 @@ virCgroupV2HasEmptyTasks(virCgroupPtr cgroup, + } + + ++static int ++virCgroupV2BindMount(virCgroupPtr group, ++ const char *oldroot, ++ const char *mountopts) ++{ ++ VIR_AUTOFREE(char *) opts = NULL; ++ VIR_AUTOFREE(char *) src = NULL; ++ ++ VIR_DEBUG("Mounting cgroups at '%s'", group->unified.mountPoint); ++ ++ if (virFileMakePath(group->unified.mountPoint) < 0) { ++ virReportSystemError(errno, _("Unable to create directory %s"), ++ group->unified.mountPoint); ++ return -1; ++ } ++ ++ if (virAsprintf(&opts, "mode=755,size=65536%s", mountopts) < 0) ++ return -1; ++ ++ if (virAsprintf(&src, "%s%s", oldroot, group->unified.mountPoint) < 0) ++ return -1; ++ ++ if (mount(src, group->unified.mountPoint, "none", MS_BIND, NULL) < 0) { ++ virReportSystemError(errno, _("Failed to bind cgroup '%s' on '%s'"), ++ src, group->unified.mountPoint); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -481,6 +514,7 @@ virCgroupBackend virCgroupV2Backend = { + .remove = virCgroupV2Remove, + .addTask = virCgroupV2AddTask, + .hasEmptyTasks = virCgroupV2HasEmptyTasks, ++ .bindMount = virCgroupV2BindMount, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2CopyMounts.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2CopyMounts.patch new file mode 100644 index 0000000..334d251 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2CopyMounts.patch @@ -0,0 +1,49 @@ +From 5429c3dfd57da26b6d6fd6368bc88d695ea2e852 Mon Sep 17 00:00:00 2001 +Message-Id: <5429c3dfd57da26b6d6fd6368bc88d695ea2e852@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:15 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2CopyMounts +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 38a3fb56471d77102f58f19a1e68d3fb372e5cb0) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <67863a638cc2666f1f2f8e7151125c32952aa247.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 02dc4e4686..5d3c80b309 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -132,11 +132,20 @@ virCgroupV2ValidateMachineGroup(virCgroupPtr group, + } + + ++static int ++virCgroupV2CopyMounts(virCgroupPtr group, ++ virCgroupPtr parent) ++{ ++ return VIR_STRDUP(group->unified.mountPoint, parent->unified.mountPoint); ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + + .available = virCgroupV2Available, + .validateMachineGroup = virCgroupV2ValidateMachineGroup, ++ .copyMounts = virCgroupV2CopyMounts, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2CopyPlacement.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2CopyPlacement.patch new file mode 100644 index 0000000..c2b9e4a --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2CopyPlacement.patch @@ -0,0 +1,68 @@ +From 1cabfada0f1a83ae78b6a7dbb9128512369fd6f4 Mon Sep 17 00:00:00 2001 +Message-Id: <1cabfada0f1a83ae78b6a7dbb9128512369fd6f4@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:16 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2CopyPlacement +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 7a86201dd6e8cc7e418ea0891aeb44bacd08a10d) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <70993f08246ff3782d9b4a5bdf9187a0c1b57882.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 27 +++++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 5d3c80b309..ed87b35db7 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -140,12 +140,39 @@ virCgroupV2CopyMounts(virCgroupPtr group, + } + + ++static int ++virCgroupV2CopyPlacement(virCgroupPtr group, ++ const char *path, ++ virCgroupPtr parent) ++{ ++ if (path[0] == '/') { ++ if (VIR_STRDUP(group->unified.placement, path) < 0) ++ return -1; ++ } else { ++ /* ++ * parent == "/" + path="" => "/" ++ * parent == "/libvirt.service" + path == "" => "/libvirt.service" ++ * parent == "/libvirt.service" + path == "foo" => "/libvirt.service/foo" ++ */ ++ if (virAsprintf(&group->unified.placement, "%s%s%s", ++ parent->unified.placement, ++ (STREQ(parent->unified.placement, "/") || ++ STREQ(path, "") ? "" : "/"), ++ path) < 0) ++ return -1; ++ } ++ ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + + .available = virCgroupV2Available, + .validateMachineGroup = virCgroupV2ValidateMachineGroup, + .copyMounts = virCgroupV2CopyMounts, ++ .copyPlacement = virCgroupV2CopyPlacement, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2DetectControllers.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2DetectControllers.patch new file mode 100644 index 0000000..af1b97e --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2DetectControllers.patch @@ -0,0 +1,125 @@ +From 079999bce280ca42a47a1521bb3b7bd06f7985f2 Mon Sep 17 00:00:00 2001 +Message-Id: <079999bce280ca42a47a1521bb3b7bd06f7985f2@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:21 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2DetectControllers +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Cgroup v2 has only single mount point for all controllers. The list +of controllers is stored in cgroup.controllers file, name of controllers +are separated by space. + +In cgroup v2 there is no cpuacct controller, the cpu.stat file always +exists with usage stats. + +Signed-off-by: Pavel Hrdina +(cherry picked from commit e1bb7fffe2571e6a337bd87a9c5ed487ee6ee046) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <2186bc99cdcfc420b1aaf516fc808dfbf582a1d0.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 69 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 69 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 270a6fb305..c8f2573864 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -33,6 +33,7 @@ + #include "vircgroup.h" + #include "vircgroupbackend.h" + #include "vircgroupv2.h" ++#include "virerror.h" + #include "virfile.h" + #include "virlog.h" + #include "virstring.h" +@@ -231,6 +232,73 @@ virCgroupV2StealPlacement(virCgroupPtr group) + } + + ++static int ++virCgroupV2ParseControllersFile(virCgroupPtr group) ++{ ++ int rc; ++ VIR_AUTOFREE(char *) contStr = NULL; ++ VIR_AUTOFREE(char *) contFile = NULL; ++ char **contList = NULL; ++ char **tmp; ++ ++ if (virAsprintf(&contFile, "%s/cgroup.controllers", ++ group->unified.mountPoint) < 0) ++ return -1; ++ ++ rc = virFileReadAll(contFile, 1024 * 1024, &contStr); ++ if (rc < 0) { ++ virReportSystemError(errno, _("Unable to read from '%s'"), contFile); ++ return -1; ++ } ++ ++ virTrimSpaces(contStr, NULL); ++ ++ contList = virStringSplit(contStr, " ", 20); ++ if (!contList) ++ return -1; ++ ++ tmp = contList; ++ ++ while (*tmp) { ++ int type = virCgroupV2ControllerTypeFromString(*tmp); ++ ++ if (type >= 0) ++ group->unified.controllers |= 1 << type; ++ ++ tmp++; ++ } ++ ++ virStringListFree(contList); ++ ++ return 0; ++} ++ ++ ++static int ++virCgroupV2DetectControllers(virCgroupPtr group, ++ int controllers) ++{ ++ size_t i; ++ ++ if (virCgroupV2ParseControllersFile(group) < 0) ++ return -1; ++ ++ /* In cgroup v2 there is no cpuacct controller, the cpu.stat file always ++ * exists with usage stats. */ ++ group->unified.controllers |= 1 << VIR_CGROUP_CONTROLLER_CPUACCT; ++ ++ for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) ++ VIR_DEBUG("Controller '%s' present=%s", ++ virCgroupV2ControllerTypeToString(i), ++ (group->unified.controllers & 1 << i) ? "yes" : "no"); ++ ++ if (controllers >= 0) ++ return controllers & group->unified.controllers; ++ else ++ return group->unified.controllers; ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -242,6 +310,7 @@ virCgroupBackend virCgroupV2Backend = { + .detectPlacement = virCgroupV2DetectPlacement, + .validatePlacement = virCgroupV2ValidatePlacement, + .stealPlacement = virCgroupV2StealPlacement, ++ .detectControllers = virCgroupV2DetectControllers, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2DetectMounts.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2DetectMounts.patch new file mode 100644 index 0000000..de683e7 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2DetectMounts.patch @@ -0,0 +1,58 @@ +From d27635600023556a1e1ea566f0860facdf8d69c9 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:17 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2DetectMounts +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 50f61a46fcd0f25f98bb89db74bea76bca5dc4a4) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <050f43f97c07f9dc1c17f477c043fbe3a6759396.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index ed87b35db7..19a9ba38f8 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -166,6 +166,21 @@ virCgroupV2CopyPlacement(virCgroupPtr group, + } + + ++static int ++virCgroupV2DetectMounts(virCgroupPtr group, ++ const char *mntType, ++ const char *mntOpts ATTRIBUTE_UNUSED, ++ const char *mntDir) ++{ ++ if (STRNEQ(mntType, "cgroup2")) ++ return 0; ++ ++ VIR_FREE(group->unified.mountPoint); ++ ++ return VIR_STRDUP(group->unified.mountPoint, mntDir); ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -173,6 +188,7 @@ virCgroupBackend virCgroupV2Backend = { + .validateMachineGroup = virCgroupV2ValidateMachineGroup, + .copyMounts = virCgroupV2CopyMounts, + .copyPlacement = virCgroupV2CopyPlacement, ++ .detectMounts = virCgroupV2DetectMounts, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2DetectPlacement.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2DetectPlacement.patch new file mode 100644 index 0000000..3998c21 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2DetectPlacement.patch @@ -0,0 +1,72 @@ +From af9bf10ff9d8a6f0ae9b6d898138144bf7dcd161 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:18 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2DetectPlacement +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If the placement was copied from parent or set to absolute path +there is nothing to do, otherwise set the placement based on +process placement from /proc/self/cgroup or /proc/{pid}/cgroup. + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 1efcf202e777d32600e90f3176e0357053341533) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <7fcc9d25385c40df5531e5b7171338a624d0c4fb.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 26 ++++++++++++++++++++++++++ + 1 file changed, 26 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 19a9ba38f8..fb1aa2de0a 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -181,6 +181,31 @@ virCgroupV2DetectMounts(virCgroupPtr group, + } + + ++static int ++virCgroupV2DetectPlacement(virCgroupPtr group, ++ const char *path, ++ const char *controllers ATTRIBUTE_UNUSED, ++ const char *selfpath) ++{ ++ if (group->unified.placement) ++ return 0; ++ ++ /* ++ * selfpath == "/" + path="" -> "/" ++ * selfpath == "/libvirt.service" + path == "" -> "/libvirt.service" ++ * selfpath == "/libvirt.service" + path == "foo" -> "/libvirt.service/foo" ++ */ ++ if (virAsprintf(&group->unified.placement, ++ "%s%s%s", selfpath, ++ (STREQ(selfpath, "/") || ++ STREQ(path, "") ? "" : "/"), ++ path) < 0) ++ return -1; ++ ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -189,6 +214,7 @@ virCgroupBackend virCgroupV2Backend = { + .copyMounts = virCgroupV2CopyMounts, + .copyPlacement = virCgroupV2CopyPlacement, + .detectMounts = virCgroupV2DetectMounts, ++ .detectPlacement = virCgroupV2DetectPlacement, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2GetAnyController.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2GetAnyController.patch new file mode 100644 index 0000000..601d42b --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2GetAnyController.patch @@ -0,0 +1,51 @@ +From 6fc9abce93fb193d748c45dbe47920b287c9aa07 Mon Sep 17 00:00:00 2001 +Message-Id: <6fc9abce93fb193d748c45dbe47920b287c9aa07@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:23 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2GetAnyController +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 171c700cd8c5509dc868c00faed9a16feaa2339d) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <2bc9d83fa5195d1650a8801c69b850ff86fd8386.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index babce95aeb..65cbad533b 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -307,6 +307,14 @@ virCgroupV2HasController(virCgroupPtr group, + } + + ++static int ++virCgroupV2GetAnyController(virCgroupPtr group) ++{ ++ /* The least significant bit is position 1. */ ++ return ffs(group->unified.controllers) - 1; ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -320,6 +328,7 @@ virCgroupBackend virCgroupV2Backend = { + .stealPlacement = virCgroupV2StealPlacement, + .detectControllers = virCgroupV2DetectControllers, + .hasController = virCgroupV2HasController, ++ .getAnyController = virCgroupV2GetAnyController, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2GetBlkioIoDeviceServiced.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2GetBlkioIoDeviceServiced.patch new file mode 100644 index 0000000..3b8bc9a --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2GetBlkioIoDeviceServiced.patch @@ -0,0 +1,106 @@ +From e549b6a2270598ad1e736837430573fafb6a7e64 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:33 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2GetBlkioIoDeviceServiced +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 93fa369df5edbf693cee472a9a8c2caa313ae2a0) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 64 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 64 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 000fd4c747..fcf39406e1 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -631,6 +631,69 @@ virCgroupV2GetBlkioIoServiced(virCgroupPtr group, + } + + ++static int ++virCgroupV2GetBlkioIoDeviceServiced(virCgroupPtr group, ++ const char *path, ++ long long *bytes_read, ++ long long *bytes_write, ++ long long *requests_read, ++ long long *requests_write) ++{ ++ VIR_AUTOFREE(char *) str1 = NULL; ++ VIR_AUTOFREE(char *) str2 = NULL; ++ char *p1; ++ size_t i; ++ ++ const char *value_names[] = { ++ "rbytes=", ++ "wbytes=", ++ "rios=", ++ "wios=", ++ }; ++ long long *value_ptrs[] = { ++ bytes_read, ++ bytes_write, ++ requests_read, ++ requests_write ++ }; ++ ++ if (virCgroupGetValueStr(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "io.stat", &str1) < 0) { ++ return -1; ++ } ++ ++ if (!(str2 = virCgroupGetBlockDevString(path))) ++ return -1; ++ ++ if (!(p1 = strstr(str1, str2))) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Cannot find byte stats for block device '%s'"), ++ str2); ++ return -1; ++ } ++ ++ for (i = 0; i < ARRAY_CARDINALITY(value_names); i++) { ++ if (!(p1 = strstr(p1, value_names[i]))) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Cannot find byte '%s' stats for block device '%s'"), ++ value_names[i], str2); ++ return -1; ++ } ++ ++ p1 += strlen(value_names[i]); ++ if (virStrToLong_ll(p1, &p1, 10, value_ptrs[i]) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Cannot parse '%s' stat '%s'"), ++ value_names[i], p1); ++ return -1; ++ } ++ } ++ ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -656,6 +719,7 @@ virCgroupBackend virCgroupV2Backend = { + .setBlkioWeight = virCgroupV2SetBlkioWeight, + .getBlkioWeight = virCgroupV2GetBlkioWeight, + .getBlkioIoServiced = virCgroupV2GetBlkioIoServiced, ++ .getBlkioIoDeviceServiced = virCgroupV2GetBlkioIoDeviceServiced, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2GetBlkioIoServiced.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2GetBlkioIoServiced.patch new file mode 100644 index 0000000..81ec8b6 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2GetBlkioIoServiced.patch @@ -0,0 +1,107 @@ +From abf2cfc52b828aa892b446385875381f735ff947 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:32 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2GetBlkioIoServiced +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 709260add941a247b3829cf940624333cb445bb7) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 65 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 65 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index f7863a5690..000fd4c747 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -567,6 +567,70 @@ virCgroupV2GetBlkioWeight(virCgroupPtr group, + } + + ++static int ++virCgroupV2GetBlkioIoServiced(virCgroupPtr group, ++ long long *bytes_read, ++ long long *bytes_write, ++ long long *requests_read, ++ long long *requests_write) ++{ ++ long long stats_val; ++ VIR_AUTOFREE(char *) str1 = NULL; ++ char *p1; ++ size_t i; ++ ++ const char *value_names[] = { ++ "rbytes=", ++ "wbytes=", ++ "rios=", ++ "wios=", ++ }; ++ long long *value_ptrs[] = { ++ bytes_read, ++ bytes_write, ++ requests_read, ++ requests_write ++ }; ++ ++ *bytes_read = 0; ++ *bytes_write = 0; ++ *requests_read = 0; ++ *requests_write = 0; ++ ++ if (virCgroupGetValueStr(group, ++ VIR_CGROUP_CONTROLLER_BLKIO, ++ "io.stat", &str1) < 0) { ++ return -1; ++ } ++ ++ /* sum up all entries of the same kind, from all devices */ ++ for (i = 0; i < ARRAY_CARDINALITY(value_names); i++) { ++ p1 = str1; ++ ++ while ((p1 = strstr(p1, value_names[i]))) { ++ p1 += strlen(value_names[i]); ++ if (virStrToLong_ll(p1, &p1, 10, &stats_val) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Cannot parse byte '%s' stat '%s'"), ++ value_names[i], p1); ++ return -1; ++ } ++ ++ if (stats_val < 0 || ++ (stats_val > 0 && *value_ptrs[i] > (LLONG_MAX - stats_val))) { ++ virReportError(VIR_ERR_OVERFLOW, ++ _("Sum of byte '%s' stat overflows"), ++ value_names[i]); ++ return -1; ++ } ++ *value_ptrs[i] += stats_val; ++ } ++ } ++ ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -591,6 +655,7 @@ virCgroupBackend virCgroupV2Backend = { + + .setBlkioWeight = virCgroupV2SetBlkioWeight, + .getBlkioWeight = virCgroupV2GetBlkioWeight, ++ .getBlkioIoServiced = virCgroupV2GetBlkioIoServiced, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2GetCpuacctStat.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2GetCpuacctStat.patch new file mode 100644 index 0000000..6370f22 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2GetCpuacctStat.patch @@ -0,0 +1,91 @@ +From d54383e93c3d3a71008d4b3a48b4dafba2368609 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:51 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2GetCpuacctStat +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 4d1d5c92bdefc38bc68bde5f9bd2dbd3c11bff2a) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <62365d349154035cfab2115d66430dcf3c7bdd03.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 49 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 49 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index afa243b3c7..d6362e2b05 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -1487,6 +1487,54 @@ virCgroupV2GetCpuacctUsage(virCgroupPtr group, + } + + ++static int ++virCgroupV2GetCpuacctStat(virCgroupPtr group, ++ unsigned long long *user, ++ unsigned long long *sys) ++{ ++ VIR_AUTOFREE(char *) str = NULL; ++ char *tmp; ++ unsigned long long userVal = 0; ++ unsigned long long sysVal = 0; ++ ++ if (virCgroupGetValueStr(group, VIR_CGROUP_CONTROLLER_CPUACCT, ++ "cpu.stat", &str) < 0) { ++ return -1; ++ } ++ ++ if (!(tmp = strstr(str, "user_usec "))) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("cannot parse cpu user stat '%s'"), str); ++ return -1; ++ } ++ tmp += strlen("user_usec "); ++ ++ if (virStrToLong_ull(tmp, &tmp, 10, &userVal) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Failed to parse value '%s' as number."), tmp); ++ return -1; ++ } ++ ++ if (!(tmp = strstr(str, "system_usec "))) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("cannot parse cpu sys stat '%s'"), str); ++ return -1; ++ } ++ tmp += strlen("system_usec "); ++ ++ if (virStrToLong_ull(tmp, &tmp, 10, &sysVal) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Failed to parse value '%s' as number."), tmp); ++ return -1; ++ } ++ ++ *user = userVal * 1000; ++ *sys = sysVal * 1000; ++ ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -1544,6 +1592,7 @@ virCgroupBackend virCgroupV2Backend = { + .supportsCpuBW = virCgroupV2SupportsCpuBW, + + .getCpuacctUsage = virCgroupV2GetCpuacctUsage, ++ .getCpuacctStat = virCgroupV2GetCpuacctStat, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2GetCpuacctUsage.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2GetCpuacctUsage.patch new file mode 100644 index 0000000..6f16073 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2GetCpuacctUsage.patch @@ -0,0 +1,75 @@ +From e0764ef7577519de460fc2c2d52127eafb077200 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:50 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2GetCpuacctUsage +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 567fcbdca56ac409e856a0be8425b2218d02fe81) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <26dc66d290ee4d5a4ba67470552df9d2fa4ae86b.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 33 +++++++++++++++++++++++++++++++++ + 1 file changed, 33 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 55f79af204..afa243b3c7 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -1456,6 +1456,37 @@ virCgroupV2SupportsCpuBW(virCgroupPtr cgroup) + } + + ++static int ++virCgroupV2GetCpuacctUsage(virCgroupPtr group, ++ unsigned long long *usage) ++{ ++ VIR_AUTOFREE(char *) str = NULL; ++ char *tmp; ++ ++ if (virCgroupGetValueStr(group, VIR_CGROUP_CONTROLLER_CPUACCT, ++ "cpu.stat", &str) < 0) { ++ return -1; ++ } ++ ++ if (!(tmp = strstr(str, "usage_usec "))) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("cannot parse cpu usage stat '%s'"), str); ++ return -1; ++ } ++ tmp += strlen("usage_usec "); ++ ++ if (virStrToLong_ull(tmp, &tmp, 10, usage) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Failed to parse value '%s' as number."), tmp); ++ return -1; ++ } ++ ++ *usage *= 1000; ++ ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -1511,6 +1542,8 @@ virCgroupBackend virCgroupV2Backend = { + .setCpuCfsQuota = virCgroupV2SetCpuCfsQuota, + .getCpuCfsQuota = virCgroupV2GetCpuCfsQuota, + .supportsCpuBW = virCgroupV2SupportsCpuBW, ++ ++ .getCpuacctUsage = virCgroupV2GetCpuacctUsage, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2GetMemSwapUsage.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2GetMemSwapUsage.patch new file mode 100644 index 0000000..2e1b584 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2GetMemSwapUsage.patch @@ -0,0 +1,58 @@ +From 64df2fa746eab23c73578c53b6d8501cbec2d04c Mon Sep 17 00:00:00 2001 +Message-Id: <64df2fa746eab23c73578c53b6d8501cbec2d04c@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:45 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2GetMemSwapUsage +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 3f728c720b782e853de4c43999a37aeceb3f95b8) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index fed6792e16..8d184bd963 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -1290,6 +1290,21 @@ virCgroupV2GetMemSwapHardLimit(virCgroupPtr group, + } + + ++static int ++virCgroupV2GetMemSwapUsage(virCgroupPtr group, ++ unsigned long long *kb) ++{ ++ unsigned long long usage_in_bytes; ++ int ret; ++ ret = virCgroupGetValueU64(group, ++ VIR_CGROUP_CONTROLLER_MEMORY, ++ "memory.swap.current", &usage_in_bytes); ++ if (ret == 0) ++ *kb = (unsigned long) usage_in_bytes >> 10; ++ return ret; ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -1336,6 +1351,7 @@ virCgroupBackend virCgroupV2Backend = { + .getMemorySoftLimit = virCgroupV2GetMemorySoftLimit, + .setMemSwapHardLimit = virCgroupV2SetMemSwapHardLimit, + .getMemSwapHardLimit = virCgroupV2GetMemSwapHardLimit, ++ .getMemSwapUsage = virCgroupV2GetMemSwapUsage, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2GetMemoryStat.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2GetMemoryStat.patch new file mode 100644 index 0000000..1233bef --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2GetMemoryStat.patch @@ -0,0 +1,117 @@ +From 7b4215f8a38221fd90bf15a3ced42cce55adf105 Mon Sep 17 00:00:00 2001 +Message-Id: <7b4215f8a38221fd90bf15a3ced42cce55adf105@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:40 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2GetMemoryStat +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit d080c001660ed0f173066b3db63ecac4edb773fc) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <9ebb30d0c01bdb6e356928701cd56501fe43af5e.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 75 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 75 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 1b7215d98b..1c7854909f 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -1042,6 +1042,80 @@ virCgroupV2SetMemory(virCgroupPtr group, + } + + ++static int ++virCgroupV2GetMemoryStat(virCgroupPtr group, ++ unsigned long long *cache, ++ unsigned long long *activeAnon, ++ unsigned long long *inactiveAnon, ++ unsigned long long *activeFile, ++ unsigned long long *inactiveFile, ++ unsigned long long *unevictable) ++{ ++ VIR_AUTOFREE(char *) stat = NULL; ++ char *line = NULL; ++ unsigned long long cacheVal = 0; ++ unsigned long long activeAnonVal = 0; ++ unsigned long long inactiveAnonVal = 0; ++ unsigned long long activeFileVal = 0; ++ unsigned long long inactiveFileVal = 0; ++ unsigned long long unevictableVal = 0; ++ ++ if (virCgroupGetValueStr(group, ++ VIR_CGROUP_CONTROLLER_MEMORY, ++ "memory.stat", ++ &stat) < 0) { ++ return -1; ++ } ++ ++ line = stat; ++ ++ while (line) { ++ char *newLine = strchr(line, '\n'); ++ char *valueStr = strchr(line, ' '); ++ unsigned long long value; ++ ++ if (newLine) ++ *newLine = '\0'; ++ ++ if (!valueStr) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("Cannot parse 'memory.stat' cgroup file.")); ++ return -1; ++ } ++ *valueStr = '\0'; ++ ++ if (virStrToLong_ull(valueStr + 1, NULL, 10, &value) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Unable to parse '%s' as an integer"), ++ valueStr + 1); ++ return -1; ++ } ++ ++ if (STREQ(line, "file")) ++ cacheVal = value >> 10; ++ else if (STREQ(line, "active_anon")) ++ activeAnonVal = value >> 10; ++ else if (STREQ(line, "inactive_anon")) ++ inactiveAnonVal = value >> 10; ++ else if (STREQ(line, "active_file")) ++ activeFileVal = value >> 10; ++ else if (STREQ(line, "inactive_file")) ++ inactiveFileVal = value >> 10; ++ else if (STREQ(line, "unevictable")) ++ unevictableVal = value >> 10; ++ } ++ ++ *cache = cacheVal; ++ *activeAnon = activeAnonVal; ++ *inactiveAnon = inactiveAnonVal; ++ *activeFile = activeFileVal; ++ *inactiveFile = inactiveFileVal; ++ *unevictable = unevictableVal; ++ ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -1080,6 +1154,7 @@ virCgroupBackend virCgroupV2Backend = { + .getBlkioDeviceWriteBps = virCgroupV2GetBlkioDeviceWriteBps, + + .setMemory = virCgroupV2SetMemory, ++ .getMemoryStat = virCgroupV2GetMemoryStat, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2GetMemoryUsage.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2GetMemoryUsage.patch new file mode 100644 index 0000000..64e2f07 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2GetMemoryUsage.patch @@ -0,0 +1,57 @@ +From 0f9d55fe0fbbdc66a5fdc2236c9433aab840a1b9 Mon Sep 17 00:00:00 2001 +Message-Id: <0f9d55fe0fbbdc66a5fdc2236c9433aab840a1b9@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:41 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2GetMemoryUsage +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 495f60edcb123a714706f765027ea190f8d20da3) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 1c7854909f..87d357b0a7 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -1116,6 +1116,20 @@ virCgroupV2GetMemoryStat(virCgroupPtr group, + } + + ++static int ++virCgroupV2GetMemoryUsage(virCgroupPtr group, ++ unsigned long *kb) ++{ ++ unsigned long long usage_in_bytes; ++ int ret = virCgroupGetValueU64(group, ++ VIR_CGROUP_CONTROLLER_MEMORY, ++ "memory.current", &usage_in_bytes); ++ if (ret == 0) ++ *kb = (unsigned long) usage_in_bytes >> 10; ++ return ret; ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -1155,6 +1169,7 @@ virCgroupBackend virCgroupV2Backend = { + + .setMemory = virCgroupV2SetMemory, + .getMemoryStat = virCgroupV2GetMemoryStat, ++ .getMemoryUsage = virCgroupV2GetMemoryUsage, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2HasController.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2HasController.patch new file mode 100644 index 0000000..9221fa2 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2HasController.patch @@ -0,0 +1,51 @@ +From e5f2fdbd6499d97073ad20fe1ea491accecff704 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:22 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2HasController +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit c8f08a5346919b3d963908eb0b61fc077dbdbccd) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <8dfef2b4c814027c13ab2d693144ec77844bff7a.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index c8f2573864..babce95aeb 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -299,6 +299,14 @@ virCgroupV2DetectControllers(virCgroupPtr group, + } + + ++static bool ++virCgroupV2HasController(virCgroupPtr group, ++ int controller) ++{ ++ return group->unified.controllers & (1 << controller); ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -311,6 +319,7 @@ virCgroupBackend virCgroupV2Backend = { + .validatePlacement = virCgroupV2ValidatePlacement, + .stealPlacement = virCgroupV2StealPlacement, + .detectControllers = virCgroupV2DetectControllers, ++ .hasController = virCgroupV2HasController, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2HasEmptyTasks.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2HasEmptyTasks.patch new file mode 100644 index 0000000..2c6a126 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2HasEmptyTasks.patch @@ -0,0 +1,59 @@ +From 40a3ab5f35bb847ae210160b5bcb2b3ab8990e5a Mon Sep 17 00:00:00 2001 +Message-Id: <40a3ab5f35bb847ae210160b5bcb2b3ab8990e5a@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:28 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2HasEmptyTasks +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 38411bb831a8c5086145b9781168349bc64fbc25) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <36bb2bd62faa6528de46da822d026f67be9f6d16.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 6ffb5ce786..074e6ec110 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -446,6 +446,22 @@ virCgroupV2AddTask(virCgroupPtr group, + } + + ++static int ++virCgroupV2HasEmptyTasks(virCgroupPtr cgroup, ++ int controller) ++{ ++ int ret = -1; ++ VIR_AUTOFREE(char *) content = NULL; ++ ++ ret = virCgroupGetValueStr(cgroup, controller, "cgroup.procs", &content); ++ ++ if (ret == 0 && content[0] == '\0') ++ ret = 1; ++ ++ return ret; ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -464,6 +480,7 @@ virCgroupBackend virCgroupV2Backend = { + .makeGroup = virCgroupV2MakeGroup, + .remove = virCgroupV2Remove, + .addTask = virCgroupV2AddTask, ++ .hasEmptyTasks = virCgroupV2HasEmptyTasks, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2MakeGroup.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2MakeGroup.patch new file mode 100644 index 0000000..aeb0055 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2MakeGroup.patch @@ -0,0 +1,174 @@ +From 4a7aa0ff6839fd9ccefce19d63c48beed32ee7f1 Mon Sep 17 00:00:00 2001 +Message-Id: <4a7aa0ff6839fd9ccefce19d63c48beed32ee7f1@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:25 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2MakeGroup +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When creating cgroup hierarchy we need to enable controllers in the +parent cgroup in order to be usable. That means writing "+{controller}" +into cgroup.subtree_control file. We can enable only controllers that +are enabled for parent cgroup, that means we need to do that for the +whole cgroup tree. + +Cgroups for threads needs to be handled differently in cgroup v2. There +are two types of controllers: + + - domain controllers: these cannot be enabled for threads + - threaded controllers: these can be enabled for threads + +In addition there are multiple types of cgroups: + + - domain: normal cgroup + - domain threaded: a domain cgroup that serves as root for threaded + cgroups + - domain invalid: invalid cgroup, can be changed into threaded, this + is the default state if you create subgroup inside + domain threaded group or threaded group + - threaded: threaded cgroup which can have domain threaded or + threaded as parent group + +In order to create threaded cgroup it's sufficient to write "threaded" +into cgroup.type file, it will automatically make parent cgroup +"domain threaded" if it was only "domain". In case the parent cgroup +is already "domain threaded" or "threaded" it will modify only the type +of current cgroup. After that we can enable threaded controllers. + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 89f52abd07d3f991ddd22990e5d61338ff350a99) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <165b3b0f0fd1e5a4b52e4b9e86e4137b3598f7ee.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 2 +- + src/util/vircgroupbackend.h | 1 + + src/util/vircgroupv2.c | 76 +++++++++++++++++++++++++++++++++++++ + 3 files changed, 78 insertions(+), 1 deletion(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 42930582db..a859628241 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -942,7 +942,7 @@ virCgroupNewThread(virCgroupPtr domain, + if (virCgroupNew(-1, name, domain, controllers, group) < 0) + return -1; + +- if (virCgroupMakeGroup(domain, *group, create, VIR_CGROUP_NONE) < 0) { ++ if (virCgroupMakeGroup(domain, *group, create, VIR_CGROUP_THREAD) < 0) { + virCgroupFree(group); + return -1; + } +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index b1f19233e4..86d1539e07 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -33,6 +33,7 @@ typedef enum { + * before creating subcgroups and + * attaching tasks + */ ++ VIR_CGROUP_THREAD = 1 << 1, /* cgroup v2 handles threads differently */ + } virCgroupBackendFlags; + + typedef enum { +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 6695901766..cf8bd01317 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -338,6 +338,81 @@ virCgroupV2PathOfController(virCgroupPtr group, + } + + ++static int ++virCgroupV2EnableController(virCgroupPtr parent, ++ int controller) ++{ ++ VIR_AUTOFREE(char *) val = NULL; ++ ++ if (virAsprintf(&val, "+%s", ++ virCgroupV2ControllerTypeToString(controller)) < 0) { ++ return -1; ++ } ++ ++ if (virCgroupSetValueStr(parent, controller, ++ "cgroup.subtree_control", val) < 0) { ++ return -1; ++ } ++ ++ return 0; ++} ++ ++ ++static int ++virCgroupV2MakeGroup(virCgroupPtr parent ATTRIBUTE_UNUSED, ++ virCgroupPtr group, ++ bool create, ++ unsigned int flags) ++{ ++ VIR_AUTOFREE(char *) path = NULL; ++ int controller; ++ ++ VIR_DEBUG("Make group %s", group->path); ++ ++ controller = virCgroupV2GetAnyController(group); ++ if (virCgroupV2PathOfController(group, controller, "", &path) < 0) ++ return -1; ++ ++ VIR_DEBUG("Make controller %s", path); ++ ++ if (!virFileExists(path) && ++ (!create || (mkdir(path, 0755) < 0 && errno != EEXIST))) { ++ virReportSystemError(errno, _("Failed to create v2 cgroup '%s'"), ++ group->path); ++ return -1; ++ } ++ ++ if (create) { ++ if (flags & VIR_CGROUP_THREAD) { ++ if (virCgroupSetValueStr(group, VIR_CGROUP_CONTROLLER_CPU, ++ "cgroup.type", "threaded") < 0) { ++ return -1; ++ } ++ ++ if (virCgroupV2EnableController(parent, ++ VIR_CGROUP_CONTROLLER_CPU) < 0) { ++ return -1; ++ } ++ } else { ++ size_t i; ++ for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { ++ if (!virCgroupV2HasController(parent, i)) ++ continue; ++ ++ /* Controllers that are implicitly enabled if available. */ ++ if (i == VIR_CGROUP_CONTROLLER_CPUACCT) ++ continue; ++ ++ if (virCgroupV2EnableController(parent, i) < 0) ++ return -1; ++ } ++ } ++ } ++ ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -353,6 +428,7 @@ virCgroupBackend virCgroupV2Backend = { + .hasController = virCgroupV2HasController, + .getAnyController = virCgroupV2GetAnyController, + .pathOfController = virCgroupV2PathOfController, ++ .makeGroup = virCgroupV2MakeGroup, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2PathOfController.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2PathOfController.patch new file mode 100644 index 0000000..012f7ba --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2PathOfController.patch @@ -0,0 +1,66 @@ +From 2a826bcdbe8e34af71634250ae814d5ff81d6ffc Mon Sep 17 00:00:00 2001 +Message-Id: <2a826bcdbe8e34af71634250ae814d5ff81d6ffc@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:24 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2PathOfController +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 0542640a9c480993c7e8be6917b0f513277b4cea) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <91b63d07af48bdb0fdc9648f4e5e4808cc90ad0e.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 65cbad533b..6695901766 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -315,6 +315,29 @@ virCgroupV2GetAnyController(virCgroupPtr group) + } + + ++static int ++virCgroupV2PathOfController(virCgroupPtr group, ++ int controller, ++ const char *key, ++ char **path) ++{ ++ if (!virCgroupV2HasController(group, controller)) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("v2 controller '%s' is not available"), ++ virCgroupV2ControllerTypeToString(controller)); ++ return -1; ++ } ++ ++ if (virAsprintf(path, "%s%s/%s", ++ group->unified.mountPoint, ++ group->unified.placement, ++ key ? key : "") < 0) ++ return -1; ++ ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -329,6 +352,7 @@ virCgroupBackend virCgroupV2Backend = { + .detectControllers = virCgroupV2DetectControllers, + .hasController = virCgroupV2HasController, + .getAnyController = virCgroupV2GetAnyController, ++ .pathOfController = virCgroupV2PathOfController, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2Remove.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2Remove.patch new file mode 100644 index 0000000..0dc70a5 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2Remove.patch @@ -0,0 +1,62 @@ +From 4a95be40b1a56cc0eb6d6f56161d536f22380804 Mon Sep 17 00:00:00 2001 +Message-Id: <4a95be40b1a56cc0eb6d6f56161d536f22380804@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:26 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2Remove +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 4fe4847438c8ff042d6d39718b26023199e67c8a) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index cf8bd01317..b5fad47ca0 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -413,6 +413,25 @@ virCgroupV2MakeGroup(virCgroupPtr parent ATTRIBUTE_UNUSED, + } + + ++static int ++virCgroupV2Remove(virCgroupPtr group) ++{ ++ VIR_AUTOFREE(char *) grppath = NULL; ++ int controller; ++ ++ /* Don't delete the root group, if we accidentally ++ ended up in it for some reason */ ++ if (STREQ(group->unified.placement, "/")) ++ return 0; ++ ++ controller = virCgroupV2GetAnyController(group); ++ if (virCgroupV2PathOfController(group, controller, "", &grppath) < 0) ++ return 0; ++ ++ return virCgroupRemoveRecursively(grppath); ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -429,6 +448,7 @@ virCgroupBackend virCgroupV2Backend = { + .getAnyController = virCgroupV2GetAnyController, + .pathOfController = virCgroupV2PathOfController, + .makeGroup = virCgroupV2MakeGroup, ++ .remove = virCgroupV2Remove, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2SetMemory.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2SetMemory.patch new file mode 100644 index 0000000..2dfb833 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2SetMemory.patch @@ -0,0 +1,71 @@ +From 9697d24cc223028555629af325af8607de350d06 Mon Sep 17 00:00:00 2001 +Message-Id: <9697d24cc223028555629af325af8607de350d06@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:39 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2SetMemory +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 63bd23a6ad17331cdc31bc07fd8b21a96d4b2eb0) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 29 +++++++++++++++++++++++++++++ + 1 file changed, 29 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 52d31925c2..1b7215d98b 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -1015,6 +1015,33 @@ virCgroupV2GetBlkioDeviceWriteBps(virCgroupPtr group, + } + + ++static int ++virCgroupV2SetMemory(virCgroupPtr group, ++ unsigned long long kb) ++{ ++ unsigned long long maxkb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; ++ ++ if (kb > maxkb) { ++ virReportError(VIR_ERR_INVALID_ARG, ++ _("Memory '%llu' must be less than %llu"), ++ kb, maxkb); ++ return -1; ++ } ++ ++ if (kb == maxkb) { ++ return virCgroupSetValueStr(group, ++ VIR_CGROUP_CONTROLLER_MEMORY, ++ "memory.max", ++ "max"); ++ } else { ++ return virCgroupSetValueU64(group, ++ VIR_CGROUP_CONTROLLER_MEMORY, ++ "memory.max", ++ kb << 10); ++ } ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -1051,6 +1078,8 @@ virCgroupBackend virCgroupV2Backend = { + .getBlkioDeviceReadBps = virCgroupV2GetBlkioDeviceReadBps, + .setBlkioDeviceWriteBps = virCgroupV2SetBlkioDeviceWriteBps, + .getBlkioDeviceWriteBps = virCgroupV2GetBlkioDeviceWriteBps, ++ ++ .setMemory = virCgroupV2SetMemory, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2SetOwner.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2SetOwner.patch new file mode 100644 index 0000000..4df00cb --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2SetOwner.patch @@ -0,0 +1,69 @@ +From c7f704deec7b42ec02ae13a678474b3ca62fecbd Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:30 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2SetOwner +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 525ac6885b508759f8618f136f04554c95138ae8) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <778612847c720bc6567b98708532175ada48ce44.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 27 +++++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 90ce660908..27519d80e3 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -495,6 +495,32 @@ virCgroupV2BindMount(virCgroupPtr group, + } + + ++static int ++virCgroupV2SetOwner(virCgroupPtr cgroup, ++ uid_t uid, ++ gid_t gid, ++ int controllers ATTRIBUTE_UNUSED) ++{ ++ VIR_AUTOFREE(char *) base = NULL; ++ ++ if (virAsprintf(&base, "%s%s", cgroup->unified.mountPoint, ++ cgroup->unified.placement) < 0) { ++ return -1; ++ } ++ ++ if (virFileChownFiles(base, uid, gid) < 0) ++ return -1; ++ ++ if (chown(base, uid, gid) < 0) { ++ virReportSystemError(errno, _("cannot chown '%s' to (%u, %u)"), ++ base, uid, gid); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -515,6 +541,7 @@ virCgroupBackend virCgroupV2Backend = { + .addTask = virCgroupV2AddTask, + .hasEmptyTasks = virCgroupV2HasEmptyTasks, + .bindMount = virCgroupV2BindMount, ++ .setOwner = virCgroupV2SetOwner, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2StealPlacement.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2StealPlacement.patch new file mode 100644 index 0000000..e120096 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2StealPlacement.patch @@ -0,0 +1,54 @@ +From f335c220a4ac822b6b66c8bd4dca0c85aad187f7 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:20 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2StealPlacement +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit f7394dcf010fc4be50b822e290e701430d45325d) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <5e3bd896f2aa16a3637b90d1c8bd3b0676c2acbd.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 815d8fca9b..270a6fb305 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -220,6 +220,17 @@ virCgroupV2ValidatePlacement(virCgroupPtr group, + } + + ++static char * ++virCgroupV2StealPlacement(virCgroupPtr group) ++{ ++ char *ret; ++ ++ VIR_STEAL_PTR(ret, group->unified.placement); ++ ++ return ret; ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -230,6 +241,7 @@ virCgroupBackend virCgroupV2Backend = { + .detectMounts = virCgroupV2DetectMounts, + .detectPlacement = virCgroupV2DetectPlacement, + .validatePlacement = virCgroupV2ValidatePlacement, ++ .stealPlacement = virCgroupV2StealPlacement, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2SupportsCpuBW.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2SupportsCpuBW.patch new file mode 100644 index 0000000..4387129 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2SupportsCpuBW.patch @@ -0,0 +1,58 @@ +From 59084112841259e4ff74bde8ad7ebf32280fdcca Mon Sep 17 00:00:00 2001 +Message-Id: <59084112841259e4ff74bde8ad7ebf32280fdcca@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:49 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2SupportsCpuBW +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 5a4d90ae6af6ea5dd1bb6ae5e3fec7307a5f1257) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index a0a7e55493..55f79af204 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -1441,6 +1441,21 @@ virCgroupV2GetCpuCfsQuota(virCgroupPtr group, + } + + ++static bool ++virCgroupV2SupportsCpuBW(virCgroupPtr cgroup) ++{ ++ VIR_AUTOFREE(char *) path = NULL; ++ ++ if (virCgroupV2PathOfController(cgroup, VIR_CGROUP_CONTROLLER_CPU, ++ "cpu.max", &path) < 0) { ++ virResetLastError(); ++ return false; ++ } ++ ++ return virFileExists(path); ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -1495,6 +1510,7 @@ virCgroupBackend virCgroupV2Backend = { + .getCpuCfsPeriod = virCgroupV2GetCpuCfsPeriod, + .setCpuCfsQuota = virCgroupV2SetCpuCfsQuota, + .getCpuCfsQuota = virCgroupV2GetCpuCfsQuota, ++ .supportsCpuBW = virCgroupV2SupportsCpuBW, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2ValidateMachineGroup.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2ValidateMachineGroup.patch new file mode 100644 index 0000000..976237b --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2ValidateMachineGroup.patch @@ -0,0 +1,94 @@ +From 3928ca076fac13572f14c20f38bcf5fb205d7670 Mon Sep 17 00:00:00 2001 +Message-Id: <3928ca076fac13572f14c20f38bcf5fb205d7670@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:14 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2ValidateMachineGroup +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When reconnecting to a domain we are validating the cgroup name. +In case of cgroup v2 we need to validate only the new format for host +without systemd '{machinename}.libvirt-{drivername}' or scope name +generated by systemd. + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 3a365ef697b8fedb929725c46753481a63ae3de7) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <97d6369bcfc2943c708fd9bfc94f71ab10e00535.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 43 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 43 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 4ab9f2b792..02dc4e4686 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -36,6 +36,7 @@ + #include "virfile.h" + #include "virlog.h" + #include "virstring.h" ++#include "virsystemd.h" + + VIR_LOG_INIT("util.cgroup"); + +@@ -90,10 +91,52 @@ virCgroupV2Available(void) + } + + ++static bool ++virCgroupV2ValidateMachineGroup(virCgroupPtr group, ++ const char *name ATTRIBUTE_UNUSED, ++ const char *drivername, ++ const char *machinename) ++{ ++ VIR_AUTOFREE(char *) partmachinename = NULL; ++ VIR_AUTOFREE(char *) scopename = NULL; ++ char *tmp; ++ ++ if (virAsprintf(&partmachinename, "%s.libvirt-%s", machinename, ++ drivername) < 0) { ++ return false; ++ } ++ ++ if (virCgroupPartitionEscape(&partmachinename) < 0) ++ return false; ++ ++ if (!(scopename = virSystemdMakeScopeName(machinename, drivername, ++ false))) { ++ return false; ++ } ++ ++ if (virCgroupPartitionEscape(&scopename) < 0) ++ return false; ++ ++ if (!(tmp = strrchr(group->unified.placement, '/'))) ++ return false; ++ tmp++; ++ ++ if (STRNEQ(tmp, partmachinename) && ++ STRNEQ(tmp, scopename)) { ++ VIR_DEBUG("Name '%s' for unified does not match '%s' or '%s'", ++ tmp, partmachinename, scopename); ++ return false; ++ } ++ ++ return true; ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + + .available = virCgroupV2Available, ++ .validateMachineGroup = virCgroupV2ValidateMachineGroup, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV2ValidatePlacement.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2ValidatePlacement.patch new file mode 100644 index 0000000..bfbf697 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV2ValidatePlacement.patch @@ -0,0 +1,57 @@ +From 64cc7545de4c32deda12cd1c6088b065c0a09592 Mon Sep 17 00:00:00 2001 +Message-Id: <64cc7545de4c32deda12cd1c6088b065c0a09592@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:19 +0200 +Subject: [PATCH] vircgroup: introduce virCgroupV2ValidatePlacement +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 9aa8226d866f7a274179bfe900d441cbd2f5ae12) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index fb1aa2de0a..815d8fca9b 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -206,6 +206,20 @@ virCgroupV2DetectPlacement(virCgroupPtr group, + } + + ++static int ++virCgroupV2ValidatePlacement(virCgroupPtr group, ++ pid_t pid ATTRIBUTE_UNUSED) ++{ ++ if (!group->unified.placement) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("Could not find placement for v2 controller")); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++ + virCgroupBackend virCgroupV2Backend = { + .type = VIR_CGROUP_BACKEND_TYPE_V2, + +@@ -215,6 +229,7 @@ virCgroupBackend virCgroupV2Backend = { + .copyPlacement = virCgroupV2CopyPlacement, + .detectMounts = virCgroupV2DetectMounts, + .detectPlacement = virCgroupV2DetectPlacement, ++ .validatePlacement = virCgroupV2ValidatePlacement, + }; + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-machinename-will-never-be-NULL.patch b/SOURCES/libvirt-vircgroup-machinename-will-never-be-NULL.patch new file mode 100644 index 0000000..e1ae46f --- /dev/null +++ b/SOURCES/libvirt-vircgroup-machinename-will-never-be-NULL.patch @@ -0,0 +1,87 @@ +From 440629a5a95d167af717a70c8d992e104866229a Mon Sep 17 00:00:00 2001 +Message-Id: <440629a5a95d167af717a70c8d992e104866229a@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:05:59 +0200 +Subject: [PATCH] vircgroup: machinename will never be NULL +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Commit moved machineName +generation before virCgroupNewDetectMachine() is called. + +Signed-off-by: Pavel Hrdina +(cherry picked from commit f9d18f89f7df937b922816aeae0024d8bd6dc72e) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <2e0f6a4d02b3f97f5b9efa74a6553d5ce11d077a.1561993099.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 27 +++++++++++---------------- + 1 file changed, 11 insertions(+), 16 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index a2c971fbf4..5adf9d3c11 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -266,27 +266,22 @@ virCgroupValidateMachineGroup(virCgroupPtr group, + if (virCgroupPartitionEscape(&partname) < 0) + return false; + +- if (machinename && +- (virAsprintf(&partmachinename, "%s.libvirt-%s", +- machinename, drivername) < 0 || +- virCgroupPartitionEscape(&partmachinename) < 0)) ++ if (virAsprintf(&partmachinename, "%s.libvirt-%s", ++ machinename, drivername) < 0 || ++ virCgroupPartitionEscape(&partmachinename) < 0) + return false; + + if (!(scopename_old = virSystemdMakeScopeName(name, drivername, true))) + return false; + +- /* We should keep trying even if this failed */ +- if (!machinename) +- virResetLastError(); +- else if (!(scopename_new = virSystemdMakeScopeName(machinename, +- drivername, false))) ++ if (!(scopename_new = virSystemdMakeScopeName(machinename, ++ drivername, false))) + return false; + + if (virCgroupPartitionEscape(&scopename_old) < 0) + return false; + +- if (scopename_new && +- virCgroupPartitionEscape(&scopename_new) < 0) ++ if (virCgroupPartitionEscape(&scopename_new) < 0) + return false; + + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { +@@ -315,16 +310,16 @@ virCgroupValidateMachineGroup(virCgroupPtr group, + tmp++; + + if (STRNEQ(tmp, name) && +- STRNEQ_NULLABLE(tmp, machinename) && ++ STRNEQ(tmp, machinename) && + STRNEQ(tmp, partname) && +- STRNEQ_NULLABLE(tmp, partmachinename) && ++ STRNEQ(tmp, partmachinename) && + STRNEQ(tmp, scopename_old) && +- STRNEQ_NULLABLE(tmp, scopename_new)) { ++ STRNEQ(tmp, scopename_new)) { + VIR_DEBUG("Name '%s' for controller '%s' does not match " + "'%s', '%s', '%s', '%s' or '%s'", + tmp, virCgroupControllerTypeToString(i), +- name, NULLSTR(machinename), partname, +- scopename_old, NULLSTR(scopename_new)); ++ name, machinename, partname, ++ scopename_old, scopename_new); + return false; + } + } +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-register-cgroup-v2-backend.patch b/SOURCES/libvirt-vircgroup-register-cgroup-v2-backend.patch new file mode 100644 index 0000000..2b650a3 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-register-cgroup-v2-backend.patch @@ -0,0 +1,39 @@ +From 6b4f272c7de58d13d89a7ebb981b43ac53c41198 Mon Sep 17 00:00:00 2001 +Message-Id: <6b4f272c7de58d13d89a7ebb981b43ac53c41198@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:52 +0200 +Subject: [PATCH] vircgroup: register cgroup v2 backend +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +All mandatory callbacks are implemented for cgroup v2 backend so we +can register it now. + +Signed-off-by: Pavel Hrdina +(cherry picked from commit a77f5326919e0d79f01686762ecc8656e4e6adc9) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <9d7990e568c23aa43ccd85011e845c840db97a27.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroupbackend.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/util/vircgroupbackend.c b/src/util/vircgroupbackend.c +index 79fe6cb73d..7ee39ac8ca 100644 +--- a/src/util/vircgroupbackend.c ++++ b/src/util/vircgroupbackend.c +@@ -52,6 +52,7 @@ virCgroupBackendRegister(virCgroupBackendPtr backend) + static void + virCgroupBackendOnceInit(void) + { ++ virCgroupV2Register(); + virCgroupV1Register(); + } + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-remove-VIR_CGROUP_SUPPORTED.patch b/SOURCES/libvirt-vircgroup-remove-VIR_CGROUP_SUPPORTED.patch new file mode 100644 index 0000000..2e27127 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-remove-VIR_CGROUP_SUPPORTED.patch @@ -0,0 +1,72 @@ +From 2a09df456c5cceabdd6d6eee167061a74d7de9ea Mon Sep 17 00:00:00 2001 +Message-Id: <2a09df456c5cceabdd6d6eee167061a74d7de9ea@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:08 +0200 +Subject: [PATCH] vircgroup: remove VIR_CGROUP_SUPPORTED +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +tests/vircgrouptest.c uses #ifdef __linux__ for a long time and no +failure was reported so far so it's safe to assume that __linux__ is +good enough to guard cgroup code. + +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 0df626698865e5158192a9090dfe4f76c2e44fc5) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 11 +++-------- + 1 file changed, 3 insertions(+), 8 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 349c388e0a..f1ecb1dbeb 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -70,11 +70,6 @@ VIR_LOG_INIT("util.cgroup"); + #define CGROUP_NB_TOTAL_CPU_STAT_PARAM 3 + #define CGROUP_NB_PER_CPU_STAT_PARAM 1 + +-#if defined(__linux__) && defined(HAVE_GETMNTENT_R) && \ +- defined(_DIRENT_HAVE_D_TYPE) && defined(_SC_CLK_TCK) +-# define VIR_CGROUP_SUPPORTED +-#endif +- + VIR_ENUM_IMPL(virCgroupController, VIR_CGROUP_CONTROLLER_LAST, + "cpu", "cpuacct", "cpuset", "memory", "devices", + "freezer", "blkio", "net_cls", "perf_event", +@@ -119,7 +114,7 @@ virCgroupGetDevicePermsString(int perms) + } + + +-#ifdef VIR_CGROUP_SUPPORTED ++#ifdef __linux__ + bool + virCgroupAvailable(void) + { +@@ -2643,7 +2638,7 @@ virCgroupControllerAvailable(int controller) + return ret; + } + +-#else /* !VIR_CGROUP_SUPPORTED */ ++#else /* !__linux__ */ + + bool + virCgroupAvailable(void) +@@ -3404,7 +3399,7 @@ virCgroupControllerAvailable(int controller ATTRIBUTE_UNUSED) + { + return false; + } +-#endif /* !VIR_CGROUP_SUPPORTED */ ++#endif /* !__linux__ */ + + + int +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-rename-controllers-to-legacy.patch b/SOURCES/libvirt-vircgroup-rename-controllers-to-legacy.patch new file mode 100644 index 0000000..3b79453 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-rename-controllers-to-legacy.patch @@ -0,0 +1,524 @@ +From da3574e1bcbc4779b516e8bf14f56abf2a19885d Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:07 +0200 +Subject: [PATCH] vircgroup: rename controllers to legacy +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +With the introduction of cgroup v2 there are new names used with +cgroups based on which version is used: + + - legacy: cgroup v1 + - unified: cgroup v2 + - hybrid: cgroup v1 and cgroup v2 + +Let's use 'legacy' instead of 'cgroupv1' or 'controllers' in our code. + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 65ba48d26745450e5079f171052caa7309c99fdf) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroup.c | 6 +- + src/util/vircgrouppriv.h | 2 +- + src/util/vircgroupv1.c | 140 +++++++++++++++++++-------------------- + tests/vircgrouptest.c | 14 ++-- + 4 files changed, 81 insertions(+), 81 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index b159bda1bb..349c388e0a 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -1246,9 +1246,9 @@ virCgroupFree(virCgroupPtr *group) + return; + + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { +- VIR_FREE((*group)->controllers[i].mountPoint); +- VIR_FREE((*group)->controllers[i].linkPoint); +- VIR_FREE((*group)->controllers[i].placement); ++ VIR_FREE((*group)->legacy[i].mountPoint); ++ VIR_FREE((*group)->legacy[i].linkPoint); ++ VIR_FREE((*group)->legacy[i].placement); + } + + VIR_FREE((*group)->path); +diff --git a/src/util/vircgrouppriv.h b/src/util/vircgrouppriv.h +index ee6aeedbb5..c50a25f195 100644 +--- a/src/util/vircgrouppriv.h ++++ b/src/util/vircgrouppriv.h +@@ -50,7 +50,7 @@ struct _virCgroup { + + virCgroupBackendPtr backend; + +- virCgroupV1Controller controllers[VIR_CGROUP_CONTROLLER_LAST]; ++ virCgroupV1Controller legacy[VIR_CGROUP_CONTROLLER_LAST]; + }; + + int virCgroupSetValueStr(virCgroupPtr group, +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 0ba8757348..482615f3c8 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -127,10 +127,10 @@ virCgroupV1ValidateMachineGroup(virCgroupPtr group, + if (i == VIR_CGROUP_CONTROLLER_SYSTEMD) + continue; + +- if (!group->controllers[i].placement) ++ if (!group->legacy[i].placement) + continue; + +- tmp = strrchr(group->controllers[i].placement, '/'); ++ tmp = strrchr(group->legacy[i].placement, '/'); + if (!tmp) + return false; + +@@ -139,7 +139,7 @@ virCgroupV1ValidateMachineGroup(virCgroupPtr group, + i == VIR_CGROUP_CONTROLLER_CPUSET) { + if (STREQ(tmp, "/emulator")) + *tmp = '\0'; +- tmp = strrchr(group->controllers[i].placement, '/'); ++ tmp = strrchr(group->legacy[i].placement, '/'); + if (!tmp) + return false; + } +@@ -171,15 +171,15 @@ virCgroupV1CopyMounts(virCgroupPtr group, + { + size_t i; + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { +- if (!parent->controllers[i].mountPoint) ++ if (!parent->legacy[i].mountPoint) + continue; + +- if (VIR_STRDUP(group->controllers[i].mountPoint, +- parent->controllers[i].mountPoint) < 0) ++ if (VIR_STRDUP(group->legacy[i].mountPoint, ++ parent->legacy[i].mountPoint) < 0) + return -1; + +- if (VIR_STRDUP(group->controllers[i].linkPoint, +- parent->controllers[i].linkPoint) < 0) ++ if (VIR_STRDUP(group->legacy[i].linkPoint, ++ parent->legacy[i].linkPoint) < 0) + return -1; + } + return 0; +@@ -193,14 +193,14 @@ virCgroupV1CopyPlacement(virCgroupPtr group, + { + size_t i; + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { +- if (!group->controllers[i].mountPoint) ++ if (!group->legacy[i].mountPoint) + continue; + + if (i == VIR_CGROUP_CONTROLLER_SYSTEMD) + continue; + + if (path[0] == '/') { +- if (VIR_STRDUP(group->controllers[i].placement, path) < 0) ++ if (VIR_STRDUP(group->legacy[i].placement, path) < 0) + return -1; + } else { + /* +@@ -208,10 +208,10 @@ virCgroupV1CopyPlacement(virCgroupPtr group, + * parent == "/libvirt.service" + path == "" => "/libvirt.service" + * parent == "/libvirt.service" + path == "foo" => "/libvirt.service/foo" + */ +- if (virAsprintf(&group->controllers[i].placement, ++ if (virAsprintf(&group->legacy[i].placement, + "%s%s%s", +- parent->controllers[i].placement, +- (STREQ(parent->controllers[i].placement, "/") || ++ parent->legacy[i].placement, ++ (STREQ(parent->legacy[i].placement, "/") || + STREQ(path, "") ? "" : "/"), + path) < 0) + return -1; +@@ -320,7 +320,7 @@ virCgroupV1DetectMounts(virCgroupPtr group, + * once. We need to save the results of the last one, + * and we need to be careful to release the memory used + * by previous processing. */ +- virCgroupV1ControllerPtr controller = &group->controllers[i]; ++ virCgroupV1ControllerPtr controller = &group->legacy[i]; + + VIR_FREE(controller->mountPoint); + VIR_FREE(controller->linkPoint); +@@ -350,19 +350,19 @@ virCgroupV1DetectPlacement(virCgroupPtr group, + const char *typestr = virCgroupV1ControllerTypeToString(i); + + if (virCgroupV1MountOptsMatchController(controllers, typestr) && +- group->controllers[i].mountPoint != NULL && +- group->controllers[i].placement == NULL) { ++ group->legacy[i].mountPoint != NULL && ++ group->legacy[i].placement == NULL) { + /* + * selfpath == "/" + path="" -> "/" + * selfpath == "/libvirt.service" + path == "" -> "/libvirt.service" + * selfpath == "/libvirt.service" + path == "foo" -> "/libvirt.service/foo" + */ + if (i == VIR_CGROUP_CONTROLLER_SYSTEMD) { +- if (VIR_STRDUP(group->controllers[i].placement, ++ if (VIR_STRDUP(group->legacy[i].placement, + selfpath) < 0) + return -1; + } else { +- if (virAsprintf(&group->controllers[i].placement, ++ if (virAsprintf(&group->legacy[i].placement, + "%s%s%s", selfpath, + (STREQ(selfpath, "/") || + STREQ(path, "") ? "" : "/"), +@@ -383,22 +383,22 @@ virCgroupV1ValidatePlacement(virCgroupPtr group, + size_t i; + + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { +- if (!group->controllers[i].mountPoint) ++ if (!group->legacy[i].mountPoint) + continue; + +- if (!group->controllers[i].placement) { ++ if (!group->legacy[i].placement) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Could not find placement for v1 controller %s at %s"), + virCgroupV1ControllerTypeToString(i), +- group->controllers[i].placement); ++ group->legacy[i].placement); + return -1; + } + + VIR_DEBUG("Detected mount/mapping %zu:%s at %s in %s for pid %lld", + i, + virCgroupV1ControllerTypeToString(i), +- group->controllers[i].mountPoint, +- group->controllers[i].placement, ++ group->legacy[i].mountPoint, ++ group->legacy[i].placement, + (long long) pid); + } + +@@ -411,7 +411,7 @@ virCgroupV1StealPlacement(virCgroupPtr group) + { + char *ret = NULL; + +- VIR_STEAL_PTR(ret, group->controllers[VIR_CGROUP_CONTROLLER_SYSTEMD].placement); ++ VIR_STEAL_PTR(ret, group->legacy[VIR_CGROUP_CONTROLLER_SYSTEMD].placement); + + return ret; + } +@@ -430,7 +430,7 @@ virCgroupV1DetectControllers(virCgroupPtr group, + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { + if (((1 << i) & controllers)) { + /* Remove non-existent controllers */ +- if (!group->controllers[i].mountPoint) { ++ if (!group->legacy[i].mountPoint) { + VIR_DEBUG("Requested controller '%s' not mounted, ignoring", + virCgroupV1ControllerTypeToString(i)); + controllers &= ~(1 << i); +@@ -441,9 +441,9 @@ virCgroupV1DetectControllers(virCgroupPtr group, + VIR_DEBUG("Controller '%s' wanted=%s, mount='%s'", + virCgroupV1ControllerTypeToString(i), + (1 << i) & controllers ? "yes" : "no", +- NULLSTR(group->controllers[i].mountPoint)); ++ NULLSTR(group->legacy[i].mountPoint)); + if (!((1 << i) & controllers) && +- group->controllers[i].mountPoint) { ++ group->legacy[i].mountPoint) { + /* Check whether a request to disable a controller + * clashes with co-mounting of controllers */ + for (j = 0; j < VIR_CGROUP_CONTROLLER_LAST; j++) { +@@ -452,8 +452,8 @@ virCgroupV1DetectControllers(virCgroupPtr group, + if (!((1 << j) & controllers)) + continue; + +- if (STREQ_NULLABLE(group->controllers[i].mountPoint, +- group->controllers[j].mountPoint)) { ++ if (STREQ_NULLABLE(group->legacy[i].mountPoint, ++ group->legacy[j].mountPoint)) { + virReportSystemError(EINVAL, + _("V1 controller '%s' is not wanted, but '%s' is co-mounted"), + virCgroupV1ControllerTypeToString(i), +@@ -461,7 +461,7 @@ virCgroupV1DetectControllers(virCgroupPtr group, + return -1; + } + } +- VIR_FREE(group->controllers[i].mountPoint); ++ VIR_FREE(group->legacy[i].mountPoint); + } + } + } else { +@@ -470,8 +470,8 @@ virCgroupV1DetectControllers(virCgroupPtr group, + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { + VIR_DEBUG("Controller '%s' present=%s", + virCgroupV1ControllerTypeToString(i), +- group->controllers[i].mountPoint ? "yes" : "no"); +- if (group->controllers[i].mountPoint == NULL) ++ group->legacy[i].mountPoint ? "yes" : "no"); ++ if (group->legacy[i].mountPoint == NULL) + continue; + controllers |= (1 << i); + } +@@ -485,7 +485,7 @@ static bool + virCgroupV1HasController(virCgroupPtr group, + int controller) + { +- return group->controllers[controller].mountPoint != NULL; ++ return group->legacy[controller].mountPoint != NULL; + } + + +@@ -499,9 +499,9 @@ virCgroupV1GetAnyController(virCgroupPtr group) + * of '/' to avoid doing bad stuff to the root + * cgroup + */ +- if (group->controllers[i].mountPoint && +- group->controllers[i].placement && +- STRNEQ(group->controllers[i].placement, "/")) { ++ if (group->legacy[i].mountPoint && ++ group->legacy[i].placement && ++ STRNEQ(group->legacy[i].placement, "/")) { + return i; + } + } +@@ -516,14 +516,14 @@ virCgroupV1PathOfController(virCgroupPtr group, + const char *key, + char **path) + { +- if (group->controllers[controller].mountPoint == NULL) { ++ if (group->legacy[controller].mountPoint == NULL) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("v1 controller '%s' is not mounted"), + virCgroupV1ControllerTypeToString(controller)); + return -1; + } + +- if (group->controllers[controller].placement == NULL) { ++ if (group->legacy[controller].placement == NULL) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("v1 controller '%s' is not enabled for group"), + virCgroupV1ControllerTypeToString(controller)); +@@ -531,8 +531,8 @@ virCgroupV1PathOfController(virCgroupPtr group, + } + + if (virAsprintf(path, "%s%s/%s", +- group->controllers[controller].mountPoint, +- group->controllers[controller].placement, ++ group->legacy[controller].mountPoint, ++ group->legacy[controller].placement, + key ? key : "") < 0) + return -1; + +@@ -618,7 +618,7 @@ virCgroupV1MakeGroup(virCgroupPtr parent, + } + + /* Skip over controllers that aren't mounted */ +- if (!group->controllers[i].mountPoint) { ++ if (!group->legacy[i].mountPoint) { + VIR_DEBUG("Skipping unmounted controller %s", + virCgroupV1ControllerTypeToString(i)); + continue; +@@ -639,7 +639,7 @@ virCgroupV1MakeGroup(virCgroupPtr parent, + * treat blkio as unmounted if mkdir fails. */ + if (i == VIR_CGROUP_CONTROLLER_BLKIO) { + VIR_DEBUG("Ignoring mkdir failure with blkio controller. Kernel probably too old"); +- VIR_FREE(group->controllers[i].mountPoint); ++ VIR_FREE(group->legacy[i].mountPoint); + continue; + } else { + virReportSystemError(errno, +@@ -649,7 +649,7 @@ virCgroupV1MakeGroup(virCgroupPtr parent, + } + } + if (i == VIR_CGROUP_CONTROLLER_CPUSET && +- group->controllers[i].mountPoint != NULL && ++ group->legacy[i].mountPoint != NULL && + virCgroupV1CpuSetInherit(parent, group) < 0) { + return -1; + } +@@ -659,7 +659,7 @@ virCgroupV1MakeGroup(virCgroupPtr parent, + */ + if ((flags & VIR_CGROUP_MEM_HIERACHY) && + i == VIR_CGROUP_CONTROLLER_MEMORY && +- group->controllers[i].mountPoint != NULL && ++ group->legacy[i].mountPoint != NULL && + virCgroupV1SetMemoryUseHierarchy(group) < 0) { + return -1; + } +@@ -682,7 +682,7 @@ virCgroupV1Remove(virCgroupPtr group) + VIR_AUTOFREE(char *) grppath = NULL; + + /* Skip over controllers not mounted */ +- if (!group->controllers[i].mountPoint) ++ if (!group->legacy[i].mountPoint) + continue; + + /* We must never rmdir() in systemd's hierarchy */ +@@ -691,7 +691,7 @@ virCgroupV1Remove(virCgroupPtr group) + + /* Don't delete the root group, if we accidentally + ended up in it for some reason */ +- if (STREQ(group->controllers[i].placement, "/")) ++ if (STREQ(group->legacy[i].placement, "/")) + continue; + + if (virCgroupV1PathOfController(group, +@@ -719,7 +719,7 @@ virCgroupV1AddTask(virCgroupPtr group, + + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { + /* Skip over controllers not mounted */ +- if (!group->controllers[i].mountPoint) ++ if (!group->legacy[i].mountPoint) + continue; + + /* We must never add tasks in systemd's hierarchy +@@ -766,17 +766,17 @@ virCgroupV1IdentifyRoot(virCgroupPtr group) + + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { + char *tmp; +- if (!group->controllers[i].mountPoint) ++ if (!group->legacy[i].mountPoint) + continue; +- if (!(tmp = strrchr(group->controllers[i].mountPoint, '/'))) { ++ if (!(tmp = strrchr(group->legacy[i].mountPoint, '/'))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Could not find directory separator in %s"), +- group->controllers[i].mountPoint); ++ group->legacy[i].mountPoint); + return NULL; + } + +- if (VIR_STRNDUP(ret, group->controllers[i].mountPoint, +- tmp - group->controllers[i].mountPoint) < 0) ++ if (VIR_STRNDUP(ret, group->legacy[i].mountPoint, ++ tmp - group->legacy[i].mountPoint) < 0) + return NULL; + return ret; + } +@@ -820,44 +820,44 @@ virCgroupV1BindMount(virCgroupPtr group, + } + + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { +- if (!group->controllers[i].mountPoint) ++ if (!group->legacy[i].mountPoint) + continue; + +- if (!virFileExists(group->controllers[i].mountPoint)) { ++ if (!virFileExists(group->legacy[i].mountPoint)) { + VIR_AUTOFREE(char *) src = NULL; + if (virAsprintf(&src, "%s%s", + oldroot, +- group->controllers[i].mountPoint) < 0) ++ group->legacy[i].mountPoint) < 0) + return -1; + + VIR_DEBUG("Create mount point '%s'", +- group->controllers[i].mountPoint); +- if (virFileMakePath(group->controllers[i].mountPoint) < 0) { ++ group->legacy[i].mountPoint); ++ if (virFileMakePath(group->legacy[i].mountPoint) < 0) { + virReportSystemError(errno, + _("Unable to create directory %s"), +- group->controllers[i].mountPoint); ++ group->legacy[i].mountPoint); + return -1; + } + +- if (mount(src, group->controllers[i].mountPoint, "none", MS_BIND, ++ if (mount(src, group->legacy[i].mountPoint, "none", MS_BIND, + NULL) < 0) { + virReportSystemError(errno, + _("Failed to bind cgroup '%s' on '%s'"), +- src, group->controllers[i].mountPoint); ++ src, group->legacy[i].mountPoint); + return -1; + } + } + +- if (group->controllers[i].linkPoint) { ++ if (group->legacy[i].linkPoint) { + VIR_DEBUG("Link mount point '%s' to '%s'", +- group->controllers[i].mountPoint, +- group->controllers[i].linkPoint); +- if (symlink(group->controllers[i].mountPoint, +- group->controllers[i].linkPoint) < 0) { ++ group->legacy[i].mountPoint, ++ group->legacy[i].linkPoint); ++ if (symlink(group->legacy[i].mountPoint, ++ group->legacy[i].linkPoint) < 0) { + virReportSystemError(errno, + _("Unable to symlink directory %s to %s"), +- group->controllers[i].mountPoint, +- group->controllers[i].linkPoint); ++ group->legacy[i].mountPoint, ++ group->legacy[i].linkPoint); + return -1; + } + } +@@ -885,11 +885,11 @@ virCgroupV1SetOwner(virCgroupPtr cgroup, + if (!((1 << i) & controllers)) + continue; + +- if (!cgroup->controllers[i].mountPoint) ++ if (!cgroup->legacy[i].mountPoint) + continue; + +- if (virAsprintf(&base, "%s%s", cgroup->controllers[i].mountPoint, +- cgroup->controllers[i].placement) < 0) ++ if (virAsprintf(&base, "%s%s", cgroup->legacy[i].mountPoint, ++ cgroup->legacy[i].placement) < 0) + goto cleanup; + + if (virDirOpen(&dh, base) < 0) +diff --git a/tests/vircgrouptest.c b/tests/vircgrouptest.c +index 588a6e824d..c4bf987ca1 100644 +--- a/tests/vircgrouptest.c ++++ b/tests/vircgrouptest.c +@@ -56,25 +56,25 @@ static int validateCgroup(virCgroupPtr cgroup, + + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { + if (STRNEQ_NULLABLE(expectMountPoint[i], +- cgroup->controllers[i].mountPoint)) { ++ cgroup->legacy[i].mountPoint)) { + fprintf(stderr, "Wrong mount '%s', expected '%s' for '%s'\n", +- cgroup->controllers[i].mountPoint, ++ cgroup->legacy[i].mountPoint, + expectMountPoint[i], + virCgroupControllerTypeToString(i)); + return -1; + } + if (STRNEQ_NULLABLE(expectLinkPoint[i], +- cgroup->controllers[i].linkPoint)) { ++ cgroup->legacy[i].linkPoint)) { + fprintf(stderr, "Wrong link '%s', expected '%s' for '%s'\n", +- cgroup->controllers[i].linkPoint, ++ cgroup->legacy[i].linkPoint, + expectLinkPoint[i], + virCgroupControllerTypeToString(i)); + return -1; + } + if (STRNEQ_NULLABLE(expectPlacement[i], +- cgroup->controllers[i].placement)) { ++ cgroup->legacy[i].placement)) { + fprintf(stderr, "Wrong placement '%s', expected '%s' for '%s'\n", +- cgroup->controllers[i].placement, ++ cgroup->legacy[i].placement, + expectPlacement[i], + virCgroupControllerTypeToString(i)); + return -1; +@@ -174,7 +174,7 @@ testCgroupDetectMounts(const void *args) + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { + virBufferAsprintf(&buf, "%-12s %s\n", + virCgroupControllerTypeToString(i), +- NULLSTR(group->controllers[i].mountPoint)); ++ NULLSTR(group->legacy[i].mountPoint)); + } + if (virBufferCheckError(&buf) < 0) + goto cleanup; +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-rename-virCgroupAdd.-Task-to-virCgroupAdd.-Process.patch b/SOURCES/libvirt-vircgroup-rename-virCgroupAdd.-Task-to-virCgroupAdd.-Process.patch new file mode 100644 index 0000000..b682d5d --- /dev/null +++ b/SOURCES/libvirt-vircgroup-rename-virCgroupAdd.-Task-to-virCgroupAdd.-Process.patch @@ -0,0 +1,222 @@ +From d91f1d09bcd6297034d7a9b87c40036aafc2b20c Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:14 +0200 +Subject: [PATCH] vircgroup: rename virCgroupAdd.*Task to virCgroupAdd.*Process +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In cgroup v2 we need to handle processes and threads differently, +following patch will introduce virCgroupAddThread. + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 0772c34685848dabf73574feeb2dd35b2edd9e18) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <75bd43c8342b621a7c01e1431a29bc505e7c155f.1561993099.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/libvirt-lxc.c | 2 +- + src/libvirt_private.syms | 4 ++-- + src/lxc/lxc_controller.c | 4 ++-- + src/qemu/qemu_process.c | 4 ++-- + src/qemu/qemu_tpm.c | 2 +- + src/util/vircgroup.c | 32 ++++++++++++++++---------------- + src/util/vircgroup.h | 4 ++-- + 7 files changed, 26 insertions(+), 26 deletions(-) + +diff --git a/src/libvirt-lxc.c b/src/libvirt-lxc.c +index c9f2146487..9bf0174b95 100644 +--- a/src/libvirt-lxc.c ++++ b/src/libvirt-lxc.c +@@ -306,7 +306,7 @@ int virDomainLxcEnterCGroup(virDomainPtr domain, + if (virCgroupNewDetect(domain->id, -1, &cgroup) < 0) + goto error; + +- if (virCgroupAddTask(cgroup, getpid()) < 0) ++ if (virCgroupAddProcess(cgroup, getpid()) < 0) + goto error; + + virCgroupFree(&cgroup); +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 2ec9d8f4bf..5dd24e2e66 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -1513,8 +1513,8 @@ virBufferVasprintf; + + + # util/vircgroup.h +-virCgroupAddMachineTask; +-virCgroupAddTask; ++virCgroupAddMachineProcess; ++virCgroupAddProcess; + virCgroupAllowAllDevices; + virCgroupAllowDevice; + virCgroupAllowDevicePath; +diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c +index 4e84391bf5..4ead2dc9f0 100644 +--- a/src/lxc/lxc_controller.c ++++ b/src/lxc/lxc_controller.c +@@ -875,12 +875,12 @@ static int virLXCControllerSetupCgroupLimits(virLXCControllerPtr ctrl) + ctrl->nicindexes))) + goto cleanup; + +- if (virCgroupAddMachineTask(ctrl->cgroup, getpid()) < 0) ++ if (virCgroupAddMachineProcess(ctrl->cgroup, getpid()) < 0) + goto cleanup; + + /* Add all qemu-nbd tasks to the cgroup */ + for (i = 0; i < ctrl->nnbdpids; i++) { +- if (virCgroupAddMachineTask(ctrl->cgroup, ctrl->nbdpids[i]) < 0) ++ if (virCgroupAddMachineProcess(ctrl->cgroup, ctrl->nbdpids[i]) < 0) + goto cleanup; + } + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index db14d322f5..c21586fa12 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -2538,7 +2538,7 @@ qemuProcessSetupPid(virDomainObjPtr vm, + goto cleanup; + + /* Move the thread to the sub dir */ +- if (virCgroupAddTask(cgroup, pid) < 0) ++ if (virCgroupAddProcess(cgroup, pid) < 0) + goto cleanup; + + } +@@ -2776,7 +2776,7 @@ qemuProcessStartManagedPRDaemon(virDomainObjPtr vm) + } + + if (priv->cgroup && +- virCgroupAddMachineTask(priv->cgroup, cpid) < 0) ++ virCgroupAddMachineProcess(priv->cgroup, cpid) < 0) + goto cleanup; + + if (qemuSecurityDomainSetPathLabel(driver, vm, socketPath, true) < 0) +diff --git a/src/qemu/qemu_tpm.c b/src/qemu/qemu_tpm.c +index 278b262c48..c64114feac 100644 +--- a/src/qemu/qemu_tpm.c ++++ b/src/qemu/qemu_tpm.c +@@ -905,7 +905,7 @@ qemuExtTPMSetupCgroup(virQEMUDriverPtr driver, + _("Could not get process id of swtpm")); + goto cleanup; + } +- if (virCgroupAddTask(cgroup, pid) < 0) ++ if (virCgroupAddProcess(cgroup, pid) < 0) + goto cleanup; + break; + case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH: +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 2328957818..cf510fb019 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -1183,35 +1183,35 @@ virCgroupAddTaskInternal(virCgroupPtr group, pid_t pid, bool withSystemd) + } + + /** +- * virCgroupAddTask: ++ * virCgroupAddProcess: + * +- * @group: The cgroup to add a task to +- * @pid: The pid of the task to add ++ * @group: The cgroup to add a process to ++ * @pid: The pid of the process to add + * +- * Will add the task to all controllers, except the ++ * Will add the process to all controllers, except the + * systemd unit controller. + * + * Returns: 0 on success, -1 on error + */ + int +-virCgroupAddTask(virCgroupPtr group, pid_t pid) ++virCgroupAddProcess(virCgroupPtr group, pid_t pid) + { + return virCgroupAddTaskInternal(group, pid, false); + } + + /** +- * virCgroupAddMachineTask: ++ * virCgroupAddMachineProcess: + * +- * @group: The cgroup to add a task to +- * @pid: The pid of the task to add ++ * @group: The cgroup to add a process to ++ * @pid: The pid of the process to add + * +- * Will add the task to all controllers, including the ++ * Will add the process to all controllers, including the + * systemd unit controller. + * + * Returns: 0 on success, -1 on error + */ + int +-virCgroupAddMachineTask(virCgroupPtr group, pid_t pid) ++virCgroupAddMachineProcess(virCgroupPtr group, pid_t pid) + { + return virCgroupAddTaskInternal(group, pid, true); + } +@@ -1592,7 +1592,7 @@ virCgroupNewMachineSystemd(const char *name, + goto error; + } + +- if (virCgroupAddTask(*group, pidleader) < 0) ++ if (virCgroupAddProcess(*group, pidleader) < 0) + goto error; + + return 0; +@@ -1648,7 +1648,7 @@ virCgroupNewMachineManual(const char *name, + group) < 0) + goto cleanup; + +- if (virCgroupAddTask(*group, pidleader) < 0) { ++ if (virCgroupAddProcess(*group, pidleader) < 0) { + virErrorPtr saved = virSaveLastError(); + virCgroupRemove(*group); + virCgroupFree(group); +@@ -4198,8 +4198,8 @@ virCgroupPathOfController(virCgroupPtr group ATTRIBUTE_UNUSED, + + + int +-virCgroupAddTask(virCgroupPtr group ATTRIBUTE_UNUSED, +- pid_t pid ATTRIBUTE_UNUSED) ++virCgroupAddProcess(virCgroupPtr group ATTRIBUTE_UNUSED, ++ pid_t pid ATTRIBUTE_UNUSED) + { + virReportSystemError(ENXIO, "%s", + _("Control groups not supported on this platform")); +@@ -4208,8 +4208,8 @@ virCgroupAddTask(virCgroupPtr group ATTRIBUTE_UNUSED, + + + int +-virCgroupAddMachineTask(virCgroupPtr group ATTRIBUTE_UNUSED, +- pid_t pid ATTRIBUTE_UNUSED) ++virCgroupAddMachineProcess(virCgroupPtr group ATTRIBUTE_UNUSED, ++ pid_t pid ATTRIBUTE_UNUSED) + { + virReportSystemError(ENXIO, "%s", + _("Control groups not supported on this platform")); +diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h +index ee3b7c7222..bbd4c2ed57 100644 +--- a/src/util/vircgroup.h ++++ b/src/util/vircgroup.h +@@ -118,8 +118,8 @@ int virCgroupPathOfController(virCgroupPtr group, + const char *key, + char **path); + +-int virCgroupAddTask(virCgroupPtr group, pid_t pid); +-int virCgroupAddMachineTask(virCgroupPtr group, pid_t pid); ++int virCgroupAddProcess(virCgroupPtr group, pid_t pid); ++int virCgroupAddMachineProcess(virCgroupPtr group, pid_t pid); + + int virCgroupSetBlkioWeight(virCgroupPtr group, unsigned int weight); + int virCgroupGetBlkioWeight(virCgroupPtr group, unsigned int *weight); +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroup-rename-virCgroupController-into-virCgroupV1Controller.patch b/SOURCES/libvirt-vircgroup-rename-virCgroupController-into-virCgroupV1Controller.patch new file mode 100644 index 0000000..a6ed638 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-rename-virCgroupController-into-virCgroupV1Controller.patch @@ -0,0 +1,82 @@ +From 648fecd5f67da4d118632251365e5dd93d987d3c Mon Sep 17 00:00:00 2001 +Message-Id: <648fecd5f67da4d118632251365e5dd93d987d3c@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:06 +0200 +Subject: [PATCH] vircgroup: rename virCgroupController into + virCgroupV1Controller +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit bebf732cfae2c1786cb92e7ba3217c551543e3a9) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <4f23fb7e55cf80372867783a87c95cac02653a94.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgrouppriv.h | 8 ++++---- + src/util/vircgroupv1.c | 4 ++-- + 2 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/util/vircgrouppriv.h b/src/util/vircgrouppriv.h +index 38c911e8ed..ee6aeedbb5 100644 +--- a/src/util/vircgrouppriv.h ++++ b/src/util/vircgrouppriv.h +@@ -32,7 +32,7 @@ + # include "vircgroup.h" + # include "vircgroupbackend.h" + +-struct _virCgroupController { ++struct _virCgroupV1Controller { + int type; + char *mountPoint; + /* If mountPoint holds several controllers co-mounted, +@@ -42,15 +42,15 @@ struct _virCgroupController { + char *linkPoint; + char *placement; + }; +-typedef struct _virCgroupController virCgroupController; +-typedef virCgroupController *virCgroupControllerPtr; ++typedef struct _virCgroupV1Controller virCgroupV1Controller; ++typedef virCgroupV1Controller *virCgroupV1ControllerPtr; + + struct _virCgroup { + char *path; + + virCgroupBackendPtr backend; + +- virCgroupController controllers[VIR_CGROUP_CONTROLLER_LAST]; ++ virCgroupV1Controller controllers[VIR_CGROUP_CONTROLLER_LAST]; + }; + + int virCgroupSetValueStr(virCgroupPtr group, +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 54e7d6ea9a..0ba8757348 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -225,7 +225,7 @@ virCgroupV1CopyPlacement(virCgroupPtr group, + static int + virCgroupV1ResolveMountLink(const char *mntDir, + const char *typeStr, +- virCgroupControllerPtr controller) ++ virCgroupV1ControllerPtr controller) + { + VIR_AUTOFREE(char *) linkSrc = NULL; + VIR_AUTOFREE(char *) tmp = NULL; +@@ -320,7 +320,7 @@ virCgroupV1DetectMounts(virCgroupPtr group, + * once. We need to save the results of the last one, + * and we need to be careful to release the memory used + * by previous processing. */ +- virCgroupControllerPtr controller = &group->controllers[i]; ++ virCgroupV1ControllerPtr controller = &group->controllers[i]; + + VIR_FREE(controller->mountPoint); + VIR_FREE(controller->linkPoint); +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroupmock-add-support-to-test-cgroup-v2.patch b/SOURCES/libvirt-vircgroupmock-add-support-to-test-cgroup-v2.patch new file mode 100644 index 0000000..55ae3fc --- /dev/null +++ b/SOURCES/libvirt-vircgroupmock-add-support-to-test-cgroup-v2.patch @@ -0,0 +1,253 @@ +From 5b4d8244ee6361111903a956843b03739f006b4a Mon Sep 17 00:00:00 2001 +Message-Id: <5b4d8244ee6361111903a956843b03739f006b4a@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:55 +0200 +Subject: [PATCH] vircgroupmock: add support to test cgroup v2 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We need to create the cgroup v2 sysfs the same way as we do for +cgroup v1. + +This introduces new VIR_CGROUP_MOCK_MODE env variable which will +configure which cgroup mode each test requires. There are three +different modes: + + - legacy: only cgroup v1 is available and it's the default mode + - hybrid: both cgroup v1 and cgroup v2 are available and have some + controllers + - unified: only cgroup v2 is available + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 61ff6021d842a3baf2f6cbc3f37dd272f6c86563) + +Conflicts: + src/util/vircgroupv2.c: missing commit c0abcca417 + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <26937fa61f83f373ff46d4a7d6cc8cb2dfd3c66d.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + tests/vircgroupmock.c | 162 ++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 147 insertions(+), 15 deletions(-) + +diff --git a/tests/vircgroupmock.c b/tests/vircgroupmock.c +index fcc00a7a7b..2041b1e970 100644 +--- a/tests/vircgroupmock.c ++++ b/tests/vircgroupmock.c +@@ -36,6 +36,7 @@ + + # include + # include "testutilslxc.h" ++# include "viralloc.h" + # include "virstring.h" + # include "virfile.h" + +@@ -107,7 +108,8 @@ static int make_file(const char *path, + return ret; + } + +-static int make_controller(const char *path, mode_t mode) ++ ++static int make_controller_v1(const char *path, mode_t mode) + { + int ret = -1; + const char *controller; +@@ -233,11 +235,86 @@ static int make_controller(const char *path, mode_t mode) + goto cleanup; + } + ++# undef MAKE_FILE ++ + ret = 0; + cleanup: + return ret; + } + ++ ++static int make_controller_v2(const char *path, mode_t mode) ++{ ++ if (!STRPREFIX(path, fakesysfscgroupdir)) { ++ errno = EINVAL; ++ return -1; ++ } ++ ++ if (real_mkdir(path, mode) < 0 && errno != EEXIST) ++ return -1; ++ ++# define MAKE_FILE(name, value) \ ++ do { \ ++ if (make_file(path, name, value) < 0) \ ++ return -1; \ ++ } while (0) ++ ++ MAKE_FILE("cgroup.controllers", "cpu io memory\n"); ++ MAKE_FILE("cgroup.subtree_control", ""); ++ MAKE_FILE("cgroup.type", "domain\n"); ++ MAKE_FILE("cpu.max", "max 100000\n"); ++ MAKE_FILE("cpu.stat", ++ "usage_usec 0\n" ++ "user_usec 0\n" ++ "system_usec 0\n" ++ "nr_periods 0\n" ++ "nr_throttled 0\n" ++ "throttled_usec 0\n"); ++ MAKE_FILE("cpu.weight", "100\n"); ++ MAKE_FILE("memory.current", "1455321088\n"); ++ MAKE_FILE("memory.high", "max\n"); ++ MAKE_FILE("memory.max", "max\n"); ++ MAKE_FILE("memory.stat", ++ "anon 0\n" ++ "file 0\n" ++ "kernel_stack 0\n" ++ "slab 0\n" ++ "sock 0\n" ++ "shmem 0\n" ++ "file_mapped 0\n" ++ "file_dirty 0\n" ++ "file_writeback 0\n" ++ "inactive_anon 0\n" ++ "active_anon 0\n" ++ "inactive_file 0\n" ++ "active_file 0\n" ++ "unevictable 0\n" ++ "slab_reclaimable 0\n" ++ "slab_unreclaimable 0\n" ++ "pgfault 0\n" ++ "pgmajfault 0\n" ++ "pgrefill 0\n" ++ "pgscan 0\n" ++ "pgsteal 0\n" ++ "pgactivate 0\n" ++ "pgdeactivate 0\n" ++ "pglazyfree 0\n" ++ "pglazyfreed 0\n" ++ "workingset_refault 0\n" ++ "workingset_activate 0\n" ++ "workingset_nodereclaim 0\n"); ++ MAKE_FILE("memory.swap.current", "0\n"); ++ MAKE_FILE("memory.swap.max", "max\n"); ++ MAKE_FILE("io.stat", "8:0 rbytes=26828800 wbytes=77062144 rios=2256 wios=7849 dbytes=0 dios=0\n"); ++ MAKE_FILE("io.max", ""); ++ MAKE_FILE("io.weight", "default 100\n"); ++ ++# undef MAKE_FILE ++ ++ return 0; ++} ++ ++ + static void init_syms(void) + { + if (real_fopen) +@@ -251,16 +328,64 @@ static void init_syms(void) + VIR_MOCK_REAL_INIT(open); + } + ++ ++static int make_controller(const char *path, mode_t mode) ++{ ++ const char *mock; ++ bool unified = false; ++ bool hybrid = false; ++ ++ mock = getenv("VIR_CGROUP_MOCK_MODE"); ++ if (mock) { ++ if (STREQ(mock, "unified")) { ++ unified = true; ++ } else if (STREQ(mock, "hybrid")) { ++ hybrid = true; ++ } else { ++ fprintf(stderr, "invalid mode '%s'\n", mock); ++ abort(); ++ } ++ } ++ ++ if (unified || (hybrid && strstr(path, "unified"))) { ++ return make_controller_v2(path, mode); ++ } else { ++ return make_controller_v1(path, mode); ++ } ++} ++ ++ + static void init_sysfs(void) + { +- if (fakerootdir && fakesysfscgroupdir) +- return; ++ const char *mock; ++ char *newfakerootdir; ++ bool unified = false; ++ bool hybrid = false; + +- if (!(fakerootdir = getenv("LIBVIRT_FAKE_ROOT_DIR"))) { ++ if (!(newfakerootdir = getenv("LIBVIRT_FAKE_ROOT_DIR"))) { + fprintf(stderr, "Missing LIBVIRT_FAKE_ROOT_DIR env variable\n"); + abort(); + } + ++ if (fakerootdir && STREQ(fakerootdir, newfakerootdir)) ++ return; ++ ++ fakerootdir = newfakerootdir; ++ ++ mock = getenv("VIR_CGROUP_MOCK_MODE"); ++ if (mock) { ++ if (STREQ(mock, "unified")) { ++ unified = true; ++ } else if (STREQ(mock, "hybrid")) { ++ hybrid = true; ++ } else { ++ fprintf(stderr, "invalid mode '%s'\n", mock); ++ abort(); ++ } ++ } ++ ++ VIR_FREE(fakesysfscgroupdir); ++ + if (virAsprintfQuiet(&fakesysfscgroupdir, "%s%s", + fakerootdir, SYSFS_CGROUP_PREFIX) < 0) + abort(); +@@ -283,18 +408,25 @@ static void init_sysfs(void) + free(path); \ + } while (0) + +- MAKE_CONTROLLER("cpu"); +- MAKE_CONTROLLER("cpuacct"); +- MAKE_CONTROLLER("cpu,cpuacct"); +- MAKE_CONTROLLER("cpu,cpuacct/system"); +- MAKE_CONTROLLER("cpuset"); +- MAKE_CONTROLLER("blkio"); +- MAKE_CONTROLLER("memory"); +- MAKE_CONTROLLER("freezer"); ++ if (unified) { ++ MAKE_CONTROLLER(""); ++ } else if (hybrid) { ++ MAKE_CONTROLLER("unified"); ++ MAKE_CONTROLLER("cpuset"); ++ MAKE_CONTROLLER("freezer"); ++ } else { ++ MAKE_CONTROLLER("cpu"); ++ MAKE_CONTROLLER("cpuacct"); ++ MAKE_CONTROLLER("cpu,cpuacct"); ++ MAKE_CONTROLLER("cpuset"); ++ MAKE_CONTROLLER("blkio"); ++ MAKE_CONTROLLER("memory"); ++ MAKE_CONTROLLER("freezer"); + +- if (make_file(fakesysfscgroupdir, +- SYSFS_CPU_PRESENT_MOCKED, "8-23,48-159\n") < 0) +- abort(); ++ if (make_file(fakesysfscgroupdir, ++ SYSFS_CPU_PRESENT_MOCKED, "8-23,48-159\n") < 0) ++ abort(); ++ } + } + + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroupmock-change-cgroup-prefix.patch b/SOURCES/libvirt-vircgroupmock-change-cgroup-prefix.patch new file mode 100644 index 0000000..82784b1 --- /dev/null +++ b/SOURCES/libvirt-vircgroupmock-change-cgroup-prefix.patch @@ -0,0 +1,104 @@ +From bbb7b7a4cb906bdeaf46ab664ce67a0a27b9ef5d Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:54 +0200 +Subject: [PATCH] vircgroupmock: change cgroup prefix +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Remove the trailing '/' from prefix. This change is required in order +to introduce tests for unified cgroups. They are usually mounted in +'/sys/fs/cgroup'. + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 9bd1979e37ca703f8e29c2dfca83a9cd04af2982) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + tests/vircgroupmock.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/tests/vircgroupmock.c b/tests/vircgroupmock.c +index 3afe2fe192..fcc00a7a7b 100644 +--- a/tests/vircgroupmock.c ++++ b/tests/vircgroupmock.c +@@ -58,7 +58,7 @@ const char *fakedevicedir0 = FAKEDEVDIR0; + const char *fakedevicedir1 = FAKEDEVDIR1; + + +-# define SYSFS_CGROUP_PREFIX "/not/really/sys/fs/cgroup/" ++# define SYSFS_CGROUP_PREFIX "/not/really/sys/fs/cgroup" + # define SYSFS_CPU_PRESENT "/sys/devices/system/cpu/present" + # define SYSFS_CPU_PRESENT_MOCKED "devices_system_cpu_present" + +@@ -356,7 +356,7 @@ int access(const char *path, int mode) + if (STRPREFIX(path, SYSFS_CGROUP_PREFIX)) { + init_sysfs(); + char *newpath; +- if (asprintf(&newpath, "%s/%s", ++ if (asprintf(&newpath, "%s%s", + fakesysfscgroupdir, + path + strlen(SYSFS_CGROUP_PREFIX)) < 0) { + errno = ENOMEM; +@@ -388,7 +388,7 @@ int __lxstat(int ver, const char *path, struct stat *sb) + if (STRPREFIX(path, SYSFS_CGROUP_PREFIX)) { + init_sysfs(); + char *newpath; +- if (asprintf(&newpath, "%s/%s", ++ if (asprintf(&newpath, "%s%s", + fakesysfscgroupdir, + path + strlen(SYSFS_CGROUP_PREFIX)) < 0) { + errno = ENOMEM; +@@ -419,7 +419,7 @@ int lstat(const char *path, struct stat *sb) + if (STRPREFIX(path, SYSFS_CGROUP_PREFIX)) { + init_sysfs(); + char *newpath; +- if (asprintf(&newpath, "%s/%s", ++ if (asprintf(&newpath, "%s%s", + fakesysfscgroupdir, + path + strlen(SYSFS_CGROUP_PREFIX)) < 0) { + errno = ENOMEM; +@@ -450,7 +450,7 @@ int __xstat(int ver, const char *path, struct stat *sb) + if (STRPREFIX(path, SYSFS_CGROUP_PREFIX)) { + init_sysfs(); + char *newpath; +- if (asprintf(&newpath, "%s/%s", ++ if (asprintf(&newpath, "%s%s", + fakesysfscgroupdir, + path + strlen(SYSFS_CGROUP_PREFIX)) < 0) { + errno = ENOMEM; +@@ -489,7 +489,7 @@ int stat(const char *path, struct stat *sb) + } + } else if (STRPREFIX(path, SYSFS_CGROUP_PREFIX)) { + init_sysfs(); +- if (asprintf(&newpath, "%s/%s", ++ if (asprintf(&newpath, "%s%s", + fakesysfscgroupdir, + path + strlen(SYSFS_CGROUP_PREFIX)) < 0) { + errno = ENOMEM; +@@ -521,7 +521,7 @@ int mkdir(const char *path, mode_t mode) + if (STRPREFIX(path, SYSFS_CGROUP_PREFIX)) { + init_sysfs(); + char *newpath; +- if (asprintf(&newpath, "%s/%s", ++ if (asprintf(&newpath, "%s%s", + fakesysfscgroupdir, + path + strlen(SYSFS_CGROUP_PREFIX)) < 0) { + errno = ENOMEM; +@@ -554,7 +554,7 @@ int open(const char *path, int flags, ...) + + if (STRPREFIX(path, SYSFS_CGROUP_PREFIX)) { + init_sysfs(); +- if (asprintf(&newpath, "%s/%s", ++ if (asprintf(&newpath, "%s%s", + fakesysfscgroupdir, + path + strlen(SYSFS_CGROUP_PREFIX)) < 0) { + errno = ENOMEM; +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroupmock-cleanup-unused-cgroup-files.patch b/SOURCES/libvirt-vircgroupmock-cleanup-unused-cgroup-files.patch new file mode 100644 index 0000000..8a2d326 --- /dev/null +++ b/SOURCES/libvirt-vircgroupmock-cleanup-unused-cgroup-files.patch @@ -0,0 +1,150 @@ +From 0542ea82913e75374a5efb0c7dde147036d32d20 Mon Sep 17 00:00:00 2001 +Message-Id: <0542ea82913e75374a5efb0c7dde147036d32d20@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:17 +0200 +Subject: [PATCH] vircgroupmock: cleanup unused cgroup files +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit f9085cf702f5fe5bf786045b9cc95365ab4e628b) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + tests/vircgroupmock.c | 73 ------------------------------------------- + 1 file changed, 73 deletions(-) + +diff --git a/tests/vircgroupmock.c b/tests/vircgroupmock.c +index bae8304f6c..cd5422dcba 100644 +--- a/tests/vircgroupmock.c ++++ b/tests/vircgroupmock.c +@@ -214,13 +214,7 @@ static int make_controller(const char *path, mode_t mode) + if (STRPREFIX(controller, "cpu,cpuacct")) { + MAKE_FILE("cpu.cfs_period_us", "100000\n"); + MAKE_FILE("cpu.cfs_quota_us", "-1\n"); +- MAKE_FILE("cpu.rt_period_us", "1000000\n"); +- MAKE_FILE("cpu.rt_runtime_us", "950000\n"); + MAKE_FILE("cpu.shares", "1024\n"); +- MAKE_FILE("cpu.stat", +- "nr_periods 0\n" +- "nr_throttled 0\n" +- "throttled_time 0\n"); + MAKE_FILE("cpuacct.stat", + "user 216687025\n" + "system 43421396\n"); +@@ -235,46 +229,19 @@ static int make_controller(const char *path, mode_t mode) + "709566900 0 0 0 0 0 0 0 444777342 0 0 0 0 0 0 0 " + "5683512916 0 0 0 0 0 0 0 635751356 0 0 0 0 0 0 0\n"); + } else if (STRPREFIX(controller, "cpuset")) { +- MAKE_FILE("cpuset.cpu_exclusive", "1\n"); + if (STREQ(controller, "cpuset")) + MAKE_FILE("cpuset.cpus", "0-1"); + else + MAKE_FILE("cpuset.cpus", ""); /* Values don't inherit */ +- MAKE_FILE("cpuset.mem_exclusive", "1\n"); +- MAKE_FILE("cpuset.mem_hardwall", "0\n"); + MAKE_FILE("cpuset.memory_migrate", "0\n"); +- MAKE_FILE("cpuset.memory_pressure", "0\n"); +- MAKE_FILE("cpuset.memory_pressure_enabled", "0\n"); +- MAKE_FILE("cpuset.memory_spread_page", "0\n"); +- MAKE_FILE("cpuset.memory_spread_slab", "0\n"); + if (STREQ(controller, "cpuset")) + MAKE_FILE("cpuset.mems", "0"); + else + MAKE_FILE("cpuset.mems", ""); /* Values don't inherit */ +- MAKE_FILE("cpuset.sched_load_balance", "1\n"); +- MAKE_FILE("cpuset.sched_relax_domain_level", "-1\n"); + } else if (STRPREFIX(controller, "memory")) { +- MAKE_FILE("memory.failcnt", "0\n"); +- MAKE_FILE("memory.force_empty", ""); /* Write only */ +- MAKE_FILE("memory.kmem.tcp.failcnt", "0\n"); +- MAKE_FILE("memory.kmem.tcp.limit_in_bytes", "9223372036854775807\n"); +- MAKE_FILE("memory.kmem.tcp.max_usage_in_bytes", "0\n"); +- MAKE_FILE("memory.kmem.tcp.usage_in_bytes", "16384\n"); + MAKE_FILE("memory.limit_in_bytes", "9223372036854775807\n"); +- MAKE_FILE("memory.max_usage_in_bytes", "0\n"); +- MAKE_FILE("memory.memsw.failcnt", ""); /* Not supported */ + MAKE_FILE("memory.memsw.limit_in_bytes", ""); /* Not supported */ +- MAKE_FILE("memory.memsw.max_usage_in_bytes", ""); /* Not supported */ + MAKE_FILE("memory.memsw.usage_in_bytes", ""); /* Not supported */ +- MAKE_FILE("memory.move_charge_at_immigrate", "0\n"); +- MAKE_FILE("memory.numa_stat", +- "total=367664 N0=367664\n" +- "file=314764 N0=314764\n" +- "anon=51999 N0=51999\n" +- "unevictable=901 N0=901\n"); +- MAKE_FILE("memory.oom_control", +- "oom_kill_disable 0\n" +- "under_oom 0\n"); + MAKE_FILE("memory.soft_limit_in_bytes", "9223372036854775807\n"); + MAKE_FILE("memory.stat", + "cache 1336619008\n" +@@ -306,50 +273,11 @@ static int make_controller(const char *path, mode_t mode) + "recent_rotated_file 2547948\n" + "recent_scanned_anon 113796164\n" + "recent_scanned_file 8199863\n"); +- MAKE_FILE("memory.swappiness", "60\n"); + MAKE_FILE("memory.usage_in_bytes", "1455321088\n"); + MAKE_FILE("memory.use_hierarchy", "0\n"); + } else if (STRPREFIX(controller, "freezer")) { + MAKE_FILE("freezer.state", "THAWED"); + } else if (STRPREFIX(controller, "blkio")) { +- MAKE_FILE("blkio.io_merged", +- "8:0 Read 1100949\n" +- "8:0 Write 2248076\n" +- "8:0 Sync 63063\n" +- "8:0 Async 3285962\n" +- "8:0 Total 3349025\n"); +- MAKE_FILE("blkio.io_queued", +- "8:0 Read 0\n" +- "8:0 Write 0\n" +- "8:0 Sync 0\n" +- "8:0 Async 0\n" +- "8:0 Total 0\n"); +- MAKE_FILE("blkio.io_service_bytes", +- "8:0 Read 59542078464\n" +- "8:0 Write 397369182208\n" +- "8:0 Sync 234080922624\n" +- "8:0 Async 222830338048\n" +- "8:0 Total 456911260672\n"); +- MAKE_FILE("blkio.io_serviced", +- "8:0 Read 3402504\n" +- "8:0 Write 14966516\n" +- "8:0 Sync 12064031\n" +- "8:0 Async 6304989\n" +- "8:0 Total 18369020\n"); +- MAKE_FILE("blkio.io_service_time", +- "8:0 Read 10747537542349\n" +- "8:0 Write 9200028590575\n" +- "8:0 Sync 6449319855381\n" +- "8:0 Async 13498246277543\n" +- "8:0 Total 19947566132924\n"); +- MAKE_FILE("blkio.io_wait_time", +- "8:0 Read 14687514824889\n" +- "8:0 Write 357748452187691\n" +- "8:0 Sync 55296974349413\n" +- "8:0 Async 317138992663167\n" +- "8:0 Total 372435967012580\n"); +- MAKE_FILE("blkio.reset_stats", ""); /* Write only */ +- MAKE_FILE("blkio.sectors", "8:0 892404806\n"); + MAKE_FILE("blkio.throttle.io_service_bytes", + "8:0 Read 59542107136\n" + "8:0 Write 411440480256\n" +@@ -376,7 +304,6 @@ static int make_controller(const char *path, mode_t mode) + MAKE_FILE("blkio.throttle.read_iops_device", ""); + MAKE_FILE("blkio.throttle.write_bps_device", ""); + MAKE_FILE("blkio.throttle.write_iops_device", ""); +- MAKE_FILE("blkio.time", "8:0 61019089\n"); + MAKE_FILE("blkio.weight", "1000\n"); + MAKE_FILE("blkio.weight_device", ""); + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroupmock-rewrite-cgroup-fopen-mocking.patch b/SOURCES/libvirt-vircgroupmock-rewrite-cgroup-fopen-mocking.patch new file mode 100644 index 0000000..2abb06c --- /dev/null +++ b/SOURCES/libvirt-vircgroupmock-rewrite-cgroup-fopen-mocking.patch @@ -0,0 +1,390 @@ +From d323cd99b256b368c37f0a36eef8b3b2d6213346 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:18 +0200 +Subject: [PATCH] vircgroupmock: rewrite cgroup fopen mocking +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Move all the cgroup data into separate files out of vircgroupmock.c +and rework the fopen function to load data from files. This will +make it easier to add more test cases. + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 5cf1b25708328ad4006572801d0829548418cfe7) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + tests/vircgroupdata/all-in-one.cgroups | 7 ++ + tests/vircgroupdata/all-in-one.mounts | 2 +- + tests/vircgroupdata/all-in-one.parsed | 12 +- + tests/vircgroupdata/all-in-one.self.cgroup | 1 + + tests/vircgroupdata/logind.cgroups | 10 ++ + tests/vircgroupdata/logind.mounts | 2 + + tests/vircgroupdata/logind.self.cgroup | 1 + + tests/vircgroupdata/systemd.cgroups | 8 ++ + tests/vircgroupdata/systemd.mounts | 11 ++ + tests/vircgroupdata/systemd.self.cgroup | 6 + + tests/vircgroupmock.c | 136 +++------------------ + tests/vircgrouptest.c | 10 +- + 12 files changed, 79 insertions(+), 127 deletions(-) + create mode 100644 tests/vircgroupdata/all-in-one.cgroups + create mode 100644 tests/vircgroupdata/all-in-one.self.cgroup + create mode 100644 tests/vircgroupdata/logind.cgroups + create mode 100644 tests/vircgroupdata/logind.mounts + create mode 100644 tests/vircgroupdata/logind.self.cgroup + create mode 100644 tests/vircgroupdata/systemd.cgroups + create mode 100644 tests/vircgroupdata/systemd.mounts + create mode 100644 tests/vircgroupdata/systemd.self.cgroup + +diff --git a/tests/vircgroupdata/all-in-one.cgroups b/tests/vircgroupdata/all-in-one.cgroups +new file mode 100644 +index 0000000000..7208e5a0b6 +--- /dev/null ++++ b/tests/vircgroupdata/all-in-one.cgroups +@@ -0,0 +1,7 @@ ++#subsys_name hierarchy num_cgroups enabled ++cpuset 6 1 1 ++cpu 6 1 1 ++cpuacct 6 1 1 ++memory 6 1 1 ++devices 6 1 1 ++blkio 6 1 1 +diff --git a/tests/vircgroupdata/all-in-one.mounts b/tests/vircgroupdata/all-in-one.mounts +index 14093b961c..76c579ff69 100644 +--- a/tests/vircgroupdata/all-in-one.mounts ++++ b/tests/vircgroupdata/all-in-one.mounts +@@ -4,4 +4,4 @@ proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0 + udev /dev devtmpfs rw,relatime,size=16458560k,nr_inodes=4114640,mode=755 0 0 + devpts /dev/pts devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 0 0 + nfsd /proc/fs/nfsd nfsd rw,relatime 0 0 +-cgroup /sys/fs/cgroup cgroup rw,relatime,blkio,devices,memory,cpuacct,cpu,cpuset 0 0 ++cgroup /not/really/sys/fs/cgroup cgroup rw,relatime,blkio,devices,memory,cpuacct,cpu,cpuset 0 0 +diff --git a/tests/vircgroupdata/all-in-one.parsed b/tests/vircgroupdata/all-in-one.parsed +index 2701778fea..d703d08fb9 100644 +--- a/tests/vircgroupdata/all-in-one.parsed ++++ b/tests/vircgroupdata/all-in-one.parsed +@@ -1,10 +1,10 @@ +-cpu /sys/fs/cgroup +-cpuacct /sys/fs/cgroup +-cpuset /sys/fs/cgroup +-memory /sys/fs/cgroup +-devices /sys/fs/cgroup ++cpu /not/really/sys/fs/cgroup ++cpuacct /not/really/sys/fs/cgroup ++cpuset /not/really/sys/fs/cgroup ++memory /not/really/sys/fs/cgroup ++devices /not/really/sys/fs/cgroup + freezer +-blkio /sys/fs/cgroup ++blkio /not/really/sys/fs/cgroup + net_cls + perf_event + name=systemd +diff --git a/tests/vircgroupdata/all-in-one.self.cgroup b/tests/vircgroupdata/all-in-one.self.cgroup +new file mode 100644 +index 0000000000..cf237502e9 +--- /dev/null ++++ b/tests/vircgroupdata/all-in-one.self.cgroup +@@ -0,0 +1 @@ ++6:blkio,devices,memory,cpuacct,cpu,cpuset:/ +diff --git a/tests/vircgroupdata/logind.cgroups b/tests/vircgroupdata/logind.cgroups +new file mode 100644 +index 0000000000..9d46f130e0 +--- /dev/null ++++ b/tests/vircgroupdata/logind.cgroups +@@ -0,0 +1,10 @@ ++#subsys_name hierarchy num_cgroups enabled ++cpuset 0 1 1 ++cpu 0 1 1 ++cpuacct 0 1 1 ++memory 0 1 0 ++devices 0 1 1 ++freezer 0 1 1 ++net_cls 0 1 1 ++blkio 0 1 1 ++perf_event 0 1 1 +diff --git a/tests/vircgroupdata/logind.mounts b/tests/vircgroupdata/logind.mounts +new file mode 100644 +index 0000000000..3ab908aee9 +--- /dev/null ++++ b/tests/vircgroupdata/logind.mounts +@@ -0,0 +1,2 @@ ++none /not/really/sys/fs/cgroup tmpfs rw,rootcontext=system_u:object_r:sysfs_t:s0,seclabel,relatime,size=4k,mode=755 0 0 ++systemd /not/really/sys/fs/cgroup/systemd cgroup rw,nosuid,nodev,noexec,relatime,name=systemd 0 0 +diff --git a/tests/vircgroupdata/logind.self.cgroup b/tests/vircgroupdata/logind.self.cgroup +new file mode 100644 +index 0000000000..31e0cfe8eb +--- /dev/null ++++ b/tests/vircgroupdata/logind.self.cgroup +@@ -0,0 +1 @@ ++0:name=systemd:/ +diff --git a/tests/vircgroupdata/systemd.cgroups b/tests/vircgroupdata/systemd.cgroups +new file mode 100644 +index 0000000000..d32dfab222 +--- /dev/null ++++ b/tests/vircgroupdata/systemd.cgroups +@@ -0,0 +1,8 @@ ++#subsys_name hierarchy num_cgroups enabled ++cpuset 2 4 1 ++cpu 3 48 1 ++cpuacct 3 48 1 ++memory 4 4 1 ++devices 5 4 1 ++freezer 6 4 1 ++blkio 8 4 1 +diff --git a/tests/vircgroupdata/systemd.mounts b/tests/vircgroupdata/systemd.mounts +new file mode 100644 +index 0000000000..75572c86f7 +--- /dev/null ++++ b/tests/vircgroupdata/systemd.mounts +@@ -0,0 +1,11 @@ ++rootfs / rootfs rw 0 0 ++tmpfs /run tmpfs rw,seclabel,nosuid,nodev,mode=755 0 0 ++tmpfs /not/really/sys/fs/cgroup tmpfs rw,seclabel,nosuid,nodev,noexec,mode=755 0 0 ++cgroup /not/really/sys/fs/cgroup/systemd cgroup rw,nosuid,nodev,noexec,relatime,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd 0 0 ++cgroup /not/really/sys/fs/cgroup/cpuset cgroup rw,nosuid,nodev,noexec,relatime,cpuset 0 0 ++cgroup /not/really/sys/fs/cgroup/cpu,cpuacct cgroup rw,nosuid,nodev,noexec,relatime,cpuacct,cpu 0 0 ++cgroup /not/really/sys/fs/cgroup/freezer cgroup rw,nosuid,nodev,noexec,relatime,freezer 0 0 ++cgroup /not/really/sys/fs/cgroup/blkio cgroup rw,nosuid,nodev,noexec,relatime,blkio 0 0 ++cgroup /not/really/sys/fs/cgroup/memory cgroup rw,nosuid,nodev,noexec,relatime,memory 0 0 ++/dev/sda1 /boot ext4 rw,seclabel,relatime,data=ordered 0 0 ++tmpfs /tmp tmpfs rw,seclabel,relatime,size=1024000k 0 0 +diff --git a/tests/vircgroupdata/systemd.self.cgroup b/tests/vircgroupdata/systemd.self.cgroup +new file mode 100644 +index 0000000000..2b95af79d2 +--- /dev/null ++++ b/tests/vircgroupdata/systemd.self.cgroup +@@ -0,0 +1,6 @@ ++115:memory:/ ++8:blkio:/ ++6:freezer:/ ++3:cpuacct,cpu:/system ++2:cpuset:/ ++1:name=systemd:/user/berrange/123 +diff --git a/tests/vircgroupmock.c b/tests/vircgroupmock.c +index cd5422dcba..3afe2fe192 100644 +--- a/tests/vircgroupmock.c ++++ b/tests/vircgroupmock.c +@@ -81,85 +81,6 @@ const char *fakedevicedir1 = FAKEDEVDIR1; + * of files beneath it + */ + +-/* +- * Intentionally missing the 'devices' mount. +- * Co-mounting cpu & cpuacct controllers +- * An anonymous controller for systemd +- */ +-const char *procmounts = +- "rootfs / rootfs rw 0 0\n" +- "tmpfs /run tmpfs rw,seclabel,nosuid,nodev,mode=755 0 0\n" +- "tmpfs /not/really/sys/fs/cgroup tmpfs rw,seclabel,nosuid,nodev,noexec,mode=755 0 0\n" +- "cgroup /not/really/sys/fs/cgroup/systemd cgroup rw,nosuid,nodev,noexec,relatime,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd 0 0\n" +- "cgroup /not/really/sys/fs/cgroup/cpuset cgroup rw,nosuid,nodev,noexec,relatime,cpuset 0 0\n" +- "cgroup /not/really/sys/fs/cgroup/cpu,cpuacct cgroup rw,nosuid,nodev,noexec,relatime,cpuacct,cpu 0 0\n" +- "cgroup /not/really/sys/fs/cgroup/freezer cgroup rw,nosuid,nodev,noexec,relatime,freezer 0 0\n" +- "cgroup /not/really/sys/fs/cgroup/blkio cgroup rw,nosuid,nodev,noexec,relatime,blkio 0 0\n" +- "cgroup /not/really/sys/fs/cgroup/memory cgroup rw,nosuid,nodev,noexec,relatime,memory 0 0\n" +- "/dev/sda1 /boot ext4 rw,seclabel,relatime,data=ordered 0 0\n" +- "tmpfs /tmp tmpfs rw,seclabel,relatime,size=1024000k 0 0\n"; +- +-const char *procselfcgroups = +- "115:memory:/\n" +- "8:blkio:/\n" +- "6:freezer:/\n" +- "3:cpuacct,cpu:/system\n" +- "2:cpuset:/\n" +- "1:name=systemd:/user/berrange/123\n"; +- +-const char *proccgroups = +- "#subsys_name hierarchy num_cgroups enabled\n" +- "cpuset 2 4 1\n" +- "cpu 3 48 1\n" +- "cpuacct 3 48 1\n" +- "memory 4 4 1\n" +- "devices 5 4 1\n" +- "freezer 6 4 1\n" +- "blkio 8 4 1\n"; +- +- +-const char *procmountsallinone = +- "rootfs / rootfs rw 0 0\n" +- "sysfs /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0\n" +- "proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0\n" +- "udev /dev devtmpfs rw,relatime,size=16458560k,nr_inodes=4114640,mode=755 0 0\n" +- "devpts /dev/pts devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 0 0\n" +- "nfsd /proc/fs/nfsd nfsd rw,relatime 0 0\n" +- "cgroup /not/really/sys/fs/cgroup cgroup rw,relatime,blkio,devices,memory,cpuacct,cpu,cpuset 0 0\n"; +- +-const char *procselfcgroupsallinone = +- "6:blkio,devices,memory,cpuacct,cpu,cpuset:/"; +- +-const char *proccgroupsallinone = +- "#subsys_name hierarchy num_cgroups enabled\n" +- "cpuset 6 1 1\n" +- "cpu 6 1 1\n" +- "cpuacct 6 1 1\n" +- "memory 6 1 1\n" +- "devices 6 1 1\n" +- "blkio 6 1 1\n"; +- +-const char *procmountslogind = +- "none /not/really/sys/fs/cgroup tmpfs rw,rootcontext=system_u:object_r:sysfs_t:s0,seclabel,relatime,size=4k,mode=755 0 0\n" +- "systemd /not/really/sys/fs/cgroup/systemd cgroup rw,nosuid,nodev,noexec,relatime,name=systemd 0 0\n"; +- +-const char *procselfcgroupslogind = +- "1:name=systemd:/\n"; +- +-const char *proccgroupslogind = +- "#subsys_name hierarchy num_cgroups enabled\n" +- "cpuset 0 1 1\n" +- "cpu 0 1 1\n" +- "cpuacct 0 1 1\n" +- "memory 0 1 0\n" +- "devices 0 1 1\n" +- "freezer 0 1 1\n" +- "net_cls 0 1 1\n" +- "blkio 0 1 1\n" +- "perf_event 0 1 1\n"; +- +- +- + static int make_file(const char *path, + const char *name, + const char *value) +@@ -379,29 +300,16 @@ static void init_sysfs(void) + + FILE *fopen(const char *path, const char *mode) + { +- const char *mock; +- bool allinone = false, logind = false; +- init_syms(); ++ char *filepath = NULL; ++ const char *type = NULL; ++ FILE *rc = NULL; ++ const char *filename = getenv("VIR_CGROUP_MOCK_FILENAME"); + +- mock = getenv("VIR_CGROUP_MOCK_MODE"); +- if (mock) { +- if (STREQ(mock, "allinone")) +- allinone = true; +- else if (STREQ(mock, "logind")) +- logind = true; +- } ++ init_syms(); + + if (STREQ(path, "/proc/mounts")) { + if (STREQ(mode, "r")) { +- if (allinone) +- return fmemopen((void *)procmountsallinone, +- strlen(procmountsallinone) + 1, mode); +- else if (logind) +- return fmemopen((void *)procmountslogind, +- strlen(procmountslogind) + 1, mode); +- else +- return fmemopen((void *)procmounts, +- strlen(procmounts) + 1, mode); ++ type = "mounts"; + } else { + errno = EACCES; + return NULL; +@@ -409,15 +317,7 @@ FILE *fopen(const char *path, const char *mode) + } + if (STREQ(path, "/proc/cgroups")) { + if (STREQ(mode, "r")) { +- if (allinone) +- return fmemopen((void *)proccgroupsallinone, +- strlen(proccgroupsallinone) + 1, mode); +- else if (logind) +- return fmemopen((void *)proccgroupslogind, +- strlen(proccgroupslogind) + 1, mode); +- else +- return fmemopen((void *)proccgroups, +- strlen(proccgroups) + 1, mode); ++ type = "cgroups"; + } else { + errno = EACCES; + return NULL; +@@ -425,21 +325,25 @@ FILE *fopen(const char *path, const char *mode) + } + if (STREQ(path, "/proc/self/cgroup")) { + if (STREQ(mode, "r")) { +- if (allinone) +- return fmemopen((void *)procselfcgroupsallinone, +- strlen(procselfcgroupsallinone) + 1, mode); +- else if (logind) +- return fmemopen((void *)procselfcgroupslogind, +- strlen(procselfcgroupslogind) + 1, mode); +- else +- return fmemopen((void *)procselfcgroups, +- strlen(procselfcgroups) + 1, mode); ++ type = "self.cgroup"; + } else { + errno = EACCES; + return NULL; + } + } + ++ if (type) { ++ if (!filename) ++ abort(); ++ if (virAsprintfQuiet(&filepath, "%s/vircgroupdata/%s.%s", ++ abs_srcdir, filename, type) < 0) { ++ abort(); ++ } ++ rc = real_fopen(filepath, mode); ++ free(filepath); ++ return rc; ++ } ++ + return real_fopen(path, mode); + } + +diff --git a/tests/vircgrouptest.c b/tests/vircgrouptest.c +index be50f3e73c..7968903cad 100644 +--- a/tests/vircgrouptest.c ++++ b/tests/vircgrouptest.c +@@ -890,6 +890,7 @@ mymain(void) + DETECT_MOUNTS("no-cgroups"); + DETECT_MOUNTS("kubevirt"); + ++ setenv("VIR_CGROUP_MOCK_FILENAME", "systemd", 1); + if (virTestRun("New cgroup for self", testCgroupNewForSelf, NULL) < 0) + ret = -1; + +@@ -925,20 +926,21 @@ mymain(void) + + if (virTestRun("virCgroupGetPercpuStats works", testCgroupGetPercpuStats, NULL) < 0) + ret = -1; ++ unsetenv("VIR_CGROUP_MOCK_FILENAME"); + +- setenv("VIR_CGROUP_MOCK_MODE", "allinone", 1); ++ setenv("VIR_CGROUP_MOCK_FILENAME", "all-in-one", 1); + if (virTestRun("New cgroup for self (allinone)", testCgroupNewForSelfAllInOne, NULL) < 0) + ret = -1; + if (virTestRun("Cgroup available", testCgroupAvailable, (void*)0x1) < 0) + ret = -1; +- unsetenv("VIR_CGROUP_MOCK_MODE"); ++ unsetenv("VIR_CGROUP_MOCK_FILENAME"); + +- setenv("VIR_CGROUP_MOCK_MODE", "logind", 1); ++ setenv("VIR_CGROUP_MOCK_FILENAME", "logind", 1); + if (virTestRun("New cgroup for self (logind)", testCgroupNewForSelfLogind, NULL) < 0) + ret = -1; + if (virTestRun("Cgroup available", testCgroupAvailable, (void*)0x0) < 0) + ret = -1; +- unsetenv("VIR_CGROUP_MOCK_MODE"); ++ unsetenv("VIR_CGROUP_MOCK_FILENAME"); + + if (getenv("LIBVIRT_SKIP_CLEANUP") == NULL) + virFileDeleteTree(fakerootdir); +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgrouptest-add-cgroup-v2-tests.patch b/SOURCES/libvirt-vircgrouptest-add-cgroup-v2-tests.patch new file mode 100644 index 0000000..4d676e4 --- /dev/null +++ b/SOURCES/libvirt-vircgrouptest-add-cgroup-v2-tests.patch @@ -0,0 +1,83 @@ +From 8b85c2ad4afbad2998163ac61b376320b4f392b8 Mon Sep 17 00:00:00 2001 +Message-Id: <8b85c2ad4afbad2998163ac61b376320b4f392b8@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:08:01 +0200 +Subject: [PATCH] vircgrouptest: add cgroup v2 tests +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit edf59855cf9b78fc4dc95f4b2833d87188decc71) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <5354c6c494c94b274e3b366188597ccd0828aefa.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + tests/vircgrouptest.c | 36 ++++++++++++++++++++++++++++++++---- + 1 file changed, 32 insertions(+), 4 deletions(-) + +diff --git a/tests/vircgrouptest.c b/tests/vircgrouptest.c +index 87f8fa7e67..3b844f0fbf 100644 +--- a/tests/vircgrouptest.c ++++ b/tests/vircgrouptest.c +@@ -570,14 +570,35 @@ static int testCgroupNewForSelfAllInOne(const void *args ATTRIBUTE_UNUSED) + static int testCgroupNewForSelfLogind(const void *args ATTRIBUTE_UNUSED) + { + virCgroupPtr cgroup = NULL; +- int ret = -1; + +- if (virCgroupNewSelf(&cgroup) == 0) { +- fprintf(stderr, "Expected cgroup creation to fail.\n"); ++ if (virCgroupNewSelf(&cgroup) >= 0) { ++ fprintf(stderr, "Expected to fail, only systemd cgroup available.\n"); ++ virCgroupFree(&cgroup); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++ ++static int testCgroupNewForSelfUnified(const void *args ATTRIBUTE_UNUSED) ++{ ++ virCgroupPtr cgroup = NULL; ++ int ret = -1; ++ const char *empty[VIR_CGROUP_CONTROLLER_LAST] = { 0 }; ++ unsigned int controllers = ++ (1 << VIR_CGROUP_CONTROLLER_CPU) | ++ (1 << VIR_CGROUP_CONTROLLER_CPUACCT) | ++ (1 << VIR_CGROUP_CONTROLLER_MEMORY) | ++ (1 << VIR_CGROUP_CONTROLLER_BLKIO); ++ ++ if (virCgroupNewSelf(&cgroup) < 0) { ++ fprintf(stderr, "Cannot create cgroup for self\n"); + goto cleanup; + } + +- ret = 0; ++ ret = validateCgroup(cgroup, "", empty, empty, empty, ++ "/not/really/sys/fs/cgroup", "/", controllers); + cleanup: + virCgroupFree(&cgroup); + return ret; +@@ -994,7 +1015,14 @@ mymain(void) + ret = -1; + cleanupFakeFS(fakerootdir); + ++ /* cgroup unified */ + ++ fakerootdir = initFakeFS("unified", "unified"); ++ if (virTestRun("New cgroup for self (unified)", testCgroupNewForSelfUnified, NULL) < 0) ++ ret = -1; ++ if (virTestRun("Cgroup available (unified)", testCgroupAvailable, (void*)0x1) < 0) ++ ret = -1; ++ cleanupFakeFS(fakerootdir); + + return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; + } +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgrouptest-add-detect-mounts-test-for-cgroup-v2.patch b/SOURCES/libvirt-vircgrouptest-add-detect-mounts-test-for-cgroup-v2.patch new file mode 100644 index 0000000..38cbd13 --- /dev/null +++ b/SOURCES/libvirt-vircgrouptest-add-detect-mounts-test-for-cgroup-v2.patch @@ -0,0 +1,115 @@ +From ab8447f6e6a5ab8e3d278be61bc9ccc93c435d3b Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:58 +0200 +Subject: [PATCH] vircgrouptest: add detect mounts test for cgroup v2 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 8f43c7a698b7a360d508eccc82ffc08e930cc3f8) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <10b25253a0f4705093b96cfe56a0c64bb2114785.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + tests/vircgroupdata/unified.cgroups | 13 +++++++++++++ + tests/vircgroupdata/unified.mounts | 20 ++++++++++++++++++++ + tests/vircgroupdata/unified.parsed | 11 +++++++++++ + tests/vircgroupdata/unified.self.cgroup | 1 + + tests/vircgrouptest.c | 3 +++ + 5 files changed, 48 insertions(+) + create mode 100644 tests/vircgroupdata/unified.cgroups + create mode 100644 tests/vircgroupdata/unified.mounts + create mode 100644 tests/vircgroupdata/unified.parsed + create mode 100644 tests/vircgroupdata/unified.self.cgroup + +diff --git a/tests/vircgroupdata/unified.cgroups b/tests/vircgroupdata/unified.cgroups +new file mode 100644 +index 0000000000..e0d8a3561c +--- /dev/null ++++ b/tests/vircgroupdata/unified.cgroups +@@ -0,0 +1,13 @@ ++#subsys_name hierarchy num_cgroups enabled ++cpuset 0 1 1 ++cpu 0 1 1 ++cpuacct 0 1 1 ++blkio 0 1 1 ++memory 0 1 1 ++devices 0 1 1 ++freezer 0 1 1 ++net_cls 0 1 1 ++perf_event 0 1 1 ++net_prio 0 1 1 ++hugetlb 0 1 1 ++pids 0 1 1 +diff --git a/tests/vircgroupdata/unified.mounts b/tests/vircgroupdata/unified.mounts +new file mode 100644 +index 0000000000..b4ab94a2c3 +--- /dev/null ++++ b/tests/vircgroupdata/unified.mounts +@@ -0,0 +1,20 @@ ++sysfs /sys sysfs rw,seclabel,nosuid,nodev,noexec,relatime 0 0 ++proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0 ++devtmpfs /dev devtmpfs rw,seclabel,nosuid,size=1009844k,nr_inodes=252461,mode=755 0 0 ++securityfs /sys/kernel/security securityfs rw,nosuid,nodev,noexec,relatime 0 0 ++tmpfs /dev/shm tmpfs rw,seclabel,nosuid,nodev 0 0 ++devpts /dev/pts devpts rw,seclabel,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 0 0 ++tmpfs /run tmpfs rw,seclabel,nosuid,nodev,mode=755 0 0 ++cgroup2 /not/really/sys/fs/cgroup cgroup2 rw,seclabel,nosuid,nodev,noexec,relatime,nsdelegate 0 0 ++pstore /sys/fs/pstore pstore rw,seclabel,nosuid,nodev,noexec,relatime 0 0 ++bpf /sys/fs/bpf bpf rw,nosuid,nodev,noexec,relatime,mode=700 0 0 ++configfs /sys/kernel/config configfs rw,relatime 0 0 ++/dev/vda2 / ext4 rw,seclabel,relatime 0 0 ++selinuxfs /sys/fs/selinux selinuxfs rw,relatime 0 0 ++debugfs /sys/kernel/debug debugfs rw,seclabel,relatime 0 0 ++hugetlbfs /dev/hugepages hugetlbfs rw,seclabel,relatime,pagesize=2M 0 0 ++systemd-1 /proc/sys/fs/binfmt_misc autofs rw,relatime,fd=40,pgrp=1,timeout=0,minproto=5,maxproto=5,direct,pipe_ino=14586 0 0 ++mqueue /dev/mqueue mqueue rw,seclabel,relatime 0 0 ++tmpfs /tmp tmpfs rw,seclabel,nosuid,nodev 0 0 ++sunrpc /var/lib/nfs/rpc_pipefs rpc_pipefs rw,relatime 0 0 ++tmpfs /run/user/0 tmpfs rw,seclabel,nosuid,nodev,relatime,size=204000k,mode=700 0 0 +diff --git a/tests/vircgroupdata/unified.parsed b/tests/vircgroupdata/unified.parsed +new file mode 100644 +index 0000000000..3de0fc643d +--- /dev/null ++++ b/tests/vircgroupdata/unified.parsed +@@ -0,0 +1,11 @@ ++cpu ++cpuacct ++cpuset ++memory ++devices ++freezer ++blkio ++net_cls ++perf_event ++name=systemd ++unified /not/really/sys/fs/cgroup +diff --git a/tests/vircgroupdata/unified.self.cgroup b/tests/vircgroupdata/unified.self.cgroup +new file mode 100644 +index 0000000000..1e027b2a3c +--- /dev/null ++++ b/tests/vircgroupdata/unified.self.cgroup +@@ -0,0 +1 @@ ++0::/ +diff --git a/tests/vircgrouptest.c b/tests/vircgrouptest.c +index b66682e6c8..1ce1371ddc 100644 +--- a/tests/vircgrouptest.c ++++ b/tests/vircgrouptest.c +@@ -900,6 +900,9 @@ mymain(void) + DETECT_MOUNTS("all-in-one"); + DETECT_MOUNTS_FAIL("no-cgroups"); + DETECT_MOUNTS("kubevirt"); ++ fakerootdir = initFakeFS("unified", NULL); ++ DETECT_MOUNTS("unified"); ++ cleanupFakeFS(fakerootdir); + + fakerootdir = initFakeFS(NULL, "systemd"); + if (virTestRun("New cgroup for self", testCgroupNewForSelf, NULL) < 0) +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgrouptest-add-detect-mounts-test-for-hybrid-cgroups.patch b/SOURCES/libvirt-vircgrouptest-add-detect-mounts-test-for-hybrid-cgroups.patch new file mode 100644 index 0000000..298390f --- /dev/null +++ b/SOURCES/libvirt-vircgrouptest-add-detect-mounts-test-for-hybrid-cgroups.patch @@ -0,0 +1,125 @@ +From 804df2c86f609fee35603273329f773e6eead7a8 Mon Sep 17 00:00:00 2001 +Message-Id: <804df2c86f609fee35603273329f773e6eead7a8@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:59 +0200 +Subject: [PATCH] vircgrouptest: add detect mounts test for hybrid cgroups +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 1981c79c4b068b918c3f34093ed2e634811b4147) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <8692433b683cef60139ee0b11052fd7f0de9ea41.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + tests/vircgroupdata/hybrid.cgroups | 12 ++++++++++++ + tests/vircgroupdata/hybrid.mounts | 23 +++++++++++++++++++++++ + tests/vircgroupdata/hybrid.parsed | 11 +++++++++++ + tests/vircgroupdata/hybrid.self.cgroup | 9 +++++++++ + tests/vircgrouptest.c | 3 +++ + 5 files changed, 58 insertions(+) + create mode 100644 tests/vircgroupdata/hybrid.cgroups + create mode 100644 tests/vircgroupdata/hybrid.mounts + create mode 100644 tests/vircgroupdata/hybrid.parsed + create mode 100644 tests/vircgroupdata/hybrid.self.cgroup + +diff --git a/tests/vircgroupdata/hybrid.cgroups b/tests/vircgroupdata/hybrid.cgroups +new file mode 100644 +index 0000000000..7f3bc7b8cb +--- /dev/null ++++ b/tests/vircgroupdata/hybrid.cgroups +@@ -0,0 +1,12 @@ ++#subsys_name hierarchy num_cgroups enabled ++cpuset 2 1 1 ++cpu 0 1 1 ++cpuacct 0 1 1 ++blkio 0 1 1 ++memory 0 1 1 ++devices 3 1 1 ++freezer 5 1 1 ++net_cls 4 1 1 ++perf_event 6 1 1 ++hugetlb 7 1 1 ++pids 8 1 1 +diff --git a/tests/vircgroupdata/hybrid.mounts b/tests/vircgroupdata/hybrid.mounts +new file mode 100644 +index 0000000000..d6f5f82115 +--- /dev/null ++++ b/tests/vircgroupdata/hybrid.mounts +@@ -0,0 +1,23 @@ ++proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0 ++sysfs /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0 ++devtmpfs /dev devtmpfs rw,nosuid,size=10240k,nr_inodes=502705,mode=755 0 0 ++devpts /dev/pts devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 0 0 ++tmpfs /dev/shm tmpfs rw,nosuid,nodev,noexec 0 0 ++tmpfs /run tmpfs rw,nosuid,nodev,noexec,mode=755 0 0 ++mqueue /dev/mqueue mqueue rw,nosuid,nodev,noexec,relatime 0 0 ++securityfs /sys/kernel/security securityfs rw,nosuid,nodev,noexec,relatime 0 0 ++debugfs /sys/kernel/debug debugfs rw,nosuid,nodev,noexec,relatime 0 0 ++configfs /sys/kernel/config configfs rw,nosuid,nodev,noexec,relatime 0 0 ++fusectl /sys/fs/fuse/connections fusectl rw,nosuid,nodev,noexec,relatime 0 0 ++selinuxfs /sys/fs/selinux selinuxfs rw,relatime 0 0 ++pstore /sys/fs/pstore pstore rw,nosuid,nodev,noexec,relatime 0 0 ++cgroup_root /not/really/sys/fs/cgroup tmpfs rw,nosuid,nodev,noexec,relatime,size=10240k,mode=755 0 0 ++openrc /not/really/sys/fs/cgroup/openrc cgroup rw,nosuid,nodev,noexec,relatime,release_agent=/lib64/rc/sh/cgroup-release-agent.sh,name=openrc 0 0 ++none /not/really/sys/fs/cgroup/unified cgroup2 rw,nosuid,nodev,noexec,relatime,nsdelegate 0 0 ++cpuset /not/really/sys/fs/cgroup/cpuset cgroup rw,nosuid,nodev,noexec,relatime,cpuset 0 0 ++devices /not/really/sys/fs/cgroup/devices cgroup rw,nosuid,nodev,noexec,relatime,devices 0 0 ++net_cls /not/really/sys/fs/cgroup/net_cls cgroup rw,nosuid,nodev,noexec,relatime,net_cls 0 0 ++freezer /not/really/sys/fs/cgroup/freezer cgroup rw,nosuid,nodev,noexec,relatime,freezer 0 0 ++perf_event /not/really/sys/fs/cgroup/perf_event cgroup rw,nosuid,nodev,noexec,relatime,perf_event 0 0 ++hugetlb /not/really/sys/fs/cgroup/hugetlb cgroup rw,nosuid,nodev,noexec,relatime,hugetlb 0 0 ++pids /not/really/sys/fs/cgroup/pids cgroup rw,nosuid,nodev,noexec,relatime,pids 0 0 +diff --git a/tests/vircgroupdata/hybrid.parsed b/tests/vircgroupdata/hybrid.parsed +new file mode 100644 +index 0000000000..7600de5f45 +--- /dev/null ++++ b/tests/vircgroupdata/hybrid.parsed +@@ -0,0 +1,11 @@ ++cpu ++cpuacct ++cpuset /not/really/sys/fs/cgroup/cpuset ++memory ++devices /not/really/sys/fs/cgroup/devices ++freezer /not/really/sys/fs/cgroup/freezer ++blkio ++net_cls /not/really/sys/fs/cgroup/net_cls ++perf_event /not/really/sys/fs/cgroup/perf_event ++name=systemd ++unified /not/really/sys/fs/cgroup/unified +diff --git a/tests/vircgroupdata/hybrid.self.cgroup b/tests/vircgroupdata/hybrid.self.cgroup +new file mode 100644 +index 0000000000..2a08905c91 +--- /dev/null ++++ b/tests/vircgroupdata/hybrid.self.cgroup +@@ -0,0 +1,9 @@ ++8:pids:/ ++7:hugetlb:/ ++6:perf_event:/ ++5:freezer:/ ++4:net_cls:/ ++3:devices:/ ++2:cpuset:/ ++1:name=openrc:/ ++0::/ +diff --git a/tests/vircgrouptest.c b/tests/vircgrouptest.c +index 1ce1371ddc..aeb2840823 100644 +--- a/tests/vircgrouptest.c ++++ b/tests/vircgrouptest.c +@@ -903,6 +903,9 @@ mymain(void) + fakerootdir = initFakeFS("unified", NULL); + DETECT_MOUNTS("unified"); + cleanupFakeFS(fakerootdir); ++ fakerootdir = initFakeFS("hybrid", NULL); ++ DETECT_MOUNTS("hybrid"); ++ cleanupFakeFS(fakerootdir); + + fakerootdir = initFakeFS(NULL, "systemd"); + if (virTestRun("New cgroup for self", testCgroupNewForSelf, NULL) < 0) +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgrouptest-add-hybrid-tests.patch b/SOURCES/libvirt-vircgrouptest-add-hybrid-tests.patch new file mode 100644 index 0000000..b01a628 --- /dev/null +++ b/SOURCES/libvirt-vircgrouptest-add-hybrid-tests.patch @@ -0,0 +1,90 @@ +From 0628a57a5b4a28d644970a2ad82cfadc14a3cd9f Mon Sep 17 00:00:00 2001 +Message-Id: <0628a57a5b4a28d644970a2ad82cfadc14a3cd9f@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:08:02 +0200 +Subject: [PATCH] vircgrouptest: add hybrid tests +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit a26de856f98119bf651ed9928c64b6f96f78f185) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <434692bd0df2a6f28c93e3cc071187144820d836.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + tests/vircgrouptest.c | 48 +++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 48 insertions(+) + +diff --git a/tests/vircgrouptest.c b/tests/vircgrouptest.c +index 3b844f0fbf..7fde50b463 100644 +--- a/tests/vircgrouptest.c ++++ b/tests/vircgrouptest.c +@@ -605,6 +605,45 @@ static int testCgroupNewForSelfUnified(const void *args ATTRIBUTE_UNUSED) + } + + ++static int testCgroupNewForSelfHybrid(const void *args ATTRIBUTE_UNUSED) ++{ ++ virCgroupPtr cgroup = NULL; ++ int ret = -1; ++ const char *empty[VIR_CGROUP_CONTROLLER_LAST] = { 0 }; ++ const char *mounts[VIR_CGROUP_CONTROLLER_LAST] = { ++ [VIR_CGROUP_CONTROLLER_CPUSET] = "/not/really/sys/fs/cgroup/cpuset", ++ [VIR_CGROUP_CONTROLLER_DEVICES] = "/not/really/sys/fs/cgroup/devices", ++ [VIR_CGROUP_CONTROLLER_FREEZER] = "/not/really/sys/fs/cgroup/freezer", ++ [VIR_CGROUP_CONTROLLER_NET_CLS] = "/not/really/sys/fs/cgroup/net_cls", ++ [VIR_CGROUP_CONTROLLER_PERF_EVENT] = "/not/really/sys/fs/cgroup/perf_event", ++ }; ++ const char *placement[VIR_CGROUP_CONTROLLER_LAST] = { ++ [VIR_CGROUP_CONTROLLER_CPUSET] = "/", ++ [VIR_CGROUP_CONTROLLER_DEVICES] = "/", ++ [VIR_CGROUP_CONTROLLER_FREEZER] = "/", ++ [VIR_CGROUP_CONTROLLER_NET_CLS] = "/", ++ [VIR_CGROUP_CONTROLLER_PERF_EVENT] = "/", ++ }; ++ unsigned int controllers = ++ (1 << VIR_CGROUP_CONTROLLER_CPU) | ++ (1 << VIR_CGROUP_CONTROLLER_CPUACCT) | ++ (1 << VIR_CGROUP_CONTROLLER_MEMORY) | ++ (1 << VIR_CGROUP_CONTROLLER_BLKIO); ++ ++ if (virCgroupNewSelf(&cgroup) < 0) { ++ fprintf(stderr, "Cannot create cgroup for self\n"); ++ goto cleanup; ++ } ++ ++ ret = validateCgroup(cgroup, "", mounts, empty, placement, ++ "/not/really/sys/fs/cgroup/unified", "/", controllers); ++ ++ cleanup: ++ virCgroupFree(&cgroup); ++ return ret; ++} ++ ++ + static int testCgroupAvailable(const void *args) + { + bool got = virCgroupAvailable(); +@@ -1024,6 +1063,15 @@ mymain(void) + ret = -1; + cleanupFakeFS(fakerootdir); + ++ /* cgroup hybrid */ ++ ++ fakerootdir = initFakeFS("hybrid", "hybrid"); ++ if (virTestRun("New cgroup for self (hybrid)", testCgroupNewForSelfHybrid, NULL) < 0) ++ ret = -1; ++ if (virTestRun("Cgroup available (hybrid)", testCgroupAvailable, (void*)0x1) < 0) ++ ret = -1; ++ cleanupFakeFS(fakerootdir); ++ + return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; + } + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgrouptest-call-virCgroupDetectMounts-directly.patch b/SOURCES/libvirt-vircgrouptest-call-virCgroupDetectMounts-directly.patch new file mode 100644 index 0000000..77285a2 --- /dev/null +++ b/SOURCES/libvirt-vircgrouptest-call-virCgroupDetectMounts-directly.patch @@ -0,0 +1,163 @@ +From 094b38a5c13a27f2f48897bd8cf811741a754db7 Mon Sep 17 00:00:00 2001 +Message-Id: <094b38a5c13a27f2f48897bd8cf811741a754db7@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:19 +0200 +Subject: [PATCH] vircgrouptest: call virCgroupDetectMounts directly +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Because we can set which files to return for cgroup tests there +is no need to have special function tailored to run tests. + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 4988f4b347d3c56af4bdb9852d1461f08f6cfced) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <5b3185e7dd49ac4d9a56532e6d77ad1aa098db95.1561993099.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/libvirt_private.syms | 2 +- + src/util/vircgroup.c | 21 +++++---------------- + src/util/vircgrouppriv.h | 4 +--- + tests/vircgrouptest.c | 16 ++++++++-------- + 4 files changed, 15 insertions(+), 28 deletions(-) + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index f8c1a0df16..b66beb7f91 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -1528,7 +1528,7 @@ virCgroupDelThread; + virCgroupDenyAllDevices; + virCgroupDenyDevice; + virCgroupDenyDevicePath; +-virCgroupDetectMountsFromFile; ++virCgroupDetectMounts; + virCgroupFree; + virCgroupGetBlkioDeviceReadBps; + virCgroupGetBlkioDeviceReadIops; +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index f08fe3600e..53f5faafd2 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -430,9 +430,7 @@ virCgroupMountOptsMatchController(const char *mntOpts, + * mounted and where + */ + int +-virCgroupDetectMountsFromFile(virCgroupPtr group, +- const char *path, +- bool checkLinks) ++virCgroupDetectMounts(virCgroupPtr group) + { + size_t i; + FILE *mounts = NULL; +@@ -440,9 +438,9 @@ virCgroupDetectMountsFromFile(virCgroupPtr group, + char buf[CGROUP_MAX_VAL]; + int ret = -1; + +- mounts = fopen(path, "r"); ++ mounts = fopen("/proc/mounts", "r"); + if (mounts == NULL) { +- virReportSystemError(errno, _("Unable to open %s"), path); ++ virReportSystemError(errno, "%s", _("Unable to open /proc/mounts")); + return -1; + } + +@@ -470,8 +468,7 @@ virCgroupDetectMountsFromFile(virCgroupPtr group, + + /* If it is a co-mount it has a filename like "cpu,cpuacct" + * and we must identify the symlink path */ +- if (checkLinks && +- virCgroupResolveMountLink(entry.mnt_dir, typestr, ++ if (virCgroupResolveMountLink(entry.mnt_dir, typestr, + controller) < 0) { + goto cleanup; + } +@@ -485,12 +482,6 @@ virCgroupDetectMountsFromFile(virCgroupPtr group, + return ret; + } + +-static int +-virCgroupDetectMounts(virCgroupPtr group) +-{ +- return virCgroupDetectMountsFromFile(group, "/proc/mounts", true); +-} +- + + static int + virCgroupCopyPlacement(virCgroupPtr group, +@@ -4090,9 +4081,7 @@ virCgroupAvailable(void) + + + int +-virCgroupDetectMountsFromFile(virCgroupPtr group ATTRIBUTE_UNUSED, +- const char *path ATTRIBUTE_UNUSED, +- bool checkLinks ATTRIBUTE_UNUSED) ++virCgroupDetectMounts(virCgroupPtr group ATTRIBUTE_UNUSED) + { + virReportSystemError(ENXIO, "%s", + _("Control groups not supported on this platform")); +diff --git a/src/util/vircgrouppriv.h b/src/util/vircgrouppriv.h +index a0034f3889..f78fe8bb9c 100644 +--- a/src/util/vircgrouppriv.h ++++ b/src/util/vircgrouppriv.h +@@ -50,9 +50,7 @@ struct _virCgroup { + virCgroupController controllers[VIR_CGROUP_CONTROLLER_LAST]; + }; + +-int virCgroupDetectMountsFromFile(virCgroupPtr group, +- const char *path, +- bool checkLinks); ++int virCgroupDetectMounts(virCgroupPtr group); + + int virCgroupNewPartition(const char *path, + bool create, +diff --git a/tests/vircgrouptest.c b/tests/vircgrouptest.c +index 7968903cad..6a38091a86 100644 +--- a/tests/vircgrouptest.c ++++ b/tests/vircgrouptest.c +@@ -164,21 +164,21 @@ testCgroupDetectMounts(const void *args) + { + int result = -1; + const char *file = args; +- char *mounts = NULL; + char *parsed = NULL; + const char *actual; + virCgroupPtr group = NULL; + virBuffer buf = VIR_BUFFER_INITIALIZER; + size_t i; + +- if (virAsprintf(&mounts, "%s/vircgroupdata/%s.mounts", +- abs_srcdir, file) < 0 || +- virAsprintf(&parsed, "%s/vircgroupdata/%s.parsed", +- abs_srcdir, file) < 0 || +- VIR_ALLOC(group) < 0) ++ setenv("VIR_CGROUP_MOCK_FILENAME", file, 1); ++ ++ if (virAsprintf(&parsed, "%s/vircgroupdata/%s.parsed", abs_srcdir, file) < 0) + goto cleanup; + +- if (virCgroupDetectMountsFromFile(group, mounts, false) < 0) ++ if (VIR_ALLOC(group) < 0) ++ goto cleanup; ++ ++ if (virCgroupDetectMounts(group) < 0) + goto cleanup; + + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { +@@ -196,7 +196,7 @@ testCgroupDetectMounts(const void *args) + result = 0; + + cleanup: +- VIR_FREE(mounts); ++ unsetenv("VIR_CGROUP_MOCK_FILENAME"); + VIR_FREE(parsed); + virCgroupFree(&group); + virBufferFreeAndReset(&buf); +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgrouptest-call-virCgroupNewSelf-instead-virCgroupDetectMounts.patch b/SOURCES/libvirt-vircgrouptest-call-virCgroupNewSelf-instead-virCgroupDetectMounts.patch new file mode 100644 index 0000000..1984f62 --- /dev/null +++ b/SOURCES/libvirt-vircgrouptest-call-virCgroupNewSelf-instead-virCgroupDetectMounts.patch @@ -0,0 +1,544 @@ +From e3b6a0736a5b8e23041006ac004cccf1e48ae528 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:06:20 +0200 +Subject: [PATCH] vircgrouptest: call virCgroupNewSelf instead + virCgroupDetectMounts +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This will be required once cgroup v2 is introduced. The cgroup +detection is not simple and we will have multiple backends so we +should not just jump into the middle of the detection code. + +In order to use virCgroupNewSelf we need to create all the remaining +data files: + + - {name}.cgroups represents /proc/cgroups, it is a list of cgroup + controllers compiled into kernel + + - {name}.self.cgroup represents /proc/self/cgroup, it describes + cgroups to which the process belongs + +For "no-cgroups" we need to modify the expected behavior because +virCgroupNewSelf() will fail if there are no controllers available. + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 8b62008d2bc5442f7755e579ea754ffd5e3f9691) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <3d1ddcca1a1e323e607445c5d1089698122efdd8.1561993099.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/libvirt_private.syms | 1 - + src/util/vircgroup.c | 11 +------ + src/util/vircgrouppriv.h | 2 -- + tests/vircgroupdata/cgroups1.cgroups | 11 +++++++ + tests/vircgroupdata/cgroups1.self.cgroup | 11 +++++++ + tests/vircgroupdata/cgroups2.cgroups | 10 +++++++ + tests/vircgroupdata/cgroups2.self.cgroup | 10 +++++++ + tests/vircgroupdata/cgroups3.cgroups | 12 ++++++++ + tests/vircgroupdata/cgroups3.self.cgroup | 12 ++++++++ + tests/vircgroupdata/fedora-18.cgroups | 10 +++++++ + tests/vircgroupdata/fedora-18.self.cgroup | 9 ++++++ + tests/vircgroupdata/fedora-21.cgroups | 12 ++++++++ + tests/vircgroupdata/fedora-21.self.cgroup | 10 +++++++ + tests/vircgroupdata/kubevirt.cgroups | 10 +++++++ + tests/vircgroupdata/kubevirt.self.cgroup | 10 +++++++ + tests/vircgroupdata/no-cgroups.cgroups | 8 +++++ + tests/vircgroupdata/no-cgroups.parsed | 10 ------- + tests/vircgroupdata/no-cgroups.self.cgroup | 0 + tests/vircgroupdata/ovirt-node-6.6.cgroups | 9 ++++++ + .../vircgroupdata/ovirt-node-6.6.self.cgroup | 8 +++++ + tests/vircgroupdata/ovirt-node-7.1.cgroups | 11 +++++++ + .../vircgroupdata/ovirt-node-7.1.self.cgroup | 10 +++++++ + tests/vircgroupdata/rhel-7.1.cgroups | 11 +++++++ + tests/vircgroupdata/rhel-7.1.self.cgroup | 10 +++++++ + tests/vircgrouptest.c | 30 ++++++++++++++----- + 25 files changed, 217 insertions(+), 31 deletions(-) + create mode 100644 tests/vircgroupdata/cgroups1.cgroups + create mode 100644 tests/vircgroupdata/cgroups1.self.cgroup + create mode 100644 tests/vircgroupdata/cgroups2.cgroups + create mode 100644 tests/vircgroupdata/cgroups2.self.cgroup + create mode 100644 tests/vircgroupdata/cgroups3.cgroups + create mode 100644 tests/vircgroupdata/cgroups3.self.cgroup + create mode 100644 tests/vircgroupdata/fedora-18.cgroups + create mode 100644 tests/vircgroupdata/fedora-18.self.cgroup + create mode 100644 tests/vircgroupdata/fedora-21.cgroups + create mode 100644 tests/vircgroupdata/fedora-21.self.cgroup + create mode 100644 tests/vircgroupdata/kubevirt.cgroups + create mode 100644 tests/vircgroupdata/kubevirt.self.cgroup + create mode 100644 tests/vircgroupdata/no-cgroups.cgroups + delete mode 100644 tests/vircgroupdata/no-cgroups.parsed + create mode 100644 tests/vircgroupdata/no-cgroups.self.cgroup + create mode 100644 tests/vircgroupdata/ovirt-node-6.6.cgroups + create mode 100644 tests/vircgroupdata/ovirt-node-6.6.self.cgroup + create mode 100644 tests/vircgroupdata/ovirt-node-7.1.cgroups + create mode 100644 tests/vircgroupdata/ovirt-node-7.1.self.cgroup + create mode 100644 tests/vircgroupdata/rhel-7.1.cgroups + create mode 100644 tests/vircgroupdata/rhel-7.1.self.cgroup + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index b66beb7f91..8c4be84fd5 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -1528,7 +1528,6 @@ virCgroupDelThread; + virCgroupDenyAllDevices; + virCgroupDenyDevice; + virCgroupDenyDevicePath; +-virCgroupDetectMounts; + virCgroupFree; + virCgroupGetBlkioDeviceReadBps; + virCgroupGetBlkioDeviceReadIops; +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 53f5faafd2..d55f411daa 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -429,7 +429,7 @@ virCgroupMountOptsMatchController(const char *mntOpts, + * Process /proc/mounts figuring out what controllers are + * mounted and where + */ +-int ++static int + virCgroupDetectMounts(virCgroupPtr group) + { + size_t i; +@@ -4080,15 +4080,6 @@ virCgroupAvailable(void) + } + + +-int +-virCgroupDetectMounts(virCgroupPtr group ATTRIBUTE_UNUSED) +-{ +- virReportSystemError(ENXIO, "%s", +- _("Control groups not supported on this platform")); +- return -1; +-} +- +- + int + virCgroupNewPartition(const char *path ATTRIBUTE_UNUSED, + bool create ATTRIBUTE_UNUSED, +diff --git a/src/util/vircgrouppriv.h b/src/util/vircgrouppriv.h +index f78fe8bb9c..046c96c52c 100644 +--- a/src/util/vircgrouppriv.h ++++ b/src/util/vircgrouppriv.h +@@ -50,8 +50,6 @@ struct _virCgroup { + virCgroupController controllers[VIR_CGROUP_CONTROLLER_LAST]; + }; + +-int virCgroupDetectMounts(virCgroupPtr group); +- + int virCgroupNewPartition(const char *path, + bool create, + int controllers, +diff --git a/tests/vircgroupdata/cgroups1.cgroups b/tests/vircgroupdata/cgroups1.cgroups +new file mode 100644 +index 0000000000..a03c290a98 +--- /dev/null ++++ b/tests/vircgroupdata/cgroups1.cgroups +@@ -0,0 +1,11 @@ ++#subsys_name hierarchy num_cgroups enabled ++cpuset 1 1 1 ++cpu 2 1 1 ++cpuacct 3 1 1 ++blkio 8 1 1 ++memory 4 1 1 ++devices 5 1 1 ++freezer 6 1 1 ++net_cls 7 1 1 ++net_prio 9 1 1 ++hugetlb 10 1 1 +diff --git a/tests/vircgroupdata/cgroups1.self.cgroup b/tests/vircgroupdata/cgroups1.self.cgroup +new file mode 100644 +index 0000000000..181f0c22f8 +--- /dev/null ++++ b/tests/vircgroupdata/cgroups1.self.cgroup +@@ -0,0 +1,11 @@ ++10:hugetlb:/ ++9:net_prio:/ ++8:blkio:/ ++7:net_cls:/ ++6:freezer:/ ++5:devices:/ ++4:memory:/ ++3:cpuacct:/ ++2:cpu:/ ++1:cpuset:/ ++0:name=openrc:/ +diff --git a/tests/vircgroupdata/cgroups2.cgroups b/tests/vircgroupdata/cgroups2.cgroups +new file mode 100644 +index 0000000000..f0a7699559 +--- /dev/null ++++ b/tests/vircgroupdata/cgroups2.cgroups +@@ -0,0 +1,10 @@ ++#subsys_name hierarchy num_cgroups enabled ++cpuset 1 1 1 ++cpu 2 1 1 ++cpuacct 3 1 1 ++blkio 7 1 1 ++memory 4 1 1 ++devices 5 1 1 ++freezer 6 1 1 ++perf_event 8 1 1 ++hugetlb 9 1 1 +diff --git a/tests/vircgroupdata/cgroups2.self.cgroup b/tests/vircgroupdata/cgroups2.self.cgroup +new file mode 100644 +index 0000000000..3d0e793e5a +--- /dev/null ++++ b/tests/vircgroupdata/cgroups2.self.cgroup +@@ -0,0 +1,10 @@ ++9:hugetlb:/ ++8:perf_event:/ ++7:blkio:/ ++6:freezer:/ ++5:devices:/ ++4:memory:/ ++3:cpuacct:/ ++2:cpu:/ ++1:cpuset:/ ++0:name=openrc:/ +diff --git a/tests/vircgroupdata/cgroups3.cgroups b/tests/vircgroupdata/cgroups3.cgroups +new file mode 100644 +index 0000000000..294d95dedf +--- /dev/null ++++ b/tests/vircgroupdata/cgroups3.cgroups +@@ -0,0 +1,12 @@ ++#subsys_name hierarchy num_cgroups enabled ++cpuset 1 1 1 ++cpu 2 1 1 ++cpuacct 3 1 1 ++blkio 8 1 1 ++memory 4 1 1 ++devices 5 1 1 ++freezer 6 1 1 ++net_cls 7 1 1 ++perf_event 9 1 1 ++net_prio 10 1 1 ++hugetlb 11 1 1 +diff --git a/tests/vircgroupdata/cgroups3.self.cgroup b/tests/vircgroupdata/cgroups3.self.cgroup +new file mode 100644 +index 0000000000..bf346abdf9 +--- /dev/null ++++ b/tests/vircgroupdata/cgroups3.self.cgroup +@@ -0,0 +1,12 @@ ++11:hugetlb:/ ++10:net_prio:/ ++9:perf_event:/ ++8:blkio:/ ++7:net_cls:/ ++6:freezer:/ ++5:devices:/ ++4:memory:/ ++3:cpuacct:/ ++2:cpu:/ ++1:cpuset:/ ++0:name=openrc:/ +diff --git a/tests/vircgroupdata/fedora-18.cgroups b/tests/vircgroupdata/fedora-18.cgroups +new file mode 100644 +index 0000000000..8eb41087f3 +--- /dev/null ++++ b/tests/vircgroupdata/fedora-18.cgroups +@@ -0,0 +1,10 @@ ++#subsys_name hierarchy num_cgroups enabled ++cpuset 1 1 1 ++cpu 2 1 1 ++cpuacct 2 1 1 ++blkio 7 1 1 ++memory 3 1 1 ++devices 4 1 1 ++freezer 5 1 1 ++net_cls 6 1 1 ++perf_event 8 1 1 +diff --git a/tests/vircgroupdata/fedora-18.self.cgroup b/tests/vircgroupdata/fedora-18.self.cgroup +new file mode 100644 +index 0000000000..da9ad8ad4d +--- /dev/null ++++ b/tests/vircgroupdata/fedora-18.self.cgroup +@@ -0,0 +1,9 @@ ++8:perf_event:/ ++7:blkio:/ ++6:net_cls:/ ++5:freezer:/ ++4:devices:/ ++3:memory:/ ++2:cpu,cpuacct:/ ++1:cpuset:/ ++0:name=systemd:/ +diff --git a/tests/vircgroupdata/fedora-21.cgroups b/tests/vircgroupdata/fedora-21.cgroups +new file mode 100644 +index 0000000000..3e1401ee98 +--- /dev/null ++++ b/tests/vircgroupdata/fedora-21.cgroups +@@ -0,0 +1,12 @@ ++#subsys_name hierarchy num_cgroups enabled ++cpuset 1 1 1 ++cpu 2 1 1 ++cpuacct 2 1 1 ++blkio 7 1 1 ++memory 3 1 1 ++devices 4 1 1 ++freezer 5 1 1 ++net_cls 6 1 1 ++perf_event 8 1 1 ++net_prio 6 1 1 ++hugetlb 9 1 1 +diff --git a/tests/vircgroupdata/fedora-21.self.cgroup b/tests/vircgroupdata/fedora-21.self.cgroup +new file mode 100644 +index 0000000000..4c666bd59e +--- /dev/null ++++ b/tests/vircgroupdata/fedora-21.self.cgroup +@@ -0,0 +1,10 @@ ++9:hugetlb:/ ++8:perf_event:/ ++7:blkio:/ ++6:net_cls,net_prio:/ ++5:freezer:/ ++4:devices:/ ++3:memory:/ ++2:cpu,cpuacct:/ ++1:cpuset:/ ++0:name=systemd:/ +diff --git a/tests/vircgroupdata/kubevirt.cgroups b/tests/vircgroupdata/kubevirt.cgroups +new file mode 100644 +index 0000000000..f0a7699559 +--- /dev/null ++++ b/tests/vircgroupdata/kubevirt.cgroups +@@ -0,0 +1,10 @@ ++#subsys_name hierarchy num_cgroups enabled ++cpuset 1 1 1 ++cpu 2 1 1 ++cpuacct 3 1 1 ++blkio 7 1 1 ++memory 4 1 1 ++devices 5 1 1 ++freezer 6 1 1 ++perf_event 8 1 1 ++hugetlb 9 1 1 +diff --git a/tests/vircgroupdata/kubevirt.self.cgroup b/tests/vircgroupdata/kubevirt.self.cgroup +new file mode 100644 +index 0000000000..3d0e793e5a +--- /dev/null ++++ b/tests/vircgroupdata/kubevirt.self.cgroup +@@ -0,0 +1,10 @@ ++9:hugetlb:/ ++8:perf_event:/ ++7:blkio:/ ++6:freezer:/ ++5:devices:/ ++4:memory:/ ++3:cpuacct:/ ++2:cpu:/ ++1:cpuset:/ ++0:name=openrc:/ +diff --git a/tests/vircgroupdata/no-cgroups.cgroups b/tests/vircgroupdata/no-cgroups.cgroups +new file mode 100644 +index 0000000000..3ed1d4e45e +--- /dev/null ++++ b/tests/vircgroupdata/no-cgroups.cgroups +@@ -0,0 +1,8 @@ ++#subsys_name hierarchy num_cgroups enabled ++cpuset 0 1 1 ++cpu 0 1 1 ++cpuacct 0 1 1 ++memory 0 1 1 ++devices 0 1 1 ++freezer 0 1 1 ++blkio 0 1 1 +diff --git a/tests/vircgroupdata/no-cgroups.parsed b/tests/vircgroupdata/no-cgroups.parsed +deleted file mode 100644 +index bf4eea085f..0000000000 +--- a/tests/vircgroupdata/no-cgroups.parsed ++++ /dev/null +@@ -1,10 +0,0 @@ +-cpu +-cpuacct +-cpuset +-memory +-devices +-freezer +-blkio +-net_cls +-perf_event +-name=systemd +diff --git a/tests/vircgroupdata/no-cgroups.self.cgroup b/tests/vircgroupdata/no-cgroups.self.cgroup +new file mode 100644 +index 0000000000..e69de29bb2 +diff --git a/tests/vircgroupdata/ovirt-node-6.6.cgroups b/tests/vircgroupdata/ovirt-node-6.6.cgroups +new file mode 100644 +index 0000000000..aaabf11a44 +--- /dev/null ++++ b/tests/vircgroupdata/ovirt-node-6.6.cgroups +@@ -0,0 +1,9 @@ ++#subsys_name hierarchy num_cgroups enabled ++cpuset 0 1 1 ++cpu 1 1 1 ++cpuacct 2 1 1 ++blkio 7 1 1 ++memory 3 1 1 ++devices 4 1 1 ++freezer 5 1 1 ++net_cls 6 1 1 +diff --git a/tests/vircgroupdata/ovirt-node-6.6.self.cgroup b/tests/vircgroupdata/ovirt-node-6.6.self.cgroup +new file mode 100644 +index 0000000000..dadc8155fa +--- /dev/null ++++ b/tests/vircgroupdata/ovirt-node-6.6.self.cgroup +@@ -0,0 +1,8 @@ ++7:blkio:/ ++6:net_cls:/ ++5:freezer:/ ++4:devices:/ ++3:memory:/ ++2:cpuacct:/ ++1:cpu:/ ++0:cpuset:/ +diff --git a/tests/vircgroupdata/ovirt-node-7.1.cgroups b/tests/vircgroupdata/ovirt-node-7.1.cgroups +new file mode 100644 +index 0000000000..687297ad4a +--- /dev/null ++++ b/tests/vircgroupdata/ovirt-node-7.1.cgroups +@@ -0,0 +1,11 @@ ++#subsys_name hierarchy num_cgroups enabled ++cpuset 1 1 1 ++cpu 2 1 1 ++cpuacct 2 1 1 ++blkio 7 1 1 ++memory 3 1 1 ++devices 4 1 1 ++freezer 5 1 1 ++net_cls 6 1 1 ++perf_event 8 1 1 ++hugetlb 9 1 1 +diff --git a/tests/vircgroupdata/ovirt-node-7.1.self.cgroup b/tests/vircgroupdata/ovirt-node-7.1.self.cgroup +new file mode 100644 +index 0000000000..f07e8e20f5 +--- /dev/null ++++ b/tests/vircgroupdata/ovirt-node-7.1.self.cgroup +@@ -0,0 +1,10 @@ ++9:hugetlb:/ ++8:perf_event:/ ++7:blkio:/ ++6:net_cls:/ ++5:freezer:/ ++4:devices:/ ++3:memory:/ ++2:cpu,cpuacct:/ ++1:cpuset:/ ++0:name=systemd:/ +diff --git a/tests/vircgroupdata/rhel-7.1.cgroups b/tests/vircgroupdata/rhel-7.1.cgroups +new file mode 100644 +index 0000000000..687297ad4a +--- /dev/null ++++ b/tests/vircgroupdata/rhel-7.1.cgroups +@@ -0,0 +1,11 @@ ++#subsys_name hierarchy num_cgroups enabled ++cpuset 1 1 1 ++cpu 2 1 1 ++cpuacct 2 1 1 ++blkio 7 1 1 ++memory 3 1 1 ++devices 4 1 1 ++freezer 5 1 1 ++net_cls 6 1 1 ++perf_event 8 1 1 ++hugetlb 9 1 1 +diff --git a/tests/vircgroupdata/rhel-7.1.self.cgroup b/tests/vircgroupdata/rhel-7.1.self.cgroup +new file mode 100644 +index 0000000000..f07e8e20f5 +--- /dev/null ++++ b/tests/vircgroupdata/rhel-7.1.self.cgroup +@@ -0,0 +1,10 @@ ++9:hugetlb:/ ++8:perf_event:/ ++7:blkio:/ ++6:net_cls:/ ++5:freezer:/ ++4:devices:/ ++3:memory:/ ++2:cpu,cpuacct:/ ++1:cpuset:/ ++0:name=systemd:/ +diff --git a/tests/vircgrouptest.c b/tests/vircgrouptest.c +index 6a38091a86..5031a2973d 100644 +--- a/tests/vircgrouptest.c ++++ b/tests/vircgrouptest.c +@@ -159,26 +159,37 @@ const char *linksLogind[VIR_CGROUP_CONTROLLER_LAST] = { + }; + + ++struct _detectMountsData { ++ const char *file; ++ bool fail; ++}; ++ ++ + static int + testCgroupDetectMounts(const void *args) + { + int result = -1; +- const char *file = args; ++ const struct _detectMountsData *data = args; + char *parsed = NULL; + const char *actual; + virCgroupPtr group = NULL; + virBuffer buf = VIR_BUFFER_INITIALIZER; + size_t i; + +- setenv("VIR_CGROUP_MOCK_FILENAME", file, 1); ++ setenv("VIR_CGROUP_MOCK_FILENAME", data->file, 1); + +- if (virAsprintf(&parsed, "%s/vircgroupdata/%s.parsed", abs_srcdir, file) < 0) ++ if (virAsprintf(&parsed, "%s/vircgroupdata/%s.parsed", ++ abs_srcdir, data->file) < 0) { + goto cleanup; ++ } + +- if (VIR_ALLOC(group) < 0) ++ if (virCgroupNewSelf(&group) < 0) { ++ if (data->fail) ++ result = 0; + goto cleanup; ++ } + +- if (virCgroupDetectMounts(group) < 0) ++ if (data->fail) + goto cleanup; + + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { +@@ -870,13 +881,16 @@ mymain(void) + + setenv("LIBVIRT_FAKE_ROOT_DIR", fakerootdir, 1); + +-# define DETECT_MOUNTS(file) \ ++# define DETECT_MOUNTS_FULL(file, fail) \ + do { \ ++ struct _detectMountsData data = { file, fail }; \ + if (virTestRun("Detect cgroup mounts for " file, \ + testCgroupDetectMounts, \ +- file) < 0) \ ++ &data) < 0) \ + ret = -1; \ + } while (0) ++# define DETECT_MOUNTS(file) DETECT_MOUNTS_FULL(file, false); ++# define DETECT_MOUNTS_FAIL(file) DETECT_MOUNTS_FULL(file, true); + + DETECT_MOUNTS("ovirt-node-6.6"); + DETECT_MOUNTS("ovirt-node-7.1"); +@@ -887,7 +901,7 @@ mymain(void) + DETECT_MOUNTS("cgroups2"); + DETECT_MOUNTS("cgroups3"); + DETECT_MOUNTS("all-in-one"); +- DETECT_MOUNTS("no-cgroups"); ++ DETECT_MOUNTS_FAIL("no-cgroups"); + DETECT_MOUNTS("kubevirt"); + + setenv("VIR_CGROUP_MOCK_FILENAME", "systemd", 1); +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgrouptest-introduce-initFakeFS-and-cleanupFakeFS-helpers.patch b/SOURCES/libvirt-vircgrouptest-introduce-initFakeFS-and-cleanupFakeFS-helpers.patch new file mode 100644 index 0000000..521994b --- /dev/null +++ b/SOURCES/libvirt-vircgrouptest-introduce-initFakeFS-and-cleanupFakeFS-helpers.patch @@ -0,0 +1,120 @@ +From d1c2f060ea724b4f430f9e3198676e18bf0656af Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:56 +0200 +Subject: [PATCH] vircgrouptest: introduce initFakeFS and cleanupFakeFS helpers +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We need to configure multiple env variables for each set of tests so +create helper functions to do that. + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 9b9c6528a2f867a3be79022b4f282116d2efd3cd) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + tests/vircgrouptest.c | 48 ++++++++++++++++++++++++++++++++----------- + 1 file changed, 36 insertions(+), 12 deletions(-) + +diff --git a/tests/vircgrouptest.c b/tests/vircgrouptest.c +index c4bf987ca1..1837383e61 100644 +--- a/tests/vircgrouptest.c ++++ b/tests/vircgrouptest.c +@@ -831,10 +831,10 @@ static int testCgroupGetBlkioIoDeviceServiced(const void *args ATTRIBUTE_UNUSED) + + # define FAKEROOTDIRTEMPLATE abs_builddir "/fakerootdir-XXXXXX" + +-static int +-mymain(void) ++static char * ++initFakeFS(const char *mode, ++ const char *filename) + { +- int ret = 0; + char *fakerootdir; + + if (VIR_STRDUP_QUIET(fakerootdir, FAKEROOTDIRTEMPLATE) < 0) { +@@ -849,6 +849,33 @@ mymain(void) + + setenv("LIBVIRT_FAKE_ROOT_DIR", fakerootdir, 1); + ++ if (mode) ++ setenv("VIR_CGROUP_MOCK_MODE", mode, 1); ++ ++ if (filename) ++ setenv("VIR_CGROUP_MOCK_FILENAME", filename, 1); ++ ++ return fakerootdir; ++} ++ ++static void ++cleanupFakeFS(char *fakerootdir) ++{ ++ if (getenv("LIBVIRT_SKIP_CLEANUP") == NULL) ++ virFileDeleteTree(fakerootdir); ++ ++ VIR_FREE(fakerootdir); ++ unsetenv("LIBVIRT_FAKE_ROOT_DIR"); ++ unsetenv("VIR_CGROUP_MOCK_MODE"); ++ unsetenv("VIR_CGROUP_MOCK_FILENAME"); ++} ++ ++static int ++mymain(void) ++{ ++ int ret = 0; ++ char *fakerootdir; ++ + # define DETECT_MOUNTS_FULL(file, fail) \ + do { \ + struct _detectMountsData data = { file, fail }; \ +@@ -872,7 +899,7 @@ mymain(void) + DETECT_MOUNTS_FAIL("no-cgroups"); + DETECT_MOUNTS("kubevirt"); + +- setenv("VIR_CGROUP_MOCK_FILENAME", "systemd", 1); ++ fakerootdir = initFakeFS(NULL, "systemd"); + if (virTestRun("New cgroup for self", testCgroupNewForSelf, NULL) < 0) + ret = -1; + +@@ -908,26 +935,23 @@ mymain(void) + + if (virTestRun("virCgroupGetPercpuStats works", testCgroupGetPercpuStats, NULL) < 0) + ret = -1; +- unsetenv("VIR_CGROUP_MOCK_FILENAME"); ++ cleanupFakeFS(fakerootdir); + +- setenv("VIR_CGROUP_MOCK_FILENAME", "all-in-one", 1); ++ fakerootdir = initFakeFS(NULL, "all-in-one"); + if (virTestRun("New cgroup for self (allinone)", testCgroupNewForSelfAllInOne, NULL) < 0) + ret = -1; + if (virTestRun("Cgroup available", testCgroupAvailable, (void*)0x1) < 0) + ret = -1; +- unsetenv("VIR_CGROUP_MOCK_FILENAME"); ++ cleanupFakeFS(fakerootdir); + +- setenv("VIR_CGROUP_MOCK_FILENAME", "logind", 1); ++ fakerootdir = initFakeFS(NULL, "logind"); + if (virTestRun("New cgroup for self (logind)", testCgroupNewForSelfLogind, NULL) < 0) + ret = -1; + if (virTestRun("Cgroup available", testCgroupAvailable, (void*)0x0) < 0) + ret = -1; +- unsetenv("VIR_CGROUP_MOCK_FILENAME"); ++ cleanupFakeFS(fakerootdir); + +- if (getenv("LIBVIRT_SKIP_CLEANUP") == NULL) +- virFileDeleteTree(fakerootdir); + +- VIR_FREE(fakerootdir); + + return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; + } +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgrouptest-prepare-testCgroupDetectMounts-for-cgroup-v2.patch b/SOURCES/libvirt-vircgrouptest-prepare-testCgroupDetectMounts-for-cgroup-v2.patch new file mode 100644 index 0000000..41df5c6 --- /dev/null +++ b/SOURCES/libvirt-vircgrouptest-prepare-testCgroupDetectMounts-for-cgroup-v2.patch @@ -0,0 +1,137 @@ +From 541ede1193bfb32f73d76918d755c0f3d403e5ce Mon Sep 17 00:00:00 2001 +Message-Id: <541ede1193bfb32f73d76918d755c0f3d403e5ce@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:57 +0200 +Subject: [PATCH] vircgrouptest: prepare testCgroupDetectMounts for cgroup v2 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 9f8d170dab8dc30d4563cb038e5aef393b0d1128) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + tests/vircgroupdata/all-in-one.parsed | 1 + + tests/vircgroupdata/cgroups1.parsed | 1 + + tests/vircgroupdata/cgroups2.parsed | 1 + + tests/vircgroupdata/cgroups3.parsed | 1 + + tests/vircgroupdata/fedora-18.parsed | 1 + + tests/vircgroupdata/fedora-21.parsed | 1 + + tests/vircgroupdata/kubevirt.parsed | 1 + + tests/vircgroupdata/ovirt-node-6.6.parsed | 1 + + tests/vircgroupdata/ovirt-node-7.1.parsed | 1 + + tests/vircgroupdata/rhel-7.1.parsed | 1 + + tests/vircgrouptest.c | 2 ++ + 11 files changed, 12 insertions(+) + +diff --git a/tests/vircgroupdata/all-in-one.parsed b/tests/vircgroupdata/all-in-one.parsed +index d703d08fb9..97c96e8ecd 100644 +--- a/tests/vircgroupdata/all-in-one.parsed ++++ b/tests/vircgroupdata/all-in-one.parsed +@@ -8,3 +8,4 @@ blkio /not/really/sys/fs/cgroup + net_cls + perf_event + name=systemd ++unified +diff --git a/tests/vircgroupdata/cgroups1.parsed b/tests/vircgroupdata/cgroups1.parsed +index b6916f17a1..16431aa006 100644 +--- a/tests/vircgroupdata/cgroups1.parsed ++++ b/tests/vircgroupdata/cgroups1.parsed +@@ -8,3 +8,4 @@ blkio /sys/fs/cgroup/blkio + net_cls /sys/fs/cgroup/net_cls + perf_event + name=systemd ++unified +diff --git a/tests/vircgroupdata/cgroups2.parsed b/tests/vircgroupdata/cgroups2.parsed +index 5eb2bc7bb2..d1bb0dcb7c 100644 +--- a/tests/vircgroupdata/cgroups2.parsed ++++ b/tests/vircgroupdata/cgroups2.parsed +@@ -8,3 +8,4 @@ blkio /sys/fs/cgroup/blkio + net_cls + perf_event /sys/fs/cgroup/perf_event + name=systemd ++unified +diff --git a/tests/vircgroupdata/cgroups3.parsed b/tests/vircgroupdata/cgroups3.parsed +index 2b1f3825c1..44e475c9d2 100644 +--- a/tests/vircgroupdata/cgroups3.parsed ++++ b/tests/vircgroupdata/cgroups3.parsed +@@ -8,3 +8,4 @@ blkio /sys/fs/cgroup/blkio + net_cls /sys/fs/cgroup/net_cls + perf_event /sys/fs/cgroup/perf_event + name=systemd ++unified +diff --git a/tests/vircgroupdata/fedora-18.parsed b/tests/vircgroupdata/fedora-18.parsed +index 8d5ba75c7e..662a38a9e8 100644 +--- a/tests/vircgroupdata/fedora-18.parsed ++++ b/tests/vircgroupdata/fedora-18.parsed +@@ -8,3 +8,4 @@ blkio /sys/fs/cgroup/blkio + net_cls /sys/fs/cgroup/net_cls + perf_event /sys/fs/cgroup/perf_event + name=systemd /sys/fs/cgroup/systemd ++unified +diff --git a/tests/vircgroupdata/fedora-21.parsed b/tests/vircgroupdata/fedora-21.parsed +index 3377af0382..4e447fd7bd 100644 +--- a/tests/vircgroupdata/fedora-21.parsed ++++ b/tests/vircgroupdata/fedora-21.parsed +@@ -8,3 +8,4 @@ blkio /sys/fs/cgroup/blkio + net_cls /sys/fs/cgroup/net_cls,net_prio + perf_event /sys/fs/cgroup/perf_event + name=systemd /sys/fs/cgroup/systemd ++unified +diff --git a/tests/vircgroupdata/kubevirt.parsed b/tests/vircgroupdata/kubevirt.parsed +index 6948707238..bf977f8363 100644 +--- a/tests/vircgroupdata/kubevirt.parsed ++++ b/tests/vircgroupdata/kubevirt.parsed +@@ -8,3 +8,4 @@ blkio /sys/fs/cgroup/blkio + net_cls + perf_event /sys/fs/cgroup/perf_event + name=systemd ++unified +diff --git a/tests/vircgroupdata/ovirt-node-6.6.parsed b/tests/vircgroupdata/ovirt-node-6.6.parsed +index 01bf466be6..9d10813d8c 100644 +--- a/tests/vircgroupdata/ovirt-node-6.6.parsed ++++ b/tests/vircgroupdata/ovirt-node-6.6.parsed +@@ -8,3 +8,4 @@ blkio /cgroup/blkio + net_cls /cgroup/net_cls + perf_event + name=systemd ++unified +diff --git a/tests/vircgroupdata/ovirt-node-7.1.parsed b/tests/vircgroupdata/ovirt-node-7.1.parsed +index 8d5ba75c7e..662a38a9e8 100644 +--- a/tests/vircgroupdata/ovirt-node-7.1.parsed ++++ b/tests/vircgroupdata/ovirt-node-7.1.parsed +@@ -8,3 +8,4 @@ blkio /sys/fs/cgroup/blkio + net_cls /sys/fs/cgroup/net_cls + perf_event /sys/fs/cgroup/perf_event + name=systemd /sys/fs/cgroup/systemd ++unified +diff --git a/tests/vircgroupdata/rhel-7.1.parsed b/tests/vircgroupdata/rhel-7.1.parsed +index 8d5ba75c7e..662a38a9e8 100644 +--- a/tests/vircgroupdata/rhel-7.1.parsed ++++ b/tests/vircgroupdata/rhel-7.1.parsed +@@ -8,3 +8,4 @@ blkio /sys/fs/cgroup/blkio + net_cls /sys/fs/cgroup/net_cls + perf_event /sys/fs/cgroup/perf_event + name=systemd /sys/fs/cgroup/systemd ++unified +diff --git a/tests/vircgrouptest.c b/tests/vircgrouptest.c +index 1837383e61..b66682e6c8 100644 +--- a/tests/vircgrouptest.c ++++ b/tests/vircgrouptest.c +@@ -176,6 +176,8 @@ testCgroupDetectMounts(const void *args) + virCgroupControllerTypeToString(i), + NULLSTR(group->legacy[i].mountPoint)); + } ++ virBufferAsprintf(&buf, "%-12s %s\n", ++ "unified", NULLSTR(group->unified.mountPoint)); + if (virBufferCheckError(&buf) < 0) + goto cleanup; + +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgrouptest-prepare-validateCgroup-for-cgroupv2.patch b/SOURCES/libvirt-vircgrouptest-prepare-validateCgroup-for-cgroupv2.patch new file mode 100644 index 0000000..fe04791 --- /dev/null +++ b/SOURCES/libvirt-vircgrouptest-prepare-validateCgroup-for-cgroupv2.patch @@ -0,0 +1,150 @@ +From f186ff31027a18b0568cf8c31da4fbffb7e3ead7 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:08:00 +0200 +Subject: [PATCH] vircgrouptest: prepare validateCgroup for cgroupv2 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 2a3df5fac52abb0d414d221a5da3bb957675a094) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + tests/vircgrouptest.c | 53 +++++++++++++++++++++++++++++++++++-------- + 1 file changed, 44 insertions(+), 9 deletions(-) + +diff --git a/tests/vircgrouptest.c b/tests/vircgrouptest.c +index aeb2840823..87f8fa7e67 100644 +--- a/tests/vircgrouptest.c ++++ b/tests/vircgrouptest.c +@@ -44,7 +44,10 @@ static int validateCgroup(virCgroupPtr cgroup, + const char *expectPath, + const char **expectMountPoint, + const char **expectLinkPoint, +- const char **expectPlacement) ++ const char **expectPlacement, ++ const char *expectUnifiedMountPoint, ++ const char *expectUnifiedPlacement, ++ unsigned int expectUnifiedControllers) + { + size_t i; + +@@ -81,6 +84,38 @@ static int validateCgroup(virCgroupPtr cgroup, + } + } + ++ if (STRNEQ_NULLABLE(expectUnifiedMountPoint, ++ cgroup->unified.mountPoint)) { ++ fprintf(stderr, "Wrong mount '%s', expected '%s' for 'unified'\n", ++ cgroup->unified.mountPoint, ++ expectUnifiedMountPoint); ++ return -1; ++ } ++ if (STRNEQ_NULLABLE(expectUnifiedPlacement, ++ cgroup->unified.placement)) { ++ fprintf(stderr, "Wrong placement '%s', expected '%s' for 'unified'\n", ++ cgroup->unified.placement, ++ expectUnifiedPlacement); ++ return -1; ++ } ++ if (expectUnifiedControllers != cgroup->unified.controllers) { ++ for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { ++ int type = 1 << i; ++ if ((expectUnifiedControllers & type) != (cgroup->unified.controllers & type)) { ++ const char *typeStr = virCgroupControllerTypeToString(i); ++ if (expectUnifiedControllers & type) { ++ fprintf(stderr, "expected controller '%s' for 'unified', " ++ "but it's missing\n", typeStr); ++ } else { ++ fprintf(stderr, "existing controller '%s' for 'unified', " ++ "but it's not expected\n", typeStr); ++ } ++ } ++ ++ } ++ return -1; ++ } ++ + return 0; + } + +@@ -216,7 +251,7 @@ static int testCgroupNewForSelf(const void *args ATTRIBUTE_UNUSED) + goto cleanup; + } + +- ret = validateCgroup(cgroup, "", mountsFull, links, placement); ++ ret = validateCgroup(cgroup, "", mountsFull, links, placement, NULL, NULL, 0); + + cleanup: + virCgroupFree(&cgroup); +@@ -295,14 +330,14 @@ static int testCgroupNewForPartition(const void *args ATTRIBUTE_UNUSED) + fprintf(stderr, "Cannot create /virtualmachines cgroup: %d\n", -rv); + goto cleanup; + } +- ret = validateCgroup(cgroup, "/virtualmachines.partition", mountsSmall, links, placementSmall); ++ ret = validateCgroup(cgroup, "/virtualmachines.partition", mountsSmall, links, placementSmall, NULL, NULL, 0); + virCgroupFree(&cgroup); + + if ((rv = virCgroupNewPartition("/virtualmachines", true, -1, &cgroup)) != 0) { + fprintf(stderr, "Cannot create /virtualmachines cgroup: %d\n", -rv); + goto cleanup; + } +- ret = validateCgroup(cgroup, "/virtualmachines.partition", mountsFull, links, placementFull); ++ ret = validateCgroup(cgroup, "/virtualmachines.partition", mountsFull, links, placementFull, NULL, NULL, 0); + + cleanup: + virCgroupFree(&cgroup); +@@ -352,7 +387,7 @@ static int testCgroupNewForPartitionNested(const void *args ATTRIBUTE_UNUSED) + } + + ret = validateCgroup(cgroup, "/deployment.partition/production.partition", +- mountsFull, links, placementFull); ++ mountsFull, links, placementFull, NULL, NULL, 0); + + cleanup: + virCgroupFree(&cgroup); +@@ -408,7 +443,7 @@ static int testCgroupNewForPartitionNestedDeep(const void *args ATTRIBUTE_UNUSED + } + + ret = validateCgroup(cgroup, "/user/berrange.user/production.partition", +- mountsFull, links, placementFull); ++ mountsFull, links, placementFull, NULL, NULL, 0); + + cleanup: + virCgroupFree(&cgroup); +@@ -444,7 +479,7 @@ static int testCgroupNewForPartitionDomain(const void *args ATTRIBUTE_UNUSED) + goto cleanup; + } + +- ret = validateCgroup(domaincgroup, "/production.partition/foo.libvirt-lxc", mountsFull, links, placement); ++ ret = validateCgroup(domaincgroup, "/production.partition/foo.libvirt-lxc", mountsFull, links, placement, NULL, NULL, 0); + + cleanup: + virCgroupFree(&partitioncgroup); +@@ -495,7 +530,7 @@ static int testCgroupNewForPartitionDomainEscaped(const void *args ATTRIBUTE_UNU + * since our fake /proc/cgroups pretends this controller + * isn't compiled into the kernel + */ +- ret = validateCgroup(domaincgroup, "/_cgroup.evil/net_cls.evil/__evil.evil/_cpu.foo.libvirt-lxc", mountsFull, links, placement); ++ ret = validateCgroup(domaincgroup, "/_cgroup.evil/net_cls.evil/__evil.evil/_cpu.foo.libvirt-lxc", mountsFull, links, placement, NULL, NULL, 0); + + cleanup: + virCgroupFree(&partitioncgroup3); +@@ -524,7 +559,7 @@ static int testCgroupNewForSelfAllInOne(const void *args ATTRIBUTE_UNUSED) + goto cleanup; + } + +- ret = validateCgroup(cgroup, "", mountsAllInOne, linksAllInOne, placement); ++ ret = validateCgroup(cgroup, "", mountsAllInOne, linksAllInOne, placement, NULL, NULL, 0); + + cleanup: + virCgroupFree(&cgroup); +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroupv1-fix-build-on-non-linux-OSes.patch b/SOURCES/libvirt-vircgroupv1-fix-build-on-non-linux-OSes.patch new file mode 100644 index 0000000..b25993f --- /dev/null +++ b/SOURCES/libvirt-vircgroupv1-fix-build-on-non-linux-OSes.patch @@ -0,0 +1,94 @@ +From 2b27d54de68a4581a9b46fe5c399b45c0014fcbd Mon Sep 17 00:00:00 2001 +Message-Id: <2b27d54de68a4581a9b46fe5c399b45c0014fcbd@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:07:10 +0200 +Subject: [PATCH] vircgroupv1: fix build on non-linux OSes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Cgroups are linux specific and we need to make sure that the code is +compiled only on linux. On different OSes it fails the compilation: + +../../src/util/vircgroupv1.c:65:19: error: variable has incomplete type 'struct mntent' + struct mntent entry; + ^ +../../src/util/vircgroupv1.c:65:12: note: forward declaration of 'struct mntent' + struct mntent entry; + ^ +../../src/util/vircgroupv1.c:74:12: error: implicit declaration of function 'getmntent_r' is invalid in C99 [-Werror,-Wimplicit-function-declaration] + while (getmntent_r(mounts, &entry, buf, sizeof(buf)) != NULL) { + ^ +../../src/util/vircgroupv1.c:814:39: error: use of undeclared identifier 'MS_NOSUID' + if (mount("tmpfs", root, "tmpfs", MS_NOSUID|MS_NODEV|MS_NOEXEC, opts) < 0) { + ^ +../../src/util/vircgroupv1.c:814:49: error: use of undeclared identifier 'MS_NODEV' + if (mount("tmpfs", root, "tmpfs", MS_NOSUID|MS_NODEV|MS_NOEXEC, opts) < 0) { + ^ +../../src/util/vircgroupv1.c:814:58: error: use of undeclared identifier 'MS_NOEXEC' + if (mount("tmpfs", root, "tmpfs", MS_NOSUID|MS_NODEV|MS_NOEXEC, opts) < 0) { + ^ +../../src/util/vircgroupv1.c:841:65: error: use of undeclared identifier 'MS_BIND' + if (mount(src, group->legacy[i].mountPoint, "none", MS_BIND, + ^ + +Reviewed-by: Ján Tomko +Signed-off-by: Pavel Hrdina +(cherry picked from commit 0615c8436ac868889454bee2781b6c9993518597) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv1.c | 20 +++++++++++++++----- + 1 file changed, 15 insertions(+), 5 deletions(-) + +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 482615f3c8..97d108d3ac 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -20,13 +20,11 @@ + */ + #include + +-#if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R ++#ifdef __linux__ + # include +-#endif +-#include +-#if defined HAVE_SYS_MOUNT_H ++# include + # include +-#endif ++#endif /* __linux__ */ + + #include "internal.h" + +@@ -56,6 +54,8 @@ VIR_ENUM_IMPL(virCgroupV1Controller, VIR_CGROUP_CONTROLLER_LAST, + "name=systemd"); + + ++#ifdef __linux__ ++ + /* We're looking for at least one 'cgroup' fs mount, + * which is *not* a named mount. */ + static bool +@@ -2100,3 +2100,13 @@ virCgroupV1Register(void) + { + virCgroupBackendRegister(&virCgroupV1Backend); + } ++ ++#else /* !__linux__ */ ++ ++void ++virCgroupV1Register(void) ++{ ++ VIR_INFO("Control groups not supported on this platform"); ++} ++ ++#endif /* !__linux__ */ +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroupv2-fix-abort-in-VIR_AUTOFREE.patch b/SOURCES/libvirt-vircgroupv2-fix-abort-in-VIR_AUTOFREE.patch new file mode 100644 index 0000000..105f2f3 --- /dev/null +++ b/SOURCES/libvirt-vircgroupv2-fix-abort-in-VIR_AUTOFREE.patch @@ -0,0 +1,65 @@ +From c627fa58c17960e5eed999049bf966b5ea952c3b Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Fri, 30 Aug 2019 16:35:33 +0200 +Subject: [PATCH] vircgroupv2: fix abort in VIR_AUTOFREE + +Introduced by commit that +tried to fix an issue where we would fail to parse values from files. + +We cannot change the original pointer that is going to be used by +VIR_AUTOFREE. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1747440 + +Signed-off-by: Pavel Hrdina +Acked-by: Peter Krempa +(cherry picked from commit 9a99b01f8d3b2be491f9f8412c6f894d30d7e2fe) +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Jiri Denemark +--- + src/util/vircgroupv2.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index e31a2d1121..e7b9093754 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -848,6 +848,7 @@ virCgroupV2GetBlkioDeviceWeight(virCgroupPtr group, + VIR_AUTOFREE(char *) path = NULL; + VIR_AUTOFREE(char *) str = NULL; + VIR_AUTOFREE(char *) value = NULL; ++ char *tmp; + + if (virCgroupV2PathOfController(group, VIR_CGROUP_CONTROLLER_BLKIO, + "io.weight", &path) < 0) { +@@ -868,7 +869,7 @@ virCgroupV2GetBlkioDeviceWeight(virCgroupPtr group, + + if (!str) { + *weight = 0; +- } else if (virStrToLong_ui(str, &str, 10, weight) < 0) { ++ } else if (virStrToLong_ui(str, &tmp, 10, weight) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to parse '%s' as an integer"), + str); +@@ -1575,6 +1576,7 @@ virCgroupV2GetCpuCfsQuota(virCgroupPtr group, + long long *cfs_quota) + { + VIR_AUTOFREE(char *) str = NULL; ++ char *tmp; + + if (virCgroupGetValueStr(group, VIR_CGROUP_CONTROLLER_CPU, + "cpu.max", &str) < 0) { +@@ -1586,7 +1588,7 @@ virCgroupV2GetCpuCfsQuota(virCgroupPtr group, + return 0; + } + +- if (virStrToLong_ll(str, &str, 10, cfs_quota) < 0) { ++ if (virStrToLong_ll(str, &tmp, 10, cfs_quota) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to parse value '%s' from cpu.max."), str); + return -1; +-- +2.23.0 + diff --git a/SOURCES/libvirt-vircgroupv2-fix-parsing-multiple-values-in-single-file.patch b/SOURCES/libvirt-vircgroupv2-fix-parsing-multiple-values-in-single-file.patch new file mode 100644 index 0000000..c76eb62 --- /dev/null +++ b/SOURCES/libvirt-vircgroupv2-fix-parsing-multiple-values-in-single-file.patch @@ -0,0 +1,105 @@ +From ae178683071d3948d1d1da6205726a3e24923b45 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Wed, 21 Aug 2019 09:42:34 +0200 +Subject: [PATCH] vircgroupv2: fix parsing multiple values in single file + +Our virStrToLong* helpers converts string to integers where it wraps +strtol standard function. After the conversion happens and there are +some remaining invalid characters our helpers will fail if the second +argument is NULL. + +We need to pass pointer to string in cases where there are multiple +values in a single file. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1741825 + +Signed-off-by: Pavel Hrdina +Reviewed-by: Jiri Denemark +(cherry picked from commit c854e0bd33c7a5afb04a36465bf04f861b2efef5) +Signed-off-by: Pavel Hrdina +Message-Id: <49fe97f452eb4247040b1f322d348a3eea931efe.1566373284.git.phrdina@redhat.com> +Reviewed-by: Jiri Denemark +--- + src/util/vircgroupv2.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 9ae47e775e..e129686a52 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -672,7 +672,7 @@ virCgroupV2GetBlkioWeight(virCgroupPtr group, + tmp = value; + } + +- if (virStrToLong_ui(tmp, NULL, 10, weight) < 0) { ++ if (virStrToLong_ui(tmp, &tmp, 10, weight) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to parse '%s' as an integer"), + tmp); +@@ -868,7 +868,7 @@ virCgroupV2GetBlkioDeviceWeight(virCgroupPtr group, + + if (!str) { + *weight = 0; +- } else if (virStrToLong_ui(str, NULL, 10, weight) < 0) { ++ } else if (virStrToLong_ui(str, &str, 10, weight) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to parse '%s' as an integer"), + str); +@@ -938,7 +938,7 @@ virCgroupV2GetBlkioDeviceReadIops(virCgroupPtr group, + + if (STREQLEN(tmp, "max", 3)) { + *riops = 0; +- } else if (virStrToLong_ui(tmp, NULL, 10, riops) < 0) { ++ } else if (virStrToLong_ui(tmp, &tmp, 10, riops) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to parse '%s' as an integer"), + str); +@@ -1009,7 +1009,7 @@ virCgroupV2GetBlkioDeviceWriteIops(virCgroupPtr group, + + if (STREQLEN(tmp, "max", 3)) { + *wiops = 0; +- } else if (virStrToLong_ui(tmp, NULL, 10, wiops) < 0) { ++ } else if (virStrToLong_ui(tmp, &tmp, 10, wiops) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to parse '%s' as an integer"), + str); +@@ -1080,7 +1080,7 @@ virCgroupV2GetBlkioDeviceReadBps(virCgroupPtr group, + + if (STREQLEN(tmp, "max", 3)) { + *rbps = 0; +- } else if (virStrToLong_ull(tmp, NULL, 10, rbps) < 0) { ++ } else if (virStrToLong_ull(tmp, &tmp, 10, rbps) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to parse '%s' as an integer"), + str); +@@ -1151,7 +1151,7 @@ virCgroupV2GetBlkioDeviceWriteBps(virCgroupPtr group, + + if (STREQLEN(tmp, "max", 3)) { + *wbps = 0; +- } else if (virStrToLong_ull(tmp, NULL, 10, wbps) < 0) { ++ } else if (virStrToLong_ull(tmp, &tmp, 10, wbps) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to parse '%s' as an integer"), + str); +@@ -1534,7 +1534,7 @@ virCgroupV2GetCpuCfsPeriod(virCgroupPtr group, + return -1; + } + +- if (virStrToLong_ull(tmp, NULL, 10, cfs_period) < 0) { ++ if (virStrToLong_ull(tmp, &tmp, 10, cfs_period) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to parse value '%s' from cpu.max."), str); + return -1; +@@ -1584,7 +1584,7 @@ virCgroupV2GetCpuCfsQuota(virCgroupPtr group, + if (STREQLEN(str, "max", 3)) + *cfs_quota = ULLONG_MAX / 1000; + +- if (virStrToLong_ll(str, NULL, 10, cfs_quota) < 0) { ++ if (virStrToLong_ll(str, &str, 10, cfs_quota) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to parse value '%s' from cpu.max."), str); + return -1; +-- +2.23.0 + diff --git a/SOURCES/libvirt-vircgroupv2-fix-setting-cpu.max-period.patch b/SOURCES/libvirt-vircgroupv2-fix-setting-cpu.max-period.patch new file mode 100644 index 0000000..c07b46e --- /dev/null +++ b/SOURCES/libvirt-vircgroupv2-fix-setting-cpu.max-period.patch @@ -0,0 +1,42 @@ +From 164b5885c6916d39a71a4778da9782c9dc6cadf0 Mon Sep 17 00:00:00 2001 +Message-Id: <164b5885c6916d39a71a4778da9782c9dc6cadf0@dist-git> +From: Pavel Hrdina +Date: Fri, 6 Sep 2019 09:29:41 +0200 +Subject: [PATCH] vircgroupv2: fix setting cpu.max period + +When we set cpu.max period we need to parse the cpu.max file first as +it contains both quota and period values separated by space. When only +a single number is written to that file it will set quota. However, +in order to change period we need to write both values. + +The code was prepared for that but mistakenly used new line to end the +string with the first value. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749227 + +Signed-off-by: Pavel Hrdina +Reviewed-by: Erik Skultety +(cherry picked from commit 0bd4ad193d8ba7f0104f4739f19f2731e7cf9f56) +Signed-off-by: Pavel Hrdina +Message-Id: <3a1021b39f7b5add388e98eae4caa63975b60fc3.1567754949.git.phrdina@redhat.com> +Reviewed-by: Erik Skultety +--- + src/util/vircgroupv2.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index e7b9093754..13a51e67a4 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -1507,7 +1507,7 @@ virCgroupV2SetCpuCfsPeriod(virCgroupPtr group, + _("Invalid 'cpu.max' data.")); + return -1; + } +- *tmp = '\n'; ++ *tmp = '\0'; + + if (virAsprintf(&value, "%s %llu", str, cfs_period) < 0) + return -1; +-- +2.23.0 + diff --git a/SOURCES/libvirt-vircgroupv2-fix-virCgroupV2GetCpuCfsQuota-for-max-value.patch b/SOURCES/libvirt-vircgroupv2-fix-virCgroupV2GetCpuCfsQuota-for-max-value.patch new file mode 100644 index 0000000..06680d6 --- /dev/null +++ b/SOURCES/libvirt-vircgroupv2-fix-virCgroupV2GetCpuCfsQuota-for-max-value.patch @@ -0,0 +1,39 @@ +From dd46b194155d91d44d8c10f5bca48a5b4d296f63 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Wed, 21 Aug 2019 09:42:35 +0200 +Subject: [PATCH] vircgroupv2: fix virCgroupV2GetCpuCfsQuota for "max" value + +If the first value in cpu.max is "max" return from function. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1741837 + +Signed-off-by: Pavel Hrdina +Reviewed-by: Jiri Denemark +(cherry picked from commit 23689cddd4542041cdfa3416705993d373033961) +Signed-off-by: Pavel Hrdina +Message-Id: <287fbea9b44a5f7263505dc5fbd72d1bf2692bc6.1566373284.git.phrdina@redhat.com> +Reviewed-by: Jiri Denemark +--- + src/util/vircgroupv2.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index e129686a52..e31a2d1121 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -1581,8 +1581,10 @@ virCgroupV2GetCpuCfsQuota(virCgroupPtr group, + return -1; + } + +- if (STREQLEN(str, "max", 3)) ++ if (STREQLEN(str, "max", 3)) { + *cfs_quota = ULLONG_MAX / 1000; ++ return 0; ++ } + + if (virStrToLong_ll(str, &str, 10, cfs_quota) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, +-- +2.23.0 + diff --git a/SOURCES/libvirt-vircgroupv2-fix-virCgroupV2ValidateMachineGroup.patch b/SOURCES/libvirt-vircgroupv2-fix-virCgroupV2ValidateMachineGroup.patch new file mode 100644 index 0000000..0b7339d --- /dev/null +++ b/SOURCES/libvirt-vircgroupv2-fix-virCgroupV2ValidateMachineGroup.patch @@ -0,0 +1,47 @@ +From 9193cc6a2395f2f26bcae2d990f78b2860b08ae9 Mon Sep 17 00:00:00 2001 +Message-Id: <9193cc6a2395f2f26bcae2d990f78b2860b08ae9@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:08:10 +0200 +Subject: [PATCH] vircgroupv2: fix virCgroupV2ValidateMachineGroup +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When libvirt is reconnecting to running domain that uses cgroup v2 +the QEMU process reports cgroup for the emulator directory because the +main thread is in that cgroup. We need to remove the "/emulator" part +in order to match with the root cgroup directory name for that domain. + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 634bd528cb194439f0bea0815f579d0b0c1b1a92) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <963bff76d79df2da95b1881fc9b7329be7b59d52.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 5652fcfffb..8658454d8b 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -121,6 +121,13 @@ virCgroupV2ValidateMachineGroup(virCgroupPtr group, + + if (!(tmp = strrchr(group->unified.placement, '/'))) + return false; ++ ++ if (STREQ(tmp, "/emulator")) { ++ *tmp = '\0'; ++ ++ if (!(tmp = strrchr(group->unified.placement, '/'))) ++ return false; ++ } + tmp++; + + if (STRNEQ(tmp, partmachinename) && +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircgroupv2-store-enabled-controllers.patch b/SOURCES/libvirt-vircgroupv2-store-enabled-controllers.patch new file mode 100644 index 0000000..86a974a --- /dev/null +++ b/SOURCES/libvirt-vircgroupv2-store-enabled-controllers.patch @@ -0,0 +1,79 @@ +From 6d526969ab72e7c35b988a7154d8343001a05208 Mon Sep 17 00:00:00 2001 +Message-Id: <6d526969ab72e7c35b988a7154d8343001a05208@dist-git> +From: Pavel Hrdina +Date: Thu, 25 Jul 2019 13:37:02 +0200 +Subject: [PATCH] vircgroupv2: store enabled controllers +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In cgroups v2 when a new group is created by default no controller is +enabled so the detection code will not detect any controllers. + +When enabling the controllers we should also store them for the group. + +Signed-off-by: Pavel Hrdina +Acked-by: Peter Krempa +(cherry picked from commit 56fdf3f025207a550726767e3f0ec1f290603ba4) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <3cef886d4257a746e5a7182246d5457664d8bcec.1564054553.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircgroupv2.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 7b3cd64cc5..9ae47e775e 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -364,7 +364,8 @@ virCgroupV2PathOfController(virCgroupPtr group, + * 0 on success + */ + static int +-virCgroupV2EnableController(virCgroupPtr parent, ++virCgroupV2EnableController(virCgroupPtr group, ++ virCgroupPtr parent, + int controller, + bool report) + { +@@ -390,6 +391,8 @@ virCgroupV2EnableController(virCgroupPtr parent, + return -2; + } + ++ group->unified.controllers |= 1 << controller; ++ + return 0; + } + +@@ -431,14 +434,14 @@ virCgroupV2MakeGroup(virCgroupPtr parent ATTRIBUTE_UNUSED, + } + + if (virCgroupV2HasController(parent, VIR_CGROUP_CONTROLLER_CPU) && +- virCgroupV2EnableController(parent, ++ virCgroupV2EnableController(group, parent, + VIR_CGROUP_CONTROLLER_CPU, + true) < 0) { + return -1; + } + + if (virCgroupV2HasController(parent, VIR_CGROUP_CONTROLLER_CPUSET) && +- virCgroupV2EnableController(parent, ++ virCgroupV2EnableController(group, parent, + VIR_CGROUP_CONTROLLER_CPUSET, + true) < 0) { + return -1; +@@ -455,7 +458,7 @@ virCgroupV2MakeGroup(virCgroupPtr parent ATTRIBUTE_UNUSED, + if (i == VIR_CGROUP_CONTROLLER_CPUACCT) + continue; + +- rc = virCgroupV2EnableController(parent, i, false); ++ rc = virCgroupV2EnableController(group, parent, i, false); + if (rc < 0) { + if (rc == -2) { + virResetLastError(); +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircommand-Separate-mass-FD-closing-into-a-function.patch b/SOURCES/libvirt-vircommand-Separate-mass-FD-closing-into-a-function.patch new file mode 100644 index 0000000..eea098c --- /dev/null +++ b/SOURCES/libvirt-vircommand-Separate-mass-FD-closing-into-a-function.patch @@ -0,0 +1,111 @@ +From 0f27acb41229aa29d539f1975c36c78f75fdf11c Mon Sep 17 00:00:00 2001 +Message-Id: <0f27acb41229aa29d539f1975c36c78f75fdf11c@dist-git> +From: Michal Privoznik +Date: Tue, 30 Jul 2019 15:30:53 +0200 +Subject: [PATCH] vircommand: Separate mass FD closing into a function +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +I will optimize this code a bit in the next commit. But for that +it is better if the code lives in a separate function. + +Signed-off-by: Michal Privoznik +Reviewed-by: Ján Tomko +(cherry picked from commit c1a9bfbbba48fea44fdfbe532e084c5323c9c9b3) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1721434 + +Signed-off-by: Michal Privoznik +Message-Id: <6de04910a1dc7c2e5554983b504b1a9932411a60.1564493409.git.mprivozn@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/vircommand.c | 52 ++++++++++++++++++++++++++++--------------- + 1 file changed, 34 insertions(+), 18 deletions(-) + +diff --git a/src/util/vircommand.c b/src/util/vircommand.c +index d328431373..8ae9a952a3 100644 +--- a/src/util/vircommand.c ++++ b/src/util/vircommand.c +@@ -491,6 +491,37 @@ virExecCommon(virCommandPtr cmd, gid_t *groups, int ngroups) + return ret; + } + ++static int ++virCommandMassClose(virCommandPtr cmd, ++ int childin, ++ int childout, ++ int childerr) ++{ ++ int openmax = sysconf(_SC_OPEN_MAX); ++ int fd; ++ int tmpfd; ++ ++ if (openmax < 0) { ++ virReportSystemError(errno, "%s", ++ _("sysconf(_SC_OPEN_MAX) failed")); ++ return -1; ++ } ++ ++ for (fd = 3; fd < openmax; fd++) { ++ if (fd == childin || fd == childout || fd == childerr) ++ continue; ++ if (!virCommandFDIsSet(cmd, fd)) { ++ tmpfd = fd; ++ VIR_MASS_CLOSE(tmpfd); ++ } else if (virSetInherit(fd, true) < 0) { ++ virReportSystemError(errno, _("failed to preserve fd %d"), fd); ++ return -1; ++ } ++ } ++ ++ return 0; ++} ++ + /* + * virExec: + * @cmd virCommandPtr containing all information about the program to +@@ -500,13 +531,12 @@ static int + virExec(virCommandPtr cmd) + { + pid_t pid; +- int null = -1, fd, openmax; ++ int null = -1; + int pipeout[2] = {-1, -1}; + int pipeerr[2] = {-1, -1}; + int childin = cmd->infd; + int childout = -1; + int childerr = -1; +- int tmpfd; + VIR_AUTOFREE(char *) binarystr = NULL; + const char *binary = NULL; + int ret; +@@ -612,23 +642,9 @@ virExec(virCommandPtr cmd) + if (cmd->mask) + umask(cmd->mask); + ret = EXIT_CANCELED; +- openmax = sysconf(_SC_OPEN_MAX); +- if (openmax < 0) { +- virReportSystemError(errno, "%s", +- _("sysconf(_SC_OPEN_MAX) failed")); ++ ++ if (virCommandMassClose(cmd, childin, childout, childerr) < 0) + goto fork_error; +- } +- for (fd = 3; fd < openmax; fd++) { +- if (fd == childin || fd == childout || fd == childerr) +- continue; +- if (!virCommandFDIsSet(cmd, fd)) { +- tmpfd = fd; +- VIR_MASS_CLOSE(tmpfd); +- } else if (virSetInherit(fd, true) < 0) { +- virReportSystemError(errno, _("failed to preserve fd %d"), fd); +- goto fork_error; +- } +- } + + if (prepareStdFd(childin, STDIN_FILENO) < 0) { + virReportSystemError(errno, +-- +2.22.0 + diff --git a/SOURCES/libvirt-vircpuhost-Add-support-for-reading-MSRs.patch b/SOURCES/libvirt-vircpuhost-Add-support-for-reading-MSRs.patch new file mode 100644 index 0000000..1f5ccce --- /dev/null +++ b/SOURCES/libvirt-vircpuhost-Add-support-for-reading-MSRs.patch @@ -0,0 +1,155 @@ +From 6094ea6111dd57274b6037e76f662a06b8e5c9d1 Mon Sep 17 00:00:00 2001 +Message-Id: <6094ea6111dd57274b6037e76f662a06b8e5c9d1@dist-git> +From: Jiri Denemark +Date: Fri, 21 Jun 2019 09:25:43 +0200 +Subject: [PATCH] vircpuhost: Add support for reading MSRs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The new virHostCPUGetMSR internal API will try to read the MSR from +/dev/cpu/0/msr and if it is not possible (the device does not exist or +libvirt is running unprivileged), it will fallback to asking KVM for the +MSR using KVM_GET_MSRS ioctl. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit df4b46737f43a1a67f9b5de2840213a1bd2b3cce) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Conflicts: + src/util/virhostcpu.h + - different header file guard symbol + +Signed-off-by: Jiri Denemark +Message-Id: <0d4c18704c435cccc2b18ebd55f4f914caf05d13.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/libvirt_private.syms | 1 + + src/util/virhostcpu.c | 80 ++++++++++++++++++++++++++++++++++++++++ + src/util/virhostcpu.h | 3 ++ + 3 files changed, 84 insertions(+) + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 347667b17c..9ebc5384fb 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -1974,6 +1974,7 @@ virHostCPUGetInfo; + virHostCPUGetKVMMaxVCPUs; + virHostCPUGetMap; + virHostCPUGetMicrocodeVersion; ++virHostCPUGetMSR; + virHostCPUGetOnline; + virHostCPUGetOnlineBitmap; + virHostCPUGetPresentBitmap; +diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c +index effe04ca3a..d0c47faa18 100644 +--- a/src/util/virhostcpu.c ++++ b/src/util/virhostcpu.c +@@ -64,6 +64,7 @@ + VIR_LOG_INIT("util.hostcpu"); + + #define KVM_DEVICE "/dev/kvm" ++#define MSR_DEVICE "/dev/cpu/0/msr" + + + #if defined(__FreeBSD__) || defined(__APPLE__) +@@ -1266,3 +1267,82 @@ virHostCPUGetMicrocodeVersion(void) + } + + #endif /* __linux__ */ ++ ++ ++#if HAVE_LINUX_KVM_H && defined(KVM_GET_MSRS) ++static int ++virHostCPUGetMSRFromKVM(unsigned long index, ++ uint64_t *result) ++{ ++ VIR_AUTOCLOSE fd = -1; ++ struct { ++ struct kvm_msrs header; ++ struct kvm_msr_entry entry; ++ } msr = { ++ .header = { .nmsrs = 1 }, ++ .entry = { .index = index }, ++ }; ++ ++ if ((fd = open(KVM_DEVICE, O_RDONLY)) < 0) { ++ virReportSystemError(errno, _("Unable to open %s"), KVM_DEVICE); ++ return -1; ++ } ++ ++ if (ioctl(fd, KVM_GET_MSRS, &msr) < 0) { ++ VIR_DEBUG("Cannot get MSR 0x%lx from KVM", index); ++ return 1; ++ } ++ ++ *result = msr.entry.data; ++ return 0; ++} ++ ++#else ++ ++static int ++virHostCPUGetMSRFromKVM(unsigned long index ATTRIBUTE_UNUSED, ++ uint64_t *result ATTRIBUTE_UNUSED) ++{ ++ virReportSystemError(ENOSYS, "%s", ++ _("Reading MSRs via KVM is not supported on this platform")); ++ return -1; ++} ++#endif /* HAVE_LINUX_KVM_H && defined(KVM_GET_MSRS) */ ++ ++ ++/* ++ * Returns 0 on success, ++ * 1 when the MSR is not supported by the host CPU, ++* -1 on error. ++ */ ++int ++virHostCPUGetMSR(unsigned long index, ++ uint64_t *msr) ++{ ++ VIR_AUTOCLOSE fd = -1; ++ char ebuf[1024]; ++ ++ *msr = 0; ++ ++ if ((fd = open(MSR_DEVICE, O_RDONLY)) < 0) { ++ VIR_DEBUG("Unable to open %s: %s", ++ MSR_DEVICE, virStrerror(errno, ebuf, sizeof(ebuf))); ++ } else { ++ int rc = pread(fd, msr, sizeof(*msr), index); ++ ++ if (rc == sizeof(*msr)) ++ return 0; ++ ++ if (rc < 0 && errno == EIO) { ++ VIR_DEBUG("CPU does not support MSR 0x%lx", index); ++ return 1; ++ } ++ ++ VIR_DEBUG("Cannot read MSR 0x%lx from %s: %s", ++ index, MSR_DEVICE, virStrerror(errno, ebuf, sizeof(ebuf))); ++ } ++ ++ VIR_DEBUG("Falling back to KVM ioctl"); ++ ++ return virHostCPUGetMSRFromKVM(index, msr); ++} +diff --git a/src/util/virhostcpu.h b/src/util/virhostcpu.h +index f9f3359288..e705623d4f 100644 +--- a/src/util/virhostcpu.h ++++ b/src/util/virhostcpu.h +@@ -68,4 +68,7 @@ int virHostCPUGetOnline(unsigned int cpu, bool *online); + + unsigned int virHostCPUGetMicrocodeVersion(void); + ++int virHostCPUGetMSR(unsigned long index, ++ uint64_t *msr); ++ + #endif /* __VIR_HOSTCPU_H__*/ +-- +2.22.0 + diff --git a/SOURCES/libvirt-virdbus-Grab-a-ref-as-long-as-the-while-loop-is-executed.patch b/SOURCES/libvirt-virdbus-Grab-a-ref-as-long-as-the-while-loop-is-executed.patch new file mode 100644 index 0000000..499c3d4 --- /dev/null +++ b/SOURCES/libvirt-virdbus-Grab-a-ref-as-long-as-the-while-loop-is-executed.patch @@ -0,0 +1,49 @@ +From 2b04ec4cfae111f315514395030ab1106b6370da Mon Sep 17 00:00:00 2001 +Message-Id: <2b04ec4cfae111f315514395030ab1106b6370da@dist-git> +From: Marc Hartmayer +Date: Fri, 16 Aug 2019 16:01:55 +0200 +Subject: [PATCH] virdbus: Grab a ref as long as the while loop is executed +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Grab a ref for info->bus (a DBus connection) as long as the while loop +is running. With the grabbed reference it is ensured that info->bus +isn't freed as long as the while loop is executed. This is necessary +as it's allowed to drop the last ref for the bus connection in a +handler. + +There was already a bug of this kind in libdbus itself: +https://bugs.freedesktop.org/show_bug.cgi?id=15635. + +Signed-off-by: Marc Hartmayer +Reviewed-by: Boris Fiuczynski +Reviewed-by: John Ferlan +(cherry picked from commit 6707ffd11c1d8940ca7dfa7aaef707a60ef6756e) + +RHEL-8.1.0: https://bugzilla.redhat.com/show_bug.cgi?id=1741900 +Signed-off-by: Ján Tomko +Message-Id: <9656cea8218d901d5e44a157362cd0f009ff1a7d.1565964111.git.jtomko@redhat.com> +Reviewed-by: Jiri Denemark +--- + src/util/virdbus.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/util/virdbus.c b/src/util/virdbus.c +index ba8b684f17..d0e2c76e48 100644 +--- a/src/util/virdbus.c ++++ b/src/util/virdbus.c +@@ -198,8 +198,10 @@ static void virDBusWatchCallback(int fdatch ATTRIBUTE_UNUSED, + + (void)dbus_watch_handle(watch, dbus_flags); + ++ dbus_connection_ref(info->bus); + while (dbus_connection_dispatch(info->bus) == DBUS_DISPATCH_DATA_REMAINS) + /* keep dispatching while data remains */; ++ dbus_connection_unref(info->bus); + } + + +-- +2.22.1 + diff --git a/SOURCES/libvirt-virfile-Detect-ceph-as-shared-FS.patch b/SOURCES/libvirt-virfile-Detect-ceph-as-shared-FS.patch new file mode 100644 index 0000000..0576034 --- /dev/null +++ b/SOURCES/libvirt-virfile-Detect-ceph-as-shared-FS.patch @@ -0,0 +1,139 @@ +From 6dd1c06ab2d05193d8cfee720f16d6b1d84b2cdf Mon Sep 17 00:00:00 2001 +Message-Id: <6dd1c06ab2d05193d8cfee720f16d6b1d84b2cdf@dist-git> +From: Michal Privoznik +Date: Tue, 4 Jun 2019 13:27:35 +0200 +Subject: [PATCH] virfile: Detect ceph as shared FS +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +https://bugzilla.redhat.com/show_bug.cgi?id=1665553 + +Ceph can be mounted just like any other filesystem and in fact is +a shared and cluster filesystem. The filesystem magic constant +was taken from kernel sources as it is not in magic.h yet. + +Signed-off-by: Michal Privoznik +Reviewed-by: Erik Skultety +(cherry picked from commit 6dd2a2ae6386b1d51edcc9a434f56d7f9dc2cb35) +https: //bugzilla.redhat.com/show_bug.cgi?id=1698133 +Message-Id: <55c1009db101780867229bdeea3f739db2efafeb.1559647301.git.pkrempa@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/virfile.c | 9 ++++++++- + src/util/virfile.h | 1 + + src/util/virstoragefile.c | 3 ++- + tests/virfiledata/mounts3.txt | 2 ++ + tests/virfilemock.c | 5 +++++ + tests/virfiletest.c | 2 ++ + 6 files changed, 20 insertions(+), 2 deletions(-) + +diff --git a/src/util/virfile.c b/src/util/virfile.c +index 716b55d770..471d309062 100644 +--- a/src/util/virfile.c ++++ b/src/util/virfile.c +@@ -3537,6 +3537,9 @@ int virFilePrintf(FILE *fp, const char *msg, ...) + # ifndef FUSE_SUPER_MAGIC + # define FUSE_SUPER_MAGIC 0x65735546 + # endif ++# ifndef CEPH_SUPER_MAGIC ++# define CEPH_SUPER_MAGIC 0x00C36400 ++# endif + + # define PROC_MOUNTS "/proc/mounts" + +@@ -3682,6 +3685,9 @@ virFileIsSharedFSType(const char *path, + if ((fstypes & VIR_FILE_SHFS_CIFS) && + (f_type == CIFS_SUPER_MAGIC)) + return 1; ++ if ((fstypes & VIR_FILE_SHFS_CEPH) && ++ (f_type == CEPH_SUPER_MAGIC)) ++ return 1; + + return 0; + } +@@ -3845,7 +3851,8 @@ int virFileIsSharedFS(const char *path) + VIR_FILE_SHFS_OCFS | + VIR_FILE_SHFS_AFS | + VIR_FILE_SHFS_SMB | +- VIR_FILE_SHFS_CIFS); ++ VIR_FILE_SHFS_CIFS | ++ VIR_FILE_SHFS_CEPH); + } + + +diff --git a/src/util/virfile.h b/src/util/virfile.h +index 6f1e802fde..1d16e96b59 100644 +--- a/src/util/virfile.h ++++ b/src/util/virfile.h +@@ -205,6 +205,7 @@ enum { + VIR_FILE_SHFS_AFS = (1 << 3), + VIR_FILE_SHFS_SMB = (1 << 4), + VIR_FILE_SHFS_CIFS = (1 << 5), ++ VIR_FILE_SHFS_CEPH = (1 << 6), + }; + + int virFileIsSharedFSType(const char *path, int fstypes) ATTRIBUTE_NONNULL(1); +diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c +index 58f67278da..0b15219c3e 100644 +--- a/src/util/virstoragefile.c ++++ b/src/util/virstoragefile.c +@@ -1366,7 +1366,8 @@ int virStorageFileIsClusterFS(const char *path) + */ + return virFileIsSharedFSType(path, + VIR_FILE_SHFS_GFS2 | +- VIR_FILE_SHFS_OCFS); ++ VIR_FILE_SHFS_OCFS | ++ VIR_FILE_SHFS_CEPH); + } + + #ifdef LVS +diff --git a/tests/virfiledata/mounts3.txt b/tests/virfiledata/mounts3.txt +index 134c6e8f81..68eded048c 100644 +--- a/tests/virfiledata/mounts3.txt ++++ b/tests/virfiledata/mounts3.txt +@@ -33,3 +33,5 @@ host:/nfs /nfs nfs4 rw,relatime,vers=4.1,rsize=1048576,wsize=1048576,namlen=255, + dev /nfs/blah devtmpfs rw,nosuid,relatime,size=10240k,nr_inodes=4093060,mode=755 0 0 + host:/gv0 /gluster fuse.glusterfs rw 0 0 + root@host:/tmp/mkdir /gluster/sshfs fuse.sshfs rw 0 0 ++192.168.0.1:/ceph/data /ceph ceph rw,noatime,name=cephfs,secret=,acl,wsize=16777216 0 0 ++192.168.0.1,192.168.0.2,192.168.0.3:/ceph/data2 /ceph/multi ceph rw,noatime,name=cephfs,secret=,acl,wsize=16777216 0 0 +diff --git a/tests/virfilemock.c b/tests/virfilemock.c +index ae5c8d025a..eb5182df66 100644 +--- a/tests/virfilemock.c ++++ b/tests/virfilemock.c +@@ -88,6 +88,9 @@ setmntent(const char *filename, const char *type) + #ifndef FUSE_SUPER_MAGIC + # define FUSE_SUPER_MAGIC 0x65735546 + #endif ++#ifndef CEPH_SUPER_MAGIC ++# define CEPH_SUPER_MAGIC 0x00c36400 ++#endif + + + static int +@@ -134,6 +137,8 @@ statfs_mock(const char *mtab, + ftype = CIFS_SUPER_MAGIC; + } else if (STRPREFIX(mb.mnt_type, "fuse")) { + ftype = FUSE_SUPER_MAGIC; ++ } else if (STRPREFIX(mb.mnt_type, "ceph")) { ++ ftype = CEPH_SUPER_MAGIC; + } else { + /* Everything else is EXT4. We don't care really for other paths. */ + ftype = EXT4_SUPER_MAGIC; +diff --git a/tests/virfiletest.c b/tests/virfiletest.c +index a246d601ba..972c07fdc5 100644 +--- a/tests/virfiletest.c ++++ b/tests/virfiletest.c +@@ -458,6 +458,8 @@ mymain(void) + DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/gluster/file", true); + DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/gluster/sshfs/file", false); + DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/some/symlink/file", true); ++ DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/ceph/file", true); ++ DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/ceph/multi/file", true); + + return ret != 0 ? EXIT_FAILURE : EXIT_SUCCESS; + } +-- +2.22.0 + diff --git a/SOURCES/libvirt-virfile-added-GPFS-as-shared-fs.patch b/SOURCES/libvirt-virfile-added-GPFS-as-shared-fs.patch new file mode 100644 index 0000000..b807638 --- /dev/null +++ b/SOURCES/libvirt-virfile-added-GPFS-as-shared-fs.patch @@ -0,0 +1,124 @@ +From fca427057cfad652bd787096b9af94d273c69185 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Diego Michelotto +Date: Tue, 4 Jun 2019 13:27:36 +0200 +Subject: [PATCH] virfile: added GPFS as shared fs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Added GPFS as shared file system recognized during live migration +security checks. + +GPFS is 'IBM General Parallel File System' also called +'IBM Spectrum Scale' + +BUG: https://bugzilla.redhat.com/show_bug.cgi?id=1679528 + +Signed-off-by: Diego Michelotto +Signed-off-by: Peter Krempa +(cherry picked from commit d163b940a73a0d6b8277a4bccef2b60936933cf0) +https: //bugzilla.redhat.com/show_bug.cgi?id=1698133 +Message-Id: <5d98c30627de2ed2fd02a77ecadaac0585c5fb15.1559647301.git.pkrempa@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/virfile.c | 9 ++++++++- + src/util/virfile.h | 1 + + tests/virfiledata/mounts3.txt | 1 + + tests/virfilemock.c | 5 +++++ + tests/virfiletest.c | 1 + + 5 files changed, 16 insertions(+), 1 deletion(-) + +diff --git a/src/util/virfile.c b/src/util/virfile.c +index 471d309062..e0564295dd 100644 +--- a/src/util/virfile.c ++++ b/src/util/virfile.c +@@ -3540,6 +3540,9 @@ int virFilePrintf(FILE *fp, const char *msg, ...) + # ifndef CEPH_SUPER_MAGIC + # define CEPH_SUPER_MAGIC 0x00C36400 + # endif ++# ifndef GPFS_SUPER_MAGIC ++# define GPFS_SUPER_MAGIC 0x47504653 ++# endif + + # define PROC_MOUNTS "/proc/mounts" + +@@ -3688,6 +3691,9 @@ virFileIsSharedFSType(const char *path, + if ((fstypes & VIR_FILE_SHFS_CEPH) && + (f_type == CEPH_SUPER_MAGIC)) + return 1; ++ if ((fstypes & VIR_FILE_SHFS_GPFS) && ++ (f_type == GPFS_SUPER_MAGIC)) ++ return 1; + + return 0; + } +@@ -3852,7 +3858,8 @@ int virFileIsSharedFS(const char *path) + VIR_FILE_SHFS_AFS | + VIR_FILE_SHFS_SMB | + VIR_FILE_SHFS_CIFS | +- VIR_FILE_SHFS_CEPH); ++ VIR_FILE_SHFS_CEPH | ++ VIR_FILE_SHFS_GPFS); + } + + +diff --git a/src/util/virfile.h b/src/util/virfile.h +index 1d16e96b59..51c221e069 100644 +--- a/src/util/virfile.h ++++ b/src/util/virfile.h +@@ -206,6 +206,7 @@ enum { + VIR_FILE_SHFS_SMB = (1 << 4), + VIR_FILE_SHFS_CIFS = (1 << 5), + VIR_FILE_SHFS_CEPH = (1 << 6), ++ VIR_FILE_SHFS_GPFS = (1 << 7), + }; + + int virFileIsSharedFSType(const char *path, int fstypes) ATTRIBUTE_NONNULL(1); +diff --git a/tests/virfiledata/mounts3.txt b/tests/virfiledata/mounts3.txt +index 68eded048c..4377e5d471 100644 +--- a/tests/virfiledata/mounts3.txt ++++ b/tests/virfiledata/mounts3.txt +@@ -35,3 +35,4 @@ host:/gv0 /gluster fuse.glusterfs rw 0 0 + root@host:/tmp/mkdir /gluster/sshfs fuse.sshfs rw 0 0 + 192.168.0.1:/ceph/data /ceph ceph rw,noatime,name=cephfs,secret=,acl,wsize=16777216 0 0 + 192.168.0.1,192.168.0.2,192.168.0.3:/ceph/data2 /ceph/multi ceph rw,noatime,name=cephfs,secret=,acl,wsize=16777216 0 0 ++gpfs_data /gpfs/data gpfs rw,relatime 0 0 +diff --git a/tests/virfilemock.c b/tests/virfilemock.c +index eb5182df66..02f26433d4 100644 +--- a/tests/virfilemock.c ++++ b/tests/virfilemock.c +@@ -91,6 +91,9 @@ setmntent(const char *filename, const char *type) + #ifndef CEPH_SUPER_MAGIC + # define CEPH_SUPER_MAGIC 0x00c36400 + #endif ++#ifndef GPFS_SUPER_MAGIC ++# define GPFS_SUPER_MAGIC 0x47504653 ++#endif + + + static int +@@ -139,6 +142,8 @@ statfs_mock(const char *mtab, + ftype = FUSE_SUPER_MAGIC; + } else if (STRPREFIX(mb.mnt_type, "ceph")) { + ftype = CEPH_SUPER_MAGIC; ++ } else if (STRPREFIX(mb.mnt_type, "gpfs")) { ++ ftype = GPFS_SUPER_MAGIC; + } else { + /* Everything else is EXT4. We don't care really for other paths. */ + ftype = EXT4_SUPER_MAGIC; +diff --git a/tests/virfiletest.c b/tests/virfiletest.c +index 972c07fdc5..5f17676c75 100644 +--- a/tests/virfiletest.c ++++ b/tests/virfiletest.c +@@ -460,6 +460,7 @@ mymain(void) + DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/some/symlink/file", true); + DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/ceph/file", true); + DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/ceph/multi/file", true); ++ DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/gpfs/data", true); + + return ret != 0 ? EXIT_FAILURE : EXIT_SUCCESS; + } +-- +2.22.0 + diff --git a/SOURCES/libvirt-virhostcpu-Make-virHostCPUGetMSR-work-only-on-x86.patch b/SOURCES/libvirt-virhostcpu-Make-virHostCPUGetMSR-work-only-on-x86.patch new file mode 100644 index 0000000..e9b18c4 --- /dev/null +++ b/SOURCES/libvirt-virhostcpu-Make-virHostCPUGetMSR-work-only-on-x86.patch @@ -0,0 +1,89 @@ +From 7ff2ecfcd684bcf4865ceac786f1c6809d84d0aa Mon Sep 17 00:00:00 2001 +Message-Id: <7ff2ecfcd684bcf4865ceac786f1c6809d84d0aa@dist-git> +From: Michal Privoznik +Date: Fri, 21 Jun 2019 09:25:44 +0200 +Subject: [PATCH] virhostcpu: Make virHostCPUGetMSR() work only on x86 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Model specific registers are a thing only on x86. Also, the +/dev/cpu/0/msr path exists only on Linux and the fallback +mechanism (asking KVM) exists on Linux and FreeBSD only. + +Therefore, move the function within #ifdef that checks all +aforementioned constraints and provide a dummy stub for all +other cases. + +This fixes the build on my arm box, mingw-* builds, etc. + +Signed-off-by: Michal Privoznik +Reviewed-by: Jiri Denemark +(cherry picked from commit ae3d812b006b84c6d06605868d19554ea0156392) + +https://bugzilla.redhat.com/show_bug.cgi?id=1697627 + +Signed-off-by: Jiri Denemark +Message-Id: <0f234c69059ad57462bb71d42983cdaedea26e78.1561068591.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko +--- + src/util/virhostcpu.c | 32 ++++++++++++++++++-------------- + 1 file changed, 18 insertions(+), 14 deletions(-) + +diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c +index d0c47faa18..aafa84c8e5 100644 +--- a/src/util/virhostcpu.c ++++ b/src/util/virhostcpu.c +@@ -1269,7 +1269,9 @@ virHostCPUGetMicrocodeVersion(void) + #endif /* __linux__ */ + + +-#if HAVE_LINUX_KVM_H && defined(KVM_GET_MSRS) ++#if HAVE_LINUX_KVM_H && defined(KVM_GET_MSRS) && \ ++ (defined(__i386__) || defined(__x86_64__)) && \ ++ (defined(__linux__) || defined(__FreeBSD__)) + static int + virHostCPUGetMSRFromKVM(unsigned long index, + uint64_t *result) +@@ -1297,19 +1299,6 @@ virHostCPUGetMSRFromKVM(unsigned long index, + return 0; + } + +-#else +- +-static int +-virHostCPUGetMSRFromKVM(unsigned long index ATTRIBUTE_UNUSED, +- uint64_t *result ATTRIBUTE_UNUSED) +-{ +- virReportSystemError(ENOSYS, "%s", +- _("Reading MSRs via KVM is not supported on this platform")); +- return -1; +-} +-#endif /* HAVE_LINUX_KVM_H && defined(KVM_GET_MSRS) */ +- +- + /* + * Returns 0 on success, + * 1 when the MSR is not supported by the host CPU, +@@ -1346,3 +1335,18 @@ virHostCPUGetMSR(unsigned long index, + + return virHostCPUGetMSRFromKVM(index, msr); + } ++ ++#else ++ ++int ++virHostCPUGetMSR(unsigned long index ATTRIBUTE_UNUSED, ++ uint64_t *msr ATTRIBUTE_UNUSED) ++{ ++ virReportSystemError(ENOSYS, "%s", ++ _("Reading MSRs is not supported on this platform")); ++ return -1; ++} ++ ++#endif /* HAVE_LINUX_KVM_H && defined(KVM_GET_MSRS) && \ ++ (defined(__i386__) || defined(__x86_64__)) && \ ++ (defined(__linux__) || defined(__FreeBSD__)) */ +-- +2.22.0 + diff --git a/SOURCES/libvirt-virt-host-validate-Fix-build-on-non-Linux.patch b/SOURCES/libvirt-virt-host-validate-Fix-build-on-non-Linux.patch new file mode 100644 index 0000000..39c9f15 --- /dev/null +++ b/SOURCES/libvirt-virt-host-validate-Fix-build-on-non-Linux.patch @@ -0,0 +1,45 @@ +From f3366321b1911d327985ed16717a8589869d6fb3 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Michal Privoznik +Date: Mon, 1 Jul 2019 17:08:05 +0200 +Subject: [PATCH] virt-host-validate: Fix build on non-Linux +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +For non-Linux platforms we have +virHostValidateCGroupControllers() stub which only reports an +error. But we are not marking the ignored arguments the way we +should. + +Signed-off-by: Michal Privoznik +Reviewed-by: Pavel Hrdina +(cherry picked from commit 8524faf8c4007edfbc5363a018821139667a9e32) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <34a0cf3fd56060036b473a82c9b2b39beba0d589.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + tools/virt-host-validate-common.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/virt-host-validate-common.c b/tools/virt-host-validate-common.c +index 73165d673a..5dd1605daa 100644 +--- a/tools/virt-host-validate-common.c ++++ b/tools/virt-host-validate-common.c +@@ -324,8 +324,8 @@ int virHostValidateCGroupControllers(const char *hvname, + return ret; + } + #else /* !__linux__ */ +-int virHostValidateCGroupControllers(const char *hvname, +- int controllers, ++int virHostValidateCGroupControllers(const char *hvname ATTRIBUTE_UNUSED, ++ int controllers ATTRIBUTE_UNUSED, + virHostValidateLevel level) + { + virHostMsgFail(level, "%s", "This platform does not support cgroups"); +-- +2.22.0 + diff --git a/SOURCES/libvirt-virt-host-validate-require-freezer-for-LXC.patch b/SOURCES/libvirt-virt-host-validate-require-freezer-for-LXC.patch new file mode 100644 index 0000000..a54edba --- /dev/null +++ b/SOURCES/libvirt-virt-host-validate-require-freezer-for-LXC.patch @@ -0,0 +1,38 @@ +From f150121476cbe99dcca7378583aa1f0533c072d1 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:08:04 +0200 +Subject: [PATCH] virt-host-validate: require freezer for LXC +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Cgroup freezer support for LXC was added in libvirt-0.7.2. + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 0a7101c89b787d2f45690f8ad3a4b932b000b758) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: +Reviewed-by: Ján Tomko +--- + tools/virt-host-validate-lxc.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tools/virt-host-validate-lxc.c b/tools/virt-host-validate-lxc.c +index 3c55b1b26d..8613f37cc7 100644 +--- a/tools/virt-host-validate-lxc.c ++++ b/tools/virt-host-validate-lxc.c +@@ -70,6 +70,7 @@ int virHostValidateLXC(void) + (1 << VIR_CGROUP_CONTROLLER_CPUACCT) | + (1 << VIR_CGROUP_CONTROLLER_CPUSET) | + (1 << VIR_CGROUP_CONTROLLER_DEVICES) | ++ (1 << VIR_CGROUP_CONTROLLER_FREEZER) | + (1 << VIR_CGROUP_CONTROLLER_BLKIO), + VIR_HOST_VALIDATE_FAIL) < 0) { + ret = -1; +-- +2.22.0 + diff --git a/SOURCES/libvirt-virt-host-validate-rewrite-cgroup-detection-to-use-util-vircgroup.patch b/SOURCES/libvirt-virt-host-validate-rewrite-cgroup-detection-to-use-util-vircgroup.patch new file mode 100644 index 0000000..9e9a6fe --- /dev/null +++ b/SOURCES/libvirt-virt-host-validate-rewrite-cgroup-detection-to-use-util-vircgroup.patch @@ -0,0 +1,371 @@ +From 0ede215415509022d94092b75ef075495c91a5d5 Mon Sep 17 00:00:00 2001 +Message-Id: <0ede215415509022d94092b75ef075495c91a5d5@dist-git> +From: Pavel Hrdina +Date: Mon, 1 Jul 2019 17:08:03 +0200 +Subject: [PATCH] virt-host-validate: rewrite cgroup detection to use + util/vircgroup +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This removes code duplication and simplifies cgroup detection. +As a drawback we will not have separate messages to enable cgroup +controller in kernel or to mount it. On the other side the rewrite +adds support for cgroup v2. + +The kernel config support was wrong because it was parsing +'/proc/self/cgroup' instead of '/proc/cgroups/' file. + +The mount suggestion is removed as well because it will not work +with cgroup v2. + +Signed-off-by: Pavel Hrdina +(cherry picked from commit 0f4d7daa8cd43b62911413c2cc1614f87380e459) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297 + +Signed-off-by: Pavel Hrdina +Message-Id: <0a79b9dcaee25d04b993c4e6576d75ce7c45ac0f.1561993100.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko +--- + tools/virt-host-validate-common.c | 164 ++++++------------------------ + tools/virt-host-validate-common.h | 7 +- + tools/virt-host-validate-lxc.c | 38 ++----- + tools/virt-host-validate-qemu.c | 38 ++----- + 4 files changed, 53 insertions(+), 194 deletions(-) + +diff --git a/tools/virt-host-validate-common.c b/tools/virt-host-validate-common.c +index c45dfc5d8c..73165d673a 100644 +--- a/tools/virt-host-validate-common.c ++++ b/tools/virt-host-validate-common.c +@@ -26,12 +26,10 @@ + #include + #include + #include +-#ifdef HAVE_MNTENT_H +-# include +-#endif /* HAVE_MNTENT_H */ + #include + + #include "viralloc.h" ++#include "vircgroup.h" + #include "virfile.h" + #include "virt-host-validate-common.h" + #include "virstring.h" +@@ -290,152 +288,50 @@ int virHostValidateLinuxKernel(const char *hvname, + } + } + +- +-static int virHostValidateCGroupSupport(const char *hvname, +- const char *cg_name, +- virHostValidateLevel level, +- const char *config_name) ++#ifdef __linux__ ++int virHostValidateCGroupControllers(const char *hvname, ++ int controllers, ++ virHostValidateLevel level) + { +- virHostMsgCheck(hvname, "for cgroup '%s' controller support", cg_name); +- FILE *fp = fopen("/proc/self/cgroup", "r"); +- size_t len = 0; +- char *line = NULL; +- ssize_t ret; +- bool matched = false; ++ virCgroupPtr group = NULL; ++ int ret = 0; ++ size_t i; + +- if (!fp) +- goto error; ++ if (virCgroupNewSelf(&group) < 0) ++ return -1; + +- while ((ret = getline(&line, &len, fp)) >= 0 && !matched) { +- char **cgroups; +- char *start; +- char *end; +- size_t ncgroups; +- size_t i; ++ for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { ++ int flag = 1 << i; ++ const char *cg_name = virCgroupControllerTypeToString(i); + +- /* Each line in this file looks like +- * +- * 4:cpu,cpuacct:/machine.slice/machine-qemu\x2dtest.scope/emulator +- * +- * Since multiple cgroups can be part of the same line and some cgroup +- * names can appear as part of other cgroup names (eg. 'cpu' is a +- * prefix for both 'cpuacct' and 'cpuset'), it's not enough to simply +- * check whether the cgroup name is present somewhere inside the file. +- * +- * Moreover, there's nothing stopping the cgroup name from appearing +- * in an unrelated mount point name as well */ +- +- /* Look for the first colon. +- * The part we're interested in starts right after it */ +- if (!(start = strchr(line, ':'))) +- continue; +- start++; +- +- /* Look for the second colon. +- * The part we're interested in ends exactly there */ +- if (!(end = strchr(start, ':'))) +- continue; +- *end = '\0'; +- +- if (!(cgroups = virStringSplitCount(start, ",", 0, &ncgroups))) ++ if (!(controllers & flag)) + continue; + +- /* Look for the matching cgroup */ +- for (i = 0; i < ncgroups; i++) { +- if (STREQ(cgroups[i], cg_name)) +- matched = true; ++ virHostMsgCheck(hvname, "for cgroup '%s' controller support", cg_name); ++ ++ if (!virCgroupHasController(group, i)) { ++ ret = -1; ++ virHostMsgFail(level, "Enable '%s' in kernel Kconfig file or " ++ "mount/enable cgroup controller in your system", ++ cg_name); ++ } else { ++ virHostMsgPass(); + } +- +- virStringListFreeCount(cgroups, ncgroups); + } + +- VIR_FREE(line); +- VIR_FORCE_FCLOSE(fp); +- if (!matched) +- goto error; ++ virCgroupFree(&group); + +- virHostMsgPass(); +- return 0; +- +- error: +- VIR_FREE(line); +- virHostMsgFail(level, "Enable CONFIG_%s in kernel Kconfig file", config_name); +- return -1; ++ return ret; + } +- +-#ifdef HAVE_MNTENT_H +-static int virHostValidateCGroupMount(const char *hvname, +- const char *cg_name, +- virHostValidateLevel level) ++#else /* !__linux__ */ ++int virHostValidateCGroupControllers(const char *hvname, ++ int controllers, ++ virHostValidateLevel level) + { +- virHostMsgCheck(hvname, "for cgroup '%s' controller mount-point", cg_name); +- FILE *fp = setmntent("/proc/mounts", "r"); +- struct mntent ent; +- char mntbuf[1024]; +- bool matched = false; +- +- if (!fp) +- goto error; +- +- while (getmntent_r(fp, &ent, mntbuf, sizeof(mntbuf)) && !matched) { +- char **opts; +- size_t nopts; +- size_t i; +- +- /* Ignore non-cgroup mounts */ +- if (STRNEQ(ent.mnt_type, "cgroup")) +- continue; +- +- if (!(opts = virStringSplitCount(ent.mnt_opts, ",", 0, &nopts))) +- continue; +- +- /* Look for a mount option matching the cgroup name */ +- for (i = 0; i < nopts; i++) { +- if (STREQ(opts[i], cg_name)) +- matched = true; +- } +- +- virStringListFreeCount(opts, nopts); +- } +- endmntent(fp); +- if (!matched) +- goto error; +- +- virHostMsgPass(); +- return 0; +- +- error: +- virHostMsgFail(level, "Mount '%s' cgroup controller (suggested at /sys/fs/cgroup/%s)", +- cg_name, cg_name); +- return -1; +-} +-#else /* ! HAVE_MNTENT_H */ +-static int virHostValidateCGroupMount(const char *hvname, +- const char *cg_name, +- virHostValidateLevel level) +-{ +- virHostMsgCheck(hvname, "for cgroup '%s' controller mount-point", cg_name); + virHostMsgFail(level, "%s", "This platform does not support cgroups"); + return -1; + } +-#endif /* ! HAVE_MNTENT_H */ +- +-int virHostValidateCGroupController(const char *hvname, +- const char *cg_name, +- virHostValidateLevel level, +- const char *config_name) +-{ +- if (virHostValidateCGroupSupport(hvname, +- cg_name, +- level, +- config_name) < 0) +- return -1; +- if (virHostValidateCGroupMount(hvname, +- cg_name, +- level) < 0) +- return -1; +- return 0; +-} ++#endif /* !__linux__ */ + + int virHostValidateIOMMU(const char *hvname, + virHostValidateLevel level) +diff --git a/tools/virt-host-validate-common.h b/tools/virt-host-validate-common.h +index b6fe17daa7..b23dd7cdbe 100644 +--- a/tools/virt-host-validate-common.h ++++ b/tools/virt-host-validate-common.h +@@ -77,10 +77,9 @@ int virHostValidateNamespace(const char *hvname, + virHostValidateLevel level, + const char *hint); + +-int virHostValidateCGroupController(const char *hvname, +- const char *cg_name, +- virHostValidateLevel level, +- const char *config_name); ++int virHostValidateCGroupControllers(const char *hvname, ++ int controllers, ++ virHostValidateLevel level); + + int virHostValidateIOMMU(const char *hvname, + virHostValidateLevel level); +diff --git a/tools/virt-host-validate-lxc.c b/tools/virt-host-validate-lxc.c +index 64d9279c30..3c55b1b26d 100644 +--- a/tools/virt-host-validate-lxc.c ++++ b/tools/virt-host-validate-lxc.c +@@ -23,6 +23,7 @@ + + #include "virt-host-validate-lxc.h" + #include "virt-host-validate-common.h" ++#include "vircgroup.h" + + int virHostValidateLXC(void) + { +@@ -63,35 +64,16 @@ int virHostValidateLXC(void) + _("User namespace support is recommended")) < 0) + ret = -1; + +- if (virHostValidateCGroupController("LXC", "memory", +- VIR_HOST_VALIDATE_FAIL, +- "MEMCG") < 0) +- ret = -1; +- +- if (virHostValidateCGroupController("LXC", "cpu", +- VIR_HOST_VALIDATE_FAIL, +- "CGROUP_CPU") < 0) +- ret = -1; +- +- if (virHostValidateCGroupController("LXC", "cpuacct", +- VIR_HOST_VALIDATE_FAIL, +- "CGROUP_CPUACCT") < 0) +- ret = -1; +- +- if (virHostValidateCGroupController("LXC", "cpuset", +- VIR_HOST_VALIDATE_FAIL, +- "CPUSETS") < 0) +- ret = -1; +- +- if (virHostValidateCGroupController("LXC", "devices", +- VIR_HOST_VALIDATE_FAIL, +- "CGROUP_DEVICE") < 0) +- ret = -1; +- +- if (virHostValidateCGroupController("LXC", "blkio", +- VIR_HOST_VALIDATE_FAIL, +- "BLK_CGROUP") < 0) ++ if (virHostValidateCGroupControllers("LXC", ++ (1 << VIR_CGROUP_CONTROLLER_MEMORY) | ++ (1 << VIR_CGROUP_CONTROLLER_CPU) | ++ (1 << VIR_CGROUP_CONTROLLER_CPUACCT) | ++ (1 << VIR_CGROUP_CONTROLLER_CPUSET) | ++ (1 << VIR_CGROUP_CONTROLLER_DEVICES) | ++ (1 << VIR_CGROUP_CONTROLLER_BLKIO), ++ VIR_HOST_VALIDATE_FAIL) < 0) { + ret = -1; ++ } + + #if WITH_FUSE + if (virHostValidateDeviceExists("LXC", "/sys/fs/fuse/connections", +diff --git a/tools/virt-host-validate-qemu.c b/tools/virt-host-validate-qemu.c +index d7573ea8b3..ff3c1f0231 100644 +--- a/tools/virt-host-validate-qemu.c ++++ b/tools/virt-host-validate-qemu.c +@@ -26,6 +26,7 @@ + #include "virt-host-validate-common.h" + #include "virarch.h" + #include "virbitmap.h" ++#include "vircgroup.h" + + int virHostValidateQEMU(void) + { +@@ -96,35 +97,16 @@ int virHostValidateQEMU(void) + _("Load the 'tun' module to enable networking for QEMU guests")) < 0) + ret = -1; + +- if (virHostValidateCGroupController("QEMU", "memory", +- VIR_HOST_VALIDATE_WARN, +- "MEMCG") < 0) +- ret = -1; +- +- if (virHostValidateCGroupController("QEMU", "cpu", +- VIR_HOST_VALIDATE_WARN, +- "CGROUP_CPU") < 0) +- ret = -1; +- +- if (virHostValidateCGroupController("QEMU", "cpuacct", +- VIR_HOST_VALIDATE_WARN, +- "CGROUP_CPUACCT") < 0) +- ret = -1; +- +- if (virHostValidateCGroupController("QEMU", "cpuset", +- VIR_HOST_VALIDATE_WARN, +- "CPUSETS") < 0) +- ret = -1; +- +- if (virHostValidateCGroupController("QEMU", "devices", +- VIR_HOST_VALIDATE_WARN, +- "CGROUP_DEVICES") < 0) +- ret = -1; +- +- if (virHostValidateCGroupController("QEMU", "blkio", +- VIR_HOST_VALIDATE_WARN, +- "BLK_CGROUP") < 0) ++ if (virHostValidateCGroupControllers("QEMU", ++ (1 << VIR_CGROUP_CONTROLLER_MEMORY) | ++ (1 << VIR_CGROUP_CONTROLLER_CPU) | ++ (1 << VIR_CGROUP_CONTROLLER_CPUACCT) | ++ (1 << VIR_CGROUP_CONTROLLER_CPUSET) | ++ (1 << VIR_CGROUP_CONTROLLER_DEVICES) | ++ (1 << VIR_CGROUP_CONTROLLER_BLKIO), ++ VIR_HOST_VALIDATE_WARN) < 0) { + ret = -1; ++ } + + if (virHostValidateIOMMU("QEMU", + VIR_HOST_VALIDATE_WARN) < 0) +-- +2.22.0 + diff --git a/SPECS/libvirt.spec b/SPECS/libvirt.spec index 1b453db..fa6e7f7 100644 --- a/SPECS/libvirt.spec +++ b/SPECS/libvirt.spec @@ -69,9 +69,17 @@ %else %define with_storage_sheepdog 0 %endif -%define with_storage_gluster 0%{!?_without_storage_gluster:1} %define with_numactl 0%{!?_without_numactl:1} +%define with_storage_gluster 0%{!?_without_storage_gluster:1} +%ifnarch %{qemu_kvm_arches} + # gluster is only built where qemu driver is enabled on RHEL 8 + %if 0%{?rhel} >= 8 + %define with_storage_gluster 0 + %endif +%endif + + # F25+ has zfs-fuse %if 0%{?fedora} %define with_storage_zfs 0%{!?_without_storage_zfs:1} @@ -243,7 +251,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 4.5.0 -Release: 24.3%{?dist}%{?extra_release} +Release: 35%{?dist}%{?extra_release} License: LGPLv2+ URL: https://libvirt.org/ @@ -448,17 +456,354 @@ Patch192: libvirt-util-remove-test-code-accidentally-committed-to-virFirewallDZo Patch193: libvirt-qemu-command-Don-t-skip-readonly-and-throttling-info-for-empty-drive.patch Patch194: libvirt-util-fix-memory-leak-in-virFirewallDInterfaceSetZone.patch Patch195: libvirt-network-explicitly-allow-icmp-icmpv6-in-libvirt-zonefile.patch -Patch196: libvirt-cpu_x86-Do-not-cache-microcode-version.patch -Patch197: libvirt-qemu-Don-t-cache-microcode-version.patch -Patch198: libvirt-cputest-Add-data-for-Intel-R-Xeon-R-CPU-E3-1225-v5.patch -Patch199: libvirt-cpu_map-Define-md-clear-CPUID-bit.patch -Patch200: libvirt-admin-reject-clients-unless-their-UID-matches-the-current-UID.patch -Patch201: libvirt-locking-restrict-sockets-to-mode-0600.patch -Patch202: libvirt-logging-restrict-sockets-to-mode-0600.patch -Patch203: libvirt-api-disallow-virDomainSaveImageGetXMLDesc-on-read-only-connections.patch -Patch204: libvirt-api-disallow-virDomainManagedSaveDefineXML-on-read-only-connections.patch -Patch205: libvirt-api-disallow-virConnectGetDomainCapabilities-on-read-only-connections.patch -Patch206: libvirt-api-disallow-virConnect-HypervisorCPU-on-read-only-connections.patch +Patch196: libvirt-tests-qemuxml2argv-add-CAPS_ARCH_LATEST-macro.patch +Patch197: libvirt-qemu-Add-ccw-support-for-vhost-vsock.patch +Patch198: libvirt-qemu-Allow-creating-ppc64-guests-with-graphics-and-no-USB-mouse.patch +Patch199: libvirt-conf-Expose-virDomainSCSIDriveAddressIsUsed.patch +Patch200: libvirt-qemuhotplugtest-Don-t-plug-a-SCSI-disk-at-unit-7.patch +Patch201: libvirt-qemu_hotplug-Check-for-duplicate-drive-addresses.patch +Patch202: libvirt-cpu_map-Add-support-for-cldemote-CPU-feature.patch +Patch203: libvirt-util-alloc-add-macros-for-implementing-automatic-cleanup-functionality.patch +Patch204: libvirt-qemu-domain-Simplify-non-VFIO-memLockLimit-calculation-for-PPC64.patch +Patch205: libvirt-qemu_domain-add-a-PPC64-memLockLimit-helper.patch +Patch206: libvirt-qemu_domain-NVLink2-bridge-detection-function-for-PPC64.patch +Patch207: libvirt-PPC64-support-for-NVIDIA-V100-GPU-with-NVLink2-passthrough.patch +Patch208: libvirt-cpu_x86-Do-not-cache-microcode-version.patch +Patch209: libvirt-qemu-Don-t-cache-microcode-version.patch +Patch210: libvirt-cputest-Add-data-for-Intel-R-Xeon-R-CPU-E3-1225-v5.patch +Patch211: libvirt-cpu_map-Define-md-clear-CPUID-bit.patch +Patch212: libvirt-admin-reject-clients-unless-their-UID-matches-the-current-UID.patch +Patch213: libvirt-locking-restrict-sockets-to-mode-0600.patch +Patch214: libvirt-logging-restrict-sockets-to-mode-0600.patch +Patch215: libvirt-util-skip-RDMA-detection-for-non-PCI-network-devices.patch +Patch216: libvirt-virfile-Detect-ceph-as-shared-FS.patch +Patch217: libvirt-virfile-added-GPFS-as-shared-fs.patch +Patch218: libvirt-util-bitmap-define-cleanup-function-using-VIR_DEFINE_AUTOPTR_FUNC.patch +Patch219: libvirt-qemu-Rework-setting-process-affinity.patch +Patch220: libvirt-qemu-Set-up-EMULATOR-thread-and-cpuset.mems-before-exec-ing-qemu.patch +Patch221: libvirt-conf-Add-definitions-for-uid-and-fid-PCI-address-attributes.patch +Patch222: libvirt-qemu-Introduce-zPCI-capability.patch +Patch223: libvirt-qemu-Enable-PCI-multi-bus-for-S390-guests.patch +Patch224: libvirt-conf-Introduce-extension-flag-and-zPCI-member-for-PCI-address.patch +Patch225: libvirt-conf-Introduce-address-caching-for-PCI-extensions.patch +Patch226: libvirt-qemu-Auto-add-pci-root-for-s390-s390x-guests.patch +Patch227: libvirt-conf-use-virXMLFormatElement-in-virDomainDeviceInfoFormat.patch +Patch228: libvirt-conf-Introduce-parser-formatter-for-uid-and-fid.patch +Patch229: libvirt-qemu-Add-zPCI-address-definition-check.patch +Patch230: libvirt-conf-Allocate-release-uid-and-fid-in-PCI-address.patch +Patch231: libvirt-qemu-Generate-and-use-zPCI-device-in-QEMU-command-line.patch +Patch232: libvirt-qemu-Add-hotpluging-support-for-PCI-devices-on-S390-guests.patch +Patch233: libvirt-qemuDomainRemoveRNGDevice-Remove-associated-chardev-too.patch +Patch234: libvirt-qemu_hotplug-remove-erroneous-call-to-qemuDomainDetachExtensionDevice.patch +Patch235: libvirt-qemu_hotplug-remove-another-erroneous-qemuDomainDetachExtensionDevice-call.patch +Patch236: libvirt-util-Propagate-numad-failures-correctly.patch +Patch237: libvirt-util-Introduce-virBitmapUnion.patch +Patch238: libvirt-util-Introduce-virNumaNodesetToCPUset.patch +Patch239: libvirt-qemu-Fix-qemuProcessInitCpuAffinity.patch +Patch240: libvirt-qemu-Fix-leak-in-qemuProcessInitCpuAffinity.patch +Patch241: libvirt-qemu-Drop-cleanup-label-from-qemuProcessInitCpuAffinity.patch +Patch242: libvirt-qemu-Fix-NULL-pointer-access-in-qemuProcessInitCpuAffinity.patch +Patch243: libvirt-qemuBuildMemoryBackendProps-Pass-priv-instead-of-its-individual-members.patch +Patch244: libvirt-qemu-Don-t-use-mem-prealloc-among-with-.prealloc-yes.patch +Patch245: libvirt-nwfilter-fix-adding-std-MAC-and-IP-values-to-filter-binding.patch +Patch246: libvirt-qemuProcessBuildDestroyMemoryPathsImpl-Don-t-overwrite-error.patch +Patch247: libvirt-qemu_security-Fully-implement-qemuSecurityDomainSetPathLabel.patch +Patch248: libvirt-qemu-process-SEV-Assume-libDir-to-be-the-directory-to-create-files-in.patch +Patch249: libvirt-qemu-process-SEV-Relabel-guest-owner-s-SEV-files-created-before-start.patch +Patch250: libvirt-api-disallow-virDomainSaveImageGetXMLDesc-on-read-only-connections.patch +Patch251: libvirt-api-disallow-virDomainManagedSaveDefineXML-on-read-only-connections.patch +Patch252: libvirt-api-disallow-virConnectGetDomainCapabilities-on-read-only-connections.patch +Patch253: libvirt-api-disallow-virConnect-HypervisorCPU-on-read-only-connections.patch +Patch254: libvirt-rpc-virnetlibsshsession-update-deprecated-functions.patch +Patch255: libvirt-cpu-allow-include-files-for-CPU-definition.patch +Patch256: libvirt-cpu-fix-cleanup-when-signature-parsing-fails.patch +Patch257: libvirt-cpu-push-more-parsing-logic-into-common-code.patch +Patch258: libvirt-cpu-simplify-failure-cleanup-paths.patch +Patch259: libvirt-cpu_map-Add-support-for-arch-capabilities-feature.patch +Patch260: libvirt-cputest-Add-data-for-Intel-R-Xeon-R-CPU-E5-2630-v4.patch +Patch261: libvirt-cputest-Add-data-for-Intel-R-Core-TM-i7-7600U.patch +Patch262: libvirt-cputest-Add-data-for-Intel-R-Xeon-R-CPU-E7540.patch +Patch263: libvirt-cputest-Add-data-for-Intel-R-Xeon-R-CPU-E5-2650.patch +Patch264: libvirt-cputest-Add-data-for-Intel-R-Core-TM-i7-8700.patch +Patch265: libvirt-cpu_x86-Separate-ancestor-model-parsing-from-x86ModelParse.patch +Patch266: libvirt-cpu_x86-Separate-signature-parsing-from-x86ModelParse.patch +Patch267: libvirt-cpu_x86-Separate-vendor-parsing-from-x86ModelParse.patch +Patch268: libvirt-cpu_x86-Separate-feature-list-parsing-from-x86ModelParse.patch +Patch269: libvirt-cpu_x86-Make-sure-CPU-model-names-are-unique-in-cpu_map.patch +Patch270: libvirt-cpu_x86-Add-x86ModelCopySignatures-helper.patch +Patch271: libvirt-cpu_x86-Store-CPU-signature-in-an-array.patch +Patch272: libvirt-cpu_x86-Allow-multiple-signatures-for-a-CPU-model.patch +Patch273: libvirt-cpu_x86-Log-decoded-CPU-model-and-signatures.patch +Patch274: libvirt-qemu_capabilities-Inroduce-virQEMUCapsGetCPUModelX86Data.patch +Patch275: libvirt-qemu_capabilities-Introduce-virQEMUCapsGetCPUModelInfo.patch +Patch276: libvirt-qemu_capabilities-Use-virQEMUCapsGetCPUModelInfo.patch +Patch277: libvirt-cpu_x86-Add-virCPUx86DataGetSignature-for-tests.patch +Patch278: libvirt-cpu_map-Add-hex-representation-of-signatures.patch +Patch279: libvirt-cputest-Test-CPU-signatures.patch +Patch280: libvirt-cpu_map-Add-more-signatures-for-Conroe-CPU-model.patch +Patch281: libvirt-cpu_map-Add-more-signatures-for-Penryn-CPU-model.patch +Patch282: libvirt-cpu_map-Add-more-signatures-for-Nehalem-CPU-models.patch +Patch283: libvirt-cpu_map-Add-more-signatures-for-Westmere-CPU-model.patch +Patch284: libvirt-cpu_map-Add-more-signatures-for-SandyBridge-CPU-models.patch +Patch285: libvirt-cpu_map-Add-more-signatures-for-IvyBridge-CPU-models.patch +Patch286: libvirt-cpu_map-Add-more-signatures-for-Haswell-CPU-models.patch +Patch287: libvirt-cpu_map-Add-more-signatures-for-Broadwell-CPU-models.patch +Patch288: libvirt-cpu_map-Add-more-signatures-for-Skylake-Client-CPU-models.patch +Patch289: libvirt-cpu-Don-t-access-invalid-memory-in-virCPUx86Translate.patch +Patch290: libvirt-cpu_x86-Require-cpuid-within-feature-in-CPU-map.patch +Patch291: libvirt-cputest-Add-data-for-Intel-R-Xeon-R-Platinum-8268-CPU.patch +Patch292: libvirt-cpu_map-Add-Cascadelake-Server-CPU-model.patch +Patch293: libvirt-cpu_x86-Introduce-virCPUx86DataItem-container-struct.patch +Patch294: libvirt-cpu_x86-Rename-virCPUx86Vendor.cpuid.patch +Patch295: libvirt-cpu_x86-Rename-virCPUx86DataItem-variables.patch +Patch296: libvirt-cpu_x86-Rename-x86DataCpuidNext-function.patch +Patch297: libvirt-cpu_x86-Rename-x86DataCpuid.patch +Patch298: libvirt-cpu_x86-Rename-virCPUx86CPUIDSorter.patch +Patch299: libvirt-cpu_x86-Rename-virCPUx86DataAddCPUIDInt.patch +Patch300: libvirt-cpu_x86-Rename-virCPUx86DataAddCPUID.patch +Patch301: libvirt-cpu_x86-Rename-virCPUx86VendorToCPUID.patch +Patch302: libvirt-cpu_x86-Simplify-x86DataAdd.patch +Patch303: libvirt-cpu_x86-Introduce-virCPUx86DataCmp.patch +Patch304: libvirt-cpu_x86-Make-x86cpuidSetBits-more-general.patch +Patch305: libvirt-cpu_x86-Make-x86cpuidClearBits-more-general.patch +Patch306: libvirt-cpu_x86-Make-x86cpuidAndBits-more-general.patch +Patch307: libvirt-cpu_x86-Make-x86cpuidMatchMasked-more-general.patch +Patch308: libvirt-cpu_x86-Make-x86cpuidMatch-more-general.patch +Patch309: libvirt-cpu_x86-Store-virCPUx86DataItem-content-in-union.patch +Patch310: libvirt-cpu_x86-Add-support-for-storing-MSR-features-in-CPU-map.patch +Patch311: libvirt-cpu_x86-Move-CheckFeature-functions.patch +Patch312: libvirt-cputest-Add-support-for-MSR-features-to-cpu-parse.sh.patch +Patch313: libvirt-util-file-introduce-VIR_AUTOCLOSE-macro-to-close-fd-of-the-file-automatically.patch +Patch314: libvirt-vircpuhost-Add-support-for-reading-MSRs.patch +Patch315: libvirt-virhostcpu-Make-virHostCPUGetMSR-work-only-on-x86.patch +Patch316: libvirt-cpu_x86-Fix-placement-of-CheckFeature-functions.patch +Patch317: libvirt-cpu_conf-Introduce-virCPUDefFilterFeatures.patch +Patch318: libvirt-qemu_command-Use-consistent-syntax-for-CPU-features.patch +Patch319: libvirt-tests-Add-QEMU-caps-data-for-future-4.1.0.patch +Patch320: libvirt-tests-Add-domain-capabilities-case-for-QEMU-4.1.0.patch +Patch321: libvirt-qemuxml2argvtest-Add-test-for-CPU-features-translation.patch +Patch322: libvirt-qemu-Add-APIs-for-translating-CPU-features.patch +Patch323: libvirt-qemu-Probe-for-max-x86_64-cpu-type.patch +Patch324: libvirt-qemu-Probe-for-unavailable-features-CPU-property.patch +Patch325: libvirt-qemu-Probe-host-CPU-after-capabilities.patch +Patch326: libvirt-qemu_command-Use-canonical-names-of-CPU-features.patch +Patch327: libvirt-qemu-Translate-feature-names-from-query-cpu-model-expansion.patch +Patch328: libvirt-qemu-Don-t-use-full-CPU-model-expansion.patch +Patch329: libvirt-qemu-Make-qemuMonitorGetGuestCPU-usable-on-x86-only.patch +Patch330: libvirt-cpu-Introduce-virCPUDataAddFeature.patch +Patch331: libvirt-qemu-Add-type-filter-to-qemuMonitorJSONParsePropsList.patch +Patch332: libvirt-util-string-Introduce-macro-for-automatic-string-lists.patch +Patch333: libvirt-util-json-define-cleanup-function-using-VIR_DEFINE_AUTOPTR_FUNC.patch +Patch334: libvirt-qemu-Introduce-generic-qemuMonitorGetGuestCPU.patch +Patch335: libvirt-qemu_process-Prefer-generic-qemuMonitorGetGuestCPU.patch +Patch336: libvirt-util-Rework-virStringListAdd.patch +Patch337: libvirt-conf-Introduce-virCPUDefCheckFeatures.patch +Patch338: libvirt-cpu_x86-Turn-virCPUx86DataIteratorInit-into-a-function.patch +Patch339: libvirt-cpu_x86-Introduce-virCPUx86FeatureFilter-MSR.patch +Patch340: libvirt-cpu_x86-Read-CPU-features-from-IA32_ARCH_CAPABILITIES-MSR.patch +Patch341: libvirt-cpu_map-Introduce-IA32_ARCH_CAPABILITIES-MSR-features.patch +Patch342: libvirt-qemu-Forbid-MSR-features-with-old-QEMU.patch +Patch343: libvirt-qemu-Drop-MSR-features-from-host-model-with-old-QEMU.patch +Patch344: libvirt-cpu_x86-Fix-memory-leak-virCPUx86GetHost.patch +Patch345: libvirt-qemu-Use-tmpChr-in-qemuDomainDetachChrDevice-to-build-device-string.patch +Patch346: libvirt-qemu-Drop-user-prefix-for-guestfwd-netdev.patch +Patch347: libvirt-qemu_hotplug-Attach-guestfwd-using-netdev_add.patch +Patch348: libvirt-qemu_hotplug-Detach-guestfwd-using-netdev_del.patch +Patch349: libvirt-qemuhotplugtest-Test-guestfwd-attach-and-detach.patch +Patch350: libvirt-daemon-Register-secret-driver-before-storage-driver.patch +Patch351: libvirt-bhyve-Move-autostarting-of-domains-into-bhyveStateInitialize.patch +Patch352: libvirt-Revert-virStateDriver-Separate-AutoStart-from-Initialize.patch +Patch353: libvirt-Revert-Separate-out-StateAutoStart-from-StateInitialize.patch +Patch354: libvirt-util-moving-type-argument-to-avoid-issues-with-mount-syscall.patch +Patch355: libvirt-util-cgroup-use-VIR_AUTOFREE-instead-of-VIR_FREE-for-scalar-types.patch +Patch356: libvirt-vircgroup-Rename-structs-to-start-with-underscore.patch +Patch357: libvirt-vircgroup-Introduce-standard-set-of-typedefs-and-use-them.patch +Patch358: libvirt-vircgroup-Extract-file-link-resolving-into-separate-function.patch +Patch359: libvirt-vircgroup-Remove-unused-function-virCgroupKill.patch +Patch360: libvirt-vircgroup-Unexport-unused-function-virCgroupAddTaskController.patch +Patch361: libvirt-vircgroup-Unexport-unused-function-virCgroupRemoveRecursively.patch +Patch362: libvirt-vircgroup-Move-function-used-in-tests-into-vircgrouppriv.h.patch +Patch363: libvirt-vircgroup-Remove-pointless-bool-parameter.patch +Patch364: libvirt-vircgroup-Extract-mount-options-matching-into-function.patch +Patch365: libvirt-vircgroup-Use-virCgroupMountOptsMatchController-in-virCgroupDetectPlacement.patch +Patch366: libvirt-vircgroup-Introduce-virCgroupEnableMissingControllers.patch +Patch367: libvirt-vircgroup-machinename-will-never-be-NULL.patch +Patch368: libvirt-vircgroup-Remove-virCgroupAddTaskController.patch +Patch369: libvirt-vircgroup-Introduce-virCgroupGetMemoryStat.patch +Patch370: libvirt-lxc-Use-virCgroupGetMemoryStat.patch +Patch371: libvirt-vircgroup-fix-MinGW-build.patch +Patch372: libvirt-vircgroup-Duplicate-string-before-modifying.patch +Patch373: libvirt-vircgroup-Extract-controller-detection-into-function.patch +Patch374: libvirt-vircgroup-Extract-placement-validation-into-function.patch +Patch375: libvirt-vircgroup-Split-virCgroupPathOfController-into-two-functions.patch +Patch376: libvirt-vircgroup-Call-virCgroupRemove-inside-virCgroupMakeGroup.patch +Patch377: libvirt-vircgroup-Simplify-if-conditions-in-virCgroupMakeGroup.patch +Patch378: libvirt-vircgroup-Remove-obsolete-sa_assert.patch +Patch379: libvirt-tests-Resolve-possible-overrun.patch +Patch380: libvirt-vircgroup-cleanup-controllers-not-managed-by-systemd-on-error.patch +Patch381: libvirt-vircgroup-fix-bug-in-virCgroupEnableMissingControllers.patch +Patch382: libvirt-vircgroup-rename-virCgroupAdd.-Task-to-virCgroupAdd.-Process.patch +Patch383: libvirt-vircgroup-introduce-virCgroupTaskFlags.patch +Patch384: libvirt-vircgroup-introduce-virCgroupAddThread.patch +Patch385: libvirt-vircgroupmock-cleanup-unused-cgroup-files.patch +Patch386: libvirt-vircgroupmock-rewrite-cgroup-fopen-mocking.patch +Patch387: libvirt-vircgrouptest-call-virCgroupDetectMounts-directly.patch +Patch388: libvirt-vircgrouptest-call-virCgroupNewSelf-instead-virCgroupDetectMounts.patch +Patch389: libvirt-util-introduce-vircgroupbackend-files.patch +Patch390: libvirt-vircgroup-introduce-cgroup-v1-backend-files.patch +Patch391: libvirt-vircgroup-extract-virCgroupV1Available.patch +Patch392: libvirt-vircgroup-detect-available-backend-for-cgroup.patch +Patch393: libvirt-vircgroup-extract-virCgroupV1ValidateMachineGroup.patch +Patch394: libvirt-vircgroup-extract-virCgroupV1CopyMounts.patch +Patch395: libvirt-vircgroup-extract-v1-detect-functions.patch +Patch396: libvirt-vircgroup-extract-virCgroupV1CopyPlacement.patch +Patch397: libvirt-vircgroup-extract-virCgroupV1ValidatePlacement.patch +Patch398: libvirt-vircgroup-extract-virCgroupV1StealPlacement.patch +Patch399: libvirt-vircgroup-extract-virCgroupV1DetectControllers.patch +Patch400: libvirt-vircgroup-extract-virCgroupV1HasController.patch +Patch401: libvirt-vircgroup-extract-virCgroupV1GetAnyController.patch +Patch402: libvirt-vircgroup-extract-virCgroupV1PathOfController.patch +Patch403: libvirt-vircgroup-extract-virCgroupV1MakeGroup.patch +Patch404: libvirt-vircgroup-extract-virCgroupV1Remove.patch +Patch405: libvirt-vircgroup-extract-virCgroupV1AddTask.patch +Patch406: libvirt-vircgroup-extract-virCgroupV1HasEmptyTasks.patch +Patch407: libvirt-vircgroup-extract-virCgroupV1BindMount.patch +Patch408: libvirt-vircgroup-extract-virCgroupV1SetOwner.patch +Patch409: libvirt-vircgroup-extract-virCgroupV1-Set-Get-BlkioWeight.patch +Patch410: libvirt-vircgroup-extract-virCgroupV1GetBlkioIoServiced.patch +Patch411: libvirt-vircgroup-extract-virCgroupV1GetBlkioIoDeviceServiced.patch +Patch412: libvirt-vircgroup-extract-virCgroupV1-Set-Get-BlkioDeviceWeight.patch +Patch413: libvirt-vircgroup-extract-virCgroupV1-Set-Get-BlkioDeviceReadIops.patch +Patch414: libvirt-vircgroup-extract-virCgroupV1-Set-Get-BlkioDeviceWriteIops.patch +Patch415: libvirt-vircgroup-extract-virCgroupV1-Set-Get-BlkioDeviceReadBps.patch +Patch416: libvirt-vircgroup-extract-virCgroupV1-Set-Get-BlkioDeviceWriteBps.patch +Patch417: libvirt-vircgroup-extract-virCgroupV1SetMemory.patch +Patch418: libvirt-vircgroup-extract-virCgroupV1GetMemoryStat.patch +Patch419: libvirt-vircgroup-extract-virCgroupV1GetMemoryUsage.patch +Patch420: libvirt-vircgroup-extract-virCgroupV1-Set-Get-Memory-Limit.patch +Patch421: libvirt-vircgroup-extract-virCgroupV1GetMemSwapUsage.patch +Patch422: libvirt-vircgroup-extract-virCgroupV1-Allow-Deny-Device.patch +Patch423: libvirt-vircgroup-extract-virCgroupV1-Allow-Deny-AllDevices.patch +Patch424: libvirt-vircgroup-extract-virCgroupV1-Set-Get-CpuShares.patch +Patch425: libvirt-vircgroup-extract-virCgroupV1-Set-Get-CpuCfsPeriod.patch +Patch426: libvirt-vircgroup-extract-virCgroupV1-Set-Get-CpuCfsQuota.patch +Patch427: libvirt-vircgroup-extract-virCgroupV1SupportsCpuBW.patch +Patch428: libvirt-vircgroup-extract-virCgroupV1GetCpuacct-Usage.patch +Patch429: libvirt-vircgroup-extract-virCgroupV1GetCpuacctStat.patch +Patch430: libvirt-vircgroup-extract-virCgroupV1-Set-Get-FreezerState.patch +Patch431: libvirt-vircgroup-extract-virCgroupV1-Set-Get-CpusetMems.patch +Patch432: libvirt-vircgroup-extract-virCgroupV1-Set-Get-CpusetMemoryMigrate.patch +Patch433: libvirt-vircgroup-extract-virCgroupV1-Set-Get-CpusetCpus.patch +Patch434: libvirt-vircgroup-rename-virCgroupController-into-virCgroupV1Controller.patch +Patch435: libvirt-vircgroup-rename-controllers-to-legacy.patch +Patch436: libvirt-vircgroup-remove-VIR_CGROUP_SUPPORTED.patch +Patch437: libvirt-vircgroup-include-system-headers-only-on-linux.patch +Patch438: libvirt-vircgroupv1-fix-build-on-non-linux-OSes.patch +Patch439: libvirt-Revert-vircgroup-cleanup-controllers-not-managed-by-systemd-on-error.patch +Patch440: libvirt-util-introduce-cgroup-v2-files.patch +Patch441: libvirt-vircgroup-introduce-virCgroupV2Available.patch +Patch442: libvirt-vircgroup-introduce-virCgroupV2ValidateMachineGroup.patch +Patch443: libvirt-vircgroup-introduce-virCgroupV2CopyMounts.patch +Patch444: libvirt-vircgroup-introduce-virCgroupV2CopyPlacement.patch +Patch445: libvirt-vircgroup-introduce-virCgroupV2DetectMounts.patch +Patch446: libvirt-vircgroup-introduce-virCgroupV2DetectPlacement.patch +Patch447: libvirt-vircgroup-introduce-virCgroupV2ValidatePlacement.patch +Patch448: libvirt-vircgroup-introduce-virCgroupV2StealPlacement.patch +Patch449: libvirt-vircgroup-introduce-virCgroupV2DetectControllers.patch +Patch450: libvirt-vircgroup-introduce-virCgroupV2HasController.patch +Patch451: libvirt-vircgroup-introduce-virCgroupV2GetAnyController.patch +Patch452: libvirt-vircgroup-introduce-virCgroupV2PathOfController.patch +Patch453: libvirt-vircgroup-introduce-virCgroupV2MakeGroup.patch +Patch454: libvirt-vircgroup-introduce-virCgroupV2Remove.patch +Patch455: libvirt-vircgroup-introduce-virCgroupV2AddTask.patch +Patch456: libvirt-vircgroup-introduce-virCgroupV2HasEmptyTasks.patch +Patch457: libvirt-vircgroup-introduce-virCgroupV2BindMount.patch +Patch458: libvirt-vircgroup-introduce-virCgroupV2SetOwner.patch +Patch459: libvirt-vircgroup-introduce-virCgroupV2-Set-Get-BlkioWeight.patch +Patch460: libvirt-vircgroup-introduce-virCgroupV2GetBlkioIoServiced.patch +Patch461: libvirt-vircgroup-introduce-virCgroupV2GetBlkioIoDeviceServiced.patch +Patch462: libvirt-vircgroup-introduce-virCgroupV2-Set-Get-BlkioDeviceWeight.patch +Patch463: libvirt-vircgroup-introduce-virCgroupV2-Set-Get-BlkioDeviceReadIops.patch +Patch464: libvirt-vircgroup-introduce-virCgroupV2-Set-Get-BlkioDeviceWriteIops.patch +Patch465: libvirt-vircgroup-introduce-virCgroupV2-Set-Get-BlkioDeviceReadBps.patch +Patch466: libvirt-vircgroup-introduce-virCgroupV2-Set-Get-BlkioDeviceWriteBps.patch +Patch467: libvirt-vircgroup-introduce-virCgroupV2SetMemory.patch +Patch468: libvirt-vircgroup-introduce-virCgroupV2GetMemoryStat.patch +Patch469: libvirt-vircgroup-introduce-virCgroupV2GetMemoryUsage.patch +Patch470: libvirt-vircgroup-introduce-virCgroupV2-Set-Get-MemoryHardLimit.patch +Patch471: libvirt-vircgroup-introduce-virCgroupV2-Set-Get-MemorySoftLimit.patch +Patch472: libvirt-vircgroup-introduce-virCgroupV2-Set-Get-MemSwapHardLimit.patch +Patch473: libvirt-vircgroup-introduce-virCgroupV2GetMemSwapUsage.patch +Patch474: libvirt-vircgroup-introduce-virCgroupV2-Set-Get-CpuShares.patch +Patch475: libvirt-vircgroup-introduce-virCgroupV2-Set-Get-CpuCfsPeriod.patch +Patch476: libvirt-vircgroup-introduce-virCgroupV2-Set-Get-CpuCfsQuota.patch +Patch477: libvirt-vircgroup-introduce-virCgroupV2SupportsCpuBW.patch +Patch478: libvirt-vircgroup-introduce-virCgroupV2GetCpuacctUsage.patch +Patch479: libvirt-vircgroup-introduce-virCgroupV2GetCpuacctStat.patch +Patch480: libvirt-vircgroup-register-cgroup-v2-backend.patch +Patch481: libvirt-vircgroup-add-support-for-hybrid-configuration.patch +Patch482: libvirt-vircgroupmock-change-cgroup-prefix.patch +Patch483: libvirt-vircgroupmock-add-support-to-test-cgroup-v2.patch +Patch484: libvirt-vircgrouptest-introduce-initFakeFS-and-cleanupFakeFS-helpers.patch +Patch485: libvirt-vircgrouptest-prepare-testCgroupDetectMounts-for-cgroup-v2.patch +Patch486: libvirt-vircgrouptest-add-detect-mounts-test-for-cgroup-v2.patch +Patch487: libvirt-vircgrouptest-add-detect-mounts-test-for-hybrid-cgroups.patch +Patch488: libvirt-vircgrouptest-prepare-validateCgroup-for-cgroupv2.patch +Patch489: libvirt-vircgrouptest-add-cgroup-v2-tests.patch +Patch490: libvirt-vircgrouptest-add-hybrid-tests.patch +Patch491: libvirt-virt-host-validate-rewrite-cgroup-detection-to-use-util-vircgroup.patch +Patch492: libvirt-virt-host-validate-require-freezer-for-LXC.patch +Patch493: libvirt-virt-host-validate-Fix-build-on-non-Linux.patch +Patch494: libvirt-tests-Use-correct-function-name-in-error-path.patch +Patch495: libvirt-util-Fix-virCgroupGetMemoryStat.patch +Patch496: libvirt-tests-Augment-vcgrouptest-to-add-virCgroupGetMemoryStat.patch +Patch497: libvirt-vircgroup-introduce-virCgroupKillRecursiveCB.patch +Patch498: libvirt-vircgroupv2-fix-virCgroupV2ValidateMachineGroup.patch +Patch499: libvirt-util-implement-virCgroupV2-Set-Get-CpusetMems.patch +Patch500: libvirt-util-implement-virCgroupV2-Set-Get-CpusetMemoryMigrate.patch +Patch501: libvirt-util-implement-virCgroupV2-Set-Get-CpusetCpus.patch +Patch502: libvirt-util-enable-cgroups-v2-cpuset-controller-for-threads.patch +Patch503: libvirt-util-vircgroup-pass-parent-cgroup-into-virCgroupDetectControllersCB.patch +Patch504: libvirt-internal-introduce-a-family-of-NULLSTR-macros.patch +Patch505: libvirt-util-vircgroup-improve-controller-detection.patch +Patch506: libvirt-util-vircgroupv2-use-any-controller-to-create-thread-directory.patch +Patch507: libvirt-util-vircgroupv2-enable-CPU-controller-only-if-it-s-available.patch +Patch508: libvirt-util-vircgroupv2-separate-return-values-of-virCgroupV2EnableController.patch +Patch509: libvirt-util-vircgroupv2-don-t-error-out-if-enabling-controller-fails.patch +Patch510: libvirt-util-vircgroupv2-mark-only-requested-controllers-as-available.patch +Patch511: libvirt-Revert-util-vircgroup-pass-parent-cgroup-into-virCgroupDetectControllersCB.patch +Patch512: libvirt-util-vircgroupv2-stop-enabling-missing-controllers-with-systemd.patch +Patch513: libvirt-virWaitForDevices-Drop-confusing-part-of-comment.patch +Patch514: libvirt-lib-Drop-UDEVSETTLE.patch +Patch515: libvirt-m4-Provide-default-value-fore-UDEVADM.patch +Patch516: libvirt-m4-Drop-needless-string-checks.patch +Patch517: libvirt-util-vircgroup-introduce-virCgroup-Get-Set-ValueRaw.patch +Patch518: libvirt-util-vircgroup-move-virCgroupGetValueStr-out-of-virCgroupGetValueForBlkDev.patch +Patch519: libvirt-util-vircgroupv1-add-support-for-BFQ-blkio-files.patch +Patch520: libvirt-util-vircgroupv2-add-support-for-BFQ-files.patch +Patch521: libvirt-Handle-copying-bitmaps-to-larger-data-buffers.patch +Patch522: libvirt-virDomainObjListAddLocked-fix-double-free.patch +Patch523: libvirt-docs-schemas-Decouple-the-virtio-options-from-each-other.patch +Patch524: libvirt-util-command-use-VIR_AUTOFREE-instead-of-VIR_FREE-for-scalar-types.patch +Patch525: libvirt-util-command-define-cleanup-function-using-VIR_DEFINE_AUTOPTR_FUNC.patch +Patch526: libvirt-util-netdevopenvswitch-use-VIR_AUTOFREE-instead-of-VIR_FREE-for-scalar-types.patch +Patch527: libvirt-util-virnetdevopenvswitch-Drop-an-unused-variable-ovs_timeout.patch +Patch528: libvirt-util-netdevopenvswitch-use-VIR_AUTOPTR-for-aggregate-types.patch +Patch529: libvirt-util-suppress-unimportant-ovs-vsctl-errors-when-getting-interface-stats.patch +Patch530: libvirt-virNetDevOpenvswitchInterfaceStats-Optimize-for-speed.patch +Patch531: libvirt-test-Introduce-virnetdevopenvswitchtest.patch +Patch532: libvirt-vircommand-Separate-mass-FD-closing-into-a-function.patch +Patch533: libvirt-virCommand-use-procfs-to-learn-opened-FDs.patch +Patch534: libvirt-util-command-Ignore-bitmap-errors-when-enumerating-file-descriptors-to-close.patch +Patch535: libvirt-util-Avoid-possible-error-in-virCommandMassClose.patch +Patch536: libvirt-vircgroup-fix-cgroups-v2-controllers-detection.patch +Patch537: libvirt-vircgroupv2-store-enabled-controllers.patch +Patch538: libvirt-virDomainObjListAddLocked-Produce-better-error-message-than-Duplicate-key.patch +Patch539: libvirt-virdbus-Grab-a-ref-as-long-as-the-while-loop-is-executed.patch +Patch540: libvirt-vircgroupv2-fix-parsing-multiple-values-in-single-file.patch +Patch541: libvirt-vircgroupv2-fix-virCgroupV2GetCpuCfsQuota-for-max-value.patch +Patch542: libvirt-vircgroupv2-fix-abort-in-VIR_AUTOFREE.patch +Patch543: libvirt-vircgroupv2-fix-setting-cpu.max-period.patch Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} @@ -2370,27 +2715,381 @@ exit 0 %changelog -* Sun Jun 30 2019 Danilo de Paula - 4.5.0-24.3 +* Mon Sep 16 2019 Jiri Denemark - 4.5.0-35 +- vircgroupv2: fix setting cpu.max period (rhbz#1749227) + +* Wed Sep 4 2019 Jiri Denemark - 4.5.0-34 +- vircgroupv2: fix abort in VIR_AUTOFREE (rhbz#1747440) + +* Mon Aug 26 2019 Jiri Denemark - 4.5.0-33 +- vircgroupv2: fix parsing multiple values in single file (rhbz#1741825) +- vircgroupv2: fix virCgroupV2GetCpuCfsQuota for "max" value (rhbz#1741837) + +* Mon Aug 19 2019 Jiri Denemark - 4.5.0-32 +- virDomainObjListAddLocked: Produce better error message than 'Duplicate key' (rhbz#1737790) +- virdbus: Grab a ref as long as the while loop is executed (rhbz#1741900) + +* Tue Jul 30 2019 Jiri Denemark - 4.5.0-31 +- virDomainObjListAddLocked: fix double free (rhbz#1728530) +- docs: schemas: Decouple the virtio options from each other (rhbz#1729675) +- util: command: use VIR_AUTOFREE instead of VIR_FREE for scalar types (rhbz#1721434) +- util: command: define cleanup function using VIR_DEFINE_AUTOPTR_FUNC (rhbz#1721434) +- util: netdevopenvswitch: use VIR_AUTOFREE instead of VIR_FREE for scalar types (rhbz#1721434) +- util: virnetdevopenvswitch: Drop an unused variable @ovs_timeout (rhbz#1721434) +- util: netdevopenvswitch: use VIR_AUTOPTR for aggregate types (rhbz#1721434) +- util: suppress unimportant ovs-vsctl errors when getting interface stats (rhbz#1721434) +- virNetDevOpenvswitchInterfaceStats: Optimize for speed (rhbz#1721434) +- test: Introduce virnetdevopenvswitchtest (rhbz#1721434) +- vircommand: Separate mass FD closing into a function (rhbz#1721434) +- virCommand: use procfs to learn opened FDs (rhbz#1721434) +- util: command: Ignore bitmap errors when enumerating file descriptors to close (rhbz#1721434) +- util: Avoid possible error in virCommandMassClose (rhbz#1721434) +- vircgroup: fix cgroups v2 controllers detection (rhbz#1689297) +- vircgroupv2: store enabled controllers (rhbz#1689297) + +* Wed Jul 3 2019 Jiri Denemark - 4.5.0-30 +- virWaitForDevices: Drop confusing part of comment (rhbz#1710575) +- lib: Drop UDEVSETTLE (rhbz#1710575) +- m4: Provide default value fore UDEVADM (rhbz#1710575) +- m4: Drop needless string checks (rhbz#1710575) +- util: vircgroup: introduce virCgroup(Get|Set)ValueRaw (rhbz#1658890) +- util: vircgroup: move virCgroupGetValueStr out of virCgroupGetValueForBlkDev (rhbz#1658890) +- util: vircgroupv1: add support for BFQ blkio files (rhbz#1658890) +- util: vircgroupv2: add support for BFQ files (rhbz#1658890) +- Handle copying bitmaps to larger data buffers (rhbz#1703160) + +* Tue Jul 2 2019 Jiri Denemark - 4.5.0-29 +- cpu: allow include files for CPU definition (rhbz#1686895) +- cpu: fix cleanup when signature parsing fails (rhbz#1686895) +- cpu: push more parsing logic into common code (rhbz#1686895) +- cpu: simplify failure cleanup paths (rhbz#1686895) +- cpu_map: Add support for arch-capabilities feature (rhbz#1693433) +- cputest: Add data for Intel(R) Xeon(R) CPU E5-2630 v4 (rhbz#1686895) +- cputest: Add data for Intel(R) Core(TM) i7-7600U (rhbz#1686895) +- cputest: Add data for Intel(R) Xeon(R) CPU E7540 (rhbz#1686895) +- cputest: Add data for Intel(R) Xeon(R) CPU E5-2650 (rhbz#1686895) +- cputest: Add data for Intel(R) Core(TM) i7-8700 (rhbz#1686895) +- cpu_x86: Separate ancestor model parsing from x86ModelParse (rhbz#1686895) +- cpu_x86: Separate signature parsing from x86ModelParse (rhbz#1686895) +- cpu_x86: Separate vendor parsing from x86ModelParse (rhbz#1686895) +- cpu_x86: Separate feature list parsing from x86ModelParse (rhbz#1686895) +- cpu_x86: Make sure CPU model names are unique in cpu_map (rhbz#1686895) +- cpu_x86: Add x86ModelCopySignatures helper (rhbz#1686895) +- cpu_x86: Store CPU signature in an array (rhbz#1686895) +- cpu_x86: Allow multiple signatures for a CPU model (rhbz#1686895) +- cpu_x86: Log decoded CPU model and signatures (rhbz#1686895) +- qemu_capabilities: Inroduce virQEMUCapsGetCPUModelX86Data (rhbz#1686895) +- qemu_capabilities: Introduce virQEMUCapsGetCPUModelInfo (rhbz#1686895) +- qemu_capabilities: Use virQEMUCapsGetCPUModelInfo (rhbz#1686895) +- cpu_x86: Add virCPUx86DataGetSignature for tests (rhbz#1686895) +- cpu_map: Add hex representation of signatures (rhbz#1686895) +- cputest: Test CPU signatures (rhbz#1686895) +- cpu_map: Add more signatures for Conroe CPU model (rhbz#1686895) +- cpu_map: Add more signatures for Penryn CPU model (rhbz#1686895) +- cpu_map: Add more signatures for Nehalem CPU models (rhbz#1686895) +- cpu_map: Add more signatures for Westmere CPU model (rhbz#1686895) +- cpu_map: Add more signatures for SandyBridge CPU models (rhbz#1686895) +- cpu_map: Add more signatures for IvyBridge CPU models (rhbz#1686895) +- cpu_map: Add more signatures for Haswell CPU models (rhbz#1686895) +- cpu_map: Add more signatures for Broadwell CPU models (rhbz#1686895) +- cpu_map: Add more signatures for Skylake-Client CPU models (rhbz#1686895) +- cpu: Don't access invalid memory in virCPUx86Translate (rhbz#1686895) +- cpu_x86: Require within in CPU map (rhbz#1697627) +- cputest: Add data for Intel(R) Xeon(R) Platinum 8268 CPU (rhbz#1693433) +- cpu_map: Add Cascadelake-Server CPU model (rhbz#1693433) +- cpu_x86: Introduce virCPUx86DataItem container struct (rhbz#1697627) +- cpu_x86: Rename virCPUx86Vendor.cpuid (rhbz#1697627) +- cpu_x86: Rename virCPUx86DataItem variables (rhbz#1697627) +- cpu_x86: Rename x86DataCpuidNext function (rhbz#1697627) +- cpu_x86: Rename x86DataCpuid (rhbz#1697627) +- cpu_x86: Rename virCPUx86CPUIDSorter (rhbz#1697627) +- cpu_x86: Rename virCPUx86DataAddCPUIDInt (rhbz#1697627) +- cpu_x86: Rename virCPUx86DataAddCPUID (rhbz#1697627) +- cpu_x86: Rename virCPUx86VendorToCPUID (rhbz#1697627) +- cpu_x86: Simplify x86DataAdd (rhbz#1697627) +- cpu_x86: Introduce virCPUx86DataCmp (rhbz#1697627) +- cpu_x86: Make x86cpuidSetBits more general (rhbz#1697627) +- cpu_x86: Make x86cpuidClearBits more general (rhbz#1697627) +- cpu_x86: Make x86cpuidAndBits more general (rhbz#1697627) +- cpu_x86: Make x86cpuidMatchMasked more general (rhbz#1697627) +- cpu_x86: Make x86cpuidMatch more general (rhbz#1697627) +- cpu_x86: Store virCPUx86DataItem content in union (rhbz#1697627) +- cpu_x86: Add support for storing MSR features in CPU map (rhbz#1697627) +- cpu_x86: Move *CheckFeature functions (rhbz#1697627) +- cputest: Add support for MSR features to cpu-parse.sh (rhbz#1697627) +- util: file: introduce VIR_AUTOCLOSE macro to close fd of the file automatically (rhbz#1697627) +- vircpuhost: Add support for reading MSRs (rhbz#1697627) +- virhostcpu: Make virHostCPUGetMSR() work only on x86 (rhbz#1697627) +- cpu_x86: Fix placement of *CheckFeature functions (rhbz#1697627) +- cpu_conf: Introduce virCPUDefFilterFeatures (rhbz#1697627) +- qemu_command: Use consistent syntax for CPU features (rhbz#1697627) +- tests: Add QEMU caps data for future 4.1.0 (rhbz#1697627) +- tests: Add domain capabilities case for QEMU 4.1.0 (rhbz#1697627) +- qemuxml2argvtest: Add test for CPU features translation (rhbz#1697627) +- qemu: Add APIs for translating CPU features (rhbz#1697627) +- qemu: Probe for max-x86_64-cpu type (rhbz#1697627) +- qemu: Probe for "unavailable-features" CPU property (rhbz#1697627) +- qemu: Probe host CPU after capabilities (rhbz#1697627) +- qemu_command: Use canonical names of CPU features (rhbz#1697627) +- qemu: Translate feature names from query-cpu-model-expansion (rhbz#1697627) +- qemu: Don't use full CPU model expansion (rhbz#1697627) +- qemu: Make qemuMonitorGetGuestCPU usable on x86 only (rhbz#1697627) +- cpu: Introduce virCPUDataAddFeature (rhbz#1697627) +- qemu: Add type filter to qemuMonitorJSONParsePropsList (rhbz#1697627) +- util: string: Introduce macro for automatic string lists (rhbz#1697627) +- util: json: define cleanup function using VIR_DEFINE_AUTOPTR_FUNC (rhbz#1697627) +- qemu: Introduce generic qemuMonitorGetGuestCPU (rhbz#1697627) +- qemu_process: Prefer generic qemuMonitorGetGuestCPU (rhbz#1697627) +- util: Rework virStringListAdd (rhbz#1697627) +- conf: Introduce virCPUDefCheckFeatures (rhbz#1697627) +- cpu_x86: Turn virCPUx86DataIteratorInit into a function (rhbz#1697627) +- cpu_x86: Introduce virCPUx86FeatureFilter*MSR (rhbz#1697627) +- cpu_x86: Read CPU features from IA32_ARCH_CAPABILITIES MSR (rhbz#1697627) +- cpu_map: Introduce IA32_ARCH_CAPABILITIES MSR features (rhbz#1697627) +- qemu: Forbid MSR features with old QEMU (rhbz#1697627) +- qemu: Drop MSR features from host-model with old QEMU (rhbz#1697627) +- cpu_x86: Fix memory leak - virCPUx86GetHost (rhbz#1697627) +- qemu: Use @tmpChr in qemuDomainDetachChrDevice to build device string (rhbz#1624204) +- qemu: Drop "user-" prefix for guestfwd netdev (rhbz#1624204) +- qemu_hotplug: Attach guestfwd using netdev_add (rhbz#1624204) +- qemu_hotplug: Detach guestfwd using netdev_del (rhbz#1624204) +- qemuhotplugtest: Test guestfwd attach and detach (rhbz#1624204) +- daemon: Register secret driver before storage driver (rhbz#1685151) +- bhyve: Move autostarting of domains into bhyveStateInitialize (rhbz#1685151) +- Revert "virStateDriver - Separate AutoStart from Initialize" (rhbz#1685151) +- Revert "Separate out StateAutoStart from StateInitialize" (rhbz#1685151) +- util: moving 'type' argument to avoid issues with mount() syscall. (rhbz#1689297) +- util: cgroup: use VIR_AUTOFREE instead of VIR_FREE for scalar types (rhbz#1689297) +- vircgroup: Rename structs to start with underscore (rhbz#1689297) +- vircgroup: Introduce standard set of typedefs and use them (rhbz#1689297) +- vircgroup: Extract file link resolving into separate function (rhbz#1689297) +- vircgroup: Remove unused function virCgroupKill() (rhbz#1689297) +- vircgroup: Unexport unused function virCgroupAddTaskController() (rhbz#1689297) +- vircgroup: Unexport unused function virCgroupRemoveRecursively (rhbz#1689297) +- vircgroup: Move function used in tests into vircgrouppriv.h (rhbz#1689297) +- vircgroup: Remove pointless bool parameter (rhbz#1689297) +- vircgroup: Extract mount options matching into function (rhbz#1689297) +- vircgroup: Use virCgroupMountOptsMatchController in virCgroupDetectPlacement (rhbz#1689297) +- vircgroup: Introduce virCgroupEnableMissingControllers (rhbz#1689297) +- vircgroup: machinename will never be NULL (rhbz#1689297) +- vircgroup: Remove virCgroupAddTaskController (rhbz#1689297) +- vircgroup: Introduce virCgroupGetMemoryStat (rhbz#1689297) +- lxc: Use virCgroupGetMemoryStat (rhbz#1689297) +- vircgroup: fix MinGW build (rhbz#1689297) +- vircgroup: Duplicate string before modifying (rhbz#1689297) +- vircgroup: Extract controller detection into function (rhbz#1689297) +- vircgroup: Extract placement validation into function (rhbz#1689297) +- vircgroup: Split virCgroupPathOfController into two functions (rhbz#1689297) +- vircgroup: Call virCgroupRemove inside virCgroupMakeGroup (rhbz#1689297) +- vircgroup: Simplify if conditions in virCgroupMakeGroup (rhbz#1689297) +- vircgroup: Remove obsolete sa_assert (rhbz#1689297) +- tests: Resolve possible overrun (rhbz#1689297) +- vircgroup: cleanup controllers not managed by systemd on error (rhbz#1689297) +- vircgroup: fix bug in virCgroupEnableMissingControllers (rhbz#1689297) +- vircgroup: rename virCgroupAdd.*Task to virCgroupAdd.*Process (rhbz#1689297) +- vircgroup: introduce virCgroupTaskFlags (rhbz#1689297) +- vircgroup: introduce virCgroupAddThread (rhbz#1689297) +- vircgroupmock: cleanup unused cgroup files (rhbz#1689297) +- vircgroupmock: rewrite cgroup fopen mocking (rhbz#1689297) +- vircgrouptest: call virCgroupDetectMounts directly (rhbz#1689297) +- vircgrouptest: call virCgroupNewSelf instead virCgroupDetectMounts (rhbz#1689297) +- util: introduce vircgroupbackend files (rhbz#1689297) +- vircgroup: introduce cgroup v1 backend files (rhbz#1689297) +- vircgroup: extract virCgroupV1Available (rhbz#1689297) +- vircgroup: detect available backend for cgroup (rhbz#1689297) +- vircgroup: extract virCgroupV1ValidateMachineGroup (rhbz#1689297) +- vircgroup: extract virCgroupV1CopyMounts (rhbz#1689297) +- vircgroup: extract v1 detect functions (rhbz#1689297) +- vircgroup: extract virCgroupV1CopyPlacement (rhbz#1689297) +- vircgroup: extract virCgroupV1ValidatePlacement (rhbz#1689297) +- vircgroup: extract virCgroupV1StealPlacement (rhbz#1689297) +- vircgroup: extract virCgroupV1DetectControllers (rhbz#1689297) +- vircgroup: extract virCgroupV1HasController (rhbz#1689297) +- vircgroup: extract virCgroupV1GetAnyController (rhbz#1689297) +- vircgroup: extract virCgroupV1PathOfController (rhbz#1689297) +- vircgroup: extract virCgroupV1MakeGroup (rhbz#1689297) +- vircgroup: extract virCgroupV1Remove (rhbz#1689297) +- vircgroup: extract virCgroupV1AddTask (rhbz#1689297) +- vircgroup: extract virCgroupV1HasEmptyTasks (rhbz#1689297) +- vircgroup: extract virCgroupV1BindMount (rhbz#1689297) +- vircgroup: extract virCgroupV1SetOwner (rhbz#1689297) +- vircgroup: extract virCgroupV1(Set|Get)BlkioWeight (rhbz#1689297) +- vircgroup: extract virCgroupV1GetBlkioIoServiced (rhbz#1689297) +- vircgroup: extract virCgroupV1GetBlkioIoDeviceServiced (rhbz#1689297) +- vircgroup: extract virCgroupV1(Set|Get)BlkioDeviceWeight (rhbz#1689297) +- vircgroup: extract virCgroupV1(Set|Get)BlkioDeviceReadIops (rhbz#1689297) +- vircgroup: extract virCgroupV1(Set|Get)BlkioDeviceWriteIops (rhbz#1689297) +- vircgroup: extract virCgroupV1(Set|Get)BlkioDeviceReadBps (rhbz#1689297) +- vircgroup: extract virCgroupV1(Set|Get)BlkioDeviceWriteBps (rhbz#1689297) +- vircgroup: extract virCgroupV1SetMemory (rhbz#1689297) +- vircgroup: extract virCgroupV1GetMemoryStat (rhbz#1689297) +- vircgroup: extract virCgroupV1GetMemoryUsage (rhbz#1689297) +- vircgroup: extract virCgroupV1(Set|Get)Memory*Limit (rhbz#1689297) +- vircgroup: extract virCgroupV1GetMemSwapUsage (rhbz#1689297) +- vircgroup: extract virCgroupV1(Allow|Deny)Device (rhbz#1689297) +- vircgroup: extract virCgroupV1(Allow|Deny)AllDevices (rhbz#1689297) +- vircgroup: extract virCgroupV1(Set|Get)CpuShares (rhbz#1689297) +- vircgroup: extract virCgroupV1(Set|Get)CpuCfsPeriod (rhbz#1689297) +- vircgroup: extract virCgroupV1(Set|Get)CpuCfsQuota (rhbz#1689297) +- vircgroup: extract virCgroupV1SupportsCpuBW (rhbz#1689297) +- vircgroup: extract virCgroupV1GetCpuacct*Usage (rhbz#1689297) +- vircgroup: extract virCgroupV1GetCpuacctStat (rhbz#1689297) +- vircgroup: extract virCgroupV1(Set|Get)FreezerState (rhbz#1689297) +- vircgroup: extract virCgroupV1(Set|Get)CpusetMems (rhbz#1689297) +- vircgroup: extract virCgroupV1(Set|Get)CpusetMemoryMigrate (rhbz#1689297) +- vircgroup: extract virCgroupV1(Set|Get)CpusetCpus (rhbz#1689297) +- vircgroup: rename virCgroupController into virCgroupV1Controller (rhbz#1689297) +- vircgroup: rename controllers to legacy (rhbz#1689297) +- vircgroup: remove VIR_CGROUP_SUPPORTED (rhbz#1689297) +- vircgroup: include system headers only on linux (rhbz#1689297) +- vircgroupv1: fix build on non-linux OSes (rhbz#1689297) +- Revert "vircgroup: cleanup controllers not managed by systemd on error" (rhbz#1689297) +- util: introduce cgroup v2 files (rhbz#1689297) +- vircgroup: introduce virCgroupV2Available (rhbz#1689297) +- vircgroup: introduce virCgroupV2ValidateMachineGroup (rhbz#1689297) +- vircgroup: introduce virCgroupV2CopyMounts (rhbz#1689297) +- vircgroup: introduce virCgroupV2CopyPlacement (rhbz#1689297) +- vircgroup: introduce virCgroupV2DetectMounts (rhbz#1689297) +- vircgroup: introduce virCgroupV2DetectPlacement (rhbz#1689297) +- vircgroup: introduce virCgroupV2ValidatePlacement (rhbz#1689297) +- vircgroup: introduce virCgroupV2StealPlacement (rhbz#1689297) +- vircgroup: introduce virCgroupV2DetectControllers (rhbz#1689297) +- vircgroup: introduce virCgroupV2HasController (rhbz#1689297) +- vircgroup: introduce virCgroupV2GetAnyController (rhbz#1689297) +- vircgroup: introduce virCgroupV2PathOfController (rhbz#1689297) +- vircgroup: introduce virCgroupV2MakeGroup (rhbz#1689297) +- vircgroup: introduce virCgroupV2Remove (rhbz#1689297) +- vircgroup: introduce virCgroupV2AddTask (rhbz#1689297) +- vircgroup: introduce virCgroupV2HasEmptyTasks (rhbz#1689297) +- vircgroup: introduce virCgroupV2BindMount (rhbz#1689297) +- vircgroup: introduce virCgroupV2SetOwner (rhbz#1689297) +- vircgroup: introduce virCgroupV2(Set|Get)BlkioWeight (rhbz#1689297) +- vircgroup: introduce virCgroupV2GetBlkioIoServiced (rhbz#1689297) +- vircgroup: introduce virCgroupV2GetBlkioIoDeviceServiced (rhbz#1689297) +- vircgroup: introduce virCgroupV2(Set|Get)BlkioDeviceWeight (rhbz#1689297) +- vircgroup: introduce virCgroupV2(Set|Get)BlkioDeviceReadIops (rhbz#1689297) +- vircgroup: introduce virCgroupV2(Set|Get)BlkioDeviceWriteIops (rhbz#1689297) +- vircgroup: introduce virCgroupV2(Set|Get)BlkioDeviceReadBps (rhbz#1689297) +- vircgroup: introduce virCgroupV2(Set|Get)BlkioDeviceWriteBps (rhbz#1689297) +- vircgroup: introduce virCgroupV2SetMemory (rhbz#1689297) +- vircgroup: introduce virCgroupV2GetMemoryStat (rhbz#1689297) +- vircgroup: introduce virCgroupV2GetMemoryUsage (rhbz#1689297) +- vircgroup: introduce virCgroupV2(Set|Get)MemoryHardLimit (rhbz#1689297) +- vircgroup: introduce virCgroupV2(Set|Get)MemorySoftLimit (rhbz#1689297) +- vircgroup: introduce virCgroupV2(Set|Get)MemSwapHardLimit (rhbz#1689297) +- vircgroup: introduce virCgroupV2GetMemSwapUsage (rhbz#1689297) +- vircgroup: introduce virCgroupV2(Set|Get)CpuShares (rhbz#1689297) +- vircgroup: introduce virCgroupV2(Set|Get)CpuCfsPeriod (rhbz#1689297) +- vircgroup: introduce virCgroupV2(Set|Get)CpuCfsQuota (rhbz#1689297) +- vircgroup: introduce virCgroupV2SupportsCpuBW (rhbz#1689297) +- vircgroup: introduce virCgroupV2GetCpuacctUsage (rhbz#1689297) +- vircgroup: introduce virCgroupV2GetCpuacctStat (rhbz#1689297) +- vircgroup: register cgroup v2 backend (rhbz#1689297) +- vircgroup: add support for hybrid configuration (rhbz#1689297) +- vircgroupmock: change cgroup prefix (rhbz#1689297) +- vircgroupmock: add support to test cgroup v2 (rhbz#1689297) +- vircgrouptest: introduce initFakeFS and cleanupFakeFS helpers (rhbz#1689297) +- vircgrouptest: prepare testCgroupDetectMounts for cgroup v2 (rhbz#1689297) +- vircgrouptest: add detect mounts test for cgroup v2 (rhbz#1689297) +- vircgrouptest: add detect mounts test for hybrid cgroups (rhbz#1689297) +- vircgrouptest: prepare validateCgroup for cgroupv2 (rhbz#1689297) +- vircgrouptest: add cgroup v2 tests (rhbz#1689297) +- vircgrouptest: add hybrid tests (rhbz#1689297) +- virt-host-validate: rewrite cgroup detection to use util/vircgroup (rhbz#1689297) +- virt-host-validate: require freezer for LXC (rhbz#1689297) +- virt-host-validate: Fix build on non-Linux (rhbz#1689297) +- tests: Use correct function name in error path (rhbz#1689297) +- util: Fix virCgroupGetMemoryStat (rhbz#1689297) +- tests: Augment vcgrouptest to add virCgroupGetMemoryStat (rhbz#1689297) +- vircgroup: introduce virCgroupKillRecursiveCB (rhbz#1689297) +- vircgroupv2: fix virCgroupV2ValidateMachineGroup (rhbz#1689297) +- util: implement virCgroupV2(Set|Get)CpusetMems (rhbz#1689297) +- util: implement virCgroupV2(Set|Get)CpusetMemoryMigrate (rhbz#1689297) +- util: implement virCgroupV2(Set|Get)CpusetCpus (rhbz#1689297) +- util: enable cgroups v2 cpuset controller for threads (rhbz#1689297) +- util: vircgroup: pass parent cgroup into virCgroupDetectControllersCB (rhbz#1689297) +- internal: introduce a family of NULLSTR macros (rhbz#1689297) +- util: vircgroup: improve controller detection (rhbz#1689297) +- util: vircgroupv2: use any controller to create thread directory (rhbz#1689297) +- util: vircgroupv2: enable CPU controller only if it's available (rhbz#1689297) +- util: vircgroupv2: separate return values of virCgroupV2EnableController (rhbz#1689297) +- util: vircgroupv2: don't error out if enabling controller fails (rhbz#1689297) +- util: vircgroupv2: mark only requested controllers as available (rhbz#1689297) +- Revert "util: vircgroup: pass parent cgroup into virCgroupDetectControllersCB" (rhbz#1689297) +- util: vircgroupv2: stop enabling missing controllers with systemd (rhbz#1689297) + +* Fri Jun 28 2019 Danilo de Paula - 4.5.0-28 - Rebuild all virt packages to fix RHEL's upgrade path -- Resolves: rhbz#1696354 - (Ensure modular RPM upgrade path [ZStream Clone] [rhel-8.0.0.z]) +- Resolves: rhbz#1695587 + (Ensure modular RPM upgrade path) -* Tue Jun 18 2019 Jiri Denemark - 4.5.0-23.3.el8 +* Fri Jun 21 2019 Jiri Denemark - 4.5.0-27 +- RHEL: spec: Disable gluster on i686 (rhbz#1722668) +- rpc: virnetlibsshsession: update deprecated functions (rhbz#1722735) + +* Thu Jun 20 2019 Jiri Denemark - 4.5.0-26 - api: disallow virDomainSaveImageGetXMLDesc on read-only connections (CVE-2019-10161) - api: disallow virDomainManagedSaveDefineXML on read-only connections (CVE-2019-10166) - api: disallow virConnectGetDomainCapabilities on read-only connections (CVE-2019-10167) - api: disallow virConnect*HypervisorCPU on read-only connections (CVE-2019-10168) -* Thu May 16 2019 Jiri Denemark - 4.5.0-23.2.el8 +* Fri Jun 14 2019 Jiri Denemark - 4.5.0-25 - admin: reject clients unless their UID matches the current UID (CVE-2019-10132) - locking: restrict sockets to mode 0600 (CVE-2019-10132) - logging: restrict sockets to mode 0600 (CVE-2019-10132) - -* Mon May 6 2019 Jiri Denemark - 4.5.0-23.1.el8 -- cpu_x86: Do not cache microcode version (CVE-2018-12130, CVE-2018-12126, CVE-2018-11091, CVE-2018-12127) -- qemu: Don't cache microcode version (CVE-2018-12130, CVE-2018-12126, CVE-2018-11091, CVE-2018-12127) -- cputest: Add data for Intel(R) Xeon(R) CPU E3-1225 v5 (CVE-2018-12130, CVE-2018-12126, CVE-2018-11091, CVE-2018-12127) -- cpu_map: Define md-clear CPUID bit (CVE-2018-12130, CVE-2018-12126, CVE-2018-11091, CVE-2018-12127) +- util: skip RDMA detection for non-PCI network devices (rhbz#1693299) +- virfile: Detect ceph as shared FS (rhbz#1698133) +- virfile: added GPFS as shared fs (rhbz#1698133) +- util: bitmap: define cleanup function using VIR_DEFINE_AUTOPTR_FUNC (rhbz#1716943) +- qemu: Rework setting process affinity (rhbz#1716943) +- qemu: Set up EMULATOR thread and cpuset.mems before exec()-ing qemu (rhbz#1716943) +- conf: Add definitions for 'uid' and 'fid' PCI address attributes (rhbz#1508149) +- qemu: Introduce zPCI capability (rhbz#1508149) +- qemu: Enable PCI multi bus for S390 guests (rhbz#1508149) +- conf: Introduce extension flag and zPCI member for PCI address (rhbz#1508149) +- conf: Introduce address caching for PCI extensions (rhbz#1508149) +- qemu: Auto add pci-root for s390/s390x guests (rhbz#1508149) +- conf: use virXMLFormatElement() in virDomainDeviceInfoFormat() (rhbz#1508149) +- conf: Introduce parser, formatter for uid and fid (rhbz#1508149) +- qemu: Add zPCI address definition check (rhbz#1508149) +- conf: Allocate/release 'uid' and 'fid' in PCI address (rhbz#1508149) +- qemu: Generate and use zPCI device in QEMU command line (rhbz#1508149) +- qemu: Add hotpluging support for PCI devices on S390 guests (rhbz#1508149) +- qemuDomainRemoveRNGDevice: Remove associated chardev too (rhbz#1508149) +- qemu_hotplug: remove erroneous call to qemuDomainDetachExtensionDevice() (rhbz#1508149) +- qemu_hotplug: remove another erroneous qemuDomainDetachExtensionDevice() call (rhbz#1508149) +- util: Propagate numad failures correctly (rhbz#1716907) +- util: Introduce virBitmapUnion() (rhbz#1716908) +- util: Introduce virNumaNodesetToCPUset() (rhbz#1716908) +- qemu: Fix qemuProcessInitCpuAffinity() (rhbz#1716908) +- qemu: Fix leak in qemuProcessInitCpuAffinity() (rhbz#1716908) +- qemu: Drop cleanup label from qemuProcessInitCpuAffinity() (rhbz#1716908) +- qemu: Fix NULL pointer access in qemuProcessInitCpuAffinity() (rhbz#1716908) +- qemuBuildMemoryBackendProps: Pass @priv instead of its individual members (rhbz#1624223) +- qemu: Don't use -mem-prealloc among with .prealloc=yes (rhbz#1624223) +- nwfilter: fix adding std MAC and IP values to filter binding (rhbz#1691356) +- qemuProcessBuildDestroyMemoryPathsImpl: Don't overwrite error (rhbz#1658112) +- qemu_security: Fully implement qemuSecurityDomainSetPathLabel (rhbz#1658112) +- qemu: process: SEV: Assume libDir to be the directory to create files in (rhbz#1658112) +- qemu: process: SEV: Relabel guest owner's SEV files created before start (rhbz#1658112) + +* Tue May 14 2019 Jiri Denemark - 4.5.0-24 +- tests: qemuxml2argv: add CAPS_ARCH_LATEST macro (rhbz#1698855) +- qemu: Add ccw support for vhost-vsock (rhbz#1698855) +- qemu: Allow creating ppc64 guests with graphics and no USB mouse (rhbz#1683681) +- conf: Expose virDomainSCSIDriveAddressIsUsed (rhbz#1692354) +- qemuhotplugtest: Don't plug a SCSI disk at unit 7 (rhbz#1692354) +- qemu_hotplug: Check for duplicate drive addresses (rhbz#1692354) +- cpu_map: Add support for cldemote CPU feature (rhbz#1537731) +- util: alloc: add macros for implementing automatic cleanup functionality (rhbz#1505998) +- qemu: domain: Simplify non-VFIO memLockLimit calculation for PPC64 (rhbz#1505998) +- qemu_domain: add a PPC64 memLockLimit helper (rhbz#1505998) +- qemu_domain: NVLink2 bridge detection function for PPC64 (rhbz#1505998) +- PPC64 support for NVIDIA V100 GPU with NVLink2 passthrough (rhbz#1505998) +- cpu_x86: Do not cache microcode version (CVE-2018-12127, CVE-2019-11091, CVE-2018-12126, CVE-2018-12130) +- qemu: Don't cache microcode version (CVE-2018-12127, CVE-2019-11091, CVE-2018-12126, CVE-2018-12130) +- cputest: Add data for Intel(R) Xeon(R) CPU E3-1225 v5 (CVE-2018-12127, CVE-2019-11091, CVE-2018-12126, CVE-2018-12130) +- cpu_map: Define md-clear CPUID bit (CVE-2018-12127, CVE-2019-11091, CVE-2018-12126, CVE-2018-12130) * Fri Feb 15 2019 Jiri Denemark - 4.5.0-23 - network: explicitly allow icmp/icmpv6 in libvirt zonefile (rhbz#1650320)