📄 cmvmi.cpp
字号:
/* Copyright (C) 2003 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include "Cmvmi.hpp"#include <Configuration.hpp>#include <kernel_types.h>#include <TransporterRegistry.hpp>#include <NdbOut.hpp>#include <NdbMem.h>#include <SignalLoggerManager.hpp>#include <FastScheduler.hpp>#define DEBUG(x) { ndbout << "CMVMI::" << x << endl; }#include <signaldata/TestOrd.hpp>#include <signaldata/EventReport.hpp>#include <signaldata/TamperOrd.hpp>#include <signaldata/StartOrd.hpp>#include <signaldata/CloseComReqConf.hpp>#include <signaldata/SetLogLevelOrd.hpp>#include <signaldata/EventSubscribeReq.hpp>#include <signaldata/DumpStateOrd.hpp>#include <signaldata/DisconnectRep.hpp>#include <EventLogger.hpp>#include <TimeQueue.hpp>#include <NdbSleep.h>#include <SafeCounter.hpp>// Used here only to print event reports on stdout/console.EventLogger g_eventLogger;extern int simulate_error_during_shutdown;Cmvmi::Cmvmi(const Configuration & conf) : SimulatedBlock(CMVMI, conf) ,theConfig((Configuration&)conf) ,subscribers(subscriberPool){ BLOCK_CONSTRUCTOR(Cmvmi); Uint32 long_sig_buffer_size; const ndb_mgm_configuration_iterator * p = conf.getOwnConfigIterator(); ndbrequire(p != 0); ndb_mgm_get_int_parameter(p, CFG_DB_LONG_SIGNAL_BUFFER, &long_sig_buffer_size); long_sig_buffer_size= long_sig_buffer_size / 256; g_sectionSegmentPool.setSize(long_sig_buffer_size); // Add received signals addRecSignal(GSN_CONNECT_REP, &Cmvmi::execCONNECT_REP); addRecSignal(GSN_DISCONNECT_REP, &Cmvmi::execDISCONNECT_REP); addRecSignal(GSN_NDB_TAMPER, &Cmvmi::execNDB_TAMPER, true); addRecSignal(GSN_SET_LOGLEVELORD, &Cmvmi::execSET_LOGLEVELORD); addRecSignal(GSN_EVENT_REP, &Cmvmi::execEVENT_REP); addRecSignal(GSN_STTOR, &Cmvmi::execSTTOR); addRecSignal(GSN_READ_CONFIG_REQ, &Cmvmi::execREAD_CONFIG_REQ); addRecSignal(GSN_CLOSE_COMREQ, &Cmvmi::execCLOSE_COMREQ); addRecSignal(GSN_ENABLE_COMORD, &Cmvmi::execENABLE_COMORD); addRecSignal(GSN_OPEN_COMREQ, &Cmvmi::execOPEN_COMREQ); addRecSignal(GSN_TEST_ORD, &Cmvmi::execTEST_ORD); addRecSignal(GSN_STATISTICS_REQ, &Cmvmi::execSTATISTICS_REQ); addRecSignal(GSN_TAMPER_ORD, &Cmvmi::execTAMPER_ORD); addRecSignal(GSN_SET_VAR_REQ, &Cmvmi::execSET_VAR_REQ); addRecSignal(GSN_SET_VAR_CONF, &Cmvmi::execSET_VAR_CONF); addRecSignal(GSN_SET_VAR_REF, &Cmvmi::execSET_VAR_REF); addRecSignal(GSN_STOP_ORD, &Cmvmi::execSTOP_ORD); addRecSignal(GSN_START_ORD, &Cmvmi::execSTART_ORD); addRecSignal(GSN_EVENT_SUBSCRIBE_REQ, &Cmvmi::execEVENT_SUBSCRIBE_REQ); addRecSignal(GSN_DUMP_STATE_ORD, &Cmvmi::execDUMP_STATE_ORD); addRecSignal(GSN_TESTSIG, &Cmvmi::execTESTSIG); subscriberPool.setSize(5); const ndb_mgm_configuration_iterator * db = theConfig.getOwnConfigIterator(); for(unsigned j = 0; j<LogLevel::LOGLEVEL_CATEGORIES; j++){ Uint32 logLevel; if(!ndb_mgm_get_int_parameter(db, CFG_MIN_LOGLEVEL+j, &logLevel)){ clogLevel.setLogLevel((LogLevel::EventCategory)j, logLevel); } } ndb_mgm_configuration_iterator * iter = theConfig.getClusterConfigIterator(); for(ndb_mgm_first(iter); ndb_mgm_valid(iter); ndb_mgm_next(iter)){ jam(); Uint32 nodeId; Uint32 nodeType; ndbrequire(!ndb_mgm_get_int_parameter(iter,CFG_NODE_ID, &nodeId)); ndbrequire(!ndb_mgm_get_int_parameter(iter,CFG_TYPE_OF_SECTION,&nodeType)); switch(nodeType){ case NodeInfo::DB: c_dbNodes.set(nodeId); break; case NodeInfo::API: case NodeInfo::MGM: case NodeInfo::REP: break; default: ndbrequire(false); } setNodeInfo(nodeId).m_type = nodeType; } setNodeInfo(getOwnNodeId()).m_connected = true; setNodeInfo(getOwnNodeId()).m_version = ndbGetOwnVersion();}Cmvmi::~Cmvmi(){}#ifdef ERROR_INSERTNodeBitmask c_error_9000_nodes_mask;#endifvoid Cmvmi::execNDB_TAMPER(Signal* signal) { jamEntry(); SET_ERROR_INSERT_VALUE(signal->theData[0]); if(ERROR_INSERTED(9999)){ CRASH_INSERTION(9999); } if(ERROR_INSERTED(9998)){ while(true) NdbSleep_SecSleep(1); } if(ERROR_INSERTED(9997)){ ndbrequire(false); }#ifndef NDB_WIN32 if(ERROR_INSERTED(9996)){ simulate_error_during_shutdown= SIGSEGV; ndbrequire(false); } if(ERROR_INSERTED(9995)){ simulate_error_during_shutdown= SIGSEGV; kill(getpid(), SIGABRT); }#endif}//execNDB_TAMPER()void Cmvmi::execSET_LOGLEVELORD(Signal* signal) { SetLogLevelOrd * const llOrd = (SetLogLevelOrd *)&signal->theData[0]; LogLevel::EventCategory category; Uint32 level; jamEntry(); for(unsigned int i = 0; i<llOrd->noOfEntries; i++){ category = (LogLevel::EventCategory)(llOrd->theData[i] >> 16); level = llOrd->theData[i] & 0xFFFF; clogLevel.setLogLevel(category, level); }}//execSET_LOGLEVELORD()void Cmvmi::execEVENT_REP(Signal* signal) { //----------------------------------------------------------------------- // This message is sent to report any types of events in NDB. // Based on the log level they will be either ignored or // reported. Currently they are printed, but they will be // transferred to the management server for further distribution // to the graphical management interface. //----------------------------------------------------------------------- EventReport * const eventReport = (EventReport *)&signal->theData[0]; Ndb_logevent_type eventType = eventReport->getEventType(); Uint32 nodeId= eventReport->getNodeId(); if (nodeId == 0) { nodeId= refToNode(signal->getSendersBlockRef()); eventReport->setNodeId(nodeId); } jamEntry(); /** * If entry is not found */ Uint32 threshold; LogLevel::EventCategory eventCategory; Logger::LoggerLevel severity; EventLoggerBase::EventTextFunction textF; if (EventLoggerBase::event_lookup(eventType,eventCategory,threshold,severity,textF)) return; SubscriberPtr ptr; for(subscribers.first(ptr); ptr.i != RNIL; subscribers.next(ptr)){ if(ptr.p->logLevel.getLogLevel(eventCategory) < threshold){ continue; } sendSignal(ptr.p->blockRef, GSN_EVENT_REP, signal, signal->length(), JBB); } if(clogLevel.getLogLevel(eventCategory) < threshold){ return; } // Print the event info g_eventLogger.log(eventReport->getEventType(), signal->theData); return;}//execEVENT_REP()voidCmvmi::execEVENT_SUBSCRIBE_REQ(Signal * signal){ EventSubscribeReq * subReq = (EventSubscribeReq *)&signal->theData[0]; SubscriberPtr ptr; jamEntry(); DBUG_ENTER("Cmvmi::execEVENT_SUBSCRIBE_REQ"); /** * Search for subcription */ for(subscribers.first(ptr); ptr.i != RNIL; subscribers.next(ptr)){ if(ptr.p->blockRef == subReq->blockRef) break; } if(ptr.i == RNIL){ /** * Create a new one */ if(subscribers.seize(ptr) == false){ sendSignal(subReq->blockRef, GSN_EVENT_SUBSCRIBE_REF, signal, 1, JBB); return; } ptr.p->logLevel.clear(); ptr.p->blockRef = subReq->blockRef; } if(subReq->noOfEntries == 0){ /** * Cancel subscription */ subscribers.release(ptr.i); } else { /** * Update subscription */ LogLevel::EventCategory category; Uint32 level = 0; for(Uint32 i = 0; i<subReq->noOfEntries; i++){ category = (LogLevel::EventCategory)(subReq->theData[i] >> 16); level = subReq->theData[i] & 0xFFFF; ptr.p->logLevel.setLogLevel(category, level); DBUG_PRINT("info",("entry %d: level=%d, category= %d", i, level, category)); } } signal->theData[0] = ptr.i; sendSignal(ptr.p->blockRef, GSN_EVENT_SUBSCRIBE_CONF, signal, 1, JBB); DBUG_VOID_RETURN;}voidCmvmi::cancelSubscription(NodeId nodeId){ SubscriberPtr ptr; subscribers.first(ptr); while(ptr.i != RNIL){ Uint32 i = ptr.i; BlockReference blockRef = ptr.p->blockRef; subscribers.next(ptr); if(refToNode(blockRef) == nodeId){ subscribers.release(i); } }}void Cmvmi::sendSTTORRY(Signal* signal){ jam(); signal->theData[3] = 1; signal->theData[4] = 3; signal->theData[5] = 8; signal->theData[6] = 255; sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 7, JBB);}//Cmvmi::sendSTTORRYvoid Cmvmi::execREAD_CONFIG_REQ(Signal* signal){ jamEntry(); const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr(); Uint32 ref = req->senderRef; Uint32 senderData = req->senderData; const ndb_mgm_configuration_iterator * p = theConfiguration.getOwnConfigIterator(); ndbrequire(p != 0); ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend(); conf->senderRef = reference(); conf->senderData = senderData; sendSignal(ref, GSN_READ_CONFIG_CONF, signal, ReadConfigConf::SignalLength, JBB);}void Cmvmi::execSTTOR(Signal* signal){ Uint32 theStartPhase = signal->theData[1]; jamEntry(); if (theStartPhase == 1){ jam(); sendSTTORRY(signal); return; } else if (theStartPhase == 3) { jam(); globalData.activateSendPacked = 1; sendSTTORRY(signal); } else if (theStartPhase == 8){ /*---------------------------------------------------*/ /* Open com to API + REP nodes */ /*---------------------------------------------------*/ signal->theData[0] = 0; // no answer signal->theData[1] = 0; // no id signal->theData[2] = NodeInfo::API; execOPEN_COMREQ(signal); signal->theData[0] = 0; // no answer signal->theData[1] = 0; // no id signal->theData[2] = NodeInfo::REP; execOPEN_COMREQ(signal); globalData.theStartLevel = NodeState::SL_STARTED; sendSTTORRY(signal); } else { jam(); if(theConfig.lockPagesInMainMemory()){ int res = NdbMem_MemLockAll(); if(res != 0){ g_eventLogger.warning("Failed to memlock pages"); warningEvent("Failed to memlock pages"); } } sendSTTORRY(signal); }}void Cmvmi::execCLOSE_COMREQ(Signal* signal){ // Close communication with the node and halt input/output from // other blocks than QMGR CloseComReqConf * const closeCom = (CloseComReqConf *)&signal->theData[0]; const BlockReference userRef = closeCom->xxxBlockRef; Uint32 failNo = closeCom->failNo;// Uint32 noOfNodes = closeCom->noOfNodes; jamEntry(); for (unsigned i = 0; i < MAX_NODES; i++){ if(NodeBitmask::get(closeCom->theNodes, i)){ jam(); //----------------------------------------------------- // Report that the connection to the node is closed //----------------------------------------------------- signal->theData[0] = NDB_LE_CommunicationClosed; signal->theData[1] = i; sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB); globalTransporterRegistry.setIOState(i, HaltIO); globalTransporterRegistry.do_disconnect(i); } } if (failNo != 0) { jam(); signal->theData[0] = userRef; signal->theData[1] = failNo; sendSignal(QMGR_REF, GSN_CLOSE_COMCONF, signal, 19, JBA); }}void Cmvmi::execOPEN_COMREQ(Signal* signal){ // Connect to the specifed NDB node, only QMGR allowed communication // so far with the node const BlockReference userRef = signal->theData[0]; Uint32 tStartingNode = signal->theData[1]; Uint32 tData2 = signal->theData[2]; jamEntry(); const Uint32 len = signal->getLength(); if(len == 2){#ifdef ERROR_INSERT if (! (ERROR_INSERTED(9000) && c_error_9000_nodes_mask.get(tStartingNode)))#endif { globalTransporterRegistry.do_connect(tStartingNode); globalTransporterRegistry.setIOState(tStartingNode, HaltIO); //----------------------------------------------------- // Report that the connection to the node is opened //----------------------------------------------------- signal->theData[0] = NDB_LE_CommunicationOpened; signal->theData[1] = tStartingNode; sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB); //----------------------------------------------------- } } else { for(unsigned int i = 1; i < MAX_NODES; i++ ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -