qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [RFC PATCH 03/13] nbd: do not leak nbd_trip coroutines when


From: Paolo Bonzini
Subject: [Qemu-devel] [RFC PATCH 03/13] nbd: do not leak nbd_trip coroutines when a connection is torn down
Date: Mon, 27 Aug 2012 17:00:16 +0200

Because nbd_client_close removes the I/O handlers for the client
socket, there is no way that any suspended coroutines are restarted.
This will be a problem with the QEMU embedded NBD server, because
we will have a QMP command to forcibly close all connections with
the clients.

Instead, we can exploit the reference counting of NBDClients; shutdown
the client socket, which will make it readable and writeable.  The
coroutines then will fail and exit cleanly.  The last refcount finally
triggers the closure of the client.

Signed-off-by: Paolo Bonzini <address@hidden>
---
 nbd.c | 18 +++++++++++-------
 nbd.h |  3 +++
 2 file modificati, 14 inserzioni(+), 7 rimozioni(-)

diff --git a/nbd.c b/nbd.c
index c1edbeb..cb4e8fe 100644
--- a/nbd.c
+++ b/nbd.c
@@ -657,18 +657,22 @@ static void nbd_client_get(NBDClient *client)
 static void nbd_client_put(NBDClient *client)
 {
     if (--client->refcount == 0) {
+        qemu_set_fd_handler2(client->sock, NULL, NULL, NULL, NULL);
+        close(client->sock);
+        client->sock = -1;
+        if (client->close) {
+            client->close(client);
+        }
         g_free(client);
     }
 }
 
-static void nbd_client_close(NBDClient *client)
+void nbd_client_close(NBDClient *client)
 {
-    qemu_set_fd_handler2(client->sock, NULL, NULL, NULL, NULL);
-    close(client->sock);
-    client->sock = -1;
-    if (client->close) {
-        client->close(client);
-    }
+    /* Force requests to finish.  They will drop their own references,
+     * then we'll close the socket and free the NBDClient.
+     */
+    shutdown(client->sock, 2);
     nbd_client_put(client);
 }
 
diff --git a/nbd.h b/nbd.h
index 40d58d3..6305d68 100644
--- a/nbd.h
+++ b/nbd.h
@@ -81,7 +81,10 @@ typedef struct NBDClient NBDClient;
 NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset,
                           off_t size, uint32_t nbdflags);
 void nbd_export_close(NBDExport *exp);
+
 NBDClient *nbd_client_new(NBDExport *exp, int csock,
                           void (*close)(NBDClient *));
+void nbd_client_close(NBDClient *client);
+
 
 #endif
-- 
1.7.11.2





reply via email to

[Prev in Thread] Current Thread [Next in Thread]