Fix sending of reply to final RPC message

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
This commit is contained in:
Daniel P. Berrange 2011-07-08 12:54:29 +01:00
parent afe8839f01
commit 3cfdc57b85
4 changed files with 20 additions and 8 deletions

View File

@ -483,11 +483,11 @@ cleanup:
static int static int
remoteDispatchClose(virNetServerPtr server ATTRIBUTE_UNUSED, remoteDispatchClose(virNetServerPtr server ATTRIBUTE_UNUSED,
virNetServerClientPtr client, virNetServerClientPtr client ATTRIBUTE_UNUSED,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED, virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED) virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED)
{ {
virNetServerClientClose(client); virNetServerClientDelayedClose(client);
return 0; return 0;
} }

View File

@ -338,7 +338,7 @@ int daemonFreeClientStream(virNetServerClientPtr client,
memset(msg, 0, sizeof(*msg)); memset(msg, 0, sizeof(*msg));
msg->header.type = VIR_NET_REPLY; msg->header.type = VIR_NET_REPLY;
if (virNetServerClientSendMessage(client, msg) < 0) { if (virNetServerClientSendMessage(client, msg) < 0) {
virNetServerClientMarkClose(client); virNetServerClientImmediateClose(client);
virNetMessageFree(msg); virNetMessageFree(msg);
ret = -1; ret = -1;
} }
@ -608,7 +608,7 @@ daemonStreamHandleWrite(virNetServerClientPtr client,
virNetMessageQueueServe(&stream->rx); virNetMessageQueueServe(&stream->rx);
if (ret < 0) { if (ret < 0) {
virNetMessageFree(msg); virNetMessageFree(msg);
virNetServerClientMarkClose(client); virNetServerClientImmediateClose(client);
return -1; return -1;
} }
@ -623,7 +623,7 @@ daemonStreamHandleWrite(virNetServerClientPtr client,
msg->header.type = VIR_NET_REPLY; msg->header.type = VIR_NET_REPLY;
if (virNetServerClientSendMessage(client, msg) < 0) { if (virNetServerClientSendMessage(client, msg) < 0) {
virNetMessageFree(msg); virNetMessageFree(msg);
virNetServerClientMarkClose(client); virNetServerClientImmediateClose(client);
return -1; return -1;
} }
} }

View File

@ -61,6 +61,7 @@ struct _virNetServerClient
{ {
int refs; int refs;
bool wantClose; bool wantClose;
bool delayedClose;
virMutex lock; virMutex lock;
virNetSocketPtr sock; virNetSocketPtr sock;
int auth; int auth;
@ -587,7 +588,14 @@ bool virNetServerClientIsClosed(virNetServerClientPtr client)
return closed; return closed;
} }
void virNetServerClientMarkClose(virNetServerClientPtr client) void virNetServerClientDelayedClose(virNetServerClientPtr client)
{
virNetServerClientLock(client);
client->delayedClose = true;
virNetServerClientUnlock(client);
}
void virNetServerClientImmediateClose(virNetServerClientPtr client)
{ {
virNetServerClientLock(client); virNetServerClientLock(client);
client->wantClose = true; client->wantClose = true;
@ -852,6 +860,9 @@ virNetServerClientDispatchWrite(virNetServerClientPtr client)
virNetMessageFree(msg); virNetMessageFree(msg);
virNetServerClientUpdateEvent(client); virNetServerClientUpdateEvent(client);
if (client->delayedClose)
client->wantClose = true;
} }
} }
} }

View File

@ -86,9 +86,10 @@ void virNetServerClientSetDispatcher(virNetServerClientPtr client,
virNetServerClientDispatchFunc func, virNetServerClientDispatchFunc func,
void *opaque); void *opaque);
void virNetServerClientClose(virNetServerClientPtr client); void virNetServerClientClose(virNetServerClientPtr client);
bool virNetServerClientIsClosed(virNetServerClientPtr client); bool virNetServerClientIsClosed(virNetServerClientPtr client);
void virNetServerClientMarkClose(virNetServerClientPtr client);
void virNetServerClientDelayedClose(virNetServerClientPtr client);
void virNetServerClientImmediateClose(virNetServerClientPtr client);
bool virNetServerClientWantClose(virNetServerClientPtr client); bool virNetServerClientWantClose(virNetServerClientPtr client);
int virNetServerClientInit(virNetServerClientPtr client); int virNetServerClientInit(virNetServerClientPtr client);