Merge branch 'develop' into firewall

This commit is contained in:
Markus Makela
2014-11-13 09:50:02 +02:00
24 changed files with 756 additions and 479 deletions

View File

@ -66,6 +66,11 @@ if(GCOV)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lgcov") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lgcov")
endif() endif()
if(FAKE_CODE)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DFAKE_CODE")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DFAKE_CODE")
endif()
subdirs(MYSQL_DIR_ALL ${MYSQL_DIR}) subdirs(MYSQL_DIR_ALL ${MYSQL_DIR})
foreach(DIR ${MYSQL_DIR_ALL}) foreach(DIR ${MYSQL_DIR_ALL})
include_directories(${DIR}) include_directories(${DIR})

View File

@ -162,7 +162,8 @@ struct logfile_st {
mlist_t lf_blockbuf_list; mlist_t lf_blockbuf_list;
int lf_buf_size; int lf_buf_size;
bool lf_flushflag; bool lf_flushflag;
int lf_spinlock; /**< lf_flushflag */ bool lf_rotateflag;
int lf_spinlock; /**< lf_flushflag & lf_rotateflag */
int lf_npending_writes; int lf_npending_writes;
#if defined(SS_DEBUG) #if defined(SS_DEBUG)
skygw_chk_t lf_chk_tail; skygw_chk_t lf_chk_tail;
@ -232,6 +233,11 @@ static bool logfile_init(
static void logfile_done(logfile_t* logfile); static void logfile_done(logfile_t* logfile);
static void logfile_free_memory(logfile_t* lf); static void logfile_free_memory(logfile_t* lf);
static void logfile_flush(logfile_t* lf); static void logfile_flush(logfile_t* lf);
static void logfile_rotate(logfile_t* lf);
static bool logfile_create(logfile_t* lf);
static bool logfile_open_file(filewriter_t* fw, logfile_t* lf);
static char* form_full_file_name(strpart_t* parts, int seqno, int seqnoidx);
static bool filewriter_init( static bool filewriter_init(
logmanager_t* logmanager, logmanager_t* logmanager,
filewriter_t* fw, filewriter_t* fw,
@ -249,11 +255,13 @@ static bool logmanager_register(bool writep);
static void logmanager_unregister(void); static void logmanager_unregister(void);
static bool logmanager_init_nomutex(int argc, char* argv[]); static bool logmanager_init_nomutex(int argc, char* argv[]);
static void logmanager_done_nomutex(void); static void logmanager_done_nomutex(void);
static int logmanager_write_log( static int logmanager_write_log(
logfile_id_t id, logfile_id_t id,
bool flush, bool flush,
bool use_valist, bool use_valist,
bool spread_down, bool spread_down,
bool rotate,
size_t len, size_t len,
const char* str, const char* str,
va_list valist); va_list valist);
@ -393,8 +401,10 @@ static bool logmanager_init_nomutex(
*/ */
lm_enabled_logfiles_bitmask = lm->lm_enabled_logfiles; lm_enabled_logfiles_bitmask = lm->lm_enabled_logfiles;
/** Initialize filewriter data and open the (first) log file(s) /**
* for each log file type. */ * Initialize filewriter data and open the log file
* for each log file type.
*/
if (!filewriter_init(lm, fw, lm->lm_clientmes, lm->lm_logmes)) if (!filewriter_init(lm, fw, lm->lm_clientmes, lm->lm_logmes))
{ {
err = 1; err = 1;
@ -630,6 +640,8 @@ static logfile_t* logmanager_get_logfile(
* @param spread_down - in, use * @param spread_down - in, use
* if true, log string is spread to all logs having larger id. * if true, log string is spread to all logs having larger id.
* *
* @param rotate if set, closes currently open log file and opens a new one
*
* @param str_len - in, use * @param str_len - in, use
* length of formatted string * length of formatted string
* *
@ -650,6 +662,7 @@ static int logmanager_write_log(
bool flush, bool flush,
bool use_valist, bool use_valist,
bool spread_down, bool spread_down,
bool rotate,
size_t str_len, size_t str_len,
const char* str, const char* str,
va_list valist) va_list valist)
@ -673,6 +686,7 @@ static int logmanager_write_log(
true, true,
false, false,
false, false,
false,
strlen(errstr)+1, strlen(errstr)+1,
errstr, errstr,
valist); valist);
@ -689,14 +703,21 @@ static int logmanager_write_log(
CHK_LOGFILE(lf); CHK_LOGFILE(lf);
/** /**
* When string pointer is NULL, case is skygw_log_flush and no * When string pointer is NULL, operation is either flush or rotate.
* writing is involved. With flush && str != NULL case is
* skygw_log_write_flush.
*/ */
if (str == NULL) { if (str == NULL)
ss_dassert(flush); {
logfile_flush(lf); /**< here we wake up file writer */ if (flush)
} else { {
logfile_flush(lf); /*< wakes up file writer */
}
else if (rotate)
{
logfile_rotate(lf); /*< wakes up file writer */
}
}
else
{
/** Length of string that will be written, limited by bufsize */ /** Length of string that will be written, limited by bufsize */
int safe_str_len; int safe_str_len;
@ -711,7 +732,6 @@ static int logmanager_write_log(
{ {
safe_str_len = timestamp_len-1+str_len; safe_str_len = timestamp_len-1+str_len;
} }
/** /**
* Seek write position and register to block buffer. * Seek write position and register to block buffer.
* Then print formatted string to write position. * Then print formatted string to write position.
@ -719,32 +739,26 @@ static int logmanager_write_log(
#if defined (SS_LOG_DEBUG) #if defined (SS_LOG_DEBUG)
{ {
char *copy,*tok; char *copy,*tok;
int tokval; int tokval;
simple_mutex_lock(&msg_mutex,true); simple_mutex_lock(&msg_mutex,true);
copy = strdup(str); copy = strdup(str);
tok = strtok(copy,"|"); tok = strtok(copy,"|");
tok = strtok(NULL,"|"); tok = strtok(NULL,"|");
if(strstr(str,"message|") && tok){ if(strstr(str,"message|") && tok)
{
tokval = atoi(tok); tokval = atoi(tok);
if(prevval > 0){ if(prevval > 0)
{
ss_dassert(tokval == (prevval + 1)); ss_dassert(tokval == (prevval + 1));
} }
prevval = tokval; prevval = tokval;
} }
free(copy); free(copy);
simple_mutex_unlock(&msg_mutex); simple_mutex_unlock(&msg_mutex);
} }
#endif #endif
@ -860,7 +874,7 @@ static int logmanager_write_log(
blockbuf_unregister(bb_c); blockbuf_unregister(bb_c);
} }
} /* if (spread_down) */ } /* if (spread_down) */
} } /* if (str == NULL) */
return_err: return_err:
return err; return err;
@ -1247,6 +1261,7 @@ static bool logfile_set_enabled(
true, true,
false, false,
false, false,
false,
strlen(errstr)+1, strlen(errstr)+1,
errstr, errstr,
notused); notused);
@ -1272,6 +1287,7 @@ static bool logfile_set_enabled(
true, true,
false, false,
false, false,
false,
strlen(logstr)+1, strlen(logstr)+1,
logstr, logstr,
notused); notused);
@ -1317,9 +1333,6 @@ int skygw_log_write_flush(
/** /**
* Find out the length of log string (to be formatted str). * Find out the length of log string (to be formatted str).
*/ */
va_start(valist, str); va_start(valist, str);
len = vsnprintf(NULL, 0, str, valist); len = vsnprintf(NULL, 0, str, valist);
va_end(valist); va_end(valist);
@ -1331,7 +1344,7 @@ int skygw_log_write_flush(
* Write log string to buffer and add to file write list. * Write log string to buffer and add to file write list.
*/ */
va_start(valist, str); va_start(valist, str);
err = logmanager_write_log(id, true, true, true, len, str, valist); err = logmanager_write_log(id, true, true, true, false, len, str, valist);
va_end(valist); va_end(valist);
if (err != 0) { if (err != 0) {
@ -1370,9 +1383,6 @@ int skygw_log_write(
err = 1; err = 1;
goto return_unregister; goto return_unregister;
} }
/** /**
* Find out the length of log string (to be formatted str). * Find out the length of log string (to be formatted str).
*/ */
@ -1388,7 +1398,7 @@ int skygw_log_write(
*/ */
va_start(valist, str); va_start(valist, str);
err = logmanager_write_log(id, false, true, true, len, str, valist); err = logmanager_write_log(id, false, true, true, false, len, str, valist);
va_end(valist); va_end(valist);
if (err != 0) { if (err != 0) {
@ -1415,7 +1425,7 @@ int skygw_log_flush(
goto return_err; goto return_err;
} }
CHK_LOGMANAGER(lm); CHK_LOGMANAGER(lm);
err = logmanager_write_log(id, true, false, false, 0, NULL, valist); err = logmanager_write_log(id, true, false, false, false, 0, NULL, valist);
if (err != 0) { if (err != 0) {
fprintf(stderr, "skygw_log_flush failed.\n"); fprintf(stderr, "skygw_log_flush failed.\n");
@ -1428,6 +1438,60 @@ return_err:
return err; return err;
} }
/**
* Replace current logfile with new file with increased sequence number on
* its name.
*/
int skygw_log_rotate(
logfile_id_t id)
{
int err = 0;
logfile_t* lf;
va_list valist; /**< Dummy, must be present but it is not processed */
if (!logmanager_register(false))
{
ss_dfprintf(stderr,
"Can't register to logmanager, rotating failed\n");
goto return_err;
}
CHK_LOGMANAGER(lm);
lf = &lm->lm_logfile[id];
LOGIF(LM, (skygw_log_write(
LOGFILE_MESSAGE,
"Log rotation is called for %s.",
lf->lf_full_file_name)));
err = logmanager_write_log(id, false, false, false, true, 0, NULL, valist);
if (err != 0)
{
LOGIF(LE, (skygw_log_write(
LOGFILE_ERROR,
"Log file rotation failed for file %s.",
lf->lf_full_file_name)));
fprintf(stderr, "skygw_log_rotate failed.\n");
goto return_unregister;
}
return_unregister:
LOGIF(LM, (skygw_log_write_flush(
LOGFILE_MESSAGE,
"File %s use for log writing..",
lf->lf_full_file_name)));
logmanager_unregister();
return_err:
return err;
}
/** /**
* @node Register as a logging client to logmanager. * @node Register as a logging client to logmanager.
* *
@ -1841,6 +1905,237 @@ static void logfile_flush(
skygw_message_send(lf->lf_logmes); skygw_message_send(lf->lf_logmes);
} }
/**
* Set rotate flag for a log file and wake up the writer thread which then
* performs the actual rotation task.
*
* @param lf logfile pointer
*/
static void logfile_rotate(
logfile_t* lf)
{
CHK_LOGFILE(lf);
acquire_lock(&lf->lf_spinlock);
lf->lf_rotateflag = true;
release_lock(&lf->lf_spinlock);
skygw_message_send(lf->lf_logmes);
}
/**
* Forms complete path name for logfile and tests that the file doesn't conflict
* with any existing file and it is writable.
*
* @param lf logfile pointer
*
* @return true if succeed, false if failed
*/
static bool logfile_create(
logfile_t* lf)
{
bool namecreatefail;
bool nameconflicts;
bool store_shmem;
bool writable;
bool succp;
strpart_t spart[3]; /*< string parts of which the file is composed of */
/**
* sparts is an array but next pointers are used to walk through
* the list of string parts.
*/
spart[0].sp_next = &spart[1];
spart[1].sp_next = &spart[2];
spart[2].sp_next = NULL;
spart[1].sp_string = lf->lf_name_prefix;
spart[2].sp_string = lf->lf_name_suffix;
store_shmem = lf->lf_store_shmem;
do {
namecreatefail = false;
nameconflicts = false;
spart[0].sp_string = lf->lf_filepath;
/**
* Create name for log file. Seqno is added between prefix &
* suffix (index == 2)
*/
lf->lf_full_file_name =
form_full_file_name(spart, lf->lf_name_seqno, 2);
if (store_shmem)
{
spart[0].sp_string = lf->lf_linkpath;
/**
* Create name for link file
*/
lf->lf_full_link_name = form_full_file_name(
spart,
lf->lf_name_seqno,
2);
}
/**
* At least one of the files couldn't be created. Increase
* sequence number and retry until succeeds.
*/
if (lf->lf_full_file_name == NULL ||
(store_shmem && lf->lf_full_link_name == NULL))
{
namecreatefail = true;
goto file_create_fail;
}
/**
* If file exists but is different type, create fails and
* new, increased sequence number is added to file name.
*/
if (check_file_and_path(lf->lf_full_file_name, &writable))
{
/** Found similarly named file which isn't writable */
if (!writable || file_is_symlink(lf->lf_full_file_name))
{
nameconflicts = true;
goto file_create_fail;
}
}
else
{
/**
* Opening the file failed for some other reason than
* existing non-writable file. Shut down.
*/
if (!writable)
{
succp = false;
goto return_succp;
}
}
if (store_shmem)
{
if (check_file_and_path(lf->lf_full_file_name, &writable))
{
/** Found similarly named file which isn't writable */
if (!writable ||
file_is_symlink(lf->lf_full_file_name))
{
unlink(lf->lf_full_file_name);
nameconflicts = true;
}
}
else
{
/**
* Opening the file failed for some other reason than
* existing non-writable file. Shut down.
*/
if (!writable)
{
succp = false;
goto return_succp;
}
}
}
file_create_fail:
if (namecreatefail || nameconflicts)
{
lf->lf_name_seqno += 1;
if (lf->lf_full_file_name != NULL)
{
free(lf->lf_full_file_name);
lf->lf_full_file_name = NULL;
}
if (lf->lf_full_link_name != NULL)
{
free(lf->lf_full_link_name);
lf->lf_full_link_name = NULL;
}
}
} while (namecreatefail || nameconflicts);
succp = true;
return_succp:
return succp;
}
/**
* Opens a log file and writes header to the beginning of it. File name, FILE*,
* and file descriptor are stored to skygw_file_t struct which is stored in
* filewriter strcuture passed as parameter.
*
* @param fw filewriter pointer
* @param lf logfile pointer
*
* @return true if succeed; the resulting skygw_file_t is written in filewriter,
* false if failed.
*
*/
static bool logfile_open_file(
filewriter_t* fw,
logfile_t* lf)
{
bool succp;
char* start_msg_str;
int err;
if (lf->lf_store_shmem)
{
/** Create symlink pointing to log file */
fw->fwr_file[lf->lf_id] = skygw_file_init(
lf->lf_full_file_name,
lf->lf_full_link_name);
}
else
{
/** Create normal disk-resident log file */
fw->fwr_file[lf->lf_id] = skygw_file_init(
lf->lf_full_file_name,
NULL);
}
if (fw->fwr_file[lf->lf_id] == NULL)
{
fprintf(stderr,
"Error : opening logfile %s failed.\n",
lf->lf_full_file_name);
succp = false;
goto return_succp;
}
if (lf->lf_enabled)
{
start_msg_str = strdup("---\tLogging is enabled.\n");
}
else
{
start_msg_str = strdup("---\tLogging is disabled.\n");
}
err = skygw_file_write(fw->fwr_file[lf->lf_id],
(void *)start_msg_str,
strlen(start_msg_str),
true);
if (err != 0)
{
fprintf(stderr,
"Error : writing to file %s failed due to %d, %s. "
"Exiting MaxScale.\n",
lf->lf_full_file_name,
err,
strerror(err));
succp = false;
goto return_succp;
}
free(start_msg_str);
succp = true;
return_succp:
return succp;
}
/** /**
* @node Combine all name parts from left to right. * @node Combine all name parts from left to right.
@ -2122,12 +2417,6 @@ static bool logfile_init(
{ {
bool succp = false; bool succp = false;
fnames_conf_t* fn = &logmanager->lm_fnames_conf; fnames_conf_t* fn = &logmanager->lm_fnames_conf;
/** string parts of which the file is composed of */
strpart_t strparts[3];
bool namecreatefail = false;
bool nameconflicts = false;
bool writable;
logfile->lf_state = INIT; logfile->lf_state = INIT;
#if defined(SS_DEBUG) #if defined(SS_DEBUG)
logfile->lf_chk_top = CHK_NUM_LOGFILE; logfile->lf_chk_top = CHK_NUM_LOGFILE;
@ -2141,21 +2430,12 @@ static bool logfile_init(
logfile->lf_name_seqno = 1; logfile->lf_name_seqno = 1;
logfile->lf_lmgr = logmanager; logfile->lf_lmgr = logmanager;
logfile->lf_flushflag = false; logfile->lf_flushflag = false;
logfile->lf_rotateflag= false;
logfile->lf_spinlock = 0; logfile->lf_spinlock = 0;
logfile->lf_store_shmem = store_shmem; logfile->lf_store_shmem = store_shmem;
logfile->lf_write_syslog = write_syslog; logfile->lf_write_syslog = write_syslog;
logfile->lf_buf_size = MAX_LOGSTRLEN; logfile->lf_buf_size = MAX_LOGSTRLEN;
logfile->lf_enabled = logmanager->lm_enabled_logfiles & logfile_id; logfile->lf_enabled = logmanager->lm_enabled_logfiles & logfile_id;
/**
* strparts is an array but next pointers are used to walk through
* the list of string parts.
*/
strparts[0].sp_next = &strparts[1];
strparts[1].sp_next = &strparts[2];
strparts[2].sp_next = NULL;
strparts[1].sp_string = logfile->lf_name_prefix;
strparts[2].sp_string = logfile->lf_name_suffix;
/** /**
* If file is stored in shared memory in /dev/shm, a link * If file is stored in shared memory in /dev/shm, a link
* pointing to shm file is created and located to the file * pointing to shm file is created and located to the file
@ -2173,7 +2453,7 @@ static bool logfile_init(
if (c == NULL) if (c == NULL)
{ {
succp = false; succp = false;
goto file_create_fail; goto return_with_succp;
} }
sprintf(c, "%s%d", shm_pathname_prefix, pid); sprintf(c, "%s%d", shm_pathname_prefix, pid);
logfile->lf_filepath = c; logfile->lf_filepath = c;
@ -2182,7 +2462,7 @@ static bool logfile_init(
errno != EEXIST) errno != EEXIST)
{ {
succp = false; succp = false;
goto file_create_fail; goto return_with_succp;
} }
logfile->lf_linkpath = strdup(fn->fn_logpath); logfile->lf_linkpath = strdup(fn->fn_logpath);
logfile->lf_linkpath = add_slash(logfile->lf_linkpath); logfile->lf_linkpath = add_slash(logfile->lf_linkpath);
@ -2193,113 +2473,10 @@ static bool logfile_init(
} }
logfile->lf_filepath = add_slash(logfile->lf_filepath); logfile->lf_filepath = add_slash(logfile->lf_filepath);
do { if (!(succp = logfile_create(logfile)))
namecreatefail = false;
nameconflicts = false;
strparts[0].sp_string = logfile->lf_filepath;
/**
* Create name for log file. Seqno is added between prefix &
* suffix (index == 2)
*/
logfile->lf_full_file_name =
form_full_file_name(strparts, logfile->lf_name_seqno, 2);
if (store_shmem)
{ {
strparts[0].sp_string = logfile->lf_linkpath;
/**
* Create name for link file
*/
logfile->lf_full_link_name =
form_full_file_name(strparts,
logfile->lf_name_seqno,
2);
}
/**
* At least one of the files couldn't be created. Increase
* sequence number and retry until succeeds.
*/
if (logfile->lf_full_file_name == NULL ||
(store_shmem && logfile->lf_full_link_name == NULL))
{
namecreatefail = true;
goto file_create_fail;
}
/**
* If file exists but is different type, create fails and
* new, increased sequence number is added to file name.
*/
if (check_file_and_path(
logfile->lf_full_file_name,
&writable))
{
/** Found similarly named file which isn't writable */
if (!writable ||
file_is_symlink(logfile->lf_full_file_name))
{
nameconflicts = true;
goto file_create_fail;
}
}
else
{
/**
* Opening the file failed for some other reason than
* existing non-writable file. Shut down.
*/
if (!writable)
{
succp = false;
goto return_with_succp; goto return_with_succp;
} }
}
if (store_shmem)
{
if (check_file_and_path(
logfile->lf_full_file_name,
&writable))
{
/** Found similarly named file which isn't writable */
if (!writable ||
file_is_symlink(logfile->lf_full_file_name))
{
unlink(logfile->lf_full_file_name);
nameconflicts = true;
}
}
else
{
/**
* Opening the file failed for some other reason than
* existing non-writable file. Shut down.
*/
if (!writable)
{
succp = false;
goto return_with_succp;
}
}
}
file_create_fail:
if (namecreatefail || nameconflicts)
{
logfile->lf_name_seqno += 1;
if (logfile->lf_full_file_name != NULL)
{
free(logfile->lf_full_file_name);
logfile->lf_full_file_name = NULL;
}
if (logfile->lf_full_link_name != NULL)
{
free(logfile->lf_full_link_name);
logfile->lf_full_link_name = NULL;
}
}
} while (namecreatefail || nameconflicts);
/** /**
* Create a block buffer list for log file. Clients' writes go to buffers * Create a block buffer list for log file. Clients' writes go to buffers
* from where separate log flusher thread writes them to disk. * from where separate log flusher thread writes them to disk.
@ -2334,11 +2511,11 @@ file_create_fail:
CHK_LOGFILE(logfile); CHK_LOGFILE(logfile);
return_with_succp: return_with_succp:
if (!succp) { if (!succp)
{
logfile_done(logfile); logfile_done(logfile);
} }
ss_dassert(logfile->lf_state == RUN || ss_dassert(logfile->lf_state == RUN || logfile->lf_state == DONE);
logfile->lf_state == DONE);
return succp; return succp;
} }
@ -2397,16 +2574,14 @@ static void logfile_free_memory(
} }
/** /**
* @node Initialize filewriter struct to a given address * @node Initialize filewriter data and open the log file for each log file type.
* *
* Parameters: * @param logmanager Log manager struct
* @param fw - <usage> * @param fw File writer struct
* <description> * @param clientmes Messaging from file writer to log manager
* @param logmes Messaging from loggers to file writer thread
* *
* @return * @return true if succeed, false if failed
*
*
* @details (write detailed description here)
* *
*/ */
static bool filewriter_init( static bool filewriter_init(
@ -2416,11 +2591,9 @@ static bool filewriter_init(
skygw_message_t* logmes) skygw_message_t* logmes)
{ {
bool succp = false; bool succp = false;
int err;
logfile_t* lf; logfile_t* lf;
logfile_id_t id; logfile_id_t id;
int i; int i;
char* start_msg_str;
CHK_LOGMANAGER(logmanager); CHK_LOGMANAGER(logmanager);
@ -2438,59 +2611,25 @@ static bool filewriter_init(
if (fw->fwr_logmes == NULL || fw->fwr_clientmes == NULL) { if (fw->fwr_logmes == NULL || fw->fwr_clientmes == NULL) {
goto return_succp; goto return_succp;
} }
for (i=LOGFILE_FIRST; i<=LOGFILE_LAST; i <<= 1) {
for (i=LOGFILE_FIRST; i<=LOGFILE_LAST; i <<= 1)
{
id = (logfile_id_t)i; id = (logfile_id_t)i;
lf = logmanager_get_logfile(logmanager, id); lf = logmanager_get_logfile(logmanager, id);
if (lf->lf_store_shmem) if (!(succp = logfile_open_file(fw, lf)))
{
/** Create symlink pointing to log file */
fw->fwr_file[id] = skygw_file_init(lf->lf_full_file_name,
lf->lf_full_link_name);
}
else
{
/** Create normal disk-resident log file */
fw->fwr_file[id] = skygw_file_init(lf->lf_full_file_name,
NULL);
}
if (fw->fwr_file[id] == NULL)
{ {
fprintf(stderr, fprintf(stderr,
"Error : opening %s failed, %s. Exiting " "Error : opening log file %s failed. Exiting "
"MaxScale\n", "MaxScale\n",
lf->lf_full_file_name, lf->lf_full_file_name);
strerror(errno));
goto return_succp; goto return_succp;
} }
} /*< for */
if (lf->lf_enabled) {
start_msg_str = strdup("---\tLogging is enabled.\n");
} else {
start_msg_str = strdup("---\tLogging is disabled.\n");
}
err = skygw_file_write(fw->fwr_file[id],
(void *)start_msg_str,
strlen(start_msg_str),
true);
if (err != 0)
{
fprintf(stderr,
"Error : writing to file %s failed due to %d, %s. "
"Exiting MaxScale.\n",
lf->lf_full_file_name,
err,
strerror(err));
succp = false;
goto return_succp;
}
free(start_msg_str);
}
fw->fwr_state = RUN; fw->fwr_state = RUN;
CHK_FILEWRITER(fw); CHK_FILEWRITER(fw);
succp = true; succp = true;
return_succp: return_succp:
if (!succp) { if (!succp) {
filewriter_done(fw); filewriter_done(fw);
@ -2511,9 +2650,10 @@ static void filewriter_done(
case INIT: case INIT:
fw->fwr_logmes = NULL; fw->fwr_logmes = NULL;
fw->fwr_clientmes = NULL; fw->fwr_clientmes = NULL;
for (i=LOGFILE_FIRST; i<=LOGFILE_LAST; i++) { for (i=LOGFILE_FIRST; i<=LOGFILE_LAST; i++)
{
id = (logfile_id_t)i; id = (logfile_id_t)i;
skygw_file_done(fw->fwr_file[id]); skygw_file_close(fw->fwr_file[id], true);
} }
fw->fwr_state = DONE; fw->fwr_state = DONE;
case DONE: case DONE:
@ -2581,6 +2721,7 @@ static void* thr_filewriter_fun(
blockbuf_state_t flush_blockbuf; /**< flush single block buffer. */ blockbuf_state_t flush_blockbuf; /**< flush single block buffer. */
bool flush_logfile; /**< flush logfile */ bool flush_logfile; /**< flush logfile */
bool flushall_logfiles;/**< flush all logfiles */ bool flushall_logfiles;/**< flush all logfiles */
bool rotate_logfile; /*< close current and open new file */
size_t vn1; size_t vn1;
size_t vn2; size_t vn2;
@ -2602,7 +2743,8 @@ static void* thr_filewriter_fun(
flushall_logfiles = skygw_thread_must_exit(thr); flushall_logfiles = skygw_thread_must_exit(thr);
/** Process all logfiles which have buffered writes. */ /** Process all logfiles which have buffered writes. */
for (i=LOGFILE_FIRST; i<=LOGFILE_LAST; i <<= 1) { for (i=LOGFILE_FIRST; i<=LOGFILE_LAST; i <<= 1)
{
retry_flush_on_exit: retry_flush_on_exit:
/** /**
* Get file pointer of current logfile. * Get file pointer of current logfile.
@ -2611,13 +2753,45 @@ static void* thr_filewriter_fun(
lf = &lm->lm_logfile[(logfile_id_t)i]; lf = &lm->lm_logfile[(logfile_id_t)i];
/** /**
* read and reset logfile's flushflag * read and reset logfile's flush- and rotateflag
*/ */
acquire_lock(&lf->lf_spinlock); acquire_lock(&lf->lf_spinlock);
flush_logfile = lf->lf_flushflag; flush_logfile = lf->lf_flushflag;
rotate_logfile = lf->lf_rotateflag;
lf->lf_flushflag = false; lf->lf_flushflag = false;
lf->lf_rotateflag = false;
release_lock(&lf->lf_spinlock); release_lock(&lf->lf_spinlock);
/**
* Log rotation :
* Close current, and open a new file for the log.
*/
if (rotate_logfile)
{
bool succp;
lf->lf_name_seqno += 1; /*< new sequence number */
if (!(succp = logfile_create(lf)))
{
lf->lf_name_seqno -= 1; /*< restore */
}
else if ((succp = logfile_open_file(fwr, lf)))
{
skygw_file_close(file, false); /*< close old file */
}
if (!succp)
{
LOGIF(LE, (skygw_log_write(
LOGFILE_ERROR,
"Error : Log rotation failed. "
"Creating replacement file %s "
"failed. Continuing "
"logging to existing file.",
lf->lf_full_file_name)));
}
continue;
}
/** /**
* get logfile's block buffer list * get logfile's block buffer list
*/ */
@ -2651,14 +2825,14 @@ static void* thr_filewriter_fun(
* buffer is at least half-full * buffer is at least half-full
* -> write to disk * -> write to disk
*/ */
while(bb->bb_refcount > 0) { while(bb->bb_refcount > 0)
{
simple_mutex_unlock( simple_mutex_unlock(
&bb->bb_mutex); &bb->bb_mutex);
simple_mutex_lock( simple_mutex_lock(
&bb->bb_mutex, &bb->bb_mutex,
true); true);
} }
err = skygw_file_write( err = skygw_file_write(
file, file,
(void *)bb->bb_buf, (void *)bb->bb_buf,

View File

@ -75,6 +75,7 @@ void skygw_logmanager_exit(void);
void skygw_log_done(void); void skygw_log_done(void);
int skygw_log_write(logfile_id_t id, const char* format, ...); int skygw_log_write(logfile_id_t id, const char* format, ...);
int skygw_log_flush(logfile_id_t id); int skygw_log_flush(logfile_id_t id);
int skygw_log_rotate(logfile_id_t id);
int skygw_log_write_flush(logfile_id_t id, const char* format, ...); int skygw_log_write_flush(logfile_id_t id, const char* format, ...);
int skygw_log_enable(logfile_id_t id); int skygw_log_enable(logfile_id_t id);
int skygw_log_disable(logfile_id_t id); int skygw_log_disable(logfile_id_t id);

View File

@ -57,9 +57,7 @@ int main(int argc, char** argv)
{ {
fgets(readbuff,4092,infile); fgets(readbuff,4092,infile);
psize = strlen(readbuff); psize = strlen(readbuff);
if(psize > 4092){ if(psize < 4092){
continue;
}
qbuff = gwbuf_alloc(psize + 7); qbuff = gwbuf_alloc(psize + 7);
*(qbuff->sbuf->data + 0) = (unsigned char)psize; *(qbuff->sbuf->data + 0) = (unsigned char)psize;
*(qbuff->sbuf->data + 1) = (unsigned char)(psize>>8); *(qbuff->sbuf->data + 1) = (unsigned char)(psize>>8);
@ -71,7 +69,7 @@ int main(int argc, char** argv)
fprintf(outfile,"%s\n",tok); fprintf(outfile,"%s\n",tok);
free(tok); free(tok);
gwbuf_free(qbuff); gwbuf_free(qbuff);
}
} }
fclose(infile); fclose(infile);
fclose(outfile); fclose(outfile);

View File

@ -509,10 +509,14 @@ bool succp = false;
pthread_self(), pthread_self(),
dcb->fd, dcb->fd,
dcb))); dcb)));
#endif /* SS_DEBUG */
#if defined(FAKE_CODE)
conn_open[dcb->fd] = false; conn_open[dcb->fd] = false;
#endif /* FAKE_CODE */
#if defined(SS_DEBUG)
ss_debug(dcb->fd = -1;) ss_debug(dcb->fd = -1;)
} }
#endif #endif /* SS_DEBUG */
succp = dcb_set_state(dcb, DCB_STATE_DISCONNECTED, NULL); succp = dcb_set_state(dcb, DCB_STATE_DISCONNECTED, NULL);
ss_dassert(succp); ss_dassert(succp);
dcb_next = dcb->memdata.next; dcb_next = dcb->memdata.next;
@ -658,7 +662,6 @@ int dcb_read(
int rc; int rc;
int n ; int n ;
int nread = 0; int nread = 0;
int eno = 0;
CHK_DCB(dcb); CHK_DCB(dcb);
while (true) while (true)
@ -669,8 +672,6 @@ int dcb_read(
if (rc == -1) if (rc == -1)
{ {
eno = errno;
errno = 0;
LOGIF(LE, (skygw_log_write_flush( LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR, LOGFILE_ERROR,
"Error : ioctl FIONREAD for dcb %p in " "Error : ioctl FIONREAD for dcb %p in "
@ -678,8 +679,8 @@ int dcb_read(
dcb, dcb,
STRDCBSTATE(dcb->state), STRDCBSTATE(dcb->state),
dcb->fd, dcb->fd,
eno, errno,
strerror(eno)))); strerror(errno))));
n = -1; n = -1;
goto return_n; goto return_n;
} }
@ -727,11 +728,10 @@ int dcb_read(
"for dcb %p fd %d, due %d, %s.", "for dcb %p fd %d, due %d, %s.",
dcb, dcb,
dcb->fd, dcb->fd,
eno, errno,
strerror(eno)))); strerror(errno))));
n = -1; n = -1;
ss_dassert(buffer != NULL);
goto return_n; goto return_n;
} }
GW_NOINTR_CALL(n = read(dcb->fd, GWBUF_DATA(buffer), bufsize); GW_NOINTR_CALL(n = read(dcb->fd, GWBUF_DATA(buffer), bufsize);
@ -739,10 +739,7 @@ int dcb_read(
if (n <= 0) if (n <= 0)
{ {
int eno = errno; if (errno != 0 && errno != EAGAIN && errno != EWOULDBLOCK)
errno = 0;
if (eno != 0 && eno != EAGAIN && eno != EWOULDBLOCK)
{ {
LOGIF(LE, (skygw_log_write_flush( LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR, LOGFILE_ERROR,
@ -751,8 +748,8 @@ int dcb_read(
dcb, dcb,
STRDCBSTATE(dcb->state), STRDCBSTATE(dcb->state),
dcb->fd, dcb->fd,
eno, errno,
strerror(eno)))); strerror(errno))));
} }
gwbuf_free(buffer); gwbuf_free(buffer);
goto return_n; goto return_n;

View File

@ -1073,16 +1073,29 @@ double avg1 = 0.0, avg5 = 0.0, avg15 = 0.0;
{ {
char *event_string char *event_string
= event_to_string(thread_data[i].event); = event_to_string(thread_data[i].event);
bool from_heap;
if (event_string == NULL) if (event_string == NULL)
{
from_heap = false;
event_string = "??"; event_string = "??";
}
else
{
from_heap = true;
}
dcb_printf(dcb, dcb_printf(dcb,
" %2d | %-10s | %6d | %-16p | %s\n", " %2d | %-10s | %6d | %-16p | %s\n",
i, state, thread_data[i].n_fds, i, state, thread_data[i].n_fds,
thread_data[i].cur_dcb, event_string); thread_data[i].cur_dcb, event_string);
if (from_heap)
{
free(event_string); free(event_string);
} }
} }
} }
}
/** /**
* The function used to calculate time based load data. This is called by the * The function used to calculate time based load data. This is called by the

View File

@ -269,7 +269,17 @@ MAXKEYS key;
errno, errno,
strerror(errno)))); strerror(errno))));
} }
chmod(secret_file, S_IRUSR);
if( chmod(secret_file, S_IRUSR) < 0)
{
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"Error : failed to change the permissions of the"
"secret file [%s]. Error %d, %s.",
secret_file,
errno,
strerror(errno))));
}
return 0; return 0;
} }

View File

@ -187,9 +187,10 @@ session_alloc(SERVICE *service, DCB *client_dcb)
session_free(session); session_free(session);
client_dcb->session = NULL; client_dcb->session = NULL;
session = NULL; session = NULL;
LOGIF(LE, (skygw_log_write_flush( LOGIF(LE, (skygw_log_write(
LOGFILE_ERROR, LOGFILE_ERROR,
"Error : Failed to create %s session.", "Error : Setting up filters failed. "
"Terminating session %s.",
service->name))); service->name)));
goto return_session; goto return_session;
} }

View File

@ -30,7 +30,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <errno.h>
#include <poll.h> #include <poll.h>
#include <dcb.h> #include <dcb.h>
@ -44,6 +44,7 @@ test1()
{ {
DCB *dcb; DCB *dcb;
int result; int result;
int eno = 0;
/* Poll tests */ /* Poll tests */
ss_dfprintf(stderr, ss_dfprintf(stderr,
@ -51,10 +52,35 @@ int result;
poll_init(); poll_init();
ss_dfprintf(stderr, "\t..done\nAdd a DCB"); ss_dfprintf(stderr, "\t..done\nAdd a DCB");
dcb = dcb_alloc(DCB_ROLE_SERVICE_LISTENER); dcb = dcb_alloc(DCB_ROLE_SERVICE_LISTENER);
if(dcb == NULL){
ss_dfprintf(stderr, "\nError on function call: dcb_alloc() returned NULL.\n");
return 1;
}
dcb->fd = socket(AF_UNIX, SOCK_STREAM, 0); dcb->fd = socket(AF_UNIX, SOCK_STREAM, 0);
poll_add_dcb(dcb);
poll_remove_dcb(dcb); if(dcb->fd < 0){
poll_add_dcb(dcb); ss_dfprintf(stderr, "\nError on function call: socket() returned %d: %s\n",errno,strerror(errno));
return 1;
}
if((eno = poll_add_dcb(dcb)) != 0){
ss_dfprintf(stderr, "\nError on function call: poll_add_dcb() returned %d.\n",eno);
return 1;
}
if((eno = poll_remove_dcb(dcb)) != 0){
ss_dfprintf(stderr, "\nError on function call: poll_remove_dcb() returned %d.\n",eno);
return 1;
}
if((eno = poll_add_dcb(dcb)) != 0){
ss_dfprintf(stderr, "\nError on function call: poll_add_dcb() returned %d.\n",eno);
return 1;
}
ss_dfprintf(stderr, "\t..done\nStart wait for events."); ss_dfprintf(stderr, "\t..done\nStart wait for events.");
sleep(10); sleep(10);
poll_shutdown(); poll_shutdown();

View File

@ -225,7 +225,9 @@ int gw_getsockerrno(
goto return_eno; goto return_eno;
} }
getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *)&eno, &elen); if(getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *)&eno, &elen) != 0){
eno = 0;
}
return_eno: return_eno:
return eno; return eno;

View File

@ -435,7 +435,7 @@ HINT_MODE mode = HM_EXECUTE;
token_free(tok); token_free(tok);
} /*< while */ } /*< while */
if (tok->token == TOK_EOL) if ( tok && tok->token == TOK_EOL)
{ {
token_free(tok); token_free(tok);
} }

View File

@ -398,7 +398,7 @@ routeQuery(FILTER *instance, void *session, GWBUF *queue)
QLA_INSTANCE *my_instance = (QLA_INSTANCE *)instance; QLA_INSTANCE *my_instance = (QLA_INSTANCE *)instance;
QLA_SESSION *my_session = (QLA_SESSION *)session; QLA_SESSION *my_session = (QLA_SESSION *)session;
char *ptr; char *ptr;
int length; int length = 0;
struct tm t; struct tm t;
struct timeval tv; struct timeval tv;

View File

@ -415,8 +415,9 @@ GWBUF *clone = NULL;
modutil_MySQL_Query(queue, &dummy, &length, &residual); modutil_MySQL_Query(queue, &dummy, &length, &residual);
clone = gwbuf_clone(queue); clone = gwbuf_clone(queue);
my_session->residual = residual; my_session->residual = residual;
free(ptr);
} }
free(ptr);
} }
/* Pass the query downstream */ /* Pass the query downstream */

