---
 storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp |   40 +++++
 storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp |    5 
 storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp   |   11 +
 storage/ndb/test/ndbapi/test_event.cpp            |  175 ++++++++++++++++++++++
 4 files changed, 227 insertions(+), 4 deletions(-)

Index: telco-6.2/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
===================================================================
--- telco-6.2.orig/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp	2008-07-04 10:48:08.000000000 +0200
+++ telco-6.2/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp	2008-07-04 10:48:54.000000000 +0200
@@ -8726,6 +8726,20 @@ void Dbdih::execGCP_COMMIT(Signal* signa
   }
   Uint64 gci = gci_lo | (Uint64(gci_hi) << 32);
 
+#ifdef ERROR_INSERT
+  if (ERROR_INSERTED(7211))
+  {
+    ndbout_c("err 7211 killing %d", c_error_insert_extra);
+    Uint32 save = signal->theData[0];
+    signal->theData[0] = 5048;
+    sendSignal(numberToRef(DBLQH, c_error_insert_extra),
+               GSN_NDB_TAMPER, signal, 1, JBB);
+    signal->theData[0] = save;
+    CLEAR_ERROR_INSERT_VALUE;
+    return;
+  }
+#endif
+
   Uint32 masterRef = calcDihBlockRef(masterNodeId);
   ndbrequire(masterNodeId = cmasterNodeId);
   if (isMaster())
@@ -8804,6 +8818,19 @@ void Dbdih::execGCP_TCFINISHED(Signal* s
     return;
   }
 
+#ifdef ERROR_INSERT
+  if (ERROR_INSERTED(7212))
+  {
+    ndbout_c("err 7212 killing %d", c_error_insert_extra);
+    Uint32 save = signal->theData[0];
+    signal->theData[0] = 9999;
+    sendSignal(numberToRef(CMVMI, c_error_insert_extra),
+               GSN_NDB_TAMPER, signal, 1, JBB);
+    signal->theData[0] = save;
+    CLEAR_ERROR_INSERT_VALUE;
+  }
+#endif
+
 #ifdef GCP_TIMER_HACK
   NdbTick_getMicroTimer(&globalData.gcp_timer_commit[1]);
 #endif
@@ -15527,6 +15554,19 @@ Dbdih::execDUMP_STATE_ORD(Signal* signal
   if (signal->theData[0] == 7901)
     globalData.gcp_timer_limit = signal->theData[1];
 #endif
+
+  DECLARE_DUMP0(DBDIH, 7211, "Set error 7211 with extra arg")
+  {
+    SET_ERROR_INSERT_VALUE2(7211, signal->theData[1]);
+    return;
+  }
+
+  DECLARE_DUMP0(DBDIH, 7212, "Set error 7212 with extra arg")
+  {
+    SET_ERROR_INSERT_VALUE2(7212, signal->theData[1]);
+    return;
+  }
+
 }//Dbdih::execDUMP_STATE_ORD()
 
 void
Index: telco-6.2/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
===================================================================
--- telco-6.2.orig/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp	2008-07-04 10:48:08.000000000 +0200
+++ telco-6.2/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp	2008-07-04 10:48:54.000000000 +0200
@@ -7466,7 +7466,16 @@ void Dbtc::startTakeOverLab(Signal* sign
       signal->theData[0] = tcNodeFailptr.i;
       signal->theData[1] = cownref;
       signal->theData[2] = tfailedNodeId;
-      sendSignal(tblockref, GSN_LQH_TRANSREQ, signal, 3, JBB);
+      if (ERROR_INSERTED(8064) && hostptr.i == getOwnNodeId())
+      {
+        ndbout_c("sending delayed GSN_LQH_TRANSREQ to self");
+        sendSignalWithDelay(tblockref, GSN_LQH_TRANSREQ, signal, 100, 3);
+        CLEAR_ERROR_INSERT_VALUE;
+      }
+      else
+      {
+        sendSignal(tblockref, GSN_LQH_TRANSREQ, signal, 3, JBB);
+      }
     }//if
   }//for
 }//Dbtc::startTakeOverLab()
