diff --git a/CMakeLists.txt b/CMakeLists.txt index 00604caa2..a9d8cbef1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,6 +66,11 @@ if(GCOV) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lgcov") 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}) foreach(DIR ${MYSQL_DIR_ALL}) include_directories(${DIR}) diff --git a/log_manager/log_manager.cc b/log_manager/log_manager.cc index eef43efd0..0e923d9d1 100644 --- a/log_manager/log_manager.cc +++ b/log_manager/log_manager.cc @@ -162,7 +162,8 @@ struct logfile_st { mlist_t lf_blockbuf_list; int lf_buf_size; bool lf_flushflag; - int lf_spinlock; /**< lf_flushflag */ + bool lf_rotateflag; + int lf_spinlock; /**< lf_flushflag & lf_rotateflag */ int lf_npending_writes; #if defined(SS_DEBUG) skygw_chk_t lf_chk_tail; @@ -232,6 +233,11 @@ static bool logfile_init( static void logfile_done(logfile_t* logfile); static void logfile_free_memory(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( logmanager_t* logmanager, filewriter_t* fw, @@ -249,14 +255,16 @@ static bool logmanager_register(bool writep); static void logmanager_unregister(void); static bool logmanager_init_nomutex(int argc, char* argv[]); static void logmanager_done_nomutex(void); + static int logmanager_write_log( logfile_id_t id, - bool flush, - bool use_valist, - bool spread_down, - size_t len, - const char* str, - va_list valist); + bool flush, + bool use_valist, + bool spread_down, + bool rotate, + size_t len, + const char* str, + va_list valist); static blockbuf_t* blockbuf_init(logfile_id_t id); static void blockbuf_node_done(void* bb_data); @@ -393,8 +401,10 @@ static bool logmanager_init_nomutex( */ 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)) { err = 1; @@ -629,6 +639,8 @@ static logfile_t* logmanager_get_logfile( * * @param spread_down - in, use * 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 * length of formatted string @@ -650,6 +662,7 @@ static int logmanager_write_log( bool flush, bool use_valist, bool spread_down, + bool rotate, size_t str_len, const char* str, va_list valist) @@ -673,6 +686,7 @@ static int logmanager_write_log( true, false, false, + false, strlen(errstr)+1, errstr, valist); @@ -689,14 +703,21 @@ static int logmanager_write_log( CHK_LOGFILE(lf); /** - * When string pointer is NULL, case is skygw_log_flush and no - * writing is involved. With flush && str != NULL case is - * skygw_log_write_flush. + * When string pointer is NULL, operation is either flush or rotate. */ - if (str == NULL) { - ss_dassert(flush); - logfile_flush(lf); /**< here we wake up file writer */ - } else { + if (str == NULL) + { + if (flush) + { + 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 */ int safe_str_len; @@ -704,14 +725,13 @@ static int logmanager_write_log( /** Findout how much can be safely written with current block size */ if (timestamp_len-1+str_len > lf->lf_buf_size) - { - safe_str_len = lf->lf_buf_size; - } + { + safe_str_len = lf->lf_buf_size; + } else - { - safe_str_len = timestamp_len-1+str_len; - } - + { + safe_str_len = timestamp_len-1+str_len; + } /** * Seek write position and register to block buffer. * Then print formatted string to write position. @@ -719,32 +739,26 @@ static int logmanager_write_log( #if defined (SS_LOG_DEBUG) { - - char *copy,*tok; - int tokval; + char *copy,*tok; + int tokval; - simple_mutex_lock(&msg_mutex,true); + simple_mutex_lock(&msg_mutex,true); + copy = strdup(str); + tok = strtok(copy,"|"); + tok = strtok(NULL,"|"); - copy = strdup(str); - - tok = strtok(copy,"|"); - - tok = strtok(NULL,"|"); - - if(strstr(str,"message|") && tok){ - - tokval = atoi(tok); - - if(prevval > 0){ - ss_dassert(tokval == (prevval + 1)); - } - - prevval = tokval; - } - - free(copy); - simple_mutex_unlock(&msg_mutex); + if(strstr(str,"message|") && tok) + { + tokval = atoi(tok); + if(prevval > 0) + { + ss_dassert(tokval == (prevval + 1)); + } + prevval = tokval; + } + free(copy); + simple_mutex_unlock(&msg_mutex); } #endif @@ -801,7 +815,7 @@ static int logmanager_write_log( if (wp[safe_str_len-2] == '\n') { wp[safe_str_len-2]=' '; - } + } wp[safe_str_len-1] = '\n'; blockbuf_unregister(bb); @@ -860,7 +874,7 @@ static int logmanager_write_log( blockbuf_unregister(bb_c); } } /* if (spread_down) */ - } + } /* if (str == NULL) */ return_err: return err; @@ -1247,6 +1261,7 @@ static bool logfile_set_enabled( true, false, false, + false, strlen(errstr)+1, errstr, notused); @@ -1272,6 +1287,7 @@ static bool logfile_set_enabled( true, false, false, + false, strlen(logstr)+1, logstr, notused); @@ -1317,9 +1333,6 @@ int skygw_log_write_flush( /** * Find out the length of log string (to be formatted str). */ - - - va_start(valist, str); len = vsnprintf(NULL, 0, str, valist); va_end(valist); @@ -1331,7 +1344,7 @@ int skygw_log_write_flush( * Write log string to buffer and add to file write list. */ 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); if (err != 0) { @@ -1370,9 +1383,6 @@ int skygw_log_write( err = 1; goto return_unregister; } - - - /** * Find out the length of log string (to be formatted str). */ @@ -1388,7 +1398,7 @@ int skygw_log_write( */ 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); if (err != 0) { @@ -1415,7 +1425,7 @@ int skygw_log_flush( goto return_err; } 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) { fprintf(stderr, "skygw_log_flush failed.\n"); @@ -1428,6 +1438,60 @@ 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. * @@ -1841,6 +1905,237 @@ static void logfile_flush( 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. @@ -2122,12 +2417,6 @@ static bool logfile_init( { bool succp = false; 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; #if defined(SS_DEBUG) logfile->lf_chk_top = CHK_NUM_LOGFILE; @@ -2141,21 +2430,12 @@ static bool logfile_init( logfile->lf_name_seqno = 1; logfile->lf_lmgr = logmanager; logfile->lf_flushflag = false; + logfile->lf_rotateflag= false; logfile->lf_spinlock = 0; logfile->lf_store_shmem = store_shmem; logfile->lf_write_syslog = write_syslog; logfile->lf_buf_size = MAX_LOGSTRLEN; 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 * pointing to shm file is created and located to the file @@ -2173,7 +2453,7 @@ static bool logfile_init( if (c == NULL) { succp = false; - goto file_create_fail; + goto return_with_succp; } sprintf(c, "%s%d", shm_pathname_prefix, pid); logfile->lf_filepath = c; @@ -2182,7 +2462,7 @@ static bool logfile_init( errno != EEXIST) { succp = false; - goto file_create_fail; + goto return_with_succp; } logfile->lf_linkpath = strdup(fn->fn_logpath); logfile->lf_linkpath = add_slash(logfile->lf_linkpath); @@ -2192,114 +2472,11 @@ static bool logfile_init( logfile->lf_filepath = strdup(fn->fn_logpath); } logfile->lf_filepath = add_slash(logfile->lf_filepath); - - do { - 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; - } - } - - 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); + if (!(succp = logfile_create(logfile))) + { + goto return_with_succp; + } /** * Create a block buffer list for log file. Clients' writes go to buffers * from where separate log flusher thread writes them to disk. @@ -2334,11 +2511,11 @@ file_create_fail: CHK_LOGFILE(logfile); return_with_succp: - if (!succp) { + if (!succp) + { logfile_done(logfile); } - ss_dassert(logfile->lf_state == RUN || - logfile->lf_state == DONE); + ss_dassert(logfile->lf_state == RUN || logfile->lf_state == DONE); 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 fw - - * + * @param logmanager Log manager struct + * @param fw File writer struct + * @param clientmes Messaging from file writer to log manager + * @param logmes Messaging from loggers to file writer thread * - * @return - * - * - * @details (write detailed description here) + * @return true if succeed, false if failed * */ static bool filewriter_init( @@ -2416,11 +2591,9 @@ static bool filewriter_init( skygw_message_t* logmes) { bool succp = false; - int err; logfile_t* lf; logfile_id_t id; int i; - char* start_msg_str; CHK_LOGMANAGER(logmanager); @@ -2438,59 +2611,25 @@ static bool filewriter_init( if (fw->fwr_logmes == NULL || fw->fwr_clientmes == NULL) { 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; lf = logmanager_get_logfile(logmanager, id); - if (lf->lf_store_shmem) - { - /** 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) + if (!(succp = logfile_open_file(fw, lf))) { fprintf(stderr, - "Error : opening %s failed, %s. Exiting " + "Error : opening log file %s failed. Exiting " "MaxScale\n", - lf->lf_full_file_name, - strerror(errno)); - 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[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; + lf->lf_full_file_name); goto return_succp; - } - free(start_msg_str); - } + } + } /*< for */ fw->fwr_state = RUN; CHK_FILEWRITER(fw); succp = true; + return_succp: if (!succp) { filewriter_done(fw); @@ -2511,9 +2650,10 @@ static void filewriter_done( case INIT: fw->fwr_logmes = 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; - skygw_file_done(fw->fwr_file[id]); + skygw_file_close(fw->fwr_file[id], true); } fw->fwr_state = DONE; case DONE: @@ -2581,6 +2721,7 @@ static void* thr_filewriter_fun( blockbuf_state_t flush_blockbuf; /**< flush single block buffer. */ bool flush_logfile; /**< flush logfile */ bool flushall_logfiles;/**< flush all logfiles */ + bool rotate_logfile; /*< close current and open new file */ size_t vn1; size_t vn2; @@ -2602,7 +2743,8 @@ static void* thr_filewriter_fun( flushall_logfiles = skygw_thread_must_exit(thr); /** 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: /** * Get file pointer of current logfile. @@ -2611,13 +2753,45 @@ static void* thr_filewriter_fun( 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); - flush_logfile = lf->lf_flushflag; - lf->lf_flushflag = false; + flush_logfile = lf->lf_flushflag; + rotate_logfile = lf->lf_rotateflag; + lf->lf_flushflag = false; + lf->lf_rotateflag = false; 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 */ @@ -2651,14 +2825,14 @@ static void* thr_filewriter_fun( * buffer is at least half-full * -> write to disk */ - while(bb->bb_refcount > 0) { + while(bb->bb_refcount > 0) + { simple_mutex_unlock( &bb->bb_mutex); simple_mutex_lock( &bb->bb_mutex, true); } - err = skygw_file_write( file, (void *)bb->bb_buf, diff --git a/log_manager/log_manager.h b/log_manager/log_manager.h index 776b6cbb7..9266e865e 100644 --- a/log_manager/log_manager.h +++ b/log_manager/log_manager.h @@ -75,6 +75,7 @@ void skygw_logmanager_exit(void); void skygw_log_done(void); int skygw_log_write(logfile_id_t id, const char* format, ...); 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_enable(logfile_id_t id); int skygw_log_disable(logfile_id_t id); diff --git a/query_classifier/test/canonical_tests/canonizer.c b/query_classifier/test/canonical_tests/canonizer.c index d44478399..6df5f0049 100644 --- a/query_classifier/test/canonical_tests/canonizer.c +++ b/query_classifier/test/canonical_tests/canonizer.c @@ -57,21 +57,19 @@ int main(int argc, char** argv) { fgets(readbuff,4092,infile); psize = strlen(readbuff); - if(psize > 4092){ - continue; - } - qbuff = gwbuf_alloc(psize + 7); - *(qbuff->sbuf->data + 0) = (unsigned char)psize; - *(qbuff->sbuf->data + 1) = (unsigned char)(psize>>8); - *(qbuff->sbuf->data + 2) = (unsigned char)(psize>>16); - *(qbuff->sbuf->data + 4) = 0x03; - memcpy(qbuff->start + 5,readbuff,psize + 1); - parse_query(qbuff); - tok = skygw_get_canonical(qbuff); - fprintf(outfile,"%s\n",tok); - free(tok); - gwbuf_free(qbuff); - + if(psize < 4092){ + qbuff = gwbuf_alloc(psize + 7); + *(qbuff->sbuf->data + 0) = (unsigned char)psize; + *(qbuff->sbuf->data + 1) = (unsigned char)(psize>>8); + *(qbuff->sbuf->data + 2) = (unsigned char)(psize>>16); + *(qbuff->sbuf->data + 4) = 0x03; + memcpy(qbuff->start + 5,readbuff,psize + 1); + parse_query(qbuff); + tok = skygw_get_canonical(qbuff); + fprintf(outfile,"%s\n",tok); + free(tok); + gwbuf_free(qbuff); + } } fclose(infile); fclose(outfile); diff --git a/server/core/dcb.c b/server/core/dcb.c index da0f123e8..26ab592c5 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -509,10 +509,14 @@ bool succp = false; pthread_self(), dcb->fd, dcb))); +#endif /* SS_DEBUG */ +#if defined(FAKE_CODE) conn_open[dcb->fd] = false; +#endif /* FAKE_CODE */ +#if defined(SS_DEBUG) ss_debug(dcb->fd = -1;) } -#endif +#endif /* SS_DEBUG */ succp = dcb_set_state(dcb, DCB_STATE_DISCONNECTED, NULL); ss_dassert(succp); dcb_next = dcb->memdata.next; @@ -658,7 +662,6 @@ int dcb_read( int rc; int n ; int nread = 0; - int eno = 0; CHK_DCB(dcb); while (true) @@ -669,8 +672,6 @@ int dcb_read( if (rc == -1) { - eno = errno; - errno = 0; LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, "Error : ioctl FIONREAD for dcb %p in " @@ -678,8 +679,8 @@ int dcb_read( dcb, STRDCBSTATE(dcb->state), dcb->fd, - eno, - strerror(eno)))); + errno, + strerror(errno)))); n = -1; goto return_n; } @@ -727,22 +728,18 @@ int dcb_read( "for dcb %p fd %d, due %d, %s.", dcb, dcb->fd, - eno, - strerror(eno)))); + errno, + strerror(errno)))); n = -1; - ss_dassert(buffer != NULL); goto return_n; } GW_NOINTR_CALL(n = read(dcb->fd, GWBUF_DATA(buffer), bufsize); dcb->stats.n_reads++); if (n <= 0) - { - int eno = errno; - errno = 0; - - if (eno != 0 && eno != EAGAIN && eno != EWOULDBLOCK) + { + if (errno != 0 && errno != EAGAIN && errno != EWOULDBLOCK) { LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, @@ -751,10 +748,10 @@ int dcb_read( dcb, STRDCBSTATE(dcb->state), dcb->fd, - eno, - strerror(eno)))); + errno, + strerror(errno)))); } - gwbuf_free(buffer); + gwbuf_free(buffer); goto return_n; } nread += n; diff --git a/server/core/poll.c b/server/core/poll.c index 6bc730189..36e118b72 100644 --- a/server/core/poll.c +++ b/server/core/poll.c @@ -1073,13 +1073,26 @@ double avg1 = 0.0, avg5 = 0.0, avg15 = 0.0; { char *event_string = event_to_string(thread_data[i].event); + bool from_heap; + if (event_string == NULL) + { + from_heap = false; event_string = "??"; + } + else + { + from_heap = true; + } dcb_printf(dcb, " %2d | %-10s | %6d | %-16p | %s\n", i, state, thread_data[i].n_fds, thread_data[i].cur_dcb, event_string); - free(event_string); + + if (from_heap) + { + free(event_string); + } } } } diff --git a/server/core/secrets.c b/server/core/secrets.c index 2e09f661f..a27ee0d3b 100644 --- a/server/core/secrets.c +++ b/server/core/secrets.c @@ -269,7 +269,17 @@ MAXKEYS key; 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; } diff --git a/server/core/session.c b/server/core/session.c index 5795cd878..7170c6bcc 100644 --- a/server/core/session.c +++ b/server/core/session.c @@ -187,9 +187,10 @@ session_alloc(SERVICE *service, DCB *client_dcb) session_free(session); client_dcb->session = NULL; session = NULL; - LOGIF(LE, (skygw_log_write_flush( + LOGIF(LE, (skygw_log_write( LOGFILE_ERROR, - "Error : Failed to create %s session.", + "Error : Setting up filters failed. " + "Terminating session %s.", service->name))); goto return_session; } diff --git a/server/core/test/testpoll.c b/server/core/test/testpoll.c index 4d8d4cc04..a790e03a6 100644 --- a/server/core/test/testpoll.c +++ b/server/core/test/testpoll.c @@ -30,7 +30,7 @@ #include #include #include - +#include #include #include @@ -44,6 +44,7 @@ test1() { DCB *dcb; int result; + int eno = 0; /* Poll tests */ ss_dfprintf(stderr, @@ -51,10 +52,35 @@ int result; poll_init(); ss_dfprintf(stderr, "\t..done\nAdd a DCB"); 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); - poll_add_dcb(dcb); - poll_remove_dcb(dcb); - poll_add_dcb(dcb); + + if(dcb->fd < 0){ + 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."); sleep(10); poll_shutdown(); diff --git a/server/core/utils.c b/server/core/utils.c index 71c7888ed..937341f26 100644 --- a/server/core/utils.c +++ b/server/core/utils.c @@ -225,7 +225,9 @@ int gw_getsockerrno( 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; diff --git a/server/modules/filter/hint/hintparser.c b/server/modules/filter/hint/hintparser.c index df0888508..0d0e47dcb 100644 --- a/server/modules/filter/hint/hintparser.c +++ b/server/modules/filter/hint/hintparser.c @@ -435,7 +435,7 @@ HINT_MODE mode = HM_EXECUTE; token_free(tok); } /*< while */ - if (tok->token == TOK_EOL) + if ( tok && tok->token == TOK_EOL) { token_free(tok); } diff --git a/server/modules/filter/qlafilter.c b/server/modules/filter/qlafilter.c index 0f669b060..2f25ba1fb 100644 --- a/server/modules/filter/qlafilter.c +++ b/server/modules/filter/qlafilter.c @@ -398,7 +398,7 @@ routeQuery(FILTER *instance, void *session, GWBUF *queue) QLA_INSTANCE *my_instance = (QLA_INSTANCE *)instance; QLA_SESSION *my_session = (QLA_SESSION *)session; char *ptr; -int length; +int length = 0; struct tm t; struct timeval tv; diff --git a/server/modules/filter/tee.c b/server/modules/filter/tee.c index 94dc29ea0..43f7075c5 100644 --- a/server/modules/filter/tee.c +++ b/server/modules/filter/tee.c @@ -415,8 +415,9 @@ GWBUF *clone = NULL; modutil_MySQL_Query(queue, &dummy, &length, &residual); clone = gwbuf_clone(queue); my_session->residual = residual; - free(ptr); + } + free(ptr); } /* Pass the query downstream */ diff --git a/server/modules/filter/topfilter.c b/server/modules/filter/topfilter.c index e4c16b2ba..eaf471910 100644 --- a/server/modules/filter/topfilter.c +++ b/server/modules/filter/topfilter.c @@ -314,10 +314,10 @@ char *remote, *user; else my_session->userName = NULL; 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_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_session->active = 0; diff --git a/server/modules/monitor/galera_mon.c b/server/modules/monitor/galera_mon.c index a06e08cc4..274b6a30d 100644 --- a/server/modules/monitor/galera_mon.c +++ b/server/modules/monitor/galera_mon.c @@ -159,7 +159,7 @@ MYSQL_MONITOR *handle; handle->master = NULL; handle->connect_timeout=DEFAULT_CONNECT_TIMEOUT; handle->read_timeout=DEFAULT_READ_TIMEOUT; - handle->write_timeout=DEFAULT_READ_TIMEOUT; + handle->write_timeout=DEFAULT_WRITE_TIMEOUT; spinlock_init(&handle->lock); } handle->tid = (THREAD)thread_start(monitorMain, handle); diff --git a/server/modules/protocol/httpd.c b/server/modules/protocol/httpd.c index 9729fb99d..175e0ad12 100644 --- a/server/modules/protocol/httpd.c +++ b/server/modules/protocol/httpd.c @@ -40,6 +40,7 @@ #include #include #include +#include MODULE_INFO info = { MODULE_API_PROTOCOL, @@ -171,7 +172,7 @@ HTTPD_session *client_data = NULL; 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]; i++; j++; } @@ -236,7 +237,7 @@ HTTPD_session *client_data = NULL; dcb_printf(dcb, "Welcome to HTTPD MaxScale (c) %s\n\n", version_str); if (strcmp(url, "/show") == 0) { - if (strlen(query_string)) { + if (query_string && strlen(query_string)) { if (strcmp(query_string, "dcb") == 0) dprintAllDCBs(dcb); if (strcmp(query_string, "session") == 0) @@ -327,25 +328,28 @@ int n_connect = 0; else { atomic_add(&dcb->stats.n_accepts, 1); - client = dcb_alloc(DCB_ROLE_REQUEST_HANDLER); - client->fd = so; - client->remote = strdup(inet_ntoa(addr.sin_addr)); - memcpy(&client->func, &MyObject, sizeof(GWPROTOCOL)); + + if((client = dcb_alloc(DCB_ROLE_REQUEST_HANDLER))){ + client->fd = so; + client->remote = strdup(inet_ntoa(addr.sin_addr)); + memcpy(&client->func, &MyObject, sizeof(GWPROTOCOL)); - /* we don't need the session */ - client->session = NULL; + /* we don't need the session */ + client->session = NULL; - /* create the session data for HTTPD */ - client_data = (HTTPD_session *)calloc(1, sizeof(HTTPD_session)); - client->data = client_data; + /* create the session data for HTTPD */ + client_data = (HTTPD_session *)calloc(1, sizeof(HTTPD_session)); + client->data = client_data; - if (poll_add_dcb(client) == -1) - { - return n_connect; + if (poll_add_dcb(client) == -1) + { + return n_connect; + } + n_connect++; } - n_connect++; } } + close(so); return n_connect; } @@ -373,7 +377,8 @@ httpd_listen(DCB *listener, char *config) { struct sockaddr_in addr; int one = 1; -int rc; +int rc; +int syseno = 0; memcpy(&listener->func, &MyObject, sizeof(GWPROTOCOL)); if (!parse_bindconfig(config, 6442, &addr)) @@ -385,12 +390,16 @@ int rc; } /* socket options */ - setsockopt(listener->fd, + syseno = setsockopt(listener->fd, SOL_SOCKET, SO_REUSEADDR, (char *)&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 */ setnonblocking(listener->fd); @@ -439,15 +448,19 @@ static int httpd_get_line(int sock, char *buf, int size) { if (c == '\r') { n = recv(sock, &c, 1, MSG_PEEK); /* DEBUG printf("%02X\n", c); */ - if ((n > 0) && (c == '\n')) - recv(sock, &c, 1, 0); - else + if ((n > 0) && (c == '\n')) { + if(recv(sock, &c, 1, 0) < 0){ + c = '\n'; + } + } else { c = '\n'; + } } buf[i] = c; i++; - } else + } else { c = '\n'; + } } buf[i] = '\0'; diff --git a/server/modules/protocol/mysql_backend.c b/server/modules/protocol/mysql_backend.c index 57b74df63..fcb75e004 100644 --- a/server/modules/protocol/mysql_backend.c +++ b/server/modules/protocol/mysql_backend.c @@ -271,6 +271,11 @@ static int gw_read_backend_event(DCB *dcb) { CHK_SESSION(session); + if (session == NULL) + { + rc = 0; + goto return_with_lock; + } router = session->service->router; router_instance = session->service->router_instance; rsession = session->router_session; @@ -388,13 +393,10 @@ static int gw_read_backend_event(DCB *dcb) { dcb, dcb->session))); - if (session != NULL) - { - spinlock_acquire(&session->ses_lock); - session->state = SESSION_STATE_STOPPING; - spinlock_release(&session->ses_lock); - } - ss_dassert(dcb->dcb_errhandle_called); + spinlock_acquire(&session->ses_lock); + session->state = SESSION_STATE_STOPPING; + spinlock_release(&session->ses_lock); + ss_dassert(dcb->dcb_errhandle_called); dcb_close(dcb); } rc = 1; @@ -1168,43 +1170,42 @@ static int backend_write_delayqueue(DCB *dcb) SESSION *session = dcb->session; CHK_SESSION(session); - - router = session->service->router; - router_instance = session->service->router_instance; - rsession = session->router_session; + + if (session != NULL) + { + router = session->service->router; + router_instance = session->service->router_instance; + rsession = session->router_session; #if defined(SS_DEBUG) - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Backend write delayqueue error handling."))); + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Backend write delayqueue error handling."))); #endif - errbuf = mysql_create_custom_error( - 1, - 0, - "Failed to write buffered data to back-end server. " - "Buffer was empty or back-end was disconnected during " - "operation. Attempting to find a new backend."); - - router->handleError(router_instance, - rsession, - errbuf, - dcb, - ERRACT_NEW_CONNECTION, - &succp); - gwbuf_free(errbuf); + errbuf = mysql_create_custom_error( + 1, + 0, + "Failed to write buffered data to back-end server. " + "Buffer was empty or back-end was disconnected during " + "operation. Attempting to find a new backend."); + + router->handleError(router_instance, + rsession, + errbuf, + dcb, + ERRACT_NEW_CONNECTION, + &succp); + gwbuf_free(errbuf); - if (!succp) - { - if (session != NULL) - { + if (!succp) + { spinlock_acquire(&session->ses_lock); session->state = SESSION_STATE_STOPPING; spinlock_release(&session->ses_lock); - } - ss_dassert(dcb->dcb_errhandle_called); - dcb_close(dcb); - } - } - + ss_dassert(dcb->dcb_errhandle_called); + dcb_close(dcb); + } + } + } return rc; } @@ -1383,8 +1384,8 @@ static GWBUF* process_response_data ( GWBUF* readbuf, int nbytes_to_process) /*< number of new bytes read */ { - int npackets_left = 0; /*< response's packet count */ - size_t nbytes_left = 0; /*< nbytes to be read for the packet */ + int npackets_left = 0; /*< response's packet count */ + size_t nbytes_left = 0; /*< nbytes to be read for the packet */ MySQLProtocol* p; GWBUF* outbuf = NULL; diff --git a/server/modules/protocol/mysql_client.c b/server/modules/protocol/mysql_client.c index 0426b4b49..8a3e666f6 100644 --- a/server/modules/protocol/mysql_client.c +++ b/server/modules/protocol/mysql_client.c @@ -940,6 +940,7 @@ int gw_MySQLListener( char *config_bind) { int l_so; + int syseno = 0; struct sockaddr_in serv_addr; struct sockaddr_un local_addr; struct sockaddr *current_addr; @@ -988,7 +989,10 @@ int gw_MySQLListener( listen_dcb->fd = -1; // 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 setnonblocking(l_so); @@ -1068,9 +1072,9 @@ int gw_MySQLListener( strerror(errno)); return 0; } -#if defined(SS_DEBUG) +#if defined(FAKE_CODE) conn_open[l_so] = true; -#endif +#endif /* FAKE_CODE */ listen_dcb->func.accept = gw_MySQLAccept; return 1; @@ -1101,6 +1105,7 @@ int gw_MySQLAccept(DCB *listener) int sendbuf = GW_BACKEND_SO_SNDBUF; socklen_t optlen = sizeof(sendbuf); int eno = 0; + int syseno = 0; int i = 0; CHK_DCB(listener); @@ -1201,13 +1206,22 @@ int gw_MySQLAccept(DCB *listener) "%lu [gw_MySQLAccept] Accepted fd %d.", pthread_self(), c_sock))); +#endif /* SS_DEBUG */ +#if defined(FAKE_CODE) conn_open[c_sock] = true; -#endif +#endif /* FAKE_CODE */ /* set nonblocking */ 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; - 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); client_dcb = dcb_alloc(DCB_ROLE_REQUEST_HANDLER); diff --git a/server/modules/protocol/mysql_common.c b/server/modules/protocol/mysql_common.c index 1ddbabed3..374cabfb5 100644 --- a/server/modules/protocol/mysql_common.c +++ b/server/modules/protocol/mysql_common.c @@ -741,13 +741,13 @@ int gw_send_authentication_to_backend( * */ int gw_do_connect_to_backend( - char *host, - int port, - int* fd) + char *host, + int port, + int *fd) { struct sockaddr_in serv_addr; - int rv; - int so = 0; + int rv; + int so = 0; int bufsize; memset(&serv_addr, 0, sizeof serv_addr); @@ -755,8 +755,6 @@ int gw_do_connect_to_backend( so = socket(AF_INET,SOCK_STREAM,0); if (so < 0) { - int eno = errno; - errno = 0; LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, "Error: Establishing connection to backend server " @@ -764,8 +762,8 @@ int gw_do_connect_to_backend( "due %d, %s.", host, port, - eno, - strerror(eno)))); + errno, + strerror(errno)))); rv = -1; goto return_rv; } @@ -774,29 +772,25 @@ int gw_do_connect_to_backend( serv_addr.sin_port = htons(port); bufsize = GW_BACKEND_SO_SNDBUF; - if(setsockopt(so, SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)) != 0) - { - int eno = errno; - errno = 0; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error: Failed to set socket options " - "%s:%d failed.\n\t\t Socket configuration failed " - "due %d, %s.", - host, - port, - eno, - strerror(eno)))); - rv = -1; - goto return_rv; - } - + if(setsockopt(so, SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)) != 0) + { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error: Failed to set socket options " + "%s:%d failed.\n\t\t Socket configuration failed " + "due %d, %s.", + host, + port, + errno, + strerror(errno)))); + rv = -1; + /** Close socket */ + goto close_so; + } bufsize = GW_BACKEND_SO_RCVBUF; - if(setsockopt(so, SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize)) != 0) - { - int eno = errno; - errno = 0; + if(setsockopt(so, SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize)) != 0) + { LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, "Error: Failed to set socket options " @@ -804,49 +798,35 @@ int gw_do_connect_to_backend( "due %d, %s.", host, port, - eno, - strerror(eno)))); - rv = -1; - goto return_rv; - } + errno, + strerror(errno)))); + rv = -1; + /** Close socket */ + goto close_so; + } /* set socket to as non-blocking here */ setnonblocking(so); rv = connect(so, (struct sockaddr *)&serv_addr, sizeof(serv_addr)); - if (rv != 0) { - int eno = errno; - errno = 0; - - if (eno == EINPROGRESS) { + if (rv != 0) + { + if (errno == EINPROGRESS) + { rv = 1; - } else { - int rc; - int oldfd = so; - + } + else + { LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, "Error: Failed to connect backend server %s:%d, " "due %d, %s.", host, port, - eno, - strerror(eno)))); - /*< Close newly created socket. */ - rc = 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; + errno, + strerror(errno)))); + /** Close socket */ + goto close_so; } } *fd = so; @@ -858,11 +838,26 @@ int gw_do_connect_to_backend( host, port, so))); -#if defined(SS_DEBUG) +#if defined(FAKE_CODE) conn_open[so] = true; -#endif +#endif /* FAKE_CODE */ + 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); } - else + else /*< scan and count history commands */ { + len = 1; + while (h1->scom_next != NULL) { h1 = h1->scom_next; + len += 1; } 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); - if (first_letter == '\0') + if (*first_letter == '\0') { rval = NULL; goto retblock; diff --git a/server/modules/protocol/telnetd.c b/server/modules/protocol/telnetd.c index 8250c9caf..e8c208c20 100644 --- a/server/modules/protocol/telnetd.c +++ b/server/modules/protocol/telnetd.c @@ -358,7 +358,8 @@ telnetd_listen(DCB *listener, char *config) { struct sockaddr_in addr; int one = 1; -int rc; +int rc; +int syseno = 0; memcpy(&listener->func, &MyObject, sizeof(GWPROTOCOL)); @@ -372,7 +373,12 @@ int rc; } // 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 setnonblocking(listener->fd); // bind address and port diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index 43d5643a6..eca2a5615 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -851,7 +851,9 @@ static void* newSession( rses_end_locked_router_action(client_rses); - /** Both Master and at least 1 slave must be found */ + /** + * Master and at least slaves must be found + */ if (!succp) { free(client_rses->rses_backend_ref); free(client_rses); @@ -1538,12 +1540,12 @@ skygw_query_type_t is_read_tmp_table( } } - for(i = 0; isession; - if (session != NULL) - CHK_SESSION(session); + if (session == NULL || rses == NULL) + { + *succp = false; + return; + } + CHK_SESSION(session); + CHK_CLIENT_RSES(rses); switch (action) { case ERRACT_NEW_CONNECTION: - { - if (rses != NULL) - CHK_CLIENT_RSES(rses); - + { if (!rses_begin_locked_router_action(rses)) { *succp = false; diff --git a/utils/skygw_debug.h b/utils/skygw_debug.h index 3d43451b5..7294a7ba6 100644 --- a/utils/skygw_debug.h +++ b/utils/skygw_debug.h @@ -183,8 +183,7 @@ typedef enum skygw_chk_t { ((p) == MYSQL_COM_QUIT ? "COM_QUIT" : \ ((p) == MYSQL_COM_STMT_PREPARE ? "MYSQL_COM_STMT_PREPARE" : \ ((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" : \ ((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]; -#endif +#endif /* FAKE_CODE */ #endif /* SKYGW_DEBUG_H */ diff --git a/utils/skygw_utils.cc b/utils/skygw_utils.cc index f801b497f..088e76ae3 100644 --- a/utils/skygw_utils.cc +++ b/utils/skygw_utils.cc @@ -1696,7 +1696,8 @@ return_succp: } static bool file_write_footer( - skygw_file_t* file) + skygw_file_t* file, + bool shutdown) { bool succp = false; size_t wbytes1; @@ -1710,10 +1711,20 @@ static bool file_write_footer( const char* header_buf4; CHK_FILE(file); - header_buf1 = "MaxScale is shut down.\t"; + + if (shutdown) + { + header_buf1 = "MaxScale is shut down.\t"; + } + else + { + header_buf1 = "Closed file due log rotation.\t"; + } tslen = get_timestamp_len(); header_buf3 = (char *)malloc(tslen); - if (header_buf3 == NULL) { + + if (header_buf3 == NULL) + { goto return_succp; } 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); 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, "* Writing header %s %s to %s failed.\n", header_buf1, @@ -1743,7 +1755,8 @@ static bool file_write_footer( succp = true; return_succp: - if (header_buf3 != NULL) { + if (header_buf3 != NULL) + { free(header_buf3); } return succp; @@ -1886,43 +1899,44 @@ return_file: return file; } - -void skygw_file_done( - skygw_file_t* file) +void skygw_file_close( + skygw_file_t* file, + bool shutdown) { - int fd; - int err; - - if (file != NULL) { - CHK_FILE(file); - - if (!file_write_footer(file)) { - fprintf(stderr, - "* Writing header of log file %s failed.\n", - file->sf_fname); - perror("SkyGW file open\n"); - } - - fd = fileno(file->sf_file); - fsync(fd); - err = fclose(file->sf_file); - - if (err != 0) { - fprintf(stderr, - "* Closing file %s failed : %s.\n", - file->sf_fname, - strerror(errno)); - } - else + int fd; + int err; + + if (file != NULL) + { + CHK_FILE(file); + + if (!file_write_footer(file, shutdown)) + { + fprintf(stderr, + "* Writing footer to log file %s failed.\n", + file->sf_fname); + perror("Write fike footer\n"); + } + fd = fileno(file->sf_file); + fsync(fd); + + if ((err = fclose(file->sf_file)) != 0) + { + fprintf(stderr, + "* Closing file %s failed due to %d, %s.\n", + file->sf_fname, + errno, + strerror(errno)); + } + else { ss_dfprintf(stderr, "Closed %s\n", file->sf_fname); free(file->sf_fname); free(file); } - } + } } - /** * Find the given needle - user-provided literal - and replace it with * replacement string. Separate user-provided literals from matching table names diff --git a/utils/skygw_utils.h b/utils/skygw_utils.h index 17ce75f7d..2379dbb03 100644 --- a/utils/skygw_utils.h +++ b/utils/skygw_utils.h @@ -145,7 +145,7 @@ EXTERN_C_BLOCK_END /** Skygw file routines */ 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( skygw_file_t* file, void* data,