List:Commits« Previous MessageNext Message »
From:Magnus Blåudd Date:May 5 2010 3:27pm
Subject:bzr commit into mysql-5.1-telco-7.0 branch (magnus.blaudd:3525)
View as plain text  
#At file:///home/msvensson/mysql/tmp/7.0/ based on revid:magnus.blaudd@strippedx1i3vzcyrq1y4o

 3525 Magnus Blåudd	2010-05-05 [merge]
      Merge

    added:
      mysql-test/suite/ndb_team/r/ndb_restart.result
      mysql-test/suite/ndb_team/t/ndb_restart.test
    modified:
      mysql-test/suite/ndb/t/add_node01.test
      mysql-test/suite/ndb/t/add_node02.test
      mysql-test/suite/ndb/t/add_node03.test
      mysql-test/suite/ndb_team/t/ndb_autodiscover3.test
      storage/ndb/src/common/portlib/NdbHost.c
      storage/ndb/src/common/portlib/my_daemon.cc
      storage/ndb/src/kernel/angel.cpp
      storage/ndb/src/kernel/angel.hpp
      storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp
      storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp
      storage/ndb/src/kernel/error/ErrorReporter.cpp
      storage/ndb/src/kernel/error/ErrorReporter.hpp
      storage/ndb/src/kernel/main.cpp
      storage/ndb/src/kernel/ndbd.cpp
      storage/ndb/src/kernel/ndbd.hpp
      storage/ndb/src/kernel/vm/Configuration.cpp
      storage/ndb/src/kernel/vm/Configuration.hpp
      storage/ndb/src/kernel/vm/DynArr256.cpp
      storage/ndb/src/kernel/vm/Emulator.cpp
      storage/ndb/src/kernel/vm/Emulator.hpp
      storage/ndb/src/kernel/vm/SimulatedBlock.cpp
      storage/ndb/src/kernel/vm/ThreadConfig.cpp
      storage/ndb/src/kernel/vm/ThreadConfig.hpp
      storage/ndb/src/kernel/vm/bench_pool.cpp
      storage/ndb/src/kernel/vm/mt.cpp
=== modified file 'mysql-test/suite/ndb/t/add_node01.test'
--- a/mysql-test/suite/ndb/t/add_node01.test	2009-04-07 07:47:30 +0000
+++ b/mysql-test/suite/ndb/t/add_node01.test	2010-03-17 10:50:18 +0000
@@ -1,7 +1,5 @@
 -- source include/have_ndb.inc
 -- source include/not_embedded.inc
-# angel does not currently work on windoze
--- source include/not_windows.inc 
 --result_format 2
 
 ## Make mtr.pl restart all servers after this test

=== modified file 'mysql-test/suite/ndb/t/add_node02.test'
--- a/mysql-test/suite/ndb/t/add_node02.test	2009-04-07 07:47:30 +0000
+++ b/mysql-test/suite/ndb/t/add_node02.test	2010-03-17 10:50:18 +0000
@@ -1,7 +1,5 @@
 -- source include/have_ndb.inc
 -- source include/not_embedded.inc
-# angel does not currently work on windoze
--- source include/not_windows.inc
 --result_format 2
 
 ## Make mtr.pl restart all servers after this test

=== modified file 'mysql-test/suite/ndb/t/add_node03.test'
--- a/mysql-test/suite/ndb/t/add_node03.test	2009-04-07 07:47:30 +0000
+++ b/mysql-test/suite/ndb/t/add_node03.test	2010-03-17 10:50:18 +0000
@@ -1,7 +1,5 @@
 -- source include/have_ndb.inc
 -- source include/not_embedded.inc
-# angel does not currently work on windoze
--- source include/not_windows.inc
 --result_format 2
 
 ## Make mtr.pl restart all servers after this test

=== added file 'mysql-test/suite/ndb_team/r/ndb_restart.result'
--- a/mysql-test/suite/ndb_team/r/ndb_restart.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb_team/r/ndb_restart.result	2010-03-16 07:33:47 +0000
@@ -0,0 +1,41 @@
+create table t1(a int primary key, b int) engine = ndb;
+insert into t1 values (1, 2);
+Node 1 is being restarted
+
+Database node 1 is being started.
+
+select * from t1 order by a;
+a	b
+1	2
+insert into t1 values (2, 3);
+Node 1 is being restarted
+
+Database node 1 is being started.
+
+select * from t1 order by a;
+a	b
+1	2
+2	3
+insert into t1 values (3, 4);
+Executing RESTART on all nodes.
+Starting shutdown. This may take a while. Please wait...
+All DB nodes are being restarted.
+
+NDB Cluster is being started.
+NDB Cluster is being started.
+
+select * from t1 order by a;
+a	b
+1	2
+2	3
+3	4
+insert into t1 values (4, 5);
+Executing RESTART on all nodes.
+Starting shutdown. This may take a while. Please wait...
+All DB nodes are being restarted.
+
+NDB Cluster is being started.
+NDB Cluster is being started.
+
+select * from t1;
+ERROR 42S02: Table 'test.t1' doesn't exist

=== modified file 'mysql-test/suite/ndb_team/t/ndb_autodiscover3.test'
--- a/mysql-test/suite/ndb_team/t/ndb_autodiscover3.test	2009-12-18 12:35:47 +0000
+++ b/mysql-test/suite/ndb_team/t/ndb_autodiscover3.test	2010-03-17 10:50:18 +0000
@@ -9,8 +9,6 @@ call mtr.add_suppression("NDB_SHARE: .* 
 # see bug#21563
 -- source include/have_binlog_format_mixed_or_row.inc
 
-# angel does not currently work on windoze
--- source include/not_windows.inc
 --disable_warnings
 drop table if exists t1, t2;
 --disable_query_log

=== added file 'mysql-test/suite/ndb_team/t/ndb_restart.test'
--- a/mysql-test/suite/ndb_team/t/ndb_restart.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb_team/t/ndb_restart.test	2010-03-16 07:33:47 +0000
@@ -0,0 +1,76 @@
+--source include/have_ndb.inc
+
+#
+# Setup
+#
+let $ndb_mgm_cmd = $NDB_MGM --no-defaults --verbose=0;
+let $ndb_waiter_cmd = $NDB_WAITER --no-defaults;
+
+#
+# Create test table
+#

+create table t1(a int primary key, b int) engine = ndb;
+insert into t1 values (1, 2);
+
+#
+# Restart node 1
+#
+--exec $ndb_mgm_cmd -e "1 RESTART"
+--exec $ndb_waiter_cmd --nowait-nodes=2 --not-started > /dev/null
+--exec $ndb_mgm_cmd -e "1 START"
+--exec $ndb_waiter_cmd  > /dev/null
+
+# Check table is still there
+select * from t1 order by a;
+insert into t1 values (2, 3);
+
+#
+# Restart node 1 --initial
+#
+--exec $ndb_mgm_cmd -e "1 RESTART -I"
+--exec $ndb_waiter_cmd --nowait-nodes=2 --not-started  > /dev/null
+--exec $ndb_mgm_cmd -e "1 START"
+--exec $ndb_waiter_cmd  > /dev/null
+
+# Check table is still there
+select * from t1 order by a;
+insert into t1 values (3, 4);
+
+#
+# Restart all
+#
+--exec $ndb_mgm_cmd -e "ALL RESTART -N"
+--exec $ndb_waiter_cmd --not-started > /dev/null
+--exec $ndb_mgm_cmd -e "ALL START"
+--exec $ndb_waiter_cmd > /dev/null
+
+# Wait for mysqld to reconnect
+--disable_result_log
+--disable_query_log
+--source include/ndb_not_readonly.inc
+--enable_result_log
+--enable_query_log
+
+# Check table is still there
+select * from t1 order by a;
+insert into t1 values (4, 5);
+
+#
+# Restart all initial
+#
+--exec $ndb_mgm_cmd -e "ALL RESTART -N -I"
+--exec $ndb_waiter_cmd --not-started > /dev/null
+--exec $ndb_mgm_cmd -e "ALL START"
+--exec $ndb_waiter_cmd > /dev/null
+
+# Wait for mysqld to reconnect
+--disable_result_log
+--disable_query_log
+--source include/ndb_not_readonly.inc
+--enable_result_log
+--enable_query_log
+
+# Check table is gone
+--error ER_NO_SUCH_TABLE
+select * from t1;
+

=== modified file 'storage/ndb/src/common/portlib/NdbHost.c'
--- a/storage/ndb/src/common/portlib/NdbHost.c	2009-05-27 15:21:45 +0000
+++ b/storage/ndb/src/common/portlib/NdbHost.c	2010-03-17 07:00:12 +0000
@@ -27,12 +27,12 @@ int NdbHost_GetHostName(char* buf)
   return 0;
 }
 
-#ifdef NDB_WIN
-#include <process.h>
-#define getpid _getpid
-#endif
 int NdbHost_GetProcessId(void)
 {
+#ifdef _WIN32
+  return GetCurrentProcessId();
+#else
   return getpid();
+#endif
 }
 

=== modified file 'storage/ndb/src/common/portlib/my_daemon.cc'
--- a/storage/ndb/src/common/portlib/my_daemon.cc	2009-03-25 09:18:47 +0000
+++ b/storage/ndb/src/common/portlib/my_daemon.cc	2010-03-17 08:19:32 +0000
@@ -23,6 +23,7 @@
 #include <my_daemon.h>
 
 #include <BaseString.hpp>
+#include <portlib/NdbHost.h>
 
 static FILE *dlog_file;
 
@@ -312,7 +313,8 @@ do_files(const char *pidfile_name, int p
                 pidfile_name, errno);
 
   char buf[32];
-  int length = my_snprintf(buf, sizeof(buf), "%ld", (long)getpid());
+  int length = my_snprintf(buf, sizeof(buf), "%ld",
+                           (long)NdbHost_GetProcessId());
   if (write(pidfd, buf, length) != length)
     return ERR1("Failed to write pid to pidfile '%s', errno: %d",
                 pidfile_name, errno);

=== modified file 'storage/ndb/src/kernel/angel.cpp'
--- a/storage/ndb/src/kernel/angel.cpp	2010-05-04 14:34:54 +0000
+++ b/storage/ndb/src/kernel/angel.cpp	2010-05-05 15:27:29 +0000
@@ -16,8 +16,10 @@
 
 #include <ndb_global.h>
 #include <ndb_version.h>
+#include <signal.h>
 
 #include "angel.hpp"
+#include "ndbd.hpp"
 
 #include <NdbConfig.h>
 #include <NdbAutoPtr.hpp>
