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

MySQL数据库

开发平台:

Visual C++

  1.     createReplica->logNodeId[logNode] = fblFoundReplicaPtr.p->procNode;
  2.     createReplica->logStartGci[logNode] = startGci;
  3.     if (fblStopGci >= stopGci) {
  4.       jam();
  5.       createReplica->logStopGci[logNode] = stopGci;
  6.     } else {
  7.       jam();
  8.       createReplica->logStopGci[logNode] = fblStopGci;
  9.     }//if
  10.   }//if
  11.   return fblStopGci != 0;
  12. }//Dbdih::findBestLogNode()
  13. Uint32 Dbdih::findLogInterval(ConstPtr<ReplicaRecord> replicaPtr, 
  14.       Uint32 startGci)
  15. {
  16.   ndbrequire(replicaPtr.p->noCrashedReplicas <= 8);
  17.   Uint32 loopLimit = replicaPtr.p->noCrashedReplicas + 1;
  18.   for (Uint32 i = 0; i < loopLimit; i++) {
  19.     jam();
  20.     if (replicaPtr.p->createGci[i] <= startGci) {
  21.       if (replicaPtr.p->replicaLastGci[i] >= startGci) {
  22.         jam();
  23.         return replicaPtr.p->replicaLastGci[i];
  24.       }//if
  25.     }//if
  26.   }//for
  27.   return 0;
  28. }//Dbdih::findLogInterval()
  29. /*************************************************************************/
  30. /*                                                                       */
  31. /*       MODULE: FIND THE MINIMUM GCI THAT THIS NODE HAS LOG RECORDS FOR.*/
  32. /*************************************************************************/
  33. void Dbdih::findMinGci(ReplicaRecordPtr fmgReplicaPtr,
  34.                        Uint32& keepGci,
  35.                        Uint32& oldestRestorableGci)
  36. {
  37.   Uint32 nextLcpNo;
  38.   Uint32 lcpNo;
  39.   for (Uint32 i = 0; i < MAX_LCP_STORED; i++) {
  40.     jam();
  41.     if ((fmgReplicaPtr.p->lcpStatus[i] == ZVALID) &&
  42.         ((fmgReplicaPtr.p->lcpId[i] + MAX_LCP_STORED) <= (SYSFILE->latestLCP_ID + 1))) {
  43.       jam();
  44.       /*--------------------------------------------------------------------*/
  45.       // We invalidate the checkpoint we are preparing to overwrite. 
  46.       // The LCP id is still the old lcp id, 
  47.       // this is the reason of comparing with lcpId + 1.
  48.       /*---------------------------------------------------------------------*/
  49.       fmgReplicaPtr.p->lcpStatus[i] = ZINVALID;
  50.     }//if
  51.   }//for
  52.   keepGci = (Uint32)-1;
  53.   oldestRestorableGci = 0;
  54.   nextLcpNo = fmgReplicaPtr.p->nextLcp;
  55.   lcpNo = fmgReplicaPtr.p->nextLcp;
  56.   do {
  57.     ndbrequire(lcpNo < MAX_LCP_STORED);
  58.     if (fmgReplicaPtr.p->lcpStatus[lcpNo] == ZVALID &&
  59. fmgReplicaPtr.p->maxGciStarted[lcpNo] <= coldgcp)
  60.     {
  61.       jam();
  62.       keepGci = fmgReplicaPtr.p->maxGciCompleted[lcpNo];
  63.       oldestRestorableGci = fmgReplicaPtr.p->maxGciStarted[lcpNo];
  64.       ndbrequire(((int)oldestRestorableGci) >= 0);      
  65.       return;
  66.     } else {
  67.       jam();
  68.       if (fmgReplicaPtr.p->createGci[0] == fmgReplicaPtr.p->initialGci) {
  69.         jam();
  70. /*-------------------------------------------------------------------
  71.  * WE CAN STILL RESTORE THIS REPLICA WITHOUT ANY LOCAL CHECKPOINTS BY
  72.  * ONLY USING THE LOG. IF THIS IS NOT POSSIBLE THEN WE REPORT THE LAST
  73.  * VALID LOCAL CHECKPOINT AS THE MINIMUM GCI RECOVERABLE.
  74.  *-----------------------------------------------------------------*/
  75.         keepGci = fmgReplicaPtr.p->createGci[0];
  76.       }//if
  77.     }//if
  78.     lcpNo = prevLcpNo(lcpNo);
  79.   } while (lcpNo != nextLcpNo);
  80.   return;
  81. }//Dbdih::findMinGci()
  82. bool Dbdih::findStartGci(ConstPtr<ReplicaRecord> replicaPtr,
  83.                          Uint32 stopGci,
  84.                          Uint32& startGci,
  85.                          Uint32& lcpNo) 
  86. {
  87.   lcpNo = replicaPtr.p->nextLcp;
  88.   const Uint32 startLcpNo = lcpNo;
  89.   do {
  90.     lcpNo = prevLcpNo(lcpNo);
  91.     ndbrequire(lcpNo < MAX_LCP_STORED);
  92.     if (replicaPtr.p->lcpStatus[lcpNo] == ZVALID) {
  93.       if (replicaPtr.p->maxGciStarted[lcpNo] < stopGci) {
  94.         jam();
  95. /* ----------------------------------------------------------------- */
  96. /*   WE HAVE FOUND A USEFUL LOCAL CHECKPOINT THAT CAN BE USED FOR    */
  97. /*   RESTARTING THIS FRAGMENT REPLICA.                               */
  98. /* ----------------------------------------------------------------- */
  99.         startGci = replicaPtr.p->maxGciCompleted[lcpNo] + 1;
  100.         return true;
  101.       } 
  102.     }
  103.   } while (lcpNo != startLcpNo);
  104.   /* --------------------------------------------------------------------- */
  105.   /*       NO VALID LOCAL CHECKPOINT WAS AVAILABLE. WE WILL ADD THE        */
  106.   /*       FRAGMENT. THUS THE NEXT LCP MUST BE SET TO ZERO.                */
  107.   /*       WE MUST EXECUTE THE LOG FROM THE INITIAL GLOBAL CHECKPOINT WHEN */
  108.   /*       THE TABLE WAS CREATED.                                          */
  109.   /* --------------------------------------------------------------------- */
  110.   startGci = replicaPtr.p->initialGci;
  111.   ndbrequire(replicaPtr.p->nextLcp == 0);
  112.   return false;
  113. }//Dbdih::findStartGci()
  114. /**************************************************************************/
  115. /* ---------------------------------------------------------------------- */
  116. /*       FIND A TAKE OVER REPLICA WHICH IS TO BE STARTED OR COMMITTED WHEN*/
  117. /*       TAKING OVER A FAILED NODE.                                       */
  118. /* ---------------------------------------------------------------------- */
  119. /*************************************************************************/
  120. void Dbdih::findToReplica(TakeOverRecord* regTakeOver,
  121.                           Uint32 replicaType,
  122.                           FragmentstorePtr fragPtr,
  123.                           ReplicaRecordPtr& ftrReplicaPtr)
  124. {
  125.   switch (replicaType) {
  126.   case CreateFragReq::STORED:
  127.   case CreateFragReq::COMMIT_STORED:
  128.     /* ----------------------------------------------------------------------*/
  129.     /* HERE WE SEARCH FOR STORED REPLICAS. THE REPLICA MUST BE STORED IN THE */
  130.     /* SECTION FOR OLD STORED REPLICAS SINCE WE HAVE NOT TAKEN OVER YET.     */
  131.     /* ----------------------------------------------------------------------*/
  132.     ftrReplicaPtr.i = fragPtr.p->oldStoredReplicas;
  133.     while (ftrReplicaPtr.i != RNIL) {
  134.       ptrCheckGuard(ftrReplicaPtr, creplicaFileSize, replicaRecord);
  135.       if (ftrReplicaPtr.p->procNode == regTakeOver->toStartingNode) {
  136.         jam();
  137.         return;
  138.       } else {
  139.         if (ftrReplicaPtr.p->procNode == regTakeOver->toFailedNode) {
  140.           jam();
  141.           return;
  142.         } else {
  143.           jam();
  144.           ftrReplicaPtr.i = ftrReplicaPtr.p->nextReplica;
  145.         }//if
  146.       }//if
  147.     }//while
  148.     break;
  149.   default:
  150.     ndbrequire(false);
  151.     break;
  152.   }//switch
  153. }//Dbdih::findToReplica()
  154. void Dbdih::initCommonData()
  155. {
  156.   c_blockCommit = false;
  157.   c_blockCommitNo = 0;
  158.   c_createFragmentLock = RNIL;
  159.   c_endToLock = RNIL;
  160.   cfailurenr = 1;
  161.   cfirstAliveNode = RNIL;
  162.   cfirstDeadNode = RNIL;
  163.   cfirstVerifyQueue = RNIL;
  164.   cgckptflag = false;
  165.   cgcpDelay = 0;
  166.   cgcpMasterTakeOverState = GMTOS_IDLE; 
  167.   cgcpOrderBlocked = 0;
  168.   cgcpParticipantState = GCP_PARTICIPANT_READY;
  169.   cgcpSameCounter = 0;
  170.   cgcpStartCounter = 0;
  171.   cgcpStatus = GCP_READY;
  172.   clastVerifyQueue = RNIL;
  173.   c_lcpMasterTakeOverState.set(LMTOS_IDLE, __LINE__);
  174.   c_lcpState.clcpDelay = 0;
  175.   c_lcpState.lcpStart = ZIDLE;
  176.   c_lcpState.lcpStartGcp = 0;
  177.   c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
  178.   c_lcpState.currentFragment.tableId = 0;
  179.   c_lcpState.currentFragment.fragmentId = 0;
  180.   c_lcpState.noOfLcpFragRepOutstanding = 0;
  181.   c_lcpState.keepGci = 0;
  182.   c_lcpState.oldestRestorableGci = 0;
  183.   c_lcpState.ctcCounter = 0;
  184.   c_lcpState.ctimer = 0;
  185.   c_lcpState.immediateLcpStart = false;
  186.   c_lcpState.m_MASTER_LCPREQ_Received = false;
  187.     
  188.   cmasterdihref = 0;
  189.   cmasterNodeId = 0;
  190.   cmasterState = MASTER_IDLE;
  191.   cmasterTakeOverNode = 0;
  192.   cnewgcp = 0;
  193.   cnoHotSpare = 0;
  194.   cnoOfActiveTables = 0;
  195.   cnoOfNodeGroups = 0;
  196.   cnoReplicas = 0;
  197.   coldgcp = 0;
  198.   coldGcpId = 0;
  199.   coldGcpStatus = cgcpStatus;
  200.   con_lineNodes = 0;
  201.   creceivedfrag = 0;
  202.   crestartGci = 0;
  203.   crestartInfoFile[0] = RNIL;
  204.   crestartInfoFile[1] = RNIL;
  205.   cstartGcpNow = false;
  206.   cstartPhase = 0;
  207.   c_startToLock = RNIL;
  208.   cstarttype = (Uint32)-1;
  209.   csystemnodes = 0;
  210.   c_updateToLock = RNIL;
  211.   currentgcp = 0;
  212.   cverifyQueueCounter = 0;
  213.   cwaitLcpSr = false;
  214.   nodeResetStart();
  215.   c_nodeStartMaster.wait = ZFALSE;
  216.   memset(&sysfileData[0], 0, sizeof(sysfileData));
  217.   const ndb_mgm_configuration_iterator * p = 
  218.     theConfiguration.getOwnConfigIterator();
  219.   ndbrequire(p != 0);
  220.   
  221.   c_lcpState.clcpDelay = 20;
  222.   ndb_mgm_get_int_parameter(p, CFG_DB_LCP_INTERVAL, &c_lcpState.clcpDelay);
  223.   c_lcpState.clcpDelay = c_lcpState.clcpDelay > 31 ? 31 : c_lcpState.clcpDelay;
  224.   
  225.   cminHotSpareNodes = 0;
  226.   //ndb_mgm_get_int_parameter(p, CFG_DB_MIN_HOT_SPARES, &cminHotSpareNodes);
  227.   cminHotSpareNodes = cminHotSpareNodes > 2 ? 2 : cminHotSpareNodes;
  228.   cnoReplicas = 1;
  229.   ndb_mgm_get_int_parameter(p, CFG_DB_NO_REPLICAS, &cnoReplicas);
  230.   cnoReplicas = cnoReplicas > 4 ? 4 : cnoReplicas;
  231.   cgcpDelay = 2000;
  232.   ndb_mgm_get_int_parameter(p, CFG_DB_GCP_INTERVAL, &cgcpDelay);
  233.   cgcpDelay =  cgcpDelay > 60000 ? 60000 : (cgcpDelay < 10 ? 10 : cgcpDelay);
  234. }//Dbdih::initCommonData()
  235. void Dbdih::initFragstore(FragmentstorePtr fragPtr) 
  236. {
  237.   fragPtr.p->storedReplicas = RNIL;
  238.   fragPtr.p->oldStoredReplicas = RNIL;
  239.   
  240.   fragPtr.p->noStoredReplicas = 0;
  241.   fragPtr.p->noOldStoredReplicas = 0;
  242.   fragPtr.p->fragReplicas = 0;
  243.   fragPtr.p->preferredPrimary = 0;
  244.   for (Uint32 i = 0; i < MAX_REPLICAS; i++)
  245.     fragPtr.p->activeNodes[i] = 0;
  246.   
  247.   fragPtr.p->noLcpReplicas = 0;
  248.   fragPtr.p->distributionKey = 0;
  249. }//Dbdih::initFragstore()
  250. /*************************************************************************/
  251. /*                                                                       */
  252. /*       MODULE: INIT_RESTART_INFO                                       */
  253. /*       DESCRIPTION: INITIATE RESTART INFO VARIABLE AND VARIABLES FOR   */
  254. /*                    GLOBAL CHECKPOINTS.                                */
  255. /*************************************************************************/
  256. void Dbdih::initRestartInfo() 
  257. {
  258.   Uint32 i;
  259.   for (i = 0; i < MAX_NDB_NODES; i++) {
  260.     SYSFILE->lastCompletedGCI[i] = 0;
  261.   }//for
  262.   NodeRecordPtr nodePtr;
  263.   nodePtr.i = cfirstAliveNode;
  264.   do {
  265.     jam();
  266.     ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
  267.     SYSFILE->lastCompletedGCI[nodePtr.i] = 1;
  268.     /* FIRST GCP = 1 ALREADY SET BY LQH */
  269.     nodePtr.i = nodePtr.p->nextNode;
  270.   } while (nodePtr.i != RNIL);
  271.   coldgcp = 1;
  272.   currentgcp = 2;
  273.   cnewgcp = 2;
  274.   crestartGci = 1;
  275.   SYSFILE->keepGCI             = 1;
  276.   SYSFILE->oldestRestorableGCI = 1;
  277.   SYSFILE->newestRestorableGCI = 1;
  278.   SYSFILE->systemRestartBits   = 0;
  279.   for (i = 0; i < NodeBitmask::Size; i++) {
  280.     SYSFILE->lcpActive[0]        = 0;
  281.   }//for  
  282.   for (i = 0; i < Sysfile::TAKE_OVER_SIZE; i++) {
  283.     SYSFILE->takeOver[i] = 0;
  284.   }//for
  285.   Sysfile::setInitialStartOngoing(SYSFILE->systemRestartBits);
  286. }//Dbdih::initRestartInfo()
  287. /*--------------------------------------------------------------------*/
  288. /*       NODE GROUP BITS ARE INITIALISED BEFORE THIS.                 */
  289. /*       NODE ACTIVE BITS ARE INITIALISED BEFORE THIS.                */
  290. /*--------------------------------------------------------------------*/
  291. /*************************************************************************/
  292. /*                                                                       */
  293. /*       MODULE: INIT_RESTORABLE_GCI_FILES                               */
  294. /*       DESCRIPTION: THE SUBROUTINE SETS UP THE FILES THAT REFERS TO THE*/
  295. /*       FILES THAT KEEP THE VARIABLE CRESTART_INFO                      */
  296. /*************************************************************************/
  297. void Dbdih::initRestorableGciFiles() 
  298. {
  299.   Uint32 tirgTmp;
  300.   FileRecordPtr filePtr;
  301.   seizeFile(filePtr);
  302.   filePtr.p->tabRef = RNIL;
  303.   filePtr.p->fileType = FileRecord::GCP_FILE;
  304.   filePtr.p->reqStatus = FileRecord::IDLE;
  305.   filePtr.p->fileStatus = FileRecord::CLOSED;
  306.   crestartInfoFile[0] = filePtr.i;
  307.   filePtr.p->fileName[0] = (Uint32)-1;  /* T DIRECTORY NOT USED  */
  308.   filePtr.p->fileName[1] = (Uint32)-1;  /* F DIRECTORY NOT USED  */
  309.   filePtr.p->fileName[2] = (Uint32)-1;  /* S PART IGNORED        */
  310.   tirgTmp = 1;  /* FILE NAME VERSION 1   */
  311.   tirgTmp = (tirgTmp << 8) + 6; /* .SYSFILE              */
  312.   tirgTmp = (tirgTmp << 8) + 1; /* D1 DIRECTORY          */
  313.   tirgTmp = (tirgTmp << 8) + 0; /* P0 FILE NAME          */
  314.   filePtr.p->fileName[3] = tirgTmp;
  315.   /* --------------------------------------------------------------------- */
  316.   /*       THE NAME BECOMES /D1/DBDICT/S0.SYSFILE                          */
  317.   /* --------------------------------------------------------------------- */
  318.   seizeFile(filePtr);
  319.   filePtr.p->tabRef = RNIL;
  320.   filePtr.p->fileType = FileRecord::GCP_FILE;
  321.   filePtr.p->reqStatus = FileRecord::IDLE;
  322.   filePtr.p->fileStatus = FileRecord::CLOSED;
  323.   crestartInfoFile[1] = filePtr.i;
  324.   filePtr.p->fileName[0] = (Uint32)-1;  /* T DIRECTORY NOT USED  */
  325.   filePtr.p->fileName[1] = (Uint32)-1;  /* F DIRECTORY NOT USED  */
  326.   filePtr.p->fileName[2] = (Uint32)-1;  /* S PART IGNORED        */
  327.   tirgTmp = 1;  /* FILE NAME VERSION 1   */
  328.   tirgTmp = (tirgTmp << 8) + 6; /* .SYSFILE              */
  329.   tirgTmp = (tirgTmp << 8) + 2; /* D1 DIRECTORY          */
  330.   tirgTmp = (tirgTmp << 8) + 0; /* P0 FILE NAME          */
  331.   filePtr.p->fileName[3] = tirgTmp;
  332.   /* --------------------------------------------------------------------- */
  333.   /*       THE NAME BECOMES /D2/DBDICT/P0.SYSFILE                          */
  334.   /* --------------------------------------------------------------------- */
  335. }//Dbdih::initRestorableGciFiles()
  336. void Dbdih::initTable(TabRecordPtr tabPtr)
  337. {
  338.   tabPtr.p->noOfFragChunks = 0;
  339.   tabPtr.p->method = TabRecord::NOTDEFINED;
  340.   tabPtr.p->tabStatus = TabRecord::TS_IDLE;
  341.   tabPtr.p->noOfWords = 0;
  342.   tabPtr.p->noPages = 0;
  343.   tabPtr.p->tabLcpStatus = TabRecord::TLS_COMPLETED;
  344.   tabPtr.p->tabCopyStatus = TabRecord::CS_IDLE;
  345.   tabPtr.p->tabUpdateState = TabRecord::US_IDLE;
  346.   tabPtr.p->noOfBackups = 0;
  347.   tabPtr.p->kvalue = 0;
  348.   tabPtr.p->hashpointer = (Uint32)-1;
  349.   tabPtr.p->mask = 0;
  350.   tabPtr.p->storedTable = 1;
  351.   tabPtr.p->tabErrorCode = 0;
  352.   tabPtr.p->schemaVersion = (Uint32)-1;
  353.   tabPtr.p->tabRemoveNode = RNIL;
  354.   tabPtr.p->totalfragments = (Uint32)-1;
  355.   tabPtr.p->connectrec = RNIL;
  356.   tabPtr.p->tabFile[0] = RNIL;
  357.   tabPtr.p->tabFile[1] = RNIL;
  358.   tabPtr.p->m_dropTab.tabUserRef = 0;
  359.   tabPtr.p->m_dropTab.tabUserPtr = RNIL;
  360.   Uint32 i;
  361.   for (i = 0; i < MAX_NDB_NODES; i++) {
  362.     tabPtr.p->startFid[i] = RNIL;
  363.   }//for
  364.   for (i = 0; i < 8; i++) {
  365.     tabPtr.p->pageRef[i] = RNIL;
  366.   }//for
  367.   tabPtr.p->tableType = DictTabInfo::UndefTableType;
  368. }//Dbdih::initTable()
  369. /*************************************************************************/
  370. /*                                                                       */
  371. /*       MODULE: INIT_TABLE_FILES                                        */
  372. /*       DESCRIPTION: THE SUBROUTINE SETS UP THE FILES THAT REFERS TO THE*/
  373. /*       FILES THAT KEEP THE TABLE FRAGMENTATION DESCRIPTION.            */
  374. /*************************************************************************/
  375. void Dbdih::initTableFile(TabRecordPtr tabPtr)
  376. {
  377.   Uint32 titfTmp;
  378.   FileRecordPtr filePtr;
  379.   seizeFile(filePtr);
  380.   filePtr.p->tabRef = tabPtr.i;
  381.   filePtr.p->fileType = FileRecord::TABLE_FILE;
  382.   filePtr.p->reqStatus = FileRecord::IDLE;
  383.   filePtr.p->fileStatus = FileRecord::CLOSED;
  384.   tabPtr.p->tabFile[0] = filePtr.i;
  385.   filePtr.p->fileName[0] = (Uint32)-1;  /* T DIRECTORY NOT USED  */
  386.   filePtr.p->fileName[1] = (Uint32)-1;  /* F DIRECTORY NOT USED  */
  387.   filePtr.p->fileName[2] = tabPtr.i;    /* Stid FILE NAME        */
  388.   titfTmp = 1;  /* FILE NAME VERSION 1   */
  389.   titfTmp = (titfTmp << 8) + 3; /* .FRAGLIST             */
  390.   titfTmp = (titfTmp << 8) + 1; /* D1 DIRECTORY          */
  391.   titfTmp = (titfTmp << 8) + 255;       /* P PART IGNORED        */
  392.   filePtr.p->fileName[3] = titfTmp;
  393.   /* --------------------------------------------------------------------- */
  394.   /*       THE NAME BECOMES /D1/DBDICT/Stid.FRAGLIST                       */
  395.   /* --------------------------------------------------------------------- */
  396.   seizeFile(filePtr);
  397.   filePtr.p->tabRef = tabPtr.i;
  398.   filePtr.p->fileType = FileRecord::TABLE_FILE;
  399.   filePtr.p->reqStatus = FileRecord::IDLE;
  400.   filePtr.p->fileStatus = FileRecord::CLOSED;
  401.   tabPtr.p->tabFile[1] = filePtr.i;
  402.   filePtr.p->fileName[0] = (Uint32)-1;  /* T DIRECTORY NOT USED  */
  403.   filePtr.p->fileName[1] = (Uint32)-1;  /* F DIRECTORY NOT USED  */
  404.   filePtr.p->fileName[2] = tabPtr.i;    /* Stid FILE NAME        */
  405.   titfTmp = 1;  /* FILE NAME VERSION 1   */
  406.   titfTmp = (titfTmp << 8) + 3; /* .FRAGLIST             */
  407.   titfTmp = (titfTmp << 8) + 2; /* D2 DIRECTORY          */
  408.   titfTmp = (titfTmp << 8) + 255;       /* P PART IGNORED        */
  409.   filePtr.p->fileName[3] = titfTmp;
  410.   /* --------------------------------------------------------------------- */
  411.   /*       THE NAME BECOMES /D2/DBDICT/Stid.FRAGLIST                       */
  412.   /* --------------------------------------------------------------------- */
  413. }//Dbdih::initTableFile()
  414. void Dbdih::initialiseRecordsLab(Signal* signal, 
  415.  Uint32 stepNo, Uint32 retRef, Uint32 retData) 
  416. {
  417.   switch (stepNo) {
  418.   case 0:
  419.     jam();
  420.     initCommonData();
  421.     break;
  422.   case 1:{
  423.     ApiConnectRecordPtr apiConnectptr;
  424.     jam();
  425.     /******** INTIALIZING API CONNECT RECORDS ********/
  426.     for (apiConnectptr.i = 0; apiConnectptr.i < capiConnectFileSize; apiConnectptr.i++) {
  427.       refresh_watch_dog();
  428.       ptrAss(apiConnectptr, apiConnectRecord);
  429.       apiConnectptr.p->nextApi = RNIL;
  430.     }//for
  431.     jam();
  432.     break;
  433.   }
  434.   case 2:{
  435.     ConnectRecordPtr connectPtr;
  436.     jam();
  437.     /****** CONNECT ******/
  438.     for (connectPtr.i = 0; connectPtr.i < cconnectFileSize; connectPtr.i++) {
  439.       refresh_watch_dog();
  440.       ptrAss(connectPtr, connectRecord);
  441.       connectPtr.p->userpointer = RNIL;
  442.       connectPtr.p->userblockref = ZNIL;
  443.       connectPtr.p->connectState = ConnectRecord::FREE;
  444.       connectPtr.p->table = RNIL;
  445.       connectPtr.p->nfConnect = connectPtr.i + 1;
  446.     }//for
  447.     connectPtr.i = cconnectFileSize - 1;
  448.     ptrAss(connectPtr, connectRecord);
  449.     connectPtr.p->nfConnect = RNIL;
  450.     cfirstconnect = 0;
  451.     break;
  452.   }
  453.   case 3:
  454.     {
  455.       FileRecordPtr filePtr;
  456.       jam();
  457.       /******** INTIALIZING FILE RECORDS ********/
  458.       for (filePtr.i = 0; filePtr.i < cfileFileSize; filePtr.i++) {
  459. ptrAss(filePtr, fileRecord);
  460. filePtr.p->nextFile = filePtr.i + 1;
  461. filePtr.p->fileStatus = FileRecord::CLOSED;
  462. filePtr.p->reqStatus = FileRecord::IDLE;
  463.       }//for
  464.       filePtr.i = cfileFileSize - 1;
  465.       ptrAss(filePtr, fileRecord);
  466.       filePtr.p->nextFile = RNIL;
  467.       cfirstfreeFile = 0;
  468.       initRestorableGciFiles();
  469.       break;
  470.     }
  471.   case 4:
  472.     jam();
  473.     initialiseFragstore();
  474.     break;
  475.   case 5:
  476.     {
  477.       jam();
  478.       /******* NODE GROUP RECORD ******/
  479.       /******* NODE RECORD       ******/
  480.       NodeGroupRecordPtr loopNGPtr;
  481.       for (loopNGPtr.i = 0; loopNGPtr.i < MAX_NDB_NODES; loopNGPtr.i++) {
  482. ptrAss(loopNGPtr, nodeGroupRecord);
  483. loopNGPtr.p->nodesInGroup[0] = RNIL;
  484. loopNGPtr.p->nodesInGroup[1] = RNIL;
  485. loopNGPtr.p->nodesInGroup[2] = RNIL;
  486. loopNGPtr.p->nodesInGroup[3] = RNIL;
  487. loopNGPtr.p->nextReplicaNode = 0;
  488. loopNGPtr.p->nodeCount = 0;
  489. loopNGPtr.p->activeTakeOver = false;
  490.       }//for
  491.       NodeRecordPtr nodePtr;
  492.       for (nodePtr.i = 0; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
  493. ptrAss(nodePtr, nodeRecord);
  494. new (nodePtr.p) NodeRecord();
  495.       }//for
  496.       break;
  497.     }
  498.   case 6:
  499.     {
  500.       PageRecordPtr pagePtr;
  501.       jam();
  502.       /******* PAGE RECORD ******/
  503.       for (pagePtr.i = 0; pagePtr.i < cpageFileSize; pagePtr.i++) {
  504.         refresh_watch_dog();
  505. ptrAss(pagePtr, pageRecord);
  506. pagePtr.p->nextfreepage = pagePtr.i + 1;
  507.       }//for
  508.       pagePtr.i = cpageFileSize - 1;
  509.       ptrAss(pagePtr, pageRecord);
  510.       pagePtr.p->nextfreepage = RNIL;
  511.       cfirstfreepage = 0;
  512.       break;
  513.     }
  514.   case 7:
  515.     {
  516.       ReplicaRecordPtr initReplicaPtr;
  517.       jam();
  518.       /******* REPLICA RECORD ******/
  519.       for (initReplicaPtr.i = 0; initReplicaPtr.i < creplicaFileSize;
  520.    initReplicaPtr.i++) {
  521.         refresh_watch_dog();
  522. ptrAss(initReplicaPtr, replicaRecord);
  523. initReplicaPtr.p->lcpIdStarted = 0;
  524. initReplicaPtr.p->lcpOngoingFlag = false;
  525. initReplicaPtr.p->nextReplica = initReplicaPtr.i + 1;
  526.       }//for
  527.       initReplicaPtr.i = creplicaFileSize - 1;
  528.       ptrAss(initReplicaPtr, replicaRecord);
  529.       initReplicaPtr.p->nextReplica = RNIL;
  530.       cnoFreeReplicaRec = creplicaFileSize;
  531.       cfirstfreeReplica = 0;
  532.       break;
  533.     }
  534.   case 8:
  535.     {
  536.       TabRecordPtr loopTabptr;
  537.       jam();
  538.       /********* TAB-DESCRIPTOR ********/
  539.       for (loopTabptr.i = 0; loopTabptr.i < ctabFileSize; loopTabptr.i++) {
  540. ptrAss(loopTabptr, tabRecord);
  541.         refresh_watch_dog();
  542. initTable(loopTabptr);
  543.       }//for
  544.       break;
  545.     }
  546.   case 9:
  547.     {
  548.       TakeOverRecordPtr takeOverPtr;
  549.       jam();
  550.       cfirstfreeTakeOver = RNIL;
  551.       for (takeOverPtr.i = 0; takeOverPtr.i < MAX_NDB_NODES; takeOverPtr.i++) {
  552. ptrAss(takeOverPtr, takeOverRecord);
  553. initTakeOver(takeOverPtr);
  554. releaseTakeOver(takeOverPtr.i);
  555.       }//for
  556.       ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
  557.       conf->senderRef = reference();
  558.       conf->senderData = retData;
  559.       sendSignal(retRef, GSN_READ_CONFIG_CONF, signal, 
  560.  ReadConfigConf::SignalLength, JBB);
  561.       return;
  562.       break;
  563.     }
  564.   default:
  565.     ndbrequire(false);
  566.     break;
  567.   }//switch
  568.   jam();
  569.   /* ---------------------------------------------------------------------- */
  570.   /* SEND REAL-TIME BREAK DURING INIT OF VARIABLES DURING SYSTEM RESTART.   */
  571.   /* ---------------------------------------------------------------------- */
  572.   signal->theData[0] = DihContinueB::ZINITIALISE_RECORDS;
  573.   signal->theData[1] = stepNo + 1;
  574.   signal->theData[2] = retRef;
  575.   signal->theData[3] = retData;
  576.   sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB);
  577. }//Dbdih::initialiseRecordsLab()
  578. /*************************************************************************/
  579. /*       INSERT THE NODE INTO THE LINKED LIST OF NODES INVOLVED ALL      */
  580. /*       DISTRIBUTED PROTOCOLS (EXCEPT GCP PROTOCOL THAT USES THE DIH    */
  581. /*       LINKED LIST INSTEAD).                                           */
  582. /*************************************************************************/
  583. void Dbdih::insertAlive(NodeRecordPtr newNodePtr) 
  584. {
  585.   NodeRecordPtr nodePtr;
  586.   nodePtr.i = cfirstAliveNode;
  587.   if (nodePtr.i == RNIL) {
  588.     jam();
  589.     cfirstAliveNode = newNodePtr.i;
  590.   } else {
  591.     do {
  592.       ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
  593.       if (nodePtr.p->nextNode == RNIL) {
  594.         jam();
  595.         nodePtr.p->nextNode = newNodePtr.i;
  596.         break;
  597.       } else {
  598.         jam();
  599.         nodePtr.i = nodePtr.p->nextNode;
  600.       }//if
  601.     } while (1);
  602.   }//if
  603.   newNodePtr.p->nextNode = RNIL;
  604. }//Dbdih::insertAlive()
  605. void Dbdih::insertBackup(FragmentstorePtr fragPtr, Uint32 nodeId)
  606. {
  607.   for (Uint32 i = fragPtr.p->fragReplicas; i > 1; i--) {
  608.     jam();
  609.     ndbrequire(i < MAX_REPLICAS && i > 0);
  610.     fragPtr.p->activeNodes[i] = fragPtr.p->activeNodes[i - 1];
  611.   }//for
  612.   fragPtr.p->activeNodes[1] = nodeId;
  613.   fragPtr.p->fragReplicas++;
  614. }//Dbdih::insertBackup()
  615. void Dbdih::insertDeadNode(NodeRecordPtr newNodePtr) 
  616. {
  617.   NodeRecordPtr nodePtr;
  618.   nodePtr.i = cfirstDeadNode;
  619.   if (nodePtr.i == RNIL) {
  620.     jam();
  621.     cfirstDeadNode = newNodePtr.i;
  622.   } else {
  623.     do {
  624.       jam();
  625.       ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
  626.       if (nodePtr.p->nextNode == RNIL) {
  627.         jam();
  628.         nodePtr.p->nextNode = newNodePtr.i;
  629.         break;
  630.       } else {
  631.         jam();
  632.         nodePtr.i = nodePtr.p->nextNode;
  633.       }//if
  634.     } while (1);
  635.   }//if
  636.   newNodePtr.p->nextNode = RNIL;
  637. }//Dbdih::insertDeadNode()
  638. void Dbdih::linkOldStoredReplica(FragmentstorePtr fragPtr,
  639.                                  ReplicaRecordPtr replicatePtr) 
  640. {
  641.   ReplicaRecordPtr losReplicaPtr;
  642.   replicatePtr.p->nextReplica = RNIL;
  643.   fragPtr.p->noOldStoredReplicas++;
  644.   losReplicaPtr.i = fragPtr.p->oldStoredReplicas;
  645.   if (losReplicaPtr.i == RNIL) {
  646.     jam();
  647.     fragPtr.p->oldStoredReplicas = replicatePtr.i;
  648.     return;
  649.   }//if
  650.   ptrCheckGuard(losReplicaPtr, creplicaFileSize, replicaRecord);
  651.   while (losReplicaPtr.p->nextReplica != RNIL) {
  652.     jam();
  653.     losReplicaPtr.i = losReplicaPtr.p->nextReplica;
  654.     ptrCheckGuard(losReplicaPtr, creplicaFileSize, replicaRecord);
  655.   }//if
  656.   losReplicaPtr.p->nextReplica = replicatePtr.i;
  657. }//Dbdih::linkOldStoredReplica()
  658. void Dbdih::linkStoredReplica(FragmentstorePtr fragPtr,
  659.                               ReplicaRecordPtr replicatePtr)
  660. {
  661.   ReplicaRecordPtr lsrReplicaPtr;
  662.   fragPtr.p->noStoredReplicas++;
  663.   replicatePtr.p->nextReplica = RNIL;
  664.   lsrReplicaPtr.i = fragPtr.p->storedReplicas;
  665.   if (fragPtr.p->storedReplicas == RNIL) {
  666.     jam();
  667.     fragPtr.p->storedReplicas = replicatePtr.i;
  668.     return;
  669.   }//if
  670.   ptrCheckGuard(lsrReplicaPtr, creplicaFileSize, replicaRecord);
  671.   while (lsrReplicaPtr.p->nextReplica != RNIL) {
  672.     jam();
  673.     lsrReplicaPtr.i = lsrReplicaPtr.p->nextReplica;
  674.     ptrCheckGuard(lsrReplicaPtr, creplicaFileSize, replicaRecord);
  675.   }//if
  676.   lsrReplicaPtr.p->nextReplica = replicatePtr.i;
  677. }//Dbdih::linkStoredReplica()
  678. /*************************************************************************/
  679. /*        MAKE NODE GROUPS BASED ON THE LIST OF NODES RECEIVED FROM CNTR */
  680. /*************************************************************************/
  681. void Dbdih::makeNodeGroups(Uint32 nodeArray[]) 
  682. {
  683.   NodeRecordPtr mngNodeptr;
  684.   Uint32 tmngNode;
  685.   Uint32 tmngNodeGroup;
  686.   Uint32 tmngReplica;
  687.   Uint32 tmngLimit;
  688.   Uint32 i;
  689.   /**-----------------------------------------------------------------------
  690.    * ASSIGN ALL ACTIVE NODES INTO NODE GROUPS. HOT SPARE NODES ARE ASSIGNED 
  691.    * TO NODE GROUP ZNIL
  692.    *-----------------------------------------------------------------------*/
  693.   tmngNodeGroup = 0;
  694.   tmngReplica = 0;
  695.   tmngLimit = csystemnodes - cnoHotSpare;
  696.   ndbrequire(tmngLimit < MAX_NDB_NODES);
  697.   for (i = 0; i < tmngLimit; i++) {
  698.     NodeGroupRecordPtr NGPtr;
  699.     jam();
  700.     tmngNode = nodeArray[i];
  701.     mngNodeptr.i = tmngNode;
  702.     ptrCheckGuard(mngNodeptr, MAX_NDB_NODES, nodeRecord);
  703.     mngNodeptr.p->nodeGroup = tmngNodeGroup;
  704.     NGPtr.i = tmngNodeGroup;
  705.     ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
  706.     arrGuard(tmngReplica, MAX_REPLICAS);
  707.     NGPtr.p->nodesInGroup[tmngReplica] = mngNodeptr.i;
  708.     tmngReplica++;
  709.     if (tmngReplica == cnoReplicas) {
  710.       jam();
  711.       tmngNodeGroup++;
  712.       tmngReplica = 0;
  713.     }//if
  714.   }//for
  715.   cnoOfNodeGroups = tmngNodeGroup;
  716.   ndbrequire(csystemnodes < MAX_NDB_NODES);
  717.   for (i = tmngLimit + 1; i < csystemnodes; i++) {
  718.     jam();
  719.     tmngNode = nodeArray[i];
  720.     mngNodeptr.i = tmngNode;
  721.     ptrCheckGuard(mngNodeptr, MAX_NDB_NODES, nodeRecord);
  722.     mngNodeptr.p->nodeGroup = ZNIL;
  723.   }//for
  724.   for(i = 0; i < MAX_NDB_NODES; i++){
  725.     jam();
  726.     Sysfile::setNodeGroup(i, SYSFILE->nodeGroups, NO_NODE_GROUP_ID);
  727.   }//for
  728.   for (mngNodeptr.i = 1; mngNodeptr.i < MAX_NDB_NODES; mngNodeptr.i++) {
  729.     jam();
  730.     ptrAss(mngNodeptr, nodeRecord);
  731.     if (mngNodeptr.p->nodeGroup != ZNIL) {
  732.       jam();
  733.       Sysfile::setNodeGroup(mngNodeptr.i, SYSFILE->nodeGroups, mngNodeptr.p->nodeGroup);
  734.     }//if
  735.   }//for
  736. }//Dbdih::makeNodeGroups()
  737. /**
  738.  * On node failure QMGR asks DIH about node groups.  This is
  739.  * a direct signal (function call in same process).  Input is
  740.  * bitmask of surviving nodes.  The routine is not concerned
  741.  * about node count.  Reply is one of:
  742.  * 1) win - we can survive, and nobody else can
  743.  * 2) lose - we cannot survive
  744.  * 3) partition - we can survive but there could be others
  745.  */
  746. void Dbdih::execCHECKNODEGROUPSREQ(Signal* signal)
  747. {
  748.   jamEntry();
  749.   CheckNodeGroups* sd = (CheckNodeGroups*)&signal->theData[0];
  750.   bool direct = (sd->requestType & CheckNodeGroups::Direct);
  751.   bool ok = false;
  752.   switch(sd->requestType & ~CheckNodeGroups::Direct){
  753.   case CheckNodeGroups::ArbitCheck:{
  754.     ok = true;
  755.     jam();
  756.     unsigned missall = 0;
  757.     unsigned haveall = 0;
  758.     for (Uint32 i = 0; i < cnoOfNodeGroups; i++) {
  759.       jam();
  760.       NodeGroupRecordPtr ngPtr;
  761.       ngPtr.i = i;
  762.       ptrAss(ngPtr, nodeGroupRecord);
  763.       Uint32 count = 0;
  764.       for (Uint32 j = 0; j < ngPtr.p->nodeCount; j++) {
  765. jam();
  766. Uint32 nodeId = ngPtr.p->nodesInGroup[j];
  767. if (sd->mask.get(nodeId)) {
  768.   jam();
  769.   count++;
  770. }//if
  771.       }//for
  772.       if (count == 0) {
  773. jam();
  774. missall++;
  775.       }//if
  776.       if (count == ngPtr.p->nodeCount) {
  777. haveall++;
  778.       }//if
  779.     }//for
  780.     if (missall) {
  781.       jam();
  782.       sd->output = CheckNodeGroups::Lose;
  783.     } else if (haveall) {
  784.       jam();
  785.       sd->output = CheckNodeGroups::Win;
  786.     } else {
  787.       jam();
  788.       sd->output = CheckNodeGroups::Partitioning;
  789.     }//if
  790.   }
  791.     break;
  792.   case CheckNodeGroups::GetNodeGroup:
  793.     ok = true;
  794.     sd->output = Sysfile::getNodeGroup(getOwnNodeId(), SYSFILE->nodeGroups);
  795.     break;
  796.   case CheckNodeGroups::GetNodeGroupMembers: {
  797.     ok = true;
  798.     Uint32 ownNodeGoup =
  799.       Sysfile::getNodeGroup(sd->nodeId, SYSFILE->nodeGroups);
  800.     sd->output = ownNodeGoup;
  801.     sd->mask.clear();
  802.     NodeGroupRecordPtr ngPtr;
  803.     ngPtr.i = ownNodeGoup;
  804.     ptrAss(ngPtr, nodeGroupRecord);
  805.     for (Uint32 j = 0; j < ngPtr.p->nodeCount; j++) {
  806.       jam();
  807.       sd->mask.set(ngPtr.p->nodesInGroup[j]);
  808.     }
  809. #if 0
  810.     for (int i = 0; i < MAX_NDB_NODES; i++) {
  811.       if (ownNodeGoup == 
  812.   Sysfile::getNodeGroup(i, SYSFILE->nodeGroups)) {
  813. sd->mask.set(i);
  814.       }
  815.     }
  816. #endif
  817.   }
  818.     break;
  819.   }
  820.   ndbrequire(ok);
  821.   
  822.   if (!direct)
  823.     sendSignal(sd->blockRef, GSN_CHECKNODEGROUPSCONF, signal,
  824.        CheckNodeGroups::SignalLength, JBB);
  825. }//Dbdih::execCHECKNODEGROUPSREQ()
  826. void Dbdih::makePrnList(ReadNodesConf * readNodes, Uint32 nodeArray[]) 
  827. {
  828.   cfirstAliveNode = RNIL;
  829.   ndbrequire(con_lineNodes > 0);
  830.   ndbrequire(csystemnodes < MAX_NDB_NODES);
  831.   for (Uint32 i = 0; i < csystemnodes; i++) {
  832.     NodeRecordPtr nodePtr;
  833.     jam();
  834.     nodePtr.i = nodeArray[i];
  835.     ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
  836.     new (nodePtr.p) NodeRecord();
  837.     if (NodeBitmask::get(readNodes->inactiveNodes, nodePtr.i) == false){
  838.       jam();
  839.       nodePtr.p->nodeStatus = NodeRecord::ALIVE;
  840.       nodePtr.p->useInTransactions = true;
  841.       nodePtr.p->copyCompleted = true;
  842.       nodePtr.p->m_inclDihLcp = true;
  843.       insertAlive(nodePtr);
  844.     } else {
  845.       jam();
  846.       nodePtr.p->nodeStatus = NodeRecord::DEAD;
  847.       insertDeadNode(nodePtr);
  848.     }//if
  849.   }//for
  850. }//Dbdih::makePrnList()
  851. /*************************************************************************/
  852. /*       A NEW CRASHED REPLICA IS ADDED BY A NODE FAILURE.               */
  853. /*************************************************************************/
  854. void Dbdih::newCrashedReplica(Uint32 nodeId, ReplicaRecordPtr ncrReplicaPtr) 
  855. {
  856.   /*----------------------------------------------------------------------*/
  857.   /*       SET THE REPLICA_LAST_GCI OF THE CRASHED REPLICA TO LAST GCI    */
  858.   /*       EXECUTED BY THE FAILED NODE.                                   */
  859.   /*----------------------------------------------------------------------*/
  860.   /*       WE HAVE A NEW CRASHED REPLICA. INITIATE CREATE GCI TO INDICATE */
  861.   /*       THAT THE NEW REPLICA IS NOT STARTED YET AND REPLICA_LAST_GCI IS*/
  862.   /*       SET TO -1 TO INDICATE THAT IT IS NOT DEAD YET.                 */
  863.   /*----------------------------------------------------------------------*/
  864.   arrGuard(ncrReplicaPtr.p->noCrashedReplicas + 1, 8);
  865.   ncrReplicaPtr.p->replicaLastGci[ncrReplicaPtr.p->noCrashedReplicas] = 
  866.     SYSFILE->lastCompletedGCI[nodeId];
  867.   ncrReplicaPtr.p->noCrashedReplicas = ncrReplicaPtr.p->noCrashedReplicas + 1;
  868.   ncrReplicaPtr.p->createGci[ncrReplicaPtr.p->noCrashedReplicas] = 0;
  869.   ncrReplicaPtr.p->replicaLastGci[ncrReplicaPtr.p->noCrashedReplicas] = 
  870.     (Uint32)-1;
  871. }//Dbdih::newCrashedReplica()
  872. /*************************************************************************/
  873. /*       AT NODE FAILURE DURING START OF A NEW NODE WE NEED TO RESET A   */
  874. /*       SET OF VARIABLES CONTROLLING THE START AND INDICATING ONGOING   */
  875. /*       START OF A NEW NODE.                                            */
  876. /*************************************************************************/
  877. void Dbdih::nodeResetStart()
  878. {
  879.   jam();
  880.   c_nodeStartMaster.startNode = RNIL;
  881.   c_nodeStartMaster.failNr = cfailurenr;
  882.   c_nodeStartMaster.activeState = false;
  883.   c_nodeStartMaster.blockGcp = false;
  884.   c_nodeStartMaster.blockLcp = false;
  885.   c_nodeStartMaster.m_outstandingGsn = 0;
  886. }//Dbdih::nodeResetStart()
  887. void Dbdih::openFileRw(Signal* signal, FileRecordPtr filePtr) 
  888. {
  889.   signal->theData[0] = reference();
  890.   signal->theData[1] = filePtr.i;
  891.   signal->theData[2] = filePtr.p->fileName[0];
  892.   signal->theData[3] = filePtr.p->fileName[1];
  893.   signal->theData[4] = filePtr.p->fileName[2];
  894.   signal->theData[5] = filePtr.p->fileName[3];
  895.   signal->theData[6] = FsOpenReq::OM_READWRITE;
  896.   sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, 7, JBA);
  897. }//Dbdih::openFileRw()
  898. void Dbdih::openFileRo(Signal* signal, FileRecordPtr filePtr) 
  899. {
  900.   signal->theData[0] = reference();
  901.   signal->theData[1] = filePtr.i;
  902.   signal->theData[2] = filePtr.p->fileName[0];
  903.   signal->theData[3] = filePtr.p->fileName[1];
  904.   signal->theData[4] = filePtr.p->fileName[2];
  905.   signal->theData[5] = filePtr.p->fileName[3];
  906.   signal->theData[6] = FsOpenReq::OM_READONLY;
  907.   sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, 7, JBA);
  908. }//Dbdih::openFileRw()
  909. /*************************************************************************/
  910. /*       REMOVE A CRASHED REPLICA BY PACKING THE ARRAY OF CREATED GCI AND*/
  911. /*       THE LAST GCI OF THE CRASHED REPLICA.                            */
  912. /*************************************************************************/
  913. void Dbdih::packCrashedReplicas(ReplicaRecordPtr replicaPtr)
  914. {
  915.   ndbrequire(replicaPtr.p->noCrashedReplicas > 0);
  916.   ndbrequire(replicaPtr.p->noCrashedReplicas <= 8);
  917.   for (Uint32 i = 0; i < replicaPtr.p->noCrashedReplicas; i++) {
  918.     jam();
  919.     replicaPtr.p->createGci[i] = replicaPtr.p->createGci[i + 1];
  920.     replicaPtr.p->replicaLastGci[i] = replicaPtr.p->replicaLastGci[i + 1];
  921.   }//for
  922.   replicaPtr.p->noCrashedReplicas--;
  923. #ifdef VM_TRACE
  924.   for (Uint32 i = 0; i < replicaPtr.p->noCrashedReplicas; i++) {
  925.     jam();
  926.     ndbrequire(replicaPtr.p->createGci[i] != 0xF1F1F1F1);
  927.     ndbrequire(replicaPtr.p->replicaLastGci[i] != 0xF1F1F1F1);
  928.   }//for
  929. #endif
  930. }//Dbdih::packCrashedReplicas()
  931. void Dbdih::prepareReplicas(FragmentstorePtr fragPtr)
  932. {
  933.   ReplicaRecordPtr prReplicaPtr;
  934.   Uint32 prevReplica = RNIL;
  935.   /* --------------------------------------------------------------------- */
  936.   /*       BEGIN BY LINKING ALL REPLICA RECORDS ONTO THE OLD STORED REPLICA*/
  937.   /*       LIST.                                                           */
  938.   /*       AT A SYSTEM RESTART OBVIOUSLY ALL NODES ARE OLD.                */
  939.   /* --------------------------------------------------------------------- */
  940.   prReplicaPtr.i = fragPtr.p->storedReplicas;
  941.   while (prReplicaPtr.i != RNIL) {
  942.     jam();
  943.     prevReplica = prReplicaPtr.i;
  944.     ptrCheckGuard(prReplicaPtr, creplicaFileSize, replicaRecord);
  945.     prReplicaPtr.i = prReplicaPtr.p->nextReplica;
  946.   }//while
  947.   /* --------------------------------------------------------------------- */
  948.   /*       LIST OF STORED REPLICAS WILL BE EMPTY NOW.                      */
  949.   /* --------------------------------------------------------------------- */
  950.   if (prevReplica != RNIL) {
  951.     prReplicaPtr.i = prevReplica;
  952.     ptrCheckGuard(prReplicaPtr, creplicaFileSize, replicaRecord);
  953.     prReplicaPtr.p->nextReplica = fragPtr.p->oldStoredReplicas;
  954.     fragPtr.p->oldStoredReplicas = fragPtr.p->storedReplicas;
  955.     fragPtr.p->storedReplicas = RNIL;
  956.     fragPtr.p->noOldStoredReplicas += fragPtr.p->noStoredReplicas;
  957.     fragPtr.p->noStoredReplicas = 0;
  958.   }//if
  959. }//Dbdih::prepareReplicas()
  960. void Dbdih::readFragment(RWFragment* rf, FragmentstorePtr fragPtr)
  961. {
  962.   Uint32 TreadFid = readPageWord(rf);
  963.   fragPtr.p->preferredPrimary = readPageWord(rf);
  964.   fragPtr.p->noStoredReplicas = readPageWord(rf);
  965.   fragPtr.p->noOldStoredReplicas = readPageWord(rf);
  966.   Uint32 TdistKey = readPageWord(rf);
  967.   ndbrequire(fragPtr.p->noStoredReplicas > 0);
  968.   ndbrequire(TreadFid == rf->fragId);  
  969.   ndbrequire(TdistKey < 256);
  970.   if ((cstarttype == NodeState::ST_NODE_RESTART) || 
  971.       (cstarttype == NodeState::ST_INITIAL_NODE_RESTART)) {
  972.     jam();
  973.     fragPtr.p->distributionKey = TdistKey;
  974.   }//if
  975. }//Dbdih::readFragment()
  976. Uint32 Dbdih::readPageWord(RWFragment* rf) 
  977. {
  978.   if (rf->wordIndex >= 2048) {
  979.     jam();
  980.     ndbrequire(rf->wordIndex == 2048);
  981.     rf->pageIndex++;
  982.     ndbrequire(rf->pageIndex < 8);
  983.     rf->rwfPageptr.i = rf->rwfTabPtr.p->pageRef[rf->pageIndex];
  984.     ptrCheckGuard(rf->rwfPageptr, cpageFileSize, pageRecord);
  985.     rf->wordIndex = 32;
  986.   }//if
  987.   Uint32 dataWord = rf->rwfPageptr.p->word[rf->wordIndex];
  988.   rf->wordIndex++;
  989.   return dataWord;
  990. }//Dbdih::readPageWord()
  991. void Dbdih::readReplica(RWFragment* rf, ReplicaRecordPtr readReplicaPtr) 
  992. {
  993.   Uint32 i;
  994.   readReplicaPtr.p->procNode = readPageWord(rf);
  995.   readReplicaPtr.p->initialGci = readPageWord(rf);
  996.   readReplicaPtr.p->noCrashedReplicas = readPageWord(rf);
  997.   readReplicaPtr.p->nextLcp = readPageWord(rf);
  998.   for (i = 0; i < MAX_LCP_STORED; i++) {
  999.     readReplicaPtr.p->maxGciCompleted[i] = readPageWord(rf);
  1000.     readReplicaPtr.p->maxGciStarted[i] = readPageWord(rf);
  1001.     readReplicaPtr.p->lcpId[i] = readPageWord(rf);
  1002.     readReplicaPtr.p->lcpStatus[i] = readPageWord(rf);
  1003.   }//for
  1004.   const Uint32 noCrashedReplicas = readReplicaPtr.p->noCrashedReplicas;
  1005.   ndbrequire(noCrashedReplicas < 8);
  1006.   for (i = 0; i < noCrashedReplicas; i++) {
  1007.     readReplicaPtr.p->createGci[i] = readPageWord(rf);
  1008.     readReplicaPtr.p->replicaLastGci[i] = readPageWord(rf);
  1009.     ndbrequire(readReplicaPtr.p->createGci[i] != 0xF1F1F1F1);
  1010.     ndbrequire(readReplicaPtr.p->replicaLastGci[i] != 0xF1F1F1F1);
  1011.   }//for
  1012.   for(i = noCrashedReplicas; i<8; i++){
  1013.     readReplicaPtr.p->createGci[i] = readPageWord(rf);
  1014.     readReplicaPtr.p->replicaLastGci[i] = readPageWord(rf);
  1015.     // They are not initialized...
  1016.     readReplicaPtr.p->createGci[i] = 0;
  1017.     readReplicaPtr.p->replicaLastGci[i] = ~0;
  1018.   }
  1019.   /* ---------------------------------------------------------------------- */
  1020.   /*       IF THE LAST COMPLETED LOCAL CHECKPOINT IS VALID AND LARGER THAN  */
  1021.   /*       THE LAST COMPLETED CHECKPOINT THEN WE WILL INVALIDATE THIS LOCAL */
  1022.   /*       CHECKPOINT FOR THIS REPLICA.                                     */
  1023.   /* ---------------------------------------------------------------------- */
  1024.   Uint32 trraLcp = prevLcpNo(readReplicaPtr.p->nextLcp);
  1025.   ndbrequire(trraLcp < MAX_LCP_STORED);
  1026.   if ((readReplicaPtr.p->lcpStatus[trraLcp] == ZVALID) &&
  1027.       (readReplicaPtr.p->lcpId[trraLcp] > SYSFILE->latestLCP_ID)) {
  1028.     jam();
  1029.     readReplicaPtr.p->lcpStatus[trraLcp] = ZINVALID;
  1030.   }//if
  1031.   /* ---------------------------------------------------------------------- */
  1032.   /*       WE ALSO HAVE TO INVALIDATE ANY LOCAL CHECKPOINTS THAT HAVE BEEN  */
  1033.   /*       INVALIDATED BY MOVING BACK THE RESTART GCI.                      */
  1034.   /* ---------------------------------------------------------------------- */
  1035.   for (i = 0; i < MAX_LCP_STORED; i++) {
  1036.     jam();
  1037.     if ((readReplicaPtr.p->lcpStatus[i] == ZVALID) &&
  1038.         (readReplicaPtr.p->maxGciStarted[i] > SYSFILE->newestRestorableGCI)) {
  1039.       jam();
  1040.       readReplicaPtr.p->lcpStatus[i] = ZINVALID;
  1041.     }//if
  1042.   }//for
  1043.   /* ---------------------------------------------------------------------- */
  1044.   /*       WE WILL REMOVE ANY OCCURRENCES OF REPLICAS THAT HAVE CRASHED     */
  1045.   /*       THAT ARE NO LONGER VALID DUE TO MOVING RESTART GCI BACKWARDS.    */
  1046.   /* ---------------------------------------------------------------------- */
  1047.   removeTooNewCrashedReplicas(readReplicaPtr);
  1048.   /* ---------------------------------------------------------------------- */
  1049.   /*       WE WILL REMOVE ANY OCCURRENCES OF REPLICAS THAT HAVE CRASHED     */
  1050.   /*       THAT ARE NO LONGER VALID SINCE THEY ARE NO LONGER RESTORABLE.    */
  1051.   /* ---------------------------------------------------------------------- */
  1052.   removeOldCrashedReplicas(readReplicaPtr);
  1053.   /* --------------------------------------------------------------------- */
  1054.   // We set the last GCI of the replica that was alive before the node
  1055.   // crashed last time. We set it to the last GCI which the node participated in.
  1056.   /* --------------------------------------------------------------------- */
  1057.   ndbrequire(readReplicaPtr.p->noCrashedReplicas < 8);
  1058.   readReplicaPtr.p->replicaLastGci[readReplicaPtr.p->noCrashedReplicas] = 
  1059.     SYSFILE->lastCompletedGCI[readReplicaPtr.p->procNode];
  1060.   /* ---------------------------------------------------------------------- */
  1061.   /*       FIND PROCESSOR RECORD                                            */
  1062.   /* ---------------------------------------------------------------------- */
  1063. }//Dbdih::readReplica()
  1064. void Dbdih::readReplicas(RWFragment* rf, FragmentstorePtr fragPtr)
  1065. {
  1066.   Uint32 i;
  1067.   ReplicaRecordPtr newReplicaPtr;
  1068.   Uint32 noStoredReplicas = fragPtr.p->noStoredReplicas;
  1069.   Uint32 noOldStoredReplicas = fragPtr.p->noOldStoredReplicas;
  1070.   /* ----------------------------------------------------------------------- */
  1071.   /*      WE CLEAR THE NUMBER OF STORED REPLICAS SINCE IT WILL BE CALCULATED */
  1072.   /*      BY THE LINKING SUBROUTINES.                                        */
  1073.   /* ----------------------------------------------------------------------- */
  1074.   fragPtr.p->noStoredReplicas = 0;
  1075.   fragPtr.p->noOldStoredReplicas = 0;
  1076.   Uint32 replicaIndex = 0;
  1077.   ndbrequire(noStoredReplicas + noOldStoredReplicas <= MAX_REPLICAS);
  1078.   for (i = 0; i < noStoredReplicas; i++) {
  1079.     seizeReplicaRec(newReplicaPtr);
  1080.     readReplica(rf, newReplicaPtr);
  1081.     if (checkNodeAlive(newReplicaPtr.p->procNode)) {
  1082.       jam();
  1083.       ndbrequire(replicaIndex < MAX_REPLICAS);
  1084.       fragPtr.p->activeNodes[replicaIndex] = newReplicaPtr.p->procNode;
  1085.       replicaIndex++;
  1086.       linkStoredReplica(fragPtr, newReplicaPtr);
  1087.     } else {
  1088.       jam();
  1089.       linkOldStoredReplica(fragPtr, newReplicaPtr);
  1090.     }//if
  1091.   }//for
  1092.   fragPtr.p->fragReplicas = noStoredReplicas;
  1093.   for (i = 0; i < noOldStoredReplicas; i++) {
  1094.     jam();
  1095.     seizeReplicaRec(newReplicaPtr);
  1096.     readReplica(rf, newReplicaPtr);
  1097.     linkOldStoredReplica(fragPtr, newReplicaPtr);
  1098.   }//for
  1099. }//Dbdih::readReplicas()
  1100. void Dbdih::readRestorableGci(Signal* signal, FileRecordPtr filePtr) 
  1101. {
  1102.   signal->theData[0] = filePtr.p->fileRef;
  1103.   signal->theData[1] = reference();
  1104.   signal->theData[2] = filePtr.i;
  1105.   signal->theData[3] = ZLIST_OF_PAIRS;
  1106.   signal->theData[4] = ZVAR_NO_CRESTART_INFO;
  1107.   signal->theData[5] = 1;
  1108.   signal->theData[6] = 0;
  1109.   signal->theData[7] = 0;
  1110.   sendSignal(NDBFS_REF, GSN_FSREADREQ, signal, 8, JBA);
  1111. }//Dbdih::readRestorableGci()
  1112. void Dbdih::readTabfile(Signal* signal, TabRecord* tab, FileRecordPtr filePtr) 
  1113. {
  1114.   signal->theData[0] = filePtr.p->fileRef;
  1115.   signal->theData[1] = reference();
  1116.   signal->theData[2] = filePtr.i;
  1117.   signal->theData[3] = ZLIST_OF_PAIRS;
  1118.   signal->theData[4] = ZVAR_NO_WORD;
  1119.   signal->theData[5] = tab->noPages;
  1120.   for (Uint32 i = 0; i < tab->noPages; i++) {
  1121.     signal->theData[6 + (2 * i)] = tab->pageRef[i];
  1122.     signal->theData[7 + (2 * i)] = i;
  1123.   }//for
  1124.   sendSignal(NDBFS_REF, GSN_FSREADREQ, signal, 22, JBA);
  1125. }//Dbdih::readTabfile()
  1126. void Dbdih::releasePage(Uint32 pageIndex)
  1127. {
  1128.   PageRecordPtr pagePtr;
  1129.   pagePtr.i = pageIndex;
  1130.   ptrCheckGuard(pagePtr, cpageFileSize, pageRecord);
  1131.   pagePtr.p->nextfreepage = cfirstfreepage;
  1132.   cfirstfreepage = pagePtr.i;
  1133. }//Dbdih::releasePage()
  1134. void Dbdih::releaseTabPages(Uint32 tableId) 
  1135. {
  1136.   TabRecordPtr tabPtr;
  1137.   tabPtr.i = tableId;
  1138.   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  1139.   ndbrequire(tabPtr.p->noPages <= 8);
  1140.   for (Uint32 i = 0; i < tabPtr.p->noPages; i++) {
  1141.     jam();
  1142.     releasePage(tabPtr.p->pageRef[i]);
  1143.   }//for
  1144.   tabPtr.p->noPages = 0;
  1145. }//Dbdih::releaseTabPages()
  1146. /*************************************************************************/
  1147. /*       REMOVE NODE FROM SET OF ALIVE NODES.                            */
  1148. /*************************************************************************/
  1149. void Dbdih::removeAlive(NodeRecordPtr removeNodePtr) 
  1150. {
  1151.   NodeRecordPtr nodePtr;
  1152.   nodePtr.i = cfirstAliveNode;
  1153.   if (nodePtr.i == removeNodePtr.i) {
  1154.     jam();
  1155.     cfirstAliveNode = removeNodePtr.p->nextNode;
  1156.     return;
  1157.   }//if
  1158.   do {
  1159.     jam();
  1160.     ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
  1161.     if (nodePtr.p->nextNode == removeNodePtr.i) {
  1162.       jam();
  1163.       nodePtr.p->nextNode = removeNodePtr.p->nextNode;
  1164.       break;
  1165.     } else {
  1166.       jam();
  1167.       nodePtr.i = nodePtr.p->nextNode;
  1168.     }//if
  1169.   } while (1);
  1170. }//Dbdih::removeAlive()
  1171. /*************************************************************************/
  1172. /*       REMOVE NODE FROM SET OF DEAD NODES.                             */
  1173. /*************************************************************************/
  1174. void Dbdih::removeDeadNode(NodeRecordPtr removeNodePtr) 
  1175. {
  1176.   NodeRecordPtr nodePtr;
  1177.   nodePtr.i = cfirstDeadNode;
  1178.   if (nodePtr.i == removeNodePtr.i) {
  1179.     jam();
  1180.     cfirstDeadNode = removeNodePtr.p->nextNode;
  1181.     return;
  1182.   }//if
  1183.   do {
  1184.     jam();
  1185.     ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
  1186.     if (nodePtr.p->nextNode == removeNodePtr.i) {
  1187.       jam();
  1188.       nodePtr.p->nextNode = removeNodePtr.p->nextNode;
  1189.       break;
  1190.     } else {
  1191.       jam();
  1192.       nodePtr.i = nodePtr.p->nextNode;
  1193.     }//if
  1194.   } while (1);
  1195. }//Dbdih::removeDeadNode()
  1196. /*---------------------------------------------------------------*/
  1197. /*       REMOVE REPLICAS OF A FAILED NODE FROM LIST OF STORED    */
  1198. /*       REPLICAS AND MOVE IT TO THE LIST OF OLD STORED REPLICAS.*/
  1199. /*       ALSO UPDATE THE CRASHED REPLICA INFORMATION.            */
  1200. /*---------------------------------------------------------------*/
  1201. void Dbdih::removeNodeFromStored(Uint32 nodeId,
  1202.                                  FragmentstorePtr fragPtr,
  1203.                                  ReplicaRecordPtr replicatePtr)
  1204. {
  1205.   newCrashedReplica(nodeId, replicatePtr);
  1206.   removeStoredReplica(fragPtr, replicatePtr);
  1207.   linkOldStoredReplica(fragPtr, replicatePtr);
  1208.   ndbrequire(fragPtr.p->storedReplicas != RNIL);
  1209. }//Dbdih::removeNodeFromStored()
  1210. /*************************************************************************/
  1211. /*       REMOVE ANY OLD CRASHED REPLICAS THAT ARE NOT RESTORABLE ANY MORE*/
  1212. /*************************************************************************/
  1213. void Dbdih::removeOldCrashedReplicas(ReplicaRecordPtr rocReplicaPtr) 
  1214. {
  1215.   while (rocReplicaPtr.p->noCrashedReplicas > 0) {
  1216.     jam();
  1217.     /* --------------------------------------------------------------------- */
  1218.     /*       ONLY IF THERE IS AT LEAST ONE REPLICA THEN CAN WE REMOVE ANY.   */
  1219.     /* --------------------------------------------------------------------- */
  1220.     if (rocReplicaPtr.p->replicaLastGci[0] < SYSFILE->oldestRestorableGCI){
  1221.       jam();
  1222.       /* ------------------------------------------------------------------- */
  1223.       /*     THIS CRASHED REPLICA HAS BECOME EXTINCT AND MUST BE REMOVED TO  */
  1224.       /*     GIVE SPACE FOR NEW CRASHED REPLICAS.                            */
  1225.       /* ------------------------------------------------------------------- */
  1226.       packCrashedReplicas(rocReplicaPtr);
  1227.     } else {
  1228.       break;
  1229.     }//if
  1230.   }//while
  1231.   if (rocReplicaPtr.p->createGci[0] < SYSFILE->keepGCI){
  1232.     jam();
  1233.     /* --------------------------------------------------------------------- */
  1234.     /*       MOVE FORWARD THE CREATE GCI TO A GCI THAT CAN BE USED. WE HAVE  */
  1235.     /*       NO CERTAINTY IN FINDING ANY LOG RECORDS FROM OLDER GCI'S.       */
  1236.     /* --------------------------------------------------------------------- */
  1237.     rocReplicaPtr.p->createGci[0] = SYSFILE->keepGCI;
  1238.     ndbrequire(SYSFILE->keepGCI != 0xF1F1F1F1);
  1239.   }//if
  1240. }//Dbdih::removeOldCrashedReplicas()
  1241. void Dbdih::removeOldStoredReplica(FragmentstorePtr fragPtr,
  1242.                                    ReplicaRecordPtr replicatePtr) 
  1243. {
  1244.   ReplicaRecordPtr rosTmpReplicaPtr;
  1245.   ReplicaRecordPtr rosPrevReplicaPtr;
  1246.   fragPtr.p->noOldStoredReplicas--;
  1247.   if (fragPtr.p->oldStoredReplicas == replicatePtr.i) {
  1248.     jam();
  1249.     fragPtr.p->oldStoredReplicas = replicatePtr.p->nextReplica;
  1250.   } else {
  1251.     rosPrevReplicaPtr.i = fragPtr.p->oldStoredReplicas;
  1252.     ptrCheckGuard(rosPrevReplicaPtr, creplicaFileSize, replicaRecord);
  1253.     rosTmpReplicaPtr.i = rosPrevReplicaPtr.p->nextReplica;
  1254.     while (rosTmpReplicaPtr.i != replicatePtr.i) {
  1255.       jam();
  1256.       rosPrevReplicaPtr.i = rosTmpReplicaPtr.i;
  1257.       ptrCheckGuard(rosPrevReplicaPtr, creplicaFileSize, replicaRecord);
  1258.       ptrCheckGuard(rosTmpReplicaPtr, creplicaFileSize, replicaRecord);
  1259.       rosTmpReplicaPtr.i = rosTmpReplicaPtr.p->nextReplica;
  1260.     }//if
  1261.     rosPrevReplicaPtr.p->nextReplica = replicatePtr.p->nextReplica;
  1262.   }//if
  1263. }//Dbdih::removeOldStoredReplica()
  1264. void Dbdih::removeStoredReplica(FragmentstorePtr fragPtr,
  1265.                                 ReplicaRecordPtr replicatePtr)
  1266. {
  1267.   ReplicaRecordPtr rsrTmpReplicaPtr;
  1268.   ReplicaRecordPtr rsrPrevReplicaPtr;
  1269.   fragPtr.p->noStoredReplicas--;
  1270.   if (fragPtr.p->storedReplicas == replicatePtr.i) {
  1271.     jam();
  1272.     fragPtr.p->storedReplicas = replicatePtr.p->nextReplica;
  1273.   } else {
  1274.     jam();
  1275.     rsrPrevReplicaPtr.i = fragPtr.p->storedReplicas;
  1276.     rsrTmpReplicaPtr.i = fragPtr.p->storedReplicas;
  1277.     ptrCheckGuard(rsrTmpReplicaPtr, creplicaFileSize, replicaRecord);
  1278.     rsrTmpReplicaPtr.i = rsrTmpReplicaPtr.p->nextReplica;
  1279.     while (rsrTmpReplicaPtr.i != replicatePtr.i) {
  1280.       jam();
  1281.       rsrPrevReplicaPtr.i = rsrTmpReplicaPtr.i;
  1282.       ptrCheckGuard(rsrTmpReplicaPtr, creplicaFileSize, replicaRecord);
  1283.       rsrTmpReplicaPtr.i = rsrTmpReplicaPtr.p->nextReplica;
  1284.     }//while
  1285.     ptrCheckGuard(rsrPrevReplicaPtr, creplicaFileSize, replicaRecord);
  1286.     rsrPrevReplicaPtr.p->nextReplica = replicatePtr.p->nextReplica;
  1287.   }//if
  1288. }//Dbdih::removeStoredReplica()
  1289. /*************************************************************************/
  1290. /*       REMOVE ALL TOO NEW CRASHED REPLICAS THAT IS IN THIS REPLICA.    */
  1291. /*************************************************************************/
  1292. void Dbdih::removeTooNewCrashedReplicas(ReplicaRecordPtr rtnReplicaPtr) 
  1293. {
  1294.   while (rtnReplicaPtr.p->noCrashedReplicas > 0) {
  1295.     jam();
  1296.     /* --------------------------------------------------------------------- */
  1297.     /*       REMOVE ALL REPLICAS THAT ONLY LIVED IN A PERIOD THAT HAVE BEEN  */
  1298.     /*       REMOVED FROM THE RESTART INFORMATION SINCE THE RESTART FAILED   */
  1299.     /*       TOO MANY TIMES.                                                 */
  1300.     /* --------------------------------------------------------------------- */
  1301.     arrGuard(rtnReplicaPtr.p->noCrashedReplicas - 1, 8);
  1302.     if (rtnReplicaPtr.p->createGci[rtnReplicaPtr.p->noCrashedReplicas - 1] > 
  1303.         SYSFILE->newestRestorableGCI){
  1304.       jam();
  1305.       rtnReplicaPtr.p->createGci[rtnReplicaPtr.p->noCrashedReplicas - 1] = 
  1306. (Uint32)-1;
  1307.       rtnReplicaPtr.p->replicaLastGci[rtnReplicaPtr.p->noCrashedReplicas - 1] = 
  1308. (Uint32)-1;
  1309.       rtnReplicaPtr.p->noCrashedReplicas--;
  1310.     } else {
  1311.       break;
  1312.     }//if
  1313.   }//while
  1314. }//Dbdih::removeTooNewCrashedReplicas()
  1315. /*************************************************************************/
  1316. /*                                                                       */
  1317. /*       MODULE: SEARCH FOR POSSIBLE REPLICAS THAT CAN HANDLE THE GLOBAL */
  1318. /*               CHECKPOINT WITHOUT NEEDING ANY EXTRA LOGGING FACILITIES.*/
  1319. /*               A MAXIMUM OF FOUR NODES IS RETRIEVED.                   */
  1320. /*************************************************************************/
  1321. void Dbdih::searchStoredReplicas(FragmentstorePtr fragPtr) 
  1322. {
  1323.   Uint32 nextReplicaPtrI;
  1324.   ConstPtr<ReplicaRecord> replicaPtr;
  1325.   replicaPtr.i = fragPtr.p->storedReplicas;
  1326.   while (replicaPtr.i != RNIL) {
  1327.     jam();
  1328.     ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
  1329.     nextReplicaPtrI = replicaPtr.p->nextReplica;
  1330.     NodeRecordPtr nodePtr;
  1331.     nodePtr.i = replicaPtr.p->procNode;
  1332.     ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
  1333.     if (nodePtr.p->nodeStatus == NodeRecord::ALIVE) {
  1334.       jam();
  1335.       switch (nodePtr.p->activeStatus) {
  1336.       case Sysfile::NS_Active:
  1337.       case Sysfile::NS_ActiveMissed_1:
  1338.       case Sysfile::NS_ActiveMissed_2:{
  1339. /* ----------------------------------------------------------------- */
  1340. /*   INITIALISE THE CREATE REPLICA STRUCTURE THAT IS USED FOR SENDING*/
  1341. /*   TO LQH START_FRAGREQ.                                           */
  1342. /*   SET THE DATA NODE WHERE THE LOCAL CHECKPOINT IS FOUND. ALSO     */
  1343. /*   SET A REFERENCE TO THE REPLICA POINTER OF THAT.                 */
  1344. /* ----------------------------------------------------------------- */
  1345. CreateReplicaRecordPtr createReplicaPtr;
  1346. createReplicaPtr.i = cnoOfCreateReplicas;
  1347. ptrCheckGuard(createReplicaPtr, 4, createReplicaRecord);
  1348. cnoOfCreateReplicas++;
  1349. createReplicaPtr.p->dataNodeId = replicaPtr.p->procNode;
  1350. createReplicaPtr.p->replicaRec = replicaPtr.i;
  1351. /* ----------------------------------------------------------------- */
  1352. /*   WE NEED TO SEARCH FOR A PROPER LOCAL CHECKPOINT TO USE FOR THE  */
  1353. /*   SYSTEM RESTART.                                                 */
  1354. /* ----------------------------------------------------------------- */
  1355. Uint32 startGci;
  1356. Uint32 startLcpNo;
  1357. Uint32 stopGci = SYSFILE->newestRestorableGCI;
  1358. bool result = findStartGci(replicaPtr,
  1359.    stopGci,
  1360.    startGci,
  1361.    startLcpNo);
  1362. if (!result) {
  1363.   jam();
  1364.   /* --------------------------------------------------------------- */
  1365.   /* WE COULD NOT FIND ANY LOCAL CHECKPOINT. THE FRAGMENT THUS DO NOT*/
  1366.   /* CONTAIN ANY VALID LOCAL CHECKPOINT. IT DOES HOWEVER CONTAIN A   */
  1367.   /* VALID FRAGMENT LOG. THUS BY FIRST CREATING THE FRAGMENT AND THEN*/
  1368.   /* EXECUTING THE FRAGMENT LOG WE CAN CREATE THE FRAGMENT AS        */
  1369.   /* DESIRED. THIS SHOULD ONLY OCCUR AFTER CREATING A FRAGMENT.      */
  1370.   /*                                                                 */
  1371.   /* TO INDICATE THAT NO LOCAL CHECKPOINT IS TO BE USED WE SET THE   */
  1372.   /* LOCAL CHECKPOINT TO ZNIL.                                       */
  1373.   /* --------------------------------------------------------------- */
  1374.   createReplicaPtr.p->lcpNo = ZNIL;
  1375. } else {
  1376.   jam();
  1377.   /* --------------------------------------------------------------- */
  1378.   /* WE FOUND A PROPER LOCAL CHECKPOINT TO RESTART FROM.             */
  1379.   /* SET LOCAL CHECKPOINT ID AND LOCAL CHECKPOINT NUMBER.            */
  1380.   /* --------------------------------------------------------------- */
  1381.   createReplicaPtr.p->lcpNo = startLcpNo;
  1382.   arrGuard(startLcpNo, MAX_LCP_STORED);
  1383.   createReplicaPtr.p->createLcpId = replicaPtr.p->lcpId[startLcpNo];
  1384. }//if
  1385. if(ERROR_INSERTED(7073) || ERROR_INSERTED(7074)){
  1386.   jam();
  1387.   nodePtr.p->nodeStatus = NodeRecord::DEAD;
  1388. }
  1389. /* ----------------------------------------------------------------- */
  1390. /*   WE HAVE EITHER FOUND A LOCAL CHECKPOINT OR WE ARE PLANNING TO   */
  1391. /*   EXECUTE THE LOG FROM THE INITIAL CREATION OF THE TABLE. IN BOTH */
  1392. /*   CASES WE NEED TO FIND A SET OF LOGS THAT CAN EXECUTE SUCH THAT  */
  1393. /*   WE RECOVER TO THE SYSTEM RESTART GLOBAL CHECKPOINT.             */
  1394. /* -_--------------------------------------------------------------- */
  1395. if (!findLogNodes(createReplicaPtr.p, fragPtr, startGci, stopGci)) {
  1396.   jam();
  1397.   /* --------------------------------------------------------------- */
  1398.   /* WE WERE NOT ABLE TO FIND ANY WAY OF RESTORING THIS REPLICA.     */
  1399.   /* THIS IS A POTENTIAL SYSTEM ERROR.                               */
  1400.   /* --------------------------------------------------------------- */
  1401.   cnoOfCreateReplicas--;
  1402.   return;
  1403. }//if
  1404. if(ERROR_INSERTED(7073) || ERROR_INSERTED(7074)){
  1405.   jam();
  1406.   nodePtr.p->nodeStatus = NodeRecord::ALIVE;
  1407. }
  1408. break;
  1409.       }
  1410.       default:
  1411.         jam();
  1412.         /*empty*/;
  1413.         break;
  1414.       }//switch
  1415.     }
  1416.     replicaPtr.i = nextReplicaPtrI;
  1417.   }//while
  1418. }//Dbdih::searchStoredReplicas()
  1419. /*************************************************************************/
  1420. /*                                                                       */
  1421. /*       MODULE: SEIZE_FILE                                              */
  1422. /*       DESCRIPTION: THE SUBROUTINE SEIZES A FILE RECORD FROM THE       */
  1423. /*                    FREE LIST.                                         */
  1424. /*************************************************************************/
  1425. void Dbdih::seizeFile(FileRecordPtr& filePtr)
  1426. {
  1427.   filePtr.i = cfirstfreeFile;
  1428.   ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
  1429.   cfirstfreeFile = filePtr.p->nextFile;
  1430.   filePtr.p->nextFile = RNIL;
  1431. }//Dbdih::seizeFile()
  1432. /*************************************************************************/
  1433. /*       SEND CREATE_FRAGREQ TO ALL NODES IN THE NDB CLUSTER.            */
  1434. /*************************************************************************/
  1435. /*************************************************************************/
  1436. /*                                                                       */
  1437. /*       MODULE: FIND THE START GCI AND LOCAL CHECKPOINT TO USE.         */
  1438. /*************************************************************************/
  1439. void Dbdih::sendStartFragreq(Signal* signal, 
  1440.      TabRecordPtr tabPtr, Uint32 fragId) 
  1441. {
  1442.   CreateReplicaRecordPtr replicaPtr;
  1443.   for (replicaPtr.i = 0; replicaPtr.i < cnoOfCreateReplicas; replicaPtr.i++) {
  1444.     jam();
  1445.     ptrAss(replicaPtr, createReplicaRecord);
  1446.     BlockReference ref = calcLqhBlockRef(replicaPtr.p->dataNodeId);
  1447.     StartFragReq * const startFragReq = (StartFragReq *)&signal->theData[0];
  1448.     startFragReq->userPtr = replicaPtr.p->replicaRec;
  1449.     startFragReq->userRef = reference();
  1450.     startFragReq->lcpNo = replicaPtr.p->lcpNo;
  1451.     startFragReq->lcpId = replicaPtr.p->createLcpId;
  1452.     startFragReq->tableId = tabPtr.i;
  1453.     startFragReq->fragId = fragId;
  1454.     if(ERROR_INSERTED(7072) || ERROR_INSERTED(7074)){
  1455.       jam();
  1456.       const Uint32 noNodes = replicaPtr.p->noLogNodes;
  1457.       Uint32 start = replicaPtr.p->logStartGci[noNodes - 1];
  1458.       const Uint32 stop  = replicaPtr.p->logStopGci[noNodes - 1];
  1459.       for(Uint32 i = noNodes; i < 4 && (stop - start) > 0; i++){
  1460. replicaPtr.p->noLogNodes++;
  1461. replicaPtr.p->logStopGci[i - 1] = start;
  1462. replicaPtr.p->logNodeId[i] = replicaPtr.p->logNodeId[i-1];
  1463. replicaPtr.p->logStartGci[i] = start + 1;
  1464. replicaPtr.p->logStopGci[i] = stop;      
  1465. start += 1;
  1466.       }
  1467.     }
  1468.     
  1469.     startFragReq->noOfLogNodes = replicaPtr.p->noLogNodes;
  1470.     
  1471.     for (Uint32 i = 0; i < 4 ; i++) {
  1472.       startFragReq->lqhLogNode[i] = replicaPtr.p->logNodeId[i];
  1473.       startFragReq->startGci[i] = replicaPtr.p->logStartGci[i];
  1474.       startFragReq->lastGci[i] = replicaPtr.p->logStopGci[i];
  1475.     }//for    
  1476.     sendSignal(ref, GSN_START_FRAGREQ, signal, 
  1477.        StartFragReq::SignalLength, JBB);
  1478.   }//for
  1479. }//Dbdih::sendStartFragreq()
  1480. /*************************************************************************/
  1481. /*       SET THE INITIAL ACTIVE STATUS ON ALL NODES AND PUT INTO LISTS.  */
  1482. /*************************************************************************/
  1483. void Dbdih::setInitialActiveStatus()
  1484. {
  1485.   NodeRecordPtr siaNodeptr;
  1486.   Uint32 tsiaNodeActiveStatus;
  1487.   Uint32 tsiaNoActiveNodes;
  1488.   tsiaNoActiveNodes = csystemnodes - cnoHotSpare;
  1489.   for(Uint32 i = 0; i<Sysfile::NODE_STATUS_SIZE; i++)
  1490.     SYSFILE->nodeStatus[i] = 0;
  1491.   for (siaNodeptr.i = 1; siaNodeptr.i < MAX_NDB_NODES; siaNodeptr.i++) {
  1492.     ptrAss(siaNodeptr, nodeRecord);
  1493.     if (siaNodeptr.p->nodeStatus == NodeRecord::ALIVE) {
  1494.       if (tsiaNoActiveNodes == 0) {
  1495.         jam();
  1496.         siaNodeptr.p->activeStatus = Sysfile::NS_HotSpare;
  1497.       } else {
  1498.         jam();
  1499.         tsiaNoActiveNodes = tsiaNoActiveNodes - 1;
  1500.         siaNodeptr.p->activeStatus = Sysfile::NS_Active;
  1501.       }//if
  1502.     } else {
  1503.       jam();
  1504.       siaNodeptr.p->activeStatus = Sysfile::NS_NotDefined;
  1505.     }//if
  1506.     switch (siaNodeptr.p->activeStatus) {
  1507.     case Sysfile::NS_Active:
  1508.       jam();
  1509.       tsiaNodeActiveStatus = Sysfile::NS_Active;
  1510.       break;
  1511.     case Sysfile::NS_HotSpare:
  1512.       jam();
  1513.       tsiaNodeActiveStatus = Sysfile::NS_HotSpare;
  1514.       break;
  1515.     case Sysfile::NS_NotDefined:
  1516.       jam();
  1517.       tsiaNodeActiveStatus = Sysfile::NS_NotDefined;
  1518.       break;
  1519.     default:
  1520.       ndbrequire(false);
  1521.       return;
  1522.       break;
  1523.     }//switch
  1524.     Sysfile::setNodeStatus(siaNodeptr.i, SYSFILE->nodeStatus,
  1525.                            tsiaNodeActiveStatus);
  1526.   }//for
  1527. }//Dbdih::setInitialActiveStatus()
  1528. /*************************************************************************/
  1529. /*       SET LCP ACTIVE STATUS AT THE END OF A LOCAL CHECKPOINT.        */
  1530. /*************************************************************************/
  1531. void Dbdih::setLcpActiveStatusEnd()
  1532. {
  1533.   NodeRecordPtr nodePtr;
  1534.   for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
  1535.     jam();
  1536.     ptrAss(nodePtr, nodeRecord);
  1537.     if (c_lcpState.m_participatingLQH.get(nodePtr.i)){
  1538.       switch (nodePtr.p->activeStatus) {
  1539.       case Sysfile::NS_Active:
  1540.       case Sysfile::NS_ActiveMissed_1:
  1541.       case Sysfile::NS_ActiveMissed_2:
  1542.         jam();
  1543. /*-------------------------------------------------------------------*/
  1544. /* THE NODE PARTICIPATED IN THIS CHECKPOINT. 
  1545.  * WE CAN SET ITS STATUS TO ACTIVE */
  1546. /*-------------------------------------------------------------------*/
  1547.         nodePtr.p->activeStatus = Sysfile::NS_Active;
  1548.         takeOverCompleted(nodePtr.i);
  1549.         break;
  1550.       case Sysfile::NS_TakeOver:
  1551.         jam();
  1552. /*-------------------------------------------------------------------*/
  1553. /* THE NODE HAS COMPLETED A CHECKPOINT AFTER TAKE OVER. WE CAN NOW   */
  1554. /* SET ITS STATUS TO ACTIVE. WE CAN ALSO COMPLETE THE TAKE OVER      */
  1555. /* AND ALSO WE CLEAR THE TAKE OVER NODE IN THE RESTART INFO.         */
  1556. /*-------------------------------------------------------------------*/
  1557.         nodePtr.p->activeStatus = Sysfile::NS_Active;
  1558.         takeOverCompleted(nodePtr.i);
  1559.         break;
  1560.       default:
  1561.         ndbrequire(false);
  1562.         return;
  1563.         break;
  1564.       }//switch
  1565.     }//if
  1566.   }//for
  1567.   if(getNodeState().getNodeRestartInProgress()){
  1568.     jam();
  1569.     if(c_lcpState.m_participatingLQH.get(getOwnNodeId())){
  1570.       nodePtr.i = getOwnNodeId();
  1571.       ptrAss(nodePtr, nodeRecord);
  1572.       ndbrequire(nodePtr.p->activeStatus == Sysfile::NS_Active);
  1573.       ndbout_c("NR: setLcpActiveStatusEnd - m_participatingLQH");
  1574.     } else {
  1575.       ndbout_c("NR: setLcpActiveStatusEnd - !m_participatingLQH");
  1576.     }
  1577.   }
  1578.   
  1579.   c_lcpState.m_participatingDIH.clear();
  1580.   c_lcpState.m_participatingLQH.clear();
  1581.   if (isMaster()) {
  1582.     jam();
  1583.     setNodeRestartInfoBits();
  1584.   }//if
  1585. }//Dbdih::setLcpActiveStatusEnd()
  1586. void Dbdih::takeOverCompleted(Uint32 aNodeId)
  1587. {
  1588.   TakeOverRecordPtr takeOverPtr;
  1589.   takeOverPtr.i = findTakeOver(aNodeId);
  1590.   if (takeOverPtr.i != RNIL) {
  1591.     jam();
  1592.     ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
  1593.     if (takeOverPtr.p->toMasterStatus != TakeOverRecord::WAIT_LCP) {
  1594.       jam();
  1595.       ndbrequire(!isMaster());
  1596.       return;
  1597.     }//if
  1598.     ndbrequire(isMaster());
  1599.     Sysfile::setTakeOverNode(aNodeId, SYSFILE->takeOver, 0);
  1600.     takeOverPtr.p->toMasterStatus = TakeOverRecord::TO_END_COPY;
  1601.     cstartGcpNow = true;
  1602.   }//if
  1603. }//Dbdih::takeOverCompleted()
  1604. /*************************************************************************/
  1605. /*       SET LCP ACTIVE STATUS BEFORE STARTING A LOCAL CHECKPOINT.       */
  1606. /*************************************************************************/
  1607. void Dbdih::setLcpActiveStatusStart(Signal* signal) 
  1608. {
  1609.   NodeRecordPtr nodePtr;
  1610.   c_lcpState.m_participatingLQH.clear();
  1611.   c_lcpState.m_participatingDIH.clear();
  1612.   
  1613.   for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
  1614.     ptrAss(nodePtr, nodeRecord);
  1615. #if 0    
  1616.     if(nodePtr.p->nodeStatus != NodeRecord::NOT_IN_CLUSTER){
  1617.       infoEvent("Node %d nodeStatus=%d activeStatus=%d copyCompleted=%d lcp=%d",
  1618. nodePtr.i, 
  1619. nodePtr.p->nodeStatus,
  1620. nodePtr.p->activeStatus,
  1621. nodePtr.p->copyCompleted,
  1622. nodePtr.p->m_inclDihLcp);
  1623.     }
  1624. #endif
  1625.     if(nodePtr.p->nodeStatus == NodeRecord::ALIVE && nodePtr.p->m_inclDihLcp){
  1626.       jam();
  1627.       c_lcpState.m_participatingDIH.set(nodePtr.i);
  1628.     }
  1629.     if ((nodePtr.p->nodeStatus == NodeRecord::ALIVE) &&
  1630. (nodePtr.p->copyCompleted)) {
  1631.       switch (nodePtr.p->activeStatus) {
  1632.       case Sysfile::NS_Active:
  1633.         jam();
  1634. /*-------------------------------------------------------------------*/
  1635. // The normal case. Starting a LCP for a started node which hasn't
  1636. // missed the previous LCP.
  1637. /*-------------------------------------------------------------------*/
  1638. c_lcpState.m_participatingLQH.set(nodePtr.i);
  1639.         break;
  1640.       case Sysfile::NS_ActiveMissed_1:
  1641.         jam();
  1642. /*-------------------------------------------------------------------*/
  1643. // The node is starting up and is participating in a local checkpoint
  1644. // as the final phase of the start-up. We can still use the checkpoints
  1645. // on the node after a system restart.
  1646. /*-------------------------------------------------------------------*/
  1647. c_lcpState.m_participatingLQH.set(nodePtr.i);
  1648.         break;
  1649.       case Sysfile::NS_ActiveMissed_2:
  1650.         jam();
  1651. /*-------------------------------------------------------------------*/
  1652. // The node is starting up and is participating in a local checkpoint
  1653. // as the final phase of the start-up. We have missed so 
  1654. // many checkpoints that we no longer can use this node to 
  1655. // recreate fragments from disk.
  1656. // It must be taken over with the copy fragment process after a system
  1657. // crash. We indicate this by setting the active status to TAKE_OVER.
  1658. /*-------------------------------------------------------------------*/
  1659.         nodePtr.p->activeStatus = Sysfile::NS_TakeOver;
  1660.         //break; // Fall through
  1661.       case Sysfile::NS_TakeOver:{
  1662.         TakeOverRecordPtr takeOverPtr;
  1663.         jam();
  1664. /*-------------------------------------------------------------------*/
  1665. /*      THIS NODE IS CURRENTLY TAKING OVER A FAILED NODE.            */
  1666. /*-------------------------------------------------------------------*/
  1667.         takeOverPtr.i = findTakeOver(nodePtr.i);
  1668.         if (takeOverPtr.i != RNIL) {
  1669.           jam();
  1670.           ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
  1671.           if (takeOverPtr.p->toMasterStatus == TakeOverRecord::WAIT_LCP) {
  1672.             jam();
  1673.     /*---------------------------------------------------------------
  1674.      * ALL THE INFORMATION HAVE BEEN REPLICATED TO THE NEW 
  1675.      * NODE AND WE ARE ONLY WAITING FOR A LOCAL CHECKPOINT TO BE 
  1676.      * PERFORMED ON THE NODE TO SET ITS STATUS TO ACTIVE.   
  1677.      */
  1678.     infoEvent("Node %d is WAIT_LCP including in LCP", nodePtr.i);
  1679.     c_lcpState.m_participatingLQH.set(nodePtr.i);
  1680.           }//if
  1681.         }//if
  1682.         break;
  1683.       }
  1684.       default:
  1685.         jam();
  1686.         /*empty*/;
  1687.         break;
  1688.       }//switch
  1689.     } else {
  1690.       switch (nodePtr.p->activeStatus) {
  1691.       case Sysfile::NS_Active:
  1692.         jam();
  1693.         nodePtr.p->activeStatus = Sysfile::NS_ActiveMissed_1;
  1694.         break;
  1695.       case Sysfile::NS_ActiveMissed_1:
  1696.         jam();
  1697.         nodePtr.p->activeStatus = Sysfile::NS_ActiveMissed_2;
  1698.         break;
  1699.       case Sysfile::NS_ActiveMissed_2:
  1700.         jam();
  1701.         if ((nodePtr.p->nodeStatus == NodeRecord::ALIVE) &&
  1702.             (!nodePtr.p->copyCompleted)) {
  1703.           jam();
  1704.   /*-----------------------------------------------------------------*/
  1705.   // The node is currently starting up and has not completed the 
  1706.   // copy phase.
  1707.   // It will thus be in the TAKE_OVER state.
  1708.   /*-----------------------------------------------------------------*/
  1709.           ndbrequire(findTakeOver(nodePtr.i) != RNIL);
  1710.           nodePtr.p->activeStatus = Sysfile::NS_TakeOver;
  1711.         } else {
  1712.           jam();
  1713.   /*-----------------------------------------------------------------*/
  1714.   /* THE NODE IS ACTIVE AND HAS NOT COMPLETED ANY OF THE LAST 3 
  1715.    * CHECKPOINTS */
  1716.   /* WE MUST TAKE IT OUT OF ACTION AND START A NEW NODE TO TAKE OVER.*/
  1717.   /*-----------------------------------------------------------------*/
  1718.           nodePtr.p->activeStatus = Sysfile::NS_NotActive_NotTakenOver;
  1719.         }//if
  1720.         break;
  1721.       case Sysfile::NS_TakeOver:
  1722. jam();
  1723. break;
  1724.       default:
  1725.         jam();
  1726.         /*empty*/;
  1727.         break;
  1728.       }//switch
  1729.     }//if
  1730.   }//for
  1731.   if (isMaster()) {
  1732.     jam();
  1733.     checkStartTakeOver(signal);
  1734.     setNodeRestartInfoBits();
  1735.   }//if
  1736. }//Dbdih::setLcpActiveStatusStart()
  1737. /*************************************************************************/
  1738. /* SET NODE ACTIVE STATUS AT SYSTEM RESTART AND WHEN UPDATED BY MASTER   */
  1739. /*************************************************************************/
  1740. void Dbdih::setNodeActiveStatus() 
  1741. {
  1742.   NodeRecordPtr snaNodeptr;
  1743.   for (snaNodeptr.i = 1; snaNodeptr.i < MAX_NDB_NODES; snaNodeptr.i++) {
  1744.     ptrAss(snaNodeptr, nodeRecord);
  1745.     const Uint32 tsnaNodeBits = Sysfile::getNodeStatus(snaNodeptr.i,
  1746.                                                        SYSFILE->nodeStatus);
  1747.     switch (tsnaNodeBits) {
  1748.     case Sysfile::NS_Active:
  1749.       jam();
  1750.       snaNodeptr.p->activeStatus = Sysfile::NS_Active;
  1751.       break;
  1752.     case Sysfile::NS_ActiveMissed_1:
  1753.       jam();
  1754.       snaNodeptr.p->activeStatus = Sysfile::NS_ActiveMissed_1;
  1755.       break;
  1756.     case Sysfile::NS_ActiveMissed_2:
  1757.       jam();
  1758.       snaNodeptr.p->activeStatus = Sysfile::NS_ActiveMissed_2;
  1759.       break;
  1760.     case Sysfile::NS_TakeOver:
  1761.       jam();
  1762.       snaNodeptr.p->activeStatus = Sysfile::NS_TakeOver;
  1763.       break;
  1764.     case Sysfile::NS_HotSpare:
  1765.       jam();
  1766.       snaNodeptr.p->activeStatus = Sysfile::NS_HotSpare;
  1767.       break;
  1768.     case Sysfile::NS_NotActive_NotTakenOver:
  1769.       jam();
  1770.       snaNodeptr.p->activeStatus = Sysfile::NS_NotActive_NotTakenOver;
  1771.       break;
  1772.     case Sysfile::NS_NotDefined:
  1773.       jam();
  1774.       snaNodeptr.p->activeStatus = Sysfile::NS_NotDefined;
  1775.       break;
  1776.     default:
  1777.       ndbrequire(false);
  1778.       break;
  1779.     }//switch
  1780.   }//for
  1781. }//Dbdih::setNodeActiveStatus()
  1782. /***************************************************************************/
  1783. /* SET THE NODE GROUP BASED ON THE RESTART INFORMATION OR AS SET BY MASTER */
  1784. /***************************************************************************/
  1785. void Dbdih::setNodeGroups()
  1786. {
  1787.   NodeGroupRecordPtr NGPtr;
  1788.   NodeRecordPtr sngNodeptr;
  1789.   Uint32 Ti;
  1790.   for (Ti = 0; Ti < MAX_NDB_NODES; Ti++) {
  1791.     NGPtr.i = Ti;
  1792.     ptrAss(NGPtr, nodeGroupRecord);
  1793.     NGPtr.p->nodeCount = 0;
  1794.   }//for    
  1795.   for (sngNodeptr.i = 1; sngNodeptr.i < MAX_NDB_NODES; sngNodeptr.i++) {
  1796.     ptrAss(sngNodeptr, nodeRecord);
  1797.     Sysfile::ActiveStatus s = 
  1798.       (Sysfile::ActiveStatus)Sysfile::getNodeStatus(sngNodeptr.i,
  1799.     SYSFILE->nodeStatus);
  1800.     switch (s){
  1801.     case Sysfile::NS_Active:
  1802.     case Sysfile::NS_ActiveMissed_1:
  1803.     case Sysfile::NS_ActiveMissed_2:
  1804.     case Sysfile::NS_NotActive_NotTakenOver:
  1805.     case Sysfile::NS_TakeOver:
  1806.       jam();
  1807.       sngNodeptr.p->nodeGroup = Sysfile::getNodeGroup(sngNodeptr.i,
  1808.                                                       SYSFILE->nodeGroups);
  1809.       NGPtr.i = sngNodeptr.p->nodeGroup;
  1810.       ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
  1811.       NGPtr.p->nodesInGroup[NGPtr.p->nodeCount] = sngNodeptr.i;
  1812.       NGPtr.p->nodeCount++;
  1813.       break;
  1814.     case Sysfile::NS_HotSpare:
  1815.     case Sysfile::NS_NotDefined:
  1816.       jam();
  1817.       sngNodeptr.p->nodeGroup = ZNIL;
  1818.       break;
  1819.     default:
  1820.       ndbrequire(false);
  1821.       return;
  1822.       break;
  1823.     }//switch
  1824.   }//for
  1825.   cnoOfNodeGroups = 0;
  1826.   for (Ti = 0; Ti < MAX_NDB_NODES; Ti++) {
  1827.     jam();
  1828.     NGPtr.i = Ti;
  1829.     ptrAss(NGPtr, nodeGroupRecord);
  1830.     if (NGPtr.p->nodeCount != 0) {
  1831.       jam();
  1832.       cnoOfNodeGroups++;
  1833.     }//if
  1834.   }//for
  1835.   cnoHotSpare = csystemnodes - (cnoOfNodeGroups * cnoReplicas);
  1836. }//Dbdih::setNodeGroups()
  1837. /*************************************************************************/
  1838. /* SET NODE INFORMATION AFTER RECEIVING RESTART INFORMATION FROM MASTER. */
  1839. /* WE TAKE THE OPPORTUNITY TO SYNCHRONISE OUR DATA WITH THE MASTER. IT   */
  1840. /* IS ONLY THE MASTER THAT WILL ACT ON THIS DATA. WE WILL KEEP THEM      */
  1841. /* UPDATED FOR THE CASE WHEN WE HAVE TO BECOME MASTER.                   */
  1842. /*************************************************************************/
  1843. void Dbdih::setNodeInfo(Signal* signal) 
  1844. {
  1845.   setNodeActiveStatus();
  1846.   setNodeGroups();
  1847.   sendHOT_SPAREREP(signal);
  1848. }//Dbdih::setNodeInfo()
  1849. /*************************************************************************/
  1850. // Keep also DBDICT informed about the Hot Spare situation in the cluster.
  1851. /*************************************************************************/
  1852. void Dbdih::sendHOT_SPAREREP(Signal* signal)
  1853. {
  1854.   NodeRecordPtr locNodeptr;
  1855.   Uint32 Ti = 0;
  1856.   HotSpareRep * const hotSpare = (HotSpareRep*)&signal->theData[0];
  1857.   NodeBitmask::clear(hotSpare->theHotSpareNodes);
  1858.   for (locNodeptr.i = 1; locNodeptr.i < MAX_NDB_NODES; locNodeptr.i++) {
  1859.     ptrAss(locNodeptr, nodeRecord);
  1860.     switch (locNodeptr.p->activeStatus) {
  1861.     case Sysfile::NS_HotSpare:
  1862.       jam();
  1863.       NodeBitmask::set(hotSpare->theHotSpareNodes, locNodeptr.i);
  1864.       Ti++;
  1865.       break;
  1866.     default:
  1867.       jam();
  1868.       break;
  1869.     }//switch
  1870.   }//for
  1871.   hotSpare->noHotSpareNodes = Ti;
  1872.   sendSignal(DBDICT_REF, GSN_HOT_SPAREREP,
  1873.              signal, HotSpareRep::SignalLength, JBB);
  1874. }//Dbdih::sendHOT_SPAREREP()
  1875. /*************************************************************************/
  1876. /*       SET LCP ACTIVE STATUS FOR ALL NODES BASED ON THE INFORMATION IN */
  1877. /*       THE RESTART INFORMATION.                                        */
  1878. /*************************************************************************/
  1879. #if 0
  1880. void Dbdih::setNodeLcpActiveStatus()
  1881. {
  1882.   c_lcpState.m_lcpActiveStatus.clear();
  1883.   for (Uint32 i = 1; i < MAX_NDB_NODES; i++) {
  1884.     if (NodeBitmask::get(SYSFILE->lcpActive, i)) {
  1885.       jam();
  1886.       c_lcpState.m_lcpActiveStatus.set(i);
  1887.     }//if
  1888.   }//for
  1889. }//Dbdih::setNodeLcpActiveStatus()
  1890. #endif
  1891. /*************************************************************************/
  1892. /* SET THE RESTART INFO BITS BASED ON THE NODES ACTIVE STATUS.           */
  1893. /*************************************************************************/
  1894. void Dbdih::setNodeRestartInfoBits() 
  1895. {
  1896.   NodeRecordPtr nodePtr;
  1897.   Uint32 tsnrNodeGroup;
  1898.   Uint32 tsnrNodeActiveStatus;
  1899.   Uint32 i; 
  1900.   for(i = 1; i < MAX_NDB_NODES; i++){
  1901.     Sysfile::setNodeStatus(i, SYSFILE->nodeStatus, Sysfile::NS_Active);
  1902.   }//for
  1903.   for(i = 1; i < Sysfile::NODE_GROUPS_SIZE; i++){
  1904.     SYSFILE->nodeGroups[i] = 0;
  1905.   }//for
  1906.   NdbNodeBitmask::clear(SYSFILE->lcpActive);
  1907.   
  1908.   for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
  1909.     ptrAss(nodePtr, nodeRecord);
  1910.     switch (nodePtr.p->activeStatus) {
  1911.     case Sysfile::NS_Active:
  1912.       jam();
  1913.       tsnrNodeActiveStatus = Sysfile::NS_Active;
  1914.       break;
  1915.     case Sysfile::NS_ActiveMissed_1:
  1916.       jam();
  1917.       tsnrNodeActiveStatus = Sysfile::NS_ActiveMissed_1;
  1918.       break;
  1919.     case Sysfile::NS_ActiveMissed_2:
  1920.       jam();
  1921.       tsnrNodeActiveStatus = Sysfile::NS_ActiveMissed_2;
  1922.       break;
  1923.     case Sysfile::NS_HotSpare:
  1924.       jam();
  1925.       tsnrNodeActiveStatus = Sysfile::NS_HotSpare;
  1926.       break;
  1927.     case Sysfile::NS_TakeOver:
  1928.       jam();
  1929.       tsnrNodeActiveStatus = Sysfile::NS_TakeOver;
  1930.       break;
  1931.     case Sysfile::NS_NotActive_NotTakenOver:
  1932.       jam();
  1933.       tsnrNodeActiveStatus = Sysfile::NS_NotActive_NotTakenOver;
  1934.       break;
  1935.     case Sysfile::NS_NotDefined:
  1936.       jam();
  1937.       tsnrNodeActiveStatus = Sysfile::NS_NotDefined;
  1938.       break;
  1939.     default:
  1940.       ndbrequire(false);
  1941.       tsnrNodeActiveStatus = Sysfile::NS_NotDefined; // remove warning
  1942.       break;
  1943.     }//switch
  1944.     Sysfile::setNodeStatus(nodePtr.i, SYSFILE->nodeStatus, 
  1945.                            tsnrNodeActiveStatus);
  1946.     if (nodePtr.p->nodeGroup == ZNIL) {
  1947.       jam();
  1948.       tsnrNodeGroup = NO_NODE_GROUP_ID;
  1949.     } else {
  1950.       jam();
  1951.       tsnrNodeGroup = nodePtr.p->nodeGroup;
  1952.     }//if
  1953.     Sysfile::setNodeGroup(nodePtr.i, SYSFILE->nodeGroups, tsnrNodeGroup);
  1954.     if (c_lcpState.m_participatingLQH.get(nodePtr.i)){
  1955.       jam();
  1956.       NodeBitmask::set(SYSFILE->lcpActive, nodePtr.i);
  1957.     }//if
  1958.   }//for
  1959. }//Dbdih::setNodeRestartInfoBits()
  1960. /*************************************************************************/
  1961. /*       START THE GLOBAL CHECKPOINT PROTOCOL IN MASTER AT START-UP      */
  1962. /*************************************************************************/
  1963. void Dbdih::startGcp(Signal* signal) 
  1964. {
  1965.   cgcpStatus = GCP_READY;
  1966.   coldGcpStatus = cgcpStatus;
  1967.   coldGcpId = cnewgcp;
  1968.   cgcpSameCounter = 0;
  1969.   signal->theData[0] = DihContinueB::ZSTART_GCP;
  1970.   signal->theData[1] = 0;
  1971.   sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
  1972.   signal->theData[0] = DihContinueB::ZCHECK_GCP_STOP;
  1973.   sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 1);
  1974. }//Dbdih::startGcp()
  1975. void Dbdih::updateNodeInfo(FragmentstorePtr fragPtr)
  1976. {
  1977.   ReplicaRecordPtr replicatePtr;
  1978.   Uint32 index = 0;
  1979.   replicatePtr.i = fragPtr.p->storedReplicas;
  1980.   do {
  1981.     jam();
  1982.     ptrCheckGuard(replicatePtr, creplicaFileSize, replicaRecord);
  1983.     ndbrequire(index < MAX_REPLICAS);
  1984.     fragPtr.p->activeNodes[index] = replicatePtr.p->procNode;
  1985.     index++;
  1986.     replicatePtr.i = replicatePtr.p->nextReplica;
  1987.   } while (replicatePtr.i != RNIL);
  1988.   fragPtr.p->fragReplicas = index;
  1989.   /* ----------------------------------------------------------------------- */
  1990.   // We switch primary to the preferred primary if the preferred primary is
  1991.   // in the list.
  1992.   /* ----------------------------------------------------------------------- */
  1993.   const Uint32 prefPrim = fragPtr.p->preferredPrimary;
  1994.   for (Uint32 i = 1; i < index; i++) {
  1995.     jam();
  1996.     ndbrequire(i < MAX_REPLICAS);
  1997.     if (fragPtr.p->activeNodes[i] == prefPrim){
  1998.       jam();
  1999.       Uint32 switchNode = fragPtr.p->activeNodes[0];
  2000.       fragPtr.p->activeNodes[0] = prefPrim;
  2001.       fragPtr.p->activeNodes[i] = switchNode;
  2002.       break;
  2003.     }//if
  2004.   }//for
  2005. }//Dbdih::updateNodeInfo()
  2006. void Dbdih::writeFragment(RWFragment* wf, FragmentstorePtr fragPtr) 
  2007. {
  2008.   writePageWord(wf, wf->fragId);
  2009.   writePageWord(wf, fragPtr.p->preferredPrimary);
  2010.   writePageWord(wf, fragPtr.p->noStoredReplicas);
  2011.   writePageWord(wf, fragPtr.p->noOldStoredReplicas);
  2012.   writePageWord(wf, fragPtr.p->distributionKey);
  2013. }//Dbdih::writeFragment()
  2014. void Dbdih::writePageWord(RWFragment* wf, Uint32 dataWord)
  2015. {
  2016.   if (wf->wordIndex >= 2048) {
  2017.     jam();
  2018.     ndbrequire(wf->wordIndex == 2048);
  2019.     allocpage(wf->rwfPageptr);
  2020.     wf->wordIndex = 32;
  2021.     wf->pageIndex++;
  2022.     ndbrequire(wf->pageIndex < 8);
  2023.     wf->rwfTabPtr.p->pageRef[wf->pageIndex] = wf->rwfPageptr.i;
  2024.     wf->rwfTabPtr.p->noPages++;
  2025.   }//if
  2026.   wf->rwfPageptr.p->word[wf->wordIndex] = dataWord;
  2027.   wf->wordIndex++;
  2028. }//Dbdih::writePageWord()
  2029. void Dbdih::writeReplicas(RWFragment* wf, Uint32 replicaStartIndex) 
  2030. {
  2031.   ReplicaRecordPtr wfReplicaPtr;
  2032.   wfReplicaPtr.i = replicaStartIndex;
  2033.   while (wfReplicaPtr.i != RNIL) {
  2034.     jam();
  2035.     ptrCheckGuard(wfReplicaPtr, creplicaFileSize, replicaRecord);
  2036.     writePageWord(wf, wfReplicaPtr.p->procNode);
  2037.     writePageWord(wf, wfReplicaPtr.p->initialGci);
  2038.     writePageWord(wf, wfReplicaPtr.p->noCrashedReplicas);
  2039.     writePageWord(wf, wfReplicaPtr.p->nextLcp);
  2040.     Uint32 i;
  2041.     for (i = 0; i < MAX_LCP_STORED; i++) {
  2042.       writePageWord(wf, wfReplicaPtr.p->maxGciCompleted[i]);
  2043.       writePageWord(wf, wfReplicaPtr.p->maxGciStarted[i]);
  2044.       writePageWord(wf, wfReplicaPtr.p->lcpId[i]);
  2045.       writePageWord(wf, wfReplicaPtr.p->lcpStatus[i]);
  2046.     }//if
  2047.     for (i = 0; i < 8; i++) {
  2048.       writePageWord(wf, wfReplicaPtr.p->createGci[i]);
  2049.       writePageWord(wf, wfReplicaPtr.p->replicaLastGci[i]);
  2050.     }//if
  2051.     wfReplicaPtr.i = wfReplicaPtr.p->nextReplica;
  2052.   }//while
  2053. }//Dbdih::writeReplicas()
  2054. void Dbdih::writeRestorableGci(Signal* signal, FileRecordPtr filePtr)
  2055. {
  2056.   for (Uint32 i = 0; i < Sysfile::SYSFILE_SIZE32; i++) {
  2057.     sysfileDataToFile[i] = sysfileData[i];
  2058.   }//for
  2059.   signal->theData[0] = filePtr.p->fileRef;
  2060.   signal->theData[1] = reference();
  2061.   signal->theData[2] = filePtr.i;
  2062.   signal->theData[3] = ZLIST_OF_PAIRS_SYNCH;
  2063.   signal->theData[4] = ZVAR_NO_CRESTART_INFO_TO_FILE;
  2064.   signal->theData[5] = 1; /* AMOUNT OF PAGES */
  2065.   signal->theData[6] = 0; /* MEMORY PAGE = 0 SINCE COMMON STORED VARIABLE  */
  2066.   signal->theData[7] = 0;
  2067.   sendSignal(NDBFS_REF, GSN_FSWRITEREQ, signal, 8, JBA);
  2068. }//Dbdih::writeRestorableGci()
  2069. void Dbdih::writeTabfile(Signal* signal, TabRecord* tab, FileRecordPtr filePtr) 
  2070. {
  2071.   signal->theData[0] = filePtr.p->fileRef;
  2072.   signal->theData[1] = reference();
  2073.   signal->theData[2] = filePtr.i;
  2074.   signal->theData[3] = ZLIST_OF_PAIRS;
  2075.   signal->theData[4] = ZVAR_NO_WORD;
  2076.   signal->theData[5] = tab->noPages;
  2077.   for (Uint32 i = 0; i < tab->noPages; i++) {
  2078.     jam();
  2079.     signal->theData[6 + (2 * i)] = tab->pageRef[i];
  2080.     signal->theData[7 + (2 * i)] = i;
  2081.   }//for
  2082.   Uint32 length = 6 + (2 * tab->noPages);
  2083.   sendSignal(NDBFS_REF, GSN_FSWRITEREQ, signal, length, JBA);
  2084. }//Dbdih::writeTabfile()
  2085. void Dbdih::execDEBUG_SIG(Signal* signal) 
  2086. {
  2087.   signal = signal; //Avoid compiler warnings
  2088. }//Dbdih::execDEBUG_SIG()
  2089. void
  2090. Dbdih::execDUMP_STATE_ORD(Signal* signal)
  2091. {
  2092.   DumpStateOrd * const & dumpState = (DumpStateOrd *)&signal->theData[0];
  2093.   if (dumpState->args[0] == DumpStateOrd::DihDumpNodeRestartInfo) {
  2094.     infoEvent("c_nodeStartMaster.blockLcp = %d, c_nodeStartMaster.blockGcp = %d, c_nodeStartMaster.wait = %d",
  2095.       c_nodeStartMaster.blockLcp, c_nodeStartMaster.blockGcp, c_nodeStartMaster.wait);
  2096.     infoEvent("cstartGcpNow = %d, cgcpStatus = %d",
  2097.               cstartGcpNow, cgcpStatus);
  2098.     infoEvent("cfirstVerifyQueue = %d, cverifyQueueCounter = %d",
  2099.               cfirstVerifyQueue, cverifyQueueCounter);
  2100.     infoEvent("cgcpOrderBlocked = %d, cgcpStartCounter = %d",
  2101.               cgcpOrderBlocked, cgcpStartCounter);
  2102.   }//if  
  2103.   if (dumpState->args[0] == DumpStateOrd::DihDumpNodeStatusInfo) {
  2104.     NodeRecordPtr localNodePtr;
  2105.     infoEvent("Printing nodeStatus of all nodes");
  2106.     for (localNodePtr.i = 1; localNodePtr.i < MAX_NDB_NODES; localNodePtr.i++) {
  2107.       ptrAss(localNodePtr, nodeRecord);
  2108.       if (localNodePtr.p->nodeStatus != NodeRecord::NOT_IN_CLUSTER) {
  2109.         infoEvent("Node = %d has status = %d",
  2110.   localNodePtr.i, localNodePtr.p->nodeStatus);
  2111.       }//if
  2112.     }//for
  2113.   }//if
  2114.   
  2115.   if (dumpState->args[0] == DumpStateOrd::DihPrintFragmentation){
  2116.     infoEvent("Printing fragmentation of all tables --");
  2117.     for(Uint32 i = 0; i<ctabFileSize; i++){
  2118.       TabRecordPtr tabPtr;
  2119.       tabPtr.i = i;
  2120.       ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  2121.       
  2122.       if(tabPtr.p->tabStatus != TabRecord::TS_ACTIVE)
  2123. continue;
  2124.       
  2125.       for(Uint32 j = 0; j < tabPtr.p->totalfragments; j++){
  2126. FragmentstorePtr fragPtr;
  2127. getFragstore(tabPtr.p, j, fragPtr);
  2128. Uint32 nodeOrder[MAX_REPLICAS];
  2129. const Uint32 noOfReplicas = extractNodeInfo(fragPtr.p, nodeOrder);
  2130. char buf[100];
  2131. BaseString::snprintf(buf, sizeof(buf), " Table %d Fragment %d - ", tabPtr.i, j);
  2132. for(Uint32 k = 0; k < noOfReplicas; k++){
  2133.   char tmp[100];
  2134.   BaseString::snprintf(tmp, sizeof(tmp), "%d ", nodeOrder[k]);
  2135.   strcat(buf, tmp);
  2136. }
  2137. infoEvent(buf);
  2138.       }
  2139.     }
  2140.   }
  2141.   
  2142.   if (signal->theData[0] == 7000) {
  2143.     infoEvent("ctimer = %d, cgcpParticipantState = %d, cgcpStatus = %d",
  2144.               c_lcpState.ctimer, cgcpParticipantState, cgcpStatus);
  2145.     infoEvent("coldGcpStatus = %d, coldGcpId = %d, cmasterState = %d",
  2146.               coldGcpStatus, coldGcpId, cmasterState);
  2147.     infoEvent("cmasterTakeOverNode = %d, ctcCounter = %d",
  2148.               cmasterTakeOverNode, c_lcpState.ctcCounter);
  2149.   }//if  
  2150.   if (signal->theData[0] == 7001) {
  2151.     infoEvent("c_lcpState.keepGci = %d",
  2152.               c_lcpState.keepGci);
  2153.     infoEvent("c_lcpState.lcpStatus = %d, clcpStartGcp = %d",
  2154.               c_lcpState.lcpStatus, 
  2155.       c_lcpState.lcpStartGcp);
  2156.     infoEvent("cgcpStartCounter = %d, cimmediateLcpStart = %d",
  2157.               cgcpStartCounter, c_lcpState.immediateLcpStart);
  2158.   }//if  
  2159.   if (signal->theData[0] == 7002) {
  2160.     infoEvent("cnoOfActiveTables = %d, cgcpDelay = %d",
  2161.               cnoOfActiveTables, cgcpDelay);
  2162.     infoEvent("cdictblockref = %d, cfailurenr = %d",
  2163.               cdictblockref, cfailurenr);
  2164.     infoEvent("con_lineNodes = %d, reference() = %d, creceivedfrag = %d",
  2165.               con_lineNodes, reference(), creceivedfrag);
  2166.   }//if  
  2167.   if (signal->theData[0] == 7003) {
  2168.     infoEvent("cfirstAliveNode = %d, cgckptflag = %d",
  2169.               cfirstAliveNode, cgckptflag);
  2170.     infoEvent("clocallqhblockref = %d, clocaltcblockref = %d, cgcpOrderBlocked = %d",
  2171.               clocallqhblockref, clocaltcblockref, cgcpOrderBlocked);
  2172.     infoEvent("cstarttype = %d, csystemnodes = %d, currentgcp = %d",
  2173.               cstarttype, csystemnodes, currentgcp);
  2174.   }//if  
  2175.   if (signal->theData[0] == 7004) {
  2176.     infoEvent("cmasterdihref = %d, cownNodeId = %d, cnewgcp = %d",
  2177.               cmasterdihref, cownNodeId, cnewgcp);
  2178.     infoEvent("cndbStartReqBlockref = %d, cremainingfrags = %d",
  2179.               cndbStartReqBlockref, cremainingfrags);
  2180.     infoEvent("cntrlblockref = %d, cgcpSameCounter = %d, coldgcp = %d",
  2181.               cntrlblockref, cgcpSameCounter, coldgcp);
  2182.   }//if  
  2183.   if (signal->theData[0] == 7005) {
  2184.     infoEvent("crestartGci = %d",
  2185.               crestartGci);
  2186.   }//if  
  2187.   if (signal->theData[0] == 7006) {
  2188.     infoEvent("clcpDelay = %d, cgcpMasterTakeOverState = %d",
  2189.               c_lcpState.clcpDelay, cgcpMasterTakeOverState);
  2190.     infoEvent("cmasterNodeId = %d", cmasterNodeId);
  2191.     infoEvent("cnoHotSpare = %d, c_nodeStartMaster.startNode = %d, c_nodeStartMaster.wait = %d",
  2192.               cnoHotSpare, c_nodeStartMaster.startNode, c_nodeStartMaster.wait);
  2193.   }//if  
  2194.   if (signal->theData[0] == 7007) {
  2195.     infoEvent("c_nodeStartMaster.failNr = %d", c_nodeStartMaster.failNr);
  2196.     infoEvent("c_nodeStartMaster.startInfoErrorCode = %d",
  2197.               c_nodeStartMaster.startInfoErrorCode);
  2198.     infoEvent("c_nodeStartMaster.blockLcp = %d, c_nodeStartMaster.blockGcp = %d",
  2199.               c_nodeStartMaster.blockLcp, c_nodeStartMaster.blockGcp);
  2200.   }//if  
  2201.   if (signal->theData[0] == 7008) {
  2202.     infoEvent("cfirstDeadNode = %d, cstartPhase = %d, cnoReplicas = %d",
  2203.               cfirstDeadNode, cstartPhase, cnoReplicas);
  2204.     infoEvent("cwaitLcpSr = %d",cwaitLcpSr);
  2205.   }//if  
  2206.   if (signal->theData[0] == 7009) {
  2207.     infoEvent("ccalcOldestRestorableGci = %d, cnoOfNodeGroups = %d",
  2208.               c_lcpState.oldestRestorableGci, cnoOfNodeGroups);
  2209.     infoEvent("cstartGcpNow = %d",
  2210.               cstartGcpNow);
  2211.     infoEvent("crestartGci = %d",
  2212.               crestartGci);
  2213.   }//if  
  2214.   if (signal->theData[0] == 7010) {
  2215.     infoEvent("cminHotSpareNodes = %d, c_lcpState.lcpStatusUpdatedPlace = %d, cLcpStart = %d",
  2216.               cminHotSpareNodes, c_lcpState.lcpStatusUpdatedPlace, c_lcpState.lcpStart);
  2217.     infoEvent("c_blockCommit = %d, c_blockCommitNo = %d",
  2218.               c_blockCommit, c_blockCommitNo);
  2219.   }//if  
  2220.   if (signal->theData[0] == 7011){
  2221.     infoEvent("c_COPY_GCIREQ_Counter = %s", 
  2222.       c_COPY_GCIREQ_Counter.getText());
  2223.     infoEvent("c_COPY_TABREQ_Counter = %s", 
  2224.       c_COPY_TABREQ_Counter.getText());
  2225.     infoEvent("c_CREATE_FRAGREQ_Counter = %s", 
  2226.       c_CREATE_FRAGREQ_Counter.getText());
  2227.     infoEvent("c_DIH_SWITCH_REPLICA_REQ_Counter = %s", 
  2228.       c_DIH_SWITCH_REPLICA_REQ_Counter.getText());
  2229.     infoEvent("c_EMPTY_LCP_REQ_Counter = %s",c_EMPTY_LCP_REQ_Counter.getText());
  2230.     infoEvent("c_END_TOREQ_Counter = %s", c_END_TOREQ_Counter.getText());
  2231.     infoEvent("c_GCP_COMMIT_Counter = %s", c_GCP_COMMIT_Counter.getText());
  2232.     infoEvent("c_GCP_PREPARE_Counter = %s", c_GCP_PREPARE_Counter.getText());
  2233.     infoEvent("c_GCP_SAVEREQ_Counter = %s", c_GCP_SAVEREQ_Counter.getText());
  2234.     infoEvent("c_INCL_NODEREQ_Counter = %s", c_INCL_NODEREQ_Counter.getText());
  2235.     infoEvent("c_MASTER_GCPREQ_Counter = %s", 
  2236.       c_MASTER_GCPREQ_Counter.getText());
  2237.     infoEvent("c_MASTER_LCPREQ_Counter = %s", 
  2238.       c_MASTER_LCPREQ_Counter.getText());
  2239.     infoEvent("c_START_INFOREQ_Counter = %s", 
  2240.       c_START_INFOREQ_Counter.getText());
  2241.     infoEvent("c_START_RECREQ_Counter = %s", c_START_RECREQ_Counter.getText());
  2242.     infoEvent("c_START_TOREQ_Counter = %s", c_START_TOREQ_Counter.getText());
  2243.     infoEvent("c_STOP_ME_REQ_Counter = %s", c_STOP_ME_REQ_Counter.getText());
  2244.     infoEvent("c_TC_CLOPSIZEREQ_Counter = %s", 
  2245.       c_TC_CLOPSIZEREQ_Counter.getText());
  2246.     infoEvent("c_TCGETOPSIZEREQ_Counter = %s", 
  2247.       c_TCGETOPSIZEREQ_Counter.getText());
  2248.     infoEvent("c_UPDATE_TOREQ_Counter = %s", c_UPDATE_TOREQ_Counter.getText());
  2249.   }
  2250.   if(signal->theData[0] == 7012){
  2251.     char buf[8*_NDB_NODE_BITMASK_SIZE+1];
  2252.     infoEvent("ParticipatingDIH = %s", c_lcpState.m_participatingDIH.getText(buf));
  2253.     infoEvent("ParticipatingLQH = %s", c_lcpState.m_participatingLQH.getText(buf));
  2254.     infoEvent("m_LCP_COMPLETE_REP_Counter_DIH = %s",
  2255.       c_lcpState.m_LCP_COMPLETE_REP_Counter_DIH.getText());
  2256.     infoEvent("m_LCP_COMPLETE_REP_Counter_LQH = %s",
  2257.       c_lcpState.m_LCP_COMPLETE_REP_Counter_LQH.getText());
  2258.     infoEvent("m_LAST_LCP_FRAG_ORD = %s",
  2259.       c_lcpState.m_LAST_LCP_FRAG_ORD.getText());
  2260.     infoEvent("m_LCP_COMPLETE_REP_From_Master_Received = %d",
  2261.       c_lcpState.m_LCP_COMPLETE_REP_From_Master_Received);
  2262.     
  2263.     NodeRecordPtr nodePtr;
  2264.     for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
  2265.       jam();
  2266.       ptrAss(nodePtr, nodeRecord);
  2267.       if(nodePtr.p->nodeStatus == NodeRecord::ALIVE){
  2268.         Uint32 i;
  2269. for(i = 0; i<nodePtr.p->noOfStartedChkpt; i++){
  2270.   infoEvent("Node %d: started: table=%d fragment=%d replica=%d",
  2271.     nodePtr.i, 
  2272.     nodePtr.p->startedChkpt[i].tableId,
  2273.     nodePtr.p->startedChkpt[i].fragId,
  2274.     nodePtr.p->startedChkpt[i].replicaPtr);
  2275. }
  2276. for(i = 0; i<nodePtr.p->noOfQueuedChkpt; i++){
  2277.   infoEvent("Node %d: queued: table=%d fragment=%d replica=%d",
  2278.     nodePtr.i, 
  2279.     nodePtr.p->queuedChkpt[i].tableId,
  2280.     nodePtr.p->queuedChkpt[i].fragId,
  2281.     nodePtr.p->queuedChkpt[i].replicaPtr);
  2282. }
  2283.       }
  2284.     }
  2285.   }
  2286.   if(dumpState->args[0] == 7019 && signal->getLength() == 2)
  2287.   {
  2288.     char buf2[8+1];
  2289.     NodeRecordPtr nodePtr;
  2290.     nodePtr.i = signal->theData[1];
  2291.     ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
  2292.     infoEvent("NF Node %d tc: %d lqh: %d dih: %d dict: %d recNODE_FAILREP: %d",
  2293.       nodePtr.i,
  2294.       nodePtr.p->dbtcFailCompleted,
  2295.       nodePtr.p->dblqhFailCompleted,
  2296.       nodePtr.p->dbdihFailCompleted,
  2297.       nodePtr.p->dbdictFailCompleted,
  2298.       nodePtr.p->recNODE_FAILREP);
  2299.     infoEvent(" m_NF_COMPLETE_REP: %s m_nodefailSteps: %s",
  2300.       nodePtr.p->m_NF_COMPLETE_REP.getText(),
  2301.       nodePtr.p->m_nodefailSteps.getText(buf2));
  2302.   }
  2303.   
  2304.   if(dumpState->args[0] == 7020 && signal->getLength() > 3)
  2305.   {
  2306.     Uint32 gsn= signal->theData[1];
  2307.     Uint32 block= signal->theData[2];
  2308.     Uint32 length= signal->length() - 3;
  2309.     memmove(signal->theData, signal->theData+3, 4*length);
  2310.     sendSignal(numberToRef(block, getOwnNodeId()), gsn, signal, length, JBB);
  2311.     
  2312.     warningEvent("-- SENDING CUSTOM SIGNAL --");
  2313.     char buf[100], buf2[100];
  2314.     buf2[0]= 0;
  2315.     for(Uint32 i = 0; i<length; i++)
  2316.     {
  2317.       snprintf(buf, 100, "%s %.8x", buf2, signal->theData[i]);
  2318.       snprintf(buf2, 100, "%s", buf);
  2319.     }
  2320.     warningEvent("gsn: %d block: %s, length: %d theData: %s", 
  2321.  gsn, getBlockName(block, "UNKNOWN"), length, buf);
  2322.     g_eventLogger.warning("-- SENDING CUSTOM SIGNAL --");
  2323.     g_eventLogger.warning("gsn: %d block: %s, length: %d theData: %s", 
  2324.   gsn, getBlockName(block, "UNKNOWN"), length, buf);
  2325.   }
  2326.   
  2327.   if(dumpState->args[0] == DumpStateOrd::DihDumpLCPState){
  2328.     infoEvent("-- Node %d LCP STATE --", getOwnNodeId());
  2329.     infoEvent("lcpStatus = %d (update place = %d) ",
  2330.       c_lcpState.lcpStatus, c_lcpState.lcpStatusUpdatedPlace);
  2331.     infoEvent
  2332.       ("lcpStart = %d lcpStartGcp = %d keepGci = %d oldestRestorable = %d",
  2333.        c_lcpState.lcpStart, c_lcpState.lcpStartGcp, 
  2334.        c_lcpState.keepGci, c_lcpState.oldestRestorableGci);
  2335.     
  2336.     infoEvent
  2337.       ("immediateLcpStart = %d masterLcpNodeId = %d",
  2338.        c_lcpState.immediateLcpStart,
  2339.        refToNode(c_lcpState.m_masterLcpDihRef));
  2340.     infoEvent("-- Node %d LCP STATE --", getOwnNodeId());
  2341.   }
  2342.   if(dumpState->args[0] == DumpStateOrd::DihDumpLCPMasterTakeOver){
  2343.     infoEvent("-- Node %d LCP MASTER TAKE OVER STATE --", getOwnNodeId());
  2344.     infoEvent
  2345.       ("c_lcpMasterTakeOverState.state = %d updatePlace = %d failedNodeId = %d",
  2346.        c_lcpMasterTakeOverState.state,
  2347.        c_lcpMasterTakeOverState.updatePlace,
  2348.        c_lcpMasterTakeOverState.failedNodeId);
  2349.     
  2350.     infoEvent("c_lcpMasterTakeOverState.minTableId = %u minFragId = %u",
  2351.       c_lcpMasterTakeOverState.minTableId,
  2352.       c_lcpMasterTakeOverState.minFragId);
  2353.     
  2354.     infoEvent("-- Node %d LCP MASTER TAKE OVER STATE --", getOwnNodeId());
  2355.   }
  2356.   if (signal->theData[0] == 7015){
  2357.     for(Uint32 i = 0; i<ctabFileSize; i++){
  2358.       TabRecordPtr tabPtr;
  2359.       tabPtr.i = i;
  2360.       ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  2361.       
  2362.       if(tabPtr.p->tabStatus != TabRecord::TS_ACTIVE)
  2363. continue;
  2364.       
  2365.       infoEvent
  2366. ("Table %d: TabCopyStatus: %d TabUpdateStatus: %d TabLcpStatus: %d",
  2367.  tabPtr.i, 
  2368.  tabPtr.p->tabCopyStatus, 
  2369.  tabPtr.p->tabUpdateState,
  2370.  tabPtr.p->tabLcpStatus);
  2371.       FragmentstorePtr fragPtr;
  2372.       for (Uint32 fid = 0; fid < tabPtr.p->totalfragments; fid++) {
  2373. jam();
  2374. getFragstore(tabPtr.p, fid, fragPtr);
  2375. char buf[100], buf2[100];
  2376. BaseString::snprintf(buf, sizeof(buf), " Fragment %d: noLcpReplicas==%d ", 
  2377.  fid, fragPtr.p->noLcpReplicas);
  2378. Uint32 num=0;
  2379. ReplicaRecordPtr replicaPtr;
  2380. replicaPtr.i = fragPtr.p->storedReplicas;
  2381. do {
  2382.   ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
  2383.   BaseString::snprintf(buf2, sizeof(buf2), "%s %d(on %d)=%d(%s)",
  2384.    buf, num, 
  2385.    replicaPtr.p->procNode, 
  2386.    replicaPtr.p->lcpIdStarted,
  2387.    replicaPtr.p->lcpOngoingFlag ? "Ongoing" : "Idle");
  2388.   BaseString::snprintf(buf, sizeof(buf), "%s", buf2);
  2389.   
  2390.   num++;
  2391.   replicaPtr.i = replicaPtr.p->nextReplica;
  2392. } while (replicaPtr.i != RNIL);
  2393. infoEvent(buf);
  2394.       }
  2395.     }
  2396.   }
  2397.   if(dumpState->args[0] == DumpStateOrd::EnableUndoDelayDataWrite){
  2398.     ndbout << "Dbdih:: delay write of datapages for table = " 
  2399.    << dumpState->args[1]<< endl;
  2400.     // Send this dump to ACC and TUP
  2401.     EXECUTE_DIRECT(DBACC, GSN_DUMP_STATE_ORD, signal, 2);
  2402.     EXECUTE_DIRECT(DBTUP, GSN_DUMP_STATE_ORD, signal, 2);
  2403.     
  2404.     // Start immediate LCP
  2405.     c_lcpState.ctimer += (1 << c_lcpState.clcpDelay);
  2406.     return;
  2407.   }
  2408.   if (signal->theData[0] == DumpStateOrd::DihAllAllowNodeStart) {
  2409.     for (Uint32 i = 1; i < MAX_NDB_NODES; i++)
  2410.       setAllowNodeStart(i, true);
  2411.     return;
  2412.   }//if
  2413.   if (signal->theData[0] == DumpStateOrd::DihMinTimeBetweenLCP) {
  2414.     // Set time between LCP to min value
  2415.     ndbout << "Set time between LCP to min value" << endl;
  2416.     c_lcpState.clcpDelay = 0; // TimeBetweenLocalCheckpoints.min
  2417.     return;
  2418.   }
  2419.   if (signal->theData[0] == DumpStateOrd::DihMaxTimeBetweenLCP) {
  2420.     // Set time between LCP to max value
  2421.     ndbout << "Set time between LCP to max value" << endl;
  2422.     c_lcpState.clcpDelay = 31; // TimeBetweenLocalCheckpoints.max
  2423.     return;
  2424.   }
  2425.   
  2426.   if(dumpState->args[0] == 7098){
  2427.     if(signal->length() == 3){
  2428.       jam();
  2429.       infoEvent("startLcpRoundLoopLab(tabel=%d, fragment=%d)",
  2430. signal->theData[1], signal->theData[2]);
  2431.       startLcpRoundLoopLab(signal, signal->theData[1], signal->theData[2]);
  2432.       return;
  2433.     } else {
  2434.       infoEvent("Invalid no of arguments to 7098 - startLcpRoundLoopLab -"
  2435. " expected 2 (tableId, fragmentId)");
  2436.     }
  2437.   }
  2438.   if(dumpState->args[0] == DumpStateOrd::DihStartLcpImmediately){
  2439.     c_lcpState.ctimer += (1 << c_lcpState.clcpDelay);
  2440.     return;
  2441.   }
  2442. }//Dbdih::execDUMP_STATE_ORD()
  2443. void
  2444. Dbdih::execPREP_DROP_TAB_REQ(Signal* signal){
  2445.   jamEntry();
  2446.   
  2447.   PrepDropTabReq* req = (PrepDropTabReq*)signal->getDataPtr();
  2448.   
  2449.   TabRecordPtr tabPtr;
  2450.   tabPtr.i = req->tableId;
  2451.   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  2452.   
  2453.   Uint32 senderRef = req->senderRef;
  2454.   Uint32 senderData = req->senderData;
  2455.   
  2456.   PrepDropTabRef::ErrorCode err = PrepDropTabRef::OK;
  2457.   { /**
  2458.      * Check table state
  2459.      */
  2460.     bool ok = false;
  2461.     switch(tabPtr.p->tabStatus){
  2462.     case TabRecord::TS_IDLE:
  2463.       ok = true;
  2464.       jam();
  2465.       err = PrepDropTabRef::NoSuchTable;
  2466.       break;
  2467.     case TabRecord::TS_DROPPING:
  2468.       ok = true;
  2469.       jam();
  2470.       err = PrepDropTabRef::PrepDropInProgress;
  2471.       break;
  2472.     case TabRecord::TS_CREATING:
  2473.       jam();
  2474.       ok = true;
  2475.       break;
  2476.     case TabRecord::TS_ACTIVE:
  2477.       ok = true;
  2478.       jam();
  2479.       break;
  2480.     }
  2481.     ndbrequire(ok);
  2482.   }
  2483.   if(err != PrepDropTabRef::OK){
  2484.     jam();
  2485.     PrepDropTabRef* ref = (PrepDropTabRef*)signal->getDataPtrSend();
  2486.     ref->senderRef = reference();
  2487.     ref->senderData = senderData;
  2488.     ref->tableId = tabPtr.i;
  2489.     ref->errorCode = err;
  2490.     sendSignal(senderRef, GSN_PREP_DROP_TAB_REF, signal,
  2491.        PrepDropTabRef::SignalLength, JBB);
  2492.     return;
  2493.   }
  2494.   tabPtr.p->tabStatus = TabRecord::TS_DROPPING;
  2495.   tabPtr.p->m_prepDropTab.senderRef = senderRef;
  2496.   tabPtr.p->m_prepDropTab.senderData = senderData;
  2497.   
  2498.   if(isMaster()){
  2499.     /**
  2500.      * Remove from queue
  2501.      */
  2502.     NodeRecordPtr nodePtr;
  2503.     for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
  2504.       jam();
  2505.       ptrAss(nodePtr, nodeRecord);
  2506.       if (c_lcpState.m_participatingLQH.get(nodePtr.i)){
  2507. Uint32 index = 0;
  2508. Uint32 count = nodePtr.p->noOfQueuedChkpt;
  2509. while(index < count){
  2510.   if(nodePtr.p->queuedChkpt[index].tableId == tabPtr.i){
  2511.     jam();
  2512.     //     ndbout_c("Unqueuing %d", index);
  2513.     
  2514.     count--;
  2515.     for(Uint32 i = index; i<count; i++){
  2516.       jam();
  2517.       nodePtr.p->queuedChkpt[i] = nodePtr.p->queuedChkpt[i + 1];
  2518.     }
  2519.   } else {
  2520.     index++;
  2521.   }
  2522. }
  2523. nodePtr.p->noOfQueuedChkpt = count;
  2524.       }
  2525.     }
  2526.   }
  2527.   
  2528.   { /**
  2529.      * Check table lcp state
  2530.      */
  2531.     
  2532.     bool ok = false;
  2533.     switch(tabPtr.p->tabLcpStatus){
  2534.     case TabRecord::TLS_COMPLETED:
  2535.     case TabRecord::TLS_WRITING_TO_FILE:
  2536.       ok = true;
  2537.       jam();
  2538.       break;
  2539.       return;
  2540.     case TabRecord::TLS_ACTIVE:
  2541.       ok = true;
  2542.       jam();
  2543.       
  2544.       tabPtr.p->tabLcpStatus = TabRecord::TLS_COMPLETED;
  2545.       
  2546.       /**
  2547.        * First check if all fragments are done
  2548.        */
  2549.       if(checkLcpAllTablesDoneInLqh()){
  2550. jam();
  2551. ndbout_c("This is the last table");
  2552. /**
  2553.  * Then check if saving of tab info is done for all tables
  2554.  */
  2555. LcpStatus a = c_lcpState.lcpStatus;
  2556. checkLcpCompletedLab(signal);
  2557. if(a != c_lcpState.lcpStatus){
  2558.   ndbout_c("And all tables are written to already written disk");
  2559. }
  2560.       }
  2561.       break;
  2562.     }
  2563.     ndbrequire(ok);
  2564.   }  
  2565.   
  2566.   { /**
  2567.      * Send WaitDropTabReq to all LQH
  2568.      */
  2569.     WaitDropTabReq * req = (WaitDropTabReq*)signal->getDataPtrSend();
  2570.     req->tableId = tabPtr.i;
  2571.     req->senderRef = reference();
  2572.     
  2573.     NodeRecordPtr nodePtr;
  2574.     nodePtr.i = cfirstAliveNode;
  2575.     tabPtr.p->m_prepDropTab.waitDropTabCount.clearWaitingFor();
  2576.     while(nodePtr.i != RNIL){
  2577.       jam();
  2578.       ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
  2579.       
  2580.       tabPtr.p->m_prepDropTab.waitDropTabCount.setWaitingFor(nodePtr.i);
  2581.       sendSignal(calcLqhBlockRef(nodePtr.i), GSN_WAIT_DROP_TAB_REQ,
  2582.  signal, WaitDropTabReq::SignalLength, JBB);
  2583.       
  2584.       nodePtr.i = nodePtr.p->nextNode;
  2585.     }
  2586.   }
  2587.   
  2588.   waitDropTabWritingToFile(signal, tabPtr);
  2589. }
  2590. void
  2591. Dbdih::waitDropTabWritingToFile(Signal* signal, TabRecordPtr tabPtr){
  2592.   
  2593.   if(tabPtr.p->tabLcpStatus == TabRecord::TLS_WRITING_TO_FILE){
  2594.     jam();
  2595.     signal->theData[0] = DihContinueB::WAIT_DROP_TAB_WRITING_TO_FILE;
  2596.     signal->theData[1] = tabPtr.i;
  2597.     sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 2);
  2598.     return;
  2599.   }
  2600.   ndbrequire(tabPtr.p->tabLcpStatus ==  TabRecord::TLS_COMPLETED);
  2601.   checkPrepDropTabComplete(signal, tabPtr);
  2602. }
  2603. void
  2604. Dbdih::checkPrepDropTabComplete(Signal* signal, TabRecordPtr tabPtr){
  2605.   
  2606.   if(tabPtr.p->tabLcpStatus !=  TabRecord::TLS_COMPLETED){
  2607.     jam();
  2608.     return;
  2609.   }
  2610.   
  2611.   if(!tabPtr.p->m_prepDropTab.waitDropTabCount.done()){
  2612.     jam();
  2613.     return;
  2614.   }
  2615.   
  2616.   const Uint32 ref = tabPtr.p->m_prepDropTab.senderRef;
  2617.   if(ref != 0){
  2618.     PrepDropTabConf* conf = (PrepDropTabConf*)signal->getDataPtrSend();
  2619.     conf->tableId = tabPtr.i;
  2620.     conf->senderRef = reference();
  2621.     conf->senderData = tabPtr.p->m_prepDropTab.senderData;
  2622.     sendSignal(tabPtr.p->m_prepDropTab.senderRef, GSN_PREP_DROP_TAB_CONF, 
  2623.        signal, PrepDropTabConf::SignalLength, JBB);
  2624.     tabPtr.p->m_prepDropTab.senderRef = 0;
  2625.   }
  2626. }
  2627. void
  2628. Dbdih::execWAIT_DROP_TAB_REF(Signal* signal){
  2629.   jamEntry();
  2630.   WaitDropTabRef * ref = (WaitDropTabRef*)signal->getDataPtr();
  2631.   
  2632.   TabRecordPtr tabPtr;
  2633.   tabPtr.i = ref->tableId;
  2634.   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  2635.   
  2636.   ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_DROPPING);
  2637.   Uint32 nodeId = refToNode(ref->senderRef);
  2638.  
  2639.   ndbrequire(ref->errorCode == WaitDropTabRef::NoSuchTable ||
  2640.      ref->errorCode == WaitDropTabRef::NF_FakeErrorREF);
  2641.   tabPtr.p->m_prepDropTab.waitDropTabCount.clearWaitingFor(nodeId);
  2642.   checkPrepDropTabComplete(signal, tabPtr);
  2643. }
  2644. void
  2645. Dbdih::execWAIT_DROP_TAB_CONF(Signal* signal){
  2646.   jamEntry();
  2647.   WaitDropTabConf * conf = (WaitDropTabConf*)signal->getDataPtr();
  2648.   
  2649.   TabRecordPtr tabPtr;
  2650.   tabPtr.i = conf->tableId;
  2651.   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
  2652.   
  2653.   ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_DROPPING);
  2654.   Uint32 nodeId = refToNode(conf->senderRef);
  2655.   tabPtr.p->m_prepDropTab.waitDropTabCount.clearWaitingFor(nodeId);
  2656.   checkPrepDropTabComplete(signal, tabPtr);
  2657. }
  2658. void
  2659. Dbdih::checkWaitDropTabFailedLqh(Signal* signal, Uint32 nodeId, Uint32 tableId){
  2660.   
  2661.   TabRecordPtr tabPtr;
  2662.   tabPtr.i = tableId;
  2663.   WaitDropTabConf * conf = (WaitDropTabConf*)signal->getDataPtr();
  2664.   conf->tableId = tableId;
  2665.   const Uint32 RT_BREAK = 16;
  2666.   for(Uint32 i = 0; i<RT_BREAK && tabPtr.i < ctabFileSize; i++, tabPtr.i++){
  2667.     ptrAss(tabPtr, tabRecord);
  2668.     if(tabPtr.p->tabStatus == TabRecord::TS_DROPPING){
  2669.       if(tabPtr.p->m_prepDropTab.waitDropTabCount.isWaitingFor(nodeId)){
  2670. conf->senderRef = calcLqhBlockRef(nodeId);
  2671. execWAIT_DROP_TAB_CONF(signal);
  2672. tabPtr.i++;
  2673. break;
  2674.       }
  2675.     }
  2676.   }
  2677.   
  2678.   if(tabPtr.i == ctabFileSize){
  2679.     /**
  2680.      * Finished
  2681.      */
  2682.     jam();
  2683.     return;
  2684.   }
  2685.   
  2686.   signal->theData[0] = DihContinueB::CHECK_WAIT_DROP_TAB_FAILED_LQH;
  2687.   signal->theData[1] = nodeId;
  2688.   signal->theData[2] = tabPtr.i;
  2689.   sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
  2690. }
  2691. void
  2692. Dbdih::execNDB_TAMPER(Signal* signal)
  2693. {
  2694.   if ((ERROR_INSERTED(7011)) &&
  2695.       (signal->theData[0] == 7012)) {
  2696.     CLEAR_ERROR_INSERT_VALUE;
  2697.     calculateKeepGciLab(signal, 0, 0);
  2698.     return;
  2699.   }//if
  2700.   SET_ERROR_INSERT_VALUE(signal->theData[0]);
  2701.   return;
  2702. }//Dbdih::execNDB_TAMPER()
  2703. void Dbdih::execSET_VAR_REQ(Signal* signal) {
  2704. #if 0
  2705.   SetVarReq* const setVarReq = (SetVarReq*)&signal->theData[0];
  2706.   ConfigParamId var = setVarReq->variable();
  2707.   int val = setVarReq->value();
  2708.   switch (var) {
  2709.   case TimeBetweenLocalCheckpoints:
  2710.     c_lcpState.clcpDelay = val;
  2711.     sendSignal(CMVMI_REF, GSN_SET_VAR_CONF, signal, 1, JBB);
  2712.     break;
  2713.   case TimeBetweenGlobalCheckpoints:
  2714.     cgcpDelay = val;
  2715.     sendSignal(CMVMI_REF, GSN_SET_VAR_CONF, signal, 1, JBB);
  2716.     break;
  2717.   default:
  2718.     sendSignal(CMVMI_REF, GSN_SET_VAR_REF, signal, 1, JBB);
  2719.   } // switch
  2720. #endif
  2721. }
  2722. void Dbdih::execBLOCK_COMMIT_ORD(Signal* signal){
  2723.   BlockCommitOrd* const block = (BlockCommitOrd *)&signal->theData[0];
  2724.   jamEntry();
  2725. #if 0
  2726.   ndbrequire(c_blockCommit == false || 
  2727.      c_blockCommitNo == block->failNo);
  2728. #else
  2729.   if(!(c_blockCommit == false || c_blockCommitNo == block->failNo)){
  2730.     infoEvent("Possible bug in Dbdih::execBLOCK_COMMIT_ORD c_blockCommit = %d c_blockCommitNo = %d"
  2731.       " sig->failNo = %d", c_blockCommit, c_blockCommitNo, block->failNo);
  2732.   }
  2733. #endif
  2734.   c_blockCommit = true;
  2735.   c_blockCommitNo = block->failNo;
  2736. }
  2737. void Dbdih::execUNBLOCK_COMMIT_ORD(Signal* signal){
  2738.   UnblockCommitOrd* const unblock = (UnblockCommitOrd *)&signal->theData[0];
  2739.   (void)unblock;
  2740.   jamEntry();
  2741.   
  2742.   if(c_blockCommit == true){
  2743.     jam();
  2744.     //    ndbrequire(c_blockCommitNo == unblock->failNo);
  2745.     
  2746.     c_blockCommit = false;
  2747.     emptyverificbuffer(signal, true);
  2748.   }
  2749. }
  2750. void Dbdih::execSTOP_PERM_REQ(Signal* signal){
  2751.   jamEntry();
  2752.   
  2753.   StopPermReq* const req = (StopPermReq*)&signal->theData[0];
  2754.   StopPermRef* const ref = (StopPermRef*)&signal->theData[0];
  2755.   
  2756.   const Uint32 senderData = req->senderData;
  2757.   const BlockReference senderRef = req->senderRef;
  2758.   const NodeId nodeId = refToNode(senderRef);
  2759.   
  2760.   if (isMaster()) {
  2761.     /**
  2762.      * Master
  2763.      */
  2764.     jam();
  2765.     CRASH_INSERTION(7065);
  2766.     if (c_stopPermMaster.clientRef != 0) {
  2767.       jam();
  2768.       ref->senderData = senderData;
  2769.       ref->errorCode  = StopPermRef::NodeShutdownInProgress;
  2770.       sendSignal(senderRef, GSN_STOP_PERM_REF, signal,
  2771.                  StopPermRef::SignalLength, JBB);
  2772.       return;
  2773.     }//if
  2774.     
  2775.     if (c_nodeStartMaster.activeState) {
  2776.       jam();
  2777.       ref->senderData = senderData;
  2778.       ref->errorCode  = StopPermRef::NodeStartInProgress;
  2779.       sendSignal(senderRef, GSN_STOP_PERM_REF, signal,
  2780.                  StopPermRef::SignalLength, JBB);
  2781.       return;
  2782.     }//if
  2783.     
  2784.     /**
  2785.      * Lock
  2786.      */
  2787.     c_nodeStartMaster.activeState = true;
  2788.     c_stopPermMaster.clientRef = senderRef;
  2789.     c_stopPermMaster.clientData = senderData;
  2790.     c_stopPermMaster.returnValue = 0;
  2791.     c_switchReplicas.clear();
  2792.     Mutex mutex(signal, c_mutexMgr, c_switchPrimaryMutexHandle);
  2793.     Callback c = { safe_cast(&Dbdih::switch_primary_stop_node), nodeId };
  2794.     ndbrequire(mutex.lock(c));
  2795.   } else { 
  2796.     /** 
  2797.      * Proxy part
  2798.      */
  2799.     jam();
  2800.     CRASH_INSERTION(7066);
  2801.     if(c_stopPermProxy.clientRef != 0){
  2802.       jam();
  2803.       ref->senderData = senderData;
  2804.       ref->errorCode = StopPermRef::NodeShutdownInProgress;
  2805.       sendSignal(senderRef, GSN_STOP_PERM_REF, signal, 2, JBB);
  2806.       return;
  2807.     }//if
  2808.     
  2809.     c_stopPermProxy.clientRef = senderRef;
  2810.     c_stopPermProxy.masterRef = cmasterdihref;
  2811.     c_stopPermProxy.clientData = senderData;
  2812.     
  2813.     req->senderRef = reference();
  2814.     req->senderData = senderData;
  2815.     sendSignal(cmasterdihref, GSN_STOP_PERM_REQ, signal,
  2816.        StopPermReq::SignalLength, JBB);
  2817.   }//if
  2818. }//Dbdih::execSTOP_PERM_REQ()
  2819. void
  2820. Dbdih::switch_primary_stop_node(Signal* signal, Uint32 node_id, Uint32 ret_val) 
  2821. {
  2822.   ndbrequire(ret_val == 0);
  2823.   signal->theData[0] = DihContinueB::SwitchReplica;
  2824.   signal->theData[1] = node_id;
  2825.   signal->theData[2] = 0; // table id
  2826.   signal->theData[3] = 0; // fragment id
  2827.   sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB);
  2828. }
  2829. void Dbdih::execSTOP_PERM_REF(Signal* signal)
  2830. {
  2831.   jamEntry();
  2832.   ndbrequire(c_stopPermProxy.clientRef != 0);
  2833.   ndbrequire(c_stopPermProxy.masterRef == signal->senderBlockRef());
  2834.   sendSignal(c_stopPermProxy.clientRef, GSN_STOP_PERM_REF, signal, 2, JBB);  
  2835.   c_stopPermProxy.clientRef = 0;
  2836. }//Dbdih::execSTOP_PERM_REF()
  2837. void Dbdih::execSTOP_PERM_CONF(Signal* signal)
  2838. {
  2839.   jamEntry();
  2840.   ndbrequire(c_stopPermProxy.clientRef != 0);
  2841.   ndbrequire(c_stopPermProxy.masterRef == signal->senderBlockRef());
  2842.   sendSignal(c_stopPermProxy.clientRef, GSN_STOP_PERM_CONF, signal, 1, JBB);
  2843.   c_stopPermProxy.clientRef = 0;
  2844. }//Dbdih::execSTOP_PERM_CONF()
  2845. void Dbdih::execDIH_SWITCH_REPLICA_REQ(Signal* signal)
  2846. {
  2847.   jamEntry();
  2848.   DihSwitchReplicaReq* const req = (DihSwitchReplicaReq*)&signal->theData[0];
  2849.   const Uint32 tableId = req->tableId;
  2850.   const Uint32 fragNo = req->fragNo;
  2851.   const BlockReference senderRef = req->senderRef;
  2852.   CRASH_INSERTION(7067);
  2853.   TabRecordPtr tabPtr;
  2854.   tabPtr.i = tableId;
  2855.   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord); 
  2856.   ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_ACTIVE);
  2857.   if (tabPtr.p->tabCopyStatus != TabRecord::CS_IDLE) {
  2858.     jam();
  2859.     sendSignal(reference(), GSN_DIH_SWITCH_REPLICA_REQ, signal, 
  2860.        DihSwitchReplicaReq::SignalLength, JBB);
  2861.     return;
  2862.   }//if
  2863.   FragmentstorePtr fragPtr;
  2864.   getFragstore(tabPtr.p, fragNo, fragPtr);
  2865.   
  2866.   /**
  2867.    * Do funky stuff
  2868.    */
  2869.   Uint32 oldOrder[MAX_REPLICAS];
  2870.   const Uint32 noOfReplicas = extractNodeInfo(fragPtr.p, oldOrder);
  2871.   
  2872.   if (noOfReplicas < req->noOfReplicas) {
  2873.     jam();
  2874.     //---------------------------------------------------------------------
  2875.     // A crash occurred in the middle of our switch handling.
  2876.     //---------------------------------------------------------------------
  2877.     DihSwitchReplicaRef* const ref = (DihSwitchReplicaRef*)&signal->theData[0];
  2878.     ref->senderNode = cownNodeId;
  2879.     ref->errorCode = StopPermRef::NF_CausedAbortOfStopProcedure;
  2880.     sendSignal(senderRef, GSN_DIH_SWITCH_REPLICA_REF, signal,
  2881.                DihSwitchReplicaRef::SignalLength, JBB);
  2882.   }//if
  2883.   for (Uint32 i = 0; i < noOfReplicas; i++) {
  2884.     jam();
  2885.     ndbrequire(i < MAX_REPLICAS);
  2886.     fragPtr.p->activeNodes[i] = req->newNodeOrder[i];
  2887.   }//for
  2888.   /**
  2889.    * Reply
  2890.    */
  2891.   DihSwitchReplicaConf* const conf = (DihSwitchReplicaConf*)&signal->theData[0];
  2892.   conf->senderNode = cownNodeId;
  2893.   sendSignal(senderRef, GSN_DIH_SWITCH_REPLICA_CONF, signal,
  2894.              DihSwitchReplicaConf::SignalLength, JBB);
  2895. }//Dbdih::execDIH_SWITCH_REPLICA_REQ()
  2896. void Dbdih::execDIH_SWITCH_REPLICA_CONF(Signal* signal)
  2897. {
  2898.   jamEntry();
  2899.   /**
  2900.    * Response to master
  2901.    */
  2902.   CRASH_INSERTION(7068);
  2903.   DihSwitchReplicaConf* const conf = (DihSwitchReplicaConf*)&signal->theData[0];
  2904.   switchReplicaReply(signal, conf->senderNode);
  2905. }//Dbdih::execDIH_SWITCH_REPLICA_CONF()
  2906. void Dbdih::execDIH_SWITCH_REPLICA_REF(Signal* signal)
  2907. {
  2908.   jamEntry();
  2909.   DihSwitchReplicaRef* const ref = (DihSwitchReplicaRef*)&signal->theData[0];  
  2910.   if(c_stopPermMaster.returnValue == 0){
  2911.     jam();
  2912.     c_stopPermMaster.returnValue = ref->errorCode;
  2913.   }//if
  2914.   switchReplicaReply(signal, ref->senderNode);
  2915. }//Dbdih::execDIH_SWITCH_REPLICA_REF()
  2916. void Dbdih::switchReplicaReply(Signal* signal, 
  2917.        NodeId nodeId){
  2918.   jam();
  2919.   receiveLoopMacro(DIH_SWITCH_REPLICA_REQ, nodeId);
  2920.   //------------------------------------------------------
  2921.   // We have received all responses from the nodes. Thus
  2922.   // we have completed switching replica roles. Continue
  2923.   // with the next fragment.
  2924.   //------------------------------------------------------
  2925.   if(c_stopPermMaster.returnValue != 0){
  2926.     jam();
  2927.     c_switchReplicas.tableId = ctabFileSize + 1;
  2928.   }//if
  2929.   c_switchReplicas.fragNo++;
  2930.   signal->theData[0] = DihContinueB::SwitchReplica;
  2931.   signal->theData[1] = c_switchReplicas.nodeId;
  2932.   signal->theData[2] = c_switchReplicas.tableId;
  2933.   signal->theData[3] = c_switchReplicas.fragNo;
  2934.   sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB);
  2935. }//Dbdih::switchReplicaReply()
  2936. void
  2937. Dbdih::switchReplica(Signal* signal, 
  2938.      Uint32 nodeId,
  2939.      Uint32 tableId, 
  2940.      Uint32 fragNo){
  2941.   jam();
  2942.   DihSwitchReplicaReq* const req = (DihSwitchReplicaReq*)&signal->theData[0];
  2943.   const Uint32 RT_BREAK = 64;
  2944.   
  2945.   for (Uint32 i = 0; i < RT_BREAK; i++) {
  2946.     jam();
  2947.     if (tableId >= ctabFileSize) {
  2948.       jam();
  2949.       StopPermConf* const conf = (StopPermConf*)&signal->theData[0];
  2950.       StopPermRef*  const ref  = (StopPermRef*)&signal->theData[0];
  2951.       /**
  2952.        * Finished with all tables
  2953.        */
  2954.       if(c_stopPermMaster.returnValue == 0) {
  2955. jam();
  2956. conf->senderData = c_stopPermMaster.clientData;
  2957. sendSignal(c_stopPermMaster.clientRef, GSN_STOP_PERM_CONF, 
  2958.    signal, 1, JBB);
  2959.       } else {
  2960.         jam();
  2961.         ref->senderData = c_stopPermMaster.clientData;
  2962.         ref->errorCode  = c_stopPermMaster.returnValue;
  2963.         sendSignal(c_stopPermMaster.clientRef, GSN_STOP_PERM_REF, signal, 2,JBB);
  2964.       }//if
  2965.       
  2966.       /**
  2967.        * UnLock
  2968.        */
  2969.       c_nodeStartMaster.activeState = false;
  2970.       c_stopPermMaster.clientRef = 0;
  2971.       c_stopPermMaster.clientData = 0;
  2972.       c_stopPermMaster.returnValue = 0;
  2973.       Mutex mutex(signal, c_mutexMgr, c_switchPrimaryMutexHandle);
  2974.       mutex.unlock(); // ignore result
  2975.       return;
  2976.     }//if
  2977.     
  2978.     TabRecordPtr tabPtr;
  2979.     tabPtr.i = tableId;
  2980.     ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);  
  2981.     
  2982.     if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE) {
  2983.       jam();
  2984.       tableId++;
  2985.       fragNo = 0;
  2986.       continue;
  2987.     }//if    
  2988.     if (fragNo >= tabPtr.p->totalfragments) {
  2989.       jam();
  2990.       tableId++;
  2991.       fragNo = 0;
  2992.       continue;
  2993.     }//if    
  2994.     FragmentstorePtr fragPtr;
  2995.     getFragstore(tabPtr.p, fragNo, fragPtr);
  2996.     
  2997.     Uint32 oldOrder[MAX_REPLICAS];
  2998.     const Uint32 noOfReplicas = extractNodeInfo(fragPtr.p, oldOrder);
  2999.     if(oldOrder[0] != nodeId) {
  3000.       jam();
  3001.       fragNo++;
  3002.       continue;
  3003.     }//if    
  3004.     req->tableId = tableId;
  3005.     req->fragNo = fragNo;
  3006.     req->noOfReplicas = noOfReplicas;
  3007.     for (Uint32 i = 0; i < (noOfReplicas - 1); i++) {
  3008.       req->newNodeOrder[i] = oldOrder[i+1];
  3009.     }//for
  3010.     req->newNodeOrder[noOfReplicas-1] = nodeId;
  3011.     req->senderRef = reference();
  3012.     
  3013.     /**
  3014.      * Initialize struct
  3015.      */
  3016.     c_switchReplicas.tableId = tableId;
  3017.     c_switchReplicas.fragNo = fragNo;
  3018.     c_switchReplicas.nodeId = nodeId;
  3019.     sendLoopMacro(DIH_SWITCH_REPLICA_REQ, sendDIH_SWITCH_REPLICA_REQ);
  3020.     return;
  3021.   }//for
  3022.   signal->theData[0] = DihContinueB::SwitchReplica;
  3023.   signal->theData[1] = nodeId;
  3024.   signal->theData[2] = tableId;
  3025.   signal->theData[3] = fragNo;
  3026.   sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB);
  3027. }//Dbdih::switchReplica()
  3028. void Dbdih::execSTOP_ME_REQ(Signal* signal)
  3029. {
  3030.   jamEntry();
  3031.   StopMeReq* const req = (StopMeReq*)&signal->theData[0];
  3032.   const BlockReference senderRef = req->senderRef; 
  3033.   const Uint32 senderData = req->senderData;
  3034.   const Uint32 nodeId = refToNode(senderRef);
  3035.   { 
  3036.     /**
  3037.      * Set node dead (remove from operations)
  3038.      */
  3039.     NodeRecordPtr nodePtr;
  3040.     nodePtr.i = nodeId;
  3041.     ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
  3042.     nodePtr.p->useInTransactions = false;
  3043.   }
  3044.   if (nodeId != getOwnNodeId()) {
  3045.     jam();
  3046.     StopMeConf * const stopMeConf = (StopMeConf *)&signal->theData[0];
  3047.     stopMeConf->senderData = senderData;
  3048.     stopMeConf->senderRef  = reference();
  3049.     sendSignal(senderRef, GSN_STOP_ME_CONF, signal, 
  3050.        StopMeConf::SignalLength, JBB);
  3051.     return;
  3052.   }//if
  3053.   
  3054.   /**
  3055.    * Local signal
  3056.    */
  3057.   jam();
  3058.   ndbrequire(c_stopMe.clientRef == 0);
  3059.   
  3060.   c_stopMe.clientData  = senderData;
  3061.   c_stopMe.clientRef   = senderRef;
  3062.   
  3063.   req->senderData = senderData;
  3064.   req->senderRef  = reference();
  3065.   sendLoopMacro(STOP_ME_REQ, sendSTOP_ME_REQ);
  3066.   /**
  3067.    * Send conf to self
  3068.    */
  3069.   StopMeConf * const stopMeConf = (StopMeConf *)&signal->theData[0];
  3070.   stopMeConf->senderData = senderData;
  3071.   stopMeConf->senderRef  = reference();
  3072.   sendSignal(reference(), GSN_STOP_ME_CONF, signal, 
  3073.      StopMeConf::SignalLength, JBB);
  3074. }//Dbdih::execSTOP_ME_REQ()
  3075. void Dbdih::execSTOP_ME_REF(Signal* signal)
  3076. {
  3077.   ndbrequire(false);
  3078. }
  3079. void Dbdih::execSTOP_ME_CONF(Signal* signal)
  3080. {
  3081.   jamEntry();
  3082.   StopMeConf * const stopMeConf = (StopMeConf *)&signal->theData[0];
  3083.   
  3084.   const Uint32 senderRef  = stopMeConf->senderRef;
  3085.   const Uint32 senderData = stopMeConf->senderData;
  3086.   const Uint32 nodeId     = refToNode(senderRef);
  3087.   ndbrequire(c_stopMe.clientRef != 0);
  3088.   ndbrequire(c_stopMe.clientData == senderData);
  3089.   receiveLoopMacro(STOP_ME_REQ, nodeId);
  3090.   //---------------------------------------------------------
  3091.   // All STOP_ME_REQ have been received. We will send the
  3092.   // confirmation back to the requesting block.
  3093.   //---------------------------------------------------------
  3094.   stopMeConf->senderRef = reference();
  3095.   stopMeConf->senderData = c_stopMe.clientData;
  3096.   sendSignal(c_stopMe.clientRef, GSN_STOP_ME_CONF, signal,
  3097.      StopMeConf::SignalLength, JBB);
  3098.   c_stopMe.clientRef = 0;
  3099. }//Dbdih::execSTOP_ME_CONF()
  3100. void Dbdih::execWAIT_GCP_REQ(Signal* signal)
  3101. {
  3102.   jamEntry();
  3103.   WaitGCPReq* const req = (WaitGCPReq*)&signal->theData[0];
  3104.   WaitGCPRef* const ref = (WaitGCPRef*)&signal->theData[0];
  3105.   WaitGCPConf* const conf = (WaitGCPConf*)&signal->theData[0];
  3106.   const Uint32 senderData = req->senderData;
  3107.   const BlockReference senderRef = req->senderRef;
  3108.   const Uint32 requestType = req->requestType;
  3109.   if(requestType == WaitGCPReq::CurrentGCI) {
  3110.     jam();
  3111.     conf->senderData = senderData;
  3112.     conf->gcp = cnewgcp;
  3113.     sendSignal(senderRef, GSN_WAIT_GCP_CONF, signal, 
  3114.        WaitGCPConf::SignalLength, JBB);
  3115.     return;
  3116.   }//if
  3117.   if(isMaster()) {
  3118.     /**
  3119.      * Master
  3120.      */
  3121.     jam();
  3122.     if((requestType == WaitGCPReq::CompleteIfRunning) &&
  3123.        (cgcpStatus == GCP_READY)) {
  3124.       jam();
  3125.       conf->senderData = senderData;
  3126.       conf->gcp = coldgcp;
  3127.       sendSignal(senderRef, GSN_WAIT_GCP_CONF, signal, 
  3128.  WaitGCPConf::SignalLength, JBB);
  3129.       return;
  3130.     }//if
  3131.     WaitGCPMasterPtr ptr;
  3132.     if(c_waitGCPMasterList.seize(ptr) == false){
  3133.       jam();
  3134.       ref->senderData = senderData;
  3135.       ref->errorCode = WaitGCPRef::NoWaitGCPRecords;
  3136.       sendSignal(senderRef, GSN_WAIT_GCP_REF, signal, 
  3137.  WaitGCPRef::SignalLength, JBB);
  3138.       return;
  3139.     }//if
  3140.     ptr.p->clientRef = senderRef;
  3141.     ptr.p->clientData = senderData;
  3142.     
  3143.     if((requestType == WaitGCPReq::CompleteForceStart) && 
  3144.        (cgcpStatus == GCP_READY)) {
  3145.       jam();
  3146.       cstartGcpNow = true;
  3147.     }//if
  3148.     return;
  3149.   } else { 
  3150.     /** 
  3151.      * Proxy part
  3152.      */
  3153.     jam();
  3154.     WaitGCPProxyPtr ptr;
  3155.     if (c_waitGCPProxyList.seize(ptr) == false) {
  3156.       jam();
  3157.       ref->senderData = senderData;
  3158.       ref->errorCode = WaitGCPRef::NoWaitGCPRecords;
  3159.       sendSignal(senderRef, GSN_WAIT_GCP_REF, signal, 
  3160.  WaitGCPRef::SignalLength, JBB);
  3161.       return;
  3162.     }//if
  3163.     ptr.p->clientRef = senderRef;
  3164.     ptr.p->clientData = senderData;
  3165.     ptr.p->masterRef = cmasterdihref;
  3166.     req->senderData = ptr.i;
  3167.     req->senderRef = reference();
  3168.     req->requestType = requestType;
  3169.     sendSignal(cmasterdihref, GSN_WAIT_GCP_REQ, signal,
  3170.        WaitGCPReq::SignalLength, JBB);
  3171.     return;
  3172.   }//if
  3173. }//Dbdih::execWAIT_GCP_REQ()
  3174. void Dbdih::execWAIT_GCP_REF(Signal* signal)
  3175. {
  3176.   jamEntry();
  3177.   ndbrequire(!isMaster());
  3178.   WaitGCPRef* const ref = (WaitGCPRef*)&signal->theData[0];  
  3179.   
  3180.   const Uint32 proxyPtr = ref->senderData;
  3181.   const Uint32 errorCode = ref->errorCode;
  3182.   
  3183.   WaitGCPProxyPtr ptr;
  3184.   ptr.i = proxyPtr;
  3185.   c_waitGCPProxyList.getPtr(ptr);
  3186.   ref->senderData = ptr.p->clientData;
  3187.   ref->errorCode = errorCode;
  3188.   sendSignal(ptr.p->clientRef, GSN_WAIT_GCP_REF, signal,
  3189.      WaitGCPRef::SignalLength, JBB);
  3190.   c_waitGCPProxyList.release(ptr);
  3191. }//Dbdih::execWAIT_GCP_REF()
  3192. void Dbdih::execWAIT_GCP_CONF(Signal* signal)
  3193. {
  3194.   jamEntry();
  3195.   ndbrequire(!isMaster());  
  3196.   WaitGCPConf* const conf = (WaitGCPConf*)&signal->theData[0];
  3197.   const Uint32 proxyPtr = conf->senderData;
  3198.   const Uint32 gcp = conf->gcp;
  3199.   WaitGCPProxyPtr ptr;
  3200.   ptr.i = proxyPtr;
  3201.   c_waitGCPProxyList.getPtr(ptr);
  3202.   conf->senderData = ptr.p->clientData;
  3203.   conf->gcp = gcp;
  3204.   sendSignal(ptr.p->clientRef, GSN_WAIT_GCP_CONF, signal,
  3205.      WaitGCPConf::SignalLength, JBB);
  3206.   
  3207.   c_waitGCPProxyList.release(ptr);
  3208. }//Dbdih::execWAIT_GCP_CONF()
  3209. void Dbdih::checkWaitGCPProxy(Signal* signal, NodeId failedNodeId)
  3210. {
  3211.   jam();
  3212.   WaitGCPRef* const ref = (WaitGCPRef*)&signal->theData[0];  
  3213.   ref->errorCode = WaitGCPRef::NF_CausedAbortOfProcedure;
  3214.   WaitGCPProxyPtr ptr;
  3215.   c_waitGCPProxyList.first(ptr);
  3216.   while(ptr.i != RNIL) {
  3217.     jam();    
  3218.     const Uint32 i = ptr.i;
  3219.     const Uint32 clientData = ptr.p->clientData;
  3220.     const BlockReference clientRef = ptr.p->clientRef;
  3221.     const BlockReference masterRef = ptr.p->masterRef;
  3222.     
  3223.     c_waitGCPProxyList.next(ptr);    
  3224.     if(refToNode(masterRef) == failedNodeId) {
  3225.       jam();      
  3226.       c_waitGCPProxyList.release(i);
  3227.       ref->senderData = clientData;
  3228.       sendSignal(clientRef, GSN_WAIT_GCP_REF, signal, 
  3229.  WaitGCPRef::SignalLength, JBB);
  3230.     }//if
  3231.   }//while
  3232. }//Dbdih::checkWaitGCPProxy()
  3233. void Dbdih::checkWaitGCPMaster(Signal* signal, NodeId failedNodeId)
  3234. {
  3235.   jam();  
  3236.   WaitGCPMasterPtr ptr;
  3237.   c_waitGCPMasterList.first(ptr);
  3238.   while (ptr.i != RNIL) {
  3239.     jam();
  3240.     const Uint32 i = ptr.i;
  3241.     const NodeId nodeId = refToNode(ptr.p->clientRef);
  3242.     
  3243.     c_waitGCPMasterList.next(ptr);
  3244.     if (nodeId == failedNodeId) {
  3245.       jam()     
  3246. c_waitGCPMasterList.release(i);
  3247.     }//if
  3248.   }//while
  3249. }//Dbdih::checkWaitGCPMaster()
  3250. void Dbdih::emptyWaitGCPMasterQueue(Signal* signal)
  3251. {
  3252.   jam();
  3253.   WaitGCPConf* const conf = (WaitGCPConf*)&signal->theData[0];
  3254.   conf->gcp = coldgcp;
  3255.   
  3256.   WaitGCPMasterPtr ptr;
  3257.   c_waitGCPMasterList.first(ptr);  
  3258.   while(ptr.i != RNIL) {
  3259.     jam();
  3260.     const Uint32 i = ptr.i;
  3261.     const Uint32 clientData = ptr.p->clientData;
  3262.     const BlockReference clientRef = ptr.p->clientRef;
  3263.     c_waitGCPMasterList.next(ptr);    
  3264.     conf->senderData = clientData;
  3265.     sendSignal(clientRef, GSN_WAIT_GCP_CONF, signal,
  3266.        WaitGCPConf::SignalLength, JBB);
  3267.     
  3268.     c_waitGCPMasterList.release(i);
  3269.   }//while
  3270. }//Dbdih::emptyWaitGCPMasterQueue()
  3271. void Dbdih::setNodeStatus(Uint32 nodeId, NodeRecord::NodeStatus newStatus)
  3272. {
  3273.   NodeRecordPtr nodePtr;
  3274.   nodePtr.i = nodeId;
  3275.   ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
  3276.   nodePtr.p->nodeStatus = newStatus;
  3277. }//Dbdih::setNodeStatus()
  3278. Dbdih::NodeRecord::NodeStatus Dbdih::getNodeStatus(Uint32 nodeId)
  3279. {
  3280.   NodeRecordPtr nodePtr;
  3281.   nodePtr.i = nodeId;
  3282.   ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
  3283.   return nodePtr.p->nodeStatus;
  3284. }//Dbdih::getNodeStatus()
  3285. Sysfile::ActiveStatus 
  3286. Dbdih::getNodeActiveStatus(Uint32 nodeId)
  3287. {
  3288.   NodeRecordPtr nodePtr;
  3289.   nodePtr.i = nodeId;
  3290.   ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
  3291.   return nodePtr.p->activeStatus;
  3292. }//Dbdih::getNodeActiveStatus()
  3293. void
  3294. Dbdih::setNodeActiveStatus(Uint32 nodeId, Sysfile::ActiveStatus newStatus)
  3295. {
  3296.   NodeRecordPtr nodePtr;
  3297.   nodePtr.i = nodeId;
  3298.   ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
  3299.   nodePtr.p->activeStatus = newStatus;
  3300. }//Dbdih::setNodeActiveStatus()
  3301. void Dbdih::setAllowNodeStart(Uint32 nodeId, bool newState)
  3302. {
  3303.   NodeRecordPtr nodePtr;
  3304.   nodePtr.i = nodeId;
  3305.   ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
  3306.   nodePtr.p->allowNodeStart = newState;
  3307. }//Dbdih::setAllowNodeStart()
  3308. void Dbdih::setNodeCopyCompleted(Uint32 nodeId, bool newState)
  3309. {
  3310.   NodeRecordPtr nodePtr;
  3311.   nodePtr.i = nodeId;
  3312.   ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
  3313.   nodePtr.p->copyCompleted = newState;
  3314. }//Dbdih::setNodeCopyCompleted()
  3315. bool Dbdih::getAllowNodeStart(Uint32 nodeId)
  3316. {
  3317.   NodeRecordPtr nodePtr;
  3318.   nodePtr.i = nodeId;
  3319.   ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
  3320.   return nodePtr.p->allowNodeStart;
  3321. }//Dbdih::getAllowNodeStart()
  3322. bool Dbdih::getNodeCopyCompleted(Uint32 nodeId)
  3323. {
  3324.   NodeRecordPtr nodePtr;
  3325.   nodePtr.i = nodeId;
  3326.   ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
  3327.   return nodePtr.p->copyCompleted;
  3328. }//Dbdih::getNodeCopyCompleted()
  3329. bool Dbdih::checkNodeAlive(Uint32 nodeId)
  3330. {
  3331.   NodeRecordPtr nodePtr;
  3332.   nodePtr.i = nodeId;
  3333.   ndbrequire(nodeId > 0);
  3334.   ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
  3335.   if (nodePtr.p->nodeStatus != NodeRecord::ALIVE) {
  3336.     return false;
  3337.   } else {
  3338.     return true;
  3339.   }//if
  3340. }//Dbdih::checkNodeAlive()
  3341. bool Dbdih::isMaster()
  3342. {
  3343.   return (reference() == cmasterdihref);
  3344. }//Dbdih::isMaster()
  3345. bool Dbdih::isActiveMaster()
  3346. {
  3347.   return ((reference() == cmasterdihref) && (cmasterState == MASTER_ACTIVE));
  3348. }//Dbdih::isActiveMaster()
  3349. Dbdih::NodeRecord::NodeRecord(){
  3350.   m_nodefailSteps.clear();
  3351.   gcpstate = NodeRecord::READY;
  3352.   activeStatus = Sysfile::NS_NotDefined;
  3353.   recNODE_FAILREP = ZFALSE;
  3354.   nodeGroup = ZNIL;
  3355.   dbtcFailCompleted = ZTRUE;
  3356.   dbdictFailCompleted = ZTRUE;
  3357.   dbdihFailCompleted = ZTRUE;
  3358.   dblqhFailCompleted = ZTRUE;
  3359.   noOfStartedChkpt = 0;
  3360.   noOfQueuedChkpt = 0;
  3361.   lcpStateAtTakeOver = (MasterLCPConf::State)255;
  3362.   activeTabptr = RNIL;
  3363.   nodeStatus = NodeRecord::NOT_IN_CLUSTER;
  3364.   useInTransactions = false;
  3365.   copyCompleted = false;
  3366.   allowNodeStart = true;
  3367. }