Commit f1042103 authored by unknown's avatar unknown

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.


sql/sql_plugin.cc:
  Bug33358
    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.
mysql-test/r/plugin_load.result:
  New BitKeeper file ``mysql-test/r/plugin_load.result''
mysql-test/t/plugin_load-master.opt:
  New BitKeeper file ``mysql-test/t/plugin_load-master.opt''
mysql-test/t/plugin_load.test:
  New BitKeeper file ``mysql-test/t/plugin_load.test''
parent f23b19ea
SELECT @@global.example_enum_var = 'e2';
@@global.example_enum_var = 'e2'
1
$EXAMPLE_PLUGIN_OPT
"--plugin-load=;EXAMPLE=ha_example.so;"
--plugin-example-enum-var=e2
--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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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);
......
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