mirror of
https://github.com/MariaDB/server.git
synced 2025-07-27 18:02:13 +03:00
WL#2935 - SHOW STATUS support in plugins
The patch adds DYNAMIC_ARRAY all_status_vars, which is now the sole source of status information for SHOW STATUS. Status variables can be added to and removed from the array dynamically. SHOW STATUS command uses this array instead of static array from mysqld.cc Compatibility with the old, global list of status variables is preserved in init_server_components(), where this global list is simply appended to all_status_vars. include/plugin.h: WL#2935 - SHOW STATUS support in plugins plugin/fulltext/plugin_example.c: WL#2935 - SHOW STATUS support in plugins example sql/ha_innodb.cc: s/struct show_var_st/SHOW_VAR/ sql/ha_innodb.h: s/struct show_var_st/SHOW_VAR/ sql/mysql_priv.h: WL#2935 - SHOW STATUS support in plugins add_status_vars(), remove_status_vars() sql/mysqld.cc: bug: plugin_free must be called even with --skip-grants add_status_vars()/free_status_vars(), remove unused SHOW_xxx_CONST s/struct show_var_st/SHOW_VAR/ sql/set_var.cc: s/struct show_var_st/SHOW_VAR/ sql/sql_parse.cc: s/struct show_var_st/SHOW_VAR/ sql/sql_plugin.cc: WL#2935 - SHOW STATUS support in plugins sql/sql_plugin.h: WL#2935 - SHOW STATUS support in plugins sql/sql_show.cc: WL#2935 - SHOW STATUS support in plugins DYNAMIC_ARRAY all_status_vars, add_status_vars(), remove_status_vars() s/struct show_var_st/SHOW_VAR/ sql/structs.h: WL#2935 - SHOW STATUS support in plugins SHOW STATUS definitions moved to include/plugin.h and sql_plugin.h s/struct show_var_st/SHOW_VAR/
This commit is contained in:
@ -94,7 +94,8 @@ static st_plugin_dl *plugin_dl_insert_or_reuse(struct st_plugin_dl *plugin_dl)
|
||||
|
||||
static inline void free_plugin_mem(struct st_plugin_dl *p)
|
||||
{
|
||||
dlclose(p->handle);
|
||||
if (p->handle)
|
||||
dlclose(p->handle);
|
||||
my_free(p->dl.str, MYF(MY_ALLOW_ZERO_PTR));
|
||||
if (p->version != MYSQL_PLUGIN_INTERFACE_VERSION)
|
||||
my_free((gptr)p->plugins, MYF(MY_ALLOW_ZERO_PTR));
|
||||
@ -182,7 +183,7 @@ static st_plugin_dl *plugin_dl_add(LEX_STRING *dl, int report)
|
||||
{
|
||||
int i, sizeof_st_plugin;
|
||||
struct st_mysql_plugin *old, *cur;
|
||||
char *ptr=(char *)sym;
|
||||
char *ptr= (char *)sym;
|
||||
|
||||
if ((sym= dlsym(plugin_dl.handle, sizeof_st_plugin_sym)))
|
||||
sizeof_st_plugin= *(int *)sym;
|
||||
@ -196,8 +197,12 @@ static st_plugin_dl *plugin_dl_add(LEX_STRING *dl, int report)
|
||||
sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), sizeof_st_plugin_sym);
|
||||
DBUG_RETURN(0);
|
||||
#else
|
||||
/*
|
||||
When the following assert starts failing, we'll have to switch
|
||||
to the upper branch of the #ifdef
|
||||
*/
|
||||
DBUG_ASSERT(min_plugin_interface_version == 0);
|
||||
sizeof_st_plugin=(int)offsetof(struct st_mysql_plugin, version);
|
||||
sizeof_st_plugin= (int)offsetof(struct st_mysql_plugin, version);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -217,29 +222,17 @@ static st_plugin_dl *plugin_dl_add(LEX_STRING *dl, int report)
|
||||
sql_print_error(ER(ER_OUTOFMEMORY), plugin_dl.dl.length);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
/*
|
||||
All st_plugin fields not initialized in the plugin explicitly, are
|
||||
set to 0. It matches C standard behaviour for struct initializers that
|
||||
have less values than the struct definition.
|
||||
*/
|
||||
for (i=0;
|
||||
(old=(struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info;
|
||||
i++)
|
||||
{
|
||||
switch (plugin_dl.version) {
|
||||
default: /* version > MYSQL_PLUGIN_INTERFACE_VERSION */
|
||||
/* fall through */
|
||||
case 0x0001:
|
||||
cur[i].version=old->version;
|
||||
// cur[i].status_vars=old->status_vars;
|
||||
/* fall through */
|
||||
case 0x0000:
|
||||
cur[i].type=old->type;
|
||||
cur[i].info=old->info;
|
||||
cur[i].name=old->name;
|
||||
cur[i].author=old->author;
|
||||
cur[i].descr=old->descr;
|
||||
cur[i].init=old->init;
|
||||
cur[i].deinit=old->deinit;
|
||||
}
|
||||
}
|
||||
memcpy(cur+i, old, min(sizeof(cur[i]), sizeof_st_plugin));
|
||||
|
||||
sym=cur;
|
||||
sym= cur;
|
||||
}
|
||||
plugin_dl.plugins= (struct st_mysql_plugin *)sym;
|
||||
|
||||
@ -320,7 +313,7 @@ static struct st_plugin_int *plugin_find_internal(LEX_STRING *name, int type)
|
||||
{
|
||||
struct st_plugin_int *plugin= (st_plugin_int *)
|
||||
hash_search(&plugin_hash[i], (const byte *)name->str, name->length);
|
||||
if (plugin)
|
||||
if (plugin)
|
||||
DBUG_RETURN(plugin);
|
||||
}
|
||||
}
|
||||
@ -382,7 +375,6 @@ static st_plugin_int *plugin_insert_or_reuse(struct st_plugin_int *plugin)
|
||||
struct st_plugin_int *));
|
||||
}
|
||||
|
||||
|
||||
static my_bool plugin_add(LEX_STRING *name, LEX_STRING *dl, int report)
|
||||
{
|
||||
struct st_plugin_int tmp;
|
||||
@ -429,21 +421,20 @@ static my_bool plugin_add(LEX_STRING *name, LEX_STRING *dl, int report)
|
||||
tmp.name.length= name_len;
|
||||
tmp.ref_count= 0;
|
||||
tmp.state= PLUGIN_IS_UNINITIALIZED;
|
||||
if (! (tmp_plugin_ptr= plugin_insert_or_reuse(&tmp)))
|
||||
if (plugin->status_vars)
|
||||
{
|
||||
if (report & REPORT_TO_USER)
|
||||
my_error(ER_OUTOFMEMORY, MYF(0), sizeof(struct st_plugin_int));
|
||||
if (report & REPORT_TO_LOG)
|
||||
sql_print_error(ER(ER_OUTOFMEMORY), sizeof(struct st_plugin_int));
|
||||
goto err;
|
||||
SHOW_VAR array[2]= {
|
||||
{plugin->name, (char*)plugin->status_vars, SHOW_ARRAY},
|
||||
{0, 0, SHOW_UNDEF}
|
||||
};
|
||||
if (add_status_vars(array)) // add_status_vars makes a copy
|
||||
goto err;
|
||||
}
|
||||
if (! (tmp_plugin_ptr= plugin_insert_or_reuse(&tmp)))
|
||||
goto err;
|
||||
if (my_hash_insert(&plugin_hash[plugin->type], (byte*)tmp_plugin_ptr))
|
||||
{
|
||||
tmp_plugin_ptr->state= PLUGIN_IS_FREED;
|
||||
if (report & REPORT_TO_USER)
|
||||
my_error(ER_OUTOFMEMORY, MYF(0), sizeof(struct st_plugin_int));
|
||||
if (report & REPORT_TO_LOG)
|
||||
sql_print_error(ER(ER_OUTOFMEMORY), sizeof(struct st_plugin_int));
|
||||
goto err;
|
||||
}
|
||||
DBUG_RETURN(FALSE);
|
||||
@ -454,6 +445,14 @@ static my_bool plugin_add(LEX_STRING *name, LEX_STRING *dl, int report)
|
||||
if (report & REPORT_TO_LOG)
|
||||
sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), name->str);
|
||||
err:
|
||||
if (plugin->status_vars)
|
||||
{
|
||||
SHOW_VAR array[2]= {
|
||||
{plugin->name, (char*)plugin->status_vars, SHOW_ARRAY},
|
||||
{0, 0, SHOW_UNDEF}
|
||||
};
|
||||
remove_status_vars(array);
|
||||
}
|
||||
plugin_dl_del(dl);
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
@ -466,6 +465,14 @@ static void plugin_del(LEX_STRING *name)
|
||||
DBUG_ENTER("plugin_del");
|
||||
if ((plugin= plugin_find_internal(name, MYSQL_ANY_PLUGIN)))
|
||||
{
|
||||
if (plugin->plugin->status_vars)
|
||||
{
|
||||
SHOW_VAR array[2]= {
|
||||
{plugin->plugin->name, (char*)plugin->plugin->status_vars, SHOW_ARRAY},
|
||||
{0, 0, SHOW_UNDEF}
|
||||
};
|
||||
remove_status_vars(array);
|
||||
}
|
||||
hash_delete(&plugin_hash[plugin->plugin->type], (byte*)plugin);
|
||||
plugin_dl_del(&plugin->plugin_dl->dl);
|
||||
plugin->state= PLUGIN_IS_FREED;
|
||||
@ -494,7 +501,7 @@ void plugin_unlock(struct st_plugin_int *plugin)
|
||||
static int plugin_initialize(struct st_plugin_int *plugin)
|
||||
{
|
||||
DBUG_ENTER("plugin_initialize");
|
||||
|
||||
|
||||
if (plugin->plugin->init)
|
||||
{
|
||||
if (plugin->plugin->init())
|
||||
@ -506,7 +513,7 @@ static int plugin_initialize(struct st_plugin_int *plugin)
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
switch (plugin->plugin->type)
|
||||
{
|
||||
case MYSQL_STORAGE_ENGINE_PLUGIN:
|
||||
@ -605,11 +612,11 @@ int plugin_init(void)
|
||||
get_hash_key, NULL, 0))
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
||||
initialized= 1;
|
||||
|
||||
DBUG_RETURN(0);
|
||||
|
||||
|
||||
err:
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
@ -651,9 +658,9 @@ void plugin_load(void)
|
||||
MEM_ROOT mem;
|
||||
THD *new_thd;
|
||||
DBUG_ENTER("plugin_load");
|
||||
|
||||
|
||||
DBUG_ASSERT(initialized);
|
||||
|
||||
|
||||
if (!(new_thd= new THD))
|
||||
{
|
||||
sql_print_error("Can't allocate memory for plugin structures");
|
||||
@ -716,12 +723,7 @@ void plugin_free(void)
|
||||
{
|
||||
struct st_plugin_dl *tmp= dynamic_element(&plugin_dl_array, i,
|
||||
struct st_plugin_dl *);
|
||||
#ifdef HAVE_DLOPEN
|
||||
if (tmp->handle)
|
||||
{
|
||||
free_plugin_mem(tmp);
|
||||
}
|
||||
#endif
|
||||
free_plugin_mem(tmp);
|
||||
}
|
||||
delete_dynamic(&plugin_dl_array);
|
||||
if (initialized)
|
||||
@ -746,7 +748,7 @@ my_bool mysql_install_plugin(THD *thd, LEX_STRING *name, LEX_STRING *dl)
|
||||
tables.table_name= tables.alias= (char *)"plugin";
|
||||
if (check_table_access(thd, INSERT_ACL, &tables, 0))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
|
||||
/* need to open before acquiring THR_LOCK_plugin or it will deadlock */
|
||||
if (! (table = open_ltable(thd, &tables, TL_WRITE)))
|
||||
DBUG_RETURN(TRUE);
|
||||
@ -755,7 +757,7 @@ my_bool mysql_install_plugin(THD *thd, LEX_STRING *name, LEX_STRING *dl)
|
||||
if (plugin_add(name, dl, REPORT_TO_USER))
|
||||
goto err;
|
||||
tmp= plugin_find_internal(name, MYSQL_ANY_PLUGIN);
|
||||
|
||||
|
||||
if (plugin_initialize(tmp))
|
||||
{
|
||||
my_error(ER_CANT_INITIALIZE_UDF, MYF(0), name->str,
|
||||
@ -774,7 +776,7 @@ my_bool mysql_install_plugin(THD *thd, LEX_STRING *name, LEX_STRING *dl)
|
||||
table->file->print_error(error, MYF(0));
|
||||
goto deinit;
|
||||
}
|
||||
|
||||
|
||||
rw_unlock(&THR_LOCK_plugin);
|
||||
DBUG_RETURN(FALSE);
|
||||
deinit:
|
||||
@ -815,7 +817,7 @@ my_bool mysql_uninstall_plugin(THD *thd, LEX_STRING *name)
|
||||
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PLUGIN", name->str);
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
||||
if (plugin->ref_count)
|
||||
{
|
||||
plugin->state= PLUGIN_IS_DELETED;
|
||||
@ -858,13 +860,13 @@ my_bool plugin_foreach(THD *thd, plugin_foreach_func *func,
|
||||
struct st_plugin_int *plugin;
|
||||
DBUG_ENTER("mysql_uninstall_plugin");
|
||||
rw_rdlock(&THR_LOCK_plugin);
|
||||
|
||||
|
||||
if (type == MYSQL_ANY_PLUGIN)
|
||||
{
|
||||
for (idx= 0; idx < plugin_array.elements; idx++)
|
||||
{
|
||||
plugin= dynamic_element(&plugin_array, idx, struct st_plugin_int *);
|
||||
|
||||
|
||||
/* FREED records may have garbage pointers */
|
||||
if ((plugin->state != PLUGIN_IS_FREED) &&
|
||||
func(thd, plugin, arg))
|
||||
|
Reference in New Issue
Block a user