Sorry ,This is our inner patch. Sorry for disturb every one -----邮件原件----- 发件人: Caoxinhua 发送时间: 2017年10月28日 9:24 收件人: libvir-list@xxxxxxxxxx; jferlan@xxxxxxxxxx; mkletzan@xxxxxxxxxx; berrange@xxxxxxxxxx 抄送: 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@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list