diff --git a/Hotpatch-introduce-DomainHotpatchManage-API.patch b/Hotpatch-introduce-DomainHotpatchManage-API.patch new file mode 100644 index 0000000000000000000000000000000000000000..26b643df70cca5662374893a66f4fc9de10350d0 --- /dev/null +++ b/Hotpatch-introduce-DomainHotpatchManage-API.patch @@ -0,0 +1,211 @@ +From 9a12606bb5caf3e213ce1564445d88325592e642 Mon Sep 17 00:00:00 2001 +From: AlexChen +Date: Tue, 19 Oct 2021 14:50:32 +0800 +Subject: [PATCH] Hotpatch: introduce DomainHotpatchManage API + +Signed-off-by: Hao Wang +Signed-off-by: Bihong Yu +Signed-off-by: AlexChen +--- + 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 + diff --git a/Revert-libvirt-support-aarch64-vtpm-with-parameter-t.patch b/Revert-libvirt-support-aarch64-vtpm-with-parameter-t.patch new file mode 100644 index 0000000000000000000000000000000000000000..a26b4ce3c8380774b7e25e2cbac11fd95046097a --- /dev/null +++ b/Revert-libvirt-support-aarch64-vtpm-with-parameter-t.patch @@ -0,0 +1,108 @@ +From 78c25600daf2a2822e7ecec2af9e7458b9f44eff Mon Sep 17 00:00:00 2001 +From: yezengruan +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 +--- + 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 + diff --git a/Revert-tests-disabale-storage-tests.patch b/Revert-tests-disabale-storage-tests.patch new file mode 100644 index 0000000000000000000000000000000000000000..78cab82e0161e24adad840d3ec43207ca73ed793 --- /dev/null +++ b/Revert-tests-disabale-storage-tests.patch @@ -0,0 +1,42 @@ +From 8629a253113a019215b38f7206db03892157a370 Mon Sep 17 00:00:00 2001 +From: imxcc +Date: Sat, 29 Jan 2022 17:14:59 +0800 +Subject: [PATCH] Revert tests: disabale storage tests + +Signed-off-by: imxcc +--- + 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 + diff --git a/docs-build-Don-t-include-stylesheet-in-intermediate-.patch b/docs-build-Don-t-include-stylesheet-in-intermediate-.patch new file mode 100644 index 0000000000000000000000000000000000000000..b13d5e0987f025a28ecc6b4060a979496e7a688d --- /dev/null +++ b/docs-build-Don-t-include-stylesheet-in-intermediate-.patch @@ -0,0 +1,62 @@ +From c99e7e8abe1e22f504173a976a82e1a72551bdc1 Mon Sep 17 00:00:00 2001 +From: Peter Krempa +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 +Reviewed-by: Ján Tomko +Signed-off-by: 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 + diff --git a/domain-add-logs-for-virDomainHotpatchManage.patch b/domain-add-logs-for-virDomainHotpatchManage.patch new file mode 100644 index 0000000000000000000000000000000000000000..ef63bf495abf03a2d6f94e65d3489eb050205505 --- /dev/null +++ b/domain-add-logs-for-virDomainHotpatchManage.patch @@ -0,0 +1,45 @@ +From e59b2064ffefbc94c729d38ec0180197e2b1f8ed Mon Sep 17 00:00:00 2001 +From: AlexChen +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 +Signed-off-by: AlexChen +--- + 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 + diff --git a/hotpatch-Implement-qemuDomainHotpatchManage.patch b/hotpatch-Implement-qemuDomainHotpatchManage.patch new file mode 100644 index 0000000000000000000000000000000000000000..79bcd38a37d2ee86a6278a2bd08d8df245736644 --- /dev/null +++ b/hotpatch-Implement-qemuDomainHotpatchManage.patch @@ -0,0 +1,336 @@ +From b255a024007eb236745b703586a2fed8bdedae6c Mon Sep 17 00:00:00 2001 +From: AlexChen +Date: Tue, 19 Oct 2021 22:11:45 +0800 +Subject: [PATCH] hotpatch: Implement qemuDomainHotpatchManage + +Signed-off-by: Hao Wang +Signed-off-by: Bihong Yu +Signed-off-by: AlexChen +--- + 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 ++ * . ++ * ++ */ ++ ++ ++#include ++#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 ++ * . ++ * ++ */ ++ ++#pragma once ++ ++#include ++#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 + diff --git a/hotpatch-check-vm-id-and-pid-before-using-hotpatch-a.patch b/hotpatch-check-vm-id-and-pid-before-using-hotpatch-a.patch new file mode 100644 index 0000000000000000000000000000000000000000..13d997c3364985fffd88de1446d769b24badaf8b --- /dev/null +++ b/hotpatch-check-vm-id-and-pid-before-using-hotpatch-a.patch @@ -0,0 +1,135 @@ +From 58121fbc3085296364e6b90bc16cb56eeaf36f77 Mon Sep 17 00:00:00 2001 +From: AlexChen +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 +Signed-off-by: AlexChen +--- + 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 + diff --git a/hotpatch-implement-hotpatch-virsh-api.patch b/hotpatch-implement-hotpatch-virsh-api.patch new file mode 100644 index 0000000000000000000000000000000000000000..552ae2dda8d20bb8266739d61eda1bca9fbb6bac --- /dev/null +++ b/hotpatch-implement-hotpatch-virsh-api.patch @@ -0,0 +1,110 @@ +From cf380e22898f70f5782bcea8b0d22027ff7d86af Mon Sep 17 00:00:00 2001 +From: AlexChen +Date: Wed, 20 Oct 2021 11:07:34 +0800 +Subject: [PATCH] hotpatch: implement hotpatch virsh api + +Signed-off-by: Hao Wang +Signed-off-by: Bihong Yu +Signed-off-by: AlexChen +--- + 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 , and ") ++ }, ++ {.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 + diff --git a/hotpatch-introduce-hotpatch-async-job-flag.patch b/hotpatch-introduce-hotpatch-async-job-flag.patch new file mode 100644 index 0000000000000000000000000000000000000000..24f1611410ace86ce95e81c3629b6bc9ec3d4f05 --- /dev/null +++ b/hotpatch-introduce-hotpatch-async-job-flag.patch @@ -0,0 +1,155 @@ +From a83bb0dc19d7c92c200b9a234e120d16878eac19 Mon Sep 17 00:00:00 2001 +From: AlexChen +Date: Tue, 19 Oct 2021 22:41:24 +0800 +Subject: [PATCH] hotpatch: introduce hotpatch async job flag + +Signed-off-by: Hao Wang +Signed-off-by: Bihong Yu +Signed-off-by: AlexChen +--- + 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 + diff --git a/hotpatch-virsh-support-autoload-mode.patch b/hotpatch-virsh-support-autoload-mode.patch new file mode 100644 index 0000000000000000000000000000000000000000..2c95db6e60c039fc6e7911f39ff0e4484d8ab696 --- /dev/null +++ b/hotpatch-virsh-support-autoload-mode.patch @@ -0,0 +1,302 @@ +From 3be8bb571d13795c2824dd6d2089035a1be6cf57 Mon Sep 17 00:00:00 2001 +From: jiang-dawei15 +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 , and ") ++ .help = N_("hotpatch action, choose from , , and ") + }, + {.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 + diff --git a/libvirt.spec b/libvirt.spec index 72b971ce8f114c4ff7b06ab7d7ab890af8778b18..44dfe1b0e18f0ee85cfaa174d4bedea1cc31f543 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -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 +- 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 +- 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 +- 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 +- hotpatch: virsh support autoload mode + +* Fri Jan 29 2022 imxcc +- Revert "tests: disabale storage tests" + +* Fri Jan 14 2022 imxcc +- tests: disabale storage tests + +* Tue Jan 11 2022 imxcc +- docs: build: Don't include stylesheet in intermediate html +- tests: Replace deprecated ASN1 code + +* Mon Dec 06 2021 Euler Robot +- 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 +- Hotpatch: introduce DomainHotpatchManage API +- hotpatch: Implement qemuDomainHotpatchManage +- hotpatch: introduce hotpatch async job flag + * Sun Sep 26 2021 imxcc - fix cve-2021-3667 cve-2021-3631 diff --git a/qemu-Avoid-deprecated-migrate-set-cache-size-QMP-com.patch b/qemu-Avoid-deprecated-migrate-set-cache-size-QMP-com.patch new file mode 100644 index 0000000000000000000000000000000000000000..84b84143837bd384af6fe63a1e43135f7ae528f5 --- /dev/null +++ b/qemu-Avoid-deprecated-migrate-set-cache-size-QMP-com.patch @@ -0,0 +1,81 @@ +From 4fe1ead5da84610bba30cae9315ff38de765711f Mon Sep 17 00:00:00 2001 +From: Jiri Denemark +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 +Reviewed-by: Peter Krempa +--- + 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 + diff --git a/qemu-Avoid-deprecated-migrate_set_downtime-QMP-comma.patch b/qemu-Avoid-deprecated-migrate_set_downtime-QMP-comma.patch new file mode 100644 index 0000000000000000000000000000000000000000..6bab2e21817175dc4165d271f46c0cc7b30bcc19 --- /dev/null +++ b/qemu-Avoid-deprecated-migrate_set_downtime-QMP-comma.patch @@ -0,0 +1,65 @@ +From df9385f88c666783c7ac53800f00e359a4177145 Mon Sep 17 00:00:00 2001 +From: Jiri Denemark +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 +Reviewed-by: Peter Krempa +--- + 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 + diff --git a/qemu-Avoid-deprecated-migrate_set_speed-QMP-command.patch b/qemu-Avoid-deprecated-migrate_set_speed-QMP-command.patch new file mode 100644 index 0000000000000000000000000000000000000000..814f5086ab252159cef07de13355d5c73d5ca745 --- /dev/null +++ b/qemu-Avoid-deprecated-migrate_set_speed-QMP-command.patch @@ -0,0 +1,174 @@ +From d72c84f9369152d0ca69fb201d4ae41ee559a94b Mon Sep 17 00:00:00 2001 +From: Jiri Denemark +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 +Reviewed-by: Peter Krempa +--- + 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 + diff --git a/qemu-Avoid-deprecated-query-migrate-cache-size-QMP-c.patch b/qemu-Avoid-deprecated-query-migrate-cache-size-QMP-c.patch new file mode 100644 index 0000000000000000000000000000000000000000..3fe24e4ea9acb64aac584369bd34fcc98403b013 --- /dev/null +++ b/qemu-Avoid-deprecated-query-migrate-cache-size-QMP-c.patch @@ -0,0 +1,62 @@ +From c458102192d82a3a8a5f045cd9df34c29b287ab8 Mon Sep 17 00:00:00 2001 +From: Jiri Denemark +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 +Reviewed-by: Peter Krempa +--- + 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 + diff --git a/qemu-Fix-libvirt-hang-due-to-early-TPM-device-stop.patch b/qemu-Fix-libvirt-hang-due-to-early-TPM-device-stop.patch new file mode 100644 index 0000000000000000000000000000000000000000..d191dd5a30a5e9b480c2a7f2a4ee4335df21439f --- /dev/null +++ b/qemu-Fix-libvirt-hang-due-to-early-TPM-device-stop.patch @@ -0,0 +1,51 @@ +From 6d4e247786117b0b9b57722778c26328993a8f52 Mon Sep 17 00:00:00 2001 +From: Stefan Berger +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 +Signed-off-by: Stefan Berger +Reviewed-by: Michal Privoznik +Signed-off-by: yezengruan +--- + 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 + diff --git a/qemu-Fix-swtpm-device-with-aarch64.patch b/qemu-Fix-swtpm-device-with-aarch64.patch new file mode 100644 index 0000000000000000000000000000000000000000..b5160d6390950817bd8ce44e01d5c837a32ac615 --- /dev/null +++ b/qemu-Fix-swtpm-device-with-aarch64.patch @@ -0,0 +1,208 @@ +From 2480d7857c6ea384567009840040b900f5440616 Mon Sep 17 00:00:00 2001 +From: Jim Fehlig +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 + + + + + +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 +Reviewed-by: Andrea Bolognani +Signed-off-by: yezengruan +--- + 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 @@ + + + ++ ++ + + + +@@ -150,6 +152,7 @@ + + + ++ + + + +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 @@ ++ ++ aarch64test ++ 496d7ea8-9739-544b-4ebd-ef08be936e8b ++ 1048576 ++ 1 ++ ++ hvm ++ ++ ++ /usr/bin/qemu-system-aarch64 ++ ++ ++ ++ ++ +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 + diff --git a/qemu-Prepare-for-testing-of-netdev_add-props-via-qem.patch b/qemu-Prepare-for-testing-of-netdev_add-props-via-qem.patch new file mode 100644 index 0000000000000000000000000000000000000000..07bd69d4bdfe7d6b3f602c939bf6e3eb68b9ebad --- /dev/null +++ b/qemu-Prepare-for-testing-of-netdev_add-props-via-qem.patch @@ -0,0 +1,305 @@ +From fb869a0d3a28591d17a9f047eafd3b77513d6d77 Mon Sep 17 00:00:00 2001 +From: Peter Krempa +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 +Reviewed-by: Eric Blake +--- + 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 + diff --git a/qemu-Probe-for-a-few-params-supported-by-migrate-set.patch b/qemu-Probe-for-a-few-params-supported-by-migrate-set.patch new file mode 100644 index 0000000000000000000000000000000000000000..f4f1cc7c577172cd0b72fc457648671f0c286f74 --- /dev/null +++ b/qemu-Probe-for-a-few-params-supported-by-migrate-set.patch @@ -0,0 +1,589 @@ +From aa0f670f9d558c518a5890cbfa7f969e1d2841aa Mon Sep 17 00:00:00 2001 +From: Jiri Denemark +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 +Reviewed-by: Peter Krempa +--- + 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 @@ + + + ++ ++ + 2010000 + 0 + 61700287 +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 @@ + + + ++ ++ + 2010000 + 0 + 42900287 +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 @@ + + + ++ ++ + 2010000 + 0 + 39100287 +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 @@ + + + ++ ++ + 2010000 + 0 + 43100287 +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 @@ + + + ++ ++ ++ + 2011000 + 0 + 39100288 +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 @@ + + + ++ ++ ++ + 2011000 + 0 + 43100288 +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 @@ + + + ++ ++ ++ + 2012000 + 0 + 61700289 +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 @@ + + + ++ ++ ++ + 2011090 + 0 + 42900289 +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 @@ + + + ++ ++ ++ + 2012000 + 0 + 39100289 +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 @@ + + + ++ ++ ++ + 2011090 + 0 + 43100289 +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 @@ + + + ++ ++ + 2007093 + 0 + 39100246 +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 @@ + + + ++ ++ + 2008000 + 0 + 43100246 +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 @@ + + + ++ ++ + 2009000 + 0 + 42900247 +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 @@ + + + ++ ++ + 2009000 + 0 + 39100247 +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 @@ + + + ++ ++ + 2009000 + 0 + 43100247 +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 @@ + + + ++ ++ ++ + 2012050 + 0 + 42900239 +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 @@ + + + ++ ++ ++ + 3000000 + 0 + 0 +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 @@ + + + ++ ++ ++ + 3000000 + 0 + 0 +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 @@ + + + ++ ++ ++ + 3000000 + 0 + 39100239 +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 @@ + + + ++ ++ ++ + 3000000 + 0 + 43100239 +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 @@ + + + ++ ++ ++ + 3000091 + 0 + 42900240 +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 @@ + + + ++ ++ ++ + 3000092 + 0 + 43100240 +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 @@ + + + ++ ++ ++ + 4000000 + 0 + 61700240 +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 @@ + + + ++ ++ ++ + 4000000 + 0 + 42900240 +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 @@ + + + ++ ++ ++ + 4000000 + 0 + 0 +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 @@ + + + ++ ++ ++ + 4000000 + 0 + 0 +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 @@ + + + ++ ++ ++ + 4000000 + 0 + 39100240 +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 @@ + + + ++ ++ ++ + 4000000 + 0 + 43100240 +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 @@ + + + ++ ++ ++ + 4001000 + 0 + 43100241 +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 @@ + + + ++ ++ ++ + 4001050 + 0 + 61700242 +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 @@ + + + ++ ++ ++ + 4001050 + 0 + 42900242 +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 @@ + + + ++ ++ ++ + 4001050 + 0 + 39100242 +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 @@ + + + ++ ++ ++ + 4002000 + 0 + 43100242 +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 @@ + + + ++ ++ ++ + 4002050 + 0 + 61700241 +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 @@ + + + ++ ++ ++ + 4002050 + 0 + 42900241 +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 @@ + + + ++ ++ ++ + 4002050 + 0 + 43100241 +-- +2.27.0 + diff --git a/qemu-Track-numa-mem-supported-machine-attribute.patch b/qemu-Track-numa-mem-supported-machine-attribute.patch new file mode 100644 index 0000000000000000000000000000000000000000..5ea7c374cea0253b61af25bbf685723ad0f177c9 --- /dev/null +++ b/qemu-Track-numa-mem-supported-machine-attribute.patch @@ -0,0 +1,5669 @@ +From 1e4b3c3a1e5777f43cb713c4370deb8ccb4a649b Mon Sep 17 00:00:00 2001 +From: xiaojin Yang +Date: Fri, 11 Mar 2022 16:00:35 +0800 +Subject: [PATCH 6/8] qemu: Track numa-mem-supported machine attribute +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +There is 'numa-mem-supported' machine attribute which specifies +whether '-numa mem=' is supported. Store it in our capabilities +as it will be used in later commits when building the command +line. + +Signed-off-by: Michal Privoznik +Reviewed-by: Ján Tomko + +Signed-off-by: Xiaojin Yang +--- + src/qemu/qemu_capabilities.c | 41 ++- + src/qemu/qemu_capabilities.h | 3 + + src/qemu/qemu_capspriv.h | 3 +- + src/qemu/qemu_monitor.h | 1 + + src/qemu/qemu_monitor_json.c | 11 + + .../caps_1.5.3.x86_64.xml | 60 ++-- + .../caps_1.6.0.x86_64.xml | 68 ++--- + .../caps_1.7.0.x86_64.xml | 76 ++--- + .../caps_2.1.1.x86_64.xml | 92 +++--- + .../caps_2.10.0.aarch64.xml | 204 +++++++------- + .../caps_2.10.0.ppc64.xml | 84 +++--- + .../caps_2.10.0.s390x.xml | 28 +- + .../caps_2.10.0.x86_64.xml | 140 +++++----- + .../caps_2.11.0.s390x.xml | 32 +-- + .../caps_2.11.0.x86_64.xml | 140 +++++----- + .../caps_2.12.0.aarch64.xml | 228 +++++++-------- + .../caps_2.12.0.ppc64.xml | 100 +++---- + .../caps_2.12.0.s390x.xml | 36 +-- + .../caps_2.12.0.x86_64.xml | 148 +++++----- + .../caps_2.4.0.x86_64.xml | 116 ++++---- + .../caps_2.5.0.x86_64.xml | 124 ++++---- + .../caps_2.6.0.aarch64.xml | 164 +++++------ + .../qemucapabilitiesdata/caps_2.6.0.ppc64.xml | 60 ++-- + .../caps_2.6.0.x86_64.xml | 100 +++---- + .../qemucapabilitiesdata/caps_2.7.0.s390x.xml | 16 +- + .../caps_2.7.0.x86_64.xml | 108 +++---- + .../qemucapabilitiesdata/caps_2.8.0.s390x.xml | 20 +- + .../caps_2.8.0.x86_64.xml | 124 ++++---- + .../qemucapabilitiesdata/caps_2.9.0.ppc64.xml | 80 +++--- + .../qemucapabilitiesdata/caps_2.9.0.s390x.xml | 24 +- + .../caps_2.9.0.x86_64.xml | 132 ++++----- + .../qemucapabilitiesdata/caps_3.0.0.ppc64.xml | 104 +++---- + .../caps_3.0.0.riscv32.xml | 10 +- + .../caps_3.0.0.riscv64.xml | 10 +- + .../qemucapabilitiesdata/caps_3.0.0.s390x.xml | 40 +-- + .../caps_3.0.0.x86_64.xml | 156 +++++------ + .../qemucapabilitiesdata/caps_3.1.0.ppc64.xml | 108 +++---- + .../caps_3.1.0.x86_64.xml | 164 +++++------ + .../caps_4.0.0.aarch64.xml | 264 +++++++++--------- + .../qemucapabilitiesdata/caps_4.0.0.ppc64.xml | 112 ++++---- + .../caps_4.0.0.riscv32.xml | 10 +- + .../caps_4.0.0.riscv64.xml | 10 +- + .../qemucapabilitiesdata/caps_4.0.0.s390x.xml | 48 ++-- + .../caps_4.0.0.x86_64.xml | 164 +++++------ + .../caps_4.1.0.x86_64.xml | 176 ++++++------ + .../caps_4.2.0.aarch64.xml | 52 ++-- + .../qemucapabilitiesdata/caps_4.2.0.ppc64.xml | 72 ++--- + .../caps_4.2.0.x86_64.xml | 184 ++++++------ + .../caps_5.0.0.aarch64.xml | 52 ++-- + .../qemucapabilitiesdata/caps_5.0.0.ppc64.xml | 76 ++--- + .../caps_5.0.0.x86_64.xml | 176 ++++++------ + tests/testutilsqemu.c | 6 +- + 52 files changed, 2304 insertions(+), 2253 deletions(-) + +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index fb7726235d..6013be9d05 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -586,6 +586,7 @@ struct _virQEMUCapsMachineType { + bool hotplugCpus; + bool qemuDefault; + char *defaultCPU; ++ bool numaMemSupported; + }; + + typedef struct _virQEMUCapsHostCPUData virQEMUCapsHostCPUData; +@@ -1813,6 +1814,7 @@ virQEMUCapsAccelCopyMachineTypes(virQEMUCapsAccelPtr dst, + dst->machineTypes[i].maxCpus = src->machineTypes[i].maxCpus; + dst->machineTypes[i].hotplugCpus = src->machineTypes[i].hotplugCpus; + dst->machineTypes[i].qemuDefault = src->machineTypes[i].qemuDefault; ++ dst->machineTypes[i].numaMemSupported = src->machineTypes[i].numaMemSupported; + } + } + +@@ -2453,6 +2455,25 @@ virQEMUCapsGetMachineDefaultCPU(virQEMUCapsPtr qemuCaps, + } + + ++bool ++virQEMUCapsGetMachineNumaMemSupported(virQEMUCapsPtr qemuCaps, ++ virDomainVirtType virtType, ++ const char *name) ++{ ++ virQEMUCapsAccelPtr accel; ++ size_t i; ++ ++ accel = virQEMUCapsGetAccel(qemuCaps, virtType); ++ ++ for (i = 0; i < accel->nmachineTypes; i++) { ++ if (STREQ(accel->machineTypes[i].name, name)) ++ return accel->machineTypes[i].numaMemSupported; ++ } ++ ++ return false; ++} ++ ++ + /** + * virQEMUCapsSetGICCapabilities: + * @qemuCaps: QEMU capabilities +@@ -2665,7 +2686,8 @@ virQEMUCapsAddMachine(virQEMUCapsPtr qemuCaps, + const char *defaultCPU, + int maxCpus, + bool hotplugCpus, +- bool isDefault) ++ bool isDefault, ++ bool numaMemSupported) + { + virQEMUCapsAccelPtr accel = virQEMUCapsGetAccel(qemuCaps, virtType); + virQEMUCapsMachineTypePtr mach; +@@ -2684,6 +2706,8 @@ virQEMUCapsAddMachine(virQEMUCapsPtr qemuCaps, + mach->hotplugCpus = hotplugCpus; + + mach->qemuDefault = isDefault; ++ ++ mach->numaMemSupported = numaMemSupported; + } + + /** +@@ -2729,7 +2753,8 @@ virQEMUCapsProbeQMPMachineTypes(virQEMUCapsPtr qemuCaps, + machines[i]->defaultCPU, + machines[i]->maxCpus, + machines[i]->hotplugCpus, +- machines[i]->isDefault); ++ machines[i]->isDefault, ++ machines[i]->numaMemSupported); + + if (preferredMachine && + (STREQ_NULLABLE(machines[i]->alias, preferredMachine) || +@@ -3949,6 +3974,11 @@ virQEMUCapsLoadMachines(virQEMUCapsAccelPtr caps, + caps->machineTypes[i].qemuDefault = true; + VIR_FREE(str); + ++ str = virXMLPropString(nodes[i], "numaMemSupported"); ++ if (STREQ_NULLABLE(str, "yes")) ++ caps->machineTypes[i].numaMemSupported = true; ++ VIR_FREE(str); ++ + caps->machineTypes[i].defaultCPU = virXMLPropString(nodes[i], "defaultCPU"); + } + +@@ -4069,7 +4099,7 @@ virQEMUCapsParseSEVInfo(virQEMUCapsPtr qemuCaps, xmlXPathContextPtr ctxt) + * ... + * + * ... +- * ++ * + * ... + * + */ +@@ -4405,6 +4435,8 @@ virQEMUCapsFormatMachines(virQEMUCapsAccelPtr caps, + virBufferAddLit(buf, " default='yes'"); + virBufferEscapeString(buf, " defaultCPU='%s'", + caps->machineTypes[i].defaultCPU); ++ if (caps->machineTypes[i].numaMemSupported) ++ virBufferAddLit(buf, " numaMemSupported='yes'"); + virBufferAddLit(buf, "/>\n"); + } + } +@@ -6108,7 +6140,8 @@ virQEMUCapsStripMachineAliasesForVirtType(virQEMUCapsPtr qemuCaps, + + if (name) { + virQEMUCapsAddMachine(qemuCaps, virtType, name, NULL, mach->defaultCPU, +- mach->maxCpus, mach->hotplugCpus, mach->qemuDefault); ++ mach->maxCpus, mach->hotplugCpus, mach->qemuDefault, ++ mach->numaMemSupported); + } + } + } +diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h +index 0ac92d77c3..5f28006b48 100644 +--- a/src/qemu/qemu_capabilities.h ++++ b/src/qemu/qemu_capabilities.h +@@ -661,6 +661,9 @@ bool virQEMUCapsGetMachineHotplugCpus(virQEMUCapsPtr qemuCaps, + const char *virQEMUCapsGetMachineDefaultCPU(virQEMUCapsPtr qemuCaps, + const char *name, + virDomainVirtType type); ++bool virQEMUCapsGetMachineNumaMemSupported(virQEMUCapsPtr qemuCaps, ++ virDomainVirtType virtType, ++ const char *name); + + void virQEMUCapsFilterByMachineType(virQEMUCapsPtr qemuCaps, + virDomainVirtType virtType, +diff --git a/src/qemu/qemu_capspriv.h b/src/qemu/qemu_capspriv.h +index 9c2be24ada..4c053af195 100644 +--- a/src/qemu/qemu_capspriv.h ++++ b/src/qemu/qemu_capspriv.h +@@ -119,4 +119,5 @@ virQEMUCapsAddMachine(virQEMUCapsPtr qemuCaps, + const char *defaultCPU, + int maxCpus, + bool hotplugCpus, +- bool isDefault); ++ bool isDefault, ++ bool numaMemSupported); +diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h +index 7a3240f00a..83a33b5b0f 100644 +--- a/src/qemu/qemu_monitor.h ++++ b/src/qemu/qemu_monitor.h +@@ -1095,6 +1095,7 @@ struct _qemuMonitorMachineInfo { + unsigned int maxCpus; + bool hotplugCpus; + char *defaultCPU; ++ bool numaMemSupported; + }; + + int qemuMonitorGetMachines(qemuMonitorPtr mon, +diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c +index c1d92b2009..199b73eafe 100644 +--- a/src/qemu/qemu_monitor_json.c ++++ b/src/qemu/qemu_monitor_json.c +@@ -5634,6 +5634,17 @@ int qemuMonitorJSONGetMachines(qemuMonitorPtr mon, + + info->defaultCPU = g_strdup(tmp); + } ++ ++ if (virJSONValueObjectHasKey(child, "numa-mem-supported")) { ++ if (virJSONValueObjectGetBoolean(child, "numa-mem-supported", &info->numaMemSupported) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("qemu-machines reply has malformed " ++ "'numa-mem-supported' data")); ++ goto cleanup; ++ } ++ } else { ++ info->numaMemSupported = true; ++ } + } + + ret = n; +diff --git a/tests/qemucapabilitiesdata/caps_1.5.3.x86_64.xml b/tests/qemucapabilitiesdata/caps_1.5.3.x86_64.xml +index b57cb2ab59..63609dad86 100644 +--- a/tests/qemucapabilitiesdata/caps_1.5.3.x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_1.5.3.x86_64.xml +@@ -114,21 +114,21 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -153,19 +153,19 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + +diff --git a/tests/qemucapabilitiesdata/caps_1.6.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_1.6.0.x86_64.xml +index 5d0a14a5db..2287e37956 100644 +--- a/tests/qemucapabilitiesdata/caps_1.6.0.x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_1.6.0.x86_64.xml +@@ -119,23 +119,23 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -160,21 +160,21 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + +diff --git a/tests/qemucapabilitiesdata/caps_1.7.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_1.7.0.x86_64.xml +index c196fe5e45..48f9535486 100644 +--- a/tests/qemucapabilitiesdata/caps_1.7.0.x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_1.7.0.x86_64.xml +@@ -121,25 +121,25 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -164,23 +164,23 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + +diff --git a/tests/qemucapabilitiesdata/caps_2.1.1.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.1.1.x86_64.xml +index 1edcaa4657..e792506e8c 100644 +--- a/tests/qemucapabilitiesdata/caps_2.1.1.x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_2.1.1.x86_64.xml +@@ -138,29 +138,29 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -186,27 +186,27 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + +diff --git a/tests/qemucapabilitiesdata/caps_2.10.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_2.10.0.aarch64.xml +index e253df4077..af2787ed1b 100644 +--- a/tests/qemucapabilitiesdata/caps_2.10.0.aarch64.xml ++++ b/tests/qemucapabilitiesdata/caps_2.10.0.aarch64.xml +@@ -179,57 +179,57 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -261,57 +261,57 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +diff --git a/tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml +index 8df611353f..7afb2fa2c5 100644 +--- a/tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml ++++ b/tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml +@@ -581,27 +581,27 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -1035,25 +1035,25 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + +diff --git a/tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml +index 27ce348b80..b307b439f6 100644 +--- a/tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml ++++ b/tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml +@@ -211,13 +211,13 @@ + + + +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ + + + +@@ -1262,11 +1262,11 @@ + + + +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ + +diff --git a/tests/qemucapabilitiesdata/caps_2.10.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.10.0.x86_64.xml +index 368985a611..8e4ab591db 100644 +--- a/tests/qemucapabilitiesdata/caps_2.10.0.x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_2.10.0.x86_64.xml +@@ -532,41 +532,41 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -949,39 +949,39 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + +diff --git a/tests/qemucapabilitiesdata/caps_2.11.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.11.0.s390x.xml +index c5bcf1c818..83c2905e1f 100644 +--- a/tests/qemucapabilitiesdata/caps_2.11.0.s390x.xml ++++ b/tests/qemucapabilitiesdata/caps_2.11.0.s390x.xml +@@ -218,14 +218,14 @@ + + + +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -2609,12 +2609,12 @@ + + + +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ + +diff --git a/tests/qemucapabilitiesdata/caps_2.11.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.11.0.x86_64.xml +index 717ef46f78..ddc187a584 100644 +--- a/tests/qemucapabilitiesdata/caps_2.11.0.x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_2.11.0.x86_64.xml +@@ -510,41 +510,41 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -943,39 +943,39 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + +diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml +index fbee7661a1..fddbfebddd 100644 +--- a/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml ++++ b/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml +@@ -198,63 +198,63 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -289,63 +289,63 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_2.12.0.ppc64.xml +index 31a643f5d1..148b928520 100644 +--- a/tests/qemucapabilitiesdata/caps_2.12.0.ppc64.xml ++++ b/tests/qemucapabilitiesdata/caps_2.12.0.ppc64.xml +@@ -600,31 +600,31 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -1062,29 +1062,29 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + +diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml +index d0ea4d780a..2b1301d234 100644 +--- a/tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml ++++ b/tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml +@@ -231,15 +231,15 @@ + + + +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -2479,13 +2479,13 @@ + + + +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ + +diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml +index 3db7162a34..125346ffd7 100644 +--- a/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml +@@ -667,43 +667,43 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -1242,43 +1242,43 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + 47 + 1 +diff --git a/tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml +index 9b486effe1..b4745d49b9 100644 +--- a/tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml +@@ -167,35 +167,35 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -224,33 +224,33 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + +diff --git a/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml +index 147b179fdb..21fc702fc7 100644 +--- a/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml +@@ -173,37 +173,37 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -232,35 +232,35 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + +diff --git a/tests/qemucapabilitiesdata/caps_2.6.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_2.6.0.aarch64.xml +index fddca13ee2..c41c30c923 100644 +--- a/tests/qemucapabilitiesdata/caps_2.6.0.aarch64.xml ++++ b/tests/qemucapabilitiesdata/caps_2.6.0.aarch64.xml +@@ -159,47 +159,47 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -230,47 +230,47 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +diff --git a/tests/qemucapabilitiesdata/caps_2.6.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_2.6.0.ppc64.xml +index deb5c28790..b619ec4dd1 100644 +--- a/tests/qemucapabilitiesdata/caps_2.6.0.ppc64.xml ++++ b/tests/qemucapabilitiesdata/caps_2.6.0.ppc64.xml +@@ -556,21 +556,21 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -1001,19 +1001,19 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + +diff --git a/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml +index fc508aba8a..492f2720fd 100644 +--- a/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml +@@ -185,31 +185,31 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -238,29 +238,29 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + +diff --git a/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml +index 17351ca6bf..2bacb2008a 100644 +--- a/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml ++++ b/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml +@@ -97,13 +97,13 @@ + + s390x + +- +- +- +- ++ ++ ++ ++ + +- +- +- +- ++ ++ ++ ++ + +diff --git a/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml +index ed199057dc..71cfc3f2c3 100644 +--- a/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml +@@ -191,33 +191,33 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -247,31 +247,31 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + +diff --git a/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml +index 7becf1bfb6..335e2c1a69 100644 +--- a/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml ++++ b/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml +@@ -184,11 +184,11 @@ + + + +- +- +- +- +- ++ ++ ++ ++ ++ + + + +@@ -253,9 +253,9 @@ + + + +- +- +- +- +- ++ ++ ++ ++ ++ + +diff --git a/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml +index 2a0b1f61de..30ef536ecb 100644 +--- a/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml +@@ -222,37 +222,37 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -378,35 +378,35 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + +diff --git a/tests/qemucapabilitiesdata/caps_2.9.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_2.9.0.ppc64.xml +index 9141e29757..e6aee2519b 100644 +--- a/tests/qemucapabilitiesdata/caps_2.9.0.ppc64.xml ++++ b/tests/qemucapabilitiesdata/caps_2.9.0.ppc64.xml +@@ -573,26 +573,26 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -1026,24 +1026,24 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + +diff --git a/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml +index bcc7d4bd4e..ce042443df 100644 +--- a/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml ++++ b/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml +@@ -190,12 +190,12 @@ + + + +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ + + + +@@ -260,10 +260,10 @@ + + + +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ + +diff --git a/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml +index 5cd82aa979..6781484056 100644 +--- a/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml +@@ -473,39 +473,39 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -865,37 +865,37 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + +diff --git a/tests/qemucapabilitiesdata/caps_3.0.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_3.0.0.ppc64.xml +index 6916da2047..b4b9d7ee01 100644 +--- a/tests/qemucapabilitiesdata/caps_3.0.0.ppc64.xml ++++ b/tests/qemucapabilitiesdata/caps_3.0.0.ppc64.xml +@@ -602,32 +602,32 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -1065,30 +1065,30 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + +diff --git a/tests/qemucapabilitiesdata/caps_3.0.0.riscv32.xml b/tests/qemucapabilitiesdata/caps_3.0.0.riscv32.xml +index 802b624073..14550b8c7f 100644 +--- a/tests/qemucapabilitiesdata/caps_3.0.0.riscv32.xml ++++ b/tests/qemucapabilitiesdata/caps_3.0.0.riscv32.xml +@@ -104,9 +104,9 @@ + 0 + + riscv32 +- +- +- +- +- ++ ++ ++ ++ ++ + +diff --git a/tests/qemucapabilitiesdata/caps_3.0.0.riscv64.xml b/tests/qemucapabilitiesdata/caps_3.0.0.riscv64.xml +index a16db0912d..1479b2bb2d 100644 +--- a/tests/qemucapabilitiesdata/caps_3.0.0.riscv64.xml ++++ b/tests/qemucapabilitiesdata/caps_3.0.0.riscv64.xml +@@ -104,9 +104,9 @@ + 0 + + riscv64 +- +- +- +- +- ++ ++ ++ ++ ++ + +diff --git a/tests/qemucapabilitiesdata/caps_3.0.0.s390x.xml b/tests/qemucapabilitiesdata/caps_3.0.0.s390x.xml +index 6992e10237..96984d2bc3 100644 +--- a/tests/qemucapabilitiesdata/caps_3.0.0.s390x.xml ++++ b/tests/qemucapabilitiesdata/caps_3.0.0.s390x.xml +@@ -240,16 +240,16 @@ + + + +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -2689,14 +2689,14 @@ + + + +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + +diff --git a/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml +index 9fdfc634ff..f936f502c3 100644 +--- a/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml +@@ -585,45 +585,45 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -1189,43 +1189,43 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + +diff --git a/tests/qemucapabilitiesdata/caps_3.1.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_3.1.0.ppc64.xml +index 4039923e5f..e1bc4beddb 100644 +--- a/tests/qemucapabilitiesdata/caps_3.1.0.ppc64.xml ++++ b/tests/qemucapabilitiesdata/caps_3.1.0.ppc64.xml +@@ -607,33 +607,33 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -1071,31 +1071,31 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + +diff --git a/tests/qemucapabilitiesdata/caps_3.1.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_3.1.0.x86_64.xml +index 02fc245fca..f462022fb5 100644 +--- a/tests/qemucapabilitiesdata/caps_3.1.0.x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_3.1.0.x86_64.xml +@@ -664,47 +664,47 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -1374,45 +1374,45 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + +diff --git a/tests/qemucapabilitiesdata/caps_4.0.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_4.0.0.aarch64.xml +index 278f2d9135..963c991d5e 100644 +--- a/tests/qemucapabilitiesdata/caps_4.0.0.aarch64.xml ++++ b/tests/qemucapabilitiesdata/caps_4.0.0.aarch64.xml +@@ -215,72 +215,72 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -318,72 +318,72 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +diff --git a/tests/qemucapabilitiesdata/caps_4.0.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_4.0.0.ppc64.xml +index 897ca08af0..2062fd0a90 100644 +--- a/tests/qemucapabilitiesdata/caps_4.0.0.ppc64.xml ++++ b/tests/qemucapabilitiesdata/caps_4.0.0.ppc64.xml +@@ -621,34 +621,34 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -1086,32 +1086,32 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + +diff --git a/tests/qemucapabilitiesdata/caps_4.0.0.riscv32.xml b/tests/qemucapabilitiesdata/caps_4.0.0.riscv32.xml +index 1993d52d42..3bd809f824 100644 +--- a/tests/qemucapabilitiesdata/caps_4.0.0.riscv32.xml ++++ b/tests/qemucapabilitiesdata/caps_4.0.0.riscv32.xml +@@ -179,9 +179,9 @@ + 0 + v4.0.0 + riscv32 +- +- +- +- +- ++ ++ ++ ++ ++ + +diff --git a/tests/qemucapabilitiesdata/caps_4.0.0.riscv64.xml b/tests/qemucapabilitiesdata/caps_4.0.0.riscv64.xml +index 348138ab5a..b0ad30460b 100644 +--- a/tests/qemucapabilitiesdata/caps_4.0.0.riscv64.xml ++++ b/tests/qemucapabilitiesdata/caps_4.0.0.riscv64.xml +@@ -179,9 +179,9 @@ + 0 + v4.0.0 + riscv64 +- +- +- +- +- ++ ++ ++ ++ ++ + +diff --git a/tests/qemucapabilitiesdata/caps_4.0.0.s390x.xml b/tests/qemucapabilitiesdata/caps_4.0.0.s390x.xml +index 1542ed6c68..44e527f570 100644 +--- a/tests/qemucapabilitiesdata/caps_4.0.0.s390x.xml ++++ b/tests/qemucapabilitiesdata/caps_4.0.0.s390x.xml +@@ -254,18 +254,18 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -2902,16 +2902,16 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + +diff --git a/tests/qemucapabilitiesdata/caps_4.0.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_4.0.0.x86_64.xml +index 9292313570..ab43924eaa 100644 +--- a/tests/qemucapabilitiesdata/caps_4.0.0.x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_4.0.0.x86_64.xml +@@ -671,47 +671,47 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -1382,45 +1382,45 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + +diff --git a/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml +index d07a27b4f8..aff2c6fcad 100644 +--- a/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml +@@ -847,50 +847,50 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -1951,48 +1951,48 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + +diff --git a/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml +index fb3d5996c4..6aa36bac54 100644 +--- a/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml ++++ b/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml +@@ -251,7 +251,7 @@ + + + +- ++ + + + +@@ -264,26 +264,26 @@ + + + +- ++ + +- ++ + + +- ++ + + +- ++ + + + + +- ++ + +- ++ + +- ++ + +- ++ + + + +@@ -300,10 +300,10 @@ + + + +- +- ++ ++ + +- ++ + + + +@@ -314,7 +314,7 @@ + + + +- ++ + + + +@@ -380,7 +380,7 @@ + + + +- ++ + + + +@@ -393,26 +393,26 @@ + + + +- ++ + +- ++ + + +- ++ + + +- ++ + + + + +- ++ + +- ++ + +- ++ + +- ++ + + + +@@ -429,10 +429,10 @@ + + + +- +- ++ ++ + +- ++ + + + +@@ -442,7 +442,7 @@ + + + +- ++ + + + +diff --git a/tests/qemucapabilitiesdata/caps_4.2.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_4.2.0.ppc64.xml +index daea978d9f..871dc41579 100644 +--- a/tests/qemucapabilitiesdata/caps_4.2.0.ppc64.xml ++++ b/tests/qemucapabilitiesdata/caps_4.2.0.ppc64.xml +@@ -626,34 +626,34 @@ + + + +- ++ + + + + + +- +- ++ ++ + + +- +- ++ ++ + +- +- +- ++ ++ ++ + +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ + +- +- ++ ++ + + + +@@ -1094,34 +1094,34 @@ + + + +- ++ + + + + + +- +- ++ ++ + + +- +- ++ ++ + +- +- +- ++ ++ ++ + +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ + +- +- ++ ++ + + + +diff --git a/tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml +index 2d5b2ad0f0..383aa10f49 100644 +--- a/tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml +@@ -1099,53 +1099,53 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ + + + +@@ -2562,51 +2562,51 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ + +diff --git a/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml +index be0be79fda..92ad10c9b8 100644 +--- a/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml ++++ b/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml +@@ -255,7 +255,7 @@ + + + +- ++ + + + +@@ -268,26 +268,26 @@ + + + +- ++ + + + + +- ++ + + +- ++ + + + + +- ++ + +- ++ + +- ++ + +- ++ + + + +@@ -306,10 +306,10 @@ + + + +- +- ++ ++ + +- ++ + + + +@@ -320,8 +320,8 @@ + + + +- +- ++ ++ + + + +@@ -388,7 +388,7 @@ + + + +- ++ + + + +@@ -401,26 +401,26 @@ + + + +- ++ + + + + +- ++ + + +- ++ + + + + +- ++ + +- ++ + +- ++ + +- ++ + + + +@@ -439,10 +439,10 @@ + + + +- +- ++ ++ + +- ++ + + + +@@ -453,8 +453,8 @@ + + + +- +- ++ ++ + + + +diff --git a/tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml +index 3ee17a66a4..6842b3c28a 100644 +--- a/tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml ++++ b/tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml +@@ -638,36 +638,36 @@ + + + +- ++ + + +- +- ++ ++ + +- ++ + +- +- +- +- ++ ++ ++ ++ + + +- +- +- +- ++ ++ ++ ++ + +- ++ + +- +- ++ ++ + +- ++ + + +- +- +- ++ ++ ++ + + + +@@ -1109,36 +1109,36 @@ + + + +- ++ + + +- +- ++ ++ + +- ++ + +- +- +- +- ++ ++ ++ ++ + + +- +- +- +- ++ ++ ++ ++ + +- ++ + +- +- ++ ++ + +- ++ + + +- +- +- ++ ++ ++ + + + +diff --git a/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml +index 73f9319199..577b96e6fa 100644 +--- a/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml +@@ -1136,51 +1136,51 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ + + + +@@ -2659,49 +2659,49 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ + +diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c +index bae1fa828b..6c43f07015 100644 +--- a/tests/testutilsqemu.c ++++ b/tests/testutilsqemu.c +@@ -344,7 +344,8 @@ int qemuTestCapsCacheInsert(virFileCachePtr cache, + NULL, + 0, + false, +- false); ++ false, ++ true); + } + for (j = 0; kvm_machines[i][j] != NULL; j++) { + virQEMUCapsAddMachine(tmpCaps, +@@ -354,7 +355,8 @@ int qemuTestCapsCacheInsert(virFileCachePtr cache, + NULL, + 0, + false, +- false); ++ false, ++ true); + virQEMUCapsSet(tmpCaps, QEMU_CAPS_KVM); + } + } +-- +2.27.0 + diff --git a/qemu-command-Generate-netdev-command-line-via-JSON-c.patch b/qemu-command-Generate-netdev-command-line-via-JSON-c.patch new file mode 100644 index 0000000000000000000000000000000000000000..90b8a68fd80b1bbfddfc0d95253d76c9de38eadf --- /dev/null +++ b/qemu-command-Generate-netdev-command-line-via-JSON-c.patch @@ -0,0 +1,354 @@ +From 0ab9df24cbe5b6cfd2aa259aaaef2f8fb2696ce2 Mon Sep 17 00:00:00 2001 +From: Peter Krempa +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 +Reviewed-by: Eric Blake +--- + 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 + diff --git a/qemuBuildChannelChrDeviceStr-Remove-formatting-of-pr.patch b/qemuBuildChannelChrDeviceStr-Remove-formatting-of-pr.patch new file mode 100644 index 0000000000000000000000000000000000000000..6f175ece3e639b36099f3d44827a0ad8e15ead7c --- /dev/null +++ b/qemuBuildChannelChrDeviceStr-Remove-formatting-of-pr.patch @@ -0,0 +1,152 @@ +From f0b20bfdd5e0967da8b98a1c66649c23a94b3d3c Mon Sep 17 00:00:00 2001 +From: Peter Krempa +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 +Reviewed-by: Eric Blake +--- + 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 + diff --git a/qemuBuildChannelGuestfwdNetdevProps-Convert-to-gener.patch b/qemuBuildChannelGuestfwdNetdevProps-Convert-to-gener.patch new file mode 100644 index 0000000000000000000000000000000000000000..b3608a17f76f41bbb2c0910c26987a928c6550ef --- /dev/null +++ b/qemuBuildChannelGuestfwdNetdevProps-Convert-to-gener.patch @@ -0,0 +1,128 @@ +From 17e751be222dd86959f71afda2fca8b0ed09f55b Mon Sep 17 00:00:00 2001 +From: Peter Krempa +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 +Reviewed-by: Eric Blake +--- + 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 + diff --git a/qemuBuildChannelsCommandLine-Extract-common-formatti.patch b/qemuBuildChannelsCommandLine-Extract-common-formatti.patch new file mode 100644 index 0000000000000000000000000000000000000000..8fe7f9358eece44d909434a15aca18333030ee9e --- /dev/null +++ b/qemuBuildChannelsCommandLine-Extract-common-formatti.patch @@ -0,0 +1,72 @@ +From 31c32f8d76a447899ff4a5c551c06a2888814111 Mon Sep 17 00:00:00 2001 +From: Peter Krempa +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 +Reviewed-by: Eric Blake +--- + 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 + diff --git a/qemuBuildChannelsCommandLine-Use-typecasted-switch-f.patch b/qemuBuildChannelsCommandLine-Use-typecasted-switch-f.patch new file mode 100644 index 0000000000000000000000000000000000000000..44dbd6c9c7967a0f02a941bf5323cba4d1da79b4 --- /dev/null +++ b/qemuBuildChannelsCommandLine-Use-typecasted-switch-f.patch @@ -0,0 +1,42 @@ +From 2aac11e296b60464c0ef4870879b6e75d5e0ee46 Mon Sep 17 00:00:00 2001 +From: Peter Krempa +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 +Reviewed-by: Eric Blake +--- + 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 + diff --git a/qemuBuildHostNetStr-Stop-using-ipv6-net-convenience-.patch b/qemuBuildHostNetStr-Stop-using-ipv6-net-convenience-.patch new file mode 100644 index 0000000000000000000000000000000000000000..eb150b05992f19b99924f67fe76bbd55b7cf52e8 --- /dev/null +++ b/qemuBuildHostNetStr-Stop-using-ipv6-net-convenience-.patch @@ -0,0 +1,68 @@ +From ed5210b67f18478af5669976abb6b61c3bd576e0 Mon Sep 17 00:00:00 2001 +From: Peter Krempa +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 +Reviewed-by: Eric Blake +--- + 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 + diff --git a/qemuBuildNumaArgStr-Switch-order-of-if-and-for.patch b/qemuBuildNumaArgStr-Switch-order-of-if-and-for.patch new file mode 100644 index 0000000000000000000000000000000000000000..dfa4cec840cec28e82281aa552fc1f6e43d69c0d --- /dev/null +++ b/qemuBuildNumaArgStr-Switch-order-of-if-and-for.patch @@ -0,0 +1,46 @@ +From 6a0f76d72b231bf0baacf70d715aad387476ac98 Mon Sep 17 00:00:00 2001 +From: xiaojin Yang +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 +Reviewed-by: Ján Tomko + +Signed-off-by: Xiaojin Yang +--- + 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 + diff --git a/qemuBuildNumaArgStr-Use-modern-numa-memdev-if-old-nu.patch b/qemuBuildNumaArgStr-Use-modern-numa-memdev-if-old-nu.patch new file mode 100644 index 0000000000000000000000000000000000000000..6ac3f80adab41fccf061db8367a702ad6e7962cf --- /dev/null +++ b/qemuBuildNumaArgStr-Use-modern-numa-memdev-if-old-nu.patch @@ -0,0 +1,57 @@ +From a6fccda9f1637a3464e812a16c2cd1f12d5b213d Mon Sep 17 00:00:00 2001 +From: xiaojin Yang +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 +Reviewed-by: Ján Tomko + +Signed-off-by: Xiaojin Yang +--- + 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 + diff --git a/qemuMonitorAddNetdev-Convert-to-the-native-JSON-prop.patch b/qemuMonitorAddNetdev-Convert-to-the-native-JSON-prop.patch new file mode 100644 index 0000000000000000000000000000000000000000..a7c69b15ec82b7d3dcea2eaa6242631b85b2448b --- /dev/null +++ b/qemuMonitorAddNetdev-Convert-to-the-native-JSON-prop.patch @@ -0,0 +1,198 @@ +From 2d555c8e864c8ba7dbc7a22e37712b70b59e5293 Mon Sep 17 00:00:00 2001 +From: Peter Krempa +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 +Reviewed-by: Eric Blake +--- + 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 + diff --git a/qemuMonitorJSON-Add-Remove-Netdev-Refactor-cleanup.patch b/qemuMonitorJSON-Add-Remove-Netdev-Refactor-cleanup.patch new file mode 100644 index 0000000000000000000000000000000000000000..a851f75f418c8362bd218f0ce5c8fdc683c45b60 --- /dev/null +++ b/qemuMonitorJSON-Add-Remove-Netdev-Refactor-cleanup.patch @@ -0,0 +1,107 @@ +From 3e1026fb3619aae6b1be4879797474d10d22a54c Mon Sep 17 00:00:00 2001 +From: Peter Krempa +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 +Reviewed-by: Eric Blake +--- + 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 + diff --git a/qemu_tpm-Generate-log-file-path-among-with-storage-p.patch b/qemu_tpm-Generate-log-file-path-among-with-storage-p.patch new file mode 100644 index 0000000000000000000000000000000000000000..1b6c853656eb954a7ac8f08d9e53d1d0a13032e4 --- /dev/null +++ b/qemu_tpm-Generate-log-file-path-among-with-storage-p.patch @@ -0,0 +1,149 @@ +From 85a1643f583a46b1fc3a01d5c2e87ba6262be586 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +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 +Reviewed-by: Ján Tomko +Signed-off-by: yezengruan +--- + 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 + diff --git a/qemu_tpm-Move-logfile-path-generation-into-a-separat.patch b/qemu_tpm-Move-logfile-path-generation-into-a-separat.patch new file mode 100644 index 0000000000000000000000000000000000000000..858d21b030e85b90f3ce1a50d7a98706114d3435 --- /dev/null +++ b/qemu_tpm-Move-logfile-path-generation-into-a-separat.patch @@ -0,0 +1,57 @@ +From bad37cab00ef58f11028246fd2e302f768302dba Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +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 +Reviewed-by: Ján Tomko +Signed-off-by: yezengruan +--- + 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 + diff --git a/qemuxml2argvtest-Add-QAPI-QMP-schema-validation-for-.patch b/qemuxml2argvtest-Add-QAPI-QMP-schema-validation-for-.patch new file mode 100644 index 0000000000000000000000000000000000000000..c61e2ac7442f428f7ba27105114c7d0a82d9f79b --- /dev/null +++ b/qemuxml2argvtest-Add-QAPI-QMP-schema-validation-for-.patch @@ -0,0 +1,181 @@ +From 63e167446b11121a0e375ad28375b6f5a44a5d95 Mon Sep 17 00:00:00 2001 +From: Peter Krempa +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 +Reviewed-by: Eric Blake +--- + 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 + diff --git a/testCompareXMLToArgv-Split-out-preparation-and-comma.patch b/testCompareXMLToArgv-Split-out-preparation-and-comma.patch new file mode 100644 index 0000000000000000000000000000000000000000..b81e2fadd8bda89c1da5fbcf8ebda33eee42d6bd --- /dev/null +++ b/testCompareXMLToArgv-Split-out-preparation-and-comma.patch @@ -0,0 +1,204 @@ +From fb0de8df975557e74af01a0eee0d25c08981c02a Mon Sep 17 00:00:00 2001 +From: Peter Krempa +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 +Reviewed-by: Eric Blake +--- + 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 + diff --git a/tests-Replace-deprecated-ASN1-code.patch b/tests-Replace-deprecated-ASN1-code.patch new file mode 100644 index 0000000000000000000000000000000000000000..2cf05d5934ce7f5ea8087d1c8187fed26d8982f9 --- /dev/null +++ b/tests-Replace-deprecated-ASN1-code.patch @@ -0,0 +1,81 @@ +From 88b38f685d57aac074656104def7111fe854e7c3 Mon Sep 17 00:00:00 2001 +From: Luke Yue +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 +Reviewed-by: Michal Privoznik +--- + 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 + #include + +-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 + diff --git a/tests-disabale-storage-tests.patch b/tests-disabale-storage-tests.patch new file mode 100644 index 0000000000000000000000000000000000000000..09afb47e4674d603f84f59eaa5bdb6f79b66fc21 --- /dev/null +++ b/tests-disabale-storage-tests.patch @@ -0,0 +1,45 @@ +From c4001b2b3f3a078db03ffdc0812e72881972b300 Mon Sep 17 00:00:00 2001 +From: imxcc +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 +--- + 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 + diff --git a/testutilsqemuschema-Introduce-testQEMUSchemaValidate.patch b/testutilsqemuschema-Introduce-testQEMUSchemaValidate.patch new file mode 100644 index 0000000000000000000000000000000000000000..11f423b515edf32f2482dedc9772fbea1a7891fe --- /dev/null +++ b/testutilsqemuschema-Introduce-testQEMUSchemaValidate.patch @@ -0,0 +1,94 @@ +From 740581f96fa4007d6549e82131a9ef48a6478149 Mon Sep 17 00:00:00 2001 +From: Peter Krempa +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 +Reviewed-by: Ján Tomko +--- + 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 + diff --git a/util-json-Introduce-virJSONValueObjectAppendStringPr.patch b/util-json-Introduce-virJSONValueObjectAppendStringPr.patch new file mode 100644 index 0000000000000000000000000000000000000000..7f63b0e99d993bec1109ff8a95ac4b5d2beb1549 --- /dev/null +++ b/util-json-Introduce-virJSONValueObjectAppendStringPr.patch @@ -0,0 +1,73 @@ +From 0924902c3814677f9f328f521a95d4a79635d81a Mon Sep 17 00:00:00 2001 +From: Peter Krempa +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 +Reviewed-by: Eric Blake +--- + 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 + diff --git a/util-virqemu-Introduce-virQEMUBuildNetdevCommandline.patch b/util-virqemu-Introduce-virQEMUBuildNetdevCommandline.patch new file mode 100644 index 0000000000000000000000000000000000000000..299725dedc3d47e5c71b0fead1eeeb8c52342bcd --- /dev/null +++ b/util-virqemu-Introduce-virQEMUBuildNetdevCommandline.patch @@ -0,0 +1,81 @@ +From b9ff1a5a81df23f0a138a7f6d7d3ab0654f669e2 Mon Sep 17 00:00:00 2001 +From: Peter Krempa +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 +Reviewed-by: Eric Blake +--- + 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 + diff --git a/virCommand-Introduce-virCommandGetArgList.patch b/virCommand-Introduce-virCommandGetArgList.patch new file mode 100644 index 0000000000000000000000000000000000000000..997ededa162c96c0d2a0db26102b97e915dac9c1 --- /dev/null +++ b/virCommand-Introduce-virCommandGetArgList.patch @@ -0,0 +1,77 @@ +From 548ea1fcfcfbfc40fab04301e780d28ebe4320a4 Mon Sep 17 00:00:00 2001 +From: Peter Krempa +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 +Reviewed-by: Eric Blake +--- + 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 + diff --git a/virQEMUBuildCommandLineJSON-Add-possibility-for-usin.patch b/virQEMUBuildCommandLineJSON-Add-possibility-for-usin.patch new file mode 100644 index 0000000000000000000000000000000000000000..06aa3aaa7ecd1f718ac9c28c20d44e2fa7247eb5 --- /dev/null +++ b/virQEMUBuildCommandLineJSON-Add-possibility-for-usin.patch @@ -0,0 +1,218 @@ +From b80d9efd8af5de335e3c1de24b74d2e647832458 Mon Sep 17 00:00:00 2001 +From: Peter Krempa +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 +Reviewed-by: Eric Blake +--- + 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 + diff --git a/virQEMUBuildCommandLineJSON-Allow-skipping-certain-k.patch b/virQEMUBuildCommandLineJSON-Allow-skipping-certain-k.patch new file mode 100644 index 0000000000000000000000000000000000000000..e67e949cb9aaa2de93870bae12dbfd409da055c4 --- /dev/null +++ b/virQEMUBuildCommandLineJSON-Allow-skipping-certain-k.patch @@ -0,0 +1,202 @@ +From b1e8b606813b1097cdb3a0d9e9f04c629d7bcf29 Mon Sep 17 00:00:00 2001 +From: Peter Krempa +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 +Reviewed-by: Eric Blake +--- + 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 + diff --git a/virQEMUBuildNetdevCommandlineFromJSON-Prepare-for-qu.patch b/virQEMUBuildNetdevCommandlineFromJSON-Prepare-for-qu.patch new file mode 100644 index 0000000000000000000000000000000000000000..1b2a1bd656660fbe58bec7bd5508557eaad94642 --- /dev/null +++ b/virQEMUBuildNetdevCommandlineFromJSON-Prepare-for-qu.patch @@ -0,0 +1,88 @@ +From 9df86be1d8d974dc6bcf174c63814cd4492ddd5e Mon Sep 17 00:00:00 2001 +From: Peter Krempa +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 +Reviewed-by: Eric Blake +--- + 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 + diff --git a/virtpm-Fix-path-handling-in-virTPMEmulatorInit.patch b/virtpm-Fix-path-handling-in-virTPMEmulatorInit.patch new file mode 100644 index 0000000000000000000000000000000000000000..9697233d5d2647b613112928271dc6387d582d3e --- /dev/null +++ b/virtpm-Fix-path-handling-in-virTPMEmulatorInit.patch @@ -0,0 +1,48 @@ +From 4fe54e0e98050bf4529d67a266b6b10286312eaa Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +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 +Reviewed-by: Ján Tomko +Signed-off-by: yezengruan +--- + 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 +