aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel P. Berrange <berrange@redhat.com>2011-06-30 12:28:10 +0100
committerDaniel P. Berrange <berrange@redhat.com>2011-06-30 18:04:01 +0100
commitdf65adf13620db656baa3aa2a56819e6e09c1014 (patch)
treee73426bb0ffc1b375fbd6bc59f433c606188f5c5
parentEnsure RPC message is cleared before being reused (diff)
downloadlibvirt-df65adf13620db656baa3aa2a56819e6e09c1014.tar.gz
libvirt-df65adf13620db656baa3aa2a56819e6e09c1014.tar.bz2
libvirt-df65adf13620db656baa3aa2a56819e6e09c1014.zip
Fix release of filtered stream messages
The stream code was reusing a stream message object before it was removed from the linked list of filtered messages. This caused any later queued messages to be completely lost. * daemon/stream.c: Delay reuse of stream message until after it is removed from the queue
-rw-r--r--daemon/stream.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/daemon/stream.c b/daemon/stream.c
index e4fcf90a1..685cee2e0 100644
--- a/daemon/stream.c
+++ b/daemon/stream.c
@@ -456,10 +456,6 @@ daemonStreamHandleWriteData(virNetServerClientPtr client,
/* Partial write, so indicate we have more todo later */
if (msg->bufferOffset < msg->bufferLength)
return 1;
-
- /* A dummy 'send' just to free up 'msg' object */
- memset(msg, 0, sizeof(*msg));
- return virNetServerClientSendMessage(client, msg);
} else if (ret == -2) {
/* Blocking, so indicate we have more todo later */
return 1;
@@ -603,6 +599,22 @@ daemonStreamHandleWrite(virNetServerClientPtr client,
virNetServerClientMarkClose(client);
return -1;
}
+
+ /* 'CONTINUE' messages don't send a reply (unless error
+ * occurred), so to release the 'msg' object we need to
+ * send a fake zero-length reply. Nothing actually gets
+ * onto the wire, but this causes the client to reset
+ * its active request count / throttling
+ */
+ if (msg->header.status == VIR_NET_CONTINUE) {
+ memset(msg, 0, sizeof(*msg));
+ msg->header.type = VIR_NET_REPLY;
+ if (virNetServerClientSendMessage(client, msg) < 0) {
+ virNetMessageFree(msg);
+ virNetServerClientMarkClose(client);
+ return -1;
+ }
+ }
}
return 0;