From: Jeffrey Altman Date: Thu, 10 Jan 2008 23:48:02 +0000 (+0000) Subject: windows-smb-synchronization-20080110 X-Git-Tag: BP-openafs-windows-kdfs-ifs~211 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=8b82cbeef760992c6e3d27f9f6ea1f4e0bb559ab;p=packages%2Fo%2Fopenafs.git windows-smb-synchronization-20080110 LICENSE MIT 1. prevent stopping the smb_Listeners due to an ip addr change when the LANA is determined either by registry assignment or loopback detection 2. add synchronization logic to prevent smb_Listener restarts prior to smb_Listener thread stoppage 3. no longer permit panics from smb_Listener threads 4. move the probe logic from cm_IPAddrDaemon thread to the cm_Daemon thread in order to avoid the loss of ip addr change events. If an adapter stops and restarts fast enough there might not be anything for us to do. --- diff --git a/src/WINNT/afsd/cm_daemon.c b/src/WINNT/afsd/cm_daemon.c index f8d014dc0..4e9818d0c 100644 --- a/src/WINNT/afsd/cm_daemon.c +++ b/src/WINNT/afsd/cm_daemon.c @@ -46,6 +46,7 @@ cm_bkgRequest_t *cm_bkgListEndp; /* last elt in the list of requests */ static int daemon_ShutdownFlag = 0; static int cm_nDaemons = 0; +static time_t lastIPAddrChange = 0; static EVENT_HANDLE cm_Daemon_ShutdownEvent = NULL; static EVENT_HANDLE cm_IPAddrDaemon_ShutdownEvent = NULL; @@ -69,17 +70,9 @@ void cm_IpAddrDaemon(long parm) thrd_SetEvent(cm_IPAddrDaemon_ShutdownEvent); Result = NotifyAddrChange(NULL,NULL); if (Result == NO_ERROR && daemon_ShutdownFlag == 0) { + lastIPAddrChange = osi_Time(); smb_SetLanAdapterChangeDetected(); thrd_ResetEvent(cm_IPAddrDaemon_ShutdownEvent); - Sleep(2500); - if (daemon_ShutdownFlag == 0) { - osi_Log0(afsd_logp, "cm_IpAddrDaemon CheckDownServers"); - cm_CheckServers(CM_FLAG_CHECKVLDBSERVERS | CM_FLAG_CHECKUPSERVERS | CM_FLAG_CHECKDOWNSERVERS, NULL); - cm_ForceNewConnectionsAllServers(); - cm_CheckServers(CM_FLAG_CHECKFILESERVERS | CM_FLAG_CHECKUPSERVERS | CM_FLAG_CHECKDOWNSERVERS, NULL); - smb_CheckVCs(); - cm_VolStatus_Network_Addr_Change(); - } } } @@ -349,6 +342,7 @@ void cm_Daemon(long parm) HMODULE hHookDll; char * name = "cm_Daemon_ShutdownEvent"; int configureFirewall = IsWindowsFirewallPresent(); + int bAddrChangeCheck = 0; cm_Daemon_ShutdownEvent = thrd_CreateEvent(NULL, FALSE, FALSE, name); if ( GetLastError() == ERROR_ALREADY_EXISTS ) @@ -423,9 +417,18 @@ void cm_Daemon(long parm) /* find out what time it is */ now = osi_Time(); + + /* Determine whether an address change took place that we need to respond to */ + if (bAddrChangeCheck) + bAddrChangeCheck = 0; + + if (lastIPAddrChange != 0 && lastIPAddrChange + 2500 < now) { + bAddrChangeCheck = 1; + lastIPAddrChange = 0; + } /* check down servers */ - if (now > lastDownServerCheck + cm_daemonCheckDownInterval && + if ((bAddrChangeCheck || now > lastDownServerCheck + cm_daemonCheckDownInterval) && daemon_ShutdownFlag == 0) { lastDownServerCheck = now; osi_Log0(afsd_logp, "cm_Daemon CheckDownServers"); @@ -435,8 +438,11 @@ void cm_Daemon(long parm) now = osi_Time(); } + if (bAddrChangeCheck) + cm_ForceNewConnectionsAllServers(); + /* check up servers */ - if (now > lastUpServerCheck + cm_daemonCheckUpInterval && + if ((bAddrChangeCheck || now > lastUpServerCheck + cm_daemonCheckUpInterval) && daemon_ShutdownFlag == 0) { lastUpServerCheck = now; osi_Log0(afsd_logp, "cm_Daemon CheckUpServers"); @@ -446,6 +452,11 @@ void cm_Daemon(long parm) now = osi_Time(); } + if (bAddrChangeCheck) { + smb_CheckVCs(); + cm_VolStatus_Network_Addr_Change(); + } + if (now > lastVolCheck + cm_daemonCheckVolInterval && daemon_ShutdownFlag == 0) { lastVolCheck = now; @@ -465,7 +476,7 @@ void cm_Daemon(long parm) now = osi_Time(); } - if (now > lastBusyVolCheck + cm_daemonCheckOfflineVolInterval && + if ((bAddrChangeCheck || now > lastBusyVolCheck + cm_daemonCheckOfflineVolInterval) && daemon_ShutdownFlag == 0) { lastVolCheck = now; cm_CheckOfflineVolumes(); diff --git a/src/WINNT/afsd/smb.c b/src/WINNT/afsd/smb.c index 31d981cf3..7372052d1 100644 --- a/src/WINNT/afsd/smb.c +++ b/src/WINNT/afsd/smb.c @@ -93,6 +93,7 @@ EVENT_HANDLE NCBavails[NCB_MAX], NCBevents[NCB_MAX]; EVENT_HANDLE **NCBreturns; EVENT_HANDLE **NCBShutdown; EVENT_HANDLE *smb_ServerShutdown; +EVENT_HANDLE ListenerShutdown[256]; DWORD NCBsessions[NCB_MAX]; NCB *NCBs[NCB_MAX]; struct smb_packet *bufs[NCB_MAX]; @@ -103,7 +104,6 @@ unsigned short LSNs[SESSION_MAX]; int lanas[SESSION_MAX]; BOOL dead_sessions[SESSION_MAX]; LANA_ENUM lana_list; - /* for raw I/O */ osi_mutex_t smb_RawBufLock; char *smb_RawBufs; @@ -8059,6 +8059,12 @@ void smb_Listener(void *parmp) char cname[MAX_COMPUTERNAME_LENGTH+1]; int cnamelen = MAX_COMPUTERNAME_LENGTH+1; INT_PTR lana = (INT_PTR) parmp; + char eventName[MAX_PATH]; + + sprintf(eventName,"smb_Listener_lana_%d", (char)lana); + ListenerShutdown[lana] = thrd_CreateEvent(NULL, FALSE, FALSE, eventName); + if ( GetLastError() == ERROR_ALREADY_EXISTS ) + thrd_ResetEvent(ListenerShutdown[lana]); ncbp = GetNCB(); @@ -8087,30 +8093,35 @@ void smb_Listener(void *parmp) code = Netbios(ncbp); if (code == NRC_NAMERR) { - /* An smb shutdown must have taken place */ + /* An smb shutdown or Vista resume must have taken place */ osi_Log2(smb_logp, "NCBLISTEN lana=%d failed with NRC_NAMERR.", ncbp->ncb_lana_num, code); - continue; - } else if (code == NRC_BRIDGE) { - int lanaRemaining = 0; - lock_ObtainMutex(&smb_StartedLock); - if (smb_ListenerState == SMB_LISTENER_STOPPED || smbShutdownFlag == 1) { + if (lock_TryMutex(&smb_StartedLock)) { + lana_list.lana[i] = LANA_INVALID; lock_ReleaseMutex(&smb_StartedLock); - ExitThread(1); } + break; + } else if (code == NRC_BRIDGE || code != 0) { + int lanaRemaining = 0; - osi_Log2(smb_logp, - "NCBLISTEN lana=%d failed with NRC_BRIDGE. Listener thread exiting.", - ncbp->ncb_lana_num, code); + while (!lock_TryMutex(&smb_StartedLock)) { + if (smb_ListenerState == SMB_LISTENER_STOPPED || smbShutdownFlag == 1) + goto exit_thread; + Sleep(50); + } + + osi_Log2(smb_logp, + "NCBLISTEN lana=%d failed with %s. Listener thread exiting.", + ncbp->ncb_lana_num, ncb_error_string(code)); for (i = 0; i < lana_list.length; i++) { - if (lana_list.lana[i] == ncbp->ncb_lana_num) { - smb_StopListener(ncbp, lana_list.lana[i]); - lana_list.lana[i] = 255; + if (lana_list.lana[i] == lana) { + smb_StopListener(ncbp, lana_list.lana[i], FALSE); + lana_list.lana[i] = LANA_INVALID; } - if (lana_list.lana[i] != 255) + if (lana_list.lana[i] != LANA_INVALID) lanaRemaining++; } @@ -8124,15 +8135,18 @@ void smb_Listener(void *parmp) smb_LANadapter = LANA_INVALID; lana_list.length = 0; } - FreeNCB(ncbp); lock_ReleaseMutex(&smb_StartedLock); - return; - } else if (code != 0) { + break; + } +#if 0 + else if (code != 0) { char tbuffer[AFSPATHMAX]; /* terminate silently if shutdown flag is set */ - if (smb_ListenerState == SMB_LISTENER_STOPPED || smbShutdownFlag == 1) { - ExitThread(1); + while (!lock_TryMutex(&smb_StartedLock)) { + if (smb_ListenerState == SMB_LISTENER_STOPPED || smbShutdownFlag == 1) + goto exit_thread; + Sleep(50); } osi_Log3(smb_logp, @@ -8149,7 +8163,11 @@ void smb_Listener(void *parmp) code = (*smb_MBfunc)(NULL, tbuffer, "AFS Client Service: Fatal Error", MB_OK|MB_SERVICE_NOTIFICATION); osi_panic(tbuffer, __FILE__, __LINE__); + + lock_ReleaseMutex(&smb_StartedLock); + break; } +#endif /* 0 */ /* check for remote conns */ /* first get remote name and insert null terminator */ @@ -8329,7 +8347,10 @@ void smb_Listener(void *parmp) lock_ReleaseMutex(&smb_ListenerLock); } /* dispatch while loop */ +exit_thread: FreeNCB(ncbp); + thrd_SetEvent(ListenerShutdown[lana]); + return; } void smb_SetLanAdapterChangeDetected(void) @@ -8358,10 +8379,9 @@ void smb_LanAdapterChange(int locked) { if (!powerStateSuspended && SUCCEEDED(lana_GetUncServerNameEx(NetbiosName, &lanaNum, &bGateway, - LANA_NETBIOS_NAME_FULL))) { - - if ( lanaNum != LANA_INVALID && smb_LANadapter != lanaNum || - isGateway != bGateway || + LANA_NETBIOS_NAME_FULL)) && + lanaNum != LANA_INVALID && smb_LANadapter != lanaNum) { + if ( isGateway != bGateway || strcmp(cm_NetbiosName, NetbiosName) ) { change = 1; } else { @@ -8476,7 +8496,7 @@ int smb_NetbiosInit(int locked) code = ncbp->ncb_retcode; if (code != 0) { afsi_log("Netbios NCBRESET lana %d error code %d", lana_list.lana[i], code); - lana_list.lana[i] = 255; /* invalid lana */ + lana_list.lana[i] = LANA_INVALID; /* invalid lana */ } else { afsi_log("Netbios NCBRESET lana %d succeeded", lana_list.lana[i]); } @@ -8516,7 +8536,7 @@ int smb_NetbiosInit(int locked) else { afsi_log("Netbios NCBADDNAME lana %d error code %d", lana, code); if (code == NRC_BRIDGE) { /* invalid LANA num */ - lana_list.lana[l] = 255; + lana_list.lana[l] = LANA_INVALID; continue; } else if (code == NRC_DUPNAME) { @@ -8532,7 +8552,7 @@ int smb_NetbiosInit(int locked) afsi_log("Netbios NCBDELNAME lana %d error code %d\n", lana, code); } if (code != 0 || delname_tried) { - lana_list.lana[l] = 255; + lana_list.lana[l] = LANA_INVALID; } else if (code == 0) { if (!delname_tried) { @@ -8544,7 +8564,7 @@ int smb_NetbiosInit(int locked) } else { afsi_log("Netbios NCBADDNAME lana %d error code %d", lana, code); - lana_list.lana[l] = 255; /* invalid lana */ + lana_list.lana[l] = LANA_INVALID; /* invalid lana */ } } if (code == 0) { @@ -8603,7 +8623,7 @@ void smb_StartListeners(int locked) ); for (i = 0; i < lana_list.length; i++) { - if (lana_list.lana[i] == 255) + if (lana_list.lana[i] == LANA_INVALID) continue; phandle = thrd_Create(NULL, 65536, (ThreadFunc) smb_Listener, (void*)lana_list.lana[i], 0, &lpid, "smb_Listener"); @@ -8631,7 +8651,7 @@ void smb_RestartListeners(int locked) lock_ReleaseMutex(&smb_StartedLock); } -void smb_StopListener(NCB *ncbp, int lana) +void smb_StopListener(NCB *ncbp, int lana, int wait) { long code; @@ -8657,6 +8677,9 @@ void smb_StopListener(NCB *ncbp, int lana) } else { afsi_log("Netbios NCBRESET lana %d succeeded", lana); } + + if (wait) + thrd_WaitForSingleObject_Event(ListenerShutdown[lana], INFINITE); } void smb_StopListeners(int locked) @@ -8687,11 +8710,11 @@ void smb_StopListeners(int locked) for (l = 0; l < lana_list.length; l++) { lana = lana_list.lana[l]; - if (lana != 255) { - smb_StopListener(ncbp, lana); + if (lana != LANA_INVALID) { + smb_StopListener(ncbp, lana, TRUE); /* mark the adapter invalid */ - lana_list.lana[l] = 255; /* invalid lana */ + lana_list.lana[l] = LANA_INVALID; /* invalid lana */ } } @@ -8701,7 +8724,6 @@ void smb_StopListeners(int locked) FreeNCB(ncbp); if (!locked) lock_ReleaseMutex(&smb_StartedLock); - Sleep(1000); /* give the listener threads a chance to exit */ } void smb_Init(osi_log_t *logp, int useV3, @@ -9127,7 +9149,7 @@ void smb_Shutdown(void) /* Delete Netbios name */ memset((char *)ncbp, 0, sizeof(NCB)); for (i = 0; i < lana_list.length; i++) { - if (lana_list.lana[i] == 255) continue; + if (lana_list.lana[i] == LANA_INVALID) continue; ncbp->ncb_command = NCBDELNAME; ncbp->ncb_lana_num = lana_list.lana[i]; memcpy(ncbp->ncb_name,smb_sharename,NCBNAMSZ); diff --git a/src/WINNT/afsd/smb.h b/src/WINNT/afsd/smb.h index f8f89801b..7abdf5709 100644 --- a/src/WINNT/afsd/smb.h +++ b/src/WINNT/afsd/smb.h @@ -732,7 +732,7 @@ extern void smb_SetRequestStartTime(void); extern void smb_ResetServerPriority(void); extern void smb_RestartListeners(int); extern void smb_StopListeners(int); -extern void smb_StopListener(NCB *ncbp, int lana); +extern void smb_StopListener(NCB *ncbp, int lana, int wait); extern long smb_IsNetworkStarted(void); extern void smb_LanAdapterChange(int); extern void smb_SetLanAdapterChangeDetected(void);