Projects
home:Eustace:branches:Eulaceura:Factory
libvirt
_service:obs_scm:hotpatch-virsh-support-autoloa...
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:obs_scm:hotpatch-virsh-support-autoload-mode.patch of Package libvirt
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
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2