windows-smb-started-synchronization-20080108
[openafs.git] / src / WINNT / afsd / afsd_service.c
index 7b444d9..ac58d2a 100644 (file)
@@ -9,6 +9,7 @@
 #include <setjmp.h>
 #include "afsd.h"
 #include "afsd_init.h"
+#include "lanahelper.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <winsock2.h>
@@ -39,7 +40,7 @@ HANDLE hAFSDWorkerThread[WORKER_THREADS];
 
 HANDLE WaitToTerminate;
 
-int GlobalStatus;
+static int GlobalStatus;
 
 #ifdef JUMP
 unsigned int MainThreadId;
@@ -49,7 +50,8 @@ jmp_buf notifier_jmp;
 extern int traceOnPanic;
 extern HANDLE afsi_file;
 
-int powerEventsRegistered = 0;
+static int powerEventsRegistered = 0;
+extern int powerStateSuspended = 0;
 
 /*
  * Notifier function for use by osi_panic
@@ -59,6 +61,8 @@ static void afsd_notifier(char *msgp, char *filep, long line)
 #ifdef AFSIFS
     int i;
 #endif
+    if (!msgp)
+        msgp = "unspecified assert";
 
     if (filep)
        LogEvent(EVENTLOG_ERROR_TYPE, MSG_SERVICE_ERROR_STOP_WITH_MSG_AND_LOCATION, 
@@ -74,6 +78,10 @@ static void afsd_notifier(char *msgp, char *filep, long line)
     buf_ForceTrace(TRUE);
 
     afsi_log("--- begin dump ---");
+    cm_MemDumpDirStats(afsi_file, "a", 0);
+    cm_MemDumpBPlusStats(afsi_file, "a", 0);
+    cm_DumpCells(afsi_file, "a", 0);
+    cm_DumpVolumes(afsi_file, "a", 0);
     cm_DumpSCache(afsi_file, "a", 0);
 #ifdef keisa
     cm_dnlcDump(afsi_file, "a");
@@ -83,7 +91,8 @@ static void afsd_notifier(char *msgp, char *filep, long line)
     afsi_log("--- end   dump ---");
     
 #ifdef DEBUG
-    DebugBreak();      
+    if (IsDebuggerPresent())
+        DebugBreak();  
 #endif
 
     SetEvent(WaitToTerminate);
@@ -174,7 +183,8 @@ afsd_ServiceControlHandler(DWORD ctrlCode)
             afsi_log("SERVICE_CONTROL_SHUTDOWN");
 
         /* Write all dirty buffers back to server */
-        buf_CleanAndReset();
+       if ( !lana_OnlyLoopback() )
+           buf_CleanAndReset();
 
         /* Force trace if requested */
         code = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