Index: telco-6.2/storage/ndb/test/ndbapi/test_event.cpp
===================================================================
--- telco-6.2.orig/storage/ndb/test/ndbapi/test_event.cpp	2008-07-04 10:48:08.000000000 +0200
+++ telco-6.2/storage/ndb/test/ndbapi/test_event.cpp	2008-07-04 10:48:54.000000000 +0200
@@ -22,6 +22,7 @@
 #include <NdbRestarter.hpp>
 #include <NdbRestarts.hpp>
 #include <signaldata/DumpStateOrd.hpp>
+#include <NdbEnv.h>
 
 #define GETNDB(ps) ((NDBT_NdbApiStep*)ps)->getNdb()
 
@@ -849,6 +850,82 @@ end:
   DBUG_RETURN(result);
 }
 
+int runEventConsumer(NDBT_Context* ctx, NDBT_Step* step)
+{
+  DBUG_ENTER("runEventConsumer");
+  int result = NDBT_OK;
+  const NdbDictionary::Table * table= ctx->getTab();
+  HugoTransactions hugoTrans(* table);
+
+  char buf[1024];
+  sprintf(buf, "%s_EVENT", table->getName());
+  NdbEventOperation *pOp, *pCreate = 0;
+  pCreate = pOp = GETNDB(step)->createEventOperation(buf);
+  if ( pOp == NULL ) {
+    g_err << "Event operation creation failed on %s" << buf << endl;
+    DBUG_RETURN(NDBT_FAILED);
+  }
+  bool merge_events = ctx->getProperty("MergeEvents");
+  pOp->mergeEvents(merge_events);
+
+  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());
+  }
+
+  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;
+    result = NDBT_FAILED;
+    goto end;
+  }
+
+  ctx->setProperty("LastGCI_hi", ~(Uint32)0);
+  ctx->broadcast();
+
+  while(!ctx->isTestStopped())
+  {
+    int count= 0;
+    Ndb* ndb= GETNDB(step);
+
+    Uint64 last_gci = 0;
+    while(!ctx->isTestStopped())
+    {
+      Uint32 count = 0;
+      Uint64 curr_gci;
+      ndb->pollEvents(100, &curr_gci);
+      if (curr_gci != last_gci)
+      {
+        while ((pOp= ndb->nextEvent()) != 0)
+        {
+          count++;
+        }
+        last_gci = curr_gci;
+      }
+      ndbout_c("Consumed gci: %u/%u, %d events",
+               Uint32(last_gci >> 32), Uint32(last_gci), count);
+    }
+  }
+
+end:
+  if(pCreate)
+  {
+    if (GETNDB(step)->dropEventOperation(pCreate)) {
+      g_err << "dropEventOperation execution failed "
+	    << GETNDB(step)->getNdbError().code << " "
+	    << GETNDB(step)->getNdbError().message << endl;
+      result = NDBT_FAILED;
+    }
+  }
+  ctx->stopTest();
+  DBUG_RETURN(result);
+}
+
 int runEventListenerUntilStopped(NDBT_Context* ctx, NDBT_Step* step)
 {
   
@@ -1736,6 +1813,17 @@ runSubscribeUnsubscribe(NDBT_Context* ct
   return NDBT_OK;
 }
 
+int
+runLoadTable(NDBT_Context* ctx, NDBT_Step* step)
+{
+  int records = ctx->getNumRecords();
+  HugoTransactions hugoTrans(*ctx->getTab());
+  if (hugoTrans.loadTable(GETNDB(step), records) != 0){
+    return NDBT_FAILED;
+  }
+  return NDBT_OK;
+}
+
 int 
 runScanUpdateUntilStopped(NDBT_Context* ctx, NDBT_Step* step){
   int records = ctx->getNumRecords();
@@ -2690,6 +2778,84 @@ runBug37442(NDBT_Context* ctx, NDBT_Step
   return NDBT_OK;
 }
 
+int
+runBug30780(NDBT_Context* ctx, NDBT_Step* step)
+{
+  int result = NDBT_OK;
+
+  NdbRestarter res;
+
+  if (res.getNumDbNodes() < 2)
+  {
+    ctx->stopTest();
+    return NDBT_OK;
+  }
+
+  const int cases = 4;
+  int loops = ctx->getNumLoops();
+  if (loops <= cases)
+    loops = cases + 1;
+  for (int i = 0; i<loops; i++)
+  {
+    int master = res.getMasterNodeId();
+    int next = res.getNextMasterNodeId(master);
+
+    res.insertErrorInNode(next, 8064);
+    int val1[] = { 7211, 0 };
+    int val2[] = { DumpStateOrd::CmvmiSetRestartOnErrorInsert, 1 };
+    if (res.dumpStateOneNode(master, val2, 2))
+      return NDBT_FAILED;
+
+    int c = i % cases;
+    {
+      char buf[100];
+      const char * off = NdbEnv_GetEnv("NDB_ERR", buf, sizeof(buf));
+      if (off)
+      {
+        c = atoi(off);
+      }
+    }
+    switch(c){
+    case 0:
+      ndbout_c("stopping %u", master);
+      res.restartOneDbNode(master,
+                           /** initial */ false,
+                           /** nostart */ true,
+                           /** abort   */ true);
+      break;
+    case 1:
+      ndbout_c("stopping %u, err 7211", master);
+      val1[0] = 7211;
+      val1[1] = master;
+      res.dumpStateOneNode(next, val1, 2);
+      break;
+    case 2:
+      ndbout_c("stopping %u, err 7212", master);
+      val1[0] = 7212;
+      val1[1] = master;
+      res.dumpStateOneNode(next, val1, 2);
+      break;
+    case 3:
+      ndbout_c("stopping %u, err 7007", master);
+      res.insertErrorInNode(master, 7007);
+      break;
+    }
+    ndbout_c("waiting for %u", master);
+    res.waitNodesNoStart(&master, 1);
+    ndbout_c("starting %u", master);
+    res.startNodes(&master, 1);
+    ndbout_c("waiting for cluster started");
+    if (res.waitClusterStarted())
+    {
+      return NDBT_FAILED;
+    }
+  }
+
+  ctx->stopTest();
+  return NDBT_OK;
+}
+
+
 NDBT_TESTSUITE(test_event);
 TESTCASE("BasicEventOperation", 
 	 "Verify that we can listen to Events"
@@ -2881,6 +3047,15 @@ TESTCASE("Bug37442", "")
 {
   INITIALIZER(runBug37442);
 }
+TESTCASE("Bug30780", "")
+{
+  INITIALIZER(runCreateEvent);
+  INITIALIZER(runLoadTable);
+  STEP(runEventConsumer);
+  STEPS(runScanUpdateUntilStopped, 3);
+  STEP(runBug30780);
+  FINALIZER(runDropEvent);
+}
 NDBT_TESTSUITE_END(test_event);
 
 int main(int argc, const char** argv){
Index: telco-6.2/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
===================================================================
--- telco-6.2.orig/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp	2008-07-04 10:49:28.000000000 +0200
+++ telco-6.2/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp	2008-07-04 10:49:38.000000000 +0200
@@ -6146,9 +6146,8 @@ void Dblqh::execCOMPLETE(Signal* signal)
     errorReport(signal, 1);
     return;
   }//if
-  if (ERROR_INSERTED(5042)) {
-    ndbrequire(false);
-  }
+  CRASH_INSERTION(5042);
+
   if (ERROR_INSERTED(5013)) {
     CLEAR_ERROR_INSERT_VALUE;
     sendSignalWithDelay(cownref, GSN_COMPLETE, signal, 2000, 3);
