From 85f12e5fa729ba4e28a6846542599426054515c5 Mon Sep 17 00:00:00 2001 From: Euler Robot Date: Tue, 19 Oct 2021 14:50:32 +0800 Subject: [PATCH 1/9] 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 4f14b5522978d9168f6f2a96f3597787b18080cf Mon Sep 17 00:00:00 2001 From: Euler Robot Date: Tue, 19 Oct 2021 22:11:45 +0800 Subject: [PATCH 2/9] 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 30004321c7e02ea9e138be1097ffa0337bad5212 Mon Sep 17 00:00:00 2001 From: Euler Robot Date: Tue, 19 Oct 2021 22:41:24 +0800 Subject: [PATCH 3/9] 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 21982ec222eff2f3a3a5bb3233fb8421a4f018e8 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Mon, 6 Dec 2021 16:28:22 +0800 Subject: [PATCH 4/9] 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 12ea335e029768f327586fe50a0a5cb50b976fb5 Mon Sep 17 00:00:00 2001 From: Euler Robot Date: Wed, 20 Oct 2021 11:07:34 +0800 Subject: [PATCH 5/9] 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 4f8a29100d331802cf87687cac4691656ec3588a Mon Sep 17 00:00:00 2001 From: Euler Robot Date: Fri, 9 Jul 2021 10:50:07 +0800 Subject: [PATCH 6/9] 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 f1c2abe075f23e57bec000bf45a2c39b78bb25aa Mon Sep 17 00:00:00 2001 From: Euler Robot Date: Mon, 12 Jul 2021 21:28:41 +0800 Subject: [PATCH 7/9] 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 481fd67b622435b0ae833d1fdb0eff432e7171f7 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Mon, 6 Dec 2021 16:28:25 +0800 Subject: [PATCH 8/9] 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 ae6bfcdba756a0c87bd201c63b20b8b322c3394e Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Mon, 6 Dec 2021 16:28:27 +0800 Subject: [PATCH 9/9] 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