View File

@ -314,10 +314,10 @@ char *remote, *user;
else else
my_session->userName = NULL; my_session->userName = NULL;
my_session->active = 1; my_session->active = 1;
if (my_instance->source && strcmp(my_session->clientHost, if (my_instance->source && my_session->clientHost && strcmp(my_session->clientHost,
my_instance->source)) my_instance->source))
my_session->active = 0; my_session->active = 0;
if (my_instance->user && strcmp(my_session->userName, if (my_instance->user && my_session->userName && strcmp(my_session->userName,
my_instance->user)) my_instance->user))
my_session->active = 0; my_session->active = 0;

View File

@ -159,7 +159,7 @@ MYSQL_MONITOR *handle;
handle->master = NULL; handle->master = NULL;
handle->connect_timeout=DEFAULT_CONNECT_TIMEOUT; handle->connect_timeout=DEFAULT_CONNECT_TIMEOUT;
handle->read_timeout=DEFAULT_READ_TIMEOUT; handle->read_timeout=DEFAULT_READ_TIMEOUT;
handle->write_timeout=DEFAULT_READ_TIMEOUT; handle->write_timeout=DEFAULT_WRITE_TIMEOUT;
spinlock_init(&handle->lock); spinlock_init(&handle->lock);
} }
handle->tid = (THREAD)thread_start(monitorMain, handle); handle->tid = (THREAD)thread_start(monitorMain, handle);

