From 37afe1b34a20ffebe98381629ec615bd5957518a Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Mon, 27 Sep 2010 16:55:09 +0400 Subject: [PATCH 1/2] 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. --- mysql-test/r/plugin_load_option.result | 2 ++ mysql-test/t/plugin_load_option-master.opt | 3 ++ mysql-test/t/plugin_load_option.test | 5 +++ sql/share/errmsg-utf8.txt | 2 ++ sql/sql_plugin.cc | 39 +++++++++++++--------- sql/sql_plugin.h | 7 +++- 6 files changed, 42 insertions(+), 16 deletions(-) create mode 100644 mysql-test/r/plugin_load_option.result create mode 100644 mysql-test/t/plugin_load_option-master.opt create mode 100644 mysql-test/t/plugin_load_option.test diff --git a/mysql-test/r/plugin_load_option.result b/mysql-test/r/plugin_load_option.result new file mode 100644 index 00000000000..3e49e3c6b47 --- /dev/null +++ b/mysql-test/r/plugin_load_option.result @@ -0,0 +1,2 @@ +UNINSTALL PLUGIN example; +ERROR HY000: Plugin 'example' is force_plus_permanent and can not be unloaded diff --git a/mysql-test/t/plugin_load_option-master.opt b/mysql-test/t/plugin_load_option-master.opt new file mode 100644 index 00000000000..3be53c3b713 --- /dev/null +++ b/mysql-test/t/plugin_load_option-master.opt @@ -0,0 +1,3 @@ +$EXAMPLE_PLUGIN_OPT +$EXAMPLE_PLUGIN_LOAD +--plugin-example=FORCE_PLUS_PERMANENT diff --git a/mysql-test/t/plugin_load_option.test b/mysql-test/t/plugin_load_option.test new file mode 100644 index 00000000000..604be30b561 --- /dev/null +++ b/mysql-test/t/plugin_load_option.test @@ -0,0 +1,5 @@ +--source include/not_windows_embedded.inc +--source include/have_example_plugin.inc + +--error ER_PLUGIN_IS_PERMANENT +UNINSTALL PLUGIN example; diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 9e7fdbfeae5..b01b824f236 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -6346,3 +6346,5 @@ ER_STORED_FUNCTION_PREVENTS_SWITCH_SQL_LOG_BIN ER_FAILED_READ_FROM_PAR_FILE eng "Failed to read from the .par file" swe "Misslyckades läsa från .par filen" +ER_PLUGIN_IS_PERMANENT + eng "Plugin '%s' is force_plus_permanent and can not be unloaded" diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 956be657af2..71e2f844168 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -41,9 +41,8 @@ extern struct st_mysql_plugin *mysql_mandatory_plugins[]; @note The order of the enumeration is critical. @see construct_options */ -static const char *global_plugin_typelib_names[]= - { "OFF", "ON", "FORCE", NULL }; -enum enum_plugin_load_policy {PLUGIN_OFF, PLUGIN_ON, PLUGIN_FORCE}; +const char *global_plugin_typelib_names[]= + { "OFF", "ON", "FORCE", "FORCE_PLUS_PERMANENT", NULL }; static TYPELIB global_plugin_typelib= { array_elements(global_plugin_typelib_names)-1, "", global_plugin_typelib_names, NULL }; @@ -796,6 +795,7 @@ static bool plugin_add(MEM_ROOT *tmp_root, tmp.name.length= name_len; tmp.ref_count= 0; tmp.state= PLUGIN_IS_UNINITIALIZED; + tmp.load_option= PLUGIN_ON; if (test_plugin_options(tmp_root, &tmp, argc, argv)) tmp.state= PLUGIN_IS_DISABLED; @@ -1237,7 +1237,7 @@ int plugin_init(int *argc, char **argv, int flags) tmp.name.str= (char *)plugin->name; tmp.name.length= strlen(plugin->name); tmp.state= 0; - tmp.is_mandatory= mandatory; + tmp.load_option= mandatory ? PLUGIN_FORCE : PLUGIN_ON; /* If the performance schema is compiled in, @@ -1256,7 +1256,7 @@ int plugin_init(int *argc, char **argv, int flags) to work, by using '--skip-performance-schema' (the plugin) */ 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)); if (test_plugin_options(&tmp_root, &tmp, argc, argv)) @@ -1334,7 +1334,8 @@ int plugin_init(int *argc, char **argv, int flags) while ((plugin_ptr= *(--reap))) { 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; plugin_deinitialize(plugin_ptr, true); mysql_mutex_lock(&LOCK_plugin); @@ -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); 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; if (plugin->ref_count) @@ -3054,7 +3060,8 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp, plugin_dash.length + 1); 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 */ options[0].name= plugin_name_ptr; @@ -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 }; 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) ? &tmp->mem_root : &plugin_mem_root; @@ -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") && 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++) 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, We adjust the default value to account for the hardcoded exceptions we have set for the federated and ndbcluster storage engines. */ - if (!tmp->is_mandatory) - opts[0].def_value= opts[1].def_value= plugin_load_policy; + if (tmp->load_option != PLUGIN_FORCE && + 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); (*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, Set plugin loading policy from option value. First element in the option list is always the option value. */ - if (!tmp->is_mandatory) - plugin_load_policy= (enum_plugin_load_policy)*(ulong*)opts[0].value; + if (tmp->load_option != PLUGIN_FORCE && + 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); - tmp->is_mandatory= (plugin_load_policy == PLUGIN_FORCE); + disable_plugin= (plugin_load_option == PLUGIN_OFF); + tmp->load_option= plugin_load_option; /* If the plugin is disabled it should not be initialized. diff --git a/sql/sql_plugin.h b/sql/sql_plugin.h index 079dc4e6dca..5fa9afb3066 100644 --- a/sql/sql_plugin.h +++ b/sql/sql_plugin.h @@ -32,6 +32,9 @@ class sys_var; 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 @@ -95,7 +98,7 @@ struct st_plugin_int void *data; /* plugin type specific, e.g. handlerton */ MEM_ROOT mem_root; /* memory for dynamic plugin structures */ 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; #define plugin_data(pi,cast) ((cast)((pi)->data)) #define plugin_name(pi) (&((pi)->name)) #define plugin_state(pi) ((pi)->state) +#define plugin_load_option(pi) ((pi)->load_option) #define plugin_equals(p1,p2) ((p1) == (p2)) #else 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_name(pi) (&((pi)[0]->name)) #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]) #endif From d9aa82154b02ec2e6bccb0048f9e0c94b6b0af6b Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Mon, 27 Sep 2010 17:03:27 +0400 Subject: [PATCH 2/2] WL#5496 - Plugin LOAD_OPTION in INFORMATION_SCHEMA.PLUGINS This patch implements I_S.PLUGINS.LOAD_OPTION column as specified by WL#5496. mysql-test/r/plugin_load_option.result: A test case for WL#5496. mysql-test/suite/funcs_1/r/is_columns_is.result: Adjusted a test case according to WL#5496. mysql-test/t/plugin_load_option.test: A test case for WL#5496. sql/sql_show.cc: Added LOAD_OPTION column to I_S.PLUGINS. --- mysql-test/r/plugin_load_option.result | 5 +++++ mysql-test/suite/funcs_1/r/is_columns_is.result | 2 ++ mysql-test/t/plugin_load_option.test | 3 +++ sql/sql_show.cc | 6 ++++++ 4 files changed, 16 insertions(+) diff --git a/mysql-test/r/plugin_load_option.result b/mysql-test/r/plugin_load_option.result index 3e49e3c6b47..fec41bac8e6 100644 --- a/mysql-test/r/plugin_load_option.result +++ b/mysql-test/r/plugin_load_option.result @@ -1,2 +1,7 @@ UNINSTALL PLUGIN example; ERROR HY000: Plugin 'example' is force_plus_permanent and can not be unloaded +SELECT PLUGIN_NAME, PLUGIN_STATUS, LOAD_OPTION FROM INFORMATION_SCHEMA.PLUGINS +WHERE PLUGIN_NAME IN ('MyISAM', 'EXAMPLE'); +PLUGIN_NAME PLUGIN_STATUS LOAD_OPTION +MyISAM ACTIVE FORCE +EXAMPLE ACTIVE FORCE_PLUS_PERMANENT diff --git a/mysql-test/suite/funcs_1/r/is_columns_is.result b/mysql-test/suite/funcs_1/r/is_columns_is.result index ea13b8619ce..ba64ea0887e 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_is.result +++ b/mysql-test/suite/funcs_1/r/is_columns_is.result @@ -165,6 +165,7 @@ def information_schema PARTITIONS TABLE_NAME 3 NO varchar 64 192 NULL NULL utf8 def information_schema PARTITIONS TABLE_ROWS 13 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select def information_schema PARTITIONS TABLE_SCHEMA 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select def information_schema PARTITIONS UPDATE_TIME 20 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select +def information_schema PLUGINS LOAD_OPTION 11 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select def information_schema PLUGINS PLUGIN_AUTHOR 8 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select def information_schema PLUGINS PLUGIN_DESCRIPTION 9 NULL YES longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext select def information_schema PLUGINS PLUGIN_LIBRARY 6 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select @@ -562,6 +563,7 @@ NULL information_schema PARTITIONS CHECKSUM bigint NULL NULL NULL NULL bigint(21 3.0000 information_schema PLUGINS PLUGIN_AUTHOR varchar 64 192 utf8 utf8_general_ci varchar(64) 1.0000 information_schema PLUGINS PLUGIN_DESCRIPTION longtext 4294967295 4294967295 utf8 utf8_general_ci longtext 3.0000 information_schema PLUGINS PLUGIN_LICENSE varchar 80 240 utf8 utf8_general_ci varchar(80) +3.0000 information_schema PLUGINS LOAD_OPTION varchar 64 192 utf8 utf8_general_ci varchar(64) NULL information_schema PROCESSLIST ID bigint NULL NULL NULL NULL bigint(4) 3.0000 information_schema PROCESSLIST USER varchar 16 48 utf8 utf8_general_ci varchar(16) 3.0000 information_schema PROCESSLIST HOST varchar 64 192 utf8 utf8_general_ci varchar(64) diff --git a/mysql-test/t/plugin_load_option.test b/mysql-test/t/plugin_load_option.test index 604be30b561..e49b693b5be 100644 --- a/mysql-test/t/plugin_load_option.test +++ b/mysql-test/t/plugin_load_option.test @@ -3,3 +3,6 @@ --error ER_PLUGIN_IS_PERMANENT UNINSTALL PLUGIN example; + +SELECT PLUGIN_NAME, PLUGIN_STATUS, LOAD_OPTION FROM INFORMATION_SCHEMA.PLUGINS +WHERE PLUGIN_NAME IN ('MyISAM', 'EXAMPLE'); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 6b24e3db7bc..10b918b2505 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -211,6 +211,11 @@ static my_bool show_plugins(THD *thd, plugin_ref plugin, } table->field[9]->set_notnull(); + table->field[10]->store( + global_plugin_typelib_names[plugin_load_option(plugin)], + strlen(global_plugin_typelib_names[plugin_load_option(plugin)]), + cs); + return schema_table_store_record(thd, table); } @@ -7214,6 +7219,7 @@ ST_FIELD_INFO plugin_fields_info[]= {"PLUGIN_AUTHOR", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, {"PLUGIN_DESCRIPTION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE}, {"PLUGIN_LICENSE", 80, MYSQL_TYPE_STRING, 0, 1, "License", SKIP_OPEN_TABLE}, + {"LOAD_OPTION", 64, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} };