diff --git a/add-phytium-2000plus-and-s2500-support-on-arm-archit.patch b/add-phytium-2000plus-and-s2500-support-on-arm-archit.patch new file mode 100644 index 0000000000000000000000000000000000000000..70dbcdf646f9da32f38ce70db208f2f8a195a0a9 --- /dev/null +++ b/add-phytium-2000plus-and-s2500-support-on-arm-archit.patch @@ -0,0 +1,81 @@ +From a26baed5dd515430c710dc1cfa6561b7beb48639 Mon Sep 17 00:00:00 2001 +From: root +Date: Thu, 4 Feb 2021 17:35:46 +0800 +Subject: [PATCH] add phytium 2000plus and s2500 support on arm architecture + for capability + +Signed-off-by: imxcc +--- + src/cpu_map/Makefile.inc.am | 2 ++ + src/cpu_map/arm_FT-2000plus.xml | 6 ++++++ + src/cpu_map/arm_Tengyun-S2500.xml | 6 ++++++ + src/cpu_map/arm_vendors.xml | 1 + + src/cpu_map/index.xml | 4 ++++ + 5 files changed, 19 insertions(+) + create mode 100644 src/cpu_map/arm_FT-2000plus.xml + create mode 100644 src/cpu_map/arm_Tengyun-S2500.xml + +diff --git a/src/cpu_map/Makefile.inc.am b/src/cpu_map/Makefile.inc.am +index 3059e2b5b7..8eb818706a 100644 +--- a/src/cpu_map/Makefile.inc.am ++++ b/src/cpu_map/Makefile.inc.am +@@ -73,6 +73,8 @@ cpumap_DATA = \ + cpu_map/arm_cortex-a57.xml \ + cpu_map/arm_cortex-a72.xml \ + cpu_map/arm_Kunpeng-920.xml \ ++ cpu_map/arm_FT-2000plus.xml \ ++ cpu_map/arm_Tengyun-S2500.xml \ + $(NULL) + + EXTRA_DIST += $(cpumap_DATA) +diff --git a/src/cpu_map/arm_FT-2000plus.xml b/src/cpu_map/arm_FT-2000plus.xml +new file mode 100644 +index 0000000000..b532f65f68 +--- /dev/null ++++ b/src/cpu_map/arm_FT-2000plus.xml +@@ -0,0 +1,6 @@ ++ ++ ++ ++ ++ ++ +diff --git a/src/cpu_map/arm_Tengyun-S2500.xml b/src/cpu_map/arm_Tengyun-S2500.xml +new file mode 100644 +index 0000000000..22b865e368 +--- /dev/null ++++ b/src/cpu_map/arm_Tengyun-S2500.xml +@@ -0,0 +1,6 @@ ++ ++ ++ ++ ++ ++ +diff --git a/src/cpu_map/arm_vendors.xml b/src/cpu_map/arm_vendors.xml +index 840bf9a2f8..05175495a0 100644 +--- a/src/cpu_map/arm_vendors.xml ++++ b/src/cpu_map/arm_vendors.xml +@@ -11,4 +11,5 @@ + + + ++ + +diff --git a/src/cpu_map/index.xml b/src/cpu_map/index.xml +index c7bbd501fd..3ccc76b9ed 100644 +--- a/src/cpu_map/index.xml ++++ b/src/cpu_map/index.xml +@@ -96,5 +96,9 @@ + + + ++ ++ ++ ++ + + +-- +2.27.0 + diff --git a/conf-domain_conf-pin-the-retry_interval-and-retry_ti.patch b/conf-domain_conf-pin-the-retry_interval-and-retry_ti.patch new file mode 100644 index 0000000000000000000000000000000000000000..0cc4e051aa598f0046af15ad3dcfd27be3b554a7 --- /dev/null +++ b/conf-domain_conf-pin-the-retry_interval-and-retry_ti.patch @@ -0,0 +1,31 @@ +From 0f4c30a060c60ecccd15033a46063acc00f2251f Mon Sep 17 00:00:00 2001 +From: Mao Zhongyi +Date: Sat, 18 Sep 2021 14:20:24 +0800 +Subject: [PATCH] conf/domain_conf: pin the retry_interval and retry_timeout + parameters to xml + +Signed-off-by: Mao Zhongyi +--- + src/conf/domain_conf.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 2b7eee17f0..fa33335c94 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -24976,6 +24976,12 @@ virDomainDiskDefFormatDriver(virBufferPtr buf, + virBufferAsprintf(&driverBuf, " rerror_policy='%s'", + virDomainDiskErrorPolicyTypeToString(disk->rerror_policy)); + ++ if (disk->retry_interval) ++ virBufferAsprintf(&driverBuf, " retry_interval='%ld'", disk->retry_interval); ++ ++ if (disk->retry_timeout) ++ virBufferAsprintf(&driverBuf, " retry_timeout='%ld'", disk->retry_timeout); ++ + if (disk->iomode) + virBufferAsprintf(&driverBuf, " io='%s'", + virDomainDiskIoTypeToString(disk->iomode)); +-- +2.27.0 + diff --git a/cpu_map-Add-Cooperlake-x86-CPU-model.patch b/cpu_map-Add-Cooperlake-x86-CPU-model.patch new file mode 100644 index 0000000000000000000000000000000000000000..96d36bbad7454f0b8fb3a0fece69ed2e4de02bd4 --- /dev/null +++ b/cpu_map-Add-Cooperlake-x86-CPU-model.patch @@ -0,0 +1,167 @@ +From 41717af8988db9c2d9d8b753f306f6deaa1cec8d Mon Sep 17 00:00:00 2001 +From: Jiri Denemark +Date: Tue, 19 May 2020 15:08:11 +0200 +Subject: [PATCH 2/3] cpu_map: Add Cooperlake x86 CPU model + +The stepping range (10-11) is likely incomplete. QEMU uses 10 and the +CPUID data for Cooperlake show 11. We will update the range if needed +once more details about he CPU are available. + +Signed-off-by: Jiri Denemark +Reviewed-by: Pavel Hrdina +Signed-off-by: Jingyi Wang +--- + src/cpu_map/index.xml | 1 + + src/cpu_map/x86_Cooperlake.xml | 89 +++++++++++++++++++ + .../domaincapsdata/qemu_5.0.0-q35.x86_64.xml | 1 + + .../domaincapsdata/qemu_5.0.0-tcg.x86_64.xml | 1 + + tests/domaincapsdata/qemu_5.0.0.x86_64.xml | 1 + + 5 files changed, 93 insertions(+) + create mode 100644 src/cpu_map/x86_Cooperlake.xml + +diff --git a/src/cpu_map/index.xml b/src/cpu_map/index.xml +index 672d0a3c92..3ccc76b9ed 100644 +--- a/src/cpu_map/index.xml ++++ b/src/cpu_map/index.xml +@@ -54,6 +54,7 @@ + + + ++ + + + +diff --git a/src/cpu_map/x86_Cooperlake.xml b/src/cpu_map/x86_Cooperlake.xml +new file mode 100644 +index 0000000000..77e695aea4 +--- /dev/null ++++ b/src/cpu_map/x86_Cooperlake.xml +@@ -0,0 +1,89 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml +index ff721530cd..fa945fc002 100644 +--- a/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml ++++ b/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml +@@ -93,6 +93,7 @@ + EPYC-IBPB + EPYC + Dhyana ++ Cooperlake + Conroe + Cascadelake-Server-noTSX + Cascadelake-Server +diff --git a/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml +index d567863f49..a0eeed7c2d 100644 +--- a/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml +@@ -101,6 +101,7 @@ + EPYC-IBPB + EPYC + Dhyana ++ Cooperlake + Conroe + Cascadelake-Server-noTSX + Cascadelake-Server +diff --git a/tests/domaincapsdata/qemu_5.0.0.x86_64.xml b/tests/domaincapsdata/qemu_5.0.0.x86_64.xml +index 2c6066003d..fbde7a6ba2 100644 +--- a/tests/domaincapsdata/qemu_5.0.0.x86_64.xml ++++ b/tests/domaincapsdata/qemu_5.0.0.x86_64.xml +@@ -92,6 +92,7 @@ + EPYC-IBPB + EPYC + Dhyana ++ Cooperlake + Conroe + Cascadelake-Server-noTSX + Cascadelake-Server +-- +2.27.0 + diff --git a/cpu_map-Add-pschange-mc-no-bit-in-IA32_ARCH_CAPABILI.patch b/cpu_map-Add-pschange-mc-no-bit-in-IA32_ARCH_CAPABILI.patch new file mode 100644 index 0000000000000000000000000000000000000000..79420a720918c2f968903cc9af093e76cb67de66 --- /dev/null +++ b/cpu_map-Add-pschange-mc-no-bit-in-IA32_ARCH_CAPABILI.patch @@ -0,0 +1,131 @@ +From 9696e88e150fce9ea82eadb16726c8c3a7a197ae Mon Sep 17 00:00:00 2001 +From: Jiri Denemark +Date: Mon, 18 May 2020 20:55:42 +0200 +Subject: [PATCH 1/3] cpu_map: Add pschange-mc-no bit in IA32_ARCH_CAPABILITIES + MSR + +Signed-off-by: Jiri Denemark +Reviewed-by: Pavel Hrdina +Signed-off-by: Jingyi Wang +--- + src/cpu_map/x86_features.xml | 3 +++ + tests/cputestdata/x86_64-cpuid-Core-i7-8550U-enabled.xml | 2 +- + tests/cputestdata/x86_64-cpuid-Core-i7-8550U-guest.xml | 1 + + tests/cputestdata/x86_64-cpuid-Core-i7-8550U-host.xml | 1 + + tests/cputestdata/x86_64-cpuid-Core-i7-8550U-json.xml | 1 + + tests/domaincapsdata/qemu_4.2.0-q35.x86_64.xml | 1 + + tests/domaincapsdata/qemu_4.2.0.x86_64.xml | 1 + + tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml | 1 + + tests/domaincapsdata/qemu_5.0.0.x86_64.xml | 1 + + 9 files changed, 11 insertions(+), 1 deletion(-) + +diff --git a/src/cpu_map/x86_features.xml b/src/cpu_map/x86_features.xml +index 2c4c29dc99..8525ae0fa5 100644 +--- a/src/cpu_map/x86_features.xml ++++ b/src/cpu_map/x86_features.xml +@@ -509,6 +509,9 @@ + + + ++ ++ ++ + + + +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-8550U-enabled.xml b/tests/cputestdata/x86_64-cpuid-Core-i7-8550U-enabled.xml +index 6c480eeacf..57f8ebabba 100644 +--- a/tests/cputestdata/x86_64-cpuid-Core-i7-8550U-enabled.xml ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-8550U-enabled.xml +@@ -5,5 +5,5 @@ + + + +- ++ + +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-8550U-guest.xml b/tests/cputestdata/x86_64-cpuid-Core-i7-8550U-guest.xml +index 92404e4d03..ed06515e99 100644 +--- a/tests/cputestdata/x86_64-cpuid-Core-i7-8550U-guest.xml ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-8550U-guest.xml +@@ -26,6 +26,7 @@ + + + ++ + + + +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-8550U-host.xml b/tests/cputestdata/x86_64-cpuid-Core-i7-8550U-host.xml +index 7f6fe2eac3..7681c94649 100644 +--- a/tests/cputestdata/x86_64-cpuid-Core-i7-8550U-host.xml ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-8550U-host.xml +@@ -27,4 +27,5 @@ + + + ++ + +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-8550U-json.xml b/tests/cputestdata/x86_64-cpuid-Core-i7-8550U-json.xml +index 645c0934c2..4774d39c7e 100644 +--- a/tests/cputestdata/x86_64-cpuid-Core-i7-8550U-json.xml ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-8550U-json.xml +@@ -14,6 +14,7 @@ + + + ++ + + + +diff --git a/tests/domaincapsdata/qemu_4.2.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_4.2.0-q35.x86_64.xml +index 1b8b8be2f5..fcb0505da0 100644 +--- a/tests/domaincapsdata/qemu_4.2.0-q35.x86_64.xml ++++ b/tests/domaincapsdata/qemu_4.2.0-q35.x86_64.xml +@@ -47,6 +47,7 @@ + + + ++ + + + qemu64 +diff --git a/tests/domaincapsdata/qemu_4.2.0.x86_64.xml b/tests/domaincapsdata/qemu_4.2.0.x86_64.xml +index 213dcc5a08..e22ef8e032 100644 +--- a/tests/domaincapsdata/qemu_4.2.0.x86_64.xml ++++ b/tests/domaincapsdata/qemu_4.2.0.x86_64.xml +@@ -46,6 +46,7 @@ + + + ++ + + + qemu64 +diff --git a/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml +index 45c3e00b1e..ff721530cd 100644 +--- a/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml ++++ b/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml +@@ -47,6 +47,7 @@ + + + ++ + + + qemu64 +diff --git a/tests/domaincapsdata/qemu_5.0.0.x86_64.xml b/tests/domaincapsdata/qemu_5.0.0.x86_64.xml +index d2a884eed1..2c6066003d 100644 +--- a/tests/domaincapsdata/qemu_5.0.0.x86_64.xml ++++ b/tests/domaincapsdata/qemu_5.0.0.x86_64.xml +@@ -46,6 +46,7 @@ + + + ++ + + + qemu64 +-- +2.27.0 + diff --git a/cpu_map-Distribute-x86_Cooperlake.xml.patch b/cpu_map-Distribute-x86_Cooperlake.xml.patch new file mode 100644 index 0000000000000000000000000000000000000000..bcef2fb93ac2ca71d00dee664026063e027f2834 --- /dev/null +++ b/cpu_map-Distribute-x86_Cooperlake.xml.patch @@ -0,0 +1,30 @@ +From fc20e12b3be7a4c96ff0a71112d69181408506d1 Mon Sep 17 00:00:00 2001 +From: Jiri Denemark +Date: Tue, 26 May 2020 12:52:00 +0200 +Subject: [PATCH 3/3] cpu_map: Distribute x86_Cooperlake.xml +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Jiri Denemark +Reviewed-by: Daniel P. Berrangé +Signed-off-by: Jingyi Wang +--- + src/cpu_map/Makefile.inc.am | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/cpu_map/Makefile.inc.am b/src/cpu_map/Makefile.inc.am +index ab5268d94f..8eb818706a 100644 +--- a/src/cpu_map/Makefile.inc.am ++++ b/src/cpu_map/Makefile.inc.am +@@ -22,6 +22,7 @@ cpumap_DATA = \ + cpu_map/x86_Cascadelake-Server.xml \ + cpu_map/x86_Cascadelake-Server-noTSX.xml \ + cpu_map/x86_Conroe.xml \ ++ cpu_map/x86_Cooperlake.xml \ + cpu_map/x86_core2duo.xml \ + cpu_map/x86_coreduo.xml \ + cpu_map/x86_cpu64-rhel5.xml \ +-- +2.27.0 + diff --git a/libvirt-Add-retry-support-for-error-policy.patch b/libvirt-Add-retry-support-for-error-policy.patch new file mode 100644 index 0000000000000000000000000000000000000000..9a39d75b5f561cc0cd5f3071a4cf317033286428 --- /dev/null +++ b/libvirt-Add-retry-support-for-error-policy.patch @@ -0,0 +1,119 @@ +From b70fa44fc68c2c845bb6a7e82d6798268b1150ce Mon Sep 17 00:00:00 2001 +From: Jiahui Cen +Date: Thu, 25 Feb 2021 18:55:30 +0800 +Subject: [PATCH] libvirt: Add 'retry' support for error policy + +Introduce error_policy=/rerror_policy='retry' to support +werror=/rerror=retry mechanism in qemu. + +Add retry_interval parameter to control the interval between retries. +Add retry_timeout parameter to control the total retry times. + +Signed-off-by: Jiahui Cen +Signed-off-by: Ying Fang +--- + src/conf/domain_conf.c | 25 +++++++++++++++++++++++++ + src/conf/domain_conf.h | 3 +++ + src/qemu/qemu_command.c | 8 ++++++++ + src/qemu/qemu_domain.c | 2 ++ + 4 files changed, 38 insertions(+) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index cf93a591f4..1e4ed87978 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -355,6 +355,7 @@ VIR_ENUM_IMPL(virDomainDiskErrorPolicy, + "report", + "ignore", + "enospace", ++ "retry", + ); + + VIR_ENUM_IMPL(virDomainDiskIo, +@@ -10212,6 +10213,30 @@ virDomainDiskDefDriverParseXML(virDomainDiskDefPtr def, + } + VIR_FREE(tmp); + ++ def->retry_interval = -1; ++ if ((tmp = virXMLPropString(cur, "retry_interval")) && ++ ((def->error_policy != VIR_DOMAIN_DISK_ERROR_POLICY_RETRY && ++ def->rerror_policy != VIR_DOMAIN_DISK_ERROR_POLICY_RETRY) || ++ (virStrToLong_l(tmp, NULL, 10, &def->retry_interval) < 0) || ++ (def->retry_interval < 0))) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, ++ _("unknown disk retry interval '%s'"), tmp); ++ return -1; ++ } ++ VIR_FREE(tmp); ++ ++ def->retry_timeout = -1; ++ if ((tmp = virXMLPropString(cur, "retry_timeout")) && ++ ((def->error_policy != VIR_DOMAIN_DISK_ERROR_POLICY_RETRY && ++ def->rerror_policy != VIR_DOMAIN_DISK_ERROR_POLICY_RETRY) || ++ (virStrToLong_l(tmp, NULL, 10, &def->retry_timeout) < 0) || ++ (def->retry_timeout < 0))) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, ++ _("unknown disk retry interval '%s'"), tmp); ++ return -1; ++ } ++ VIR_FREE(tmp); ++ + if ((tmp = virXMLPropString(cur, "io")) && + (def->iomode = virDomainDiskIoTypeFromString(tmp)) <= 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, +diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h +index 33875d942f..97c301ebf1 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -396,6 +396,7 @@ typedef enum { + VIR_DOMAIN_DISK_ERROR_POLICY_REPORT, + VIR_DOMAIN_DISK_ERROR_POLICY_IGNORE, + VIR_DOMAIN_DISK_ERROR_POLICY_ENOSPACE, ++ VIR_DOMAIN_DISK_ERROR_POLICY_RETRY, + + VIR_DOMAIN_DISK_ERROR_POLICY_LAST + } virDomainDiskErrorPolicy; +@@ -561,6 +562,8 @@ struct _virDomainDiskDef { + int cachemode; /* enum virDomainDiskCache */ + int error_policy; /* enum virDomainDiskErrorPolicy */ + int rerror_policy; /* enum virDomainDiskErrorPolicy */ ++ long retry_interval; ++ long retry_timeout; + int iomode; /* enum virDomainDiskIo */ + int ioeventfd; /* enum virTristateSwitch */ + int event_idx; /* enum virTristateSwitch */ +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index 2f65b8ddc6..e901ea0534 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -1723,6 +1723,14 @@ qemuBuildDiskFrontendAttributeErrorPolicy(virDomainDiskDefPtr disk, + virBufferAsprintf(buf, ",werror=%s", wpolicy); + if (rpolicy) + virBufferAsprintf(buf, ",rerror=%s", rpolicy); ++ if ((disk->error_policy == VIR_DOMAIN_DISK_ERROR_POLICY_RETRY || ++ disk->rerror_policy == VIR_DOMAIN_DISK_ERROR_POLICY_RETRY) && ++ disk->retry_interval >= 0) ++ virBufferAsprintf(buf, ",retry_interval=%ld", disk->retry_interval); ++ if ((disk->error_policy == VIR_DOMAIN_DISK_ERROR_POLICY_RETRY || ++ disk->rerror_policy == VIR_DOMAIN_DISK_ERROR_POLICY_RETRY) && ++ disk->retry_timeout >= 0) ++ virBufferAsprintf(buf, ",retry_timeout=%ld", disk->retry_timeout); + } + + +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index dd48b6fff3..daab7ebec3 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -12299,6 +12299,8 @@ qemuDomainDiskChangeSupported(virDomainDiskDefPtr disk, + CHECK_EQ(cachemode, "cache", true); + CHECK_EQ(error_policy, "error_policy", true); + CHECK_EQ(rerror_policy, "rerror_policy", true); ++ CHECK_EQ(retry_interval, "retry_interval", true); ++ CHECK_EQ(retry_timeout, "retry_timeout", true); + CHECK_EQ(iomode, "io", true); + CHECK_EQ(ioeventfd, "ioeventfd", true); + CHECK_EQ(event_idx, "event_idx", true); +-- +2.27.0 + diff --git a/libvirt-conf-Set-default-values-of-retry-fileds.patch b/libvirt-conf-Set-default-values-of-retry-fileds.patch new file mode 100644 index 0000000000000000000000000000000000000000..1f1165ddb4921c404a084c6fa035283c5c213737 --- /dev/null +++ b/libvirt-conf-Set-default-values-of-retry-fileds.patch @@ -0,0 +1,87 @@ +From 285179a9e8440b32175a0793172b81cf6fcdfa4c Mon Sep 17 00:00:00 2001 +From: Jiahui Cen +Date: Thu, 18 Mar 2021 15:14:20 +0800 +Subject: [PATCH] libvirt/conf: Set default values of retry fileds + +Currently the default values of retry_interval and retry_timeout are set +to -1, when 'driver' option exists without retry fileds. It conflicts +with the default values when the 'driver' option does not exist. + +So let's set default values of retry_interval and retry_timeout to 0 when +retry policy is not enabled. + +Signed-off-by: Jiahui Cen +--- + src/conf/domain_conf.c | 18 ++++++++++++------ + src/conf/domain_conf.h | 3 +++ + 2 files changed, 15 insertions(+), 6 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 1e4ed87978..2b7eee17f0 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -10185,6 +10185,7 @@ virDomainDiskDefDriverParseXML(virDomainDiskDefPtr def, + xmlNodePtr cur) + { + g_autofree char *tmp = NULL; ++ bool retry_enabled = false; + + def->driverName = virXMLPropString(cur, "name"); + +@@ -10213,28 +10214,33 @@ virDomainDiskDefDriverParseXML(virDomainDiskDefPtr def, + } + VIR_FREE(tmp); + +- def->retry_interval = -1; ++ retry_enabled = (def->error_policy == VIR_DOMAIN_DISK_ERROR_POLICY_RETRY) || ++ (def->rerror_policy == VIR_DOMAIN_DISK_ERROR_POLICY_RETRY); ++ + if ((tmp = virXMLPropString(cur, "retry_interval")) && +- ((def->error_policy != VIR_DOMAIN_DISK_ERROR_POLICY_RETRY && +- def->rerror_policy != VIR_DOMAIN_DISK_ERROR_POLICY_RETRY) || ++ (!retry_enabled || + (virStrToLong_l(tmp, NULL, 10, &def->retry_interval) < 0) || + (def->retry_interval < 0))) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown disk retry interval '%s'"), tmp); + return -1; + } ++ if (retry_enabled && !tmp) { ++ def->retry_interval = VIR_DOMAIN_DISK_DEFAULT_RETRY_INTERVAL; ++ } + VIR_FREE(tmp); + +- def->retry_timeout = -1; + if ((tmp = virXMLPropString(cur, "retry_timeout")) && +- ((def->error_policy != VIR_DOMAIN_DISK_ERROR_POLICY_RETRY && +- def->rerror_policy != VIR_DOMAIN_DISK_ERROR_POLICY_RETRY) || ++ (!retry_enabled || + (virStrToLong_l(tmp, NULL, 10, &def->retry_timeout) < 0) || + (def->retry_timeout < 0))) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown disk retry interval '%s'"), tmp); + return -1; + } ++ if (retry_enabled && !tmp) { ++ def->retry_timeout = VIR_DOMAIN_DISK_DEFAULT_RETRY_TIMEOUT; ++ } + VIR_FREE(tmp); + + if ((tmp = virXMLPropString(cur, "io")) && +diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h +index 97c301ebf1..bebb9f46fb 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -523,6 +523,9 @@ typedef enum { + } virDomainMemoryAllocation; + + ++#define VIR_DOMAIN_DISK_DEFAULT_RETRY_INTERVAL 1000 ++#define VIR_DOMAIN_DISK_DEFAULT_RETRY_TIMEOUT 0 ++ + /* Stores the virtual disk configuration */ + struct _virDomainDiskDef { + virStorageSourcePtr src; /* non-NULL. XXX Allow NULL for empty cdrom? */ +-- +2.27.0 + diff --git a/libvirt.spec b/libvirt.spec index 7601eb9aa26cedc2dc17670e432ef38aa75b139a..3e62b29beb0c3c6ebdefaa078821ecfe9bf22685 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -48,6 +48,8 @@ %define with_storage_zfs 0 %endif +%define arg_dtrace --without-dtrace + # We need a recent enough libiscsi (>= 1.18.0) %define with_storage_iscsi_direct 0%{!?_without_storage_iscsi_direct:1} @@ -56,7 +58,7 @@ %define with_sanlock 0%{!?_without_sanlock:1} %define with_numad 0%{!?_without_numad:0} %define with_firewalld 0%{!?_without_firewalld:1} -%define with_firewalld_zone 0%{!?_without_firewalld_zone:1} +%define with_firewalld_zone 0%{!?_without_firewalld_zone:0} %define with_libssh2 0%{!?_without_libssh2:1} %define with_wireshark 0%{!?_without_wireshark:1} %define with_libssh 0%{!?_without_libssh:1} @@ -99,7 +101,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 6.2.0 -Release: 7 +Release: 18 License: LGPLv2+ URL: https://libvirt.org/ @@ -131,6 +133,26 @@ Patch0020: libvirt-cpu_map-add-kunpeng-920-features-as-known-features.patch 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: rpc-gendispatch-handle-empty-flags.patch +Patch0025: rpc-add-support-for-filtering-acls-by-uint-params.patch +Patch0026: rpc-require-write-acl-for-guest-agent-in-virDomainIn.patch +Patch0027: qemu-agent-set-ifname-to-NULL-after-freeing.patch +Patch0028: util-Move-virIsDevMapperDevice-to-virdevmapper.c.patch +Patch0029: virdevmapper-Don-t-use-libdevmapper-to-obtain-depend.patch +Patch0030: libvirt-Add-retry-support-for-error-policy.patch +Patch0031: qemu-Support-retry-BLOCK_IO_ERROR-event.patch +Patch0032: libvirt-conf-Set-default-values-of-retry-fileds.patch +Patch0033: cpu_map-Add-Cooperlake-x86-CPU-model.patch +Patch0034: cpu_map-Add-pschange-mc-no-bit-in-IA32_ARCH_CAPABILI.patch +Patch0035: cpu_map-Distribute-x86_Cooperlake.xml.patch +Patch0036: conf-domain_conf-pin-the-retry_interval-and-retry_ti.patch +Patch0037: storage_driver-Unlock-object-on-ACL-fail-in-storageP.patch +Patch0038: security-fix-SELinux-label-generation-logic.patch +Patch0039: add-phytium-2000plus-and-s2500-support-on-arm-archit.patch +Patch0040: virDevMapperGetTargets-Don-t-ignore-EBADF.patch +Patch0041: virdevmapper-Don-t-cache-device-mapper-major.patch +Patch0042: virdevmapper-Handle-kernel-without-device-mapper-sup.patch +Patch0043: virsh-Display-vhostuser-socket-path-in-domblklist.patch Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} @@ -1082,7 +1104,7 @@ cd %{_vpath_builddir} --with-libpcap \ --with-macvtap \ --with-audit \ - --with-dtrace \ + %{?arg_dtrace} \ --with-driver-modules \ %{?arg_firewalld} \ %{?arg_firewalld_zone} \ @@ -1177,7 +1199,7 @@ rm -f $RPM_BUILD_ROOT%{_datadir}/augeas/lenses/tests/test_libvirtd_libxl.aug # Copied into libvirt-docs subpackage eventually mv $RPM_BUILD_ROOT%{_datadir}/doc/libvirt libvirt-docs -%ifarch %{power64} s390x x86_64 ia64 alpha sparc64 +%ifarch %{power64} s390x ia64 alpha sparc64 mv $RPM_BUILD_ROOT%{_datadir}/systemtap/tapset/libvirt_probes.stp \ $RPM_BUILD_ROOT%{_datadir}/systemtap/tapset/libvirt_probes-64.stp @@ -1743,10 +1765,12 @@ exit 0 %{_bindir}/virt-pki-validate %{_bindir}/virt-host-validate -%{_datadir}/systemtap/tapset/libvirt_probes*.stp -%{_datadir}/systemtap/tapset/libvirt_functions.stp -%if %{with_qemu} -%{_datadir}/systemtap/tapset/libvirt_qemu_probes*.stp +%ifnarch aarch64 x86_64 + %{_datadir}/systemtap/tapset/libvirt_probes*.stp + %{_datadir}/systemtap/tapset/libvirt_functions.stp + %if %{with_qemu} + %{_datadir}/systemtap/tapset/libvirt_qemu_probes*.stp + %endif %endif %if %{with_bash_completion} @@ -1863,6 +1887,48 @@ exit 0 %changelog +* Wed Jun 15 2022 yezengruan +- libvir.spec: build without dtrace + +* Tue Mar 08 2022 imxcc +- virsh: Display vhostuser socket path in domblklist + +* Wed Dec 08 2021 Euler Robot +- virDevMapperGetTargets: Don't ignore EBADF +- virdevmapper: Don't cache device-mapper major +- virdevmapper: Handle kernel without device-mapper support + +* Wed Dec 08 2021 Euler Robot +- add phytium 2000plus and s2500 support on arm architecture for capability + +* Sun Sep 26 2021 Euler Robot +- storage_driver: Unlock object on ACL fail in storagePoolLookupByTargetPath +- security: fix SELinux label generation logic + +* Fri Sep 24 2021 Euler Robot +- conf/domain_conf: pin the retry_interval and retry_timeout parameters to xml + +* Tue Jul 27 2021 Jingyi Wang +- add new CPU model Cooperlake + +* Fri Apr 23 2021 Chen Qun +- libvirt: Add 'retry' support for error policy +- qemu: Support 'retry' BLOCK_IO_ERROR event. +- libvirt/conf: Set default values of retry fileds + +* Wed Jan 20 2021 Huawei Technologies Co., Ltd +- util: Move virIsDevMapperDevice() to virdevmapper.c +- virdevmapper: Don't use libdevmapper to obtain dependencies + +* Tue Dec 8 2020 Huawei Technologies Co., Ltd +- add --without-firewalld-zone to configure commandline for old firewalld version + +* Wed Oct 14 2020 Huawei Technologies Co., Ltd +- rpc: gendispatch: handle empty flags +- rpc: add support for filtering @acls by uint params +- rpc: require write acl for guest agent in virDomainInterfaceAddresses +- qemu: agent: set ifname to NULL after freeing + * Tue Aug 4 2020 Xu Yandong - 6.2.0-7 - Substitute security_context_t with char pointer. * Tue May 26 2020 Xu Yandong - 6.2.0-6 diff --git a/qemu-Support-retry-BLOCK_IO_ERROR-event.patch b/qemu-Support-retry-BLOCK_IO_ERROR-event.patch new file mode 100644 index 0000000000000000000000000000000000000000..7bf11f9e9471d2cb1dd7e92b31701f48a2e26c96 --- /dev/null +++ b/qemu-Support-retry-BLOCK_IO_ERROR-event.patch @@ -0,0 +1,57 @@ +From 0b8b52e43ba34993c4b2781db477c4131f3abd30 Mon Sep 17 00:00:00 2001 +From: Jiahui Cen +Date: Thu, 25 Feb 2021 18:55:31 +0800 +Subject: [PATCH] qemu: Support 'retry' BLOCK_IO_ERROR event. + +Accept BLOCK_IO_ERROR event with action='retry' from qemu. + +Signed-off-by: Jiahui Cen +Signed-off-by: Ying Fang +--- + include/libvirt/libvirt-domain.h | 1 + + src/qemu/qemu_monitor_json.c | 2 +- + tools/virsh-domain.c | 3 ++- + 3 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h +index b440818ec2..90cb652db1 100644 +--- a/include/libvirt/libvirt-domain.h ++++ b/include/libvirt/libvirt-domain.h +@@ -3701,6 +3701,7 @@ typedef enum { + VIR_DOMAIN_EVENT_IO_ERROR_NONE = 0, /* No action, IO error ignored */ + VIR_DOMAIN_EVENT_IO_ERROR_PAUSE, /* Guest CPUs are paused */ + VIR_DOMAIN_EVENT_IO_ERROR_REPORT, /* IO error reported to guest OS */ ++ VIR_DOMAIN_EVENT_IO_ERROR_RETRY, /* Failed IO retried */ + + # ifdef VIR_ENUM_SENTINELS + VIR_DOMAIN_EVENT_IO_ERROR_LAST +diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c +index 619717eae5..ef25764a98 100644 +--- a/src/qemu/qemu_monitor_json.c ++++ b/src/qemu/qemu_monitor_json.c +@@ -898,7 +898,7 @@ static void qemuMonitorJSONHandleWatchdog(qemuMonitorPtr mon, virJSONValuePtr da + VIR_ENUM_DECL(qemuMonitorIOErrorAction); + VIR_ENUM_IMPL(qemuMonitorIOErrorAction, + VIR_DOMAIN_EVENT_IO_ERROR_LAST, +- "ignore", "stop", "report", ++ "ignore", "stop", "report", "retry", + ); + + +diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c +index 0a623086a4..65d5c831ec 100644 +--- a/tools/virsh-domain.c ++++ b/tools/virsh-domain.c +@@ -13065,7 +13065,8 @@ VIR_ENUM_IMPL(virshDomainEventIOError, + VIR_DOMAIN_EVENT_IO_ERROR_LAST, + N_("none"), + N_("pause"), +- N_("report")); ++ N_("report"), ++ N_("retry")); + + static const char * + virshDomainEventIOErrorToString(int action) +-- +2.27.0 + diff --git a/qemu-agent-set-ifname-to-NULL-after-freeing.patch b/qemu-agent-set-ifname-to-NULL-after-freeing.patch new file mode 100644 index 0000000000000000000000000000000000000000..f7501467e0c7b7c5c7710bae58a30df450eade6f --- /dev/null +++ b/qemu-agent-set-ifname-to-NULL-after-freeing.patch @@ -0,0 +1,33 @@ +From ebd3e9057bfed59761e0554108d541f94eddb835 Mon Sep 17 00:00:00 2001 +From: Jan Tomko +Date: Wed, 14 Oct 2020 17:23:54 +0800 +Subject: [PATCH] qemu: agent: set ifname to NULL after freeing + +CVE-2020-25637 + +Signed-off-by: Jan Tomko +Rported-by: Ilja Van Sprundel +Reviewed-by: Mauro Matteo Cascella +Reviewed-by: Jiri Denemark + +cherry-pick from commit a63b48c5ecef077bf0f909a85f453a605600cf05 +Signed-off-by: Jiajie Li +--- + src/qemu/qemu_agent.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c +index d7fcc869c6..31d3268d42 100644 +--- a/src/qemu/qemu_agent.c ++++ b/src/qemu/qemu_agent.c +@@ -2166,6 +2166,7 @@ qemuAgentGetInterfaces(qemuAgentPtr agent, + + /* Has to be freed for each interface. */ + virStringListFree(ifname); ++ ifname = NULL; + + /* as well as IP address which - moreover - + * can be presented multiple times */ +-- +2.23.0 + diff --git a/rpc-add-support-for-filtering-acls-by-uint-params.patch b/rpc-add-support-for-filtering-acls-by-uint-params.patch new file mode 100644 index 0000000000000000000000000000000000000000..69e50f320f1ccc45bafe6162d6306b7964bbfaec --- /dev/null +++ b/rpc-add-support-for-filtering-acls-by-uint-params.patch @@ -0,0 +1,100 @@ +From cc4f12dacfd39a903a6caa5a38e317023e5aed30 Mon Sep 17 00:00:00 2001 +From: Jan Tomko +Date: Wed, 14 Oct 2020 17:06:09 +0800 +Subject: [PATCH] rpc: add support for filtering @acls by uint params + +CVE-2020-25637 + +Add a new field to @acl annotations for filtering by +unsigned int parameters. + +Signed-off-by: Jan Tomko +Reviewed-by: Jiri Denemark + +cherry-pick from commit 50864dcda191eb35732dbd80fb6ca251a6bba923 +Signed-off-by: Jiajie Li +--- + src/remote/remote_protocol.x | 3 +++ + src/rpc/gendispatch.pl | 21 ++++++++++++++++++++- + 2 files changed, 23 insertions(+), 1 deletion(-) + +diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x +index d4393680e9..5f3858c00c 100644 +--- a/src/remote/remote_protocol.x ++++ b/src/remote/remote_protocol.x +@@ -3805,6 +3805,7 @@ enum remote_procedure { + * + * - @acl: : + * - @acl: :: ++ * - @acl: :::: + * + * Declare the access control requirements for the API. May be repeated + * multiple times, if multiple rules are required. +@@ -3814,6 +3815,8 @@ enum remote_procedure { + * is one of the permissions in access/viraccessperm.h + * indicates the rule only applies if the named flag + * is set in the API call ++ * and can be used to check an unsigned in parameter ++ * against value + * + * - @aclfilter: : + * +diff --git a/src/rpc/gendispatch.pl b/src/rpc/gendispatch.pl +index 6feb1c8320..590a46ef66 100755 +--- a/src/rpc/gendispatch.pl ++++ b/src/rpc/gendispatch.pl +@@ -2111,10 +2111,12 @@ elsif ($mode eq "client") { + my @acl; + foreach (@{$acl}) { + my @bits = split /:/; +- push @acl, { object => $bits[0], perm => $bits[1], flags => $bits[2] } ++ push @acl, { object => $bits[0], perm => $bits[1], flags => $bits[2], ++ param => $bits[3], value => $bits[4] } + } + + my $checkflags = 0; ++ my $paramtocheck = undef; + for (my $i = 1 ; $i <= $#acl ; $i++) { + if ($acl[$i]->{object} ne $acl[0]->{object}) { + die "acl for '$call->{ProcName}' cannot check different objects"; +@@ -2122,6 +2124,9 @@ elsif ($mode eq "client") { + if (defined $acl[$i]->{flags} && length $acl[$i]->{flags}) { + $checkflags = 1; + } ++ if (defined $acl[$i]->{param}) { ++ $paramtocheck = $acl[$i]->{param}; ++ } + } + + my $apiname = $prefix . $call->{ProcName}; +@@ -2157,6 +2162,9 @@ elsif ($mode eq "client") { + if ($checkflags) { + push @argdecls, "unsigned int flags"; + } ++ if (defined $paramtocheck) { ++ push @argdecls, "unsigned int " . $paramtocheck; ++ } + + my $ret; + my $pass; +@@ -2217,6 +2225,17 @@ elsif ($mode eq "client") { + } + print " "; + } ++ if (defined $acl->{param}) { ++ my $param = $acl->{param}; ++ my $value = $acl->{value}; ++ if ($value =~ /^\!/) { ++ $value = substr $value, 1; ++ print "($param != ($value)) &&\n"; ++ } else { ++ print "($param == ($value)) &&\n"; ++ } ++ print " "; ++ } + print "(rv = $method(" . join(", ", @argvars, $perm) . ")) <= 0) {\n"; + print " virObjectUnref(mgr);\n"; + if ($action eq "Ensure") { +-- +2.23.0 + diff --git a/rpc-gendispatch-handle-empty-flags.patch b/rpc-gendispatch-handle-empty-flags.patch new file mode 100644 index 0000000000000000000000000000000000000000..dc649b108636bd98be1e7a8df1358eacdc06de92 --- /dev/null +++ b/rpc-gendispatch-handle-empty-flags.patch @@ -0,0 +1,47 @@ +From 9ba16c0b1608545161df2f999c73bc374b83df61 Mon Sep 17 00:00:00 2001 +From: Jan Tomko +Date: Wed, 14 Oct 2020 16:38:07 +0800 +Subject: [PATCH] rpc: gendispatch: handle empty flags + +CVE-2020-25637 + +Prepare for omission of the in remote_protocol.x +@acl annotations: + @acl: :: +so that we can add more field after, e.g.: + @acl: ::: + +Signed-off-by: Jan Tomko +Reviewed-by: Jiri Denemark + +cherry-pick from commit 955029bd0ad7ef96000f529ac38204a8f4a96401 +Signed-off-by: Jiajie Li +--- + src/rpc/gendispatch.pl | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/rpc/gendispatch.pl b/src/rpc/gendispatch.pl +index 0b2ae59910..6feb1c8320 100755 +--- a/src/rpc/gendispatch.pl ++++ b/src/rpc/gendispatch.pl +@@ -2119,7 +2119,7 @@ elsif ($mode eq "client") { + if ($acl[$i]->{object} ne $acl[0]->{object}) { + die "acl for '$call->{ProcName}' cannot check different objects"; + } +- if (defined $acl[$i]->{flags}) { ++ if (defined $acl[$i]->{flags} && length $acl[$i]->{flags}) { + $checkflags = 1; + } + } +@@ -2207,7 +2207,7 @@ elsif ($mode eq "client") { + my $method = "virAccessManagerCheck" . $object; + my $space = ' ' x length($method); + print " if ("; +- if (defined $acl->{flags}) { ++ if (defined $acl->{flags} && length $acl->{flags}) { + my $flags = $acl->{flags}; + if ($flags =~ /^\!/) { + $flags = substr $flags, 1; +-- +2.23.0 + diff --git a/rpc-require-write-acl-for-guest-agent-in-virDomainIn.patch b/rpc-require-write-acl-for-guest-agent-in-virDomainIn.patch new file mode 100644 index 0000000000000000000000000000000000000000..b986007a4c4e8eb7616cb9a9b56a81709206cbf4 --- /dev/null +++ b/rpc-require-write-acl-for-guest-agent-in-virDomainIn.patch @@ -0,0 +1,78 @@ +From 2061c613c60e6248fc7cc95107bc502ce0f4bd2d Mon Sep 17 00:00:00 2001 +From: Jan Tomko +Date: Wed, 14 Oct 2020 17:18:29 +0800 +Subject: [PATCH] rpc: require write acl for guest agent in + virDomainInterfaceAddresses + +CVE-2020-25637 + +Add a requirement for domain:write if source is set to +VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT. + +Signed-off-by: Jan Tomko +Reported-by: Ilja Van Sprundel +Reviewed-by: Jiri Denemark + +cherry-pick from commit e4116eaa44cb366b59f7fe98f4b88d04c04970ad +Signed-off-by: Jiajie Li +--- + src/libxl/libxl_driver.c | 2 +- + src/lxc/lxc_driver.c | 2 +- + src/qemu/qemu_driver.c | 2 +- + src/remote/remote_protocol.x | 1 + + 4 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c +index 7ec4fcc3d1..16bc91d503 100644 +--- a/src/libxl/libxl_driver.c ++++ b/src/libxl/libxl_driver.c +@@ -6381,7 +6381,7 @@ libxlDomainInterfaceAddresses(virDomainPtr dom, + if (!(vm = libxlDomObjFromDomain(dom))) + goto cleanup; + +- if (virDomainInterfaceAddressesEnsureACL(dom->conn, vm->def) < 0) ++ if (virDomainInterfaceAddressesEnsureACL(dom->conn, vm->def, source) < 0) + goto cleanup; + + if (virDomainObjCheckActive(vm) < 0) +diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c +index 851894c459..71c7068bbf 100644 +--- a/src/lxc/lxc_driver.c ++++ b/src/lxc/lxc_driver.c +@@ -1698,7 +1698,7 @@ lxcDomainInterfaceAddresses(virDomainPtr dom, + if (!(vm = lxcDomObjFromDomain(dom))) + goto cleanup; + +- if (virDomainInterfaceAddressesEnsureACL(dom->conn, vm->def) < 0) ++ if (virDomainInterfaceAddressesEnsureACL(dom->conn, vm->def, source) < 0) + goto cleanup; + + if (virDomainObjCheckActive(vm) < 0) +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index 8bc5368b2f..c0e88bca46 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -22042,7 +22042,7 @@ qemuDomainInterfaceAddresses(virDomainPtr dom, + if (!(vm = qemuDomainObjFromDomain(dom))) + goto cleanup; + +- if (virDomainInterfaceAddressesEnsureACL(dom->conn, vm->def) < 0) ++ if (virDomainInterfaceAddressesEnsureACL(dom->conn, vm->def, source) < 0) + goto cleanup; + + if (virDomainObjCheckActive(vm) < 0) +diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x +index 5f3858c00c..8b05082b61 100644 +--- a/src/remote/remote_protocol.x ++++ b/src/remote/remote_protocol.x +@@ -6211,6 +6211,7 @@ enum remote_procedure { + /** + * @generate: none + * @acl: domain:read ++ * @acl: domain:write::source:VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT + */ + REMOTE_PROC_DOMAIN_INTERFACE_ADDRESSES = 353, + +-- +2.23.0 + diff --git a/security-fix-SELinux-label-generation-logic.patch b/security-fix-SELinux-label-generation-logic.patch new file mode 100644 index 0000000000000000000000000000000000000000..f8b09dc166592e11696f9faff272c7e75a924a74 --- /dev/null +++ b/security-fix-SELinux-label-generation-logic.patch @@ -0,0 +1,54 @@ +From 7dd260dc2d8b8269488785d216972579aa234b3e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Mon, 28 Jun 2021 13:09:04 +0100 +Subject: [PATCH] security: fix SELinux label generation logic +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +A process can access a file if the set of MCS categories +for the file is equal-to *or* a subset-of, the set of +MCS categories for the process. + +If there are two VMs: + + a) svirt_t:s0:c117 + b) svirt_t:s0:c117,c720 + +Then VM (b) is able to access files labelled for VM (a). + +IOW, we must discard case where the categories are equal +because that is a subset of many other valid category pairs. + +Fixes: https://gitlab.com/libvirt/libvirt/-/issues/153 +CVE-2021-3631 +Reviewed-by: Peter Krempa +Signed-off-by: Daniel P. Berrangé +--- + src/security/security_selinux.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c +index 72d1658e05..f1281b9cc0 100644 +--- a/src/security/security_selinux.c ++++ b/src/security/security_selinux.c +@@ -391,7 +391,15 @@ virSecuritySELinuxMCSFind(virSecurityManagerPtr mgr, + VIR_DEBUG("Try cat %s:c%d,c%d", sens, c1 + catMin, c2 + catMin); + + if (c1 == c2) { +- mcs = g_strdup_printf("%s:c%d", sens, catMin + c1); ++ /* ++ * A process can access a file if the set of MCS categories ++ * for the file is equal-to *or* a subset-of, the set of ++ * MCS categories for the process. ++ * ++ * IOW, we must discard case where the categories are equal ++ * because that is a subset of other category pairs. ++ */ ++ continue; + } else { + if (c1 > c2) { + int t = c1; +-- +2.27.0 + diff --git a/storage_driver-Unlock-object-on-ACL-fail-in-storageP.patch b/storage_driver-Unlock-object-on-ACL-fail-in-storageP.patch new file mode 100644 index 0000000000000000000000000000000000000000..5c0fa3642a39519b1963caf9743f13cb10a034a5 --- /dev/null +++ b/storage_driver-Unlock-object-on-ACL-fail-in-storageP.patch @@ -0,0 +1,36 @@ +From 87771fdd5930502a3970e6363785d42ed030b901 Mon Sep 17 00:00:00 2001 +From: Peter Krempa +Date: Wed, 21 Jul 2021 11:22:25 +0200 +Subject: [PATCH] storage_driver: Unlock object on ACL fail in + storagePoolLookupByTargetPath + +'virStoragePoolObjListSearch' returns a locked and refed object, thus we +must release it on ACL permission failure. + +Fixes: 7aa0e8c0cb8 +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1984318 +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +--- + src/storage/storage_driver.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c +index 2db763caa5..d52d537152 100644 +--- a/src/storage/storage_driver.c ++++ b/src/storage/storage_driver.c +@@ -1740,8 +1740,10 @@ storagePoolLookupByTargetPath(virConnectPtr conn, + storagePoolLookupByTargetPathCallback, + cleanpath))) { + def = virStoragePoolObjGetDef(obj); +- if (virStoragePoolLookupByTargetPathEnsureACL(conn, def) < 0) ++ if (virStoragePoolLookupByTargetPathEnsureACL(conn, def) < 0) { ++ virStoragePoolObjEndAPI(&obj); + return NULL; ++ } + + pool = virGetStoragePool(conn, def->name, def->uuid, NULL, NULL); + virStoragePoolObjEndAPI(&obj); +-- +2.27.0 + diff --git a/util-Move-virIsDevMapperDevice-to-virdevmapper.c.patch b/util-Move-virIsDevMapperDevice-to-virdevmapper.c.patch new file mode 100644 index 0000000000000000000000000000000000000000..d6afe99c534f7708f24954241ad9896673d4df1f --- /dev/null +++ b/util-Move-virIsDevMapperDevice-to-virdevmapper.c.patch @@ -0,0 +1,176 @@ +From c140f7450d1a4a570b110f36a610134ce2d0d1a6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20Pr=C3=ADvozn=C3=ADk?= +Date: Thu, 14 Jan 2021 09:26:01 +0800 +Subject: [PATCH] util: Move virIsDevMapperDevice() to virdevmapper.c + +CVE-2020-14339 + +When introducing virdevmapper.c (in v4.3.0-rc1~427) I didn't +realize there is a function that calls in devmapper. The function +is called virIsDevMapperDevice() and lives in virutil.c. Now that +we have a special file for handling devmapper move it there. + +Signed-off-by: Michal Privoznik +Reviewed-by: Jiri Denemark + +cherry-pick from commit dfa0e118f745fe3f4fe95975c6100f0fc6d788be +Signed-off-by: Jiajie Li +--- + src/libvirt_private.syms | 2 +- + src/storage/parthelper.c | 2 +- + src/storage/storage_backend_disk.c | 1 + + src/util/virdevmapper.c | 24 ++++++++++++++++++++++++ + src/util/virdevmapper.h | 3 +++ + src/util/virutil.c | 24 ------------------------ + src/util/virutil.h | 2 -- + 7 files changed, 30 insertions(+), 28 deletions(-) + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index e276f55bb1..bac96e140e 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -1931,6 +1931,7 @@ virDBusSetSharedBus; + + # util/virdevmapper.h + virDevMapperGetTargets; ++virIsDevMapperDevice; + + + # util/virdnsmasq.h +@@ -3415,7 +3416,6 @@ virGetUserShell; + virHostGetDRMRenderNode; + virHostHasIOMMU; + virIndexToDiskName; +-virIsDevMapperDevice; + virMemoryLimitIsSet; + virMemoryLimitTruncate; + virMemoryMaxValue; +diff --git a/src/storage/parthelper.c b/src/storage/parthelper.c +index 761a7f93fc..812e90d3cb 100644 +--- a/src/storage/parthelper.c ++++ b/src/storage/parthelper.c +@@ -36,10 +36,10 @@ + #include + #include + +-#include "virutil.h" + #include "virfile.h" + #include "virstring.h" + #include "virgettext.h" ++#include "virdevmapper.h" + + /* we don't need to include the full internal.h just for this */ + #define STREQ(a, b) (strcmp(a, b) == 0) +diff --git a/src/storage/storage_backend_disk.c b/src/storage/storage_backend_disk.c +index 35b07abbfe..eae23ec24a 100644 +--- a/src/storage/storage_backend_disk.c ++++ b/src/storage/storage_backend_disk.c +@@ -32,6 +32,7 @@ + #include "virutil.h" + #include "configmake.h" + #include "virstring.h" ++#include "virdevmapper.h" + + #define VIR_FROM_THIS VIR_FROM_STORAGE + +diff --git a/src/util/virdevmapper.c b/src/util/virdevmapper.c +index feb5982315..ecc5e433c7 100644 +--- a/src/util/virdevmapper.c ++++ b/src/util/virdevmapper.c +@@ -202,3 +202,27 @@ virDevMapperGetTargets(const char *path G_GNUC_UNUSED, + return -1; + } + #endif /* ! WITH_DEVMAPPER */ ++ ++ ++#if WITH_DEVMAPPER ++bool ++virIsDevMapperDevice(const char *dev_name) ++{ ++ struct stat buf; ++ ++ if (!stat(dev_name, &buf) && ++ S_ISBLK(buf.st_mode) && ++ dm_is_dm_major(major(buf.st_rdev))) ++ return true; ++ ++ return false; ++} ++ ++#else /* ! WITH_DEVMAPPER */ ++ ++bool ++virIsDevMapperDevice(const char *dev_name G_GNUC_UNUSED) ++{ ++ return false; ++} ++#endif /* ! WITH_DEVMAPPER */ +diff --git a/src/util/virdevmapper.h b/src/util/virdevmapper.h +index 87bbc63cfd..834900692e 100644 +--- a/src/util/virdevmapper.h ++++ b/src/util/virdevmapper.h +@@ -25,3 +25,6 @@ + int + virDevMapperGetTargets(const char *path, + char ***devPaths) G_GNUC_NO_INLINE; ++ ++bool ++virIsDevMapperDevice(const char *dev_name) ATTRIBUTE_NONNULL(1); +diff --git a/src/util/virutil.c b/src/util/virutil.c +index 5b52e4e6d4..bea9749cae 100644 +--- a/src/util/virutil.c ++++ b/src/util/virutil.c +@@ -37,10 +37,6 @@ + + #include + +-#if WITH_DEVMAPPER +-# include +-#endif +- + #ifdef HAVE_GETPWUID_R + # include + # include +@@ -1340,26 +1336,6 @@ void virWaitForDevices(void) + ignore_value(virCommandRun(cmd, &exitstatus)); + } + +-#if WITH_DEVMAPPER +-bool +-virIsDevMapperDevice(const char *dev_name) +-{ +- struct stat buf; +- +- if (!stat(dev_name, &buf) && +- S_ISBLK(buf.st_mode) && +- dm_is_dm_major(major(buf.st_rdev))) +- return true; +- +- return false; +-} +-#else +-bool virIsDevMapperDevice(const char *dev_name G_GNUC_UNUSED) +-{ +- return false; +-} +-#endif +- + bool + virValidateWWN(const char *wwn) + { +diff --git a/src/util/virutil.h b/src/util/virutil.h +index ee23f0c1f4..e4328564e4 100644 +--- a/src/util/virutil.h ++++ b/src/util/virutil.h +@@ -114,8 +114,6 @@ bool virDoesUserExist(const char *name); + bool virDoesGroupExist(const char *name); + + +-bool virIsDevMapperDevice(const char *dev_name) ATTRIBUTE_NONNULL(1); +- + bool virValidateWWN(const char *wwn); + + int virGetDeviceID(const char *path, +-- +2.27.0 + diff --git a/virDevMapperGetTargets-Don-t-ignore-EBADF.patch b/virDevMapperGetTargets-Don-t-ignore-EBADF.patch new file mode 100644 index 0000000000000000000000000000000000000000..30cc2214d9e81970f9da99b4def4f43bc7d3705f --- /dev/null +++ b/virDevMapperGetTargets-Don-t-ignore-EBADF.patch @@ -0,0 +1,53 @@ +From 63a6d2b325f4cad831a3bd349bb33359273093f7 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Thu, 23 Jul 2020 17:08:46 +0200 +Subject: [PATCH] virDevMapperGetTargets: Don't ignore EBADF +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Michal Privoznik +Reviewed-by: Daniel P. Berrangé +--- + src/qemu/qemu_cgroup.c | 2 +- + src/qemu/qemu_domain.c | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c +index 057f87124c..aa721df100 100644 +--- a/src/qemu/qemu_cgroup.c ++++ b/src/qemu/qemu_cgroup.c +@@ -91,7 +91,7 @@ qemuSetupImagePathCgroup(virDomainObjPtr vm, + } + + if (virDevMapperGetTargets(path, &targetPaths) < 0 && +- errno != ENOSYS && errno != EBADF) { ++ errno != ENOSYS) { + virReportSystemError(errno, + _("Unable to get devmapper targets for %s"), + path); +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index daab7ebec3..adae36db0e 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -14923,7 +14923,7 @@ qemuDomainSetupDisk(virQEMUDriverConfigPtr cfg G_GNUC_UNUSED, + return -1; + + if (virDevMapperGetTargets(next->path, &targetPaths) < 0 && +- errno != ENOSYS && errno != EBADF) { ++ errno != ENOSYS) { + virReportSystemError(errno, + _("Unable to get devmapper targets for %s"), + next->path); +@@ -15976,7 +15976,7 @@ qemuDomainNamespaceSetupDisk(virDomainObjPtr vm, + tmpPath = g_strdup(next->path); + + if (virDevMapperGetTargets(next->path, &targetPaths) < 0 && +- errno != ENOSYS && errno != EBADF) { ++ errno != ENOSYS) { + virReportSystemError(errno, + _("Unable to get devmapper targets for %s"), + next->path); +-- +2.27.0 + diff --git a/virdevmapper-Don-t-cache-device-mapper-major.patch b/virdevmapper-Don-t-cache-device-mapper-major.patch new file mode 100644 index 0000000000000000000000000000000000000000..b080043bb44ced1096a40336d38494486b0500b9 --- /dev/null +++ b/virdevmapper-Don-t-cache-device-mapper-major.patch @@ -0,0 +1,91 @@ +From fb5ac9b0db25984b0d54149dc15b87f513523430 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Tue, 18 Aug 2020 11:08:15 +0200 +Subject: [PATCH] virdevmapper: Don't cache device-mapper major + +The device mapper major is needed in virIsDevMapperDevice() which +determines whether given device is managed by device-mapper. This +number is obtained by parsing /proc/devices and then stored in a +global variable so that the file doesn't have to be parsed again. +However, as it turns out this logic is flawed - the major number +is not static and can change as it can be specified as a +parameter when loading the dm-mod module. + +Unfortunately, I was not able to come up with a good solution and +thus the /proc/devices file is being parsed every time we need +the device mapper major. + +Signed-off-by: Michal Privoznik +Reviewed-by: Peter Krempa +Reviewed-by: Christian Ehrhardt +Tested-by: Christian Ehrhardt +--- + src/util/virdevmapper.c | 17 +++++------------ + 1 file changed, 5 insertions(+), 12 deletions(-) + +diff --git a/src/util/virdevmapper.c b/src/util/virdevmapper.c +index a471504176..b43dbefa9a 100644 +--- a/src/util/virdevmapper.c ++++ b/src/util/virdevmapper.c +@@ -46,11 +46,9 @@ + + G_STATIC_ASSERT(BUF_SIZE > sizeof(struct dm_ioctl)); + +-static unsigned int virDMMajor; +- + + static int +-virDevMapperOnceInit(void) ++virDevMapperGetMajor(unsigned int *major) + { + g_autofree char *buf = NULL; + VIR_AUTOSTRINGLIST lines = NULL; +@@ -69,7 +67,7 @@ virDevMapperOnceInit(void) + + if (sscanf(lines[i], "%u %ms\n", &maj, &dev) == 2 && + STREQ(dev, DM_NAME)) { +- virDMMajor = maj; ++ *major = maj; + break; + } + } +@@ -85,9 +83,6 @@ virDevMapperOnceInit(void) + } + + +-VIR_ONCE_GLOBAL_INIT(virDevMapper); +- +- + static void * + virDMIoctl(int controlFD, int cmd, struct dm_ioctl *dm, char **buf) + { +@@ -305,9 +300,6 @@ virDevMapperGetTargets(const char *path, + * consist of devices or yet another targets. If that's the + * case, we have to stop recursion somewhere. */ + +- if (virDevMapperInitialize() < 0) +- return -1; +- + if ((controlFD = virDMOpen()) < 0) + return -1; + +@@ -319,13 +311,14 @@ bool + virIsDevMapperDevice(const char *dev_name) + { + struct stat buf; ++ unsigned int major; + +- if (virDevMapperInitialize() < 0) ++ if (virDevMapperGetMajor(&major) < 0) + return false; + + if (!stat(dev_name, &buf) && + S_ISBLK(buf.st_mode) && +- major(buf.st_rdev) == virDMMajor) ++ major(buf.st_rdev) == major) + return true; + + return false; +-- +2.27.0 + diff --git a/virdevmapper-Don-t-use-libdevmapper-to-obtain-depend.patch b/virdevmapper-Don-t-use-libdevmapper-to-obtain-depend.patch new file mode 100644 index 0000000000000000000000000000000000000000..420280414d53b83e2b521c429fa4eafbd9dc4538 --- /dev/null +++ b/virdevmapper-Don-t-use-libdevmapper-to-obtain-depend.patch @@ -0,0 +1,488 @@ +From 8cd9aa6a5e3ea2b6a39d9befff08c1d4e79ee4a3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20Pr=C3=ADvozn=C3=ADk?= +Date: Thu, 14 Jan 2021 09:38:20 +0800 +Subject: [PATCH] virdevmapper: Don't use libdevmapper to obtain dependencies +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +CVE-2020-14339 + +When building domain's private /dev in a namespace, libdevmapper +is consulted for getting full dependency tree of domain's disks. +The reason is that for a multipath devices all dependent devices +must be created in the namespace and allowed in CGroups. + +However, this approach is very fragile as building of namespace +happens in the forked off child process, after mass close of FDs +and just before dropping privileges and execing QEMU. And it so +happens that when calling libdevmapper APIs, one of them opens +/dev/mapper/control and saves the FD into a global variable. The +FD is kept open until the lib is unlinked or dm_lib_release() is +called explicitly. We are doing neither. + +However, the virDevMapperGetTargets() function is called also +from libvirtd (when setting up CGroups) and thus has to be thread +safe. Unfortunately, libdevmapper APIs are not thread safe (nor +async signal safe) and thus we can't use them. Reimplement what +libdevmapper would do using plain C (ioctl()-s, /proc/devices +parsing, /dev/mapper dirwalking, and so on). + +Fixes: a30078cb832646177defd256e77c632905f1e6d0 +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1858260 + +Signed-off-by: Michal Privoznik +Reviewed-by: Daniel P. Berrangé + +cherry-pick from commit 22494556542c676d1b9e7f1c1f2ea13ac17e1e3e +Signed-off-by: Jiajie Li +--- + po/POTFILES.in | 1 + + src/util/virdevmapper.c | 334 +++++++++++++++++++++++++++------------- + 2 files changed, 229 insertions(+), 106 deletions(-) + +diff --git a/po/POTFILES.in b/po/POTFILES.in +index 551411a854..6f9620d73a 100644 +--- a/po/POTFILES.in ++++ b/po/POTFILES.in +@@ -238,6 +238,7 @@ + @SRCDIR@/src/util/vircrypto.c + @SRCDIR@/src/util/virdaemon.c + @SRCDIR@/src/util/virdbus.c ++@SRCDIR@/src/util/virdevmapper.c + @SRCDIR@/src/util/virdnsmasq.c + @SRCDIR@/src/util/virerror.c + @SRCDIR@/src/util/virerror.h +diff --git a/src/util/virdevmapper.c b/src/util/virdevmapper.c +index ecc5e433c7..a471504176 100644 +--- a/src/util/virdevmapper.c ++++ b/src/util/virdevmapper.c +@@ -20,38 +20,67 @@ + + #include + ++#include "virdevmapper.h" ++#include "internal.h" ++ + #ifdef __linux__ + # include +-#endif ++# include ++# include ++# include ++# include ++# include + +-#ifdef WITH_DEVMAPPER +-# include +-#endif ++# include "virthread.h" ++# include "viralloc.h" ++# include "virstring.h" ++# include "virfile.h" ++ ++# define VIR_FROM_THIS VIR_FROM_STORAGE ++ ++# define PROC_DEVICES "/proc/devices" ++# define DM_NAME "device-mapper" ++# define DEV_DM_DIR "/dev/" DM_DIR ++# define CONTROL_PATH DEV_DM_DIR "/" DM_CONTROL_NODE ++# define BUF_SIZE (16 * 1024) ++ ++G_STATIC_ASSERT(BUF_SIZE > sizeof(struct dm_ioctl)); ++ ++static unsigned int virDMMajor; + +-#include "virdevmapper.h" +-#include "internal.h" +-#include "virthread.h" +-#include "viralloc.h" +-#include "virstring.h" +- +-#ifdef WITH_DEVMAPPER +-static void +-virDevMapperDummyLogger(int level G_GNUC_UNUSED, +- const char *file G_GNUC_UNUSED, +- int line G_GNUC_UNUSED, +- int dm_errno G_GNUC_UNUSED, +- const char *fmt G_GNUC_UNUSED, +- ...) +-{ +- return; +-} + + static int + virDevMapperOnceInit(void) + { +- /* Ideally, we would not need this. But libdevmapper prints +- * error messages to stderr by default. Sad but true. */ +- dm_log_with_errno_init(virDevMapperDummyLogger); ++ g_autofree char *buf = NULL; ++ VIR_AUTOSTRINGLIST lines = NULL; ++ size_t i; ++ ++ if (virFileReadAll(PROC_DEVICES, BUF_SIZE, &buf) < 0) ++ return -1; ++ ++ lines = virStringSplit(buf, "\n", 0); ++ if (!lines) ++ return -1; ++ ++ for (i = 0; lines[i]; i++) { ++ g_autofree char *dev = NULL; ++ unsigned int maj; ++ ++ if (sscanf(lines[i], "%u %ms\n", &maj, &dev) == 2 && ++ STREQ(dev, DM_NAME)) { ++ virDMMajor = maj; ++ break; ++ } ++ } ++ ++ if (!lines[i]) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Unable to find major for %s"), ++ DM_NAME); ++ return -1; ++ } ++ + return 0; + } + +@@ -59,101 +88,190 @@ virDevMapperOnceInit(void) + VIR_ONCE_GLOBAL_INIT(virDevMapper); + + ++static void * ++virDMIoctl(int controlFD, int cmd, struct dm_ioctl *dm, char **buf) ++{ ++ size_t bufsize = BUF_SIZE; ++ ++ reread: ++ *buf = g_new0(char, bufsize); ++ ++ dm->version[0] = DM_VERSION_MAJOR; ++ dm->version[1] = 0; ++ dm->version[2] = 0; ++ dm->data_size = bufsize; ++ dm->data_start = sizeof(struct dm_ioctl); ++ ++ memcpy(*buf, dm, sizeof(struct dm_ioctl)); ++ ++ if (ioctl(controlFD, cmd, *buf) < 0) { ++ VIR_FREE(*buf); ++ return NULL; ++ } ++ ++ memcpy(dm, *buf, sizeof(struct dm_ioctl)); ++ ++ if (dm->flags & DM_BUFFER_FULL_FLAG) { ++ bufsize += BUF_SIZE; ++ VIR_FREE(*buf); ++ goto reread; ++ } ++ ++ return *buf + dm->data_start; ++} ++ ++ + static int +-virDevMapperGetTargetsImpl(const char *path, +- char ***devPaths_ret, +- unsigned int ttl) ++virDMOpen(void) + { +- struct dm_task *dmt = NULL; +- struct dm_deps *deps; +- struct dm_info info; +- char **devPaths = NULL; +- char **recursiveDevPaths = NULL; +- size_t i; +- int ret = -1; ++ VIR_AUTOCLOSE controlFD = -1; ++ struct dm_ioctl dm; ++ g_autofree char *tmp = NULL; ++ int ret; + +- *devPaths_ret = NULL; ++ memset(&dm, 0, sizeof(dm)); + +- if (virDevMapperInitialize() < 0) +- return ret; ++ if ((controlFD = open(CONTROL_PATH, O_RDWR)) < 0) ++ return -1; + +- if (ttl == 0) { +- errno = ELOOP; +- return ret; ++ if (!virDMIoctl(controlFD, DM_VERSION, &dm, &tmp)) { ++ virReportSystemError(errno, "%s", ++ _("Unable to get device-mapper version")); ++ return -1; + } + +- if (!(dmt = dm_task_create(DM_DEVICE_DEPS))) { +- if (errno == ENOENT || errno == ENODEV) { +- /* It's okay. Kernel is probably built without +- * devmapper support. */ +- ret = 0; +- } +- return ret; ++ if (dm.version[0] != DM_VERSION_MAJOR) { ++ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, ++ _("Unsupported device-mapper version. Expected %d got %d"), ++ DM_VERSION_MAJOR, dm.version[0]); ++ return -1; + } + +- if (!dm_task_set_name(dmt, path)) { +- if (errno == ENOENT) { +- /* It's okay, @path is not managed by devmapper => +- * not a devmapper device. */ +- ret = 0; +- } +- goto cleanup; ++ ret = controlFD; ++ controlFD = -1; ++ return ret; ++} ++ ++ ++static char * ++virDMSanitizepath(const char *path) ++{ ++ g_autofree char *dmDirPath = NULL; ++ struct dirent *ent = NULL; ++ struct stat sb[2]; ++ DIR *dh = NULL; ++ const char *p; ++ char *ret = NULL; ++ int rc; ++ ++ /* If a path is NOT provided then assume it's DM name */ ++ p = strrchr(path, '/'); ++ ++ if (!p) ++ return g_strdup(path); ++ else ++ p++; ++ ++ /* It's a path. Check if the last component is DM name */ ++ if (stat(path, &sb[0]) < 0) { ++ virReportError(errno, ++ _("Unable to stat %p"), ++ path); ++ return NULL; + } + +- dm_task_no_open_count(dmt); ++ dmDirPath = g_strdup_printf(DEV_DM_DIR "/%s", p); + +- if (!dm_task_run(dmt)) { +- if (errno == ENXIO) { +- /* If @path = "/dev/mapper/control" ENXIO is returned. */ +- ret = 0; ++ if (stat(dmDirPath, &sb[1]) == 0 && ++ sb[0].st_rdev == sb[1].st_rdev) { ++ return g_strdup(p); ++ } ++ ++ /* The last component of @path wasn't DM name. Let's check if ++ * there's a device under /dev/mapper/ with the same rdev. */ ++ if (virDirOpen(&dh, DEV_DM_DIR) < 0) ++ return NULL; ++ ++ while ((rc = virDirRead(dh, &ent, DEV_DM_DIR)) > 0) { ++ g_autofree char *tmp = g_strdup_printf(DEV_DM_DIR "/%s", ent->d_name); ++ ++ if (stat(tmp, &sb[1]) == 0 && ++ sb[0].st_rdev == sb[0].st_rdev) { ++ ret = g_steal_pointer(&tmp); ++ break; + } +- goto cleanup; + } + +- if (!dm_task_get_info(dmt, &info)) +- goto cleanup; ++ virDirClose(&dh); ++ return ret; ++} ++ ++ ++static int ++virDevMapperGetTargetsImpl(int controlFD, ++ const char *path, ++ char ***devPaths_ret, ++ unsigned int ttl) ++{ ++ g_autofree char *sanitizedPath = NULL; ++ g_autofree char *buf = NULL; ++ struct dm_ioctl dm; ++ struct dm_target_deps *deps = NULL; ++ VIR_AUTOSTRINGLIST devPaths = NULL; ++ size_t i; ++ ++ memset(&dm, 0, sizeof(dm)); ++ *devPaths_ret = NULL; ++ ++ if (ttl == 0) { ++ errno = ELOOP; ++ return -1; ++ } ++ ++ if (!virIsDevMapperDevice(path)) ++ return 0; ++ ++ if (!(sanitizedPath = virDMSanitizepath(path))) ++ return 0; + +- if (!info.exists) { +- ret = 0; +- goto cleanup; ++ if (virStrncpy(dm.name, sanitizedPath, -1, DM_TABLE_DEPS) < 0) { ++ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", ++ _("Resolved device mapper name too long")); ++ return -1; + } + +- if (!(deps = dm_task_get_deps(dmt))) +- goto cleanup; ++ deps = virDMIoctl(controlFD, DM_TABLE_DEPS, &dm, &buf); ++ if (!deps) { ++ if (errno == ENXIO) ++ return 0; ++ ++ virReportSystemError(errno, ++ _("Unable to query dependencies for %s"), ++ path); ++ return -1; ++ } + + if (VIR_ALLOC_N_QUIET(devPaths, deps->count + 1) < 0) +- goto cleanup; ++ return -1; + + for (i = 0; i < deps->count; i++) { + devPaths[i] = g_strdup_printf("/dev/block/%u:%u", +- major(deps->device[i]), +- minor(deps->device[i])); ++ major(deps->dev[i]), ++ minor(deps->dev[i])); + } + +- recursiveDevPaths = NULL; + for (i = 0; i < deps->count; i++) { +- char **tmpPaths; ++ VIR_AUTOSTRINGLIST tmpPaths = NULL; + +- if (virDevMapperGetTargetsImpl(devPaths[i], &tmpPaths, ttl - 1) < 0) +- goto cleanup; ++ if (virDevMapperGetTargetsImpl(controlFD, devPaths[i], &tmpPaths, ttl - 1) < 0) ++ return -1; + +- if (tmpPaths && +- virStringListMerge(&recursiveDevPaths, &tmpPaths) < 0) { +- virStringListFree(tmpPaths); +- goto cleanup; +- } ++ if (virStringListMerge(&devPaths, &tmpPaths) < 0) ++ return -1; + } + +- if (virStringListMerge(&devPaths, &recursiveDevPaths) < 0) +- goto cleanup; +- + *devPaths_ret = g_steal_pointer(&devPaths); +- ret = 0; +- cleanup: +- virStringListFree(recursiveDevPaths); +- virStringListFree(devPaths); +- dm_task_destroy(dmt); +- return ret; ++ return 0; + } + + +@@ -172,9 +290,6 @@ virDevMapperGetTargetsImpl(const char *path, + * If @path consists of yet another devmapper targets these are + * consulted recursively. + * +- * If we don't have permissions to talk to kernel, -1 is returned +- * and errno is set to EBADF. +- * + * Returns 0 on success, + * -1 otherwise (with errno set, no libvirt error is + * reported) +@@ -183,46 +298,53 @@ int + virDevMapperGetTargets(const char *path, + char ***devPaths) + { ++ VIR_AUTOCLOSE controlFD = -1; + const unsigned int ttl = 32; + + /* Arbitrary limit on recursion level. A devmapper target can + * consist of devices or yet another targets. If that's the + * case, we have to stop recursion somewhere. */ + +- return virDevMapperGetTargetsImpl(path, devPaths, ttl); +-} ++ if (virDevMapperInitialize() < 0) ++ return -1; + +-#else /* ! WITH_DEVMAPPER */ ++ if ((controlFD = virDMOpen()) < 0) ++ return -1; + +-int +-virDevMapperGetTargets(const char *path G_GNUC_UNUSED, +- char ***devPaths G_GNUC_UNUSED) +-{ +- errno = ENOSYS; +- return -1; ++ return virDevMapperGetTargetsImpl(controlFD, path, devPaths, ttl); + } +-#endif /* ! WITH_DEVMAPPER */ + + +-#if WITH_DEVMAPPER + bool + virIsDevMapperDevice(const char *dev_name) + { + struct stat buf; + ++ if (virDevMapperInitialize() < 0) ++ return false; ++ + if (!stat(dev_name, &buf) && + S_ISBLK(buf.st_mode) && +- dm_is_dm_major(major(buf.st_rdev))) +- return true; ++ major(buf.st_rdev) == virDMMajor) ++ return true; + + return false; + } + +-#else /* ! WITH_DEVMAPPER */ ++#else /* !defined(__linux__) */ ++ ++int ++virDevMapperGetTargets(const char *path G_GNUC_UNUSED, ++ char ***devPaths G_GNUC_UNUSED) ++{ ++ errno = ENOSYS; ++ return -1; ++} ++ + + bool + virIsDevMapperDevice(const char *dev_name G_GNUC_UNUSED) + { + return false; + } +-#endif /* ! WITH_DEVMAPPER */ ++#endif /* ! defined(__linux__) */ +-- +2.27.0 + diff --git a/virdevmapper-Handle-kernel-without-device-mapper-sup.patch b/virdevmapper-Handle-kernel-without-device-mapper-sup.patch new file mode 100644 index 0000000000000000000000000000000000000000..ba256260898c50d33969378f8f5b73a6df118ad0 --- /dev/null +++ b/virdevmapper-Handle-kernel-without-device-mapper-sup.patch @@ -0,0 +1,79 @@ +From 83298f3086380c9b3b3ec39a2d6bf7b33592683b Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Tue, 18 Aug 2020 11:04:24 +0200 +Subject: [PATCH] virdevmapper: Handle kernel without device-mapper support + +In one of my latest patch (v6.6.0~30) I was trying to remove +libdevmapper use in favor of our own implementation. However, the +code did not take into account that device mapper can be not +compiled into the kernel (e.g. be a separate module that's not +loaded) in which case /proc/devices won't have the device-mapper +major number and thus virDevMapperGetTargets() and/or +virIsDevMapperDevice() fails. + +However, such failure is safe to ignore, because if device mapper +is missing then there can't be any multipath devices and thus we +don't need to allow the deps in CGroups, nor create them in the +domain private namespace, etc. + +Fixes: 22494556542c676d1b9e7f1c1f2ea13ac17e1e3e +Reported-by: Andrea Bolognani +Reported-by: Christian Ehrhardt +Signed-off-by: Michal Privoznik +Reviewed-by: Peter Krempa +Reviewed-by: Christian Ehrhardt +Tested-by: Christian Ehrhardt +--- + src/util/virdevmapper.c | 20 ++++++++++++++++++-- + 1 file changed, 18 insertions(+), 2 deletions(-) + +diff --git a/src/util/virdevmapper.c b/src/util/virdevmapper.c +index b43dbefa9a..a81e2edee4 100644 +--- a/src/util/virdevmapper.c ++++ b/src/util/virdevmapper.c +@@ -54,6 +54,9 @@ virDevMapperGetMajor(unsigned int *major) + VIR_AUTOSTRINGLIST lines = NULL; + size_t i; + ++ if (!virFileExists(CONTROL_PATH)) ++ return -2; ++ + if (virFileReadAll(PROC_DEVICES, BUF_SIZE, &buf) < 0) + return -1; + +@@ -126,8 +129,13 @@ virDMOpen(void) + + memset(&dm, 0, sizeof(dm)); + +- if ((controlFD = open(CONTROL_PATH, O_RDWR)) < 0) ++ if ((controlFD = open(CONTROL_PATH, O_RDWR)) < 0) { ++ if (errno == ENOENT) ++ return -2; ++ ++ virReportSystemError(errno, _("Unable to open %s"), CONTROL_PATH); + return -1; ++ } + + if (!virDMIoctl(controlFD, DM_VERSION, &dm, &tmp)) { + virReportSystemError(errno, "%s", +@@ -300,8 +308,16 @@ virDevMapperGetTargets(const char *path, + * consist of devices or yet another targets. If that's the + * case, we have to stop recursion somewhere. */ + +- if ((controlFD = virDMOpen()) < 0) ++ if ((controlFD = virDMOpen()) < 0) { ++ if (controlFD == -2) { ++ /* The CONTROL_PATH doesn't exist. Probably the ++ * module isn't loaded, yet. Don't error out, just ++ * exit. */ ++ return 0; ++ } ++ + return -1; ++ } + + return virDevMapperGetTargetsImpl(controlFD, path, devPaths, ttl); + } +-- +2.27.0 + diff --git a/virsh-Display-vhostuser-socket-path-in-domblklist.patch b/virsh-Display-vhostuser-socket-path-in-domblklist.patch new file mode 100644 index 0000000000000000000000000000000000000000..cc6ed7a804a960560f737e85c9d5481050569018 --- /dev/null +++ b/virsh-Display-vhostuser-socket-path-in-domblklist.patch @@ -0,0 +1,32 @@ +From a50b9b25b94d590215ccbe18a6b9860990098f81 Mon Sep 17 00:00:00 2001 +From: dinglimin +Date: Thu, 16 Dec 2021 17:18:48 +0800 +Subject: [PATCH] virsh: Display vhostuser socket path in domblklist + +The domblklist command is designed to show a brief information about the blocks +of a domain. One piece of information that is shows is "Target" and "Source". +Before the modification, the Vhost disk of SPDK is displayed as "-". After +the modification, the socket associated with it can be displayed. + +Signed-off-by: dinglimin +--- + tools/virsh-domain-monitor.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c +index 9b8c69fa9d..74ff369597 100644 +--- a/tools/virsh-domain-monitor.c ++++ b/tools/virsh-domain-monitor.c +@@ -665,7 +665,8 @@ cmdDomblklist(vshControl *ctl, const vshCmd *cmd) + "|./source/@dev" + "|./source/@dir" + "|./source/@name" +- "|./source/@volume)", ctxt); ++ "|./source/@volume" ++ "|./source/@path)", ctxt); + } + + if (details) { +-- +2.27.0 +