]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
windows-do-not-expire-cbs-when-servers-are-down-20070802
authorJeffrey Altman <jaltman@secure-endpoints.com>
Thu, 2 Aug 2007 21:44:54 +0000 (21:44 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Thu, 2 Aug 2007 21:44:54 +0000 (21:44 +0000)
if all of the servers are down when a callback is due to expire
delay the expiration until at least one server is available.
this prevents some applications that are running when the CM
is off the network from failing if their pages are swapped out.

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

index e33f6185f4185647d2f745bb4ece7c9fb060cc0c..5a80a23dfa57176bf4d11d470da6e31fc82dd56b 100644 (file)
@@ -1752,12 +1752,52 @@ long cm_GetCallback(cm_scache_t *scp, struct cm_user *userp,
     return code;
 }
 
+
+/* called with cm_scacheLock held */
+long cm_CBServersUp(cm_scache_t *scp, time_t * downTime)
+{
+    cm_vol_state_t *statep;
+    cm_volume_t * volp = scp->volp;
+    afs_uint32 volID = scp->fid.volume;
+    cm_serverRef_t *tsrp;
+    int found;
+
+    *downTime = 0;
+
+    if (scp->cbServerp == NULL)
+        return 1;
+
+    if (volp->rw.ID == volID) {
+        statep = &volp->rw;
+    } else if (volp->ro.ID == volID) {
+        statep = &volp->ro;
+    } else if (volp->bk.ID == volID) {
+        statep = &volp->bk;
+    }
+
+    if (statep->state == vl_online)
+        return 1;
+
+    for (found = 0,tsrp = statep->serversp; tsrp; tsrp=tsrp->next) {
+        if (tsrp->server == scp->cbServerp)
+            found = 1;
+        if (tsrp->server->downTime > *downTime)
+            *downTime = tsrp->server->downTime;
+    }
+
+    /* if the cbServerp does not match the current volume server list
+     * we report the callback server as up so the callback can be 
+     * expired.
+     */
+    return(found ? 0 : 1);
+}
+
 /* called periodically by cm_daemon to shut down use of expired callbacks */
 void cm_CheckCBExpiration(void)
 {
     int i;
     cm_scache_t *scp;
-    time_t now;
+    time_t now, downTime = 0;
         
     osi_Log0(afsd_logp, "CheckCBExpiration");
 
@@ -1765,18 +1805,23 @@ void cm_CheckCBExpiration(void)
     lock_ObtainWrite(&cm_scacheLock);
     for (i=0; i<cm_data.scacheHashTableSize; i++) {
         for (scp = cm_data.scacheHashTablep[i]; scp; scp=scp->nextp) {
-            cm_HoldSCacheNoLock(scp);
-            if (scp->cbExpires > 0 && (scp->cbServerp == NULL || now > scp->cbExpires)) {
+
+            if (scp->cbServerp && scp->cbExpires > 0 && now > scp->cbExpires && 
+                 (cm_CBServersUp(scp, &downTime) || downTime == 0 || downTime >= scp->cbExpires)) 
+            {
+                cm_HoldSCacheNoLock(scp);
                 lock_ReleaseWrite(&cm_scacheLock);
-                osi_Log4(afsd_logp, "Callback Expiration Discarding SCache scp 0x%p vol %u vn %u uniq %u", 
+                
+                osi_Log4(afsd_logp, "Callback Expiration Discarding SCache scp 0x%p vol %u vn %u uniq %u",
                           scp, scp->fid.volume, scp->fid.vnode, scp->fid.unique);
                 lock_ObtainMutex(&scp->mx);
                 cm_DiscardSCache(scp);
                 lock_ReleaseMutex(&scp->mx);
                 cm_CallbackNotifyChange(scp);
+
+                cm_ReleaseSCacheNoLock(scp);
                 lock_ObtainWrite(&cm_scacheLock);
             }
-            cm_ReleaseSCacheNoLock(scp);
         }
     }
     lock_ReleaseWrite(&cm_scacheLock);
index 71012c3ff6524dcf7b09b0a074958f3b66bc6457..1eeebbe7cdc02a3a20bc113e28514bdf2296e4b6 100644 (file)
@@ -522,9 +522,10 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp,
     else if (errorCode >= -64 && errorCode < 0) {
         /* mark server as down */
         lock_ObtainMutex(&serverp->mx);
-       if (reqp->flags & CM_REQ_NEW_CONN_FORCED)
+       if (reqp->flags & CM_REQ_NEW_CONN_FORCED) {
            serverp->flags |= CM_SERVERFLAG_DOWN;
-       else {
+            serverp->downTime = osi_Time();
+        } else {
            reqp->flags |= CM_REQ_NEW_CONN_FORCED;
            forcing_new = 1;
        }
index 4a9b325fb0369e301dc349974069fe197c64e996..e7185714d12d25383e667a5621c5b0b5423fbd3f 100644 (file)
@@ -106,6 +106,7 @@ cm_PingServer(cm_server_t *tsp)
     if (code >= 0) {
        /* mark server as up */
        tsp->flags &= ~CM_SERVERFLAG_DOWN;
+        tsp->downTime = 0;
 
        /* we currently handle 32-bits of capabilities */
        if (caps.Capabilities_len > 0) {
@@ -148,6 +149,7 @@ cm_PingServer(cm_server_t *tsp)
     } else {
        /* mark server as down */
        tsp->flags |= CM_SERVERFLAG_DOWN;
+        tsp->downTime = osi_Time();
        if (code != VRESTARTING)
            cm_ForceNewConnections(tsp);
 
index 53d0442b7e4a930f0c7123d7c1997befafaf777e..772287fb2b4d2e7e846963a0260592e8f35cb833 100644 (file)
@@ -36,6 +36,7 @@ typedef struct cm_server {
     osi_mutex_t mx;
     unsigned short ipRank;             /* server priority */
     cm_server_vols_t *  vols;           /* by mx */
+    time_t downTime;                    /* by mx */
 } cm_server_t;
 
 enum repstate {srv_not_busy, srv_busy, srv_offline, srv_deleted};