- hotpatch: if hotpatch_path not in qemu.conf,the hotpatch doesn't antoload - remote: check for negative array lengths before allocation - Fix off-by-one error in udevListInterfacesByStatus - Fix warnings found by clang - hotpatch: virsh support autoload mode - domain: add logs for virDomainHotpatchManage - hotpatch: check vm id and pid before using hotpatch api - hotpatch: implement hotpatch virsh api - hotpatch: introduce hotpatch async job flag - hotpatch: Implement qemuDomainHotpatchManage - Hotpatch: introduce DomainHotpatchManage API Signed-off-by: Jiabo Feng <fengjiabo1@huawei.com>
388 lines
11 KiB
Diff
388 lines
11 KiB
Diff
From 2721c0ce65045c90e54fcab383d4af83415bd3f3 Mon Sep 17 00:00:00 2001
|
|
From: AlexChen <alex.chen@huawei.com>
|
|
Date: Tue, 19 Oct 2021 14:50:32 +0800
|
|
Subject: [PATCH] hotpatch: Implement qemuDomainHotpatchManage
|
|
|
|
Signed-off-by: Hao Wang <wanghao232@huawei.com>
|
|
Signed-off-by: Bihong Yu <yubihong@huawei.com>
|
|
Signed-off-by: AlexChen <alex.chen@huawei.com>
|
|
---
|
|
include/libvirt/libvirt-domain.h | 10 +-
|
|
src/libvirt-domain.c | 2 +-
|
|
src/libvirt_public.syms | 2 +-
|
|
src/qemu/meson.build | 1 +
|
|
src/qemu/qemu_driver.c | 48 ++++++++
|
|
src/qemu/qemu_hotpatch.c | 182 +++++++++++++++++++++++++++++++
|
|
src/qemu/qemu_hotpatch.h | 36 ++++++
|
|
7 files changed, 274 insertions(+), 7 deletions(-)
|
|
create mode 100644 src/qemu/qemu_hotpatch.c
|
|
create mode 100644 src/qemu/qemu_hotpatch.h
|
|
|
|
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
|
|
index f8def59032..e786ecfab2 100644
|
|
--- a/include/libvirt/libvirt-domain.h
|
|
+++ b/include/libvirt/libvirt-domain.h
|
|
@@ -6422,13 +6422,13 @@ int virDomainAuthorizedSSHKeysGet(virDomainPtr domain,
|
|
* Since: 6.2.0
|
|
*/
|
|
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 */
|
|
+ VIR_DOMAIN_HOTPATCH_NONE = 0, /* No action (Since: 6.2.0) */
|
|
+ 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) */
|
|
|
|
# ifdef VIR_ENUM_SENTINELS
|
|
- VIR_DOMAIN_HOTPATCH_LAST
|
|
+ VIR_DOMAIN_HOTPATCH_LAST /* Last index (Since: 6.2.0) */
|
|
# endif
|
|
} virDomainHotpatchAction;
|
|
|
|
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
|
|
index 26833efd0e..21b01110fe 100644
|
|
--- a/src/libvirt-domain.c
|
|
+++ b/src/libvirt-domain.c
|
|
@@ -13805,7 +13805,7 @@ virDomainBackupGetXMLDesc(virDomainPtr domain,
|
|
*
|
|
* Returns success messages in case of success, NULL otherwise.
|
|
*
|
|
- * Since: 6.10.0
|
|
+ * Since: 6.2.0
|
|
*/
|
|
char *
|
|
virDomainHotpatchManage(virDomainPtr domain,
|
|
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
|
|
index 52a5d03240..8b38fe9a5f 100644
|
|
--- a/src/libvirt_public.syms
|
|
+++ b/src/libvirt_public.syms
|
|
@@ -882,7 +882,7 @@ LIBVIRT_6.10.0 {
|
|
global:
|
|
virDomainAuthorizedSSHKeysGet;
|
|
virDomainAuthorizedSSHKeysSet;
|
|
-} LIBVIRT_6.0.0;
|
|
+} LIBVIRT_6.2.0;
|
|
|
|
LIBVIRT_7.1.0 {
|
|
global:
|
|
diff --git a/src/qemu/meson.build b/src/qemu/meson.build
|
|
index 2279fef2ca..9d5b4da35d 100644
|
|
--- a/src/qemu/meson.build
|
|
+++ b/src/qemu/meson.build
|
|
@@ -42,6 +42,7 @@ qemu_driver_sources = [
|
|
'qemu_vhost_user.c',
|
|
'qemu_vhost_user_gpu.c',
|
|
'qemu_virtiofs.c',
|
|
+ 'qemu_hotpatch.c',
|
|
]
|
|
|
|
driver_source_files += files(qemu_driver_sources)
|
|
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
|
|
index d00d2a27c6..3dd82d6f12 100644
|
|
--- a/src/qemu/qemu_driver.c
|
|
+++ b/src/qemu/qemu_driver.c
|
|
@@ -105,6 +105,7 @@
|
|
#include "virdomaincheckpointobjlist.h"
|
|
#include "virutil.h"
|
|
#include "backup_conf.h"
|
|
+#include "qemu_hotpatch.h"
|
|
|
|
#define VIR_FROM_THIS VIR_FROM_QEMU
|
|
|
|
@@ -19934,6 +19935,52 @@ qemuDomainFDAssociate(virDomainPtr domain,
|
|
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,
|
|
@@ -20178,6 +20225,7 @@ static virHypervisorDriver qemuHypervisorDriver = {
|
|
.domainAgentSetResponseTimeout = qemuDomainAgentSetResponseTimeout, /* 5.10.0 */
|
|
.domainBackupBegin = qemuDomainBackupBegin, /* 6.0.0 */
|
|
.domainBackupGetXMLDesc = qemuDomainBackupGetXMLDesc, /* 6.0.0 */
|
|
+ .domainHotpatchManage = qemuDomainHotpatchManage, /* 6.2.0 */
|
|
.domainAuthorizedSSHKeysGet = qemuDomainAuthorizedSSHKeysGet, /* 6.10.0 */
|
|
.domainAuthorizedSSHKeysSet = qemuDomainAuthorizedSSHKeysSet, /* 6.10.0 */
|
|
.domainGetMessages = qemuDomainGetMessages, /* 7.1.0 */
|
|
diff --git a/src/qemu/qemu_hotpatch.c b/src/qemu/qemu_hotpatch.c
|
|
new file mode 100644
|
|
index 0000000000..c1a4ab7aca
|
|
--- /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
|
|
+ * <http://www.gnu.org/licenses/>.
|
|
+ *
|
|
+ */
|
|
+
|
|
+
|
|
+#include <unistd.h>
|
|
+#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(virDomainObj *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(virDomainObj *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(virDomainObj *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..3cf22f7fc4
|
|
--- /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
|
|
+ * <http://www.gnu.org/licenses/>.
|
|
+ *
|
|
+ */
|
|
+
|
|
+#pragma once
|
|
+
|
|
+#include <unistd.h>
|
|
+#include "qemu/qemu_conf.h"
|
|
+
|
|
+char *
|
|
+qemuDomainHotpatchQuery(virDomainObj *vm);
|
|
+
|
|
+char *
|
|
+qemuDomainHotpatchApply(virDomainObj *vm,
|
|
+ const char *patch);
|
|
+
|
|
+char *
|
|
+qemuDomainHotpatchUnapply(virDomainObj *vm,
|
|
+ const char *id);
|
|
--
|
|
2.27.0
|
|
|