@@ -229,11 +239,22 @@ afsd_ServiceControlHandlerEx(
     DWORD dummyLen, doTrace;
     long code;
     DWORD dwRet = ERROR_CALL_NOT_IMPLEMENTED;
+    OSVERSIONINFO osVersion;
+
+    /* Get the version of Windows */
+    memset(&osVersion, 0x00, sizeof(osVersion));
+    osVersion.dwOSVersionInfoSize = sizeof(osVersion);
+    GetVersionEx(&osVersion);
 
     switch (ctrlCode) 
     {
     case SERVICE_CONTROL_SHUTDOWN:
     case SERVICE_CONTROL_STOP:
+       if (ctrlCode == SERVICE_CONTROL_SHUTDOWN)
+           afsi_log("SERVICE_CONTROL_SHUTDOWN");
+       else
+            afsi_log("SERVICE_CONTROL_STOP");
+
         ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
         ServiceStatus.dwWin32ExitCode = NO_ERROR;
         ServiceStatus.dwCheckPoint = 1;
@@ -242,7 +263,8 @@ afsd_ServiceControlHandlerEx(
         SetServiceStatus(StatusHandle, &ServiceStatus);
 
         /* Write all dirty buffers back to server */
-        buf_CleanAndReset();
+       if ( !lana_OnlyLoopback() )
+           buf_CleanAndReset();
 
         /* Force trace if requested */
         code = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
@@ -298,34 +320,56 @@ afsd_ServiceControlHandlerEx(
                 case PBT_APMQUERYSUSPEND:       
                     afsi_log("SERVICE_CONTROL_APMQUERYSUSPEND"); 
                     /* Write all dirty buffers back to server */
-                    buf_CleanAndReset();
+                   if ( !lana_OnlyLoopback() ) {
+                       buf_CleanAndReset();
+                        cm_SuspendSCache();
+                    }
+                    afsi_log("SERVICE_CONTROL_APMQUERYSUSPEND buf_CleanAndReset complete"); 
                     dwRet = NO_ERROR;                       
                     break;                                  
                 case PBT_APMQUERYSTANDBY:                                                         
                     afsi_log("SERVICE_CONTROL_APMQUERYSTANDBY"); 
                     /* Write all dirty buffers back to server */
-                    buf_CleanAndReset();
+                   if ( !lana_OnlyLoopback() ) {
+                       buf_CleanAndReset();
+                        cm_SuspendSCache();
+                    }
+                    afsi_log("SERVICE_CONTROL_APMQUERYSTANDBY buf_CleanAndReset complete"); 
                     dwRet = NO_ERROR;                                                             
                     break;                                                                        
                                                                                                                          
                     /* allow remaining case PBT_WhatEver */                                           
                 case PBT_APMSUSPEND:                         
-                    afsi_log("SERVICE_CONTROL_APMSUSPEND"); 
+                    afsi_log("SERVICE_CONTROL_APMSUSPEND");
+                   powerStateSuspended = 1;
+                   if (osVersion.dwMajorVersion >= 6) {
+                        cm_SuspendSCache();
+                       smb_StopListeners(0);
+                    }
                     dwRet = NO_ERROR;                       
                     break;                                  
                 case PBT_APMSTANDBY:                  
                     afsi_log("SERVICE_CONTROL_APMSTANDBY"); 
+                   powerStateSuspended = 1;
+                   if (osVersion.dwMajorVersion >= 6) {
+                        cm_SuspendSCache();
+                       smb_StopListeners(0);
+                    }
                     dwRet = NO_ERROR;                       
                     break;                                  
                 case PBT_APMRESUMECRITICAL:             
                     afsi_log("SERVICE_CONTROL_APMRESUMECRITICAL"); 
+                   if (osVersion.dwMajorVersion >= 6)
+                       smb_RestartListeners(0);
                     dwRet = NO_ERROR;                       
                     break;                                  
                 case PBT_APMRESUMESUSPEND:                                                        
+                   /* User logged in after suspend */
                     afsi_log("SERVICE_CONTROL_APMRESUMESUSPEND"); 
                     dwRet = NO_ERROR;                       
                     break;                                  
-                case PBT_APMRESUMESTANDBY:                                                        
+                case PBT_APMRESUMESTANDBY:            
+                   /* User logged in after standby */
                     afsi_log("SERVICE_CONTROL_APMRESUMESTANDBY"); 
                     dwRet = NO_ERROR;                       
                     break;                                  
@@ -345,8 +389,12 @@ afsd_ServiceControlHandlerEx(
 #endif
                     dwRet = NO_ERROR;                       
                     break;                                  
-                case PBT_APMRESUMEAUTOMATIC:                                                      
+                case PBT_APMRESUMEAUTOMATIC:          
+                   /* This is the message delivered once all devices are up */
                     afsi_log("SERVICE_CONTROL_APMRESUMEAUTOMATIC"); 
+                   powerStateSuspended = 0;
+                   if (osVersion.dwMajorVersion >= 6)
+                       smb_RestartListeners(0);
                     dwRet = NO_ERROR;                       
                     break;                                  
                 default:                                                                          
@@ -393,7 +441,7 @@ static DWORD __stdcall MountGlobalDrivesThread(void * notUsed)
 
     dwResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_QUERY_VALUE, &hKey);
     if (dwResult != ERROR_SUCCESS)
-        return;
+        return 0;
 
     while (dwIndex < MAX_DRIVES) {
         dwDriveSize = sizeof(szDriveToMapTo);
@@ -957,7 +1005,11 @@ BOOL AFSModulesVerify(void)
         RegCloseKey (parmKey);
     }
 
-    if (verifyServiceSig && cacheSize < 716800) {
+    if (verifyServiceSig 
+#ifndef _WIN64
+         && cacheSize < 716800
+#endif
+         ) {
         trustVerified = VerifyTrust(filename);
     } else {
         afsi_log("Signature Verification disabled");
@@ -1111,7 +1163,7 @@ afsd_Main(DWORD argc, LPTSTR *argv)
     ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
     ServiceStatus.dwWin32ExitCode = NO_ERROR;
     ServiceStatus.dwCheckPoint = 1;
-    ServiceStatus.dwWaitHint = 30000;
+    ServiceStatus.dwWaitHint = 120000;
     /* accept Power Events */
     ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_POWEREVENT | SERVICE_ACCEPT_PARAMCHANGE;
     SetServiceStatus(StatusHandle, &ServiceStatus);
@@ -1189,19 +1241,22 @@ afsd_Main(DWORD argc, LPTSTR *argv)
         }
         else
         {
-            /* allow another 15 seconds to start */
+            /* allow another 120 seconds to start */
             ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
             ServiceStatus.dwServiceSpecificExitCode = 0;
             ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
             ServiceStatus.dwWin32ExitCode = NO_ERROR;
             ServiceStatus.dwCheckPoint = 2;
-            ServiceStatus.dwWaitHint = 20000;
+            ServiceStatus.dwWaitHint = 120000;
             /* accept Power Events */
             ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_POWEREVENT | SERVICE_ACCEPT_PARAMCHANGE;
             SetServiceStatus(StatusHandle, &ServiceStatus);
         }
     }
 
+    /* Perform Volume Status Notification Initialization */
+    cm_VolStatus_Initialization();
+
 #ifdef JUMP
     MainThreadId = GetCurrentThreadId();
     jmpret = setjmp(notifier_jmp);
@@ -1216,8 +1271,8 @@ afsd_Main(DWORD argc, LPTSTR *argv)
         }
 
 #ifndef NOTSERVICE
-        ServiceStatus.dwCheckPoint++;
-        ServiceStatus.dwWaitHint -= 5000;
+        ServiceStatus.dwCheckPoint = 3;
+        ServiceStatus.dwWaitHint = 30000;
         SetServiceStatus(StatusHandle, &ServiceStatus);
 #endif
         code = afsd_InitDaemons(&reason);
@@ -1254,11 +1309,14 @@ afsd_Main(DWORD argc, LPTSTR *argv)
         }
 
 #ifndef NOTSERVICE
-        ServiceStatus.dwCheckPoint++;
-        ServiceStatus.dwWaitHint -= 5000;
+        ServiceStatus.dwCheckPoint = 4;
+        ServiceStatus.dwWaitHint = 15000;
         SetServiceStatus(StatusHandle, &ServiceStatus);
 #endif
 
+        /* Notify any volume status handlers that the cache manager has started */
+        cm_VolStatus_Service_Started();
+
 /* the following ifdef chooses the mode of operation for the service.  to enable
  * a runtime flag (instead of compile-time), pioctl() would need to dynamically
  * determine the mode, in order to use the correct ioctl special-file path. */
@@ -1310,7 +1368,7 @@ afsd_Main(DWORD argc, LPTSTR *argv)
 #ifndef NOTSERVICE
         ServiceStatus.dwCurrentState = SERVICE_RUNNING;
         ServiceStatus.dwWin32ExitCode = NO_ERROR;
-        ServiceStatus.dwCheckPoint = 0;
+        ServiceStatus.dwCheckPoint = 5;
         ServiceStatus.dwWaitHint = 0;
 
         /* accept Power events */
@@ -1356,6 +1414,13 @@ afsd_Main(DWORD argc, LPTSTR *argv)
         CloseHandle(hAFSDWorkerThread[cnt]);
 #endif
 
+    ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
+    ServiceStatus.dwWin32ExitCode = NO_ERROR;
+    ServiceStatus.dwCheckPoint = 6;
+    ServiceStatus.dwWaitHint = 120000;
+    ServiceStatus.dwControlsAccepted = 0;
+    SetServiceStatus(StatusHandle, &ServiceStatus);
+
     afsi_log("Received Termination Signal, Stopping Service");
 
     if ( GlobalStatus )
@@ -1375,19 +1440,6 @@ afsd_Main(DWORD argc, LPTSTR *argv)
         }
         FreeLibrary(hHookDll);
         hHookDll = NULL;
-
-        if (hookRc == FALSE)
-        {
-            ServiceStatus.dwCurrentState = SERVICE_STOPPED;
-            ServiceStatus.dwWin32ExitCode = NO_ERROR;
-            ServiceStatus.dwCheckPoint = 0;
-            ServiceStatus.dwWaitHint = 0;
-            ServiceStatus.dwControlsAccepted = 0;
-            SetServiceStatus(StatusHandle, &ServiceStatus);
-                       
-            /* exit if initialization failed */
-            return;
-        }
     }
 
 