View File

@ -40,6 +40,7 @@
#include <httpd.h> #include <httpd.h>
#include <gw.h> #include <gw.h>
#include <modinfo.h> #include <modinfo.h>
#include <log_manager.h>
MODULE_INFO info = { MODULE_INFO info = {
MODULE_API_PROTOCOL, MODULE_API_PROTOCOL,
@ -171,7 +172,7 @@ HTTPD_session *client_data = NULL;
j++; j++;
} }
while (!ISspace(buf[j]) && (i < sizeof(url) - 1) && (j < sizeof(buf))) { while (!ISspace(buf[j]) && (i < sizeof(url) - 1) && (j < sizeof(buf) - 1)) {
url[i] = buf[j]; url[i] = buf[j];
i++; j++; i++; j++;
} }
@ -236,7 +237,7 @@ HTTPD_session *client_data = NULL;
dcb_printf(dcb, "Welcome to HTTPD MaxScale (c) %s\n\n", version_str); dcb_printf(dcb, "Welcome to HTTPD MaxScale (c) %s\n\n", version_str);
if (strcmp(url, "/show") == 0) { if (strcmp(url, "/show") == 0) {
if (strlen(query_string)) { if (query_string && strlen(query_string)) {
if (strcmp(query_string, "dcb") == 0) if (strcmp(query_string, "dcb") == 0)
dprintAllDCBs(dcb); dprintAllDCBs(dcb);
if (strcmp(query_string, "session") == 0) if (strcmp(query_string, "session") == 0)
@ -327,7 +328,8 @@ int n_connect = 0;
else else
{ {
atomic_add(&dcb->stats.n_accepts, 1); atomic_add(&dcb->stats.n_accepts, 1);
client = dcb_alloc(DCB_ROLE_REQUEST_HANDLER);
if((client = dcb_alloc(DCB_ROLE_REQUEST_HANDLER))){
client->fd = so; client->fd = so;
client->remote = strdup(inet_ntoa(addr.sin_addr)); client->remote = strdup(inet_ntoa(addr.sin_addr));
memcpy(&client->func, &MyObject, sizeof(GWPROTOCOL)); memcpy(&client->func, &MyObject, sizeof(GWPROTOCOL));
@ -346,6 +348,8 @@ int n_connect = 0;
n_connect++; n_connect++;
} }
} }
}
close(so);
return n_connect; return n_connect;
} }
@ -374,6 +378,7 @@ httpd_listen(DCB *listener, char *config)
struct sockaddr_in addr; struct sockaddr_in addr;
int one = 1; int one = 1;
int rc; int rc;
int syseno = 0;
memcpy(&listener->func, &MyObject, sizeof(GWPROTOCOL)); memcpy(&listener->func, &MyObject, sizeof(GWPROTOCOL));
if (!parse_bindconfig(config, 6442, &addr)) if (!parse_bindconfig(config, 6442, &addr))
@ -385,12 +390,16 @@ int rc;
} }
/* socket options */ /* socket options */
setsockopt(listener->fd, syseno = setsockopt(listener->fd,
SOL_SOCKET, SOL_SOCKET,
SO_REUSEADDR, SO_REUSEADDR,
(char *)&one, (char *)&one,
sizeof(one)); sizeof(one));
if(syseno != 0){
skygw_log_write_flush(LOGFILE_ERROR,"Error: Failed to set socket options. Error %d: %s",errno,strerror(errno));
return 0;
}
/* set NONBLOCKING mode */ /* set NONBLOCKING mode */
setnonblocking(listener->fd); setnonblocking(listener->fd);
@ -439,16 +448,20 @@ static int httpd_get_line(int sock, char *buf, int size) {
if (c == '\r') { if (c == '\r') {
n = recv(sock, &c, 1, MSG_PEEK); n = recv(sock, &c, 1, MSG_PEEK);
/* DEBUG printf("%02X\n", c); */ /* DEBUG printf("%02X\n", c); */
if ((n > 0) && (c == '\n')) if ((n > 0) && (c == '\n')) {
recv(sock, &c, 1, 0); if(recv(sock, &c, 1, 0) < 0){
else
c = '\n'; c = '\n';
} }
} else {
c = '\n';
}
}
buf[i] = c; buf[i] = c;
i++; i++;
} else } else {
c = '\n'; c = '\n';
} }
}
buf[i] = '\0'; buf[i] = '\0';

