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(a)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