diff --git a/innobase/include/srv0start.h b/innobase/include/srv0start.h index c4c8dac5d7a..539ccb32744 100644 --- a/innobase/include/srv0start.h +++ b/innobase/include/srv0start.h @@ -63,11 +63,13 @@ innobase_start_or_create_for_mysql(void); /* out: DB_SUCCESS or error code */ /******************************************************************** Shuts down the Innobase database. */ - int innobase_shutdown_for_mysql(void); /*=============================*/ /* out: DB_SUCCESS or error code */ +#ifdef __NETWARE__ +void set_panic_flag_for_netware(void); +#endif extern ulint srv_sizeof_trx_t_in_ha_innodb_cc; diff --git a/innobase/include/ut0dbg.h b/innobase/include/ut0dbg.h index bec9cdd42b5..fe6aba2cccb 100644 --- a/innobase/include/ut0dbg.h +++ b/innobase/include/ut0dbg.h @@ -22,7 +22,38 @@ extern ulint* ut_dbg_null_ptr; extern const char* ut_dbg_msg_assert_fail; extern const char* ut_dbg_msg_trap; extern const char* ut_dbg_msg_stop; - +/* Have a graceful exit on NetWare rather than a segfault to avoid abends */ +#ifdef __NETWARE__ +extern ibool panic_shutdown; +#define ut_a(EXPR) do {\ + if (!((ulint)(EXPR) + ut_dbg_zero)) {\ + ut_print_timestamp(stderr);\ + fprintf(stderr, ut_dbg_msg_assert_fail,\ + os_thread_pf(os_thread_get_curr_id()), __FILE__,\ + (ulint)__LINE__);\ + fputs("InnoDB: Failing assertion: " #EXPR "\n", stderr);\ + fputs(ut_dbg_msg_trap, stderr);\ + ut_dbg_stop_threads = TRUE;\ + if (ut_dbg_stop_threads) {\ + fprintf(stderr, ut_dbg_msg_stop,\ + os_thread_pf(os_thread_get_curr_id()), __FILE__, (ulint)__LINE__);\ + }\ + if(!panic_shutdown){\ + panic_shutdown = TRUE;\ + innobase_shutdown_for_mysql();}\ + exit(1);\ + }\ +} while (0) +#define ut_error do {\ + ut_print_timestamp(stderr);\ + fprintf(stderr, ut_dbg_msg_assert_fail,\ + os_thread_pf(os_thread_get_curr_id()), __FILE__, (ulint)__LINE__);\ + fprintf(stderr, ut_dbg_msg_trap);\ + ut_dbg_stop_threads = TRUE;\ + if(!panic_shutdown){panic_shutdown = TRUE;\ + innobase_shutdown_for_mysql();}\ +} while (0) +#else #define ut_a(EXPR) do {\ if (!((ulint)(EXPR) + ut_dbg_zero)) {\ ut_print_timestamp(stderr);\ @@ -49,6 +80,7 @@ extern const char* ut_dbg_msg_stop; ut_dbg_stop_threads = TRUE;\ if (*(ut_dbg_null_ptr)) ut_dbg_null_ptr = NULL;\ } while (0) +#endif #ifdef UNIV_DEBUG # define ut_ad(EXPR) ut_a(EXPR) diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c index 30c9982068e..9baa86234a0 100644 --- a/innobase/srv/srv0start.c +++ b/innobase/srv/srv0start.c @@ -1079,6 +1079,7 @@ NetWare. */ for (i = 0; i < srv_n_file_io_threads; i++) { n[i] = i; + os_thread_create(io_handler_thread, n + i, thread_ids + i); } @@ -1440,7 +1441,6 @@ NetWare. */ } fflush(stderr); - return((int) DB_SUCCESS); } @@ -1453,7 +1453,9 @@ innobase_shutdown_for_mysql(void) /* out: DB_SUCCESS or error code */ { ulint i; - +#ifdef __NETWARE__ + extern ibool panic_shutdown; +#endif if (!srv_was_started) { if (srv_is_being_started) { ut_print_timestamp(stderr); @@ -1471,8 +1473,11 @@ innobase_shutdown_for_mysql(void) The step 1 is the real InnoDB shutdown. The remaining steps just free data structures after the shutdown. */ +#ifdef __NETWARE__ + if(!panic_shutdown) +#endif logs_empty_and_mark_files_at_shutdown(); - + if (srv_conc_n_threads != 0) { fprintf(stderr, "InnoDB: Warning: query counter shows %ld queries still\n" @@ -1540,12 +1545,11 @@ innobase_shutdown_for_mysql(void) mem_free(srv_monitor_file_name); } } - + mutex_free(&srv_monitor_file_mutex); /* 3. Free all InnoDB's own mutexes and the os_fast_mutexes inside them */ - sync_close(); /* 4. Free the os_conc_mutex and all os_events and os_mutexes */ @@ -1556,7 +1560,7 @@ innobase_shutdown_for_mysql(void) /* 5. Free all allocated memory and the os_fast_mutex created in ut0mem.c */ - ut_free_all_mem(); + ut_free_all_mem(); if (os_thread_count != 0 || os_event_count != 0 @@ -1583,3 +1587,11 @@ innobase_shutdown_for_mysql(void) return((int) DB_SUCCESS); } + +#ifdef __NETWARE__ +void set_panic_flag_for_netware() +{ + extern ibool panic_shutdown; + panic_shutdown = TRUE; +} +#endif diff --git a/innobase/ut/ut0dbg.c b/innobase/ut/ut0dbg.c index 65703ec1c86..2a0cfe1f13a 100644 --- a/innobase/ut/ut0dbg.c +++ b/innobase/ut/ut0dbg.c @@ -14,7 +14,12 @@ ulint ut_dbg_zero = 0; /* If this is set to TRUE all threads will stop into the next assertion and assert */ ibool ut_dbg_stop_threads = FALSE; - +#ifdef __NETWARE__ +ibool panic_shutdown = FALSE; /* This is set to TRUE when on NetWare there + happens an InnoDB assertion failure or other + fatal error condition that requires an + immediate shutdown. */ +#endif /* Null pointer used to generate memory trap */ ulint* ut_dbg_null_ptr = NULL; diff --git a/innobase/ut/ut0mem.c b/innobase/ut/ut0mem.c index 2cab36a9580..9b08b1e79aa 100644 --- a/innobase/ut/ut0mem.c +++ b/innobase/ut/ut0mem.c @@ -106,7 +106,13 @@ ut_malloc_low( /* Make an intentional seg fault so that we get a stack trace */ + /* Intentional segfault on NetWare causes an abend. Avoid this + by graceful exit handling in ut_a(). */ +#if (!defined __NETWARE__) if (*ut_mem_null_ptr) ut_mem_null_ptr = 0; +#else + ut_a(0); +#endif } if (set_to_zero) { diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index f233dd5a5c5..22ddfe779d5 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -121,6 +121,10 @@ char innodb_dummy_stmt_trx_handle = 'D'; static HASH innobase_open_tables; +#ifdef __NETWARE__ /* some special cleanup for NetWare */ +bool nw_panic = FALSE; +#endif + static mysql_byte* innobase_get_key(INNOBASE_SHARE *share,uint *length, my_bool not_used __attribute__((unused))); static INNOBASE_SHARE *get_share(const char *table_name); @@ -950,6 +954,11 @@ innobase_end(void) DBUG_ENTER("innobase_end"); +#ifdef __NETWARE__ /* some special cleanup for NetWare */ + if (nw_panic) { + set_panic_flag_for_netware(); + } +#endif err = innobase_shutdown_for_mysql(); hash_free(&innobase_open_tables); my_free(internal_innobase_data_file_path,MYF(MY_ALLOW_ZERO_PTR)); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 8f08099f340..e4d60fc9e7c 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1547,6 +1547,8 @@ void registerwithneb() ulong neb_event_callback(struct EventBlock *eblock) { EventChangeVolStateEnter_s *voldata; + extern bool nw_panic; + voldata= (EventChangeVolStateEnter_s *)eblock->EBEventData; /* Deactivation of a volume */ @@ -1559,6 +1561,7 @@ ulong neb_event_callback(struct EventBlock *eblock) if (!memcmp(&voldata->volID, &datavolid, sizeof(VolumeID_t))) { consoleprintf("MySQL data volume is deactivated, shutting down MySQL Server \n"); + nw_panic = TRUE; kill_server(0); } }