From: "Daniel P. Berrange" <berrange(a)redhat.com>
The dispatch for the CLOSE RPC call was invoking the method
virNetServerClientClose(). This caused the client connection
to be immediately terminated. This meant the reply to the
final RPC message was never sent. Prior to the RPC rewrite
we merely flagged the connection for closing, and actually
closed it when the next RPC call dispatch had completed.
* daemon/remote.c: Flag connection for a delayed close
* daemon/stream.c: Update to use new API for closing
failed connection
* src/rpc/virnetserverclient.c, src/rpc/virnetserverclient.h:
Add support for a delayed connection close. Rename the
virNetServerClientMarkClose method to virNetServerClientImmediateClose
to clarify its semantics
---
daemon/remote.c | 4 ++--
daemon/stream.c | 6 +++---
src/rpc/virnetserverclient.c | 13 ++++++++++++-
src/rpc/virnetserverclient.h | 5 +++--
4 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/daemon/remote.c b/daemon/remote.c
index 2889908..a2e79ef 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -483,11 +483,11 @@ cleanup:
static int
remoteDispatchClose(virNetServerPtr server ATTRIBUTE_UNUSED,
- virNetServerClientPtr client,
+ virNetServerClientPtr client ATTRIBUTE_UNUSED,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED)
{
- virNetServerClientClose(client);
+ virNetServerClientDelayedClose(client);
return 0;
}
diff --git a/daemon/stream.c b/daemon/stream.c
index 28f6c32..4a8f1ee 100644
--- a/daemon/stream.c
+++ b/daemon/stream.c
@@ -338,7 +338,7 @@ int daemonFreeClientStream(virNetServerClientPtr client,
memset(msg, 0, sizeof(*msg));
msg->header.type = VIR_NET_REPLY;
if (virNetServerClientSendMessage(client, msg) < 0) {
- virNetServerClientMarkClose(client);
+ virNetServerClientImmediateClose(client);
virNetMessageFree(msg);
ret = -1;
}
@@ -608,7 +608,7 @@ daemonStreamHandleWrite(virNetServerClientPtr client,
virNetMessageQueueServe(&stream->rx);
if (ret < 0) {
virNetMessageFree(msg);
- virNetServerClientMarkClose(client);
+ virNetServerClientImmediateClose(client);
return -1;
}
@@ -623,7 +623,7 @@ daemonStreamHandleWrite(virNetServerClientPtr client,
msg->header.type = VIR_NET_REPLY;
if (virNetServerClientSendMessage(client, msg) < 0) {
virNetMessageFree(msg);
- virNetServerClientMarkClose(client);
+ virNetServerClientImmediateClose(client);
return -1;
}
}
diff --git a/src/rpc/virnetserverclient.c b/src/rpc/virnetserverclient.c
index 6aeb3a4..742c3a4 100644
--- a/src/rpc/virnetserverclient.c
+++ b/src/rpc/virnetserverclient.c
@@ -61,6 +61,7 @@ struct _virNetServerClient
{
int refs;
bool wantClose;
+ bool delayedClose;
virMutex lock;
virNetSocketPtr sock;
int auth;
@@ -587,7 +588,14 @@ bool virNetServerClientIsClosed(virNetServerClientPtr client)
return closed;
}
-void virNetServerClientMarkClose(virNetServerClientPtr client)
+void virNetServerClientDelayedClose(virNetServerClientPtr client)
+{
+ virNetServerClientLock(client);
+ client->delayedClose = true;
+ virNetServerClientUnlock(client);
+}
+
+void virNetServerClientImmediateClose(virNetServerClientPtr client)
{
virNetServerClientLock(client);
client->wantClose = true;
@@ -852,6 +860,9 @@ virNetServerClientDispatchWrite(virNetServerClientPtr client)
virNetMessageFree(msg);
virNetServerClientUpdateEvent(client);
+
+ if (client->delayedClose)
+ client->wantClose = true;
}
}
}
diff --git a/src/rpc/virnetserverclient.h b/src/rpc/virnetserverclient.h
index 66510c3..3d2e1fb 100644
--- a/src/rpc/virnetserverclient.h
+++ b/src/rpc/virnetserverclient.h
@@ -86,9 +86,10 @@ void virNetServerClientSetDispatcher(virNetServerClientPtr client,
virNetServerClientDispatchFunc func,
void *opaque);
void virNetServerClientClose(virNetServerClientPtr client);
-
bool virNetServerClientIsClosed(virNetServerClientPtr client);
-void virNetServerClientMarkClose(virNetServerClientPtr client);
+
+void virNetServerClientDelayedClose(virNetServerClientPtr client);
+void virNetServerClientImmediateClose(virNetServerClientPtr client);
bool virNetServerClientWantClose(virNetServerClientPtr client);
int virNetServerClientInit(virNetServerClientPtr client);
--
1.7.6