Commit 6162e758 authored by Alexey Botchkov's avatar Alexey Botchkov

Custom build.

parent 4d89931a
MYSQL_VERSION_MAJOR=10 MYSQL_VERSION_MAJOR=10
MYSQL_VERSION_MINOR=2 MYSQL_VERSION_MINOR=2
MYSQL_VERSION_PATCH=24 MYSQL_VERSION_PATCH=240
This diff is collapsed.
/* Copyright (c) 2000, 2015, Oracle and/or its affiliates. /* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
Copyright (c) 2008, 2019, MariaDB Corporation. Copyright (c) 2008, 2019, MariaDB Corporation.
x
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
......
...@@ -55,6 +55,85 @@ bool check_audit_mask(const unsigned long *lhs, ...@@ -55,6 +55,85 @@ 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 Acquire and lock any additional audit plugins as required
...@@ -92,13 +171,170 @@ static my_bool acquire_plugins(THD *thd, plugin_ref plugin, void *arg) ...@@ -92,13 +171,170 @@ static my_bool acquire_plugins(THD *thd, plugin_ref plugin, void *arg)
} }
/* lock the plugin and add it to the list */ /* 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); insert_dynamic(&thd->audit_class_plugins, (uchar*) &plugin);
return 0; 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 @brief Acquire audit plugins
...@@ -116,7 +352,7 @@ void mysql_audit_acquire_plugins(THD *thd, ulong *event_class_mask) ...@@ -116,7 +352,7 @@ void mysql_audit_acquire_plugins(THD *thd, ulong *event_class_mask)
if (check_audit_mask(thd->audit_class_mask, 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); add_audit_mask(thd->audit_class_mask, event_class_mask);
} }
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
...@@ -152,7 +388,7 @@ void mysql_audit_release(THD *thd) ...@@ -152,7 +388,7 @@ void mysql_audit_release(THD *thd)
} }
/* Now we actually unlock the plugins */ /* 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); thd->audit_class_plugins.elements);
/* Reset the state of thread values */ /* Reset the state of thread values */
......
...@@ -125,7 +125,7 @@ plugin_type_init plugin_type_deinitialize[MYSQL_MAX_PLUGIN_TYPE_NUM]= ...@@ -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 Essentially, we want to initialize MYSQL_KEY_MANAGEMENT_PLUGIN before
MYSQL_STORAGE_ENGINE_PLUGIN, and that before MYSQL_INFORMATION_SCHEMA_PLUGIN 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, MYSQL_DAEMON_PLUGIN,
MariaDB_ENCRYPTION_PLUGIN, MariaDB_ENCRYPTION_PLUGIN,
...@@ -224,12 +224,12 @@ static struct ...@@ -224,12 +224,12 @@ static struct
*/ */
mysql_mutex_t LOCK_plugin; mysql_mutex_t LOCK_plugin;
static DYNAMIC_ARRAY plugin_dl_array; static DYNAMIC_ARRAY plugin_dl_array;
static DYNAMIC_ARRAY plugin_array; DYNAMIC_ARRAY plugin_array;
static HASH plugin_hash[MYSQL_MAX_PLUGIN_TYPE_NUM]; HASH plugin_hash[MYSQL_MAX_PLUGIN_TYPE_NUM];
static MEM_ROOT plugin_mem_root; 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; ulong dlopen_count;
...@@ -891,7 +891,7 @@ static struct st_plugin_int *plugin_find_internal(const LEX_STRING *name, int ty ...@@ -891,7 +891,7 @@ static struct st_plugin_int *plugin_find_internal(const LEX_STRING *name, int ty
{ {
uint i; uint i;
DBUG_ENTER("plugin_find_internal"); DBUG_ENTER("plugin_find_internal");
if (! initialized) if (! sql_plugin_initialized)
DBUG_RETURN(0); DBUG_RETURN(0);
mysql_mutex_assert_owner(&LOCK_plugin); mysql_mutex_assert_owner(&LOCK_plugin);
...@@ -1186,7 +1186,7 @@ static void plugin_variables_deinit(struct st_plugin_int *plugin) ...@@ -1186,7 +1186,7 @@ static void plugin_variables_deinit(struct st_plugin_int *plugin)
mysql_del_sys_var_chain(plugin->system_vars); 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 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) ...@@ -1239,7 +1239,7 @@ static void plugin_deinitialize(struct st_plugin_int *plugin, bool ref_check)
plugin_variables_deinit(plugin); 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"); DBUG_ENTER("plugin_del");
mysql_mutex_assert_owner(&LOCK_plugin); mysql_mutex_assert_owner(&LOCK_plugin);
...@@ -1539,7 +1539,7 @@ int plugin_init(int *argc, char **argv, int flags) ...@@ -1539,7 +1539,7 @@ int plugin_init(int *argc, char **argv, int flags)
LEX_STRING MyISAM= { C_STRING_WITH_LEN("MyISAM") }; LEX_STRING MyISAM= { C_STRING_WITH_LEN("MyISAM") };
DBUG_ENTER("plugin_init"); DBUG_ENTER("plugin_init");
if (initialized) if (sql_plugin_initialized)
DBUG_RETURN(0); DBUG_RETURN(0);
dlopen_count =0; dlopen_count =0;
...@@ -1578,7 +1578,7 @@ int plugin_init(int *argc, char **argv, int flags) ...@@ -1578,7 +1578,7 @@ int plugin_init(int *argc, char **argv, int flags)
mysql_mutex_lock(&LOCK_plugin); mysql_mutex_lock(&LOCK_plugin);
initialized= 1; sql_plugin_initialized= 1;
/* /*
First we register builtin plugins First we register builtin plugins
...@@ -1935,7 +1935,7 @@ void plugin_shutdown(void) ...@@ -1935,7 +1935,7 @@ void plugin_shutdown(void)
struct st_plugin_dl **dl; struct st_plugin_dl **dl;
DBUG_ENTER("plugin_shutdown"); DBUG_ENTER("plugin_shutdown");
if (initialized) if (sql_plugin_initialized)
{ {
mysql_mutex_lock(&LOCK_plugin); mysql_mutex_lock(&LOCK_plugin);
...@@ -2027,7 +2027,7 @@ void plugin_shutdown(void) ...@@ -2027,7 +2027,7 @@ void plugin_shutdown(void)
cleanup_variables(&max_system_variables); cleanup_variables(&max_system_variables);
mysql_mutex_unlock(&LOCK_plugin); mysql_mutex_unlock(&LOCK_plugin);
initialized= 0; sql_plugin_initialized= 0;
mysql_mutex_destroy(&LOCK_plugin); mysql_mutex_destroy(&LOCK_plugin);
my_afree(plugins); my_afree(plugins);
...@@ -2357,7 +2357,7 @@ bool plugin_foreach_with_mask(THD *thd, plugin_foreach_func *func, ...@@ -2357,7 +2357,7 @@ bool plugin_foreach_with_mask(THD *thd, plugin_foreach_func *func,
my_bool res= FALSE; my_bool res= FALSE;
DBUG_ENTER("plugin_foreach_with_mask"); DBUG_ENTER("plugin_foreach_with_mask");
if (!initialized) if (!sql_plugin_initialized)
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
mysql_mutex_lock(&LOCK_plugin); mysql_mutex_lock(&LOCK_plugin);
...@@ -4167,7 +4167,7 @@ void add_plugin_options(DYNAMIC_ARRAY *options, MEM_ROOT *mem_root) ...@@ -4167,7 +4167,7 @@ void add_plugin_options(DYNAMIC_ARRAY *options, MEM_ROOT *mem_root)
struct st_plugin_int *p; struct st_plugin_int *p;
my_option *opt; my_option *opt;
if (!initialized) if (!sql_plugin_initialized)
return; return;
for (uint idx= 0; idx < plugin_array.elements; idx++) for (uint idx= 0; idx < plugin_array.elements; idx++)
......
...@@ -111,7 +111,7 @@ struct st_plugin_int ...@@ -111,7 +111,7 @@ struct st_plugin_int
st_ptr_backup *ptr_backup; st_ptr_backup *ptr_backup;
uint nbackups; uint nbackups;
uint state; 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 */ uint locks_total; /* how many times the plugin was locked */
void *data; /* plugin type specific, e.g. handlerton */ void *data; /* plugin type specific, e.g. handlerton */
MEM_ROOT mem_root; /* memory for dynamic plugin structures */ MEM_ROOT mem_root; /* memory for dynamic plugin structures */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment