[libvirt] [PATCH v3 2/2] remote: free client all event callbacks at remoteClientCloseFunc
John Ferlan
jferlan at redhat.com
Sun Nov 12 14:45:56 UTC 2017
On 11/11/2017 03:30 AM, xinhua.Cao wrote:
> base on commit fe8f1c8b8650c8ab5e7d27338f4538582651bd14, we solve
> libvirt coredump problem, but it introduce a memory leak sense:
>
> 1. one client register a domain event such as reboot event
> 2. and client was terminated unexpectly, such as kill -9,
> then this client object will not free at libvirtd service program.
>
> remoteDispatchConnectDomainEventCallbackRegisterAny reference the client,
> but when client was terminated before it call deRegisterAny,the reference
> of client will not reduced to zero. so the memory leak take place.
> this patch will deRegister all event callbacks when client was close.
> ---
> daemon/remote.c | 62 +++++++++++++++++++++++++++++++++------------------------
> 1 file changed, 36 insertions(+), 26 deletions(-)
>
See my comments from the v2 series....
John
> diff --git a/daemon/remote.c b/daemon/remote.c
> index cbcb6e8..2073534 100644
> --- a/daemon/remote.c
> +++ b/daemon/remote.c
> @@ -1689,6 +1689,37 @@ void remoteRelayConnectionClosedEvent(virConnectPtr conn ATTRIBUTE_UNUSED, int r
> neventCallbacks = 0; \
> } while (0);
>
> +static void
> +remoteClientFreePrivateCallbacks(struct daemonClientPrivate *priv)
> +{
> + DEREG_CB(priv->conn, priv->domainEventCallbacks,
> + priv->ndomainEventCallbacks,
> + virConnectDomainEventDeregisterAny, "domain");
> + DEREG_CB(priv->conn, priv->networkEventCallbacks,
> + priv->nnetworkEventCallbacks,
> + virConnectNetworkEventDeregisterAny, "network");
> + DEREG_CB(priv->conn, priv->storageEventCallbacks,
> + priv->nstorageEventCallbacks,
> + virConnectStoragePoolEventDeregisterAny, "storage");
> + DEREG_CB(priv->conn, priv->nodeDeviceEventCallbacks,
> + priv->nnodeDeviceEventCallbacks,
> + virConnectNodeDeviceEventDeregisterAny, "node device");
> + DEREG_CB(priv->conn, priv->secretEventCallbacks,
> + priv->nsecretEventCallbacks,
> + virConnectSecretEventDeregisterAny, "secret");
> + DEREG_CB(priv->conn, priv->qemuEventCallbacks,
> + priv->nqemuEventCallbacks,
> + virConnectDomainQemuMonitorEventDeregister, "qemu monitor");
> +
> + if (priv->closeRegistered) {
> + if (virConnectUnregisterCloseCallback(priv->conn,
> + remoteRelayConnectionClosedEvent) < 0)
> + VIR_WARN("unexpected close callback event deregister failure");
> + }
> +}
> +#undef DEREG_CB
> +
> +
> /*
> * You must hold lock for at least the client
> * We don't free stuff here, merely disconnect the client's
> @@ -1706,40 +1737,17 @@ void remoteClientFreeFunc(void *data)
>
> virIdentitySetCurrent(sysident);
>
> - DEREG_CB(priv->conn, priv->domainEventCallbacks,
> - priv->ndomainEventCallbacks,
> - virConnectDomainEventDeregisterAny, "domain");
> - DEREG_CB(priv->conn, priv->networkEventCallbacks,
> - priv->nnetworkEventCallbacks,
> - virConnectNetworkEventDeregisterAny, "network");
> - DEREG_CB(priv->conn, priv->storageEventCallbacks,
> - priv->nstorageEventCallbacks,
> - virConnectStoragePoolEventDeregisterAny, "storage");
> - DEREG_CB(priv->conn, priv->nodeDeviceEventCallbacks,
> - priv->nnodeDeviceEventCallbacks,
> - virConnectNodeDeviceEventDeregisterAny, "node device");
> - DEREG_CB(priv->conn, priv->secretEventCallbacks,
> - priv->nsecretEventCallbacks,
> - virConnectSecretEventDeregisterAny, "secret");
> - DEREG_CB(priv->conn, priv->qemuEventCallbacks,
> - priv->nqemuEventCallbacks,
> - virConnectDomainQemuMonitorEventDeregister, "qemu monitor");
> -
> - if (priv->closeRegistered) {
> - if (virConnectUnregisterCloseCallback(priv->conn,
> - remoteRelayConnectionClosedEvent) < 0)
> - VIR_WARN("unexpected close callback event deregister failure");
> - }
> + remoteClientFreePrivateCallbacks(priv);
>
> virConnectClose(priv->conn);
>
> virIdentitySetCurrent(NULL);
> virObjectUnref(sysident);
> - }
>
> + }
> VIR_FREE(priv);
> +
> }
> -#undef DEREG_CB
>
>
> static void remoteClientCloseFunc(virNetServerClientPtr client)
> @@ -1747,6 +1755,8 @@ static void remoteClientCloseFunc(virNetServerClientPtr client)
> struct daemonClientPrivate *priv = virNetServerClientGetPrivateData(client);
>
> daemonRemoveAllClientStreams(priv->streams);
> + if (priv->conn)
> + remoteClientFreePrivateCallbacks(priv);
> }
>
>
>
More information about the libvir-list
mailing list