📄 provisionserver.cxx
字号:
ProvisionServer::timerFailFunc(void* arg){ // sleep and check if we still syncing... sleep(FAIL_SLEEP_TIME); ProvisionServer::instance().failTimerHandler();}voidProvisionServer::failTimerHandler(){ _MutextimerLock.lock(); failTimerPending = false; int result = _copy.timedoutSync(); _MutextimerLock.unlock(); // we get err if we are in an illegal state, and FAIL if we are in SLAVE, // in which case we assume we had a sync request that timed out. If we // actually succeeded, then restarted, it will interupt the sync, but // we will eventually sync since we start the timer again. The only // way this can fail is if the delay is too low to allow sync if (result == RedundancyManager::ERR || result == RedundancyManager::FAIL) { cpLog(LOG_ERR, "Sync took >600s, abort sync and reset timer."); setSyncTimer(); }}voidProvisionServer::initiateSync(){ cpLog(LOG_DEBUG, "Sync Timer expired. Attempting to sync."); int result; // set timer to false and check state machine _MutextimerLock.lock(); timerPending = false; result = _copy.startSync(); _MutextimerLock.unlock(); if (result == RedundancyManager::OK) { // if we get here we are the sync master. map < string, TimeStamp > remoteMap, localMap; result = getLocalMap(localMap); if (result != 0) { cpLog(LOG_ERR, "Unable to generate list of local data items"); return ; } // get the remote list of items/timestamps result = _copy.getRemoteMap(remoteMap); if (result != RedundancyManager::OK) { if (result == RedundancyManager::ERR) { _copy.connFailed(); return ; } if (result == RedundancyManager::FAIL) { _copy.badReturn(); setSyncTimer(); return ; } } // go through local list and compare to remote 4 possibilities: // 1) Not on remote -- send to remote // 2) Local is older -- get from remote // 3) Local is newer -- send to remote // 4) Both are equal -- no data sent to remote // remove from the remote list if found, then we go through what is // left on that list -- that is stuff on remote we don't have const int DO_NOTHING = 0; const int SEND_REMOTE = 1; const int GET_REMOTE = 2; string itemData; TimeStamp timestamp = 0; string group, name; for (map < string, TimeStamp > ::iterator itr = localMap.begin(); itr != localMap.end(); itr++) { int action = DO_NOTHING; map < string, TimeStamp > ::iterator remoteItr = remoteMap.find((*itr).first); if (remoteItr == remoteMap.end()) { action = SEND_REMOTE; // not on remote server, so put } else { if ( (*itr).second > (*remoteItr).second ) { action = SEND_REMOTE; } else if ((*itr).second < (*remoteItr).second) { action = GET_REMOTE; } else { action = DO_NOTHING; } } // else nothing, essentially if (action == SEND_REMOTE) { // write to remote server try { if (parseMapItem((*itr).first, group, name) != 0) { cpLog(LOG_ERR, "Failed to parse map entry : %s", (*itr).first.c_str()); _copy.abortSync(); setSyncTimer(); return ; } itemData = _dataStore->getItem(group, name); } catch (VIoException& e) { // Failed to read the item -- either because it is // not there or permissions are wrong string reason = e.getDescription(); cpLog(LOG_ERR, "Failed to read local item (%s,%s): %s", group.c_str(), name.c_str(), reason.c_str()); cpLog(LOG_ERR, "Cannot read local file, aborting", group.c_str(), name.c_str(), reason.c_str()); // abort assert(0); // should never get here, but just in case _copy.abortSync(); setSyncTimer(); return ; } cpLog(LOG_DEBUG, "Sending remote %s %s with date %lu", group.c_str(), name.c_str(), timestamp); result = _copy.writeItem(group, name, itemData, (*itr).second); if (result != RedundancyManager::OK) { if (result == RedundancyManager::ERR) { _copy.connFailed(); return ; } if (result == RedundancyManager::FAIL) { _copy.badReturn(); setSyncTimer(); return ; } } } // end of write item if (action == GET_REMOTE) { if (parseMapItem((*itr).first, group, name) != 0) { cpLog(LOG_ERR, "Failed to parse map entry : %s", (*itr).first.c_str()); _copy.abortSync(); setSyncTimer(); return ; } result = _copy.readItem(group, name, itemData, timestamp); if (result != RedundancyManager::OK) { if (result == RedundancyManager::ERR) { _copy.connFailed(); return ; } if (result == RedundancyManager::FAIL) { _copy.badReturn(); setSyncTimer(); return ; } } try { cpLog(LOG_DEBUG, "Putting %s %s with date %lu from remote", group.c_str(), name.c_str(), timestamp); _dataStore->putItem(group, name, itemData, timestamp); _registerManager.modifyItem(group, name, false); } catch (VIoException& e) { // Failed to write the item. Log and die since this // means we can't access our own datastore properly string reason = e.getDescription(); cpLog(LOG_ERR, "Failed to write local item : %s to filestore", reason.c_str()); cpLog(LOG_ERR, "Aborting. Check file permissions on datastore"); assert(0); // should never get here, but just in case... _copy.abortSync(); setSyncTimer(); return ; } } // remove it from the remote map remoteMap.erase((*itr).first); } // end of local list loop // whatever is left in the remote list doesn't exist in the local // map, so grab them for (map < string, TimeStamp > ::iterator itr = remoteMap.begin(); itr != remoteMap.end(); itr++) { if (parseMapItem((*itr).first, group, name) != 0) { cpLog(LOG_ERR, "Failed to parse map entry : %s", (*itr).first.c_str()); _copy.abortSync(); setSyncTimer(); return ; } result = _copy.readItem(group, name, itemData, timestamp); if (result != RedundancyManager::OK) { if (result == RedundancyManager::ERR) { _copy.connFailed(); return ; } if (result == RedundancyManager::FAIL) { _copy.badReturn(); setSyncTimer(); return ; } } try { cpLog(LOG_DEBUG, "Putting %s %s with date %lu from remote", group.c_str(), name.c_str(), timestamp); _dataStore->putItem(group, name, itemData, timestamp); _registerManager.modifyItem(group, name, false); } catch (VIoException& e) { //Failed to write the item string reason = e.getDescription(); cpLog(LOG_ERR, "Failed to write local item : %s", reason.c_str()); cpLog(LOG_ERR, "Check that you have permission to write files", reason.c_str()); // should die now since the server can't write its own data assert(0); // should never get here, but just in case _copy.abortSync(); setSyncTimer(); return ; } } // get their registration cpLog(LOG_DEBUG, "Getting remote registration list"); result = _copy.getRemoteRegistration(_registerManager); if (result != RedundancyManager::OK) { if (result == RedundancyManager::ERR) { _copy.connFailed(); return ; } if (result == RedundancyManager::FAIL) { _copy.badReturn(); setSyncTimer(); return ; } } // send our registration result = _copy.putLocalRegistration(_registerManager); if (result != RedundancyManager::OK) { cpLog(LOG_ERR, "Send registration failed -- Sync failed!"); if (result == RedundancyManager::ERR) { _copy.connFailed(); return ; } if (result == RedundancyManager::FAIL) { _copy.badReturn(); setSyncTimer(); return ; } } // finally, send SYNCGOOD int result = _copy.sendGood(); if (result != RedundancyManager::OK) { if (result == RedundancyManager::ERR) { _copy.connFailed(); return ; } if (result == RedundancyManager::FAIL) { _copy.badReturn(); setSyncTimer(); return ; } } cpLog(LOG_DEBUG, "Synchronization Succeeded!"); } else { // no action (expired but we are already syched or something cpLog(LOG_DEBUG, "no sync because not in OK state!"); } return ;}voidProvisionServer::processRequest(LockedConnection& conn) throw (VException&){ cpLog(LOG_DEBUG, "%d: processing request %d", pthread_self(), conn.getConnId()); char buf[MAXLINE]; buf[0] = '\0'; int nread = 0; switch(myAclFile.verify(conn.getIp())) { case AclFile::AclDenied: cpLog(LOG_INFO, "ACL: denied connection"); { _MutexconnectionMapLock.lock(); int tmp = conn.getConnId(); conn.close(); conn.doneService(); _connectionMap.erase(tmp); _MutexconnectionMapLock.unlock(); } return ; case AclFile::AclReadOnly: cpLog(LOG_DEBUG, "ACL: readonly allowed"); conn.readAuthorize(); break; case AclFile::AclReadWrite: cpLog(LOG_DEBUG, "ACL: readwrite allowed"); conn.writeAuthorize(); break; } if (conn.readLine(buf, sizeof(buf) - 1, nread) <= 0) { cpLog(LOG_DEBUG, "%d: closing %d", pthread_self(), conn.getConnId()); _MutexconnectionMapLock.lock(); int tmp = conn.getConnId(); cpLog(LOG_DEBUG, "processRequest: %p", &_MutexconnectionMapLock); conn.close(); conn.doneService(); _connectionMap.erase(tmp); _MutexconnectionMapLock.unlock(); return ; } buf[nread] = '\0'; char req[MAXLINE], arg[MAXLINE], arg2[MAXLINE], arg3[MAXLINE], arg4[MAXLINE], arg5[MAXLINE]; sscanf(buf, "%s%s%s%s%s%s", req, arg, arg2, arg3, arg4, arg5); string vppReq; vppReq = req; cpLog(LOG_DEBUG, "%d: %d: Received message : %s, command is %s", pthread_self(), conn.getConnId(), buf, vppReq.c_str()); // figure out what we are doing and get it... bool processedCommand = false; if (vppReq == TLS_REQ ) { if(myFileOkTls && TlsConnection::hasTls()) { cpLog(LOG_DEBUG, "trying to do TLS"); sendVPPOk(conn); // convert to TLS if(conn.initTlsServer(myCertPath.c_str(), myKeyPath.c_str()) <= 0) { cpLog(LOG_ERR, "failed to do TLS correctly"); // failed, do something here _MutexconnectionMapLock.lock(); int tmp = conn.getConnId(); conn.close(); conn.doneService(); _connectionMap.erase(tmp); _MutexconnectionMapLock.unlock(); return; } cpLog(LOG_DEBUG, "initialized TLS connection"); } else { if(!TlsConnection::hasTls()) { cpLog(LOG_DEBUG, "cannot do TLS (no support compiled in)"); } else { cpLog(LOG_DEBUG, "cannot do TLS (missing config files)"); } sendVPPFail(conn); } processedCommand = true; } if( !myRequireTls || (myRequireTls && conn.isTls())) { // in these situations, allow AUTH requests if ( vppReq == AUTH_REQ ) { handleAuthRequest(conn, arg); processedCommand = true; } if ( conn.isReadAuthorized() ) { // only allow these commands if Reading is authorized if ( vppReq == GET_REQ ) { handleGetRequest(conn, arg, arg2); processedCommand = true; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -