List:Commits« Previous MessageNext Message »
From:knielsen Date:May 23 2008 11:27am
Subject:bk commit into 5.1 tree (knielsen:1.2604)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of knielsen.  When knielsen 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@stripped, 2008-05-23 11:26:56+02:00, knielsen@ymer.(none) +8 -0
  Fix race in ENABLE_COMORD signal.
  
  When QMGR sends ENABLE_COMORD to CMVMI to enable IO with a node
  (IOState), it is necessary that this signal is executed before other
  node starts sending signals, otherwise signals can get lost.
  
  There was no mechanism to ensure this, it just so happened that
  current scheduler ensured this. But it will break with ndbmtd.
  
  Fix by replacing with ENABLE_COMREQ / ENABLE_COMCONF signal pair.

  storage/ndb/include/kernel/GlobalSignalNumbers.h@stripped, 2008-05-23 11:26:51+02:00,
knielsen@ymer.(none) +2 -2
    Add signals

  storage/ndb/include/kernel/signaldata/EnableCom.hpp@stripped, 2008-05-23 11:26:52+02:00,
knielsen@ymer.(none) +47 -0
    New BitKeeper file ``storage/ndb/include/kernel/signaldata/EnableCom.hpp''

  storage/ndb/include/kernel/signaldata/EnableCom.hpp@stripped, 2008-05-23 11:26:52+02:00,
knielsen@ymer.(none) +0 -0

  storage/ndb/src/common/debugger/signaldata/SignalNames.cpp@stripped, 2008-05-23
11:26:51+02:00, knielsen@ymer.(none) +2 -1
    Add signals

  storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp@stripped, 2008-05-23 11:26:51+02:00,
knielsen@ymer.(none) +41 -19
    Fix race in ENABLE_COMORD signal.
    
    When QMGR sends ENABLE_COMORD to CMVMI to enable IO with a node
    (IOState), it is necessary that this signal is executed before other
    node starts sending signals, otherwise signals can get lost.
    
    There was no mechanism to ensure this, it just so happened that
    current scheduler ensured this. But it will break with ndbmtd.
    
    Fix by replacing with ENABLE_COMREQ / ENABLE_COMCONF signal pair.

  storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.hpp@stripped, 2008-05-23 11:26:51+02:00,
knielsen@ymer.(none) +1 -1
    Fix race in ENABLE_COMORD signal.
    
    When QMGR sends ENABLE_COMORD to CMVMI to enable IO with a node
    (IOState), it is necessary that this signal is executed before other
    node starts sending signals, otherwise signals can get lost.
    
    There was no mechanism to ensure this, it just so happened that
    current scheduler ensured this. But it will break with ndbmtd.
    
    Fix by replacing with ENABLE_COMREQ / ENABLE_COMCONF signal pair.

  storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp@stripped, 2008-05-23 11:26:52+02:00,
knielsen@ymer.(none) +11 -0
    Fix race in ENABLE_COMORD signal.
    
    When QMGR sends ENABLE_COMORD to CMVMI to enable IO with a node
    (IOState), it is necessary that this signal is executed before other
    node starts sending signals, otherwise signals can get lost.
    
    There was no mechanism to ensure this, it just so happened that
    current scheduler ensured this. But it will break with ndbmtd.
    
    Fix by replacing with ENABLE_COMREQ / ENABLE_COMCONF signal pair.

  storage/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp@stripped, 2008-05-23 11:26:52+02:00,
knielsen@ymer.(none) +1 -0
    Fix race in ENABLE_COMORD signal.
    
    When QMGR sends ENABLE_COMORD to CMVMI to enable IO with a node
    (IOState), it is necessary that this signal is executed before other
    node starts sending signals, otherwise signals can get lost.
    
    There was no mechanism to ensure this, it just so happened that
    current scheduler ensured this. But it will break with ndbmtd.
    
    Fix by replacing with ENABLE_COMREQ / ENABLE_COMCONF signal pair.

  storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp@stripped, 2008-05-23 11:26:52+02:00,