View File

@ -271,6 +271,11 @@ static int gw_read_backend_event(DCB *dcb) {
CHK_SESSION(session); CHK_SESSION(session);
if (session == NULL)
{
rc = 0;
goto return_with_lock;
}
router = session->service->router; router = session->service->router;
router_instance = session->service->router_instance; router_instance = session->service->router_instance;
rsession = session->router_session; rsession = session->router_session;
@ -388,12 +393,9 @@ static int gw_read_backend_event(DCB *dcb) {
dcb, dcb,
dcb->session))); dcb->session)));
if (session != NULL)
{
spinlock_acquire(&session->ses_lock); spinlock_acquire(&session->ses_lock);
session->state = SESSION_STATE_STOPPING; session->state = SESSION_STATE_STOPPING;
spinlock_release(&session->ses_lock); spinlock_release(&session->ses_lock);
}
ss_dassert(dcb->dcb_errhandle_called); ss_dassert(dcb->dcb_errhandle_called);
dcb_close(dcb); dcb_close(dcb);
} }
@ -1169,6 +1171,8 @@ static int backend_write_delayqueue(DCB *dcb)
CHK_SESSION(session); CHK_SESSION(session);
if (session != NULL)
{
router = session->service->router; router = session->service->router;
router_instance = session->service->router_instance; router_instance = session->service->router_instance;
rsession = session->router_session; rsession = session->router_session;
@ -1193,18 +1197,15 @@ static int backend_write_delayqueue(DCB *dcb)
gwbuf_free(errbuf); gwbuf_free(errbuf);
if (!succp) if (!succp)
{
if (session != NULL)
{ {
spinlock_acquire(&session->ses_lock); spinlock_acquire(&session->ses_lock);
session->state = SESSION_STATE_STOPPING; session->state = SESSION_STATE_STOPPING;
spinlock_release(&session->ses_lock); spinlock_release(&session->ses_lock);
}
ss_dassert(dcb->dcb_errhandle_called); ss_dassert(dcb->dcb_errhandle_called);
dcb_close(dcb); dcb_close(dcb);
} }
} }
}
return rc; return rc;
} }

