]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
DEVEL15-windows-readonly-volume-callbacks-20071109
authorJeffrey Altman <jaltman@secure-endpoints.com>
Sat, 10 Nov 2007 00:15:55 +0000 (00:15 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Sat, 10 Nov 2007 00:15:55 +0000 (00:15 +0000)
A .readonly volume callback applies to the entire volume.  Track it
in the cm_volume_t cbExpiresRO field and apply it to all cm_scache_t
objects with valid callbacks that are associated with that volume upon
each daemon callback check.  This will prevent premature callback
expiration.

Also, attempt to automatically refresh the callbacks every 30 minutes
by obtaining a callback on the volume root.  This value is configurable
with the "daemonCheckVolCBInterval" registry value.

Change from osi_Time() to time() for expiration values in order to
permit conversion to human readable values in cmdebug.

(cherry picked from commit b43d778e9342dd19c010354cf6db854fdf1f7d22)

src/WINNT/afsd/cm_callback.c
src/WINNT/afsd/cm_daemon.c
src/WINNT/afsd/cm_scache.c
src/WINNT/afsd/cm_volume.c
src/WINNT/afsd/cm_volume.h

index 00cd50502dbd0de9aa822daf633367a250f55299..ee45a2c34c349fbc4b2639441ba7e63b8475914d 100644 (file)
@@ -267,6 +267,11 @@ void cm_RevokeVolumeCallback(struct rx_call *callp, cm_cell_t *cellp, AFSFid *fi
                 cm_CallbackNotifyChange(scp);
                 lock_ObtainWrite(&cm_scacheLock);
                 cm_ReleaseSCacheNoLock(scp);
+
+                if (scp->flags & CM_SCACHEFLAG_PURERO && scp->volp) {
+                    scp->volp->cbExpiresRO = 0;
+                }
+                
             }
         }      /* search one hash bucket */
     }  /* search all hash buckets */
@@ -484,6 +489,10 @@ SRXAFSCB_InitCallBackState(struct rx_call *callp)
                     cm_CallbackNotifyChange(scp);
                 lock_ObtainWrite(&cm_scacheLock);
                 cm_ReleaseSCacheNoLock(scp);
+
+                if (discarded && (scp->flags & CM_SCACHEFLAG_PURERO) && scp->volp && scp->volp->cbExpiresRO != 0)
+                    scp->volp->cbExpiresRO = 0;
+
             }  /* search one hash bucket */
        }       /* search all hash buckets */
        
@@ -741,7 +750,10 @@ SRXAFSCB_GetCE(struct rx_call *callp, long index, AFSDBCacheEntry *cep)
     cep->Length = scp->length.LowPart;
     cep->DataVersion = scp->dataVersion;
     cep->callback = afs_data_pointer_to_int32(scp->cbServerp);
-    cep->cbExpires = scp->cbExpires;
+    if (scp->flags & CM_SCACHEFLAG_PURERO && scp->volp)
+        cep->cbExpires = scp->volp->cbExpiresRO;
+    else
+        cep->cbExpires = scp->cbExpires;
     cep->refCount = scp->refCount;
     cep->opens = scp->openReads;
     cep->writers = scp->openWrites;
@@ -852,7 +864,10 @@ SRXAFSCB_GetCE64(struct rx_call *callp, long index, AFSDBCacheEntry64 *cep)
 #endif
     cep->DataVersion = scp->dataVersion;
     cep->callback = afs_data_pointer_to_int32(scp->cbServerp);
-    cep->cbExpires = scp->cbExpires;
+    if (scp->flags & CM_SCACHEFLAG_PURERO && scp->volp)
+        cep->cbExpires = scp->volp->cbExpiresRO;
+    else
+        cep->cbExpires = scp->cbExpires;
     cep->refCount = scp->refCount;
     cep->opens = scp->openReads;
     cep->writers = scp->openWrites;
@@ -1529,7 +1544,7 @@ void cm_StartCallbackGrantingCall(cm_scache_t *scp, cm_callbackRequest_t *cbrp)
     lock_ObtainWrite(&cm_callbackLock);
     cbrp->callbackCount = cm_callbackCount;
     cm_activeCallbackGrantingCalls++;
-    cbrp->startTime = osi_Time();
+    cbrp->startTime = time(NULL);
     cbrp->serverp = NULL;
     lock_ReleaseWrite(&cm_callbackLock);
 }
