void DblqhProxy::execSTART_FRAGREQ(Signal* signal) { StartFragReq* req = (StartFragReq*)signal->getDataPtrSend(); Uint32 instance = getInstanceKey(req->tableId, req->fragId); // wl4391_todo impl. method that fakes senders block-ref sendSignal(numberToRef(DBLQH, instance, getOwnNodeId()), GSN_START_FRAGREQ, signal, signal->getLength(), JBB); }
static Uint32 switchRef(Uint32 block, Uint32 node) { const Uint32 ref = numberToRef(block, node); #ifdef DBINFO_SCAN_TRACE ndbout_c("Dbinfo: switching to %s in node %d, ref: 0x%.8x", getBlockName(block, "<unknown>"), node, ref); #endif return ref; }
void ClusterMgr::execDISCONNECT_REP(const NdbApiSignal* sig, const LinearSectionPtr ptr[]) { const DisconnectRep * rep = CAST_CONSTPTR(DisconnectRep, sig->getDataPtr()); Uint32 nodeId = rep->nodeId; assert(nodeId > 0 && nodeId < MAX_NODES); Node & cm_node = theNodes[nodeId]; trp_node & theNode = cm_node; bool node_failrep = theNode.m_node_fail_rep; set_node_dead(theNode); theNode.set_connected(false); noOfConnectedNodes--; if (noOfConnectedNodes == 0) { if (!global_flag_skip_invalidate_cache && theFacade.m_globalDictCache) { theFacade.m_globalDictCache->lock(); theFacade.m_globalDictCache->invalidate_all(); theFacade.m_globalDictCache->unlock(); m_connect_count ++; m_cluster_state = CS_waiting_for_clean_cache; } if (m_auto_reconnect == 0) { theStop = 2; } } if (node_failrep == false) { /** * Inform API */ NdbApiSignal signal(numberToRef(API_CLUSTERMGR, getOwnNodeId())); signal.theVerId_signalNumber = GSN_NODE_FAILREP; signal.theReceiversBlockNumber = API_CLUSTERMGR; signal.theTrace = 0; signal.theLength = NodeFailRep::SignalLengthLong; NodeFailRep * rep = CAST_PTR(NodeFailRep, signal.getDataPtrSend()); rep->failNo = 0; rep->masterNodeId = 0; rep->noOfNodes = 1; NodeBitmask::clear(rep->theAllNodes); NodeBitmask::set(rep->theAllNodes, nodeId); execNODE_FAILREP(&signal, 0); } }
void DblqhProxy::execLQHFRAGREQ(Signal* signal) { LqhFragReq* req = (LqhFragReq*)signal->getDataPtrSend(); Uint32 instance = getInstanceKey(req->tableId, req->fragId); /* Ensure instance hasn't quietly mapped back to proxy! */ ndbrequire(signal->getSendersBlockRef() != reference()); // wl4391_todo impl. method that fakes senders block-ref sendSignal(numberToRef(DBLQH, instance, getOwnNodeId()), GSN_LQHFRAGREQ, signal, signal->getLength(), JBB); }
void ClusterMgr::execAPI_REGREQ(const Uint32 * theData){ const ApiRegReq * const apiRegReq = (ApiRegReq *)&theData[0]; const NodeId nodeId = refToNode(apiRegReq->ref); #ifdef DEBUG_REG ndbout_c("ClusterMgr: Recd API_REGREQ from node %d", nodeId); #endif assert(nodeId > 0 && nodeId < MAX_NODES); Node & node = theNodes[nodeId]; assert(node.defined == true); assert(node.connected == true); if(node.m_info.m_version != apiRegReq->version){ node.m_info.m_version = apiRegReq->version; if (getMajor(node.m_info.m_version) < getMajor(NDB_VERSION) || getMinor(node.m_info.m_version) < getMinor(NDB_VERSION)) { node.compatible = false; } else { node.compatible = true; } } NdbApiSignal signal(numberToRef(API_CLUSTERMGR, theFacade.ownId())); signal.theVerId_signalNumber = GSN_API_REGCONF; signal.theReceiversBlockNumber = API_CLUSTERMGR; signal.theTrace = 0; signal.theLength = ApiRegConf::SignalLength; ApiRegConf * const conf = CAST_PTR(ApiRegConf, signal.getDataPtrSend()); conf->qmgrRef = numberToRef(API_CLUSTERMGR, theFacade.ownId()); conf->version = NDB_VERSION; conf->apiHeartbeatFrequency = node.hbFrequency; theFacade.sendSignalUnCond(&signal, nodeId); }
void reportConnect(void * callbackObj, NodeId nodeId){ SignalT<1> signalT; Signal &signal= *(Signal*)&signalT; memset(&signal.header, 0, sizeof(signal.header)); signal.header.theLength = 1; signal.header.theSendersSignalId = 0; signal.header.theSendersBlockRef = numberToRef(0, globalData.ownId); signal.theData[0] = nodeId; globalScheduler.execute(&signal, JBA, CMVMI, GSN_CONNECT_REP); }
/** * Send signal to QMGR. The input includes signal number and * signal data. The signal data is normally a copy of a received * signal so it contains expected arbitrator node id and ticket. * The sender in signal data is the QMGR node id. */ void ArbitMgr::sendSignalToQmgr(ArbitSignal& aSignal) { NdbApiSignal signal(numberToRef(API_CLUSTERMGR, m_clusterMgr.getOwnNodeId())); signal.theVerId_signalNumber = aSignal.gsn; signal.theReceiversBlockNumber = QMGR; signal.theTrace = 0; signal.theLength = ArbitSignalData::SignalLength; ArbitSignalData* sd = CAST_PTR(ArbitSignalData, signal.getDataPtrSend()); sd->sender = numberToRef(API_CLUSTERMGR, m_clusterMgr.getOwnNodeId()); sd->code = aSignal.data.code; sd->node = aSignal.data.node; sd->ticket = aSignal.data.ticket; sd->mask = aSignal.data.mask; #ifdef DEBUG_ARBIT char buf[17] = ""; ndbout << "arbit send: "; ndbout << " gsn=" << aSignal.gsn; ndbout << " recv=" << aSignal.data.sender; ndbout << " code=" << aSignal.data.code; ndbout << " node=" << aSignal.data.node; ndbout << " ticket=" << aSignal.data.ticket.getText(buf, sizeof(buf)); ndbout << " mask=" << aSignal.data.mask.getText(buf, sizeof(buf)); ndbout << endl; #endif { m_clusterMgr.lock(); m_clusterMgr.raw_sendSignal(&signal, aSignal.data.sender); m_clusterMgr.flush_send_buffers(); m_clusterMgr.unlock(); } }
/** * Report average receive length in bytes (4096 last receives) */ void reportReceiveLen(void * callbackObj, NodeId nodeId, Uint32 count, Uint64 bytes){ SignalT<3> signalT; Signal &signal= *(Signal*)&signalT; memset(&signal.header, 0, sizeof(signal.header)); signal.header.theLength = 3; signal.header.theSendersSignalId = 0; signal.header.theSendersBlockRef = numberToRef(0, globalData.ownId); signal.theData[0] = NDB_LE_ReceiveBytesStatistic; signal.theData[1] = nodeId; signal.theData[2] = (bytes/count); globalScheduler.execute(&signal, JBA, CMVMI, GSN_EVENT_REP); }
void DbtcProxy::execTAKE_OVERTCCONF(Signal* signal) { jamEntry(); if (!checkNodeFailSequence(signal)) { jam(); return; } for (Uint32 i = 0; i < c_workers; i++) { jam(); Uint32 ref = numberToRef(number(), workerInstance(i), getOwnNodeId()); sendSignal(ref, GSN_TAKE_OVERTCCONF, signal, signal->getLength(), JBB); } }
void DblqhProxy::completeLCP_1(Signal* signal) { ndbrequire(c_lcpRecord.m_state == LcpRecord::L_RUNNING); c_lcpRecord.m_state = LcpRecord::L_COMPLETING_1; ndbrequire(c_lcpRecord.m_complete_outstanding == 0); /** * send LCP_FRAG_ORD (lastFragmentFlag = true) * to all LQH instances... * they will reply with LCP_COMPLETE_REP */ LcpFragOrd* ord = (LcpFragOrd*)signal->getDataPtrSend(); ord->lcpId = c_lcpRecord.m_lcpId; ord->lastFragmentFlag = true; for (Uint32 i = 0; i<c_workers; i++) { jam(); c_lcpRecord.m_complete_outstanding++; sendSignal(workerRef(i), GSN_LCP_FRAG_ORD, signal, LcpFragOrd::SignalLength, JBB); } /** * send END_LCP_REQ to all pgman instances (except "extra" pgman) * they will reply with END_LCP_CONF */ EndLcpReq* req = (EndLcpReq*)signal->getDataPtrSend(); req->senderData= 0; req->senderRef= reference(); req->backupPtr= 0; req->backupId= c_lcpRecord.m_lcpId; for (Uint32 i = 0; i<c_workers; i++) { jam(); c_lcpRecord.m_complete_outstanding++; sendSignal(numberToRef(PGMAN, workerInstance(i), getOwnNodeId()), GSN_END_LCP_REQ, signal, EndLcpReq::SignalLength, JBB); } }
// GSN_EXEC_FRAGCONF void DblqhProxy::execEXEC_FRAGCONF(Signal* signal) { Uint32 ref = signal->theData[1]; if (refToNode(ref) == getOwnNodeId()) { jam(); sendSignal(ref, GSN_EXEC_FRAGCONF, signal, 1, JBB); } else if (ndb_route_exec_frag(getNodeInfo(refToNode(ref)).m_version)) { jam(); sendSignal(numberToRef(DBLQH, refToNode(ref)), GSN_EXEC_FRAGCONF, signal, 2, JBB); } else { jam(); sendSignal(ref, GSN_EXEC_FRAGCONF, signal, 2, JBB); } }
/** * Report connection broken */ void reportDisconnect(void * callbackObj, NodeId nodeId, Uint32 errNo){ DBUG_ENTER("reportDisconnect"); SignalT<sizeof(DisconnectRep)/4> signalT; Signal &signal= *(Signal*)&signalT; memset(&signal.header, 0, sizeof(signal.header)); signal.header.theLength = DisconnectRep::SignalLength; signal.header.theSendersSignalId = 0; signal.header.theSendersBlockRef = numberToRef(0, globalData.ownId); signal.header.theTrace = TestOrd::TraceDisconnect; DisconnectRep * const rep = (DisconnectRep *)&signal.theData[0]; rep->nodeId = nodeId; rep->err = errNo; globalScheduler.execute(&signal, JBA, CMVMI, GSN_DISCONNECT_REP); DBUG_VOID_RETURN; }
void Dbtup::bufferTRANSID_AI(Signal* signal, BlockReference aRef, Uint32 Tlen) { if (Tlen == 3) return; Uint32 hostId= refToNode(aRef); Uint32 Theader= ((refToBlock(aRef) << 16)+(Tlen-3)); ndbrequire(hostId < MAX_NODES); Uint32 TpacketLen= hostBuffer[hostId].packetLenTA; Uint32 TnoOfPackets= hostBuffer[hostId].noOfPacketsTA; Uint32 sig0= signal->theData[0]; Uint32 sig1= signal->theData[1]; Uint32 sig2= signal->theData[2]; BlockReference TBref= numberToRef(API_PACKED, hostId); if ((Tlen + TpacketLen + 1) <= 25) { // ---------------------------------------------------------------- // There is still space in the buffer. We will copy it into the // buffer. // ---------------------------------------------------------------- jam(); updatePackedList(signal, hostId); } else if (false && TnoOfPackets == 1) { // ---------------------------------------------------------------- // The buffer is full and there was only one packet buffered. We // will send this as a normal signal. // ---------------------------------------------------------------- Uint32 TnewRef= numberToRef((hostBuffer[hostId].packetBufferTA[0] >> 16), hostId); MEMCOPY_NO_WORDS(&signal->theData[0], &hostBuffer[hostId].packetBufferTA[1], TpacketLen - 1); sendSignal(TnewRef, GSN_TRANSID_AI, signal, (TpacketLen - 1), JBB); TpacketLen= 0; TnoOfPackets= 0; } else {
void DblqhProxy::sendSTART_RECREQ_2(Signal* signal, Uint32 ssId) { Ss_START_RECREQ_2& ss = ssFind<Ss_START_RECREQ_2>(ssId); const Ss_START_RECREQ_2::Req* req = (const Ss_START_RECREQ_2::Req*)signal->getDataPtr(); if (firstReply(ss)) { ss.m_req = *req; } else { jam(); /* * Fragments can be started from different lcpId's. LGMAN must run * UNDO until lowest lcpId. Each DBLQH instance computes the lowest * lcpId in START_FRAGREQ. In MT case the proxy further computes * the lowest of the lcpId's from worker instances. */ if (req->lcpId < ss.m_req.lcpId) { jam(); ss.m_req.lcpId = req->lcpId; } ndbrequire(ss.m_req.proxyBlockNo == req->proxyBlockNo); } if (!lastReply(ss)) return; { Ss_START_RECREQ_2::Req* req = (Ss_START_RECREQ_2::Req*)signal->getDataPtrSend(); *req = ss.m_req; BlockReference ref = numberToRef(req->proxyBlockNo, getOwnNodeId()); sendSignal(ref, GSN_START_RECREQ, signal, Ss_START_RECREQ_2::Req::SignalLength, JBB); } }
void DblqhProxy::completeLCP_2(Signal* signal) { jamEntry(); ndbrequire(c_lcpRecord.m_state == LcpRecord::L_COMPLETING_1); c_lcpRecord.m_state = LcpRecord::L_COMPLETING_2; EndLcpReq* req = (EndLcpReq*)signal->getDataPtrSend(); req->senderData= 0; req->senderRef= reference(); req->backupPtr= 0; req->backupId= c_lcpRecord.m_lcpId; c_lcpRecord.m_complete_outstanding++; /** * send to "extra" instance * that will checkpoint extent-pages */ // NOTE: ugly to use MaxLqhWorkers directly Uint32 instance = c_workers + 1; sendSignal(numberToRef(PGMAN, instance, getOwnNodeId()), GSN_END_LCP_REQ, signal, EndLcpReq::SignalLength, JBB); }
// GSN_EXEC_FRAGREQ void DblqhProxy::execEXEC_FRAGREQ(Signal* signal) { Uint32 ref = ((ExecFragReq*)signal->getDataPtr())->dst; if (refToNode(ref) == getOwnNodeId()) { jam(); sendSignal(ref, GSN_EXEC_FRAGREQ, signal, signal->getLength(), JBB); } else if (ndb_route_exec_frag(getNodeInfo(refToNode(ref)).m_version)) { jam(); sendSignal(numberToRef(DBLQH, refToNode(ref)), GSN_EXEC_FRAGREQ, signal, signal->getLength(), JBB); } else { jam(); sendSignal(ref, GSN_EXEC_FRAGREQ, signal, signal->getLength(), JBB); } }
void ClusterMgr::reportDisconnected(NodeId nodeId) { assert(nodeId > 0 && nodeId < MAX_NODES); assert(noOfConnectedNodes > 0); /** * We know that we have trp_client lock * but we don't know if we are polling...and for_each can * only be used by a poller... * * Send signal to self, so that we can do this when receiving a signal */ NdbApiSignal signal(numberToRef(API_CLUSTERMGR, getOwnNodeId())); signal.theVerId_signalNumber = GSN_DISCONNECT_REP; signal.theReceiversBlockNumber = API_CLUSTERMGR; signal.theTrace = 0; signal.theLength = DisconnectRep::SignalLength; DisconnectRep * rep = CAST_PTR(DisconnectRep, signal.getDataPtrSend()); rep->nodeId = nodeId; rep->err = 0; raw_sendSignal(&signal, getOwnNodeId()); }
inline BlockReference SimulatedBlock::calcSumaBlockRef (NodeId aNodeId){ return numberToRef(SUMA, aNodeId); }
inline BlockReference SimulatedBlock::calcApiClusterMgrBlockRef (NodeId aNodeId){ return numberToRef(API_CLUSTERMGR, aNodeId); }
inline BlockReference SimulatedBlock::calcTrixBlockRef (NodeId aNodeId){ return numberToRef(TRIX, aNodeId); }
inline BlockReference SimulatedBlock::calcBackupBlockRef (NodeId aNodeId){ return numberToRef(BACKUP, aNodeId); }
inline BlockReference SimulatedBlock::calcQmgrBlockRef (NodeId aNodeId){ return numberToRef(QMGR, aNodeId); }
inline BlockReference SimulatedBlock::calcNdbCntrBlockRef (NodeId aNodeId){ return numberToRef(NDBCNTR, aNodeId); }
inline BlockReference SimulatedBlock::calcTuxBlockRef (NodeId aNodeId){ return numberToRef(DBTUX, aNodeId); }
inline BlockReference SimulatedBlock::calcDictBlockRef (NodeId aNodeId){ return numberToRef(DBDICT, aNodeId); }
inline BlockReference SimulatedBlock::calcAccBlockRef (NodeId aNodeId){ return numberToRef(DBACC, aNodeId); }
inline BlockReference SimulatedBlock::calcLqhBlockRef (NodeId aNodeId){ return numberToRef(DBLQH, aNodeId); }
Uint32 TransporterRegistry::unpack(Uint32 * readPtr, Uint32 sizeOfData, NodeId remoteNodeId, IOState state) { SignalHeader signalHeader; LinearSectionPtr ptr[3]; Uint32 usedData = 0; Uint32 loop_count = 0; if(state == NoHalt || state == HaltOutput){ while ((sizeOfData >= 4 + sizeof(Protocol6)) && (loop_count < MAX_RECEIVED_SIGNALS)) { Uint32 word1 = readPtr[0]; Uint32 word2 = readPtr[1]; Uint32 word3 = readPtr[2]; loop_count++; #if 0 if(Protocol6::getByteOrder(word1) != MY_OWN_BYTE_ORDER){ //Do funky stuff } #endif const Uint16 messageLen32 = Protocol6::getMessageLength(word1); const Uint32 messageLenBytes = ((Uint32)messageLen32) << 2; if(messageLen32 == 0 || messageLen32 > MAX_MESSAGE_SIZE){ DEBUG("Message Size = " << messageLenBytes); reportError(callbackObj, remoteNodeId, TE_INVALID_MESSAGE_LENGTH); return usedData; }//if if (sizeOfData < messageLenBytes) { break; }//if if(Protocol6::getCheckSumIncluded(word1)){ const Uint32 tmpLen = messageLen32 - 1; const Uint32 checkSumSent = readPtr[tmpLen]; const Uint32 checkSumComputed = computeChecksum(&readPtr[0], tmpLen); if(checkSumComputed != checkSumSent){ reportError(callbackObj, remoteNodeId, TE_INVALID_CHECKSUM); return usedData; }//if }//if #if 0 if(Protocol6::getCompressed(word1)){ //Do funky stuff }//if #endif Protocol6::createSignalHeader(&signalHeader, word1, word2, word3); Uint32 sBlockNum = signalHeader.theSendersBlockRef; sBlockNum = numberToRef(sBlockNum, remoteNodeId); signalHeader.theSendersBlockRef = sBlockNum; Uint8 prio = Protocol6::getPrio(word1); Uint32 * signalData = &readPtr[3]; if(Protocol6::getSignalIdIncluded(word1) == 0){ signalHeader.theSendersSignalId = ~0; } else { signalHeader.theSendersSignalId = * signalData; signalData ++; }//if signalHeader.theSignalId= ~0; Uint32 * sectionPtr = signalData + signalHeader.theLength; Uint32 * sectionData = sectionPtr + signalHeader.m_noOfSections; for(Uint32 i = 0; i<signalHeader.m_noOfSections; i++){ Uint32 sz = * sectionPtr; ptr[i].sz = sz; ptr[i].p = sectionData; sectionPtr ++; sectionData += sz; } execute(callbackObj, &signalHeader, prio, signalData, ptr); readPtr += messageLen32; sizeOfData -= messageLenBytes; usedData += messageLenBytes; }//while return usedData; } else { /** state = HaltIO || state == HaltInput */ while ((sizeOfData >= 4 + sizeof(Protocol6)) && (loop_count < MAX_RECEIVED_SIGNALS)) { Uint32 word1 = readPtr[0]; Uint32 word2 = readPtr[1]; Uint32 word3 = readPtr[2]; loop_count++; #if 0 if(Protocol6::getByteOrder(word1) != MY_OWN_BYTE_ORDER){ //Do funky stuff }//if #endif const Uint16 messageLen32 = Protocol6::getMessageLength(word1); const Uint32 messageLenBytes = ((Uint32)messageLen32) << 2; if(messageLen32 == 0 || messageLen32 > MAX_MESSAGE_SIZE){ DEBUG("Message Size = " << messageLenBytes); reportError(callbackObj, remoteNodeId, TE_INVALID_MESSAGE_LENGTH); return usedData; }//if if (sizeOfData < messageLenBytes) { break; }//if if(Protocol6::getCheckSumIncluded(word1)){ const Uint32 tmpLen = messageLen32 - 1; const Uint32 checkSumSent = readPtr[tmpLen]; const Uint32 checkSumComputed = computeChecksum(&readPtr[0], tmpLen); if(checkSumComputed != checkSumSent){ //theTransporters[remoteNodeId]->disconnect(); reportError(callbackObj, remoteNodeId, TE_INVALID_CHECKSUM); return usedData; }//if }//if #if 0 if(Protocol6::getCompressed(word1)){ //Do funky stuff }//if #endif Protocol6::createSignalHeader(&signalHeader, word1, word2, word3); Uint32 rBlockNum = signalHeader.theReceiversBlockNumber; if(rBlockNum == 252){ Uint32 sBlockNum = signalHeader.theSendersBlockRef; sBlockNum = numberToRef(sBlockNum, remoteNodeId); signalHeader.theSendersBlockRef = sBlockNum; Uint8 prio = Protocol6::getPrio(word1); Uint32 * signalData = &readPtr[3]; if(Protocol6::getSignalIdIncluded(word1) == 0){ signalHeader.theSendersSignalId = ~0; } else { signalHeader.theSendersSignalId = * signalData; signalData ++; }//if Uint32 * sectionPtr = signalData + signalHeader.theLength; Uint32 * sectionData = sectionPtr + signalHeader.m_noOfSections; for(Uint32 i = 0; i<signalHeader.m_noOfSections; i++){ Uint32 sz = * sectionPtr; ptr[i].sz = sz; ptr[i].p = sectionData; sectionPtr ++; sectionData += sz; } execute(callbackObj, &signalHeader, prio, signalData, ptr); } else { DEBUG("prepareReceive(...) - Discarding message to block: " << rBlockNum << " from Node: " << remoteNodeId); }//if readPtr += messageLen32; sizeOfData -= messageLenBytes; usedData += messageLenBytes; }//while return usedData; }//if }
void ClusterMgr::execAPI_REGREQ(const Uint32 * theData) { const ApiRegReq * const apiRegReq = (ApiRegReq *)&theData[0]; const NodeId nodeId = refToNode(apiRegReq->ref); #ifdef DEBUG_REG ndbout_c("ClusterMgr: Recd API_REGREQ from node %d", nodeId); #endif assert(nodeId > 0 && nodeId < MAX_NODES); Node & cm_node = theNodes[nodeId]; trp_node & node = cm_node; assert(node.defined == true); assert(node.is_connected() == true); /* API nodes send API_REGREQ once to themselves. Other than that, there are no API-API heart beats. */ assert(cm_node.m_info.m_type != NodeInfo::API || (nodeId == getOwnNodeId() && !cm_node.is_confirmed())); if(node.m_info.m_version != apiRegReq->version) { node.m_info.m_version = apiRegReq->version; node.m_info.m_mysql_version = apiRegReq->mysql_version; if (node.m_info.m_version < NDBD_SPLIT_VERSION) node.m_info.m_mysql_version = 0; if (getMajor(node.m_info.m_version) < getMajor(NDB_VERSION) || getMinor(node.m_info.m_version) < getMinor(NDB_VERSION)) { node.compatible = false; } else { node.compatible = true; } } NdbApiSignal signal(numberToRef(API_CLUSTERMGR, theFacade.ownId())); signal.theVerId_signalNumber = GSN_API_REGCONF; signal.theReceiversBlockNumber = API_CLUSTERMGR; signal.theTrace = 0; signal.theLength = ApiRegConf::SignalLength; ApiRegConf * const conf = CAST_PTR(ApiRegConf, signal.getDataPtrSend()); conf->qmgrRef = numberToRef(API_CLUSTERMGR, theFacade.ownId()); conf->version = NDB_VERSION; conf->mysql_version = NDB_MYSQL_VERSION_D; /* This is the frequency (in centiseonds) at which we want the other node to send API_REGREQ messages. */ conf->apiHeartbeatFrequency = m_hbFrequency/10; conf->minDbVersion= 0; conf->nodeState= node.m_state; node.set_confirmed(true); if (safe_sendSignal(&signal, nodeId) != 0) node.set_confirmed(false); }
/** * This is called as a callback when executing update_connections which * is always called with ownership of trp_client lock. */ void ClusterMgr::reportConnected(NodeId nodeId) { DBUG_ENTER("ClusterMgr::reportConnected"); DBUG_PRINT("info", ("nodeId: %u", nodeId)); /** * Ensure that we are sending heartbeat every 100 ms * until we have got the first reply from NDB providing * us with the real time-out period to use. */ assert(nodeId > 0 && nodeId < MAX_NODES); if (nodeId != getOwnNodeId()) { noOfConnectedNodes++; } Node & cm_node = theNodes[nodeId]; trp_node & theNode = cm_node; if (theNode.m_info.m_type == NodeInfo::DB) { noOfConnectedDBNodes++; if (noOfConnectedDBNodes == 1) { // Data node connected, use ConnectBackoffMaxTime theFacade.get_registry()->set_connect_backoff_max_time_in_ms(connect_backoff_max_time); } } cm_node.hbMissed = 0; cm_node.hbCounter = 0; cm_node.hbFrequency = 0; assert(theNode.is_connected() == false); /** * make sure the node itself is marked connected even * if first API_REGCONF has not arrived */ theNode.set_connected(true); theNode.m_state.m_connected_nodes.set(nodeId); theNode.m_info.m_version = 0; theNode.compatible = true; theNode.nfCompleteRep = true; theNode.m_node_fail_rep = false; theNode.m_state.startLevel = NodeState::SL_NOTHING; theNode.minDbVersion = 0; /** * We know that we have clusterMgrThreadMutex and trp_client::mutex * but we don't know if we are polling...and for_each can * only be used by a poller... * * Send signal to self, so that we can do this when receiving a signal */ NdbApiSignal signal(numberToRef(API_CLUSTERMGR, getOwnNodeId())); signal.theVerId_signalNumber = GSN_CONNECT_REP; signal.theReceiversBlockNumber = API_CLUSTERMGR; signal.theTrace = 0; signal.theLength = 1; signal.getDataPtrSend()[0] = nodeId; raw_sendSignal(&signal, getOwnNodeId()); DBUG_VOID_RETURN; }