summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ulogd/mysql/ulogd_MYSQL.c101
1 files changed, 83 insertions, 18 deletions
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 <schuster.sven@gmx.de>:
* Added the "port" parameter to specify ports different from 3306
+ *
+ * 12 May 2005, Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
+ * Added reconnecting to lost mysql server.
*/
#include <stdlib.h>
#include <string.h>
+#include <time.h>
#include <arpa/inet.h>
#include <ulogd/ulogd.h>
#include <ulogd/conffile.h>
@@ -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);