diff --git a/storage/ndb/src/common/util/InputStream.cpp b/storage/ndb/src/common/util/InputStream.cpp
index 17703eb7e52d4e644e0313aab4596938026d3624..ee7f2d5c8b267b4999b4551067e2cab1206d17cd 100644
--- a/storage/ndb/src/common/util/InputStream.cpp
+++ b/storage/ndb/src/common/util/InputStream.cpp
@@ -59,6 +59,7 @@ SocketInputStream::gets(char * buf, int bufLen) {
 
   if(res == 0)
   {
+    m_timedout= true;
     buf[0]=0;
     return buf;
   }
@@ -67,7 +68,6 @@ SocketInputStream::gets(char * buf, int bufLen) {
 
   if(res == -1)
   {
-    m_timedout= true;
     return 0;
   }
 
diff --git a/storage/ndb/src/mgmapi/mgmapi.cpp b/storage/ndb/src/mgmapi/mgmapi.cpp
index a0a6493f41da704a7637381b1375395a36f384f2..5671bf1561d2f0e38ead1391a4eb11fe49576b13 100644
--- a/storage/ndb/src/mgmapi/mgmapi.cpp
+++ b/storage/ndb/src/mgmapi/mgmapi.cpp
@@ -137,18 +137,41 @@ setError(NdbMgmHandle h, int error, int error_line, const char * msg, ...){
     return ret; \
   }
 
-#define CHECK_REPLY(reply, ret) \
+#define CHECK_REPLY(handle, reply, ret) \
   if(reply == NULL) { \
-    SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_REPLY, ""); \
+    if(!handle->last_error) \
+      SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_REPLY, ""); \
     return ret; \
   }
 
-#define DBUG_CHECK_REPLY(reply, ret) \
+#define DBUG_CHECK_REPLY(handle, reply, ret) \
   if (reply == NULL) { \
-    SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_REPLY, ""); \
+    if(!handle->last_error) \
+      SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_REPLY, ""); \
     DBUG_RETURN(ret);                                    \
   }
 
+#define CHECK_TIMEDOUT(in, out) \
+  if(in.timedout() || out.timedout()) \
+    SET_ERROR(handle, ETIMEDOUT, \
+              "Time out talking to management server");
+
+#define CHECK_TIMEDOUT_RET(h, in, out, ret) \
+  if(in.timedout() || out.timedout()) { \
+    SET_ERROR(handle, ETIMEDOUT, \
+              "Time out talking to management server"); \
+    ndb_mgm_disconnect_quiet(h); \
+    return ret; \
+  }
+
+#define DBUG_CHECK_TIMEDOUT_RET(h, in, out, ret) \
+  if(in.timedout() || out.timedout()) { \
+    SET_ERROR(handle, ETIMEDOUT, \
+              "Time out talking to management server"); \
+    ndb_mgm_disconnect_quiet(h); \
+    DBUG_RETURN(ret); \
+  }
+
 /*****************************************************************************
  * Handles
  *****************************************************************************/
@@ -375,6 +398,8 @@ ndb_mgm_call(NdbMgmHandle handle, const ParserRow<ParserDummy> *command_reply,
   }
   out.println("");
 
+  CHECK_TIMEDOUT_RET(handle, in, out, NULL);
+
   Parser_t::Context ctx;
   ParserDummy session(handle->socket);
   Parser_t parser(command_reply, in, true, true, true);
@@ -382,14 +407,17 @@ ndb_mgm_call(NdbMgmHandle handle, const ParserRow<ParserDummy> *command_reply,
   const Properties* p = parser.parse(ctx, session);
   if (p == NULL){
     if(!ndb_mgm_is_connected(handle)) {
+      CHECK_TIMEDOUT_RET(handle, in, out, NULL);
       DBUG_RETURN(NULL);
     }
     else
     {
+      CHECK_TIMEDOUT_RET(handle, in, out, NULL);
       if(ctx.m_status==Parser_t::Eof
 	 || ctx.m_status==Parser_t::NoLine)
       {
 	ndb_mgm_disconnect(handle);
+        CHECK_TIMEDOUT_RET(handle, in, out, NULL);
 	DBUG_RETURN(NULL);
       }
       /**
@@ -411,6 +439,10 @@ ndb_mgm_call(NdbMgmHandle handle, const ParserRow<ParserDummy> *command_reply,
     p->print(handle->logfile, "IN: ");
   }
 #endif
+
+  if(p && (in.timedout() || out.timedout()))
+    delete p;
+  CHECK_TIMEDOUT_RET(handle, in, out, NULL);
   DBUG_RETURN(p);
 }
 
@@ -603,6 +635,22 @@ ndb_mgm_get_fd(NdbMgmHandle handle)
   return handle->socket;
 }
 
+/**
+ * Disconnect from mgm server without error checking
+ * Should be used internally only.
+ * e.g. on timeout, we leave NdbMgmHandle disconnected
+ */
+extern "C"
+int
+ndb_mgm_disconnect_quiet(NdbMgmHandle handle)
+{
+  NDB_CLOSE_SOCKET(handle->socket);
+  handle->socket = NDB_INVALID_SOCKET;
+  handle->connected = 0;
+
+  return 0;
+}
+
 /**
  * Disconnect from a mgm server
  */
@@ -614,11 +662,7 @@ ndb_mgm_disconnect(NdbMgmHandle handle)
   CHECK_HANDLE(handle, -1);
   CHECK_CONNECTED(handle, -1);
 
-  NDB_CLOSE_SOCKET(handle->socket);
-  handle->socket = NDB_INVALID_SOCKET;
-  handle->connected = 0;
-
-  return 0;
+  return ndb_mgm_disconnect_quiet(handle);
 }
 
 struct ndb_mgm_type_atoi 
@@ -787,18 +831,24 @@ ndb_mgm_get_status(NdbMgmHandle handle)
   out.println("get status");
   out.println("");
 
+  CHECK_TIMEDOUT_RET(handle, in, out, NULL);
+
   char buf[1024];
   if(!in.gets(buf, sizeof(buf)))
   {
+    CHECK_TIMEDOUT_RET(handle, in, out, NULL);
     SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_REPLY, "Probably disconnected");
     return NULL;
   }
   if(strcmp("node status\n", buf) != 0) {
+    CHECK_TIMEDOUT_RET(handle, in, out, NULL);
+    ndbout << in.timedout() << " " << out.timedout() << buf << endl;
     SET_ERROR(handle, NDB_MGM_ILLEGAL_NODE_STATUS, buf);
     return NULL;
   }
   if(!in.gets(buf, sizeof(buf)))
   {
+    CHECK_TIMEDOUT_RET(handle, in, out, NULL);
     SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_REPLY, "Probably disconnected");
     return NULL;
   }
