From c04a69fb372b0a7121ab3c23f671b4b353bbf2ff Mon Sep 17 00:00:00 2001 From: laforge Date: Sun, 29 May 2005 18:52:14 +0000 Subject: add 'reconnect' option in case mysql server goes down at some point --- ulogd/mysql/ulogd_MYSQL.c | 101 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 83 insertions(+), 18 deletions(-) (limited to 'ulogd/mysql') diff --git a/ulogd/mysql/ulogd_MYSQL.c b/ulogd/mysql/ulogd_MYSQL.c index 8ec2f34..7765c71 100644 --- a/ulogd/mysql/ulogd_MYSQL.c +++ b/ulogd/mysql/ulogd_MYSQL.c @@ -31,10 +31,14 @@ * * 09 Feb 2005, Sven Schuster : * Added the "port" parameter to specify ports different from 3306 + * + * 12 May 2005, Jozsef Kadlecsik + * Added reconnecting to lost mysql server. */ #include #include +#include #include #include #include @@ -52,6 +56,9 @@ struct _field { struct _field *next; }; +/* The plugin handler */ +static ulog_output_t mysql_plugin; + /* the database handle we are using */ static MYSQL *dbh; @@ -67,6 +74,10 @@ static char *stmt_val; /* pointer to current inser position in statement */ static char *stmt_ins; +/* Attempt to reconnect if connection is lost */ +time_t reconnect = 0; +#define TIME_ERR ((time_t)-1) /* Be paranoid */ + /* our configuration directives */ static config_entry_t db_ce = { .key = "db", @@ -108,6 +119,14 @@ static config_entry_t port_ce = { .type = CONFIG_TYPE_INT, }; +static config_entry_t reconnect_ce = { + .next = &port_ce, + .key = "reconnect", + .type = CONFIG_TYPE_INT, +}; + +static int _mysql_init_db(ulog_iret_t *result); + /* our main output function, called by ulogd */ static int mysql_output(ulog_iret_t *result) { @@ -214,15 +233,21 @@ static int mysql_output(ulog_iret_t *result) /* now we have created our statement, insert it */ - if(mysql_real_query(dbh, stmt, strlen(stmt))) { + if (mysql_real_query(dbh, stmt, strlen(stmt))) { ulogd_log(ULOGD_ERROR, "sql error during insert: %s\n", mysql_error(dbh)); - return 1; + return _mysql_init_db(result); } return 0; } +/* no connection, plugin disabled */ +static int mysql_output_disabled(ulog_iret_t *result) +{ + return 0; +} + #define MYSQL_INSERTTEMPL "insert into X (Y) values (Z)" #define MYSQL_VALSIZE 100 @@ -234,11 +259,8 @@ static int mysql_createstmt(void) char buf[ULOGD_MAX_KEYLEN]; char *underscore; - if (stmt) { - ulogd_log(ULOGD_NOTICE, "createstmt called, but stmt" - " already existing\n"); - return 1; - } + if (stmt) + free(stmt); /* caclulate the size for the insert statement */ size = strlen(MYSQL_INSERTTEMPL) + strlen(table_ce.u.string); @@ -255,7 +277,7 @@ static int mysql_createstmt(void) if (!stmt) { ulogd_log(ULOGD_ERROR, "OOM!\n"); - return 1; + return -1; } sprintf(stmt, "insert into %s (", table_ce.u.string); @@ -289,11 +311,18 @@ static int mysql_get_columns(const char *table) int id; if (!dbh) - return 1; + return -1; result = mysql_list_fields(dbh, table, NULL); if (!result) - return 1; + return -1; + + /* Cleanup before reconnect */ + while (fields) { + f = fields; + fields = f->next; + free(f); + } while ((field = mysql_fetch_field(result))) { @@ -315,7 +344,7 @@ static int mysql_get_columns(const char *table) f = (struct _field *) malloc(sizeof *f); if (!f) { ulogd_log(ULOGD_ERROR, "OOM!\n"); - return 1; + return -1; } strncpy(f->name, buf, ULOGD_MAX_KEYLEN); f->id = id; @@ -333,35 +362,71 @@ static int mysql_open_db(char *server, int port, char *user, char *pass, { dbh = mysql_init(NULL); if (!dbh) - return 1; + return -1; if (!mysql_real_connect(dbh, server, user, pass, db, port, NULL, 0)) - return 1; + return -1; return 0; } -static int _mysql_init(void) +static int init_reconnect(void) { - /* have the opts parsed */ - config_parse_file("MYSQL", &port_ce); + if (reconnect_ce.u.value) { + reconnect = time(NULL); + if (reconnect != TIME_ERR) { + ulogd_log(ULOGD_ERROR, "no connection to database, " + "attempting to reconnect " + "after %u seconds\n", + reconnect_ce.u.value); + reconnect += reconnect_ce.u.value; + mysql_plugin.output = &_mysql_init_db; + return -1; + } + } + /* Disable plugin permanently */ + mysql_plugin.output = &mysql_output_disabled; + + return 0; +} +static int _mysql_init_db(ulog_iret_t *result) +{ + if (reconnect && reconnect > time(NULL)) + return 0; + if (mysql_open_db(host_ce.u.string, port_ce.u.value, user_ce.u.string, pass_ce.u.string, db_ce.u.string)) { ulogd_log(ULOGD_ERROR, "can't establish database connection\n"); - return -1; + return init_reconnect(); } /* read the fieldnames to know which values to insert */ if (mysql_get_columns(table_ce.u.string)) { ulogd_log(ULOGD_ERROR, "unable to get mysql columns\n"); - return -1; + return init_reconnect(); } mysql_createstmt(); + + /* enable plugin */ + mysql_plugin.output = &mysql_output; + + reconnect = 0; + if (result) + return mysql_output(result); + return 0; } +static int _mysql_init(void) +{ + /* have the opts parsed */ + config_parse_file("MYSQL", &reconnect_ce); + + return _mysql_init_db(NULL); +} + static void _mysql_fini(void) { mysql_close(dbh); -- cgit v1.2.3