@@ -1547,7 +1562,7 @@ void cm_EndCallbackGrantingCall(cm_scache_t *scp, cm_callbackRequest_t *cbrp,
     cm_racingRevokes_t *nrevp;         /* where we'll be next */
     int freeFlag;
     cm_server_t * serverp = NULL;
-    int discardScp = 0;
+    int discardScp = 0, discardVolCB = 0;
 
     lock_ObtainWrite(&cm_callbackLock);
     if (flags & CM_CALLBACK_MAINTAINCOUNT) {
@@ -1576,6 +1591,8 @@ void cm_EndCallbackGrantingCall(cm_scache_t *scp, cm_callbackRequest_t *cbrp,
                     serverp = cbrp->serverp;
             }
             scp->cbExpires = cbrp->startTime + cbp->ExpirationTime;
+            if (scp->flags & CM_SCACHEFLAG_PURERO && scp->volp)
+                scp->volp->cbExpiresRO = scp->cbExpires;
         } else {
             if (freeFlag)
                 serverp = cbrp->serverp;
@@ -1613,6 +1630,10 @@ void cm_EndCallbackGrantingCall(cm_scache_t *scp, cm_callbackRequest_t *cbrp,
                       cbrp->callbackCount, revp->callbackCount,
                       cm_callbackCount);
             discardScp = 1;
+
+            if ((scp->flags & CM_SCACHEFLAG_PURERO) && scp->volp && 
+                (revp->flags & (CM_RACINGFLAG_CANCELVOL | CM_RACINGFLAG_CANCELALL)))
+                scp->volp->cbExpiresRO = 0;
         }
         if (freeFlag) 
             free(revp);
@@ -1824,6 +1845,11 @@ void cm_CheckCBExpiration(void)
     for (i=0; i<cm_data.scacheHashTableSize; i++) {
         for (scp = cm_data.scacheHashTablep[i]; scp; scp=scp->nextp) {
             downTime = 0;
+            if (scp->flags & CM_SCACHEFLAG_PURERO && scp->volp) {
+                if (scp->volp->cbExpiresRO > scp->cbExpires && scp->cbExpires > 0)
+                    scp->cbExpires = scp->volp->cbExpiresRO;
+            }
+
             if (scp->cbServerp && scp->cbExpires > 0 && now > scp->cbExpires && 
                  (cm_CBServersUp(scp, &downTime) || downTime == 0 || downTime >= scp->cbExpires)) 
             {
index 01f52a667ed34491d2ecfa6231f0b88fb06f1169..7b2df639c46f68964af46334ffa28949739772ca 100644 (file)
@@ -34,6 +34,7 @@ long cm_daemonCheckDownInterval  = 180;
 long cm_daemonCheckUpInterval    = 240;
 long cm_daemonCheckVolInterval   = 3600;
 long cm_daemonCheckCBInterval    = 60;
+long cm_daemonCheckVolCBInterval = 1800;
 long cm_daemonCheckLockInterval  = 60;
 long cm_daemonTokenCheckInterval = 180;
 long cm_daemonCheckOfflineVolInterval = 600;
@@ -274,6 +275,13 @@ cm_DaemonCheckInit(void)
        cm_daemonCheckCBInterval = dummy;
     afsi_log("daemonCheckCBInterval is %d", cm_daemonCheckCBInterval);
 
+    dummyLen = sizeof(DWORD);
+    code = RegQueryValueEx(parmKey, "daemonCheckVolCBInterval", NULL, NULL,
+                           (BYTE *) &dummy, &dummyLen);
+    if (code == ERROR_SUCCESS)
+       cm_daemonCheckVolCBInterval = dummy;
+    afsi_log("daemonCheckVolCBInterval is %d", cm_daemonCheckVolCBInterval);
+
     dummyLen = sizeof(DWORD);
     code = RegQueryValueEx(parmKey, "daemonCheckLockInterval", NULL, NULL,
                            (BYTE *) &dummy, &dummyLen);
@@ -305,6 +313,7 @@ void cm_Daemon(long parm)
     time_t lastLockCheck;
     time_t lastVolCheck;
     time_t lastCBExpirationCheck;
+    time_t lastVolCBRenewalCheck;
     time_t lastDownServerCheck;
     time_t lastUpServerCheck;
     time_t lastTokenCacheCheck;
@@ -344,6 +353,7 @@ void cm_Daemon(long parm)
     now = osi_Time();
     lastVolCheck = now - cm_daemonCheckVolInterval/2 + (rand() % cm_daemonCheckVolInterval);
     lastCBExpirationCheck = now - cm_daemonCheckCBInterval/2 + (rand() % cm_daemonCheckCBInterval);
+    lastVolCBRenewalCheck = now - cm_daemonCheckVolCBInterval/2 + (rand() % cm_daemonCheckVolCBInterval);
     lastLockCheck = now - cm_daemonCheckLockInterval/2 + (rand() % cm_daemonCheckLockInterval);
     lastDownServerCheck = now - cm_daemonCheckDownInterval/2 + (rand() % cm_daemonCheckDownInterval);
     lastUpServerCheck = now - cm_daemonCheckUpInterval/2 + (rand() % cm_daemonCheckUpInterval);
@@ -402,6 +412,12 @@ void cm_Daemon(long parm)
            now = osi_Time();
         }
 
+        if (now > lastVolCBRenewalCheck + cm_daemonCheckVolCBInterval) {
+            lastVolCBRenewalCheck = now;
+            cm_VolumeRenewROCallbacks();
+            now = osi_Time();
+        }
+
         if (now > lastBusyVolCheck + cm_daemonCheckOfflineVolInterval) {
             lastVolCheck = now;
             cm_CheckOfflineVolumes();
index 0ae96a9958278702a66e244f38b1403563ab098a..6a43d827592b4c7732b5e9d78b416958c65193ca 100644 (file)
@@ -498,8 +498,14 @@ cm_SuspendSCache(void)
 
     lock_ObtainWrite(&cm_scacheLock);
     for ( scp = cm_data.allSCachesp; scp; scp = scp->allNextp ) {
-        if (scp->cbServerp)
+        if (scp->cbServerp) {
+            if (scp->flags & CM_SCACHEFLAG_PURERO && scp->volp) {
+                if (scp->volp->cbExpiresRO == scp->cbExpires) {
+                    scp->volp->cbExpiresRO = now+1;
+                }
+            }
             scp->cbExpires = now+1;
+        }
     }
     lock_ReleaseWrite(&cm_scacheLock);
 }
index 79f61d4020d2ffcab56295a73e0550a9ddafa4dd..a4a2b6f3e25497aca50ab0289ddb042a310e1e69 100644 (file)
@@ -77,7 +77,7 @@ cm_ShutdownVolume(void)
             cm_VolumeStatusNotification(volp, volp->ro.ID, volp->ro.state, vl_alldown);
         if (volp->bk.ID)
             cm_VolumeStatusNotification(volp, volp->bk.ID, volp->bk.state, vl_alldown);
-
+        volp->cbExpiresRO = 0;
         lock_FinalizeMutex(&volp->mx);
     }
 
@@ -118,6 +118,7 @@ void cm_InitVolume(int newFile, long maxVols)
                     cm_VolumeStatusNotification(volp, volp->ro.ID, vl_alldown, volp->ro.state);
                 if (volp->bk.ID)
                     cm_VolumeStatusNotification(volp, volp->bk.ID, vl_alldown, volp->bk.state);
+                volp->cbExpiresRO = 0;
             }
         }
         osi_EndOnce(&once);