@@ -807,6 +857,7 @@ ndb_mgm_get_status(NdbMgmHandle handle)
   Vector<BaseString> split;
   tmp.split(split, ":");
   if(split.size() != 2){
+    CHECK_TIMEDOUT_RET(handle, in, out, NULL);
     SET_ERROR(handle, NDB_MGM_ILLEGAL_NODE_STATUS, buf);
     return NULL;
   }
@@ -841,8 +892,12 @@ ndb_mgm_get_status(NdbMgmHandle handle)
     if(!in.gets(buf, sizeof(buf)))
     {
       free(state);
-      SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_REPLY,
-                "Probably disconnected");
+      if(in.timedout() || out.timedout())
+        SET_ERROR(handle, ETIMEDOUT,
+                  "Time out talking to management server");
+      else
+        SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_REPLY,
+                  "Probably disconnected");
       return NULL;
     }
     tmp.assign(buf);
@@ -873,6 +928,7 @@ ndb_mgm_get_status(NdbMgmHandle handle)
 
   if(i+1 != noOfNodes){
     free(state);
+    CHECK_TIMEDOUT_RET(handle, in, out, NULL);
     SET_ERROR(handle, NDB_MGM_ILLEGAL_NODE_STATUS, "Node count mismatch");
     return NULL;
   }
