代码拉取完成,页面将自动刷新
同步操作将从 src-openEuler/libvirt 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
From 3be8bb571d13795c2824dd6d2089035a1be6cf57 Mon Sep 17 00:00:00 2001
From: jiang-dawei15 <jiangdawei15@huawei.com>
Date: Wed, 26 Jan 2022 15:18:10 +0800
Subject: [PATCH] hotpatch: virsh support autoload mode
---
include/libvirt/libvirt-domain.h | 1 +
src/qemu/qemu_conf.c | 9 +++
src/qemu/qemu_conf.h | 1 +
src/qemu/qemu_driver.c | 5 ++
src/qemu/qemu_hotpatch.c | 122 +++++++++++++++++++++++++++++++
src/qemu/qemu_hotpatch.h | 3 +
src/qemu/qemu_process.c | 6 ++
tools/virsh-domain.c | 5 +-
8 files changed, 150 insertions(+), 2 deletions(-)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 2d6432cab2..4ab0c9c0b2 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -4997,6 +4997,7 @@ typedef enum {
VIR_DOMAIN_HOTPATCH_APPLY, /* Apply hotpatch */
VIR_DOMAIN_HOTPATCH_UNAPPLY, /* Unapply hotpatch */
VIR_DOMAIN_HOTPATCH_QUERY, /* Query hotpatch */
+ VIR_DOMAIN_HOTPATCH_AUTOLOAD, /* Autoload hotpatch */
# ifdef VIR_ENUM_SENTINELS
VIR_DOMAIN_HOTPATCH_LAST
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 809e8fe526..bd96ccb78e 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -1006,6 +1006,12 @@ virQEMUDriverConfigLoadCapsFiltersEntry(virQEMUDriverConfigPtr cfg,
return 0;
}
+static int
+virQEMUDriverConfigLoadHotpatchPathEntry(virQEMUDriverConfigPtr cfg,
+ virConfPtr conf)
+{
+ return virConfGetValueString(conf, "hotpatch_path", &cfg->hotpatchPath);
+}
int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg,
const char *filename,
@@ -1078,6 +1084,9 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg,
if (virQEMUDriverConfigLoadCapsFiltersEntry(cfg, conf) < 0)
return -1;
+ if (virQEMUDriverConfigLoadHotpatchPathEntry(cfg, conf) < 0)
+ return -1;
+
return 0;
}
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index 14f9b9e81e..f0124a0fe2 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -220,6 +220,7 @@ struct _virQEMUDriverConfig {
gid_t swtpm_group;
char **capabilityfilters;
+ char *hotpatchPath;
};
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virQEMUDriverConfig, virObjectUnref);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 2b24881f75..37b2c4a2da 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -23186,6 +23186,7 @@ qemuDomainHotpatchManage(virDomainPtr domain,
virQEMUDriverPtr driver = domain->conn->privateData;
char *ret = NULL;
size_t len;
+ g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
virCheckFlags(0, NULL);
@@ -23214,6 +23215,10 @@ qemuDomainHotpatchManage(virDomainPtr domain,
ret = qemuDomainHotpatchQuery(vm);
break;
+ case VIR_DOMAIN_HOTPATCH_AUTOLOAD:
+ ret = qemuDomainHotpatchAutoload(vm, cfg->hotpatchPath);
+ break;
+
default:
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("Unknow hotpatch action"));
diff --git a/src/qemu/qemu_hotpatch.c b/src/qemu/qemu_hotpatch.c
index 03e63c1341..02f511cc38 100644
--- a/src/qemu/qemu_hotpatch.c
+++ b/src/qemu/qemu_hotpatch.c
@@ -25,6 +25,8 @@
#include "virerror.h"
#include "virfile.h"
#include "virlog.h"
+#include "virbuffer.h"
+#include "virstring.h"
#include "vircommand.h"
#include "qemu/qemu_domain.h"
#include "qemu_hotpatch.h"
@@ -32,6 +34,7 @@
#define LIBCARE_CTL "libcare-ctl"
#define LIBCARE_ERROR_NUMBER 255
#define MAX_PATCHID_LEN 8
+#define MAX_FILE_SIZE (1024*1024)
#define VIR_FROM_THIS VIR_FROM_QEMU
@@ -204,3 +207,122 @@ qemuDomainHotpatchUnapply(virDomainObjPtr vm,
VIR_FREE(output);
return NULL;
}
+
+char *
+qemuDomainHotpatchAutoload(virDomainObjPtr vm, char *hotpatch_path)
+{
+ VIR_AUTOSTRINGLIST applied_patches = NULL;
+ VIR_AUTOSTRINGLIST lines = NULL;
+ g_autofree char *applied_patch = NULL;
+ g_autofree char *libvirtd_conf = NULL;
+ g_autofree char *patch_conf = NULL;
+ g_autofree char *buf = NULL;
+ char *ret = NULL;
+ int i, j, len;
+
+ if (hotpatch_path == NULL) {
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("Invalid hotpatch path."));
+ return NULL;
+ }
+
+ /* get hotpatch info from Patch.conf */
+ patch_conf = g_strdup_printf("%s/Patch.conf", hotpatch_path);
+ if ((len = virFileReadAll(patch_conf, MAX_FILE_SIZE, &buf)) < 0) {
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("Failed to read Patch.conf file."));
+ return NULL;
+ }
+ if (len > 0)
+ buf[len-1] = '\0';
+
+ lines = virStringSplit(buf, "\n", 0);
+ if (!lines)
+ return NULL;
+
+ /* get domain hotpatch infomation */
+ applied_patch = qemuDomainHotpatchQuery(vm);
+ if (!applied_patch)
+ return NULL;
+
+ applied_patches = virStringSplit(applied_patch, "\n", 0);
+ if (!applied_patches)
+ return NULL;
+
+ /* load all hotpatch which are listed in Patch.conf one by one */
+ for (i = 0; lines[i] != NULL; i++) {
+ VIR_AUTOSTRINGLIST patch_info = NULL;
+ g_autofree char *kpatch_dir = NULL;
+ g_autofree char *file_path = NULL;
+ struct dirent *de;
+ DIR *dh;
+ int direrr;
+
+ if (!strstr(lines[i], "QEMU-"))
+ continue;
+
+ patch_info = virStringSplit(lines[i], " ", 0);
+ if (!patch_info)
+ continue;
+
+ /* skip already applied patch */
+ if (strstr(applied_patch, patch_info[2]))
+ continue;
+
+ /* get the kpatch file name */
+ kpatch_dir = g_strdup_printf("%s/%s", hotpatch_path, patch_info[1]);
+ if (!kpatch_dir || !virFileExists(kpatch_dir))
+ return NULL;
+
+ if (virDirOpen(&dh, kpatch_dir) < 0)
+ return NULL;
+ if ((direrr = virDirRead(dh, &de, kpatch_dir)) > 0) {
+ GStatBuf sb;
+
+ file_path = g_strdup_printf("%s/%s", kpatch_dir, de->d_name);
+ if (g_lstat(file_path, &sb) < 0) {
+ virReportSystemError(errno, _("Cannot access '%s'"),
+ file_path);
+ VIR_DIR_CLOSE(dh);
+ return NULL;
+ }
+ }
+ VIR_DIR_CLOSE(dh);
+
+ if (qemuDomainHotpatchApply(vm, file_path) == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("failed to apply the hotpatch."));
+ return NULL;
+ }
+ }
+
+ /* unload the hotpatch which are not listed in Patch.conf */
+ for (i = 0; applied_patches[i] != NULL; i++) {
+ const char *patch_id = NULL;
+ bool is_need_unload = true;
+
+ if (!strstr(applied_patches[i], "Patch id"))
+ continue;
+
+ patch_id = strstr(applied_patches[i], ":") + 1;
+ virSkipSpaces(&patch_id);
+
+ for (j = 0; lines[j] != NULL; j++) {
+ if (!strstr(lines[j], "QEMU-"))
+ continue;
+ if (strstr(lines[j], patch_id)) {
+ is_need_unload = false;
+ break;
+ }
+ }
+ if (is_need_unload == true)
+ if (qemuDomainHotpatchUnapply(vm, patch_id) == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("failed to unapply the hotpatch."));
+ return NULL;
+ }
+ }
+
+ ret = g_strdup_printf("Hotpatch autoload successfully.\n");
+ return ret;
+}
diff --git a/src/qemu/qemu_hotpatch.h b/src/qemu/qemu_hotpatch.h
index 4c84a57950..8e0bfe348a 100644
--- a/src/qemu/qemu_hotpatch.h
+++ b/src/qemu/qemu_hotpatch.h
@@ -34,3 +34,6 @@ qemuDomainHotpatchApply(virDomainObjPtr vm,
char *
qemuDomainHotpatchUnapply(virDomainObjPtr vm,
const char *id);
+
+char *
+qemuDomainHotpatchAutoload(virDomainObjPtr vm, char *path_config);
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 818a72d8f9..24dd9f052c 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -59,6 +59,7 @@
#include "qemu_firmware.h"
#include "qemu_backup.h"
#include "qemu_dbus.h"
+#include "qemu_hotpatch.h"
#include "cpu/cpu.h"
#include "cpu/cpu_x86.h"
@@ -6684,6 +6685,7 @@ qemuProcessLaunch(virConnectPtr conn,
g_autoptr(virQEMUDriverConfig) cfg = NULL;
size_t nnicindexes = 0;
g_autofree int *nicindexes = NULL;
+ g_autofree char *autoLoadStatus = NULL;
size_t i;
VIR_DEBUG("conn=%p driver=%p vm=%p name=%s if=%d asyncJob=%d "
@@ -6993,6 +6995,10 @@ qemuProcessLaunch(virConnectPtr conn,
qemuProcessAutoDestroyAdd(driver, vm, conn) < 0)
goto cleanup;
+ /* Autoload hotpatch */
+ if ((autoLoadStatus = qemuDomainHotpatchAutoload(vm, cfg->hotpatchPath)) == NULL) {
+ VIR_WARN("Failed to autoload the hotpatch for %s.", vm->def->name);
+ }
ret = 0;
cleanup:
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 813be4a0db..b5375ebd3e 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -14344,7 +14344,7 @@ static const vshCmdOptDef opts_hotpatch[] = {
{.name = "action",
.type = VSH_OT_DATA,
.flags = VSH_OFLAG_REQ,
- .help = N_("hotpatch action, choose from <apply>, <unapply> and <query>")
+ .help = N_("hotpatch action, choose from <apply>, <unapply>, <query> and <autoload>")
},
{.name = "patch",
.type = VSH_OT_STRING,
@@ -14363,7 +14363,8 @@ VIR_ENUM_IMPL(virDomainHotpatchAction,
"none",
"apply",
"unapply",
- "query");
+ "query",
+ "autoload");
static bool
cmdHotpatch(vshControl *ctl,
--
2.30.0
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。