daemon/remote.c | 52 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 20 deletions(-)
【DTS/AR】:DTS2017102200357
【description】:当客户端注册libvirt事件后,将客户端进程Kill,libvirtd服务端会有内存泄露。
Change-Id: I7eeffb4f1ba46038cd41fd26e6725ad2943229a8
---
daemon/remote.c | 52 ++++++++++++++++++++++++++++++++--------------------
1 file changed, 32 insertions(+), 20 deletions(-)
diff --git a/daemon/remote.c b/daemon/remote.c
index f67370f..4b8de85 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -1727,25 +1727,14 @@ void remoteRelayConnectionClosedEvent(virConnectPtr conn ATTRIBUTE_UNUSED, int r
VIR_WARN("unexpected %s event deregister failure", name); \
} \
VIR_FREE(eventCallbacks); \
+ neventCallbacks = 0; \
} while (0);
-/*
- * You must hold lock for at least the client
- * We don't free stuff here, merely disconnect the client's
- * network socket & resources.
- * We keep the libvirt connection open until any async
- * jobs have finished, then clean it up elsewhere
- */
-void remoteClientFreeFunc(void *data)
+static void
+remoteFreePrivCallbacks(void *data)
{
struct daemonClientPrivate *priv = data;
-
- /* Deregister event delivery callback */
- if (priv->conn) {
- virIdentityPtr sysident = virIdentityGetSystem();
-
- virIdentitySetCurrent(sysident);
-
+ if (priv && priv->conn) {
DEREG_CB(priv->conn, priv->domainEventCallbacks,
priv->ndomainEventCallbacks,
virConnectDomainEventDeregisterAny, "domain");
@@ -1764,6 +1753,27 @@ void remoteClientFreeFunc(void *data)
DEREG_CB(priv->conn, priv->qemuEventCallbacks,
priv->nqemuEventCallbacks,
virConnectDomainQemuMonitorEventDeregister, "qemu monitor");
+ }
+}
+#undef DEREG_CB
+
+/*
+ * You must hold lock for at least the client
+ * We don't free stuff here, merely disconnect the client's
+ * network socket & resources.
+ * We keep the libvirt connection open until any async
+ * jobs have finished, then clean it up elsewhere
+ */
+void remoteClientFreeFunc(void *data)
+{
+ struct daemonClientPrivate *priv = data;
+
+ /* Deregister event delivery callback */
+ if (priv) {
+ virIdentityPtr sysident = virIdentityGetSystem();
+
+ virIdentitySetCurrent(sysident);
+ remoteFreePrivCallbacks(priv);
if (priv->closeRegistered) {
if (virConnectUnregisterCloseCallback(priv->conn,
@@ -1775,19 +1785,21 @@ void remoteClientFreeFunc(void *data)
virIdentitySetCurrent(NULL);
virObjectUnref(sysident);
- }
- VIR_FREE(priv->hmacSalt);
- VIR_FREE(priv);
+ VIR_FREE(priv->hmacSalt);
+ VIR_FREE(priv);
+ }
}
-#undef DEREG_CB
static void remoteClientCloseFunc(virNetServerClientPtr client)
{
struct daemonClientPrivate *priv = virNetServerClientGetPrivateData(client);
- daemonRemoveAllClientStreams(priv->streams);
+ if (priv) {
+ daemonRemoveAllClientStreams(priv->streams);
+ remoteFreePrivCallbacks(priv);
+ }
}
--
2.8.3
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Sorry ,This is our inner patch. Sorry for disturb every one -----邮件原件----- 发件人: Caoxinhua 发送时间: 2017年10月28日 9:24 收件人: libvir-list@redhat.com; jferlan@redhat.com; mkletzan@redhat.com; berrange@redhat.com 抄送: Huangweidong (C); Yanqiangjun; weifuqiang; Wangjing (King, Euler); Caoxinhua 主题: [PATCH] fix libvirtd memory leak when client was killed by user at eventRegister sense 【DTS/AR】:DTS2017102200357 【description】:当客户端注册libvirt事件后,将客户端进程Kill,libvirtd服务端会有内存泄露。 Change-Id: I7eeffb4f1ba46038cd41fd26e6725ad2943229a8 --- daemon/remote.c | 52 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index f67370f..4b8de85 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -1727,25 +1727,14 @@ void remoteRelayConnectionClosedEvent(virConnectPtr conn ATTRIBUTE_UNUSED, int r VIR_WARN("unexpected %s event deregister failure", name); \ } \ VIR_FREE(eventCallbacks); \ + neventCallbacks = 0; \ } while (0); -/* - * You must hold lock for at least the client - * We don't free stuff here, merely disconnect the client's - * network socket & resources. - * We keep the libvirt connection open until any async - * jobs have finished, then clean it up elsewhere - */ -void remoteClientFreeFunc(void *data) +static void +remoteFreePrivCallbacks(void *data) { struct daemonClientPrivate *priv = data; - - /* Deregister event delivery callback */ - if (priv->conn) { - virIdentityPtr sysident = virIdentityGetSystem(); - - virIdentitySetCurrent(sysident); - + if (priv && priv->conn) { DEREG_CB(priv->conn, priv->domainEventCallbacks, priv->ndomainEventCallbacks, virConnectDomainEventDeregisterAny, "domain"); @@ -1764,6 +1753,27 @@ void remoteClientFreeFunc(void *data) DEREG_CB(priv->conn, priv->qemuEventCallbacks, priv->nqemuEventCallbacks, virConnectDomainQemuMonitorEventDeregister, "qemu monitor"); + } +} +#undef DEREG_CB + +/* + * You must hold lock for at least the client + * We don't free stuff here, merely disconnect the client's + * network socket & resources. + * We keep the libvirt connection open until any async + * jobs have finished, then clean it up elsewhere */ void +remoteClientFreeFunc(void *data) { + struct daemonClientPrivate *priv = data; + + /* Deregister event delivery callback */ + if (priv) { + virIdentityPtr sysident = virIdentityGetSystem(); + + virIdentitySetCurrent(sysident); + remoteFreePrivCallbacks(priv); if (priv->closeRegistered) { if (virConnectUnregisterCloseCallback(priv->conn, @@ -1775,19 +1785,21 @@ void remoteClientFreeFunc(void *data) virIdentitySetCurrent(NULL); virObjectUnref(sysident); - } - VIR_FREE(priv->hmacSalt); - VIR_FREE(priv); + VIR_FREE(priv->hmacSalt); + VIR_FREE(priv); + } } -#undef DEREG_CB static void remoteClientCloseFunc(virNetServerClientPtr client) { struct daemonClientPrivate *priv = virNetServerClientGetPrivateData(client); - daemonRemoveAllClientStreams(priv->streams); + if (priv) { + daemonRemoveAllClientStreams(priv->streams); + remoteFreePrivCallbacks(priv); + } } -- 2.8.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
© 2016 - 2025 Red Hat, Inc.