diff options
Diffstat (limited to 'sql/sql_plugin.cc')
-rw-r--r-- | sql/sql_plugin.cc | 114 |
1 files changed, 75 insertions, 39 deletions
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index c7f36014003..44b2a8220b3 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -269,6 +269,7 @@ struct st_bookmark uint name_len; int offset; uint version; + bool loaded; char key[1]; }; @@ -778,7 +779,7 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report) if (global_system_variables.log_warnings > 2) { struct link_map *lm = (struct link_map*) plugin_dl.handle; - sql_print_information("Loaded '%s' with offset 0x%lx", dl->str, lm->l_addr); + sql_print_information("Loaded '%s' with offset 0x%zx", dl->str, (size_t)lm->l_addr); } #endif @@ -981,8 +982,8 @@ static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref rc, *plugin= pi; #endif pi->ref_count++; - DBUG_PRINT("lock",("thd: 0x%lx plugin: \"%s\" LOCK ref_count: %d", - (long) current_thd, pi->name.str, pi->ref_count)); + 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); @@ -1178,6 +1179,13 @@ err: DBUG_RETURN(errs > 0 || oks + dupes == 0); } +static void plugin_variables_deinit(struct st_plugin_int *plugin) +{ + + for (sys_var *var= plugin->system_vars; var; var= var->next) + (*var->test_load)= FALSE; + mysql_del_sys_var_chain(plugin->system_vars); +} static void plugin_deinitialize(struct st_plugin_int *plugin, bool ref_check) { @@ -1229,8 +1237,7 @@ static void plugin_deinitialize(struct st_plugin_int *plugin, bool ref_check) if (ref_check && plugin->ref_count) sql_print_error("Plugin '%s' has ref_count=%d after deinitialization.", plugin->name.str, plugin->ref_count); - - mysql_del_sys_var_chain(plugin->system_vars); + plugin_variables_deinit(plugin); } static void plugin_del(struct st_plugin_int *plugin) @@ -1335,8 +1342,8 @@ static void intern_plugin_unlock(LEX *lex, plugin_ref plugin) DBUG_ASSERT(pi->ref_count); pi->ref_count--; - DBUG_PRINT("lock",("thd: 0x%lx plugin: \"%s\" UNLOCK ref_count: %d", - (long) current_thd, pi->name.str, pi->ref_count)); + 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; @@ -1393,10 +1400,10 @@ static int plugin_initialize(MEM_ROOT *tmp_root, struct st_plugin_int *plugin, mysql_mutex_unlock(&LOCK_plugin); - mysql_rwlock_wrlock(&LOCK_system_variables_hash); + mysql_prlock_wrlock(&LOCK_system_variables_hash); if (test_plugin_options(tmp_root, plugin, argc, argv)) state= PLUGIN_IS_DISABLED; - mysql_rwlock_unlock(&LOCK_system_variables_hash); + mysql_prlock_unlock(&LOCK_system_variables_hash); if (options_only || state == PLUGIN_IS_DISABLED) { @@ -1449,7 +1456,7 @@ static int plugin_initialize(MEM_ROOT *tmp_root, struct st_plugin_int *plugin, err: if (ret) - mysql_del_sys_var_chain(plugin->system_vars); + plugin_variables_deinit(plugin); mysql_mutex_lock(&LOCK_plugin); plugin->state= state; @@ -1542,19 +1549,23 @@ int plugin_init(int *argc, char **argv, int flags) init_alloc_root(&plugin_vars_mem_root, 4096, 4096, MYF(0)); init_alloc_root(&tmp_root, 4096, 4096, MYF(0)); - if (my_hash_init(&bookmark_hash, &my_charset_bin, 16, 0, 0, + if (my_hash_init(&bookmark_hash, &my_charset_bin, 32, 0, 0, get_bookmark_hash_key, NULL, HASH_UNIQUE)) goto err; + /* + The 80 is from 2016-04-27 when we had 71 default plugins + Big enough to avoid many mallocs even in future + */ if (my_init_dynamic_array(&plugin_dl_array, sizeof(struct st_plugin_dl *), 16, 16, MYF(0)) || my_init_dynamic_array(&plugin_array, - sizeof(struct st_plugin_int *), 16, 16, MYF(0))) + sizeof(struct st_plugin_int *), 80, 32, MYF(0))) goto err; for (i= 0; i < MYSQL_MAX_PLUGIN_TYPE_NUM; i++) { - if (my_hash_init(&plugin_hash[i], system_charset_info, 16, 0, 0, + if (my_hash_init(&plugin_hash[i], system_charset_info, 32, 0, 0, get_plugin_hash_key, NULL, HASH_UNIQUE)) goto err; } @@ -1766,7 +1777,7 @@ static void plugin_load(MEM_ROOT *tmp_root) TABLE *table; READ_RECORD read_record_info; int error; - THD *new_thd= new THD; + THD *new_thd= new THD(0); bool result; DBUG_ENTER("plugin_load"); @@ -1797,7 +1808,8 @@ static void plugin_load(MEM_ROOT *tmp_root) goto end; } - if (init_read_record(&read_record_info, new_thd, table, NULL, 1, 0, FALSE)) + if (init_read_record(&read_record_info, new_thd, table, NULL, NULL, 1, 0, + FALSE)) { sql_print_error("Could not initialize init_read_record; Plugins not " "loaded"); @@ -2158,8 +2170,8 @@ bool mysql_install_plugin(THD *thd, const LEX_STRING *name, See also mysql_uninstall_plugin() and initialize_audit_plugin() */ - - mysql_audit_acquire_plugins(thd, event_class_mask); + if (mysql_audit_general_enabled()) + mysql_audit_acquire_plugins(thd, event_class_mask); mysql_mutex_lock(&LOCK_plugin); error= plugin_add(thd->mem_root, name, &dl, REPORT_TO_USER); @@ -2305,7 +2317,8 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name, See also mysql_install_plugin() and initialize_audit_plugin() */ - mysql_audit_acquire_plugins(thd, event_class_mask); + if (mysql_audit_general_enabled()) + mysql_audit_acquire_plugins(thd, event_class_mask); mysql_mutex_lock(&LOCK_plugin); @@ -2791,20 +2804,22 @@ static void update_func_double(THD *thd, struct st_mysql_sys_var *var, System Variables support ****************************************************************************/ - -sys_var *find_sys_var(THD *thd, const char *str, uint length) +sys_var *find_sys_var_ex(THD *thd, const char *str, size_t length, + bool throw_error, bool locked) { sys_var *var; sys_var_pluginvar *pi= NULL; plugin_ref plugin; - DBUG_ENTER("find_sys_var"); + DBUG_ENTER("find_sys_var_ex"); + DBUG_PRINT("enter", ("var '%.*s'", (int)length, str)); - mysql_mutex_lock(&LOCK_plugin); - mysql_rwlock_rdlock(&LOCK_system_variables_hash); + if (!locked) + mysql_mutex_lock(&LOCK_plugin); + mysql_prlock_rdlock(&LOCK_system_variables_hash); if ((var= intern_find_sys_var(str, length)) && (pi= var->cast_pluginvar())) { - mysql_rwlock_unlock(&LOCK_system_variables_hash); + mysql_prlock_unlock(&LOCK_system_variables_hash); LEX *lex= thd ? thd->lex : 0; if (!(plugin= intern_plugin_lock(lex, plugin_int_to_ref(pi->plugin)))) var= NULL; /* failed to lock it, it must be uninstalling */ @@ -2817,15 +2832,21 @@ sys_var *find_sys_var(THD *thd, const char *str, uint length) } } else - mysql_rwlock_unlock(&LOCK_system_variables_hash); - mysql_mutex_unlock(&LOCK_plugin); + mysql_prlock_unlock(&LOCK_system_variables_hash); + if (!locked) + mysql_mutex_unlock(&LOCK_plugin); - if (!var) - my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str); + if (!throw_error && !var) + my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (int)length, (char*) str); DBUG_RETURN(var); } +sys_var *find_sys_var(THD *thd, const char *str, size_t length) +{ + return find_sys_var_ex(thd, str, length, false, false); +} + /* called by register_var, construct_options and test_plugin_options. Returns the 'bookmark' for the named variable. @@ -3040,9 +3061,9 @@ static uchar *intern_sys_var_ptr(THD* thd, int offset, bool global_lock) if (!thd->variables.dynamic_variables_ptr || (uint)offset > thd->variables.dynamic_variables_head) { - mysql_rwlock_rdlock(&LOCK_system_variables_hash); + mysql_prlock_rdlock(&LOCK_system_variables_hash); sync_dynamic_session_variables(thd, global_lock); - mysql_rwlock_unlock(&LOCK_system_variables_hash); + mysql_prlock_unlock(&LOCK_system_variables_hash); } DBUG_RETURN((uchar*)thd->variables.dynamic_variables_ptr + offset); } @@ -3157,7 +3178,7 @@ static void cleanup_variables(struct system_variables *vars) st_bookmark *v; uint idx; - mysql_rwlock_rdlock(&LOCK_system_variables_hash); + mysql_prlock_rdlock(&LOCK_system_variables_hash); for (idx= 0; idx < bookmark_hash.records; idx++) { v= (st_bookmark*) my_hash_element(&bookmark_hash, idx); @@ -3176,7 +3197,7 @@ static void cleanup_variables(struct system_variables *vars) *ptr= NULL; } } - mysql_rwlock_unlock(&LOCK_system_variables_hash); + mysql_prlock_unlock(&LOCK_system_variables_hash); DBUG_ASSERT(vars->table_plugin == NULL); DBUG_ASSERT(vars->tmp_table_plugin == NULL); @@ -3241,8 +3262,8 @@ static void plugin_vars_free_values(sys_var *vars) { /* Free the string from global_system_variables. */ char **valptr= (char**) piv->real_value_ptr(NULL, OPT_GLOBAL); - DBUG_PRINT("plugin", ("freeing value for: '%s' addr: 0x%lx", - var->name.str, (long) valptr)); + DBUG_PRINT("plugin", ("freeing value for: '%s' addr: %p", + var->name.str, valptr)); my_free(*valptr); *valptr= NULL; } @@ -3305,14 +3326,14 @@ uchar* sys_var_pluginvar::real_value_ptr(THD *thd, enum_var_type type) { switch (plugin_var->flags & PLUGIN_VAR_TYPEMASK) { case PLUGIN_VAR_BOOL: - thd->sys_var_tmp.my_bool_value= option.def_value; + thd->sys_var_tmp.my_bool_value= (my_bool)option.def_value; return (uchar*) &thd->sys_var_tmp.my_bool_value; case PLUGIN_VAR_INT: - thd->sys_var_tmp.int_value= option.def_value; + thd->sys_var_tmp.int_value= (int)option.def_value; return (uchar*) &thd->sys_var_tmp.int_value; case PLUGIN_VAR_LONG: case PLUGIN_VAR_ENUM: - thd->sys_var_tmp.long_value= option.def_value; + thd->sys_var_tmp.long_value= (long)option.def_value; return (uchar*) &thd->sys_var_tmp.long_value; case PLUGIN_VAR_LONGLONG: case PLUGIN_VAR_SET: @@ -3931,6 +3952,14 @@ my_bool mark_changed(int, const struct my_option *opt, char *) } /** + It is always false to mark global plugin variable unloaded just to be + safe because we have no way now to know truth about them. + + TODO: make correct mechanism for global plugin variables +*/ +static bool static_unload= FALSE; + +/** Create and register system variables supplied from the plugin and assigns initial values from corresponding command line arguments. @@ -4007,9 +4036,13 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp, tmp_backup[tmp->nbackups++].save(&o->name); if ((var= find_bookmark(tmp->name.str, o->name, o->flags))) + { varname= var->key + 1; + var->loaded= TRUE; + } else { + var= NULL; len= tmp->name.length + strlen(o->name) + 2; varname= (char*) alloc_root(mem_root, len); strxmov(varname, tmp->name.str, "-", o->name, NullS); @@ -4017,6 +4050,9 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp, convert_dash_to_underscore(varname, len-1); } v= new (mem_root) sys_var_pluginvar(&chain, varname, tmp, o); + v->test_load= (var ? &var->loaded : &static_unload); + DBUG_ASSERT(static_unload == FALSE); + if (!(o->flags & PLUGIN_VAR_NOCMDOPT)) { // update app_type, used for I_S.SYSTEM_VARIABLES @@ -4217,10 +4253,10 @@ int thd_key_create(MYSQL_THD_KEY_T *key) PLUGIN_VAR_NOSYSVAR | PLUGIN_VAR_NOCMDOPT; char namebuf[256]; snprintf(namebuf, sizeof(namebuf), "%u", thd_key_no++); - mysql_rwlock_wrlock(&LOCK_system_variables_hash); + mysql_prlock_wrlock(&LOCK_system_variables_hash); // non-letters in the name as an extra safety st_bookmark *bookmark= register_var("\a\v\a\t\a\r", namebuf, flags); - mysql_rwlock_unlock(&LOCK_system_variables_hash); + mysql_prlock_unlock(&LOCK_system_variables_hash); if (bookmark) { *key= bookmark->offset; |