diff options
author | Sergey Vojtovich <svoj@sun.com> | 2010-08-20 13:58:28 +0400 |
---|---|---|
committer | Sergey Vojtovich <svoj@sun.com> | 2010-08-20 13:58:28 +0400 |
commit | b51c8cab3e0afccd6b44fea70e59243b24844158 (patch) | |
tree | e850824b3144dbcdd2a6f5ae296157e5713a9d67 /sql/sql_audit.cc | |
parent | e28d6ee66a8404dd0f8fe3aaabb9d72544e5d42e (diff) | |
download | mariadb-git-b51c8cab3e0afccd6b44fea70e59243b24844158.tar.gz |
BUG#54989 - With null_audit installed, server hangs on an
attempt to install a plugin twice
Server crashes when [UN]INSTALL PLUGIN fails (returns an
error) and general log is disabled and there are audit
plugins interested in MYSQL_AUDIT_GENERAL_CLASS.
When audit event is triggered, audit subsystem acquires interested
plugins by walking through plugin list. Evidently plugin list
iterator protects plugin list by acquiring LOCK_plugin, see
plugin_foreach_with_mask().
On the other hand [UN]INSTALL PLUGIN is acquiring LOCK_plugin
rather for a long time.
When audit event is triggered during [UN]INSTALL PLUGIN, plugin
list iterator acquires the same lock (within the same thread)
second time.
Repeatable only with general_log disabled, because general_log
triggers MYSQL_AUDIT_GENERAL_LOG event, which acquires audit
plugins before [UN]INSTALL PLUGIN acquired LOCK_plugin.
With this fix we pre-acquire audit plugins for events that
may potentially occur during [UN]INSTALL PLUGIN.
This hack should be removed when LOCK_plugin is fixed so it
protects only what it supposed to protect.
No test case for this fix - we do not have facility to test
audit plugins yet.
sql/sql_audit.cc:
Move "acquire audit plugin" logics to a separate
function.
sql/sql_audit.h:
Move "acquire audit plugin" logics to a separate
function.
sql/sql_plugin.cc:
Pre-acquire audit plugins for events that may potentially occur
during [UN]INSTALL PLUGIN.
Diffstat (limited to 'sql/sql_audit.cc')
-rw-r--r-- | sql/sql_audit.cc | 44 |
1 files changed, 30 insertions, 14 deletions
diff --git a/sql/sql_audit.cc b/sql/sql_audit.cc index 7d269d455a9..b7d363dc09a 100644 --- a/sql/sql_audit.cc +++ b/sql/sql_audit.cc @@ -138,6 +138,30 @@ static my_bool acquire_plugins(THD *thd, plugin_ref plugin, void *arg) /** + @brief Acquire audit plugins + + @param[in] thd MySQL thread handle + @param[in] event_class Audit event class + + @details Ensure that audit plugins interested in given event + class are locked by current thread. +*/ +void mysql_audit_acquire_plugins(THD *thd, uint event_class) +{ + unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE]; + DBUG_ENTER("mysql_audit_acquire_plugins"); + set_audit_mask(event_class_mask, event_class); + if (thd && !check_audit_mask(mysql_global_audit_mask, event_class_mask) && + check_audit_mask(thd->audit_class_mask, event_class_mask)) + { + plugin_foreach(thd, acquire_plugins, MYSQL_AUDIT_PLUGIN, &event_class); + add_audit_mask(thd->audit_class_mask, event_class_mask); + } + DBUG_VOID_RETURN; +} + + +/** Notify the audit system of an event @param[in] thd @@ -151,21 +175,8 @@ void mysql_audit_notify(THD *thd, uint event_class, uint event_subtype, ...) { va_list ap; audit_handler_t *handlers= audit_handlers + event_class; - unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE]; - DBUG_ASSERT(event_class < audit_handlers_count); - - set_audit_mask(event_class_mask, event_class); - /* - Check to see if we have acquired the audit plugins for the - required audit event classes. - */ - if (thd && check_audit_mask(thd->audit_class_mask, event_class_mask)) - { - plugin_foreach(thd, acquire_plugins, MYSQL_AUDIT_PLUGIN, &event_class); - add_audit_mask(thd->audit_class_mask, event_class_mask); - } - + mysql_audit_acquire_plugins(thd, event_class); va_start(ap, event_subtype); (*handlers)(thd, event_subtype, ap); va_end(ap); @@ -448,6 +459,11 @@ static void event_class_dispatch(THD *thd, const struct mysql_event *event) #else /* EMBEDDED_LIBRARY */ +void mysql_audit_acquire_plugins(THD *thd, uint event_class) +{ +} + + void mysql_audit_initialize() { } |