【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
Show replies by date
Sorry ,This is our inner patch. Sorry for disturb every one
-----邮件原件-----
发件人: Caoxinhua
发送时间: 2017年10月28日 9:24
收件人: libvir-list(a)redhat.com; jferlan(a)redhat.com; mkletzan(a)redhat.com; berrange(a)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