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

MySQL数据库

开发平台:

Visual C++

  1.     tupKeyReq->opRef = tcConnectptr.i;
  2.     tupKeyReq->applRef = cownref;
  3.     tupKeyReq->schemaVersion = scanptr.p->scanSchemaVersion;
  4.     tupKeyReq->storedProcedure = scanptr.p->scanStoredProcId;
  5.     tupKeyReq->transId1 = tcConnectptr.p->transid[0];
  6.     tupKeyReq->transId2 = tcConnectptr.p->transid[1];
  7.     tupKeyReq->fragPtr = tupFragPtr;
  8.     tupKeyReq->primaryReplica = (tcConnectptr.p->seqNoReplica == 0)?true:false;
  9.     tupKeyReq->coordinatorTC = tcConnectptr.p->tcBlockref;
  10.     tupKeyReq->tcOpIndex = tcConnectptr.p->tcOprec;
  11.     tupKeyReq->savePointId = tcConnectptr.p->savePointId;
  12.     Uint32 blockNo = refToBlock(tcConnectptr.p->tcTupBlockref);
  13.     EXECUTE_DIRECT(blockNo, GSN_TUPKEYREQ, signal, 
  14.                TupKeyReq::SignalLength);
  15.   }
  16. }//Dblqh::copySendTupkeyReqLab()
  17. /*---------------------------------------------------------------------------*/
  18. /*   USED IN COPYING OPERATION TO RECEIVE ATTRINFO FROM TUP.                 */
  19. /*---------------------------------------------------------------------------*/
  20. /* ************>> */
  21. /*  TRANSID_AI  > */
  22. /* ************>> */
  23. void Dblqh::execTRANSID_AI(Signal* signal) 
  24. {
  25.   jamEntry();
  26.   tcConnectptr.i = signal->theData[0];
  27.   ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
  28.   Uint32 length = signal->length() - 3;
  29.   ndbrequire(tcConnectptr.p->transactionState == TcConnectionrec::COPY_TUPKEY);
  30.   Uint32 * src = &signal->theData[3];
  31.   while(length > 22){
  32.     if (saveTupattrbuf(signal, src, 22) == ZOK) {
  33.       ;
  34.     } else {
  35.       jam();
  36.       tcConnectptr.p->errorCode = ZGET_ATTRINBUF_ERROR;
  37.       return;
  38.     }//if
  39.     src += 22;
  40.     length -= 22;
  41.   }
  42.   if (saveTupattrbuf(signal, src, length) == ZOK) {
  43.     return;
  44.   }
  45.   jam();
  46.   tcConnectptr.p->errorCode = ZGET_ATTRINBUF_ERROR;
  47. }//Dblqh::execTRANSID_AI()
  48. /*--------------------------------------------------------------------------*/
  49. /*     ENTER TUPKEYCONF WITH                                                */
  50. /*          TC_CONNECTPTR,                                                  */
  51. /*          TDATA2,                                                         */
  52. /*          TDATA3,                                                         */
  53. /*          TDATA4,                                                         */
  54. /*          TDATA5                                                          */
  55. /*--------------------------------------------------------------------------*/
  56. /*  PRECONDITION:   TRANSACTION_STATE = COPY_TUPKEY                         */
  57. /*--------------------------------------------------------------------------*/
  58. void Dblqh::copyTupkeyConfLab(Signal* signal) 
  59. {
  60.   const TupKeyConf * const tupKeyConf = (TupKeyConf *)signal->getDataPtr();
  61.   UintR readLength = tupKeyConf->readLength;
  62.   scanptr.i = tcConnectptr.p->tcScanRec;
  63.   c_scanRecordPool.getPtr(scanptr);
  64.   releaseActiveFrag(signal);
  65.   if (tcConnectptr.p->errorCode != 0) {
  66.     jam();
  67.     closeCopyLab(signal);
  68.     return;
  69.   }//if
  70.   if (scanptr.p->scanCompletedStatus == ZTRUE) {
  71.     jam();
  72. /*---------------------------------------------------------------------------*/
  73. /*   THE COPY PROCESS HAVE BEEN CLOSED. MOST LIKELY A NODE FAILURE.          */
  74. /*---------------------------------------------------------------------------*/
  75.     closeCopyLab(signal);
  76.     return;
  77.   }//if
  78.   tcConnectptr.p->totSendlenAi = readLength;
  79.   tcConnectptr.p->connectState = TcConnectionrec::COPY_CONNECTED;
  80.   calculateHash(signal);
  81. /*---------------------------------------------------------------------------*/
  82. // To avoid using up to many operation records in ACC we will increase the
  83. // constant to ensure that we never send more than 40 records at a time.
  84. // This is where the constant 56 comes from. For long records this constant
  85. // will not matter that much. The current maximum is 6000 words outstanding
  86. // (including a number of those 56 words not really sent). We also have to
  87. // ensure that there are never more simultaneous usage of these operation
  88. // records to ensure that node recovery does not fail because of simultaneous
  89. // scanning.
  90. /*---------------------------------------------------------------------------*/
  91.   UintR TnoOfWords = readLength + tcConnectptr.p->primKeyLen;
  92.   TnoOfWords = TnoOfWords + MAGIC_CONSTANT;
  93.   TnoOfWords = TnoOfWords + (TnoOfWords >> 2);
  94.   /*-----------------------------------------------------------------
  95.    * NOTE for transid1!
  96.    * Transid1 in the tcConnection record is used load regulate the 
  97.    * copy(node recovery) process.
  98.    * The number of outstanding words are written in the transid1 
  99.    * variable. This will be sent to the starting node in the 
  100.    * LQHKEYREQ signal and when the answer is returned in the LQHKEYCONF
  101.    * we can reduce the number of outstanding words and check to see
  102.    * if more LQHKEYREQ signals should be sent.
  103.    * 
  104.    * However efficient this method is rather unsafe in such way that
  105.    * it overwrites the transid1 original data.
  106.    *
  107.    * Also see TR 587.
  108.    *----------------------------------------------------------------*/
  109.   tcConnectptr.p->transid[0] = TnoOfWords; // Data overload, see note!
  110.   packLqhkeyreqLab(signal);
  111.   tcConnectptr.p->copyCountWords += TnoOfWords;
  112.   scanptr.p->scanState = ScanRecord::WAIT_LQHKEY_COPY;
  113.   if (tcConnectptr.p->copyCountWords < cmaxWordsAtNodeRec) {
  114.     nextRecordCopy(signal);
  115.     return;
  116.   }//if
  117.   return;
  118. }//Dblqh::copyTupkeyConfLab()
  119. /*---------------------------------------------------------------------------*/
  120. /*     ENTER LQHKEYCONF                                                      */
  121. /*---------------------------------------------------------------------------*/
  122. /*   PRECONDITION: CONNECT_STATE = COPY_CONNECTED                            */
  123. /*---------------------------------------------------------------------------*/
  124. void Dblqh::copyCompletedLab(Signal* signal) 
  125. {
  126.   const LqhKeyConf * const lqhKeyConf = (LqhKeyConf *)signal->getDataPtr();  
  127.   ndbrequire(tcConnectptr.p->transid[1] == lqhKeyConf->transId2);
  128.   scanptr.i = tcConnectptr.p->tcScanRec;
  129.   c_scanRecordPool.getPtr(scanptr);
  130.   if (tcConnectptr.p->copyCountWords >= cmaxWordsAtNodeRec) {
  131.     tcConnectptr.p->copyCountWords -= lqhKeyConf->transId1; // Data overload, see note!
  132.     if (scanptr.p->scanCompletedStatus == ZTRUE) {
  133.       jam();
  134. /*---------------------------------------------------------------------------*/
  135. // Copy to complete, we will not start any new copying.
  136. /*---------------------------------------------------------------------------*/
  137.       closeCopyLab(signal);
  138.       return;
  139.     }//if
  140.     if (tcConnectptr.p->copyCountWords < cmaxWordsAtNodeRec) {
  141.       jam();
  142.       nextRecordCopy(signal);
  143.     }//if
  144.     return;
  145.   }//if
  146.   tcConnectptr.p->copyCountWords -= lqhKeyConf->transId1; // Data overload, see note!
  147.   ndbrequire(tcConnectptr.p->copyCountWords <= cmaxWordsAtNodeRec);
  148.   if (tcConnectptr.p->copyCountWords > 0) {
  149.     jam();
  150.     return;
  151.   }//if
  152. /*---------------------------------------------------------------------------*/
  153. // No more outstanding copies. We will only start new ones from here if it was
  154. // stopped before and this only happens when copyCountWords is bigger than the
  155. // threshold value. Since this did not occur we must be waiting for completion.
  156. // Check that this is so. If not we crash to find out what is going on.
  157. /*---------------------------------------------------------------------------*/
  158.   if (scanptr.p->scanCompletedStatus == ZTRUE) {
  159.     jam();
  160.     closeCopyLab(signal);
  161.     return;
  162.   }//if
  163.   if (scanptr.p->scanState == ScanRecord::WAIT_LQHKEY_COPY) {
  164.     jam();
  165. /*---------------------------------------------------------------------------*/
  166. // Make sure that something is in progress. Otherwise we will simply stop
  167. // and nothing more will happen.
  168. /*---------------------------------------------------------------------------*/
  169.     systemErrorLab(signal);
  170.     return;
  171.   }//if
  172.   return;
  173. }//Dblqh::copyCompletedLab()
  174. void Dblqh::nextRecordCopy(Signal* signal)
  175. {
  176.   fragptr.i = tcConnectptr.p->fragmentptr;
  177.   ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
  178.   scanptr.i = tcConnectptr.p->tcScanRec;
  179.   c_scanRecordPool.getPtr(scanptr);
  180.   if (scanptr.p->scanState != ScanRecord::WAIT_LQHKEY_COPY) {
  181.     jam();
  182. /*---------------------------------------------------------------------------*/
  183. // Make sure that nothing is in progress. Otherwise we will have to simultaneous
  184. // scans on the same record and this will certainly lead to unexpected
  185. // behaviour.
  186. /*---------------------------------------------------------------------------*/
  187.     systemErrorLab(signal);
  188.     return;
  189.   }//if
  190.   scanptr.p->scanState = ScanRecord::WAIT_NEXT_SCAN_COPY;
  191.   switch (fragptr.p->fragStatus) {
  192.   case Fragrecord::FSACTIVE:
  193.     jam();
  194.     linkActiveFrag(signal);
  195.     break;
  196.   case Fragrecord::BLOCKED:
  197.     jam();
  198.     linkFragQueue(signal);
  199.     tcConnectptr.p->transactionState = TcConnectionrec::COPY_STOPPED;
  200.     return;
  201.     break;
  202.   case Fragrecord::FREE:
  203.     jam();
  204.   case Fragrecord::ACTIVE_CREATION:
  205.     jam();
  206.   case Fragrecord::CRASH_RECOVERING:
  207.     jam();
  208.   case Fragrecord::DEFINED:
  209.     jam();
  210.   case Fragrecord::REMOVING:
  211.     jam();
  212.   default:
  213.     jam();
  214.     systemErrorLab(signal);
  215.     return;
  216.     break;
  217.   }//switch
  218.   continueCopyAfterBlockedLab(signal);
  219.   return;
  220. }//Dblqh::nextRecordCopy()
  221. void Dblqh::continueCopyAfterBlockedLab(Signal* signal) 
  222. {
  223.   scanptr.i = tcConnectptr.p->tcScanRec;
  224.   c_scanRecordPool.getPtr(scanptr);
  225.   tcConnectptr.p->errorCode = 0;
  226.   Uint32 acc_op_ptr= get_acc_ptr_from_scan_record(scanptr.p, 0, false);
  227.   signal->theData[0] = scanptr.p->scanAccPtr;
  228.   signal->theData[1] = acc_op_ptr;
  229.   signal->theData[2] = NextScanReq::ZSCAN_NEXT_COMMIT;
  230.   sendSignal(tcConnectptr.p->tcAccBlockref, GSN_NEXT_SCANREQ, signal, 3, JBB);
  231.   return;
  232. }//Dblqh::continueCopyAfterBlockedLab()
  233. void Dblqh::copyLqhKeyRefLab(Signal* signal) 
  234. {
  235.   ndbrequire(tcConnectptr.p->transid[1] == signal->theData[4]);
  236.   tcConnectptr.p->copyCountWords -= signal->theData[3];
  237.   scanptr.i = tcConnectptr.p->tcScanRec;
  238.   c_scanRecordPool.getPtr(scanptr);
  239.   scanptr.p->scanErrorCounter++;
  240.   tcConnectptr.p->errorCode = terrorCode;
  241.   closeCopyLab(signal);
  242.   return;
  243. }//Dblqh::copyLqhKeyRefLab()
  244. void Dblqh::closeCopyLab(Signal* signal) 
  245. {
  246.   if (tcConnectptr.p->copyCountWords > 0) {
  247. /*---------------------------------------------------------------------------*/
  248. // We are still waiting for responses from the starting node.
  249. // Wait until all of those have arrived until we start the
  250. // close process.
  251. /*---------------------------------------------------------------------------*/
  252.     jam();
  253.     return;
  254.   }//if
  255.   tcConnectptr.p->transid[0] = 0;
  256.   tcConnectptr.p->transid[1] = 0;
  257.   fragptr.i = tcConnectptr.p->fragmentptr;
  258.   ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
  259.   scanptr.i = tcConnectptr.p->tcScanRec;
  260.   c_scanRecordPool.getPtr(scanptr);
  261.   scanptr.p->scanState = ScanRecord::WAIT_CLOSE_COPY;
  262.   switch (fragptr.p->fragStatus) {
  263.   case Fragrecord::FSACTIVE:
  264.     jam();
  265.     linkActiveFrag(signal);
  266.     break;
  267.   case Fragrecord::BLOCKED:
  268.     jam();
  269.     linkFragQueue(signal);
  270.     tcConnectptr.p->transactionState = TcConnectionrec::COPY_CLOSE_STOPPED;
  271.     return;
  272.     break;
  273.   case Fragrecord::FREE:
  274.     jam();
  275.   case Fragrecord::ACTIVE_CREATION:
  276.     jam();
  277.   case Fragrecord::CRASH_RECOVERING:
  278.     jam();
  279.   case Fragrecord::DEFINED:
  280.     jam();
  281.   case Fragrecord::REMOVING:
  282.     jam();
  283.   default:
  284.     jam();
  285.     systemErrorLab(signal);
  286.     return;
  287.     break;
  288.   }//switch
  289.   continueCloseCopyAfterBlockedLab(signal);
  290.   return;
  291. }//Dblqh::closeCopyLab()
  292. void Dblqh::continueCloseCopyAfterBlockedLab(Signal* signal) 
  293. {
  294.   scanptr.i = tcConnectptr.p->tcScanRec;
  295.   c_scanRecordPool.getPtr(scanptr);
  296.   signal->theData[0] = scanptr.p->scanAccPtr;
  297.   signal->theData[1] = RNIL;
  298.   signal->theData[2] = ZCOPY_CLOSE;
  299.   sendSignal(tcConnectptr.p->tcAccBlockref, GSN_NEXT_SCANREQ, signal, 3, JBB);
  300.   return;
  301. }//Dblqh::continueCloseCopyAfterBlockedLab()
  302. /*---------------------------------------------------------------------------*/
  303. /*   ENTER NEXT_SCANCONF WITH                                                */
  304. /*     SCANPTR,                                                              */
  305. /*     TFRAGID,                                                              */
  306. /*     TACC_OPPTR,                                                           */
  307. /*     TLOCAL_KEY1,                                                          */
  308. /*     TLOCAL_KEY2,                                                          */
  309. /*     TKEY_LENGTH,                                                          */
  310. /*     TKEY1,                                                                */
  311. /*     TKEY2,                                                                */
  312. /*     TKEY3,                                                                */
  313. /*     TKEY4                                                                 */
  314. /*---------------------------------------------------------------------------*/
  315. /*   PRECONDITION: SCAN_STATE = WAIT_CLOSE_COPY                              */
  316. /*---------------------------------------------------------------------------*/
  317. void Dblqh::accCopyCloseConfLab(Signal* signal) 
  318. {
  319.   tcConnectptr.i = scanptr.p->scanTcrec;
  320.   scanptr.p->scanState = ScanRecord::WAIT_DELETE_STORED_PROC_ID_COPY;
  321.   ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
  322.   signal->theData[0] = tcConnectptr.p->tupConnectrec;
  323.   signal->theData[1] = tcConnectptr.p->tableref;
  324.   signal->theData[2] = scanptr.p->scanSchemaVersion;
  325.   signal->theData[3] = ZDELETE_STORED_PROC_ID;
  326.   signal->theData[4] = scanptr.p->scanStoredProcId;
  327.   sendSignal(tcConnectptr.p->tcTupBlockref, GSN_STORED_PROCREQ, signal, 5, JBB);
  328.   return;
  329. }//Dblqh::accCopyCloseConfLab()
  330. /*---------------------------------------------------------------------------*/
  331. /*   ENTER STORED_PROCCONF WITH                                              */
  332. /*     TC_CONNECTPTR,                                                        */
  333. /*     TSTORED_PROC_ID                                                       */
  334. /*---------------------------------------------------------------------------*/
  335. /* PRECONDITION: SCAN_STATE = WAIT_DELETE_STORED_PROC_ID_COPY                */
  336. /*---------------------------------------------------------------------------*/
  337. void Dblqh::tupCopyCloseConfLab(Signal* signal) 
  338. {
  339.   fragptr.i = tcConnectptr.p->fragmentptr;
  340.   ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
  341.   fragptr.p->copyFragState = ZIDLE;
  342.   if (tcConnectptr.p->abortState == TcConnectionrec::NEW_FROM_TC) {
  343.     jam();
  344.     tcNodeFailptr.i = tcConnectptr.p->tcNodeFailrec;
  345.     ptrCheckGuard(tcNodeFailptr, ctcNodeFailrecFileSize, tcNodeFailRecord);
  346.     tcNodeFailptr.p->tcRecNow = tcConnectptr.i + 1;
  347.     signal->theData[0] = ZLQH_TRANS_NEXT;
  348.     signal->theData[1] = tcNodeFailptr.i;
  349.     sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
  350.     CopyFragRef * const ref = (CopyFragRef *)&signal->theData[0];
  351.     ref->userPtr = scanptr.p->copyPtr;
  352.     ref->sendingNodeId = cownNodeid;
  353.     ref->startingNodeId = scanptr.p->scanNodeId;
  354.     ref->tableId = fragptr.p->tabRef;
  355.     ref->fragId = fragptr.p->fragId;
  356.     ref->errorCode = ZNODE_FAILURE_ERROR;
  357.     sendSignal(scanptr.p->scanApiBlockref, GSN_COPY_FRAGREF, signal,
  358.                CopyFragRef::SignalLength, JBB);
  359.   } else {
  360.     if (scanptr.p->scanErrorCounter > 0) {
  361.       jam();
  362.       CopyFragRef * const ref = (CopyFragRef *)&signal->theData[0];
  363.       ref->userPtr = scanptr.p->copyPtr;
  364.       ref->sendingNodeId = cownNodeid;
  365.       ref->startingNodeId = scanptr.p->scanNodeId;
  366.       ref->tableId = fragptr.p->tabRef;
  367.       ref->fragId = fragptr.p->fragId;
  368.       ref->errorCode = tcConnectptr.p->errorCode;
  369.       sendSignal(scanptr.p->scanApiBlockref, GSN_COPY_FRAGREF, signal,
  370.                  CopyFragRef::SignalLength, JBB);
  371.     } else {
  372.       jam();
  373.       CopyFragConf * const conf = (CopyFragConf *)&signal->theData[0];
  374.       conf->userPtr = scanptr.p->copyPtr;
  375.       conf->sendingNodeId = cownNodeid;
  376.       conf->startingNodeId = scanptr.p->scanNodeId;
  377.       conf->tableId = tcConnectptr.p->tableref;
  378.       conf->fragId = tcConnectptr.p->fragmentid;
  379.       sendSignal(scanptr.p->scanApiBlockref, GSN_COPY_FRAGCONF, signal,
  380.                  CopyFragConf::SignalLength, JBB);
  381.     }//if
  382.   }//if
  383.   releaseActiveCopy(signal);
  384.   tcConnectptr.p->tcScanRec = RNIL;
  385.   finishScanrec(signal);
  386.   releaseOprec(signal);
  387.   releaseTcrec(signal, tcConnectptr);
  388.   releaseScanrec(signal);
  389. }//Dblqh::tupCopyCloseConfLab()
  390. /*---------------------------------------------------------------------------*/
  391. /*   A NODE FAILURE OCCURRED DURING THE COPY PROCESS. WE NEED TO CLOSE THE   */
  392. /*   COPY PROCESS SINCE A NODE FAILURE DURING THE COPY PROCESS WILL ALSO     */
  393. /*   FAIL THE NODE THAT IS TRYING TO START-UP.                               */
  394. /*---------------------------------------------------------------------------*/
  395. void Dblqh::closeCopyRequestLab(Signal* signal) 
  396. {
  397.   scanptr.p->scanErrorCounter++;
  398.   switch (scanptr.p->scanState) {
  399.   case ScanRecord::WAIT_TUPKEY_COPY:
  400.   case ScanRecord::WAIT_COPY_KEYINFO:
  401.   case ScanRecord::WAIT_NEXT_SCAN_COPY:
  402.     jam();
  403. /*---------------------------------------------------------------------------*/
  404. /*   SET COMPLETION STATUS AND WAIT FOR OPPORTUNITY TO STOP THE SCAN.        */
  405. //   ALSO SET NO OF WORDS OUTSTANDING TO ZERO TO AVOID ETERNAL WAIT.
  406. /*---------------------------------------------------------------------------*/
  407.     scanptr.p->scanCompletedStatus = ZTRUE;
  408.     tcConnectptr.p->copyCountWords = 0;
  409.     break;
  410.   case ScanRecord::WAIT_ACC_COPY:
  411.   case ScanRecord::WAIT_STORED_PROC_COPY:
  412.     jam();
  413. /*---------------------------------------------------------------------------*/
  414. /*   WE ARE CURRENTLY STARTING UP THE SCAN. SET COMPLETED STATUS AND WAIT FOR*/
  415. /*   COMPLETION OF STARTUP.                                                  */
  416. /*---------------------------------------------------------------------------*/
  417.     scanptr.p->scanCompletedStatus = ZTRUE;
  418.     break;
  419.   case ScanRecord::WAIT_CLOSE_COPY:
  420.   case ScanRecord::WAIT_DELETE_STORED_PROC_ID_COPY:
  421.     jam();
  422. /*---------------------------------------------------------------------------*/
  423. /*   CLOSE IS ALREADY ONGOING. WE NEED NOT DO ANYTHING.                      */
  424. /*---------------------------------------------------------------------------*/
  425.     break;
  426.   case ScanRecord::WAIT_LQHKEY_COPY:
  427.     jam();
  428. /*---------------------------------------------------------------------------*/
  429. /*   WE ARE WAITING FOR THE FAILED NODE. THE NODE WILL NEVER COME BACK.      */
  430. //   WE NEED TO START THE FAILURE HANDLING IMMEDIATELY.
  431. //   ALSO SET NO OF WORDS OUTSTANDING TO ZERO TO AVOID ETERNAL WAIT.
  432. /*---------------------------------------------------------------------------*/
  433.     tcConnectptr.p->copyCountWords = 0;
  434.     closeCopyLab(signal);
  435.     break;
  436.   default:
  437.     ndbrequire(false);
  438.     break;
  439.   }//switch
  440.   return;
  441. }//Dblqh::closeCopyRequestLab()
  442. /* ****************************************************** */
  443. /*  COPY_ACTIVEREQ: Change state of a fragment to ACTIVE. */
  444. /* ****************************************************** */
  445. void Dblqh::execCOPY_ACTIVEREQ(Signal* signal) 
  446. {
  447.   CRASH_INSERTION(5026);
  448.   const CopyActiveReq * const req = (CopyActiveReq *)&signal->theData[0];
  449.   jamEntry();
  450.   Uint32 masterPtr = req->userPtr;
  451.   BlockReference masterRef = req->userRef;
  452.   tabptr.i = req->tableId;
  453.   ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
  454.   Uint32 fragId = req->fragId;
  455.   ndbrequire(getFragmentrec(signal, fragId));
  456.   fragptr.p->fragDistributionKey = req->distributionKey;
  457.   
  458.   ndbrequire(cnoActiveCopy < 3);
  459.   cactiveCopy[cnoActiveCopy] = fragptr.i;
  460.   cnoActiveCopy++;
  461.   fragptr.p->masterBlockref = masterRef;
  462.   fragptr.p->masterPtr = masterPtr;
  463.   if (fragptr.p->fragStatus == Fragrecord::FSACTIVE) {
  464.     jam();
  465. /*------------------------------------------------------*/
  466. /*       PROCESS HAVE ALREADY BEEN STARTED BY PREVIOUS  */
  467. /*       MASTER. WE HAVE ALREADY SET THE PROPER MASTER  */
  468. /*       BLOCK REFERENCE.                               */
  469. /*------------------------------------------------------*/
  470.     if (fragptr.p->activeTcCounter == 0) {
  471.       jam();
  472. /*------------------------------------------------------*/
  473. /*       PROCESS WAS EVEN COMPLETED.                    */
  474. /*------------------------------------------------------*/
  475.       sendCopyActiveConf(signal, tabptr.i);
  476.     }//if
  477.     return;
  478.   }//if
  479.   fragptr.p->fragStatus = Fragrecord::FSACTIVE;
  480.   if (fragptr.p->lcpFlag == Fragrecord::LCP_STATE_TRUE) {
  481.     jam();
  482.     fragptr.p->logFlag = Fragrecord::STATE_TRUE;
  483.   }//if
  484.   fragptr.p->activeTcCounter = 1;
  485. /*------------------------------------------------------*/
  486. /*       SET IT TO ONE TO ENSURE THAT IT IS NOT POSSIBLE*/
  487. /*       TO DECREASE IT TO ZERO UNTIL WE HAVE COMPLETED */
  488. /*       THE SCAN.                                      */
  489. /*------------------------------------------------------*/
  490.   signal->theData[0] = ZSCAN_TC_CONNECT;
  491.   signal->theData[1] = 0;
  492.   signal->theData[2] = tabptr.i;
  493.   signal->theData[3] = fragId;
  494.   sendSignal(cownref, GSN_CONTINUEB, signal, 4, JBB);
  495.   return;
  496. }//Dblqh::execCOPY_ACTIVEREQ()
  497. void Dblqh::scanTcConnectLab(Signal* signal, Uint32 tstartTcConnect, Uint32 fragId) 
  498. {
  499.   Uint32 tendTcConnect;
  500.   ndbrequire(getFragmentrec(signal, fragId));
  501.   if ((tstartTcConnect + 200) >= ctcConnectrecFileSize) {
  502.     jam();
  503.     tendTcConnect = ctcConnectrecFileSize - 1;
  504.   } else {
  505.     jam();
  506.     tendTcConnect = tstartTcConnect + 200;
  507.   }//if
  508.   for (tcConnectptr.i = tstartTcConnect; 
  509.        tcConnectptr.i <= tendTcConnect; 
  510.        tcConnectptr.i++) {
  511.     jam();
  512.     ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
  513.     if (tcConnectptr.p->transactionState != TcConnectionrec::IDLE) {
  514.       switch (tcConnectptr.p->logWriteState) {
  515.       case TcConnectionrec::NOT_WRITTEN:
  516.         jam();
  517.         if (fragptr.i == tcConnectptr.p->fragmentptr) {
  518.           jam();
  519.           fragptr.p->activeTcCounter = fragptr.p->activeTcCounter + 1;
  520.           tcConnectptr.p->logWriteState = TcConnectionrec::NOT_WRITTEN_WAIT;
  521.         }//if
  522.         break;
  523.       default:
  524.         jam();
  525.         /*empty*/;
  526.         break;
  527.       }//switch
  528.     }//if
  529.   }//for
  530.   if (tendTcConnect < (ctcConnectrecFileSize - 1)) {
  531.     jam();
  532.     signal->theData[0] = ZSCAN_TC_CONNECT;
  533.     signal->theData[1] = tendTcConnect + 1;
  534.     signal->theData[2] = tabptr.i;
  535.     signal->theData[3] = fragId;
  536.     sendSignal(cownref, GSN_CONTINUEB, signal, 4, JBB);
  537.   } else {
  538.     jam();
  539. /*------------------------------------------------------*/
  540. /*       THE SCAN HAVE BEEN COMPLETED. WE CHECK IF ALL  */
  541. /*       OPERATIONS HAVE ALREADY BEEN COMPLETED.        */
  542. /*------------------------------------------------------*/
  543.     ndbrequire(fragptr.p->activeTcCounter > 0);
  544.     fragptr.p->activeTcCounter--;
  545.     if (fragptr.p->activeTcCounter == 0) {
  546.       jam();
  547. /*------------------------------------------------------*/
  548. /*       SET START GLOBAL CHECKPOINT TO THE NEXT        */
  549. /*       CHECKPOINT WE HAVE NOT YET HEARD ANYTHING ABOUT*/
  550. /*       THIS GCP WILL BE COMPLETELY COVERED BY THE LOG.*/
  551. /*------------------------------------------------------*/
  552.       fragptr.p->startGci = cnewestGci + 1;
  553.       sendCopyActiveConf(signal, tabptr.i);
  554.     }//if
  555.   }//if
  556.   return;
  557. }//Dblqh::scanTcConnectLab()
  558. /*---------------------------------------------------------------------------*/
  559. /*   A NEW MASTER IS REQUESTING THE STATE IN LQH OF THE COPY FRAGMENT PARTS. */
  560. /*---------------------------------------------------------------------------*/
  561. /* ***************>> */
  562. /*  COPY_STATEREQ  > */
  563. /* ***************>> */
  564. void Dblqh::execCOPY_STATEREQ(Signal* signal) 
  565. {
  566.   jamEntry();
  567.   ndbrequire(0)
  568. #if 0
  569.   Uint32* dataPtr = &signal->theData[2];
  570.   BlockReference tmasterBlockref = signal->theData[0];
  571.   Uint32 tnoCopy = 0;
  572.   do {
  573.     jam();
  574.     arrGuard(tnoCopy, 4);
  575.     fragptr.i = cactiveCopy[tnoCopy];
  576.     if (fragptr.i == RNIL) {
  577.       jam();
  578.       break;
  579.     }//if
  580.     ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
  581.     if (fragptr.p->copyFragState != ZIDLE) {
  582.       jam();
  583. /*---------------------------------------------------------------------------*/
  584. /*   THIS FRAGMENT IS CURRENTLY ACTIVE IN COPYING THE FRAGMENT.              */
  585. /*---------------------------------------------------------------------------*/
  586.       scanptr.i = fragptr.p->fragScanRec[NR_ScanNo];
  587.       c_scanRecordPool.getPtr(scanptr);
  588.       if (scanptr.p->scanCompletedStatus == ZTRUE) {
  589.         jam();
  590.         dataPtr[3 + (tnoCopy << 2)] = ZCOPY_CLOSING;
  591.       } else {
  592.         jam();
  593.         dataPtr[3 + (tnoCopy << 2)] = ZCOPY_ONGOING;
  594.       }//if
  595.       dataPtr[2 + (tnoCopy << 2)] = scanptr.p->scanSchemaVersion;
  596.       scanptr.p->scanApiBlockref = tmasterBlockref;
  597.     } else {
  598.       ndbrequire(fragptr.p->activeTcCounter != 0);
  599. /*---------------------------------------------------------------------------*/
  600. /*   COPY FRAGMENT IS COMPLETED AND WE ARE CURRENTLY GETTING THE STARTING    */
  601. /*   GCI OF THE NEW REPLICA OF THIS FRAGMENT.                                */
  602. /*---------------------------------------------------------------------------*/
  603.       fragptr.p->masterBlockref = tmasterBlockref;
  604.       dataPtr[3 + (tnoCopy << 2)] = ZCOPY_ACTIVATION;
  605.     }//if
  606.     dataPtr[tnoCopy << 2] = fragptr.p->tabRef;
  607.     dataPtr[1 + (tnoCopy << 2)] = fragptr.p->fragId;
  608.     tnoCopy++;
  609.   } while (tnoCopy < cnoActiveCopy);
  610.   signal->theData[0] = cownNodeid;
  611.   signal->theData[1] = tnoCopy;
  612.   sendSignal(tmasterBlockref, GSN_COPY_STATECONF, signal, 18, JBB);
  613. #endif
  614.   return;
  615. }//Dblqh::execCOPY_STATEREQ()
  616. /* ========================================================================= */
  617. /* =======              INITIATE TC RECORD AT COPY FRAGMENT          ======= */
  618. /*                                                                           */
  619. /*       SUBROUTINE SHORT NAME = ICT                                         */
  620. /* ========================================================================= */
  621. void Dblqh::initCopyTc(Signal* signal) 
  622. {
  623.   const NextScanConf * const nextScanConf = (NextScanConf *)&signal->theData[0];
  624.   tcConnectptr.p->primKeyLen = nextScanConf->keyLength;
  625.   tcConnectptr.p->tupkeyData[0] = nextScanConf->key[0];
  626.   tcConnectptr.p->tupkeyData[1] = nextScanConf->key[1];
  627.   tcConnectptr.p->tupkeyData[2] = nextScanConf->key[2];
  628.   tcConnectptr.p->tupkeyData[3] = nextScanConf->key[3];
  629.   scanptr.p->scanLocalref[0] = nextScanConf->localKey[0];
  630.   scanptr.p->scanLocalref[1] = nextScanConf->localKey[1];
  631.   scanptr.p->scanLocalFragid = nextScanConf->fragId;
  632.   tcConnectptr.p->operation = ZREAD;
  633.   tcConnectptr.p->apiVersionNo = 0;
  634.   tcConnectptr.p->opExec = 0; /* NOT INTERPRETED MODE */
  635.   tcConnectptr.p->schemaVersion = scanptr.p->scanSchemaVersion;
  636.   Uint32 reqinfo = 0;
  637.   LqhKeyReq::setKeyLen(reqinfo, nextScanConf->keyLength);
  638.   LqhKeyReq::setLockType(reqinfo, ZINSERT);
  639.   LqhKeyReq::setDirtyFlag(reqinfo, 1);
  640.   LqhKeyReq::setSimpleFlag(reqinfo, 1);
  641.   LqhKeyReq::setOperation(reqinfo, ZWRITE);
  642.                                         /* AILen in LQHKEYREQ  IS ZERO */
  643.   tcConnectptr.p->reqinfo = reqinfo;
  644. /* ------------------------------------------------------------------------ */
  645. /* THE RECEIVING NODE WILL EXPECT THAT IT IS THE LAST NODE AND WILL         */
  646. /* SEND COMPLETED AS THE RESPONSE SIGNAL SINCE DIRTY_OP BIT IS SET.         */
  647. /* ------------------------------------------------------------------------ */
  648.   tcConnectptr.p->nodeAfterNext[0] = ZNIL;
  649.   tcConnectptr.p->nodeAfterNext[1] = ZNIL;
  650.   tcConnectptr.p->tcBlockref = cownref;
  651.   tcConnectptr.p->readlenAi = 0;
  652.   tcConnectptr.p->storedProcId = ZNIL;
  653.   tcConnectptr.p->opExec = 0;
  654.   tcConnectptr.p->nextSeqNoReplica = 0;
  655.   tcConnectptr.p->dirtyOp = ZFALSE;
  656.   tcConnectptr.p->lastReplicaNo = 0;
  657.   tcConnectptr.p->currTupAiLen = 0;
  658.   tcConnectptr.p->tcTimer = cLqhTimeOutCount;
  659. }//Dblqh::initCopyTc()
  660. /* ------------------------------------------------------------------------- */
  661. /* -------               SEND COPY_ACTIVECONF TO MASTER DIH          ------- */
  662. /*                                                                           */
  663. /* ------------------------------------------------------------------------- */
  664. void Dblqh::sendCopyActiveConf(Signal* signal, Uint32 tableId) 
  665. {
  666.   releaseActiveCopy(signal);
  667.   CopyActiveConf * const conf = (CopyActiveConf *)&signal->theData[0];
  668.   conf->userPtr = fragptr.p->masterPtr;
  669.   conf->tableId = tableId;
  670.   conf->fragId = fragptr.p->fragId;
  671.   conf->startingNodeId = cownNodeid;
  672.   conf->startGci = fragptr.p->startGci;
  673.   sendSignal(fragptr.p->masterBlockref, GSN_COPY_ACTIVECONF, signal,
  674.              CopyActiveConf::SignalLength, JBB);
  675. }//Dblqh::sendCopyActiveConf()
  676. /* ########################################################################## 
  677.  * #######                       LOCAL CHECKPOINT MODULE              #######
  678.  *
  679.  * ########################################################################## 
  680.  * --------------------------------------------------------------------------
  681.  *  THIS MODULE HANDLES THE EXECUTION AND CONTROL OF LOCAL CHECKPOINTS
  682.  *  IT CONTROLS THE LOCAL CHECKPOINTS IN TUP AND ACC. IT DOES ALSO INTERACT
  683.  *  WITH DIH TO CONTROL WHICH GLOBAL CHECKPOINTS THAT ARE RECOVERABLE
  684.  * ------------------------------------------------------------------------- */
  685. void Dblqh::execEMPTY_LCP_REQ(Signal* signal)
  686. {
  687.   jamEntry();
  688.   CRASH_INSERTION(5008);
  689.   EmptyLcpReq * const emptyLcpOrd = (EmptyLcpReq*)&signal->theData[0];
  690.   lcpPtr.i = 0;
  691.   ptrAss(lcpPtr, lcpRecord);
  692.   
  693.   Uint32 nodeId = refToNode(emptyLcpOrd->senderRef);
  694.   lcpPtr.p->m_EMPTY_LCP_REQ.set(nodeId);
  695.   lcpPtr.p->reportEmpty = true;
  696.   if (lcpPtr.p->lcpState == LcpRecord::LCP_IDLE){ 
  697.     jam();
  698.     bool ok = false;
  699.     switch(clcpCompletedState){
  700.     case LCP_IDLE:
  701.       ok = true;
  702.       sendEMPTY_LCP_CONF(signal, true);
  703.       break;
  704.     case LCP_RUNNING:
  705.       ok = true;
  706.       sendEMPTY_LCP_CONF(signal, false);
  707.       break;
  708.     case LCP_CLOSE_STARTED:
  709.       jam();
  710.     case ACC_LCP_CLOSE_COMPLETED:
  711.       jam();
  712.     case TUP_LCP_CLOSE_COMPLETED:
  713.       jam();
  714.       ok = true;
  715.       break;
  716.     }
  717.     ndbrequire(ok);
  718.     
  719.   }//if
  720.   
  721.   return;
  722. }//Dblqh::execEMPTY_LCPREQ()
  723. void Dblqh::execLCP_FRAG_ORD(Signal* signal)
  724. {
  725.   jamEntry();
  726.   CRASH_INSERTION(5010);
  727.   LcpFragOrd * const lcpFragOrd = (LcpFragOrd *)&signal->theData[0];
  728.   Uint32 lcpId = lcpFragOrd->lcpId;
  729.   lcpPtr.i = 0;
  730.   ptrAss(lcpPtr, lcpRecord);
  731.   
  732.   lcpPtr.p->lastFragmentFlag = lcpFragOrd->lastFragmentFlag;
  733.   if (lcpFragOrd->lastFragmentFlag) {
  734.     jam();
  735.     if (lcpPtr.p->lcpState == LcpRecord::LCP_IDLE) {
  736.       jam();
  737.       /* ----------------------------------------------------------
  738.        *       NOW THE COMPLETE LOCAL CHECKPOINT ROUND IS COMPLETED.  
  739.        * -------------------------------------------------------- */
  740.       if (cnoOfFragsCheckpointed > 0) {
  741.         jam();
  742.         completeLcpRoundLab(signal);
  743.       } else {
  744.         jam();
  745.         sendLCP_COMPLETE_REP(signal, lcpId);
  746.       }//if
  747.     }
  748.     return;
  749.   }//if
  750.   tabptr.i = lcpFragOrd->tableId;
  751.   ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
  752.   
  753.   ndbrequire(tabptr.p->tableStatus == Tablerec::PREP_DROP_TABLE_ONGOING ||
  754.      tabptr.p->tableStatus == Tablerec::PREP_DROP_TABLE_DONE ||
  755.      tabptr.p->tableStatus == Tablerec::TABLE_DEFINED);
  756.   ndbrequire(getFragmentrec(signal, lcpFragOrd->fragmentId));
  757.   
  758.   lcpPtr.i = 0;
  759.   ptrAss(lcpPtr, lcpRecord);
  760.   ndbrequire(!lcpPtr.p->lcpQueued);
  761.   if (c_lcpId < lcpFragOrd->lcpId) {
  762.     jam();
  763.     /**
  764.      * A new LCP
  765.      */
  766.     c_lcpId = lcpFragOrd->lcpId;
  767.     ndbrequire(lcpPtr.p->lcpState == LcpRecord::LCP_IDLE);
  768.     setLogTail(signal, lcpFragOrd->keepGci);
  769.     ndbrequire(clcpCompletedState == LCP_IDLE);
  770.     clcpCompletedState = LCP_RUNNING;
  771.   }//if
  772.   cnoOfFragsCheckpointed++;
  773.   
  774.   if(tabptr.p->tableStatus == Tablerec::PREP_DROP_TABLE_DONE){
  775.     jam();
  776.     LcpRecord::FragOrd fragOrd;
  777.     fragOrd.fragPtrI = fragptr.i;
  778.     fragOrd.lcpFragOrd = * lcpFragOrd;
  779.     sendLCP_FRAG_REP(signal, fragOrd);
  780.     return;
  781.   }
  782.   if (lcpPtr.p->lcpState != LcpRecord::LCP_IDLE) {
  783.     ndbrequire(lcpPtr.p->lcpQueued == false);
  784.     lcpPtr.p->lcpQueued = true;
  785.     lcpPtr.p->queuedFragment.fragPtrI = fragptr.i;
  786.     lcpPtr.p->queuedFragment.lcpFragOrd = * lcpFragOrd;
  787.     return;
  788.   }//if
  789.   
  790.   lcpPtr.p->currentFragment.fragPtrI = fragptr.i;
  791.   lcpPtr.p->currentFragment.lcpFragOrd = * lcpFragOrd;
  792.   
  793.   sendLCP_FRAGIDREQ(signal);
  794. }//Dblqh::execLCP_FRAGORD()
  795. /* --------------------------------------------------------------------------
  796.  *       PRECONDITION: LCP_PTR:LCP_STATE = WAIT_FRAGID
  797.  * -------------------------------------------------------------------------- 
  798.  *       WE NOW HAVE THE LOCAL FRAGMENTS THAT THE LOCAL CHECKPOINT WILL USE.
  799.  * -------------------------------------------------------------------------- */
  800. void Dblqh::execLCP_FRAGIDCONF(Signal* signal) 
  801. {
  802.   UintR Tfragid[4];
  803.   jamEntry();
  804.   lcpPtr.i = signal->theData[0];
  805.   
  806.   Uint32 TaccPtr = signal->theData[1];
  807.   Uint32 noLocfrag = signal->theData[2];
  808.   Tfragid[0] = signal->theData[3];
  809.   Tfragid[1] = signal->theData[4];
  810.   ptrCheckGuard(lcpPtr, clcpFileSize, lcpRecord);
  811.   ndbrequire(lcpPtr.p->lcpState == LcpRecord::LCP_WAIT_FRAGID);
  812.   /* ------------------------------------------------------------------------
  813.    * NO ERROR CHECKING OF TNO_LOCFRAG VALUE. OUT OF BOUND WILL IMPLY THAT AN
  814.    * INDEX OUT OF RANGE WILL CAUSE A SYSTEM RESTART WHICH IS DESIRED.
  815.    * ------------------------------------------------------------------------ */
  816.   lcpPtr.p->lcpAccptr = TaccPtr;
  817.   fragptr.i = lcpPtr.p->currentFragment.fragPtrI;
  818.   ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
  819.   ndbrequire(noLocfrag - 1 < 2);
  820.   for (Uint32 Tindex = 0; Tindex < noLocfrag; Tindex++) {
  821.     jam();
  822.     Uint32 fragId = Tfragid[Tindex];
  823.     /* ----------------------------------------------------------------------
  824.      *  THERE IS NO ERROR CHECKING ON PURPOSE. IT IS POSSIBLE TO CALCULATE HOW
  825.      *  MANY LOCAL LCP RECORDS THERE SHOULD BE. IT SHOULD NEVER HAPPEN THAT 
  826.      *  THERE IS NO ONE FREE. IF THERE IS NO ONE IT WILL ALSO BE A POINTER 
  827.      *  OUT OF RANGE WHICH IS AN ERROR CODE IN ITSELF. REUSES ERROR HANDLING 
  828.      *  IN AXE VM.
  829.      * ---------------------------------------------------------------------- */
  830.     seizeLcpLoc(signal);
  831.     initLcpLocAcc(signal, fragId);
  832.     seizeLcpLoc(signal);
  833.     initLcpLocTup(signal, fragId);
  834.     signal->theData[0] = lcpLocptr.i;
  835.     signal->theData[1] = cownref;
  836.     signal->theData[2] = lcpPtr.p->currentFragment.lcpFragOrd.tableId;
  837.     signal->theData[3] = lcpLocptr.p->locFragid;
  838.     signal->theData[4] = lcpPtr.p->currentFragment.lcpFragOrd.lcpNo;
  839.     signal->theData[5] = lcpPtr.p->currentFragment.lcpFragOrd.lcpId % MAX_LCP_STORED;
  840.     sendSignal(fragptr.p->tupBlockref, GSN_TUP_PREPLCPREQ, signal, 6, JBB);
  841.   }//for
  842.   lcpPtr.p->lcpState = LcpRecord::LCP_WAIT_TUP_PREPLCP;
  843.   return;
  844. }//Dblqh::execLCP_FRAGIDCONF()
  845. /* --------------------------------------------------------------------------
  846.  *       PRECONDITION: LCP_LOCPTR:LCP_STATE = WAIT_TUPPREPLCP
  847.  * --------------------------------------------------------------------------
  848.  *       WE HAVE NOW PREPARED A LOCAL FRAGMENT IN TUP FOR LCP EXECUTION.
  849.  * -------------------------------------------------------------------------- */
  850. void Dblqh::execTUP_PREPLCPCONF(Signal* signal) 
  851. {
  852.   UintR ttupPtr;
  853.   jamEntry();
  854.   lcpLocptr.i = signal->theData[0];
  855.   ttupPtr = signal->theData[1];
  856.   ptrCheckGuard(lcpLocptr, clcpLocrecFileSize, lcpLocRecord);
  857.   lcpPtr.i = lcpLocptr.p->masterLcpRec;
  858.   ptrCheckGuard(lcpPtr, clcpFileSize, lcpRecord);
  859.   ndbrequire(lcpLocptr.p->lcpLocstate == LcpLocRecord::WAIT_TUP_PREPLCP);
  860.   lcpLocptr.p->tupRef = ttupPtr;
  861.   lcpLocptr.p->lcpLocstate = LcpLocRecord::IDLE;
  862.   checkLcpTupprep(signal);
  863.   if (lcpPtr.p->lcpState != LcpRecord::LCP_WAIT_HOLDOPS) {
  864.     jam();
  865.     return;
  866.   }//if
  867.   fragptr.i = lcpPtr.p->currentFragment.fragPtrI;
  868.   ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
  869.   lcpLocptr.i = lcpPtr.p->firstLcpLocAcc;
  870.   do {
  871.     jam();
  872.     ptrCheckGuard(lcpLocptr, clcpLocrecFileSize, lcpLocRecord);
  873.     lcpLocptr.p->lcpLocstate = LcpLocRecord::WAIT_LCPHOLDOP;
  874.     signal->theData[0] = lcpPtr.p->lcpAccptr;
  875.     signal->theData[1] = lcpLocptr.p->locFragid;
  876.     signal->theData[2] = 0;
  877.     signal->theData[3] = lcpLocptr.i;
  878.     sendSignal(fragptr.p->accBlockref, GSN_LCP_HOLDOPREQ, signal, 4, JBA);
  879.     lcpLocptr.i = lcpLocptr.p->nextLcpLoc;
  880.   } while (lcpLocptr.i != RNIL);
  881.   /* ------------------------------------------------------------------------
  882.    *   SET STATE ON FRAGMENT TO BLOCKED TO ENSURE THAT NO MORE OPERATIONS ARE
  883.    *   STARTED FROM LQH IN TUP AND ACC UNTIL THE START CHECKPOINT HAS BEEN
  884.    *   COMPLETED. ALSO SET THE LOCAL CHECKPOINT STATE TO WAIT FOR 
  885.    *   LCP_HOLDOPCONF
  886.    * ----------------------------------------------------------------------- */
  887.   fragptr.p->fragStatus = Fragrecord::BLOCKED;
  888.   fragptr.p->fragActiveStatus = ZTRUE;
  889.   lcpPtr.p->lcpState = LcpRecord::LCP_WAIT_HOLDOPS;
  890.   return;
  891. }//Dblqh::execTUP_PREPLCPCONF()
  892. void Dblqh::execTUP_PREPLCPREF(Signal* signal) 
  893. {
  894.   jamEntry();
  895.   ndbrequire(false);
  896. }//Dblqh::execTUP_PREPLCPREF()
  897. void Dblqh::execLCP_FRAGIDREF(Signal* signal) 
  898. {
  899.   jamEntry();
  900.   ndbrequire(false);
  901. }//Dblqh::execLCP_FRAGIDREF()
  902. /* --------------------------------------------------------------------------
  903.  *   A NUMBER OF OPERATIONS THAT HAVE BEEN SET ON HOLD IN ACC. MOVE THOSE TO
  904.  *   LIST OF BLOCKED ACC OPERATIONS. IF MORE OPERATIONS ARE BLOCKED GET THOSE
  905.  *   OTHERWISE CONTINUE THE LOCAL CHECKPOINT BY REQUESTING TUP AND ACC TO
  906.  *   WRITE THEIR START CHECKPOINT.
  907.  * -------------------------------------------------------------------------- 
  908.  *       PRECONDITION: LCP_LOCPTR:LCP_LOCSTATE = WAIT_LCPHOLDOP
  909.  * ------------------------------------------------------------------------- */
  910. /* ***************>> */
  911. /*  LCP_HOLDOPCONF > */
  912. /* ***************>> */
  913. void Dblqh::execLCP_HOLDOPCONF(Signal* signal) 
  914. {
  915.   UintR tnoHoldops;
  916.   Uint32 Tdata[23];
  917.   Uint32 Tlength;
  918.   jamEntry();
  919.   lcpLocptr.i = signal->theData[0];
  920.   Tlength = signal->theData[1];
  921.   for (Uint32 i = 0; i < 23; i++)
  922.     Tdata[i] = signal->theData[i + 2];
  923.   ptrCheckGuard(lcpLocptr, clcpLocrecFileSize, lcpLocRecord);
  924.   ndbrequire(lcpLocptr.p->lcpLocstate == LcpLocRecord::WAIT_LCPHOLDOP);
  925.   lcpPtr.i = lcpLocptr.p->masterLcpRec;
  926.   /* ------------------------------------------------------------------------
  927.    *   NO ERROR CHECK ON USING VALUE IN MASTER_LCP_REC. ERROR IN THIS 
  928.    *   REFERENCE WILL CAUSE POINTER OUT OF RANGE WHICH CAUSES A SYSTEM RESTART.
  929.    * ----------------------------------------------------------------------- */
  930.   tnoHoldops = Tlength & 65535;
  931.   ptrCheckGuard(lcpPtr, clcpFileSize, lcpRecord);
  932.   fragptr.i = lcpPtr.p->currentFragment.fragPtrI;
  933.   ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
  934.   ndbrequire(tnoHoldops <= 23);
  935.   for (Uint32 Tindex = 0; Tindex < tnoHoldops; Tindex++) {
  936.     jam();
  937.     tcConnectptr.i = Tdata[Tindex];
  938.     ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
  939.     moveActiveToAcc(signal);
  940.   }//for
  941.   if ((Tlength >> 16) == 1) {
  942.     jam();
  943.                                         /* MORE HOLDOPS NEEDED */
  944.     signal->theData[0] = lcpPtr.p->lcpAccptr;
  945.     signal->theData[1] = lcpLocptr.p->locFragid;
  946.     signal->theData[2] = 1;
  947.     signal->theData[3] = lcpLocptr.i;
  948.     sendSignal(fragptr.p->accBlockref, GSN_LCP_HOLDOPREQ, signal, 4, JBA);
  949.     return;
  950.   } else {
  951.     jam();
  952.                                         /* NO MORE HOLDOPS NEEDED */
  953.     lcpLocptr.p->lcpLocstate = LcpLocRecord::HOLDOP_READY;
  954.     checkLcpHoldop(signal);
  955.     if (lcpPtr.p->lcpState == LcpRecord::LCP_WAIT_ACTIVE_FINISH) {
  956.       if (fragptr.p->activeList == RNIL) {
  957.         jam();
  958. /* ------------------------------------------------------------------ 
  959.  *  THERE ARE NO MORE ACTIVE OPERATIONS. IT IS NOW OK TO START THE 
  960.  *  LOCAL CHECKPOINT IN BOTH TUP AND ACC.
  961.  * ----------------------------------------------------------------- */
  962.         sendStartLcp(signal);
  963.         lcpPtr.p->lcpState = LcpRecord::LCP_START_CHKP;
  964.       } else {
  965.         jam();
  966. // Set this to signal releaseActiveFrag 
  967. // that it should check to see if itäs time to call sendStartLcp
  968. fragptr.p->lcpRef = lcpPtr.i;
  969.       }//if
  970.     }//if
  971.   }//if
  972.   /* ----------------------- */
  973.   /*           ELSE          */
  974.   /* ------------------------------------------------------------------------
  975.    *   THERE ARE STILL MORE ACTIVE OPERATIONS. WAIT UNTIL THEY ARE FINSIHED.
  976.    *   THIS IS DISCOVERED WHEN RELEASE_ACTIVE_FRAG IS EXECUTED.
  977.    * ------------------------------------------------------------------------
  978.    *       DO NOTHING, EXIT IS EXECUTED BELOW                                  
  979.    * ----------------------------------------------------------------------- */
  980.   return;
  981. }//Dblqh::execLCP_HOLDOPCONF()
  982. /* ***************> */
  983. /*  LCP_HOLDOPREF > */
  984. /* ***************> */
  985. void Dblqh::execLCP_HOLDOPREF(Signal* signal) 
  986. {
  987.   jamEntry();
  988.   ndbrequire(false);
  989. }//Dblqh::execLCP_HOLDOPREF()
  990. /* ************************************************************************>>
  991.  *  ACC_LCPSTARTED: Confirm that ACC started local checkpoint and undo 
  992.  *  logging is on. 
  993.  * ************************************************************************>> 
  994.  * --------------------------------------------------------------------------
  995.  *       PRECONDITION: LCP_LOCPTR:LCP_LOCSTATE = ACC_WAIT_STARTED 
  996.  * ------------------------------------------------------------------------- */
  997. void Dblqh::execACC_LCPSTARTED(Signal* signal) 
  998. {
  999.   jamEntry();
  1000.   lcpLocptr.i = signal->theData[0];
  1001.   ptrCheckGuard(lcpLocptr, clcpLocrecFileSize, lcpLocRecord);
  1002.   ndbrequire(lcpLocptr.p->lcpLocstate == LcpLocRecord::ACC_WAIT_STARTED);
  1003.   lcpPtr.i = lcpLocptr.p->masterLcpRec;
  1004.   ptrCheckGuard(lcpPtr, clcpFileSize, lcpRecord);
  1005.   /* ------------------------------------------------------------------------ 
  1006.    * NO ERROR CHECK ON USING VALUE IN MASTER_LCP_REC. ERROR IN THIS 
  1007.    * REFERENCE  WILL CAUSE POINTER OUT OF RANGE WHICH CAUSES A SYSTEM RESTART.
  1008.    * ----------------------------------------------------------------------- */
  1009.   lcpLocptr.p->lcpLocstate = LcpLocRecord::ACC_STARTED;
  1010.   lcpStartedLab(signal);
  1011.   return;
  1012. }//Dblqh::execACC_LCPSTARTED()
  1013. /* ******************************************> */
  1014. /*  TUP_LCPSTARTED: Same as above but for TUP. */
  1015. /* ******************************************> */
  1016. /* -------------------------------------------------------------------------- 
  1017.  *       PRECONDITION: LCP_LOCPTR:LCP_LOCSTATE = TUP_WAIT_STARTED
  1018.  * ------------------------------------------------------------------------- */
  1019. void Dblqh::execTUP_LCPSTARTED(Signal* signal) 
  1020. {
  1021.   jamEntry();
  1022.   lcpLocptr.i = signal->theData[0];
  1023.   ptrCheckGuard(lcpLocptr, clcpLocrecFileSize, lcpLocRecord);
  1024.   ndbrequire(lcpLocptr.p->lcpLocstate == LcpLocRecord::TUP_WAIT_STARTED);
  1025.   lcpPtr.i = lcpLocptr.p->masterLcpRec;
  1026.   ptrCheckGuard(lcpPtr, clcpFileSize, lcpRecord);
  1027.   /* ------------------------------------------------------------------------
  1028.    *   NO ERROR CHECK ON USING VALUE IN MASTER_LCP_REC. ERROR IN THIS REFERENCE
  1029.    *   WILL CAUSE POINTER OUT OF RANGE WHICH CAUSES A SYSTEM RESTART.
  1030.    * ----------------------------------------------------------------------- */
  1031.   lcpLocptr.p->lcpLocstate = LcpLocRecord::TUP_STARTED;
  1032.   lcpStartedLab(signal);
  1033.   return;
  1034. }//Dblqh::execTUP_LCPSTARTED()
  1035. void Dblqh::lcpStartedLab(Signal* signal) 
  1036. {
  1037.   if (checkLcpStarted(signal))
  1038.   {
  1039.     jam();
  1040.     /* ----------------------------------------------------------------------
  1041.      *  THE LOCAL CHECKPOINT HAS BEEN STARTED. IT IS NOW TIME TO 
  1042.      *  RESTART THE TRANSACTIONS WHICH HAVE BEEN BLOCKED.
  1043.      * --------------------------------------------------------------------- */
  1044.     fragptr.i = lcpPtr.p->currentFragment.fragPtrI;
  1045.     ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
  1046.     /* ----------------------------------------------------------------------
  1047.      *    UPDATE THE MAX_GCI_IN_LCP AND MAX_GCI_COMPLETED_IN_LCP NOW BEFORE
  1048.      *    ACTIVATING THE FRAGMENT AGAIN.
  1049.      * --------------------------------------------------------------------- */
  1050.     ndbrequire(lcpPtr.p->currentFragment.lcpFragOrd.lcpNo < MAX_LCP_STORED);
  1051.     fragptr.p->maxGciInLcp = fragptr.p->newestGci;
  1052.     fragptr.p->maxGciCompletedInLcp = cnewestCompletedGci;
  1053.     sendAccContOp(signal); /* START OPERATIONS IN ACC       */
  1054.     moveAccActiveFrag(signal); /* MOVE FROM ACC BLOCKED LIST TO ACTIVE LIST 
  1055.    ON FRAGMENT */
  1056.   }
  1057.   /*---------------*/
  1058.   /*       ELSE    */
  1059.   /*-------------------------------------------------------------------------*/
  1060.   /*    THE LOCAL CHECKPOINT HAS NOT BEEN STARTED. EXIT AND WAIT FOR 
  1061.    *    MORE SIGNALS */
  1062.   /*-------------------------------------------------------------------------*/
  1063.   /*       DO NOTHING, EXIT IS EXECUTED BELOW                                */
  1064.   /*-------------------------------------------------------------------------*/
  1065.   return;
  1066. }//Dblqh::lcpStartedLab()
  1067. /*---------------------------------------------------------------------------
  1068.  *     ACC HAVE RESTARTED THE BLOCKED OPERATIONS AGAIN IN ONE FRAGMENT PART. 
  1069.  *     IT IS NOW OUR TURN TO RESTART ALL OPERATIONS QUEUED IN LQH IF ALL 
  1070.  *     FRAGMENT PARTS ARE COMPLETED.
  1071.  *-------------------------------------------------------------------------- */
  1072. void Dblqh::execACC_CONTOPCONF(Signal* signal) 
  1073. {
  1074.   if(ERROR_INSERTED(5035) && signal->getSendersBlockRef() != reference()){
  1075.     sendSignalWithDelay(reference(), GSN_ACC_CONTOPCONF, signal, 1000, 
  1076. signal->length());
  1077.     return;
  1078.   }
  1079.   jamEntry();
  1080.   lcpLocptr.i = signal->theData[0];
  1081.   ptrCheckGuard(lcpLocptr, clcpLocrecFileSize, lcpLocRecord);
  1082.   lcpLocptr.p->accContCounter = 1;
  1083.   lcpPtr.i = lcpLocptr.p->masterLcpRec;
  1084.   ptrCheckGuard(lcpPtr, clcpFileSize, lcpRecord);
  1085.   lcpLocptr.i = lcpPtr.p->firstLcpLocAcc;
  1086.   do {
  1087.     ptrCheckGuard(lcpLocptr, clcpLocrecFileSize, lcpLocRecord);
  1088.     if (lcpLocptr.p->accContCounter == 0) {
  1089.       jam();
  1090.       return;
  1091.     }//if
  1092.     lcpLocptr.i = lcpLocptr.p->nextLcpLoc;
  1093.   } while (lcpLocptr.i != RNIL);
  1094.   fragptr.i = lcpPtr.p->currentFragment.fragPtrI;
  1095.   ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
  1096.   restartOperationsLab(signal);
  1097.   return;
  1098. }//Dblqh::execACC_CONTOPCONF()
  1099. /* ********************************************************* */
  1100. /*  LQH_RESTART_OP: Restart operations after beeing blocked. */
  1101. /* ********************************************************* */
  1102. /*---------------------------------------------------------------------------*/
  1103. /*       PRECONDITION: FRAG_STATUS = BLOCKED AND LCP_STATE = STARTED         */
  1104. /*---------------------------------------------------------------------------*/
  1105. void Dblqh::execLQH_RESTART_OP(Signal* signal) 
  1106. {
  1107.   jamEntry();
  1108.   fragptr.i = signal->theData[0];
  1109.   ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
  1110.   lcpPtr.i = signal->theData[1];
  1111.   ptrCheckGuard(lcpPtr, clcpFileSize, lcpRecord);
  1112.   ndbrequire(fragptr.p->fragStatus == Fragrecord::BLOCKED);
  1113.   restartOperationsLab(signal);
  1114. }//Dblqh::execLQH_RESTART_OP()
  1115. void Dblqh::restartOperationsLab(Signal* signal) 
  1116. {
  1117.   Uint32 loopCount = 0;
  1118.   tcConnectptr.i = fragptr.p->firstWaitQueue;
  1119.   do {
  1120.     if (tcConnectptr.i != RNIL) {
  1121.       jam();
  1122. /*---------------------------------------------------------------------------*/
  1123. /*    START UP THE TRANSACTION AGAIN. WE START IT AS A SEPARATE SIGNAL.      */
  1124. /*---------------------------------------------------------------------------*/
  1125.       signal->theData[0] = ZRESTART_OPERATIONS_AFTER_STOP;
  1126.       signal->theData[1] = tcConnectptr.i;
  1127.       signal->theData[2] = fragptr.i;
  1128.       sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB);
  1129.       ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
  1130.       tcConnectptr.i = tcConnectptr.p->nextTc;
  1131.     } else {
  1132.       jam();
  1133. /*--------------------------------------------------------------------------*/
  1134. /* NO MORE OPERATIONS TO RESTART. WE CAN NOW RESET THE STATE TO ACTIVE AND  */
  1135. /* RESTART NORMAL ACTIVITIES ON THE FRAGMENT WHILE THE FUZZY PART OF THE    */
  1136. /* LOCAL CHECKPOINT IS COMPLETING.                                          */
  1137. /* IF THE CHECKPOINT WAS COMPLETED ALREADY ON THIS FRAGMENT WE PROCEED WITH */
  1138. /* THE NEXT FRAGMENT NOW THAT WE HAVE COMPLETED THIS CHECKPOINT.            */
  1139. /*--------------------------------------------------------------------------*/
  1140.       fragptr.p->fragStatus = Fragrecord::FSACTIVE;
  1141.       if (lcpPtr.p->lcpState == LcpRecord::LCP_BLOCKED_COMP) {
  1142.         jam();
  1143.         contChkpNextFragLab(signal);
  1144.         return;
  1145.       }//if
  1146.       return;
  1147.     }//if
  1148.     loopCount++;
  1149.     if (loopCount > 16) {
  1150.       jam();
  1151.       signal->theData[0] = fragptr.i;
  1152.       signal->theData[1] = lcpPtr.i;
  1153.       sendSignal(cownref, GSN_LQH_RESTART_OP, signal, 2, JBB);
  1154.       return;
  1155.     }//if
  1156.   } while (1);
  1157. }//Dblqh::restartOperationsLab()
  1158. void Dblqh::restartOperationsAfterStopLab(Signal* signal) 
  1159. {
  1160.   /*-------------------------------------------------------------------------
  1161.    * WHEN ARRIVING HERE THE OPERATION IS ALREADY SET IN THE ACTIVE LIST. 
  1162.    * THUS WE CAN IMMEDIATELY CALL THE METHODS THAT EXECUTE FROM WHERE 
  1163.    * THE OPERATION WAS STOPPED.
  1164.    *------------------------------------------------------------------------ */
  1165.   switch (tcConnectptr.p->transactionState) {
  1166.   case TcConnectionrec::STOPPED:
  1167.     jam();
  1168.     /*-----------------------------------------------------------------------
  1169.      *       STOPPED BEFORE TRYING TO SEND ACCKEYREQ           
  1170.      *---------------------------------------------------------------------- */
  1171.     prepareContinueAfterBlockedLab(signal);
  1172.     return;
  1173.     break;
  1174.   case TcConnectionrec::COMMIT_STOPPED:
  1175.     jam();
  1176.     /* ----------------------------------------------------------------------
  1177.      *       STOPPED BEFORE TRYING TO SEND ACC_COMMITREQ
  1178.      * --------------------------------------------------------------------- */
  1179.     releaseActiveFrag(signal);
  1180.     commitContinueAfterBlockedLab(signal);
  1181.     return;
  1182.     break;
  1183.   case TcConnectionrec::ABORT_STOPPED:
  1184.     jam();
  1185.     /* ----------------------------------------------------------------------
  1186.      *       STOPPED BEFORE TRYING TO SEND ACC_ABORTREQ
  1187.      * --------------------------------------------------------------------- */
  1188.     abortContinueAfterBlockedLab(signal, true);
  1189.     return;
  1190.     break;
  1191.   case TcConnectionrec::COPY_STOPPED:
  1192.     jam();
  1193.     /* ----------------------------------------------------------------------
  1194.      *       STOPPED BEFORE TRYING TO SEND NEXT_SCANREQ DURING COPY FRAGMENT
  1195.      * --------------------------------------------------------------------- */
  1196.     continueCopyAfterBlockedLab(signal);
  1197.     return;
  1198.     break;
  1199.   case TcConnectionrec::COPY_FIRST_STOPPED:
  1200.     jam();
  1201.     /* ----------------------------------------------------------------------
  1202.      *       STOPPED BEFORE TRYING TO SEND NEXT_SCANREQ DURING COPY FRAGMENT
  1203.      * --------------------------------------------------------------------- */
  1204.     continueFirstCopyAfterBlockedLab(signal);
  1205.     return;
  1206.     break;
  1207.   case TcConnectionrec::SCAN_FIRST_STOPPED:
  1208.     jam();
  1209.     /* ----------------------------------------------------------------------
  1210.      *       STOPPED BEFORE TRYING TO SEND NEXT_SCANREQ DURING SCAN
  1211.      * --------------------------------------------------------------------- */
  1212.     tcConnectptr.p->transactionState = TcConnectionrec::SCAN_STATE_USED;
  1213.     continueFirstScanAfterBlockedLab(signal);
  1214.     return;
  1215.     break;
  1216.   case TcConnectionrec::SCAN_CHECK_STOPPED:
  1217.     jam();
  1218.     /* ----------------------------------------------------------------------
  1219.      *       STOPPED BEFORE TRYING TO SEND NEXT_SCANREQ DURING SCAN
  1220.      * --------------------------------------------------------------------- */
  1221.     tcConnectptr.p->transactionState = TcConnectionrec::SCAN_STATE_USED;
  1222.     continueAfterCheckLcpStopBlocked(signal);
  1223.     return;
  1224.     break;
  1225.   case TcConnectionrec::SCAN_STOPPED:
  1226.     jam();
  1227.     /* ----------------------------------------------------------------------
  1228.      *       STOPPED BEFORE TRYING TO SEND NEXT_SCANREQ DURING SCAN
  1229.      * --------------------------------------------------------------------- */
  1230.     tcConnectptr.p->transactionState = TcConnectionrec::SCAN_STATE_USED;
  1231.     continueScanAfterBlockedLab(signal);
  1232.     return;
  1233.     break;
  1234.   case TcConnectionrec::SCAN_RELEASE_STOPPED:
  1235.     jam();
  1236.     /* ----------------------------------------------------------------------
  1237.      *       STOPPED BEFORE TRYING TO SEND NEXT_SCANREQ DURING RELEASE 
  1238.      *       LOCKS IN SCAN  
  1239.      * --------------------------------------------------------------------- */
  1240.     tcConnectptr.p->transactionState = TcConnectionrec::SCAN_STATE_USED;
  1241.     continueScanReleaseAfterBlockedLab(signal);
  1242.     return;
  1243.     break;
  1244.   case TcConnectionrec::SCAN_CLOSE_STOPPED:
  1245.     jam();
  1246.     /* ----------------------------------------------------------------------
  1247.      *       STOPPED BEFORE TRYING TO SEND NEXT_SCANREQ DURING CLOSE OF SCAN
  1248.      * --------------------------------------------------------------------- */
  1249.     continueCloseScanAfterBlockedLab(signal);
  1250.     return;
  1251.     break;
  1252.   case TcConnectionrec::COPY_CLOSE_STOPPED:
  1253.     jam();
  1254.     /* ----------------------------------------------------------------------
  1255.      *       STOPPED BEFORE TRYING TO SEND NEXT_SCANREQ DURING CLOSE OF COPY
  1256.      * --------------------------------------------------------------------- */
  1257.     continueCloseCopyAfterBlockedLab(signal);
  1258.     return;
  1259.     break;
  1260.   default:
  1261.     jam();
  1262.     systemErrorLab(signal);
  1263.     return;
  1264.     break;
  1265.   }//switch
  1266. }//Dblqh::restartOperationsAfterStopLab()
  1267. /* *************** */
  1268. /*  ACC_LCPCONF  > */
  1269. /* *************** */
  1270. /*---------------------------------------------------------------------------
  1271.  *       PRECONDITION: LCP_LOCPTR:LCP_LOCSTATE = ACC_STARTED 
  1272.  *-------------------------------------------------------------------------- */
  1273. void Dblqh::execACC_LCPCONF(Signal* signal) 
  1274. {
  1275.   jamEntry();
  1276.   lcpLocptr.i = signal->theData[0];
  1277.   ptrCheckGuard(lcpLocptr, clcpLocrecFileSize, lcpLocRecord);
  1278.   ndbrequire(lcpLocptr.p->lcpLocstate == LcpLocRecord::ACC_STARTED);
  1279.   lcpPtr.i = lcpLocptr.p->masterLcpRec;
  1280.   ptrCheckGuard(lcpPtr, clcpFileSize, lcpRecord);
  1281.   /* ------------------------------------------------------------------------
  1282.    *   NO ERROR CHECK ON USING VALUE IN MASTER_LCP_REC. ERROR IN 
  1283.    *   THIS REFERENCE WILL CAUSE POINTER OUT OF RANGE WHICH CAUSES A 
  1284.    *   SYSTEM RESTART.
  1285.    * ----------------------------------------------------------------------- */
  1286.   lcpLocptr.p->lcpLocstate = LcpLocRecord::ACC_COMPLETED;
  1287.   lcpCompletedLab(signal);
  1288.   return;
  1289. }//Dblqh::execACC_LCPCONF()
  1290. /* *************** */
  1291. /*  TUP_LCPCONF  > */
  1292. /* *************** */
  1293. /* --------------------------------------------------------------------------
  1294.  *       PRECONDITION: LCP_LOCPTR:LCP_LOCSTATE = TUP_STARTED    
  1295.  * ------------------------------------------------------------------------- */
  1296. void Dblqh::execTUP_LCPCONF(Signal* signal) 
  1297. {
  1298.   jamEntry();
  1299.   lcpLocptr.i = signal->theData[0];
  1300.   ptrCheckGuard(lcpLocptr, clcpLocrecFileSize, lcpLocRecord);
  1301.   ndbrequire(lcpLocptr.p->lcpLocstate == LcpLocRecord::TUP_STARTED);
  1302.   lcpPtr.i = lcpLocptr.p->masterLcpRec;
  1303.   ptrCheckGuard(lcpPtr, clcpFileSize, lcpRecord);
  1304.   /* ------------------------------------------------------------------------
  1305.    *  NO ERROR CHECK ON USING VALUE IN MASTER_LCP_REC. ERROR IN THIS
  1306.    *  REFERENCE WILL CAUSE POINTER OUT OF RANGE WHICH CAUSES A SYSTEM RESTART.
  1307.    * ----------------------------------------------------------------------- */
  1308.   lcpLocptr.p->lcpLocstate = LcpLocRecord::TUP_COMPLETED;
  1309.   lcpCompletedLab(signal);
  1310.   return;
  1311. }//Dblqh::execTUP_LCPCONF()
  1312. void Dblqh::lcpCompletedLab(Signal* signal) 
  1313. {
  1314.   checkLcpCompleted(signal);
  1315.   if (lcpPtr.p->lcpState != LcpRecord::LCP_COMPLETED) {
  1316.     jam();
  1317.     /* ----------------------------------------------------------------------
  1318.      *       THE LOCAL CHECKPOINT HAS NOT BEEN COMPLETED, EXIT & WAIT 
  1319.      *       FOR MORE SIGNALS 
  1320.      * --------------------------------------------------------------------- */
  1321.     return;
  1322.   }//if
  1323.   /* ------------------------------------------------------------------------
  1324.    *   THE LOCAL CHECKPOINT HAS BEEN COMPLETED. IT IS NOW TIME TO START 
  1325.    *   A LOCAL CHECKPOINT ON THE NEXT FRAGMENT OR COMPLETE THIS LCP ROUND.
  1326.    * ------------------------------------------------------------------------ 
  1327.    *   WE START BY SENDING LCP_REPORT TO DIH TO REPORT THE COMPLETED LCP.
  1328.    *   TO CATER FOR NODE CRASHES WE SEND IT IN PARALLEL TO ALL NODES.
  1329.    * ----------------------------------------------------------------------- */
  1330.   fragptr.i = lcpPtr.p->currentFragment.fragPtrI;
  1331.   ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
  1332.   fragptr.p->fragActiveStatus = ZFALSE;
  1333.   contChkpNextFragLab(signal);
  1334.   return;
  1335. }//Dblqh::lcpCompletedLab()
  1336. void
  1337. Dblqh::sendLCP_FRAG_REP(Signal * signal, 
  1338. const LcpRecord::FragOrd & fragOrd) const {
  1339.   
  1340.   FragrecordPtr fragPtr;
  1341.   fragPtr.i = fragOrd.fragPtrI;
  1342.   ptrCheckGuard(fragPtr, cfragrecFileSize, fragrecord);
  1343.   ndbrequire(fragOrd.lcpFragOrd.lcpNo < MAX_LCP_STORED);
  1344.   LcpFragRep * const lcpReport = (LcpFragRep *)&signal->theData[0];
  1345.   lcpReport->nodeId = cownNodeid;
  1346.   lcpReport->lcpId = fragOrd.lcpFragOrd.lcpId;
  1347.   lcpReport->lcpNo = fragOrd.lcpFragOrd.lcpNo;
  1348.   lcpReport->tableId = fragOrd.lcpFragOrd.tableId;
  1349.   lcpReport->fragId = fragOrd.lcpFragOrd.fragmentId;
  1350.   lcpReport->maxGciCompleted = fragPtr.p->maxGciCompletedInLcp;
  1351.   lcpReport->maxGciStarted = fragPtr.p->maxGciInLcp;
  1352.   
  1353.   for (Uint32 i = 0; i < cnoOfNodes; i++) {
  1354.     jam();
  1355.     Uint32 nodeId = cnodeData[i];
  1356.     if(cnodeStatus[i] == ZNODE_UP){
  1357.       jam();
  1358.       BlockReference Tblockref = calcDihBlockRef(nodeId);
  1359.       sendSignal(Tblockref, GSN_LCP_FRAG_REP, signal, 
  1360.  LcpFragRep::SignalLength, JBB);
  1361.     }//if
  1362.   }//for
  1363. }
  1364. void Dblqh::contChkpNextFragLab(Signal* signal) 
  1365. {
  1366.   /* ------------------------------------------------------------------------ 
  1367.    *       UPDATE THE LATEST LOCAL CHECKPOINT COMPLETED ON FRAGMENT.
  1368.    *       UPDATE THE LCP_ID OF THIS CHECKPOINT.
  1369.    *       REMOVE THE LINK BETWEEN THE FRAGMENT RECORD AND THE LCP RECORD.
  1370.    * ----------------------------------------------------------------------- */
  1371.   if (fragptr.p->fragStatus == Fragrecord::BLOCKED) {
  1372.     jam();
  1373.     /**
  1374.      * LCP of fragment complete
  1375.      *   but restarting of operations isn't
  1376.      */
  1377.     lcpPtr.p->lcpState = LcpRecord::LCP_BLOCKED_COMP;
  1378.     //restartOperationsLab(signal);
  1379.     return;
  1380.   }//if
  1381.   /**
  1382.    * Send rep when fragment is done + unblocked
  1383.    */
  1384.   sendLCP_FRAG_REP(signal, lcpPtr.p->currentFragment);
  1385.   
  1386.   /* ------------------------------------------------------------------------
  1387.    *       WE ALSO RELEASE THE LOCAL LCP RECORDS.
  1388.    * ----------------------------------------------------------------------- */
  1389.   releaseLocalLcps(signal);
  1390.   if (lcpPtr.p->lcpQueued) {
  1391.     jam();
  1392.     /* ----------------------------------------------------------------------
  1393.      *  Transfer the state from the queued to the active LCP.
  1394.      * --------------------------------------------------------------------- */
  1395.     lcpPtr.p->lcpQueued = false;
  1396.     lcpPtr.p->currentFragment = lcpPtr.p->queuedFragment;
  1397.     
  1398.     /* ----------------------------------------------------------------------
  1399.      *       START THE QUEUED LOCAL CHECKPOINT.
  1400.      * --------------------------------------------------------------------- */
  1401.     sendLCP_FRAGIDREQ(signal);
  1402.     return;
  1403.   }//if
  1404.   
  1405.   lcpPtr.p->lcpState = LcpRecord::LCP_IDLE;
  1406.   if (lcpPtr.p->lastFragmentFlag){
  1407.     jam();
  1408.     /* ----------------------------------------------------------------------
  1409.      *       NOW THE COMPLETE LOCAL CHECKPOINT ROUND IS COMPLETED.  
  1410.      * --------------------------------------------------------------------- */
  1411.     completeLcpRoundLab(signal);
  1412.     return;
  1413.   }//if
  1414.   
  1415.   if (lcpPtr.p->reportEmpty) {
  1416.     jam();
  1417.     sendEMPTY_LCP_CONF(signal, false);
  1418.   }//if
  1419.   return;
  1420. }//Dblqh::contChkpNextFragLab()
  1421. void Dblqh::sendLCP_FRAGIDREQ(Signal* signal)
  1422. {
  1423.   ndbrequire(lcpPtr.p->firstLcpLocTup == RNIL);
  1424.   ndbrequire(lcpPtr.p->firstLcpLocAcc == RNIL);
  1425.   
  1426.   TablerecPtr tabPtr;
  1427.   tabPtr.i = lcpPtr.p->currentFragment.lcpFragOrd.tableId;
  1428.   ptrAss(tabPtr, tablerec);
  1429.   if(tabPtr.p->tableStatus == Tablerec::PREP_DROP_TABLE_ONGOING ||
  1430.      tabPtr.p->tableStatus == Tablerec::PREP_DROP_TABLE_DONE){
  1431.     jam();
  1432.     /**
  1433.      * Fake that the fragment is done
  1434.      */
  1435.     lcpCompletedLab(signal);
  1436.     return;
  1437.   }
  1438.   
  1439.   ndbrequire(tabPtr.p->tableStatus == Tablerec::TABLE_DEFINED);
  1440.   
  1441.   lcpPtr.p->lcpState = LcpRecord::LCP_WAIT_FRAGID;
  1442.   signal->theData[0] = lcpPtr.i;
  1443.   signal->theData[1] = cownref;
  1444.   signal->theData[2] = lcpPtr.p->currentFragment.lcpFragOrd.lcpNo;
  1445.   signal->theData[3] = lcpPtr.p->currentFragment.lcpFragOrd.tableId;
  1446.   signal->theData[4] = lcpPtr.p->currentFragment.lcpFragOrd.fragmentId;
  1447.   signal->theData[5] = lcpPtr.p->currentFragment.lcpFragOrd.lcpId % MAX_LCP_STORED;
  1448.   sendSignal(fragptr.p->accBlockref, GSN_LCP_FRAGIDREQ, signal, 6, JBB);
  1449. }//Dblqh::sendLCP_FRAGIDREQ()
  1450. void Dblqh::sendEMPTY_LCP_CONF(Signal* signal, bool idle)
  1451. {
  1452.   
  1453.   EmptyLcpConf * const rep = (EmptyLcpConf*)&signal->theData[0];
  1454.   /* ----------------------------------------------------------------------
  1455.    *       We have been requested to report when there are no more local
  1456.    *       waiting to be started or ongoing. In this signal we also report
  1457.    *       the last completed fragments state.
  1458.    * ---------------------------------------------------------------------- */
  1459.   rep->senderNodeId = getOwnNodeId();
  1460.   if(!idle){
  1461.     jam();
  1462.     rep->idle = 0 ;
  1463.     rep->tableId = lcpPtr.p->currentFragment.lcpFragOrd.tableId;
  1464.     rep->fragmentId = lcpPtr.p->currentFragment.lcpFragOrd.fragmentId;
  1465.     rep->lcpNo = lcpPtr.p->currentFragment.lcpFragOrd.lcpNo;
  1466.     rep->lcpId = lcpPtr.p->currentFragment.lcpFragOrd.lcpId;
  1467.   } else {
  1468.     jam();
  1469.     rep->idle = 1;
  1470.     rep->tableId = ~0;
  1471.     rep->fragmentId = ~0;
  1472.     rep->lcpNo = ~0;
  1473.     rep->lcpId = c_lcpId;
  1474.   }
  1475.   
  1476.   for (Uint32 i = 0; i < cnoOfNodes; i++) {
  1477.     jam();
  1478.     Uint32 nodeId = cnodeData[i];
  1479.     if (lcpPtr.p->m_EMPTY_LCP_REQ.get(nodeId)) {
  1480.       jam();
  1481.       
  1482.       BlockReference blockref = calcDihBlockRef(nodeId);
  1483.       sendSignal(blockref, GSN_EMPTY_LCP_CONF, signal, 
  1484.  EmptyLcpConf::SignalLength, JBB);
  1485.     }//if
  1486.   }//for
  1487.   lcpPtr.p->reportEmpty = false;
  1488.   lcpPtr.p->m_EMPTY_LCP_REQ.clear();
  1489. }//Dblqh::sendEMPTY_LCPCONF()
  1490. void Dblqh::execACC_LCPREF(Signal* signal) 
  1491. {
  1492.   jamEntry();
  1493.   ndbrequire(false);
  1494. }//Dblqh::execACC_LCPREF()
  1495. void Dblqh::execTUP_LCPREF(Signal* signal) 
  1496. {
  1497.   jamEntry();
  1498.   ndbrequire(false);
  1499. }//Dblqh::execTUP_LCPREF()
  1500. /* --------------------------------------------------------------------------
  1501.  *       THE LOCAL CHECKPOINT ROUND IS NOW COMPLETED. SEND COMPLETED MESSAGE
  1502.  *       TO THE MASTER DIH.
  1503.  * ------------------------------------------------------------------------- */
  1504. void Dblqh::completeLcpRoundLab(Signal* signal)
  1505. {
  1506.   clcpCompletedState = LCP_CLOSE_STARTED;
  1507.   signal->theData[0] = caccBlockref;
  1508.   signal->theData[1] = cownref;
  1509.   sendSignal(caccBlockref, GSN_END_LCPREQ, signal, 2, JBB);
  1510.   signal->theData[0] = ctupBlockref;
  1511.   signal->theData[1] = cownref;
  1512.   sendSignal(ctupBlockref, GSN_END_LCPREQ, signal, 2, JBB);
  1513.   return;
  1514. }//Dblqh::completeLcpRoundLab()
  1515. void Dblqh::execEND_LCPCONF(Signal* signal) 
  1516. {
  1517.   jamEntry();
  1518.   BlockReference userpointer = signal->theData[0];
  1519.   if (userpointer == caccBlockref) {
  1520.     if (clcpCompletedState == LCP_CLOSE_STARTED) {
  1521.       jam();
  1522.       clcpCompletedState = ACC_LCP_CLOSE_COMPLETED;
  1523.       return;
  1524.     } else {
  1525.       jam();
  1526.       ndbrequire(clcpCompletedState == TUP_LCP_CLOSE_COMPLETED);
  1527.       clcpCompletedState = LCP_IDLE;
  1528.     }//if
  1529.   } else {
  1530.     ndbrequire(userpointer == ctupBlockref);
  1531.     if (clcpCompletedState == LCP_CLOSE_STARTED) {
  1532.       jam();
  1533.       clcpCompletedState = TUP_LCP_CLOSE_COMPLETED;
  1534.       return;
  1535.     } else {
  1536.       jam();
  1537.       ndbrequire(clcpCompletedState == ACC_LCP_CLOSE_COMPLETED);
  1538.       clcpCompletedState = LCP_IDLE;
  1539.     }//if
  1540.   }//if
  1541.   lcpPtr.i = 0;
  1542.   ptrAss(lcpPtr, lcpRecord);
  1543.   sendLCP_COMPLETE_REP(signal, lcpPtr.p->currentFragment.lcpFragOrd.lcpId);
  1544. }//Dblqh::execEND_LCPCONF()
  1545. void Dblqh::sendLCP_COMPLETE_REP(Signal* signal, Uint32 lcpId)
  1546. {
  1547.   cnoOfFragsCheckpointed = 0;
  1548.   ndbrequire((cnoOfNodes - 1) < (MAX_NDB_NODES - 1));
  1549.   /* ------------------------------------------------------------------------
  1550.    *       WE SEND COMP_LCP_ROUND TO ALL NODES TO PREPARE FOR NODE CRASHES.
  1551.    * ----------------------------------------------------------------------- */
  1552.   lcpPtr.i = 0;
  1553.   ptrAss(lcpPtr, lcpRecord);
  1554.   lcpPtr.p->lastFragmentFlag = false;
  1555.   
  1556.   LcpCompleteRep* rep = (LcpCompleteRep*)signal->getDataPtrSend();
  1557.   rep->nodeId = getOwnNodeId();
  1558.   rep->lcpId = lcpId;
  1559.   rep->blockNo = DBLQH;
  1560.   
  1561.   for (Uint32 i = 0; i < cnoOfNodes; i++) {
  1562.     jam();
  1563.     Uint32 nodeId = cnodeData[i];
  1564.     if(cnodeStatus[i] == ZNODE_UP){
  1565.       jam();
  1566.       
  1567.       BlockReference blockref = calcDihBlockRef(nodeId);
  1568.       sendSignal(blockref, GSN_LCP_COMPLETE_REP, signal, 
  1569.  LcpCompleteRep::SignalLength, JBB);
  1570.     }//if
  1571.   }//for
  1572.   if(lcpPtr.p->reportEmpty){
  1573.     jam();
  1574.     sendEMPTY_LCP_CONF(signal, true);
  1575.   }
  1576.   return;
  1577. }//Dblqh::sendCOMP_LCP_ROUND()
  1578. /* ==========================================================================
  1579.  * =======  CHECK IF ALL PARTS OF A LOCAL CHECKPOINT ARE COMPLETED    ======= 
  1580.  *
  1581.  *       SUBROUTINE SHORT NAME = CLC
  1582.  * ========================================================================= */
  1583. void Dblqh::checkLcpCompleted(Signal* signal) 
  1584. {
  1585.   LcpLocRecordPtr clcLcpLocptr;
  1586.   clcLcpLocptr.i = lcpPtr.p->firstLcpLocAcc;
  1587.   while (clcLcpLocptr.i != RNIL) {
  1588.     ptrCheckGuard(clcLcpLocptr, clcpLocrecFileSize, lcpLocRecord);
  1589.     if (clcLcpLocptr.p->lcpLocstate != LcpLocRecord::ACC_COMPLETED) {
  1590.       jam();
  1591.       ndbrequire((clcLcpLocptr.p->lcpLocstate == LcpLocRecord::ACC_WAIT_STARTED) ||
  1592.                  (clcLcpLocptr.p->lcpLocstate == LcpLocRecord::ACC_STARTED));
  1593.       return;
  1594.     }//if
  1595.     clcLcpLocptr.i = clcLcpLocptr.p->nextLcpLoc;
  1596.   }
  1597.   clcLcpLocptr.i = lcpPtr.p->firstLcpLocTup;
  1598.   while (clcLcpLocptr.i != RNIL){
  1599.     ptrCheckGuard(clcLcpLocptr, clcpLocrecFileSize, lcpLocRecord);
  1600.     if (clcLcpLocptr.p->lcpLocstate != LcpLocRecord::TUP_COMPLETED) {
  1601.       jam();
  1602.       ndbrequire((clcLcpLocptr.p->lcpLocstate==LcpLocRecord::TUP_WAIT_STARTED) 
  1603.  ||(clcLcpLocptr.p->lcpLocstate == LcpLocRecord::TUP_STARTED));
  1604.       return;
  1605.     }//if
  1606.     clcLcpLocptr.i = clcLcpLocptr.p->nextLcpLoc;
  1607.   }
  1608.   
  1609.   lcpPtr.p->lcpState = LcpRecord::LCP_COMPLETED;
  1610. }//Dblqh::checkLcpCompleted()
  1611. /* ========================================================================== 
  1612.  * =======              CHECK IF ALL HOLD OPERATIONS ARE COMPLETED    ======= 
  1613.  *
  1614.  *       SUBROUTINE SHORT NAME = CHO
  1615.  * ========================================================================= */
  1616. void Dblqh::checkLcpHoldop(Signal* signal) 
  1617. {
  1618.   LcpLocRecordPtr choLcpLocptr;
  1619.   choLcpLocptr.i = lcpPtr.p->firstLcpLocAcc;
  1620.   do {
  1621.     ptrCheckGuard(choLcpLocptr, clcpLocrecFileSize, lcpLocRecord);
  1622.     if (choLcpLocptr.p->lcpLocstate != LcpLocRecord::HOLDOP_READY) {
  1623.       ndbrequire(choLcpLocptr.p->lcpLocstate == LcpLocRecord::WAIT_LCPHOLDOP);
  1624.       return;
  1625.     }//if
  1626.     choLcpLocptr.i = choLcpLocptr.p->nextLcpLoc;
  1627.   } while (choLcpLocptr.i != RNIL);
  1628.   lcpPtr.p->lcpState = LcpRecord::LCP_WAIT_ACTIVE_FINISH;
  1629. }//Dblqh::checkLcpHoldop()
  1630. /* ========================================================================== 
  1631.  * =======  CHECK IF ALL PARTS OF A LOCAL CHECKPOINT ARE STARTED      ======= 
  1632.  *
  1633.  *       SUBROUTINE SHORT NAME = CLS
  1634.  * ========================================================================== */
  1635. bool
  1636. Dblqh::checkLcpStarted(Signal* signal) 
  1637. {
  1638.   LcpLocRecordPtr clsLcpLocptr;
  1639.   terrorCode = ZOK;
  1640.   clsLcpLocptr.i = lcpPtr.p->firstLcpLocAcc;
  1641.   int i = 0;
  1642.   do {
  1643.     ptrCheckGuard(clsLcpLocptr, clcpLocrecFileSize, lcpLocRecord);
  1644.     if (clsLcpLocptr.p->lcpLocstate == LcpLocRecord::ACC_WAIT_STARTED){
  1645.       return false;
  1646.     }//if
  1647.     clsLcpLocptr.i = clsLcpLocptr.p->nextLcpLoc;
  1648.     i++;
  1649.   } while (clsLcpLocptr.i != RNIL);
  1650.   i = 0;
  1651.   clsLcpLocptr.i = lcpPtr.p->firstLcpLocTup;
  1652.   do {
  1653.     ptrCheckGuard(clsLcpLocptr, clcpLocrecFileSize, lcpLocRecord);
  1654.     if (clsLcpLocptr.p->lcpLocstate == LcpLocRecord::TUP_WAIT_STARTED){
  1655.       return false;
  1656.     }//if
  1657.     clsLcpLocptr.i = clsLcpLocptr.p->nextLcpLoc;
  1658.     i++;
  1659.   } while (clsLcpLocptr.i != RNIL);
  1660.   
  1661.   return true;
  1662. }//Dblqh::checkLcpStarted()
  1663. /* ========================================================================== 
  1664.  * =======       CHECK IF ALL PREPARE TUP OPERATIONS ARE COMPLETED    =======
  1665.  *
  1666.  *       SUBROUTINE SHORT NAME = CLT
  1667.  * ========================================================================== */
  1668. void Dblqh::checkLcpTupprep(Signal* signal) 
  1669. {
  1670.   LcpLocRecordPtr cltLcpLocptr;
  1671.   cltLcpLocptr.i = lcpPtr.p->firstLcpLocTup;
  1672.   do {
  1673.     ptrCheckGuard(cltLcpLocptr, clcpLocrecFileSize, lcpLocRecord);
  1674.     if (cltLcpLocptr.p->lcpLocstate != LcpLocRecord::IDLE) {
  1675.       ndbrequire(cltLcpLocptr.p->lcpLocstate == LcpLocRecord::WAIT_TUP_PREPLCP);
  1676.       return;
  1677.     }//if
  1678.     cltLcpLocptr.i = cltLcpLocptr.p->nextLcpLoc;
  1679.   } while (cltLcpLocptr.i != RNIL);
  1680.   lcpPtr.p->lcpState = LcpRecord::LCP_WAIT_HOLDOPS;
  1681. }//Dblqh::checkLcpTupprep()
  1682. /* ========================================================================== 
  1683.  * =======            INITIATE LCP LOCAL RECORD USED TOWARDS ACC      ======= 
  1684.  *
  1685.  * ========================================================================== */
  1686. void Dblqh::initLcpLocAcc(Signal* signal, Uint32 fragId) 
  1687. {
  1688.   lcpLocptr.p->nextLcpLoc = lcpPtr.p->firstLcpLocAcc;
  1689.   lcpPtr.p->firstLcpLocAcc = lcpLocptr.i;
  1690.   lcpLocptr.p->locFragid = fragId;
  1691.   lcpLocptr.p->waitingBlock = LcpLocRecord::ACC;
  1692.   lcpLocptr.p->lcpLocstate = LcpLocRecord::IDLE;
  1693.   lcpLocptr.p->masterLcpRec = lcpPtr.i;
  1694.   lcpLocptr.p->tupRef = RNIL;
  1695. }//Dblqh::initLcpLocAcc()
  1696. /* ========================================================================== 
  1697.  * =======           INITIATE LCP LOCAL RECORD USED TOWARDS TUP       ======= 
  1698.  *
  1699.  * ========================================================================== */
  1700. void Dblqh::initLcpLocTup(Signal* signal, Uint32 fragId) 
  1701. {
  1702.   lcpLocptr.p->nextLcpLoc = lcpPtr.p->firstLcpLocTup;
  1703.   lcpPtr.p->firstLcpLocTup = lcpLocptr.i;
  1704.   lcpLocptr.p->locFragid = fragId;
  1705.   lcpLocptr.p->waitingBlock = LcpLocRecord::TUP;
  1706.   lcpLocptr.p->lcpLocstate = LcpLocRecord::WAIT_TUP_PREPLCP;
  1707.   lcpLocptr.p->masterLcpRec = lcpPtr.i;
  1708.   lcpLocptr.p->tupRef = RNIL;
  1709. }//Dblqh::initLcpLocTup()
  1710. /* --------------------------------------------------------------------------
  1711.  * -------         MOVE OPERATION FROM ACC WAITING LIST ON FRAGMENT   ------- 
  1712.  * -------               TO ACTIVE LIST ON FRAGMENT                   -------
  1713.  *
  1714.  *       SUBROUTINE SHORT NAME = MAA
  1715.  * -------------------------------------------------------------------------- */
  1716. void Dblqh::moveAccActiveFrag(Signal* signal) 
  1717. {
  1718.   UintR maaTcNextConnectptr;
  1719.   tcConnectptr.i = fragptr.p->accBlockedList;
  1720.   fragptr.p->accBlockedList = RNIL;
  1721.   /* ------------------------------------------------------------------------
  1722.    *       WE WILL MOVE ALL RECORDS FROM THE ACC BLOCKED LIST AT ONCE.
  1723.    * ------------------------------------------------------------------------ */
  1724.   while (tcConnectptr.i != RNIL) {
  1725.     jam();
  1726.     ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
  1727.     maaTcNextConnectptr = tcConnectptr.p->nextTc;
  1728.     ndbrequire(tcConnectptr.p->listState == TcConnectionrec::ACC_BLOCK_LIST);
  1729.     tcConnectptr.p->listState = TcConnectionrec::NOT_IN_LIST;
  1730.     linkActiveFrag(signal);
  1731.     tcConnectptr.i = maaTcNextConnectptr;
  1732.   }//while
  1733. }//Dblqh::moveAccActiveFrag()
  1734. /* -------------------------------------------------------------------------- 
  1735.  * -------               MOVE OPERATION FROM ACTIVE LIST ON FRAGMENT  ------- 
  1736.  * -------               TO ACC BLOCKED LIST ON FRAGMENT              -------
  1737.  *
  1738.  *       SUBROUTINE SHORT NAME = MAT
  1739.  * -------------------------------------------------------------------------- */
  1740. void Dblqh::moveActiveToAcc(Signal* signal) 
  1741. {
  1742.   TcConnectionrecPtr matTcNextConnectptr;
  1743.   releaseActiveList(signal);
  1744.   /* ------------------------------------------------------------------------
  1745.    *       PUT OPERATION RECORD FIRST IN ACC BLOCKED LIST.
  1746.    * ------------------------------------------------------------------------ */
  1747.   matTcNextConnectptr.i = fragptr.p->accBlockedList;
  1748.   tcConnectptr.p->nextTc = matTcNextConnectptr.i;
  1749.   tcConnectptr.p->prevTc = RNIL;
  1750.   tcConnectptr.p->listState = TcConnectionrec::ACC_BLOCK_LIST;
  1751.   fragptr.p->accBlockedList = tcConnectptr.i;
  1752.   if (matTcNextConnectptr.i != RNIL) {
  1753.     jam();
  1754.     ptrCheckGuard(matTcNextConnectptr, ctcConnectrecFileSize, tcConnectionrec);
  1755.     matTcNextConnectptr.p->prevTc = tcConnectptr.i;
  1756.   }//if
  1757. }//Dblqh::moveActiveToAcc()
  1758. /* ------------------------------------------------------------------------- */
  1759. /* ---- RELEASE LOCAL LCP RECORDS AFTER COMPLETION OF A LOCAL CHECKPOINT---- */
  1760. /*                                                                           */
  1761. /*       SUBROUTINE SHORT NAME = RLL                                         */
  1762. /* ------------------------------------------------------------------------- */
  1763. void Dblqh::releaseLocalLcps(Signal* signal) 
  1764. {
  1765.   lcpLocptr.i = lcpPtr.p->firstLcpLocAcc;
  1766.   while (lcpLocptr.i != RNIL){
  1767.     ptrCheckGuard(lcpLocptr, clcpLocrecFileSize, lcpLocRecord);
  1768.     Uint32 tmp = lcpLocptr.p->nextLcpLoc;
  1769.     releaseLcpLoc(signal);
  1770.     lcpLocptr.i = tmp;
  1771.   } 
  1772.   lcpPtr.p->firstLcpLocAcc = RNIL;
  1773.   
  1774.   lcpLocptr.i = lcpPtr.p->firstLcpLocTup;
  1775.   while (lcpLocptr.i != RNIL){
  1776.     ptrCheckGuard(lcpLocptr, clcpLocrecFileSize, lcpLocRecord);
  1777.     Uint32 tmp = lcpLocptr.p->nextLcpLoc;
  1778.     releaseLcpLoc(signal);
  1779.     lcpLocptr.i = tmp;
  1780.   } 
  1781.   lcpPtr.p->firstLcpLocTup = RNIL;
  1782.   
  1783. }//Dblqh::releaseLocalLcps()
  1784. /* ------------------------------------------------------------------------- */
  1785. /* -------       SEIZE LCP LOCAL RECORD                              ------- */
  1786. /*                                                                           */
  1787. /* ------------------------------------------------------------------------- */
  1788. void Dblqh::seizeLcpLoc(Signal* signal) 
  1789. {
  1790.   lcpLocptr.i = cfirstfreeLcpLoc;
  1791.   ptrCheckGuard(lcpLocptr, clcpLocrecFileSize, lcpLocRecord);
  1792.   cfirstfreeLcpLoc = lcpLocptr.p->nextLcpLoc;
  1793.   lcpLocptr.p->nextLcpLoc = RNIL;
  1794. }//Dblqh::seizeLcpLoc()
  1795. /* ------------------------------------------------------------------------- */
  1796. /* -------               SEND ACC_CONT_OP                            ------- */
  1797. /*                                                                           */
  1798. /*       INPUT:          LCP_PTR         LOCAL CHECKPOINT RECORD             */
  1799. /*                       FRAGPTR         FRAGMENT RECORD                     */
  1800. /*                                                                           */
  1801. /*       SUBROUTINE SHORT NAME = SAC                                         */
  1802. /* ------------------------------------------------------------------------- */
  1803. void Dblqh::sendAccContOp(Signal* signal) 
  1804. {
  1805.   LcpLocRecordPtr sacLcpLocptr;
  1806.   int count = 0;
  1807.   sacLcpLocptr.i = lcpPtr.p->firstLcpLocAcc;
  1808.   do {
  1809.     ptrCheckGuard(sacLcpLocptr, clcpLocrecFileSize, lcpLocRecord);
  1810.     sacLcpLocptr.p->accContCounter = 0;
  1811.     /* ------------------------------------------------------------------- */
  1812.     /*SEND START OPERATIONS TO ACC AGAIN                                   */
  1813.     /* ------------------------------------------------------------------- */
  1814.     signal->theData[0] = lcpPtr.p->lcpAccptr;
  1815.     signal->theData[1] = sacLcpLocptr.p->locFragid;
  1816.     sendSignal(fragptr.p->accBlockref, GSN_ACC_CONTOPREQ, signal, 2, JBA);
  1817.     sacLcpLocptr.i = sacLcpLocptr.p->nextLcpLoc;
  1818.   } while (sacLcpLocptr.i != RNIL);
  1819.   
  1820. }//Dblqh::sendAccContOp()
  1821. /* ------------------------------------------------------------------------- */
  1822. /* -------               SEND ACC_LCPREQ AND TUP_LCPREQ              ------- */
  1823. /*                                                                           */
  1824. /*       INPUT:          LCP_PTR             LOCAL CHECKPOINT RECORD         */
  1825. /*                       FRAGPTR             FRAGMENT RECORD                 */
  1826. /*       SUBROUTINE SHORT NAME = STL                                         */
  1827. /* ------------------------------------------------------------------------- */
  1828. void Dblqh::sendStartLcp(Signal* signal) 
  1829. {
  1830.   LcpLocRecordPtr stlLcpLocptr;
  1831.   stlLcpLocptr.i = lcpPtr.p->firstLcpLocAcc;
  1832.   do {
  1833.     jam();
  1834.     ptrCheckGuard(stlLcpLocptr, clcpLocrecFileSize, lcpLocRecord);
  1835.     stlLcpLocptr.p->lcpLocstate = LcpLocRecord::ACC_WAIT_STARTED;
  1836.     signal->theData[0] = lcpPtr.p->lcpAccptr;
  1837.     signal->theData[1] = stlLcpLocptr.i;
  1838.     signal->theData[2] = stlLcpLocptr.p->locFragid;
  1839.     sendSignal(fragptr.p->accBlockref, GSN_ACC_LCPREQ, signal, 3, JBA);
  1840.     stlLcpLocptr.i = stlLcpLocptr.p->nextLcpLoc;
  1841.   } while (stlLcpLocptr.i != RNIL);
  1842.   stlLcpLocptr.i = lcpPtr.p->firstLcpLocTup;
  1843.   do {
  1844.     jam();
  1845.     ptrCheckGuard(stlLcpLocptr, clcpLocrecFileSize, lcpLocRecord);
  1846.     stlLcpLocptr.p->lcpLocstate = LcpLocRecord::TUP_WAIT_STARTED;
  1847.     signal->theData[0] = stlLcpLocptr.i;
  1848.     signal->theData[1] = cownref;
  1849.     signal->theData[2] = stlLcpLocptr.p->tupRef;
  1850.     if(ERROR_INSERTED(5077))
  1851.       sendSignalWithDelay(fragptr.p->tupBlockref, GSN_TUP_LCPREQ, 
  1852.   signal, 5000, 3);
  1853.     else
  1854.       sendSignal(fragptr.p->tupBlockref, GSN_TUP_LCPREQ, signal, 3, JBA);
  1855.     stlLcpLocptr.i = stlLcpLocptr.p->nextLcpLoc;
  1856.   } while (stlLcpLocptr.i != RNIL);
  1857.   if(ERROR_INSERTED(5077))
  1858.   {
  1859.     ndbout_c("Delayed TUP_LCPREQ with 5 sec");
  1860.   }
  1861. }//Dblqh::sendStartLcp()
  1862. /* ------------------------------------------------------------------------- */
  1863. /* -------               SET THE LOG TAIL IN THE LOG FILES           ------- */
  1864. /*                                                                           */
  1865. /*THIS SUBROUTINE HAVE BEEN BUGGY AND IS RATHER COMPLEX. IT IS IMPORTANT TO  */
  1866. /*REMEMBER THAT WE SEARCH FROM THE TAIL UNTIL WE REACH THE HEAD (CURRENT).   */
  1867. /*THE TAIL AND HEAD CAN BE ON THE SAME MBYTE. WE SEARCH UNTIL WE FIND A MBYTE*/
  1868. /*THAT WE NEED TO KEEP. WE THEN SET THE TAIL TO BE THE PREVIOUS. IF WE DO    */
  1869. /*NOT FIND A MBYTE THAT WE NEED TO KEEP UNTIL WE REACH THE HEAD THEN WE USE  */
  1870. /*THE HEAD AS TAIL. FINALLY WE HAVE TO MOVE BACK THE TAIL TO ALSO INCLUDE    */
  1871. /*ALL PREPARE RECORDS. THIS MEANS THAT LONG-LIVED TRANSACTIONS ARE DANGEROUS */
  1872. /*FOR SHORT LOGS.                                                            */
  1873. /* ------------------------------------------------------------------------- */
  1874. // this function has not been verified yet
  1875. Uint32 Dblqh::remainingLogSize(const LogFileRecordPtr &sltCurrLogFilePtr,
  1876.        const LogPartRecordPtr &sltLogPartPtr)
  1877. {
  1878.   Uint32 hf = sltCurrLogFilePtr.p->fileNo*ZNO_MBYTES_IN_FILE+sltCurrLogFilePtr.p->currentMbyte;
  1879.   Uint32 tf = sltLogPartPtr.p->logTailFileNo*ZNO_MBYTES_IN_FILE+sltLogPartPtr.p->logTailMbyte;
  1880.   Uint32 sz = sltLogPartPtr.p->noLogFiles*ZNO_MBYTES_IN_FILE;
  1881.   if (tf > hf) hf += sz;
  1882.   return sz-(hf-tf);
  1883. }
  1884. void Dblqh::setLogTail(Signal* signal, Uint32 keepGci) 
  1885. {
  1886.   LogPartRecordPtr sltLogPartPtr;
  1887.   LogFileRecordPtr sltLogFilePtr;
  1888. #if 0
  1889.   LogFileRecordPtr sltCurrLogFilePtr;
  1890. #endif
  1891.   UintR tsltMbyte;
  1892.   UintR tsltStartMbyte;
  1893.   UintR tsltIndex;
  1894.   UintR tsltFlag;
  1895.   for (sltLogPartPtr.i = 0; sltLogPartPtr.i < 4; sltLogPartPtr.i++) {
  1896.     jam();
  1897.     ptrAss(sltLogPartPtr, logPartRecord);
  1898.     findLogfile(signal, sltLogPartPtr.p->logTailFileNo,
  1899.                 sltLogPartPtr, &sltLogFilePtr);
  1900. #if 0
  1901.     sltCurrLogFilePtr.i = sltLogPartPtr.p->currentLogfile;
  1902.     ptrCheckGuard(sltCurrLogFilePtr, clogFileFileSize, logFileRecord);
  1903.     infoEvent("setLogTail: Available log file %d size = %d[mbytes]+%d[words]", sltLogPartPtr.i,
  1904.       remainingLogSize(sltCurrLogFilePtr, sltLogPartPtr), sltCurrLogFilePtr.p->remainingWordsInMbyte);
  1905. #endif
  1906.     tsltMbyte = sltLogPartPtr.p->logTailMbyte;
  1907.     tsltStartMbyte = tsltMbyte;
  1908.     tsltFlag = ZFALSE;
  1909.     if (sltLogFilePtr.i == sltLogPartPtr.p->currentLogfile) {
  1910. /* ------------------------------------------------------------------------- */
  1911. /*THE LOG AND THE TAIL IS ALREADY IN THE SAME FILE.                          */
  1912. /* ------------------------------------------------------------------------- */
  1913.       if (sltLogFilePtr.p->currentMbyte >= sltLogPartPtr.p->logTailMbyte) {
  1914.         jam();
  1915. /* ------------------------------------------------------------------------- */
  1916. /*THE CURRENT MBYTE IS AHEAD OF OR AT THE TAIL. THUS WE WILL ONLY LOOK FOR   */
  1917. /*THE TAIL UNTIL WE REACH THE CURRENT MBYTE WHICH IS IN THIS LOG FILE.       */
  1918. /*IF THE LOG TAIL IS AHEAD OF THE CURRENT MBYTE BUT IN THE SAME LOG FILE     */
  1919. /*THEN WE HAVE TO SEARCH THROUGH ALL FILES BEFORE WE COME TO THE CURRENT     */
  1920. /*MBYTE. WE ALWAYS STOP WHEN WE COME TO THE CURRENT MBYTE SINCE THE TAIL     */
  1921. /*CAN NEVER BE BEFORE THE HEAD.                                              */
  1922. /* ------------------------------------------------------------------------- */
  1923.         tsltFlag = ZTRUE;
  1924.       }//if
  1925.     }//if
  1926. /* ------------------------------------------------------------------------- */
  1927. /*NOW START SEARCHING FOR THE NEW TAIL, STARTING AT THE CURRENT TAIL AND     */
  1928. /*PROCEEDING UNTIL WE FIND A MBYTE WHICH IS NEEDED TO KEEP OR UNTIL WE REACH */
  1929. /*CURRENT MBYTE (THE HEAD).                                                  */
  1930. /* ------------------------------------------------------------------------- */
  1931.   SLT_LOOP:
  1932.     for (tsltIndex = tsltStartMbyte;
  1933.  tsltIndex <= ZNO_MBYTES_IN_FILE - 1; 
  1934.  tsltIndex++) {
  1935.       if (sltLogFilePtr.p->logMaxGciStarted[tsltIndex] >= keepGci) {
  1936. /* ------------------------------------------------------------------------- */
  1937. /*WE ARE NOT ALLOWED TO STEP THE LOG ANY FURTHER AHEAD                       */
  1938. /*SET THE NEW LOG TAIL AND CONTINUE WITH NEXT LOG PART.                      */
  1939. /*THIS MBYTE IS NOT TO BE INCLUDED SO WE NEED TO STEP BACK ONE MBYTE.        */
  1940. /* ------------------------------------------------------------------------- */
  1941.         if (tsltIndex != 0) {
  1942.           jam();
  1943.           tsltMbyte = tsltIndex - 1;
  1944.         } else {
  1945.           jam();
  1946. /* ------------------------------------------------------------------------- */
  1947. /*STEPPING BACK INCLUDES ALSO STEPPING BACK TO THE PREVIOUS LOG FILE.        */
  1948. /* ------------------------------------------------------------------------- */
  1949.           tsltMbyte = ZNO_MBYTES_IN_FILE - 1;
  1950.           sltLogFilePtr.i = sltLogFilePtr.p->prevLogFile;
  1951.           ptrCheckGuard(sltLogFilePtr, clogFileFileSize, logFileRecord);
  1952.         }//if
  1953.         goto SLT_BREAK;
  1954.       } else {
  1955.         jam();
  1956.         if (tsltFlag == ZTRUE) {
  1957. /* ------------------------------------------------------------------------- */
  1958. /*WE ARE IN THE SAME FILE AS THE CURRENT MBYTE AND WE CAN REACH THE CURRENT  */
  1959. /*MBYTE BEFORE WE REACH A NEW TAIL.                                          */
  1960. /* ------------------------------------------------------------------------- */
  1961.           if (tsltIndex == sltLogFilePtr.p->currentMbyte) {
  1962.             jam();
  1963. /* ------------------------------------------------------------------------- */
  1964. /*THE TAIL OF THE LOG IS ACTUALLY WITHIN THE CURRENT MBYTE. THUS WE SET THE  */
  1965. /*LOG TAIL TO BE THE CURRENT MBYTE.                                          */
  1966. /* ------------------------------------------------------------------------- */
  1967.             tsltMbyte = sltLogFilePtr.p->currentMbyte;
  1968.             goto SLT_BREAK;
  1969.           }//if
  1970.         }//if
  1971.       }//if
  1972.     }//for
  1973.     sltLogFilePtr.i = sltLogFilePtr.p->nextLogFile;
  1974.     ptrCheckGuard(sltLogFilePtr, clogFileFileSize, logFileRecord);
  1975.     if (sltLogFilePtr.i == sltLogPartPtr.p->currentLogfile) {
  1976.       jam();
  1977.       tsltFlag = ZTRUE;
  1978.     }//if
  1979.     tsltStartMbyte = 0;
  1980.     goto SLT_LOOP;
  1981.   SLT_BREAK:
  1982.     jam();
  1983.     {
  1984.       UintR ToldTailFileNo = sltLogPartPtr.p->logTailFileNo;
  1985.       UintR ToldTailMByte = sltLogPartPtr.p->logTailMbyte;
  1986.       arrGuard(tsltMbyte, 16);
  1987.       sltLogPartPtr.p->logTailFileNo = 
  1988.          sltLogFilePtr.p->logLastPrepRef[tsltMbyte] >> 16;
  1989. /* ------------------------------------------------------------------------- */
  1990. /*SINCE LOG_MAX_GCI_STARTED ONLY KEEP TRACK OF COMMIT LOG RECORDS WE ALSO    */
  1991. /*HAVE TO STEP BACK THE TAIL SO THAT WE INCLUDE ALL PREPARE RECORDS          */
  1992. /*NEEDED FOR THOSE COMMIT RECORDS IN THIS MBYTE. THIS IS A RATHER            */
  1993. /*CONSERVATIVE APPROACH BUT IT WORKS.                                        */
  1994. /* ------------------------------------------------------------------------- */
  1995.       sltLogPartPtr.p->logTailMbyte = 
  1996.         sltLogFilePtr.p->logLastPrepRef[tsltMbyte] & 65535;
  1997.       if ((ToldTailFileNo != sltLogPartPtr.p->logTailFileNo) ||
  1998.           (ToldTailMByte != sltLogPartPtr.p->logTailMbyte)) {
  1999.         jam();
  2000.         if (sltLogPartPtr.p->logPartState == LogPartRecord::TAIL_PROBLEM) {
  2001.           if (sltLogPartPtr.p->firstLogQueue == RNIL) {
  2002.             jam();
  2003.             sltLogPartPtr.p->logPartState = LogPartRecord::IDLE;
  2004.           } else {
  2005.             jam();
  2006.             sltLogPartPtr.p->logPartState = LogPartRecord::ACTIVE;
  2007.           }//if
  2008.         }//if
  2009.       }//if
  2010.     }
  2011. #if 0
  2012.     infoEvent("setLogTail: Available log file %d size = %d[mbytes]+%d[words]", sltLogPartPtr.i,
  2013.       remainingLogSize(sltCurrLogFilePtr, sltLogPartPtr), sltCurrLogFilePtr.p->remainingWordsInMbyte);
  2014. #endif
  2015.   }//for
  2016. }//Dblqh::setLogTail()
  2017. /* ######################################################################### */
  2018. /* #######                       GLOBAL CHECKPOINT MODULE            ####### */
  2019. /*                                                                           */
  2020. /* ######################################################################### */
  2021. /*---------------------------------------------------------------------------*/
  2022. /* THIS MODULE HELPS DIH IN DISCOVERING WHEN GLOBAL CHECKPOINTS ARE          */
  2023. /* RECOVERABLE. IT HANDLES THE REQUEST GCP_SAVEREQ THAT REQUESTS LQH TO      */
  2024. /* SAVE A PARTICULAR GLOBAL CHECKPOINT TO DISK AND RESPOND WHEN COMPLETED.   */
  2025. /*---------------------------------------------------------------------------*/
  2026. /* *************** */
  2027. /*  GCP_SAVEREQ  > */
  2028. /* *************** */
  2029. void Dblqh::execGCP_SAVEREQ(Signal* signal) 
  2030. {
  2031.   jamEntry();
  2032.   const GCPSaveReq * const saveReq = (GCPSaveReq *)&signal->theData[0];
  2033.   if (ERROR_INSERTED(5000)) {
  2034.     systemErrorLab(signal);
  2035.   }
  2036.   if (ERROR_INSERTED(5007)){
  2037.     CLEAR_ERROR_INSERT_VALUE;
  2038.     sendSignalWithDelay(cownref, GSN_GCP_SAVEREQ, signal, 10000, 
  2039. signal->length());
  2040.     return;
  2041.   }
  2042.   const Uint32 dihBlockRef = saveReq->dihBlockRef;
  2043.   const Uint32 dihPtr = saveReq->dihPtr;
  2044.   const Uint32 gci = saveReq->gci;
  2045.   
  2046.   ndbrequire(gci >= cnewestCompletedGci);
  2047.   
  2048.   if (gci == cnewestCompletedGci) {
  2049. /*---------------------------------------------------------------------------*/
  2050. /* GLOBAL CHECKPOINT HAVE ALREADY BEEN HANDLED. REQUEST MUST HAVE BEEN SENT  */
  2051. /* FROM NEW MASTER DIH.                                                      */
  2052. /*---------------------------------------------------------------------------*/
  2053.     if (ccurrentGcprec == RNIL) {
  2054.       jam();
  2055. /*---------------------------------------------------------------------------*/
  2056. /* THIS INDICATES THAT WE HAVE ALREADY SENT GCP_SAVECONF TO PREVIOUS MASTER. */
  2057. /* WE SIMPLY SEND IT ALSO TO THE NEW MASTER.                                 */
  2058. /*---------------------------------------------------------------------------*/
  2059.       GCPSaveConf * const saveConf = (GCPSaveConf*)&signal->theData[0];
  2060.       saveConf->dihPtr = dihPtr;
  2061.       saveConf->nodeId = getOwnNodeId();
  2062.       saveConf->gci    = cnewestCompletedGci;
  2063.       sendSignal(dihBlockRef, GSN_GCP_SAVECONF, signal, 
  2064.  GCPSaveConf::SignalLength, JBA);
  2065.       return;
  2066.     }
  2067.     jam();
  2068. /*---------------------------------------------------------------------------*/
  2069. /* WE HAVE NOT YET SENT THE RESPONSE TO THE OLD MASTER. WE WILL SET THE NEW  */
  2070. /* RECEIVER OF THE RESPONSE AND THEN EXIT SINCE THE PROCESS IS ALREADY       */
  2071. /* STARTED.                                                                  */
  2072. /*---------------------------------------------------------------------------*/
  2073.     gcpPtr.i = ccurrentGcprec;
  2074.     ptrCheckGuard(gcpPtr, cgcprecFileSize, gcpRecord);
  2075.     gcpPtr.p->gcpUserptr = dihPtr;
  2076.     gcpPtr.p->gcpBlockref = dihBlockRef;
  2077.     return;
  2078.   }//if
  2079.   
  2080.   ndbrequire(ccurrentGcprec == RNIL);
  2081.   
  2082.   
  2083.   if(getNodeState().startLevel >= NodeState::SL_STOPPING_4){
  2084.     GCPSaveRef * const saveRef = (GCPSaveRef*)&signal->theData[0];
  2085.     saveRef->dihPtr = dihPtr;
  2086.     saveRef->nodeId = getOwnNodeId();
  2087.     saveRef->gci    = gci;
  2088.     saveRef->errorCode = GCPSaveRef::NodeShutdownInProgress;
  2089.     sendSignal(dihBlockRef, GSN_GCP_SAVEREF, signal, 
  2090.        GCPSaveRef::SignalLength, JBB);
  2091.     return;
  2092.   }
  2093.   if(getNodeState().getNodeRestartInProgress()){
  2094.     GCPSaveRef * const saveRef = (GCPSaveRef*)&signal->theData[0];
  2095.     saveRef->dihPtr = dihPtr;
  2096.     saveRef->nodeId = getOwnNodeId();
  2097.     saveRef->gci    = gci;
  2098.     saveRef->errorCode = GCPSaveRef::NodeRestartInProgress;
  2099.     sendSignal(dihBlockRef, GSN_GCP_SAVEREF, signal, 
  2100.        GCPSaveRef::SignalLength, JBB);
  2101.     return;
  2102.   }
  2103.   
  2104.   ccurrentGcprec = 0;
  2105.   gcpPtr.i = ccurrentGcprec;
  2106.   ptrCheckGuard(gcpPtr, cgcprecFileSize, gcpRecord);
  2107.   
  2108.   cnewestCompletedGci = gci;
  2109.   if (gci > cnewestGci) {
  2110.     jam();
  2111.     cnewestGci = gci;
  2112.   }//if
  2113.   
  2114.   gcpPtr.p->gcpBlockref = dihBlockRef;
  2115.   gcpPtr.p->gcpUserptr = dihPtr;
  2116.   gcpPtr.p->gcpId = gci;
  2117.   bool tlogActive = false;
  2118.   for (logPartPtr.i = 0; logPartPtr.i <= 3; logPartPtr.i++) {
  2119.     ptrAss(logPartPtr, logPartRecord);
  2120.     if (logPartPtr.p->logPartState == LogPartRecord::ACTIVE) {
  2121.       jam();
  2122.       logPartPtr.p->waitWriteGciLog = LogPartRecord::WWGL_TRUE;
  2123.       tlogActive = true;
  2124.     } else {
  2125.       jam();
  2126.       logPartPtr.p->waitWriteGciLog = LogPartRecord::WWGL_FALSE;
  2127.       logFilePtr.i = logPartPtr.p->currentLogfile;
  2128.       ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
  2129.       logPagePtr.i = logFilePtr.p->currentLogpage;
  2130.       ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
  2131.       writeCompletedGciLog(signal);
  2132.     }//if
  2133.   }//for
  2134.   if (tlogActive == true) {
  2135.     jam();
  2136.     return;
  2137.   }//if
  2138.   initGcpRecLab(signal);
  2139.   startTimeSupervision(signal);
  2140.   return;
  2141. }//Dblqh::execGCP_SAVEREQ()
  2142. /* ------------------------------------------------------------------------- */
  2143. /*  START TIME SUPERVISION OF THE LOG PARTS.                                 */
  2144. /* ------------------------------------------------------------------------- */
  2145. void Dblqh::startTimeSupervision(Signal* signal) 
  2146. {
  2147.   for (logPartPtr.i = 0; logPartPtr.i <= 3; logPartPtr.i++) {
  2148.     jam();
  2149.     ptrAss(logPartPtr, logPartRecord);
  2150. /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
  2151. /* WE HAVE TO START CHECKING IF THE LOG IS TO BE WRITTEN EVEN IF PAGES ARE   */
  2152. /* FULL. INITIALISE THE VALUES OF WHERE WE ARE IN THE LOG CURRENTLY.         */
  2153. /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
  2154.     logPartPtr.p->logPartTimer = 0;
  2155.     logPartPtr.p->logTimer = 1;
  2156.     signal->theData[0] = ZTIME_SUPERVISION;
  2157.     signal->theData[1] = logPartPtr.i;
  2158.     sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
  2159.   }//for
  2160. }//Dblqh::startTimeSupervision()
  2161. /*---------------------------------------------------------------------------*/
  2162. /* WE SET THE GLOBAL CHECKPOINT VARIABLES AFTER WRITING THE COMPLETED GCI LOG*/
  2163. /* RECORD. THIS ENSURES THAT WE WILL ENCOUNTER THE COMPLETED GCI RECORD WHEN */
  2164. /* WE EXECUTE THE FRAGMENT LOG.                                              */
  2165. /*---------------------------------------------------------------------------*/
  2166. void Dblqh::initGcpRecLab(Signal* signal) 
  2167. {
  2168. /* ======================================================================== */
  2169. /* =======               INITIATE GCP RECORD                        ======= */
  2170. /*                                                                          */
  2171. /*       SUBROUTINE SHORT NAME = IGR                                        */
  2172. /* ======================================================================== */
  2173.   for (logPartPtr.i = 0; logPartPtr.i <= 3; logPartPtr.i++) {
  2174.     jam();
  2175.     ptrAss(logPartPtr, logPartRecord);
  2176. /*--------------------------------------------------*/
  2177. /*       BY SETTING THE GCPREC = 0 WE START THE     */
  2178. /*       CHECKING BY CHECK_GCP_COMPLETED. THIS      */
  2179. /*       CHECKING MUST NOT BE STARTED UNTIL WE HAVE */
  2180. /*       INSERTED ALL COMPLETE GCI LOG RECORDS IN   */
  2181. /*       ALL LOG PARTS.                             */
  2182. /*--------------------------------------------------*/
  2183.     logPartPtr.p->gcprec = 0;
  2184.     gcpPtr.p->gcpLogPartState[logPartPtr.i] = ZWAIT_DISK;
  2185.     gcpPtr.p->gcpSyncReady[logPartPtr.i] = ZFALSE;
  2186.     logFilePtr.i = logPartPtr.p->currentLogfile;
  2187.     ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
  2188.     gcpPtr.p->gcpFilePtr[logPartPtr.i] = logFilePtr.i;
  2189.     logPagePtr.i = logFilePtr.p->currentLogpage;
  2190.     ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
  2191.     if (logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] == ZPAGE_HEADER_SIZE) {
  2192.       jam();
  2193. /*--------------------------------------------------*/
  2194. /*       SINCE THE CURRENT FILEPAGE POINTS AT THE   */
  2195. /*       NEXT WORD TO BE WRITTEN WE HAVE TO ADJUST  */
  2196. /*       FOR THIS BY DECREASING THE FILE PAGE BY ONE*/
  2197. /*       IF NO WORD HAS BEEN WRITTEN ON THE CURRENT */
  2198. /*       FILEPAGE.                                  */
  2199. /*--------------------------------------------------*/
  2200.       gcpPtr.p->gcpPageNo[logPartPtr.i] = logFilePtr.p->currentFilepage - 1;
  2201.       gcpPtr.p->gcpWordNo[logPartPtr.i] = ZPAGE_SIZE - 1;
  2202.     } else {
  2203.       jam();
  2204.       gcpPtr.p->gcpPageNo[logPartPtr.i] = logFilePtr.p->currentFilepage;
  2205.       gcpPtr.p->gcpWordNo[logPartPtr.i] = 
  2206. logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] - 1;
  2207.     }//if
  2208.   }//for
  2209.   return;
  2210. }//Dblqh::initGcpRecLab()
  2211. /* ========================================================================= */
  2212. /* ==== CHECK IF ANY GLOBAL CHECKPOINTS ARE COMPLETED AFTER A COMPLETED===== */
  2213. /*      DISK WRITE.                                                          */
  2214. /*                                                                           */
  2215. /*       SUBROUTINE SHORT NAME = CGC                                         */
  2216. /* ========================================================================= */
  2217. void Dblqh::checkGcpCompleted(Signal* signal,
  2218.                               Uint32 tcgcPageWritten,
  2219.                               Uint32 tcgcWordWritten) 
  2220. {
  2221.   UintR tcgcFlag;
  2222.   UintR tcgcJ;
  2223.   gcpPtr.i = logPartPtr.p->gcprec;
  2224.   if (gcpPtr.i != RNIL) {
  2225.     jam();
  2226. /* ------------------------------------------------------------------------- */
  2227. /* IF THE GLOBAL CHECKPOINT IS NOT WAITING FOR COMPLETION THEN WE CAN QUIT   */
  2228. /* THE SEARCH IMMEDIATELY.                                                   */
  2229. /* ------------------------------------------------------------------------- */
  2230.     ptrCheckGuard(gcpPtr, cgcprecFileSize, gcpRecord);
  2231.     if (gcpPtr.p->gcpFilePtr[logPartPtr.i] == logFilePtr.i) {
  2232. /* ------------------------------------------------------------------------- */
  2233. /* IF THE COMPLETED DISK OPERATION WAS ON ANOTHER FILE THAN THE ONE WE ARE   */
  2234. /* WAITING FOR, THEN WE CAN ALSO QUIT THE SEARCH IMMEDIATELY.                */
  2235. /* ------------------------------------------------------------------------- */
  2236.       if (tcgcPageWritten < gcpPtr.p->gcpPageNo[logPartPtr.i]) {
  2237.         jam();
  2238. /* ------------------------------------------------------------------------- */
  2239. /* THIS LOG PART HAVE NOT YET WRITTEN THE GLOBAL CHECKPOINT TO DISK.         */
  2240. /* ------------------------------------------------------------------------- */
  2241.         return;
  2242.       } else {
  2243.         if (tcgcPageWritten == gcpPtr.p->gcpPageNo[logPartPtr.i]) {
  2244.           if (tcgcWordWritten < gcpPtr.p->gcpWordNo[logPartPtr.i]) {
  2245.             jam();
  2246. /* ------------------------------------------------------------------------- */
  2247. /* THIS LOG PART HAVE NOT YET WRITTEN THE GLOBAL CHECKPOINT TO DISK.         */
  2248. /* ------------------------------------------------------------------------- */
  2249.             return;
  2250.           }//if
  2251.         }//if
  2252.       }//if
  2253. /* ------------------------------------------------------------------------- */
  2254. /* THIS LOG PART HAVE WRITTEN THE GLOBAL CHECKPOINT TO DISK.                 */
  2255. /* ------------------------------------------------------------------------- */
  2256.       logPartPtr.p->gcprec = RNIL;
  2257.       gcpPtr.p->gcpLogPartState[logPartPtr.i] = ZON_DISK;
  2258.       tcgcFlag = ZTRUE;
  2259.       for (tcgcJ = 0; tcgcJ <= 3; tcgcJ++) {
  2260.         jam();
  2261.         if (gcpPtr.p->gcpLogPartState[tcgcJ] != ZON_DISK) {
  2262.           jam();
  2263. /* ------------------------------------------------------------------------- */
  2264. /*ALL LOG PARTS HAVE NOT SAVED THIS GLOBAL CHECKPOINT TO DISK YET. WAIT FOR  */
  2265. /*THEM TO COMPLETE.                                                          */
  2266. /* ------------------------------------------------------------------------- */
  2267.           tcgcFlag = ZFALSE;
  2268.         }//if
  2269.       }//for
  2270.       if (tcgcFlag == ZTRUE) {
  2271.         jam();
  2272. /* ------------------------------------------------------------------------- */
  2273. /*WE HAVE FOUND A COMPLETED GLOBAL CHECKPOINT OPERATION. WE NOW NEED TO SEND */
  2274. /*GCP_SAVECONF, REMOVE THE GCP RECORD FROM THE LIST OF WAITING GCP RECORDS   */
  2275. /*ON THIS LOG PART AND RELEASE THE GCP RECORD.                               */
  2276. // After changing the log implementation we need to perform a FSSYNCREQ on all
  2277. // log files where the last log word resided first before proceeding.
  2278. /* ------------------------------------------------------------------------- */
  2279.         UintR Ti;
  2280.         for (Ti = 0; Ti < 4; Ti++) {
  2281.           LogFileRecordPtr loopLogFilePtr;
  2282.           loopLogFilePtr.i = gcpPtr.p->gcpFilePtr[Ti];
  2283.           ptrCheckGuard(loopLogFilePtr, clogFileFileSize, logFileRecord);
  2284.           if (loopLogFilePtr.p->logFileStatus == LogFileRecord::OPEN) {
  2285.             jam();
  2286.             signal->theData[0] = loopLogFilePtr.p->fileRef;
  2287.             signal->theData[1] = cownref;
  2288.             signal->theData[2] = gcpPtr.p->gcpFilePtr[Ti];
  2289.             sendSignal(NDBFS_REF, GSN_FSSYNCREQ, signal, 3, JBA);
  2290.           } else {
  2291.             ndbrequire((loopLogFilePtr.p->logFileStatus == 
  2292.                         LogFileRecord::CLOSED) ||
  2293.                         (loopLogFilePtr.p->logFileStatus == 
  2294.                          LogFileRecord::CLOSING_WRITE_LOG) ||
  2295.                         (loopLogFilePtr.p->logFileStatus == 
  2296.                          LogFileRecord::OPENING_WRITE_LOG));
  2297.             signal->theData[0] = loopLogFilePtr.i;
  2298.             execFSSYNCCONF(signal);
  2299.           }//if
  2300.         }//for
  2301.         return;
  2302.       }//if
  2303.     }//if
  2304.   }//if
  2305. }//Dblqh::checkGcpCompleted()
  2306. void
  2307. Dblqh::execFSSYNCCONF(Signal* signal)
  2308. {
  2309.   GcpRecordPtr localGcpPtr;
  2310.   LogFileRecordPtr localLogFilePtr;
  2311.   LogPartRecordPtr localLogPartPtr;
  2312.   localLogFilePtr.i = signal->theData[0];
  2313.   ptrCheckGuard(localLogFilePtr, clogFileFileSize, logFileRecord);
  2314.   localLogPartPtr.i = localLogFilePtr.p->logPartRec;
  2315.   localGcpPtr.i = ccurrentGcprec;
  2316.   ptrCheckGuard(localGcpPtr, cgcprecFileSize, gcpRecord);
  2317.   localGcpPtr.p->gcpSyncReady[localLogPartPtr.i] = ZTRUE;
  2318.   UintR Ti;
  2319.   for (Ti = 0; Ti < 4; Ti++) {
  2320.     jam();
  2321.     if (localGcpPtr.p->gcpSyncReady[Ti] == ZFALSE) {
  2322.       jam();
  2323.       return;
  2324.     }//if
  2325.   }//for
  2326.   GCPSaveConf * const saveConf = (GCPSaveConf *)&signal->theData[0];
  2327.   saveConf->dihPtr = localGcpPtr.p->gcpUserptr;
  2328.   saveConf->nodeId = getOwnNodeId();
  2329.   saveConf->gci    = localGcpPtr.p->gcpId;
  2330.   sendSignal(localGcpPtr.p->gcpBlockref, GSN_GCP_SAVECONF, signal, 
  2331.      GCPSaveConf::SignalLength, JBA);
  2332.   ccurrentGcprec = RNIL;
  2333. }//Dblqh::execFSSYNCCONF()
  2334. /* ######################################################################### */
  2335. /* #######                            FILE HANDLING MODULE           ####### */
  2336. /*                                                                           */
  2337. /* ######################################################################### */
  2338. /*       THIS MODULE HANDLES RESPONSE MESSAGES FROM THE FILE SYSTEM          */
  2339. /* ######################################################################### */
  2340. /* ######################################################################### */
  2341. /*       SIGNAL RECEPTION MODULE                                             */
  2342. /*       THIS MODULE IS A SUB-MODULE OF THE FILE SYSTEM HANDLING.            */
  2343. /*                                                                           */
  2344. /*  THIS MODULE CHECKS THE STATE AND JUMPS TO THE PROPER PART OF THE FILE    */
  2345. /*  HANDLING MODULE.                                                         */
  2346. /* ######################################################################### */
  2347. /* *************** */
  2348. /*  FSCLOSECONF  > */
  2349. /* *************** */
  2350. void Dblqh::execFSCLOSECONF(Signal* signal) 
  2351. {
  2352.   jamEntry();
  2353.   logFilePtr.i = signal->theData[0];
  2354.   ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
  2355.   switch (logFilePtr.p->logFileStatus) {
  2356.   case LogFileRecord::CLOSE_SR_INVALIDATE_PAGES:
  2357.     jam();
  2358.     logFilePtr.p->logFileStatus = LogFileRecord::CLOSED;
  2359.     // Set the prev file to check if we shall close it.
  2360.     logFilePtr.i = logFilePtr.p->prevLogFile;
  2361.     ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
  2362.     exitFromInvalidate(signal);
  2363.     return;
  2364.   case LogFileRecord::CLOSING_INIT:
  2365.     jam();
  2366.     closingInitLab(signal);
  2367.     return;
  2368.   case LogFileRecord::CLOSING_SR:
  2369.     jam();
  2370.     closingSrLab(signal);
  2371.     return;
  2372.   case LogFileRecord::CLOSING_EXEC_SR:
  2373.     jam();
  2374.     closeExecSrLab(signal);
  2375.     return;
  2376.   case LogFileRecord::CLOSING_EXEC_SR_COMPLETED:
  2377.     jam();
  2378.     closeExecSrCompletedLab(signal);
  2379.     return;
  2380.   case LogFileRecord::CLOSING_WRITE_LOG:
  2381.     jam();
  2382.     closeWriteLogLab(signal);
  2383.     return;
  2384.   case LogFileRecord::CLOSING_EXEC_LOG:
  2385.     jam();
  2386.     closeExecLogLab(signal);
  2387.     return;
  2388.   default:
  2389.     jam();
  2390.     systemErrorLab(signal);
  2391.     return;
  2392.   }//switch
  2393. }//Dblqh::execFSCLOSECONF()
  2394. /* ************>> */
  2395. /*  FSOPENCONF  > */
  2396. /* ************>> */
  2397. void Dblqh::execFSOPENCONF(Signal* signal) 
  2398. {
  2399.   jamEntry();
  2400.   initFsopenconf(signal);
  2401.   switch (logFilePtr.p->logFileStatus) {
  2402.   case LogFileRecord::OPEN_SR_INVALIDATE_PAGES:
  2403.     jam();
  2404.     logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
  2405.     readFileInInvalidate(signal);
  2406.     return;
  2407.   case LogFileRecord::OPENING_INIT:
  2408.     jam();
  2409.     logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
  2410.     openFileInitLab(signal);
  2411.     return;
  2412.   case LogFileRecord::OPEN_SR_FRONTPAGE:
  2413.     jam();
  2414.     logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
  2415.     openSrFrontpageLab(signal);
  2416.     return;
  2417.   case LogFileRecord::OPEN_SR_LAST_FILE:
  2418.     jam();
  2419.     logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
  2420.     openSrLastFileLab(signal);
  2421.     return;
  2422.   case LogFileRecord::OPEN_SR_NEXT_FILE:
  2423.     jam();
  2424.     logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
  2425.     openSrNextFileLab(signal);
  2426.     return;
  2427.   case LogFileRecord::OPEN_EXEC_SR_START:
  2428.     jam();
  2429.     logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
  2430.     openExecSrStartLab(signal);
  2431.     return;
  2432.   case LogFileRecord::OPEN_EXEC_SR_NEW_MBYTE:
  2433.     jam();
  2434.     logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
  2435.     openExecSrNewMbyteLab(signal);
  2436.     return;
  2437.   case LogFileRecord::OPEN_SR_FOURTH_PHASE:
  2438.     jam();
  2439.     logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
  2440.     openSrFourthPhaseLab(signal);
  2441.     return;
  2442.   case LogFileRecord::OPEN_SR_FOURTH_NEXT:
  2443.     jam();
  2444.     logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
  2445.     openSrFourthNextLab(signal);
  2446.     return;
  2447.   case LogFileRecord::OPEN_SR_FOURTH_ZERO:
  2448.     jam();
  2449.     logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
  2450.     openSrFourthZeroLab(signal);
  2451.     return;
  2452.   case LogFileRecord::OPENING_WRITE_LOG:
  2453.     jam();
  2454.     logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
  2455.     return;
  2456.   case LogFileRecord::OPEN_EXEC_LOG:
  2457.     jam();
  2458.     logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
  2459.     openExecLogLab(signal);
  2460.     return;
  2461.   default:
  2462.     jam();
  2463.     systemErrorLab(signal);
  2464.     return;
  2465.   }//switch
  2466. }//Dblqh::execFSOPENCONF()
  2467. /* ************>> */
  2468. /*  FSREADCONF  > */
  2469. /* ************>> */
  2470. void Dblqh::execFSREADCONF(Signal* signal) 
  2471. {
  2472.   jamEntry();
  2473.   initFsrwconf(signal, false);
  2474.   switch (lfoPtr.p->lfoState) {
  2475.   case LogFileOperationRecord::READ_SR_LAST_MBYTE:
  2476.     jam();
  2477.     releaseLfo(signal);
  2478.     readSrLastMbyteLab(signal);
  2479.     return;
  2480.   case LogFileOperationRecord::READ_SR_FRONTPAGE:
  2481.     jam();
  2482.     releaseLfo(signal);
  2483.     readSrFrontpageLab(signal);
  2484.     return;
  2485.   case LogFileOperationRecord::READ_SR_LAST_FILE:
  2486.     jam();
  2487.     releaseLfo(signal);
  2488.     readSrLastFileLab(signal);
  2489.     return;
  2490.   case LogFileOperationRecord::READ_SR_NEXT_FILE:
  2491.     jam();
  2492.     releaseLfo(signal);
  2493.     readSrNextFileLab(signal);
  2494.     return;
  2495.   case LogFileOperationRecord::READ_EXEC_SR:
  2496.     jam();
  2497.     readExecSrLab(signal);
  2498.     return;
  2499.   case LogFileOperationRecord::READ_EXEC_LOG:
  2500.     jam();
  2501.     readExecLogLab(signal);
  2502.     return;
  2503.   case LogFileOperationRecord::READ_SR_INVALIDATE_PAGES:
  2504.     jam();
  2505.     invalidateLogAfterLastGCI(signal);
  2506.     return;
  2507.   case LogFileOperationRecord::READ_SR_FOURTH_PHASE:
  2508.     jam();
  2509.     releaseLfo(signal);
  2510.     readSrFourthPhaseLab(signal);
  2511.     return;
  2512.   case LogFileOperationRecord::READ_SR_FOURTH_ZERO:
  2513.     jam();
  2514.     releaseLfo(signal);
  2515.     readSrFourthZeroLab(signal);
  2516.     return;
  2517.   default:
  2518.     jam();
  2519.     systemErrorLab(signal);
  2520.     return;
  2521.   }//switch
  2522. }//Dblqh::execFSREADCONF()
  2523. /* ************>> */
  2524. /*  FSREADCONF  > */
  2525. /* ************>> */
  2526. void Dblqh::execFSREADREF(Signal* signal) 
  2527. {
  2528.   jamEntry();
  2529.   lfoPtr.i = signal->theData[0];
  2530.   ptrCheckGuard(lfoPtr, clfoFileSize, logFileOperationRecord);
  2531.   switch (lfoPtr.p->lfoState) {
  2532.   case LogFileOperationRecord::READ_SR_LAST_MBYTE:
  2533.     jam();
  2534.     break;
  2535.   case LogFileOperationRecord::READ_SR_FRONTPAGE:
  2536.     jam();
  2537.     break;
  2538.   case LogFileOperationRecord::READ_SR_LAST_FILE:
  2539.     jam();
  2540.     break;
  2541.   case LogFileOperationRecord::READ_SR_NEXT_FILE:
  2542.     jam();
  2543.     break;
  2544.   case LogFileOperationRecord::READ_EXEC_SR:
  2545.     jam();
  2546.     break;
  2547.   case LogFileOperationRecord::READ_EXEC_LOG:
  2548.     jam();
  2549.     break;
  2550.   case LogFileOperationRecord::READ_SR_FOURTH_PHASE:
  2551.     jam();
  2552.     break;
  2553.   case LogFileOperationRecord::READ_SR_FOURTH_ZERO:
  2554.     jam();
  2555.     break;
  2556.   case LogFileOperationRecord::READ_SR_INVALIDATE_PAGES:
  2557.     jam()
  2558.     break;
  2559.   default:
  2560.     jam();
  2561.     break;
  2562.   }//switch
  2563.   {
  2564.     char msg[100];
  2565.     sprintf(msg, "File system read failed during LogFileOperationRecord state %d", (Uint32)lfoPtr.p->lfoState);
  2566.     fsRefError(signal,__LINE__,msg);
  2567.   }
  2568. }//Dblqh::execFSREADREF()
  2569. /* *************** */
  2570. /*  FSWRITECONF  > */
  2571. /* *************** */
  2572. void Dblqh::execFSWRITECONF(Signal* signal) 
  2573. {
  2574.   jamEntry();
  2575.   initFsrwconf(signal, true);
  2576.   switch (lfoPtr.p->lfoState) {
  2577.   case LogFileOperationRecord::WRITE_SR_INVALIDATE_PAGES:
  2578.     jam();
  2579.     invalidateLogAfterLastGCI(signal);
  2580.     return;
  2581.   case LogFileOperationRecord::WRITE_PAGE_ZERO:
  2582.     jam();
  2583.     writePageZeroLab(signal);
  2584.     return;
  2585.   case LogFileOperationRecord::LAST_WRITE_IN_FILE:
  2586.     jam();
  2587.     lastWriteInFileLab(signal);
  2588.     return;
  2589.   case LogFileOperationRecord::INIT_WRITE_AT_END:
  2590.     jam();
  2591.     initWriteEndLab(signal);
  2592.     return;
  2593.   case LogFileOperationRecord::INIT_FIRST_PAGE:
  2594.     jam();
  2595.     initFirstPageLab(signal);
  2596.     return;
  2597.   case LogFileOperationRecord::WRITE_GCI_ZERO:
  2598.     jam();
  2599.     writeGciZeroLab(signal);
  2600.     return;
  2601.   case LogFileOperationRecord::WRITE_DIRTY:
  2602.     jam();
  2603.     writeDirtyLab(signal);
  2604.     return;
  2605.   case LogFileOperationRecord::WRITE_INIT_MBYTE:
  2606.     jam();
  2607.     writeInitMbyteLab(signal);
  2608.     return;
  2609.   case LogFileOperationRecord::ACTIVE_WRITE_LOG:
  2610.     jam();
  2611.     writeLogfileLab(signal);
  2612.     return;
  2613.   case LogFileOperationRecord::FIRST_PAGE_WRITE_IN_LOGFILE:
  2614.     jam();
  2615.     firstPageWriteLab(signal);
  2616.     return;
  2617.   default:
  2618.     jam();
  2619.     systemErrorLab(signal);
  2620.     return;
  2621.   }//switch
  2622. }//Dblqh::execFSWRITECONF()
  2623. /* ************>> */
  2624. /*  FSWRITEREF  > */
  2625. /* ************>> */
  2626. void Dblqh::execFSWRITEREF(Signal* signal) 
  2627. {
  2628.   jamEntry();
  2629.   lfoPtr.i = signal->theData[0];
  2630.   ptrCheckGuard(lfoPtr, clfoFileSize, logFileOperationRecord);
  2631.   terrorCode = signal->theData[1];
  2632.   switch (lfoPtr.p->lfoState) {
  2633.   case LogFileOperationRecord::WRITE_PAGE_ZERO:
  2634.     jam();
  2635.     break;
  2636.   case LogFileOperationRecord::LAST_WRITE_IN_FILE:
  2637.     jam();
  2638.     break;
  2639.   case LogFileOperationRecord::INIT_WRITE_AT_END:
  2640.     jam();
  2641.     break;
  2642.   case LogFileOperationRecord::INIT_FIRST_PAGE:
  2643.     jam();
  2644.     break;
  2645.   case LogFileOperationRecord::WRITE_GCI_ZERO:
  2646.     jam();
  2647.     break;
  2648.   case LogFileOperationRecord::WRITE_DIRTY:
  2649.     jam();
  2650.     break;
  2651.   case LogFileOperationRecord::WRITE_INIT_MBYTE:
  2652.     jam();
  2653.     break;
  2654.   case LogFileOperationRecord::ACTIVE_WRITE_LOG:
  2655.     jam();
  2656.     break;
  2657.   case LogFileOperationRecord::FIRST_PAGE_WRITE_IN_LOGFILE:
  2658.     jam();
  2659.     break;
  2660.   case LogFileOperationRecord::WRITE_SR_INVALIDATE_PAGES:
  2661.     jam();
  2662.     systemErrorLab(signal);
  2663.   default:
  2664.     jam();
  2665.     break;
  2666.   }//switch
  2667.   {
  2668.     char msg[100];
  2669.     sprintf(msg, "File system write failed during LogFileOperationRecord state %d", (Uint32)lfoPtr.p->lfoState);
  2670.     fsRefError(signal,__LINE__,msg);
  2671.   }
  2672. }//Dblqh::execFSWRITEREF()
  2673. /* ========================================================================= */
  2674. /* =======              INITIATE WHEN RECEIVING FSOPENCONF           ======= */
  2675. /*                                                                           */
  2676. /* ========================================================================= */
  2677. void Dblqh::initFsopenconf(Signal* signal) 
  2678. {
  2679.   logFilePtr.i = signal->theData[0];
  2680.   ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
  2681.   logFilePtr.p->fileRef = signal->theData[1];
  2682.   logPartPtr.i = logFilePtr.p->logPartRec;
  2683.   ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
  2684.   logFilePtr.p->currentMbyte = 0;
  2685.   logFilePtr.p->filePosition = 0;
  2686.   logFilePtr.p->logFilePagesToDiskWithoutSynch = 0;
  2687. }//Dblqh::initFsopenconf()
  2688. /* ========================================================================= */
  2689. /* =======       INITIATE WHEN RECEIVING FSREADCONF AND FSWRITECONF  ======= */
  2690. /*                                                                           */
  2691. /* ========================================================================= */
  2692. void Dblqh::initFsrwconf(Signal* signal, bool write) 
  2693. {
  2694.   LogPageRecordPtr logP;
  2695.   Uint32 noPages, totPages;
  2696.   lfoPtr.i = signal->theData[0];
  2697.   ptrCheckGuard(lfoPtr, clfoFileSize, logFileOperationRecord);
  2698.   totPages= lfoPtr.p->noPagesRw;
  2699.   logFilePtr.i = lfoPtr.p->logFileRec;
  2700.   ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
  2701.   logPartPtr.i = logFilePtr.p->logPartRec;
  2702.   ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
  2703.   logPagePtr.i = lfoPtr.p->firstLfoPage;
  2704.   ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
  2705.   logP= logPagePtr;
  2706.   noPages= 1;
  2707.   ndbassert(totPages > 0);
  2708.   for (;;)
  2709.   {
  2710.     logP.p->logPageWord[ZPOS_IN_WRITING]= 0;
  2711.     logP.p->logPageWord[ZPOS_IN_FREE_LIST]= 0;
  2712.     if (noPages == totPages)
  2713.       return;
  2714.     if (write)
  2715.       logP.i= logP.p->logPageWord[ZNEXT_PAGE];
  2716.     else
  2717.       logP.i= lfoPtr.p->logPageArray[noPages];
  2718.     ptrCheckGuard(logP, clogPageFileSize, logPageRecord);
  2719.     noPages++;
  2720.   }
  2721. }//Dblqh::initFsrwconf()
  2722. /* ######################################################################### */
  2723. /*       NORMAL OPERATION MODULE                                             */
  2724. /*       THIS MODULE IS A SUB-MODULE OF THE FILE SYSTEM HANDLING.            */
  2725. /*                                                                           */
  2726. /*   THIS PART HANDLES THE NORMAL OPENING, CLOSING AND WRITING OF LOG FILES  */
  2727. /*   DURING NORMAL OPERATION.                                                */
  2728. /* ######################################################################### */
  2729. /*---------------------------------------------------------------------------*/
  2730. /* THIS SIGNAL IS USED TO SUPERVISE THAT THE LOG RECORDS ARE NOT KEPT IN MAIN*/
  2731. /* MEMORY FOR MORE THAN 1 SECOND TO ACHIEVE THE PROPER RELIABILITY.          */
  2732. /*---------------------------------------------------------------------------*/
  2733. void Dblqh::timeSup(Signal* signal) 
  2734. {
  2735.   LogPageRecordPtr origLogPagePtr;
  2736.   Uint32 wordWritten;
  2737.   jamEntry();
  2738.   logPartPtr.i = signal->theData[0];
  2739.   ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
  2740.   logFilePtr.i = logPartPtr.p->currentLogfile;
  2741.   ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
  2742.   logPagePtr.i = logFilePtr.p->currentLogpage;
  2743.   ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
  2744.   if (logPartPtr.p->logPartTimer != logPartPtr.p->logTimer) {
  2745.     jam();
  2746. /*--------------------------------------------------------------------------*/
  2747. /*       THIS LOG PART HAS NOT WRITTEN TO DISK DURING THE LAST SECOND.      */
  2748. /*--------------------------------------------------------------------------*/
  2749.     switch (logPartPtr.p->logPartState) {
  2750.     case LogPartRecord::FILE_CHANGE_PROBLEM:
  2751.       jam();
  2752. /*--------------------------------------------------------------------------*/
  2753. /*       THIS LOG PART HAS PROBLEMS IN CHANGING FILES MAKING IT IMPOSSIBLE  */
  2754. //       TO WRITE TO THE FILE CURRENTLY. WE WILL COMEBACK LATER AND SEE IF
  2755. //       THE PROBLEM HAS BEEN FIXED.
  2756. /*--------------------------------------------------------------------------*/
  2757.     case LogPartRecord::ACTIVE:
  2758.       jam();
  2759. /*---------------------------------------------------------------------------*/
  2760. /* AN OPERATION IS CURRENTLY ACTIVE IN WRITING THIS LOG PART. WE THUS CANNOT */
  2761. /* WRITE ANYTHING TO DISK AT THIS MOMENT. WE WILL SEND A SIGNAL DELAYED FOR  */
  2762. /* 10 MS AND THEN TRY AGAIN. POSSIBLY THE LOG PART WILL HAVE BEEN WRITTEN    */
  2763. /* UNTIL THEN OR ELSE IT SHOULD BE FREE TO WRITE AGAIN.                      */
  2764. /*---------------------------------------------------------------------------*/
  2765.       signal->theData[0] = ZTIME_SUPERVISION;
  2766.       signal->theData[1] = logPartPtr.i;
  2767.       sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 10, 2);
  2768.       return;
  2769.       break;
  2770.     case LogPartRecord::IDLE:
  2771.     case LogPartRecord::TAIL_PROBLEM:
  2772.       jam();
  2773. /*---------------------------------------------------------------------------*/
  2774. /* IDLE AND NOT WRITTEN TO DISK IN A SECOND. ALSO WHEN WE HAVE A TAIL PROBLEM*/
  2775. /* WE HAVE TO WRITE TO DISK AT TIMES. WE WILL FIRST CHECK WHETHER ANYTHING   */
  2776. /* AT ALL HAVE BEEN WRITTEN TO THE PAGES BEFORE WRITING TO DISK.             */
  2777. /*---------------------------------------------------------------------------*/
  2778. /* WE HAVE TO WRITE TO DISK IN ALL CASES SINCE THERE COULD BE INFORMATION    */
  2779. /* STILL IN THE LOG THAT WAS GENERATED BEFORE THE PREVIOUS TIME SUPERVISION  */
  2780. /* BUT AFTER THE LAST DISK WRITE. THIS PREVIOUSLY STOPPED ALL DISK WRITES    */
  2781. /* WHEN NO MORE LOG WRITES WERE PERFORMED (THIS HAPPENED WHEN LOG GOT FULL   */
  2782. /* AND AFTER LOADING THE INITIAL RECORDS IN INITIAL START).                  */
  2783. /*---------------------------------------------------------------------------*/
  2784.       if (((logFilePtr.p->currentFilepage + 1) & (ZPAGES_IN_MBYTE -1)) == 0) {
  2785.         jam();
  2786. /*---------------------------------------------------------------------------*/
  2787. /* THIS IS THE LAST PAGE IN THIS MBYTE. WRITE NEXT LOG AND SWITCH TO NEXT    */
  2788. /* MBYTE.                                                                    */
  2789. /*---------------------------------------------------------------------------*/
  2790.         changeMbyte(signal);
  2791.       } else {
  2792. /*---------------------------------------------------------------------------*/
  2793. /* WRITE THE LOG PAGE TO DISK EVEN IF IT IS NOT FULL. KEEP PAGE AND WRITE A  */
  2794. /* COPY. THE ORIGINAL PAGE WILL BE WRITTEN AGAIN LATER ON.                   */
  2795. /*---------------------------------------------------------------------------*/
  2796.         wordWritten = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] - 1;
  2797.         origLogPagePtr.i = logPagePtr.i;
  2798.         origLogPagePtr.p = logPagePtr.p;
  2799.         seizeLogpage(signal);
  2800.         MEMCOPY_NO_WORDS(&logPagePtr.p->logPageWord[0],
  2801.                          &origLogPagePtr.p->logPageWord[0],
  2802.                          wordWritten + 1);
  2803.         ndbrequire(wordWritten < ZPAGE_SIZE);
  2804.         if (logFilePtr.p->noLogpagesInBuffer > 0) {
  2805.           jam();
  2806.           completedLogPage(signal, ZENFORCE_WRITE, __LINE__);
  2807. /*---------------------------------------------------------------------------*/
  2808. /*SINCE WE ARE ONLY WRITING PART OF THE LAST PAGE WE HAVE TO UPDATE THE WORD */
  2809. /*WRITTEN TO REFLECT THE REAL LAST WORD WRITTEN. WE ALSO HAVE TO MOVE THE    */
  2810. /*FILE POSITION ONE STEP BACKWARDS SINCE WE ARE NOT WRITING THE LAST PAGE    */
  2811. /*COMPLETELY. IT WILL BE WRITTEN AGAIN.                                      */
  2812. /*---------------------------------------------------------------------------*/
  2813.           lfoPtr.p->lfoWordWritten = wordWritten;
  2814.           logFilePtr.p->filePosition = logFilePtr.p->filePosition - 1;
  2815.         } else {
  2816.           if (wordWritten == (ZPAGE_HEADER_SIZE - 1)) {
  2817. /*---------------------------------------------------------------------------*/
  2818. /*THIS IS POSSIBLE BUT VERY UNLIKELY. IF THE PAGE WAS COMPLETED AFTER THE LAST*/
  2819. /*WRITE TO DISK THEN NO_LOG_PAGES_IN_BUFFER > 0 AND IF NOT WRITTEN SINCE LAST*/
  2820. /*WRITE TO DISK THEN THE PREVIOUS PAGE MUST HAVE BEEN WRITTEN BY SOME        */
  2821. /*OPERATION AND THAT BECAME COMPLETELY FULL. IN ANY CASE WE NEED NOT WRITE AN*/
  2822. /*EMPTY PAGE TO DISK.                                                        */
  2823. /*---------------------------------------------------------------------------*/
  2824.             jam();
  2825.             releaseLogpage(signal);
  2826.           } else {
  2827.             jam();
  2828.             writeSinglePage(signal, logFilePtr.p->currentFilepage,
  2829.                             wordWritten, __LINE__);
  2830.             lfoPtr.p->lfoState = LogFileOperationRecord::ACTIVE_WRITE_LOG;
  2831.           }//if
  2832.         }//if
  2833.       }//if
  2834.       break;
  2835.     default:
  2836.       ndbrequire(false);
  2837.       break;
  2838.     }//switch
  2839.   }//if
  2840.   logPartPtr.p->logTimer++;
  2841.   return;
  2842. }//Dblqh::timeSup()
  2843. void Dblqh::writeLogfileLab(Signal* signal) 
  2844. {
  2845. /*---------------------------------------------------------------------------*/
  2846. /* CHECK IF ANY GLOBAL CHECKPOINTS ARE COMPLETED DUE TO THIS COMPLETED DISK  */
  2847. /* WRITE.                                                                    */
  2848. /*---------------------------------------------------------------------------*/
  2849.   switch (logFilePtr.p->fileChangeState) {
  2850.   case LogFileRecord::NOT_ONGOING:
  2851.     jam();
  2852.     checkGcpCompleted(signal,
  2853.                       ((lfoPtr.p->lfoPageNo + lfoPtr.p->noPagesRw) - 1),
  2854.                       lfoPtr.p->lfoWordWritten);
  2855.     break;
  2856. #if 0
  2857.   case LogFileRecord::BOTH_WRITES_ONGOING:
  2858.     jam();
  2859.     ndbout_c("not crashing!!");
  2860.     // Fall-through
  2861. #endif
  2862.   case LogFileRecord::WRITE_PAGE_ZERO_ONGOING:
  2863.   case LogFileRecord::LAST_WRITE_ONGOING:
  2864.     jam();
  2865.     logFilePtr.p->lastPageWritten = (lfoPtr.p->lfoPageNo + lfoPtr.p->noPagesRw) - 1;
  2866.     logFilePtr.p->lastWordWritten = lfoPtr.p->lfoWordWritten;
  2867.     break;
  2868.   default:
  2869.     jam();
  2870.     systemErrorLab(signal);
  2871.     return;
  2872.     break;
  2873.   }//switch
  2874.   releaseLfoPages(signal);
  2875.   releaseLfo(signal);
  2876.   return;
  2877. }//Dblqh::writeLogfileLab()
  2878. void Dblqh::closeWriteLogLab(Signal* signal) 
  2879. {
  2880.   logFilePtr.p->logFileStatus = LogFileRecord::CLOSED;
  2881.   return;
  2882. }//Dblqh::closeWriteLogLab()
  2883. /* ######################################################################### */
  2884. /*       FILE CHANGE MODULE                                                  */
  2885. /*       THIS MODULE IS A SUB-MODULE OF THE FILE SYSTEM HANDLING.            */
  2886. /*                                                                           */
  2887. /*THIS PART OF THE FILE MODULE HANDLES WHEN WE ARE CHANGING LOG FILE DURING  */
  2888. /*NORMAL OPERATION. WE HAVE TO BE CAREFUL WHEN WE ARE CHANGING LOG FILE SO   */
  2889. /*THAT WE DO NOT COMPLICATE THE SYSTEM RESTART PROCESS TOO MUCH.             */
  2890. /*THE IDEA IS THAT WE START BY WRITING THE LAST WRITE IN THE OLD FILE AND WE */
  2891. /*ALSO WRITE THE FIRST PAGE OF THE NEW FILE CONCURRENT WITH THAT. THIS FIRST */
  2892. /*PAGE IN THE NEW FILE DO NOT CONTAIN ANY LOG RECORDS OTHER THAN A DESCRIPTOR*/
  2893. /*CONTAINING INFORMATION ABOUT GCI'S NEEDED AT SYSTEM RESTART AND A NEXT LOG */
  2894. /*RECORD.                                                                    */
  2895. /*                                                                           */
  2896. /*WHEN BOTH OF THOSE WRITES HAVE COMPLETED WE ALSO WRITE PAGE ZERO IN FILE   */
  2897. /*ZERO. THE ONLY INFORMATION WHICH IS INTERESTING HERE IS THE NEW FILE NUMBER*/
  2898. /*                                                                           */
  2899. /*IF OPTIMISATIONS ARE NEEDED OF THE LOG HANDLING THEN IT IS POSSIBLE TO     */
  2900. /*AVOID WRITING THE FIRST PAGE OF THE NEW PAGE IMMEDIATELY. THIS COMPLICATES */
  2901. /*THE SYSTEM RESTART AND ONE HAS TO TAKE SPECIAL CARE WITH FILE ZERO. IT IS  */
  2902. /*HOWEVER NO LARGE PROBLEM TO CHANGE INTO THIS SCENARIO. TO AVOID ALSO THE   */
  2903. /*WRITING OF PAGE ZERO IS ALSO POSSIBLE BUT COMPLICATES THE DESIGN EVEN      */
  2904. /*FURTHER. IT GETS FAIRLY COMPLEX TO FIND THE END OF THE LOG. SOME SORT OF   */
  2905. /*BINARY SEARCH IS HOWEVER MOST LIKELY A GOOD METHODOLOGY FOR THIS.          */
  2906. /* ######################################################################### */
  2907. void Dblqh::firstPageWriteLab(Signal* signal) 
  2908. {
  2909.   releaseLfo(signal);
  2910. /*---------------------------------------------------------------------------*/
  2911. /*       RELEASE PAGE ZERO IF THE FILE IS NOT FILE 0.                        */
  2912. /*---------------------------------------------------------------------------*/
  2913.   Uint32 fileNo = logFilePtr.p->fileNo;
  2914.   if (fileNo != 0) {
  2915.     jam();
  2916.     releaseLogpage(signal);
  2917.   }//if
  2918. /*---------------------------------------------------------------------------*/
  2919. /* IF A NEW FILE HAS BEEN OPENED WE SHALL ALWAYS ALSO WRITE TO PAGE O IN     */
  2920. /* FILE 0. THE AIM IS TO MAKE RESTARTS EASIER BY SPECIFYING WHICH IS THE     */
  2921. /* LAST FILE WHERE LOGGING HAS STARTED.                                      */
  2922. /*---------------------------------------------------------------------------*/
  2923. /* FIRST CHECK WHETHER THE LAST WRITE IN THE PREVIOUS FILE HAVE COMPLETED    */
  2924. /*---------------------------------------------------------------------------*/
  2925.   if (logFilePtr.p->fileChangeState == LogFileRecord::BOTH_WRITES_ONGOING) {
  2926.     jam();
  2927. /*---------------------------------------------------------------------------*/
  2928. /* THE LAST WRITE WAS STILL ONGOING.                                         */
  2929. /*---------------------------------------------------------------------------*/
  2930.     logFilePtr.p->fileChangeState = LogFileRecord::LAST_WRITE_ONGOING;
  2931.     return;
  2932.   } else {
  2933.     jam();
  2934.     ndbrequire(logFilePtr.p->fileChangeState == LogFileRecord::FIRST_WRITE_ONGOING);
  2935. /*---------------------------------------------------------------------------*/
  2936. /* WRITE TO PAGE 0 IN IN FILE 0 NOW.                                         */
  2937. /*---------------------------------------------------------------------------*/
  2938.     logFilePtr.p->fileChangeState = LogFileRecord::WRITE_PAGE_ZERO_ONGOING;
  2939.     if (fileNo == 0) {
  2940.       jam();
  2941. /*---------------------------------------------------------------------------*/
  2942. /* IF THE NEW FILE WAS 0 THEN WE HAVE ALREADY WRITTEN PAGE ZERO IN FILE 0.   */
  2943. /*---------------------------------------------------------------------------*/
  2944.       logFilePtr.p->fileChangeState = LogFileRecord::NOT_ONGOING;
  2945.       return;
  2946.     } else {
  2947.       jam();
  2948. /*---------------------------------------------------------------------------*/