Commit 37afe1b3 authored by Sergey Vojtovich's avatar Sergey Vojtovich

WL#5341 - Sticky plugins

This patch implements "permanent" load option for
plugins as specified by WL#5341.

mysql-test/r/plugin_load_option.result:
  A test case for WL#5341.
mysql-test/t/plugin_load_option-master.opt:
  A test case for WL#5341.
mysql-test/t/plugin_load_option.test:
  A test case for WL#5341.
sql/share/errmsg-utf8.txt:
  An error message for WL#5341.
sql/sql_plugin.cc:
  Added FORCE_PLUS_PERMANENT plugin load option.
sql/sql_plugin.h:
  Expose and use plugin load option instead of
  is_mandatory flag. This is a requirement for
  to-be-implemented WL5496.
parent f4444c00
UNINSTALL PLUGIN example;
ERROR HY000: Plugin 'example' is force_plus_permanent and can not be unloaded
$EXAMPLE_PLUGIN_OPT
$EXAMPLE_PLUGIN_LOAD
--plugin-example=FORCE_PLUS_PERMANENT
--source include/not_windows_embedded.inc
--source include/have_example_plugin.inc
--error ER_PLUGIN_IS_PERMANENT
UNINSTALL PLUGIN example;
...@@ -6346,3 +6346,5 @@ ER_STORED_FUNCTION_PREVENTS_SWITCH_SQL_LOG_BIN ...@@ -6346,3 +6346,5 @@ ER_STORED_FUNCTION_PREVENTS_SWITCH_SQL_LOG_BIN
ER_FAILED_READ_FROM_PAR_FILE ER_FAILED_READ_FROM_PAR_FILE
eng "Failed to read from the .par file" eng "Failed to read from the .par file"
swe "Misslyckades läsa från .par filen" swe "Misslyckades läsa från .par filen"
ER_PLUGIN_IS_PERMANENT
eng "Plugin '%s' is force_plus_permanent and can not be unloaded"
...@@ -41,9 +41,8 @@ extern struct st_mysql_plugin *mysql_mandatory_plugins[]; ...@@ -41,9 +41,8 @@ extern struct st_mysql_plugin *mysql_mandatory_plugins[];
@note The order of the enumeration is critical. @note The order of the enumeration is critical.
@see construct_options @see construct_options
*/ */
static const char *global_plugin_typelib_names[]= const char *global_plugin_typelib_names[]=
{ "OFF", "ON", "FORCE", NULL }; { "OFF", "ON", "FORCE", "FORCE_PLUS_PERMANENT", NULL };
enum enum_plugin_load_policy {PLUGIN_OFF, PLUGIN_ON, PLUGIN_FORCE};
static TYPELIB global_plugin_typelib= static TYPELIB global_plugin_typelib=
{ array_elements(global_plugin_typelib_names)-1, { array_elements(global_plugin_typelib_names)-1,
"", global_plugin_typelib_names, NULL }; "", global_plugin_typelib_names, NULL };
...@@ -796,6 +795,7 @@ static bool plugin_add(MEM_ROOT *tmp_root, ...@@ -796,6 +795,7 @@ static bool plugin_add(MEM_ROOT *tmp_root,
tmp.name.length= name_len; tmp.name.length= name_len;
tmp.ref_count= 0; tmp.ref_count= 0;
tmp.state= PLUGIN_IS_UNINITIALIZED; tmp.state= PLUGIN_IS_UNINITIALIZED;
tmp.load_option= PLUGIN_ON;
if (test_plugin_options(tmp_root, &tmp, argc, argv)) if (test_plugin_options(tmp_root, &tmp, argc, argv))
tmp.state= PLUGIN_IS_DISABLED; tmp.state= PLUGIN_IS_DISABLED;
...@@ -1237,7 +1237,7 @@ int plugin_init(int *argc, char **argv, int flags) ...@@ -1237,7 +1237,7 @@ int plugin_init(int *argc, char **argv, int flags)
tmp.name.str= (char *)plugin->name; tmp.name.str= (char *)plugin->name;
tmp.name.length= strlen(plugin->name); tmp.name.length= strlen(plugin->name);
tmp.state= 0; tmp.state= 0;
tmp.is_mandatory= mandatory; tmp.load_option= mandatory ? PLUGIN_FORCE : PLUGIN_ON;
/* /*
If the performance schema is compiled in, If the performance schema is compiled in,
...@@ -1256,7 +1256,7 @@ int plugin_init(int *argc, char **argv, int flags) ...@@ -1256,7 +1256,7 @@ int plugin_init(int *argc, char **argv, int flags)
to work, by using '--skip-performance-schema' (the plugin) to work, by using '--skip-performance-schema' (the plugin)
*/ */
if (!my_strcasecmp(&my_charset_latin1, plugin->name, "PERFORMANCE_SCHEMA")) if (!my_strcasecmp(&my_charset_latin1, plugin->name, "PERFORMANCE_SCHEMA"))
tmp.is_mandatory= true; tmp.load_option= PLUGIN_FORCE;
free_root(&tmp_root, MYF(MY_MARK_BLOCKS_FREE)); free_root(&tmp_root, MYF(MY_MARK_BLOCKS_FREE));
if (test_plugin_options(&tmp_root, &tmp, argc, argv)) if (test_plugin_options(&tmp_root, &tmp, argc, argv))
...@@ -1334,7 +1334,8 @@ int plugin_init(int *argc, char **argv, int flags) ...@@ -1334,7 +1334,8 @@ int plugin_init(int *argc, char **argv, int flags)
while ((plugin_ptr= *(--reap))) while ((plugin_ptr= *(--reap)))
{ {
mysql_mutex_unlock(&LOCK_plugin); mysql_mutex_unlock(&LOCK_plugin);
if (plugin_ptr->is_mandatory) if (plugin_ptr->load_option == PLUGIN_FORCE ||
plugin_ptr->load_option == PLUGIN_FORCE_PLUS_PERMANENT)
reaped_mandatory_plugin= TRUE; reaped_mandatory_plugin= TRUE;
plugin_deinitialize(plugin_ptr, true); plugin_deinitialize(plugin_ptr, true);
mysql_mutex_lock(&LOCK_plugin); mysql_mutex_lock(&LOCK_plugin);
...@@ -1844,6 +1845,11 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name) ...@@ -1844,6 +1845,11 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name)
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PLUGIN", name->str); my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PLUGIN", name->str);
goto err; goto err;
} }
if (plugin->load_option == PLUGIN_FORCE_PLUS_PERMANENT)
{
my_error(ER_PLUGIN_IS_PERMANENT, MYF(0), name->str);
goto err;
}
plugin->state= PLUGIN_IS_DELETED; plugin->state= PLUGIN_IS_DELETED;
if (plugin->ref_count) if (plugin->ref_count)
...@@ -3054,7 +3060,8 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp, ...@@ -3054,7 +3060,8 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
plugin_dash.length + 1); plugin_dash.length + 1);
strxmov(plugin_name_with_prefix_ptr, plugin_dash.str, plugin_name_ptr, NullS); strxmov(plugin_name_with_prefix_ptr, plugin_dash.str, plugin_name_ptr, NullS);
if (!tmp->is_mandatory) if (tmp->load_option != PLUGIN_FORCE &&
tmp->load_option != PLUGIN_FORCE_PLUS_PERMANENT)
{ {
/* support --skip-plugin-foo syntax */ /* support --skip-plugin-foo syntax */
options[0].name= plugin_name_ptr; options[0].name= plugin_name_ptr;
...@@ -3314,7 +3321,7 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp, ...@@ -3314,7 +3321,7 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
{ {
struct sys_var_chain chain= { NULL, NULL }; struct sys_var_chain chain= { NULL, NULL };
bool disable_plugin; bool disable_plugin;
enum_plugin_load_policy plugin_load_policy= tmp->is_mandatory ? PLUGIN_FORCE : PLUGIN_ON; enum_plugin_load_option plugin_load_option= tmp->load_option;
MEM_ROOT *mem_root= alloc_root_inited(&tmp->mem_root) ? MEM_ROOT *mem_root= alloc_root_inited(&tmp->mem_root) ?
&tmp->mem_root : &plugin_mem_root; &tmp->mem_root : &plugin_mem_root;
...@@ -3335,7 +3342,7 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp, ...@@ -3335,7 +3342,7 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
*/ */
if (!(my_strcasecmp(&my_charset_latin1, tmp->name.str, "federated") && if (!(my_strcasecmp(&my_charset_latin1, tmp->name.str, "federated") &&
my_strcasecmp(&my_charset_latin1, tmp->name.str, "ndbcluster"))) my_strcasecmp(&my_charset_latin1, tmp->name.str, "ndbcluster")))
plugin_load_policy= PLUGIN_OFF; plugin_load_option= PLUGIN_OFF;
for (opt= tmp->plugin->system_vars; opt && *opt; opt++) for (opt= tmp->plugin->system_vars; opt && *opt; opt++)
count+= 2; /* --{plugin}-{optname} and --plugin-{plugin}-{optname} */ count+= 2; /* --{plugin}-{optname} and --plugin-{plugin}-{optname} */
...@@ -3359,8 +3366,9 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp, ...@@ -3359,8 +3366,9 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
We adjust the default value to account for the hardcoded exceptions We adjust the default value to account for the hardcoded exceptions
we have set for the federated and ndbcluster storage engines. we have set for the federated and ndbcluster storage engines.
*/ */
if (!tmp->is_mandatory) if (tmp->load_option != PLUGIN_FORCE &&
opts[0].def_value= opts[1].def_value= plugin_load_policy; tmp->load_option != PLUGIN_FORCE_PLUS_PERMANENT)
opts[0].def_value= opts[1].def_value= plugin_load_option;
error= handle_options(argc, &argv, opts, NULL); error= handle_options(argc, &argv, opts, NULL);
(*argc)++; /* add back one for the program name */ (*argc)++; /* add back one for the program name */
...@@ -3375,12 +3383,13 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp, ...@@ -3375,12 +3383,13 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
Set plugin loading policy from option value. First element in the option Set plugin loading policy from option value. First element in the option
list is always the <plugin name> option value. list is always the <plugin name> option value.
*/ */
if (!tmp->is_mandatory) if (tmp->load_option != PLUGIN_FORCE &&
plugin_load_policy= (enum_plugin_load_policy)*(ulong*)opts[0].value; tmp->load_option != PLUGIN_FORCE_PLUS_PERMANENT)
plugin_load_option= (enum_plugin_load_option) *(ulong*) opts[0].value;
} }
disable_plugin= (plugin_load_policy == PLUGIN_OFF); disable_plugin= (plugin_load_option == PLUGIN_OFF);
tmp->is_mandatory= (plugin_load_policy == PLUGIN_FORCE); tmp->load_option= plugin_load_option;
/* /*
If the plugin is disabled it should not be initialized. If the plugin is disabled it should not be initialized.
......
...@@ -32,6 +32,9 @@ ...@@ -32,6 +32,9 @@
class sys_var; class sys_var;
enum SHOW_COMP_OPTION { SHOW_OPTION_YES, SHOW_OPTION_NO, SHOW_OPTION_DISABLED}; enum SHOW_COMP_OPTION { SHOW_OPTION_YES, SHOW_OPTION_NO, SHOW_OPTION_DISABLED};
enum enum_plugin_load_option { PLUGIN_OFF, PLUGIN_ON, PLUGIN_FORCE,
PLUGIN_FORCE_PLUS_PERMANENT };
extern const char *global_plugin_typelib_names[];
#include <my_sys.h> #include <my_sys.h>
...@@ -95,7 +98,7 @@ struct st_plugin_int ...@@ -95,7 +98,7 @@ struct st_plugin_int
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 */
sys_var *system_vars; /* server variables for this plugin */ sys_var *system_vars; /* server variables for this plugin */
bool is_mandatory; /* If true then plugin must not fail to load */ enum enum_plugin_load_option load_option; /* OFF, ON, FORCE, F+PERMANENT */
}; };
...@@ -110,6 +113,7 @@ typedef struct st_plugin_int *plugin_ref; ...@@ -110,6 +113,7 @@ typedef struct st_plugin_int *plugin_ref;
#define plugin_data(pi,cast) ((cast)((pi)->data)) #define plugin_data(pi,cast) ((cast)((pi)->data))
#define plugin_name(pi) (&((pi)->name)) #define plugin_name(pi) (&((pi)->name))
#define plugin_state(pi) ((pi)->state) #define plugin_state(pi) ((pi)->state)
#define plugin_load_option(pi) ((pi)->load_option)
#define plugin_equals(p1,p2) ((p1) == (p2)) #define plugin_equals(p1,p2) ((p1) == (p2))
#else #else
typedef struct st_plugin_int **plugin_ref; typedef struct st_plugin_int **plugin_ref;
...@@ -118,6 +122,7 @@ typedef struct st_plugin_int **plugin_ref; ...@@ -118,6 +122,7 @@ typedef struct st_plugin_int **plugin_ref;
#define plugin_data(pi,cast) ((cast)((pi)[0]->data)) #define plugin_data(pi,cast) ((cast)((pi)[0]->data))
#define plugin_name(pi) (&((pi)[0]->name)) #define plugin_name(pi) (&((pi)[0]->name))
#define plugin_state(pi) ((pi)[0]->state) #define plugin_state(pi) ((pi)[0]->state)
#define plugin_load_option(pi) ((pi)[0]->load_option)
#define plugin_equals(p1,p2) ((p1) && (p2) && (p1)[0] == (p2)[0]) #define plugin_equals(p1,p2) ((p1) && (p2) && (p1)[0] == (p2)[0])
#endif #endif
......
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