diff --git a/storage/ndb/include/kernel/GlobalSignalNumbers.h b/storage/ndb/include/kernel/GlobalSignalNumbers.h
index b05b79cf176a7edb793712f244ea8d6a87cea29c..c3acd30369f988d3b61834955de2fc74a8aa49c5 100644
--- a/storage/ndb/include/kernel/GlobalSignalNumbers.h
+++ b/storage/ndb/include/kernel/GlobalSignalNumbers.h
@@ -111,9 +111,9 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES;
 /* 57 unused */
 /* 58 unused */
 /* 59 unused */
-/* 60 unused */
-/* 61 unused */
-/* 62 unused */
+#define GSN_ALLOC_NODEID_REQ            60
+#define GSN_ALLOC_NODEID_CONF           61
+#define GSN_ALLOC_NODEID_REF            62
 /* 63 unused */
 /* 64 unused */
 /* 65 unused */
diff --git a/storage/ndb/include/kernel/signaldata/AllocNodeId.hpp b/storage/ndb/include/kernel/signaldata/AllocNodeId.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..40b30a573e1902019c2caad96eb861df1cf6b1fe
--- /dev/null
+++ b/storage/ndb/include/kernel/signaldata/AllocNodeId.hpp
@@ -0,0 +1,65 @@
+/* Copyright (C) 2003 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; either version 2 of the License, or
+   (at your option) any later version.
+
+   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 ALLOC_NODE_ID_HPP
+#define ALLOC_NODE_ID_HPP
+
+#include "SignalData.hpp"
+#include <NodeBitmask.hpp>
+
+/**
+ * Request to allocate node id
+ */
+class AllocNodeIdReq {
+public:
+  STATIC_CONST( SignalLength = 3 );
+
+  Uint32 senderRef;
+  Uint32 senderData;
+  Uint32 nodeId;
+};
+
+class AllocNodeIdConf {
+public:
+  STATIC_CONST( SignalLength = 3 );
+
+  Uint32 senderRef;
+  Uint32 senderData;
+  Uint32 nodeId;
+};
+
+class AllocNodeIdRef {
+public:
+  STATIC_CONST( SignalLength = 5 );
+
+  enum ErrorCodes {
+    NoError = 0,
+    Undefined = 1,
+    NF_FakeErrorREF = 11,
+    Busy  = 701,
+    NotMaster  = 702,
+    NodeReserved = 1701,
+    NodeConnected = 1702,
+    NodeFailureHandlingNotCompleted = 1703
+  };
+
+  Uint32 senderRef;
+  Uint32 senderData;
+  Uint32 nodeId;
+  Uint32 errorCode;
+  Uint32 masterRef;
+};
+#endif
diff --git a/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp b/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp
index d2f4c7d57cc8fc734caace43406d00c3a95dd9c6..86c9aa36b94074b457313c3faa1b7b1affe2d3be 100644
--- a/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp
+++ b/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp
@@ -1509,6 +1509,9 @@ void Ndbcntr::execNODE_FAILREP(Signal* signal)
   sendSignal(SUMA_REF, GSN_NODE_FAILREP, signal,
 	     NodeFailRep::SignalLength, JBB);
 