@@ -768,6 +769,7 @@ long cm_GetVolumeByName(struct cm_cell *cellp, char *volumeNamep,
         volp->rw.state = volp->ro.state = volp->bk.state = vl_unknown;
         volp->rw.nextp = volp->ro.nextp = volp->bk.nextp = NULL;
         volp->rw.flags = volp->ro.flags = volp->bk.flags = 0;
+        volp->cbExpiresRO = 0;
         cm_AddVolumeToNameHashTable(volp);
         lock_ReleaseWrite(&cm_volumeLock);
     }
@@ -1498,3 +1500,38 @@ enum volstatus cm_GetVolumeStatus(cm_volume_t *volp, afs_uint32 volID)
     }
 }
 
+
+void 
+cm_VolumeRenewROCallbacks(void)
+{
+    cm_volume_t * volp;
+
+
+    lock_ObtainRead(&cm_volumeLock);
+    for (volp = cm_data.allVolumesp; volp; volp=volp->allNextp) {
+        if ( volp->cbExpiresRO > 0) {
+            cm_req_t      req;
+            cm_fid_t      fid;
+            cm_scache_t * scp;
+
+            fid.cell = volp->cellp->cellID;
+            fid.volume = volp->ro.ID;
+            fid.vnode = 1;
+            fid.unique = 1;
+
+            cm_InitReq(&req);
+
+            if (cm_GetSCache(&fid, &scp, cm_rootUserp, &req) == 0) {
+                lock_ReleaseRead(&cm_volumeLock);
+                lock_ObtainMutex(&scp->mx);
+                cm_GetCallback(scp, cm_rootUserp, &req, 1);
+                lock_ReleaseMutex(&scp->mx);
+                cm_ReleaseSCache(scp);
+                lock_ObtainRead(&cm_volumeLock);
+            }
+        }
+    }
+    lock_ReleaseRead(&cm_volumeLock);
+}
+
+
index d6f149772f88b770d72208aabc9b59083edbef49..26269709f74a1f29645ec498d1e2a5887ca051cf 100644 (file)
@@ -39,6 +39,7 @@ typedef struct cm_volume {
     osi_mutex_t mx;
     afs_uint32 flags;                  /* by mx */
     afs_uint32 refCount;               /* by cm_volumeLock */
+    time_t cbExpiresRO;                 /* latest RO expiration time; by cm_scacheLock */
 } cm_volume_t;
 
 #define CM_VOLUMEFLAG_RESET       1    /* reload this info on next use */
@@ -119,4 +120,6 @@ extern void cm_UpdateVolumeStatus(cm_volume_t *volp, afs_uint32 volID);
 extern void cm_VolumeStatusNotification(cm_volume_t * volp, afs_uint32 volID, enum volstatus old, enum volstatus new);
 
 extern enum volstatus cm_GetVolumeStatus(cm_volume_t *volp, afs_uint32 volID);
+
+extern void cm_VolumeRenewROCallbacks(void);
 #endif /*  __CM_VOLUME_H_ENV__ */