Merge branch 'develop' into firewall
This commit is contained in:
		@ -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})
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
@ -630,6 +640,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);
 | 
			
		||||
			copy = strdup(str);
 | 
			
		||||
			tok = strtok(copy,"|");
 | 
			
		||||
			tok = strtok(NULL,"|");
 | 
			
		||||
 | 
			
		||||
		  simple_mutex_lock(&msg_mutex,true);
 | 
			
		||||
 | 
			
		||||
		  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
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
@ -2193,113 +2473,10 @@ static bool logfile_init(
 | 
			
		||||
        }
 | 
			
		||||
        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 - <usage>
 | 
			
		||||
 *          <description>
 | 
			
		||||
 * @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,
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
 | 
			
		||||
@ -57,21 +57,19 @@ int main(int argc, char** argv)
 | 
			
		||||
		{
 | 
			
		||||
			fgets(readbuff,4092,infile);
 | 
			
		||||
			psize = strlen(readbuff);
 | 
			
		||||
			if(psize > 4092){
 | 
			
		||||
				continue;
 | 
			
		||||
			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);
 | 
			
		||||
			}			
 | 
			
		||||
			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);
 | 
			
		||||
 | 
			
		||||
@ -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,11 +728,10 @@ 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);
 | 
			
		||||
@ -739,10 +739,7 @@ int dcb_read(
 | 
			
		||||
                
 | 
			
		||||
                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;
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
@ -30,7 +30,7 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <poll.h>
 | 
			
		||||
#include <dcb.h>
 | 
			
		||||
 | 
			
		||||
@ -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();
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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 */
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
 | 
			
		||||
@ -40,6 +40,7 @@
 | 
			
		||||
#include <httpd.h>
 | 
			
		||||
#include <gw.h>
 | 
			
		||||
#include <modinfo.h>
 | 
			
		||||
#include <log_manager.h>
 | 
			
		||||
 | 
			
		||||
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));
 | 
			
		||||
			
 | 
			
		||||
			/* we don't need the session */
 | 
			
		||||
			client->session = NULL;
 | 
			
		||||
			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));
 | 
			
		||||
 | 
			
		||||
			/* create the session data for HTTPD */
 | 
			
		||||
			client_data = (HTTPD_session *)calloc(1, sizeof(HTTPD_session));
 | 
			
		||||
			client->data = client_data;
 | 
			
		||||
				/* we don't need the session */
 | 
			
		||||
				client->session = NULL;
 | 
			
		||||
 | 
			
		||||
			if (poll_add_dcb(client) == -1)
 | 
			
		||||
			{
 | 
			
		||||
				return n_connect;
 | 
			
		||||
				/* 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;
 | 
			
		||||
					}
 | 
			
		||||
				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';
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
@ -1169,42 +1171,41 @@ static int backend_write_delayqueue(DCB *dcb)
 | 
			
		||||
                
 | 
			
		||||
                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.");
 | 
			
		||||
			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);
 | 
			
		||||
			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;
 | 
			
		||||
      
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -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 <min_nslaves> 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; i<tsize;i++)
 | 
			
		||||
		{
 | 
			
		||||
			free(tbl[i]);
 | 
			
		||||
		}
 | 
			
		||||
	
 | 
			
		||||
	if(tbl != NULL){
 | 
			
		||||
		for(i = 0; i<tsize;i++)
 | 
			
		||||
			{
 | 
			
		||||
				free(tbl[i]);
 | 
			
		||||
			}
 | 
			
		||||
		free(tbl);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
@ -4104,15 +4106,17 @@ static void handleError (
 | 
			
		||||
	}
 | 
			
		||||
        session = backend_dcb->session;
 | 
			
		||||
        
 | 
			
		||||
        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;
 | 
			
		||||
 | 
			
		||||
@ -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 */
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
	int fd;
 | 
			
		||||
	int err;
 | 
			
		||||
	
 | 
			
		||||
        if (file != NULL) {
 | 
			
		||||
                CHK_FILE(file);
 | 
			
		||||
	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");
 | 
			
		||||
                }
 | 
			
		||||
		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);
 | 
			
		||||
		
 | 
			
		||||
                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
 | 
			
		||||
		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 
 | 
			
		||||
 | 
			
		||||
@ -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,
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user