]> xenbits.xensource.com Git - libvirt.git/commitdiff
Fix sending of reply to final RPC message
authorDaniel P. Berrange <berrange@redhat.com>
Fri, 8 Jul 2011 11:54:29 +0000 (12:54 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Fri, 8 Jul 2011 15:19:57 +0000 (16:19 +0100)
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
daemon/stream.c
src/rpc/virnetserverclient.c
src/rpc/virnetserverclient.h

index 288990855ef48323d7919fa9a82a0ebd6299de82..a2e79efa99dd3fc13dc5bc774d37d0fc550e58f0 100644 (file)
@@ -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;
 }
 
index 28f6c326d7b35c718974647f4d865764e75ef0ae..4a8f1eed91276c74fcee8f2669f6532f3212ab26 100644 (file)
@@ -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;
             }
         }
index 6aeb3a4d4ac004492aa00fde86466bceaecf3577..742c3a4bbabdd7f4c77b6cfdf5deb40226cc17f0 100644 (file)
@@ -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;
          }
     }
 }
index 66510c31c5b9ad1a710d0284f9a22143451e2699..3d2e1fba4520b0626dd138791172d8da3321c69e 100644 (file)
@@ -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);