From 28a9e3f98407965d20597369a6059baf6db70e01 Mon Sep 17 00:00:00 2001 From: Nick Vyzas Date: Thu, 30 Nov 2017 20:39:59 +0200 Subject: [PATCH] Fixes - "Event log file is overwritten on ProxySQL service restart" #1201 --- lib/MySQL_Logger.cpp | 55 +++++++++++++++++++++++++++++--------------- lib/MySQL_Thread.cpp | 27 +++++++++++++++++++--- 2 files changed, 61 insertions(+), 21 deletions(-) diff --git a/lib/MySQL_Logger.cpp b/lib/MySQL_Logger.cpp index 60fc3d710..e8519b29f 100644 --- a/lib/MySQL_Logger.cpp +++ b/lib/MySQL_Logger.cpp @@ -2,7 +2,7 @@ #include "proxysql.h" #include "cpp.h" #include - +#include static uint8_t mysql_encode_length(uint64_t len, unsigned char *hd) { if (len < 251) return 1; @@ -206,15 +206,16 @@ void MySQL_Logger::flush_log_unlocked() { void MySQL_Logger::open_log_unlocked() { - if (log_file_id==0) { - log_file_id=find_next_id()+1; + log_file_id=find_next_id(); + if (log_file_id!=0) { + log_file_id=find_next_id()+1; } else { - log_file_id++; + log_file_id++; } char *filen=NULL; if (base_filename[0]=='/') { // absolute path filen=(char *)malloc(strlen(base_filename)+10); - sprintf(filen,"/%s.%08d",base_filename,log_file_id); + sprintf(filen,"%s.%08d",base_filename,log_file_id); } else { // relative path filen=(char *)malloc(strlen(datadir)+strlen(base_filename)+10); sprintf(filen,"%s/%s.%08d",datadir,base_filename,log_file_id); @@ -343,26 +344,44 @@ unsigned int MySQL_Logger::find_next_id() { int maxidx=0; DIR *dir; struct dirent *ent; + char *eval_filename = NULL; + char *eval_dirname = NULL; + char *eval_pathname = NULL; assert(base_filename); - assert(datadir); - size_t bfl=strlen(base_filename); - if ((dir = opendir(datadir)) != NULL) { - while ((ent = readdir (dir)) != NULL) { - if (strlen(ent->d_name)==bfl+9) { - if (strncmp(ent->d_name,base_filename,bfl)==0) { - if (ent->d_name[bfl]=='.') { - int idx=atoi(ent->d_name+bfl+1); + if (base_filename[0] == '/') { + eval_pathname = strdup(base_filename); + eval_filename = basename(eval_pathname); + eval_dirname = dirname(eval_pathname); + } else { + assert(datadir); + eval_filename = strdup(base_filename); + eval_dirname = strdup(datadir); + } + size_t efl=strlen(eval_filename); + if ((dir = opendir(eval_dirname)) != NULL) { + while ((ent = readdir (dir)) != NULL) { + if (strlen(ent->d_name)==efl+9) { + if (strncmp(ent->d_name,eval_filename,efl)==0) { + if (ent->d_name[efl]=='.') { + int idx=atoi(ent->d_name+efl+1); if (idx>maxidx) maxidx=idx; } } } } - closedir (dir); - return maxidx; + closedir (dir); + if (base_filename[0] != '/') { + free(eval_dirname); + free(eval_filename); + } + if (eval_pathname) { + free(eval_pathname); + } + return maxidx; } else { - /* could not open directory */ - fprintf(stderr,"Unable to open datadir: %s\n", datadir); + /* could not open directory */ + proxy_error("Unable to open datadir: %s\n", eval_dirname); exit(EXIT_FAILURE); - } + } return 0; } diff --git a/lib/MySQL_Thread.cpp b/lib/MySQL_Thread.cpp index 5a8931ef7..0d4aaddd0 100644 --- a/lib/MySQL_Thread.cpp +++ b/lib/MySQL_Thread.cpp @@ -4,6 +4,8 @@ #include "cpp.h" #include "MySQL_Thread.h" #include "SpookyV2.h" +#include +#include #ifdef DEBUG MySQL_Session *sess_stopat; @@ -1693,9 +1695,28 @@ bool MySQL_Threads_Handler::set_variable(char *name, char *value) { // this is t } if (!strcasecmp(name,"eventslog_filename")) { - free(variables.eventslog_filename); - variables.eventslog_filename=strdup(value); - return true; + if (value[strlen(value) - 1] == '/') { + proxy_error("%s is an invalid value for eventslog_filename, please specify a filename not just the path\n", value); + return false; + } else if (value[0] == '/') { + char *full_path = strdup(value); + char *eval_dirname = dirname(full_path); + DIR* eventlog_dir = opendir(eval_dirname); + free(full_path); + if (eventlog_dir) { + closedir(eventlog_dir); + free(variables.eventslog_filename); + variables.eventslog_filename=strdup(value); + return true; + } else { + proxy_error("%s is an invalid value for eventslog_filename path, the directory cannot be accessed\n", eval_dirname); + return false; + } + } else { + free(variables.eventslog_filename); + variables.eventslog_filename=strdup(value); + return true; + } } if (!strcasecmp(name,"server_capabilities")) { int intv=atoi(value);