From c6f0aa11035e9cf012acd516fa8a62c27b85ea83 Mon Sep 17 00:00:00 2001 From: AlexChen Date: Wed, 16 Sep 2020 19:11:13 +0800 Subject: [PATCH 1/7] tests/commandtest: skip the test4 and test18 if the testcase is run in the container env Signed-off-by: AlexChen --- ...t-skip-the-test4-if-the-testcase-is-.patch | 73 +++++++++++++++++++ libvirt.spec | 5 +- 2 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 libvirt-tests-commandtest-skip-the-test4-if-the-testcase-is-.patch diff --git a/libvirt-tests-commandtest-skip-the-test4-if-the-testcase-is-.patch b/libvirt-tests-commandtest-skip-the-test4-if-the-testcase-is-.patch new file mode 100644 index 0000000..4e56639 --- /dev/null +++ b/libvirt-tests-commandtest-skip-the-test4-if-the-testcase-is-.patch @@ -0,0 +1,73 @@ +From df5d95b8db5ec8a79dee223338a72a9f8897a538 Mon Sep 17 00:00:00 2001 +From: AlexChen +Date: Wed, 16 Sep 2020 15:53:57 +0800 +Subject: [PATCH] tests/commandtest: skip the test4 if the testcase is run in + the container env + +In a container environment without an init thread, the daemoned +process is not reclaimed, and Test4 loops forever, causing +the compilation to hung. So, skip it. + +Signed-off-by: AlexChen +--- + tests/commandtest.c | 23 ++++++++++++++++++----- + 1 file changed, 18 insertions(+), 5 deletions(-) + +diff --git a/tests/commandtest.c b/tests/commandtest.c +index d5092b7dd0..2cc27c64a1 100644 +--- a/tests/commandtest.c ++++ b/tests/commandtest.c +@@ -259,6 +259,7 @@ static int test4(const void *unused G_GNUC_UNUSED) + char *pidfile = virPidFileBuildPath(abs_builddir, "commandhelper"); + pid_t pid; + int ret = -1; ++ int count = 0; + + if (!pidfile) + goto cleanup; +@@ -275,9 +276,14 @@ static int test4(const void *unused G_GNUC_UNUSED) + printf("cannot read pidfile\n"); + goto cleanup; + } +- while (kill(pid, 0) != -1) +- g_usleep(100*1000); +- ++ while (kill(pid, 0) != -1) { ++ if (count++ >= 600) { ++ printf("check time exceeds 60s, it may be in container env, " ++ "skip this testcase!!!\n"); ++ break; ++ } ++ g_usleep(100*1000); /* 100ms */ ++ } + ret = checkoutput("test4", NULL); + + cleanup: +@@ -734,6 +740,7 @@ static int test18(const void *unused G_GNUC_UNUSED) + char *pidfile = virPidFileBuildPath(abs_builddir, "commandhelper"); + pid_t pid; + int ret = -1; ++ int count = 0; + + if (!pidfile) + goto cleanup; +@@ -760,8 +767,14 @@ static int test18(const void *unused G_GNUC_UNUSED) + goto cleanup; + } + +- while (kill(pid, SIGINT) != -1) +- g_usleep(100*1000); ++ while (kill(pid, SIGINT) != -1) { ++ if (count++ >= 600) { ++ printf("check time exceeds 60s, it may be in container env, " ++ "skip this testcase!!!\n"); ++ break; ++ } ++ g_usleep(100*1000); /* 100ms */ ++ } + + ret = 0; + +-- +2.23.0 + diff --git a/libvirt.spec b/libvirt.spec index 203361e..c16d114 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -99,7 +99,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 6.2.0 -Release: 8 +Release: 9 License: LGPLv2+ URL: https://libvirt.org/ @@ -132,6 +132,7 @@ Patch0021: libvirt-Substitute-security_context_t-with-char.patch Patch0022: libvirt-conf-Don-t-format-http-cookies-unless-VIR_DOMAIN_DEF.patch Patch0023: libvirt-virstoragetest-testBackingParse-Use-VIR_DOMAIN_DEF_F.patch Patch0024: libvirt-support-aarch64-vtpm-with-parameter-tpm-tis-.patch +Patch0025: libvirt-tests-commandtest-skip-the-test4-if-the-testcase-is-.patch Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} @@ -1864,6 +1865,8 @@ exit 0 %changelog +* Wed Aug 5 2020 AlexChen - 6.2.0-9 +- tests: skip the test4 if the testcase is run in the container env * Wed Aug 5 2020 Jiang Fangjie - 6.2.0-8 - Libvirt supports aarch64 vtpm with parameter tpm-tis-device * Tue Aug 4 2020 Xu Yandong - 6.2.0-7 -- Gitee From 676ca2f0f6232bcc5cdd22556498ee4799249b1a Mon Sep 17 00:00:00 2001 From: Jin Yan Date: Tue, 22 Sep 2020 13:09:21 +0800 Subject: [PATCH 2/7] bugfix: cherry-pick some bugfix patches from open source community bugfix patches list: d677de remote: fix driver name check for libxl driver 075641 systemd: start libvirtd after firewalld iptables services 06fc99 qemuDomainCleanupRun: Actually run cleanup callbacks in reverse order 01626c virDevMapperGetTargetsImpl: quit early if device is not a devmapper target 006782 qemu: only stop external devices after the domain 42a415 qemuDomainStorageSourcePrivateDispose: Free httpcookie cc8c29 Don't require secdrivers to implement .domainMoveImageMetadata 0230e3 qemuProcessStop: Use XATTRs to restore seclabels on disks a domain is mirroring into 8fd274 qemuProcessStop: Reattach NVMe disks a domain is mirroring into 55029d security: don't fail if built without attr support a5a297 qemu: Skip pre creation of NVMe disks 2a372 Fix some wrong usage of ATTRIBUTE_NONNULL e728ff conf: Increase cpuset length limit for CPU pinning 8f58a4 virQEMUDriverConfigNew: Add slash to cfg defaultTLSx509certdir for non-embeded driver 1b22dd qemuDomainSetNumaParamsLive: set nodeset for root cgroup bdb8f2 qemu: do not add model when actual iface type is hostdev Signed-off-by: Jin Yan --- ...cdrivers-to-implement-.domainMoveIma.patch | 42 +++++++ ...ome-wrong-usage-of-ATTRIBUTE_NONNULL.patch | 56 +++++++++ ...-cpuset-length-limit-for-CPU-pinning.patch | 33 ++++++ ...qemu-Skip-pre-creation-of-NVMe-disks.patch | 53 +++++++++ ...model-when-actual-iface-type-is-host.patch | 34 ++++++ ...op-external-devices-after-the-domain.patch | 47 ++++++++ ...pRun-Actually-run-cleanup-callbacks-.patch | 54 +++++++++ ...aParamsLive-set-nodeset-for-root-cgr.patch | 49 ++++++++ ...eSourcePrivateDispose-Free-httpcooki.patch | 43 +++++++ ...Reattach-NVMe-disks-a-domain-is-mirr.patch | 41 +++++++ ...Use-XATTRs-to-restore-seclabels-on-d.patch | 44 ++++++++ ...x-driver-name-check-for-libxl-driver.patch | 38 +++++++ ...t-fail-if-built-without-attr-support.patch | 75 +++++++++++++ ...bvirtd-after-firewalld-iptables-serv.patch | 106 ++++++++++++++++++ ...argetsImpl-quit-early-if-device-is-n.patch | 63 +++++++++++ ...figNew-Add-slash-to-cfg-defaultTLSx5.patch | 35 ++++++ libvirt.spec | 20 +++- 17 files changed, 832 insertions(+), 1 deletion(-) create mode 100644 libvirt-Don-t-require-secdrivers-to-implement-.domainMoveIma.patch create mode 100644 libvirt-Fix-some-wrong-usage-of-ATTRIBUTE_NONNULL.patch create mode 100644 libvirt-conf-Increase-cpuset-length-limit-for-CPU-pinning.patch create mode 100644 libvirt-qemu-Skip-pre-creation-of-NVMe-disks.patch create mode 100644 libvirt-qemu-do-not-add-model-when-actual-iface-type-is-host.patch create mode 100644 libvirt-qemu-only-stop-external-devices-after-the-domain.patch create mode 100644 libvirt-qemuDomainCleanupRun-Actually-run-cleanup-callbacks-.patch create mode 100644 libvirt-qemuDomainSetNumaParamsLive-set-nodeset-for-root-cgr.patch create mode 100644 libvirt-qemuDomainStorageSourcePrivateDispose-Free-httpcooki.patch create mode 100644 libvirt-qemuProcessStop-Reattach-NVMe-disks-a-domain-is-mirr.patch create mode 100644 libvirt-qemuProcessStop-Use-XATTRs-to-restore-seclabels-on-d.patch create mode 100644 libvirt-remote-fix-driver-name-check-for-libxl-driver.patch create mode 100644 libvirt-security-don-t-fail-if-built-without-attr-support.patch create mode 100644 libvirt-systemd-start-libvirtd-after-firewalld-iptables-serv.patch create mode 100644 libvirt-virDevMapperGetTargetsImpl-quit-early-if-device-is-n.patch create mode 100644 libvirt-virQEMUDriverConfigNew-Add-slash-to-cfg-defaultTLSx5.patch diff --git a/libvirt-Don-t-require-secdrivers-to-implement-.domainMoveIma.patch b/libvirt-Don-t-require-secdrivers-to-implement-.domainMoveIma.patch new file mode 100644 index 0000000..579fbc7 --- /dev/null +++ b/libvirt-Don-t-require-secdrivers-to-implement-.domainMoveIma.patch @@ -0,0 +1,42 @@ +From 19845de491a3102df4256a3457c7d5669bccda63 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Mon, 18 May 2020 10:07:30 +0200 +Subject: [PATCH] Don't require secdrivers to implement + .domainMoveImageMetadata + +The AppArmor secdriver does not use labels to grant access to +resources. Therefore, it doesn't use XATTRs and hence it lacks +implementation of .domainMoveImageMetadata callback. This leads +to a harmless but needless error message appearing in the logs: + + virSecurityManagerMoveImageMetadata:476 : this function is not + supported by the connection driver: virSecurityManagerMoveImageMetadata + +Closes: https://gitlab.com/libvirt/libvirt/-/issues/25 + +cherry-pick from commit: cc8c297e473afd55e5d8e35e18345d8df176059d + +Signed-off-by: Michal Privoznik +Reviewed-by: Erik Skultety +Signed-off-by: Jin Yan +--- + src/security/security_manager.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/src/security/security_manager.c b/src/security/security_manager.c +index fe03274..1445291 100644 +--- a/src/security/security_manager.c ++++ b/src/security/security_manager.c +@@ -473,8 +473,7 @@ virSecurityManagerMoveImageMetadata(virSecurityManagerPtr mgr, + return ret; + } + +- virReportUnsupportedError(); +- return -1; ++ return 0; + } + + +-- +1.8.3.1 + diff --git a/libvirt-Fix-some-wrong-usage-of-ATTRIBUTE_NONNULL.patch b/libvirt-Fix-some-wrong-usage-of-ATTRIBUTE_NONNULL.patch new file mode 100644 index 0000000..240f77e --- /dev/null +++ b/libvirt-Fix-some-wrong-usage-of-ATTRIBUTE_NONNULL.patch @@ -0,0 +1,56 @@ +From 42e4b74e1bbd08aad3afa46d741e46c40a8af73d Mon Sep 17 00:00:00 2001 +From: Bihong Yu +Date: Sat, 6 Jun 2020 18:52:35 +0800 +Subject: [PATCH] Fix some wrong usage of ATTRIBUTE_NONNULL() + +The virStateInitialize() function has ATTRIBUTE_NONNULL() +referring to @root argument (incorrectly anyway) but in +daemonRunStateInit() NULL is passed in anyway. + +Then there is virCommandAddArgPair() which also has +ATTRIBUTE_NONNULL() for one of its arguments and then checks the +argument for being NULL anyways. + +cherry-pick from commit: 2a372a5ad5fab3bf26fb9bea019d38fa04ba8b34 + +Signed-off-by:Bihong Yu +Reviewed-by:Chuan Zheng +Signed-off-by: Michal Privoznik +Reviewed-by: Michal Privoznik +Signed-off-by: Jin Yan +--- + src/libvirt_internal.h | 3 +-- + src/util/vircommand.h | 3 +-- + 2 files changed, 2 insertions(+), 4 deletions(-) + +diff --git a/src/libvirt_internal.h b/src/libvirt_internal.h +index 00ef7aa..72c6127 100644 +--- a/src/libvirt_internal.h ++++ b/src/libvirt_internal.h +@@ -33,8 +33,7 @@ int virStateInitialize(bool privileged, + bool mandatory, + const char *root, + virStateInhibitCallback inhibit, +- void *opaque) +- ATTRIBUTE_NONNULL(2); ++ void *opaque); + int virStateCleanup(void); + int virStateReload(void); + int virStateStop(void); +diff --git a/src/util/vircommand.h b/src/util/vircommand.h +index 9086f9a..4e6cb0a 100644 +--- a/src/util/vircommand.h ++++ b/src/util/vircommand.h +@@ -128,8 +128,7 @@ void virCommandAddArgFormat(virCommandPtr cmd, + + void virCommandAddArgPair(virCommandPtr cmd, + const char *name, +- const char *val) +- ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); ++ const char *val); + + void virCommandAddArgSet(virCommandPtr cmd, + const char *const*vals) ATTRIBUTE_NONNULL(2); +-- +1.8.3.1 + diff --git a/libvirt-conf-Increase-cpuset-length-limit-for-CPU-pinning.patch b/libvirt-conf-Increase-cpuset-length-limit-for-CPU-pinning.patch new file mode 100644 index 0000000..7c09892 --- /dev/null +++ b/libvirt-conf-Increase-cpuset-length-limit-for-CPU-pinning.patch @@ -0,0 +1,33 @@ +From fc8c41dbb52eb9ce3ee36680ecb53a41f4146610 Mon Sep 17 00:00:00 2001 +From: Jiri Denemark +Date: Thu, 11 Jun 2020 13:53:27 +0200 +Subject: [PATCH] conf: Increase cpuset length limit for CPU pinning + +Domains are now allowed to be pinned to host CPUs with IDs up to 16383. +The new limit is as arbitrary as the old one. It's just bigger. + +cherry-pick from commit: e728ffba5119cfb1488aa7363fef596940449f50 + +Signed-off-by: Jiri Denemark +Reviewed-by: Michal Privoznik +Signed-off-by: Jin Yan +--- + src/conf/domain_conf.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h +index a40773a..16e6253 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -2241,7 +2241,7 @@ struct _virDomainHugePage { + unsigned long long size; /* hugepage size in KiB */ + }; + +-#define VIR_DOMAIN_CPUMASK_LEN 1024 ++#define VIR_DOMAIN_CPUMASK_LEN 16384 + + struct _virDomainIOThreadIDDef { + bool autofill; +-- +1.8.3.1 + diff --git a/libvirt-qemu-Skip-pre-creation-of-NVMe-disks.patch b/libvirt-qemu-Skip-pre-creation-of-NVMe-disks.patch new file mode 100644 index 0000000..d1c07be --- /dev/null +++ b/libvirt-qemu-Skip-pre-creation-of-NVMe-disks.patch @@ -0,0 +1,53 @@ +From a7f7d8f7513af2b98d01259480f63167cf44cced Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Tue, 26 May 2020 16:26:25 +0200 +Subject: [PATCH] qemu: Skip pre-creation of NVMe disks +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Upon migration with disks, libvirt determines if each disk exists +on the destination and tries to pre-create missing ones. Well, +NVMe disks can't be pre-created, but they can be checked for +presence. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1823639 + +cherry-pick from commit: a5a297f387fee9e9aa4cbc2df6788c330fd33ad1 + +Signed-off-by: Michal Privoznik +Reviewed-by: Ján Tomko +Signed-off-by: Jin Yan +--- + src/qemu/qemu_migration.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c +index 65b47ec..3f4627b 100644 +--- a/src/qemu/qemu_migration.c ++++ b/src/qemu/qemu_migration.c +@@ -315,6 +315,7 @@ qemuMigrationDstPrecreateStorage(virDomainObjPtr vm, + for (i = 0; i < nbd->ndisks; i++) { + virDomainDiskDefPtr disk; + const char *diskSrcPath; ++ g_autofree char *nvmePath = NULL; + + VIR_DEBUG("Looking up disk target '%s' (capacity=%llu)", + nbd->disks[i].target, nbd->disks[i].capacity); +@@ -326,7 +327,12 @@ qemuMigrationDstPrecreateStorage(virDomainObjPtr vm, + goto cleanup; + } + +- diskSrcPath = virDomainDiskGetSource(disk); ++ if (disk->src->type == VIR_STORAGE_TYPE_NVME) { ++ virPCIDeviceAddressGetSysfsFile(&disk->src->nvme->pciAddr, &nvmePath); ++ diskSrcPath = nvmePath; ++ } else { ++ diskSrcPath = virDomainDiskGetSource(disk); ++ } + + /* Skip disks we don't want to migrate and already existing disks. */ + if (!qemuMigrationAnyCopyDisk(disk, nmigrate_disks, migrate_disks) || +-- +1.8.3.1 + diff --git a/libvirt-qemu-do-not-add-model-when-actual-iface-type-is-host.patch b/libvirt-qemu-do-not-add-model-when-actual-iface-type-is-host.patch new file mode 100644 index 0000000..c3b8255 --- /dev/null +++ b/libvirt-qemu-do-not-add-model-when-actual-iface-type-is-host.patch @@ -0,0 +1,34 @@ +From c8a043dcdf4f04288bcfc34c25054dcef571a6a7 Mon Sep 17 00:00:00 2001 +From: Paulo de Rezende Pinatti +Date: Tue, 16 Jun 2020 16:32:10 +0200 +Subject: [PATCH] qemu: do not add model when actual iface type is hostdev + +No default model should be added to the interface +entry at post parse when its actual network type is hostdev +as doing so might cause a mismatch between the interface +definition and its actual device type. + +cherry-pick from commit: bdb8f2e41867ae5dbcc040909b1b8c20fd864a40 + +Signed-off-by: Paulo de Rezende Pinatti +Reviewed-by: Laine Stump +Signed-off-by: Jin Yan +--- + 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 91c1a49..cfada81 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -9334,6 +9334,7 @@ qemuDomainDeviceNetDefPostParse(virDomainNetDefPtr net, + virQEMUCapsPtr qemuCaps) + { + if (net->type != VIR_DOMAIN_NET_TYPE_HOSTDEV && ++ virDomainNetResolveActualType(net) != VIR_DOMAIN_NET_TYPE_HOSTDEV && + !virDomainNetGetModelString(net)) + net->model = qemuDomainDefaultNetModel(def, qemuCaps); + +-- +1.8.3.1 + diff --git a/libvirt-qemu-only-stop-external-devices-after-the-domain.patch b/libvirt-qemu-only-stop-external-devices-after-the-domain.patch new file mode 100644 index 0000000..80a50ec --- /dev/null +++ b/libvirt-qemu-only-stop-external-devices-after-the-domain.patch @@ -0,0 +1,47 @@ +From 7dd15a340179598dece5546c9e4fec9b8e47aca7 Mon Sep 17 00:00:00 2001 +From: Ján Tomko +Date: Tue, 12 May 2020 12:59:07 +0200 +Subject: [PATCH] qemu: only stop external devices after the domain +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +A failure in qemuProcessLaunch would lead to qemuExtDevicesStop +being called twice - once in the cleanup section and then again +in qemuProcessStop. + +However, the first one is called while the QEMU process is +still running, which is too soon for the swtpm process, because +the swtmp_ioctl command can lock up: + +https://bugzilla.redhat.com/show_bug.cgi?id=1822523 + +Remove the first call and only leave the one in qemuProcessStop, +which is called after the QEMU process is killed. + +cherry-pick from commit: 006782a8bc5a27125211946fcb12a40f7d4ed12a + +Signed-off-by: Ján Tomko +Reviewed-by: Daniel Henrique Barboza +Reviewed-by: Erik Skultety +Signed-off-by: Jin Yan +--- + src/qemu/qemu_process.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 6b9f6fb..6fbe0c1 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -6998,8 +6998,6 @@ qemuProcessLaunch(virConnectPtr conn, + ret = 0; + + cleanup: +- if (ret < 0) +- qemuExtDevicesStop(driver, vm); + qemuDomainSecretDestroy(vm); + return ret; + } +-- +1.8.3.1 + diff --git a/libvirt-qemuDomainCleanupRun-Actually-run-cleanup-callbacks-.patch b/libvirt-qemuDomainCleanupRun-Actually-run-cleanup-callbacks-.patch new file mode 100644 index 0000000..98170db --- /dev/null +++ b/libvirt-qemuDomainCleanupRun-Actually-run-cleanup-callbacks-.patch @@ -0,0 +1,54 @@ +From 517d69d6c3935adf59fcf9ed11cb05e1dfa8a6f3 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Tue, 5 May 2020 13:45:44 +0200 +Subject: [PATCH] qemuDomainCleanupRun: Actually run cleanup callbacks in + reverse order +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We have a framework to register cleanup callbacks that are run +when a domain is shut down. The idea is to run callbacks in +reverse order than they were registered. However, looking at the +code this is not the case. Fortunately, this framework is used to +register a single callback and a single callback only - +qemuMigrationDstPrepareCleanup() - therefore there was no problem +just yet. + +cherry-pick from commit: 06fc99b6ceb846b07e1cae3d82916ef50ca5f60e + +Signed-off-by: Michal Privoznik +Reviewed-by: Ján Tomko +Signed-off-by: Jin Yan +--- + src/qemu/qemu_domain.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index b1a4647..36bef67 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -11561,18 +11561,14 @@ qemuDomainCleanupRun(virQEMUDriverPtr driver, + virDomainObjPtr vm) + { + qemuDomainObjPrivatePtr priv = vm->privateData; +- size_t i; + + VIR_DEBUG("driver=%p, vm=%s", driver, vm->def->name); + + /* run cleanup callbacks in reverse order */ +- for (i = 0; i < priv->ncleanupCallbacks; i++) { +- if (priv->cleanupCallbacks[priv->ncleanupCallbacks - (i + 1)]) +- priv->cleanupCallbacks[i](driver, vm); +- } ++ while (priv->ncleanupCallbacks) ++ priv->cleanupCallbacks[--priv->ncleanupCallbacks](driver, vm); + + VIR_FREE(priv->cleanupCallbacks); +- priv->ncleanupCallbacks = 0; + priv->ncleanupCallbacks_max = 0; + } + +-- +1.8.3.1 + diff --git a/libvirt-qemuDomainSetNumaParamsLive-set-nodeset-for-root-cgr.patch b/libvirt-qemuDomainSetNumaParamsLive-set-nodeset-for-root-cgr.patch new file mode 100644 index 0000000..9718f24 --- /dev/null +++ b/libvirt-qemuDomainSetNumaParamsLive-set-nodeset-for-root-cgr.patch @@ -0,0 +1,49 @@ +From 222d16af976dc08ee3ea2008d1dc68b00a1ccc9f Mon Sep 17 00:00:00 2001 +From: Daniel Henrique Barboza +Date: Thu, 11 Jun 2020 15:54:57 -0300 +Subject: [PATCH] qemuDomainSetNumaParamsLive: set nodeset for root cgroup + +This function handles the change of NUMA nodeset for a given +guest, setting CpusetMems for the emulator, vcpus and IOThread +sub-groups. It doesn't set the same nodeset to the root cgroup +though. This means that cpuset.mems of the root cgroup ends up +holding the new nodeset and the old nodeset as well. For +a guest with placement=strict, nodeset='0', doing + +virsh numatune 0 8 --live + +Will make cpuset.mems of emulator, vcpus and iothread to be +"8", but cpuset.mems of the root cgroup will be "0,8". + +This means that any new tasks that ends up landing in the +root cgroup, aside from the emulator/vcpus/iothread sub-groups, +will be split between the old nodeset and the new nodeset, +which is not what we want. + +cherry-pick from commit: 1b22dd6dd44202094e0f78f887cbe790c00e9ebc + +Signed-off-by: Daniel Henrique Barboza +Reviewed-by: Michal Privoznik +Signed-off-by: Jin Yan +--- + src/qemu/qemu_driver.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index 8bc5368..cb049fe 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -9728,6 +9728,10 @@ qemuDomainSetNumaParamsLive(virDomainObjPtr vm, + virCgroupFree(&cgroup_temp); + } + ++ /* set nodeset for root cgroup */ ++ if (virCgroupSetCpusetMems(priv->cgroup, nodeset_str) < 0) ++ goto cleanup; ++ + ret = 0; + cleanup: + virCgroupFree(&cgroup_temp); +-- +1.8.3.1 + diff --git a/libvirt-qemuDomainStorageSourcePrivateDispose-Free-httpcooki.patch b/libvirt-qemuDomainStorageSourcePrivateDispose-Free-httpcooki.patch new file mode 100644 index 0000000..9fc391e --- /dev/null +++ b/libvirt-qemuDomainStorageSourcePrivateDispose-Free-httpcooki.patch @@ -0,0 +1,43 @@ +From 8263665d2003446a9b08181fdcc13b89397aae7d Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Thu, 14 May 2020 10:47:42 +0200 +Subject: [PATCH] qemuDomainStorageSourcePrivateDispose: Free httpcookie + +==156803== 58 (40 direct, 18 indirect) bytes in 1 blocks are definitely lost in loss record 306 of 463 +==156803== at 0x4839EC6: calloc (vg_replace_malloc.c:762) +==156803== by 0x5791AC0: g_malloc0 (in /usr/lib64/libglib-2.0.so.0.6400.1) +==156803== by 0x48F60DC: virAlloc (viralloc.c:48) +==156803== by 0x18DD74: qemuStorageSourcePrivateDataAssignSecinfo (qemu_domain.c:2384) +==156803== by 0x18DFD5: qemuStorageSourcePrivateDataParse (qemu_domain.c:2433) +==156803== by 0x49EC884: virDomainStorageSourceParse (domain_conf.c:9857) +==156803== by 0x49ECBA3: virDomainDiskBackingStoreParse (domain_conf.c:9909) +==156803== by 0x49F129D: virDomainDiskDefParseXML (domain_conf.c:10785) +==156803== by 0x4A1804E: virDomainDefParseXML (domain_conf.c:21543) +==156803== by 0x4A1B60C: virDomainObjParseXML (domain_conf.c:22254) +==156803== by 0x4A1BFE9: virDomainObjParseNode (domain_conf.c:22429) +==156803== by 0x4A1C0B4: virDomainObjParseFile (domain_conf.c:22443 + +cherry-pick from commit: 42a415d5a548d828c4b6bd42ad59dfc44b113fa9 + +Signed-off-by: Michal Privoznik +Reviewed-by: Peter Krempa +Signed-off-by: Jin Yan +--- + 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 36bef67..91c1a49 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -1203,6 +1203,7 @@ qemuDomainStorageSourcePrivateDispose(void *obj) + + g_clear_pointer(&priv->secinfo, qemuDomainSecretInfoFree); + g_clear_pointer(&priv->encinfo, qemuDomainSecretInfoFree); ++ g_clear_pointer(&priv->httpcookie, qemuDomainSecretInfoFree); + } + + +-- +1.8.3.1 + diff --git a/libvirt-qemuProcessStop-Reattach-NVMe-disks-a-domain-is-mirr.patch b/libvirt-qemuProcessStop-Reattach-NVMe-disks-a-domain-is-mirr.patch new file mode 100644 index 0000000..510f073 --- /dev/null +++ b/libvirt-qemuProcessStop-Reattach-NVMe-disks-a-domain-is-mirr.patch @@ -0,0 +1,41 @@ +From 2358e2dd4971793f4c8cc530251ed0b01536e603 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Mon, 18 May 2020 15:11:49 +0200 +Subject: [PATCH] qemuProcessStop: Reattach NVMe disks a domain is mirroring + into + +If the mirror destination is not a file but a NVMe disk, then +call qemuHostdevReAttachOneNVMeDisk() to reattach the NVMe back +to the host. + +This would be done by blockjob code when the job finishes, but in +this case the job won't finish - QEMU is killed meanwhile. + +Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1825785 + +cherry-pick from commit: 8fd2749b2df99f3ac27215e9e4ab8be191c39460 + +Signed-off-by: Michal Privoznik +Reviewed-by: Peter Krempa +Signed-off-by: Jin Yan +--- + src/qemu/qemu_process.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 9285ace..280fed9 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -7606,6 +7606,9 @@ void qemuProcessStop(virQEMUDriverPtr driver, + if (disk->mirror) { + if (qemuSecurityRestoreImageLabel(driver, vm, disk->mirror, false) < 0) + VIR_WARN("Unable to restore security label on %s", disk->dst); ++ ++ if (virStorageSourceChainHasNVMe(disk->mirror)) ++ qemuHostdevReAttachOneNVMeDisk(driver, vm->def->name, disk->mirror); + } + + qemuBlockRemoveImageMetadata(driver, vm, disk->dst, disk->src); +-- +1.8.3.1 + diff --git a/libvirt-qemuProcessStop-Use-XATTRs-to-restore-seclabels-on-d.patch b/libvirt-qemuProcessStop-Use-XATTRs-to-restore-seclabels-on-d.patch new file mode 100644 index 0000000..679d7bd --- /dev/null +++ b/libvirt-qemuProcessStop-Use-XATTRs-to-restore-seclabels-on-d.patch @@ -0,0 +1,44 @@ +From 63846560cf12789ff592374dfc6211d83e693e9d Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Mon, 18 May 2020 15:07:46 +0200 +Subject: [PATCH] qemuProcessStop: Use XATTRs to restore seclabels on disks a + domain is mirroring into + +In v5.10.0-rc1~42 (which was later fixed in v6.0.0-rc1~487) I am +removing XATTRs for a file that QEMU is mirroring a disk into but +it is killed meanwhile. Well, we can call +qemuSecurityRestoreImageLabel() which will not only remove XATTRs +but also use them to restore the original owner of the file. + +This would be done by blockjob code when the job finishes, but in +this case the job won't finish - QEMU is killed meanwhile + +cherry-pick from commit: 0230e3838402624756d6cd913b7d92639fafc7d0 + +Signed-off-by: Michal Privoznik +Reviewed-by: Peter Krempa +Signed-off-by: Jin Yan +--- + src/qemu/qemu_process.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 6fbe0c1..9285ace 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -7603,8 +7603,10 @@ void qemuProcessStop(virQEMUDriverPtr driver, + for (i = 0; i < def->ndisks; i++) { + virDomainDiskDefPtr disk = def->disks[i]; + +- if (disk->mirror) +- qemuBlockRemoveImageMetadata(driver, vm, disk->dst, disk->mirror); ++ if (disk->mirror) { ++ if (qemuSecurityRestoreImageLabel(driver, vm, disk->mirror, false) < 0) ++ VIR_WARN("Unable to restore security label on %s", disk->dst); ++ } + + qemuBlockRemoveImageMetadata(driver, vm, disk->dst, disk->src); + } +-- +1.8.3.1 + diff --git a/libvirt-remote-fix-driver-name-check-for-libxl-driver.patch b/libvirt-remote-fix-driver-name-check-for-libxl-driver.patch new file mode 100644 index 0000000..916a2b7 --- /dev/null +++ b/libvirt-remote-fix-driver-name-check-for-libxl-driver.patch @@ -0,0 +1,38 @@ +From 1285a266c106ebac3fc6d1a7d5bf839a7623a5a0 Mon Sep 17 00:00:00 2001 +From: Daniel P. Berrangé +Date: Mon, 4 May 2020 17:41:46 +0100 +Subject: [PATCH] remote: fix driver name check for libxl driver +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The virConnectGetType() returns "Xen" for libxl, not "LIBXL". + +This prevents users opening a connection to the libxl driver when using +the modular daemons. + +cherry-pick from commit: d677de9d567e3e87be295b91723457b461345caa + +Reviewed-by: Jim Fehlig +Signed-off-by: Daniel P. Berrangé +Signed-off-by: Jin Yan +--- + src/remote/remote_daemon_dispatch.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/remote/remote_daemon_dispatch.c b/src/remote/remote_daemon_dispatch.c +index c5506c2..d2652e3 100644 +--- a/src/remote/remote_daemon_dispatch.c ++++ b/src/remote/remote_daemon_dispatch.c +@@ -2111,7 +2111,7 @@ remoteDispatchConnectOpen(virNetServerPtr server G_GNUC_UNUSED, + + VIR_DEBUG("Primary driver type is '%s'", type); + if (STREQ(type, "QEMU") || +- STREQ(type, "LIBXL") || ++ STREQ(type, "Xen") || + STREQ(type, "LXC") || + STREQ(type, "VBOX") || + STREQ(type, "bhyve") || +-- +1.8.3.1 + diff --git a/libvirt-security-don-t-fail-if-built-without-attr-support.patch b/libvirt-security-don-t-fail-if-built-without-attr-support.patch new file mode 100644 index 0000000..e431498 --- /dev/null +++ b/libvirt-security-don-t-fail-if-built-without-attr-support.patch @@ -0,0 +1,75 @@ +From ba950b814f7a2037829d54e3d1e0522c42c104a4 Mon Sep 17 00:00:00 2001 +From: Christian Ehrhardt +Date: Tue, 26 May 2020 09:33:38 +0200 +Subject: [PATCH] security: don't fail if built without attr support + +If built without attr support removing any image will trigger + qemuBlockRemoveImageMetadata (the one that emits the warning) + -> qemuSecurityMoveImageMetadata + -> virSecurityManagerMoveImageMetadata + -> virSecurityDACMoveImageMetadata + -> virSecurityDACMoveImageMetadataHelper + -> virProcessRunInFork (spawns subprocess) + -> virSecurityMoveRememberedLabel + +In there due to !HAVE_LIBATTR virFileGetXAttrQuiet will return +ENOSYS and from there the chain will error out. + +That is wrong and looks like: + libvirtd[6320]: internal error: child reported (status=125): + libvirtd[6320]: Unable to remove disk metadata on vm testguest from + /var/lib/uvtool/libvirt/images/testguest.qcow (disk target vda) + +This change makes virSecurityDACMoveImageMetadataHelper and +virSecuritySELinuxMoveImageMetadataHelper accept that +error code gracefully and in that sense it is an extension of: +5214b2f1a3f "security: Don't skip label restore on file systems lacking XATTRs" +which does the same for other call chains into the virFile*XAttr functions. + +cherry-pick from commit: 55029d93150e33d70b02b6de2b899c05054c5d3a + +Signed-off-by: Christian Ehrhardt +Reviewed-by: Michal Privoznik +Signed-off-by: Jin Yan +--- + src/security/security_dac.c | 6 ++++++ + src/security/security_selinux.c | 6 ++++++ + 2 files changed, 12 insertions(+) + +diff --git a/src/security/security_dac.c b/src/security/security_dac.c +index 11fff63..51cabf1 100644 +--- a/src/security/security_dac.c ++++ b/src/security/security_dac.c +@@ -1132,6 +1132,12 @@ virSecurityDACMoveImageMetadataHelper(pid_t pid G_GNUC_UNUSED, + + ret = virSecurityMoveRememberedLabel(SECURITY_DAC_NAME, data->src, data->dst); + virSecurityManagerMetadataUnlock(data->mgr, &state); ++ ++ if (ret == -2) { ++ /* Libvirt built without XATTRS */ ++ ret = 0; ++ } ++ + return ret; + } + +diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c +index 72d1658..78ea618 100644 +--- a/src/security/security_selinux.c ++++ b/src/security/security_selinux.c +@@ -1990,6 +1990,12 @@ virSecuritySELinuxMoveImageMetadataHelper(pid_t pid G_GNUC_UNUSED, + + ret = virSecurityMoveRememberedLabel(SECURITY_SELINUX_NAME, data->src, data->dst); + virSecurityManagerMetadataUnlock(data->mgr, &state); ++ ++ if (ret == -2) { ++ /* Libvirt built without XATTRS */ ++ ret = 0; ++ } ++ + return ret; + } + +-- +1.8.3.1 + diff --git a/libvirt-systemd-start-libvirtd-after-firewalld-iptables-serv.patch b/libvirt-systemd-start-libvirtd-after-firewalld-iptables-serv.patch new file mode 100644 index 0000000..8d35964 --- /dev/null +++ b/libvirt-systemd-start-libvirtd-after-firewalld-iptables-serv.patch @@ -0,0 +1,106 @@ +From 1ed313f35a4ac27ed29395ed30ec6e7966b798fd Mon Sep 17 00:00:00 2001 +From: Laine Stump +Date: Fri, 1 May 2020 00:05:50 -0400 +Subject: [PATCH] systemd: start libvirtd after firewalld/iptables services + +When a system has enabled the iptables/ip6tables services rather than +firewalld, there is no explicit ordering of the start of those +services vs. libvirtd. This creates a problem when libvirtd.service is +started before ip[6]tables, as the latter, when it finally is started, +will remove all of the iptables rules that had previously been added +by libvirt, including the custom chains where libvirt's rules are +kept. This results in an error message similar to the following when a +user subsequently tries to start a new libvirt network: + + "Error while activating network: Call to virNetworkCreate failed: + internal error: Failed to apply firewall rules + /usr/sbin/ip6tables -w --table filter --insert LIBVIRT_FWO \ + --in-interface virbr2 --jump REJECT: + ip6tables: No chain/target/match by that name." + +(Prior to logging this error, it also would have caused failure to +forward (or block) traffic in some cases, e.g. for guests on a NATed +network, since libvirt's rules to forward/block had all been deleted +and libvirt didn't know about it, so it couldn't fix the problem) + +When this happens, the problem can be remedied by simply restarting +libvirtd.service (which has the side-effect of reloading all +libvirt-generated firewall rules) + +Instead, we can just explicitly stating in the libvirtd.service file +that libvirtd.service should start after ip6tables.service and +ip6tables.service, eliminating the race condition that leads to the +error. + +There is also nothing (that I can see) in the systemd .service files +to guarantee that firewalld.service will be started (if enabled) prior +to libvirtd.service. The same error scenario given above would occur +if libvirtd.service started before firewalld.service. Even before +that, though libvirtd would have detected that firewalld.service was +disabled, and then turn off all firewalld support. So, for example, +firewalld's libvirt zone wouldn't be used, and most likely traffic +from guests would therefore be blocked (all with no external +indication of the source of the problem other than a debug-level log +when libvirtd was started saying that firewalld wasn't in use); also +libvirtd wouldn't notice when firewalld reloaded its rules (which also +simultaneously deletes all of libvirt's rules). + +I'm not aware of any reports that have been traced back to +libvirtd.service starting before firewalld.service, but have seen that +error reported multiple times, and also don't see an existing +dependency that would guarantee firewalld.service starts before +libvirtd.service, so it's possible it's been happening and we just +haven't gotten to the bottom of it. + +This patch adds an After= line to the libvirtd.service file for each +of iptables.service, ip6tables.service, and firewalld.servicee, which +should guarantee that libvirtd.service isn't started until systemd has +started whichever of the others is enabled. + +This race was diagnosed, and patch proposed, by Jason Montleon in +https://bugzilla.redhat.com/1723698 . At the time (April 2019) danpb +agreed with him that this change to libvirtd.service was a reasonable +thing to do, but I guess everyone thought someone else was going to +post a patch, so in the end nobody did. + +cherry-pick from commit: 0756415f147dda15a417bd79eef9a62027d176e6 + +Signed-off-by: Laine Stump +Reviewed-by: Michal Privoznik +Signed-off-by: Jin Yan +--- + src/network/virtnetworkd.service.in | 3 +++ + src/remote/libvirtd.service.in | 3 +++ + 2 files changed, 6 insertions(+) + +diff --git a/src/network/virtnetworkd.service.in b/src/network/virtnetworkd.service.in +index 656e8b4..56182e1 100644 +--- a/src/network/virtnetworkd.service.in ++++ b/src/network/virtnetworkd.service.in +@@ -5,6 +5,9 @@ Requires=virtnetworkd.socket + Requires=virtnetworkd-ro.socket + Requires=virtnetworkd-admin.socket + After=network.target ++After=firewalld.service ++After=iptables.service ++After=ip6tables.service + After=dbus.service + After=apparmor.service + After=local-fs.target +diff --git a/src/remote/libvirtd.service.in b/src/remote/libvirtd.service.in +index 90b2cad..cc0d4e3 100644 +--- a/src/remote/libvirtd.service.in ++++ b/src/remote/libvirtd.service.in +@@ -11,6 +11,9 @@ Wants=libvirtd-admin.socket + Wants=systemd-machined.service + Before=libvirt-guests.service + After=network.target ++After=firewalld.service ++After=iptables.service ++After=ip6tables.service + After=dbus.service + After=iscsid.service + After=apparmor.service +-- +1.8.3.1 + diff --git a/libvirt-virDevMapperGetTargetsImpl-quit-early-if-device-is-n.patch b/libvirt-virDevMapperGetTargetsImpl-quit-early-if-device-is-n.patch new file mode 100644 index 0000000..b5b5268 --- /dev/null +++ b/libvirt-virDevMapperGetTargetsImpl-quit-early-if-device-is-n.patch @@ -0,0 +1,63 @@ +From c279162d6d335d4302a74c1e19dbce8eaff75679 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Fri, 24 Apr 2020 13:17:51 +0200 +Subject: [PATCH] virDevMapperGetTargetsImpl: quit early if device is not a + devmapper target +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +As suggested in the linked bug, libvirt should firstly check +whether the major number of the device is device mapper major. +Because if it isn't subsequent DM_DEVICE_DEPS task may not only +fail, but also yield different results. In the bugzilla this is +demonstrated by creating a devmapper target named 'loop0' and +then creating loop target /dev/loop0. When the latter is then +passed to a domain, our virDevMapperGetTargetsImpl() function +blindly asks devmapper to provide target dependencies for +/dev/loop0 and because of the way devmapper APIs work, it will +'sanitize' the input by using the last component only which is +'loop0' and thus return different results than expected. + +Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1823976 + +cherry-pick from commit: 01626c668ecfbe465d18799ac4628e6127ea1d47 + +Signed-off-by: Michal Privoznik +Reviewed-by: Ján Tomko +Signed-off-by: Jin Yan +--- + src/util/virdevmapper.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/src/util/virdevmapper.c b/src/util/virdevmapper.c +index feb5982..79dbc3d 100644 +--- a/src/util/virdevmapper.c ++++ b/src/util/virdevmapper.c +@@ -64,6 +64,7 @@ virDevMapperGetTargetsImpl(const char *path, + char ***devPaths_ret, + unsigned int ttl) + { ++ struct stat sb; + struct dm_task *dmt = NULL; + struct dm_deps *deps; + struct dm_info info; +@@ -82,6 +83,15 @@ virDevMapperGetTargetsImpl(const char *path, + return ret; + } + ++ if (stat(path, &sb) < 0) { ++ if (errno == ENOENT) ++ return 0; ++ return -1; ++ } ++ ++ if (!dm_is_dm_major(major(sb.st_dev))) ++ return 0; ++ + if (!(dmt = dm_task_create(DM_DEVICE_DEPS))) { + if (errno == ENOENT || errno == ENODEV) { + /* It's okay. Kernel is probably built without +-- +1.8.3.1 + diff --git a/libvirt-virQEMUDriverConfigNew-Add-slash-to-cfg-defaultTLSx5.patch b/libvirt-virQEMUDriverConfigNew-Add-slash-to-cfg-defaultTLSx5.patch new file mode 100644 index 0000000..bb1ba29 --- /dev/null +++ b/libvirt-virQEMUDriverConfigNew-Add-slash-to-cfg-defaultTLSx5.patch @@ -0,0 +1,35 @@ +From a34f1d6623f3fb1ec03982ef776e31a4b450158d Mon Sep 17 00:00:00 2001 +From: Peter Krempa +Date: Tue, 16 Jun 2020 12:36:55 +0200 +Subject: [PATCH] virQEMUDriverConfigNew: Add slash to + cfg->defaultTLSx509certdir for non-embedded driver + +Commit 068efae5b1a9ef accidentally removed the slash. + +https://bugzilla.redhat.com/show_bug.cgi?id=1847234 + +cherry-pick from commit: 8f58a4003532d5fffdadf2adc659c94eba3fa21a + +Signed-off-by: Peter Krempa +Reviewed-by: Andrea Bolognani +Signed-off-by: Jin Yan +--- + src/qemu/qemu_conf.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c +index 15837ce..809e8fe 100644 +--- a/src/qemu/qemu_conf.c ++++ b/src/qemu/qemu_conf.c +@@ -234,7 +234,7 @@ virQEMUDriverConfigPtr virQEMUDriverConfigNew(bool privileged, + * directory doesn't exist (although we don't check if this exists). + */ + if (root == NULL) { +- cfg->defaultTLSx509certdir = g_strdup(SYSCONFDIR "pki/qemu"); ++ cfg->defaultTLSx509certdir = g_strdup(SYSCONFDIR "/pki/qemu"); + } else { + cfg->defaultTLSx509certdir = g_strdup_printf("%s/etc/pki/qemu", root); + } +-- +1.8.3.1 + diff --git a/libvirt.spec b/libvirt.spec index c16d114..887a511 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -99,7 +99,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 6.2.0 -Release: 9 +Release: 10 License: LGPLv2+ URL: https://libvirt.org/ @@ -133,6 +133,22 @@ Patch0022: libvirt-conf-Don-t-format-http-cookies-unless-VIR_DOMAIN_DEF.patch Patch0023: libvirt-virstoragetest-testBackingParse-Use-VIR_DOMAIN_DEF_F.patch Patch0024: libvirt-support-aarch64-vtpm-with-parameter-tpm-tis-.patch Patch0025: libvirt-tests-commandtest-skip-the-test4-if-the-testcase-is-.patch +Patch0026: libvirt-remote-fix-driver-name-check-for-libxl-driver.patch +Patch0027: libvirt-systemd-start-libvirtd-after-firewalld-iptables-serv.patch +Patch0028: libvirt-qemuDomainCleanupRun-Actually-run-cleanup-callbacks-.patch +Patch0029: libvirt-virDevMapperGetTargetsImpl-quit-early-if-device-is-n.patch +Patch0030: libvirt-qemu-only-stop-external-devices-after-the-domain.patch +Patch0031: libvirt-qemuDomainStorageSourcePrivateDispose-Free-httpcooki.patch +Patch0032: libvirt-Don-t-require-secdrivers-to-implement-.domainMoveIma.patch +Patch0033: libvirt-qemuProcessStop-Use-XATTRs-to-restore-seclabels-on-d.patch +Patch0034: libvirt-qemuProcessStop-Reattach-NVMe-disks-a-domain-is-mirr.patch +Patch0035: libvirt-security-don-t-fail-if-built-without-attr-support.patch +Patch0036: libvirt-qemu-Skip-pre-creation-of-NVMe-disks.patch +Patch0037: libvirt-Fix-some-wrong-usage-of-ATTRIBUTE_NONNULL.patch +Patch0038: libvirt-conf-Increase-cpuset-length-limit-for-CPU-pinning.patch +Patch0039: libvirt-virQEMUDriverConfigNew-Add-slash-to-cfg-defaultTLSx5.patch +Patch0040: libvirt-qemuDomainSetNumaParamsLive-set-nodeset-for-root-cgr.patch +Patch0041: libvirt-qemu-do-not-add-model-when-actual-iface-type-is-host.patch Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} @@ -1865,6 +1881,8 @@ exit 0 %changelog +* Tue Sep 22 2020 Jin Yan - 6.2.0-10 +- bugfix: cherry-pick some bugfix patches from opensource community * Wed Aug 5 2020 AlexChen - 6.2.0-9 - tests: skip the test4 if the testcase is run in the container env * Wed Aug 5 2020 Jiang Fangjie - 6.2.0-8 -- Gitee From 25f331e848aaf383aa80b0ccaee2fcbca669a0d0 Mon Sep 17 00:00:00 2001 From: Zeyu Jin Date: Tue, 22 Sep 2020 17:31:10 +0800 Subject: [PATCH 3/7] bugfix: backport an upstream patch to fix '/run/libvirt/qemu/dbus' racing bug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are races condiction to make '/run/libvirt/qemu/dbus' directory in virDirCreateNoFork() while concurrent start VMs, and get "failed to create directory '/run/libvirt/qemu/dbus': File exists" error message. pre-create the dbus directory in qemuStateInitialize. Signed-off-by: Bihong Yu Reviewed-by: Ján Tomko Signed-off-by: Ján Tomko --- ...the-dbus-directory-in-qemuStateIniti.patch | 92 +++++++++++++++++++ libvirt.spec | 5 +- 2 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 libvirt-qemu-pre-create-the-dbus-directory-in-qemuStateIniti.patch diff --git a/libvirt-qemu-pre-create-the-dbus-directory-in-qemuStateIniti.patch b/libvirt-qemu-pre-create-the-dbus-directory-in-qemuStateIniti.patch new file mode 100644 index 0000000..7c2dae6 --- /dev/null +++ b/libvirt-qemu-pre-create-the-dbus-directory-in-qemuStateIniti.patch @@ -0,0 +1,92 @@ +From 3ee423c363b69588e82e522ad1634193284c09a7 Mon Sep 17 00:00:00 2001 +From: Bihong Yu +Date: Tue, 14 Jul 2020 15:44:05 +0800 +Subject: [PATCH] qemu: pre-create the dbus directory in qemuStateInitialize +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +There are races condiction to make '/run/libvirt/qemu/dbus' directory in +virDirCreateNoFork() while concurrent start VMs, and get "failed to create +directory '/run/libvirt/qemu/dbus': File exists" error message. pre-create the +dbus directory in qemuStateInitialize. + +Signed-off-by: Bihong Yu +Reviewed-by: Ján Tomko +Signed-off-by: Ján Tomko +--- + src/qemu/qemu_dbus.c | 10 ---------- + src/qemu/qemu_dbus.h | 2 -- + src/qemu/qemu_driver.c | 7 +++++++ + src/qemu/qemu_process.c | 3 --- + 4 files changed, 7 insertions(+), 15 deletions(-) + +diff --git a/src/qemu/qemu_dbus.c b/src/qemu/qemu_dbus.c +index 51f6c94e3e..81042876fe 100644 +--- a/src/qemu/qemu_dbus.c ++++ b/src/qemu/qemu_dbus.c +@@ -33,16 +33,6 @@ + VIR_LOG_INIT("qemu.dbus"); + + +-int +-qemuDBusPrepareHost(virQEMUDriverPtr driver) +-{ +- g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); +- +- return virDirCreate(cfg->dbusStateDir, 0770, cfg->user, cfg->group, +- VIR_DIR_CREATE_ALLOW_EXIST); +-} +- +- + static char * + qemuDBusCreatePidFilename(virQEMUDriverConfigPtr cfg, + const char *shortName) +diff --git a/src/qemu/qemu_dbus.h b/src/qemu/qemu_dbus.h +index 474eb1058b..3c2145a223 100644 +--- a/src/qemu/qemu_dbus.h ++++ b/src/qemu/qemu_dbus.h +@@ -21,8 +21,6 @@ + #include "qemu_conf.h" + #include "qemu_domain.h" + +-int qemuDBusPrepareHost(virQEMUDriverPtr driver); +- + char *qemuDBusGetAddress(virQEMUDriverPtr driver, + virDomainObjPtr vm); + +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index 8e81c30a93..53980d4d78 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -743,6 +743,13 @@ qemuStateInitialize(bool privileged, + goto error; + } + ++ if (virDirCreate(cfg->dbusStateDir, 0770, cfg->user, cfg->group, ++ VIR_DIR_CREATE_ALLOW_EXIST) < 0) { ++ virReportSystemError(errno, _("Failed to create dbus state dir %s"), ++ cfg->dbusStateDir); ++ goto error; ++ } ++ + if ((qemu_driver->lockFD = + virPidFileAcquire(cfg->stateDir, "driver", false, getpid())) < 0) + goto error; +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index e8b15ee3ca..1006f41614 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -6466,9 +6466,6 @@ qemuProcessPrepareHost(virQEMUDriverPtr driver, + qemuDomainObjPrivatePtr priv = vm->privateData; + g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); + +- if (qemuDBusPrepareHost(driver) < 0) +- return -1; +- + if (qemuPrepareNVRAM(cfg, vm) < 0) + return -1; + +-- +2.25.0.windows.1 + diff --git a/libvirt.spec b/libvirt.spec index 887a511..8feb4ef 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -99,7 +99,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 6.2.0 -Release: 10 +Release: 11 License: LGPLv2+ URL: https://libvirt.org/ @@ -149,6 +149,7 @@ Patch0038: libvirt-conf-Increase-cpuset-length-limit-for-CPU-pinning.patch Patch0039: libvirt-virQEMUDriverConfigNew-Add-slash-to-cfg-defaultTLSx5.patch Patch0040: libvirt-qemuDomainSetNumaParamsLive-set-nodeset-for-root-cgr.patch Patch0041: libvirt-qemu-do-not-add-model-when-actual-iface-type-is-host.patch +Patch0042: libvirt-qemu-pre-create-the-dbus-directory-in-qemuStateIniti.patch Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} @@ -1881,6 +1882,8 @@ exit 0 %changelog +* Tue Sep 22 2020 Zeyu Jin - 6.2.0-11 +- bugfix: backport an upstream patch to fix '/run/libvirt/qemu/dbus' racing bug. * Tue Sep 22 2020 Jin Yan - 6.2.0-10 - bugfix: cherry-pick some bugfix patches from opensource community * Wed Aug 5 2020 AlexChen - 6.2.0-9 -- Gitee From f25125ef959598c85370371f14129d1f923f1a5a Mon Sep 17 00:00:00 2001 From: hao__wangh Date: Tue, 22 Sep 2020 17:11:07 +0800 Subject: [PATCH 4/7] backport upstream patches --- ...or-OOM-after-calling-xmlBufferCreate.patch | 100 ++++++++++++++++ libvirt-leaseshelper-Report-more-errors.patch | 66 +++++++++++ ...easeshelper-Wait-to-acquire-PID-file.patch | 45 ++++++++ ...ramfb-attribute-for-mediated-devices.patch | 107 ++++++++++++++++++ ...ackendProps-Use-boolean-type-for-pme.patch | 57 ++++++++++ ...rl-Do-not-open-directory-for-writing.patch | 40 +++++++ libvirt.spec | 10 +- 7 files changed, 424 insertions(+), 1 deletion(-) create mode 100644 libvirt-conf-vmx-check-for-OOM-after-calling-xmlBufferCreate.patch create mode 100644 libvirt-leaseshelper-Report-more-errors.patch create mode 100644 libvirt-leaseshelper-Wait-to-acquire-PID-file.patch create mode 100644 libvirt-qemu-format-ramfb-attribute-for-mediated-devices.patch create mode 100644 libvirt-qemuBuildMemoryBackendProps-Use-boolean-type-for-pme.patch create mode 100644 libvirt-resctrl-Do-not-open-directory-for-writing.patch diff --git a/libvirt-conf-vmx-check-for-OOM-after-calling-xmlBufferCreate.patch b/libvirt-conf-vmx-check-for-OOM-after-calling-xmlBufferCreate.patch new file mode 100644 index 0000000..e822e9d --- /dev/null +++ b/libvirt-conf-vmx-check-for-OOM-after-calling-xmlBufferCreate.patch @@ -0,0 +1,100 @@ +From 657c7f5d79fe43823ffb4d46e244bea15a65baf6 Mon Sep 17 00:00:00 2001 +From: Laine Stump +Date: Thu, 18 Jun 2020 12:49:09 -0400 +Subject: [PATCH 1/6] conf, vmx: check for OOM after calling xmlBufferCreate() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Although libvirt itself uses g_malloc0() and friends, which exit when +there isn't enouogh memory, libxml2 uses standard malloc(), which just +returns NULL on OOM - this means we must check for NULL on return from +any libxml2 functions that allocate memory. + +xmlBufferCreate(), for example, might return NULL, and we don't always +check for it. This patch adds checks where it isn't already done. + +(NB: Although libxml2 has a provision for changing behavior on OOM (by +calling xmlMemSetup() to change what functions are used to +allocating/freeing memory), we can't use that, since parts of libvirt +code end up in libvirt.so, which is linked and called directly by +applications that may themselves use libxml2 (and may have already set +their own alternate malloc()), e.g. drivers like esx which live totally +in the library rather than a separate process.) + +cherry pick from: b7a92bce070fd57844a59bf8b1c30cb4ef4f3acd + +Signed-off-by: Laine Stump +Reviewed-by: Ján Tomko +--- + src/conf/domain_conf.c | 6 +++++- + src/conf/network_conf.c | 6 +++++- + src/vmx/vmx.c | 11 +++++++---- + 3 files changed, 17 insertions(+), 6 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 914e03c..37c785a 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -29022,7 +29022,11 @@ virDomainDefFormatInternalSetRootName(virDomainDefPtr def, + * Thankfully, libxml maps what looks like globals into + * thread-local uses, so we are thread-safe. */ + xmlIndentTreeOutput = 1; +- xmlbuf = xmlBufferCreate(); ++ if (!(xmlbuf = xmlBufferCreate())) { ++ virReportOOMError(); ++ goto error; ++ } ++ + if (xmlNodeDump(xmlbuf, def->metadata->doc, def->metadata, + virBufferGetIndent(buf) / 2, 1) < 0) { + xmlBufferFree(xmlbuf); +diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c +index 819b645..c379042 100644 +--- a/src/conf/network_conf.c ++++ b/src/conf/network_conf.c +@@ -2478,7 +2478,11 @@ virNetworkDefFormatBuf(virBufferPtr buf, + * Thankfully, libxml maps what looks like globals into + * thread-local uses, so we are thread-safe. */ + xmlIndentTreeOutput = 1; +- xmlbuf = xmlBufferCreate(); ++ if (!(xmlbuf = xmlBufferCreate())) { ++ virReportOOMError(); ++ return -1; ++ } ++ + if (xmlNodeDump(xmlbuf, def->metadata->doc, def->metadata, + virBufferGetIndent(buf) / 2, 1) < 0) { + xmlBufferFree(xmlbuf); +diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c +index b1fd118..fbc8366 100644 +--- a/src/vmx/vmx.c ++++ b/src/vmx/vmx.c +@@ -697,8 +697,8 @@ virVMXConvertToUTF8(const char *encoding, const char *string) + { + char *result = NULL; + xmlCharEncodingHandlerPtr handler; +- xmlBufferPtr input; +- xmlBufferPtr utf8; ++ xmlBufferPtr input = NULL; ++ xmlBufferPtr utf8 = NULL; + + handler = xmlFindCharEncodingHandler(encoding); + +@@ -708,8 +708,11 @@ virVMXConvertToUTF8(const char *encoding, const char *string) + return NULL; + } + +- input = xmlBufferCreateStatic((char *)string, strlen(string)); +- utf8 = xmlBufferCreate(); ++ if (!(input = xmlBufferCreateStatic((char *)string, strlen(string))) || ++ !(utf8 = xmlBufferCreate())) { ++ virReportOOMError(); ++ goto cleanup; ++ } + + if (xmlCharEncInFunc(handler, utf8, input) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, +-- +1.8.3.1 + diff --git a/libvirt-leaseshelper-Report-more-errors.patch b/libvirt-leaseshelper-Report-more-errors.patch new file mode 100644 index 0000000..b6dce6f --- /dev/null +++ b/libvirt-leaseshelper-Report-more-errors.patch @@ -0,0 +1,66 @@ +From cc842aa3030697b1a454e15ccfb2a201e57d5602 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Mon, 15 Jun 2020 12:53:48 +0200 +Subject: [PATCH 3/6] leaseshelper: Report more errors +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Some functions or code paths that may fail don't report error +(e.g. when acquiring PID file fails) leading to a silent quit +of the leaseshelper. This makes it super hard for us and users +to debug what is happening. Fortunately, dnsmasq captures both +stdout and stderr so we can write an error message there. + +cherry pick from: 9ed345ac1a035c8cf1de37431de638f4bac41de3 + +Signed-off-by: Michal Privoznik +Reviewed-by: Daniel P. Berrangé +--- + src/network/leaseshelper.c | 18 ++++++++++++++---- + 1 file changed, 14 insertions(+), 4 deletions(-) + +diff --git a/src/network/leaseshelper.c b/src/network/leaseshelper.c +index 86c847d..2b5fc0f 100644 +--- a/src/network/leaseshelper.c ++++ b/src/network/leaseshelper.c +@@ -131,8 +131,10 @@ main(int argc, char **argv) + * events for expired leases. So, libvirtd sets another env var for this + * purpose */ + if (!interface && +- !(interface = getenv("VIR_BRIDGE_NAME"))) +- goto cleanup; ++ !(interface = getenv("VIR_BRIDGE_NAME"))) { ++ fprintf(stderr, _("interface not set\n")); ++ exit(EXIT_FAILURE); ++ } + + ip = argv[3]; + mac = argv[2]; +@@ -160,13 +162,21 @@ main(int argc, char **argv) + pid_file = g_strdup(RUNSTATEDIR "/leaseshelper.pid"); + + /* Try to claim the pidfile, exiting if we can't */ +- if ((pid_file_fd = virPidFileAcquirePath(pid_file, true, getpid())) < 0) ++ if ((pid_file_fd = virPidFileAcquirePath(pid_file, true, getpid())) < 0) { ++ fprintf(stderr, ++ _("Unable to acquire PID file: %s\n errno=%d"), ++ pid_file, errno); + goto cleanup; ++ } + + /* Since interfaces can be hot plugged, we need to make sure that the + * corresponding custom lease file exists. If not, 'touch' it */ +- if (virFileTouch(custom_lease_file, 0644) < 0) ++ if (virFileTouch(custom_lease_file, 0644) < 0) { ++ fprintf(stderr, ++ _("Unable to create: %s\n errno=%d"), ++ custom_lease_file, errno); + goto cleanup; ++ } + + switch ((enum virLeaseActionFlags) action) { + case VIR_LEASE_ACTION_ADD: +-- +1.8.3.1 + diff --git a/libvirt-leaseshelper-Wait-to-acquire-PID-file.patch b/libvirt-leaseshelper-Wait-to-acquire-PID-file.patch new file mode 100644 index 0000000..4cbdd02 --- /dev/null +++ b/libvirt-leaseshelper-Wait-to-acquire-PID-file.patch @@ -0,0 +1,45 @@ +From 173b80e8f8103f26438d344e9b97335d4e5036b4 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Thu, 11 Jun 2020 16:43:22 +0200 +Subject: [PATCH 2/6] leaseshelper: Wait to acquire PID file +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +On a DHCP transaction, dnsmasq runs our leases helper which +updates corresponding JSON files. While one dnsmasq won't run the +leaseshelper in parallel, two dnsmasqs (from two distinct +networks) might. To avoid corrupting JSON file, the leaseshelper +acquires PID file first. Well, the way it's acquiring it is not +ideal - it calls virPidFileAcquirePath(wait = false); which +means, that either it acquires the PID file instantly or returns +an error and does not touch the JSON at all. This in turn means +that there might be a leases record missing. With wait = true, +this won't happen. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1840307 + +cherry pick from: 876211ef4a192df1603b45715044ec14567d7e9f + +Signed-off-by: Michal Privoznik +Reviewed-by: Daniel P. Berrangé +--- + src/network/leaseshelper.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/network/leaseshelper.c b/src/network/leaseshelper.c +index a1780ca..86c847d 100644 +--- a/src/network/leaseshelper.c ++++ b/src/network/leaseshelper.c +@@ -160,7 +160,7 @@ main(int argc, char **argv) + pid_file = g_strdup(RUNSTATEDIR "/leaseshelper.pid"); + + /* Try to claim the pidfile, exiting if we can't */ +- if ((pid_file_fd = virPidFileAcquirePath(pid_file, false, getpid())) < 0) ++ if ((pid_file_fd = virPidFileAcquirePath(pid_file, true, getpid())) < 0) + goto cleanup; + + /* Since interfaces can be hot plugged, we need to make sure that the +-- +1.8.3.1 + diff --git a/libvirt-qemu-format-ramfb-attribute-for-mediated-devices.patch b/libvirt-qemu-format-ramfb-attribute-for-mediated-devices.patch new file mode 100644 index 0000000..0cbf3a4 --- /dev/null +++ b/libvirt-qemu-format-ramfb-attribute-for-mediated-devices.patch @@ -0,0 +1,107 @@ +From e017f95c7d833c0e9a463a1613d01fe93020606b Mon Sep 17 00:00:00 2001 +From: Jonathon Jongsma +Date: Tue, 23 Jun 2020 13:29:56 -0500 +Subject: [PATCH 5/6] qemu: format 'ramfb' attribute for mediated devices +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +It's possible to use ramfb as the boot display of an assigned vgpu +device. This was introduced in 4b95738c, but unfortunately the attribute +was not formatted into the xml output for such a device. This patch +fixes that oversight and adds a xml2xml test to verify proper behavior. + +https://bugzilla.redhat.com/show_bug.cgi?id=1847791 + +cherry pick from: c5815b31976f3982d18c7f6c1367ab6e403eb7eb + +Signed-off-by: Jonathon Jongsma +Reviewed-by: Daniel Henrique Barboza +Signed-off-by: Ján Tomko +Reviewed-by: Ján Tomko +--- + src/conf/domain_conf.c | 3 ++ + .../hostdev-mdev-display-ramfb.x86_64-latest.xml | 44 ++++++++++++++++++++++ + tests/qemuxml2xmltest.c | 1 + + 3 files changed, 48 insertions(+) + create mode 100644 tests/qemuxml2xmloutdata/hostdev-mdev-display-ramfb.x86_64-latest.xml + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 37c785a..93e78a0 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -27849,6 +27849,9 @@ virDomainHostdevDefFormat(virBufferPtr buf, + if (mdevsrc->display != VIR_TRISTATE_SWITCH_ABSENT) + virBufferAsprintf(buf, " display='%s'", + virTristateSwitchTypeToString(mdevsrc->display)); ++ if (mdevsrc->ramfb != VIR_TRISTATE_SWITCH_ABSENT) ++ virBufferAsprintf(buf, " ramfb='%s'", ++ virTristateSwitchTypeToString(mdevsrc->ramfb)); + } + + } +diff --git a/tests/qemuxml2xmloutdata/hostdev-mdev-display-ramfb.x86_64-latest.xml b/tests/qemuxml2xmloutdata/hostdev-mdev-display-ramfb.x86_64-latest.xml +new file mode 100644 +index 0000000..c134400 +--- /dev/null ++++ b/tests/qemuxml2xmloutdata/hostdev-mdev-display-ramfb.x86_64-latest.xml +@@ -0,0 +1,44 @@ ++ ++ QEMUGuest2 ++ c7a5fdbd-edaf-9455-926a-d65c16db1809 ++ 219136 ++ 219136 ++ 1 ++ ++ hvm ++ ++ ++ ++ qemu64 ++ ++ ++ destroy ++ restart ++ destroy ++ ++ /usr/bin/qemu-system-i386 ++ ++
++ ++ ++ ++
++ ++ ++ ++ ++ ++ ++