@@ -901,7 +957,7 @@ ndb_mgm_enter_single_user(NdbMgmHandle handle,
   args.put("nodeId", nodeId);
   const Properties *reply;
   reply = ndb_mgm_call(handle, enter_single_reply, "enter single user", &args);
-  CHECK_REPLY(reply, -1);
+  CHECK_REPLY(handle, reply, -1);
 
   BaseString result;
   reply->get("result", result);
@@ -932,7 +988,7 @@ ndb_mgm_exit_single_user(NdbMgmHandle handle, struct ndb_mgm_reply* /*reply*/)
 
   const Properties *reply;
   reply = ndb_mgm_call(handle, exit_single_reply, "exit single user", 0);
-  CHECK_REPLY(reply, -1);
+  CHECK_REPLY(handle, reply, -1);
 
   const char * buf;
   reply->get("result", &buf);
@@ -1029,7 +1085,7 @@ ndb_mgm_stop3(NdbMgmHandle handle, int no_of_nodes, const int * node_list,
       reply = ndb_mgm_call(handle, stop_reply_v2, "stop all", &args);
     else
       reply = ndb_mgm_call(handle, stop_reply_v1, "stop all", &args);
-    CHECK_REPLY(reply, -1);
+    CHECK_REPLY(handle, reply, -1);
 
     if(!reply->get("stopped", &stoppedNoOfNodes)){
       SET_ERROR(handle, NDB_MGM_STOP_FAILED, 
@@ -1071,7 +1127,7 @@ ndb_mgm_stop3(NdbMgmHandle handle, int no_of_nodes, const int * node_list,
   else
     reply = ndb_mgm_call(handle, stop_reply_v1, "stop", &args);
 
-  CHECK_REPLY(reply, stoppedNoOfNodes);
+  CHECK_REPLY(handle, reply, stoppedNoOfNodes);
   if(!reply->get("stopped", &stoppedNoOfNodes)){
     SET_ERROR(handle, NDB_MGM_STOP_FAILED, 
 	      "Could not get number of stopped nodes from mgm server");
@@ -1174,7 +1230,7 @@ ndb_mgm_restart3(NdbMgmHandle handle, int no_of_nodes, const int * node_list,
     handle->read_timeout= 5*60*1000; // 5 minutes
     reply = ndb_mgm_call(handle, restart_reply_v1, "restart all", &args);
     handle->read_timeout= timeout;
-    CHECK_REPLY(reply, -1);
+    CHECK_REPLY(handle, reply, -1);
 
     BaseString result;
     reply->get("result", result);
@@ -1301,7 +1357,7 @@ ndb_mgm_get_clusterlog_severity_filter(NdbMgmHandle handle,
   Properties args;
   const Properties *reply;
   reply = ndb_mgm_call(handle, getinfo_reply, "get info clusterlog", &args);
-  CHECK_REPLY(reply, -1);
+  CHECK_REPLY(handle, reply, -1);
   
   for(unsigned int i=0; i < severity_size; i++) {
     reply->get(clusterlog_severity_names[severity[i].category], &severity[i].value);
@@ -1332,7 +1388,7 @@ ndb_mgm_get_clusterlog_severity_filter_old(NdbMgmHandle handle)
   Properties args;
   const Properties *reply;
   reply = ndb_mgm_call(handle, getinfo_reply, "get info clusterlog", &args);
-  CHECK_REPLY(reply, NULL);
+  CHECK_REPLY(handle, reply, NULL);
   
   for(int i=0; i < (int)NDB_MGM_EVENT_SEVERITY_ALL; i++) {
     reply->get(clusterlog_severity_names[i], &enabled[i]);
@@ -1364,7 +1420,7 @@ ndb_mgm_set_clusterlog_severity_filter(NdbMgmHandle handle,
   
   const Properties *reply;
   reply = ndb_mgm_call(handle, filter_reply, "set logfilter", &args);
-  CHECK_REPLY(reply, retval);
+  CHECK_REPLY(handle, reply, retval);
 
   BaseString result;
   reply->get("result", result);
@@ -1458,7 +1514,7 @@ ndb_mgm_get_clusterlog_loglevel(NdbMgmHandle handle,
   Properties args;
   const Properties *reply;
   reply = ndb_mgm_call(handle, getloglevel_reply, "get cluster loglevel", &args);
-  CHECK_REPLY(reply, -1);
+  CHECK_REPLY(handle, reply, -1);
 
   for(int i=0; i < loglevel_count; i++) {
     reply->get(clusterlog_names[loglevel[i].category], &loglevel[i].value);
@@ -1494,7 +1550,7 @@ ndb_mgm_get_clusterlog_loglevel_old(NdbMgmHandle handle)
   Properties args;
   const Properties *reply;
   reply = ndb_mgm_call(handle, getloglevel_reply, "get cluster loglevel", &args);
-  CHECK_REPLY(reply, NULL);
+  CHECK_REPLY(handle, reply, NULL);
 
   for(int i=0; i < loglevel_count; i++) {
     reply->get(clusterlog_names[i], &loglevel[i]);
@@ -1527,7 +1583,7 @@ ndb_mgm_set_clusterlog_loglevel(NdbMgmHandle handle, int nodeId,
   const Properties *reply;
   reply = ndb_mgm_call(handle, clusterlog_reply, 
 		       "set cluster loglevel", &args);
-  CHECK_REPLY(reply, -1);
+  CHECK_REPLY(handle, reply, -1);
   
   DBUG_ENTER("ndb_mgm_set_clusterlog_loglevel");
   DBUG_PRINT("enter",("node=%d, category=%d, level=%d", nodeId, cat, level));
@@ -1565,7 +1621,7 @@ ndb_mgm_set_loglevel_node(NdbMgmHandle handle, int nodeId,
   args.put("level", level);
   const Properties *reply;
   reply = ndb_mgm_call(handle, loglevel_reply, "set loglevel", &args);
-  CHECK_REPLY(reply, -1);
+  CHECK_REPLY(handle, reply, -1);
 
   BaseString result;
   reply->get("result", result);
@@ -1624,7 +1680,7 @@ ndb_mgm_listen_event_internal(NdbMgmHandle handle, const int filter[],
 
   if(reply == NULL) {
     close(sockfd);
-    CHECK_REPLY(reply, -1);
+    CHECK_REPLY(handle, reply, -1);
   }
   delete reply;
   return sockfd;
@@ -1668,7 +1724,7 @@ ndb_mgm_dump_state(NdbMgmHandle handle, int nodeId, const int * _args,
 
   const Properties *prop;
   prop = ndb_mgm_call(handle, dump_state_reply, "dump state", &args);
-  CHECK_REPLY(prop, -1);
+  CHECK_REPLY(handle, prop, -1);
 
   BaseString result;
   prop->get("result", result);
@@ -1705,6 +1761,7 @@ ndb_mgm_start_signallog(NdbMgmHandle handle, int nodeId,
 		       start_signallog_reply,
 		       "start signallog",
 		       &args);
+  CHECK_REPLY(handle, prop, -1);
 
   if(prop != NULL) {
     BaseString result;
@@ -1741,6 +1798,7 @@ ndb_mgm_stop_signallog(NdbMgmHandle handle, int nodeId,
 
   const Properties *prop;
   prop = ndb_mgm_call(handle, stop_signallog_reply, "stop signallog", &args);
+  CHECK_REPLY(handle, prop, -1);
 
   if(prop != NULL) {
     BaseString result;
@@ -1805,6 +1863,7 @@ ndb_mgm_log_signals(NdbMgmHandle handle, int nodeId,
 
   const Properties *prop;
   prop = ndb_mgm_call(handle, stop_signallog_reply, "log signals", &args);
+  CHECK_REPLY(handle, prop, -1);
 
   if(prop != NULL) {
     BaseString result;
@@ -1842,6 +1901,7 @@ ndb_mgm_set_trace(NdbMgmHandle handle, int nodeId, int traceNumber,
 
   const Properties *prop;
   prop = ndb_mgm_call(handle, set_trace_reply, "set trace", &args);
+  CHECK_REPLY(handle, prop, -1);
 
   if(prop != NULL) {
     BaseString result;
@@ -1879,6 +1939,7 @@ ndb_mgm_insert_error(NdbMgmHandle handle, int nodeId, int errorCode,
 
   const Properties *prop;
   prop = ndb_mgm_call(handle, insert_error_reply, "insert error", &args);
+  CHECK_REPLY(handle, prop, -1);
 
   if(prop != NULL) {
     BaseString result;
@@ -1919,7 +1980,7 @@ ndb_mgm_start(NdbMgmHandle handle, int no_of_nodes, const int * node_list)
     Properties args;
     const Properties *reply;
     reply = ndb_mgm_call(handle, start_reply, "start all", &args);
-    CHECK_REPLY(reply, -1);
+    CHECK_REPLY(handle, reply, -1);
 
     Uint32 count = 0;
     if(!reply->get("started", &count)){
@@ -1985,7 +2046,7 @@ ndb_mgm_start_backup(NdbMgmHandle handle, int wait_completed,
     reply = ndb_mgm_call(handle, start_backup_reply, "start backup", &args);
     handle->read_timeout= old_timeout;
   }
-  CHECK_REPLY(reply, -1);
+  CHECK_REPLY(handle, reply, -1);
 
   BaseString result;
   reply->get("result", result);
@@ -2019,7 +2080,7 @@ ndb_mgm_abort_backup(NdbMgmHandle handle, unsigned int backupId,
 
   const Properties *prop;
   prop = ndb_mgm_call(handle, stop_backup_reply, "abort backup", &args);
-  CHECK_REPLY(prop, -1);
+  CHECK_REPLY(handle, prop, -1);
 
   const char * buf;
   prop->get("result", &buf);
@@ -2036,7 +2097,7 @@ ndb_mgm_abort_backup(NdbMgmHandle handle, unsigned int backupId,
 extern "C"
 struct ndb_mgm_configuration *
 ndb_mgm_get_configuration(NdbMgmHandle handle, unsigned int version) {
-
+  SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_get_configuration");
   CHECK_HANDLE(handle, 0);
   CHECK_CONNECTED(handle, 0);
 
@@ -2054,7 +2115,7 @@ ndb_mgm_get_configuration(NdbMgmHandle handle, unsigned int version) {
   
   const Properties *prop;
   prop = ndb_mgm_call(handle, reply, "get config", &args);
-  CHECK_REPLY(prop, 0);
+  CHECK_REPLY(handle, prop, 0);
   
   do {
     const char * buf;
@@ -2091,9 +2152,14 @@ ndb_mgm_get_configuration(NdbMgmHandle handle, unsigned int version) {
     size_t start = 0;
     do {
       if((read = read_socket(handle->socket, handle->read_timeout, 
-			     &buf64[start], len-start)) == -1){
-	delete[] buf64; 
+			     &buf64[start], len-start)) < 1){
+	delete[] buf64;
 	buf64 = 0;
+        if(read==0)
+          SET_ERROR(handle, ETIMEDOUT, "Timeout reading packed config");
+        else
+          SET_ERROR(handle, errno, "Error reading packed config");
+        ndb_mgm_disconnect_quiet(handle);
 	break;
       }
       start += read;
@@ -2214,7 +2280,7 @@ ndb_mgm_alloc_nodeid(NdbMgmHandle handle, unsigned int version, int nodetype,
   
   const Properties *prop;
   prop= ndb_mgm_call(handle, reply, "get nodeid", &args);
-  CHECK_REPLY(prop, -1);
+  CHECK_REPLY(handle, prop, -1);
 
   nodeid= -1;
   do {
@@ -2266,7 +2332,7 @@ ndb_mgm_set_int_parameter(NdbMgmHandle handle,
   
   const Properties *prop;
   prop= ndb_mgm_call(handle, reply, "set parameter", &args);
-  CHECK_REPLY(prop, -1);
+  CHECK_REPLY(handle, prop, -1);
 
   int res= -1;
   do {
@@ -2305,7 +2371,8 @@ ndb_mgm_set_int64_parameter(NdbMgmHandle handle,
   
   const Properties *prop;
   prop= ndb_mgm_call(handle, reply, "set parameter", &args);
-  
+  CHECK_REPLY(handle, prop, 0);
+
   if(prop == NULL) {
     SET_ERROR(handle, EIO, "Unable set parameter");
     return -1;
@@ -2348,6 +2415,7 @@ ndb_mgm_set_string_parameter(NdbMgmHandle handle,
   
   const Properties *prop;
   prop= ndb_mgm_call(handle, reply, "set parameter", &args);
+  CHECK_REPLY(handle, prop, 0);
   
   if(prop == NULL) {
     SET_ERROR(handle, EIO, "Unable set parameter");
@@ -2385,7 +2453,8 @@ ndb_mgm_purge_stale_sessions(NdbMgmHandle handle, char **purged){
   
   const Properties *prop;
   prop= ndb_mgm_call(handle, reply, "purge stale sessions", &args);
-  
+  CHECK_REPLY(handle, prop, -1);
+
   if(prop == NULL) {
     SET_ERROR(handle, EIO, "Unable to purge stale sessions");
     return -1;
@@ -2470,7 +2539,7 @@ ndb_mgm_set_connection_int_parameter(NdbMgmHandle handle,
   
   const Properties *prop;
   prop= ndb_mgm_call(handle, reply, "set connection parameter", &args);
-  DBUG_CHECK_REPLY(prop, -1);
+  DBUG_CHECK_REPLY(handle, prop, -1);
 
   int res= -1;
   do {
@@ -2512,7 +2581,7 @@ ndb_mgm_get_connection_int_parameter(NdbMgmHandle handle,
   
   const Properties *prop;
   prop = ndb_mgm_call(handle, reply, "get connection parameter", &args);
-  DBUG_CHECK_REPLY(prop, -3);
+  DBUG_CHECK_REPLY(handle, prop, -3);
 
   int res= -1;
   do {
@@ -2574,7 +2643,7 @@ ndb_mgm_get_mgmd_nodeid(NdbMgmHandle handle)
   
   const Properties *prop;
   prop = ndb_mgm_call(handle, reply, "get mgmd nodeid", &args);
-  DBUG_CHECK_REPLY(prop, 0);
+  DBUG_CHECK_REPLY(handle, prop, 0);
 
   if(!prop->get("nodeid",&nodeid)){
     fprintf(handle->errstream, "Unable to get value\n");
@@ -2609,7 +2678,7 @@ int ndb_mgm_report_event(NdbMgmHandle handle, Uint32 *data, Uint32 length)
   
   const Properties *prop;
   prop = ndb_mgm_call(handle, reply, "report event", &args);
-  DBUG_CHECK_REPLY(prop, -1);
+  DBUG_CHECK_REPLY(handle, prop, -1);
 
   DBUG_RETURN(0);
 }
@@ -2628,6 +2697,7 @@ int ndb_mgm_end_session(NdbMgmHandle handle)
   SocketInputStream in(handle->socket, handle->read_timeout);
   char buf[32];
   in.gets(buf, sizeof(buf));
+  CHECK_TIMEDOUT_RET(handle, in, s_output, -1);
 
   DBUG_RETURN(0);
 }
@@ -2653,7 +2723,7 @@ int ndb_mgm_get_version(NdbMgmHandle handle,
 
   const Properties *prop;
   prop = ndb_mgm_call(handle, reply, "get version", &args);
-  CHECK_REPLY(prop, 0);
+  CHECK_REPLY(handle, prop, 0);
 
   Uint32 id;
   if(!prop->get("id",&id)){
@@ -2704,7 +2774,7 @@ ndb_mgm_get_session_id(NdbMgmHandle handle)
   
   const Properties *prop;
   prop = ndb_mgm_call(handle, reply, "get session id", &args);
-  CHECK_REPLY(prop, 0);
+  CHECK_REPLY(handle, prop, 0);
 
   if(!prop->get("id",&session_id)){
     fprintf(handle->errstream, "Unable to get session id\n");
@@ -2741,7 +2811,7 @@ ndb_mgm_get_session(NdbMgmHandle handle, Uint64 id,
 
   const Properties *prop;
   prop = ndb_mgm_call(handle, reply, "get session", &args);
-  CHECK_REPLY(prop, 0);
+  CHECK_REPLY(handle, prop, 0);
 
   Uint64 r_id;
   int rlen= 0;
diff --git a/storage/ndb/src/mgmapi/mgmapi_internal.h b/storage/ndb/src/mgmapi/mgmapi_internal.h
index d30be221dcd98a73ad293b3d465934b91902d897..192bc57afd95eccfab981cc646dc8503d0a50777 100644
--- a/storage/ndb/src/mgmapi/mgmapi_internal.h
+++ b/storage/ndb/src/mgmapi/mgmapi_internal.h
@@ -68,6 +68,8 @@ extern "C" {
    */
   NDB_SOCKET_TYPE ndb_mgm_convert_to_transporter(NdbMgmHandle *handle);
 
+  int ndb_mgm_disconnect_quiet(NdbMgmHandle handle);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/storage/ndb/src/mgmsrv/Services.cpp b/storage/ndb/src/mgmsrv/Services.cpp
index 0bbdf4a9e51e51e90f1b71e9af322e12d9309955..17072c240aef7b8d33ae1a295cce370d0429db75 100644
--- a/storage/ndb/src/mgmsrv/Services.cpp
+++ b/storage/ndb/src/mgmsrv/Services.cpp
@@ -290,6 +290,8 @@ struct PurgeStruct
 
 #define ERROR_INSERTED(x) (g_errorInsert == x || m_errorInsert == x)
 
+#define SLEEP_ERROR_INSERTED(x) if(ERROR_INSERTED(x)){NdbSleep_SecSleep(10);}
+
 MgmApiSession::MgmApiSession(class MgmtSrvr & mgm, NDB_SOCKET_TYPE sock, Uint64 session_id)
   : SocketServer::Session(sock), m_mgmsrv(mgm)
 {
@@ -599,13 +601,23 @@ MgmApiSession::getConfig(Parser_t::Context &,
   
   char *tmp_str = (char *) malloc(base64_needed_encoded_length(src.length()));
   (void) base64_encode(src.get_data(), src.length(), tmp_str);
-  
+
+  SLEEP_ERROR_INSERTED(1);
+
   m_output->println("get config reply");
   m_output->println("result: Ok");
   m_output->println("Content-Length: %d", strlen(tmp_str));
   m_output->println("Content-Type: ndbconfig/octet-stream");
+  SLEEP_ERROR_INSERTED(2);
   m_output->println("Content-Transfer-Encoding: base64");
   m_output->println("");
+  if(ERROR_INSERTED(3))
+  {
+    int l= strlen(tmp_str);
+    tmp_str[l/2]='\0';
+    m_output->println(tmp_str);
+    NdbSleep_SecSleep(10);
+  }
   m_output->println(tmp_str);
 
   free(tmp_str);
@@ -748,6 +760,7 @@ MgmApiSession::endSession(Parser<MgmApiSession>::Context &,
 
   m_allocated_resources= new MgmtSrvr::Allocated_resources(m_mgmsrv);
 
+  SLEEP_ERROR_INSERTED(1);
   m_output->println("end session reply");
 }
 
@@ -998,12 +1011,16 @@ MgmApiSession::getStatus(Parser<MgmApiSession>::Context &,
   while(m_mgmsrv.getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_MGM)){
     noOfNodes++;
   }
-  
+  SLEEP_ERROR_INSERTED(1);
   m_output->println("node status");
+  SLEEP_ERROR_INSERTED(2);
   m_output->println("nodes: %d", noOfNodes);
+  SLEEP_ERROR_INSERTED(3);
   printNodeStatus(m_output, m_mgmsrv, NDB_MGM_NODE_TYPE_NDB);
   printNodeStatus(m_output, m_mgmsrv, NDB_MGM_NODE_TYPE_MGM);
+  SLEEP_ERROR_INSERTED(4);
   printNodeStatus(m_output, m_mgmsrv, NDB_MGM_NODE_TYPE_API);
+  SLEEP_ERROR_INSERTED(5);
 
   nodeId = 0;
 
@@ -1118,8 +1135,10 @@ MgmApiSession::enterSingleUser(Parser<MgmApiSession>::Context &,
 			  Properties const &args) {
   int stopped = 0;
   Uint32 nodeId = 0;
+  int result= 0;
   args.get("nodeId", &nodeId);
-  int result = m_mgmsrv.enterSingleUser(&stopped, nodeId);
+
+  result = m_mgmsrv.enterSingleUser(&stopped, nodeId);
   m_output->println("enter single user reply");
   if(result != 0) {
     m_output->println("result: %s", get_error_text(result));
@@ -1616,12 +1635,11 @@ void
 MgmApiSession::check_connection(Parser_t::Context &ctx,
 				const class Properties &args)
 {
-  if(ERROR_INSERTED(1))
-  {
-    NdbSleep_SecSleep(10);
-  }
+  SLEEP_ERROR_INSERTED(1);
   m_output->println("check connection reply");
+  SLEEP_ERROR_INSERTED(2);
   m_output->println("result: Ok");
+  SLEEP_ERROR_INSERTED(3);
   m_output->println("");
 }
 
@@ -1642,10 +1660,7 @@ MgmApiSession::get_mgmd_nodeid(Parser_t::Context &ctx,
 {
   m_output->println("get mgmd nodeid reply");
   m_output->println("nodeid:%u",m_mgmsrv.getOwnNodeId());
-  if(ERROR_INSERTED(1))
-  {
-    NdbSleep_SecSleep(10);
-  }
+  SLEEP_ERROR_INSERTED(1);
 
   m_output->println("");
 }
diff --git a/storage/ndb/test/ndbapi/testMgm.cpp b/storage/ndb/test/ndbapi/testMgm.cpp
index 35ad6c73ec159144ef1fc99602b505d009e258ec..5f3147f1d91127a8548bb28e9eb49cf432f8f95d 100644
--- a/storage/ndb/test/ndbapi/testMgm.cpp
+++ b/storage/ndb/test/ndbapi/testMgm.cpp
@@ -22,6 +22,7 @@
 #include <random.h>
 #include <mgmapi.h>
 #include <mgmapi_debug.h>
+#include <InputStream.hpp>
 
 int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){
 
@@ -191,6 +192,8 @@ int runTestApiSession(NDBT_Context* ctx, NDBT_Step* step)
   ndb_mgm_set_connectstring(h, mgm);
   ndb_mgm_connect(h,0,0,0);
 
+  NdbSleep_SecSleep(1);
+
   if(ndb_mgm_get_session(h,session_id,&sess,&slen))
   {
     ndbout << "Failed, session still exists" << endl;
@@ -207,64 +210,278 @@ int runTestApiSession(NDBT_Context* ctx, NDBT_Step* step)
   }
 }
 
-int runTestApiTimeout1(NDBT_Context* ctx, NDBT_Step* step)
+int runTestApiTimeoutBasic(NDBT_Context* ctx, NDBT_Step* step)
 {
   char *mgm= ctx->getRemoteMgm();
   int result= NDBT_FAILED;
   int cc= 0;
+  int mgmd_nodeid= 0;
+  ndb_mgm_reply reply;
 
   NdbMgmHandle h;
   h= ndb_mgm_create_handle();
   ndb_mgm_set_connectstring(h, mgm);
-  ndb_mgm_connect(h,0,0,0);
 
-  if(ndb_mgm_check_connection(h) < 0)
+  ndbout << "TEST timout check_connection" << endl;
+  for(int error_ins=1; error_ins<=3; error_ins++)
   {
-    result= NDBT_FAILED;
-    goto done;
+    ndbout << "trying error " << error_ins << endl;
+    ndb_mgm_connect(h,0,0,0);
+
+    if(ndb_mgm_check_connection(h) < 0)
+    {
+      result= NDBT_FAILED;
+      goto done;
+    }
+
+    mgmd_nodeid= ndb_mgm_get_mgmd_nodeid(h);
+    if(mgmd_nodeid==0)
+    {
+      ndbout << "Failed to get mgmd node id to insert error" << endl;
+      result= NDBT_FAILED;
+      goto done;
+    }
+
+    reply.return_code= 0;
+
+    if(ndb_mgm_insert_error(h, mgmd_nodeid, error_ins, &reply)< 0)
+    {
+      ndbout << "failed to insert error " << endl;
+      result= NDBT_FAILED;
+      goto done;
+    }
+
+    ndb_mgm_set_timeout(h,2500);
+
+    cc= ndb_mgm_check_connection(h);
+    if(cc < 0)
+      result= NDBT_OK;
+    else
+      result= NDBT_FAILED;
+
+    if(ndb_mgm_is_connected(h))
+    {
+      ndbout << "FAILED: still connected" << endl;
+      result= NDBT_FAILED;
+    }
   }
 
-  ndb_mgm_reply reply;
-  reply.return_code= 0;
+  ndbout << "TEST get_mgmd_nodeid" << endl;
+  ndb_mgm_connect(h,0,0,0);
 
-  if(ndb_mgm_insert_error(h, 3, 1, &reply)< 0)
+  if(ndb_mgm_insert_error(h, mgmd_nodeid, 0, &reply)< 0)
   {
-    ndbout << "failed to insert error " << endl;
+    ndbout << "failed to remove inserted error " << endl;
     result= NDBT_FAILED;
     goto done;
   }
 
-  ndb_mgm_set_timeout(h,2500);
-
-  cc= ndb_mgm_check_connection(h);
-  if(cc < 0)
-    result= NDBT_OK;
-  else
-    result= NDBT_FAILED;
-
-  ndbout << "test 2" << endl;
-  ndb_mgm_connect(h,0,0,0);
-
   cc= ndb_mgm_get_mgmd_nodeid(h);
+  ndbout << "got node id: " << cc << endl;
   if(cc==0)
-    result= NDBT_OK;
-  else
+  {
+    ndbout << "FAILED: didn't get node id" << endl;
     result= NDBT_FAILED;
+  }
+  else
+    result= NDBT_OK;
+
+  ndbout << "TEST end_session" << endl;
+  ndb_mgm_connect(h,0,0,0);
 
-  if(ndb_mgm_insert_error(h, 3, 0, &reply)< 0)
+  if(ndb_mgm_insert_error(h, mgmd_nodeid, 1, &reply)< 0)
   {
-    ndbout << "failed to remove inserted error " << endl;
+    ndbout << "FAILED: insert error 1" << endl;
     result= NDBT_FAILED;
     goto done;
   }
 
-  cc= ndb_mgm_get_mgmd_nodeid(h);
-  ndbout << "got node id: " << cc << endl;
+  cc= ndb_mgm_end_session(h);
   if(cc==0)
+  {
+    ndbout << "FAILED: success in calling end_session" << endl;
+    result= NDBT_FAILED;
+  }
+  else if(ndb_mgm_get_latest_error(h)!=ETIMEDOUT)
+  {
+    ndbout << "FAILED: Incorrect error code (" << ndb_mgm_get_latest_error(h)
+           << " != expected " << ETIMEDOUT << ") desc: "
+           << ndb_mgm_get_latest_error_desc(h)
+           << " line: " << ndb_mgm_get_latest_error_line(h)
+           << " msg: " << ndb_mgm_get_latest_error_msg(h)
+           << endl;
     result= NDBT_FAILED;
+  }
   else
     result= NDBT_OK;
 
+  if(ndb_mgm_is_connected(h))
+  {
+    ndbout << "FAILED: is still connected after error" << endl;
+    result= NDBT_FAILED;
+  }
+done:
+  ndb_mgm_disconnect(h);
+  ndb_mgm_destroy_handle(&h);
+
+  return result;
+}
+
+int runTestApiGetStatusTimeout(NDBT_Context* ctx, NDBT_Step* step)
+{
+  char *mgm= ctx->getRemoteMgm();
+  int result= NDBT_OK;
+  int cc= 0;
+  int mgmd_nodeid= 0;
+
+  NdbMgmHandle h;
+  h= ndb_mgm_create_handle();
+  ndb_mgm_set_connectstring(h, mgm);
+
+  for(int error_ins=0; error_ins<=5; error_ins++)
+  {
+    ndb_mgm_connect(h,0,0,0);
+
+    if(ndb_mgm_check_connection(h) < 0)
+    {
+      result= NDBT_FAILED;
+      goto done;
+    }
+
+    mgmd_nodeid= ndb_mgm_get_mgmd_nodeid(h);
+    if(mgmd_nodeid==0)
+    {
+      ndbout << "Failed to get mgmd node id to insert error" << endl;
+      result= NDBT_FAILED;
+      goto done;
+    }
+
+    ndb_mgm_reply reply;
+    reply.return_code= 0;
+
+    if(ndb_mgm_insert_error(h, mgmd_nodeid, error_ins, &reply)< 0)
+    {
+      ndbout << "failed to insert error " << error_ins << endl;
+      result= NDBT_FAILED;
+    }
+
+    ndbout << "trying error: " << error_ins << endl;
+
+    ndb_mgm_set_timeout(h,2500);
+
+    struct ndb_mgm_cluster_state *cl= ndb_mgm_get_status(h);
+
+    if(cl!=NULL)
+      free(cl);
+
+    /*
+     * For whatever strange reason,
+     * get_status is okay with not having the last enter there.
+     * instead of "fixing" the api, let's have a special case
+     * so we don't break any behaviour
+     */
+
+    if(error_ins!=0 && error_ins!=5 && cl!=NULL)
+    {
+      ndbout << "FAILED: got a ndb_mgm_cluster_state back" << endl;
+      result= NDBT_FAILED;
+    }
+
+    if(error_ins!=0 && error_ins!=5 && ndb_mgm_is_connected(h))
+    {
+      ndbout << "FAILED: is still connected after error" << endl;
+      result= NDBT_FAILED;
+    }
+
+    if(error_ins!=0 && error_ins!=5 && ndb_mgm_get_latest_error(h)!=ETIMEDOUT)
+    {
+      ndbout << "FAILED: Incorrect error code (" << ndb_mgm_get_latest_error(h)
+             << " != expected " << ETIMEDOUT << ") desc: "
+             << ndb_mgm_get_latest_error_desc(h)
+             << " line: " << ndb_mgm_get_latest_error_line(h)
+             << " msg: " << ndb_mgm_get_latest_error_msg(h)
+             << endl;
+      result= NDBT_FAILED;
+    }
+  }
+
+done:
+  ndb_mgm_disconnect(h);
+  ndb_mgm_destroy_handle(&h);
+
+  return result;
+}
+
+int runTestMgmApiGetConfigTimeout(NDBT_Context* ctx, NDBT_Step* step)
+{
+  char *mgm= ctx->getRemoteMgm();
+  int result= NDBT_OK;
+  int mgmd_nodeid= 0;
+
+  NdbMgmHandle h;
+  h= ndb_mgm_create_handle();
+  ndb_mgm_set_connectstring(h, mgm);
+
+  for(int error_ins=0; error_ins<=3; error_ins++)
+  {
+    ndb_mgm_connect(h,0,0,0);
+
+    if(ndb_mgm_check_connection(h) < 0)
+    {
+      result= NDBT_FAILED;
+      goto done;
+    }
+
+    mgmd_nodeid= ndb_mgm_get_mgmd_nodeid(h);
+    if(mgmd_nodeid==0)
+    {
+      ndbout << "Failed to get mgmd node id to insert error" << endl;
+      result= NDBT_FAILED;
+      goto done;
+    }
+
+    ndb_mgm_reply reply;
+    reply.return_code= 0;
+
+    if(ndb_mgm_insert_error(h, mgmd_nodeid, error_ins, &reply)< 0)
+    {
+      ndbout << "failed to insert error " << error_ins << endl;
+      result= NDBT_FAILED;
+    }
+
+    ndbout << "trying error: " << error_ins << endl;
+
+    ndb_mgm_set_timeout(h,2500);
+
+    struct ndb_mgm_configuration *c= ndb_mgm_get_configuration(h,0);
+
+    if(c!=NULL)
+      free(c);
+
+    if(error_ins!=0 && c!=NULL)
+    {
+      ndbout << "FAILED: got a ndb_mgm_configuration back" << endl;
+      result= NDBT_FAILED;
+    }
+
+    if(error_ins!=0 && ndb_mgm_is_connected(h))
+    {
+      ndbout << "FAILED: is still connected after error" << endl;
+      result= NDBT_FAILED;
+    }
+
+    if(error_ins!=0 && ndb_mgm_get_latest_error(h)!=ETIMEDOUT)
+    {
+      ndbout << "FAILED: Incorrect error code (" << ndb_mgm_get_latest_error(h)
+             << " != expected " << ETIMEDOUT << ") desc: "
+             << ndb_mgm_get_latest_error_desc(h)
+             << " line: " << ndb_mgm_get_latest_error_line(h)
+             << " msg: " << ndb_mgm_get_latest_error_msg(h)
+             << endl;
+      result= NDBT_FAILED;
+    }
+  }
+
 done:
   ndb_mgm_disconnect(h);
   ndb_mgm_destroy_handle(&h);
@@ -272,6 +489,103 @@ int runTestApiTimeout1(NDBT_Context* ctx, NDBT_Step* step)
   return result;
 }
 
+int runTestMgmApiEventTimeout(NDBT_Context* ctx, NDBT_Step* step)
+{
+  char *mgm= ctx->getRemoteMgm();
+  int result= NDBT_OK;
+  int mgmd_nodeid= 0;
+
+  NdbMgmHandle h;
+  h= ndb_mgm_create_handle();
+  ndb_mgm_set_connectstring(h, mgm);
+
+  for(int error_ins=0; error_ins<=3; error_ins++)
+  {
+    ndb_mgm_connect(h,0,0,0);
+
+    if(ndb_mgm_check_connection(h) < 0)
+    {
+      result= NDBT_FAILED;
+      goto done;
+    }
+
+    mgmd_nodeid= ndb_mgm_get_mgmd_nodeid(h);
+    if(mgmd_nodeid==0)
+    {
+      ndbout << "Failed to get mgmd node id to insert error" << endl;
+      result= NDBT_FAILED;
+      goto done;
+    }
+
+    ndb_mgm_reply reply;
+    reply.return_code= 0;
+
+    if(ndb_mgm_insert_error(h, mgmd_nodeid, error_ins, &reply)< 0)
+    {
+      ndbout << "failed to insert error " << error_ins << endl;
+      result= NDBT_FAILED;
+    }
+
+    ndbout << "trying error: " << error_ins << endl;
+
+    ndb_mgm_set_timeout(h,2500);
+
+    int filter[] = { 15, NDB_MGM_EVENT_CATEGORY_BACKUP,
+                     1, NDB_MGM_EVENT_CATEGORY_STARTUP,
+                     0 };
+    int fd= ndb_mgm_listen_event(h, filter);
+
+    if(fd==NDB_INVALID_SOCKET)
+    {
+      ndbout << "FAILED: could not listen to event" << endl;
+      result= NDBT_FAILED;
+    }
+
+    char *tmp= 0;
+    char buf[512];
+    SocketInputStream in(fd,20000);
+    do {
+      if((tmp = in.gets(buf, sizeof(buf))))
+      {
+        const char ping_token[]="<PING>";
+        if(memcmp(ping_token,tmp,sizeof(ping_token)-1))
+          if(tmp && strlen(tmp))
+            ndbout << tmp;
+      }
+      else
+      {
+        if(in.timedout())
+        {
+          ndbout << "TIMED OUT READING EVENT" << endl;
+          break;
+        }
+      }
+    } while(true);
+
+    if(error_ins!=0 && ndb_mgm_is_connected(h))
+    {
+      ndbout << "FAILED: is still connected after error" << endl;
+      result= NDBT_FAILED;
+    }
+
+    if(error_ins!=0 && ndb_mgm_get_latest_error(h)!=ETIMEDOUT)
+    {
+      ndbout << "FAILED: Incorrect error code (" << ndb_mgm_get_latest_error(h)
+             << " != expected " << ETIMEDOUT << ") desc: "
+             << ndb_mgm_get_latest_error_desc(h)
+             << " line: " << ndb_mgm_get_latest_error_line(h)
+             << " msg: " << ndb_mgm_get_latest_error_msg(h)
+             << endl;
+      result= NDBT_FAILED;
+    }
+  }
+
+done:
+  ndb_mgm_disconnect(h);
+  ndb_mgm_destroy_handle(&h);
+
+  return result;
+}
 
 NDBT_TESTSUITE(testMgm);
 TESTCASE("SingleUserMode", 
@@ -284,9 +598,24 @@ TESTCASE("ApiSessionFailure",
   INITIALIZER(runTestApiSession);
 
 }
-TESTCASE("ApiTimeout1",
-	 "Test timeout for MGMAPI"){
-  INITIALIZER(runTestApiTimeout1);
+TESTCASE("ApiTimeoutBasic",
+	 "Basic timeout tests for MGMAPI"){
+  INITIALIZER(runTestApiTimeoutBasic);
+
+}
+TESTCASE("ApiGetStatusTimeout",
+	 "Test timeout for MGMAPI getStatus"){
+  INITIALIZER(runTestApiGetStatusTimeout);
+
+}
+TESTCASE("ApiGetConfigTimeout",
+	 "Test timeouts for mgmapi get_configuration"){
+  INITIALIZER(runTestMgmApiGetConfigTimeout);
+
+}
+TESTCASE("ApiMgmEventTimeout",
+	 "Test timeouts for mgmapi get_configuration"){
+  INITIALIZER(runTestMgmApiEventTimeout);
 
 }
 NDBT_TESTSUITE_END(testMgm);