View File

@ -940,6 +940,7 @@ int gw_MySQLListener(
char *config_bind) char *config_bind)
{ {
int l_so; int l_so;
int syseno = 0;
struct sockaddr_in serv_addr; struct sockaddr_in serv_addr;
struct sockaddr_un local_addr; struct sockaddr_un local_addr;
struct sockaddr *current_addr; struct sockaddr *current_addr;
@ -988,7 +989,10 @@ int gw_MySQLListener(
listen_dcb->fd = -1; listen_dcb->fd = -1;
// socket options // socket options
setsockopt(l_so, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)); if((syseno = setsockopt(l_so, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one))) != 0){
LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR,"Error: Failed to set socket options. Error %d: %s",errno,strerror(errno))));
}
// set NONBLOCKING mode // set NONBLOCKING mode
setnonblocking(l_so); setnonblocking(l_so);
@ -1068,9 +1072,9 @@ int gw_MySQLListener(
strerror(errno)); strerror(errno));
return 0; return 0;
} }
#if defined(SS_DEBUG) #if defined(FAKE_CODE)
conn_open[l_so] = true; conn_open[l_so] = true;
#endif #endif /* FAKE_CODE */
listen_dcb->func.accept = gw_MySQLAccept; listen_dcb->func.accept = gw_MySQLAccept;
return 1; return 1;
@ -1101,6 +1105,7 @@ int gw_MySQLAccept(DCB *listener)
int sendbuf = GW_BACKEND_SO_SNDBUF; int sendbuf = GW_BACKEND_SO_SNDBUF;
socklen_t optlen = sizeof(sendbuf); socklen_t optlen = sizeof(sendbuf);
int eno = 0; int eno = 0;
int syseno = 0;
int i = 0; int i = 0;
CHK_DCB(listener); CHK_DCB(listener);
@ -1201,13 +1206,22 @@ int gw_MySQLAccept(DCB *listener)
"%lu [gw_MySQLAccept] Accepted fd %d.", "%lu [gw_MySQLAccept] Accepted fd %d.",
pthread_self(), pthread_self(),
c_sock))); c_sock)));
#endif /* SS_DEBUG */
#if defined(FAKE_CODE)
conn_open[c_sock] = true; conn_open[c_sock] = true;
#endif #endif /* FAKE_CODE */
/* set nonblocking */ /* set nonblocking */
sendbuf = GW_CLIENT_SO_SNDBUF; sendbuf = GW_CLIENT_SO_SNDBUF;
setsockopt(c_sock, SOL_SOCKET, SO_SNDBUF, &sendbuf, optlen);
if((syseno = setsockopt(c_sock, SOL_SOCKET, SO_SNDBUF, &sendbuf, optlen)) != 0){
LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR,"Error: Failed to set socket options. Error %d: %s",errno,strerror(errno))));
}
sendbuf = GW_CLIENT_SO_RCVBUF; sendbuf = GW_CLIENT_SO_RCVBUF;
setsockopt(c_sock, SOL_SOCKET, SO_RCVBUF, &sendbuf, optlen);
if((syseno = setsockopt(c_sock, SOL_SOCKET, SO_RCVBUF, &sendbuf, optlen)) != 0){
LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR,"Error: Failed to set socket options. Error %d: %s",errno,strerror(errno))));
}
setnonblocking(c_sock); setnonblocking(c_sock);
client_dcb = dcb_alloc(DCB_ROLE_REQUEST_HANDLER); client_dcb = dcb_alloc(DCB_ROLE_REQUEST_HANDLER);