knielsen@ymer.(none) +105 -25
    Fix race in ENABLE_COMORD signal.
    
    When QMGR sends ENABLE_COMORD to CMVMI to enable IO with a node
    (IOState), it is necessary that this signal is executed before other
    node starts sending signals, otherwise signals can get lost.
    
    There was no mechanism to ensure this, it just so happened that
    current scheduler ensured this. But it will break with ndbmtd.
    
    Fix by replacing with ENABLE_COMREQ / ENABLE_COMCONF signal pair.

diff -Nrup a/storage/ndb/include/kernel/GlobalSignalNumbers.h
b/storage/ndb/include/kernel/GlobalSignalNumbers.h
--- a/storage/ndb/include/kernel/GlobalSignalNumbers.h	2008-05-19 17:31:02 +02:00
+++ b/storage/ndb/include/kernel/GlobalSignalNumbers.h	2008-05-23 11:26:51 +02:00
@@ -190,7 +190,7 @@ extern const GlobalSignalNumber NO_OF_SI
 #define GSN_CLOSE_COMCONF               126 /* local */
 #define GSN_CLOSE_COMREQ                127 /* local */
 #define GSN_CM_ACKADD                   128 /* distr. */
-/* 129 unused */
+#define GSN_ENABLE_COMCONF              129 /* local */
 #define GSN_CM_ADD                      130 /* distr. */
 /* 131 unused */
 /* 132 not unused */
@@ -335,7 +335,7 @@ extern const GlobalSignalNumber NO_OF_SI
 #define GSN_DIVERIFYCONF                239
 #define GSN_DIVERIFYREF                 240
 #define GSN_DIVERIFYREQ                 241
-#define GSN_ENABLE_COMORD               242
+#define GSN_ENABLE_COMREQ               242 /* local */
 #define GSN_END_LCPCONF                 243
 #define GSN_END_LCP_CONF                243
 #define GSN_END_LCPREQ                  244
