MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:tomas Date:February 14 2007 4:40am
Subject:bk commit into 5.1 tree (tomas:1.2415)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of tomas. When tomas does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.2415 07/02/14 11:40:37 tomas@stripped +9 -0
  Merge poseidon.mysql.com:/home/tomas/mysql-5.0-telco-gca
  into  poseidon.mysql.com:/home/tomas/mysql-5.1-telco-6.1_2

  storage/ndb/src/ndbapi/SignalSender.cpp
    1.12 07/02/14 11:40:29 tomas@stripped +0 -2
    manual merge

  storage/ndb/src/ndbapi/ClusterMgr.cpp
    1.37 07/02/14 11:40:29 tomas@stripped +0 -0
    manual merge

  storage/ndb/src/mgmsrv/MgmtSrvr.cpp
    1.119 07/02/14 11:40:29 tomas@stripped +0 -1
    manual merge

  storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
    1.102 07/02/14 11:40:29 tomas@stripped +2 -4
    manual merge

  storage/ndb/include/kernel/signaldata/DumpStateOrd.hpp
    1.16 07/02/14 11:40:29 tomas@stripped +0 -1
    manual merge

  storage/ndb/src/ndbapi/SignalSender.hpp
    1.4 07/02/14 11:32:11 tomas@stripped +0 -0
    Auto merged

  storage/ndb/src/ndbapi/ClusterMgr.hpp
    1.17 07/02/14 11:32:11 tomas@stripped +0 -0
    Auto merged

  storage/ndb/src/kernel/vm/WatchDog.cpp
    1.7 07/02/14 11:32:10 tomas@stripped +0 -0
    Auto merged

  storage/ndb/src/ndbapi/SignalSender.hpp
    1.1.2.2 07/02/14 11:32:10 tomas@stripped +0 -0
    Merge rename: ndb/src/ndbapi/SignalSender.hpp -> storage/ndb/src/ndbapi/SignalSender.hpp

  storage/ndb/src/ndbapi/SignalSender.cpp
    1.3.6.2 07/02/14 11:32:10 tomas@stripped +0 -0
    Merge rename: ndb/src/ndbapi/SignalSender.cpp -> storage/ndb/src/ndbapi/SignalSender.cpp

  storage/ndb/src/ndbapi/ClusterMgr.hpp
    1.4.8.2 07/02/14 11:32:10 tomas@stripped +0 -0
    Merge rename: ndb/src/ndbapi/ClusterMgr.hpp -> storage/ndb/src/ndbapi/ClusterMgr.hpp

  storage/ndb/src/ndbapi/ClusterMgr.cpp
    1.17.11.2 07/02/14 11:32:10 tomas@stripped +0 -0
    Merge rename: ndb/src/ndbapi/ClusterMgr.cpp -> storage/ndb/src/ndbapi/ClusterMgr.cpp

  storage/ndb/src/mgmsrv/MgmtSrvr.cpp
    1.73.44.2 07/02/14 11:32:10 tomas@stripped +0 -0
    Merge rename: ndb/src/mgmsrv/MgmtSrvr.cpp -> storage/ndb/src/mgmsrv/MgmtSrvr.cpp

  storage/ndb/src/kernel/vm/WatchDog.cpp
    1.3.3.2 07/02/14 11:32:10 tomas@stripped +0 -0
    Merge rename: ndb/src/kernel/vm/WatchDog.cpp -> storage/ndb/src/kernel/vm/WatchDog.cpp

  storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
    1.24.65.2 07/02/14 11:32:10 tomas@stripped +0 -0
    Merge rename: ndb/src/kernel/blocks/dbdih/DbdihMain.cpp -> storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp

  storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp
    1.43 07/02/14 11:32:10 tomas@stripped +0 -0
    Auto merged

  storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp
    1.18.16.2 07/02/14 11:32:09 tomas@stripped +0 -0
    Merge rename: ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp -> storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp

  storage/ndb/include/kernel/signaldata/DumpStateOrd.hpp
    1.3.9.2 07/02/14 11:32:09 tomas@stripped +0 -0
    Merge rename: ndb/include/kernel/signaldata/DumpStateOrd.hpp -> storage/ndb/include/kernel/signaldata/DumpStateOrd.hpp

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	tomas
# Host:	poseidon.mysql.com
# Root:	/home/tomas/mysql-5.1-telco-6.1_2/RESYNC

--- 1.3.9.1/ndb/include/kernel/signaldata/DumpStateOrd.hpp	2007-02-14 11:05:31 +07:00
+++ 1.16/storage/ndb/include/kernel/signaldata/DumpStateOrd.hpp	2007-02-14 11:40:29 +07:00
@@ -111,6 +111,7 @@ public:
                                       to be able to debug if events
                                       for some reason does not end up
                                       in clusterlog */
+    LCPContinue = 5900,
     // 7000 DIH
     // 7001 DIH
     // 7002 DIH
@@ -141,7 +142,11 @@ public:
     // 12000 Tux
     TuxLogToFile = 12001,
     TuxSetLogFlags = 12002,
-    TuxMetaDataJunk = 12009
+    TuxMetaDataJunk = 12009,
+    
+    DumpTsman = 9800, 
+    DumpLgman = 10000,
+    DumpPgman = 11000
   };
 public:
   

--- 1.18.16.1/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp	2007-02-14 11:05:31 +07:00
+++ 1.43/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp	2007-02-14 11:32:10 +07:00
@@ -46,22 +46,23 @@
 EventLogger g_eventLogger;
 extern int simulate_error_during_shutdown;
 
-Cmvmi::Cmvmi(const Configuration & conf) :
-  SimulatedBlock(CMVMI, conf)
-  ,theConfig((Configuration&)conf)
+Cmvmi::Cmvmi(Block_context& ctx) :
+  SimulatedBlock(CMVMI, ctx)
   ,subscribers(subscriberPool)
 {
   BLOCK_CONSTRUCTOR(Cmvmi);
 
   Uint32 long_sig_buffer_size;
-  const ndb_mgm_configuration_iterator * p = conf.getOwnConfigIterator();
+  const ndb_mgm_configuration_iterator * p = 
+    m_ctx.m_config.getOwnConfigIterator();
   ndbrequire(p != 0);
 
   ndb_mgm_get_int_parameter(p, CFG_DB_LONG_SIGNAL_BUFFER,  
 			    &long_sig_buffer_size);
 
   long_sig_buffer_size= long_sig_buffer_size / 256;
-  g_sectionSegmentPool.setSize(long_sig_buffer_size);
+  g_sectionSegmentPool.setSize(long_sig_buffer_size,
+                               false,true,true,CFG_DB_LONG_SIGNAL_BUFFER);
 
   // Add received signals
   addRecSignal(GSN_CONNECT_REP, &Cmvmi::execCONNECT_REP);
@@ -93,8 +94,8 @@ Cmvmi::Cmvmi(const Configuration & conf)
   addRecSignal(GSN_NODE_START_REP, &Cmvmi::execNODE_START_REP, true);
   
   subscriberPool.setSize(5);
-
-  const ndb_mgm_configuration_iterator * db = theConfig.getOwnConfigIterator();
+  
+  const ndb_mgm_configuration_iterator * db = m_ctx.m_config.getOwnConfigIterator();
   for(unsigned j = 0; j<LogLevel::LOGLEVEL_CATEGORIES; j++){
     Uint32 logLevel;
     if(!ndb_mgm_get_int_parameter(db, CFG_MIN_LOGLEVEL+j, &logLevel)){
@@ -103,7 +104,7 @@ Cmvmi::Cmvmi(const Configuration & conf)
     }
   }
   
-  ndb_mgm_configuration_iterator * iter = theConfig.getClusterConfigIterator();
+  ndb_mgm_configuration_iterator * iter = m_ctx.m_config.getClusterConfigIterator();
   for(ndb_mgm_first(iter); ndb_mgm_valid(iter); ndb_mgm_next(iter)){
     jam();
     Uint32 nodeId;
@@ -118,7 +119,6 @@ Cmvmi::Cmvmi(const Configuration & conf)
       break;
     case NodeInfo::API:
     case NodeInfo::MGM:
-    case NodeInfo::REP:
       break;
     default:
       ndbrequire(false);
@@ -128,10 +128,12 @@ Cmvmi::Cmvmi(const Configuration & conf)
 
   setNodeInfo(getOwnNodeId()).m_connected = true;
   setNodeInfo(getOwnNodeId()).m_version = ndbGetOwnVersion();
+  setNodeInfo(getOwnNodeId()).m_mysql_version = NDB_MYSQL_VERSION_D;
 }
 
 Cmvmi::~Cmvmi()
 {
+  m_shared_page_pool.clear();
 }
 
 #ifdef ERROR_INSERT
@@ -226,8 +228,9 @@ void Cmvmi::execEVENT_REP(Signal* signal
   }
 
   // Print the event info
-  g_eventLogger.log(eventReport->getEventType(), signal->theData);
-
+  g_eventLogger.log(eventReport->getEventType(), 
+		    signal->theData, signal->getLength(), 0, 0);
+  
   return;
 }//execEVENT_REP()
 
