// // Thread Creation // BOOL PowerNotificationThreadCreate() { BOOL bSuccess = FALSE; DWORD dwThreadId = 0; char eventName[MAX_PATH]; do { // create power event notification event // bManualReset=TRUE, bInitialState=FALSE gThreadInfo.hEventPowerEvent = CreateEvent(NULL, TRUE, FALSE, TEXT("afsd_flushvol_EventPowerEvent")); if ( GetLastError() == ERROR_ALREADY_EXISTS ) afsi_log("Event Object Already Exists: %s", eventName); if (gThreadInfo.hEventPowerEvent == NULL) break; // create mainline resume event // bManualReset=FALSE, bInitialState=FALSE gThreadInfo.hEventResumeMain = CreateEvent(NULL, FALSE, FALSE, TEXT("afsd_flushvol_EventResumeMain")); if ( GetLastError() == ERROR_ALREADY_EXISTS ) afsi_log("Event Object Already Exists: %s", eventName); if (gThreadInfo.hEventResumeMain == NULL) break; // create thread terminate event // bManualReset=FALSE, bInitialState=FALSE gThreadInfo.hEventTerminate = CreateEvent(NULL, FALSE, FALSE, TEXT("afsd_flushvol_EventTerminate")); if ( GetLastError() == ERROR_ALREADY_EXISTS ) afsi_log("Event Object Already Exists: %s", eventName); if (gThreadInfo.hEventTerminate == NULL) break; // good so far - create thread gThreadHandle = CreateThread(NULL, 0, afsd_ServiceFlushVolumesThreadProc, (LPVOID) &gThreadInfo, 0, &dwThreadId); if (!gThreadHandle) break; bSuccess = TRUE; } while (0); if (!bSuccess) { CheckAndCloseHandle(gThreadInfo.hEventPowerEvent); CheckAndCloseHandle(gThreadInfo.hEventResumeMain); CheckAndCloseHandle(gThreadInfo.hEventTerminate); CheckAndCloseHandle(gThreadHandle); } return bSuccess; }
extern "C" lana_number_t lana_FindLoopback(void) { NCB ncb; LANA_ENUM lana_list; int status; int i; memset(&ncb, 0, sizeof(ncb)); ncb.ncb_command = NCBENUM; ncb.ncb_buffer = (UCHAR *) &lana_list; ncb.ncb_length = sizeof(lana_list); status = Netbios(&ncb); if (status != 0) { #ifndef NOLOGGING afsi_log("Netbios NCBENUM failed: status %ld", status); #endif return LANA_INVALID; } for (i = 0; i < lana_list.length; i++) { if (lana_IsLoopback(lana_list.lana[i],TRUE)) { // Found one, return it. #ifndef NOLOGGING afsi_log("lana_FindLoopback: Found LAN adapter %d", lana_list.lana[i]); #endif return lana_list.lana[i]; } } // Could not find a loopback adapter. return LANA_INVALID; }
static int IsWindowsFirewallPresent(void) { SC_HANDLE scm; SC_HANDLE svc; BOOLEAN flag; BOOLEAN result = FALSE; LPQUERY_SERVICE_CONFIG pConfig = NULL; DWORD BufSize; LONG status; /* Open services manager */ scm = OpenSCManager(NULL, NULL, GENERIC_READ); if (!scm) return FALSE; /* Open Windows Firewall service */ 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; /* Query Windows Firewall service config, first just to get buffer size */ /* Expected to fail, so don't test return value */ (void) QueryServiceConfig(svc, NULL, 0, &BufSize); status = GetLastError(); if (status != ERROR_INSUFFICIENT_BUFFER) goto close_svc; /* Allocate buffer */ pConfig = (LPQUERY_SERVICE_CONFIG)GlobalAlloc(GMEM_FIXED,BufSize); if (!pConfig) goto close_svc; /* Query Windows Firewall service config, this time for real */ flag = QueryServiceConfig(svc, pConfig, BufSize, &BufSize); 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; free_pConfig: GlobalFree(pConfig); close_svc: CloseServiceHandle(svc); close_scm: CloseServiceHandle(scm); return result; }
/* Returns TRUE if all adapters are loopback adapters */ extern "C" BOOL lana_OnlyLoopback(void) { NCB ncb; LANA_ENUM lana_list; int status; int i; memset(&ncb, 0, sizeof(ncb)); ncb.ncb_command = NCBENUM; ncb.ncb_buffer = (UCHAR *) &lana_list; ncb.ncb_length = sizeof(lana_list); status = Netbios(&ncb); if (status != 0) { #ifndef NOLOGGING afsi_log("Netbios NCBENUM failed: status %ld", status); #endif return FALSE; } for (i = 0; i < lana_list.length; i++) { if (!lana_IsLoopback(lana_list.lana[i],FALSE)) { // Found one non-Loopback adapter return FALSE; } } // All adapters are loopback return TRUE; }
void cm_IpAddrDaemon(long parm) { extern void smb_CheckVCs(void); char * name = "cm_IPAddrDaemon_ShutdownEvent"; cm_IPAddrDaemon_ShutdownEvent = thrd_CreateEvent(NULL, FALSE, FALSE, name); if ( GetLastError() == ERROR_ALREADY_EXISTS ) afsi_log("Event Object Already Exists: %s", name); rx_StartClientThread(); while (daemon_ShutdownFlag == 0) { DWORD Result; thrd_SetEvent(cm_IPAddrDaemon_ShutdownEvent); Result = NotifyAddrChange(NULL,NULL); if (Result == NO_ERROR && daemon_ShutdownFlag == 0) { lastIPAddrChange = osi_Time(); smb_SetLanAdapterChangeDetected(); cm_SetLanAdapterChangeDetected(); thrd_ResetEvent(cm_IPAddrDaemon_ShutdownEvent); } } thrd_SetEvent(cm_IPAddrDaemon_ShutdownEvent); }
///////////////////////////////////////////////////////////////////// // // Call routine found in FS.EXE to flush volume. // // At entry, input param is UNC string for volume, // e.g. '\\afs\all\athena.mit.edu\user\m\h\mholiday' // // I believe that success from 'pioctl' routine // indicated by return value of zero (0). // afs_int32 afsd_ServicePerformFlushVolumeCmd(char *data) { afs_int32 code; struct ViceIoctl blob; afsi_log("Flushing Volume \"%s\"",data); memset(&blob, '\0', sizeof(blob)); code = pioctl(data, VIOC_FLUSHVOLUME, &blob, 0); return code; }
long cm_ValidateCell(void) { cm_cell_t * cellp; afs_uint32 count1, count2; for (cellp = cm_data.allCellsp, count1 = 0; cellp; cellp=cellp->allNextp, count1++) { if ( cellp->magic != CM_CELL_MAGIC ) { afsi_log("cm_ValidateCell failure: cellp->magic != CM_CELL_MAGIC"); fprintf(stderr, "cm_ValidateCell failure: cellp->magic != CM_CELL_MAGIC\n"); return -1; } if ( count1 != 0 && cellp == cm_data.allCellsp || count1 > cm_data.maxCells ) { afsi_log("cm_ValidateCell failure: cm_data.allCellsp infinite loop"); fprintf(stderr, "cm_ValidateCell failure: cm_data.allCellsp infinite loop\n"); return -2; } } for (cellp = cm_data.freeCellsp, count2 = 0; cellp; cellp=cellp->freeNextp, count2++) { if ( count2 != 0 && cellp == cm_data.freeCellsp || count2 > cm_data.maxCells ) { afsi_log("cm_ValidateCell failure: cm_data.freeCellsp infinite loop"); fprintf(stderr, "cm_ValidateCell failure: cm_data.freeCellsp infinite loop\n"); return -3; } } if ( (count1 + count2) != cm_data.currentCells ) { afsi_log("cm_ValidateCell failure: count != cm_data.currentCells"); fprintf(stderr, "cm_ValidateCell failure: count != cm_data.currentCells\n"); return -4; } return 0; }
/* periodic lock check daemon */ void * cm_LockDaemon(void * vparm) { time_t now; time_t lastLockCheck; char * name = "cm_LockDaemon_ShutdownEvent"; cm_LockDaemon_ShutdownEvent = thrd_CreateEvent(NULL, FALSE, FALSE, name); if ( GetLastError() == ERROR_ALREADY_EXISTS ) afsi_log("Event Object Already Exists: %s", name); now = osi_Time(); lastLockCheck = now - cm_daemonCheckLockInterval/2 + (rand() % cm_daemonCheckLockInterval); while (daemon_ShutdownFlag == 0) { if (powerStateSuspended) { Sleep(1000); continue; } now = osi_Time(); if (now > lastLockCheck + cm_daemonCheckLockInterval && daemon_ShutdownFlag == 0 && powerStateSuspended == 0) { lastLockCheck = now; cm_CheckLocks(); if (daemon_ShutdownFlag == 1) break; } thrd_Sleep(1000); /* sleep 1 second */ } thrd_SetEvent(cm_LockDaemon_ShutdownEvent); pthread_exit(NULL); return NULL; }
long RpcInit() { LONG status = ERROR_SUCCESS; HANDLE listenThread; ULONG listenThreadID = 0; char * name = "afsd_rpc_ShutdownEvent"; lock_InitializeMutex(&tokenEventLock, "token event lock", LOCK_HIERARCHY_TOKEN_EVENT_GLOBAL); rpc_ShutdownEvent = thrd_CreateEvent(NULL, FALSE, FALSE, name); if ( GetLastError() == ERROR_ALREADY_EXISTS ) afsi_log("Event Object Already Exists: %s", name); listenThread = CreateThread(NULL, 0, (PTHREAD_START_ROUTINE)RpcListen, 0, 0, &listenThreadID); if (listenThread == NULL) { status = GetLastError(); } CloseHandle(listenThread); return status; }
/* periodic check daemon */ void cm_Daemon(long parm) { time_t now; time_t lastLockCheck; time_t lastVolCheck; time_t lastCBExpirationCheck; time_t lastVolCBRenewalCheck; time_t lastDownServerCheck; time_t lastUpServerCheck; time_t lastTokenCacheCheck; time_t lastBusyVolCheck; time_t lastPerformanceCheck; time_t lastServerRankCheck; char thostName[200]; unsigned long code; struct hostent *thp; 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 ) afsi_log("Event Object Already Exists: %s", name); if (!configureFirewall) { afsi_log("No Windows Firewall detected"); } if (cm_freelanceEnabled && cm_freelanceImportCellServDB) cm_FreelanceImportCellServDB(); /* 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. */ /* * Seed the random number generator with our own address, so that * clients starting at the same time don't all do vol checks at the * same time. */ gethostname(thostName, sizeof(thostName)); thp = gethostbyname(thostName); if (thp == NULL) /* In djgpp, gethostname returns the netbios name of the machine. gethostbyname will fail looking this up if it differs from DNS name. */ code = 0; else memcpy(&code, thp->h_addr_list[0], 4); srand(ntohl(code)); cm_DaemonCheckInit(); now = osi_Time(); lastVolCheck = now - cm_daemonCheckVolInterval/2 + (rand() % cm_daemonCheckVolInterval); lastCBExpirationCheck = now - cm_daemonCheckCBInterval/2 + (rand() % cm_daemonCheckCBInterval); if (cm_daemonCheckVolCBInterval) 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); lastTokenCacheCheck = now - cm_daemonTokenCheckInterval/2 + (rand() % cm_daemonTokenCheckInterval); lastBusyVolCheck = now - cm_daemonCheckOfflineVolInterval/2 * (rand() % cm_daemonCheckOfflineVolInterval); if (cm_daemonPerformanceTuningInterval) lastPerformanceCheck = now - cm_daemonPerformanceTuningInterval/2 * (rand() % cm_daemonPerformanceTuningInterval); lastServerRankCheck = now - cm_daemonRankServerInterval/2 * (rand() % cm_daemonRankServerInterval); while (daemon_ShutdownFlag == 0) { if (powerStateSuspended) { Sleep(1000); continue; } /* check to see if the listener threads halted due to network * disconnect or other issues. If so, attempt to restart them. */ smb_RestartListeners(0); if (daemon_ShutdownFlag == 1) break; if (configureFirewall) { /* Open Microsoft Firewall to allow in port 7001 */ switch (icf_CheckAndAddAFSPorts(AFS_PORTSET_CLIENT)) { case 0: afsi_log("Windows Firewall Configuration succeeded"); configureFirewall = 0; break; case 1: afsi_log("Invalid Windows Firewall Port Set"); break; case 2: afsi_log("Unable to open Windows Firewall Profile"); break; case 3: afsi_log("Unable to create/modify Windows Firewall Port entries"); break; default: afsi_log("Unknown Windows Firewall Configuration error"); } } /* 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 ((bAddrChangeCheck || now > lastDownServerCheck + cm_daemonCheckDownInterval) && daemon_ShutdownFlag == 0 && powerStateSuspended == 0) { lastDownServerCheck = now; osi_Log0(afsd_logp, "cm_Daemon CheckDownServers"); cm_CheckServers(CM_FLAG_CHECKDOWNSERVERS, NULL); if (daemon_ShutdownFlag == 1) break; now = osi_Time(); } if (bAddrChangeCheck && daemon_ShutdownFlag == 0 && powerStateSuspended == 0) cm_ForceNewConnectionsAllServers(); /* check up servers */ if ((bAddrChangeCheck || now > lastUpServerCheck + cm_daemonCheckUpInterval) && daemon_ShutdownFlag == 0 && powerStateSuspended == 0) { lastUpServerCheck = now; osi_Log0(afsd_logp, "cm_Daemon CheckUpServers"); cm_CheckServers(CM_FLAG_CHECKUPSERVERS, NULL); if (daemon_ShutdownFlag == 1) break; now = osi_Time(); } if (bAddrChangeCheck && daemon_ShutdownFlag == 0 && powerStateSuspended == 0) { smb_CheckVCs(); cm_VolStatus_Network_Addr_Change(); } if (now > lastVolCheck + cm_daemonCheckVolInterval && daemon_ShutdownFlag == 0 && powerStateSuspended == 0) { lastVolCheck = now; cm_RefreshVolumes(); if (daemon_ShutdownFlag == 1) break; now = osi_Time(); } /* Rank all up servers */ if ((now > lastServerRankCheck + cm_daemonRankServerInterval) && daemon_ShutdownFlag == 0 && powerStateSuspended == 0) { lastServerRankCheck = now; osi_Log0(afsd_logp, "cm_Daemon RankServer"); cm_RankUpServers(); if(daemon_ShutdownFlag == 1) break; now = osi_Time(); } if (cm_daemonCheckVolCBInterval && now > lastVolCBRenewalCheck + cm_daemonCheckVolCBInterval && daemon_ShutdownFlag == 0 && powerStateSuspended == 0) { lastVolCBRenewalCheck = now; cm_VolumeRenewROCallbacks(); if (daemon_ShutdownFlag == 1) break; now = osi_Time(); } if ((bAddrChangeCheck || now > lastBusyVolCheck + cm_daemonCheckOfflineVolInterval) && daemon_ShutdownFlag == 0 && powerStateSuspended == 0) { lastVolCheck = now; cm_CheckOfflineVolumes(); if (daemon_ShutdownFlag == 1) break; now = osi_Time(); } if (now > lastCBExpirationCheck + cm_daemonCheckCBInterval && daemon_ShutdownFlag == 0 && powerStateSuspended == 0) { lastCBExpirationCheck = now; cm_CheckCBExpiration(); if (daemon_ShutdownFlag == 1) break; now = osi_Time(); } if (now > lastLockCheck + cm_daemonCheckLockInterval && daemon_ShutdownFlag == 0 && powerStateSuspended == 0) { lastLockCheck = now; cm_CheckLocks(); if (daemon_ShutdownFlag == 1) break; now = osi_Time(); } if (now > lastTokenCacheCheck + cm_daemonTokenCheckInterval && daemon_ShutdownFlag == 0 && powerStateSuspended == 0) { lastTokenCacheCheck = now; cm_CheckTokenCache(now); if (daemon_ShutdownFlag == 1) break; now = osi_Time(); } /* allow an exit to be called prior to stopping the service */ hHookDll = cm_LoadAfsdHookLib(); if (hHookDll) { BOOL hookRc = TRUE; AfsdDaemonHook daemonHook = ( AfsdDaemonHook ) GetProcAddress(hHookDll, AFSD_DAEMON_HOOK); if (daemonHook) { hookRc = daemonHook(); } FreeLibrary(hHookDll); hHookDll = NULL; if (hookRc == FALSE) { SetEvent(WaitToTerminate); } if (daemon_ShutdownFlag == 1) { break; } now = osi_Time(); } if (cm_daemonPerformanceTuningInterval && now > lastPerformanceCheck + cm_daemonPerformanceTuningInterval && daemon_ShutdownFlag == 0 && powerStateSuspended == 0) { lastPerformanceCheck = now; cm_PerformanceTuningCheck(); if (daemon_ShutdownFlag == 1) break; now = osi_Time(); } thrd_Sleep(10000); /* sleep 10 seconds */ } thrd_SetEvent(cm_Daemon_ShutdownEvent); }
void cm_DaemonCheckInit(void) { HKEY parmKey; DWORD dummyLen; DWORD dummy; DWORD code; code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY, 0, KEY_QUERY_VALUE, &parmKey); if (code) return; dummyLen = sizeof(DWORD); code = RegQueryValueEx(parmKey, "daemonCheckDownInterval", NULL, NULL, (BYTE *) &dummy, &dummyLen); if (code == ERROR_SUCCESS && dummy) cm_daemonCheckDownInterval = dummy; afsi_log("daemonCheckDownInterval is %d", cm_daemonCheckDownInterval); dummyLen = sizeof(DWORD); code = RegQueryValueEx(parmKey, "daemonCheckUpInterval", NULL, NULL, (BYTE *) &dummy, &dummyLen); if (code == ERROR_SUCCESS && dummy) cm_daemonCheckUpInterval = dummy; afsi_log("daemonCheckUpInterval is %d", cm_daemonCheckUpInterval); dummyLen = sizeof(DWORD); code = RegQueryValueEx(parmKey, "daemonCheckVolInterval", NULL, NULL, (BYTE *) &dummy, &dummyLen); if (code == ERROR_SUCCESS && dummy) cm_daemonCheckVolInterval = dummy; afsi_log("daemonCheckVolInterval is %d", cm_daemonCheckVolInterval); dummyLen = sizeof(DWORD); code = RegQueryValueEx(parmKey, "daemonCheckCBInterval", NULL, NULL, (BYTE *) &dummy, &dummyLen); if (code == ERROR_SUCCESS && dummy) 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 && dummy) cm_daemonCheckVolCBInterval = dummy; afsi_log("daemonCheckVolCBInterval is %d", cm_daemonCheckVolCBInterval); dummyLen = sizeof(DWORD); code = RegQueryValueEx(parmKey, "daemonCheckLockInterval", NULL, NULL, (BYTE *) &dummy, &dummyLen); if (code == ERROR_SUCCESS && dummy) cm_daemonCheckLockInterval = dummy; afsi_log("daemonCheckLockInterval is %d", cm_daemonCheckLockInterval); dummyLen = sizeof(DWORD); code = RegQueryValueEx(parmKey, "daemonCheckTokenInterval", NULL, NULL, (BYTE *) &dummy, &dummyLen); if (code == ERROR_SUCCESS && dummy) cm_daemonTokenCheckInterval = dummy; afsi_log("daemonCheckTokenInterval is %d", cm_daemonTokenCheckInterval); dummyLen = sizeof(DWORD); code = RegQueryValueEx(parmKey, "daemonCheckOfflineVolInterval", NULL, NULL, (BYTE *) &dummy, &dummyLen); if (code == ERROR_SUCCESS && dummy) cm_daemonCheckOfflineVolInterval = dummy; afsi_log("daemonCheckOfflineVolInterval is %d", cm_daemonCheckOfflineVolInterval); dummyLen = sizeof(DWORD); code = RegQueryValueEx(parmKey, "daemonPerformanceTuningInterval", NULL, NULL, (BYTE *) &dummy, &dummyLen); dummyLen = sizeof(DWORD); code = RegQueryValueEx(parmKey, "daemonRankServerInterval", NULL, NULL, (BYTE *) &dummy, &dummyLen); if (code == ERROR_SUCCESS && dummy) cm_daemonRankServerInterval = dummy; afsi_log("daemonRankServerInterval is %d", cm_daemonRankServerInterval); if (code == ERROR_SUCCESS) cm_daemonPerformanceTuningInterval = dummy; afsi_log("daemonPerformanceTuningInterval is %d", cm_daemonPerformanceTuningInterval); RegCloseKey(parmKey); if (cm_daemonPerformanceTuningInterval) cm_PerformanceTuningInit(); }
long cm_ValidateACLCache(void) { long size = cm_data.stats * 2; long count; cm_aclent_t * aclp; if ( cm_data.aclLRUp == NULL && cm_data.aclLRUEndp != NULL || cm_data.aclLRUp != NULL && cm_data.aclLRUEndp == NULL) { afsi_log("cm_ValidateACLCache failure: inconsistent LRU pointers"); fprintf(stderr, "cm_ValidateACLCache failure: inconsistent LRU pointers\n"); return -9; } for ( aclp = cm_data.aclLRUp, count = 0; aclp; aclp = (cm_aclent_t *) osi_QNext(&aclp->q), count++ ) { if (aclp->magic != CM_ACLENT_MAGIC) { afsi_log("cm_ValidateACLCache failure: acpl->magic != CM_ACLENT_MAGIC"); fprintf(stderr, "cm_ValidateACLCache failure: acpl->magic != CM_ACLENT_MAGIC\n"); return -1; } if (aclp->nextp && aclp->nextp->magic != CM_ACLENT_MAGIC) { afsi_log("cm_ValidateACLCache failure: acpl->nextp->magic != CM_ACLENT_MAGIC"); fprintf(stderr,"cm_ValidateACLCache failure: acpl->nextp->magic != CM_ACLENT_MAGIC\n"); return -2; } if (aclp->backp && aclp->backp->magic != CM_SCACHE_MAGIC) { afsi_log("cm_ValidateACLCache failure: acpl->backp->magic != CM_SCACHE_MAGIC"); fprintf(stderr,"cm_ValidateACLCache failure: acpl->backp->magic != CM_SCACHE_MAGIC\n"); return -3; } if (count != 0 && aclp == cm_data.aclLRUp || count > size) { afsi_log("cm_ValidateACLCache failure: loop in cm_data.aclLRUp list"); fprintf(stderr, "cm_ValidateACLCache failure: loop in cm_data.aclLRUp list\n"); return -4; } } for ( aclp = cm_data.aclLRUEndp, count = 0; aclp; aclp = (cm_aclent_t *) osi_QPrev(&aclp->q), count++ ) { if (aclp->magic != CM_ACLENT_MAGIC) { afsi_log("cm_ValidateACLCache failure: aclp->magic != CM_ACLENT_MAGIC"); fprintf(stderr, "cm_ValidateACLCache failure: aclp->magic != CM_ACLENT_MAGIC\n"); return -5; } if (aclp->nextp && aclp->nextp->magic != CM_ACLENT_MAGIC) { afsi_log("cm_ValidateACLCache failure: aclp->nextp->magic != CM_ACLENT_MAGIC"); fprintf(stderr, "cm_ValidateACLCache failure: aclp->nextp->magic != CM_ACLENT_MAGIC\n"); return -6; } if (aclp->backp && aclp->backp->magic != CM_SCACHE_MAGIC) { afsi_log("cm_ValidateACLCache failure: aclp->backp->magic != CM_SCACHE_MAGIC"); fprintf(stderr, "cm_ValidateACLCache failure: aclp->backp->magic != CM_SCACHE_MAGIC\n"); return -7; } if (count != 0 && aclp == cm_data.aclLRUEndp || count > size) { afsi_log("cm_ValidateACLCache failure: loop in cm_data.aclLRUEndp list"); fprintf(stderr, "cm_ValidateACLCache failure: loop in cm_data.aclLRUEndp list\n"); return -8; } } return 0; }
// Is the given lana a Windows Loopback Adapter? // TODO: implement a better check for loopback // TODO: also check for proper bindings (IPv4) // For VMWare we only check the first five octets since the last one may vary extern "C" BOOL lana_IsLoopback(lana_number_t lana, BOOL reset) { NCB ncb; struct { ADAPTER_STATUS status; NAME_BUFFER names[MAX_LANA+1]; } astat; unsigned char kWLA_MAC[6] = { 0x02, 0x00, 0x4c, 0x4f, 0x4f, 0x50 }; unsigned char kVista_WLA_MAC[6] = { 0x7F, 0x00, 0x00, 0x01, 0x4f, 0x50 }; #ifdef USE_VMWARE unsigned char kVMWare_MAC[5] = { 0x00, 0x50, 0x56, 0xC0, 0x00 }; #endif int status; HKEY hkConfig; LONG rv; int regLana = -1; DWORD dummyLen; rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE,AFSREG_CLT_SVC_PARAM_SUBKEY,0,KEY_READ,&hkConfig); if (rv == ERROR_SUCCESS) { dummyLen = sizeof(regLana); rv = RegQueryValueEx(hkConfig, szForceLanaLoopback, NULL, NULL, (LPBYTE) ®Lana, &dummyLen); RegCloseKey(hkConfig); if (regLana == lana) return TRUE; } if (reset) { // Reset the adapter: in Win32, this is required for every process, and // acts as an init call, not as a real hardware reset. memset(&ncb, 0, sizeof(ncb)); ncb.ncb_command = NCBRESET; ncb.ncb_callname[0] = 100; ncb.ncb_callname[2] = 100; ncb.ncb_lana_num = lana; status = Netbios(&ncb); if (status == 0) status = ncb.ncb_retcode; if (status != 0) { #ifndef NOLOGGING afsi_log("NCBRESET failed: lana %u, status %ld", lana, status); #endif return FALSE; } } // Use the NCBASTAT command to get the adapter address. memset(&ncb, 0, sizeof(ncb)); ncb.ncb_command = NCBASTAT; ncb.ncb_lana_num = lana; strcpy((char *) ncb.ncb_callname, "* "); ncb.ncb_buffer = (UCHAR *) &astat; ncb.ncb_length = sizeof(astat); status = Netbios(&ncb); if (status == 0) status = ncb.ncb_retcode; if (ncb.ncb_retcode != 0) { #ifndef NOLOGGING afsi_log("NCBASTAT failed: lana %u, status %ld", lana, status); #endif return FALSE; } return (memcmp(astat.status.adapter_address, kWLA_MAC, 6) == 0 || memcmp(astat.status.adapter_address, kVista_WLA_MAC, 6) == 0 #ifdef USE_VMWARE || memcmp(astat.status.adapter_address, kVMWare_MAC, 5) == 0 #endif ); }
// Return an array of LANAINFOs corresponding to a connection named LanaName // (NULL LanaName matches all connections), and has an IPv4 binding. Returns // NULL if something goes wrong. // NOTE: caller must free the returned block if non NULL. extern "C" LANAINFO * lana_FindLanaByName(const char *LanaName) { const char RegNetBiosLinkageKeyName[] = "System\\CurrentControlSet\\Services\\NetBios\\Linkage"; HKEY hkey; LONG status; struct { BYTE flags; BYTE number; } lanamap[MAX_LANA+1]; DWORD lanamapsize = sizeof(lanamap); DWORD type; char *bindpaths = NULL; DWORD bindpathsize; int nlana; int i; char *guid; char *name; char *pBind; char *p; LANAINFO * lanainfo; // Open the NetBios Linkage key. status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, RegNetBiosLinkageKeyName, 0, KEY_QUERY_VALUE, &hkey); if (status != ERROR_SUCCESS) { #ifndef NOLOGGING afsi_log("Failed to open NetBios Linkage key (status %ld)", status); #endif return NULL; } // Read the lana map. status = RegQueryValueEx(hkey, "LanaMap", 0, &type, (BYTE *) &lanamap, &lanamapsize); if (status != ERROR_SUCCESS) { #ifndef NOLOGGING afsi_log("Failed to read LanaMap (status %ld)", status); #endif RegCloseKey(hkey); return NULL; } if (lanamapsize == 0) { #ifndef NOLOGGING afsi_log("No data in LanaMap"); #endif return NULL; } nlana = lanamapsize / sizeof(lanamap[0]); // Get the bind paths for NetBios so we can match them up // with the lana map. First we query for the size, so we // can allocate an appropriate buffer. status = RegQueryValueEx(hkey, "Bind", 0, &type, NULL, &bindpathsize); if (status == ERROR_SUCCESS && bindpathsize != 0) { bindpaths = (char *) malloc(bindpathsize * sizeof(char)); if (bindpaths == NULL) { #ifndef NOLOGGING afsi_log("Cannot allocate %ld bytes for bindpaths", bindpathsize); #endif RegCloseKey(hkey); return NULL; } status = RegQueryValueEx(hkey, "Bind", 0, &type, (BYTE *) bindpaths, &bindpathsize); } RegCloseKey(hkey); if (status != ERROR_SUCCESS) { #ifndef NOLOGGING afsi_log("Failed to read bind paths (status %ld)", status); #endif if (bindpaths != NULL) free(bindpaths); return NULL; } if (bindpathsize == 0) { #ifndef NOLOGGING afsi_log("No bindpath data"); #endif if (bindpaths != NULL) free(bindpaths); return NULL; } if (LanaName) { lanainfo = (LANAINFO *) malloc(sizeof(LANAINFO)*2); if(lanainfo == NULL) { free(bindpaths); return NULL; } memset(lanainfo, 0, sizeof(LANAINFO) * 2); lanainfo[0].lana_number = LANA_INVALID; } else { lanainfo = (LANAINFO *) malloc(sizeof(LANAINFO)*(nlana+1)); if(lanainfo == NULL) { free(bindpaths); return NULL; } memset(lanainfo, 0, sizeof(LANAINFO) * (nlana+1)); } int index = 0; // Iterate over the lana map entries and bind paths. for (i = 0, pBind = bindpaths; i < nlana; i++, pBind += strlen(pBind) + 1) { // Ignore an invalid map entry. if ((lanamap[i].flags & 1) == 0) continue; // check for an IPv4 binding if(!strstr(pBind,"_Tcpip_")) continue; // Find the beginning of the GUID. guid = strchr(pBind, '{'); if (guid == NULL) continue; // Malformed path entry? guid = strdup(guid); if (guid == NULL) continue; // Find the end of the GUID. p = strchr(guid, '}'); if (p == NULL) { free(guid); // Malformed GUID? continue; } *++p = '\0'; // Ignore anything after the GUID. status = lana_GetNameFromGuid(guid, &name); free(guid); if (status == 0 && name != 0) { if (LanaName) { if (strcmp(name, LanaName) ==0) { lanainfo[index].lana_number = lanamap[i].number; _tcscpy(lanainfo[index].lana_name, name); free(name); index++; break; } } else { lanainfo[index].lana_number = lanamap[i].number; _tcscpy(lanainfo[index].lana_name, name); free(name); index++; } } } lanainfo[index].lana_number = LANA_INVALID; free(bindpaths); return lanainfo; }
// Get the Connection Name for the given GUID. extern "C" int lana_GetNameFromGuid(char *Guid, char **Name) { typedef HRESULT (WINAPI *HrLanProcAddr)(GUID *, PCWSTR, PWSTR, LPDWORD); HrLanProcAddr HrLanProc = NULL; HMODULE hNetMan; int size; WCHAR *wGuid = NULL; WCHAR wName[MAX_PATH]; DWORD NameSize = MAX_PATH; char *name = NULL; HRESULT status; // Convert the Guid string to Unicode. First we ask only for the size // of the converted string. Then we allocate a buffer of sufficient // size to hold the result of the conversion. size = MultiByteToWideChar(CP_ACP, 0, Guid, -1, NULL, 0); wGuid = (WCHAR *) malloc(size * sizeof(WCHAR)); MultiByteToWideChar(CP_ACP, 0, Guid, -1, wGuid, size); // First try the IShellFolder interface, which was unimplemented // for the network connections folder before XP. /* XXX pbh 9/11/03 - revert to using the undocumented APIs on XP while * waiting to hear back from PSS about the slow reboot issue. * This is an ugly, misleading hack, but is minimally invasive * and will be easy to rollback. */ //status = getname_shellfolder(wGuid, wName, NameSize); status = E_NOTIMPL; /* XXX end of pbh 9/11/03 temporary hack*/ if (status == E_NOTIMPL) { // The IShellFolder interface is not implemented on this platform. // Try the (undocumented) HrLanConnectionNameFromGuidOrPath API // from the netman DLL. #ifndef NOLOGGING afsi_log("IShellFolder API not implemented, trying HrLanConnectionNameFromGuidOrPath"); #endif hNetMan = LoadLibrary("netman.dll"); if (hNetMan == NULL) { free(wGuid); return -1; } /* Super Secret Microsoft Call */ HrLanProc = (HrLanProcAddr) GetProcAddress(hNetMan, "HrLanConnectionNameFromGuidOrPath"); if (HrLanProc == NULL) { FreeLibrary(hNetMan); free(wGuid); return -1; } status = HrLanProc(NULL, wGuid, wName, &NameSize); FreeLibrary(hNetMan); } free(wGuid); if (FAILED(status)) { #ifndef NOLOGGING afsi_log("lana_GetNameFromGuid: failed to get connection name (status %ld)", status); #endif return -1; } // Get the required buffer size, and then convert the string. size = WideCharToMultiByte(CP_ACP, 0, wName, -1, NULL, 0, NULL, NULL); name = (char *) malloc(size); if (name == NULL) return -1; WideCharToMultiByte(CP_ACP, 0, wName, -1, name, size, NULL, NULL); #ifndef NOLOGGING afsi_log("Connection name for %s is '%s'", Guid, name); #endif if (*Name) *Name = name; else free(name); return 0; }
void RpcListen() { RPC_STATUS status; char *task; RPC_BINDING_VECTOR *ptrBindingVector = NULL; BOOLEAN ifaceRegistered = FALSE; BOOLEAN epRegistered = FALSE; #ifdef NOOSIDEBUGSERVER /* Use All Protseqs already done in OSI */ status = RpcServerUseAllProtseqs(1, NULL); if (status != RPC_S_OK) { task = "Use All Protocol Sequences"; goto cleanup; } #endif /* NOOSIDEBUGSERVER */ status = RpcServerRegisterIf(afsrpc_v1_0_s_ifspec, NULL, NULL); if (status != RPC_S_OK) { task = "Register Interface"; goto cleanup; } ifaceRegistered = TRUE; status = RpcServerInqBindings(&ptrBindingVector); if (status != RPC_S_OK) { task = "Inquire Bindings"; goto cleanup; } status = RpcServerRegisterAuthInfo(NULL, RPC_C_AUTHN_WINNT, NULL, NULL); if (status != RPC_S_OK) { task = "Register Authentication Info"; goto cleanup; } status = RpcEpRegister(afsrpc_v1_0_s_ifspec, ptrBindingVector, NULL, "AFS session key interface"); if (status != RPC_S_OK) { task = "Register Endpoints"; goto cleanup; } epRegistered = TRUE; afsi_log("RPC server listening"); status = RpcServerListen(OSI_MAXRPCCALLS, OSI_MAXRPCCALLS, 0); if (status != RPC_S_OK) { task = "Server Listen"; } cleanup: if (epRegistered) (void) RpcEpUnregister(afsrpc_v1_0_s_ifspec, ptrBindingVector, NULL); if (ptrBindingVector) (void) RpcBindingVectorFree(&ptrBindingVector); if (ifaceRegistered) (void) RpcServerUnregisterIf(afsrpc_v1_0_s_ifspec, NULL, FALSE); if (status != RPC_S_OK) afsi_log("RPC problem, code %d for %s", status, task); else afsi_log("RPC shutdown"); if (rpc_ShutdownEvent != NULL) thrd_SetEvent(rpc_ShutdownEvent); return; }
void cm_BkgDaemon(void * parm) { cm_bkgRequest_t *rp; afs_int32 code; char name[32] = ""; long daemonID = (long)parm; snprintf(name, sizeof(name), "cm_BkgDaemon_ShutdownEvent%d", daemonID); cm_BkgDaemon_ShutdownEvent[daemonID] = thrd_CreateEvent(NULL, FALSE, FALSE, name); if ( GetLastError() == ERROR_ALREADY_EXISTS ) afsi_log("Event Object Already Exists: %s", name); rx_StartClientThread(); lock_ObtainWrite(&cm_daemonLock); while (daemon_ShutdownFlag == 0) { if (powerStateSuspended) { Sleep(1000); continue; } if (!cm_bkgListEndp) { osi_SleepW((LONG_PTR)&cm_bkgListp, &cm_daemonLock); lock_ObtainWrite(&cm_daemonLock); continue; } /* we found a request */ for (rp = cm_bkgListEndp; rp; rp = (cm_bkgRequest_t *) osi_QPrev(&rp->q)) { if (cm_ServerAvailable(&rp->scp->fid, rp->userp) && !(rp->scp->flags & CM_SCACHEFLAG_DATASTORING)) 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_assertx(cm_bkgQueueCount-- > 0, "cm_bkgQueueCount 0"); lock_ReleaseWrite(&cm_daemonLock); 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 /* * Keep the following list synchronized with the * error code list in cm_BkgStore. * cm_SyncOpDone(CM_SCACHESYNC_ASYNCSTORE) will be called there unless * one of these errors has occurred. */ switch ( code ) { 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: if (rp->procp == cm_BkgStore) { osi_Log2(afsd_logp, "cm_BkgDaemon re-queueing failed request 0x%p code 0x%x", rp, code); lock_ObtainWrite(&cm_daemonLock); cm_bkgQueueCount++; osi_QAddT((osi_queue_t **) &cm_bkgListp, (osi_queue_t **)&cm_bkgListEndp, &rp->q); break; } /* otherwise fall through */ case 0: /* success */ default: /* other error */ if (code == 0) osi_Log1(afsd_logp,"cm_BkgDaemon SUCCESS: request 0x%p", rp); else osi_Log2(afsd_logp,"cm_BkgDaemon FAILED: request dropped 0x%p code 0x%x", rp, code); cm_ReleaseUser(rp->userp); cm_ReleaseSCache(rp->scp); free(rp); lock_ObtainWrite(&cm_daemonLock); } } lock_ReleaseWrite(&cm_daemonLock); thrd_SetEvent(cm_BkgDaemon_ShutdownEvent[daemonID]); }
void * cm_BkgDaemon(void * vparm) { cm_bkgRequest_t *rp; afs_int32 code; char name[32] = ""; long daemonID = (long)(LONG_PTR)vparm; snprintf(name, sizeof(name), "cm_BkgDaemon_ShutdownEvent%u", daemonID); cm_BkgDaemon_ShutdownEvent[daemonID] = thrd_CreateEvent(NULL, FALSE, FALSE, name); if ( GetLastError() == ERROR_ALREADY_EXISTS ) afsi_log("Event Object Already Exists: %s", name); rx_StartClientThread(); lock_ObtainWrite(&cm_daemonLockp[daemonID]); while (daemon_ShutdownFlag == 0) { int willBlock = 0; if (powerStateSuspended) { Sleep(1000); continue; } if (!cm_bkgListEndpp[daemonID]) { osi_SleepW((LONG_PTR)&cm_bkgListpp[daemonID], &cm_daemonLockp[daemonID]); lock_ObtainWrite(&cm_daemonLockp[daemonID]); continue; } /* we found a request */ for (rp = cm_bkgListEndpp[daemonID]; rp; rp = (cm_bkgRequest_t *) osi_QPrev(&rp->q)) { if (rp->scp->flags & CM_SCACHEFLAG_DELETED) break; /* * If the request has active I/O such that this worker would * be forced to block, leave the request in the queue and move * on to one that might be available for servicing. */ if (cm_RequestWillBlock(rp)) { willBlock++; continue; } if (cm_ServerAvailable(&rp->scp->fid, rp->userp)) break; } if (rp == NULL) { /* * Couldn't find a request that we could process at the * current time. If there were requests that would cause * the worker to block, sleep for 25ms so it can promptly * respond when it is available. Otherwise, sleep for 1s. * * This polling cycle needs to be replaced with a proper * producer/consumer dynamic worker pool. */ osi_Log2(afsd_logp,"cm_BkgDaemon[%u] sleeping %dms all tasks would block", daemonID, willBlock ? 100 : 1000); lock_ReleaseWrite(&cm_daemonLockp[daemonID]); Sleep(willBlock ? 100 : 1000); lock_ObtainWrite(&cm_daemonLockp[daemonID]); continue; } osi_QRemoveHT((osi_queue_t **) &cm_bkgListpp[daemonID], (osi_queue_t **) &cm_bkgListEndpp[daemonID], &rp->q); osi_assertx(cm_bkgQueueCountp[daemonID]-- > 0, "cm_bkgQueueCount 0"); lock_ReleaseWrite(&cm_daemonLockp[daemonID]); osi_Log2(afsd_logp,"cm_BkgDaemon[%u] processing request 0x%p", daemonID, rp); if (rp->scp->flags & CM_SCACHEFLAG_DELETED) { osi_Log2(afsd_logp,"cm_BkgDaemon[%u] DELETED scp 0x%x", daemonID, rp->scp); code = CM_ERROR_BADFD; } else { #ifdef DEBUG_REFCOUNT osi_Log3(afsd_logp,"cm_BkgDaemon[%u] (before) scp 0x%x ref %d", daemonID, rp->scp, rp->scp->refCount); #endif code = (*rp->procp)(rp->scp, rp->p1, rp->p2, rp->p3, rp->p4, rp->userp, &rp->req); #ifdef DEBUG_REFCOUNT osi_Log3(afsd_logp,"cm_BkgDaemon[%u] (after) scp 0x%x ref %d", daemonID, rp->scp, rp->scp->refCount); #endif } /* * Keep the following list synchronized with the * error code list in cm_BkgStore. * cm_SyncOpDone(CM_SCACHESYNC_ASYNCSTORE) will be called there unless * one of these errors has occurred. */ switch ( code ) { 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: if (rp->procp == cm_BkgStore || rp->procp == RDR_BkgFetch) { osi_Log3(afsd_logp, "cm_BkgDaemon[%u] re-queueing failed request 0x%p code 0x%x", daemonID, rp, code); lock_ObtainWrite(&cm_daemonLockp[daemonID]); cm_bkgQueueCountp[daemonID]++; osi_QAddT((osi_queue_t **) &cm_bkgListpp[daemonID], (osi_queue_t **)&cm_bkgListEndpp[daemonID], &rp->q); break; } /* otherwise fall through */ case 0: /* success */ default: /* other error */ if (code == 0) { osi_Log2(afsd_logp,"cm_BkgDaemon[%u] SUCCESS: request 0x%p", daemonID, rp); } else { osi_Log3(afsd_logp,"cm_BkgDaemon[%u] FAILED: request dropped 0x%p code 0x%x", daemonID, rp, code); } cm_ReleaseUser(rp->userp); cm_ReleaseSCache(rp->scp); free(rp); lock_ObtainWrite(&cm_daemonLockp[daemonID]); } } lock_ReleaseWrite(&cm_daemonLockp[daemonID]); thrd_SetEvent(cm_BkgDaemon_ShutdownEvent[daemonID]); pthread_exit(NULL); return NULL; }