@@ -28,28 +30,6 @@
 #include <EventLogger.hpp>
 extern EventLogger * g_eventLogger;
 
-#include "vm/SimBlockList.hpp"
-
-
-#define MAX_FAILED_STARTUPS 3
-// Flag set by child through SIGUSR1 to signal a failed startup
-static bool failed_startup_flag=false;
-// Counter for consecutive failed startups
-static Uint32 failed_startups=0;
-
-// child signalling failed restart
-extern "C"
-void
-handler_sigusr1(int signum)
-{
-  if (!failed_startup_flag)
-  {
-    failed_startups++;
-    failed_startup_flag=true;
-  }
-  g_eventLogger->info("Angel received ndbd startup failure count %u.", failed_startups);
-}
-
 static void
 angel_exit(int code)
 {
@@ -60,73 +40,26 @@ angel_exit(int code)
 #endif
 }
 
+#include "../mgmapi/mgmapi_configuration.hpp"
 
-// These are used already before fork if fetch_configuration() fails
-// (e.g. Unable to alloc node id).  Set them to something reasonable.
-FILE *child_info_file_r=stdin;
-FILE *child_info_file_w=stdout;
-
-#include <Properties.hpp>
-
-static int
-insert(const char * pair, Properties & p)
-{
-  BaseString tmp(pair);
-
-  tmp.trim(" \t\n\r");
-  Vector<BaseString> split;
-  tmp.split(split, ":=", 2);
-  if (split.size() != 2)
-    return -1;
-  p.put(split[0].trim().c_str(), split[1].trim().c_str());
-  return 0;
-}
-
-static int
-readChildInfo(Properties &info)
-{
-  fclose(child_info_file_w);
-  char buf[128];
-  while (fgets(buf, sizeof (buf), child_info_file_r))
-    insert(buf, info);
-  fclose(child_info_file_r);
-  return 0;
-}
-
-static bool
-get_int_property(Properties &info,
-                 const char *token, Uint32 *int_val)
+static void
+reportShutdown(const ndb_mgm_configuration* config,
+               NodeId nodeid, int error_exit,
+               bool restart, bool nostart, bool initial,
+               Uint32 error, Uint32 signum, Uint32 sphase)
 {
-  const char *str_val=0;
-  if (!info.get(token, &str_val))
-    return false;
-  char *endptr;
-  long int tmp=strtol(str_val, &endptr, 10);
-  if (str_val == endptr)
-    return false;
-  *int_val=tmp;
-  return true;
-}
+  // Only allow "initial" and "nostart" to be set if "restart" is set
+  assert(restart ||
+         (!restart && !initial && !nostart));
 
