[libvirt] [PATCH 1/3] client rpc: Report proper error for keepalive disconnections

Jiri Denemark jdenemar at redhat.com
Thu Sep 17 12:23:11 UTC 2015


Whenever a connection was closed due to keepalive timeout, we would log
a warning but the interrupted API would return rather useless generic
error:

    internal error: received hangup / error event on socket

Let's report a proper keepalive timeout error and make sure it is
propagated to all pending APIs. The error should be better now:

    internal error: connection closed due to keepalive timeout

Based on an old patch from Martin Kletzander.

Signed-off-by: Jiri Denemark <jdenemar at redhat.com>
---
 src/rpc/virkeepalive.c | 10 +++++-----
 src/rpc/virnetclient.c | 12 ++++++++++++
 2 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/src/rpc/virkeepalive.c b/src/rpc/virkeepalive.c
index c882313..c9faf88 100644
--- a/src/rpc/virkeepalive.c
+++ b/src/rpc/virkeepalive.c
@@ -136,11 +136,11 @@ virKeepAliveTimerInternal(virKeepAlivePtr ka,
           ka, ka->client, ka->countToDeath, timeval);
 
     if (ka->countToDeath == 0) {
-        VIR_WARN("No response from client %p after %d keepalive messages in"
-                 " %d seconds",
-                 ka->client,
-                 ka->count,
-                 timeval);
+        VIR_DEBUG("No response from client %p after %d keepalive messages "
+                  "in %d seconds",
+                  ka->client, ka->count, timeval);
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("connection closed due to keepalive timeout"));
         return true;
     } else {
         ka->countToDeath--;
diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c
index d0b96b6..6e59ea6 100644
--- a/src/rpc/virnetclient.c
+++ b/src/rpc/virnetclient.c
@@ -107,6 +107,7 @@ struct _virNetClient {
     virKeepAlivePtr keepalive;
     bool wantClose;
     int closeReason;
+    virErrorPtr error;
 
     virNetClientCloseFunc closeCb;
     void *closeOpaque;
@@ -636,10 +637,14 @@ virNetClientMarkClose(virNetClientPtr client,
                       int reason)
 {
     VIR_DEBUG("client=%p, reason=%d", client, reason);
+
     if (client->sock)
         virNetSocketRemoveIOCallback(client->sock);
+
     /* Don't override reason that's already set. */
     if (!client->wantClose) {
+        if (!client->error)
+            client->error = virSaveLastError();
         client->wantClose = true;
         client->closeReason = reason;
     }
@@ -670,6 +675,9 @@ virNetClientCloseLocked(virNetClientPtr client)
     client->keepalive = NULL;
     client->wantClose = false;
 
+    virFreeError(client->error);
+    client->error = NULL;
+
     if (ka || client->closeCb) {
         virNetClientCloseFunc closeCb = client->closeCb;
         void *closeOpaque = client->closeOpaque;
@@ -1602,6 +1610,10 @@ static int virNetClientIOEventLoop(virNetClientPtr client,
     }
 
  error:
+    if (client->error) {
+        VIR_DEBUG("error on socket: %s", client->error->message);
+        virSetError(client->error);
+    }
     virNetClientCallRemove(&client->waitDispatch, thiscall);
     virNetClientIOEventLoopPassTheBuck(client, thiscall);
     return -1;
-- 
2.5.2




More information about the libvir-list mailing list