Commit 8a40180c authored by unknown's avatar unknown

ndb - bug#15695 bug#16447 bug#18612

  For various reasone have a partitioned cluster been created
  This patch makes sure that when they connect
  1) it's detected
  2) shutdown is forced


ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp:
  New dump/error insert for simulating network failure
ndb/src/kernel/blocks/qmgr/Qmgr.hpp:
  1) Activly detect paritioned cluster(s)
  2) add some documentation
ndb/src/kernel/blocks/qmgr/QmgrMain.cpp:
  1) Activly detect paritioned cluster(s)
  2) add some documentation
parent 241377c7
...@@ -133,6 +133,9 @@ Cmvmi::~Cmvmi() ...@@ -133,6 +133,9 @@ Cmvmi::~Cmvmi()
{ {
} }
#ifdef ERROR_INSERT
NodeBitmask c_error_9000_nodes_mask;
#endif
void Cmvmi::execNDB_TAMPER(Signal* signal) void Cmvmi::execNDB_TAMPER(Signal* signal)
{ {
...@@ -390,21 +393,33 @@ void Cmvmi::execOPEN_COMREQ(Signal* signal) ...@@ -390,21 +393,33 @@ void Cmvmi::execOPEN_COMREQ(Signal* signal)
const Uint32 len = signal->getLength(); const Uint32 len = signal->getLength();
if(len == 2){ if(len == 2){
globalTransporterRegistry.do_connect(tStartingNode);
globalTransporterRegistry.setIOState(tStartingNode, HaltIO);
//----------------------------------------------------- #ifdef ERROR_INSERT
// Report that the connection to the node is opened if (! (ERROR_INSERTED(9000) && c_error_9000_nodes_mask.get(tStartingNode)))
//----------------------------------------------------- #endif
signal->theData[0] = EventReport::CommunicationOpened; {
signal->theData[1] = tStartingNode; globalTransporterRegistry.do_connect(tStartingNode);
sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB); globalTransporterRegistry.setIOState(tStartingNode, HaltIO);
//-----------------------------------------------------
//-----------------------------------------------------
// Report that the connection to the node is opened
//-----------------------------------------------------
signal->theData[0] = EventReport::CommunicationOpened;
signal->theData[1] = tStartingNode;
sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
//-----------------------------------------------------
}
} else { } else {
for(unsigned int i = 1; i < MAX_NODES; i++ ) { for(unsigned int i = 1; i < MAX_NODES; i++ ) {
jam(); jam();
if (i != getOwnNodeId() && getNodeInfo(i).m_type == tData2){ if (i != getOwnNodeId() && getNodeInfo(i).m_type == tData2){
jam(); jam();
#ifdef ERROR_INSERT
if (ERROR_INSERTED(9000) && c_error_9000_nodes_mask.get(i))
continue;
#endif
globalTransporterRegistry.do_connect(i); globalTransporterRegistry.do_connect(i);
globalTransporterRegistry.setIOState(i, HaltIO); globalTransporterRegistry.setIOState(i, HaltIO);
...@@ -1010,7 +1025,8 @@ Cmvmi::execDUMP_STATE_ORD(Signal* signal) ...@@ -1010,7 +1025,8 @@ Cmvmi::execDUMP_STATE_ORD(Signal* signal)
} }
DumpStateOrd * const & dumpState = (DumpStateOrd *)&signal->theData[0]; DumpStateOrd * const & dumpState = (DumpStateOrd *)&signal->theData[0];
if (dumpState->args[0] == DumpStateOrd::CmvmiDumpConnections){ Uint32 arg = dumpState->args[0];
if (arg == DumpStateOrd::CmvmiDumpConnections){
for(unsigned int i = 1; i < MAX_NODES; i++ ){ for(unsigned int i = 1; i < MAX_NODES; i++ ){
const char* nodeTypeStr = ""; const char* nodeTypeStr = "";
switch(getNodeInfo(i).m_type){ switch(getNodeInfo(i).m_type){
...@@ -1043,13 +1059,13 @@ Cmvmi::execDUMP_STATE_ORD(Signal* signal) ...@@ -1043,13 +1059,13 @@ Cmvmi::execDUMP_STATE_ORD(Signal* signal)
} }
} }
if (dumpState->args[0] == DumpStateOrd::CmvmiDumpLongSignalMemory){ if (arg == DumpStateOrd::CmvmiDumpLongSignalMemory){
infoEvent("Cmvmi: g_sectionSegmentPool size: %d free: %d", infoEvent("Cmvmi: g_sectionSegmentPool size: %d free: %d",
g_sectionSegmentPool.getSize(), g_sectionSegmentPool.getSize(),
g_sectionSegmentPool.getNoOfFree()); g_sectionSegmentPool.getNoOfFree());
} }
if (dumpState->args[0] == DumpStateOrd::CmvmiSetRestartOnErrorInsert) if (arg == DumpStateOrd::CmvmiSetRestartOnErrorInsert)
{ {
if(signal->getLength() == 1) if(signal->getLength() == 1)
{ {
...@@ -1069,7 +1085,7 @@ Cmvmi::execDUMP_STATE_ORD(Signal* signal) ...@@ -1069,7 +1085,7 @@ Cmvmi::execDUMP_STATE_ORD(Signal* signal)
} }
} }
if (dumpState->args[0] == DumpStateOrd::CmvmiTestLongSigWithDelay) { if (arg == DumpStateOrd::CmvmiTestLongSigWithDelay) {
unsigned i; unsigned i;
Uint32 loopCount = dumpState->args[1]; Uint32 loopCount = dumpState->args[1];
const unsigned len0 = 11; const unsigned len0 = 11;
...@@ -1097,6 +1113,30 @@ Cmvmi::execDUMP_STATE_ORD(Signal* signal) ...@@ -1097,6 +1113,30 @@ Cmvmi::execDUMP_STATE_ORD(Signal* signal)
sendSignal(reference(), GSN_TESTSIG, signal, 8, JBB, ptr, 2); sendSignal(reference(), GSN_TESTSIG, signal, 8, JBB, ptr, 2);
} }
#ifdef ERROR_INSERT
if (arg == 9000)
{
SET_ERROR_INSERT_VALUE(9000);
for (Uint32 i = 1; i<signal->getLength(); i++)
c_error_9000_nodes_mask.set(signal->theData[i]);
}
if (arg == 9001)
{
CLEAR_ERROR_INSERT_VALUE;
for (Uint32 i = 0; i<MAX_NODES; i++)
{
if (c_error_9000_nodes_mask.get(i))
{
signal->theData[0] = 0;
signal->theData[1] = i;
EXECUTE_DIRECT(CMVMI, GSN_OPEN_COMREQ, signal, 2);
}
}
c_error_9000_nodes_mask.clear();
}
#endif
#ifdef VM_TRACE #ifdef VM_TRACE
#if 0 #if 0
{ {
......
...@@ -100,7 +100,12 @@ public: ...@@ -100,7 +100,12 @@ public:
}; };
struct StartRecord { struct StartRecord {
void reset(){ m_startKey++; m_startNode = 0;} void reset(){
m_startKey++;
m_startNode = 0;
m_gsn = RNIL;
m_nodes.clearWaitingFor();
}
Uint32 m_startKey; Uint32 m_startKey;
Uint32 m_startNode; Uint32 m_startNode;
Uint64 m_startTimeout; Uint64 m_startTimeout;
...@@ -112,6 +117,14 @@ public: ...@@ -112,6 +117,14 @@ public:
NdbNodeBitmask c_definedNodes; // DB nodes in config NdbNodeBitmask c_definedNodes; // DB nodes in config
NdbNodeBitmask c_clusterNodes; // DB nodes in cluster NdbNodeBitmask c_clusterNodes; // DB nodes in cluster
NodeBitmask c_connectedNodes; // All kinds of connected nodes NodeBitmask c_connectedNodes; // All kinds of connected nodes
/**
* Nodes which we're checking for partitioned cluster
*
* i.e. nodes that connect to use, when we already have elected president
*/
NdbNodeBitmask c_cmregreq_nodes;
Uint32 c_maxDynamicId; Uint32 c_maxDynamicId;
// Records // Records
...@@ -251,8 +264,10 @@ private: ...@@ -251,8 +264,10 @@ private:
// Generated statement blocks // Generated statement blocks
void startphase1(Signal* signal); void startphase1(Signal* signal);
void electionWon(); void electionWon(Signal* signal);
void cmInfoconf010Lab(Signal* signal); void cmInfoconf010Lab(Signal* signal);
bool check_cmregreq_reply(Signal* signal, Uint32 nodeId, Uint32 gsn);
void apiHbHandlingLab(Signal* signal); void apiHbHandlingLab(Signal* signal);
void timerHandlingLab(Signal* signal); void timerHandlingLab(Signal* signal);
void hbReceivedLab(Signal* signal); void hbReceivedLab(Signal* signal);
......
...@@ -56,6 +56,33 @@ ...@@ -56,6 +56,33 @@
#define DEBUG_START3(signal, msg) #define DEBUG_START3(signal, msg)
#endif #endif
/**
* c_start.m_gsn = GSN_CM_REGREQ
* Possible for all nodes
* c_start.m_nodes contains all nodes in config
*
* c_start.m_gsn = GSN_CM_NODEINFOREQ;
* Set when receiving CM_REGCONF
* State possible for starting node only (not in cluster)
*
* c_start.m_nodes contains all node in alive cluster that
* that has not replied to GSN_CM_NODEINFOREQ
* passed by president in GSN_CM_REGCONF
*
* c_start.m_gsn = GSN_CM_ADD
* Possible for president only
* Set when receiving and accepting CM_REGREQ (to include node)
*
* c_start.m_nodes contains all nodes in alive cluster + starting node
* that has not replied to GSN_CM_ADD
* by sending GSN_CM_ACKADD
*
* c_start.m_gsn = GSN_CM_NODEINFOCONF
* Possible for non presidents only
* c_start.m_nodes contains a node that has been accepted by president
* but has not connected to us yet
*/
// Signal entries and statement blocks // Signal entries and statement blocks
/* 4 P R O G R A M */ /* 4 P R O G R A M */
/*******************************/ /*******************************/
...@@ -259,18 +286,24 @@ void Qmgr::execCONNECT_REP(Signal* signal) ...@@ -259,18 +286,24 @@ void Qmgr::execCONNECT_REP(Signal* signal)
{ {
jamEntry(); jamEntry();
const Uint32 nodeId = signal->theData[0]; const Uint32 nodeId = signal->theData[0];
if (ERROR_INSERTED(931))
{
jam();
ndbout_c("Discarding CONNECT_REP(%d)", nodeId);
infoEvent("Discarding CONNECT_REP(%d)", nodeId);
return;
}
c_connectedNodes.set(nodeId); c_connectedNodes.set(nodeId);
NodeRecPtr nodePtr; NodeRecPtr nodePtr;
nodePtr.i = getOwnNodeId(); nodePtr.i = getOwnNodeId();
ptrCheckGuard(nodePtr, MAX_NODES, nodeRec); ptrCheckGuard(nodePtr, MAX_NODES, nodeRec);
switch(nodePtr.p->phase){ switch(nodePtr.p->phase){
case ZSTARTING:
case ZRUNNING: case ZRUNNING:
ndbrequire(!c_clusterNodes.get(nodeId));
case ZSTARTING:
jam(); jam();
if(!c_start.m_nodes.isWaitingFor(nodeId)){
jam();
return;
}
break; break;
case ZPREPARE_FAIL: case ZPREPARE_FAIL:
case ZFAIL_CLOSING: case ZFAIL_CLOSING:
...@@ -282,32 +315,64 @@ void Qmgr::execCONNECT_REP(Signal* signal) ...@@ -282,32 +315,64 @@ void Qmgr::execCONNECT_REP(Signal* signal)
case ZAPI_INACTIVE: case ZAPI_INACTIVE:
return; return;
} }
if (getNodeInfo(nodeId).getType() != NodeInfo::DB)
{
jam();
return;
}
switch(c_start.m_gsn){ switch(c_start.m_gsn){
case GSN_CM_REGREQ: case GSN_CM_REGREQ:
jam(); jam();
sendCmRegReq(signal, nodeId); sendCmRegReq(signal, nodeId);
/**
* We're waiting for CM_REGCONF c_start.m_nodes contains all configured
* nodes
*/
ndbrequire(nodePtr.p->phase == ZSTARTING);
ndbrequire(c_start.m_nodes.isWaitingFor(nodeId));
return; return;
case GSN_CM_NODEINFOREQ: case GSN_CM_NODEINFOREQ:
jam(); jam();
sendCmNodeInfoReq(signal, nodeId, nodePtr.p);
if (c_start.m_nodes.isWaitingFor(nodeId))
{
jam();
ndbrequire(getOwnNodeId() != cpresident);
ndbrequire(nodePtr.p->phase == ZSTARTING);
sendCmNodeInfoReq(signal, nodeId, nodePtr.p);
return;
}
return; return;
case GSN_CM_ADD:{ case GSN_CM_NODEINFOCONF:{
jam(); jam();
ndbrequire(getOwnNodeId() != cpresident);
c_start.m_nodes.clearWaitingFor(nodeId);
c_start.m_gsn = RNIL;
NodeRecPtr addNodePtr; ndbrequire(getOwnNodeId() != cpresident);
addNodePtr.i = nodeId; ndbrequire(nodePtr.p->phase == ZRUNNING);
ptrCheckGuard(addNodePtr, MAX_NDB_NODES, nodeRec); if (c_start.m_nodes.isWaitingFor(nodeId))
cmAddPrepare(signal, addNodePtr, nodePtr.p); {
return; jam();
c_start.m_nodes.clearWaitingFor(nodeId);
c_start.m_gsn = RNIL;
NodeRecPtr addNodePtr;
addNodePtr.i = nodeId;
ptrCheckGuard(addNodePtr, MAX_NDB_NODES, nodeRec);
cmAddPrepare(signal, addNodePtr, nodePtr.p);
return;
}
} }
default: default:
return; (void)1;
} }
ndbrequire(!c_start.m_nodes.isWaitingFor(nodeId));
ndbrequire(!c_cmregreq_nodes.get(nodeId));
c_cmregreq_nodes.set(nodeId);
sendCmRegReq(signal, nodeId);
c_regReqReqSent--;
return; return;
}//Qmgr::execCONNECT_REP() }//Qmgr::execCONNECT_REP()
...@@ -601,22 +666,39 @@ void Qmgr::execCM_REGCONF(Signal* signal) ...@@ -601,22 +666,39 @@ void Qmgr::execCM_REGCONF(Signal* signal)
jamEntry(); jamEntry();
const CmRegConf * const cmRegConf = (CmRegConf *)&signal->theData[0]; const CmRegConf * const cmRegConf = (CmRegConf *)&signal->theData[0];
Uint32 presidentNodeId = cmRegConf->presidentNodeId;
if (check_cmregreq_reply(signal, presidentNodeId, GSN_CM_REGCONF))
{
jam();
return;
}
if (!ndbCompatible_ndb_ndb(NDB_VERSION, cmRegConf->presidentVersion)) { if (!ndbCompatible_ndb_ndb(NDB_VERSION, cmRegConf->presidentVersion)) {
jam(); jam();
char buf[128]; char buf[128];
BaseString::snprintf(buf,sizeof(buf),"incompatible version own=0x%x other=0x%x, shutting down", NDB_VERSION, cmRegConf->presidentVersion); BaseString::snprintf(buf,sizeof(buf),
"incompatible version own=0x%x other=0x%x, "
" shutting down",
NDB_VERSION, cmRegConf->presidentVersion);
systemErrorLab(signal, __LINE__, buf); systemErrorLab(signal, __LINE__, buf);
return; return;
} }
myNodePtr.i = getOwnNodeId();
ptrCheckGuard(myNodePtr, MAX_NDB_NODES, nodeRec);
ndbrequire(c_start.m_gsn == GSN_CM_REGREQ);
ndbrequire(myNodePtr.p->phase = ZSTARTING);
cpdistref = cmRegConf->presidentBlockRef; cpdistref = cmRegConf->presidentBlockRef;
cpresident = cmRegConf->presidentNodeId; cpresident = cmRegConf->presidentNodeId;
UintR TdynamicId = cmRegConf->dynamicId; UintR TdynamicId = cmRegConf->dynamicId;
c_maxDynamicId = TdynamicId; c_maxDynamicId = TdynamicId;
c_clusterNodes.assign(NdbNodeBitmask::Size, cmRegConf->allNdbNodes); c_clusterNodes.assign(NdbNodeBitmask::Size, cmRegConf->allNdbNodes);
myNodePtr.p->ndynamicId = TdynamicId;
/*--------------------------------------------------------------*/ /*--------------------------------------------------------------*/
// Send this as an EVENT REPORT to inform about hearing about // Send this as an EVENT REPORT to inform about hearing about
// other NDB node proclaiming to be president. // other NDB node proclaiming to be president.
...@@ -627,10 +709,6 @@ void Qmgr::execCM_REGCONF(Signal* signal) ...@@ -627,10 +709,6 @@ void Qmgr::execCM_REGCONF(Signal* signal)
signal->theData[3] = TdynamicId; signal->theData[3] = TdynamicId;
sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 4, JBB); sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 4, JBB);
myNodePtr.i = getOwnNodeId();
ptrCheckGuard(myNodePtr, MAX_NDB_NODES, nodeRec);
myNodePtr.p->ndynamicId = TdynamicId;
for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
jam(); jam();
if (c_clusterNodes.get(nodePtr.i)){ if (c_clusterNodes.get(nodePtr.i)){
...@@ -653,6 +731,134 @@ void Qmgr::execCM_REGCONF(Signal* signal) ...@@ -653,6 +731,134 @@ void Qmgr::execCM_REGCONF(Signal* signal)
return; return;
}//Qmgr::execCM_REGCONF() }//Qmgr::execCM_REGCONF()
bool
Qmgr::check_cmregreq_reply(Signal* signal, Uint32 nodeId, Uint32 gsn)
{
NodeRecPtr myNodePtr;
myNodePtr.i = getOwnNodeId();
ptrCheckGuard(myNodePtr, MAX_NDB_NODES, nodeRec);
NodeRecPtr nodePtr;
nodePtr.i = nodeId;
ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec);
/**
* Try to decide if replying node
* knows who is president
*/
Uint32 president_reply = RNIL;
switch(gsn){
case GSN_CM_REGREF:{
jam();
CmRegRef* ref = (CmRegRef*)signal->getDataPtr();
switch(ref->errorCode){
case CmRegRef::ZBUSY:
case CmRegRef::ZBUSY_PRESIDENT:
case CmRegRef::ZBUSY_TO_PRES:
jam();
/**
* Only president replies this
*/
ndbrequire(nodeId == ref->presidentCandidate);
president_reply = nodeId;
break;
case CmRegRef::ZNOT_PRESIDENT:
jam();
president_reply = ref->presidentCandidate;
break;
case CmRegRef::ZNOT_IN_CFG:
case CmRegRef::ZNOT_DEAD:
case CmRegRef::ZELECTION:
// Neither of these replies give certain president knowledge
jam();
}
break;
}
case GSN_CM_REGCONF:
jam();
president_reply = nodeId;
break;
}
char buf[256];
switch(c_start.m_gsn){
case GSN_CM_REGREQ:
jam();
ndbrequire(c_start.m_nodes.isWaitingFor(nodeId));
ndbrequire(c_cmregreq_nodes.isclear());
ndbrequire(myNodePtr.p->phase == ZSTARTING);
return false;
case GSN_CM_NODEINFOREQ:
jam();
ndbrequire(myNodePtr.p->phase == ZSTARTING);
if (c_start.m_nodes.isWaitingFor(nodeId))
{
jam();
/**
* We're waiting for CM_NODEINFO
*/
if (gsn == GSN_CM_REGREF)
{
jam();
return false;
}
jam();
BaseString::snprintf(buf, sizeof(buf),
"Partitioned cluster! check StartPartialTimeout, "
" received CM_REGCONF from %d"
" while waiting for GSN_CM_NODEINFOCONF."
" president=%d",
nodeId, cpresident);
goto die_direct;
}
goto check_reply;
default:
case GSN_CM_NODEINFOCONF:
jam();
ndbrequire(myNodePtr.p->phase == ZRUNNING);
goto check_reply;
}
check_reply:
jam();
c_cmregreq_nodes.clear(nodeId);
if (gsn == GSN_CM_REGCONF)
{
jam();
BaseString::snprintf(buf, sizeof(buf),
"Partitioned cluster! check StartPartialTimeout, "
" received CM_REGCONF"
" from %d I think president: %d",
nodeId, cpresident);
goto die_direct;
}
if (president_reply != RNIL && president_reply != cpresident)
{
jam();
BaseString::snprintf(buf, sizeof(buf),
"Partitioned cluster! check StartPartialTimeout, "
" received CM_REGREF from %d specifying president as"
" %d, president: %d",
nodeId, president_reply, cpresident);
goto die_direct;
}
return false;
die_direct:
ndbout_c(buf);
progError(__LINE__,
ERR_ARBIT_SHUTDOWN,
buf);
ndbrequire(false);
}
void void
Qmgr::sendCmNodeInfoReq(Signal* signal, Uint32 nodeId, const NodeRec * self){ Qmgr::sendCmNodeInfoReq(Signal* signal, Uint32 nodeId, const NodeRec * self){
CmNodeInfoReq * const req = (CmNodeInfoReq*)signal->getDataPtrSend(); CmNodeInfoReq * const req = (CmNodeInfoReq*)signal->getDataPtrSend();
...@@ -685,13 +891,21 @@ Qmgr::sendCmNodeInfoReq(Signal* signal, Uint32 nodeId, const NodeRec * self){ ...@@ -685,13 +891,21 @@ Qmgr::sendCmNodeInfoReq(Signal* signal, Uint32 nodeId, const NodeRec * self){
void Qmgr::execCM_REGREF(Signal* signal) void Qmgr::execCM_REGREF(Signal* signal)
{ {
jamEntry(); jamEntry();
c_regReqReqRecv++;
// Ignore block reference in data[0]
UintR TaddNodeno = signal->theData[1]; UintR TaddNodeno = signal->theData[1];
UintR TrefuseReason = signal->theData[2]; UintR TrefuseReason = signal->theData[2];
Uint32 candidate = signal->theData[3]; Uint32 candidate = signal->theData[3];
DEBUG_START3(signal, TrefuseReason); DEBUG_START3(signal, TrefuseReason);
if (check_cmregreq_reply(signal, TaddNodeno, GSN_CM_REGREF))
{
jam();
return;
}
c_regReqReqRecv++;
// Ignore block reference in data[0]
if(candidate != cpresidentCandidate){ if(candidate != cpresidentCandidate){
jam(); jam();
...@@ -779,7 +993,7 @@ void Qmgr::execCM_REGREF(Signal* signal) ...@@ -779,7 +993,7 @@ void Qmgr::execCM_REGREF(Signal* signal)
Uint64 now = NdbTick_CurrentMillisecond(); Uint64 now = NdbTick_CurrentMillisecond();
if((c_regReqReqRecv == cnoOfNodes) || now > c_stopElectionTime){ if((c_regReqReqRecv == cnoOfNodes) || now > c_stopElectionTime){
jam(); jam();
electionWon(); electionWon(signal);
sendSttorryLab(signal); sendSttorryLab(signal);
/** /**
...@@ -793,7 +1007,7 @@ void Qmgr::execCM_REGREF(Signal* signal) ...@@ -793,7 +1007,7 @@ void Qmgr::execCM_REGREF(Signal* signal)
}//Qmgr::execCM_REGREF() }//Qmgr::execCM_REGREF()
void void
Qmgr::electionWon(){ Qmgr::electionWon(Signal* signal){
NodeRecPtr myNodePtr; NodeRecPtr myNodePtr;
cpresident = getOwnNodeId(); /* This node becomes president. */ cpresident = getOwnNodeId(); /* This node becomes president. */
myNodePtr.i = getOwnNodeId(); myNodePtr.i = getOwnNodeId();
...@@ -812,6 +1026,12 @@ Qmgr::electionWon(){ ...@@ -812,6 +1026,12 @@ Qmgr::electionWon(){
cpresidentAlive = ZTRUE; cpresidentAlive = ZTRUE;
c_stopElectionTime = ~0; c_stopElectionTime = ~0;
c_start.reset(); c_start.reset();
signal->theData[0] = EventReport::CM_REGCONF;
signal->theData[1] = getOwnNodeId();
signal->theData[2] = cpresident;
signal->theData[3] = 1;
sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 4, JBB);
} }
/* /*
...@@ -946,7 +1166,7 @@ Qmgr::cmAddPrepare(Signal* signal, NodeRecPtr nodePtr, const NodeRec * self){ ...@@ -946,7 +1166,7 @@ Qmgr::cmAddPrepare(Signal* signal, NodeRecPtr nodePtr, const NodeRec * self){
ndbrequire(signal->header.theVerId_signalNumber == GSN_CM_ADD); ndbrequire(signal->header.theVerId_signalNumber == GSN_CM_ADD);
c_start.m_nodes.clearWaitingFor(); c_start.m_nodes.clearWaitingFor();
c_start.m_nodes.setWaitingFor(nodePtr.i); c_start.m_nodes.setWaitingFor(nodePtr.i);
c_start.m_gsn = GSN_CM_ADD; c_start.m_gsn = GSN_CM_NODEINFOCONF;
#else #else
warningEvent("Enabling communication to CM_ADD node %u state=%d", warningEvent("Enabling communication to CM_ADD node %u state=%d",
nodePtr.i, nodePtr.i,
...@@ -1847,7 +2067,8 @@ void Qmgr::execDISCONNECT_REP(Signal* signal) ...@@ -1847,7 +2067,8 @@ void Qmgr::execDISCONNECT_REP(Signal* signal)
const DisconnectRep * const rep = (DisconnectRep *)&signal->theData[0]; const DisconnectRep * const rep = (DisconnectRep *)&signal->theData[0];
const Uint32 nodeId = rep->nodeId; const Uint32 nodeId = rep->nodeId;
c_connectedNodes.clear(nodeId); c_connectedNodes.clear(nodeId);
c_cmregreq_nodes.clear(nodeId);
NodeRecPtr nodePtr; NodeRecPtr nodePtr;
nodePtr.i = getOwnNodeId(); nodePtr.i = getOwnNodeId();
ptrCheckGuard(nodePtr, MAX_NODES, nodeRec); ptrCheckGuard(nodePtr, MAX_NODES, nodeRec);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment