revision-id: 02b2f9687f9d464ba5e5711ae16104b9f901bc9f (mariadb-10.2.24-1-g02b2f96) parent(s): e0271a7b43c6df652c6a074858853a6d0da20c1e committer: Alexey Botchkov timestamp: 2019-05-23 01:33:36 +0400 message: Custom build. --- VERSION | 2 +- plugin/server_audit/server_audit.c | 108 ++++++++++------- sql/sql_audit.cc | 243 ++++++++++++++++++++++++++++++++++++- sql/sql_plugin.cc | 28 ++--- sql/sql_plugin.h | 2 +- 5 files changed, 322 insertions(+), 61 deletions(-) diff --git a/VERSION b/VERSION index 65e6c5d..bc05255 100644 --- a/VERSION +++ b/VERSION @@ -1,3 +1,3 @@ MYSQL_VERSION_MAJOR=10 MYSQL_VERSION_MINOR=2 -MYSQL_VERSION_PATCH=24 +MYSQL_VERSION_PATCH=240 diff --git a/plugin/server_audit/server_audit.c b/plugin/server_audit/server_audit.c index 4e8c7ad..8ca32e9 100644 --- a/plugin/server_audit/server_audit.c +++ b/plugin/server_audit/server_audit.c @@ -15,7 +15,7 @@ #define PLUGIN_VERSION 0x104 -#define PLUGIN_STR_VERSION "1.4.5" +#define PLUGIN_STR_VERSION "1.4.W" #define _my_thread_var loc_thread_var @@ -292,7 +292,7 @@ static unsigned long long file_rotate_size; static unsigned int rotations; static my_bool rotate= TRUE; static char logging; -static int internal_stop_logging= 0; +static volatile int internal_stop_logging= 0; static char incl_user_buffer[1024]; static char excl_user_buffer[1024]; static char *big_buffer= NULL; @@ -534,16 +534,20 @@ static struct st_mysql_show_var audit_status[]= #if defined(HAVE_PSI_INTERFACE) && !defined(FLOGGER_NO_PSI) /* These belong to the service initialization */ static PSI_mutex_key key_LOCK_operations; +static PSI_mutex_key key_LOCK_atomic`; static PSI_mutex_key key_LOCK_bigbuffer; static PSI_mutex_info mutex_key_list[]= { { &key_LOCK_operations, "SERVER_AUDIT_plugin::lock_operations", PSI_FLAG_GLOBAL}, + { &key_LOCK_atomic, "SERVER_AUDIT_plugin::lock_atomic", + PSI_FLAG_GLOBAL}, { &key_LOCK_bigbuffer, "SERVER_AUDIT_plugin::lock_bigbuffer", PSI_FLAG_GLOBAL} }; #endif static mysql_mutex_t lock_operations; +static mysql_mutex_t lock_atomic; static mysql_mutex_t lock_bigbuffer; /* The Percona server and partly MySQL don't support */ @@ -554,6 +558,13 @@ static mysql_mutex_t lock_bigbuffer; /* worths doing. */ #define CLIENT_ERROR if (!started_mysql) my_printf_error +#define ADD_ATOMIC(x, a) \ + do { \ + flogger_mutex_lock(&lock_atomic); \ + x+= a; \ + flogger_mutex_unlock(&lock_atomic); \ + } while (0) + static uchar *getkey_user(const char *entry, size_t *length, my_bool nu __attribute__((unused)) ) { @@ -732,20 +743,20 @@ static int user_coll_fill(struct user_coll *c, char *users, if (cmp_user && take_over_cmp) { - internal_stop_logging= 1; + ADD_ATOMIC(internal_stop_logging, 1); CLIENT_ERROR(1, "User '%.*s' was removed from the" " server_audit_excl_users.", MYF(ME_JUST_WARNING), (int) cmp_length, users); - internal_stop_logging= 0; + ADD_ATOMIC(internal_stop_logging, -1); blank_user(cmp_user); refill_cmp_coll= 1; } else if (cmp_user) { - internal_stop_logging= 1; + ADD_ATOMIC(internal_stop_logging, 1); CLIENT_ERROR(1, "User '%.*s' is in the server_audit_incl_users, " "so wasn't added.", MYF(ME_JUST_WARNING), (int) cmp_length, users); - internal_stop_logging= 0; + ADD_ATOMIC(internal_stop_logging, -1); remove_user(users); continue; } @@ -1253,15 +1264,19 @@ static void change_connection(struct connection_info *cn, event->ip, event->ip_length); } -static int write_log(const char *message, size_t len) +static int write_log(const char *message, size_t len, int take_lock) { + int result= 0; + if (take_lock) + flogger_mutex_lock(&lock_operations); if (output_type == OUTPUT_FILE) { if (logfile && (is_active= (logger_write(logfile, message, len) == (int)len))) - return 0; + goto exit; + ++log_write_failures; - return 1; + result= 1; } else if (output_type == OUTPUT_SYSLOG) { @@ -1269,7 +1284,10 @@ static int write_log(const char *message, size_t len) syslog_priority_codes[syslog_priority], "%s %.*s", syslog_info, (int)len, message); } - return 0; +exit: + if (take_lock) + flogger_mutex_unlock(&lock_operations); + return result; } @@ -1328,7 +1346,7 @@ static int log_connection(const struct connection_info *cn, csize+= my_snprintf(message+csize, sizeof(message) - 1 - csize, ",%.*s,,%d", cn->db_length, cn->db, event->status); message[csize]= '\n'; - return write_log(message, csize + 1); + return write_log(message, csize + 1, 1); } @@ -1349,7 +1367,7 @@ static int log_connection_event(const struct mysql_event_connection *event, csize+= my_snprintf(message+csize, sizeof(message) - 1 - csize, ",%.*s,,%d", event->database_length, event->database, event->status); message[csize]= '\n'; - return write_log(message, csize + 1); + return write_log(message, csize + 1, 1); } @@ -1478,21 +1496,28 @@ static size_t escape_string_hide_passwords(const char *str, unsigned int len, -static int do_log_user(const char *name) +static int do_log_user(const char *name, int take_lock) { size_t len; + int result; if (!name) return 0; len= strlen(name); - if (incl_user_coll.n_users) - return coll_search(&incl_user_coll, name, len) != 0; + if (take_lock) + flogger_mutex_lock(&lock_operations); - if (excl_user_coll.n_users) - return coll_search(&excl_user_coll, name, len) == 0; + if (incl_user_coll.n_users) + result= coll_search(&incl_user_coll, name, len) != 0; + else if (excl_user_coll.n_users) + result= coll_search(&excl_user_coll, name, len) == 0; + else + result= 1; - return 1; + if (take_lock) + flogger_mutex_unlock(&lock_operations); + return result; } @@ -1589,7 +1614,7 @@ static int filter_query_type(const char *query, struct sa_keyword *kwd) static int log_statement_ex(const struct connection_info *cn, time_t ev_time, unsigned long thd_id, const char *query, unsigned int query_len, - int error_code, const char *type) + int error_code, const char *type, int take_lock) { size_t csize; char message_loc[1024]; @@ -1737,7 +1762,7 @@ static int log_statement_ex(const struct connection_info *cn, csize+= my_snprintf(message+csize, message_size - 1 - csize, "\',%d", error_code); message[csize]= '\n'; - result= write_log(message, csize + 1); + result= write_log(message, csize + 1, take_lock); if (message == big_buffer) flogger_mutex_unlock(&lock_bigbuffer); @@ -1751,7 +1776,7 @@ static int log_statement(const struct connection_info *cn, { return log_statement_ex(cn, event->general_time, event->general_thread_id, event->general_query, event->general_query_length, - event->general_error_code, type); + event->general_error_code, type, 1); } @@ -1773,7 +1798,7 @@ static int log_table(const struct connection_info *cn, ",%.*s,%.*s,",event->database_length, event->database, event->table_length, event->table); message[csize]= '\n'; - return write_log(message, csize + 1); + return write_log(message, csize + 1, 1); } @@ -1797,7 +1822,7 @@ static int log_rename(const struct connection_info *cn, event->new_database_length, event->new_database, event->new_table_length, event->new_table); message[csize]= '\n'; - return write_log(message, csize + 1); + return write_log(message, csize + 1, 1); } @@ -1989,8 +2014,6 @@ void auditing(MYSQL_THD thd, unsigned int event_class, const void *ev) if (!thd || internal_stop_logging) return; - flogger_mutex_lock(&lock_operations); - if (maria_55_started && debug_server_started && event_class == MYSQL_AUDIT_GENERAL_CLASS) { @@ -2025,7 +2048,7 @@ void auditing(MYSQL_THD thd, unsigned int event_class, const void *ev) goto exit_func; if (event_class == MYSQL_AUDIT_GENERAL_CLASS && FILTER(EVENT_QUERY) && - cn && do_log_user(cn->user)) + cn && do_log_user(cn->user, 1)) { const struct mysql_event_general *event = (const struct mysql_event_general *) ev; @@ -2044,7 +2067,7 @@ void auditing(MYSQL_THD thd, unsigned int event_class, const void *ev) { const struct mysql_event_table *event = (const struct mysql_event_table *) ev; - if (do_log_user(event->user)) + if (do_log_user(event->user, 1)) { switch (event->event_subclass) { @@ -2110,7 +2133,6 @@ void auditing(MYSQL_THD thd, unsigned int event_class, const void *ev) } if (cn) cn->log_always= 0; - flogger_mutex_unlock(&lock_operations); } @@ -2378,6 +2400,7 @@ static int server_audit_init(void *p __attribute__((unused))) PSI_server->register_mutex("server_audit", mutex_key_list, 1); #endif flogger_mutex_init(key_LOCK_operations, &lock_operations, MY_MUTEX_INIT_FAST); + flogger_mutex_init(key_LOCK_operations, &lock_atomic, MY_MUTEX_INIT_FAST); flogger_mutex_init(key_LOCK_operations, &lock_bigbuffer, MY_MUTEX_INIT_FAST); coll_init(&incl_user_coll); @@ -2465,6 +2488,7 @@ static int server_audit_deinit(void *p __attribute__((unused))) (void) free(big_buffer); flogger_mutex_destroy(&lock_operations); + flogger_mutex_destroy(&lock_atomic); flogger_mutex_destroy(&lock_bigbuffer); error_header(); @@ -2554,11 +2578,11 @@ static void log_current_query(MYSQL_THD thd) return; cn= get_loc_info(thd); if (!ci_needs_setup(cn) && cn->query_length && - FILTER(EVENT_QUERY) && do_log_user(cn->user)) + FILTER(EVENT_QUERY) && do_log_user(cn->user, 0)) { cn->log_always= 1; log_statement_ex(cn, cn->query_time, thd_get_thread_id(thd), - cn->query, cn->query_length, 0, "QUERY"); + cn->query, cn->query_length, 0, "QUERY", 0); cn->log_always= 0; } } @@ -2570,21 +2594,22 @@ static void update_file_path(MYSQL_THD thd, { char *new_name= (*(char **) save) ? *(char **) save : empty_str; - if (!maria_55_started || !debug_server_started) - flogger_mutex_lock(&lock_operations); - internal_stop_logging= 1; + ADD_ATOMIC(internal_stop_logging, 1); error_header(); fprintf(stderr, "Log file name was changed to '%s'.\n", new_name); + if (!maria_55_started || !debug_server_started) + flogger_mutex_lock(&lock_operations); + if (logging) log_current_query(thd); + if (logging && output_type == OUTPUT_FILE) { char *sav_path= file_path; file_path= new_name; - internal_stop_logging= 1; stop_logging(); if (start_logging()) { @@ -2600,16 +2625,15 @@ static void update_file_path(MYSQL_THD thd, } goto exit_func; } - internal_stop_logging= 0; } strncpy(path_buffer, new_name, sizeof(path_buffer)-1); path_buffer[sizeof(path_buffer)-1]= 0; file_path= path_buffer; exit_func: - internal_stop_logging= 0; if (!maria_55_started || !debug_server_started) flogger_mutex_unlock(&lock_operations); + ADD_ATOMIC(internal_stop_logging, -1); } @@ -2740,8 +2764,8 @@ static void update_output_type(MYSQL_THD thd, if (output_type == new_output_type) return; + ADD_ATOMIC(internal_stop_logging, 1); flogger_mutex_lock(&lock_operations); - internal_stop_logging= 1; if (logging) { log_current_query(thd); @@ -2755,8 +2779,8 @@ static void update_output_type(MYSQL_THD thd, if (logging) start_logging(); - internal_stop_logging= 0; flogger_mutex_unlock(&lock_operations); + ADD_ATOMIC(internal_stop_logging, -1); } @@ -2804,9 +2828,9 @@ static void update_logging(MYSQL_THD thd, if (new_logging == logging) return; + ADD_ATOMIC(internal_stop_logging, 1); if (!maria_55_started || !debug_server_started) flogger_mutex_lock(&lock_operations); - internal_stop_logging= 1; if ((logging= new_logging)) { start_logging(); @@ -2821,9 +2845,9 @@ static void update_logging(MYSQL_THD thd, stop_logging(); } - internal_stop_logging= 0; if (!maria_55_started || !debug_server_started) flogger_mutex_unlock(&lock_operations); + ADD_ATOMIC(internal_stop_logging, -1); } @@ -2835,16 +2859,16 @@ static void update_mode(MYSQL_THD thd __attribute__((unused)), if (mode_readonly || new_mode == mode) return; + ADD_ATOMIC(internal_stop_logging, 1); if (!maria_55_started || !debug_server_started) flogger_mutex_lock(&lock_operations); - internal_stop_logging= 1; mark_always_logged(thd); error_header(); fprintf(stderr, "Logging mode was changed from %d to %d.\n", mode, new_mode); mode= new_mode; - internal_stop_logging= 0; if (!maria_55_started || !debug_server_started) flogger_mutex_unlock(&lock_operations); + ADD_ATOMIC(internal_stop_logging, -1); } diff --git a/sql/sql_audit.cc b/sql/sql_audit.cc index 8134adc..8df4c25 100644 --- a/sql/sql_audit.cc +++ b/sql/sql_audit.cc @@ -55,6 +55,86 @@ bool check_audit_mask(const unsigned long *lhs, } +static plugin_ref audit_intern_plugin_lock(LEX *lex, plugin_ref rc, + uint state_mask= PLUGIN_IS_READY | + PLUGIN_IS_UNINITIALIZED | + PLUGIN_IS_DELETED) +{ + st_plugin_int *pi= plugin_ref_to_int(rc); + DBUG_ENTER("intern_plugin_lock"); + + //mysql_mutex_assert_owner(&LOCK_plugin); + + if (pi->state & state_mask) + { + plugin_ref plugin; +#ifdef DBUG_OFF + /* + In optimized builds we don't do reference counting for built-in + (plugin->plugin_dl == 0) plugins. + */ + if (!pi->plugin_dl) + DBUG_RETURN(pi); + + plugin= pi; +#else + /* + For debugging, we do an additional malloc which allows the + memory manager and/or valgrind to track locked references and + double unlocks to aid resolving reference counting problems. + */ + if (!(plugin= (plugin_ref) my_malloc(sizeof(pi), MYF(MY_WME)))) + DBUG_RETURN(NULL); + + *plugin= pi; +#endif + my_atomic_add32(&pi->ref_count, 1); + DBUG_PRINT("lock",("thd: %p plugin: \"%s\" LOCK ref_count: %d", + current_thd, pi->name.str, pi->ref_count)); + + if (lex) + insert_dynamic(&lex->plugins, (uchar*)&plugin); + DBUG_RETURN(plugin); + } + DBUG_RETURN(NULL); +} + + +static plugin_ref audit_plugin_lock(THD *thd, plugin_ref ptr) +{ + LEX *lex= thd ? thd->lex : 0; + plugin_ref rc; + DBUG_ENTER("plugin_lock"); + +#ifdef DBUG_OFF + /* + In optimized builds we don't do reference counting for built-in + (plugin->plugin_dl == 0) plugins. + + Note that we access plugin->plugin_dl outside of LOCK_plugin, and for + dynamic plugins a 'plugin' could correspond to plugin that was unloaded + meanwhile! But because st_plugin_int is always allocated on + plugin_mem_root, the pointer can never be invalid - the memory is never + freed. + Of course, the memory that 'plugin' points to can be overwritten by + another plugin being loaded, but plugin->plugin_dl can never change + from zero to non-zero or vice versa. + That is, it's always safe to check for plugin->plugin_dl==0 even + without a mutex. + */ + if (! plugin_dlib(ptr)) + { + plugin_ref_to_int(ptr)->locks_total++; + DBUG_RETURN(ptr); + } +#endif + //mysql_mutex_lock(&LOCK_plugin); + plugin_ref_to_int(ptr)->locks_total++; + rc= audit_intern_plugin_lock(lex, ptr); + //mysql_mutex_unlock(&LOCK_plugin); + DBUG_RETURN(rc); +} + /** Acquire and lock any additional audit plugins as required @@ -92,13 +172,170 @@ static my_bool acquire_plugins(THD *thd, plugin_ref plugin, void *arg) } /* lock the plugin and add it to the list */ - plugin= my_plugin_lock(NULL, plugin); + plugin= audit_plugin_lock(NULL, plugin); insert_dynamic(&thd->audit_class_plugins, (uchar*) &plugin); return 0; } +extern bool reap_needed; +extern DYNAMIC_ARRAY plugin_array; +extern HASH plugin_hash[MYSQL_MAX_PLUGIN_TYPE_NUM]; +extern int plugin_type_initialization_order[]; +void plugin_deinitialize(struct st_plugin_int *plugin, bool ref_check); +void plugin_del(struct st_plugin_int *plugin); +static void audit_reap_plugins(void) +{ + uint count; + struct st_plugin_int *plugin, **reap, **list; + + //mysql_mutex_assert_owner(&LOCK_plugin); + + if (!reap_needed) + return; + + reap_needed= false; + count= plugin_array.elements; + reap= (struct st_plugin_int **)my_alloca(sizeof(plugin)*(count+1)); + *(reap++)= NULL; + + for (uint i=0; i < MYSQL_MAX_PLUGIN_TYPE_NUM; i++) + { + HASH *hash= plugin_hash + plugin_type_initialization_order[i]; + for (uint j= 0; j < hash->records; j++) + { + plugin= (struct st_plugin_int *) my_hash_element(hash, j); + if (plugin->state == PLUGIN_IS_DELETED && !plugin->ref_count) + { + /* change the status flag to prevent reaping by another thread */ + plugin->state= PLUGIN_IS_DYING; + *(reap++)= plugin; + } + } + } + + + list= reap; + while ((plugin= *(--list))) + plugin_deinitialize(plugin, true); + + mysql_mutex_lock(&LOCK_plugin); + + while ((plugin= *(--reap))) + plugin_del(plugin); + + mysql_mutex_unlock(&LOCK_plugin); + + my_afree(reap); +} + +static void audit_intern_plugin_unlock(LEX *lex, plugin_ref plugin) +{ + int i; + st_plugin_int *pi; + DBUG_ENTER("intern_plugin_unlock"); + + //mysql_mutex_assert_owner(&LOCK_plugin); + + if (!plugin) + DBUG_VOID_RETURN; + + pi= plugin_ref_to_int(plugin); + +#ifdef DBUG_OFF + if (!pi->plugin_dl) + DBUG_VOID_RETURN; +#else + my_free(plugin); +#endif + + if (lex) + { + /* + Remove one instance of this plugin from the use list. + We are searching backwards so that plugins locked last + could be unlocked faster - optimizing for LIFO semantics. + */ + for (i= lex->plugins.elements - 1; i >= 0; i--) + if (plugin == *dynamic_element(&lex->plugins, i, plugin_ref*)) + { + delete_dynamic_element(&lex->plugins, i); + break; + } + DBUG_ASSERT(i >= 0); + } + + DBUG_ASSERT(pi->ref_count); + my_atomic_add32(&pi->ref_count, -1); + + DBUG_PRINT("lock",("thd: %p plugin: \"%s\" UNLOCK ref_count: %d", + current_thd, pi->name.str, pi->ref_count)); + + if (pi->state == PLUGIN_IS_DELETED && !pi->ref_count) + reap_needed= true; + + DBUG_VOID_RETURN; +} + + +static void audit_plugin_unlock_list(THD *thd, plugin_ref *list, uint count) +{ + LEX *lex= thd ? thd->lex : 0; + DBUG_ENTER("plugin_unlock_list"); + if (count == 0) + DBUG_VOID_RETURN; + + DBUG_ASSERT(list); + //mysql_mutex_lock(&LOCK_plugin); + while (count--) + audit_intern_plugin_unlock(lex, *list++); + audit_reap_plugins(); + //mysql_mutex_unlock(&LOCK_plugin); + DBUG_VOID_RETURN; +} + + +extern bool sql_plugin_initialized; +static bool audit_plugin_foreach(THD *thd, plugin_foreach_func *func, + int type, void *arg) +{ + uint idx, total= 0; + struct st_plugin_int *plugin; + plugin_ref *plugins; + my_bool res= FALSE; + DBUG_ENTER("plugin_foreach_with_mask"); + + if (!sql_plugin_initialized) + DBUG_RETURN(FALSE); + + //mysql_mutex_lock(&LOCK_plugin); + { + HASH *hash= plugin_hash + type; + plugins= (plugin_ref*) my_alloca(hash->records * sizeof(plugin_ref)); + for (idx= 0; idx < hash->records; idx++) + { + plugin= (struct st_plugin_int *) my_hash_element(hash, idx); + if ((plugins[total]= audit_intern_plugin_lock(0, plugin_int_to_ref(plugin), + PLUGIN_IS_READY))) + total++; + } + } + //mysql_mutex_unlock(&LOCK_plugin); + + for (idx= 0; idx < total; idx++) + { + /* It will stop iterating on first engine error when "func" returns TRUE */ + if ((res= func(thd, plugins[idx], arg))) + break; + } + + audit_plugin_unlock_list(0, plugins, total); + my_afree(plugins); + DBUG_RETURN(res); +} + + /** @brief Acquire audit plugins @@ -116,7 +353,7 @@ void mysql_audit_acquire_plugins(THD *thd, ulong *event_class_mask) if (check_audit_mask(thd->audit_class_mask, event_class_mask)) { - plugin_foreach(thd, acquire_plugins, MYSQL_AUDIT_PLUGIN, event_class_mask); + audit_plugin_foreach(thd, acquire_plugins, MYSQL_AUDIT_PLUGIN, event_class_mask); add_audit_mask(thd->audit_class_mask, event_class_mask); } DBUG_VOID_RETURN; @@ -152,7 +389,7 @@ void mysql_audit_release(THD *thd) } /* Now we actually unlock the plugins */ - plugin_unlock_list(NULL, (plugin_ref*) thd->audit_class_plugins.buffer, + audit_plugin_unlock_list(NULL, (plugin_ref*) thd->audit_class_plugins.buffer, thd->audit_class_plugins.elements); /* Reset the state of thread values */ diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index da83eae..f0ab157 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -125,7 +125,7 @@ plugin_type_init plugin_type_deinitialize[MYSQL_MAX_PLUGIN_TYPE_NUM]= Essentially, we want to initialize MYSQL_KEY_MANAGEMENT_PLUGIN before MYSQL_STORAGE_ENGINE_PLUGIN, and that before MYSQL_INFORMATION_SCHEMA_PLUGIN */ -static int plugin_type_initialization_order[MYSQL_MAX_PLUGIN_TYPE_NUM]= +int plugin_type_initialization_order[MYSQL_MAX_PLUGIN_TYPE_NUM]= { MYSQL_DAEMON_PLUGIN, MariaDB_ENCRYPTION_PLUGIN, @@ -224,12 +224,12 @@ static struct */ mysql_mutex_t LOCK_plugin; static DYNAMIC_ARRAY plugin_dl_array; -static DYNAMIC_ARRAY plugin_array; -static HASH plugin_hash[MYSQL_MAX_PLUGIN_TYPE_NUM]; +DYNAMIC_ARRAY plugin_array; +HASH plugin_hash[MYSQL_MAX_PLUGIN_TYPE_NUM]; static MEM_ROOT plugin_mem_root; -static bool reap_needed= false; +bool reap_needed= false; -static bool initialized= 0; +bool sql_plugin_initialized= 0; ulong dlopen_count; @@ -891,7 +891,7 @@ static struct st_plugin_int *plugin_find_internal(const LEX_STRING *name, int ty { uint i; DBUG_ENTER("plugin_find_internal"); - if (! initialized) + if (! sql_plugin_initialized) DBUG_RETURN(0); mysql_mutex_assert_owner(&LOCK_plugin); @@ -1186,7 +1186,7 @@ static void plugin_variables_deinit(struct st_plugin_int *plugin) mysql_del_sys_var_chain(plugin->system_vars); } -static void plugin_deinitialize(struct st_plugin_int *plugin, bool ref_check) +void plugin_deinitialize(struct st_plugin_int *plugin, bool ref_check) { /* we don't want to hold the LOCK_plugin mutex as it may cause @@ -1239,7 +1239,7 @@ static void plugin_deinitialize(struct st_plugin_int *plugin, bool ref_check) plugin_variables_deinit(plugin); } -static void plugin_del(struct st_plugin_int *plugin) +void plugin_del(struct st_plugin_int *plugin) { DBUG_ENTER("plugin_del"); mysql_mutex_assert_owner(&LOCK_plugin); @@ -1539,7 +1539,7 @@ int plugin_init(int *argc, char **argv, int flags) LEX_STRING MyISAM= { C_STRING_WITH_LEN("MyISAM") }; DBUG_ENTER("plugin_init"); - if (initialized) + if (sql_plugin_initialized) DBUG_RETURN(0); dlopen_count =0; @@ -1578,7 +1578,7 @@ int plugin_init(int *argc, char **argv, int flags) mysql_mutex_lock(&LOCK_plugin); - initialized= 1; + sql_plugin_initialized= 1; /* First we register builtin plugins @@ -1935,7 +1935,7 @@ void plugin_shutdown(void) struct st_plugin_dl **dl; DBUG_ENTER("plugin_shutdown"); - if (initialized) + if (sql_plugin_initialized) { mysql_mutex_lock(&LOCK_plugin); @@ -2027,7 +2027,7 @@ void plugin_shutdown(void) cleanup_variables(&max_system_variables); mysql_mutex_unlock(&LOCK_plugin); - initialized= 0; + sql_plugin_initialized= 0; mysql_mutex_destroy(&LOCK_plugin); my_afree(plugins); @@ -2357,7 +2357,7 @@ bool plugin_foreach_with_mask(THD *thd, plugin_foreach_func *func, my_bool res= FALSE; DBUG_ENTER("plugin_foreach_with_mask"); - if (!initialized) + if (!sql_plugin_initialized) DBUG_RETURN(FALSE); mysql_mutex_lock(&LOCK_plugin); @@ -4167,7 +4167,7 @@ void add_plugin_options(DYNAMIC_ARRAY *options, MEM_ROOT *mem_root) struct st_plugin_int *p; my_option *opt; - if (!initialized) + if (!sql_plugin_initialized) return; for (uint idx= 0; idx < plugin_array.elements; idx++) diff --git a/sql/sql_plugin.h b/sql/sql_plugin.h index 7b89246..0d7f765 100644 --- a/sql/sql_plugin.h +++ b/sql/sql_plugin.h @@ -111,7 +111,7 @@ struct st_plugin_int st_ptr_backup *ptr_backup; uint nbackups; uint state; - uint ref_count; /* number of threads using the plugin */ + volatile int32 ref_count; /* number of threads using the plugin */ uint locks_total; /* how many times the plugin was locked */ void *data; /* plugin type specific, e.g. handlerton */ MEM_ROOT mem_root; /* memory for dynamic plugin structures */