---
 storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp         |   79 ++---------
 storage/ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp     |    5 
 storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp |   35 ++++
 storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp           |    1 
 storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp       |   88 ++++++++++--
 storage/ndb/test/ndbapi/test_event.cpp                |  128 ++++++++++++++----
 6 files changed, 240 insertions(+), 96 deletions(-)

Index: drop6/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp
===================================================================
--- drop6.orig/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp	2008-02-27 12:31:38.000000000 +0100
+++ drop6/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp	2008-02-27 12:32:45.000000000 +0100
@@ -392,13 +392,6 @@ void Cmvmi::execSTTOR(Signal* signal)
                           signal, 100, len);
       return;
     }
-    /*---------------------------------------------------*/
-    /* Open com to API + REP nodes                       */
-    /*---------------------------------------------------*/
-    signal->theData[0] = 0; // no answer
-    signal->theData[1] = 0; // no id
-    signal->theData[2] = NodeInfo::API;
-    execOPEN_COMREQ(signal);
     globalData.theStartLevel = NodeState::SL_STARTED;
     sendSTTORRY(signal);
   }
@@ -461,14 +454,6 @@ void Cmvmi::execOPEN_COMREQ(Signal* sign
 	   && c_error_9000_nodes_mask.get(tStartingNode)))
 #endif
     {
-      if (globalData.theStartLevel != NodeState::SL_STARTED &&
-          (getNodeInfo(tStartingNode).m_type != NodeInfo::DB &&
-           getNodeInfo(tStartingNode).m_type != NodeInfo::MGM))
-      {
-        jam();
-        goto done;
-      }
-
       globalTransporterRegistry.do_connect(tStartingNode);
       globalTransporterRegistry.setIOState(tStartingNode, HaltIO);
       
@@ -493,7 +478,6 @@ void Cmvmi::execOPEN_COMREQ(Signal* sign
 	    && c_error_9000_nodes_mask.get(i))
 	  continue;
 #endif
-	
 	globalTransporterRegistry.do_connect(i);
 	globalTransporterRegistry.setIOState(i, HaltIO);
 	
@@ -565,37 +549,13 @@ void Cmvmi::execCONNECT_REP(Signal *sign
   globalData.m_nodeInfo[hostId].m_version = 0;
   globalData.m_nodeInfo[hostId].m_signalVersion = 0;
   
-  if(type == NodeInfo::DB || globalData.theStartLevel >= NodeState::SL_STARTED){
-    jam();
-    
-    /**
-     * Inform QMGR that client has connected
-     */
+  signal->theData[0] = hostId;
+  sendSignal(QMGR_REF, GSN_CONNECT_REP, signal, 1, JBA);
 
-    signal->theData[0] = hostId;
-    sendSignal(QMGR_REF, GSN_CONNECT_REP, signal, 1, JBA);
-  } else if(globalData.theStartLevel == NodeState::SL_CMVMI ||
-            globalData.theStartLevel == NodeState::SL_STARTING) {
-    jam();
-    /**
-     * Someone connected before start was finished
-     */
-    if(type == NodeInfo::MGM){
-      jam();
-      signal->theData[0] = hostId;
-      sendSignal(QMGR_REF, GSN_CONNECT_REP, signal, 1, JBA);
-    } else {
-      /**
-       * Dont allow api nodes to connect
-       */
-      abort();
-      globalTransporterRegistry.do_disconnect(hostId);
-    }
-  }
-  
   /* Automatically subscribe events for MGM nodes.
    */
-  if(type == NodeInfo::MGM){
+  if(type == NodeInfo::MGM)
+  {
     jam();
     globalTransporterRegistry.setIOState(hostId, NoHalt);
   }
@@ -801,26 +761,16 @@ Cmvmi::execSTART_ORD(Signal* signal) {
     return;
   }
   
-  if(globalData.theStartLevel == NodeState::SL_NOTHING){
+  if(globalData.theStartLevel == NodeState::SL_NOTHING)
+  {
     jam();
     globalData.theStartLevel = NodeState::SL_CMVMI;
-    /**
-     * Open connections to management servers
-     */
-    for(unsigned int i = 1; i < MAX_NODES; i++ ){
-      if (getNodeInfo(i).m_type == NodeInfo::MGM){ 
-        if(!globalTransporterRegistry.is_connected(i)){
-          globalTransporterRegistry.do_connect(i);
-          globalTransporterRegistry.setIOState(i, NoHalt);
-        }
-      }
-    }
-
     EXECUTE_DIRECT(QMGR, GSN_START_ORD, signal, 1);
     return ;
   }
   
-  if(globalData.theStartLevel == NodeState::SL_CMVMI){
+  if(globalData.theStartLevel == NodeState::SL_CMVMI)
+  {
     jam();
 
     if(theConfig.lockPagesInMainMemory() == 2)
@@ -848,8 +798,10 @@ Cmvmi::execSTART_ORD(Signal* signal) {
     // Disconnect all nodes as part of the system restart. 
     // We need to ensure that we are starting up
     // without any connected nodes.   
-    for(unsigned int i = 1; i < MAX_NODES; i++ ){
-      if (i != getOwnNodeId() && getNodeInfo(i).m_type != NodeInfo::MGM){
+    for(unsigned int i = 1; i < MAX_NODES; i++ )
+    {
+      if (i != getOwnNodeId() && getNodeInfo(i).m_type != NodeInfo::MGM)
+      {
         globalTransporterRegistry.do_disconnect(i);
         globalTransporterRegistry.setIOState(i, HaltIO);
       }
@@ -1234,6 +1186,13 @@ Cmvmi::execDUMP_STATE_ORD(Signal* signal
     c_error_9000_nodes_mask.clear();
     c_error_9000_nodes_mask.set(signal->theData[1]);
   }
+
+  if (arg == 9004 && signal->getLength() == 2)
+  {
+    SET_ERROR_INSERT_VALUE(9004);
+    c_error_9000_nodes_mask.clear();
+    c_error_9000_nodes_mask.set(signal->theData[1]);
+  }
 #endif
 
 #ifdef VM_TRACE
Index: drop6/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp
===================================================================
--- drop6.orig/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp	2008-02-27 12:19:01.000000000 +0100
+++ drop6/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp	2008-02-27 12:32:45.000000000 +0100
@@ -419,6 +419,7 @@ private:
   Uint16 cnoPrepFailedNodes;
   Uint16 cnoCommitFailedNodes;
   Uint16 cactivateApiCheck;
+  Uint16 c_allow_api_connect;
   UintR chbApiDelay;
 
   UintR ccommitFailureNr;
Index: drop6/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
===================================================================
--- drop6.orig/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp	2008-02-27 12:19:01.000000000 +0100
+++ drop6/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp	2008-02-27 13:33:22.000000000 +0100
@@ -251,15 +251,35 @@ Qmgr::execSTART_ORD(Signal* signal)
   {
     ptrAss(nodePtr, nodeRec);
     nodePtr.p->ndynamicId = 0;	
-    if(getNodeInfo(nodePtr.i).m_type == NodeInfo::DB)
-    {
+    Uint32 cnt = 0;
+    Uint32 type = getNodeInfo(nodePtr.i).m_type;
+    switch(type){
+    case NodeInfo::DB:
+      jam();
       nodePtr.p->phase = ZINIT;
       c_definedNodes.set(nodePtr.i);
-    } else {
+      break;
+    case NodeInfo::API:
+      jam();
+      nodePtr.p->phase = ZAPI_INACTIVE;
+      break;
+    case NodeInfo::MGM:
+      jam();
+      /**
+       * Enable communication to MGM direcly
+       *   by setting ZFAIL_CLOSING (picked up in checkStartInterface)
+       */
+      ndbout_c("enable node %u", nodePtr.i);
+      cnt = 3;
+      nodePtr.p->phase = ZFAIL_CLOSING;
+      nodePtr.p->failState = NORMAL;
+      break;
+    default:
+      jam();
       nodePtr.p->phase = ZAPI_INACTIVE;
     }
     
-    setNodeInfo(nodePtr.i).m_heartbeat_cnt= 0;
+    setNodeInfo(nodePtr.i).m_heartbeat_cnt = cnt;
     nodePtr.p->sendPrepFailReqStatus = Q_NOT_ACTIVE;
     nodePtr.p->sendCommitFailReqStatus = Q_NOT_ACTIVE;
     nodePtr.p->sendPresToStatus = Q_NOT_ACTIVE;
@@ -312,6 +332,30 @@ void Qmgr::execSTTOR(Signal* signal) 
       }
     }
     break;
+  case 8:{
+    /**
+     * Enable communication to all API nodes by setting state
+     *   to ZFAIL_CLOSING (which will make it auto-open in checkStartInterface)
+     */
+    c_allow_api_connect = 1;
+    NodeRecPtr nodePtr;
+    for (nodePtr.i = 1; nodePtr.i < MAX_NODES; nodePtr.i++)
+    {
+      jam();
+      Uint32 type = getNodeInfo(nodePtr.i).m_type;
+      if (type != NodeInfo::API)
+        continue;
+
+      ptrAss(nodePtr, nodeRec);
+      if (nodePtr.p->phase == ZAPI_INACTIVE)
+      {
+        jam();
+        setNodeInfo(nodePtr.i).m_heartbeat_cnt = 3;
+        nodePtr.p->phase = ZFAIL_CLOSING;
+        nodePtr.p->failState = NORMAL;
+      }
+    }
+  }
   }
   
   sendSttorryLab(signal);
@@ -324,8 +368,9 @@ void Qmgr::sendSttorryLab(Signal* signal
 /*< STTORRY                  <*/
 /****************************<*/
   signal->theData[3] = 7;
-  signal->theData[4] = 255;
-  sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 5, JBB);
+  signal->theData[4] = 8;
+  signal->theData[5] = 255;
+  sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 6, JBB);
   return;
 }//Qmgr::sendSttorryLab()
 
@@ -2095,6 +2140,7 @@ void Qmgr::initData(Signal* signal) 
   cneighbourl = ZNIL;
   cdelayRegreq = ZDELAY_REGREQ;
   cactivateApiCheck = 0;
+  c_allow_api_connect = 0;
   ctoStatus = Q_NOT_ACTIVE;
 
   interface_check_timer.setDelay(1000);
@@ -2398,6 +2444,7 @@ void Qmgr::checkStartInterface(Signal* s
 	// been disconnected for at least three seconds.
 	/*-------------------------------------------------------------------*/
         setNodeInfo(nodePtr.i).m_heartbeat_cnt= 0;
+        ndbout_c("node %u connected but ZFAIL_CLOSING", nodePtr.i);
       }//if
       if ((getNodeInfo(nodePtr.i).m_heartbeat_cnt > 3)
 	  && (nodePtr.p->failState == NORMAL)) {
@@ -2408,13 +2455,34 @@ void Qmgr::checkStartInterface(Signal* s
 	 * IS COMPLETE.
 	 *-------------------------------------------------------------------*/
         nodePtr.p->failState = NORMAL;
-        if (getNodeInfo(nodePtr.i).m_type != NodeInfo::DB){
+        Uint32 type = getNodeInfo(nodePtr.i).m_type;
+        switch(type){
+        case NodeInfo::DB:
+          jam();
+          nodePtr.p->phase = ZINIT;
+          break;
+        case NodeInfo::MGM:
           jam();
           nodePtr.p->phase = ZAPI_INACTIVE;
-        } else {
+          break;
+        case NodeInfo::API:
           jam();
-          nodePtr.p->phase = ZINIT;
-        }//if
+          if (c_allow_api_connect)
+          {
+            jam();
+            nodePtr.p->phase = ZAPI_INACTIVE;
+            break;
+          }
+          else
+          {
+            /**
+             * Dont allow API node to connect before c_allow_api_connect
+             */
+            jam();
+            setNodeInfo(nodePtr.i).m_heartbeat_cnt = 3;
+            continue;
+          }
+        }
 
         setNodeInfo(nodePtr.i).m_heartbeat_cnt= 0;
         signal->theData[0] = 0;
Index: drop6/storage/ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp
===================================================================
--- drop6.orig/storage/ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp	2008-02-27 13:16:36.000000000 +0100
+++ drop6/storage/ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp	2008-02-27 13:17:21.000000000 +0100
@@ -48,6 +48,7 @@
 //------- OTHERS ---------------------------------------------
 #define ZSTARTUP  1
 #define ZSHUTDOWN 2
+#define ZBLOCK_STTOR 3
 
 #define ZSIZE_NDB_BLOCKS_REC 16 /* MAX BLOCKS IN NDB                    */
 #define ZSIZE_SYSTAB 2048
@@ -383,6 +384,10 @@ private:
   void execREAD_CONFIG_CONF(Signal*);
 
   friend struct UpgradeStartup;
+
+#ifdef ERROR_INSERT
+  Uint32 c_error_insert_extra;
+#endif
 };
 
 #endif
Index: drop6/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp
===================================================================
--- drop6.orig/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp	2008-02-27 13:07:05.000000000 +0100
+++ drop6/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp	2008-02-27 13:41:24.000000000 +0100
@@ -152,6 +152,18 @@ void Ndbcntr::execCONTINUEB(Signal* sign
     jam();
     c_stopRec.checkTimeout(signal);
     break;
+  case ZBLOCK_STTOR:
+    if (ERROR_INSERTED(1002))
+    {
+      signal->theData[0] = ZBLOCK_STTOR;
+      sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 1);
+      return;
+    }
+    else
+    {
+      c_missra.sendNextSTTOR(signal);
+    }
+    return;
   default:
     jam();
     systemErrorLab(signal, __LINE__);
@@ -2054,6 +2066,19 @@ Ndbcntr::execDUMP_STATE_ORD(Signal* sign
     return;
   }
 
+  if (arg == 71)
+  {
+    if (signal->getLength() == 2)
+    {
+      c_error_insert_extra = signal->theData[1];
+      SET_ERROR_INSERT_VALUE(1002);
+    }
+    else if (ERROR_INSERTED(1002))
+    {
+      CLEAR_ERROR_INSERT_VALUE;
+    }
+  }
+
 }//Ndbcntr::execDUMP_STATE_ORD()
 
 void Ndbcntr::execSET_VAR_REQ(Signal* signal) {
@@ -2816,6 +2841,16 @@ void Ndbcntr::Missra::sendNextSTTOR(Sign
   for(; currentStartPhase < 255 ;
       currentStartPhase++, g_currentStartPhase = currentStartPhase){
     jam();
+
+#ifdef ERROR_INSERT
+    if (cntr.cerrorInsert == 1002 &&
+        cntr.c_error_insert_extra == currentStartPhase)
+    {
+      signal->theData[0] = ZBLOCK_STTOR;
+      cntr.sendSignalWithDelay(cntr.reference(), GSN_CONTINUEB, signal, 100, 1);
+      return;
+    }
+#endif
     
     const Uint32 start = currentBlockIndex;
 
Index: drop6/storage/ndb/test/ndbapi/test_event.cpp
===================================================================
--- drop6.orig/storage/ndb/test/ndbapi/test_event.cpp	2008-02-27 11:20:26.000000000 +0100
+++ drop6/storage/ndb/test/ndbapi/test_event.cpp	2008-02-27 13:42:00.000000000 +0100
@@ -1873,22 +1873,10 @@ runBug33793(NDBT_Context* ctx, NDBT_Step
   return NDBT_OK;
 }
 
+static
 int
-runBug34853(NDBT_Context* ctx, NDBT_Step* step)
+cc(Ndb_cluster_connection** ctx, Ndb** ndb)
 {
-  int result = NDBT_OK;
-  int loops = ctx->getNumLoops();
-  int records = ctx->getNumRecords();
-  Ndb* pNdb = GETNDB(step);
-  NdbRestarter res;
-
-  if (res.getNumDbNodes() < 2)
-  {
-    return NDBT_OK;
-  }
-
-  int nodeId = res.getDbNodeId(rand() % res.getNumDbNodes());
-
   Ndb_cluster_connection* xncc = new Ndb_cluster_connection;
   int ret;
   if ((ret = xncc->connect(30, 1, 0)) != 0)
@@ -1918,20 +1906,68 @@ runBug34853(NDBT_Context* ctx, NDBT_Step
     return NDBT_FAILED;
   }
 
-  const NdbDictionary::Table * table= ctx->getTab();
+  * ctx = xncc;
+  * ndb = xndb;
+  return 0;
+}
+
+static
+NdbEventOperation*
+op(Ndb* xndb, const NdbDictionary::Table * table)
+{
   char buf[1024];
   sprintf(buf, "%s_EVENT", table->getName());
-  NdbEventOperation *pOp, *pCreate = 0;
-  pCreate = pOp = xndb->createEventOperation(buf);
+  NdbEventOperation *pOp;
+  pOp = xndb->createEventOperation(buf);
   if ( pOp == NULL )
   {
+    g_err << "Event operation creation failed on %s" << buf << endl;
+    return 0;
+  }
+
+  int n_columns= table->getNoOfColumns();
+  NdbRecAttr* recAttr[1024];
+  NdbRecAttr* recAttrPre[1024];
+  for (int i = 0; i < n_columns; i++) {
+    recAttr[i]    = pOp->getValue(table->getColumn(i)->getName());
+    recAttrPre[i] = pOp->getPreValue(table->getColumn(i)->getName());
+  }
+
+  return pOp;
+}
+
+int
+runBug34853(NDBT_Context* ctx, NDBT_Step* step)
+{
+  int result = NDBT_OK;
+  int loops = ctx->getNumLoops();
+  int records = ctx->getNumRecords();
+  Ndb* pNdb = GETNDB(step);
+  NdbRestarter res;
+
+  if (res.getNumDbNodes() < 2)
+  {
+    return NDBT_OK;
+  }
+
+  Ndb_cluster_connection* xncc;
+  Ndb* xndb;
+
+  if (cc(&xncc, &xndb))
+  {
+    return NDBT_FAILED;
+  }
+
+  NdbEventOperation* pOp = op(xndb, ctx->getTab());
+  if (pOp == 0)
+  {
     delete xndb;
     delete xncc;
-    g_err << "Event operation creation failed on %s" << buf << endl;
     return NDBT_FAILED;
   }
 
   int api = xncc->node_id();
+  int nodeId = res.getDbNodeId(rand() % res.getNumDbNodes());
   ndbout_c("stopping %u", nodeId);
   res.restartOneDbNode(nodeId,
                        /** initial */ false,
@@ -1949,14 +1985,55 @@ runBug34853(NDBT_Context* ctx, NDBT_Step
   ndbout_c("waiting cluster");
   res.waitClusterStarted();
 
+  if (pOp->execute())
+  { // This starts changes to "start flowing"
+    g_err << "execute operation execution failed: \n";
+    g_err << pOp->getNdbError().code << " "
+	  << pOp->getNdbError().message << endl;
+    delete xndb;
+    delete xncc;
+    return NDBT_FAILED;
+  }
+
+  xndb->dropEventOperation(pOp);
 
-  int i;
-  int n_columns= table->getNoOfColumns();
-  NdbRecAttr* recAttr[1024];
-  NdbRecAttr* recAttrPre[1024];
-  for (i = 0; i < n_columns; i++) {
-    recAttr[i]    = pOp->getValue(table->getColumn(i)->getName());
-    recAttrPre[i] = pOp->getPreValue(table->getColumn(i)->getName());
+  ndbout_c("stopping %u", nodeId);
+  res.restartOneDbNode(nodeId,
+                       /** initial */ false,
+                       /** nostart */ true,
+                       /** abort   */ true);
+
+  ndbout_c("waiting for %u", nodeId);
+  res.waitNodesNoStart(&nodeId, 1);
+
+  dump[0] = 71;
+  dump[1] = 7;
+  res.dumpStateOneNode(nodeId, dump, 2);
+  res.startNodes(&nodeId, 1);
+  ndbout_c("waiting node sp 7");
+  res.waitNodesStartPhase(&nodeId, 1, 6);
+
+  delete xndb;
+  delete xncc;
+
+  NdbSleep_SecSleep(5); // 3 seconds to open connections. i.e 5 > 3
+
+  dump[0] = 71;
+  res.dumpStateOneNode(nodeId, dump, 1);
+
+  res.waitClusterStarted();
+
+  if (cc(&xncc, &xndb))
+  {
+    return NDBT_FAILED;
+  }
+
+  pOp = op(xndb, ctx->getTab());
+  if (pOp == 0)
+  {
+    delete xndb;
+    delete xncc;
+    return NDBT_FAILED;
   }
 
   if (pOp->execute())
@@ -1970,7 +2047,6 @@ runBug34853(NDBT_Context* ctx, NDBT_Step
   }
 
   xndb->dropEventOperation(pOp);
-
   delete xndb;
   delete xncc;
   return NDBT_OK;
