From 46685efb6b119e1979bd0926decc0b89e1502c4a Mon Sep 17 00:00:00 2001 From: Euler Robot 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 --- ...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 +