commit 0dda594da99aede7621018a3705e7cf4c13b1606 Author: Jim Fehlig Date: Thu Jun 21 09:21:44 2012 -0600 Fix deadlock on libvirtd shutdown When shutting down libvirtd, the virNetServer shutdown can deadlock if there are in-flight jobs being handled by virNetServerHandleJob(). virNetServerFree() will acquire the virNetServer lock and call virThreadPoolFree() to terminate the workers, waiting for the workers to finish. But in-flight workers will attempt to acquire the virNetServer lock, resulting in deadlock. Fix the deadlock by unlocking the virNetServer lock before calling virThreadPoolFree(). This is safe since the virNetServerPtr object is ref-counted and only decrementing the ref count needs to be protected. Additionally, there is no need to re-acquire the lock after virThreadPoolFree() completes as all the workers have terminated. Index: libvirt-0.9.11.4/src/rpc/virnetserver.c =================================================================== --- libvirt-0.9.11.4.orig/src/rpc/virnetserver.c +++ libvirt-0.9.11.4/src/rpc/virnetserver.c @@ -801,10 +801,9 @@ void virNetServerFree(virNetServerPtr sr virNetServerLock(srv); VIR_DEBUG("srv=%p refs=%d", srv, srv->refs); srv->refs--; - if (srv->refs > 0) { - virNetServerUnlock(srv); + virNetServerUnlock(srv); + if (srv->refs > 0) return; - } for (i = 0 ; i < srv->nservices ; i++) virNetServerServiceToggle(srv->services[i], false); @@ -845,7 +844,6 @@ void virNetServerFree(virNetServerPtr sr dbus_connection_unref(srv->sysbus); #endif - virNetServerUnlock(srv); virMutexDestroy(&srv->lock); VIR_FREE(srv); }