From 859b66180f98fdf7d53d206e0549daecdbee9a1d Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Tue, 9 Nov 2010 19:02:12 +0000 Subject: [PATCH] added proper error handling. daemon will shut down on critical errors. additionally use the lockfile to mark errors requiring manuel intervention and keep the daemon from restarting. --- Makefile | 5 ++--- cdr.c | 27 ++++++++++----------------- mediator.c | 38 ++++++++++++++++++++++++-------------- mediator.h | 4 ++++ medmysql.c | 42 +++++++++++++++++++++++++++++------------- medmysql.h | 6 ++---- 6 files changed, 71 insertions(+), 51 deletions(-) diff --git a/Makefile b/Makefile index 62552ef..7f6d0ca 100644 --- a/Makefile +++ b/Makefile @@ -2,10 +2,9 @@ BIN=mediator CC := gcc -#CFLAGS := -I. -I/usr/include/mysql -I/usr/local/include -g -Wall -DWITH_TIME_CALC - GLIB_CFLAGS := `pkg-config glib-2.0 --cflags` -CFLAGS := -I. -I/usr/include/mysql $(GLIB_CFLAGS) -g -Wall -O3 +CFLAGS := -I/usr/include/mysql $(GLIB_CFLAGS) -g -Wall -O3 +#CFLAGS += -DWITH_TIME_CALC GLIB_LDFLAGS := `pkg-config glib-2.0 --libs` LDFLAGS := -lmysqlclient -O3 diff --git a/cdr.c b/cdr.c index 1eeda22..9e11e77 100644 --- a/cdr.c +++ b/cdr.c @@ -88,15 +88,11 @@ int cdr_process_records(med_entry_t *records, u_int64_t count, u_int64_t *ext_co syslog(LOG_WARNING, "Multiple (%d) BYE messages for callid '%s' found, trashing...", msg_byes, callid); trash = 1; - ret = -1; } else { if(cdr_create_cdrs(records, count, &cdrs, &cdr_count, &trash) != 0) - { - /* try again next round */ - ret = -1; - } + goto error; else { *ext_count = cdr_count; @@ -108,15 +104,11 @@ int cdr_process_records(med_entry_t *records, u_int64_t count, u_int64_t *ext_co } if(medmysql_insert_cdrs(cdrs, cdr_count, batches) != 0) - { - /* TODO: error handling */ - } + goto error; else { if(medmysql_backup_entries(callid, batches) != 0) - { - // TODO: error handling - } + goto error; } } @@ -140,17 +132,18 @@ int cdr_process_records(med_entry_t *records, u_int64_t count, u_int64_t *ext_co { /*syslog(LOG_WARNING, "No INVITE message for callid '%s' found, trashing...", callid);*/ trash = 1; - ret = -1; } if(trash) { if(medmysql_trash_entries(callid, batches) != 0) - { - /* TODO: error handling */ - } + goto error; } return ret; + + +error: + return -1; } static int cdr_parse_srcleg(char *srcleg, cdr_entry_t *cdr) @@ -385,13 +378,13 @@ int cdr_create_cdrs(med_entry_t *records, u_int64_t count, if(cdr_parse_srcleg(e->src_leg, cdr) < 0) { *trash = 1; - return -1; + return 0; } if(cdr_parse_dstleg(e->dst_leg, cdr) < 0) { *trash = 1; - return -1; + return 0; } if(cdr_fill_record(cdr) != 0) diff --git a/mediator.c b/mediator.c index 96d09b0..757d504 100644 --- a/mediator.c +++ b/mediator.c @@ -98,6 +98,8 @@ static void mediator_signal(int signal) /**********************************************************************/ static int mediator_lock() { + struct stat sb; + mediator_lockfd = open(MEDIATOR_LOCK_FILE, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR); if(mediator_lockfd == -1) { @@ -109,6 +111,14 @@ static int mediator_lock() syslog(LOG_CRIT, "Error locking lock file: %s", strerror(errno)); return -1; } + if (fstat(mediator_lockfd, &sb)) { + syslog(LOG_CRIT, "Error getting file stats for lock file: %m"); + return -1; + } + if (sb.st_size) { + syslog(LOG_CRIT, "Non-empty lock file '%s' detected, refusing to start. Examine its contents to learn about the cause, and then delete it to clear the error", MEDIATOR_LOCK_FILE); + return -1; + } return 0; } @@ -206,15 +216,12 @@ int main(int argc, char **argv) last_count = mediator_count; if(medmysql_fetch_callids(&callids, &id_count) != 0) - { - /* TODO: error processing? */ - sleep(config_interval); - continue; + break; - } if(id_count > 0) { - medmysql_batch_start(&batches); + if (medmysql_batch_start(&batches)) + break; /*syslog(LOG_DEBUG, "Processing %"PRIu64" accounting record group(s).", id_count);*/ for(i = 0; i < id_count && !mediator_shutdown; ++i) @@ -224,15 +231,10 @@ int main(int argc, char **argv) #endif if(medmysql_fetch_records(&(callids[i]), &records, &rec_count) != 0) - { - /* TODO: error processing? */ - continue; - } + goto out; if(cdr_process_records(records, rec_count, &cdr_count, &batches) != 0) - { - /* TODO: error processing? */ - } + goto out; if(rec_count > 0) { @@ -249,7 +251,8 @@ int main(int argc, char **argv) } free(callids); - medmysql_batch_end(&batches); + if (medmysql_batch_end(&batches)) + break; } @@ -265,6 +268,7 @@ int main(int argc, char **argv) } } +out: mediator_destroy_maps(); syslog(LOG_INFO, "Shutting down."); @@ -273,3 +277,9 @@ int main(int argc, char **argv) syslog(LOG_INFO, "Successfully shut down."); return 0; } + + +void critical(const char *msg) { + write(mediator_lockfd, msg, strlen(msg)); + write(mediator_lockfd, "\n", 1); +} diff --git a/mediator.h b/mediator.h index 7d6f650..6ad7506 100644 --- a/mediator.h +++ b/mediator.h @@ -77,4 +77,8 @@ extern GHashTable *med_peer_host_table; extern GHashTable *med_peer_ip_table; extern GHashTable *med_uuid_table; + +void critical(const char *); + + #endif /* _MEDIATOR_H */ diff --git a/medmysql.c b/medmysql.c index a2635dc..21a122a 100644 --- a/medmysql.c +++ b/medmysql.c @@ -23,6 +23,9 @@ static MYSQL *cdr_handler = NULL; static MYSQL *med_handler = NULL; static MYSQL *prov_handler = NULL; +static int medmysql_flush_cdr(struct medmysql_batches *); +static int medmysql_flush_medlist(struct medmysql_str *); + /**********************************************************************/ int medmysql_init() { @@ -495,18 +498,22 @@ out: } -void medmysql_batch_start(struct medmysql_batches *batches) { - mysql_real_query(cdr_handler, "start transaction", 17); - mysql_real_query(med_handler, "start transaction", 17); +int medmysql_batch_start(struct medmysql_batches *batches) { + if (mysql_real_query(cdr_handler, "start transaction", 17)) + return -1; + if (mysql_real_query(med_handler, "start transaction", 17)) + return -1; batches->cdrs.len = 0; batches->acc_backup.len = 0; batches->acc_trash.len = 0; batches->to_delete.len = 0; + + return 0; } -int medmysql_flush_cdr(struct medmysql_batches *batches) { +static int medmysql_flush_cdr(struct medmysql_batches *batches) { if (batches->cdrs.len == 0) return 0; if (batches->cdrs.str[batches->cdrs.len - 1] != ',') @@ -527,7 +534,7 @@ int medmysql_flush_cdr(struct medmysql_batches *batches) { return 0; } -int medmysql_flush_medlist(struct medmysql_str *str) { +static int medmysql_flush_medlist(struct medmysql_str *str) { if (str->len == 0) return 0; if (str->str[str->len - 1] != ',') @@ -539,7 +546,8 @@ int medmysql_flush_medlist(struct medmysql_str *str) { { str->len = 0; syslog(LOG_CRIT, "Error executing query: %s", - mysql_error(cdr_handler)); + mysql_error(med_handler)); + critical("Failed to execute potentially crucial SQL query, check syslog for details"); return -1; } @@ -547,12 +555,20 @@ int medmysql_flush_medlist(struct medmysql_str *str) { return 0; } -void medmysql_batch_end(struct medmysql_batches *batches) { - medmysql_flush_cdr(batches); - medmysql_flush_medlist(&batches->acc_trash); - medmysql_flush_medlist(&batches->acc_backup); - medmysql_flush_medlist(&batches->to_delete); +int medmysql_batch_end(struct medmysql_batches *batches) { + if (medmysql_flush_cdr(batches)) + return -1; + if (medmysql_flush_medlist(&batches->acc_trash)) + return -1; + if (medmysql_flush_medlist(&batches->acc_backup)) + return -1; + if (medmysql_flush_medlist(&batches->to_delete)) + return -1; - mysql_real_query(cdr_handler, "commit", 6); - mysql_real_query(med_handler, "commit", 6); + if (mysql_real_query(cdr_handler, "commit", 6)) + return -1; + if (mysql_real_query(med_handler, "commit", 6)) + return -1; + + return 0; } diff --git a/medmysql.h b/medmysql.h index 1a2f4f5..8468ec0 100644 --- a/medmysql.h +++ b/medmysql.h @@ -30,9 +30,7 @@ int medmysql_delete_entries(const char *callid, struct medmysql_batches *); int medmysql_insert_cdrs(cdr_entry_t *records, u_int64_t count, struct medmysql_batches *); int medmysql_load_maps(GHashTable *host_table, GHashTable *ip_table); int medmysql_load_uuids(GHashTable *uuid_table); -void medmysql_batch_start(struct medmysql_batches *); -int medmysql_flush_cdr(struct medmysql_batches *); -int medmysql_flush_medlist(struct medmysql_str *); -void medmysql_batch_end(struct medmysql_batches *); +int medmysql_batch_start(struct medmysql_batches *); +int medmysql_batch_end(struct medmysql_batches *); #endif /* _MED_MYSQL_H */