+  sendSignal(QMGR_REF, GSN_NODE_FAILREP, signal,
+	     NodeFailRep::SignalLength, JBB);
+
   Uint32 nodeId = 0;
   while(!allFailed.isclear()){
     nodeId = allFailed.find(nodeId + 1);
diff --git a/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp b/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp
index 4a17d56d31e4317c68a5bfe0a18290392ba6dc0e..b2202122aa15e5dcd66f0fa938fc30f8a6e207e1 100644
--- a/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp
+++ b/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp
@@ -29,6 +29,10 @@
 #include <signaldata/CmRegSignalData.hpp>
 #include <signaldata/ApiRegSignalData.hpp>
 #include <signaldata/FailRep.hpp>
+#include <signaldata/AllocNodeId.hpp>
+
+#include <SafeCounter.hpp>
+#include <RequestTracker.hpp>
 
 #include "timer.hpp"
 
@@ -222,6 +226,12 @@ private:
   void execAPI_VERSION_REQ(Signal* signal);
   void execAPI_BROADCAST_REP(Signal* signal);
 
+  void execNODE_FAILREP(Signal *);
+  void execALLOC_NODEID_REQ(Signal *);
+  void execALLOC_NODEID_CONF(Signal *);
+  void execALLOC_NODEID_REF(Signal *);
+  void completeAllocNodeIdReq(Signal *);
+
   // Arbitration signals
   void execARBIT_CFG(Signal* signal);
   void execARBIT_PREPREQ(Signal* signal);
@@ -388,6 +398,14 @@ private:
   Uint16 cprepFailedNodes[MAX_NDB_NODES];
   Uint16 ccommitFailedNodes[MAX_NDB_NODES];
 
+  struct OpAllocNodeIdReq {
+    RequestTracker m_tracker;
+    AllocNodeIdReq m_req;
+    Uint32 m_connectCount;
+    Uint32 m_error;
+  };
+
+  struct OpAllocNodeIdReq opAllocNodeIdReq;
 };
 
 #endif
diff --git a/storage/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp b/storage/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp
index 751641ae896f4dd3bb24db5525037f34d4371061..ef3b836d2035238c5230834bdb28ae165934216c 100644
--- a/storage/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp
+++ b/storage/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp
@@ -85,6 +85,11 @@ Qmgr::Qmgr(const class Configuration & conf)
   addRecSignal(GSN_READ_NODESREQ, &Qmgr::execREAD_NODESREQ);
   addRecSignal(GSN_SET_VAR_REQ,  &Qmgr::execSET_VAR_REQ);
   addRecSignal(GSN_API_BROADCAST_REP,  &Qmgr::execAPI_BROADCAST_REP);
+
+  addRecSignal(GSN_NODE_FAILREP, &Qmgr::execNODE_FAILREP);
+  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);
   
   // Arbitration signals
   addRecSignal(GSN_ARBIT_PREPREQ, &Qmgr::execARBIT_PREPREQ);
diff --git a/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp b/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
index 0d1c7b8c500d34d79f9c97679432167ef4815142..d18375beeef0a63b7d6e0a0f9e22519b69945a1f 100644
--- a/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
+++ b/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
@@ -3984,3 +3984,167 @@ Qmgr::execAPI_BROADCAST_REP(Signal* signal)
   NodeReceiverGroup rg(API_CLUSTERMGR, mask);
   sendSignal(rg, api.gsn, signal, len, JBB); // forward sections
 }
