Merge branch 'develop' of github.com:skysql/MaxScale into develop

Conflicts:
	server/modules/filter/regexfilter.c
This commit is contained in:
Mark Riddoch
2014-11-07 13:16:15 +00:00
12 changed files with 203 additions and 113 deletions

View File

@ -423,9 +423,17 @@ static bool logmanager_init_nomutex(
return_succp: return_succp:
if (err != 0) if (err != 0)
{ {
skygw_message_done(lm->lm_clientmes); if (lm != NULL)
skygw_message_done(lm->lm_logmes); {
if (lm->lm_clientmes != NULL)
{
skygw_message_done(lm->lm_clientmes);
}
if (lm->lm_logmes != NULL)
{
skygw_message_done(lm->lm_logmes);
}
}
/** This releases memory of all created objects */ /** This releases memory of all created objects */
logmanager_done_nomutex(); logmanager_done_nomutex();
fprintf(stderr, "*\n* Error : Initializing log manager failed.\n*\n"); fprintf(stderr, "*\n* Error : Initializing log manager failed.\n*\n");
@ -1895,15 +1903,18 @@ static char* form_full_file_name(
fprintf(stderr, "Error : Too long file name= %d.\n", (int)fnlen); fprintf(stderr, "Error : Too long file name= %d.\n", (int)fnlen);
goto return_filename; goto return_filename;
} }
filename = (char*)calloc(1, fnlen); filename = (char*)calloc(1, fnlen);
snprintf(seqnostr, s+1, "%d", seqno);
if (seqnostr != NULL)
{
snprintf(seqnostr, s+1, "%d", seqno);
}
for (i=0, p=parts; p->sp_string != NULL; i++, p=p->sp_next) for (i=0, p=parts; p->sp_string != NULL; i++, p=p->sp_next)
{ {
if (i == seqnoidx) if (seqnostr != NULL && i == seqnoidx)
{ {
strcat(filename, seqnostr); strcat(filename, seqnostr); /*< add sequence number */
} }
strcat(filename, p->sp_string); strcat(filename, p->sp_string);

View File

@ -45,8 +45,9 @@ int main(int argc, char** argv)
} }
block_size = atoi(argv[3]); block_size = atoi(argv[3]);
if(block_size < 1){ if(block_size < 1 || block_size > 1024){
fprintf(stderr,"Message size too small, must be at least 1 byte long."); fprintf(stderr,"Message size too small or large, must be at least 1 byte long and must not exceed 1024 bytes.");
return 1;
} }

View File

@ -1088,30 +1088,31 @@ char** skygw_get_table_names(GWBUF* querybuf,int* tblsize, bool fullnames)
} }
} }
if(tmp != NULL){
char *catnm = NULL;
char *catnm = NULL; if(fullnames)
{
if(fullnames) if(tbl->db && strcmp(tbl->db,"skygw_virtual") != 0)
{ {
if(tbl->db && strcmp(tbl->db,"skygw_virtual") != 0) catnm = (char*)calloc(strlen(tbl->db) + strlen(tbl->table_name) + 2,sizeof(char));
{ strcpy(catnm,tbl->db);
catnm = (char*)calloc(strlen(tbl->db) + strlen(tbl->table_name) + 2,sizeof(char)); strcat(catnm,".");
strcpy(catnm,tbl->db); strcat(catnm,tbl->table_name);
strcat(catnm,"."); }
strcat(catnm,tbl->table_name); }
}
}
if(catnm) if(catnm)
{ {
tables[i++] = catnm; tables[i++] = catnm;
} }
else else
{ {
tables[i++] = strdup(tbl->table_name); tables[i++] = strdup(tbl->table_name);
} }
tbl=tbl->next_local; tbl=tbl->next_local;
}
} }
lex->current_select = lex->current_select->next_select_in_list(); lex->current_select = lex->current_select->next_select_in_list();
} }

View File

