提交 c91776d5 编写于 作者: J Jiri Denemark

client rpc: Report proper error for keepalive disconnections

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: NJiri Denemark <jdenemar@redhat.com>
上级 363995b0
......@@ -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--;
......
......@@ -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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册