]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
windows-readonly-volume-callbacks-20071109
authorJeffrey Altman <jaltman@secure-endpoints.com>
Sat, 10 Nov 2007 00:14:26 +0000 (00:14 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Sat, 10 Nov 2007 00:14:26 +0000 (00:14 +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.

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 d6d9e8311218b148e96df4fed147992559be5bbc..866f8d2554b27e965383a3c82b5f87cff67fef11 100644 (file)
@@ -263,6 +263,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 */
@@ -480,6 +485,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 */
        
@@ -737,7 +746,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;
@@ -848,7 +860,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;
@@ -1525,7 +1540,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);
 }
@@ -1543,7 +1558,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) {
@@ -1572,6 +1587,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;
@@ -1609,6 +1626,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);
@@ -1820,6 +1841,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 15aaad135810e9ca27ddd003ee769c5d27d6af0a..5e47a7f3234c9e713e6fe376b31e0ed9f4e4bf11 100644 (file)
@@ -30,6 +30,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;
@@ -268,6 +269,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);
@@ -299,6 +307,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;
@@ -338,6 +347,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);
@@ -396,6 +406,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 0a19d823772e1b0ac7168fe19bf918ea2c5b1429..9b6ed5e447a6da4b6f7bc17c7f52534f56ab8d5a 100644 (file)
@@ -496,8 +496,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 b3d46f8e25ceb07c40de6553d3701478848f94b8..3ee4812ee4d786c03e1db89b8b3119a90a892551 100644 (file)
@@ -73,7 +73,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);
     }
 
@@ -114,6 +114,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);
@@ -764,6 +765,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);
     }
@@ -1494,3 +1496,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__ */