diff -Nrup a/storage/ndb/include/kernel/signaldata/EnableCom.hpp
b/storage/ndb/include/kernel/signaldata/EnableCom.hpp
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/storage/ndb/include/kernel/signaldata/EnableCom.hpp	2008-05-23 11:26:52 +02:00
@@ -0,0 +1,47 @@
+/* Copyright (C) 2008 MySQL AB
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+#ifndef ENABLE_COM_H
+#define ENABLE_COM_H
+
+#include "SignalData.hpp"
+
+class EnableComReq  {
+  friend class Qmgr;
+  friend class Cmvmi;
+
+public:
+  STATIC_CONST( SignalLength = 2 + NodeBitmask::Size );
+private:
+
+  Uint32 m_senderRef;
+  Uint32 m_senderData;
+  Uint32 m_nodeIds[NodeBitmask::Size];
+};
+
+class EnableComConf  {
+  friend class Qmgr;
+  friend class Cmvmi;
+
+public:
+  STATIC_CONST( SignalLength = 2 + NodeBitmask::Size );
+private:
+
+  Uint32 m_senderRef;
+  Uint32 m_senderData;
+  Uint32 m_nodeIds[NodeBitmask::Size];
+};
+
+#endif
diff -Nrup a/storage/ndb/src/common/debugger/signaldata/SignalNames.cpp
b/storage/ndb/src/common/debugger/signaldata/SignalNames.cpp
--- a/storage/ndb/src/common/debugger/signaldata/SignalNames.cpp	2008-05-19 17:31:02
+02:00
+++ b/storage/ndb/src/common/debugger/signaldata/SignalNames.cpp	2008-05-23 11:26:51
+02:00
@@ -172,7 +172,8 @@ const GsnName SignalNames [] = {
   ,{ GSN_DIVERIFYREQ,            "DIVERIFYREQ" }
   ,{ GSN_EMPTY_LCP_REQ,          "EMPTY_LCP_REQ" }
   ,{ GSN_EMPTY_LCP_CONF,         "EMPTY_LCP_CONF" }
-  ,{ GSN_ENABLE_COMORD,          "ENABLE_COMORD" }
+  ,{ GSN_ENABLE_COMREQ,          "ENABLE_COMREQ" }
+  ,{ GSN_ENABLE_COMCONF,         "ENABLE_COMCONF" }
   ,{ GSN_END_LCPCONF,            "END_LCPCONF" }
   ,{ GSN_END_LCPREQ,             "END_LCPREQ" }
   ,{ GSN_END_TOCONF,             "END_TOCONF" }
diff -Nrup a/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp
b/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp
--- a/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp	2008-04-25 13:02:33 +02:00
+++ b/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp	2008-05-23 11:26:51 +02:00
@@ -35,6 +35,7 @@
 #include <signaldata/EventSubscribeReq.hpp>
 #include <signaldata/DumpStateOrd.hpp>
 #include <signaldata/DisconnectRep.hpp>
+#include <signaldata/EnableCom.hpp>
 
 #include <EventLogger.hpp>
 #include <TimeQueue.hpp>
@@ -74,7 +75,7 @@ Cmvmi::Cmvmi(Block_context& ctx) :
   addRecSignal(GSN_STTOR,  &Cmvmi::execSTTOR);
   addRecSignal(GSN_READ_CONFIG_REQ,  &Cmvmi::execREAD_CONFIG_REQ);
   addRecSignal(GSN_CLOSE_COMREQ,  &Cmvmi::execCLOSE_COMREQ);
-  addRecSignal(GSN_ENABLE_COMORD,  &Cmvmi::execENABLE_COMORD);
+  addRecSignal(GSN_ENABLE_COMREQ,  &Cmvmi::execENABLE_COMREQ);
   addRecSignal(GSN_OPEN_COMREQ,  &Cmvmi::execOPEN_COMREQ);
   addRecSignal(GSN_TEST_ORD,  &Cmvmi::execTEST_ORD);
 
@@ -516,7 +517,6 @@ void Cmvmi::execOPEN_COMREQ(Signal* sign
     }
   }
   
-done:  
   if (userRef != 0) {
     jam(); 
     signal->theData[0] = tStartingNode;
@@ -526,27 +526,49 @@ done:  
   mt_receive_unlock();
 }
 
-void Cmvmi::execENABLE_COMORD(Signal* signal)
+void Cmvmi::execENABLE_COMREQ(Signal* signal)
 {
-  // Enable communication with all our NDB blocks to this node
-  
-  Uint32 tStartingNode = signal->theData[0];
+  jamEntry();
+  const EnableComReq *enableComReq = (const EnableComReq *)signal->getDataPtr();
+
+  /* Need to copy out signal data to not clobber it with sendSignal(). */
+  Uint32 senderRef = enableComReq->m_senderRef;
+  Uint32 senderData = enableComReq->m_senderData;
+  Uint32 nodes[NodeBitmask::Size];
+  MEMCOPY_NO_WORDS(nodes, enableComReq->m_nodeIds, NodeBitmask::Size);
+
   mt_receive_lock();
