DbdihMain.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:494k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1.     jam();
  2.     /* --------------------------------------------------------------------- */
  3.     /*   ERROR IN FIRST FILE, TRY THE SECOND FILE.                           */
  4.     /* --------------------------------------------------------------------- */
  5.     filePtr.i = crestartInfoFile[1];
  6.     ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
  7.     openFileRw(signal, filePtr);
  8.     filePtr.p->reqStatus = FileRecord::OPENING_GCP;
  9.     return;
  10.   }//if
  11.   /* ----------------------------------------------------------------------- */
  12.   /*     WE DISCOVERED A FAILURE WITH THE SECOND FILE AS WELL. THIS IS A     */
  13.   /*     SERIOUS PROBLEM. REPORT FAILURE TO NDBCNTR.                         */
  14.   /* ----------------------------------------------------------------------- */
  15.   sendSignal(cntrlblockref, GSN_DIH_RESTARTREF, signal, 1, JBB);
  16. }//Dbdih::closingGcpCrashLab()
  17. /*****************************************************************************/
  18. /* ------------------------------------------------------------------------- */
  19. /*       THIS IS AN INITIAL RESTART. WE WILL CREATE THE TWO FILES DESCRIBING */
  20. /*       THE GLOBAL CHECKPOINTS THAT ARE RESTORABLE.                         */
  21. /* ------------------------------------------------------------------------- */
  22. /*****************************************************************************/
  23. void Dbdih::initGciFilesLab(Signal* signal) 
  24. {
  25.   FileRecordPtr filePtr;
  26.   filePtr.i = crestartInfoFile[0];
  27.   ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
  28.   createFileRw(signal, filePtr);
  29.   filePtr.p->reqStatus = FileRecord::CREATING_GCP;
  30. }//Dbdih::initGciFilesLab()
  31. /* ------------------------------------------------------------------------- */
  32. /*       GLOBAL CHECKPOINT FILE HAVE BEEN SUCCESSFULLY CREATED.              */
  33. /* ------------------------------------------------------------------------- */
  34. void Dbdih::creatingGcpLab(Signal* signal, FileRecordPtr filePtr) 
  35. {
  36.   if (filePtr.i == crestartInfoFile[0]) {
  37.     jam();
  38.     /* --------------------------------------------------------------------- */
  39.     /*   IF CREATED FIRST THEN ALSO CREATE THE SECOND FILE.                  */
  40.     /* --------------------------------------------------------------------- */
  41.     filePtr.i = crestartInfoFile[1];
  42.     ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
  43.     createFileRw(signal, filePtr);
  44.     filePtr.p->reqStatus = FileRecord::CREATING_GCP;
  45.   } else {
  46.     jam();
  47.     /* --------------------------------------------------------------------- */
  48.     /*   BOTH FILES HAVE BEEN CREATED. NOW WRITE THE INITIAL DATA TO BOTH    */
  49.     /*   OF THE FILES.                                                       */
  50.     /* --------------------------------------------------------------------- */
  51.     filePtr.i = crestartInfoFile[0];
  52.     ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
  53.     writeRestorableGci(signal, filePtr);
  54.     filePtr.p->reqStatus = FileRecord::WRITE_INIT_GCP;
  55.   }//if
  56. }//Dbdih::creatingGcpLab()
  57. /* ------------------------------------------------------------------------- */
  58. /*       WE HAVE SUCCESSFULLY WRITTEN A GCI FILE.                            */
  59. /* ------------------------------------------------------------------------- */
  60. void Dbdih::writeInitGcpLab(Signal* signal, FileRecordPtr filePtr) 
  61. {
  62.   filePtr.p->reqStatus = FileRecord::IDLE;
  63.   if (filePtr.i == crestartInfoFile[0]) {
  64.     jam();
  65.     /* --------------------------------------------------------------------- */
  66.     /*   WE HAVE WRITTEN THE FIRST FILE NOW ALSO WRITE THE SECOND FILE.      */
  67.     /* --------------------------------------------------------------------- */
  68.     filePtr.i = crestartInfoFile[1];
  69.     ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
  70.     writeRestorableGci(signal, filePtr);
  71.     filePtr.p->reqStatus = FileRecord::WRITE_INIT_GCP;
  72.   } else {
  73.     /* --------------------------------------------------------------------- */
  74.     /*   WE HAVE WRITTEN BOTH FILES. LEAVE BOTH FILES OPEN AND CONFIRM OUR   */
  75.     /*   PART OF THE INITIAL START.                                          */
  76.     /* --------------------------------------------------------------------- */
  77.     if (isMaster()) {
  78.       jam();
  79.       /*---------------------------------------------------------------------*/
  80.       // IN MASTER NODES THE START REQUEST IS RECEIVED FROM NDBCNTR AND WE MUST
  81.       // RESPOND WHEN COMPLETED.
  82.       /*---------------------------------------------------------------------*/
  83.       signal->theData[0] = reference();
  84.       sendSignal(cndbStartReqBlockref, GSN_NDB_STARTCONF, signal, 1, JBB);
  85.     } else {
  86.       jam();
  87.       ndbsttorry10Lab(signal, __LINE__);
  88.       return;
  89.     }//if
  90.   }//if
  91. }//Dbdih::writeInitGcpLab()
  92. /*****************************************************************************/
  93. /* **********     NODES DELETION MODULE                          *************/
  94. /*****************************************************************************/
  95. /*---------------------------------------------------------------------------*/
  96. /*                    LOGIC FOR NODE FAILURE                                 */
  97. /*---------------------------------------------------------------------------*/
  98. void Dbdih::execNODE_FAILREP(Signal* signal)
  99. {
  100.   Uint32 i;
  101.   Uint32 failedNodes[MAX_NDB_NODES];
  102.   jamEntry();
  103.   NodeFailRep * const nodeFail = (NodeFailRep *)&signal->theData[0];
  104.   cfailurenr = nodeFail->failNo;
  105.   Uint32 newMasterId = nodeFail->masterNodeId;
  106.   const Uint32 noOfFailedNodes = nodeFail->noOfNodes;
  107.   /*-------------------------------------------------------------------------*/
  108.   // The first step is to convert from a bit mask to an array of failed nodes.
  109.   /*-------------------------------------------------------------------------*/
  110.   Uint32 index = 0;
  111.   for (i = 1; i < MAX_NDB_NODES; i++) {
  112.     jam();
  113.     if(NodeBitmask::get(nodeFail->theNodes, i)){
  114.       jam();
  115.       failedNodes[index] = i;
  116.       index++;
  117.     }//if
  118.   }//for
  119.   ndbrequire(noOfFailedNodes == index);
  120.   ndbrequire(noOfFailedNodes - 1 < MAX_NDB_NODES);
  121.   /*-------------------------------------------------------------------------*/
  122.   // The second step is to update the node status of the failed nodes, remove
  123.   // them from the alive node list and put them into the dead node list. Also
  124.   // update the number of nodes on-line.
  125.   // We also set certain state variables ensuring that the node no longer is 
  126.   // used in transactions and also mark that we received this signal.
  127.   /*-------------------------------------------------------------------------*/
  128.   for (i = 0; i < noOfFailedNodes; i++) {
  129.     jam();
  130.     NodeRecordPtr TNodePtr;
  131.     TNodePtr.i = failedNodes[i];
  132.     ptrCheckGuard(TNodePtr, MAX_NDB_NODES, nodeRecord);
  133.     TNodePtr.p->useInTransactions = false;
  134.     TNodePtr.p->m_inclDihLcp = false;
  135.     TNodePtr.p->recNODE_FAILREP = ZTRUE;
  136.     if (TNodePtr.p->nodeStatus == NodeRecord::ALIVE) {
  137.       jam();
  138.       con_lineNodes--;
  139.       TNodePtr.p->nodeStatus = NodeRecord::DIED_NOW;
  140.       removeAlive(TNodePtr);
  141.       insertDeadNode(TNodePtr);
  142.     }//if
  143.   }//for
  144.   /*-------------------------------------------------------------------------*/
  145.   // Verify that we can continue to operate the cluster. If we cannot we will
  146.   // not return from checkEscalation. 
  147.   /*-------------------------------------------------------------------------*/
  148.   checkEscalation();
  149.   /*------------------------------------------------------------------------*/
  150.   // Verify that a starting node has also crashed. Reset the node start record.
  151.   /*-------------------------------------------------------------------------*/
  152.   if (c_nodeStartMaster.startNode != RNIL) {
  153.     ndbrequire(getNodeStatus(c_nodeStartMaster.startNode)!= NodeRecord::ALIVE);
  154.   }//if
  155.   /*--------------------------------------------------*/
  156.   /*                                                  */
  157.   /*       WE CHANGE THE REFERENCE TO MASTER DIH      */
  158.   /*       BLOCK AND POINTER AT THIS PLACE IN THE CODE*/
  159.   /*--------------------------------------------------*/
  160.   Uint32 oldMasterId = cmasterNodeId;
  161.   BlockReference oldMasterRef = cmasterdihref;
  162.   cmasterdihref = calcDihBlockRef(newMasterId);
  163.   cmasterNodeId = newMasterId;
  164.   const bool masterTakeOver = (oldMasterId != newMasterId);
  165.   for(i = 0; i < noOfFailedNodes; i++) {
  166.     NodeRecordPtr failedNodePtr;
  167.     failedNodePtr.i = failedNodes[i];
  168.     ptrCheckGuard(failedNodePtr, MAX_NDB_NODES, nodeRecord);
  169.     Uint32 activeTakeOverPtr = findTakeOver(failedNodes[i]);
  170.     if (oldMasterRef == reference()) {
  171.       /*-------------------------------------------------------*/
  172.       // Functions that need to be called only for master nodes.
  173.       /*-------------------------------------------------------*/
  174.       checkCopyTab(failedNodePtr);
  175.       checkStopPermMaster(signal, failedNodePtr);
  176.       checkWaitGCPMaster(signal, failedNodes[i]);
  177.       checkTakeOverInMasterAllNodeFailure(signal, failedNodePtr);
  178.       checkTakeOverInMasterCopyNodeFailure(signal, failedNodePtr.i);
  179.       checkTakeOverInMasterStartNodeFailure(signal, activeTakeOverPtr);
  180.       checkGcpOutstanding(signal, failedNodePtr.i);
  181.     } else {
  182.       jam();
  183.       /*-----------------------------------------------------------*/
  184.       // Functions that need to be called only for nodes that were
  185.       // not master before these failures.
  186.       /*-----------------------------------------------------------*/
  187.       checkStopPermProxy(signal, failedNodes[i]);
  188.       checkWaitGCPProxy(signal, failedNodes[i]);
  189.       if (isMaster()) {
  190. /*-----------------------------------------------------------*/
  191. // We take over as master since old master has failed
  192. /*-----------------------------------------------------------*/
  193.         handleTakeOverNewMaster(signal, activeTakeOverPtr);
  194.       } else {
  195. /*-----------------------------------------------------------*/
  196. // We are not master and will not become master.
  197. /*-----------------------------------------------------------*/
  198.         checkTakeOverInNonMasterStartNodeFailure(signal, activeTakeOverPtr);
  199.       }//if
  200.     }//if
  201.     /*--------------------------------------------------*/
  202.     // Functions that need to be called for all nodes.
  203.     /*--------------------------------------------------*/
  204.     checkStopMe(signal, failedNodePtr);
  205.     failedNodeLcpHandling(signal, failedNodePtr);
  206.     checkWaitDropTabFailedLqh(signal, failedNodePtr.i, 0); // 0 = start w/ tab 0
  207.     startRemoveFailedNode(signal, failedNodePtr);
  208.     /**
  209.      * This is the last function called
  210.      *   It modifies failedNodePtr.p->nodeStatus
  211.      */
  212.     failedNodeSynchHandling(signal, failedNodePtr);
  213.   }//for
  214.   
  215.   if(masterTakeOver){
  216.     jam();
  217.     startLcpMasterTakeOver(signal, oldMasterId);
  218.     startGcpMasterTakeOver(signal, oldMasterId);
  219.     if(getNodeState().getNodeRestartInProgress()){
  220.       jam();
  221.       progError(__LINE__, 
  222. ERR_SYSTEM_ERROR,
  223. "Unhandle master failure during node restart");
  224.     }
  225.   }
  226.   
  227.   if (isMaster()) {
  228.     jam();
  229.     setNodeRestartInfoBits();
  230.   }//if
  231. }//Dbdih::execNODE_FAILREP()
  232. void Dbdih::checkCopyTab(NodeRecordPtr failedNodePtr)
  233. {
  234.   jam();
  235.   if(c_nodeStartMaster.startNode != failedNodePtr.i){
  236.     jam();
  237.     return;
  238.   }
  239.   
  240.   switch(c_nodeStartMaster.m_outstandingGsn){
  241.   case GSN_COPY_TABREQ:
  242.     jam();
  243.     ndbrequire(c_COPY_TABREQ_Counter.isWaitingFor(failedNodePtr.i));
  244.     releaseTabPages(failedNodePtr.p->activeTabptr);
  245.     c_COPY_TABREQ_Counter.clearWaitingFor(failedNodePtr.i);
  246.     c_nodeStartMaster.wait = ZFALSE;
  247.     break;
  248.   case GSN_START_INFOREQ:
  249.   case GSN_START_PERMCONF:
  250.   case GSN_DICTSTARTREQ:
  251.   case GSN_START_MECONF:
  252.     jam();
  253.     break;
  254.   default:
  255.     ndbout_c("outstanding gsn: %s(%d)", 
  256.      getSignalName(c_nodeStartMaster.m_outstandingGsn), 
  257.      c_nodeStartMaster.m_outstandingGsn);
  258.     ndbrequire(false);
  259.   }
  260.   
  261.   nodeResetStart();  
  262. }//Dbdih::checkCopyTab()
  263. void Dbdih::checkStopMe(Signal* signal, NodeRecordPtr failedNodePtr)
  264. {
  265.   jam();
  266.   if (c_STOP_ME_REQ_Counter.isWaitingFor(failedNodePtr.i)){
  267.     jam();
  268.     ndbrequire(c_stopMe.clientRef != 0);
  269.     StopMeConf * const stopMeConf = (StopMeConf *)&signal->theData[0];
  270.     stopMeConf->senderRef = calcDihBlockRef(failedNodePtr.i);
  271.     stopMeConf->senderData = c_stopMe.clientData;
  272.     sendSignal(reference(), GSN_STOP_ME_CONF, signal, 
  273.        StopMeConf::SignalLength, JBB);
  274.   }//if
  275. }//Dbdih::checkStopMe()
  276. void Dbdih::checkStopPermMaster(Signal* signal, NodeRecordPtr failedNodePtr)
  277. {
  278.   DihSwitchReplicaRef* const ref = (DihSwitchReplicaRef*)&signal->theData[0];
  279.   jam();
  280.   if (c_DIH_SWITCH_REPLICA_REQ_Counter.isWaitingFor(failedNodePtr.i)){
  281.     jam();
  282.     ndbrequire(c_stopPermMaster.clientRef != 0);
  283.     ref->senderNode = failedNodePtr.i;
  284.     ref->errorCode = StopPermRef::NF_CausedAbortOfStopProcedure;
  285.     sendSignal(reference(), GSN_DIH_SWITCH_REPLICA_REF, signal,
  286.                DihSwitchReplicaRef::SignalLength, JBB);
  287.     return;
  288.   }//if
  289. }//Dbdih::checkStopPermMaster()
  290. void Dbdih::checkStopPermProxy(Signal* signal, NodeId failedNodeId)
  291. {
  292.   jam();
  293.   if(c_stopPermProxy.clientRef != 0 && 
  294.      refToNode(c_stopPermProxy.masterRef) == failedNodeId){
  295.     
  296.     /**
  297.      * The master has failed report to proxy-client
  298.      */
  299.     jam();
  300.     StopPermRef* const ref = (StopPermRef*)&signal->theData[0];
  301.     
  302.     ref->senderData = c_stopPermProxy.clientData;
  303.     ref->errorCode  = StopPermRef::NF_CausedAbortOfStopProcedure;
  304.     sendSignal(c_stopPermProxy.clientRef, GSN_STOP_PERM_REF, signal, 2, JBB);
  305.     c_stopPermProxy.clientRef = 0;
  306.   }//if
  307. }//Dbdih::checkStopPermProxy()
  308. void 
  309. Dbdih::checkTakeOverInMasterAllNodeFailure(Signal* signal, 
  310.    NodeRecordPtr failedNodePtr)
  311. {
  312.   //------------------------------------------------------------------------
  313.   // This code is used to handle the failure of "all" nodes during the 
  314.   // take over when "all" nodes are informed about state changes in 
  315.   // the take over protocol.
  316.   //--------------------------------------------------------------------------
  317.   if (c_START_TOREQ_Counter.isWaitingFor(failedNodePtr.i)){
  318.     jam();
  319.     StartToConf * const conf = (StartToConf *)&signal->theData[0];
  320.     conf->userPtr = c_startToLock;
  321.     conf->sendingNodeId = failedNodePtr.i;
  322.     conf->startingNodeId = getStartNode(c_startToLock);
  323.     sendSignal(reference(), GSN_START_TOCONF, signal, 
  324.        StartToConf::SignalLength, JBB);
  325.   }//if
  326.   if (c_CREATE_FRAGREQ_Counter.isWaitingFor(failedNodePtr.i)){
  327.     jam();
  328.     CreateFragConf * const conf = (CreateFragConf *)&signal->theData[0];
  329.     TakeOverRecordPtr takeOverPtr;
  330.     takeOverPtr.i = c_createFragmentLock;
  331.     ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
  332.     conf->userPtr = takeOverPtr.i;
  333.     conf->tableId = takeOverPtr.p->toCurrentTabref;
  334.     conf->fragId = takeOverPtr.p->toCurrentFragid;
  335.     conf->sendingNodeId = failedNodePtr.i;
  336.     conf->startingNodeId = takeOverPtr.p->toStartingNode;
  337.     sendSignal(reference(), GSN_CREATE_FRAGCONF, signal,
  338.                CreateFragConf::SignalLength, JBB);
  339.   }//if
  340.   if (c_UPDATE_TOREQ_Counter.isWaitingFor(failedNodePtr.i)){
  341.     jam();
  342.     UpdateToConf * const conf = (UpdateToConf *)&signal->theData[0];
  343.     conf->userPtr = c_updateToLock;
  344.     conf->sendingNodeId = failedNodePtr.i;
  345.     conf->startingNodeId = getStartNode(c_updateToLock);
  346.     sendSignal(reference(), GSN_UPDATE_TOCONF, signal, 
  347.        UpdateToConf::SignalLength, JBB);
  348.   }//if
  349.   
  350.   if (c_END_TOREQ_Counter.isWaitingFor(failedNodePtr.i)){
  351.     jam();
  352.     EndToConf * const conf = (EndToConf *)&signal->theData[0];
  353.     conf->userPtr = c_endToLock;
  354.     conf->sendingNodeId = failedNodePtr.i;
  355.     conf->startingNodeId = getStartNode(c_endToLock);
  356.     sendSignal(reference(), GSN_END_TOCONF, signal, 
  357.        EndToConf::SignalLength, JBB);
  358.   }//if
  359. }//Dbdih::checkTakeOverInMasterAllNodeFailure()
  360. void Dbdih::checkTakeOverInMasterCopyNodeFailure(Signal* signal, 
  361.  Uint32 failedNodeId)
  362. {
  363.   //---------------------------------------------------------------------------
  364.   // This code is used to handle failure of the copying node during a take over
  365.   //---------------------------------------------------------------------------
  366.   TakeOverRecordPtr takeOverPtr;
  367.   for (Uint32 i = 0; i < MAX_NDB_NODES; i++) {
  368.     jam();
  369.     takeOverPtr.i = i;
  370.     ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
  371.     if ((takeOverPtr.p->toMasterStatus == TakeOverRecord::COPY_FRAG) &&
  372.         (takeOverPtr.p->toCopyNode == failedNodeId)) {
  373.       jam();
  374.       /**
  375.        * The copying node failed but the system is still operational. 
  376.        * We restart the copy process by selecting a new copy node. 
  377.        * We do not need to add a fragment however since it is already added. 
  378.        * We start again from the prepare create fragment phase.
  379.        */
  380.       prepareSendCreateFragReq(signal, takeOverPtr.i);
  381.     }//if
  382.   }//for
  383. }//Dbdih::checkTakeOverInMasterCopyNodeFailure()
  384. void Dbdih::checkTakeOverInMasterStartNodeFailure(Signal* signal, 
  385.   Uint32 takeOverPtrI)
  386. {
  387.   jam();
  388.   if (takeOverPtrI == RNIL) {
  389.     jam();
  390.     return;
  391.   }
  392.   //-----------------------------------------------------------------------
  393.   // We are the master and the starting node has failed during a take over.
  394.   // We need to handle this failure in different ways depending on the state.
  395.   //-----------------------------------------------------------------------
  396.   TakeOverRecordPtr takeOverPtr;
  397.   takeOverPtr.i = takeOverPtrI;
  398.   ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
  399.   bool ok = false;
  400.   switch (takeOverPtr.p->toMasterStatus) {
  401.   case TakeOverRecord::IDLE:
  402.     //-----------------------------------------------------------------------
  403.     // The state cannot be idle when it has a starting node.
  404.     //-----------------------------------------------------------------------
  405.     ndbrequire(false);
  406.     break;
  407.   case TakeOverRecord::TO_WAIT_START_TAKE_OVER:
  408.     jam();
  409.   case TakeOverRecord::TO_START_COPY:
  410.     jam();
  411.   case TakeOverRecord::TO_START_COPY_ONGOING:
  412.     jam();
  413.   case TakeOverRecord::TO_WAIT_START:
  414.     jam();
  415.   case TakeOverRecord::TO_WAIT_PREPARE_CREATE:
  416.     jam();
  417.   case TakeOverRecord::TO_WAIT_UPDATE_TO:
  418.     jam();
  419.   case TakeOverRecord::TO_WAIT_COMMIT_CREATE:
  420.     jam();
  421.   case TakeOverRecord::TO_END_COPY:
  422.     jam();
  423.   case TakeOverRecord::TO_END_COPY_ONGOING:
  424.     jam();
  425.   case TakeOverRecord::TO_WAIT_ENDING:
  426.     jam();
  427.     //-----------------------------------------------------------------------
  428.     // We will not do anything since an internal signal process is outstanding.
  429.     // When the signal arrives the take over will be released.
  430.     //-----------------------------------------------------------------------
  431.     ok = true;
  432.     break;
  433.   case TakeOverRecord::STARTING:
  434.     jam();
  435.     ok = true;
  436.     c_startToLock = RNIL;
  437.     c_START_TOREQ_Counter.clearWaitingFor();
  438.     endTakeOver(takeOverPtr.i);
  439.     break;
  440.   case TakeOverRecord::TO_UPDATE_TO:
  441.     jam();
  442.     ok = true;
  443.     c_updateToLock = RNIL;
  444.     c_UPDATE_TOREQ_Counter.clearWaitingFor();
  445.     endTakeOver(takeOverPtr.i);
  446.     break;
  447.   case TakeOverRecord::ENDING:
  448.     jam();
  449.     ok = true;
  450.     c_endToLock = RNIL;
  451.     c_END_TOREQ_Counter.clearWaitingFor();
  452.     endTakeOver(takeOverPtr.i);
  453.     break;
  454.   case TakeOverRecord::COMMIT_CREATE:
  455.     ok = true;
  456.     jam();
  457.     {// We have mutex
  458.       Mutex m(signal, c_mutexMgr, takeOverPtr.p->m_switchPrimaryMutexHandle);
  459.       m.unlock(); // Ignore result
  460.     }
  461.     // Fall through
  462.   case TakeOverRecord::PREPARE_CREATE:
  463.     ok = true;
  464.     jam();
  465.     c_createFragmentLock = RNIL;
  466.     c_CREATE_FRAGREQ_Counter.clearWaitingFor();
  467.     endTakeOver(takeOverPtr.i);
  468.     break;
  469.   case TakeOverRecord::LOCK_MUTEX:
  470.     ok = true;
  471.     jam();
  472.     // Lock mutex will return and do endTakeOver
  473.     break;
  474.     
  475.     //-----------------------------------------------------------------------
  476.     // Signals are outstanding to external nodes. These signals carry the node
  477.     // id of the starting node and will not use the take over record if the
  478.     // starting node has failed.
  479.     //-----------------------------------------------------------------------
  480.   case TakeOverRecord::COPY_FRAG:
  481.     ok = true;
  482.     jam();
  483.     //-----------------------------------------------------------------------
  484.     // The starting node will discover the problem. We will receive either
  485.     // COPY_FRAGREQ or COPY_FRAGCONF and then we can release the take over
  486.     // record and end the process. If the copying node should also die then
  487.     // we will try to send prepare create fragment and will then discover
  488.     // that the starting node has failed.
  489.     //-----------------------------------------------------------------------
  490.     break;
  491.   case TakeOverRecord::COPY_ACTIVE:
  492.     ok = true;
  493.     jam();
  494.     //-----------------------------------------------------------------------
  495.     // In this we are waiting for a signal from the starting node. Thus we
  496.     // can release the take over record and end the process.
  497.     //-----------------------------------------------------------------------
  498.     endTakeOver(takeOverPtr.i);
  499.     break;
  500.   case TakeOverRecord::WAIT_LCP:
  501.     ok = true;
  502.     jam();
  503.     //-----------------------------------------------------------------------
  504.     //-----------------------------------------------------------------------
  505.     endTakeOver(takeOverPtr.i);
  506.     break;
  507.     /**
  508.      * The following are states that it should not be possible to "be" in
  509.      */
  510.   case TakeOverRecord::SELECTING_NEXT:
  511.     jam();
  512.   case TakeOverRecord::TO_COPY_COMPLETED:
  513.     jam();
  514.     ndbrequire(false);
  515.   }
  516.   if(!ok){
  517.     jamLine(takeOverPtr.p->toSlaveStatus);
  518.     ndbrequire(ok);
  519.   }
  520. }//Dbdih::checkTakeOverInMasterStartNodeFailure()
  521. void Dbdih::checkTakeOverInNonMasterStartNodeFailure(Signal* signal, 
  522.      Uint32 takeOverPtrI)
  523. {
  524.   jam();
  525.   if (takeOverPtrI == RNIL) {
  526.     jam();
  527.     return;
  528.   }
  529.   //-----------------------------------------------------------------------
  530.   // We are not master and not taking over as master. A take over was ongoing
  531.   // but the starting node has now failed. Handle it according to the state
  532.   // of the take over.
  533.   //-----------------------------------------------------------------------
  534.   TakeOverRecordPtr takeOverPtr;
  535.   takeOverPtr.i = takeOverPtrI;
  536.   ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
  537.   bool ok = false;
  538.   switch (takeOverPtr.p->toSlaveStatus) {
  539.   case TakeOverRecord::TO_SLAVE_IDLE:
  540.     ndbrequire(false);
  541.     break;
  542.   case TakeOverRecord::TO_SLAVE_STARTED:
  543.     jam();
  544.   case TakeOverRecord::TO_SLAVE_CREATE_PREPARE:
  545.     jam();
  546.   case TakeOverRecord::TO_SLAVE_COPY_FRAG_COMPLETED:
  547.     jam();
  548.   case TakeOverRecord::TO_SLAVE_CREATE_COMMIT:
  549.     jam();
  550.   case TakeOverRecord::TO_SLAVE_COPY_COMPLETED:
  551.     jam();
  552.     ok = true;
  553.     endTakeOver(takeOverPtr.i);
  554.     break;
  555.   }//switch
  556.   if(!ok){
  557.     jamLine(takeOverPtr.p->toSlaveStatus);
  558.     ndbrequire(ok);
  559.   }
  560. }//Dbdih::checkTakeOverInNonMasterStartNodeFailure()
  561. void Dbdih::failedNodeSynchHandling(Signal* signal, 
  562.     NodeRecordPtr failedNodePtr)
  563. {
  564.   jam();
  565.   /*----------------------------------------------------*/
  566.   /*       INITIALISE THE VARIABLES THAT KEEP TRACK OF  */
  567.   /*       WHEN A NODE FAILURE IS COMPLETED.            */
  568.   /*----------------------------------------------------*/
  569.   failedNodePtr.p->dbdictFailCompleted = ZFALSE;
  570.   failedNodePtr.p->dbtcFailCompleted = ZFALSE;
  571.   failedNodePtr.p->dbdihFailCompleted = ZFALSE;
  572.   failedNodePtr.p->dblqhFailCompleted = ZFALSE;
  573.   
  574.   failedNodePtr.p->m_NF_COMPLETE_REP.clearWaitingFor();
  575.   NodeRecordPtr nodePtr;
  576.   for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
  577.     ptrAss(nodePtr, nodeRecord);
  578.     if (nodePtr.p->nodeStatus == NodeRecord::ALIVE) {
  579.       jam();
  580.       /**
  581.        * We'r waiting for nodePtr.i to complete 
  582.        * handling of failedNodePtr.i's death
  583.        */
  584.       failedNodePtr.p->m_NF_COMPLETE_REP.setWaitingFor(nodePtr.i);
  585.     } else {
  586.       jam();
  587.       if ((nodePtr.p->nodeStatus == NodeRecord::DYING) &&
  588.           (nodePtr.p->m_NF_COMPLETE_REP.isWaitingFor(failedNodePtr.i))){
  589.         jam();
  590. /*----------------------------------------------------*/
  591. /*       THE NODE FAILED BEFORE REPORTING THE FAILURE */
  592. /*       HANDLING COMPLETED ON THIS FAILED NODE.      */
  593. /*       REPORT THAT NODE FAILURE HANDLING WAS        */
  594. /*       COMPLETED ON THE NEW FAILED NODE FOR THIS    */
  595. /*       PARTICULAR OLD FAILED NODE.                  */
  596. /*----------------------------------------------------*/
  597.         NFCompleteRep * const nf = (NFCompleteRep *)&signal->theData[0];
  598.         nf->blockNo = 0;
  599.         nf->nodeId  = failedNodePtr.i;
  600.         nf->failedNodeId = nodePtr.i;
  601. nf->from    = __LINE__;
  602.         sendSignal(reference(), GSN_NF_COMPLETEREP, signal, 
  603.                    NFCompleteRep::SignalLength, JBB);
  604.       }//if
  605.     }//if
  606.   }//for
  607.   if (failedNodePtr.p->nodeStatus == NodeRecord::DIED_NOW) {
  608.     jam();
  609.     failedNodePtr.p->nodeStatus = NodeRecord::DYING;
  610.   } else {
  611.     jam();
  612.     /*----------------------------------------------------*/
  613.     // No more processing needed when node not even started
  614.     // yet. We give the node status to DEAD since we do not
  615.     // care whether all nodes complete the node failure
  616.     // handling. The node have not been included in the
  617.     // node failure protocols.
  618.     /*----------------------------------------------------*/
  619.     failedNodePtr.p->nodeStatus = NodeRecord::DEAD;
  620.     /**-----------------------------------------------------------------------
  621.      * WE HAVE COMPLETED HANDLING THE NODE FAILURE IN DIH. WE CAN REPORT THIS 
  622.      * TO DIH THAT WAIT FOR THE OTHER BLOCKS TO BE CONCLUDED AS WELL.
  623.      *-----------------------------------------------------------------------*/
  624.     NFCompleteRep * const nf = (NFCompleteRep *)&signal->theData[0];
  625.     nf->blockNo      = DBDIH;
  626.     nf->nodeId       = cownNodeId;
  627.     nf->failedNodeId = failedNodePtr.i;
  628.     nf->from         = __LINE__;
  629.     sendSignal(reference(), GSN_NF_COMPLETEREP, signal, 
  630.                NFCompleteRep::SignalLength, JBB);
  631.   }//if
  632. }//Dbdih::failedNodeSynchHandling()
  633. Uint32 Dbdih::findTakeOver(Uint32 failedNodeId)
  634. {
  635.   for (Uint32 i = 0; i < MAX_NDB_NODES; i++) {
  636.     jam();
  637.     TakeOverRecordPtr takeOverPtr;
  638.     takeOverPtr.i = i;
  639.     ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
  640.     if (takeOverPtr.p->toStartingNode == failedNodeId) {
  641.       jam();
  642.       return i;
  643.     }//if
  644.   }//for
  645.   return RNIL;
  646. }//Dbdih::findTakeOver()
  647. Uint32 Dbdih::getStartNode(Uint32 takeOverPtrI)
  648. {
  649.   TakeOverRecordPtr takeOverPtr;
  650.   takeOverPtr.i = takeOverPtrI;
  651.   ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
  652.   return takeOverPtr.p->toStartingNode;
  653. }//Dbdih::getStartNode()
  654. void Dbdih::failedNodeLcpHandling(Signal* signal, NodeRecordPtr failedNodePtr)
  655. {
  656.   jam();
  657.   const Uint32 nodeId = failedNodePtr.i;
  658.   if (c_lcpState.m_participatingLQH.get(failedNodePtr.i)){
  659.     /*----------------------------------------------------*/
  660.     /*  THE NODE WAS INVOLVED IN A LOCAL CHECKPOINT. WE   */
  661.     /* MUST UPDATE THE ACTIVE STATUS TO INDICATE THAT     */
  662.     /* THE NODE HAVE MISSED A LOCAL CHECKPOINT.           */
  663.     /*----------------------------------------------------*/
  664.     switch (failedNodePtr.p->activeStatus) {
  665.     case Sysfile::NS_Active:
  666.       jam();
  667.       failedNodePtr.p->activeStatus = Sysfile::NS_ActiveMissed_1;
  668.       break;
  669.     case Sysfile::NS_ActiveMissed_1:
  670.       jam();
  671.       failedNodePtr.p->activeStatus = Sysfile::NS_ActiveMissed_2;
  672.       break;
  673.     case Sysfile::NS_ActiveMissed_2:
  674.       jam();
  675.       failedNodePtr.p->activeStatus = Sysfile::NS_NotActive_NotTakenOver;
  676.       break;
  677.     case Sysfile::NS_TakeOver:
  678.       jam();
  679.       failedNodePtr.p->activeStatus = Sysfile::NS_NotActive_NotTakenOver;
  680.       break;
  681.     default:
  682.       ndbout << "activeStatus = " << (Uint32) failedNodePtr.p->activeStatus;
  683.       ndbout << " at failure after NODE_FAILREP of node = ";
  684.       ndbout << failedNodePtr.i << endl;
  685.       ndbrequire(false);
  686.       break;
  687.     }//switch
  688.   }//if
  689.   c_lcpState.m_participatingDIH.clear(failedNodePtr.i);
  690.   c_lcpState.m_participatingLQH.clear(failedNodePtr.i);
  691.   if(c_lcpState.m_LCP_COMPLETE_REP_Counter_DIH.isWaitingFor(failedNodePtr.i)){
  692.     jam();
  693.     LcpCompleteRep * rep = (LcpCompleteRep*)signal->getDataPtrSend();
  694.     rep->nodeId = failedNodePtr.i;
  695.     rep->lcpId = SYSFILE->latestLCP_ID;
  696.     rep->blockNo = DBDIH;
  697.     sendSignal(reference(), GSN_LCP_COMPLETE_REP, signal, 
  698.        LcpCompleteRep::SignalLength, JBB);
  699.   }
  700.   /**
  701.    * Check if we'r waiting for the failed node's LQH to complete
  702.    *
  703.    * Note that this is ran "before" LCP master take over
  704.    */
  705.   if(c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH.isWaitingFor(nodeId)){
  706.     jam();
  707.     LcpCompleteRep * rep = (LcpCompleteRep*)signal->getDataPtrSend();
  708.     rep->nodeId  = nodeId;
  709.     rep->lcpId   = SYSFILE->latestLCP_ID;
  710.     rep->blockNo = DBLQH;
  711.     sendSignal(reference(), GSN_LCP_COMPLETE_REP, signal, 
  712.        LcpCompleteRep::SignalLength, JBB);
  713.     if(c_lcpState.m_LAST_LCP_FRAG_ORD.isWaitingFor(nodeId)){
  714.       jam();
  715.       /**
  716.        * Make sure we're ready to accept it
  717.        */
  718.       c_lcpState.m_LAST_LCP_FRAG_ORD.clearWaitingFor(nodeId);
  719.     }
  720.   }
  721.   
  722.   if (c_TCGETOPSIZEREQ_Counter.isWaitingFor(failedNodePtr.i)) {
  723.     jam();
  724.     signal->theData[0] = failedNodePtr.i;
  725.     signal->theData[1] = 0;
  726.     sendSignal(reference(), GSN_TCGETOPSIZECONF, signal, 2, JBB);
  727.   }//if
  728.   
  729.   if (c_TC_CLOPSIZEREQ_Counter.isWaitingFor(failedNodePtr.i)) {
  730.     jam();
  731.     signal->theData[0] = failedNodePtr.i;
  732.     sendSignal(reference(), GSN_TC_CLOPSIZECONF, signal, 1, JBB);
  733.   }//if
  734.   if (c_START_LCP_REQ_Counter.isWaitingFor(failedNodePtr.i)) {
  735.     jam();
  736.     StartLcpConf * conf = (StartLcpConf*)signal->getDataPtrSend();
  737.     conf->senderRef = numberToRef(DBLQH, failedNodePtr.i);
  738.     conf->lcpId = SYSFILE->latestLCP_ID;
  739.     sendSignal(reference(), GSN_START_LCP_CONF, signal, 
  740.        StartLcpConf::SignalLength, JBB);
  741.   }//if
  742.   
  743.   if (c_EMPTY_LCP_REQ_Counter.isWaitingFor(failedNodePtr.i)) {
  744.     jam();
  745.     EmptyLcpConf * const rep = (EmptyLcpConf *)&signal->theData[0];
  746.     rep->senderNodeId = failedNodePtr.i;
  747.     rep->tableId = ~0;
  748.     rep->fragmentId = ~0;
  749.     rep->lcpNo = 0;
  750.     rep->lcpId = SYSFILE->latestLCP_ID;
  751.     rep->idle = true;
  752.     sendSignal(reference(), GSN_EMPTY_LCP_CONF, signal, 
  753.        EmptyLcpConf::SignalLength, JBB);
  754.   }//if
  755.   if (c_MASTER_LCPREQ_Counter.isWaitingFor(failedNodePtr.i)) {
  756.     jam();
  757.     MasterLCPRef * const ref = (MasterLCPRef *)&signal->theData[0];
  758.     ref->senderNodeId = failedNodePtr.i;
  759.     ref->failedNodeId = cmasterTakeOverNode;
  760.     sendSignal(reference(), GSN_MASTER_LCPREF, signal, 
  761.        MasterLCPRef::SignalLength, JBB);
  762.   }//if
  763.   
  764. }//Dbdih::failedNodeLcpHandling()
  765. void Dbdih::checkGcpOutstanding(Signal* signal, Uint32 failedNodeId){
  766.   if (c_GCP_PREPARE_Counter.isWaitingFor(failedNodeId)){
  767.     jam();
  768.     signal->theData[0] = failedNodeId;
  769.     signal->theData[1] = cnewgcp;
  770.     sendSignal(reference(), GSN_GCP_PREPARECONF, signal, 2, JBB);
  771.   }//if
  772.   if (c_GCP_COMMIT_Counter.isWaitingFor(failedNodeId)) {
  773.     jam();
  774.     signal->theData[0] = failedNodeId;
  775.     signal->theData[1] = coldgcp;
  776.     signal->theData[2] = cfailurenr;
  777.     sendSignal(reference(), GSN_GCP_NODEFINISH, signal, 3, JBB);
  778.   }//if
  779.   if (c_GCP_SAVEREQ_Counter.isWaitingFor(failedNodeId)) {
  780.     jam();
  781.     GCPSaveRef * const saveRef = (GCPSaveRef*)&signal->theData[0];
  782.     saveRef->dihPtr = failedNodeId;
  783.     saveRef->nodeId = failedNodeId;
  784.     saveRef->gci    = coldgcp;
  785.     saveRef->errorCode = GCPSaveRef::FakedSignalDueToNodeFailure;
  786.     sendSignal(reference(), GSN_GCP_SAVEREF, signal, 
  787.        GCPSaveRef::SignalLength, JBB);
  788.   }//if
  789.   if (c_COPY_GCIREQ_Counter.isWaitingFor(failedNodeId)) {
  790.     jam();
  791.     signal->theData[0] = failedNodeId;
  792.     sendSignal(reference(), GSN_COPY_GCICONF, signal, 1, JBB);
  793.   }//if
  794.   
  795.   if (c_MASTER_GCPREQ_Counter.isWaitingFor(failedNodeId)){
  796.     jam();
  797.     MasterGCPRef * const ref = (MasterGCPRef *)&signal->theData[0];
  798.     ref->senderNodeId = failedNodeId;
  799.     ref->failedNodeId = cmasterTakeOverNode;
  800.     sendSignal(reference(), GSN_MASTER_GCPREF, signal, 
  801.        MasterGCPRef::SignalLength, JBB);
  802.   }//if
  803. }//Dbdih::handleGcpStateInMaster()
  804.  
  805.  
  806. void
  807. Dbdih::startLcpMasterTakeOver(Signal* signal, Uint32 nodeId){
  808.   jam();
  809.   c_lcpMasterTakeOverState.minTableId = ~0;
  810.   c_lcpMasterTakeOverState.minFragId = ~0;
  811.   c_lcpMasterTakeOverState.failedNodeId = nodeId;
  812.   
  813.   c_lcpMasterTakeOverState.set(LMTOS_WAIT_EMPTY_LCP, __LINE__);
  814.   
  815.   if(c_EMPTY_LCP_REQ_Counter.done()){
  816.     jam();
  817.     c_lcpState.m_LAST_LCP_FRAG_ORD.clearWaitingFor();
  818.     EmptyLcpReq* req = (EmptyLcpReq*)signal->getDataPtrSend();
  819.     req->senderRef = reference();
  820.     sendLoopMacro(EMPTY_LCP_REQ, sendEMPTY_LCP_REQ);
  821.     ndbrequire(!c_EMPTY_LCP_REQ_Counter.done());
  822.   } else {
  823.     /**
  824.      * Node failure during master take over...
  825.      */
  826.     ndbout_c("Nodefail during master take over");
  827.   }
  828.   
  829.   setLocalNodefailHandling(signal, nodeId, NF_LCP_TAKE_OVER);
  830. }
  831. void Dbdih::startGcpMasterTakeOver(Signal* signal, Uint32 oldMasterId){
  832.   jam();
  833.   /*--------------------------------------------------*/
  834.   /*                                                  */
  835.   /*       THE MASTER HAVE FAILED AND WE WERE ELECTED */
  836.   /*       TO BE THE NEW MASTER NODE. WE NEED TO QUERY*/
  837.   /*       ALL THE OTHER NODES ABOUT THEIR STATUS IN  */
  838.   /*       ORDER TO BE ABLE TO TAKE OVER CONTROL OF   */
  839.   /*       THE GLOBAL CHECKPOINT PROTOCOL AND THE     */
  840.   /*       LOCAL CHECKPOINT PROTOCOL.                 */
  841.   /*--------------------------------------------------*/
  842.   if(!isMaster()){
  843.     jam();
  844.     return;
  845.   }
  846.   cmasterState = MASTER_TAKE_OVER_GCP;
  847.   cmasterTakeOverNode = oldMasterId;
  848.   MasterGCPReq * const req = (MasterGCPReq *)&signal->theData[0];  
  849.   req->masterRef = reference();
  850.   req->failedNodeId = oldMasterId;
  851.   sendLoopMacro(MASTER_GCPREQ, sendMASTER_GCPREQ);
  852.   cgcpMasterTakeOverState = GMTOS_INITIAL;
  853.   
  854.   signal->theData[0] = EventReport::GCP_TakeoverStarted;
  855.   sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB);
  856.   setLocalNodefailHandling(signal, oldMasterId, NF_GCP_TAKE_OVER);
  857. }//Dbdih::handleNewMaster()
  858. void Dbdih::handleTakeOverNewMaster(Signal* signal, Uint32 takeOverPtrI)
  859. {
  860.   jam();
  861.   if (takeOverPtrI != RNIL) {
  862.     jam();
  863.     TakeOverRecordPtr takeOverPtr;
  864.     takeOverPtr.i = takeOverPtrI;
  865.     ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
  866.     bool ok = false;
  867.     switch (takeOverPtr.p->toSlaveStatus) {
  868.     case TakeOverRecord::TO_SLAVE_IDLE:
  869.       ndbrequire(false);
  870.       break;
  871.     case TakeOverRecord::TO_SLAVE_STARTED:
  872.       jam();
  873.     case TakeOverRecord::TO_SLAVE_CREATE_PREPARE:
  874.       jam();
  875.     case TakeOverRecord::TO_SLAVE_COPY_FRAG_COMPLETED:
  876.       jam();
  877.     case TakeOverRecord::TO_SLAVE_CREATE_COMMIT:
  878.       jam();
  879.       ok = true;
  880.       infoEvent("Unhandled MasterTO of TO slaveStatus=%d killing node %d",
  881. takeOverPtr.p->toSlaveStatus,
  882. takeOverPtr.p->toStartingNode);
  883.       takeOverPtr.p->toMasterStatus = TakeOverRecord::COPY_ACTIVE;
  884.       
  885.       {
  886. BlockReference cntrRef = calcNdbCntrBlockRef(takeOverPtr.p->toStartingNode);
  887. SystemError * const sysErr = (SystemError*)&signal->theData[0];
  888. sysErr->errorCode = SystemError::CopyFragRefError;
  889. sysErr->errorRef = reference();
  890. sysErr->data1= 0;
  891. sysErr->data2= __LINE__;
  892. sendSignal(cntrRef, GSN_SYSTEM_ERROR, signal, 
  893.    SystemError::SignalLength, JBB);
  894.       }
  895.       break;
  896.     case TakeOverRecord::TO_SLAVE_COPY_COMPLETED:
  897.       ok = true;
  898.       jam();
  899.       takeOverPtr.p->toMasterStatus = TakeOverRecord::WAIT_LCP;
  900.       break;
  901.     }
  902.     ndbrequire(ok);
  903.   }//if
  904. }//Dbdih::handleTakeOverNewMaster()
  905. void Dbdih::startRemoveFailedNode(Signal* signal, NodeRecordPtr failedNodePtr)
  906. {
  907.   Uint32 nodeId = failedNodePtr.i;
  908.   if(failedNodePtr.p->nodeStatus != NodeRecord::DIED_NOW){
  909.     jam();
  910.     /**
  911.      * Is node isn't alive. It can't be part of LCP
  912.      */
  913.     ndbrequire(!c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH.isWaitingFor(nodeId));
  914.     
  915.     /**
  916.      * And there is no point in removing any replicas
  917.      *   It's dead...
  918.      */
  919.     return;
  920.   }
  921.   
  922.   jam();
  923.   signal->theData[0] = DihContinueB::ZREMOVE_NODE_FROM_TABLE;
  924.   signal->theData[1] = failedNodePtr.i;
  925.   signal->theData[2] = 0; // Tab id
  926.   sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
  927.   
  928.   setLocalNodefailHandling(signal, failedNodePtr.i, NF_REMOVE_NODE_FROM_TABLE);
  929. }//Dbdih::startRemoveFailedNode()
  930. /*--------------------------------------------------*/
  931. /*       THE MASTER HAS FAILED AND THE NEW MASTER IS*/
  932. /*       QUERYING THIS NODE ABOUT THE STATE OF THE  */
  933. /*       GLOBAL CHECKPOINT PROTOCOL                 */
  934. /*--------------------------------------------------*/
  935. void Dbdih::execMASTER_GCPREQ(Signal* signal) 
  936. {
  937.   NodeRecordPtr failedNodePtr;
  938.   MasterGCPReq * const masterGCPReq = (MasterGCPReq *)&signal->theData[0];  
  939.   jamEntry();
  940.   const BlockReference newMasterBlockref = masterGCPReq->masterRef;
  941.   const Uint32 failedNodeId = masterGCPReq->failedNodeId;
  942.   if (c_copyGCISlave.m_copyReason != CopyGCIReq::IDLE) {
  943.     jam();
  944.     /*--------------------------------------------------*/
  945.     /*       WE ARE CURRENTLY WRITING THE RESTART INFO  */
  946.     /*       IN THIS NODE. SINCE ONLY ONE PROCESS IS    */
  947.     /*       ALLOWED TO DO THIS AT A TIME WE MUST ENSURE*/
  948.     /*       THAT THIS IS NOT ONGOING WHEN THE NEW      */
  949.     /*       MASTER TAKES OVER CONTROL. IF NOT ALL NODES*/
  950.     /*       RECEIVE THE SAME RESTART INFO DUE TO THE   */
  951.     /*       FAILURE OF THE MASTER IT IS TAKEN CARE OF  */
  952.     /*       BY THE NEW MASTER.                         */
  953.     /*--------------------------------------------------*/
  954.     sendSignalWithDelay(reference(), GSN_MASTER_GCPREQ,
  955.                         signal, 10, MasterGCPReq::SignalLength);
  956.     return;
  957.   }//if
  958.   failedNodePtr.i = failedNodeId;
  959.   ptrCheckGuard(failedNodePtr, MAX_NDB_NODES, nodeRecord);
  960.   if (failedNodePtr.p->nodeStatus == NodeRecord::ALIVE) {
  961.     jam();
  962.     /*--------------------------------------------------*/
  963.     /*       ENSURE THAT WE HAVE PROCESSED THE SIGNAL   */
  964.     /*       NODE_FAILURE BEFORE WE PROCESS THIS REQUEST*/
  965.     /*       FROM THE NEW MASTER. THIS ENSURES THAT WE  */
  966.     /*       HAVE REMOVED THE FAILED NODE FROM THE LIST */
  967.     /*       OF ACTIVE NODES AND SO FORTH.              */
  968.     /*--------------------------------------------------*/
  969.     sendSignalWithDelay(reference(), GSN_MASTER_GCPREQ,
  970.                         signal, 10, MasterGCPReq::SignalLength);
  971.     return;
  972.   } else {
  973.     ndbrequire(failedNodePtr.p->nodeStatus == NodeRecord::DYING);
  974.   }//if
  975.   MasterGCPConf::State gcpState;
  976.   switch (cgcpParticipantState) {
  977.   case GCP_PARTICIPANT_READY:
  978.     jam();
  979.     /*--------------------------------------------------*/
  980.     /*       THE GLOBAL CHECKPOINT IS NOT ACTIVE SINCE  */
  981.     /*       THE PREVIOUS GLOBAL CHECKPOINT IS COMPLETED*/
  982.     /*       AND THE NEW HAVE NOT STARTED YET.          */
  983.     /*--------------------------------------------------*/
  984.     gcpState = MasterGCPConf::GCP_READY;
  985.     break;
  986.   case GCP_PARTICIPANT_PREPARE_RECEIVED:
  987.     jam();
  988.     /*--------------------------------------------------*/
  989.     /*       GCP_PREPARE HAVE BEEN RECEIVED AND RESPONSE*/
  990.     /*       HAVE BEEN SENT.                            */
  991.     /*--------------------------------------------------*/
  992.     gcpState = MasterGCPConf::GCP_PREPARE_RECEIVED;
  993.     break;
  994.   case GCP_PARTICIPANT_COMMIT_RECEIVED:
  995.     jam();
  996.     /*------------------------------------------------*/
  997.     /*       GCP_COMMIT HAVE BEEN RECEIVED BUT NOT YET*/
  998.     /*       GCP_TCFINISHED FROM LOCAL TC.            */
  999.     /*------------------------------------------------*/
  1000.     gcpState = MasterGCPConf::GCP_COMMIT_RECEIVED;
  1001.     break;
  1002.   case GCP_PARTICIPANT_TC_FINISHED:
  1003.     jam();
  1004.     /*------------------------------------------------*/
  1005.     /*       GCP_COMMIT HAS BEEN RECEIVED AND ALSO    */
  1006.     /*       GCP_TCFINISHED HAVE BEEN RECEIVED.       */
  1007.     /*------------------------------------------------*/
  1008.     gcpState = MasterGCPConf::GCP_TC_FINISHED;
  1009.     break;
  1010.   case GCP_PARTICIPANT_COPY_GCI_RECEIVED:
  1011.     /*--------------------------------------------------*/
  1012.     /*       COPY RESTART INFORMATION HAS BEEN RECEIVED */
  1013.     /*       BUT NOT YET COMPLETED.                     */
  1014.     /*--------------------------------------------------*/
  1015.     ndbrequire(false);
  1016.     gcpState= MasterGCPConf::GCP_READY; // remove warning
  1017.     break;
  1018.   default:
  1019.     /*------------------------------------------------*/
  1020.     /*                                                */
  1021.     /*       THIS SHOULD NOT OCCUR SINCE THE ABOVE    */
  1022.     /*       STATES ARE THE ONLY POSSIBLE STATES AT A */
  1023.     /*       NODE WHICH WAS NOT A MASTER NODE.        */
  1024.     /*------------------------------------------------*/
  1025.     ndbrequire(false);
  1026.     gcpState= MasterGCPConf::GCP_READY; // remove warning
  1027.     break;
  1028.   }//switch
  1029.   MasterGCPConf * const masterGCPConf = (MasterGCPConf *)&signal->theData[0];  
  1030.   masterGCPConf->gcpState  = gcpState;
  1031.   masterGCPConf->senderNodeId = cownNodeId;
  1032.   masterGCPConf->failedNodeId = failedNodeId;
  1033.   masterGCPConf->newGCP = cnewgcp;
  1034.   masterGCPConf->latestLCP = SYSFILE->latestLCP_ID;
  1035.   masterGCPConf->oldestRestorableGCI = SYSFILE->oldestRestorableGCI;
  1036.   masterGCPConf->keepGCI = SYSFILE->keepGCI;  
  1037.   for(Uint32 i = 0; i < NdbNodeBitmask::Size; i++)
  1038.     masterGCPConf->lcpActive[i] = SYSFILE->lcpActive[i];
  1039.   sendSignal(newMasterBlockref, GSN_MASTER_GCPCONF, signal, 
  1040.              MasterGCPConf::SignalLength, JBB);
  1041. }//Dbdih::execMASTER_GCPREQ()
  1042. void Dbdih::execMASTER_GCPCONF(Signal* signal) 
  1043. {
  1044.   NodeRecordPtr senderNodePtr;
  1045.   MasterGCPConf * const masterGCPConf = (MasterGCPConf *)&signal->theData[0];
  1046.   jamEntry();
  1047.   senderNodePtr.i = masterGCPConf->senderNodeId;
  1048.   ptrCheckGuard(senderNodePtr, MAX_NDB_NODES, nodeRecord);
  1049.   
  1050.   MasterGCPConf::State gcpState = (MasterGCPConf::State)masterGCPConf->gcpState;
  1051.   const Uint32 failedNodeId = masterGCPConf->failedNodeId;
  1052.   const Uint32 newGcp = masterGCPConf->newGCP;
  1053.   const Uint32 latestLcpId = masterGCPConf->latestLCP;
  1054.   const Uint32 oldestRestorableGci = masterGCPConf->oldestRestorableGCI;
  1055.   const Uint32 oldestKeepGci = masterGCPConf->keepGCI;
  1056.   if (latestLcpId > SYSFILE->latestLCP_ID) {
  1057.     jam();
  1058. #if 0
  1059.     ndbout_c("Dbdih: Setting SYSFILE->latestLCP_ID to %d", latestLcpId);
  1060.     SYSFILE->latestLCP_ID = latestLcpId;
  1061. #endif
  1062.     SYSFILE->keepGCI = oldestKeepGci;
  1063.     SYSFILE->oldestRestorableGCI = oldestRestorableGci;
  1064.     for(Uint32 i = 0; i < NdbNodeBitmask::Size; i++)
  1065.       SYSFILE->lcpActive[i] = masterGCPConf->lcpActive[i];
  1066.   }//if
  1067.   switch (gcpState) {
  1068.   case MasterGCPConf::GCP_READY:
  1069.     jam();
  1070.     senderNodePtr.p->gcpstate = NodeRecord::READY;
  1071.     break;
  1072.   case MasterGCPConf::GCP_PREPARE_RECEIVED:
  1073.     jam();
  1074.     senderNodePtr.p->gcpstate = NodeRecord::PREPARE_RECEIVED;
  1075.     cnewgcp = newGcp;
  1076.     break;
  1077.   case MasterGCPConf::GCP_COMMIT_RECEIVED:
  1078.     jam();
  1079.     senderNodePtr.p->gcpstate = NodeRecord::COMMIT_SENT;
  1080.     break;
  1081.   case MasterGCPConf::GCP_TC_FINISHED:
  1082.     jam();
  1083.     senderNodePtr.p->gcpstate = NodeRecord::NODE_FINISHED;
  1084.     break;
  1085.   default:
  1086.     ndbrequire(false);
  1087.     break;
  1088.   }//switch
  1089.   switch (cgcpMasterTakeOverState) {
  1090.   case GMTOS_INITIAL:
  1091.     switch (gcpState) {
  1092.     case MasterGCPConf::GCP_READY:
  1093.       jam();
  1094.       cgcpMasterTakeOverState = ALL_READY;
  1095.       break;
  1096.     case MasterGCPConf::GCP_PREPARE_RECEIVED:
  1097.       jam();
  1098.       cgcpMasterTakeOverState = ALL_PREPARED;
  1099.       break;
  1100.     case MasterGCPConf::GCP_COMMIT_RECEIVED:
  1101.       jam();
  1102.       cgcpMasterTakeOverState = COMMIT_STARTED_NOT_COMPLETED;
  1103.       break;
  1104.     case MasterGCPConf::GCP_TC_FINISHED:
  1105.       jam();
  1106.       cgcpMasterTakeOverState = COMMIT_COMPLETED;
  1107.       break;
  1108.     default:
  1109.       ndbrequire(false);
  1110.       break;
  1111.     }//switch
  1112.     break;
  1113.   case ALL_READY:
  1114.     switch (gcpState) {
  1115.     case MasterGCPConf::GCP_READY:
  1116.       jam();
  1117.       /*empty*/;
  1118.       break;
  1119.     case MasterGCPConf::GCP_PREPARE_RECEIVED:
  1120.       jam();
  1121.       cgcpMasterTakeOverState = PREPARE_STARTED_NOT_COMMITTED;
  1122.       break;
  1123.     case MasterGCPConf::GCP_COMMIT_RECEIVED:
  1124.       ndbrequire(false);
  1125.       break;
  1126.     case MasterGCPConf::GCP_TC_FINISHED:
  1127.       jam();
  1128.       cgcpMasterTakeOverState = SAVE_STARTED_NOT_COMPLETED;
  1129.       break;
  1130.     default:
  1131.       ndbrequire(false);
  1132.       break;
  1133.     }//switch
  1134.     break;
  1135.   case PREPARE_STARTED_NOT_COMMITTED:
  1136.     switch (gcpState) {
  1137.     case MasterGCPConf::GCP_READY:
  1138.       jam();
  1139.       break;
  1140.     case MasterGCPConf::GCP_PREPARE_RECEIVED:
  1141.       jam();
  1142.       break;
  1143.     case MasterGCPConf::GCP_COMMIT_RECEIVED:
  1144.       ndbrequire(false);
  1145.       break;
  1146.     case MasterGCPConf::GCP_TC_FINISHED:
  1147.       ndbrequire(false);
  1148.       break;
  1149.     default:
  1150.       ndbrequire(false);
  1151.       break;
  1152.     }//switch
  1153.     break;
  1154.   case ALL_PREPARED:
  1155.     switch (gcpState) {
  1156.     case MasterGCPConf::GCP_READY:
  1157.       jam();
  1158.       cgcpMasterTakeOverState = PREPARE_STARTED_NOT_COMMITTED;
  1159.       break;
  1160.     case MasterGCPConf::GCP_PREPARE_RECEIVED:
  1161.       jam();
  1162.       break;
  1163.     case MasterGCPConf::GCP_COMMIT_RECEIVED:
  1164.       jam();
  1165.       cgcpMasterTakeOverState = COMMIT_STARTED_NOT_COMPLETED;
  1166.       break;
  1167.     case MasterGCPConf::GCP_TC_FINISHED:
  1168.       jam();
  1169.       cgcpMasterTakeOverState = COMMIT_STARTED_NOT_COMPLETED;
  1170.       break;
  1171.     default:
  1172.       ndbrequire(false);
  1173.       break;
  1174.     }//switch
  1175.     break;
  1176.   case COMMIT_STARTED_NOT_COMPLETED:
  1177.     switch (gcpState) {
  1178.     case MasterGCPConf::GCP_READY:
  1179.       ndbrequire(false);
  1180.       break;
  1181.     case MasterGCPConf::GCP_PREPARE_RECEIVED:
  1182.       jam();
  1183.       break;
  1184.     case MasterGCPConf::GCP_COMMIT_RECEIVED:
  1185.       jam();
  1186.       break;
  1187.     case MasterGCPConf::GCP_TC_FINISHED:
  1188.       jam();
  1189.       break;
  1190.     default:
  1191.       ndbrequire(false);
  1192.       break;
  1193.     }//switch
  1194.     break;
  1195.   case COMMIT_COMPLETED:
  1196.     switch (gcpState) {
  1197.     case MasterGCPConf::GCP_READY:
  1198.       cgcpMasterTakeOverState = SAVE_STARTED_NOT_COMPLETED;
  1199.       break;
  1200.     case MasterGCPConf::GCP_PREPARE_RECEIVED:
  1201.       jam();
  1202.       cgcpMasterTakeOverState = COMMIT_STARTED_NOT_COMPLETED;
  1203.       break;
  1204.     case MasterGCPConf::GCP_COMMIT_RECEIVED:
  1205.       jam();
  1206.       cgcpMasterTakeOverState = COMMIT_STARTED_NOT_COMPLETED;
  1207.       break;
  1208.     case MasterGCPConf::GCP_TC_FINISHED:
  1209.       jam();
  1210.       break;
  1211.     default:
  1212.       ndbrequire(false);
  1213.       break;
  1214.     }//switch
  1215.     break;
  1216.   case SAVE_STARTED_NOT_COMPLETED:
  1217.     switch (gcpState) {
  1218.     case MasterGCPConf::GCP_READY:
  1219.       jam();
  1220.       break;
  1221.     case MasterGCPConf::GCP_PREPARE_RECEIVED:
  1222.       ndbrequire(false);
  1223.       break;
  1224.     case MasterGCPConf::GCP_COMMIT_RECEIVED:
  1225.       ndbrequire(false);
  1226.       break;
  1227.     case MasterGCPConf::GCP_TC_FINISHED:
  1228.       jam();
  1229.       break;
  1230.     default:
  1231.       ndbrequire(false);
  1232.       break;
  1233.     }//switch
  1234.     break;
  1235.   default:
  1236.     ndbrequire(false);
  1237.     break;
  1238.   }//switch
  1239.   receiveLoopMacro(MASTER_GCPREQ, senderNodePtr.i);
  1240.   /*-------------------------------------------------------------------------*/
  1241.   // We have now received all responses and are ready to take over the GCP
  1242.   // protocol as master.
  1243.   /*-------------------------------------------------------------------------*/
  1244.   MASTER_GCPhandling(signal, failedNodeId);
  1245.   return;
  1246. }//Dbdih::execMASTER_GCPCONF()
  1247. void Dbdih::execMASTER_GCPREF(Signal* signal) 
  1248. {
  1249.   const MasterGCPRef * const ref = (MasterGCPRef *)&signal->theData[0];
  1250.   jamEntry();
  1251.   receiveLoopMacro(MASTER_GCPREQ, ref->senderNodeId);
  1252.   /*-------------------------------------------------------------------------*/
  1253.   // We have now received all responses and are ready to take over the GCP
  1254.   // protocol as master.
  1255.   /*-------------------------------------------------------------------------*/
  1256.   MASTER_GCPhandling(signal, ref->failedNodeId);
  1257. }//Dbdih::execMASTER_GCPREF()
  1258. void Dbdih::MASTER_GCPhandling(Signal* signal, Uint32 failedNodeId) 
  1259. {
  1260.   NodeRecordPtr failedNodePtr;
  1261.   cmasterState = MASTER_ACTIVE;
  1262.   /*----------------------------------------------------------*/
  1263.   /*       REMOVE ALL ACTIVE STATUS ON ALREADY FAILED NODES   */
  1264.   /*       THIS IS PERFORMED HERE SINCE WE GET THE LCP ACTIVE */
  1265.   /*       STATUS AS PART OF THE COPY RESTART INFO AND THIS IS*/
  1266.   /*       HANDLED BY THE MASTER GCP TAKE OVER PROTOCOL.      */
  1267.   /*----------------------------------------------------------*/
  1268.   
  1269.   failedNodePtr.i = failedNodeId;
  1270.   ptrCheckGuard(failedNodePtr, MAX_NDB_NODES, nodeRecord);
  1271.   switch (cgcpMasterTakeOverState) {
  1272.   case ALL_READY:
  1273.     jam();
  1274.     startGcp(signal);
  1275.     break;
  1276.   case PREPARE_STARTED_NOT_COMMITTED:
  1277.     {
  1278.       NodeRecordPtr nodePtr;
  1279.       jam();
  1280.       c_GCP_PREPARE_Counter.clearWaitingFor();
  1281.       nodePtr.i = cfirstAliveNode;
  1282.       do {
  1283. jam();
  1284. ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
  1285. if (nodePtr.p->gcpstate == NodeRecord::READY) {
  1286.   jam();
  1287.   c_GCP_PREPARE_Counter.setWaitingFor(nodePtr.i);
  1288.   sendGCP_PREPARE(signal, nodePtr.i);
  1289. }//if
  1290. nodePtr.i = nodePtr.p->nextNode;
  1291.       } while(nodePtr.i != RNIL);
  1292.       if (c_GCP_PREPARE_Counter.done()) {
  1293. jam();
  1294. gcpcommitreqLab(signal);
  1295.       }//if
  1296.       break;
  1297.     }
  1298.   case ALL_PREPARED:
  1299.     jam();
  1300.     gcpcommitreqLab(signal);
  1301.     break;
  1302.   case COMMIT_STARTED_NOT_COMPLETED:
  1303.     {
  1304.       NodeRecordPtr nodePtr;
  1305.       jam();
  1306.       c_GCP_COMMIT_Counter.clearWaitingFor();
  1307.       nodePtr.i = cfirstAliveNode;
  1308.       do {
  1309. jam();
  1310. ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
  1311. if (nodePtr.p->gcpstate == NodeRecord::PREPARE_RECEIVED) {
  1312.   jam();
  1313.   sendGCP_COMMIT(signal, nodePtr.i);
  1314.   c_GCP_COMMIT_Counter.setWaitingFor(nodePtr.i);
  1315. } else {
  1316.   ndbrequire((nodePtr.p->gcpstate == NodeRecord::NODE_FINISHED) ||
  1317.      (nodePtr.p->gcpstate == NodeRecord::COMMIT_SENT));
  1318. }//if
  1319. nodePtr.i = nodePtr.p->nextNode;
  1320.       } while(nodePtr.i != RNIL);
  1321.       if (c_GCP_COMMIT_Counter.done()){
  1322. jam();
  1323. gcpsavereqLab(signal);
  1324.       }//if
  1325.       break;
  1326.     }
  1327.   case COMMIT_COMPLETED:
  1328.     jam();
  1329.     gcpsavereqLab(signal);
  1330.     break;
  1331.   case SAVE_STARTED_NOT_COMPLETED:
  1332.     {
  1333.       NodeRecordPtr nodePtr;
  1334.       jam();
  1335.       SYSFILE->newestRestorableGCI = coldgcp;
  1336.       nodePtr.i = cfirstAliveNode;
  1337.       do {
  1338. jam();
  1339. ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
  1340. SYSFILE->lastCompletedGCI[nodePtr.i] = coldgcp;
  1341. nodePtr.i = nodePtr.p->nextNode;
  1342.       } while (nodePtr.i != RNIL);
  1343.       /**-------------------------------------------------------------------
  1344.        * THE FAILED NODE DID ALSO PARTICIPATE IN THIS GLOBAL CHECKPOINT 
  1345.        * WHICH IS RECORDED.
  1346.        *-------------------------------------------------------------------*/
  1347.       SYSFILE->lastCompletedGCI[failedNodeId] = coldgcp;
  1348.       copyGciLab(signal, CopyGCIReq::GLOBAL_CHECKPOINT);
  1349.       break;
  1350.     }
  1351.   default:
  1352.     ndbrequire(false);
  1353.     break;
  1354.   }//switch
  1355.   signal->theData[0] = EventReport::GCP_TakeoverCompleted;
  1356.   sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB);
  1357.   /*--------------------------------------------------*/
  1358.   /*       WE SEPARATE HANDLING OF GLOBAL CHECKPOINTS */
  1359.   /*       AND LOCAL CHECKPOINTS HERE. LCP'S HAVE TO  */
  1360.   /*       REMOVE ALL FAILED FRAGMENTS BEFORE WE CAN  */
  1361.   /*       HANDLE THE LCP PROTOCOL.                   */
  1362.   /*--------------------------------------------------*/
  1363.   checkLocalNodefailComplete(signal, failedNodeId, NF_GCP_TAKE_OVER);
  1364.   
  1365.   return;
  1366. }//Dbdih::masterGcpConfFromFailedLab()
  1367. void
  1368. Dbdih::invalidateNodeLCP(Signal* signal, Uint32 nodeId, Uint32 tableId)
  1369. {
  1370.   jamEntry();
  1371.   TabRecordPtr tabPtr;
  1372.   tabPtr.i = tableId;  
  1373.   const Uint32 RT_BREAK = 64;
  1374.   if (ERROR_INSERTED(7125)) {
  1375.     return;
  1376.   }//if
  1377.   for (Uint32 i = 0; i<RT_BREAK; i++) {
  1378.     jam();
  1379.     if (tabPtr.i >= ctabFileSize){
  1380.       jam();
  1381.       /**
  1382.        * Ready with entire loop
  1383.        * Return to master
  1384.        */
  1385.       setAllowNodeStart(nodeId, true);
  1386.       if (getNodeStatus(nodeId) == NodeRecord::STARTING) {
  1387.         jam();
  1388.         StartInfoConf * conf = (StartInfoConf*)&signal->theData[0];
  1389.         conf->sendingNodeId = cownNodeId;
  1390.         conf->startingNodeId = nodeId;
  1391.         sendSignal(cmasterdihref, GSN_START_INFOCONF, signal,
  1392.                    StartInfoConf::SignalLength, JBB);
  1393.       }//if
  1394.       return;
  1395.     }//if
  1396.     ptrAss(tabPtr, tabRecord);
  1397.     if (tabPtr.p->tabStatus == TabRecord::TS_ACTIVE) {
  1398.       jam();
  1399.       invalidateNodeLCP(signal, nodeId, tabPtr);
  1400.       return;
  1401.     }//if
  1402.     tabPtr.i++;
  1403.   }//for
  1404.   signal->theData[0] = DihContinueB::ZINVALIDATE_NODE_LCP;
  1405.   signal->theData[1] = nodeId;
  1406.   signal->theData[2] = tabPtr.i;
  1407.   sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
  1408. }//Dbdih::invalidateNodeLCP()
  1409. void
  1410. Dbdih::invalidateNodeLCP(Signal* signal, Uint32 nodeId, TabRecordPtr tabPtr)
  1411. {  
  1412.   /**
  1413.    * Check so that no one else is using the tab descriptior
  1414.    */
  1415.   if (tabPtr.p->tabCopyStatus != TabRecord::CS_IDLE) {
  1416.     jam();    
  1417.     signal->theData[0] = DihContinueB::ZINVALIDATE_NODE_LCP;
  1418.     signal->theData[1] = nodeId;
  1419.     signal->theData[2] = tabPtr.i;
  1420.     sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 20, 3);
  1421.     return;
  1422.   }//if  
  1423.   /**
  1424.    * For each fragment
  1425.    */
  1426.   bool modified = false;
  1427.   FragmentstorePtr fragPtr;
  1428.   for(Uint32 fragNo = 0; fragNo < tabPtr.p->totalfragments; fragNo++){
  1429.     jam();
  1430.     getFragstore(tabPtr.p, fragNo, fragPtr);    
  1431.     /**
  1432.      * For each of replica record
  1433.      */
  1434.     ReplicaRecordPtr replicaPtr;
  1435.     for(replicaPtr.i = fragPtr.p->oldStoredReplicas; replicaPtr.i != RNIL;
  1436.         replicaPtr.i = replicaPtr.p->nextReplica) {
  1437.       jam();
  1438.       ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
  1439.       if(replicaPtr.p->procNode == nodeId){
  1440.         jam();
  1441.         /**
  1442.          * Found one with correct node id
  1443.          */
  1444.         /**
  1445.          * Invalidate all LCP's
  1446.          */
  1447.         modified = true;
  1448.         for(int i = 0; i < MAX_LCP_STORED; i++) {
  1449.           replicaPtr.p->lcpStatus[i] = ZINVALID;       
  1450.         }//if
  1451.         /**
  1452.          * And reset nextLcp
  1453.          */
  1454.         replicaPtr.p->nextLcp = 0;
  1455.         replicaPtr.p->noCrashedReplicas = 0;
  1456.       }//if
  1457.     }//for
  1458.   }//for
  1459.   if (modified) {
  1460.     jam();
  1461.     /**
  1462.      * Save table description to disk
  1463.      */
  1464.     tabPtr.p->tabCopyStatus  = TabRecord::CS_INVALIDATE_NODE_LCP;
  1465.     tabPtr.p->tabUpdateState = TabRecord::US_INVALIDATE_NODE_LCP;
  1466.     tabPtr.p->tabRemoveNode  = nodeId;
  1467.     signal->theData[0] = DihContinueB::ZPACK_TABLE_INTO_PAGES;
  1468.     signal->theData[1] = tabPtr.i;
  1469.     sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
  1470.     return;
  1471.   } 
  1472.   
  1473.   jam();
  1474.   /**
  1475.    * Move to next table
  1476.    */
  1477.   tabPtr.i++;
  1478.   signal->theData[0] = DihContinueB::ZINVALIDATE_NODE_LCP;
  1479.   signal->theData[1] = nodeId;
  1480.   signal->theData[2] = tabPtr.i;
  1481.   sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
  1482.   return;
  1483. }//Dbdih::invalidateNodeLCP()
  1484. /*------------------------------------------------*/
  1485. /*       INPUT:  TABPTR                           */
  1486. /*               TNODEID                          */
  1487. /*------------------------------------------------*/
  1488. void Dbdih::removeNodeFromTables(Signal* signal, 
  1489.  Uint32 nodeId, Uint32 tableId) 
  1490. {
  1491.   jamEntry();
  1492.   TabRecordPtr tabPtr;
  1493.   tabPtr.i = tableId;  
  1494.   const Uint32 RT_BREAK = 64;
  1495.   for (Uint32 i = 0; i<RT_BREAK; i++) {
  1496.     jam();
  1497.     if (tabPtr.i >= ctabFileSize){
  1498.       jam();
  1499.       removeNodeFromTablesComplete(signal, nodeId);
  1500.       return;
  1501.     }//if
  1502.     ptrAss(tabPtr, tabRecord);
  1503.     if (tabPtr.p->tabStatus == TabRecord::TS_ACTIVE) {
  1504.       jam();
  1505.       removeNodeFromTable(signal, nodeId, tabPtr);
  1506.       return;
  1507.     }//if
  1508.     tabPtr.i++;
  1509.   }//for
  1510.   signal->theData[0] = DihContinueB::ZREMOVE_NODE_FROM_TABLE;
  1511.   signal->theData[1] = nodeId;
  1512.   signal->theData[2] = tabPtr.i;
  1513.   sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
  1514. }
  1515. void Dbdih::removeNodeFromTable(Signal* signal, 
  1516. Uint32 nodeId, TabRecordPtr tabPtr){ 
  1517.   
  1518.   /**
  1519.    * Check so that no one else is using the tab descriptior
  1520.    */
  1521.   if (tabPtr.p->tabCopyStatus != TabRecord::CS_IDLE) {
  1522.     jam();    
  1523.     signal->theData[0] = DihContinueB::ZREMOVE_NODE_FROM_TABLE;
  1524.     signal->theData[1] = nodeId;
  1525.     signal->theData[2] = tabPtr.i;
  1526.     sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 20, 3);
  1527.     return;
  1528.   }//if  
  1529.   /**
  1530.    * For each fragment
  1531.    */
  1532.   Uint32 noOfRemovedReplicas = 0;     // No of replicas removed
  1533.   Uint32 noOfRemovedLcpReplicas = 0;  // No of replicas in LCP removed 
  1534.   Uint32 noOfRemainingLcpReplicas = 0;// No of replicas in LCP remaining
  1535.   //const Uint32 lcpId = SYSFILE->latestLCP_ID;
  1536.   const bool lcpOngoingFlag = (tabPtr.p->tabLcpStatus== TabRecord::TLS_ACTIVE);
  1537.   
  1538.   FragmentstorePtr fragPtr;
  1539.   for(Uint32 fragNo = 0; fragNo < tabPtr.p->totalfragments; fragNo++){
  1540.     jam();
  1541.     getFragstore(tabPtr.p, fragNo, fragPtr);    
  1542.     
  1543.     /**
  1544.      * For each of replica record
  1545.      */
  1546.     Uint32 replicaNo = 0;
  1547.     ReplicaRecordPtr replicaPtr;
  1548.     for(replicaPtr.i = fragPtr.p->storedReplicas; replicaPtr.i != RNIL;
  1549.         replicaPtr.i = replicaPtr.p->nextReplica, replicaNo++) {
  1550.       jam();
  1551.       ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
  1552.       if(replicaPtr.p->procNode == nodeId){
  1553.         jam();
  1554. noOfRemovedReplicas++;
  1555. removeNodeFromStored(nodeId, fragPtr, replicaPtr);
  1556. if(replicaPtr.p->lcpOngoingFlag){
  1557.   jam();
  1558.   /**
  1559.    * This replica is currently LCP:ed
  1560.    */
  1561.   ndbrequire(fragPtr.p->noLcpReplicas > 0);
  1562.   fragPtr.p->noLcpReplicas --;
  1563.   
  1564.   noOfRemovedLcpReplicas ++;
  1565.   replicaPtr.p->lcpOngoingFlag = false;
  1566. }
  1567.       }
  1568.     }
  1569.     noOfRemainingLcpReplicas += fragPtr.p->noLcpReplicas;
  1570.   }
  1571.   
  1572.   if(noOfRemovedReplicas == 0){
  1573.     jam();
  1574.     /**
  1575.      * The table had no replica on the failed node
  1576.      *   continue with next table
  1577.      */
  1578.     tabPtr.i++;
  1579.     signal->theData[0] = DihContinueB::ZREMOVE_NODE_FROM_TABLE;
  1580.     signal->theData[1] = nodeId;
  1581.     signal->theData[2] = tabPtr.i;
  1582.     sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
  1583.     return;
  1584.   }
  1585.   
  1586.   /**
  1587.    * We did remove at least one replica
  1588.    */
  1589.   bool ok = false;
  1590.   switch(tabPtr.p->tabLcpStatus){
  1591.   case TabRecord::TLS_COMPLETED:
  1592.     ok = true;
  1593.     jam();
  1594.     /**
  1595.      * WE WILL WRITE THE TABLE DESCRIPTION TO DISK AT THIS TIME 
  1596.      * INDEPENDENT OF WHAT THE LOCAL CHECKPOINT NEEDED. 
  1597.      * THIS IS TO ENSURE THAT THE FAILED NODES ARE ALSO UPDATED ON DISK 
  1598.      * IN THE DIH DATA STRUCTURES BEFORE WE COMPLETE HANDLING OF THE 
  1599.      * NODE FAILURE.
  1600.      */
  1601.     ndbrequire(noOfRemovedLcpReplicas == 0);
  1602.     
  1603.     tabPtr.p->tabCopyStatus = TabRecord::CS_REMOVE_NODE;
  1604.     tabPtr.p->tabUpdateState = TabRecord::US_REMOVE_NODE;
  1605.     tabPtr.p->tabRemoveNode = nodeId;
  1606.     signal->theData[0] = DihContinueB::ZPACK_TABLE_INTO_PAGES;
  1607.     signal->theData[1] = tabPtr.i;
  1608.     sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
  1609.     return;
  1610.     break;
  1611.   case TabRecord::TLS_ACTIVE:
  1612.     ok = true;
  1613.     jam();
  1614.     /**
  1615.      * The table is participating in an LCP currently
  1616.      */
  1617.     // Fall through
  1618.     break;
  1619.   case TabRecord::TLS_WRITING_TO_FILE:
  1620.     ok = true;
  1621.     jam();
  1622.     /**
  1623.      * This should never happen since we in the beginning of this function
  1624.      * checks the tabCopyStatus
  1625.      */
  1626.     ndbrequire(lcpOngoingFlag);
  1627.     ndbrequire(false);
  1628.     break;
  1629.   }    
  1630.   ndbrequire(ok);
  1631.   /**
  1632.    * The table is participating in an LCP currently
  1633.    *   and we removed some replicas that should have been checkpointed
  1634.    */
  1635.   ndbrequire(c_lcpState.lcpStatus != LCP_STATUS_IDLE);
  1636.   ndbrequire(tabPtr.p->tabLcpStatus == TabRecord::TLS_ACTIVE);
  1637.   
  1638.   /**
  1639.    * Save the table
  1640.    */
  1641.   tabPtr.p->tabCopyStatus = TabRecord::CS_REMOVE_NODE;
  1642.   tabPtr.p->tabUpdateState = TabRecord::US_REMOVE_NODE;
  1643.   tabPtr.p->tabRemoveNode = nodeId;
  1644.   signal->theData[0] = DihContinueB::ZPACK_TABLE_INTO_PAGES;
  1645.   signal->theData[1] = tabPtr.i;
  1646.   sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
  1647.   
  1648.   if(noOfRemainingLcpReplicas == 0){
  1649.     jam();
  1650.     /**
  1651.      * The removal on the failed node made the LCP complete
  1652.      */
  1653.     tabPtr.p->tabLcpStatus = TabRecord::TLS_WRITING_TO_FILE;
  1654.     checkLcpAllTablesDoneInLqh();
  1655.   }
  1656. }
  1657.   
  1658. void
  1659. Dbdih::removeNodeFromTablesComplete(Signal* signal, Uint32 nodeId){
  1660.   jam();
  1661.   /**
  1662.    * Check if we "accidently" completed a LCP
  1663.    */
  1664.   checkLcpCompletedLab(signal);
  1665.   
  1666.   /**
  1667.    * Check if we (DIH) are finished with node fail handling
  1668.    */
  1669.   checkLocalNodefailComplete(signal, nodeId, NF_REMOVE_NODE_FROM_TABLE);
  1670. }
  1671. void
  1672. Dbdih::checkLocalNodefailComplete(Signal* signal, Uint32 failedNodeId,
  1673.   NodefailHandlingStep step){
  1674.   jam();
  1675.   NodeRecordPtr nodePtr;
  1676.   nodePtr.i = failedNodeId;
  1677.   ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
  1678.   
  1679.   ndbrequire(nodePtr.p->m_nodefailSteps.get(step));
  1680.   nodePtr.p->m_nodefailSteps.clear(step);
  1681.   if(nodePtr.p->m_nodefailSteps.count() > 0){
  1682.     jam();
  1683.     return;
  1684.   }
  1685.   NFCompleteRep * const nf = (NFCompleteRep *)&signal->theData[0];
  1686.   nf->blockNo = DBDIH;
  1687.   nf->nodeId = cownNodeId;
  1688.   nf->failedNodeId = failedNodeId;
  1689.   nf->from = __LINE__;
  1690.   sendSignal(reference(), GSN_NF_COMPLETEREP, signal, 
  1691.              NFCompleteRep::SignalLength, JBB);
  1692. }
  1693. void
  1694. Dbdih::setLocalNodefailHandling(Signal* signal, Uint32 failedNodeId,
  1695. NodefailHandlingStep step){
  1696.   jam();
  1697.   
  1698.   NodeRecordPtr nodePtr;
  1699.   nodePtr.i = failedNodeId;
  1700.   ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
  1701.   
  1702.   ndbrequire(!nodePtr.p->m_nodefailSteps.get(step));
  1703.   nodePtr.p->m_nodefailSteps.set(step);
  1704. }
  1705. void Dbdih::startLcpTakeOverLab(Signal* signal, Uint32 failedNodeId)
  1706. {
  1707.   /*--------------------------------------------------------------------*/
  1708.   // Start LCP master take over process. Consists of the following steps.
  1709.   // 1) Ensure that all LQH's have reported all fragments they have been
  1710.   // told to checkpoint. Can be a fairly long step time-wise.
  1711.   // 2) Query all nodes about their LCP status.
  1712.   // During the query process we do not want our own state to change.
  1713.   // This can change due to delayed reception of LCP_REPORT, completed
  1714.   // save of table on disk or reception of DIH_LCPCOMPLETE from other
  1715.   // node.
  1716.   /*--------------------------------------------------------------------*/
  1717. }//Dbdih::startLcpTakeOver()
  1718. void Dbdih::execEMPTY_LCP_CONF(Signal* signal)
  1719. {
  1720.   jamEntry();
  1721.  
  1722.   ndbrequire(c_lcpMasterTakeOverState.state == LMTOS_WAIT_EMPTY_LCP);
  1723.   
  1724.   const EmptyLcpConf * const conf = (EmptyLcpConf *)&signal->theData[0];
  1725.   Uint32 nodeId = conf->senderNodeId;
  1726.   if(!conf->idle){
  1727.     jam();
  1728.     if (conf->tableId < c_lcpMasterTakeOverState.minTableId) {
  1729.       jam();
  1730.       c_lcpMasterTakeOverState.minTableId = conf->tableId;
  1731.       c_lcpMasterTakeOverState.minFragId = conf->fragmentId;
  1732.     } else if (conf->tableId == c_lcpMasterTakeOverState.minTableId &&
  1733.        conf->fragmentId < c_lcpMasterTakeOverState.minFragId) {
  1734.       jam();
  1735.       c_lcpMasterTakeOverState.minFragId = conf->fragmentId;
  1736.     }//if
  1737.     if(isMaster()){
  1738.       jam();
  1739.       c_lcpState.m_LAST_LCP_FRAG_ORD.setWaitingFor(nodeId);    
  1740.     }
  1741.   }
  1742.   
  1743.   receiveLoopMacro(EMPTY_LCP_REQ, nodeId);
  1744.   /*--------------------------------------------------------------------*/
  1745.   // Received all EMPTY_LCPCONF. We can continue with next phase of the
  1746.   // take over LCP master process.
  1747.   /*--------------------------------------------------------------------*/
  1748.   c_lcpMasterTakeOverState.set(LMTOS_WAIT_LCP_FRAG_REP, __LINE__);
  1749.   checkEmptyLcpComplete(signal);
  1750.   return;
  1751. }//Dbdih::execEMPTY_LCPCONF()
  1752. void
  1753. Dbdih::checkEmptyLcpComplete(Signal *signal){
  1754.   
  1755.   ndbrequire(c_lcpMasterTakeOverState.state == LMTOS_WAIT_LCP_FRAG_REP);
  1756.   
  1757.   if(c_lcpState.noOfLcpFragRepOutstanding > 0){
  1758.     jam();
  1759.     return;
  1760.   }
  1761.   
  1762.   if(isMaster()){
  1763.     jam();
  1764.     signal->theData[0] = EventReport::LCP_TakeoverStarted;
  1765.     sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB);
  1766.     
  1767.     signal->theData[0] = 7012;
  1768.     execDUMP_STATE_ORD(signal);
  1769.     
  1770.     c_lcpMasterTakeOverState.set(LMTOS_INITIAL, __LINE__);
  1771.     MasterLCPReq * const req = (MasterLCPReq *)&signal->theData[0];
  1772.     req->masterRef = reference();
  1773.     req->failedNodeId = c_lcpMasterTakeOverState.failedNodeId;
  1774.     sendLoopMacro(MASTER_LCPREQ, sendMASTER_LCPREQ);
  1775.   } else {
  1776.     sendMASTER_LCPCONF(signal);
  1777.   }
  1778. }
  1779. /*--------------------------------------------------*/
  1780. /*       THE MASTER HAS FAILED AND THE NEW MASTER IS*/
  1781. /*       QUERYING THIS NODE ABOUT THE STATE OF THE  */
  1782. /*       LOCAL CHECKPOINT PROTOCOL.                 */
  1783. /*--------------------------------------------------*/
  1784. void Dbdih::execMASTER_LCPREQ(Signal* signal) 
  1785. {
  1786.   const MasterLCPReq * const req = (MasterLCPReq *)&signal->theData[0];
  1787.   jamEntry();
  1788.   const BlockReference newMasterBlockref = req->masterRef;
  1789.   Uint32 failedNodeId = req->failedNodeId;
  1790.   /**
  1791.    * There can be no take over with the same master
  1792.    */
  1793.   ndbrequire(c_lcpState.m_masterLcpDihRef != newMasterBlockref);
  1794.   c_lcpState.m_masterLcpDihRef = newMasterBlockref;
  1795.   c_lcpState.m_MASTER_LCPREQ_Received = true;
  1796.   c_lcpState.m_MASTER_LCPREQ_FailedNodeId = failedNodeId;
  1797.   
  1798.   if(newMasterBlockref != cmasterdihref){
  1799.     jam();
  1800.     ndbrequire(0);
  1801.   }
  1802.   
  1803.   sendMASTER_LCPCONF(signal);
  1804. }//Dbdih::execMASTER_LCPREQ()
  1805. void
  1806. Dbdih::sendMASTER_LCPCONF(Signal * signal){
  1807.   if(!c_EMPTY_LCP_REQ_Counter.done()){
  1808.     /**
  1809.      * Have not received all EMPTY_LCP_REP 
  1810.      * dare not answer MASTER_LCP_CONF yet
  1811.      */
  1812.     jam();
  1813.     return;
  1814.   }
  1815.   if(!c_lcpState.m_MASTER_LCPREQ_Received){
  1816.     jam();
  1817.     /**
  1818.      * Has not received MASTER_LCPREQ yet
  1819.      */
  1820.     return;
  1821.   }
  1822.   
  1823.   if(c_lcpState.lcpStatus == LCP_INIT_TABLES){
  1824.     jam();
  1825.     /**
  1826.      * Still aborting old initLcpLab
  1827.      */
  1828.     return;
  1829.   }
  1830.   if(c_lcpState.lcpStatus == LCP_COPY_GCI){
  1831.     jam();
  1832.     /**
  1833.      * Restart it
  1834.      */
  1835.     //Uint32 lcpId = SYSFILE->latestLCP_ID;
  1836.     SYSFILE->latestLCP_ID--;
  1837.     c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
  1838. #if 0
  1839.     if(c_copyGCISlave.m_copyReason == CopyGCIReq::LOCAL_CHECKPOINT){
  1840.       ndbout_c("Dbdih: Also resetting c_copyGCISlave");
  1841.       c_copyGCISlave.m_copyReason = CopyGCIReq::IDLE;
  1842.       c_copyGCISlave.m_expectedNextWord = 0;
  1843.     }
  1844. #endif
  1845.   }
  1846.   bool ok = false;
  1847.   MasterLCPConf::State lcpState;
  1848.   switch (c_lcpState.lcpStatus) {
  1849.   case LCP_STATUS_IDLE:
  1850.     ok = true;
  1851.     jam();
  1852.     /*------------------------------------------------*/
  1853.     /*       LOCAL CHECKPOINT IS CURRENTLY NOT ACTIVE */
  1854.     /*       SINCE NO COPY OF RESTART INFORMATION HAVE*/
  1855.     /*       BEEN RECEIVED YET. ALSO THE PREVIOUS     */
  1856.     /*       CHECKPOINT HAVE BEEN FULLY COMPLETED.    */
  1857.     /*------------------------------------------------*/
  1858.     lcpState = MasterLCPConf::LCP_STATUS_IDLE;
  1859.     break;
  1860.   case LCP_STATUS_ACTIVE:
  1861.     ok = true;
  1862.     jam();
  1863.     /*--------------------------------------------------*/
  1864.     /*       COPY OF RESTART INFORMATION HAS BEEN       */
  1865.     /*       PERFORMED AND ALSO RESPONSE HAVE BEEN SENT.*/
  1866.     /*--------------------------------------------------*/
  1867.     lcpState = MasterLCPConf::LCP_STATUS_ACTIVE;
  1868.     break;
  1869.   case LCP_TAB_COMPLETED:
  1870.     ok = true;
  1871.     jam();
  1872.     /*--------------------------------------------------------*/
  1873.     /*       ALL LCP_REPORT'S HAVE BEEN COMPLETED FOR         */
  1874.     /*       ALL TABLES.     SAVE OF AT LEAST ONE TABLE IS    */
  1875.     /*       ONGOING YET.                                     */
  1876.     /*--------------------------------------------------------*/
  1877.     lcpState = MasterLCPConf::LCP_TAB_COMPLETED;
  1878.     break;
  1879.   case LCP_TAB_SAVED:
  1880.     ok = true;
  1881.     jam();
  1882.     /*--------------------------------------------------------*/
  1883.     /*       ALL LCP_REPORT'S HAVE BEEN COMPLETED FOR         */
  1884.     /*       ALL TABLES.     ALL TABLES HAVE ALSO BEEN SAVED  */
  1885.     /*       ALL OTHER NODES ARE NOT YET FINISHED WITH        */
  1886.     /*       THE LOCAL CHECKPOINT.                            */
  1887.     /*--------------------------------------------------------*/
  1888.     lcpState = MasterLCPConf::LCP_TAB_SAVED;
  1889.     break;
  1890.   case LCP_TCGET:
  1891.   case LCP_CALCULATE_KEEP_GCI:
  1892.   case LCP_TC_CLOPSIZE:
  1893.   case LCP_START_LCP_ROUND:
  1894.     /**
  1895.      * These should only exists on the master
  1896.      *   but since this is master take over
  1897.      *   it not allowed
  1898.      */
  1899.     ndbrequire(false);
  1900.     lcpState= MasterLCPConf::LCP_STATUS_IDLE; // remove warning
  1901.     break;
  1902.   case LCP_COPY_GCI:
  1903.   case LCP_INIT_TABLES:
  1904.     ok = true;
  1905.     /**
  1906.      * These two states are handled by if statements above
  1907.      */
  1908.     ndbrequire(false);
  1909.     lcpState= MasterLCPConf::LCP_STATUS_IDLE; // remove warning
  1910.     break;
  1911.   }//switch
  1912.   ndbrequire(ok);
  1913.   Uint32 failedNodeId = c_lcpState.m_MASTER_LCPREQ_FailedNodeId;
  1914.   MasterLCPConf * const conf = (MasterLCPConf *)&signal->theData[0];
  1915.   conf->senderNodeId = cownNodeId;
  1916.   conf->lcpState = lcpState;
  1917.   conf->failedNodeId = failedNodeId;
  1918.   sendSignal(c_lcpState.m_masterLcpDihRef, GSN_MASTER_LCPCONF,
  1919.              signal, MasterLCPConf::SignalLength, JBB);
  1920.   // Answer to MASTER_LCPREQ sent, reset flag so 
  1921.   // that it's not sent again before another request comes in
  1922.   c_lcpState.m_MASTER_LCPREQ_Received = false;
  1923.   if(c_lcpState.lcpStatus == LCP_TAB_SAVED){
  1924. #ifdef VM_TRACE
  1925.     ndbout_c("Sending extra GSN_LCP_COMPLETE_REP to new master");    
  1926. #endif
  1927.     sendLCP_COMPLETE_REP(signal);
  1928.   }
  1929.   if(!isMaster()){
  1930.     c_lcpMasterTakeOverState.set(LMTOS_IDLE, __LINE__);
  1931.     checkLocalNodefailComplete(signal, failedNodeId, NF_LCP_TAKE_OVER);
  1932.   }
  1933.   
  1934.   return;
  1935. }
  1936. NdbOut&
  1937. operator<<(NdbOut& out, const Dbdih::LcpMasterTakeOverState state){
  1938.   switch(state){
  1939.   case Dbdih::LMTOS_IDLE:
  1940.     out << "LMTOS_IDLE";
  1941.     break;
  1942.   case Dbdih::LMTOS_WAIT_EMPTY_LCP:
  1943.     out << "LMTOS_WAIT_EMPTY_LCP";
  1944.     break;
  1945.   case Dbdih::LMTOS_WAIT_LCP_FRAG_REP:
  1946.     out << "LMTOS_WAIT_EMPTY_LCP";
  1947.     break;
  1948.   case Dbdih::LMTOS_INITIAL:
  1949.     out << "LMTOS_INITIAL";
  1950.     break;
  1951.   case Dbdih::LMTOS_ALL_IDLE:
  1952.     out << "LMTOS_ALL_IDLE";
  1953.     break;
  1954.   case Dbdih::LMTOS_ALL_ACTIVE:
  1955.     out << "LMTOS_ALL_ACTIVE";
  1956.     break;
  1957.   case Dbdih::LMTOS_LCP_CONCLUDING:
  1958.     out << "LMTOS_LCP_CONCLUDING";
  1959.     break;
  1960.   case Dbdih::LMTOS_COPY_ONGOING:
  1961.     out << "LMTOS_COPY_ONGOING";
  1962.     break;
  1963.   }
  1964.   return out;
  1965. }
  1966. struct MASTERLCP_StateTransitions {
  1967.   Dbdih::LcpMasterTakeOverState CurrentState;
  1968.   MasterLCPConf::State ParticipantState;
  1969.   Dbdih::LcpMasterTakeOverState NewState;
  1970. };
  1971. static const
  1972. MASTERLCP_StateTransitions g_masterLCPTakeoverStateTransitions[] = {
  1973.   /**
  1974.    * Current = LMTOS_INITIAL
  1975.    */
  1976.   { Dbdih::LMTOS_INITIAL, 
  1977.     MasterLCPConf::LCP_STATUS_IDLE, 
  1978.     Dbdih::LMTOS_ALL_IDLE },
  1979.   
  1980.   { Dbdih::LMTOS_INITIAL, 
  1981.     MasterLCPConf::LCP_STATUS_ACTIVE,
  1982.     Dbdih::LMTOS_ALL_ACTIVE },
  1983.   { Dbdih::LMTOS_INITIAL, 
  1984.     MasterLCPConf::LCP_TAB_COMPLETED,
  1985.     Dbdih::LMTOS_LCP_CONCLUDING },
  1986.   { Dbdih::LMTOS_INITIAL, 
  1987.     MasterLCPConf::LCP_TAB_SAVED,
  1988.     Dbdih::LMTOS_LCP_CONCLUDING },
  1989.   /**
  1990.    * Current = LMTOS_ALL_IDLE
  1991.    */
  1992.   { Dbdih::LMTOS_ALL_IDLE,
  1993.     MasterLCPConf::LCP_STATUS_IDLE,
  1994.     Dbdih::LMTOS_ALL_IDLE },
  1995.   { Dbdih::LMTOS_ALL_IDLE,
  1996.     MasterLCPConf::LCP_STATUS_ACTIVE,
  1997.     Dbdih::LMTOS_COPY_ONGOING },
  1998.   { Dbdih::LMTOS_ALL_IDLE,
  1999.     MasterLCPConf::LCP_TAB_COMPLETED,
  2000.     Dbdih::LMTOS_LCP_CONCLUDING },
  2001.   { Dbdih::LMTOS_ALL_IDLE,
  2002.     MasterLCPConf::LCP_TAB_SAVED,
  2003.     Dbdih::LMTOS_LCP_CONCLUDING },
  2004.   /**
  2005.    * Current = LMTOS_COPY_ONGOING
  2006.    */
  2007.   { Dbdih::LMTOS_COPY_ONGOING,
  2008.     MasterLCPConf::LCP_STATUS_IDLE,
  2009.     Dbdih::LMTOS_COPY_ONGOING },
  2010.   { Dbdih::LMTOS_COPY_ONGOING,
  2011.     MasterLCPConf::LCP_STATUS_ACTIVE,
  2012.     Dbdih::LMTOS_COPY_ONGOING },
  2013.   
  2014.   /**
  2015.    * Current = LMTOS_ALL_ACTIVE
  2016.    */
  2017.   { Dbdih::LMTOS_ALL_ACTIVE,
  2018.     MasterLCPConf::LCP_STATUS_IDLE,
  2019.     Dbdih::LMTOS_COPY_ONGOING },
  2020.   { Dbdih::LMTOS_ALL_ACTIVE,
  2021.     MasterLCPConf::LCP_STATUS_ACTIVE,
  2022.     Dbdih::LMTOS_ALL_ACTIVE },
  2023.   { Dbdih::LMTOS_ALL_ACTIVE,
  2024.     MasterLCPConf::LCP_TAB_COMPLETED,
  2025.     Dbdih::LMTOS_LCP_CONCLUDING },    
  2026.   
  2027.   { Dbdih::LMTOS_ALL_ACTIVE,
  2028.     MasterLCPConf::LCP_TAB_SAVED,
  2029.     Dbdih::LMTOS_LCP_CONCLUDING },    
  2030.   /**
  2031.    * Current = LMTOS_LCP_CONCLUDING
  2032.    */
  2033.   { Dbdih::LMTOS_LCP_CONCLUDING,
  2034.     MasterLCPConf::LCP_STATUS_IDLE, 
  2035.     Dbdih::LMTOS_LCP_CONCLUDING },
  2036.   
  2037.   { Dbdih::LMTOS_LCP_CONCLUDING, 
  2038.     MasterLCPConf::LCP_STATUS_ACTIVE,
  2039.     Dbdih::LMTOS_LCP_CONCLUDING },
  2040.   { Dbdih::LMTOS_LCP_CONCLUDING, 
  2041.     MasterLCPConf::LCP_TAB_COMPLETED,
  2042.     Dbdih::LMTOS_LCP_CONCLUDING },
  2043.   { Dbdih::LMTOS_LCP_CONCLUDING, 
  2044.     MasterLCPConf::LCP_TAB_SAVED,
  2045.     Dbdih::LMTOS_LCP_CONCLUDING }
  2046. };
  2047. const Uint32 g_masterLCPTakeoverStateTransitionsRows = 
  2048. sizeof(g_masterLCPTakeoverStateTransitions) / sizeof(struct MASTERLCP_StateTransitions);
  2049. void Dbdih::execMASTER_LCPCONF(Signal* signal) 
  2050. {
  2051.   const MasterLCPConf * const conf = (MasterLCPConf *)&signal->theData[0];
  2052.   jamEntry();
  2053.   Uint32 senderNodeId = conf->senderNodeId;
  2054.   MasterLCPConf::State lcpState = (MasterLCPConf::State)conf->lcpState;
  2055.   const Uint32 failedNodeId = conf->failedNodeId;
  2056.   NodeRecordPtr nodePtr;
  2057.   nodePtr.i = senderNodeId;
  2058.   ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
  2059.   nodePtr.p->lcpStateAtTakeOver = lcpState;
  2060. #ifdef VM_TRACE
  2061.   ndbout_c("MASTER_LCPCONF");
  2062.   printMASTER_LCP_CONF(stdout, &signal->theData[0], 0, 0);
  2063. #endif  
  2064.   bool found = false;
  2065.   for(Uint32 i = 0; i<g_masterLCPTakeoverStateTransitionsRows; i++){
  2066.     const struct MASTERLCP_StateTransitions * valid = 
  2067.       &g_masterLCPTakeoverStateTransitions[i];
  2068.     
  2069.     if(valid->CurrentState == c_lcpMasterTakeOverState.state && 
  2070.        valid->ParticipantState == lcpState){
  2071.       jam();
  2072.       found = true;
  2073.       c_lcpMasterTakeOverState.set(valid->NewState, __LINE__);
  2074.       break;
  2075.     }
  2076.   }
  2077.   ndbrequire(found);
  2078.   bool ok = false;
  2079.   switch(lcpState){
  2080.   case MasterLCPConf::LCP_STATUS_IDLE:
  2081.     ok = true;
  2082.     break;
  2083.   case MasterLCPConf::LCP_STATUS_ACTIVE:
  2084.   case MasterLCPConf::LCP_TAB_COMPLETED:
  2085.   case MasterLCPConf::LCP_TAB_SAVED:
  2086.     ok = true;
  2087.     c_lcpState.m_LCP_COMPLETE_REP_Counter_DIH.setWaitingFor(nodePtr.i);
  2088.     break;
  2089.   }
  2090.   ndbrequire(ok);
  2091.   receiveLoopMacro(MASTER_LCPREQ, senderNodeId);
  2092.   /*-------------------------------------------------------------------------*/
  2093.   // We have now received all responses and are ready to take over the LCP
  2094.   // protocol as master.
  2095.   /*-------------------------------------------------------------------------*/
  2096.   MASTER_LCPhandling(signal, failedNodeId);
  2097. }//Dbdih::execMASTER_LCPCONF()
  2098. void Dbdih::execMASTER_LCPREF(Signal* signal) 
  2099. {
  2100.   const MasterLCPRef * const ref = (MasterLCPRef *)&signal->theData[0];
  2101.   jamEntry();
  2102.   receiveLoopMacro(MASTER_LCPREQ, ref->senderNodeId);
  2103.   /*-------------------------------------------------------------------------*/
  2104.   // We have now received all responses and are ready to take over the LCP
  2105.   // protocol as master.
  2106.   /*-------------------------------------------------------------------------*/
  2107.   MASTER_LCPhandling(signal, ref->failedNodeId);
  2108. }//Dbdih::execMASTER_LCPREF()
  2109. void Dbdih::MASTER_LCPhandling(Signal* signal, Uint32 failedNodeId) 
  2110. {
  2111.   /*-------------------------------------------------------------------------
  2112.    *
  2113.    * WE ARE NOW READY TO CONCLUDE THE TAKE OVER AS MASTER. 
  2114.    * WE HAVE ENOUGH INFO TO START UP ACTIVITIES IN THE PROPER PLACE. 
  2115.    * ALSO SET THE PROPER STATE VARIABLES.
  2116.    *------------------------------------------------------------------------*/
  2117.   c_lcpState.currentFragment.tableId = c_lcpMasterTakeOverState.minTableId;
  2118.   c_lcpState.currentFragment.fragmentId = c_lcpMasterTakeOverState.minFragId;
  2119.   c_lcpState.m_LAST_LCP_FRAG_ORD = c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH;
  2120.   NodeRecordPtr failedNodePtr;  
  2121.   failedNodePtr.i = failedNodeId;
  2122.   ptrCheckGuard(failedNodePtr, MAX_NDB_NODES, nodeRecord);
  2123.   switch (c_lcpMasterTakeOverState.state) {
  2124.   case LMTOS_ALL_IDLE:
  2125.     jam();
  2126.     /* --------------------------------------------------------------------- */
  2127.     // All nodes were idle in the LCP protocol. Start checking for start of LCP
  2128.     // protocol.
  2129.     /* --------------------------------------------------------------------- */
  2130. #ifdef VM_TRACE
  2131.     ndbout_c("MASTER_LCPhandling:: LMTOS_ALL_IDLE -> checkLcpStart");
  2132. #endif
  2133.     checkLcpStart(signal, __LINE__);
  2134.     break;
  2135.   case LMTOS_COPY_ONGOING:
  2136.     jam();
  2137.     /* --------------------------------------------------------------------- */
  2138.     // We were in the starting process of the LCP protocol. We will restart the
  2139.     // protocol by calculating the keep gci and storing the new lcp id.
  2140.     /* --------------------------------------------------------------------- */
  2141. #ifdef VM_TRACE
  2142.     ndbout_c("MASTER_LCPhandling:: LMTOS_COPY_ONGOING -> storeNewLcpId");
  2143. #endif
  2144.     if (c_lcpState.lcpStatus == LCP_STATUS_ACTIVE) {
  2145.       jam();
  2146.       /*---------------------------------------------------------------------*/
  2147.       /*  WE NEED TO DECREASE THE LATEST LCP ID SINCE WE HAVE ALREADY        */
  2148.       /*  STARTED THIS */
  2149.       /*  LOCAL CHECKPOINT.                                                  */
  2150.       /*---------------------------------------------------------------------*/
  2151.       Uint32 lcpId = SYSFILE->latestLCP_ID;
  2152. #ifdef VM_TRACE
  2153.       ndbout_c("Decreasing latestLCP_ID from %d to %d", lcpId, lcpId - 1);
  2154. #endif
  2155.       SYSFILE->latestLCP_ID--;
  2156.     }//if
  2157.     storeNewLcpIdLab(signal);
  2158.     break;
  2159.   case LMTOS_ALL_ACTIVE:
  2160.     {
  2161.       jam();
  2162.       /* ------------------------------------------------------------------- 
  2163.        * Everybody was in the active phase. We will restart sending 
  2164.        * LCP_FRAGORD to the nodes from the new master. 
  2165.        * We also need to set dihLcpStatus to ZACTIVE
  2166.        * in the master node since the master will wait for all nodes to 
  2167.        * complete before finalising the LCP process.
  2168.        * ------------------------------------------------------------------ */
  2169. #ifdef VM_TRACE
  2170.       ndbout_c("MASTER_LCPhandling:: LMTOS_ALL_ACTIVE -> "
  2171.        "startLcpRoundLoopLab(table=%u, fragment=%u)",
  2172.        c_lcpMasterTakeOverState.minTableId, 
  2173.        c_lcpMasterTakeOverState.minFragId);
  2174. #endif
  2175.     
  2176.       c_lcpState.keepGci = SYSFILE->keepGCI;
  2177.       c_lcpState.setLcpStatus(LCP_START_LCP_ROUND, __LINE__);
  2178.       startLcpRoundLoopLab(signal, 0, 0);
  2179.       break;
  2180.     }
  2181.   case LMTOS_LCP_CONCLUDING:
  2182.     {
  2183.       jam();
  2184.       /* ------------------------------------------------------------------- */
  2185.       // The LCP process is in the finalisation phase. We simply wait for it to
  2186.       // complete with signals arriving in. We need to check also if we should
  2187.       // change state due to table write completion during state 
  2188.       // collection phase.
  2189.       /* ------------------------------------------------------------------- */
  2190.       ndbrequire(c_lcpState.lcpStatus != LCP_STATUS_IDLE);
  2191.       startLcpRoundLoopLab(signal, 0, 0);
  2192.       break;
  2193.     }
  2194.   default:
  2195.     ndbrequire(false);
  2196.     break;
  2197.   }//switch
  2198.   signal->theData[0] = EventReport::LCP_TakeoverCompleted;
  2199.   signal->theData[1] = c_lcpMasterTakeOverState.state;
  2200.   sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
  2201.   
  2202.   signal->theData[0] = 7012;
  2203.   execDUMP_STATE_ORD(signal);
  2204.   signal->theData[0] = 7015;
  2205.   execDUMP_STATE_ORD(signal);
  2206.   c_lcpMasterTakeOverState.set(LMTOS_IDLE, __LINE__);
  2207.   checkLocalNodefailComplete(signal, failedNodePtr.i, NF_LCP_TAKE_OVER);
  2208. }
  2209. /* ------------------------------------------------------------------------- */
  2210. /*       A BLOCK OR A NODE HAS COMPLETED THE HANDLING OF THE NODE FAILURE.   */
  2211. /* ------------------------------------------------------------------------- */
  2212. void Dbdih::execNF_COMPLETEREP(Signal* signal) 
  2213. {
  2214.   NodeRecordPtr failedNodePtr;
  2215.   NFCompleteRep * const nfCompleteRep = (NFCompleteRep *)&signal->theData[0];
  2216.   jamEntry();
  2217.   const Uint32 blockNo = nfCompleteRep->blockNo;
  2218.   Uint32 nodeId       = nfCompleteRep->nodeId;
  2219.   failedNodePtr.i = nfCompleteRep->failedNodeId;
  2220.   ptrCheckGuard(failedNodePtr, MAX_NDB_NODES, nodeRecord);
  2221.   switch (blockNo) {
  2222.   case DBTC:
  2223.     jam();
  2224.     ndbrequire(failedNodePtr.p->dbtcFailCompleted == ZFALSE);
  2225.     /* -------------------------------------------------------------------- */
  2226.     // Report the event that DBTC completed node failure handling.
  2227.     /* -------------------------------------------------------------------- */
  2228.     signal->theData[0] = EventReport::NodeFailCompleted;
  2229.     signal->theData[1] = DBTC;
  2230.     signal->theData[2] = failedNodePtr.i;
  2231.     sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
  2232.     failedNodePtr.p->dbtcFailCompleted = ZTRUE;
  2233.     break;
  2234.   case DBDICT:
  2235.     jam();
  2236.     ndbrequire(failedNodePtr.p->dbdictFailCompleted == ZFALSE);
  2237.     /* --------------------------------------------------------------------- */
  2238.     // Report the event that DBDICT completed node failure handling.
  2239.     /* --------------------------------------------------------------------- */
  2240.     signal->theData[0] = EventReport::NodeFailCompleted;
  2241.     signal->theData[1] = DBDICT;
  2242.     signal->theData[2] = failedNodePtr.i;
  2243.     sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
  2244.     failedNodePtr.p->dbdictFailCompleted = ZTRUE;
  2245.     break;
  2246.   case DBDIH:
  2247.     jam();
  2248.     ndbrequire(failedNodePtr.p->dbdihFailCompleted == ZFALSE);
  2249.     /* --------------------------------------------------------------------- */
  2250.     // Report the event that DBDIH completed node failure handling.
  2251.     /* --------------------------------------------------------------------- */
  2252.     signal->theData[0] = EventReport::NodeFailCompleted;
  2253.     signal->theData[1] = DBDIH;
  2254.     signal->theData[2] = failedNodePtr.i;
  2255.     sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
  2256.     failedNodePtr.p->dbdihFailCompleted = ZTRUE;
  2257.     break;
  2258.   case DBLQH:
  2259.     jam();
  2260.     ndbrequire(failedNodePtr.p->dblqhFailCompleted == ZFALSE);
  2261.     /* --------------------------------------------------------------------- */
  2262.     // Report the event that DBDIH completed node failure handling.
  2263.     /* --------------------------------------------------------------------- */
  2264.     signal->theData[0] = EventReport::NodeFailCompleted;
  2265.     signal->theData[1] = DBLQH;
  2266.     signal->theData[2] = failedNodePtr.i;
  2267.     sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
  2268.     failedNodePtr.p->dblqhFailCompleted = ZTRUE;
  2269.     break;
  2270.   case 0: /* Node has finished */
  2271.     jam();
  2272.     ndbrequire(nodeId < MAX_NDB_NODES);
  2273.     if (failedNodePtr.p->recNODE_FAILREP == ZFALSE) {
  2274.       jam();
  2275.       /* ------------------------------------------------------------------- */
  2276.       // We received a report about completion of node failure before we 
  2277.       // received the message about the NODE failure ourselves. 
  2278.       // We will send the signal to ourselves with a small delay 
  2279.       // (10 milliseconds).
  2280.       /* ------------------------------------------------------------------- */
  2281.       //nf->from = __LINE__;
  2282.       sendSignalWithDelay(reference(), GSN_NF_COMPLETEREP, signal, 10,
  2283.   signal->length());
  2284.       return;
  2285.     }//if
  2286.     
  2287.     if (!failedNodePtr.p->m_NF_COMPLETE_REP.isWaitingFor(nodeId)){
  2288.       jam();
  2289.       return;
  2290.     }
  2291.       
  2292.     failedNodePtr.p->m_NF_COMPLETE_REP.clearWaitingFor(nodeId);;
  2293.     
  2294.     /* -------------------------------------------------------------------- */
  2295.     // Report the event that nodeId has completed node failure handling.
  2296.     /* -------------------------------------------------------------------- */
  2297.     signal->theData[0] = EventReport::NodeFailCompleted;
  2298.     signal->theData[1] = 0;
  2299.     signal->theData[2] = failedNodePtr.i;
  2300.     signal->theData[3] = nodeId;
  2301.     sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 4, JBB);
  2302.     
  2303.     nodeFailCompletedCheckLab(signal, failedNodePtr);
  2304.     return;
  2305.     break;
  2306.   default:
  2307.     ndbrequire(false);
  2308.     return;
  2309.     break;
  2310.   }//switch
  2311.   if (failedNodePtr.p->dbtcFailCompleted == ZFALSE) {
  2312.     jam();
  2313.     return;
  2314.   }//if
  2315.   if (failedNodePtr.p->dbdictFailCompleted == ZFALSE) {
  2316.     jam();
  2317.     return;
  2318.   }//if
  2319.   if (failedNodePtr.p->dbdihFailCompleted == ZFALSE) {
  2320.     jam();
  2321.     return;
  2322.   }//if
  2323.   if (failedNodePtr.p->dblqhFailCompleted == ZFALSE) {
  2324.     jam();
  2325.     return;
  2326.   }//if
  2327.   /* ----------------------------------------------------------------------- */
  2328.   /*     ALL BLOCKS IN THIS NODE HAVE COMPLETED THEIR PART OF HANDLING THE   */
  2329.   /*     NODE FAILURE. WE CAN NOW REPORT THIS COMPLETION TO ALL OTHER NODES. */
  2330.   /* ----------------------------------------------------------------------- */
  2331.   NodeRecordPtr nodePtr;
  2332.   for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
  2333.     jam();
  2334.     ptrAss(nodePtr, nodeRecord);
  2335.     if (nodePtr.p->nodeStatus == NodeRecord::ALIVE) {
  2336.       jam();
  2337.       BlockReference ref = calcDihBlockRef(nodePtr.i);
  2338.       NFCompleteRep * const nf = (NFCompleteRep *)&signal->theData[0];
  2339.       nf->blockNo      = 0;
  2340.       nf->nodeId       = cownNodeId;
  2341.       nf->failedNodeId = failedNodePtr.i;
  2342.       nf->from = __LINE__;
  2343.       sendSignal(ref, GSN_NF_COMPLETEREP, signal, 
  2344.                  NFCompleteRep::SignalLength, JBB);
  2345.     }//if
  2346.   }//for
  2347.   return;
  2348. }//Dbdih::execNF_COMPLETEREP()
  2349. void Dbdih::nodeFailCompletedCheckLab(Signal* signal, 
  2350.       NodeRecordPtr failedNodePtr) 
  2351. {
  2352.   jam();
  2353.   if (!failedNodePtr.p->m_NF_COMPLETE_REP.done()){
  2354.     jam(); 
  2355.     return;
  2356.   }//if
  2357.   /* ---------------------------------------------------------------------- */
  2358.   /*    ALL BLOCKS IN ALL NODES HAVE NOW REPORTED COMPLETION OF THE NODE    */
  2359.   /*    FAILURE HANDLING. WE ARE NOW READY TO ACCEPT THAT THIS NODE STARTS  */
  2360.   /*    AGAIN.                                                              */
  2361.   /* ---------------------------------------------------------------------- */
  2362.   jam();
  2363.   failedNodePtr.p->nodeStatus = NodeRecord::DEAD;
  2364.   failedNodePtr.p->recNODE_FAILREP = ZFALSE;
  2365.   
  2366.   /* ---------------------------------------------------------------------- */
  2367.   // Report the event that all nodes completed node failure handling.
  2368.   /* ---------------------------------------------------------------------- */
  2369.   signal->theData[0] = EventReport::NodeFailCompleted;
  2370.   signal->theData[1] = 0;
  2371.   signal->theData[2] = failedNodePtr.i;
  2372.   signal->theData[3] = 0;
  2373.   sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 4, JBB);
  2374.   /* ---------------------------------------------------------------------- */
  2375.   // Report to QMGR that we have concluded recovery handling of this node.
  2376.   /* ---------------------------------------------------------------------- */
  2377.   signal->theData[0] = failedNodePtr.i;
  2378.   sendSignal(QMGR_REF, GSN_NDB_FAILCONF, signal, 1, JBB);
  2379.   
  2380.   if (isMaster()) {
  2381.     jam();
  2382.     /* --------------------------------------------------------------------- */
  2383.     /*   IF WE ARE MASTER WE MUST CHECK IF COPY FRAGMENT WAS INTERRUPTED     */
  2384.     /*   BY THE FAILED NODES.                                                */
  2385.     /* --------------------------------------------------------------------- */
  2386.     TakeOverRecordPtr takeOverPtr;
  2387.     takeOverPtr.i = 0;
  2388.     ptrAss(takeOverPtr, takeOverRecord);
  2389.     if ((takeOverPtr.p->toMasterStatus == TakeOverRecord::COPY_FRAG) &&
  2390.         (failedNodePtr.i == takeOverPtr.p->toCopyNode)) {
  2391.       jam();
  2392. #ifdef VM_TRACE
  2393.       ndbrequire("Tell jonas" == 0);
  2394. #endif
  2395.       /*------------------------------------------------------------------*/
  2396.       /*       WE ARE CURRENTLY IN THE PROCESS OF COPYING A FRAGMENT. WE  */
  2397.       /*       WILL CHECK IF THE COPY NODE HAVE FAILED.                   */
  2398.       /*------------------------------------------------------------------*/
  2399.       takeOverPtr.p->toMasterStatus = TakeOverRecord::SELECTING_NEXT;
  2400.       startNextCopyFragment(signal, takeOverPtr.i);
  2401.       return;
  2402.     }//if
  2403.     checkStartTakeOver(signal);
  2404.   }//if
  2405.   return;
  2406. }//Dbdih::nodeFailCompletedCheckLab()
  2407. /*****************************************************************************/
  2408. /* **********     SEIZING / RELEASING MODULE                     *************/
  2409. /*****************************************************************************/
  2410. /*
  2411.   3.4   L O C A L  N O D E   S E I Z E  
  2412.   ************************************
  2413.   */
  2414. /*
  2415.   3.4.1   L O C A L  N O D E   S E I Z E   R E Q U E S T
  2416.   ******************************************************
  2417.   */
  2418. void Dbdih::execDISEIZEREQ(Signal* signal) 
  2419. {
  2420.   ConnectRecordPtr connectPtr;
  2421.   jamEntry();
  2422.   Uint32 userPtr = signal->theData[0];
  2423.   BlockReference userRef = signal->theData[1];
  2424.   ndbrequire(cfirstconnect != RNIL);
  2425.   connectPtr.i = cfirstconnect;
  2426.   ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
  2427.   cfirstconnect = connectPtr.p->nfConnect;
  2428.   connectPtr.p->nfConnect = RNIL;
  2429.   connectPtr.p->userpointer = userPtr;
  2430.   connectPtr.p->userblockref = userRef;
  2431.   connectPtr.p->connectState = ConnectRecord::INUSE;
  2432.   signal->theData[0] = connectPtr.p->userpointer;
  2433.   signal->theData[1] = connectPtr.i;
  2434.   sendSignal(userRef, GSN_DISEIZECONF, signal, 2, JBB);
  2435. }//Dbdih::execDISEIZEREQ()
  2436. /*
  2437.   3.5   L O C A L  N O D E   R E L E A S E
  2438.   ****************************************
  2439.   */
  2440. /*
  2441.   3.5.1   L O C A L  N O D E   R E L E A S E   R E Q U E S T
  2442.   *******************************************************=
  2443.   */
  2444. void Dbdih::execDIRELEASEREQ(Signal* signal) 
  2445. {
  2446.   ConnectRecordPtr connectPtr;
  2447.   jamEntry();
  2448.   connectPtr.i = signal->theData[0];
  2449.   Uint32 userRef = signal->theData[2];
  2450.   ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
  2451.   ndbrequire(connectPtr.p->connectState != ConnectRecord::FREE);
  2452.   ndbrequire(connectPtr.p->userblockref == userRef);
  2453.   signal->theData[0] = connectPtr.p->userpointer;
  2454.   sendSignal(connectPtr.p->userblockref, GSN_DIRELEASECONF, signal, 1, JBB);
  2455.   release_connect(connectPtr);
  2456. }//Dbdih::execDIRELEASEREQ()
  2457. /*
  2458.   3.7   A D D   T A B L E
  2459.   **********************=
  2460.   */
  2461. /*****************************************************************************/
  2462. /* **********     TABLE ADDING MODULE                            *************/
  2463. /*****************************************************************************/
  2464. /*
  2465.   3.7.1   A D D   T A B L E   M A I N L Y
  2466.   ***************************************
  2467.   */
  2468. void Dbdih::execCREATE_FRAGMENTATION_REQ(Signal * signal){
  2469.   jamEntry();
  2470.   CreateFragmentationReq * const req = 
  2471.     (CreateFragmentationReq*)signal->getDataPtr();
  2472.   
  2473.   const Uint32 senderRef = req->senderRef;
  2474.   const Uint32 senderData = req->senderData;
  2475.   const Uint32 fragmentNode = req->fragmentNode;
  2476.   const Uint32 fragmentType = req->fragmentationType;
  2477.   //const Uint32 fragmentCount = req->noOfFragments;
  2478.   const Uint32 primaryTableId = req->primaryTableId;
  2479.   Uint32 err = 0;
  2480.   
  2481.   do {
  2482.     Uint32 noOfFragments = 0;
  2483.     Uint32 noOfReplicas = cnoReplicas;
  2484.     switch(fragmentType){
  2485.     case DictTabInfo::AllNodesSmallTable:
  2486.       jam();
  2487.       noOfFragments = csystemnodes;
  2488.       break;
  2489.     case DictTabInfo::AllNodesMediumTable:
  2490.       jam();
  2491.       noOfFragments = 2 * csystemnodes;
  2492.       break;
  2493.     case DictTabInfo::AllNodesLargeTable:
  2494.       jam();
  2495.       noOfFragments = 4 * csystemnodes;
  2496.       break;
  2497.     case DictTabInfo::SingleFragment:
  2498.       jam();
  2499.       noOfFragments = 1;
  2500.       break;
  2501. #if 0
  2502.     case DictTabInfo::SpecifiedFragmentCount:
  2503.       noOfFragments = (fragmentCount == 0 ? 1 : (fragmentCount + 1)/ 2);
  2504.       break;
  2505. #endif
  2506.     default:
  2507.       jam();
  2508.       err = CreateFragmentationRef::InvalidFragmentationType;
  2509.       break;
  2510.     }
  2511.     if(err)
  2512.       break;
  2513.    
  2514.     NodeGroupRecordPtr NGPtr;
  2515.     TabRecordPtr primTabPtr;
  2516.     if (primaryTableId == RNIL) {
  2517.       if(fragmentNode == 0){
  2518.         jam();
  2519. // needs to be fixed for single fragment tables
  2520.         NGPtr.i = 0; //c_nextNodeGroup;
  2521.         c_nextNodeGroup = (NGPtr.i + 1 == cnoOfNodeGroups ? 0 : NGPtr.i + 1);
  2522.       } else if(! (fragmentNode < MAX_NDB_NODES)) {
  2523.         jam();
  2524.         err = CreateFragmentationRef::InvalidNodeId;
  2525.       } else {
  2526.         jam();
  2527.         const Uint32 stat = Sysfile::getNodeStatus(fragmentNode,
  2528.                                                    SYSFILE->nodeStatus);
  2529.         switch (stat) {
  2530.         case Sysfile::NS_Active:
  2531.         case Sysfile::NS_ActiveMissed_1:
  2532.         case Sysfile::NS_ActiveMissed_2:
  2533.         case Sysfile::NS_TakeOver:
  2534.           jam();
  2535.           break;
  2536.         case Sysfile::NS_NotActive_NotTakenOver:
  2537.           jam();
  2538.           break;
  2539.         case Sysfile::NS_HotSpare:
  2540.           jam();
  2541.         case Sysfile::NS_NotDefined:
  2542.           jam();
  2543.         default:
  2544.           jam();
  2545.           err = CreateFragmentationRef::InvalidNodeType;
  2546.           break;
  2547.         }
  2548.         if(err)
  2549.           break;
  2550.         NGPtr.i = Sysfile::getNodeGroup(fragmentNode,
  2551.                                         SYSFILE->nodeGroups);
  2552.         break;
  2553.       }
  2554.     } else {
  2555.       if (primaryTableId >= ctabFileSize) {
  2556.         jam();
  2557.         err = CreateFragmentationRef::InvalidPrimaryTable;
  2558.         break;
  2559.       }
  2560.       primTabPtr.i = primaryTableId;
  2561.       ptrAss(primTabPtr, tabRecord);
  2562.       if (primTabPtr.p->tabStatus != TabRecord::TS_ACTIVE) {
  2563.         jam();
  2564.         err = CreateFragmentationRef::InvalidPrimaryTable;
  2565.         break;
  2566.       }
  2567.       if (noOfFragments != primTabPtr.p->totalfragments) {
  2568.         jam();
  2569.         err = CreateFragmentationRef::InvalidFragmentationType;
  2570.         break;
  2571.       }
  2572.     }
  2573.     
  2574.     //@todo use section writer
  2575.     Uint32 count = 2;
  2576.     Uint32 fragments[2 + 8*MAX_REPLICAS*MAX_NDB_NODES];
  2577.     Uint32 next_replica_node[MAX_NDB_NODES];
  2578.     memset(next_replica_node,0,sizeof(next_replica_node));
  2579.     if (primaryTableId == RNIL) {
  2580.       jam();
  2581.       for(Uint32 fragNo = 0; fragNo<noOfFragments; fragNo++){
  2582.         jam();
  2583.         ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);      
  2584.         Uint32 ind = next_replica_node[NGPtr.i];
  2585.         const Uint32 max = NGPtr.p->nodeCount;
  2586.         //-------------------------------------------------------------------
  2587.         // We make an extra step to ensure that the primary replicas are
  2588.         // spread among the nodes.
  2589.         //-------------------------------------------------------------------
  2590.         next_replica_node[NGPtr.i] = (ind + 1 >= max ? 0 : ind + 1);
  2591.         
  2592.         for(Uint32 replicaNo = 0; replicaNo<noOfReplicas; replicaNo++){
  2593.           jam();
  2594.           const Uint32 nodeId = NGPtr.p->nodesInGroup[ind++];
  2595.           fragments[count++] = nodeId;
  2596.           ind = (ind == max ? 0 : ind);
  2597.         }
  2598.         
  2599.         /**
  2600.          * Next node group for next fragment
  2601.          */
  2602.         NGPtr.i++;
  2603.         NGPtr.i = (NGPtr.i == cnoOfNodeGroups ? 0 : NGPtr.i);
  2604.       }
  2605.     } else {
  2606.       for (Uint32 fragNo = 0;
  2607.            fragNo < primTabPtr.p->totalfragments; fragNo++) {
  2608.         jam();
  2609.         FragmentstorePtr fragPtr;
  2610.         ReplicaRecordPtr replicaPtr;
  2611.         getFragstore(primTabPtr.p, fragNo, fragPtr);
  2612.         fragments[count++] = fragPtr.p->preferredPrimary;
  2613.         for (replicaPtr.i = fragPtr.p->storedReplicas;
  2614.              replicaPtr.i != RNIL;
  2615.              replicaPtr.i = replicaPtr.p->nextReplica) {
  2616.           jam();
  2617.           ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
  2618.           if (replicaPtr.p->procNode != fragPtr.p->preferredPrimary) {
  2619.             jam();
  2620.             fragments[count++] = replicaPtr.p->procNode;
  2621.           }//if
  2622.         }//for
  2623.         for (replicaPtr.i = fragPtr.p->oldStoredReplicas;
  2624.              replicaPtr.i != RNIL;
  2625.              replicaPtr.i = replicaPtr.p->nextReplica) {
  2626.           jam();
  2627.           ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
  2628.           if (replicaPtr.p->procNode != fragPtr.p->preferredPrimary) {
  2629.             jam();
  2630.             fragments[count++] = replicaPtr.p->procNode;
  2631.           }//if
  2632.         }//for
  2633.       }
  2634.     }
  2635.     ndbrequire(count == (2 + noOfReplicas * noOfFragments)); 
  2636.     
  2637.     CreateFragmentationConf * const conf = 
  2638.       (CreateFragmentationConf*)signal->getDataPtrSend();
  2639.     conf->senderRef = reference();
  2640.     conf->senderData = senderData;
  2641.     conf->noOfReplicas = noOfReplicas;
  2642.     conf->noOfFragments = noOfFragments;
  2643.     fragments[0] = noOfReplicas;
  2644.     fragments[1] = noOfFragments;
  2645.     
  2646.     LinearSectionPtr ptr[3];
  2647.     ptr[0].p = &fragments[0];
  2648.     ptr[0].sz = count;
  2649.     sendSignal(senderRef,
  2650.        GSN_CREATE_FRAGMENTATION_CONF,
  2651.        signal, 
  2652.        CreateFragmentationConf::SignalLength,
  2653.        JBB,
  2654.        ptr,
  2655.        1);
  2656.     return;
  2657.   } while(false);
  2658.   
  2659.   CreateFragmentationRef * const ref = 
  2660.     (CreateFragmentationRef*)signal->getDataPtrSend();
  2661.   ref->senderRef = reference();
  2662.   ref->senderData = senderData;
  2663.   ref->errorCode = err;
  2664.   sendSignal(senderRef, GSN_CREATE_FRAGMENTATION_REF, signal, 
  2665.      CreateFragmentationRef::SignalLength, JBB);
  2666. }
  2667. void Dbdih::execDIADDTABREQ(Signal* signal) 
  2668. {
  2669.   jamEntry();
  2670.   DiAddTabReq * const req = (DiAddTabReq*)signal->getDataPtr();
  2671.   // Seize connect record
  2672.   ndbrequire(cfirstconnect != RNIL);
  2673.   ConnectRecordPtr connectPtr;
  2674.   connectPtr.i = cfirstconnect;
  2675.   ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
  2676.   cfirstconnect = connectPtr.p->nfConnect;
  2677.   
  2678.   const Uint32 userPtr = req->connectPtr;
  2679.   const BlockReference userRef = signal->getSendersBlockRef();
  2680.   connectPtr.p->nfConnect = RNIL;
  2681.   connectPtr.p->userpointer = userPtr;
  2682.   connectPtr.p->userblockref = userRef;
  2683.   connectPtr.p->connectState = ConnectRecord::INUSE;
  2684.   connectPtr.p->table = req->tableId;
  2685.   
  2686.   TabRecordPtr tabPtr;
  2687.   tabPtr.i = req->tableId;
  2688.   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  2689.   tabPtr.p->connectrec = connectPtr.i;
  2690.   tabPtr.p->tableType = req->tableType;
  2691.   tabPtr.p->schemaVersion = req->schemaVersion;
  2692.   tabPtr.p->primaryTableId = req->primaryTableId;
  2693.   if(tabPtr.p->tabStatus == TabRecord::TS_ACTIVE){
  2694.     jam();
  2695.     tabPtr.p->tabStatus = TabRecord::TS_CREATING;
  2696.     sendAddFragreq(signal, connectPtr, tabPtr, 0);
  2697.     return;
  2698.   }
  2699.   if(getNodeState().getSystemRestartInProgress() &&
  2700.      tabPtr.p->tabStatus == TabRecord::TS_IDLE){
  2701.     jam();
  2702.     
  2703.     ndbrequire(cmasterNodeId == getOwnNodeId());
  2704.     tabPtr.p->tabStatus = TabRecord::TS_CREATING;
  2705.     
  2706.     initTableFile(tabPtr);
  2707.     FileRecordPtr filePtr;
  2708.     filePtr.i = tabPtr.p->tabFile[0];
  2709.     ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
  2710.     openFileRw(signal, filePtr);
  2711.     filePtr.p->reqStatus = FileRecord::OPENING_TABLE;
  2712.     return;
  2713.   }
  2714.   /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
  2715.   /* AT THE TIME OF INITIATING THE FILE OF TABLE         */
  2716.   /* DESCRIPTION IS CREATED FOR APPROPRIATE SIZE. EACH   */
  2717.   /* EACH RECORD IN THIS FILE HAS THE INFORMATION ABOUT  */
  2718.   /* ONE TABLE. THE POINTER TO THIS RECORD IS THE TABLE  */
  2719.   /* REFERENCE. IN THE BEGINNING ALL RECORDS ARE CREATED */
  2720.   /* BUT THEY DO NOT HAVE ANY INFORMATION ABOUT ANY TABLE*/
  2721.   /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
  2722.   tabPtr.p->tabStatus = TabRecord::TS_CREATING;
  2723.   tabPtr.p->storedTable = req->storedTable;
  2724.   tabPtr.p->method = TabRecord::HASH;
  2725.   tabPtr.p->kvalue = req->kValue;
  2726.   Uint32 fragments[2 + 8*MAX_REPLICAS*MAX_NDB_NODES];
  2727.   SegmentedSectionPtr fragDataPtr;
  2728.   signal->getSection(fragDataPtr, DiAddTabReq::FRAGMENTATION);
  2729.   copy(fragments, fragDataPtr);
  2730.   releaseSections(signal);
  2731.   const Uint32 noReplicas = fragments[0];
  2732.   const Uint32 noFragments = fragments[1];
  2733.   tabPtr.p->noOfBackups = noReplicas - 1;
  2734.   tabPtr.p->totalfragments = noFragments;
  2735.   ndbrequire(noReplicas == cnoReplicas); // Only allowed
  2736.   if (ERROR_INSERTED(7173)) {
  2737.     addtabrefuseLab(signal, connectPtr, ZREPLERROR1);
  2738.     return;
  2739.   }
  2740.   if ((noReplicas * noFragments) > cnoFreeReplicaRec) {
  2741.     jam();
  2742.     addtabrefuseLab(signal, connectPtr, ZREPLERROR1);
  2743.     return;
  2744.   }//if
  2745.   if (noFragments > cremainingfrags) {
  2746.     jam();
  2747.     addtabrefuseLab(signal, connectPtr, ZREPLERROR1);
  2748.     return;
  2749.   }//if
  2750.   
  2751.   Uint32 logTotalFragments = 1;
  2752.   while (logTotalFragments <= tabPtr.p->totalfragments) {
  2753.     jam();
  2754.     logTotalFragments <<= 1;
  2755.   }
  2756.   logTotalFragments >>= 1;
  2757.   tabPtr.p->mask = logTotalFragments - 1;
  2758.   tabPtr.p->hashpointer = tabPtr.p->totalfragments - logTotalFragments;
  2759.   allocFragments(tabPtr.p->totalfragments, tabPtr);  
  2760.   Uint32 index = 2;
  2761.   for (Uint32 fragId = 0; fragId < noFragments; fragId++) {
  2762.     jam();
  2763.     FragmentstorePtr fragPtr;
  2764.     Uint32 activeIndex = 0;
  2765.     getFragstore(tabPtr.p, fragId, fragPtr);
  2766.     fragPtr.p->preferredPrimary = fragments[index];
  2767.     for (Uint32 i = 0; i<noReplicas; i++) {
  2768.       const Uint32 nodeId = fragments[index++];
  2769.       ReplicaRecordPtr replicaPtr;
  2770.       allocStoredReplica(fragPtr, replicaPtr, nodeId);
  2771.       if (getNodeStatus(nodeId) == NodeRecord::ALIVE) {
  2772.         jam();
  2773.         ndbrequire(activeIndex < MAX_REPLICAS);
  2774.         fragPtr.p->activeNodes[activeIndex] = nodeId;
  2775.         activeIndex++;
  2776.       } else {
  2777.         jam();
  2778.         removeStoredReplica(fragPtr, replicaPtr);
  2779.         linkOldStoredReplica(fragPtr, replicaPtr);
  2780.       }//if
  2781.     }//for
  2782.     fragPtr.p->fragReplicas = activeIndex;
  2783.     ndbrequire(activeIndex > 0 && fragPtr.p->storedReplicas != RNIL);
  2784.   }
  2785.   initTableFile(tabPtr);
  2786.   tabPtr.p->tabCopyStatus = TabRecord::CS_ADD_TABLE_MASTER;
  2787.   signal->theData[0] = DihContinueB::ZPACK_TABLE_INTO_PAGES;
  2788.   signal->theData[1] = tabPtr.i;
  2789.   sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
  2790. }
  2791. void
  2792. Dbdih::addTable_closeConf(Signal * signal, Uint32 tabPtrI){
  2793.   TabRecordPtr tabPtr;
  2794.   tabPtr.i = tabPtrI;
  2795.   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  2796.   ConnectRecordPtr connectPtr;
  2797.   connectPtr.i = tabPtr.p->connectrec;
  2798.   ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
  2799.   
  2800.   sendAddFragreq(signal, connectPtr, tabPtr, 0);
  2801. }
  2802. void
  2803. Dbdih::sendAddFragreq(Signal* signal, ConnectRecordPtr connectPtr, 
  2804.       TabRecordPtr tabPtr, Uint32 fragId){
  2805.   jam();
  2806.   const Uint32 fragCount = tabPtr.p->totalfragments;
  2807.   ReplicaRecordPtr replicaPtr; replicaPtr.i = RNIL;
  2808.   for(; fragId<fragCount; fragId++){
  2809.     jam();
  2810.     FragmentstorePtr fragPtr;
  2811.     getFragstore(tabPtr.p, fragId, fragPtr);    
  2812.     
  2813.     replicaPtr.i = fragPtr.p->storedReplicas;
  2814.     while(replicaPtr.i != RNIL){
  2815.       jam();
  2816.       ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);      
  2817.       if(replicaPtr.p->procNode == getOwnNodeId()){
  2818. break;
  2819.       }
  2820.       replicaPtr.i = replicaPtr.p->nextReplica;
  2821.     }
  2822.     
  2823.     if(replicaPtr.i != RNIL){
  2824.       jam();
  2825.       break;
  2826.     }
  2827.     
  2828.     replicaPtr.i = fragPtr.p->oldStoredReplicas;
  2829.     while(replicaPtr.i != RNIL){
  2830.       jam();
  2831.       ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);      
  2832.       if(replicaPtr.p->procNode == getOwnNodeId()){
  2833. break;
  2834.       }
  2835.       replicaPtr.i = replicaPtr.p->nextReplica;
  2836.     }
  2837.     if(replicaPtr.i != RNIL){
  2838.       jam();
  2839.       break;
  2840.     }
  2841.   }
  2842.   
  2843.   if(replicaPtr.i != RNIL){
  2844.     jam();
  2845.     ndbrequire(fragId < fragCount);
  2846.     ndbrequire(replicaPtr.p->procNode == getOwnNodeId());
  2847.     Uint32 requestInfo = 0;
  2848.     if(!tabPtr.p->storedTable){
  2849.       requestInfo |= LqhFragReq::TemporaryTable;
  2850.     }
  2851.     
  2852.     if(getNodeState().getNodeRestartInProgress()){
  2853.       requestInfo |= LqhFragReq::CreateInRunning;
  2854.     }
  2855.     
  2856.     AddFragReq* const req = (AddFragReq*)signal->getDataPtr();
  2857.     req->dihPtr = connectPtr.i;
  2858.     req->senderData = connectPtr.p->userpointer;
  2859.     req->fragmentId = fragId;
  2860.     req->requestInfo = requestInfo;
  2861.     req->tableId = tabPtr.i;
  2862.     req->nextLCP = 0;
  2863.     req->nodeId = getOwnNodeId();
  2864.     req->totalFragments = fragCount;
  2865.     req->startGci = SYSFILE->newestRestorableGCI;
  2866.     sendSignal(DBDICT_REF, GSN_ADD_FRAGREQ, signal, 
  2867.        AddFragReq::SignalLength, JBB);
  2868.     return;
  2869.   }
  2870.   
  2871.   // Done
  2872.   DiAddTabConf * const conf = (DiAddTabConf*)signal->getDataPtr();
  2873.   conf->senderData = connectPtr.p->userpointer;
  2874.   sendSignal(connectPtr.p->userblockref, GSN_DIADDTABCONF, signal, 
  2875.      DiAddTabConf::SignalLength, JBB);  
  2876.   // Release
  2877.   release_connect(connectPtr);
  2878. }
  2879. void
  2880. Dbdih::release_connect(ConnectRecordPtr ptr)
  2881. {
  2882.   ptr.p->userblockref = ZNIL;
  2883.   ptr.p->userpointer = RNIL;
  2884.   ptr.p->connectState = ConnectRecord::FREE;
  2885.   ptr.p->nfConnect = cfirstconnect;
  2886.   cfirstconnect = ptr.i;
  2887. }
  2888. void
  2889. Dbdih::execADD_FRAGCONF(Signal* signal){
  2890.   jamEntry();
  2891.   AddFragConf * const conf = (AddFragConf*)signal->getDataPtr();
  2892.   ConnectRecordPtr connectPtr;
  2893.   connectPtr.i = conf->dihPtr;
  2894.   ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
  2895.   TabRecordPtr tabPtr;
  2896.   tabPtr.i = connectPtr.p->table;
  2897.   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  2898.   sendAddFragreq(signal, connectPtr, tabPtr, conf->fragId + 1);
  2899. }
  2900. void
  2901. Dbdih::execADD_FRAGREF(Signal* signal){
  2902.   jamEntry();
  2903.   AddFragRef * const ref = (AddFragRef*)signal->getDataPtr();
  2904.   ConnectRecordPtr connectPtr;
  2905.   connectPtr.i = ref->dihPtr;
  2906.   ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
  2907.   {
  2908.     DiAddTabRef * const ref = (DiAddTabRef*)signal->getDataPtr();
  2909.     ref->senderData = connectPtr.p->userpointer;
  2910.     ref->errorCode = ~0;
  2911.     sendSignal(connectPtr.p->userblockref, GSN_DIADDTABREF, signal, 
  2912.        DiAddTabRef::SignalLength, JBB);  
  2913.   }
  2914.   
  2915.   // Release
  2916.   release_connect(connectPtr);
  2917. }
  2918. /*
  2919.   3.7.1.3   R E F U S E
  2920.   *********************
  2921.   */
  2922. void Dbdih::addtabrefuseLab(Signal* signal, ConnectRecordPtr connectPtr, Uint32 errorCode) 
  2923. {
  2924.   signal->theData[0] = connectPtr.p->userpointer;
  2925.   signal->theData[1] = errorCode;
  2926.   sendSignal(connectPtr.p->userblockref, GSN_DIADDTABREF, signal, 2, JBB);
  2927.   release_connect(connectPtr);
  2928.   return;
  2929. }//Dbdih::addtabrefuseLab()
  2930. /*
  2931.   3.7.2   A D D   T A B L E   D U P L I C A T I O N
  2932.   *************************************************
  2933.   */
  2934. /*
  2935.   3.7.2.1    A D D   T A B L E   D U P L I C A T I O N   R E Q U E S T
  2936.   *******************************************************************=
  2937.   */
  2938. /*
  2939.   D E L E T E   T A B L E
  2940.   **********************=
  2941.   */
  2942. /*****************************************************************************/
  2943. /***********              DELETE TABLE  MODULE                   *************/
  2944. /*****************************************************************************/
  2945. void
  2946. Dbdih::execDROP_TAB_REQ(Signal* signal){
  2947.   jamEntry();
  2948.   DropTabReq* req = (DropTabReq*)signal->getDataPtr();
  2949.   TabRecordPtr tabPtr;
  2950.   tabPtr.i = req->tableId;
  2951.   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  2952.   
  2953.   tabPtr.p->m_dropTab.tabUserRef = req->senderRef;
  2954.   tabPtr.p->m_dropTab.tabUserPtr = req->senderData;
  2955.   DropTabReq::RequestType rt = (DropTabReq::RequestType)req->requestType;
  2956.   switch(rt){
  2957.   case DropTabReq::OnlineDropTab:
  2958.     jam();
  2959.     ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_DROPPING);
  2960.     releaseTable(tabPtr);
  2961.     break;
  2962.   case DropTabReq::CreateTabDrop:
  2963.     jam();
  2964.     releaseTable(tabPtr);
  2965.     break;
  2966.   case DropTabReq::RestartDropTab:
  2967.     break;
  2968.   }
  2969.   
  2970.   startDeleteFile(signal, tabPtr);
  2971. }
  2972. void Dbdih::startDeleteFile(Signal* signal, TabRecordPtr tabPtr)
  2973. {
  2974.   if (tabPtr.p->tabFile[0] == RNIL) {
  2975.     jam();
  2976.     initTableFile(tabPtr);
  2977.   }//if
  2978.   openTableFileForDelete(signal, tabPtr.p->tabFile[0]);
  2979. }//Dbdih::startDeleteFile()
  2980. void Dbdih::openTableFileForDelete(Signal* signal, Uint32 fileIndex)
  2981. {
  2982.   FileRecordPtr filePtr;
  2983.   filePtr.i = fileIndex;
  2984.   ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
  2985.   openFileRw(signal, filePtr);
  2986.   filePtr.p->reqStatus = FileRecord::TABLE_OPEN_FOR_DELETE;
  2987. }//Dbdih::openTableFileForDelete()
  2988. void Dbdih::tableOpenLab(Signal* signal, FileRecordPtr filePtr) 
  2989. {
  2990.   closeFileDelete(signal, filePtr);
  2991.   filePtr.p->reqStatus = FileRecord::TABLE_CLOSE_DELETE;
  2992.   return;
  2993. }//Dbdih::tableOpenLab()
  2994. void Dbdih::tableDeleteLab(Signal* signal, FileRecordPtr filePtr) 
  2995. {
  2996.   TabRecordPtr tabPtr;
  2997.   tabPtr.i = filePtr.p->tabRef;
  2998.   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  2999.   if (filePtr.i == tabPtr.p->tabFile[0]) {
  3000.     jam();
  3001.     openTableFileForDelete(signal, tabPtr.p->tabFile[1]);
  3002.     return;
  3003.   }//if
  3004.   ndbrequire(filePtr.i == tabPtr.p->tabFile[1]);
  3005.   
  3006.   releaseFile(tabPtr.p->tabFile[0]);
  3007.   releaseFile(tabPtr.p->tabFile[1]);
  3008.   tabPtr.p->tabFile[0] = tabPtr.p->tabFile[1] = RNIL;
  3009.   tabPtr.p->tabStatus = TabRecord::TS_IDLE;
  3010.   
  3011.   DropTabConf * const dropConf = (DropTabConf *)signal->getDataPtrSend();
  3012.   dropConf->senderRef = reference();
  3013.   dropConf->senderData = tabPtr.p->m_dropTab.tabUserPtr;
  3014.   dropConf->tableId = tabPtr.i;
  3015.   sendSignal(tabPtr.p->m_dropTab.tabUserRef, GSN_DROP_TAB_CONF, 
  3016.      signal, DropTabConf::SignalLength, JBB);
  3017.   
  3018.   tabPtr.p->m_dropTab.tabUserPtr = RNIL;
  3019.   tabPtr.p->m_dropTab.tabUserRef = 0;
  3020. }//Dbdih::tableDeleteLab()
  3021. void Dbdih::releaseTable(TabRecordPtr tabPtr)
  3022. {
  3023.   FragmentstorePtr fragPtr;
  3024.   if (tabPtr.p->noOfFragChunks > 0) {
  3025.     for (Uint32 fragId = 0; fragId < tabPtr.p->totalfragments; fragId++) {
  3026.       jam();
  3027.       getFragstore(tabPtr.p, fragId, fragPtr);
  3028.       releaseReplicas(fragPtr.p->storedReplicas);
  3029.       releaseReplicas(fragPtr.p->oldStoredReplicas);
  3030.     }//for
  3031.     releaseFragments(tabPtr);
  3032.   }
  3033.   if (tabPtr.p->tabFile[0] != RNIL) {
  3034.     jam();
  3035.     releaseFile(tabPtr.p->tabFile[0]);
  3036.     releaseFile(tabPtr.p->tabFile[1]);
  3037.     tabPtr.p->tabFile[0] = tabPtr.p->tabFile[1] = RNIL;
  3038.   }//if
  3039. }//Dbdih::releaseTable()
  3040. void Dbdih::releaseReplicas(Uint32 replicaPtrI) 
  3041. {
  3042.   ReplicaRecordPtr replicaPtr;
  3043.   replicaPtr.i = replicaPtrI;
  3044.   jam();
  3045.   while (replicaPtr.i != RNIL) {
  3046.     jam();
  3047.     ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
  3048.     Uint32 tmp = replicaPtr.p->nextReplica;
  3049.     replicaPtr.p->nextReplica = cfirstfreeReplica;
  3050.     cfirstfreeReplica = replicaPtr.i;
  3051.     replicaPtr.i = tmp;
  3052.     cnoFreeReplicaRec++;
  3053.   }//while
  3054. }//Dbdih::releaseReplicas()
  3055. void Dbdih::seizeReplicaRec(ReplicaRecordPtr& replicaPtr) 
  3056. {
  3057.   replicaPtr.i = cfirstfreeReplica;
  3058.   ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
  3059.   cfirstfreeReplica = replicaPtr.p->nextReplica;
  3060.   cnoFreeReplicaRec--;
  3061.   replicaPtr.p->nextReplica = RNIL;
  3062. }//Dbdih::seizeReplicaRec()
  3063. void Dbdih::releaseFile(Uint32 fileIndex)
  3064. {
  3065.   FileRecordPtr filePtr;
  3066.   filePtr.i = fileIndex;
  3067.   ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
  3068.   filePtr.p->nextFile = cfirstfreeFile;
  3069.   cfirstfreeFile = filePtr.i;
  3070. }//Dbdih::releaseFile()
  3071. void Dbdih::execALTER_TAB_REQ(Signal * signal)
  3072. {
  3073.   AlterTabReq* const req = (AlterTabReq*)signal->getDataPtr();
  3074.   const Uint32 senderRef = req->senderRef;
  3075.   const Uint32 senderData = req->senderData;
  3076.   const Uint32 changeMask = req->changeMask;
  3077.   const Uint32 tableId = req->tableId;
  3078.   const Uint32 tableVersion = req->tableVersion;
  3079.   const Uint32 gci = req->gci;
  3080.   AlterTabReq::RequestType requestType = 
  3081.     (AlterTabReq::RequestType) req->requestType;
  3082.   TabRecordPtr tabPtr;
  3083.   tabPtr.i = tableId;
  3084.   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  3085.   tabPtr.p->schemaVersion = tableVersion;
  3086.   // Request handled successfully 
  3087.   AlterTabConf * conf = (AlterTabConf*)signal->getDataPtrSend();
  3088.   conf->senderRef = reference();
  3089.   conf->senderData = senderData;
  3090.   conf->changeMask = changeMask;
  3091.   conf->tableId = tableId;
  3092.   conf->tableVersion = tableVersion;
  3093.   conf->gci = gci;
  3094.   conf->requestType = requestType;
  3095.   sendSignal(senderRef, GSN_ALTER_TAB_CONF, signal, 
  3096.      AlterTabConf::SignalLength, JBB);
  3097. }
  3098. /*
  3099.   G E T   N O D E S  
  3100.   **********************=
  3101.   */
  3102. /*****************************************************************************/
  3103. /* **********     TRANSACTION  HANDLING  MODULE                  *************/
  3104. /*****************************************************************************/
  3105. /*
  3106.   3.8.1    G E T   N O D E S   R E Q U E S T
  3107.   ******************************************
  3108.   Asks what nodes should be part of a transaction.
  3109. */
  3110. void Dbdih::execDIGETNODESREQ(Signal* signal) 
  3111. {
  3112.   const DiGetNodesReq * const req = (DiGetNodesReq *)&signal->theData[0];
  3113.   FragmentstorePtr fragPtr;
  3114.   TabRecordPtr tabPtr;
  3115.   tabPtr.i = req->tableId;
  3116.   Uint32 hashValue = req->hashValue;
  3117.   Uint32 ttabFileSize = ctabFileSize;
  3118.   TabRecord* regTabDesc = tabRecord;
  3119.   jamEntry();
  3120.   ptrCheckGuard(tabPtr, ttabFileSize, regTabDesc);
  3121.   hashValue = hashValue >> tabPtr.p->kvalue;
  3122.   Uint32 fragId = tabPtr.p->mask & hashValue;
  3123.   ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_ACTIVE);
  3124.   if (fragId < tabPtr.p->hashpointer) {
  3125.     jam();
  3126.     fragId = hashValue & ((tabPtr.p->mask << 1) + 1);
  3127.   }//if
  3128.   getFragstore(tabPtr.p, fragId, fragPtr);
  3129.   DiGetNodesConf * const conf = (DiGetNodesConf *)&signal->theData[0];
  3130.   Uint32 nodeCount = extractNodeInfo(fragPtr.p, conf->nodes);
  3131.   Uint32 sig2 = (nodeCount - 1) + 
  3132.     (fragPtr.p->distributionKey << 16);
  3133.   conf->zero = 0;
  3134.   conf->reqinfo = sig2;
  3135.   conf->fragId = fragId;
  3136. }//Dbdih::execDIGETNODESREQ()
  3137. Uint32 Dbdih::extractNodeInfo(const Fragmentstore * fragPtr, Uint32 nodes[]) 
  3138. {
  3139.   Uint32 nodeCount = 0;
  3140.   for (Uint32 i = 0; i < fragPtr->fragReplicas; i++) {
  3141.     jam();
  3142.     NodeRecordPtr nodePtr;
  3143.     ndbrequire(i < MAX_REPLICAS);
  3144.     nodePtr.i = fragPtr->activeNodes[i];
  3145.     ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
  3146.     if (nodePtr.p->useInTransactions) {
  3147.       jam();
  3148.       nodes[nodeCount] = nodePtr.i;
  3149.       nodeCount++;
  3150.     }//if
  3151.   }//for
  3152.   ndbrequire(nodeCount > 0);
  3153.   return nodeCount;
  3154. }//Dbdih::extractNodeInfo()
  3155. void 
  3156. Dbdih::getFragstore(TabRecord * tab,        //In parameter
  3157.                     Uint32 fragNo,              //In parameter
  3158.                     FragmentstorePtr & fragptr) //Out parameter
  3159. {
  3160.   FragmentstorePtr fragPtr;
  3161.   Uint32 chunkNo = fragNo >> LOG_NO_OF_FRAGS_PER_CHUNK;
  3162.   Uint32 chunkIndex = fragNo & (NO_OF_FRAGS_PER_CHUNK - 1);
  3163.   Uint32 TfragstoreFileSize = cfragstoreFileSize;
  3164.   Fragmentstore* TfragStore = fragmentstore;
  3165.   if (chunkNo < MAX_NDB_NODES) {
  3166.     fragPtr.i = tab->startFid[chunkNo] + chunkIndex;
  3167.     ptrCheckGuard(fragPtr, TfragstoreFileSize, TfragStore);
  3168.     fragptr = fragPtr;
  3169.     return;
  3170.   }//if
  3171.   ndbrequire(false);
  3172. }//Dbdih::getFragstore()
  3173. void Dbdih::allocFragments(Uint32 noOfFragments, TabRecordPtr tabPtr)
  3174. {
  3175.   FragmentstorePtr fragPtr;
  3176.   Uint32 noOfChunks = (noOfFragments + (NO_OF_FRAGS_PER_CHUNK - 1)) >> LOG_NO_OF_FRAGS_PER_CHUNK;
  3177.   ndbrequire(cremainingfrags >= noOfFragments);
  3178.   for (Uint32 i = 0; i < noOfChunks; i++) {
  3179.     jam();
  3180.     Uint32 baseFrag = cfirstfragstore;
  3181.     tabPtr.p->startFid[i] = baseFrag;
  3182.     fragPtr.i = baseFrag;
  3183.     ptrCheckGuard(fragPtr, cfragstoreFileSize, fragmentstore);
  3184.     cfirstfragstore = fragPtr.p->nextFragmentChunk;
  3185.     cremainingfrags -= NO_OF_FRAGS_PER_CHUNK;
  3186.     for (Uint32 j = 0; j < NO_OF_FRAGS_PER_CHUNK; j++) {
  3187.       jam();
  3188.       fragPtr.i = baseFrag + j;
  3189.       ptrCheckGuard(fragPtr, cfragstoreFileSize, fragmentstore);
  3190.       initFragstore(fragPtr);
  3191.     }//if
  3192.   }//for
  3193.   tabPtr.p->noOfFragChunks = noOfChunks;
  3194. }//Dbdih::allocFragments()
  3195. void Dbdih::releaseFragments(TabRecordPtr tabPtr)
  3196. {
  3197.   FragmentstorePtr fragPtr;
  3198.   for (Uint32 i = 0; i < tabPtr.p->noOfFragChunks; i++) {
  3199.     jam();
  3200.     Uint32 baseFrag = tabPtr.p->startFid[i];
  3201.     fragPtr.i = baseFrag;
  3202.     ptrCheckGuard(fragPtr, cfragstoreFileSize, fragmentstore);
  3203.     fragPtr.p->nextFragmentChunk = cfirstfragstore;
  3204.     cfirstfragstore = baseFrag;
  3205.     tabPtr.p->startFid[i] = RNIL;
  3206.     cremainingfrags += NO_OF_FRAGS_PER_CHUNK;
  3207.   }//for
  3208.   tabPtr.p->noOfFragChunks = 0;
  3209. }//Dbdih::releaseFragments()
  3210. void Dbdih::initialiseFragstore()
  3211. {
  3212.   Uint32 i;
  3213.   FragmentstorePtr fragPtr;
  3214.   for (i = 0; i < cfragstoreFileSize; i++) {
  3215.     fragPtr.i = i;
  3216.     ptrCheckGuard(fragPtr, cfragstoreFileSize, fragmentstore);
  3217.     initFragstore(fragPtr);
  3218.   }//for
  3219.   Uint32 noOfChunks = cfragstoreFileSize >> LOG_NO_OF_FRAGS_PER_CHUNK;
  3220.   fragPtr.i = 0;
  3221.   cfirstfragstore = RNIL;
  3222.   cremainingfrags = 0;
  3223.   for (i = 0; i < noOfChunks; i++) {
  3224.     refresh_watch_dog();
  3225.     ptrCheckGuard(fragPtr, cfragstoreFileSize, fragmentstore);
  3226.     fragPtr.p->nextFragmentChunk = cfirstfragstore;
  3227.     cfirstfragstore = fragPtr.i;
  3228.     fragPtr.i += NO_OF_FRAGS_PER_CHUNK;
  3229.     cremainingfrags += NO_OF_FRAGS_PER_CHUNK;
  3230.   }//for    
  3231. }//Dbdih::initialiseFragstore()
  3232. /*
  3233.   3.9   V E R I F I C A T I O N
  3234.   ****************************=
  3235.   */
  3236. /****************************************************************************/
  3237. /* **********     VERIFICATION SUB-MODULE                       *************/
  3238. /****************************************************************************/
  3239. /*
  3240.   3.9.1     R E C E I V I N G  O F  V E R I F I C A T I O N   R E Q U E S T
  3241.   *************************************************************************
  3242.   */
  3243. void Dbdih::execDIVERIFYREQ(Signal* signal) 
  3244. {
  3245.   jamEntry();
  3246.   if ((getBlockCommit() == false) &&
  3247.       (cfirstVerifyQueue == RNIL)) {
  3248.     jam();
  3249.     /*-----------------------------------------------------------------------*/
  3250.     // We are not blocked and the verify queue was empty currently so we can
  3251.     // simply reply back to TC immediately. The method was called with 
  3252.     // EXECUTE_DIRECT so we reply back by setting signal data and returning. 
  3253.     // theData[0] already contains the correct information so 
  3254.     // we need not touch it.
  3255.     /*-----------------------------------------------------------------------*/
  3256.     signal->theData[1] = currentgcp;
  3257.     signal->theData[2] = 0;
  3258.     return;
  3259.   }//if
  3260.   /*-------------------------------------------------------------------------*/
  3261.   // Since we are blocked we need to put this operation last in the verify
  3262.   // queue to ensure that operation starts up in the correct order.
  3263.   /*-------------------------------------------------------------------------*/
  3264.   ApiConnectRecordPtr tmpApiConnectptr;
  3265.   ApiConnectRecordPtr localApiConnectptr;
  3266.   cverifyQueueCounter++;
  3267.   localApiConnectptr.i = signal->theData[0];
  3268.   tmpApiConnectptr.i = clastVerifyQueue;
  3269.   ptrCheckGuard(localApiConnectptr, capiConnectFileSize, apiConnectRecord);
  3270.   localApiConnectptr.p->apiGci = cnewgcp;
  3271.   localApiConnectptr.p->nextApi = RNIL;
  3272.   clastVerifyQueue = localApiConnectptr.i;
  3273.   if (tmpApiConnectptr.i == RNIL) {
  3274.     jam();
  3275.     cfirstVerifyQueue = localApiConnectptr.i;
  3276.   } else {
  3277.     jam();
  3278.     ptrCheckGuard(tmpApiConnectptr, capiConnectFileSize, apiConnectRecord);
  3279.     tmpApiConnectptr.p->nextApi = localApiConnectptr.i;
  3280.   }//if
  3281.   emptyverificbuffer(signal, false);
  3282.   signal->theData[2] = 1; // Indicate no immediate return
  3283.   return;
  3284. }//Dbdih::execDIVERIFYREQ()
  3285. void Dbdih::execDI_FCOUNTREQ(Signal* signal) 
  3286. {
  3287.   ConnectRecordPtr connectPtr;
  3288.   TabRecordPtr tabPtr;
  3289.   jamEntry();
  3290.   connectPtr.i = signal->theData[0];
  3291.   tabPtr.i = signal->theData[1];
  3292.   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  3293.   ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_ACTIVE);
  3294.   if(connectPtr.i != RNIL){
  3295.     ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
  3296.     if (connectPtr.p->connectState == ConnectRecord::INUSE) {
  3297.       jam();
  3298.       signal->theData[0] = connectPtr.p->userpointer;
  3299.       signal->theData[1] = tabPtr.p->totalfragments;
  3300.       sendSignal(connectPtr.p->userblockref, GSN_DI_FCOUNTCONF, signal,2, JBB);
  3301.       return;
  3302.     }//if
  3303.     signal->theData[0] = connectPtr.p->userpointer;
  3304.     signal->theData[1] = ZERRONOUSSTATE;
  3305.     sendSignal(connectPtr.p->userblockref, GSN_DI_FCOUNTREF, signal, 2, JBB);
  3306.     return;
  3307.   }//if
  3308.   //connectPtr.i == RNIL -> question without connect record
  3309.   const Uint32 senderData = signal->theData[2];
  3310.   const BlockReference senderRef = signal->senderBlockRef();
  3311.   signal->theData[0] = RNIL;
  3312.   signal->theData[1] = tabPtr.p->totalfragments;
  3313.   signal->theData[2] = tabPtr.i;
  3314.   signal->theData[3] = senderData;
  3315.   signal->theData[4] = tabPtr.p->noOfBackups;
  3316.   sendSignal(senderRef, GSN_DI_FCOUNTCONF, signal, 5, JBB);
  3317. }//Dbdih::execDI_FCOUNTREQ()
  3318. void Dbdih::execDIGETPRIMREQ(Signal* signal) 
  3319. {
  3320.   FragmentstorePtr fragPtr;
  3321.   ConnectRecordPtr connectPtr;
  3322.   TabRecordPtr tabPtr;
  3323.   jamEntry();
  3324.   Uint32 passThrough = signal->theData[1];
  3325.   tabPtr.i = signal->theData[2];
  3326.   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  3327.   if (DictTabInfo::isOrderedIndex(tabPtr.p->tableType)) {
  3328.     jam();
  3329.     tabPtr.i = tabPtr.p->primaryTableId;
  3330.     ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  3331.   }
  3332.   Uint32 fragId = signal->theData[3];
  3333.   
  3334.   ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_ACTIVE);
  3335.   connectPtr.i = signal->theData[0];
  3336.   if(connectPtr.i != RNIL)
  3337.   {
  3338.     jam();
  3339.     ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
  3340.     signal->theData[0] = connectPtr.p->userpointer;
  3341.   }
  3342.   else
  3343.   {
  3344.     jam();
  3345.     signal->theData[0] = RNIL;
  3346.   }
  3347.   
  3348.   Uint32 nodes[MAX_REPLICAS];
  3349.   getFragstore(tabPtr.p, fragId, fragPtr);
  3350.   Uint32 count = extractNodeInfo(fragPtr.p, nodes);
  3351.   
  3352.   signal->theData[1] = passThrough;
  3353.   signal->theData[2] = nodes[0];
  3354.   signal->theData[3] = nodes[1];
  3355.   signal->theData[4] = nodes[2];
  3356.   signal->theData[5] = nodes[3];
  3357.   signal->theData[6] = count;
  3358.   signal->theData[7] = tabPtr.i;
  3359.   signal->theData[8] = fragId;
  3360.   const BlockReference senderRef = signal->senderBlockRef();
  3361.   sendSignal(senderRef, GSN_DIGETPRIMCONF, signal, 9, JBB);
  3362. }//Dbdih::execDIGETPRIMREQ()
  3363. /****************************************************************************/
  3364. /* **********     GLOBAL-CHECK-POINT HANDLING  MODULE           *************/
  3365. /****************************************************************************/
  3366. /*
  3367.   3.10   G L O B A L  C H E C K P O I N T ( IN  M A S T E R  R O L E)
  3368.   *******************************************************************
  3369.   */
  3370. void Dbdih::checkGcpStopLab(Signal* signal) 
  3371. {
  3372.   Uint32 tgcpStatus;
  3373.   tgcpStatus = cgcpStatus;
  3374.   if (tgcpStatus == coldGcpStatus) {
  3375.     jam();
  3376.     if (coldGcpId == cnewgcp) {
  3377.       jam();
  3378.       if (cgcpStatus != GCP_READY) {
  3379.         jam();
  3380.         cgcpSameCounter++;
  3381.         if (cgcpSameCounter == 1200) {
  3382.           jam();