@@ -1401,7 +1453,9 @@ afsd_Main(DWORD argc, LPTSTR *argv)
                                          
     cm_DaemonShutdown();                 
     afsi_log("Daemon shutdown complete");
-                                         
+    
+    afsd_ShutdownCM();
+
     buf_Shutdown();                      
     afsi_log("Buffer shutdown complete");
                                          
@@ -1409,7 +1463,7 @@ afsd_Main(DWORD argc, LPTSTR *argv)
     afsi_log("rx finalization complete");
                                          
 #ifndef AFSIFS
-       smb_Shutdown();                      
+    smb_Shutdown();                      
     afsi_log("smb shutdown complete");   
 #endif
                                          
@@ -1428,6 +1482,17 @@ afsd_Main(DWORD argc, LPTSTR *argv)
         PowerNotificationThreadExit();
 #endif
 
+    cm_DirDumpStats();
+#ifdef USE_BPLUS
+    cm_BPlusDumpStats();
+#endif
+
+    /* Notify any Volume Status Handlers that we are stopped */
+    cm_VolStatus_Service_Stopped();
+
+    /* Cleanup any Volume Status Notification Handler */
+    cm_VolStatus_Finalize();
+
     /* allow an exit to be called after stopping the service */
     hHookDll = LoadLibrary(AFSD_HOOK_DLL);
     if (hHookDll)
@@ -1447,7 +1512,7 @@ afsd_Main(DWORD argc, LPTSTR *argv)
 
     ServiceStatus.dwCurrentState = SERVICE_STOPPED;
     ServiceStatus.dwWin32ExitCode = GlobalStatus ? ERROR_EXCEPTION_IN_SERVICE : NO_ERROR;
-    ServiceStatus.dwCheckPoint = 0;
+    ServiceStatus.dwCheckPoint = 7;
     ServiceStatus.dwWaitHint = 0;
     ServiceStatus.dwControlsAccepted = 0;
     SetServiceStatus(StatusHandle, &ServiceStatus);