INT32 iPmdDMNChildProc::active() { INT32 rc = SDB_OK; rc = attachSHM(); if ( SDB_OK == rc ) { UINT32 i = 3; UINT32 sn = _procInfo->sn; while( i-- > 0 ) { if ( sn != _procInfo->sn && (sn + 1) != _procInfo->sn ) { rc = SDB_PERM; PD_RC_CHECK( rc, PDERROR, "Don't repeat start the process" ); } ossSleep( 2 * OSS_ONE_SEC ) ; } _procInfo->szTag[ 0 ] = 0 ; _procInfo->init() ; } else { rc = allocSHM(); PD_RC_CHECK( rc, PDERROR, "Failed to allocate share-memory(rc=%d)", rc ) ; } done: return rc; error: detachSHM(); goto done; }
void sdbDataSource::_destroyConn() { while ( !_toStopWorkers ) { while ( !_toDestroyConn ) { if ( _toStopWorkers ) return ; ossSleep( SDB_DS_SLEEP_TIME ) ; } sdb* conn ; _connMutex.get() ; while( !_destroyList.empty() ) { conn = _destroyList.front() ; _destroyList.pop_front() ; if ( conn ) { _strategy->sync( conn, DELIDLECONN ) ; conn->disconnect() ; SAFE_OSS_DELETE( conn ) ; } } _connMutex.release() ; _toDestroyConn = FALSE ; } }
INT32 omHostNotifierJob::doit() { INT32 rc = SDB_OK ; UINT64 count = 0 ; _om->getRSManager()->registerEDU( eduCB() ) ; while ( TRUE ) { count++ ; if ( eduCB()->isInterrupted() ) { rc = SDB_APP_INTERRUPT ; goto error ; } if ( count % 10 == 0 ) { map< string, UINT32 > mapClusterVersion ; _shareVersion->getVersionMap( mapClusterVersion ); _checkUpdateCluster( mapClusterVersion ) ; _checkDeleteCluster( mapClusterVersion ) ; } ossSleep( OSS_ONE_SEC ) ; } done: _om->getRSManager()->unregEUD( eduCB() ); return rc ; error: goto done ; }
void sdbDataSource::_createConn() { while ( !_toStopWorkers ) { while ( !_toCreateConn ) { if ( _toStopWorkers ) return ; ossSleep( SDB_DS_SLEEP_TIME ) ; } _connMutex.get() ; INT32 idleNum = _idleSize.peek() ; INT32 busyNum = _busySize.peek() ; _connMutex.release() ; INT32 maxNum = _conf.getMaxCount() ; INT32 createNum = 0 ; if ( idleNum + busyNum < maxNum ) { INT32 incNum = _conf.getDeltaIncCount() ; if ( idleNum + busyNum + incNum < maxNum ) createNum = incNum ; else createNum = maxNum - idleNum - busyNum ; } _createConnByNum( createNum ) ; _toCreateConn = FALSE ; } }
INT32 omTaskJob::doit() { INT32 rc = SDB_OK ; UINT64 count = 0 ; _om->getRSManager()->registerEDU( eduCB() ) ; while ( TRUE ) { count++ ; if ( eduCB()->isInterrupted() ) { rc = SDB_APP_INTERRUPT ; goto error ; } if ( count % 10 == 0 ) { _taskManager->run() ; } ossSleep( OSS_ONE_SEC ) ; } done: _om->getRSManager()->unregEUD( eduCB() ); return rc ; error: goto done ; }
OSS_INLINE void close() { UINT32 timeout = 0 ; _mtx.get() ; _isConnected = FALSE ; while ( _isInAsync && timeout < 60000 ) { ossSleep( 50 ) ; timeout += 50 ; } SDB_ASSERT( timeout < 60000, "socket is dead locked" ) ; _sock.close() ; _mtx.release() ; }
/* ENTRY POINTER FUNCTIONS */ INT32 pmdSyncClockEntryPoint( pmdEDUCB * cb, void * arg ) { ossTick tmp ; pmdKRCB *pKrcb = pmdGetKRCB() ; pKrcb->getEDUMgr()->activateEDU( cb ) ; while ( !cb->isDisconnected() ) { pKrcb->syncCurTime() ; pmdUpdateDBTick() ; ossSleep( PMD_SYNC_CLOCK_INTERVAL ) ; } return SDB_OK ; }
INT32 iPmdDMNChildProc::stop() { if ( NULL != _procInfo ) { INT32 tryTimes = 0; BOOLEAN isForce = FALSE ; INT32 waitTimes = PMD_QUIT_CHL_WAIT_TIMES ; while( isChildRunning() ) { ++waitTimes ; if ( tryTimes++ >= PMDDMN_STOP_CHILD_MAX_TRY_TIMES ) { isForce = TRUE ; } if ( OSS_INVALID_PID != _pid ) { if ( !isForce && _procInfo ) { if ( waitTimes >= PMD_QUIT_CHL_WAIT_TIMES ) { _procInfo->stat = PMDDMN_SHM_STAT_CHILDREN ; _procInfo->setCHLCMD( PMDDMN_SHM_CMD_CHL_QUIT ) ; waitTimes = 0 ; #if defined ( _LINUX ) ossTerminateProcess( _pid, FALSE ) ; #endif // _LINUX PD_LOG( PDEVENT, "stop the service process(%d)...", _pid ) ; } } else { ossTerminateProcess( _pid, isForce ) ; PD_LOG( PDEVENT, "Terminate the service process(%d)...", _pid ) ; } } else if ( tryTimes >= PMDDMN_STOP_CHILD_MAX_TRY_TIMES ) { break; } ossSleep( OSS_ONE_SEC ) ; } } return fini() ; }
void iPmdDMNChildProc::syncProcesserInfo() { INT32 rc = SDB_OK ; _syncEvent.reset() ; while( iPmdProc::isRunning() ) { rc = attachSHM(); if ( SDB_OK == rc ) { if ( _procInfo->isInit() && PMDDMN_SHM_STAT_DAEMON != _procInfo->stat ) { _procInfo->pid = ossGetCurrentProcessID() ; rc = ChildProcessCMD( _procInfo->getCHLCMD() ) ; if ( SDB_OK != rc ) { PD_LOG( PDERROR, "Failed to process command(rc=%d)", rc ) ; } ++( _procInfo->sn ) ; _procInfo->stat = PMDDMN_SHM_STAT_DAEMON ; } detachSHM() ; } ossSleep( OSS_ONE_SEC ) ; } rc = attachSHM(); if ( SDB_OK == rc ) { if ( _procInfo->isInit() ) { PD_LOG( PDEVENT, "stop service..." ) ; _procInfo->pid = OSS_INVALID_PID ; _procInfo->stat = PMDDMN_SHM_STAT_DAEMON ; rc = _procInfo->setDMNCMD( PMDDMN_SHM_CMD_DMN_QUIT ) ; if ( SDB_OK ==rc ) { PD_LOG( PDWARNING, "daemon process is not stop!" ); } } detachSHM(); } _syncEvent.signalAll() ; }
/* The function in windows is called by new thread, and the main thread is in dipatch service But in linux, the function is called by main thread */ INT32 cPmdDaemon::_run( INT32 argc, CHAR **argv ) { INT32 rc = SDB_OK ; INT32 retryTimes = 0 ; BOOLEAN isChildRunning = FALSE ; SDB_ASSERT( _process, "children process can't be null!" ); if ( NULL == _process ) { rc = SDB_INVALIDARG; goto error; } while( isRunning() ) { _process->lock() ; isChildRunning = _process->isChildRunning() ; _process->unlock() ; if ( !isChildRunning && isRunning() ) { PD_LOG( PDEVENT, "Start the service process...(times:%d)", retryTimes ); ++retryTimes; rc = _process->start(); if ( SDB_OK != rc ) { PD_LOG( PDWARNING, "Failed to start the process(rc=%d), " "retrying...", rc ) ; } } else { retryTimes = 0; } ossSleep( 2 * OSS_ONE_SEC ) ; } _process->signal() ; done: return rc; error: goto done; }
INT32 pmdSignalTestEntryPoint( pmdEDUCB *cb, void *arg ) { pmdEDUCB *mainCB = ( pmdEDUCB* )arg ; INT32 interval = pmdGetOptionCB()->getSignalInterval() ; UINT32 timeCounter = 0 ; while( !cb->isDisconnected() ) { ossSleep( OSS_ONE_SEC ) ; ++timeCounter ; interval = pmdGetOptionCB()->getSignalInterval() ; if ( interval > 0 && timeCounter > (UINT32)interval ) { ossPThreadKill( mainCB->getThreadID(), OSS_TEST_SIGNAL ) ; timeCounter = 0 ; } } return SDB_OK ; }
void sdbDataSource::_bgTask() { INT64 syncCoordInterval = _conf.getSyncCoordInterval() ; INT64 ckAbnormalInterval = SDB_DS_CHECKUNNORMALCOORD_INTERVAL ; INT64 ckConnInterval = _conf.getCheckInterval() ; INT64 syncCoordTimeCnt = 0 ; INT64 ckAbnormalTimeCnt = 0 ; INT64 ckConnTimeCnt = 0 ; while ( !_toStopWorkers ) { ossSleep( SDB_DS_SLEEP_TIME ) ; if ( syncCoordInterval > 0 ) { syncCoordTimeCnt += SDB_DS_SLEEP_TIME ; } ckAbnormalTimeCnt += SDB_DS_SLEEP_TIME ; ckConnTimeCnt += SDB_DS_SLEEP_TIME ; if ( syncCoordInterval > 0 && syncCoordTimeCnt >= syncCoordInterval ) { _syncCoordNodes() ; syncCoordTimeCnt = 0 ; } if ( ckAbnormalTimeCnt >= ckAbnormalInterval ) { _retrieveAddrFromAbnormalList() ; ckAbnormalTimeCnt = 0 ; } if ( ckConnTimeCnt >= ckConnInterval ) { /* #if defined (_DEBUG) cout << "ckConnTimeCnt is: " << ckConnTimeCnt << endl ; #endif */ _checkMaxIdleConn() ; ckConnTimeCnt = 0 ; } } }
// PD_TRACE_DECLARE_FUNCTION ( SDB__DPSRPCMGR_MOVE, "_dpsReplicaLogMgr::move" ) INT32 _dpsReplicaLogMgr::move( const DPS_LSN_OFFSET &offset, const DPS_LSN_VER &version ) { INT32 rc = SDB_OK ; PD_TRACE_ENTRY ( SDB__DPSRPCMGR_MOVE ); UINT32 tmpWork = 0 ; DPS_LSN_OFFSET tmpLsnOffset = 0 ; DPS_LSN_OFFSET tmpBeginOffset = 0 ; DPS_LSN tmpCurLsn ; ossScopedLock lock( &_mtx ) ; if ( DPS_INVALID_LSN_OFFSET == offset ) { rc = SDB_DPS_MOVE_FAILED ; PD_LOG( PDERROR, "can not move to a invalid lsn" ) ; goto error ; } while ( !_queSize.compare( 0 ) ) { ossSleep ( 100 ) ; } tmpWork = _work ; tmpCurLsn = _currentLsn ; tmpLsnOffset = _lsn.offset ; tmpBeginOffset = _getStartLsn().offset ; _idleSize.add ( (&_pages[_work])->getLength() ) ; (&_pages[_work])->clear() ; rc = _movePages ( offset, version ) ; if ( SDB_OK != rc ) { goto error ; } if ( offset >= tmpBeginOffset && offset <= tmpLsnOffset && tmpWork == _work && !tmpCurLsn.invalid() ) { goto done ; } rc = _logger.move( offset, version ) ; if ( SDB_OK != rc ) { goto error ; } if ( !_logger.getStartLSN().invalid() && offset < tmpBeginOffset ) { rc = _restore () ; } else //reset file idle size { _dpsLogFile *file = _logger.getWorkLogFile() ; UINT32 fileIdleSize = file->getIdleSize() + (&_pages[_work])->getLength() ; if ( fileIdleSize % DPS_DEFAULT_PAGE_SIZE != 0 ) { PD_LOG( PDERROR, "File[%s] idle size[%u] is not multi-times of " "page size, cur page info[%u, %s]", file->toString().c_str(), fileIdleSize, _work, (&_pages[_work])->toString().c_str() ) ; rc = SDB_SYS ; SDB_ASSERT( FALSE, "Idle size error" ) ; goto error ; } file->idleSize ( fileIdleSize ) ; } done: PD_TRACE_EXITRC ( SDB__DPSRPCMGR_MOVE, rc ); return rc ; error: goto done ; }
/* rest service entry point */ INT32 pmdRestSvcEntryPoint ( pmdEDUCB *cb, void *pData ) { INT32 rc = SDB_OK ; pmdKRCB *krcb = pmdGetKRCB() ; pmdOptionsCB *optionCB = krcb->getOptionCB() ; monDBCB *mondbcb = krcb->getMonDBCB () ; pmdEDUMgr *eduMgr = cb->getEDUMgr() ; ossSocket *pListerner = ( ossSocket* )pData ; EDUID agentEDU = PMD_INVALID_EDUID ; if ( SDB_OK != ( rc = eduMgr->activateEDU ( cb )) ) { goto error ; } while ( !cb->isDisconnected() && !pListerner->isClosed() ) { SOCKET s ; rc = pListerner->accept ( &s, NULL, NULL ) ; if ( SDB_TIMEOUT == rc ) { rc = SDB_OK ; continue ; } else if ( SDB_TOO_MANY_OPEN_FD == rc ) { pListerner->close() ; PD_LOG( PDERROR, "Can not accept more connections because of " "open files upto limits, restart listening" ) ; pmdIncErrNum( rc ) ; while( !cb->isDisconnected() ) { pListerner->close() ; ossSleep( 2 * OSS_ONE_SEC ) ; rc = pListerner->initSocket() ; if ( rc ) { continue ; } rc = pListerner->bind_listen() ; if ( rc ) { continue ; } PD_LOG( PDEVENT, "Restart listening on port[%d] succeed", pListerner->getLocalPort() ) ; break ; } continue ; } if ( rc && PMD_IS_DB_DOWN() ) { rc = SDB_OK ; goto done ; } else if ( rc ) { PD_LOG ( PDERROR, "Failed to accept rest socket, rc: %d", rc ) ; if ( pListerner->isClosed() ) { break ; } else { continue ; } } cb->incEventCount() ; void *pData = NULL ; *((SOCKET *) &pData) = s ; if ( !krcb->isActive() ) { ossSocket newsock ( &s ) ; newsock.close () ; continue ; } mondbcb->connInc(); if ( mondbcb->isConnLimited( optionCB->getMaxConn() ) ) { ossSocket newsock ( &s ) ; newsock.close () ; mondbcb->connDec(); continue ; } rc = eduMgr->startEDU ( EDU_TYPE_RESTAGENT, pData, &agentEDU ) ; if ( rc ) { PD_LOG( ( rc == SDB_QUIESCED ? PDWARNING : PDERROR ), "Failed to start edu, rc: %d", rc ) ; ossSocket newsock ( &s ) ; newsock.close () ; mondbcb->connDec(); continue ; } } //while ( ! cb->isDisconnected() ) done : return rc ; error : goto done ; }
INT32 sdbDataSource::getConnection( sdb*& conn, INT64 timeoutms ) { INT32 rc = SDB_OK ; BOOLEAN isGet = FALSE ; if ( 0 > timeoutms ) { timeoutms = 0 ; } if ( !_isEnabled ) { rc = SDB_DS_NOT_ENABLE ; goto error ; } while ( !isGet ) { if ( _idleSize.peek() > 0 ) { isGet = _tryGetConn( conn ) ; } else { if ( ( (UINT32)_conf.getMaxCount() ) <= _busySize.peek()) { INT64 timeCnt = 0 ; if ( 0 == timeoutms ) { timeoutms = OSS_SINT64_MAX; } while ( !isGet && 0 <= timeCnt && timeCnt < timeoutms ) { ossSleep( SDB_DS_SLEEP_TIME ) ; timeCnt += SDB_DS_SLEEP_TIME ; if ( _idleSize.peek() > 0 ) { isGet = _tryGetConn( conn ) ; } } if ( !isGet ) { rc = SDB_DRIVER_DS_RUNOUT ; goto error ; } } else { if ( 0 == _strategy->getNormalCoordNum() ) { rc = SDB_DS_NO_REACHABLE_COORD ; goto error ; } else { INT32 createNum = _createConnByNum(1); _connMutex.get() ; if ( (0 < createNum) && (0 < _idleSize.peek()) ) { sdb* pConn = _idleList.front() ; SDB_ASSERT(pConn, "the connection got from idle list can't be null") ; _idleList.pop_front() ; _idleSize.dec() ; _busyList.push_back( pConn ) ; _busySize.inc() ; _connMutex.release() ; conn = pConn ; _strategy->sync( pConn, ADDBUSYCONN ) ; isGet = TRUE ; } else { _connMutex.release() ; } } // has reachable coord } // not reach max count } // _idleSize <= 0 if ( _idleSize.peek() <= SDB_DS_TOPRECREATE_THRESHOLD ) { _toCreateConn = TRUE ; } } done: return rc ; error: goto done ; }
INT32 _pmdExternClient::authenticate( MsgHeader *pMsg ) { #if defined ( SDB_ENGINE ) INT32 rc = SDB_OK ; BSONObj authObj ; BSONElement user, pass ; rc = extractAuthMsg( pMsg, authObj ) ; if ( rc ) { PD_LOG( PDERROR, "Client[%s] extract auth msg failed, rc: %d", clientName(), rc ) ; goto error ; } user = authObj.getField( SDB_AUTH_USER ) ; pass = authObj.getField( SDB_AUTH_PASSWD ) ; _isAuthed = FALSE ; if ( SDB_ROLE_STANDALONE == pmdGetDBRole() ) // not auth { _isAuthed = TRUE ; goto done ; } else if ( SDB_ROLE_OM == pmdGetDBRole() ) { rc = sdbGetOMManager()->authenticate( authObj, _pEDUCB ) ; if ( rc ) { PD_LOG( PDERROR, "Client[%s] authenticate failed[user: %s, " "passwd: %s], rc: %d", clientName(), user.valuestrsafe(), pass.valuestrsafe(), rc ) ; goto error ; } _isAuthed = TRUE ; } else if ( SDB_ROLE_COORD == pmdGetDBRole() ) { INT64 contextID = -1 ; rtnContextBuf buf ; CoordCB *pCoordcb = pmdGetKRCB()->getCoordCB(); rtnCoordProcesserFactory *pProcesserFactory = pCoordcb->getProcesserFactory(); rtnCoordOperator *pOperator = NULL ; pOperator = pProcesserFactory->getOperator( pMsg->opCode ); rc = pOperator->execute( pMsg, _pEDUCB, contextID, &buf ) ; // special handling for password verification when there is no // addrlist specified. Usually this happen when there is only // one coord node before creating the first catalog if ( MSG_AUTH_VERIFY_REQ == pMsg->opCode && SDB_CAT_NO_ADDR_LIST == rc ) { rc = SDB_OK ; _isAuthed = TRUE ; } else if ( rc ) { PD_LOG( PDERROR, "Client[%s] authenticate failed[user: %s, " "passwd: %s], rc: %d", clientName(), user.valuestrsafe(), pass.valuestrsafe(), rc ) ; goto error ; } else { _isAuthed = TRUE ; } } else { MsgHeader *pAuthRes = NULL ; shardCB *pShard = sdbGetShardCB() ; UINT32 retryTimes = 0 ; MsgOpReply replyHeader ; replyHeader.contextID = -1 ; replyHeader.numReturned = 0 ; while ( TRUE ) { ++retryTimes ; rc = pShard->syncSend( pMsg, CATALOG_GROUPID, TRUE, &pAuthRes ) ; if ( SDB_OK != rc ) { rc = pShard->syncSend( pMsg, CATALOG_GROUPID, FALSE, &pAuthRes ) ; PD_RC_CHECK( rc, PDERROR, "Client[%s] failed to send auth " "req to catalog, rc: %d", clientName(), rc ) ; } if ( NULL == pAuthRes ) { rc = SDB_SYS ; PD_LOG( PDERROR, "syncsend return ok but res is NULL" ) ; goto error ; } rc = MSG_GET_INNER_REPLY_RC(pAuthRes) ; replyHeader.flags = rc ; replyHeader.startFrom = MSG_GET_INNER_REPLY_STARTFROM(pAuthRes) ; ossMemcpy( &(replyHeader.header), pAuthRes, sizeof( MsgHeader ) ) ; /// release recv msg SDB_OSS_FREE( (BYTE*)pAuthRes ) ; pAuthRes = NULL ; if ( SDB_CLS_NOT_PRIMARY == rc && retryTimes < PMD_AUTH_RETRY_TIMES ) { INT32 rcTmp = SDB_OK ; rcTmp = pShard->updatePrimaryByReply( &(replyHeader.header) ) ; if ( SDB_NET_CANNOT_CONNECT == rcTmp ) { /// the node is crashed, sleep some seconds PD_LOG( PDWARNING, "Catalog group primary node is crashed " "but other nodes not aware, sleep %d seconds", NET_NODE_FAULTUP_MIN_TIME ) ; ossSleep( NET_NODE_FAULTUP_MIN_TIME * OSS_ONE_SEC ) ; } if ( rcTmp ) { pShard->updateCatGroup( CLS_SHARD_TIMEOUT ) ; } continue ; } else if ( rc ) { PD_LOG( PDERROR, "Client[%s] authenticate failed[user: %s, " "passwd: %s], rc: %d", clientName(), user.valuestrsafe(), pass.valuestrsafe(), rc ) ; goto error ; } else { _isAuthed = TRUE ; } break ; } } done: if ( SDB_OK == rc && _isAuthed ) { _username = user.valuestrsafe() ; if ( !_username.empty() ) { _password = pass.valuestrsafe() ; } _pEDUCB->setUserInfo( _username, _password ) ; _makeName() ; CHAR szTmp[ 16 ] = { 0 } ; ossSnprintf( szTmp, sizeof(szTmp)-1, "%llu", _pEDUCB->getID() ) ; PD_AUDIT_OP( AUDIT_ACCESS, MSG_AUTH_VERIFY_REQ, AUDIT_OBJ_SESSION, szTmp, SDB_OK, "User[UserName:%s, RemoteIP:%s, RemotePort:%u, " "LocalIP:%s, LocalPort:%u] login succeed", getUsername(), getPeerIPAddr(), getPeerPort(), getLocalIPAddr(), getLocalPort() ) ; } return rc ; error: if ( SDB_AUTH_AUTHORITY_FORBIDDEN == rc ) { _pEDUCB->printInfo( EDU_INFO_ERROR, "username or passwd is wrong" ) ; } goto done ; #else _isAuthed = TRUE ; return SDB_OK ; #endif // SDB_ENGINE }
INT32 sdbDataSource::_createConnByNum( INT32 num ) { INT32 rc = SDB_OK ; INT32 crtNum = 0 ; sdb* conn = NULL ; while( crtNum < num ) { INT32 pos = 0 ; string coord ; rc = _strategy->getNextCoord(coord) ; if ( SDB_OK != rc ) { INT32 cnt = _retrieveAddrFromAbnormalList() ; if ( 0 == cnt ) { break ; } else { continue ; } } conn = new(std::nothrow) sdb( _conf.getUseSSL() ) ; if ( NULL == conn ) { break ; } pos = coord.find_first_of( ":" ) ; rc = conn->connect( coord.substr(0, pos).c_str(), coord.substr(pos+1, coord.length()).c_str(), _conf.getUserName().c_str(), _conf.getPasswd().c_str() ) ; if ( SDB_OK == rc ) { if ( _addNewConnSafely(conn, coord) ) { ++crtNum ; } else { conn->disconnect(); SAFE_OSS_DELETE( conn ) ; break ; } continue ; } // connect success else { INT32 retryTime = 0 ; BOOLEAN toBreak = FALSE ; while ( retryTime < SDB_DS_CREATECONN_RETRYTIME ) { rc = conn->connect( coord.substr( 0, pos ).c_str(), coord.substr( pos+1, coord.length() ).c_str(), _conf.getUserName().c_str(), _conf.getPasswd().c_str() ) ; if ( SDB_OK != rc ) { ++retryTime ; ossSleep( SDB_DS_SLEEP_TIME ) ; // TODO: (new) why we need to continue ; } // retry failed else { if ( _addNewConnSafely(conn, coord) ) { ++crtNum ; } else { conn->disconnect(); SAFE_OSS_DELETE( conn ) ; toBreak = TRUE ; } break ; } // retry success } // while for retry if ( retryTime == SDB_DS_CREATECONN_RETRYTIME ) { SAFE_OSS_DELETE( conn ) ; _strategy->mvCoordToAbnormal( coord ) ; } if ( toBreak ) { break; } } // connect failed } // while return crtNum ; }