]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
DEVEL15-windows-do-not-expire-cbs-when-servers-are-down-20070802
authorJeffrey Altman <jaltman@secure-endpoints.com>
Thu, 2 Aug 2007 21:46:12 +0000 (21:46 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Thu, 2 Aug 2007 21:46:12 +0000 (21:46 +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.

(cherry picked from commit 10b76dffa0ece0cca898637a00d34b27809b9eb9)

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 44df24f486f1dc4685c9767779b394125e769a05..6d0db27c587a0c582e8d23cc63afdff43d6ba1e0 100644 (file)
@@ -1756,12 +1756,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");
 
@@ -1769,18 +1809,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 ff3743edcc00cb6d03fdf668edfa99ffc76778ab..275afde2f8531e70e7836d20dd88d8d5e04590a3 100644 (file)
@@ -551,9 +551,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 a9b27d33527234bd781971bd9b7a059d00e940b8..87374b876969e8a90d76a5dcc0f2e0415f62644d 100644 (file)
@@ -110,6 +110,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) {
@@ -152,6 +153,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 b881602ffa3801f3c163490e792399a85097f147..5bb4431c1bc0cd1daf5f6bec612fb4ef74952831 100644 (file)
@@ -40,6 +40,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};