windows-volume-status-tracking-20070612
[openafs.git] / src / WINNT / afsd / cm_daemon.c
index 7cff084..7dc6fbc 100644 (file)
 #include <afs/param.h>
 #include <afs/stds.h>
 
-#ifndef DJGPP
 #include <windows.h>
 #include <winsock2.h>
 #include <iphlpapi.h>
-#else
-#include <netdb.h>
-#endif /* !DJGPP */
 #include <stdlib.h>
 #include <malloc.h>
 #include <string.h>
 
 /* 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;
 
@@ -48,7 +45,6 @@ cm_bkgRequest_t *cm_bkgListEndp;      /* last elt in the list of requests */
 
 static int daemon_ShutdownFlag = 0;
 
-#ifndef DJGPP
 void cm_IpAddrDaemon(long parm)
 {
     extern void smb_CheckVCs(void);
@@ -66,11 +62,11 @@ void cm_IpAddrDaemon(long parm)
        }       
     }
 }
-#endif
 
 void cm_BkgDaemon(long parm)
 {
     cm_bkgRequest_t *rp;
+    afs_int32 code;
 
     rx_StartClientThread();
 
@@ -83,24 +79,65 @@ 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);
 
-        (*rp->procp)(rp->scp, rp->p1, rp->p2, rp->p3, rp->p4, rp->userp);
-                
-        cm_ReleaseUser(rp->userp);
-        cm_ReleaseSCache(rp->scp);
-        free(rp);
+       osi_Log1(afsd_logp,"cm_BkgDaemon processing request 0x%p", rp);
+
+#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);
+#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);
 }
 
-void cm_QueueBKGRequest(cm_scache_t *scp, cm_bkgProc_t *procp, long p1, long p2, long p3, long p4,
+void cm_QueueBKGRequest(cm_scache_t *scp, cm_bkgProc_t *procp, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, afs_uint32 p4,
        cm_user_t *userp)
 {
     cm_bkgRequest_t *rp;
@@ -144,7 +181,13 @@ IsWindowsFirewallPresent(void)
     if (!scm) return FALSE;
 
     /* Open Windows Firewall service */
-    svc = OpenService(scm, "SharedAccess", SERVICE_QUERY_CONFIG);
+    svc = OpenService(scm, "MpsSvc", SERVICE_QUERY_CONFIG);
+    if (!svc) {
+       afsi_log("MpsSvc Service could not be opened for query: 0x%x", GetLastError());
+       svc = OpenService(scm, "SharedAccess", SERVICE_QUERY_CONFIG);
+       if (!svc)
+           afsi_log("SharedAccess Service could not be opened for query: 0x%x", GetLastError());
+    }
     if (!svc)
         goto close_scm;
 
@@ -162,10 +205,13 @@ IsWindowsFirewallPresent(void)
 
     /* Query Windows Firewall service config, this time for real */
     flag = QueryServiceConfig(svc, pConfig, BufSize, &BufSize);
-    if (!flag)
+    if (!flag) {
+       afsi_log("QueryServiceConfig failed: 0x%x", GetLastError());
         goto free_pConfig;
+    }
 
     /* Is it autostart? */
+    afsi_log("AutoStart 0x%x", pConfig->dwStartType);
     if (pConfig->dwStartType < SERVICE_DEMAND_START)
         result = TRUE;
 
@@ -228,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);
 }
 
@@ -241,12 +293,17 @@ 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;
     HMODULE hHookDll;
     int configureFirewall = IsWindowsFirewallPresent();
 
+    if (!configureFirewall) {
+       afsi_log("No Windows Firewall detected");
+    }
+
     /* ping all file servers, up or down, with unauthenticated connection,
      * to find out whether we have all our callbacks from the server still.
      * Also, ping down VLDBs.
@@ -276,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)) {
@@ -297,7 +360,7 @@ void cm_Daemon(long parm)
            default:
                afsi_log("Unknown Windows Firewall Configuration error");
            }
-       }
+       } 
 
         /* find out what time it is */
         now = osi_Time();
@@ -320,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();
         }
 
@@ -383,13 +452,11 @@ void cm_InitDaemon(int nDaemons)
         lock_InitializeRWLock(&cm_daemonLock, "cm_daemonLock");
         osi_EndOnce(&once);
 
-#ifndef DJGPP
        /* creating IP Address Change monitor daemon */
         phandle = thrd_Create((SecurityAttrib) 0, 0,
                                (ThreadFunc) cm_IpAddrDaemon, 0, 0, &pid, "cm_IpAddrDaemon");
         osi_assert(phandle != NULL);
         thrd_CloseHandle(phandle);
-#endif /* DJGPP */
 
         /* creating pinging daemon */
         phandle = thrd_Create((SecurityAttrib) 0, 0,