Compare commits

...

10 Commits

Author SHA1 Message Date
openeuler-ci-bot
186aff3e60
!347 [sync] PR-344: libvirt update to version 6.2.0-67
From: @openeuler-sync-bot 
Reviewed-by: @imxcc 
Signed-off-by: @imxcc
2024-08-22 09:00:04 +00:00
Jiabo Feng
3794a89ceb libvirt update to version 6.2.0-67:
- virt-host-validate: Fix IOMMU output on aarch64
- cpu: revert: Modify virCPUarmCompare to perform compare actions
- cpu: Modify virCPUarmCompare to perform compare actions
- add phytium s5000c support on arm architecture for capability

Signed-off-by: Jiabo Feng <fengjiabo1@huawei.com>
(cherry picked from commit 44c38ffc1edcbe107228e1bfb254fbccee15d88c)
2024-08-22 16:15:10 +08:00
ikarosYuuki
dfed5f54d6 qemu: enable overcommit_memory while start cvm
- qemu: enable overcommit_memory while start cvm

Signed-off-by: ikarosYuuki <tujipei@huawei.com>
(cherry picked from commit 8e920e9de2c12be1b438cef31828997b17f63eda)
2024-08-22 16:15:10 +08:00
openeuler-ci-bot
8d6b2ac3e1
!335 [sync] PR-333: libvirt update to version 6.2.0-65
From: @openeuler-sync-bot 
Reviewed-by: @imxcc 
Signed-off-by: @imxcc
2024-06-13 06:21:46 +00:00
Jiabo Feng
5b89951474 libvirt update to version 6.2.0-65:
- remote: fix double free of migration params on error
- qemu: avoid deadlock in qemuDomainObjStopWorker We are dropping the only reference here so that the event loop thread is going to be exited synchronously. In order to avoid deadlocks we need to unlock the VM so that any handler being called can finish execution and thus even loop thread be finished too.
- virsh: add tmm main command word Add tmm command word into virsh tool to call get tmm memory info API. It makes virsh can use tmm main commmand to show tmm memory info on console. This command requires specific kernel and a kernel driver to make sure its regular function. If runnning environment missing the above reliance, this command will show error result on console.
- libvirt: add get tmm memory info API and libvirtd RPC Add the get tmm memory info API into libvirt-host. Also should add the RPC calls into libvirtd for API calling.
- libvirt: support the virtCCA feature Add cvm parameter into the type of LaunchSecurity which is a optional filed for libvirt xml. Its purpose is to pass the cvm parameter through to qemu. Also this patch support virsh edit to save cvm parameter into libvirt temporary xml.
- qemu_driver: Add calc_mode for dirtyrate statistics
- virsh: Add mode option to domdirtyrate-calc virsh api
- qemu: Generate command line for dirty-ring-size
- qemu: support dirty ring feature
- conf: Turn virDomainDef.kvm_features into a struct
- qemu_validate: Allow kvm hint-dedicated on non-passthrough VMs
- virDomainFeaturesKVMDefParse: Remove tautological "if"
- virDomainFeaturesKVMDefParse: Remove tautological "switch"
- virxml: Add virXMLPropUInt
- virxml: Add virXMLPropInt
- virxml: Add virXMLPropTristateSwitch
- virxml: Add virXMLPropTristateBool
- virDomainFeaturesKVMDefParse: Remove ctxt
- virDomainFeaturesDefParse: Factor out KVM parsing into separate function
- internal.h: Introduce and use VIR_IS_POW2()
- hotpatch: if hotpatch_path not in qemu.conf,the hotpatch doesn't antoload

Signed-off-by: Jiabo Feng <fengjiabo1@huawei.com>
(cherry picked from commit 46011ccf7e4d88afb1c57224767e52843fbcb45e)
2024-06-13 11:44:38 +08:00
openeuler-ci-bot
f4eb9b66b7
!326 fix CVE-2024-4418
From: @jjiacheng 
Reviewed-by: @caozhongwang, @mdsc 
Signed-off-by: @mdsc
2024-05-27 13:09:31 +00:00
jiangjiacheng
ff377327cc fix CVE-2024-4418
- util: keep track of full GSource object not source ID number
- rpc: mark source returned by virEventGLibAddSocketWatch as unused
- rpc: ensure temporary GSource is removed from client event loop (CVE-2024-4418)
2024-05-24 20:50:43 +08:00
openeuler-ci-bot
02db625114
!299 sync commit
From: @JiaboFeng 
Reviewed-by: @imxcc 
Signed-off-by: @imxcc
2024-04-12 08:10:08 +00:00
lixianglai
491930c766 Synchronize upstream patches "Use correct tpm device for all non-x86"
Fix the exception of adding TPM devices via virt-manager
by synchronizing upstream patches.

Signed-off-by: lixianglai <lixianglai@loongson.cn>
(cherry picked from commit 7e0d98bb1b1b0719ac595124afbd135781bb4115)
2024-04-12 15:46:19 +08:00
lixianglai
afbb13c9a8 Fixed loongarch qxl device not displaying during startup phase
Fixed an issue where qxl devices could not be displayed in bios and grub
stages due to a loongarch architecture string comparison error.

Signed-off-by: lixianglai <lixianglai@loongson.cn>
(cherry picked from commit 3ec9f99b9e3286a298053975ed837c7a81f8bbe2)
2024-04-11 17:44:29 +08:00
32 changed files with 3574 additions and 24 deletions

View File