-int reportShutdown(class Configuration *config, int error_exit, int restart, Uint32 sphase=256)
-{
-  Uint32 error=0, signum=0;
-#ifndef NDB_WIN
-  Properties info;
-  readChildInfo(info);
-
-  get_int_property(info, "signal", &signum);
-  get_int_property(info, "error", &error);
-  get_int_property(info, "sphase", &sphase);
-#endif
   Uint32 length, theData[25];
   EventReport *rep=(EventReport *) theData;
 
-  rep->setNodeId(globalData.ownId);
+  rep->setNodeId(nodeid);
   if (restart)
     theData[1]=1 |
-          (globalData.theRestartFlag == initial_state ? 2 : 0) |
-    (config->getInitialStart() ? 4 : 0);
+      (nostart ? 2 : 0) |
+      (initial ? 4 : 0);
   else
     theData[1]=0;
 
@@ -145,63 +78,66 @@ int reportShutdown(class Configuration *
     length=6;
   }
 
-  { // Log event
-    const EventReport * const eventReport=(EventReport *) & theData[0];
-    g_eventLogger->log(eventReport->getEventType(), theData, length,
-                       eventReport->getNodeId(), 0);
-  }
-
-  for (unsigned n=0; n < config->m_mgmds.size(); n++)
-  {
-    NdbMgmHandle h=ndb_mgm_create_handle();
-    if (h == 0 ||
-        ndb_mgm_set_connectstring(h, config->m_mgmds[n].c_str()) ||
-        ndb_mgm_connect(h,
-                        1, //no_retries
-                        0, //retry_delay_in_seconds
-                        0 //verbose
-                        ))
-      goto handle_error;
-
-    {
-      if (ndb_mgm_report_event(h, theData, length))
-        goto handle_error;
-    }
-    goto do_next;
-
-handle_error:
-    if (h)
-    {
-      BaseString tmp(ndb_mgm_get_latest_error_msg(h));
-      tmp.append(" : ");
-      tmp.append(ndb_mgm_get_latest_error_desc(h));
-      g_eventLogger->warning("Unable to report shutdown reason to %s: %s",
-                             config->m_mgmds[n].c_str(), tmp.c_str());
-    } else
-    {
-      g_eventLogger->error("Unable to report shutdown reason to %s",
-                           config->m_mgmds[n].c_str());
+  // Log event locally
+  g_eventLogger->log(rep->getEventType(), theData, length,
+                     rep->getNodeId(), 0);
+
+  // Log event to cluster log
+  ndb_mgm_configuration_iterator iter(*config, CFG_SECTION_NODE);
+  for (iter.first(); iter.valid(); iter.next())
+  {
+    Uint32 type;
+    if (iter.get(CFG_TYPE_OF_SECTION, &type) ||
+       type != NODE_TYPE_MGM)
+      continue;
+
+    Uint32 port;
+    if (iter.get(CFG_MGM_PORT, &port))
+      continue;
+
+    const char* hostname;
+    if (iter.get(CFG_NODE_HOST, &hostname))
+      continue;
+
+    BaseString connect_str;
+    connect_str.assfmt("%s:%d", hostname, port);
+
+
+    NdbMgmHandle h = ndb_mgm_create_handle();
+    if (h == 0)
+    {
+      g_eventLogger->warning("Unable to report shutdown reason "
+                             "to '%s'(failed to create mgm handle)",
+                             connect_str.c_str());
+      continue;
     }
-do_next:
-    if (h)
-    {
-      ndb_mgm_disconnect(h);
-      ndb_mgm_destroy_handle(&h);
+
+    if (ndb_mgm_set_connectstring(h, connect_str.c_str()) ||
+        ndb_mgm_connect(h, 1, 0, 0) ||
+        ndb_mgm_report_event(h, theData, length))
+    {
+      g_eventLogger->warning("Unable to report shutdown reason "
+                             "to '%s'(error: %s - %s)",
+                             connect_str.c_str(),
+                             ndb_mgm_get_latest_error_msg(h),
+                             ndb_mgm_get_latest_error_desc(h));
     }
+
+    ndb_mgm_destroy_handle(&h);
   }
-  return 0;
 }
 
 
 static void
 ignore_signals(void)
 {
-#ifndef NDB_WIN32
   static const int ignore_list[] = {
 #ifdef SIGBREAK
     SIGBREAK,
 #endif
+#ifdef SIGHUP
     SIGHUP,
+#endif
     SIGINT,
 #if defined SIGPWR
     SIGPWR,
@@ -213,10 +149,16 @@ ignore_signals(void)
 #ifdef SIGTSTP
     SIGTSTP,
 #endif
+#ifdef SIGTTIN
     SIGTTIN,
+#endif
+#ifdef SIGTTOU
     SIGTTOU,
+#endif
     SIGABRT,
+#ifdef SIGALRM
     SIGALRM,
+#endif
 #ifdef SIGBUS
     SIGBUS,
 #endif
@@ -237,118 +179,378 @@ ignore_signals(void)
 
   for(size_t i = 0; i < sizeof(ignore_list)/sizeof(ignore_list[0]); i++)
     signal(ignore_list[i], SIG_IGN);
+}
+
+#ifdef _WIN32
+static inline
+int pipe(int pipefd[2]){
+  const unsigned int buffer_size = 4096;
+  const int flags = 0;
+  return _pipe(pipefd, buffer_size, flags);
+}
+
+#undef getpid
+#include <process.h>
+
+typedef DWORD pid_t;
+
+static inline
+pid_t waitpid(pid_t pid, int *stat_loc, int options)
+{
+  HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
+  if (handle == NULL)
+  {
+    g_eventLogger->error("waitpid: Could not open handle for pid %d, "
+                         "error: %d", pid, GetLastError());
+    return -1;
+  }
+ intptr_t ret_handle = _cwait(stat_loc, (intptr_t)handle, 0);
+ if (ret_handle == -1)
+ {
+    g_eventLogger->error("waitpid: Failed to wait for pid %d, "
+                         "errno: %d", pid, errno);
+    return -1;
+ }
+ return pid;
+}
+
+static inline
+bool WIFEXITED(int status)
+{
+  return true;
+}
+
+static inline
+int WEXITSTATUS(int status)
+{
+  return status;
+}
+
+static inline
+bool WIFSIGNALED(int status)
+{
+  return false;
+}
+
+static inline
+int WTERMSIG(int status)
+{
+  return 0;
+}
+#endif
+
+extern int main(int, char**);
+
+static pid_t
+spawn_process(const char* progname, const BaseString& args)
+{
+  char** argv = BaseString::argify(progname, args.c_str());
+  if (!argv)
+  {
+    g_eventLogger->error("spawn_process: Failed to create argv, errno: %d",
+                         errno);
+    return -1;
+  }
+
+#ifdef _WIN32
+
+  intptr_t spawn_handle = _spawnv(P_NOWAIT, progname, argv);
+  if (spawn_handle == -1)
+  {
+    g_eventLogger->error("spawn_process: Failed to spawn process, errno: %d",
+                         errno);
+    return -1;
+  }
+
+  // Convert the handle returned from spawnv_ to a pid
+  DWORD pid = GetProcessId((HANDLE)spawn_handle);
+  if (pid == 0)
+  {
+    g_eventLogger->error("spawn_process: Failed to convert handle %d "
+                         "to pid, error: %d", spawn_handle, GetLastError());
+    CloseHandle((HANDLE)spawn_handle);
+    return -1;
+  }
+  CloseHandle((HANDLE)spawn_handle);
+  return pid;
+#else
+  pid_t pid = fork();
+  if (pid == -1)
+  {

+    g_eventLogger->error("Failed to fork, errno: %d", errno);
+    return -1;
+  }
+
+  if (pid)
+  {
+    // Parent
+    return pid;
+  }
+
+  // Count number of arguments
+  int argc = 0;
+  while(argv[argc])
+    argc++;
+
+  // Calling 'main' to start program from beginning
+  // without loading (possibly new version) from disk
+  (void)main(argc, argv);
+  assert(false); // main should never return
+  exit(1);
+  return -1; // Never reached
 #endif
 }
 
-void
-childReportSignal(int signum);
+static Uint32 stop_on_error;
+
+
+/*
+  Extract the config parameters that concerns angel
+*/
+
+static bool
+configure(const ndb_mgm_configuration* conf, NodeId nodeid)
+{
+  Uint32 generation = 0;
+  ndb_mgm_configuration_iterator sys_iter(*conf, CFG_SECTION_SYSTEM);
+  if (sys_iter.get(CFG_SYS_CONFIG_GENERATION, &generation))
+  {
+    g_eventLogger->warning("Configuration didn't contain generation "
+                           "(likely old ndb_mgmd");
+  }
+  g_eventLogger->info("Using configuration with generation %u", generation);
+
+  ndb_mgm_configuration_iterator iter(*conf, CFG_SECTION_NODE);
+  if (iter.find(CFG_NODE_ID, nodeid))
+  {
+    g_eventLogger->error("Invalid configuration fetched, could not "
+                         "find own node id %d", nodeid);
+    return false;
+  }
+
+  if (iter.get(CFG_DB_STOP_ON_ERROR, &stop_on_error))
+  {
+    g_eventLogger->error("Invalid configuration fetched, could not "
+                         "find StopOnError");
+    return false;
+  }
+  g_eventLogger->debug("Using StopOnError: %u", stop_on_error);
+
+  const char * datadir;
+  if (iter.get(CFG_NODE_DATADIR, &datadir))
+  {
+    g_eventLogger->error("Invalid configuration fetched, could not "
+                         "find DataDir");
+    return false;
+  }
+  g_eventLogger->debug("Using DataDir: %s", datadir);
 
-int
-angel_run(const char* connect_str,
+  NdbConfig_SetPath(datadir);
+
+  my_setwd(NdbConfig_get_path(0), MYF(0));
+
+  return true;
+}
+
+
+void
+angel_run(const BaseString& original_args,
+          const char* connect_str,
+          int force_nodeid,
           const char* bind_address,
-          bool initialstart,
+          bool initial,
+          bool no_start,
           bool daemon)
 {
-#ifdef NDB_WIN32
-  return 1;
-#else
+  ConfigRetriever retriever(connect_str,
+                            force_nodeid,
+                            NDB_VERSION,
+                            NDB_MGM_NODE_TYPE_NDB,
+                            bind_address);
+  if (retriever.hasError())
+  {
+    g_eventLogger->error("Could not initialize connection to management "
+                         "server, error: '%s'", retriever.getErrorString());
+    angel_exit(1);
+  }
+
+  const int connnect_retries = 12;
+  const int connect_delay = 5;
+  const int verbose = 1;
+  if (retriever.do_connect(connnect_retries, connect_delay, verbose) != 0)
+  {
+    g_eventLogger->error("Could not connect to management server, "
+                         "error: '%s'", retriever.getErrorString());
+    angel_exit(1);
+  }
+  g_eventLogger->info("Angel connected to '%s:%d'",
+                      retriever.get_mgmd_host(),
+                      retriever.get_mgmd_port());
+
+  const int alloc_retries = 2;
+  const int alloc_delay = 3;
+  const Uint32 nodeid = retriever.allocNodeId(alloc_retries, alloc_delay);
+  if (nodeid == 0)
+  {
+    g_eventLogger->error("Failed to allocate nodeid, error: '%s'",
+                         retriever.getErrorString());
+    angel_exit(1);
+  }
+  g_eventLogger->info("Angel allocated nodeid: %u", nodeid);
+
+  ndb_mgm_configuration * config = retriever.getConfig(nodeid);
+  NdbAutoPtr<ndb_mgm_configuration> config_autoptr(config);
+  if (config == 0)
+  {
+    g_eventLogger->error("Could not fetch configuration/invalid "
+                         "configuration, error: '%s'",
+                         retriever.getErrorString());
+    angel_exit(1);
+  }
+
+  if (!configure(config, nodeid))
+  {
+    // Failed to configure, error already printed
+    angel_exit(1);
+  }
+
   if (daemon)
   {
     // Become a daemon
-    char *lockfile=NdbConfig_PidFileName(globalData.ownId);
-    char *logfile=NdbConfig_StdoutFileName(globalData.ownId);
+    char *lockfile = NdbConfig_PidFileName(nodeid);
+    char *logfile = NdbConfig_StdoutFileName(nodeid);
     NdbAutoPtr<char> tmp_aptr1(lockfile), tmp_aptr2(logfile);
 
 #ifndef NDB_WIN32
     if (NdbDaemon_Make(lockfile, logfile, 0) == -1)
     {
       ndbout << "Cannot become daemon: " << NdbDaemon_ErrorText << endl;
-      return 1;
+      angel_exit(1);
     }
 #endif
   }
 
-  signal(SIGUSR1, handler_sigusr1);
-
-  pid_t child= -1;
+  // Counter for consecutive failed startups
+  Uint32 failed_startups_counter = 0;
   while (true)
   {
-    // setup reporting between child and parent
-    int filedes[2];
-    if (pipe(filedes))
+
+    // Create pipe where ndbd process will report extra shutdown status
+    int fds[2];
+    if (pipe(fds))
     {
-      g_eventLogger->error("pipe() failed with errno=%d (%s)",
+      g_eventLogger->error("Failed to create pipe, errno: %d (%s)",
                            errno, strerror(errno));
-      return 1;
-    } else
+      angel_exit(1);
+    }
+
+    FILE *child_info_r;
+    if (!(child_info_r = fdopen(fds[0], "r")))
     {
-      if (!(child_info_file_w=fdopen(filedes[1], "w")))
-      {
-        g_eventLogger->error("fdopen() failed with errno=%d (%s)",
-                             errno, strerror(errno));
-      }
-      if (!(child_info_file_r=fdopen(filedes[0], "r")))
-      {
-        g_eventLogger->error("fdopen() failed with errno=%d (%s)",
-                             errno, strerror(errno));
-      }
+      g_eventLogger->error("Failed to open stream for pipe, errno: %d (%s)",
+                           errno, strerror(errno));
+      angel_exit(1);
     }
 
-    if ((child=fork()) <= 0)
-      break; // child or error
+    // Build the args used to start ndbd by appending
+    // the arguments that may have changed at the end
+    // of original argument list
+    BaseString args(original_args);
+
+    // Pass fd number of the pipe which ndbd should use
+    // for sending extra status to angel
+    args.appfmt(" --report-fd=%d", fds[1]);
+
+    // The nodeid which has been allocated by angel
+    args.appfmt(" --allocated-nodeid=%d", nodeid);
+
+    args.appfmt(" --initial=%d", initial);
+    args.appfmt(" --nostart=%d", no_start);
+
+    pid_t child = spawn_process(my_progname, args);
+    if (child == -1)
+      angel_exit(1);
 
     /**
      * Parent
      */
+    g_eventLogger->info("Angel pid: %d started child: %d",
+                        getpid(), child);
 
     ignore_signals();
 
-    /**
-     * We no longer need the mgm connection in this process
-     * (as we are the angel, not ndb)
-     *
-     * We don't want to purge any allocated resources (nodeid), so
-     * we set that option to false
-     */
-    Configuration* theConfig = globalEmulatorData.theConfiguration;
-    theConfig->closeConfiguration(false);
+    int status=0, error_exit=0;
+    while(true)
+    {
+      pid_t ret_pid = waitpid(child, &status, 0);
+      if (ret_pid == child)
+        break;
+      g_eventLogger->warning("Angel got unexpected pid %d when waiting for %d",
+                             ret_pid, child);
+    }
+
+    g_eventLogger->debug("Angel got child %d", child);
+
+    // Close the write end of pipe
+    close(fds[1]);
+
+    // Read info from the child's pipe
+    char buf[128];
+    Uint32 child_error = 0, child_signal = 0, child_sphase = 0;
+    while (fgets(buf, sizeof (buf), child_info_r))
+    {
+      int value;
+      if (sscanf(buf, "error=%d\n", &value) == 1)
+        child_error = value;
+      else if (sscanf(buf, "signal=%d\n", &value) == 1)
+        child_signal = value;
+      else if (sscanf(buf, "sphase=%d\n", &value) == 1)
+        child_sphase = value;
+      else if (strcmp(buf, "\n") != 0)
+        fprintf(stderr, "unknown info from child: '%s'\n", buf);
+    }
+    g_eventLogger->debug("error: %u, signal: %u, sphase: %u",
+                         child_error, child_signal, child_sphase);
+    // Close read end of pipe in parent
+    fclose(child_info_r);
 
-    int status=0, error_exit=0, signum=0;
-    while (waitpid(child, &status, 0) != child);
     if (WIFEXITED(status))
     {
       switch (WEXITSTATUS(status)) {
       case NRT_Default:
         g_eventLogger->info("Angel shutting down");
-        reportShutdown(theConfig, 0, 0);
+        reportShutdown(config, nodeid, 0, 0, false, false,
+                       child_error, child_signal, child_sphase);
         angel_exit(0);
         break;
       case NRT_NoStart_Restart:
-        theConfig->setInitialStart(false);
-        globalData.theRestartFlag=initial_state;
+        initial = false;
+        no_start = true;
         break;
       case NRT_NoStart_InitialStart:
-        theConfig->setInitialStart(true);
-        globalData.theRestartFlag=initial_state;
+        initial = true;
+        no_start = true;
         break;
       case NRT_DoStart_InitialStart:
-        theConfig->setInitialStart(true);
-        globalData.theRestartFlag=perform_start;
+        initial = true;
+        no_start = false;
         break;
       default:
         error_exit=1;
-        if (theConfig->stopOnError())
+        if (stop_on_error)
         {
           /**
            * Error shutdown && stopOnError()
            */
-          reportShutdown(theConfig, error_exit, 0);
+          reportShutdown(config, nodeid,
+                         error_exit, 0, false, false,
+                         child_error, child_signal, child_sphase);
           angel_exit(0);
         }
         // Fall-through
       case NRT_DoStart_Restart:
-        theConfig->setInitialStart(false);
-        globalData.theRestartFlag=perform_start;
+        initial = false;
+        no_start = false;
         break;
       }
     } else
@@ -356,50 +558,93 @@ angel_run(const char* connect_str,
       error_exit=1;
       if (WIFSIGNALED(status))
       {
-        signum=WTERMSIG(status);
-        childReportSignal(signum);
-      } else
+        child_signal = WTERMSIG(status);
+      }
+      else
       {
-        signum=127;
+        child_signal = 127;
         g_eventLogger->info("Unknown exit reason. Stopped.");
       }
-      if (theConfig->stopOnError())
+      if (stop_on_error)
       {
         /**
          * Error shutdown && stopOnError()
          */
-        reportShutdown(theConfig, error_exit, 0);
+        reportShutdown(config, nodeid,
+                       error_exit, 0, false, false,
+                       child_error, child_signal, child_sphase);
         angel_exit(0);
       }
     }
 
-    if (!failed_startup_flag)
+    // Check startup failure
+    const Uint32 STARTUP_FAILURE_SPHASE = 6;
+    const Uint32 MAX_FAILED_STARTUPS = 3;
+    if (child_sphase <= STARTUP_FAILURE_SPHASE)
     {
-      // Reset the counter for consecutive failed startups
-      failed_startups=0;
-    } else if (failed_startups >= MAX_FAILED_STARTUPS && !theConfig->stopOnError())
+      if (++failed_startups_counter >= MAX_FAILED_STARTUPS)
+      {
+        g_eventLogger->alert("Angel detected too many startup failures(%d), "
+                             "not restarting again", failed_startups_counter);
+        reportShutdown(config, nodeid,
+                       error_exit, 0, false, false,
+                       child_error, child_signal, child_sphase);
+        angel_exit(0);
+      }
+      g_eventLogger->info("Angel detected startup failure, count: %u",
+                          failed_startups_counter);
+    }
+    else
     {
-      /**
-       * Error shutdown && stopOnError()
-       */
-      g_eventLogger->alert("Ndbd has failed %u consecutive startups. "
-                           "Not restarting", failed_startups);
-      reportShutdown(theConfig, error_exit, 0);
-      angel_exit(0);
+      // Reset the counter for consecutive failed startups
+      failed_startups_counter = 0;
     }
-    failed_startup_flag=false;
-    reportShutdown(theConfig, error_exit, 1);
+
+    reportShutdown(config, nodeid,
+                   error_exit, 1,
+                   no_start,
+                   initial,
+                   child_error, child_signal, child_sphase);
     g_eventLogger->info("Ndb has terminated (pid %d) restarting", child);
-    theConfig->fetch_configuration(connect_str,
-                                   globalData.ownId, // Force same nodeid again
-                                   bind_address);
-  }
 
-  if (child >= 0)
-    g_eventLogger->info("Angel pid: %d ndb pid: %d", getppid(), getpid());
-  else if (child > 0)
-    g_eventLogger->info("Ndb pid: %d", getpid());
+    g_eventLogger->debug("Angel reconnecting to management server");
+    (void)retriever.disconnect();
 
-  return 0;
-#endif
+    const int connnect_retries = 12;
+    const int connect_delay = 5;
+    const int verbose = 1;
+    if (retriever.do_connect(connnect_retries, connect_delay, verbose) != 0)
+    {
+      g_eventLogger->error("Could not connect to management server, "
+                           "error: '%s'", retriever.getErrorString());
+      angel_exit(1);
+    }
+    g_eventLogger->info("Angel reconnected to '%s:%d'",
+                        retriever.get_mgmd_host(),
+                        retriever.get_mgmd_port());
+
+    // Tell retriver to allocate the same nodeid again
+    retriever.setNodeId(nodeid);
+
+    g_eventLogger->debug("Angel reallocating nodeid %d", nodeid);
+    const int alloc_retries = 10;
+    const int alloc_delay = 3;
+    const Uint32 realloced = retriever.allocNodeId(alloc_retries, alloc_delay);
+    if (realloced == 0)
+    {
+      g_eventLogger->error("Angel failed to allocate nodeid, error: '%s'",
+                           retriever.getErrorString());
+      angel_exit(1);
+    }
+    if (realloced != nodeid)
+    {
+      g_eventLogger->error("Angel failed to reallocate nodeid %d, got %d",
+                           nodeid, realloced);
+      angel_exit(1);
+    }
+    g_eventLogger->info("Angel reallocated nodeid: %u", nodeid);
+
+  }
+
+  abort(); // Never reached
 }

=== modified file 'storage/ndb/src/kernel/angel.hpp'
--- a/storage/ndb/src/kernel/angel.hpp	2009-03-04 14:54:30 +0000
+++ b/storage/ndb/src/kernel/angel.hpp	2010-05-05 15:27:29 +0000
@@ -16,8 +16,14 @@
 #ifndef ANGEL_HPP
 #define ANGEL_HPP
 
-int angel_run(const char* connect_str,
-              const char* bind_address,
-              bool initialstart,
-              bool daemon);
+#include <util/BaseString.hpp>
+
+void
+angel_run(const BaseString& original_args,
+          const char* connect_str,
+          int force_nodeid,
+          const char* bind_address,
+          bool initial,
+          bool no_start,
+          bool daemon);
 #endif

=== modified file 'storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp'
--- a/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp	2010-03-05 15:03:09 +0000
+++ b/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp	2010-03-16 10:08:26 +0000
@@ -857,7 +857,7 @@ Cmvmi::execSTART_ORD(Signal* signal) {
       type = NRT_DoStart_InitialStart;
     if(!StopReq::getNoStart(tmp)&&!StopReq::getInitialStart(tmp))
       type = NRT_DoStart_Restart;
-    NdbShutdown(NST_Restart, type);
+    NdbShutdown(0, NST_Restart, type);
   }
 
   if(globalData.theRestartFlag == system_started){

=== modified file 'storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp'
--- a/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp	2010-05-03 04:49:08 +0000
+++ b/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp	2010-05-05 15:27:29 +0000
@@ -3568,15 +3568,6 @@ void Ndbcntr::Missra::sendNextSTTOR(Sign
 #endif
     
     const Uint32 start = currentBlockIndex;
-
-    if (currentStartPhase == ZSTART_PHASE_6)
-    {
-      // Ndbd has passed the critical startphases.
-      // Change error handler from "startup" state
-      // to normal state.
-      ErrorReporter::setErrorHandlerShutdownType();
-    }
-
     for(; currentBlockIndex < ALL_BLOCKS_SZ; currentBlockIndex++){
       jam();
       if(ALL_BLOCKS[currentBlockIndex].NextSP == currentStartPhase){

=== modified file 'storage/ndb/src/kernel/error/ErrorReporter.cpp'
--- a/storage/ndb/src/kernel/error/ErrorReporter.cpp	2010-02-25 05:06:59 +0000
+++ b/storage/ndb/src/kernel/error/ErrorReporter.cpp	2010-03-16 09:25:26 +0000
@@ -28,6 +28,9 @@
 #include <NdbConfig.h>
 #include <Configuration.hpp>
 #include "EventLogger.hpp"
+extern EventLogger * g_eventLogger;
+
+#include "TimeModule.hpp"
 
 #include <NdbAutoPtr.hpp>
 
@@ -43,7 +46,7 @@ static void dumpJam(FILE* jamStream, 
 		    const Uint32 thrdTheEmulatedJam[],
                     Uint32 aBlockNumber);
 
-extern EventLogger * g_eventLogger;
+
 const char*
 ErrorReporter::formatTimeStampString(){
   TimeModule DateTime;          /* To create "theDateTimeString" */
@@ -190,14 +193,6 @@ ErrorReporter::formatMessage(int thr_no,
 NdbShutdownType ErrorReporter::s_errorHandlerShutdownType = NST_ErrorHandler;
 
 void
-ErrorReporter::setErrorHandlerShutdownType(NdbShutdownType nst)
-{
-  s_errorHandlerShutdownType = nst;
-}
-
-void childReportError(int error);
-
-void
 ErrorReporter::handleAssert(const char* message, const char* file, int line, int ec)
 {
   char refMessage[100];
@@ -221,9 +216,7 @@ ErrorReporter::handleAssert(const char* 
   NdbShutdownType nst = s_errorHandlerShutdownType;
   WriteMessage(ec, message, refMessage, nst);
 
-  childReportError(ec);
-
-  NdbShutdown(nst);
+  NdbShutdown(ec, nst);
   exit(1);                                      // Deadcode
 }
 
@@ -248,9 +241,7 @@ ErrorReporter::handleError(int messageID
   g_eventLogger->info(problemData);
   g_eventLogger->info(objRef);
 
-  childReportError(messageID);
-
-  NdbShutdown(nst);
+  NdbShutdown(messageID, nst);
 }
 
 int 

=== modified file 'storage/ndb/src/kernel/error/ErrorReporter.hpp'
--- a/storage/ndb/src/kernel/error/ErrorReporter.hpp	2009-09-24 18:11:21 +0000
+++ b/storage/ndb/src/kernel/error/ErrorReporter.hpp	2010-03-16 09:25:26 +0000
@@ -22,13 +22,11 @@
 #include <ndb_global.h>
 #include <ndbd_exit_codes.h>
 
-#include "TimeModule.hpp"
-#include <Emulator.hpp>
+#include "../ndbd.hpp"
 
 class ErrorReporter
 {
 public:
-  static void setErrorHandlerShutdownType(NdbShutdownType nst = NST_ErrorHandler);
   static void handleAssert(const char* message, 
 			   const char* file, 
 			   int line, int ec = NDBD_EXIT_PRGERR)  __attribute__((__noreturn__));

=== modified file 'storage/ndb/src/kernel/main.cpp'
--- a/storage/ndb/src/kernel/main.cpp	2010-05-05 09:30:08 +0000
+++ b/storage/ndb/src/kernel/main.cpp	2010-05-05 15:27:29 +0000
@@ -23,25 +23,17 @@
 #include "ndbd.hpp"
 #include "angel.hpp"
 
-#include "Configuration.hpp"
-#include "vm/SimBlockList.hpp"
-#include "ThreadConfig.hpp"
-#include <SignalLoggerManager.hpp>
-#include <NdbOut.hpp>
-#include <NdbDaemon.h>
-#include <NdbSleep.h>
-#include <NdbConfig.h>
-#include <WatchDog.hpp>
-#include <NdbAutoPtr.hpp>
-#include <Properties.hpp>
-
 #include <EventLogger.hpp>
 extern EventLogger * g_eventLogger;
 
 static int opt_daemon, opt_no_daemon, opt_foreground,
-  opt_initial, opt_no_start, opt_initialstart, opt_verbose;
+  opt_initialstart, opt_verbose;
 static const char* opt_nowait_nodes = 0;
 static const char* opt_bind_address = 0;
+static int opt_report_fd;
+static int opt_initial;
+static int opt_no_start;
+static unsigned opt_allocated_nodeid;
 
 extern NdbNodeBitmask g_nowait_nodes;
 
@@ -86,6 +78,14 @@ static struct my_option my_long_options[
     "Write more log messages",
     (uchar**) &opt_verbose, (uchar**) &opt_verbose, 0,
     GET_BOOL, NO_ARG, 0, 0, 1, 0, 0, 0 },
+  { "report-fd", 256,
+    "INTERNAL: fd where to write extra shutdown status",
+    (uchar**) &opt_report_fd, (uchar**) &opt_report_fd, 0,
+    GET_UINT, REQUIRED_ARG, 0, 0, ~0, 0, 0, 0 },
+  { "allocated-nodeid", 256,
+    "INTERNAL: nodeid allocated by angel process",
+    (uchar**) &opt_allocated_nodeid, (uchar**) &opt_allocated_nodeid, 0,
+    GET_UINT, REQUIRED_ARG, 0, 0, ~0, 0, 0, 0 },
   { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
 };
 
@@ -126,6 +126,12 @@ int main(int argc, char** argv)
   opt_debug= "d:t:O,/tmp/ndbd.trace";
 #endif
 
+  // Save the original arguments for angel
+  BaseString original_args;
+  for (int i = 0; i < argc; i++)
+    original_args.appfmt("%s ", argv[i]);
+  ndbout_c("original_args: %s ", original_args.c_str());
+
   int ho_error;
   if ((ho_error=handle_options(&argc, &argv, my_long_options,
                                ndb_std_get_one_option)))
@@ -146,6 +152,8 @@ int main(int argc, char** argv)
   DBUG_PRINT("info", ("foreground=%d", opt_foreground));
   DBUG_PRINT("info", ("ndb_connectstring=%s", opt_ndb_connectstring));
   DBUG_PRINT("info", ("ndb_nodeid=%d", opt_ndb_nodeid));
+  ndbout_c("opt_report_fd: %d", opt_report_fd);
+  ndbout_c("opt_allocated_nodeid: %d", opt_allocated_nodeid);
 
   if (opt_nowait_nodes)
   {
@@ -164,51 +172,24 @@ int main(int argc, char** argv)
     }
   }
 
-  globalEmulatorData.create();
-
-  Configuration* theConfig = globalEmulatorData.theConfiguration;
-  if(!theConfig->init(opt_no_start, opt_initial,
-                      opt_initialstart, opt_daemon)){
-    g_eventLogger->error("Failed to init Configuration");
-    exit(-1);
-  }
-  char*cfg= getenv("WIN_NDBD_CFG");
-  if(cfg) {
-    int x,y,z;
-    if(3!=sscanf(cfg,"%d %d %d",&x,&y,&z)) {
-      g_eventLogger->error("internal error: couldn't find 3 parameters");
-      exit(1);
-    }
-    theConfig->setInitialStart(x);
-    globalData.theRestartFlag= (restartStates)y;
-    globalData.ownId= z;
-  }
-  { // Do configuration
-    theConfig->fetch_configuration(opt_ndb_connectstring,
-                                   opt_ndb_nodeid,
-                                   opt_bind_address);
-  }
-
-  my_setwd(NdbConfig_get_path(0), MYF(0));
-
-#ifndef NDB_WIN32
-  if (!opt_foreground)
+  if (opt_foreground ||
+      opt_allocated_nodeid ||
+      opt_report_fd)
   {
-    if (angel_run(opt_ndb_connectstring,
-                  opt_bind_address,
-                  opt_initialstart,
-                  opt_daemon))
-      return 1;
-    // ndbd continues here
+    ndbd_run(opt_foreground, opt_report_fd,
+             opt_ndb_connectstring, opt_ndb_nodeid, opt_bind_address,
+             opt_no_start, opt_initial, opt_initialstart,
+             opt_allocated_nodeid);
   }
-  else
-    g_eventLogger->info("Ndb started in foreground");
-#else
-  g_eventLogger->info("Ndb started");
-#endif
 
-  int res = ndbd_run(opt_foreground);
-  ndbd_exit(res);
-  return res;
+  angel_run(original_args,
+            opt_ndb_connectstring,
+            opt_ndb_nodeid,
+            opt_bind_address,
+            opt_initial,
+            opt_no_start,
+            opt_daemon);
+
+  return 1; // Never reached
 }
 

=== modified file 'storage/ndb/src/kernel/ndbd.cpp'
--- a/storage/ndb/src/kernel/ndbd.cpp	2010-01-26 14:09:45 +0000
+++ b/storage/ndb/src/kernel/ndbd.cpp	2010-05-05 15:27:29 +0000
@@ -14,6 +14,7 @@
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
 #include <ndb_global.h>
+#include <signal.h>
 
 #include <NdbEnv.h>
 #include <NdbConfig.h>
@@ -331,125 +332,62 @@ get_multithreaded_config(EmulatorData& e
 }
 
 
-extern FILE *child_info_file_r;
-extern FILE *child_info_file_w;
+static void
+ndbd_exit(int code)
+{
+  // Don't allow negative return code
+  if (code < 0)
+    code = 255;
+
+// gcov will not produce results when using _exit
+#ifdef HAVE_gcov
+  exit(code);
+#else
+  _exit(code);
+#endif
+}
+
+
+static FILE *angel_info_w = NULL;
 
 static void
 writeChildInfo(const char *token, int val)
 {
-  fprintf(child_info_file_w, "%s=%d\n", token, val);
-  fflush(child_info_file_w);
+  fprintf(angel_info_w, "%s=%d\n", token, val);
+  fflush(angel_info_w);
 }
 
-void
+static void
 childReportSignal(int signum)
 {
   writeChildInfo("signal", signum);
 }
 
-void
-childReportError(int error)
-{
-  writeChildInfo("error", error);
-}
-
-void
-childExit(int code, Uint32 currentStartPhase)
+static void
+childExit(int error_code, int exit_code, Uint32 currentStartPhase)
 {
-#ifndef NDB_WIN
+  writeChildInfo("error", error_code);
   writeChildInfo("sphase", currentStartPhase);
-  writeChildInfo("exit", code);
-  fprintf(child_info_file_w, "\n");
-  fclose(child_info_file_r);
-  fclose(child_info_file_w);
-  ndbd_exit(code);
-#else
-  {
-    Configuration* theConfig=globalEmulatorData.theConfiguration;
-    theConfig->closeConfiguration(true);
-    switch (code) {
-    case NRT_Default:
-      g_eventLogger->info("Angel shutting down");
-      reportShutdown(theConfig, 0, 0, currentStartPhase);
-      ndbd_exit(0);
-      break;
-    case NRT_NoStart_Restart:
-      theConfig->setInitialStart(false);
-      globalData.theRestartFlag=initial_state;
-      break;
-    case NRT_NoStart_InitialStart:
-      theConfig->setInitialStart(true);
-      globalData.theRestartFlag=initial_state;
-      break;
-    case NRT_DoStart_InitialStart:
-      theConfig->setInitialStart(true);
-      globalData.theRestartFlag=perform_start;
-      break;
-    default:
-      if (theConfig->stopOnError())
-      {
-        /**
-         * Error shutdown && stopOnError()
-         */
-        reportShutdown(theConfig, 1, 0, currentStartPhase);
-        ndbd_exit(0);
-      }
-      // Fall-through
-    case NRT_DoStart_Restart:
-      theConfig->setInitialStart(false);
-      globalData.theRestartFlag=perform_start;
-      break;
-    }
-    char buf[80];
-    BaseString::snprintf(buf, sizeof (buf), "WIN_NDBD_CFG=%d %d %d",
-                         theConfig->getInitialStart(),
-                         globalData.theRestartFlag, globalData.ownId);
-    _putenv(buf);
-
-    char exe[MAX_PATH];
-    GetModuleFileName(0, exe, sizeof (exe));
-
-    STARTUPINFO sinfo;
-    ZeroMemory(&sinfo, sizeof (sinfo));
-    sinfo.cb=sizeof (STARTUPINFO);
-    sinfo.dwFlags=STARTF_USESHOWWINDOW;
-    sinfo.wShowWindow=SW_HIDE;
-
-    PROCESS_INFORMATION pinfo;
-    if (reportShutdown(theConfig, 0, 1, currentStartPhase))
-    {
-      g_eventLogger->error("unable to shutdown");
-      ndbd_exit(1);
-    }
-    g_eventLogger->info("Ndb has terminated.  code=%d", code);
-    if (code == NRT_NoStart_Restart)
-      globalTransporterRegistry.disconnectAll();
-    g_eventLogger->info("Ndb has terminated.  Restarting");
-    if (CreateProcess(exe, GetCommandLine(), NULL, NULL, TRUE, 0, NULL, NULL,
-                      &sinfo, &pinfo) == 0)
-    {
-      g_eventLogger->error("Angel was unable to create child ndbd process"
-                           " error: %d", GetLastError());
-    }
-  }
-#endif
+  fprintf(angel_info_w, "\n");
+  fclose(angel_info_w);
+  ndbd_exit(exit_code);
 }
 
-void
-childAbort(int code, Uint32 currentStartPhase)
+static void
+childAbort(int error_code, int exit_code, Uint32 currentStartPhase)
 {
-#ifndef NDB_WIN
+  writeChildInfo("error", error_code);
   writeChildInfo("sphase", currentStartPhase);
-  writeChildInfo("exit", code);
-  fprintf(child_info_file_w, "\n");
-  fclose(child_info_file_r);
-  fclose(child_info_file_w);
-#ifndef NDB_WIN32
+  fprintf(angel_info_w, "\n");
+  fclose(angel_info_w);
+
+#ifdef _WIN32
+  // Don't use 'abort' on Windows since it returns
+  // exit code 3 which conflict with NRT_NoStart_InitialStart
+  ndbd_exit(exit_code);
+#else
   signal(SIGABRT, SIG_DFL);
-#endif
   abort();
-#else
-  childExit(code, currentStartPhase);
 #endif
 }
 
@@ -457,7 +395,6 @@ extern "C"
 void
 handler_shutdown(int signum){
   g_eventLogger->info("Received signal %d. Performing stop.", signum);
-  childReportError(0);
   childReportSignal(signum);
   globalData.theRestartFlag = perform_stop;
 }
@@ -499,13 +436,13 @@ handler_error(int signum){
 
 static void
 catchsigs(bool foreground){
-#if !defined NDB_WIN32
-
   static const int signals_shutdown[] = {
 #ifdef SIGBREAK
     SIGBREAK,
 #endif
+#ifdef SIGHUP
     SIGHUP,
+#endif
     SIGINT,
 #if defined SIGPWR
     SIGPWR,
@@ -517,17 +454,25 @@ catchsigs(bool foreground){
 #ifdef SIGTSTP
     SIGTSTP,
 #endif
+#ifdef SIGTTIN
     SIGTTIN,
+#endif
+#ifdef SIGTTOU
     SIGTTOU
+#endif
   };
 
   static const int signals_error[] = {
     SIGABRT,
+#ifdef SIGALRM
     SIGALRM,
+#endif
 #ifdef SIGBUS
     SIGBUS,
 #endif
+#ifdef SIGCHLD
     SIGCHLD,
+#endif
     SIGFPE,
     SIGILL,
 #ifdef SIGIO
@@ -556,28 +501,59 @@ catchsigs(bool foreground){
     signal(SIGTRAP, handler_error);
 #endif
 
-#endif
 }
 
+
 void
-ndbd_exit(int code)
-{
-// gcov will not produce results when using _exit
-#ifdef HAVE_gcov
-  exit(code);
-#else
-  _exit(code);
-#endif
-}
+ndbd_run(bool foreground, int report_fd,
+         const char* connect_str, int force_nodeid, const char* bind_address,
+         bool no_start, bool initial, bool initialstart,
+         unsigned allocated_nodeid)
+{
+  if (foreground)
+    g_eventLogger->info("Ndb started in foreground");
+
+  if (report_fd)
+  {
+    g_eventLogger->debug("Opening report stream on fd: %d", report_fd);
+    // Open a stream for sending extra status to angel
+    if (!(angel_info_w = fdopen(report_fd, "w")))
+    {
+      g_eventLogger->error("Failed to open stream for reporting "
+                           "to angel, error: %d (%s)", errno, strerror(errno));
+      ndbd_exit(-1);
+    }
+  }
+  else
+  {
+    // No reporting requested, open /dev/null
+    const char* dev_null = IF_WIN("nul", "/dev/null");
+    if (!(angel_info_w = fopen(dev_null, "w")))
+    {
+      g_eventLogger->error("Failed to open stream for reporting to "
+                           "'%s', error: %d (%s)", dev_null, errno,
+                           strerror(errno));
+      ndbd_exit(-1);
+    }
+  }
 
-int
-ndbd_run(bool foreground)
-{
+  globalEmulatorData.create();
+
+  Configuration* theConfig = globalEmulatorData.theConfiguration;
+  if(!theConfig->init(no_start, initial, initialstart))
+  {
+    g_eventLogger->error("Failed to init Configuration");
+    ndbd_exit(-1);
+  }
+
+  theConfig->fetch_configuration(connect_str, force_nodeid, bind_address,
+                                 allocated_nodeid);
+
+  my_setwd(NdbConfig_get_path(0), MYF(0));
 
   if (get_multithreaded_config(globalEmulatorData))
-    return -1;
+    ndbd_exit(-1);
 
-  Configuration* theConfig = globalEmulatorData.theConfiguration;
   theConfig->setupConfiguration();
   systemInfo(* theConfig, * theConfig->m_logLevel);
 
@@ -593,11 +569,11 @@ ndbd_run(bool foreground)
     watchCounter = 9;           //  Means "doing allocation"
     globalEmulatorData.theWatchDog->registerWatchedThread(&watchCounter, 0);
     if (init_global_memory_manager(globalEmulatorData, &watchCounter))
-      return 1;
+      ndbd_exit(1);
     globalEmulatorData.theWatchDog->unregisterWatchedThread(0);
   }
 
-  globalEmulatorData.theThreadConfig->init(&globalEmulatorData);
+  globalEmulatorData.theThreadConfig->init();
 
 #ifdef VM_TRACE
   // Create a signal logger before block constructors
@@ -635,9 +611,6 @@ ndbd_run(bool foreground)
   /**
    * Do startup
    */
-
-  ErrorReporter::setErrorHandlerShutdownType(NST_ErrorHandlerStartup);
-
   switch(globalData.theRestartFlag){
   case initial_state:
     globalEmulatorData.theThreadConfig->doStart(NodeState::SL_CMVMI);
@@ -685,7 +658,193 @@ ndbd_run(bool foreground)
     globalEmulatorData.theThreadConfig->ipControlLoop(pThis, inx);
     globalEmulatorData.theConfiguration->removeThreadId(inx);
   }
-  NdbShutdown(NST_Normal);
+  NdbShutdown(0, NST_Normal);
+
+  ndbd_exit(0);
+}
+
+
+extern "C" my_bool opt_core;
+
+// instantiated and updated in NdbcntrMain.cpp
+extern Uint32 g_currentStartPhase;
+
+int simulate_error_during_shutdown= 0;
+
+void
+NdbShutdown(int error_code,
+            NdbShutdownType type,
+	    NdbRestartType restartType)
+{
+  if(type == NST_ErrorInsert)
+  {
+    type = NST_Restart;
+    restartType = (NdbRestartType)
+      globalEmulatorData.theConfiguration->getRestartOnErrorInsert();
+    if(restartType == NRT_Default)
+    {
+      type = NST_ErrorHandler;
+      globalEmulatorData.theConfiguration->stopOnError(true);
+    }
+  }
+
+  if((type == NST_ErrorHandlerSignal) || // Signal handler has already locked mutex
+     (NdbMutex_Trylock(theShutdownMutex) == 0)){
+    globalData.theRestartFlag = perform_stop;
+
+    bool restart = false;
+
+    if((type != NST_Normal &&
+	globalEmulatorData.theConfiguration->stopOnError() == false) ||
+       type == NST_Restart)
+    {
+      restart  = true;
+    }
+
+    const char * shutting = "shutting down";
+    if(restart)
+    {
+      shutting = "restarting";
+    }
+
+    switch(type){
+    case NST_Normal:
+      g_eventLogger->info("Shutdown initiated");
+      break;
+    case NST_Watchdog:
+      g_eventLogger->info("Watchdog %s system", shutting);
+      break;
+    case NST_ErrorHandler:
+      g_eventLogger->info("Error handler %s system", shutting);
+      break;
+    case NST_ErrorHandlerSignal:
+      g_eventLogger->info("Error handler signal %s system", shutting);
+      break;
+    case NST_Restart:
+      g_eventLogger->info("Restarting system");
+      break;
+    default:
+      g_eventLogger->info("Error handler %s system (unknown type: %u)",
+                          shutting, (unsigned)type);
+      type = NST_ErrorHandler;
+      break;
+    }
+
+    const char * exitAbort = 0;
+    if (opt_core)
+      exitAbort = "aborting";
+    else
+      exitAbort = "exiting";
+
+    if(type == NST_Watchdog)
+    {
+      /**
+       * Very serious, don't attempt to free, just die!!
+       */
+      g_eventLogger->info("Watchdog shutdown completed - %s", exitAbort);
+      if (opt_core)
+      {
+	childAbort(error_code, -1,g_currentStartPhase);
+      }
+      else
+      {
+	childExit(error_code, -1,g_currentStartPhase);
+      }
+    }
+
+#ifndef NDB_WIN32
+    if (simulate_error_during_shutdown)
+    {
+      kill(getpid(), simulate_error_during_shutdown);
+      while(true)
+	NdbSleep_MilliSleep(10);
+    }
+#endif
+
+    globalEmulatorData.theWatchDog->doStop();
+
+#ifdef VM_TRACE
+    FILE * outputStream = globalSignalLoggers.setOutputStream(0);
+    if(outputStream != 0)
+      fclose(outputStream);
+#endif
+
+    /**
+     * Don't touch transporter here (yet)
+     *   cause with ndbmtd, there are locks and nasty stuff
+     *   and we don't know which we are holding...
+     */
+#if NOT_YET
+
+    /**
+     * Stop all transporter connection attempts and accepts
+     */
+    globalEmulatorData.m_socket_server->stopServer();
+    globalEmulatorData.m_socket_server->stopSessions();
+    globalTransporterRegistry.stop_clients();
+
+    /**
+     * Stop transporter communication with other nodes
+     */
+    globalTransporterRegistry.stopSending();
+    globalTransporterRegistry.stopReceiving();
+
+    /**
+     * Remove all transporters
+     */
+    globalTransporterRegistry.removeAll();
+#endif
+
+    if(type == NST_ErrorInsert && opt_core)
+    {
+      // Unload some structures to reduce size of core
+      globalEmulatorData.theSimBlockList->unload();
+      NdbMutex_Unlock(theShutdownMutex);
+      globalEmulatorData.destroy();
+    }
+
+    if(type != NST_Normal && type != NST_Restart)
+    {
+      g_eventLogger->info("Error handler shutdown completed - %s", exitAbort);
+      if (opt_core)
+      {
+	childAbort(error_code, -1,g_currentStartPhase);
+      }
+      else
+      {
+	childExit(error_code, -1,g_currentStartPhase);
+      }
+    }
+
+    /**
+     * This is a normal restart, depend on angel
+     */
+    if(type == NST_Restart){
+      childExit(error_code, restartType,g_currentStartPhase);
+    }
+
+    g_eventLogger->info("Shutdown completed - exiting");
+  }
+  else
+  {
+    /**
+     * Shutdown is already in progress
+     */
 
-  return NRT_Default;
+    /**
+     * If this is the watchdog, kill system the hard way
+     */
+    if (type== NST_Watchdog)
+    {
+      g_eventLogger->info("Watchdog is killing system the hard way");
+#if defined VM_TRACE
+      childAbort(error_code, -1,g_currentStartPhase);
+#else
+      childExit(error_code, -1, g_currentStartPhase);
+#endif
+    }
+
+    while(true)
+      NdbSleep_MilliSleep(10);
+  }
 }

=== modified file 'storage/ndb/src/kernel/ndbd.hpp'
--- a/storage/ndb/src/kernel/ndbd.hpp	2009-06-04 12:56:22 +0000
+++ b/storage/ndb/src/kernel/ndbd.hpp	2010-05-05 15:27:29 +0000
@@ -16,7 +16,43 @@
 #ifndef NDBD_HPP
 #define NDBD_HPP
 
-int ndbd_run(bool foreground);
-void ndbd_exit(int code);
+void
+ndbd_run(bool foreground, int report_fd,
+         const char* connect_str, int force_nodeid, const char* bind_address,
+         bool no_start, bool initial, bool initialstart,
+         unsigned allocated_nodeid);
+
+enum NdbShutdownType {
+  NST_Normal,
+  NST_Watchdog,
+  NST_ErrorHandler,
+  NST_ErrorHandlerSignal,
+  NST_Restart,
+  NST_ErrorInsert
+};
+
+enum NdbRestartType {
+  NRT_Default               = 0,
+  NRT_NoStart_Restart       = 1, // -n
+  NRT_DoStart_Restart       = 2, //
+  NRT_NoStart_InitialStart  = 3, // -n -i
+  NRT_DoStart_InitialStart  = 4  // -i
+};
+
+/**
+ * Shutdown/restart Ndb
+ *
+ * @param error_code  - The error causing shutdown/restart
+ * @param type        - Type of shutdown/restart
+ * @param restartType - Type of restart (only valid if type == NST_Restart)
+ *
+ * NOTE! never returns
+ */
+void
+NdbShutdown(int error_code,
+            NdbShutdownType type,
+	    NdbRestartType restartType = NRT_Default);
+
+
 
 #endif

=== modified file 'storage/ndb/src/kernel/vm/Configuration.cpp'
--- a/storage/ndb/src/kernel/vm/Configuration.cpp	2010-05-04 14:34:54 +0000
+++ b/storage/ndb/src/kernel/vm/Configuration.cpp	2010-05-05 15:27:29 +0000
@@ -42,7 +42,7 @@ extern Uint32 g_start_type;
 
 bool
 Configuration::init(int _no_start, int _initial,
-                    int _initialstart, int _daemon)
+                    int _initialstart)
 {
   // Check the start flag
   if (_no_start)
@@ -54,10 +54,6 @@ Configuration::init(int _no_start, int _
   if (_initial)
     _initialStart = true;
 
-  // Check daemon flag
-  if (_daemon)
-    _daemonMode = true;
-
   globalData.ownId= 0;
 
   if (_initialstart)
@@ -81,7 +77,6 @@ Configuration::Configuration()
   _fsPath = 0;
   _backupPath = 0;
   _initialStart = false;
-  _daemonMode = false;
   m_config_retriever= 0;
   m_clusterConfig= 0;
   m_clusterConfigIter= 0;
@@ -117,7 +112,9 @@ Configuration::closeConfiguration(bool e
 void
 Configuration::fetch_configuration(const char* _connect_string,
                                    int force_nodeid,
-                                   const char* _bind_address){
+                                   const char* _bind_address,
+                                   NodeId allocated_nodeid)
+{
   /**
    * Fetch configuration from management server
    */
@@ -154,14 +151,28 @@ Configuration::fetch_configuration(const
   }
 
   ConfigRetriever &cr= *m_config_retriever;
-  globalData.ownId = cr.allocNodeId(globalData.ownId ? 10 : 2 /*retry*/,
-                                    3 /*delay*/);
-  
-  if(globalData.ownId == 0){
-    ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, 
-	      "Unable to alloc node id", m_config_retriever->getErrorString());
+
+  if (allocated_nodeid)
+  {
+    // The angel has already allocated the nodeid, no need to
+    // allocate it
+    globalData.ownId = allocated_nodeid;
   }
-  
+  else
+  {
+
+    const int alloc_retries = 2;
+    const int alloc_delay = 3;
+    globalData.ownId = cr.allocNodeId(alloc_retries, alloc_delay);
+    if(globalData.ownId == 0)
+    {
+      ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG,
+                "Unable to alloc node id",
+                m_config_retriever->getErrorString());
+    }
+  }
+  assert(globalData.ownId);
+
   ndb_mgm_configuration * p = cr.getConfig(globalData.ownId);
   if(p == 0){
     const char * s = cr.getErrorString();
@@ -215,28 +226,6 @@ Configuration::fetch_configuration(const
   }
   NdbConfig_SetPath(datadir);
 
-  m_mgmds.clear();
-  for(ndb_mgm_first(&iter); ndb_mgm_valid(&iter); ndb_mgm_next(&iter))
-  {
-    Uint32 nodeType, port;
-    char const *hostname;
-
-    ndb_mgm_get_int_parameter(&iter,CFG_TYPE_OF_SECTION,&nodeType);
-
-    if (nodeType != NodeInfo::MGM)
-      continue;
-
-    if (ndb_mgm_get_string_parameter(&iter,CFG_NODE_HOST, &hostname) ||
-	ndb_mgm_get_int_parameter(&iter,CFG_MGM_PORT, &port) ||
-	hostname == 0 || hostname[0] == 0)
-    {
-      continue;
-    }
-    BaseString connectstring(hostname);
-    connectstring.appfmt(":%d", port);
-
-    m_mgmds.push_back(connectstring);
-  }
 }
 
 static char * get_and_validate_path(ndb_mgm_configuration_iterator &iter,
@@ -899,11 +888,6 @@ Configuration::calcSizeAlt(ConfigValues 
 }
 
 void
-Configuration::setInitialStart(bool val){
-  _initialStart = val;
-}
-
-void
 Configuration::setAllRealtimeScheduler()
 {
   Uint32 i;

=== modified file 'storage/ndb/src/kernel/vm/Configuration.hpp'
--- a/storage/ndb/src/kernel/vm/Configuration.hpp	2010-05-04 14:34:54 +0000
+++ b/storage/ndb/src/kernel/vm/Configuration.hpp	2010-05-05 15:27:29 +0000
@@ -23,7 +23,7 @@
 
 #include <util/BaseString.hpp>
 #include <mgmapi.h>
-#include <ndb_types.h>
+#include <kernel_types.h>
 #include <NdbMutex.h>
 #include <NdbThread.h>
 #include <Bitmask.hpp>
@@ -58,10 +58,12 @@ public:
   ~Configuration();
 
   bool init(int _no_start, int _initial,
-            int _initialstart, int _daemon);
+            int _initialstart);
+
 
   void fetch_configuration(const char* _connect_string, int force_nodeid,
-                           const char* _bind_adress);
+                           const char* _bind_adress,
+                           NodeId allocated_nodeid);
   void setupConfiguration();
   void closeConfiguration(bool end_session= true);
   
@@ -116,12 +118,7 @@ public:
   const char * fileSystemPath() const;
   const char * backupFilePath() const;
 
-  /**
-   * 
-   */
-  bool getInitialStart() const;
-  void setInitialStart(bool val);
-  bool getDaemonMode() const;
+  bool getInitialStart() const { return _initialStart; }
 
   const ndb_mgm_configuration_iterator * getOwnConfigIterator() const;
 
@@ -135,7 +132,6 @@ public:
 private:
   friend class Cmvmi;
   friend class Qmgr;
-  friend int reportShutdown(class Configuration *config, int error, int restart, Uint32 sphase);
 
   Uint32 _stopOnError;
   Uint32 m_restartOnErrorInsert;
@@ -160,15 +156,12 @@ private:
   
   ConfigRetriever *m_config_retriever;
 
-  Vector<BaseString> m_mgmds;
-
   /**
    * arguments to NDB process
    */
   char * _fsPath;
   char * _backupPath;
   bool _initialStart;
-  bool _daemonMode; // if not, angel in foreground
 
   void calcSizeAlt(class ConfigValues * );
 };
@@ -185,16 +178,4 @@ Configuration::backupFilePath() const {
   return _backupPath;
 }
 
-inline
-bool
-Configuration::getInitialStart() const {
-  return _initialStart;
-}
-
-inline
-bool
-Configuration::getDaemonMode() const {
-  return _daemonMode;
-}
-
 #endif

=== modified file 'storage/ndb/src/kernel/vm/DynArr256.cpp'
--- a/storage/ndb/src/kernel/vm/DynArr256.cpp	2009-12-14 22:14:34 +0000
+++ b/storage/ndb/src/kernel/vm/DynArr256.cpp	2010-03-16 09:25:26 +0000
@@ -991,21 +991,6 @@ Uint32 g_currentStartPhase;
 Uint32 g_start_type;
 NdbNodeBitmask g_nowait_nodes;
 
-void childExit(int code, Uint32 currentStartPhase)
-{
-  abort();
-}
-
-void childAbort(int code, Uint32 currentStartPhase)
-{
-  abort();
-}
-
-void childReportError(int error)
-{
-  abort();
-}
-
 void
 UpgradeStartup::sendCmAppChg(Ndbcntr& cntr, Signal* signal, Uint32 startLevel){
 }

=== modified file 'storage/ndb/src/kernel/vm/Emulator.cpp'
--- a/storage/ndb/src/kernel/vm/Emulator.cpp	2010-03-09 14:16:11 +0000
+++ b/storage/ndb/src/kernel/vm/Emulator.cpp	2010-03-16 10:08:26 +0000
@@ -34,20 +34,10 @@
 
 #include <NdbMem.h>
 #include <NdbMutex.h>
-#include <NdbSleep.h>
 
 #include <EventLogger.hpp>
 extern EventLogger * g_eventLogger;
 
-void childExit(int code, Uint32 currentStartPhase);
-void childAbort(int code, Uint32 currentStartPhase);
-
-#ifndef NDB_WIN
-extern my_bool opt_core;
-#endif
-// instantiated and updated in NdbcntrMain.cpp
-extern Uint32 g_currentStartPhase;
-
 /**
  * Declare the global variables 
  */
@@ -73,7 +63,6 @@ EmulatedJamBuffer theEmulatedJamBuffer;
 
 EmulatorData globalEmulatorData;
 NdbMutex * theShutdownMutex = 0;
-int simulate_error_during_shutdown= 0;
 
 EmulatorData::EmulatorData(){
   theConfiguration = 0;
@@ -138,201 +127,3 @@ EmulatorData::destroy(){
   
   NdbMem_Destroy();
 }
-
-void
-NdbShutdown(NdbShutdownType type,
-	    NdbRestartType restartType)
-{
-  if(type == NST_ErrorInsert)
-  {
-    type = NST_Restart;
-    restartType = (NdbRestartType)
-      globalEmulatorData.theConfiguration->getRestartOnErrorInsert();
-    if(restartType == NRT_Default)
-    {
-      type = NST_ErrorHandler;
-      globalEmulatorData.theConfiguration->stopOnError(true);
-    }
-  }
-  
-  if((type == NST_ErrorHandlerSignal) || // Signal handler has already locked mutex
-     (NdbMutex_Trylock(theShutdownMutex) == 0)){
-    globalData.theRestartFlag = perform_stop;
-
-    bool restart = false;
-
-    if((type != NST_Normal && 
-	globalEmulatorData.theConfiguration->stopOnError() == false) ||
-       type == NST_Restart) 
-    {
-      restart  = true;
-    }
-
-
-    const char * shutting = "shutting down";
-    if(restart)
-    {
-      shutting = "restarting";
-    }
-    
-    switch(type){
-    case NST_Normal:
-      g_eventLogger->info("Shutdown initiated");
-      break;
-    case NST_Watchdog:
-      g_eventLogger->info("Watchdog %s system", shutting);
-      break;
-    case NST_ErrorHandler:
-      g_eventLogger->info("Error handler %s system", shutting);
-      break;
-    case NST_ErrorHandlerSignal:
-      g_eventLogger->info("Error handler signal %s system", shutting);
-      break;
-    case NST_ErrorHandlerStartup:
-      g_eventLogger->info("Error handler startup %s system", shutting);
-      break;
-    case NST_Restart:
-      g_eventLogger->info("Restarting system");
-      break;
-    default:
-      g_eventLogger->info("Error handler %s system (unknown type: %u)",
-                          shutting, (unsigned)type);
-      type = NST_ErrorHandler;
-      break;
-    }
-    
-    const char * exitAbort = 0;
-#ifndef NDB_WIN
-    if (opt_core)
-      exitAbort = "aborting";
-    else
-#endif
-      exitAbort = "exiting";
-    
-    if(type == NST_Watchdog)
-    {
-      /**
-       * Very serious, don't attempt to free, just die!!
-       */
-      g_eventLogger->info("Watchdog shutdown completed - %s", exitAbort);
-#ifndef NDB_WIN
-      if (opt_core)
-      {
-	childAbort(-1,g_currentStartPhase);
-      }
-      else
-#endif
-      {
-	childExit(-1,g_currentStartPhase);
-      }
-    }
-    
-#ifndef NDB_WIN32
-    if (simulate_error_during_shutdown) 
-    {
-      kill(getpid(), simulate_error_during_shutdown);
-      while(true)
-	NdbSleep_MilliSleep(10);
-    }
-#endif
-
-    globalEmulatorData.theWatchDog->doStop();
-    
-#ifdef VM_TRACE
-    FILE * outputStream = globalSignalLoggers.setOutputStream(0);
-    if(outputStream != 0)
-      fclose(outputStream);
-#endif
-    
-
-#ifndef NDB_WIN32
-#define UNLOAD (type == NST_ErrorInsert && opt_core)
-#else
-#define UNLOAD (0)
-#endif
-    /**
-     * Don't touch transporter here (yet)
-     *   cause with ndbmtd, there are locks and nasty stuff
-     *   and we don't know which we are holding...
-     */
-#if NOT_YET
-    
-    /**
-     * Stop all transporter connection attempts and accepts
-     */
-    globalEmulatorData.m_socket_server->stopServer();
-    globalEmulatorData.m_socket_server->stopSessions();
-    globalTransporterRegistry.stop_clients();
-
-    /**
-     * Stop transporter communication with other nodes
-     */
-    globalTransporterRegistry.stopSending();
-    globalTransporterRegistry.stopReceiving();
-    
-    /**
-     * Remove all transporters
-     */
-    globalTransporterRegistry.removeAll();
-#endif
-    
-    if(UNLOAD)
-    {
-      globalEmulatorData.theSimBlockList->unload();    
-      NdbMutex_Unlock(theShutdownMutex);
-      globalEmulatorData.destroy();
-    }
-    
-    if(type != NST_Normal && type != NST_Restart)
-    {
-      // Signal parent that error occured during startup
-#ifndef NDB_WIN
-      if (type == NST_ErrorHandlerStartup)
-	kill(getppid(), SIGUSR1);
-#endif
-      g_eventLogger->info("Error handler shutdown completed - %s", exitAbort);
-#ifndef NDB_WIN
-      if (opt_core)
-      {
-	childAbort(-1,g_currentStartPhase);
-      }
-      else
-#endif
-      {
-	childExit(-1,g_currentStartPhase);
-      }
-    }
-    
-    /**
-     * This is a normal restart, depend on angel
-     */
-    if(type == NST_Restart){
-      childExit(restartType,g_currentStartPhase);
-    }
-    
-    g_eventLogger->info("Shutdown completed - exiting");
-  } 
-  else 
-  {
-    /**
-     * Shutdown is already in progress
-     */
-    
-    /** 
-     * If this is the watchdog, kill system the hard way
-     */
-    if (type== NST_Watchdog)
-    {
-      g_eventLogger->info("Watchdog is killing system the hard way");
-#if defined VM_TRACE
-      childAbort(-1,g_currentStartPhase);
-#else
-      childExit(-1,g_currentStartPhase);
-#endif
-    }
-    
-    while(true)
-      NdbSleep_MilliSleep(10);
-  }
-}
-

=== modified file 'storage/ndb/src/kernel/vm/Emulator.hpp'
--- a/storage/ndb/src/kernel/vm/Emulator.hpp	2009-12-14 22:14:34 +0000
+++ b/storage/ndb/src/kernel/vm/Emulator.hpp	2010-03-16 09:25:26 +0000
@@ -80,34 +80,6 @@ struct EmulatorData {
 
 extern struct EmulatorData globalEmulatorData;
 
-enum NdbShutdownType {
-  NST_Normal,
-  NST_Watchdog,
-  NST_ErrorHandler,
-  NST_ErrorHandlerSignal,
-  NST_Restart,
-  NST_ErrorInsert,
-  NST_ErrorHandlerStartup
-};
-
-enum NdbRestartType {
-  NRT_Default               = 0,
-  NRT_NoStart_Restart       = 1, // -n
-  NRT_DoStart_Restart       = 2, //
-  NRT_NoStart_InitialStart  = 3, // -n -i
-  NRT_DoStart_InitialStart  = 4  // -i
-};
-
-/**
- * Shutdown/restart Ndb
- *
- * @param type        - Type of shutdown/restart
- * @param restartType - Type of restart (only valid if type == NST_Restart)
- */
-void 
-NdbShutdown(NdbShutdownType type, 
-	    NdbRestartType restartType = NRT_Default);
-
 /**
  * Compute no of pages to be used as job-buffer
  */

=== modified file 'storage/ndb/src/kernel/vm/SimulatedBlock.cpp'
--- a/storage/ndb/src/kernel/vm/SimulatedBlock.cpp	2010-03-11 09:44:08 +0000
+++ b/storage/ndb/src/kernel/vm/SimulatedBlock.cpp	2010-03-16 10:08:26 +0000
@@ -1784,9 +1784,7 @@ SimulatedBlock::progError(int line, int 
   // so that we can print them in error.log
   int magicStatus = 
     (m_ctx.m_config.stopOnError()<<1) + 
-    (m_ctx.m_config.getInitialStart()<<2) + 
-    (m_ctx.m_config.getDaemonMode()<<3);
-  
+    (m_ctx.m_config.getInitialStart()<<2);
 
   /* Add line number to block name */
   char buf[100];

=== modified file 'storage/ndb/src/kernel/vm/ThreadConfig.cpp'
--- a/storage/ndb/src/kernel/vm/ThreadConfig.cpp	2010-03-15 21:27:50 +0000
+++ b/storage/ndb/src/kernel/vm/ThreadConfig.cpp	2010-03-16 10:08:26 +0000
@@ -43,7 +43,7 @@ ThreadConfig::~ThreadConfig()
 }
 
 void
-ThreadConfig::init(EmulatorData *emulatorData)
+ThreadConfig::init()
 {
 }
 

=== modified file 'storage/ndb/src/kernel/vm/ThreadConfig.hpp'
--- a/storage/ndb/src/kernel/vm/ThreadConfig.hpp	2010-03-15 13:36:45 +0000
+++ b/storage/ndb/src/kernel/vm/ThreadConfig.hpp	2010-03-16 10:08:26 +0000
@@ -20,15 +20,15 @@
 #define ThreadConfig_H
 
 #include <kernel_types.h>
-#include <ErrorReporter.hpp>
 #include <NodeState.hpp>
+#include <portlib/NdbThread.h>
 
 class ThreadConfig
 {
 public:
   ThreadConfig();
   ~ThreadConfig();
-  void init(EmulatorData *emulatorData);
+  void init(void);
 
   void ipControlLoop(NdbThread*, Uint32 thread_index);
 

=== modified file 'storage/ndb/src/kernel/vm/bench_pool.cpp'
--- a/storage/ndb/src/kernel/vm/bench_pool.cpp	2009-05-26 18:53:34 +0000
+++ b/storage/ndb/src/kernel/vm/bench_pool.cpp	2010-03-16 09:25:26 +0000
@@ -553,21 +553,6 @@ Uint32 g_currentStartPhase;
 Uint32 g_start_type;
 NdbNodeBitmask g_nowait_nodes;
 
-void childExit(int code, Uint32 currentStartPhase)
-{
-  abort();
-}
-
-void childAbort(int code, Uint32 currentStartPhase)
-{
-  abort();
-}
-
-void childReportError(int error)
-{
-  abort();
-}
-
 void
 UpgradeStartup::sendCmAppChg(Ndbcntr& cntr, Signal* signal, Uint32 startLevel){
 }

=== modified file 'storage/ndb/src/kernel/vm/mt.cpp'
--- a/storage/ndb/src/kernel/vm/mt.cpp	2010-01-05 15:18:43 +0000
+++ b/storage/ndb/src/kernel/vm/mt.cpp	2010-03-16 08:22:13 +0000
@@ -3410,7 +3410,7 @@ ThreadConfig::~ThreadConfig()
  * constructor time the global memory manager is not available.
  */
 void
-ThreadConfig::init(EmulatorData *emulatorData)
+ThreadConfig::init()
 {
   num_lqh_workers = globalData.ndbMtLqhWorkers;
   num_lqh_threads = globalData.ndbMtLqhThreads;
@@ -3421,7 +3421,8 @@ ThreadConfig::init(EmulatorData *emulato
   ndbout << "NDBMT: num_threads=" << num_threads << endl;
 
   ::map_instance_init();
-  ::rep_init(&g_thr_repository, num_threads, emulatorData->m_mem_manager);
+  ::rep_init(&g_thr_repository, num_threads,
+             globalEmulatorData.m_mem_manager);
 }
 
 static

Attachment: [text/bzr-bundle] bzr/magnus.blaudd@sun.com-20100505152729-sv3qj374ibo1zlgj.bundle
Thread
bzr commit into mysql-5.1-telco-7.0 branch (magnus.blaudd:3525)Magnus Blåudd5 May