Commit 92265da9 authored by Alexey Botchkov's avatar Alexey Botchkov

MDEV-4472 Audit-plugin. Server-related part of the task.

     file_logger became the service.
     Data like query_id now are sent to the audit plugin.
     Fix for MDEV-4770 ported from 10.0.
     Fix added for the read_maria_plugin_info().
     Log rotation can be disabled with 'set rotations=0'.
parent 1e24cdc8
......@@ -198,6 +198,7 @@ extern int errno; /* declare errno */
#endif
#endif /* #ifndef errno */
extern char *home_dir; /* Home directory for user */
extern MYSQL_PLUGIN_IMPORT char *mysql_data_home;
extern const char *my_progname; /* program-name (printed in errors) */
extern const char *my_progname_short; /* like above but without directory */
extern char curr_dir[]; /* Current directory for user */
......
......@@ -25,7 +25,7 @@
#define MYSQL_AUDIT_CLASS_MASK_SIZE 1
#define MYSQL_AUDIT_INTERFACE_VERSION 0x0301
#define MYSQL_AUDIT_INTERFACE_VERSION 0x0302
/*************************************************************************
......@@ -59,6 +59,10 @@ struct mysql_event_general
struct charset_info_st *general_charset;
unsigned long long general_time;
unsigned long long general_rows;
/* Added in version 0x302 */
unsigned long long query_id;
const char *database;
unsigned int database_length;
};
......@@ -140,6 +144,8 @@ struct mysql_event_table
unsigned int new_database_length;
const char *new_table;
unsigned int new_table_length;
/* Added in version 0x302 */
unsigned long long query_id;
};
/*************************************************************************
......
......@@ -92,6 +92,28 @@ extern struct kill_statement_service_st {
enum thd_kill_levels (*thd_kill_level_func)(const void*);
} *thd_kill_statement_service;
enum thd_kill_levels thd_kill_level(const void*);
#include <mysql/service_logger.h>
typedef struct logger_handle_st LOGGER_HANDLE;
extern struct logger_service_st {
void (*logger_init_mutexes)();
LOGGER_HANDLE* (*open)(const char *path,
unsigned long long size_limit,
unsigned int rotations);
int (*close)(LOGGER_HANDLE *log);
int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr);
int (*printf)(LOGGER_HANDLE *log, const char *fmt, ...);
int (*write)(LOGGER_HANDLE *log, const char *buffer, size_t size);
int (*rotate)(LOGGER_HANDLE *log);
} *logger_service;
void logger_init_mutexes();
LOGGER_HANDLE *logger_open(const char *path,
unsigned long long size_limit,
unsigned int rotations);
int logger_close(LOGGER_HANDLE *log);
int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr);
int logger_printf(LOGGER_HANDLE *log, const char *fmt, ...);
int logger_write(LOGGER_HANDLE *log, const char *buffer, size_t size);
int logger_rotate(LOGGER_HANDLE *log);
struct st_mysql_xid {
long formatID;
long gtrid_length;
......@@ -258,6 +280,9 @@ struct mysql_event_general
struct charset_info_st *general_charset;
unsigned long long general_time;
unsigned long long general_rows;
unsigned long long query_id;
const char *database;
unsigned int database_length;
};
struct mysql_event_connection
{
......@@ -299,6 +324,7 @@ struct mysql_event_table
unsigned int new_database_length;
const char *new_table;
unsigned int new_table_length;
unsigned long long query_id;
};
struct st_mysql_audit
{
......
......@@ -92,6 +92,28 @@ extern struct kill_statement_service_st {
enum thd_kill_levels (*thd_kill_level_func)(const void*);
} *thd_kill_statement_service;
enum thd_kill_levels thd_kill_level(const void*);
#include <mysql/service_logger.h>
typedef struct logger_handle_st LOGGER_HANDLE;
extern struct logger_service_st {
void (*logger_init_mutexes)();
LOGGER_HANDLE* (*open)(const char *path,
unsigned long long size_limit,
unsigned int rotations);
int (*close)(LOGGER_HANDLE *log);
int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr);
int (*printf)(LOGGER_HANDLE *log, const char *fmt, ...);
int (*write)(LOGGER_HANDLE *log, const char *buffer, size_t size);
int (*rotate)(LOGGER_HANDLE *log);
} *logger_service;
void logger_init_mutexes();
LOGGER_HANDLE *logger_open(const char *path,
unsigned long long size_limit,
unsigned int rotations);
int logger_close(LOGGER_HANDLE *log);
int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr);
int logger_printf(LOGGER_HANDLE *log, const char *fmt, ...);
int logger_write(LOGGER_HANDLE *log, const char *buffer, size_t size);
int logger_rotate(LOGGER_HANDLE *log);
struct st_mysql_xid {
long formatID;
long gtrid_length;
......
......@@ -92,6 +92,28 @@ extern struct kill_statement_service_st {
enum thd_kill_levels (*thd_kill_level_func)(const void*);
} *thd_kill_statement_service;
enum thd_kill_levels thd_kill_level(const void*);
#include <mysql/service_logger.h>
typedef struct logger_handle_st LOGGER_HANDLE;
extern struct logger_service_st {
void (*logger_init_mutexes)();
LOGGER_HANDLE* (*open)(const char *path,
unsigned long long size_limit,
unsigned int rotations);
int (*close)(LOGGER_HANDLE *log);
int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr);
int (*printf)(LOGGER_HANDLE *log, const char *fmt, ...);
int (*write)(LOGGER_HANDLE *log, const char *buffer, size_t size);
int (*rotate)(LOGGER_HANDLE *log);
} *logger_service;
void logger_init_mutexes();
LOGGER_HANDLE *logger_open(const char *path,
unsigned long long size_limit,
unsigned int rotations);
int logger_close(LOGGER_HANDLE *log);
int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr);
int logger_printf(LOGGER_HANDLE *log, const char *fmt, ...);
int logger_write(LOGGER_HANDLE *log, const char *buffer, size_t size);
int logger_rotate(LOGGER_HANDLE *log);
struct st_mysql_xid {
long formatID;
long gtrid_length;
......
......@@ -60,17 +60,20 @@ extern "C" {
typedef struct logger_handle_st LOGGER_HANDLE;
extern struct logger_service_st {
void (*logger_init_mutexes)();
LOGGER_HANDLE* (*open)(const char *path,
unsigned long long size_limit,
unsigned int rotations);
int (*close)(LOGGER_HANDLE *log);
int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr);
int (*printf)(LOGGER_HANDLE *log, const char *fmt, ...);
int (*write)(LOGGER_HANDLE *log, const char *buffer, size_t size);
int (*rotate)(LOGGER_HANDLE *log);
} *logger_service;
#if 0 /*MYSQL_DYNAMIC_PLUGIN*/
#if MYSQL_DYNAMIC_PLUGIN
#define logger_init_mutexes logger_service->logger_init_mutexes
#define logger_open(path, size_limit, rotations) \
(logger_service->open(path, size_limit, rotations))
#define logger_close(log) (logger_service->close(log))
......@@ -78,17 +81,19 @@ extern struct logger_service_st {
#define logger_vprintf(log, fmt, argptr) (logger_service->\
vprintf(log, fmt, argptr))
#define logger_printf logger_service->printf
#define logger_write(log, buffer, size) \
(logger_service->write(log, buffer, size))
#else
void logger_init_mutexes();
LOGGER_HANDLE *logger_open(const char *path,
unsigned long long size_limit,
unsigned int rotations);
int logger_close(LOGGER_HANDLE *log);
int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr);
int logger_rotate(LOGGER_HANDLE *log);
int logger_printf(LOGGER_HANDLE *log, const char *fmt, ...);
void init_logger_mutexes();
int logger_write(LOGGER_HANDLE *log, const char *buffer, size_t size);
int logger_rotate(LOGGER_HANDLE *log);
#endif
......
......@@ -25,6 +25,7 @@ extern "C" {
#include <mysql/service_progress_report.h>
#include <mysql/service_debug_sync.h>
#include <mysql/service_kill_statement.h>
#include <mysql/service_logger.h>
#ifdef __cplusplus
}
......
......@@ -26,4 +26,5 @@
#define VERSION_progress_report 0x0100
#define VERSION_debug_sync 0x1000
#define VERSION_kill_statement 0x1000
#define VERSION_logger 0x0100
......@@ -22,7 +22,8 @@ SET(MYSQLSERVICES_SOURCES
my_thread_scheduler_service.c
progress_report_service.c
debug_sync_service.c
kill_statement_service.c)
kill_statement_service.c
logger_service.c)
ADD_CONVENIENCE_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES})
INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
......@@ -37,7 +37,7 @@ SET(MYSYS_SOURCES array.c charset-def.c charset.c checksum.c default.c
safemalloc.c my_new.cc
my_atomic.c my_getncpus.c my_safehash.c my_chmod.c my_rnd.c
my_uuid.c wqueue.c waiting_threads.c ma_dyncol.c
my_rdtsc.c my_context.c)
my_rdtsc.c my_context.c file_logger.c)
IF (WIN32)
SET (MYSYS_SOURCES ${MYSYS_SOURCES} my_winthread.c my_wincond.c my_winerr.c my_winfile.c my_windac.c my_conio.c)
......
......@@ -16,11 +16,9 @@
#include "my_global.h"
#include <my_sys.h>
#include "service_logger.h"
#include <mysql/service_logger.h>
#include <my_pthread.h>
extern MYSQL_PLUGIN_IMPORT char *mysql_data_home;
#ifdef HAVE_PSI_INTERFACE
/* These belong to the service initialization */
static PSI_mutex_key key_LOCK_logger_service;
......@@ -51,7 +49,6 @@ LOGGER_HANDLE *logger_open(const char *path,
unsigned int rotations)
{
LOGGER_HANDLE new_log, *l_perm;
/*
I don't think we ever need more rotations,
but if it's so, the rotation procedure should be adapted to it.
......@@ -114,6 +111,9 @@ static int do_rotate(LOGGER_HANDLE *log)
unsigned int i;
char *buf_old, *buf_new, *tmp;
if (log->rotations == 0)
return 0;
memcpy(namebuf, log->path, log->path_len);
buf_new= logname(log, namebuf, log->rotations);
......@@ -147,6 +147,7 @@ int logger_vprintf(LOGGER_HANDLE *log, const char* fmt, va_list ap)
size_t n_bytes;
mysql_mutex_lock(&log->lock);
if (log->rotations > 0)
if ((filesize= my_tell(log->file, MYF(0))) == (my_off_t) -1 ||
((unsigned long long)filesize >= log->size_limit &&
do_rotate(log)))
......@@ -168,6 +169,30 @@ exit:
}
int logger_write(LOGGER_HANDLE *log, const char *buffer, size_t size)
{
int result;
my_off_t filesize;
mysql_mutex_lock(&log->lock);
if (log->rotations > 0)
if ((filesize= my_tell(log->file, MYF(0))) == (my_off_t) -1 ||
((unsigned long long)filesize >= log->size_limit &&
do_rotate(log)))
{
result= -1;
errno= my_errno;
goto exit; /* Log rotation needed but failed */
}
result= my_write(log->file, (uchar *) buffer, size, MYF(0));
exit:
mysql_mutex_unlock(&log->lock);
return result;
}
int logger_rotate(LOGGER_HANDLE *log)
{
int result;
......@@ -188,7 +213,7 @@ int logger_printf(LOGGER_HANDLE *log, const char *fmt, ...)
return result;
}
void init_logger_mutexes()
void logger_init_mutexes()
{
#ifdef HAVE_PSI_INTERFACE
if (PSI_server)
......
......@@ -28,6 +28,7 @@ my_bool timed_mutexes= 0;
/* from my_init */
char * home_dir=0;
char *mysql_data_home= (char*) ".";
const char *my_progname= NULL, *my_progname_short= NULL;
char curr_dir[FN_REFLEN]= {0},
home_dir_buff[FN_REFLEN]= {0};
......
......@@ -13,4 +13,4 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
MYSQL_ADD_PLUGIN(sql_errlog sql_errlog.c sql_logger.cc service_logger.h MODULE_ONLY)
MYSQL_ADD_PLUGIN(sql_errlog sql_errlog.c MODULE_ONLY)
......@@ -16,7 +16,7 @@
#include <mysql/plugin_audit.h>
#include <stdio.h>
#include <time.h>
#include "service_logger.h"
#include <mysql/service_logger.h>
/*
Disable __attribute__() on non-gcc compilers.
......@@ -106,7 +106,7 @@ static void log_sql_errors(MYSQL_THD thd __attribute__((unused)),
static int sql_error_log_init(void *p __attribute__((unused)))
{
init_logger_mutexes();
logger_init_mutexes();
logfile= logger_open(filename, size_limit, rotations);
if (logfile == NULL) {
......
......@@ -593,7 +593,6 @@ key_map key_map_full(0); // Will be initialized later
DATE_TIME_FORMAT global_date_format, global_datetime_format, global_time_format;
Time_zone *default_tz;
char *mysql_data_home= const_cast<char*>(".");
const char *mysql_real_data_home_ptr= mysql_real_data_home;
char server_version[SERVER_VERSION_LENGTH];
char *mysqld_unix_port, *opt_mysql_tmpdir;
......
......@@ -314,7 +314,6 @@ extern uint mysql_data_home_len;
extern uint mysql_real_data_home_len;
extern const char *mysql_real_data_home_ptr;
extern ulong thread_handling;
extern MYSQL_PLUGIN_IMPORT char *mysql_data_home;
extern "C" MYSQL_PLUGIN_IMPORT char server_version[SERVER_VERSION_LENGTH];
extern MYSQL_PLUGIN_IMPORT char mysql_real_data_home[];
extern char mysql_unpacked_real_data_home[];
......
......@@ -82,6 +82,9 @@ static void general_class_handler(THD *thd, uint event_subtype, va_list ap)
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->query_id;
event_class_dispatch(thd, MYSQL_AUDIT_GENERAL_CLASS, &event);
}
......@@ -131,6 +134,7 @@ static void table_class_handler(THD *thd, uint event_subclass, va_list ap)
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->query_id;
event_class_dispatch(thd, MYSQL_AUDIT_TABLE_CLASS, &event);
}
......
......@@ -93,7 +93,8 @@ void mysql_audit_general_log(THD *thd, time_t time,
mysql_audit_notify(thd, MYSQL_AUDIT_GENERAL_CLASS, MYSQL_AUDIT_GENERAL_LOG,
0, time, user, userlen, cmd, cmdlen,
query, querylen, clientcs, 0);
query, querylen, clientcs, (ha_rows) 0,
thd->db, thd->db_length);
}
}
......@@ -139,7 +140,8 @@ void mysql_audit_general(THD *thd, uint event_subtype,
mysql_audit_notify(thd, MYSQL_AUDIT_GENERAL_CLASS, event_subtype,
error_code, time, user, userlen, msg, msglen,
query.str(), query.length(), query.charset(), rows);
query.str(), query.length(), query.charset(), rows,
thd->db, thd->db_length);
}
}
......@@ -162,7 +164,11 @@ void mysql_audit_general(THD *thd, uint event_subtype,
#define MYSQL_AUDIT_NOTIFY_CONNECTION_DISCONNECT(thd, errcode)\
mysql_audit_notify(\
(thd), MYSQL_AUDIT_CONNECTION_CLASS, MYSQL_AUDIT_CONNECTION_DISCONNECT,\
(errcode), (thd)->thread_id, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
(errcode), (thd)->thread_id, (thd)->security_ctx->user,\
(thd)->security_ctx->user ? strlen((thd)->security_ctx->user) : 0,\
0, 0, 0, 0, 0, 0, (thd)->security_ctx->host,\
(thd)->security_ctx->host ? strlen((thd)->security_ctx->host) : 0,\
0, 0, 0, 0)
#define MYSQL_AUDIT_NOTIFY_CONNECTION_CHANGE_USER(thd) mysql_audit_notify(\
(thd), MYSQL_AUDIT_CONNECTION_CLASS, MYSQL_AUDIT_CONNECTION_CHANGE_USER,\
......
......@@ -702,6 +702,8 @@ static my_bool read_maria_plugin_info(struct st_plugin_dl *plugin_dl,
sym= cur;
plugin_dl->allocated= true;
}
else
sym= ptr;
}
plugin_dl->plugins= (struct st_maria_plugin *)sym;
......@@ -2661,13 +2663,18 @@ static void update_func_longlong(THD *thd, struct st_mysql_sys_var *var,
static void update_func_str(THD *thd, struct st_mysql_sys_var *var,
void *tgt, const void *save)
{
char *old= *(char **) tgt;
*(char **)tgt= *(char **) save;
char *value= *(char**) save;
if (var->flags & PLUGIN_VAR_MEMALLOC)
{
*(char **)tgt= my_strdup(*(char **) save, MYF(0));
char *old= *(char**) tgt;
if (value)
*(char**) tgt= my_strdup(value, MYF(0));
else
*(char**) tgt= 0;
my_free(old);
}
else
*(char**) tgt= value;
}
static void update_func_double(THD *thd, struct st_mysql_sys_var *var,
......
......@@ -58,6 +58,16 @@ static struct kill_statement_service_st thd_kill_statement_handler= {
thd_kill_level
};
static struct logger_service_st logger_service_handler= {
logger_init_mutexes,
logger_open,
logger_close,
logger_vprintf,
logger_printf,
logger_write,
logger_rotate
};
static struct st_service_ref list_of_services[]=
{
{ "my_snprintf_service", VERSION_my_snprintf, &my_snprintf_handler },
......@@ -66,6 +76,7 @@ static struct st_service_ref list_of_services[]=
{ "my_thread_scheduler_service", VERSION_my_thread_scheduler, &my_thread_scheduler_handler },
{ "progress_report_service", VERSION_progress_report, &progress_report_handler },
{ "debug_sync_service", VERSION_debug_sync, 0 }, // updated in plugin_init()
{ "thd_kill_statement_service", VERSION_kill_statement, &thd_kill_statement_handler }
{ "thd_kill_statement_service", VERSION_kill_statement, &thd_kill_statement_handler },
{ "logger_service", VERSION_logger, &logger_service_handler },
};
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