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

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #define DBDIH_C
  14. #include <ndb_limits.h>
  15. #include <ndb_version.h>
  16. #include <NdbOut.hpp>
  17. #include "Dbdih.hpp"
  18. #include "Configuration.hpp"
  19. #include <signaldata/BlockCommitOrd.hpp>
  20. #include <signaldata/CheckNodeGroups.hpp>
  21. #include <signaldata/CreateFrag.hpp>
  22. #include <signaldata/CopyActive.hpp>
  23. #include <signaldata/CopyFrag.hpp>
  24. #include <signaldata/CopyGCIReq.hpp>
  25. #include <signaldata/DiAddTab.hpp>
  26. #include <signaldata/DictStart.hpp>
  27. #include <signaldata/DiGetNodes.hpp>
  28. #include <signaldata/DihContinueB.hpp>
  29. #include <signaldata/DihSwitchReplica.hpp>
  30. #include <signaldata/DumpStateOrd.hpp>
  31. #include <signaldata/EmptyLcp.hpp>
  32. #include <signaldata/EndTo.hpp>
  33. #include <signaldata/EventReport.hpp>
  34. #include <signaldata/GCPSave.hpp>
  35. #include <signaldata/HotSpareRep.hpp>
  36. #include <signaldata/MasterGCP.hpp>
  37. #include <signaldata/MasterLCP.hpp>
  38. #include <signaldata/NFCompleteRep.hpp>
  39. #include <signaldata/NodeFailRep.hpp>
  40. #include <signaldata/ReadNodesConf.hpp>
  41. #include <signaldata/StartFragReq.hpp>
  42. #include <signaldata/StartInfo.hpp>
  43. #include <signaldata/StartMe.hpp>
  44. #include <signaldata/StartPerm.hpp>
  45. #include <signaldata/StartRec.hpp>
  46. #include <signaldata/StartTo.hpp>
  47. #include <signaldata/StopPerm.hpp>
  48. #include <signaldata/StopMe.hpp>
  49. #include <signaldata/TestOrd.hpp>
  50. #include <signaldata/UpdateTo.hpp>
  51. #include <signaldata/WaitGCP.hpp>
  52. #include <signaldata/DihStartTab.hpp>
  53. #include <signaldata/LCP.hpp>
  54. #include <signaldata/SystemError.hpp>
  55. #include <signaldata/DropTab.hpp>
  56. #include <signaldata/AlterTab.hpp>
  57. #include <signaldata/PrepDropTab.hpp>
  58. #include <signaldata/SumaImpl.hpp>
  59. #include <signaldata/DictTabInfo.hpp>
  60. #include <signaldata/CreateFragmentation.hpp>
  61. #include <signaldata/LqhFrag.hpp>
  62. #include <signaldata/FsOpenReq.hpp>
  63. #include <DebuggerNames.hpp>
  64. #include <EventLogger.hpp>
  65. extern EventLogger g_eventLogger;
  66. #define SYSFILE ((Sysfile *)&sysfileData[0])
  67. #define RETURN_IF_NODE_NOT_ALIVE(node) 
  68.   if (!checkNodeAlive((node))) { 
  69.     jam(); 
  70.     return; 
  71.   } 
  72. #define RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverIndex, regTOPtr) 
  73.   regTOPtr.i = takeOverIndex; 
  74.   ptrCheckGuard(regTOPtr, MAX_NDB_NODES, takeOverRecord); 
  75.   if (checkToInterrupted(regTOPtr)) { 
  76.     jam(); 
  77.     return; 
  78.   } 
  79. #define receiveLoopMacro(sigName, receiveNodeId)
  80. {                                                
  81.   c_##sigName##_Counter.clearWaitingFor(receiveNodeId); 
  82.   if(c_##sigName##_Counter.done() == false){     
  83.      jam();                                      
  84.      return;                                     
  85.   }                                              
  86. }
  87. #define sendLoopMacro(sigName, signalRoutine)  
  88. {                                                                       
  89.   c_##sigName##_Counter.clearWaitingFor();                              
  90.   NodeRecordPtr specNodePtr;                                            
  91.   specNodePtr.i = cfirstAliveNode;                                      
  92.   do {                                                                  
  93.     jam();                                                              
  94.     ptrCheckGuard(specNodePtr, MAX_NDB_NODES, nodeRecord);              
  95.     c_##sigName##_Counter.setWaitingFor(specNodePtr.i);                 
  96.     signalRoutine(signal, specNodePtr.i);                               
  97.     specNodePtr.i = specNodePtr.p->nextNode;                            
  98.   } while (specNodePtr.i != RNIL);                                      
  99. }
  100. static
  101. Uint32
  102. prevLcpNo(Uint32 lcpNo){
  103.   if(lcpNo == 0)
  104.     return MAX_LCP_STORED - 1;
  105.   return lcpNo - 1;
  106. }
  107. static
  108. Uint32
  109. nextLcpNo(Uint32 lcpNo){
  110.   lcpNo++;
  111.   if(lcpNo == MAX_LCP_STORED)
  112.     return 0;
  113.   return lcpNo;
  114. }
  115. #define gth(x, y) ndbrequire(((int)x)>((int)y))
  116. void Dbdih::nullRoutine(Signal* signal, Uint32 nodeId)
  117. {
  118. }//Dbdih::nullRoutine()
  119. void Dbdih::sendCOPY_GCIREQ(Signal* signal, Uint32 nodeId) 
  120. {
  121.   ndbrequire(c_copyGCIMaster.m_copyReason != CopyGCIReq::IDLE);
  122.   
  123.   const BlockReference ref = calcDihBlockRef(nodeId);
  124.   const Uint32 wordPerSignal = CopyGCIReq::DATA_SIZE;
  125.   const Uint32 noOfSignals = ((Sysfile::SYSFILE_SIZE32 + (wordPerSignal - 1)) /
  126.       wordPerSignal);
  127.   
  128.   CopyGCIReq * const copyGCI = (CopyGCIReq *)&signal->theData[0];  
  129.   copyGCI->anyData = nodeId;
  130.   copyGCI->copyReason = c_copyGCIMaster.m_copyReason;
  131.   copyGCI->startWord = 0;
  132.   
  133.   for(Uint32 i = 0; i < noOfSignals; i++) {
  134.     jam();
  135.     { // Do copy
  136.       const int startWord = copyGCI->startWord;
  137.       for(Uint32 j = 0; j < wordPerSignal; j++) {
  138.         copyGCI->data[j] = sysfileData[j+startWord];
  139.       }//for
  140.     }
  141.     sendSignal(ref, GSN_COPY_GCIREQ, signal, 25, JBB);
  142.     copyGCI->startWord += wordPerSignal;
  143.   }//for
  144. }//Dbdih::sendCOPY_GCIREQ()
  145. void Dbdih::sendDIH_SWITCH_REPLICA_REQ(Signal* signal, Uint32 nodeId)
  146. {
  147.   const BlockReference ref    = calcDihBlockRef(nodeId);
  148.   sendSignal(ref, GSN_DIH_SWITCH_REPLICA_REQ, signal, 
  149.              DihSwitchReplicaReq::SignalLength, JBB);
  150. }//Dbdih::sendDIH_SWITCH_REPLICA_REQ()
  151. void Dbdih::sendEMPTY_LCP_REQ(Signal* signal, Uint32 nodeId)
  152. {
  153.   BlockReference ref = calcLqhBlockRef(nodeId);
  154.   sendSignal(ref, GSN_EMPTY_LCP_REQ, signal, EmptyLcpReq::SignalLength, JBB);
  155. }//Dbdih::sendEMPTY_LCPREQ()
  156. void Dbdih::sendEND_TOREQ(Signal* signal, Uint32 nodeId)
  157. {
  158.   BlockReference ref = calcDihBlockRef(nodeId);
  159.   sendSignal(ref, GSN_END_TOREQ, signal, EndToReq::SignalLength, JBB);
  160. }//Dbdih::sendEND_TOREQ()
  161. void Dbdih::sendGCP_COMMIT(Signal* signal, Uint32 nodeId)
  162. {
  163.   BlockReference ref = calcDihBlockRef(nodeId);
  164.   signal->theData[0] = cownNodeId;
  165.   signal->theData[1] = cnewgcp;
  166.   sendSignal(ref, GSN_GCP_COMMIT, signal, 2, JBA);
  167. }//Dbdih::sendGCP_COMMIT()
  168. void Dbdih::sendGCP_PREPARE(Signal* signal, Uint32 nodeId)
  169. {
  170.   BlockReference ref = calcDihBlockRef(nodeId);
  171.   signal->theData[0] = cownNodeId;
  172.   signal->theData[1] = cnewgcp;
  173.   sendSignal(ref, GSN_GCP_PREPARE, signal, 2, JBA);
  174. }//Dbdih::sendGCP_PREPARE()
  175. void Dbdih::sendGCP_SAVEREQ(Signal* signal, Uint32 nodeId)
  176. {
  177.   GCPSaveReq * const saveReq = (GCPSaveReq*)&signal->theData[0];
  178.   BlockReference ref = calcLqhBlockRef(nodeId);
  179.   saveReq->dihBlockRef = reference();
  180.   saveReq->dihPtr = nodeId;
  181.   saveReq->gci = coldgcp;
  182.   sendSignal(ref, GSN_GCP_SAVEREQ, signal, GCPSaveReq::SignalLength, JBB);
  183. }//Dbdih::sendGCP_SAVEREQ()
  184. void Dbdih::sendINCL_NODEREQ(Signal* signal, Uint32 nodeId)
  185. {
  186.   BlockReference nodeDihRef = calcDihBlockRef(nodeId);
  187.   signal->theData[0] = reference();
  188.   signal->theData[1] = c_nodeStartMaster.startNode;
  189.   signal->theData[2] = c_nodeStartMaster.failNr;
  190.   signal->theData[3] = 0;
  191.   signal->theData[4] = currentgcp;  
  192.   sendSignal(nodeDihRef, GSN_INCL_NODEREQ, signal, 5, JBB);
  193. }//Dbdih::sendINCL_NODEREQ()
  194. void Dbdih::sendMASTER_GCPREQ(Signal* signal, Uint32 nodeId)
  195. {
  196.   BlockReference ref = calcDihBlockRef(nodeId);
  197.   sendSignal(ref, GSN_MASTER_GCPREQ, signal, MasterGCPReq::SignalLength, JBB);
  198. }//Dbdih::sendMASTER_GCPREQ()
  199. void Dbdih::sendMASTER_LCPREQ(Signal* signal, Uint32 nodeId)
  200. {
  201.   BlockReference ref = calcDihBlockRef(nodeId);
  202.   sendSignal(ref, GSN_MASTER_LCPREQ, signal, MasterLCPReq::SignalLength, JBB);
  203. }//Dbdih::sendMASTER_LCPREQ()
  204. void Dbdih::sendSTART_INFOREQ(Signal* signal, Uint32 nodeId)
  205. {
  206.   const BlockReference ref = calcDihBlockRef(nodeId);
  207.   sendSignal(ref, GSN_START_INFOREQ, signal, StartInfoReq::SignalLength, JBB);
  208. }//sendSTART_INFOREQ()
  209. void Dbdih::sendSTART_RECREQ(Signal* signal, Uint32 nodeId)
  210. {
  211.   StartRecReq * const req = (StartRecReq*)&signal->theData[0];
  212.   BlockReference ref = calcLqhBlockRef(nodeId);
  213.   req->receivingNodeId = nodeId;
  214.   req->senderRef = reference();
  215.   req->keepGci = SYSFILE->keepGCI;
  216.   req->lastCompletedGci = SYSFILE->lastCompletedGCI[nodeId];
  217.   req->newestGci = SYSFILE->newestRestorableGCI;
  218.   sendSignal(ref, GSN_START_RECREQ, signal, StartRecReq::SignalLength, JBB);
  219.   signal->theData[0] = EventReport::StartREDOLog;
  220.   signal->theData[1] = nodeId;
  221.   signal->theData[2] = SYSFILE->keepGCI;
  222.   signal->theData[3] = SYSFILE->lastCompletedGCI[nodeId];
  223.   signal->theData[4] = SYSFILE->newestRestorableGCI;
  224.   sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 5, JBB);
  225. }//Dbdih::sendSTART_RECREQ()
  226. void Dbdih::sendSTART_TOREQ(Signal* signal, Uint32 nodeId)
  227. {
  228.   BlockReference ref = calcDihBlockRef(nodeId);
  229.   sendSignal(ref, GSN_START_TOREQ, signal, StartToReq::SignalLength, JBB);
  230. }//Dbdih::sendSTART_TOREQ()
  231. void Dbdih::sendSTOP_ME_REQ(Signal* signal, Uint32 nodeId)
  232. {
  233.   if (nodeId != getOwnNodeId()) {
  234.     jam();
  235.     const BlockReference ref = calcDihBlockRef(nodeId);
  236.     sendSignal(ref, GSN_STOP_ME_REQ, signal, StopMeReq::SignalLength, JBB);
  237.   }//if
  238. }//Dbdih::sendSTOP_ME_REQ()
  239. void Dbdih::sendTC_CLOPSIZEREQ(Signal* signal, Uint32 nodeId)
  240. {
  241.   BlockReference ref = calcTcBlockRef(nodeId);
  242.   signal->theData[0] = nodeId;
  243.   signal->theData[1] = reference();
  244.   sendSignal(ref, GSN_TC_CLOPSIZEREQ, signal, 2, JBB);
  245. }//Dbdih::sendTC_CLOPSIZEREQ()
  246. void Dbdih::sendTCGETOPSIZEREQ(Signal* signal, Uint32 nodeId)
  247. {
  248.   BlockReference ref = calcTcBlockRef(nodeId);
  249.   signal->theData[0] = nodeId;
  250.   signal->theData[1] = reference();
  251.   sendSignal(ref, GSN_TCGETOPSIZEREQ, signal, 2, JBB);
  252. }//Dbdih::sendTCGETOPSIZEREQ()
  253. void Dbdih::sendUPDATE_TOREQ(Signal* signal, Uint32 nodeId)
  254. {
  255.   const BlockReference ref = calcDihBlockRef(nodeId);
  256.   sendSignal(ref, GSN_UPDATE_TOREQ, signal, UpdateToReq::SignalLength, JBB);
  257. }//sendUPDATE_TOREQ()
  258. void Dbdih::execCONTINUEB(Signal* signal)
  259. {
  260.   jamEntry();
  261.   switch ((DihContinueB::Type)signal->theData[0]) {
  262.   case DihContinueB::ZPACK_TABLE_INTO_PAGES:
  263.     {
  264.       jam();
  265.       Uint32 tableId = signal->theData[1];
  266.       packTableIntoPagesLab(signal, tableId);
  267.       return;
  268.       break;
  269.     }
  270.   case DihContinueB::ZPACK_FRAG_INTO_PAGES:
  271.     {
  272.       RWFragment wf;
  273.       jam();
  274.       wf.rwfTabPtr.i = signal->theData[1];
  275.       ptrCheckGuard(wf.rwfTabPtr, ctabFileSize, tabRecord);
  276.       wf.fragId = signal->theData[2];
  277.       wf.pageIndex = signal->theData[3];
  278.       wf.wordIndex = signal->theData[4];
  279.       packFragIntoPagesLab(signal, &wf);
  280.       return;
  281.       break;
  282.     }
  283.   case DihContinueB::ZREAD_PAGES_INTO_TABLE:
  284.     {
  285.       jam();
  286.       Uint32 tableId = signal->theData[1];
  287.       readPagesIntoTableLab(signal, tableId);
  288.       return;
  289.       break;
  290.     }
  291.   case DihContinueB::ZREAD_PAGES_INTO_FRAG:
  292.     {
  293.       RWFragment rf;
  294.       jam();
  295.       rf.rwfTabPtr.i = signal->theData[1];
  296.       ptrCheckGuard(rf.rwfTabPtr, ctabFileSize, tabRecord);
  297.       rf.fragId = signal->theData[2];
  298.       rf.pageIndex = signal->theData[3];
  299.       rf.wordIndex = signal->theData[4];
  300.       readPagesIntoFragLab(signal, &rf);
  301.       return;
  302.       break;
  303.     }
  304.   case DihContinueB::ZCOPY_TABLE:
  305.     {
  306.       jam();
  307.       Uint32 tableId = signal->theData[1];
  308.       copyTableLab(signal, tableId);
  309.       return;
  310.     }
  311.   case DihContinueB::ZCOPY_TABLE_NODE:
  312.     {
  313.       NodeRecordPtr nodePtr;
  314.       CopyTableNode ctn;
  315.       jam();
  316.       ctn.ctnTabPtr.i = signal->theData[1];
  317.       ptrCheckGuard(ctn.ctnTabPtr, ctabFileSize, tabRecord);
  318.       nodePtr.i = signal->theData[2];
  319.       ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
  320.       ctn.pageIndex = signal->theData[3];
  321.       ctn.wordIndex = signal->theData[4];
  322.       ctn.noOfWords = signal->theData[5];
  323.       copyTableNode(signal, &ctn, nodePtr);
  324.       return;
  325.     }
  326.   case DihContinueB::ZSTART_FRAGMENT:
  327.     {
  328.       jam();
  329.       Uint32 tableId = signal->theData[1];
  330.       Uint32 fragId = signal->theData[2];
  331.       startFragment(signal, tableId, fragId);
  332.       return;
  333.     }
  334.   case DihContinueB::ZCOMPLETE_RESTART:
  335.     jam();
  336.     completeRestartLab(signal);
  337.     return;
  338.   case DihContinueB::ZREAD_TABLE_FROM_PAGES:
  339.     {
  340.       TabRecordPtr tabPtr;
  341.       jam();
  342.       tabPtr.i = signal->theData[1];
  343.       ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  344.       readTableFromPagesLab(signal, tabPtr);
  345.       return;
  346.     }
  347.   case DihContinueB::ZSR_PHASE2_READ_TABLE:
  348.     {
  349.       TabRecordPtr tabPtr;
  350.       jam();
  351.       tabPtr.i = signal->theData[1];
  352.       ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  353.       srPhase2ReadTableLab(signal, tabPtr);
  354.       return;
  355.     }
  356.   case DihContinueB::ZCHECK_TC_COUNTER:
  357.     jam();
  358. #ifndef NO_LCP
  359.     checkTcCounterLab(signal);
  360. #endif
  361.     return;
  362.   case DihContinueB::ZCALCULATE_KEEP_GCI:
  363.     {
  364.       jam();
  365.       Uint32 tableId = signal->theData[1];
  366.       Uint32 fragId = signal->theData[2];
  367.       calculateKeepGciLab(signal, tableId, fragId);
  368.       return;
  369.     }
  370.   case DihContinueB::ZSTORE_NEW_LCP_ID:
  371.     jam();
  372.     storeNewLcpIdLab(signal);
  373.     return;
  374.   case DihContinueB::ZTABLE_UPDATE:
  375.     {
  376.       TabRecordPtr tabPtr;
  377.       jam();
  378.       tabPtr.i = signal->theData[1];
  379.       ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  380.       tableUpdateLab(signal, tabPtr);
  381.       return;
  382.     }
  383.   case DihContinueB::ZCHECK_LCP_COMPLETED:
  384.     {
  385.       jam();
  386.       checkLcpCompletedLab(signal);
  387.       return;
  388.     }
  389.   case DihContinueB::ZINIT_LCP:
  390.     {
  391.       jam();
  392.       Uint32 senderRef = signal->theData[1];
  393.       Uint32 tableId = signal->theData[2];
  394.       initLcpLab(signal, senderRef, tableId);
  395.       return;
  396.     }
  397.   case DihContinueB::ZADD_TABLE_MASTER_PAGES:
  398.     {
  399.       TabRecordPtr tabPtr;
  400.       jam();
  401.       tabPtr.i = signal->theData[1];
  402.       ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  403.       tabPtr.p->tabUpdateState = TabRecord::US_ADD_TABLE_MASTER;
  404.       tableUpdateLab(signal, tabPtr);
  405.       return;
  406.       break;
  407.     }
  408.   case DihContinueB::ZDIH_ADD_TABLE_MASTER:
  409.     {
  410.       jam();
  411.       addTable_closeConf(signal, signal->theData[1]);
  412.       return;
  413.     }
  414.   case DihContinueB::ZADD_TABLE_SLAVE_PAGES:
  415.     {
  416.       TabRecordPtr tabPtr;
  417.       jam();
  418.       tabPtr.i = signal->theData[1];
  419.       ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  420.       tabPtr.p->tabUpdateState = TabRecord::US_ADD_TABLE_SLAVE;
  421.       tableUpdateLab(signal, tabPtr);
  422.       return;
  423.     }
  424.   case DihContinueB::ZDIH_ADD_TABLE_SLAVE:
  425.     {
  426.       ndbrequire(false);
  427.       return;
  428.     }
  429.   case DihContinueB::ZSTART_GCP:
  430.     jam();
  431. #ifndef NO_GCP
  432.     startGcpLab(signal, signal->theData[1]);
  433. #endif
  434.     return;
  435.     break;
  436.   case DihContinueB::ZCOPY_GCI:{
  437.     jam();
  438.     CopyGCIReq::CopyReason reason = (CopyGCIReq::CopyReason)signal->theData[1];
  439.     ndbrequire(c_copyGCIMaster.m_copyReason == reason);
  440.     sendLoopMacro(COPY_GCIREQ, sendCOPY_GCIREQ);
  441.     return;
  442.   }
  443.     break;
  444.   case DihContinueB::ZEMPTY_VERIFY_QUEUE:
  445.     jam();
  446.     emptyverificbuffer(signal, true);
  447.     return;
  448.     break;
  449.   case DihContinueB::ZCHECK_GCP_STOP:
  450.     jam();
  451. #ifndef NO_GCP
  452.     checkGcpStopLab(signal);
  453. #endif
  454.     return;
  455.     break;
  456.   case DihContinueB::ZREMOVE_NODE_FROM_TABLE:
  457.     {
  458.       jam();
  459.       Uint32 nodeId = signal->theData[1];
  460.       Uint32 tableId = signal->theData[2];
  461.       removeNodeFromTables(signal, nodeId, tableId);
  462.       return;
  463.     }
  464.   case DihContinueB::ZCOPY_NODE:
  465.     {
  466.       jam();
  467.       Uint32 tableId = signal->theData[1];
  468.       copyNodeLab(signal, tableId);
  469.       return;
  470.     }
  471.   case DihContinueB::ZSTART_TAKE_OVER:
  472.     {
  473.       jam();
  474.       Uint32 takeOverPtrI = signal->theData[1];
  475.       Uint32 startNode = signal->theData[2];
  476.       Uint32 toNode = signal->theData[3];
  477.       startTakeOver(signal, takeOverPtrI, startNode, toNode);
  478.       return;
  479.       break;
  480.     }
  481.   case DihContinueB::ZCHECK_START_TAKE_OVER:
  482.     jam();
  483.     checkStartTakeOver(signal);
  484.     break;
  485.   case DihContinueB::ZTO_START_COPY_FRAG:
  486.     {
  487.       jam();
  488.       Uint32 takeOverPtrI = signal->theData[1];
  489.       startNextCopyFragment(signal, takeOverPtrI);
  490.       return;
  491.     }
  492.   case DihContinueB::ZINVALIDATE_NODE_LCP:
  493.     {
  494.       jam();
  495.       const Uint32 nodeId = signal->theData[1];
  496.       const Uint32 tableId = signal->theData[2];
  497.       invalidateNodeLCP(signal, nodeId, tableId);
  498.       return;
  499.     }
  500.   case DihContinueB::ZINITIALISE_RECORDS:
  501.     jam();
  502.     initialiseRecordsLab(signal, 
  503.  signal->theData[1], 
  504.  signal->theData[2], 
  505.  signal->theData[3]);
  506.     return;
  507.     break;
  508.   case DihContinueB::ZSTART_PERMREQ_AGAIN:
  509.     jam();
  510.     nodeRestartPh2Lab(signal);
  511.     return;
  512.     break;
  513.   case DihContinueB::SwitchReplica:
  514.     {
  515.       jam();
  516.       const Uint32 nodeId = signal->theData[1];
  517.       const Uint32 tableId = signal->theData[2];
  518.       const Uint32 fragNo = signal->theData[3];
  519.       switchReplica(signal, nodeId, tableId, fragNo);
  520.       return;
  521.     }
  522.   case DihContinueB::ZSEND_START_TO:
  523.     {
  524.       jam();
  525.       Uint32 takeOverPtrI = signal->theData[1];
  526.       sendStartTo(signal, takeOverPtrI);
  527.       return;
  528.     }
  529.   case DihContinueB::ZSEND_ADD_FRAG:
  530.     {
  531.       jam();
  532.       Uint32 takeOverPtrI = signal->theData[1];
  533.       toCopyFragLab(signal, takeOverPtrI);
  534.       return;
  535.     }
  536.   case DihContinueB::ZSEND_UPDATE_TO:
  537.     {
  538.       jam();
  539.       Uint32 takeOverPtrI = signal->theData[1];
  540.       Uint32 updateState = signal->theData[4];
  541.       sendUpdateTo(signal, takeOverPtrI, updateState);
  542.       return;
  543.     }
  544.   case DihContinueB::ZSEND_END_TO:
  545.     {
  546.       jam();
  547.       Uint32 takeOverPtrI = signal->theData[1];
  548.       sendEndTo(signal, takeOverPtrI);
  549.       return;
  550.     }
  551.   case DihContinueB::ZSEND_CREATE_FRAG:
  552.     {
  553.       jam();
  554.       Uint32 takeOverPtrI = signal->theData[1];
  555.       Uint32 storedType = signal->theData[2];
  556.       Uint32 startGci = signal->theData[3];
  557.       sendCreateFragReq(signal, startGci, storedType, takeOverPtrI);
  558.       return;
  559.     }
  560.   case DihContinueB::WAIT_DROP_TAB_WRITING_TO_FILE:{
  561.     jam();
  562.     TabRecordPtr tabPtr;
  563.     tabPtr.i = signal->theData[1];
  564.     ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  565.     waitDropTabWritingToFile(signal, tabPtr);
  566.     return;
  567.   }
  568.   case DihContinueB::CHECK_WAIT_DROP_TAB_FAILED_LQH:{
  569.     jam();
  570.     Uint32 nodeId = signal->theData[1];
  571.     Uint32 tableId = signal->theData[2];
  572.     checkWaitDropTabFailedLqh(signal, nodeId, tableId);
  573.     return;
  574.   }
  575.   }//switch
  576.   
  577.   ndbrequire(false);
  578.   return;
  579. }//Dbdih::execCONTINUEB()
  580. void Dbdih::execCOPY_GCIREQ(Signal* signal) 
  581. {
  582.   CopyGCIReq * const copyGCI = (CopyGCIReq *)&signal->theData[0];
  583.   jamEntry();
  584.   CopyGCIReq::CopyReason reason = (CopyGCIReq::CopyReason)copyGCI->copyReason;
  585.   const Uint32 tstart = copyGCI->startWord;
  586.   
  587.   ndbrequire(cmasterdihref == signal->senderBlockRef()) ;
  588.   ndbrequire(c_copyGCISlave.m_copyReason  == CopyGCIReq::IDLE);
  589.   ndbrequire(c_copyGCISlave.m_expectedNextWord == tstart);
  590.   ndbrequire(reason != CopyGCIReq::IDLE);
  591.   
  592.   arrGuard(tstart + CopyGCIReq::DATA_SIZE, sizeof(sysfileData)/4);
  593.   for(Uint32 i = 0; i<CopyGCIReq::DATA_SIZE; i++)
  594.     cdata[tstart+i] = copyGCI->data[i];
  595.   
  596.   if ((tstart + CopyGCIReq::DATA_SIZE) >= Sysfile::SYSFILE_SIZE32) {
  597.     jam();
  598.     c_copyGCISlave.m_expectedNextWord = 0;
  599.   } else {
  600.     jam();
  601.     c_copyGCISlave.m_expectedNextWord += CopyGCIReq::DATA_SIZE;
  602.     return;
  603.   }//if
  604.   
  605.   memcpy(sysfileData, cdata, sizeof(sysfileData));
  606.   
  607.   c_copyGCISlave.m_copyReason = reason;
  608.   c_copyGCISlave.m_senderRef  = signal->senderBlockRef();
  609.   c_copyGCISlave.m_senderData = copyGCI->anyData;
  610.   CRASH_INSERTION2(7020, reason==CopyGCIReq::LOCAL_CHECKPOINT);
  611.   CRASH_INSERTION2(7008, reason==CopyGCIReq::GLOBAL_CHECKPOINT);
  612.   /* -------------------------------------------------------------------------*/
  613.   /*     WE SET THE REQUESTER OF THE COPY GCI TO THE CURRENT MASTER. IF THE   */
  614.   /*     CURRENT MASTER WE DO NOT WANT THE NEW MASTER TO RECEIVE CONFIRM OF   */
  615.   /*     SOMETHING HE HAS NOT SENT. THE TAKE OVER MUST BE CAREFUL.            */
  616.   /* -------------------------------------------------------------------------*/
  617.   bool ok = false;
  618.   switch(reason){
  619.   case CopyGCIReq::IDLE:
  620.     ok = true;
  621.     jam();
  622.     ndbrequire(false);
  623.     break;
  624.   case CopyGCIReq::LOCAL_CHECKPOINT: {
  625.     ok = true;
  626.     jam();
  627.     c_lcpState.setLcpStatus(LCP_COPY_GCI, __LINE__);
  628.     c_lcpState.m_masterLcpDihRef = cmasterdihref;
  629.     setNodeInfo(signal);
  630.     break;
  631.   }
  632.   case CopyGCIReq::RESTART: {
  633.     ok = true;
  634.     jam();
  635.     coldgcp = SYSFILE->newestRestorableGCI;
  636.     crestartGci = SYSFILE->newestRestorableGCI;
  637.     Sysfile::setRestartOngoing(SYSFILE->systemRestartBits);
  638.     currentgcp = coldgcp + 1;
  639.     cnewgcp = coldgcp + 1;
  640.     setNodeInfo(signal);
  641.     if ((Sysfile::getLCPOngoing(SYSFILE->systemRestartBits))) {
  642.       jam();
  643.       /* -------------------------------------------------------------------- */
  644.       //  IF THERE WAS A LOCAL CHECKPOINT ONGOING AT THE CRASH MOMENT WE WILL
  645.       //    INVALIDATE THAT LOCAL CHECKPOINT.
  646.       /* -------------------------------------------------------------------- */
  647.       invalidateLcpInfoAfterSr();
  648.     }//if
  649.     break;
  650.   }
  651.   case CopyGCIReq::GLOBAL_CHECKPOINT: {
  652.     ok = true;
  653.     jam();
  654.     cgcpParticipantState = GCP_PARTICIPANT_COPY_GCI_RECEIVED;
  655.     setNodeInfo(signal);
  656.     break;
  657.   }//if
  658.   case CopyGCIReq::INITIAL_START_COMPLETED:
  659.     ok = true;
  660.     jam();
  661.     break;
  662.   }
  663.   ndbrequire(ok);
  664.   
  665.   /* ----------------------------------------------------------------------- */
  666.   /*     WE START BY TRYING TO OPEN THE FIRST RESTORABLE GCI FILE.           */
  667.   /* ----------------------------------------------------------------------- */
  668.   FileRecordPtr filePtr;
  669.   filePtr.i = crestartInfoFile[0];
  670.   ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
  671.   if (filePtr.p->fileStatus == FileRecord::OPEN) {
  672.     jam();
  673.     openingCopyGciSkipInitLab(signal, filePtr);
  674.     return;
  675.   }//if
  676.   openFileRw(signal, filePtr);
  677.   filePtr.p->reqStatus = FileRecord::OPENING_COPY_GCI;
  678.   return;
  679. }//Dbdih::execCOPY_GCIREQ()
  680. void Dbdih::execDICTSTARTCONF(Signal* signal) 
  681. {
  682.   jamEntry();
  683.   Uint32 nodeId = refToNode(signal->getSendersBlockRef());
  684.   if (nodeId != getOwnNodeId()) {
  685.     jam();
  686.     nodeDictStartConfLab(signal);
  687.   } else {
  688.     jam();
  689.     dictStartConfLab(signal);
  690.   }//if
  691. }//Dbdih::execDICTSTARTCONF()
  692. void Dbdih::execFSCLOSECONF(Signal* signal) 
  693. {
  694.   FileRecordPtr filePtr;
  695.   jamEntry();
  696.   filePtr.i = signal->theData[0];
  697.   ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
  698.   filePtr.p->fileStatus = FileRecord::CLOSED;
  699.   FileRecord::ReqStatus status = filePtr.p->reqStatus;
  700.   filePtr.p->reqStatus = FileRecord::IDLE;
  701.   switch (status) {
  702.   case FileRecord::CLOSING_GCP:
  703.     jam();
  704.     closingGcpLab(signal, filePtr);
  705.     break;
  706.   case FileRecord::CLOSING_GCP_CRASH:
  707.     jam();
  708.     closingGcpCrashLab(signal, filePtr);
  709.     break;
  710.   case FileRecord::CLOSING_TABLE_CRASH:
  711.     jam();
  712.     closingTableCrashLab(signal, filePtr);
  713.     break;
  714.   case FileRecord::CLOSING_TABLE_SR:
  715.     jam();
  716.     closingTableSrLab(signal, filePtr);
  717.     break;
  718.   case FileRecord::TABLE_CLOSE:
  719.     jam();
  720.     tableCloseLab(signal, filePtr);
  721.     break;
  722.   case FileRecord::TABLE_CLOSE_DELETE:
  723.     jam();
  724.     tableDeleteLab(signal, filePtr);
  725.     break;
  726.   default:
  727.     ndbrequire(false);
  728.     break;
  729.   }//switch
  730.   return;
  731. }//Dbdih::execFSCLOSECONF()
  732. void Dbdih::execFSCLOSEREF(Signal* signal) 
  733. {
  734.   FileRecordPtr filePtr;
  735.   jamEntry();
  736.   filePtr.i = signal->theData[0];
  737.   ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
  738.   FileRecord::ReqStatus status = filePtr.p->reqStatus;
  739.   filePtr.p->reqStatus = FileRecord::IDLE;
  740.   switch (status) {
  741.   case FileRecord::CLOSING_GCP:
  742.     jam();
  743.     break;
  744.   case FileRecord::CLOSING_GCP_CRASH:
  745.     jam();
  746.     closingGcpCrashLab(signal, filePtr);
  747.     return;
  748.   case FileRecord::CLOSING_TABLE_CRASH:
  749.     jam();
  750.     closingTableCrashLab(signal, filePtr);
  751.     return;
  752.   case FileRecord::CLOSING_TABLE_SR:
  753.     jam();
  754.     break;
  755.   case FileRecord::TABLE_CLOSE:
  756.     jam();
  757.     break;
  758.   case FileRecord::TABLE_CLOSE_DELETE:
  759.     jam();
  760.     break;
  761.   default:
  762.     jam();
  763.     break;
  764.   }//switch
  765.   {
  766.     char msg[100];
  767.     sprintf(msg, "File system close failed during FileRecord status %d", (Uint32)status);
  768.     fsRefError(signal,__LINE__,msg);
  769.   }
  770.   return;
  771. }//Dbdih::execFSCLOSEREF()
  772. void Dbdih::execFSOPENCONF(Signal* signal) 
  773. {
  774.   FileRecordPtr filePtr;
  775.   jamEntry();
  776.   filePtr.i = signal->theData[0];
  777.   ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
  778.   filePtr.p->fileRef = signal->theData[1];
  779.   filePtr.p->fileStatus = FileRecord::OPEN;
  780.   FileRecord::ReqStatus status = filePtr.p->reqStatus;
  781.   filePtr.p->reqStatus = FileRecord::IDLE;
  782.   switch (status) {
  783.   case FileRecord::CREATING_GCP:
  784.     jam();
  785.     creatingGcpLab(signal, filePtr);
  786.     break;
  787.   case FileRecord::OPENING_COPY_GCI:
  788.     jam();
  789.     openingCopyGciSkipInitLab(signal, filePtr);
  790.     break;
  791.   case FileRecord::CREATING_COPY_GCI:
  792.     jam();
  793.     openingCopyGciSkipInitLab(signal, filePtr);
  794.     break;
  795.   case FileRecord::OPENING_GCP:
  796.     jam();
  797.     openingGcpLab(signal, filePtr);
  798.     break;
  799.   case FileRecord::OPENING_TABLE:
  800.     jam();
  801.     openingTableLab(signal, filePtr);
  802.     break;
  803.   case FileRecord::TABLE_CREATE:
  804.     jam();
  805.     tableCreateLab(signal, filePtr);
  806.     break;
  807.   case FileRecord::TABLE_OPEN_FOR_DELETE:
  808.     jam();
  809.     tableOpenLab(signal, filePtr);
  810.     break;
  811.   default:
  812.     ndbrequire(false);
  813.     break;
  814.   }//switch
  815.   return;
  816. }//Dbdih::execFSOPENCONF()
  817. void Dbdih::execFSOPENREF(Signal* signal) 
  818. {
  819.   FileRecordPtr filePtr;
  820.   jamEntry();
  821.   filePtr.i = signal->theData[0];
  822.   ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
  823.   FileRecord::ReqStatus status = filePtr.p->reqStatus;
  824.   filePtr.p->reqStatus = FileRecord::IDLE;
  825.   switch (status) {
  826.   case FileRecord::CREATING_GCP:
  827.     /* --------------------------------------------------------------------- */
  828.     /*   WE DID NOT MANAGE TO CREATE A GLOBAL CHECKPOINT FILE. SERIOUS ERROR */
  829.     /*   WHICH CAUSES A SYSTEM RESTART.                                      */
  830.     /* --------------------------------------------------------------------- */
  831.     jam();
  832.     break;
  833.   case FileRecord::OPENING_COPY_GCI:
  834.     jam();
  835.     openingCopyGciErrorLab(signal, filePtr);
  836.     return;
  837.   case FileRecord::CREATING_COPY_GCI:
  838.     jam();
  839.     break;
  840.   case FileRecord::OPENING_GCP:
  841.     jam();
  842.     openingGcpErrorLab(signal, filePtr);
  843.     return;
  844.   case FileRecord::OPENING_TABLE:
  845.     jam();
  846.     openingTableErrorLab(signal, filePtr);
  847.     return;
  848.   case FileRecord::TABLE_CREATE:
  849.     jam();
  850.     break;
  851.   case FileRecord::TABLE_OPEN_FOR_DELETE:
  852.     jam();
  853.     tableDeleteLab(signal, filePtr);
  854.     return;
  855.   default:
  856.     jam();
  857.     break;
  858.   }//switch
  859.   {
  860.     char msg[100];
  861.     sprintf(msg, "File system open failed during FileRecord status %d", (Uint32)status);
  862.     fsRefError(signal,__LINE__,msg);
  863.   }
  864.   return;
  865. }//Dbdih::execFSOPENREF()
  866. void Dbdih::execFSREADCONF(Signal* signal) 
  867. {
  868.   FileRecordPtr filePtr;
  869.   jamEntry();
  870.   filePtr.i = signal->theData[0];
  871.   ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
  872.   FileRecord::ReqStatus status = filePtr.p->reqStatus;
  873.   filePtr.p->reqStatus = FileRecord::IDLE;
  874.   switch (status) {
  875.   case FileRecord::READING_GCP:
  876.     jam();
  877.     readingGcpLab(signal, filePtr);
  878.     break;
  879.   case FileRecord::READING_TABLE:
  880.     jam();
  881.     readingTableLab(signal, filePtr);
  882.     break;
  883.   default:
  884.     ndbrequire(false);
  885.     break;
  886.   }//switch
  887.   return;
  888. }//Dbdih::execFSREADCONF()
  889. void Dbdih::execFSREADREF(Signal* signal) 
  890. {
  891.   FileRecordPtr filePtr;
  892.   jamEntry();
  893.   filePtr.i = signal->theData[0];
  894.   ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
  895.   FileRecord::ReqStatus status = filePtr.p->reqStatus;
  896.   filePtr.p->reqStatus = FileRecord::IDLE;
  897.   switch (status) {
  898.   case FileRecord::READING_GCP:
  899.     jam();
  900.     readingGcpErrorLab(signal, filePtr);
  901.     return;
  902.   case FileRecord::READING_TABLE:
  903.     jam();
  904.     readingTableErrorLab(signal, filePtr);
  905.     return;
  906.   default:
  907.     break;
  908.   }//switch
  909.   {
  910.     char msg[100];
  911.     sprintf(msg, "File system read failed during FileRecord status %d", (Uint32)status);
  912.     fsRefError(signal,__LINE__,msg);
  913.   }
  914. }//Dbdih::execFSREADREF()
  915. void Dbdih::execFSWRITECONF(Signal* signal) 
  916. {
  917.   FileRecordPtr filePtr;
  918.   jamEntry();
  919.   filePtr.i = signal->theData[0];
  920.   ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
  921.   FileRecord::ReqStatus status = filePtr.p->reqStatus;
  922.   filePtr.p->reqStatus = FileRecord::IDLE;
  923.   switch (status) {
  924.   case FileRecord::WRITING_COPY_GCI:
  925.     jam();
  926.     writingCopyGciLab(signal, filePtr);
  927.     break;
  928.   case FileRecord::WRITE_INIT_GCP:
  929.     jam();
  930.     writeInitGcpLab(signal, filePtr);
  931.     break;
  932.   case FileRecord::TABLE_WRITE:
  933.     jam();
  934.     tableWriteLab(signal, filePtr);
  935.     break;
  936.   default:
  937.     ndbrequire(false);
  938.     break;
  939.   }//switch
  940.   return;
  941. }//Dbdih::execFSWRITECONF()
  942. void Dbdih::execFSWRITEREF(Signal* signal) 
  943. {
  944.   FileRecordPtr filePtr;
  945.   jamEntry();
  946.   filePtr.i = signal->theData[0];
  947.   ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
  948.   FileRecord::ReqStatus status = filePtr.p->reqStatus;
  949.   filePtr.p->reqStatus = FileRecord::IDLE;
  950.   switch (status) {
  951.   case FileRecord::WRITING_COPY_GCI:
  952.     /* --------------------------------------------------------------------- */
  953.     /*  EVEN CREATING THE FILE DID NOT WORK. WE WILL THEN CRASH.             */
  954.     /*  ERROR IN WRITING FILE. WE WILL NOT CONTINUE FROM HERE.               */
  955.     /* --------------------------------------------------------------------- */
  956.     jam();
  957.     break;
  958.   case FileRecord::WRITE_INIT_GCP:
  959.     /* --------------------------------------------------------------------- */
  960.     /*   AN ERROR OCCURRED IN WRITING A GCI FILE WHICH IS A SERIOUS ERROR    */
  961.     /*   THAT CAUSE A SYSTEM RESTART.                                        */
  962.     /* --------------------------------------------------------------------- */
  963.     jam();
  964.     break;
  965.   case FileRecord::TABLE_WRITE:
  966.     jam();
  967.     break;
  968.   default:
  969.     jam();
  970.     break;
  971.   }//switch
  972.   {
  973.     char msg[100];
  974.     sprintf(msg, "File system write failed during FileRecord status %d", (Uint32)status);
  975.     fsRefError(signal,__LINE__,msg);
  976.   }
  977.   return;
  978. }//Dbdih::execFSWRITEREF()
  979. void Dbdih::execGETGCIREQ(Signal* signal) 
  980. {
  981.   jamEntry();
  982.   Uint32 userPtr = signal->theData[0];
  983.   BlockReference userRef = signal->theData[1];
  984.   signal->theData[0] = userPtr;
  985.   signal->theData[1] = SYSFILE->newestRestorableGCI;
  986.   sendSignal(userRef, GSN_GETGCICONF, signal, 2, JBB);
  987. }//Dbdih::execGETGCIREQ()
  988. void Dbdih::execREAD_CONFIG_REQ(Signal* signal) 
  989. {
  990.   const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr();
  991.   Uint32 ref = req->senderRef;
  992.   Uint32 senderData = req->senderData;
  993.   ndbrequire(req->noOfParameters == 0);
  994.   jamEntry();
  995.   const ndb_mgm_configuration_iterator * p = 
  996.     theConfiguration.getOwnConfigIterator();
  997.   ndbrequire(p != 0);
  998.   ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DIH_API_CONNECT, 
  999.        &capiConnectFileSize));
  1000.   ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DIH_CONNECT,&cconnectFileSize));
  1001.   ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DIH_FRAG_CONNECT, 
  1002. &cfragstoreFileSize));
  1003.   ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DIH_REPLICAS, 
  1004. &creplicaFileSize));
  1005.   ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DIH_TABLE, &ctabFileSize))
  1006.     cfileFileSize = (2 * ctabFileSize) + 2;
  1007.   initRecords();
  1008.   initialiseRecordsLab(signal, 0, ref, senderData);
  1009.   return;
  1010. }//Dbdih::execSIZEALT_REP()
  1011. void Dbdih::execSTART_COPYREF(Signal* signal) 
  1012. {
  1013.   jamEntry();
  1014.   ndbrequire(false);
  1015. }//Dbdih::execSTART_COPYREF()
  1016. void Dbdih::execSTART_FRAGCONF(Signal* signal) 
  1017. {
  1018.   (void)signal;  // Don't want compiler warning
  1019.   /* ********************************************************************* */
  1020.   /*  If anyone wants to add functionality in this method, be aware that   */
  1021.   /*  for temporary tables no START_FRAGREQ is sent and therefore no       */
  1022.   /*  START_FRAGCONF signal will be received for those tables!!            */
  1023.   /* ********************************************************************* */
  1024.   jamEntry();
  1025.   return;
  1026. }//Dbdih::execSTART_FRAGCONF()
  1027. void Dbdih::execSTART_MEREF(Signal* signal) 
  1028. {
  1029.   jamEntry();
  1030.   ndbrequire(false);
  1031. }//Dbdih::execSTART_MEREF()
  1032. void Dbdih::execTAB_COMMITREQ(Signal* signal) 
  1033. {
  1034.   TabRecordPtr tabPtr;
  1035.   jamEntry();
  1036.   Uint32 tdictPtr = signal->theData[0];
  1037.   BlockReference tdictBlockref = signal->theData[1];
  1038.   tabPtr.i = signal->theData[2];
  1039.   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  1040.   ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_CREATING);
  1041.   tabPtr.p->tabStatus = TabRecord::TS_ACTIVE;
  1042.   signal->theData[0] = tdictPtr;
  1043.   signal->theData[1] = cownNodeId;
  1044.   signal->theData[2] = tabPtr.i;
  1045.   sendSignal(tdictBlockref, GSN_TAB_COMMITCONF, signal, 3, JBB);
  1046.   return;
  1047. }//Dbdih::execTAB_COMMITREQ()
  1048. /*
  1049.   3.2   S T A N D A R D   S U B P R O G R A M S   I N   P L E X
  1050.   *************************************************************
  1051.   */
  1052. /*
  1053.   3.2.1   S T A R T /  R E S T A R T
  1054.   **********************************
  1055.   */
  1056. /*****************************************************************************/
  1057. /* **********     START / RESTART MODULE                         *************/
  1058. /*****************************************************************************/
  1059. /*
  1060.   3.2.1.1    LOADING   O W N   B L O C K  R E F E R E N C E (ABSOLUTE PHASE 1)
  1061.   *****************************************************************************
  1062.   */
  1063. void Dbdih::execDIH_RESTARTREQ(Signal* signal) 
  1064. {
  1065.   jamEntry();
  1066.   cntrlblockref = signal->theData[0];
  1067.   if(theConfiguration.getInitialStart()){
  1068.     sendSignal(cntrlblockref, GSN_DIH_RESTARTREF, signal, 1, JBB);
  1069.   } else {
  1070.     readGciFileLab(signal);
  1071.   }
  1072.   return;
  1073. }//Dbdih::execDIH_RESTARTREQ()
  1074. void Dbdih::execSTTOR(Signal* signal) 
  1075. {
  1076.   jamEntry();
  1077.   signal->theData[0] = 0;
  1078.   signal->theData[1] = 0;
  1079.   signal->theData[2] = 0;
  1080.   signal->theData[3] = 1;   // Next start phase
  1081.   signal->theData[4] = 255; // Next start phase
  1082.   sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 5, JBB);
  1083.   return;
  1084. }//Dbdih::execSTTOR()
  1085. void Dbdih::initialStartCompletedLab(Signal* signal) 
  1086. {
  1087.   /*-------------------------------------------------------------------------*/
  1088.   /* NOW THAT (RE)START IS COMPLETED WE CAN START THE LCP.*/
  1089.   /*-------------------------------------------------------------------------*/
  1090.   return;
  1091. }//Dbdih::initialStartCompletedLab()
  1092. /*
  1093.  * ***************************************************************************
  1094.  * S E N D I N G   R E P L Y  T O  S T A R T /  R E S T A R T   R E Q U E S T S
  1095.  * ****************************************************************************
  1096.  */
  1097. void Dbdih::ndbsttorry10Lab(Signal* signal, Uint32 _line) 
  1098. {
  1099.   /*-------------------------------------------------------------------------*/
  1100.   // AN NDB START PHASE HAS BEEN COMPLETED. WHEN START PHASE 6 IS COMPLETED WE
  1101.   // RECORD THAT THE SYSTEM IS RUNNING.
  1102.   /*-------------------------------------------------------------------------*/
  1103.   signal->theData[0] = reference();
  1104.   sendSignal(cntrlblockref, GSN_NDB_STTORRY, signal, 1, JBB);
  1105.   return;
  1106. }//Dbdih::ndbsttorry10Lab()
  1107. /*
  1108. ****************************************
  1109. I N T E R N A L  P H A S E S
  1110. ****************************************
  1111. */
  1112. /*---------------------------------------------------------------------------*/
  1113. /*NDB_STTOR                              START SIGNAL AT START/RESTART       */
  1114. /*---------------------------------------------------------------------------*/
  1115. void Dbdih::execNDB_STTOR(Signal* signal) 
  1116. {
  1117.   jamEntry();
  1118.   BlockReference cntrRef = signal->theData[0];    /* SENDERS BLOCK REFERENCE */
  1119.   Uint32 ownNodeId = signal->theData[1];          /* OWN PROCESSOR ID*/
  1120.   Uint32 phase = signal->theData[2];              /* INTERNAL START PHASE*/
  1121.   Uint32 typestart = signal->theData[3];
  1122.   cstarttype = typestart;
  1123.   cstartPhase = phase;
  1124.   switch (phase){
  1125.   case ZNDB_SPH1:
  1126.     jam();
  1127.     /*----------------------------------------------------------------------*/
  1128.     /* Set the delay between local checkpoints in ndb startphase 1.         */
  1129.     /*----------------------------------------------------------------------*/
  1130.     cownNodeId = ownNodeId;
  1131.     /*-----------------------------------------------------------------------*/
  1132.     // Compute all static block references in this node as part of
  1133.     // ndb start phase 1.    
  1134.     /*-----------------------------------------------------------------------*/
  1135.     cntrlblockref = cntrRef;
  1136.     clocaltcblockref = calcTcBlockRef(ownNodeId);
  1137.     clocallqhblockref = calcLqhBlockRef(ownNodeId);
  1138.     cdictblockref = calcDictBlockRef(ownNodeId);
  1139.     ndbsttorry10Lab(signal, __LINE__);
  1140.     break;
  1141.     
  1142.   case ZNDB_SPH2:
  1143.     jam();
  1144.     /*-----------------------------------------------------------------------*/
  1145.     // Set the number of replicas,  maximum is 4 replicas.
  1146.     // Read the ndb nodes from the configuration.
  1147.     /*-----------------------------------------------------------------------*/
  1148.     
  1149.     /*-----------------------------------------------------------------------*/
  1150.     // For node restarts we will also add a request for permission
  1151.     // to continue the system restart.
  1152.     // The permission is given by the master node in the alive set.  
  1153.     /*-----------------------------------------------------------------------*/
  1154.     createMutexes(signal, 0);
  1155.     break;
  1156.     
  1157.   case ZNDB_SPH3:
  1158.     jam();
  1159.     /*-----------------------------------------------------------------------*/
  1160.     // Non-master nodes performing an initial start will execute
  1161.     // the start request here since the
  1162.     // initial start do not synchronise so much from the master.
  1163.     // In the master nodes the start
  1164.     // request will be sent directly to dih (in ndb_startreq) when all
  1165.     // nodes have completed phase 3 of the start.    
  1166.     /*-----------------------------------------------------------------------*/
  1167.     cmasterState = MASTER_IDLE;
  1168.     if(cstarttype == NodeState::ST_INITIAL_START ||
  1169.        cstarttype == NodeState::ST_SYSTEM_RESTART){
  1170.       jam();
  1171.       cmasterState = isMaster() ? MASTER_ACTIVE : MASTER_IDLE;
  1172.     }
  1173.     if (!isMaster() && cstarttype == NodeState::ST_INITIAL_START) {
  1174.       jam();
  1175.       ndbStartReqLab(signal, cntrRef);
  1176.       return;
  1177.     }//if
  1178.     ndbsttorry10Lab(signal, __LINE__);
  1179.     break;
  1180.     
  1181.   case ZNDB_SPH4:
  1182.     jam();
  1183.     c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
  1184.     cmasterTakeOverNode = ZNIL;
  1185.     switch(typestart){
  1186.     case NodeState::ST_INITIAL_START:
  1187.       jam();
  1188.       ndbsttorry10Lab(signal, __LINE__);
  1189.       return;
  1190.     case NodeState::ST_SYSTEM_RESTART:
  1191.       jam();
  1192.       if (isMaster()) {
  1193. jam();
  1194. systemRestartTakeOverLab(signal);
  1195. if (anyActiveTakeOver() && false) {
  1196.   jam();
  1197.   ndbout_c("1 - anyActiveTakeOver == true");
  1198.   return;
  1199. }
  1200.       }
  1201.       ndbsttorry10Lab(signal, __LINE__);
  1202.       return;
  1203.     case NodeState::ST_INITIAL_NODE_RESTART:
  1204.     case NodeState::ST_NODE_RESTART:
  1205.       jam();
  1206.       /***********************************************************************
  1207.        * When starting nodes while system is operational we must be controlled
  1208.        * by the master since only one node restart is allowed at a time. 
  1209.        * When this signal is confirmed the master has also copied the 
  1210.        * dictionary and the distribution information.
  1211.        */
  1212.       StartMeReq * req = (StartMeReq*)&signal->theData[0];
  1213.       req->startingRef = reference();
  1214.       req->startingVersion = 0; // Obsolete
  1215.       sendSignal(cmasterdihref, GSN_START_MEREQ, signal, 
  1216.  StartMeReq::SignalLength, JBB);
  1217.       return;
  1218.     }
  1219.     ndbrequire(false);
  1220.     break;
  1221.   case ZNDB_SPH5:
  1222.     jam();
  1223.     switch(typestart){
  1224.     case NodeState::ST_INITIAL_START:
  1225.     case NodeState::ST_SYSTEM_RESTART:
  1226.       jam();
  1227.       jam();
  1228.       /*---------------------------------------------------------------------*/
  1229.       // WE EXECUTE A LOCAL CHECKPOINT AS A PART OF A SYSTEM RESTART.
  1230.       // THE IDEA IS THAT WE NEED TO
  1231.       // ENSURE THAT WE CAN RECOVER FROM PROBLEMS CAUSED BY MANY NODE
  1232.       // CRASHES THAT CAUSES THE LOG
  1233.       // TO GROW AND THE NUMBER OF LOG ROUNDS TO EXECUTE TO GROW.
  1234.       // THIS CAN OTHERWISE GET US INTO
  1235.       // A SITUATION WHICH IS UNREPAIRABLE. THUS WE EXECUTE A CHECKPOINT
  1236.       // BEFORE ALLOWING ANY TRANSACTIONS TO START.
  1237.       /*---------------------------------------------------------------------*/
  1238.       if (!isMaster()) {
  1239. jam();
  1240. ndbsttorry10Lab(signal, __LINE__);
  1241. return;
  1242.       }//if
  1243.       
  1244.       c_lcpState.immediateLcpStart = true;
  1245.       cwaitLcpSr = true;
  1246.       checkLcpStart(signal, __LINE__);
  1247.       return;
  1248.     case NodeState::ST_NODE_RESTART:
  1249.     case NodeState::ST_INITIAL_NODE_RESTART:
  1250.       jam();
  1251.       signal->theData[0] = cownNodeId;
  1252.       signal->theData[1] = reference();
  1253.       sendSignal(cmasterdihref, GSN_START_COPYREQ, signal, 2, JBB);
  1254.       return;
  1255.     }
  1256.     ndbrequire(false);
  1257.   case ZNDB_SPH6:
  1258.     jam();
  1259.     switch(typestart){
  1260.     case NodeState::ST_INITIAL_START:
  1261.     case NodeState::ST_SYSTEM_RESTART:
  1262.       jam();
  1263.       if(isMaster()){
  1264. jam();
  1265. startGcp(signal);
  1266.       }
  1267.       ndbsttorry10Lab(signal, __LINE__);
  1268.       return;
  1269.     case NodeState::ST_NODE_RESTART:
  1270.     case NodeState::ST_INITIAL_NODE_RESTART:
  1271.       ndbsttorry10Lab(signal, __LINE__);
  1272.       return;
  1273.     }
  1274.     ndbrequire(false);
  1275.     break;
  1276.   default:
  1277.     jam();
  1278.     ndbsttorry10Lab(signal, __LINE__);
  1279.     break;
  1280.   }//switch
  1281. }//Dbdih::execNDB_STTOR()
  1282. void
  1283. Dbdih::createMutexes(Signal * signal, Uint32 count){
  1284.   Callback c = { safe_cast(&Dbdih::createMutex_done), count };
  1285.   switch(count){
  1286.   case 0:{
  1287.     Mutex mutex(signal, c_mutexMgr, c_startLcpMutexHandle);
  1288.     mutex.create(c);
  1289.     return;
  1290.   }
  1291.   case 1:{
  1292.     Mutex mutex(signal, c_mutexMgr, c_switchPrimaryMutexHandle);
  1293.     mutex.create(c);
  1294.     return;
  1295.   }
  1296.   }    
  1297.   signal->theData[0] = reference();
  1298.   sendSignal(cntrlblockref, GSN_READ_NODESREQ, signal, 1, JBB);
  1299. }
  1300. void
  1301. Dbdih::createMutex_done(Signal* signal, Uint32 senderData, Uint32 retVal){
  1302.   jamEntry();
  1303.   ndbrequire(retVal == 0);
  1304.   switch(senderData){
  1305.   case 0:{
  1306.     Mutex mutex(signal, c_mutexMgr, c_startLcpMutexHandle);
  1307.     mutex.release();
  1308.   }
  1309.   case 1:{
  1310.     Mutex mutex(signal, c_mutexMgr, c_switchPrimaryMutexHandle);
  1311.     mutex.release();
  1312.   }
  1313.   }    
  1314.   
  1315.   createMutexes(signal, senderData + 1);
  1316. }
  1317. /*****************************************************************************/
  1318. /* ------------------------------------------------------------------------- */
  1319. /*       WE HAVE BEEN REQUESTED BY NDBCNTR TO PERFORM A RESTART OF THE       */
  1320. /*       DATABASE TABLES.                                                    */
  1321. /*       THIS SIGNAL IS SENT AFTER COMPLETING PHASE 3 IN ALL BLOCKS IN A     */
  1322. /*       SYSTEM RESTART. WE WILL ALSO JUMP TO THIS LABEL FROM PHASE 3 IN AN  */
  1323. /*       INITIAL START.                                                      */
  1324. /* ------------------------------------------------------------------------- */
  1325. /*****************************************************************************/
  1326. void Dbdih::execNDB_STARTREQ(Signal* signal) 
  1327. {
  1328.   jamEntry();
  1329.   BlockReference ref = signal->theData[0];
  1330.   cstarttype = signal->theData[1];
  1331.   ndbStartReqLab(signal, ref);
  1332. }//Dbdih::execNDB_STARTREQ()
  1333. void Dbdih::ndbStartReqLab(Signal* signal, BlockReference ref) 
  1334. {
  1335.   cndbStartReqBlockref = ref;
  1336.   if (cstarttype == NodeState::ST_INITIAL_START) {
  1337.     jam();
  1338.     initRestartInfo();
  1339.     initGciFilesLab(signal);
  1340.     return;
  1341.   }
  1342.   
  1343.   ndbrequire(isMaster());
  1344.   copyGciLab(signal, CopyGCIReq::RESTART); // We have already read the file!
  1345. }//Dbdih::ndbStartReqLab()
  1346. void Dbdih::execREAD_NODESCONF(Signal* signal) 
  1347. {
  1348.   unsigned i;
  1349.   ReadNodesConf * const readNodes = (ReadNodesConf *)&signal->theData[0];
  1350.   jamEntry();
  1351.   Uint32 nodeArray[MAX_NDB_NODES];
  1352.   csystemnodes  = readNodes->noOfNodes;
  1353.   cmasterNodeId = readNodes->masterNodeId;
  1354.   int index = 0;
  1355.   NdbNodeBitmask tmp; tmp.assign(2, readNodes->allNodes);
  1356.   for (i = 1; i < MAX_NDB_NODES; i++){
  1357.     jam();
  1358.     if(tmp.get(i)){
  1359.       jam();
  1360.       nodeArray[index] = i;
  1361.       if(NodeBitmask::get(readNodes->inactiveNodes, i) == false){
  1362.         jam();
  1363.         con_lineNodes++;        
  1364.       }//if      
  1365.       index++;
  1366.     }//if
  1367.   }//for  
  1368.   
  1369.   if(cstarttype == NodeState::ST_SYSTEM_RESTART || 
  1370.      cstarttype == NodeState::ST_NODE_RESTART){
  1371.     for(i = 1; i<MAX_NDB_NODES; i++){
  1372.       const Uint32 stat = Sysfile::getNodeStatus(i, SYSFILE->nodeStatus);
  1373.       if(stat == Sysfile::NS_NotDefined && !tmp.get(i)){
  1374. jam();
  1375. continue;
  1376.       }
  1377.       
  1378.       if(tmp.get(i) && stat != Sysfile::NS_NotDefined){
  1379. jam();
  1380. continue;
  1381.       }
  1382.       char buf[255];
  1383.       BaseString::snprintf(buf, sizeof(buf), 
  1384.        "Illegal configuration change."
  1385.        " Initial start needs to be performed "
  1386.        " when changing no of storage nodes (node %d)", i);
  1387.       progError(__LINE__, 
  1388. ERR_INVALID_CONFIG,
  1389. buf);
  1390.     }
  1391.   }
  1392.   
  1393.   ndbrequire(csystemnodes >= 1 && csystemnodes < MAX_NDB_NODES);  
  1394.   if (cstarttype == NodeState::ST_INITIAL_START) {
  1395.     jam();
  1396.     ndbrequire(cnoReplicas <= csystemnodes);
  1397.     calculateHotSpare();
  1398.     ndbrequire(cnoReplicas <= (csystemnodes - cnoHotSpare));
  1399.   }//if
  1400.   cmasterdihref = calcDihBlockRef(cmasterNodeId);
  1401.   /*-------------------------------------------------------------------------*/
  1402.   /* MAKE THE LIST OF PRN-RECORD WHICH IS ONE OF THE NODES-LIST IN THIS BLOCK*/
  1403.   /*-------------------------------------------------------------------------*/
  1404.   makePrnList(readNodes, nodeArray);
  1405.   if (cstarttype == NodeState::ST_INITIAL_START) {
  1406.     jam();
  1407.     /**----------------------------------------------------------------------
  1408.      * WHEN WE INITIALLY START A DATABASE WE WILL CREATE NODE GROUPS. 
  1409.      * ALL NODES ARE PUT INTO NODE GROUPS ALTHOUGH HOT SPARE NODES ARE PUT 
  1410.      * INTO A SPECIAL NODE GROUP. IN EACH NODE GROUP WE HAVE THE SAME AMOUNT 
  1411.      * OF NODES AS THERE ARE NUMBER OF REPLICAS. 
  1412.      * ONE POSSIBLE USAGE OF NODE GROUPS ARE TO MAKE A NODE GROUP A COMPLETE 
  1413.      * FRAGMENT OF THE DATABASE. THIS MEANS THAT ALL REPLICAS WILL BE STORED
  1414.      * IN THE NODE GROUP.
  1415.      *-----------------------------------------------------------------------*/
  1416.     makeNodeGroups(nodeArray);
  1417.   }//if
  1418.   ndbrequire(checkNodeAlive(cmasterNodeId));
  1419.   if (cstarttype == NodeState::ST_INITIAL_START) {
  1420.     jam();
  1421.     /**-----------------------------------------------------------------------
  1422.      * INITIALISE THE SECOND NODE-LIST AND SET NODE BITS AND SOME NODE STATUS.
  1423.      * VERY CONNECTED WITH MAKE_NODE_GROUPS. CHANGING ONE WILL AFFECT THE 
  1424.      * OTHER AS WELL.
  1425.      *-----------------------------------------------------------------------*/
  1426.     setInitialActiveStatus();
  1427.   } else if (cstarttype == NodeState::ST_SYSTEM_RESTART) {
  1428.     jam();
  1429.     /*empty*/;
  1430.   } else if ((cstarttype == NodeState::ST_NODE_RESTART) || 
  1431.              (cstarttype == NodeState::ST_INITIAL_NODE_RESTART)) {
  1432.     jam();
  1433.     nodeRestartPh2Lab(signal);
  1434.     return;
  1435.   } else {
  1436.     ndbrequire(false);
  1437.   }//if
  1438.   /**------------------------------------------------------------------------
  1439.    * ESTABLISH CONNECTIONS WITH THE OTHER DIH BLOCKS AND INITIALISE THIS 
  1440.    * NODE-LIST THAT HANDLES CONNECTION WITH OTHER DIH BLOCKS. 
  1441.    *-------------------------------------------------------------------------*/
  1442.   ndbsttorry10Lab(signal, __LINE__);
  1443. }//Dbdih::execREAD_NODESCONF()
  1444. /*---------------------------------------------------------------------------*/
  1445. /*                    START NODE LOGIC FOR NODE RESTART                      */
  1446. /*---------------------------------------------------------------------------*/
  1447. void Dbdih::nodeRestartPh2Lab(Signal* signal) 
  1448. {
  1449.   /*------------------------------------------------------------------------*/
  1450.   // REQUEST FOR PERMISSION FROM MASTER TO START A NODE IN AN ALREADY
  1451.   // RUNNING SYSTEM.
  1452.   /*------------------------------------------------------------------------*/
  1453.   StartPermReq * const req = (StartPermReq *)&signal->theData[0];
  1454.   req->blockRef  = reference();
  1455.   req->nodeId    = cownNodeId;
  1456.   req->startType = cstarttype;
  1457.   sendSignal(cmasterdihref, GSN_START_PERMREQ, signal, 3, JBB);
  1458. }//Dbdih::nodeRestartPh2Lab()
  1459. void Dbdih::execSTART_PERMCONF(Signal* signal) 
  1460. {
  1461.   jamEntry();
  1462.   CRASH_INSERTION(7121);
  1463.   Uint32 nodeId = signal->theData[0];
  1464.   cfailurenr = signal->theData[1];
  1465.   ndbrequire(nodeId == cownNodeId);
  1466.   ndbsttorry10Lab(signal, __LINE__);
  1467. }//Dbdih::execSTART_PERMCONF()
  1468. void Dbdih::execSTART_PERMREF(Signal* signal) 
  1469. {
  1470.   jamEntry();
  1471.   Uint32 errorCode = signal->theData[1];
  1472.   if (errorCode == ZNODE_ALREADY_STARTING_ERROR) {
  1473.     jam();
  1474.     /*-----------------------------------------------------------------------*/
  1475.     // The master was busy adding another node. We will wait for a second and
  1476.     // try again.
  1477.     /*-----------------------------------------------------------------------*/
  1478.     signal->theData[0] = DihContinueB::ZSTART_PERMREQ_AGAIN;
  1479.     sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 3000, 1);
  1480.     return;
  1481.   }//if
  1482.   /*------------------------------------------------------------------------*/
  1483.   // Some node process in another node involving our node was still active. We
  1484.   // will recover from this by crashing here. 
  1485.   // This is controlled restart using the
  1486.   // already existing features of node crashes. It is not a bug getting here.
  1487.   /*-------------------------------------------------------------------------*/
  1488.   ndbrequire(false);
  1489.   return;
  1490. }//Dbdih::execSTART_PERMREF()
  1491. /*---------------------------------------------------------------------------*/
  1492. /*       THIS SIGNAL IS RECEIVED IN THE STARTING NODE WHEN THE START_MEREQ   */
  1493. /*       HAS BEEN EXECUTED IN THE MASTER NODE.                               */
  1494. /*---------------------------------------------------------------------------*/
  1495. void Dbdih::execSTART_MECONF(Signal* signal) 
  1496. {
  1497.   jamEntry();
  1498.   StartMeConf * const startMe = (StartMeConf *)&signal->theData[0];  
  1499.   Uint32 nodeId = startMe->startingNodeId;
  1500.   const Uint32 startWord = startMe->startWord;
  1501.   Uint32 i;
  1502.   
  1503.   CRASH_INSERTION(7130);
  1504.   ndbrequire(nodeId == cownNodeId);
  1505.   arrGuard(startWord + StartMeConf::DATA_SIZE, sizeof(cdata)/4);
  1506.   for(i = 0; i < StartMeConf::DATA_SIZE; i++)
  1507.     cdata[startWord+i] = startMe->data[i];
  1508.   
  1509.   if(startWord + StartMeConf::DATA_SIZE < Sysfile::SYSFILE_SIZE32){
  1510.     jam();
  1511.     /**
  1512.      * We are still waiting for data
  1513.      */
  1514.     return;
  1515.   }
  1516.   jam();
  1517.   /**
  1518.    * Copy into sysfile
  1519.    *
  1520.    * But dont copy lastCompletedGCI:s
  1521.    */
  1522.   Uint32 tempGCP[MAX_NDB_NODES];
  1523.   for(i = 0; i < MAX_NDB_NODES; i++)
  1524.     tempGCP[i] = SYSFILE->lastCompletedGCI[i];
  1525.   for(i = 0; i < Sysfile::SYSFILE_SIZE32; i++)
  1526.     sysfileData[i] = cdata[i];
  1527.   for(i = 0; i < MAX_NDB_NODES; i++)
  1528.     SYSFILE->lastCompletedGCI[i] = tempGCP[i];
  1529.   setNodeActiveStatus();
  1530.   setNodeGroups();
  1531.   ndbsttorry10Lab(signal, __LINE__);
  1532. }//Dbdih::execSTART_MECONF()
  1533. void Dbdih::execSTART_COPYCONF(Signal* signal) 
  1534. {
  1535.   jamEntry();
  1536.   Uint32 nodeId = signal->theData[0];
  1537.   ndbrequire(nodeId == cownNodeId);
  1538.   CRASH_INSERTION(7132);
  1539.   ndbsttorry10Lab(signal, __LINE__);
  1540.   return;
  1541. }//Dbdih::execSTART_COPYCONF()
  1542. /*---------------------------------------------------------------------------*/
  1543. /*                    MASTER LOGIC FOR NODE RESTART                          */
  1544. /*---------------------------------------------------------------------------*/
  1545. /*                    NODE RESTART PERMISSION REQUEST                        */
  1546. /*---------------------------------------------------------------------------*/
  1547. // A REQUEST FROM A STARTING NODE TO PERFORM A NODE RESTART. IF NO OTHER NODE
  1548. // IS ACTIVE IN PERFORMING A NODE RESTART AND THERE ARE NO ACTIVE PROCESSES IN
  1549. // THIS NODE INVOLVING THE STARTING NODE  THIS REQUEST WILL BE GRANTED.
  1550. /*---------------------------------------------------------------------------*/
  1551. void Dbdih::execSTART_PERMREQ(Signal* signal)
  1552. {
  1553.   StartPermReq * const req = (StartPermReq*)&signal->theData[0];  
  1554.   jamEntry();
  1555.   const BlockReference retRef = req->blockRef;
  1556.   const Uint32 nodeId   = req->nodeId;
  1557.   const Uint32 typeStart = req->startType;
  1558.   
  1559.   CRASH_INSERTION(7122);
  1560.   ndbrequire(isMaster());
  1561.   ndbrequire(refToNode(retRef) == nodeId);
  1562.   if ((c_nodeStartMaster.activeState) ||
  1563.       (c_nodeStartMaster.wait != ZFALSE)) {
  1564.     jam();
  1565.     signal->theData[0] = nodeId;
  1566.     signal->theData[1] = ZNODE_ALREADY_STARTING_ERROR;
  1567.     sendSignal(retRef, GSN_START_PERMREF, signal, 2, JBB);
  1568.     return;
  1569.   }//if
  1570.   if (getNodeStatus(nodeId) != NodeRecord::DEAD){
  1571.     ndbout << "nodeStatus in START_PERMREQ = " 
  1572.    << (Uint32) getNodeStatus(nodeId) << endl;
  1573.     ndbrequire(false);
  1574.   }//if
  1575.   /*----------------------------------------------------------------------
  1576.    * WE START THE INCLUSION PROCEDURE 
  1577.    * ---------------------------------------------------------------------*/
  1578.   c_nodeStartMaster.failNr   = cfailurenr;
  1579.   c_nodeStartMaster.wait     = ZFALSE;
  1580.   c_nodeStartMaster.startInfoErrorCode = 0;
  1581.   c_nodeStartMaster.startNode = nodeId;
  1582.   c_nodeStartMaster.activeState = true;
  1583.   c_nodeStartMaster.m_outstandingGsn =  GSN_START_INFOREQ;
  1584.   
  1585.   setNodeStatus(nodeId, NodeRecord::STARTING);
  1586.   /**
  1587.    * But if it's a NodeState::ST_INITIAL_NODE_RESTART
  1588.    *
  1589.    * We first have to clear LCP's
  1590.    * For normal node restart we simply ensure that all nodes
  1591.    * are informed of the node restart
  1592.    */
  1593.   StartInfoReq *const r =(StartInfoReq*)&signal->theData[0];
  1594.   r->startingNodeId = nodeId;
  1595.   r->typeStart = typeStart;
  1596.   r->systemFailureNo = cfailurenr;
  1597.   sendLoopMacro(START_INFOREQ, sendSTART_INFOREQ);
  1598. }//Dbdih::execSTART_PERMREQ()
  1599. void Dbdih::execSTART_INFOREF(Signal* signal)
  1600. {
  1601.   StartInfoRef * ref = (StartInfoRef*)&signal->theData[0];
  1602.   if (getNodeStatus(ref->startingNodeId) != NodeRecord::STARTING) {
  1603.     jam();
  1604.     return;
  1605.   }//if
  1606.   ndbrequire(c_nodeStartMaster.startNode == ref->startingNodeId);
  1607.   c_nodeStartMaster.startInfoErrorCode = ref->errorCode;
  1608.   startInfoReply(signal, ref->sendingNodeId);
  1609. }//Dbdih::execSTART_INFOREF()
  1610. void Dbdih::execSTART_INFOCONF(Signal* signal)
  1611. {
  1612.   jamEntry();
  1613.   StartInfoConf * conf = (StartInfoConf*)&signal->theData[0];
  1614.   if (getNodeStatus(conf->startingNodeId) != NodeRecord::STARTING) {
  1615.     jam();
  1616.     return;
  1617.   }//if
  1618.   ndbrequire(c_nodeStartMaster.startNode == conf->startingNodeId);
  1619.   startInfoReply(signal, conf->sendingNodeId);
  1620. }//Dbdih::execSTART_INFOCONF()
  1621. void Dbdih::startInfoReply(Signal* signal, Uint32 nodeId)
  1622. {
  1623.   receiveLoopMacro(START_INFOREQ, nodeId);
  1624.   /**
  1625.    * We're finished with the START_INFOREQ's 
  1626.    */
  1627.   if (c_nodeStartMaster.startInfoErrorCode == 0) {
  1628.     jam();
  1629.     /**
  1630.      * Everything has been a success so far
  1631.      */
  1632.     StartPermConf * conf = (StartPermConf*)&signal->theData[0];
  1633.     conf->startingNodeId = c_nodeStartMaster.startNode;
  1634.     conf->systemFailureNo = cfailurenr;
  1635.     sendSignal(calcDihBlockRef(c_nodeStartMaster.startNode), 
  1636.        GSN_START_PERMCONF, signal, StartPermConf::SignalLength, JBB);
  1637.     c_nodeStartMaster.m_outstandingGsn = GSN_START_PERMCONF;
  1638.   } else {
  1639.     jam();
  1640.     StartPermRef * ref = (StartPermRef*)&signal->theData[0];
  1641.     ref->startingNodeId = c_nodeStartMaster.startNode;
  1642.     ref->errorCode = c_nodeStartMaster.startInfoErrorCode;
  1643.     sendSignal(calcDihBlockRef(c_nodeStartMaster.startNode), 
  1644.        GSN_START_PERMREF, signal, StartPermRef::SignalLength, JBB);
  1645.     nodeResetStart();
  1646.   }//if
  1647. }//Dbdih::startInfoReply()
  1648. /*---------------------------------------------------------------------------*/
  1649. /*                    NODE RESTART CONTINUE REQUEST                          */
  1650. /*---------------------------------------------------------------------------*/
  1651. // THIS SIGNAL AND THE CODE BELOW IS EXECUTED BY THE MASTER WHEN IT HAS BEEN
  1652. // REQUESTED TO START UP A NEW NODE. The master instructs the starting node
  1653. // how to set up its log for continued execution.
  1654. /*---------------------------------------------------------------------------*/
  1655. void Dbdih::execSTART_MEREQ(Signal* signal) 
  1656. {
  1657.   StartMeReq * req = (StartMeReq*)&signal->theData[0];
  1658.   jamEntry();
  1659.   const BlockReference Tblockref = req->startingRef;
  1660.   const Uint32 Tnodeid = refToNode(Tblockref);
  1661.   ndbrequire(isMaster());
  1662.   ndbrequire(c_nodeStartMaster.startNode == Tnodeid);
  1663.   ndbrequire(getNodeStatus(Tnodeid) == NodeRecord::STARTING);
  1664.   
  1665.   sendSTART_RECREQ(signal, Tnodeid);
  1666. }//Dbdih::execSTART_MEREQ()
  1667. void Dbdih::nodeRestartStartRecConfLab(Signal* signal) 
  1668. {
  1669.   c_nodeStartMaster.blockLcp = true;
  1670.   if ((c_lcpState.lcpStatus != LCP_STATUS_IDLE) &&
  1671.       (c_lcpState.lcpStatus != LCP_TCGET)) {
  1672.     jam();
  1673.     /*-----------------------------------------------------------------------*/
  1674.     // WE WILL NOT ALLOW A NODE RESTART TO COME IN WHEN A LOCAL CHECKPOINT IS
  1675.     // ONGOING. IT WOULD COMPLICATE THE LCP PROTOCOL TOO MUCH. WE WILL ADD THIS
  1676.     // LATER.
  1677.     /*-----------------------------------------------------------------------*/
  1678.     return;
  1679.   }//if
  1680.   lcpBlockedLab(signal);
  1681. }//Dbdih::nodeRestartStartRecConfLab()
  1682. void Dbdih::lcpBlockedLab(Signal* signal) 
  1683. {
  1684.   ndbrequire(getNodeStatus(c_nodeStartMaster.startNode)==NodeRecord::STARTING);
  1685.   /*------------------------------------------------------------------------*/
  1686.   // NOW WE HAVE COPIED ALL INFORMATION IN DICT WE ARE NOW READY TO COPY ALL
  1687.   // INFORMATION IN DIH TO THE NEW NODE.
  1688.   /*------------------------------------------------------------------------*/
  1689.   c_nodeStartMaster.wait = 10;
  1690.   signal->theData[0] = DihContinueB::ZCOPY_NODE;
  1691.   signal->theData[1] = 0;
  1692.   sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
  1693.   c_nodeStartMaster.m_outstandingGsn = GSN_COPY_TABREQ;
  1694. }//Dbdih::lcpBlockedLab()
  1695. void Dbdih::nodeDictStartConfLab(Signal* signal) 
  1696. {
  1697.   /*-------------------------------------------------------------------------*/
  1698.   // NOW WE HAVE COPIED BOTH DIH AND DICT INFORMATION. WE ARE NOW READY TO
  1699.   // INTEGRATE THE NODE INTO THE LCP AND GCP PROTOCOLS AND TO ALLOW UPDATES OF
  1700.   // THE DICTIONARY AGAIN.
  1701.   /*-------------------------------------------------------------------------*/
  1702.   c_nodeStartMaster.wait = ZFALSE;
  1703.   c_nodeStartMaster.blockGcp = true;
  1704.   if (cgcpStatus != GCP_READY) {
  1705.     /*-----------------------------------------------------------------------*/
  1706.     // The global checkpoint is executing. Wait until it is completed before we
  1707.     // continue processing the node recovery.
  1708.     /*-----------------------------------------------------------------------*/
  1709.     jam();
  1710.     return;
  1711.   }//if
  1712.   gcpBlockedLab(signal);
  1713.   /*-----------------------------------------------------------------*/
  1714.   // Report that node restart has completed copy of dictionary.
  1715.   /*-----------------------------------------------------------------*/
  1716.   signal->theData[0] = EventReport::NR_CopyDict;
  1717.   sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB);
  1718. }//Dbdih::nodeDictStartConfLab()
  1719. void Dbdih::dihCopyCompletedLab(Signal* signal)
  1720. {
  1721.   BlockReference ref = calcDictBlockRef(c_nodeStartMaster.startNode);
  1722.   DictStartReq * req = (DictStartReq*)&signal->theData[0];
  1723.   req->restartGci = cnewgcp;
  1724.   req->senderRef = reference();
  1725.   sendSignal(ref, GSN_DICTSTARTREQ,
  1726.              signal, DictStartReq::SignalLength, JBB);
  1727.   c_nodeStartMaster.m_outstandingGsn = GSN_DICTSTARTREQ;
  1728.   c_nodeStartMaster.wait = 0;
  1729. }//Dbdih::dihCopyCompletedLab()
  1730. void Dbdih::gcpBlockedLab(Signal* signal)
  1731. {
  1732.   /*-----------------------------------------------------------------*/
  1733.   // Report that node restart has completed copy of distribution info.
  1734.   /*-----------------------------------------------------------------*/
  1735.   signal->theData[0] = EventReport::NR_CopyDistr;
  1736.   sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB);
  1737.   /**
  1738.    * The node DIH will be part of LCP
  1739.    */
  1740.   NodeRecordPtr nodePtr;
  1741.   nodePtr.i = c_nodeStartMaster.startNode;
  1742.   ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
  1743.   nodePtr.p->m_inclDihLcp = true;
  1744.   
  1745.   /*-------------------------------------------------------------------------*/
  1746.   // NOW IT IS TIME TO INFORM ALL OTHER NODES IN THE CLUSTER OF THE STARTED
  1747.   // NODE SUCH THAT THEY ALSO INCLUDE THE NODE IN THE NODE LISTS AND SO FORTH.
  1748.   /*------------------------------------------------------------------------*/
  1749.   sendLoopMacro(INCL_NODEREQ, sendINCL_NODEREQ);
  1750.   /*-------------------------------------------------------------------------*/
  1751.   // We also need to send to the starting node to ensure he is aware of the
  1752.   // global checkpoint id and the correct state. We do not wait for any reply
  1753.   // since the starting node will not send any.
  1754.   /*-------------------------------------------------------------------------*/
  1755.   sendINCL_NODEREQ(signal, c_nodeStartMaster.startNode);
  1756. }//Dbdih::gcpBlockedLab()
  1757. /*---------------------------------------------------------------------------*/
  1758. // THIS SIGNAL IS EXECUTED IN BOTH SLAVES AND IN THE MASTER
  1759. /*---------------------------------------------------------------------------*/
  1760. void Dbdih::execINCL_NODECONF(Signal* signal) 
  1761. {
  1762.   Uint32 TsendNodeId;
  1763.   Uint32 TstartNode_or_blockref;
  1764.   
  1765.   jamEntry();
  1766.   TstartNode_or_blockref = signal->theData[0];
  1767.   TsendNodeId = signal->theData[1];
  1768.   if (TstartNode_or_blockref == clocallqhblockref) {
  1769.     jam();
  1770.     /*-----------------------------------------------------------------------*/
  1771.     // THIS SIGNAL CAME FROM THE LOCAL LQH BLOCK. 
  1772.     // WE WILL NOW SEND INCLUDE TO THE TC BLOCK.
  1773.     /*-----------------------------------------------------------------------*/
  1774.     signal->theData[0] = reference();
  1775.     signal->theData[1] = c_nodeStartSlave.nodeId;
  1776.     sendSignal(clocaltcblockref, GSN_INCL_NODEREQ, signal, 2, JBB);
  1777.     return;
  1778.   }//if
  1779.   if (TstartNode_or_blockref == clocaltcblockref) {
  1780.     jam();
  1781.     /*----------------------------------------------------------------------*/
  1782.     // THIS SIGNAL CAME FROM THE LOCAL LQH BLOCK. 
  1783.     // WE WILL NOW SEND INCLUDE TO THE DICT BLOCK.
  1784.     /*----------------------------------------------------------------------*/
  1785.     signal->theData[0] = reference();
  1786.     signal->theData[1] = c_nodeStartSlave.nodeId;
  1787.     sendSignal(cdictblockref, GSN_INCL_NODEREQ, signal, 2, JBB);
  1788.     return;
  1789.   }//if
  1790.   if (TstartNode_or_blockref == cdictblockref) {
  1791.     jam();
  1792.     /*-----------------------------------------------------------------------*/
  1793.     // THIS SIGNAL CAME FROM THE LOCAL DICT BLOCK. WE WILL NOW SEND CONF TO THE
  1794.     // BACKUP.
  1795.     /*-----------------------------------------------------------------------*/
  1796.     signal->theData[0] = reference();
  1797.     signal->theData[1] = c_nodeStartSlave.nodeId;
  1798.     sendSignal(BACKUP_REF, GSN_INCL_NODEREQ, signal, 2, JBB);
  1799.     
  1800.     // Suma will not send response to this for now, later...
  1801.     sendSignal(SUMA_REF, GSN_INCL_NODEREQ, signal, 2, JBB);
  1802.     return;
  1803.   }//if
  1804.   if (TstartNode_or_blockref == numberToRef(BACKUP, getOwnNodeId())){
  1805.     jam();
  1806.     signal->theData[0] = c_nodeStartSlave.nodeId;
  1807.     signal->theData[1] = cownNodeId;
  1808.     sendSignal(cmasterdihref, GSN_INCL_NODECONF, signal, 2, JBB);
  1809.     c_nodeStartSlave.nodeId = 0;
  1810.     return;
  1811.   }
  1812.   
  1813.   ndbrequire(cmasterdihref = reference());
  1814.   receiveLoopMacro(INCL_NODEREQ, TsendNodeId);
  1815.   CRASH_INSERTION(7128);
  1816.   /*-------------------------------------------------------------------------*/
  1817.   // Now that we have included the starting node in the node lists in the
  1818.   // various blocks we are ready to start the global checkpoint protocol
  1819.   /*------------------------------------------------------------------------*/
  1820.   c_nodeStartMaster.wait = 11;
  1821.   c_nodeStartMaster.blockGcp = false;
  1822.   signal->theData[0] = reference();
  1823.   sendSignal(reference(), GSN_UNBLO_DICTCONF, signal, 1, JBB);
  1824. }//Dbdih::execINCL_NODECONF()
  1825. void Dbdih::execUNBLO_DICTCONF(Signal* signal) 
  1826. {
  1827.   jamEntry();
  1828.   c_nodeStartMaster.wait = ZFALSE;
  1829.   if (!c_nodeStartMaster.activeState) {
  1830.     jam();
  1831.     return;
  1832.   }//if
  1833.   CRASH_INSERTION(7129);
  1834.   /**-----------------------------------------------------------------------
  1835.    * WE HAVE NOW PREPARED IT FOR INCLUSION IN THE LCP PROTOCOL. 
  1836.    * WE CAN NOW START THE LCP PROTOCOL AGAIN. 
  1837.    * WE HAVE ALSO MADE THIS FOR THE GCP PROTOCOL. 
  1838.    * WE ARE READY TO START THE PROTOCOLS AND RESPOND TO THE START REQUEST 
  1839.    * FROM THE STARTING NODE. 
  1840.    *------------------------------------------------------------------------*/
  1841.   
  1842.   StartMeConf * const startMe = (StartMeConf *)&signal->theData[0];
  1843.   
  1844.   const Uint32 wordPerSignal = StartMeConf::DATA_SIZE;
  1845.   const int noOfSignals = ((Sysfile::SYSFILE_SIZE32 + (wordPerSignal - 1)) /
  1846.                            wordPerSignal);
  1847.   
  1848.   startMe->startingNodeId = c_nodeStartMaster.startNode;
  1849.   startMe->startWord = 0;
  1850.   
  1851.   const Uint32 ref = calcDihBlockRef(c_nodeStartMaster.startNode);
  1852.   for(int i = 0; i < noOfSignals; i++){
  1853.     jam();
  1854.     { // Do copy
  1855.       const int startWord = startMe->startWord;
  1856.       for(Uint32 j = 0; j < wordPerSignal; j++){
  1857.         startMe->data[j] = sysfileData[j+startWord];
  1858.       }
  1859.     }
  1860.     sendSignal(ref, GSN_START_MECONF, signal, StartMeConf::SignalLength, JBB);
  1861.     startMe->startWord += wordPerSignal;
  1862.   }//for
  1863.   c_nodeStartMaster.m_outstandingGsn = GSN_START_MECONF;
  1864. }//Dbdih::execUNBLO_DICTCONF()
  1865. /*---------------------------------------------------------------------------*/
  1866. /*                    NODE RESTART COPY REQUEST                              */
  1867. /*---------------------------------------------------------------------------*/
  1868. // A NODE RESTART HAS REACHED ITS FINAL PHASE WHEN THE DATA IS TO BE COPIED
  1869. // TO THE NODE. START_COPYREQ IS EXECUTED BY THE MASTER NODE.
  1870. /*---------------------------------------------------------------------------*/
  1871. void Dbdih::execSTART_COPYREQ(Signal* signal) 
  1872. {
  1873.   jamEntry();
  1874.   Uint32 startNodeId = signal->theData[0];
  1875.   //BlockReference startingRef = signal->theData[1];
  1876.   ndbrequire(c_nodeStartMaster.startNode == startNodeId);
  1877.   /*-------------------------------------------------------------------------*/
  1878.   // REPORT Copy process of node restart is now about to start up.
  1879.   /*-------------------------------------------------------------------------*/
  1880.   signal->theData[0] = EventReport::NR_CopyFragsStarted;
  1881.   signal->theData[1] = startNodeId;
  1882.   sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
  1883.   CRASH_INSERTION(7131);
  1884.   nodeRestartTakeOver(signal, startNodeId);
  1885.   //  BlockReference ref = calcQmgrBlockRef(startNodeId);
  1886.   //  signal->theData[0] = cownNodeId;
  1887.   // Remove comments as soon as I open up the Qmgr block
  1888.   // TODO_RONM
  1889.   //  sendSignal(ref, GSN_ALLOW_NODE_CRASHORD, signal, 1, JBB);
  1890. }//Dbdih::execSTART_COPYREQ()
  1891. /*---------------------------------------------------------------------------*/
  1892. /*                    SLAVE LOGIC FOR NODE RESTART                           */
  1893. /*---------------------------------------------------------------------------*/
  1894. void Dbdih::execSTART_INFOREQ(Signal* signal)
  1895. {
  1896.   jamEntry();
  1897.   StartInfoReq *const req =(StartInfoReq*)&signal->theData[0];
  1898.   Uint32 startNode = req->startingNodeId;
  1899.   if (cfailurenr != req->systemFailureNo) {
  1900.     jam();
  1901.     //---------------------------------------------------------------
  1902.     // A failure occurred since master sent this request. We will ignore
  1903.     // this request since the node is already dead that is starting.
  1904.     //---------------------------------------------------------------
  1905.     return;
  1906.   }//if
  1907.   CRASH_INSERTION(7123);
  1908.   if (isMaster()) {
  1909.     jam();
  1910.     ndbrequire(getNodeStatus(startNode) == NodeRecord::STARTING);
  1911.   } else {
  1912.     jam();
  1913.     ndbrequire(getNodeStatus(startNode) == NodeRecord::DEAD);
  1914.   }//if
  1915.   if ((!getAllowNodeStart(startNode)) ||
  1916.       (c_nodeStartSlave.nodeId != 0) ||
  1917.       (ERROR_INSERTED(7124))) {
  1918.     jam();
  1919.     StartInfoRef *const ref =(StartInfoRef*)&signal->theData[0];
  1920.     ref->startingNodeId = startNode;
  1921.     ref->sendingNodeId = cownNodeId;
  1922.     ref->errorCode = ZNODE_START_DISALLOWED_ERROR;
  1923.     sendSignal(cmasterdihref, GSN_START_INFOREF, signal, 
  1924.        StartInfoRef::SignalLength, JBB);
  1925.     return;
  1926.   }//if
  1927.   setNodeStatus(startNode, NodeRecord::STARTING);
  1928.   if (req->typeStart == NodeState::ST_INITIAL_NODE_RESTART) {
  1929.     jam();
  1930.     setAllowNodeStart(startNode, false);
  1931.     invalidateNodeLCP(signal, startNode, 0);
  1932.   } else {
  1933.     jam();
  1934.     StartInfoConf * c = (StartInfoConf*)&signal->theData[0];
  1935.     c->sendingNodeId = cownNodeId;
  1936.     c->startingNodeId = startNode;
  1937.     sendSignal(cmasterdihref, GSN_START_INFOCONF, signal,
  1938.        StartInfoConf::SignalLength, JBB);
  1939.     return;
  1940.   }//if
  1941. }//Dbdih::execSTART_INFOREQ()
  1942. void Dbdih::execINCL_NODEREQ(Signal* signal) 
  1943. {
  1944.   jamEntry();
  1945.   Uint32 retRef = signal->theData[0];
  1946.   Uint32 nodeId = signal->theData[1];
  1947.   Uint32 tnodeStartFailNr = signal->theData[2];
  1948.   currentgcp = signal->theData[4];
  1949.   CRASH_INSERTION(7127);
  1950.   cnewgcp = currentgcp;
  1951.   coldgcp = currentgcp -  1;
  1952.   if (!isMaster()) {
  1953.     jam();
  1954.     /*-----------------------------------------------------------------------*/
  1955.     // We don't want to change the state of the master since he can be in the
  1956.     // state LCP_TCGET at this time.
  1957.     /*-----------------------------------------------------------------------*/
  1958.     c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
  1959.   }//if
  1960.   /*-------------------------------------------------------------------------*/
  1961.   // When a node is restarted we must ensure that a lcp will be run
  1962.   // as soon as possible and the reset the delay according to the original
  1963.   // configuration. 
  1964.   // Without an initial local checkpoint the new node will not be available.
  1965.   /*-------------------------------------------------------------------------*/
  1966.   if (getOwnNodeId() == nodeId) {
  1967.     jam();
  1968.     /*-----------------------------------------------------------------------*/
  1969.     // We are the starting node. We came here only to set the global checkpoint
  1970.     // id's and the lcp status.
  1971.     /*-----------------------------------------------------------------------*/
  1972.     CRASH_INSERTION(7171);
  1973.     return;
  1974.   }//if
  1975.   if (getNodeStatus(nodeId) != NodeRecord::STARTING) {
  1976.     jam();
  1977.     return;
  1978.   }//if
  1979.   ndbrequire(cfailurenr == tnodeStartFailNr);
  1980.   ndbrequire (c_nodeStartSlave.nodeId == 0);
  1981.   c_nodeStartSlave.nodeId = nodeId;
  1982.   
  1983.   ndbrequire (retRef == cmasterdihref);
  1984.   NodeRecordPtr nodePtr;
  1985.   nodePtr.i = nodeId;
  1986.   ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
  1987.   Sysfile::ActiveStatus TsaveState = nodePtr.p->activeStatus;
  1988.   Uint32 TnodeGroup = nodePtr.p->nodeGroup;
  1989.   new (nodePtr.p) NodeRecord();
  1990.   nodePtr.p->nodeGroup = TnodeGroup;
  1991.   nodePtr.p->activeStatus = TsaveState;
  1992.   nodePtr.p->nodeStatus = NodeRecord::ALIVE;
  1993.   nodePtr.p->useInTransactions = true;
  1994.   nodePtr.p->m_inclDihLcp = true;
  1995.   removeDeadNode(nodePtr);
  1996.   insertAlive(nodePtr);
  1997.   con_lineNodes++;
  1998.   /*-------------------------------------------------------------------------*/
  1999.   //      WE WILL ALSO SEND THE INCLUDE NODE REQUEST TO THE LOCAL LQH BLOCK.
  2000.   /*-------------------------------------------------------------------------*/
  2001.   signal->theData[0] = reference();
  2002.   signal->theData[1] = nodeId;
  2003.   signal->theData[2] = currentgcp;
  2004.   sendSignal(clocallqhblockref, GSN_INCL_NODEREQ, signal, 3, JBB);
  2005. }//Dbdih::execINCL_NODEREQ()
  2006. /* ------------------------------------------------------------------------- */
  2007. // execINCL_NODECONF() is found in the master logic part since it is used by
  2008. // both the master and the slaves.
  2009. /* ------------------------------------------------------------------------- */
  2010. /*****************************************************************************/
  2011. /***********     TAKE OVER DECISION  MODULE                      *************/
  2012. /*****************************************************************************/
  2013. // This module contains the subroutines that take the decision whether to take
  2014. // over a node now or not.
  2015. /* ------------------------------------------------------------------------- */
  2016. /*                       MASTER LOGIC FOR SYSTEM RESTART                     */
  2017. /* ------------------------------------------------------------------------- */
  2018. // WE ONLY COME HERE IF WE ARE THE MASTER AND WE ARE PERFORMING A SYSTEM
  2019. // RESTART. WE ALSO COME HERE DURING THIS SYSTEM RESTART ONE TIME PER NODE
  2020. // THAT NEEDS TAKE OVER.
  2021. /*---------------------------------------------------------------------------*/
  2022. // WE CHECK IF ANY NODE NEEDS TO BE TAKEN OVER AND THE TAKE OVER HAS NOT YET
  2023. // BEEN STARTED OR COMPLETED.
  2024. /*---------------------------------------------------------------------------*/
  2025. void
  2026. Dbdih::systemRestartTakeOverLab(Signal* signal) 
  2027. {
  2028.   NodeRecordPtr nodePtr;
  2029.   for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
  2030.     jam();
  2031.     ptrAss(nodePtr, nodeRecord);
  2032.     switch (nodePtr.p->activeStatus) {
  2033.     case Sysfile::NS_Active:
  2034.     case Sysfile::NS_ActiveMissed_1:
  2035.       jam();
  2036.       break;
  2037.       /*---------------------------------------------------------------------*/
  2038.       // WE HAVE NOT REACHED A STATE YET WHERE THIS NODE NEEDS TO BE TAKEN OVER
  2039.       /*---------------------------------------------------------------------*/
  2040.     case Sysfile::NS_ActiveMissed_2:
  2041.     case Sysfile::NS_NotActive_NotTakenOver:
  2042.       jam();
  2043.       /*---------------------------------------------------------------------*/
  2044.       // THIS NODE IS IN TROUBLE. 
  2045.       // WE MUST SUCCEED WITH A LOCAL CHECKPOINT WITH THIS NODE TO REMOVE THE 
  2046.       // DANGER. IF THE NODE IS NOT ALIVE THEN THIS WILL NOT BE
  2047.       // POSSIBLE AND WE CAN START THE TAKE OVER IMMEDIATELY IF WE HAVE ANY 
  2048.       // NODES THAT CAN PERFORM A TAKE OVER.
  2049.       /*---------------------------------------------------------------------*/
  2050.       if (nodePtr.p->nodeStatus != NodeRecord::ALIVE) {
  2051.         jam();
  2052.         Uint32 ThotSpareNode = findHotSpare();
  2053.         if (ThotSpareNode != RNIL) {
  2054.           jam();
  2055.           startTakeOver(signal, RNIL, ThotSpareNode, nodePtr.i);
  2056.         }//if
  2057.       } else if(nodePtr.p->activeStatus == Sysfile::NS_NotActive_NotTakenOver){
  2058.         jam();
  2059. /*-------------------------------------------------------------------*/
  2060. // NOT ACTIVE NODES THAT HAVE NOT YET BEEN TAKEN OVER NEEDS TAKE OVER
  2061. // IMMEDIATELY. IF WE ARE ALIVE WE TAKE OVER OUR OWN NODE.
  2062. /*-------------------------------------------------------------------*/
  2063. startTakeOver(signal, RNIL, nodePtr.i, nodePtr.i);
  2064.       }//if
  2065.       break;
  2066.     case Sysfile::NS_TakeOver:
  2067.       /**-------------------------------------------------------------------
  2068.        * WE MUST HAVE FAILED IN THE MIDDLE OF THE TAKE OVER PROCESS. 
  2069.        * WE WILL CONCLUDE THE TAKE OVER PROCESS NOW.
  2070.        *-------------------------------------------------------------------*/
  2071.       if (nodePtr.p->nodeStatus == NodeRecord::ALIVE) {
  2072.         jam();
  2073.         Uint32 takeOverNode = Sysfile::getTakeOverNode(nodePtr.i, 
  2074.        SYSFILE->takeOver);
  2075. if(takeOverNode == 0){
  2076.   jam();
  2077.   warningEvent("Bug in take-over code restarting");
  2078.   takeOverNode = nodePtr.i;
  2079. }
  2080.         startTakeOver(signal, RNIL, nodePtr.i, takeOverNode);
  2081.       } else {
  2082.         jam();
  2083. /**-------------------------------------------------------------------
  2084.  * We are not currently taking over, change our active status.
  2085.  *-------------------------------------------------------------------*/
  2086.         nodePtr.p->activeStatus = Sysfile::NS_NotActive_NotTakenOver;
  2087.         setNodeRestartInfoBits();
  2088.       }//if
  2089.       break;
  2090.     case Sysfile::NS_HotSpare:
  2091.       jam();
  2092.       break;
  2093.       /*---------------------------------------------------------------------*/
  2094.       // WE NEED NOT TAKE OVER NODES THAT ARE HOT SPARE.
  2095.       /*---------------------------------------------------------------------*/
  2096.     case Sysfile::NS_NotDefined:
  2097.       jam();
  2098.       break;
  2099.       /*---------------------------------------------------------------------*/
  2100.       // WE NEED NOT TAKE OVER NODES THAT DO NOT EVEN EXIST IN THE CLUSTER.
  2101.       /*---------------------------------------------------------------------*/
  2102.     default:
  2103.       ndbrequire(false);
  2104.       break;
  2105.     }//switch
  2106.   }//for
  2107.   /*-------------------------------------------------------------------------*/
  2108.   /* NO TAKE OVER HAS BEEN INITIATED.                                        */
  2109.   /*-------------------------------------------------------------------------*/
  2110. }//Dbdih::systemRestartTakeOverLab()
  2111. /*---------------------------------------------------------------------------*/
  2112. // This subroutine is called as part of node restart in the master node.
  2113. /*---------------------------------------------------------------------------*/
  2114. void Dbdih::nodeRestartTakeOver(Signal* signal, Uint32 startNodeId)
  2115. {
  2116.   switch (getNodeActiveStatus(startNodeId)) {
  2117.   case Sysfile::NS_Active:
  2118.   case Sysfile::NS_ActiveMissed_1:
  2119.   case Sysfile::NS_ActiveMissed_2:
  2120.     jam();
  2121.     /*-----------------------------------------------------------------------*/
  2122.     // AN ACTIVE NODE HAS BEEN STARTED. THE ACTIVE NODE MUST THEN GET ALL DATA
  2123.     // IT HAD BEFORE ITS CRASH. WE START THE TAKE OVER IMMEDIATELY. 
  2124.     // SINCE WE ARE AN ACTIVE NODE WE WILL TAKE OVER OUR OWN NODE THAT 
  2125.     // PREVIOUSLY CRASHED.
  2126.     /*-----------------------------------------------------------------------*/
  2127.     startTakeOver(signal, RNIL, startNodeId, startNodeId);
  2128.     break;
  2129.   case Sysfile::NS_HotSpare:{
  2130.     jam();
  2131.     /*-----------------------------------------------------------------------*/
  2132.     // WHEN STARTING UP A HOT SPARE WE WILL CHECK IF ANY NODE NEEDS TO TAKEN 
  2133.     // OVER. IF SO THEN WE WILL START THE TAKE OVER.
  2134.     /*-----------------------------------------------------------------------*/
  2135.       bool takeOverStarted = false;
  2136.       NodeRecordPtr nodePtr;
  2137.       for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
  2138. jam();
  2139. ptrAss(nodePtr, nodeRecord);
  2140. if (nodePtr.p->activeStatus == Sysfile::NS_NotActive_NotTakenOver) {
  2141.   jam();
  2142.   takeOverStarted = true;
  2143.   startTakeOver(signal, RNIL, startNodeId, nodePtr.i);
  2144. }//if
  2145.       }//for
  2146.       if (!takeOverStarted) {
  2147. jam();
  2148. /*-------------------------------------------------------------------*/
  2149. // NO TAKE OVER WAS NEEDED AT THE MOMENT WE START-UP AND WAIT UNTIL A 
  2150. // TAKE OVER IS NEEDED.
  2151. /*-------------------------------------------------------------------*/
  2152. BlockReference ref = calcDihBlockRef(startNodeId);
  2153. signal->theData[0] = startNodeId;
  2154. sendSignal(ref, GSN_START_COPYCONF, signal, 1, JBB);
  2155.       }//if
  2156.       break;
  2157.   }
  2158.   case Sysfile::NS_NotActive_NotTakenOver:
  2159.     jam();
  2160.     /*-----------------------------------------------------------------------*/
  2161.     // ALL DATA IN THE NODE IS LOST BUT WE HAVE NOT TAKEN OVER YET. WE WILL
  2162.     // TAKE OVER OUR OWN NODE
  2163.     /*-----------------------------------------------------------------------*/
  2164.     startTakeOver(signal, RNIL, startNodeId, startNodeId);
  2165.     break;
  2166.   case Sysfile::NS_TakeOver:{
  2167.     jam();
  2168.     /*--------------------------------------------------------------------
  2169.      * We were in the process of taking over but it was not completed.
  2170.      * We will complete it now instead.
  2171.      *--------------------------------------------------------------------*/
  2172.     Uint32 takeOverNode = Sysfile::getTakeOverNode(startNodeId, 
  2173.    SYSFILE->takeOver);
  2174.     startTakeOver(signal, RNIL, startNodeId, takeOverNode);
  2175.     break;
  2176.   }
  2177.   default:
  2178.     ndbrequire(false);
  2179.     break;
  2180.   }//switch
  2181.   nodeResetStart();
  2182. }//Dbdih::nodeRestartTakeOver()
  2183. /*************************************************************************/
  2184. // Ths routine is called when starting a local checkpoint.
  2185. /*************************************************************************/
  2186. void Dbdih::checkStartTakeOver(Signal* signal) 
  2187. {
  2188.   NodeRecordPtr csoNodeptr;
  2189.   Uint32 tcsoHotSpareNode;
  2190.   Uint32 tcsoTakeOverNode;
  2191.   if (isMaster()) {
  2192.     /*-----------------------------------------------------------------*/
  2193.     /*       WE WILL ONLY START TAKE OVER IF WE ARE MASTER.            */
  2194.     /*-----------------------------------------------------------------*/
  2195.     /*       WE WILL ONLY START THE  TAKE OVER IF THERE WERE A NEED OF */
  2196.     /*       A TAKE OVER.                                              */
  2197.     /*-----------------------------------------------------------------*/
  2198.     /*       WE CAN ONLY PERFORM THE TAKE OVER IF WE HAVE A HOT SPARE  */
  2199.     /*       AVAILABLE.                                                */
  2200.     /*-----------------------------------------------------------------*/
  2201.     tcsoTakeOverNode = 0;
  2202.     tcsoHotSpareNode = 0;
  2203.     for (csoNodeptr.i = 1; csoNodeptr.i < MAX_NDB_NODES; csoNodeptr.i++) {
  2204.       ptrAss(csoNodeptr, nodeRecord);
  2205.       if (csoNodeptr.p->activeStatus == Sysfile::NS_NotActive_NotTakenOver) {
  2206.         jam();
  2207.         tcsoTakeOverNode = csoNodeptr.i;
  2208.       } else {
  2209.         jam();
  2210.         if (csoNodeptr.p->activeStatus == Sysfile::NS_HotSpare) {
  2211.           jam();
  2212.           tcsoHotSpareNode = csoNodeptr.i;
  2213.         }//if
  2214.       }//if
  2215.     }//for
  2216.     if ((tcsoTakeOverNode != 0) &&
  2217.         (tcsoHotSpareNode != 0)) {
  2218.       jam();
  2219.       startTakeOver(signal, RNIL, tcsoHotSpareNode, tcsoTakeOverNode);
  2220.     }//if
  2221.   }//if
  2222. }//Dbdih::checkStartTakeOver()
  2223. /*****************************************************************************/
  2224. /***********     NODE ADDING  MODULE                             *************/
  2225. /***********     CODE TO HANDLE TAKE OVER                        *************/
  2226. /*****************************************************************************/
  2227. // A take over can be initiated by a number of things:
  2228. // 1) A node restart, usually the node takes over itself but can also take
  2229. //    over somebody else if its own data was already taken over
  2230. // 2) At system restart it is necessary to use the take over code to recover
  2231. //    nodes which had too old checkpoints to be restorable by the usual
  2232. //    restoration from disk.
  2233. // 3) When a node has missed too many local checkpoints and is decided by the
  2234. //    master to be taken over by a hot spare node that sits around waiting
  2235. //    for this to happen.
  2236. //
  2237. // To support multiple node failures efficiently the code is written such that
  2238. // only one take over can handle transitions in state but during a copy 
  2239. // fragment other take over's can perform state transitions.
  2240. /*****************************************************************************/
  2241. void Dbdih::startTakeOver(Signal* signal,
  2242.                           Uint32 takeOverPtrI,
  2243.                           Uint32 startNode,
  2244.                           Uint32 nodeTakenOver)
  2245. {
  2246.   NodeRecordPtr toNodePtr;
  2247.   NodeGroupRecordPtr NGPtr;
  2248.   toNodePtr.i = nodeTakenOver;
  2249.   ptrCheckGuard(toNodePtr, MAX_NDB_NODES, nodeRecord);
  2250.   NGPtr.i = toNodePtr.p->nodeGroup;
  2251.   ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
  2252.   TakeOverRecordPtr takeOverPtr;
  2253.   if (takeOverPtrI == RNIL) {
  2254.     jam();
  2255.     setAllowNodeStart(startNode, false);
  2256.     seizeTakeOver(takeOverPtr);
  2257.     if (startNode == c_nodeStartMaster.startNode) {
  2258.       jam();
  2259.       takeOverPtr.p->toNodeRestart = true;
  2260.     }//if
  2261.     takeOverPtr.p->toStartingNode = startNode;
  2262.     takeOverPtr.p->toFailedNode = nodeTakenOver;
  2263.   } else {
  2264.     jam();
  2265.     RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
  2266.     ndbrequire(takeOverPtr.p->toStartingNode == startNode);
  2267.     ndbrequire(takeOverPtr.p->toFailedNode == nodeTakenOver);
  2268.     ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::TO_WAIT_START_TAKE_OVER);
  2269.   }//if
  2270.   if ((NGPtr.p->activeTakeOver) || (ERROR_INSERTED(7157))) {
  2271.     jam();
  2272.     /**------------------------------------------------------------------------
  2273.      * A take over is already active in this node group. We only allow one 
  2274.      * take over per node group. Otherwise we will overload the node group and 
  2275.      * also we will require much more checks when starting up copying of 
  2276.      * fragments. The parallelism for take over is mainly to ensure that we 
  2277.      * can handle take over efficiently in large systems with 4 nodes and above
  2278.      * A typical case is a 8 node system executing on two 8-cpu boxes. 
  2279.      * A box crash in one of the boxes will mean 4 nodes crashes. 
  2280.      * We want to be able to restart those four nodes to some 
  2281.      * extent in parallel.
  2282.      * 
  2283.      * We will wait for a few seconds and then try again.
  2284.      */
  2285.     takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_WAIT_START_TAKE_OVER;
  2286.     signal->theData[0] = DihContinueB::ZSTART_TAKE_OVER;
  2287.     signal->theData[1] = takeOverPtr.i;
  2288.     signal->theData[2] = startNode;
  2289.     signal->theData[3] = nodeTakenOver;
  2290.     sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 5000, 4);
  2291.     return;
  2292.   }//if
  2293.   NGPtr.p->activeTakeOver = true;
  2294.   if (startNode == nodeTakenOver) {
  2295.     jam();
  2296.     switch (getNodeActiveStatus(nodeTakenOver)) {
  2297.     case Sysfile::NS_Active:
  2298.     case Sysfile::NS_ActiveMissed_1:
  2299.     case Sysfile::NS_ActiveMissed_2:
  2300.       jam();
  2301.       break;
  2302.     case Sysfile::NS_NotActive_NotTakenOver:
  2303.     case Sysfile::NS_TakeOver:
  2304.       jam();
  2305.       setNodeActiveStatus(nodeTakenOver, Sysfile::NS_TakeOver);
  2306.       break;
  2307.     default:
  2308.       ndbrequire(false);
  2309.     }//switch
  2310.   } else {
  2311.     jam();
  2312.     setNodeActiveStatus(nodeTakenOver, Sysfile::NS_HotSpare);
  2313.     setNodeActiveStatus(startNode, Sysfile::NS_TakeOver);
  2314.     changeNodeGroups(startNode, nodeTakenOver);
  2315.   }//if
  2316.   setNodeRestartInfoBits();
  2317.   /* ---------------------------------------------------------------------- */
  2318.   /*  WE SET THE RESTART INFORMATION TO INDICATE THAT WE ARE ABOUT TO TAKE  */
  2319.   /*  OVER THE FAILED NODE. WE SET THIS INFORMATION AND WAIT UNTIL THE      */
  2320.   /*  GLOBAL CHECKPOINT HAS WRITTEN THE RESTART INFORMATION.                */
  2321.   /* ---------------------------------------------------------------------- */
  2322.   Sysfile::setTakeOverNode(takeOverPtr.p->toFailedNode, SYSFILE->takeOver,
  2323.    startNode);
  2324.   takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_START_COPY;
  2325.   
  2326.   cstartGcpNow = true;
  2327. }//Dbdih::startTakeOver()
  2328. void Dbdih::changeNodeGroups(Uint32 startNode, Uint32 nodeTakenOver)
  2329. {
  2330.   NodeRecordPtr startNodePtr;
  2331.   NodeRecordPtr toNodePtr;
  2332.   startNodePtr.i = startNode;
  2333.   ptrCheckGuard(startNodePtr, MAX_NDB_NODES, nodeRecord);
  2334.   toNodePtr.i = nodeTakenOver;
  2335.   ptrCheckGuard(toNodePtr, MAX_NDB_NODES, nodeRecord);
  2336.   ndbrequire(startNodePtr.p->nodeGroup == ZNIL);
  2337.   NodeGroupRecordPtr NGPtr;
  2338.   NGPtr.i = toNodePtr.p->nodeGroup;
  2339.   ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
  2340.   bool nodeFound = false;
  2341.   for (Uint32 i = 0; i < NGPtr.p->nodeCount; i++) {
  2342.     jam();
  2343.     if (NGPtr.p->nodesInGroup[i] == nodeTakenOver) {
  2344.       jam();
  2345.       NGPtr.p->nodesInGroup[i] = startNode;
  2346.       nodeFound = true;
  2347.     }//if
  2348.   }//for
  2349.   ndbrequire(nodeFound);
  2350.   Sysfile::setNodeGroup(startNodePtr.i, SYSFILE->nodeGroups, toNodePtr.p->nodeGroup);
  2351.   startNodePtr.p->nodeGroup = toNodePtr.p->nodeGroup;
  2352.   Sysfile::setNodeGroup(toNodePtr.i, SYSFILE->nodeGroups, NO_NODE_GROUP_ID);
  2353.   toNodePtr.p->nodeGroup = ZNIL;
  2354. }//Dbdih::changeNodeGroups()
  2355. void Dbdih::checkToCopy()
  2356. {
  2357.   TakeOverRecordPtr takeOverPtr;
  2358.   for (takeOverPtr.i = 0;takeOverPtr.i < MAX_NDB_NODES; takeOverPtr.i++) {
  2359.     ptrAss(takeOverPtr, takeOverRecord);
  2360.     /*----------------------------------------------------------------------*/
  2361.     // TAKE OVER HANDLING WRITES RESTART INFORMATION THROUGH 
  2362.     // THE GLOBAL CHECKPOINT
  2363.     // PROTOCOL. WE CHECK HERE BEFORE STARTING A WRITE OF THE RESTART 
  2364.     // INFORMATION.
  2365.     /*-----------------------------------------------------------------------*/
  2366.     if (takeOverPtr.p->toMasterStatus == TakeOverRecord::TO_START_COPY) {
  2367.       jam();
  2368.       takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_START_COPY_ONGOING;
  2369.     } else if (takeOverPtr.p->toMasterStatus == TakeOverRecord::TO_END_COPY) {
  2370.       jam();
  2371.       takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_END_COPY_ONGOING;
  2372.     }//if
  2373.   }//for
  2374. }//Dbdih::checkToCopy()
  2375. void Dbdih::checkToCopyCompleted(Signal* signal)
  2376. {
  2377.   /* ------------------------------------------------------------------------*/
  2378.   /*     WE CHECK HERE IF THE WRITING OF TAKE OVER INFORMATION ALSO HAS BEEN */
  2379.   /*     COMPLETED.                                                          */
  2380.   /* ------------------------------------------------------------------------*/
  2381.   TakeOverRecordPtr toPtr;
  2382.   for (toPtr.i = 0; toPtr.i < MAX_NDB_NODES; toPtr.i++) {
  2383.     ptrAss(toPtr, takeOverRecord);
  2384.     if (toPtr.p->toMasterStatus == TakeOverRecord::TO_START_COPY_ONGOING){
  2385.       jam();
  2386.       sendStartTo(signal, toPtr.i);
  2387.     } else if (toPtr.p->toMasterStatus == TakeOverRecord::TO_END_COPY_ONGOING){
  2388.       jam();
  2389.       sendEndTo(signal, toPtr.i);
  2390.     } else {
  2391.       jam();
  2392.     }//if
  2393.   }//for
  2394. }//Dbdih::checkToCopyCompleted()
  2395. bool Dbdih::checkToInterrupted(TakeOverRecordPtr& takeOverPtr)
  2396. {
  2397.   if (checkNodeAlive(takeOverPtr.p->toStartingNode)) {
  2398.     jam();
  2399.     return false;
  2400.   } else {
  2401.     jam();
  2402.     endTakeOver(takeOverPtr.i);
  2403.     return true;
  2404.   }//if
  2405. }//Dbdih::checkToInterrupted()
  2406. void Dbdih::sendStartTo(Signal* signal, Uint32 takeOverPtrI)
  2407. {
  2408.   TakeOverRecordPtr takeOverPtr;
  2409.   CRASH_INSERTION(7155);
  2410.   RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
  2411.   if ((c_startToLock != RNIL) || (ERROR_INSERTED(7158))) {
  2412.     jam();
  2413.     takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_WAIT_START;
  2414.     signal->theData[0] = DihContinueB::ZSEND_START_TO;
  2415.     signal->theData[1] = takeOverPtrI;
  2416.     signal->theData[2] = takeOverPtr.p->toStartingNode;
  2417.     signal->theData[3] = takeOverPtr.p->toFailedNode;
  2418.     sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 30, 4);
  2419.     return;
  2420.   }//if
  2421.   c_startToLock = takeOverPtrI;
  2422.   StartToReq * const req = (StartToReq *)&signal->theData[0];
  2423.   req->userPtr = takeOverPtr.i;
  2424.   req->userRef = reference();
  2425.   req->startingNodeId = takeOverPtr.p->toStartingNode;
  2426.   req->nodeTakenOver = takeOverPtr.p->toFailedNode;
  2427.   req->nodeRestart = takeOverPtr.p->toNodeRestart;
  2428.   takeOverPtr.p->toMasterStatus = TakeOverRecord::STARTING;
  2429.   sendLoopMacro(START_TOREQ, sendSTART_TOREQ);
  2430. }//Dbdih::sendStartTo()
  2431. void Dbdih::execSTART_TOREQ(Signal* signal) 
  2432. {
  2433.   TakeOverRecordPtr takeOverPtr;
  2434.   jamEntry();
  2435.   const StartToReq * const req = (StartToReq *)&signal->theData[0];
  2436.   takeOverPtr.i = req->userPtr;
  2437.   BlockReference ref = req->userRef;
  2438.   Uint32 startingNode = req->startingNodeId;
  2439.   CRASH_INSERTION(7133);
  2440.   RETURN_IF_NODE_NOT_ALIVE(req->startingNodeId);
  2441.   ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
  2442.   allocateTakeOver(takeOverPtr);
  2443.   initStartTakeOver(req, takeOverPtr);
  2444.   
  2445.   StartToConf * const conf = (StartToConf *)&signal->theData[0];
  2446.   conf->userPtr = takeOverPtr.i;
  2447.   conf->sendingNodeId = cownNodeId;
  2448.   conf->startingNodeId = startingNode;
  2449.   sendSignal(ref, GSN_START_TOCONF, signal, StartToConf::SignalLength, JBB);
  2450. }//Dbdih::execSTART_TOREQ()
  2451. void Dbdih::execSTART_TOCONF(Signal* signal) 
  2452. {
  2453.   TakeOverRecordPtr takeOverPtr;
  2454.   jamEntry();
  2455.   const StartToConf * const conf = (StartToConf *)&signal->theData[0];
  2456.   CRASH_INSERTION(7147);
  2457.   RETURN_IF_NODE_NOT_ALIVE(conf->startingNodeId);
  2458.   
  2459.   takeOverPtr.i = conf->userPtr;
  2460.   ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
  2461.   ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::STARTING);
  2462.   ndbrequire(takeOverPtr.p->toStartingNode == conf->startingNodeId);
  2463.   receiveLoopMacro(START_TOREQ, conf->sendingNodeId);
  2464.   CRASH_INSERTION(7134);
  2465.   c_startToLock = RNIL;
  2466.   startNextCopyFragment(signal, takeOverPtr.i);
  2467. }//Dbdih::execSTART_TOCONF()
  2468. void Dbdih::initStartTakeOver(const StartToReq * req, 
  2469.       TakeOverRecordPtr takeOverPtr)
  2470. {
  2471.   takeOverPtr.p->toCurrentTabref = 0;
  2472.   takeOverPtr.p->toCurrentFragid = 0;
  2473.   takeOverPtr.p->toStartingNode = req->startingNodeId;
  2474.   takeOverPtr.p->toFailedNode = req->nodeTakenOver;
  2475.   takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_SLAVE_STARTED;
  2476.   takeOverPtr.p->toCopyNode = RNIL;
  2477.   takeOverPtr.p->toCurrentReplica = RNIL;
  2478.   takeOverPtr.p->toNodeRestart = req->nodeRestart;
  2479. }//Dbdih::initStartTakeOver()
  2480. void Dbdih::startNextCopyFragment(Signal* signal, Uint32 takeOverPtrI)
  2481. {
  2482.   TabRecordPtr tabPtr;
  2483.   TakeOverRecordPtr takeOverPtr;
  2484.   Uint32 loopCount;
  2485.   RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
  2486.   takeOverPtr.p->toMasterStatus = TakeOverRecord::SELECTING_NEXT;
  2487.   loopCount = 0;
  2488.   if (ERROR_INSERTED(7159)) {
  2489.     loopCount = 100;
  2490.   }//if
  2491.   while (loopCount++ < 100) {
  2492.     tabPtr.i = takeOverPtr.p->toCurrentTabref;
  2493.     if (tabPtr.i >= ctabFileSize) {
  2494.       jam();
  2495.       CRASH_INSERTION(7136);
  2496.       sendUpdateTo(signal, takeOverPtr.i, UpdateToReq::TO_COPY_COMPLETED);
  2497.       return;
  2498.     }//if
  2499.     ptrAss(tabPtr, tabRecord);
  2500.     if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE){
  2501.       jam();
  2502.       takeOverPtr.p->toCurrentFragid = 0;
  2503.       takeOverPtr.p->toCurrentTabref++;
  2504.       continue;
  2505.     }//if
  2506.     Uint32 fragId = takeOverPtr.p->toCurrentFragid;
  2507.     if (fragId >= tabPtr.p->totalfragments) {
  2508.       jam();
  2509.       takeOverPtr.p->toCurrentFragid = 0;
  2510.       takeOverPtr.p->toCurrentTabref++;
  2511.       if (ERROR_INSERTED(7135)) {
  2512.         if (takeOverPtr.p->toCurrentTabref == 1) {
  2513.           ndbrequire(false);
  2514.         }//if
  2515.       }//if
  2516.       continue;
  2517.     }//if
  2518.     FragmentstorePtr fragPtr;
  2519.     getFragstore(tabPtr.p, fragId, fragPtr);
  2520.     ReplicaRecordPtr loopReplicaPtr;
  2521.     loopReplicaPtr.i = fragPtr.p->oldStoredReplicas;
  2522.     while (loopReplicaPtr.i != RNIL) {
  2523.       ptrCheckGuard(loopReplicaPtr, creplicaFileSize, replicaRecord);
  2524.       if (loopReplicaPtr.p->procNode == takeOverPtr.p->toFailedNode) {
  2525.         jam();
  2526. /* ----------------------------------------------------------------- */
  2527. /* WE HAVE FOUND A REPLICA THAT BELONGED THE FAILED NODE THAT NEEDS  */
  2528. /* TAKE OVER. WE TAKE OVER THIS REPLICA TO THE NEW NODE.             */
  2529. /* ----------------------------------------------------------------- */
  2530.         takeOverPtr.p->toCurrentReplica = loopReplicaPtr.i;
  2531.         toCopyFragLab(signal, takeOverPtr.i);
  2532.         return;
  2533.       } else if (loopReplicaPtr.p->procNode == takeOverPtr.p->toStartingNode) {
  2534.         jam();
  2535. /* ----------------------------------------------------------------- */
  2536. /* WE HAVE OBVIOUSLY STARTED TAKING OVER THIS WITHOUT COMPLETING IT. */
  2537. /* WE     */
  2538. /* NEED TO COMPLETE THE TAKE OVER OF THIS REPLICA.                   */
  2539. /* ----------------------------------------------------------------- */
  2540.         takeOverPtr.p->toCurrentReplica = loopReplicaPtr.i;
  2541.         toCopyFragLab(signal, takeOverPtr.i);
  2542.         return;
  2543.       } else {
  2544.         jam();
  2545.         loopReplicaPtr.i = loopReplicaPtr.p->nextReplica;
  2546.       }//if
  2547.     }//while
  2548.     takeOverPtr.p->toCurrentFragid++;
  2549.   }//while
  2550.   signal->theData[0] = DihContinueB::ZTO_START_COPY_FRAG;
  2551.   signal->theData[1] = takeOverPtr.i;
  2552.   sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
  2553. }//Dbdih::startNextCopyFragment()
  2554. void Dbdih::toCopyFragLab(Signal* signal,
  2555.                           Uint32 takeOverPtrI) 
  2556. {
  2557.   TakeOverRecordPtr takeOverPtr;
  2558.   RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
  2559.   CreateReplicaRecordPtr createReplicaPtr;
  2560.   createReplicaPtr.i = 0;
  2561.   ptrAss(createReplicaPtr, createReplicaRecord);
  2562.   ReplicaRecordPtr replicaPtr;
  2563.   replicaPtr.i = takeOverPtr.p->toCurrentReplica;
  2564.   ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
  2565.   TabRecordPtr tabPtr;
  2566.   tabPtr.i = takeOverPtr.p->toCurrentTabref;
  2567.   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  2568.   /* ----------------------------------------------------------------------- */
  2569.   /* WE HAVE FOUND A REPLICA THAT NEEDS TAKE OVER. WE WILL START THIS TAKE   */
  2570.   /* OVER BY ADDING THE FRAGMENT WHEREAFTER WE WILL ORDER THE PRIMARY        */
  2571.   /* REPLICA TO COPY ITS CONTENT TO THE NEW STARTING REPLICA.                */
  2572.   /* THIS OPERATION IS A SINGLE USER OPERATION UNTIL WE HAVE SENT            */
  2573.   /* COPY_FRAGREQ. AFTER SENDING COPY_FRAGREQ WE ARE READY TO START A NEW    */
  2574.   /* FRAGMENT REPLICA. WE WILL NOT IMPLEMENT THIS IN THE FIRST PHASE.        */
  2575.   /* ----------------------------------------------------------------------- */
  2576.   cnoOfCreateReplicas = 1;
  2577.   createReplicaPtr.p->hotSpareUse = true;
  2578.   createReplicaPtr.p->dataNodeId = takeOverPtr.p->toStartingNode;
  2579.   prepareSendCreateFragReq(signal, takeOverPtrI);
  2580. }//Dbdih::toCopyFragLab()
  2581. void Dbdih::prepareSendCreateFragReq(Signal* signal, Uint32 takeOverPtrI)
  2582. {
  2583.   TakeOverRecordPtr takeOverPtr;
  2584.   RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
  2585.   TabRecordPtr tabPtr;
  2586.   tabPtr.i = takeOverPtr.p->toCurrentTabref;
  2587.   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  2588.   FragmentstorePtr fragPtr;
  2589.   getFragstore(tabPtr.p, takeOverPtr.p->toCurrentFragid, fragPtr);
  2590.   Uint32 nodes[MAX_REPLICAS];
  2591.   extractNodeInfo(fragPtr.p, nodes);
  2592.   takeOverPtr.p->toCopyNode = nodes[0];
  2593.   sendCreateFragReq(signal, 0, CreateFragReq::STORED, takeOverPtr.i);
  2594. }//Dbdih::prepareSendCreateFragReq()
  2595. void Dbdih::sendCreateFragReq(Signal* signal,
  2596.                               Uint32 startGci,
  2597.                               Uint32 replicaType,
  2598.                               Uint32 takeOverPtrI) 
  2599. {
  2600.   TakeOverRecordPtr takeOverPtr;
  2601.   RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
  2602.   if ((c_createFragmentLock != RNIL) ||
  2603.       ((ERROR_INSERTED(7161))&&(replicaType == CreateFragReq::STORED)) ||
  2604.       ((ERROR_INSERTED(7162))&&(replicaType == CreateFragReq::COMMIT_STORED))){
  2605.     if (replicaType == CreateFragReq::STORED) {
  2606.       jam();
  2607.       takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_WAIT_PREPARE_CREATE;
  2608.     } else {
  2609.       ndbrequire(replicaType == CreateFragReq::COMMIT_STORED);
  2610.       jam();
  2611.       takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_WAIT_COMMIT_CREATE;
  2612.     }//if
  2613.     signal->theData[0] = DihContinueB::ZSEND_CREATE_FRAG;
  2614.     signal->theData[1] = takeOverPtr.i;
  2615.     signal->theData[2] = replicaType;
  2616.     signal->theData[3] = startGci;
  2617.     signal->theData[4] = takeOverPtr.p->toStartingNode;
  2618.     signal->theData[5] = takeOverPtr.p->toFailedNode;
  2619.     sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 50, 6);
  2620.     return;
  2621.   }//if
  2622.   c_createFragmentLock = takeOverPtr.i;
  2623.   sendLoopMacro(CREATE_FRAGREQ, nullRoutine);
  2624.   CreateFragReq * const req = (CreateFragReq *)&signal->theData[0];
  2625.   req->userPtr = takeOverPtr.i;
  2626.   req->userRef = reference();
  2627.   req->tableId = takeOverPtr.p->toCurrentTabref;
  2628.   req->fragId = takeOverPtr.p->toCurrentFragid;
  2629.   req->startingNodeId = takeOverPtr.p->toStartingNode;
  2630.   req->copyNodeId = takeOverPtr.p->toCopyNode;
  2631.   req->startGci = startGci;
  2632.   req->replicaType = replicaType;
  2633.   NodeRecordPtr nodePtr;
  2634.   nodePtr.i = cfirstAliveNode;
  2635.   do {
  2636.     ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
  2637.     BlockReference ref = calcDihBlockRef(nodePtr.i);
  2638.     sendSignal(ref, GSN_CREATE_FRAGREQ, signal, 
  2639.        CreateFragReq::SignalLength, JBB);
  2640.     nodePtr.i = nodePtr.p->nextNode;
  2641.   } while (nodePtr.i != RNIL);
  2642.   if (replicaType == CreateFragReq::STORED) {
  2643.     jam();
  2644.     takeOverPtr.p->toMasterStatus = TakeOverRecord::PREPARE_CREATE;
  2645.   } else {
  2646.     ndbrequire(replicaType == CreateFragReq::COMMIT_STORED);
  2647.     jam();
  2648.     takeOverPtr.p->toMasterStatus = TakeOverRecord::COMMIT_CREATE;
  2649.   }
  2650. }//Dbdih::sendCreateFragReq()
  2651. /* --------------------------------------------------------------------------*/
  2652. /*       AN ORDER TO START OR COMMIT THE REPLICA CREATION ARRIVED FROM THE   */
  2653. /*       MASTER.                                                             */
  2654. /* --------------------------------------------------------------------------*/
  2655. void Dbdih::execCREATE_FRAGREQ(Signal* signal) 
  2656. {
  2657.   jamEntry();
  2658.   CreateFragReq * const req = (CreateFragReq *)&signal->theData[0];
  2659.   TakeOverRecordPtr takeOverPtr;
  2660.   takeOverPtr.i = req->userPtr;
  2661.   ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
  2662.   BlockReference retRef = req->userRef;
  2663.   TabRecordPtr tabPtr;
  2664.   tabPtr.i = req->tableId;
  2665.   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  2666.   Uint32 fragId = req->fragId;
  2667.   Uint32 tdestNodeid = req->startingNodeId;
  2668.   Uint32 tsourceNodeid = req->copyNodeId;
  2669.   Uint32 startGci = req->startGci;
  2670.   Uint32 replicaType = req->replicaType;
  2671.   FragmentstorePtr fragPtr;
  2672.   getFragstore(tabPtr.p, fragId, fragPtr);
  2673.   RETURN_IF_NODE_NOT_ALIVE(tdestNodeid);
  2674.   ReplicaRecordPtr frReplicaPtr;
  2675.   findToReplica(takeOverPtr.p, replicaType, fragPtr, frReplicaPtr);
  2676.   ndbrequire(frReplicaPtr.i != RNIL);
  2677.   switch (replicaType) {
  2678.   case CreateFragReq::STORED:
  2679.     jam();
  2680.     CRASH_INSERTION(7138);
  2681.     /* ----------------------------------------------------------------------*/
  2682.     /*  HERE WE ARE INSERTING THE NEW BACKUP NODE IN THE EXECUTION OF ALL    */
  2683.     /*  OPERATIONS. FROM HERE ON ALL OPERATIONS ON THIS FRAGMENT WILL INCLUDE*/
  2684.     /*  USE OF THE NEW REPLICA.                                              */
  2685.     /* --------------------------------------------------------------------- */
  2686.     insertBackup(fragPtr, tdestNodeid);
  2687.     takeOverPtr.p->toCopyNode = tsourceNodeid;
  2688.     takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_SLAVE_CREATE_PREPARE;
  2689.     
  2690.     fragPtr.p->distributionKey++;
  2691.     fragPtr.p->distributionKey &= 255;
  2692.     break;
  2693.   case CreateFragReq::COMMIT_STORED:
  2694.     jam();
  2695.     CRASH_INSERTION(7139);
  2696.     /* ----------------------------------------------------------------------*/
  2697.     /*  HERE WE ARE MOVING THE REPLICA TO THE STORED SECTION SINCE IT IS NOW */
  2698.     /*  FULLY LOADED WITH ALL DATA NEEDED.                                   */
  2699.     // We also update the order of the replicas here so that if the new 
  2700.     // replica is the desired primary we insert it as primary.
  2701.     /* ----------------------------------------------------------------------*/
  2702.     takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_SLAVE_CREATE_COMMIT;
  2703.     removeOldStoredReplica(fragPtr, frReplicaPtr);
  2704.     linkStoredReplica(fragPtr, frReplicaPtr);
  2705.     updateNodeInfo(fragPtr);
  2706.     break;
  2707.   default:
  2708.     ndbrequire(false);
  2709.     break;
  2710.   }//switch
  2711.   /* ------------------------------------------------------------------------*/
  2712.   /*       THE NEW NODE OF THIS REPLICA IS THE STARTING NODE.                */
  2713.   /* ------------------------------------------------------------------------*/
  2714.   if (frReplicaPtr.p->procNode != takeOverPtr.p->toStartingNode) {
  2715.     jam();
  2716.     /* ---------------------------------------------------------------------*/
  2717.     /*  IF WE ARE STARTING A TAKE OVER NODE WE MUST INVALIDATE ALL LCP'S.   */
  2718.     /*  OTHERWISE WE WILL TRY TO START LCP'S THAT DO NOT EXIST.             */
  2719.     /* ---------------------------------------------------------------------*/
  2720.     frReplicaPtr.p->procNode = takeOverPtr.p->toStartingNode;
  2721.     frReplicaPtr.p->noCrashedReplicas = 0;
  2722.     frReplicaPtr.p->createGci[0] = startGci;
  2723.     ndbrequire(startGci != 0xF1F1F1F1);
  2724.     frReplicaPtr.p->replicaLastGci[0] = (Uint32)-1;
  2725.     for (Uint32 i = 0; i < MAX_LCP_STORED; i++) {
  2726.       frReplicaPtr.p->lcpStatus[i] = ZINVALID;
  2727.     }//for
  2728.   } else {
  2729.     jam();
  2730.     const Uint32 noCrashed = frReplicaPtr.p->noCrashedReplicas;
  2731.     arrGuard(noCrashed, 8);
  2732.     frReplicaPtr.p->createGci[noCrashed] = startGci;
  2733.     ndbrequire(startGci != 0xF1F1F1F1);
  2734.     frReplicaPtr.p->replicaLastGci[noCrashed] = (Uint32)-1;
  2735.   }//if
  2736.   takeOverPtr.p->toCurrentTabref = tabPtr.i;
  2737.   takeOverPtr.p->toCurrentFragid = fragId;
  2738.   CreateFragConf * const conf = (CreateFragConf *)&signal->theData[0];
  2739.   conf->userPtr = takeOverPtr.i;
  2740.   conf->tableId = tabPtr.i;
  2741.   conf->fragId = fragId;
  2742.   conf->sendingNodeId = cownNodeId;
  2743.   conf->startingNodeId = tdestNodeid;
  2744.   sendSignal(retRef, GSN_CREATE_FRAGCONF, signal,
  2745.              CreateFragConf::SignalLength, JBB);
  2746. }//Dbdih::execCREATE_FRAGREQ()
  2747. void Dbdih::execCREATE_FRAGCONF(Signal* signal) 
  2748. {
  2749.   jamEntry();
  2750.   CRASH_INSERTION(7148);
  2751.   const CreateFragConf * const conf = (CreateFragConf *)&signal->theData[0];
  2752.   Uint32 fragId = conf->fragId;
  2753.   RETURN_IF_NODE_NOT_ALIVE(conf->startingNodeId);
  2754.   TabRecordPtr tabPtr;
  2755.   tabPtr.i = conf->tableId;
  2756.   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  2757.   TakeOverRecordPtr takeOverPtr;
  2758.   takeOverPtr.i = conf->userPtr;
  2759.   ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
  2760.   ndbrequire(tabPtr.i == takeOverPtr.p->toCurrentTabref);
  2761.   ndbrequire(fragId == takeOverPtr.p->toCurrentFragid);
  2762.   receiveLoopMacro(CREATE_FRAGREQ, conf->sendingNodeId);
  2763.   c_createFragmentLock = RNIL;
  2764.   if (takeOverPtr.p->toMasterStatus == TakeOverRecord::PREPARE_CREATE) {
  2765.     jam();
  2766.     CRASH_INSERTION(7140);
  2767.     /* --------------------------------------------------------------------- */
  2768.     /*   ALL NODES HAVE PREPARED THE INTRODUCTION OF THIS NEW NODE AND IT IS */
  2769.     /*   ALREADY IN USE. WE CAN NOW START COPYING THE FRAGMENT.              */
  2770.     /*---------------------------------------------------------------------- */
  2771.     FragmentstorePtr fragPtr;
  2772.     getFragstore(tabPtr.p, fragId, fragPtr);
  2773.     takeOverPtr.p->toMasterStatus = TakeOverRecord::COPY_FRAG;
  2774.     BlockReference ref = calcLqhBlockRef(takeOverPtr.p->toCopyNode);
  2775.     CopyFragReq * const copyFragReq = (CopyFragReq *)&signal->theData[0];
  2776.     copyFragReq->userPtr = takeOverPtr.i;
  2777.     copyFragReq->userRef = reference();
  2778.     copyFragReq->tableId = tabPtr.i;
  2779.     copyFragReq->fragId = fragId;
  2780.     copyFragReq->nodeId = takeOverPtr.p->toStartingNode;
  2781.     copyFragReq->schemaVersion = tabPtr.p->schemaVersion;
  2782.     copyFragReq->distributionKey = fragPtr.p->distributionKey;
  2783.     sendSignal(ref, GSN_COPY_FRAGREQ, signal, CopyFragReq::SignalLength, JBB);
  2784.   } else {
  2785.     ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::COMMIT_CREATE);
  2786.     jam();
  2787.     CRASH_INSERTION(7141);
  2788.     /* --------------------------------------------------------------------- */
  2789.     // REPORT that copy of fragment has been completed.
  2790.     /* --------------------------------------------------------------------- */
  2791.     signal->theData[0] = EventReport::NR_CopyFragDone;
  2792.     signal->theData[1] = takeOverPtr.p->toStartingNode;
  2793.     signal->theData[2] = tabPtr.i;
  2794.     signal->theData[3] = takeOverPtr.p->toCurrentFragid;
  2795.     sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 4, JBB);
  2796.     /* --------------------------------------------------------------------- */
  2797.     /*   WE HAVE NOW CREATED THIS NEW REPLICA AND WE ARE READY TO TAKE THE   */
  2798.     /*   THE NEXT REPLICA.                                                   */
  2799.     /* --------------------------------------------------------------------- */
  2800.     Mutex mutex(signal, c_mutexMgr, takeOverPtr.p->m_switchPrimaryMutexHandle);
  2801.     mutex.unlock(); // ignore result
  2802.     takeOverPtr.p->toCurrentFragid++;
  2803.     startNextCopyFragment(signal, takeOverPtr.i);
  2804.   }//if
  2805. }//Dbdih::execCREATE_FRAGCONF()
  2806. void Dbdih::execCOPY_FRAGREF(Signal* signal) 
  2807. {
  2808.   const CopyFragRef * const ref = (CopyFragRef *)&signal->theData[0];
  2809.   jamEntry();
  2810.   Uint32 takeOverPtrI = ref->userPtr;
  2811.   Uint32 startingNodeId = ref->startingNodeId;
  2812.   Uint32 errorCode = ref->errorCode;
  2813.   TakeOverRecordPtr takeOverPtr;
  2814.   RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
  2815.   ndbrequire(errorCode != ZNODE_FAILURE_ERROR);
  2816.   ndbrequire(ref->tableId == takeOverPtr.p->toCurrentTabref);
  2817.   ndbrequire(ref->fragId == takeOverPtr.p->toCurrentFragid);
  2818.   ndbrequire(ref->startingNodeId == takeOverPtr.p->toStartingNode);
  2819.   ndbrequire(ref->sendingNodeId == takeOverPtr.p->toCopyNode);
  2820.   ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::COPY_FRAG);
  2821.   endTakeOver(takeOverPtrI);
  2822.   //--------------------------------------------------------------------------
  2823.   // For some reason we did not succeed in copying a fragment. We treat this
  2824.   // as a serious failure and crash the starting node.
  2825.   //--------------------------------------------------------------------------
  2826.   BlockReference cntrRef = calcNdbCntrBlockRef(startingNodeId);
  2827.   SystemError * const sysErr = (SystemError*)&signal->theData[0];
  2828.   sysErr->errorCode = SystemError::CopyFragRefError;
  2829.   sysErr->errorRef = reference();
  2830.   sysErr->data1 = errorCode;
  2831.   sysErr->data2 = 0;
  2832.   sendSignal(cntrRef, GSN_SYSTEM_ERROR, signal, 
  2833.      SystemError::SignalLength, JBB);
  2834.   return;
  2835. }//Dbdih::execCOPY_FRAGREF()
  2836. void Dbdih::execCOPY_FRAGCONF(Signal* signal) 
  2837. {
  2838.   const CopyFragConf * const conf = (CopyFragConf *)&signal->theData[0];
  2839.   jamEntry();
  2840.   CRASH_INSERTION(7142);
  2841.   TakeOverRecordPtr takeOverPtr;
  2842.   Uint32 takeOverPtrI = conf->userPtr;
  2843.   RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
  2844.   ndbrequire(conf->tableId == takeOverPtr.p->toCurrentTabref);
  2845.   ndbrequire(conf->fragId == takeOverPtr.p->toCurrentFragid);
  2846.   ndbrequire(conf->startingNodeId == takeOverPtr.p->toStartingNode);
  2847.   ndbrequire(conf->sendingNodeId == takeOverPtr.p->toCopyNode);
  2848.   ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::COPY_FRAG);
  2849.   sendUpdateTo(signal, takeOverPtr.i, 
  2850.        (Uint32)UpdateToReq::TO_COPY_FRAG_COMPLETED);
  2851. }//Dbdih::execCOPY_FRAGCONF()
  2852. void Dbdih::sendUpdateTo(Signal* signal, 
  2853.  Uint32 takeOverPtrI, Uint32 updateState)
  2854. {
  2855.   TakeOverRecordPtr takeOverPtr;
  2856.   RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
  2857.   if ((c_updateToLock != RNIL) || 
  2858.       ((ERROR_INSERTED(7163)) && 
  2859.        (updateState == UpdateToReq::TO_COPY_FRAG_COMPLETED)) ||
  2860.       ((ERROR_INSERTED(7169)) && 
  2861.        (updateState == UpdateToReq::TO_COPY_COMPLETED))) {
  2862.     jam();
  2863.     takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_WAIT_UPDATE_TO;
  2864.     signal->theData[0] = DihContinueB::ZSEND_UPDATE_TO;
  2865.     signal->theData[1] = takeOverPtrI;
  2866.     signal->theData[2] = takeOverPtr.p->toStartingNode;
  2867.     signal->theData[3] = takeOverPtr.p->toFailedNode;
  2868.     signal->theData[4] = updateState;
  2869.     sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 30, 5);
  2870.     return;
  2871.   }//if
  2872.   c_updateToLock = takeOverPtrI;
  2873.   if (updateState == UpdateToReq::TO_COPY_FRAG_COMPLETED) {
  2874.     jam();
  2875.     takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_UPDATE_TO;
  2876.   } else {
  2877.     jam();
  2878.     ndbrequire(updateState == UpdateToReq::TO_COPY_COMPLETED);
  2879.     takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_COPY_COMPLETED;
  2880.   }//if
  2881.   UpdateToReq * const req = (UpdateToReq *)&signal->theData[0];
  2882.   req->userPtr = takeOverPtr.i;
  2883.   req->userRef = reference();
  2884.   req->updateState = (UpdateToReq::UpdateState)updateState;
  2885.   req->startingNodeId = takeOverPtr.p->toStartingNode;
  2886.   req->tableId = takeOverPtr.p->toCurrentTabref;
  2887.   req->fragmentNo = takeOverPtr.p->toCurrentFragid;
  2888.   sendLoopMacro(UPDATE_TOREQ, sendUPDATE_TOREQ);
  2889. }//Dbdih::sendUpdateTo()
  2890. void Dbdih::execUPDATE_TOREQ(Signal* signal)
  2891. {
  2892.   jamEntry();
  2893.   const UpdateToReq * const req = (UpdateToReq *)&signal->theData[0];
  2894.   BlockReference ref = req->userRef;
  2895.   ndbrequire(cmasterdihref == ref);
  2896.   CRASH_INSERTION(7154);
  2897.   RETURN_IF_NODE_NOT_ALIVE(req->startingNodeId);
  2898.   TakeOverRecordPtr takeOverPtr;
  2899.   takeOverPtr.i = req->userPtr;
  2900.   ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
  2901.   ndbrequire(req->startingNodeId == takeOverPtr.p->toStartingNode);
  2902.   if (req->updateState == UpdateToReq::TO_COPY_FRAG_COMPLETED) {
  2903.     jam();
  2904.     ndbrequire(takeOverPtr.p->toSlaveStatus == TakeOverRecord::TO_SLAVE_CREATE_PREPARE);
  2905.     takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_SLAVE_COPY_FRAG_COMPLETED;
  2906.     takeOverPtr.p->toCurrentTabref = req->tableId;
  2907.     takeOverPtr.p->toCurrentFragid = req->fragmentNo;
  2908.   } else {
  2909.     jam();
  2910.     ndbrequire(req->updateState == UpdateToReq::TO_COPY_COMPLETED);
  2911.     takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_SLAVE_COPY_COMPLETED;
  2912.     setNodeCopyCompleted(takeOverPtr.p->toStartingNode, true);
  2913.   }//if
  2914.   UpdateToConf * const conf = (UpdateToConf *)&signal->theData[0];
  2915.   conf->userPtr = takeOverPtr.i;
  2916.   conf->sendingNodeId = cownNodeId;
  2917.   conf->startingNodeId = takeOverPtr.p->toStartingNode;
  2918.   sendSignal(ref, GSN_UPDATE_TOCONF, signal, UpdateToConf::SignalLength, JBB);
  2919. }//Dbdih::execUPDATE_TOREQ()
  2920. void Dbdih::execUPDATE_TOCONF(Signal* signal)
  2921. {
  2922.   const UpdateToConf * const conf = (UpdateToConf *)&signal->theData[0];
  2923.   CRASH_INSERTION(7152);
  2924.   RETURN_IF_NODE_NOT_ALIVE(conf->startingNodeId);
  2925.   TakeOverRecordPtr takeOverPtr;
  2926.   takeOverPtr.i = conf->userPtr;
  2927.   ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
  2928.   receiveLoopMacro(UPDATE_TOREQ, conf->sendingNodeId);
  2929.   CRASH_INSERTION(7153);
  2930.   c_updateToLock = RNIL;
  2931.   if (takeOverPtr.p->toMasterStatus == TakeOverRecord::TO_COPY_COMPLETED) {
  2932.     jam();
  2933.     toCopyCompletedLab(signal, takeOverPtr);
  2934.     return;
  2935.   } else {
  2936.     ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::TO_UPDATE_TO);
  2937.   }//if
  2938.   TabRecordPtr tabPtr;
  2939.   tabPtr.i = takeOverPtr.p->toCurrentTabref;
  2940.   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  2941.   FragmentstorePtr fragPtr;
  2942.   getFragstore(tabPtr.p, takeOverPtr.p->toCurrentFragid, fragPtr);
  2943.   takeOverPtr.p->toMasterStatus = TakeOverRecord::COPY_ACTIVE;
  2944.   BlockReference lqhRef = calcLqhBlockRef(takeOverPtr.p->toStartingNode);
  2945.   CopyActiveReq * const req = (CopyActiveReq *)&signal->theData[0];
  2946.   req->userPtr = takeOverPtr.i;
  2947.   req->userRef = reference();
  2948.   req->tableId = takeOverPtr.p->toCurrentTabref;
  2949.   req->fragId = takeOverPtr.p->toCurrentFragid;
  2950.   req->distributionKey = fragPtr.p->distributionKey;
  2951.   sendSignal(lqhRef, GSN_COPY_ACTIVEREQ, signal,
  2952.              CopyActiveReq::SignalLength, JBB);
  2953. }//Dbdih::execUPDATE_TOCONF()
  2954. void Dbdih::execCOPY_ACTIVECONF(Signal* signal) 
  2955. {
  2956.   const CopyActiveConf * const conf = (CopyActiveConf *)&signal->theData[0];
  2957.   jamEntry();
  2958.   CRASH_INSERTION(7143);
  2959.   TakeOverRecordPtr takeOverPtr;
  2960.   takeOverPtr.i = conf->userPtr;
  2961.   ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
  2962.   ndbrequire(conf->tableId == takeOverPtr.p->toCurrentTabref);
  2963.   ndbrequire(conf->fragId == takeOverPtr.p->toCurrentFragid);
  2964.   ndbrequire(checkNodeAlive(conf->startingNodeId));
  2965.   ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::COPY_ACTIVE);
  2966.   takeOverPtr.p->startGci = conf->startGci;
  2967.   takeOverPtr.p->toMasterStatus = TakeOverRecord::LOCK_MUTEX;
  2968.   
  2969.   Mutex mutex(signal, c_mutexMgr, takeOverPtr.p->m_switchPrimaryMutexHandle);
  2970.   Callback c = { safe_cast(&Dbdih::switchPrimaryMutex_locked), takeOverPtr.i };
  2971.   ndbrequire(mutex.lock(c));
  2972. }//Dbdih::execCOPY_ACTIVECONF()
  2973. void
  2974. Dbdih::switchPrimaryMutex_locked(Signal* signal, Uint32 toPtrI, Uint32 retVal){
  2975.   jamEntry();
  2976.   ndbrequire(retVal == 0);
  2977.   TakeOverRecordPtr takeOverPtr;
  2978.   takeOverPtr.i = toPtrI;
  2979.   ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
  2980.   ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::LOCK_MUTEX);
  2981.   
  2982.   if (!checkNodeAlive((takeOverPtr.p->toStartingNode))) {
  2983.     // We have mutex
  2984.     Mutex mutex(signal, c_mutexMgr, takeOverPtr.p->m_switchPrimaryMutexHandle);
  2985.     mutex.unlock(); // Ignore result
  2986.     
  2987.     c_createFragmentLock = RNIL;
  2988.     c_CREATE_FRAGREQ_Counter.clearWaitingFor();
  2989.     endTakeOver(takeOverPtr.i);
  2990.     return;
  2991.   }
  2992.   
  2993.   takeOverPtr.p->toMasterStatus = TakeOverRecord::COMMIT_CREATE;
  2994.   sendCreateFragReq(signal, takeOverPtr.p->startGci, 
  2995.     CreateFragReq::COMMIT_STORED, takeOverPtr.i);
  2996. }
  2997. void Dbdih::toCopyCompletedLab(Signal * signal, TakeOverRecordPtr takeOverPtr)
  2998. {
  2999.   signal->theData[0] = EventReport::NR_CopyFragsCompleted;
  3000.   signal->theData[1] = takeOverPtr.p->toStartingNode;
  3001.   sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
  3002.   c_lcpState.immediateLcpStart = true;
  3003.   takeOverPtr.p->toMasterStatus = TakeOverRecord::WAIT_LCP;
  3004.   
  3005.   /*-----------------------------------------------------------------------*/
  3006.   /* NOW WE CAN ALLOW THE NEW NODE TO PARTICIPATE IN LOCAL CHECKPOINTS.    */
  3007.   /* WHEN THE FIRST LOCAL CHECKPOINT IS READY WE DECLARE THE TAKE OVER AS  */
  3008.   /* COMPLETED. SINCE LOCAL CHECKPOINTS HAVE BEEN BLOCKED DURING THE COPY  */
  3009.   /* PROCESS WE MUST ALSO START A NEW LOCAL CHECKPOINT PROCESS BY ENSURING */
  3010.   /* THAT IT LOOKS LIKE IT IS TIME FOR A NEW LOCAL CHECKPOINT AND BY       */
  3011.   /* UNBLOCKING THE LOCAL CHECKPOINT AGAIN.                                */
  3012.   /* --------------------------------------------------------------------- */
  3013. }//Dbdih::toCopyCompletedLab()
  3014. void Dbdih::sendEndTo(Signal* signal, Uint32 takeOverPtrI)
  3015. {
  3016.   TakeOverRecordPtr takeOverPtr;
  3017.   CRASH_INSERTION(7156);
  3018.   RETURN_IF_TAKE_OVER_INTERRUPTED(takeOverPtrI, takeOverPtr);
  3019.   if ((c_endToLock != RNIL) || (ERROR_INSERTED(7164))) {
  3020.     jam();
  3021.     takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_WAIT_ENDING;
  3022.     signal->theData[0] = DihContinueB::ZSEND_END_TO;
  3023.     signal->theData[1] = takeOverPtrI;
  3024.     signal->theData[2] = takeOverPtr.p->toStartingNode;
  3025.     signal->theData[3] = takeOverPtr.p->toFailedNode;
  3026.     sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 30, 4);
  3027.     return;
  3028.   }//if
  3029.   c_endToLock = takeOverPtr.i;
  3030.   takeOverPtr.p->toMasterStatus = TakeOverRecord::ENDING;
  3031.   EndToReq * const req = (EndToReq *)&signal->theData[0];
  3032.   req->userPtr = takeOverPtr.i;
  3033.   req->userRef = reference();
  3034.   req->startingNodeId = takeOverPtr.p->toStartingNode;
  3035.   sendLoopMacro(END_TOREQ, sendEND_TOREQ);
  3036. }//Dbdih::sendStartTo()
  3037. void Dbdih::execEND_TOREQ(Signal* signal)
  3038. {
  3039.   jamEntry();
  3040.   const EndToReq * const req = (EndToReq *)&signal->theData[0];
  3041.   BlockReference ref = req->userRef;
  3042.   Uint32 startingNodeId = req->startingNodeId;
  3043.   CRASH_INSERTION(7144);
  3044.   RETURN_IF_NODE_NOT_ALIVE(startingNodeId);
  3045.   TakeOverRecordPtr takeOverPtr;
  3046.   takeOverPtr.i = req->userPtr;
  3047.   ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
  3048.   ndbrequire(startingNodeId == takeOverPtr.p->toStartingNode);
  3049.   takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_SLAVE_IDLE;
  3050.   
  3051.   if (!isMaster()) {
  3052.     jam();
  3053.     endTakeOver(takeOverPtr.i);
  3054.   }//if
  3055.   EndToConf * const conf = (EndToConf *)&signal->theData[0];
  3056.   conf->userPtr = takeOverPtr.i;
  3057.   conf->sendingNodeId = cownNodeId;
  3058.   conf->startingNodeId = startingNodeId;
  3059.   sendSignal(ref, GSN_END_TOCONF, signal, EndToConf::SignalLength, JBB);
  3060. }//Dbdih::execEND_TOREQ()
  3061. void Dbdih::execEND_TOCONF(Signal* signal) 
  3062. {
  3063.   const EndToConf * const conf = (EndToConf *)&signal->theData[0];
  3064.   jamEntry();
  3065.   const Uint32 nodeId = conf->startingNodeId;
  3066.   CRASH_INSERTION(7145);
  3067.   RETURN_IF_NODE_NOT_ALIVE(nodeId);
  3068.   TakeOverRecordPtr takeOverPtr;
  3069.   takeOverPtr.i = conf->userPtr;
  3070.   ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
  3071.   ndbrequire(takeOverPtr.p->toMasterStatus == TakeOverRecord::ENDING);
  3072.   ndbrequire(nodeId == takeOverPtr.p->toStartingNode);
  3073.   receiveLoopMacro(END_TOREQ, conf->sendingNodeId);
  3074.   CRASH_INSERTION(7146);
  3075.   c_endToLock = RNIL;
  3076.   /* -----------------------------------------------------------------------*/
  3077.   /*  WE HAVE FINALLY COMPLETED THE TAKE OVER. WE RESET THE STATUS AND CHECK*/
  3078.   /*  IF ANY MORE TAKE OVERS ARE NEEDED AT THE MOMENT.                      */
  3079.   /*  FIRST WE CHECK IF A RESTART IS ONGOING. IN THAT CASE WE RESTART PHASE */
  3080.   /*  4 AND CHECK IF ANY MORE TAKE OVERS ARE NEEDED BEFORE WE START NDB     */
  3081.   /*  CLUSTER. THIS CAN ONLY HAPPEN IN A SYSTEM RESTART.                    */
  3082.   /* ---------------------------------------------------------------------- */
  3083.   if (takeOverPtr.p->toNodeRestart) {
  3084.     jam();
  3085.     /* ----------------------------------------------------------------------*/
  3086.     /* THE TAKE OVER NODE WAS A STARTING NODE. WE WILL SEND START_COPYCONF   */
  3087.     /* TO THE STARTING NODE SUCH THAT THE NODE CAN COMPLETE THE START-UP.    */
  3088.     /* --------------------------------------------------------------------- */
  3089.     BlockReference ref = calcDihBlockRef(takeOverPtr.p->toStartingNode);
  3090.     signal->theData[0] = takeOverPtr.p->toStartingNode;
  3091.     sendSignal(ref, GSN_START_COPYCONF, signal, 1,JBB);
  3092.   }//if
  3093.   endTakeOver(takeOverPtr.i);
  3094.   ndbout_c("2 - endTakeOver");
  3095.   if (cstartPhase == ZNDB_SPH4) {
  3096.     jam();
  3097.     ndbrequire(false);
  3098.     if (anyActiveTakeOver()) {
  3099.       jam();
  3100.       ndbout_c("4 - anyActiveTakeOver == true");
  3101.       return;
  3102.     }//if
  3103.     ndbout_c("5 - anyActiveTakeOver == false -> ndbsttorry10Lab");
  3104.     ndbsttorry10Lab(signal, __LINE__);
  3105.     return;
  3106.   }//if
  3107.   checkStartTakeOver(signal);
  3108. }//Dbdih::execEND_TOCONF()
  3109. void Dbdih::allocateTakeOver(TakeOverRecordPtr& takeOverPtr)
  3110. {
  3111.   if (isMaster()) {
  3112.     jam();
  3113.     //--------------------------------------------
  3114.     // Master already seized the take over record.
  3115.     //--------------------------------------------
  3116.     return;
  3117.   }//if
  3118.   if (takeOverPtr.i == cfirstfreeTakeOver) {
  3119.     jam();
  3120.     seizeTakeOver(takeOverPtr);
  3121.   } else {
  3122.     TakeOverRecordPtr nextTakeOverptr;
  3123.     TakeOverRecordPtr prevTakeOverptr;
  3124.     nextTakeOverptr.i = takeOverPtr.p->nextTakeOver;
  3125.     prevTakeOverptr.i = takeOverPtr.p->prevTakeOver;
  3126.     if (prevTakeOverptr.i != RNIL) {
  3127.       jam();
  3128.       ptrCheckGuard(prevTakeOverptr, MAX_NDB_NODES, takeOverRecord);
  3129.       prevTakeOverptr.p->nextTakeOver = nextTakeOverptr.i;
  3130.     }//if
  3131.     if (nextTakeOverptr.i != RNIL) {
  3132.       jam();
  3133.       ptrCheckGuard(nextTakeOverptr, MAX_NDB_NODES, takeOverRecord);
  3134.       nextTakeOverptr.p->prevTakeOver = prevTakeOverptr.i;
  3135.     }//if
  3136.   }//if
  3137. }//Dbdih::allocateTakeOver()
  3138. void Dbdih::seizeTakeOver(TakeOverRecordPtr& takeOverPtr)
  3139. {
  3140.   TakeOverRecordPtr nextTakeOverptr;
  3141.   ndbrequire(cfirstfreeTakeOver != RNIL);
  3142.   takeOverPtr.i = cfirstfreeTakeOver;
  3143.   ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
  3144.   cfirstfreeTakeOver = takeOverPtr.p->nextTakeOver;
  3145.   nextTakeOverptr.i = takeOverPtr.p->nextTakeOver;
  3146.   if (nextTakeOverptr.i != RNIL) {
  3147.     jam();
  3148.     ptrCheckGuard(nextTakeOverptr, MAX_NDB_NODES, takeOverRecord);
  3149.     nextTakeOverptr.p->prevTakeOver = RNIL;
  3150.   }//if
  3151.   takeOverPtr.p->nextTakeOver = RNIL;
  3152.   takeOverPtr.p->prevTakeOver = RNIL;
  3153. }//Dbdih::seizeTakeOver()
  3154. void Dbdih::endTakeOver(Uint32 takeOverPtrI)
  3155. {
  3156.   TakeOverRecordPtr takeOverPtr;
  3157.   takeOverPtr.i = takeOverPtrI;
  3158.   ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
  3159.   releaseTakeOver(takeOverPtrI);
  3160.   if ((takeOverPtr.p->toMasterStatus != TakeOverRecord::IDLE) &&
  3161.       (takeOverPtr.p->toMasterStatus != TakeOverRecord::TO_WAIT_START_TAKE_OVER)) {
  3162.     jam();
  3163.     NodeGroupRecordPtr NGPtr;
  3164.     NodeRecordPtr nodePtr;
  3165.     nodePtr.i = takeOverPtr.p->toStartingNode;
  3166.     ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
  3167.     NGPtr.i = nodePtr.p->nodeGroup;
  3168.     ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
  3169.     NGPtr.p->activeTakeOver = false;
  3170.   }//if
  3171.   setAllowNodeStart(takeOverPtr.p->toStartingNode, true);
  3172.   initTakeOver(takeOverPtr);
  3173. }//Dbdih::endTakeOver()
  3174. void Dbdih::releaseTakeOver(Uint32 takeOverPtrI)
  3175. {
  3176.   TakeOverRecordPtr takeOverPtr;
  3177.   takeOverPtr.i = takeOverPtrI;
  3178.   ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
  3179.   takeOverPtr.p->nextTakeOver = cfirstfreeTakeOver;
  3180.   cfirstfreeTakeOver = takeOverPtr.i;
  3181. }//Dbdih::releaseTakeOver()
  3182. void Dbdih::initTakeOver(TakeOverRecordPtr takeOverPtr)
  3183. {
  3184.   takeOverPtr.p->toCopyNode = RNIL;
  3185.   takeOverPtr.p->toCurrentFragid = RNIL;
  3186.   takeOverPtr.p->toCurrentReplica = RNIL;
  3187.   takeOverPtr.p->toCurrentTabref = RNIL;
  3188.   takeOverPtr.p->toFailedNode = RNIL;
  3189.   takeOverPtr.p->toStartingNode = RNIL;
  3190.   takeOverPtr.p->prevTakeOver = RNIL;
  3191.   takeOverPtr.p->nextTakeOver = RNIL;
  3192.   takeOverPtr.p->toNodeRestart = false;
  3193.   takeOverPtr.p->toMasterStatus = TakeOverRecord::IDLE;
  3194.   takeOverPtr.p->toSlaveStatus = TakeOverRecord::TO_SLAVE_IDLE;
  3195. }//Dbdih::initTakeOver()
  3196. bool Dbdih::anyActiveTakeOver()
  3197. {
  3198.   TakeOverRecordPtr takeOverPtr;
  3199.   for (takeOverPtr.i = 0; takeOverPtr.i < MAX_NDB_NODES; takeOverPtr.i++) {
  3200.     ptrAss(takeOverPtr, takeOverRecord);
  3201.     if (takeOverPtr.p->toMasterStatus != TakeOverRecord::IDLE) {
  3202.       jam();
  3203.       return true;
  3204.     }//if
  3205.   }//for
  3206.   return false;
  3207. }//Dbdih::anyActiveTakeOver()
  3208. /*****************************************************************************/
  3209. /* ------------------------------------------------------------------------- */
  3210. /*       WE HAVE BEEN REQUESTED TO PERFORM A SYSTEM RESTART. WE START BY     */
  3211. /*       READING THE GCI FILES. THIS REQUEST WILL ONLY BE SENT TO THE MASTER */
  3212. /*       DIH. THAT MEANS WE HAVE TO REPLICATE THE INFORMATION WE READ FROM   */
  3213. /*       OUR FILES TO ENSURE THAT ALL NODES HAVE THE SAME DISTRIBUTION       */
  3214. /*       INFORMATION.                                                        */
  3215. /* ------------------------------------------------------------------------- */
  3216. /*****************************************************************************/
  3217. void Dbdih::readGciFileLab(Signal* signal) 
  3218. {
  3219.   FileRecordPtr filePtr;
  3220.   filePtr.i = crestartInfoFile[0];
  3221.   ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
  3222.   filePtr.p->reqStatus = FileRecord::OPENING_GCP;
  3223.   openFileRo(signal, filePtr);
  3224. }//Dbdih::readGciFileLab()
  3225. void Dbdih::openingGcpLab(Signal* signal, FileRecordPtr filePtr) 
  3226. {
  3227.   /* ----------------------------------------------------------------------- */
  3228.   /*     WE HAVE SUCCESSFULLY OPENED A FILE CONTAINING INFORMATION ABOUT     */
  3229.   /*     THE GLOBAL CHECKPOINTS THAT ARE POSSIBLE TO RESTART.                */
  3230.   /* ----------------------------------------------------------------------- */
  3231.   readRestorableGci(signal, filePtr);
  3232.   filePtr.p->reqStatus = FileRecord::READING_GCP;
  3233. }//Dbdih::openingGcpLab()
  3234. void Dbdih::readingGcpLab(Signal* signal, FileRecordPtr filePtr) 
  3235. {
  3236.   /* ----------------------------------------------------------------------- */
  3237.   /*     WE HAVE NOW SUCCESSFULLY MANAGED TO READ IN THE GLOBAL CHECKPOINT   */
  3238.   /*     INFORMATION FROM FILE. LATER WE WILL ADD SOME FUNCTIONALITY THAT    */
  3239.   /*     CHECKS THE RESTART TIMERS TO DEDUCE FROM WHERE TO RESTART.          */
  3240.   /*     NOW WE WILL SIMPLY RESTART FROM THE NEWEST GLOBAL CHECKPOINT        */
  3241.   /*     POSSIBLE TO RESTORE.                                                */
  3242.   /*                                                                         */
  3243.   /*     BEFORE WE INVOKE DICT WE NEED TO COPY CRESTART_INFO TO ALL NODES.   */
  3244.   /*     WE ALSO COPY TO OUR OWN NODE. TO ENABLE US TO DO THIS PROPERLY WE   */
  3245.   /*     START BY CLOSING THIS FILE.                                         */
  3246.   /* ----------------------------------------------------------------------- */
  3247.   closeFile(signal, filePtr);
  3248.   filePtr.p->reqStatus = FileRecord::CLOSING_GCP;
  3249. }//Dbdih::readingGcpLab()
  3250. void Dbdih::closingGcpLab(Signal* signal, FileRecordPtr filePtr) 
  3251. {
  3252.   if (Sysfile::getInitialStartOngoing(SYSFILE->systemRestartBits) == false){
  3253.     jam();
  3254.     selectMasterCandidateAndSend(signal); 
  3255.     return;
  3256.   } else {
  3257.     jam();
  3258.     sendSignal(cntrlblockref, GSN_DIH_RESTARTREF, signal, 1, JBB);
  3259.     return;
  3260.   }//if
  3261. }//Dbdih::closingGcpLab()
  3262. /* ------------------------------------------------------------------------- */
  3263. /*       SELECT THE MASTER CANDIDATE TO BE USED IN SYSTEM RESTARTS.          */
  3264. /* ------------------------------------------------------------------------- */
  3265. void Dbdih::selectMasterCandidateAndSend(Signal* signal)
  3266. {
  3267.   Uint32 gci = 0;
  3268.   Uint32 masterCandidateId = 0;
  3269.   NodeRecordPtr nodePtr;
  3270.   for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
  3271.     jam();
  3272.     ptrAss(nodePtr, nodeRecord);
  3273.     if (SYSFILE->lastCompletedGCI[nodePtr.i] > gci) {
  3274.       jam();
  3275.       masterCandidateId = nodePtr.i;
  3276.       gci = SYSFILE->lastCompletedGCI[nodePtr.i];
  3277.     }//if
  3278.   }//for
  3279.   ndbrequire(masterCandidateId != 0);
  3280.   setNodeGroups();
  3281.   signal->theData[0] = masterCandidateId;
  3282.   signal->theData[1] = gci;
  3283.   sendSignal(cntrlblockref, GSN_DIH_RESTARTCONF, signal, 2, JBB);
  3284.   Uint32 node_groups[MAX_NDB_NODES];
  3285.   memset(node_groups, 0, sizeof(node_groups));
  3286.   for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
  3287.     jam();
  3288.     const Uint32 ng = Sysfile::getNodeGroup(nodePtr.i, SYSFILE->nodeGroups);
  3289.     if(ng != NO_NODE_GROUP_ID){
  3290.       ndbrequire(ng < MAX_NDB_NODES);
  3291.       node_groups[ng]++;
  3292.     }
  3293.   }
  3294.   
  3295.   for (nodePtr.i = 0; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
  3296.     jam();
  3297.     Uint32 count = node_groups[nodePtr.i];
  3298.     if(count != 0 && count != cnoReplicas){
  3299.       char buf[255];
  3300.       BaseString::snprintf(buf, sizeof(buf), 
  3301.        "Illegal configuration change."
  3302.        " Initial start needs to be performed "
  3303.        " when changing no of replicas (%d != %d)", 
  3304.        node_groups[nodePtr.i], cnoReplicas);
  3305.       progError(__LINE__, 
  3306. ERR_INVALID_CONFIG,
  3307. buf);
  3308.     }
  3309.   }
  3310. }//Dbdih::selectMasterCandidate()
  3311. /* ------------------------------------------------------------------------- */
  3312. /*       ERROR HANDLING DURING READING RESTORABLE GCI FROM FILE.             */
  3313. /* ------------------------------------------------------------------------- */
  3314. void Dbdih::openingGcpErrorLab(Signal* signal, FileRecordPtr filePtr) 
  3315. {
  3316.   filePtr.p->fileStatus = FileRecord::CRASHED;
  3317.   filePtr.p->reqStatus = FileRecord::IDLE;
  3318.   if (crestartInfoFile[0] == filePtr.i) {
  3319.     jam();
  3320.     /* --------------------------------------------------------------------- */
  3321.     /*   THE FIRST FILE WAS NOT ABLE TO BE OPENED. SET STATUS TO CRASHED AND */
  3322.     /*   TRY OPEN THE NEXT FILE.                                             */
  3323.     /* --------------------------------------------------------------------- */
  3324.     filePtr.i = crestartInfoFile[1];
  3325.     ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
  3326.     openFileRo(signal, filePtr);
  3327.     filePtr.p->reqStatus = FileRecord::OPENING_GCP;
  3328.   } else {
  3329.     jam();
  3330.     /* --------------------------------------------------------------------- */
  3331.     /*   WE FAILED IN OPENING THE SECOND FILE. BOTH FILES WERE CORRUPTED. WE */
  3332.     /*   CANNOT CONTINUE THE RESTART IN THIS CASE. TELL NDBCNTR OF OUR       */
  3333.     /*   FAILURE.                                                            */
  3334.     /*---------------------------------------------------------------------- */
  3335.     sendSignal(cntrlblockref, GSN_DIH_RESTARTREF, signal, 1, JBB);
  3336.     return;
  3337.   }//if
  3338. }//Dbdih::openingGcpErrorLab()
  3339. void Dbdih::readingGcpErrorLab(Signal* signal, FileRecordPtr filePtr) 
  3340. {
  3341.   filePtr.p->fileStatus = FileRecord::CRASHED;
  3342.   /* ----------------------------------------------------------------------- */
  3343.   /*     WE FAILED IN READING THE FILE AS WELL. WE WILL CLOSE THIS FILE.     */
  3344.   /* ----------------------------------------------------------------------- */
  3345.   closeFile(signal, filePtr);
  3346.   filePtr.p->reqStatus = FileRecord::CLOSING_GCP_CRASH;
  3347. }//Dbdih::readingGcpErrorLab()
  3348. void Dbdih::closingGcpCrashLab(Signal* signal, FileRecordPtr filePtr) 
  3349. {
  3350.   if (crestartInfoFile[0] == filePtr.i) {