libvirt update to version 9.10.0-5:
- 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>
This commit is contained in:
parent
307ea8abab
commit
f5ca4aa04e
39
Fix-off-by-one-error-in-udevListInterfacesByStatus.patch
Normal file
39
Fix-off-by-one-error-in-udevListInterfacesByStatus.patch
Normal file
@ -0,0 +1,39 @@
|
||||
From 0f082f9d3df0b1c2b63c2b5ad3201e08d1ffe449 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Kletzander <mkletzan@redhat.com>
|
||||
Date: Tue, 27 Feb 2024 16:20:12 +0100
|
||||
Subject: [PATCH] Fix off-by-one error in udevListInterfacesByStatus
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Ever since this function was introduced in 2012 it could've tried
|
||||
filling in an extra interface name. That was made worse in 2019 when
|
||||
the caller functions started accepting NULL arrays of size 0.
|
||||
|
||||
This is assigned CVE-2024-1441.
|
||||
|
||||
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
|
||||
Reported-by: Alexander Kuznetsov <kuznetsovam@altlinux.org>
|
||||
Fixes: 5a33366f5c0b18c93d161bd144f9f079de4ac8ca
|
||||
Fixes: d6064e2759a24e0802f363e3a810dc5a7d7ebb15
|
||||
Reviewed-by: Ján Tomko <jtomko@redhat.com>
|
||||
---
|
||||
src/interface/interface_backend_udev.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/interface/interface_backend_udev.c b/src/interface/interface_backend_udev.c
|
||||
index fb6799ed94..4091483060 100644
|
||||
--- a/src/interface/interface_backend_udev.c
|
||||
+++ b/src/interface/interface_backend_udev.c
|
||||
@@ -222,7 +222,7 @@ udevListInterfacesByStatus(virConnectPtr conn,
|
||||
g_autoptr(virInterfaceDef) def = NULL;
|
||||
|
||||
/* Ensure we won't exceed the size of our array */
|
||||
- if (count > names_len)
|
||||
+ if (count >= names_len)
|
||||
break;
|
||||
|
||||
path = udev_list_entry_get_name(dev_entry);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
30
Fix-warnings-found-by-clang.patch
Normal file
30
Fix-warnings-found-by-clang.patch
Normal file
@ -0,0 +1,30 @@
|
||||
From f3bee7ca84e0e7f915ad425935e6279b227a00a6 Mon Sep 17 00:00:00 2001
|
||||
From: Chenxi Mao <chenxi.mao@suse.com>
|
||||
Date: Tue, 4 Apr 2023 14:25:17 +0800
|
||||
Subject: [PATCH] Fix warnings found by clang
|
||||
|
||||
Warnings found if build with clang 15:
|
||||
|
||||
[ 257s] ../../src/qemu/qemu_hotpatch.c:217:22: error: unused variable 'libvirtd_conf' [-Werror,-Wunused-variable]
|
||||
[ 257s] g_autofree char *libvirtd_conf = NULL;
|
||||
|
||||
Signed-off-by: Chenxi Mao <chenxi.mao@suse.com>
|
||||
---
|
||||
src/qemu/qemu_hotpatch.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/src/qemu/qemu_hotpatch.c b/src/qemu/qemu_hotpatch.c
|
||||
index 0259ae76c8..29d13db030 100644
|
||||
--- a/src/qemu/qemu_hotpatch.c
|
||||
+++ b/src/qemu/qemu_hotpatch.c
|
||||
@@ -214,7 +214,6 @@ 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;
|
||||
--
|
||||
2.27.0
|
||||
|
||||
224
Hotpatch-introduce-DomainHotpatchManage-API.patch
Normal file
224
Hotpatch-introduce-DomainHotpatchManage-API.patch
Normal file
@ -0,0 +1,224 @@
|
||||
From dd9b8be8f47638f9149f3b577f1c38e36cd3e0db 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: introduce DomainHotpatchManage API
|
||||
|
||||
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 | 23 +++++++++++++
|
||||
scripts/check-aclrules.py | 1 +
|
||||
src/driver-hypervisor.h | 8 +++++
|
||||
src/libvirt-domain.c | 59 ++++++++++++++++++++++++++++++++
|
||||
src/libvirt_public.syms | 5 +++
|
||||
src/remote/remote_driver.c | 1 +
|
||||
src/remote/remote_protocol.x | 19 +++++++++-
|
||||
7 files changed, 115 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
|
||||
index a1902546bb..f8def59032 100644
|
||||
--- a/include/libvirt/libvirt-domain.h
|
||||
+++ b/include/libvirt/libvirt-domain.h
|
||||
@@ -6416,6 +6416,29 @@ int virDomainAuthorizedSSHKeysGet(virDomainPtr domain,
|
||||
char ***keys,
|
||||
unsigned int flags);
|
||||
|
||||
+/**
|
||||
+ * virDomainHotpatchAction:
|
||||
+ *
|
||||
+ * 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 */
|
||||
+
|
||||
+# ifdef VIR_ENUM_SENTINELS
|
||||
+ VIR_DOMAIN_HOTPATCH_LAST
|
||||
+# endif
|
||||
+} virDomainHotpatchAction;
|
||||
+
|
||||
+char *
|
||||
+virDomainHotpatchManage(virDomainPtr domain,
|
||||
+ int action,
|
||||
+ const char *patch,
|
||||
+ const char *id,
|
||||
+ unsigned int flags);
|
||||
+
|
||||
/**
|
||||
* virDomainAuthorizedSSHKeysSetFlags:
|
||||
*
|
||||
diff --git a/scripts/check-aclrules.py b/scripts/check-aclrules.py
|
||||
index ed6805058b..e39dbd2ba8 100755
|
||||
--- a/scripts/check-aclrules.py
|
||||
+++ b/scripts/check-aclrules.py
|
||||
@@ -53,6 +53,7 @@ permitted = {
|
||||
"connectURIProbe": True,
|
||||
"localOnly": True,
|
||||
"domainQemuAttach": True,
|
||||
+ "domainHotpatchManage": True,
|
||||
}
|
||||
|
||||
# XXX this vzDomainMigrateConfirm3Params looks
|
||||
diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h
|
||||
index 5219344b72..e54af0515f 100644
|
||||
--- a/src/driver-hypervisor.h
|
||||
+++ b/src/driver-hypervisor.h
|
||||
@@ -1448,6 +1448,13 @@ typedef int
|
||||
int *fds,
|
||||
unsigned int flags);
|
||||
|
||||
+typedef char *
|
||||
+(*virDrvDomainHotpatchManage)(virDomainPtr domain,
|
||||
+ int action,
|
||||
+ const char *patch,
|
||||
+ const char *id,
|
||||
+ unsigned int flags);
|
||||
+
|
||||
typedef struct _virHypervisorDriver virHypervisorDriver;
|
||||
|
||||
/**
|
||||
@@ -1720,4 +1727,5 @@ struct _virHypervisorDriver {
|
||||
virDrvDomainGetMessages domainGetMessages;
|
||||
virDrvDomainStartDirtyRateCalc domainStartDirtyRateCalc;
|
||||
virDrvDomainFDAssociate domainFDAssociate;
|
||||
+ virDrvDomainHotpatchManage domainHotpatchManage;
|
||||
};
|
||||
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
|
||||
index 77a9682ecb..26833efd0e 100644
|
||||
--- a/src/libvirt-domain.c
|
||||
+++ b/src/libvirt-domain.c
|
||||
@@ -13784,6 +13784,65 @@ virDomainBackupGetXMLDesc(virDomainPtr domain,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * virDomainHotpatchManage:
|
||||
+ * @domain: a domain object
|
||||
+ * @action: the action type from virDomainHotpatchAction
|
||||
+ * @patch: the target hotpatch file
|
||||
+ * @id: the patch id of the target hotpatch
|
||||
+ * @flags: extra flags; not used yet, so callers should always pass 0
|
||||
+ *
|
||||
+ * Manage hotpatch for the current domain according to @action.
|
||||
+ *
|
||||
+ * If the @action is set to VIR_DOMAIN_HOTPATCH_APPLY, apply hotpatch
|
||||
+ * @patch to the current domain.
|
||||
+ *
|
||||
+ * If the @action is set to VIR_DOMAIN_HOTPATCH_UNAPPLY, unapply the
|
||||
+ * hotpatch which is matched with @id from the current domain.
|
||||
+ *
|
||||
+ * If the @action is set to VIR_DOMAIN_HOTPATCH_QUERY, query infomations
|
||||
+ * of the applied hotpatch of the current domain.
|
||||
+ *
|
||||
+ * Returns success messages in case of success, NULL otherwise.
|
||||
+ *
|
||||
+ * Since: 6.10.0
|
||||
+ */
|
||||
+char *
|
||||
+virDomainHotpatchManage(virDomainPtr domain,
|
||||
+ int action,
|
||||
+ const char *patch,
|
||||
+ const char *id,
|
||||
+ unsigned int flags)
|
||||
+{
|
||||
+ virConnectPtr conn;
|
||||
+
|
||||
+ virResetLastError();
|
||||
+
|
||||
+ virCheckDomainReturn(domain, NULL);
|
||||
+ conn = domain->conn;
|
||||
+
|
||||
+ virCheckReadOnlyGoto(conn->flags, error);
|
||||
+
|
||||
+ if (action == VIR_DOMAIN_HOTPATCH_APPLY)
|
||||
+ virCheckNonNullArgGoto(patch, error);
|
||||
+
|
||||
+ if (action == VIR_DOMAIN_HOTPATCH_UNAPPLY)
|
||||
+ virCheckNonNullArgGoto(id, error);
|
||||
+
|
||||
+ if (conn->driver->domainHotpatchManage) {
|
||||
+ char *ret;
|
||||
+ ret = conn->driver->domainHotpatchManage(domain, action, patch, id, flags);
|
||||
+ if (!ret)
|
||||
+ goto error;
|
||||
+
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ virReportUnsupportedError();
|
||||
+ error:
|
||||
+ virDispatchError(conn);
|
||||
+ return NULL;
|
||||
+}
|
||||
|
||||
/**
|
||||
* virDomainAuthorizedSSHKeysGet:
|
||||
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
|
||||
index bd1e916d2a..52a5d03240 100644
|
||||
--- a/src/libvirt_public.syms
|
||||
+++ b/src/libvirt_public.syms
|
||||
@@ -873,6 +873,11 @@ LIBVIRT_6.0.0 {
|
||||
virDomainBackupGetXMLDesc;
|
||||
} LIBVIRT_5.10.0;
|
||||
|
||||
+LIBVIRT_6.2.0 {
|
||||
+ global:
|
||||
+ virDomainHotpatchManage;
|
||||
+} LIBVIRT_6.0.0;
|
||||
+
|
||||
LIBVIRT_6.10.0 {
|
||||
global:
|
||||
virDomainAuthorizedSSHKeysGet;
|
||||
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
|
||||
index c4831db6cd..25fae1cad6 100644
|
||||
--- a/src/remote/remote_driver.c
|
||||
+++ b/src/remote/remote_driver.c
|
||||
@@ -7842,6 +7842,7 @@ static virHypervisorDriver hypervisor_driver = {
|
||||
.domainAgentSetResponseTimeout = remoteDomainAgentSetResponseTimeout, /* 5.10.0 */
|
||||
.domainBackupBegin = remoteDomainBackupBegin, /* 6.0.0 */
|
||||
.domainBackupGetXMLDesc = remoteDomainBackupGetXMLDesc, /* 6.0.0 */
|
||||
+ .domainHotpatchManage = remoteDomainHotpatchManage, /* 6.2.0 */
|
||||
.domainAuthorizedSSHKeysGet = remoteDomainAuthorizedSSHKeysGet, /* 6.10.0 */
|
||||
.domainAuthorizedSSHKeysSet = remoteDomainAuthorizedSSHKeysSet, /* 6.10.0 */
|
||||
.domainGetMessages = remoteDomainGetMessages, /* 7.1.0 */
|
||||
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
|
||||
index e295b0acc3..eea11df2ea 100644
|
||||
--- a/src/remote/remote_protocol.x
|
||||
+++ b/src/remote/remote_protocol.x
|
||||
@@ -3956,6 +3956,17 @@ struct remote_domain_event_memory_device_size_change_msg {
|
||||
unsigned hyper size;
|
||||
};
|
||||
|
||||
+struct remote_domain_hotpatch_manage_args {
|
||||
+ remote_nonnull_domain dom;
|
||||
+ int action;
|
||||
+ remote_string patch;
|
||||
+ remote_string id;
|
||||
+ unsigned int flags;
|
||||
+};
|
||||
+
|
||||
+struct remote_domain_hotpatch_manage_ret {
|
||||
+ remote_string info;
|
||||
+};
|
||||
|
||||
struct remote_domain_fd_associate_args {
|
||||
remote_nonnull_domain dom;
|
||||
@@ -7021,5 +7032,11 @@ enum remote_procedure {
|
||||
* @generate: both
|
||||
* @acl: none
|
||||
*/
|
||||
- REMOTE_PROC_NETWORK_EVENT_CALLBACK_METADATA_CHANGE = 446
|
||||
+ REMOTE_PROC_NETWORK_EVENT_CALLBACK_METADATA_CHANGE = 446,
|
||||
+
|
||||
+ /**
|
||||
+ * @generate: both
|
||||
+ * @acl: domain:read
|
||||
+ */
|
||||
+ REMOTE_PROC_DOMAIN_HOTPATCH_MANAGE = 800
|
||||
};
|
||||
--
|
||||
2.27.0
|
||||
|
||||
45
domain-add-logs-for-virDomainHotpatchManage.patch
Normal file
45
domain-add-logs-for-virDomainHotpatchManage.patch
Normal file
@ -0,0 +1,45 @@
|
||||
From a7f63f8c85e3bc287920ed83361e4f44ce2e25d7 Mon Sep 17 00:00:00 2001
|
||||
From: AlexChen <alex.chen@huawei.com>
|
||||
Date: Mon, 12 Jul 2021 21:28:41 +0800
|
||||
Subject: [PATCH] domain: add logs for virDomainHotpatchManage
|
||||
|
||||
Add logs for virDomainHotpatchManage to facilitate the location of
|
||||
issues related to subsequent hotpatch.
|
||||
|
||||
Signed-off-by: Bihong Yu <yubihong@huawei.com>
|
||||
Signed-off-by: AlexChen <alex.chen@huawei.com>
|
||||
---
|
||||
src/libvirt-domain.c | 13 +++++++++++--
|
||||
1 file changed, 11 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
|
||||
index 21b01110fe..b1c5a8c52c 100644
|
||||
--- a/src/libvirt-domain.c
|
||||
+++ b/src/libvirt-domain.c
|
||||
@@ -13829,12 +13829,21 @@ virDomainHotpatchManage(virDomainPtr domain,
|
||||
if (action == VIR_DOMAIN_HOTPATCH_UNAPPLY)
|
||||
virCheckNonNullArgGoto(id, error);
|
||||
|
||||
+ VIR_INFO("enter virDomainHotpatchManage domainname=%s, action=%d, "
|
||||
+ "patch=%s, id=%s, flags=%d",
|
||||
+ NULLSTR(domain->name), action,
|
||||
+ NULLSTR(patch), NULLSTR(id), flags);
|
||||
+
|
||||
if (conn->driver->domainHotpatchManage) {
|
||||
char *ret;
|
||||
ret = conn->driver->domainHotpatchManage(domain, action, patch, id, flags);
|
||||
- if (!ret)
|
||||
+ if (!ret) {
|
||||
+ VIR_ERROR("domain %s managed hotpatch failed",
|
||||
+ NULLSTR(domain->name));
|
||||
goto error;
|
||||
-
|
||||
+ }
|
||||
+ VIR_INFO("domain %s managed hotpatch successfully",
|
||||
+ NULLSTR(domain->name));
|
||||
return ret;
|
||||
}
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
387
hotpatch-Implement-qemuDomainHotpatchManage.patch
Normal file
387
hotpatch-Implement-qemuDomainHotpatchManage.patch
Normal file
@ -0,0 +1,387 @@
|
||||
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
|
||||
|
||||
151
hotpatch-check-vm-id-and-pid-before-using-hotpatch-a.patch
Normal file
151
hotpatch-check-vm-id-and-pid-before-using-hotpatch-a.patch
Normal file
@ -0,0 +1,151 @@
|
||||
From ebdf0312a590ba60f3d304f338737155f469dd7a Mon Sep 17 00:00:00 2001
|
||||
From: AlexChen <alex.chen@huawei.com>
|
||||
Date: Fri, 9 Jul 2021 10:50:07 +0800
|
||||
Subject: [PATCH] hotpatch: check vm id and pid before using hotpatch api
|
||||
|
||||
Check if the vm is alive before using hotpatch api by calling
|
||||
virDomainObjCheckActive() to check vm id and calling
|
||||
qemuDomainHotpatchCheckPid() to check vm pid.
|
||||
|
||||
Signed-off-by: Bihong Yu <yubihong@huawei.com>
|
||||
Signed-off-by: AlexChen <alex.chen@huawei.com>
|
||||
---
|
||||
src/qemu/qemu_driver.c | 9 ++++++---
|
||||
src/qemu/qemu_hotpatch.c | 36 ++++++++++++++++++++++++++++++------
|
||||
2 files changed, 36 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
|
||||
index 31917ef591..05cc0db3ae 100644
|
||||
--- a/src/qemu/qemu_driver.c
|
||||
+++ b/src/qemu/qemu_driver.c
|
||||
@@ -19954,11 +19954,14 @@ qemuDomainHotpatchManage(virDomainPtr domain,
|
||||
if (!(vm = qemuDomainObjFromDomain(domain)))
|
||||
goto cleanup;
|
||||
|
||||
- if (VirDomainObjBeginAsyncJob(driver, vm, QEMU_ASYNC_JOB_HOTPATCH,
|
||||
+ if (virDomainObjBeginAsyncJob(vm, VIR_ASYNC_JOB_HOTPATCH,
|
||||
VIR_DOMAIN_JOB_OPERATION_HOTPATCH, 0) < 0)
|
||||
goto cleanup;
|
||||
|
||||
- qemuDomainObjSetAsyncJobMask(vm, QEMU_JOB_DEFAULT_MASK);
|
||||
+ if (virDomainObjCheckActive(vm) < 0)
|
||||
+ goto endjob;
|
||||
+
|
||||
+ qemuDomainObjSetAsyncJobMask(vm, VIR_JOB_DEFAULT_MASK);
|
||||
|
||||
switch (action) {
|
||||
case VIR_DOMAIN_HOTPATCH_APPLY:
|
||||
@@ -19987,7 +19990,7 @@ qemuDomainHotpatchManage(virDomainPtr domain,
|
||||
ret[len - 1] = '\0';
|
||||
|
||||
endjob:
|
||||
- qemuDomainObjEndAsyncJob(driver, vm);
|
||||
+ virDomainObjEndAsyncJob(vm);
|
||||
|
||||
cleanup:
|
||||
virDomainObjEndAPI(&vm);
|
||||
diff --git a/src/qemu/qemu_hotpatch.c b/src/qemu/qemu_hotpatch.c
|
||||
index c1a4ab7aca..31ef5bb7f2 100644
|
||||
--- a/src/qemu/qemu_hotpatch.c
|
||||
+++ b/src/qemu/qemu_hotpatch.c
|
||||
@@ -37,12 +37,25 @@
|
||||
|
||||
VIR_LOG_INIT("qemu_hotpatch");
|
||||
|
||||
+static int
|
||||
+qemuDomainHotpatchCheckPid(pid_t pid)
|
||||
+{
|
||||
+ if (pid <= 0) {
|
||||
+ virReportError(VIR_ERR_INVALID_ARG,
|
||||
+ "%s", _("Invalid pid"));
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
char *
|
||||
qemuDomainHotpatchQuery(virDomainObj *vm)
|
||||
{
|
||||
g_autoptr(virCommand) cmd = NULL;
|
||||
g_autofree char *binary = NULL;
|
||||
char *output = NULL;
|
||||
+ pid_t pid = vm->pid;
|
||||
int ret = -1;
|
||||
|
||||
if (!(binary = virFindFileInPath(LIBCARE_CTL))) {
|
||||
@@ -51,12 +64,15 @@ qemuDomainHotpatchQuery(virDomainObj *vm)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+ if (qemuDomainHotpatchCheckPid(pid) < 0)
|
||||
+ return NULL;
|
||||
+
|
||||
cmd = virCommandNewArgList(binary, "info", "-p", NULL);
|
||||
- virCommandAddArgFormat(cmd, "%d", vm->pid);
|
||||
+ virCommandAddArgFormat(cmd, "%d", pid);
|
||||
virCommandSetOutputBuffer(cmd, &output);
|
||||
|
||||
VIR_DEBUG("Querying hotpatch for domain %s. (%s info -p %d)",
|
||||
- vm->def->name, binary, vm->pid);
|
||||
+ vm->def->name, binary, pid);
|
||||
|
||||
if (virCommandRun(cmd, &ret) < 0)
|
||||
goto error;
|
||||
@@ -80,6 +96,7 @@ qemuDomainHotpatchApply(virDomainObj *vm,
|
||||
g_autoptr(virCommand) cmd = NULL;
|
||||
g_autofree char *binary = NULL;
|
||||
char *output = NULL;
|
||||
+ pid_t pid = vm->pid;
|
||||
int ret = -1;
|
||||
|
||||
if (!patch || !virFileExists(patch)) {
|
||||
@@ -94,13 +111,16 @@ qemuDomainHotpatchApply(virDomainObj *vm,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+ if (qemuDomainHotpatchCheckPid(pid) < 0)
|
||||
+ return NULL;
|
||||
+
|
||||
cmd = virCommandNewArgList(binary, "patch", "-p", NULL);
|
||||
- virCommandAddArgFormat(cmd, "%d", vm->pid);
|
||||
+ virCommandAddArgFormat(cmd, "%d", 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);
|
||||
+ vm->def->name, binary, pid, patch);
|
||||
|
||||
if (virCommandRun(cmd, &ret) < 0)
|
||||
goto error;
|
||||
@@ -144,6 +164,7 @@ qemuDomainHotpatchUnapply(virDomainObj *vm,
|
||||
g_autoptr(virCommand) cmd = NULL;
|
||||
g_autofree char *binary = NULL;
|
||||
char *output = NULL;
|
||||
+ pid_t pid = vm->pid;
|
||||
int ret = -1;
|
||||
|
||||
if (!id || !qemuDomainHotpatchIsPatchidValid(id)) {
|
||||
@@ -158,13 +179,16 @@ qemuDomainHotpatchUnapply(virDomainObj *vm,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+ if (qemuDomainHotpatchCheckPid(pid) < 0)
|
||||
+ return NULL;
|
||||
+
|
||||
cmd = virCommandNewArgList(binary, "unpatch", "-p", NULL);
|
||||
- virCommandAddArgFormat(cmd, "%d", vm->pid);
|
||||
+ virCommandAddArgFormat(cmd, "%d", 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);
|
||||
+ vm->def->name, binary, pid, id);
|
||||
|
||||
if (virCommandRun(cmd, &ret) < 0)
|
||||
goto error;
|
||||
--
|
||||
2.27.0
|
||||
|
||||
34
hotpatch-if-hotpatch_path-not-in-qemu.conf-the-hotpa.patch
Normal file
34
hotpatch-if-hotpatch_path-not-in-qemu.conf-the-hotpa.patch
Normal file
@ -0,0 +1,34 @@
|
||||
From 033b8d177e4512f0ba3af8ed46ee38a4251c7e1c Mon Sep 17 00:00:00 2001
|
||||
From: Dawei Jiang <jiangdawei15@huawei.com>
|
||||
Date: Mon, 8 Apr 2024 19:59:11 +0800
|
||||
Subject: [PATCH] hotpatch: if hotpatch_path not in qemu.conf,the hotpatch
|
||||
doesn't antoload
|
||||
|
||||
Signed-off-by: Dawei Jiang <jiangdawei15@huawei.com>
|
||||
---
|
||||
src/qemu/qemu_process.c | 8 +++++---
|
||||
1 file changed, 5 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
|
||||
index 41e9660ecd..348280d9be 100644
|
||||
--- a/src/qemu/qemu_process.c
|
||||
+++ b/src/qemu/qemu_process.c
|
||||
@@ -7929,10 +7929,12 @@ qemuProcessLaunch(virConnectPtr conn,
|
||||
goto cleanup;
|
||||
|
||||
/* Autoload hotpatch */
|
||||
- if ((autoLoadStatus = qemuDomainHotpatchAutoload(vm, cfg->hotpatchPath)) == NULL) {
|
||||
- VIR_WARN("Failed to autoload the hotpatch for %s.", vm->def->name);
|
||||
+ if (cfg->hotpatchPath != NULL) {
|
||||
+ autoLoadStatus = qemuDomainHotpatchAutoload(vm, cfg->hotpatchPath);
|
||||
+ if (autoLoadStatus == NULL) {
|
||||
+ VIR_WARN("Failed to autoload the hotpatch for %s.", vm->def->name);
|
||||
+ }
|
||||
}
|
||||
-
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
--
|
||||
2.27.0
|
||||
|
||||
110
hotpatch-implement-hotpatch-virsh-api.patch
Normal file
110
hotpatch-implement-hotpatch-virsh-api.patch
Normal file
@ -0,0 +1,110 @@
|
||||
From d56a3df418b90f4a6f303a3830732b5fde8d3a10 Mon Sep 17 00:00:00 2001
|
||||
From: AlexChen <alex.chen@huawei.com>
|
||||
Date: Wed, 20 Oct 2021 11:07:34 +0800
|
||||
Subject: [PATCH] hotpatch: implement hotpatch virsh api
|
||||
|
||||
Signed-off-by: Hao Wang <wanghao232@huawei.com>
|
||||
Signed-off-by: Bihong Yu <yubihong@huawei.com>
|
||||
Signed-off-by: AlexChen <alex.chen@huawei.com>
|
||||
---
|
||||
tools/virsh-domain.c | 78 ++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 78 insertions(+)
|
||||
|
||||
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
|
||||
index 9d22e219f7..d88ac3cca6 100644
|
||||
--- a/tools/virsh-domain.c
|
||||
+++ b/tools/virsh-domain.c
|
||||
@@ -13556,6 +13556,78 @@ cmdGuestInfo(vshControl *ctl, const vshCmd *cmd)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * "hotpatch" command
|
||||
+ */
|
||||
+static const vshCmdInfo info_hotpatch[] = {
|
||||
+ {.name = "help",
|
||||
+ .data = N_("Manage hotpatch of a live domain")
|
||||
+ },
|
||||
+ {.name = "desc",
|
||||
+ .data = N_("Manage hotpatch of a live domain")
|
||||
+ },
|
||||
+ {.name = NULL}
|
||||
+};
|
||||
+
|
||||
+static const vshCmdOptDef opts_hotpatch[] = {
|
||||
+ VIRSH_COMMON_OPT_DOMAIN_FULL(0),
|
||||
+ {.name = "action",
|
||||
+ .type = VSH_OT_DATA,
|
||||
+ .flags = VSH_OFLAG_REQ,
|
||||
+ .help = N_("hotpatch action, choose from <apply>, <unapply> and <query>")
|
||||
+ },
|
||||
+ {.name = "patch",
|
||||
+ .type = VSH_OT_STRING,
|
||||
+ .help = N_("the absolute path of the hotpatch file, mandatory when action=apply")
|
||||
+ },
|
||||
+ {.name = "id",
|
||||
+ .type = VSH_OT_STRING,
|
||||
+ .help = N_("the unique id of the target patch, mandatory when action=unapply")
|
||||
+ },
|
||||
+ {.name = NULL}
|
||||
+};
|
||||
+
|
||||
+VIR_ENUM_DECL(virDomainHotpatchAction);
|
||||
+VIR_ENUM_IMPL(virDomainHotpatchAction,
|
||||
+ VIR_DOMAIN_HOTPATCH_LAST,
|
||||
+ "none",
|
||||
+ "apply",
|
||||
+ "unapply",
|
||||
+ "query");
|
||||
+
|
||||
+static bool
|
||||
+cmdHotpatch(vshControl *ctl,
|
||||
+ const vshCmd *cmd)
|
||||
+{
|
||||
+ g_autoptr(virshDomain) dom = NULL;
|
||||
+ const char *patch = NULL;
|
||||
+ const char *id = NULL;
|
||||
+ const char *actionstr = NULL;
|
||||
+ int action = -1;
|
||||
+ g_autofree char *ret = NULL;
|
||||
+
|
||||
+ if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
|
||||
+ return false;
|
||||
+
|
||||
+ if (vshCommandOptStringReq(ctl, cmd, "action", &actionstr) < 0)
|
||||
+ return false;
|
||||
+
|
||||
+ if (actionstr)
|
||||
+ action = virDomainHotpatchActionTypeFromString(actionstr);
|
||||
+
|
||||
+ if (vshCommandOptStringReq(ctl, cmd, "patch", &patch) < 0)
|
||||
+ return false;
|
||||
+
|
||||
+ if (vshCommandOptStringReq(ctl, cmd, "id", &id) < 0)
|
||||
+ return false;
|
||||
+
|
||||
+ if (!(ret = virDomainHotpatchManage(dom, action, patch, id, 0)))
|
||||
+ return false;
|
||||
+
|
||||
+ vshPrint(ctl, _("%s"), ret);
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* "get-user-sshkeys" command
|
||||
*/
|
||||
@@ -14456,5 +14528,11 @@ const vshCmdDef domManagementCmds[] = {
|
||||
.info = info_dom_fd_associate,
|
||||
.flags = 0
|
||||
},
|
||||
+ {.name = "hotpatch",
|
||||
+ .handler = cmdHotpatch,
|
||||
+ .opts = opts_hotpatch,
|
||||
+ .info = info_hotpatch,
|
||||
+ .flags = 0
|
||||
+ },
|
||||
{.name = NULL}
|
||||
};
|
||||
--
|
||||
2.27.0
|
||||
|
||||
161
hotpatch-introduce-hotpatch-async-job-flag.patch
Normal file
161
hotpatch-introduce-hotpatch-async-job-flag.patch
Normal file
@ -0,0 +1,161 @@
|
||||
From 180e19162083fb74e9e9cbc676ce42611bb2e496 Mon Sep 17 00:00:00 2001
|
||||
From: AlexChen <alex.chen@huawei.com>
|
||||
Date: Tue, 19 Oct 2021 22:41:24 +0800
|
||||
Subject: [PATCH] hotpatch: introduce hotpatch async job flag
|
||||
|
||||
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 | 1 +
|
||||
src/conf/virdomainjob.c | 1 +
|
||||
src/conf/virdomainjob.h | 1 +
|
||||
src/qemu/qemu_domainjob.c | 2 ++
|
||||
src/qemu/qemu_driver.c | 14 +++++++++++++-
|
||||
src/qemu/qemu_migration.c | 2 ++
|
||||
src/qemu/qemu_process.c | 1 +
|
||||
tools/virsh-domain.c | 1 +
|
||||
8 files changed, 22 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
|
||||
index e786ecfab2..96e62deac3 100644
|
||||
--- a/include/libvirt/libvirt-domain.h
|
||||
+++ b/include/libvirt/libvirt-domain.h
|
||||
@@ -4201,6 +4201,7 @@ typedef enum {
|
||||
VIR_DOMAIN_JOB_OPERATION_DUMP = 8, /* (Since: 3.3.0) */
|
||||
VIR_DOMAIN_JOB_OPERATION_BACKUP = 9, /* (Since: 6.0.0) */
|
||||
VIR_DOMAIN_JOB_OPERATION_SNAPSHOT_DELETE = 10, /* (Since: 9.0.0) */
|
||||
+ VIR_DOMAIN_JOB_OPERATION_HOTPATCH = 11, /* (Since: 6.2.0) */
|
||||
|
||||
# ifdef VIR_ENUM_SENTINELS
|
||||
VIR_DOMAIN_JOB_OPERATION_LAST /* (Since: 3.3.0) */
|
||||
diff --git a/src/conf/virdomainjob.c b/src/conf/virdomainjob.c
|
||||
index 38f08f1d18..d21fc653a0 100644
|
||||
--- a/src/conf/virdomainjob.c
|
||||
+++ b/src/conf/virdomainjob.c
|
||||
@@ -51,6 +51,7 @@ VIR_ENUM_IMPL(virDomainAsyncJob,
|
||||
"snapshot",
|
||||
"start",
|
||||
"backup",
|
||||
+ "hotpatch",
|
||||
);
|
||||
|
||||
virDomainJobData *
|
||||
diff --git a/src/conf/virdomainjob.h b/src/conf/virdomainjob.h
|
||||
index 0d62bab287..d0f632edad 100644
|
||||
--- a/src/conf/virdomainjob.h
|
||||
+++ b/src/conf/virdomainjob.h
|
||||
@@ -75,6 +75,7 @@ typedef enum {
|
||||
VIR_ASYNC_JOB_SNAPSHOT,
|
||||
VIR_ASYNC_JOB_START,
|
||||
VIR_ASYNC_JOB_BACKUP,
|
||||
+ VIR_ASYNC_JOB_HOTPATCH,
|
||||
|
||||
VIR_ASYNC_JOB_LAST
|
||||
} virDomainAsyncJob;
|
||||
diff --git a/src/qemu/qemu_domainjob.c b/src/qemu/qemu_domainjob.c
|
||||
index 245e51f14b..c9753c4f2b 100644
|
||||
--- a/src/qemu/qemu_domainjob.c
|
||||
+++ b/src/qemu/qemu_domainjob.c
|
||||
@@ -56,6 +56,7 @@ qemuDomainAsyncJobPhaseToString(virDomainAsyncJob job,
|
||||
case VIR_ASYNC_JOB_START:
|
||||
case VIR_ASYNC_JOB_NONE:
|
||||
case VIR_ASYNC_JOB_BACKUP:
|
||||
+ case VIR_ASYNC_JOB_HOTPATCH:
|
||||
G_GNUC_FALLTHROUGH;
|
||||
case VIR_ASYNC_JOB_LAST:
|
||||
break;
|
||||
@@ -82,6 +83,7 @@ qemuDomainAsyncJobPhaseFromString(virDomainAsyncJob job,
|
||||
case VIR_ASYNC_JOB_START:
|
||||
case VIR_ASYNC_JOB_NONE:
|
||||
case VIR_ASYNC_JOB_BACKUP:
|
||||
+ case VIR_ASYNC_JOB_HOTPATCH:
|
||||
G_GNUC_FALLTHROUGH;
|
||||
case VIR_ASYNC_JOB_LAST:
|
||||
break;
|
||||
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
|
||||
index 3dd82d6f12..31917ef591 100644
|
||||
--- a/src/qemu/qemu_driver.c
|
||||
+++ b/src/qemu/qemu_driver.c
|
||||
@@ -12251,6 +12251,8 @@ qemuDomainAbortJobFlags(virDomainPtr dom,
|
||||
qemuBackupJobCancelBlockjobs(vm, priv->backup, true, VIR_ASYNC_JOB_NONE);
|
||||
ret = 0;
|
||||
break;
|
||||
+ case VIR_ASYNC_JOB_HOTPATCH:
|
||||
+ break;
|
||||
|
||||
case VIR_ASYNC_JOB_LAST:
|
||||
default:
|
||||
@@ -19942,7 +19944,8 @@ qemuDomainHotpatchManage(virDomainPtr domain,
|
||||
const char *id,
|
||||
unsigned int flags)
|
||||
{
|
||||
- virDomainObjPtr vm;
|
||||
+ virDomainObj *vm;
|
||||
+ virQEMUDriver *driver = domain->conn->privateData;
|
||||
char *ret = NULL;
|
||||
size_t len;
|
||||
|
||||
@@ -19951,6 +19954,12 @@ qemuDomainHotpatchManage(virDomainPtr domain,
|
||||
if (!(vm = qemuDomainObjFromDomain(domain)))
|
||||
goto cleanup;
|
||||
|
||||
+ if (VirDomainObjBeginAsyncJob(driver, vm, QEMU_ASYNC_JOB_HOTPATCH,
|
||||
+ VIR_DOMAIN_JOB_OPERATION_HOTPATCH, 0) < 0)
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ qemuDomainObjSetAsyncJobMask(vm, QEMU_JOB_DEFAULT_MASK);
|
||||
+
|
||||
switch (action) {
|
||||
case VIR_DOMAIN_HOTPATCH_APPLY:
|
||||
ret = qemuDomainHotpatchApply(vm, patch);
|
||||
@@ -19977,6 +19986,9 @@ qemuDomainHotpatchManage(virDomainPtr domain,
|
||||
if (len > 0)
|
||||
ret[len - 1] = '\0';
|
||||
|
||||
+ endjob:
|
||||
+ qemuDomainObjEndAsyncJob(driver, vm);
|
||||
+
|
||||
cleanup:
|
||||
virDomainObjEndAPI(&vm);
|
||||
return ret;
|
||||
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
|
||||
index f9c34b72e8..73395ce3b2 100644
|
||||
--- a/src/qemu/qemu_migration.c
|
||||
+++ b/src/qemu/qemu_migration.c
|
||||
@@ -1846,6 +1846,8 @@ qemuMigrationJobName(virDomainObj *vm)
|
||||
return _("start");
|
||||
case VIR_ASYNC_JOB_BACKUP:
|
||||
return _("backup");
|
||||
+ case VIR_ASYNC_JOB_HOTPATCH:
|
||||
+ return _("hotpatch job");
|
||||
case VIR_ASYNC_JOB_NONE:
|
||||
case VIR_ASYNC_JOB_LAST:
|
||||
default:
|
||||
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
|
||||
index fc05b4b24f..318f9f6182 100644
|
||||
--- a/src/qemu/qemu_process.c
|
||||
+++ b/src/qemu/qemu_process.c
|
||||
@@ -3758,6 +3758,7 @@ qemuProcessRecoverJob(virQEMUDriver *driver,
|
||||
JOB_MASK(VIR_JOB_MODIFY)));
|
||||
break;
|
||||
|
||||
+ case VIR_ASYNC_JOB_HOTPATCH:
|
||||
case VIR_ASYNC_JOB_NONE:
|
||||
case VIR_ASYNC_JOB_LAST:
|
||||
break;
|
||||
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
|
||||
index 66f933dead..9d22e219f7 100644
|
||||
--- a/tools/virsh-domain.c
|
||||
+++ b/tools/virsh-domain.c
|
||||
@@ -6152,6 +6152,7 @@ VIR_ENUM_IMPL(virshDomainJobOperation,
|
||||
N_("Dump"),
|
||||
N_("Backup"),
|
||||
N_("Snapshot delete"),
|
||||
+ N_("Hotpatch"),
|
||||
);
|
||||
|
||||
static const char *
|
||||
--
|
||||
2.27.0
|
||||
|
||||
302
hotpatch-virsh-support-autoload-mode.patch
Normal file
302
hotpatch-virsh-support-autoload-mode.patch
Normal file
@ -0,0 +1,302 @@
|
||||
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
|
||||
|
||||
26
libvirt.spec
26
libvirt.spec
@ -262,7 +262,7 @@
|
||||
Summary: Library providing a simple virtualization API
|
||||
Name: libvirt
|
||||
Version: 9.10.0
|
||||
Release: 4
|
||||
Release: 5
|
||||
License: LGPLv2+
|
||||
URL: https://libvirt.org/
|
||||
|
||||
@ -302,6 +302,17 @@ Patch0028: qemu-Make-monitor-aware-of-CPU-clusters.patch
|
||||
Patch0029: tests-Verify-handling-of-CPU-clusters-in-QMP-data.patch
|
||||
Patch0030: docs-Improve-documentation-for-CPU-topology.patch
|
||||
Patch0031: docs-Document-CPU-clusters.patch
|
||||
Patch0032: Hotpatch-introduce-DomainHotpatchManage-API.patch
|
||||
Patch0033: hotpatch-Implement-qemuDomainHotpatchManage.patch
|
||||
Patch0034: hotpatch-introduce-hotpatch-async-job-flag.patch
|
||||
Patch0035: hotpatch-implement-hotpatch-virsh-api.patch
|
||||
Patch0036: hotpatch-check-vm-id-and-pid-before-using-hotpatch-a.patch
|
||||
Patch0037: domain-add-logs-for-virDomainHotpatchManage.patch
|
||||
Patch0038: hotpatch-virsh-support-autoload-mode.patch
|
||||
Patch0039: Fix-warnings-found-by-clang.patch
|
||||
Patch0040: Fix-off-by-one-error-in-udevListInterfacesByStatus.patch
|
||||
Patch0041: remote-check-for-negative-array-lengths-before-alloc.patch
|
||||
Patch0042: hotpatch-if-hotpatch_path-not-in-qemu.conf-the-hotpa.patch
|
||||
|
||||
Requires: libvirt-daemon = %{version}-%{release}
|
||||
Requires: libvirt-daemon-config-network = %{version}-%{release}
|
||||
@ -2595,6 +2606,19 @@ exit 0
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Wed Apr 10 2024 JiaboFeng <fengjiabo1@huawei.com> - 9.10.0-5
|
||||
- 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
|
||||
|
||||
* Tue Apr 2 2024 JiaboFeng <fengjiabo1@huawei.com> - 9.10.0-4
|
||||
- docs: Document CPU clusters
|
||||
- docs: Improve documentation for CPU topology
|
||||
|
||||
216
remote-check-for-negative-array-lengths-before-alloc.patch
Normal file
216
remote-check-for-negative-array-lengths-before-alloc.patch
Normal file
@ -0,0 +1,216 @@
|
||||
From 9085bbfb415baa258f58e79c56454a520c03d91f Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
|
||||
Date: Fri, 15 Mar 2024 10:47:50 +0000
|
||||
Subject: [PATCH] remote: check for negative array lengths before allocation
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
While the C API entry points will validate non-negative lengths
|
||||
for various parameters, the RPC server de-serialization code
|
||||
will need to allocate memory for arrays before entering the C
|
||||
API. These allocations will thus happen before the non-negative
|
||||
length check is performed.
|
||||
|
||||
Passing a negative length to the g_new0 function will usually
|
||||
result in a crash due to the negative length being treated as
|
||||
a huge positive number.
|
||||
|
||||
This was found and diagnosed by ALT Linux Team with AFLplusplus.
|
||||
|
||||
CVE-2024-2494
|
||||
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
|
||||
Found-by: Alexandr Shashkin <dutyrok@altlinux.org>
|
||||
Co-developed-by: Alexander Kuznetsov <kuznetsovam@altlinux.org>
|
||||
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
---
|
||||
src/remote/remote_daemon_dispatch.c | 65 +++++++++++++++++++++++++++++
|
||||
src/rpc/gendispatch.pl | 5 +++
|
||||
2 files changed, 70 insertions(+)
|
||||
|
||||
diff --git a/src/remote/remote_daemon_dispatch.c b/src/remote/remote_daemon_dispatch.c
|
||||
index 7daf503b51..7542caa952 100644
|
||||
--- a/src/remote/remote_daemon_dispatch.c
|
||||
+++ b/src/remote/remote_daemon_dispatch.c
|
||||
@@ -2291,6 +2291,10 @@ remoteDispatchDomainGetSchedulerParameters(virNetServer *server G_GNUC_UNUSED,
|
||||
if (!conn)
|
||||
goto cleanup;
|
||||
|
||||
+ if (args->nparams < 0) {
|
||||
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams must be non-negative"));
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
if (args->nparams > REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
|
||||
goto cleanup;
|
||||
@@ -2339,6 +2343,10 @@ remoteDispatchDomainGetSchedulerParametersFlags(virNetServer *server G_GNUC_UNUS
|
||||
if (!conn)
|
||||
goto cleanup;
|
||||
|
||||
+ if (args->nparams < 0) {
|
||||
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams must be non-negative"));
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
if (args->nparams > REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
|
||||
goto cleanup;
|
||||
@@ -2497,6 +2505,10 @@ remoteDispatchDomainBlockStatsFlags(virNetServer *server G_GNUC_UNUSED,
|
||||
goto cleanup;
|
||||
flags = args->flags;
|
||||
|
||||
+ if (args->nparams < 0) {
|
||||
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams must be non-negative"));
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
if (args->nparams > REMOTE_DOMAIN_BLOCK_STATS_PARAMETERS_MAX) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
|
||||
goto cleanup;
|
||||
@@ -2717,6 +2729,14 @@ remoteDispatchDomainGetVcpuPinInfo(virNetServer *server G_GNUC_UNUSED,
|
||||
if (!(dom = get_nonnull_domain(conn, args->dom)))
|
||||
goto cleanup;
|
||||
|
||||
+ if (args->ncpumaps < 0) {
|
||||
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("ncpumaps must be non-negative"));
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ if (args->maplen < 0) {
|
||||
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("maplen must be non-negative"));
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
if (args->ncpumaps > REMOTE_VCPUINFO_MAX) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("ncpumaps > REMOTE_VCPUINFO_MAX"));
|
||||
goto cleanup;
|
||||
@@ -2811,6 +2831,11 @@ remoteDispatchDomainGetEmulatorPinInfo(virNetServer *server G_GNUC_UNUSED,
|
||||
if (!(dom = get_nonnull_domain(conn, args->dom)))
|
||||
goto cleanup;
|
||||
|
||||
+ if (args->maplen < 0) {
|
||||
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("maplen must be non-negative"));
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
/* Allocate buffers to take the results */
|
||||
if (args->maplen > 0)
|
||||
cpumaps = g_new0(unsigned char, args->maplen);
|
||||
@@ -2858,6 +2883,14 @@ remoteDispatchDomainGetVcpus(virNetServer *server G_GNUC_UNUSED,
|
||||
if (!(dom = get_nonnull_domain(conn, args->dom)))
|
||||
goto cleanup;
|
||||
|
||||
+ if (args->maxinfo < 0) {
|
||||
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("maxinfo must be non-negative"));
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ if (args->maplen < 0) {
|
||||
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("maxinfo must be non-negative"));
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
if (args->maxinfo > REMOTE_VCPUINFO_MAX) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("maxinfo > REMOTE_VCPUINFO_MAX"));
|
||||
goto cleanup;
|
||||
@@ -3096,6 +3129,10 @@ remoteDispatchDomainGetMemoryParameters(virNetServer *server G_GNUC_UNUSED,
|
||||
|
||||
flags = args->flags;
|
||||
|
||||
+ if (args->nparams < 0) {
|
||||
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams must be non-negative"));
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
if (args->nparams > REMOTE_DOMAIN_MEMORY_PARAMETERS_MAX) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
|
||||
goto cleanup;
|
||||
@@ -3156,6 +3193,10 @@ remoteDispatchDomainGetNumaParameters(virNetServer *server G_GNUC_UNUSED,
|
||||
|
||||
flags = args->flags;
|
||||
|
||||
+ if (args->nparams < 0) {
|
||||
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams must be non-negative"));
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
if (args->nparams > REMOTE_DOMAIN_NUMA_PARAMETERS_MAX) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
|
||||
goto cleanup;
|
||||
@@ -3216,6 +3257,10 @@ remoteDispatchDomainGetBlkioParameters(virNetServer *server G_GNUC_UNUSED,
|
||||
|
||||
flags = args->flags;
|
||||
|
||||
+ if (args->nparams < 0) {
|
||||
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams must be non-negative"));
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
if (args->nparams > REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
|
||||
goto cleanup;
|
||||
@@ -3277,6 +3322,10 @@ remoteDispatchNodeGetCPUStats(virNetServer *server G_GNUC_UNUSED,
|
||||
|
||||
flags = args->flags;
|
||||
|
||||
+ if (args->nparams < 0) {
|
||||
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams must be non-negative"));
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
if (args->nparams > REMOTE_NODE_CPU_STATS_MAX) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
|
||||
goto cleanup;
|
||||
@@ -3339,6 +3388,10 @@ remoteDispatchNodeGetMemoryStats(virNetServer *server G_GNUC_UNUSED,
|
||||
|
||||
flags = args->flags;
|
||||
|
||||
+ if (args->nparams < 0) {
|
||||
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams must be non-negative"));
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
if (args->nparams > REMOTE_NODE_MEMORY_STATS_MAX) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
|
||||
goto cleanup;
|
||||
@@ -3514,6 +3567,10 @@ remoteDispatchDomainGetBlockIoTune(virNetServer *server G_GNUC_UNUSED,
|
||||
if (!conn)
|
||||
goto cleanup;
|
||||
|
||||
+ if (args->nparams < 0) {
|
||||
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams must be non-negative"));
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
if (args->nparams > REMOTE_DOMAIN_BLOCK_IO_TUNE_PARAMETERS_MAX) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
|
||||
goto cleanup;
|
||||
@@ -5079,6 +5136,10 @@ remoteDispatchDomainGetInterfaceParameters(virNetServer *server G_GNUC_UNUSED,
|
||||
|
||||
flags = args->flags;
|
||||
|
||||
+ if (args->nparams < 0) {
|
||||
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams must be non-negative"));
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
if (args->nparams > REMOTE_DOMAIN_INTERFACE_PARAMETERS_MAX) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
|
||||
goto cleanup;
|
||||
@@ -5299,6 +5360,10 @@ remoteDispatchNodeGetMemoryParameters(virNetServer *server G_GNUC_UNUSED,
|
||||
|
||||
flags = args->flags;
|
||||
|
||||
+ if (args->nparams < 0) {
|
||||
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams must be non-negative"));
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
if (args->nparams > REMOTE_NODE_MEMORY_PARAMETERS_MAX) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
|
||||
goto cleanup;
|
||||
diff --git a/src/rpc/gendispatch.pl b/src/rpc/gendispatch.pl
|
||||
index 5ce988c5ae..c5842dc796 100755
|
||||
--- a/src/rpc/gendispatch.pl
|
||||
+++ b/src/rpc/gendispatch.pl
|
||||
@@ -1070,6 +1070,11 @@ elsif ($mode eq "server") {
|
||||
print "\n";
|
||||
|
||||
if ($single_ret_as_list) {
|
||||
+ print " if (args->$single_ret_list_max_var < 0) {\n";
|
||||
+ print " virReportError(VIR_ERR_RPC,\n";
|
||||
+ print " \"%s\", _(\"max$single_ret_list_name must be non-negative\"));\n";
|
||||
+ print " goto cleanup;\n";
|
||||
+ print " }\n";
|
||||
print " if (args->$single_ret_list_max_var > $single_ret_list_max_define) {\n";
|
||||
print " virReportError(VIR_ERR_RPC,\n";
|
||||
print " \"%s\", _(\"max$single_ret_list_name > $single_ret_list_max_define\"));\n";
|
||||
--
|
||||
2.27.0
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user