From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> Allow detection of socket close in virNetClient via an callback function, triggered on any condition that causes the socket to be close. Signed-off-by: Daniel P. Berrange <berrange@xxxxxxxxxx> --- src/libvirt_private.syms | 2 +- src/rpc/virnetclient.c | 35 +++++++++++++++++++++++++++++++---- src/rpc/virnetclient.h | 9 +++++++++ 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 734c881..83ca99f 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1319,7 +1319,7 @@ virNetClientSendNoReply; virNetClientSendNonBlock; virNetClientSendWithReply; virNetClientSendWithReplyStream; -virNetClientSetEOFNotify; +virNetClientSetCloseCallback; virNetClientSetSASLSession; virNetClientSetTLSSession; diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c index a258746..aba58ec 100644 --- a/src/rpc/virnetclient.c +++ b/src/rpc/virnetclient.c @@ -102,6 +102,10 @@ struct _virNetClient { virKeepAlivePtr keepalive; bool wantClose; int closeReason; + + virNetClientCloseFunc closeCb; + void *closeOpaque; + virFreeCallback closeFf; }; @@ -125,6 +129,19 @@ static void virNetClientUnlock(virNetClientPtr client) } +void virNetClientSetCloseCallback(virNetClientPtr client, + virNetClientCloseFunc cb, + void *opaque, + virFreeCallback ff) +{ + virNetClientLock(client); + client->closeCb = cb; + client->closeOpaque = opaque; + client->closeFf = ff; + virNetClientUnlock(client); +} + + static void virNetClientIncomingEvent(virNetSocketPtr sock, int events, void *opaque); @@ -463,6 +480,9 @@ void virNetClientFree(virNetClientPtr client) return; } + if (client->closeFf) + client->closeFf(client->closeOpaque); + for (i = 0 ; i < client->nprograms ; i++) virNetClientProgramFree(client->programs[i]); VIR_FREE(client->programs); @@ -519,12 +539,19 @@ virNetClientCloseLocked(virNetClientPtr client) client->keepalive = NULL; client->wantClose = false; - if (ka) { + if (ka || client->closeCb) { + virNetClientCloseFunc closeCb = client->closeCb; + void *closeOpaque = client->closeOpaque; + int closeReason = client->closeReason; client->refs++; virNetClientUnlock(client); - virKeepAliveStop(ka); - virKeepAliveFree(ka); + if (ka) { + virKeepAliveStop(ka); + virKeepAliveFree(ka); + } + if (closeCb) + closeCb(client, closeReason, closeOpaque); virNetClientLock(client); client->refs--; @@ -534,7 +561,7 @@ virNetClientCloseLocked(virNetClientPtr client) static void virNetClientCloseInternal(virNetClientPtr client, int reason) { - VIR_DEBUG("client=%p", client); + VIR_DEBUG("client=%p wantclose=%d", client, client ? client->wantClose : false); if (!client) return; diff --git a/src/rpc/virnetclient.h b/src/rpc/virnetclient.h index 3b8cbb2..c939475 100644 --- a/src/rpc/virnetclient.h +++ b/src/rpc/virnetclient.h @@ -51,6 +51,15 @@ virNetClientPtr virNetClientNewSSH(const char *nodename, virNetClientPtr virNetClientNewExternal(const char **cmdargv); +typedef void (*virNetClientCloseFunc)(virNetClientPtr client, + int reason, + void *opaque); + +void virNetClientSetCloseCallback(virNetClientPtr client, + virNetClientCloseFunc cb, + void *opaque, + virFreeCallback ff); + void virNetClientRef(virNetClientPtr client); int virNetClientGetFD(virNetClientPtr client); -- 1.7.10.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list