diff --git a/myisam/mi_check.c b/myisam/mi_check.c index 246d2c58dde..038ce8d953f 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -3193,9 +3193,11 @@ int sort_write_record(MI_SORT_PARAM *sort_param) break; case COMPRESSED_RECORD: reclength=info->packed_length; - length=save_pack_length(block_buff,reclength); + length= save_pack_length((uint) share->pack.version, block_buff, + reclength); if (info->s->base.blobs) - length+=save_pack_length(block_buff+length,info->blob_length); + length+= save_pack_length((uint) share->pack.version, + block_buff + length, info->blob_length); if (my_b_write(&info->rec_cache,block_buff,length) || my_b_write(&info->rec_cache,(byte*) sort_param->rec_buff,reclength)) { diff --git a/myisam/mi_packrec.c b/myisam/mi_packrec.c index 1a71d43a7f1..322420b71db 100644 --- a/myisam/mi_packrec.c +++ b/myisam/mi_packrec.c @@ -149,11 +149,12 @@ my_bool _mi_read_pack_info(MI_INFO *info, pbool fix_keys) my_errno=HA_ERR_END_OF_FILE; goto err0; } - if (memcmp((byte*) header,(byte*) myisam_pack_file_magic,4)) + if (memcmp((byte*) header, (byte*) myisam_pack_file_magic, 3)) { my_errno=HA_ERR_WRONG_IN_RECORD; goto err0; } + share->pack.version= header[3]; share->pack.header_length= uint4korr(header+4); share->min_pack_length=(uint) uint4korr(header+8); share->max_pack_length=(uint) uint4korr(header+12); @@ -1040,38 +1041,12 @@ uint _mi_pack_get_block_info(MI_INFO *myisam, MI_BLOCK_INFO *info, File file, return BLOCK_FATAL_ERROR; DBUG_DUMP("header",(byte*) header,ref_length); } - if (header[0] < 254) - { - info->rec_len=header[0]; - head_length=1; - } - else if (header[0] == 254) - { - info->rec_len=uint2korr(header+1); - head_length=3; - } - else - { - info->rec_len=uint3korr(header+1); - head_length=4; - } + head_length= read_pack_length((uint) myisam->s->pack.version, header, + &info->rec_len); if (myisam->s->base.blobs) { - if (header[head_length] < 254) - { - info->blob_len=header[head_length]; - head_length++; - } - else if (header[head_length] == 254) - { - info->blob_len=uint2korr(header+head_length+1); - head_length+=3; - } - else - { - info->blob_len=uint3korr(header+head_length+1); - head_length+=4; - } + head_length+= read_pack_length((uint) myisam->s->pack.version, + header + head_length, &info->blob_len); if (!(mi_alloc_rec_buff(myisam,info->rec_len + info->blob_len, &myisam->rec_buff))) return BLOCK_FATAL_ERROR; /* not enough memory */ @@ -1220,34 +1195,12 @@ void _mi_unmap_file(MI_INFO *info) static uchar *_mi_mempack_get_block_info(MI_INFO *myisam,MI_BLOCK_INFO *info, uchar *header) { - if (header[0] < 254) - info->rec_len= *header++; - else if (header[0] == 254) - { - info->rec_len=uint2korr(header+1); - header+=3; - } - else - { - info->rec_len=uint3korr(header+1); - header+=4; - } + header+= read_pack_length((uint) myisam->s->pack.version, header, + &info->rec_len); if (myisam->s->base.blobs) { - if (header[0] < 254) - { - info->blob_len= *header++; - } - else if (header[0] == 254) - { - info->blob_len=uint2korr(header+1); - header+=3; - } - else - { - info->blob_len=uint3korr(header+1); - header+=4; - } + header+= read_pack_length((uint) myisam->s->pack.version, header, + &info->blob_len); /* mi_alloc_rec_buff sets my_errno on error */ if (!(mi_alloc_rec_buff(myisam, info->blob_len, &myisam->rec_buff))) @@ -1319,7 +1272,7 @@ static int _mi_read_rnd_mempack_record(MI_INFO *info, byte *buf, /* Save length of row */ -uint save_pack_length(byte *block_buff,ulong length) +uint save_pack_length(uint version, byte *block_buff, ulong length) { if (length < 254) { @@ -1333,6 +1286,46 @@ uint save_pack_length(byte *block_buff,ulong length) return 3; } *(uchar*) block_buff=255; - int3store(block_buff+1,(ulong) length); - return 4; + if (version == 1) /* old format */ + { + DBUG_ASSERT(length <= 0xFFFFFF); + int3store(block_buff + 1, (ulong) length); + return 4; + } + else + { + int4store(block_buff + 1, (ulong) length); + return 5; + } +} + + +uint read_pack_length(uint version, const uchar *buf, ulong *length) +{ + if (buf[0] < 254) + { + *length= buf[0]; + return 1; + } + else if (buf[0] == 254) + { + *length= uint2korr(buf + 1); + return 3; + } + if (version == 1) /* old format */ + { + *length= uint3korr(buf + 1); + return 4; + } + else + { + *length= uint4korr(buf + 1); + return 5; + } +} + + +uint calc_pack_length(uint version, ulong length) +{ + return (length < 254) ? 1 : (length < 65536) ? 3 : (version == 1) ? 4 : 5; } diff --git a/myisam/mi_static.c b/myisam/mi_static.c index f41aeff8453..9725c120f44 100644 --- a/myisam/mi_static.c +++ b/myisam/mi_static.c @@ -27,7 +27,7 @@ LIST *myisam_open_list=0; uchar NEAR myisam_file_magic[]= { (uchar) 254, (uchar) 254,'\007', '\001', }; uchar NEAR myisam_pack_file_magic[]= -{ (uchar) 254, (uchar) 254,'\010', '\001', }; +{ (uchar) 254, (uchar) 254,'\010', '\002', }; my_string myisam_log_filename=(char*) "myisam.log"; File myisam_log_file= -1; uint myisam_quick_table_bits=9; diff --git a/myisam/myisamdef.h b/myisam/myisamdef.h index a41bcf5449b..15b310e907e 100644 --- a/myisam/myisamdef.h +++ b/myisam/myisamdef.h @@ -149,6 +149,7 @@ typedef struct st_mi_blob /* Info of record */ typedef struct st_mi_isam_pack { ulong header_length; uint ref_length; + uchar version; } MI_PACK; @@ -669,7 +670,9 @@ extern void _myisam_log_record(enum myisam_log_commands command,MI_INFO *info, int result); extern my_bool _mi_memmap_file(MI_INFO *info); extern void _mi_unmap_file(MI_INFO *info); -extern uint save_pack_length(byte *block_buff,ulong length); +extern uint save_pack_length(uint version, byte *block_buff, ulong length); +extern uint read_pack_length(uint version, const uchar *buf, ulong *length); +extern uint calc_pack_length(uint version, ulong length); uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite); char *mi_state_info_read(char *ptr, MI_STATE_INFO *state); diff --git a/myisam/myisampack.c b/myisam/myisampack.c index c5db66ef209..f017e4d23ab 100644 --- a/myisam/myisampack.c +++ b/myisam/myisampack.c @@ -1675,6 +1675,7 @@ static int compress_isam_file(PACK_MRG_INFO *mrg, HUFF_COUNTS *huff_counts) HUFF_COUNTS *count,*end_count; HUFF_TREE *tree; MI_INFO *isam_file=mrg->file[0]; + uint pack_version= (uint) isam_file->s->pack.version; DBUG_ENTER("compress_isam_file"); if (!(record=(byte*) my_alloca(isam_file->s->base.reclength))) @@ -1702,23 +1703,10 @@ static int compress_isam_file(PACK_MRG_INFO *mrg, HUFF_COUNTS *huff_counts) huff_counts[i].tree->height+huff_counts[i].length_bits; } max_calc_length/=8; - if (max_calc_length < 254) - pack_ref_length=1; - else if (max_calc_length <= 65535) - pack_ref_length=3; - else - pack_ref_length=4; + pack_ref_length= calc_pack_length(pack_version, max_calc_length); record_count=0; - pack_blob_length=0; - if (isam_file->s->base.blobs) - { - if (mrg->max_blob_length < 254) - pack_blob_length=1; - else if (mrg->max_blob_length <= 65535) - pack_blob_length=3; - else - pack_blob_length=4; - } + pack_blob_length= isam_file->s->base.blobs ? + calc_pack_length(pack_version, mrg->max_blob_length) : 0; max_pack_length=pack_ref_length+pack_blob_length; mrg_reset(mrg); @@ -1874,9 +1862,10 @@ static int compress_isam_file(PACK_MRG_INFO *mrg, HUFF_COUNTS *huff_counts) } flush_bits(); length=(ulong) (file_buffer.pos-record_pos)-max_pack_length; - pack_length=save_pack_length(record_pos,length); + pack_length= save_pack_length(pack_version, record_pos, length); if (pack_blob_length) - pack_length+=save_pack_length(record_pos+pack_length,tot_blob_length); + pack_length+= save_pack_length(pack_version, record_pos + pack_length, + tot_blob_length); /* Correct file buffer if the header was smaller */ if (pack_length != max_pack_length) diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index a6c25fcd26c..12bc5ca2582 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -551,3 +551,12 @@ DROP TABLE t1,t2; select * from (select group_concat('c') from DUAL) t; group_concat('c') NULL +create table t1 ( a int not null default 0); +select * from (select group_concat(a) from t1) t2; +group_concat(a) +NULL +select group_concat('x') UNION ALL select 1; +group_concat('x') +NULL +1 +drop table t1; diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test index 827a2813718..9e003d19ab9 100644 --- a/mysql-test/t/func_gconcat.test +++ b/mysql-test/t/func_gconcat.test @@ -348,4 +348,12 @@ DROP TABLE t1,t2; # select * from (select group_concat('c') from DUAL) t; +# +# Bug #12859 group_concat in subquery cause incorrect not null +# +create table t1 ( a int not null default 0); +select * from (select group_concat(a) from t1) t2; +select group_concat('x') UNION ALL select 1; +drop table t1; + # End of 4.1 tests diff --git a/ndb/include/util/ndb_opts.h b/ndb/include/util/ndb_opts.h index ca4ca5eac83..462d9996582 100644 --- a/ndb/include/util/ndb_opts.h +++ b/ndb/include/util/ndb_opts.h @@ -30,8 +30,14 @@ my_bool opt_ndb_optimized_node_selection bool opt_endinfo= 0; my_bool opt_ndb_shm; +my_bool opt_core; #define OPT_NDB_CONNECTSTRING 'c' +#if defined VM_TRACE && ( ! ( defined NDB_OSE || defined NDB_SOFTOSE) ) +#define OPT_WANT_CORE_DEFAULT 1 +#else +#define OPT_WANT_CORE_DEFAULT 0 +#endif #define NDB_STD_OPTS_COMMON \ { "usage", '?', "Display this help and exit.", \ @@ -57,7 +63,10 @@ my_bool opt_ndb_shm; GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},\ { "connect-string", OPT_NDB_CONNECTSTRING, "same as --ndb-connectstring",\ (gptr*) &opt_connect_str, (gptr*) &opt_connect_str, 0,\ - GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 } + GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },\ + { "core-file", OPT_WANT_CORE, "Write core on errors.",\ + (gptr*) &opt_core, (gptr*) &opt_core, 0,\ + GET_BOOL, NO_ARG, OPT_WANT_CORE_DEFAULT, 0, 0, 0, 0, 0} #ifndef DBUG_OFF #define NDB_STD_OPTS(prog_name) \ @@ -80,6 +89,7 @@ enum ndb_std_options { OPT_NDB_SHM= 256, OPT_NDB_SHM_SIGNUM, OPT_NDB_OPTIMIZED_NODE_SELECTION, + OPT_WANT_CORE, NDB_STD_OPTIONS_LAST /* should always be last in this enum */ }; diff --git a/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp b/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp index 2e2c834ad9c..071a85c96da 100644 --- a/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp +++ b/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp @@ -2493,6 +2493,14 @@ void Ndbcntr::Missra::sendNextSTTOR(Signal* signal){ 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){ diff --git a/ndb/src/kernel/error/ErrorReporter.cpp b/ndb/src/kernel/error/ErrorReporter.cpp index e4ead4ce34d..25409db48a8 100644 --- a/ndb/src/kernel/error/ErrorReporter.cpp +++ b/ndb/src/kernel/error/ErrorReporter.cpp @@ -152,6 +152,14 @@ ErrorReporter::formatMessage(ErrorCategory type, return; } +NdbShutdownType ErrorReporter::s_errorHandlerShutdownType = NST_ErrorHandler; + +void +ErrorReporter::setErrorHandlerShutdownType(NdbShutdownType nst) +{ + s_errorHandlerShutdownType = nst; +} + void ErrorReporter::handleAssert(const char* message, const char* file, int line) { @@ -170,7 +178,7 @@ ErrorReporter::handleAssert(const char* message, const char* file, int line) WriteMessage(assert, ERR_ERROR_PRGERR, message, refMessage, theEmulatedJamIndex, theEmulatedJam); - NdbShutdown(NST_ErrorHandler); + NdbShutdown(s_errorHandlerShutdownType); } void @@ -182,7 +190,7 @@ ErrorReporter::handleThreadAssert(const char* message, BaseString::snprintf(refMessage, 100, "file: %s lineNo: %d - %s", file, line, message); - NdbShutdown(NST_ErrorHandler); + NdbShutdown(s_errorHandlerShutdownType); }//ErrorReporter::handleThreadAssert() @@ -201,6 +209,8 @@ ErrorReporter::handleError(ErrorCategory type, int messageID, if(messageID == ERR_ERROR_INSERT){ NdbShutdown(NST_ErrorInsert); } else { + if (nst == NST_ErrorHandler) + nst = s_errorHandlerShutdownType; NdbShutdown(nst); } } diff --git a/ndb/src/kernel/error/ErrorReporter.hpp b/ndb/src/kernel/error/ErrorReporter.hpp index 2c79f242eea..c5533df46f4 100644 --- a/ndb/src/kernel/error/ErrorReporter.hpp +++ b/ndb/src/kernel/error/ErrorReporter.hpp @@ -26,6 +26,7 @@ class ErrorReporter { public: + static void setErrorHandlerShutdownType(NdbShutdownType nst = NST_ErrorHandler); static void handleAssert(const char* message, const char* file, int line); @@ -57,6 +58,7 @@ public: static const char* formatTimeStampString(); private: + static enum NdbShutdownType s_errorHandlerShutdownType; }; #endif diff --git a/ndb/src/kernel/main.cpp b/ndb/src/kernel/main.cpp index 1cab3c96d19..aa220b0ae05 100644 --- a/ndb/src/kernel/main.cpp +++ b/ndb/src/kernel/main.cpp @@ -45,8 +45,14 @@ extern NdbMutex * theShutdownMutex; void catchsigs(bool ignore); // for process signal handling +#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; extern "C" void handler_shutdown(int signum); // for process signal handling extern "C" void handler_error(int signum); // for process signal handling +extern "C" void handler_sigusr1(int signum); // child signalling failed restart // Shows system information void systemInfo(const Configuration & conf, @@ -92,6 +98,8 @@ int main(int argc, char** argv) } #ifndef NDB_WIN32 + signal(SIGUSR1, handler_sigusr1); + for(pid_t child = fork(); child != 0; child = fork()){ /** * Parent @@ -137,6 +145,20 @@ int main(int argc, char** argv) */ exit(0); } + if (!failed_startup_flag) + { + // Reset the counter for consecutive failed startups + failed_startups = 0; + } + else if (failed_startups >= MAX_FAILED_STARTUPS && !theConfig->stopOnError()) + { + /** + * Error shutdown && stopOnError() + */ + g_eventLogger.alert("Ndbd has failed %u consecutive startups. Not restarting", failed_startups); + exit(0); + } + failed_startup_flag = false; g_eventLogger.info("Ndb has terminated (pid %d) restarting", child); theConfig->fetch_configuration(); } @@ -170,6 +192,9 @@ int main(int argc, char** argv) /** * Do startup */ + + ErrorReporter::setErrorHandlerShutdownType(NST_ErrorHandlerStartup); + switch(globalData.theRestartFlag){ case initial_state: globalEmulatorData.theThreadConfig->doStart(NodeState::SL_CMVMI); @@ -359,3 +384,15 @@ handler_error(int signum){ BaseString::snprintf(errorData, 40, "Signal %d received", signum); ERROR_SET_SIGNAL(fatal, 0, errorData, __FILE__); } + +extern "C" +void +handler_sigusr1(int signum) +{ + if (!failed_startup_flag) + { + failed_startups++; + failed_startup_flag = true; + } + g_eventLogger.info("Received signal %d. Ndbd failed startup (%u).", signum, failed_startups); +} diff --git a/ndb/src/kernel/vm/Emulator.cpp b/ndb/src/kernel/vm/Emulator.cpp index f52233fc276..058829e05e2 100644 --- a/ndb/src/kernel/vm/Emulator.cpp +++ b/ndb/src/kernel/vm/Emulator.cpp @@ -39,6 +39,7 @@ extern "C" { extern void (* ndb_new_handler)(); } extern EventLogger g_eventLogger; +extern my_bool opt_core; /** * Declare the global variables @@ -154,6 +155,9 @@ NdbShutdown(NdbShutdownType type, 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; @@ -165,23 +169,25 @@ NdbShutdown(NdbShutdownType type, } const char * exitAbort = 0; -#if defined VM_TRACE && ( ! ( defined NDB_OSE || defined NDB_SOFTOSE) ) - exitAbort = "aborting"; -#else - exitAbort = "exiting"; -#endif + 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 defined VM_TRACE && ( ! ( defined NDB_OSE || defined NDB_SOFTOSE) ) - signal(6, SIG_DFL); - abort(); -#else - exit(-1); -#endif + if (opt_core) + { + signal(6, SIG_DFL); + abort(); + } + else + { + exit(-1); + } } #ifndef NDB_WIN32 @@ -229,13 +235,19 @@ NdbShutdown(NdbShutdownType type, } if(type != NST_Normal && type != NST_Restart){ + // Signal parent that error occured during startup + if (type == NST_ErrorHandlerStartup) + kill(getppid(), SIGUSR1); g_eventLogger.info("Error handler shutdown completed - %s", exitAbort); -#if ( defined VM_TRACE || defined ERROR_INSERT ) && ( ! ( defined NDB_OSE || defined NDB_SOFTOSE) ) - signal(6, SIG_DFL); - abort(); -#else - exit(-1); -#endif + if (opt_core) + { + signal(6, SIG_DFL); + abort(); + } + else + { + exit(-1); + } } /** diff --git a/ndb/src/kernel/vm/Emulator.hpp b/ndb/src/kernel/vm/Emulator.hpp index dba8cb3ab9b..cd194202d85 100644 --- a/ndb/src/kernel/vm/Emulator.hpp +++ b/ndb/src/kernel/vm/Emulator.hpp @@ -83,7 +83,8 @@ enum NdbShutdownType { NST_ErrorHandler, NST_ErrorHandlerSignal, NST_Restart, - NST_ErrorInsert + NST_ErrorInsert, + NST_ErrorHandlerStartup }; enum NdbRestartType { diff --git a/ndb/src/mgmsrv/ConfigInfo.cpp b/ndb/src/mgmsrv/ConfigInfo.cpp index cface035174..36a72dcb975 100644 --- a/ndb/src/mgmsrv/ConfigInfo.cpp +++ b/ndb/src/mgmsrv/ConfigInfo.cpp @@ -25,6 +25,7 @@ #include extern my_bool opt_ndb_shm; +extern my_bool opt_core; #define MAX_LINE_LENGTH 255 #define KEY_INTERNAL 0 @@ -2140,11 +2141,10 @@ static void require(bool v) { if(!v) { -#ifndef DBUG_OFF - abort(); -#else - exit(-1); -#endif + if (opt_core) + abort(); + else + exit(-1); } } @@ -2214,7 +2214,7 @@ ConfigInfo::ConfigInfo() ndbout << "Error: Parameter " << param._fname << " defined twice in section " << param._section << "." << endl; - exit(-1); + require(false); } // Add new pinfo to section @@ -2264,7 +2264,7 @@ ConfigInfo::ConfigInfo() ndbout << "Check that each entry has a section failed." << endl; ndbout << "Parameter \"" << m_ParamInfo[i]._fname << endl; ndbout << "Edit file " << __FILE__ << "." << endl; - exit(-1); + require(false); } if(m_ParamInfo[i]._type == ConfigInfo::CI_SECTION) @@ -2277,7 +2277,7 @@ ConfigInfo::ConfigInfo() << "\" does not exist in section \"" << m_ParamInfo[i]._section << "\"." << endl; ndbout << "Edit file " << __FILE__ << "." << endl; - exit(-1); + require(false); } } } diff --git a/ndb/src/mgmsrv/MgmtSrvr.cpp b/ndb/src/mgmsrv/MgmtSrvr.cpp index 452dabc50e0..acab2ef9eac 100644 --- a/ndb/src/mgmsrv/MgmtSrvr.cpp +++ b/ndb/src/mgmsrv/MgmtSrvr.cpp @@ -65,6 +65,18 @@ extern int global_flag_send_heartbeat_now; extern int g_no_nodeid_checks; +extern my_bool opt_core; + +static void require(bool v) +{ + if(!v) + { + if (opt_core) + abort(); + else + exit(-1); + } +} void * MgmtSrvr::logLevelThread_C(void* m) @@ -436,14 +448,14 @@ MgmtSrvr::MgmtSrvr(SocketServer *socket_server, if (tmp_nodeid == 0) { ndbout_c(m_config_retriever->getErrorString()); - exit(-1); + require(false); } // read config from other managent server _config= fetchConfig(); if (_config == 0) { ndbout << m_config_retriever->getErrorString() << endl; - exit(-1); + require(false); } _ownNodeId= tmp_nodeid; } @@ -454,7 +466,7 @@ MgmtSrvr::MgmtSrvr(SocketServer *socket_server, _config= readConfig(); if (_config == 0) { ndbout << "Unable to read config file" << endl; - exit(-1); + require(false); } } @@ -511,7 +523,7 @@ MgmtSrvr::MgmtSrvr(SocketServer *socket_server, if ((m_node_id_mutex = NdbMutex_Create()) == 0) { ndbout << "mutex creation failed line = " << __LINE__ << endl; - exit(-1); + require(false); } if (_ownNodeId == 0) // we did not get node id from other server @@ -522,7 +534,7 @@ MgmtSrvr::MgmtSrvr(SocketServer *socket_server, 0, 0, error_string)){ ndbout << "Unable to obtain requested nodeid: " << error_string.c_str() << endl; - exit(-1); + require(false); } _ownNodeId = tmp; } @@ -533,7 +545,7 @@ MgmtSrvr::MgmtSrvr(SocketServer *socket_server, _ownNodeId)) { ndbout << m_config_retriever->getErrorString() << endl; - exit(-1); + require(false); } } @@ -2203,18 +2215,18 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId, iter(*(ndb_mgm_configuration *)_config->m_configValues, CFG_SECTION_NODE); for(iter.first(); iter.valid(); iter.next()) { unsigned tmp= 0; - if(iter.get(CFG_NODE_ID, &tmp)) abort(); + if(iter.get(CFG_NODE_ID, &tmp)) require(false); if (*nodeId && *nodeId != tmp) continue; found_matching_id= true; - if(iter.get(CFG_TYPE_OF_SECTION, &type_c)) abort(); + if(iter.get(CFG_TYPE_OF_SECTION, &type_c)) require(false); if(type_c != (unsigned)type) continue; found_matching_type= true; if (connected_nodes.get(tmp)) continue; found_free_node= true; - if(iter.get(CFG_NODE_HOST, &config_hostname)) abort(); + if(iter.get(CFG_NODE_HOST, &config_hostname)) require(false); if (config_hostname && config_hostname[0] == 0) config_hostname= 0; else if (client_addr) { @@ -2561,7 +2573,7 @@ MgmtSrvr::backupCallback(BackupEvent & event) int MgmtSrvr::repCommand(Uint32* repReqId, Uint32 request, bool waitCompleted) { - abort(); + require(false); return 0; } @@ -2715,7 +2727,7 @@ MgmtSrvr::setDbParameter(int node, int param, const char * value, ndbout_c("Updating node %d param: %d to %s", node, param, val_char); break; default: - abort(); + require(false); } assert(res); } while(node == 0 && iter.next() == 0); diff --git a/ndb/src/mgmsrv/Services.cpp b/ndb/src/mgmsrv/Services.cpp index 00cf6390c73..46bfb531b61 100644 --- a/ndb/src/mgmsrv/Services.cpp +++ b/ndb/src/mgmsrv/Services.cpp @@ -343,8 +343,6 @@ MgmApiSession::getConfig_old(Parser_t::Context &ctx) { } #endif /* MGM_GET_CONFIG_BACKWARDS_COMPAT */ -inline void require(bool b){ if(!b) abort(); } - void MgmApiSession::getConfig(Parser_t::Context &ctx, const class Properties &args) { diff --git a/ndb/tools/Makefile.am b/ndb/tools/Makefile.am index 89830129576..795441380a8 100644 --- a/ndb/tools/Makefile.am +++ b/ndb/tools/Makefile.am @@ -30,7 +30,7 @@ ndb_restore_SOURCES = restore/restore_main.cpp \ restore/consumer.cpp \ restore/consumer_restore.cpp \ restore/consumer_printer.cpp \ - restore/Restore.cpp + restore/Restore.cpp $(tools_common_sources) ndb_config_SOURCES = ndb_config.cpp \ ../src/mgmsrv/Config.cpp \ diff --git a/ndb/tools/ndb_config.cpp b/ndb/tools/ndb_config.cpp index d188aec1337..725249a5af5 100644 --- a/ndb/tools/ndb_config.cpp +++ b/ndb/tools/ndb_config.cpp @@ -42,6 +42,7 @@ static const char * g_field_delimiter=","; static const char * g_row_delimiter=" "; int g_print_full_config, opt_ndb_shm; +my_bool opt_core; typedef ndb_mgm_configuration_iterator Iter; diff --git a/ndb/tools/restore/consumer_restore.cpp b/ndb/tools/restore/consumer_restore.cpp index d782a561e6a..70ea7460d78 100644 --- a/ndb/tools/restore/consumer_restore.cpp +++ b/ndb/tools/restore/consumer_restore.cpp @@ -14,9 +14,12 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include #include "consumer_restore.hpp" #include +extern my_bool opt_core; + extern FilteredNdbOut err; extern FilteredNdbOut info; extern FilteredNdbOut debug; @@ -458,7 +461,11 @@ bool BackupRestore::errorHandler(restore_callback_t *cb) void BackupRestore::exitHandler() { release(); - exit(-1); + NDBT_ProgramExit(NDBT_FAILED); + if (opt_core) + abort(); + else + exit(NDBT_FAILED); } @@ -492,7 +499,7 @@ BackupRestore::logEntry(const LogEntry & tup) { // Deep shit, TODO: handle the error err << "Cannot start transaction" << endl; - exit(-1); + exitHandler(); } // if const NdbDictionary::Table * table = get_table(tup.m_table->m_dictTable); @@ -500,7 +507,7 @@ BackupRestore::logEntry(const LogEntry & tup) if (op == NULL) { err << "Cannot get operation: " << trans->getNdbError() << endl; - exit(-1); + exitHandler(); } // if int check = 0; @@ -518,13 +525,13 @@ BackupRestore::logEntry(const LogEntry & tup) default: err << "Log entry has wrong operation type." << " Exiting..."; - exit(-1); + exitHandler(); } if (check != 0) { err << "Error defining op: " << trans->getNdbError() << endl; - exit(-1); + exitHandler(); } // if Bitmask<4096> keys; @@ -553,7 +560,7 @@ BackupRestore::logEntry(const LogEntry & tup) if (check != 0) { err << "Error defining op: " << trans->getNdbError() << endl; - exit(-1); + exitHandler(); } // if } @@ -582,7 +589,7 @@ BackupRestore::logEntry(const LogEntry & tup) if (!ok) { err << "execute failed: " << errobj << endl; - exit(-1); + exitHandler(); } } @@ -629,7 +636,7 @@ BackupRestore::tuple(const TupleS & tup) { // Deep shit, TODO: handle the error ndbout << "Cannot start transaction" << endl; - exit(-1); + exitHandler(); } // if const TableS * table = tup.getTable(); @@ -638,7 +645,7 @@ BackupRestore::tuple(const TupleS & tup) { ndbout << "Cannot get operation: "; ndbout << trans->getNdbError() << endl; - exit(-1); + exitHandler(); } // if // TODO: check return value and handle error @@ -646,7 +653,7 @@ BackupRestore::tuple(const TupleS & tup) { ndbout << "writeTuple call failed: "; ndbout << trans->getNdbError() << endl; - exit(-1); + exitHandler(); } // if for (int i = 0; i < tup.getNoOfAttributes(); i++) @@ -680,7 +687,7 @@ BackupRestore::tuple(const TupleS & tup) { ndbout << "execute failed: "; ndbout << trans->getNdbError() << endl; - exit(-1); + exitHandler(); } m_ndb->closeTransaction(trans); if (ret == 0) diff --git a/ndb/tools/restore/restore_main.cpp b/ndb/tools/restore/restore_main.cpp index 0c4419bb072..d786dffe89e 100644 --- a/ndb/tools/restore/restore_main.cpp +++ b/ndb/tools/restore/restore_main.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include "consumer_restore.hpp" #include "consumer_printer.hpp" @@ -116,14 +117,14 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), if (ga_nodeId == 0) { printf("Error in --nodeid,-n setting, see --help\n"); - exit(1); + exit(NDBT_ProgramExit(NDBT_WRONGARGS)); } break; case 'b': if (ga_backupId == 0) { printf("Error in --backupid,-b setting, see --help\n"); - exit(1); + exit(NDBT_ProgramExit(NDBT_WRONGARGS)); } break; } @@ -136,7 +137,7 @@ readArguments(int *pargc, char*** pargv) load_defaults("my",load_default_groups,pargc,pargv); if (handle_options(pargc, pargv, my_long_options, get_one_option)) { - exit(1); + exit(NDBT_ProgramExit(NDBT_WRONGARGS)); } BackupPrinter* printer = new BackupPrinter(); @@ -226,6 +227,15 @@ free_data_callback() g_consumers[i]->tuple_free(); } +static void exitHandler(int code) +{ + NDBT_ProgramExit(code); + if (opt_core) + abort(); + else + exit(code); +} + int main(int argc, char** argv) { @@ -233,7 +243,7 @@ main(int argc, char** argv) if (!readArguments(&argc, &argv)) { - return -1; + exitHandler(NDBT_FAILED); } Ndb::setConnectString(opt_connect_str); @@ -245,7 +255,7 @@ main(int argc, char** argv) if (!metaData.readHeader()) { ndbout << "Failed to read " << metaData.getFilename() << endl << endl; - return -1; + exitHandler(NDBT_FAILED); } const BackupFormat::FileHeader & tmp = metaData.getFileHeader(); @@ -263,20 +273,20 @@ main(int argc, char** argv) if (res == 0) { ndbout_c("Restore: Failed to load content"); - return -1; + exitHandler(NDBT_FAILED); } if (metaData.getNoOfTables() == 0) { ndbout_c("Restore: The backup contains no tables "); - return -1; + exitHandler(NDBT_FAILED); } if (!metaData.validateFooter()) { ndbout_c("Restore: Failed to validate footer."); - return -1; + exitHandler(NDBT_FAILED); } Uint32 i; @@ -285,7 +295,7 @@ main(int argc, char** argv) if (!g_consumers[i]->init()) { clearConsumers(); - return -11; + exitHandler(NDBT_FAILED); } } @@ -300,7 +310,7 @@ main(int argc, char** argv) ndbout_c("Restore: Failed to restore table: %s. " "Exiting...", metaData[i]->getTableName()); - return -11; + exitHandler(NDBT_FAILED); } } } @@ -309,7 +319,7 @@ main(int argc, char** argv) if (!g_consumers[i]->endOfTables()) { ndbout_c("Restore: Failed while closing tables"); - return -11; + exitHandler(NDBT_FAILED); } if (ga_restore || ga_print) @@ -322,7 +332,7 @@ main(int argc, char** argv) if (!dataIter.readHeader()) { ndbout << "Failed to read header of data file. Exiting..." ; - return -11; + exitHandler(NDBT_FAILED); } @@ -340,12 +350,12 @@ main(int argc, char** argv) { ndbout_c("Restore: An error occured while restoring data. " "Exiting..."); - return -1; + exitHandler(NDBT_FAILED); } if (!dataIter.validateFragmentFooter()) { ndbout_c("Restore: Error validating fragment footer. " "Exiting..."); - return -1; + exitHandler(NDBT_FAILED); } } // while (dataIter.readFragmentHeader(res)) @@ -353,7 +363,7 @@ main(int argc, char** argv) { err << "Restore: An error occured while restoring data. Exiting... " << "res=" << res << endl; - return -1; + exitHandler(NDBT_FAILED); } @@ -366,7 +376,7 @@ main(int argc, char** argv) if (!logIter.readHeader()) { err << "Failed to read header of data file. Exiting..." << endl; - return -1; + exitHandler(NDBT_FAILED); } const LogEntry * logEntry = 0; @@ -380,7 +390,7 @@ main(int argc, char** argv) { err << "Restore: An restoring the data log. Exiting... res=" << res << endl; - return -1; + exitHandler(NDBT_FAILED); } logIter.validateFooter(); //not implemented for (i= 0; i < g_consumers.size(); i++) @@ -395,14 +405,14 @@ main(int argc, char** argv) ndbout_c("Restore: Failed to finalize restore table: %s. " "Exiting...", metaData[i]->getTableName()); - return -11; + exitHandler(NDBT_FAILED); } } } } } clearConsumers(); - return 0; + return NDBT_ProgramExit(NDBT_OK); } // main template class Vector;