-  globalTransporterRegistry.setIOState(tStartingNode, NoHalt);
-  setNodeInfo(tStartingNode).m_connected = true;
+  /* Enable communication with all our NDB blocks to these nodes. */
+  Uint32 search_from = 0;
+  for (;;)
+  {
+    Uint32 tStartingNode = NodeBitmask::find(nodes, search_from);
+    if (tStartingNode == NodeBitmask::NotFound)
+      break;
+    search_from = tStartingNode + 1;
+
+    globalTransporterRegistry.setIOState(tStartingNode, NoHalt);
+    setNodeInfo(tStartingNode).m_connected = true;
+
     //-----------------------------------------------------
-  // Report that the version of the node
-  //-----------------------------------------------------
-  signal->theData[0] = NDB_LE_ConnectedApiVersion;
-  signal->theData[1] = tStartingNode;
-  signal->theData[2] = getNodeInfo(tStartingNode).m_version;
-  signal->theData[3] = getNodeInfo(tStartingNode).m_mysql_version;
-  
-  sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 4, JBB);
+    // Report that the version of the node
+    //-----------------------------------------------------
+    signal->theData[0] = NDB_LE_ConnectedApiVersion;
+    signal->theData[1] = tStartingNode;
+    signal->theData[2] = getNodeInfo(tStartingNode).m_version;
+    signal->theData[3] = getNodeInfo(tStartingNode).m_mysql_version;
+
+    sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 4, JBB);
+    //-----------------------------------------------------
+  }
+
+  EnableComConf *enableComConf = (EnableComConf *)signal->getDataPtrSend();
+  enableComConf->m_senderRef = reference();
+  enableComConf->m_senderData = senderData;
+  MEMCOPY_NO_WORDS(enableComConf->m_nodeIds, nodes, NodeBitmask::Size);
+  sendSignal(senderRef, GSN_ENABLE_COMCONF, signal,
+             EnableComConf::SignalLength, JBA);
   mt_receive_unlock();
-  //-----------------------------------------------------
-  
-  jamEntry();
 }
 
 void Cmvmi::execDISCONNECT_REP(Signal *signal)
diff -Nrup a/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.hpp
b/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.hpp
--- a/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.hpp	2007-02-14 06:35:28 +01:00
+++ b/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.hpp	2008-05-23 11:26:51 +02:00
@@ -50,7 +50,7 @@ private:
   void execREAD_CONFIG_REQ(Signal* signal);
   void execSTTOR(Signal* signal);
   void execCLOSE_COMREQ(Signal* signal);
-  void execENABLE_COMORD(Signal* signal);
+  void execENABLE_COMREQ(Signal* signal);
   void execOPEN_COMREQ(Signal* signal);
   void execSIZEALT_ACK(Signal* signal);
   void execTEST_ORD(Signal* signal);
diff -Nrup a/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp
b/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp
--- a/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp	2008-04-25 11:17:13 +02:00
+++ b/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp	2008-05-23 11:26:52 +02:00
@@ -208,6 +208,13 @@ public:
     }
   };
   
+  /* State values for handling ENABLE_COMREQ / ENABLE_COMCONF. */
+  enum EnableComState {
+    ENABLE_COM_CM_ADD_COMMIT = 0,
+    ENABLE_COM_CM_COMMIT_NEW = 1,
+    ENABLE_COM_API_REGREQ = 2
+  };
+
 public:
   Qmgr(Block_context&);
   virtual ~Qmgr();
@@ -266,6 +273,10 @@ private:
   void execALLOC_NODEID_CONF(Signal *);
   void execALLOC_NODEID_REF(Signal *);
   void completeAllocNodeIdReq(Signal *);
+  void execENABLE_COMCONF(Signal *signal);
+  void handleEnableComAddCommit(Signal *signal, Uint32 node);
+  void handleEnableComCommitNew(Signal *signal);
+  void handleEnableComApiRegreq(Signal *signal, Uint32 node);
   
   void execSTART_ORD(Signal*);
 
diff -Nrup a/storage/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp
b/storage/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp
--- a/storage/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp	2007-11-23 11:09:28 +01:00
+++ b/storage/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp	2008-05-23 11:26:52 +02:00
@@ -115,6 +115,7 @@ Qmgr::Qmgr(Block_context& ctx)
   addRecSignal(GSN_ALLOC_NODEID_REQ,  &Qmgr::execALLOC_NODEID_REQ);
   addRecSignal(GSN_ALLOC_NODEID_CONF,  &Qmgr::execALLOC_NODEID_CONF);
   addRecSignal(GSN_ALLOC_NODEID_REF,  &Qmgr::execALLOC_NODEID_REF);
+  addRecSignal(GSN_ENABLE_COMCONF,  &Qmgr::execENABLE_COMCONF);
   
   // Arbitration signals
   addRecSignal(GSN_ARBIT_PREPREQ, &Qmgr::execARBIT_PREPREQ);
