16 #include <ndb_global.h> 
   19 #include <NdbConfig.h> 
   21 #include <portlib/NdbDir.hpp> 
   22 #include <NdbAutoPtr.hpp> 
   23 #include <portlib/NdbNuma.h> 
   25 #include "vm/SimBlockList.hpp" 
   26 #include "vm/WatchDog.hpp" 
   27 #include "vm/ThreadConfig.hpp" 
   28 #include "vm/Configuration.hpp" 
   32 #include <ConfigRetriever.hpp> 
   33 #include <LogLevel.hpp> 
   35 #if defined NDB_SOLARIS 
   36 #include <sys/processor.h> 
   39 #include <EventLogger.hpp> 
   49   GetSystemInfo(&sinfo);
 
   50   processors = sinfo.dwNumberOfProcessors;
 
   52   if(ERROR_SUCCESS==RegOpenKeyEx
 
   54       TEXT(
"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"),
 
   55       0, KEY_READ, &hKey)) {
 
   57     DWORD cbData = 
sizeof(dwMHz);
 
   58     if(ERROR_SUCCESS==RegQueryValueEx(hKey,
 
   59                                       "~MHz", 0, 0, (LPBYTE)&dwMHz, &cbData)) {
 
   64 #elif defined NDB_SOLARIS 
   66   processor_info_t pinfo; memset(&pinfo, 0, 
sizeof(pinfo));
 
   68   while(processors < 16 && pid < 256){
 
   69     if(!processor_info(pid++, &pinfo))
 
   72   speed = pinfo.pi_clock;
 
   76     g_eventLogger->
info(
"NDB Cluster -- DB node %d", globalData.ownId);
 
   77     g_eventLogger->
info(
"%s --", NDB_VERSION_STRING);
 
   79     g_eventLogger->
info(
"NDB is running on a machine with %d processor(s) at %d MHz",
 
   84     Uint32 t = config.timeBetweenWatchDogCheck();
 
   85     g_eventLogger->
info(
"WatchDog timer is set to %d ms", t);
 
   94   ndb_mgm_get_int64_parameter(p, CFG_DB_INDEX_MEM, &accmem);
 
   97     accmem /= GLOBAL_PAGE_SIZE;
 
   99     Uint32 lqhInstances = 1;
 
  100     if (globalData.isNdbMtLqh)
 
  102       lqhInstances = globalData.ndbMtLqhWorkers;
 
  105     accmem += lqhInstances * (32 / 4); 
 
  107   return Uint32(accmem);
 
  111 init_global_memory_manager(
EmulatorData &ed, Uint32 *watchCounter)
 
  114     ed.theConfiguration->getOwnConfigIterator();
 
  121   ndb_mgm_get_int_parameter(p, CFG_DB_NUMA, &numa);
 
  124     int res = NdbNuma_setInterleaved();
 
  125     g_eventLogger->
info(
"numa_set_interleave_mask(numa_all_nodes) : %s",
 
  126                         res == 0 ? 
"OK" : 
"no numa support");
 
  129   Uint64 shared_mem = 8*1024*1024;
 
  130   ndb_mgm_get_int64_parameter(p, CFG_DB_SGA, &shared_mem);
 
  131   Uint32 shared_pages = Uint32(shared_mem /= GLOBAL_PAGE_SIZE);
 
  134   if (ndb_mgm_get_int_parameter(p, CFG_TUP_PAGE, &tupmem))
 
  136     g_eventLogger->
alert(
"Failed to get CFG_TUP_PAGE parameter from " 
  145     Uint32 accpages = compute_acc_32kpages(p);
 
  149   Uint32 lqhInstances = 1;
 
  150   if (globalData.isNdbMtLqh)
 
  152     lqhInstances = globalData.ndbMtLqhWorkers;
 
  160     rl.m_resource_id = RG_DATAMEM;
 
  164   Uint32 maxopen = 4 * 4; 
 
  165   Uint32 filebuffer = NDB_FILE_BUFFER_SIZE;
 
  166   Uint32 filepages = (filebuffer / GLOBAL_PAGE_SIZE) * maxopen;
 
  173     ndb_mgm_get_int_parameter(p, CFG_DB_REDO_BUFFER,
 
  178       redomem /= GLOBAL_PAGE_SIZE;
 
  179       Uint32 tmp = redomem & 15;
 
  182         redomem += (16 - tmp);
 
  185       filepages += lqhInstances * redomem; 
 
  192     rl.m_min = filepages;
 
  193     rl.m_max = filepages;
 
  194     rl.m_resource_id = RG_FILE_BUFFERS;
 
  198   Uint32 jbpages = compute_jb_pages(&ed);
 
  204     rl.m_resource_id = RG_JOBBUFFER;
 
  209   if (globalTransporterRegistry.get_using_default_send_buffer() == 
false)
 
  212     sbpages = Uint32((mem + GLOBAL_PAGE_SIZE - 1) / GLOBAL_PAGE_SIZE);
 
  216     rl.m_resource_id = RG_TRANSPORTER_BUFFERS;
 
  220   Uint32 pgman_pages = 0;
 
  225     Uint64 page_buffer = 64*1024*1024;
 
  226     ndb_mgm_get_int64_parameter(p, CFG_DB_DISK_PAGE_BUFFER_MEMORY,&page_buffer);
 
  229     pages += Uint32(page_buffer / GLOBAL_PAGE_SIZE); 
 
  230     pages += LCP_RESTORE_BUFFER * lqhInstances;
 
  232     pgman_pages += pages;
 
  236     rl.m_min = pgman_pages;
 
  237     rl.m_max = pgman_pages;
 
  238     rl.m_resource_id = RG_DISK_PAGE_BUFFER;  
 
  242   Uint32 sum = shared_pages + tupmem + filepages + jbpages + sbpages +
 
  250     rl.m_resource_id = 0;
 
  254   if (!ed.m_mem_manager->
init(watchCounter))
 
  265     g_eventLogger->
alert(
"Malloc (%lld bytes) for %s and %s failed, exiting",
 
  266                          Uint64(shared_mem + tupmem) * GLOBAL_PAGE_SIZE,
 
  267                          dm.m_name, sga.m_name);
 
  271   Uint32 late_alloc = 0;
 
  272   ndb_mgm_get_int_parameter(p, CFG_DB_LATE_ALLOC,
 
  276   ndb_mgm_get_int_parameter(p, CFG_DB_MEMLOCK, &memlock);
 
  283     Uint32 rg[] = { RG_JOBBUFFER, RG_FILE_BUFFERS, RG_TRANSPORTER_BUFFERS, 0 };
 
  284     ed.m_mem_manager->
map(watchCounter, memlock, rg);
 
  288     ed.m_mem_manager->
map(watchCounter, memlock); 
 
  299   globalData.isNdbMt = SimulatedBlock::isMultiThreaded();
 
  300   if (!globalData.isNdbMt)
 
  302     ndbout << 
"NDBMT: non-mt" << endl;
 
  306   THRConfig & conf = ed.theConfiguration->m_thr_config;
 
  308   Uint32 threadcount = conf.getThreadCount();
 
  309   ndbout << 
"NDBMT: MaxNoOfExecutionThreads=" << threadcount << endl;
 
  311   globalData.isNdbMtLqh = 
true;
 
  314     if (conf.getMtClassic())
 
  316       globalData.isNdbMtLqh = 
false;
 
  320   if (!globalData.isNdbMtLqh)
 
  323   Uint32 threads = conf.getThreadCount(THRConfig::T_LDM);
 
  324   Uint32 workers = threads;
 
  333     if (ndb_mgm_find(p, CFG_NODE_ID, globalData.ownId))
 
  337     ndb_mgm_get_int_parameter(p, CFG_NDBMT_LQH_WORKERS, &workers);
 
  344     p = NdbEnv_GetEnv(
"NDBMT_LQH_WORKERS", (
char*)0, 0);
 
  350   ndbout << 
"NDBMT: workers=" << workers
 
  351          << 
" threads=" << threads << endl;
 
  353   assert(workers != 0 && workers <= MAX_NDBMT_LQH_WORKERS);
 
  354   assert(threads != 0 && threads <= MAX_NDBMT_LQH_THREADS);
 
  355   assert(workers % threads == 0);
 
  357   globalData.ndbMtLqhWorkers = workers;
 
  358   globalData.ndbMtLqhThreads = threads;
 
  379 static FILE *angel_info_w = NULL;
 
  382 writeChildInfo(
const char *token, 
int val)
 
  384   fprintf(angel_info_w, 
"%s=%d\n", token, val);
 
  385   fflush(angel_info_w);
 
  389 childReportSignal(
int signum)
 
  391   writeChildInfo(
"signal", signum);
 
  395 childExit(
int error_code, 
int exit_code, Uint32 currentStartPhase)
 
  397   writeChildInfo(
"error", error_code);
 
  398   writeChildInfo(
"sphase", currentStartPhase);
 
  399   fprintf(angel_info_w, 
"\n");
 
  400   fclose(angel_info_w);
 
  401   ndbd_exit(exit_code);
 
  405 childAbort(
int error_code, 
int exit_code, Uint32 currentStartPhase)
 
  407   writeChildInfo(
"error", error_code);
 
  408   writeChildInfo(
"sphase", currentStartPhase);
 
  409   fprintf(angel_info_w, 
"\n");
 
  410   fclose(angel_info_w);
 
  415   ndbd_exit(exit_code);
 
  417   signal(SIGABRT, SIG_DFL);
 
  424 handler_shutdown(
int signum){
 
  425   g_eventLogger->
info(
"Received signal %d. Performing stop.", signum);
 
  426   childReportSignal(signum);
 
  427   globalData.theRestartFlag = perform_stop;
 
  430 extern NdbMutex * theShutdownMutex;
 
  434 handler_error(
int signum){
 
  436   static bool handling_error = 
false;
 
  437   static pthread_t thread_id; 
 
  439   if (handling_error &&
 
  440       pthread_equal(thread_id, pthread_self()))
 
  444         signal(signum, SIG_DFL);
 
  445     kill(getpid(), signum);
 
  448       NdbSleep_MilliSleep(10);
 
  450   if(theShutdownMutex && NdbMutex_Trylock(theShutdownMutex) != 0)
 
  452       NdbSleep_MilliSleep(10);
 
  454   thread_id = pthread_self();
 
  455   handling_error = 
true;
 
  457   g_eventLogger->
info(
"Received signal %d. Running error handler.", signum);
 
  458   childReportSignal(signum);
 
  460   char errorData[64], *info= 0;
 
  461 #ifdef HAVE_STRSIGNAL 
  462   info= strsignal(signum);
 
  465                        info ? info : 
"No text for signal available");
 
  466   ERROR_SET_SIGNAL(fatal, NDBD_EXIT_OS_SIGNAL_RECEIVED, errorData, __FILE__);
 
  471 catchsigs(
bool foreground){
 
  472   static const int signals_shutdown[] = {
 
  482 #elif defined SIGINFO 
  498   static const int signals_error[] = {
 
  520   static const int signals_ignore[] = {
 
  525   for(i = 0; i < 
sizeof(signals_shutdown)/
sizeof(signals_shutdown[0]); i++)
 
  526     signal(signals_shutdown[i], handler_shutdown);
 
  527   for(i = 0; i < 
sizeof(signals_error)/
sizeof(signals_error[0]); i++)
 
  528     signal(signals_error[i], handler_error);
 
  529   for(i = 0; i < 
sizeof(signals_ignore)/
sizeof(signals_ignore[0]); i++)
 
  530     signal(signals_ignore[i], SIG_IGN);
 
  534     signal(SIGTRAP, handler_error);
 
  540 static HANDLE g_shutdown_event;
 
  542 DWORD WINAPI shutdown_thread(LPVOID)
 
  545   WaitForSingleObject(g_shutdown_event, INFINITE);
 
  547   g_eventLogger->
info(
"Performing stop");
 
  548   globalData.theRestartFlag = perform_stop;
 
  555 ndbd_run(
bool foreground, 
int report_fd,
 
  556          const char* connect_str, 
int force_nodeid, 
const char* bind_address,
 
  557          bool no_start, 
bool initial, 
bool initialstart,
 
  558          unsigned allocated_nodeid)
 
  562     char shutdown_event_name[32];
 
  563     _snprintf(shutdown_event_name, 
sizeof(shutdown_event_name),
 
  564               "ndbd_shutdown_%d", GetCurrentProcessId());
 
  566     g_shutdown_event = CreateEvent(NULL, TRUE, FALSE, shutdown_event_name);
 
  567     if (g_shutdown_event == NULL)
 
  569       g_eventLogger->
error(
"Failed to create shutdown event, error: %d",
 
  574     HANDLE thread = CreateThread(NULL, 0, &shutdown_thread, NULL, 0, NULL);
 
  577       g_eventLogger->
error(
"couldn't start shutdown thread, error: %d",
 
  585     g_eventLogger->
info(
"Ndb started in foreground");
 
  589     g_eventLogger->
debug(
"Opening report stream on fd: %d", report_fd);
 
  591     if (!(angel_info_w = fdopen(report_fd, 
"w")))
 
  593       g_eventLogger->
error(
"Failed to open stream for reporting " 
  594                            "to angel, error: %d (%s)", errno, strerror(errno));
 
  601     const char* dev_null = IF_WIN(
"nul", 
"/dev/null");
 
  602     if (!(angel_info_w = fopen(dev_null, 
"w")))
 
  604       g_eventLogger->
error(
"Failed to open stream for reporting to " 
  605                            "'%s', error: %d (%s)", dev_null, errno,
 
  611   globalEmulatorData.
create();
 
  613   Configuration* theConfig = globalEmulatorData.theConfiguration;
 
  614   if(!theConfig->init(no_start, initial, initialstart))
 
  616     g_eventLogger->
error(
"Failed to init Configuration");
 
  623   if (NdbDir::chdir(NdbConfig_get_path(NULL)) != 0)
 
  625     g_eventLogger->
warning(
"Cannot change directory to '%s', error: %d",
 
  626                            NdbConfig_get_path(NULL), errno);
 
  632   if (get_multithreaded_config(globalEmulatorData))
 
  635   systemInfo(* theConfig, * theConfig->m_logLevel);
 
  637   NdbThread* pWatchdog = globalEmulatorData.theWatchDog->doStart();
 
  647     globalEmulatorData.theWatchDog->registerWatchedThread(&watchCounter, 0);
 
  648     if (init_global_memory_manager(globalEmulatorData, &watchCounter))
 
  650     globalEmulatorData.theWatchDog->unregisterWatchedThread(0);
 
  653   globalEmulatorData.theThreadConfig->init();
 
  657   char *
buf= NdbConfig_SignalLogFileName(globalData.ownId);
 
  659   FILE * signalLog = fopen(buf, 
"a");
 
  660   globalSignalLoggers.setOwnNodeId(globalData.ownId);
 
  661   globalSignalLoggers.setOutputStream(signalLog);
 
  662 #if 1 // to log startup 
  663   { 
const char* p = NdbEnv_GetEnv(
"NDB_SIGNAL_LOG", (
char*)0, 0);
 
  667       for (
char* q = buf; *q != 0; q++) *q = toupper(toascii(*q));
 
  668       globalSignalLoggers.log(SignalLoggerManager::LogInOut, buf);
 
  669       globalData.testOn = 1;
 
  670       assert(signalLog != 0);
 
  671       fprintf(signalLog, 
"START\n");
 
  679   globalEmulatorData.theSimBlockList->load(globalEmulatorData);
 
  683   status = NdbThread_SetConcurrencyLevel(30);
 
  686   catchsigs(foreground);
 
  691   switch(globalData.theRestartFlag){
 
  700     assert(
"Illegal state globalData.theRestartFlag" == 0);
 
  705   if (!globalTransporterRegistry.start_service(*globalEmulatorData.m_socket_server)){
 
  706     ndbout_c(
"globalTransporterRegistry.start_service() failed");
 
  711   if(!globalTransporterRegistry.connect_client(
 
  712                  theConfig->get_config_retriever()->get_mgmHandlePtr()))
 
  713       ERROR_SET(fatal, NDBD_EXIT_CONNECTION_SETUP_FAILED,
 
  714                 "Failed to convert mgm connection to a transporter",
 
  717   NdbThread* pTrp = globalTransporterRegistry.start_clients();
 
  720     ndbout_c(
"globalTransporterRegistry.start_clients() failed");
 
  726   globalEmulatorData.theConfiguration->
addThread(pTrp, SocketClientThread);
 
  727   globalEmulatorData.theConfiguration->
addThread(pWatchdog, WatchDogThread);
 
  728   globalEmulatorData.theConfiguration->
addThread(pSockServ, SocketServerThread);
 
  732     NdbThread *pThis = NdbThread_CreateObject(0);
 
  733     Uint32 inx = globalEmulatorData.theConfiguration->
addThread(pThis,
 
  735     globalEmulatorData.theThreadConfig->
ipControlLoop(pThis, inx);
 
  736     globalEmulatorData.theConfiguration->removeThreadId(inx);
 
  738   NdbShutdown(0, NST_Normal);
 
  744 extern "C" my_bool opt_core;
 
  747 extern Uint32 g_currentStartPhase;
 
  749 int simulate_error_during_shutdown= 0;
 
  752 NdbShutdown(
int error_code,
 
  753             NdbShutdownType 
type,
 
  754             NdbRestartType restartType)
 
  756   if(type == NST_ErrorInsert)
 
  759     restartType = (NdbRestartType)
 
  760       globalEmulatorData.theConfiguration->getRestartOnErrorInsert();
 
  761     if(restartType == NRT_Default)
 
  763       type = NST_ErrorHandler;
 
  764       globalEmulatorData.theConfiguration->stopOnError(
true);
 
  768   if((type == NST_ErrorHandlerSignal) || 
 
  769      (NdbMutex_Trylock(theShutdownMutex) == 0)){
 
  770     globalData.theRestartFlag = perform_stop;
 
  772     bool restart = 
false;
 
  774     if((type != NST_Normal &&
 
  775         globalEmulatorData.theConfiguration->stopOnError() == 
false) ||
 
  781     const char * shutting = 
"shutting down";
 
  784       shutting = 
"restarting";
 
  789       g_eventLogger->
info(
"Shutdown initiated");
 
  792       g_eventLogger->
info(
"Watchdog %s system", shutting);
 
  794     case NST_ErrorHandler:
 
  795       g_eventLogger->
info(
"Error handler %s system", shutting);
 
  797     case NST_ErrorHandlerSignal:
 
  798       g_eventLogger->
info(
"Error handler signal %s system", shutting);
 
  801       g_eventLogger->
info(
"Restarting system");
 
  804       g_eventLogger->
info(
"Error handler %s system (unknown type: %u)",
 
  805                           shutting, (
unsigned)type);
 
  806       type = NST_ErrorHandler;
 
  810     const char * exitAbort = 0;
 
  812       exitAbort = 
"aborting";
 
  814       exitAbort = 
"exiting";
 
  816     if(type == NST_Watchdog)
 
  821       g_eventLogger->
info(
"Watchdog shutdown completed - %s", exitAbort);
 
  824         childAbort(error_code, -1,g_currentStartPhase);
 
  828         childExit(error_code, -1,g_currentStartPhase);
 
  833     if (simulate_error_during_shutdown)
 
  835       kill(getpid(), simulate_error_during_shutdown);
 
  837         NdbSleep_MilliSleep(10);
 
  841     globalEmulatorData.theWatchDog->doStop();
 
  844     FILE * outputStream = globalSignalLoggers.setOutputStream(0);
 
  845     if(outputStream != 0)
 
  846       fclose(outputStream);
 
  859     globalEmulatorData.m_socket_server->stopServer();
 
  861     globalTransporterRegistry.stop_clients();
 
  866     globalTransporterRegistry.stopSending();
 
  875     if(type == NST_ErrorInsert && opt_core)
 
  878       globalEmulatorData.theSimBlockList->unload();
 
  879       NdbMutex_Unlock(theShutdownMutex);
 
  883     if(type != NST_Normal && type != NST_Restart)
 
  885       g_eventLogger->
info(
"Error handler shutdown completed - %s", exitAbort);
 
  888         childAbort(error_code, -1,g_currentStartPhase);
 
  892         childExit(error_code, -1,g_currentStartPhase);
 
  899     if(type == NST_Restart){
 
  900       childExit(error_code, restartType,g_currentStartPhase);
 
  903     g_eventLogger->
info(
"Shutdown completed - exiting");
 
  914     if (type== NST_Watchdog)
 
  916       g_eventLogger->
info(
"Watchdog is killing system the hard way");
 
  918       childAbort(error_code, -1,g_currentStartPhase);
 
  920       childExit(error_code, -1, g_currentStartPhase);
 
  925       NdbSleep_MilliSleep(10);