View File

@ -755,8 +755,6 @@ int gw_do_connect_to_backend(
so = socket(AF_INET,SOCK_STREAM,0); so = socket(AF_INET,SOCK_STREAM,0);
if (so < 0) { if (so < 0) {
int eno = errno;
errno = 0;
LOGIF(LE, (skygw_log_write_flush( LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR, LOGFILE_ERROR,
"Error: Establishing connection to backend server " "Error: Establishing connection to backend server "
@ -764,8 +762,8 @@ int gw_do_connect_to_backend(
"due %d, %s.", "due %d, %s.",
host, host,
port, port,
eno, errno,
strerror(eno)))); strerror(errno))));
rv = -1; rv = -1;
goto return_rv; goto return_rv;
} }
@ -776,8 +774,6 @@ int gw_do_connect_to_backend(
if(setsockopt(so, SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)) != 0) if(setsockopt(so, SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)) != 0)
{ {
int eno = errno;
errno = 0;
LOGIF(LE, (skygw_log_write_flush( LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR, LOGFILE_ERROR,
"Error: Failed to set socket options " "Error: Failed to set socket options "
@ -785,18 +781,16 @@ int gw_do_connect_to_backend(
"due %d, %s.", "due %d, %s.",
host, host,
port, port,
eno, errno,
strerror(eno)))); strerror(errno))));
rv = -1; rv = -1;
goto return_rv; /** Close socket */
goto close_so;
} }
bufsize = GW_BACKEND_SO_RCVBUF; bufsize = GW_BACKEND_SO_RCVBUF;
if(setsockopt(so, SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize)) != 0) if(setsockopt(so, SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize)) != 0)
{ {
int eno = errno;
errno = 0;
LOGIF(LE, (skygw_log_write_flush( LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR, LOGFILE_ERROR,
"Error: Failed to set socket options " "Error: Failed to set socket options "
@ -804,49 +798,35 @@ int gw_do_connect_to_backend(
"due %d, %s.", "due %d, %s.",
host, host,
port, port,
eno, errno,
strerror(eno)))); strerror(errno))));
rv = -1; rv = -1;
goto return_rv; /** Close socket */
goto close_so;
} }
/* set socket to as non-blocking here */ /* set socket to as non-blocking here */
setnonblocking(so); setnonblocking(so);
rv = connect(so, (struct sockaddr *)&serv_addr, sizeof(serv_addr)); rv = connect(so, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
if (rv != 0) { if (rv != 0)
int eno = errno; {
errno = 0; if (errno == EINPROGRESS)
{
if (eno == EINPROGRESS) {
rv = 1; rv = 1;
} else { }
int rc; else
int oldfd = so; {
LOGIF(LE, (skygw_log_write_flush( LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR, LOGFILE_ERROR,
"Error: Failed to connect backend server %s:%d, " "Error: Failed to connect backend server %s:%d, "
"due %d, %s.", "due %d, %s.",
host, host,
port, port,
eno, errno,
strerror(eno)))); strerror(errno))));
/*< Close newly created socket. */ /** Close socket */
rc = close(so); goto close_so;
if (rc != 0) {
int eno = errno;
errno = 0;
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"Error: Failed to "
"close socket %d due %d, %s.",
oldfd,
eno,
strerror(eno))));
}
goto return_rv;
} }
} }
*fd = so; *fd = so;
@ -858,11 +838,26 @@ int gw_do_connect_to_backend(
host, host,
port, port,
so))); so)));
#if defined(SS_DEBUG) #if defined(FAKE_CODE)
conn_open[so] = true; conn_open[so] = true;
#endif #endif /* FAKE_CODE */
return_rv: return_rv:
return rv; return rv;
close_so:
/*< Close newly created socket. */
if (close(so) != 0)
{
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"Error: Failed to "
"close socket %d due %d, %s.",
so,
errno,
strerror(errno))));
}
goto return_rv;
} }
/** /**
@ -1779,11 +1774,14 @@ void protocol_archive_srv_command(
{ {
p->protocol_cmd_history = server_command_copy(s1); p->protocol_cmd_history = server_command_copy(s1);
} }
else else /*< scan and count history commands */
{ {
len = 1;
while (h1->scom_next != NULL) while (h1->scom_next != NULL)
{ {
h1 = h1->scom_next; h1 = h1->scom_next;
len += 1;
} }
h1->scom_next = server_command_copy(s1); h1->scom_next = server_command_copy(s1);
} }
@ -2076,7 +2074,7 @@ char* get_username_from_auth(
first_letter = (char *)(data + 4 + 4 + 4 + 1 + 23); first_letter = (char *)(data + 4 + 4 + 4 + 1 + 23);
if (first_letter == '\0') if (*first_letter == '\0')
{ {
rval = NULL; rval = NULL;
goto retblock; goto retblock;

View File

@ -359,6 +359,7 @@ telnetd_listen(DCB *listener, char *config)
struct sockaddr_in addr; struct sockaddr_in addr;
int one = 1; int one = 1;
int rc; int rc;
int syseno = 0;
memcpy(&listener->func, &MyObject, sizeof(GWPROTOCOL)); memcpy(&listener->func, &MyObject, sizeof(GWPROTOCOL));
@ -372,7 +373,12 @@ int rc;
} }
// socket options // socket options
setsockopt(listener->fd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)); syseno = setsockopt(listener->fd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one));
if(syseno != 0){
LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR,"Error: Failed to set socket options. Error %d: %s",errno,strerror(errno))));
return 0;
}
// set NONBLOCKING mode // set NONBLOCKING mode
setnonblocking(listener->fd); setnonblocking(listener->fd);
// bind address and port // bind address and port