@ -0,0 +1,30 @@
From 8b57ac24787afc0a94f3ba8e065f9524c986fa7f Mon Sep 17 00:00:00 2001
From: lixianglai <lixianglai@loongson.cn>
Date: Tue, 12 Sep 2023 02:08:31 -0400
Subject: [PATCH] Fixed loongarch qxl device not displaying during startup
phase
Fixed an issue where qxl devices could not be displayed in bios and grub
stages due to a loongarch architecture string comparison error.
Signed-off-by: lixianglai <lixianglai@loongson.cn>
---
src/qemu/qemu_domain.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index fbc665aff3..5933039f5c 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -12998,7 +12998,7 @@ qemuDomainMachineIsLoongson(const char *machine,
return false;
if (STREQ(machine, "loongson7a") ||
- STRPREFIX(machine, "loongson7a-")) {
+ STRPREFIX(machine, "loongson7a")) {
return true;
}
--
2.27.0

View File

@ -0,0 +1,55 @@
From 942ec21751ab2af7d74ee1f3aa01f60b77cb8e5f Mon Sep 17 00:00:00 2001
From: pengmengguang <pengmengguang@phytium.com.cn>
Date: Wed, 3 Jul 2024 09:44:36 +0800
Subject: [PATCH] add phytium s5000c support on arm architecture for capability
Add information of phytium s5000c in relative files.
Signed-off-by: pengmengguang <pengmengguang@phytium.com.cn>
Signed-off-by: Jiakun Shuai <shuaijiakun1288@phytium.com.cn>
---
src/cpu_map/Makefile.inc.am | 1 +
src/cpu_map/arm_Tengyun-S5000C.xml | 6 ++++++
src/cpu_map/index.xml | 1 +
3 files changed, 8 insertions(+)
create mode 100644 src/cpu_map/arm_Tengyun-S5000C.xml
diff --git a/src/cpu_map/Makefile.inc.am b/src/cpu_map/Makefile.inc.am
index 3c674dea40..203d1feb6b 100644
--- a/src/cpu_map/Makefile.inc.am
+++ b/src/cpu_map/Makefile.inc.am
@@ -77,6 +77,7 @@ cpumap_DATA = \
cpu_map/arm_Kunpeng-920.xml \
cpu_map/arm_FT-2000plus.xml \
cpu_map/arm_Tengyun-S2500.xml \
+ cpu_map/arm_Tengyun-S5000C.xml \
$(NULL)
EXTRA_DIST += $(cpumap_DATA)
diff --git a/src/cpu_map/arm_Tengyun-S5000C.xml b/src/cpu_map/arm_Tengyun-S5000C.xml
new file mode 100644
index 0000000000..f8fa593c19
--- /dev/null
+++ b/src/cpu_map/arm_Tengyun-S5000C.xml
@@ -0,0 +1,6 @@
+<cpus>
+ <model name='Tengyun-S5000C'>
+ <vendor name='Phytium'/>
+ <pvr value='0x862'/>
+ </model>
+</cpus>
diff --git a/src/cpu_map/index.xml b/src/cpu_map/index.xml
index 1c05dd814d..1b7f50d76a 100644
--- a/src/cpu_map/index.xml
+++ b/src/cpu_map/index.xml
@@ -100,6 +100,7 @@
<!-- Phytium-based CPU models -->
<include filename='arm_FT-2000plus.xml'/>
<include filename='arm_Tengyun-S2500.xml'/>
+ <include filename='arm_Tengyun-S5000C.xml'/>
</arch>
<arch name='loongarch64'>
--
2.41.0.windows.1

View File

@ -0,0 +1,139 @@
From 715288515d2c6eb2c6d036b8068e3a6b15d1adf3 Mon Sep 17 00:00:00 2001
From: Michal Privoznik <mprivozn@redhat.com>
Date: Tue, 14 Dec 2021 10:24:30 +0100
Subject: [PATCH] conf: Turn virDomainDef.kvm_features into a struct
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
In future commits we will need to store not just an array of
VIR_TRISTATE_SWITCH_* but also an additional integer. Follow the
example of TCG and introduce a structure where both the array an
integer can live.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: J谩n Tomko <jtomko@redhat.com>
Signed-off-by: Shaokun Wei <weishaokun@kylinos.cn>
---
src/conf/domain_conf.c | 20 +++++++++++++-------
src/conf/domain_conf.h | 7 ++++++-
src/qemu/qemu_command.c | 4 ++--
3 files changed, 21 insertions(+), 10 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index e884d94ef7..e94ae4ea17 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -3476,6 +3476,7 @@ void virDomainDefFree(virDomainDefPtr def)
VIR_FREE(def->emulator);
VIR_FREE(def->description);
VIR_FREE(def->title);
+ VIR_FREE(def->kvm_features);
VIR_FREE(def->hyperv_vendor_id);
virBlkioDeviceArrayClear(def->blkio.devices,
@@ -20596,7 +20597,9 @@ static int
virDomainFeaturesKVMDefParse(virDomainDef *def,
xmlNodePtr node)
{
- def->features[VIR_DOMAIN_FEATURE_KVM] = VIR_TRISTATE_SWITCH_ON;
+ g_autofree virDomainFeatureKVM *kvm = NULL;
+
+ kvm = g_new0(virDomainFeatureKVM, 1);
node = xmlFirstElementChild(node);
while (node) {
@@ -20615,11 +20618,14 @@ virDomainFeaturesKVMDefParse(virDomainDef *def,
&value) < 0)
return -1;
- def->kvm_features[feature] = value;
+ kvm->features[feature] = value;
node = xmlNextElementSibling(node);
}
+ def->features[VIR_DOMAIN_FEATURE_KVM] = VIR_TRISTATE_SWITCH_ON;
+ def->kvm_features = g_steal_pointer(&kvm);
+
return 0;
}
@@ -23584,13 +23590,13 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src,
switch ((virDomainKVM) i) {
case VIR_DOMAIN_KVM_HIDDEN:
case VIR_DOMAIN_KVM_DEDICATED:
- if (src->kvm_features[i] != dst->kvm_features[i]) {
+ if (src->kvm_features->features[i] != dst->kvm_features->features[i]) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("State of KVM feature '%s' differs: "
"source: '%s', destination: '%s'"),
virDomainKVMTypeToString(i),
- virTristateSwitchTypeToString(src->kvm_features[i]),
- virTristateSwitchTypeToString(dst->kvm_features[i]));
+ virTristateSwitchTypeToString(src->kvm_features->features[i]),
+ virTristateSwitchTypeToString(dst->kvm_features->features[i]));
return false;
}
@@ -29201,11 +29207,11 @@ virDomainDefFormatFeatures(virBufferPtr buf,
switch ((virDomainKVM) j) {
case VIR_DOMAIN_KVM_HIDDEN:
case VIR_DOMAIN_KVM_DEDICATED:
- if (def->kvm_features[j])
+ if (def->kvm_features->features[j])
virBufferAsprintf(&childBuf, "<%s state='%s'/>\n",
virDomainKVMTypeToString(j),
virTristateSwitchTypeToString(
- def->kvm_features[j]));
+ def->kvm_features->features[j]));
break;
/* coverity[dead_error_begin] */
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 6d56ef0282..d75d06d7b8 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2297,6 +2297,11 @@ struct _virDomainResctrlDef {
size_t nmonitors;
};
+typedef struct _virDomainFeatureKVM virDomainFeatureKVM;
+struct _virDomainFeatureKVM {
+ int features[VIR_DOMAIN_KVM_LAST];
+};
+
struct _virDomainVcpuDef {
bool online;
@@ -2479,7 +2484,7 @@ struct _virDomainDef {
int features[VIR_DOMAIN_FEATURE_LAST];
int caps_features[VIR_DOMAIN_PROCES_CAPS_FEATURE_LAST];
int hyperv_features[VIR_DOMAIN_HYPERV_LAST];
- int kvm_features[VIR_DOMAIN_KVM_LAST];
+ virDomainFeatureKVM *kvm_features;
int msrs_features[VIR_DOMAIN_MSRS_LAST];
unsigned int hyperv_spinlocks;
int hyperv_stimer_direct;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index d7db30d19b..ed843315dc 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6911,12 +6911,12 @@ qemuBuildCpuCommandLine(virCommandPtr cmd,
for (i = 0; i < VIR_DOMAIN_KVM_LAST; i++) {
switch ((virDomainKVM) i) {
case VIR_DOMAIN_KVM_HIDDEN:
- if (def->kvm_features[i] == VIR_TRISTATE_SWITCH_ON)
+ if (def->kvm_features->features[i] == VIR_TRISTATE_SWITCH_ON)
virBufferAddLit(&buf, ",kvm=off");
break;
case VIR_DOMAIN_KVM_DEDICATED:
- if (def->kvm_features[i] == VIR_TRISTATE_SWITCH_ON)
+ if (def->kvm_features->features[i] == VIR_TRISTATE_SWITCH_ON)
virBufferAddLit(&buf, ",kvm-hint-dedicated=on");
break;
--
2.27.0

View File

@ -0,0 +1,46 @@
From 0acd85e553d371b86b5c387f23301947329fdcf3 Mon Sep 17 00:00:00 2001
From: Zhenyu Zheng <zheng.zhenyu@outlook.com>
Date: Thu, 24 Sep 2020 22:12:21 +0800
Subject: [PATCH] cpu: Modify virCPUarmCompare to perform compare actions
Modify virCPUarmCompare in cpu_arm.c to perform compare action.
This patch only adds host to host CPU compare, the rest cases
remains the same. This is useful for source and destination host
compare during migrations to avoid migration between different
CPU models that have different CPU freatures.
-------------------------------------------------------------
This patch only adds host to host CPU compare, the rest cases
remains the same.
Signed-off-by: Zhenyu Zheng <zheng.zhenyu@outlook.com>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Signed-off-by: pengmengguang <pengmengguang@phytium.com.cn>
Conflicts:
[pengmengguang: adjust content]
Signed-off-by: Jiakun Shuai <shuaijiakun1288@phytium.com.cn>
---
src/cpu/cpu_arm.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/cpu/cpu_arm.c b/src/cpu/cpu_arm.c
index a0c0befaa0..b2b2d90a40 100644
--- a/src/cpu/cpu_arm.c
+++ b/src/cpu/cpu_arm.c
@@ -979,6 +979,10 @@ virCPUarmCompare(virCPUDefPtr host,
virCPUCompareResult ret = VIR_CPU_COMPARE_ERROR;
g_autofree char *message = NULL;
+ /* Only support host to host CPU compare for ARM */
+ if (cpu->type != VIR_CPU_TYPE_HOST)
+ return VIR_CPU_COMPARE_IDENTICAL;
+
if (!host || !host->model) {
if (failMessages) {
virReportError(VIR_ERR_CPU_INCOMPATIBLE, "%s",
--
2.41.0.windows.1

View File

@ -0,0 +1,33 @@
From e980606145f5a3d8e1e669982f2e8d10bc10a77b Mon Sep 17 00:00:00 2001
From: Jiakun Shuai <shuaijiakun1288@phytium.com.cn>
Date: Mon, 29 Jul 2024 18:29:40 +0800
Subject: [PATCH] cpu: revert: Modify virCPUarmCompare to perform compare
actions
There is something wrong with the previous commit:
cpu: Modify virCPUarmCompare to perform compare actions (0acd85e553d3)
Let's revert it and push the correct version later.
Signed-off-by: Jiakun Shuai <shuaijiakun1288@phytium.com.cn>
---
src/cpu/cpu_arm.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/src/cpu/cpu_arm.c b/src/cpu/cpu_arm.c
index b2b2d90a40..a0c0befaa0 100644
--- a/src/cpu/cpu_arm.c
+++ b/src/cpu/cpu_arm.c
@@ -979,10 +979,6 @@ virCPUarmCompare(virCPUDefPtr host,
virCPUCompareResult ret = VIR_CPU_COMPARE_ERROR;
g_autofree char *message = NULL;
- /* Only support host to host CPU compare for ARM */
- if (cpu->type != VIR_CPU_TYPE_HOST)
- return VIR_CPU_COMPARE_IDENTICAL;
-
if (!host || !host->model) {
if (failMessages) {
virReportError(VIR_ERR_CPU_INCOMPATIBLE, "%s",
--
2.41.0.windows.1

View File

@ -0,0 +1,32 @@
From f083c24428a2f4d5106a9369dec0876f6143d270 Mon Sep 17 00:00:00 2001
From: Dawei Jiang <jiangdawei15@huawei.com>
Date: Mon, 8 Apr 2024 19:59:11 +0800
Subject: [PATCH] hotpatch: if hotpatch_path not in qemu.conf,the hotpatch
doesn't antoload
Signed-off-by: Dawei Jiang <jiangdawei15@huawei.com>
---
src/qemu/qemu_process.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 48d39ba97c..013c9eb847 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -7330,8 +7330,11 @@ qemuProcessLaunch(virConnectPtr conn,
goto cleanup;
/* Autoload hotpatch */
- if ((autoLoadStatus = qemuDomainHotpatchAutoload(vm, cfg->hotpatchPath)) == NULL) {
- VIR_WARN("Failed to autoload the hotpatch for %s.", vm->def->name);
+ if (cfg->hotpatchPath != NULL) {
+ autoLoadStatus = qemuDomainHotpatchAutoload(vm, cfg->hotpatchPath);
+ if (autoLoadStatus == NULL) {
+ VIR_WARN("Failed to autoload the hotpatch for %s.", vm->def->name);
+ }
}
ret = 0;
--
2.27.0

View File

@ -0,0 +1,56 @@
From d568dc527cd3098df2460d3e991efe3ad8b80410 Mon Sep 17 00:00:00 2001
From: Michal Privoznik <mprivozn@redhat.com>
Date: Wed, 4 Nov 2020 19:41:27 +0100
Subject: [PATCH] internal.h: Introduce and use VIR_IS_POW2()
This macro checks whether given number is an integer power of
two. At the same time, I've identified two places where we check
for pow2 and I'm replacing them with the macro.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Tested-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Tested-by: Han Han <hhan@redhat.com>
Reviewed-by: Shaokun Wei <weishaokun@kylinos.cn>
---
src/internal.h | 9 +++++++++
src/util/virrandom.c | 2 +-
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/src/internal.h b/src/internal.h
index 440f01d370..40c993977a 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -216,6 +216,15 @@
(a) = (a) ^ (b); \
} while (0)
+/**
+ * VIR_IS_POW2:
+ *
+ * Returns true if given number is a power of two
+ */
+#define VIR_IS_POW2(x) \
+ ((x) && !((x) & ((x) - 1)))
+
+
/**
* virCheckFlags:
* @supported: an OR'ed set of supported flags
diff --git a/src/util/virrandom.c b/src/util/virrandom.c
index 1b4102cf58..500f55c956 100644
--- a/src/util/virrandom.c
+++ b/src/util/virrandom.c
@@ -89,7 +89,7 @@ double virRandom(void)
*/
uint32_t virRandomInt(uint32_t max)
{
- if ((max & (max - 1)) == 0)
+ if (VIR_IS_POW2(max))
return virRandomBits(__builtin_ffs(max) - 1);
double val = virRandom();
--
2.27.0

View File

@ -0,0 +1,405 @@
From cd0f3755bd04bb58089d756400f20c75550e54f2 Mon Sep 17 00:00:00 2001
From: tujipei <tujipei@huawei.com>
Date: Wed, 12 Jun 2024 12:02:00 +0800
Subject: [PATCH] libvirt: add get tmm memory info API and libvirtd RPC Add the
get tmm memory info API into libvirt-host. Also should add the RPC calls into
libvirtd for API calling.
Signed-off-by: tujipei <tujipei@huawei.com>
---
include/libvirt/libvirt-host.h | 2 +
scripts/apibuild.py | 1 +
scripts/check-aclrules.py | 1 +
src/driver-hypervisor.h | 5 +
src/libvirt-host.c | 35 +++++++
src/libvirt_public.syms | 1 +
src/qemu/qemu_driver.c | 139 ++++++++++++++++++++++++++++
src/remote/remote_daemon_dispatch.c | 23 +++++
src/remote/remote_driver.c | 29 ++++++
src/remote/remote_protocol.x | 16 +++-
10 files changed, 251 insertions(+), 1 deletion(-)
diff --git a/include/libvirt/libvirt-host.h b/include/libvirt/libvirt-host.h
index 6972834175..e7272ccb20 100644
--- a/include/libvirt/libvirt-host.h
+++ b/include/libvirt/libvirt-host.h
@@ -820,5 +820,7 @@ int virNodeAllocPages(virConnectPtr conn,
unsigned int cellCount,
unsigned int flags);
+char *virConnectGetTmmMemoryInfo(virConnectPtr conn,
+ unsigned int detail);
#endif /* LIBVIRT_HOST_H */
diff --git a/scripts/apibuild.py b/scripts/apibuild.py
index c98bcf6091..9b78754e5d 100755
--- a/scripts/apibuild.py
+++ b/scripts/apibuild.py
@@ -107,6 +107,7 @@ ignored_functions = {
"virDomainMigrateConfirm3Params": "private function for migration",
"virDomainMigratePrepareTunnel3Params": "private function for tunnelled migration",
"virErrorCopyNew": "private",
+ "virConnectGetTmmMemoryInfo": "private function for tmm",
}
ignored_macros = {
diff --git a/scripts/check-aclrules.py b/scripts/check-aclrules.py
index e196f81de9..aa5a589c85 100755
--- a/scripts/check-aclrules.py
+++ b/scripts/check-aclrules.py
@@ -54,6 +54,7 @@ whitelist = {
"localOnly": True,
"domainQemuAttach": True,
"domainHotpatchManage": True,
+ "connectGetTmmMemoryInfo": True,
}
# XXX this vzDomainMigrateConfirm3Params looks
diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h
index 82f808905d..e48b701365 100644
--- a/src/driver-hypervisor.h
+++ b/src/driver-hypervisor.h
@@ -1402,6 +1402,10 @@ typedef int
typedef struct _virHypervisorDriver virHypervisorDriver;
typedef virHypervisorDriver *virHypervisorDriverPtr;
+typedef char *
+(*virDrvConnectGetTmmMemoryInfo)(virConnectPtr conn,
+ bool detail);
+
/**
* _virHypervisorDriver:
*
@@ -1664,4 +1668,5 @@ struct _virHypervisorDriver {
virDrvDomainBackupGetXMLDesc domainBackupGetXMLDesc;
virDrvDomainHotpatchManage domainHotpatchManage;
virDrvDomainStartDirtyRateCalc domainStartDirtyRateCalc;
+ virDrvConnectGetTmmMemoryInfo connectGetTmmMemoryInfo;
};
diff --git a/src/libvirt-host.c b/src/libvirt-host.c
index bc3d1d2803..d0750d28cc 100644
--- a/src/libvirt-host.c
+++ b/src/libvirt-host.c
@@ -1754,3 +1754,38 @@ virNodeGetSEVInfo(virConnectPtr conn,
virDispatchError(conn);
return -1;
}
+
+/*
+ * virConnectGetTmmMemoryInfo:
+ * @conn: pointer to the hypervisor connection
+ * @detail: whether libvirtd return detailed tmm memory information;
+ * the default value is 0 which means don't return detailed tmm memory information.
+ *
+ * If Tmm enable, then will fill the cotents of string buffer with tmm memory information.
+ *
+ * Returns string ptr in case of success, and NULL in case of failure.
+ */
+char *
+virConnectGetTmmMemoryInfo(virConnectPtr conn,
+ unsigned int detail)
+{
+ VIR_DEBUG("conn=%p", conn);
+
+ virResetLastError();
+
+ virCheckConnectReturn(conn, NULL);
+
+ if (conn->driver->connectGetTmmMemoryInfo) {
+ char *ret;
+ ret = conn->driver->connectGetTmmMemoryInfo(conn, detail);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+ error:
+ virDispatchError(conn);
+ return NULL;
+}
+
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index f006516208..284b7f7873 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -877,5 +877,6 @@ LIBVIRT_6.2.0 {
global:
virDomainHotpatchManage;
virDomainStartDirtyRateCalc;
+ virConnectGetTmmMemoryInfo;
} LIBVIRT_6.0.0;
# .... define new API here using predicted next version number ....
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 77a139c66b..1e3f63a39a 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -23385,6 +23385,144 @@ qemuDomainStartDirtyRateCalc(virDomainPtr dom,
return ret;
}
+static int
+qemuConnectTmmInfoListAppend(char ***targetInfoStrList,
+ char **infoStrList,
+ int targetNumaNum,
+ int *startIndex,
+ int maxListSize)
+{
+ char *numStart;
+ int numaNode, index, ret = 0;
+
+ for (index = *startIndex; index < maxListSize; index++) {
+ if (strlen(infoStrList[index]) == 0)
+ break;
+
+ numStart = strstr(infoStrList[index], "node ");
+ if (!numStart)
+ return -1;
+
+ virSkipToDigit((const char **)(&numStart));
+ ret = virStrToLong_i(numStart, &numStart, 10, &numaNode);
+ if (ret < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Failed to get current numa node"));
+ return ret;
+ }
+
+ if (numaNode == targetNumaNum) {
+ ret = virStringListAdd(targetInfoStrList, infoStrList[index]);
+ if (ret < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s [%d]",
+ _("Failed to get add info list member"), index);
+ return ret;
+ }
+ } else {
+ break;
+ }
+ }
+
+ *startIndex = index;
+
+ return ret;
+}
+
+static char *
+qemuConnectTmmDetailInfoFormat(char *baseMeminfo,
+ char *slabInfo)
+{
+ int ret, i = 0, j = 0;
+ char *numStart, *numListStart, *format = NULL;
+ char **baseMeminfoSplits = virStringSplit(baseMeminfo, "\n", 0);
+ char **slabInfoSplits = virStringSplit(slabInfo, "\n", 0);
+ char **resultStrList = NULL;
+ int numaSize, numaIndex, headNumaNode;
+ ssize_t meminfoListSize = virStringListLength((const char * const *)baseMeminfoSplits);
+ ssize_t slabInfoSize = virStringListLength((const char * const *)slabInfoSplits);
+
+ numStart = strchr(baseMeminfoSplits[i], ':');
+ numListStart = strchr(baseMeminfoSplits[i], '(');
+ if (!numStart || !numListStart)
+ goto cleanup;
+
+ virSkipToDigit((const char **)(&numStart));
+ ret = virStrToLong_i(numStart, &numStart, 10, &numaSize);
+ if (ret < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Failed to get available numa size"));
+ goto cleanup;
+ }
+
+ ret = virStringListAdd(&resultStrList, baseMeminfoSplits[i++]);
+ if (ret < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s [%d]",
+ _("Failed to get add base memory info list member"), (i - 1));
+ goto cleanup;
+ }
+
+ virSkipToDigit((const char **)(&numListStart));
+ for (numaIndex = 0; *numListStart && numaIndex < numaSize; numaIndex++, numListStart++) {
+ ret = virStrToLong_i(numListStart, &numListStart, 10, &headNumaNode);
+ if (ret < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Failed to get current numa node"));
+ goto cleanup;
+ }
+
+ ret = qemuConnectTmmInfoListAppend(&resultStrList, baseMeminfoSplits, headNumaNode, &i, meminfoListSize);
+ if (ret < 0)
+ goto cleanup;
+ ret = qemuConnectTmmInfoListAppend(&resultStrList, slabInfoSplits, headNumaNode, &j, slabInfoSize);
+ if (ret < 0)
+ goto cleanup;
+ }
+
+ format = virStringListJoin((const char **)resultStrList, "\n");
+
+ cleanup:
+ virStringListFree(baseMeminfoSplits);
+ virStringListFree(slabInfoSplits);
+ virStringListFree(resultStrList);
+ return format;
+}
+
+static char *
+qemuConnectGetTmmMemoryInfo(virConnectPtr conn G_GNUC_UNUSED,
+ bool detail)
+{
+ int maxLen = 10 * 1024;
+ char *meminfo = NULL;
+ g_autofree char *formatInfo = NULL;
+ g_autofree char *baseMeminfo = NULL;
+ g_autofree char *slabInfo = NULL;
+ g_autofree char *buddyInfo = NULL;
+
+ if (virFileReadAll("/sys/kernel/tmm/memory_info", maxLen, &baseMeminfo) < 0)
+ goto end;
+ if (detail && virFileReadAll("/sys/kernel/tmm/slab_info", maxLen, &slabInfo) < 0)
+ goto end;
+ if (detail && virFileReadAll("/sys/kernel/tmm/buddy_info", maxLen, &buddyInfo) < 0)
+ goto end;
+
+ if (detail) {
+ if (!virStringIsEmpty(baseMeminfo) && !virStringIsEmpty(slabInfo)) {
+ formatInfo = qemuConnectTmmDetailInfoFormat(baseMeminfo, slabInfo);
+ if (formatInfo == NULL)
+ goto end;
+ } else {
+ formatInfo = g_strdup_printf(_("%s%s"), baseMeminfo, slabInfo);
+ }
+
+ meminfo = g_strdup_printf(_("%s\n%s"), formatInfo, buddyInfo);
+ } else {
+ meminfo = g_steal_pointer(&baseMeminfo);
+ }
+
+end:
+ return meminfo;
+}
+
static virHypervisorDriver qemuHypervisorDriver = {
.name = QEMU_DRIVER_NAME,
@@ -23627,6 +23765,7 @@ static virHypervisorDriver qemuHypervisorDriver = {
.domainBackupGetXMLDesc = qemuDomainBackupGetXMLDesc, /* 6.0.0 */
.domainHotpatchManage = qemuDomainHotpatchManage, /* 6.2.0 */
.domainStartDirtyRateCalc = qemuDomainStartDirtyRateCalc, /* 6.2.0 */
+ .connectGetTmmMemoryInfo = qemuConnectGetTmmMemoryInfo, /* 6.2.0 */
};
diff --git a/src/remote/remote_daemon_dispatch.c b/src/remote/remote_daemon_dispatch.c
index 0bbcc05235..a9763cee7b 100644
--- a/src/remote/remote_daemon_dispatch.c
+++ b/src/remote/remote_daemon_dispatch.c
@@ -7268,6 +7268,29 @@ remoteDispatchNetworkPortGetParameters(virNetServerPtr server G_GNUC_UNUSED,
return rv;
}
+static int
+remoteDispatchConnectGetTmmMemoryInfo(virNetServerPtr server G_GNUC_UNUSED,
+ virNetServerClientPtr client,
+ virNetMessagePtr msg G_GNUC_UNUSED,
+ virNetMessageErrorPtr rerr,
+ remote_connect_get_tmm_memory_info_args *args,
+ remote_connect_get_tmm_memory_info_ret *ret)
+{
+ int rv = -1;
+ char *meminfo = NULL;
+ virConnectPtr conn = remoteGetHypervisorConn(client);
+
+ if (conn && (meminfo = virConnectGetTmmMemoryInfo(conn, args->detail))) {
+ rv = 0;
+ ret->meminfo = meminfo;
+ }
+
+ if (rv < 0)
+ virNetMessageSaveError(rerr);
+
+ return rv;
+}
+
/*----- Helpers. -----*/
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 9c272b4ff8..b597ae614c 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -8253,6 +8253,34 @@ remoteDomainGetGuestInfo(virDomainPtr dom,
return rv;
}
+static char *
+remoteConnectGetTmmMemoryInfo(virConnectPtr conn,
+ bool detail)
+{
+ char *rv = NULL;
+ struct private_data *priv = conn->privateData;
+ remote_connect_get_tmm_memory_info_args args;
+ remote_connect_get_tmm_memory_info_ret ret;
+
+ remoteDriverLock(priv);
+
+ args.detail = detail;
+
+ memset(&ret, 0, sizeof(ret));
+
+ if (call(conn, priv, 0, REMOTE_PROC_CONNECT_GET_TMM_MEMORY_INFO,
+ (xdrproc_t)xdr_remote_connect_get_tmm_memory_info_args, (char *)&args,
+ (xdrproc_t)xdr_remote_connect_get_tmm_memory_info_ret, (char *)&ret) < 0) {
+ goto done;
+ }
+
+ rv = ret.meminfo;
+
+ done:
+ remoteDriverUnlock(priv);
+ return rv;
+}
+
/* get_nonnull_domain and get_nonnull_network turn an on-wire
* (name, uuid) pair into virDomainPtr or virNetworkPtr object.
* These can return NULL if underlying memory allocations fail,
@@ -8686,6 +8714,7 @@ static virHypervisorDriver hypervisor_driver = {
.domainBackupGetXMLDesc = remoteDomainBackupGetXMLDesc, /* 6.0.0 */
.domainHotpatchManage = remoteDomainHotpatchManage, /* 6.2.0 */
.domainStartDirtyRateCalc = remoteDomainStartDirtyRateCalc, /* 6.2.0 */
+ .connectGetTmmMemoryInfo = remoteConnectGetTmmMemoryInfo /* 6.2.0 */
};
static virNetworkDriver network_driver = {
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index d89cc1a087..f37bd332a1 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -3789,6 +3789,14 @@ struct remote_domain_start_dirty_rate_calc_args {
unsigned int flags;
};
+struct remote_connect_get_tmm_memory_info_args {
+ unsigned int detail;
+};
+
+struct remote_connect_get_tmm_memory_info_ret {
+ remote_nonnull_string meminfo;
+};
+
/*----- Protocol. -----*/
/* Define the program number, protocol version and procedure numbers here. */
@@ -6698,5 +6706,11 @@ enum remote_procedure {
* @generate: both
* @acl: domain:read
*/
- REMOTE_PROC_DOMAIN_HOTPATCH_MANAGE = 800
+ REMOTE_PROC_DOMAIN_HOTPATCH_MANAGE = 800,
+
+ /**
+ * @generate: none
+ * @acl: connect:read
+ */
+ REMOTE_PROC_CONNECT_GET_TMM_MEMORY_INFO = 900
};
--
2.27.0

View File

@ -0,0 +1,189 @@
From a2b13dd8d6e0282d76a583f36965b3a00cdb7eea Mon Sep 17 00:00:00 2001
From: liupingwei <tujipei@huawei.com>
Date: Wed, 12 Jun 2024 11:39:38 +0800
Subject: [PATCH] libvirt: support the virtCCA feature Add cvm parameter into
the type of LaunchSecurity which is a optional filed for libvirt xml. Its
purpose is to pass the cvm parameter through to qemu. Also this patch support
virsh edit to save cvm parameter into libvirt temporary xml.
Signed-off-by: tujipei <tujipei@huawei.com>
---
docs/schemas/domaincommon.rng | 67 ++++++++++++++++++++---------------
src/conf/domain_conf.c | 25 ++++++++++---
src/conf/domain_conf.h | 3 ++
src/qemu/qemu_command.c | 2 ++
4 files changed, 63 insertions(+), 34 deletions(-)
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index e3b51d333c..a49842a9d0 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -460,35 +460,44 @@
<define name="launchSecurity">
<element name="launchSecurity">
- <attribute name="type">
- <value>sev</value>
- </attribute>
- <interleave>
- <element name="cbitpos">
- <data type='unsignedInt'/>
- </element>
- <element name="reducedPhysBits">
- <data type='unsignedInt'/>
- </element>
- <element name="policy">
- <ref name='hexuint'/>
- </element>
- <optional>
- <element name="handle">
- <ref name='unsignedInt'/>
- </element>
- </optional>
- <optional>
- <element name="dhCert">
- <data type="string"/>
- </element>
- </optional>
- <optional>
- <element name="session">
- <data type="string"/>
- </element>
- </optional>
- </interleave>
+ <choice>
+ <group>
+ <attribute name="type">
+ <value>sev</value>
+ </attribute>
+ <interleave>
+ <element name="cbitpos">
+ <data type='unsignedInt'/>
+ </element>
+ <element name="reducedPhysBits">
+ <data type='unsignedInt'/>
+ </element>
+ <element name="policy">
+ <ref name='hexuint'/>
+ </element>
+ <optional>
+ <element name="handle">
+ <ref name='unsignedInt'/>
+ </element>
+ </optional>
+ <optional>
+ <element name="dhCert">
+ <data type="string"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="session">
+ <data type="string"/>
+ </element>
+ </optional>
+ </interleave>
+ </group>
+ <group>
+ <attribute name="type">
+ <value>cvm</value>
+ </attribute>
+ </group>
+ </choice>
</element>
</define>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index cf807c7747..9219d08753 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1273,6 +1273,7 @@ VIR_ENUM_IMPL(virDomainLaunchSecurity,
VIR_DOMAIN_LAUNCH_SECURITY_LAST,
"",
"sev",
+ "cvm",
);
static virClassPtr virDomainObjClass;
@@ -16823,6 +16824,7 @@ virDomainSEVDefParseXML(xmlNodePtr sevNode,
def->sectype = virDomainLaunchSecurityTypeFromString(type);
switch ((virDomainLaunchSecurity) def->sectype) {
case VIR_DOMAIN_LAUNCH_SECURITY_SEV:
+ case VIR_DOMAIN_LAUNCH_SECURITY_CVM:
break;
case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
@@ -22169,11 +22171,19 @@ virDomainDefParseXML(xmlDocPtr xml,
ctxt->node = node;
VIR_FREE(nodes);
- /* Check for SEV feature */
+ /* Check for CVM/SEV feature */
if ((node = virXPathNode("./launchSecurity", ctxt)) != NULL) {
- def->sev = virDomainSEVDefParseXML(node, ctxt);
- if (!def->sev)
- goto error;
+ tmp = virXMLPropString(node, "type");
+ if((virDomainLaunchSecurity)virDomainLaunchSecurityTypeFromString(tmp) == VIR_DOMAIN_LAUNCH_SECURITY_CVM) {
+ def->cvm = true;
+ } else {
+ def->sev = virDomainSEVDefParseXML(node, ctxt);
+ if(!def->sev) {
+ VIR_FREE(tmp);
+ goto error;
+ }
+ }
+ VIR_FREE(tmp);
}
/* analysis of memory devices */
@@ -29861,7 +29871,12 @@ virDomainDefFormatInternalSetRootName(virDomainDefPtr def,
if (def->keywrap)
virDomainKeyWrapDefFormat(buf, def->keywrap);
- virDomainSEVDefFormat(buf, def->sev);
+ if (def->cvm) {
+ virBufferAddLit(buf, "<launchSecurity type='cvm'>\n");
+ virBufferAddLit(buf, "</launchSecurity>\n");
+ } else {
+ virDomainSEVDefFormat(buf, def->sev);
+ }
virBufferAdjustIndent(buf, -2);
virBufferAsprintf(buf, "</%s>\n", rootname);
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 7419bf8d7e..180975840c 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2373,6 +2373,7 @@ struct _virDomainKeyWrapDef {
typedef enum {
VIR_DOMAIN_LAUNCH_SECURITY_NONE,
VIR_DOMAIN_LAUNCH_SECURITY_SEV,
+ VIR_DOMAIN_LAUNCH_SECURITY_CVM,
VIR_DOMAIN_LAUNCH_SECURITY_LAST,
} virDomainLaunchSecurity;
@@ -2586,6 +2587,8 @@ struct _virDomainDef {
/* SEV-specific domain */
virDomainSEVDefPtr sev;
+ /* CVM-specific domain */
+ bool cvm;
/* Application-specific custom metadata */
xmlNodePtr metadata;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 9fcea9d46a..675a624919 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -7266,6 +7266,8 @@ qemuBuildMachineCommandLine(virCommandPtr cmd,
if (def->sev)
virBufferAddLit(&buf, ",memory-encryption=sev0");
+ if (def->cvm)
+ virBufferAddLit(&buf, ",kvm-type=cvm");
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCKDEV)) {
if (priv->pflash0)
--
2.27.0

View File

@ -101,7 +101,7 @@
Summary: Library providing a simple virtualization API
Name: libvirt
Version: 6.2.0
Release: 62
Release: 67
License: LGPLv2+
URL: https://libvirt.org/
@ -489,26 +489,57 @@ Patch0376: selinux-adapt-to-libselinux.patch
Patch0377: Revert-selinux-adapt-to-libselinux.patch
Patch0378: selinux-Reflect-context_str-type-change.patch
Patch0379: virnetsshsession-Adapt-to-change-libssh2-API.patch
Patch0380: qemu-Fix-incorrect-command-name-in-error-messages.patch
Patch0381: esx-call-freeaddrinfo-earlier-in-esxUtil_ResolveHost.patch
Patch0382: admin-fix-leak-of-typed-parameters-on-error.patch
Patch0383: Use-un-signed-printf-specifiers-correctly.patch
Patch0384: fix-the-issue-of-errors-when-saving-after-virsh-edit.patch
Patch0385: virrandom-Fix-printf-format-string-in-virRandomGener.patch
Patch0386: qemu_migration_cookie-Rename-ret-in-qemuDomainExtrac.patch
Patch0387: tests-upstream-Fixing-compiler-warning-in-cputest.patch
Patch0388: qemu-Return-perf-status-that-affect-next-boot-for-sh.patch
Patch0389: lxc-fix-lxcContainerMountAllFS-DEREF_BEFORE_CHECK.patch
Patch0390: Include-vdpa-devices-in-node-device-list.patch
Patch0391: node_device-fix-leak-of-DIR.patch
Patch0392: vdpa-Introduce-the-new-device-type-vdpa-to-hostdev.patch
Patch0393: vdpa-support-vdpa-device-hot-plug-unplug.patch
Patch0394: vdpa-support-vdpa-device-migrate.patch
Patch0395: vdpa-return-pcieFlags-when-calculate-vdpa-passthroug.patch
Patch0396: vdpa-Release-pci-slot-address-when-unplugging-vdpa-d.patch
Patch0397: virsh-Fix-off-by-one-error-in-udevListInterfacesBySt.patch
Patch0398: remote-check-for-negative-array-lengths-before-alloc.patch
Patch0399: interface-fix-udev_device_get_sysattr_value-return-v.patch
Patch0380: qemu-command-Use-correct-tpm-device-for-all-non-x86.patch
Patch0381: Fixed-loongarch-qxl-device-not-displaying-during-sta.patch
Patch0382: qemu-Fix-incorrect-command-name-in-error-messages.patch
Patch0383: esx-call-freeaddrinfo-earlier-in-esxUtil_ResolveHost.patch
Patch0384: admin-fix-leak-of-typed-parameters-on-error.patch
Patch0385: Use-un-signed-printf-specifiers-correctly.patch
Patch0386: fix-the-issue-of-errors-when-saving-after-virsh-edit.patch
Patch0387: virrandom-Fix-printf-format-string-in-virRandomGener.patch
Patch0388: qemu_migration_cookie-Rename-ret-in-qemuDomainExtrac.patch
Patch0389: tests-upstream-Fixing-compiler-warning-in-cputest.patch
Patch0390: qemu-Return-perf-status-that-affect-next-boot-for-sh.patch
Patch0391: lxc-fix-lxcContainerMountAllFS-DEREF_BEFORE_CHECK.patch
Patch0392: Include-vdpa-devices-in-node-device-list.patch
Patch0393: node_device-fix-leak-of-DIR.patch
Patch0394: vdpa-Introduce-the-new-device-type-vdpa-to-hostdev.patch
Patch0395: vdpa-support-vdpa-device-hot-plug-unplug.patch
Patch0396: vdpa-support-vdpa-device-migrate.patch
Patch0397: vdpa-return-pcieFlags-when-calculate-vdpa-passthroug.patch
Patch0398: vdpa-Release-pci-slot-address-when-unplugging-vdpa-d.patch
Patch0399: virsh-Fix-off-by-one-error-in-udevListInterfacesBySt.patch
Patch0400: remote-check-for-negative-array-lengths-before-alloc.patch
Patch0401: interface-fix-udev_device_get_sysattr_value-return-v.patch
Patch0402: util-keep-track-of-full-GSource-object-not-source-ID.patch
Patch0403: rpc-mark-source-returned-by-virEventGLibAddSocketWat.patch
Patch0404: rpc-ensure-temporary-GSource-is-removed-from-client-.patch
Patch0405: hotpatch-if-hotpatch_path-not-in-qemu.conf-the-hotpa.patch
Patch0406: internal.h-Introduce-and-use-VIR_IS_POW2.patch
Patch0407: virDomainFeaturesDefParse-Factor-out-KVM-parsing-int.patch
Patch0408: virDomainFeaturesKVMDefParse-Remove-ctxt.patch
Patch0409: virxml-Add-virXMLPropTristateBool.patch
Patch0410: virxml-Add-virXMLPropTristateSwitch.patch
Patch0411: virxml-Add-virXMLPropInt.patch
Patch0412: virxml-Add-virXMLPropUInt.patch
Patch0413: virDomainFeaturesKVMDefParse-Remove-tautological-swi.patch
Patch0414: virDomainFeaturesKVMDefParse-Remove-tautological-if.patch
Patch0415: qemu_validate-Allow-kvm-hint-dedicated-on-non-passth.patch
Patch0416: conf-Turn-virDomainDef.kvm_features-into-a-struct.patch
Patch0417: qemu-support-dirty-ring-feature.patch
Patch0418: qemu-Generate-command-line-for-dirty-ring-size.patch
Patch0419: virsh-Add-mode-option-to-domdirtyrate-calc-virsh-api.patch
Patch0420: qemu_driver-Add-calc_mode-for-dirtyrate-statistics.patch
Patch0421: libvirt-support-the-virtCCA-feature.patch
Patch0422: libvirt-add-get-tmm-memory-info-API-and-libvirtd-RPC.patch
Patch0423: virsh-add-tmm-main-command-word.patch
Patch0424: qemu-avoid-deadlock-in-qemuDomainObjStopWorker.patch
Patch0425: remote-fix-double-free-of-migration-params-on-error.patch
Patch0426: qemu-enable-overcommit_memory-while-start-cvm.patch
Patch0427: add-phytium-s5000c-support-on-arm-architecture-for-c.patch
Patch0428: cpu-Modify-virCPUarmCompare-to-perform-compare-actio.patch
Patch0429: cpu-revert-Modify-virCPUarmCompare-to-perform-compar.patch
Patch0430: virt-host-validate-Fix-IOMMU-output-on-aarch64.patch
Requires: libvirt-daemon = %{version}-%{release}
Requires: libvirt-daemon-config-network = %{version}-%{release}
@ -2245,16 +2276,53 @@ exit 0
%changelog
* Wed Apr 10 2024 caozhongwang <caozhongwang1@huawei.com>
* Thu Aug 22 2024 Jiabo Feng <fengjiabo1@huawei.com> - 6.2.0-67
- virt-host-validate: Fix IOMMU output on aarch64
- cpu: revert: Modify virCPUarmCompare to perform compare actions
- cpu: Modify virCPUarmCompare to perform compare actions
- add phytium s5000c support on arm architecture for capability
* Thu July 1 2024 ikarosYuuki <tujipei@huawei.com> - 6.2.0-66
- qemu: enable overcommit_memory while start cvm
* Thu Jun 13 2024 Jiabo Feng <fengjiabo1@huawei.com> - 6.2.0-65
- remote: fix double free of migration params on error
- qemu: avoid deadlock in qemuDomainObjStopWorker We are dropping the only reference here so that the event loop thread is going to be exited synchronously. In order to avoid deadlocks we need to unlock the VM so that any handler being called can finish execution and thus even loop thread be finished too.
- virsh: add tmm main command word Add tmm command word into virsh tool to call get tmm memory info API. It makes virsh can use tmm main commmand to show tmm memory info on console. This command requires specific kernel and a kernel driver to make sure its regular function. If runnning environment missing the above reliance, this command will show error result on console.
- libvirt: add get tmm memory info API and libvirtd RPC Add the get tmm memory info API into libvirt-host. Also should add the RPC calls into libvirtd for API calling.
- libvirt: support the virtCCA feature Add cvm parameter into the type of LaunchSecurity which is a optional filed for libvirt xml. Its purpose is to pass the cvm parameter through to qemu. Also this patch support virsh edit to save cvm parameter into libvirt temporary xml.
- qemu_driver: Add calc_mode for dirtyrate statistics
- virsh: Add mode option to domdirtyrate-calc virsh api
- qemu: Generate command line for dirty-ring-size
- qemu: support dirty ring feature
- conf: Turn virDomainDef.kvm_features into a struct
- qemu_validate: Allow kvm hint-dedicated on non-passthrough VMs
- virDomainFeaturesKVMDefParse: Remove tautological "if"
- virDomainFeaturesKVMDefParse: Remove tautological "switch"
- virxml: Add virXMLPropUInt
- virxml: Add virXMLPropInt
- virxml: Add virXMLPropTristateSwitch
- virxml: Add virXMLPropTristateBool
- virDomainFeaturesKVMDefParse: Remove ctxt
- virDomainFeaturesDefParse: Factor out KVM parsing into separate function
- internal.h: Introduce and use VIR_IS_POW2()
- hotpatch: if hotpatch_path not in qemu.conf,the hotpatch doesn't antoload
* Fri May 24 2024 jiangjiacheng <jiangjiacheng@huawei.com> - 6.2.0-64
- util: keep track of full GSource object not source ID number
- rpc: mark source returned by virEventGLibAddSocketWatch as unused
- rpc: ensure temporary GSource is removed from client event loop (CVE-2024-4418)
* Wed Apr 10 2024 caozhongwang <caozhongwang1@huawei.com> - 6.2.0-63
- interface: fix udev_device_get_sysattr_value return value check (CVE-2024-2496)
- remote: check for negative array lengths before allocation (CVE-2024-2494)
- vish:Fix off-by-one error in udevListInterfacesByStatus (CVE-2024-1441)
* Wed Mar 13 2024 jiangdongxu <jiangdongxu1@huawei.com> - 6.2.0-61
* Wed Mar 13 2024 jiangdongxu <jiangdongxu1@huawei.com> - 6.2.0-62
- vdpa: Release pci slot address when unplugging vdpa device
- vdpa: return pcieFlags when calculate vdpa passthrough devices.
* Wed Nov 29 2023 Jiabo Feng <fengjiabo1@huawei.com> - 6.2.0-60
* Wed Nov 29 2023 Jiabo Feng <fengjiabo1@huawei.com> - 6.2.0-61
- vdpa: support vdpa device migrate
- vdpa: support vdpa device hot plug/unplug
- vdpa: Introduce the new device type vdpa to hostdev
@ -2271,6 +2339,9 @@ exit 0
- esx: call freeaddrinfo earlier in esxUtil_ResolveHostname Call freeaddrinfo() as soon as @result is not needed anymore, i.e. right after getnameinfo(); this avoids calling freeaddrinfo() in two branches.
- qemu: Fix incorrect command name in error messages
* Tue Sep 12 2023 lixianglai <lixianglai@loongson.cn> - 6.2.0-60
- Fixed loongarch qxl device not displaying during startup phase
- Synchronize upstream patches "Use correct tpm device for all non-x86"
* Wed Aug 9 2023 Jiabo Feng <fengjiabo1@huawei.com> - 6.2.0-59
- virnetsshsession: Adapt to change libssh2 API

View File

@ -0,0 +1,56 @@
From 03df55a833efbf60200e2617d285b54afa916325 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hyman=20Huang=28=E9=BB=84=E5=8B=87=29?=
<huangy81@chinatelecom.cn>
Date: Tue, 23 Nov 2021 09:36:59 -0500
Subject: [PATCH] qemu: Generate command line for dirty-ring-size
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
On QEMU command line it's represented by the dirty-ring-size
attribute of KVM accelerator.
Signed-off-by: Hyman Huang(榛勫媷) <huangy81@chinatelecom.cn>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Shaokun Wei <weishaokun@kylinos.cn>
---
src/qemu/qemu_command.c | 9 +++++++++
tests/qemuxml2argvdata/kvm-features.args | 2 +-
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index b879f7f39a..9fcea9d46a 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -7295,6 +7295,15 @@ qemuBuildAccelCommandLine(virCommand *cmd,
case VIR_DOMAIN_VIRT_KVM:
virBufferAddLit(&buf, "kvm");
+ /*
+ * only handle the kvm case, tcg case use the legacy style
+ * not that either kvm or tcg can be specified by libvirt
+ * so do not worry about the conflict of specifying both
+ * */
+ if (def->features[VIR_DOMAIN_FEATURE_KVM] == VIR_TRISTATE_SWITCH_ON &&
+ def->kvm_features->features[VIR_DOMAIN_KVM_DIRTY_RING] == VIR_TRISTATE_SWITCH_ON) {
+ virBufferAsprintf(&buf, ",dirty-ring-size=%d", def->kvm_features->dirty_ring_size);
+ }
break;
case VIR_DOMAIN_VIRT_KQEMU:
diff --git a/tests/qemuxml2argvdata/kvm-features.args b/tests/qemuxml2argvdata/kvm-features.args
index 07ab9d5224..d70f0d4846 100644
--- a/tests/qemuxml2argvdata/kvm-features.args
+++ b/tests/qemuxml2argvdata/kvm-features.args
@@ -11,7 +11,7 @@ QEMU_AUDIO_DRV=none \
-name QEMUGuest1 \
-S \
-machine pc,usb=off,dump-guest-core=off \
--accel kvm \
+-accel kvm,dirty-ring-size=4096 \
-cpu host,kvm=off,kvm-hint-dedicated=on \
-m 214 \
-realtime mlock=off \
--
2.27.0

View File

@ -0,0 +1,55 @@
From e69e8b9da6483cb4646869e47d6b808a30f49be4 Mon Sep 17 00:00:00 2001
From: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
Date: Thu, 16 Mar 2023 02:54:16 +0000
Subject: [PATCH] qemu: avoid deadlock in qemuDomainObjStopWorker We are
dropping the only reference here so that the event loop thread is going to be
exited synchronously. In order to avoid deadlocks we need to unlock the VM so
that any handler being called can finish execution and thus even loop thread
be finished too.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy@virtuozzo.com>
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: tangbin <tangbin_yewu@cmss.chinamobile.com>
(cherry-pick from 860a999802d3c82538373bb3f314f92a2e258754)
---
src/qemu/qemu_domain.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 70835e4efd..746adff3f1 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -2192,11 +2192,21 @@ void
qemuDomainObjStopWorker(virDomainObjPtr dom)
{
qemuDomainObjPrivatePtr priv = dom->privateData;
+ virEventThread *eventThread;
- if (priv->eventThread) {
- g_object_unref(priv->eventThread);
- priv->eventThread = NULL;
- }
+ if (!priv->eventThread)
+ return;
+
+ /*
+ * We are dropping the only reference here so that the event loop thread
+ * is going to be exited synchronously. In order to avoid deadlocks we
+ * need to unlock the VM so that any handler being called can finish
+ * execution and thus even loop thread be finished too.
+ */
+ eventThread = g_steal_pointer(&priv->eventThread);
+ virObjectUnlock(dom);
+ g_object_unref(eventThread);
+ virObjectLock(dom);
}
--
2.27.0

View File

@ -0,0 +1,32 @@
From 4127f2c1599683af1de75574065f1942eea9ad88 Mon Sep 17 00:00:00 2001
From: Cole Robinson <crobinso@redhat.com>
Date: Sat, 18 Jun 2022 12:46:03 -0400
Subject: [PATCH] qemu: command: Use correct tpm device for all non-x86
The qemu `tpm-tis` device is an ISA device, so only really applicable
to x86 archs. For all non-x86 archs we should use `tpm-tis-device`
This fixes tpm-tis usage on armv7l and riscv
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Signed-off-by: Cole Robinson <crobinso@redhat.com>
---
src/qemu/qemu_command.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index dc7fb871e7..832c17b602 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -9311,7 +9311,7 @@ qemuBuildTPMDevStr(const virDomainDef *def,
virDomainTPMDef *tpm = def->tpm;
const char *model = virDomainTPMModelTypeToString(tpm->model);
- if (tpm->model == VIR_DOMAIN_TPM_MODEL_TIS && def->os.arch == VIR_ARCH_AARCH64)
+ if (tpm->model == VIR_DOMAIN_TPM_MODEL_TIS && !ARCH_IS_X86(def->os.arch))
model = "tpm-tis-device";
virBufferAsprintf(&buf, "%s,tpmdev=tpm-%s,id=%s",
--
2.27.0

View File

@ -0,0 +1,36 @@
From 90b6a01fe7433e7d5ee3fc2e5eac334e2905fed9 Mon Sep 17 00:00:00 2001
From: ikarosYuuki <tujipei@huawei.com>
Date: Tue, 9 Jul 2024 22:03:05 +0800
Subject: [PATCH] qemu: enable overcommit_memory while start cvm In case of
asymmetric memory numa, starting cvm with huge memory might be prevented by
host kernel because of non-secure memory smaller than secure memory in the
same numa. Ensuring the normal launch of cvm, libvirt need to enable
overcommit_memory feature by writing the 1 to overcommit_memory system file.
Signed-off-by: ikarosYuuki <tujipei@huawei.com>
---
src/qemu/qemu_driver.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 1e3f63a39a..823ffbc673 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7424,6 +7424,14 @@ qemuDomainObjStart(virConnectPtr conn,
}
}
+ if (vm->def->cvm) {
+ if (virFileWriteStr("/proc/sys/vm/overcommit_memory", "1", 0)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Failed to enable overcommit_memory"));
+ return -1;
+ }
+ }
+
ret = qemuProcessStart(conn, driver, vm, NULL, asyncJob,
NULL, -1, NULL, NULL,
VIR_NETDEV_VPORT_PROFILE_OP_CREATE, start_flags);
--
2.31.1.windows.1

View File

@ -0,0 +1,254 @@
From 24a179c25897dbfaa015ff62940648877d9d50ef Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hyman=20Huang=28=E9=BB=84=E5=8B=87=29?=
<huangy81@chinatelecom.cn>
Date: Tue, 23 Nov 2021 09:36:58 -0500
Subject: [PATCH] qemu: support dirty ring feature
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Dirty ring feature was introduced in qemu-6.1.0, this patch
add the corresponding feature named 'dirty-ring', which enable
dirty ring feature when starting VM.
To enable the feature, the following XML needs to be added to
the guest's domain description:
<features>
<kvm>
<dirty-ring state='on' size='xxx'>
</kvm>
</features>
If property "state=on", property "size" must be specified, which
should be power of 2 and range in [1024, 65526].
Signed-off-by: Hyman Huang(榛勫媷) <huangy81@chinatelecom.cn>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Shaokun Wei <weishaokun@kylinos.cn>
---
docs/formatdomain.html.in | 7 ++++
docs/schemas/domaincommon.rng | 10 +++++
src/conf/domain_conf.c | 42 +++++++++++++++++++
src/conf/domain_conf.h | 3 ++
src/qemu/qemu_command.c | 3 ++
tests/qemuxml2argvdata/kvm-features-off.xml | 1 +
tests/qemuxml2argvdata/kvm-features.xml | 1 +
tests/qemuxml2xmloutdata/kvm-features-off.xml | 1 +
tests/qemuxml2xmloutdata/kvm-features.xml | 1 +
9 files changed, 69 insertions(+)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 6e51c3bac9..0521a847d8 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -2055,6 +2055,7 @@
&lt;kvm&gt;
&lt;hidden state='on'/&gt;
&lt;hint-dedicated state='on'/&gt;
+ &lt;dirty-ring state='on' size='4096'/&gt;
&lt;/kvm&gt;
&lt;pvspinlock state='on'/&gt;
&lt;gic version='2'/&gt;
@@ -2235,6 +2236,12 @@
<td>on, off</td>
<td><span class="since">5.7.0 (QEMU 2.12.0)</span></td>
</tr>
+ <tr>
+ <td>dirty-ring</td>
+ <td>Enable dirty ring feature</td>
+ <td>on, off; size - must be power of 2, range [1024,65536]</td>
+ <td><span class="since">8.0.0 (QEMU 6.1)</span></td>
+ </tr>
</table>
</dd>
<dt><code>pmu</code></dt>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 764f826df4..e3b51d333c 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -6327,6 +6327,16 @@
<ref name="featurestate"/>
</element>
</optional>
+ <optional>
+ <element name="dirty-ring">
+ <ref name="featurestate"/>
+ <optional>
+ <attribute name="size">
+ <data type="unsignedInt"/>
+ </attribute>
+ </optional>
+ </element>
+ </optional>
</interleave>
</element>
</define>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index e94ae4ea17..cf807c7747 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -205,6 +205,7 @@ VIR_ENUM_IMPL(virDomainKVM,
VIR_DOMAIN_KVM_LAST,
"hidden",
"hint-dedicated",
+ "dirty-ring",
);
VIR_ENUM_IMPL(virDomainMsrsUnknown,
@@ -20620,6 +20621,22 @@ virDomainFeaturesKVMDefParse(virDomainDef *def,
kvm->features[feature] = value;
+ /* dirty ring feature should parse size property */
+ if (feature == VIR_DOMAIN_KVM_DIRTY_RING &&
+ value == VIR_TRISTATE_SWITCH_ON) {
+ if (virXMLPropUInt(node, "size", 0, VIR_XML_PROP_REQUIRED,
+ &kvm->dirty_ring_size) < 0) {
+ return -1;
+ }
+ if (!VIR_IS_POW2(kvm->dirty_ring_size) ||
+ kvm->dirty_ring_size < 1024 ||
+ kvm->dirty_ring_size > 65536) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("dirty ring must be power of 2 and ranges [1024, 65536]"));
+ return -1;
+ }
+ }
+
node = xmlNextElementSibling(node);
}
@@ -23590,6 +23607,7 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src,
switch ((virDomainKVM) i) {
case VIR_DOMAIN_KVM_HIDDEN:
case VIR_DOMAIN_KVM_DEDICATED:
+ case VIR_DOMAIN_KVM_DIRTY_RING:
if (src->kvm_features->features[i] != dst->kvm_features->features[i]) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("State of KVM feature '%s' differs: "
@@ -23607,6 +23625,16 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src,
break;
}
}
+
+ if (src->kvm_features->dirty_ring_size != dst->kvm_features->dirty_ring_size) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("dirty ring size of KVM feature '%s' differs: "
+ "source: '%d', destination: '%d'"),
+ virDomainKVMTypeToString(i),
+ src->kvm_features->dirty_ring_size,
+ dst->kvm_features->dirty_ring_size);
+ return false;
+ }
}
/* smm */
@@ -29214,6 +29242,20 @@ virDomainDefFormatFeatures(virBufferPtr buf,
def->kvm_features->features[j]));
break;
+ case VIR_DOMAIN_KVM_DIRTY_RING:
+ if (def->kvm_features->features[j] != VIR_TRISTATE_SWITCH_ABSENT) {
+ virBufferAsprintf(&childBuf, "<%s state='%s'",
+ virDomainKVMTypeToString(j),
+ virTristateSwitchTypeToString(def->kvm_features->features[j]));
+ if (def->kvm_features->dirty_ring_size > 0) {
+ virBufferAsprintf(&childBuf, " size='%d'/>\n",
+ def->kvm_features->dirty_ring_size);
+ } else {
+ virBufferAddLit(&childBuf, "/>\n");
+ }
+ }
+ break;
+
/* coverity[dead_error_begin] */
case VIR_DOMAIN_KVM_LAST:
break;
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index d75d06d7b8..7419bf8d7e 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1840,6 +1840,7 @@ typedef enum {
typedef enum {
VIR_DOMAIN_KVM_HIDDEN = 0,
VIR_DOMAIN_KVM_DEDICATED,
+ VIR_DOMAIN_KVM_DIRTY_RING,
VIR_DOMAIN_KVM_LAST
} virDomainKVM;
@@ -2300,6 +2301,8 @@ struct _virDomainResctrlDef {
typedef struct _virDomainFeatureKVM virDomainFeatureKVM;
struct _virDomainFeatureKVM {
int features[VIR_DOMAIN_KVM_LAST];
+
+ unsigned int dirty_ring_size; /* size of dirty ring for each vCPU, no units */
};
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index ed843315dc..b879f7f39a 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6920,6 +6920,9 @@ qemuBuildCpuCommandLine(virCommandPtr cmd,
virBufferAddLit(&buf, ",kvm-hint-dedicated=on");
break;
+ case VIR_DOMAIN_KVM_DIRTY_RING:
+ break;
+
/* coverity[dead_error_begin] */
case VIR_DOMAIN_KVM_LAST:
break;
diff --git a/tests/qemuxml2argvdata/kvm-features-off.xml b/tests/qemuxml2argvdata/kvm-features-off.xml
index 21d492c8b9..f53e31db6b 100644
--- a/tests/qemuxml2argvdata/kvm-features-off.xml
+++ b/tests/qemuxml2argvdata/kvm-features-off.xml
@@ -13,6 +13,7 @@
<kvm>
<hidden state='off'/>
<hint-dedicated state='off'/>
+ <dirty-ring state='off'/>
</kvm>
</features>
<clock offset='utc'/>
diff --git a/tests/qemuxml2argvdata/kvm-features.xml b/tests/qemuxml2argvdata/kvm-features.xml
index 85f74786c9..fd08a7a0f5 100644
--- a/tests/qemuxml2argvdata/kvm-features.xml
+++ b/tests/qemuxml2argvdata/kvm-features.xml
@@ -13,6 +13,7 @@
<kvm>
<hidden state='on'/>
<hint-dedicated state='on'/>
+ <dirty-ring state='on' size='4096'/>
</kvm>
</features>
<cpu mode='host-passthrough' check='none'/>
diff --git a/tests/qemuxml2xmloutdata/kvm-features-off.xml b/tests/qemuxml2xmloutdata/kvm-features-off.xml
index 9068be3e7b..2c8b6a81d3 100644
--- a/tests/qemuxml2xmloutdata/kvm-features-off.xml
+++ b/tests/qemuxml2xmloutdata/kvm-features-off.xml
@@ -13,6 +13,7 @@
<kvm>
<hidden state='off'/>
<hint-dedicated state='off'/>
+ <dirty-ring state='off'/>
</kvm>
</features>
<clock offset='utc'/>
diff --git a/tests/qemuxml2xmloutdata/kvm-features.xml b/tests/qemuxml2xmloutdata/kvm-features.xml
index 7c554671b3..6e97065fed 100644
--- a/tests/qemuxml2xmloutdata/kvm-features.xml
+++ b/tests/qemuxml2xmloutdata/kvm-features.xml
@@ -13,6 +13,7 @@
<kvm>
<hidden state='on'/>
<hint-dedicated state='on'/>
+ <dirty-ring state='on' size='4096'/>
</kvm>
</features>
<cpu mode='host-passthrough' check='none'/>
--
2.27.0

View File

@ -0,0 +1,184 @@
From e2db7dec8f43ac5ba8eb518a4d6cb6d58f9dee60 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hyman=20Huang=28=E9=BB=84=E5=8B=87=29?=
<huangy81@chinatelecom.cn>
Date: Sun, 20 Feb 2022 21:28:15 +0800
Subject: [PATCH] qemu_driver: Add calc_mode for dirtyrate statistics
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Add calc_mode for dirtyrate statistics retured by
virsh domstats --dirtyrate api, also add vcpu dirtyrate
if dirty-ring mode was used in last measurement.
Signed-off-by: Hyman Huang(榛勫媷) <huangy81@chinatelecom.cn>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Shaokun Wei <weishaokun@kylinos.cn>
---
src/libvirt-domain.c | 6 ++++
src/qemu/qemu_driver.c | 22 +++++++++++++--
src/qemu/qemu_monitor.h | 10 +++++++
src/qemu/qemu_monitor_json.c | 53 ++++++++++++++++++++++++++++++++++++
4 files changed, 88 insertions(+), 3 deletions(-)
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index 8f6ff2fe22..d2b2c89353 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -11697,6 +11697,12 @@ virConnectGetDomainCapabilities(virConnectPtr conn,
* "dirtyrate.megabytes_per_second" - the calculated memory dirty rate in
* MiB/s as long long. It is produced
* only if the calc_status is measured.
+ * "dirtyrate.calc_mode" - the calculation mode used last measurement, either
+ * of these 3 'page-sampling,dirty-bitmap,dirty-ring'
+ * values returned.
+ * "dirtyrate.vcpu.<num>.megabytes_per_second" - the calculated memory dirty
+ * rate for a virtual cpu as
+ * unsigned long long.
*
* Note that entire stats groups or individual stat fields may be missing from
* the output in case they are not supported by the given hypervisor, are not
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 9cb14b01ad..77a139c66b 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -21723,11 +21723,27 @@ qemuDomainGetStatsDirtyRate(virQEMUDriverPtr driver,
"dirtyrate.calc_period") < 0)
return -1;
- if ((info.status == VIR_DOMAIN_DIRTYRATE_MEASURED) &&
- virTypedParamListAddLLong(params, info.dirtyRate,
- "dirtyrate.megabytes_per_second") < 0)
+ if (virTypedParamListAddString(params,
+ qemuMonitorDirtyRateCalcModeTypeToString(info.mode),
+ "dirtyrate.calc_mode") < 0)
return -1;
+ if (info.status == VIR_DOMAIN_DIRTYRATE_MEASURED) {
+ if (virTypedParamListAddLLong(params, info.dirtyRate,
+ "dirtyrate.megabytes_per_second") < 0)
+ return -1;
+
+ if (info.mode == QEMU_MONITOR_DIRTYRATE_CALC_MODE_DIRTY_RING) {
+ size_t i;
+ for (i = 0; i < info.nvcpus; i++) {
+ if (virTypedParamListAddULLong(params, info.rates[i].value,
+ "dirtyrate.vcpu.%d.megabytes_per_second",
+ info.rates[i].idx) < 0)
+ return -1;
+ }
+ }
+ }
+
return 0;
}
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 1c6b001872..949a04f60f 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1464,6 +1464,12 @@ qemuMonitorStartDirtyRateCalc(qemuMonitorPtr mon,
int seconds,
qemuMonitorDirtyRateCalcMode mode);
+typedef struct _qemuMonitorDirtyRateVcpu qemuMonitorDirtyRateVcpu;
+struct _qemuMonitorDirtyRateVcpu {
+ int idx; /* virtual cpu index */
+ unsigned long long value; /* virtual cpu dirty page rate in MB/s */
+};
+
typedef struct _qemuMonitorDirtyRateInfo qemuMonitorDirtyRateInfo;
typedef qemuMonitorDirtyRateInfo *qemuMonitorDirtyRateInfoPtr;
@@ -1473,6 +1479,10 @@ struct _qemuMonitorDirtyRateInfo {
int calcTime; /* the period of dirtyrate calculation */
long long startTime; /* the start time of dirtyrate calculation */
long long dirtyRate; /* the dirtyrate in MiB/s */
+ qemuMonitorDirtyRateCalcMode mode; /* calculation mode used in
+ last measurement */
+ size_t nvcpus; /* number of virtual cpu */
+ qemuMonitorDirtyRateVcpu *rates; /* array of dirty page rate */
};
int
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 8f040bbe59..e7134d90b6 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -9450,12 +9450,46 @@ VIR_ENUM_IMPL(qemuMonitorDirtyRateStatus,
"measuring",
"measured");
+static int
+qemuMonitorJSONExtractVcpuDirtyRate(virJSONValue *data,
+ qemuMonitorDirtyRateInfo *info)
+{
+ size_t nvcpus;
+ size_t i;
+
+ nvcpus = virJSONValueArraySize(data);
+ info->nvcpus = nvcpus;
+ info->rates = g_new0(qemuMonitorDirtyRateVcpu, nvcpus);
+
+ for (i = 0; i < nvcpus; i++) {
+ virJSONValue *entry = virJSONValueArrayGet(data, i);
+ if (virJSONValueObjectGetNumberInt(entry, "id",
+ &info->rates[i].idx) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("query-dirty-rate reply was missing 'id' data"));
+ return -1;
+ }
+
+ if (virJSONValueObjectGetNumberUlong(entry, "dirty-rate",
+ &info->rates[i].value) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("query-dirty-rate reply was missing 'dirty-rate' data"));
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
static int
qemuMonitorJSONExtractDirtyRateInfo(virJSONValuePtr data,
qemuMonitorDirtyRateInfoPtr info)
{
const char *statusstr;
+ const char *modestr;
int status;
+ int mode;
+ virJSONValue *rates = NULL;
if (!(statusstr = virJSONValueObjectGetString(data, "status"))) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -9492,6 +9526,25 @@ qemuMonitorJSONExtractDirtyRateInfo(virJSONValuePtr data,
return -1;
}
+ if ((modestr = virJSONValueObjectGetString(data, "mode"))) {
+ if ((mode = qemuMonitorDirtyRateCalcModeTypeFromString(modestr)) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Unknown dirty page rate calculation mode: %s"), modestr);
+ return -1;
+ }
+ info->mode = mode;
+ } else {
+ info->mode = QEMU_MONITOR_DIRTYRATE_CALC_MODE_PAGE_SAMPLING;
+ }
+
+ if ((rates = virJSONValueObjectGetArray(data, "vcpu-dirty-rate"))) {
+ if (qemuMonitorJSONExtractVcpuDirtyRate(rates, info) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("query-dirty-rate parsing 'vcpu-dirty-rate' in failure"));
+ return -1;
+ }
+ }
+
return 0;
}
--
2.27.0

View File

@ -0,0 +1,58 @@
From 15746790ca62e46aa68e8a79c51a15bbf9b3d1ab Mon Sep 17 00:00:00 2001
From: Tim Wiederhake <twiederh@redhat.com>
Date: Fri, 19 Feb 2021 10:54:00 +0100
Subject: [PATCH] qemu_validate: Allow kvm hint-dedicated on non-passthrough
VMs
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
A VM defined similar to:
...
<features><kvm><hint-dedicated state='on'/></kvm></features>
<cpu mode="host-model"/>
...
is currently invalid, as hint-dedicated is only allowed if cpu mode
is host-passthrough or maximum. This restriction is unnecessary, see
https://bugzilla.redhat.com/show_bug.cgi?id=1857671
Signed-off-by: Tim Wiederhake <twiederh@redhat.com>
Reviewed-by: J谩n Tomko <jtomko@redhat.com>
Signed-off-by: J谩n Tomko <jtomko@redhat.com>
Reviewed-by: Shaokun Wei <weishaokun@kylinos.cn>
---
src/qemu/qemu_domain.c | 11 +----------
1 file changed, 1 insertion(+), 10 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index fd3e3f64c0..537411a711 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -5251,16 +5251,6 @@ qemuDomainDefValidateFeatures(const virDomainDef *def,
}
break;
- case VIR_DOMAIN_FEATURE_KVM:
- if (def->kvm_features[VIR_DOMAIN_KVM_DEDICATED] == VIR_TRISTATE_SWITCH_ON &&
- (!def->cpu || def->cpu->mode != VIR_CPU_MODE_HOST_PASSTHROUGH)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("kvm-hint-dedicated=on is only applicable "
- "for cpu host-passthrough"));
- return -1;
- }
- break;
-
case VIR_DOMAIN_FEATURE_VMPORT:
if (def->features[i] != VIR_TRISTATE_SWITCH_ABSENT &&
!virQEMUCapsSupportsVmport(qemuCaps, def)) {
@@ -5333,6 +5323,7 @@ qemuDomainDefValidateFeatures(const virDomainDef *def,
}
break;
+ case VIR_DOMAIN_FEATURE_KVM:
case VIR_DOMAIN_FEATURE_ACPI:
case VIR_DOMAIN_FEATURE_PAE:
case VIR_DOMAIN_FEATURE_HAP:
--
2.27.0

View File

@ -0,0 +1,88 @@
From cec0f6ad7c8de43ec16d200b437533111f991c82 Mon Sep 17 00:00:00 2001
From: wangmeiyang <wangmeiyang@xfusion.com>
Date: Fri, 21 Apr 2023 14:22:52 +0800
Subject: [PATCH] remote: fix double free of migration params on error
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The remote_*_args methods will generally borrow pointers
passed in the caller, so should not be freed.
On failure of the virTypedParamsSerialize method, however,
xdr_free was being called. This is presumably because it
was thought that the params may have been partially
serialized and need cleaning up. This is incorrect, as
virTypedParamsSerialize takes care to cleanup partially
serialized data. This xdr_free call would lead to free'ing
the borrowed cookie pointers, which would be a double free.
origin commit: https://gitlab.com/libvirt/libvirt/-/commit/2b5f9251129d61cfc6cffa63d367af27850602a4
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
Signed-off-by: Daniel P. Berrang¨¦ <berrange@redhat.com>
Signed-off-by: Meiyang Wang <wangmeiyang@xfusion.com>
---
src/remote/remote_driver.c | 12 ------------
1 file changed, 12 deletions(-)
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 9c272b4ff8..fb34b1e727 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -7067,8 +7067,6 @@ remoteDomainMigrateBegin3Params(virDomainPtr domain,
(virTypedParameterRemotePtr *) &args.params.params_val,
&args.params.params_len,
VIR_TYPED_PARAM_STRING_OKAY) < 0) {
- xdr_free((xdrproc_t) xdr_remote_domain_migrate_begin3_params_args,
- (char *) &args);
goto cleanup;
}
@@ -7129,8 +7127,6 @@ remoteDomainMigratePrepare3Params(virConnectPtr dconn,
(virTypedParameterRemotePtr *) &args.params.params_val,
&args.params.params_len,
VIR_TYPED_PARAM_STRING_OKAY) < 0) {
- xdr_free((xdrproc_t) xdr_remote_domain_migrate_prepare3_params_args,
- (char *) &args);
goto cleanup;
}
@@ -7211,8 +7207,6 @@ remoteDomainMigratePrepareTunnel3Params(virConnectPtr dconn,
(virTypedParameterRemotePtr *) &args.params.params_val,
&args.params.params_len,
VIR_TYPED_PARAM_STRING_OKAY) < 0) {
- xdr_free((xdrproc_t) xdr_remote_domain_migrate_prepare_tunnel3_params_args,
- (char *) &args);
goto cleanup;
}
@@ -7297,8 +7291,6 @@ remoteDomainMigratePerform3Params(virDomainPtr dom,
(virTypedParameterRemotePtr *) &args.params.params_val,
&args.params.params_len,
VIR_TYPED_PARAM_STRING_OKAY) < 0) {
- xdr_free((xdrproc_t) xdr_remote_domain_migrate_perform3_params_args,
- (char *) &args);
goto cleanup;
}
@@ -7364,8 +7356,6 @@ remoteDomainMigrateFinish3Params(virConnectPtr dconn,
(virTypedParameterRemotePtr *) &args.params.params_val,
&args.params.params_len,
VIR_TYPED_PARAM_STRING_OKAY) < 0) {
- xdr_free((xdrproc_t) xdr_remote_domain_migrate_finish3_params_args,
- (char *) &args);
goto cleanup;
}
@@ -7433,8 +7423,6 @@ remoteDomainMigrateConfirm3Params(virDomainPtr domain,
(virTypedParameterRemotePtr *) &args.params.params_val,
&args.params.params_len,
VIR_TYPED_PARAM_STRING_OKAY) < 0) {
- xdr_free((xdrproc_t) xdr_remote_domain_migrate_confirm3_params_args,
- (char *) &args);
goto cleanup;
}
--
2.27.0

View File

@ -0,0 +1,94 @@
From 351dc443b1c6718b999cc40250ef0b210bcef118 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Tue, 30 Apr 2024 11:51:15 +0100
Subject: [PATCH 3/3] rpc: ensure temporary GSource is removed from client
event loop
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
==238721==ERROR: AddressSanitizer: stack-use-after-return on address 0x75cd18709788 at pc 0x75cd3111f907 bp 0x75cd181ff550 sp 0x75cd181ff548
WRITE of size 4 at 0x75cd18709788 thread T11
#0 0x75cd3111f906 in virNetClientIOEventFD /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/rpc/virnetclient.c:1634:15
#1 0x75cd3210d198 (/usr/lib/libglib-2.0.so.0+0x5a198) (BuildId: 0a2311dfbbc6c215dc36f4b6bdd2b4b6fbae55a2)
#2 0x75cd3216c3be (/usr/lib/libglib-2.0.so.0+0xb93be) (BuildId: 0a2311dfbbc6c215dc36f4b6bdd2b4b6fbae55a2)
#3 0x75cd3210ddc6 in g_main_loop_run (/usr/lib/libglib-2.0.so.0+0x5adc6) (BuildId: 0a2311dfbbc6c215dc36f4b6bdd2b4b6fbae55a2)
#4 0x75cd3111a47c in virNetClientIOEventLoop /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/rpc/virnetclient.c:1722:9
#5 0x75cd3111a47c in virNetClientIO /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/rpc/virnetclient.c:2002:10
#6 0x75cd3111a47c in virNetClientSendInternal /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/rpc/virnetclient.c:2170:11
#7 0x75cd311198a8 in virNetClientSendWithReply /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/rpc/virnetclient.c:2198:11
#8 0x75cd31111653 in virNetClientProgramCall /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/rpc/virnetclientprogram.c:318:9
#9 0x75cd31241c8f in callFull /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/remote/remote_driver.c:6054:10
#10 0x75cd31241c8f in call /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/remote/remote_driver.c:6076:12
#11 0x75cd31241c8f in remoteNetworkGetXMLDesc /usr/src/debug/libvirt/libvirt-10.2.0/build/src/remote/remote_client_bodies.h:5959:9
#12 0x75cd31410ff7 in virNetworkGetXMLDesc /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/libvirt-network.c:952:15
The root cause is a bad assumption in the virNetClientIOEventLoop
method. This method is run by whichever thread currently owns the
buck, and is responsible for handling I/O. Inside a for(;;) loop,
this method creates a temporary GSource, adds it to the event loop
and runs g_main_loop_run(). When I/O is ready, the GSource callback
(virNetClientIOEventFD) will fire and call g_main_loop_quit(), and
return G_SOURCE_REMOVE which results in the temporary GSource being
destroyed. A g_autoptr() will then remove the last reference.
What was overlooked, is that a second thread can come along and
while it can't enter virNetClientIOEventLoop, it will register an
idle source that uses virNetClientIOWakeup to interrupt the
original thread's 'g_main_loop_run' call. When this happens the
virNetClientIOEventFD callback never runs, and so the temporary
GSource is not destroyed. The g_autoptr() will remove a reference,
but by virtue of still being attached to the event context, there
is an extra reference held causing GSource to be leaked. The
next time 'g_main_loop_run' is called, the original GSource will
trigger its callback, and access data that was allocated on the
stack by the previous thread, and likely SEGV.
To solve this, the thread calling 'g_main_loop_run' must call
g_source_destroy, immediately upon return, to guarantee that
the temporary GSource is removed.
CVE-2024-4418
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Reported-by: Martin Shirokov <shirokovmartin@gmail.com>
Tested-by: Martin Shirokov <shirokovmartin@gmail.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
src/rpc/virnetclient.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c
index f4bb537d50..969c624ae5 100644
--- a/src/rpc/virnetclient.c
+++ b/src/rpc/virnetclient.c
@@ -1619,7 +1619,7 @@ static int virNetClientIOEventLoop(virNetClientPtr client,
#endif /* !WIN32 */
int timeout = -1;
virNetMessagePtr msg = NULL;
- g_autoptr(GSource) G_GNUC_UNUSED source = NULL;
+ g_autoptr(GSource) source = NULL;
GIOCondition ev = 0;
struct virNetClientIOEventData data = {
.client = client,
@@ -1683,6 +1683,18 @@ static int virNetClientIOEventLoop(virNetClientPtr client,
g_main_loop_run(client->eventLoop);
+ /*
+ * If virNetClientIOEventFD ran, this GSource will already be
+ * destroyed due to G_SOURCE_REMOVE. It is harmless to re-destroy
+ * it, since we still own a reference.
+ *
+ * If virNetClientIOWakeup ran, it will have interrupted the
+ * g_main_loop_run call, before virNetClientIOEventFD could
+ * run, and thus the GSource is still registered, and we need
+ * to destroy it since it is referencing stack memory for 'data'
+ */
+ g_source_destroy(source);
+
#ifndef WIN32
ignore_value(pthread_sigmask(SIG_SETMASK, &oldmask, NULL));
#endif /* !WIN32 */
--
2.33.0

View File

@ -0,0 +1,57 @@
From 5ab53ff977e17d20b0bf01010f2c3168781a659e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
Date: Fri, 3 Sep 2021 16:36:54 +0200
Subject: [PATCH 2/3] rpc: mark source returned by virEventGLibAddSocketWatch
as unused
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Two users of virEventGLibAddSocketWatch care about the GSource
it returns.
The other three free it by assigning it to an autofreed variable.
Mark them with G_GNUC_UNUSED to make this obvious to the reader
and the compiler.
Signed-off-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
---
src/rpc/virnetclient.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c
index 0a413f0153..f4bb537d50 100644
--- a/src/rpc/virnetclient.c
+++ b/src/rpc/virnetclient.c
@@ -826,7 +826,7 @@ virNetClientIOEventTLS(int fd,
static gboolean
virNetClientTLSHandshake(virNetClientPtr client)
{
- g_autoptr(GSource) source = NULL;
+ g_autoptr(GSource) G_GNUC_UNUSED source = NULL;
GIOCondition ev;
int ret;
@@ -883,7 +883,7 @@ int virNetClientSetTLSSession(virNetClientPtr client,
int ret;
char buf[1];
int len;
- g_autoptr(GSource) source = NULL;
+ g_autoptr(GSource) G_GNUC_UNUSED source = NULL;
#ifndef WIN32
sigset_t oldmask, blockedsigs;
@@ -1619,7 +1619,7 @@ static int virNetClientIOEventLoop(virNetClientPtr client,
#endif /* !WIN32 */
int timeout = -1;
virNetMessagePtr msg = NULL;
- g_autoptr(GSource) source = NULL;
+ g_autoptr(GSource) G_GNUC_UNUSED source = NULL;
GIOCondition ev = 0;
struct virNetClientIOEventData data = {
.client = client,
--
2.33.0

View File

@ -0,0 +1,303 @@
From 4160ede0261dfccd8156721a22fa48d9cd3c448a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Tue, 28 Jul 2020 15:54:13 +0100
Subject: [PATCH 1/3] util: keep track of full GSource object not source ID
number
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The source ID number is an alternative way to identify a source that has
been added to a GMainContext. Internally when a source ID is given, glib
will lookup the corresponding GSource and use that. The use of a source
ID is racy in some cases though, because it is invalid to continue to
use an ID number after the GSource has been removed. It is thus safer
to use the GSource object directly and have full control over the ref
counting and thus cleanup.
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
src/rpc/virnetclient.c | 27 +++++++------
src/util/vireventglib.c | 73 +++++++++++++++++++++++-------------
src/util/vireventglibwatch.c | 19 ++++++----
src/util/vireventglibwatch.h | 13 ++++---
4 files changed, 79 insertions(+), 53 deletions(-)
diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c
index 1c5bef86a1..0a413f0153 100644
--- a/src/rpc/virnetclient.c
+++ b/src/rpc/virnetclient.c
@@ -826,6 +826,7 @@ virNetClientIOEventTLS(int fd,
static gboolean
virNetClientTLSHandshake(virNetClientPtr client)
{
+ g_autoptr(GSource) source = NULL;
GIOCondition ev;
int ret;
@@ -840,10 +841,10 @@ virNetClientTLSHandshake(virNetClientPtr client)
else
ev = G_IO_OUT;
- virEventGLibAddSocketWatch(virNetSocketGetFD(client->sock),
- ev,
- client->eventCtx,
- virNetClientIOEventTLS, client, NULL);
+ source = virEventGLibAddSocketWatch(virNetSocketGetFD(client->sock),
+ ev,
+ client->eventCtx,
+ virNetClientIOEventTLS, client, NULL);
return TRUE;
}
@@ -882,6 +883,7 @@ int virNetClientSetTLSSession(virNetClientPtr client,
int ret;
char buf[1];
int len;
+ g_autoptr(GSource) source = NULL;
#ifndef WIN32
sigset_t oldmask, blockedsigs;
@@ -934,10 +936,10 @@ int virNetClientSetTLSSession(virNetClientPtr client,
* etc. If we make the grade, it will send us a '\1' byte.
*/
- virEventGLibAddSocketWatch(virNetSocketGetFD(client->sock),
- G_IO_IN,
- client->eventCtx,
- virNetClientIOEventTLSConfirm, client, NULL);
+ source = virEventGLibAddSocketWatch(virNetSocketGetFD(client->sock),
+ G_IO_IN,
+ client->eventCtx,
+ virNetClientIOEventTLSConfirm, client, NULL);
#ifndef WIN32
/* Block SIGWINCH from interrupting poll in curses programs */
@@ -1617,6 +1619,7 @@ static int virNetClientIOEventLoop(virNetClientPtr client,
#endif /* !WIN32 */
int timeout = -1;
virNetMessagePtr msg = NULL;
+ g_autoptr(GSource) source = NULL;
GIOCondition ev = 0;
struct virNetClientIOEventData data = {
.client = client,
@@ -1651,10 +1654,10 @@ static int virNetClientIOEventLoop(virNetClientPtr client,
if (client->nstreams)
ev |= G_IO_IN;
- virEventGLibAddSocketWatch(virNetSocketGetFD(client->sock),
- ev,
- client->eventCtx,
- virNetClientIOEventFD, &data, NULL);
+ source = virEventGLibAddSocketWatch(virNetSocketGetFD(client->sock),
+ ev,
+ client->eventCtx,
+ virNetClientIOEventFD, &data, NULL);
/* Release lock while poll'ing so other threads
* can stuff themselves on the queue */
diff --git a/src/util/vireventglib.c b/src/util/vireventglib.c
index 803332a6f8..6e334b3398 100644
--- a/src/util/vireventglib.c
+++ b/src/util/vireventglib.c
@@ -45,7 +45,7 @@ struct virEventGLibHandle
int fd;
int events;
int removed;
- guint source;
+ GSource *source;
virEventHandleCallback cb;
void *opaque;
virFreeCallback ff;
@@ -56,7 +56,7 @@ struct virEventGLibTimeout
int timer;
int interval;
int removed;
- guint source;
+ GSource *source;
virEventTimeoutCallback cb;
void *opaque;
virFreeCallback ff;
@@ -210,23 +210,25 @@ virEventGLibHandleUpdate(int watch,
if (events == data->events)
goto cleanup;
- if (data->source != 0) {
- VIR_DEBUG("Removed old handle watch=%d", data->source);
- g_source_remove(data->source);
+ if (data->source != NULL) {
+ VIR_DEBUG("Removed old handle source=%p", data->source);
+ g_source_destroy(data->source);
+ g_source_unref(data->source);
}
data->source = virEventGLibAddSocketWatch(
data->fd, cond, NULL, virEventGLibHandleDispatch, data, NULL);
data->events = events;
- VIR_DEBUG("Added new handle watch=%d", data->source);
+ VIR_DEBUG("Added new handle source=%p", data->source);
} else {
- if (data->source == 0)
+ if (data->source == NULL)
goto cleanup;
- VIR_DEBUG("Removed old handle watch=%d", data->source);
- g_source_remove(data->source);
- data->source = 0;
+ VIR_DEBUG("Removed old handle source=%p", data->source);
+ g_source_destroy(data->source);
+ g_source_unref(data->source);
+ data->source = NULL;
data->events = 0;
}
@@ -272,9 +274,10 @@ virEventGLibHandleRemove(int watch)
VIR_DEBUG("Remove handle data=%p watch=%d fd=%d",
data, watch, data->fd);
- if (data->source != 0) {
- g_source_remove(data->source);
- data->source = 0;
+ if (data->source != NULL) {
+ g_source_destroy(data->source);
+ g_source_unref(data->source);
+ data->source = NULL;
data->events = 0;
}
@@ -309,6 +312,22 @@ virEventGLibTimeoutDispatch(void *opaque)
return TRUE;
}
+
+static GSource *
+virEventGLibTimeoutCreate(int interval,
+ struct virEventGLibTimeout *data)
+{
+ GSource *source = g_timeout_source_new(interval);
+
+ g_source_set_callback(source,
+ virEventGLibTimeoutDispatch,
+ data, NULL);
+ g_source_attach(source, NULL);
+
+ return source;
+}
+
+
static int
virEventGLibTimeoutAdd(int interval,
virEventTimeoutCallback cb,
@@ -327,9 +346,7 @@ virEventGLibTimeoutAdd(int interval,
data->opaque = opaque;
data->ff = ff;
if (interval >= 0)
- data->source = g_timeout_add(interval,
- virEventGLibTimeoutDispatch,
- data);
+ data->source = virEventGLibTimeoutCreate(interval, data);
g_ptr_array_add(timeouts, data);
@@ -390,19 +407,20 @@ virEventGLibTimeoutUpdate(int timer,
VIR_DEBUG("Update timeout data=%p timer=%d interval=%d ms", data, timer, interval);
if (interval >= 0) {
- if (data->source != 0)
- g_source_remove(data->source);
+ if (data->source != NULL) {
+ g_source_destroy(data->source);
+ g_source_unref(data->source);
+ }
data->interval = interval;
- data->source = g_timeout_add(data->interval,
- virEventGLibTimeoutDispatch,
- data);
+ data->source = virEventGLibTimeoutCreate(interval, data);
} else {
- if (data->source == 0)
+ if (data->source == NULL)
goto cleanup;
- g_source_remove(data->source);
- data->source = 0;
+ g_source_destroy(data->source);
+ g_source_unref(data->source);
+ data->source = NULL;
}
cleanup:
@@ -448,9 +466,10 @@ virEventGLibTimeoutRemove(int timer)
VIR_DEBUG("Remove timeout data=%p timer=%d",
data, timer);
- if (data->source != 0) {
- g_source_remove(data->source);
- data->source = 0;
+ if (data->source != NULL) {
+ g_source_destroy(data->source);
+ g_source_unref(data->source);
+ data->source = NULL;
}
/* since the actual timeout deletion is done asynchronously, a timeoutUpdate call may
diff --git a/src/util/vireventglibwatch.c b/src/util/vireventglibwatch.c
index 178707f6b7..b7f3a8786a 100644
--- a/src/util/vireventglibwatch.c
+++ b/src/util/vireventglibwatch.c
@@ -233,17 +233,20 @@ GSource *virEventGLibCreateSocketWatch(int fd,
#endif /* WIN32 */
-guint virEventGLibAddSocketWatch(int fd,
- GIOCondition condition,
- GMainContext *context,
- virEventGLibSocketFunc func,
- gpointer opaque,
- GDestroyNotify notify)
+GSource *
+virEventGLibAddSocketWatch(int fd,
+ GIOCondition condition,
+ GMainContext *context,
+ virEventGLibSocketFunc func,
+ gpointer opaque,
+ GDestroyNotify notify)
{
- g_autoptr(GSource) source = NULL;
+ GSource *source = NULL;
source = virEventGLibCreateSocketWatch(fd, condition);
g_source_set_callback(source, (GSourceFunc)func, opaque, notify);
- return g_source_attach(source, context);
+ g_source_attach(source, context);
+
+ return source;
}
diff --git a/src/util/vireventglibwatch.h b/src/util/vireventglibwatch.h
index 2f7e61cfba..f57be1f503 100644
--- a/src/util/vireventglibwatch.h
+++ b/src/util/vireventglibwatch.h
@@ -40,9 +40,10 @@ typedef gboolean (*virEventGLibSocketFunc)(int fd,
GIOCondition condition,
gpointer data);
-guint virEventGLibAddSocketWatch(int fd,
- GIOCondition condition,
- GMainContext *context,
- virEventGLibSocketFunc func,
- gpointer opaque,
- GDestroyNotify notify);
+GSource *virEventGLibAddSocketWatch(int fd,
+ GIOCondition condition,
+ GMainContext *context,
+ virEventGLibSocketFunc func,
+ gpointer opaque,
+ GDestroyNotify notify)
+ G_GNUC_WARN_UNUSED_RESULT;
--
2.33.0

View File

@ -0,0 +1,157 @@
From a935e07ee487f10c9d90f16e53fe5be8ef000484 Mon Sep 17 00:00:00 2001
From: Tim Wiederhake <twiederh@redhat.com>
Date: Tue, 22 Jun 2021 14:22:46 +0200
Subject: [PATCH] virDomainFeaturesDefParse: Factor out KVM parsing into
separate function
Only moving code, cleanup to follow.
Signed-off-by: Tim Wiederhake <twiederh@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: weishaokun <weishaokun@kylinos.cn>
---
src/conf/domain_conf.c | 110 +++++++++++++++++++++++------------------
1 file changed, 63 insertions(+), 47 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 5a04d1b5d1..ac2bb8abb4 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -20592,6 +20592,65 @@ virDomainMemorytuneDefParse(virDomainDefPtr def,
return ret;
}
+static int
+virDomainFeaturesKVMDefParse(virDomainDef *def,
+ xmlXPathContext *ctxt)
+{
+ g_autofree char *tmp = NULL;
+ g_autofree xmlNodePtr *nodes = NULL;
+ size_t i;
+ int n;
+
+ def->features[VIR_DOMAIN_FEATURE_KVM] = VIR_TRISTATE_SWITCH_ON;
+
+ if (def->features[VIR_DOMAIN_FEATURE_KVM] == VIR_TRISTATE_SWITCH_ON) {
+ int feature;
+ virTristateSwitch value;
+ if ((n = virXPathNodeSet("./features/kvm/*", ctxt, &nodes)) < 0)
+ return -1;
+
+ for (i = 0; i < n; i++) {
+ feature = virDomainKVMTypeFromString((const char *)nodes[i]->name);
+ if (feature < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unsupported KVM feature: %s"),
+ nodes[i]->name);
+ return -1;
+ }
+
+ switch ((virDomainKVM) feature) {
+ case VIR_DOMAIN_KVM_HIDDEN:
+ case VIR_DOMAIN_KVM_DEDICATED:
+ if (!(tmp = virXMLPropString(nodes[i], "state"))) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("missing 'state' attribute for "
+ "KVM feature '%s'"),
+ nodes[i]->name);
+ return -1;
+ }
+
+ if ((value = virTristateSwitchTypeFromString(tmp)) < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("invalid value of state argument "
+ "for KVM feature '%s'"),
+ nodes[i]->name);
+ return -1;
+ }
+
+ VIR_FREE(tmp);
+ def->kvm_features[feature] = value;
+ break;
+
+ /* coverity[dead_error_begin] */
+ case VIR_DOMAIN_KVM_LAST:
+ break;
+ }
+ }
+ VIR_FREE(nodes);
+ }
+
+ return 0;
+}
static virDomainDefPtr
virDomainDefParseXML(xmlDocPtr xml,
@@ -21109,11 +21168,14 @@ virDomainDefParseXML(xmlDocPtr xml,
case VIR_DOMAIN_FEATURE_VIRIDIAN:
case VIR_DOMAIN_FEATURE_PRIVNET:
case VIR_DOMAIN_FEATURE_HYPERV:
- case VIR_DOMAIN_FEATURE_KVM:
case VIR_DOMAIN_FEATURE_MSRS:
def->features[val] = VIR_TRISTATE_SWITCH_ON;
break;
+ case VIR_DOMAIN_FEATURE_KVM:
+ if (virDomainFeaturesKVMDefParse(def, ctxt) < 0)
+ goto error;
+ break;
case VIR_DOMAIN_FEATURE_CAPABILITIES:
if ((tmp = virXMLPropString(nodes[i], "policy"))) {
if ((def->features[val] = virDomainCapabilitiesPolicyTypeFromString(tmp)) == -1) {
@@ -21375,52 +21437,6 @@ virDomainDefParseXML(xmlDocPtr xml,
VIR_FREE(nodes);
}
- if (def->features[VIR_DOMAIN_FEATURE_KVM] == VIR_TRISTATE_SWITCH_ON) {
- int feature;
- int value;
- if ((n = virXPathNodeSet("./features/kvm/*", ctxt, &nodes)) < 0)
- goto error;
-
- for (i = 0; i < n; i++) {
- feature = virDomainKVMTypeFromString((const char *)nodes[i]->name);
- if (feature < 0) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("unsupported KVM feature: %s"),
- nodes[i]->name);
- goto error;
- }
-
- switch ((virDomainKVM) feature) {
- case VIR_DOMAIN_KVM_HIDDEN:
- case VIR_DOMAIN_KVM_DEDICATED:
- if (!(tmp = virXMLPropString(nodes[i], "state"))) {
- virReportError(VIR_ERR_XML_ERROR,
- _("missing 'state' attribute for "
- "KVM feature '%s'"),
- nodes[i]->name);
- goto error;
- }
-
- if ((value = virTristateSwitchTypeFromString(tmp)) < 0) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("invalid value of state argument "
- "for KVM feature '%s'"),
- nodes[i]->name);
- goto error;
- }
-
- VIR_FREE(tmp);
- def->kvm_features[feature] = value;
- break;
-
- /* coverity[dead_error_begin] */
- case VIR_DOMAIN_KVM_LAST:
- break;
- }
- }
- VIR_FREE(nodes);
- }
-
if (def->features[VIR_DOMAIN_FEATURE_SMM] == VIR_TRISTATE_SWITCH_ON) {
int rv = virDomainParseScaledValue("string(./features/smm/tseg)",
"string(./features/smm/tseg/@unit)",
--
2.27.0

View File

@ -0,0 +1,97 @@
From dcbc9a2cfa0894e2bfc46c2a01659a86518c6e0a Mon Sep 17 00:00:00 2001
From: Tim Wiederhake <twiederh@redhat.com>
Date: Tue, 22 Jun 2021 14:22:47 +0200
Subject: [PATCH] virDomainFeaturesKVMDefParse: Remove ctxt
Iterating over all child elements of a node does not require xpath.
By doing away with xpath for this code, the code can be simplified.
Signed-off-by: Tim Wiederhake <twiederh@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Shaokun Wei <weishaokun@kylinos.cn>
---
src/conf/domain_conf.c | 25 +++++++++++--------------
1 file changed, 11 insertions(+), 14 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index ac2bb8abb4..9073db8541 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -20594,38 +20594,34 @@ virDomainMemorytuneDefParse(virDomainDefPtr def,
static int
virDomainFeaturesKVMDefParse(virDomainDef *def,
- xmlXPathContext *ctxt)
+ xmlNodePtr node)
{
g_autofree char *tmp = NULL;
- g_autofree xmlNodePtr *nodes = NULL;
- size_t i;
- int n;
def->features[VIR_DOMAIN_FEATURE_KVM] = VIR_TRISTATE_SWITCH_ON;
if (def->features[VIR_DOMAIN_FEATURE_KVM] == VIR_TRISTATE_SWITCH_ON) {
int feature;
virTristateSwitch value;
- if ((n = virXPathNodeSet("./features/kvm/*", ctxt, &nodes)) < 0)
- return -1;
- for (i = 0; i < n; i++) {
- feature = virDomainKVMTypeFromString((const char *)nodes[i]->name);
+ node = xmlFirstElementChild(node);
+ while (node) {
+ feature = virDomainKVMTypeFromString((const char *)node->name);
if (feature < 0) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unsupported KVM feature: %s"),
- nodes[i]->name);
+ node->name);
return -1;
}
switch ((virDomainKVM) feature) {
case VIR_DOMAIN_KVM_HIDDEN:
case VIR_DOMAIN_KVM_DEDICATED:
- if (!(tmp = virXMLPropString(nodes[i], "state"))) {
+ if (!(tmp = virXMLPropString(node, "state"))) {
virReportError(VIR_ERR_XML_ERROR,
_("missing 'state' attribute for "
"KVM feature '%s'"),
- nodes[i]->name);
+ node->name);
return -1;
}
@@ -20633,7 +20629,7 @@ virDomainFeaturesKVMDefParse(virDomainDef *def,
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("invalid value of state argument "
"for KVM feature '%s'"),
- nodes[i]->name);
+ node->name);
return -1;
}
@@ -20645,8 +20641,9 @@ virDomainFeaturesKVMDefParse(virDomainDef *def,
case VIR_DOMAIN_KVM_LAST:
break;
}
+
+ node = xmlNextElementSibling(node);
}
- VIR_FREE(nodes);
}
return 0;
@@ -21173,7 +21170,7 @@ virDomainDefParseXML(xmlDocPtr xml,
break;
case VIR_DOMAIN_FEATURE_KVM:
- if (virDomainFeaturesKVMDefParse(def, ctxt) < 0)
+ if (virDomainFeaturesKVMDefParse(def, nodes[i]) < 0)
goto error;
break;
case VIR_DOMAIN_FEATURE_CAPABILITIES:
--
2.27.0

View File

@ -0,0 +1,62 @@
From 73d21e001e964d7d86f4659ef9cdee95a90ec97c Mon Sep 17 00:00:00 2001
From: Tim Wiederhake <twiederh@redhat.com>
Date: Tue, 22 Jun 2021 14:22:49 +0200
Subject: [PATCH] virDomainFeaturesKVMDefParse: Remove tautological "if"
Signed-off-by: Tim Wiederhake <twiederh@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Shaokun Wei <weishaokun@kylinos.cn>
---
src/conf/domain_conf.c | 30 ++++++++++++++----------------
1 file changed, 14 insertions(+), 16 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index dca49b6a55..e884d94ef7 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -20598,28 +20598,26 @@ virDomainFeaturesKVMDefParse(virDomainDef *def,
{
def->features[VIR_DOMAIN_FEATURE_KVM] = VIR_TRISTATE_SWITCH_ON;
- if (def->features[VIR_DOMAIN_FEATURE_KVM] == VIR_TRISTATE_SWITCH_ON) {
+ node = xmlFirstElementChild(node);
+ while (node) {
int feature;
virTristateSwitch value;
- node = xmlFirstElementChild(node);
- while (node) {
- feature = virDomainKVMTypeFromString((const char *)node->name);
- if (feature < 0) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("unsupported KVM feature: %s"),
- node->name);
- return -1;
- }
+ feature = virDomainKVMTypeFromString((const char *)node->name);
+ if (feature < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unsupported KVM feature: %s"),
+ node->name);
+ return -1;
+ }
- if (virXMLPropTristateSwitch(node, "state", VIR_XML_PROP_REQUIRED,
- &value) < 0)
- return -1;
+ if (virXMLPropTristateSwitch(node, "state", VIR_XML_PROP_REQUIRED,
+ &value) < 0)
+ return -1;
- def->kvm_features[feature] = value;
+ def->kvm_features[feature] = value;
- node = xmlNextElementSibling(node);
- }
+ node = xmlNextElementSibling(node);
}
return 0;
--
2.27.0

View File

@ -0,0 +1,69 @@
From 956a277c82699de93d53444a4c8bf451108b501b Mon Sep 17 00:00:00 2001
From: Tim Wiederhake <twiederh@redhat.com>
Date: Tue, 22 Jun 2021 14:22:48 +0200
Subject: [PATCH] virDomainFeaturesKVMDefParse: Remove tautological "switch"
`feature` is always one of the values listed in the switch,
ensured by `virDomainKVMTypeFromString` above.
Signed-off-by: Tim Wiederhake <twiederh@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Shaokun Wei <weishaokun@kylinos.cn>
---
src/conf/domain_conf.c | 32 ++++----------------------------
1 file changed, 4 insertions(+), 28 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 9073db8541..dca49b6a55 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -20596,8 +20596,6 @@ static int
virDomainFeaturesKVMDefParse(virDomainDef *def,
xmlNodePtr node)
{
- g_autofree char *tmp = NULL;
-
def->features[VIR_DOMAIN_FEATURE_KVM] = VIR_TRISTATE_SWITCH_ON;
if (def->features[VIR_DOMAIN_FEATURE_KVM] == VIR_TRISTATE_SWITCH_ON) {
@@ -20614,33 +20612,11 @@ virDomainFeaturesKVMDefParse(virDomainDef *def,
return -1;
}
- switch ((virDomainKVM) feature) {
- case VIR_DOMAIN_KVM_HIDDEN:
- case VIR_DOMAIN_KVM_DEDICATED:
- if (!(tmp = virXMLPropString(node, "state"))) {
- virReportError(VIR_ERR_XML_ERROR,
- _("missing 'state' attribute for "
- "KVM feature '%s'"),
- node->name);
- return -1;
- }
-
- if ((value = virTristateSwitchTypeFromString(tmp)) < 0) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("invalid value of state argument "
- "for KVM feature '%s'"),
- node->name);
- return -1;
- }
-
- VIR_FREE(tmp);
- def->kvm_features[feature] = value;
- break;
+ if (virXMLPropTristateSwitch(node, "state", VIR_XML_PROP_REQUIRED,
+ &value) < 0)
+ return -1;
- /* coverity[dead_error_begin] */
- case VIR_DOMAIN_KVM_LAST:
- break;
- }
+ def->kvm_features[feature] = value;
node = xmlNextElementSibling(node);
}
--
2.27.0

View File

@ -0,0 +1,178 @@
From ff93e58df5e280d0d1b89a09999e001a5b4e1f01 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hyman=20Huang=28=E9=BB=84=E5=8B=87=29?=
<huangy81@chinatelecom.cn>
Date: Sun, 20 Feb 2022 21:28:14 +0800
Subject: [PATCH] virsh: Add mode option to domdirtyrate-calc virsh api
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Extend domdirtyrate-calc virsh api with mode option, either
of these three options "page-sampling,dirty-bitmap,dirty-ring"
can be specified when calculating dirty page rate.
Signed-off-by: Hyman Huang(榛勫媷) <huangy81@chinatelecom.cn>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Shaokun Wei <weishaokun@kylinos.cn>
---
docs/manpages/virsh.rst | 7 ++++--
tools/virsh-completer-domain.c | 19 +++++++++++++++
tools/virsh-completer-domain.h | 5 ++++
tools/virsh-domain.c | 42 +++++++++++++++++++++++++++++++++-
tools/virsh-domain.h | 9 ++++++++
5 files changed, 79 insertions(+), 3 deletions(-)
diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
index d7c8b2dfb2..c5be6dec8c 100644
--- a/docs/manpages/virsh.rst
+++ b/docs/manpages/virsh.rst
@@ -1704,13 +1704,16 @@ domdirtyrate-calc
::
domdirtyrate-calc <domain> [--seconds <sec>]
+ --mode=[page-sampling | dirty-bitmap | dirty-ring]
Calculate an active domain's memory dirty rate which may be expected by
user in order to decide whether it's proper to be migrated out or not.
The ``seconds`` parameter can be used to calculate dirty rate in a
specific time which allows 60s at most now and would be default to 1s
-if missing. The calculated dirty rate information is available by calling
-'domstats --dirtyrate'.
+if missing. These three *page-sampling, dirty-bitmap, dirty-ring* modes
+are mutually exclusive and alternative when specify calculation mode,
+*page-sampling* is the default mode if missing. The calculated dirty
+rate information is available by calling 'domstats --dirtyrate'.
domdisplay
diff --git a/tools/virsh-completer-domain.c b/tools/virsh-completer-domain.c
index 7e155d9ee2..c21fcb1941 100644
--- a/tools/virsh-completer-domain.c
+++ b/tools/virsh-completer-domain.c
@@ -335,3 +335,22 @@ virshDomainHostnameSourceCompleter(vshControl *ctl G_GNUC_UNUSED,
return ret;
}
+
+
+char **
+virshDomainDirtyRateCalcModeCompleter(vshControl *ctl G_GNUC_UNUSED,
+ const vshCmd *cmd G_GNUC_UNUSED,
+ unsigned int flags)
+{
+ char **ret = NULL;
+ size_t i;
+
+ virCheckFlags(0, NULL);
+
+ ret = g_new0(char *, VIRSH_DOMAIN_DIRTYRATE_CALC_MODE_LAST + 1);
+
+ for (i = 0; i < VIRSH_DOMAIN_DIRTYRATE_CALC_MODE_LAST; i++)
+ ret[i] = g_strdup(virshDomainDirtyRateCalcModeTypeToString(i));
+
+ return ret;
+}
diff --git a/tools/virsh-completer-domain.h b/tools/virsh-completer-domain.h
index b00b05e3bd..95773086f7 100644
--- a/tools/virsh-completer-domain.h
+++ b/tools/virsh-completer-domain.h
@@ -62,3 +62,8 @@ virshDomainInterfaceAddrSourceCompleter(vshControl *ctl,
char ** virshDomainHostnameSourceCompleter(vshControl *ctl,
const vshCmd *cmd,
unsigned int flags);
+
+char **
+virshDomainDirtyRateCalcModeCompleter(vshControl *ctl,
+ const vshCmd *cmd,
+ unsigned int flags);
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 595a210493..c8bd61d5b7 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -14443,15 +14443,29 @@ static const vshCmdOptDef opts_domdirtyrate_calc[] = {
.help = N_("calculate memory dirty rate within specified seconds, "
"the supported value range from 1 to 60, default to 1.")
},
+ {.name = "mode",
+ .type = VSH_OT_STRING,
+ .completer = virshDomainDirtyRateCalcModeCompleter,
+ .help = N_("dirty page rate calculation mode, either of these 3 options "
+ "'page-sampling, dirty-bitmap, dirty-ring' can be specified.")
+ },
{.name = NULL}
};
+VIR_ENUM_IMPL(virshDomainDirtyRateCalcMode,
+ VIRSH_DOMAIN_DIRTYRATE_CALC_MODE_LAST,
+ "page-sampling",
+ "dirty-bitmap",
+ "dirty-ring");
+
static bool
cmdDomDirtyRateCalc(vshControl *ctl, const vshCmd *cmd)
{
virDomainPtr dom = NULL;
int seconds = 1; /* the default value is 1 */
bool ret = false;
+ const char *modestr = NULL;
+ unsigned int flags = 0;
if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
return false;
@@ -14459,7 +14473,33 @@ cmdDomDirtyRateCalc(vshControl *ctl, const vshCmd *cmd)
if (vshCommandOptInt(ctl, cmd, "seconds", &seconds) < 0)
goto cleanup;
- if (virDomainStartDirtyRateCalc(dom, seconds, 0) < 0)
+ if (vshCommandOptStringReq(ctl, cmd, "mode", &modestr) < 0)
+ goto cleanup;
+
+ if (modestr) {
+ int mode = virshDomainDirtyRateCalcModeTypeFromString(modestr);
+
+ if (mode < 0) {
+ vshError(ctl, _("Unknown calculation mode '%s'"), modestr);
+ goto cleanup;
+ }
+
+ switch ((virshDomainDirtyRateCalcMode) mode) {
+ case VIRSH_DOMAIN_DIRTYRATE_CALC_MODE_PAGE_SAMPLING:
+ flags |= VIR_DOMAIN_DIRTYRATE_MODE_PAGE_SAMPLING;
+ break;
+ case VIRSH_DOMAIN_DIRTYRATE_CALC_MODE_DIRTY_BITMAP:
+ flags |= VIR_DOMAIN_DIRTYRATE_MODE_DIRTY_BITMAP;
+ break;
+ case VIRSH_DOMAIN_DIRTYRATE_CALC_MODE_DIRTY_RING:
+ flags |= VIR_DOMAIN_DIRTYRATE_MODE_DIRTY_RING;
+ break;
+ case VIRSH_DOMAIN_DIRTYRATE_CALC_MODE_LAST:
+ break;
+ }
+ }
+
+ if (virDomainStartDirtyRateCalc(dom, seconds, flags) < 0)
goto cleanup;
vshPrintExtra(ctl, _("Start to calculate domain's memory "
diff --git a/tools/virsh-domain.h b/tools/virsh-domain.h
index 0d59c579d4..ab6147ca7f 100644
--- a/tools/virsh-domain.h
+++ b/tools/virsh-domain.h
@@ -38,4 +38,13 @@ typedef enum {
VIR_ENUM_DECL(virshDomainHostnameSource);
+typedef enum {
+ VIRSH_DOMAIN_DIRTYRATE_CALC_MODE_PAGE_SAMPLING,
+ VIRSH_DOMAIN_DIRTYRATE_CALC_MODE_DIRTY_BITMAP,
+ VIRSH_DOMAIN_DIRTYRATE_CALC_MODE_DIRTY_RING,
+ VIRSH_DOMAIN_DIRTYRATE_CALC_MODE_LAST,
+} virshDomainDirtyRateCalcMode;
+
+VIR_ENUM_DECL(virshDomainDirtyRateCalcMode);
+
extern const vshCmdDef domManagementCmds[];
--
2.27.0

View File

@ -0,0 +1,134 @@
From d9599ee42db6a62cac6ae89c8d246c4c47574d5f Mon Sep 17 00:00:00 2001
From: tujipei <tujipei@huawei.com>
Date: Wed, 12 Jun 2024 14:34:57 +0800
Subject: [PATCH] virsh: add tmm main command word Add tmm command word into
virsh tool to call get tmm memory info API. It makes virsh can use tmm main
commmand to show tmm memory info on console. This command requires specific
kernel and a kernel driver to make sure its regular function. If runnning
environment missing the above reliance, this command will show error result
on console.
Signed-off-by: tujipei <tujipei@huawei.com>
---
tools/virsh-host.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 99 insertions(+)
diff --git a/tools/virsh-host.c b/tools/virsh-host.c
index 67d5466be2..4f54cafec7 100644
--- a/tools/virsh-host.c
+++ b/tools/virsh-host.c
@@ -1799,6 +1799,99 @@ cmdHypervisorCPUBaseline(vshControl *ctl,
return ret;
}
+/*
+ * "securememinfo" command
+ */
+
+static const vshCmdInfo info_tmm[] = {
+ {.name = "help",
+ .data = N_("Interaction with the tmm")
+ },
+ {.name = "desc",
+ .data = N_("Call the host kernel dev which is provided for virsh to use receiving tmm informations.")
+ },
+ {.name = NULL}
+};
+
+static const vshCmdOptDef opts_tmm[] = {
+ {.name = "dev",
+ .type = VSH_OT_DATA,
+ .flags = VSH_OFLAG_REQ,
+ .help = N_("Device name of host kernel dev")
+ },
+ {.name = "detail",
+ .type = VSH_OT_BOOL,
+ .help = N_("print detailed info if this option contained in cmd")
+ },
+ {.name = NULL}
+};
+
+static bool
+virshGetTmmMemoryInfo(vshControl *ctl,
+ const vshCmd *cmd)
+{
+ char *tmmMemoryInfo = NULL;
+ bool detail;
+ virshControlPtr priv = ctl->privData;
+
+ detail = vshCommandOptBool(cmd, "detail");
+ if (!(tmmMemoryInfo = virConnectGetTmmMemoryInfo(priv->conn, (unsigned int)detail))) {
+ vshError(ctl, _("Get tmm_memory_info failed"));
+ return false;
+ }
+
+ vshPrintExtra(ctl, _("%s"), tmmMemoryInfo);
+
+ VIR_FREE(tmmMemoryInfo);
+ return true;
+}
+
+typedef bool
+(*virshTmmFunc)(vshControl *ctl,
+ const vshCmd *cmd);
+
+struct _virshTmmFuncInfo {
+ const char *devName;
+ virshTmmFunc funcPtr;
+};
+
+typedef struct _virshTmmFuncInfo virshTmmFuncInfo;
+
+static virshTmmFuncInfo virshTmmFuncMap[] = {
+ {"tmm_memory_info", virshGetTmmMemoryInfo},
+};
+
+static bool
+virshTmmRunFunc(vshControl *ctl,
+ const char *devName,
+ const vshCmd *cmd)
+{
+ int funcIndex;
+
+ for (funcIndex = 0; funcIndex < sizeof(virshTmmFuncMap) / sizeof(virshTmmFuncInfo); funcIndex++) {
+ if (strcmp(devName, virshTmmFuncMap[funcIndex].devName) == 0) {
+ virshTmmFuncMap[funcIndex].funcPtr(ctl, cmd);
+ return true;
+ }
+ }
+
+ vshError(ctl, _("Invalid dev name"));
+ return false;
+}
+
+static bool
+cmdTmm(vshControl *ctl, const vshCmd *cmd)
+{
+ const char *devName = NULL;
+
+ if (vshCommandOptStringReq(ctl, cmd, "dev", &devName) < 0)
+ return false;
+
+ if (!virshTmmRunFunc(ctl, devName, cmd))
+ return false;
+
+ return true;
+}
const vshCmdDef hostAndHypervisorCmds[] = {
{.name = "allocpages",
@@ -1927,5 +2020,11 @@ const vshCmdDef hostAndHypervisorCmds[] = {
.info = info_version,
.flags = 0
},
+ {.name = "tmm",
+ .handler = cmdTmm,
+ .opts = opts_tmm,
+ .info = info_tmm,
+ .flags = 0
+ },
{.name = NULL}
};
--
2.27.0

View File

@ -0,0 +1,102 @@
From b8f4d98289a0746675edb036978bd02ab5f59c21 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fabiano@fidencio.org>
Date: Tue, 8 Jun 2021 22:16:42 +0200
Subject: [PATCH] virt-host-validate: Fix IOMMU output on aarch64
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
virt-host-validate should print "Checking for device assignment IOMMU
support" for all architectures, not only for Intel / AMD.
This is the output without the patch:
```
[fidencio@dentola libvirt]$ virt-host-validate
QEMU: comprobando if device /dev/kvm exists : PASA
QEMU: comprobando if device /dev/kvm is accessible : PASA
QEMU: comprobando if device /dev/vhost-net exists : PASA
QEMU: comprobando if device /dev/net/tun exists : PASA
QEMU: comprobando for cgroup 'cpu' controller support : PASA
QEMU: comprobando for cgroup 'cpuacct' controller support : PASA
QEMU: comprobando for cgroup 'cpuset' controller support : PASA
QEMU: comprobando for cgroup 'memory' controller support : PASA
QEMU: comprobando for cgroup 'devices' controller support : ADVERTENCIA (Enable 'devices' in kernel Kconfig file or mount/enable cgroup controller in your system)
QEMU: comprobando for cgroup 'blkio' controller support : PASA
ADVERTENCIA (Unknown if this platform has IOMMU support)
QEMU: comprobando for secure guest support : ADVERTENCIA (Unknown if this platform has Secure Guest support)
```
This is the output with the patch:
```
[fidencio@dentola libvirt]$ ./build/tools/virt-host-validate
QEMU: Checking if device /dev/kvm exists : PASS
QEMU: Checking if device /dev/kvm is accessible : PASS
QEMU: Checking if device /dev/vhost-net exists : PASS
QEMU: Checking if device /dev/net/tun exists : PASS
QEMU: Checking for cgroup 'cpu' controller support : PASS
QEMU: Checking for cgroup 'cpuacct' controller support : PASS
QEMU: Checking for cgroup 'cpuset' controller support : PASS
QEMU: Checking for cgroup 'memory' controller support : PASS
QEMU: Checking for cgroup 'devices' controller support : WARN (Enable 'devices' in kernel Kconfig file or mount/enable cgroup controller in your system)
QEMU: Checking for cgroup 'blkio' controller support : PASS
QEMU: Checking for device assignment IOMMU support : WARN (Unknown if this platform has IOMMU support)
QEMU: Checking for secure guest support : WARN (Unknown if this platform has Secure Guest support)
```
Signed-off-by: Fabiano Fidêncio <fabiano@fidencio.org>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
---
tools/virt-host-validate-common.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/tools/virt-host-validate-common.c b/tools/virt-host-validate-common.c
index fbefbada96..a78903fb38 100644
--- a/tools/virt-host-validate-common.c
+++ b/tools/virt-host-validate-common.c
@@ -339,6 +339,8 @@ int virHostValidateIOMMU(const char *hvname,
DIR *dir;
int rc;
+ virHostMsgCheck(hvname, "%s", _("for device assignment IOMMU support"));
+
flags = virHostValidateGetCPUFlags();
if (flags && virBitmapIsBitSet(flags, VIR_HOST_VALIDATE_CPU_FLAG_VMX))
@@ -349,7 +351,6 @@ int virHostValidateIOMMU(const char *hvname,
virBitmapFree(flags);
if (isIntel) {
- virHostMsgCheck(hvname, "%s", _("for device assignment IOMMU support"));
if (access("/sys/firmware/acpi/tables/DMAR", F_OK) == 0) {
virHostMsgPass();
bootarg = "intel_iommu=on";
@@ -361,7 +362,6 @@ int virHostValidateIOMMU(const char *hvname,
return -1;
}
} else if (isAMD) {
- virHostMsgCheck(hvname, "%s", _("for device assignment IOMMU support"));
if (access("/sys/firmware/acpi/tables/IVRS", F_OK) == 0) {
virHostMsgPass();
bootarg = "iommu=pt iommu=1";
@@ -373,7 +373,7 @@ int virHostValidateIOMMU(const char *hvname,
return -1;
}
} else if (ARCH_IS_PPC64(arch)) {
- /* Empty Block */
+ virHostMsgPass();
} else if (ARCH_IS_S390(arch)) {
/* On s390x, we skip the IOMMU check if there are no PCI
* devices (which is quite usual on s390x). If there are
@@ -385,6 +385,7 @@ int virHostValidateIOMMU(const char *hvname,
VIR_DIR_CLOSE(dir);
if (rc <= 0)
return 0;
+ virHostMsgPass();
} else {
virHostMsgFail(level,
"Unknown if this platform has IOMMU support");
--
2.41.0.windows.1

View File

@ -0,0 +1,122 @@
From 0d94495d109537d7d266071e42e13de9a1539752 Mon Sep 17 00:00:00 2001
From: Tim Wiederhake <twiederh@redhat.com>
Date: Fri, 16 Apr 2021 11:41:47 +0200
Subject: [PATCH] virxml: Add virXMLPropInt
Convenience function to return the value of an integer XML attribute.
Signed-off-by: Tim Wiederhake <twiederh@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Shaokun Wei <weishaokun@kylinos.cn>
---
src/libvirt_private.syms | 1 +
src/util/virxml.c | 53 ++++++++++++++++++++++++++++++++++++++++
src/util/virxml.h | 9 +++++++
3 files changed, 63 insertions(+)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 15924e69a5..4720bb0ab0 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -3480,6 +3480,7 @@ virXMLNodeSanitizeNamespaces;
virXMLNodeToString;
virXMLParseHelper;
virXMLPickShellSafeComment;
+virXMLPropInt;
virXMLPropString;
virXMLPropStringLimit;
virXMLPropTristateBool;
diff --git a/src/util/virxml.c b/src/util/virxml.c
index b7f8063497..f6f028896e 100644
--- a/src/util/virxml.c
+++ b/src/util/virxml.c
@@ -647,6 +647,59 @@ virXMLPropTristateSwitch(xmlNodePtr node,
}
+/**
+ * virXMLPropInt:
+ * @node: XML dom node pointer
+ * @name: Name of the property (attribute) to get
+ * @base: Number base, see strtol
+ * @flags: Bitwise or of virXMLPropFlags
+ * @result: The returned value
+ *
+ * Convenience function to return value of an integer attribute.
+ *
+ * Returns 1 in case of success in which case @result is set,
+ * or 0 if the attribute is not present,
+ * or -1 and reports an error on failure.
+ */
+int
+virXMLPropInt(xmlNodePtr node,
+ const char *name,
+ int base,
+ virXMLPropFlags flags,
+ int *result)
+{
+ g_autofree char *tmp = NULL;
+ int val;
+
+ if (!(tmp = virXMLPropString(node, name))) {
+ if (!(flags & VIR_XML_PROP_REQUIRED))
+ return 0;
+
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Missing required attribute '%s' in element '%s'"),
+ name, node->name);
+ return -1;
+ }
+
+ if (virStrToLong_i(tmp, NULL, base, &val) < 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Invalid value for attribute '%s' in element '%s': '%s'. Expected integer value"),
+ name, node->name, tmp);
+ return -1;
+ }
+
+ if ((flags & VIR_XML_PROP_NONZERO) && (val == 0)) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Invalid value for attribute '%s' in element '%s': Zero is not permitted"),
+ name, node->name);
+ return -1;
+ }
+
+ *result = val;
+ return 1;
+}
+
+
/**
* virXPathBoolean:
* @xpath: the XPath string to evaluate
diff --git a/src/util/virxml.h b/src/util/virxml.h
index 0cf293d5ae..28538fe035 100644
--- a/src/util/virxml.h
+++ b/src/util/virxml.h
@@ -37,6 +37,7 @@ xmlXPathContextPtr virXMLXPathContextNew(xmlDocPtr xml)
typedef enum {
VIR_XML_PROP_OPTIONAL = 0, /* Attribute may be absent */
VIR_XML_PROP_REQUIRED = 1 << 0, /* Attribute may not be absent */
+ VIR_XML_PROP_NONZERO = 1 << 1, /* Attribute may not be zero */
} virXMLPropFlags;
@@ -101,6 +102,14 @@ virXMLPropTristateSwitch(xmlNodePtr node,
virTristateSwitch *result)
ATTRIBUTE_NONNULL(0) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3);
+int
+virXMLPropInt(xmlNodePtr node,
+ const char *name,
+ int base,
+ virXMLPropFlags flags,
+ int *result)
+ ATTRIBUTE_NONNULL(0) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(4);
+
/* Internal function; prefer the macros below. */
xmlDocPtr virXMLParseHelper(int domcode,
const char *filename,
--
2.27.0

View File

@ -0,0 +1,123 @@
From a664916fd2d121a7aa733fac05bbdbf1d4ac2248 Mon Sep 17 00:00:00 2001
From: Tim Wiederhake <twiederh@redhat.com>
Date: Fri, 16 Apr 2021 11:41:45 +0200
Subject: [PATCH] virxml: Add virXMLPropTristateBool
Convenience function to return the value of a yes / no XML attribute.
Signed-off-by: Tim Wiederhake <twiederh@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Shaokun Wei <weishaokun@kylinos.cn>
---
src/libvirt_private.syms | 1 +
src/util/virxml.c | 44 ++++++++++++++++++++++++++++++++++++++++
src/util/virxml.h | 15 ++++++++++++++
3 files changed, 60 insertions(+)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index a00e354859..42b3700d57 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -3482,6 +3482,7 @@ virXMLParseHelper;
virXMLPickShellSafeComment;
virXMLPropString;
virXMLPropStringLimit;
+virXMLPropTristateBool;
virXMLSaveFile;
virXMLValidateAgainstSchema;
virXMLValidatorFree;
diff --git a/src/util/virxml.c b/src/util/virxml.c
index 9ea7b99dba..a1fe319e08 100644
--- a/src/util/virxml.c
+++ b/src/util/virxml.c
@@ -559,6 +559,50 @@ virXMLNodeContentString(xmlNodePtr node)
}
+/**
+ * virXMLPropTristateBool:
+ * @node: XML dom node pointer
+ * @name: Name of the property (attribute) to get
+ * @flags: Bitwise or of virXMLPropFlags
+ * @result: The returned value
+ *
+ * Convenience function to return value of a yes / no attribute.
+ *
+ * Returns 1 in case of success in which case @result is set,
+ * or 0 if the attribute is not present,
+ * or -1 and reports an error on failure.
+ */
+int
+virXMLPropTristateBool(xmlNodePtr node,
+ const char* name,
+ virXMLPropFlags flags,
+ virTristateBool *result)
+{
+ g_autofree char *tmp = NULL;
+ int val;
+
+ if (!(tmp = virXMLPropString(node, name))) {
+ if (!(flags & VIR_XML_PROP_REQUIRED))
+ return 0;
+
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Missing required attribute '%s' in element '%s'"),
+ name, node->name);
+ return -1;
+ }
+
+ if ((val = virTristateBoolTypeFromString(tmp)) <= 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Invalid value for attribute '%s' in element '%s': '%s'. Expected 'yes' or 'no'"),
+ name, node->name, tmp);
+ return -1;
+ }
+
+ *result = val;
+ return 1;
+}
+
+
/**
* virXPathBoolean:
* @xpath: the XPath string to evaluate
diff --git a/src/util/virxml.h b/src/util/virxml.h
index 26ab9f9c2d..1d7070b98f 100644
--- a/src/util/virxml.h
+++ b/src/util/virxml.h
@@ -28,10 +28,18 @@
#include <libxml/relaxng.h>
#include "virbuffer.h"
+#include "virenum.h"
xmlXPathContextPtr virXMLXPathContextNew(xmlDocPtr xml)
G_GNUC_WARN_UNUSED_RESULT;
+
+typedef enum {
+ VIR_XML_PROP_OPTIONAL = 0, /* Attribute may be absent */
+ VIR_XML_PROP_REQUIRED = 1 << 0, /* Attribute may not be absent */
+} virXMLPropFlags;
+
+
int virXPathBoolean(const char *xpath,
xmlXPathContextPtr ctxt);
char * virXPathString(const char *xpath,
@@ -79,6 +87,13 @@ char * virXMLPropStringLimit(xmlNodePtr node,
char * virXMLNodeContentString(xmlNodePtr node);
long virXMLChildElementCount(xmlNodePtr node);
+int
+virXMLPropTristateBool(xmlNodePtr node,
+ const char *name,
+ virXMLPropFlags flags,
+ virTristateBool *result)
+ ATTRIBUTE_NONNULL(0) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3);
+
/* Internal function; prefer the macros below. */
xmlDocPtr virXMLParseHelper(int domcode,
const char *filename,
--
2.27.0

View File

@ -0,0 +1,104 @@
From 78bfdbe8b72eb81fbe1e96b1e94a07a5944b0e97 Mon Sep 17 00:00:00 2001
From: Tim Wiederhake <twiederh@redhat.com>
Date: Fri, 16 Apr 2021 11:41:46 +0200
Subject: [PATCH] virxml: Add virXMLPropTristateSwitch
Convenience function to return the value of an on / off XML attribute.
Signed-off-by: Tim Wiederhake <twiederh@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Shaokun Wei <weishaokun@kylinos.cn>
---
src/libvirt_private.syms | 1 +
src/util/virxml.c | 44 ++++++++++++++++++++++++++++++++++++++++
src/util/virxml.h | 7 +++++++
3 files changed, 52 insertions(+)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 42b3700d57..15924e69a5 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -3483,6 +3483,7 @@ virXMLPickShellSafeComment;
virXMLPropString;
virXMLPropStringLimit;
virXMLPropTristateBool;
+virXMLPropTristateSwitch;
virXMLSaveFile;
virXMLValidateAgainstSchema;
virXMLValidatorFree;
diff --git a/src/util/virxml.c b/src/util/virxml.c
index a1fe319e08..b7f8063497 100644
--- a/src/util/virxml.c
+++ b/src/util/virxml.c
@@ -603,6 +603,50 @@ virXMLPropTristateBool(xmlNodePtr node,
}
+/**
+ * virXMLPropTristateSwitch:
+ * @node: XML dom node pointer
+ * @name: Name of the property (attribute) to get
+ * @flags: Bitwise or of virXMLPropFlags
+ * @result: The returned value
+ *
+ * Convenience function to return value of an on / off attribute.
+ *
+ * Returns 1 in case of success in which case @result is set,
+ * or 0 if the attribute is not present,
+ * or -1 and reports an error on failure.
+ */
+int
+virXMLPropTristateSwitch(xmlNodePtr node,
+ const char* name,
+ virXMLPropFlags flags,
+ virTristateSwitch *result)
+{
+ g_autofree char *tmp = NULL;
+ int val;
+
+ if (!(tmp = virXMLPropString(node, name))) {
+ if (!(flags & VIR_XML_PROP_REQUIRED))
+ return 0;
+
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Missing required attribute '%s' in element '%s'"),
+ name, node->name);
+ return -1;
+ }
+
+ if ((val = virTristateSwitchTypeFromString(tmp)) <= 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Invalid value for attribute '%s' in element '%s': '%s'. Expected 'on' or 'off'"),
+ name, node->name, tmp);
+ return -1;
+ }
+
+ *result = val;
+ return 1;
+}
+
+
/**
* virXPathBoolean:
* @xpath: the XPath string to evaluate
diff --git a/src/util/virxml.h b/src/util/virxml.h
index 1d7070b98f..0cf293d5ae 100644
--- a/src/util/virxml.h
+++ b/src/util/virxml.h
@@ -94,6 +94,13 @@ virXMLPropTristateBool(xmlNodePtr node,
virTristateBool *result)
ATTRIBUTE_NONNULL(0) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3);
+int
+virXMLPropTristateSwitch(xmlNodePtr node,
+ const char *name,
+ virXMLPropFlags flags,
+ virTristateSwitch *result)
+ ATTRIBUTE_NONNULL(0) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3);
+
/* Internal function; prefer the macros below. */
xmlDocPtr virXMLParseHelper(int domcode,
const char *filename,
--
2.27.0

View File

@ -0,0 +1,129 @@
From 122ef42d1d0e1d2d66968ab1e038926261e28e22 Mon Sep 17 00:00:00 2001
From: Tim Wiederhake <twiederh@redhat.com>
Date: Fri, 16 Apr 2021 11:41:48 +0200
Subject: [PATCH] virxml: Add virXMLPropUInt
Convenience function to return the value of an unsigned integer XML attribute.
Signed-off-by: Tim Wiederhake <twiederh@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Shaokun Wei <weishaokun@kylinos.cn>
---
src/libvirt_private.syms | 1 +
src/util/virxml.c | 60 ++++++++++++++++++++++++++++++++++++++++
src/util/virxml.h | 9 ++++++
3 files changed, 70 insertions(+)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 4720bb0ab0..82d720c7c1 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -3485,6 +3485,7 @@ virXMLPropString;
virXMLPropStringLimit;
virXMLPropTristateBool;
virXMLPropTristateSwitch;
+virXMLPropUInt;
virXMLSaveFile;
virXMLValidateAgainstSchema;
virXMLValidatorFree;
diff --git a/src/util/virxml.c b/src/util/virxml.c
index f6f028896e..de86ce3d2b 100644
--- a/src/util/virxml.c
+++ b/src/util/virxml.c
@@ -700,6 +700,66 @@ virXMLPropInt(xmlNodePtr node,
}
+/**
+ * virXMLPropUInt:
+ * @node: XML dom node pointer
+ * @name: Name of the property (attribute) to get
+ * @base: Number base, see strtol
+ * @flags: Bitwise or of virXMLPropFlags
+ * @result: The returned value
+ *
+ * Convenience function to return value of an unsigned integer attribute.
+ *
+ * Returns 1 in case of success in which case @result is set,
+ * or 0 if the attribute is not present,
+ * or -1 and reports an error on failure.
+ */
+int
+virXMLPropUInt(xmlNodePtr node,
+ const char* name,
+ int base,
+ virXMLPropFlags flags,
+ unsigned int *result)
+{
+ g_autofree char *tmp = NULL;
+ int ret;
+ unsigned int val;
+
+ if (!(tmp = virXMLPropString(node, name))) {
+ if (!(flags & VIR_XML_PROP_REQUIRED))
+ return 0;
+
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Missing required attribute '%s' in element '%s'"),
+ name, node->name);
+ return -1;
+ }
+
+ if (flags & VIR_XML_PROP_WRAPNEGATIVE) {
+ ret = virStrToLong_ui(tmp, NULL, base, &val);
+ } else {
+ ret = virStrToLong_uip(tmp, NULL, base, &val);
+ }
+
+ if (ret < 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Invalid value for attribute '%s' in element '%s': '%s'. Expected integer value"),
+ name, node->name, tmp);
+ return -1;
+ }
+
+ if ((flags & VIR_XML_PROP_NONZERO) && (val == 0)) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Invalid value for attribute '%s' in element '%s': Zero is not permitted"),
+ name, node->name);
+ return -1;
+ }
+
+ *result = val;
+ return 1;
+}
+
+
/**
* virXPathBoolean:
* @xpath: the XPath string to evaluate
diff --git a/src/util/virxml.h b/src/util/virxml.h
index 28538fe035..d953743ab1 100644
--- a/src/util/virxml.h
+++ b/src/util/virxml.h
@@ -38,6 +38,7 @@ typedef enum {
VIR_XML_PROP_OPTIONAL = 0, /* Attribute may be absent */
VIR_XML_PROP_REQUIRED = 1 << 0, /* Attribute may not be absent */
VIR_XML_PROP_NONZERO = 1 << 1, /* Attribute may not be zero */
+ VIR_XML_PROP_WRAPNEGATIVE = 1 << 2, /* Wrap around negative values */
} virXMLPropFlags;
@@ -110,6 +111,14 @@ virXMLPropInt(xmlNodePtr node,
int *result)
ATTRIBUTE_NONNULL(0) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(4);
+int
+virXMLPropUInt(xmlNodePtr node,
+ const char* name,
+ int base,
+ virXMLPropFlags flags,
+ unsigned int *result)
+ ATTRIBUTE_NONNULL(0) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(4);
+
/* Internal function; prefer the macros below. */
xmlDocPtr virXMLParseHelper(int domcode,
const char *filename,
--
2.27.0