windows-volume-status-tracking-20070612
[openafs.git] / src / WINNT / afsd / cm_daemon.c
index 06488f1..7dc6fbc 100644 (file)
 
 /* in seconds */
 long cm_daemonCheckDownInterval  = 180;
-long cm_daemonCheckUpInterval    = 600;
+long cm_daemonCheckUpInterval    = 240;
 long cm_daemonCheckVolInterval   = 3600;
 long cm_daemonCheckCBInterval    = 60;
 long cm_daemonCheckLockInterval  = 60;
 long cm_daemonTokenCheckInterval = 180;
+long cm_daemonCheckBusyVolInterval = 600;
 
 osi_rwlock_t cm_daemonLock;
 
@@ -65,6 +66,7 @@ void cm_IpAddrDaemon(long parm)
 void cm_BkgDaemon(long parm)
 {
     cm_bkgRequest_t *rp;
+    afs_int32 code;
 
     rx_StartClientThread();
 
@@ -77,23 +79,60 @@ void cm_BkgDaemon(long parm)
         }
                 
         /* we found a request */
-        rp = cm_bkgListEndp;
-        cm_bkgListEndp = (cm_bkgRequest_t *) osi_QPrev(&rp->q);
-        osi_QRemove((osi_queue_t **) &cm_bkgListp, &rp->q);
+        for (rp = cm_bkgListEndp; rp; rp = (cm_bkgRequest_t *) osi_QPrev(&rp->q))
+       {
+           if (cm_ServerAvailable(&rp->scp->fid, rp->userp))
+               break;
+       }
+       if (rp == NULL) {
+           /* we couldn't find a request that we could process at the current time */
+           lock_ReleaseWrite(&cm_daemonLock);
+           Sleep(1000);
+           lock_ObtainWrite(&cm_daemonLock);
+           continue;
+       }
+
+        osi_QRemoveHT((osi_queue_t **) &cm_bkgListp, (osi_queue_t **) &cm_bkgListEndp, &rp->q);
         osi_assert(cm_bkgQueueCount-- > 0);
         lock_ReleaseWrite(&cm_daemonLock);
 
-       osi_Log2(afsd_logp,"cm_BkgDaemon (before) scp 0x%x ref %d",rp->scp, rp->scp->refCount);
+       osi_Log1(afsd_logp,"cm_BkgDaemon processing request 0x%p", rp);
 
-        (*rp->procp)(rp->scp, rp->p1, rp->p2, rp->p3, rp->p4, rp->userp);
-                
+#ifdef DEBUG_REFCOUNT
+       osi_Log2(afsd_logp,"cm_BkgDaemon (before) scp 0x%x ref %d",rp->scp, rp->scp->refCount);
+#endif
+        code = (*rp->procp)(rp->scp, rp->p1, rp->p2, rp->p3, rp->p4, rp->userp);
+#ifdef DEBUG_REFCOUNT                
        osi_Log2(afsd_logp,"cm_BkgDaemon (after) scp 0x%x ref %d",rp->scp, rp->scp->refCount);
-
-       cm_ReleaseUser(rp->userp);
-        cm_ReleaseSCache(rp->scp);
-        free(rp);
+#endif
+       if (code == 0) {
+           cm_ReleaseUser(rp->userp);
+           cm_ReleaseSCache(rp->scp);
+           free(rp);
+       }
 
         lock_ObtainWrite(&cm_daemonLock);
+
+       switch ( code ) {
+       case 0: /* success */
+           osi_Log1(afsd_logp,"cm_BkgDaemon SUCCESS: request 0x%p", rp);
+           break;
+       case CM_ERROR_TIMEDOUT: /* or server restarting */
+       case CM_ERROR_RETRY:
+       case CM_ERROR_WOULDBLOCK:
+       case CM_ERROR_ALLBUSY:
+       case CM_ERROR_ALLDOWN:
+       case CM_ERROR_ALLOFFLINE:
+       case CM_ERROR_PARTIALWRITE:
+           osi_Log2(afsd_logp,"cm_BkgDaemon re-queueing failed request 0x%p code 0x%x",
+                    rp, code);
+           cm_bkgQueueCount++;
+           osi_QAddT((osi_queue_t **) &cm_bkgListp, (osi_queue_t **)&cm_bkgListEndp, &rp->q);
+           break;
+       default:
+           osi_Log2(afsd_logp,"cm_BkgDaemon FAILED: request dropped 0x%p code 0x%x",
+                    rp, code);
+       }
     }
     lock_ReleaseWrite(&cm_daemonLock);
 }
@@ -235,6 +274,12 @@ cm_DaemonCheckInit(void)
     if (code == ERROR_SUCCESS)
        cm_daemonTokenCheckInterval = dummy;
     
+    dummyLen = sizeof(DWORD);
+    code = RegQueryValueEx(parmKey, "BusyVolumeCheckInterval", NULL, NULL,
+                           (BYTE *) &dummy, &dummyLen);
+    if (code == ERROR_SUCCESS)
+       cm_daemonCheckBusyVolInterval = dummy;
+    
     RegCloseKey(parmKey);
 }
 
@@ -248,6 +293,7 @@ void cm_Daemon(long parm)
     time_t lastDownServerCheck;
     time_t lastUpServerCheck;
     time_t lastTokenCacheCheck;
+    time_t lastBusyVolCheck;
     char thostName[200];
     unsigned long code;
     struct hostent *thp;
@@ -287,8 +333,14 @@ void cm_Daemon(long parm)
     lastDownServerCheck = now - cm_daemonCheckDownInterval/2 + (rand() % cm_daemonCheckDownInterval);
     lastUpServerCheck = now - cm_daemonCheckUpInterval/2 + (rand() % cm_daemonCheckUpInterval);
     lastTokenCacheCheck = now - cm_daemonTokenCheckInterval/2 + (rand() % cm_daemonTokenCheckInterval);
+    lastBusyVolCheck = now - cm_daemonCheckBusyVolInterval/2 * (rand() % cm_daemonCheckBusyVolInterval);
 
     while (daemon_ShutdownFlag == 0) {
+       /* check to see if the listener threads halted due to network 
+        * disconnect or other issues.  If so, attempt to restart them.
+        */
+       smb_RestartListeners();
+
        if (configureFirewall) {
            /* Open Microsoft Firewall to allow in port 7001 */
            switch (icf_CheckAndAddAFSPorts(AFS_PORTSET_CLIENT)) {
@@ -331,7 +383,13 @@ void cm_Daemon(long parm)
 
         if (now > lastVolCheck + cm_daemonCheckVolInterval) {
             lastVolCheck = now;
-            cm_CheckVolumes();
+            cm_RefreshVolumes();
+           now = osi_Time();
+        }
+
+        if (now > lastBusyVolCheck + cm_daemonCheckBusyVolInterval) {
+            lastVolCheck = now;
+            cm_CheckOfflineVolumes();
            now = osi_Time();
         }