]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
Add an explicit virNetClientClose method
authorDaniel P. Berrange <berrange@redhat.com>
Tue, 19 Jul 2011 13:13:32 +0000 (14:13 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Tue, 19 Jul 2011 15:20:34 +0000 (11:20 -0400)
Since the I/O callback registered against virNetSocket will
hold a reference on the virNetClient, we can't rely on the
virNetClientFree to be able to close the network connection.
The last reference will only go away when the event callback
fires (likely due to EOF from the server).

This is sub-optimal and can potentially cause a leak of the
virNetClient object if the server were to not explicitly
close the socket itself

* src/remote/remote_driver.c: Explicitly close the client
  object when disconnecting
* src/rpc/virnetclient.c, src/rpc/virnetclient.h: Add a
  virNetClientClose method

src/remote/remote_driver.c
src/rpc/virnetclient.c
src/rpc/virnetclient.h

index c2f8bbde06d6d4268e719e469ad911016d8dc569..6bae353c75c5041888cf2859e92916605f5f0875 100644 (file)
@@ -684,6 +684,7 @@ doRemoteOpen (virConnectPtr conn,
         free_qparam_set (vars);
 
  failed:
+    virNetClientClose(priv->client);
     virNetClientFree(priv->client);
     priv->client = NULL;
 
@@ -834,6 +835,7 @@ doRemoteClose (virConnectPtr conn, struct private_data *priv)
 
     virNetTLSContextFree(priv->tls);
     priv->tls = NULL;
+    virNetClientClose(priv->client);
     virNetClientFree(priv->client);
     priv->client = NULL;
     virNetClientProgramFree(priv->remoteProgram);
index 27542a57ac3808f2efe86432ea30176a11054e93..dfc4ed94948128edfde9f335e6600c752ee1cab5 100644 (file)
@@ -255,7 +255,8 @@ void virNetClientFree(virNetClientPtr client)
 
     VIR_FREE(client->hostname);
 
-    virNetSocketRemoveIOCallback(client->sock);
+    if (client->sock)
+        virNetSocketRemoveIOCallback(client->sock);
     virNetSocketFree(client->sock);
     virNetTLSSessionFree(client->tls);
 #if HAVE_SASL
@@ -268,6 +269,22 @@ void virNetClientFree(virNetClientPtr client)
 }
 
 
+void virNetClientClose(virNetClientPtr client)
+{
+    virNetClientLock(client);
+    virNetSocketRemoveIOCallback(client->sock);
+    virNetSocketFree(client->sock);
+    client->sock = NULL;
+    virNetTLSSessionFree(client->tls);
+    client->tls = NULL;
+#if HAVE_SASL
+    virNetSASLSessionFree(client->sasl);
+    client->sasl = NULL;
+#endif
+    virNetClientUnlock(client);
+}
+
+
 #if HAVE_SASL
 void virNetClientSetSASLSession(virNetClientPtr client,
                                 virNetSASLSessionPtr sasl)
@@ -1118,6 +1135,9 @@ void virNetClientIncomingEvent(virNetSocketPtr sock,
 
     virNetClientLock(client);
 
+    if (!client->sock)
+        goto done;
+
     /* This should be impossible, but it doesn't hurt to check */
     if (client->waitDispatch)
         goto done;
index 6acdf508a057a8e1e63135438919a17e63342e68..a0983bc734b195e1c9f2762da8f2704570d5cbc6 100644 (file)
@@ -81,5 +81,6 @@ const char *virNetClientRemoteAddrString(virNetClientPtr client);
 int virNetClientGetTLSKeySize(virNetClientPtr client);
 
 void virNetClientFree(virNetClientPtr client);
+void virNetClientClose(virNetClientPtr client);
 
 #endif /* __VIR_NET_CLIENT_H__ */