@ -57,6 +57,9 @@ int main(int argc, char** argv)
{ {
fgets(readbuff,4092,infile); fgets(readbuff,4092,infile);
psize = strlen(readbuff); psize = strlen(readbuff);
if(psize < 0 || psize > 4092){
continue;
}
qbuff = gwbuf_alloc(psize + 7); qbuff = gwbuf_alloc(psize + 7);
*(qbuff->sbuf->data + 0) = (unsigned char)psize; *(qbuff->sbuf->data + 0) = (unsigned char)psize;
*(qbuff->sbuf->data + 1) = (unsigned char)(psize>>8); *(qbuff->sbuf->data + 1) = (unsigned char)(psize>>8);

View File

@ -1268,7 +1268,7 @@ SERVER *server;
(PERCENT_TYPE|COUNT_TYPE)); (PERCENT_TYPE|COUNT_TYPE));
} }
if (!succp) if (!succp && param != NULL)
{ {
LOGIF(LM, (skygw_log_write( LOGIF(LM, (skygw_log_write(
LOGFILE_MESSAGE, LOGFILE_MESSAGE,
@ -1359,10 +1359,10 @@ SERVER *server;
serviceSetUser(obj->element, serviceSetUser(obj->element,
user, user,
auth); auth);
if (enable_root_user && service) if (enable_root_user)
serviceEnableRootUser(service, atoi(enable_root_user)); serviceEnableRootUser(service, atoi(enable_root_user));
if (allow_localhost_match_wildcard_host) if (allow_localhost_match_wildcard_host && service)
serviceEnableLocalhostMatchWildcardHost( serviceEnableLocalhostMatchWildcardHost(
service, service,
atoi(allow_localhost_match_wildcard_host)); atoi(allow_localhost_match_wildcard_host));

View File

@ -1479,7 +1479,11 @@ int main(int argc, char **argv)
bool succp; bool succp;
sprintf(buf, "%s/log", home_dir); sprintf(buf, "%s/log", home_dir);
mkdir(buf, 0777); if(mkdir(buf, 0777) != 0){
fprintf(stderr,
"Error: Cannot create log directory: %s\n",buf);
goto return_main;
}
argv[0] = "MaxScale"; argv[0] = "MaxScale";
argv[1] = "-j"; argv[1] = "-j";
argv[2] = buf; argv[2] = buf;

View File

@ -39,7 +39,7 @@
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
char *enc; char *enc, *pw;
if (argc != 2) if (argc != 2)
{ {
@ -47,9 +47,21 @@ char *enc;
exit(1); exit(1);
} }
if ((enc = encryptPassword(argv[1])) != NULL) pw = calloc(81,sizeof(char));
if(pw == NULL){
fprintf(stderr, "Error: cannot allocate enough memory.");
exit(1);
}
strncpy(pw,argv[1],80);
if ((enc = encryptPassword(pw)) != NULL){
printf("%s\n", enc); printf("%s\n", enc);
else }else{
fprintf(stderr, "Failed to encode the password\n"); fprintf(stderr, "Failed to encode the password\n");
}
free(pw);
return 0; return 0;
} }

View File

@ -61,7 +61,9 @@ int buflen;
ss_info_dassert(0 == GWBUF_EMPTY(buffer), "Buffer should not be empty"); ss_info_dassert(0 == GWBUF_EMPTY(buffer), "Buffer should not be empty");
ss_info_dassert(GWBUF_IS_TYPE_UNDEFINED(buffer), "Buffer type should be undefined"); ss_info_dassert(GWBUF_IS_TYPE_UNDEFINED(buffer), "Buffer type should be undefined");
ss_dfprintf(stderr, "\t..done\nSet a hint for the buffer"); ss_dfprintf(stderr, "\t..done\nSet a hint for the buffer");
hint = hint_create_parameter(NULL, strdup("name"), "value"); char* name = strdup("name");
hint = hint_create_parameter(NULL, name, "value");
free(name);
gwbuf_add_hint(buffer, hint); gwbuf_add_hint(buffer, hint);
ss_info_dassert(hint == buffer->hint, "Buffer should point to first and only hint"); ss_info_dassert(hint == buffer->hint, "Buffer should point to first and only hint");
ss_dfprintf(stderr, "\t..done\nSet a property for the buffer"); ss_dfprintf(stderr, "\t..done\nSet a property for the buffer");

View File

@ -415,6 +415,7 @@ GWBUF *clone = NULL;
modutil_MySQL_Query(queue, &dummy, &length, &residual); modutil_MySQL_Query(queue, &dummy, &length, &residual);
clone = gwbuf_clone(queue); clone = gwbuf_clone(queue);
my_session->residual = residual; my_session->residual = residual;
free(ptr);
} }
} }

View File

@ -137,8 +137,8 @@ FILTER_PARAMETER** read_params(int* paramc)
do_read = 0; do_read = 0;
} }
} }
FILTER_PARAMETER** params; FILTER_PARAMETER** params = NULL;
if((params = malloc(sizeof(FILTER_PARAMETER*)*(pc+1)))!=NULL){ if((params = malloc(sizeof(FILTER_PARAMETER*)*(pc+1))) != NULL){
for(i = 0;i<pc;i++){ for(i = 0;i<pc;i++){
params[i] = malloc(sizeof(FILTER_PARAMETER)); params[i] = malloc(sizeof(FILTER_PARAMETER));
if(params[i]){ if(params[i]){
@ -147,10 +147,10 @@ FILTER_PARAMETER** read_params(int* paramc)
} }
free(names[i]); free(names[i]);
free(values[i]); free(values[i]);
} }
params[pc] = NULL;
*paramc = pc;
} }
params[pc] = NULL;
*paramc = pc;
return params; return params;
} }
@ -303,7 +303,7 @@ int load_query()
int i, qcount = 0, qbuff_sz = 10, rval = 0; int i, qcount = 0, qbuff_sz = 10, rval = 0;
int offset = 0; int offset = 0;
unsigned int qlen = 0; unsigned int qlen = 0;
buffer = (char*)malloc(4092*sizeof(char)); buffer = (char*)calloc(4092,sizeof(char));
if(buffer == NULL){ if(buffer == NULL){
printf("Error: cannot allocate enough memory.\n"); printf("Error: cannot allocate enough memory.\n");
skygw_log_write(LOGFILE_ERROR,"Error: cannot allocate enough memory.\n"); skygw_log_write(LOGFILE_ERROR,"Error: cannot allocate enough memory.\n");
@ -925,8 +925,9 @@ GWBUF* gen_packet(PACKET pkt)
int process_opts(int argc, char** argv) int process_opts(int argc, char** argv)
{ {
int fd = open_file("harness.cnf",1), buffsize = 1024; unsigned int fd = open_file("harness.cnf",1), buffsize = 1024;
int rd,fsize,rdsz; int rd,rdsz;
unsigned int fsize;
char *buff = calloc(buffsize,sizeof(char)), *tok = NULL; char *buff = calloc(buffsize,sizeof(char)), *tok = NULL;
/**Parse 'harness.cnf' file*/ /**Parse 'harness.cnf' file*/

View File

@ -453,12 +453,13 @@ static int gw_read_backend_event(DCB *dcb) {
0, 0,
"Read from backend failed"); "Read from backend failed");
router->handleError(router_instance, router->handleError(
session->router_session, router_instance,
errbuf, session->router_session,
dcb, errbuf,
ERRACT_NEW_CONNECTION, dcb,
&succp); ERRACT_NEW_CONNECTION,
&succp);
gwbuf_free(errbuf); gwbuf_free(errbuf);
if (!succp) if (!succp)
@ -1170,7 +1171,7 @@ static int backend_write_delayqueue(DCB *dcb)
0, 0,
"Failed to write buffered data to back-end server. " "Failed to write buffered data to back-end server. "
"Buffer was empty or back-end was disconnected during " "Buffer was empty or back-end was disconnected during "
"operation. Session will be closed."); "operation. Attempting to find a new backend.");
router->handleError(router_instance, router->handleError(router_instance,
rsession, rsession,

View File

@ -1406,7 +1406,7 @@ void check_drop_tmp_table(
{ {
int tsize = 0, klen = 0,i; int tsize = 0, klen = 0,i;
char** tbl; char** tbl = NULL;
char *hkey,*dbname; char *hkey,*dbname;
MYSQL_session* data; MYSQL_session* data;
@ -1425,29 +1425,31 @@ void check_drop_tmp_table(
if (is_drop_table_query(querybuf)) if (is_drop_table_query(querybuf))
{ {
tbl = skygw_get_table_names(querybuf,&tsize,false); tbl = skygw_get_table_names(querybuf,&tsize,false);
if(tbl != NULL){
for(i = 0; i<tsize; i++) for(i = 0; i<tsize; i++)
{ {
klen = strlen(dbname) + strlen(tbl[i]) + 2; klen = strlen(dbname) + strlen(tbl[i]) + 2;
hkey = calloc(klen,sizeof(char)); hkey = calloc(klen,sizeof(char));
strcpy(hkey,dbname); strcpy(hkey,dbname);
strcat(hkey,"."); strcat(hkey,".");
strcat(hkey,tbl[i]); strcat(hkey,tbl[i]);
if (rses_prop_tmp && if (rses_prop_tmp &&
rses_prop_tmp->rses_prop_data.temp_tables) rses_prop_tmp->rses_prop_data.temp_tables)
{ {
if (hashtable_delete(rses_prop_tmp->rses_prop_data.temp_tables, if (hashtable_delete(rses_prop_tmp->rses_prop_data.temp_tables,
(void *)hkey)) (void *)hkey))
{ {
LOGIF(LT, (skygw_log_write(LOGFILE_TRACE, LOGIF(LT, (skygw_log_write(LOGFILE_TRACE,
"Temporary table dropped: %s",hkey))); "Temporary table dropped: %s",hkey)));
} }
} }
free(tbl[i]); free(tbl[i]);
free(hkey); free(hkey);
} }
free(tbl);
free(tbl);
}
} }
} }
@ -1468,7 +1470,7 @@ skygw_query_type_t is_read_tmp_table(
bool target_tmp_table = false; bool target_tmp_table = false;
int tsize = 0, klen = 0,i; int tsize = 0, klen = 0,i;
char** tbl; char** tbl = NULL;
char *hkey,*dbname; char *hkey,*dbname;
MYSQL_session* data; MYSQL_session* data;
@ -1493,7 +1495,7 @@ skygw_query_type_t is_read_tmp_table(
{ {
tbl = skygw_get_table_names(querybuf,&tsize,false); tbl = skygw_get_table_names(querybuf,&tsize,false);
if (tsize > 0) if (tbl != NULL && tsize > 0)
{ {
/** Query targets at least one table */ /** Query targets at least one table */
for(i = 0; i<tsize && !target_tmp_table && tbl[i]; i++) for(i = 0; i<tsize && !target_tmp_table && tbl[i]; i++)
@ -1529,7 +1531,10 @@ skygw_query_type_t is_read_tmp_table(
{ {
free(tbl[i]); free(tbl[i]);
} }
free(tbl);
if(tbl != NULL){
free(tbl);
}
return qtype; return qtype;
} }
@ -1714,27 +1719,41 @@ static int routeQuery(
LOGIF(LE, LOGIF(LE,
(skygw_log_write_flush( (skygw_log_write_flush(
LOGFILE_ERROR, LOGFILE_ERROR,
"Error: Failed to route %s:%s:\"%s\" to " "Error: Can't route %s:%s:\"%s\" to "
"backend server. %s.", "backend server. Router is closed.",
STRPACKETTYPE(packet_type), STRPACKETTYPE(packet_type),
STRQTYPE(qtype), STRQTYPE(qtype),
(query_str == NULL ? "(empty)" : query_str), (query_str == NULL ? "(empty)" : query_str))));
(rses_is_closed ? "Router was closed" : free(query_str);
"Router has no backend servers where to "
"route to"))));
} }
ret = 0;
goto retblock; goto retblock;
} }
/** Read stored master DCB pointer */
if ((master_dcb = router_cli_ses->rses_master_ref->bref_dcb) == NULL)
{
char* query_str = modutil_get_query(querybuf);
CHK_DCB(master_dcb);
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"Error: Can't route %s:%s:\"%s\" to "
"backend server. Session doesn't have a Master "
"node",
STRPACKETTYPE(packet_type),
STRQTYPE(qtype),
(query_str == NULL ? "(empty)" : query_str))));
free(query_str);
ret = 0;
goto retblock;
}
/** If buffer is not contiguous, make it such */ /** If buffer is not contiguous, make it such */
if (querybuf->next != NULL) if (querybuf->next != NULL)
{ {
querybuf = gwbuf_make_contiguous(querybuf); querybuf = gwbuf_make_contiguous(querybuf);
} }
/** Read stored master DCB pointer */
master_dcb = router_cli_ses->rses_master_ref->bref_dcb;
CHK_DCB(master_dcb);
switch(packet_type) { switch(packet_type) {
case MYSQL_COM_QUIT: /*< 1 QUIT will close all sessions */ case MYSQL_COM_QUIT: /*< 1 QUIT will close all sessions */
case MYSQL_COM_INIT_DB: /*< 2 DDL must go to the master */ case MYSQL_COM_INIT_DB: /*< 2 DDL must go to the master */
@ -2030,13 +2049,13 @@ static int routeQuery(
NULL, NULL,
MAX_RLAG_UNDEFINED); MAX_RLAG_UNDEFINED);
if (succp && (master_dcb == NULL || master_dcb == curr_master_dcb)) if (succp && master_dcb == curr_master_dcb)
{ {
atomic_add(&inst->stats.n_master, 1); atomic_add(&inst->stats.n_master, 1);
target_dcb = master_dcb; target_dcb = master_dcb;
} }
else else
{ {
if (succp && master_dcb != curr_master_dcb) if (succp && master_dcb != curr_master_dcb)
{ {
LOGIF(LT, (skygw_log_write(LOGFILE_TRACE, LOGIF(LT, (skygw_log_write(LOGFILE_TRACE,
@ -4077,6 +4096,22 @@ static void handleError (
return; return;
} }
if (rses->rses_master_ref->bref_dcb == backend_dcb)
{
/** Master failed, can't recover */
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"Error : Master node have failed. "
"Session will be closed.")));
*succp = false;
rses_end_locked_router_action(rses);
return;
}
/**
* This is called in hope of getting replacement for
* failed slave(s).
*/
*succp = handle_error_new_connection(inst, *succp = handle_error_new_connection(inst,
rses, rses,
backend_dcb, backend_dcb,
@ -4119,7 +4154,18 @@ static void handle_error_reply_client(
} }
/** /**
* This must be called with router lock * Check if there is backend reference pointing at failed DCB, and reset its
* flags. Then clear DCB's callback and finally : try to find replacement(s)
* for failed slave(s).
*
* This must be called with router lock.
*
* @param inst router instance
* @param rses router client session
* @param dcb failed DCB
* @param errmsg error message which is sent to client if it is waiting
*
* @return true if there are enough backend connections to continue, false if not
*/ */
static bool handle_error_new_connection( static bool handle_error_new_connection(
ROUTER_INSTANCE* inst, ROUTER_INSTANCE* inst,
@ -4139,25 +4185,14 @@ static bool handle_error_new_connection(
ses = backend_dcb->session; ses = backend_dcb->session;
CHK_SESSION(ses); CHK_SESSION(ses);
bref = get_bref_from_dcb(rses, backend_dcb); /**
* If bref == NULL it has been replaced already with another one.
/** failed DCB has already been replaced */
if (bref == NULL)
{
succp = true;
goto return_succp;
}
/**
* Error handler is already called for this DCB because
* it's not polling anymore. It can be assumed that
* it succeed because rses isn't closed.
*/ */
if (backend_dcb->state != DCB_STATE_POLLING) if ((bref = get_bref_from_dcb(rses, backend_dcb)) == NULL)
{ {
succp = true; succp = true;
goto return_succp; goto return_succp;
} }
CHK_BACKEND_REF(bref); CHK_BACKEND_REF(bref);
if (BREF_IS_WAITING_RESULT(bref)) if (BREF_IS_WAITING_RESULT(bref))
@ -4169,6 +4204,17 @@ static bool handle_error_new_connection(
} }
bref_clear_state(bref, BREF_IN_USE); bref_clear_state(bref, BREF_IN_USE);
bref_set_state(bref, BREF_CLOSED); bref_set_state(bref, BREF_CLOSED);
/**
* Error handler is already called for this DCB because
* it's not polling anymore. It can be assumed that
* it succeed because rses isn't closed.
*/
if (backend_dcb->state != DCB_STATE_POLLING)
{
succp = true;
goto return_succp;
}
/** /**
* Remove callback because this DCB won't be used * Remove callback because this DCB won't be used
* unless it is reconnected later, and then the callback * unless it is reconnected later, and then the callback
@ -4293,8 +4339,8 @@ static bool have_enough_servers(
} }
else else
{ {
double pct = (*p_rses)->rses_config.rw_max_slave_conn_percent/100; int pct = (*p_rses)->rses_config.rw_max_slave_conn_percent/100;
double nservers = (double)router_nsrv*pct; int nservers = router_nsrv*pct;
if ((*p_rses)->rses_config.rw_max_slave_conn_count < min_nsrv) if ((*p_rses)->rses_config.rw_max_slave_conn_count < min_nsrv)
{ {
@ -4313,11 +4359,11 @@ static bool have_enough_servers(
LOGFILE_ERROR, LOGFILE_ERROR,
"Error : Unable to start %s service. There are " "Error : Unable to start %s service. There are "
"too few backend servers configured in " "too few backend servers configured in "
"MaxScale.cnf. Found %d%% when at least %.0f%% " "MaxScale.cnf. Found %d%% when at least %d%% "
"would be required.", "would be required.",
router->service->name, router->service->name,
(*p_rses)->rses_config.rw_max_slave_conn_percent, (*p_rses)->rses_config.rw_max_slave_conn_percent,
min_nsrv/(((double)router_nsrv)/100)))); min_nsrv/(router_nsrv/100))));
} }
} }
free(*p_rses); free(*p_rses);
@ -4380,7 +4426,14 @@ static int rses_get_max_replication_lag(
return conf_max_rlag; return conf_max_rlag;
} }
/**
* Finds out if there is a backend reference pointing at the DCB given as
* parameter.
* @param rses router client session
* @param dcb DCB
*
* @return backend reference pointer if succeed or NULL
*/
static backend_ref_t* get_bref_from_dcb( static backend_ref_t* get_bref_from_dcb(
ROUTER_CLIENT_SES* rses, ROUTER_CLIENT_SES* rses,
DCB* dcb) DCB* dcb)