| 2282 | } |
| 2283 | |
| 2284 | bool mysql_install_plugin(THD *thd, const LEX_CSTRING *name, |
| 2285 | const LEX_CSTRING *dl_arg) |
| 2286 | { |
| 2287 | TABLE_LIST tables; |
| 2288 | TABLE *table; |
| 2289 | LEX_CSTRING dl= *dl_arg; |
| 2290 | enum install_status error; |
| 2291 | int argc=orig_argc; |
| 2292 | char **argv=orig_argv; |
| 2293 | unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE] = |
| 2294 | { MYSQL_AUDIT_GENERAL_CLASSMASK }; |
| 2295 | DBUG_ENTER("mysql_install_plugin"); |
| 2296 | |
| 2297 | tables.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_PLUGIN_NAME, 0, TL_WRITE); |
| 2298 | if (!opt_noacl && check_table_access(thd, INSERT_ACL, &tables, FALSE, 1, FALSE)) |
| 2299 | DBUG_RETURN(TRUE); |
| 2300 | WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL); |
| 2301 | |
| 2302 | /* need to open before acquiring LOCK_plugin or it will deadlock */ |
| 2303 | table= open_ltable(thd, &tables, TL_WRITE, MYSQL_LOCK_IGNORE_TIMEOUT); |
| 2304 | if (!table || !plugin_table_is_valid(table)) |
| 2305 | DBUG_RETURN(TRUE); |
| 2306 | |
| 2307 | if (my_load_defaults(MYSQL_CONFIG_NAME, load_default_groups, &argc, &argv, NULL)) |
| 2308 | { |
| 2309 | my_error(ER_PLUGIN_IS_NOT_LOADED, MYF(0), name->str); |
| 2310 | DBUG_RETURN(TRUE); |
| 2311 | } |
| 2312 | |
| 2313 | /* |
| 2314 | Pre-acquire audit plugins for events that may potentially occur |
| 2315 | during [UN]INSTALL PLUGIN. |
| 2316 | |
| 2317 | When audit event is triggered, audit subsystem acquires interested |
| 2318 | plugins by walking through plugin list. Evidently plugin list |
| 2319 | iterator protects plugin list by acquiring LOCK_plugin, see |
| 2320 | plugin_foreach_with_mask(). |
| 2321 | |
| 2322 | On the other hand [UN]INSTALL PLUGIN is acquiring LOCK_plugin |
| 2323 | rather for a long time. |
| 2324 | |
| 2325 | When audit event is triggered during [UN]INSTALL PLUGIN, plugin |
| 2326 | list iterator acquires the same lock (within the same thread) |
| 2327 | second time. |
| 2328 | |
| 2329 | This hack should be removed when LOCK_plugin is fixed so it |
| 2330 | protects only what it supposed to protect. |
| 2331 | |
| 2332 | See also mysql_uninstall_plugin() and initialize_audit_plugin() |
| 2333 | */ |
| 2334 | if (mysql_audit_general_enabled()) |
| 2335 | mysql_audit_acquire_plugins(thd, event_class_mask); |
| 2336 | |
| 2337 | mysql_mutex_lock(&LOCK_plugin); |
| 2338 | DEBUG_SYNC(thd, "acquired_LOCK_plugin"); |
| 2339 | error= plugin_add(thd->mem_root, thd->lex->create_info.if_not_exists(), |
| 2340 | name, &dl, MYF(0)); |
| 2341 | if (unlikely(error != INSTALL_GOOD)) |
no test coverage detected