+
+void
+Qmgr::execNODE_FAILREP(Signal * signal)
+{
+  jamEntry();
+  // make sure any distributed signals get acknowledged
+  // destructive of the signal
+  c_counterMgr.execNODE_FAILREP(signal);
+}
+
+void
+Qmgr::execALLOC_NODEID_REQ(Signal * signal)
+{
+  jamEntry();
+  const AllocNodeIdReq * req = (AllocNodeIdReq*)signal->getDataPtr();
+  Uint32 senderRef = req->senderRef;
+  Uint32 nodeId = req->nodeId;
+  Uint32 error = 0;
+
+  if (refToBlock(senderRef) != QMGR) // request from management server
+  {
+    /* master */
+
+    if (getOwnNodeId() != cpresident)
+      error = AllocNodeIdRef::NotMaster;
+    else if (!opAllocNodeIdReq.m_tracker.done())
+      error = AllocNodeIdRef::Busy;
+    else if (c_connectedNodes.get(nodeId))
+      error = AllocNodeIdRef::NodeConnected;
+
+    if (error)
+    {
+      jam();
+      AllocNodeIdRef * ref = (AllocNodeIdRef*)signal->getDataPtrSend();
+      ref->senderRef = reference();
+      ref->errorCode = error;
+      ref->masterRef = numberToRef(QMGR, cpresident);
+      sendSignal(senderRef, GSN_ALLOC_NODEID_REF, signal,
+                 AllocNodeIdRef::SignalLength, JBB);
+      return;
+    }
+
+    opAllocNodeIdReq.m_req = *req;
+    opAllocNodeIdReq.m_error = 0;
+    opAllocNodeIdReq.m_connectCount = getNodeInfo(refToNode(senderRef)).m_connectCount;
+
+    jam();
+    AllocNodeIdReq * req = (AllocNodeIdReq*)signal->getDataPtrSend();
+    req->senderRef = reference();
+    NodeReceiverGroup rg(QMGR, c_clusterNodes);
+    RequestTracker & p = opAllocNodeIdReq.m_tracker;
+    p.init<AllocNodeIdRef>(c_counterMgr, rg, GSN_ALLOC_NODEID_REF, 0);
+
+    sendSignal(rg, GSN_ALLOC_NODEID_REQ, signal,
+               AllocNodeIdReq::SignalLength, JBB);
+    return;
+  }
+
+  /* participant */
+
+  if (c_connectedNodes.get(nodeId))
+    error = AllocNodeIdRef::NodeConnected;
+  else
+  {
+    NodeRecPtr nodePtr;
+    nodePtr.i = nodeId;
+    ptrAss(nodePtr, nodeRec);
+    if (nodePtr.p->failState != NORMAL)
+      error = AllocNodeIdRef::NodeFailureHandlingNotCompleted;
+  }
+
+  if (error)
+  {
+    AllocNodeIdRef * ref = (AllocNodeIdRef*)signal->getDataPtrSend();
+    ref->senderRef = reference();
+    ref->errorCode = error;
+    sendSignal(senderRef, GSN_ALLOC_NODEID_REF, signal,
+               AllocNodeIdRef::SignalLength, JBB);
+    return;
+  }
+
+  AllocNodeIdConf * conf = (AllocNodeIdConf*)signal->getDataPtrSend();
+  conf->senderRef = reference();
+  sendSignal(senderRef, GSN_ALLOC_NODEID_CONF, signal,
+             AllocNodeIdConf::SignalLength, JBB);
+}
+
+void
+Qmgr::execALLOC_NODEID_CONF(Signal * signal)
+{
+  /* master */
+
+  jamEntry();
+  const AllocNodeIdConf * conf = (AllocNodeIdConf*)signal->getDataPtr();
+  opAllocNodeIdReq.m_tracker.reportConf(c_counterMgr,
+                                        refToNode(conf->senderRef));
+  completeAllocNodeIdReq(signal);
+}
+
+
+void
+Qmgr::execALLOC_NODEID_REF(Signal * signal)
+{
+  /* master */
+
+  jamEntry();
+  const AllocNodeIdRef * ref = (AllocNodeIdRef*)signal->getDataPtr();
+  if (ref->errorCode == AllocNodeIdRef::NF_FakeErrorREF)
+  {
+    opAllocNodeIdReq.m_tracker.ignoreRef(c_counterMgr,
+                                         refToNode(ref->senderRef));    
+  }
+  else
+  {
+    opAllocNodeIdReq.m_tracker.reportRef(c_counterMgr,
+                                         refToNode(ref->senderRef));
+    if (opAllocNodeIdReq.m_error == 0)
+      opAllocNodeIdReq.m_error = ref->errorCode;
+  }
+  completeAllocNodeIdReq(signal);
+}
+
+void
+Qmgr::completeAllocNodeIdReq(Signal *signal)
+{
+  /* master */
+
+  if (!opAllocNodeIdReq.m_tracker.done())
+  {
+    jam();
+    return;
+  }
+
+  if (opAllocNodeIdReq.m_connectCount !=
+      getNodeInfo(refToNode(opAllocNodeIdReq.m_req.senderRef)).m_connectCount)
+  {
+    // management server not same version as the original requester
+    jam();
+    return;
+  }
+
+  if (opAllocNodeIdReq.m_tracker.hasRef())
+  {
+    jam();
+    AllocNodeIdRef * ref = (AllocNodeIdRef*)signal->getDataPtrSend();
+    ref->senderRef = reference();
+    ref->senderData = opAllocNodeIdReq.m_req.senderData;
+    ref->nodeId = opAllocNodeIdReq.m_req.nodeId;
+    ref->errorCode = opAllocNodeIdReq.m_error;
+    ref->masterRef = numberToRef(QMGR, cpresident);
+    ndbassert(AllocNodeIdRef::SignalLength == 5);
+    sendSignal(opAllocNodeIdReq.m_req.senderRef, GSN_ALLOC_NODEID_REF, signal,
+               AllocNodeIdRef::SignalLength, JBB);
+    return;
+  }
+  jam();
+  AllocNodeIdConf * conf = (AllocNodeIdConf*)signal->getDataPtrSend();
+  conf->senderRef = reference();
+  conf->senderData = opAllocNodeIdReq.m_req.senderData;
+  conf->nodeId = opAllocNodeIdReq.m_req.nodeId;
+  ndbassert(AllocNodeIdConf::SignalLength == 3);
+  sendSignal(opAllocNodeIdReq.m_req.senderRef, GSN_ALLOC_NODEID_CONF, signal,
+             AllocNodeIdConf::SignalLength, JBB);
+}
diff --git a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp
index b3a25eaa0da1951b346ea927361d020dd6aef50c..cf9965b94e0dd687ce1710e1bce94eca8468b177 100644
--- a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp
+++ b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp
@@ -40,6 +40,7 @@
 #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>
