]> xenbits.xensource.com Git - libvirt.git/commitdiff
rpc: Avoid deadlock when closing client connection
authorJiri Denemark <jdenemar@redhat.com>
Mon, 18 Feb 2013 14:10:04 +0000 (15:10 +0100)
committerJiri Denemark <jdenemar@redhat.com>
Tue, 19 Feb 2013 09:52:37 +0000 (10:52 +0100)
We need to drop the server lock before calling virObjectUnlock(client)
since in case we had the last reference to the client, its dispose
callback would be called and that could possibly try to lock the server
and cause a deadlock. This is exactly what happens when there is only
one QEMU domain running and it is marked to be autodestroyed when the
connection dies. This results in qemuProcessAutoDestroy ->
qemuProcessStop -> virNetServerRemoveShutdownInhibition call sequence,
where the last function locks the server.

src/rpc/virnetserver.c

index 95333d0cc3cfc00875c78f67c561c411520f2a4a..e536cc30ee015c91b05436379fe45e0d0e8a7f60 100644 (file)
@@ -1120,7 +1120,7 @@ void virNetServerRun(virNetServerPtr srv)
             if (virNetServerClientWantClose(srv->clients[i]))
                 virNetServerClientClose(srv->clients[i]);
             if (virNetServerClientIsClosed(srv->clients[i])) {
-                virObjectUnref(srv->clients[i]);
+                virNetServerClientPtr client = srv->clients[i];
                 if (srv->nclients > 1) {
                     memmove(srv->clients + i,
                             srv->clients + i + 1,
@@ -1131,6 +1131,10 @@ void virNetServerRun(virNetServerPtr srv)
                     srv->nclients = 0;
                 }
 
+                virObjectUnlock(srv);
+                virObjectUnref(client);
+                virObjectLock(srv);
+
                 goto reprocess;
             }
         }