diff -Nrup a/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
b/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
--- a/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp	2008-04-25 11:20:41 +02:00
+++ b/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp	2008-05-23 11:26:52 +02:00
@@ -34,6 +34,7 @@
 #include <signaldata/DisconnectRep.hpp>
 #include <signaldata/ApiBroadcast.hpp>
 #include <signaldata/Upgrade.hpp>
+#include <signaldata/EnableCom.hpp>
 
 #include <ndb_version.h>
 
@@ -1928,14 +1929,13 @@ void Qmgr::execCM_ADD(Signal* signal) 
     /**
      *  ENABLE COMMUNICATION WITH ALL BLOCKS WITH THE NEWLY ADDED NODE
      */
-    signal->theData[0] = addNodePtr.i;
-    sendSignal(CMVMI_REF, GSN_ENABLE_COMORD, signal, 1, JBA);
-
-    sendCmAckAdd(signal, addNodePtr.i, CmAdd::AddCommit);
-    if(getOwnNodeId() != cpresident){
-      jam();
-      c_start.reset();
-    }
+    EnableComReq *enableComReq = (EnableComReq *)signal->getDataPtrSend();
+    enableComReq->m_senderRef = reference();
+    enableComReq->m_senderData = ENABLE_COM_CM_ADD_COMMIT;
+    NodeBitmask::clear(enableComReq->m_nodeIds);
+    NodeBitmask::set(enableComReq->m_nodeIds, addNodePtr.i);
+    sendSignal(CMVMI_REF, GSN_ENABLE_COMREQ, signal,
+               EnableComReq::SignalLength, JBA);
     break;
   }
   case CmAdd::CommitNew:
@@ -1946,6 +1946,57 @@ void Qmgr::execCM_ADD(Signal* signal) 
 }//Qmgr::execCM_ADD()
 
 void
+Qmgr::handleEnableComAddCommit(Signal *signal, Uint32 node)
+{
+  sendCmAckAdd(signal, node, CmAdd::AddCommit);
+  if(getOwnNodeId() != cpresident){
+    jam();
+    c_start.reset();
+  }
+}
+
+void
+Qmgr::execENABLE_COMCONF(Signal *signal)
+{
+  const EnableComConf *enableComConf =
+    (const EnableComConf *)signal->getDataPtr();
+  Uint32 state = enableComConf->m_senderData;
+  Uint32 node = NodeBitmask::find(enableComConf->m_nodeIds, 0);
+
+  jamEntry();
+
+  switch (state)
+  {
+    case ENABLE_COM_CM_ADD_COMMIT:
+      jam();
+      /* Only exactly one node possible here. */
+      ndbrequire(node != NodeBitmask::NotFound);
+      ndbrequire(NodeBitmask::find(enableComConf->m_nodeIds, node + 1) ==
+                 NodeBitmask::NotFound);
+      handleEnableComAddCommit(signal, node);
+      break;
+
+    case ENABLE_COM_CM_COMMIT_NEW:
+      jam();
+      handleEnableComCommitNew(signal);
+      break;
+
+    case ENABLE_COM_API_REGREQ:
+      jam();
+      /* Only exactly one node possible here. */
+      ndbrequire(node != NodeBitmask::NotFound);
+      ndbrequire(NodeBitmask::find(enableComConf->m_nodeIds, node + 1) ==
+                 NodeBitmask::NotFound);
+      handleEnableComApiRegreq(signal, node);
+      break;
+
+    default:
+      jam();
+      ndbrequire(false);
+  }
+}
+
+void
 Qmgr::joinedCluster(Signal* signal, NodeRecPtr nodePtr){
   /**
    * WE HAVE BEEN INCLUDED IN THE CLUSTER WE CAN START BEING PART OF THE 
@@ -1968,6 +2019,10 @@ Qmgr::joinedCluster(Signal* signal, Node
    * ENABLE COMMUNICATION WITH ALL BLOCKS IN THE CURRENT CLUSTER AND SET 
    * THE NODES IN THE CLUSTER TO BE RUNNING. 
    */
+  EnableComReq *enableComReq = (EnableComReq *)signal->getDataPtrSend();
+  enableComReq->m_senderRef = reference();
+  enableComReq->m_senderData = ENABLE_COM_CM_COMMIT_NEW;
+  NodeBitmask::clear(enableComReq->m_nodeIds);
   for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
     jam();
     ptrAss(nodePtr, nodeRec);
@@ -1977,11 +2032,25 @@ Qmgr::joinedCluster(Signal* signal, Node
       // to open communication to ourself.
       /*-------------------------------------------------------------------*/
       jam();
-      signal->theData[0] = nodePtr.i;
-      sendSignal(CMVMI_REF, GSN_ENABLE_COMORD, signal, 1, JBA);
+      NodeBitmask::set(enableComReq->m_nodeIds, nodePtr.i);
     }//if
   }//for