@@ -1712,6 +1713,88 @@ MgmtSrvr::get_connected_nodes(NodeBitmask &connected_nodes) const
   }
 }
 
+int
+MgmtSrvr::alloc_node_id_req(Uint32 free_node_id)
+{
+  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;
+
+  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)
+        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,
@@ -1836,6 +1919,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);
+    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;
diff --git a/storage/ndb/src/mgmsrv/MgmtSrvr.hpp b/storage/ndb/src/mgmsrv/MgmtSrvr.hpp
index 0e2ebad8188bff15a5e1d1e8bac6590dcfcf20a5..ec6ab47bc2a4ca96f5a57816a15906ba92e007ba 100644
--- a/storage/ndb/src/mgmsrv/MgmtSrvr.hpp
+++ b/storage/ndb/src/mgmsrv/MgmtSrvr.hpp
@@ -506,7 +506,8 @@ private:
    *   @return  -1 if block not found, otherwise block number
    */
   int getBlockNumber(const BaseString &blockName);
-  
+
+  int alloc_node_id_req(Uint32 free_node_id);
   //**************************************************************************
   
   int _blockNumber;
diff --git a/storage/ndb/src/ndbapi/ndberror.c b/storage/ndb/src/ndbapi/ndberror.c
index 389c1008536eaa20965e40423b31044f7d51cac9..6ea45fd0d60c9d6bccf4b17623fa5b5813e1398e 100644
--- a/storage/ndb/src/ndbapi/ndberror.c
+++ b/storage/ndb/src/ndbapi/ndberror.c
@@ -81,6 +81,7 @@ static const char* empty_string = "";
  * 1400 - SUMA
  * 1500 - LGMAN
  * 1600 - TSMAN
+ * 1700 - QMGR
  * 4000 - API
  * 4100 - ""
  * 4200 - ""
@@ -450,6 +451,15 @@ ErrorBundle ErrorCodes[] = {
   { 1348, DMEC, AE, "Backup failed to allocate file record (check configuration)" },
   { 1349, DMEC, AE, "Backup failed to allocate attribute record (check configuration)" },
   { 1329, DMEC, AE, "Backup during software upgrade not supported" },
+
+  /**
+   * Node id allocation error codes
+   */ 
+
+  { 1700, DMEC, IE, "Undefined error" },
+  { 1701, DMEC, AE, "Node already reserved" },
+  { 1702, DMEC, AE, "Node already connected" },
+  { 1703, DMEC, AE, "Node failure handling not completed" },
   
   /**
    * Still uncategorized