Bug#33358
"Plugin enum variables can't be set from command line" fix crash of LOCK_plugins mutex when loading plug-ins from command line. fix off-by-one bug when loading multiple plug-ins from the command line. initialize command line handling for ENUM and SET plugin variable types.
This commit is contained in:
parent
de3f89096d
commit
98515df213
3
mysql-test/r/plugin_load.result
Normal file
3
mysql-test/r/plugin_load.result
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
SELECT @@global.example_enum_var = 'e2';
|
||||||
|
@@global.example_enum_var = 'e2'
|
||||||
|
1
|
3
mysql-test/t/plugin_load-master.opt
Normal file
3
mysql-test/t/plugin_load-master.opt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
$EXAMPLE_PLUGIN_OPT
|
||||||
|
"--plugin-load=;EXAMPLE=ha_example.so;"
|
||||||
|
--plugin-example-enum-var=e2
|
3
mysql-test/t/plugin_load.test
Normal file
3
mysql-test/t/plugin_load.test
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
--source include/have_example_plugin.inc
|
||||||
|
|
||||||
|
SELECT @@global.example_enum_var = 'e2';
|
@ -1412,7 +1412,11 @@ static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv,
|
|||||||
while (list)
|
while (list)
|
||||||
{
|
{
|
||||||
if (p == buffer + sizeof(buffer) - 1)
|
if (p == buffer + sizeof(buffer) - 1)
|
||||||
break;
|
{
|
||||||
|
sql_print_error("plugin-load parameter too long");
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
switch ((*(p++)= *(list++))) {
|
switch ((*(p++)= *(list++))) {
|
||||||
case '\0':
|
case '\0':
|
||||||
list= NULL; /* terminate the loop */
|
list= NULL; /* terminate the loop */
|
||||||
@ -1421,10 +1425,17 @@ static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv,
|
|||||||
case ':': /* can't use this as delimiter as it may be drive letter */
|
case ':': /* can't use this as delimiter as it may be drive letter */
|
||||||
#endif
|
#endif
|
||||||
case ';':
|
case ';':
|
||||||
name.str[name.length]= '\0';
|
str->str[str->length]= '\0';
|
||||||
if (str != &dl) // load all plugins in named module
|
if (str == &name) // load all plugins in named module
|
||||||
{
|
{
|
||||||
|
if (!name.length)
|
||||||
|
{
|
||||||
|
p--; /* reset pointer */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
dl= name;
|
dl= name;
|
||||||
|
pthread_mutex_lock(&LOCK_plugin);
|
||||||
if ((plugin_dl= plugin_dl_add(&dl, REPORT_TO_LOG)))
|
if ((plugin_dl= plugin_dl_add(&dl, REPORT_TO_LOG)))
|
||||||
{
|
{
|
||||||
for (plugin= plugin_dl->plugins; plugin->info; plugin++)
|
for (plugin= plugin_dl->plugins; plugin->info; plugin++)
|
||||||
@ -1434,7 +1445,10 @@ static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv,
|
|||||||
|
|
||||||
free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE));
|
free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE));
|
||||||
if (plugin_add(tmp_root, &name, &dl, argc, argv, REPORT_TO_LOG))
|
if (plugin_add(tmp_root, &name, &dl, argc, argv, REPORT_TO_LOG))
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&LOCK_plugin);
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
plugin_dl_del(&dl); // reduce ref count
|
plugin_dl_del(&dl); // reduce ref count
|
||||||
}
|
}
|
||||||
@ -1442,9 +1456,14 @@ static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE));
|
free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE));
|
||||||
|
pthread_mutex_lock(&LOCK_plugin);
|
||||||
if (plugin_add(tmp_root, &name, &dl, argc, argv, REPORT_TO_LOG))
|
if (plugin_add(tmp_root, &name, &dl, argc, argv, REPORT_TO_LOG))
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&LOCK_plugin);
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
pthread_mutex_unlock(&LOCK_plugin);
|
||||||
name.length= dl.length= 0;
|
name.length= dl.length= 0;
|
||||||
dl.str= NULL; name.str= p= buffer;
|
dl.str= NULL; name.str= p= buffer;
|
||||||
str= &name;
|
str= &name;
|
||||||
@ -1453,6 +1472,7 @@ static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv,
|
|||||||
case '#':
|
case '#':
|
||||||
if (str == &name)
|
if (str == &name)
|
||||||
{
|
{
|
||||||
|
name.str[name.length]= '\0';
|
||||||
str= &dl;
|
str= &dl;
|
||||||
str->str= p;
|
str->str= p;
|
||||||
continue;
|
continue;
|
||||||
@ -2999,7 +3019,8 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
|
|||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt->flags & PLUGIN_VAR_NOCMDOPT)
|
if ((opt->flags & (PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_THDLOCAL))
|
||||||
|
== PLUGIN_VAR_NOCMDOPT)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!opt->name)
|
if (!opt->name)
|
||||||
@ -3009,7 +3030,7 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
|
|||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(v= find_bookmark(name, opt->name, opt->flags)))
|
if (!(opt->flags & PLUGIN_VAR_THDLOCAL))
|
||||||
{
|
{
|
||||||
optnamelen= strlen(opt->name);
|
optnamelen= strlen(opt->name);
|
||||||
optname= (char*) alloc_root(mem_root, namelen + optnamelen + 2);
|
optname= (char*) alloc_root(mem_root, namelen + optnamelen + 2);
|
||||||
@ -3017,7 +3038,23 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
|
|||||||
optnamelen= namelen + optnamelen + 1;
|
optnamelen= namelen + optnamelen + 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
optname= (char*) memdup_root(mem_root, v->key + 1, (optnamelen= v->name_len) + 1);
|
{
|
||||||
|
/* this should not fail because register_var should create entry */
|
||||||
|
if (!(v= find_bookmark(name, opt->name, opt->flags)))
|
||||||
|
{
|
||||||
|
sql_print_error("Thread local variable '%s' not allocated "
|
||||||
|
"in plugin '%s'.", opt->name, plugin_name);
|
||||||
|
DBUG_RETURN(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
*(int*)(opt + 1)= offset= v->offset;
|
||||||
|
|
||||||
|
if (opt->flags & PLUGIN_VAR_NOCMDOPT)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
optname= (char*) memdup_root(mem_root, v->key + 1,
|
||||||
|
(optnamelen= v->name_len) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
/* convert '_' to '-' */
|
/* convert '_' to '-' */
|
||||||
for (p= optname; *p; p++)
|
for (p= optname; *p; p++)
|
||||||
@ -3029,20 +3066,13 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
|
|||||||
options->app_type= opt;
|
options->app_type= opt;
|
||||||
options->id= (options-1)->id + 1;
|
options->id= (options-1)->id + 1;
|
||||||
|
|
||||||
if (opt->flags & PLUGIN_VAR_THDLOCAL)
|
|
||||||
*(int*)(opt + 1)= offset= v->offset;
|
|
||||||
|
|
||||||
plugin_opt_set_limits(options, opt);
|
plugin_opt_set_limits(options, opt);
|
||||||
|
|
||||||
if ((opt->flags & PLUGIN_VAR_TYPEMASK) != PLUGIN_VAR_ENUM &&
|
if (opt->flags & PLUGIN_VAR_THDLOCAL)
|
||||||
(opt->flags & PLUGIN_VAR_TYPEMASK) != PLUGIN_VAR_SET)
|
options->value= options->u_max_value= (uchar**)
|
||||||
{
|
(global_system_variables.dynamic_variables_ptr + offset);
|
||||||
if (opt->flags & PLUGIN_VAR_THDLOCAL)
|
else
|
||||||
options->value= options->u_max_value= (uchar**)
|
options->value= options->u_max_value= *(uchar***) (opt + 1);
|
||||||
(global_system_variables.dynamic_variables_ptr + offset);
|
|
||||||
else
|
|
||||||
options->value= options->u_max_value= *(uchar***) (opt + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
options[1]= options[0];
|
options[1]= options[0];
|
||||||
options[1].name= p= (char*) alloc_root(mem_root, optnamelen + 8);
|
options[1].name= p= (char*) alloc_root(mem_root, optnamelen + 8);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user