00001 /* Copyright (C) 2003 MySQL AB 00002 00003 This program is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU General Public License as published by 00005 the Free Software Foundation; either version 2 of the License, or 00006 (at your option) any later version. 00007 00008 This program is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 GNU General Public License for more details. 00012 00013 You should have received a copy of the GNU General Public License 00014 along with this program; if not, write to the Free Software 00015 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 00016 00017 #include <ndb_global.h> 00018 00019 #include "Emulator.hpp" 00020 #include <FastScheduler.hpp> 00021 #include <SignalLoggerManager.hpp> 00022 #include <TransporterRegistry.hpp> 00023 #include <TimeQueue.hpp> 00024 00025 #include "Configuration.hpp" 00026 #include "WatchDog.hpp" 00027 #include "ThreadConfig.hpp" 00028 #include "SimBlockList.hpp" 00029 00030 #include <NodeState.hpp> 00031 00032 #include <NdbMem.h> 00033 #include <NdbOut.hpp> 00034 #include <NdbMutex.h> 00035 #include <NdbSleep.h> 00036 00037 extern "C" { 00038 extern void (* ndb_new_handler)(); 00039 } 00040 00045 #ifndef NO_EMULATED_JAM 00046 Uint8 theEmulatedJam[EMULATED_JAM_SIZE * 4]; 00047 Uint32 theEmulatedJamIndex = 0; 00048 Uint32 theEmulatedJamBlockNumber = 0; 00049 #endif 00050 00051 GlobalData globalData; 00052 00053 TimeQueue globalTimeQueue; 00054 FastScheduler globalScheduler; 00055 TransporterRegistry globalTransporterRegistry; 00056 00057 #ifdef VM_TRACE 00058 SignalLoggerManager globalSignalLoggers; 00059 #endif 00060 00061 EmulatorData globalEmulatorData; 00062 NdbMutex * theShutdownMutex = 0; 00063 int simulate_error_during_shutdown= 0; 00064 00065 EmulatorData::EmulatorData(){ 00066 theConfiguration = 0; 00067 theWatchDog = 0; 00068 theThreadConfig = 0; 00069 theSimBlockList = 0; 00070 theShutdownMutex = 0; 00071 m_socket_server = 0; 00072 } 00073 00074 void 00075 ndb_new_handler_impl(){ 00076 ERROR_SET(fatal, ERR_MEMALLOC, "New handler", ""); 00077 } 00078 00079 void 00080 EmulatorData::create(){ 00081 NdbMem_Create(); 00082 00083 theConfiguration = new Configuration(); 00084 theWatchDog = new WatchDog(); 00085 theThreadConfig = new ThreadConfig(); 00086 theSimBlockList = new SimBlockList(); 00087 m_socket_server = new SocketServer(); 00088 00089 theShutdownMutex = NdbMutex_Create(); 00090 00091 ndb_new_handler = ndb_new_handler_impl; 00092 } 00093 00094 void 00095 EmulatorData::destroy(){ 00096 if(theConfiguration) 00097 delete theConfiguration; theConfiguration = 0; 00098 if(theWatchDog) 00099 delete theWatchDog; theWatchDog = 0; 00100 if(theThreadConfig) 00101 delete theThreadConfig; theThreadConfig = 0; 00102 if(theSimBlockList) 00103 delete theSimBlockList; theSimBlockList = 0; 00104 if(m_socket_server) 00105 delete m_socket_server; m_socket_server = 0; 00106 NdbMem_Destroy(); 00107 } 00108 00109 void 00110 NdbShutdown(NdbShutdownType type, 00111 NdbRestartType restartType){ 00112 00113 if(type == NST_ErrorInsert){ 00114 type = NST_Restart; 00115 restartType = (NdbRestartType) 00116 globalEmulatorData.theConfiguration->getRestartOnErrorInsert(); 00117 if(restartType == NRT_Default){ 00118 type = NST_ErrorHandler; 00119 globalEmulatorData.theConfiguration->stopOnError(true); 00120 } 00121 } 00122 00123 if((type == NST_ErrorHandlerSignal) || // Signal handler has already locked mutex 00124 (NdbMutex_Trylock(theShutdownMutex) == 0)){ 00125 globalData.theRestartFlag = perform_stop; 00126 00127 bool restart = false; 00128 #if ! ( defined NDB_OSE || defined NDB_SOFTOSE) 00129 if((type != NST_Normal && 00130 globalEmulatorData.theConfiguration->stopOnError() == false) || 00131 type == NST_Restart) { 00132 00133 restart = true; 00134 } 00135 #endif 00136 00137 const char * shutting = "shutting down"; 00138 if(restart){ 00139 shutting = "restarting"; 00140 } 00141 00142 switch(type){ 00143 case NST_Normal: 00144 ndbout << "Shutdown initiated" << endl; 00145 break; 00146 case NST_Watchdog: 00147 ndbout << "Watchdog " << shutting << " system" << endl; 00148 break; 00149 case NST_ErrorHandler: 00150 ndbout << "Error handler " << shutting << " system" << endl; 00151 break; 00152 case NST_ErrorHandlerSignal: 00153 ndbout << "Error handler signal " << shutting << " system" << endl; 00154 break; 00155 case NST_Restart: 00156 ndbout << "Restarting system" << endl; 00157 break; 00158 default: 00159 ndbout << "Error handler " << shutting << " system" 00160 << " (unknown type: " << (unsigned)type << ")" << endl; 00161 type = NST_ErrorHandler; 00162 break; 00163 } 00164 00165 const char * exitAbort = 0; 00166 #if defined VM_TRACE && ( ! ( defined NDB_OSE || defined NDB_SOFTOSE) ) 00167 exitAbort = "aborting"; 00168 #else 00169 exitAbort = "exiting"; 00170 #endif 00171 00172 if(type == NST_Watchdog){ 00176 ndbout << "Watchdog shutdown completed - " << exitAbort << endl; 00177 #if defined VM_TRACE && ( ! ( defined NDB_OSE || defined NDB_SOFTOSE) ) 00178 signal(6, SIG_DFL); 00179 abort(); 00180 #else 00181 exit(-1); 00182 #endif 00183 } 00184 00185 #ifndef NDB_WIN32 00186 if (simulate_error_during_shutdown) { 00187 kill(getpid(), simulate_error_during_shutdown); 00188 while(true) 00189 NdbSleep_MilliSleep(10); 00190 } 00191 #endif 00192 00193 globalEmulatorData.theWatchDog->doStop(); 00194 00195 #ifdef VM_TRACE 00196 FILE * outputStream = globalSignalLoggers.setOutputStream(0); 00197 if(outputStream != 0) 00198 fclose(outputStream); 00199 #endif 00200 00204 globalEmulatorData.m_socket_server->stopServer(); 00205 globalEmulatorData.m_socket_server->stopSessions(); 00206 globalTransporterRegistry.stop_clients(); 00207 00211 globalTransporterRegistry.stopSending(); 00212 globalTransporterRegistry.stopReceiving(); 00213 00217 globalTransporterRegistry.removeAll(); 00218 00219 #ifdef VM_TRACE 00220 #define UNLOAD (type != NST_ErrorHandler && type != NST_Watchdog) 00221 #else 00222 #define UNLOAD true 00223 #endif 00224 if(UNLOAD){ 00225 globalEmulatorData.theSimBlockList->unload(); 00226 globalEmulatorData.destroy(); 00227 } 00228 00229 if(type != NST_Normal && type != NST_Restart){ 00230 ndbout << "Error handler shutdown completed - " << exitAbort << endl; 00231 #if ( defined VM_TRACE || defined ERROR_INSERT ) && ( ! ( defined NDB_OSE || defined NDB_SOFTOSE) ) 00232 signal(6, SIG_DFL); 00233 abort(); 00234 #else 00235 exit(-1); 00236 #endif 00237 } 00238 00242 if(type == NST_Restart){ 00243 exit(restartType); 00244 } 00245 00246 ndbout << "Shutdown completed - exiting" << endl; 00247 } else { 00255 if (type== NST_Watchdog){ 00256 ndbout << "Watchdog is killing system the hard way" << endl; 00257 #if defined VM_TRACE && ( ! ( defined NDB_OSE || defined NDB_SOFTOSE) ) 00258 signal(6, SIG_DFL); 00259 abort(); 00260 #else 00261 exit(-1); 00262 #endif 00263 } 00264 00265 while(true) 00266 NdbSleep_MilliSleep(10); 00267 } 00268 } 00269
1.4.3