]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
DEVEL15-windows-free-server-deadlock-20080813
authorJeffrey Altman <jaltman@secure-endpoints.com>
Thu, 14 Aug 2008 03:37:59 +0000 (03:37 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Thu, 14 Aug 2008 03:37:59 +0000 (03:37 +0000)
LICENSE MIT

avoid a deadloc when freeing servers.  cm_serverLock must be released
around cm_GCConnections()

(cherry picked from commit 06b5006517c77767a246df2b6d66a344a44cbea1)

src/WINNT/afsd/cm_server.c
src/WINNT/afsd/cm_server.h

index be2b7fd7558e039071f88ee2f96f01583c0ace7d..0a442fc816d6df9c63c38d727585f63d9ccaa143 100644 (file)
@@ -1191,16 +1191,32 @@ void cm_RandomizeServer(cm_serverRef_t** list)
 void cm_FreeServer(cm_server_t* serverp)
 {
     cm_server_vols_t * tsrvp, *nextp;
+    int delserver = 0;
 
     cm_PutServerNoLock(serverp);
     if (serverp->refCount == 0)
     {
-        /* we need to check to ensure that all of the connections
+        /* 
+         * we need to check to ensure that all of the connections
          * for this server have a 0 refCount; otherwise, they will
          * not be garbage collected 
+         *
+         * must drop the cm_serverLock because cm_GCConnections
+         * obtains the cm_connLock and that comes first in the 
+         * lock hierarchy.  
          */
+        lock_ReleaseWrite(&cm_serverLock);
         cm_GCConnections(serverp);  /* connsp */
+        lock_ObtainWrite(&cm_serverLock);
+    }
 
+
+    /* 
+     * Once we have the cm_serverLock locked check to make
+     * sure the refCount is still zero before removing the 
+     * server entirely.
+     */
+    if (serverp->refCount == 0) {
        if (!(serverp->flags & CM_SERVERFLAG_PREF_SET)) {
             switch (serverp->type) {
             case CM_SERVER_VLDB:
index 143ff4cb2005ed6452ed22d53afa834edaabd9bd..93001b668e67397c4694f3580ef9ae4f6049ef48 100644 (file)
@@ -128,6 +128,8 @@ extern cm_server_t * cm_FindServerByIP(afs_uint32 addr, int type);
 
 extern void cm_SetLanAdapterChangeDetected(void);
 
+extern void cm_RemoveVolumeFromServer(cm_server_t * serverp, afs_uint32 volID);
+
 /* Protected by cm_syscfgLock (rw) */
 extern int cm_noIPAddr;         /* number of client network interfaces */
 extern int cm_IPAddr[CM_MAXINTERFACE_ADDR];    /* client's IP address in host order */