@@ -359,7 +359,7 @@ childReportSignal(int signum)
359359 writeChildInfo (" signal" , signum);
360360}
361361
362- void
362+ static void
363363childExit (int error_code, int exit_code, Uint32 currentStartPhase)
364364{
365365 writeChildInfo (" error" , error_code);
@@ -369,7 +369,7 @@ childExit(int error_code, int exit_code, Uint32 currentStartPhase)
369369 ndbd_exit (exit_code);
370370}
371371
372- void
372+ static void
373373childAbort (int error_code, int exit_code, Uint32 currentStartPhase)
374374{
375375#ifndef NDB_WIN
@@ -657,3 +657,199 @@ ndbd_run(bool foreground, int report_fd,
657657
658658 ndbd_exit (0 );
659659}
660+
661+
662+ extern " C" my_bool opt_core;
663+
664+ // instantiated and updated in NdbcntrMain.cpp
665+ extern Uint32 g_currentStartPhase;
666+
667+ int simulate_error_during_shutdown= 0 ;
668+
669+ void
670+ NdbShutdown (int error_code,
671+ NdbShutdownType type,
672+ NdbRestartType restartType)
673+ {
674+ if (type == NST_ErrorInsert)
675+ {
676+ type = NST_Restart;
677+ restartType = (NdbRestartType)
678+ globalEmulatorData.theConfiguration ->getRestartOnErrorInsert ();
679+ if (restartType == NRT_Default)
680+ {
681+ type = NST_ErrorHandler;
682+ globalEmulatorData.theConfiguration ->stopOnError (true );
683+ }
684+ }
685+
686+ if ((type == NST_ErrorHandlerSignal) || // Signal handler has already locked mutex
687+ (NdbMutex_Trylock (theShutdownMutex) == 0 )){
688+ globalData.theRestartFlag = perform_stop;
689+
690+ bool restart = false ;
691+
692+ if ((type != NST_Normal &&
693+ globalEmulatorData.theConfiguration ->stopOnError () == false ) ||
694+ type == NST_Restart)
695+ {
696+ restart = true ;
697+ }
698+
699+ const char * shutting = " shutting down" ;
700+ if (restart)
701+ {
702+ shutting = " restarting" ;
703+ }
704+
705+ switch (type){
706+ case NST_Normal:
707+ g_eventLogger->info (" Shutdown initiated" );
708+ break ;
709+ case NST_Watchdog:
710+ g_eventLogger->info (" Watchdog %s system" , shutting);
711+ break ;
712+ case NST_ErrorHandler:
713+ g_eventLogger->info (" Error handler %s system" , shutting);
714+ break ;
715+ case NST_ErrorHandlerSignal:
716+ g_eventLogger->info (" Error handler signal %s system" , shutting);
717+ break ;
718+ case NST_Restart:
719+ g_eventLogger->info (" Restarting system" );
720+ break ;
721+ default :
722+ g_eventLogger->info (" Error handler %s system (unknown type: %u)" ,
723+ shutting, (unsigned )type);
724+ type = NST_ErrorHandler;
725+ break ;
726+ }
727+
728+ const char * exitAbort = 0 ;
729+ #ifndef NDB_WIN
730+ if (opt_core)
731+ exitAbort = " aborting" ;
732+ else
733+ #endif
734+ exitAbort = " exiting" ;
735+
736+ if (type == NST_Watchdog)
737+ {
738+ /* *
739+ * Very serious, don't attempt to free, just die!!
740+ */
741+ g_eventLogger->info (" Watchdog shutdown completed - %s" , exitAbort);
742+ #ifndef NDB_WIN
743+ if (opt_core)
744+ {
745+ childAbort (error_code, -1 ,g_currentStartPhase);
746+ }
747+ else
748+ #endif
749+ {
750+ childExit (error_code, -1 ,g_currentStartPhase);
751+ }
752+ }
753+
754+ #ifndef NDB_WIN32
755+ if (simulate_error_during_shutdown)
756+ {
757+ kill (getpid (), simulate_error_during_shutdown);
758+ while (true )
759+ NdbSleep_MilliSleep (10 );
760+ }
761+ #endif
762+
763+ globalEmulatorData.theWatchDog ->doStop ();
764+
765+ #ifdef VM_TRACE
766+ FILE * outputStream = globalSignalLoggers.setOutputStream (0 );
767+ if (outputStream != 0 )
768+ fclose (outputStream);
769+ #endif
770+
771+ #ifndef NDB_WIN32
772+ #define UNLOAD (type == NST_ErrorInsert && opt_core)
773+ #else
774+ #define UNLOAD (0 )
775+ #endif
776+ /* *
777+ * Don't touch transporter here (yet)
778+ * cause with ndbmtd, there are locks and nasty stuff
779+ * and we don't know which we are holding...
780+ */
781+ #if NOT_YET
782+
783+ /* *
784+ * Stop all transporter connection attempts and accepts
785+ */
786+ globalEmulatorData.m_socket_server ->stopServer ();
787+ globalEmulatorData.m_socket_server ->stopSessions ();
788+ globalTransporterRegistry.stop_clients ();
789+
790+ /* *
791+ * Stop transporter communication with other nodes
792+ */
793+ globalTransporterRegistry.stopSending ();
794+ globalTransporterRegistry.stopReceiving ();
795+
796+ /* *
797+ * Remove all transporters
798+ */
799+ globalTransporterRegistry.removeAll ();
800+ #endif
801+
802+ if (UNLOAD)
803+ {
804+ globalEmulatorData.theSimBlockList ->unload ();
805+ NdbMutex_Unlock (theShutdownMutex);
806+ globalEmulatorData.destroy ();
807+ }
808+
809+ if (type != NST_Normal && type != NST_Restart)
810+ {
811+ g_eventLogger->info (" Error handler shutdown completed - %s" , exitAbort);
812+ #ifndef NDB_WIN
813+ if (opt_core)
814+ {
815+ childAbort (error_code, -1 ,g_currentStartPhase);
816+ }
817+ else
818+ #endif
819+ {
820+ childExit (error_code, -1 ,g_currentStartPhase);
821+ }
822+ }
823+
824+ /* *
825+ * This is a normal restart, depend on angel
826+ */
827+ if (type == NST_Restart){
828+ childExit (error_code, restartType,g_currentStartPhase);
829+ }
830+
831+ g_eventLogger->info (" Shutdown completed - exiting" );
832+ }
833+ else
834+ {
835+ /* *
836+ * Shutdown is already in progress
837+ */
838+
839+ /* *
840+ * If this is the watchdog, kill system the hard way
841+ */
842+ if (type== NST_Watchdog)
843+ {
844+ g_eventLogger->info (" Watchdog is killing system the hard way" );
845+ #if defined VM_TRACE
846+ childAbort (error_code, -1 ,g_currentStartPhase);
847+ #else
848+ childExit (error_code, -1 , g_currentStartPhase);
849+ #endif
850+ }
851+
852+ while (true )
853+ NdbSleep_MilliSleep (10 );
854+ }
855+ }
0 commit comments