1 Star 0 Fork 70

Jiabo Feng/libvirt

forked from src-openEuler/libvirt 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
hotpatch-virsh-support-autoload-mode.patch 9.75 KB
一键复制 编辑 原始数据 按行查看 历史
Jiabo Feng 提交于 2024-04-10 21:35 . libvirt update to version 9.10.0-5:
From 48da26004ea0222cc8819e097a004980662ef3eb 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 | 2 +
src/qemu/qemu_driver.c | 5 ++
src/qemu/qemu_hotpatch.c | 120 +++++++++++++++++++++++++++++++
src/qemu/qemu_hotpatch.h | 3 +
src/qemu/qemu_process.c | 7 ++
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 96e62deac3..6120c6cea7 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -6427,6 +6427,7 @@ typedef enum {
VIR_DOMAIN_HOTPATCH_APPLY, /* Apply hotpatch (Since: 6.2.0) */
VIR_DOMAIN_HOTPATCH_UNAPPLY, /* Unapply hotpatch (Since: 6.2.0) */
VIR_DOMAIN_HOTPATCH_QUERY, /* Query hotpatch (Since: 6.2.0) */
+ VIR_DOMAIN_HOTPATCH_AUTOLOAD, /* Autoload hotpatch (Since: 6.2.0) */
# ifdef VIR_ENUM_SENTINELS
VIR_DOMAIN_HOTPATCH_LAST /* Last index (Since: 6.2.0) */
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 513b5ebb1e..30343d3d12 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -1064,6 +1064,12 @@ virQEMUDriverConfigLoadCapsFiltersEntry(virQEMUDriverConfig *cfg,
return 0;
}
+static int
+virQEMUDriverConfigLoadHotpatchPathEntry(virQEMUDriverConfig *cfg,
+ virConf *conf)
+{
+ return virConfGetValueString(conf, "hotpatch_path", &cfg->hotpatchPath);
+}
int virQEMUDriverConfigLoadFile(virQEMUDriverConfig *cfg,
const char *filename,
@@ -1136,6 +1142,9 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfig *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 1a3ba3a0fb..8034ec7885 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -231,6 +231,8 @@ struct _virQEMUDriverConfig {
char *deprecationBehavior;
virQEMUSchedCore schedCore;
+
+ char *hotpatchPath;
};
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virQEMUDriverConfig, virObjectUnref);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 05cc0db3ae..6b07bcc8dc 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -19948,6 +19948,7 @@ qemuDomainHotpatchManage(virDomainPtr domain,
virQEMUDriver *driver = domain->conn->privateData;
char *ret = NULL;
size_t len;
+ g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
virCheckFlags(0, NULL);
@@ -19976,6 +19977,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 31ef5bb7f2..0259ae76c8 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,120 @@ qemuDomainHotpatchUnapply(virDomainObj *vm,
VIR_FREE(output);
return NULL;
}
+
+char *
+qemuDomainHotpatchAutoload(virDomainObj *vm, char *hotpatch_path)
+{
+ g_auto(GStrv) applied_patches = NULL;
+ g_auto(GStrv) 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 = g_strsplit(buf, "\n", 0);
+ if (!lines)
+ return NULL;
+
+ /* get domain hotpatch infomation */
+ applied_patch = qemuDomainHotpatchQuery(vm);
+ if (!applied_patch)
+ return NULL;
+
+ applied_patches = g_strsplit(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++) {
+ g_auto(GStrv) patch_info = NULL;
+ g_autofree char *kpatch_dir = NULL;
+ g_autofree char *file_path = NULL;
+ struct dirent *de;
+ g_autoptr(DIR) dh = NULL;
+ int direrr;
+
+ if (!strstr(lines[i], "QEMU-"))
+ continue;
+
+ patch_info = g_strsplit(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);
+ return NULL;
+ }
+ }
+
+ 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 3cf22f7fc4..7cab4787c6 100644
--- a/src/qemu/qemu_hotpatch.h
+++ b/src/qemu/qemu_hotpatch.h
@@ -34,3 +34,6 @@ qemuDomainHotpatchApply(virDomainObj *vm,
char *
qemuDomainHotpatchUnapply(virDomainObj *vm,
const char *id);
+
+char *
+qemuDomainHotpatchAutoload(virDomainObj *vm, char *path_config);
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 318f9f6182..41e9660ecd 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -61,6 +61,7 @@
#include "qemu_backup.h"
#include "qemu_dbus.h"
#include "qemu_snapshot.h"
+#include "qemu_hotpatch.h"
#include "cpu/cpu.h"
#include "cpu/cpu_x86.h"
@@ -7595,6 +7596,7 @@ qemuProcessLaunch(virConnectPtr conn,
g_autofree int *nicindexes = NULL;
unsigned long long maxMemLock = 0;
bool incomingMigrationExtDevices = false;
+ g_autofree char *autoLoadStatus = NULL;
VIR_DEBUG("conn=%p driver=%p vm=%p name=%s id=%d asyncJob=%d "
"incoming.uri=%s "
@@ -7926,6 +7928,11 @@ qemuProcessLaunch(virConnectPtr conn,
if (qemuProcessDeleteThreadContextHelper(vm, asyncJob) < 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 d88ac3cca6..89bd737f19 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -13574,7 +13574,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,
@@ -13593,7 +13593,8 @@ VIR_ENUM_IMPL(virDomainHotpatchAction,
"none",
"apply",
"unapply",
- "query");
+ "query",
+ "autoload");
static bool
cmdHotpatch(vshControl *ctl,
--
2.27.0
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/JiaboFeng/libvirt.git
git@gitee.com:JiaboFeng/libvirt.git
JiaboFeng
libvirt
libvirt
master

搜索帮助