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

MySQL数据库

开发平台:

Visual C++

  1. /* WRITE PAGE ZERO IN FILE ZERO. LOG_FILE_REC WILL REFER TO THE LOG FILE WE  */
  2. /* HAVE JUST WRITTEN PAGE ZERO IN TO GET HOLD OF LOG_FILE_PTR FOR THIS       */
  3. /* RECORD QUICKLY. THIS IS NEEDED TO GET HOLD OF THE FILE_CHANGE_STATE.      */
  4. /* THE ONLY INFORMATION WE WANT TO CHANGE IS THE LAST FILE NUMBER IN THE     */
  5. /* FILE DESCRIPTOR. THIS IS USED AT SYSTEM RESTART TO FIND THE END OF THE    */
  6. /* LOG PART.                                                                 */
  7. /*---------------------------------------------------------------------------*/
  8.       Uint32 currLogFile = logFilePtr.i;
  9.       logFilePtr.i = logPartPtr.p->firstLogfile;
  10.       ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
  11.       logPagePtr.i = logFilePtr.p->logPageZero;
  12.       ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
  13.       logPagePtr.p->logPageWord[ZPAGE_HEADER_SIZE + ZPOS_FILE_NO] = fileNo;
  14.       writeSinglePage(signal, 0, ZPAGE_SIZE - 1, __LINE__);
  15.       lfoPtr.p->logFileRec = currLogFile;
  16.       lfoPtr.p->lfoState = LogFileOperationRecord::WRITE_PAGE_ZERO;
  17.       return;
  18.     }//if
  19.   }//if
  20. }//Dblqh::firstPageWriteLab()
  21. void Dblqh::lastWriteInFileLab(Signal* signal) 
  22. {
  23.   LogFileRecordPtr locLogFilePtr;
  24. /*---------------------------------------------------------------------------*/
  25. /* CHECK IF ANY GLOBAL CHECKPOINTS ARE COMPLETED DUE TO THIS COMPLETED DISK  */
  26. /* WRITE.                                                                    */
  27. /*---------------------------------------------------------------------------*/
  28.   checkGcpCompleted(signal,
  29.                     ((lfoPtr.p->lfoPageNo + lfoPtr.p->noPagesRw) - 1),
  30.                     (ZPAGE_SIZE - 1));
  31.   releaseLfoPages(signal);
  32.   releaseLfo(signal);
  33. /*---------------------------------------------------------------------------*/
  34. /* IF THE FILE IS NOT IN USE OR THE NEXT FILE TO BE USED WE WILL CLOSE IT.   */
  35. /*---------------------------------------------------------------------------*/
  36.   locLogFilePtr.i = logPartPtr.p->currentLogfile;
  37.   ptrCheckGuard(locLogFilePtr, clogFileFileSize, logFileRecord);
  38.   if (logFilePtr.i != locLogFilePtr.i) {
  39.     if (logFilePtr.i != locLogFilePtr.p->nextLogFile) {
  40.       if (logFilePtr.p->fileNo != 0) {
  41.         jam();
  42. /*---------------------------------------------------------------------------*/
  43. /* THE FILE IS NOT FILE ZERO EITHER. WE WILL NOT CLOSE FILE ZERO SINCE WE    */
  44. /* USE IT TO KEEP TRACK OF THE CURRENT LOG FILE BY WRITING PAGE ZERO IN      */
  45. /* FILE ZERO.                                                                */
  46. /*---------------------------------------------------------------------------*/
  47. /* WE WILL CLOSE THE FILE.                                                   */
  48. /*---------------------------------------------------------------------------*/
  49.         logFilePtr.p->logFileStatus = LogFileRecord::CLOSING_WRITE_LOG;
  50.         closeFile(signal, logFilePtr);
  51.       }//if
  52.     }//if
  53.   }//if
  54. /*---------------------------------------------------------------------------*/
  55. /* IF A NEW FILE HAS BEEN OPENED WE SHALL ALWAYS ALSO WRITE TO PAGE O IN     */
  56. /* FILE 0. THE AIM IS TO MAKE RESTARTS EASIER BY SPECIFYING WHICH IS THE     */
  57. /* LAST FILE WHERE LOGGING HAS STARTED.                                      */
  58. /*---------------------------------------------------------------------------*/
  59. /* FIRST CHECK WHETHER THE FIRST WRITE IN THE NEW FILE HAVE COMPLETED        */
  60. /* THIS STATE INFORMATION IS IN THE NEW LOG FILE AND THUS WE HAVE TO MOVE    */
  61. /* THE LOG FILE POINTER TO THIS LOG FILE.                                    */
  62. /*---------------------------------------------------------------------------*/
  63.   logFilePtr.i = logFilePtr.p->nextLogFile;
  64.   ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
  65.   if (logFilePtr.p->fileChangeState == LogFileRecord::BOTH_WRITES_ONGOING) {
  66.     jam();
  67. /*---------------------------------------------------------------------------*/
  68. /* THE FIRST WRITE WAS STILL ONGOING.                                        */
  69. /*---------------------------------------------------------------------------*/
  70.     logFilePtr.p->fileChangeState = LogFileRecord::FIRST_WRITE_ONGOING;
  71.     return;
  72.   } else {
  73.     ndbrequire(logFilePtr.p->fileChangeState == LogFileRecord::LAST_WRITE_ONGOING);
  74. /*---------------------------------------------------------------------------*/
  75. /* WRITE TO PAGE 0 IN IN FILE 0 NOW.                                         */
  76. /*---------------------------------------------------------------------------*/
  77.     logFilePtr.p->fileChangeState = LogFileRecord::WRITE_PAGE_ZERO_ONGOING;
  78.     Uint32 fileNo = logFilePtr.p->fileNo;
  79.     if (fileNo == 0) {
  80.       jam();
  81. /*---------------------------------------------------------------------------*/
  82. /* IF THE NEW FILE WAS 0 THEN WE HAVE ALREADY WRITTEN PAGE ZERO IN FILE 0.   */
  83. /*---------------------------------------------------------------------------*/
  84.       logFilePtr.p->fileChangeState = LogFileRecord::NOT_ONGOING;
  85.       return;
  86.     } else {
  87.       jam();
  88. /*---------------------------------------------------------------------------*/
  89. /* WRITE PAGE ZERO IN FILE ZERO. LOG_FILE_REC WILL REFER TO THE LOG FILE WE  */
  90. /* HAVE JUST WRITTEN PAGE ZERO IN TO GET HOLD OF LOG_FILE_PTR FOR THIS       */
  91. /* RECORD QUICKLY. THIS IS NEEDED TO GET HOLD OF THE FILE_CHANGE_STATE.      */
  92. /* THE ONLY INFORMATION WE WANT TO CHANGE IS THE LAST FILE NUMBER IN THE     */
  93. /* FILE DESCRIPTOR. THIS IS USED AT SYSTEM RESTART TO FIND THE END OF THE    */
  94. /* LOG PART.                                                                 */
  95. /*---------------------------------------------------------------------------*/
  96.       Uint32 currLogFile = logFilePtr.i;
  97.       logFilePtr.i = logPartPtr.p->firstLogfile;
  98.       ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
  99.       logPagePtr.i = logFilePtr.p->logPageZero;
  100.       ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
  101.       logPagePtr.p->logPageWord[ZPAGE_HEADER_SIZE + ZPOS_FILE_NO] = fileNo;
  102.       writeSinglePage(signal, 0, ZPAGE_SIZE - 1, __LINE__);
  103.       lfoPtr.p->logFileRec = currLogFile;
  104.       lfoPtr.p->lfoState = LogFileOperationRecord::WRITE_PAGE_ZERO;
  105.       return;
  106.     }//if
  107.   }//if
  108. }//Dblqh::lastWriteInFileLab()
  109. void Dblqh::writePageZeroLab(Signal* signal) 
  110. {
  111.   logFilePtr.p->fileChangeState = LogFileRecord::NOT_ONGOING;
  112. /*---------------------------------------------------------------------------*/
  113. /* IT COULD HAVE ARRIVED PAGE WRITES TO THE CURRENT FILE WHILE WE WERE       */
  114. /* WAITING FOR THIS DISK WRITE TO COMPLETE. THEY COULD NOT CHECK FOR         */
  115. /* COMPLETED GLOBAL CHECKPOINTS. THUS WE SHOULD DO THAT NOW INSTEAD.         */
  116. /*---------------------------------------------------------------------------*/
  117.   checkGcpCompleted(signal,
  118.                     logFilePtr.p->lastPageWritten,
  119.                     logFilePtr.p->lastWordWritten);
  120.   releaseLfo(signal);
  121.   return;
  122. }//Dblqh::writePageZeroLab()
  123. /* ######################################################################### */
  124. /*       INITIAL START MODULE                                                */
  125. /*       THIS MODULE IS A SUB-MODULE OF THE FILE SYSTEM HANDLING.            */
  126. /*                                                                           */
  127. /*THIS MODULE INITIALISES ALL THE LOG FILES THAT ARE NEEDED AT A SYSTEM      */
  128. /*RESTART AND WHICH ARE USED DURING NORMAL OPERATIONS. IT CREATES THE FILES  */
  129. /*AND SETS A PROPER SIZE OF THEM AND INITIALISES THE FIRST PAGE IN EACH FILE */
  130. /* ######################################################################### */
  131. void Dblqh::openFileInitLab(Signal* signal) 
  132. {
  133.   logFilePtr.p->logFileStatus = LogFileRecord::OPEN_INIT;
  134.   seizeLogpage(signal);
  135.   writeSinglePage(signal, (ZNO_MBYTES_IN_FILE * ZPAGES_IN_MBYTE) - 1,
  136.                   ZPAGE_SIZE - 1, __LINE__);
  137.   lfoPtr.p->lfoState = LogFileOperationRecord::INIT_WRITE_AT_END;
  138.   return;
  139. }//Dblqh::openFileInitLab()
  140. void Dblqh::initWriteEndLab(Signal* signal) 
  141. {
  142.   releaseLfo(signal);
  143.   initLogpage(signal);
  144.   if (logFilePtr.p->fileNo == 0) {
  145.     jam();
  146. /*---------------------------------------------------------------------------*/
  147. /* PAGE ZERO IN FILE ZERO MUST SET LOG LAP TO ONE SINCE IT HAS STARTED       */
  148. /* WRITING TO THE LOG, ALSO GLOBAL CHECKPOINTS ARE SET TO ZERO.              */
  149. /*---------------------------------------------------------------------------*/
  150.     logPagePtr.p->logPageWord[ZPOS_LOG_LAP] = 1;
  151.     logPagePtr.p->logPageWord[ZPOS_MAX_GCI_STARTED] = 0;
  152.     logPagePtr.p->logPageWord[ZPOS_MAX_GCI_COMPLETED] = 0;
  153.     logFilePtr.p->logMaxGciStarted[0] = 0;
  154.     logFilePtr.p->logMaxGciCompleted[0] = 0;
  155.   }//if
  156. /*---------------------------------------------------------------------------*/
  157. /* REUSE CODE FOR INITIALISATION OF FIRST PAGE IN ALL LOG FILES.             */
  158. /*---------------------------------------------------------------------------*/
  159.   writeFileHeaderOpen(signal, ZINIT);
  160.   return;
  161. }//Dblqh::initWriteEndLab()
  162. void Dblqh::initFirstPageLab(Signal* signal) 
  163. {
  164.   releaseLfo(signal);
  165.   if (logFilePtr.p->fileNo == 0) {
  166.     jam();
  167. /*---------------------------------------------------------------------------*/
  168. /* IN FILE ZERO WE WILL INSERT A PAGE ONE WHERE WE WILL INSERT A COMPLETED   */
  169. /* GCI RECORD FOR GCI = 0.                                                   */
  170. /*---------------------------------------------------------------------------*/
  171.     initLogpage(signal);
  172.     logPagePtr.p->logPageWord[ZPOS_LOG_LAP] = 1;
  173.     logPagePtr.p->logPageWord[ZPAGE_HEADER_SIZE] = ZCOMPLETED_GCI_TYPE;
  174.     logPagePtr.p->logPageWord[ZPAGE_HEADER_SIZE + 1] = 1;
  175.     writeSinglePage(signal, 1, ZPAGE_SIZE - 1, __LINE__);
  176.     lfoPtr.p->lfoState = LogFileOperationRecord::WRITE_GCI_ZERO;
  177.     return;
  178.   }//if
  179.   logFilePtr.p->currentMbyte = 1;
  180.   writeInitMbyte(signal);
  181.   return;
  182. }//Dblqh::initFirstPageLab()
  183. void Dblqh::writeGciZeroLab(Signal* signal) 
  184. {
  185.   releaseLfo(signal);
  186.   logFilePtr.p->currentMbyte = 1;
  187.   writeInitMbyte(signal);
  188.   return;
  189. }//Dblqh::writeGciZeroLab()
  190. void Dblqh::writeInitMbyteLab(Signal* signal) 
  191. {
  192.   releaseLfo(signal);
  193.   logFilePtr.p->currentMbyte = logFilePtr.p->currentMbyte + 1;
  194.   if (logFilePtr.p->currentMbyte == ZNO_MBYTES_IN_FILE) {
  195.     jam();
  196.     releaseLogpage(signal);
  197.     logFilePtr.p->logFileStatus = LogFileRecord::CLOSING_INIT;
  198.     closeFile(signal, logFilePtr);
  199.     return;
  200.   }//if
  201.   writeInitMbyte(signal);
  202.   return;
  203. }//Dblqh::writeInitMbyteLab()
  204. void Dblqh::closingInitLab(Signal* signal) 
  205. {
  206.   logFilePtr.p->logFileStatus = LogFileRecord::CLOSED;
  207.   logPartPtr.i = logFilePtr.p->logPartRec;
  208.   ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
  209.   if (logFilePtr.p->nextLogFile == logPartPtr.p->firstLogfile) {
  210.     jam();
  211.     checkInitCompletedLab(signal);
  212.     return;
  213.   } else {
  214.     jam();
  215.     logFilePtr.i = logFilePtr.p->nextLogFile;
  216.     ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
  217.     openLogfileInit(signal);
  218.   }//if
  219.   return;
  220. }//Dblqh::closingInitLab()
  221. void Dblqh::checkInitCompletedLab(Signal* signal) 
  222. {
  223.   logPartPtr.p->logPartState = LogPartRecord::SR_FIRST_PHASE_COMPLETED;
  224. /*---------------------------------------------------------------------------*/
  225. /* WE HAVE NOW INITIALISED ALL FILES IN THIS LOG PART. WE CAN NOW SET THE    */
  226. /* THE LOG LAP TO ONE SINCE WE WILL START WITH LOG LAP ONE. LOG LAP = ZERO   */
  227. /* MEANS THIS PART OF THE LOG IS NOT WRITTEN YET.                            */
  228. /*---------------------------------------------------------------------------*/
  229.   logPartPtr.p->logLap = 1;
  230.   logPartPtr.i = 0;
  231. CHECK_LOG_PARTS_LOOP:
  232.   ptrAss(logPartPtr, logPartRecord);
  233.   if (logPartPtr.p->logPartState != LogPartRecord::SR_FIRST_PHASE_COMPLETED) {
  234.     jam();
  235. /*---------------------------------------------------------------------------*/
  236. /* THIS PART HAS STILL NOT COMPLETED. WAIT FOR THIS TO OCCUR.                */
  237. /*---------------------------------------------------------------------------*/
  238.     return;
  239.   }//if
  240.   if (logPartPtr.i == 3) {
  241.     jam();
  242. /*---------------------------------------------------------------------------*/
  243. /* ALL LOG PARTS ARE COMPLETED. NOW WE CAN CONTINUE WITH THE RESTART         */
  244. /* PROCESSING. THE NEXT STEP IS TO PREPARE FOR EXECUTING OPERATIONS. THUS WE */
  245. /* NEED TO INITIALISE ALL NEEDED DATA AND TO OPEN FILE ZERO AND THE NEXT AND */
  246. /* TO SET THE CURRENT LOG PAGE TO BE PAGE 1 IN FILE ZERO.                    */
  247. /*---------------------------------------------------------------------------*/
  248.     for (logPartPtr.i = 0; logPartPtr.i <= 3; logPartPtr.i++) {
  249.       ptrAss(logPartPtr, logPartRecord);
  250.       signal->theData[0] = ZINIT_FOURTH;
  251.       signal->theData[1] = logPartPtr.i;
  252.       sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
  253.     }//for
  254.     return;
  255.   } else {
  256.     jam();
  257.     logPartPtr.i = logPartPtr.i + 1;
  258.     goto CHECK_LOG_PARTS_LOOP;
  259.   }//if
  260. }//Dblqh::checkInitCompletedLab()
  261. /* ========================================================================= */
  262. /* =======       INITIATE LOG FILE OPERATION RECORD WHEN ALLOCATED   ======= */
  263. /*                                                                           */
  264. /* ========================================================================= */
  265. void Dblqh::initLfo(Signal* signal) 
  266. {
  267.   lfoPtr.p->firstLfoPage = RNIL;
  268.   lfoPtr.p->lfoState = LogFileOperationRecord::IDLE;
  269.   lfoPtr.p->logFileRec = logFilePtr.i;
  270.   lfoPtr.p->noPagesRw = 0;
  271.   lfoPtr.p->lfoPageNo = ZNIL;
  272. }//Dblqh::initLfo()
  273. /* ========================================================================= */
  274. /* =======              INITIATE LOG FILE WHEN ALLOCATED             ======= */
  275. /*                                                                           */
  276. /*       INPUT:  TFILE_NO        NUMBER OF THE FILE INITIATED                */
  277. /*               LOG_PART_PTR    NUMBER OF LOG PART                          */
  278. /*       SUBROUTINE SHORT NAME = IL                                          */
  279. /* ========================================================================= */
  280. void Dblqh::initLogfile(Signal* signal, Uint32 fileNo) 
  281. {
  282.   UintR tilTmp;
  283.   UintR tilIndex;
  284.   logFilePtr.p->currentFilepage = 0;
  285.   logFilePtr.p->currentLogpage = RNIL;
  286.   logFilePtr.p->fileName[0] = (UintR)-1;
  287.   logFilePtr.p->fileName[1] = (UintR)-1; /* = H'FFFFFFFF = -1 */
  288.   logFilePtr.p->fileName[2] = fileNo;         /* Sfile_no */
  289.   tilTmp = 1;                         /* VERSION 1 OF FILE NAME */
  290.   tilTmp = (tilTmp << 8) + 1;     /* FRAGMENT LOG => .FRAGLOG AS EXTENSION */
  291.   tilTmp = (tilTmp << 8) + (8 + logPartPtr.i); /* DIRECTORY = D(8+Part)/DBLQH */
  292.   tilTmp = (tilTmp << 8) + 255;               /* IGNORE Pxx PART OF FILE NAME */
  293.   logFilePtr.p->fileName[3] = tilTmp;
  294. /* ========================================================================= */
  295. /*       FILE NAME BECOMES /D2/DBLQH/Tpart_no/Sfile_no.FRAGLOG               */
  296. /* ========================================================================= */
  297.   logFilePtr.p->fileNo = fileNo;
  298.   logFilePtr.p->filePosition = 0;
  299.   logFilePtr.p->firstLfo = RNIL;
  300.   logFilePtr.p->lastLfo = RNIL;
  301.   logFilePtr.p->logFileStatus = LogFileRecord::CLOSED;
  302.   logFilePtr.p->logPartRec = logPartPtr.i;
  303.   logFilePtr.p->noLogpagesInBuffer = 0;
  304.   logFilePtr.p->firstFilledPage = RNIL;
  305.   logFilePtr.p->lastFilledPage = RNIL;
  306.   logFilePtr.p->lastPageWritten = 0;
  307.   logFilePtr.p->logPageZero = RNIL;
  308.   logFilePtr.p->currentMbyte = 0;
  309.   for (tilIndex = 0; tilIndex <= 15; tilIndex++) {
  310.     logFilePtr.p->logMaxGciCompleted[tilIndex] = (UintR)-1;
  311.     logFilePtr.p->logMaxGciStarted[tilIndex] = (UintR)-1;
  312.     logFilePtr.p->logLastPrepRef[tilIndex] = 0;
  313.   }//for
  314. }//Dblqh::initLogfile()
  315. /* ========================================================================= */
  316. /* =======              INITIATE LOG PAGE WHEN ALLOCATED             ======= */
  317. /*                                                                           */
  318. /* ========================================================================= */
  319. void Dblqh::initLogpage(Signal* signal) 
  320. {
  321.   TcConnectionrecPtr ilpTcConnectptr;
  322.   logPagePtr.p->logPageWord[ZPOS_LOG_LAP] = logPartPtr.p->logLap;
  323.   logPagePtr.p->logPageWord[ZPOS_MAX_GCI_COMPLETED] = 
  324.         logPartPtr.p->logPartNewestCompletedGCI;
  325.   logPagePtr.p->logPageWord[ZPOS_MAX_GCI_STARTED] = cnewestGci;
  326.   logPagePtr.p->logPageWord[ZPOS_VERSION] = NDB_VERSION;
  327.   logPagePtr.p->logPageWord[ZPOS_NO_LOG_FILES] = logPartPtr.p->noLogFiles;
  328.   logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = ZPAGE_HEADER_SIZE;
  329.   ilpTcConnectptr.i = logPartPtr.p->firstLogTcrec;
  330.   if (ilpTcConnectptr.i != RNIL) {
  331.     jam();
  332.     ptrCheckGuard(ilpTcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
  333.     logPagePtr.p->logPageWord[ZLAST_LOG_PREP_REF] = 
  334.       (ilpTcConnectptr.p->logStartFileNo << 16) +
  335.       (ilpTcConnectptr.p->logStartPageNo >> ZTWOLOG_NO_PAGES_IN_MBYTE);
  336.   } else {
  337.     jam();
  338.     logPagePtr.p->logPageWord[ZLAST_LOG_PREP_REF] = 
  339.       (logFilePtr.p->fileNo << 16) + 
  340.       (logFilePtr.p->currentFilepage >> ZTWOLOG_NO_PAGES_IN_MBYTE);
  341.   }//if
  342. }//Dblqh::initLogpage()
  343. /* ------------------------------------------------------------------------- */
  344. /* -------               OPEN LOG FILE FOR READ AND WRITE            ------- */
  345. /*                                                                           */
  346. /*       SUBROUTINE SHORT NAME = OFR                                         */
  347. /* ------------------------------------------------------------------------- */
  348. void Dblqh::openFileRw(Signal* signal, LogFileRecordPtr olfLogFilePtr) 
  349. {
  350.   signal->theData[0] = cownref;
  351.   signal->theData[1] = olfLogFilePtr.i;
  352.   signal->theData[2] = olfLogFilePtr.p->fileName[0];
  353.   signal->theData[3] = olfLogFilePtr.p->fileName[1];
  354.   signal->theData[4] = olfLogFilePtr.p->fileName[2];
  355.   signal->theData[5] = olfLogFilePtr.p->fileName[3];
  356.   signal->theData[6] = ZOPEN_READ_WRITE;
  357.   sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, 7, JBA);
  358. }//Dblqh::openFileRw()
  359. /* ------------------------------------------------------------------------- */
  360. /* -------               OPEN LOG FILE DURING INITIAL START          ------- */
  361. /*                                                                           */
  362. /*       SUBROUTINE SHORT NAME = OLI                                         */
  363. /* ------------------------------------------------------------------------- */
  364. void Dblqh::openLogfileInit(Signal* signal) 
  365. {
  366.   logFilePtr.p->logFileStatus = LogFileRecord::OPENING_INIT;
  367.   signal->theData[0] = cownref;
  368.   signal->theData[1] = logFilePtr.i;
  369.   signal->theData[2] = logFilePtr.p->fileName[0];
  370.   signal->theData[3] = logFilePtr.p->fileName[1];
  371.   signal->theData[4] = logFilePtr.p->fileName[2];
  372.   signal->theData[5] = logFilePtr.p->fileName[3];
  373.   signal->theData[6] = 0x302;
  374.   sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, 7, JBA);
  375. }//Dblqh::openLogfileInit()
  376. /* OPEN FOR READ/WRITE, DO CREATE AND DO TRUNCATE FILE */
  377. /* ------------------------------------------------------------------------- */
  378. /* -------               OPEN NEXT LOG FILE                          ------- */
  379. /*                                                                           */
  380. /*       SUBROUTINE SHORT NAME = ONL                                         */
  381. /* ------------------------------------------------------------------------- */
  382. void Dblqh::openNextLogfile(Signal* signal) 
  383. {
  384.   LogFileRecordPtr onlLogFilePtr;
  385.   if (logPartPtr.p->noLogFiles > 2) {
  386.     jam();
  387. /* -------------------------------------------------- */
  388. /*       IF ONLY 1 OR 2 LOG FILES EXIST THEN THEY ARE */
  389. /*       ALWAYS OPEN AND THUS IT IS NOT NECESSARY TO  */
  390. /*       OPEN THEM NOW.                               */
  391. /* -------------------------------------------------- */
  392.     onlLogFilePtr.i = logFilePtr.p->nextLogFile;
  393.     ptrCheckGuard(onlLogFilePtr, clogFileFileSize, logFileRecord);
  394.     if (onlLogFilePtr.p->logFileStatus != LogFileRecord::CLOSED) {
  395.       ndbrequire(onlLogFilePtr.p->fileNo == 0);
  396.       return;
  397.     }//if
  398.     onlLogFilePtr.p->logFileStatus = LogFileRecord::OPENING_WRITE_LOG;
  399.     signal->theData[0] = cownref;
  400.     signal->theData[1] = onlLogFilePtr.i;
  401.     signal->theData[2] = onlLogFilePtr.p->fileName[0];
  402.     signal->theData[3] = onlLogFilePtr.p->fileName[1];
  403.     signal->theData[4] = onlLogFilePtr.p->fileName[2];
  404.     signal->theData[5] = onlLogFilePtr.p->fileName[3];
  405.     signal->theData[6] = 2;
  406.     sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, 7, JBA);
  407.   }//if
  408. }//Dblqh::openNextLogfile()
  409.         /* OPEN FOR READ/WRITE, DON'T CREATE AND DON'T TRUNCATE FILE */
  410. /* ------------------------------------------------------------------------- */
  411. /* -------                       RELEASE LFO RECORD                  ------- */
  412. /*                                                                           */
  413. /* ------------------------------------------------------------------------- */
  414. void Dblqh::releaseLfo(Signal* signal) 
  415. {
  416. #ifdef VM_TRACE
  417.   // Check that lfo record isn't already in free list
  418.   LogFileOperationRecordPtr TlfoPtr;
  419.   TlfoPtr.i = cfirstfreeLfo;
  420.   while (TlfoPtr.i != RNIL){
  421.     ptrCheckGuard(TlfoPtr, clfoFileSize, logFileOperationRecord);
  422.     ndbrequire(TlfoPtr.i != lfoPtr.i);
  423.     TlfoPtr.i = TlfoPtr.p->nextLfo;
  424.   }
  425. #endif
  426.   lfoPtr.p->nextLfo = cfirstfreeLfo;
  427.   lfoPtr.p->lfoTimer = 0;
  428.   cfirstfreeLfo = lfoPtr.i;
  429.   lfoPtr.p->lfoState = LogFileOperationRecord::IDLE;
  430. }//Dblqh::releaseLfo()
  431. /* ------------------------------------------------------------------------- */
  432. /* ------- RELEASE ALL LOG PAGES CONNECTED TO A LFO RECORD           ------- */
  433. /*                                                                           */
  434. /*       SUBROUTINE SHORT NAME = RLP                                         */
  435. /* ------------------------------------------------------------------------- */
  436. void Dblqh::releaseLfoPages(Signal* signal) 
  437. {
  438.   LogPageRecordPtr rlpLogPagePtr;
  439.   logPagePtr.i = lfoPtr.p->firstLfoPage;
  440. RLP_LOOP:
  441.   ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
  442.   rlpLogPagePtr.i = logPagePtr.p->logPageWord[ZNEXT_PAGE];
  443.   releaseLogpage(signal);
  444.   if (rlpLogPagePtr.i != RNIL) {
  445.     jam();
  446.     logPagePtr.i = rlpLogPagePtr.i;
  447.     ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
  448.     goto RLP_LOOP;
  449.   }//if
  450.   lfoPtr.p->firstLfoPage = RNIL;
  451. }//Dblqh::releaseLfoPages()
  452. /* ------------------------------------------------------------------------- */
  453. /* -------                       RELEASE LOG PAGE                    ------- */
  454. /*                                                                           */
  455. /* ------------------------------------------------------------------------- */
  456. void Dblqh::releaseLogpage(Signal* signal) 
  457. {
  458. #ifdef VM_TRACE
  459.   // Check that log page isn't already in free list
  460.   ndbrequire(logPagePtr.p->logPageWord[ZPOS_IN_FREE_LIST] == 0);
  461. #endif
  462.   cnoOfLogPages++;
  463.   logPagePtr.p->logPageWord[ZNEXT_PAGE] = cfirstfreeLogPage;
  464.   logPagePtr.p->logPageWord[ZPOS_IN_WRITING]= 0;
  465.   logPagePtr.p->logPageWord[ZPOS_IN_FREE_LIST]= 1;
  466.   cfirstfreeLogPage = logPagePtr.i;
  467. }//Dblqh::releaseLogpage()
  468. /* ------------------------------------------------------------------------- */
  469. /* -------       SEIZE LFO RECORD                                    ------- */
  470. /*                                                                           */
  471. /* ------------------------------------------------------------------------- */
  472. void Dblqh::seizeLfo(Signal* signal) 
  473. {
  474.   lfoPtr.i = cfirstfreeLfo;
  475.   ptrCheckGuard(lfoPtr, clfoFileSize, logFileOperationRecord);
  476.   cfirstfreeLfo = lfoPtr.p->nextLfo;
  477.   lfoPtr.p->nextLfo = RNIL;
  478.   lfoPtr.p->lfoTimer = cLqhTimeOutCount;
  479. }//Dblqh::seizeLfo()
  480. /* ------------------------------------------------------------------------- */
  481. /* -------       SEIZE LOG FILE RECORD                               ------- */
  482. /*                                                                           */
  483. /* ------------------------------------------------------------------------- */
  484. void Dblqh::seizeLogfile(Signal* signal) 
  485. {
  486.   logFilePtr.i = cfirstfreeLogFile;
  487.   ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
  488. /* ------------------------------------------------------------------------- */
  489. /*IF LIST IS EMPTY THEN A SYSTEM CRASH IS INVOKED SINCE LOG_FILE_PTR = RNIL  */
  490. /* ------------------------------------------------------------------------- */
  491.   cfirstfreeLogFile = logFilePtr.p->nextLogFile;
  492.   logFilePtr.p->nextLogFile = RNIL;
  493. }//Dblqh::seizeLogfile()
  494. /* ------------------------------------------------------------------------- */
  495. /* -------       SEIZE LOG PAGE RECORD                               ------- */
  496. /*                                                                           */
  497. /* ------------------------------------------------------------------------- */
  498. void Dblqh::seizeLogpage(Signal* signal) 
  499. {
  500.   cnoOfLogPages--;
  501.   logPagePtr.i = cfirstfreeLogPage;
  502.   ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
  503. /* ------------------------------------------------------------------------- */
  504. /*IF LIST IS EMPTY THEN A SYSTEM CRASH IS INVOKED SINCE LOG_PAGE_PTR = RNIL  */
  505. /* ------------------------------------------------------------------------- */
  506.   cfirstfreeLogPage = logPagePtr.p->logPageWord[ZNEXT_PAGE];
  507.   logPagePtr.p->logPageWord[ZNEXT_PAGE] = RNIL;
  508.   logPagePtr.p->logPageWord[ZPOS_IN_FREE_LIST] = 0;
  509. }//Dblqh::seizeLogpage()
  510. /* ------------------------------------------------------------------------- */
  511. /* -------               WRITE FILE DESCRIPTOR INFORMATION           ------- */
  512. /*                                                                           */
  513. /*       SUBROUTINE SHORT NAME: WFD                                          */
  514. // Pointer handling:
  515. // logFilePtr in
  516. // logPartPtr in
  517. /* ------------------------------------------------------------------------- */
  518. void Dblqh::writeFileDescriptor(Signal* signal) 
  519. {
  520.   TcConnectionrecPtr wfdTcConnectptr;
  521.   UintR twfdFileNo;
  522.   UintR twfdMbyte;
  523. /* -------------------------------------------------- */
  524. /*       START BY WRITING TO LOG FILE RECORD          */
  525. /* -------------------------------------------------- */
  526.   arrGuard(logFilePtr.p->currentMbyte, 16);
  527.   logFilePtr.p->logMaxGciCompleted[logFilePtr.p->currentMbyte] = 
  528.     logPartPtr.p->logPartNewestCompletedGCI;
  529.   logFilePtr.p->logMaxGciStarted[logFilePtr.p->currentMbyte] = cnewestGci;
  530.   wfdTcConnectptr.i = logPartPtr.p->firstLogTcrec;
  531.   if (wfdTcConnectptr.i != RNIL) {
  532.     jam();
  533.     ptrCheckGuard(wfdTcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
  534.     twfdFileNo = wfdTcConnectptr.p->logStartFileNo;
  535.     twfdMbyte = wfdTcConnectptr.p->logStartPageNo >> ZTWOLOG_NO_PAGES_IN_MBYTE;
  536.     logFilePtr.p->logLastPrepRef[logFilePtr.p->currentMbyte] = 
  537.       (twfdFileNo << 16) + twfdMbyte;
  538.   } else {
  539.     jam();
  540.     logFilePtr.p->logLastPrepRef[logFilePtr.p->currentMbyte] = 
  541.       (logFilePtr.p->fileNo << 16) + logFilePtr.p->currentMbyte;
  542.   }//if
  543. }//Dblqh::writeFileDescriptor()
  544. /* ------------------------------------------------------------------------- */
  545. /* -------               WRITE THE HEADER PAGE OF A NEW FILE         ------- */
  546. /*                                                                           */
  547. /*       SUBROUTINE SHORT NAME:  WMO                                         */
  548. /* ------------------------------------------------------------------------- */
  549. void Dblqh::writeFileHeaderOpen(Signal* signal, Uint32 wmoType) 
  550. {
  551.   LogFileRecordPtr wmoLogFilePtr;
  552.   UintR twmoNoLogDescriptors;
  553.   UintR twmoLoop;
  554.   UintR twmoIndex;
  555. /* -------------------------------------------------- */
  556. /*       WRITE HEADER INFORMATION IN THE NEW FILE.    */
  557. /* -------------------------------------------------- */
  558.   logPagePtr.p->logPageWord[ZPAGE_HEADER_SIZE + ZPOS_LOG_TYPE] = ZFD_TYPE;
  559.   logPagePtr.p->logPageWord[ZPAGE_HEADER_SIZE + ZPOS_FILE_NO] = 
  560.     logFilePtr.p->fileNo;
  561.   if (logPartPtr.p->noLogFiles > ZMAX_LOG_FILES_IN_PAGE_ZERO) {
  562.     jam();
  563.     twmoNoLogDescriptors = ZMAX_LOG_FILES_IN_PAGE_ZERO;
  564.   } else {
  565.     jam();
  566.     twmoNoLogDescriptors = logPartPtr.p->noLogFiles;
  567.   }//if
  568.   logPagePtr.p->logPageWord[ZPAGE_HEADER_SIZE + ZPOS_NO_FD] = 
  569.     twmoNoLogDescriptors;
  570.   wmoLogFilePtr.i = logFilePtr.i;
  571.   twmoLoop = 0;
  572. WMO_LOOP:
  573.   jam();
  574.   if (twmoLoop < twmoNoLogDescriptors) {
  575.     jam();
  576.     ptrCheckGuard(wmoLogFilePtr, clogFileFileSize, logFileRecord);
  577.     for (twmoIndex = 0; twmoIndex <= ZNO_MBYTES_IN_FILE - 1; twmoIndex++) {
  578.       jam();
  579.       arrGuard(((ZPAGE_HEADER_SIZE + ZFD_HEADER_SIZE) + 
  580.                 (twmoLoop * ZFD_PART_SIZE)) + twmoIndex, ZPAGE_SIZE);
  581.       logPagePtr.p->logPageWord[((ZPAGE_HEADER_SIZE + ZFD_HEADER_SIZE) + 
  582.                    (twmoLoop * ZFD_PART_SIZE)) + twmoIndex] = 
  583.             wmoLogFilePtr.p->logMaxGciCompleted[twmoIndex];
  584.       arrGuard((((ZPAGE_HEADER_SIZE + ZFD_HEADER_SIZE) +
  585.                  (twmoLoop * ZFD_PART_SIZE)) + ZNO_MBYTES_IN_FILE) +
  586.                   twmoIndex, ZPAGE_SIZE);
  587.       logPagePtr.p->logPageWord[(((ZPAGE_HEADER_SIZE + ZFD_HEADER_SIZE) + 
  588.            (twmoLoop * ZFD_PART_SIZE)) + ZNO_MBYTES_IN_FILE) + twmoIndex] = 
  589.          wmoLogFilePtr.p->logMaxGciStarted[twmoIndex];
  590.       arrGuard((((ZPAGE_HEADER_SIZE + ZFD_HEADER_SIZE) +
  591.         (twmoLoop * ZFD_PART_SIZE)) + (2 * ZNO_MBYTES_IN_FILE)) +
  592.          twmoIndex, ZPAGE_SIZE);
  593.       logPagePtr.p->logPageWord[(((ZPAGE_HEADER_SIZE + ZFD_HEADER_SIZE) + 
  594.         (twmoLoop * ZFD_PART_SIZE)) + (2 * ZNO_MBYTES_IN_FILE)) + twmoIndex] = 
  595.           wmoLogFilePtr.p->logLastPrepRef[twmoIndex];
  596.     }//for
  597.     wmoLogFilePtr.i = wmoLogFilePtr.p->prevLogFile;
  598.     twmoLoop = twmoLoop + 1;
  599.     goto WMO_LOOP;
  600.   }//if
  601.   logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = 
  602.     (ZPAGE_HEADER_SIZE + ZFD_HEADER_SIZE) +
  603.     (ZFD_PART_SIZE * twmoNoLogDescriptors);
  604.   arrGuard(logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX], ZPAGE_SIZE);
  605.   logPagePtr.p->logPageWord[logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX]] = 
  606.        ZNEXT_LOG_RECORD_TYPE;
  607. /* ------------------------------------------------------- */
  608. /*       THIS IS A SPECIAL WRITE OF THE FIRST PAGE IN THE  */
  609. /*       LOG FILE. THIS HAS SPECIAL SIGNIFANCE TO FIND     */
  610. /*       THE END OF THE LOG AT SYSTEM RESTART.             */
  611. /* ------------------------------------------------------- */
  612.   writeSinglePage(signal, 0, ZPAGE_SIZE - 1, __LINE__);
  613.   if (wmoType == ZINIT) {
  614.     jam();
  615.     lfoPtr.p->lfoState = LogFileOperationRecord::INIT_FIRST_PAGE;
  616.   } else {
  617.     jam();
  618.     lfoPtr.p->lfoState = LogFileOperationRecord::FIRST_PAGE_WRITE_IN_LOGFILE;
  619.   }//if
  620.   logFilePtr.p->filePosition = 1;
  621.   if (wmoType == ZNORMAL) {
  622.     jam();
  623. /* -------------------------------------------------- */
  624. /*       ALLOCATE A NEW PAGE SINCE THE CURRENT IS     */
  625. /*       WRITTEN.                                     */
  626. /* -------------------------------------------------- */
  627.     seizeLogpage(signal);
  628.     initLogpage(signal);
  629.     logFilePtr.p->currentLogpage = logPagePtr.i;
  630.     logFilePtr.p->currentFilepage = logFilePtr.p->currentFilepage + 1;
  631.   }//if
  632. }//Dblqh::writeFileHeaderOpen()
  633. /* -------------------------------------------------- */
  634. /*       THE NEW FILE POSITION WILL ALWAYS BE 1 SINCE */
  635. /*       WE JUST WROTE THE FIRST PAGE IN THE LOG FILE */
  636. /* -------------------------------------------------- */
  637. /* ------------------------------------------------------------------------- */
  638. /* -------               WRITE A MBYTE HEADER DURING INITIAL START   ------- */
  639. /*                                                                           */
  640. /*       SUBROUTINE SHORT NAME: WIM                                          */
  641. /* ------------------------------------------------------------------------- */
  642. void Dblqh::writeInitMbyte(Signal* signal) 
  643. {
  644.   initLogpage(signal);
  645.   writeSinglePage(signal, logFilePtr.p->currentMbyte * ZPAGES_IN_MBYTE,
  646.                   ZPAGE_SIZE - 1, __LINE__);
  647.   lfoPtr.p->lfoState = LogFileOperationRecord::WRITE_INIT_MBYTE;
  648. }//Dblqh::writeInitMbyte()
  649. /* ------------------------------------------------------------------------- */
  650. /* -------               WRITE A SINGLE PAGE INTO A FILE             ------- */
  651. /*                                                                           */
  652. /*       INPUT:          TWSP_PAGE_NO    THE PAGE NUMBER WRITTEN             */
  653. /*       SUBROUTINE SHORT NAME:  WSP                                         */
  654. /* ------------------------------------------------------------------------- */
  655. void Dblqh::writeSinglePage(Signal* signal, Uint32 pageNo,
  656.                             Uint32 wordWritten, Uint32 place) 
  657. {
  658.   seizeLfo(signal);
  659.   initLfo(signal);
  660.   lfoPtr.p->firstLfoPage = logPagePtr.i;
  661.   logPagePtr.p->logPageWord[ZNEXT_PAGE] = RNIL;
  662.   writeDbgInfoPageHeader(logPagePtr, place, pageNo, wordWritten);
  663.   // Calculate checksum for page
  664.   logPagePtr.p->logPageWord[ZPOS_CHECKSUM] = calcPageCheckSum(logPagePtr);
  665.   lfoPtr.p->lfoPageNo = pageNo;
  666.   lfoPtr.p->lfoWordWritten = wordWritten;
  667.   lfoPtr.p->noPagesRw = 1;
  668. /* -------------------------------------------------- */
  669. /*       SET TIMER ON THIS LOG PART TO SIGNIFY THAT A */
  670. /*       LOG RECORD HAS BEEN SENT AT THIS TIME.       */
  671. /* -------------------------------------------------- */
  672.   logPartPtr.p->logPartTimer = logPartPtr.p->logTimer;
  673.   signal->theData[0] = logFilePtr.p->fileRef;
  674.   signal->theData[1] = cownref;
  675.   signal->theData[2] = lfoPtr.i;
  676.   signal->theData[3] = ZLIST_OF_PAIRS_SYNCH;
  677.   signal->theData[4] = ZVAR_NO_LOG_PAGE_WORD;
  678.   signal->theData[5] = 1;                     /* ONE PAGE WRITTEN */
  679.   signal->theData[6] = logPagePtr.i;
  680.   signal->theData[7] = pageNo;
  681.   sendSignal(NDBFS_REF, GSN_FSWRITEREQ, signal, 8, JBA);
  682. }//Dblqh::writeSinglePage()
  683. /* ##########################################################################
  684.  *     SYSTEM RESTART PHASE ONE MODULE
  685.  *     THIS MODULE IS A SUB-MODULE OF THE FILE SYSTEM HANDLING.
  686.  *
  687.  *     THIS MODULE CONTAINS THE CODE FOR THE FIRST PHASE OF THE SYSTEM RESTART.
  688.  *     THE AIM OF THIS PHASE IS TO FIND THE END OF THE LOG AND TO FIND 
  689.  *     INFORMATION ABOUT WHERE GLOBAL CHECKPOINTS ARE COMPLETED AND STARTED 
  690.  *     IN THE LOG. THIS INFORMATION IS NEEDED TO START PHASE THREE OF 
  691.  *     THE SYSTEM RESTART.
  692.  * ########################################################################## */
  693. /* --------------------------------------------------------------------------
  694.  *     A SYSTEM RESTART OR NODE RESTART IS ONGOING. WE HAVE NOW OPENED FILE 0
  695.  *     NOW WE NEED TO READ PAGE 0 TO FIND WHICH LOG FILE THAT WAS OPEN AT 
  696.  *     CRASH TIME.
  697.  * -------------------------------------------------------------------------- */
  698. void Dblqh::openSrFrontpageLab(Signal* signal) 
  699. {
  700.   readSinglePage(signal, 0);
  701.   lfoPtr.p->lfoState = LogFileOperationRecord::READ_SR_FRONTPAGE;
  702.   return;
  703. }//Dblqh::openSrFrontpageLab()
  704. /* -------------------------------------------------------------------------
  705.  * WE HAVE NOW READ PAGE 0 IN FILE 0. CHECK THE LAST OPEN FILE. ACTUALLY THE
  706.  * LAST OPEN FILE COULD BE THE NEXT AFTER THAT. CHECK THAT FIRST. WHEN THE  
  707.  * LAST WAS FOUND WE CAN FIND ALL THE NEEDED INFORMATION WHERE TO START AND  
  708.  * STOP READING THE LOG.
  709.  * -------------------------------------------------------------------------- */
  710. void Dblqh::readSrFrontpageLab(Signal* signal) 
  711. {
  712.   Uint32 fileNo = logPagePtr.p->logPageWord[ZPAGE_HEADER_SIZE + ZPOS_FILE_NO];
  713.   if (fileNo == 0) {
  714.     jam();
  715.     /* ----------------------------------------------------------------------
  716.      *       FILE 0 WAS ALSO LAST FILE SO WE DO NOT NEED TO READ IT AGAIN.
  717.      * ---------------------------------------------------------------------- */
  718.     readSrLastFileLab(signal);
  719.     return;
  720.   }//if
  721.   /* ------------------------------------------------------------------------
  722.    *    CLOSE FILE 0 SO THAT WE HAVE CLOSED ALL FILES WHEN STARTING TO READ 
  723.    *    THE FRAGMENT LOG. ALSO RELEASE PAGE ZERO.
  724.    * ------------------------------------------------------------------------ */
  725.   releaseLogpage(signal);
  726.   logFilePtr.p->logFileStatus = LogFileRecord::CLOSING_SR;
  727.   closeFile(signal, logFilePtr);
  728.   LogFileRecordPtr locLogFilePtr;
  729.   findLogfile(signal, fileNo, logPartPtr, &locLogFilePtr);
  730.   locLogFilePtr.p->logFileStatus = LogFileRecord::OPEN_SR_LAST_FILE;
  731.   openFileRw(signal, locLogFilePtr);
  732.   return;
  733. }//Dblqh::readSrFrontpageLab()
  734. void Dblqh::openSrLastFileLab(Signal* signal) 
  735. {
  736.   readSinglePage(signal, 0);
  737.   lfoPtr.p->lfoState = LogFileOperationRecord::READ_SR_LAST_FILE;
  738.   return;
  739. }//Dblqh::openSrLastFileLab()
  740. void Dblqh::readSrLastFileLab(Signal* signal) 
  741. {
  742.   logPartPtr.p->logLap = logPagePtr.p->logPageWord[ZPOS_LOG_LAP];
  743.   if (logPartPtr.p->noLogFiles > ZMAX_LOG_FILES_IN_PAGE_ZERO) {
  744.     jam();
  745.     initGciInLogFileRec(signal, ZMAX_LOG_FILES_IN_PAGE_ZERO);
  746.   } else {
  747.     jam();
  748.     initGciInLogFileRec(signal, logPartPtr.p->noLogFiles);
  749.   }//if
  750.   releaseLogpage(signal);
  751.   /* ------------------------------------------------------------------------
  752.    *    NOW WE HAVE FOUND THE LAST LOG FILE. WE ALSO NEED TO FIND THE LAST
  753.    *    MBYTE THAT WAS LAST WRITTEN BEFORE THE SYSTEM CRASH.
  754.    * ------------------------------------------------------------------------ */
  755.   logPartPtr.p->lastLogfile = logFilePtr.i;
  756.   readSinglePage(signal, 0);
  757.   lfoPtr.p->lfoState = LogFileOperationRecord::READ_SR_LAST_MBYTE;
  758.   logFilePtr.p->currentMbyte = 0;
  759.   return;
  760. }//Dblqh::readSrLastFileLab()
  761. void Dblqh::readSrLastMbyteLab(Signal* signal) 
  762. {
  763.   if (logPartPtr.p->lastMbyte == ZNIL) {
  764.     if (logPagePtr.p->logPageWord[ZPOS_LOG_LAP] < logPartPtr.p->logLap) {
  765.       jam();
  766.       logPartPtr.p->lastMbyte = logFilePtr.p->currentMbyte - 1;
  767.     }//if
  768.   }//if
  769.   arrGuard(logFilePtr.p->currentMbyte, 16);
  770.   logFilePtr.p->logMaxGciCompleted[logFilePtr.p->currentMbyte] = 
  771.     logPagePtr.p->logPageWord[ZPOS_MAX_GCI_COMPLETED];
  772.   logFilePtr.p->logMaxGciStarted[logFilePtr.p->currentMbyte] = 
  773.     logPagePtr.p->logPageWord[ZPOS_MAX_GCI_STARTED];
  774.   logFilePtr.p->logLastPrepRef[logFilePtr.p->currentMbyte] = 
  775.     logPagePtr.p->logPageWord[ZLAST_LOG_PREP_REF];
  776.   releaseLogpage(signal);
  777.   if (logFilePtr.p->currentMbyte < (ZNO_MBYTES_IN_FILE - 1)) {
  778.     jam();
  779.     logFilePtr.p->currentMbyte++;
  780.     readSinglePage(signal, ZPAGES_IN_MBYTE * logFilePtr.p->currentMbyte);
  781.     lfoPtr.p->lfoState = LogFileOperationRecord::READ_SR_LAST_MBYTE;
  782.     return;
  783.   } else {
  784.     jam();
  785.     /* ----------------------------------------------------------------------
  786.      *    THE LOG WAS IN THE LAST MBYTE WHEN THE CRASH OCCURRED SINCE ALL 
  787.      *    LOG LAPS ARE EQUAL TO THE CURRENT LOG LAP.
  788.      * ---------------------------------------------------------------------- */
  789.     if (logPartPtr.p->lastMbyte == ZNIL) {
  790.       jam();
  791.       logPartPtr.p->lastMbyte = ZNO_MBYTES_IN_FILE - 1;
  792.     }//if
  793.   }//if
  794.   logFilePtr.p->logFileStatus = LogFileRecord::CLOSING_SR;
  795.   closeFile(signal, logFilePtr);
  796.   if (logPartPtr.p->noLogFiles > ZMAX_LOG_FILES_IN_PAGE_ZERO) {
  797.     Uint32 fileNo;
  798.     if (logFilePtr.p->fileNo >= ZMAX_LOG_FILES_IN_PAGE_ZERO) {
  799.       jam();
  800.       fileNo = logFilePtr.p->fileNo - ZMAX_LOG_FILES_IN_PAGE_ZERO;
  801.     } else {
  802.       jam();
  803.       fileNo = 
  804. (logPartPtr.p->noLogFiles + logFilePtr.p->fileNo) - 
  805. ZMAX_LOG_FILES_IN_PAGE_ZERO;
  806.     }//if
  807.     if (fileNo == 0) {
  808.       jam();
  809.       /* --------------------------------------------------------------------
  810.        *  AVOID USING FILE 0 AGAIN SINCE THAT IS PROBABLY CLOSING AT THE 
  811.        *  MOMENT.
  812.        * -------------------------------------------------------------------- */
  813.       fileNo = 1;
  814.       logPartPtr.p->srRemainingFiles = 
  815. logPartPtr.p->noLogFiles - (ZMAX_LOG_FILES_IN_PAGE_ZERO - 1);
  816.     } else {
  817.       jam();
  818.       logPartPtr.p->srRemainingFiles = 
  819. logPartPtr.p->noLogFiles - ZMAX_LOG_FILES_IN_PAGE_ZERO;
  820.     }//if
  821.     LogFileRecordPtr locLogFilePtr;
  822.     findLogfile(signal, fileNo, logPartPtr, &locLogFilePtr);
  823.     locLogFilePtr.p->logFileStatus = LogFileRecord::OPEN_SR_NEXT_FILE;
  824.     openFileRw(signal, locLogFilePtr);
  825.     return;
  826.   }//if
  827.   /* ------------------------------------------------------------------------
  828.    *   THERE WERE NO NEED TO READ ANY MORE PAGE ZERO IN OTHER FILES. 
  829.    *   WE NOW HAVE ALL THE NEEDED INFORMATION ABOUT THE GCI'S THAT WE NEED. 
  830.    *   NOW JUST WAIT FOR CLOSE OPERATIONS TO COMPLETE.
  831.    * ------------------------------------------------------------------------ */
  832.   return;
  833. }//Dblqh::readSrLastMbyteLab()
  834. void Dblqh::openSrNextFileLab(Signal* signal) 
  835. {
  836.   readSinglePage(signal, 0);
  837.   lfoPtr.p->lfoState = LogFileOperationRecord::READ_SR_NEXT_FILE;
  838.   return;
  839. }//Dblqh::openSrNextFileLab()
  840. void Dblqh::readSrNextFileLab(Signal* signal) 
  841. {
  842.   if (logPartPtr.p->srRemainingFiles > ZMAX_LOG_FILES_IN_PAGE_ZERO) {
  843.     jam();
  844.     initGciInLogFileRec(signal, ZMAX_LOG_FILES_IN_PAGE_ZERO);
  845.   } else {
  846.     jam();
  847.     initGciInLogFileRec(signal, logPartPtr.p->srRemainingFiles);
  848.   }//if
  849.   releaseLogpage(signal);
  850.   logFilePtr.p->logFileStatus = LogFileRecord::CLOSING_SR;
  851.   closeFile(signal, logFilePtr);
  852.   if (logPartPtr.p->srRemainingFiles > ZMAX_LOG_FILES_IN_PAGE_ZERO) {
  853.     Uint32 fileNo;
  854.     if (logFilePtr.p->fileNo >= ZMAX_LOG_FILES_IN_PAGE_ZERO) {
  855.       jam();
  856.       fileNo = logFilePtr.p->fileNo - ZMAX_LOG_FILES_IN_PAGE_ZERO;
  857.     } else {
  858.       jam();
  859.       fileNo = 
  860. (logPartPtr.p->noLogFiles + logFilePtr.p->fileNo) - 
  861. ZMAX_LOG_FILES_IN_PAGE_ZERO;
  862.     }//if
  863.     if (fileNo == 0) {
  864.       jam();
  865.       /* --------------------------------------------------------------------
  866.        * AVOID USING FILE 0 AGAIN SINCE THAT IS PROBABLY CLOSING AT THE MOMENT.
  867.        * -------------------------------------------------------------------- */
  868.       fileNo = 1;
  869.       logPartPtr.p->srRemainingFiles = 
  870. logPartPtr.p->srRemainingFiles - (ZMAX_LOG_FILES_IN_PAGE_ZERO - 1);
  871.     } else {
  872.       jam();
  873.       logPartPtr.p->srRemainingFiles = 
  874. logPartPtr.p->srRemainingFiles - ZMAX_LOG_FILES_IN_PAGE_ZERO;
  875.     }//if
  876.     LogFileRecordPtr locLogFilePtr;
  877.     findLogfile(signal, fileNo, logPartPtr, &locLogFilePtr);
  878.     locLogFilePtr.p->logFileStatus = LogFileRecord::OPEN_SR_NEXT_FILE;
  879.     openFileRw(signal, locLogFilePtr);
  880.   }//if
  881.   /* ------------------------------------------------------------------------
  882.    *   THERE WERE NO NEED TO READ ANY MORE PAGE ZERO IN OTHER FILES. 
  883.    *   WE NOW HAVE ALL THE NEEDED INFORMATION ABOUT THE GCI'S THAT WE NEED. 
  884.    *   NOW JUST WAIT FOR CLOSE OPERATIONS TO COMPLETE.
  885.    * ------------------------------------------------------------------------ */
  886.   return;
  887. }//Dblqh::readSrNextFileLab()
  888. void Dblqh::closingSrLab(Signal* signal) 
  889. {
  890.   logFilePtr.p->logFileStatus = LogFileRecord::CLOSED;
  891.   logPartPtr.i = logFilePtr.p->logPartRec;
  892.   ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
  893.   logFilePtr.i = logPartPtr.p->firstLogfile;
  894.   do {
  895.     jam();
  896.     ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
  897.     if (logFilePtr.p->logFileStatus != LogFileRecord::CLOSED) {
  898.       jam();
  899.       /* --------------------------------------------------------------------
  900.        *  EXIT AND WAIT FOR REMAINING LOG FILES TO COMPLETE THEIR WORK.
  901.        * -------------------------------------------------------------------- */
  902.       return;
  903.     }//if
  904.     logFilePtr.i = logFilePtr.p->nextLogFile;
  905.   } while (logFilePtr.i != logPartPtr.p->firstLogfile);
  906.   /* ------------------------------------------------------------------------
  907.    *  ALL FILES IN THIS PART HAVE BEEN CLOSED. THIS INDICATES THAT THE FIRST
  908.    *  PHASE OF THE SYSTEM RESTART HAVE BEEN CONCLUDED FOR THIS LOG PART.
  909.    *  CHECK IF ALL OTHER LOG PARTS ARE ALSO COMPLETED.
  910.    * ------------------------------------------------------------------------ */
  911.   logPartPtr.p->logPartState = LogPartRecord::SR_FIRST_PHASE_COMPLETED;
  912.   for (logPartPtr.i = 0; logPartPtr.i <= 3; logPartPtr.i++) {
  913.     jam();
  914.     ptrAss(logPartPtr, logPartRecord);
  915.     if (logPartPtr.p->logPartState != LogPartRecord::SR_FIRST_PHASE_COMPLETED) {
  916.       jam();
  917.       /* --------------------------------------------------------------------
  918.        * EXIT AND WAIT FOR THE REST OF THE LOG PARTS TO COMPLETE.
  919.        * -------------------------------------------------------------------- */
  920.       return;
  921.     }//if
  922.   }//for
  923.   /* ------------------------------------------------------------------------
  924.    *       THE FIRST PHASE HAVE BEEN COMPLETED.
  925.    * ------------------------------------------------------------------------ */
  926.   signal->theData[0] = ZSR_PHASE3_START;
  927.   signal->theData[1] = ZSR_PHASE1_COMPLETED;
  928.   sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
  929.   return;
  930. }//Dblqh::closingSrLab()
  931. /* ##########################################################################
  932.  * #######                  SYSTEM RESTART PHASE TWO MODULE           ####### 
  933.  *
  934.  *  THIS MODULE HANDLES THE SYSTEM RESTART WHERE LQH CONTROLS TUP AND ACC TO
  935.  *  ENSURE THAT THEY HAVE KNOWLEDGE OF ALL FRAGMENTS AND HAVE DONE THE NEEDED
  936.  *  READING OF DATA FROM FILE AND EXECUTION OF LOCAL LOGS. THIS PROCESS
  937.  *  EXECUTES CONCURRENTLY WITH PHASE ONE OF THE SYSTEM RESTART. THIS PHASE
  938.  *  FINDS THE INFORMATION ABOUT THE FRAGMENT LOG NEEDED TO EXECUTE THE FRAGMENT
  939.  *  LOG.
  940.  *  WHEN TUP AND ACC HAVE PREPARED ALL FRAGMENTS THEN LQH ORDERS THOSE LQH'S
  941.  *  THAT ARE RESPONSIBLE TO EXECUTE THE FRAGMENT LOGS TO DO SO. IT IS POSSIBLE 
  942.  *  THAT ANOTHER NODE EXECUTES THE LOG FOR A FRAGMENT RESIDING AT THIS NODE.
  943.  * ########################################################################## */
  944. /* ***************>> */
  945. /*  START_FRAGREQ  > */
  946. /* ***************>> */
  947. void Dblqh::execSTART_FRAGREQ(Signal* signal) 
  948. {
  949.   const StartFragReq * const startFragReq = (StartFragReq *)&signal->theData[0];
  950.   jamEntry();
  951.   tabptr.i = startFragReq->tableId;
  952.   Uint32 fragId = startFragReq->fragId;
  953.   ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
  954.   if (!getFragmentrec(signal, fragId)) {
  955.     startFragRefLab(signal);
  956.     return;
  957.   }//if
  958.   tabptr.p->tableStatus = Tablerec::TABLE_DEFINED;
  959.   
  960.   initFragrecSr(signal);
  961.   if (startFragReq->lcpNo == ZNIL) {
  962.     jam();
  963.     /* ----------------------------------------------------------------------
  964.      *  THERE WAS NO LOCAL CHECKPOINT AVAILABLE FOR THIS FRAGMENT. WE DO 
  965.      *  NOT NEED TO READ IN THE LOCAL FRAGMENT. WE HAVE ALREADY ADDED THE 
  966.      *  FRAGMENT AS AN EMPTY FRAGMENT AT THIS POINT. THUS WE CAN SIMPLY 
  967.      *  EXIT AND THE FRAGMENT WILL PARTICIPATE IN THE EXECUTION OF THE LOG.
  968.      *  PUT FRAGMENT ON LIST OF COMPLETED FRAGMENTS FOR EXECUTION OF LOG.
  969.      * ---------------------------------------------------------------------- */
  970.     fragptr.p->nextFrag = cfirstCompletedFragSr;
  971.     cfirstCompletedFragSr = fragptr.i;
  972.     return;
  973.   }//if
  974.   if (cfirstWaitFragSr == RNIL) {
  975.     jam();
  976.       lcpPtr.i = 0;
  977.     ptrAss(lcpPtr, lcpRecord);
  978.     if (lcpPtr.p->lcpState == LcpRecord::LCP_IDLE) {
  979.       jam();
  980.       initLcpSr(signal, startFragReq->lcpNo,
  981.                 startFragReq->lcpId, tabptr.i,
  982.                 fragId, fragptr.i);
  983.       signal->theData[0] = lcpPtr.i;
  984.       signal->theData[1] = cownref;
  985.       signal->theData[2] = lcpPtr.p->currentFragment.lcpFragOrd.lcpNo;
  986.       signal->theData[3] = lcpPtr.p->currentFragment.lcpFragOrd.tableId;
  987.       signal->theData[4] = lcpPtr.p->currentFragment.lcpFragOrd.fragmentId;
  988.       sendSignal(fragptr.p->accBlockref, GSN_SR_FRAGIDREQ, signal, 5, JBB);
  989.       return;
  990.     }//if
  991.   }//if
  992.   fragptr.p->nextFrag = cfirstWaitFragSr;
  993.   cfirstWaitFragSr = fragptr.i;
  994. }//Dblqh::execSTART_FRAGREQ()
  995. void Dblqh::startFragRefLab(Signal* signal) 
  996. {
  997.   const StartFragReq * const startFragReq = (StartFragReq *)&signal->theData[0];
  998.   BlockReference userRef = startFragReq->userRef;
  999.   Uint32 userPtr = startFragReq->userPtr;
  1000.   signal->theData[0] = userPtr;
  1001.   signal->theData[1] = terrorCode;
  1002.   signal->theData[2] = cownNodeid;
  1003.   sendSignal(userRef, GSN_START_FRAGREF, signal, 3, JBB);
  1004.   return;
  1005. }//Dblqh::startFragRefLab()
  1006. /* ***************>> */
  1007. /*  SR_FRAGIDCONF  > */
  1008. /* ***************>> */
  1009. /* --------------------------------------------------------------------------
  1010.  *       PRECONDITION: LCP_PTR:LCP_STATE = SR_WAIT_FRAGID 
  1011.  * -------------------------------------------------------------------------- */
  1012. void Dblqh::execSR_FRAGIDCONF(Signal* signal) 
  1013. {
  1014.   SrFragidConf * const srFragidConf = (SrFragidConf *)&signal->theData[0];
  1015.   jamEntry();
  1016.   lcpPtr.i = srFragidConf->lcpPtr;
  1017.   ptrCheckGuard(lcpPtr, clcpFileSize, lcpRecord);
  1018.   ndbrequire(lcpPtr.p->lcpState == LcpRecord::LCP_SR_WAIT_FRAGID);
  1019.   /* ------------------------------------------------------------------------
  1020.    *  NO ERROR CHECKING OF TNO_LOCFRAG VALUE. OUT OF BOUND WILL IMPLY THAT AN
  1021.    *  INDEX OUT OF RANGE WILL CAUSE A SYSTEM RESTART WHICH IS DESIRED.
  1022.    * ------------------------------------------------------------------------ */
  1023.   lcpPtr.p->lcpAccptr = srFragidConf->accPtr;
  1024.   fragptr.i = lcpPtr.p->currentFragment.fragPtrI;
  1025.   ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
  1026.   fragptr.p->accFragptr[0] = srFragidConf->fragPtr[0];
  1027.   fragptr.p->accFragptr[1] = srFragidConf->fragPtr[1];
  1028.   fragptr.p->hashCheckBit = srFragidConf->hashCheckBit;
  1029.   Uint32 noLocFrag = srFragidConf->noLocFrag;
  1030.   ndbrequire(noLocFrag == 2);
  1031.   Uint32 fragid[2];
  1032.   Uint32 i;
  1033.   for (i = 0; i < noLocFrag; i++) {
  1034.     fragid[i] = srFragidConf->fragId[i];
  1035.   }//for
  1036.   for (i = 0; i < noLocFrag; i++) {
  1037.     jam();
  1038.     Uint32 fragId = fragid[i];
  1039.     /* ----------------------------------------------------------------------
  1040.      *  THERE IS NO ERROR CHECKING ON PURPOSE. IT IS POSSIBLE TO CALCULATE HOW
  1041.      *  MANY LOCAL LCP RECORDS THERE SHOULD BE. IT SHOULD NEVER HAPPEN THAT 
  1042.      *  THERE IS NO ONE FREE. IF THERE IS NO ONE IT WILL ALSO BE A POINTER 
  1043.      *  OUT OF RANGE WHICH IS AN ERROR CODE IN ITSELF. REUSES ERROR 
  1044.      *  HANDLING IN AXE VM.
  1045.      * ---------------------------------------------------------------------- */
  1046.     seizeLcpLoc(signal);
  1047.     initLcpLocAcc(signal, fragId);
  1048.     lcpLocptr.p->lcpLocstate = LcpLocRecord::SR_ACC_STARTED;
  1049.     signal->theData[0] = lcpPtr.p->lcpAccptr;
  1050.     signal->theData[1] = lcpLocptr.i;
  1051.     signal->theData[2] = lcpLocptr.p->locFragid;
  1052.     signal->theData[3] = lcpPtr.p->currentFragment.lcpFragOrd.lcpId % MAX_LCP_STORED;
  1053.     sendSignal(fragptr.p->accBlockref, GSN_ACC_SRREQ, signal, 4, JBB);
  1054.     seizeLcpLoc(signal);
  1055.     initLcpLocTup(signal, fragId);
  1056.     lcpLocptr.p->lcpLocstate = LcpLocRecord::SR_TUP_STARTED;
  1057.     signal->theData[0] = lcpLocptr.i;
  1058.     signal->theData[1] = cownref;
  1059.     signal->theData[2] = lcpPtr.p->currentFragment.lcpFragOrd.tableId;
  1060.     signal->theData[3] = lcpLocptr.p->locFragid;
  1061.     signal->theData[4] = lcpPtr.p->currentFragment.lcpFragOrd.lcpNo;
  1062.     sendSignal(fragptr.p->tupBlockref, GSN_TUP_SRREQ, signal, 5, JBB);
  1063.   }//for
  1064.   lcpPtr.p->lcpState = LcpRecord::LCP_SR_STARTED;
  1065.   return;
  1066. }//Dblqh::execSR_FRAGIDCONF()
  1067. /* ***************> */
  1068. /*  SR_FRAGIDREF  > */
  1069. /* ***************> */
  1070. void Dblqh::execSR_FRAGIDREF(Signal* signal) 
  1071. {
  1072.   jamEntry();
  1073.   ndbrequire(false);
  1074. }//Dblqh::execSR_FRAGIDREF()
  1075. /* ************>> */
  1076. /*  ACC_SRCONF  > */
  1077. /* ************>> */
  1078. /* --------------------------------------------------------------------------
  1079.  *       PRECONDITION: LCP_LOCPTR:LCP_LOCSTATE = SR_ACC_STARTED
  1080.  * -------------------------------------------------------------------------- */
  1081. void Dblqh::execACC_SRCONF(Signal* signal) 
  1082. {
  1083.   jamEntry();
  1084.   lcpLocptr.i = signal->theData[0];
  1085.   ptrCheckGuard(lcpLocptr, clcpLocrecFileSize, lcpLocRecord);
  1086.   if (lcpLocptr.p->lcpLocstate != LcpLocRecord::SR_ACC_STARTED) {
  1087.     jam();
  1088.     systemErrorLab(signal);
  1089.     return;
  1090.   }//if
  1091.   lcpPtr.i = lcpLocptr.p->masterLcpRec;
  1092.   ptrCheckGuard(lcpPtr, clcpFileSize, lcpRecord);
  1093.   /* ------------------------------------------------------------------------
  1094.    *  NO ERROR CHECK ON USING VALUE IN MASTER_LCP_REC. ERROR IN THIS REFERENCE
  1095.    *  WILL CAUSE POINTER OUT OF RANGE WHICH CAUSES A SYSTEM RESTART.
  1096.    * ------------------------------------------------------------------------ */
  1097.   lcpLocptr.p->lcpLocstate = LcpLocRecord::SR_ACC_COMPLETED;
  1098.   srCompletedLab(signal);
  1099.   return;
  1100. }//Dblqh::execACC_SRCONF()
  1101. /* ************> */
  1102. /*  ACC_SRREF  > */
  1103. /* ************> */
  1104. void Dblqh::execACC_SRREF(Signal* signal) 
  1105. {
  1106.   jamEntry();
  1107.   terrorCode = signal->theData[1];
  1108.   systemErrorLab(signal);
  1109.   return;
  1110. }//Dblqh::execACC_SRREF()
  1111. /* ************>> */
  1112. /*  TUP_SRCONF  > */
  1113. /* ************>> */
  1114. /* --------------------------------------------------------------------------
  1115.  *       PRECONDITION: LCP_LOCPTR:LCP_LOCSTATE = SR_TUP_STARTED
  1116.  * -------------------------------------------------------------------------- */
  1117. void Dblqh::execTUP_SRCONF(Signal* signal) 
  1118. {
  1119.   jamEntry();
  1120.   lcpLocptr.i = signal->theData[0];
  1121.   ptrCheckGuard(lcpLocptr, clcpLocrecFileSize, lcpLocRecord);
  1122.   Uint32 tupFragPtr = signal->theData[1];
  1123.   ndbrequire(lcpLocptr.p->lcpLocstate == LcpLocRecord::SR_TUP_STARTED);
  1124.   lcpPtr.i = lcpLocptr.p->masterLcpRec;
  1125.   ptrCheckGuard(lcpPtr, clcpFileSize, lcpRecord);
  1126.   /* ------------------------------------------------------------------------
  1127.    *  NO ERROR CHECK ON USING VALUE IN MASTER_LCP_REC. ERROR IN THIS REFERENCE
  1128.    *  WILL CAUSE POINTER OUT OF RANGE WHICH CAUSES A SYSTEM RESTART.
  1129.    * ------------------------------------------------------------------------ */
  1130.   lcpLocptr.p->lcpLocstate = LcpLocRecord::SR_TUP_COMPLETED;
  1131.   fragptr.i = lcpPtr.p->currentFragment.fragPtrI;
  1132.   ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
  1133.   if (lcpLocptr.i == lcpPtr.p->firstLcpLocTup) {
  1134.     jam();
  1135.     fragptr.p->tupFragptr[1] = tupFragPtr;
  1136.   } else {
  1137.     jam();
  1138.     fragptr.p->tupFragptr[0] = tupFragPtr;
  1139.   }//if
  1140.   srCompletedLab(signal);
  1141.   return;
  1142. }//Dblqh::execTUP_SRCONF()
  1143. void Dblqh::srCompletedLab(Signal* signal) 
  1144. {
  1145.   checkSrCompleted(signal);
  1146.   if (lcpPtr.p->lcpState == LcpRecord::LCP_SR_COMPLETED) {
  1147.     jam();
  1148.     /* ----------------------------------------------------------------------
  1149.      *  THE SYSTEM RESTART OF THIS FRAGMENT HAS BEEN COMPLETED. IT IS NOW
  1150.      *  TIME TO START A SYSTEM RESTART ON THE NEXT FRAGMENT OR CONTINUE 
  1151.      *  WITH THE NEXT STEP OF THE SYSTEM RESTART. THIS STEP IS TO EXECUTE 
  1152.      *  THE FRAGMENT LOGS.
  1153.      * ----------------------------------------------------------------------
  1154.      *  WE RELEASE THE LOCAL LCP RECORDS.
  1155.      * --------------------------------------------------------------------- */
  1156.     releaseLocalLcps(signal);
  1157.     /* ----------------------------------------------------------------------
  1158.      *  PUT FRAGMENT ON LIST OF FRAGMENTS WHICH HAVE BEEN STARTED AS PART OF 
  1159.      *  THE SYSTEM RESTART. THEY ARE NOW WAITING TO EXECUTE THE FRAGMENT LOG.
  1160.      * --------------------------------------------------------------------- */
  1161.     fragptr.i = lcpPtr.p->currentFragment.fragPtrI;
  1162.     ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
  1163.     fragptr.p->nextFrag = cfirstCompletedFragSr;
  1164.     cfirstCompletedFragSr = fragptr.i;
  1165.     if (cfirstWaitFragSr != RNIL) {
  1166.       jam();
  1167.       /* --------------------------------------------------------------------
  1168.        *  ANOTHER FRAGMENT IS WAITING FOR SYSTEM RESTART. RESTART THIS 
  1169.        *  FRAGMENT AS WELL.
  1170.        * -------------------------------------------------------------------- */
  1171.       fragptr.i = cfirstWaitFragSr;
  1172.       ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
  1173.       cfirstWaitFragSr = fragptr.p->nextFrag;
  1174.       /* --------------------------------------------------------------------
  1175.        *  RETRIEVE DATA FROM THE FRAGMENT RECORD.
  1176.        * -------------------------------------------------------------------- */
  1177.       ndbrequire(fragptr.p->srChkpnr < MAX_LCP_STORED);
  1178.       initLcpSr(signal,
  1179.                 fragptr.p->srChkpnr,
  1180.                 fragptr.p->lcpId[fragptr.p->srChkpnr],
  1181.                 fragptr.p->tabRef,
  1182.                 fragptr.p->fragId,
  1183.                 fragptr.i);
  1184.       signal->theData[0] = lcpPtr.i;
  1185.       signal->theData[1] = cownref;
  1186.       signal->theData[2] = lcpPtr.p->currentFragment.lcpFragOrd.lcpNo;
  1187.       signal->theData[3] = lcpPtr.p->currentFragment.lcpFragOrd.tableId;
  1188.       signal->theData[4] = lcpPtr.p->currentFragment.lcpFragOrd.fragmentId;
  1189.       sendSignal(fragptr.p->accBlockref, GSN_SR_FRAGIDREQ, signal, 5, JBB);
  1190.       return;
  1191.     } else {
  1192.       jam();
  1193.       /* --------------------------------------------------------------------
  1194.        *  NO MORE FRAGMENTS ARE WAITING FOR SYSTEM RESTART.
  1195.        * -------------------------------------------------------------------- */
  1196.       lcpPtr.p->lcpState = LcpRecord::LCP_IDLE;
  1197.       if (cstartRecReq == ZTRUE) {
  1198.         jam();
  1199. /* ----------------------------------------------------------------
  1200.          *  WE HAVE ALSO RECEIVED AN INDICATION THAT NO MORE FRAGMENTS 
  1201.  *  NEEDS RESTART.
  1202.  *  NOW IT IS TIME TO START EXECUTING THE UNDO LOG.
  1203.  * ----------------------------------------------------------------
  1204.  *  WE ARE NOW IN A POSITION TO ORDER TUP AND ACC TO START 
  1205.  *  EXECUTING THEIR UNDO LOGS. THIS MUST BE DONE BEFORE THE 
  1206.  *  FRAGMENT LOGS CAN BE EXECUTED.
  1207.  * ---------------------------------------------------------------- */
  1208.         csrExecUndoLogState = EULS_STARTED;
  1209.         signal->theData[0] = caccBlockref;
  1210.         signal->theData[1] = cownref;
  1211.         sendSignal(caccBlockref, GSN_START_RECREQ, signal, 2, JBB);
  1212.         signal->theData[0] = ctupBlockref;
  1213.         signal->theData[1] = cownref;
  1214.         sendSignal(ctupBlockref, GSN_START_RECREQ, signal, 2, JBB);
  1215.         return;
  1216.       } else {
  1217.         jam();
  1218. /* ----------------------------------------------------------------
  1219.  *  WE HAVE NOT RECEIVED ALL FRAGMENTS YET OR AT LEAST NOT WE 
  1220.  *  HAVE NOT RECEIVED THE START_RECREQ SIGNAL. EXIT AND WAIT 
  1221.  *  FOR MORE.
  1222.  * ---------------------------------------------------------------- */
  1223.         return;
  1224.       }//if
  1225.     }//if
  1226.   }//if
  1227.   /*---------------*/
  1228.   /*       ELSE    */
  1229.   /*-------------------------------------------------------------------------
  1230.    *       THE SYSTEM RESTART ON THIS FRAGMENT HAS NOT BEEN COMPLETED, 
  1231.    *       EXIT AND WAIT FOR MORE SIGNALS
  1232.    *-------------------------------------------------------------------------
  1233.    *       DO NOTHING, EXIT IS EXECUTED BELOW
  1234.    *------------------------------------------------------------------------- */
  1235.   return;
  1236. }//Dblqh::srCompletedLab()
  1237. /* ************> */
  1238. /*  TUP_SRREF  > */
  1239. /* ************> */
  1240. void Dblqh::execTUP_SRREF(Signal* signal) 
  1241. {
  1242.   jamEntry();
  1243.   terrorCode = signal->theData[1];
  1244.   systemErrorLab(signal);
  1245.   return;
  1246. }//Dblqh::execTUP_SRREF()
  1247. /* ***************> */
  1248. /*  START_RECREQ  > */
  1249. /* ***************> */
  1250. void Dblqh::execSTART_RECREQ(Signal* signal) 
  1251. {
  1252.   CRASH_INSERTION(5027);
  1253.   jamEntry();
  1254.   StartRecReq * const req = (StartRecReq*)&signal->theData[0];
  1255.   cmasterDihBlockref = req->senderRef;
  1256.   crestartOldestGci = req->keepGci;
  1257.   crestartNewestGci = req->lastCompletedGci;
  1258.   cnewestGci = req->newestGci;
  1259.   ndbrequire(req->receivingNodeId == cownNodeid);
  1260.   cnewestCompletedGci = cnewestGci;
  1261.   cstartRecReq = ZTRUE;
  1262.   for (logPartPtr.i = 0; logPartPtr.i < 4; logPartPtr.i++) {
  1263.     ptrAss(logPartPtr, logPartRecord);
  1264.     logPartPtr.p->logPartNewestCompletedGCI = cnewestCompletedGci;
  1265.   }//for
  1266.   /* ------------------------------------------------------------------------
  1267.    *   WE HAVE TO SET THE OLDEST AND THE NEWEST GLOBAL CHECKPOINT IDENTITY 
  1268.    *   THAT WILL SURVIVE THIS SYSTEM RESTART. THIS IS NEEDED SO THAT WE CAN
  1269.    *   SET THE LOG HEAD AND LOG TAIL PROPERLY BEFORE STARTING THE SYSTEM AGAIN.
  1270.    *   WE ALSO NEED TO SET CNEWEST_GCI TO ENSURE THAT LOG RECORDS ARE EXECUTED
  1271.    *   WITH A PROPER GCI.
  1272.    *------------------------------------------------------------------------ */
  1273.   if (cstartType == NodeState::ST_NODE_RESTART) {
  1274.     jam();
  1275.     signal->theData[0] = ZSR_PHASE3_START;
  1276.     signal->theData[1] = ZSR_PHASE2_COMPLETED;
  1277.     sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
  1278.     return;
  1279.   }//if
  1280.   if(cstartType == NodeState::ST_INITIAL_NODE_RESTART){
  1281.     jam();
  1282.     StartRecConf * conf = (StartRecConf*)signal->getDataPtrSend();
  1283.     conf->startingNodeId = getOwnNodeId();
  1284.     sendSignal(cmasterDihBlockref, GSN_START_RECCONF, signal, 
  1285.        StartRecConf::SignalLength, JBB);
  1286.     return;
  1287.   }//if
  1288.   if (cfirstWaitFragSr == RNIL) {
  1289.     /* ----------------------------------------------------------------------
  1290.      *      THERE ARE NO FRAGMENTS WAITING TO BE RESTARTED.
  1291.      * --------------------------------------------------------------------- */
  1292.     lcpPtr.i = 0;
  1293.     ptrAss(lcpPtr, lcpRecord);
  1294.     if (lcpPtr.p->lcpState == LcpRecord::LCP_IDLE) {
  1295.       jam();
  1296.       /* --------------------------------------------------------------------
  1297.        *    THERE ARE NO FRAGMENTS THAT ARE CURRENTLY PERFORMING THEIR 
  1298.        *    SYSTEM RESTART.
  1299.        * --------------------------------------------------------------------
  1300.        *    WE ARE NOW IN A POSITION TO ORDER TUP AND ACC TO START EXECUTING 
  1301.        *    THEIR UNDO LOGS. THIS MUST BE DONE BEFORE THE FRAGMENT LOGS 
  1302.        *    CAN BE EXECUTED.   
  1303.        * ------------------------------------------------------------------- */
  1304.       csrExecUndoLogState = EULS_STARTED;
  1305.       signal->theData[0] = caccBlockref;
  1306.       signal->theData[1] = cownref;
  1307.       sendSignal(caccBlockref, GSN_START_RECREQ, signal, 2, JBB);
  1308.       signal->theData[0] = ctupBlockref;
  1309.       signal->theData[1] = cownref;
  1310.       sendSignal(ctupBlockref, GSN_START_RECREQ, signal, 2, JBB);
  1311.     }//if
  1312.   }//if
  1313.   /* -----------------------------------------------------------------------
  1314.    *       EXIT AND WAIT FOR COMPLETION OF ALL FRAGMENTS.
  1315.    * ----------------------------------------------------------------------- */
  1316.   return;
  1317. }//Dblqh::execSTART_RECREQ()
  1318. /* ***************>> */
  1319. /*  START_RECCONF  > */
  1320. /* ***************>> */
  1321. void Dblqh::execSTART_RECCONF(Signal* signal) 
  1322. {
  1323.   jamEntry();
  1324.   BlockReference userRef = signal->theData[0];
  1325.   if (userRef == caccBlockref) {
  1326.     if (csrExecUndoLogState == EULS_STARTED) {
  1327.       jam();
  1328.       csrExecUndoLogState = EULS_ACC_COMPLETED;
  1329.     } else {
  1330.       ndbrequire(csrExecUndoLogState == EULS_TUP_COMPLETED);
  1331.       jam();
  1332.       csrExecUndoLogState = EULS_COMPLETED;
  1333.       /* --------------------------------------------------------------------
  1334.        *       START THE FIRST PHASE OF EXECUTION OF THE LOG.
  1335.        * ------------------------------------------------------------------- */
  1336.       startExecSr(signal);
  1337.     }//if
  1338.   } else {
  1339.     ndbrequire(userRef == ctupBlockref);
  1340.     if (csrExecUndoLogState == EULS_STARTED) {
  1341.       jam();
  1342.       csrExecUndoLogState = EULS_TUP_COMPLETED;
  1343.     } else {
  1344.       ndbrequire(csrExecUndoLogState == EULS_ACC_COMPLETED);
  1345.       jam();
  1346.       csrExecUndoLogState = EULS_COMPLETED;
  1347.       /* --------------------------------------------------------------------
  1348.        *       START THE FIRST PHASE OF EXECUTION OF THE LOG.
  1349.        * ------------------------------------------------------------------- */
  1350.       startExecSr(signal);
  1351.     }//if
  1352.   }//if
  1353.   return;
  1354. }//Dblqh::execSTART_RECCONF()
  1355. /* ***************> */
  1356. /*  START_RECREF  > */
  1357. /* ***************> */
  1358. void Dblqh::execSTART_RECREF(Signal* signal) 
  1359. {
  1360.   jamEntry();
  1361.   ndbrequire(false);
  1362. }//Dblqh::execSTART_RECREF()
  1363. /* ***************>> */
  1364. /*  START_EXEC_SR  > */
  1365. /* ***************>> */
  1366. void Dblqh::execSTART_EXEC_SR(Signal* signal) 
  1367. {
  1368.   FragrecordPtr prevFragptr;
  1369.   jamEntry();
  1370.   fragptr.i = signal->theData[0];
  1371.   prevFragptr.i = signal->theData[1];
  1372.   if (fragptr.i == RNIL) {
  1373.     jam();
  1374.     ndbrequire(cnoOfNodes < MAX_NDB_NODES);
  1375.     /* ----------------------------------------------------------------------
  1376.      *    NO MORE FRAGMENTS TO START EXECUTING THE LOG ON.
  1377.      *    SEND EXEC_SRREQ TO ALL LQH TO INDICATE THAT THIS NODE WILL 
  1378.      *    NOT REQUEST ANY MORE FRAGMENTS TO EXECUTE THE FRAGMENT LOG ON.
  1379.      * ---------------------------------------------------------------------- 
  1380.      *    WE NEED TO SEND THOSE SIGNALS EVEN IF WE HAVE NOT REQUESTED 
  1381.      *    ANY FRAGMENTS PARTICIPATE IN THIS PHASE.
  1382.      * --------------------------------------------------------------------- */
  1383.     for (Uint32 i = 0; i < cnoOfNodes; i++) {
  1384.       jam();
  1385.       if (cnodeStatus[i] == ZNODE_UP) {
  1386.         jam();
  1387.         ndbrequire(cnodeData[i] < MAX_NDB_NODES);
  1388.         BlockReference ref = calcLqhBlockRef(cnodeData[i]);
  1389.         signal->theData[0] = cownNodeid;
  1390.         sendSignal(ref, GSN_EXEC_SRREQ, signal, 1, JBB);
  1391.       }//if
  1392.     }//for
  1393.   } else {
  1394.     jam();
  1395.     ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
  1396.     if (fragptr.p->srNoLognodes > csrPhasesCompleted) {
  1397.       jam();
  1398.       Uint32 index = csrPhasesCompleted;
  1399.       arrGuard(index, 4);
  1400.       BlockReference ref = calcLqhBlockRef(fragptr.p->srLqhLognode[index]);
  1401.       fragptr.p->srStatus = Fragrecord::SS_STARTED;
  1402.       /* --------------------------------------------------------------------
  1403.        *  SINCE WE CAN HAVE SEVERAL LQH NODES PER FRAGMENT WE CALCULATE 
  1404.        *  THE LQH POINTER IN SUCH A WAY THAT WE CAN DEDUCE WHICH OF THE 
  1405.        *  LQH NODES THAT HAS RESPONDED WHEN EXEC_FRAGCONF IS RECEIVED.
  1406.        * ------------------------------------------------------------------- */
  1407.       ExecFragReq * const execFragReq = (ExecFragReq *)&signal->theData[0];
  1408.       execFragReq->userPtr = fragptr.i;
  1409.       execFragReq->userRef = cownref;
  1410.       execFragReq->tableId = fragptr.p->tabRef;
  1411.       execFragReq->fragId = fragptr.p->fragId;
  1412.       execFragReq->startGci = fragptr.p->srStartGci[index];
  1413.       execFragReq->lastGci = fragptr.p->srLastGci[index];
  1414.       sendSignal(ref, GSN_EXEC_FRAGREQ, signal, ExecFragReq::SignalLength, JBB);
  1415.       prevFragptr.i = fragptr.i;
  1416.       fragptr.i = fragptr.p->nextFrag;
  1417.     } else {
  1418.       jam();
  1419.       /* --------------------------------------------------------------------
  1420.        *  THIS FRAGMENT IS NOW FINISHED WITH THE SYSTEM RESTART. IT DOES 
  1421.        *  NOT NEED TO PARTICIPATE IN ANY MORE PHASES. REMOVE IT FROM THE 
  1422.        *  LIST OF COMPLETED FRAGMENTS TO EXECUTE THE LOG ON.
  1423.        *  ALSO SEND START_FRAGCONF TO DIH AND SET THE STATE TO ACTIVE ON THE
  1424.        *  FRAGMENT.
  1425.        * ------------------------------------------------------------------- */
  1426.       Uint32 next = fragptr.p->nextFrag;
  1427.       if (prevFragptr.i != RNIL) {
  1428.         jam();
  1429.         ptrCheckGuard(prevFragptr, cfragrecFileSize, fragrecord);
  1430.         prevFragptr.p->nextFrag = next;
  1431.       } else {
  1432.         jam();
  1433.         cfirstCompletedFragSr = next;
  1434.       }//if
  1435.       /**
  1436.        * Put fragment on list which has completed REDO log
  1437.        */
  1438.       fragptr.p->nextFrag = c_redo_log_complete_frags;
  1439.       c_redo_log_complete_frags = fragptr.i;
  1440.       
  1441.       fragptr.p->fragStatus = Fragrecord::FSACTIVE;
  1442.       fragptr.p->logFlag = Fragrecord::STATE_TRUE;
  1443.       signal->theData[0] = fragptr.p->srUserptr;
  1444.       signal->theData[1] = cownNodeid;
  1445.       sendSignal(fragptr.p->srBlockref, GSN_START_FRAGCONF, signal, 2, JBB);
  1446.       /* --------------------------------------------------------------------
  1447.        *  WE HAVE TO ENSURE THAT THIS FRAGMENT IS NOT PUT BACK ON THE LIST BY
  1448.        *  MISTAKE. WE DO THIS BY ALSO REMOVING IT AS PREVIOUS IN START_EXEC_SR
  1449.        *  THIS IS PERFORMED BY KEEPING PREV_FRAGPTR AS PREV_FRAGPTR BUT MOVING
  1450.        *  FRAGPTR TO THE NEXT FRAGMENT IN THE LIST.
  1451.        * ------------------------------------------------------------------- */
  1452.       fragptr.i = next;
  1453.     }//if
  1454.     signal->theData[0] = fragptr.i;
  1455.     signal->theData[1] = prevFragptr.i;
  1456.     sendSignal(cownref, GSN_START_EXEC_SR, signal, 2, JBB);
  1457.   }//if
  1458.   return;
  1459. }//Dblqh::execSTART_EXEC_SR()
  1460. /* ***************> */
  1461. /*  EXEC_FRAGREQ  > */
  1462. /* ***************> */
  1463. /* --------------------------------------------------------------------------
  1464.  *  THIS SIGNAL IS USED TO REQUEST THAT A FRAGMENT PARTICIPATES IN EXECUTING
  1465.  *  THE LOG IN THIS NODE.
  1466.  * ------------------------------------------------------------------------- */
  1467. void Dblqh::execEXEC_FRAGREQ(Signal* signal) 
  1468. {
  1469.   ExecFragReq * const execFragReq = (ExecFragReq *)&signal->theData[0];
  1470.   jamEntry();
  1471.   tabptr.i = execFragReq->tableId;
  1472.   Uint32 fragId = execFragReq->fragId;
  1473.   ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
  1474.   if (!getFragmentrec(signal, fragId)) {
  1475.     jam();
  1476.     if (!insertFragrec(signal, fragId)) {
  1477.       jam();
  1478.       sendExecFragRefLab(signal);
  1479.       return;
  1480.     }//if    
  1481.     initFragrec(signal, tabptr.i, fragId, ZLOG_NODE);
  1482.     fragptr.p->execSrStatus = Fragrecord::ACTIVE_REMOVE_AFTER;
  1483.   } else {
  1484.     jam();
  1485.     if (fragptr.p->execSrStatus == Fragrecord::ACTIVE_REMOVE_AFTER) {
  1486.       jam();
  1487.       fragptr.p->execSrStatus = Fragrecord::ACTIVE_REMOVE_AFTER;
  1488.     } else {
  1489.       jam();
  1490.     }//if
  1491.   }//if
  1492.   ndbrequire(fragptr.p->execSrNoReplicas < 4);
  1493.   fragptr.p->execSrBlockref[fragptr.p->execSrNoReplicas] = execFragReq->userRef;
  1494.   fragptr.p->execSrUserptr[fragptr.p->execSrNoReplicas] = execFragReq->userPtr;
  1495.   fragptr.p->execSrStartGci[fragptr.p->execSrNoReplicas] = execFragReq->startGci;
  1496.   fragptr.p->execSrLastGci[fragptr.p->execSrNoReplicas] = execFragReq->lastGci;
  1497.   fragptr.p->execSrStatus = Fragrecord::ACTIVE;
  1498.   fragptr.p->execSrNoReplicas++;
  1499.   cnoFragmentsExecSr++;
  1500.   return;
  1501. }//Dblqh::execEXEC_FRAGREQ()
  1502. void Dblqh::sendExecFragRefLab(Signal* signal) 
  1503. {
  1504.   ExecFragReq * const execFragReq = (ExecFragReq *)&signal->theData[0];
  1505.   BlockReference retRef = execFragReq->userRef;
  1506.   Uint32 retPtr = execFragReq->userPtr;
  1507.   signal->theData[0] = retPtr;
  1508.   signal->theData[1] = terrorCode;
  1509.   sendSignal(retRef, GSN_EXEC_FRAGREF, signal, 2, JBB);
  1510.   return;
  1511. }//Dblqh::sendExecFragRefLab()
  1512. /* ***************>> */
  1513. /*  EXEC_FRAGCONF  > */
  1514. /* ***************>> */
  1515. void Dblqh::execEXEC_FRAGCONF(Signal* signal) 
  1516. {
  1517.   jamEntry();
  1518.   fragptr.i = signal->theData[0];
  1519.   ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
  1520.   fragptr.p->srStatus = Fragrecord::SS_COMPLETED;
  1521.   return;
  1522. }//Dblqh::execEXEC_FRAGCONF()
  1523. /* ***************> */
  1524. /*  EXEC_FRAGREF  > */
  1525. /* ***************> */
  1526. void Dblqh::execEXEC_FRAGREF(Signal* signal) 
  1527. {
  1528.   jamEntry();
  1529.   terrorCode = signal->theData[1];
  1530.   systemErrorLab(signal);
  1531.   return;
  1532. }//Dblqh::execEXEC_FRAGREF()
  1533. /* *************** */
  1534. /*  EXEC_SRCONF  > */
  1535. /* *************** */
  1536. void Dblqh::execEXEC_SRCONF(Signal* signal) 
  1537. {
  1538.   jamEntry();
  1539.   Uint32 nodeId = signal->theData[0];
  1540.   arrGuard(nodeId, MAX_NDB_NODES);
  1541.   cnodeExecSrState[nodeId] = ZEXEC_SR_COMPLETED;
  1542.   ndbrequire(cnoOfNodes < MAX_NDB_NODES);
  1543.   for (Uint32 i = 0; i < cnoOfNodes; i++) {
  1544.     jam();
  1545.     if (cnodeStatus[i] == ZNODE_UP) {
  1546.       jam();
  1547.       nodeId = cnodeData[i];
  1548.       arrGuard(nodeId, MAX_NDB_NODES);
  1549.       if (cnodeExecSrState[nodeId] != ZEXEC_SR_COMPLETED) {
  1550.         jam();
  1551. /* ------------------------------------------------------------------
  1552.  *  ALL NODES HAVE NOT REPORTED COMPLETION OF EXECUTING FRAGMENT 
  1553.  *  LOGS YET.
  1554.  * ----------------------------------------------------------------- */
  1555.         return;
  1556.       }//if
  1557.     }//if
  1558.   }//for
  1559.   /* ------------------------------------------------------------------------
  1560.    *  CLEAR NODE SYSTEM RESTART EXECUTION STATE TO PREPARE FOR NEXT PHASE OF
  1561.    *  LOG EXECUTION.
  1562.    * ----------------------------------------------------------------------- */
  1563.   for (nodeId = 0; nodeId < MAX_NDB_NODES; nodeId++) {
  1564.     cnodeExecSrState[nodeId] = ZSTART_SR;
  1565.   }//for
  1566.   /* ------------------------------------------------------------------------
  1567.    *  NOW CHECK IF ALL FRAGMENTS IN THIS PHASE HAVE COMPLETED. IF SO START THE
  1568.    *  NEXT PHASE.
  1569.    * ----------------------------------------------------------------------- */
  1570.   fragptr.i = cfirstCompletedFragSr;
  1571.   if (fragptr.i == RNIL) {
  1572.     jam();
  1573.     execSrCompletedLab(signal);
  1574.     return;
  1575.   }//if
  1576.   do {
  1577.     jam();
  1578.     ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
  1579.     ndbrequire(fragptr.p->srStatus == Fragrecord::SS_COMPLETED);
  1580.     fragptr.i = fragptr.p->nextFrag;
  1581.   } while (fragptr.i != RNIL);
  1582.   execSrCompletedLab(signal);
  1583.   return;
  1584. }//Dblqh::execEXEC_SRCONF()
  1585. void Dblqh::execSrCompletedLab(Signal* signal) 
  1586. {
  1587.   csrPhasesCompleted++;
  1588.   /* ------------------------------------------------------------------------
  1589.    *  ALL FRAGMENTS WERE COMPLETED. THIS PHASE IS COMPLETED. IT IS NOW TIME TO
  1590.    *  START THE NEXT PHASE.
  1591.    * ----------------------------------------------------------------------- */
  1592.   if (csrPhasesCompleted >= 4) {
  1593.     jam();
  1594.     /* ----------------------------------------------------------------------
  1595.      *  THIS WAS THE LAST PHASE. WE HAVE NOW COMPLETED THE EXECUTION THE 
  1596.      *  FRAGMENT LOGS IN ALL NODES. BEFORE WE SEND START_RECCONF TO THE 
  1597.      *  MASTER DIH TO INDICATE A COMPLETED SYSTEM RESTART IT IS NECESSARY 
  1598.      *  TO FIND THE HEAD AND THE TAIL OF THE LOG WHEN NEW OPERATIONS START 
  1599.      *  TO COME AGAIN.
  1600.      * 
  1601.      * THE FIRST STEP IS TO FIND THE HEAD AND TAIL MBYTE OF EACH LOG PART.
  1602.      * TO DO THIS WE REUSE THE CONTINUEB SIGNAL SR_LOG_LIMITS. THEN WE 
  1603.      * HAVE TO FIND THE ACTUAL PAGE NUMBER AND PAGE INDEX WHERE TO 
  1604.      * CONTINUE WRITING THE LOG AFTER THE SYSTEM RESTART.
  1605.      * --------------------------------------------------------------------- */
  1606.     for (logPartPtr.i = 0; logPartPtr.i < 4; logPartPtr.i++) {
  1607.       jam();
  1608.       ptrAss(logPartPtr, logPartRecord);
  1609.       logPartPtr.p->logPartState = LogPartRecord::SR_FOURTH_PHASE_STARTED;
  1610.       logPartPtr.p->logLastGci = crestartNewestGci;
  1611.       logPartPtr.p->logStartGci = crestartOldestGci;
  1612.       logPartPtr.p->logExecState = LogPartRecord::LES_SEARCH_STOP;
  1613.       if (logPartPtr.p->headFileNo == ZNIL) {
  1614.         jam();
  1615. /* -----------------------------------------------------------------
  1616.  *  IF WE HAVEN'T FOUND ANY HEAD OF THE LOG THEN WE ARE IN SERIOUS 
  1617.  *  PROBLEM.  THIS SHOULD NOT OCCUR. IF IT OCCURS ANYWAY THEN WE 
  1618.  *  HAVE TO FIND A CURE FOR THIS PROBLEM.
  1619.  * ----------------------------------------------------------------- */
  1620.         systemErrorLab(signal);
  1621.         return;
  1622.       }//if
  1623.       signal->theData[0] = ZSR_LOG_LIMITS;
  1624.       signal->theData[1] = logPartPtr.i;
  1625.       signal->theData[2] = logPartPtr.p->lastLogfile;
  1626.       signal->theData[3] = logPartPtr.p->lastMbyte;
  1627.       sendSignal(cownref, GSN_CONTINUEB, signal, 4, JBB);
  1628.     }//for
  1629.     return;
  1630.   } else {
  1631.     jam();
  1632.     /* ----------------------------------------------------------------------
  1633.      *   THERE ARE YET MORE PHASES TO RESTART.
  1634.      *   WE MUST INITIALISE DATA FOR NEXT PHASE AND SEND START SIGNAL.
  1635.      * --------------------------------------------------------------------- */
  1636.     startExecSr(signal);
  1637.   }//if
  1638.   return;
  1639. }//Dblqh::execSrCompletedLab()
  1640. /* ************>> */
  1641. /*  EXEC_SRREQ  > */
  1642. /* ************>> */
  1643. void Dblqh::execEXEC_SRREQ(Signal* signal) 
  1644. {
  1645.   jamEntry();
  1646.   Uint32 nodeId = signal->theData[0];
  1647.   ndbrequire(nodeId < MAX_NDB_NODES);
  1648.   cnodeSrState[nodeId] = ZEXEC_SR_COMPLETED;
  1649.   ndbrequire(cnoOfNodes < MAX_NDB_NODES);
  1650.   for (Uint32 i = 0; i < cnoOfNodes; i++) {
  1651.     jam();
  1652.     if (cnodeStatus[i] == ZNODE_UP) {
  1653.       jam();
  1654.       nodeId = cnodeData[i];
  1655.       if (cnodeSrState[nodeId] != ZEXEC_SR_COMPLETED) {
  1656.         jam();
  1657. /* ------------------------------------------------------------------
  1658.  *  ALL NODES HAVE NOT REPORTED COMPLETION OF SENDING EXEC_FRAGREQ YET.
  1659.  * ----------------------------------------------------------------- */
  1660.         return;
  1661.       }//if
  1662.     }//if
  1663.   }//for
  1664.   /* ------------------------------------------------------------------------
  1665.    *  CLEAR NODE SYSTEM RESTART STATE TO PREPARE FOR NEXT PHASE OF LOG 
  1666.    *  EXECUTION
  1667.    * ----------------------------------------------------------------------- */
  1668.   for (nodeId = 0; nodeId < MAX_NDB_NODES; nodeId++) {
  1669.     cnodeSrState[nodeId] = ZSTART_SR;
  1670.   }//for
  1671.   if (csrPhasesCompleted != 0) {
  1672.     /* ----------------------------------------------------------------------
  1673.      *       THE FIRST PHASE MUST ALWAYS EXECUTE THE LOG.
  1674.      * --------------------------------------------------------------------- */
  1675.     if (cnoFragmentsExecSr == 0) {
  1676.       jam();
  1677.       /* --------------------------------------------------------------------
  1678.        *   THERE WERE NO FRAGMENTS THAT NEEDED TO EXECUTE THE LOG IN THIS PHASE.
  1679.        * ------------------------------------------------------------------- */
  1680.       srPhase3Comp(signal);
  1681.       return;
  1682.     }//if
  1683.   }//if
  1684.   /* ------------------------------------------------------------------------
  1685.    *  NOW ALL NODES HAVE SENT ALL EXEC_FRAGREQ. NOW WE CAN START EXECUTING THE
  1686.    *  LOG FROM THE MINIMUM GCI NEEDED UNTIL THE MAXIMUM GCI NEEDED.
  1687.    *
  1688.    *  WE MUST FIRST CHECK IF THE FIRST PHASE OF THE SYSTEM RESTART HAS BEEN
  1689.    *  COMPLETED. THIS HANDLING IS PERFORMED IN THE FILE SYSTEM MODULE
  1690.    * ----------------------------------------------------------------------- */
  1691.   signal->theData[0] = ZSR_PHASE3_START;
  1692.   signal->theData[1] = ZSR_PHASE2_COMPLETED;
  1693.   sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
  1694.   return;
  1695. }//Dblqh::execEXEC_SRREQ()
  1696. /* ######################################################################### */
  1697. /*       SYSTEM RESTART PHASE THREE MODULE                                   */
  1698. /*       THIS MODULE IS A SUB-MODULE OF THE FILE SYSTEM HANDLING.            */
  1699. /*                                                                           */
  1700. /* THIS MODULE IS CONCERNED WITH EXECUTING THE FRAGMENT LOG. IT DOES ALSO    */
  1701. /* CONTAIN SIGNAL RECEPTIONS LQHKEYCONF AND LQHKEYREF SINCE LQHKEYREQ IS USED*/
  1702. /* TO EXECUTE THE LOG RECORDS.                                               */
  1703. /*                                                                           */
  1704. /* BEFORE IT STARTS IT HAS BEEN DECIDED WHERE TO START AND WHERE TO STOP     */
  1705. /* READING THE FRAGMENT LOG BY USING THE INFORMATION ABOUT GCI DISCOVERED IN */
  1706. /* PHASE ONE OF THE SYSTEM RESTART.                                          */
  1707. /* ######################################################################### */
  1708. /*---------------------------------------------------------------------------*/
  1709. /* PHASE THREE OF THE SYSTEM RESTART CAN NOW START. ONE OF THE PHASES HAVE   */
  1710. /* COMPLETED.                                                                */
  1711. /*---------------------------------------------------------------------------*/
  1712. void Dblqh::srPhase3Start(Signal* signal) 
  1713. {
  1714.   UintR tsrPhaseStarted;
  1715.   
  1716.   jamEntry();
  1717.   tsrPhaseStarted = signal->theData[0];
  1718.   if (csrPhaseStarted == ZSR_NO_PHASE_STARTED) {
  1719.     jam();
  1720.     csrPhaseStarted = tsrPhaseStarted;
  1721.     if (cstartType == NodeState::ST_NODE_RESTART) {
  1722.       ndbrequire(cinitialStartOngoing == ZTRUE);
  1723.       cinitialStartOngoing = ZFALSE;
  1724.       checkStartCompletedLab(signal);
  1725.     }//if
  1726.     return;
  1727.   }//if  
  1728.   ndbrequire(csrPhaseStarted != tsrPhaseStarted);
  1729.   ndbrequire(csrPhaseStarted != ZSR_BOTH_PHASES_STARTED);
  1730.   csrPhaseStarted = ZSR_BOTH_PHASES_STARTED;
  1731.   for (logPartPtr.i = 0; logPartPtr.i < 4; logPartPtr.i++) {
  1732.     jam();
  1733.     ptrAss(logPartPtr, logPartRecord);
  1734.     logPartPtr.p->logPartState = LogPartRecord::SR_THIRD_PHASE_STARTED;
  1735.     logPartPtr.p->logStartGci = (UintR)-1;
  1736.     if (csrPhasesCompleted == 0) {
  1737.       jam();
  1738.       /* -------------------------------------------------------------------- 
  1739.        *  THE FIRST PHASE WE MUST ENSURE THAT IT REACHES THE END OF THE LOG.
  1740.        * ------------------------------------------------------------------- */
  1741.       logPartPtr.p->logLastGci = crestartNewestGci;
  1742.     } else {
  1743.       jam();
  1744.       logPartPtr.p->logLastGci = 2;
  1745.     }//if
  1746.   }//for
  1747.   if (cstartType == NodeState::ST_NODE_RESTART) {
  1748.     jam();
  1749.     /* ----------------------------------------------------------------------
  1750.      *  FOR A NODE RESTART WE HAVE NO FRAGMENTS DEFINED YET. 
  1751.      *  THUS WE CAN SKIP THAT PART
  1752.      * --------------------------------------------------------------------- */
  1753.     signal->theData[0] = ZSR_GCI_LIMITS;
  1754.     signal->theData[1] = RNIL;
  1755.     sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
  1756.   } else {
  1757.     jam();
  1758.     signal->theData[0] = ZSR_GCI_LIMITS;
  1759.     signal->theData[1] = 0;
  1760.     sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
  1761.   }//if
  1762.   return;
  1763. }//Dblqh::srPhase3Start()
  1764. /* --------------------------------------------------------------------------
  1765.  *   WE NOW WE NEED TO FIND THE LIMITS WITHIN WHICH TO EXECUTE 
  1766.  *   THE FRAGMENT LOG
  1767.  * ------------------------------------------------------------------------- */
  1768. void Dblqh::srGciLimits(Signal* signal) 
  1769. {
  1770.   LogPartRecordPtr tmpLogPartPtr;
  1771.   jamEntry();
  1772.   fragptr.i = signal->theData[0];
  1773.   Uint32 loopCount = 0;
  1774.   logPartPtr.i = 0;
  1775.   ptrAss(logPartPtr, logPartRecord);
  1776.   while (fragptr.i < cfragrecFileSize) {
  1777.     jam();
  1778.     ptrAss(fragptr, fragrecord);
  1779.     if (fragptr.p->execSrStatus != Fragrecord::IDLE) {
  1780.       jam();
  1781.       ndbrequire(fragptr.p->execSrNoReplicas - 1 < 4);
  1782.       for (Uint32 i = 0; i < fragptr.p->execSrNoReplicas; i++) {
  1783.         jam();
  1784.         if (fragptr.p->execSrStartGci[i] < logPartPtr.p->logStartGci) {
  1785.           jam();
  1786.           logPartPtr.p->logStartGci = fragptr.p->execSrStartGci[i];
  1787.         }//if
  1788.         if (fragptr.p->execSrLastGci[i] > logPartPtr.p->logLastGci) {
  1789.           jam();
  1790.           logPartPtr.p->logLastGci = fragptr.p->execSrLastGci[i];
  1791.         }//if
  1792.       }//for
  1793.     }//if
  1794.     loopCount++;
  1795.     if (loopCount > 20) {
  1796.       jam();
  1797.       signal->theData[0] = ZSR_GCI_LIMITS;
  1798.       signal->theData[1] = fragptr.i + 1;
  1799.       sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
  1800.       return;
  1801.     } else {
  1802.       jam();
  1803.       fragptr.i++;
  1804.     }//if
  1805.   }//while
  1806.   if (logPartPtr.p->logStartGci == (UintR)-1) {
  1807.     jam();
  1808.       /* --------------------------------------------------------------------
  1809.        *  THERE WERE NO FRAGMENTS TO INSTALL WE WILL EXECUTE THE LOG AS 
  1810.        *  SHORT AS POSSIBLE TO REACH THE END OF THE LOG. THIS WE DO BY 
  1811.        *  STARTING AT THE STOP GCI.
  1812.        * ------------------------------------------------------------------- */
  1813.     logPartPtr.p->logStartGci = logPartPtr.p->logLastGci;
  1814.   }//if
  1815.   for (tmpLogPartPtr.i = 1; tmpLogPartPtr.i < 4; tmpLogPartPtr.i++) {
  1816.     ptrAss(tmpLogPartPtr, logPartRecord);
  1817.     tmpLogPartPtr.p->logStartGci = logPartPtr.p->logStartGci;
  1818.     tmpLogPartPtr.p->logLastGci = logPartPtr.p->logLastGci;
  1819.   }//for
  1820.   for (logPartPtr.i = 0; logPartPtr.i < 4; logPartPtr.i++) {
  1821.     jam();
  1822.     ptrAss(logPartPtr, logPartRecord);
  1823.     logPartPtr.p->logExecState = LogPartRecord::LES_SEARCH_STOP;
  1824.     signal->theData[0] = ZSR_LOG_LIMITS;
  1825.     signal->theData[1] = logPartPtr.i;
  1826.     signal->theData[2] = logPartPtr.p->lastLogfile;
  1827.     signal->theData[3] = logPartPtr.p->lastMbyte;
  1828.     sendSignal(cownref, GSN_CONTINUEB, signal, 4, JBB);
  1829.   }//for
  1830. }//Dblqh::srGciLimits()
  1831. /* --------------------------------------------------------------------------
  1832.  *       IT IS NOW TIME TO FIND WHERE TO START EXECUTING THE LOG.
  1833.  *       THIS SIGNAL IS SENT FOR EACH LOG PART AND STARTS THE EXECUTION 
  1834.  *       OF THE LOG FOR THIS PART.
  1835.  *-------------------------------------------------------------------------- */
  1836. void Dblqh::srLogLimits(Signal* signal) 
  1837. {
  1838.   Uint32 tlastPrepRef;
  1839.   Uint32 tmbyte;
  1840.   jamEntry();
  1841.   logPartPtr.i = signal->theData[0];
  1842.   ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
  1843.   logFilePtr.i = signal->theData[1];
  1844.   ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
  1845.   tmbyte = signal->theData[2];
  1846.   Uint32 loopCount = 0;
  1847.   /* ------------------------------------------------------------------------
  1848.    *   WE ARE SEARCHING FOR THE START AND STOP MBYTE OF THE LOG THAT IS TO BE
  1849.    *   EXECUTED.
  1850.    * ----------------------------------------------------------------------- */
  1851.   while(true) {
  1852.     ndbrequire(tmbyte < 16);
  1853.     if (logPartPtr.p->logExecState == LogPartRecord::LES_SEARCH_STOP) {
  1854.       if (logFilePtr.p->logMaxGciCompleted[tmbyte] < logPartPtr.p->logLastGci) {
  1855.         jam();
  1856.       /* --------------------------------------------------------------------
  1857.        *  WE ARE STEPPING BACKWARDS FROM MBYTE TO MBYTE. THIS IS THE FIRST 
  1858.        *  MBYTE WHICH IS TO BE INCLUDED IN THE LOG EXECUTION. THE STOP GCI 
  1859.        *  HAS NOT BEEN COMPLETED BEFORE THIS MBYTE. THUS THIS MBYTE HAVE 
  1860.        *  TO BE EXECUTED.
  1861.        * ------------------------------------------------------------------- */
  1862.         logPartPtr.p->stopLogfile = logFilePtr.i;
  1863.         logPartPtr.p->stopMbyte = tmbyte;
  1864.         logPartPtr.p->logExecState = LogPartRecord::LES_SEARCH_START;
  1865.       }//if
  1866.     }//if
  1867.   /* ------------------------------------------------------------------------
  1868.    *  WHEN WE HAVEN'T FOUND THE STOP MBYTE IT IS NOT NECESSARY TO LOOK FOR THE
  1869.    *  START MBYTE. THE REASON IS THE FOLLOWING LOGIC CHAIN: 
  1870.    *    MAX_GCI_STARTED >= MAX_GCI_COMPLETED >= LAST_GCI >= START_GCI
  1871.    *  THUS MAX_GCI_STARTED >= START_GCI. THUS MAX_GCI_STARTED < START_GCI CAN
  1872.    *  NOT BE TRUE AS WE WILL CHECK OTHERWISE.
  1873.    * ----------------------------------------------------------------------- */
  1874.     if (logPartPtr.p->logExecState == LogPartRecord::LES_SEARCH_START) {
  1875.       if (logFilePtr.p->logMaxGciStarted[tmbyte] < logPartPtr.p->logStartGci) {
  1876.         jam();
  1877.       /* --------------------------------------------------------------------
  1878.        *  WE HAVE NOW FOUND THE START OF THE EXECUTION OF THE LOG. 
  1879.        *  WE STILL HAVE TO MOVE IT BACKWARDS TO ALSO INCLUDE THE 
  1880.        *  PREPARE RECORDS WHICH WERE STARTED IN A PREVIOUS MBYTE.
  1881.        * ------------------------------------------------------------------- */
  1882.         tlastPrepRef = logFilePtr.p->logLastPrepRef[tmbyte];
  1883.         logPartPtr.p->startMbyte = tlastPrepRef & 65535;
  1884.         LogFileRecordPtr locLogFilePtr;
  1885.         findLogfile(signal, tlastPrepRef >> 16, logPartPtr, &locLogFilePtr);
  1886.         logPartPtr.p->startLogfile = locLogFilePtr.i;
  1887.         logPartPtr.p->logExecState = LogPartRecord::LES_EXEC_LOG;
  1888.       }//if
  1889.     }//if
  1890.     if (logPartPtr.p->logExecState != LogPartRecord::LES_EXEC_LOG) {
  1891.       if (tmbyte == 0) {
  1892.         jam();
  1893.         tmbyte = ZNO_MBYTES_IN_FILE - 1;
  1894.         logFilePtr.i = logFilePtr.p->prevLogFile;
  1895.         ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
  1896.       } else {
  1897.         jam();
  1898.         tmbyte--;
  1899.       }//if
  1900.       if (logPartPtr.p->lastLogfile == logFilePtr.i) {
  1901.         ndbrequire(logPartPtr.p->lastMbyte != tmbyte);
  1902.       }//if
  1903.       if (loopCount > 20) {
  1904.         jam();
  1905.         signal->theData[0] = ZSR_LOG_LIMITS;
  1906.         signal->theData[1] = logPartPtr.i;
  1907.         signal->theData[2] = logFilePtr.i;
  1908.         signal->theData[3] = tmbyte;
  1909.         sendSignal(cownref, GSN_CONTINUEB, signal, 4, JBB);
  1910.         return;
  1911.       }//if
  1912.       loopCount++;
  1913.     } else {
  1914.       jam();
  1915.       break;
  1916.     }//if
  1917.   }//while
  1918.   /* ------------------------------------------------------------------------
  1919.    *  WE HAVE NOW FOUND BOTH THE START AND THE STOP OF THE LOG. NOW START
  1920.    *  EXECUTING THE LOG. THE FIRST ACTION IS TO OPEN THE LOG FILE WHERE TO
  1921.    *  START EXECUTING THE LOG.
  1922.    * ----------------------------------------------------------------------- */
  1923.   if (logPartPtr.p->logPartState == LogPartRecord::SR_THIRD_PHASE_STARTED) {
  1924.     jam();
  1925.     logFilePtr.i = logPartPtr.p->startLogfile;
  1926.     ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
  1927.     logFilePtr.p->logFileStatus = LogFileRecord::OPEN_EXEC_SR_START;
  1928.     openFileRw(signal, logFilePtr);
  1929.   } else {
  1930.     jam();
  1931.     ndbrequire(logPartPtr.p->logPartState == LogPartRecord::SR_FOURTH_PHASE_STARTED);
  1932.       /* --------------------------------------------------------------------
  1933.        *  WE HAVE NOW FOUND THE TAIL MBYTE IN THE TAIL FILE. 
  1934.        *  SET THOSE PARAMETERS IN THE LOG PART. 
  1935.        *  WE HAVE ALSO FOUND THE HEAD MBYTE. WE STILL HAVE TO SEARCH  
  1936.        *  FOR THE PAGE NUMBER AND PAGE INDEX WHERE TO SET THE HEAD.
  1937.        * ------------------------------------------------------------------- */
  1938.     logFilePtr.i = logPartPtr.p->startLogfile;
  1939.     ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
  1940.     logPartPtr.p->logTailFileNo = logFilePtr.p->fileNo;
  1941.     logPartPtr.p->logTailMbyte = logPartPtr.p->startMbyte;
  1942.       /* --------------------------------------------------------------------
  1943.        *  THE HEAD WE ACTUALLY FOUND DURING EXECUTION OF LOG SO WE USE 
  1944.        *  THIS INFO HERE RATHER THAN THE MBYTE WE FOUND TO BE THE HEADER.
  1945.        * ------------------------------------------------------------------- */
  1946.     LogFileRecordPtr locLogFilePtr;
  1947.     findLogfile(signal, logPartPtr.p->headFileNo, logPartPtr, &locLogFilePtr);
  1948.     locLogFilePtr.p->logFileStatus = LogFileRecord::OPEN_SR_FOURTH_PHASE;
  1949.     openFileRw(signal, locLogFilePtr);
  1950.   }//if
  1951.   return;
  1952. }//Dblqh::srLogLimits()
  1953. void Dblqh::openExecSrStartLab(Signal* signal) 
  1954. {
  1955.   logPartPtr.p->currentLogfile = logFilePtr.i;
  1956.   logFilePtr.p->currentMbyte = logPartPtr.p->startMbyte;
  1957.   /* ------------------------------------------------------------------------
  1958.    *     WE NEED A TC CONNECT RECORD TO HANDLE EXECUTION OF LOG RECORDS.
  1959.    * ------------------------------------------------------------------------ */
  1960.   seizeTcrec();
  1961.   logPartPtr.p->logTcConrec = tcConnectptr.i;
  1962.   /* ------------------------------------------------------------------------
  1963.    *   THE FIRST LOG RECORD TO EXECUTE IS ALWAYS AT A NEW MBYTE.
  1964.    *   SET THE NUMBER OF PAGES IN THE MAIN MEMORY BUFFER TO ZERO AS AN INITIAL
  1965.    *   VALUE. THIS VALUE WILL BE UPDATED AND ENSURED THAT IT RELEASES PAGES IN
  1966.    *   THE SUBROUTINE READ_EXEC_SR.
  1967.    * ----------------------------------------------------------------------- */
  1968.   logPartPtr.p->mmBufferSize = 0;
  1969.   readExecSrNewMbyte(signal);
  1970.   return;
  1971. }//Dblqh::openExecSrStartLab()
  1972. /* ---------------------------------------------------------------------------
  1973.  *  WE WILL ALWAYS ENSURE THAT WE HAVE AT LEAST 16 KBYTE OF LOG PAGES WHEN WE
  1974.  *  START READING A LOG RECORD. THE ONLY EXCEPTION IS WHEN WE COME CLOSE TO A 
  1975.  *  MBYTE BOUNDARY. SINCE WE KNOW THAT LOG RECORDS ARE NEVER WRITTEN ACROSS A 
  1976.  *  MBYTE BOUNDARY THIS IS NOT A PROBLEM.
  1977.  *
  1978.  *  WE START BY READING 64 KBYTE BEFORE STARTING TO EXECUTE THE LOG RECORDS.
  1979.  *  WHEN WE COME BELOW 64 KBYTE WE READ ANOTHER SET OF LOG PAGES. WHEN WE 
  1980.  *  GO BELOW 16 KBYTE WE WAIT UNTIL THE READ PAGES HAVE ENTERED THE BLOCK.
  1981.  * ------------------------------------------------------------------------- */
  1982. /* --------------------------------------------------------------------------
  1983.  *       NEW PAGES FROM LOG FILE DURING EXECUTION OF LOG HAS ARRIVED.
  1984.  * ------------------------------------------------------------------------- */
  1985. void Dblqh::readExecSrLab(Signal* signal) 
  1986. {
  1987.   buildLinkedLogPageList(signal);
  1988.   /* ------------------------------------------------------------------------
  1989.    *   WE NEED TO SET THE CURRENT PAGE INDEX OF THE FIRST PAGE SINCE IT CAN BE 
  1990.    *   USED IMMEDIATELY WITHOUT ANY OTHER INITIALISATION. THE REST OF THE PAGES
  1991.    *   WILL BE INITIALISED BY READ_LOGWORD.
  1992.    * ----------------------------------------------------------------------- */
  1993.   logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = ZPAGE_HEADER_SIZE;
  1994.   if (logPartPtr.p->logExecState == 
  1995.       LogPartRecord::LES_WAIT_READ_EXEC_SR_NEW_MBYTE) {
  1996.     jam();
  1997.     /* ----------------------------------------------------------------------
  1998.      *  THIS IS THE FIRST READ DURING THE EXECUTION OF THIS MBYTE. SET THE 
  1999.      *  NEW CURRENT LOG PAGE TO THE FIRST OF THESE PAGES. CHANGE 
  2000.      *  LOG_EXEC_STATE TO ENSURE THAT WE START EXECUTION OF THE LOG.
  2001.      * --------------------------------------------------------------------- */
  2002.     logFilePtr.p->currentFilepage = logFilePtr.p->currentMbyte * 
  2003.                                     ZPAGES_IN_MBYTE;
  2004.     logPartPtr.p->prevFilepage = logFilePtr.p->currentFilepage;
  2005.     logFilePtr.p->currentLogpage = lfoPtr.p->firstLfoPage;
  2006.     logPartPtr.p->prevLogpage = logFilePtr.p->currentLogpage;
  2007.   }//if
  2008.   moveToPageRef(signal);
  2009.   releaseLfo(signal);
  2010.   /* ------------------------------------------------------------------------
  2011.    *  NOW WE HAVE COMPLETED THE RECEPTION OF THESE PAGES. 
  2012.    *  NOW CHECK IF WE NEED TO READ MORE PAGES.
  2013.    * ----------------------------------------------------------------------- */
  2014.   checkReadExecSr(signal);
  2015.   if (logPartPtr.p->logExecState == LogPartRecord::LES_EXEC_LOG) {
  2016.     jam();
  2017.     signal->theData[0] = ZEXEC_SR;
  2018.     signal->theData[1] = logPartPtr.i;
  2019.     sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
  2020.     return;
  2021.   }//if
  2022.   return;
  2023. }//Dblqh::readExecSrLab()
  2024. void Dblqh::openExecSrNewMbyteLab(Signal* signal) 
  2025. {
  2026.   readExecSrNewMbyte(signal);
  2027.   return;
  2028. }//Dblqh::openExecSrNewMbyteLab()
  2029. void Dblqh::closeExecSrLab(Signal* signal) 
  2030. {
  2031.   LogFileRecordPtr locLogFilePtr;
  2032.   logFilePtr.p->logFileStatus = LogFileRecord::CLOSED;
  2033.   logPartPtr.i = logFilePtr.p->logPartRec;
  2034.   ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
  2035.   locLogFilePtr.i = logPartPtr.p->currentLogfile;
  2036.   ptrCheckGuard(locLogFilePtr, clogFileFileSize, logFileRecord);
  2037.   locLogFilePtr.p->logFileStatus = LogFileRecord::OPEN_EXEC_SR_NEW_MBYTE;
  2038.   openFileRw(signal, locLogFilePtr);
  2039.   return;
  2040. }//Dblqh::closeExecSrLab()
  2041. void Dblqh::writeDirtyLab(Signal* signal) 
  2042. {
  2043.   releaseLfo(signal);
  2044.   signal->theData[0] = logPartPtr.i;
  2045.   execSr(signal);
  2046.   return;
  2047. }//Dblqh::writeDirtyLab()
  2048. /* --------------------------------------------------------------------------
  2049.  *       EXECUTE A LOG RECORD WITHIN THE CURRENT MBYTE.
  2050.  * ------------------------------------------------------------------------- */
  2051. void Dblqh::execSr(Signal* signal) 
  2052. {
  2053.   LogFileRecordPtr nextLogFilePtr;
  2054.   LogPageRecordPtr tmpLogPagePtr;
  2055.   Uint32 logWord;
  2056.   jamEntry();
  2057.   logPartPtr.i = signal->theData[0];
  2058.   ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
  2059.   do {
  2060.     jam();
  2061.     logFilePtr.i = logPartPtr.p->currentLogfile;
  2062.     ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
  2063.     logPagePtr.i = logPartPtr.p->prevLogpage;
  2064.     ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
  2065.     if (logPagePtr.p->logPageWord[ZPOS_DIRTY] == ZDIRTY) {
  2066.       jam();
  2067.       switch (logPartPtr.p->logExecState) {
  2068.       case LogPartRecord::LES_EXEC_LOG_COMPLETED:
  2069.       case LogPartRecord::LES_EXEC_LOG_NEW_FILE:
  2070.       case LogPartRecord::LES_EXEC_LOG_NEW_MBYTE:
  2071.         jam();
  2072. /* ------------------------------------------------------------------
  2073.  *  IN THIS WE HAVE COMPLETED EXECUTION OF THE CURRENT LOG PAGE
  2074.  *  AND CAN WRITE IT TO DISK SINCE IT IS DIRTY.
  2075.  * ----------------------------------------------------------------- */
  2076.         writeDirty(signal, __LINE__);
  2077.         return;
  2078.         break;
  2079.       case LogPartRecord::LES_EXEC_LOG:
  2080.       jam();
  2081.       /* --------------------------------------------------------------------
  2082.        *  IN THIS CASE WE ONLY WRITE THE PAGE TO DISK IF WE HAVE COMPLETED 
  2083.        *  EXECUTION OF LOG RECORDS BELONGING TO THIS LOG PAGE.
  2084.        * ------------------------------------------------------------------- */
  2085.         if (logFilePtr.p->currentLogpage != logPartPtr.p->prevLogpage) {
  2086.           jam();
  2087.           writeDirty(signal, __LINE__);
  2088.           return;
  2089.         }//if
  2090.         break;
  2091.       default:
  2092.         ndbrequire(false);
  2093.         break;
  2094.       }//switch
  2095.     }//if
  2096.     if (logFilePtr.p->currentLogpage != logPartPtr.p->prevLogpage) {
  2097.       jam();
  2098.       logPartPtr.p->prevLogpage = logPagePtr.p->logPageWord[ZNEXT_PAGE];
  2099.       logPartPtr.p->prevFilepage++;
  2100.       continue;
  2101.     }//if
  2102.     switch (logPartPtr.p->logExecState) {
  2103.     case LogPartRecord::LES_EXEC_LOG_COMPLETED:
  2104.       jam();
  2105.       releaseMmPages(signal);
  2106.       logFilePtr.p->logFileStatus = LogFileRecord::CLOSING_EXEC_SR_COMPLETED;
  2107.       closeFile(signal, logFilePtr);
  2108.       return;
  2109.       break;
  2110.     case LogPartRecord::LES_EXEC_LOG_NEW_MBYTE:
  2111.       jam();
  2112.       logFilePtr.p->currentMbyte++;
  2113.       readExecSrNewMbyte(signal);
  2114.       return;
  2115.       break;
  2116.     case LogPartRecord::LES_EXEC_LOG_NEW_FILE:
  2117.       jam();
  2118.       nextLogFilePtr.i = logFilePtr.p->nextLogFile;
  2119.       logPartPtr.p->currentLogfile = nextLogFilePtr.i;
  2120.       ptrCheckGuard(nextLogFilePtr, clogFileFileSize, logFileRecord);
  2121.       nextLogFilePtr.p->currentMbyte = 0;
  2122.       logFilePtr.p->logFileStatus = LogFileRecord::CLOSING_EXEC_SR;
  2123.       closeFile(signal, logFilePtr);
  2124.       return;
  2125.       break;
  2126.     case LogPartRecord::LES_EXEC_LOG:
  2127.       jam();
  2128.       /*empty*/;
  2129.       break;
  2130.     default:
  2131.       jam();
  2132.       systemErrorLab(signal);
  2133.       return;
  2134.       break;
  2135.     }//switch
  2136.     logPagePtr.i = logFilePtr.p->currentLogpage;
  2137.     ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
  2138.     logPartPtr.p->savePageIndex = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
  2139.     if (logPartPtr.p->execSrPagesRead < ZMIN_READ_BUFFER_SIZE) {
  2140.       /* --------------------------------------------------------------------
  2141.        *  THERE WERE LESS THAN 16 KBYTE OF LOG PAGES REMAINING. WE WAIT UNTIL
  2142.        *  THE NEXT 64 KBYTE ARRIVES UNTIL WE CONTINUE AGAIN.
  2143.        * ------------------------------------------------------------------- */
  2144.       if ((logPartPtr.p->execSrPagesRead + 
  2145.    logPartPtr.p->execSrPagesExecuted) < ZPAGES_IN_MBYTE) {
  2146.         jam();
  2147. /* ------------------------------------------------------------------
  2148.  *  WE ONLY STOP AND WAIT IF THERE MORE PAGES TO READ. IF IT IS NOT 
  2149.  *  THEN IT IS THE END OF THE MBYTE AND WE WILL CONTINUE. IT IS NO 
  2150.  *  RISK THAT A LOG RECORD WE FIND WILL NOT BE READ AT THIS TIME 
  2151.  *  SINCE THE LOG RECORDS NEVER SPAN OVER A MBYTE BOUNDARY.
  2152.  * ----------------------------------------------------------------- */
  2153.         readExecSr(signal);
  2154.         logPartPtr.p->logExecState = LogPartRecord::LES_WAIT_READ_EXEC_SR;
  2155.         return;
  2156.       }//if
  2157.     }//if
  2158.     logWord = readLogword(signal);
  2159.     switch (logWord) {
  2160. /* ========================================================================= */
  2161. /* ========================================================================= */
  2162.     case ZPREP_OP_TYPE:
  2163.     {
  2164.       logWord = readLogword(signal);
  2165.       stepAhead(signal, logWord - 2);
  2166.       break;
  2167.     }
  2168. /* ========================================================================= */
  2169. /* ========================================================================= */
  2170.     case ZINVALID_COMMIT_TYPE:
  2171.       jam();
  2172.       stepAhead(signal, ZCOMMIT_LOG_SIZE - 1);
  2173.       break;
  2174. /* ========================================================================= */
  2175. /* ========================================================================= */
  2176.     case ZCOMMIT_TYPE:
  2177.     {
  2178.       CommitLogRecord commitLogRecord;
  2179.       jam();
  2180.       tcConnectptr.i = logPartPtr.p->logTcConrec;
  2181.       ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
  2182.       readCommitLog(signal, &commitLogRecord);
  2183.       if (tcConnectptr.p->gci > crestartNewestGci) {
  2184.         jam();
  2185. /*---------------------------------------------------------------------------*/
  2186. /* THIS LOG RECORD MUST BE IGNORED. IT IS PART OF A GLOBAL CHECKPOINT WHICH  */
  2187. /* WILL BE INVALIDATED BY THE SYSTEM RESTART. IF NOT INVALIDATED IT MIGHT BE */
  2188. /* EXECUTED IN A FUTURE SYSTEM RESTART.                                      */
  2189. /*---------------------------------------------------------------------------*/
  2190.         tmpLogPagePtr.i = logPartPtr.p->prevLogpage;
  2191.         ptrCheckGuard(tmpLogPagePtr, clogPageFileSize, logPageRecord);
  2192.         arrGuard(logPartPtr.p->savePageIndex, ZPAGE_SIZE);
  2193.         tmpLogPagePtr.p->logPageWord[logPartPtr.p->savePageIndex] = 
  2194.                                                   ZINVALID_COMMIT_TYPE;
  2195.         tmpLogPagePtr.p->logPageWord[ZPOS_DIRTY] = ZDIRTY;
  2196.       } else {
  2197.         jam();
  2198. /*---------------------------------------------------------------------------*/
  2199. /* CHECK IF I AM SUPPOSED TO EXECUTE THIS LOG RECORD. IF I AM THEN SAVE PAGE */
  2200. /* INDEX IN CURRENT LOG PAGE SINCE IT WILL BE OVERWRITTEN WHEN EXECUTING THE */
  2201. /* LOG RECORD.                                                               */
  2202. /*---------------------------------------------------------------------------*/
  2203.         logPartPtr.p->execSrExecuteIndex = 0;
  2204.         Uint32 result = checkIfExecLog(signal);
  2205.         if (result == ZOK) {
  2206.           jam();
  2207. //*---------------------------------------------------------------------------*/
  2208. /* IN A NODE RESTART WE WILL NEVER END UP HERE SINCE NO FRAGMENTS HAVE BEEN  */
  2209. /* DEFINED YET. THUS NO EXTRA CHECKING FOR NODE RESTART IS NECESSARY.        */
  2210. /*---------------------------------------------------------------------------*/
  2211.           logPartPtr.p->savePageIndex = 
  2212.              logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
  2213.           tcConnectptr.p->fragmentptr = fragptr.i;
  2214.           findPageRef(signal, &commitLogRecord);
  2215.           logPartPtr.p->execSrLogPageIndex = commitLogRecord.startPageIndex;
  2216.           if (logPagePtr.i != RNIL) {
  2217.             jam();
  2218.             logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = commitLogRecord.startPageIndex;
  2219.             logPartPtr.p->execSrLogPage = logPagePtr.i;
  2220.             execLogRecord(signal);
  2221.             return;
  2222.           }//if
  2223.           logPartPtr.p->execSrStartPageNo = commitLogRecord.startPageNo;
  2224.           logPartPtr.p->execSrStopPageNo = commitLogRecord.stopPageNo;
  2225.           findLogfile(signal, commitLogRecord.fileNo, logPartPtr, &logFilePtr);
  2226.           logPartPtr.p->execSrExecLogFile = logFilePtr.i;
  2227.           if (logFilePtr.i == logPartPtr.p->currentLogfile) {
  2228.             jam();
  2229.             readExecLog(signal);
  2230.             lfoPtr.p->lfoState = LogFileOperationRecord::READ_EXEC_LOG;
  2231.             return;
  2232.           } else {
  2233.             jam();
  2234. /*---------------------------------------------------------------------------*/
  2235. /* THE FILE IS CURRENTLY NOT OPEN. WE MUST OPEN IT BEFORE WE CAN READ FROM   */
  2236. /* THE FILE.                                                                 */
  2237. /*---------------------------------------------------------------------------*/
  2238.             logFilePtr.p->logFileStatus = LogFileRecord::OPEN_EXEC_LOG;
  2239.             openFileRw(signal, logFilePtr);
  2240.             return;
  2241.           }//if
  2242.         }//if
  2243.       }//if
  2244.       break;
  2245.     }
  2246. /* ========================================================================= */
  2247. /* ========================================================================= */
  2248.     case ZABORT_TYPE:
  2249.       jam();
  2250.       stepAhead(signal, ZABORT_LOG_SIZE - 1);
  2251.       break;
  2252. /* ========================================================================= */
  2253. /* ========================================================================= */
  2254.     case ZFD_TYPE:
  2255.       jam();
  2256. /*---------------------------------------------------------------------------*/
  2257. /* THIS IS THE FIRST ITEM WE ENCOUNTER IN A NEW FILE. AT THIS MOMENT WE SHALL*/
  2258. /* SIMPLY BYPASS IT. IT HAS NO SIGNIFANCE WHEN EXECUTING THE LOG. IT HAS ITS */
  2259. /* SIGNIFANCE WHEN FINDING THE START END THE END OF THE LOG.                 */
  2260. /* WE HARDCODE THE PAGE INDEX SINCE THIS SHOULD NEVER BE FOUND AT ANY OTHER  */
  2261. /* PLACE THAN IN THE FIRST PAGE OF A NEW FILE IN THE FIRST POSITION AFTER THE*/
  2262. /* HEADER.                                                                   */
  2263. /*---------------------------------------------------------------------------*/
  2264.       ndbrequire(logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] == 
  2265.   (ZPAGE_HEADER_SIZE + ZPOS_NO_FD));
  2266.       {
  2267.         Uint32 noFdDescriptors = 
  2268.   logPagePtr.p->logPageWord[ZPAGE_HEADER_SIZE + ZPOS_NO_FD];
  2269.           logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = 
  2270.       (ZPAGE_HEADER_SIZE + ZFD_HEADER_SIZE) + 
  2271.       (noFdDescriptors * ZFD_PART_SIZE);
  2272.       }
  2273.       break;
  2274. /* ========================================================================= */
  2275. /* ========================================================================= */
  2276.     case ZNEXT_LOG_RECORD_TYPE:
  2277.       jam();
  2278.       stepAhead(signal, ZPAGE_SIZE - logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX]);
  2279.       break;
  2280. /* ========================================================================= */
  2281. /* ========================================================================= */
  2282.     case ZNEXT_MBYTE_TYPE:
  2283. /*---------------------------------------------------------------------------*/
  2284. /* WE WILL SKIP A PART OF THE LOG FILE. ACTUALLY THE NEXT POINTER IS TO      */
  2285. /* A NEW MBYTE. THEREFORE WE WILL START UP A NEW MBYTE. THIS NEW MBYTE IS    */
  2286. /* HOWEVER ONLY STARTED IF IT IS NOT AFTER THE STOP MBYTE.                   */
  2287. /* IF WE HAVE REACHED THE END OF THE STOP MBYTE THEN THE EXECUTION OF THE LOG*/
  2288. /* IS COMPLETED.                                                             */
  2289. /*---------------------------------------------------------------------------*/
  2290.       if (logPartPtr.p->currentLogfile == logPartPtr.p->stopLogfile) {
  2291.         if (logFilePtr.p->currentMbyte == logPartPtr.p->stopMbyte) {
  2292.           jam();
  2293. /*---------------------------------------------------------------------------*/
  2294. /* THIS WAS THE LAST MBYTE TO EXECUTE IN THIS LOG PART. WE SHOULD HAVE FOUND */
  2295. /* A COMPLETED GCI RECORD OF THE LAST GCI BEFORE THIS. FOR SOME REASON THIS  */
  2296. /* RECORD WAS NOT AVAILABLE ON THE LOG. CRASH THE SYSTEM, A VERY SERIOUS     */
  2297. /* ERROR WHICH WE MUST REALLY WORK HARD TO AVOID.                            */
  2298. /*---------------------------------------------------------------------------*/
  2299. /*---------------------------------------------------------------------------*/
  2300. /* SEND A SIGNAL TO THE SIGNAL LOG AND THEN CRASH THE SYSTEM.                */
  2301. /*---------------------------------------------------------------------------*/
  2302.           signal->theData[0] = RNIL;
  2303.           signal->theData[1] = logPartPtr.i;
  2304.   Uint32 tmp = logFilePtr.p->fileName[3];
  2305.   tmp = (tmp >> 8) & 0xff;// To get the Directory, DXX.
  2306.   signal->theData[2] = tmp;
  2307.           signal->theData[3] = logFilePtr.p->fileNo;
  2308.           signal->theData[4] = logFilePtr.p->currentFilepage;
  2309.           signal->theData[5] = logFilePtr.p->currentMbyte;
  2310.           signal->theData[6] = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
  2311.           sendSignal(cownref, GSN_DEBUG_SIG, signal, 7, JBA);
  2312.           return;
  2313.         }//if
  2314.       }//if
  2315. /*---------------------------------------------------------------------------*/
  2316. /* START EXECUTION OF A NEW MBYTE IN THE LOG.                                */
  2317. /*---------------------------------------------------------------------------*/
  2318.       if (logFilePtr.p->currentMbyte < (ZNO_MBYTES_IN_FILE - 1)) {
  2319.         jam();
  2320.         logPartPtr.p->logExecState = LogPartRecord::LES_EXEC_LOG_NEW_MBYTE;
  2321.       } else {
  2322.         ndbrequire(logFilePtr.p->currentMbyte == (ZNO_MBYTES_IN_FILE - 1));
  2323.         jam();
  2324. /*---------------------------------------------------------------------------*/
  2325. /* WE HAVE TO CHANGE FILE. CLOSE THIS ONE AND THEN OPEN THE NEXT.            */
  2326. /*---------------------------------------------------------------------------*/
  2327.         logPartPtr.p->logExecState = LogPartRecord::LES_EXEC_LOG_NEW_FILE;
  2328.       }//if
  2329.       break;
  2330. /* ========================================================================= */
  2331. /* ========================================================================= */
  2332.     case ZCOMPLETED_GCI_TYPE:
  2333.       jam();
  2334.       logWord = readLogword(signal);
  2335.       if (logWord == logPartPtr.p->logLastGci) {
  2336.         jam();
  2337. /*---------------------------------------------------------------------------*/
  2338. /* IF IT IS THE LAST GCI TO LIVE AFTER SYSTEM RESTART THEN WE RECORD THE NEXT*/
  2339. /* WORD AS THE NEW HEADER OF THE LOG FILE. OTHERWISE WE SIMPLY IGNORE THIS   */
  2340. /* LOG RECORD.                                                               */
  2341. /*---------------------------------------------------------------------------*/
  2342.         if (csrPhasesCompleted == 0) {
  2343.           jam();
  2344. /*---------------------------------------------------------------------------*/
  2345. /*WE ONLY RECORD THE HEAD OF THE LOG IN THE FIRST LOG ROUND OF LOG EXECUTION.*/
  2346. /*---------------------------------------------------------------------------*/
  2347.           logPartPtr.p->headFileNo = logFilePtr.p->fileNo;
  2348.           logPartPtr.p->headPageNo = logFilePtr.p->currentFilepage;
  2349.           logPartPtr.p->headPageIndex = 
  2350.                   logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
  2351.         }//if
  2352. /*---------------------------------------------------------------------------*/
  2353. /* THERE IS NO NEED OF EXECUTING PAST THIS LINE SINCE THERE WILL ONLY BE LOG */
  2354. /* RECORDS THAT WILL BE OF NO INTEREST. THUS CLOSE THE FILE AND START THE    */
  2355. /* NEXT PHASE OF THE SYSTEM RESTART.                                         */
  2356. /*---------------------------------------------------------------------------*/
  2357.         logPartPtr.p->logExecState = LogPartRecord::LES_EXEC_LOG_COMPLETED;
  2358.       }//if
  2359.       break;
  2360.     default:
  2361.       jam();
  2362. /* ========================================================================= */
  2363. /* ========================================================================= */
  2364. /*---------------------------------------------------------------------------*/
  2365. /* SEND A SIGNAL TO THE SIGNAL LOG AND THEN CRASH THE SYSTEM.                */
  2366. /*---------------------------------------------------------------------------*/
  2367.       signal->theData[0] = RNIL;
  2368.       signal->theData[1] = logPartPtr.i;
  2369.       Uint32 tmp = logFilePtr.p->fileName[3];
  2370.       tmp = (tmp >> 8) & 0xff;// To get the Directory, DXX.
  2371.       signal->theData[2] = tmp;
  2372.       signal->theData[3] = logFilePtr.p->fileNo;
  2373.       signal->theData[4] = logFilePtr.p->currentMbyte;
  2374.       signal->theData[5] = logFilePtr.p->currentFilepage;
  2375.       signal->theData[6] = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
  2376.       signal->theData[7] = logWord;
  2377.       sendSignal(cownref, GSN_DEBUG_SIG, signal, 8, JBA);
  2378.       return;
  2379.       break;
  2380.     }//switch
  2381. /*---------------------------------------------------------------------------*/
  2382. // We continue to execute log records until we find a proper one to execute or
  2383. // that we reach a new page.
  2384. /*---------------------------------------------------------------------------*/
  2385.   } while (1);
  2386. }//Dblqh::execSr()
  2387. /*---------------------------------------------------------------------------*/
  2388. /* THIS SIGNAL IS ONLY RECEIVED TO BE CAPTURED IN THE SIGNAL LOG. IT IS      */
  2389. /* ALSO USED TO CRASH THE SYSTEM AFTER SENDING A SIGNAL TO THE LOG.          */
  2390. /*---------------------------------------------------------------------------*/
  2391. void Dblqh::execDEBUG_SIG(Signal* signal) 
  2392. {
  2393. /*
  2394. 2.5 TEMPORARY VARIABLES
  2395. -----------------------
  2396. */
  2397.   UintR tdebug;
  2398.   jamEntry();
  2399.   logPagePtr.i = signal->theData[0];
  2400.   tdebug = logPagePtr.p->logPageWord[0];
  2401.   char buf[100];
  2402.   BaseString::snprintf(buf, 100, 
  2403.    "Error while reading REDO log.n"
  2404.    "D=%d, F=%d Mb=%d FP=%d W1=%d W2=%d",
  2405.    signal->theData[2], signal->theData[3], signal->theData[4],
  2406.    signal->theData[5], signal->theData[6], signal->theData[7]);
  2407.   progError(__LINE__, ERR_SR_REDOLOG, buf);  
  2408.   return;
  2409. }//Dblqh::execDEBUG_SIG()
  2410. /*---------------------------------------------------------------------------*/
  2411. /*---------------------------------------------------------------------------*/
  2412. void Dblqh::closeExecLogLab(Signal* signal) 
  2413. {
  2414.   logFilePtr.p->logFileStatus = LogFileRecord::CLOSED;
  2415.   signal->theData[0] = ZEXEC_SR;
  2416.   signal->theData[1] = logFilePtr.p->logPartRec;
  2417.   sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
  2418.   return;
  2419. }//Dblqh::closeExecLogLab()
  2420. void Dblqh::openExecLogLab(Signal* signal) 
  2421. {
  2422.   readExecLog(signal);
  2423.   lfoPtr.p->lfoState = LogFileOperationRecord::READ_EXEC_LOG;
  2424.   return;
  2425. }//Dblqh::openExecLogLab()
  2426. void Dblqh::readExecLogLab(Signal* signal) 
  2427. {
  2428.   buildLinkedLogPageList(signal);
  2429.   logPartPtr.p->logExecState = LogPartRecord::LES_EXEC_LOGREC_FROM_FILE;
  2430.   logPartPtr.p->execSrLfoRec = lfoPtr.i;
  2431.   logPartPtr.p->execSrLogPage = logPagePtr.i;
  2432.   logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = 
  2433.     logPartPtr.p->execSrLogPageIndex;
  2434.   execLogRecord(signal);
  2435.   return;
  2436. }//Dblqh::readExecLogLab()
  2437. /*---------------------------------------------------------------------------*/
  2438. /* THIS CODE IS USED TO EXECUTE A LOG RECORD WHEN IT'S DATA HAVE BEEN LOCATED*/
  2439. /* AND TRANSFERRED INTO MEMORY.                                              */
  2440. /*---------------------------------------------------------------------------*/
  2441. void Dblqh::execLogRecord(Signal* signal) 
  2442. {
  2443.   jamEntry();
  2444.   tcConnectptr.i = logPartPtr.p->logTcConrec;
  2445.   ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
  2446.   fragptr.i = tcConnectptr.p->fragmentptr;
  2447.   ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
  2448.   // Read a log record and prepare it for execution
  2449.   readLogHeader(signal);
  2450.   readKey(signal);
  2451.   readAttrinfo(signal);
  2452.   initReqinfoExecSr(signal);
  2453.   arrGuard(logPartPtr.p->execSrExecuteIndex, 4);
  2454.   BlockReference ref = fragptr.p->execSrBlockref[logPartPtr.p->execSrExecuteIndex];
  2455.   tcConnectptr.p->nextReplica = refToNode(ref);
  2456.   tcConnectptr.p->connectState = TcConnectionrec::LOG_CONNECTED;
  2457.   tcConnectptr.p->tcOprec = tcConnectptr.i;
  2458.   packLqhkeyreqLab(signal);
  2459.   return;
  2460. }//Dblqh::execLogRecord()
  2461. //----------------------------------------------------------------------------
  2462. // This function invalidates log pages after the last GCI record in a 
  2463. // system/node restart. This is to ensure that the end of the log is 
  2464. // consistent. This function is executed last in start phase 3.
  2465. // RT 450. EDTJAMO.
  2466. //----------------------------------------------------------------------------
  2467. void Dblqh::invalidateLogAfterLastGCI(Signal* signal) {
  2468.   
  2469.   jam();
  2470.   if (logPartPtr.p->logExecState != LogPartRecord::LES_EXEC_LOG_INVALIDATE) {
  2471.     jam();
  2472.     systemError(signal);
  2473.   }
  2474.   if (logFilePtr.p->fileNo != logPartPtr.p->invalidateFileNo) {
  2475.     jam();
  2476.     systemError(signal);
  2477.   }
  2478.   switch (lfoPtr.p->lfoState) {
  2479.   case LogFileOperationRecord::WRITE_SR_INVALIDATE_PAGES:
  2480.     jam();
  2481.     releaseLfo(signal);
  2482.     releaseLogpage(signal); 
  2483.     if (logPartPtr.p->invalidatePageNo < (ZNO_MBYTES_IN_FILE * ZPAGES_IN_MBYTE - 1)) {
  2484.       // We continue in this file.
  2485.       logPartPtr.p->invalidatePageNo++;
  2486.     } else {
  2487.       // We continue in the next file.
  2488.       logFilePtr.i = logFilePtr.p->nextLogFile;
  2489.       ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
  2490.       logPartPtr.p->invalidateFileNo = logFilePtr.p->fileNo;
  2491.       // Page 0 is used for file descriptors.
  2492.       logPartPtr.p->invalidatePageNo = 1; 
  2493.       if (logFilePtr.p->logFileStatus != LogFileRecord::OPEN) {
  2494. jam();
  2495. logFilePtr.p->logFileStatus = LogFileRecord::OPEN_SR_INVALIDATE_PAGES;
  2496. openFileRw(signal, logFilePtr);
  2497. return;
  2498. break;
  2499.       }
  2500.     }
  2501.     // Read a page from the log file. 
  2502.     readFileInInvalidate(signal);
  2503.     return;
  2504.     break;
  2505.   case LogFileOperationRecord::READ_SR_INVALIDATE_PAGES:
  2506.     jam();
  2507.     releaseLfo(signal);
  2508.     // Check if this page must be invalidated.
  2509.     // If the log lap number on a page after the head of the tail is the same 
  2510.     // as the actual log lap number we must invalidate this page. Otherwise it
  2511.     // could be impossible to find the end of the log in a later system/node 
  2512.     // restart.
  2513.     if (logPagePtr.p->logPageWord[ZPOS_LOG_LAP] == logPartPtr.p->logLap) {
  2514.       // This page must be invalidated.
  2515.       logPagePtr.p->logPageWord[ZPOS_LOG_LAP] = 0;
  2516.       // Contact NDBFS. Real time break.
  2517.       writeSinglePage(signal, logPartPtr.p->invalidatePageNo,
  2518.                       ZPAGE_SIZE - 1, __LINE__);
  2519.       lfoPtr.p->lfoState = LogFileOperationRecord::WRITE_SR_INVALIDATE_PAGES;
  2520.     } else {
  2521.       // We are done with invalidating. Finish start phase 3.4. 
  2522.       exitFromInvalidate(signal);
  2523.     }
  2524.     return;
  2525.     break;
  2526.   default:
  2527.     jam();
  2528.     systemError(signal);
  2529.     return;
  2530.     break;
  2531.   }
  2532.   return;
  2533. }//Dblqh::invalidateLogAfterLastGCI
  2534. void Dblqh::readFileInInvalidate(Signal* signal) {
  2535.   jam();
  2536.   // Contact NDBFS. Real time break.
  2537.   readSinglePage(signal, logPartPtr.p->invalidatePageNo); 
  2538.   lfoPtr.p->lfoState = LogFileOperationRecord::READ_SR_INVALIDATE_PAGES;
  2539. }
  2540. void Dblqh::exitFromInvalidate(Signal* signal) {
  2541.   jam();
  2542.   // Close files if necessary. Current file and the next file should be 
  2543.   // left open.
  2544.   if (logFilePtr.i != logPartPtr.p->currentLogfile) {
  2545.     LogFileRecordPtr currentLogFilePtr;
  2546.     LogFileRecordPtr nextAfterCurrentLogFilePtr;
  2547.     currentLogFilePtr.i = logPartPtr.p->currentLogfile;
  2548.     ptrCheckGuard(currentLogFilePtr, clogFileFileSize, logFileRecord);
  2549.     nextAfterCurrentLogFilePtr.i = currentLogFilePtr.p->nextLogFile;
  2550.     if (logFilePtr.i != nextAfterCurrentLogFilePtr.i) {
  2551.       // This file should be closed.
  2552.       logFilePtr.p->logFileStatus = LogFileRecord::CLOSE_SR_INVALIDATE_PAGES;
  2553.       closeFile(signal, logFilePtr);  
  2554.       // Return from this function and wait for close confirm. Then come back 
  2555.       // and test the previous file for closing.
  2556.       return;
  2557.     }
  2558.   }    
  2559.   // We are done with closing files, send completed signal and exit this phase.
  2560.   signal->theData[0] = ZSR_FOURTH_COMP;
  2561.   signal->theData[1] = logPartPtr.i;
  2562.   sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
  2563.   return;
  2564. }
  2565. /*---------------------------------------------------------------------------*/
  2566. /* THE EXECUTION OF A LOG RECORD IS COMPLETED. RELEASE PAGES IF THEY WERE    */
  2567. /* READ FROM DISK FOR THIS PARTICULAR OPERATION.                             */
  2568. /*---------------------------------------------------------------------------*/
  2569. void Dblqh::completedLab(Signal* signal) 
  2570. {
  2571.   Uint32 result = returnExecLog(signal);
  2572. /*---------------------------------------------------------------------------*/
  2573. /*       ENTER COMPLETED WITH                                                */
  2574. /*         LQH_CONNECTPTR                                                    */
  2575. /*---------------------------------------------------------------------------*/
  2576.   if (result == ZOK) {
  2577.     jam();
  2578.     execLogRecord(signal);
  2579.     return;
  2580.   } else if (result == ZNOT_OK) {
  2581.     jam();
  2582.     signal->theData[0] = ZEXEC_SR;
  2583.     signal->theData[1] = logPartPtr.i;
  2584.     sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
  2585.   } else {
  2586.     jam();
  2587.     /*empty*/;
  2588.   }//if
  2589. /*---------------------------------------------------------------------------*/
  2590. /* WE HAVE TO WAIT FOR CLOSING OF THE EXECUTED LOG FILE BEFORE PROCEEDING IN */
  2591. /* RARE CASES.                                                               */
  2592. /*---------------------------------------------------------------------------*/
  2593.   return;
  2594. }//Dblqh::completedLab()
  2595. /*---------------------------------------------------------------------------*/
  2596. /* EXECUTION OF LOG RECORD WAS NOT SUCCESSFUL. CHECK IF IT IS OK ANYWAY,     */
  2597. /* THEN EXECUTE THE NEXT LOG RECORD.                                         */
  2598. /*---------------------------------------------------------------------------*/
  2599. void Dblqh::logLqhkeyrefLab(Signal* signal) 
  2600. {
  2601.   Uint32 result = returnExecLog(signal);
  2602.   switch (tcConnectptr.p->operation) {
  2603.   case ZUPDATE:
  2604.   case ZDELETE:
  2605.     jam();
  2606.     ndbrequire(terrorCode == ZNO_TUPLE_FOUND);
  2607.     break;
  2608.   case ZINSERT:
  2609.     jam();
  2610.     ndbrequire(terrorCode == ZTUPLE_ALREADY_EXIST);
  2611.     break;
  2612.   default:
  2613.     ndbrequire(false);
  2614.     return;
  2615.     break;
  2616.   }//switch
  2617.   if (result == ZOK) {
  2618.     jam();
  2619.     execLogRecord(signal);
  2620.     return;
  2621.   } else if (result == ZNOT_OK) {
  2622.     jam();
  2623.     signal->theData[0] = ZEXEC_SR;
  2624.     signal->theData[1] = logPartPtr.i;
  2625.     sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
  2626.   } else {
  2627.     jam();
  2628.     /*empty*/;
  2629.   }//if
  2630.   /* ------------------------------------------------------------------------
  2631.    *  WE HAVE TO WAIT FOR CLOSING OF THE EXECUTED LOG FILE BEFORE 
  2632.    *  PROCEEDING IN RARE CASES.
  2633.    * ----------------------------------------------------------------------- */
  2634.   return;
  2635. }//Dblqh::logLqhkeyrefLab()
  2636. void Dblqh::closeExecSrCompletedLab(Signal* signal) 
  2637. {
  2638.   logFilePtr.p->logFileStatus = LogFileRecord::CLOSED;
  2639.   signal->theData[0] = logFilePtr.p->logPartRec;
  2640.   execLogComp(signal);
  2641.   return;
  2642. }//Dblqh::closeExecSrCompletedLab()
  2643. /* --------------------------------------------------------------------------
  2644.  *  ONE OF THE LOG PARTS HAVE COMPLETED EXECUTING THE LOG. CHECK IF ALL LOG
  2645.  *  PARTS ARE COMPLETED. IF SO START SENDING EXEC_FRAGCONF AND EXEC_SRCONF.
  2646.  * ------------------------------------------------------------------------- */
  2647. void Dblqh::execLogComp(Signal* signal) 
  2648. {
  2649.   logPartPtr.i = signal->theData[0];
  2650.   ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
  2651.   logPartPtr.p->logPartState = LogPartRecord::SR_THIRD_PHASE_COMPLETED;
  2652.   /* ------------------------------------------------------------------------
  2653.    *  WE MUST RELEASE THE TC CONNECT RECORD HERE SO THAT IT CAN BE REUSED.
  2654.    * ----------------------------------------------------------------------- */
  2655.   tcConnectptr.i = logPartPtr.p->logTcConrec;
  2656.   ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
  2657.   releaseTcrecLog(signal, tcConnectptr);
  2658.   for (logPartPtr.i = 0; logPartPtr.i <= 3; logPartPtr.i++) {
  2659.     jam();
  2660.     ptrAss(logPartPtr, logPartRecord);
  2661.     if (logPartPtr.p->logPartState != LogPartRecord::SR_THIRD_PHASE_COMPLETED) {
  2662.       if (logPartPtr.p->logPartState != LogPartRecord::SR_THIRD_PHASE_STARTED) {
  2663.         jam();
  2664.         systemErrorLab(signal);
  2665.         return;
  2666.       } else {
  2667.         jam();
  2668. /* ------------------------------------------------------------------
  2669.  *  THIS LOG PART WAS NOT COMPLETED YET. EXIT AND WAIT FOR IT 
  2670.  *  TO COMPLETE     
  2671.  * ----------------------------------------------------------------- */
  2672.         return;
  2673.       }//if
  2674.     }//if
  2675.   }//for
  2676.   /* ------------------------------------------------------------------------
  2677.    *   ALL LOG PARTS HAVE COMPLETED THE EXECUTION OF THE LOG. WE CAN NOW START
  2678.    *   SENDING THE EXEC_FRAGCONF SIGNALS TO ALL INVOLVED FRAGMENTS.
  2679.    * ----------------------------------------------------------------------- */
  2680.   if (cstartType != NodeState::ST_NODE_RESTART) {
  2681.     jam();
  2682.     signal->theData[0] = ZSEND_EXEC_CONF;
  2683.     signal->theData[1] = 0;
  2684.     sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
  2685.   } else {
  2686.     jam();
  2687.     /* ----------------------------------------------------------------------
  2688.      *  FOR NODE RESTART WE CAN SKIP A NUMBER OF STEPS SINCE WE HAVE NO 
  2689.      *  FRAGMENTS DEFINED AT THIS POINT. OBVIOUSLY WE WILL NOT NEED TO 
  2690.      *  EXECUTE ANY MORE LOG STEPS EITHER AND THUS WE CAN IMMEDIATELY 
  2691.      *  START FINDING THE END AND THE START OF THE LOG.
  2692.      * --------------------------------------------------------------------- */
  2693.     csrPhasesCompleted = 3;
  2694.     execSrCompletedLab(signal);
  2695.     return;
  2696.   }//if
  2697.   return;
  2698. }//Dblqh::execLogComp()
  2699. /* --------------------------------------------------------------------------
  2700.  *  GO THROUGH THE FRAGMENT RECORDS TO DEDUCE TO WHICH SHALL BE SENT
  2701.  *  EXEC_FRAGCONF AFTER COMPLETING THE EXECUTION OF THE LOG.
  2702.  * ------------------------------------------------------------------------- */
  2703. void Dblqh::sendExecConf(Signal* signal) 
  2704. {
  2705.   jamEntry();
  2706.   fragptr.i = signal->theData[0];
  2707.   Uint32 loopCount = 0;
  2708.   while (fragptr.i < cfragrecFileSize) {
  2709.     ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
  2710.     if (fragptr.p->execSrStatus != Fragrecord::IDLE) {
  2711.       jam();
  2712.       ndbrequire(fragptr.p->execSrNoReplicas - 1 < 4);
  2713.       for (Uint32 i = 0; i < fragptr.p->execSrNoReplicas; i++) {
  2714.         jam();
  2715.         signal->theData[0] = fragptr.p->execSrUserptr[i];
  2716.         sendSignal(fragptr.p->execSrBlockref[i], GSN_EXEC_FRAGCONF, 
  2717.    signal, 1, JBB);
  2718.       }//for
  2719.       if (fragptr.p->execSrStatus == Fragrecord::ACTIVE) {
  2720.         jam();
  2721.         fragptr.p->execSrStatus = Fragrecord::IDLE;
  2722.       } else {
  2723.         ndbrequire(fragptr.p->execSrStatus == Fragrecord::ACTIVE_REMOVE_AFTER);
  2724.         jam();
  2725.         Uint32 fragId = fragptr.p->fragId;
  2726.         tabptr.i = fragptr.p->tabRef;
  2727.         ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
  2728.         deleteFragrec(fragId);
  2729.       }//if
  2730.       fragptr.p->execSrNoReplicas = 0;
  2731.     }//if
  2732.     loopCount++;
  2733.     if (loopCount > 20) {
  2734.       jam();
  2735.       signal->theData[0] = ZSEND_EXEC_CONF;
  2736.       signal->theData[1] = fragptr.i + 1;
  2737.       sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
  2738.       return;
  2739.     } else {
  2740.       jam();
  2741.       fragptr.i++;
  2742.     }//if
  2743.   }//while
  2744.     /* ----------------------------------------------------------------------
  2745.      *  WE HAVE NOW SENT ALL EXEC_FRAGCONF. NOW IT IS TIME TO SEND 
  2746.      *  EXEC_SRCONF TO ALL NODES.
  2747.      * --------------------------------------------------------------------- */
  2748.   srPhase3Comp(signal);
  2749. }//Dblqh::sendExecConf()
  2750. /* --------------------------------------------------------------------------
  2751.  *       PHASE 3 HAS NOW COMPLETED. INFORM ALL OTHER NODES OF THIS EVENT.
  2752.  * ------------------------------------------------------------------------- */
  2753. void Dblqh::srPhase3Comp(Signal* signal) 
  2754. {
  2755.   jamEntry();
  2756.   ndbrequire(cnoOfNodes < MAX_NDB_NODES);
  2757.   for (Uint32 i = 0; i < cnoOfNodes; i++) {
  2758.     jam();
  2759.     if (cnodeStatus[i] == ZNODE_UP) {
  2760.       jam();
  2761.       ndbrequire(cnodeData[i] < MAX_NDB_NODES);
  2762.       BlockReference ref = calcLqhBlockRef(cnodeData[i]);
  2763.       signal->theData[0] = cownNodeid;
  2764.       sendSignal(ref, GSN_EXEC_SRCONF, signal, 1, JBB);
  2765.     }//if
  2766.   }//for
  2767.   return;
  2768. }//Dblqh::srPhase3Comp()
  2769. /* ########################################################################## 
  2770.  *    SYSTEM RESTART PHASE FOUR MODULE
  2771.  *    THIS MODULE IS A SUB-MODULE OF THE FILE SYSTEM HANDLING.
  2772.  *
  2773.  *    THIS MODULE SETS UP THE HEAD AND TAIL POINTERS OF THE LOG PARTS IN THE
  2774.  *    FRAGMENT LOG. WHEN IT IS COMPLETED IT REPORTS TO THE MASTER DIH THAT
  2775.  *    IT HAS COMPLETED THE PART OF THE SYSTEM RESTART WHERE THE DATABASE IS
  2776.  *    LOADED.
  2777.  *    IT ALSO OPENS THE CURRENT LOG FILE AND THE NEXT AND SETS UP THE FIRST 
  2778.  *    LOG PAGE WHERE NEW LOG DATA IS TO BE INSERTED WHEN THE SYSTEM STARTS 
  2779.  *    AGAIN.
  2780.  *
  2781.  *    THIS PART IS ACTUALLY EXECUTED FOR ALL RESTART TYPES.
  2782.  * ######################################################################### */
  2783. void Dblqh::initFourth(Signal* signal) 
  2784. {
  2785.   LogFileRecordPtr locLogFilePtr;
  2786.   jamEntry();
  2787.   logPartPtr.i = signal->theData[0];
  2788.   ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
  2789.   crestartNewestGci = 1;
  2790.   crestartOldestGci = 1;
  2791.   /* ------------------------------------------------------------------------
  2792.    *       INITIALISE LOG PART AND LOG FILES AS NEEDED.
  2793.    * ----------------------------------------------------------------------- */
  2794.   logPartPtr.p->headFileNo = 0;
  2795.   logPartPtr.p->headPageNo = 1;
  2796.   logPartPtr.p->headPageIndex = ZPAGE_HEADER_SIZE + 2;
  2797.   logPartPtr.p->logPartState = LogPartRecord::SR_FOURTH_PHASE_STARTED;
  2798.   logPartPtr.p->logTailFileNo = 0;
  2799.   logPartPtr.p->logTailMbyte = 0;
  2800.   locLogFilePtr.i = logPartPtr.p->firstLogfile;
  2801.   ptrCheckGuard(locLogFilePtr, clogFileFileSize, logFileRecord);
  2802.   locLogFilePtr.p->logFileStatus = LogFileRecord::OPEN_SR_FOURTH_PHASE;
  2803.   openFileRw(signal, locLogFilePtr);
  2804.   return;
  2805. }//Dblqh::initFourth()
  2806. void Dblqh::openSrFourthPhaseLab(Signal* signal) 
  2807. {
  2808.   /* ------------------------------------------------------------------------
  2809.    *  WE HAVE NOW OPENED THE HEAD LOG FILE WE WILL NOW START READING IT 
  2810.    *  FROM THE HEAD MBYTE TO FIND THE NEW HEAD OF THE LOG.
  2811.    * ----------------------------------------------------------------------- */
  2812.   readSinglePage(signal, logPartPtr.p->headPageNo);
  2813.   lfoPtr.p->lfoState = LogFileOperationRecord::READ_SR_FOURTH_PHASE;
  2814.   return;
  2815. }//Dblqh::openSrFourthPhaseLab()
  2816. void Dblqh::readSrFourthPhaseLab(Signal* signal) 
  2817. {
  2818.   if(c_diskless){
  2819.     jam();
  2820.     logPagePtr.p->logPageWord[ZPOS_LOG_LAP] = 1;
  2821.   }
  2822.   /* ------------------------------------------------------------------------
  2823.    *  INITIALISE ALL LOG PART INFO AND LOG FILE INFO THAT IS NEEDED TO 
  2824.    *  START UP THE SYSTEM.
  2825.    * ------------------------------------------------------------------------
  2826.    *  INITIALISE THE NEWEST GLOBAL CHECKPOINT IDENTITY AND THE NEWEST 
  2827.    *  COMPLETED GLOBAL CHECKPOINT IDENITY AS THE NEWEST THAT WAS RESTARTED.
  2828.    * ------------------------------------------------------------------------
  2829.    *  INITIALISE THE HEAD PAGE INDEX IN THIS PAGE.
  2830.    *  ASSIGN IT AS THE CURRENT LOGPAGE.
  2831.    *  ASSIGN THE FILE AS THE CURRENT LOG FILE.
  2832.    *  ASSIGN THE CURRENT FILE NUMBER FROM THE CURRENT LOG FILE AND THE NEXT
  2833.    *  FILE NUMBER FROM THE NEXT LOG FILE.
  2834.    *  ASSIGN THE CURRENT FILEPAGE FROM HEAD PAGE NUMBER.
  2835.    *  ASSIGN THE CURRENT MBYTE BY DIVIDING PAGE NUMBER BY 128.
  2836.    *  INITIALISE LOG LAP TO BE THE LOG LAP AS FOUND IN THE HEAD PAGE.
  2837.    *  WE HAVE TO CALCULATE THE NUMBER OF REMAINING WORDS IN THIS MBYTE.
  2838.    * ----------------------------------------------------------------------- */
  2839.   cnewestGci = crestartNewestGci;
  2840.   cnewestCompletedGci = crestartNewestGci;
  2841.   logPartPtr.p->logPartNewestCompletedGCI = cnewestCompletedGci;
  2842.   logPartPtr.p->currentLogfile = logFilePtr.i;
  2843.   logFilePtr.p->filePosition = logPartPtr.p->headPageNo;
  2844.   logFilePtr.p->currentMbyte = 
  2845.                   logPartPtr.p->headPageNo >> ZTWOLOG_NO_PAGES_IN_MBYTE;
  2846.   logFilePtr.p->fileChangeState = LogFileRecord::NOT_ONGOING;
  2847.   logPartPtr.p->logLap = logPagePtr.p->logPageWord[ZPOS_LOG_LAP];
  2848.   logFilePtr.p->currentFilepage = logPartPtr.p->headPageNo;
  2849.   logFilePtr.p->currentLogpage = logPagePtr.i;
  2850.   initLogpage(signal);
  2851.   logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = logPartPtr.p->headPageIndex;
  2852.   logFilePtr.p->remainingWordsInMbyte = 
  2853.     ((
  2854.       ((logFilePtr.p->currentMbyte + 1) * ZPAGES_IN_MBYTE) -
  2855.      logFilePtr.p->currentFilepage) *
  2856.     (ZPAGE_SIZE - ZPAGE_HEADER_SIZE)) -
  2857.       (logPartPtr.p->headPageIndex - ZPAGE_HEADER_SIZE);
  2858.   /* ------------------------------------------------------------------------
  2859.    *     THE NEXT STEP IS TO OPEN THE NEXT LOG FILE (IF THERE IS ONE).
  2860.    * ----------------------------------------------------------------------- */
  2861.   if (logFilePtr.p->nextLogFile != logFilePtr.i) {
  2862.     LogFileRecordPtr locLogFilePtr;
  2863.     jam();
  2864.     locLogFilePtr.i = logFilePtr.p->nextLogFile;
  2865.     ptrCheckGuard(locLogFilePtr, clogFileFileSize, logFileRecord);
  2866.     locLogFilePtr.p->logFileStatus = LogFileRecord::OPEN_SR_FOURTH_NEXT;
  2867.     openFileRw(signal, locLogFilePtr);
  2868.   } else {
  2869.     jam();
  2870.     /* ----------------------------------------------------------------------
  2871.      *  THIS CAN ONLY OCCUR IF WE HAVE ONLY ONE LOG FILE. THIS LOG FILE MUST 
  2872.      *  BE LOG FILE ZERO AND THAT IS THE FILE WE CURRENTLY HAVE READ.
  2873.      *  THUS WE CAN CONTINUE IMMEDIATELY TO READ PAGE ZERO IN FILE ZERO.
  2874.      * --------------------------------------------------------------------- */
  2875.     openSrFourthZeroSkipInitLab(signal);
  2876.     return;
  2877.   }//if
  2878.   return;
  2879. }//Dblqh::readSrFourthPhaseLab()
  2880. void Dblqh::openSrFourthNextLab(Signal* signal) 
  2881. {
  2882.   /* ------------------------------------------------------------------------
  2883.    *       WE MUST ALSO HAVE FILE 0 OPEN ALL THE TIME.
  2884.    * ----------------------------------------------------------------------- */
  2885.   logFilePtr.i = logPartPtr.p->firstLogfile;
  2886.   ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
  2887.   if (logFilePtr.p->logFileStatus == LogFileRecord::OPEN) {
  2888.     jam();
  2889.     openSrFourthZeroSkipInitLab(signal);
  2890.     return;
  2891.   } else {
  2892.     jam();
  2893.     logFilePtr.p->logFileStatus = LogFileRecord::OPEN_SR_FOURTH_ZERO;
  2894.     openFileRw(signal, logFilePtr);
  2895.   }//if
  2896.   return;
  2897. }//Dblqh::openSrFourthNextLab()
  2898. void Dblqh::openSrFourthZeroLab(Signal* signal) 
  2899. {
  2900.   openSrFourthZeroSkipInitLab(signal);
  2901.   return;
  2902. }//Dblqh::openSrFourthZeroLab()
  2903. void Dblqh::openSrFourthZeroSkipInitLab(Signal* signal) 
  2904. {
  2905.   if (logFilePtr.i == logPartPtr.p->currentLogfile) {
  2906.     if (logFilePtr.p->currentFilepage == 0) {
  2907.       jam();
  2908.       /* -------------------------------------------------------------------
  2909.        *  THE HEADER PAGE IN THE LOG IS PAGE ZERO IN FILE ZERO. 
  2910.        *  THIS SHOULD NEVER OCCUR.
  2911.        * ------------------------------------------------------------------- */
  2912.       systemErrorLab(signal);
  2913.       return;
  2914.     }//if
  2915.   }//if
  2916.   readSinglePage(signal, 0);
  2917.   lfoPtr.p->lfoState = LogFileOperationRecord::READ_SR_FOURTH_ZERO;
  2918.   return;
  2919. }//Dblqh::openSrFourthZeroSkipInitLab()
  2920. void Dblqh::readSrFourthZeroLab(Signal* signal) 
  2921. {
  2922.   logFilePtr.p->logPageZero = logPagePtr.i;
  2923.   // --------------------------------------------------------------------
  2924.   //   This is moved to invalidateLogAfterLastGCI(), RT453. 
  2925.   //   signal->theData[0] = ZSR_FOURTH_COMP;
  2926.   //   signal->theData[1] = logPartPtr.i;
  2927.   //   sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
  2928.   // --------------------------------------------------------------------
  2929.   
  2930.   // Need to invalidate log pages after the head of the log. RT 453. EDTJAMO.
  2931.   // Set the start of the invalidation.
  2932.   logFilePtr.i = logPartPtr.p->currentLogfile;
  2933.   ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
  2934.   logPartPtr.p->invalidateFileNo = logPartPtr.p->headFileNo;
  2935.   logPartPtr.p->invalidatePageNo = logPartPtr.p->headPageNo;
  2936.    
  2937.   logPartPtr.p->logExecState = LogPartRecord::LES_EXEC_LOG_INVALIDATE;
  2938.   seizeLfo(signal);
  2939.   initLfo(signal);
  2940.   // The state here is a little confusing, but simulates that we return
  2941.   // to invalidateLogAfterLastGCI() from an invalidate write and are ready
  2942.   // to read a page from file. 
  2943.   lfoPtr.p->lfoState = LogFileOperationRecord::WRITE_SR_INVALIDATE_PAGES;
  2944.   invalidateLogAfterLastGCI(signal);
  2945.   return;
  2946. }//Dblqh::readSrFourthZeroLab()
  2947. /* -------------------------------------------------------------------------- 
  2948.  *     ONE OF THE LOG PARTS HAVE COMPLETED PHASE FOUR OF THE SYSTEM RESTART.
  2949.  *     CHECK IF ALL LOG PARTS ARE COMPLETED. IF SO SEND START_RECCONF
  2950.  * ------------------------------------------------------------------------- */
  2951. void Dblqh::srFourthComp(Signal* signal) 
  2952. {
  2953.   jamEntry();
  2954.   logPartPtr.i = signal->theData[0];
  2955.   ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
  2956.   logPartPtr.p->logPartState = LogPartRecord::SR_FOURTH_PHASE_COMPLETED;
  2957.   for (logPartPtr.i = 0; logPartPtr.i <= 3; logPartPtr.i++) {
  2958.     jam();
  2959.     ptrAss(logPartPtr, logPartRecord);
  2960.     if (logPartPtr.p->logPartState != LogPartRecord::SR_FOURTH_PHASE_COMPLETED) {