@@ -323,9 +326,35 @@ Cmvmi::execREAD_CONFIG_REQ(Signal* signa
   Uint32 senderData = req->senderData;
 
   const ndb_mgm_configuration_iterator * p = 
-    theConfiguration.getOwnConfigIterator();
+    m_ctx.m_config.getOwnConfigIterator();
   ndbrequire(p != 0);
 
+  Uint64 page_buffer = 64*1024*1024;
+  ndb_mgm_get_int64_parameter(p, CFG_DB_DISK_PAGE_BUFFER_MEMORY, &page_buffer);
+  
+  Uint32 pages = 0;
+  pages += page_buffer / GLOBAL_PAGE_SIZE; // in pages
+  pages += LCP_RESTORE_BUFFER;
+  m_global_page_pool.setSize(pages + 64, true);
+  
+  Uint64 shared_mem = 8*1024*1024;
+  ndb_mgm_get_int64_parameter(p, CFG_DB_SGA, &shared_mem);
+  shared_mem /= GLOBAL_PAGE_SIZE;
+  if (shared_mem)
+  {
+    Resource_limit rl;
+    rl.m_min = 0;
+    rl.m_max = shared_mem;
+    rl.m_resource_id = 0;
+    m_ctx.m_mm.set_resource_limit(rl);
+  }
+  
+  ndbrequire(m_ctx.m_mm.init());
+  {
+    void* ptr = m_ctx.m_mm.get_memroot();
+    m_shared_page_pool.set((GlobalPage*)ptr, ~0);
+  }
+  
   ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
   conf->senderRef = reference();
   conf->senderData = senderData;
@@ -341,7 +370,7 @@ void Cmvmi::execSTTOR(Signal* signal)
   if (theStartPhase == 1){
     jam();
 
-    if(theConfig.lockPagesInMainMemory() == 1)
+    if(m_ctx.m_config.lockPagesInMainMemory() == 1)
     {
       int res = NdbMem_MemLockAll(0);
       if(res != 0){
@@ -364,10 +393,6 @@ void Cmvmi::execSTTOR(Signal* signal)
     signal->theData[1] = 0; // no id
     signal->theData[2] = NodeInfo::API;
     execOPEN_COMREQ(signal);
-    signal->theData[0] = 0; // no answer
-    signal->theData[1] = 0; // no id
-    signal->theData[2] = NodeInfo::REP;
-    execOPEN_COMREQ(signal);    
     globalData.theStartLevel = NodeState::SL_STARTED;
     sendSTTORRY(signal);
   }
@@ -481,8 +506,9 @@ void Cmvmi::execENABLE_COMORD(Signal* si
   signal->theData[0] = NDB_LE_ConnectedApiVersion;
   signal->theData[1] = tStartingNode;
   signal->theData[2] = getNodeInfo(tStartingNode).m_version;
-
-  sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
+  signal->theData[3] = getNodeInfo(tStartingNode).m_mysql_version;
+  
+  sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 4, JBB);
   //-----------------------------------------------------
   
   jamEntry();
@@ -532,7 +558,7 @@ void Cmvmi::execCONNECT_REP(Signal *sign
   const NodeInfo::NodeType type = (NodeInfo::NodeType)getNodeInfo(hostId).m_type;
   ndbrequire(type != NodeInfo::INVALID);
   globalData.m_nodeInfo[hostId].m_version = 0;
-  globalData.m_nodeInfo[hostId].m_signalVersion = 0;
+  globalData.m_nodeInfo[hostId].m_mysql_version = 0;
   
   if(type == NodeInfo::DB || globalData.theStartLevel >= NodeState::SL_STARTED){
     jam();
@@ -555,6 +581,7 @@ void Cmvmi::execCONNECT_REP(Signal *sign
       /**
        * Dont allow api nodes to connect
        */
+      ndbout_c("%d %d %d", hostId, type, globalData.theStartLevel);
       abort();
       globalTransporterRegistry.do_disconnect(hostId);
     }
@@ -789,7 +816,7 @@ Cmvmi::execSTART_ORD(Signal* signal) {
   if(globalData.theStartLevel == NodeState::SL_CMVMI){
     jam();
 
-    if(theConfig.lockPagesInMainMemory() == 2)
+    if(m_ctx.m_config.lockPagesInMainMemory() == 2)
     {
       int res = NdbMem_MemLockAll(1);
       if(res != 0)
@@ -964,7 +991,7 @@ void Cmvmi::handleSET_VAR_REQ(Signal* si
 
   switch (var) {
   case MaxNoOfSavedMessages:
-    theConfig.maxNoOfErrorLogs(val);
+    m_ctx.m_config.maxNoOfErrorLogs(val);
     sendSignal(CMVMI_REF, GSN_SET_VAR_CONF, signal, 1, JBB);
     break;
     
@@ -985,12 +1012,12 @@ void Cmvmi::handleSET_VAR_REQ(Signal* si
     break;
 
   case TimeBetweenWatchDogCheck:
-    theConfig.timeBetweenWatchDogCheck(val);
+    m_ctx.m_config.timeBetweenWatchDogCheck(val);
     sendSignal(CMVMI_REF, GSN_SET_VAR_CONF, signal, 1, JBB);
     break;
 
   case StopOnError:
-    theConfig.stopOnError(val);
+    m_ctx.m_config.stopOnError(val);
     sendSignal(CMVMI_REF, GSN_SET_VAR_CONF, signal, 1, JBB);
     break;
     
@@ -1050,6 +1077,9 @@ Cmvmi::execDUMP_STATE_ORD(Signal* signal
   sendSignal(SUMA_REF, GSN_DUMP_STATE_ORD,    signal, signal->length(), JBB);
   sendSignal(TRIX_REF, GSN_DUMP_STATE_ORD,    signal, signal->length(), JBB);
   sendSignal(DBTUX_REF, GSN_DUMP_STATE_ORD,   signal, signal->length(), JBB);
+  sendSignal(LGMAN_REF, GSN_DUMP_STATE_ORD,   signal, signal->length(), JBB);
+  sendSignal(TSMAN_REF, GSN_DUMP_STATE_ORD,   signal, signal->length(), JBB);
+  sendSignal(PGMAN_REF, GSN_DUMP_STATE_ORD,   signal, signal->length(), JBB);
   
   /**
    *
@@ -1085,9 +1115,6 @@ Cmvmi::execDUMP_STATE_ORD(Signal* signal
       case NodeInfo::MGM:
 	nodeTypeStr = "MGM";
 	break;
-      case NodeInfo::REP:
-	nodeTypeStr = "REP";
-	break;
       case NodeInfo::INVALID:
 	nodeTypeStr = 0;
 	break;
@@ -1128,6 +1155,37 @@ Cmvmi::execDUMP_STATE_ORD(Signal* signal
 	      g_sectionSegmentPool.getSize(),
 	      g_sectionSegmentPool.getNoOfFree());
   }
+
+  if (dumpState->args[0] == 1000)
+  {
+    Uint32 len = signal->getLength();
+    if (signal->getLength() == 1)
+    {
+      signal->theData[1] = 0;
+      signal->theData[2] = ~0;
+      sendSignal(reference(), GSN_DUMP_STATE_ORD, signal, 3, JBB);
+      return;
+    }
+    Uint32 id = signal->theData[1];
+    Resource_limit rl;
+    if (!m_ctx.m_mm.get_resource_limit(id, rl))
+      len = 2;
+    else
+    {
+      if (rl.m_min || rl.m_curr || rl.m_max)
+	infoEvent("Resource %d min: %d max: %d curr: %d",
+		  id, rl.m_min, rl.m_max, rl.m_curr);
+    }
+
+    if (len == 3)
+    {
+      signal->theData[0] = 1000;
+      signal->theData[1] = id+1;
+      signal->theData[2] = ~0;
+      sendSignal(reference(), GSN_DUMP_STATE_ORD, signal, 3, JBB);
+    }
+    return;
+  }
   
   if (arg == DumpStateOrd::CmvmiSetRestartOnErrorInsert)
   {
@@ -1135,17 +1193,17 @@ Cmvmi::execDUMP_STATE_ORD(Signal* signal
     {
       Uint32 val = (Uint32)NRT_NoStart_Restart;
       const ndb_mgm_configuration_iterator * p = 
-	theConfig.getOwnConfigIterator();
+	m_ctx.m_config.getOwnConfigIterator();
       ndbrequire(p != 0);
       
       if(!ndb_mgm_get_int_parameter(p, CFG_DB_STOP_ON_ERROR_INSERT, &val))
       {
-	theConfig.setRestartOnErrorInsert(val);
+        m_ctx.m_config.setRestartOnErrorInsert(val);
       }
     }
     else
     {
-      theConfig.setRestartOnErrorInsert(signal->theData[1]);
+      m_ctx.m_config.setRestartOnErrorInsert(signal->theData[1]);
     }
   }
 
@@ -1188,13 +1246,16 @@ Cmvmi::execDUMP_STATE_ORD(Signal* signal
   if (arg == 9001)
   {
     CLEAR_ERROR_INSERT_VALUE;
-    for (Uint32 i = 0; i<MAX_NODES; i++)
+    if (signal->getLength() == 1 || signal->theData[1])
     {
-      if (c_error_9000_nodes_mask.get(i))
+      for (Uint32 i = 0; i<MAX_NODES; i++)
       {
-	signal->theData[0] = 0;
-	signal->theData[1] = i;
-	EXECUTE_DIRECT(CMVMI, GSN_OPEN_COMREQ, signal, 2);
+	if (c_error_9000_nodes_mask.get(i))
+	{
+	  signal->theData[0] = 0;
+	  signal->theData[1] = i;
+	  EXECUTE_DIRECT(CMVMI, GSN_OPEN_COMREQ, signal, 2);
+	}
       }
     }
     c_error_9000_nodes_mask.clear();
@@ -1279,7 +1340,7 @@ Cmvmi::execTESTSIG(Signal* signal){
     fprintf(stdout, "\n");
     
     for(i = 0; i<signal->header.m_noOfSections; i++){
-      SegmentedSectionPtr ptr = {0,0,0};
+      SegmentedSectionPtr ptr;
       ndbout_c("-- Section %d --", i);
       signal->getSection(ptr, i);
       ndbrequire(ptr.p != 0);
@@ -1337,7 +1398,7 @@ Cmvmi::execTESTSIG(Signal* signal){
     LinearSectionPtr ptr[3];
     const Uint32 secs = signal->getNoOfSections();
     for(i = 0; i<secs; i++){
-      SegmentedSectionPtr sptr = {0,0,0};
+      SegmentedSectionPtr sptr;
       signal->getSection(sptr, i);
       ptr[i].sz = sptr.sz;
       ptr[i].p = new Uint32[sptr.sz];
@@ -1386,7 +1447,7 @@ Cmvmi::execTESTSIG(Signal* signal){
     LinearSectionPtr ptr[3];
     const Uint32 secs = signal->getNoOfSections();
     for(i = 0; i<secs; i++){
-      SegmentedSectionPtr sptr = {0,0,0};
+      SegmentedSectionPtr sptr;
       signal->getSection(sptr, i);
       ptr[i].sz = sptr.sz;
       ptr[i].p = new Uint32[sptr.sz];
@@ -1452,7 +1513,7 @@ Cmvmi::execTESTSIG(Signal* signal){
     const Uint32 secs = signal->getNoOfSections();
     memset(g_test, 0, sizeof(g_test));
     for(i = 0; i<secs; i++){
-      SegmentedSectionPtr sptr  = {0,0,0};
+      SegmentedSectionPtr sptr;
       signal->getSection(sptr, i);
       g_test[i].sz = sptr.sz;
       g_test[i].p = new Uint32[sptr.sz];

--- 1.24.65.1/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp	2007-02-14 11:16:04 +07:00
+++ 1.102/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp	2007-02-14 11:40:29 +07:00
@@ -66,6 +66,7 @@
 #include <signaldata/CreateFragmentation.hpp>
 #include <signaldata/LqhFrag.hpp>
 #include <signaldata/FsOpenReq.hpp>
+#include <signaldata/DihFragCount.hpp>
 #include <signaldata/DictLock.hpp>
 #include <DebuggerNames.hpp>
 
@@ -609,6 +610,14 @@ void Dbdih::execCONTINUEB(Signal* signal
     checkWaitDropTabFailedLqh(signal, nodeId, tableId);
     return;
   }
+  case DihContinueB::ZTO_START_FRAGMENTS:
+  {
+    TakeOverRecordPtr takeOverPtr;
+    takeOverPtr.i = signal->theData[1];
+    ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
+    nr_start_fragments(signal, takeOverPtr);
+    return;
+  }
   }//switch
   
   ndbrequire(false);
@@ -665,7 +674,9 @@ done:  
   if (cmasterdihref != reference())
   {
     jam();
+    Uint32 tmp= SYSFILE->m_restart_seq;
     memcpy(sysfileData, cdata, sizeof(sysfileData));
+    SYSFILE->m_restart_seq = tmp;
   }
 
   c_copyGCISlave.m_copyReason = reason;
@@ -1078,7 +1089,7 @@ void Dbdih::execREAD_CONFIG_REQ(Signal* 
   jamEntry();
 
   const ndb_mgm_configuration_iterator * p = 
-    theConfiguration.getOwnConfigIterator();
+    m_ctx.m_config.getOwnConfigIterator();
   ndbrequireErr(p != 0, NDBD_EXIT_INVALID_CONFIG);
 
   initData();
@@ -1121,6 +1132,26 @@ void Dbdih::execSTART_FRAGCONF(Signal* s
   return;
 }//Dbdih::execSTART_FRAGCONF()
 
+void Dbdih::execSTART_FRAGREF(Signal* signal) 
+{
+  jamEntry();
+ 
+  /**
+   * Kill starting node
+   */
+  Uint32 errCode = signal->theData[1];
+  Uint32 nodeId = signal->theData[2];
+  
+  SystemError * const sysErr = (SystemError*)&signal->theData[0];
+  sysErr->errorCode = SystemError::StartFragRefError;
+  sysErr->errorRef = reference();
+  sysErr->data1 = errCode;
+  sysErr->data2 = 0;
+  sendSignal(calcNdbCntrBlockRef(nodeId), GSN_SYSTEM_ERROR, signal, 
+	     SystemError::SignalLength, JBB);
+  return;
+}//Dbdih::execSTART_FRAGCONF()
+
 void Dbdih::execSTART_MEREF(Signal* signal) 
 {
   jamEntry();
@@ -1164,7 +1195,7 @@ void Dbdih::execDIH_RESTARTREQ(Signal* s
 {
   jamEntry();
   cntrlblockref = signal->theData[0];
-  if(theConfiguration.getInitialStart()){
+  if(m_ctx.m_config.getInitialStart()){
     sendSignal(cntrlblockref, GSN_DIH_RESTARTREF, signal, 1, JBB);
   } else {
     readGciFileLab(signal);
@@ -1523,7 +1554,7 @@ void Dbdih::execREAD_NODESCONF(Signal* s
     if(tmp.get(i)){
       jam();
       nodeArray[index] = i;
-      if(NodeBitmask::get(readNodes->inactiveNodes, i) == false){
+      if(NdbNodeBitmask::get(readNodes->inactiveNodes, i) == false){
         jam();
         con_lineNodes++;        
       }//if      
@@ -1733,12 +1764,15 @@ void Dbdih::execSTART_MECONF(Signal* sig
    *
    * But dont copy lastCompletedGCI:s
    */
+  Uint32 key = SYSFILE->m_restart_seq;
   Uint32 tempGCP[MAX_NDB_NODES];
   for(i = 0; i < MAX_NDB_NODES; i++)
     tempGCP[i] = SYSFILE->lastCompletedGCI[i];
 
   for(i = 0; i < Sysfile::SYSFILE_SIZE32; i++)
     sysfileData[i] = cdata[i];
+
+  SYSFILE->m_restart_seq = key;
   for(i = 0; i < MAX_NDB_NODES; i++)
     SYSFILE->lastCompletedGCI[i] = tempGCP[i];
 
@@ -1896,11 +1930,6 @@ void Dbdih::execSTART_MEREQ(Signal* sign
   ndbrequire(c_nodeStartMaster.startNode == Tnodeid);
   ndbrequire(getNodeStatus(Tnodeid) == NodeRecord::STARTING);
   
-  sendSTART_RECREQ(signal, Tnodeid);
-}//Dbdih::execSTART_MEREQ()
-
-void Dbdih::nodeRestartStartRecConfLab(Signal* signal) 
-{
   c_nodeStartMaster.blockLcp = true;
   if ((c_lcpState.lcpStatus != LCP_STATUS_IDLE) &&
       (c_lcpState.lcpStatus != LCP_TCGET)) {
@@ -2047,6 +2076,9 @@ void Dbdih::execINCL_NODECONF(Signal* si
     signal->theData[0] = reference();
     signal->theData[1] = c_nodeStartSlave.nodeId;
     sendSignal(BACKUP_REF, GSN_INCL_NODEREQ, signal, 2, JBB);
+    
+    // Suma will not send response to this for now, later...
+    sendSignal(SUMA_REF, GSN_INCL_NODEREQ, signal, 2, JBB);
     return;
   }//if
   if (TstartNode_or_blockref == numberToRef(BACKUP, getOwnNodeId())){
@@ -2723,13 +2755,14 @@ void Dbdih::sendStartTo(Signal* signal, 
     return;
   }//if
   c_startToLock = takeOverPtrI;
+
+  takeOverPtr.p->toMasterStatus = TakeOverRecord::STARTING;
   StartToReq * const req = (StartToReq *)&signal->theData[0];
   req->userPtr = takeOverPtr.i;
   req->userRef = reference();
   req->startingNodeId = takeOverPtr.p->toStartingNode;
   req->nodeTakenOver = takeOverPtr.p->toFailedNode;
   req->nodeRestart = takeOverPtr.p->toNodeRestart;
-  takeOverPtr.p->toMasterStatus = TakeOverRecord::STARTING;
   sendLoopMacro(START_TOREQ, sendSTART_TOREQ);
 }//Dbdih::sendStartTo()
 
@@ -2773,9 +2806,166 @@ void Dbdih::execSTART_TOCONF(Signal* sig
   CRASH_INSERTION(7134);
   c_startToLock = RNIL;
 
+  if (takeOverPtr.p->toNodeRestart)
+  {
+    jam();
+    takeOverPtr.p->toMasterStatus = TakeOverRecord::STARTING_LOCAL_FRAGMENTS;
+    nr_start_fragments(signal, takeOverPtr);
+    return;
+  }
+
   startNextCopyFragment(signal, takeOverPtr.i);
 }//Dbdih::execSTART_TOCONF()
 
+void
+Dbdih::nr_start_fragments(Signal* signal, 
+			  TakeOverRecordPtr takeOverPtr)
+{
+  Uint32 loopCount = 0 ;
+  TabRecordPtr tabPtr;
+  while (loopCount++ < 100) {
+    tabPtr.i = takeOverPtr.p->toCurrentTabref;
+    if (tabPtr.i >= ctabFileSize) {
+      jam();
+      nr_run_redo(signal, takeOverPtr);
+      return;
+    }//if
+    ptrAss(tabPtr, tabRecord);
+    if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE ||
+	tabPtr.p->tabStorage != TabRecord::ST_NORMAL)
+    {
+      jam();
+      takeOverPtr.p->toCurrentFragid = 0;
+      takeOverPtr.p->toCurrentTabref++;
+      continue;
+    }//if
+    Uint32 fragId = takeOverPtr.p->toCurrentFragid;
+    if (fragId >= tabPtr.p->totalfragments) {
+      jam();
+      takeOverPtr.p->toCurrentFragid = 0;
+      takeOverPtr.p->toCurrentTabref++;
+      continue;
+    }//if
+    FragmentstorePtr fragPtr;
+    getFragstore(tabPtr.p, fragId, fragPtr);
+    ReplicaRecordPtr loopReplicaPtr;
+    loopReplicaPtr.i = fragPtr.p->oldStoredReplicas;
+    while (loopReplicaPtr.i != RNIL) {
+      ptrCheckGuard(loopReplicaPtr, creplicaFileSize, replicaRecord);
+      if (loopReplicaPtr.p->procNode == takeOverPtr.p->toStartingNode) {
+        jam();
+	nr_start_fragment(signal, takeOverPtr, loopReplicaPtr);
+	break;
+      } else {
+        jam();
+        loopReplicaPtr.i = loopReplicaPtr.p->nextReplica;
+      }//if
+    }//while
+    takeOverPtr.p->toCurrentFragid++;
+  }//while
+  signal->theData[0] = DihContinueB::ZTO_START_FRAGMENTS;
+  signal->theData[1] = takeOverPtr.i;
+  sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
+}
+
+void
+Dbdih::nr_start_fragment(Signal* signal, 
+			 TakeOverRecordPtr takeOverPtr,
+			 ReplicaRecordPtr replicaPtr)
+{
+  Uint32 i, j = 0;
+  Uint32 maxLcpId = 0;
+  Uint32 maxLcpIndex = ~0;
+  
+  Uint32 restorableGCI = 0;
+  
+  ndbout_c("tab: %d frag: %d replicaP->nextLcp: %d",
+	   takeOverPtr.p->toCurrentTabref,
+	   takeOverPtr.p->toCurrentFragid,
+	   replicaPtr.p->nextLcp);
+  
+  Uint32 idx = replicaPtr.p->nextLcp;
+  for(i = 0; i<MAX_LCP_STORED; i++, idx = nextLcpNo(idx))
+  {
+    ndbout_c("scanning idx: %d lcpId: %d", idx, replicaPtr.p->lcpId[idx]);
+    if (replicaPtr.p->lcpStatus[idx] == ZVALID) 
+    {
+      ndbrequire(replicaPtr.p->lcpId[idx] > maxLcpId);
+      Uint32 startGci = replicaPtr.p->maxGciCompleted[idx];
+      Uint32 stopGci = replicaPtr.p->maxGciStarted[idx];
+      for (;j < replicaPtr.p->noCrashedReplicas; j++)
+      {
+	ndbout_c("crashed replica: %d(%d) replicaLastGci: %d",
+		 j, 
+		 replicaPtr.p->noCrashedReplicas,
+		 replicaPtr.p->replicaLastGci[j]);
+	if (replicaPtr.p->replicaLastGci[j] > stopGci)
+	{
+	  maxLcpId = replicaPtr.p->lcpId[idx];
+	  maxLcpIndex = idx;
+	  restorableGCI = replicaPtr.p->replicaLastGci[j];
+	  break;
+	}
+      }
+    }
+  }
+  
+  if (maxLcpIndex == ~ (Uint32) 0)
+  {
+    ndbout_c("Didnt find any LCP for node: %d tab: %d frag: %d",
+	     takeOverPtr.p->toStartingNode,
+	     takeOverPtr.p->toCurrentTabref,
+	     takeOverPtr.p->toCurrentFragid);
+    replicaPtr.p->lcpIdStarted = 0;
+    BlockReference ref = calcLqhBlockRef(takeOverPtr.p->toStartingNode);
+    StartFragReq *req = (StartFragReq *)signal->getDataPtrSend();
+    req->userPtr = 0;
+    req->userRef = reference();
+    req->lcpNo = ZNIL;
+    req->lcpId = 0;
+    req->tableId = takeOverPtr.p->toCurrentTabref;
+    req->fragId = takeOverPtr.p->toCurrentFragid;
+    req->noOfLogNodes = 0;
+    sendSignal(ref, GSN_START_FRAGREQ, signal, 
+	       StartFragReq::SignalLength, JBB);
+  }
+  else
+  {
+    ndbout_c("Found LCP: %d(%d) maxGciStarted: %d maxGciCompleted: %d restorable: %d(%d) newestRestorableGCI: %d",
+	     maxLcpId,
+	     maxLcpIndex,
+	     replicaPtr.p->maxGciStarted[maxLcpIndex],
+	     replicaPtr.p->maxGciCompleted[maxLcpIndex],	     
+	     restorableGCI,
+	     SYSFILE->lastCompletedGCI[takeOverPtr.p->toStartingNode],
+	     SYSFILE->newestRestorableGCI);
+
+    replicaPtr.p->lcpIdStarted = restorableGCI;
+    BlockReference ref = calcLqhBlockRef(takeOverPtr.p->toStartingNode);
+    StartFragReq *req = (StartFragReq *)signal->getDataPtrSend();
+    req->userPtr = 0;
+    req->userRef = reference();
+    req->lcpNo = maxLcpIndex;
+    req->lcpId = maxLcpId;
+    req->tableId = takeOverPtr.p->toCurrentTabref;
+    req->fragId = takeOverPtr.p->toCurrentFragid;
+    req->noOfLogNodes = 1;
+    req->lqhLogNode[0] = takeOverPtr.p->toStartingNode;
+    req->startGci[0] = replicaPtr.p->maxGciCompleted[maxLcpIndex];
+    req->lastGci[0] = restorableGCI;
+    sendSignal(ref, GSN_START_FRAGREQ, signal, 
+	       StartFragReq::SignalLength, JBB);
+  }
+}
+
+void
+Dbdih::nr_run_redo(Signal* signal, TakeOverRecordPtr takeOverPtr)
+{
+  takeOverPtr.p->toCurrentTabref = 0;
+  takeOverPtr.p->toCurrentFragid = 0;
+  sendSTART_RECREQ(signal, takeOverPtr.p->toStartingNode);
+}
+
 void Dbdih::initStartTakeOver(const StartToReq * req, 
 			      TakeOverRecordPtr takeOverPtr)
 {
@@ -3108,6 +3298,14 @@ void Dbdih::execCREATE_FRAGCONF(Signal* 
     /*---------------------------------------------------------------------- */
     FragmentstorePtr fragPtr;
     getFragstore(tabPtr.p, fragId, fragPtr);
+    Uint32 gci = 0;
+    if (takeOverPtr.p->toNodeRestart)
+    {
+      ReplicaRecordPtr replicaPtr;
+      findReplica(replicaPtr, fragPtr.p, takeOverPtr.p->toStartingNode, true);
+      gci = replicaPtr.p->lcpIdStarted;
+      replicaPtr.p->lcpIdStarted = 0;
+    }
     takeOverPtr.p->toMasterStatus = TakeOverRecord::COPY_FRAG;
     BlockReference ref = calcLqhBlockRef(takeOverPtr.p->toCopyNode);
     CopyFragReq * const copyFragReq = (CopyFragReq *)&signal->theData[0];
@@ -3118,6 +3316,7 @@ void Dbdih::execCREATE_FRAGCONF(Signal* 
     copyFragReq->nodeId = takeOverPtr.p->toStartingNode;
     copyFragReq->schemaVersion = tabPtr.p->schemaVersion;
     copyFragReq->distributionKey = fragPtr.p->distributionKey;
+    copyFragReq->gci = gci;
     copyFragReq->nodeCount = extractNodeInfo(fragPtr.p, 
 					     copyFragReq->nodeList);
     sendSignal(ref, GSN_COPY_FRAGREQ, signal, 
@@ -3650,6 +3849,7 @@ void Dbdih::readingGcpLab(Signal* signal
   /*     WE ALSO COPY TO OUR OWN NODE. TO ENABLE US TO DO THIS PROPERLY WE   */
   /*     START BY CLOSING THIS FILE.                                         */
   /* ----------------------------------------------------------------------- */
+  globalData.m_restart_seq = ++SYSFILE->m_restart_seq;
   closeFile(signal, filePtr);
   filePtr.p->reqStatus = FileRecord::CLOSING_GCP;
 }//Dbdih::readingGcpLab()
@@ -3858,13 +4058,18 @@ void Dbdih::execNODE_FAILREP(Signal* sig
   Uint32 newMasterId = nodeFail->masterNodeId;
   const Uint32 noOfFailedNodes = nodeFail->noOfNodes;
 
+  if (ERROR_INSERTED(7179))
+  {
+    CLEAR_ERROR_INSERT_VALUE;
+  }
+
   /*-------------------------------------------------------------------------*/
   // The first step is to convert from a bit mask to an array of failed nodes.
   /*-------------------------------------------------------------------------*/
   Uint32 index = 0;
   for (i = 1; i < MAX_NDB_NODES; i++) {
     jam();
-    if(NodeBitmask::get(nodeFail->theNodes, i)){
+    if(NdbNodeBitmask::get(nodeFail->theNodes, i)){
       jam();
       failedNodes[index] = i;
       index++;
@@ -4168,6 +4373,8 @@ void Dbdih::checkTakeOverInMasterStartNo
 						  Uint32 takeOverPtrI)
 {
   jam();
+  ndbout_c("checkTakeOverInMasterStartNodeFailure %x",
+	   takeOverPtrI);
   if (takeOverPtrI == RNIL) {
     jam();
     return;
@@ -4181,6 +4388,9 @@ void Dbdih::checkTakeOverInMasterStartNo
   takeOverPtr.i = takeOverPtrI;
   ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
 
+  ndbout_c("takeOverPtr.p->toMasterStatus: %x", 
+	   takeOverPtr.p->toMasterStatus);
+  
   bool ok = false;
   switch (takeOverPtr.p->toMasterStatus) {
   case TakeOverRecord::IDLE:
@@ -4289,6 +4499,13 @@ void Dbdih::checkTakeOverInMasterStartNo
     //-----------------------------------------------------------------------
     endTakeOver(takeOverPtr.i);
     break;
+
+  case TakeOverRecord::STARTING_LOCAL_FRAGMENTS:
+    ok = true;
+    jam();
+    endTakeOver(takeOverPtr.i);
+    break;
+    
     /**
      * The following are states that it should not be possible to "be" in
      */
@@ -5362,7 +5579,7 @@ void Dbdih::removeNodeFromTable(Signal* 
 
   //const Uint32 lcpId = SYSFILE->latestLCP_ID;
   const bool lcpOngoingFlag = (tabPtr.p->tabLcpStatus== TabRecord::TLS_ACTIVE);
-  const bool temporary = !tabPtr.p->storedTable;
+  const bool unlogged = (tabPtr.p->tabStorage != TabRecord::ST_NORMAL);
   
   FragmentstorePtr fragPtr;
   for(Uint32 fragNo = 0; fragNo < tabPtr.p->totalfragments; fragNo++){
@@ -5383,7 +5600,7 @@ void Dbdih::removeNodeFromTable(Signal* 
         jam();
 	found = true;
 	noOfRemovedReplicas++;
-	removeNodeFromStored(nodeId, fragPtr, replicaPtr, temporary);
+	removeNodeFromStored(nodeId, fragPtr, replicaPtr, unlogged);
 	if(replicaPtr.p->lcpOngoingFlag){
 	  jam();
 	  /**
@@ -5710,11 +5927,9 @@ Dbdih::sendMASTER_LCPCONF(Signal * signa
 #endif
   }
 
-  bool ok = false;
   MasterLCPConf::State lcpState;
   switch (c_lcpState.lcpStatus) {
   case LCP_STATUS_IDLE:
-    ok = true;
     jam();
     /*------------------------------------------------*/
     /*       LOCAL CHECKPOINT IS CURRENTLY NOT ACTIVE */
@@ -5725,7 +5940,6 @@ Dbdih::sendMASTER_LCPCONF(Signal * signa
     lcpState = MasterLCPConf::LCP_STATUS_IDLE;
     break;
   case LCP_STATUS_ACTIVE:
-    ok = true;
     jam();
     /*--------------------------------------------------*/
     /*       COPY OF RESTART INFORMATION HAS BEEN       */
@@ -5734,7 +5948,6 @@ Dbdih::sendMASTER_LCPCONF(Signal * signa
     lcpState = MasterLCPConf::LCP_STATUS_ACTIVE;
     break;
   case LCP_TAB_COMPLETED:
-    ok = true;
     jam();
     /*--------------------------------------------------------*/
     /*       ALL LCP_REPORT'S HAVE BEEN COMPLETED FOR         */
@@ -5744,7 +5957,6 @@ Dbdih::sendMASTER_LCPCONF(Signal * signa
     lcpState = MasterLCPConf::LCP_TAB_COMPLETED;
     break;
   case LCP_TAB_SAVED:
-    ok = true;
     jam();
     /*--------------------------------------------------------*/
     /*       ALL LCP_REPORT'S HAVE BEEN COMPLETED FOR         */
@@ -5768,15 +5980,16 @@ Dbdih::sendMASTER_LCPCONF(Signal * signa
     break;
   case LCP_COPY_GCI:
   case LCP_INIT_TABLES:
-    ok = true;
     /**
      * These two states are handled by if statements above
      */
     ndbrequire(false);
     lcpState= MasterLCPConf::LCP_STATUS_IDLE; // remove warning
     break;
+  default:
+    ndbrequire(false);
+    lcpState= MasterLCPConf::LCP_STATUS_IDLE; // remove warning
   }//switch
-  ndbrequire(ok);
 
   Uint32 failedNodeId = c_lcpState.m_MASTER_LCPREQ_FailedNodeId;
   MasterLCPConf * const conf = (MasterLCPConf *)&signal->theData[0];
@@ -6374,96 +6587,147 @@ void Dbdih::execDIRELEASEREQ(Signal* sig
   3.7.1   A D D   T A B L E   M A I N L Y
   ***************************************
   */
-void Dbdih::execCREATE_FRAGMENTATION_REQ(Signal * signal){
+
+static inline void inc_node_or_group(Uint32 &node, Uint32 max_node)
+{
+  Uint32 next = node + 1;
+  node = (next == max_node ? 0 : next);
+}
+
+/*
+  Spread fragments in backwards compatible mode
+*/
+static void set_default_node_groups(Signal *signal, Uint32 noFrags)
+{
+  Uint16 *node_group_array = (Uint16*)&signal->theData[25];
+  Uint32 i;
+  node_group_array[0] = 0;
+  for (i = 1; i < noFrags; i++)
+    node_group_array[i] = UNDEF_NODEGROUP;
+}
+void Dbdih::execCREATE_FRAGMENTATION_REQ(Signal * signal)
+{
+  Uint16 node_group_id[MAX_NDB_PARTITIONS];
   jamEntry();
   CreateFragmentationReq * const req = 
     (CreateFragmentationReq*)signal->getDataPtr();
   
   const Uint32 senderRef = req->senderRef;
   const Uint32 senderData = req->senderData;
-  const Uint32 fragmentNode = req->fragmentNode;
-  const Uint32 fragmentType = req->fragmentationType;
-  //const Uint32 fragmentCount = req->noOfFragments;
+  Uint32 noOfFragments = req->noOfFragments;
+  const Uint32 fragType = req->fragmentationType;
   const Uint32 primaryTableId = req->primaryTableId;
 
   Uint32 err = 0;
   
   do {
-    Uint32 noOfFragments = 0;
-    Uint32 noOfReplicas = cnoReplicas;
-    switch(fragmentType){
-    case DictTabInfo::AllNodesSmallTable:
-      jam();
-      noOfFragments = csystemnodes;
-      break;
-    case DictTabInfo::AllNodesMediumTable:
-      jam();
-      noOfFragments = 2 * csystemnodes;
-      break;
-    case DictTabInfo::AllNodesLargeTable:
-      jam();
-      noOfFragments = 4 * csystemnodes;
-      break;
-    case DictTabInfo::SingleFragment:
-      jam();
-      noOfFragments = 1;
-      break;
-#if 0
-    case DictTabInfo::SpecifiedFragmentCount:
-      noOfFragments = (fragmentCount == 0 ? 1 : (fragmentCount + 1)/ 2);
-      break;
-#endif
-    default:
-      jam();
-      err = CreateFragmentationRef::InvalidFragmentationType;
-      break;
-    }
-    if(err)
-      break;
-   
     NodeGroupRecordPtr NGPtr;
     TabRecordPtr primTabPtr;
+    Uint32 count = 2;
+    Uint16 noOfReplicas = cnoReplicas;
+    Uint16 *fragments = (Uint16*)(signal->theData+25);
     if (primaryTableId == RNIL) {
-      if(fragmentNode == 0){
-        jam();
-        NGPtr.i = 0; 
-	if(noOfFragments < csystemnodes)
-	{
-	  NGPtr.i = c_nextNodeGroup; 
-	  c_nextNodeGroup = (NGPtr.i + 1 == cnoOfNodeGroups ? 0 : NGPtr.i + 1);
-	}
-      } else if(! (fragmentNode < MAX_NDB_NODES)) {
-        jam();
-        err = CreateFragmentationRef::InvalidNodeId;
-      } else {
-        jam();
-        const Uint32 stat = Sysfile::getNodeStatus(fragmentNode,
-                                                   SYSFILE->nodeStatus);
-        switch (stat) {
-        case Sysfile::NS_Active:
-        case Sysfile::NS_ActiveMissed_1:
-        case Sysfile::NS_ActiveMissed_2:
-        case Sysfile::NS_TakeOver:
+      jam();
+      switch ((DictTabInfo::FragmentType)fragType)
+      {
+        /*
+          Backward compatability and for all places in code not changed.
+        */
+        case DictTabInfo::AllNodesSmallTable:
+          jam();
+          noOfFragments = csystemnodes;
+          set_default_node_groups(signal, noOfFragments);
+          break;
+        case DictTabInfo::AllNodesMediumTable:
           jam();
+          noOfFragments = 2 * csystemnodes;
+          set_default_node_groups(signal, noOfFragments);
           break;
-        case Sysfile::NS_NotActive_NotTakenOver:
+        case DictTabInfo::AllNodesLargeTable:
           jam();
+          noOfFragments = 4 * csystemnodes;
+          set_default_node_groups(signal, noOfFragments);
           break;
-        case Sysfile::NS_HotSpare:
+        case DictTabInfo::SingleFragment:
           jam();
-        case Sysfile::NS_NotDefined:
+          noOfFragments = 1;
+          set_default_node_groups(signal, noOfFragments);
+          break;
+        case DictTabInfo::DistrKeyHash:
+          jam();
+        case DictTabInfo::DistrKeyLin:
           jam();
+          if (noOfFragments == 0)
+          {
+            jam();
+            noOfFragments = csystemnodes;
+            set_default_node_groups(signal, noOfFragments);
+          }
+          break;
         default:
           jam();
-          err = CreateFragmentationRef::InvalidNodeType;
+          if (noOfFragments == 0)
+          {
+            jam();
+            err = CreateFragmentationRef::InvalidFragmentationType;
+          }
           break;
+      }
+      if (err)
+        break;
+      /*
+        When we come here the the exact partition is specified
+        and there is an array of node groups sent along as well.
+      */
+      memcpy(&node_group_id[0], &signal->theData[25], 2 * noOfFragments);
+      Uint16 next_replica_node[MAX_NDB_NODES];
+      memset(next_replica_node,0,sizeof(next_replica_node));
+      Uint32 default_node_group= c_nextNodeGroup;
+      for(Uint32 fragNo = 0; fragNo < noOfFragments; fragNo++)
+      {
+        jam();
+        NGPtr.i = node_group_id[fragNo];
+        if (NGPtr.i == UNDEF_NODEGROUP)
+        {
+          jam();
+	  NGPtr.i = default_node_group; 
         }
-        if(err)
+        if (NGPtr.i > cnoOfNodeGroups)
+        {
+          jam();
+          err = CreateFragmentationRef::InvalidNodeGroup;
           break;
-        NGPtr.i = Sysfile::getNodeGroup(fragmentNode,
-                                        SYSFILE->nodeGroups);
+        }
+        ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);
+        const Uint32 max = NGPtr.p->nodeCount;
+	
+	fragments[count++] = c_nextLogPart++; // Store logpart first
+	Uint32 tmp= next_replica_node[NGPtr.i];
+        for(Uint32 replicaNo = 0; replicaNo < noOfReplicas; replicaNo++)
+        {
+          jam();
+          const Uint16 nodeId = NGPtr.p->nodesInGroup[tmp];
+          fragments[count++]= nodeId;
+          inc_node_or_group(tmp, max);
+        }
+        inc_node_or_group(tmp, max);
+	next_replica_node[NGPtr.i]= tmp;
+	
+        /**
+         * Next node group for next fragment
+         */
+        inc_node_or_group(default_node_group, cnoOfNodeGroups);
+      }
+      if (err)
+      {
+        jam();
         break;
       }
+      else
+      {
+        jam();
+        c_nextNodeGroup = default_node_group;
+      }
     } else {
       if (primaryTableId >= ctabFileSize) {
         jam();
@@ -6477,48 +6741,14 @@ void Dbdih::execCREATE_FRAGMENTATION_REQ
         err = CreateFragmentationRef::InvalidPrimaryTable;
         break;
       }
-      if (noOfFragments != primTabPtr.p->totalfragments) {
-        jam();
-        err = CreateFragmentationRef::InvalidFragmentationType;
-        break;
-      }
-    }
-    
-    Uint32 count = 2;
-    Uint16 *fragments = (Uint16*)(signal->theData+25);
-    if (primaryTableId == RNIL) {
-      jam();
-      Uint8 next_replica_node[MAX_NDB_NODES];
-      memset(next_replica_node,0,sizeof(next_replica_node));
-      for(Uint32 fragNo = 0; fragNo<noOfFragments; fragNo++){
-        jam();
-        ptrCheckGuard(NGPtr, MAX_NDB_NODES, nodeGroupRecord);      
-        const Uint32 max = NGPtr.p->nodeCount;
-	
-	Uint32 tmp= next_replica_node[NGPtr.i];
-        for(Uint32 replicaNo = 0; replicaNo<noOfReplicas; replicaNo++)
-        {
-          jam();
-          const Uint32 nodeId = NGPtr.p->nodesInGroup[tmp++];
-          fragments[count++] = nodeId;
-          tmp = (tmp >= max ? 0 : tmp);
-        }
-	tmp++;
-	next_replica_node[NGPtr.i]= (tmp >= max ? 0 : tmp);
-	
-        /**
-         * Next node group for next fragment
-         */
-        NGPtr.i++;
-        NGPtr.i = (NGPtr.i == cnoOfNodeGroups ? 0 : NGPtr.i);
-      }
-    } else {
+      noOfFragments= primTabPtr.p->totalfragments;
       for (Uint32 fragNo = 0;
-           fragNo < primTabPtr.p->totalfragments; fragNo++) {
+           fragNo < noOfFragments; fragNo++) {
         jam();
         FragmentstorePtr fragPtr;
         ReplicaRecordPtr replicaPtr;
         getFragstore(primTabPtr.p, fragNo, fragPtr);
+	fragments[count++] = fragPtr.p->m_log_part_id;
         fragments[count++] = fragPtr.p->preferredPrimary;
         for (replicaPtr.i = fragPtr.p->storedReplicas;
              replicaPtr.i != RNIL;
@@ -6527,9 +6757,9 @@ void Dbdih::execCREATE_FRAGMENTATION_REQ
           ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
           if (replicaPtr.p->procNode != fragPtr.p->preferredPrimary) {
             jam();
-            fragments[count++] = replicaPtr.p->procNode;
-          }//if
-        }//for
+            fragments[count++]= replicaPtr.p->procNode;
+          }
+        }
         for (replicaPtr.i = fragPtr.p->oldStoredReplicas;
              replicaPtr.i != RNIL;
              replicaPtr.i = replicaPtr.p->nextReplica) {
@@ -6537,12 +6767,12 @@ void Dbdih::execCREATE_FRAGMENTATION_REQ
           ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
           if (replicaPtr.p->procNode != fragPtr.p->preferredPrimary) {
             jam();
-            fragments[count++] = replicaPtr.p->procNode;
-          }//if
-        }//for
+            fragments[count++]= replicaPtr.p->procNode;
+          }
+        }
       }
     }
-    if(count != (2 + noOfReplicas * noOfFragments)){
+    if(count != (2U + (1 + noOfReplicas) * noOfFragments)){
         char buf[255];
         BaseString::snprintf(buf, sizeof(buf),
                            "Illegal configuration change: NoOfReplicas."
@@ -6554,14 +6784,15 @@ void Dbdih::execCREATE_FRAGMENTATION_REQ
       (CreateFragmentationConf*)signal->getDataPtrSend();
     conf->senderRef = reference();
     conf->senderData = senderData;
-    conf->noOfReplicas = noOfReplicas;
-    conf->noOfFragments = noOfFragments;
+    conf->noOfReplicas = (Uint32)noOfReplicas;
+    conf->noOfFragments = (Uint32)noOfFragments;
 
-    fragments[0] = noOfReplicas;
-    fragments[1] = noOfFragments;
+    fragments[0]= noOfReplicas;
+    fragments[1]= noOfFragments;
     
     if(senderRef != 0)
     {
+      jam();
       LinearSectionPtr ptr[3];
       ptr[0].p = (Uint32*)&fragments[0];
       ptr[0].sz = (count + 1) / 2;
@@ -6573,33 +6804,17 @@ void Dbdih::execCREATE_FRAGMENTATION_REQ
 		 ptr,
 		 1);
     }
-    else
-    {
-      // Execute direct
-      signal->theData[0] = 0;
-    }
+    // Always ACK/NACK (here ACK)
+    signal->theData[0] = 0;
     return;
   } while(false);
-
-  if(senderRef != 0)
-  {
-    CreateFragmentationRef * const ref = 
-      (CreateFragmentationRef*)signal->getDataPtrSend();
-    ref->senderRef = reference();
-    ref->senderData = senderData;
-    ref->errorCode = err;
-    sendSignal(senderRef, GSN_CREATE_FRAGMENTATION_REF, signal, 
-	       CreateFragmentationRef::SignalLength, JBB);
-  }
-  else
-  {
-    // Execute direct
-    signal->theData[0] = err;
-  }
+  // Always ACK/NACK (here NACK)
+  signal->theData[0] = err;
 }
 
 void Dbdih::execDIADDTABREQ(Signal* signal) 
 {
+  Uint32 fragType;
   jamEntry();
 
   DiAddTabReq * const req = (DiAddTabReq*)signal->getDataPtr();
@@ -6624,6 +6839,7 @@ void Dbdih::execDIADDTABREQ(Signal* sign
   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
   tabPtr.p->connectrec = connectPtr.i;
   tabPtr.p->tableType = req->tableType;
+  fragType= req->fragType;
   tabPtr.p->schemaVersion = req->schemaVersion;
   tabPtr.p->primaryTableId = req->primaryTableId;
 
@@ -6659,15 +6875,46 @@ void Dbdih::execDIADDTABREQ(Signal* sign
   /* BUT THEY DO NOT HAVE ANY INFORMATION ABOUT ANY TABLE*/
   /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
   tabPtr.p->tabStatus = TabRecord::TS_CREATING;
-  tabPtr.p->storedTable = req->storedTable;
-  tabPtr.p->method = TabRecord::HASH;
+  if(req->loggedTable)
+    tabPtr.p->tabStorage= TabRecord::ST_NORMAL;
+  else if(req->temporaryTable)
+    tabPtr.p->tabStorage= TabRecord::ST_TEMPORARY;
+  else
+    tabPtr.p->tabStorage= TabRecord::ST_NOLOGGING;
   tabPtr.p->kvalue = req->kValue;
 
+  switch ((DictTabInfo::FragmentType)fragType)
+  {
+    case DictTabInfo::AllNodesSmallTable:
+    case DictTabInfo::AllNodesMediumTable:
+    case DictTabInfo::AllNodesLargeTable:
+    case DictTabInfo::SingleFragment:
+      jam();
+    case DictTabInfo::DistrKeyLin:
+      jam();
+      tabPtr.p->method= TabRecord::LINEAR_HASH;
+      break;
+    case DictTabInfo::DistrKeyHash:
+    case DictTabInfo::DistrKeyUniqueHashIndex:
+    case DictTabInfo::DistrKeyOrderedIndex:
+      jam();
+      tabPtr.p->method= TabRecord::NORMAL_HASH;
+      break;
+    case DictTabInfo::UserDefined:
+      jam();
+      tabPtr.p->method= TabRecord::USER_DEFINED;
+      break;
+    default:
+      ndbrequire(false);
+  }
+
   union {
     Uint16 fragments[2 + MAX_FRAG_PER_NODE*MAX_REPLICAS*MAX_NDB_NODES];
     Uint32 align;
   };
   SegmentedSectionPtr fragDataPtr;
+  LINT_INIT(fragDataPtr.i);
+  LINT_INIT(fragDataPtr.sz);
   signal->getSection(fragDataPtr, DiAddTabReq::FRAGMENTATION);
   copy((Uint32*)fragments, fragDataPtr);
   releaseSections(signal);
@@ -6711,7 +6958,9 @@ void Dbdih::execDIADDTABREQ(Signal* sign
     FragmentstorePtr fragPtr;
     Uint32 activeIndex = 0;
     getFragstore(tabPtr.p, fragId, fragPtr);
+    fragPtr.p->m_log_part_id = fragments[index++];
     fragPtr.p->preferredPrimary = fragments[index];
+    
     for (Uint32 i = 0; i<noReplicas; i++) {
       const Uint32 nodeId = fragments[index++];
       ReplicaRecordPtr replicaPtr;
@@ -6755,10 +7004,12 @@ Dbdih::sendAddFragreq(Signal* signal, Co
 		      TabRecordPtr tabPtr, Uint32 fragId){
   jam();
   const Uint32 fragCount = tabPtr.p->totalfragments;
-  ReplicaRecordPtr replicaPtr; replicaPtr.i = RNIL;
+  ReplicaRecordPtr replicaPtr;
+  LINT_INIT(replicaPtr.p);
+  replicaPtr.i = RNIL;
+  FragmentstorePtr fragPtr;
   for(; fragId<fragCount; fragId++){
     jam();
-    FragmentstorePtr fragPtr;
     getFragstore(tabPtr.p, fragId, fragPtr);    
     
     replicaPtr.i = fragPtr.p->storedReplicas;
@@ -6798,7 +7049,7 @@ Dbdih::sendAddFragreq(Signal* signal, Co
     ndbrequire(replicaPtr.p->procNode == getOwnNodeId());
 
     Uint32 requestInfo = 0;
-    if(!tabPtr.p->storedTable){
+    if(tabPtr.p->tabStorage != TabRecord::ST_NORMAL){
       requestInfo |= LqhFragReq::TemporaryTable;
     }
     
@@ -6816,6 +7067,7 @@ Dbdih::sendAddFragreq(Signal* signal, Co
     req->nodeId = getOwnNodeId();
     req->totalFragments = fragCount;
     req->startGci = SYSFILE->newestRestorableGCI;
+    req->logPartId = fragPtr.p->m_log_part_id;
     sendSignal(DBDICT_REF, GSN_ADD_FRAGREQ, signal, 
 	       AddFragReq::SignalLength, JBB);
     return;
@@ -7097,17 +7349,40 @@ void Dbdih::execDIGETNODESREQ(Signal* si
   tabPtr.i = req->tableId;
   Uint32 hashValue = req->hashValue;
   Uint32 ttabFileSize = ctabFileSize;
+  Uint32 fragId;
+  DiGetNodesConf * const conf = (DiGetNodesConf *)&signal->theData[0];
   TabRecord* regTabDesc = tabRecord;
   jamEntry();
   ptrCheckGuard(tabPtr, ttabFileSize, regTabDesc);
-  Uint32 fragId = hashValue & tabPtr.p->mask;
-  ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_ACTIVE);
-  if (fragId < tabPtr.p->hashpointer) {
+  if (tabPtr.p->method == TabRecord::LINEAR_HASH)
+  {
     jam();
-    fragId = hashValue & ((tabPtr.p->mask << 1) + 1);
-  }//if
+    fragId = hashValue & tabPtr.p->mask;
+    ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_ACTIVE);
+    if (fragId < tabPtr.p->hashpointer) {
+      jam();
+      fragId = hashValue & ((tabPtr.p->mask << 1) + 1);
+    }//if
+  }
+  else if (tabPtr.p->method == TabRecord::NORMAL_HASH)
+  {
+    jam();
+    fragId= hashValue % tabPtr.p->totalfragments;
+  }
+  else
+  {
+    jam();
+    ndbassert(tabPtr.p->method == TabRecord::USER_DEFINED);
+    fragId= hashValue;
+    if (fragId >= tabPtr.p->totalfragments)
+    {
+      jam();
+      conf->zero= 1; //Indicate error;
+      signal->theData[1]= ZUNDEFINED_FRAGMENT_ERROR;
+      return;
+    }
+  }
   getFragstore(tabPtr.p, fragId, fragPtr);
-  DiGetNodesConf * const conf = (DiGetNodesConf *)&signal->theData[0];
   Uint32 nodeCount = extractNodeInfo(fragPtr.p, conf->nodes);
   Uint32 sig2 = (nodeCount - 1) + 
     (fragPtr.p->distributionKey << 16);
@@ -7274,39 +7549,70 @@ void Dbdih::execDIVERIFYREQ(Signal* sign
 
 void Dbdih::execDI_FCOUNTREQ(Signal* signal) 
 {
+  DihFragCountReq * const req = (DihFragCountReq*)signal->getDataPtr();
   ConnectRecordPtr connectPtr;
   TabRecordPtr tabPtr;
+  const BlockReference senderRef = signal->senderBlockRef();
+  const Uint32 senderData = req->m_senderData;
   jamEntry();
-  connectPtr.i = signal->theData[0];
-  tabPtr.i = signal->theData[1];
+  connectPtr.i = req->m_connectionData;
+  tabPtr.i = req->m_tableRef;
   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
 
-  ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_ACTIVE);
+  if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE)
+  {
+    DihFragCountRef* ref = (DihFragCountRef*)signal->getDataPtrSend();
+    //connectPtr.i == RNIL -> question without connect record
+    if(connectPtr.i == RNIL)
+      ref->m_connectionData = RNIL;
+    else
+    {
+      jam();
+      ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
+      ref->m_connectionData = connectPtr.p->userpointer;
+    }
+    ref->m_tableRef = tabPtr.i;
+    ref->m_senderData = senderData;
+    ref->m_error = DihFragCountRef::ErroneousTableState;
+    ref->m_tableStatus = tabPtr.p->tabStatus;
+    sendSignal(senderRef, GSN_DI_FCOUNTREF, signal, 
+               DihFragCountRef::SignalLength, JBB);
+    return;
+  }
 
   if(connectPtr.i != RNIL){
     ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord);
     if (connectPtr.p->connectState == ConnectRecord::INUSE) {
       jam();
-      signal->theData[0] = connectPtr.p->userpointer;
-      signal->theData[1] = tabPtr.p->totalfragments;
-      sendSignal(connectPtr.p->userblockref, GSN_DI_FCOUNTCONF, signal,2, JBB);
-      return;
-    }//if
-    signal->theData[0] = connectPtr.p->userpointer;
-    signal->theData[1] = ZERRONOUSSTATE;
-    sendSignal(connectPtr.p->userblockref, GSN_DI_FCOUNTREF, signal, 2, JBB);
+      DihFragCountConf* conf = (DihFragCountConf*)signal->getDataPtrSend();
+      conf->m_connectionData = connectPtr.p->userpointer;
+      conf->m_tableRef = tabPtr.i;
+      conf->m_senderData = senderData;
+      conf->m_fragmentCount = tabPtr.p->totalfragments;
+      conf->m_noOfBackups = tabPtr.p->noOfBackups;
+      sendSignal(connectPtr.p->userblockref, GSN_DI_FCOUNTCONF, signal,
+                 DihFragCountConf::SignalLength, JBB);
+      return;
+    }//if
+    DihFragCountRef* ref = (DihFragCountRef*)signal->getDataPtrSend();
+    ref->m_connectionData = connectPtr.p->userpointer;
+    ref->m_tableRef = tabPtr.i;
+    ref->m_senderData = senderData;
+    ref->m_error = DihFragCountRef::ErroneousTableState;
+    ref->m_tableStatus = tabPtr.p->tabStatus;
+    sendSignal(connectPtr.p->userblockref, GSN_DI_FCOUNTREF, signal, 
+               DihFragCountRef::SignalLength, JBB);
     return;
   }//if
-
+  DihFragCountConf* conf = (DihFragCountConf*)signal->getDataPtrSend();
   //connectPtr.i == RNIL -> question without connect record
-  const Uint32 senderData = signal->theData[2];
-  const BlockReference senderRef = signal->senderBlockRef();
-  signal->theData[0] = RNIL;
-  signal->theData[1] = tabPtr.p->totalfragments;
-  signal->theData[2] = tabPtr.i;
-  signal->theData[3] = senderData;
-  signal->theData[4] = tabPtr.p->noOfBackups;
-  sendSignal(senderRef, GSN_DI_FCOUNTCONF, signal, 5, JBB);
+  conf->m_connectionData = RNIL;
+  conf->m_tableRef = tabPtr.i;
+  conf->m_senderData = senderData;
+  conf->m_fragmentCount = tabPtr.p->totalfragments;
+  conf->m_noOfBackups = tabPtr.p->noOfBackups;
+  sendSignal(senderRef, GSN_DI_FCOUNTCONF, signal, 
+             DihFragCountConf::SignalLength, JBB);
 }//Dbdih::execDI_FCOUNTREQ()
 
 void Dbdih::execDIGETPRIMREQ(Signal* signal) 
@@ -8080,6 +8386,15 @@ void Dbdih::writingCopyGciLab(Signal* si
   if (reason == CopyGCIReq::GLOBAL_CHECKPOINT) {
     jam();
     cgcpParticipantState = GCP_PARTICIPANT_READY;
+    
+    SubGcpCompleteRep * const rep = (SubGcpCompleteRep*)signal->getDataPtr();
+    rep->gci = coldgcp;
+    sendSignal(SUMA_REF, GSN_SUB_GCP_COMPLETE_REP, signal, 
+	       SubGcpCompleteRep::SignalLength, JBB);
+
+    EXECUTE_DIRECT(LGMAN, GSN_SUB_GCP_COMPLETE_REP, signal, 
+		   SubGcpCompleteRep::SignalLength);
+    jamEntry();
   }
   
   jam();
@@ -8168,9 +8483,9 @@ void Dbdih::initLcpLab(Signal* signal, U
       continue;
     }
 
-    if (tabPtr.p->storedTable == 0) {
+    if (tabPtr.p->tabStorage != TabRecord::ST_NORMAL) {
       /**
-       * Temporary table
+       * Table is not logged
        */
       jam();
       tabPtr.p->tabLcpStatus = TabRecord::TLS_COMPLETED;
@@ -8483,7 +8798,7 @@ Dbdih::resetReplicaSr(TabRecordPtr tabPt
 	    ConstPtr<ReplicaRecord> constReplicaPtr;
 	    constReplicaPtr.i = replicaPtr.i;
 	    constReplicaPtr.p = replicaPtr.p;
-	    if (tabPtr.p->storedTable == 0 ||
+	    if (tabPtr.p->tabStorage != TabRecord::ST_NORMAL ||
 		setup_create_replica(fragPtr,
 				     &createReplica, constReplicaPtr))
 	    {
@@ -8676,12 +8991,11 @@ void Dbdih::readPagesIntoTableLab(Signal
   rf.rwfTabPtr.p->hashpointer = readPageWord(&rf);
   rf.rwfTabPtr.p->kvalue = readPageWord(&rf);
   rf.rwfTabPtr.p->mask = readPageWord(&rf);
-  ndbrequire(readPageWord(&rf) == TabRecord::HASH);
-  rf.rwfTabPtr.p->method = TabRecord::HASH;
-  /* ---------------------------------- */
-  /* Type of table, 2 = temporary table */
-  /* ---------------------------------- */
-  rf.rwfTabPtr.p->storedTable = readPageWord(&rf); 
+  rf.rwfTabPtr.p->method = (TabRecord::Method)readPageWord(&rf);
+  /* ------------- */
+  /* Type of table */
+  /* ------------- */
+  rf.rwfTabPtr.p->tabStorage = (TabRecord::Storage)(readPageWord(&rf)); 
 
   Uint32 noOfFrags = rf.rwfTabPtr.p->totalfragments;
   ndbrequire(noOfFrags > 0);
@@ -8771,8 +9085,8 @@ void Dbdih::packTableIntoPagesLab(Signal
   writePageWord(&wf, tabPtr.p->hashpointer);
   writePageWord(&wf, tabPtr.p->kvalue);
   writePageWord(&wf, tabPtr.p->mask);
-  writePageWord(&wf, TabRecord::HASH);
-  writePageWord(&wf, tabPtr.p->storedTable);
+  writePageWord(&wf, tabPtr.p->method);
+  writePageWord(&wf, tabPtr.p->tabStorage);
 
   signal->theData[0] = DihContinueB::ZPACK_FRAG_INTO_PAGES;
   signal->theData[1] = tabPtr.i;
@@ -8872,6 +9186,80 @@ void Dbdih::packFragIntoPagesLab(Signal*
 /*****************************************************************************/
 /* **********     START FRAGMENT MODULE                          *************/
 /*****************************************************************************/
+void
+Dbdih::dump_replica_info()
+{
+  TabRecordPtr tabPtr;
+  FragmentstorePtr fragPtr;
+
+  for(tabPtr.i = 0; tabPtr.i < ctabFileSize; tabPtr.i++)
+  {
+    ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
+    if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE)
+      continue;
+    
+    for(Uint32 fid = 0; fid<tabPtr.p->totalfragments; fid++)
+    {
+      getFragstore(tabPtr.p, fid, fragPtr);
+      ndbout_c("tab: %d frag: %d gci: %d\n  -- storedReplicas:", 
+	       tabPtr.i, fid, SYSFILE->newestRestorableGCI);
+      
+      Uint32 i;
+      ReplicaRecordPtr replicaPtr;
+      replicaPtr.i = fragPtr.p->storedReplicas;
+      for(; replicaPtr.i != RNIL; replicaPtr.i = replicaPtr.p->nextReplica)
+      {
+	ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
+	ndbout_c("  node: %d initialGci: %d nextLcp: %d noCrashedReplicas: %d",
+		 replicaPtr.p->procNode,
+		 replicaPtr.p->initialGci,
+		 replicaPtr.p->nextLcp,
+		 replicaPtr.p->noCrashedReplicas);
+	for(i = 0; i<MAX_LCP_STORED; i++)
+	{
+	  ndbout_c("    i: %d %s : lcpId: %d maxGci Completed: %d Started: %d",
+		   i, 
+		   (replicaPtr.p->lcpStatus[i] == ZVALID ?"VALID":"INVALID"),
+		   replicaPtr.p->lcpId[i],
+		   replicaPtr.p->maxGciCompleted[i],
+		   replicaPtr.p->maxGciStarted[i]);
+	}
+	
+	for (i = 0; i < 8; i++)
+	{
+	  ndbout_c("    crashed replica: %d replicaLastGci: %d createGci: %d",
+		   i, 
+		   replicaPtr.p->replicaLastGci[i],
+		   replicaPtr.p->createGci[i]);
+	}
+      }
+      ndbout_c("  -- oldStoredReplicas");
+      replicaPtr.i = fragPtr.p->oldStoredReplicas;
+      for(; replicaPtr.i != RNIL; replicaPtr.i = replicaPtr.p->nextReplica)
+      {
+	ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
+	for(i = 0; i<MAX_LCP_STORED; i++)
+	{
+	  ndbout_c("    i: %d %s : lcpId: %d maxGci Completed: %d Started: %d",
+		   i, 
+		   (replicaPtr.p->lcpStatus[i] == ZVALID ?"VALID":"INVALID"),
+		   replicaPtr.p->lcpId[i],
+		   replicaPtr.p->maxGciCompleted[i],
+		   replicaPtr.p->maxGciStarted[i]);
+	}
+	
+	for (i = 0; i < 8; i++)
+	{
+	  ndbout_c("    crashed replica: %d replicaLastGci: %d createGci: %d",
+		   i, 
+		   replicaPtr.p->replicaLastGci[i],
+		   replicaPtr.p->createGci[i]);
+	}
+      }
+    }
+  }
+}
+
 void Dbdih::startFragment(Signal* signal, Uint32 tableId, Uint32 fragId) 
 {
   Uint32 TloopCount = 0;
@@ -8903,7 +9291,7 @@ void Dbdih::startFragment(Signal* signal
       continue;
     }
     
-    if(tabPtr.p->storedTable == 0){
+    if(tabPtr.p->tabStorage != TabRecord::ST_NORMAL){
       jam();
       TloopCount++;
       tableId++;
@@ -8933,6 +9321,7 @@ void Dbdih::startFragment(Signal* signal
   /*     SEARCH FOR STORED REPLICAS THAT CAN BE USED TO RESTART THE SYSTEM.  */
   /* ----------------------------------------------------------------------- */
   searchStoredReplicas(fragPtr);
+
   if (cnoOfCreateReplicas == 0) {
     /* --------------------------------------------------------------------- */
     /*   THERE WERE NO STORED REPLICAS AVAILABLE THAT CAN SERVE AS REPLICA TO*/
@@ -8945,6 +9334,10 @@ void Dbdih::startFragment(Signal* signal
     char buf[64];
     BaseString::snprintf(buf, sizeof(buf), "table: %d fragment: %d gci: %d",
 			 tableId, fragId, SYSFILE->newestRestorableGCI);
+
+    ndbout_c(buf);
+    dump_replica_info();
+    
     progError(__LINE__, NDBD_EXIT_NO_RESTORABLE_REPLICA, buf);
     ndbrequire(false);
     return;
@@ -9021,8 +9414,8 @@ void Dbdih::execSTART_RECCONF(Signal* si
     // otherwise we have a problem.
     /* --------------------------------------------------------------------- */
     jam();
-    ndbrequire(senderNodeId == c_nodeStartMaster.startNode);
-    nodeRestartStartRecConfLab(signal);
+    ndbout_c("startNextCopyFragment");
+    startNextCopyFragment(signal, findTakeOver(senderNodeId));
     return;
   } else {
     /* --------------------------------------------------------------------- */
@@ -9524,7 +9917,7 @@ void Dbdih::calculateKeepGciLab(Signal* 
     }//if
     ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
     if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE || 
-	tabPtr.p->storedTable == 0) {
+	tabPtr.p->tabStorage != TabRecord::ST_NORMAL) {
       if (TloopCount > 100) {
         jam();
         signal->theData[0] = DihContinueB::ZCALCULATE_KEEP_GCI;
@@ -9884,12 +10277,42 @@ void Dbdih::execLCP_FRAG_REP(Signal* sig
   Uint32 fragId = lcpReport->fragId;
   
   jamEntry();
+
+  if (ERROR_INSERTED(7178) && nodeId != getOwnNodeId())
+  {
+    jam();
+    Uint32 owng =Sysfile::getNodeGroup(getOwnNodeId(), SYSFILE->nodeGroups);
+    Uint32 nodeg = Sysfile::getNodeGroup(nodeId, SYSFILE->nodeGroups);
+    if (owng == nodeg)
+    {
+      jam();
+      ndbout_c("throwing away LCP_FRAG_REP from  (and killing) %d", nodeId);
+      SET_ERROR_INSERT_VALUE(7179);
+      signal->theData[0] = 9999;
+      sendSignal(numberToRef(CMVMI, nodeId), 
+		 GSN_NDB_TAMPER, signal, 1, JBA);  
+      return;
+    }
+  }
  
+  if (ERROR_INSERTED(7179) && nodeId != getOwnNodeId())
+  {
+    jam();
+    Uint32 owng =Sysfile::getNodeGroup(getOwnNodeId(), SYSFILE->nodeGroups);
+    Uint32 nodeg = Sysfile::getNodeGroup(nodeId, SYSFILE->nodeGroups);
+    if (owng == nodeg)
+    {
+      jam();
+      ndbout_c("throwing away LCP_FRAG_REP from %d", nodeId);
+      return;
+    }
+  }    
+
   CRASH_INSERTION2(7025, isMaster());
   CRASH_INSERTION2(7016, !isMaster());
-
+  
   bool fromTimeQueue = (signal->senderBlockRef() == reference());
-
+  
   TabRecordPtr tabPtr;
   tabPtr.i = tableId;
   ptrCheckGuard(tabPtr, ctabFileSize, tabRecord);
@@ -10052,9 +10475,11 @@ Dbdih::checkLcpAllTablesDoneInLqh(){
 }
 
 void Dbdih::findReplica(ReplicaRecordPtr& replicaPtr, 
-			Fragmentstore* fragPtrP, Uint32 nodeId)
+			Fragmentstore* fragPtrP, 
+			Uint32 nodeId,
+			bool old)
 {
-  replicaPtr.i = fragPtrP->storedReplicas;
+  replicaPtr.i = old ? fragPtrP->oldStoredReplicas : fragPtrP->storedReplicas;
   while(replicaPtr.i != RNIL){
     ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
     if (replicaPtr.p->procNode == nodeId) {
@@ -10088,6 +10513,37 @@ void Dbdih::findReplica(ReplicaRecordPtr
   ndbrequire(false);
 }//Dbdih::findReplica()
 
+
+int
+Dbdih::handle_invalid_lcp_no(const LcpFragRep* rep, 
+			     ReplicaRecordPtr replicaPtr)
+{
+  ndbrequire(!isMaster());
+  Uint32 lcpNo = rep->lcpNo;
+  Uint32 lcpId = rep->lcpId;
+  Uint32 replicaLcpNo = replicaPtr.p->nextLcp;
+  Uint32 prevReplicaLcpNo = prevLcpNo(replicaLcpNo);
+
+  warningEvent("Detected previous node failure of %d during lcp",
+	       rep->nodeId);
+  replicaPtr.p->nextLcp = lcpNo;
+  replicaPtr.p->lcpId[lcpNo] = 0;
+  replicaPtr.p->lcpStatus[lcpNo] = ZINVALID;
+  
+  for (Uint32 i = lcpNo; i != lcpNo; i = nextLcpNo(i))
+  {
+    jam();
+    if (replicaPtr.p->lcpStatus[i] == ZVALID &&
+	replicaPtr.p->lcpId[i] >= lcpId)
+    {
+      ndbout_c("i: %d lcpId: %d", i, replicaPtr.p->lcpId[i]);
+      ndbrequire(false);
+    }
+  }
+
+  return 0;
+}
+
 /**
  * Return true  if table is all fragment replicas have been checkpointed
  *                 to disk (in all LQHs)
@@ -10116,9 +10572,12 @@ Dbdih::reportLcpCompletion(const LcpFrag
   
   ndbrequire(replicaPtr.p->lcpOngoingFlag == true);
   if(lcpNo != replicaPtr.p->nextLcp){
-    g_eventLogger.error("lcpNo = %d replicaPtr.p->nextLcp = %d", 
-                        lcpNo, replicaPtr.p->nextLcp);
-    ndbrequire(false);
+    if (handle_invalid_lcp_no(lcpReport, replicaPtr))
+    {
+      g_eventLogger.error("lcpNo = %d replicaPtr.p->nextLcp = %d",
+                          lcpNo, replicaPtr.p->nextLcp);
+      ndbrequire(false);
+    }
   }
   ndbrequire(lcpNo == replicaPtr.p->nextLcp);
   ndbrequire(lcpNo < MAX_LCP_STORED);
@@ -10451,6 +10910,14 @@ void Dbdih::allNodesLcpCompletedLab(Sign
 /* ------------------------------------------------------------------------- */
 void Dbdih::tableUpdateLab(Signal* signal, TabRecordPtr tabPtr) {
   FileRecordPtr filePtr;
+  if(tabPtr.p->tabStorage == TabRecord::ST_TEMPORARY) {
+    // For temporary tables we do not write to disk. Mark both copies 0 and 1
+    // as done, and go straight to the after-close code.
+    filePtr.i = tabPtr.p->tabFile[1];
+    ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
+    tableCloseLab(signal, filePtr);
+    return;
+  }
   filePtr.i = tabPtr.p->tabFile[0];
   ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
   createFileRw(signal, filePtr);
@@ -11069,6 +11536,7 @@ Dbdih::findBestLogNode(CreateReplicaReco
 {
   ConstPtr<ReplicaRecord> fblFoundReplicaPtr;
   ConstPtr<ReplicaRecord> fblReplicaPtr;
+  LINT_INIT(fblFoundReplicaPtr.p);
   
   /* --------------------------------------------------------------------- */
   /*       WE START WITH ZERO AS FOUND TO ENSURE THAT FIRST HIT WILL BE    */
@@ -11311,6 +11779,7 @@ void Dbdih::initCommonData()
   cnoHotSpare = 0;
   cnoOfActiveTables = 0;
   cnoOfNodeGroups = 0;
+  c_nextNodeGroup = 0;
   cnoReplicas = 0;
   coldgcp = 0;
   coldGcpId = 0;
@@ -11330,6 +11799,7 @@ void Dbdih::initCommonData()
   c_newest_restorable_gci = 0;
   cverifyQueueCounter = 0;
   cwaitLcpSr = false;
+  c_nextLogPart = 0;
 
   nodeResetStart();
   c_nodeStartMaster.wait = ZFALSE;
@@ -11337,7 +11807,7 @@ void Dbdih::initCommonData()
   memset(&sysfileData[0], 0, sizeof(sysfileData));
 
   const ndb_mgm_configuration_iterator * p = 
-    theConfiguration.getOwnConfigIterator();
+    m_ctx.m_config.getOwnConfigIterator();
   ndbrequire(p != 0);
   
   c_lcpState.clcpDelay = 20;
@@ -11409,13 +11879,15 @@ void Dbdih::initRestartInfo() 
   SYSFILE->oldestRestorableGCI = 1;
   SYSFILE->newestRestorableGCI = 1;
   SYSFILE->systemRestartBits   = 0;
-  for (i = 0; i < NodeBitmask::Size; i++) {
+  for (i = 0; i < NdbNodeBitmask::Size; i++) {
     SYSFILE->lcpActive[0]        = 0;
   }//for  
   for (i = 0; i < Sysfile::TAKE_OVER_SIZE; i++) {
     SYSFILE->takeOver[i] = 0;
   }//for
   Sysfile::setInitialStartOngoing(SYSFILE->systemRestartBits);
+  srand(time(0));
+  globalData.m_restart_seq = SYSFILE->m_restart_seq = 0;
 }//Dbdih::initRestartInfo()
 
 /*--------------------------------------------------------------------*/
@@ -11482,7 +11954,7 @@ void Dbdih::initTable(TabRecordPtr tabPt
   tabPtr.p->kvalue = 0;
   tabPtr.p->hashpointer = (Uint32)-1;
   tabPtr.p->mask = 0;
-  tabPtr.p->storedTable = 1;
+  tabPtr.p->tabStorage = TabRecord::ST_NORMAL;
   tabPtr.p->tabErrorCode = 0;
   tabPtr.p->schemaVersion = (Uint32)-1;
   tabPtr.p->tabRemoveNode = RNIL;
@@ -12017,7 +12489,7 @@ void Dbdih::makePrnList(ReadNodesConf * 
     nodePtr.i = nodeArray[i];
     ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRecord);
     new (nodePtr.p) NodeRecord();
-    if (NodeBitmask::get(readNodes->inactiveNodes, nodePtr.i) == false){
+    if (NdbNodeBitmask::get(readNodes->inactiveNodes, nodePtr.i) == false){
       jam();
       nodePtr.p->nodeStatus = NodeRecord::ALIVE;
       nodePtr.p->useInTransactions = true;
@@ -12166,6 +12638,8 @@ void Dbdih::readFragment(RWFragment* rf,
     jam();
     fragPtr.p->distributionKey = TdistKey;
   }//if
+
+  fragPtr.p->m_log_part_id = readPageWord(rf);
 }//Dbdih::readFragment()
 
 Uint32 Dbdih::readPageWord(RWFragment* rf) 
@@ -13100,13 +13574,13 @@ void Dbdih::sendHOT_SPAREREP(Signal* sig
   NodeRecordPtr locNodeptr;
   Uint32 Ti = 0;
   HotSpareRep * const hotSpare = (HotSpareRep*)&signal->theData[0];
-  NodeBitmask::clear(hotSpare->theHotSpareNodes);
+  NdbNodeBitmask::clear(hotSpare->theHotSpareNodes);
   for (locNodeptr.i = 1; locNodeptr.i < MAX_NDB_NODES; locNodeptr.i++) {
     ptrAss(locNodeptr, nodeRecord);
     switch (locNodeptr.p->activeStatus) {
     case Sysfile::NS_HotSpare:
       jam();
-      NodeBitmask::set(hotSpare->theHotSpareNodes, locNodeptr.i);
+      NdbNodeBitmask::set(hotSpare->theHotSpareNodes, locNodeptr.i);
       Ti++;
       break;
     default:
@@ -13128,7 +13602,7 @@ void Dbdih::setNodeLcpActiveStatus()
 {
   c_lcpState.m_lcpActiveStatus.clear();
   for (Uint32 i = 1; i < MAX_NDB_NODES; i++) {
-    if (NodeBitmask::get(SYSFILE->lcpActive, i)) {
+    if (NdbNodeBitmask::get(SYSFILE->lcpActive, i)) {
       jam();
       c_lcpState.m_lcpActiveStatus.set(i);
     }//if
@@ -13201,7 +13675,7 @@ void Dbdih::setNodeRestartInfoBits() 
     Sysfile::setNodeGroup(nodePtr.i, SYSFILE->nodeGroups, tsnrNodeGroup);
     if (c_lcpState.m_participatingLQH.get(nodePtr.i)){
       jam();
-      NodeBitmask::set(SYSFILE->lcpActive, nodePtr.i);
+      NdbNodeBitmask::set(SYSFILE->lcpActive, nodePtr.i);
     }//if
   }//for
 }//Dbdih::setNodeRestartInfoBits()
@@ -13262,6 +13736,7 @@ void Dbdih::writeFragment(RWFragment* wf
   writePageWord(wf, fragPtr.p->noStoredReplicas);
   writePageWord(wf, fragPtr.p->noOldStoredReplicas);
   writePageWord(wf, fragPtr.p->distributionKey);
+  writePageWord(wf, fragPtr.p->m_log_part_id);
 }//Dbdih::writeFragment()
 
 void Dbdih::writePageWord(RWFragment* wf, Uint32 dataWord)
@@ -13328,7 +13803,7 @@ void Dbdih::writeTabfile(Signal* signal,
   signal->theData[0] = filePtr.p->fileRef;
   signal->theData[1] = reference();
   signal->theData[2] = filePtr.i;
-  signal->theData[3] = ZLIST_OF_PAIRS;
+  signal->theData[3] = ZLIST_OF_PAIRS_SYNCH;
   signal->theData[4] = ZVAR_NO_WORD;
   signal->theData[5] = tab->noPages;
   for (Uint32 i = 0; i < tab->noPages; i++) {
@@ -13691,7 +14166,7 @@ Dbdih::execDUMP_STATE_ORD(Signal* signal
     if (signal->getLength() == 1)
     {
       const ndb_mgm_configuration_iterator * p = 
-	theConfiguration.getOwnConfigIterator();
+	m_ctx.m_config.getOwnConfigIterator();
       ndbrequire(p != 0);
       ndb_mgm_get_int_parameter(p, CFG_DB_GCP_INTERVAL, &cgcpDelay);
     }
@@ -14816,13 +15291,14 @@ Dbdih::sendDictLockReq(Signal* signal, U
   {
     Uint32 masterVersion = getNodeInfo(cmasterNodeId).m_version;
 
-    unsigned int get_major = getMajor(masterVersion);
-    unsigned int get_minor = getMinor(masterVersion);
-    unsigned int get_build = getBuild(masterVersion);
-
-    ndbrequire(get_major == 4 || get_major == 5);
+    const unsigned int get_major = getMajor(masterVersion);
+    const unsigned int get_minor = getMinor(masterVersion);
+    const unsigned int get_build = getBuild(masterVersion);
+    ndbrequire(get_major >= 4);
 
     if (masterVersion < NDBD_DICT_LOCK_VERSION_5 ||
+        masterVersion < NDBD_DICT_LOCK_VERSION_5_1 &&
+          get_major == 5 && get_minor == 1 ||
         ERROR_INSERTED(7176)) {
       jam();
 
@@ -14893,10 +15369,13 @@ Dbdih::sendDictUnlockOrd(Signal* signal,
   {
     Uint32 masterVersion = getNodeInfo(cmasterNodeId).m_version;
 
-    unsigned int get_major = getMajor(masterVersion);
-    ndbrequire(get_major == 4 || get_major == 5);
+    const unsigned int get_major = getMajor(masterVersion);
+    const unsigned int get_minor = getMinor(masterVersion);
+    ndbrequire(get_major >= 4);
 
     if (masterVersion < NDBD_DICT_LOCK_VERSION_5 ||
+        masterVersion < NDBD_DICT_LOCK_VERSION_5_1 &&
+          get_major == 5 && get_minor == 1 ||
         ERROR_INSERTED(7176)) {
       return;
     }

--- 1.73.44.1/ndb/src/mgmsrv/MgmtSrvr.cpp	2007-02-14 11:05:31 +07:00
+++ 1.119/storage/ndb/src/mgmsrv/MgmtSrvr.cpp	2007-02-14 11:40:29 +07:00
@@ -36,10 +36,10 @@
 #include <signaldata/EventReport.hpp>
 #include <signaldata/DumpStateOrd.hpp>
 #include <signaldata/BackupSignalData.hpp>
-#include <signaldata/GrepImpl.hpp>
 #include <signaldata/ManagementServer.hpp>
 #include <signaldata/NFCompleteRep.hpp>
 #include <signaldata/NodeFailRep.hpp>
+#include <signaldata/AllocNodeId.hpp>
 #include <NdbSleep.h>
 #include <EventLogger.hpp>
 #include <DebuggerNames.hpp>
@@ -501,10 +501,6 @@ MgmtSrvr::MgmtSrvr(SocketServer *socket_
       case NODE_TYPE_MGM:
 	nodeTypes[id] = NDB_MGM_NODE_TYPE_MGM;
 	break;
-      case NODE_TYPE_REP:
-	nodeTypes[id] = NDB_MGM_NODE_TYPE_REP;
-	break;
-      case NODE_TYPE_EXT_REP:
       default:
 	break;
       }
@@ -587,8 +583,7 @@ MgmtSrvr::start(BaseString &error_string
       DBUG_RETURN(false);
     }
   }
-  theFacade= TransporterFacade::theFacadeInstance
-    = new TransporterFacade();
+  theFacade= new TransporterFacade();
   
   if(theFacade == 0) {
     DEBUG("MgmtSrvr.cpp: theFacade is NULL.");
@@ -743,9 +738,11 @@ MgmtSrvr::start(int nodeId)
  *****************************************************************************/
 
 int 
-MgmtSrvr::versionNode(int nodeId, Uint32 &version, const char **address)
+MgmtSrvr::versionNode(int nodeId, Uint32 &version, Uint32& mysql_version,
+		      const char **address)
 {
   version= 0;
+  mysql_version = 0;
   if (getOwnNodeId() == nodeId)
   {
     /**
@@ -758,8 +755,9 @@ MgmtSrvr::versionNode(int nodeId, Uint32
      * If we don't get an address (i.e. no db nodes),
      * we get the address from the configuration.
      */
-    sendVersionReq(nodeId, version, address);
+    sendVersionReq(nodeId, version, mysql_version, address);
     version= NDB_VERSION;
+    mysql_version = NDB_MYSQL_VERSION_D;
     if(!*address)
     {
       ndb_mgm_configuration_iterator
@@ -779,20 +777,26 @@ MgmtSrvr::versionNode(int nodeId, Uint32
   {
     ClusterMgr::Node node= theFacade->theClusterMgr->getNodeInfo(nodeId);
     if(node.connected)
+    {
       version= node.m_info.m_version;
+      mysql_version = node.m_info.m_mysql_version;
+    }
     *address= get_connect_address(nodeId);
   }
   else if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_API ||
 	   getNodeType(nodeId) == NDB_MGM_NODE_TYPE_MGM)
   {
-    return sendVersionReq(nodeId, version, address);
+    return sendVersionReq(nodeId, version, mysql_version, address);
   }
 
   return 0;
 }
 
 int 
-MgmtSrvr::sendVersionReq(int v_nodeId, Uint32 &version, const char **address)
+MgmtSrvr::sendVersionReq(int v_nodeId, 
+			 Uint32 &version, 
+			 Uint32& mysql_version,
+			 const char **address)
 {
   SignalSender ss(theFacade);
   ss.lock();
@@ -845,6 +849,9 @@ MgmtSrvr::sendVersionReq(int v_nodeId, U
 	CAST_CONSTPTR(ApiVersionConf, signal->getDataPtr());
       assert((int) conf->nodeId == v_nodeId);
       version = conf->version;
+      mysql_version = conf->mysql_version;
+      if (version < NDBD_SPLIT_VERSION)
+	mysql_version = 0;
       struct in_addr in;
       in.s_addr= conf->inet_addr;
       *address= inet_ntoa(in);
@@ -860,7 +867,7 @@ MgmtSrvr::sendVersionReq(int v_nodeId, U
     case GSN_NODE_FAILREP:{
       const NodeFailRep * const rep =
 	CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
-      if (NodeBitmask::get(rep->theNodes,nodeId))
+      if (NdbNodeBitmask::get(rep->theNodes,nodeId))
 	do_send = 1; // retry with other node
       continue;
     }
@@ -959,7 +966,7 @@ int MgmtSrvr::sendStopMgmd(NodeId nodeId
  */
 
 int MgmtSrvr::sendSTOP_REQ(const Vector<NodeId> &node_ids,
-			   NodeBitmask &stoppedNodes,
+			   NdbNodeBitmask &stoppedNodes,
 			   Uint32 singleUserNodeId,
 			   bool abort,
 			   bool stop,
@@ -985,6 +992,15 @@ int MgmtSrvr::sendSTOP_REQ(const Vector<
   StopReq* const stopReq = CAST_PTR(StopReq, ssig.getDataPtrSend());
   ssig.set(ss, TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ, StopReq::SignalLength);
 
+  NdbNodeBitmask notstarted;
+  for (Uint32 i = 0; i<node_ids.size(); i++)
+  {
+    Uint32 nodeId = node_ids[i];
+    ClusterMgr::Node node = theFacade->theClusterMgr->getNodeInfo(nodeId);
+    if (node.m_state.startLevel != NodeState::SL_STARTED)
+      notstarted.set(nodeId);
+  }
+  
   stopReq->requestInfo = 0;
   stopReq->apiTimeout = 5000;
   stopReq->transactionTimeout = 1000;
@@ -1011,7 +1027,7 @@ int MgmtSrvr::sendSTOP_REQ(const Vector<
   }
 
   // send the signals
-  NodeBitmask nodes;
+  NdbNodeBitmask nodes;
   NodeId nodeId= 0;
   int use_master_node= 0;
   int do_send= 0;
@@ -1155,6 +1171,14 @@ int MgmtSrvr::sendSTOP_REQ(const Vector<
     case GSN_NODE_FAILREP:{
       const NodeFailRep * const rep =
 	CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
+      NdbNodeBitmask mask;
+      char buf[100];
+      mask.assign(NdbNodeBitmask::Size, rep->theNodes);
+      mask.bitAND(notstarted);
+      nodes.bitANDC(mask);
+      
+      if (singleUserNodeId == 0)
+	stoppedNodes.bitOR(mask);
       break;
     }
     default:
@@ -1191,7 +1215,7 @@ int MgmtSrvr::stopNodes(const Vector<Nod
 	return OPERATION_NOT_ALLOWED_START_STOP;
     }
   }
-  NodeBitmask nodes;
+  NdbNodeBitmask nodes;
   int ret= sendSTOP_REQ(node_ids,
                         nodes,
                         0,
@@ -1234,7 +1258,7 @@ int MgmtSrvr::shutdownMGM(int *stopCount
 
 int MgmtSrvr::shutdownDB(int * stopCount, bool abort)
 {
-  NodeBitmask nodes;
+  NdbNodeBitmask nodes;
   Vector<NodeId> node_ids;
 
   int tmp;
@@ -1270,7 +1294,7 @@ int MgmtSrvr::enterSingleUser(int * stop
        (node.m_state.startLevel != NodeState::SL_NOTHING))
       return OPERATION_NOT_ALLOWED_START_STOP;
   }
-  NodeBitmask nodes;
+  NdbNodeBitmask nodes;
   Vector<NodeId> node_ids;
   int stopSelf;
   int ret = sendSTOP_REQ(node_ids,
@@ -1296,7 +1320,7 @@ int MgmtSrvr::restartNodes(const Vector<
                            bool initialStart, bool abort,
                            int *stopSelf)
 {
-  NodeBitmask nodes;
+  NdbNodeBitmask nodes;
   int ret= sendSTOP_REQ(node_ids,
                         nodes,
                         0,
@@ -1327,10 +1351,11 @@ int MgmtSrvr::restartNodes(const Vector<
     while (s != NDB_MGM_NODE_STATUS_NOT_STARTED && waitTime > 0)
     {
       Uint32 startPhase = 0, version = 0, dynamicId = 0, nodeGroup = 0;
+      Uint32 mysql_version = 0;
       Uint32 connectCount = 0;
       bool system;
       const char *address;
-      status(nodeId, &s, &version, &startPhase, 
+      status(nodeId, &s, &version, &mysql_version, &startPhase, 
              &system, &dynamicId, &nodeGroup, &connectCount, &address);
       NdbSleep_MilliSleep(100);  
       waitTime = (maxTime - NdbTick_CurrentMillisecond());
@@ -1354,7 +1379,7 @@ int MgmtSrvr::restartNodes(const Vector<
 int MgmtSrvr::restartDB(bool nostart, bool initialStart,
                         bool abort, int * stopCount)
 {
-  NodeBitmask nodes;
+  NdbNodeBitmask nodes;
   Vector<NodeId> node_ids;
   int tmp;
 
@@ -1395,10 +1420,11 @@ int MgmtSrvr::restartDB(bool nostart, bo
 #endif
     while (s != NDB_MGM_NODE_STATUS_NOT_STARTED && waitTime > 0) {
       Uint32 startPhase = 0, version = 0, dynamicId = 0, nodeGroup = 0;
+      Uint32 mysql_version = 0;
       Uint32 connectCount = 0;
       bool system;
       const char *address;
-      status(nodeId, &s, &version, &startPhase, 
+      status(nodeId, &s, &version, &mysql_version, &startPhase, 
 	     &system, &dynamicId, &nodeGroup, &connectCount, &address);
       NdbSleep_MilliSleep(100);  
       waitTime = (maxTime - NdbTick_CurrentMillisecond());
@@ -1477,6 +1503,7 @@ int 
 MgmtSrvr::status(int nodeId, 
                  ndb_mgm_node_status * _status, 
 		 Uint32 * version,
+		 Uint32 * mysql_version,
 		 Uint32 * _phase, 
 		 bool * _system,
 		 Uint32 * dynamic,
@@ -1486,7 +1513,7 @@ MgmtSrvr::status(int nodeId, 
 {
   if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_API ||
       getNodeType(nodeId) == NDB_MGM_NODE_TYPE_MGM) {
-    versionNode(nodeId, *version, address);
+    versionNode(nodeId, *version, *mysql_version, address);
   } else {
     *address= get_connect_address(nodeId);
   }
@@ -1501,6 +1528,7 @@ MgmtSrvr::status(int nodeId, 
   
   if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_NDB) {
     * version = node.m_info.m_version;
+    * mysql_version = node.m_info.m_mysql_version;
   }
 
   * dynamic = node.m_state.dynamicId;
@@ -1948,10 +1976,7 @@ MgmtSrvr::handleReceivedSignal(NdbApiSig
     break;
   case GSN_EVENT_REP:
   {
-    EventReport *rep = (EventReport*) signal->getDataPtr();
-    if (rep->getNodeId() == 0)
-      rep->setNodeId(refToNode(signal->theSendersBlockRef));
-    eventReport(signal->getDataPtr());
+    eventReport(signal->getDataPtr(), signal->getLength());
     break;
   }
 
@@ -1994,9 +2019,8 @@ MgmtSrvr::handleStatus(NodeId nodeId, bo
       DBUG_VOID_RETURN;
     }
   }
-  
   rep->setNodeId(_ownNodeId);
-  eventReport(theData);
+  eventReport(theData, 1);
   DBUG_VOID_RETURN;
 }
 
@@ -2056,7 +2080,7 @@ MgmtSrvr::get_connected_nodes(NodeBitmas
 {
   if (theFacade && theFacade->theClusterMgr) 
   {
-    for(Uint32 i = 0; i < MAX_NODES; i++)
+    for(Uint32 i = 0; i < MAX_NDB_NODES; i++)
     {
       if (getNodeType(i) == NDB_MGM_NODE_TYPE_NDB)
       {
@@ -2067,6 +2091,92 @@ MgmtSrvr::get_connected_nodes(NodeBitmas
   }
 }
 
+int
+MgmtSrvr::alloc_node_id_req(NodeId free_node_id, enum ndb_mgm_node_type type)
+{
+  SignalSender ss(theFacade);
+  ss.lock(); // lock will be released on exit
+
+  SimpleSignal ssig;
+  AllocNodeIdReq* req = CAST_PTR(AllocNodeIdReq, ssig.getDataPtrSend());
+  ssig.set(ss, TestOrd::TraceAPI, QMGR, GSN_ALLOC_NODEID_REQ,
+	   AllocNodeIdReq::SignalLength);
+  
+  req->senderRef = ss.getOwnRef();
+  req->senderData = 19;
+  req->nodeId = free_node_id;
+  req->nodeType = type;
+
+  int do_send = 1;
+  NodeId nodeId = 0;
+  while (1)
+  {
+    if (nodeId == 0)
+    {
+      bool next;
+      while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true &&
+            theFacade->get_node_alive(nodeId) == false);
+      if (!next)
+        return NO_CONTACT_WITH_DB_NODES;
+      do_send = 1;
+    }
+    if (do_send)
+    {
+      if (ss.sendSignal(nodeId, &ssig) != SEND_OK) {
+        return SEND_OR_RECEIVE_FAILED;
+      }
+      do_send = 0;
+    }
+    
+    SimpleSignal *signal = ss.waitFor();
+
+    int gsn = signal->readSignalNumber();
+    switch (gsn) {
+    case GSN_ALLOC_NODEID_CONF:
+    {
+      const AllocNodeIdConf * const conf =
+        CAST_CONSTPTR(AllocNodeIdConf, signal->getDataPtr());
+      return 0;
+    }
+    case GSN_ALLOC_NODEID_REF:
+    {
+      const AllocNodeIdRef * const ref =
+        CAST_CONSTPTR(AllocNodeIdRef, signal->getDataPtr());
+      if (ref->errorCode == AllocNodeIdRef::NotMaster ||
+          ref->errorCode == AllocNodeIdRef::Busy)
+      {
+        do_send = 1;
+        nodeId = refToNode(ref->masterRef);
+        continue;
+      }
+      return ref->errorCode;
+    }
+    case GSN_NF_COMPLETEREP:
+    {
+      const NFCompleteRep * const rep =
+        CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr());
+#ifdef VM_TRACE
+      ndbout_c("Node %d fail completed", rep->failedNodeId);
+#endif
+      if (rep->failedNodeId == nodeId)
+      {
+	do_send = 1;
+        nodeId = 0;
+      }
+      continue;
+    }
+    case GSN_NODE_FAILREP:{
+      // ignore NF_COMPLETEREP will come
+      continue;
+    }
+    default:
+      report_unknown_signal(signal);
+      return SEND_OR_RECEIVE_FAILED;
+    }
+  }
+  return 0;
+}
+
 bool
 MgmtSrvr::alloc_node_id(NodeId * nodeId, 
 			enum ndb_mgm_node_type type,
@@ -2197,6 +2307,39 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId,
   }
   NdbMutex_Unlock(m_configMutex);
 
+  if (id_found && client_addr != 0)
+  {
+    int res = alloc_node_id_req(id_found, type);
+    unsigned save_id_found = id_found;
+    switch (res)
+    {
+    case 0:
+      // ok continue
+      break;
+    case NO_CONTACT_WITH_DB_NODES:
+      // ok continue
+      break;
+    default:
+      // something wrong
+      id_found = 0;
+      break;
+
+    }
+    if (id_found == 0)
+    {
+      char buf[128];
+      ndb_error_string(res, buf, sizeof(buf));
+      error_string.appfmt("Cluster refused allocation of id %d. Error: %d (%s).",
+			  save_id_found, res, buf);
+      g_eventLogger.warning("Cluster refused allocation of id %d. "
+                            "Connection from ip %s. "
+                            "Returned error string \"%s\"", save_id_found,
+                            inet_ntoa(((struct sockaddr_in *)(client_addr))->sin_addr),
+                            error_string.c_str());
+      DBUG_RETURN(false);
+    }
+  }
+
   if (id_found)
   {
     *nodeId= id_found;
@@ -2384,16 +2527,16 @@ MgmtSrvr::getNextNodeId(NodeId * nodeId,
 #include "Services.hpp"
 
 void
-MgmtSrvr::eventReport(const Uint32 * theData)
+MgmtSrvr::eventReport(const Uint32 * theData, Uint32 len)
 {
   const EventReport * const eventReport = (EventReport *)&theData[0];
   
   NodeId nodeId = eventReport->getNodeId();
   Ndb_logevent_type type = eventReport->getEventType();
   // Log event
-  g_eventLogger.log(type, theData, nodeId, 
+  g_eventLogger.log(type, theData, len, nodeId, 
 		    &m_event_listner[0].m_logLevel);  
-  m_event_listner.log(type, theData, nodeId);
+  m_event_listner.log(type, theData, len, nodeId);
 }
 
 /***************************************************************************
@@ -2463,7 +2606,7 @@ MgmtSrvr::startBackup(Uint32& backupId, 
       const BackupCompleteRep * const rep = 
 	CAST_CONSTPTR(BackupCompleteRep, signal->getDataPtr());
 #ifdef VM_TRACE
-      ndbout_c("Backup(%d) completed %d", rep->backupId);
+      ndbout_c("Backup(%d) completed", rep->backupId);
 #endif
       event.Event = BackupEvent::BackupCompleted;
       event.Completed.BackupId = rep->backupId;
@@ -2528,7 +2671,7 @@ MgmtSrvr::startBackup(Uint32& backupId, 
     case GSN_NODE_FAILREP:{
       const NodeFailRep * const rep =
 	CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
-      if (NodeBitmask::get(rep->theNodes,nodeId) ||
+      if (NdbNodeBitmask::get(rep->theNodes,nodeId) ||
 	  waitCompleted == 1)
 	return 1326;
       // wait for next signal
@@ -2571,17 +2714,6 @@ MgmtSrvr::abortBackup(Uint32 backupId)
 }
 
 
-/*****************************************************************************
- * Global Replication
- *****************************************************************************/
-
-int
-MgmtSrvr::repCommand(Uint32* repReqId, Uint32 request, bool waitCompleted)
-{
-  require(false);
-  return 0;
-}
-
 MgmtSrvr::Allocated_resources::Allocated_resources(MgmtSrvr &m)
   : m_mgmsrv(m)
 {
@@ -2730,7 +2862,7 @@ MgmtSrvr::setDbParameter(int node, int p
       break;
     case 1:
       res = i2.set(param, val_64);
-      ndbout_c("Updating node %d param: %d to %Ld",  node, param, val_32);
+      ndbout_c("Updating node %d param: %d to %u",  node, param, val_32);
       break;
     case 2:
       res = i2.set(param, val_char);

--- 1.17.11.1/ndb/src/ndbapi/ClusterMgr.cpp	2007-02-14 11:05:31 +07:00
+++ 1.37/storage/ndb/src/ndbapi/ClusterMgr.cpp	2007-02-14 11:40:29 +07:00
@@ -36,6 +36,7 @@
 #include <mgmapi_configuration.hpp>
 #include <mgmapi_config_parameters.h>
 
+int global_flag_skip_invalidate_cache = 0;
 //#define DEBUG_REG
 
 // Just a C wrapper for threadMain
@@ -44,15 +45,7 @@ void*
 runClusterMgr_C(void * me)
 {
   ((ClusterMgr*) me)->threadMain();
-  /** 
-   * Sleep to allow another thread that is not exiting to take control 
-   * of signals allocated by this thread
-   *
-   * see Ndb::~Ndb() in Ndbinit.cpp
-   */  
-#ifdef NDB_OSE
-  NdbSleep_MilliSleep(50);
-#endif
+
   return NULL;
 }
 
@@ -72,6 +65,7 @@ ClusterMgr::ClusterMgr(TransporterFacade
   noOfConnectedNodes= 0;
   theClusterMgrThread= 0;
   m_connect_count = 0;
+  m_cluster_state = CS_waiting_for_clean_cache;
   DBUG_VOID_RETURN;
 }
 
@@ -112,18 +106,6 @@ ClusterMgr::init(ndb_mgm_configuration_i
     case NODE_TYPE_MGM:
       theNodes[tmp].m_info.m_type = NodeInfo::MGM;
       break;
-    case NODE_TYPE_REP:
-      theNodes[tmp].m_info.m_type = NodeInfo::REP;
-      break;
-    case NODE_TYPE_EXT_REP:
-      theNodes[tmp].m_info.m_type = NodeInfo::REP;
-      {
-	Uint32 hbFreq = 10000;
-	//ndb_mgm_get_int_parameter(iter, CFG_, &hbFreq);
-	theNodes[tmp].hbFrequency = hbFreq;
-	assert(100 <= hbFreq && hbFreq < 60 * 60 * 1000);
-      }
-      break;
     default:
       type = type;
 #if 0
@@ -182,7 +164,7 @@ ClusterMgr::forceHB()
     NodeBitmask ndb_nodes;
     ndb_nodes.clear();
     waitForHBFromNodes.clear();
-    for(Uint32 i = 0; i < MAX_NODES; i++)
+    for(Uint32 i = 0; i < MAX_NDB_NODES; i++)
     {
       if(!theNodes[i].defined)
         continue;
@@ -209,6 +191,7 @@ ClusterMgr::forceHB()
     ApiRegReq * req = CAST_PTR(ApiRegReq, signal.getDataPtrSend());
     req->ref = numberToRef(API_CLUSTERMGR, theFacade.ownId());
     req->version = NDB_VERSION;
+    req->mysql_version = NDB_MYSQL_VERSION_D;
 
     int nodeId= 0;
     for(int i=0;
@@ -241,7 +224,7 @@ ClusterMgr::threadMain( ){
   ApiRegReq * req = CAST_PTR(ApiRegReq, signal.getDataPtrSend());
   req->ref = numberToRef(API_CLUSTERMGR, theFacade.ownId());
   req->version = NDB_VERSION;
-
+  req->mysql_version = NDB_MYSQL_VERSION_D;
   
   Uint32 timeSlept = 100;
   Uint64 now = NdbTick_CurrentMillisecond();
@@ -250,8 +233,18 @@ ClusterMgr::threadMain( ){
     /**
      * Start of Secure area for use of Transporter
      */
+    if (m_cluster_state == CS_waiting_for_clean_cache)
+    {
+      theFacade.m_globalDictCache.lock();
+      unsigned sz= theFacade.m_globalDictCache.get_size();
+      theFacade.m_globalDictCache.unlock();
+      if (sz)
+        goto next;
+      m_cluster_state = CS_waiting_for_first_connect;
+    }
+
     theFacade.lock_mutex();
-    for (int i = 1; i < MAX_NODES; i++){
+    for (int i = 1; i < MAX_NDB_NODES; i++){
       /**
        * Send register request (heartbeat) to all available nodes 
        * at specified timing intervals
@@ -281,13 +274,6 @@ ClusterMgr::threadMain( ){
 	  theNode.hbCounter = 0;
 	}
 
-	/**
-	 * If the node is of type REP, 
-	 * then the receiver of the signal should be API_CLUSTERMGR
-	 */
-	if (theNode.m_info.m_type == NodeInfo::REP) {
-	  signal.theReceiversBlockNumber = API_CLUSTERMGR;
-	}
 #ifdef DEBUG_REG
 	ndbout_c("ClusterMgr: Sending API_REGREQ to node %d", (int)nodeId);
 #endif
@@ -304,6 +290,7 @@ ClusterMgr::threadMain( ){
      */
     theFacade.unlock_mutex();
     
+next:
     // Sleep for 100 ms between each Registration Heartbeat
     Uint64 before = now;
     NdbSleep_MilliSleep(100); 
@@ -370,6 +357,7 @@ ClusterMgr::execAPI_REGREQ(const Uint32 
   ApiRegConf * const conf = CAST_PTR(ApiRegConf, signal.getDataPtrSend());
   conf->qmgrRef = numberToRef(API_CLUSTERMGR, theFacade.ownId());
   conf->version = NDB_VERSION;
+  conf->mysql_version = NDB_MYSQL_VERSION_D;
   conf->apiHeartbeatFrequency = node.hbFrequency;
   theFacade.sendSignalUnCond(&signal, nodeId);
 }
@@ -385,7 +373,7 @@ ClusterMgr::execAPI_REGCONF(const Uint32
   ndbout_c("ClusterMgr: Recd API_REGCONF from node %d", nodeId);
 #endif
 
-  assert(nodeId > 0 && nodeId < MAX_NODES);
+  assert(nodeId > 0 && nodeId < MAX_NDB_NODES);
   
   Node & node = theNodes[nodeId];
   assert(node.defined == true);
@@ -393,6 +381,10 @@ ClusterMgr::execAPI_REGCONF(const Uint32
 
   if(node.m_info.m_version != apiRegConf->version){
     node.m_info.m_version = apiRegConf->version;
+    node.m_info.m_mysql_version = apiRegConf->mysql_version;
+    if (node.m_info.m_version < NDBD_SPLIT_VERSION)
+      node.m_info.m_mysql_version = 0;
+        
     if (global_mgmt_server_check == 1)
       node.compatible = ndbCompatible_mgmt_ndb(NDB_VERSION,
 					       node.m_info.m_version);
@@ -403,7 +395,18 @@ ClusterMgr::execAPI_REGCONF(const Uint32
 
   node.m_api_reg_conf = true;
 
-  node.m_state = apiRegConf->nodeState;
+  if (node.m_info.m_version >= NDBD_255_NODES_VERSION)
+  {
+    node.m_state = apiRegConf->nodeState;
+  }
+  else
+  {
+    /**
+     * from 2 to 8 words = 6 words diff, 6*4 = 24
+     */
+    memcpy(&node.m_state, &apiRegConf->nodeState, sizeof(node.m_state) - 24);
+  }
+  
   if (node.compatible && (node.m_state.startLevel == NodeState::SL_STARTED  ||
 			  node.m_state.startLevel == NodeState::SL_SINGLEUSER)){
     set_node_alive(node, true);
@@ -412,9 +415,6 @@ ClusterMgr::execAPI_REGCONF(const Uint32
   }//if
   node.m_info.m_heartbeat_cnt = 0;
   node.hbCounter = 0;
-  if (node.m_info.m_type != NodeInfo::REP) {
-    node.hbFrequency = (apiRegConf->apiHeartbeatFrequency * 10) - 50;
-  }
 
   if(waitingForHB)
   {
@@ -426,6 +426,7 @@ ClusterMgr::execAPI_REGCONF(const Uint32
       NdbCondition_Broadcast(waitForHBCond);
     }
   }
+  node.hbFrequency = (apiRegConf->apiHeartbeatFrequency * 10) - 50;
 }
 
 void
@@ -435,7 +436,7 @@ ClusterMgr::execAPI_REGREF(const Uint32 
   
   const NodeId nodeId = refToNode(ref->ref);
   
-  assert(nodeId > 0 && nodeId < MAX_NODES);
+  assert(nodeId > 0 && nodeId < MAX_NDB_NODES);
   
   Node & node = theNodes[nodeId];
   assert(node.connected == true);
@@ -463,8 +464,8 @@ ClusterMgr::execAPI_REGREF(const Uint32 
 void
 ClusterMgr::execNODE_FAILREP(const Uint32 * theData){
   NodeFailRep * const nodeFail = (NodeFailRep *)&theData[0];
-  for(int i = 1; i<MAX_NODES; i++){
-    if(NodeBitmask::get(nodeFail->theNodes, i)){
+  for(int i = 1; i<MAX_NDB_NODES; i++){
+    if(NdbNodeBitmask::get(nodeFail->theNodes, i)){
       reportNodeFailed(i);
     }
   }
@@ -475,7 +476,7 @@ ClusterMgr::execNF_COMPLETEREP(const Uin
   NFCompleteRep * const nfComp = (NFCompleteRep *)theData;
 
   const NodeId nodeId = nfComp->failedNodeId;
-  assert(nodeId > 0 && nodeId < MAX_NODES);
+  assert(nodeId > 0 && nodeId < MAX_NDB_NODES);
   
   theFacade.ReportNodeFailureComplete(nodeId);
   theNodes[nodeId].nfCompleteRep = true;
@@ -483,12 +484,14 @@ ClusterMgr::execNF_COMPLETEREP(const Uin
 
 void
 ClusterMgr::reportConnected(NodeId nodeId){
+  DBUG_ENTER("ClusterMgr::reportConnected");
+  DBUG_PRINT("info", ("nodeId: %u", nodeId));
   /**
    * Ensure that we are sending heartbeat every 100 ms
    * until we have got the first reply from NDB providing
    * us with the real time-out period to use.
    */
-  assert(nodeId > 0 && nodeId < MAX_NODES);
+  assert(nodeId > 0 && nodeId < MAX_NDB_NODES);
 
   noOfConnectedNodes++;
 
@@ -502,21 +505,19 @@ ClusterMgr::reportConnected(NodeId nodeI
    * if first API_REGCONF has not arrived
    */
   theNode.m_state.m_connected_nodes.set(nodeId);
-
-  if (theNode.m_info.m_type != NodeInfo::REP) {
-    theNode.hbFrequency = 0;
-  }
+  theNode.hbFrequency = 0;
   theNode.m_info.m_version = 0;
   theNode.compatible = true;
   theNode.nfCompleteRep = true;
   theNode.m_state.startLevel = NodeState::SL_NOTHING;
   
   theFacade.ReportNodeAlive(nodeId);
+  DBUG_VOID_RETURN;
 }
 
 void
 ClusterMgr::reportDisconnected(NodeId nodeId){
-  assert(nodeId > 0 && nodeId < MAX_NODES);
+  assert(nodeId > 0 && nodeId < MAX_NDB_NODES);
   assert(noOfConnectedNodes > 0);
 
   noOfConnectedNodes--;
@@ -551,12 +552,16 @@ ClusterMgr::reportNodeFailed(NodeId node
   theNode.nfCompleteRep = false;
   if(noOfAliveNodes == 0)
   {
-    theFacade.m_globalDictCache.lock();
-    theFacade.m_globalDictCache.invalidate_all();
-    theFacade.m_globalDictCache.unlock();
-    m_connect_count ++;
+    if (!global_flag_skip_invalidate_cache)
+    {
+      theFacade.m_globalDictCache.lock();
+      theFacade.m_globalDictCache.invalidate_all();
+      theFacade.m_globalDictCache.unlock();
+      m_connect_count ++;
+      m_cluster_state = CS_waiting_for_clean_cache;
+    }
     NFCompleteRep rep;
-    for(Uint32 i = 1; i<MAX_NODES; i++){
+    for(Uint32 i = 1; i<MAX_NDB_NODES; i++){
       if(theNodes[i].defined && theNodes[i].nfCompleteRep == false){
 	rep.failedNodeId = i;
 	execNF_COMPLETEREP((Uint32*)&rep);

--- 1.4.8.1/ndb/src/ndbapi/ClusterMgr.hpp	2007-02-14 11:05:31 +07:00
+++ 1.17/storage/ndb/src/ndbapi/ClusterMgr.hpp	2007-02-14 11:32:11 +07:00
@@ -58,6 +58,11 @@ private:
   class TransporterFacade & theFacade;
   
 public:
+  enum Cluster_state {
+    CS_waiting_for_clean_cache = 0,
+    CS_waiting_for_first_connect,
+    CS_connected
+  };
   struct Node {
     Node();
     bool defined;
@@ -79,6 +84,7 @@ public:
   
   const Node &  getNodeInfo(NodeId) const;
   Uint32        getNoOfConnectedNodes() const;
+  bool          isClusterAlive() const;
   void          hb_received(NodeId);
 
   Uint32        m_connect_count;
@@ -92,6 +98,7 @@ private:
   NdbCondition* waitForHBCond;
   bool          waitingForHB;
 
+  enum Cluster_state m_cluster_state;
   /**
    * Used for controlling start/stop of the thread
    */
@@ -136,6 +143,11 @@ ClusterMgr::getNoOfConnectedNodes() cons
 }
 
 inline
+bool
+ClusterMgr::isClusterAlive() const {
+  return noOfAliveNodes != 0;
+}
+inline
 void
 ClusterMgr::hb_received(NodeId nodeId) {
   theNodes[nodeId].m_info.m_heartbeat_cnt= 0;
@@ -179,6 +191,8 @@ private:
     GlobalSignalNumber gsn;
     ArbitSignalData data;
     NDB_TICKS timestamp;
+
+    ArbitSignal() {}
 
     inline void init(GlobalSignalNumber aGsn, const Uint32* aData) {
       gsn = aGsn;

--- 1.3.6.1/ndb/src/ndbapi/SignalSender.cpp	2007-02-14 11:05:31 +07:00
+++ 1.12/storage/ndb/src/ndbapi/SignalSender.cpp	2007-02-14 11:40:29 +07:00
@@ -138,17 +138,6 @@ SignalSender::getNoOfConnectedNodes() co
   return theFacade->theClusterMgr->getNoOfConnectedNodes();
 }
 
-SendStatus
-SignalSender::sendSignal(Uint16 nodeId, const SimpleSignal * s){
-  assert(getNodeInfo(nodeId).m_api_reg_conf == true ||
-         s->readSignalNumber() == GSN_API_REGREQ);
-  return theFacade->theTransporterRegistry->prepareSend(&s->header,
-							1, // JBB
-							&s->theData[0],
-							nodeId, 
-							&s->ptr[0]);
-}
-
 template<class T>
 SimpleSignal *
 SignalSender::waitFor(Uint32 timeOutMillis, T & t)
@@ -276,8 +265,8 @@ SignalSender::execNodeStatus(void* signa
     rep->failNo = 0;
     rep->masterNodeId = 0;
     rep->noOfNodes = 1;
-    NodeBitmask::clear(rep->theNodes);
-    NodeBitmask::set(rep->theNodes,nodeId);
+    NdbNodeBitmask::clear(rep->theNodes);
+    NdbNodeBitmask::set(rep->theNodes,nodeId);
   }
 
   ss->m_jobBuffer.push_back(s);
Thread
bk commit into 5.1 tree (tomas:1.2415)tomas14 Feb