-  
+
+  if (!NodeBitmask::isclear(enableComReq->m_nodeIds))
+  {
+    jam();
+    sendSignal(CMVMI_REF, GSN_ENABLE_COMREQ, signal,
+               EnableComReq::SignalLength, JBA);
+  }
+  else
+  {
+    handleEnableComCommitNew(signal);
+  }
+}
+
+void
+Qmgr::handleEnableComCommitNew(Signal *signal)
+{
   sendSttorryLab(signal);
   
   sendCmAckAdd(signal, getOwnNodeId(), CmAdd::CommitNew);
@@ -3039,23 +3108,34 @@ void Qmgr::execAPI_REGREQ(Signal* signal
      *----------------------------------------------------------------------*/
     apiNodePtr.p->phase = ZAPI_ACTIVE;
     apiNodePtr.p->blockRef = ref;
-    signal->theData[0] = apiNodePtr.i;
-    sendSignal(CMVMI_REF, GSN_ENABLE_COMORD, signal, 1, JBA);
-    
-    recompute_version_info(type, version);
-    
-    signal->theData[0] = apiNodePtr.i;
-    signal->theData[1] = version;
-    NodeReceiverGroup rg(QMGR, c_clusterNodes);
-    rg.m_nodes.clear(getOwnNodeId());
-    sendVersionedDb(rg, GSN_NODE_VERSION_REP, signal, 2, JBB, 
-		    NDBD_NODE_VERSION_REP);
-    
-    signal->theData[0] = apiNodePtr.i;
-    EXECUTE_DIRECT(NDBCNTR, GSN_API_START_REP, signal, 1);
+    EnableComReq *enableComReq = (EnableComReq *)signal->getDataPtrSend();
+    enableComReq->m_senderRef = reference();
+    enableComReq->m_senderData = ENABLE_COM_API_REGREQ;
+    NodeBitmask::clear(enableComReq->m_nodeIds);
+    NodeBitmask::set(enableComReq->m_nodeIds, apiNodePtr.i);
+    sendSignal(CMVMI_REF, GSN_ENABLE_COMREQ, signal,
+               EnableComReq::SignalLength, JBA);
   }
   return;
 }//Qmgr::execAPI_REGREQ()
+
+void
+Qmgr::handleEnableComApiRegreq(Signal *signal, Uint32 node)
+{
+  NodeInfo::NodeType type = getNodeInfo(node).getType();
+  Uint32 version = getNodeInfo(node).m_version;
+  recompute_version_info(type, version);
+
+  signal->theData[0] = node;
+  signal->theData[1] = version;
+  NodeReceiverGroup rg(QMGR, c_clusterNodes);
+  rg.m_nodes.clear(getOwnNodeId());
+  sendVersionedDb(rg, GSN_NODE_VERSION_REP, signal, 2, JBB,
+                  NDBD_NODE_VERSION_REP);
+
+  signal->theData[0] = node;
+  EXECUTE_DIRECT(NDBCNTR, GSN_API_START_REP, signal, 1);
+}
 
 void
 Qmgr::sendVersionedDb(NodeReceiverGroup rg,
Thread
bk commit into 5.1 tree (knielsen:1.2604)knielsen23 May