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

MySQL数据库

开发平台:

Visual C++

  1. #ifdef VM_TRACE
  2.           ndbout << "System crash due to GCP Stop in state = ";
  3.           ndbout << (Uint32) cgcpStatus << endl;
  4. #endif
  5.           crashSystemAtGcpStop(signal);
  6.           return;
  7.         }//if
  8.       } else {
  9.         jam();
  10.         if (cgcpOrderBlocked == 0) {
  11.           jam();
  12.           cgcpSameCounter++;
  13.           if (cgcpSameCounter == 1200) {
  14.             jam();
  15. #ifdef VM_TRACE
  16.             ndbout << "System crash due to GCP Stop in state = ";
  17.             ndbout << (Uint32) cgcpStatus << endl;
  18. #endif
  19.     crashSystemAtGcpStop(signal);
  20.             return;
  21.           }//if
  22.         } else {
  23.           jam();
  24.           cgcpSameCounter = 0;
  25.         }//if
  26.       }//if
  27.     } else {
  28.       jam();
  29.       cgcpSameCounter = 0;
  30.     }//if
  31.   } else {
  32.     jam();
  33.     cgcpSameCounter = 0;
  34.   }//if
  35.   signal->theData[0] = DihContinueB::ZCHECK_GCP_STOP;
  36.   signal->theData[1] = coldGcpStatus;
  37.   signal->theData[2] = cgcpStatus;
  38.   signal->theData[3] = coldGcpId;
  39.   signal->theData[4] = cnewgcp;
  40.   signal->theData[5] = cgcpSameCounter;
  41.   sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 6);
  42.   coldGcpStatus = cgcpStatus;
  43.   coldGcpId = cnewgcp;
  44.   return;
  45. }//Dbdih::checkGcpStopLab()
  46. void Dbdih::startGcpLab(Signal* signal, Uint32 aWaitTime) 
  47. {
  48.   if ((cgcpOrderBlocked == 1) ||
  49.       (c_nodeStartMaster.blockGcp == true) ||
  50.       (cfirstVerifyQueue != RNIL)) {
  51.     /*************************************************************************/
  52.     // 1: Global Checkpoint has been stopped by management command
  53.     // 2: Global Checkpoint is blocked by node recovery activity
  54.     // 3: Previous global checkpoint is not yet completed.
  55.     // All this means that global checkpoint cannot start now.
  56.     /*************************************************************************/
  57.     jam();
  58.     cgcpStartCounter++;
  59.     signal->theData[0] = DihContinueB::ZSTART_GCP;
  60.     signal->theData[1] = aWaitTime > 100 ? (aWaitTime - 100) : 0;
  61.     sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 2);
  62.     return;
  63.   }//if
  64.   if (cstartGcpNow == false && aWaitTime > 100){
  65.     /*************************************************************************/
  66.     // We still have more than 100 milliseconds before we start the next and 
  67.     // nobody has ordered immediate start of a global checkpoint.
  68.     // During initial start we will use continuos global checkpoints to 
  69.     // speed it up since we need to complete a global checkpoint after 
  70.     // inserting a lot of records.
  71.     /*************************************************************************/
  72.     jam();
  73.     cgcpStartCounter++;
  74.     signal->theData[0] = DihContinueB::ZSTART_GCP;
  75.     signal->theData[1] = (aWaitTime - 100);
  76.     sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 2);
  77.     return;
  78.   }//if
  79.   cgcpStartCounter = 0;
  80.   cstartGcpNow = false;
  81.   /***************************************************************************/
  82.   // Report the event that a global checkpoint has started.
  83.   /***************************************************************************/
  84.   signal->theData[0] = EventReport::GlobalCheckpointStarted; //Event type
  85.   signal->theData[1] = cnewgcp;
  86.   sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
  87.   CRASH_INSERTION(7000);
  88.   cnewgcp++;
  89.   signal->setTrace(TestOrd::TraceGlobalCheckpoint);
  90.   sendLoopMacro(GCP_PREPARE, sendGCP_PREPARE);
  91.   cgcpStatus = GCP_PREPARE_SENT;
  92. }//Dbdih::startGcpLab()
  93. void Dbdih::execGCP_PREPARECONF(Signal* signal) 
  94. {
  95.   jamEntry();
  96.   Uint32 senderNodeId = signal->theData[0];
  97.   Uint32 gci = signal->theData[1];
  98.   ndbrequire(gci == cnewgcp);
  99.   receiveLoopMacro(GCP_PREPARE, senderNodeId);
  100.   //-------------------------------------------------------------
  101.   // We have now received all replies. We are ready to continue
  102.   // with committing the global checkpoint.
  103.   //-------------------------------------------------------------
  104.   gcpcommitreqLab(signal);
  105. }//Dbdih::execGCP_PREPARECONF()
  106. void Dbdih::gcpcommitreqLab(Signal* signal) 
  107. {
  108.   CRASH_INSERTION(7001);
  109.   sendLoopMacro(GCP_COMMIT, sendGCP_COMMIT);
  110.   cgcpStatus = GCP_COMMIT_SENT;
  111.   return;
  112. }//Dbdih::gcpcommitreqLab()
  113. void Dbdih::execGCP_NODEFINISH(Signal* signal) 
  114. {
  115.   jamEntry();
  116.   const Uint32 senderNodeId = signal->theData[0];
  117.   const Uint32 gci = signal->theData[1];
  118.   const Uint32 failureNr = signal->theData[2];
  119.   if (!isMaster()) {
  120.     jam();
  121.     ndbrequire(failureNr > cfailurenr);
  122.     //-------------------------------------------------------------
  123.     // Another node thinks we are master. This could happen when he
  124.     // has heard of a node failure which I have not heard of. Ignore
  125.     // signal in this case since we will discover it by sending
  126.     // MASTER_GCPREQ to the node.
  127.     //-------------------------------------------------------------
  128.     return;
  129.   } else if (cmasterState == MASTER_TAKE_OVER_GCP) {
  130.     jam();
  131.     //-------------------------------------------------------------
  132.     // We are currently taking over as master. We will delay the
  133.     // signal until we have completed the take over gcp handling.
  134.     //-------------------------------------------------------------
  135.     sendSignalWithDelay(reference(), GSN_GCP_NODEFINISH, signal, 20, 3);
  136.     return;
  137.   } else {
  138.     ndbrequire(cmasterState == MASTER_ACTIVE);
  139.   }//if
  140.   ndbrequire(gci == coldgcp);
  141.   receiveLoopMacro(GCP_COMMIT, senderNodeId);
  142.   //-------------------------------------------------------------
  143.   // We have now received all replies. We are ready to continue
  144.   // with saving the global checkpoint to disk.
  145.   //-------------------------------------------------------------
  146.   CRASH_INSERTION(7002);
  147.   gcpsavereqLab(signal);
  148.   return;
  149. }//Dbdih::execGCP_NODEFINISH()
  150. void Dbdih::gcpsavereqLab(Signal* signal) 
  151. {
  152.   sendLoopMacro(GCP_SAVEREQ, sendGCP_SAVEREQ);
  153.   cgcpStatus = GCP_NODE_FINISHED;
  154. }//Dbdih::gcpsavereqLab()
  155. void Dbdih::execGCP_SAVECONF(Signal* signal) 
  156. {
  157.   jamEntry();  
  158.   const GCPSaveConf * const saveConf = (GCPSaveConf*)&signal->theData[0];
  159.   ndbrequire(saveConf->gci == coldgcp);
  160.   ndbrequire(saveConf->nodeId == saveConf->dihPtr);
  161.   SYSFILE->lastCompletedGCI[saveConf->nodeId] = saveConf->gci;  
  162.   GCP_SAVEhandling(signal, saveConf->nodeId);
  163. }//Dbdih::execGCP_SAVECONF()
  164. void Dbdih::execGCP_SAVEREF(Signal* signal) 
  165. {
  166.   jamEntry();
  167.   const GCPSaveRef * const saveRef = (GCPSaveRef*)&signal->theData[0];
  168.   ndbrequire(saveRef->gci == coldgcp);
  169.   ndbrequire(saveRef->nodeId == saveRef->dihPtr);
  170.   /**
  171.    * Only allow reason not to save
  172.    */
  173.   ndbrequire(saveRef->errorCode == GCPSaveRef::NodeShutdownInProgress ||
  174.      saveRef->errorCode == GCPSaveRef::FakedSignalDueToNodeFailure ||
  175.      saveRef->errorCode == GCPSaveRef::NodeRestartInProgress);
  176.   GCP_SAVEhandling(signal, saveRef->nodeId);
  177. }//Dbdih::execGCP_SAVEREF()
  178. void Dbdih::GCP_SAVEhandling(Signal* signal, Uint32 nodeId) 
  179. {
  180.   receiveLoopMacro(GCP_SAVEREQ, nodeId);
  181.   /*-------------------------------------------------------------------------*/
  182.   // All nodes have replied. We are ready to update the system file.
  183.   /*-------------------------------------------------------------------------*/
  184.   cgcpStatus = GCP_SAVE_LQH_FINISHED;  
  185.   CRASH_INSERTION(7003);
  186.   checkToCopy();
  187.   /**------------------------------------------------------------------------
  188.    * SET NEW RECOVERABLE GCI. ALSO RESET RESTART COUNTER TO ZERO. 
  189.    * THIS INDICATES THAT THE SYSTEM HAS BEEN RECOVERED AND SURVIVED AT 
  190.    * LEAST ONE GLOBAL CHECKPOINT PERIOD. WE WILL USE THIS PARAMETER TO 
  191.    * SET BACK THE RESTART GCI IF WE ENCOUNTER MORE THAN ONE UNSUCCESSFUL 
  192.    * RESTART.
  193.    *------------------------------------------------------------------------*/
  194.   SYSFILE->newestRestorableGCI = coldgcp;
  195.   if(Sysfile::getInitialStartOngoing(SYSFILE->systemRestartBits) &&
  196.      getNodeState().startLevel == NodeState::SL_STARTED){
  197.     jam();
  198. #if 0
  199.     ndbout_c("Dbdih: Clearing initial start ongoing");
  200. #endif
  201.     Sysfile::clearInitialStartOngoing(SYSFILE->systemRestartBits);
  202.   }
  203.   copyGciLab(signal, CopyGCIReq::GLOBAL_CHECKPOINT);
  204. }//Dbdih::GCP_SAVEhandling()
  205. /*
  206.   3.11   G L O B A L  C H E C K P O I N T (N O T - M A S T E R)
  207.   *************************************************************
  208.   */
  209. void Dbdih::execGCP_PREPARE(Signal* signal) 
  210. {
  211.   jamEntry();
  212.   CRASH_INSERTION(7005);
  213.   Uint32 masterNodeId = signal->theData[0];
  214.   Uint32 gci = signal->theData[1];
  215.   BlockReference retRef = calcDihBlockRef(masterNodeId);
  216.                                                  
  217.   ndbrequire (cmasterdihref == retRef);
  218.   ndbrequire (cgcpParticipantState == GCP_PARTICIPANT_READY);
  219.   ndbrequire (gci == (currentgcp + 1));
  220.   
  221.   cgckptflag = true;
  222.   cgcpParticipantState = GCP_PARTICIPANT_PREPARE_RECEIVED;
  223.   cnewgcp = gci;
  224.   signal->theData[0] = cownNodeId;
  225.   signal->theData[1] = gci;  
  226.   sendSignal(retRef, GSN_GCP_PREPARECONF, signal, 2, JBA);
  227.   return;
  228. }//Dbdih::execGCP_PREPARE()
  229. void Dbdih::execGCP_COMMIT(Signal* signal) 
  230. {
  231.   jamEntry();
  232.   CRASH_INSERTION(7006);
  233.   Uint32 masterNodeId = signal->theData[0];
  234.   Uint32 gci = signal->theData[1];
  235.   ndbrequire(gci == (currentgcp + 1));
  236.   ndbrequire(masterNodeId = cmasterNodeId);
  237.   ndbrequire(cgcpParticipantState == GCP_PARTICIPANT_PREPARE_RECEIVED);
  238.   
  239.   coldgcp = currentgcp;
  240.   currentgcp = cnewgcp;  
  241.   cgckptflag = false;
  242.   emptyverificbuffer(signal, true);
  243.   cgcpParticipantState = GCP_PARTICIPANT_COMMIT_RECEIVED;
  244.   signal->theData[1] = coldgcp;
  245.   sendSignal(clocaltcblockref, GSN_GCP_NOMORETRANS, signal, 2, JBB);
  246.   return;
  247. }//Dbdih::execGCP_COMMIT()
  248. void Dbdih::execGCP_TCFINISHED(Signal* signal) 
  249. {
  250.   jamEntry();
  251.   CRASH_INSERTION(7007);
  252.   Uint32 gci = signal->theData[1];
  253.   ndbrequire(gci == coldgcp);
  254.   cgcpParticipantState = GCP_PARTICIPANT_TC_FINISHED;
  255.   signal->theData[0] = cownNodeId;
  256.   signal->theData[1] = coldgcp;
  257.   signal->theData[2] = cfailurenr;
  258.   sendSignal(cmasterdihref, GSN_GCP_NODEFINISH, signal, 3, JBB);
  259. }//Dbdih::execGCP_TCFINISHED()
  260. /*****************************************************************************/
  261. //******     RECEIVING   TAMPER   REQUEST   FROM    NDBAPI             ******
  262. /*****************************************************************************/
  263. void Dbdih::execDIHNDBTAMPER(Signal* signal) 
  264. {
  265.   jamEntry();
  266.   Uint32 tcgcpblocked = signal->theData[0];
  267.   /* ACTION TO BE TAKEN BY DIH */
  268.   Uint32 tuserpointer = signal->theData[1];
  269.   BlockReference tuserblockref = signal->theData[2];
  270.   switch (tcgcpblocked) {
  271.   case 1:
  272.     jam();
  273.     if (isMaster()) {
  274.       jam();
  275.       cgcpOrderBlocked = 1;
  276.     } else {
  277.       jam();
  278.       /* TRANSFER THE REQUEST */
  279.       /* TO MASTER*/
  280.       signal->theData[0] = tcgcpblocked;
  281.       signal->theData[1] = tuserpointer;
  282.       signal->theData[2] = tuserblockref;
  283.       sendSignal(cmasterdihref, GSN_DIHNDBTAMPER, signal, 3, JBB);
  284.     }//if
  285.     break;
  286.   case 2:
  287.     jam();
  288.     if (isMaster()) {
  289.       jam();
  290.       cgcpOrderBlocked = 0;
  291.     } else {
  292.       jam();
  293.       /* TRANSFER THE REQUEST */
  294.       /* TO MASTER*/
  295.       signal->theData[0] = tcgcpblocked;
  296.       signal->theData[1] = tuserpointer;
  297.       signal->theData[2] = tuserblockref;
  298.       sendSignal(cmasterdihref, GSN_DIHNDBTAMPER, signal, 3, JBB);
  299.     }//if
  300.     break;
  301.   case 3:
  302.     ndbrequire(false);
  303.     return;
  304.     break;
  305.   case 4:
  306.     jam();
  307.     signal->theData[0] = tuserpointer;
  308.     signal->theData[1] = crestartGci;
  309.     sendSignal(tuserblockref, GSN_DIHNDBTAMPER, signal, 2, JBB);
  310.     break;
  311. #ifdef ERROR_INSERT
  312.   case 5:
  313.     jam();
  314.     /*----------------------------------------------------------------------*/
  315.     // Insert errors.
  316.     /*----------------------------------------------------------------------*/
  317.     if (tuserpointer < 1000) {
  318.       /*--------------------------------------------------------------------*/
  319.       // Insert errors into QMGR.
  320.       /*--------------------------------------------------------------------*/
  321.       jam();
  322.       tuserblockref = QMGR_REF;
  323.     } else if (tuserpointer < 2000) {
  324.       /*--------------------------------------------------------------------*/
  325.       // Insert errors into NDBCNTR.
  326.       /*--------------------------------------------------------------------*/
  327.       jam();
  328.       tuserblockref = NDBCNTR_REF;
  329.     } else if (tuserpointer < 3000) {
  330.       /*--------------------------------------------------------------------*/
  331.       // Insert errors into NDBFS.
  332.       /*--------------------------------------------------------------------*/
  333.       jam();
  334.       tuserblockref = NDBFS_REF;
  335.     } else if (tuserpointer < 4000) {
  336.       /*--------------------------------------------------------------------*/
  337.       // Insert errors into DBACC.
  338.       /*--------------------------------------------------------------------*/
  339.       jam();
  340.       tuserblockref = DBACC_REF;
  341.     } else if (tuserpointer < 5000) {
  342.       /*--------------------------------------------------------------------*/
  343.       // Insert errors into DBTUP.
  344.       /*--------------------------------------------------------------------*/
  345.       jam();
  346.       tuserblockref = DBTUP_REF;
  347.     } else if (tuserpointer < 6000) {
  348.       /*---------------------------------------------------------------------*/
  349.       // Insert errors into DBLQH.
  350.       /*---------------------------------------------------------------------*/
  351.       jam();
  352.       tuserblockref = DBLQH_REF;
  353.     } else if (tuserpointer < 7000) {
  354.       /*---------------------------------------------------------------------*/
  355.       // Insert errors into DBDICT.
  356.       /*---------------------------------------------------------------------*/
  357.       jam();
  358.       tuserblockref = DBDICT_REF;
  359.     } else if (tuserpointer < 8000) {
  360.       /*---------------------------------------------------------------------*/
  361.       // Insert errors into DBDIH.
  362.       /*--------------------------------------------------------------------*/
  363.       jam();
  364.       tuserblockref = DBDIH_REF;
  365.     } else if (tuserpointer < 9000) {
  366.       /*--------------------------------------------------------------------*/
  367.       // Insert errors into DBTC.
  368.       /*--------------------------------------------------------------------*/
  369.       jam();
  370.       tuserblockref = DBTC_REF;
  371.     } else if (tuserpointer < 10000) {
  372.       /*--------------------------------------------------------------------*/
  373.       // Insert errors into CMVMI.
  374.       /*--------------------------------------------------------------------*/
  375.       jam();
  376.       tuserblockref = CMVMI_REF;
  377.     } else if (tuserpointer < 11000) {
  378.       jam();
  379.       tuserblockref = BACKUP_REF;
  380.     } else if (tuserpointer < 12000) {
  381.       // DBUTIL_REF ?
  382.       jam();
  383.     } else if (tuserpointer < 13000) {
  384.       jam();
  385.       tuserblockref = DBTUX_REF;
  386.     } else if (tuserpointer < 14000) {
  387.       jam();
  388.       tuserblockref = SUMA_REF;
  389.     } else if (tuserpointer < 15000) {
  390.       jam();
  391.       tuserblockref = DBDICT_REF;
  392.     } else if (tuserpointer < 30000) {
  393.       /*--------------------------------------------------------------------*/
  394.       // Ignore errors in the 20000-range.
  395.       /*--------------------------------------------------------------------*/
  396.       jam();
  397.       return;
  398.     } else if (tuserpointer < 40000) {
  399.       jam();
  400.       /*--------------------------------------------------------------------*/
  401.       // Redirect errors to master DIH in the 30000-range.
  402.       /*--------------------------------------------------------------------*/
  403.       tuserblockref = cmasterdihref;
  404.       tuserpointer -= 30000;
  405.       signal->theData[0] = 5;
  406.       signal->theData[1] = tuserpointer;
  407.       signal->theData[2] = tuserblockref;
  408.       sendSignal(tuserblockref, GSN_DIHNDBTAMPER, signal, 3, JBB);
  409.       return;
  410.     } else if (tuserpointer < 50000) {
  411.       NodeRecordPtr localNodeptr;
  412.       Uint32 Tfound = 0;
  413.       jam();
  414.       /*--------------------------------------------------------------------*/
  415.       // Redirect errors to non-master DIH in the 40000-range.
  416.       /*--------------------------------------------------------------------*/
  417.       tuserpointer -= 40000;
  418.       for (localNodeptr.i = 1; 
  419.            localNodeptr.i < MAX_NDB_NODES;
  420.            localNodeptr.i++) {
  421.         jam();
  422.         ptrAss(localNodeptr, nodeRecord);
  423.         if ((localNodeptr.p->nodeStatus == NodeRecord::ALIVE) &&
  424.             (localNodeptr.i != cmasterNodeId)) {
  425.           jam();
  426.           tuserblockref = calcDihBlockRef(localNodeptr.i);
  427.           Tfound = 1;
  428.           break;
  429.         }//if
  430.       }//for
  431.       if (Tfound == 0) {
  432.         jam();
  433. /*-------------------------------------------------------------------*/
  434. // Ignore since no non-master node existed.
  435. /*-------------------------------------------------------------------*/
  436.         return;
  437.       }//if
  438.       signal->theData[0] = 5;
  439.       signal->theData[1] = tuserpointer;
  440.       signal->theData[2] = tuserblockref;
  441.       sendSignal(tuserblockref, GSN_DIHNDBTAMPER, signal, 3, JBB);
  442.       return;
  443.     } else {
  444.       jam();
  445.       return;
  446.     }//if
  447.     signal->theData[0] = tuserpointer;
  448.     if (tuserpointer != 0) {
  449.       sendSignal(tuserblockref, GSN_NDB_TAMPER, signal, 1, JBB);
  450.     } else {
  451.       sendSignal(QMGR_REF, GSN_NDB_TAMPER, signal, 1, JBB);
  452.       sendSignal(NDBCNTR_REF, GSN_NDB_TAMPER, signal, 1, JBB);
  453.       sendSignal(NDBFS_REF, GSN_NDB_TAMPER, signal, 1, JBB);
  454.       sendSignal(DBACC_REF, GSN_NDB_TAMPER, signal, 1, JBB);
  455.       sendSignal(DBTUP_REF, GSN_NDB_TAMPER, signal, 1, JBB);
  456.       sendSignal(DBLQH_REF, GSN_NDB_TAMPER, signal, 1, JBB);
  457.       sendSignal(DBDICT_REF, GSN_NDB_TAMPER, signal, 1, JBB);
  458.       sendSignal(DBDIH_REF, GSN_NDB_TAMPER, signal, 1, JBB);
  459.       sendSignal(DBTC_REF, GSN_NDB_TAMPER, signal, 1, JBB);
  460.       sendSignal(CMVMI_REF, GSN_NDB_TAMPER, signal, 1, JBB);
  461.     }//if
  462.     break;
  463. #endif
  464.   default:
  465.     ndbrequire(false);
  466.     break;
  467.   }//switch
  468.   return;
  469. }//Dbdih::execDIHNDBTAMPER()
  470. /*****************************************************************************/
  471. /* **********     FILE HANDLING MODULE                           *************/
  472. /*****************************************************************************/
  473. void Dbdih::copyGciLab(Signal* signal, CopyGCIReq::CopyReason reason) 
  474. {
  475.   if(c_copyGCIMaster.m_copyReason != CopyGCIReq::IDLE){
  476.     /**
  477.      * There can currently only be one waiting
  478.      */
  479.     ndbrequire(c_copyGCIMaster.m_waiting == CopyGCIReq::IDLE);
  480.     c_copyGCIMaster.m_waiting = reason;
  481.     return;
  482.   }
  483.   c_copyGCIMaster.m_copyReason = reason;
  484.   sendLoopMacro(COPY_GCIREQ, sendCOPY_GCIREQ);
  485. }//Dbdih::copyGciLab()
  486. /* ------------------------------------------------------------------------- */
  487. /* COPY_GCICONF                           RESPONSE TO COPY_GCIREQ            */
  488. /* ------------------------------------------------------------------------- */
  489. void Dbdih::execCOPY_GCICONF(Signal* signal) 
  490. {
  491.   jamEntry();
  492.   NodeRecordPtr senderNodePtr;
  493.   senderNodePtr.i = signal->theData[0];
  494.   receiveLoopMacro(COPY_GCIREQ, senderNodePtr.i);
  495.   CopyGCIReq::CopyReason waiting = c_copyGCIMaster.m_waiting;
  496.   CopyGCIReq::CopyReason current = c_copyGCIMaster.m_copyReason;
  497.   c_copyGCIMaster.m_copyReason = CopyGCIReq::IDLE;
  498.   c_copyGCIMaster.m_waiting = CopyGCIReq::IDLE;
  499.   bool ok = false;
  500.   switch(current){
  501.   case CopyGCIReq::RESTART:{
  502.     ok = true;
  503.     jam();
  504.     DictStartReq * req = (DictStartReq*)&signal->theData[0];
  505.     req->restartGci = SYSFILE->newestRestorableGCI;
  506.     req->senderRef = reference();
  507.     sendSignal(cdictblockref, GSN_DICTSTARTREQ,
  508.                signal, DictStartReq::SignalLength, JBB);
  509.     break;
  510.   }
  511.   case CopyGCIReq::LOCAL_CHECKPOINT:{
  512.     ok = true;
  513.     jam();
  514.     startLcpRoundLab(signal);
  515.     break;
  516.   }
  517.   case CopyGCIReq::GLOBAL_CHECKPOINT:
  518.     ok = true;
  519.     jam();
  520.     checkToCopyCompleted(signal);
  521.     /************************************************************************/
  522.     // Report the event that a global checkpoint has completed.
  523.     /************************************************************************/
  524.     signal->setTrace(0);
  525.     signal->theData[0] = EventReport::GlobalCheckpointCompleted; //Event type
  526.     signal->theData[1] = coldgcp;
  527.     sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);    
  528.     CRASH_INSERTION(7004);
  529.     emptyWaitGCPMasterQueue(signal);    
  530.     cgcpStatus = GCP_READY;
  531.     signal->theData[0] = DihContinueB::ZSTART_GCP;
  532.     signal->theData[1] = cgcpDelay;
  533.     sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 2);
  534.     if (c_nodeStartMaster.blockGcp == true) {
  535.       jam();
  536.       /* ------------------------------------------------------------------ */
  537.       /*  A NEW NODE WANTS IN AND WE MUST ALLOW IT TO COME IN NOW SINCE THE */
  538.       /*       GCP IS COMPLETED.                                            */
  539.       /* ------------------------------------------------------------------ */
  540.       gcpBlockedLab(signal);
  541.     }//if
  542.     break;
  543.   case CopyGCIReq::INITIAL_START_COMPLETED:
  544.     ok = true;
  545.     jam();
  546.     initialStartCompletedLab(signal);
  547.     break;
  548.   case CopyGCIReq::IDLE:
  549.     ok = false;
  550.     jam();
  551.   }
  552.   ndbrequire(ok);
  553.   /**
  554.    * Pop queue
  555.    */
  556.   if(waiting != CopyGCIReq::IDLE){
  557.     c_copyGCIMaster.m_copyReason = waiting;
  558.     signal->theData[0] = DihContinueB::ZCOPY_GCI;
  559.     signal->theData[1] = waiting;
  560.     sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
  561.   }
  562. }//Dbdih::execCOPY_GCICONF()
  563. void Dbdih::invalidateLcpInfoAfterSr()
  564. {
  565.   NodeRecordPtr nodePtr;
  566.   SYSFILE->latestLCP_ID--;
  567.   Sysfile::clearLCPOngoing(SYSFILE->systemRestartBits);
  568.   for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
  569.     jam();
  570.     ptrAss(nodePtr, nodeRecord);
  571.     if (!NdbNodeBitmask::get(SYSFILE->lcpActive, nodePtr.i)){
  572.       jam();
  573.       /* ------------------------------------------------------------------- */
  574.       // The node was not active in the local checkpoint. 
  575.       // To avoid that we step the active status too fast to not 
  576.       // active we step back one step from Sysfile::NS_ActiveMissed_x.
  577.       /* ------------------------------------------------------------------- */
  578.       switch (nodePtr.p->activeStatus) {
  579.       case Sysfile::NS_Active:
  580. /* ----------------------------------------------------------------- */
  581. // When not active in ongoing LCP and still active is a contradiction.
  582. /* ----------------------------------------------------------------- */
  583.         ndbrequire(false);
  584.       case Sysfile::NS_ActiveMissed_1:
  585.         jam();
  586.         nodePtr.p->activeStatus = Sysfile::NS_Active;
  587.         break;
  588.       case Sysfile::NS_ActiveMissed_2:
  589.         jam();
  590.         nodePtr.p->activeStatus = Sysfile::NS_ActiveMissed_1;
  591.         break;
  592.       default:
  593.         jam();
  594.         break;
  595.       }//switch
  596.     }//if
  597.   }//for
  598.   setNodeRestartInfoBits();
  599. }//Dbdih::invalidateLcpInfoAfterSr()
  600. /* ------------------------------------------------------------------------- */
  601. /*       THE NEXT STEP IS TO WRITE THE FILE.                                 */
  602. /* ------------------------------------------------------------------------- */
  603. void Dbdih::openingCopyGciSkipInitLab(Signal* signal, FileRecordPtr filePtr) 
  604. {
  605.   writeRestorableGci(signal, filePtr);
  606.   filePtr.p->reqStatus = FileRecord::WRITING_COPY_GCI;
  607.   return;
  608. }//Dbdih::openingCopyGciSkipInitLab()
  609. void Dbdih::writingCopyGciLab(Signal* signal, FileRecordPtr filePtr) 
  610. {
  611.   /* ----------------------------------------------------------------------- */
  612.   /*     WE HAVE NOW WRITTEN THIS FILE. WRITE ALSO NEXT FILE IF THIS IS NOT  */
  613.   /*     ALREADY THE LAST.                                                   */
  614.   /* ----------------------------------------------------------------------- */
  615.   filePtr.p->reqStatus = FileRecord::IDLE;
  616.   if (filePtr.i == crestartInfoFile[0]) {
  617.     jam();
  618.     filePtr.i = crestartInfoFile[1];
  619.     ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
  620.     if (filePtr.p->fileStatus == FileRecord::OPEN) {
  621.       jam();
  622.       openingCopyGciSkipInitLab(signal, filePtr);
  623.       return;
  624.     }//if
  625.     openFileRw(signal, filePtr);
  626.     filePtr.p->reqStatus = FileRecord::OPENING_COPY_GCI;
  627.     return;
  628.   }//if
  629.   /* ----------------------------------------------------------------------- */
  630.   /*     WE HAVE COMPLETED WRITING BOTH FILES SUCCESSFULLY. NOW REPORT OUR   */
  631.   /*     SUCCESS TO THE MASTER DIH. BUT FIRST WE NEED TO RESET A NUMBER OF   */
  632.   /*     VARIABLES USED BY THE LOCAL CHECKPOINT PROCESS (ONLY IF TRIGGERED   */
  633.   /*     BY LOCAL CHECKPOINT PROCESS.                                        */
  634.   /* ----------------------------------------------------------------------- */
  635.   CopyGCIReq::CopyReason reason = c_copyGCISlave.m_copyReason;
  636.   
  637.   if (reason == CopyGCIReq::GLOBAL_CHECKPOINT) {
  638.     jam();
  639.     cgcpParticipantState = GCP_PARTICIPANT_READY;
  640.     
  641.     SubGcpCompleteRep * const rep = (SubGcpCompleteRep*)signal->getDataPtr();
  642.     rep->gci = coldgcp;
  643.     rep->senderData = 0;
  644.     sendSignal(SUMA_REF, GSN_SUB_GCP_COMPLETE_REP, signal, 
  645.        SubGcpCompleteRep::SignalLength, JBB);
  646.   }
  647.   
  648.   jam();
  649.   c_copyGCISlave.m_copyReason = CopyGCIReq::IDLE;
  650.   
  651.   if(c_copyGCISlave.m_senderRef == cmasterdihref){
  652.     jam();
  653.     /**
  654.      * Only if same master
  655.      */
  656.     signal->theData[0] = c_copyGCISlave.m_senderData;
  657.     sendSignal(c_copyGCISlave.m_senderRef, GSN_COPY_GCICONF, signal, 1, JBB);
  658.   }
  659.   return;
  660. }//Dbdih::writingCopyGciLab()
  661. void Dbdih::execSTART_LCP_REQ(Signal* signal){
  662.   StartLcpReq * req = (StartLcpReq*)signal->getDataPtr();
  663.  
  664.   CRASH_INSERTION2(7021, isMaster());
  665.   CRASH_INSERTION2(7022, !isMaster());
  666.   ndbrequire(c_lcpState.m_masterLcpDihRef = req->senderRef);
  667.   c_lcpState.m_participatingDIH = req->participatingDIH;
  668.   c_lcpState.m_participatingLQH = req->participatingLQH;
  669.   
  670.   c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH = req->participatingLQH;
  671.   if(isMaster()){
  672.     jam();
  673.     ndbrequire(isActiveMaster());
  674.     c_lcpState.m_LCP_COMPLETE_REP_Counter_DIH = req->participatingDIH;
  675.   } else {
  676.     c_lcpState.m_LCP_COMPLETE_REP_Counter_DIH.clearWaitingFor();
  677.   }
  678.   c_lcpState.m_LCP_COMPLETE_REP_From_Master_Received = false;  
  679.   c_lcpState.setLcpStatus(LCP_INIT_TABLES, __LINE__);
  680.   
  681.   signal->theData[0] = DihContinueB::ZINIT_LCP;
  682.   signal->theData[1] = c_lcpState.m_masterLcpDihRef;
  683.   signal->theData[2] = 0;
  684.   sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
  685. }
  686. void Dbdih::initLcpLab(Signal* signal, Uint32 senderRef, Uint32 tableId) 
  687. {
  688.   TabRecordPtr tabPtr;
  689.   tabPtr.i = tableId;
  690.   if(c_lcpState.m_masterLcpDihRef != senderRef){
  691.     jam();
  692.     /**
  693.      * This is LCP master takeover
  694.      */
  695. #ifdef VM_TRACE
  696.     ndbout_c("initLcpLab aborted due to LCP master takeover - 1");
  697. #endif
  698.     c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
  699.     sendMASTER_LCPCONF(signal);
  700.     return;
  701.   }
  702.   if(c_lcpState.m_masterLcpDihRef != cmasterdihref){
  703.     jam();
  704.     /**
  705.      * Master take over but has not yet received MASTER_LCPREQ
  706.      */
  707. #ifdef VM_TRACE
  708.     ndbout_c("initLcpLab aborted due to LCP master takeover - 2");    
  709. #endif
  710.     return;
  711.   }
  712.   //const Uint32 lcpId = SYSFILE->latestLCP_ID;
  713.   for(; tabPtr.i < ctabFileSize; tabPtr.i++){
  714.     ptrAss(tabPtr, tabRecord);
  715.     if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE) {
  716.       jam();
  717.       tabPtr.p->tabLcpStatus = TabRecord::TLS_COMPLETED;
  718.       continue;
  719.     }
  720.     if (tabPtr.p->storedTable == 0) {
  721.       /**
  722.        * Temporary table
  723.        */
  724.       jam();
  725.       tabPtr.p->tabLcpStatus = TabRecord::TLS_COMPLETED;
  726.       continue;
  727.     }
  728.     
  729.     if (tabPtr.p->tabCopyStatus != TabRecord::CS_IDLE) {
  730.       /* ----------------------------------------------------------------- */
  731.       // We protect the updates of table data structures by this variable.
  732.       /* ----------------------------------------------------------------- */
  733.       jam();
  734.       signal->theData[0] = DihContinueB::ZINIT_LCP;
  735.       signal->theData[1] = senderRef;
  736.       signal->theData[2] = tabPtr.i;
  737.       sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 20, 3);
  738.       return;
  739.     }//if
  740.     /**
  741.      * Found a table
  742.      */
  743.     tabPtr.p->tabLcpStatus = TabRecord::TLS_ACTIVE;
  744.     /**
  745.      * For each fragment
  746.      */
  747.     for (Uint32 fragId = 0; fragId < tabPtr.p->totalfragments; fragId++) {
  748.       jam();
  749.       FragmentstorePtr fragPtr;
  750.       getFragstore(tabPtr.p, fragId, fragPtr);
  751.       /**
  752.        * For each of replica record
  753.        */
  754.       Uint32 replicaCount = 0;
  755.       ReplicaRecordPtr replicaPtr;
  756.       for(replicaPtr.i = fragPtr.p->storedReplicas; replicaPtr.i != RNIL;
  757.   replicaPtr.i = replicaPtr.p->nextReplica) {
  758. jam();
  759. ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
  760. Uint32 nodeId = replicaPtr.p->procNode;
  761. if(c_lcpState.m_participatingLQH.get(nodeId)){
  762.   jam();
  763.   replicaCount++;
  764.   replicaPtr.p->lcpOngoingFlag = true;
  765. }
  766.       }
  767.       
  768.       fragPtr.p->noLcpReplicas = replicaCount;
  769.     }//for
  770.     
  771.     signal->theData[0] = DihContinueB::ZINIT_LCP;
  772.     signal->theData[1] = senderRef;
  773.     signal->theData[2] = tabPtr.i + 1;
  774.     sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
  775.     return;
  776.   }
  777.   /**
  778.    * No more tables
  779.    */
  780.   jam();
  781.   if (c_lcpState.m_masterLcpDihRef != reference()){
  782.     jam();
  783.     ndbrequire(!isMaster());
  784.     c_lcpState.setLcpStatus(LCP_STATUS_ACTIVE, __LINE__);
  785.   } else {
  786.     jam();
  787.     ndbrequire(isMaster());
  788.   }
  789.   CRASH_INSERTION2(7023, isMaster());
  790.   CRASH_INSERTION2(7024, !isMaster());
  791.   
  792.   jam();
  793.   StartLcpConf * conf = (StartLcpConf*)signal->getDataPtrSend();
  794.   conf->senderRef = reference();
  795.   sendSignal(c_lcpState.m_masterLcpDihRef, GSN_START_LCP_CONF, signal, 
  796.      StartLcpConf::SignalLength, JBB);
  797.   return;
  798. }//Dbdih::initLcpLab()
  799. /* ------------------------------------------------------------------------- */
  800. /*       ERROR HANDLING FOR COPY RESTORABLE GCI FILE.                        */
  801. /* ------------------------------------------------------------------------- */
  802. void Dbdih::openingCopyGciErrorLab(Signal* signal, FileRecordPtr filePtr) 
  803. {
  804.   createFileRw(signal, filePtr);
  805.   /* ------------------------------------------------------------------------- */
  806.   /*       ERROR IN OPENING FILE. WE WILL TRY BY CREATING FILE INSTEAD.        */
  807.   /* ------------------------------------------------------------------------- */
  808.   filePtr.p->reqStatus = FileRecord::CREATING_COPY_GCI;
  809.   return;
  810. }//Dbdih::openingCopyGciErrorLab()
  811. /* ------------------------------------------------------------------------- */
  812. /*       ENTER DICTSTARTCONF WITH                                            */
  813. /*         TBLOCKREF                                                         */
  814. /* ------------------------------------------------------------------------- */
  815. void Dbdih::dictStartConfLab(Signal* signal) 
  816. {
  817.   /* ----------------------------------------------------------------------- */
  818.   /*     WE HAVE NOW RECEIVED ALL THE TABLES TO RESTART.                     */
  819.   /* ----------------------------------------------------------------------- */
  820.   signal->theData[0] = DihContinueB::ZSTART_FRAGMENT;
  821.   signal->theData[1] = 0;  /* START WITH TABLE 0    */
  822.   signal->theData[2] = 0;  /* AND FRAGMENT 0        */
  823.   sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
  824.   return;
  825. }//Dbdih::dictStartConfLab()
  826. void Dbdih::openingTableLab(Signal* signal, FileRecordPtr filePtr) 
  827. {
  828.   /* ---------------------------------------------------------------------- */
  829.   /*    SUCCESSFULLY OPENED A FILE. READ THE FIRST PAGE OF THIS FILE.       */
  830.   /* ---------------------------------------------------------------------- */
  831.   TabRecordPtr tabPtr;
  832.   PageRecordPtr pagePtr;
  833.   tabPtr.i = filePtr.p->tabRef;
  834.   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  835.   tabPtr.p->noPages = 1;
  836.   allocpage(pagePtr);
  837.   tabPtr.p->pageRef[0] = pagePtr.i;
  838.   readTabfile(signal, tabPtr.p, filePtr);
  839.   filePtr.p->reqStatus = FileRecord::READING_TABLE;
  840.   return;
  841. }//Dbdih::openingTableLab()
  842. void Dbdih::openingTableErrorLab(Signal* signal, FileRecordPtr filePtr) 
  843. {
  844.   TabRecordPtr tabPtr;
  845.   tabPtr.i = filePtr.p->tabRef;
  846.   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  847.   /* ---------------------------------------------------------------------- */
  848.   /*    WE FAILED IN OPENING A FILE. IF THE FIRST FILE THEN TRY WITH THE    */
  849.   /*    DUPLICATE FILE, OTHERWISE WE REPORT AN ERROR IN THE SYSTEM RESTART. */
  850.   /* ---------------------------------------------------------------------- */
  851.   ndbrequire(filePtr.i == tabPtr.p->tabFile[0]);
  852.   filePtr.i = tabPtr.p->tabFile[1];
  853.   ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
  854.   openFileRw(signal, filePtr);
  855.   filePtr.p->reqStatus = FileRecord::OPENING_TABLE;
  856. }//Dbdih::openingTableErrorLab()
  857. void Dbdih::readingTableLab(Signal* signal, FileRecordPtr filePtr) 
  858. {
  859.   TabRecordPtr tabPtr;
  860.   PageRecordPtr pagePtr;
  861.   /* ---------------------------------------------------------------------- */
  862.   /*    WE HAVE SUCCESSFULLY READ A NUMBER OF PAGES IN THE TABLE FILE. IF   */
  863.   /*    MORE PAGES EXIST IN THE FILE THEN READ ALL PAGES IN THE FILE.       */
  864.   /* ---------------------------------------------------------------------- */
  865.   filePtr.p->reqStatus = FileRecord::IDLE;
  866.   tabPtr.i = filePtr.p->tabRef;
  867.   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  868.   pagePtr.i = tabPtr.p->pageRef[0];
  869.   ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
  870.   Uint32 noOfStoredPages = pagePtr.p->word[33];
  871.   if (tabPtr.p->noPages < noOfStoredPages) {
  872.     jam();
  873.     ndbrequire(noOfStoredPages <= 8);
  874.     for (Uint32 i = tabPtr.p->noPages; i < noOfStoredPages; i++) {
  875.       jam();
  876.       allocpage(pagePtr);
  877.       tabPtr.p->pageRef[i] = pagePtr.i;
  878.     }//for
  879.     tabPtr.p->noPages = noOfStoredPages;
  880.     readTabfile(signal, tabPtr.p, filePtr);
  881.     filePtr.p->reqStatus = FileRecord::READING_TABLE;
  882.   } else {
  883.     ndbrequire(tabPtr.p->noPages == pagePtr.p->word[33]);
  884.     ndbrequire(tabPtr.p->tabCopyStatus == TabRecord::CS_IDLE);
  885.     jam();
  886.     /* --------------------------------------------------------------------- */
  887.     /*   WE HAVE READ ALL PAGES. NOW READ FROM PAGES INTO TABLE AND FRAGMENT */
  888.     /*   DATA STRUCTURES.                                                    */
  889.     /* --------------------------------------------------------------------- */
  890.     tabPtr.p->tabCopyStatus = TabRecord::CS_SR_PHASE1_READ_PAGES;
  891.     signal->theData[0] = DihContinueB::ZREAD_PAGES_INTO_TABLE;
  892.     signal->theData[1] = tabPtr.i;
  893.     sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
  894.     return;
  895.   }//if
  896.   return;
  897. }//Dbdih::readingTableLab()
  898. void Dbdih::readTableFromPagesLab(Signal* signal, TabRecordPtr tabPtr) 
  899. {
  900.   FileRecordPtr filePtr;
  901.   filePtr.i = tabPtr.p->tabFile[0];
  902.   ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
  903.   /* ---------------------------------------------------------------------- */
  904.   /*    WE HAVE NOW COPIED TO OUR NODE. WE HAVE NOW COMPLETED RESTORING     */
  905.   /*    THIS TABLE. CONTINUE WITH THE NEXT TABLE.                           */
  906.   /*    WE ALSO NEED TO CLOSE THE TABLE FILE.                               */
  907.   /* ---------------------------------------------------------------------- */
  908.   if (filePtr.p->fileStatus != FileRecord::OPEN) {
  909.     jam();
  910.     filePtr.i = tabPtr.p->tabFile[1];
  911.     ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
  912.   }//if
  913.   closeFile(signal, filePtr);
  914.   filePtr.p->reqStatus = FileRecord::CLOSING_TABLE_SR;
  915.   return;
  916. }//Dbdih::readTableFromPagesLab()
  917. void Dbdih::closingTableSrLab(Signal* signal, FileRecordPtr filePtr) 
  918. {
  919.   /**
  920.    * Update table/fragment info
  921.    */
  922.   TabRecordPtr tabPtr;
  923.   tabPtr.i = filePtr.p->tabRef;
  924.   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  925.   resetReplicaSr(tabPtr);
  926.   signal->theData[0] = DihContinueB::ZCOPY_TABLE;
  927.   signal->theData[1] = filePtr.p->tabRef;
  928.   sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
  929.   return;
  930. }//Dbdih::closingTableSrLab()
  931. void
  932. Dbdih::resetReplicaSr(TabRecordPtr tabPtr){
  933.   const Uint32 newestRestorableGCI = SYSFILE->newestRestorableGCI;
  934.   
  935.   for(Uint32 i = 0; i<tabPtr.p->totalfragments; i++){
  936.     FragmentstorePtr fragPtr;
  937.     getFragstore(tabPtr.p, i, fragPtr);
  938.     
  939.     /**
  940.      * 1) Start by moving all replicas into oldStoredReplicas
  941.      */
  942.     prepareReplicas(fragPtr);
  943.     /**
  944.      * 2) Move all "alive" replicas into storedReplicas
  945.      *    + update noCrashedReplicas...
  946.      */
  947.     ReplicaRecordPtr replicaPtr;
  948.     replicaPtr.i = fragPtr.p->oldStoredReplicas;
  949.     while (replicaPtr.i != RNIL) {
  950.       jam();
  951.       ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
  952.       const Uint32 nextReplicaPtrI = replicaPtr.p->nextReplica;
  953.       NodeRecordPtr nodePtr;
  954.       nodePtr.i = replicaPtr.p->procNode;
  955.       ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
  956.       const Uint32 noCrashedReplicas = replicaPtr.p->noCrashedReplicas;
  957.       if (nodePtr.p->nodeStatus == NodeRecord::ALIVE) {
  958. jam();
  959. switch (nodePtr.p->activeStatus) {
  960. case Sysfile::NS_Active:
  961. case Sysfile::NS_ActiveMissed_1:
  962. case Sysfile::NS_ActiveMissed_2:{
  963.   jam();
  964.   /* --------------------------------------------------------------- */
  965.   /* THE NODE IS ALIVE AND KICKING AND ACTIVE, LET'S USE IT.         */
  966.   /* --------------------------------------------------------------- */
  967.   arrGuard(noCrashedReplicas, 8);
  968.   Uint32 lastGci = replicaPtr.p->replicaLastGci[noCrashedReplicas];
  969.   if(lastGci >= newestRestorableGCI){
  970.     jam();
  971.     /** -------------------------------------------------------------
  972.      * THE REPLICA WAS ALIVE AT THE SYSTEM FAILURE. WE WILL SET THE 
  973.      * LAST REPLICA GCI TO MINUS ONE SINCE IT HASN'T FAILED YET IN THE
  974.      * NEW SYSTEM.                                                    
  975.      *-------------------------------------------------------------- */
  976.     replicaPtr.p->replicaLastGci[noCrashedReplicas] = (Uint32)-1;
  977.   } else {
  978.     jam();
  979.     /*--------------------------------------------------------------
  980.      * SINCE IT WAS NOT ALIVE AT THE TIME OF THE SYSTEM CRASH THIS IS 
  981.      * A COMPLETELY NEW REPLICA. WE WILL SET THE CREATE GCI TO BE THE 
  982.      * NEXT GCI TO BE EXECUTED.                                       
  983.      *--------_----------------------------------------------------- */
  984.     const Uint32 nextCrashed = noCrashedReplicas + 1;
  985.     replicaPtr.p->noCrashedReplicas = nextCrashed;
  986.     arrGuard(nextCrashed, 8);
  987.     replicaPtr.p->createGci[nextCrashed] = newestRestorableGCI + 1;
  988.     ndbrequire(newestRestorableGCI + 1 != 0xF1F1F1F1);
  989.     replicaPtr.p->replicaLastGci[nextCrashed] = (Uint32)-1;
  990.   }//if
  991.   resetReplicaLcp(replicaPtr.p, newestRestorableGCI);
  992.   /* -----------------------------------------------------------------
  993.    *   LINK THE REPLICA INTO THE STORED REPLICA LIST. WE WILL USE THIS
  994.    *   NODE AS A STORED REPLICA.                                      
  995.    *   WE MUST FIRST LINK IT OUT OF THE LIST OF OLD STORED REPLICAS.  
  996.    * --------------------------------------------------------------- */
  997.   removeOldStoredReplica(fragPtr, replicaPtr);
  998.   linkStoredReplica(fragPtr, replicaPtr);
  999. }
  1000.         default:
  1001.   jam();
  1002.   /*empty*/;
  1003.   break;
  1004. }
  1005.       }
  1006.       replicaPtr.i = nextReplicaPtrI;
  1007.     }//while
  1008.   }
  1009. }
  1010. void
  1011. Dbdih::resetReplicaLcp(ReplicaRecord * replicaP, Uint32 stopGci){
  1012.   Uint32 lcpNo = replicaP->nextLcp;
  1013.   const Uint32 startLcpNo = lcpNo;
  1014.   do {
  1015.     lcpNo = prevLcpNo(lcpNo);
  1016.     ndbrequire(lcpNo < MAX_LCP_STORED);
  1017.     if (replicaP->lcpStatus[lcpNo] == ZVALID) {
  1018.       if (replicaP->maxGciStarted[lcpNo] < stopGci) {
  1019.         jam();
  1020. /* ----------------------------------------------------------------- */
  1021. /*   WE HAVE FOUND A USEFUL LOCAL CHECKPOINT THAT CAN BE USED FOR    */
  1022. /*   RESTARTING THIS FRAGMENT REPLICA.                               */
  1023. /* ----------------------------------------------------------------- */
  1024.         return ;
  1025.       }//if
  1026.     }//if
  1027.     
  1028.     /**
  1029.      * WE COULD  NOT USE THIS LOCAL CHECKPOINT. IT WAS TOO
  1030.      * RECENT OR SIMPLY NOT A VALID CHECKPOINT.
  1031.      * WE SHOULD THUS REMOVE THIS LOCAL CHECKPOINT SINCE IT WILL NEVER
  1032.      * AGAIN BE USED. SET LCP_STATUS TO INVALID.
  1033.      */
  1034.     replicaP->nextLcp = lcpNo;
  1035.     replicaP->lcpId[lcpNo] = 0;
  1036.     replicaP->lcpStatus[lcpNo] = ZINVALID;
  1037.   } while (lcpNo != startLcpNo);
  1038.   
  1039.   replicaP->nextLcp = 0;
  1040. }
  1041. void Dbdih::readingTableErrorLab(Signal* signal, FileRecordPtr filePtr) 
  1042. {
  1043.   TabRecordPtr tabPtr;
  1044.   tabPtr.i = filePtr.p->tabRef;
  1045.   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  1046.   /* ---------------------------------------------------------------------- */
  1047.   /*    READING THIS FILE FAILED. CLOSE IT AFTER RELEASING ALL PAGES.       */
  1048.   /* ---------------------------------------------------------------------- */
  1049.   ndbrequire(tabPtr.p->noPages <= 8);
  1050.   for (Uint32 i = 0; i < tabPtr.p->noPages; i++) {
  1051.     jam();
  1052.     releasePage(tabPtr.p->pageRef[i]);
  1053.   }//for
  1054.   closeFile(signal, filePtr);
  1055.   filePtr.p->reqStatus = FileRecord::CLOSING_TABLE_CRASH;
  1056.   return;
  1057. }//Dbdih::readingTableErrorLab()
  1058. void Dbdih::closingTableCrashLab(Signal* signal, FileRecordPtr filePtr) 
  1059. {
  1060.   TabRecordPtr tabPtr;
  1061.   /* ---------------------------------------------------------------------- */
  1062.   /*    WE HAVE NOW CLOSED A FILE WHICH WE HAD A READ ERROR WITH. PROCEED   */
  1063.   /*    WITH NEXT FILE IF NOT THE LAST OTHERWISE REPORT ERROR.              */
  1064.   /* ---------------------------------------------------------------------- */
  1065.   tabPtr.i = filePtr.p->tabRef;
  1066.   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  1067.   ndbrequire(filePtr.i == tabPtr.p->tabFile[0]);
  1068.   filePtr.i = tabPtr.p->tabFile[1];
  1069.   ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
  1070.   openFileRw(signal, filePtr);
  1071.   filePtr.p->reqStatus = FileRecord::OPENING_TABLE;
  1072. }//Dbdih::closingTableCrashLab()
  1073. /*****************************************************************************/
  1074. /* **********     COPY TABLE MODULE                              *************/
  1075. /*****************************************************************************/
  1076. void Dbdih::execCOPY_TABREQ(Signal* signal) 
  1077. {
  1078.   CRASH_INSERTION(7172);
  1079.   TabRecordPtr tabPtr;
  1080.   PageRecordPtr pagePtr;
  1081.   jamEntry();
  1082.   BlockReference ref = signal->theData[0];
  1083.   Uint32 reqinfo = signal->theData[1];
  1084.   tabPtr.i = signal->theData[2];
  1085.   Uint32 schemaVersion = signal->theData[3];
  1086.   Uint32 noOfWords = signal->theData[4];
  1087.   ndbrequire(ref == cmasterdihref);
  1088.   ndbrequire(!isMaster());
  1089.   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  1090.   if (reqinfo == 1) {
  1091.     jam();
  1092.     tabPtr.p->schemaVersion = schemaVersion;
  1093.     initTableFile(tabPtr);
  1094.   }//if
  1095.   ndbrequire(tabPtr.p->noPages < 8);
  1096.   if (tabPtr.p->noOfWords == 0) {
  1097.     jam();
  1098.     allocpage(pagePtr);
  1099.     tabPtr.p->pageRef[tabPtr.p->noPages] = pagePtr.i;
  1100.     tabPtr.p->noPages++;
  1101.   } else {
  1102.     jam();
  1103.     pagePtr.i = tabPtr.p->pageRef[tabPtr.p->noPages - 1];
  1104.     ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
  1105.   }//if
  1106.   ndbrequire(tabPtr.p->noOfWords + 15 < 2048);
  1107.   ndbrequire(tabPtr.p->noOfWords < 2048);
  1108.   MEMCOPY_NO_WORDS(&pagePtr.p->word[tabPtr.p->noOfWords], &signal->theData[5], 16);
  1109.   tabPtr.p->noOfWords += 16;
  1110.   if (tabPtr.p->noOfWords == 2048) {
  1111.     jam();
  1112.     tabPtr.p->noOfWords = 0;
  1113.   }//if
  1114.   if (noOfWords > 16) {
  1115.     jam();
  1116.     return;
  1117.   }//if
  1118.   tabPtr.p->noOfWords = 0;
  1119.   ndbrequire(tabPtr.p->tabCopyStatus == TabRecord::CS_IDLE);
  1120.   tabPtr.p->tabCopyStatus = TabRecord::CS_COPY_TAB_REQ;
  1121.   signal->theData[0] = DihContinueB::ZREAD_PAGES_INTO_TABLE;
  1122.   signal->theData[1] = tabPtr.i;
  1123.   sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
  1124. }//Dbdih::execCOPY_TABREQ()
  1125. void
  1126. Dbdih::copyTabReq_complete(Signal* signal, TabRecordPtr tabPtr){
  1127.   if (!isMaster()) {
  1128.     jam();
  1129.     //----------------------------------------------------------------------------
  1130.     // In this particular case we do not release table pages if we are master. The
  1131.     // reason is that the master could still be sending the table info to another
  1132.     // node.
  1133.     //----------------------------------------------------------------------------
  1134.     releaseTabPages(tabPtr.i);
  1135.     tabPtr.p->tabStatus = TabRecord::TS_ACTIVE;
  1136.     for (Uint32 fragId = 0; fragId < tabPtr.p->totalfragments; fragId++) {
  1137.       jam();
  1138.       FragmentstorePtr fragPtr;
  1139.       getFragstore(tabPtr.p, fragId, fragPtr);
  1140.       updateNodeInfo(fragPtr);
  1141.     }//for
  1142.   }//if
  1143.   signal->theData[0] = cownNodeId;
  1144.   signal->theData[1] = tabPtr.i;
  1145.   sendSignal(cmasterdihref, GSN_COPY_TABCONF, signal, 2, JBB);
  1146. }
  1147. /*****************************************************************************/
  1148. /* ******  READ FROM A NUMBER OF PAGES INTO THE TABLE DATA STRUCTURES ********/
  1149. /*****************************************************************************/
  1150. void Dbdih::readPagesIntoTableLab(Signal* signal, Uint32 tableId) 
  1151. {
  1152.   RWFragment rf;
  1153.   rf.wordIndex = 35;
  1154.   rf.pageIndex = 0;
  1155.   rf.rwfTabPtr.i = tableId;
  1156.   ptrCheckGuard(rf.rwfTabPtr, ctabFileSize, tabRecord);
  1157.   rf.rwfPageptr.i = rf.rwfTabPtr.p->pageRef[0];
  1158.   ptrCheckGuard(rf.rwfPageptr, cpageFileSize, pageRecord);
  1159.   rf.rwfTabPtr.p->totalfragments = readPageWord(&rf);
  1160.   rf.rwfTabPtr.p->noOfBackups = readPageWord(&rf);
  1161.   rf.rwfTabPtr.p->hashpointer = readPageWord(&rf);
  1162.   rf.rwfTabPtr.p->kvalue = readPageWord(&rf);
  1163.   rf.rwfTabPtr.p->mask = readPageWord(&rf);
  1164.   ndbrequire(readPageWord(&rf) == TabRecord::HASH);
  1165.   rf.rwfTabPtr.p->method = TabRecord::HASH;
  1166.   /* ---------------------------------- */
  1167.   /* Type of table, 2 = temporary table */
  1168.   /* ---------------------------------- */
  1169.   rf.rwfTabPtr.p->storedTable = readPageWord(&rf); 
  1170.   Uint32 noOfFrags = rf.rwfTabPtr.p->totalfragments;
  1171.   ndbrequire(noOfFrags > 0);
  1172.   ndbrequire((noOfFrags * (rf.rwfTabPtr.p->noOfBackups + 1)) <= cnoFreeReplicaRec);
  1173.   allocFragments(noOfFrags, rf.rwfTabPtr);
  1174.   
  1175.   signal->theData[0] = DihContinueB::ZREAD_PAGES_INTO_FRAG;
  1176.   signal->theData[1] = rf.rwfTabPtr.i;
  1177.   signal->theData[2] = 0;
  1178.   signal->theData[3] = rf.pageIndex;
  1179.   signal->theData[4] = rf.wordIndex;
  1180.   sendSignal(reference(), GSN_CONTINUEB, signal, 5, JBB);
  1181.   return;
  1182. }//Dbdih::readPagesIntoTableLab()
  1183. void Dbdih::readPagesIntoFragLab(Signal* signal, RWFragment* rf) 
  1184. {
  1185.   ndbrequire(rf->pageIndex < 8);
  1186.   rf->rwfPageptr.i = rf->rwfTabPtr.p->pageRef[rf->pageIndex];
  1187.   ptrCheckGuard(rf->rwfPageptr, cpageFileSize, pageRecord);
  1188.   FragmentstorePtr fragPtr;
  1189.   getFragstore(rf->rwfTabPtr.p, rf->fragId, fragPtr);
  1190.   readFragment(rf, fragPtr);
  1191.   readReplicas(rf, fragPtr);
  1192.   rf->fragId++;
  1193.   if (rf->fragId == rf->rwfTabPtr.p->totalfragments) {
  1194.     jam();
  1195.     switch (rf->rwfTabPtr.p->tabCopyStatus) {
  1196.     case TabRecord::CS_SR_PHASE1_READ_PAGES:
  1197.       jam();
  1198.       releaseTabPages(rf->rwfTabPtr.i);
  1199.       rf->rwfTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
  1200.       signal->theData[0] = DihContinueB::ZREAD_TABLE_FROM_PAGES;
  1201.       signal->theData[1] = rf->rwfTabPtr.i;
  1202.       sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
  1203.       return;
  1204.       break;
  1205.     case TabRecord::CS_COPY_TAB_REQ:
  1206.       jam();
  1207.       rf->rwfTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
  1208.       if(getNodeState().getSystemRestartInProgress()){
  1209. jam();
  1210. copyTabReq_complete(signal, rf->rwfTabPtr);
  1211. return;
  1212.       }
  1213.       rf->rwfTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
  1214.       rf->rwfTabPtr.p->tabUpdateState = TabRecord::US_COPY_TAB_REQ;
  1215.       signal->theData[0] = DihContinueB::ZTABLE_UPDATE;
  1216.       signal->theData[1] = rf->rwfTabPtr.i;
  1217.       sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
  1218.       return;
  1219.       break;
  1220.     default:
  1221.       ndbrequire(false);
  1222.       return;
  1223.       break;
  1224.     }//switch
  1225.   } else {
  1226.     jam();
  1227.     signal->theData[0] = DihContinueB::ZREAD_PAGES_INTO_FRAG;
  1228.     signal->theData[1] = rf->rwfTabPtr.i;
  1229.     signal->theData[2] = rf->fragId;
  1230.     signal->theData[3] = rf->pageIndex;
  1231.     signal->theData[4] = rf->wordIndex;
  1232.     sendSignal(reference(), GSN_CONTINUEB, signal, 5, JBB);
  1233.   }//if
  1234.   return;
  1235. }//Dbdih::readPagesIntoFragLab()
  1236. /*****************************************************************************/
  1237. /*****   WRITING FROM TABLE DATA STRUCTURES INTO A SET OF PAGES         ******/
  1238. // execCONTINUEB(ZPACK_TABLE_INTO_PAGES)
  1239. /*****************************************************************************/
  1240. void Dbdih::packTableIntoPagesLab(Signal* signal, Uint32 tableId) 
  1241. {
  1242.   RWFragment wf;
  1243.   TabRecordPtr tabPtr;
  1244.   allocpage(wf.rwfPageptr);
  1245.   tabPtr.i = tableId;
  1246.   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  1247.   tabPtr.p->pageRef[0] = wf.rwfPageptr.i;
  1248.   tabPtr.p->noPages = 1;
  1249.   wf.wordIndex = 35;
  1250.   wf.pageIndex = 0;
  1251.   writePageWord(&wf, tabPtr.p->totalfragments);
  1252.   writePageWord(&wf, tabPtr.p->noOfBackups);
  1253.   writePageWord(&wf, tabPtr.p->hashpointer);
  1254.   writePageWord(&wf, tabPtr.p->kvalue);
  1255.   writePageWord(&wf, tabPtr.p->mask);
  1256.   writePageWord(&wf, TabRecord::HASH);
  1257.   writePageWord(&wf, tabPtr.p->storedTable);
  1258.   signal->theData[0] = DihContinueB::ZPACK_FRAG_INTO_PAGES;
  1259.   signal->theData[1] = tabPtr.i;
  1260.   signal->theData[2] = 0;
  1261.   signal->theData[3] = wf.pageIndex;
  1262.   signal->theData[4] = wf.wordIndex;
  1263.   sendSignal(reference(), GSN_CONTINUEB, signal, 5, JBB);
  1264. }//Dbdih::packTableIntoPagesLab()
  1265. /*****************************************************************************/
  1266. // execCONTINUEB(ZPACK_FRAG_INTO_PAGES)
  1267. /*****************************************************************************/
  1268. void Dbdih::packFragIntoPagesLab(Signal* signal, RWFragment* wf) 
  1269. {
  1270.   ndbrequire(wf->pageIndex < 8);
  1271.   wf->rwfPageptr.i = wf->rwfTabPtr.p->pageRef[wf->pageIndex];
  1272.   ptrCheckGuard(wf->rwfPageptr, cpageFileSize, pageRecord);
  1273.   FragmentstorePtr fragPtr;
  1274.   getFragstore(wf->rwfTabPtr.p, wf->fragId, fragPtr);
  1275.   writeFragment(wf, fragPtr);
  1276.   writeReplicas(wf, fragPtr.p->storedReplicas);
  1277.   writeReplicas(wf, fragPtr.p->oldStoredReplicas);
  1278.   wf->fragId++;
  1279.   if (wf->fragId == wf->rwfTabPtr.p->totalfragments) {
  1280.     jam();
  1281.     PageRecordPtr pagePtr;
  1282.     pagePtr.i = wf->rwfTabPtr.p->pageRef[0];
  1283.     ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
  1284.     pagePtr.p->word[33] = wf->rwfTabPtr.p->noPages;
  1285.     pagePtr.p->word[34] = ((wf->rwfTabPtr.p->noPages - 1) * 2048) + wf->wordIndex;
  1286.     switch (wf->rwfTabPtr.p->tabCopyStatus) {
  1287.     case TabRecord::CS_SR_PHASE2_READ_TABLE:
  1288.       /* -------------------------------------------------------------------*/
  1289.       // We are performing a system restart and we are now ready to copy the
  1290.       // table from this node (the master) to all other nodes.
  1291.       /* -------------------------------------------------------------------*/
  1292.       jam();
  1293.       wf->rwfTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
  1294.       signal->theData[0] = DihContinueB::ZSR_PHASE2_READ_TABLE;
  1295.       signal->theData[1] = wf->rwfTabPtr.i;
  1296.       sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
  1297.       return;
  1298.       break;
  1299.     case TabRecord::CS_COPY_NODE_STATE:
  1300.       jam();
  1301.       tableCopyNodeLab(signal, wf->rwfTabPtr);
  1302.       return;
  1303.       break;
  1304.     case TabRecord::CS_LCP_READ_TABLE:
  1305.       jam();
  1306.       signal->theData[0] = DihContinueB::ZTABLE_UPDATE;
  1307.       signal->theData[1] = wf->rwfTabPtr.i;
  1308.       sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
  1309.       return;
  1310.       break;
  1311.     case TabRecord::CS_REMOVE_NODE:
  1312.     case TabRecord::CS_INVALIDATE_NODE_LCP:
  1313.       jam();
  1314.       signal->theData[0] = DihContinueB::ZTABLE_UPDATE;
  1315.       signal->theData[1] = wf->rwfTabPtr.i;
  1316.       sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
  1317.       return;
  1318.       break;
  1319.     case TabRecord::CS_ADD_TABLE_MASTER:
  1320.       jam();
  1321.       wf->rwfTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
  1322.       signal->theData[0] = DihContinueB::ZADD_TABLE_MASTER_PAGES;
  1323.       signal->theData[1] = wf->rwfTabPtr.i;
  1324.       sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
  1325.       return;
  1326.       break;
  1327.     case TabRecord::CS_ADD_TABLE_SLAVE:
  1328.       jam();
  1329.       wf->rwfTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
  1330.       signal->theData[0] = DihContinueB::ZADD_TABLE_SLAVE_PAGES;
  1331.       signal->theData[1] = wf->rwfTabPtr.i;
  1332.       sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
  1333.       return;
  1334.       break;
  1335.     default:
  1336.       ndbrequire(false);
  1337.       return;
  1338.       break;
  1339.     }//switch
  1340.   } else {
  1341.     jam();
  1342.     signal->theData[0] = DihContinueB::ZPACK_FRAG_INTO_PAGES;
  1343.     signal->theData[1] = wf->rwfTabPtr.i;
  1344.     signal->theData[2] = wf->fragId;
  1345.     signal->theData[3] = wf->pageIndex;
  1346.     signal->theData[4] = wf->wordIndex;
  1347.     sendSignal(reference(), GSN_CONTINUEB, signal, 5, JBB);
  1348.   }//if
  1349.   return;
  1350. }//Dbdih::packFragIntoPagesLab()
  1351. /*****************************************************************************/
  1352. /* **********     START FRAGMENT MODULE                          *************/
  1353. /*****************************************************************************/
  1354. void Dbdih::startFragment(Signal* signal, Uint32 tableId, Uint32 fragId) 
  1355. {
  1356.   Uint32 TloopCount = 0;
  1357.   TabRecordPtr tabPtr;
  1358.   while (true) {
  1359.     if (TloopCount > 100) {
  1360.       jam();
  1361.       signal->theData[0] = DihContinueB::ZSTART_FRAGMENT;
  1362.       signal->theData[1] = tableId;
  1363.       signal->theData[2] = 0;
  1364.       sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
  1365.       return;
  1366.     }
  1367.     
  1368.     if (tableId >= ctabFileSize) {
  1369.       jam();
  1370.       signal->theData[0] = DihContinueB::ZCOMPLETE_RESTART;
  1371.       sendSignal(reference(), GSN_CONTINUEB, signal, 1, JBB);
  1372.       return;
  1373.     }//if
  1374.     
  1375.     tabPtr.i = tableId;
  1376.     ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  1377.     if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE){
  1378.       jam();
  1379.       TloopCount++;
  1380.       tableId++;
  1381.       fragId = 0;
  1382.       continue;
  1383.     }
  1384.     
  1385.     if(tabPtr.p->storedTable == 0){
  1386.       jam();
  1387.       TloopCount++;
  1388.       tableId++;
  1389.       fragId = 0;
  1390.       continue;
  1391.     }
  1392.     
  1393.     jam();
  1394.     break;
  1395.   }//while
  1396.   
  1397.   FragmentstorePtr fragPtr;
  1398.   getFragstore(tabPtr.p, fragId, fragPtr);
  1399.   /* ----------------------------------------------------------------------- */
  1400.   /*     WE NEED TO RESET THE REPLICA DATA STRUCTURES. THIS MEANS THAT WE    */
  1401.   /*     MUST REMOVE REPLICAS THAT WAS NOT STARTED AT THE GCI TO RESTORE. WE */
  1402.   /*     NEED TO PUT ALL STORED REPLICAS ON THE LIST OF OLD STORED REPLICAS  */
  1403.   /*     RESET THE NUMBER OF REPLICAS TO CREATE.                             */
  1404.   /* ----------------------------------------------------------------------- */
  1405.   cnoOfCreateReplicas = 0;
  1406.   /* ----------------------------------------------------------------------- */
  1407.   /*     WE WILL NEVER START MORE THAN FOUR FRAGMENT REPLICAS WHATEVER THE   */
  1408.   /*     DESIRED REPLICATION IS.                                             */
  1409.   /* ----------------------------------------------------------------------- */
  1410.   ndbrequire(tabPtr.p->noOfBackups < 4);
  1411.   /* ----------------------------------------------------------------------- */
  1412.   /*     SEARCH FOR STORED REPLICAS THAT CAN BE USED TO RESTART THE SYSTEM.  */
  1413.   /* ----------------------------------------------------------------------- */
  1414.   searchStoredReplicas(fragPtr);
  1415.   if (cnoOfCreateReplicas == 0) {
  1416.     /* --------------------------------------------------------------------- */
  1417.     /*   THERE WERE NO STORED REPLICAS AVAILABLE THAT CAN SERVE AS REPLICA TO*/
  1418.     /*   RESTART THE SYSTEM FROM. IN A LATER RELEASE WE WILL ADD             */
  1419.     /*   FUNCTIONALITY TO CHECK IF THERE ARE ANY STANDBY NODES THAT COULD DO */
  1420.     /*   THIS TASK INSTEAD IN THIS IMPLEMENTATION WE SIMPLY CRASH THE SYSTEM.*/
  1421.     /*   THIS WILL DECREASE THE GCI TO RESTORE WHICH HOPEFULLY WILL MAKE IT  */
  1422.     /*   POSSIBLE TO RESTORE THE SYSTEM.                                     */
  1423.     /* --------------------------------------------------------------------- */
  1424.     char buf[100];
  1425.     BaseString::snprintf(buf, sizeof(buf), 
  1426.      "Unable to find restorable replica for "
  1427.      "table: %d fragment: %d gci: %d",
  1428.      tableId, fragId, SYSFILE->newestRestorableGCI);
  1429.     progError(__LINE__, 
  1430.       ERR_SYSTEM_ERROR,
  1431.       buf);
  1432.     ndbrequire(false);
  1433.     return;
  1434.   }//if
  1435.   
  1436.   /* ----------------------------------------------------------------------- */
  1437.   /*     WE HAVE CHANGED THE NODE TO BE PRIMARY REPLICA AND THE NODES TO BE  */
  1438.   /*     BACKUP NODES. WE MUST UPDATE THIS NODES DATA STRUCTURE SINCE WE     */
  1439.   /*     WILL NOT COPY THE TABLE DATA TO OURSELF.                            */
  1440.   /* ----------------------------------------------------------------------- */
  1441.   updateNodeInfo(fragPtr);
  1442.   /* ----------------------------------------------------------------------- */
  1443.   /*     NOW WE HAVE COLLECTED ALL THE REPLICAS WE COULD GET. WE WILL NOW    */
  1444.   /*     RESTART THE FRAGMENT REPLICAS WE HAVE FOUND IRRESPECTIVE OF IF THERE*/
  1445.   /*     ARE ENOUGH ACCORDING TO THE DESIRED REPLICATION.                    */
  1446.   /* ----------------------------------------------------------------------- */
  1447.   /*     WE START BY SENDING ADD_FRAGREQ FOR THOSE REPLICAS THAT NEED IT.    */
  1448.   /* ----------------------------------------------------------------------- */
  1449.   CreateReplicaRecordPtr createReplicaPtr;
  1450.   for (createReplicaPtr.i = 0; 
  1451.        createReplicaPtr.i < cnoOfCreateReplicas; 
  1452.        createReplicaPtr.i++) {
  1453.     jam();
  1454.     ptrCheckGuard(createReplicaPtr, 4, createReplicaRecord);
  1455.     createReplicaPtr.p->hotSpareUse = false;
  1456.   }//for
  1457.   sendStartFragreq(signal, tabPtr, fragId);
  1458.   /**
  1459.    * Don't wait for START_FRAGCONF
  1460.    */
  1461.   fragId++;
  1462.   if (fragId >= tabPtr.p->totalfragments) {
  1463.     jam();
  1464.     tabPtr.i++;
  1465.     fragId = 0;
  1466.   }//if
  1467.   signal->theData[0] = DihContinueB::ZSTART_FRAGMENT;
  1468.   signal->theData[1] = tabPtr.i;
  1469.   signal->theData[2] = fragId;
  1470.   sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
  1471.   
  1472.   return;
  1473. }//Dbdih::startFragmentLab()
  1474. /*****************************************************************************/
  1475. /* **********     COMPLETE RESTART MODULE                        *************/
  1476. /*****************************************************************************/
  1477. void Dbdih::completeRestartLab(Signal* signal) 
  1478. {
  1479.   sendLoopMacro(START_RECREQ, sendSTART_RECREQ);
  1480. }//completeRestartLab()
  1481. /* ------------------------------------------------------------------------- */
  1482. //       SYSTEM RESTART:
  1483. /*         A NODE HAS COMPLETED RESTORING ALL DATABASE FRAGMENTS.            */
  1484. //       NODE RESTART:
  1485. //         THE STARTING NODE HAS PREPARED ITS LOG FILES TO ENABLE EXECUTION
  1486. //         OF TRANSACTIONS.
  1487. // Precondition:
  1488. //   This signal must be received by the master node.
  1489. /* ------------------------------------------------------------------------- */
  1490. void Dbdih::execSTART_RECCONF(Signal* signal) 
  1491. {
  1492.   jamEntry();
  1493.   Uint32 senderNodeId = signal->theData[0];
  1494.   ndbrequire(isMaster());
  1495.   if (getNodeState().startLevel >= NodeState::SL_STARTED){
  1496.     /* --------------------------------------------------------------------- */
  1497.     // Since our node is already up and running this must be a node restart.
  1498.     // This means that we should be the master node, 
  1499.     // otherwise we have a problem.
  1500.     /* --------------------------------------------------------------------- */
  1501.     jam();
  1502.     ndbrequire(senderNodeId == c_nodeStartMaster.startNode);
  1503.     nodeRestartStartRecConfLab(signal);
  1504.     return;
  1505.   } else {
  1506.     /* --------------------------------------------------------------------- */
  1507.     // This was the system restart case. We set the state indicating that the
  1508.     // node has completed restoration of all fragments.
  1509.     /* --------------------------------------------------------------------- */
  1510.     receiveLoopMacro(START_RECREQ, senderNodeId);
  1511.     signal->theData[0] = reference();
  1512.     sendSignal(cntrlblockref, GSN_NDB_STARTCONF, signal, 1, JBB);
  1513.     return;
  1514.   }//if
  1515. }//Dbdih::execSTART_RECCONF()
  1516. void Dbdih::copyNodeLab(Signal* signal, Uint32 tableId) 
  1517. {
  1518.   /* ----------------------------------------------------------------------- */
  1519.   // This code is executed by the master to assist a node restart in receiving
  1520.   // the data in the master.
  1521.   /* ----------------------------------------------------------------------- */
  1522.   Uint32 TloopCount = 0;
  1523.   if (!c_nodeStartMaster.activeState) {
  1524.     jam();
  1525.     /* --------------------------------------------------------------------- */
  1526.     // Obviously the node crashed in the middle of its node restart. We will 
  1527.     // stop this process simply by returning after resetting the wait indicator.
  1528.     /* ---------------------------------------------------------------------- */
  1529.     c_nodeStartMaster.wait = ZFALSE;
  1530.     return;
  1531.   }//if
  1532.   TabRecordPtr tabPtr;
  1533.   tabPtr.i = tableId;
  1534.   while (tabPtr.i < ctabFileSize) {
  1535.     ptrAss(tabPtr, tabRecord);
  1536.     if (tabPtr.p->tabStatus == TabRecord::TS_ACTIVE) {
  1537.       /* -------------------------------------------------------------------- */
  1538.       // The table is defined. We will start by packing the table into pages.
  1539.       // The tabCopyStatus indicates to the CONTINUEB(ZPACK_TABLE_INTO_PAGES)
  1540.       // who called it. After packing the table into page(s) it will be sent to 
  1541.       // the starting node by COPY_TABREQ signals. After returning from the 
  1542.       // starting node we will return to this subroutine and continue 
  1543.       // with the next table.
  1544.       /* -------------------------------------------------------------------- */
  1545.       ndbrequire(tabPtr.p->tabCopyStatus == TabRecord::CS_IDLE);
  1546.       tabPtr.p->tabCopyStatus = TabRecord::CS_COPY_NODE_STATE;
  1547.       signal->theData[0] = DihContinueB::ZPACK_TABLE_INTO_PAGES;
  1548.       signal->theData[1] = tabPtr.i;
  1549.       sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
  1550.       return;
  1551.     } else {
  1552.       jam();
  1553.       if (TloopCount > 100) {
  1554. /* ------------------------------------------------------------------ */
  1555. // Introduce real-time break after looping through 100 not copied tables
  1556. /* ----------------------------------------------------------------- */
  1557.         jam();
  1558.         signal->theData[0] = DihContinueB::ZCOPY_NODE;
  1559.         signal->theData[1] = tabPtr.i + 1;
  1560.         sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
  1561.         return;
  1562.       } else {
  1563.         jam();
  1564.         TloopCount++;
  1565.         tabPtr.i++;
  1566.       }//if
  1567.     }//if
  1568.   }//while
  1569.   dihCopyCompletedLab(signal);
  1570.   return;
  1571. }//Dbdih::copyNodeLab()
  1572. void Dbdih::tableCopyNodeLab(Signal* signal, TabRecordPtr tabPtr) 
  1573. {
  1574.   /* ----------------------------------------------------------------------- */
  1575.   /*       COPY PAGES READ TO STARTING NODE.                                 */
  1576.   /* ----------------------------------------------------------------------- */
  1577.   if (!c_nodeStartMaster.activeState) {
  1578.     jam();
  1579.     releaseTabPages(tabPtr.i);
  1580.     c_nodeStartMaster.wait = ZFALSE;
  1581.     return;
  1582.   }//if
  1583.   NodeRecordPtr copyNodePtr;
  1584.   PageRecordPtr pagePtr;
  1585.   copyNodePtr.i = c_nodeStartMaster.startNode;
  1586.   ptrCheckGuard(copyNodePtr, MAX_NDB_NODES, nodeRecord);
  1587.   copyNodePtr.p->activeTabptr = tabPtr.i;
  1588.   pagePtr.i = tabPtr.p->pageRef[0];
  1589.   ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
  1590.   signal->theData[0] = DihContinueB::ZCOPY_TABLE_NODE;
  1591.   signal->theData[1] = tabPtr.i;
  1592.   signal->theData[2] = copyNodePtr.i;
  1593.   signal->theData[3] = 0;
  1594.   signal->theData[4] = 0;
  1595.   signal->theData[5] = pagePtr.p->word[34];
  1596.   sendSignal(reference(), GSN_CONTINUEB, signal, 6, JBB);
  1597. }//Dbdih::tableCopyNodeLab()
  1598. /* ------------------------------------------------------------------------- */
  1599. // execCONTINUEB(ZCOPY_TABLE)
  1600. // This routine is used to copy the table descriptions from the master to
  1601. // other nodes. It is used in the system restart to copy from master to all
  1602. // starting nodes.
  1603. /* ------------------------------------------------------------------------- */
  1604. void Dbdih::copyTableLab(Signal* signal, Uint32 tableId) 
  1605. {
  1606.   TabRecordPtr tabPtr;
  1607.   tabPtr.i = tableId;
  1608.   ptrAss(tabPtr, tabRecord);
  1609.   ndbrequire(tabPtr.p->tabCopyStatus == TabRecord::CS_IDLE);
  1610.   tabPtr.p->tabCopyStatus = TabRecord::CS_SR_PHASE2_READ_TABLE;
  1611.   signal->theData[0] = DihContinueB::ZPACK_TABLE_INTO_PAGES;
  1612.   signal->theData[1] = tabPtr.i;
  1613.   sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
  1614.   return;
  1615. }//Dbdih::copyTableLab()
  1616. /* ------------------------------------------------------------------------- */
  1617. // execCONTINUEB(ZSR_PHASE2_READ_TABLE)
  1618. /* ------------------------------------------------------------------------- */
  1619. void Dbdih::srPhase2ReadTableLab(Signal* signal, TabRecordPtr tabPtr) 
  1620. {
  1621.   /* ----------------------------------------------------------------------- */
  1622.   // We set the sendCOPY_TABREQState to ZACTIVE for all nodes since it is a long
  1623.   // process to send off all table descriptions. Thus we ensure that we do
  1624.   // not encounter race conditions where one node is completed before the
  1625.   // sending process is completed. This could lead to that we start off the
  1626.   // system before we actually finished all copying of table descriptions
  1627.   // and could lead to strange errors.
  1628.   /* ----------------------------------------------------------------------- */
  1629.   //sendLoopMacro(COPY_TABREQ, nullRoutine);
  1630.   breakCopyTableLab(signal, tabPtr, cfirstAliveNode);
  1631.   return;
  1632. }//Dbdih::srPhase2ReadTableLab()
  1633. /* ------------------------------------------------------------------------- */
  1634. /*       COPY PAGES READ TO ALL NODES.                                       */
  1635. /* ------------------------------------------------------------------------- */
  1636. void Dbdih::breakCopyTableLab(Signal* signal, TabRecordPtr tabPtr, Uint32 nodeId) 
  1637. {
  1638.   NodeRecordPtr nodePtr;
  1639.   nodePtr.i = nodeId;
  1640.   while (nodePtr.i != RNIL) {
  1641.     jam();
  1642.     ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
  1643.     if (nodePtr.i == getOwnNodeId()){
  1644.       jam();
  1645.       /* ------------------------------------------------------------------- */
  1646.       /* NOT NECESSARY TO COPY TO MY OWN NODE. I ALREADY HAVE THE PAGES.     */
  1647.       /* I DO HOWEVER NEED TO STORE THE TABLE DESCRIPTION ONTO DISK.         */
  1648.       /* ------------------------------------------------------------------- */
  1649.       /* IF WE ARE MASTER WE ONLY NEED TO SAVE THE TABLE ON DISK. WE ALREADY */
  1650.       /* HAVE THE TABLE DESCRIPTION IN THE DATA STRUCTURES.                  */
  1651.       // AFTER COMPLETING THE WRITE TO DISK THE MASTER WILL ALSO SEND
  1652.       // COPY_TABCONF AS ALL THE OTHER NODES.
  1653.       /* ------------------------------------------------------------------- */
  1654.       c_COPY_TABREQ_Counter.setWaitingFor(nodePtr.i);
  1655.       tabPtr.p->tabUpdateState = TabRecord::US_COPY_TAB_REQ;
  1656.       signal->theData[0] = DihContinueB::ZTABLE_UPDATE;
  1657.       signal->theData[1] = tabPtr.i;
  1658.       sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
  1659.       nodePtr.i = nodePtr.p->nextNode;
  1660.     } else {
  1661.       PageRecordPtr pagePtr;
  1662.       /* -------------------------------------------------------------------- */
  1663.       // RATHER THAN SENDING ALL COPY_TABREQ IN PARALLEL WE WILL SERIALISE THIS
  1664.       // ACTIVITY AND WILL THUS CALL breakCopyTableLab AGAIN WHEN COMPLETED THE
  1665.       // SENDING OF COPY_TABREQ'S.
  1666.       /* -------------------------------------------------------------------- */
  1667.       jam();
  1668.       tabPtr.p->tabCopyStatus = TabRecord::CS_SR_PHASE3_COPY_TABLE;
  1669.       pagePtr.i = tabPtr.p->pageRef[0];
  1670.       ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
  1671.       signal->theData[0] = DihContinueB::ZCOPY_TABLE_NODE;
  1672.       signal->theData[1] = tabPtr.i;
  1673.       signal->theData[2] = nodePtr.i;
  1674.       signal->theData[3] = 0;
  1675.       signal->theData[4] = 0;
  1676.       signal->theData[5] = pagePtr.p->word[34];
  1677.       sendSignal(reference(), GSN_CONTINUEB, signal, 6, JBB);
  1678.       return;
  1679.     }//if
  1680.   }//while
  1681.   /* ----------------------------------------------------------------------- */
  1682.   /*    WE HAVE NOW SENT THE TABLE PAGES TO ALL NODES. EXIT AND WAIT FOR ALL */
  1683.   /*    REPLIES.                                                             */
  1684.   /* ----------------------------------------------------------------------- */
  1685.   return;
  1686. }//Dbdih::breakCopyTableLab()
  1687. /* ------------------------------------------------------------------------- */
  1688. // execCONTINUEB(ZCOPY_TABLE_NODE)
  1689. /* ------------------------------------------------------------------------- */
  1690. void Dbdih::copyTableNode(Signal* signal, 
  1691.   CopyTableNode* ctn, NodeRecordPtr nodePtr) 
  1692. {
  1693.   if (getNodeState().startLevel >= NodeState::SL_STARTED){
  1694.     /* --------------------------------------------------------------------- */
  1695.     // We are in the process of performing a node restart and are copying a
  1696.     // table description to a starting node. We will check that no nodes have
  1697.     // crashed in this process.
  1698.     /* --------------------------------------------------------------------- */
  1699.     if (!c_nodeStartMaster.activeState) {
  1700.       jam();
  1701.       /** ------------------------------------------------------------------
  1702.        * The starting node crashed. We will release table pages and stop this
  1703.        * copy process and allow new node restarts to start.
  1704.        * ------------------------------------------------------------------ */
  1705.       releaseTabPages(ctn->ctnTabPtr.i);
  1706.       c_nodeStartMaster.wait = ZFALSE;
  1707.       return;
  1708.     }//if
  1709.   }//if
  1710.   ndbrequire(ctn->pageIndex < 8);
  1711.   ctn->ctnPageptr.i = ctn->ctnTabPtr.p->pageRef[ctn->pageIndex];
  1712.   ptrCheckGuard(ctn->ctnPageptr, cpageFileSize, pageRecord);
  1713.   /**
  1714.    * If first page & firstWord reqinfo = 1 (first signal)
  1715.    */
  1716.   Uint32 reqinfo = (ctn->pageIndex == 0) && (ctn->wordIndex == 0);
  1717.   if(reqinfo == 1){
  1718.     c_COPY_TABREQ_Counter.setWaitingFor(nodePtr.i);
  1719.   }
  1720.   
  1721.   for (Uint32 i = 0; i < 16; i++) {
  1722.     jam();
  1723.     sendCopyTable(signal, ctn, calcDihBlockRef(nodePtr.i), reqinfo);
  1724.     reqinfo = 0;
  1725.     if (ctn->noOfWords <= 16) {
  1726.       jam();
  1727.       switch (ctn->ctnTabPtr.p->tabCopyStatus) {
  1728.       case TabRecord::CS_SR_PHASE3_COPY_TABLE:
  1729. /* ------------------------------------------------------------------ */
  1730. // We have copied the table description to this node. 
  1731. // We will now proceed
  1732. // with sending the table description to the next node in the node list.
  1733. /* ------------------------------------------------------------------ */
  1734.         jam();
  1735.         ctn->ctnTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
  1736.         breakCopyTableLab(signal, ctn->ctnTabPtr, nodePtr.p->nextNode);
  1737.         return;
  1738.         break;
  1739.       case TabRecord::CS_COPY_NODE_STATE:
  1740.         jam();
  1741.         ctn->ctnTabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
  1742.         return;
  1743.         break;
  1744.       default:
  1745.         ndbrequire(false);
  1746.         break;
  1747.       }//switch
  1748.     } else {
  1749.       jam();
  1750.       ctn->wordIndex += 16;
  1751.       if (ctn->wordIndex == 2048) {
  1752.         jam();
  1753.         ctn->wordIndex = 0;
  1754.         ctn->pageIndex++;
  1755.         ndbrequire(ctn->pageIndex < 8);
  1756.         ctn->ctnPageptr.i = ctn->ctnTabPtr.p->pageRef[ctn->pageIndex];
  1757.         ptrCheckGuard(ctn->ctnPageptr, cpageFileSize, pageRecord);
  1758.       }//if
  1759.       ctn->noOfWords -= 16;
  1760.     }//if
  1761.   }//for
  1762.   signal->theData[0] = DihContinueB::ZCOPY_TABLE_NODE;
  1763.   signal->theData[1] = ctn->ctnTabPtr.i;
  1764.   signal->theData[2] = nodePtr.i;
  1765.   signal->theData[3] = ctn->pageIndex;
  1766.   signal->theData[4] = ctn->wordIndex;
  1767.   signal->theData[5] = ctn->noOfWords;
  1768.   sendSignal(reference(), GSN_CONTINUEB, signal, 6, JBB);
  1769. }//Dbdih::copyTableNodeLab()
  1770. void Dbdih::sendCopyTable(Signal* signal, CopyTableNode* ctn,
  1771.                           BlockReference ref, Uint32 reqinfo) 
  1772. {
  1773.   signal->theData[0] = reference();
  1774.   signal->theData[1] = reqinfo;
  1775.   signal->theData[2] = ctn->ctnTabPtr.i;
  1776.   signal->theData[3] = ctn->ctnTabPtr.p->schemaVersion;
  1777.   signal->theData[4] = ctn->noOfWords;
  1778.   ndbrequire(ctn->wordIndex + 15 < 2048);
  1779.   MEMCOPY_NO_WORDS(&signal->theData[5], &ctn->ctnPageptr.p->word[ctn->wordIndex], 16);
  1780.   sendSignal(ref, GSN_COPY_TABREQ, signal, 21, JBB);
  1781. }//Dbdih::sendCopyTable()
  1782. void Dbdih::execCOPY_TABCONF(Signal* signal) 
  1783. {
  1784.   NodeRecordPtr nodePtr;
  1785.   jamEntry();
  1786.   nodePtr.i = signal->theData[0];
  1787.   Uint32 tableId = signal->theData[1];
  1788.   if (getNodeState().startLevel >= NodeState::SL_STARTED){
  1789.     /* --------------------------------------------------------------------- */
  1790.     // We are in the process of performing a node restart. Continue by copying
  1791.     // the next table to the starting node.
  1792.     /* --------------------------------------------------------------------- */
  1793.     jam();
  1794.     NodeRecordPtr nodePtr;
  1795.     nodePtr.i = signal->theData[0];
  1796.     ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
  1797.     c_COPY_TABREQ_Counter.clearWaitingFor(nodePtr.i);
  1798.     releaseTabPages(tableId);
  1799.     signal->theData[0] = DihContinueB::ZCOPY_NODE;
  1800.     signal->theData[1] = tableId + 1;
  1801.     sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
  1802.     return;
  1803.   } else {
  1804.     /* --------------------------------------------------------------------- */
  1805.     // We are in the process of performing a system restart. Check if all nodes
  1806.     // have saved the new table description to file and then continue with the
  1807.     // next table.
  1808.     /* --------------------------------------------------------------------- */
  1809.     receiveLoopMacro(COPY_TABREQ, nodePtr.i);
  1810.     /* --------------------------------------------------------------------- */
  1811.     /*   WE HAVE NOW COPIED TO ALL NODES. WE HAVE NOW COMPLETED RESTORING    */
  1812.     /*   THIS TABLE. CONTINUE WITH THE NEXT TABLE.                           */
  1813.     /*   WE NEED TO RELEASE THE PAGES IN THE TABLE IN THIS NODE HERE.        */
  1814.     /*   WE ALSO NEED TO CLOSE THE TABLE FILE.                               */
  1815.     /* --------------------------------------------------------------------- */
  1816.     releaseTabPages(tableId);
  1817.     TabRecordPtr tabPtr;
  1818.     tabPtr.i = tableId;
  1819.     ptrCheckGuard(tabPtr, ctabFileSize, tabRecord); 
  1820.     ConnectRecordPtr connectPtr;
  1821.     connectPtr.i = tabPtr.p->connectrec;
  1822.     ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord); 
  1823.     
  1824.     sendAddFragreq(signal, connectPtr, tabPtr, 0);
  1825.     return;
  1826.   }//if
  1827. }//Dbdih::execCOPY_TABCONF()
  1828. /*
  1829.   3.13   L O C A L   C H E C K P O I N T  (M A S T E R)
  1830.   ****************************************************
  1831.   */
  1832. /*****************************************************************************/
  1833. /* **********     LOCAL-CHECK-POINT-HANDLING MODULE              *************/
  1834. /*****************************************************************************/
  1835. /* ------------------------------------------------------------------------- */
  1836. /*       IT IS TIME TO CHECK IF IT IS TIME TO START A LOCAL CHECKPOINT.      */
  1837. /*       WE WILL EITHER START AFTER 1 MILLION WORDS HAVE ARRIVED OR WE WILL  */
  1838. /*       EXECUTE AFTER ABOUT 16 MINUTES HAVE PASSED BY.                      */
  1839. /* ------------------------------------------------------------------------- */
  1840. void Dbdih::checkTcCounterLab(Signal* signal) 
  1841. {
  1842.   CRASH_INSERTION(7009);
  1843.   if (c_lcpState.lcpStatus != LCP_STATUS_IDLE) {
  1844.     ndbout << "lcpStatus = " << (Uint32) c_lcpState.lcpStatus;
  1845.     ndbout << "lcpStatusUpdatedPlace = " << 
  1846.       c_lcpState.lcpStatusUpdatedPlace << endl;
  1847.     ndbrequire(false);
  1848.     return;
  1849.   }//if
  1850.   c_lcpState.ctimer += 32;
  1851.   if ((c_nodeStartMaster.blockLcp == true) ||
  1852.       ((c_lcpState.lcpStartGcp + 1) > currentgcp)) {
  1853.     jam();
  1854.     /* --------------------------------------------------------------------- */
  1855.     // No reason to start juggling the states and checking for start of LCP if
  1856.     // we are blocked to start an LCP anyway.
  1857.     // We also block LCP start if we have not completed one global checkpoints
  1858.     // before starting another local checkpoint.
  1859.     /* --------------------------------------------------------------------- */
  1860.     signal->theData[0] = DihContinueB::ZCHECK_TC_COUNTER;
  1861.     signal->theData[1] = __LINE__;
  1862.     sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 1 * 100, 2);
  1863.     return;
  1864.   }//if 
  1865.   c_lcpState.setLcpStatus(LCP_TCGET, __LINE__);
  1866.   
  1867.   c_lcpState.ctcCounter = c_lcpState.ctimer;
  1868.   sendLoopMacro(TCGETOPSIZEREQ, sendTCGETOPSIZEREQ);
  1869. }//Dbdih::checkTcCounterLab()
  1870. void Dbdih::checkLcpStart(Signal* signal, Uint32 lineNo)
  1871. {
  1872.   /* ----------------------------------------------------------------------- */
  1873.   // Verify that we are not attempting to start another instance of the LCP
  1874.   // when it is not alright to do so.
  1875.   /* ----------------------------------------------------------------------- */
  1876.   ndbrequire(c_lcpState.lcpStart == ZIDLE);
  1877.   c_lcpState.lcpStart = ZACTIVE;
  1878.   signal->theData[0] = DihContinueB::ZCHECK_TC_COUNTER;
  1879.   signal->theData[1] = lineNo;
  1880.   sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 1000, 2);
  1881. }//Dbdih::checkLcpStart()
  1882. /* ------------------------------------------------------------------------- */
  1883. /*TCGETOPSIZECONF          HOW MUCH OPERATION SIZE HAVE BEEN EXECUTED BY TC  */
  1884. /* ------------------------------------------------------------------------- */
  1885. void Dbdih::execTCGETOPSIZECONF(Signal* signal) 
  1886. {
  1887.   jamEntry();
  1888.   Uint32 senderNodeId = signal->theData[0];
  1889.   c_lcpState.ctcCounter += signal->theData[1];
  1890.   
  1891.   receiveLoopMacro(TCGETOPSIZEREQ, senderNodeId);
  1892.   ndbrequire(c_lcpState.lcpStatus == LCP_TCGET);
  1893.   ndbrequire(c_lcpState.lcpStart == ZACTIVE);
  1894.   /* ----------------------------------------------------------------------- */
  1895.   // We are not actively starting another LCP, still we receive this signal.
  1896.   // This is not ok.
  1897.   /* ---------------------------------------------------------------------- */
  1898.   /*    ALL TC'S HAVE RESPONDED NOW. NOW WE WILL CHECK IF ENOUGH OPERATIONS */
  1899.   /*    HAVE EXECUTED TO ENABLE US TO START A NEW LOCAL CHECKPOINT.         */
  1900.   /*    WHILE COPYING DICTIONARY AND DISTRIBUTION INFO TO A STARTING NODE   */
  1901.   /*    WE WILL ALSO NOT ALLOW THE LOCAL CHECKPOINT TO PROCEED.             */
  1902.   /*----------------------------------------------------------------------- */
  1903.   if (c_lcpState.immediateLcpStart == false) {
  1904.     if ((c_lcpState.ctcCounter < 
  1905.  ((Uint32)1 << c_lcpState.clcpDelay)) ||
  1906.         (c_nodeStartMaster.blockLcp == true)) {
  1907.       jam();
  1908.       c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
  1909.       signal->theData[0] = DihContinueB::ZCHECK_TC_COUNTER;
  1910.       signal->theData[1] = __LINE__;
  1911.       sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 1 * 100, 2);
  1912.       return;
  1913.     }//if
  1914.   }//if
  1915.   c_lcpState.lcpStart = ZIDLE;
  1916.   c_lcpState.immediateLcpStart = false;
  1917.   /* ----------------------------------------------------------------------- 
  1918.    * Now the initial lcp is started, 
  1919.    * we can reset the delay to its orginal value
  1920.    * --------------------------------------------------------------------- */
  1921.   CRASH_INSERTION(7010);
  1922.   /* ----------------------------------------------------------------------- */
  1923.   /*     IF MORE THAN 1 MILLION WORDS PASSED THROUGH THE TC'S THEN WE WILL   */
  1924.   /*     START A NEW LOCAL CHECKPOINT. CLEAR CTIMER. START CHECKPOINT        */
  1925.   /*     ACTIVITY BY CALCULATING THE KEEP GLOBAL CHECKPOINT.                 */
  1926.   // Also remember the current global checkpoint to ensure that we run at least
  1927.   // one global checkpoints between each local checkpoint that we start up.
  1928.   /* ----------------------------------------------------------------------- */
  1929.   c_lcpState.ctimer = 0;
  1930.   c_lcpState.keepGci = coldgcp;
  1931.   c_lcpState.lcpStartGcp = currentgcp;
  1932.   /* ----------------------------------------------------------------------- */
  1933.   /*       UPDATE THE NEW LATEST LOCAL CHECKPOINT ID.                        */
  1934.   /* ----------------------------------------------------------------------- */
  1935.   cnoOfActiveTables = 0;
  1936.   c_lcpState.setLcpStatus(LCP_CALCULATE_KEEP_GCI, __LINE__);
  1937.   c_lcpState.oldestRestorableGci = SYSFILE->oldestRestorableGCI;
  1938.   ndbrequire(((int)c_lcpState.oldestRestorableGci) > 0);
  1939.   if (ERROR_INSERTED(7011)) {
  1940.     signal->theData[0] = EventReport::LCPStoppedInCalcKeepGci;
  1941.     signal->theData[1] = 0;
  1942.     sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
  1943.     return;
  1944.   }//if
  1945.   signal->theData[0] = DihContinueB::ZCALCULATE_KEEP_GCI;
  1946.   signal->theData[1] = 0;  /* TABLE ID = 0          */
  1947.   signal->theData[2] = 0;  /* FRAGMENT ID = 0       */
  1948.   sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
  1949.   return;
  1950. }//Dbdih::execTCGETOPSIZECONF()
  1951. /* ------------------------------------------------------------------------- */
  1952. /*       WE NEED TO CALCULATE THE OLDEST GLOBAL CHECKPOINT THAT WILL BE      */
  1953. /*       COMPLETELY RESTORABLE AFTER EXECUTING THIS LOCAL CHECKPOINT.        */
  1954. /* ------------------------------------------------------------------------- */
  1955. void Dbdih::calculateKeepGciLab(Signal* signal, Uint32 tableId, Uint32 fragId) 
  1956. {
  1957.   TabRecordPtr tabPtr;
  1958.   Uint32 TloopCount = 1;
  1959.   tabPtr.i = tableId;
  1960.   do {
  1961.     if (tabPtr.i >= ctabFileSize) {
  1962.       if (cnoOfActiveTables > 0) {
  1963.         jam();
  1964.         signal->theData[0] = DihContinueB::ZSTORE_NEW_LCP_ID;
  1965.         sendSignal(reference(), GSN_CONTINUEB, signal, 1, JBB);
  1966.         return;
  1967.       } else {
  1968.         jam();
  1969. /* ------------------------------------------------------------------ */
  1970. /* THERE ARE NO TABLES TO CHECKPOINT. WE STOP THE CHECKPOINT ALREADY  */
  1971. /* HERE TO AVOID STRANGE PROBLEMS LATER.                              */
  1972. /* ------------------------------------------------------------------ */
  1973.         c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
  1974.         checkLcpStart(signal, __LINE__);
  1975.         return;
  1976.       }//if
  1977.     }//if
  1978.     ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  1979.     if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE || 
  1980. tabPtr.p->storedTable == 0) {
  1981.       if (TloopCount > 100) {
  1982.         jam();
  1983.         signal->theData[0] = DihContinueB::ZCALCULATE_KEEP_GCI;
  1984.         signal->theData[1] = tabPtr.i + 1;
  1985.         signal->theData[2] = 0;
  1986.         sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
  1987.         return;
  1988.       } else {
  1989.         jam();
  1990.         TloopCount++;
  1991.         tabPtr.i++;
  1992.       }//if
  1993.     } else {
  1994.       jam();
  1995.       TloopCount = 0;
  1996.     }//if
  1997.   } while (TloopCount != 0);
  1998.   cnoOfActiveTables++;
  1999.   FragmentstorePtr fragPtr;
  2000.   getFragstore(tabPtr.p, fragId, fragPtr);
  2001.   checkKeepGci(fragPtr.p->storedReplicas);
  2002.   fragId++;
  2003.   if (fragId >= tabPtr.p->totalfragments) {
  2004.     jam();
  2005.     tabPtr.i++;
  2006.     fragId = 0;
  2007.   }//if
  2008.   signal->theData[0] = DihContinueB::ZCALCULATE_KEEP_GCI;
  2009.   signal->theData[1] = tabPtr.i;
  2010.   signal->theData[2] = fragId;
  2011.   sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
  2012.   return;
  2013. }//Dbdih::calculateKeepGciLab()
  2014. /* ------------------------------------------------------------------------- */
  2015. /*       WE NEED TO STORE ON DISK THE FACT THAT WE ARE STARTING THIS LOCAL   */
  2016. /*       CHECKPOINT ROUND. THIS WILL INVALIDATE ALL THE LOCAL CHECKPOINTS    */
  2017. /*       THAT WILL EVENTUALLY BE OVERWRITTEN AS PART OF THIS LOCAL CHECKPOINT*/
  2018. /* ------------------------------------------------------------------------- */
  2019. void Dbdih::storeNewLcpIdLab(Signal* signal) 
  2020. {
  2021.   /***************************************************************************/
  2022.   // Report the event that a local checkpoint has started.
  2023.   /***************************************************************************/
  2024.   signal->theData[0] = EventReport::LocalCheckpointStarted; //Event type
  2025.   signal->theData[1] = SYSFILE->latestLCP_ID + 1;
  2026.   signal->theData[2] = c_lcpState.keepGci;
  2027.   signal->theData[3] = c_lcpState.oldestRestorableGci;
  2028.   sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 4, JBB);
  2029.   
  2030.   signal->setTrace(TestOrd::TraceLocalCheckpoint);
  2031.   CRASH_INSERTION(7013);
  2032.   SYSFILE->keepGCI = c_lcpState.keepGci;
  2033.   //Uint32 lcpId = SYSFILE->latestLCP_ID;
  2034.   SYSFILE->latestLCP_ID++;
  2035.   SYSFILE->oldestRestorableGCI = c_lcpState.oldestRestorableGci;
  2036.   const Uint32 oldestRestorableGCI = SYSFILE->oldestRestorableGCI;
  2037.   //const Uint32 newestRestorableGCI = SYSFILE->newestRestorableGCI;
  2038.   //ndbrequire(newestRestorableGCI >= oldestRestorableGCI);
  2039.   Int32 val = oldestRestorableGCI;
  2040.   ndbrequire(val > 0);
  2041.   
  2042.   /* ----------------------------------------------------------------------- */
  2043.   /* SET BIT INDICATING THAT LOCAL CHECKPOINT IS ONGOING. THIS IS CLEARED    */
  2044.   /* AT THE END OF A LOCAL CHECKPOINT.                                       */
  2045.   /* ----------------------------------------------------------------------- */
  2046.   SYSFILE->setLCPOngoing(SYSFILE->systemRestartBits);
  2047.   /* ---------------------------------------------------------------------- */
  2048.   /*    CHECK IF ANY NODE MUST BE TAKEN OUT OF SERVICE AND REFILLED WITH    */
  2049.   /*    NEW FRESH DATA FROM AN ACTIVE NODE.                                 */
  2050.   /* ---------------------------------------------------------------------- */
  2051.   setLcpActiveStatusStart(signal);
  2052.   c_lcpState.setLcpStatus(LCP_COPY_GCI, __LINE__);
  2053.   //#ifdef VM_TRACE
  2054.   //  infoEvent("LocalCheckpoint %d started", SYSFILE->latestLCP_ID);
  2055.   //  signal->theData[0] = 7012;
  2056.   //  execDUMP_STATE_ORD(signal);
  2057.   //#endif
  2058.   
  2059.   copyGciLab(signal, CopyGCIReq::LOCAL_CHECKPOINT);
  2060. }//Dbdih::storeNewLcpIdLab()
  2061. void Dbdih::startLcpRoundLab(Signal* signal) {
  2062.   jam();
  2063.   Mutex mutex(signal, c_mutexMgr, c_startLcpMutexHandle);
  2064.   Callback c = { safe_cast(&Dbdih::startLcpMutex_locked), 0 };
  2065.   ndbrequire(mutex.lock(c));
  2066. }
  2067. void
  2068. Dbdih::startLcpMutex_locked(Signal* signal, Uint32 senderData, Uint32 retVal){
  2069.   jamEntry();
  2070.   ndbrequire(retVal == 0);
  2071.   
  2072.   StartLcpReq* req = (StartLcpReq*)signal->getDataPtrSend();
  2073.   req->senderRef = reference();
  2074.   req->lcpId = SYSFILE->latestLCP_ID;
  2075.   req->participatingLQH = c_lcpState.m_participatingLQH;
  2076.   req->participatingDIH = c_lcpState.m_participatingDIH;
  2077.   sendLoopMacro(START_LCP_REQ, sendSTART_LCP_REQ);
  2078. }
  2079. void
  2080. Dbdih::sendSTART_LCP_REQ(Signal* signal, Uint32 nodeId){
  2081.   BlockReference ref = calcDihBlockRef(nodeId);
  2082.   sendSignal(ref, GSN_START_LCP_REQ, signal, StartLcpReq::SignalLength, JBB);
  2083. }
  2084. void
  2085. Dbdih::execSTART_LCP_CONF(Signal* signal){
  2086.   StartLcpConf * conf = (StartLcpConf*)signal->getDataPtr();
  2087.   
  2088.   Uint32 nodeId = refToNode(conf->senderRef);
  2089.   receiveLoopMacro(START_LCP_REQ, nodeId);  
  2090.   Mutex mutex(signal, c_mutexMgr, c_startLcpMutexHandle);
  2091.   Callback c = { safe_cast(&Dbdih::startLcpMutex_unlocked), 0 };
  2092.   mutex.unlock(c);
  2093. }
  2094. void
  2095. Dbdih::startLcpMutex_unlocked(Signal* signal, Uint32 data, Uint32 retVal){
  2096.   jamEntry();
  2097.   ndbrequire(retVal == 0);
  2098.   Mutex mutex(signal, c_mutexMgr, c_startLcpMutexHandle);
  2099.   mutex.release();
  2100.   
  2101.   CRASH_INSERTION(7014);
  2102.   c_lcpState.setLcpStatus(LCP_TC_CLOPSIZE, __LINE__);
  2103.   sendLoopMacro(TC_CLOPSIZEREQ, sendTC_CLOPSIZEREQ);
  2104. }
  2105. void Dbdih::execTC_CLOPSIZECONF(Signal* signal) {
  2106.   jamEntry();
  2107.   Uint32 senderNodeId = signal->theData[0];
  2108.   receiveLoopMacro(TC_CLOPSIZEREQ, senderNodeId);
  2109.   
  2110.   ndbrequire(c_lcpState.lcpStatus == LCP_TC_CLOPSIZE);
  2111.   /* ----------------------------------------------------------------------- */
  2112.   /*     ALL TC'S HAVE CLEARED THEIR OPERATION SIZE COUNTERS. NOW PROCEED BY */
  2113.   /*     STARTING THE LOCAL CHECKPOINT IN EACH LQH.                          */
  2114.   /* ----------------------------------------------------------------------- */
  2115.   c_lcpState.m_LAST_LCP_FRAG_ORD = c_lcpState.m_participatingLQH;
  2116.   CRASH_INSERTION(7015);
  2117.   c_lcpState.setLcpStatus(LCP_START_LCP_ROUND, __LINE__);
  2118.   startLcpRoundLoopLab(signal, 0, 0);
  2119. }//Dbdih::execTC_CLOPSIZECONF()
  2120. void Dbdih::startLcpRoundLoopLab(Signal* signal, 
  2121.  Uint32 startTableId, Uint32 startFragId) 
  2122. {
  2123.   NodeRecordPtr nodePtr;
  2124.   for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
  2125.     ptrAss(nodePtr, nodeRecord);
  2126.     if (nodePtr.p->nodeStatus == NodeRecord::ALIVE) {
  2127.       ndbrequire(nodePtr.p->noOfStartedChkpt == 0);
  2128.       ndbrequire(nodePtr.p->noOfQueuedChkpt == 0);
  2129.     }//if
  2130.   }//if
  2131.   c_lcpState.currentFragment.tableId = startTableId;
  2132.   c_lcpState.currentFragment.fragmentId = startFragId;
  2133.   startNextChkpt(signal);
  2134. }//Dbdih::startLcpRoundLoopLab()
  2135. void Dbdih::startNextChkpt(Signal* signal)
  2136. {
  2137.   Uint32 lcpId = SYSFILE->latestLCP_ID;
  2138.   NdbNodeBitmask busyNodes; 
  2139.   busyNodes.clear();
  2140.   const Uint32 lcpNodes = c_lcpState.m_participatingLQH.count();
  2141.   
  2142.   bool save = true;
  2143.   LcpState::CurrentFragment curr = c_lcpState.currentFragment;
  2144.   
  2145.   while (curr.tableId < ctabFileSize) {
  2146.     TabRecordPtr tabPtr;
  2147.     tabPtr.i = curr.tableId;
  2148.     ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  2149.     if ((tabPtr.p->tabStatus != TabRecord::TS_ACTIVE) ||
  2150.         (tabPtr.p->tabLcpStatus != TabRecord::TLS_ACTIVE)) {
  2151.       curr.tableId++;
  2152.       curr.fragmentId = 0;
  2153.       continue;
  2154.     }//if
  2155.     
  2156.     FragmentstorePtr fragPtr;
  2157.     getFragstore(tabPtr.p, curr.fragmentId, fragPtr);
  2158.     
  2159.     ReplicaRecordPtr replicaPtr;
  2160.     for(replicaPtr.i = fragPtr.p->storedReplicas;
  2161. replicaPtr.i != RNIL ;
  2162. replicaPtr.i = replicaPtr.p->nextReplica){
  2163.       
  2164.       jam();
  2165.       ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
  2166.       
  2167.       NodeRecordPtr nodePtr;
  2168.       nodePtr.i = replicaPtr.p->procNode;
  2169.       ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
  2170.       
  2171.       if (replicaPtr.p->lcpOngoingFlag &&
  2172.           replicaPtr.p->lcpIdStarted < lcpId) {
  2173.         jam();
  2174. //-------------------------------------------------------------------
  2175. // We have found a replica on a node that performs local checkpoint
  2176. // that is alive and that have not yet been started.
  2177. //-------------------------------------------------------------------
  2178.         if (nodePtr.p->noOfStartedChkpt < 2) {
  2179.           jam();
  2180.   /**
  2181.    * Send LCP_FRAG_ORD to LQH
  2182.    */
  2183.   
  2184.   /**
  2185.    * Mark the replica so with lcpIdStarted == true
  2186.    */
  2187.           replicaPtr.p->lcpIdStarted = lcpId;
  2188.           Uint32 i = nodePtr.p->noOfStartedChkpt;
  2189.           nodePtr.p->startedChkpt[i].tableId = tabPtr.i;
  2190.           nodePtr.p->startedChkpt[i].fragId = curr.fragmentId;
  2191.           nodePtr.p->startedChkpt[i].replicaPtr = replicaPtr.i;
  2192.           nodePtr.p->noOfStartedChkpt = i + 1;
  2193.   sendLCP_FRAG_ORD(signal, nodePtr.p->startedChkpt[i]);
  2194.         } else if (nodePtr.p->noOfQueuedChkpt < 2) {
  2195.           jam();
  2196.   /**
  2197.    * Put LCP_FRAG_ORD "in queue"
  2198.    */
  2199.   
  2200.   /**
  2201.    * Mark the replica so with lcpIdStarted == true
  2202.    */
  2203.           replicaPtr.p->lcpIdStarted = lcpId;
  2204.   
  2205.           Uint32 i = nodePtr.p->noOfQueuedChkpt;
  2206.           nodePtr.p->queuedChkpt[i].tableId = tabPtr.i;
  2207.           nodePtr.p->queuedChkpt[i].fragId = curr.fragmentId;
  2208.           nodePtr.p->queuedChkpt[i].replicaPtr = replicaPtr.i;
  2209.           nodePtr.p->noOfQueuedChkpt = i + 1;
  2210.         } else {
  2211.           jam();
  2212.   if(save){
  2213.     /**
  2214.      * Stop increasing value on first that was "full"
  2215.      */
  2216.     c_lcpState.currentFragment = curr;
  2217.     save = false;
  2218.   }
  2219.   
  2220.   busyNodes.set(nodePtr.i);
  2221.   if(busyNodes.count() == lcpNodes){
  2222.     /**
  2223.      * There were no possibility to start the local checkpoint 
  2224.      * and it was not possible to queue it up. In this case we 
  2225.      * stop the start of local checkpoints until the nodes with a 
  2226.      * backlog have performed more checkpoints. We will return and 
  2227.      * will not continue the process of starting any more checkpoints.
  2228.      */
  2229.     return;
  2230.   }//if
  2231. }//if
  2232.       }
  2233.     }//while
  2234.     curr.fragmentId++;
  2235.     if (curr.fragmentId >= tabPtr.p->totalfragments) {
  2236.       jam();
  2237.       curr.fragmentId = 0;
  2238.       curr.tableId++;
  2239.     }//if
  2240.   }//while
  2241.   
  2242.   sendLastLCP_FRAG_ORD(signal);
  2243. }//Dbdih::startNextChkpt()
  2244. void Dbdih::sendLastLCP_FRAG_ORD(Signal* signal)
  2245. {
  2246.   LcpFragOrd * const lcpFragOrd = (LcpFragOrd *)&signal->theData[0];
  2247.   lcpFragOrd->tableId = RNIL;
  2248.   lcpFragOrd->fragmentId = 0;
  2249.   lcpFragOrd->lcpId = SYSFILE->latestLCP_ID;
  2250.   lcpFragOrd->lcpNo = 0;
  2251.   lcpFragOrd->keepGci = c_lcpState.keepGci;
  2252.   lcpFragOrd->lastFragmentFlag = true;
  2253.   NodeRecordPtr nodePtr;
  2254.   for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
  2255.     jam();
  2256.     ptrAss(nodePtr, nodeRecord);
  2257.     
  2258.     if(nodePtr.p->noOfQueuedChkpt == 0 &&
  2259.        nodePtr.p->noOfStartedChkpt == 0 &&
  2260.        c_lcpState.m_LAST_LCP_FRAG_ORD.isWaitingFor(nodePtr.i)){
  2261.       jam();
  2262.       CRASH_INSERTION(7028);
  2263.       
  2264.       /**
  2265.        * Nothing queued or started <=> Complete on that node
  2266.        *
  2267.        */
  2268.       c_lcpState.m_LAST_LCP_FRAG_ORD.clearWaitingFor(nodePtr.i);
  2269.       if(ERROR_INSERTED(7075)){
  2270. continue;
  2271.       }
  2272.       BlockReference ref = calcLqhBlockRef(nodePtr.i);
  2273.       sendSignal(ref, GSN_LCP_FRAG_ORD, signal,LcpFragOrd::SignalLength, JBB);
  2274.     }
  2275.   }
  2276.   if(ERROR_INSERTED(7075)){
  2277.     if(c_lcpState.m_LAST_LCP_FRAG_ORD.done())
  2278.       CRASH_INSERTION(7075);
  2279.   }
  2280. }//Dbdih::sendLastLCP_FRAGORD()
  2281. /* ------------------------------------------------------------------------- */
  2282. /*       A FRAGMENT REPLICA HAS COMPLETED EXECUTING ITS LOCAL CHECKPOINT.    */
  2283. /*       CHECK IF ALL REPLICAS IN THE TABLE HAVE COMPLETED. IF SO STORE THE  */
  2284. /*       THE TABLE DISTRIBUTION ON DISK. ALSO SEND LCP_REPORT TO ALL OTHER   */
  2285. /*       NODES SO THAT THEY CAN STORE THE TABLE ONTO DISK AS WELL.           */
  2286. /* ------------------------------------------------------------------------- */
  2287. void Dbdih::execLCP_FRAG_REP(Signal* signal) 
  2288. {
  2289.   jamEntry();
  2290.   ndbrequire(c_lcpState.lcpStatus != LCP_STATUS_IDLE);
  2291.   
  2292. #if 0
  2293.   printLCP_FRAG_REP(stdout, 
  2294.     signal->getDataPtr(),
  2295.     signal->length(), number());
  2296. #endif  
  2297.   LcpFragRep * const lcpReport = (LcpFragRep *)&signal->theData[0];
  2298.   Uint32 nodeId = lcpReport->nodeId;
  2299.   Uint32 tableId = lcpReport->tableId;
  2300.   Uint32 fragId = lcpReport->fragId;
  2301.   
  2302.   jamEntry();
  2303.  
  2304.   CRASH_INSERTION2(7025, isMaster());
  2305.   CRASH_INSERTION2(7016, !isMaster());
  2306.   bool fromTimeQueue = (signal->senderBlockRef() == reference());
  2307.   TabRecordPtr tabPtr;
  2308.   tabPtr.i = tableId;
  2309.   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  2310.   if(tabPtr.p->tabCopyStatus != TabRecord::CS_IDLE) {
  2311.     jam();
  2312.     /*-----------------------------------------------------------------------*/
  2313.     // If the table is currently copied to disk we also 
  2314.     // stop already here to avoid strange half-way updates 
  2315.     // of the table data structures.
  2316.     /*-----------------------------------------------------------------------*/
  2317.     /*
  2318.       We need to send this signal without a delay since we have discovered
  2319.       that we have run out of space in the short time queue. This problem
  2320.       is very erunlikely to happen but it has and it results in a node crash. 
  2321.       This should be considered a "quick fix" and not a permanent solution. 
  2322.       A cleaner/better way would be to check the time queue if it is full or
  2323.       not before sending this signal.
  2324.     */
  2325.     sendSignal(reference(), GSN_LCP_FRAG_REP, signal, signal->length(), JBB);  
  2326.     /* Kept here for reference
  2327.        sendSignalWithDelay(reference(), GSN_LCP_FRAG_REP, 
  2328.        signal, 20, signal->length());
  2329.     */
  2330.     if(!fromTimeQueue){
  2331.       c_lcpState.noOfLcpFragRepOutstanding++;
  2332.     }    
  2333.     
  2334.     return;
  2335.   }//if
  2336.   
  2337.   if(fromTimeQueue){
  2338.     jam();
  2339.     
  2340.     ndbrequire(c_lcpState.noOfLcpFragRepOutstanding > 0);
  2341.     c_lcpState.noOfLcpFragRepOutstanding--;
  2342.   }
  2343.   bool tableDone = reportLcpCompletion(lcpReport);
  2344.   
  2345.   Uint32 started = lcpReport->maxGciStarted;
  2346.   Uint32 completed = lcpReport->maxGciCompleted;
  2347.   if(tableDone){
  2348.     jam();
  2349.     if(tabPtr.p->tabStatus == TabRecord::TS_DROPPING){
  2350.       jam();
  2351.       ndbout_c("TS_DROPPING - Neglecting to save Table: %d Frag: %d - ",
  2352.        tableId,
  2353.        fragId);
  2354.     } else {
  2355.       jam();
  2356.       /**
  2357.        * Write table description to file
  2358.        */
  2359.       tabPtr.p->tabLcpStatus = TabRecord::TLS_WRITING_TO_FILE;
  2360.       tabPtr.p->tabCopyStatus = TabRecord::CS_LCP_READ_TABLE;
  2361.       tabPtr.p->tabUpdateState = TabRecord::US_LOCAL_CHECKPOINT;
  2362.       signal->theData[0] = DihContinueB::ZPACK_TABLE_INTO_PAGES;
  2363.       signal->theData[1] = tabPtr.i;
  2364.       sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
  2365.       
  2366.       checkLcpAllTablesDoneInLqh();
  2367.     }
  2368.   }
  2369. #ifdef VM_TRACE
  2370.   /* --------------------------------------------------------------------- */
  2371.   // REPORT that local checkpoint have completed this fragment.
  2372.   /* --------------------------------------------------------------------- */
  2373.   signal->theData[0] = EventReport::LCPFragmentCompleted;
  2374.   signal->theData[1] = nodeId;
  2375.   signal->theData[2] = tableId;
  2376.   signal->theData[3] = fragId;
  2377.   signal->theData[4] = started;
  2378.   signal->theData[5] = completed;
  2379.   sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 6, JBB);
  2380. #endif
  2381.   
  2382.   bool ok = false;
  2383.   switch(c_lcpMasterTakeOverState.state){
  2384.   case LMTOS_IDLE:
  2385.     ok = true;
  2386.     jam();
  2387.     /**
  2388.      * Fall through
  2389.      */
  2390.     break;
  2391.   case LMTOS_WAIT_EMPTY_LCP: // LCP Take over waiting for EMPTY_LCPCONF
  2392.     jam();
  2393.     return;
  2394.   case LMTOS_WAIT_LCP_FRAG_REP:
  2395.     jam();
  2396.     checkEmptyLcpComplete(signal);
  2397.     return;
  2398.   case LMTOS_INITIAL:
  2399.   case LMTOS_ALL_IDLE:
  2400.   case LMTOS_ALL_ACTIVE:
  2401.   case LMTOS_LCP_CONCLUDING:
  2402.   case LMTOS_COPY_ONGOING:
  2403.     ndbrequire(false);
  2404.   }
  2405.   ndbrequire(ok);
  2406.   
  2407.   /* ----------------------------------------------------------------------- */
  2408.   // Check if there are more LCP's to start up.
  2409.   /* ----------------------------------------------------------------------- */
  2410.   if(isMaster()){
  2411.     jam();
  2412.     /**
  2413.      * Remove from "running" array
  2414.      */
  2415.     NodeRecordPtr nodePtr;
  2416.     nodePtr.i = nodeId;
  2417.     ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
  2418.     
  2419.     const Uint32 outstanding = nodePtr.p->noOfStartedChkpt;
  2420.     ndbrequire(outstanding > 0);
  2421.     if(nodePtr.p->startedChkpt[0].tableId != tableId ||
  2422.        nodePtr.p->startedChkpt[0].fragId != fragId){
  2423.       jam();
  2424.       ndbrequire(outstanding > 1);
  2425.       ndbrequire(nodePtr.p->startedChkpt[1].tableId == tableId);
  2426.       ndbrequire(nodePtr.p->startedChkpt[1].fragId == fragId);
  2427.     } else {
  2428.       jam();
  2429.       nodePtr.p->startedChkpt[0] = nodePtr.p->startedChkpt[1];
  2430.     }
  2431.     nodePtr.p->noOfStartedChkpt--;
  2432.     checkStartMoreLcp(signal, nodeId);
  2433.   }
  2434. }
  2435. bool
  2436. Dbdih::checkLcpAllTablesDoneInLqh(){
  2437.   TabRecordPtr tabPtr;
  2438.   /**
  2439.    * Check if finished with all tables
  2440.    */
  2441.   for (tabPtr.i = 0; tabPtr.i < ctabFileSize; tabPtr.i++) {
  2442.     jam();
  2443.     ptrAss(tabPtr, tabRecord);
  2444.     if ((tabPtr.p->tabStatus == TabRecord::TS_ACTIVE) &&
  2445.         (tabPtr.p->tabLcpStatus == TabRecord::TLS_ACTIVE)) {
  2446.       jam();
  2447.       /**
  2448.        * Nope, not finished with all tables
  2449.        */
  2450.       return false;
  2451.     }//if
  2452.   }//for
  2453.   
  2454.   CRASH_INSERTION2(7026, isMaster());
  2455.   CRASH_INSERTION2(7017, !isMaster());
  2456.   
  2457.   c_lcpState.setLcpStatus(LCP_TAB_COMPLETED, __LINE__);
  2458.   return true;
  2459. }
  2460. void Dbdih::findReplica(ReplicaRecordPtr& replicaPtr, 
  2461. Fragmentstore* fragPtrP, Uint32 nodeId)
  2462. {
  2463.   replicaPtr.i = fragPtrP->storedReplicas;
  2464.   while(replicaPtr.i != RNIL){
  2465.     ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
  2466.     if (replicaPtr.p->procNode == nodeId) {
  2467.       jam();
  2468.       return;
  2469.     } else {
  2470.       jam();
  2471.       replicaPtr.i = replicaPtr.p->nextReplica;
  2472.     }//if
  2473.   };
  2474. #ifdef VM_TRACE
  2475.   ndbout_c("Fragment Replica(node=%d) not found", nodeId);
  2476.   replicaPtr.i = fragPtrP->oldStoredReplicas;
  2477.   while(replicaPtr.i != RNIL){
  2478.     ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
  2479.     if (replicaPtr.p->procNode == nodeId) {
  2480.       jam();
  2481.       break;
  2482.     } else {
  2483.       jam();
  2484.       replicaPtr.i = replicaPtr.p->nextReplica;
  2485.     }//if
  2486.   };
  2487.   if(replicaPtr.i != RNIL){
  2488.     ndbout_c("...But was found in oldStoredReplicas");
  2489.   } else {
  2490.     ndbout_c("...And wasn't found in oldStoredReplicas");
  2491.   }
  2492. #endif
  2493.   ndbrequire(false);
  2494. }//Dbdih::findReplica()
  2495. /**
  2496.  * Return true  if table is all fragment replicas have been checkpointed
  2497.  *                 to disk (in all LQHs)
  2498.  *        false otherwise
  2499.  */
  2500. bool
  2501. Dbdih::reportLcpCompletion(const LcpFragRep* lcpReport)
  2502. {
  2503.   Uint32 lcpNo = lcpReport->lcpNo;
  2504.   Uint32 lcpId = lcpReport->lcpId;
  2505.   Uint32 maxGciStarted = lcpReport->maxGciStarted;
  2506.   Uint32 maxGciCompleted = lcpReport->maxGciCompleted;
  2507.   Uint32 tableId = lcpReport->tableId;
  2508.   Uint32 fragId = lcpReport->fragId;
  2509.   Uint32 nodeId = lcpReport->nodeId;
  2510.   TabRecordPtr tabPtr;
  2511.   tabPtr.i = tableId;
  2512.   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  2513.   
  2514.   FragmentstorePtr fragPtr;
  2515.   getFragstore(tabPtr.p, fragId, fragPtr);
  2516.   
  2517.   ReplicaRecordPtr replicaPtr;
  2518.   findReplica(replicaPtr, fragPtr.p, nodeId);
  2519.   
  2520.   ndbrequire(replicaPtr.p->lcpOngoingFlag == true);
  2521.   if(lcpNo != replicaPtr.p->nextLcp){
  2522.     ndbout_c("lcpNo = %d replicaPtr.p->nextLcp = %d", 
  2523.      lcpNo, replicaPtr.p->nextLcp);
  2524.     ndbrequire(false);
  2525.   }
  2526.   ndbrequire(lcpNo == replicaPtr.p->nextLcp);
  2527.   ndbrequire(lcpNo < MAX_LCP_STORED);
  2528.   ndbrequire(replicaPtr.p->lcpId[lcpNo] != lcpId);
  2529.   
  2530.   replicaPtr.p->lcpIdStarted = lcpId;
  2531.   replicaPtr.p->lcpOngoingFlag = false;
  2532.   
  2533.   removeOldCrashedReplicas(replicaPtr);
  2534.   replicaPtr.p->lcpId[lcpNo] = lcpId;
  2535.   replicaPtr.p->lcpStatus[lcpNo] = ZVALID;
  2536.   replicaPtr.p->maxGciStarted[lcpNo] = maxGciStarted;
  2537.   gth(maxGciStarted + 1, 0);
  2538.   replicaPtr.p->maxGciCompleted[lcpNo] = maxGciCompleted;
  2539.   replicaPtr.p->nextLcp = nextLcpNo(replicaPtr.p->nextLcp);
  2540.   ndbrequire(fragPtr.p->noLcpReplicas > 0);
  2541.   fragPtr.p->noLcpReplicas --;
  2542.   
  2543.   if(fragPtr.p->noLcpReplicas > 0){
  2544.     jam();
  2545.     return false;
  2546.   }
  2547.   
  2548.   for (Uint32 fid = 0; fid < tabPtr.p->totalfragments; fid++) {
  2549.     jam();
  2550.     getFragstore(tabPtr.p, fid, fragPtr);
  2551.     if (fragPtr.p->noLcpReplicas > 0){
  2552.       jam();
  2553.       /* ----------------------------------------------------------------- */
  2554.       // Not all fragments in table have been checkpointed.
  2555.       /* ----------------------------------------------------------------- */
  2556.       if(0)
  2557. ndbout_c("reportLcpCompletion: fragment %d not ready", fid);
  2558.       return false;
  2559.     }//if
  2560.   }//for
  2561.   return true;
  2562. }//Dbdih::reportLcpCompletion()
  2563. void Dbdih::checkStartMoreLcp(Signal* signal, Uint32 nodeId)
  2564. {
  2565.   ndbrequire(isMaster());
  2566.   NodeRecordPtr nodePtr;
  2567.   nodePtr.i = nodeId;
  2568.   ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
  2569.   
  2570.   ndbrequire(nodePtr.p->noOfStartedChkpt < 2);
  2571.   
  2572.   if (nodePtr.p->noOfQueuedChkpt > 0) {
  2573.     jam();
  2574.     nodePtr.p->noOfQueuedChkpt--;
  2575.     Uint32 i = nodePtr.p->noOfStartedChkpt;
  2576.     nodePtr.p->startedChkpt[i] = nodePtr.p->queuedChkpt[0];
  2577.     nodePtr.p->queuedChkpt[0] = nodePtr.p->queuedChkpt[1];
  2578.     //-------------------------------------------------------------------
  2579.     // We can send a LCP_FRAGORD to the node ordering it to perform a
  2580.     // local checkpoint on this fragment replica.
  2581.     //-------------------------------------------------------------------
  2582.     nodePtr.p->noOfStartedChkpt = i + 1;
  2583.     
  2584.     sendLCP_FRAG_ORD(signal, nodePtr.p->startedChkpt[i]);
  2585.   }
  2586.   /* ----------------------------------------------------------------------- */
  2587.   // When there are no more outstanding LCP reports and there are no one queued
  2588.   // in at least one node, then we are ready to make sure all nodes have at
  2589.   // least two outstanding LCP requests per node and at least two queued for
  2590.   // sending.
  2591.   /* ----------------------------------------------------------------------- */
  2592.   startNextChkpt(signal);
  2593. }//Dbdih::checkStartMoreLcp()
  2594. void
  2595. Dbdih::sendLCP_FRAG_ORD(Signal* signal, 
  2596. NodeRecord::FragmentCheckpointInfo info){ 
  2597.   
  2598.   ReplicaRecordPtr replicaPtr;
  2599.   replicaPtr.i = info.replicaPtr;
  2600.   ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
  2601.   
  2602.   BlockReference ref = calcLqhBlockRef(replicaPtr.p->procNode);
  2603.   
  2604.   LcpFragOrd * const lcpFragOrd = (LcpFragOrd *)&signal->theData[0];
  2605.   lcpFragOrd->tableId    = info.tableId;
  2606.   lcpFragOrd->fragmentId = info.fragId;
  2607.   lcpFragOrd->lcpId      = SYSFILE->latestLCP_ID;
  2608.   lcpFragOrd->lcpNo      = replicaPtr.p->nextLcp;
  2609.   lcpFragOrd->keepGci    = c_lcpState.keepGci;
  2610.   lcpFragOrd->lastFragmentFlag = false;
  2611.   sendSignal(ref, GSN_LCP_FRAG_ORD, signal, LcpFragOrd::SignalLength, JBB);
  2612. }
  2613. void Dbdih::checkLcpCompletedLab(Signal* signal) 
  2614. {
  2615.   if(c_lcpState.lcpStatus < LCP_TAB_COMPLETED){
  2616.     jam();
  2617.     return;
  2618.   }
  2619.   
  2620.   TabRecordPtr tabPtr;
  2621.   for (tabPtr.i = 0; tabPtr.i < ctabFileSize; tabPtr.i++) {
  2622.     jam();
  2623.     ptrAss(tabPtr, tabRecord);
  2624.     if (tabPtr.p->tabStatus == TabRecord::TS_ACTIVE) {
  2625.       if (tabPtr.p->tabLcpStatus != TabRecord::TLS_COMPLETED) {
  2626.         jam();
  2627.         return;
  2628.       }//if
  2629.     }//if
  2630.   }//for
  2631.   CRASH_INSERTION2(7027, isMaster());
  2632.   CRASH_INSERTION2(7018, !isMaster());
  2633.   if(c_lcpState.lcpStatus == LCP_TAB_COMPLETED){
  2634.     /**
  2635.      * We'r done
  2636.      */
  2637.     c_lcpState.setLcpStatus(LCP_TAB_SAVED, __LINE__);
  2638.     sendLCP_COMPLETE_REP(signal);
  2639.     return;
  2640.   }
  2641.   ndbrequire(c_lcpState.lcpStatus == LCP_TAB_SAVED);
  2642.   allNodesLcpCompletedLab(signal);
  2643.   return;
  2644. }//Dbdih::checkLcpCompletedLab()
  2645. void
  2646. Dbdih::sendLCP_COMPLETE_REP(Signal* signal){
  2647.   jam();
  2648.   LcpCompleteRep * rep = (LcpCompleteRep*)signal->getDataPtrSend();
  2649.   rep->nodeId = getOwnNodeId();
  2650.   rep->lcpId = SYSFILE->latestLCP_ID;
  2651.   rep->blockNo = DBDIH;
  2652.   
  2653.   sendSignal(c_lcpState.m_masterLcpDihRef, GSN_LCP_COMPLETE_REP, signal, 
  2654.      LcpCompleteRep::SignalLength, JBB);
  2655. }
  2656. /*-------------------------------------------------------------------------- */
  2657. /* COMP_LCP_ROUND                   A LQH HAS COMPLETED A LOCAL CHECKPOINT  */
  2658. /*------------------------------------------------------------------------- */
  2659. void Dbdih::execLCP_COMPLETE_REP(Signal* signal) 
  2660. {
  2661.   jamEntry();
  2662. #if 0
  2663.   ndbout_c("LCP_COMPLETE_REP"); 
  2664.   printLCP_COMPLETE_REP(stdout, 
  2665. signal->getDataPtr(),
  2666. signal->length(), number());
  2667. #endif
  2668.   LcpCompleteRep * rep = (LcpCompleteRep*)signal->getDataPtr();
  2669.   Uint32 lcpId = rep->lcpId;
  2670.   Uint32 nodeId = rep->nodeId;
  2671.   Uint32 blockNo = rep->blockNo;
  2672.   if(c_lcpMasterTakeOverState.state > LMTOS_WAIT_LCP_FRAG_REP){
  2673.     jam();
  2674.     /**
  2675.      * Don't allow LCP_COMPLETE_REP to arrive during
  2676.      * LCP master take over
  2677.      */
  2678.     ndbrequire(isMaster());
  2679.     ndbrequire(blockNo == DBDIH);
  2680.     sendSignalWithDelay(reference(), GSN_LCP_COMPLETE_REP, signal, 100, 
  2681. signal->length());
  2682.     return;
  2683.   }
  2684.   ndbrequire(c_lcpState.lcpStatus != LCP_STATUS_IDLE);
  2685.   
  2686.   switch(blockNo){
  2687.   case DBLQH:
  2688.     jam();
  2689.     c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH.clearWaitingFor(nodeId);
  2690.     ndbrequire(!c_lcpState.m_LAST_LCP_FRAG_ORD.isWaitingFor(nodeId));
  2691.     break;
  2692.   case DBDIH:
  2693.     jam();
  2694.     ndbrequire(isMaster());
  2695.     c_lcpState.m_LCP_COMPLETE_REP_Counter_DIH.clearWaitingFor(nodeId);
  2696.     break;
  2697.   case 0:
  2698.     jam();
  2699.     ndbrequire(!isMaster());
  2700.     ndbrequire(c_lcpState.m_LCP_COMPLETE_REP_From_Master_Received == false);
  2701.     c_lcpState.m_LCP_COMPLETE_REP_From_Master_Received = true;
  2702.     break;
  2703.   default:
  2704.     ndbrequire(false);
  2705.   }
  2706.   ndbrequire(lcpId == SYSFILE->latestLCP_ID);
  2707.   
  2708.   allNodesLcpCompletedLab(signal);
  2709.   return;
  2710. }
  2711. void Dbdih::allNodesLcpCompletedLab(Signal* signal)
  2712. {
  2713.   jam();
  2714.   
  2715.   if (c_lcpState.lcpStatus != LCP_TAB_SAVED) {
  2716.     jam();
  2717.     /**
  2718.      * We have not sent LCP_COMPLETE_REP to master DIH yet
  2719.      */
  2720.     return;
  2721.   }//if
  2722.   
  2723.   if (!c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH.done()){
  2724.     jam();
  2725.     return;
  2726.   }
  2727.   if (!c_lcpState.m_LCP_COMPLETE_REP_Counter_DIH.done()){
  2728.     jam();
  2729.     return;
  2730.   }
  2731.   if (!isMaster() && 
  2732.       c_lcpState.m_LCP_COMPLETE_REP_From_Master_Received == false){
  2733.     jam();
  2734.     /**
  2735.      * Wait until master DIH has signaled lcp is complete
  2736.      */
  2737.     return;
  2738.   }
  2739.   if(c_lcpMasterTakeOverState.state != LMTOS_IDLE){
  2740.     jam();
  2741. #ifdef VM_TRACE
  2742.     ndbout_c("Exiting from allNodesLcpCompletedLab");
  2743. #endif
  2744.     return;
  2745.   }
  2746.   
  2747.   /*------------------------------------------------------------------------ */
  2748.   /*     WE HAVE NOW COMPLETED A LOCAL CHECKPOINT. WE ARE NOW READY TO WAIT  */
  2749.   /*     FOR THE NEXT LOCAL CHECKPOINT. SEND WITHOUT TIME-OUT SINCE IT MIGHT */
  2750.   /*     BE TIME TO START THE NEXT LOCAL CHECKPOINT IMMEDIATELY.             */
  2751.   /*     CLEAR BIT 3 OF SYSTEM RESTART BITS TO INDICATE THAT THERE IS NO     */
  2752.   /*     LOCAL CHECKPOINT ONGOING. THIS WILL BE WRITTEN AT SOME LATER TIME   */
  2753.   /*     DURING A GLOBAL CHECKPOINT. IT IS NOT NECESSARY TO WRITE IT         */
  2754.   /*     IMMEDIATELY. WE WILL ALSO CLEAR BIT 2 OF SYSTEM RESTART BITS IF ALL */
  2755.   /*     CURRENTLY ACTIVE NODES COMPLETED THE LOCAL CHECKPOINT.              */
  2756.   /*------------------------------------------------------------------------ */
  2757.   CRASH_INSERTION(7019);
  2758.   signal->setTrace(0);
  2759.   c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
  2760.   setLcpActiveStatusEnd();
  2761.   Sysfile::clearLCPOngoing(SYSFILE->systemRestartBits);
  2762.   if(!isMaster()){
  2763.     jam();
  2764.     /**
  2765.      * We're not master, be content
  2766.      */
  2767.     return;
  2768.   }
  2769.   // Send LCP_COMPLETE_REP to all other nodes
  2770.   // allowing them to set their lcpStatus to LCP_STATUS_IDLE
  2771.   LcpCompleteRep * rep = (LcpCompleteRep*)signal->getDataPtrSend();
  2772.   rep->nodeId = getOwnNodeId();
  2773.   rep->lcpId = SYSFILE->latestLCP_ID;
  2774.   rep->blockNo = 0; // 0 = Sent from master
  2775.   
  2776.   NodeRecordPtr nodePtr;
  2777.   nodePtr.i = cfirstAliveNode;
  2778.   do {
  2779.     jam();
  2780.     ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);   
  2781.     if (nodePtr.i != cownNodeId){
  2782.       BlockReference ref = calcDihBlockRef(nodePtr.i);
  2783.       sendSignal(ref, GSN_LCP_COMPLETE_REP, signal, 
  2784.  LcpCompleteRep::SignalLength, JBB); 
  2785.     }    
  2786.     nodePtr.i = nodePtr.p->nextNode;
  2787.   } while (nodePtr.i != RNIL);        
  2788.   
  2789.   jam();
  2790.   /***************************************************************************/
  2791.   // Report the event that a local checkpoint has completed.
  2792.   /***************************************************************************/
  2793.   signal->theData[0] = EventReport::LocalCheckpointCompleted; //Event type
  2794.   signal->theData[1] = SYSFILE->latestLCP_ID;
  2795.   sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
  2796.   
  2797.   /**
  2798.    * Start checking for next LCP
  2799.    */
  2800.   checkLcpStart(signal, __LINE__);
  2801.   
  2802.   if (cwaitLcpSr == true) {
  2803.     jam();
  2804.     cwaitLcpSr = false;
  2805.     ndbsttorry10Lab(signal, __LINE__);
  2806.     return;
  2807.   }//if
  2808.   
  2809.   if (c_nodeStartMaster.blockLcp == true) {
  2810.     jam();
  2811.     lcpBlockedLab(signal);
  2812.     return;
  2813.   }//if
  2814.   return;
  2815. }//Dbdih::allNodesLcpCompletedLab()
  2816. /******************************************************************************/
  2817. /* **********     TABLE UPDATE MODULE                             *************/
  2818. /* ****************************************************************************/
  2819. /* ------------------------------------------------------------------------- */
  2820. /*       THIS MODULE IS USED TO UPDATE THE TABLE DESCRIPTION. IT STARTS BY   */
  2821. /*       CREATING THE FIRST TABLE FILE, THEN UPDATES THIS FILE AND CLOSES IT.*/
  2822. /*       AFTER THAT THE SAME HAPPENS WITH THE SECOND FILE. AFTER THAT THE    */
  2823. /*       TABLE DISTRIBUTION HAS BEEN UPDATED.                                */
  2824. /*                                                                           */
  2825. /*       THE REASON FOR CREATING THE FILE AND NOT OPENING IT IS TO ENSURE    */
  2826. /*       THAT WE DO NOT GET A MIX OF OLD AND NEW INFORMATION IN THE FILE IN  */
  2827. /*       ERROR SITUATIONS.                                                   */
  2828. /* ------------------------------------------------------------------------- */
  2829. void Dbdih::tableUpdateLab(Signal* signal, TabRecordPtr tabPtr) {
  2830.   FileRecordPtr filePtr;
  2831.   filePtr.i = tabPtr.p->tabFile[0];
  2832.   ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
  2833.   createFileRw(signal, filePtr);
  2834.   filePtr.p->reqStatus = FileRecord::TABLE_CREATE;
  2835.   return;
  2836. }//Dbdih::tableUpdateLab()
  2837. void Dbdih::tableCreateLab(Signal* signal, FileRecordPtr filePtr) 
  2838. {
  2839.   TabRecordPtr tabPtr;
  2840.   tabPtr.i = filePtr.p->tabRef;
  2841.   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  2842.   writeTabfile(signal, tabPtr.p, filePtr);
  2843.   filePtr.p->reqStatus = FileRecord::TABLE_WRITE;
  2844.   return;
  2845. }//Dbdih::tableCreateLab()
  2846. void Dbdih::tableWriteLab(Signal* signal, FileRecordPtr filePtr) 
  2847. {
  2848.   closeFile(signal, filePtr);
  2849.   filePtr.p->reqStatus = FileRecord::TABLE_CLOSE;
  2850.   return;
  2851. }//Dbdih::tableWriteLab()
  2852. void Dbdih::tableCloseLab(Signal* signal, FileRecordPtr filePtr) 
  2853. {
  2854.   TabRecordPtr tabPtr;
  2855.   tabPtr.i = filePtr.p->tabRef;
  2856.   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  2857.   if (filePtr.i == tabPtr.p->tabFile[0]) {
  2858.     jam();
  2859.     filePtr.i = tabPtr.p->tabFile[1];
  2860.     ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
  2861.     createFileRw(signal, filePtr);
  2862.     filePtr.p->reqStatus = FileRecord::TABLE_CREATE;
  2863.     return;
  2864.   }//if
  2865.   switch (tabPtr.p->tabUpdateState) {
  2866.   case TabRecord::US_LOCAL_CHECKPOINT:
  2867.     jam();
  2868.     releaseTabPages(tabPtr.i);
  2869.     signal->theData[0] = DihContinueB::ZCHECK_LCP_COMPLETED;
  2870.     sendSignal(reference(), GSN_CONTINUEB, signal, 1, JBB);
  2871.     tabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
  2872.     tabPtr.p->tabUpdateState = TabRecord::US_IDLE;
  2873.     tabPtr.p->tabLcpStatus = TabRecord::TLS_COMPLETED;
  2874.     return;
  2875.     break;
  2876.   case TabRecord::US_REMOVE_NODE:
  2877.     jam();
  2878.     releaseTabPages(tabPtr.i);
  2879.     for (Uint32 fragId = 0; fragId < tabPtr.p->totalfragments; fragId++) {
  2880.       jam();
  2881.       FragmentstorePtr fragPtr;
  2882.       getFragstore(tabPtr.p, fragId, fragPtr);
  2883.       updateNodeInfo(fragPtr);
  2884.     }//for
  2885.     tabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
  2886.     tabPtr.p->tabUpdateState = TabRecord::US_IDLE;
  2887.     if (tabPtr.p->tabLcpStatus == TabRecord::TLS_WRITING_TO_FILE) {
  2888.       jam();
  2889.       tabPtr.p->tabLcpStatus = TabRecord::TLS_COMPLETED;
  2890.       signal->theData[0] = DihContinueB::ZCHECK_LCP_COMPLETED;
  2891.       sendSignal(reference(), GSN_CONTINUEB, signal, 1, JBB);
  2892.     }//if
  2893.     signal->theData[0] = DihContinueB::ZREMOVE_NODE_FROM_TABLE;
  2894.     signal->theData[1] = tabPtr.p->tabRemoveNode;
  2895.     signal->theData[2] = tabPtr.i + 1;
  2896.     sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
  2897.     return;
  2898.     break;
  2899.   case TabRecord::US_INVALIDATE_NODE_LCP:
  2900.     jam();
  2901.     releaseTabPages(tabPtr.i);
  2902.     tabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
  2903.     tabPtr.p->tabUpdateState = TabRecord::US_IDLE;
  2904.     
  2905.     signal->theData[0] = DihContinueB::ZINVALIDATE_NODE_LCP;
  2906.     signal->theData[1] = tabPtr.p->tabRemoveNode;
  2907.     signal->theData[2] = tabPtr.i + 1;
  2908.     sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
  2909.     return;
  2910.   case TabRecord::US_COPY_TAB_REQ:
  2911.     jam();
  2912.     tabPtr.p->tabUpdateState = TabRecord::US_IDLE;
  2913.     copyTabReq_complete(signal, tabPtr);
  2914.     return;
  2915.     break;
  2916.   case TabRecord::US_ADD_TABLE_MASTER:
  2917.     jam();
  2918.     releaseTabPages(tabPtr.i);
  2919.     tabPtr.p->tabUpdateState = TabRecord::US_IDLE;
  2920.     signal->theData[0] = DihContinueB::ZDIH_ADD_TABLE_MASTER;
  2921.     signal->theData[1] = tabPtr.i;
  2922.     sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
  2923.     return;
  2924.     break;
  2925.   case TabRecord::US_ADD_TABLE_SLAVE:
  2926.     jam();
  2927.     releaseTabPages(tabPtr.i);
  2928.     tabPtr.p->tabUpdateState = TabRecord::US_IDLE;
  2929.     signal->theData[0] = DihContinueB::ZDIH_ADD_TABLE_SLAVE;
  2930.     signal->theData[1] = tabPtr.i;
  2931.     sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
  2932.     return;
  2933.     break;
  2934.   default:
  2935.     ndbrequire(false);
  2936.     return;
  2937.     break;
  2938.   }//switch
  2939. }//Dbdih::tableCloseLab()
  2940. /**
  2941.  * GCP stop detected, 
  2942.  * send SYSTEM_ERROR to all other alive nodes
  2943.  */
  2944. void Dbdih::crashSystemAtGcpStop(Signal* signal){
  2945.   NodeRecordPtr nodePtr;
  2946.   for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
  2947.     jam();
  2948.     ptrAss(nodePtr, nodeRecord);
  2949.     if (nodePtr.p->nodeStatus == NodeRecord::ALIVE) {
  2950.       jam();
  2951.       const BlockReference ref = 
  2952. numberToRef(refToBlock(cntrlblockref), nodePtr.i);
  2953.       SystemError * const sysErr = (SystemError*)&signal->theData[0];
  2954.       sysErr->errorCode = SystemError::GCPStopDetected;
  2955.       sysErr->errorRef = reference();
  2956.       sysErr->data1 = cgcpStatus;
  2957.       sysErr->data2 = cgcpOrderBlocked;
  2958.       sendSignal(ref, GSN_SYSTEM_ERROR, signal, 
  2959.  SystemError::SignalLength, JBA);
  2960.     }//if
  2961.   }//for
  2962.   return;
  2963. }//Dbdih::crashSystemAtGcpStop()
  2964. /*************************************************************************/
  2965. /*                                                                       */
  2966. /*       MODULE: ALLOCPAGE                                               */
  2967. /*       DESCRIPTION: THE SUBROUTINE IS CALLED WITH POINTER TO PAGE      */
  2968. /*                    RECORD. A PAGE  RECORD IS TAKEN FROM               */
  2969. /*                    THE FREE PAGE  LIST                                */
  2970. /*************************************************************************/
  2971. void Dbdih::allocpage(PageRecordPtr& pagePtr) 
  2972. {
  2973.   ndbrequire(cfirstfreepage != RNIL);
  2974.   pagePtr.i = cfirstfreepage;
  2975.   ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
  2976.   cfirstfreepage = pagePtr.p->nextfreepage;
  2977.   pagePtr.p->nextfreepage = RNIL;
  2978. }//Dbdih::allocpage()
  2979. /*************************************************************************/
  2980. /*                                                                       */
  2981. /*       MODULE: ALLOC_STORED_REPLICA                                    */
  2982. /*       DESCRIPTION: THE SUBROUTINE IS CALLED TO GET A REPLICA RECORD,  */
  2983. /*                    TO INITIALISE IT AND TO LINK IT INTO THE FRAGMENT  */
  2984. /*                    STORE RECORD. USED FOR STORED REPLICAS.            */
  2985. /*************************************************************************/
  2986. void Dbdih::allocStoredReplica(FragmentstorePtr fragPtr,
  2987.                                ReplicaRecordPtr& newReplicaPtr,
  2988.                                Uint32 nodeId) 
  2989. {
  2990.   Uint32 i;
  2991.   ReplicaRecordPtr arrReplicaPtr;
  2992.   ReplicaRecordPtr arrPrevReplicaPtr;
  2993.   seizeReplicaRec(newReplicaPtr);
  2994.   for (i = 0; i < MAX_LCP_STORED; i++) {
  2995.     newReplicaPtr.p->maxGciCompleted[i] = 0;
  2996.     newReplicaPtr.p->maxGciStarted[i] = 0;
  2997.     newReplicaPtr.p->lcpId[i] = 0;
  2998.     newReplicaPtr.p->lcpStatus[i] = ZINVALID;
  2999.   }//for
  3000.   newReplicaPtr.p->noCrashedReplicas = 0;
  3001.   newReplicaPtr.p->initialGci = currentgcp;
  3002.   for (i = 0; i < 8; i++) {
  3003.     newReplicaPtr.p->replicaLastGci[i] = (Uint32)-1;
  3004.     newReplicaPtr.p->createGci[i] = 0;
  3005.   }//for
  3006.   newReplicaPtr.p->createGci[0] = currentgcp;
  3007.   ndbrequire(currentgcp != 0xF1F1F1F1);
  3008.   newReplicaPtr.p->nextLcp = 0;
  3009.   newReplicaPtr.p->procNode = nodeId;
  3010.   newReplicaPtr.p->lcpOngoingFlag = false;
  3011.   newReplicaPtr.p->lcpIdStarted = 0;
  3012.   
  3013.   arrPrevReplicaPtr.i = RNIL;
  3014.   arrReplicaPtr.i = fragPtr.p->storedReplicas;
  3015.   while (arrReplicaPtr.i != RNIL) {
  3016.     jam();
  3017.     ptrCheckGuard(arrReplicaPtr, creplicaFileSize, replicaRecord);
  3018.     arrPrevReplicaPtr = arrReplicaPtr;
  3019.     arrReplicaPtr.i = arrReplicaPtr.p->nextReplica;
  3020.   }//while
  3021.   if (arrPrevReplicaPtr.i == RNIL) {
  3022.     jam();
  3023.     fragPtr.p->storedReplicas = newReplicaPtr.i;
  3024.   } else {
  3025.     jam();
  3026.     arrPrevReplicaPtr.p->nextReplica = newReplicaPtr.i;
  3027.   }//if
  3028.   fragPtr.p->noStoredReplicas++;
  3029. }//Dbdih::allocStoredReplica()
  3030. /*************************************************************************/
  3031. /*  CALCULATE HOW MANY HOT SPARES THAT ARE TO BE ASSIGNED IN THIS SYSTEM */
  3032. /*************************************************************************/
  3033. void Dbdih::calculateHotSpare() 
  3034. {
  3035.   Uint32 tchsTmp;
  3036.   Uint32 tchsNoNodes;
  3037.   switch (cnoReplicas) {
  3038.   case 1:
  3039.     jam();
  3040.     cnoHotSpare = 0;
  3041.     break;
  3042.   case 2:
  3043.   case 3:
  3044.   case 4:
  3045.     jam();
  3046.     if (csystemnodes > cnoReplicas) {
  3047.       jam();
  3048.       /* --------------------------------------------------------------------- */
  3049.       /*  WITH MORE NODES THAN REPLICAS WE WILL ALWAYS USE AT LEAST ONE HOT    */
  3050.       /*  SPARE IF THAT HAVE BEEN REQUESTED BY THE CONFIGURATION FILE. THE     */
  3051.       /*  NUMBER OF NODES TO BE USED FOR NORMAL OPERATION IS ALWAYS            */
  3052.       /*  A MULTIPLE OF THE NUMBER OF REPLICAS SINCE WE WILL ORGANISE NODES    */
  3053.       /*  INTO NODE GROUPS. THE REMAINING NODES WILL BE HOT SPARE NODES.       */
  3054.       /* --------------------------------------------------------------------- */
  3055.       if ((csystemnodes - cnoReplicas) >= cminHotSpareNodes) {
  3056.         jam();
  3057. /* --------------------------------------------------------------------- */
  3058. // We set the minimum number of hot spares according to users request
  3059. // through the configuration file.
  3060. /* --------------------------------------------------------------------- */
  3061.         tchsNoNodes = csystemnodes - cminHotSpareNodes;
  3062.         cnoHotSpare = cminHotSpareNodes;
  3063.       } else if (cminHotSpareNodes > 0) {
  3064.         jam();
  3065. /* --------------------------------------------------------------------- */
  3066. // The user requested at least one hot spare node and we will support him
  3067. // in that.
  3068. /* --------------------------------------------------------------------- */
  3069.         tchsNoNodes = csystemnodes - 1;
  3070.         cnoHotSpare = 1;
  3071.       } else {
  3072.         jam();
  3073. /* --------------------------------------------------------------------- */
  3074. // The user did not request any hot spare nodes so in this case we will
  3075. // only use hot spare nodes if the number of nodes is such that we cannot
  3076. // use all nodes as normal nodes.
  3077. /* --------------------------------------------------------------------- */
  3078.         tchsNoNodes = csystemnodes;
  3079.         cnoHotSpare = 0;
  3080.       }//if
  3081.     } else {
  3082.       jam();
  3083.       /* --------------------------------------------------------------------- */
  3084.       // We only have enough to support the replicas. We will not have any hot
  3085.       // spares.
  3086.       /* --------------------------------------------------------------------- */
  3087.       tchsNoNodes = csystemnodes;
  3088.       cnoHotSpare = 0;
  3089.     }//if
  3090.     tchsTmp = tchsNoNodes - (cnoReplicas * (tchsNoNodes / cnoReplicas));
  3091.     cnoHotSpare = cnoHotSpare + tchsTmp;
  3092.     break;
  3093.   default:
  3094.     jam();
  3095.     progError(0, 0);
  3096.     break;
  3097.   }//switch
  3098. }//Dbdih::calculateHotSpare()
  3099. /*************************************************************************/
  3100. /* CHECK IF THE NODE CRASH IS TO ESCALATE INTO A SYSTEM CRASH. WE COULD  */
  3101. /* DO THIS BECAUSE ALL REPLICAS OF SOME FRAGMENT ARE LOST. WE COULD ALSO */
  3102. /* DO IT AFTER MANY NODE FAILURES THAT MAKE IT VERY DIFFICULT TO RESTORE */
  3103. /* DATABASE AFTER A SYSTEM CRASH. IT MIGHT EVEN BE IMPOSSIBLE AND THIS   */
  3104. /* MUST BE AVOIDED EVEN MORE THAN AVOIDING SYSTEM CRASHES.               */
  3105. /*************************************************************************/
  3106. void Dbdih::checkEscalation() 
  3107. {
  3108.   Uint32 TnodeGroup[MAX_NDB_NODES];
  3109.   NodeRecordPtr nodePtr;
  3110.   Uint32 i;
  3111.   for (i = 0; i < MAX_NDB_NODES; i++) {
  3112.     TnodeGroup[i] = ZFALSE;
  3113.   }//for
  3114.   for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
  3115.     jam();
  3116.     ptrAss(nodePtr, nodeRecord);
  3117.     if (nodePtr.p->nodeStatus == NodeRecord::ALIVE &&
  3118. nodePtr.p->activeStatus == Sysfile::NS_Active){
  3119.       ndbrequire(nodePtr.p->nodeGroup < MAX_NDB_NODES);
  3120.       TnodeGroup[nodePtr.p->nodeGroup] = ZTRUE;
  3121.     }
  3122.   }
  3123.   for (i = 0; i < cnoOfNodeGroups; i++) {
  3124.     jam();
  3125.     if (TnodeGroup[i] == ZFALSE) {
  3126.       jam();
  3127.       progError(__LINE__, ERR_SYSTEM_ERROR, "Lost node group");
  3128.     }//if
  3129.   }//for
  3130. }//Dbdih::checkEscalation()
  3131. /*************************************************************************/
  3132. /*                                                                       */
  3133. /*       MODULE: CHECK_KEEP_GCI                                          */
  3134. /*       DESCRIPTION: CHECK FOR MINIMUM GCI RESTORABLE WITH NEW LOCAL    */
  3135. /*                    CHECKPOINT.                                        */
  3136. /*************************************************************************/
  3137. void Dbdih::checkKeepGci(Uint32 replicaStartIndex) 
  3138. {
  3139.   ReplicaRecordPtr ckgReplicaPtr;
  3140.   ckgReplicaPtr.i = replicaStartIndex;
  3141.   while (ckgReplicaPtr.i != RNIL) {
  3142.     jam();
  3143.     ptrCheckGuard(ckgReplicaPtr, creplicaFileSize, replicaRecord);
  3144.     Uint32 keepGci;
  3145.     Uint32 oldestRestorableGci;
  3146.     findMinGci(ckgReplicaPtr, keepGci, oldestRestorableGci);
  3147.     if (keepGci < c_lcpState.keepGci) {
  3148.       jam();
  3149.       /* ------------------------------------------------------------------- */
  3150.       /* WE MUST KEEP LOG RECORDS SO THAT WE CAN USE ALL LOCAL CHECKPOINTS   */
  3151.       /* THAT ARE AVAILABLE. THUS WE NEED TO CALCULATE THE MINIMUM OVER ALL  */
  3152.       /* FRAGMENTS.                                                          */
  3153.       /* ------------------------------------------------------------------- */
  3154.       c_lcpState.keepGci = keepGci;
  3155.     }//if
  3156.     if (oldestRestorableGci > c_lcpState.oldestRestorableGci) {
  3157.       jam();
  3158.       c_lcpState.oldestRestorableGci = oldestRestorableGci;
  3159.       ndbrequire(((int)c_lcpState.oldestRestorableGci) >= 0);
  3160.     }//if
  3161.     ckgReplicaPtr.i = ckgReplicaPtr.p->nextReplica;
  3162.   }//while
  3163. }//Dbdih::checkKeepGci()
  3164. void Dbdih::closeFile(Signal* signal, FileRecordPtr filePtr) 
  3165. {
  3166.   signal->theData[0] = filePtr.p->fileRef;
  3167.   signal->theData[1] = reference();
  3168.   signal->theData[2] = filePtr.i;
  3169.   signal->theData[3] = ZCLOSE_NO_DELETE;
  3170.   sendSignal(NDBFS_REF, GSN_FSCLOSEREQ, signal, 4, JBA);
  3171. }//Dbdih::closeFile()
  3172. void Dbdih::closeFileDelete(Signal* signal, FileRecordPtr filePtr) 
  3173. {
  3174.   signal->theData[0] = filePtr.p->fileRef;
  3175.   signal->theData[1] = reference();
  3176.   signal->theData[2] = filePtr.i;
  3177.   signal->theData[3] = ZCLOSE_DELETE;
  3178.   sendSignal(NDBFS_REF, GSN_FSCLOSEREQ, signal, 4, JBA);
  3179. }//Dbdih::closeFileDelete()
  3180. void Dbdih::createFileRw(Signal* signal, FileRecordPtr filePtr) 
  3181. {
  3182.   signal->theData[0] = reference();
  3183.   signal->theData[1] = filePtr.i;
  3184.   signal->theData[2] = filePtr.p->fileName[0];
  3185.   signal->theData[3] = filePtr.p->fileName[1];
  3186.   signal->theData[4] = filePtr.p->fileName[2];
  3187.   signal->theData[5] = filePtr.p->fileName[3];
  3188.   signal->theData[6] = ZCREATE_READ_WRITE;
  3189.   sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, 7, JBA);
  3190. }//Dbdih::createFileRw()
  3191. void Dbdih::emptyverificbuffer(Signal* signal, bool aContinueB) 
  3192. {
  3193.   if(cfirstVerifyQueue == RNIL){
  3194.     jam();
  3195.     return;
  3196.   }//if
  3197.   ApiConnectRecordPtr localApiConnectptr;
  3198.   if(getBlockCommit() == false){
  3199.     jam();
  3200.     ndbrequire(cverifyQueueCounter > 0);
  3201.     cverifyQueueCounter--;
  3202.     localApiConnectptr.i = cfirstVerifyQueue;
  3203.     ptrCheckGuard(localApiConnectptr, capiConnectFileSize, apiConnectRecord);
  3204.     ndbrequire(localApiConnectptr.p->apiGci <= currentgcp);
  3205.     cfirstVerifyQueue = localApiConnectptr.p->nextApi;
  3206.     if (cfirstVerifyQueue == RNIL) {
  3207.       jam();
  3208.       ndbrequire(cverifyQueueCounter == 0);
  3209.       clastVerifyQueue = RNIL;
  3210.     }//if
  3211.     signal->theData[0] = localApiConnectptr.i;
  3212.     signal->theData[1] = currentgcp;
  3213.     sendSignal(clocaltcblockref, GSN_DIVERIFYCONF, signal, 2, JBB);
  3214.     if (aContinueB == true) {
  3215.       jam();
  3216.       //-----------------------------------------------------------------------
  3217.       // This emptying happened as part of a take-out process by continueb signals.
  3218.       // This ensures that we will empty the queue eventually. We will also empty
  3219.       // one item every time we insert one item to ensure that the list doesn't
  3220.       // grow when it is not blocked.
  3221.       //-----------------------------------------------------------------------
  3222.       signal->theData[0] = DihContinueB::ZEMPTY_VERIFY_QUEUE;
  3223.       sendSignal(reference(), GSN_CONTINUEB, signal, 1, JBB);
  3224.     }//if
  3225.   } else {
  3226.     jam();
  3227.     //-----------------------------------------------------------------------
  3228.     // We are blocked so it is no use in continuing the emptying of the
  3229.     // verify buffer. Whenever the block is removed the emptying will
  3230.     // restart.
  3231.     //-----------------------------------------------------------------------
  3232.   }  
  3233.   return;
  3234. }//Dbdih::emptyverificbuffer()
  3235. /*----------------------------------------------------------------*/
  3236. /*       FIND A FREE HOT SPARE IF AVAILABLE AND ALIVE.            */
  3237. /*----------------------------------------------------------------*/
  3238. Uint32 Dbdih::findHotSpare()
  3239. {
  3240.   NodeRecordPtr nodePtr;
  3241.   for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
  3242.     jam();
  3243.     ptrAss(nodePtr, nodeRecord);
  3244.     if (nodePtr.p->nodeStatus == NodeRecord::ALIVE) {
  3245.       if (nodePtr.p->activeStatus == Sysfile::NS_HotSpare) {
  3246.         jam();
  3247.         return nodePtr.i;
  3248.       }//if
  3249.     }//if
  3250.   }//for
  3251.   return RNIL;
  3252. }//Dbdih::findHotSpare()
  3253. /*************************************************************************/
  3254. /*       FIND THE NODES FROM WHICH WE CAN EXECUTE THE LOG TO RESTORE THE */
  3255. /*       DATA NODE IN A SYSTEM RESTART.                                  */
  3256. /*************************************************************************/
  3257. bool Dbdih::findLogNodes(CreateReplicaRecord* createReplica,
  3258.                          FragmentstorePtr fragPtr,
  3259.                          Uint32 startGci,
  3260.                          Uint32 stopGci) 
  3261. {
  3262.   ConstPtr<ReplicaRecord> flnReplicaPtr;
  3263.   flnReplicaPtr.i = createReplica->replicaRec;
  3264.   ptrCheckGuard(flnReplicaPtr, creplicaFileSize, replicaRecord);
  3265.   /* --------------------------------------------------------------------- */
  3266.   /*       WE START BY CHECKING IF THE DATA NODE CAN HANDLE THE LOG ALL BY */
  3267.   /*       ITSELF. THIS IS THE DESIRED BEHAVIOUR. IF THIS IS NOT POSSIBLE  */
  3268.   /*       THEN WE SEARCH FOR THE BEST POSSIBLE NODES AMONG THE NODES THAT */
  3269.   /*       ARE PART OF THIS SYSTEM RESTART.                                */
  3270.   /*       THIS CAN ONLY BE HANDLED BY THE LAST CRASHED REPLICA.           */
  3271.   /*       The condition is that the replica was created before or at the  */
  3272.   /*       time of the starting gci, in addition it must have been alive   */
  3273.   /*       at the time of the stopping gci. This is checked by two         */
  3274.   /*       conditions, the first checks replicaLastGci and the second      */
  3275.   /*       checks that it is also smaller than the last gci the node was   */
  3276.   /*       involved in. This is necessary to check since createGci is set  */
  3277.   /*       Last + 1 and sometimes startGci = stopGci + 1 and in that case  */
  3278.   /*       it could happen that replicaLastGci is set to -1 with CreateGci */
  3279.   /*       set to LastGci + 1.                                             */
  3280.   /* --------------------------------------------------------------------- */
  3281.   arrGuard(flnReplicaPtr.p->noCrashedReplicas, 8);
  3282.   const Uint32 noCrashed = flnReplicaPtr.p->noCrashedReplicas;
  3283.   
  3284.   if (!(ERROR_INSERTED(7073) || ERROR_INSERTED(7074))&&
  3285.       (startGci >= flnReplicaPtr.p->createGci[noCrashed]) &&
  3286.       (stopGci <= flnReplicaPtr.p->replicaLastGci[noCrashed]) &&
  3287.       (stopGci <= SYSFILE->lastCompletedGCI[flnReplicaPtr.p->procNode])) {
  3288.     jam();
  3289.     /* --------------------------------------------------------------------- */
  3290.     /*       WE FOUND ALL THE LOG RECORDS NEEDED IN THE DATA NODE. WE WILL   */
  3291.     /*       USE THOSE.                                                      */
  3292.     /* --------------------------------------------------------------------- */
  3293.     createReplica->noLogNodes = 1;
  3294.     createReplica->logStartGci[0] = startGci;
  3295.     createReplica->logStopGci[0] = stopGci;
  3296.     createReplica->logNodeId[0] = flnReplicaPtr.p->procNode;
  3297.     return true;
  3298.   }//if
  3299.   Uint32 logNode = 0;
  3300.   do {
  3301.     Uint32 fblStopGci;
  3302.     jam();
  3303.     if(!findBestLogNode(createReplica,
  3304. fragPtr,
  3305. startGci,
  3306. stopGci,
  3307. logNode,
  3308. fblStopGci)){
  3309.       jam();
  3310.       return false;
  3311.     }
  3312.        
  3313.     logNode++;
  3314.     if (fblStopGci >= stopGci) {
  3315.       jam();
  3316.       createReplica->noLogNodes = logNode;
  3317.       return true;
  3318.     }//if
  3319.     startGci = fblStopGci + 1;
  3320.     if (logNode >= 4) { // Why??
  3321.       jam();
  3322.       break;
  3323.     }//if
  3324.   } while (1);
  3325.   /* --------------------------------------------------------------------- */
  3326.   /*       IT WAS NOT POSSIBLE TO RESTORE THE REPLICA. THIS CAN EITHER BE  */
  3327.   /*       BECAUSE OF LACKING NODES OR BECAUSE OF A REALLY SERIOUS PROBLEM.*/
  3328.   /* --------------------------------------------------------------------- */
  3329.   return false;
  3330. }//Dbdih::findLogNodes()
  3331. /*************************************************************************/
  3332. /*       FIND THE BEST POSSIBLE LOG NODE TO EXECUTE THE LOG AS SPECIFIED */
  3333. /*       BY THE INPUT PARAMETERS. WE SCAN THROUGH ALL ALIVE REPLICAS.    */
  3334. /*       THIS MEANS STORED, OLD_STORED                                   */
  3335. /*************************************************************************/
  3336. bool
  3337. Dbdih::findBestLogNode(CreateReplicaRecord* createReplica,
  3338.        FragmentstorePtr fragPtr,
  3339.        Uint32 startGci,
  3340.        Uint32 stopGci,
  3341.        Uint32 logNode,
  3342.        Uint32& fblStopGci) 
  3343. {
  3344.   ConstPtr<ReplicaRecord> fblFoundReplicaPtr;
  3345.   ConstPtr<ReplicaRecord> fblReplicaPtr;
  3346.   
  3347.   /* --------------------------------------------------------------------- */
  3348.   /*       WE START WITH ZERO AS FOUND TO ENSURE THAT FIRST HIT WILL BE    */
  3349.   /*       BETTER.                                                         */
  3350.   /* --------------------------------------------------------------------- */
  3351.   fblStopGci = 0;
  3352.   fblReplicaPtr.i = fragPtr.p->storedReplicas;
  3353.   while (fblReplicaPtr.i != RNIL) {
  3354.     jam();
  3355.     ptrCheckGuard(fblReplicaPtr, creplicaFileSize, replicaRecord);
  3356.     if (checkNodeAlive(fblReplicaPtr.p->procNode)) {
  3357.       jam();
  3358.       Uint32 fliStopGci = findLogInterval(fblReplicaPtr, startGci);
  3359.       if (fliStopGci > fblStopGci) {
  3360.         jam();
  3361.         fblStopGci = fliStopGci;
  3362.         fblFoundReplicaPtr = fblReplicaPtr;
  3363.       }//if
  3364.     }//if
  3365.     fblReplicaPtr.i = fblReplicaPtr.p->nextReplica;
  3366.   }//while
  3367.   fblReplicaPtr.i = fragPtr.p->oldStoredReplicas;
  3368.   while (fblReplicaPtr.i != RNIL) {
  3369.     jam();
  3370.     ptrCheckGuard(fblReplicaPtr, creplicaFileSize, replicaRecord);
  3371.     if (checkNodeAlive(fblReplicaPtr.p->procNode)) {
  3372.       jam();
  3373.       Uint32 fliStopGci = findLogInterval(fblReplicaPtr, startGci);
  3374.       if (fliStopGci > fblStopGci) {
  3375.         jam();
  3376.         fblStopGci = fliStopGci;
  3377.         fblFoundReplicaPtr = fblReplicaPtr;
  3378.       }//if
  3379.     }//if
  3380.     fblReplicaPtr.i = fblReplicaPtr.p->nextReplica;
  3381.   }//while
  3382.   if (fblStopGci != 0) {
  3383.     jam();
  3384.     ndbrequire(logNode < MAX_LOG_EXEC);