View File

@ -851,7 +851,9 @@ static void* newSession(
rses_end_locked_router_action(client_rses); rses_end_locked_router_action(client_rses);
/** Both Master and at least 1 slave must be found */ /**
* Master and at least <min_nslaves> slaves must be found
*/
if (!succp) { if (!succp) {
free(client_rses->rses_backend_ref); free(client_rses->rses_backend_ref);
free(client_rses); free(client_rses);
@ -1538,12 +1540,12 @@ skygw_query_type_t is_read_tmp_table(
} }
} }
if(tbl != NULL){
for(i = 0; i<tsize;i++) for(i = 0; i<tsize;i++)
{ {
free(tbl[i]); free(tbl[i]);
} }
if(tbl != NULL){
free(tbl); free(tbl);
} }
@ -4104,15 +4106,17 @@ static void handleError (
} }
session = backend_dcb->session; session = backend_dcb->session;
if (session != NULL) if (session == NULL || rses == NULL)
{
*succp = false;
return;
}
CHK_SESSION(session); CHK_SESSION(session);
CHK_CLIENT_RSES(rses);
switch (action) { switch (action) {
case ERRACT_NEW_CONNECTION: case ERRACT_NEW_CONNECTION:
{ {
if (rses != NULL)
CHK_CLIENT_RSES(rses);
if (!rses_begin_locked_router_action(rses)) if (!rses_begin_locked_router_action(rses))
{ {
*succp = false; *succp = false;

View File

@ -183,8 +183,7 @@ typedef enum skygw_chk_t {
((p) == MYSQL_COM_QUIT ? "COM_QUIT" : \ ((p) == MYSQL_COM_QUIT ? "COM_QUIT" : \
((p) == MYSQL_COM_STMT_PREPARE ? "MYSQL_COM_STMT_PREPARE" : \ ((p) == MYSQL_COM_STMT_PREPARE ? "MYSQL_COM_STMT_PREPARE" : \
((p) == MYSQL_COM_STMT_EXECUTE ? "MYSQL_COM_STMT_EXECUTE" : \ ((p) == MYSQL_COM_STMT_EXECUTE ? "MYSQL_COM_STMT_EXECUTE" : \
((p) == MYSQL_COM_UNDEFINED ? "MYSQL_COM_UNDEFINED" : \ "UNKNOWN MYSQL PACKET TYPE"))))))))))))))))))
"UNKNOWN MYSQL PACKET TYPE")))))))))))))))))))
#define STRDCBSTATE(s) ((s) == DCB_STATE_ALLOC ? "DCB_STATE_ALLOC" : \ #define STRDCBSTATE(s) ((s) == DCB_STATE_ALLOC ? "DCB_STATE_ALLOC" : \
((s) == DCB_STATE_POLLING ? "DCB_STATE_POLLING" : \ ((s) == DCB_STATE_POLLING ? "DCB_STATE_POLLING" : \
@ -531,8 +530,8 @@ typedef enum skygw_chk_t {
#if defined(SS_DEBUG) #if defined(FAKE_CODE)
bool conn_open[10240]; bool conn_open[10240];
#endif #endif /* FAKE_CODE */
#endif /* SKYGW_DEBUG_H */ #endif /* SKYGW_DEBUG_H */

View File

@ -1696,7 +1696,8 @@ return_succp:
} }
static bool file_write_footer( static bool file_write_footer(
skygw_file_t* file) skygw_file_t* file,
bool shutdown)
{ {
bool succp = false; bool succp = false;
size_t wbytes1; size_t wbytes1;
@ -1710,10 +1711,20 @@ static bool file_write_footer(
const char* header_buf4; const char* header_buf4;
CHK_FILE(file); CHK_FILE(file);
if (shutdown)
{
header_buf1 = "MaxScale is shut down.\t"; header_buf1 = "MaxScale is shut down.\t";
}
else
{
header_buf1 = "Closed file due log rotation.\t";
}
tslen = get_timestamp_len(); tslen = get_timestamp_len();
header_buf3 = (char *)malloc(tslen); header_buf3 = (char *)malloc(tslen);
if (header_buf3 == NULL) {
if (header_buf3 == NULL)
{
goto return_succp; goto return_succp;
} }
tslen = snprint_timestamp(header_buf3, tslen); tslen = snprint_timestamp(header_buf3, tslen);
@ -1729,7 +1740,8 @@ static bool file_write_footer(
wbytes1=fwrite((void*)header_buf1, len1, 1, file->sf_file); wbytes1=fwrite((void*)header_buf1, len1, 1, file->sf_file);
wbytes4=fwrite((void*)header_buf4, len4, 1, file->sf_file); wbytes4=fwrite((void*)header_buf4, len4, 1, file->sf_file);
if (wbytes1 != 1 || wbytes3 != 1 || wbytes4 != 1) { if (wbytes1 != 1 || wbytes3 != 1 || wbytes4 != 1)
{
fprintf(stderr, fprintf(stderr,
"* Writing header %s %s to %s failed.\n", "* Writing header %s %s to %s failed.\n",
header_buf1, header_buf1,
@ -1743,7 +1755,8 @@ static bool file_write_footer(
succp = true; succp = true;
return_succp: return_succp:
if (header_buf3 != NULL) { if (header_buf3 != NULL)
{
free(header_buf3); free(header_buf3);
} }
return succp; return succp;
@ -1886,31 +1899,33 @@ return_file:
return file; return file;
} }
void skygw_file_close(
void skygw_file_done( skygw_file_t* file,
skygw_file_t* file) bool shutdown)
{ {
int fd; int fd;
int err; int err;
if (file != NULL) { if (file != NULL)
{
CHK_FILE(file); CHK_FILE(file);
if (!file_write_footer(file)) { if (!file_write_footer(file, shutdown))
{
fprintf(stderr, fprintf(stderr,
"* Writing header of log file %s failed.\n", "* Writing footer to log file %s failed.\n",
file->sf_fname); file->sf_fname);
perror("SkyGW file open\n"); perror("Write fike footer\n");
} }
fd = fileno(file->sf_file); fd = fileno(file->sf_file);
fsync(fd); fsync(fd);
err = fclose(file->sf_file);
if (err != 0) { if ((err = fclose(file->sf_file)) != 0)
{
fprintf(stderr, fprintf(stderr,
"* Closing file %s failed : %s.\n", "* Closing file %s failed due to %d, %s.\n",
file->sf_fname, file->sf_fname,
errno,
strerror(errno)); strerror(errno));
} }
else else
@ -1922,7 +1937,6 @@ void skygw_file_done(
} }
} }
/** /**
* Find the given needle - user-provided literal - and replace it with * Find the given needle - user-provided literal - and replace it with
* replacement string. Separate user-provided literals from matching table names * replacement string. Separate user-provided literals from matching table names

View File

@ -145,7 +145,7 @@ EXTERN_C_BLOCK_END
/** Skygw file routines */ /** Skygw file routines */
skygw_file_t* skygw_file_init(char* fname, char* symlinkname); skygw_file_t* skygw_file_init(char* fname, char* symlinkname);
void skygw_file_done(skygw_file_t* file); void skygw_file_close(skygw_file_t* file, bool shutdown);
int skygw_file_write( int skygw_file_write(
skygw_file_t* file, skygw_file_t* file,
void* data, void* data,