!129 sync the last 16 commits of 22.03 branch

From: @yezengruan 
Reviewed-by: @imxcc 
Signed-off-by: @imxcc
This commit is contained in:
openeuler-ci-bot 2022-03-19 04:24:54 +00:00 committed by Gitee
commit 6ef66ee85e
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
44 changed files with 11640 additions and 7 deletions

View File

@ -0,0 +1,211 @@
From 9a12606bb5caf3e213ce1564445d88325592e642 Mon Sep 17 00:00:00 2001
From: AlexChen <alex.chen@huawei.com>
Date: Tue, 19 Oct 2021 14:50:32 +0800
Subject: [PATCH] Hotpatch: introduce DomainHotpatchManage API
Signed-off-by: Hao Wang <wanghao232@huawei.com>
Signed-off-by: Bihong Yu <yubihong@huawei.com>
Signed-off-by: AlexChen <alex.chen@huawei.com>
---
include/libvirt/libvirt-domain.h | 18 ++++++++++
scripts/check-aclrules.py | 1 +
src/driver-hypervisor.h | 8 +++++
src/libvirt-domain.c | 58 ++++++++++++++++++++++++++++++++
src/libvirt_public.syms | 4 +++
src/remote/remote_driver.c | 1 +
src/remote/remote_protocol.x | 20 ++++++++++-
7 files changed, 109 insertions(+), 1 deletion(-)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 90cb652db1..f91061724b 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -4991,4 +4991,22 @@ int virDomainBackupBegin(virDomainPtr domain,
char *virDomainBackupGetXMLDesc(virDomainPtr domain,
unsigned int flags);
+typedef enum {
+ VIR_DOMAIN_HOTPATCH_NONE = 0, /* No action */
+ VIR_DOMAIN_HOTPATCH_APPLY, /* Apply hotpatch */
+ VIR_DOMAIN_HOTPATCH_UNAPPLY, /* Unapply hotpatch */
+ VIR_DOMAIN_HOTPATCH_QUERY, /* Query hotpatch */
+
+# ifdef VIR_ENUM_SENTINELS
+ VIR_DOMAIN_HOTPATCH_LAST
+# endif
+} virDomainHotpatchAction;
+
+char *
+virDomainHotpatchManage(virDomainPtr domain,
+ int action,
+ const char *patch,
+ const char *id,
+ unsigned int flags);
+
#endif /* LIBVIRT_DOMAIN_H */
diff --git a/scripts/check-aclrules.py b/scripts/check-aclrules.py
index a1fa473174..e196f81de9 100755
--- a/scripts/check-aclrules.py
+++ b/scripts/check-aclrules.py
@@ -53,6 +53,7 @@ whitelist = {
"connectURIProbe": True,
"localOnly": True,
"domainQemuAttach": True,
+ "domainHotpatchManage": True,
}
# XXX this vzDomainMigrateConfirm3Params looks
diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h
index bce023017d..afc21a0b3f 100644
--- a/src/driver-hypervisor.h
+++ b/src/driver-hypervisor.h
@@ -1387,6 +1387,13 @@ typedef char *
(*virDrvDomainBackupGetXMLDesc)(virDomainPtr domain,
unsigned int flags);
+typedef char *
+(*virDrvDomainHotpatchManage)(virDomainPtr domain,
+ int action,
+ const char *patch,
+ const char *id,
+ unsigned int flags);
+
typedef struct _virHypervisorDriver virHypervisorDriver;
typedef virHypervisorDriver *virHypervisorDriverPtr;
@@ -1650,4 +1657,5 @@ struct _virHypervisorDriver {
virDrvDomainAgentSetResponseTimeout domainAgentSetResponseTimeout;
virDrvDomainBackupBegin domainBackupBegin;
virDrvDomainBackupGetXMLDesc domainBackupGetXMLDesc;
+ virDrvDomainHotpatchManage domainHotpatchManage;
};
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index a12809c2d5..068ab52f54 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -12733,3 +12733,61 @@ virDomainBackupGetXMLDesc(virDomainPtr domain,
virDispatchError(conn);
return NULL;
}
+
+/**
+ * virDomainHotpatchManage:
+ * @domain: a domain object
+ * @action: the action type from virDomainHotpatchAction
+ * @patch: the target hotpatch file
+ * @id: the patch id of the target hotpatch
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Manage hotpatch for the current domain according to @action.
+ *
+ * If the @action is set to VIR_DOMAIN_HOTPATCH_APPLY, apply hotpatch
+ * @patch to the current domain.
+ *
+ * If the @action is set to VIR_DOMAIN_HOTPATCH_UNAPPLY, unapply the
+ * hotpatch which is matched with @id from the current domain.
+ *
+ * If the @action is set to VIR_DOMAIN_HOTPATCH_QUERY, query infomations
+ * of the applied hotpatch of the current domain.
+ *
+ * Returns success messages in case of success, NULL otherwise.
+ */
+char *
+virDomainHotpatchManage(virDomainPtr domain,
+ int action,
+ const char *patch,
+ const char *id,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, NULL);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (action == VIR_DOMAIN_HOTPATCH_APPLY)
+ virCheckNonNullArgGoto(patch, error);
+
+ if (action == VIR_DOMAIN_HOTPATCH_UNAPPLY)
+ virCheckNonNullArgGoto(id, error);
+
+ if (conn->driver->domainHotpatchManage) {
+ char *ret;
+ ret = conn->driver->domainHotpatchManage(domain, action, patch, id, flags);
+ 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 539d2e3943..0ad0b9e489 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -873,4 +873,8 @@ LIBVIRT_6.0.0 {
virDomainBackupGetXMLDesc;
} LIBVIRT_5.10.0;
+LIBVIRT_6.2.0 {
+ global:
+ virDomainHotpatchManage;
+} LIBVIRT_6.0.0;
# .... define new API here using predicted next version number ....
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 7bae0c2514..1202d44017 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -8684,6 +8684,7 @@ static virHypervisorDriver hypervisor_driver = {
.domainAgentSetResponseTimeout = remoteDomainAgentSetResponseTimeout, /* 5.10.0 */
.domainBackupBegin = remoteDomainBackupBegin, /* 6.0.0 */
.domainBackupGetXMLDesc = remoteDomainBackupGetXMLDesc, /* 6.0.0 */
+ .domainHotpatchManage = remoteDomainHotpatchManage, /* 6.2.0 */
};
static virNetworkDriver network_driver = {
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index 8b05082b61..ee13075ce1 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -3771,6 +3771,18 @@ struct remote_domain_backup_get_xml_desc_ret {
remote_nonnull_string xml;
};
+struct remote_domain_hotpatch_manage_args {
+ remote_nonnull_domain dom;
+ int action;
+ remote_string patch;
+ remote_string id;
+ unsigned int flags;
+};
+
+struct remote_domain_hotpatch_manage_ret {
+ remote_string info;
+};
+
/*----- Protocol. -----*/
/* Define the program number, protocol version and procedure numbers here. */
@@ -6668,5 +6680,11 @@ enum remote_procedure {
* @priority: high
* @acl: domain:read
*/
- REMOTE_PROC_DOMAIN_BACKUP_GET_XML_DESC = 422
+ REMOTE_PROC_DOMAIN_BACKUP_GET_XML_DESC = 422,
+
+ /**
+ * @generate: both
+ * @acl: domain:read
+ */
+ REMOTE_PROC_DOMAIN_HOTPATCH_MANAGE = 800
};
--
2.27.0

View File

@ -0,0 +1,108 @@
From 78c25600daf2a2822e7ecec2af9e7458b9f44eff Mon Sep 17 00:00:00 2001
From: yezengruan <yezengruan@huawei.com>
Date: Sat, 12 Mar 2022 09:35:07 +0800
Subject: [PATCH 1/6] Revert libvirt: support aarch64 vtpm with parameter
tpm-tis-device
Before backport the patch support aarch64 vtpm, let's
revert it first.
Signed-off-by: yezengruan <yezengruan@huawei.com>
---
src/conf/domain_conf.c | 1 -
src/conf/domain_conf.h | 1 -
src/qemu/qemu_capabilities.c | 9 +--------
src/qemu/qemu_capabilities.h | 4 +---
src/qemu/qemu_domain.c | 3 ---
5 files changed, 2 insertions(+), 16 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 4e3bcf479c..54228a2151 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1141,7 +1141,6 @@ VIR_ENUM_IMPL(virDomainTPMModel,
"tpm-tis",
"tpm-crb",
"tpm-spapr",
- "tpm-tis-device",
);
VIR_ENUM_IMPL(virDomainTPMBackend,
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index ccee986849..e057c384c6 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1280,7 +1280,6 @@ typedef enum {
VIR_DOMAIN_TPM_MODEL_TIS,
VIR_DOMAIN_TPM_MODEL_CRB,
VIR_DOMAIN_TPM_MODEL_SPAPR,
- VIR_DOMAIN_TPM_MODEL_TIS_DEVICE,
VIR_DOMAIN_TPM_MODEL_LAST
} virDomainTPMModel;
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 6013be9d05..0fb3e74c77 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -568,9 +568,7 @@ VIR_ENUM_IMPL(virQEMUCaps,
"blockdev-snapshot.allow-write-only-overlay",
"blockdev-reopen",
"storage.werror",
-
- /* 360 */
- "tpm-tis-device",
+
"migration-param.bandwidth",
"migration-param.downtime",
"migration-param.xbzrle-cache-size",
@@ -1292,7 +1290,6 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = {
{ "rng-builtin", QEMU_CAPS_OBJECT_RNG_BUILTIN },
{ "tpm-spapr", QEMU_CAPS_DEVICE_TPM_SPAPR },
{ "vhost-user-fs-device", QEMU_CAPS_DEVICE_VHOST_USER_FS },
- { "tpm-tis-device", QEMU_CAPS_DEVICE_TPM_TIS_DEVICE },
};
static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsVirtioBalloon[] = {
@@ -3100,10 +3097,6 @@ const struct tpmTypeToCaps virQEMUCapsTPMModelsToCaps[] = {
.type = VIR_DOMAIN_TPM_MODEL_SPAPR,
.caps = QEMU_CAPS_DEVICE_TPM_SPAPR,
},
- {
- .type = VIR_DOMAIN_TPM_MODEL_TIS_DEVICE,
- .caps = QEMU_CAPS_DEVICE_TPM_TIS_DEVICE,
- },
};
static int
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 5f28006b48..10a6ce50e7 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -549,9 +549,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */
QEMU_CAPS_BLOCKDEV_SNAPSHOT_ALLOW_WRITE_ONLY, /* blockdev-snapshot has the 'allow-write-only-overlay' feature */
QEMU_CAPS_BLOCKDEV_REOPEN, /* 'blockdev-reopen' qmp command is supported */
QEMU_CAPS_STORAGE_WERROR, /* virtio-blk,scsi-hd.werror */
-
- /* 360 */
- QEMU_CAPS_DEVICE_TPM_TIS_DEVICE, /* -device tpm-tis-device */
+
QEMU_CAPS_MIGRATION_PARAM_BANDWIDTH, /* max-bandwidth field in migrate-set-parameters */
QEMU_CAPS_MIGRATION_PARAM_DOWNTIME, /* downtime-limit field in migrate-set-parameters */
QEMU_CAPS_MIGRATION_PARAM_XBZRLE_CACHE_SIZE, /* xbzrle-cache-size field in migrate-set-parameters */
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 2351cac120..cb2fbdc179 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -8130,9 +8130,6 @@ qemuDomainDeviceDefValidateTPM(virDomainTPMDef *tpm,
case VIR_DOMAIN_TPM_MODEL_SPAPR:
flag = QEMU_CAPS_DEVICE_TPM_SPAPR;
break;
- case VIR_DOMAIN_TPM_MODEL_TIS_DEVICE:
- flag = QEMU_CAPS_DEVICE_TPM_TIS_DEVICE;
- break;
case VIR_DOMAIN_TPM_MODEL_LAST:
default:
virReportEnumRangeError(virDomainTPMModel, tpm->model);
--
2.27.0

View File

@ -0,0 +1,42 @@
From 8629a253113a019215b38f7206db03892157a370 Mon Sep 17 00:00:00 2001
From: imxcc <xingchaochao@huawei.com>
Date: Sat, 29 Jan 2022 17:14:59 +0800
Subject: [PATCH] Revert tests: disabale storage tests
Signed-off-by: imxcc <xingchaochao@huawei.com>
---
tests/Makefile.am | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index abb261e..ada5b8f 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -363,10 +363,16 @@ endif WITH_NWFILTER
if WITH_STORAGE
test_programs += storagevolxml2argvtest
+test_programs += storagepoolxml2argvtest
test_programs += virstorageutiltest
+test_programs += storagepoolxml2xmltest
test_programs += storagepoolcapstest
endif WITH_STORAGE
+if WITH_STORAGE_FS
+test_programs += virstoragetest
+endif WITH_STORAGE_FS
+
if WITH_LINUX
test_programs += virscsitest
endif WITH_LINUX
@@ -424,6 +430,7 @@ test_scripts += $(libvirtd_test_scripts)
test_programs += \
eventtest \
+ virdrivermoduletest \
virdriverconnvalidatetest
else ! WITH_LIBVIRTD
EXTRA_DIST += $(libvirtd_test_scripts)
--
2.27.0

View File

@ -0,0 +1,62 @@
From c99e7e8abe1e22f504173a976a82e1a72551bdc1 Mon Sep 17 00:00:00 2001
From: Peter Krempa <pkrempa@redhat.com>
Date: Mon, 3 Aug 2020 07:32:29 +0200
Subject: [PATCH] docs: build: Don't include stylesheet in intermediate html
files generated from RST
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
'docutils' add a stylesheet to the output html file for direct
consumption. Since we use the html files just as an intermediate step
which is post-processed to add our own stylesheet and drop the docutils
one in the process we can ask 'rst2html' to not add any for an
intermediate file with less garbage.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Signed-off-by: rpm-build <rpm-build>
---
docs/Makefile.am | 4 ++--
docs/Makefile.in | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/docs/Makefile.am b/docs/Makefile.am
index 61862c4..4c44504 100644
--- a/docs/Makefile.am
+++ b/docs/Makefile.am
@@ -420,11 +420,11 @@ manpages/%.html.in: manpages/%.rst
grep -v '^:Manual ' < $< | \
sed -e 's|SYSCONFDIR|$(sysconfdir)|g' \
-e 's|RUNSTATEDIR|$(runstatedir)|g' | \
- $(RST2HTML) --strict > $@ || { rm $@ && exit 1; }
+ $(RST2HTML) --stylesheet= --strict > $@ || { rm $@ && exit 1; }
%.html.in: %.rst
$(AM_V_GEN)$(MKDIR_P) `dirname $@` && \
- $(RST2HTML) --strict $< > $@ || { rm $@ && exit 1; }
+ $(RST2HTML) --stylesheet= --strict $< > $@ || { rm $@ && exit 1; }
%.html.tmp: %.html.in site.xsl subsite.xsl page.xsl \
$(acl_generated)
diff --git a/docs/Makefile.in b/docs/Makefile.in
index 61eac52..1836655 100644
--- a/docs/Makefile.in
+++ b/docs/Makefile.in
@@ -1469,11 +1469,11 @@ manpages/%.html.in: manpages/%.rst
grep -v '^:Manual ' < $< | \
sed -e 's|SYSCONFDIR|$(sysconfdir)|g' \
-e 's|RUNSTATEDIR|$(runstatedir)|g' | \
- $(RST2HTML) --strict > $@ || { rm $@ && exit 1; }
+ $(RST2HTML) --stylesheet= --strict > $@ || { rm $@ && exit 1; }
%.html.in: %.rst
$(AM_V_GEN)$(MKDIR_P) `dirname $@` && \
- $(RST2HTML) --strict $< > $@ || { rm $@ && exit 1; }
+ $(RST2HTML) --stylesheet= --strict $< > $@ || { rm $@ && exit 1; }
%.html.tmp: %.html.in site.xsl subsite.xsl page.xsl \
$(acl_generated)
--
2.27.0

View File

@ -0,0 +1,45 @@
From e59b2064ffefbc94c729d38ec0180197e2b1f8ed Mon Sep 17 00:00:00 2001
From: AlexChen <alex.chen@huawei.com>
Date: Mon, 12 Jul 2021 21:28:41 +0800
Subject: [PATCH] domain: add logs for virDomainHotpatchManage
Add logs for virDomainHotpatchManage to facilitate the location of
issues related to subsequent hotpatch.
Signed-off-by: Bihong Yu <yubihong@huawei.com>
Signed-off-by: AlexChen <alex.chen@huawei.com>
---
src/libvirt-domain.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index 068ab52f54..3cf6bcb3b4 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -12777,12 +12777,21 @@ virDomainHotpatchManage(virDomainPtr domain,
if (action == VIR_DOMAIN_HOTPATCH_UNAPPLY)
virCheckNonNullArgGoto(id, error);
+ VIR_INFO("enter virDomainHotpatchManage domainname=%s, action=%d, "
+ "patch=%s, id=%s, flags=%d",
+ NULLSTR(domain->name), action,
+ NULLSTR(patch), NULLSTR(id), flags);
+
if (conn->driver->domainHotpatchManage) {
char *ret;
ret = conn->driver->domainHotpatchManage(domain, action, patch, id, flags);
- if (!ret)
+ if (!ret) {
+ VIR_ERROR("domain %s managed hotpatch failed",
+ NULLSTR(domain->name));
goto error;
-
+ }
+ VIR_INFO("domain %s managed hotpatch successfully",
+ NULLSTR(domain->name));
return ret;
}
--
2.27.0

View File

@ -0,0 +1,336 @@
From b255a024007eb236745b703586a2fed8bdedae6c Mon Sep 17 00:00:00 2001
From: AlexChen <alex.chen@huawei.com>
Date: Tue, 19 Oct 2021 22:11:45 +0800
Subject: [PATCH] hotpatch: Implement qemuDomainHotpatchManage
Signed-off-by: Hao Wang <wanghao232@huawei.com>
Signed-off-by: Bihong Yu <yubihong@huawei.com>
Signed-off-by: AlexChen <alex.chen@huawei.com>
---
src/qemu/Makefile.inc.am | 2 +
src/qemu/qemu_driver.c | 48 +++++++++++
src/qemu/qemu_hotpatch.c | 182 +++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_hotpatch.h | 36 ++++++++
4 files changed, 268 insertions(+)
create mode 100644 src/qemu/qemu_hotpatch.c
create mode 100644 src/qemu/qemu_hotpatch.h
diff --git a/src/qemu/Makefile.inc.am b/src/qemu/Makefile.inc.am
index 51cd79879d..a1a8bfa17c 100644
--- a/src/qemu/Makefile.inc.am
+++ b/src/qemu/Makefile.inc.am
@@ -73,6 +73,8 @@ QEMU_DRIVER_SOURCES = \
qemu/qemu_checkpoint.h \
qemu/qemu_backup.c \
qemu/qemu_backup.h \
+ qemu/qemu_hotpatch.c \
+ qemu/qemu_hotpatch.h \
$(NULL)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 5901f922bf..f6d99957a5 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -50,6 +50,7 @@
#include "qemu_security.h"
#include "qemu_checkpoint.h"
#include "qemu_backup.h"
+#include "qemu_hotpatch.h"
#include "virerror.h"
#include "virlog.h"
@@ -23171,6 +23172,52 @@ qemuDomainAgentSetResponseTimeout(virDomainPtr dom,
return ret;
}
+static char *
+qemuDomainHotpatchManage(virDomainPtr domain,
+ int action,
+ const char *patch,
+ const char *id,
+ unsigned int flags)
+{
+ virDomainObjPtr vm;
+ char *ret = NULL;
+ size_t len;
+
+ virCheckFlags(0, NULL);
+
+ if (!(vm = qemuDomainObjFromDomain(domain)))
+ goto cleanup;
+
+ switch (action) {
+ case VIR_DOMAIN_HOTPATCH_APPLY:
+ ret = qemuDomainHotpatchApply(vm, patch);
+ break;
+
+ case VIR_DOMAIN_HOTPATCH_UNAPPLY:
+ ret = qemuDomainHotpatchUnapply(vm, id);
+ break;
+
+ case VIR_DOMAIN_HOTPATCH_QUERY:
+ ret = qemuDomainHotpatchQuery(vm);
+ break;
+
+ default:
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("Unknow hotpatch action"));
+ }
+
+ if (!ret)
+ goto endjob;
+
+ /* Wipeout redundant empty line */
+ len = strlen(ret);
+ if (len > 0)
+ ret[len - 1] = '\0';
+
+ cleanup:
+ virDomainObjEndAPI(&vm);
+ return ret;
+}
static virHypervisorDriver qemuHypervisorDriver = {
.name = QEMU_DRIVER_NAME,
@@ -23411,6 +23458,7 @@ static virHypervisorDriver qemuHypervisorDriver = {
.domainAgentSetResponseTimeout = qemuDomainAgentSetResponseTimeout, /* 5.10.0 */
.domainBackupBegin = qemuDomainBackupBegin, /* 6.0.0 */
.domainBackupGetXMLDesc = qemuDomainBackupGetXMLDesc, /* 6.0.0 */
+ .domainHotpatchManage = qemuDomainHotpatchManage, /* 6.2.0 */
};
diff --git a/src/qemu/qemu_hotpatch.c b/src/qemu/qemu_hotpatch.c
new file mode 100644
index 0000000000..45796b3f24
--- /dev/null
+++ b/src/qemu/qemu_hotpatch.c
@@ -0,0 +1,182 @@
+/*
+ * huawei_qemu_hotpatch.h: huawei qemu hotpatch functions
+ *
+ * Copyright (C) 2021-2021 HUAWEI, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include <unistd.h>
+#include "viralloc.h"
+#include "virerror.h"
+#include "virfile.h"
+#include "virlog.h"
+#include "vircommand.h"
+#include "qemu/qemu_domain.h"
+#include "qemu_hotpatch.h"
+
+#define LIBCARE_CTL "libcare-ctl"
+#define LIBCARE_ERROR_NUMBER 255
+#define MAX_PATCHID_LEN 8
+
+#define VIR_FROM_THIS VIR_FROM_QEMU
+
+VIR_LOG_INIT("qemu_hotpatch");
+
+char *
+qemuDomainHotpatchQuery(virDomainObjPtr vm)
+{
+ g_autoptr(virCommand) cmd = NULL;
+ g_autofree char *binary = NULL;
+ char *output = NULL;
+ int ret = -1;
+
+ if (!(binary = virFindFileInPath(LIBCARE_CTL))) {
+ virReportError(VIR_ERR_OPERATION_FAILED, "%s",
+ _("Failed to find libcare-ctl command."));
+ return NULL;
+ }
+
+ cmd = virCommandNewArgList(binary, "info", "-p", NULL);
+ virCommandAddArgFormat(cmd, "%d", vm->pid);
+ virCommandSetOutputBuffer(cmd, &output);
+
+ VIR_DEBUG("Querying hotpatch for domain %s. (%s info -p %d)",
+ vm->def->name, binary, vm->pid);
+
+ if (virCommandRun(cmd, &ret) < 0)
+ goto error;
+
+ if (ret == LIBCARE_ERROR_NUMBER) {
+ virReportError(VIR_ERR_OPERATION_FAILED, "%s",
+ _("Failed to execute libcare-ctl command."));
+ goto error;
+ }
+ return output;
+
+ error:
+ VIR_FREE(output);
+ return NULL;
+}
+
+char *
+qemuDomainHotpatchApply(virDomainObjPtr vm,
+ const char *patch)
+{
+ g_autoptr(virCommand) cmd = NULL;
+ g_autofree char *binary = NULL;
+ char *output = NULL;
+ int ret = -1;
+
+ if (!patch || !virFileExists(patch)) {
+ virReportError(VIR_ERR_INVALID_ARG,
+ "%s", _("Invalid hotpatch file."));
+ return NULL;
+ }
+
+ if (!(binary = virFindFileInPath(LIBCARE_CTL))) {
+ virReportError(VIR_ERR_OPERATION_FAILED,
+ "%s", _("Failed to find libcare-ctl command."));
+ return NULL;
+ }
+
+ cmd = virCommandNewArgList(binary, "patch", "-p", NULL);
+ virCommandAddArgFormat(cmd, "%d", vm->pid);
+ virCommandAddArgList(cmd, patch, NULL);
+ virCommandSetOutputBuffer(cmd, &output);
+
+ VIR_DEBUG("Applying hotpatch for domain %s. (%s patch -p %d %s)",
+ vm->def->name, binary, vm->pid, patch);
+
+ if (virCommandRun(cmd, &ret) < 0)
+ goto error;
+
+ if (ret == LIBCARE_ERROR_NUMBER) {
+ virReportError(VIR_ERR_OPERATION_FAILED, "%s",
+ _("Failed to execute libcare-ctl command."));
+ goto error;
+ }
+ return output;
+
+ error:
+ VIR_FREE(output);
+ return NULL;
+}
+
+static bool
+qemuDomainHotpatchIsPatchidValid(const char *id)
+{
+ size_t len, i;
+
+ if (!id)
+ return false;
+
+ len = strlen(id);
+ if (len > MAX_PATCHID_LEN - 1)
+ return false;
+
+ for (i = 0; i < len; i++) {
+ if (!g_ascii_isalnum(*(id + i)))
+ return false;
+ }
+
+ return true;
+}
+
+char *
+qemuDomainHotpatchUnapply(virDomainObjPtr vm,
+ const char *id)
+{
+ g_autoptr(virCommand) cmd = NULL;
+ g_autofree char *binary = NULL;
+ char *output = NULL;
+ int ret = -1;
+
+ if (!id || !qemuDomainHotpatchIsPatchidValid(id)) {
+ virReportError(VIR_ERR_INVALID_ARG,
+ "%s", _("Invalid hotpatch id."));
+ return NULL;
+ }
+
+ if (!(binary = virFindFileInPath(LIBCARE_CTL))) {
+ virReportError(VIR_ERR_OPERATION_FAILED,
+ "%s", _("Failed to find libcare-ctl command."));
+ return NULL;
+ }
+
+ cmd = virCommandNewArgList(binary, "unpatch", "-p", NULL);
+ virCommandAddArgFormat(cmd, "%d", vm->pid);
+ virCommandAddArgList(cmd, "-i", id, NULL);
+ virCommandSetOutputBuffer(cmd, &output);
+
+ VIR_DEBUG("Unapplying hotpatch for domain %s. (%s unpatch -p %d -i %s)",
+ vm->def->name, binary, vm->pid, id);
+
+ if (virCommandRun(cmd, &ret) < 0)
+ goto error;
+
+ if (ret == LIBCARE_ERROR_NUMBER) {
+ virReportError(VIR_ERR_OPERATION_FAILED, "%s",
+ _("Failed to execute libcare-ctl command."));
+ goto error;
+ }
+ return output;
+
+ error:
+ VIR_FREE(output);
+ return NULL;
+}
diff --git a/src/qemu/qemu_hotpatch.h b/src/qemu/qemu_hotpatch.h
new file mode 100644
index 0000000000..4c84a57950
--- /dev/null
+++ b/src/qemu/qemu_hotpatch.h
@@ -0,0 +1,36 @@
+/*
+ * huawei_qemu_hotpatch.h: huawei qemu hotpatch functions
+ *
+ * Copyright (C) 2021-2021 HUAWEI, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#pragma once
+
+#include <unistd.h>
+#include "qemu/qemu_conf.h"
+
+char *
+qemuDomainHotpatchQuery(virDomainObjPtr vm);
+
+char *
+qemuDomainHotpatchApply(virDomainObjPtr vm,
+ const char *patch);
+
+char *
+qemuDomainHotpatchUnapply(virDomainObjPtr vm,
+ const char *id);
--
2.27.0

View File

@ -0,0 +1,135 @@
From 58121fbc3085296364e6b90bc16cb56eeaf36f77 Mon Sep 17 00:00:00 2001
From: AlexChen <alex.chen@huawei.com>
Date: Fri, 9 Jul 2021 10:50:07 +0800
Subject: [PATCH] hotpatch: check vm id and pid before using hotpatch api
Check if the vm is alive before using hotpatch api by calling
virDomainObjCheckActive() to check vm id and calling
qemuDomainHotpatchCheckPid() to check vm pid.
Signed-off-by: Bihong Yu <yubihong@huawei.com>
Signed-off-by: AlexChen <alex.chen@huawei.com>
---
src/qemu/qemu_driver.c | 3 +++
src/qemu/qemu_hotpatch.c | 36 ++++++++++++++++++++++++++++++------
2 files changed, 33 insertions(+), 6 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index d4c5f073bb..2b24881f75 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -23196,6 +23196,9 @@ qemuDomainHotpatchManage(virDomainPtr domain,
VIR_DOMAIN_JOB_OPERATION_HOTPATCH, 0) < 0)
goto cleanup;
+ if (virDomainObjCheckActive(vm) < 0)
+ goto endjob;
+
qemuDomainObjSetAsyncJobMask(vm, QEMU_JOB_DEFAULT_MASK);
switch (action) {
diff --git a/src/qemu/qemu_hotpatch.c b/src/qemu/qemu_hotpatch.c
index 45796b3f24..03e63c1341 100644
--- a/src/qemu/qemu_hotpatch.c
+++ b/src/qemu/qemu_hotpatch.c
@@ -37,12 +37,25 @@
VIR_LOG_INIT("qemu_hotpatch");
+static int
+qemuDomainHotpatchCheckPid(pid_t pid)
+{
+ if (pid <= 0) {
+ virReportError(VIR_ERR_INVALID_ARG,
+ "%s", _("Invalid pid"));
+ return -1;
+ }
+
+ return 0;
+}
+
char *
qemuDomainHotpatchQuery(virDomainObjPtr vm)
{
g_autoptr(virCommand) cmd = NULL;
g_autofree char *binary = NULL;
char *output = NULL;
+ pid_t pid = vm->pid;
int ret = -1;
if (!(binary = virFindFileInPath(LIBCARE_CTL))) {
@@ -51,12 +64,15 @@ qemuDomainHotpatchQuery(virDomainObjPtr vm)
return NULL;
}
+ if (qemuDomainHotpatchCheckPid(pid) < 0)
+ return NULL;
+
cmd = virCommandNewArgList(binary, "info", "-p", NULL);
- virCommandAddArgFormat(cmd, "%d", vm->pid);
+ virCommandAddArgFormat(cmd, "%d", pid);
virCommandSetOutputBuffer(cmd, &output);
VIR_DEBUG("Querying hotpatch for domain %s. (%s info -p %d)",
- vm->def->name, binary, vm->pid);
+ vm->def->name, binary, pid);
if (virCommandRun(cmd, &ret) < 0)
goto error;
@@ -80,6 +96,7 @@ qemuDomainHotpatchApply(virDomainObjPtr vm,
g_autoptr(virCommand) cmd = NULL;
g_autofree char *binary = NULL;
char *output = NULL;
+ pid_t pid = vm->pid;
int ret = -1;
if (!patch || !virFileExists(patch)) {
@@ -94,13 +111,16 @@ qemuDomainHotpatchApply(virDomainObjPtr vm,
return NULL;
}
+ if (qemuDomainHotpatchCheckPid(pid) < 0)
+ return NULL;
+
cmd = virCommandNewArgList(binary, "patch", "-p", NULL);
- virCommandAddArgFormat(cmd, "%d", vm->pid);
+ virCommandAddArgFormat(cmd, "%d", pid);
virCommandAddArgList(cmd, patch, NULL);
virCommandSetOutputBuffer(cmd, &output);
VIR_DEBUG("Applying hotpatch for domain %s. (%s patch -p %d %s)",
- vm->def->name, binary, vm->pid, patch);
+ vm->def->name, binary, pid, patch);
if (virCommandRun(cmd, &ret) < 0)
goto error;
@@ -144,6 +164,7 @@ qemuDomainHotpatchUnapply(virDomainObjPtr vm,
g_autoptr(virCommand) cmd = NULL;
g_autofree char *binary = NULL;
char *output = NULL;
+ pid_t pid = vm->pid;
int ret = -1;
if (!id || !qemuDomainHotpatchIsPatchidValid(id)) {
@@ -158,13 +179,16 @@ qemuDomainHotpatchUnapply(virDomainObjPtr vm,
return NULL;
}
+ if (qemuDomainHotpatchCheckPid(pid) < 0)
+ return NULL;
+
cmd = virCommandNewArgList(binary, "unpatch", "-p", NULL);
- virCommandAddArgFormat(cmd, "%d", vm->pid);
+ virCommandAddArgFormat(cmd, "%d", pid);
virCommandAddArgList(cmd, "-i", id, NULL);
virCommandSetOutputBuffer(cmd, &output);
VIR_DEBUG("Unapplying hotpatch for domain %s. (%s unpatch -p %d -i %s)",
- vm->def->name, binary, vm->pid, id);
+ vm->def->name, binary, pid, id);
if (virCommandRun(cmd, &ret) < 0)
goto error;
--
2.27.0

View File

@ -0,0 +1,110 @@
From cf380e22898f70f5782bcea8b0d22027ff7d86af Mon Sep 17 00:00:00 2001
From: AlexChen <alex.chen@huawei.com>
Date: Wed, 20 Oct 2021 11:07:34 +0800
Subject: [PATCH] hotpatch: implement hotpatch virsh api
Signed-off-by: Hao Wang <wanghao232@huawei.com>
Signed-off-by: Bihong Yu <yubihong@huawei.com>
Signed-off-by: AlexChen <alex.chen@huawei.com>
---
tools/virsh-domain.c | 78 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 78 insertions(+)
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index f643bd403e..813be4a0db 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -14326,6 +14326,78 @@ cmdGuestInfo(vshControl *ctl, const vshCmd *cmd)
return ret;
}
+/*
+ * "hotpatch" command
+ */
+static const vshCmdInfo info_hotpatch[] = {
+ {.name = "help",
+ .data = N_("Manage hotpatch of a live domain")
+ },
+ {.name = "desc",
+ .data = N_("Manage hotpatch of a live domain")
+ },
+ {.name = NULL}
+};
+
+static const vshCmdOptDef opts_hotpatch[] = {
+ VIRSH_COMMON_OPT_DOMAIN_FULL(0),
+ {.name = "action",
+ .type = VSH_OT_DATA,
+ .flags = VSH_OFLAG_REQ,
+ .help = N_("hotpatch action, choose from <apply>, <unapply> and <query>")
+ },
+ {.name = "patch",
+ .type = VSH_OT_STRING,
+ .help = N_("the absolute path of the hotpatch file, mandatory when action=apply")
+ },
+ {.name = "id",
+ .type = VSH_OT_STRING,
+ .help = N_("the unique id of the target patch, mandatory when action=unapply")
+ },
+ {.name = NULL}
+};
+
+VIR_ENUM_DECL(virDomainHotpatchAction);
+VIR_ENUM_IMPL(virDomainHotpatchAction,
+ VIR_DOMAIN_HOTPATCH_LAST,
+ "none",
+ "apply",
+ "unapply",
+ "query");
+
+static bool
+cmdHotpatch(vshControl *ctl,
+ const vshCmd *cmd)
+{
+ g_autoptr(virshDomain) dom = NULL;
+ const char *patch = NULL;
+ const char *id = NULL;
+ const char *actionstr = NULL;
+ int action = -1;
+ g_autofree char *ret = NULL;
+
+ if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
+ return false;
+
+ if (vshCommandOptStringReq(ctl, cmd, "action", &actionstr) < 0)
+ return false;
+
+ if (actionstr)
+ action = virDomainHotpatchActionTypeFromString(actionstr);
+
+ if (vshCommandOptStringReq(ctl, cmd, "patch", &patch) < 0)
+ return false;
+
+ if (vshCommandOptStringReq(ctl, cmd, "id", &id) < 0)
+ return false;
+
+ if (!(ret = virDomainHotpatchManage(dom, action, patch, id, 0)))
+ return false;
+
+ vshPrint(ctl, _("%s"), ret);
+ return true;
+}
+
const vshCmdDef domManagementCmds[] = {
{.name = "attach-device",
.handler = cmdAttachDevice,
@@ -14953,5 +15025,11 @@ const vshCmdDef domManagementCmds[] = {
.info = info_guestinfo,
.flags = 0
},
+ {.name = "hotpatch",
+ .handler = cmdHotpatch,
+ .opts = opts_hotpatch,
+ .info = info_hotpatch,
+ .flags = 0
+ },
{.name = NULL}
};
--
2.27.0

View File

@ -0,0 +1,155 @@
From a83bb0dc19d7c92c200b9a234e120d16878eac19 Mon Sep 17 00:00:00 2001
From: AlexChen <alex.chen@huawei.com>
Date: Tue, 19 Oct 2021 22:41:24 +0800
Subject: [PATCH] hotpatch: introduce hotpatch async job flag
Signed-off-by: Hao Wang <wanghao232@huawei.com>
Signed-off-by: Bihong Yu <yubihong@huawei.com>
Signed-off-by: AlexChen <alex.chen@huawei.com>
---
include/libvirt/libvirt-domain.h | 1 +
src/qemu/qemu_domain.c | 3 +++
src/qemu/qemu_domain.h | 1 +
src/qemu/qemu_driver.c | 13 +++++++++++++
src/qemu/qemu_migration.c | 2 ++
src/qemu/qemu_process.c | 1 +
tools/virsh-domain.c | 1 +
7 files changed, 22 insertions(+)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index f91061724b..2d6432cab2 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -3295,6 +3295,7 @@ typedef enum {
VIR_DOMAIN_JOB_OPERATION_SNAPSHOT_REVERT = 7,
VIR_DOMAIN_JOB_OPERATION_DUMP = 8,
VIR_DOMAIN_JOB_OPERATION_BACKUP = 9,
+ VIR_DOMAIN_JOB_OPERATION_HOTPATCH = 10,
# ifdef VIR_ENUM_SENTINELS
VIR_DOMAIN_JOB_OPERATION_LAST
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 5d35d49638..2351cac120 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -111,6 +111,7 @@ VIR_ENUM_IMPL(qemuDomainAsyncJob,
"snapshot",
"start",
"backup",
+ "hotpatch",
);
VIR_ENUM_IMPL(qemuDomainNamespace,
@@ -217,6 +218,7 @@ qemuDomainAsyncJobPhaseToString(qemuDomainAsyncJob job,
case QEMU_ASYNC_JOB_START:
case QEMU_ASYNC_JOB_NONE:
case QEMU_ASYNC_JOB_BACKUP:
+ case QEMU_ASYNC_JOB_HOTPATCH:
G_GNUC_FALLTHROUGH;
case QEMU_ASYNC_JOB_LAST:
break;
@@ -243,6 +245,7 @@ qemuDomainAsyncJobPhaseFromString(qemuDomainAsyncJob job,
case QEMU_ASYNC_JOB_START:
case QEMU_ASYNC_JOB_NONE:
case QEMU_ASYNC_JOB_BACKUP:
+ case QEMU_ASYNC_JOB_HOTPATCH:
G_GNUC_FALLTHROUGH;
case QEMU_ASYNC_JOB_LAST:
break;
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index cf19f4d101..678ddab624 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -107,6 +107,7 @@ typedef enum {
QEMU_ASYNC_JOB_SNAPSHOT,
QEMU_ASYNC_JOB_START,
QEMU_ASYNC_JOB_BACKUP,
+ QEMU_ASYNC_JOB_HOTPATCH,
QEMU_ASYNC_JOB_LAST
} qemuDomainAsyncJob;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index f6d99957a5..d4c5f073bb 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -13866,6 +13866,9 @@ static int qemuDomainAbortJob(virDomainPtr dom)
ret = 0;
break;
+ case QEMU_ASYNC_JOB_HOTPATCH:
+ break;
+
case QEMU_ASYNC_JOB_LAST:
default:
virReportEnumRangeError(qemuDomainAsyncJob, priv->job.asyncJob);
@@ -23180,6 +23183,7 @@ qemuDomainHotpatchManage(virDomainPtr domain,
unsigned int flags)
{
virDomainObjPtr vm;
+ virQEMUDriverPtr driver = domain->conn->privateData;
char *ret = NULL;
size_t len;
@@ -23188,6 +23192,12 @@ qemuDomainHotpatchManage(virDomainPtr domain,
if (!(vm = qemuDomainObjFromDomain(domain)))
goto cleanup;
+ if (qemuDomainObjBeginAsyncJob(driver, vm, QEMU_ASYNC_JOB_HOTPATCH,
+ VIR_DOMAIN_JOB_OPERATION_HOTPATCH, 0) < 0)
+ goto cleanup;
+
+ qemuDomainObjSetAsyncJobMask(vm, QEMU_JOB_DEFAULT_MASK);
+
switch (action) {
case VIR_DOMAIN_HOTPATCH_APPLY:
ret = qemuDomainHotpatchApply(vm, patch);
@@ -23214,6 +23224,9 @@ qemuDomainHotpatchManage(virDomainPtr domain,
if (len > 0)
ret[len - 1] = '\0';
+ endjob:
+ qemuDomainObjEndAsyncJob(driver, vm);
+
cleanup:
virDomainObjEndAPI(&vm);
return ret;
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 3f4627bd39..1665071eb3 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -1532,6 +1532,8 @@ qemuMigrationJobName(virDomainObjPtr vm)
return _("start job");
case QEMU_ASYNC_JOB_BACKUP:
return _("backup job");
+ case QEMU_ASYNC_JOB_HOTPATCH:
+ return _("hotpatch job");
case QEMU_ASYNC_JOB_LAST:
default:
return _("job");
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 9cf7242f31..818a72d8f9 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -3646,6 +3646,7 @@ qemuProcessRecoverJob(virQEMUDriverPtr driver,
priv->job.current->started = now;
break;
+ case QEMU_ASYNC_JOB_HOTPATCH:
case QEMU_ASYNC_JOB_NONE:
case QEMU_ASYNC_JOB_LAST:
break;
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 65d5c831ec..f643bd403e 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -6167,6 +6167,7 @@ VIR_ENUM_IMPL(virshDomainJobOperation,
N_("Snapshot revert"),
N_("Dump"),
N_("Backup"),
+ N_("Hotpatch"),
);
static const char *
--
2.27.0

View File

@ -0,0 +1,302 @@
From 3be8bb571d13795c2824dd6d2089035a1be6cf57 Mon Sep 17 00:00:00 2001
From: jiang-dawei15 <jiangdawei15@huawei.com>
Date: Wed, 26 Jan 2022 15:18:10 +0800
Subject: [PATCH] hotpatch: virsh support autoload mode
---
include/libvirt/libvirt-domain.h | 1 +
src/qemu/qemu_conf.c | 9 +++
src/qemu/qemu_conf.h | 1 +
src/qemu/qemu_driver.c | 5 ++
src/qemu/qemu_hotpatch.c | 122 +++++++++++++++++++++++++++++++
src/qemu/qemu_hotpatch.h | 3 +
src/qemu/qemu_process.c | 6 ++
tools/virsh-domain.c | 5 +-
8 files changed, 150 insertions(+), 2 deletions(-)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 2d6432cab2..4ab0c9c0b2 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -4997,6 +4997,7 @@ typedef enum {
VIR_DOMAIN_HOTPATCH_APPLY, /* Apply hotpatch */
VIR_DOMAIN_HOTPATCH_UNAPPLY, /* Unapply hotpatch */
VIR_DOMAIN_HOTPATCH_QUERY, /* Query hotpatch */
+ VIR_DOMAIN_HOTPATCH_AUTOLOAD, /* Autoload hotpatch */
# ifdef VIR_ENUM_SENTINELS
VIR_DOMAIN_HOTPATCH_LAST
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 809e8fe526..bd96ccb78e 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -1006,6 +1006,12 @@ virQEMUDriverConfigLoadCapsFiltersEntry(virQEMUDriverConfigPtr cfg,
return 0;
}
+static int
+virQEMUDriverConfigLoadHotpatchPathEntry(virQEMUDriverConfigPtr cfg,
+ virConfPtr conf)
+{
+ return virConfGetValueString(conf, "hotpatch_path", &cfg->hotpatchPath);
+}
int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg,
const char *filename,
@@ -1078,6 +1084,9 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg,
if (virQEMUDriverConfigLoadCapsFiltersEntry(cfg, conf) < 0)
return -1;
+ if (virQEMUDriverConfigLoadHotpatchPathEntry(cfg, conf) < 0)
+ return -1;
+
return 0;
}
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index 14f9b9e81e..f0124a0fe2 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -220,6 +220,7 @@ struct _virQEMUDriverConfig {
gid_t swtpm_group;
char **capabilityfilters;
+ char *hotpatchPath;
};
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virQEMUDriverConfig, virObjectUnref);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 2b24881f75..37b2c4a2da 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -23186,6 +23186,7 @@ qemuDomainHotpatchManage(virDomainPtr domain,
virQEMUDriverPtr driver = domain->conn->privateData;
char *ret = NULL;
size_t len;
+ g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
virCheckFlags(0, NULL);
@@ -23214,6 +23215,10 @@ qemuDomainHotpatchManage(virDomainPtr domain,
ret = qemuDomainHotpatchQuery(vm);
break;
+ case VIR_DOMAIN_HOTPATCH_AUTOLOAD:
+ ret = qemuDomainHotpatchAutoload(vm, cfg->hotpatchPath);
+ break;
+
default:
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("Unknow hotpatch action"));
diff --git a/src/qemu/qemu_hotpatch.c b/src/qemu/qemu_hotpatch.c
index 03e63c1341..02f511cc38 100644
--- a/src/qemu/qemu_hotpatch.c
+++ b/src/qemu/qemu_hotpatch.c
@@ -25,6 +25,8 @@
#include "virerror.h"
#include "virfile.h"
#include "virlog.h"
+#include "virbuffer.h"
+#include "virstring.h"
#include "vircommand.h"
#include "qemu/qemu_domain.h"
#include "qemu_hotpatch.h"
@@ -32,6 +34,7 @@
#define LIBCARE_CTL "libcare-ctl"
#define LIBCARE_ERROR_NUMBER 255
#define MAX_PATCHID_LEN 8
+#define MAX_FILE_SIZE (1024*1024)
#define VIR_FROM_THIS VIR_FROM_QEMU
@@ -204,3 +207,122 @@ qemuDomainHotpatchUnapply(virDomainObjPtr vm,
VIR_FREE(output);
return NULL;
}
+
+char *
+qemuDomainHotpatchAutoload(virDomainObjPtr vm, char *hotpatch_path)
+{
+ VIR_AUTOSTRINGLIST applied_patches = NULL;
+ VIR_AUTOSTRINGLIST lines = NULL;
+ g_autofree char *applied_patch = NULL;
+ g_autofree char *libvirtd_conf = NULL;
+ g_autofree char *patch_conf = NULL;
+ g_autofree char *buf = NULL;
+ char *ret = NULL;
+ int i, j, len;
+
+ if (hotpatch_path == NULL) {
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("Invalid hotpatch path."));
+ return NULL;
+ }
+
+ /* get hotpatch info from Patch.conf */
+ patch_conf = g_strdup_printf("%s/Patch.conf", hotpatch_path);
+ if ((len = virFileReadAll(patch_conf, MAX_FILE_SIZE, &buf)) < 0) {
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("Failed to read Patch.conf file."));
+ return NULL;
+ }
+ if (len > 0)
+ buf[len-1] = '\0';
+
+ lines = virStringSplit(buf, "\n", 0);
+ if (!lines)
+ return NULL;
+
+ /* get domain hotpatch infomation */
+ applied_patch = qemuDomainHotpatchQuery(vm);
+ if (!applied_patch)
+ return NULL;
+
+ applied_patches = virStringSplit(applied_patch, "\n", 0);
+ if (!applied_patches)
+ return NULL;
+
+ /* load all hotpatch which are listed in Patch.conf one by one */
+ for (i = 0; lines[i] != NULL; i++) {
+ VIR_AUTOSTRINGLIST patch_info = NULL;
+ g_autofree char *kpatch_dir = NULL;
+ g_autofree char *file_path = NULL;
+ struct dirent *de;
+ DIR *dh;
+ int direrr;
+
+ if (!strstr(lines[i], "QEMU-"))
+ continue;
+
+ patch_info = virStringSplit(lines[i], " ", 0);
+ if (!patch_info)
+ continue;
+
+ /* skip already applied patch */
+ if (strstr(applied_patch, patch_info[2]))
+ continue;
+
+ /* get the kpatch file name */
+ kpatch_dir = g_strdup_printf("%s/%s", hotpatch_path, patch_info[1]);
+ if (!kpatch_dir || !virFileExists(kpatch_dir))
+ return NULL;
+
+ if (virDirOpen(&dh, kpatch_dir) < 0)
+ return NULL;
+ if ((direrr = virDirRead(dh, &de, kpatch_dir)) > 0) {
+ GStatBuf sb;
+
+ file_path = g_strdup_printf("%s/%s", kpatch_dir, de->d_name);
+ if (g_lstat(file_path, &sb) < 0) {
+ virReportSystemError(errno, _("Cannot access '%s'"),
+ file_path);
+ VIR_DIR_CLOSE(dh);
+ return NULL;
+ }
+ }
+ VIR_DIR_CLOSE(dh);
+
+ if (qemuDomainHotpatchApply(vm, file_path) == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("failed to apply the hotpatch."));
+ return NULL;
+ }
+ }
+
+ /* unload the hotpatch which are not listed in Patch.conf */
+ for (i = 0; applied_patches[i] != NULL; i++) {
+ const char *patch_id = NULL;
+ bool is_need_unload = true;
+
+ if (!strstr(applied_patches[i], "Patch id"))
+ continue;
+
+ patch_id = strstr(applied_patches[i], ":") + 1;
+ virSkipSpaces(&patch_id);
+
+ for (j = 0; lines[j] != NULL; j++) {
+ if (!strstr(lines[j], "QEMU-"))
+ continue;
+ if (strstr(lines[j], patch_id)) {
+ is_need_unload = false;
+ break;
+ }
+ }
+ if (is_need_unload == true)
+ if (qemuDomainHotpatchUnapply(vm, patch_id) == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("failed to unapply the hotpatch."));
+ return NULL;
+ }
+ }
+
+ ret = g_strdup_printf("Hotpatch autoload successfully.\n");
+ return ret;
+}
diff --git a/src/qemu/qemu_hotpatch.h b/src/qemu/qemu_hotpatch.h
index 4c84a57950..8e0bfe348a 100644
--- a/src/qemu/qemu_hotpatch.h
+++ b/src/qemu/qemu_hotpatch.h
@@ -34,3 +34,6 @@ qemuDomainHotpatchApply(virDomainObjPtr vm,
char *
qemuDomainHotpatchUnapply(virDomainObjPtr vm,
const char *id);
+
+char *
+qemuDomainHotpatchAutoload(virDomainObjPtr vm, char *path_config);
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 818a72d8f9..24dd9f052c 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -59,6 +59,7 @@
#include "qemu_firmware.h"
#include "qemu_backup.h"
#include "qemu_dbus.h"
+#include "qemu_hotpatch.h"
#include "cpu/cpu.h"
#include "cpu/cpu_x86.h"
@@ -6684,6 +6685,7 @@ qemuProcessLaunch(virConnectPtr conn,
g_autoptr(virQEMUDriverConfig) cfg = NULL;
size_t nnicindexes = 0;
g_autofree int *nicindexes = NULL;
+ g_autofree char *autoLoadStatus = NULL;
size_t i;
VIR_DEBUG("conn=%p driver=%p vm=%p name=%s if=%d asyncJob=%d "
@@ -6993,6 +6995,10 @@ qemuProcessLaunch(virConnectPtr conn,
qemuProcessAutoDestroyAdd(driver, vm, conn) < 0)
goto cleanup;
+ /* Autoload hotpatch */
+ if ((autoLoadStatus = qemuDomainHotpatchAutoload(vm, cfg->hotpatchPath)) == NULL) {
+ VIR_WARN("Failed to autoload the hotpatch for %s.", vm->def->name);
+ }
ret = 0;
cleanup:
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 813be4a0db..b5375ebd3e 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -14344,7 +14344,7 @@ static const vshCmdOptDef opts_hotpatch[] = {
{.name = "action",
.type = VSH_OT_DATA,
.flags = VSH_OFLAG_REQ,
- .help = N_("hotpatch action, choose from <apply>, <unapply> and <query>")
+ .help = N_("hotpatch action, choose from <apply>, <unapply>, <query> and <autoload>")
},
{.name = "patch",
.type = VSH_OT_STRING,
@@ -14363,7 +14363,8 @@ VIR_ENUM_IMPL(virDomainHotpatchAction,
"none",
"apply",
"unapply",
- "query");
+ "query",
+ "autoload");
static bool
cmdHotpatch(vshControl *ctl,
--
2.30.0

View File

@ -48,11 +48,7 @@
%define with_storage_zfs 0
%endif
%ifarch aarch64
%define arg_dtrace --without-dtrace
%else
%define arg_dtrace --with-dtrace
%endif
# We need a recent enough libiscsi (>= 1.18.0)
%define with_storage_iscsi_direct 0%{!?_without_storage_iscsi_direct:1}
@ -105,7 +101,7 @@
Summary: Library providing a simple virtualization API
Name: libvirt
Version: 6.2.0
Release: 26
Release: 34
License: LGPLv2+
URL: https://libvirt.org/
@ -190,6 +186,49 @@ Patch0073: virDevMapperGetTargets-Don-t-ignore-EBADF.patch
Patch0074: conf-domain_conf-pin-the-retry_interval-and-retry_ti.patch
Patch0075: storage_driver-Unlock-object-on-ACL-fail-in-storageP.patch
Patch0076: security-fix-SELinux-label-generation-logic.patch
Patch0077: Hotpatch-introduce-DomainHotpatchManage-API.patch
Patch0078: hotpatch-Implement-qemuDomainHotpatchManage.patch
Patch0079: hotpatch-introduce-hotpatch-async-job-flag.patch
Patch0080: hotpatch-implement-hotpatch-virsh-api.patch
Patch0081: hotpatch-check-vm-id-and-pid-before-using-hotpatch-a.patch
Patch0082: domain-add-logs-for-virDomainHotpatchManage.patch
Patch0083: docs-build-Don-t-include-stylesheet-in-intermediate-.patch
Patch0084: tests-Replace-deprecated-ASN1-code.patch
Patch0085: tests-disabale-storage-tests.patch
Patch0086: Revert-tests-disabale-storage-tests.patch
Patch0087: hotpatch-virsh-support-autoload-mode.patch
Patch0088: virQEMUBuildCommandLineJSON-Allow-skipping-certain-k.patch
Patch0089: virQEMUBuildCommandLineJSON-Add-possibility-for-usin.patch
Patch0090: util-virqemu-Introduce-virQEMUBuildNetdevCommandline.patch
Patch0091: util-json-Introduce-virJSONValueObjectAppendStringPr.patch
Patch0092: qemuBuildChannelsCommandLine-Use-typecasted-switch-f.patch
Patch0093: qemuBuildChannelsCommandLine-Extract-common-formatti.patch
Patch0094: qemuBuildChannelChrDeviceStr-Remove-formatting-of-pr.patch
Patch0095: qemuMonitorJSON-Add-Remove-Netdev-Refactor-cleanup.patch
Patch0096: qemuBuildHostNetStr-Stop-using-ipv6-net-convenience-.patch
Patch0097: qemu-command-Generate-netdev-command-line-via-JSON-c.patch
Patch0098: qemuBuildChannelGuestfwdNetdevProps-Convert-to-gener.patch
Patch0099: qemuMonitorAddNetdev-Convert-to-the-native-JSON-prop.patch
Patch0100: virCommand-Introduce-virCommandGetArgList.patch
Patch0101: testutilsqemuschema-Introduce-testQEMUSchemaValidate.patch
Patch0102: testCompareXMLToArgv-Split-out-preparation-and-comma.patch
Patch0103: virQEMUBuildNetdevCommandlineFromJSON-Prepare-for-qu.patch
Patch0104: qemu-Prepare-for-testing-of-netdev_add-props-via-qem.patch
Patch0105: qemuxml2argvtest-Add-QAPI-QMP-schema-validation-for-.patch
Patch0106: qemu-Probe-for-a-few-params-supported-by-migrate-set.patch
Patch0107: qemu-Avoid-deprecated-migrate_set_speed-QMP-command.patch
Patch0108: qemu-Avoid-deprecated-migrate_set_downtime-QMP-comma.patch
Patch0109: qemu-Avoid-deprecated-query-migrate-cache-size-QMP-c.patch
Patch0110: qemu-Avoid-deprecated-migrate-set-cache-size-QMP-com.patch
Patch0111: qemu-Track-numa-mem-supported-machine-attribute.patch
Patch0112: qemuBuildNumaArgStr-Switch-order-of-if-and-for.patch
Patch0113: qemuBuildNumaArgStr-Use-modern-numa-memdev-if-old-nu.patch
Patch0114: Revert-libvirt-support-aarch64-vtpm-with-parameter-t.patch
Patch0115: qemu-Fix-swtpm-device-with-aarch64.patch
Patch0116: qemu-Fix-libvirt-hang-due-to-early-TPM-device-stop.patch
Patch0117: qemu_tpm-Move-logfile-path-generation-into-a-separat.patch
Patch0118: qemu_tpm-Generate-log-file-path-among-with-storage-p.patch
Patch0119: virtpm-Fix-path-handling-in-virTPMEmulatorInit.patch
Requires: libvirt-daemon = %{version}-%{release}
Requires: libvirt-daemon-config-network = %{version}-%{release}
@ -294,6 +333,7 @@ BuildRequires: librados-devel
BuildRequires: librbd-devel
%endif
%if %{with_storage_gluster}
BuildRequires: libgfapi0
BuildRequires: glusterfs-api-devel >= 3.4.1
BuildRequires: glusterfs-devel >= 3.4.1
%endif
@ -1235,7 +1275,7 @@ rm -f $RPM_BUILD_ROOT%{_datadir}/augeas/lenses/tests/test_libvirtd_libxl.aug
# Copied into libvirt-docs subpackage eventually
mv $RPM_BUILD_ROOT%{_datadir}/doc/libvirt libvirt-docs
%ifarch %{power64} s390x x86_64 ia64 alpha sparc64
%ifarch %{power64} s390x ia64 alpha sparc64
mv $RPM_BUILD_ROOT%{_datadir}/systemtap/tapset/libvirt_probes.stp \
$RPM_BUILD_ROOT%{_datadir}/systemtap/tapset/libvirt_probes-64.stp
@ -1801,7 +1841,7 @@ exit 0
%{_bindir}/virt-pki-validate
%{_bindir}/virt-host-validate
%ifnarch aarch64
%ifnarch aarch64 x86_64
%{_datadir}/systemtap/tapset/libvirt_probes*.stp
%{_datadir}/systemtap/tapset/libvirt_functions.stp
%if %{with_qemu}
@ -1923,6 +1963,67 @@ exit 0
%changelog
* Sat Mar 12 2022 yezengruan <yezengruan@huawei.com>
- Revert libvirt: support aarch64 vtpm with parameter tpm-tis-device
- qemu: Fix swtpm device with aarch64
- qemu: Fix libvirt hang due to early TPM device stop
- qemu_tpm: Move logfile path generation into a separate function
- qemu_tpm: Generate log file path among with storage path
- virtpm: Fix @path handling in virTPMEmulatorInit()
* Fri Mar 11 2022 yezengruan <yezengruan@huawei.com>
- qemu: Probe for a few params supported by migrate-set-parameters
- qemu: Avoid deprecated migrate_set_speed QMP command
- qemu: Avoid deprecated migrate_set_downtime QMP command
- qemu: Avoid deprecated query-migrate-cache-size QMP command
- qemu: Avoid deprecated migrate-set-cache-size QMP command
- qemu: Track numa-mem-supported machine attribute
- qemuBuildNumaArgStr: Switch order of if() and for()
- qemuBuildNumaArgStr: Use modern -numa memdev= if old -numa mem= is unsupported
* Mon Feb 21 2022 imxcc <xingchaochao@huawei.com>
- virQEMUBuildCommandLineJSON: Allow skipping certain keys
- virQEMUBuildCommandLineJSON: Add possibility for using 'on/off' instead of 'yes/no'
- util: virqemu: Introduce virQEMUBuildNetdevCommandlineFromJSON
- util: json: Introduce virJSONValueObjectAppendStringPrintf
- qemuBuildChannelsCommandLine: Use typecasted switch for channel type
- qemuBuildChannelsCommandLine: Extract common formatting of 'chardev'
- qemuBuildChannelChrDeviceStr: Remove formatting of properties for -netdev
- qemuMonitorJSON(Add|Remove)Netdev: Refactor cleanup
- qemuBuildHostNetStr: Stop using 'ipv6-net' convenience argument
- qemu: command: Generate -netdev command line via JSON->cmdline conversion
- qemuBuildChannelGuestfwdNetdevProps: Convert to generating JSON props
- qemuMonitorAddNetdev: Convert to the native JSON props object
- virCommand: Introduce virCommandGetArgList
- testutilsqemuschema: Introduce testQEMUSchemaValidateCommand
- testCompareXMLToArgv: Split out preparation and command formatting
- virQEMUBuildNetdevCommandlineFromJSON: Prepare for quirky 'guestfwd'
- qemu: Prepare for testing of 'netdev_add' props via qemuxml2argvtest
- qemuxml2argvtest: Add QAPI/QMP schema validation for -blockdev and -netdev
* Sat Feb 12 2022 imxcc <xingchaochao@huawei.com>
- hotpatch: virsh support autoload mode
* Fri Jan 29 2022 imxcc <xingchaochao@huawei.com>
- Revert "tests: disabale storage tests"
* Fri Jan 14 2022 imxcc <xingchaochao@huawei.com>
- tests: disabale storage tests
* Tue Jan 11 2022 imxcc <xingchaochao@huawei.com>
- docs: build: Don't include stylesheet in intermediate html
- tests: Replace deprecated ASN1 code
* Mon Dec 06 2021 Euler Robot <euler.robot@huawei.com>
- hotpatch: implement hotpatch virsh api
- hotpatch: check vm id and pid before using hotpatch api
- domain: add logs for virDomainHotpatchManage
* Mon Dec 06 2021 Euler Robot <euler.robot@huawei.com>
- Hotpatch: introduce DomainHotpatchManage API
- hotpatch: Implement qemuDomainHotpatchManage
- hotpatch: introduce hotpatch async job flag
* Sun Sep 26 2021 imxcc <xingchaochao@huawei.com>
- fix cve-2021-3667 cve-2021-3631

View File

@ -0,0 +1,81 @@
From 4fe1ead5da84610bba30cae9315ff38de765711f Mon Sep 17 00:00:00 2001
From: Jiri Denemark <jdenemar@redhat.com>
Date: Wed, 10 Jun 2020 16:13:15 +0200
Subject: [PATCH 5/8] qemu: Avoid deprecated migrate-set-cache-size QMP command
The same functionality can be achieved using migrate-set-parameters QMP
command with xbzrle-cache-size parameter.
https://bugzilla.redhat.com/show_bug.cgi?id=1845012
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
---
src/qemu/qemu_driver.c | 26 +++++++++++++++++++++-----
src/qemu/qemu_migration_params.c | 3 +--
2 files changed, 22 insertions(+), 7 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 1ad33197e0..e7166e4af3 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -14067,7 +14067,9 @@ qemuDomainMigrateSetCompressionCache(virDomainPtr dom,
virQEMUDriverPtr driver = dom->conn->privateData;
virDomainObjPtr vm;
qemuDomainObjPrivatePtr priv;
+ g_autoptr(qemuMigrationParams) migParams = NULL;
int ret = -1;
+ int rc;
virCheckFlags(0, -1);
@@ -14092,13 +14094,27 @@ qemuDomainMigrateSetCompressionCache(virDomainPtr dom,
goto endjob;
}
- qemuDomainObjEnterMonitor(driver, vm);
-
VIR_DEBUG("Setting compression cache to %llu B", cacheSize);
- ret = qemuMonitorSetMigrationCacheSize(priv->mon, cacheSize);
+ if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_PARAM_XBZRLE_CACHE_SIZE)) {
+ if (!(migParams = qemuMigrationParamsNew()))
+ goto endjob;
- if (qemuDomainObjExitMonitor(driver, vm) < 0)
- ret = -1;
+ if (qemuMigrationParamsSetULL(migParams,
+ QEMU_MIGRATION_PARAM_XBZRLE_CACHE_SIZE,
+ cacheSize) < 0)
+ goto endjob;
+
+ if (qemuMigrationParamsApply(driver, vm, QEMU_ASYNC_JOB_NONE,
+ migParams) < 0)
+ goto endjob;
+ } else {
+ qemuDomainObjEnterMonitor(driver, vm);
+ rc = qemuMonitorSetMigrationCacheSize(priv->mon, cacheSize);
+ if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
+ goto endjob;
+ }
+
+ ret = 0;
endjob:
qemuDomainObjEndJob(driver, vm);
diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c
index 810199370f..6953badcfe 100644
--- a/src/qemu/qemu_migration_params.c
+++ b/src/qemu/qemu_migration_params.c
@@ -869,8 +869,7 @@ qemuMigrationParamsApply(virQEMUDriverPtr driver,
* qemuMonitorSetMigrationParams to ignore this parameter.
*/
if (migParams->params[xbzrle].set &&
- (!priv->job.migParams ||
- !priv->job.migParams->params[xbzrle].set)) {
+ !virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_PARAM_XBZRLE_CACHE_SIZE)) {
if (qemuMonitorSetMigrationCacheSize(priv->mon,
migParams->params[xbzrle].value.ull) < 0)
goto cleanup;
--
2.27.0

View File

@ -0,0 +1,65 @@
From df9385f88c666783c7ac53800f00e359a4177145 Mon Sep 17 00:00:00 2001
From: Jiri Denemark <jdenemar@redhat.com>
Date: Wed, 10 Jun 2020 16:13:15 +0200
Subject: [PATCH 3/8] qemu: Avoid deprecated migrate_set_downtime QMP command
The same functionality can be achieved using migrate-set-parameters QMP
command with downtime-limit parameter.
https://bugzilla.redhat.com/show_bug.cgi?id=1829543
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
---
src/qemu/qemu_driver.c | 27 +++++++++++++++++++++++----
1 file changed, 23 insertions(+), 4 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 1521bc6b2b..3482dccc43 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -13892,7 +13892,9 @@ qemuDomainMigrateSetMaxDowntime(virDomainPtr dom,
virQEMUDriverPtr driver = dom->conn->privateData;
virDomainObjPtr vm;
qemuDomainObjPrivatePtr priv;
+ g_autoptr(qemuMigrationParams) migParams = NULL;
int ret = -1;
+ int rc;
virCheckFlags(0, -1);
@@ -13911,10 +13913,27 @@ qemuDomainMigrateSetMaxDowntime(virDomainPtr dom,
priv = vm->privateData;
VIR_DEBUG("Setting migration downtime to %llums", downtime);
- qemuDomainObjEnterMonitor(driver, vm);
- ret = qemuMonitorSetMigrationDowntime(priv->mon, downtime);
- if (qemuDomainObjExitMonitor(driver, vm) < 0)
- ret = -1;
+
+ if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_PARAM_DOWNTIME)) {
+ if (!(migParams = qemuMigrationParamsNew()))
+ goto endjob;
+
+ if (qemuMigrationParamsSetULL(migParams,
+ QEMU_MIGRATION_PARAM_DOWNTIME_LIMIT,
+ downtime) < 0)
+ goto endjob;
+
+ if (qemuMigrationParamsApply(driver, vm, QEMU_ASYNC_JOB_NONE,
+ migParams) < 0)
+ goto endjob;
+ } else {
+ qemuDomainObjEnterMonitor(driver, vm);
+ rc = qemuMonitorSetMigrationDowntime(priv->mon, downtime);
+ if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
+ goto endjob;
+ }
+
+ ret = 0;
endjob:
qemuDomainObjEndJob(driver, vm);
--
2.27.0

View File

@ -0,0 +1,174 @@
From d72c84f9369152d0ca69fb201d4ae41ee559a94b Mon Sep 17 00:00:00 2001
From: Jiri Denemark <jdenemar@redhat.com>
Date: Wed, 10 Jun 2020 16:13:15 +0200
Subject: [PATCH 2/8] qemu: Avoid deprecated migrate_set_speed QMP command
The same functionality can be achieved using migrate-set-parameters QMP
command with max-bandwidth parameter.
https://bugzilla.redhat.com/show_bug.cgi?id=1829545
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
---
src/qemu/qemu_driver.c | 18 ++++++++++---
src/qemu/qemu_migration.c | 53 +++++++++++++++++++++++++++++++--------
2 files changed, 57 insertions(+), 14 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 21e9a8760e..1521bc6b2b 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -14086,6 +14086,7 @@ qemuDomainMigrateSetMaxSpeed(virDomainPtr dom,
qemuDomainObjPrivatePtr priv;
bool postcopy = !!(flags & VIR_DOMAIN_MIGRATE_MAX_SPEED_POSTCOPY);
g_autoptr(qemuMigrationParams) migParams = NULL;
+ bool bwParam;
unsigned long long max;
int ret = -1;
@@ -14124,12 +14125,20 @@ qemuDomainMigrateSetMaxSpeed(virDomainPtr dom,
VIR_DEBUG("Setting migration bandwidth to %luMbs", bandwidth);
- if (postcopy) {
+ bwParam = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_PARAM_BANDWIDTH);
+
+ if (postcopy || bwParam) {
+ qemuMigrationParam param;
+
if (!(migParams = qemuMigrationParamsNew()))
goto endjob;
- if (qemuMigrationParamsSetULL(migParams,
- QEMU_MIGRATION_PARAM_MAX_POSTCOPY_BANDWIDTH,
+ if (postcopy)
+ param = QEMU_MIGRATION_PARAM_MAX_POSTCOPY_BANDWIDTH;
+ else
+ param = QEMU_MIGRATION_PARAM_MAX_BANDWIDTH;
+
+ if (qemuMigrationParamsSetULL(migParams, param,
bandwidth * 1024 * 1024) < 0)
goto endjob;
@@ -14143,9 +14152,10 @@ qemuDomainMigrateSetMaxSpeed(virDomainPtr dom,
rc = qemuMonitorSetMigrationSpeed(priv->mon, bandwidth);
if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
goto endjob;
+ }
+ if (!postcopy)
priv->migMaxBandwidth = bandwidth;
- }
ret = 0;
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 1665071eb3..cd40a886e3 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -3507,6 +3507,7 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver,
unsigned int cookieFlags = 0;
bool abort_on_error = !!(flags & VIR_MIGRATE_ABORT_ON_ERROR);
bool events = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT);
+ bool bwParam = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_PARAM_BANDWIDTH);
bool cancel = false;
unsigned int waitFlags;
virDomainDefPtr persistDef = NULL;
@@ -3594,6 +3595,11 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver,
goto error;
}
+ if (bwParam &&
+ qemuMigrationParamsSetULL(migParams, QEMU_MIGRATION_PARAM_MAX_BANDWIDTH,
+ migrate_speed * 1024 * 1024) < 0)
+ goto error;
+
if (qemuMigrationParamsApply(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT,
migParams) < 0)
goto error;
@@ -3656,7 +3662,8 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver,
goto exit_monitor;
}
- if (qemuMonitorSetMigrationSpeed(priv->mon, migrate_speed) < 0)
+ if (!bwParam &&
+ qemuMonitorSetMigrationSpeed(priv->mon, migrate_speed) < 0)
goto exit_monitor;
/* connect to the destination qemu if needed */
@@ -5311,24 +5318,41 @@ qemuMigrationSrcToFile(virQEMUDriverPtr driver, virDomainObjPtr vm,
qemuDomainAsyncJob asyncJob)
{
qemuDomainObjPrivatePtr priv = vm->privateData;
+ bool bwParam = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_PARAM_BANDWIDTH);
int rc;
int ret = -1;
int pipeFD[2] = { -1, -1 };
unsigned long saveMigBandwidth = priv->migMaxBandwidth;
char *errbuf = NULL;
virErrorPtr orig_err = NULL;
+ g_autoptr(qemuMigrationParams) migParams = NULL;
if (qemuMigrationSetDBusVMState(driver, vm) < 0)
return -1;
/* Increase migration bandwidth to unlimited since target is a file.
* Failure to change migration speed is not fatal. */
- if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) == 0) {
- qemuMonitorSetMigrationSpeed(priv->mon,
- QEMU_DOMAIN_MIG_BANDWIDTH_MAX);
- priv->migMaxBandwidth = QEMU_DOMAIN_MIG_BANDWIDTH_MAX;
- if (qemuDomainObjExitMonitor(driver, vm) < 0)
+ if (bwParam) {
+ if (!(migParams = qemuMigrationParamsNew()))
+ return -1;
+
+ if (qemuMigrationParamsSetULL(migParams,
+ QEMU_MIGRATION_PARAM_MAX_BANDWIDTH,
+ QEMU_DOMAIN_MIG_BANDWIDTH_MAX * 1024 * 1024) < 0)
+ return -1;
+
+ if (qemuMigrationParamsApply(driver, vm, asyncJob, migParams) < 0)
return -1;
+
+ priv->migMaxBandwidth = QEMU_DOMAIN_MIG_BANDWIDTH_MAX;
+ } else {
+ if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) == 0) {
+ qemuMonitorSetMigrationSpeed(priv->mon,
+ QEMU_DOMAIN_MIG_BANDWIDTH_MAX);
+ priv->migMaxBandwidth = QEMU_DOMAIN_MIG_BANDWIDTH_MAX;
+ if (qemuDomainObjExitMonitor(driver, vm) < 0)
+ return -1;
+ }
}
if (!virDomainObjIsActive(vm)) {
@@ -5409,11 +5433,20 @@ qemuMigrationSrcToFile(virQEMUDriverPtr driver, virDomainObjPtr vm,
virErrorPreserveLast(&orig_err);
/* Restore max migration bandwidth */
- if (virDomainObjIsActive(vm) &&
- qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) == 0) {
- qemuMonitorSetMigrationSpeed(priv->mon, saveMigBandwidth);
+ if (virDomainObjIsActive(vm)) {
+ if (bwParam) {
+ if (qemuMigrationParamsSetULL(migParams,
+ QEMU_MIGRATION_PARAM_MAX_BANDWIDTH,
+ saveMigBandwidth * 1024 * 1024) == 0)
+ ignore_value(qemuMigrationParamsApply(driver, vm, asyncJob,
+ migParams));
+ } else {
+ if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) == 0) {
+ qemuMonitorSetMigrationSpeed(priv->mon, saveMigBandwidth);
+ ignore_value(qemuDomainObjExitMonitor(driver, vm));
+ }
+ }
priv->migMaxBandwidth = saveMigBandwidth;
- ignore_value(qemuDomainObjExitMonitor(driver, vm));
}
VIR_FORCE_CLOSE(pipeFD[0]);
--
2.27.0

View File

@ -0,0 +1,62 @@
From c458102192d82a3a8a5f045cd9df34c29b287ab8 Mon Sep 17 00:00:00 2001
From: Jiri Denemark <jdenemar@redhat.com>
Date: Wed, 10 Jun 2020 16:13:15 +0200
Subject: [PATCH 4/8] qemu: Avoid deprecated query-migrate-cache-size QMP
command
The same functionality can be achieved using query-migrate-parameters
QMP command and checking the xbzrle-cache-size parameter.
https://bugzilla.redhat.com/show_bug.cgi?id=1829544
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
---
src/qemu/qemu_driver.c | 21 +++++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 3482dccc43..1ad33197e0 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -14006,7 +14006,9 @@ qemuDomainMigrateGetCompressionCache(virDomainPtr dom,
virQEMUDriverPtr driver = dom->conn->privateData;
virDomainObjPtr vm;
qemuDomainObjPrivatePtr priv;
+ g_autoptr(qemuMigrationParams) migParams = NULL;
int ret = -1;
+ int rc;
virCheckFlags(0, -1);
@@ -14031,12 +14033,23 @@ qemuDomainMigrateGetCompressionCache(virDomainPtr dom,
goto endjob;
}
- qemuDomainObjEnterMonitor(driver, vm);
+ if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_PARAM_XBZRLE_CACHE_SIZE)) {
+ if (qemuMigrationParamsFetch(driver, vm, QEMU_ASYNC_JOB_NONE,
+ &migParams) < 0)
+ goto endjob;
- ret = qemuMonitorGetMigrationCacheSize(priv->mon, cacheSize);
+ if (qemuMigrationParamsGetULL(migParams,
+ QEMU_MIGRATION_PARAM_XBZRLE_CACHE_SIZE,
+ cacheSize) < 0)
+ goto endjob;
+ } else {
+ qemuDomainObjEnterMonitor(driver, vm);
+ rc = qemuMonitorGetMigrationCacheSize(priv->mon, cacheSize);
+ if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
+ goto endjob;
+ }
- if (qemuDomainObjExitMonitor(driver, vm) < 0)
- ret = -1;
+ ret = 0;
endjob:
qemuDomainObjEndJob(driver, vm);
--
2.27.0

View File

@ -0,0 +1,51 @@
From 6d4e247786117b0b9b57722778c26328993a8f52 Mon Sep 17 00:00:00 2001
From: Stefan Berger <stefanb@linux.vnet.ibm.com>
Date: Fri, 19 Feb 2021 10:57:41 -0500
Subject: [PATCH 3/6] qemu: Fix libvirt hang due to early TPM device stop
This patch partially reverts commit 5cde9dee where the qemuExtDevicesStop()
was moved to a location before the QEMU process is stopped. It may be
alright to tear down some devices before QEMU is stopped, but it doesn't work
for the external TPM (swtpm) which assumes that QEMU sends it a signal to stop
it before libvirt may try to clean it up. So this patch moves the
virFileDeleteTree() calls after the call to qemuExtDevicesStop() so that the
pid file of virtiofsd is not deleted before that call.
Afftected libvirt versions are 6.10 and 7.0.
Fixes: 5cde9dee8c70b17c458d031ab6cf71dce476eea2
Cc: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Signed-off-by: yezengruan <yezengruan@huawei.com>
---
src/qemu/qemu_process.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 4f7bd0586d..d9209ac6d2 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -7410,9 +7410,6 @@ void qemuProcessStop(virQEMUDriverPtr driver,
/* Do this before we delete the tree and remove pidfile. */
qemuProcessKillManagedPRDaemon(vm);
- virFileDeleteTree(priv->libDir);
- virFileDeleteTree(priv->channelTargetDir);
-
ignore_value(virDomainChrDefForeach(vm->def,
false,
qemuProcessCleanupChardevDevice,
@@ -7432,6 +7429,9 @@ void qemuProcessStop(virQEMUDriverPtr driver,
vm->def->id = -1;
+ virFileDeleteTree(priv->libDir);
+ virFileDeleteTree(priv->channelTargetDir);
+
/* Stop autodestroy in case guest is restarted */
qemuProcessAutoDestroyRemove(driver, vm);
--
2.27.0

View File

@ -0,0 +1,208 @@
From 2480d7857c6ea384567009840040b900f5440616 Mon Sep 17 00:00:00 2001
From: Jim Fehlig <jfehlig@suse.com>
Date: Tue, 9 Feb 2021 14:57:22 -0700
Subject: [PATCH 2/6] qemu: Fix swtpm device with aarch64
Starting a VM with swtpm device fails with qemu-system-aarch64.
E.g. with TPM device config
<tpm model='tpm-tis'>
<backend type='emulator' version='2.0'/>
</tpm>
QEMU reports the following error
error: internal error: process exited while connecting to monitor:
2021-02-07T05:15:35.378927Z qemu-system-aarch64: -device
tpm-tis,tpmdev=tpm-tpm0,id=tpm0: 'tpm-tis' is not a valid device model name
Indeed the TPM device name is 'tpm-tis-device' [1][2] for aarch64,
versus the shorter 'tpm-tis' for x86. The devices are the same from
a functional POV, i.e. they both emulate a TPM device conforming to
the TIS specification. Account for the unfortunate name difference
when building the TPM device option in qemuBuildTPMDevStr(). Also
include a test case for 'tpm-tis-device'.
[1] https://qemu.readthedocs.io/en/latest/specs/tpm.html
[2] https://github.com/qemu/qemu/commit/c294ac327ca99342b90bd3a83d2cef9b447afaa7
Signed-off-by: Jim Fehlig <jfehlig@suse.com>
Reviewed-by: Andrea Bolognani <abologna@redhat.com>
Signed-off-by: yezengruan <yezengruan@huawei.com>
---
src/qemu/qemu_command.c | 3 ++
.../caps_5.0.0.aarch64.replies | 15 ++++++++
.../caps_5.0.0.aarch64.xml | 3 ++
.../aarch64-tpm.aarch64-latest.args | 35 +++++++++++++++++++
tests/qemuxml2argvdata/aarch64-tpm.xml | 15 ++++++++
tests/qemuxml2argvtest.c | 1 +
6 files changed, 72 insertions(+)
create mode 100644 tests/qemuxml2argvdata/aarch64-tpm.aarch64-latest.args
create mode 100644 tests/qemuxml2argvdata/aarch64-tpm.xml
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index f8331a7455..d5d46c0892 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -9232,6 +9232,9 @@ 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)
+ model = "tpm-tis-device";
+
virBufferAsprintf(&buf, "%s,tpmdev=tpm-%s,id=%s",
model, tpm->info.alias, tpm->info.alias);
diff --git a/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.replies b/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.replies
index a3136a0966..e848860e45 100644
--- a/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.replies
+++ b/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.replies
@@ -2734,6 +2734,10 @@
"name": "armv7m_systick",
"parent": "sys-bus-device"
},
+ {
+ "name": "tpm-emulator",
+ "parent": "tpm-backend"
+ },
{
"name": "imx6ul.ccm",
"parent": "imx.ccm"
@@ -3198,6 +3202,10 @@
"name": "authz-list",
"parent": "authz"
},
+ {
+ "name": "tpm-passthrough",
+ "parent": "tpm-backend"
+ },
{
"name": "xlnx.ps7-spi",
"parent": "sys-bus-device"
@@ -3286,6 +3294,10 @@
"name": "bcm2835-peripherals",
"parent": "sys-bus-device"
},
+ {
+ "name": "tpm-tis-device",
+ "parent": "sys-bus-device"
+ },
{
"name": "arm-its-kvm",
"parent": "arm-gicv3-its-common"
@@ -7768,6 +7780,7 @@
{
"return": [
+ "tpm-tis"
],
"id": "libvirt-36"
}
@@ -7779,6 +7792,8 @@
{
"return": [
+ "passthrough",
+ "emulator"
],
"id": "libvirt-37"
}
diff --git a/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml
index 92ad10c9b8..af282f33c1 100644
--- a/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml
+++ b/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml
@@ -42,6 +42,8 @@
<flag name='rng-random'/>
<flag name='rng-egd'/>
<flag name='megasas'/>
+ <flag name='tpm-passthrough'/>
+ <flag name='tpm-tis'/>
<flag name='pci-bridge'/>
<flag name='vfio-pci'/>
<flag name='mem-merge'/>
@@ -150,6 +152,7 @@
<flag name='blockdev-del'/>
<flag name='vhost-vsock'/>
<flag name='chardev-fd-pass'/>
+ <flag name='tpm-emulator'/>
<flag name='usb-storage.werror'/>
<flag name='egl-headless'/>
<flag name='vfio-pci.display'/>
diff --git a/tests/qemuxml2argvdata/aarch64-tpm.aarch64-latest.args b/tests/qemuxml2argvdata/aarch64-tpm.aarch64-latest.args
new file mode 100644
index 0000000000..4ca09a1fb0
--- /dev/null
+++ b/tests/qemuxml2argvdata/aarch64-tpm.aarch64-latest.args
@@ -0,0 +1,35 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/tmp/lib/domain--1-aarch64test \
+USER=test \
+LOGNAME=test \
+XDG_DATA_HOME=/tmp/lib/domain--1-aarch64test/.local/share \
+XDG_CACHE_HOME=/tmp/lib/domain--1-aarch64test/.cache \
+XDG_CONFIG_HOME=/tmp/lib/domain--1-aarch64test/.config \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-aarch64 \
+-name guest=aarch64test,debug-threads=on \
+-S \
+-object secret,id=masterKey0,format=raw,\
+file=/tmp/lib/domain--1-aarch64test/master-key.aes \
+-machine virt,accel=tcg,usb=off,dump-guest-core=off,gic-version=2 \
+-cpu cortex-a15 \
+-m 1024 \
+-overcommit mem-lock=off \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid 496d7ea8-9739-544b-4ebd-ef08be936e8b \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=1729,server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-no-acpi \
+-boot strict=on \
+-tpmdev emulator,id=tpm-tpm0,chardev=chrtpm \
+-chardev socket,id=chrtpm,path=/dev/test \
+-device tpm-tis-device,tpmdev=tpm-tpm0,id=tpm0 \
+-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\
+resourcecontrol=deny \
+-msg timestamp=on
diff --git a/tests/qemuxml2argvdata/aarch64-tpm.xml b/tests/qemuxml2argvdata/aarch64-tpm.xml
new file mode 100644
index 0000000000..d338a20f17
--- /dev/null
+++ b/tests/qemuxml2argvdata/aarch64-tpm.xml
@@ -0,0 +1,15 @@
+<domain type="qemu">
+ <name>aarch64test</name>
+ <uuid>496d7ea8-9739-544b-4ebd-ef08be936e8b</uuid>
+ <memory>1048576</memory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch="aarch64" machine="virt">hvm</type>
+ </os>
+ <devices>
+ <emulator>/usr/bin/qemu-system-aarch64</emulator>
+ <tpm model='tpm-tis'>
+ <backend type='emulator' version='2.0'/>
+ </tpm>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index dc871d5698..47fce1c3bf 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -2305,6 +2305,7 @@ mymain(void)
DO_TEST_CAPS_LATEST("tpm-emulator-tpm2");
DO_TEST_CAPS_LATEST("tpm-emulator-tpm2-enc");
DO_TEST_CAPS_LATEST_PPC64("tpm-emulator-spapr");
+ DO_TEST_CAPS_ARCH_LATEST("aarch64-tpm", "aarch64");
DO_TEST_PARSE_ERROR("pci-domain-invalid", NONE);
DO_TEST_PARSE_ERROR("pci-bus-invalid", NONE);
--
2.27.0

View File

@ -0,0 +1,305 @@
From fb869a0d3a28591d17a9f047eafd3b77513d6d77 Mon Sep 17 00:00:00 2001
From: Peter Krempa <pkrempa@redhat.com>
Date: Fri, 15 May 2020 14:24:21 +0200
Subject: [PATCH 17/18] qemu: Prepare for testing of 'netdev_add' props via
qemuxml2argvtest
qemuxml2argv test suite is way more comprehensive than the hotplug
suite. Since we share the code paths for monitor and command line
hotplug we can easily test the properties of devices against the QAPI
schema.
To achieve this we'll need to skip the JSON->commandline conversion for
the test run so that we can analyze the pure properties. This patch adds
flags for the comand line generator and hook them into the
JSON->commandline convertor for -netdev. An upcoming patch will make use
of this new infrastructure.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
src/qemu/qemu_command.c | 28 +++++++++++++++++-----------
src/qemu/qemu_command.h | 7 ++++++-
src/qemu/qemu_driver.c | 2 +-
src/qemu/qemu_process.c | 11 +++++++++--
src/qemu/qemu_process.h | 1 +
src/util/virqemu.c | 9 ++++++++-
src/util/virqemu.h | 3 ++-
tests/qemuxml2argvtest.c | 6 ++++--
8 files changed, 48 insertions(+), 19 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index bd78bfb31b..dae6b5a7f9 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -8027,7 +8027,8 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver,
virNetDevVPortProfileOp vmop,
bool standalone,
size_t *nnicindexes,
- int **nicindexes)
+ int **nicindexes,
+ unsigned int flags)
{
virDomainDefPtr def = vm->def;
int ret = -1;
@@ -8256,7 +8257,8 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver,
slirpfdName)))
goto cleanup;
- if (!(host = virQEMUBuildNetdevCommandlineFromJSON(hostnetprops)))
+ if (!(host = virQEMUBuildNetdevCommandlineFromJSON(hostnetprops,
+ (flags & QEMU_BUILD_COMMANDLINE_VALIDATE_KEEP_JSON))))
goto cleanup;
virCommandAddArgList(cmd, "-netdev", host, NULL);
@@ -8332,7 +8334,8 @@ qemuBuildNetCommandLine(virQEMUDriverPtr driver,
bool standalone,
size_t *nnicindexes,
int **nicindexes,
- unsigned int *bootHostdevNet)
+ unsigned int *bootHostdevNet,
+ unsigned int flags)
{
size_t i;
int last_good_net = -1;
@@ -8356,7 +8359,7 @@ qemuBuildNetCommandLine(virQEMUDriverPtr driver,
if (qemuBuildInterfaceCommandLine(driver, vm, logManager, secManager, cmd, net,
qemuCaps, bootNet, vmop,
standalone, nnicindexes,
- nicindexes) < 0)
+ nicindexes, flags) < 0)
goto error;
last_good_net = i;
@@ -8892,7 +8895,8 @@ qemuBuildChannelsCommandLine(virLogManagerPtr logManager,
virQEMUDriverConfigPtr cfg,
const virDomainDef *def,
virQEMUCapsPtr qemuCaps,
- bool chardevStdioLogd)
+ bool chardevStdioLogd,
+ unsigned int flags)
{
size_t i;
unsigned int cdevflags = QEMU_BUILD_CHARDEV_TCP_NOWAIT |
@@ -8921,7 +8925,8 @@ qemuBuildChannelsCommandLine(virLogManagerPtr logManager,
if (!(netdevprops = qemuBuildChannelGuestfwdNetdevProps(channel)))
return -1;
- if (!(netdevstr = virQEMUBuildNetdevCommandlineFromJSON(netdevprops)))
+ if (!(netdevstr = virQEMUBuildNetdevCommandlineFromJSON(netdevprops,
+ (flags & QEMU_BUILD_COMMANDLINE_VALIDATE_KEEP_JSON))))
return -1;
virCommandAddArgList(cmd, "-netdev", netdevstr, NULL);
@@ -9857,7 +9862,8 @@ qemuBuildCommandLine(virQEMUDriverPtr driver,
bool standalone,
bool enableFips,
size_t *nnicindexes,
- int **nicindexes)
+ int **nicindexes,
+ unsigned int flags)
{
size_t i;
char uuid[VIR_UUID_STRING_BUFLEN];
@@ -9870,9 +9876,9 @@ qemuBuildCommandLine(virQEMUDriverPtr driver,
bool chardevStdioLogd = priv->chardevStdioLogd;
VIR_DEBUG("driver=%p def=%p mon=%p "
- "qemuCaps=%p migrateURI=%s snapshot=%p vmop=%d",
+ "qemuCaps=%p migrateURI=%s snapshot=%p vmop=%d flags=0x%x",
driver, def, priv->monConfig,
- qemuCaps, migrateURI, snapshot, vmop);
+ qemuCaps, migrateURI, snapshot, vmop, flags);
if (qemuBuildCommandLineValidate(driver, def) < 0)
return NULL;
@@ -10017,7 +10023,7 @@ qemuBuildCommandLine(virQEMUDriverPtr driver,
if (qemuBuildNetCommandLine(driver, vm, logManager, secManager, cmd,
qemuCaps, vmop, standalone,
- nnicindexes, nicindexes, &bootHostdevNet) < 0)
+ nnicindexes, nicindexes, &bootHostdevNet, flags) < 0)
return NULL;
if (qemuBuildSmartcardCommandLine(logManager, secManager, cmd, cfg, def, qemuCaps,
@@ -10033,7 +10039,7 @@ qemuBuildCommandLine(virQEMUDriverPtr driver,
return NULL;
if (qemuBuildChannelsCommandLine(logManager, secManager, cmd, cfg, def, qemuCaps,
- chardevStdioLogd) < 0)
+ chardevStdioLogd, flags) < 0)
return NULL;
if (qemuBuildConsoleCommandLine(logManager, secManager, cmd, cfg, def, qemuCaps,
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index 1e6b23ba05..4b1c2103c5 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -43,6 +43,10 @@
VIR_ENUM_DECL(qemuVideo);
VIR_ENUM_DECL(qemuSoundCodec);
+typedef enum {
+ QEMU_BUILD_COMMANDLINE_VALIDATE_KEEP_JSON = 1 << 0,
+} qemuBuildCommandLineFlags;
+
virCommandPtr qemuBuildCommandLine(virQEMUDriverPtr driver,
virLogManagerPtr logManager,
virSecurityManagerPtr secManager,
@@ -53,7 +57,8 @@ virCommandPtr qemuBuildCommandLine(virQEMUDriverPtr driver,
bool standalone,
bool enableFips,
size_t *nnicindexes,
- int **nicindexes);
+ int **nicindexes,
+ unsigned int flags);
/* Generate the object properties for pr-manager */
virJSONValuePtr qemuBuildPRManagerInfoProps(virStorageSourcePtr src);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 2b24881f75..b3ebf3aa9b 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7449,7 +7449,7 @@ static char *qemuConnectDomainXMLToNative(virConnectPtr conn,
}
if (!(cmd = qemuProcessCreatePretendCmd(driver, vm, NULL,
- qemuCheckFips(), true,
+ qemuCheckFips(), true, false,
VIR_QEMU_PROCESS_START_COLD)))
goto cleanup;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 818a72d8f9..db564cae36 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -6750,7 +6750,7 @@ qemuProcessLaunch(virConnectPtr conn,
snapshot, vmop,
false,
qemuCheckFips(),
- &nnicindexes, &nicindexes)))
+ &nnicindexes, &nicindexes, 0)))
goto cleanup;
if (incoming && incoming->fd != -1)
@@ -7193,8 +7193,11 @@ qemuProcessCreatePretendCmd(virQEMUDriverPtr driver,
const char *migrateURI,
bool enableFips,
bool standalone,
+ bool jsonPropsValidation,
unsigned int flags)
{
+ unsigned int buildflags = 0;
+
virCheckFlags(VIR_QEMU_PROCESS_START_COLD |
VIR_QEMU_PROCESS_START_PAUSED |
VIR_QEMU_PROCESS_START_AUTODESTROY, NULL);
@@ -7204,6 +7207,9 @@ qemuProcessCreatePretendCmd(virQEMUDriverPtr driver,
if (standalone)
flags |= VIR_QEMU_PROCESS_START_STANDALONE;
+ if (jsonPropsValidation)
+ buildflags = QEMU_BUILD_COMMANDLINE_VALIDATE_KEEP_JSON;
+
if (qemuProcessInit(driver, vm, NULL, QEMU_ASYNC_JOB_NONE,
!!migrateURI, flags) < 0)
return NULL;
@@ -7222,7 +7228,8 @@ qemuProcessCreatePretendCmd(virQEMUDriverPtr driver,
standalone,
enableFips,
NULL,
- NULL);
+ NULL,
+ buildflags);
}
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index 3077d3ef9e..15e67b9762 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -101,6 +101,7 @@ virCommandPtr qemuProcessCreatePretendCmd(virQEMUDriverPtr driver,
const char *migrateURI,
bool enableFips,
bool standalone,
+ bool jsonPropsValidation,
unsigned int flags);
int qemuProcessInit(virQEMUDriverPtr driver,
diff --git a/src/util/virqemu.c b/src/util/virqemu.c
index 9823ebc14d..321ddeb7e3 100644
--- a/src/util/virqemu.c
+++ b/src/util/virqemu.c
@@ -292,16 +292,23 @@ virQEMUBuildCommandLineJSON(virJSONValuePtr value,
/**
* virQEMUBuildNetdevCommandlineFromJSON:
* @props: JSON properties describing a netdev
+ * @rawjson: don't transform to commandline args, but just stringify json
*
* Converts @props into arguments for -netdev including all the quirks and
* differences between the monitor and command line syntax.
+ *
+ * @rawjson is meant for testing of the schema in the xml2argvtest
*/
char *
-virQEMUBuildNetdevCommandlineFromJSON(virJSONValuePtr props)
+virQEMUBuildNetdevCommandlineFromJSON(virJSONValuePtr props,
+ bool rawjson)
{
const char *type = virJSONValueObjectGetString(props, "type");
g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
+ if (rawjson)
+ return virJSONValueToString(props, false);
+
virBufferAsprintf(&buf, "%s,", type);
if (virQEMUBuildCommandLineJSON(props, &buf, "type", true,
diff --git a/src/util/virqemu.h b/src/util/virqemu.h
index 22f47851df..b1296cb657 100644
--- a/src/util/virqemu.h
+++ b/src/util/virqemu.h
@@ -50,7 +50,8 @@ int virQEMUBuildCommandLineJSON(virJSONValuePtr value,
virQEMUBuildCommandLineJSONArrayFormatFunc array);
char *
-virQEMUBuildNetdevCommandlineFromJSON(virJSONValuePtr props);
+virQEMUBuildNetdevCommandlineFromJSON(virJSONValuePtr props,
+ bool rawjson);
int virQEMUBuildObjectCommandlineFromJSON(virBufferPtr buf,
virJSONValuePtr objprops);
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 762d65f521..2217e2d81e 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -400,7 +400,8 @@ testCompareXMLToArgvCreateArgs(virQEMUDriverPtr drv,
virDomainObjPtr vm,
const char *migrateURI,
struct testQemuInfo *info,
- unsigned int flags)
+ unsigned int flags,
+ bool jsonPropsValidation)
{
size_t i;
@@ -475,6 +476,7 @@ testCompareXMLToArgvCreateArgs(virQEMUDriverPtr drv,
return qemuProcessCreatePretendCmd(drv, vm, migrateURI,
(flags & FLAG_FIPS), false,
+ jsonPropsValidation,
VIR_QEMU_PROCESS_START_COLD);
}
@@ -570,7 +572,7 @@ testCompareXMLToArgv(const void *data)
virResetLastError();
if (!(cmd = testCompareXMLToArgvCreateArgs(&driver, vm, migrateURI, info,
- flags))) {
+ flags, false))) {
if (flags & FLAG_EXPECT_FAILURE)
goto ok;
goto cleanup;
--
2.23.0.windows.1

View File

@ -0,0 +1,589 @@
From aa0f670f9d558c518a5890cbfa7f969e1d2841aa Mon Sep 17 00:00:00 2001
From: Jiri Denemark <jdenemar@redhat.com>
Date: Wed, 10 Jun 2020 15:09:00 +0200
Subject: [PATCH 1/8] qemu: Probe for a few params supported by
migrate-set-parameters
These parameters were originally set via dedicated commands which are
now deprecated. We want to use migrate-set-parameters instead if
possible.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
---
src/qemu/qemu_capabilities.c | 6 ++++++
src/qemu/qemu_capabilities.h | 3 +++
tests/qemucapabilitiesdata/caps_2.10.0.aarch64.xml | 2 ++
tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml | 2 ++
tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml | 2 ++
tests/qemucapabilitiesdata/caps_2.10.0.x86_64.xml | 2 ++
tests/qemucapabilitiesdata/caps_2.11.0.s390x.xml | 3 +++
tests/qemucapabilitiesdata/caps_2.11.0.x86_64.xml | 3 +++
tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml | 3 +++
tests/qemucapabilitiesdata/caps_2.12.0.ppc64.xml | 3 +++
tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml | 3 +++
tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml | 3 +++
tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml | 2 ++
tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml | 2 ++
tests/qemucapabilitiesdata/caps_2.9.0.ppc64.xml | 2 ++
tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml | 2 ++
tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml | 2 ++
tests/qemucapabilitiesdata/caps_3.0.0.ppc64.xml | 3 +++
tests/qemucapabilitiesdata/caps_3.0.0.riscv32.xml | 3 +++
tests/qemucapabilitiesdata/caps_3.0.0.riscv64.xml | 3 +++
tests/qemucapabilitiesdata/caps_3.0.0.s390x.xml | 3 +++
tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml | 3 +++
tests/qemucapabilitiesdata/caps_3.1.0.ppc64.xml | 3 +++
tests/qemucapabilitiesdata/caps_3.1.0.x86_64.xml | 3 +++
tests/qemucapabilitiesdata/caps_4.0.0.aarch64.xml | 3 +++
tests/qemucapabilitiesdata/caps_4.0.0.ppc64.xml | 3 +++
tests/qemucapabilitiesdata/caps_4.0.0.riscv32.xml | 3 +++
tests/qemucapabilitiesdata/caps_4.0.0.riscv64.xml | 3 +++
tests/qemucapabilitiesdata/caps_4.0.0.s390x.xml | 3 +++
tests/qemucapabilitiesdata/caps_4.0.0.x86_64.xml | 3 +++
tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml | 3 +++
tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml | 3 +++
tests/qemucapabilitiesdata/caps_4.2.0.ppc64.xml | 3 +++
tests/qemucapabilitiesdata/caps_4.2.0.s390x.xml | 3 +++
tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml | 3 +++
tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml | 3 +++
tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml | 3 +++
tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml | 3 +++
38 files changed, 108 insertions(+)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 18bf37b569..fb7726235d 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -571,6 +571,9 @@ VIR_ENUM_IMPL(virQEMUCaps,
/* 360 */
"tpm-tis-device",
+ "migration-param.bandwidth",
+ "migration-param.downtime",
+ "migration-param.xbzrle-cache-size",
);
@@ -1451,6 +1454,9 @@ static struct virQEMUCapsStringFlags virQEMUCapsQMPSchemaQueries[] = {
{ "blockdev-add/arg-type/+nvme", QEMU_CAPS_DRIVE_NVME },
{ "query-named-block-nodes/arg-type/flat", QEMU_CAPS_QMP_QUERY_NAMED_BLOCK_NODES_FLAT },
{ "blockdev-snapshot/$allow-write-only-overlay", QEMU_CAPS_BLOCKDEV_SNAPSHOT_ALLOW_WRITE_ONLY },
+ { "migrate-set-parameters/arg-type/max-bandwidth", QEMU_CAPS_MIGRATION_PARAM_BANDWIDTH },
+ { "migrate-set-parameters/arg-type/downtime-limit", QEMU_CAPS_MIGRATION_PARAM_DOWNTIME },
+ { "migrate-set-parameters/arg-type/xbzrle-cache-size", QEMU_CAPS_MIGRATION_PARAM_XBZRLE_CACHE_SIZE },
};
typedef struct _virQEMUCapsObjectTypeProps virQEMUCapsObjectTypeProps;
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 8e16fc0e78..0ac92d77c3 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -552,6 +552,9 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */
/* 360 */
QEMU_CAPS_DEVICE_TPM_TIS_DEVICE, /* -device tpm-tis-device */
+ QEMU_CAPS_MIGRATION_PARAM_BANDWIDTH, /* max-bandwidth field in migrate-set-parameters */
+ QEMU_CAPS_MIGRATION_PARAM_DOWNTIME, /* downtime-limit field in migrate-set-parameters */
+ QEMU_CAPS_MIGRATION_PARAM_XBZRLE_CACHE_SIZE, /* xbzrle-cache-size field in migrate-set-parameters */
QEMU_CAPS_LAST /* this must always be the last item */
} virQEMUCapsFlags;
diff --git a/tests/qemucapabilitiesdata/caps_2.10.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_2.10.0.aarch64.xml
index f598b4678a..e253df4077 100644
--- a/tests/qemucapabilitiesdata/caps_2.10.0.aarch64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.10.0.aarch64.xml
@@ -140,6 +140,8 @@
<flag name='vhost-vsock'/>
<flag name='egl-headless'/>
<flag name='iothread.poll-max-ns'/>
+ <flag name='migration-param.bandwidth'/>
+ <flag name='migration-param.downtime'/>
<version>2010000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>61700287</microcodeVersion>
diff --git a/tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml
index b95a9d42ad..8df611353f 100644
--- a/tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml
@@ -140,6 +140,8 @@
<flag name='egl-headless'/>
<flag name='iothread.poll-max-ns'/>
<flag name='i8042'/>
+ <flag name='migration-param.bandwidth'/>
+ <flag name='migration-param.downtime'/>
<version>2010000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>42900287</microcodeVersion>
diff --git a/tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml
index 04ac872985..27ce348b80 100644
--- a/tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml
+++ b/tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml
@@ -107,6 +107,8 @@
<flag name='query-cpu-model-baseline'/>
<flag name='query-cpu-model-comparison'/>
<flag name='storage.werror'/>
+ <flag name='migration-param.bandwidth'/>
+ <flag name='migration-param.downtime'/>
<version>2010000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>39100287</microcodeVersion>
diff --git a/tests/qemucapabilitiesdata/caps_2.10.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.10.0.x86_64.xml
index 7ebe97b6ab..368985a611 100644
--- a/tests/qemucapabilitiesdata/caps_2.10.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.10.0.x86_64.xml
@@ -183,6 +183,8 @@
<flag name='iothread.poll-max-ns'/>
<flag name='x86-max-cpu'/>
<flag name='i8042'/>
+ <flag name='migration-param.bandwidth'/>
+ <flag name='migration-param.downtime'/>
<version>2010000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>43100287</microcodeVersion>
diff --git a/tests/qemucapabilitiesdata/caps_2.11.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.11.0.s390x.xml
index 6d36a6e484..c5bcf1c818 100644
--- a/tests/qemucapabilitiesdata/caps_2.11.0.s390x.xml
+++ b/tests/qemucapabilitiesdata/caps_2.11.0.s390x.xml
@@ -114,6 +114,9 @@
<flag name='query-cpu-model-baseline'/>
<flag name='query-cpu-model-comparison'/>
<flag name='storage.werror'/>
+ <flag name='migration-param.bandwidth'/>
+ <flag name='migration-param.downtime'/>
+ <flag name='migration-param.xbzrle-cache-size'/>
<version>2011000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>39100288</microcodeVersion>
diff --git a/tests/qemucapabilitiesdata/caps_2.11.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.11.0.x86_64.xml
index b8eb3abd40..717ef46f78 100644
--- a/tests/qemucapabilitiesdata/caps_2.11.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.11.0.x86_64.xml
@@ -189,6 +189,9 @@
<flag name='iothread.poll-max-ns'/>
<flag name='x86-max-cpu'/>
<flag name='i8042'/>
+ <flag name='migration-param.bandwidth'/>
+ <flag name='migration-param.downtime'/>
+ <flag name='migration-param.xbzrle-cache-size'/>
<version>2011000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>43100288</microcodeVersion>
diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml
index 64d8d4951c..fbee7661a1 100644
--- a/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml
@@ -156,6 +156,9 @@
<flag name='memory-backend-file.align'/>
<flag name='arm-max-cpu'/>
<flag name='drive-nvme'/>
+ <flag name='migration-param.bandwidth'/>
+ <flag name='migration-param.downtime'/>
+ <flag name='migration-param.xbzrle-cache-size'/>
<version>2012000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>61700289</microcodeVersion>
diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_2.12.0.ppc64.xml
index 38a3103c4a..31a643f5d1 100644
--- a/tests/qemucapabilitiesdata/caps_2.12.0.ppc64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.12.0.ppc64.xml
@@ -154,6 +154,9 @@
<flag name='memory-backend-file.align'/>
<flag name='drive-nvme'/>
<flag name='i8042'/>
+ <flag name='migration-param.bandwidth'/>
+ <flag name='migration-param.downtime'/>
+ <flag name='migration-param.xbzrle-cache-size'/>
<version>2011090</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>42900289</microcodeVersion>
diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml
index 21a168dd3b..d0ea4d780a 100644
--- a/tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml
+++ b/tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml
@@ -126,6 +126,9 @@
<flag name='query-cpu-model-comparison'/>
<flag name='drive-nvme'/>
<flag name='storage.werror'/>
+ <flag name='migration-param.bandwidth'/>
+ <flag name='migration-param.downtime'/>
+ <flag name='migration-param.xbzrle-cache-size'/>
<version>2012000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>39100289</microcodeVersion>
diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml
index 0c30cc75da..3db7162a34 100644
--- a/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml
@@ -198,6 +198,9 @@
<flag name='x86-max-cpu'/>
<flag name='drive-nvme'/>
<flag name='i8042'/>
+ <flag name='migration-param.bandwidth'/>
+ <flag name='migration-param.downtime'/>
+ <flag name='migration-param.xbzrle-cache-size'/>
<version>2011090</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>43100289</microcodeVersion>
diff --git a/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml
index d204b82030..7becf1bfb6 100644
--- a/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml
+++ b/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml
@@ -96,6 +96,8 @@
<flag name='query-cpu-model-baseline'/>
<flag name='query-cpu-model-comparison'/>
<flag name='storage.werror'/>
+ <flag name='migration-param.bandwidth'/>
+ <flag name='migration-param.downtime'/>
<version>2007093</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>39100246</microcodeVersion>
diff --git a/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml
index 489b67f99a..2a0b1f61de 100644
--- a/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml
@@ -160,6 +160,8 @@
<flag name='vhost-vsock'/>
<flag name='mch'/>
<flag name='i8042'/>
+ <flag name='migration-param.bandwidth'/>
+ <flag name='migration-param.downtime'/>
<version>2008000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>43100246</microcodeVersion>
diff --git a/tests/qemucapabilitiesdata/caps_2.9.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_2.9.0.ppc64.xml
index 3bc6ec8dab..9141e29757 100644
--- a/tests/qemucapabilitiesdata/caps_2.9.0.ppc64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.9.0.ppc64.xml
@@ -132,6 +132,8 @@
<flag name='vhost-vsock'/>
<flag name='iothread.poll-max-ns'/>
<flag name='i8042'/>
+ <flag name='migration-param.bandwidth'/>
+ <flag name='migration-param.downtime'/>
<version>2009000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>42900247</microcodeVersion>
diff --git a/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml
index 9a6d94d37b..bcc7d4bd4e 100644
--- a/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml
+++ b/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml
@@ -101,6 +101,8 @@
<flag name='query-cpu-model-baseline'/>
<flag name='query-cpu-model-comparison'/>
<flag name='storage.werror'/>
+ <flag name='migration-param.bandwidth'/>
+ <flag name='migration-param.downtime'/>
<version>2009000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>39100247</microcodeVersion>
diff --git a/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml
index 83fc6cde97..5cd82aa979 100644
--- a/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml
@@ -177,6 +177,8 @@
<flag name='iothread.poll-max-ns'/>
<flag name='x86-max-cpu'/>
<flag name='i8042'/>
+ <flag name='migration-param.bandwidth'/>
+ <flag name='migration-param.downtime'/>
<version>2009000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>43100247</microcodeVersion>
diff --git a/tests/qemucapabilitiesdata/caps_3.0.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_3.0.0.ppc64.xml
index 9a0b9c05c2..6916da2047 100644
--- a/tests/qemucapabilitiesdata/caps_3.0.0.ppc64.xml
+++ b/tests/qemucapabilitiesdata/caps_3.0.0.ppc64.xml
@@ -156,6 +156,9 @@
<flag name='ramfb'/>
<flag name='drive-nvme'/>
<flag name='i8042'/>
+ <flag name='migration-param.bandwidth'/>
+ <flag name='migration-param.downtime'/>
+ <flag name='migration-param.xbzrle-cache-size'/>
<version>2012050</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>42900239</microcodeVersion>
diff --git a/tests/qemucapabilitiesdata/caps_3.0.0.riscv32.xml b/tests/qemucapabilitiesdata/caps_3.0.0.riscv32.xml
index 6814a2f9c6..802b624073 100644
--- a/tests/qemucapabilitiesdata/caps_3.0.0.riscv32.xml
+++ b/tests/qemucapabilitiesdata/caps_3.0.0.riscv32.xml
@@ -96,6 +96,9 @@
<flag name='ramfb'/>
<flag name='drive-nvme'/>
<flag name='storage.werror'/>
+ <flag name='migration-param.bandwidth'/>
+ <flag name='migration-param.downtime'/>
+ <flag name='migration-param.xbzrle-cache-size'/>
<version>3000000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>0</microcodeVersion>
diff --git a/tests/qemucapabilitiesdata/caps_3.0.0.riscv64.xml b/tests/qemucapabilitiesdata/caps_3.0.0.riscv64.xml
index b81f5825cc..a16db0912d 100644
--- a/tests/qemucapabilitiesdata/caps_3.0.0.riscv64.xml
+++ b/tests/qemucapabilitiesdata/caps_3.0.0.riscv64.xml
@@ -96,6 +96,9 @@
<flag name='ramfb'/>
<flag name='drive-nvme'/>
<flag name='storage.werror'/>
+ <flag name='migration-param.bandwidth'/>
+ <flag name='migration-param.downtime'/>
+ <flag name='migration-param.xbzrle-cache-size'/>
<version>3000000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>0</microcodeVersion>
diff --git a/tests/qemucapabilitiesdata/caps_3.0.0.s390x.xml b/tests/qemucapabilitiesdata/caps_3.0.0.s390x.xml
index 85cda12076..6992e10237 100644
--- a/tests/qemucapabilitiesdata/caps_3.0.0.s390x.xml
+++ b/tests/qemucapabilitiesdata/caps_3.0.0.s390x.xml
@@ -129,6 +129,9 @@
<flag name='ramfb'/>
<flag name='drive-nvme'/>
<flag name='storage.werror'/>
+ <flag name='migration-param.bandwidth'/>
+ <flag name='migration-param.downtime'/>
+ <flag name='migration-param.xbzrle-cache-size'/>
<version>3000000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>39100239</microcodeVersion>
diff --git a/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml
index 517e27d815..9fdfc634ff 100644
--- a/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml
@@ -204,6 +204,9 @@
<flag name='drive-nvme'/>
<flag name='i8042'/>
<flag name='storage.werror'/>
+ <flag name='migration-param.bandwidth'/>
+ <flag name='migration-param.downtime'/>
+ <flag name='migration-param.xbzrle-cache-size'/>
<version>3000000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>43100239</microcodeVersion>
diff --git a/tests/qemucapabilitiesdata/caps_3.1.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_3.1.0.ppc64.xml
index 6801023208..4039923e5f 100644
--- a/tests/qemucapabilitiesdata/caps_3.1.0.ppc64.xml
+++ b/tests/qemucapabilitiesdata/caps_3.1.0.ppc64.xml
@@ -161,6 +161,9 @@
<flag name='drive-nvme'/>
<flag name='i8042'/>
<flag name='storage.werror'/>
+ <flag name='migration-param.bandwidth'/>
+ <flag name='migration-param.downtime'/>
+ <flag name='migration-param.xbzrle-cache-size'/>
<version>3000091</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>42900240</microcodeVersion>
diff --git a/tests/qemucapabilitiesdata/caps_3.1.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_3.1.0.x86_64.xml
index d901715ffc..02fc245fca 100644
--- a/tests/qemucapabilitiesdata/caps_3.1.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_3.1.0.x86_64.xml
@@ -207,6 +207,9 @@
<flag name='drive-nvme'/>
<flag name='i8042'/>
<flag name='storage.werror'/>
+ <flag name='migration-param.bandwidth'/>
+ <flag name='migration-param.downtime'/>
+ <flag name='migration-param.xbzrle-cache-size'/>
<version>3000092</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>43100240</microcodeVersion>
diff --git a/tests/qemucapabilitiesdata/caps_4.0.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_4.0.0.aarch64.xml
index 6fd1880ae2..278f2d9135 100644
--- a/tests/qemucapabilitiesdata/caps_4.0.0.aarch64.xml
+++ b/tests/qemucapabilitiesdata/caps_4.0.0.aarch64.xml
@@ -170,6 +170,9 @@
<flag name='arm-max-cpu'/>
<flag name='drive-nvme'/>
<flag name='storage.werror'/>
+ <flag name='migration-param.bandwidth'/>
+ <flag name='migration-param.downtime'/>
+ <flag name='migration-param.xbzrle-cache-size'/>
<version>4000000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>61700240</microcodeVersion>
diff --git a/tests/qemucapabilitiesdata/caps_4.0.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_4.0.0.ppc64.xml
index f7e69fcc97..897ca08af0 100644
--- a/tests/qemucapabilitiesdata/caps_4.0.0.ppc64.xml
+++ b/tests/qemucapabilitiesdata/caps_4.0.0.ppc64.xml
@@ -175,6 +175,9 @@
<flag name='drive-nvme'/>
<flag name='i8042'/>
<flag name='storage.werror'/>
+ <flag name='migration-param.bandwidth'/>
+ <flag name='migration-param.downtime'/>
+ <flag name='migration-param.xbzrle-cache-size'/>
<version>4000000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>42900240</microcodeVersion>
diff --git a/tests/qemucapabilitiesdata/caps_4.0.0.riscv32.xml b/tests/qemucapabilitiesdata/caps_4.0.0.riscv32.xml
index 6a567239b9..1993d52d42 100644
--- a/tests/qemucapabilitiesdata/caps_4.0.0.riscv32.xml
+++ b/tests/qemucapabilitiesdata/caps_4.0.0.riscv32.xml
@@ -171,6 +171,9 @@
<flag name='migration-file-drop-cache'/>
<flag name='drive-nvme'/>
<flag name='storage.werror'/>
+ <flag name='migration-param.bandwidth'/>
+ <flag name='migration-param.downtime'/>
+ <flag name='migration-param.xbzrle-cache-size'/>
<version>4000000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>0</microcodeVersion>
diff --git a/tests/qemucapabilitiesdata/caps_4.0.0.riscv64.xml b/tests/qemucapabilitiesdata/caps_4.0.0.riscv64.xml
index d6686b7c68..348138ab5a 100644
--- a/tests/qemucapabilitiesdata/caps_4.0.0.riscv64.xml
+++ b/tests/qemucapabilitiesdata/caps_4.0.0.riscv64.xml
@@ -171,6 +171,9 @@
<flag name='migration-file-drop-cache'/>
<flag name='drive-nvme'/>
<flag name='storage.werror'/>
+ <flag name='migration-param.bandwidth'/>
+ <flag name='migration-param.downtime'/>
+ <flag name='migration-param.xbzrle-cache-size'/>
<version>4000000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>0</microcodeVersion>
diff --git a/tests/qemucapabilitiesdata/caps_4.0.0.s390x.xml b/tests/qemucapabilitiesdata/caps_4.0.0.s390x.xml
index 9dc29832f9..1542ed6c68 100644
--- a/tests/qemucapabilitiesdata/caps_4.0.0.s390x.xml
+++ b/tests/qemucapabilitiesdata/caps_4.0.0.s390x.xml
@@ -137,6 +137,9 @@
<flag name='query-cpu-model-comparison'/>
<flag name='drive-nvme'/>
<flag name='storage.werror'/>
+ <flag name='migration-param.bandwidth'/>
+ <flag name='migration-param.downtime'/>
+ <flag name='migration-param.xbzrle-cache-size'/>
<version>4000000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>39100240</microcodeVersion>
diff --git a/tests/qemucapabilitiesdata/caps_4.0.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_4.0.0.x86_64.xml
index ae4004ad3c..9292313570 100644
--- a/tests/qemucapabilitiesdata/caps_4.0.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_4.0.0.x86_64.xml
@@ -212,6 +212,9 @@
<flag name='drive-nvme'/>
<flag name='i8042'/>
<flag name='storage.werror'/>
+ <flag name='migration-param.bandwidth'/>
+ <flag name='migration-param.downtime'/>
+ <flag name='migration-param.xbzrle-cache-size'/>
<version>4000000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>43100240</microcodeVersion>
diff --git a/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml
index d9bdeb2516..d07a27b4f8 100644
--- a/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml
@@ -218,6 +218,9 @@
<flag name='smp-dies'/>
<flag name='i8042'/>
<flag name='storage.werror'/>
+ <flag name='migration-param.bandwidth'/>
+ <flag name='migration-param.downtime'/>
+ <flag name='migration-param.xbzrle-cache-size'/>
<version>4001000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>43100241</microcodeVersion>
diff --git a/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml
index de16451b8b..fb3d5996c4 100644
--- a/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml
+++ b/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml
@@ -180,6 +180,9 @@
<flag name='virtio-net.failover'/>
<flag name='vhost-user-fs'/>
<flag name='storage.werror'/>
+ <flag name='migration-param.bandwidth'/>
+ <flag name='migration-param.downtime'/>
+ <flag name='migration-param.xbzrle-cache-size'/>
<version>4001050</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>61700242</microcodeVersion>
diff --git a/tests/qemucapabilitiesdata/caps_4.2.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_4.2.0.ppc64.xml
index 99ec98e8cd..daea978d9f 100644
--- a/tests/qemucapabilitiesdata/caps_4.2.0.ppc64.xml
+++ b/tests/qemucapabilitiesdata/caps_4.2.0.ppc64.xml
@@ -180,6 +180,9 @@
<flag name='i8042'/>
<flag name='rng-builtin'/>
<flag name='storage.werror'/>
+ <flag name='migration-param.bandwidth'/>
+ <flag name='migration-param.downtime'/>
+ <flag name='migration-param.xbzrle-cache-size'/>
<version>4001050</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>42900242</microcodeVersion>
diff --git a/tests/qemucapabilitiesdata/caps_4.2.0.s390x.xml b/tests/qemucapabilitiesdata/caps_4.2.0.s390x.xml
index fa3c2ef3e4..d007ae65d6 100644
--- a/tests/qemucapabilitiesdata/caps_4.2.0.s390x.xml
+++ b/tests/qemucapabilitiesdata/caps_4.2.0.s390x.xml
@@ -139,6 +139,9 @@
<flag name='rng-builtin'/>
<flag name='vhost-user-fs'/>
<flag name='storage.werror'/>
+ <flag name='migration-param.bandwidth'/>
+ <flag name='migration-param.downtime'/>
+ <flag name='migration-param.xbzrle-cache-size'/>
<version>4001050</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>39100242</microcodeVersion>
diff --git a/tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml
index c1b73f4ad5..2d5b2ad0f0 100644
--- a/tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml
@@ -224,6 +224,9 @@
<flag name='virtio-net.failover'/>
<flag name='vhost-user-fs'/>
<flag name='storage.werror'/>
+ <flag name='migration-param.bandwidth'/>
+ <flag name='migration-param.downtime'/>
+ <flag name='migration-param.xbzrle-cache-size'/>
<version>4002000</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>43100242</microcodeVersion>
diff --git a/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml
index 53fcd750d9..be0be79fda 100644
--- a/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml
+++ b/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml
@@ -182,6 +182,9 @@
<flag name='cpu.kvm-no-adjvtime'/>
<flag name='vhost-user-fs'/>
<flag name='storage.werror'/>
+ <flag name='migration-param.bandwidth'/>
+ <flag name='migration-param.downtime'/>
+ <flag name='migration-param.xbzrle-cache-size'/>
<version>4002050</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>61700241</microcodeVersion>
diff --git a/tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml
index 2fb5bb49a9..3ee17a66a4 100644
--- a/tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml
+++ b/tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml
@@ -190,6 +190,9 @@
<flag name='query-named-block-nodes.flat'/>
<flag name='blockdev-snapshot.allow-write-only-overlay'/>
<flag name='storage.werror'/>
+ <flag name='migration-param.bandwidth'/>
+ <flag name='migration-param.downtime'/>
+ <flag name='migration-param.xbzrle-cache-size'/>
<version>4002050</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>42900241</microcodeVersion>
diff --git a/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml
index f43090c9e7..73f9319199 100644
--- a/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml
@@ -227,6 +227,9 @@
<flag name='query-named-block-nodes.flat'/>
<flag name='blockdev-snapshot.allow-write-only-overlay'/>
<flag name='storage.werror'/>
+ <flag name='migration-param.bandwidth'/>
+ <flag name='migration-param.downtime'/>
+ <flag name='migration-param.xbzrle-cache-size'/>
<version>4002050</version>
<kvmVersion>0</kvmVersion>
<microcodeVersion>43100241</microcodeVersion>
--
2.27.0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,354 @@
From 0ab9df24cbe5b6cfd2aa259aaaef2f8fb2696ce2 Mon Sep 17 00:00:00 2001
From: Peter Krempa <pkrempa@redhat.com>
Date: Thu, 14 May 2020 22:50:59 +0200
Subject: [PATCH 10/18] qemu: command: Generate -netdev command line via
JSON->cmdline conversion
The 'netdev_add' command was recently formally described in qemu via the
QMP schema. This means that it also requires the arguments to be
properly formatted. Our current approach is to generate the command line
and then use qemuMonitorJSONKeywordStringToJSON to get the JSON
properties for the monitor. This will not work if we need to pass some
fields as numbers or booleans.
In this step we re-do internals of qemuBuildHostNetStr to format a JSON
object which is converted back via virQEMUBuildNetdevCommandlineFromJSON
to the equivalent command line. This will later allow fixing of the
monitor code to use the JSON object directly rather than rely on the
conversion.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
src/qemu/qemu_command.c | 163 +++++++++++++++++++++++++---------------
src/qemu/qemu_command.h | 12 +--
src/qemu/qemu_hotplug.c | 13 +++-
3 files changed, 119 insertions(+), 69 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 688c9db851..141657b3e4 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3910,7 +3910,7 @@ qemuBuildNicDevStr(virDomainDefPtr def,
}
-char *
+virJSONValuePtr
qemuBuildHostNetStr(virDomainNetDefPtr net,
char **tapfd,
size_t tapfdSize,
@@ -3919,10 +3919,11 @@ qemuBuildHostNetStr(virDomainNetDefPtr net,
const char *slirpfd)
{
bool is_tap = false;
- g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
virDomainNetType netType = virDomainNetGetActualType(net);
size_t i;
+ g_autoptr(virJSONValue) netprops = NULL;
+
if (net->script && netType != VIR_DOMAIN_NET_TYPE_ETHERNET) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("scripts are not supported on interfaces of type %s"),
@@ -3940,54 +3941,75 @@ qemuBuildHostNetStr(virDomainNetDefPtr net,
case VIR_DOMAIN_NET_TYPE_NETWORK:
case VIR_DOMAIN_NET_TYPE_DIRECT:
case VIR_DOMAIN_NET_TYPE_ETHERNET:
- virBufferAddLit(&buf, "tap,");
+ if (virJSONValueObjectCreate(&netprops, "s:type", "tap", NULL) < 0)
+ return NULL;
+
/* for one tapfd 'fd=' shall be used,
* for more than one 'fds=' is the right choice */
if (tapfdSize == 1) {
- virBufferAsprintf(&buf, "fd=%s,", tapfd[0]);
+ if (virJSONValueObjectAdd(netprops, "s:fd", tapfd[0], NULL) < 0)
+ return NULL;
} else {
- virBufferAddLit(&buf, "fds=");
- for (i = 0; i < tapfdSize; i++) {
- if (i)
- virBufferAddChar(&buf, ':');
- virBufferAdd(&buf, tapfd[i], -1);
- }
- virBufferAddChar(&buf, ',');
+ g_auto(virBuffer) fdsbuf = VIR_BUFFER_INITIALIZER;
+
+ for (i = 0; i < tapfdSize; i++)
+ virBufferAsprintf(&fdsbuf, "%s:", tapfd[i]);
+
+ virBufferTrim(&fdsbuf, ":");
+
+ if (virJSONValueObjectAdd(netprops,
+ "s:fds", virBufferCurrentContent(&fdsbuf),
+ NULL) < 0)
+ return NULL;
}
+
is_tap = true;
break;
case VIR_DOMAIN_NET_TYPE_CLIENT:
- virBufferAsprintf(&buf, "socket,connect=%s:%d,",
- net->data.socket.address,
- net->data.socket.port);
+ if (virJSONValueObjectCreate(&netprops, "s:type", "socket", NULL) < 0 ||
+ virJSONValueObjectAppendStringPrintf(netprops, "connect", "%s:%d",
+ net->data.socket.address,
+ net->data.socket.port) < 0)
+ return NULL;
break;
case VIR_DOMAIN_NET_TYPE_SERVER:
- virBufferAsprintf(&buf, "socket,listen=%s:%d,",
- NULLSTR_EMPTY(net->data.socket.address),
- net->data.socket.port);
+ if (virJSONValueObjectCreate(&netprops, "s:type", "socket", NULL) < 0 ||
+ virJSONValueObjectAppendStringPrintf(netprops, "listen", "%s:%d",
+ NULLSTR_EMPTY(net->data.socket.address),
+ net->data.socket.port) < 0)
+ return NULL;
break;
case VIR_DOMAIN_NET_TYPE_MCAST:
- virBufferAsprintf(&buf, "socket,mcast=%s:%d,",
- net->data.socket.address,
- net->data.socket.port);
+ if (virJSONValueObjectCreate(&netprops, "s:type", "socket", NULL) < 0 ||
+ virJSONValueObjectAppendStringPrintf(netprops, "mcast", "%s:%d",
+ net->data.socket.address,
+ net->data.socket.port) < 0)
+ return NULL;
break;
case VIR_DOMAIN_NET_TYPE_UDP:
- virBufferAsprintf(&buf, "socket,udp=%s:%d,localaddr=%s:%d,",
- net->data.socket.address,
- net->data.socket.port,
- net->data.socket.localaddr,
- net->data.socket.localport);
+ if (virJSONValueObjectCreate(&netprops, "s:type", "socket", NULL) < 0 ||
+ virJSONValueObjectAppendStringPrintf(netprops, "udp", "%s:%d",
+ net->data.socket.address,
+ net->data.socket.port) < 0 ||
+ virJSONValueObjectAppendStringPrintf(netprops, "localaddr", "%s:%d",
+ net->data.socket.localaddr,
+ net->data.socket.localport) < 0)
+ return NULL;
break;
case VIR_DOMAIN_NET_TYPE_USER:
if (slirpfd) {
- virBufferAsprintf(&buf, "socket,fd=%s,", slirpfd);
+ if (virJSONValueObjectCreate(&netprops, "s:type", "socket", NULL) < 0 ||
+ virJSONValueObjectAppendString(netprops, "fd", slirpfd) < 0)
+ return NULL;
} else {
- virBufferAddLit(&buf, "user,");
+ if (virJSONValueObjectCreate(&netprops, "s:type", "user", NULL) < 0)
+ return NULL;
+
for (i = 0; i < net->guestIP.nips; i++) {
const virNetDevIPAddr *ip = net->guestIP.ips[i];
g_autofree char *addr = NULL;
@@ -3996,29 +4018,40 @@ qemuBuildHostNetStr(virDomainNetDefPtr net,
return NULL;
if (VIR_SOCKET_ADDR_IS_FAMILY(&ip->address, AF_INET)) {
- virBufferAsprintf(&buf, "net=%s", addr);
+ g_autofree char *ipv4netaddr = NULL;
+
if (ip->prefix)
- virBufferAsprintf(&buf, "/%u", ip->prefix);
- virBufferAddChar(&buf, ',');
+ ipv4netaddr = g_strdup_printf("%s/%u", addr, ip->prefix);
+ else
+ ipv4netaddr = g_strdup(addr);
+
+ if (virJSONValueObjectAppendString(netprops, "net", ipv4netaddr) < 0)
+ return NULL;
} else if (VIR_SOCKET_ADDR_IS_FAMILY(&ip->address, AF_INET6)) {
- virBufferAsprintf(&buf, "ipv6-prefix=%s,", addr);
- if (ip->prefix)
- virBufferAsprintf(&buf, "ipv6-prefixlen=%u,", ip->prefix);
+ if (virJSONValueObjectAppendString(netprops, "ipv6-prefix", addr) < 0)
+ return NULL;
+ if (ip->prefix &&
+ virJSONValueObjectAppendNumberUlong(netprops, "ipv6-prefixlen",
+ ip->prefix) < 0)
+ return NULL;
}
}
}
break;
case VIR_DOMAIN_NET_TYPE_INTERNAL:
- virBufferAddLit(&buf, "user,");
+ if (virJSONValueObjectCreate(&netprops, "s:type", "user", NULL) < 0)
+ return NULL;
break;
case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
- virBufferAsprintf(&buf, "vhost-user,chardev=char%s,",
- net->info.alias);
- if (net->driver.virtio.queues > 1)
- virBufferAsprintf(&buf, "queues=%u,",
- net->driver.virtio.queues);
+ if (virJSONValueObjectCreate(&netprops, "s:type", "vhost-user", NULL) < 0 ||
+ virJSONValueObjectAppendStringPrintf(netprops, "chardev", "char%s", net->info.alias) < 0)
+ return NULL;
+
+ if (net->driver.virtio.queues > 1 &&
+ virJSONValueObjectAppendNumberUlong(netprops, "queues", net->driver.virtio.queues) < 0)
+ return NULL;
break;
case VIR_DOMAIN_NET_TYPE_HOSTDEV:
@@ -4027,31 +4060,38 @@ qemuBuildHostNetStr(virDomainNetDefPtr net,
break;
}
- virBufferAsprintf(&buf, "id=host%s,", net->info.alias);
+ if (virJSONValueObjectAppendStringPrintf(netprops, "id", "host%s", net->info.alias) < 0)
+ return NULL;
if (is_tap) {
if (vhostfdSize) {
- virBufferAddLit(&buf, "vhost=on,");
+ if (virJSONValueObjectAppendBoolean(netprops, "vhost", true) < 0)
+ return NULL;
+
if (vhostfdSize == 1) {
- virBufferAsprintf(&buf, "vhostfd=%s,", vhostfd[0]);
+ if (virJSONValueObjectAdd(netprops, "s:vhostfd", vhostfd[0], NULL) < 0)
+ return NULL;
} else {
- virBufferAddLit(&buf, "vhostfds=");
- for (i = 0; i < vhostfdSize; i++) {
- if (i)
- virBufferAddChar(&buf, ':');
- virBufferAdd(&buf, vhostfd[i], -1);
- }
- virBufferAddChar(&buf, ',');
+ g_auto(virBuffer) fdsbuf = VIR_BUFFER_INITIALIZER;
+
+ for (i = 0; i < vhostfdSize; i++)
+ virBufferAsprintf(&fdsbuf, "%s:", vhostfd[i]);
+
+ virBufferTrim(&fdsbuf, ":");
+
+ if (virJSONValueObjectAdd(netprops,
+ "s:vhostfds", virBufferCurrentContent(&fdsbuf),
+ NULL) < 0)
+ return NULL;
}
}
- if (net->tune.sndbuf_specified)
- virBufferAsprintf(&buf, "sndbuf=%lu,", net->tune.sndbuf);
- }
-
- virBufferTrim(&buf, ",");
+ if (net->tune.sndbuf_specified &&
+ virJSONValueObjectAppendNumberUlong(netprops, "sndbuf", net->tune.sndbuf) < 0)
+ return NULL;
+ }
- return virBufferContentAndReset(&buf);
+ return g_steal_pointer(&netprops);
}
@@ -8006,6 +8046,7 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver,
bool requireNicdev = false;
qemuSlirpPtr slirp;
size_t i;
+ g_autoptr(virJSONValue) hostnetprops = NULL;
if (!bootindex)
@@ -8209,11 +8250,15 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver,
if (chardev)
virCommandAddArgList(cmd, "-chardev", chardev, NULL);
- if (!(host = qemuBuildHostNetStr(net,
- tapfdName, tapfdSize,
- vhostfdName, vhostfdSize,
- slirpfdName)))
+ if (!(hostnetprops = qemuBuildHostNetStr(net,
+ tapfdName, tapfdSize,
+ vhostfdName, vhostfdSize,
+ slirpfdName)))
goto cleanup;
+
+ if (!(host = virQEMUBuildNetdevCommandlineFromJSON(hostnetprops)))
+ goto cleanup;
+
virCommandAddArgList(cmd, "-netdev", host, NULL);
/* Possible combinations:
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index 274084821b..00d9a9da8f 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -89,12 +89,12 @@ qemuBuildChrDeviceStr(char **deviceStr,
char *
qemuBuildChannelGuestfwdNetdevProps(virDomainChrDefPtr chr);
-char *qemuBuildHostNetStr(virDomainNetDefPtr net,
- char **tapfd,
- size_t tapfdSize,
- char **vhostfd,
- size_t vhostfdSize,
- const char *slirpfd);
+virJSONValuePtr qemuBuildHostNetStr(virDomainNetDefPtr net,
+ char **tapfd,
+ size_t tapfdSize,
+ char **vhostfd,
+ size_t vhostfdSize,
+ const char *slirpfd);
/* Current, best practice */
char *qemuBuildNicDevStr(virDomainDefPtr def,
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index ee97397235..1877aef1b0 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -54,6 +54,7 @@
#include "virstoragefile.h"
#include "virstring.h"
#include "virtime.h"
+#include "virqemu.h"
#define VIR_FROM_THIS VIR_FROM_QEMU
@@ -1157,6 +1158,7 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
size_t vhostfdSize = 0;
size_t queueSize = 0;
g_autofree char *nicstr = NULL;
+ g_autoptr(virJSONValue) netprops = NULL;
g_autofree char *netstr = NULL;
int ret = -1;
bool releaseaddr = false;
@@ -1382,10 +1384,13 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
for (i = 0; i < vhostfdSize; i++)
vhostfdName[i] = g_strdup_printf("vhostfd-%s%zu", net->info.alias, i);
- if (!(netstr = qemuBuildHostNetStr(net,
- tapfdName, tapfdSize,
- vhostfdName, vhostfdSize,
- slirpfdName)))
+ if (!(netprops = qemuBuildHostNetStr(net,
+ tapfdName, tapfdSize,
+ vhostfdName, vhostfdSize,
+ slirpfdName)))
+ goto cleanup;
+
+ if (!(netstr = virQEMUBuildNetdevCommandlineFromJSON(netprops)))
goto cleanup;
qemuDomainObjEnterMonitor(driver, vm);
--
2.23.0.windows.1

View File

@ -0,0 +1,152 @@
From f0b20bfdd5e0967da8b98a1c66649c23a94b3d3c Mon Sep 17 00:00:00 2001
From: Peter Krempa <pkrempa@redhat.com>
Date: Thu, 14 May 2020 13:01:59 +0200
Subject: [PATCH 07/18] qemuBuildChannelChrDeviceStr: Remove formatting of
properties for -netdev
The output of the function is fed as argument to '-device' command line
argument or 'device_add' monitor command except for 'guestfwd' channels
where it needs to be fed to -netdev/netdev_add. This is confusing and
error prone. Split it up since the caller needs to know which
command/option to use anyways, so the caller can call the appropriate
function without any magic.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
src/qemu/qemu_command.c | 36 ++++++++++++++++++++----------------
src/qemu/qemu_command.h | 3 +++
src/qemu/qemu_hotplug.c | 18 +++++++++++++-----
3 files changed, 36 insertions(+), 21 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 579e78ea75..056a74fb60 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -8872,7 +8872,7 @@ qemuBuildChannelsCommandLine(virLogManagerPtr logManager,
switch ((virDomainChrChannelTargetType) channel->targetType) {
case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_GUESTFWD:
- if (qemuBuildChrDeviceStr(&netdevstr, def, channel, qemuCaps) < 0)
+ if (!(netdevstr = qemuBuildChannelGuestfwdNetdevProps(channel)))
return -1;
virCommandAddArgList(cmd, "-netdev", netdevstr, NULL);
break;
@@ -10140,36 +10140,40 @@ qemuBuildParallelChrDeviceStr(char **deviceStr,
return 0;
}
-static int
-qemuBuildChannelChrDeviceStr(char **deviceStr,
- const virDomainDef *def,
- virDomainChrDefPtr chr)
+
+char *
+qemuBuildChannelGuestfwdNetdevProps(virDomainChrDefPtr chr)
{
- int ret = -1;
g_autofree char *addr = NULL;
int port;
- switch ((virDomainChrChannelTargetType)chr->targetType) {
- case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_GUESTFWD:
+ if (!(addr = virSocketAddrFormat(chr->target.addr)))
+ return NULL;
- addr = virSocketAddrFormat(chr->target.addr);
- if (!addr)
- return ret;
- port = virSocketAddrGetPort(chr->target.addr);
+ port = virSocketAddrGetPort(chr->target.addr);
+
+ return g_strdup_printf("user,guestfwd=tcp:%s:%i-chardev:char%s,id=%s",
+ addr, port, chr->info.alias, chr->info.alias);
+}
- *deviceStr = g_strdup_printf("user,guestfwd=tcp:%s:%i-chardev:char%s,id=%s",
- addr, port, chr->info.alias, chr->info.alias);
- break;
+static int
+qemuBuildChannelChrDeviceStr(char **deviceStr,
+ const virDomainDef *def,
+ virDomainChrDefPtr chr)
+{
+ switch ((virDomainChrChannelTargetType)chr->targetType) {
case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO:
if (!(*deviceStr = qemuBuildVirtioSerialPortDevStr(def, chr)))
return -1;
break;
+ case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_GUESTFWD:
+ /* guestfwd is as a netdev handled separately */
case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_XEN:
case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_NONE:
case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_LAST:
- return ret;
+ return -1;
}
return 0;
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index bc3ba44fb3..274084821b 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -86,6 +86,9 @@ qemuBuildChrDeviceStr(char **deviceStr,
virDomainChrDefPtr chr,
virQEMUCapsPtr qemuCaps);
+char *
+qemuBuildChannelGuestfwdNetdevProps(virDomainChrDefPtr chr);
+
char *qemuBuildHostNetStr(virDomainNetDefPtr net,
char **tapfd,
size_t tapfdSize,
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 60d0729f1e..ee97397235 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -2108,6 +2108,7 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
virErrorPtr orig_err;
virDomainDefPtr vmdef = vm->def;
g_autofree char *devstr = NULL;
+ g_autofree char *netdevstr = NULL;
virDomainChrSourceDefPtr dev = chr->source;
g_autofree char *charAlias = NULL;
bool chardevAttached = false;
@@ -2146,8 +2147,13 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
goto cleanup;
teardowncgroup = true;
- if (qemuBuildChrDeviceStr(&devstr, vmdef, chr, priv->qemuCaps) < 0)
- goto cleanup;
+ if (guestfwd) {
+ if (!(netdevstr = qemuBuildChannelGuestfwdNetdevProps(chr)))
+ goto cleanup;
+ } else {
+ if (qemuBuildChrDeviceStr(&devstr, vmdef, chr, priv->qemuCaps) < 0)
+ goto cleanup;
+ }
if (!(charAlias = qemuAliasChardevFromDevAlias(chr->info.alias)))
goto cleanup;
@@ -2166,11 +2172,13 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
goto exit_monitor;
chardevAttached = true;
- if (guestfwd) {
- if (qemuMonitorAddNetdev(priv->mon, devstr,
+ if (netdevstr) {
+ if (qemuMonitorAddNetdev(priv->mon, netdevstr,
NULL, NULL, 0, NULL, NULL, 0, -1, NULL) < 0)
goto exit_monitor;
- } else {
+ }
+
+ if (devstr) {
if (qemuMonitorAddDevice(priv->mon, devstr) < 0)
goto exit_monitor;
}
--
2.23.0.windows.1

View File

@ -0,0 +1,128 @@
From 17e751be222dd86959f71afda2fca8b0ed09f55b Mon Sep 17 00:00:00 2001
From: Peter Krempa <pkrempa@redhat.com>
Date: Fri, 15 May 2020 09:46:08 +0200
Subject: [PATCH 11/18] qemuBuildChannelGuestfwdNetdevProps: Convert to
generating JSON props
Syntax of guestfwd channel also needs to be modified to conform to the
QAPI schema.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
src/qemu/qemu_command.c | 37 +++++++++++++++++++++++++++++++------
src/qemu/qemu_command.h | 2 +-
src/qemu/qemu_hotplug.c | 6 +++++-
3 files changed, 37 insertions(+), 8 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 141657b3e4..bd78bfb31b 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -8903,6 +8903,7 @@ qemuBuildChannelsCommandLine(virLogManagerPtr logManager,
for (i = 0; i < def->nchannels; i++) {
virDomainChrDefPtr channel = def->channels[i];
g_autofree char *chardevstr = NULL;
+ g_autoptr(virJSONValue) netdevprops = NULL;
g_autofree char *netdevstr = NULL;
if (!(chardevstr = qemuBuildChrChardevStr(logManager, secManager,
@@ -8917,8 +8918,12 @@ qemuBuildChannelsCommandLine(virLogManagerPtr logManager,
switch ((virDomainChrChannelTargetType) channel->targetType) {
case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_GUESTFWD:
- if (!(netdevstr = qemuBuildChannelGuestfwdNetdevProps(channel)))
+ if (!(netdevprops = qemuBuildChannelGuestfwdNetdevProps(channel)))
return -1;
+
+ if (!(netdevstr = virQEMUBuildNetdevCommandlineFromJSON(netdevprops)))
+ return -1;
+
virCommandAddArgList(cmd, "-netdev", netdevstr, NULL);
break;
@@ -10186,19 +10191,39 @@ qemuBuildParallelChrDeviceStr(char **deviceStr,
}
-char *
+virJSONValuePtr
qemuBuildChannelGuestfwdNetdevProps(virDomainChrDefPtr chr)
{
+ g_autoptr(virJSONValue) guestfwdarr = virJSONValueNewArray();
+ g_autoptr(virJSONValue) guestfwdstrobj = virJSONValueNewObject();
g_autofree char *addr = NULL;
- int port;
+ virJSONValuePtr ret = NULL;
if (!(addr = virSocketAddrFormat(chr->target.addr)))
return NULL;
- port = virSocketAddrGetPort(chr->target.addr);
+ /* this may seem weird, but qemu indeed decided that 'guestfwd' parameter
+ * is an array of objects which have just one member named 'str' which
+ * contains the description */
+ if (virJSONValueObjectAppendStringPrintf(guestfwdstrobj, "str",
+ "tcp:%s:%i-chardev:char%s",
+ addr,
+ virSocketAddrGetPort(chr->target.addr),
+ chr->info.alias) < 0)
+ return NULL;
+
+ if (virJSONValueArrayAppend(guestfwdarr, guestfwdstrobj) < 0)
+ return NULL;
+ guestfwdstrobj = NULL;
- return g_strdup_printf("user,guestfwd=tcp:%s:%i-chardev:char%s,id=%s",
- addr, port, chr->info.alias, chr->info.alias);
+ if (virJSONValueObjectCreate(&ret,
+ "s:type", "user",
+ "a:guestfwd", &guestfwdarr,
+ "s:id", chr->info.alias,
+ NULL) < 0)
+ return NULL;
+
+ return ret;
}
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index 00d9a9da8f..1e6b23ba05 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -86,7 +86,7 @@ qemuBuildChrDeviceStr(char **deviceStr,
virDomainChrDefPtr chr,
virQEMUCapsPtr qemuCaps);
-char *
+virJSONValuePtr
qemuBuildChannelGuestfwdNetdevProps(virDomainChrDefPtr chr);
virJSONValuePtr qemuBuildHostNetStr(virDomainNetDefPtr net,
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 1877aef1b0..24a898166d 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -2113,6 +2113,7 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
virErrorPtr orig_err;
virDomainDefPtr vmdef = vm->def;
g_autofree char *devstr = NULL;
+ g_autoptr(virJSONValue) netdevprops = NULL;
g_autofree char *netdevstr = NULL;
virDomainChrSourceDefPtr dev = chr->source;
g_autofree char *charAlias = NULL;
@@ -2153,7 +2154,10 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
teardowncgroup = true;
if (guestfwd) {
- if (!(netdevstr = qemuBuildChannelGuestfwdNetdevProps(chr)))
+ if (!(netdevprops = qemuBuildChannelGuestfwdNetdevProps(chr)))
+ goto cleanup;
+
+ if (!(netdevstr = virQEMUBuildNetdevCommandlineFromJSON(netdevprops)))
goto cleanup;
} else {
if (qemuBuildChrDeviceStr(&devstr, vmdef, chr, priv->qemuCaps) < 0)
--
2.23.0.windows.1

View File

@ -0,0 +1,72 @@
From 31c32f8d76a447899ff4a5c551c06a2888814111 Mon Sep 17 00:00:00 2001
From: Peter Krempa <pkrempa@redhat.com>
Date: Thu, 14 May 2020 12:51:21 +0200
Subject: [PATCH 06/18] qemuBuildChannelsCommandLine: Extract common formatting
of 'chardev'
Both active branches create the same backend chardev. Since there is no
other case, extract it before the switch so that we don't have to
duplicate it.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
src/qemu/qemu_command.c | 32 +++++++++++---------------------
1 file changed, 11 insertions(+), 21 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 7c4db11ae2..579e78ea75 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -8857,37 +8857,27 @@ qemuBuildChannelsCommandLine(virLogManagerPtr logManager,
for (i = 0; i < def->nchannels; i++) {
virDomainChrDefPtr channel = def->channels[i];
- char *devstr;
+ g_autofree char *chardevstr = NULL;
+ g_autofree char *netdevstr = NULL;
- switch ((virDomainChrChannelTargetType) channel->targetType) {
- case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_GUESTFWD:
- if (!(devstr = qemuBuildChrChardevStr(logManager, secManager,
+ if (!(chardevstr = qemuBuildChrChardevStr(logManager, secManager,
cmd, cfg, def,
channel->source,
channel->info.alias,
qemuCaps, cdevflags)))
- return -1;
- virCommandAddArg(cmd, "-chardev");
- virCommandAddArg(cmd, devstr);
- VIR_FREE(devstr);
+ return -1;
- if (qemuBuildChrDeviceStr(&devstr, def, channel, qemuCaps) < 0)
+ virCommandAddArg(cmd, "-chardev");
+ virCommandAddArg(cmd, chardevstr);
+
+ switch ((virDomainChrChannelTargetType) channel->targetType) {
+ case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_GUESTFWD:
+ if (qemuBuildChrDeviceStr(&netdevstr, def, channel, qemuCaps) < 0)
return -1;
- virCommandAddArgList(cmd, "-netdev", devstr, NULL);
- VIR_FREE(devstr);
+ virCommandAddArgList(cmd, "-netdev", netdevstr, NULL);
break;
case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO:
- if (!(devstr = qemuBuildChrChardevStr(logManager, secManager,
- cmd, cfg, def,
- channel->source,
- channel->info.alias,
- qemuCaps, cdevflags)))
- return -1;
- virCommandAddArg(cmd, "-chardev");
- virCommandAddArg(cmd, devstr);
- VIR_FREE(devstr);
-
if (qemuBuildChrDeviceCommandLine(cmd, def, channel, qemuCaps) < 0)
return -1;
break;
--
2.23.0.windows.1

View File

@ -0,0 +1,42 @@
From 2aac11e296b60464c0ef4870879b6e75d5e0ee46 Mon Sep 17 00:00:00 2001
From: Peter Krempa <pkrempa@redhat.com>
Date: Thu, 14 May 2020 12:32:55 +0200
Subject: [PATCH 05/18] qemuBuildChannelsCommandLine: Use typecasted switch for
channel type
Cover all cases of the enum.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
src/qemu/qemu_command.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index c3ad041959..7c4db11ae2 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -8859,7 +8859,7 @@ qemuBuildChannelsCommandLine(virLogManagerPtr logManager,
virDomainChrDefPtr channel = def->channels[i];
char *devstr;
- switch (channel->targetType) {
+ switch ((virDomainChrChannelTargetType) channel->targetType) {
case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_GUESTFWD:
if (!(devstr = qemuBuildChrChardevStr(logManager, secManager,
cmd, cfg, def,
@@ -8891,6 +8891,11 @@ qemuBuildChannelsCommandLine(virLogManagerPtr logManager,
if (qemuBuildChrDeviceCommandLine(cmd, def, channel, qemuCaps) < 0)
return -1;
break;
+
+ case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_XEN:
+ case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_NONE:
+ case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_LAST:
+ return -1;
}
}
--
2.23.0.windows.1

View File

@ -0,0 +1,68 @@
From ed5210b67f18478af5669976abb6b61c3bd576e0 Mon Sep 17 00:00:00 2001
From: Peter Krempa <pkrempa@redhat.com>
Date: Thu, 14 May 2020 12:02:55 +0200
Subject: [PATCH 09/18] qemuBuildHostNetStr: Stop using 'ipv6-net' convenience
argument
In qemu the argument of 'ipv6-net' is split up into 'ipv6-prefix' and
'ipv6-prefixlen'. Additionally now that 'netdev_add' was qapified, only
the real properties are allowed. Switch to using them explicitly.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
src/qemu/qemu_command.c | 20 ++++++++++----------
tests/qemuxml2argvdata/net-user-addr.args | 3 ++-
2 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 056a74fb60..688c9db851 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3991,20 +3991,20 @@ qemuBuildHostNetStr(virDomainNetDefPtr net,
for (i = 0; i < net->guestIP.nips; i++) {
const virNetDevIPAddr *ip = net->guestIP.ips[i];
g_autofree char *addr = NULL;
- const char *prefix = "";
if (!(addr = virSocketAddrFormat(&ip->address)))
return NULL;
- if (VIR_SOCKET_ADDR_IS_FAMILY(&ip->address, AF_INET))
- prefix = "net=";
- if (VIR_SOCKET_ADDR_IS_FAMILY(&ip->address, AF_INET6))
- prefix = "ipv6-net=";
-
- virBufferAsprintf(&buf, "%s%s", prefix, addr);
- if (ip->prefix)
- virBufferAsprintf(&buf, "/%u", ip->prefix);
- virBufferAddChar(&buf, ',');
+ if (VIR_SOCKET_ADDR_IS_FAMILY(&ip->address, AF_INET)) {
+ virBufferAsprintf(&buf, "net=%s", addr);
+ if (ip->prefix)
+ virBufferAsprintf(&buf, "/%u", ip->prefix);
+ virBufferAddChar(&buf, ',');
+ } else if (VIR_SOCKET_ADDR_IS_FAMILY(&ip->address, AF_INET6)) {
+ virBufferAsprintf(&buf, "ipv6-prefix=%s,", addr);
+ if (ip->prefix)
+ virBufferAsprintf(&buf, "ipv6-prefixlen=%u,", ip->prefix);
+ }
}
}
break;
diff --git a/tests/qemuxml2argvdata/net-user-addr.args b/tests/qemuxml2argvdata/net-user-addr.args
index 6cc82d9e62..5f1de305e0 100644
--- a/tests/qemuxml2argvdata/net-user-addr.args
+++ b/tests/qemuxml2argvdata/net-user-addr.args
@@ -27,6 +27,7 @@ server,nowait \
-usb \
-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \
-device ide-hd,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,bootindex=1 \
--netdev user,net=172.17.2.0/24,ipv6-net=2001:db8:ac10:fd01::/64,id=hostnet0 \
+-netdev user,net=172.17.2.0/24,ipv6-prefix=2001:db8:ac10:fd01::,\
+ipv6-prefixlen=64,id=hostnet0 \
-device rtl8139,netdev=hostnet0,id=net0,mac=00:11:22:33:44:55,bus=pci.0,\
addr=0x3
--
2.23.0.windows.1

View File

@ -0,0 +1,46 @@
From 6a0f76d72b231bf0baacf70d715aad387476ac98 Mon Sep 17 00:00:00 2001
From: xiaojin Yang <yangxiaojin2@huawei.com>
Date: Fri, 11 Mar 2022 16:03:02 +0800
Subject: [PATCH 7/8] qemuBuildNumaArgStr: Switch order of if() and for()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When building -numa command line there is a for() loop that
builds '-numa memdev=' for each guest NUMA node. And also
records in a local variable whether any of memory-object-*
backends must be used to satisfy desired config. Well, instead of
checking in each iteration whether corresponding capabilities are
set, we can do swap if() and for() and check only once.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Signed-off-by: Xiaojin Yang <yangxiaojin2@huawei.com>
---
src/qemu/qemu_command.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index dae6b5a7f9..f9b6d56209 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -7419,11 +7419,11 @@ qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg,
/* using of -numa memdev= cannot be combined with -numa mem=, thus we
* need to check which approach to use */
- for (i = 0; i < ncells; i++) {
- if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_RAM) ||
- virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE) ||
- virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_MEMFD)) {
+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_RAM) ||
+ virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE) ||
+ virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_MEMFD)) {
+ for (i = 0; i < ncells; i++) {
if ((rc = qemuBuildMemoryCellBackendStr(def, cfg, i, priv,
&nodeBackends[i])) < 0)
goto cleanup;
--
2.27.0

View File

@ -0,0 +1,57 @@
From a6fccda9f1637a3464e812a16c2cd1f12d5b213d Mon Sep 17 00:00:00 2001
From: xiaojin Yang <yangxiaojin2@huawei.com>
Date: Fri, 11 Mar 2022 16:04:38 +0800
Subject: [PATCH 8/8] qemuBuildNumaArgStr: Use modern -numa memdev= if old
-numa mem= is unsupported
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
In previous commit we started tracking whether QEMU supports
'-numa mem='. This is tied to the machine type because migration
from '-numa mem=' to '-numa memdev' is impossible (or vice
versa). But since it's tied to a machine type (where migration
from one to another is also unsupported) we can allow QEMU to get
rid of the deprecated command line.
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1783355
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Signed-off-by: Xiaojin Yang <yangxiaojin2@huawei.com>
---
src/qemu/qemu_command.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index f9b6d56209..f8331a7455 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -7414,6 +7414,11 @@ qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg,
if (!virDomainNumatuneNodesetIsAvailable(def->numa, priv->autoNodeset))
goto cleanup;
+ if (!virQEMUCapsGetMachineNumaMemSupported(qemuCaps,
+ def->virtType,
+ def->os.machine))
+ needBackend = true;
+
if (VIR_ALLOC_N(nodeBackends, ncells) < 0)
goto cleanup;
@@ -7431,6 +7436,11 @@ qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg,
if (rc == 0)
needBackend = true;
}
+ } else if (needBackend) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("NUMA without specified memory backing is not "
+ "supported with this QEMU binary"));
+ goto cleanup;
}
if (!needBackend &&
--
2.27.0

View File

@ -0,0 +1,198 @@
From 2d555c8e864c8ba7dbc7a22e37712b70b59e5293 Mon Sep 17 00:00:00 2001
From: Peter Krempa <pkrempa@redhat.com>
Date: Fri, 15 May 2020 11:36:28 +0200
Subject: [PATCH 12/18] qemuMonitorAddNetdev: Convert to the native JSON props
object
Now that all code paths generate JSON props we can remove the conversion
to command line arguments and back in the monitor code.
Note that the test which is removed in this commit will be replaced by a
stronger testsuite later.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
src/qemu/qemu_hotplug.c | 14 +++-----------
src/qemu/qemu_monitor.c | 8 ++++----
src/qemu/qemu_monitor.h | 2 +-
src/qemu/qemu_monitor_json.c | 15 +++------------
src/qemu/qemu_monitor_json.h | 2 +-
tests/qemumonitorjsontest.c | 2 --
6 files changed, 12 insertions(+), 31 deletions(-)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 24a898166d..d7bcb6a99f 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1159,7 +1159,6 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
size_t queueSize = 0;
g_autofree char *nicstr = NULL;
g_autoptr(virJSONValue) netprops = NULL;
- g_autofree char *netstr = NULL;
int ret = -1;
bool releaseaddr = false;
bool iface_connected = false;
@@ -1390,9 +1389,6 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
slirpfdName)))
goto cleanup;
- if (!(netstr = virQEMUBuildNetdevCommandlineFromJSON(netprops)))
- goto cleanup;
-
qemuDomainObjEnterMonitor(driver, vm);
if (actualType == VIR_DOMAIN_NET_TYPE_VHOSTUSER) {
@@ -1404,7 +1400,7 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
charDevPlugged = true;
}
- if (qemuMonitorAddNetdev(priv->mon, netstr,
+ if (qemuMonitorAddNetdev(priv->mon, &netprops,
tapfd, tapfdName, tapfdSize,
vhostfd, vhostfdName, vhostfdSize,
slirpfd, slirpfdName) < 0) {
@@ -2114,7 +2110,6 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
virDomainDefPtr vmdef = vm->def;
g_autofree char *devstr = NULL;
g_autoptr(virJSONValue) netdevprops = NULL;
- g_autofree char *netdevstr = NULL;
virDomainChrSourceDefPtr dev = chr->source;
g_autofree char *charAlias = NULL;
bool chardevAttached = false;
@@ -2156,9 +2151,6 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
if (guestfwd) {
if (!(netdevprops = qemuBuildChannelGuestfwdNetdevProps(chr)))
goto cleanup;
-
- if (!(netdevstr = virQEMUBuildNetdevCommandlineFromJSON(netdevprops)))
- goto cleanup;
} else {
if (qemuBuildChrDeviceStr(&devstr, vmdef, chr, priv->qemuCaps) < 0)
goto cleanup;
@@ -2181,8 +2173,8 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
goto exit_monitor;
chardevAttached = true;
- if (netdevstr) {
- if (qemuMonitorAddNetdev(priv->mon, netdevstr,
+ if (netdevprops) {
+ if (qemuMonitorAddNetdev(priv->mon, &netdevprops,
NULL, NULL, 0, NULL, NULL, 0, -1, NULL) < 0)
goto exit_monitor;
}
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index cc62948c9c..9f4432ab3a 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -2667,7 +2667,7 @@ qemuMonitorCloseFileHandle(qemuMonitorPtr mon,
int
qemuMonitorAddNetdev(qemuMonitorPtr mon,
- const char *netdevstr,
+ virJSONValuePtr *props,
int *tapfd, char **tapfdName, int tapfdSize,
int *vhostfd, char **vhostfdName, int vhostfdSize,
int slirpfd, char *slirpfdName)
@@ -2675,10 +2675,10 @@ qemuMonitorAddNetdev(qemuMonitorPtr mon,
int ret = -1;
size_t i = 0, j = 0;
- VIR_DEBUG("netdevstr=%s tapfd=%p tapfdName=%p tapfdSize=%d"
+ VIR_DEBUG("props=%p tapfd=%p tapfdName=%p tapfdSize=%d"
"vhostfd=%p vhostfdName=%p vhostfdSize=%d"
"slirpfd=%d slirpfdName=%s",
- netdevstr, tapfd, tapfdName, tapfdSize,
+ props, tapfd, tapfdName, tapfdSize,
vhostfd, vhostfdName, vhostfdSize, slirpfd, slirpfdName);
QEMU_CHECK_MONITOR(mon);
@@ -2696,7 +2696,7 @@ qemuMonitorAddNetdev(qemuMonitorPtr mon,
qemuMonitorSendFileHandle(mon, slirpfdName, slirpfd) < 0)
goto cleanup;
- ret = qemuMonitorJSONAddNetdev(mon, netdevstr);
+ ret = qemuMonitorJSONAddNetdev(mon, props);
cleanup:
if (ret < 0) {
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 68e21dcaee..7a3240f00a 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -881,7 +881,7 @@ int qemuMonitorCloseFileHandle(qemuMonitorPtr mon,
const char *fdname);
int qemuMonitorAddNetdev(qemuMonitorPtr mon,
- const char *netdevstr,
+ virJSONValuePtr *props,
int *tapfd, char **tapfdName, int tapfdSize,
int *vhostfd, char **vhostfdName, int vhostfdSize,
int slirpfd, char *slirpfdName);
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index e6b5c7140e..c1d92b2009 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -3993,23 +3993,14 @@ int qemuMonitorJSONCloseFileHandle(qemuMonitorPtr mon,
int
qemuMonitorJSONAddNetdev(qemuMonitorPtr mon,
- const char *netdevstr)
+ virJSONValuePtr *props)
{
g_autoptr(virJSONValue) cmd = NULL;
g_autoptr(virJSONValue) reply = NULL;
- g_autoptr(virJSONValue) args = NULL;
-
- cmd = qemuMonitorJSONMakeCommand("netdev_add", NULL);
- if (!cmd)
- return -1;
-
- args = qemuMonitorJSONKeywordStringToJSON(netdevstr, "type");
- if (!args)
- return -1;
+ virJSONValuePtr pr = g_steal_pointer(props);
- if (virJSONValueObjectAppend(cmd, "arguments", args) < 0)
+ if (!(cmd = qemuMonitorJSONMakeCommandInternal("netdev_add", pr)))
return -1;
- args = NULL; /* obj owns reference to args now */
if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
return -1;
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 05a46b4fe2..dd25e5d6e6 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -210,7 +210,7 @@ int qemuMonitorJSONCloseFileHandle(qemuMonitorPtr mon,
const char *fdname);
int qemuMonitorJSONAddNetdev(qemuMonitorPtr mon,
- const char *netdevstr);
+ virJSONValuePtr *props);
int qemuMonitorJSONRemoveNetdev(qemuMonitorPtr mon,
const char *alias);
diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c
index 472775a3cf..2ec143f476 100644
--- a/tests/qemumonitorjsontest.c
+++ b/tests/qemumonitorjsontest.c
@@ -1308,7 +1308,6 @@ GEN_TEST_FUNC(qemuMonitorJSONDump, "dummy_protocol", "elf",
true)
GEN_TEST_FUNC(qemuMonitorJSONGraphicsRelocate, VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
"localhost", 12345, 12346, "certsubjectval")
-GEN_TEST_FUNC(qemuMonitorJSONAddNetdev, "id=net0,type=test")
GEN_TEST_FUNC(qemuMonitorJSONRemoveNetdev, "net0")
GEN_TEST_FUNC(qemuMonitorJSONDelDevice, "ide0")
GEN_TEST_FUNC(qemuMonitorJSONAddDevice, "some_dummy_devicestr")
@@ -3192,7 +3191,6 @@ mymain(void)
DO_TEST_GEN(qemuMonitorJSONMigrate);
DO_TEST_GEN(qemuMonitorJSONDump);
DO_TEST_GEN(qemuMonitorJSONGraphicsRelocate);
- DO_TEST_GEN(qemuMonitorJSONAddNetdev);
DO_TEST_GEN(qemuMonitorJSONRemoveNetdev);
DO_TEST_GEN(qemuMonitorJSONDelDevice);
DO_TEST_GEN(qemuMonitorJSONAddDevice);
--
2.23.0.windows.1

View File

@ -0,0 +1,107 @@
From 3e1026fb3619aae6b1be4879797474d10d22a54c Mon Sep 17 00:00:00 2001
From: Peter Krempa <pkrempa@redhat.com>
Date: Fri, 15 May 2020 11:16:32 +0200
Subject: [PATCH 08/18] qemuMonitorJSON(Add|Remove)Netdev: Refactor cleanup
Use automatic pointer cleanup for virJSONValuePtrs to get rid of the
cleanup label and ret variable.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
src/qemu/qemu_monitor_json.c | 52 +++++++++++++++---------------------
1 file changed, 22 insertions(+), 30 deletions(-)
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index ef25764a98..e6b5c7140e 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -3991,13 +3991,13 @@ int qemuMonitorJSONCloseFileHandle(qemuMonitorPtr mon,
}
-int qemuMonitorJSONAddNetdev(qemuMonitorPtr mon,
- const char *netdevstr)
+int
+qemuMonitorJSONAddNetdev(qemuMonitorPtr mon,
+ const char *netdevstr)
{
- int ret = -1;
- virJSONValuePtr cmd = NULL;
- virJSONValuePtr reply = NULL;
- virJSONValuePtr args = NULL;
+ g_autoptr(virJSONValue) cmd = NULL;
+ g_autoptr(virJSONValue) reply = NULL;
+ g_autoptr(virJSONValue) args = NULL;
cmd = qemuMonitorJSONMakeCommand("netdev_add", NULL);
if (!cmd)
@@ -4005,49 +4005,41 @@ int qemuMonitorJSONAddNetdev(qemuMonitorPtr mon,
args = qemuMonitorJSONKeywordStringToJSON(netdevstr, "type");
if (!args)
- goto cleanup;
+ return -1;
if (virJSONValueObjectAppend(cmd, "arguments", args) < 0)
- goto cleanup;
+ return -1;
args = NULL; /* obj owns reference to args now */
if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
- goto cleanup;
+ return -1;
if (qemuMonitorJSONCheckError(cmd, reply) < 0)
- goto cleanup;
+ return -1;
- ret = 0;
- cleanup:
- virJSONValueFree(args);
- virJSONValueFree(cmd);
- virJSONValueFree(reply);
- return ret;
+ return 0;
}
-int qemuMonitorJSONRemoveNetdev(qemuMonitorPtr mon,
- const char *alias)
+int
+qemuMonitorJSONRemoveNetdev(qemuMonitorPtr mon,
+ const char *alias)
{
- int ret = -1;
- virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("netdev_del",
- "s:id", alias,
- NULL);
- virJSONValuePtr reply = NULL;
+ g_autoptr(virJSONValue) cmd = qemuMonitorJSONMakeCommand("netdev_del",
+ "s:id", alias,
+ NULL);
+ g_autoptr(virJSONValue) reply = NULL;
+
if (!cmd)
return -1;
if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
- goto cleanup;
+ return -1;
if (qemuMonitorJSONCheckError(cmd, reply) < 0)
- goto cleanup;
+ return -1;
- ret = 0;
- cleanup:
- virJSONValueFree(cmd);
- virJSONValueFree(reply);
- return ret;
+ return 0;
}
--
2.23.0.windows.1

View File

@ -0,0 +1,149 @@
From 85a1643f583a46b1fc3a01d5c2e87ba6262be586 Mon Sep 17 00:00:00 2001
From: Michal Privoznik <mprivozn@redhat.com>
Date: Wed, 24 Feb 2021 17:28:42 +0100
Subject: [PATCH 5/6] qemu_tpm: Generate log file path among with storage path
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When starting a guest with TPM of type='emulator' an external
process is started with it (swtpm) to emulate TPM. This external
process is passed path to a log file via --logfile. The path to
the log file is generated in qemuTPMEmulatorPrepareHost() which
works, until the daemon is restarted. The problem is that the
path is not stored in private data or anywhere inside live XML
and thus later, when qemuExtTPMStop() is called (when shutting
off the guest) the stored logpath is NULL and thus its seclabel
is not cleaned up (see virSecuritySELinuxRestoreTPMLabels()).
Fortunately, qemuExtDevicesStop() (which calls qemuExtTPMStop()
eventually) does call qemuExtDevicesInitPaths() where the log
path can be generated again.
Basically, tpm->data.emulator.storagepath is generated in
qemuExtTPMInitPaths() and its seclabels are restored properly,
and this commit move logfile onto the same level.
This means, that the log path doesn't have to be generated in
qemuExtDevicesStart() because it was already done in
qemuExtDevicesPrepareHost().
This change also renders @vmname argument of
qemuTPMEmulatorPrepareHost() unused and thus is removed.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1769196
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Signed-off-by: yezengruan <yezengruan@huawei.com>
---
src/qemu/qemu_extdevice.c | 6 +++---
src/qemu/qemu_tpm.c | 22 ++++++++++++++--------
2 files changed, 17 insertions(+), 11 deletions(-)
diff --git a/src/qemu/qemu_extdevice.c b/src/qemu/qemu_extdevice.c
index 5a31b4d66e..025929cbcc 100644
--- a/src/qemu/qemu_extdevice.c
+++ b/src/qemu/qemu_extdevice.c
@@ -133,6 +133,9 @@ qemuExtDevicesPrepareHost(virQEMUDriverPtr driver,
virDomainDefPtr def = vm->def;
size_t i;
+ if (qemuExtDevicesInitPaths(driver, def) < 0)
+ return -1;
+
if (def->tpm &&
qemuExtTPMPrepareHost(driver, def) < 0)
return -1;
@@ -170,9 +173,6 @@ qemuExtDevicesStart(virQEMUDriverPtr driver,
virDomainDefPtr def = vm->def;
size_t i;
- if (qemuExtDevicesInitPaths(driver, def) < 0)
- return -1;
-
for (i = 0; i < def->nvideos; i++) {
virDomainVideoDefPtr video = def->videos[i];
diff --git a/src/qemu/qemu_tpm.c b/src/qemu/qemu_tpm.c
index eb155b92b0..601d5cf4e9 100644
--- a/src/qemu/qemu_tpm.c
+++ b/src/qemu/qemu_tpm.c
@@ -200,11 +200,15 @@ qemuTPMCreateEmulatorSocket(const char *swtpmStateDir,
* @tpm: TPM definition for an emulator type
* @swtpmStorageDir: the general swtpm storage dir which is used as a base
* directory for creating VM specific directories
+ * @logDir: directory where swtpm writes its logs into
+ * @vmname: name of the VM
* @uuid: the UUID of the VM
*/
static int
qemuTPMEmulatorInitPaths(virDomainTPMDefPtr tpm,
const char *swtpmStorageDir,
+ const char *logDir,
+ const char *vmname,
const unsigned char *uuid)
{
char uuidstr[VIR_UUID_STRING_BUFLEN];
@@ -217,6 +221,11 @@ qemuTPMEmulatorInitPaths(virDomainTPMDefPtr tpm,
tpm->version)))
return -1;
+ if (!tpm->data.emulator.logfile) {
+ tpm->data.emulator.logfile = qemuTPMCreateEmulatorLogPath(logDir,
+ vmname);
+ }
+
return 0;
}
@@ -273,7 +282,6 @@ qemuTPMEmulatorGetPid(const char *swtpmStateDir,
*
* @tpm: tpm definition
* @logDir: directory where swtpm writes its logs into
- * @vmname: name of the VM
* @swtpm_user: uid to run the swtpm with
* @swtpm_group: gid to run the swtpm with
* @swtpmStateDir: directory for swtpm's persistent state
@@ -287,7 +295,6 @@ qemuTPMEmulatorGetPid(const char *swtpmStateDir,
static int
qemuTPMEmulatorPrepareHost(virDomainTPMDefPtr tpm,
const char *logDir,
- const char *vmname,
uid_t swtpm_user,
gid_t swtpm_group,
const char *swtpmStateDir,
@@ -306,10 +313,6 @@ qemuTPMEmulatorPrepareHost(virDomainTPMDefPtr tpm,
VIR_DIR_CREATE_ALLOW_EXIST) < 0)
return -1;
- /* create logfile name ... */
- if (!tpm->data.emulator.logfile)
- tpm->data.emulator.logfile = qemuTPMCreateEmulatorLogPath(logDir, vmname);
-
if (!virFileExists(tpm->data.emulator.logfile) &&
virFileTouch(tpm->data.emulator.logfile, 0644) < 0) {
return -1;
@@ -704,7 +707,10 @@ qemuExtTPMInitPaths(virQEMUDriverPtr driver,
switch (def->tpm->type) {
case VIR_DOMAIN_TPM_TYPE_EMULATOR:
- return qemuTPMEmulatorInitPaths(def->tpm, cfg->swtpmStorageDir,
+ return qemuTPMEmulatorInitPaths(def->tpm,
+ cfg->swtpmStorageDir,
+ cfg->swtpmLogDir,
+ def->name,
def->uuid);
case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH:
case VIR_DOMAIN_TPM_TYPE_LAST:
@@ -729,7 +735,7 @@ qemuExtTPMPrepareHost(virQEMUDriverPtr driver,
return -1;
return qemuTPMEmulatorPrepareHost(def->tpm, cfg->swtpmLogDir,
- def->name, cfg->swtpm_user,
+ cfg->swtpm_user,
cfg->swtpm_group,
cfg->swtpmStateDir, cfg->user,
shortName);
--
2.27.0

View File

@ -0,0 +1,57 @@
From bad37cab00ef58f11028246fd2e302f768302dba Mon Sep 17 00:00:00 2001
From: Michal Privoznik <mprivozn@redhat.com>
Date: Thu, 25 Feb 2021 11:41:08 +0100
Subject: [PATCH 4/6] qemu_tpm: Move logfile path generation into a separate
function
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Strictly not needed, but the rest of paths is generated in
separate functions. Helps with code readability.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Signed-off-by: yezengruan <yezengruan@huawei.com>
---
src/qemu/qemu_tpm.c | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_tpm.c b/src/qemu/qemu_tpm.c
index 58dfdf689a..eb155b92b0 100644
--- a/src/qemu/qemu_tpm.c
+++ b/src/qemu/qemu_tpm.c
@@ -82,6 +82,21 @@ qemuTPMCreateEmulatorStoragePath(const char *swtpmStorageDir,
}
+/**
+ * qemuTPMCreateEmulatorLogPath:
+ * @logDir: directory where swtpm writes its logs into
+ * @vmname: name of the VM
+ *
+ * Create the swtpm's log path.
+ */
+static char*
+qemuTPMCreateEmulatorLogPath(const char *logDir,
+ const char *vmname)
+{
+ return g_strdup_printf("%s/%s-swtpm.log", logDir, vmname);
+}
+
+
/*
* qemuTPMEmulatorInitStorage
*
@@ -293,7 +308,7 @@ qemuTPMEmulatorPrepareHost(virDomainTPMDefPtr tpm,
/* create logfile name ... */
if (!tpm->data.emulator.logfile)
- tpm->data.emulator.logfile = g_strdup_printf("%s/%s-swtpm.log", logDir, vmname);
+ tpm->data.emulator.logfile = qemuTPMCreateEmulatorLogPath(logDir, vmname);
if (!virFileExists(tpm->data.emulator.logfile) &&
virFileTouch(tpm->data.emulator.logfile, 0644) < 0) {
--
2.27.0

View File

@ -0,0 +1,181 @@
From 63e167446b11121a0e375ad28375b6f5a44a5d95 Mon Sep 17 00:00:00 2001
From: Peter Krempa <pkrempa@redhat.com>
Date: Fri, 15 May 2020 14:33:10 +0200
Subject: [PATCH 18/18] qemuxml2argvtest: Add QAPI/QMP schema validation for
-blockdev and -netdev
Our hotplug test cases are weak in comparison to the qemuxml2argvtest.
Use all the the input data to also validate the arguments for -netdev
and -blockdev against the appropriate commands of the QMP schema.
Note that currently it's done just for the _CAPS versions of tests but
commenting out a line in the test file allows to validate even cases
which don't use real capabilities.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
tests/Makefile.am | 2 +-
tests/qemuxml2argvtest.c | 76 ++++++++++++++++++++++++++++++++++++++++
tests/testutilsqemu.c | 5 +++
tests/testutilsqemu.h | 1 +
4 files changed, 83 insertions(+), 1 deletion(-)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index ada5b8fc57..e5440906d1 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -569,7 +569,7 @@ qemuxml2argvtest_SOURCES = \
testutils.c testutils.h \
virfilewrapper.c virfilewrapper.h \
$(NULL)
-qemuxml2argvtest_LDADD = libqemutestdriver.la \
+qemuxml2argvtest_LDADD = libqemutestdriver.la libqemumonitortestutils.la \
$(LDADDS) $(LIBXML_LIBS)
libqemuxml2argvmock_la_SOURCES = \
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 2217e2d81e..dc871d5698 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -18,6 +18,7 @@
# include "qemu/qemu_migration.h"
# include "qemu/qemu_process.h"
# include "qemu/qemu_slirp.h"
+# include "qemu/qemu_qapi.h"
# include "datatypes.h"
# include "conf/storage_conf.h"
# include "cpu/cpu_map.h"
@@ -26,6 +27,8 @@
# include "virmock.h"
# include "virfilewrapper.h"
# include "configmake.h"
+# include "testutilsqemuschema.h"
+# include "qemu/qemu_monitor_json.h"
# define LIBVIRT_QEMU_CAPSPRIV_H_ALLOW
# include "qemu/qemu_capspriv.h"
@@ -481,6 +484,76 @@ testCompareXMLToArgvCreateArgs(virQEMUDriverPtr drv,
}
+static int
+testCompareXMLToArgvValidateSchema(virQEMUDriverPtr drv,
+ virDomainObjPtr vm,
+ const char *migrateURI,
+ struct testQemuInfo *info,
+ unsigned int flags)
+{
+ VIR_AUTOSTRINGLIST args = NULL;
+ size_t nargs = 0;
+ size_t i;
+ g_autoptr(virHashTable) schema = NULL;
+ g_autoptr(virCommand) cmd = NULL;
+
+ if (info->schemafile)
+ schema = testQEMUSchemaLoad(info->schemafile);
+
+ /* comment out with line comment to enable schema checking for non _CAPS tests
+ if (!schema)
+ schema = testQEMUSchemaLoadLatest(virArchToString(info->arch));
+ // */
+
+ if (!schema)
+ return 0;
+
+ if (!(cmd = testCompareXMLToArgvCreateArgs(drv, vm, migrateURI, info, flags,
+ true)))
+ return -1;
+
+ if (virCommandGetArgList(cmd, &args, &nargs) < 0)
+ return -1;
+
+ for (i = 0; i < nargs; i++) {
+ g_auto(virBuffer) debug = VIR_BUFFER_INITIALIZER;
+ g_autoptr(virJSONValue) jsonargs = NULL;
+
+ if (STREQ(args[i], "-blockdev")) {
+ if (!(jsonargs = virJSONValueFromString(args[i + 1])))
+ return -1;
+
+ if (testQEMUSchemaValidateCommand("blockdev-add", jsonargs,
+ schema, &debug) < 0) {
+ VIR_TEST_VERBOSE("failed to validate -blockdev '%s' against QAPI schema: %s",
+ args[i + 1], virBufferCurrentContent(&debug));
+ return -1;
+ }
+
+ i++;
+ } else if (STREQ(args[i], "-netdev")) {
+ if (!(jsonargs = virJSONValueFromString(args[i + 1])))
+ return -1;
+
+ /* skip the validation for pre-QAPIfication cases */
+ if (virQEMUQAPISchemaPathExists("netdev_add/arg-type/type/!string", schema))
+ continue;
+
+ if (testQEMUSchemaValidateCommand("netdev_add", jsonargs,
+ schema, &debug) < 0) {
+ VIR_TEST_VERBOSE("failed to validate -netdev '%s' against QAPI schema: %s",
+ args[i + 1], virBufferCurrentContent(&debug));
+ return -1;
+ }
+
+ i++;
+ }
+ }
+
+ return 0;
+}
+
+
static int
testCompareXMLToArgv(const void *data)
{
@@ -582,6 +655,9 @@ testCompareXMLToArgv(const void *data)
goto cleanup;
}
+ if (testCompareXMLToArgvValidateSchema(&driver, vm, migrateURI, info, flags) < 0)
+ goto cleanup;
+
if (!(actualargv = virCommandToString(cmd, false)))
goto cleanup;
diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c
index f3b4e2b3b2..bae1fa828b 100644
--- a/tests/testutilsqemu.c
+++ b/tests/testutilsqemu.c
@@ -767,6 +767,10 @@ testQemuInfoSetArgs(struct testQemuInfo *info,
if (stripmachinealiases)
virQEMUCapsStripMachineAliases(qemuCaps);
info->flags |= FLAG_REAL_CAPS;
+
+ /* provide path to the replies file for schema testing */
+ capsfile[strlen(capsfile) - 3] = '\0';
+ info->schemafile = g_strdup_printf("%sreplies", capsfile);
}
if (!qemuCaps) {
@@ -793,5 +797,6 @@ testQemuInfoClear(struct testQemuInfo *info)
{
VIR_FREE(info->infile);
VIR_FREE(info->outfile);
+ VIR_FREE(info->schemafile);
virObjectUnref(info->qemuCaps);
}
diff --git a/tests/testutilsqemu.h b/tests/testutilsqemu.h
index edee6e450c..e7c5032012 100644
--- a/tests/testutilsqemu.h
+++ b/tests/testutilsqemu.h
@@ -64,6 +64,7 @@ struct testQemuInfo {
unsigned int flags;
unsigned int parseFlags;
virArch arch;
+ char *schemafile;
};
virCapsPtr testQemuCapsInit(void);
--
2.23.0.windows.1

View File

@ -0,0 +1,204 @@
From fb0de8df975557e74af01a0eee0d25c08981c02a Mon Sep 17 00:00:00 2001
From: Peter Krempa <pkrempa@redhat.com>
Date: Fri, 15 May 2020 08:50:31 +0200
Subject: [PATCH 15/18] testCompareXMLToArgv: Split out preparation and command
formatting
There are multiple steps of setting up the domain definition prior to
formatting the command line for the tests. Extract it to a separate
function so that it's self-contained and also will allow re-running the
command line formatting which will be necessary for QMP schema
validation tests.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
tests/qemuxml2argvtest.c | 158 +++++++++++++++++++++------------------
1 file changed, 86 insertions(+), 72 deletions(-)
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 2153e44c5a..762d65f521 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -395,6 +395,90 @@ testCheckExclusiveFlags(int flags)
}
+static virCommandPtr
+testCompareXMLToArgvCreateArgs(virQEMUDriverPtr drv,
+ virDomainObjPtr vm,
+ const char *migrateURI,
+ struct testQemuInfo *info,
+ unsigned int flags)
+{
+ size_t i;
+
+ for (i = 0; i < vm->def->nhostdevs; i++) {
+ virDomainHostdevDefPtr hostdev = vm->def->hostdevs[i];
+
+ if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
+ hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI &&
+ hostdev->source.subsys.u.pci.backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT) {
+ hostdev->source.subsys.u.pci.backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO;
+ }
+ }
+
+ for (i = 0; i < vm->def->nfss; i++) {
+ virDomainFSDefPtr fs = vm->def->fss[i];
+ char *s;
+
+ if (fs->fsdriver != VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS ||
+ QEMU_DOMAIN_FS_PRIVATE(fs)->vhostuser_fs_sock)
+ continue;
+
+ s = g_strdup_printf("/tmp/lib/domain--1-guest/fs%zu.vhost-fs.sock", i);
+ QEMU_DOMAIN_FS_PRIVATE(fs)->vhostuser_fs_sock = s;
+ }
+
+ if (vm->def->vsock) {
+ virDomainVsockDefPtr vsock = vm->def->vsock;
+ qemuDomainVsockPrivatePtr vsockPriv =
+ (qemuDomainVsockPrivatePtr)vsock->privateData;
+
+ if (vsock->auto_cid == VIR_TRISTATE_BOOL_YES)
+ vsock->guest_cid = 42;
+
+ vsockPriv->vhostfd = 6789;
+ }
+
+ if (vm->def->tpm) {
+ switch (vm->def->tpm->type) {
+ case VIR_DOMAIN_TPM_TYPE_EMULATOR:
+ VIR_FREE(vm->def->tpm->data.emulator.source.data.file.path);
+ vm->def->tpm->data.emulator.source.data.file.path = g_strdup("/dev/test");
+ vm->def->tpm->data.emulator.source.type = VIR_DOMAIN_CHR_TYPE_FILE;
+ break;
+ case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH:
+ case VIR_DOMAIN_TPM_TYPE_LAST:
+ break;
+ }
+ }
+
+ for (i = 0; i < vm->def->nvideos; i++) {
+ virDomainVideoDefPtr video = vm->def->videos[i];
+
+ if (video->backend == VIR_DOMAIN_VIDEO_BACKEND_TYPE_VHOSTUSER) {
+ qemuDomainVideoPrivatePtr vpriv = QEMU_DOMAIN_VIDEO_PRIVATE(video);
+
+ vpriv->vhost_user_fd = 1729;
+ }
+ }
+
+ if (flags & FLAG_SLIRP_HELPER) {
+ for (i = 0; i < vm->def->nnets; i++) {
+ virDomainNetDefPtr net = vm->def->nets[i];
+
+ if (net->type == VIR_DOMAIN_NET_TYPE_USER &&
+ virQEMUCapsGet(info->qemuCaps, QEMU_CAPS_DBUS_VMSTATE)) {
+ qemuSlirpPtr slirp = qemuSlirpNew();
+ slirp->fd[0] = 42;
+ QEMU_DOMAIN_NETWORK_PRIVATE(net)->slirp = slirp;
+ }
+ }
+ }
+
+ return qemuProcessCreatePretendCmd(drv, vm, migrateURI,
+ (flags & FLAG_FIPS), false,
+ VIR_QEMU_PROCESS_START_COLD);
+}
+
+
static int
testCompareXMLToArgv(const void *data)
{
@@ -409,7 +493,6 @@ testCompareXMLToArgv(const void *data)
virConnectPtr conn;
char *log = NULL;
virCommandPtr cmd = NULL;
- size_t i;
qemuDomainObjPrivatePtr priv = NULL;
if (info->arch != VIR_ARCH_NONE && info->arch != VIR_ARCH_X86_64)
@@ -486,77 +569,8 @@ testCompareXMLToArgv(const void *data)
VIR_FREE(log);
virResetLastError();
- for (i = 0; i < vm->def->nhostdevs; i++) {
- virDomainHostdevDefPtr hostdev = vm->def->hostdevs[i];
-
- if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
- hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI &&
- hostdev->source.subsys.u.pci.backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT) {
- hostdev->source.subsys.u.pci.backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO;
- }
- }
-
- for (i = 0; i < vm->def->nfss; i++) {
- virDomainFSDefPtr fs = vm->def->fss[i];
- char *s;
-
- if (fs->fsdriver != VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS)
- continue;
-
- s = g_strdup_printf("/tmp/lib/domain--1-guest/fs%zu.vhost-fs.sock", i);
- QEMU_DOMAIN_FS_PRIVATE(fs)->vhostuser_fs_sock = s;
- }
-
- if (vm->def->vsock) {
- virDomainVsockDefPtr vsock = vm->def->vsock;
- qemuDomainVsockPrivatePtr vsockPriv =
- (qemuDomainVsockPrivatePtr)vsock->privateData;
-
- if (vsock->auto_cid == VIR_TRISTATE_BOOL_YES)
- vsock->guest_cid = 42;
-
- vsockPriv->vhostfd = 6789;
- }
-
- if (vm->def->tpm) {
- switch (vm->def->tpm->type) {
- case VIR_DOMAIN_TPM_TYPE_EMULATOR:
- VIR_FREE(vm->def->tpm->data.emulator.source.data.file.path);
- vm->def->tpm->data.emulator.source.data.file.path = g_strdup("/dev/test");
- vm->def->tpm->data.emulator.source.type = VIR_DOMAIN_CHR_TYPE_FILE;
- break;
- case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH:
- case VIR_DOMAIN_TPM_TYPE_LAST:
- break;
- }
- }
-
- for (i = 0; i < vm->def->nvideos; i++) {
- virDomainVideoDefPtr video = vm->def->videos[i];
-
- if (video->backend == VIR_DOMAIN_VIDEO_BACKEND_TYPE_VHOSTUSER) {
- qemuDomainVideoPrivatePtr vpriv = QEMU_DOMAIN_VIDEO_PRIVATE(video);
-
- vpriv->vhost_user_fd = 1729;
- }
- }
-
- if (flags & FLAG_SLIRP_HELPER) {
- for (i = 0; i < vm->def->nnets; i++) {
- virDomainNetDefPtr net = vm->def->nets[i];
-
- if (net->type == VIR_DOMAIN_NET_TYPE_USER &&
- virQEMUCapsGet(info->qemuCaps, QEMU_CAPS_DBUS_VMSTATE)) {
- qemuSlirpPtr slirp = qemuSlirpNew();
- slirp->fd[0] = 42;
- QEMU_DOMAIN_NETWORK_PRIVATE(net)->slirp = slirp;
- }
- }
- }
-
- if (!(cmd = qemuProcessCreatePretendCmd(&driver, vm, migrateURI,
- (flags & FLAG_FIPS), false,
- VIR_QEMU_PROCESS_START_COLD))) {
+ if (!(cmd = testCompareXMLToArgvCreateArgs(&driver, vm, migrateURI, info,
+ flags))) {
if (flags & FLAG_EXPECT_FAILURE)
goto ok;
goto cleanup;
--
2.23.0.windows.1

View File

@ -0,0 +1,81 @@
From 88b38f685d57aac074656104def7111fe854e7c3 Mon Sep 17 00:00:00 2001
From: Luke Yue <lukedyue@gmail.com>
Date: Tue, 18 May 2021 09:19:26 +0800
Subject: [PATCH] tests: Replace deprecated ASN1 code
This fixes compiler warnings when building with libtasn1 4.17.0.
Signed-off-by: Luke Yue <lukedyue@gmail.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
---
tests/pkix_asn1_tab.c | 2 +-
tests/virnettlshelpers.c | 12 ++++++------
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/tests/pkix_asn1_tab.c b/tests/pkix_asn1_tab.c
index 5d5ca3db5d..a28d5f20c3 100644
--- a/tests/pkix_asn1_tab.c
+++ b/tests/pkix_asn1_tab.c
@@ -5,7 +5,7 @@
#include <config.h>
#include <libtasn1.h>
-const ASN1_ARRAY_TYPE pkix_asn1_tab[] = {
+const asn1_static_node pkix_asn1_tab[] = {
{ "PKIX1", 536875024, NULL },
{ NULL, 1073741836, NULL },
{ "id-pkix", 1879048204, NULL },
diff --git a/tests/virnettlshelpers.c b/tests/virnettlshelpers.c
index ce38571b0a..905e633e60 100644
--- a/tests/virnettlshelpers.c
+++ b/tests/virnettlshelpers.c
@@ -37,8 +37,8 @@ VIR_LOG_INIT("tests.nettlshelpers");
* These store some static data that is needed when
* encoding extensions in the x509 certs
*/
-ASN1_TYPE pkix_asn1;
-extern const ASN1_ARRAY_TYPE pkix_asn1_tab[];
+asn1_node pkix_asn1;
+extern const asn1_static_node pkix_asn1_tab[];
/*
* To avoid consuming random entropy to generate keys,
@@ -107,7 +107,7 @@ void testTLSCleanup(const char *keyfile)
/*
* Turns an ASN1 object into a DER encoded byte array
*/
-static void testTLSDerEncode(ASN1_TYPE src,
+static void testTLSDerEncode(asn1_node src,
const char *src_name,
gnutls_datum_t * res)
{
@@ -267,7 +267,7 @@ testTLSGenerateCert(struct testTLSCertReq *req,
* the 'critical' field which we want control over
*/
if (req->basicConstraintsEnable) {
- ASN1_TYPE ext = ASN1_TYPE_EMPTY;
+ asn1_node ext = NULL;
asn1_create_element(pkix_asn1, "PKIX1.BasicConstraints", &ext);
asn1_write_value(ext, "cA", req->basicConstraintsIsCA ? "TRUE" : "FALSE", 1);
@@ -292,7 +292,7 @@ testTLSGenerateCert(struct testTLSCertReq *req,
* to be 'critical'
*/
if (req->keyUsageEnable) {
- ASN1_TYPE ext = ASN1_TYPE_EMPTY;
+ asn1_node ext = NULL;
char str[2];
str[0] = req->keyUsageValue & 0xff;
@@ -321,7 +321,7 @@ testTLSGenerateCert(struct testTLSCertReq *req,
* set this the hard way building up ASN1 data ourselves
*/
if (req->keyPurposeEnable) {
- ASN1_TYPE ext = ASN1_TYPE_EMPTY;
+ asn1_node ext = NULL;
asn1_create_element(pkix_asn1, "PKIX1.ExtKeyUsageSyntax", &ext);
if (req->keyPurposeOID1) {
--
2.27.0

View File

@ -0,0 +1,45 @@
From c4001b2b3f3a078db03ffdc0812e72881972b300 Mon Sep 17 00:00:00 2001
From: imxcc <xingchaochao@huawei.com>
Date: Fri, 14 Jan 2022 11:46:27 +0800
Subject: [PATCH] tests: disabale storage tests
The storagetest in obs cannot be, and related tests are temporarily
disabled
Signed-off-by: imxcc <xingchaochao@huawei.com>
---
tests/Makefile.am | 7 -------
1 file changed, 7 deletions(-)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index ada5b8f..abb261e 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -363,16 +363,10 @@ endif WITH_NWFILTER
if WITH_STORAGE
test_programs += storagevolxml2argvtest
-test_programs += storagepoolxml2argvtest
test_programs += virstorageutiltest
-test_programs += storagepoolxml2xmltest
test_programs += storagepoolcapstest
endif WITH_STORAGE
-if WITH_STORAGE_FS
-test_programs += virstoragetest
-endif WITH_STORAGE_FS
-
if WITH_LINUX
test_programs += virscsitest
endif WITH_LINUX
@@ -430,7 +424,6 @@ test_scripts += $(libvirtd_test_scripts)
test_programs += \
eventtest \
- virdrivermoduletest \
virdriverconnvalidatetest
else ! WITH_LIBVIRTD
EXTRA_DIST += $(libvirtd_test_scripts)
--
2.27.0

View File

@ -0,0 +1,94 @@
From 740581f96fa4007d6549e82131a9ef48a6478149 Mon Sep 17 00:00:00 2001
From: Peter Krempa <pkrempa@redhat.com>
Date: Wed, 4 Mar 2020 10:22:19 +0100
Subject: [PATCH 14/18] testutilsqemuschema: Introduce
testQEMUSchemaValidateCommand
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The new helper splits out all steps necessary to validate a QMP command
against the schema.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
---
tests/testutilsqemuschema.c | 44 +++++++++++++++++++++++++++++++++++++
tests/testutilsqemuschema.h | 6 +++++
2 files changed, 50 insertions(+)
diff --git a/tests/testutilsqemuschema.c b/tests/testutilsqemuschema.c
index 7b82ff27b2..fe8501f3a0 100644
--- a/tests/testutilsqemuschema.c
+++ b/tests/testutilsqemuschema.c
@@ -517,6 +517,50 @@ testQEMUSchemaValidate(virJSONValuePtr obj,
}
+/**
+ * testQEMUSchemaValidateCommand:
+ * @command: command to validate
+ * @arguments: arguments of @command to validate
+ * @schema: hash table containing schema entries
+ * @debug: a virBuffer which will be filled with debug information if provided
+ *
+ * Validates whether @command and its @arguments conform to the QAPI schema
+ * passed in via @schema. Returns 0, if the command and args match @schema,
+ * -1 if it does not and -2 if there is a problem with the schema or with
+ * internals.
+ *
+ * @debug is filled with information regarding the validation process
+ */
+int
+testQEMUSchemaValidateCommand(const char *command,
+ virJSONValuePtr arguments,
+ virHashTablePtr schema,
+ virBufferPtr debug)
+{
+ g_autofree char *schemapatharguments = g_strdup_printf("%s/arg-type", command);
+ g_autoptr(virJSONValue) emptyargs = NULL;
+ virJSONValuePtr schemarootcommand;
+ virJSONValuePtr schemarootarguments;
+
+ if (virQEMUQAPISchemaPathGet(command, schema, &schemarootcommand) < 0 ||
+ !schemarootcommand) {
+ virBufferAsprintf(debug, "ERROR: command '%s' not found in the schema", command);
+ return -1;
+ }
+
+ if (!arguments)
+ arguments = emptyargs = virJSONValueNewObject();
+
+ if (virQEMUQAPISchemaPathGet(schemapatharguments, schema, &schemarootarguments) < 0 ||
+ !schemarootarguments) {
+ virBufferAsprintf(debug, "ERROR: failed to look up 'arg-type' of '%s'", command);
+ return -1;
+ }
+
+ return testQEMUSchemaValidateRecurse(arguments, schemarootarguments, schema, debug);
+}
+
+
/**
* testQEMUSchemaGetLatest:
*
diff --git a/tests/testutilsqemuschema.h b/tests/testutilsqemuschema.h
index 84ee9a9670..e3a375b038 100644
--- a/tests/testutilsqemuschema.h
+++ b/tests/testutilsqemuschema.h
@@ -28,6 +28,12 @@ testQEMUSchemaValidate(virJSONValuePtr obj,
virHashTablePtr schema,
virBufferPtr debug);
+int
+testQEMUSchemaValidateCommand(const char *command,
+ virJSONValuePtr arguments,
+ virHashTablePtr schema,
+ virBufferPtr debug);
+
virJSONValuePtr
testQEMUSchemaGetLatest(const char* arch);
--
2.23.0.windows.1

View File

@ -0,0 +1,73 @@
From 0924902c3814677f9f328f521a95d4a79635d81a Mon Sep 17 00:00:00 2001
From: Peter Krempa <pkrempa@redhat.com>
Date: Thu, 14 May 2020 08:09:56 +0200
Subject: [PATCH 04/18] util: json: Introduce
virJSONValueObjectAppendStringPrintf
Add a variant similar to virJSONValueObjectAppendString which also
formats more complex value strings with printf syntax.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
src/libvirt_private.syms | 1 +
src/util/virjson.c | 17 +++++++++++++++++
src/util/virjson.h | 2 ++
3 files changed, 20 insertions(+)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 84f3bd57ca..726e7a21f9 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2349,6 +2349,7 @@ virJSONValueObjectAppendNumberLong;
virJSONValueObjectAppendNumberUint;
virJSONValueObjectAppendNumberUlong;
virJSONValueObjectAppendString;
+virJSONValueObjectAppendStringPrintf;
virJSONValueObjectCreate;
virJSONValueObjectCreateVArgs;
virJSONValueObjectDeflatten;
diff --git a/src/util/virjson.c b/src/util/virjson.c
index dc662bf8e9..6921eccb60 100644
--- a/src/util/virjson.c
+++ b/src/util/virjson.c
@@ -649,6 +649,23 @@ virJSONValueObjectAppendString(virJSONValuePtr object,
}
+int
+virJSONValueObjectAppendStringPrintf(virJSONValuePtr object,
+ const char *key,
+ const char *fmt,
+ ...)
+{
+ va_list ap;
+ g_autofree char *str = NULL;
+
+ va_start(ap, fmt);
+ str = g_strdup_vprintf(fmt, ap);
+ va_end(ap);
+
+ return virJSONValueObjectInsertString(object, key, str, false);
+}
+
+
int
virJSONValueObjectPrependString(virJSONValuePtr object,
const char *key,
diff --git a/src/util/virjson.h b/src/util/virjson.h
index 0894e91b59..588c977650 100644
--- a/src/util/virjson.h
+++ b/src/util/virjson.h
@@ -127,6 +127,8 @@ int virJSONValueObjectGetBoolean(virJSONValuePtr object, const char *key, bool *
int virJSONValueObjectIsNull(virJSONValuePtr object, const char *key);
int virJSONValueObjectAppendString(virJSONValuePtr object, const char *key, const char *value);
+int virJSONValueObjectAppendStringPrintf(virJSONValuePtr object, const char *key, const char *fmt, ...)
+ G_GNUC_PRINTF(3, 4);
int virJSONValueObjectPrependString(virJSONValuePtr object, const char *key, const char *value);
int virJSONValueObjectAppendNumberInt(virJSONValuePtr object, const char *key, int number);
int virJSONValueObjectAppendNumberUint(virJSONValuePtr object, const char *key, unsigned int number);
--
2.23.0.windows.1

View File

@ -0,0 +1,81 @@
From b9ff1a5a81df23f0a138a7f6d7d3ab0654f669e2 Mon Sep 17 00:00:00 2001
From: Peter Krempa <pkrempa@redhat.com>
Date: Thu, 14 May 2020 10:10:16 +0200
Subject: [PATCH 03/18] util: virqemu: Introduce
virQEMUBuildNetdevCommandlineFromJSON
In preparation for converting the generator of -netdev to generate JSON
which will be used to do the command line rather than the other way
around we need to introduce a convertor which properly configures
virQEMUBuildCommandLineJSON for the quirks of -netdev.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
src/libvirt_private.syms | 1 +
src/util/virqemu.c | 22 ++++++++++++++++++++++
src/util/virqemu.h | 3 +++
3 files changed, 26 insertions(+)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index bac96e140e..84f3bd57ca 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2902,6 +2902,7 @@ virQEMUBuildCommandLineJSON;
virQEMUBuildCommandLineJSONArrayBitmap;
virQEMUBuildCommandLineJSONArrayNumbered;
virQEMUBuildDriveCommandlineFromJSON;
+virQEMUBuildNetdevCommandlineFromJSON;
virQEMUBuildObjectCommandlineFromJSON;
virQEMUBuildQemuImgKeySecretOpts;
diff --git a/src/util/virqemu.c b/src/util/virqemu.c
index 549f88fcd5..0f8cab29df 100644
--- a/src/util/virqemu.c
+++ b/src/util/virqemu.c
@@ -252,6 +252,28 @@ virQEMUBuildCommandLineJSON(virJSONValuePtr value,
}
+/**
+ * virQEMUBuildNetdevCommandlineFromJSON:
+ * @props: JSON properties describing a netdev
+ *
+ * Converts @props into arguments for -netdev including all the quirks and
+ * differences between the monitor and command line syntax.
+ */
+char *
+virQEMUBuildNetdevCommandlineFromJSON(virJSONValuePtr props)
+{
+ const char *type = virJSONValueObjectGetString(props, "type");
+ g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
+
+ virBufferAsprintf(&buf, "%s,", type);
+
+ if (virQEMUBuildCommandLineJSON(props, &buf, "type", true, NULL) < 0)
+ return NULL;
+
+ return virBufferContentAndReset(&buf);
+}
+
+
static int
virQEMUBuildObjectCommandlineFromJSONInternal(virBufferPtr buf,
const char *type,
diff --git a/src/util/virqemu.h b/src/util/virqemu.h
index 67a5711613..22f47851df 100644
--- a/src/util/virqemu.h
+++ b/src/util/virqemu.h
@@ -49,6 +49,9 @@ int virQEMUBuildCommandLineJSON(virJSONValuePtr value,
bool onOff,
virQEMUBuildCommandLineJSONArrayFormatFunc array);
+char *
+virQEMUBuildNetdevCommandlineFromJSON(virJSONValuePtr props);
+
int virQEMUBuildObjectCommandlineFromJSON(virBufferPtr buf,
virJSONValuePtr objprops);
--
2.23.0.windows.1

View File

@ -0,0 +1,77 @@
From 548ea1fcfcfbfc40fab04301e780d28ebe4320a4 Mon Sep 17 00:00:00 2001
From: Peter Krempa <pkrempa@redhat.com>
Date: Wed, 13 May 2020 17:55:21 +0200
Subject: [PATCH 13/18] virCommand: Introduce virCommandGetArgList
The helper returns a list of arguments of a virCommand. This will be
useful in tests where we'll inspect certain already formatted arguments.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
src/libvirt_private.syms | 1 +
src/util/vircommand.c | 23 +++++++++++++++++++++++
src/util/vircommand.h | 1 +
3 files changed, 25 insertions(+)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 726e7a21f9..861a4892be 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1829,6 +1829,7 @@ virCommandDaemonize;
virCommandDoAsyncIO;
virCommandExec;
virCommandFree;
+virCommandGetArgList;
virCommandGetGID;
virCommandGetUID;
virCommandHandshakeNotify;
diff --git a/src/util/vircommand.c b/src/util/vircommand.c
index b84fb40948..86e4c5cd39 100644
--- a/src/util/vircommand.c
+++ b/src/util/vircommand.c
@@ -2167,6 +2167,29 @@ virCommandToString(virCommandPtr cmd, bool linebreaks)
}
+int
+virCommandGetArgList(virCommandPtr cmd,
+ char ***args,
+ size_t *nargs)
+{
+ size_t i;
+
+ if (cmd->has_error) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("invalid use of command API"));
+ return -1;
+ }
+
+ *args = g_new0(char *, cmd->nargs);
+ *nargs = cmd->nargs - 1;
+
+ for (i = 1; i < cmd->nargs; i++)
+ (*args)[i - 1] = g_strdup(cmd->args[i]);
+
+ return 0;
+}
+
+
#ifndef WIN32
/*
* Manage input and output to the child process.
diff --git a/src/util/vircommand.h b/src/util/vircommand.h
index 4e6cb0ac0d..854bfe6576 100644
--- a/src/util/vircommand.h
+++ b/src/util/vircommand.h
@@ -171,6 +171,7 @@ void virCommandWriteArgLog(virCommandPtr cmd,
int logfd);
char *virCommandToString(virCommandPtr cmd, bool linebreaks) G_GNUC_WARN_UNUSED_RESULT;
+int virCommandGetArgList(virCommandPtr cmd, char ***args, size_t *nargs);
int virCommandExec(virCommandPtr cmd, gid_t *groups, int ngroups) G_GNUC_WARN_UNUSED_RESULT;
--
2.23.0.windows.1

View File

@ -0,0 +1,218 @@
From b80d9efd8af5de335e3c1de24b74d2e647832458 Mon Sep 17 00:00:00 2001
From: Peter Krempa <pkrempa@redhat.com>
Date: Thu, 14 May 2020 22:45:24 +0200
Subject: [PATCH 02/18] virQEMUBuildCommandLineJSON: Add possibility for using
'on/off' instead of 'yes/no'
In some cases we use 'on/off' for command line arguments. Add a switch
which will select the preferred spelling for a specific usage.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
src/util/virqemu.c | 44 ++++++++++++++++++++++++-------------
src/util/virqemu.h | 10 ++++++---
tests/qemucommandutiltest.c | 2 +-
3 files changed, 37 insertions(+), 19 deletions(-)
diff --git a/src/util/virqemu.c b/src/util/virqemu.c
index 0e6fa412bc..549f88fcd5 100644
--- a/src/util/virqemu.c
+++ b/src/util/virqemu.c
@@ -37,6 +37,7 @@ struct virQEMUCommandLineJSONIteratorData {
const char *prefix;
virBufferPtr buf;
const char *skipKey;
+ bool onOff;
virQEMUBuildCommandLineJSONArrayFormatFunc arrayFunc;
};
@@ -46,6 +47,7 @@ virQEMUBuildCommandLineJSONRecurse(const char *key,
virJSONValuePtr value,
virBufferPtr buf,
const char *skipKey,
+ bool onOff,
virQEMUBuildCommandLineJSONArrayFormatFunc arrayFunc,
bool nested);
@@ -55,7 +57,8 @@ int
virQEMUBuildCommandLineJSONArrayBitmap(const char *key,
virJSONValuePtr array,
virBufferPtr buf,
- const char *skipKey G_GNUC_UNUSED)
+ const char *skipKey G_GNUC_UNUSED,
+ bool onOff G_GNUC_UNUSED)
{
ssize_t pos = -1;
ssize_t end;
@@ -84,7 +87,8 @@ int
virQEMUBuildCommandLineJSONArrayNumbered(const char *key,
virJSONValuePtr array,
virBufferPtr buf,
- const char *skipKey)
+ const char *skipKey,
+ bool onOff)
{
virJSONValuePtr member;
size_t i;
@@ -95,7 +99,7 @@ virQEMUBuildCommandLineJSONArrayNumbered(const char *key,
prefix = g_strdup_printf("%s.%zu", key, i);
- if (virQEMUBuildCommandLineJSONRecurse(prefix, member, buf, skipKey,
+ if (virQEMUBuildCommandLineJSONRecurse(prefix, member, buf, skipKey, onOff,
virQEMUBuildCommandLineJSONArrayNumbered,
true) < 0)
return 0;
@@ -122,11 +126,11 @@ virQEMUBuildCommandLineJSONIterate(const char *key,
tmpkey = g_strdup_printf("%s.%s", data->prefix, key);
return virQEMUBuildCommandLineJSONRecurse(tmpkey, value, data->buf,
- data->skipKey,
+ data->skipKey, data->onOff,
data->arrayFunc, false);
} else {
return virQEMUBuildCommandLineJSONRecurse(key, value, data->buf,
- data->skipKey,
+ data->skipKey, data->onOff,
data->arrayFunc, false);
}
}
@@ -137,10 +141,11 @@ virQEMUBuildCommandLineJSONRecurse(const char *key,
virJSONValuePtr value,
virBufferPtr buf,
const char *skipKey,
+ bool onOff,
virQEMUBuildCommandLineJSONArrayFormatFunc arrayFunc,
bool nested)
{
- struct virQEMUCommandLineJSONIteratorData data = { key, buf, skipKey, arrayFunc };
+ struct virQEMUCommandLineJSONIteratorData data = { key, buf, skipKey, onOff, arrayFunc };
virJSONType type = virJSONValueGetType(value);
virJSONValuePtr elem;
bool tmp;
@@ -165,10 +170,17 @@ virQEMUBuildCommandLineJSONRecurse(const char *key,
case VIR_JSON_TYPE_BOOLEAN:
virJSONValueGetBoolean(value, &tmp);
- if (tmp)
- virBufferAsprintf(buf, "%s=yes,", key);
- else
- virBufferAsprintf(buf, "%s=no,", key);
+ if (onOff) {
+ if (tmp)
+ virBufferAsprintf(buf, "%s=on,", key);
+ else
+ virBufferAsprintf(buf, "%s=off,", key);
+ } else {
+ if (tmp)
+ virBufferAsprintf(buf, "%s=yes,", key);
+ else
+ virBufferAsprintf(buf, "%s=no,", key);
+ }
break;
@@ -180,7 +192,7 @@ virQEMUBuildCommandLineJSONRecurse(const char *key,
return -1;
}
- if (!arrayFunc || arrayFunc(key, value, buf, skipKey) < 0) {
+ if (!arrayFunc || arrayFunc(key, value, buf, skipKey, onOff) < 0) {
/* fallback, treat the array as a non-bitmap, adding the key
* for each member */
for (i = 0; i < virJSONValueArraySize(value); i++) {
@@ -188,7 +200,7 @@ virQEMUBuildCommandLineJSONRecurse(const char *key,
/* recurse to avoid duplicating code */
if (virQEMUBuildCommandLineJSONRecurse(key, elem, buf, skipKey,
- arrayFunc, true) < 0)
+ onOff, arrayFunc, true) < 0)
return -1;
}
}
@@ -216,6 +228,7 @@ virQEMUBuildCommandLineJSONRecurse(const char *key,
* @value: json object containing the value
* @buf: otuput buffer
* @skipKey: name of key that will be handled separately by caller
+ * @onOff: Use 'on' and 'off' for boolean values rather than 'yes' and 'no'
* @arrayFunc: array formatter function to allow for different syntax
*
* Formats JSON value object into command line parameters suitable for use with
@@ -227,9 +240,10 @@ int
virQEMUBuildCommandLineJSON(virJSONValuePtr value,
virBufferPtr buf,
const char *skipKey,
+ bool onOff,
virQEMUBuildCommandLineJSONArrayFormatFunc array)
{
- if (virQEMUBuildCommandLineJSONRecurse(NULL, value, buf, skipKey, array, false) < 0)
+ if (virQEMUBuildCommandLineJSONRecurse(NULL, value, buf, skipKey, onOff, array, false) < 0)
return -1;
virBufferTrim(buf, ",");
@@ -255,7 +269,7 @@ virQEMUBuildObjectCommandlineFromJSONInternal(virBufferPtr buf,
if (props) {
virBufferAddLit(buf, ",");
- if (virQEMUBuildCommandLineJSON(props, buf, NULL,
+ if (virQEMUBuildCommandLineJSON(props, buf, NULL, false,
virQEMUBuildCommandLineJSONArrayBitmap) < 0)
return -1;
}
@@ -282,7 +296,7 @@ virQEMUBuildDriveCommandlineFromJSON(virJSONValuePtr srcdef)
virBuffer buf = VIR_BUFFER_INITIALIZER;
char *ret = NULL;
- if (virQEMUBuildCommandLineJSON(srcdef, &buf, NULL,
+ if (virQEMUBuildCommandLineJSON(srcdef, &buf, NULL, false,
virQEMUBuildCommandLineJSONArrayNumbered) < 0)
goto cleanup;
diff --git a/src/util/virqemu.h b/src/util/virqemu.h
index 9d3db7c2a2..67a5711613 100644
--- a/src/util/virqemu.h
+++ b/src/util/virqemu.h
@@ -30,19 +30,23 @@
typedef int (*virQEMUBuildCommandLineJSONArrayFormatFunc)(const char *key,
virJSONValuePtr array,
virBufferPtr buf,
- const char *skipKey);
+ const char *skipKey,
+ bool onOff);
int virQEMUBuildCommandLineJSONArrayBitmap(const char *key,
virJSONValuePtr array,
virBufferPtr buf,
- const char *skipKey);
+ const char *skipKey,
+ bool onOff);
int virQEMUBuildCommandLineJSONArrayNumbered(const char *key,
virJSONValuePtr array,
virBufferPtr buf,
- const char *skipKey);
+ const char *skipKey,
+ bool onOff);
int virQEMUBuildCommandLineJSON(virJSONValuePtr value,
virBufferPtr buf,
const char *skipKey,
+ bool onOff,
virQEMUBuildCommandLineJSONArrayFormatFunc array);
int virQEMUBuildObjectCommandlineFromJSON(virBufferPtr buf,
diff --git a/tests/qemucommandutiltest.c b/tests/qemucommandutiltest.c
index 923776e642..049fd2f0b0 100644
--- a/tests/qemucommandutiltest.c
+++ b/tests/qemucommandutiltest.c
@@ -47,7 +47,7 @@ testQemuCommandBuildFromJSON(const void *opaque)
return -1;
}
- if (virQEMUBuildCommandLineJSON(val, &buf, NULL, data->arrayfunc) < 0) {
+ if (virQEMUBuildCommandLineJSON(val, &buf, NULL, false, data->arrayfunc) < 0) {
fprintf(stderr,
"\nvirQEMUBuildCommandlineJSON failed process JSON:\n%s\n",
data->props);
--
2.23.0.windows.1

View File

@ -0,0 +1,202 @@
From b1e8b606813b1097cdb3a0d9e9f04c629d7bcf29 Mon Sep 17 00:00:00 2001
From: Peter Krempa <pkrempa@redhat.com>
Date: Thu, 14 May 2020 09:41:48 +0200
Subject: [PATCH 01/18] virQEMUBuildCommandLineJSON: Allow skipping certain
keys
Allow reusing this for formatting of netdev_add arguments into -netdev.
We need to be able to skip the 'type' property as it's used without the
prefix by our generator.
Add infrastructure which allows skipping property with a specific name.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
src/util/virqemu.c | 30 +++++++++++++++++++++---------
src/util/virqemu.h | 10 +++++++---
tests/qemucommandutiltest.c | 2 +-
3 files changed, 29 insertions(+), 13 deletions(-)
diff --git a/src/util/virqemu.c b/src/util/virqemu.c
index 78a9e0480b..0e6fa412bc 100644
--- a/src/util/virqemu.c
+++ b/src/util/virqemu.c
@@ -36,6 +36,7 @@ VIR_LOG_INIT("util.qemu");
struct virQEMUCommandLineJSONIteratorData {
const char *prefix;
virBufferPtr buf;
+ const char *skipKey;
virQEMUBuildCommandLineJSONArrayFormatFunc arrayFunc;
};
@@ -44,6 +45,7 @@ static int
virQEMUBuildCommandLineJSONRecurse(const char *key,
virJSONValuePtr value,
virBufferPtr buf,
+ const char *skipKey,
virQEMUBuildCommandLineJSONArrayFormatFunc arrayFunc,
bool nested);
@@ -52,7 +54,8 @@ virQEMUBuildCommandLineJSONRecurse(const char *key,
int
virQEMUBuildCommandLineJSONArrayBitmap(const char *key,
virJSONValuePtr array,
- virBufferPtr buf)
+ virBufferPtr buf,
+ const char *skipKey G_GNUC_UNUSED)
{
ssize_t pos = -1;
ssize_t end;
@@ -80,7 +83,8 @@ virQEMUBuildCommandLineJSONArrayBitmap(const char *key,
int
virQEMUBuildCommandLineJSONArrayNumbered(const char *key,
virJSONValuePtr array,
- virBufferPtr buf)
+ virBufferPtr buf,
+ const char *skipKey)
{
virJSONValuePtr member;
size_t i;
@@ -91,7 +95,7 @@ virQEMUBuildCommandLineJSONArrayNumbered(const char *key,
prefix = g_strdup_printf("%s.%zu", key, i);
- if (virQEMUBuildCommandLineJSONRecurse(prefix, member, buf,
+ if (virQEMUBuildCommandLineJSONRecurse(prefix, member, buf, skipKey,
virQEMUBuildCommandLineJSONArrayNumbered,
true) < 0)
return 0;
@@ -109,15 +113,20 @@ virQEMUBuildCommandLineJSONIterate(const char *key,
{
struct virQEMUCommandLineJSONIteratorData *data = opaque;
+ if (STREQ_NULLABLE(key, data->skipKey))
+ return 0;
+
if (data->prefix) {
g_autofree char *tmpkey = NULL;
tmpkey = g_strdup_printf("%s.%s", data->prefix, key);
return virQEMUBuildCommandLineJSONRecurse(tmpkey, value, data->buf,
+ data->skipKey,
data->arrayFunc, false);
} else {
return virQEMUBuildCommandLineJSONRecurse(key, value, data->buf,
+ data->skipKey,
data->arrayFunc, false);
}
}
@@ -127,10 +136,11 @@ static int
virQEMUBuildCommandLineJSONRecurse(const char *key,
virJSONValuePtr value,
virBufferPtr buf,
+ const char *skipKey,
virQEMUBuildCommandLineJSONArrayFormatFunc arrayFunc,
bool nested)
{
- struct virQEMUCommandLineJSONIteratorData data = { key, buf, arrayFunc };
+ struct virQEMUCommandLineJSONIteratorData data = { key, buf, skipKey, arrayFunc };
virJSONType type = virJSONValueGetType(value);
virJSONValuePtr elem;
bool tmp;
@@ -170,14 +180,14 @@ virQEMUBuildCommandLineJSONRecurse(const char *key,
return -1;
}
- if (!arrayFunc || arrayFunc(key, value, buf) < 0) {
+ if (!arrayFunc || arrayFunc(key, value, buf, skipKey) < 0) {
/* fallback, treat the array as a non-bitmap, adding the key
* for each member */
for (i = 0; i < virJSONValueArraySize(value); i++) {
elem = virJSONValueArrayGet((virJSONValuePtr)value, i);
/* recurse to avoid duplicating code */
- if (virQEMUBuildCommandLineJSONRecurse(key, elem, buf,
+ if (virQEMUBuildCommandLineJSONRecurse(key, elem, buf, skipKey,
arrayFunc, true) < 0)
return -1;
}
@@ -205,6 +215,7 @@ virQEMUBuildCommandLineJSONRecurse(const char *key,
* virQEMUBuildCommandLineJSON:
* @value: json object containing the value
* @buf: otuput buffer
+ * @skipKey: name of key that will be handled separately by caller
* @arrayFunc: array formatter function to allow for different syntax
*
* Formats JSON value object into command line parameters suitable for use with
@@ -215,9 +226,10 @@ virQEMUBuildCommandLineJSONRecurse(const char *key,
int
virQEMUBuildCommandLineJSON(virJSONValuePtr value,
virBufferPtr buf,
+ const char *skipKey,
virQEMUBuildCommandLineJSONArrayFormatFunc array)
{
- if (virQEMUBuildCommandLineJSONRecurse(NULL, value, buf, array, false) < 0)
+ if (virQEMUBuildCommandLineJSONRecurse(NULL, value, buf, skipKey, array, false) < 0)
return -1;
virBufferTrim(buf, ",");
@@ -243,7 +255,7 @@ virQEMUBuildObjectCommandlineFromJSONInternal(virBufferPtr buf,
if (props) {
virBufferAddLit(buf, ",");
- if (virQEMUBuildCommandLineJSON(props, buf,
+ if (virQEMUBuildCommandLineJSON(props, buf, NULL,
virQEMUBuildCommandLineJSONArrayBitmap) < 0)
return -1;
}
@@ -270,7 +282,7 @@ virQEMUBuildDriveCommandlineFromJSON(virJSONValuePtr srcdef)
virBuffer buf = VIR_BUFFER_INITIALIZER;
char *ret = NULL;
- if (virQEMUBuildCommandLineJSON(srcdef, &buf,
+ if (virQEMUBuildCommandLineJSON(srcdef, &buf, NULL,
virQEMUBuildCommandLineJSONArrayNumbered) < 0)
goto cleanup;
diff --git a/src/util/virqemu.h b/src/util/virqemu.h
index 227325e80e..9d3db7c2a2 100644
--- a/src/util/virqemu.h
+++ b/src/util/virqemu.h
@@ -29,16 +29,20 @@
typedef int (*virQEMUBuildCommandLineJSONArrayFormatFunc)(const char *key,
virJSONValuePtr array,
- virBufferPtr buf);
+ virBufferPtr buf,
+ const char *skipKey);
int virQEMUBuildCommandLineJSONArrayBitmap(const char *key,
virJSONValuePtr array,
- virBufferPtr buf);
+ virBufferPtr buf,
+ const char *skipKey);
int virQEMUBuildCommandLineJSONArrayNumbered(const char *key,
virJSONValuePtr array,
- virBufferPtr buf);
+ virBufferPtr buf,
+ const char *skipKey);
int virQEMUBuildCommandLineJSON(virJSONValuePtr value,
virBufferPtr buf,
+ const char *skipKey,
virQEMUBuildCommandLineJSONArrayFormatFunc array);
int virQEMUBuildObjectCommandlineFromJSON(virBufferPtr buf,
diff --git a/tests/qemucommandutiltest.c b/tests/qemucommandutiltest.c
index c5b3e7b735..923776e642 100644
--- a/tests/qemucommandutiltest.c
+++ b/tests/qemucommandutiltest.c
@@ -47,7 +47,7 @@ testQemuCommandBuildFromJSON(const void *opaque)
return -1;
}
- if (virQEMUBuildCommandLineJSON(val, &buf, data->arrayfunc) < 0) {
+ if (virQEMUBuildCommandLineJSON(val, &buf, NULL, data->arrayfunc) < 0) {
fprintf(stderr,
"\nvirQEMUBuildCommandlineJSON failed process JSON:\n%s\n",
data->props);
--
2.23.0.windows.1

View File

@ -0,0 +1,88 @@
From 9df86be1d8d974dc6bcf174c63814cd4492ddd5e Mon Sep 17 00:00:00 2001
From: Peter Krempa <pkrempa@redhat.com>
Date: Fri, 15 May 2020 10:59:40 +0200
Subject: [PATCH 16/18] virQEMUBuildNetdevCommandlineFromJSON: Prepare for
quirky 'guestfwd'
QEMU models guestfwd as:
'guestfwd': [
{ "str": "tcp:10.0.2.1:4600-chardev:charchannel0" },
{ "str": "...."},
]
but the command line as:
guestfwd=tcp:10.0.2.1:4600-chardev:charchannel0,guestfwd=...
I guess the original idea was to make it extensible while not worrying
about adding another object for it. Either way it requires us to add yet
another JSON->cmdline convertor for arrays.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
src/util/virqemu.c | 40 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 39 insertions(+), 1 deletion(-)
diff --git a/src/util/virqemu.c b/src/util/virqemu.c
index 0f8cab29df..9823ebc14d 100644
--- a/src/util/virqemu.c
+++ b/src/util/virqemu.c
@@ -109,6 +109,43 @@ virQEMUBuildCommandLineJSONArrayNumbered(const char *key,
}
+/**
+ * This array convertor is for quirky cases where the QMP schema mandates an
+ * array of objects with only one attribute 'str' which needs to be formatted as
+ * repeated key-value pairs without the 'str' being printed:
+ *
+ * 'guestfwd': [
+ * { "str": "tcp:10.0.2.1:4600-chardev:charchannel0" },
+ * { "str": "...."},
+ * ]
+ *
+ * guestfwd=tcp:10.0.2.1:4600-chardev:charchannel0,guestfwd=...
+ */
+static int
+virQEMUBuildCommandLineJSONArrayObjectsStr(const char *key,
+ virJSONValuePtr array,
+ virBufferPtr buf,
+ const char *skipKey G_GNUC_UNUSED,
+ bool onOff G_GNUC_UNUSED)
+{
+ g_auto(virBuffer) tmp = VIR_BUFFER_INITIALIZER;
+ size_t i;
+
+ for (i = 0; i < virJSONValueArraySize(array); i++) {
+ virJSONValuePtr member = virJSONValueArrayGet(array, i);
+ const char *str = virJSONValueObjectGetString(member, "str");
+
+ if (!str)
+ return -1;
+
+ virBufferAsprintf(&tmp, "%s=%s,", key, str);
+ }
+
+ virBufferAddBuffer(buf, &tmp);
+ return 0;
+}
+
+
/* internal iterator to handle nested object formatting */
static int
virQEMUBuildCommandLineJSONIterate(const char *key,
@@ -267,7 +304,8 @@ virQEMUBuildNetdevCommandlineFromJSON(virJSONValuePtr props)
virBufferAsprintf(&buf, "%s,", type);
- if (virQEMUBuildCommandLineJSON(props, &buf, "type", true, NULL) < 0)
+ if (virQEMUBuildCommandLineJSON(props, &buf, "type", true,
+ virQEMUBuildCommandLineJSONArrayObjectsStr) < 0)
return NULL;
return virBufferContentAndReset(&buf);
--
2.23.0.windows.1

View File

@ -0,0 +1,48 @@
From 4fe54e0e98050bf4529d67a266b6b10286312eaa Mon Sep 17 00:00:00 2001
From: Michal Privoznik <mprivozn@redhat.com>
Date: Thu, 25 Feb 2021 11:58:38 +0100
Subject: [PATCH 6/6] virtpm: Fix @path handling in virTPMEmulatorInit()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This function finds "swtmp", "swtpm_setup" and "swtpm_ioctl"
binaries in $PATH and stores resolved paths in global variables
so that they can be obtainer later. Anyway, the resolved path is
marked as g_autofree and to avoid its freeing later on in the
function the variable is set to NULL manually. Well, we have
g_steal_pointer() for that.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Signed-off-by: yezengruan <yezengruan@huawei.com>
---
src/util/virtpm.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/src/util/virtpm.c b/src/util/virtpm.c
index c734bf941a..1a61a92f69 100644
--- a/src/util/virtpm.c
+++ b/src/util/virtpm.c
@@ -325,16 +325,14 @@ virTPMEmulatorInit(void)
_("Could not stat %s"), path);
goto cleanup;
}
- *prgs[i].path = path;
+ *prgs[i].path = g_steal_pointer(&path);
if (prgs[i].caps) {
*prgs[i].caps = virTPMGetCaps(prgs[i].typeFromStringFn,
- path, prgs[i].parm);
- path = NULL;
+ *prgs[i].path, prgs[i].parm);
if (!*prgs[i].caps)
goto cleanup;
}
- path = NULL;
}
}
--
2.27.0