In addition to keepalive responses, we also need to send keepalive
requests from client IO loop to properly detect dead connection in case
a libvirt API call is called from the main loop, which prevents any
timers to be called.
---
src/rpc/virnetclient.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c
index 25bafea..033fda6 100644
--- a/src/rpc/virnetclient.c
+++ b/src/rpc/virnetclient.c
@@ -1284,6 +1284,7 @@ static int virNetClientIOEventLoop(virNetClientPtr client,
char ignore;
sigset_t oldmask, blockedsigs;
int timeout = -1;
+ virNetMessagePtr msg = NULL;
/* If we have existing SASL decoded data we don't want to sleep in
* the poll(), just check if any other FDs are also ready.
@@ -1297,6 +1298,10 @@ static int virNetClientIOEventLoop(virNetClientPtr client,
if (thiscall->nonBlock)
timeout = 0;
+ /* Limit timeout so that we can send keepalive request in time */
+ if (timeout == -1)
+ timeout = virKeepAliveTimeout(client->keepalive);
+
fds[0].events = fds[0].revents = 0;
fds[1].events = fds[1].revents = 0;
@@ -1342,6 +1347,13 @@ static int virNetClientIOEventLoop(virNetClientPtr client,
virNetClientLock(client);
+ if (virKeepAliveTrigger(client->keepalive, &msg)) {
+ client->wantClose = true;
+ } else if (msg && virNetClientQueueNonBlocking(client, msg) < 0) {
+ VIR_WARN("Could not queue keepalive request");
+ virNetMessageFree(msg);
+ }
+
/* If we have existing SASL decoded data, pretend
* the socket became readable so we consume it
*/
--
1.7.10.2