From eb02e33f400ef9fd1ac2f1d9cb7b95f6b3ccf8ab Mon Sep 17 00:00:00 2001 From: Euler Robot Date: Tue, 19 Oct 2021 14:50:32 +0800 Subject: [PATCH 01/16] Hotpatch: introduce DomainHotpatchManage API Signed-off-by: Hao Wang Signed-off-by: Bihong Yu Signed-off-by: AlexChen --- ...h-introduce-DomainHotpatchManage-API.patch | 211 ++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 Hotpatch-introduce-DomainHotpatchManage-API.patch diff --git a/Hotpatch-introduce-DomainHotpatchManage-API.patch b/Hotpatch-introduce-DomainHotpatchManage-API.patch new file mode 100644 index 0000000..26b643d --- /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 + -- Gitee From 46685efb6b119e1979bd0926decc0b89e1502c4a Mon Sep 17 00:00:00 2001 From: Euler Robot Date: Tue, 19 Oct 2021 22:11:45 +0800 Subject: [PATCH 02/16] hotpatch: Implement qemuDomainHotpatchManage Signed-off-by: Hao Wang Signed-off-by: Bihong Yu Signed-off-by: AlexChen --- ...h-Implement-qemuDomainHotpatchManage.patch | 336 ++++++++++++++++++ 1 file changed, 336 insertions(+) create mode 100644 hotpatch-Implement-qemuDomainHotpatchManage.patch diff --git a/hotpatch-Implement-qemuDomainHotpatchManage.patch b/hotpatch-Implement-qemuDomainHotpatchManage.patch new file mode 100644 index 0000000..79bcd38 --- /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 + -- Gitee From 7c0019006dc737420cfe4ddc95c935a19692db79 Mon Sep 17 00:00:00 2001 From: Euler Robot Date: Tue, 19 Oct 2021 22:41:24 +0800 Subject: [PATCH 03/16] hotpatch: introduce hotpatch async job flag Signed-off-by: Hao Wang Signed-off-by: Bihong Yu Signed-off-by: AlexChen --- ...ch-introduce-hotpatch-async-job-flag.patch | 155 ++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 hotpatch-introduce-hotpatch-async-job-flag.patch diff --git a/hotpatch-introduce-hotpatch-async-job-flag.patch b/hotpatch-introduce-hotpatch-async-job-flag.patch new file mode 100644 index 0000000..24f1611 --- /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 + -- Gitee From b2c18c4b1af04ee46442536e1955ceccecbbf18c Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Mon, 6 Dec 2021 16:28:24 +0800 Subject: [PATCH 04/16] spec: Update patch and changelog with !44 hotpatch: introduce hotpatch async job flag and Implement qemuDomainHotpatchManage !44 Hotpatch: introduce DomainHotpatchManage API hotpatch: Implement qemuDomainHotpatchManage hotpatch: introduce hotpatch async job flag Signed-off-by: AlexChen Signed-off-by: Bihong Yu Signed-off-by: Hao Wang --- libvirt.spec | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libvirt.spec b/libvirt.spec index 72b971c..72fea90 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -190,6 +190,9 @@ 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 Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} @@ -1923,6 +1926,11 @@ exit 0 %changelog +* 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 -- Gitee From 70e1f0d59d2cb00572e691d72aad6e36145aae9b Mon Sep 17 00:00:00 2001 From: Euler Robot Date: Wed, 20 Oct 2021 11:07:34 +0800 Subject: [PATCH 05/16] hotpatch: implement hotpatch virsh api Signed-off-by: Hao Wang Signed-off-by: Bihong Yu Signed-off-by: AlexChen --- hotpatch-implement-hotpatch-virsh-api.patch | 110 ++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 hotpatch-implement-hotpatch-virsh-api.patch diff --git a/hotpatch-implement-hotpatch-virsh-api.patch b/hotpatch-implement-hotpatch-virsh-api.patch new file mode 100644 index 0000000..552ae2d --- /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 + -- Gitee From c119db64e830eae9e9c481ce513188bd71c7845c Mon Sep 17 00:00:00 2001 From: Euler Robot Date: Fri, 9 Jul 2021 10:50:07 +0800 Subject: [PATCH 06/16] 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 --- ...m-id-and-pid-before-using-hotpatch-a.patch | 135 ++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 hotpatch-check-vm-id-and-pid-before-using-hotpatch-a.patch 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 0000000..13d997c --- /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 + -- Gitee From e1bddd724d8eedc65b0da336359d6c00e2bbf5a7 Mon Sep 17 00:00:00 2001 From: Euler Robot Date: Mon, 12 Jul 2021 21:28:41 +0800 Subject: [PATCH 07/16] 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 --- ...add-logs-for-virDomainHotpatchManage.patch | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 domain-add-logs-for-virDomainHotpatchManage.patch diff --git a/domain-add-logs-for-virDomainHotpatchManage.patch b/domain-add-logs-for-virDomainHotpatchManage.patch new file mode 100644 index 0000000..ef63bf4 --- /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 + -- Gitee From 90cd8115bb6c8d2f1895bb298fa2745e4235a6dc Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Mon, 6 Dec 2021 16:28:27 +0800 Subject: [PATCH 08/16] spec: Update patch and changelog with !45 hotpatch: implement hotpatch virsh api and add logs for virDomainHotpatchManage !45 hotpatch: implement hotpatch virsh api hotpatch: check vm id and pid before using hotpatch api domain: add logs for virDomainHotpatchManage Signed-off-by: AlexChen Signed-off-by: Bihong Yu Signed-off-by: Hao Wang --- libvirt.spec | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libvirt.spec b/libvirt.spec index 72fea90..f8bf831 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -193,6 +193,9 @@ 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 Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} @@ -1926,6 +1929,11 @@ exit 0 %changelog +* 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 -- Gitee From 49be1710c52886ae82f4c5d4c7194537e5599358 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Mon, 6 Dec 2021 16:28:37 +0800 Subject: [PATCH 09/16] spec: Update release version with !44 !45 increase release verison by one Signed-off-by: Chen Qun --- libvirt.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libvirt.spec b/libvirt.spec index f8bf831..9f9b3cb 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -105,7 +105,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 6.2.0 -Release: 26 +Release: 27 License: LGPLv2+ URL: https://libvirt.org/ -- Gitee From 823729a5f291de5deabc7cbbdbe0fbbc629b3f36 Mon Sep 17 00:00:00 2001 From: imxcc Date: Tue, 11 Jan 2022 22:32:12 +0800 Subject: [PATCH 10/16] backport: fix rst2html and ASN1 compiler failure Signed-off-by: imxcc --- ...-include-stylesheet-in-intermediate-.patch | 62 ++++++++++++++ libvirt.spec | 10 ++- tests-Replace-deprecated-ASN1-code.patch | 81 +++++++++++++++++++ 3 files changed, 151 insertions(+), 2 deletions(-) create mode 100644 docs-build-Don-t-include-stylesheet-in-intermediate-.patch create mode 100644 tests-Replace-deprecated-ASN1-code.patch 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 0000000..b13d5e0 --- /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/libvirt.spec b/libvirt.spec index 9f9b3cb..ff9d866 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -34,7 +34,7 @@ # Then the secondary host drivers, which run inside libvirtd %define with_storage_rbd 0%{!?_without_storage_rbd:1} %define with_storage_sheepdog 0%{!?_without_storage_sheepdog:0} -%define with_storage_gluster 0%{!?_without_storage_gluster:1} +%define with_storage_gluster 0%{!?_without_storage_gluster:0} %define with_numactl 0%{!?_without_numactl:1} @@ -105,7 +105,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 6.2.0 -Release: 27 +Release: 28 License: LGPLv2+ URL: https://libvirt.org/ @@ -196,6 +196,8 @@ 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 Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} @@ -1929,6 +1931,10 @@ exit 0 %changelog +* Tue Jun 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 diff --git a/tests-Replace-deprecated-ASN1-code.patch b/tests-Replace-deprecated-ASN1-code.patch new file mode 100644 index 0000000..2cf05d5 --- /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 + -- Gitee From ca082a53daed8ef2e155a548469d9884346a29e3 Mon Sep 17 00:00:00 2001 From: imxcc Date: Fri, 14 Jan 2022 12:53:11 +0800 Subject: [PATCH 11/16] tests: disabale storage tests The storagetest in obs cannot be, and related tests are temporarily disabled Signed-off-by: imxcc --- libvirt.spec | 9 ++++-- tests-disabale-storage-tests.patch | 45 ++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 tests-disabale-storage-tests.patch diff --git a/libvirt.spec b/libvirt.spec index ff9d866..688155c 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -34,7 +34,7 @@ # Then the secondary host drivers, which run inside libvirtd %define with_storage_rbd 0%{!?_without_storage_rbd:1} %define with_storage_sheepdog 0%{!?_without_storage_sheepdog:0} -%define with_storage_gluster 0%{!?_without_storage_gluster:0} +%define with_storage_gluster 0%{!?_without_storage_gluster:1} %define with_numactl 0%{!?_without_numactl:1} @@ -105,7 +105,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 6.2.0 -Release: 28 +Release: 29 License: LGPLv2+ URL: https://libvirt.org/ @@ -198,6 +198,7 @@ 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 Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} @@ -302,6 +303,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 @@ -1931,6 +1933,9 @@ exit 0 %changelog +* Fri Jun 14 2022 imxcc +- tests: disabale storage tests + * Tue Jun 11 2022 imxcc - docs: build: Don't include stylesheet in intermediate html - tests: Replace deprecated ASN1 code diff --git a/tests-disabale-storage-tests.patch b/tests-disabale-storage-tests.patch new file mode 100644 index 0000000..09afb47 --- /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 + -- Gitee From 8125920b1b191dcce131d7b1770f87427354cc53 Mon Sep 17 00:00:00 2001 From: imxcc Date: Sat, 29 Jan 2022 17:21:18 +0800 Subject: [PATCH 12/16] Revert "tests: disabale storage tests" glusterfs bug about "tcmalloc" has fixed, details in https://gitee.com/src-openeuler/gluterfs/pulls/26 Signed-off-by: imxcc --- Revert-tests-disabale-storage-tests.patch | 42 +++++++++++++++++++++++ libvirt.spec | 14 ++++---- 2 files changed, 49 insertions(+), 7 deletions(-) create mode 100644 Revert-tests-disabale-storage-tests.patch diff --git a/Revert-tests-disabale-storage-tests.patch b/Revert-tests-disabale-storage-tests.patch new file mode 100644 index 0000000..78cab82 --- /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/libvirt.spec b/libvirt.spec index 688155c..f9adac1 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: 29 +Release: 30 License: LGPLv2+ URL: https://libvirt.org/ @@ -199,6 +195,7 @@ 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 Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} @@ -1245,7 +1242,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 @@ -1811,7 +1808,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} @@ -1933,6 +1930,9 @@ exit 0 %changelog +* Fri Jun 29 2022 imxcc +- Revert "tests: disabale storage tests" + * Fri Jun 14 2022 imxcc - tests: disabale storage tests -- Gitee From 3b3e6707603a4fa58d972a7568643d2e9bfac333 Mon Sep 17 00:00:00 2001 From: imxcc Date: Sat, 12 Feb 2022 12:04:27 +0000 Subject: [PATCH 13/16] Update patch with openeuler !53 hotpatch:virsh support autoload mode Signed-off-by: imxcc --- hotpatch-virsh-support-autoload-mode.patch | 302 +++++++++++++++++++++ libvirt.spec | 6 +- 2 files changed, 307 insertions(+), 1 deletion(-) create mode 100644 hotpatch-virsh-support-autoload-mode.patch diff --git a/hotpatch-virsh-support-autoload-mode.patch b/hotpatch-virsh-support-autoload-mode.patch new file mode 100644 index 0000000..2c95db6 --- /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 f9adac1..40da7e1 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -101,7 +101,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 6.2.0 -Release: 30 +Release: 31 License: LGPLv2+ URL: https://libvirt.org/ @@ -196,6 +196,7 @@ 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 Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} @@ -1930,6 +1931,9 @@ exit 0 %changelog +* Sat Feb 12 2022 imxcc +- hotpatch: virsh support autoload mode + * Fri Jun 29 2022 imxcc - Revert "tests: disabale storage tests" -- Gitee From d5dde3765412bfcb2ef142df2fe63b697ecb72c4 Mon Sep 17 00:00:00 2001 From: imxcc Date: Tue, 22 Feb 2022 00:16:20 +0800 Subject: [PATCH 14/16] update patch with openeuler !54 Signed-off-by: imxcc --- libvirt.spec | 40 +- ...-testing-of-netdev_add-props-via-qem.patch | 305 +++++++++++++++ ...erate-netdev-command-line-via-JSON-c.patch | 354 ++++++++++++++++++ ...ChrDeviceStr-Remove-formatting-of-pr.patch | 152 ++++++++ ...GuestfwdNetdevProps-Convert-to-gener.patch | 128 +++++++ ...sCommandLine-Extract-common-formatti.patch | 72 ++++ ...sCommandLine-Use-typecasted-switch-f.patch | 42 +++ ...Str-Stop-using-ipv6-net-convenience-.patch | 68 ++++ ...tdev-Convert-to-the-native-JSON-prop.patch | 198 ++++++++++ ...N-Add-Remove-Netdev-Refactor-cleanup.patch | 107 ++++++ ...-Add-QAPI-QMP-schema-validation-for-.patch | 181 +++++++++ ...Argv-Split-out-preparation-and-comma.patch | 204 ++++++++++ ...ema-Introduce-testQEMUSchemaValidate.patch | 94 +++++ ...uce-virJSONValueObjectAppendStringPr.patch | 73 ++++ ...roduce-virQEMUBuildNetdevCommandline.patch | 81 ++++ ...mmand-Introduce-virCommandGetArgList.patch | 77 ++++ ...andLineJSON-Add-possibility-for-usin.patch | 218 +++++++++++ ...andLineJSON-Allow-skipping-certain-k.patch | 202 ++++++++++ ...evCommandlineFromJSON-Prepare-for-qu.patch | 88 +++++ 19 files changed, 2683 insertions(+), 1 deletion(-) create mode 100644 qemu-Prepare-for-testing-of-netdev_add-props-via-qem.patch create mode 100644 qemu-command-Generate-netdev-command-line-via-JSON-c.patch create mode 100644 qemuBuildChannelChrDeviceStr-Remove-formatting-of-pr.patch create mode 100644 qemuBuildChannelGuestfwdNetdevProps-Convert-to-gener.patch create mode 100644 qemuBuildChannelsCommandLine-Extract-common-formatti.patch create mode 100644 qemuBuildChannelsCommandLine-Use-typecasted-switch-f.patch create mode 100644 qemuBuildHostNetStr-Stop-using-ipv6-net-convenience-.patch create mode 100644 qemuMonitorAddNetdev-Convert-to-the-native-JSON-prop.patch create mode 100644 qemuMonitorJSON-Add-Remove-Netdev-Refactor-cleanup.patch create mode 100644 qemuxml2argvtest-Add-QAPI-QMP-schema-validation-for-.patch create mode 100644 testCompareXMLToArgv-Split-out-preparation-and-comma.patch create mode 100644 testutilsqemuschema-Introduce-testQEMUSchemaValidate.patch create mode 100644 util-json-Introduce-virJSONValueObjectAppendStringPr.patch create mode 100644 util-virqemu-Introduce-virQEMUBuildNetdevCommandline.patch create mode 100644 virCommand-Introduce-virCommandGetArgList.patch create mode 100644 virQEMUBuildCommandLineJSON-Add-possibility-for-usin.patch create mode 100644 virQEMUBuildCommandLineJSON-Allow-skipping-certain-k.patch create mode 100644 virQEMUBuildNetdevCommandlineFromJSON-Prepare-for-qu.patch diff --git a/libvirt.spec b/libvirt.spec index 40da7e1..10d96fc 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -101,7 +101,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 6.2.0 -Release: 31 +Release: 32 License: LGPLv2+ URL: https://libvirt.org/ @@ -197,6 +197,24 @@ 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 Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} @@ -1931,6 +1949,26 @@ exit 0 %changelog +* 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 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 0000000..07bd69d --- /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-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 0000000..90b8a68 --- /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 0000000..6f175ec --- /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 0000000..b3608a1 --- /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 0000000..8fe7f93 --- /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 0000000..44dbd6c --- /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 0000000..eb150b0 --- /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/qemuMonitorAddNetdev-Convert-to-the-native-JSON-prop.patch b/qemuMonitorAddNetdev-Convert-to-the-native-JSON-prop.patch new file mode 100644 index 0000000..a7c69b1 --- /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 0000000..a851f75 --- /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/qemuxml2argvtest-Add-QAPI-QMP-schema-validation-for-.patch b/qemuxml2argvtest-Add-QAPI-QMP-schema-validation-for-.patch new file mode 100644 index 0000000..c61e2ac --- /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 0000000..b81e2fa --- /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/testutilsqemuschema-Introduce-testQEMUSchemaValidate.patch b/testutilsqemuschema-Introduce-testQEMUSchemaValidate.patch new file mode 100644 index 0000000..11f423b --- /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 0000000..7f63b0e --- /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 0000000..299725d --- /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 0000000..997eded --- /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 0000000..06aa3aa --- /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 0000000..e67e949 --- /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 0000000..1b2a1bd --- /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 + -- Gitee From 4d80e9430b56b99e1613e9b768a52126bfa2d5aa Mon Sep 17 00:00:00 2001 From: yezengruan Date: Fri, 11 Mar 2022 20:33:42 +0800 Subject: [PATCH 15/16] update patch with openeuler !55 Signed-off-by: yezengruan --- libvirt.spec | 26 +- ...cated-migrate-set-cache-size-QMP-com.patch | 81 + ...cated-migrate_set_downtime-QMP-comma.patch | 65 + ...ecated-migrate_set_speed-QMP-command.patch | 174 + ...cated-query-migrate-cache-size-QMP-c.patch | 62 + ...-few-params-supported-by-migrate-set.patch | 589 ++ ...numa-mem-supported-machine-attribute.patch | 5669 +++++++++++++++++ ...umaArgStr-Switch-order-of-if-and-for.patch | 46 + ...Str-Use-modern-numa-memdev-if-old-nu.patch | 57 + 9 files changed, 6765 insertions(+), 4 deletions(-) create mode 100644 qemu-Avoid-deprecated-migrate-set-cache-size-QMP-com.patch create mode 100644 qemu-Avoid-deprecated-migrate_set_downtime-QMP-comma.patch create mode 100644 qemu-Avoid-deprecated-migrate_set_speed-QMP-command.patch create mode 100644 qemu-Avoid-deprecated-query-migrate-cache-size-QMP-c.patch create mode 100644 qemu-Probe-for-a-few-params-supported-by-migrate-set.patch create mode 100644 qemu-Track-numa-mem-supported-machine-attribute.patch create mode 100644 qemuBuildNumaArgStr-Switch-order-of-if-and-for.patch create mode 100644 qemuBuildNumaArgStr-Use-modern-numa-memdev-if-old-nu.patch diff --git a/libvirt.spec b/libvirt.spec index 10d96fc..37e39f8 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -101,7 +101,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 6.2.0 -Release: 32 +Release: 33 License: LGPLv2+ URL: https://libvirt.org/ @@ -215,6 +215,14 @@ 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 Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} @@ -1949,6 +1957,16 @@ exit 0 %changelog +* 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' @@ -1972,13 +1990,13 @@ exit 0 * Sat Feb 12 2022 imxcc - hotpatch: virsh support autoload mode -* Fri Jun 29 2022 imxcc +* Fri Jan 29 2022 imxcc - Revert "tests: disabale storage tests" -* Fri Jun 14 2022 imxcc +* Fri Jan 14 2022 imxcc - tests: disabale storage tests -* Tue Jun 11 2022 imxcc +* Tue Jan 11 2022 imxcc - docs: build: Don't include stylesheet in intermediate html - tests: Replace deprecated ASN1 code 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 0000000..84b8414 --- /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 0000000..6bab2e2 --- /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 0000000..814f508 --- /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 0000000..3fe24e4 --- /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-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 0000000..f4f1cc7 --- /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 0000000..5ea7c37 --- /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/qemuBuildNumaArgStr-Switch-order-of-if-and-for.patch b/qemuBuildNumaArgStr-Switch-order-of-if-and-for.patch new file mode 100644 index 0000000..dfa4cec --- /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 0000000..6ac3f80 --- /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 + -- Gitee From d5507264fde8804d5ce14b7a6dcb4e0cc094b8fb Mon Sep 17 00:00:00 2001 From: yezengruan Date: Sat, 12 Mar 2022 16:00:21 +0800 Subject: [PATCH 16/16] update patch with openeuler !57 Signed-off-by: yezengruan --- ...upport-aarch64-vtpm-with-parameter-t.patch | 108 +++++++++ libvirt.spec | 16 +- ...rt-hang-due-to-early-TPM-device-stop.patch | 51 +++++ qemu-Fix-swtpm-device-with-aarch64.patch | 208 ++++++++++++++++++ ...e-log-file-path-among-with-storage-p.patch | 149 +++++++++++++ ...gfile-path-generation-into-a-separat.patch | 57 +++++ ...-path-handling-in-virTPMEmulatorInit.patch | 48 ++++ 7 files changed, 636 insertions(+), 1 deletion(-) create mode 100644 Revert-libvirt-support-aarch64-vtpm-with-parameter-t.patch create mode 100644 qemu-Fix-libvirt-hang-due-to-early-TPM-device-stop.patch create mode 100644 qemu-Fix-swtpm-device-with-aarch64.patch create mode 100644 qemu_tpm-Generate-log-file-path-among-with-storage-p.patch create mode 100644 qemu_tpm-Move-logfile-path-generation-into-a-separat.patch create mode 100644 virtpm-Fix-path-handling-in-virTPMEmulatorInit.patch 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 0000000..a26b4ce --- /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/libvirt.spec b/libvirt.spec index 37e39f8..44dfe1b 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -101,7 +101,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 6.2.0 -Release: 33 +Release: 34 License: LGPLv2+ URL: https://libvirt.org/ @@ -223,6 +223,12 @@ 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} @@ -1957,6 +1963,14 @@ 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 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 0000000..d191dd5 --- /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 0000000..b5160d6 --- /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_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 0000000..1b6c853 --- /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 0000000..858d21b --- /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/virtpm-Fix-path-handling-in-virTPMEmulatorInit.patch b/virtpm-Fix-path-handling-in-virTPMEmulatorInit.patch new file mode 100644 index 0000000..9697233 --- /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 + -- Gitee