Commit a8d97fb8 authored by Sergey Vojtovich's avatar Sergey Vojtovich

MDEV-9651 - Simplify audit event dispatching

Simplified audit event dispatching call chain from:
  mysql_audit_notify_connection_connect() // can be inlined
  mysql_audit_notify()                    // can't be inlined
  connection_class_handler()              // can't be inlined
  event_class_dispatch()                  // can be inlined
  plugins_dispatch()                      // can be inlined
  plugin->event_notify()                  // can't be inlined
to:
  mysql_audit_notify_connection_connect() // can be inlined
  mysql_audit_notify()                    // can't be inlined
  plugins_dispatch()                      // can be inlined
  plugin->event_notify()                  // can't be inlined
parent e9f6c816
...@@ -56,7 +56,7 @@ struct mysql_event_general ...@@ -56,7 +56,7 @@ struct mysql_event_general
unsigned int general_command_length; unsigned int general_command_length;
const char *general_query; const char *general_query;
unsigned int general_query_length; unsigned int general_query_length;
struct charset_info_st *general_charset; const struct charset_info_st *general_charset;
unsigned long long general_time; unsigned long long general_time;
unsigned long long general_rows; unsigned long long general_rows;
/* Added in version 0x302 */ /* Added in version 0x302 */
......
...@@ -422,7 +422,7 @@ struct mysql_event_general ...@@ -422,7 +422,7 @@ struct mysql_event_general
unsigned int general_command_length; unsigned int general_command_length;
const char *general_query; const char *general_query;
unsigned int general_query_length; unsigned int general_query_length;
struct charset_info_st *general_charset; const struct charset_info_st *general_charset;
unsigned long long general_time; unsigned long long general_time;
unsigned long long general_rows; unsigned long long general_rows;
unsigned long long query_id; unsigned long long query_id;
......
...@@ -24,6 +24,7 @@ extern int finalize_audit_plugin(st_plugin_int *plugin); ...@@ -24,6 +24,7 @@ extern int finalize_audit_plugin(st_plugin_int *plugin);
struct st_mysql_event_generic struct st_mysql_event_generic
{ {
unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE];
unsigned int event_class; unsigned int event_class;
const void *event; const void *event;
}; };
...@@ -32,8 +33,6 @@ unsigned long mysql_global_audit_mask[MYSQL_AUDIT_CLASS_MASK_SIZE]; ...@@ -32,8 +33,6 @@ unsigned long mysql_global_audit_mask[MYSQL_AUDIT_CLASS_MASK_SIZE];
static mysql_mutex_t LOCK_audit_mask; static mysql_mutex_t LOCK_audit_mask;
static void event_class_dispatch(THD *, unsigned int, const void *);
static inline static inline
void set_audit_mask(unsigned long *mask, uint event_class) void set_audit_mask(unsigned long *mask, uint event_class)
...@@ -56,101 +55,6 @@ bool check_audit_mask(const unsigned long *lhs, ...@@ -56,101 +55,6 @@ bool check_audit_mask(const unsigned long *lhs,
} }
typedef void (*audit_handler_t)(THD *thd, uint event_subtype, va_list ap);
/**
MYSQL_AUDIT_GENERAL_CLASS handler
@param[in] thd
@param[in] event_subtype
@param[in] error_code
@param[in] ap
*/
static void general_class_handler(THD *thd, uint event_subtype, va_list ap)
{
mysql_event_general event;
event.event_subclass= event_subtype;
event.general_error_code= va_arg(ap, int);
event.general_thread_id= thd ? thd->thread_id : 0;
event.general_time= va_arg(ap, time_t);
event.general_user= va_arg(ap, const char *);
event.general_user_length= va_arg(ap, unsigned int);
event.general_command= va_arg(ap, const char *);
event.general_command_length= va_arg(ap, unsigned int);
event.general_query= va_arg(ap, const char *);
event.general_query_length= va_arg(ap, unsigned int);
event.general_charset= va_arg(ap, struct charset_info_st *);
event.general_rows= (unsigned long long) va_arg(ap, ha_rows);
event.database= va_arg(ap, const char *);
event.database_length= va_arg(ap, unsigned int);
event.query_id= (unsigned long long) (thd ? thd->query_id : 0);
event_class_dispatch(thd, MYSQL_AUDIT_GENERAL_CLASS, &event);
}
static void connection_class_handler(THD *thd, uint event_subclass, va_list ap)
{
mysql_event_connection event;
event.event_subclass= event_subclass;
event.status= va_arg(ap, int);
event.thread_id= (unsigned long) va_arg(ap, long long);
event.user= va_arg(ap, const char *);
event.user_length= va_arg(ap, unsigned int);
event.priv_user= va_arg(ap, const char *);
event.priv_user_length= va_arg(ap, unsigned int);
event.external_user= va_arg(ap, const char *);
event.external_user_length= va_arg(ap, unsigned int);
event.proxy_user= va_arg(ap, const char *);
event.proxy_user_length= va_arg(ap, unsigned int);
event.host= va_arg(ap, const char *);
event.host_length= va_arg(ap, unsigned int);
event.ip= va_arg(ap, const char *);
event.ip_length= va_arg(ap, unsigned int);
event.database= va_arg(ap, const char *);
event.database_length= va_arg(ap, unsigned int);
event_class_dispatch(thd, MYSQL_AUDIT_CONNECTION_CLASS, &event);
}
static void table_class_handler(THD *thd, uint event_subclass, va_list ap)
{
mysql_event_table event;
event.event_subclass= event_subclass;
event.read_only= va_arg(ap, int);
event.thread_id= va_arg(ap, unsigned long);
event.user= va_arg(ap, const char *);
event.priv_user= va_arg(ap, const char *);
event.priv_host= va_arg(ap, const char *);
event.external_user= va_arg(ap, const char *);
event.proxy_user= va_arg(ap, const char *);
event.host= va_arg(ap, const char *);
event.ip= va_arg(ap, const char *);
event.database= va_arg(ap, const char *);
event.database_length= va_arg(ap, unsigned int);
event.table= va_arg(ap, const char *);
event.table_length= va_arg(ap, unsigned int);
event.new_database= va_arg(ap, const char *);
event.new_database_length= va_arg(ap, unsigned int);
event.new_table= va_arg(ap, const char *);
event.new_table_length= va_arg(ap, unsigned int);
event.query_id= (unsigned long long) (thd ? thd->query_id : 0);
event_class_dispatch(thd, MYSQL_AUDIT_TABLE_CLASS, &event);
}
static audit_handler_t audit_handlers[] =
{
general_class_handler, connection_class_handler,
0,0,0,0,0,0,0,0,0,0,0,0,0, /* placeholders */
table_class_handler
};
static const uint audit_handlers_count=
(sizeof(audit_handlers) / sizeof(audit_handler_t));
/** /**
Acquire and lock any additional audit plugins as required Acquire and lock any additional audit plugins as required
...@@ -207,38 +111,16 @@ static my_bool acquire_plugins(THD *thd, plugin_ref plugin, void *arg) ...@@ -207,38 +111,16 @@ static my_bool acquire_plugins(THD *thd, plugin_ref plugin, void *arg)
void mysql_audit_acquire_plugins(THD *thd, ulong *event_class_mask) void mysql_audit_acquire_plugins(THD *thd, ulong *event_class_mask)
{ {
DBUG_ENTER("mysql_audit_acquire_plugins"); DBUG_ENTER("mysql_audit_acquire_plugins");
if (thd && !check_audit_mask(mysql_global_audit_mask, event_class_mask) && DBUG_ASSERT(thd);
check_audit_mask(thd->audit_class_mask, event_class_mask)) DBUG_ASSERT(!check_audit_mask(mysql_global_audit_mask, event_class_mask));
if (check_audit_mask(thd->audit_class_mask, event_class_mask))
{ {
plugin_foreach(thd, acquire_plugins, MYSQL_AUDIT_PLUGIN, event_class_mask); plugin_foreach(thd, acquire_plugins, MYSQL_AUDIT_PLUGIN, event_class_mask);
add_audit_mask(thd->audit_class_mask, event_class_mask); add_audit_mask(thd->audit_class_mask, event_class_mask);
} }
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/**
Notify the audit system of an event
@param[in] thd
@param[in] event_class
@param[in] event_subtype
@param[in] error_code
*/
void mysql_audit_notify(THD *thd, uint event_class, uint event_subtype, ...)
{
va_list ap;
audit_handler_t *handlers= audit_handlers + event_class;
DBUG_ASSERT(event_class < audit_handlers_count);
unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE];
set_audit_mask(event_class_mask, event_class);
mysql_audit_acquire_plugins(thd, event_class_mask);
va_start(ap, event_subtype);
(*handlers)(thd, event_subtype, ap);
va_end(ap);
}
/** /**
...@@ -496,17 +378,11 @@ static my_bool plugins_dispatch(THD *thd, plugin_ref plugin, void *arg) ...@@ -496,17 +378,11 @@ static my_bool plugins_dispatch(THD *thd, plugin_ref plugin, void *arg)
{ {
const struct st_mysql_event_generic *event_generic= const struct st_mysql_event_generic *event_generic=
(const struct st_mysql_event_generic *) arg; (const struct st_mysql_event_generic *) arg;
unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE];
st_mysql_audit *data= plugin_data(plugin, struct st_mysql_audit *); st_mysql_audit *data= plugin_data(plugin, struct st_mysql_audit *);
set_audit_mask(event_class_mask, event_generic->event_class);
/* Check to see if the plugin is interested in this event */ /* Check to see if the plugin is interested in this event */
if (check_audit_mask(data->class_mask, event_class_mask)) if (!check_audit_mask(data->class_mask, event_generic->event_class_mask))
return 0; data->event_notify(thd, event_generic->event_class, event_generic->event);
/* Actually notify the plugin */
data->event_notify(thd, event_generic->event_class, event_generic->event);
return 0; return 0;
} }
...@@ -514,17 +390,18 @@ static my_bool plugins_dispatch(THD *thd, plugin_ref plugin, void *arg) ...@@ -514,17 +390,18 @@ static my_bool plugins_dispatch(THD *thd, plugin_ref plugin, void *arg)
/** /**
Distributes an audit event to plug-ins Distributes an audit event to plug-ins
@param[in] thd @param[in] thd
@param[in] event_class
@param[in] event @param[in] event
*/ */
static void event_class_dispatch(THD *thd, unsigned int event_class, void mysql_audit_notify(THD *thd, uint event_class, const void *event)
const void *event)
{ {
struct st_mysql_event_generic event_generic; struct st_mysql_event_generic event_generic;
event_generic.event_class= event_class; event_generic.event_class= event_class;
event_generic.event= event; event_generic.event= event;
set_audit_mask(event_generic.event_class_mask, event_class);
/* /*
Check if we are doing a slow global dispatch. This event occurs when Check if we are doing a slow global dispatch. This event occurs when
thd == NULL as it is not associated with any particular thread. thd == NULL as it is not associated with any particular thread.
...@@ -537,6 +414,8 @@ static void event_class_dispatch(THD *thd, unsigned int event_class, ...@@ -537,6 +414,8 @@ static void event_class_dispatch(THD *thd, unsigned int event_class,
{ {
plugin_ref *plugins, *plugins_last; plugin_ref *plugins, *plugins_last;
mysql_audit_acquire_plugins(thd, event_generic.event_class_mask);
/* Use the cached set of audit plugins */ /* Use the cached set of audit plugins */
plugins= (plugin_ref*) thd->audit_class_plugins.buffer; plugins= (plugin_ref*) thd->audit_class_plugins.buffer;
plugins_last= plugins + thd->audit_class_plugins.elements; plugins_last= plugins + thd->audit_class_plugins.elements;
......
This diff is collapsed.
...@@ -2152,7 +2152,8 @@ bool mysql_install_plugin(THD *thd, const LEX_STRING *name, ...@@ -2152,7 +2152,8 @@ bool mysql_install_plugin(THD *thd, const LEX_STRING *name,
*/ */
unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE] = unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE] =
{ MYSQL_AUDIT_GENERAL_CLASSMASK }; { MYSQL_AUDIT_GENERAL_CLASSMASK };
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); mysql_mutex_lock(&LOCK_plugin);
error= plugin_add(thd->mem_root, name, &dl, REPORT_TO_USER); error= plugin_add(thd->mem_root, name, &dl, REPORT_TO_USER);
...@@ -2282,7 +2283,8 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name, ...@@ -2282,7 +2283,8 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name,
*/ */
unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE] = unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE] =
{ MYSQL_AUDIT_GENERAL_CLASSMASK }; { MYSQL_AUDIT_GENERAL_CLASSMASK };
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); mysql_mutex_lock(&LOCK_plugin);
......
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