From eb0cf745ca069ef58f263bb5477e1b8058b6599b Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Wed, 18 Nov 2015 11:49:44 +0200 Subject: [PATCH 01/21] Filters not being found is now an error instead of a warning. The log message was labeled as a warning instead of an error and finding out the real reason why MaxScale didn't start when a filter wasn't found was difficult. --- server/core/service.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/core/service.c b/server/core/service.c index 89c5f21ec..a5ae6e8f9 100644 --- a/server/core/service.c +++ b/server/core/service.c @@ -1113,7 +1113,7 @@ serviceSetFilters(SERVICE *service, char *filters) } else { - MXS_WARNING("Unable to find filter '%s' for service '%s'\n", + MXS_ERROR("Unable to find filter '%s' for service '%s'\n", filter_name, service->name); rval = false; break; From d59c6a35704761533c7a5c399ed8586f97e330bd Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Wed, 18 Nov 2015 10:34:50 +0200 Subject: [PATCH 02/21] readwritesplit: skygw_log_writes replaced. --- .../routing/readwritesplit/readwritesplit.c | 164 +++++++++--------- 1 file changed, 82 insertions(+), 82 deletions(-) diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index f69ec3e3b..83204966f 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -1555,15 +1555,15 @@ void check_drop_tmp_table( if(router_cli_ses == NULL || querybuf == NULL) { - skygw_log_write(LE,"[%s] Error: NULL parameters passed: %p %p", - __FUNCTION__,router_cli_ses,querybuf); + MXS_ERROR("[%s] Error: NULL parameters passed: %p %p", + __FUNCTION__,router_cli_ses,querybuf); return; } if(router_cli_ses->rses_master_ref == NULL) { - skygw_log_write(LE,"[%s] Error: Master server reference is NULL.", - __FUNCTION__); + MXS_ERROR("[%s] Error: Master server reference is NULL.", + __FUNCTION__); return; } @@ -1572,9 +1572,9 @@ void check_drop_tmp_table( if(master_dcb == NULL || master_dcb->session == NULL) { - skygw_log_write(LE,"[%s] Error: Master server DBC is NULL. " - "This means that the connection to the master server is already " - "closed while a query is still being routed.",__FUNCTION__); + MXS_ERROR("[%s] Error: Master server DBC is NULL. " + "This means that the connection to the master server is already " + "closed while a query is still being routed.",__FUNCTION__); return; } @@ -1584,7 +1584,7 @@ void check_drop_tmp_table( if(data == NULL) { - skygw_log_write(LE,"[%s] Error: User data in master server DBC is NULL.",__FUNCTION__); + MXS_ERROR("[%s] Error: User data in master server DBC is NULL.",__FUNCTION__); return; } @@ -1646,15 +1646,15 @@ static skygw_query_type_t is_read_tmp_table( if(router_cli_ses == NULL || querybuf == NULL) { - skygw_log_write(LE,"[%s] Error: NULL parameters passed: %p %p", - __FUNCTION__,router_cli_ses,querybuf); + MXS_ERROR("[%s] Error: NULL parameters passed: %p %p", + __FUNCTION__,router_cli_ses,querybuf); return type; } if(router_cli_ses->rses_master_ref == NULL) { - skygw_log_write(LE,"[%s] Error: Master server reference is NULL.", - __FUNCTION__); + MXS_ERROR("[%s] Error: Master server reference is NULL.", + __FUNCTION__); return type; } @@ -1663,9 +1663,9 @@ static skygw_query_type_t is_read_tmp_table( if(master_dcb == NULL || master_dcb->session == NULL) { - skygw_log_write(LE,"[%s] Error: Master server DBC is NULL. " - "This means that the connection to the master server is already " - "closed while a query is still being routed.",__FUNCTION__); + MXS_ERROR("[%s] Error: Master server DBC is NULL. " + "This means that the connection to the master server is already " + "closed while a query is still being routed.",__FUNCTION__); return qtype; } CHK_DCB(master_dcb); @@ -1674,7 +1674,7 @@ static skygw_query_type_t is_read_tmp_table( if(data == NULL) { - skygw_log_write(LE,"[%s] Error: User data in master server DBC is NULL.",__FUNCTION__); + MXS_ERROR("[%s] Error: User data in master server DBC is NULL.",__FUNCTION__); return qtype; } @@ -1746,15 +1746,15 @@ static void check_create_tmp_table( if(router_cli_ses == NULL || querybuf == NULL) { - skygw_log_write(LE,"[%s] Error: NULL parameters passed: %p %p", - __FUNCTION__,router_cli_ses,querybuf); + MXS_ERROR("[%s] Error: NULL parameters passed: %p %p", + __FUNCTION__,router_cli_ses,querybuf); return; } if(router_cli_ses->rses_master_ref == NULL) { - skygw_log_write(LE,"[%s] Error: Master server reference is NULL.", - __FUNCTION__); + MXS_ERROR("[%s] Error: Master server reference is NULL.", + __FUNCTION__); return; } @@ -1763,9 +1763,9 @@ static void check_create_tmp_table( if(master_dcb == NULL || master_dcb->session == NULL) { - skygw_log_write(LE,"[%s] Error: Master server DCB is NULL. " - "This means that the connection to the master server is already " - "closed while a query is still being routed.",__FUNCTION__); + MXS_ERROR("[%s] Error: Master server DCB is NULL. " + "This means that the connection to the master server is already " + "closed while a query is still being routed.",__FUNCTION__); return; } @@ -1775,7 +1775,7 @@ static void check_create_tmp_table( if(data == NULL) { - skygw_log_write(LE,"[%s] Error: User data in master server DBC is NULL.",__FUNCTION__); + MXS_ERROR("[%s] Error: User data in master server DBC is NULL.",__FUNCTION__); return; } @@ -2099,8 +2099,8 @@ static bool route_single_stmt( packet_type = MYSQL_COM_UNDEFINED; rses->rses_load_active = false; route_target = TARGET_MASTER; - skygw_log_write_flush(LT, "> LOAD DATA LOCAL INFILE finished: " - "%lu bytes sent.", rses->rses_load_data_sent + gwbuf_length(querybuf)); + MXS_INFO("> LOAD DATA LOCAL INFILE finished: " + "%lu bytes sent.", rses->rses_load_data_sent + gwbuf_length(querybuf)); } else { @@ -2230,24 +2230,23 @@ static bool route_single_stmt( char* contentstr = strndup(data, MIN(len, RWSPLIT_TRACE_MSG_LEN)); char* qtypestr = skygw_get_qtype_str(qtype); - skygw_log_write(LOGFILE_TRACE, - "> Autocommit: %s, trx is %s, cmd: %s, type: %s, " - "stmt: %s%s %s", - (rses->rses_autocommit_enabled ? "[enabled]" : "[disabled]"), - (rses->rses_transaction_active ? "[open]" : "[not open]"), - STRPACKETTYPE(ptype), - (qtypestr == NULL ? "N/A" : qtypestr), - contentstr, - (querybuf->hint == NULL ? "" : ", Hint:"), - (querybuf->hint == NULL ? "" : STRHINTTYPE(querybuf->hint->type))); + MXS_INFO("> Autocommit: %s, trx is %s, cmd: %s, type: %s, " + "stmt: %s%s %s", + (rses->rses_autocommit_enabled ? "[enabled]" : "[disabled]"), + (rses->rses_transaction_active ? "[open]" : "[not open]"), + STRPACKETTYPE(ptype), + (qtypestr == NULL ? "N/A" : qtypestr), + contentstr, + (querybuf->hint == NULL ? "" : ", Hint:"), + (querybuf->hint == NULL ? "" : STRHINTTYPE(querybuf->hint->type))); free(contentstr); free(qtypestr); } else { - skygw_log_write(LT, "> Processing LOAD DATA LOCAL INFILE: " - "%lu bytes sent.", rses->rses_load_data_sent); + MXS_INFO("> Processing LOAD DATA LOCAL INFILE: " + "%lu bytes sent.", rses->rses_load_data_sent); } } /** @@ -3014,7 +3013,7 @@ static void bref_clear_state( { if(bref == NULL) { - skygw_log_write(LE,"[%s] Error: NULL parameter.",__FUNCTION__); + MXS_ERROR("[%s] Error: NULL parameter.",__FUNCTION__); return; } if (state != BREF_WAITING_RESULT) @@ -3040,10 +3039,10 @@ static void bref_clear_state( ss_dassert(prev2 > 0); if(prev2 <= 0) { - skygw_log_write(LE,"[%s] Error: negative current operation count in backend %s:%u", - __FUNCTION__, - bref->bref_backend->backend_server->name, - bref->bref_backend->backend_server->port); + MXS_ERROR("[%s] Error: negative current operation count in backend %s:%u", + __FUNCTION__, + bref->bref_backend->backend_server->name, + bref->bref_backend->backend_server->port); } } } @@ -3055,7 +3054,7 @@ static void bref_set_state( { if(bref == NULL) { - skygw_log_write(LE,"[%s] Error: NULL parameter.",__FUNCTION__); + MXS_ERROR("[%s] Error: NULL parameter.",__FUNCTION__); return; } if (state != BREF_WAITING_RESULT) @@ -3072,11 +3071,11 @@ static void bref_set_state( ss_dassert(prev1 >= 0); if(prev1 < 0) { - skygw_log_write(LE,"[%s] Error: negative number of connections waiting for " - "results in backend %s:%u", - __FUNCTION__, - bref->bref_backend->backend_server->name, - bref->bref_backend->backend_server->port); + MXS_ERROR("[%s] Error: negative number of connections waiting for " + "results in backend %s:%u", + __FUNCTION__, + bref->bref_backend->backend_server->name, + bref->bref_backend->backend_server->port); } /** Increase global operation count */ prev2 = atomic_add( @@ -3084,10 +3083,10 @@ static void bref_set_state( ss_dassert(prev2 >= 0); if(prev2 < 0) { - skygw_log_write(LE,"[%s] Error: negative current operation count in backend %s:%u", - __FUNCTION__, - bref->bref_backend->backend_server->name, - bref->bref_backend->backend_server->port); + MXS_ERROR("[%s] Error: negative current operation count in backend %s:%u", + __FUNCTION__, + bref->bref_backend->backend_server->name, + bref->bref_backend->backend_server->port); } } } @@ -3561,7 +3560,7 @@ static rses_property_t* rses_property_init( prop = (rses_property_t*)calloc(1, sizeof(rses_property_t)); if (prop == NULL) { - skygw_log_write(LE,"Error: Malloc returned NULL. (%s:%d)",__FILE__,__LINE__); + MXS_ERROR("Error: Malloc returned NULL. (%s:%d)",__FILE__,__LINE__); return NULL; } prop->rses_prop_type = prop_type; @@ -3582,7 +3581,7 @@ static void rses_property_done( { if(prop == NULL) { - skygw_log_write(LE,"[%s] Error: NULL parameter.",__FUNCTION__); + MXS_ERROR("[%s] Error: NULL parameter.",__FUNCTION__); return; } CHK_RSES_PROP(prop); @@ -3622,12 +3621,12 @@ static int rses_property_add( { if(rses == NULL) { - skygw_log_write(LE,"Error: Router client session is NULL. (%s:%d)",__FILE__,__LINE__); + MXS_ERROR("Router client session is NULL. (%s:%d)",__FILE__,__LINE__); return -1; } if(prop == NULL) { - skygw_log_write(LE,"Error: Router client session property is NULL. (%s:%d)",__FILE__,__LINE__); + MXS_ERROR("Router client session property is NULL. (%s:%d)",__FILE__,__LINE__); return -1; } rses_property_t* p; @@ -3665,7 +3664,7 @@ static mysql_sescmd_t* rses_property_get_sescmd( if(prop == NULL) { - skygw_log_write(LE,"[%s] Error: NULL parameter.",__FUNCTION__); + MXS_ERROR("[%s] Error: NULL parameter.",__FUNCTION__); return NULL; } @@ -3715,7 +3714,7 @@ static void mysql_sescmd_done( { if(sescmd == NULL) { - skygw_log_write(LE,"[%s] Error: NULL parameter.",__FUNCTION__); + MXS_ERROR("[%s] Error: NULL parameter.",__FUNCTION__); return; } CHK_RSES_PROP(sescmd->my_sescmd_prop); @@ -3787,10 +3786,9 @@ static GWBUF* sescmd_cursor_process_replies( if(bref->reply_cmd != scmd->reply_cmd) { - skygw_log_write(LOGFILE_TRACE,"Backend " - "server '%s' response differs from master's response. " - "Closing connection.", - bref->bref_backend->backend_server->unique_name); + MXS_INFO("Backend server '%s' response differs from master's response. " + "Closing connection.", + bref->bref_backend->backend_server->unique_name); sescmd_cursor_set_active(scur,false); bref_clear_state(bref,BREF_QUERY_ACTIVE); bref_clear_state(bref,BREF_IN_USE); @@ -3813,8 +3811,8 @@ static GWBUF* sescmd_cursor_process_replies( /** Mark the rest session commands as replied */ scmd->my_sescmd_is_replied = true; scmd->reply_cmd = *((unsigned char*)replybuf->start + 4); - skygw_log_write(LT,"Master '%s' responded to a session command.", - bref->bref_backend->backend_server->unique_name); + MXS_INFO("Master '%s' responded to a session command.", + bref->bref_backend->backend_server->unique_name); int i; for(i=0;irses_nbackends;i++) @@ -3833,8 +3831,9 @@ static GWBUF* sescmd_cursor_process_replies( if(ses->rses_backend_ref[i].bref_dcb) dcb_close(ses->rses_backend_ref[i].bref_dcb); *reconnect = true; - skygw_log_write(LT,"Disabling slave %s:%d, result differs from master's result. Master: %d Slave: %d", - ses->rses_backend_ref[i].bref_backend->backend_server->name, + MXS_INFO("Disabling slave %s:%d, result differs from " + "master's result. Master: %d Slave: %d", + ses->rses_backend_ref[i].bref_backend->backend_server->name, ses->rses_backend_ref[i].bref_backend->backend_server->port, bref->reply_cmd, ses->rses_backend_ref[i].reply_cmd); @@ -3845,14 +3844,14 @@ static GWBUF* sescmd_cursor_process_replies( } else { - skygw_log_write(LT,"Slave '%s' responded before master to a session command. Result: %d", + MXS_INFO("Slave '%s' responded before master to a session command. Result: %d", bref->bref_backend->backend_server->unique_name, (int)bref->reply_cmd); if(bref->reply_cmd == 0xff) { SERVER* serv = bref->bref_backend->backend_server; - skygw_log_write(LE,"Error: Slave '%s' (%s:%u) failed to execute session command.", - serv->unique_name,serv->name,serv->port); + MXS_ERROR("Slave '%s' (%s:%u) failed to execute session command.", + serv->unique_name,serv->name,serv->port); } if(replybuf) while((replybuf = gwbuf_consume(replybuf,gwbuf_length(replybuf)))); @@ -3904,7 +3903,7 @@ static bool sescmd_cursor_is_active( if(sescmd_cursor == NULL) { - skygw_log_write(LE,"[%s] Error: NULL parameter.",__FUNCTION__); + MXS_ERROR("[%s] Error: NULL parameter.",__FUNCTION__); return false; } ss_dassert(SPINLOCK_IS_LOCKED(&sescmd_cursor->scmd_cur_rses->rses_lock)); @@ -3934,7 +3933,7 @@ static GWBUF* sescmd_cursor_clone_querybuf( GWBUF* buf; if(scur == NULL) { - skygw_log_write(LE,"[%s] Error: NULL parameter.",__FUNCTION__); + MXS_ERROR("[%s] Error: NULL parameter.",__FUNCTION__); return NULL; } ss_dassert(scur->scmd_cur_cmd != NULL); @@ -3952,7 +3951,7 @@ static bool sescmd_cursor_history_empty( if(scur == NULL) { - skygw_log_write(LE,"[%s] Error: NULL parameter.",__FUNCTION__); + MXS_ERROR("[%s] Error: NULL parameter.",__FUNCTION__); return true; } CHK_SESCMD_CUR(scur); @@ -3976,7 +3975,7 @@ static void sescmd_cursor_reset( ROUTER_CLIENT_SES* rses; if(scur == NULL) { - skygw_log_write(LE,"[%s] Error: NULL parameter.",__FUNCTION__); + MXS_ERROR("[%s] Error: NULL parameter.",__FUNCTION__); return; } CHK_SESCMD_CUR(scur); @@ -3997,7 +3996,7 @@ static bool execute_sescmd_history( sescmd_cursor_t* scur; if(bref == NULL) { - skygw_log_write(LE,"[%s] Error: NULL parameter.",__FUNCTION__); + MXS_ERROR("[%s] Error: NULL parameter.",__FUNCTION__); return false; } CHK_BACKEND_REF(bref); @@ -4038,7 +4037,7 @@ static bool execute_sescmd_in_backend( GWBUF* buf; if(backend_ref == NULL) { - skygw_log_write(LE,"[%s] Error: NULL parameter.",__FUNCTION__); + MXS_ERROR("[%s] Error: NULL parameter.",__FUNCTION__); return false; } if (BREF_IS_CLOSED(backend_ref)) @@ -4144,7 +4143,7 @@ static bool sescmd_cursor_next( if(scur == NULL) { - skygw_log_write(LE,"[%s] Error: NULL parameter.",__FUNCTION__); + MXS_ERROR("[%s] Error: NULL parameter.",__FUNCTION__); return false; } @@ -4396,9 +4395,10 @@ static bool route_session_write( if (router_cli_ses->rses_config.rw_max_sescmd_history_size > 0 && router_cli_ses->rses_nsescmd >= router_cli_ses->rses_config.rw_max_sescmd_history_size) { - skygw_log_write(LM, "Warning: Router session exceeded session command history limit. " - "Slave recovery is disabled and only slave servers with consistent session state are used " - "for the duration of the session."); + MXS_WARNING("Router session exceeded session command history limit. " + "Slave recovery is disabled and only slave servers with " + "consistent session state are used " + "for the duration of the session."); router_cli_ses->rses_config.rw_disable_sescmd_hist = true; router_cli_ses->rses_config.rw_max_sescmd_history_size = 0; } @@ -4447,7 +4447,7 @@ static bool route_session_write( */ if((prop = rses_property_init(RSES_PROP_TYPE_SESCMD)) == NULL) { - skygw_log_write(LE,"Error: Router session property initialization failed"); + MXS_ERROR("Router session property initialization failed"); rses_end_locked_router_action(router_cli_ses); return false; } @@ -4456,7 +4456,7 @@ static bool route_session_write( /** Add sescmd property to router client session */ if(rses_property_add(router_cli_ses, prop) != 0) { - skygw_log_write(LE,"Error: Session property addition failed."); + MXS_ERROR("Session property addition failed."); rses_end_locked_router_action(router_cli_ses); return false; } From afdeb6fa5bd9755d92bb1b402d77bab1b2be8830 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Wed, 18 Nov 2015 09:43:11 +0200 Subject: [PATCH 03/21] binlogrouter: All LOGIFs and skygw_log_writes replaced. All LOGIFs and skygw_log_writes replaced with the equivalent MXS_[ERROR|WARNING|NOTICE|INFO|DEBUG] macros. --- server/modules/routing/binlog/blr.c | 375 ++++++-------- server/modules/routing/binlog/blr_file.c | 438 +++++++--------- server/modules/routing/binlog/blr_master.c | 430 +++++++--------- server/modules/routing/binlog/blr_slave.c | 481 ++++++++---------- .../modules/routing/binlog/maxbinlogcheck.c | 17 +- 5 files changed, 758 insertions(+), 983 deletions(-) diff --git a/server/modules/routing/binlog/blr.c b/server/modules/routing/binlog/blr.c index 475d4e4eb..6be4414ea 100644 --- a/server/modules/routing/binlog/blr.c +++ b/server/modules/routing/binlog/blr.c @@ -157,9 +157,7 @@ version() void ModuleInit() { - LOGIF(LM, (skygw_log_write( - LOGFILE_MESSAGE, - "Initialise binlog router module %s.\n", version_str))); + MXS_NOTICE("Initialise binlog router module %s.\n", version_str); spinlock_init(&instlock); instances = NULL; } @@ -206,17 +204,16 @@ char task_name[BLRM_TASK_NAME_LEN+1] = ""; if(service->credentials.name == NULL || service->credentials.authdata == NULL) { - skygw_log_write(LE,"%s: Error: Service is missing user credentials." - " Add the missing username or passwd parameter to the service.", - service->name); + MXS_ERROR("%s: Error: Service is missing user credentials." + " Add the missing username or passwd parameter to the service.", + service->name); return NULL; } if(options == NULL || options[0] == NULL) { - skygw_log_write(LE, - "%s: Error: No router options supplied for binlogrouter", - service->name); + MXS_ERROR("%s: Error: No router options supplied for binlogrouter", + service->name); return NULL; } @@ -227,11 +224,10 @@ char task_name[BLRM_TASK_NAME_LEN+1] = ""; */ if (service->dbref != NULL) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "%s: Warning: backend database server is provided by master.ini file " - "for use with the binlog router." - " Server section is no longer required.", - service->name))); + MXS_WARNING("%s: backend database server is provided by master.ini file " + "for use with the binlog router." + " Server section is no longer required.", + service->name); server_free(service->dbref->server); free(service->dbref); @@ -239,9 +235,8 @@ char task_name[BLRM_TASK_NAME_LEN+1] = ""; } if ((inst = calloc(1, sizeof(ROUTER_INSTANCE))) == NULL) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "%s: Error: failed to allocate memory for router instance.", - service->name))); + MXS_ERROR("%s: Error: failed to allocate memory for router instance.", + service->name); return NULL; } @@ -328,10 +323,9 @@ char task_name[BLRM_TASK_NAME_LEN+1] = ""; { if ((value = strchr(options[i], '=')) == NULL) { - LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, "Warning : Unsupported router " + MXS_WARNING("Unsupported router " "option %s for binlog router.", - options[i]))); + options[i]); } else { @@ -345,20 +339,16 @@ char task_name[BLRM_TASK_NAME_LEN+1] = ""; { inst->serverid = atoi(value); if (strcmp(options[i], "server-id") == 0) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "WARNING: Configuration setting '%s' in router_options is deprecated" - " and will be removed in a later version of MaxScale. " - "Please use the new setting '%s' instead.", - "server-id", "server_id"))); + MXS_WARNING("Configuration setting '%s' in router_options is deprecated" + " and will be removed in a later version of MaxScale. " + "Please use the new setting '%s' instead.", + "server-id", "server_id"); } if (inst->serverid <= 0) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Service %s, invalid server-id '%s'. " - "Please configure it with a unique positive integer value (1..2^32-1)", - service->name, value))); + MXS_ERROR("Service %s, invalid server-id '%s'. " + "Please configure it with a unique positive integer value (1..2^32-1)", + service->name, value); free(inst); return NULL; @@ -384,12 +374,10 @@ char task_name[BLRM_TASK_NAME_LEN+1] = ""; inst->set_master_server_id = strdup(value); } if (strcmp(options[i], "master-id") == 0) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "WARNING: Configuration setting '%s' in router_options is deprecated" - " and will be removed in a later version of MaxScale. " - "Please use the new setting '%s' instead.", - "master-id", "master_id"))); + MXS_WARNING("Configuration setting '%s' in router_options is deprecated" + " and will be removed in a later version of MaxScale. " + "Please use the new setting '%s' instead.", + "master-id", "master_id"); } } else if (strcmp(options[i], "master_uuid") == 0) @@ -466,11 +454,9 @@ char task_name[BLRM_TASK_NAME_LEN+1] = ""; int h_val = (int)strtol(value, NULL, 10); if (h_val <= 0 || (errno == ERANGE)) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Warning : invalid heartbeat period %s." - " Setting it to default value %ld.", - value, inst->heartbeat))); + MXS_WARNING("Invalid heartbeat period %s." + " Setting it to default value %ld.", + value, inst->heartbeat); } else { inst->heartbeat = h_val; } @@ -485,20 +471,17 @@ char task_name[BLRM_TASK_NAME_LEN+1] = ""; } else { - LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, - "Warning : Unsupported router " - "option %s for binlog router.", - options[i]))); + MXS_WARNING("Unsupported router " + "option %s for binlog router.", + options[i]); } } } } else { - LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, "%s: Error: No router options supplied for binlogrouter", - service->name))); + MXS_ERROR("%s: Error: No router options supplied for binlogrouter", + service->name); } if (inst->fileroot == NULL) @@ -520,18 +503,16 @@ char task_name[BLRM_TASK_NAME_LEN+1] = ""; strcpy(inst->prevbinlog, ""); if ((inst->binlogdir == NULL) || (inst->binlogdir != NULL && !strlen(inst->binlogdir))) { - skygw_log_write_flush(LOGFILE_ERROR, - "Error : Service %s, binlog directory is not specified", - service->name); + MXS_ERROR("Service %s, binlog directory is not specified", + service->name); free(inst); return NULL; } if (inst->serverid <= 0) { - skygw_log_write_flush(LOGFILE_ERROR, - "Error : Service %s, server-id is not configured. " - "Please configure it with a unique positive integer value (1..2^32-1)", - service->name); + MXS_ERROR("Service %s, server-id is not configured. " + "Please configure it with a unique positive integer value (1..2^32-1)", + service->name); free(inst); return NULL; } @@ -545,12 +526,11 @@ char task_name[BLRM_TASK_NAME_LEN+1] = ""; mkdir_rval = mkdir(inst->binlogdir, 0700); if (mkdir_rval == -1) { char err_msg[STRERROR_BUFLEN]; - skygw_log_write_flush(LOGFILE_ERROR, - "Error : Service %s, Failed to create binlog directory '%s': [%d] %s", - service->name, - inst->binlogdir, - errno, - strerror_r(errno, err_msg, sizeof(err_msg))); + MXS_ERROR("Service %s, Failed to create binlog directory '%s': [%d] %s", + service->name, + inst->binlogdir, + errno, + strerror_r(errno, err_msg, sizeof(err_msg))); free(inst); return NULL; @@ -561,9 +541,8 @@ char task_name[BLRM_TASK_NAME_LEN+1] = ""; if (service->users == NULL) { service->users = (void *)mysql_users_alloc(); if (service->users == NULL) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "%s: Error allocating dbusers in createInstance", - inst->service->name))); + MXS_ERROR("%s: Error allocating dbusers in createInstance", + inst->service->name); free(inst); return NULL; @@ -576,9 +555,8 @@ char task_name[BLRM_TASK_NAME_LEN+1] = ""; SERVER *server; server = server_alloc("_none_", "MySQLBackend", (int)3306); if (server == NULL) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "%s: Error for server_alloc in createInstance", - inst->service->name))); + MXS_ERROR("%s: Error for server_alloc in createInstance", + inst->service->name); if (service->users) { users_free(service->users); service->users = NULL; @@ -605,11 +583,10 @@ char task_name[BLRM_TASK_NAME_LEN+1] = ""; rc = ini_parse(filename, blr_handler_config, inst); - LOGIF(LT, (skygw_log_write_flush(LOGFILE_TRACE, - "%s: %s parse result is %d", - inst->service->name, - filename, - rc))); + MXS_INFO("%s: %s parse result is %d", + inst->service->name, + filename, + rc); /* * retcode: @@ -618,17 +595,15 @@ char task_name[BLRM_TASK_NAME_LEN+1] = ""; if (rc != 0) { if (rc == -1) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "%s: master.ini file not found in %s." - " Master registration cannot be started." - " Configure with CHANGE MASTER TO ...", - inst->service->name, inst->binlogdir))); + MXS_ERROR("%s: master.ini file not found in %s." + " Master registration cannot be started." + " Configure with CHANGE MASTER TO ...", + inst->service->name, inst->binlogdir); } else { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "%s: master.ini file with errors in %s." - " Master registration cannot be started." - " Fix errors in it or configure with CHANGE MASTER TO ...", - inst->service->name, inst->binlogdir))); + MXS_ERROR("%s: master.ini file with errors in %s." + " Master registration cannot be started." + " Fix errors in it or configure with CHANGE MASTER TO ...", + inst->service->name, inst->binlogdir); } /* Set service user or load db users */ @@ -652,11 +627,9 @@ char task_name[BLRM_TASK_NAME_LEN+1] = ""; /* Find latest binlog file or create a new one (000001) */ if (blr_file_init(inst) == 0) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "%s: Service not started due to lack of binlog directory %s", - service->name, - inst->binlogdir))); + MXS_ERROR("%s: Service not started due to lack of binlog directory %s", + service->name, + inst->binlogdir); if (service->users) { users_free(service->users); @@ -696,10 +669,8 @@ char task_name[BLRM_TASK_NAME_LEN+1] = ""; /* Log whether the transaction safety option value is on*/ if (inst->trx_safe) { - LOGIF(LT, (skygw_log_write_flush( - LOGFILE_TRACE, - "%s: Service has transaction safety option set to ON", - service->name))); + MXS_INFO("%s: Service has transaction safety option set to ON", + service->name); } /** @@ -707,9 +678,8 @@ char task_name[BLRM_TASK_NAME_LEN+1] = ""; */ if (inst->master_state == BLRM_UNCONNECTED) { /* Check current binlog */ - LOGIF(LM, (skygw_log_write_flush( - LOGFILE_MESSAGE, "Validating binlog file '%s' ...", - inst->binlog_name))); + MXS_NOTICE("Validating binlog file '%s' ...", + inst->binlog_name); if (inst->trx_safe && !blr_check_binlog(inst)) { /* Don't start replication, just return */ @@ -717,15 +687,11 @@ char task_name[BLRM_TASK_NAME_LEN+1] = ""; } if (!inst->trx_safe) { - LOGIF(LT, (skygw_log_write_flush( - LOGFILE_TRACE, - "Current binlog file is %s, current pos is %lu\n", - inst->binlog_name, inst->binlog_position))); + MXS_INFO("Current binlog file is %s, current pos is %lu\n", + inst->binlog_name, inst->binlog_position); } else { - LOGIF(LT, (skygw_log_write_flush( - LOGFILE_TRACE, - "Current binlog file is %s, safe pos %lu, current pos is %lu\n", - inst->binlog_name, inst->binlog_position, inst->current_pos))); + MXS_INFO("Current binlog file is %s, safe pos %lu, current pos is %lu\n", + inst->binlog_name, inst->binlog_position, inst->current_pos); } /* Start replication from master server */ @@ -752,20 +718,16 @@ newSession(ROUTER *instance, SESSION *session) ROUTER_INSTANCE *inst = (ROUTER_INSTANCE *)instance; ROUTER_SLAVE *slave; - LOGIF(LD, (skygw_log_write_flush( - LOGFILE_DEBUG, - "binlog router: %lu [newSession] new router session with " - "session %p, and inst %p.", - pthread_self(), - session, - inst))); + MXS_DEBUG("binlog router: %lu [newSession] new router session with " + "session %p, and inst %p.", + pthread_self(), + session, + inst); if ((slave = (ROUTER_SLAVE *)calloc(1, sizeof(ROUTER_SLAVE))) == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Insufficient memory to create new slave session for binlog router"))); + MXS_ERROR("Insufficient memory to create new slave session for binlog router"); return NULL; } @@ -849,14 +811,12 @@ int prev_val; } spinlock_release(&router->lock); - LOGIF(LD, (skygw_log_write_flush( - LOGFILE_DEBUG, - "%lu [freeSession] Unlinked router_client_session %p from " - "router %p. Connections : %d. ", - pthread_self(), - slave, - router, - prev_val-1))); + MXS_DEBUG("%lu [freeSession] Unlinked router_client_session %p from " + "router %p. Connections : %d. ", + pthread_self(), + slave, + router, + prev_val-1); if (slave->hostname) free(slave->hostname); @@ -886,16 +846,12 @@ ROUTER_SLAVE *slave = (ROUTER_SLAVE *)router_session; /* * We must be closing the master session. */ - LOGIF(LM, (skygw_log_write_flush( - LOGFILE_MESSAGE, - "%s: Master %s disconnected after %ld seconds. " - "%lu events read,", - router->service->name, router->service->dbref->server->name, - time(0) - router->connect_time, router->stats.n_binlogs_ses))); - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Binlog router close session with master server %s", - router->service->dbref->server->unique_name))); + MXS_NOTICE("%s: Master %s disconnected after %ld seconds. " + "%lu events read,", + router->service->name, router->service->dbref->server->name, + time(0) - router->connect_time, router->stats.n_binlogs_ses); + MXS_ERROR("Binlog router close session with master server %s", + router->service->dbref->server->unique_name); blr_master_reconnect(router); return; } @@ -910,27 +866,24 @@ ROUTER_SLAVE *slave = (ROUTER_SLAVE *)router_session; atomic_add(&router->stats.n_registered, -1); if (slave->state > 0) { - LOGIF(LM, (skygw_log_write_flush( - LOGFILE_MESSAGE, - "%s: Slave %s, server id %d, disconnected after %ld seconds. " - "%d SQL commands, %d events sent (%lu bytes), binlog '%s', last position %lu", - router->service->name, slave->dcb->remote, - slave->serverid, - time(0) - slave->connect_time, - slave->stats.n_queries, - slave->stats.n_events, - slave->stats.n_bytes, - slave->binlogfile, - (unsigned long)slave->binlog_pos))); + MXS_NOTICE("%s: Slave %s, server id %d, disconnected after %ld seconds. " + "%d SQL commands, %d events sent (%lu bytes), binlog '%s', " + "last position %lu", + router->service->name, slave->dcb->remote, + slave->serverid, + time(0) - slave->connect_time, + slave->stats.n_queries, + slave->stats.n_events, + slave->stats.n_bytes, + slave->binlogfile, + (unsigned long)slave->binlog_pos); } else { - LOGIF(LM, (skygw_log_write_flush( - LOGFILE_MESSAGE, - "%s: Slave %s, server id %d, disconnected after %ld seconds. " - "%d SQL commands", - router->service->name, slave->dcb->remote, - slave->serverid, - time(0) - slave->connect_time, - slave->stats.n_queries))); + MXS_NOTICE("%s: Slave %s, server id %d, disconnected after %ld seconds. " + "%d SQL commands", + router->service->name, slave->dcb->remote, + slave->serverid, + time(0) - slave->connect_time, + slave->stats.n_queries); } /* @@ -1440,33 +1393,29 @@ unsigned long mysql_errno; free(router->m_errmsg); router->m_errmsg = strdup(errmsg); - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, "%s: Master connection error %lu '%s' in state '%s', " - "%sattempting reconnect to master %s:%d", - router->service->name, mysql_errno, errmsg, - blrm_states[router->master_state], msg, - router->service->dbref->server->name, - router->service->dbref->server->port))); + MXS_ERROR("%s: Master connection error %lu '%s' in state '%s', " + "%sattempting reconnect to master %s:%d", + router->service->name, mysql_errno, errmsg, + blrm_states[router->master_state], msg, + router->service->dbref->server->name, + router->service->dbref->server->port); } else { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, "%s: Master connection error %lu '%s' in state '%s', " - "%sattempting reconnect to master %s:%d", - router->service->name, router->m_errno, router->m_errmsg, - blrm_states[router->master_state], msg, - router->service->dbref->server->name, - router->service->dbref->server->port))); + MXS_ERROR("%s: Master connection error %lu '%s' in state '%s', " + "%sattempting reconnect to master %s:%d", + router->service->name, router->m_errno, router->m_errmsg, + blrm_states[router->master_state], msg, + router->service->dbref->server->name, + router->service->dbref->server->port); } if (errmsg) free(errmsg); *succp = true; dcb_close(backend_dcb); - LOGIF(LM, (skygw_log_write_flush( - LOGFILE_MESSAGE, - "%s: Master %s disconnected after %ld seconds. " - "%lu events read.", - router->service->name, router->service->dbref->server->name, - time(0) - router->connect_time, router->stats.n_binlogs_ses))); + MXS_NOTICE("%s: Master %s disconnected after %ld seconds. " + "%lu events read.", + router->service->name, router->service->dbref->server->name, + time(0) - router->connect_time, router->stats.n_binlogs_ses); blr_master_reconnect(router); } @@ -1734,10 +1683,10 @@ SERVICE *service; { return blr_handle_config_item(name, value, inst); } else { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Error : master.ini has an invalid section [%s], it should be [binlog_configuration]. Service %s", - section, - service->name))); + MXS_ERROR("master.ini has an invalid section [%s], it should be [binlog_configuration]. " + "Service %s", + section, + service->name); return 0; } @@ -1796,9 +1745,8 @@ char *service_user = NULL; char *service_passwd = NULL; if (serviceGetUser(service, &service_user, &service_passwd) == 0) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "failed to get service user details for service %s", - service->name))); + MXS_ERROR("failed to get service user details for service %s", + service->name); return 1; } @@ -1806,10 +1754,9 @@ char *service_passwd = NULL; dpwd = decryptPassword(service->credentials.authdata); if (!dpwd) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "decrypt password failed for service user %s, service %s", - service_user, - service->name))); + MXS_ERROR("decrypt password failed for service user %s, service %s", + service_user, + service->name); return 1; } @@ -1817,9 +1764,8 @@ char *service_passwd = NULL; newpasswd = create_hex_sha1_sha1_passwd(dpwd); if (!newpasswd) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "create hex_sha1_sha1_password failed for service user %s", - service_user))); + MXS_ERROR("create hex_sha1_sha1_password failed for service user %s", + service_user); free(dpwd); return 1; @@ -1859,10 +1805,8 @@ SERVICE *service; if (loaded < 0) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Unable to load users for service %s", - service->name))); + MXS_ERROR("Unable to load users for service %s", + service->name); /* Try loading authentication data from file cache */ @@ -1870,29 +1814,23 @@ SERVICE *service; if (loaded != -1) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Service %s, Using cached credential information file %s.", - service->name, - path))); + MXS_ERROR("Service %s, Using cached credential information file %s.", + service->name, + path); } else { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error: Service %s, Unable to read cache credential information from %s." - " No database user added to service users table.", - service->name, - path))); + MXS_ERROR("Service %s, Unable to read cache credential information from %s." + " No database user added to service users table.", + service->name, + path); } } else { /* don't update cache if no user was loaded */ if (loaded == 0) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Service %s: failed to load any user " - "information. Authentication will " - "probably fail as a result.", - service->name))); + MXS_ERROR("Service %s: failed to load any user " + "information. Authentication will " + "probably fail as a result.", + service->name); } else { /* update cached data */ blr_save_dbusers(router); @@ -1936,12 +1874,11 @@ int mkdir_rval = 0; if (mkdir_rval == -1) { char err_msg[STRERROR_BUFLEN]; - skygw_log_write(LOGFILE_ERROR, - "Error : Service %s, Failed to create directory '%s': [%d] %s", - service->name, - path, - errno, - strerror_r(errno, err_msg, sizeof(err_msg))); + MXS_ERROR("Service %s, Failed to create directory '%s': [%d] %s", + service->name, + path, + errno, + strerror_r(errno, err_msg, sizeof(err_msg))); return -1; } @@ -1999,9 +1936,7 @@ static int blr_check_binlog(ROUTER_INSTANCE *router) { n = blr_read_events_all_events(router, 0, 0); - LOGIF(LD, (skygw_log_write_flush( - LOGFILE_DEBUG, - "blr_read_events_all_events() ret = %i\n", n))); + MXS_DEBUG("blr_read_events_all_events() ret = %i\n", n); if (n != 0) { char msg_err[BINLOG_ERROR_MSG_LEN + 1] = ""; @@ -2017,11 +1952,9 @@ static int blr_check_binlog(ROUTER_INSTANCE *router) { /* set last_safe_pos */ router->last_safe_pos = router->binlog_position; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error found in binlog file %s. Safe starting pos is %lu", - router->binlog_name, - router->binlog_position))); + MXS_ERROR("Error found in binlog file %s. Safe starting pos is %lu", + router->binlog_name, + router->binlog_position); return 0; } else { diff --git a/server/modules/routing/binlog/blr_file.c b/server/modules/routing/binlog/blr_file.c index dc1683b9c..9a6e49f7a 100644 --- a/server/modules/routing/binlog/blr_file.c +++ b/server/modules/routing/binlog/blr_file.c @@ -65,7 +65,7 @@ static int blr_file_create(ROUTER_INSTANCE *router, char *file); static void blr_file_append(ROUTER_INSTANCE *router, char *file); -static void blr_log_header(logfile_id_t file, char *msg, uint8_t *ptr); +static void blr_log_header(int priority, char *msg, uint8_t *ptr); void blr_cache_read_master_data(ROUTER_INSTANCE *router); int blr_file_get_next_binlogname(ROUTER_INSTANCE *router); int blr_file_new_binlog(ROUTER_INSTANCE *router, char *file); @@ -120,9 +120,8 @@ struct dirent *dp; } if (access(router->binlogdir, R_OK) == -1) { - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "%s: Unable to read the binlog directory %s.", - router->service->name, router->binlogdir))); + MXS_ERROR("%s: Unable to read the binlog directory %s.", + router->service->name, router->binlogdir); return 0; } @@ -131,10 +130,9 @@ struct dirent *dp; if ((dirp = opendir(path)) == NULL) { char err_msg[BLRM_STRERROR_R_MSG_SIZE]; - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "%s: Unable to read the binlog directory %s, %s.", - router->service->name, router->binlogdir, - strerror_r(errno, err_msg, sizeof(err_msg))))); + MXS_ERROR("%s: Unable to read the binlog directory %s, %s.", + router->service->name, router->binlogdir, + strerror_r(errno, err_msg, sizeof(err_msg))); return 0; } while ((dp = readdir(dirp)) != NULL) @@ -232,9 +230,8 @@ int fd; { char err_msg[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "%s: Failed to create binlog file %s, %s.", - router->service->name, path, strerror_r(errno, err_msg, sizeof(err_msg))))); + MXS_ERROR("%s: Failed to create binlog file %s, %s.", + router->service->name, path, strerror_r(errno, err_msg, sizeof(err_msg))); return 0; } fsync(fd); @@ -264,9 +261,8 @@ int fd; if ((fd = open(path, O_RDWR|O_APPEND, 0666)) == -1) { - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "Failed to open binlog file %s for append.", - path))); + MXS_ERROR("Failed to open binlog file %s for append.", + path); return; } fsync(fd); @@ -280,9 +276,8 @@ int fd; } else { /* If for any reason the file's length is between 1 and 3 bytes * then report an error. */ - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "%s: binlog file %s has an invalid length %lu.", - router->service->name, path, router->current_pos))); + MXS_ERROR("%s: binlog file %s has an invalid length %lu.", + router->service->name, path, router->current_pos); close(fd); spinlock_release(&router->binlog_lock); return; @@ -309,12 +304,11 @@ int n; hdr->next_pos - hdr->event_size)) != hdr->event_size) { char err_msg[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "%s: Failed to write binlog record at %d of %s, %s. " - "Truncating to previous record.", - router->service->name, hdr->next_pos - hdr->event_size, - router->binlog_name, - strerror_r(errno, err_msg, sizeof(err_msg))))); + MXS_ERROR("%s: Failed to write binlog record at %d of %s, %s. " + "Truncating to previous record.", + router->service->name, hdr->next_pos - hdr->event_size, + router->binlog_name, + strerror_r(errno, err_msg, sizeof(err_msg))); /* Remove any partual event that was written */ ftruncate(router->binlog_fd, hdr->next_pos - hdr->event_size); return 0; @@ -378,8 +372,7 @@ BLFILE *file; if ((file->fd = open(path, O_RDONLY, 0666)) == -1) { - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "Failed to open binlog file %s", path))); + MXS_ERROR("Failed to open binlog file %s", path); free(file); spinlock_release(&router->fileslock); return NULL; @@ -458,9 +451,8 @@ struct stat statb; switch (n) { case 0: - LOGIF(LD, (skygw_log_write(LOGFILE_DEBUG, - "Reached end of binlog file '%s' at %lu.", - file->binlogname, pos))); + MXS_DEBUG("Reached end of binlog file '%s' at %lu.", + file->binlogname, pos); /* set ok indicator */ hdr->ok = SLAVE_POS_READ_OK; @@ -514,21 +506,19 @@ struct stat statb; if (hdr->next_pos < pos && hdr->event_type != ROTATE_EVENT) { - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "Next position in header appears to be incorrect " - "rereading event header at pos %lu in file %s, " - "file size is %lu. Master will write %lu in %s next.", - pos, file->binlogname, filelen, router->binlog_position, - router->binlog_name))); + MXS_ERROR("Next position in header appears to be incorrect " + "rereading event header at pos %lu in file %s, " + "file size is %lu. Master will write %lu in %s next.", + pos, file->binlogname, filelen, router->binlog_position, + router->binlog_name); if ((n = pread(file->fd, hdbuf, BINLOG_EVENT_HDR_LEN, pos)) != BINLOG_EVENT_HDR_LEN) { switch (n) { case 0: - LOGIF(LD, (skygw_log_write(LOGFILE_DEBUG, - "Reached end of binlog file at %lu.", - pos))); + MXS_DEBUG("Reached end of binlog file at %lu.", + pos); /* set ok indicator */ hdr->ok = SLAVE_POS_READ_OK; @@ -570,9 +560,8 @@ struct stat statb; } else { - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "Next position corrected by " - "rereading"))); + MXS_ERROR("Next position corrected by " + "rereading"); } } if ((result = gwbuf_alloc(hdr->event_size)) == NULL) @@ -608,7 +597,7 @@ struct stat statb; "current file size is %lu, event at %lu in binlog file '%s'", filelen, pos, file->binlogname); } - blr_log_header(LOGFILE_ERROR, "Possible malformed event header", hdbuf); + blr_log_header(LOG_ERR, "Possible malformed event header", hdbuf); } gwbuf_free(result); @@ -667,12 +656,12 @@ blr_close_binlog(ROUTER_INSTANCE *router, BLFILE *file) /** * Log the event header of binlog event * - * @param file The log file into which to write the entry - * @param msg A message strign to preceed the header with - * @param ptr The event header raw data + * @param priority The syslog priority of the message (LOG_ERR, LOG_WARNING, etc.) + * @param msg A message strign to preceed the header with + * @param ptr The event header raw data */ static void -blr_log_header(logfile_id_t file, char *msg, uint8_t *ptr) +blr_log_header(int priority, char *msg, uint8_t *ptr) { char buf[400], *bufp; int i; @@ -681,8 +670,7 @@ int i; bufp += sprintf(bufp, "%s: ", msg); for (i = 0; i < BINLOG_EVENT_HDR_LEN; i++) bufp += sprintf(bufp, "0x%02x ", ptr[i]); - skygw_log_write_flush(file, "%s", buf); - + MXS_LOG_MESSAGE(priority, "%s", buf); } /** @@ -852,9 +840,8 @@ int fde_seen = 0; memset(&fde_event, '\0', sizeof(fde_event)); if (router->binlog_fd == -1) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "ERROR: Current binlog file %s is not open", - router->binlog_name))); + MXS_ERROR("Current binlog file %s is not open", + router->binlog_name); return 1; } @@ -872,10 +859,9 @@ int fde_seen = 0; switch (n) { case 0: - LOGIF(LD, (skygw_log_write_flush(LOGFILE_DEBUG, - "End of binlog file [%s] at %llu.", - router->binlog_name, - pos))); + MXS_DEBUG("End of binlog file [%s] at %llu.", + router->binlog_name, + pos); if (n_transactions) average_events = (double)((double)total_events / (double)n_transactions) * (1.0); if (n_transactions) @@ -901,24 +887,25 @@ int fde_seen = 0; blr_format_event_size(&average_bytes, average_label); blr_format_event_size(&format_max_bytes, max_label); - LOGIF(LM, (skygw_log_write_flush(LOGFILE_MESSAGE, - "Transaction Summary for binlog '%s'\n" - "\t\t\tDescription %17s%17s%17s\n\t\t\t" - "No. of Transactions %16lu\n\t\t\t" - "No. of Events %16lu %16.1f %16lu\n\t\t\t" - "No. of Bytes %16.1f%s%16.1f%s%16.1f%s", router->binlog_name, - "Total", "Average", "Max", - n_transactions, total_events, - average_events, max_events, - format_total_bytes, total_label, average_bytes, average_label, format_max_bytes, max_label))); + MXS_NOTICE("Transaction Summary for binlog '%s'\n" + "\t\t\tDescription %17s%17s%17s\n\t\t\t" + "No. of Transactions %16lu\n\t\t\t" + "No. of Events %16lu %16.1f %16lu\n\t\t\t" + "No. of Bytes %16.1f%s%16.1f%s%16.1f%s", + router->binlog_name, + "Total", "Average", "Max", + n_transactions, total_events, + average_events, max_events, + format_total_bytes, total_label, + average_bytes, average_label, + format_max_bytes, max_label); } if (pending_transaction) { - LOGIF(LT, (skygw_log_write_flush(LOGFILE_TRACE, - "Warning : Binlog file %s contains a previous Opened Transaction" - " @ %llu. This pos is safe for slaves", - router->binlog_name, - last_known_commit))); + MXS_WARNING("Binlog file %s contains a previous Opened " + "Transaction @ %llu. This pos is safe for slaves", + router->binlog_name, + last_known_commit); } @@ -927,24 +914,21 @@ int fde_seen = 0; { char err_msg[BLRM_STRERROR_R_MSG_SIZE+1] = ""; strerror_r(errno, err_msg, BLRM_STRERROR_R_MSG_SIZE); - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "ERROR: Failed to read binlog file %s at position %llu" - " (%s).", router->binlog_name, - pos, err_msg))); + MXS_ERROR("Failed to read binlog file %s at position %llu" + " (%s).", router->binlog_name, + pos, err_msg); if (errno == EBADF) - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "ERROR: Bad file descriptor in read binlog for file %s" - ", descriptor %d.", - router->binlog_name, router->binlog_fd))); + MXS_ERROR("Bad file descriptor in read binlog for file %s" + ", descriptor %d.", + router->binlog_name, router->binlog_fd); break; } default: - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "ERROR: Short read when reading the header. " - "Expected 19 bytes but got %d bytes. " - "Binlog file is %s, position %llu", - n, router->binlog_name, pos))); + MXS_ERROR("Short read when reading the header. " + "Expected 19 bytes but got %d bytes. " + "Binlog file is %s, position %llu", + n, router->binlog_name, pos); break; } @@ -960,10 +944,9 @@ int fde_seen = 0; router->pending_transaction = 1; pending_transaction = 0; - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Warning : pending transaction has been found. " - "Setting safe pos to %lu, current pos %lu", - router->binlog_position, router->current_pos))); + MXS_WARNING("pending transaction has been found. " + "Setting safe pos to %lu, current pos %lu", + router->binlog_position, router->current_pos); return 0; } else { @@ -973,16 +956,14 @@ int fde_seen = 0; router->current_safe_event = last_known_commit; router->current_pos = pos; - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "warning : an error has been found. " - "Setting safe pos to %lu, current pos %lu", - router->binlog_position, router->current_pos))); + MXS_WARNING("an error has been found. " + "Setting safe pos to %lu, current pos %lu", + router->binlog_position, router->current_pos); if (fix) { if (ftruncate(router->binlog_fd, router->binlog_position) == 0) { - LOGIF(LM, (skygw_log_write_flush(LOGFILE_MESSAGE, - "Binlog file %s has been truncated at %lu", - router->binlog_name, - router->binlog_position))); + MXS_NOTICE("Binlog file %s has been truncated at %lu", + router->binlog_name, + router->binlog_position); fsync(router->binlog_fd); } } @@ -1010,21 +991,19 @@ int fde_seen = 0; if (router->mariadb10_compat) { if (hdr.event_type > MAX_EVENT_TYPE_MARIADB10) { - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "Invalid MariaDB 10 event type 0x%x. " - "Binlog file is %s, position %llu", - hdr.event_type, - router->binlog_name, pos))); + MXS_ERROR("Invalid MariaDB 10 event type 0x%x. " + "Binlog file is %s, position %llu", + hdr.event_type, + router->binlog_name, pos); event_error = 1; } } else { if (hdr.event_type > MAX_EVENT_TYPE) { - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "Invalid event type 0x%x. " - "Binlog file is %s, position %llu", - hdr.event_type, - router->binlog_name, pos))); + MXS_ERROR("Invalid event type 0x%x. " + "Binlog file is %s, position %llu", + hdr.event_type, + router->binlog_name, pos); event_error = 1; } @@ -1036,19 +1015,17 @@ int fde_seen = 0; router->current_safe_event = last_known_commit; router->current_pos = pos; - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "warning : an error has been found in %s. " - "Setting safe pos to %lu, current pos %lu", - router->binlog_name, - router->binlog_position, - router->current_pos))); + MXS_WARNING("an error has been found in %s. " + "Setting safe pos to %lu, current pos %lu", + router->binlog_name, + router->binlog_position, + router->current_pos); if (fix) { if (ftruncate(router->binlog_fd, router->binlog_position) == 0) { - LOGIF(LM, (skygw_log_write_flush(LOGFILE_MESSAGE, - "Binlog file %s has been truncated at %lu", - router->binlog_name, - router->binlog_position))); + MXS_NOTICE("Binlog file %s has been truncated at %lu", + router->binlog_name, + router->binlog_position); fsync(router->binlog_fd); } } @@ -1058,25 +1035,22 @@ int fde_seen = 0; if (hdr.event_size <= 0) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Event size error: " - "size %d at %llu.", - hdr.event_size, pos))); + MXS_ERROR("Event size error: " + "size %d at %llu.", + hdr.event_size, pos); router->binlog_position = last_known_commit; router->current_safe_event = last_known_commit; router->current_pos = pos; - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "warning : an error has been found. " - "Setting safe pos to %lu, current pos %lu", - router->binlog_position, router->current_pos))); + MXS_WARNING("an error has been found. " + "Setting safe pos to %lu, current pos %lu", + router->binlog_position, router->current_pos); if (fix) { if (ftruncate(router->binlog_fd, router->binlog_position) == 0) { - LOGIF(LM, (skygw_log_write_flush(LOGFILE_MESSAGE, - "Binlog file %s has been truncated at %lu", - router->binlog_name, - router->binlog_position))); + MXS_NOTICE("Binlog file %s has been truncated at %lu", + router->binlog_name, + router->binlog_position); fsync(router->binlog_fd); } } @@ -1087,26 +1061,23 @@ int fde_seen = 0; /* Allocate a GWBUF for the event */ if ((result = gwbuf_alloc(hdr.event_size)) == NULL) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "ERROR: Failed to allocate memory for binlog entry, " - "size %d at %llu.", - hdr.event_size, pos))); + MXS_ERROR("Failed to allocate memory for binlog entry, " + "size %d at %llu.", + hdr.event_size, pos); router->binlog_position = last_known_commit; router->current_safe_event = last_known_commit; router->current_pos = pos; - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "warning : an error has been found. " - "Setting safe pos to %lu, current pos %lu", - router->binlog_position, router->current_pos))); + MXS_WARNING("an error has been found. " + "Setting safe pos to %lu, current pos %lu", + router->binlog_position, router->current_pos); if (fix) { if (ftruncate(router->binlog_fd, router->binlog_position) == 0) { - LOGIF(LM, (skygw_log_write_flush(LOGFILE_MESSAGE, - "Binlog file %s has been truncated at %lu", - router->binlog_name, - router->binlog_position))); + MXS_NOTICE("Binlog file %s has been truncated at %lu", + router->binlog_name, + router->binlog_position); fsync(router->binlog_fd); } } @@ -1125,25 +1096,23 @@ int fde_seen = 0; { char err_msg[BLRM_STRERROR_R_MSG_SIZE+1] = ""; strerror_r(errno, err_msg, BLRM_STRERROR_R_MSG_SIZE); - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Error reading the event at %llu in %s. " - "%s, expected %d bytes.", - pos, router->binlog_name, - err_msg, hdr.event_size - BINLOG_EVENT_HDR_LEN))); + MXS_ERROR("Error reading the event at %llu in %s. " + "%s, expected %d bytes.", + pos, router->binlog_name, + err_msg, hdr.event_size - BINLOG_EVENT_HDR_LEN); } else { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Short read when reading the event at %llu in %s. " - "Expected %d bytes got %d bytes.", - pos, router->binlog_name, hdr.event_size - BINLOG_EVENT_HDR_LEN, n))); + MXS_ERROR("Short read when reading the event at %llu in %s. " + "Expected %d bytes got %d bytes.", + pos, router->binlog_name, + hdr.event_size - BINLOG_EVENT_HDR_LEN, n); if (filelen > 0 && filelen - pos < hdr.event_size) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Binlog event is close to the end of the binlog file %s, " - " size is %lu.", - router->binlog_name, filelen))); + MXS_ERROR("Binlog event is close to the end of the binlog file %s, " + " size is %lu.", + router->binlog_name, filelen); } } @@ -1153,16 +1122,14 @@ int fde_seen = 0; router->current_safe_event = last_known_commit; router->current_pos = pos; - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "warning : an error has been found. " - "Setting safe pos to %lu, current pos %lu", - router->binlog_position, router->current_pos))); + MXS_WARNING("an error has been found. " + "Setting safe pos to %lu, current pos %lu", + router->binlog_position, router->current_pos); if (fix) { if (ftruncate(router->binlog_fd, router->binlog_position) == 0) { - LOGIF(LM, (skygw_log_write_flush(LOGFILE_MESSAGE, - "Binlog file %s has been truncated at %lu", - router->binlog_name, - router->binlog_position))); + MXS_NOTICE("Binlog file %s has been truncated at %lu", + router->binlog_name, + router->binlog_position); fsync(router->binlog_fd); } } @@ -1209,9 +1176,8 @@ int fde_seen = 0; } if(debug) - LOGIF(LD, (skygw_log_write_flush(LOGFILE_DEBUG, - "- Format Description event FDE @ %llu, size %lu, time %lu (%s)", - pos, (unsigned long)hdr.event_size, fde_event.event_time, buf_t))); + MXS_DEBUG("- Format Description event FDE @ %llu, size %lu, time %lu (%s)", + pos, (unsigned long)hdr.event_size, fde_event.event_time, buf_t); event_header_length = ptr[2 + 50 + 4]; event_header_ntypes = hdr.event_size - event_header_length - (2 + 50 + 4 + 1); @@ -1232,14 +1198,12 @@ int fde_seen = 0; n_events = hdr.event_size - event_header_length - (2 + 50 + 4 + 1); if(debug) { - LOGIF(LD, (skygw_log_write_flush(LOGFILE_DEBUG, - " FDE ServerVersion [%50s]", ptr + 2))); + MXS_DEBUG(" FDE ServerVersion [%50s]", ptr + 2); - LOGIF(LD, (skygw_log_write_flush(LOGFILE_DEBUG, - " FDE Header EventLength %i" - ", N. of supported MySQL/MariaDB events %i", - event_header_length, - (n_events - event_header_ntypes)))); + MXS_DEBUG(" FDE Header EventLength %i" + ", N. of supported MySQL/MariaDB events %i", + event_header_length, + (n_events - event_header_ntypes)); } if (event_header_ntypes < n_events) { @@ -1247,10 +1211,10 @@ int fde_seen = 0; check_alg = checksum[0]; if(debug) - LOGIF(LD, (skygw_log_write_flush(LOGFILE_DEBUG, - " FDE Checksum alg desc %i, alg type %s", - check_alg, - check_alg == 1 ? "BINLOG_CHECKSUM_ALG_CRC32" : "NONE or UNDEF"))); + MXS_DEBUG(" FDE Checksum alg desc %i, alg type %s", + check_alg, + check_alg == 1 ? + "BINLOG_CHECKSUM_ALG_CRC32" : "NONE or UNDEF"); if (check_alg == 1) { found_chksum = 1; } else { @@ -1283,9 +1247,8 @@ int fde_seen = 0; file[slen] = 0; if(debug) - LOGIF(LD, (skygw_log_write_flush(LOGFILE_DEBUG, - "- Rotate event @ %llu, next file is [%s] @ %lu", - pos, file, new_pos))); + MXS_DEBUG("- Rotate event @ %llu, next file is [%s] @ %lu", + pos, file, new_pos); } /* If MariaDB 10 compatibility: @@ -1305,11 +1268,11 @@ int fde_seen = 0; if (flags == 0) { if (pending_transaction > 0) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "ERROR: Transaction cannot be @ pos %llu: " - "Another MariaDB 10 transaction (GTID %u-%u-%lu)" - " was opened at %llu", - pos, domainid, hdr.serverid, n_sequence, last_known_commit))); + MXS_ERROR("Transaction cannot be @ pos %llu: " + "Another MariaDB 10 transaction (GTID %u-%u-%lu)" + " was opened at %llu", + pos, domainid, hdr.serverid, + n_sequence, last_known_commit); gwbuf_free(result); @@ -1321,10 +1284,9 @@ int fde_seen = 0; event_bytes = 0; if (debug) - LOGIF(LD, (skygw_log_write_flush(LOGFILE_DEBUG, - "> MariaDB 10 Transaction (GTID %u-%u-%lu)" - " starts @ pos %llu", - domainid, hdr.serverid, n_sequence, pos))); + MXS_DEBUG("> MariaDB 10 Transaction (GTID %u-%u-%lu)" + " starts @ pos %llu", + domainid, hdr.serverid, n_sequence, pos); } } } @@ -1350,10 +1312,9 @@ int fde_seen = 0; /* A transaction starts with this event */ if (strncmp(statement_sql, "BEGIN", 5) == 0) { if (pending_transaction > 0) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "ERROR: Transaction cannot be @ pos %llu: " - "Another transaction was opened at %llu", - pos, last_known_commit))); + MXS_ERROR("Transaction cannot be @ pos %llu: " + "Another transaction was opened at %llu", + pos, last_known_commit); free(statement_sql); gwbuf_free(result); @@ -1366,8 +1327,7 @@ int fde_seen = 0; event_bytes = 0; if (debug) - LOGIF(LD, (skygw_log_write_flush(LOGFILE_DEBUG, - "> Transaction starts @ pos %llu", pos))); + MXS_DEBUG("> Transaction starts @ pos %llu", pos); } } @@ -1377,8 +1337,8 @@ int fde_seen = 0; pending_transaction = 3; if (debug) - LOGIF(LD, (skygw_log_write_flush(LOGFILE_DEBUG, - " Transaction @ pos %llu, closing @ %llu", last_known_commit, pos))); + MXS_DEBUG(" Transaction @ pos %llu, closing @ %llu", + last_known_commit, pos); } } free(statement_sql); @@ -1391,15 +1351,15 @@ int fde_seen = 0; if (pending_transaction > 0) { pending_transaction = 2; if (debug) - LOGIF(LD, (skygw_log_write_flush(LOGFILE_DEBUG, - " Transaction XID @ pos %llu, closing @ %llu", last_known_commit, pos))); + MXS_DEBUG(" Transaction XID @ pos %llu, closing @ %llu", + last_known_commit, pos); } } if (pending_transaction > 1) { if (debug) - LOGIF(LD, (skygw_log_write_flush(LOGFILE_DEBUG, - "< Transaction @ pos %llu, is now closed @ %llu. %lu events seen", last_known_commit, pos, transaction_events))); + MXS_DEBUG("< Transaction @ pos %llu, is now closed @ %llu. %lu events seen", + last_known_commit, pos, transaction_events); pending_transaction = 0; last_known_commit = pos; @@ -1415,27 +1375,24 @@ int fde_seen = 0; /* pos and next_pos sanity checks */ if (hdr.next_pos > 0 && hdr.next_pos < pos) { - LOGIF(LT, (skygw_log_write_flush(LOGFILE_TRACE, - "Binlog %s: next pos %u < pos %llu, truncating to %llu", - router->binlog_name, - hdr.next_pos, - pos, - pos))); + MXS_INFO("Binlog %s: next pos %u < pos %llu, truncating to %llu", + router->binlog_name, + hdr.next_pos, + pos, + pos); router->binlog_position = last_known_commit; router->current_safe_event = last_known_commit; router->current_pos = pos; - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "warning : an error has been found. " - "Setting safe pos to %lu, current pos %lu", - router->binlog_position, router->current_pos))); + MXS_WARNING("an error has been found. " + "Setting safe pos to %lu, current pos %lu", + router->binlog_position, router->current_pos); if (fix) { if (ftruncate(router->binlog_fd, router->binlog_position) == 0) { - LOGIF(LM, (skygw_log_write_flush(LOGFILE_MESSAGE, - "Binlog file %s has been truncated at %lu", - router->binlog_name, - router->binlog_position))); + MXS_NOTICE("Binlog file %s has been truncated at %lu", + router->binlog_name, + router->binlog_position); fsync(router->binlog_fd); } } @@ -1444,29 +1401,26 @@ int fde_seen = 0; } if (hdr.next_pos > 0 && hdr.next_pos != (pos + hdr.event_size)) { - LOGIF(LT, (skygw_log_write_flush(LOGFILE_TRACE, - "Binlog %s: next pos %u != (pos %llu + event_size %u), truncating to %llu", - router->binlog_name, - hdr.next_pos, - pos, - hdr.event_size, - pos))); + MXS_INFO("Binlog %s: next pos %u != (pos %llu + event_size %u), truncating to %llu", + router->binlog_name, + hdr.next_pos, + pos, + hdr.event_size, + pos); router->binlog_position = last_known_commit; router->current_safe_event = last_known_commit; router->current_pos = pos; - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "warning : an error has been found. " - "Setting safe pos to %lu, current pos %lu", - router->binlog_position, router->current_pos))); + MXS_WARNING("an error has been found. " + "Setting safe pos to %lu, current pos %lu", + router->binlog_position, router->current_pos); if (fix) { if (ftruncate(router->binlog_fd, router->binlog_position) == 0) { - LOGIF(LM, (skygw_log_write_flush(LOGFILE_MESSAGE, - "Binlog file %s has been truncated at %lu", - router->binlog_name, - router->binlog_position))); + MXS_NOTICE("Binlog file %s has been truncated at %lu", + router->binlog_name, + router->binlog_position); fsync(router->binlog_fd); } } @@ -1488,8 +1442,8 @@ int fde_seen = 0; pos = hdr.next_pos; } else { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Current event type %d @ %llu has nex pos = %u : exiting", hdr.event_type, pos, hdr.next_pos))); + MXS_ERROR("Current event type %d @ %llu has nex pos = %u : exiting", + hdr.event_type, pos, hdr.next_pos); break; } @@ -1497,20 +1451,18 @@ int fde_seen = 0; } if (pending_transaction) { - LOGIF(LT, (skygw_log_write_flush(LOGFILE_TRACE, - "Binlog %s contains an Open Transaction, truncating to %llu", - router->binlog_name, - last_known_commit))); + MXS_INFO("Binlog %s contains an Open Transaction, truncating to %llu", + router->binlog_name, + last_known_commit); router->binlog_position = last_known_commit; router->current_safe_event = last_known_commit; router->current_pos = pos; router->pending_transaction = 1; - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "warning : an error has been found. " - "Setting safe pos to %lu, current pos %lu", - router->binlog_position, router->current_pos))); + MXS_WARNING("an error has been found. " + "Setting safe pos to %lu, current pos %lu", + router->binlog_position, router->current_pos); return 0; } else { @@ -1707,10 +1659,9 @@ char *event_desc; event_desc = blr_get_event_description(router, first_event.event_type); - LOGIF(LM, (skygw_log_write_flush(LOGFILE_MESSAGE, - "%lu @ %llu, %s, (%s), First EventTime", - first_event.event_time, first_event.event_pos, - event_desc != NULL ? event_desc : "unknown", buf_t))); + MXS_NOTICE("%lu @ %llu, %s, (%s), First EventTime", + first_event.event_time, first_event.event_pos, + event_desc != NULL ? event_desc : "unknown", buf_t); /* Last Event */ localtime_r(&last_event.event_time, &tm_t); @@ -1722,9 +1673,8 @@ char *event_desc; event_desc = blr_get_event_description(router, last_event.event_type); - LOGIF(LM, (skygw_log_write_flush(LOGFILE_MESSAGE, - "%lu @ %llu, %s, (%s), Last EventTime", - last_event.event_time, last_event.event_pos, - event_desc != NULL ? event_desc : "unknown", buf_t))); + MXS_NOTICE("%lu @ %llu, %s, (%s), Last EventTime", + last_event.event_time, last_event.event_pos, + event_desc != NULL ? event_desc : "unknown", buf_t); } diff --git a/server/modules/routing/binlog/blr_master.c b/server/modules/routing/binlog/blr_master.c index 7126b6a20..cb555dd30 100644 --- a/server/modules/routing/binlog/blr_master.c +++ b/server/modules/routing/binlog/blr_master.c @@ -87,7 +87,7 @@ static int blr_rotate_event(ROUTER_INSTANCE *router, uint8_t *pkt, REP_HEADER * void blr_distribute_binlog_record(ROUTER_INSTANCE *router, REP_HEADER *hdr, uint8_t *ptr); static void *CreateMySQLAuthData(char *username, char *password, char *database); void blr_extract_header(uint8_t *pkt, REP_HEADER *hdr); -static void blr_log_packet(logfile_id_t file, char *msg, uint8_t *ptr, int len); +static void blr_log_packet(int priority, char *msg, uint8_t *ptr, int len); void blr_master_close(ROUTER_INSTANCE *); char *blr_extract_column(GWBUF *buf, int col); void blr_cache_response(ROUTER_INSTANCE *router, char *response, GWBUF *buf); @@ -119,13 +119,11 @@ DCB *client; if (router->master_state != BLRM_UNCONNECTED) { if (router->master_state != BLRM_SLAVE_STOPPED) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "%s: Master Connect: Unexpected master state %s\n", - router->service->name, blrm_states[router->master_state]))); + MXS_ERROR("%s: Master Connect: Unexpected master state %s\n", + router->service->name, blrm_states[router->master_state]); } else { - LOGIF(LM, (skygw_log_write_flush(LOGFILE_MESSAGE, - "%s: Master Connect: binlog state is %s\n", - router->service->name, blrm_states[router->master_state]))); + MXS_NOTICE("%s: Master Connect: binlog state is %s\n", + router->service->name, blrm_states[router->master_state]); } spinlock_release(&router->lock); return; @@ -142,8 +140,7 @@ DCB *client; spinlock_release(&router->lock); if ((client = dcb_alloc(DCB_ROLE_INTERNAL)) == NULL) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Binlog router: failed to create DCB for dummy client"))); + MXS_ERROR("Binlog router: failed to create DCB for dummy client"); return; } router->client = client; @@ -151,8 +148,7 @@ DCB *client; client->data = CreateMySQLAuthData(router->user, router->password, ""); if ((router->session = session_alloc(router->service, client)) == NULL) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Binlog router: failed to create session for connection to master"))); + MXS_ERROR("Binlog router: failed to create session for connection to master"); return; } client->session = router->session; @@ -169,17 +165,15 @@ DCB *client; } if (router->retry_backoff > BLR_MAX_BACKOFF) router->retry_backoff = BLR_MAX_BACKOFF; - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Binlog router: failed to connect to master server '%s'", - router->service->dbref->server->unique_name))); + MXS_ERROR("Binlog router: failed to connect to master server '%s'", + router->service->dbref->server->unique_name); return; } router->master->remote = strdup(router->service->dbref->server->name); - LOGIF(LM,(skygw_log_write( - LOGFILE_MESSAGE, - "%s: attempting to connect to master server %s:%d, binlog %s, pos %lu", - router->service->name, router->service->dbref->server->name, router->service->dbref->server->port, router->binlog_name, router->current_pos))); + MXS_NOTICE("%s: attempting to connect to master server %s:%d, binlog %s, pos %lu", + router->service->name, router->service->dbref->server->name, + router->service->dbref->server->port, router->binlog_name, router->current_pos); router->connect_time = time(0); @@ -339,10 +333,8 @@ char task_name[BLRM_TASK_NAME_LEN + 1] = ""; spinlock_release(&router->lock); if (router->master_state < 0 || router->master_state > BLRM_MAXSTATE) { - LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, - "Invalid master state machine state (%d) for binlog router.", - router->master_state))); + MXS_ERROR("Invalid master state machine state (%d) for binlog router.", + router->master_state); gwbuf_consume(buf, gwbuf_length(buf)); spinlock_acquire(&router->lock); @@ -351,12 +343,9 @@ char task_name[BLRM_TASK_NAME_LEN + 1] = ""; router->active_logs = 0; spinlock_release(&router->lock); atomic_add(&router->handling_threads, -1); - LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, - "%s: Pending reconnect in state %s.", - router->service->name, - blrm_states[router->master_state] - ))); + MXS_ERROR("%s: Pending reconnect in state %s.", + router->service->name, + blrm_states[router->master_state]); blr_restart_master(router); return; } @@ -374,10 +363,8 @@ char task_name[BLRM_TASK_NAME_LEN + 1] = ""; * continue. The error is saved and replayed to slaves if * they also request the GTID mode. */ - LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, - "%s: Master server does not support GTID Mode.", - router->service->name))); + MXS_ERROR("%s: Master server does not support GTID Mode.", + router->service->name); } else if (router->master_state != BLRM_BINLOGDUMP && MYSQL_RESPONSE_ERR(buf)) { @@ -395,14 +382,11 @@ char task_name[BLRM_TASK_NAME_LEN + 1] = ""; /* NULL terminated error string */ *(msg_err+msg_len)='\0'; - LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, - "%s: Received error: %lu, '%s' from master during '%s' phase " - "of the master state machine.", - router->service->name, - mysql_errno, msg_err, - blrm_states[router->master_state] - ))); + MXS_ERROR("%s: Received error: %lu, '%s' from master during '%s' phase " + "of the master state machine.", + router->service->name, + mysql_errno, msg_err, + blrm_states[router->master_state]); gwbuf_consume(buf, gwbuf_length(buf)); spinlock_acquire(&router->lock); @@ -643,14 +627,12 @@ char task_name[BLRM_TASK_NAME_LEN + 1] = ""; buf = blr_make_binlog_dump(router); router->master_state = BLRM_BINLOGDUMP; router->master->func.write(router->master, buf); - LOGIF(LM,(skygw_log_write( - LOGFILE_MESSAGE, - "%s: Request binlog records from %s at " - "position %lu from master server %s:%d", - router->service->name, router->binlog_name, - router->current_pos, - router->service->dbref->server->name, - router->service->dbref->server->port))); + MXS_NOTICE("%s: Request binlog records from %s at " + "position %lu from master server %s:%d", + router->service->name, router->binlog_name, + router->current_pos, + router->service->dbref->server->name, + router->service->dbref->server->port); /* Log binlog router identity */ blr_log_identity(router); @@ -867,12 +849,10 @@ int n_bufs = -1, pn_bufs = -1; if ((msg = malloc(len)) == NULL) { - LOGIF(LE,(skygw_log_write( - LOGFILE_ERROR, - "Insufficient memory to buffer event " - "of %d bytes. Binlog %s @ %lu.", - len, router->binlog_name, - router->current_pos))); + MXS_ERROR("Insufficient memory to buffer event " + "of %d bytes. Binlog %s @ %lu.", + len, router->binlog_name, + router->current_pos); break; } @@ -891,13 +871,11 @@ int n_bufs = -1, pn_bufs = -1; } if (remainder) { - LOGIF(LE,(skygw_log_write( - LOGFILE_ERROR, - "Expected entire message in buffer " - "chain, but failed to create complete " - "message as expected. %s @ %lu", - router->binlog_name, - router->current_pos))); + MXS_ERROR("Expected entire message in buffer " + "chain, but failed to create complete " + "message as expected. %s @ %lu", + router->binlog_name, + router->current_pos); free(msg); msg = NULL; break; @@ -914,11 +892,9 @@ int n_bufs = -1, pn_bufs = -1; * until we receive the next buffer. */ router->stats.n_residuals++; - LOGIF(LD,(skygw_log_write( - LOGFILE_DEBUG, - "Residual data left after %lu records. %s @ %lu", - router->stats.n_binlogs, - router->binlog_name, router->current_pos))); + MXS_DEBUG("Residual data left after %lu records. %s @ %lu", + router->stats.n_binlogs, + router->binlog_name, router->current_pos); break; } else @@ -949,10 +925,7 @@ int n_bufs = -1, pn_bufs = -1; { msg = "error"; } - LOGIF(LM,(skygw_log_write( - LOGFILE_MESSAGE, - "Non-event message (%s) from master.", - msg))); + MXS_NOTICE("Non-event message (%s) from master.", msg); } else { @@ -964,25 +937,22 @@ int n_bufs = -1, pn_bufs = -1; /* Sanity check */ if (hdr.ok == 0 && hdr.event_size != len - 5) { - LOGIF(LE,(skygw_log_write( - LOGFILE_ERROR, - "Packet length is %d, but event size is %d, " - "binlog file %s position %lu " - "reslen is %d and preslen is %d, " - "length of previous event %d. %s", - len, hdr.event_size, - router->binlog_name, - router->current_pos, - reslen, preslen, prev_length, - (prev_length == -1 ? - (no_residual ? "No residual data from previous call" : "Residual data from previous call") : "") - ))); - blr_log_packet(LOGFILE_ERROR, "Packet:", ptr, len); - LOGIF(LE,(skygw_log_write( - LOGFILE_ERROR, - "This event (0x%x) was contained in %d GWBUFs, " - "the previous events was contained in %d GWBUFs", - router->lastEventReceived, n_bufs, pn_bufs))); + MXS_ERROR("Packet length is %d, but event size is %d, " + "binlog file %s position %lu " + "reslen is %d and preslen is %d, " + "length of previous event %d. %s", + len, hdr.event_size, + router->binlog_name, + router->current_pos, + reslen, preslen, prev_length, + (prev_length == -1 ? + (no_residual ? "No residual data from previous call" : + "Residual data from previous call") : "")); + + blr_log_packet(LOG_ERR, "Packet:", ptr, len); + MXS_ERROR("This event (0x%x) was contained in %d GWBUFs, " + "the previous events was contained in %d GWBUFs", + router->lastEventReceived, n_bufs, pn_bufs); if (msg) { free(msg); @@ -1030,14 +1000,13 @@ int n_bufs = -1, pn_bufs = -1; free(msg); msg = NULL; } - LOGIF(LE,(skygw_log_write(LOGFILE_ERROR, - "%s: Checksum error in event " - "from master, " - "binlog %s @ %lu. " - "Closing master connection.", - router->service->name, - router->binlog_name, - router->current_pos))); + MXS_ERROR("%s: Checksum error in event " + "from master, " + "binlog %s @ %lu. " + "Closing master connection.", + router->service->name, + router->binlog_name, + router->current_pos); blr_master_close(router); blr_master_delayed_connect(router); return; @@ -1088,14 +1057,14 @@ int n_bufs = -1, pn_bufs = -1; if (flags == 0) { if (router->pending_transaction > 0) { - LOGIF(LE,(skygw_log_write_flush(LOGFILE_ERROR, - "Error: a MariaDB 10 transaction " - "is already open " - "@ %lu (GTID %u-%u-%lu) and " - "a new one starts @ %lu", - router->binlog_position, - domainid, hdr.serverid, n_sequence, - router->current_pos))); + MXS_ERROR("A MariaDB 10 transaction " + "is already open " + "@ %lu (GTID %u-%u-%lu) and " + "a new one starts @ %lu", + router->binlog_position, + domainid, hdr.serverid, + n_sequence, + router->current_pos); // An action should be taken here } @@ -1127,11 +1096,10 @@ int n_bufs = -1, pn_bufs = -1; if (strncmp(statement_sql, "BEGIN", 5) == 0) { if (router->pending_transaction > 0) { - LOGIF(LE,(skygw_log_write_flush(LOGFILE_ERROR, - "Error: a transaction is already open " - "@ %lu and a new one starts @ %lu", - router->binlog_position, - router->current_pos))); + MXS_ERROR("A transaction is already open " + "@ %lu and a new one starts @ %lu", + router->binlog_position, + router->current_pos); // An action should be taken here } @@ -1175,11 +1143,10 @@ int n_bufs = -1, pn_bufs = -1; if (hdr.event_type == FORMAT_DESCRIPTION_EVENT && hdr.next_pos == 0) { // Fake format description message - LOGIF(LD,(skygw_log_write(LOGFILE_DEBUG, - "Replication fake event. " - "Binlog %s @ %lu.", - router->binlog_name, - router->current_pos))); + MXS_DEBUG("Replication fake event. " + "Binlog %s @ %lu.", + router->binlog_name, + router->current_pos); router->stats.n_fakeevents++; if (hdr.event_type == FORMAT_DESCRIPTION_EVENT) @@ -1202,13 +1169,12 @@ int n_bufs = -1, pn_bufs = -1; } else { - LOGIF(LE,(skygw_log_write(LOGFILE_ERROR, - "%s: Received a format description " - "event that MaxScale was unable to " - "record. Event length is %d.", - router->service->name, - hdr.event_size))); - blr_log_packet(LOGFILE_ERROR, + MXS_ERROR("%s: Received a format description " + "event that MaxScale was unable to " + "record. Event length is %d.", + router->service->name, + hdr.event_size); + blr_log_packet(LOG_ERR, "Format Description Event:", ptr, len); } } @@ -1220,12 +1186,10 @@ int n_bufs = -1, pn_bufs = -1; #ifdef SHOW_EVENTS printf("Replication heartbeat\n"); #endif - LOGIF(LD,(skygw_log_write( - LOGFILE_DEBUG, - "Replication heartbeat. " - "Binlog %s @ %lu.", - router->binlog_name, - router->current_pos))); + MXS_DEBUG("Replication heartbeat. " + "Binlog %s @ %lu.", + router->binlog_name, + router->current_pos); router->stats.n_heartbeats++; @@ -1347,23 +1311,23 @@ int n_bufs = -1, pn_bufs = -1; /* No event has been sent */ if (pos == router->binlog_position) { - LOGIF(LE,(skygw_log_write(LOGFILE_ERROR, - "No events distributed to slaves for a pending transaction in %s at %lu." - " Last event from master at %lu", - router->binlog_name, - router->binlog_position, - router->current_pos))); + MXS_ERROR("No events distributed to slaves for a pending " + "transaction in %s at %lu. " + "Last event from master at %lu", + router->binlog_name, + router->binlog_position, + router->current_pos); strncpy(err_message, "No transaction events sent", BINLOG_ERROR_MSG_LEN); } else { /* Some events have been sent */ - LOGIF(LE,(skygw_log_write(LOGFILE_ERROR, - "Some events were not distributed to slaves for a pending transaction " - "in %s at %lu. Last distributed even at %llu, last event from master at %lu", - router->binlog_name, - router->binlog_position, - pos, - router->current_pos))); + MXS_ERROR("Some events were not distributed to slaves for a " + "pending transaction in %s at %lu. Last distributed " + "even at %llu, last event from master at %lu", + router->binlog_name, + router->binlog_position, + pos, + router->current_pos); strncpy(err_message, "Incomplete transaction events sent", BINLOG_ERROR_MSG_LEN); } @@ -1386,16 +1350,14 @@ int n_bufs = -1, pn_bufs = -1; else { router->stats.n_artificial++; - LOGIF(LD,(skygw_log_write( - LOGFILE_DEBUG, - "Artificial event not written " - "to disk or distributed. " - "Type 0x%x, Length %d, Binlog " - "%s @ %lu.", - hdr.event_type, - hdr.event_size, - router->binlog_name, - router->current_pos))); + MXS_DEBUG("Artificial event not written " + "to disk or distributed. " + "Type 0x%x, Length %d, Binlog " + "%s @ %lu.", + hdr.event_type, + hdr.event_size, + router->binlog_name, + router->current_pos); ptr += 5; if (hdr.event_type == ROTATE_EVENT) { @@ -1445,10 +1407,9 @@ int n_bufs = -1, pn_bufs = -1; spinlock_release(&router->lock); - LOGIF(LE,(skygw_log_write(LOGFILE_ERROR, - "Error packet in binlog stream.%s @ %lu.", - router->binlog_name, - router->current_pos))); + MXS_ERROR("Error packet in binlog stream.%s @ %lu.", + router->binlog_name, + router->current_pos); router->stats.n_binlog_errors++; } @@ -1572,9 +1533,7 @@ MYSQL_session *auth_info; if (username == NULL || password == NULL) { - LOGIF(LE,(skygw_log_write( - LOGFILE_ERROR, - "You must specify both username and password for the binlog router.\n"))); + MXS_ERROR("You must specify both username and password for the binlog router.\n"); return NULL; } @@ -1690,12 +1649,11 @@ int action; * happen. Force the slave to catchup mode in order to * try to resolve the issue. */ - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Slave %d is ahead of expected position %s@%lu. " - "Expected position %d", - slave->serverid, slave->binlogfile, - (unsigned long)slave->binlog_pos, - hdr->next_pos - hdr->event_size))); + MXS_ERROR("Slave %d is ahead of expected position %s@%lu. " + "Expected position %d", + slave->serverid, slave->binlogfile, + (unsigned long)slave->binlog_pos, + hdr->next_pos - hdr->event_size); } /* @@ -1792,13 +1750,13 @@ int action; /** * Write a raw event (the first 40 bytes at most) to a log file * - * @param file The logfile to write to - * @param msg A textual message to write before the packet - * @param ptr Pointer to the message buffer - * @param len Length of message packet + * @param priority The syslog priority of the message (LOG_ERR, LOG_WARNING, etc.) + * @param msg A textual message to write before the packet + * @param ptr Pointer to the message buffer + * @param len Length of message packet */ static void -blr_log_packet(logfile_id_t file, char *msg, uint8_t *ptr, int len) +blr_log_packet(int priority, char *msg, uint8_t *ptr, int len) { char buf[400] = ""; char *bufp; @@ -1809,10 +1767,9 @@ int i; for (i = 0; i < len && i < 40; i++) bufp += sprintf(bufp, "0x%02x ", ptr[i]); if (i < len) - skygw_log_write_flush(file, "%s...", buf); + MXS_LOG_MESSAGE(priority, "%s...", buf); else - skygw_log_write_flush(file, "%s", buf); - + MXS_LOG_MESSAGE(priority, "%s", buf); } /** @@ -1924,10 +1881,9 @@ int event_limit; /* error */ if (pos > end_pos) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Error: Reading saved events, the specified pos %llu " - "is ahead of current pos %lu for file %s", - pos, router->current_pos, router->binlog_name))); + MXS_ERROR("Reading saved events, the specified pos %llu " + "is ahead of current pos %lu for file %s", + pos, router->current_pos, router->binlog_name); return NULL; } @@ -1937,31 +1893,27 @@ int event_limit; switch (n) { case 0: - LOGIF(LD, (skygw_log_write(LOGFILE_DEBUG, - "Reading saved events: reached end of binlog file at %llu.", pos))); + MXS_DEBUG("Reading saved events: reached end of binlog file at %llu.", pos); break; case -1: { char err_msg[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "Error: Reading saved events: failed to read binlog " - "file %s at position %llu" - " (%s).", router->binlog_name, - pos, strerror_r(errno, err_msg, sizeof(err_msg))))); + MXS_ERROR("Reading saved events: failed to read binlog " + "file %s at position %llu" + " (%s).", router->binlog_name, + pos, strerror_r(errno, err_msg, sizeof(err_msg))); if (errno == EBADF) - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "Error: Reading saved events: bad file descriptor for file %s" - ", descriptor %d.", - router->binlog_name, router->binlog_fd))); + MXS_ERROR("Reading saved events: bad file descriptor for file %s" + ", descriptor %d.", + router->binlog_name, router->binlog_fd); break; } default: - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "Error: Reading saved events: short read when reading the header. " - "Expected 19 bytes but got %d bytes. " - "Binlog file is %s, position %llu", - n, router->binlog_name, pos))); + MXS_ERROR("Reading saved events: short read when reading the header. " + "Expected 19 bytes but got %d bytes. " + "Binlog file is %s, position %llu", + n, router->binlog_name, pos); break; } @@ -1979,20 +1931,18 @@ int event_limit; if (hdr->event_type > event_limit) { - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "Error: Reading saved events: invalid event type 0x%x. " - "Binlog file is %s, position %llu", - hdr->event_type, - router->binlog_name, pos))); + MXS_ERROR("Reading saved events: invalid event type 0x%x. " + "Binlog file is %s, position %llu", + hdr->event_type, + router->binlog_name, pos); return NULL; } if ((result = gwbuf_alloc(hdr->event_size)) == NULL) { - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "Error: Reading saved events: failed to allocate memory for binlog entry, " - "size %d at %llu.", - hdr->event_size, pos))); + MXS_ERROR("Reading saved events: failed to allocate memory for binlog entry, " + "size %d at %llu.", + hdr->event_size, pos); return NULL; } @@ -2006,24 +1956,21 @@ int event_limit; if (n == -1) { char err_msg[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "Error: Reading saved events: the event at %llu in %s. " - "%s, expected %d bytes.", - pos, router->binlog_name, - strerror_r(errno, err_msg, sizeof(err_msg)), hdr->event_size - 19))); + MXS_ERROR("Reading saved events: the event at %llu in %s. " + "%s, expected %d bytes.", + pos, router->binlog_name, + strerror_r(errno, err_msg, sizeof(err_msg)), hdr->event_size - 19); } else { - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "Error: Reading saved events: short read when reading " - "the event at %llu in %s. " - "Expected %d bytes got %d bytes.", - pos, router->binlog_name, hdr->event_size - 19, n))); + MXS_ERROR("Reading saved events: short read when reading " + "the event at %llu in %s. " + "Expected %d bytes got %d bytes.", + pos, router->binlog_name, hdr->event_size - 19, n); if (end_pos - pos < hdr->event_size) { - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "Error: Reading saved events: binlog event " - "is close to the end of the binlog file, " - "current file size is %llu.", end_pos))); + MXS_ERROR("Reading saved events: binlog event " + "is close to the end of the binlog file, " + "current file size is %llu.", end_pos); } } @@ -2154,14 +2101,15 @@ char *event_desc = NULL; if (router->master_state == BLRM_BINLOGDUMP && router->lastEventReceived > 0) { if ((t_now - router->stats.lastReply) > (router->heartbeat + BLR_NET_LATENCY_WAIT_TIME)) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "ERROR: No event received from master %s:%d in heartbeat period (%lu seconds), last event (%s %d) received %lu seconds ago. Assuming connection is dead and reconnecting.", - router->service->dbref->server->name, - router->service->dbref->server->port, - router->heartbeat, - event_desc != NULL ? event_desc : "unknown", - router->lastEventReceived, - t_now - router->stats.lastReply))); + MXS_ERROR("No event received from master %s:%d in heartbeat period (%lu seconds), " + "last event (%s %d) received %lu seconds ago. Assuming connection is dead " + "and reconnecting.", + router->service->dbref->server->name, + router->service->dbref->server->port, + router->heartbeat, + event_desc != NULL ? event_desc : "unknown", + router->lastEventReceived, + t_now - router->stats.lastReply); return 0; } @@ -2201,33 +2149,27 @@ static void blr_log_identity(ROUTER_INSTANCE *router) { } /* Seen by the master */ - LOGIF(LM, (skygw_log_write_flush( - LOGFILE_MESSAGE, - "%s: identity seen by the master: " - "server_id: %d, uuid: %s", - router->service->name, - router->serverid, (router->uuid == NULL ? "not available" : router->uuid)))); + MXS_NOTICE("%s: identity seen by the master: " + "server_id: %d, uuid: %s", + router->service->name, + router->serverid, (router->uuid == NULL ? "not available" : router->uuid)); /* Seen by the slaves */ /* MariaDB 5.5 and MariaDB don't have the MASTER_UUID var */ if (master_uuid == NULL) { - LOGIF(LM, (skygw_log_write_flush( - LOGFILE_MESSAGE, - "%s: identity seen by the slaves: " - "server_id: %d, hostname: %s, MySQL version: %s", - router->service->name, - router->masterid, (master_hostname == NULL ? "not available" : master_hostname), - (master_version == NULL ? "not available" : master_version)))); + MXS_NOTICE("%s: identity seen by the slaves: " + "server_id: %d, hostname: %s, MySQL version: %s", + router->service->name, + router->masterid, (master_hostname == NULL ? "not available" : master_hostname), + (master_version == NULL ? "not available" : master_version)); } else { - LOGIF(LM, (skygw_log_write_flush( - LOGFILE_MESSAGE, - "%s: identity seen by the slaves: " - "server_id: %d, uuid: %s, hostname: %s, MySQL version: %s", - router->service->name, - router->masterid, master_uuid, - (master_hostname == NULL ? "not available" : master_hostname), - (master_version == NULL ? "not available" : master_version)))); + MXS_NOTICE("%s: identity seen by the slaves: " + "server_id: %d, uuid: %s, hostname: %s, MySQL version: %s", + router->service->name, + router->masterid, master_uuid, + (master_hostname == NULL ? "not available" : master_hostname), + (master_version == NULL ? "not available" : master_version)); } } diff --git a/server/modules/routing/binlog/blr_slave.c b/server/modules/routing/binlog/blr_slave.c index 0adbaef02..6cc941587 100644 --- a/server/modules/routing/binlog/blr_slave.c +++ b/server/modules/routing/binlog/blr_slave.c @@ -176,9 +176,8 @@ blr_slave_request(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave, GWBUF *queue) { if (slave->state < 0 || slave->state > BLRS_MAXSTATE) { - LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, "Invalid slave state machine state (%d) for binlog router.", - slave->state))); + MXS_ERROR("Invalid slave state machine state (%d) for binlog router.", + slave->state); gwbuf_consume(queue, gwbuf_length(queue)); return 0; } @@ -196,11 +195,9 @@ blr_slave_request(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave, GWBUF *queue) blr_slave_send_error_packet(slave, "Binlog router is not yet configured for replication", (unsigned int) 1597, NULL); - LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, - "%s: Slave %s: Binlog router is not yet configured for replication", - router->service->name, - slave->dcb->remote))); + MXS_ERROR("%s: Slave %s: Binlog router is not yet configured for replication", + router->service->name, + slave->dcb->remote); dcb_close(slave->dcb); return 1; } @@ -215,11 +212,9 @@ blr_slave_request(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave, GWBUF *queue) blr_send_custom_error(slave->dcb, 1, 0, "MariaDB 10 Slave is required for Slave registration", "42000", 1064); - LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, - "%s: Slave %s: a MariaDB 10 Slave is required for Slave registration", - router->service->name, - slave->dcb->remote))); + MXS_ERROR("%s: Slave %s: a MariaDB 10 Slave is required for Slave registration", + router->service->name, + slave->dcb->remote); dcb_close(slave->dcb); return 1; @@ -252,18 +247,15 @@ blr_slave_request(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave, GWBUF *queue) return blr_ping(router, slave, queue); break; case COM_QUIT: - LOGIF(LD, (skygw_log_write(LOGFILE_DEBUG, - "COM_QUIT received from slave with server_id %d", - slave->serverid))); + MXS_DEBUG("COM_QUIT received from slave with server_id %d", + slave->serverid); break; default: blr_send_custom_error(slave->dcb, 1, 0, "You have an error in your SQL syntax; Check the syntax the MaxScale binlog router accepts.", "42000", 1064); - LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, - "Unexpected MySQL Command (%d) received from slave", - MYSQL_COMMAND(queue)))); + MXS_ERROR("Unexpected MySQL Command (%d) received from slave", + MYSQL_COMMAND(queue)); break; } return 0; @@ -355,13 +347,11 @@ extern char *strcasestr(); } } - LOGIF(LT, (skygw_log_write( - LOGFILE_TRACE, "Execute statement (truncated, it contains password)" - " from the slave '%s'", new_text))); + MXS_INFO("Execute statement (truncated, it contains password)" + " from the slave '%s'", new_text); free(new_text); } else { - LOGIF(LT, (skygw_log_write( - LOGFILE_TRACE, "Execute statement from the slave '%s'", query_text))); + MXS_INFO("Execute statement from the slave '%s'", query_text); } /* @@ -375,15 +365,14 @@ extern char *strcasestr(); if ((word = strtok_r(query_text, sep, &brkb)) == NULL) { - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, "%s: Incomplete query.", - router->service->name))); + MXS_ERROR("%s: Incomplete query.", router->service->name); } else if (strcasecmp(word, "SELECT") == 0) { if ((word = strtok_r(NULL, sep, &brkb)) == NULL) { - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, "%s: Incomplete select query.", - router->service->name))); + MXS_ERROR("%s: Incomplete select query.", + router->service->name); } else if (strcasecmp(word, "UNIX_TIMESTAMP()") == 0) { @@ -485,8 +474,8 @@ extern char *strcasestr(); { if ((word = strtok_r(NULL, sep, &brkb)) == NULL) { - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, "%s: Incomplete show query.", - router->service->name))); + MXS_ERROR("%s: Incomplete show query.", + router->service->name); } else if (strcasecmp(word, "WARNINGS") == 0) { @@ -502,9 +491,8 @@ extern char *strcasestr(); if ((word = strtok_r(NULL, sep, &brkb)) == NULL) { - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "%s: Expected VARIABLES in SHOW GLOBAL", - router->service->name))); + MXS_ERROR("%s: Expected VARIABLES in SHOW GLOBAL", + router->service->name); } else if (strcasecmp(word, "VARIABLES") == 0) { @@ -519,9 +507,8 @@ extern char *strcasestr(); return 1; } else - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "%s: Expected LIKE clause in SHOW GLOBAL VARIABLES.", - router->service->name))); + MXS_ERROR("%s: Expected LIKE clause in SHOW GLOBAL VARIABLES.", + router->service->name); } else if (strcasecmp(word, "STATUS") == 0) { @@ -536,9 +523,8 @@ extern char *strcasestr(); return 1; } else - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "%s: Expected LIKE clause in SHOW GLOBAL STATUS.", - router->service->name))); + MXS_ERROR("%s: Expected LIKE clause in SHOW GLOBAL STATUS.", + router->service->name); } } else if (strcasecmp(word, "VARIABLES") == 0) @@ -560,17 +546,15 @@ extern char *strcasestr(); return 1; } else - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "%s: Expected LIKE clause in SHOW VARIABLES.", - router->service->name))); + MXS_ERROR("%s: Expected LIKE clause in SHOW VARIABLES.", + router->service->name); } else if (strcasecmp(word, "MASTER") == 0) { if ((word = strtok_r(NULL, sep, &brkb)) == NULL) { - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "%s: Expected SHOW MASTER STATUS command", - router->service->name))); + MXS_ERROR("%s: Expected SHOW MASTER STATUS command", + router->service->name); } else if (strcasecmp(word, "STATUS") == 0) { @@ -588,9 +572,8 @@ extern char *strcasestr(); { if ((word = strtok_r(NULL, sep, &brkb)) == NULL) { - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "%s: Expected SHOW SLAVE STATUS command", - router->service->name))); + MXS_ERROR("%s: Expected SHOW SLAVE STATUS command", + router->service->name); } else if (strcasecmp(word, "STATUS") == 0) { @@ -624,17 +607,16 @@ extern char *strcasestr(); return 1; } else - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "%s: Expected LIKE clause in SHOW STATUS.", - router->service->name))); + MXS_ERROR("%s: Expected LIKE clause in SHOW STATUS.", + router->service->name); } } else if (strcasecmp(query_text, "SET") == 0) { if ((word = strtok_r(NULL, sep, &brkb)) == NULL) { - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, "%s: Incomplete set command.", - router->service->name))); + MXS_ERROR("%s: Incomplete set command.", + router->service->name); } else if (strcasecmp(word, "@master_heartbeat_period") == 0) { @@ -694,8 +676,8 @@ extern char *strcasestr(); { if ((word = strtok_r(NULL, sep, &brkb)) == NULL) { - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, "%s: Truncated SET NAMES command.", - router->service->name))); + MXS_ERROR("%s: Truncated SET NAMES command.", + router->service->name); } else if (strcasecmp(word, "latin1") == 0) { @@ -713,8 +695,8 @@ extern char *strcasestr(); { if ((word = strtok_r(NULL, sep, &brkb)) == NULL) { - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, "%s: Incomplete RESET command.", - router->service->name))); + MXS_ERROR("%s: Incomplete RESET command.", + router->service->name); } else if (strcasecmp(word, "SLAVE") == 0) { @@ -731,7 +713,7 @@ extern char *strcasestr(); if (!current_master) { snprintf(error_string, BINLOG_ERROR_MSG_LEN, "error allocating memory for blr_master_get_config"); - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, "%s: %s", router->service->name, error_string))); + MXS_ERROR("%s: %s", router->service->name, error_string); blr_slave_send_error_packet(slave, error_string, (unsigned int)1201, NULL); return 1; @@ -740,13 +722,15 @@ extern char *strcasestr(); /* get current data */ blr_master_get_config(router, current_master); - LOGIF(LM, (skygw_log_write(LOGFILE_MESSAGE, "%s: 'RESET SLAVE executed'. Previous state MASTER_HOST='%s', MASTER_PORT=%i, MASTER_LOG_FILE='%s', MASTER_LOG_POS=%lu, MASTER_USER='%s'", - router->service->name, - current_master->host, - current_master->port, - current_master->logfile, - current_master->pos, - current_master->user))); + MXS_NOTICE("%s: 'RESET SLAVE executed'. Previous state MASTER_HOST='%s', " + "MASTER_PORT=%i, MASTER_LOG_FILE='%s', MASTER_LOG_POS=%lu, " + "MASTER_USER='%s'", + router->service->name, + current_master->host, + current_master->port, + current_master->logfile, + current_master->pos, + current_master->user); /* remove master.ini */ strncpy(path, router->binlogdir, PATH_MAX); @@ -759,7 +743,7 @@ extern char *strcasestr(); if (removed_cfg == -1) { char err_msg[STRERROR_BUFLEN]; snprintf(error_string, BINLOG_ERROR_MSG_LEN, "Error removing %s, %s, errno %u", path, strerror_r(errno, err_msg, sizeof(err_msg)), errno); - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, "%s: %s", router->service->name, error_string))); + MXS_ERROR("%s: %s", router->service->name, error_string); } spinlock_acquire(&router->lock); @@ -790,8 +774,8 @@ extern char *strcasestr(); { if ((word = strtok_r(NULL, sep, &brkb)) == NULL) { - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, "%s: Incomplete START command.", - router->service->name))); + MXS_ERROR("%s: Incomplete START command.", + router->service->name); } else if (strcasecmp(word, "SLAVE") == 0) { @@ -804,8 +788,7 @@ extern char *strcasestr(); { if ((word = strtok_r(NULL, sep, &brkb)) == NULL) { - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, "%s: Incomplete STOP command.", - router->service->name))); + MXS_ERROR("%s: Incomplete STOP command.", router->service->name); } else if (strcasecmp(word, "SLAVE") == 0) { @@ -818,8 +801,7 @@ extern char *strcasestr(); { if ((word = strtok_r(NULL, sep, &brkb)) == NULL) { - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, "%s: Incomplete CHANGE command.", - router->service->name))); + MXS_ERROR("%s: Incomplete CHANGE command.", router->service->name); } else if (strcasecmp(word, "MASTER") == 0) { @@ -840,7 +822,7 @@ extern char *strcasestr(); if (!current_master) { free(query_text); strcpy(error_string, "Error allocating memory for blr_master_get_config"); - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, "%s: %s", router->service->name, error_string))); + MXS_ERROR("%s: %s", router->service->name, error_string); blr_slave_send_error_packet(slave, error_string, (unsigned int)1201, NULL); @@ -876,8 +858,8 @@ extern char *strcasestr(); spinlock_release(&router->lock); snprintf(error_string, BINLOG_ERROR_MSG_LEN, "Error writing into %s/master.ini: %s", router->binlogdir, error); - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, "%s: %s", - router->service->name, error_string))); + MXS_ERROR("%s: %s", + router->service->name, error_string); blr_slave_send_error_packet(slave, error_string, (unsigned int)1201, NULL); @@ -923,8 +905,8 @@ extern char *strcasestr(); { if ((word = strtok_r(NULL, sep, &brkb)) == NULL) { - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, "%s: Incomplete DISCONNECT command.", - router->service->name))); + MXS_ERROR("%s: Incomplete DISCONNECT command.", + router->service->name); } else if (strcasecmp(word, "ALL") == 0) { @@ -935,9 +917,8 @@ extern char *strcasestr(); { if ((word = strtok_r(NULL, sep, &brkb)) == NULL) { - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "%s: Expected DISCONNECT SERVER $server_id", - router->service->name))); + MXS_ERROR("%s: Expected DISCONNECT SERVER $server_id", + router->service->name); } else { int serverid = atoi(word); free(query_text); @@ -949,8 +930,7 @@ extern char *strcasestr(); free(query_text); query_text = strndup(qtext, query_len); - LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, "Unexpected query from '%s'@'%s': %s", slave->dcb->user, slave->dcb->remote, query_text))); + MXS_ERROR("Unexpected query from '%s'@'%s': %s", slave->dcb->user, slave->dcb->remote, query_text); free(query_text); blr_slave_send_error(router, slave, "You have an error in your SQL syntax; Check the syntax the MaxScale binlog router accepts."); return 1; @@ -984,8 +964,7 @@ GWBUF *clone; } else { - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "Failed to clone server response to send to slave."))); + MXS_ERROR("Failed to clone server response to send to slave."); return 0; } } @@ -1713,20 +1692,16 @@ uint32_t chksum; binlognamelen = len - 11; if (binlognamelen > BINLOG_FNAMELEN) { - LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, - "blr_slave_binlog_dump truncating binlog filename " - "from %d to %d", - binlognamelen, BINLOG_FNAMELEN))); + MXS_ERROR("blr_slave_binlog_dump truncating binlog filename " + "from %d to %d", + binlognamelen, BINLOG_FNAMELEN); binlognamelen = BINLOG_FNAMELEN; } ptr += 4; // Skip length and sequence number if (*ptr++ != COM_BINLOG_DUMP) { - LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, - "blr_slave_binlog_dump expected a COM_BINLOG_DUMP but received %d", - *(ptr-1)))); + MXS_ERROR("blr_slave_binlog_dump expected a COM_BINLOG_DUMP but received %d", + *(ptr-1)); return 0; } @@ -1737,12 +1712,10 @@ uint32_t chksum; strncpy(slave->binlogfile, (char *)ptr, binlognamelen); slave->binlogfile[binlognamelen] = 0; - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%s: COM_BINLOG_DUMP: binlog name '%s', length %d, " - "from position %lu.", router->service->name, - slave->binlogfile, binlognamelen, - (unsigned long)slave->binlog_pos))); + MXS_DEBUG("%s: COM_BINLOG_DUMP: binlog name '%s', length %d, " + "from position %lu.", router->service->name, + slave->binlogfile, binlognamelen, + (unsigned long)slave->binlog_pos); slave->seqno = 1; @@ -1808,12 +1781,10 @@ uint32_t chksum; slave->state = BLRS_DUMPING; - LOGIF(LM, (skygw_log_write( - LOGFILE_MESSAGE, - "%s: Slave %s, server id %d requested binlog file %s from position %lu", - router->service->name, slave->dcb->remote, - slave->serverid, - slave->binlogfile, (unsigned long)slave->binlog_pos))); + MXS_NOTICE("%s: Slave %s, server id %d requested binlog file %s from position %lu", + router->service->name, slave->dcb->remote, + slave->serverid, + slave->binlogfile, (unsigned long)slave->binlog_pos); if (slave->binlog_pos != router->binlog_position || strcmp(slave->binlogfile, router->binlog_name) != 0) @@ -1949,11 +1920,10 @@ char read_errmsg[BINLOG_ERROR_MSG_LEN+1]; poll_fake_write_event(slave->dcb); return rval; } - LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, - "Slave %s:%i, server-id %d, binlog '%s': blr_slave_catchup failed to open binlog file", - slave->dcb->remote, slave->port, slave->serverid, - slave->binlogfile))); + MXS_ERROR("Slave %s:%i, server-id %d, binlog '%s': blr_slave_catchup " + "failed to open binlog file", + slave->dcb->remote, slave->port, slave->serverid, + slave->binlogfile); slave->cstate &= ~CS_BUSY; slave->state = BLRS_ERRORED; @@ -1987,9 +1957,8 @@ char read_errmsg[BINLOG_ERROR_MSG_LEN+1]; unsigned long beat1 = hkheartbeat; blr_close_binlog(router, slave->file); if (hkheartbeat - beat1 > 1) - LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, "blr_close_binlog took %lu maxscale beats", - hkheartbeat - beat1))); + MXS_ERROR("blr_close_binlog took %lu maxscale beats", + hkheartbeat - beat1); blr_slave_rotate(router, slave, GWBUF_DATA(record)); beat1 = hkheartbeat; if ((slave->file = blr_open_binlog(router, slave->binlogfile)) == NULL) @@ -2005,13 +1974,12 @@ char read_errmsg[BINLOG_ERROR_MSG_LEN+1]; poll_fake_write_event(slave->dcb); return rval; } - LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, - "Slave %s:%i, server-id %d, binlog '%s': blr_slave_catchup failed to open binlog file in rotate event", - slave->dcb->remote, - slave->port, - slave->serverid, - slave->binlogfile))); + MXS_ERROR("Slave %s:%i, server-id %d, binlog '%s': blr_slave_catchup " + "failed to open binlog file in rotate event", + slave->dcb->remote, + slave->port, + slave->serverid, + slave->binlogfile); slave->state = BLRS_ERRORED; @@ -2024,9 +1992,8 @@ char read_errmsg[BINLOG_ERROR_MSG_LEN+1]; break; } if (hkheartbeat - beat1 > 1) - LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, "blr_open_binlog took %lu beats", - hkheartbeat - beat1))); + MXS_ERROR("blr_open_binlog took %lu beats", + hkheartbeat - beat1); } slave->stats.n_bytes += gwbuf_length(head); written = slave->dcb->func.write(slave->dcb, head); @@ -2046,14 +2013,13 @@ char read_errmsg[BINLOG_ERROR_MSG_LEN+1]; slave->stats.n_failed_read++; if (hdr.ok == SLAVE_POS_READ_ERR) { - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "%s Slave %s:%i, server-id %d, binlog '%s', %s", - router->service->name, - slave->dcb->remote, - slave->port, - slave->serverid, - slave->binlogfile, - read_errmsg))); + MXS_ERROR("%s Slave %s:%i, server-id %d, binlog '%s', %s", + router->service->name, + slave->dcb->remote, + slave->port, + slave->serverid, + slave->binlogfile, + read_errmsg); spinlock_acquire(&slave->catch_lock); @@ -2075,14 +2041,13 @@ char read_errmsg[BINLOG_ERROR_MSG_LEN+1]; ROUTER_OBJECT *router_obj= router->service->router; - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "%s: Slave %s:%i, server-id %d, binlog '%s', %s", - router->service->name, - slave->dcb->remote, - slave->port, - slave->serverid, - slave->binlogfile, - read_errmsg))); + MXS_ERROR("%s: Slave %s:%i, server-id %d, binlog '%s', %s", + router->service->name, + slave->dcb->remote, + slave->port, + slave->serverid, + slave->binlogfile, + read_errmsg); /* * Close the slave session and socket @@ -2142,23 +2107,21 @@ char read_errmsg[BINLOG_ERROR_MSG_LEN+1]; slave->stats.n_caughtup++; if (slave->stats.n_caughtup == 1) { - LOGIF(LM, (skygw_log_write(LOGFILE_MESSAGE, - "%s: Slave %s:%d, server-id %d is up to date '%s', position %lu.", - router->service->name, - slave->dcb->remote, - slave->port, - slave->serverid, - slave->binlogfile, (unsigned long)slave->binlog_pos))); + MXS_NOTICE("%s: Slave %s:%d, server-id %d is up to date '%s', position %lu.", + router->service->name, + slave->dcb->remote, + slave->port, + slave->serverid, + slave->binlogfile, (unsigned long)slave->binlog_pos); } else if ((slave->stats.n_caughtup % 50) == 0) { - LOGIF(LM, (skygw_log_write(LOGFILE_MESSAGE, - "%s: Slave %s:%d, server-id %d is up to date '%s', position %lu.", - router->service->name, - slave->dcb->remote, - slave->port, - slave->serverid, - slave->binlogfile, (unsigned long)slave->binlog_pos))); + MXS_NOTICE("%s: Slave %s:%d, server-id %d is up to date '%s', position %lu.", + router->service->name, + slave->dcb->remote, + slave->port, + slave->serverid, + slave->binlogfile, (unsigned long)slave->binlog_pos); } } } @@ -2178,13 +2141,12 @@ char read_errmsg[BINLOG_ERROR_MSG_LEN+1]; * but the new binlog file has not yet been created. Therefore * we ignore these issues during the rotate processing. */ - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "Slave reached end of file for binlog file %s at %lu " - "which is not the file currently being downloaded. " - "Master binlog is %s, %lu. This may be caused by a " - "previous failure of the master.", - slave->binlogfile, (unsigned long)slave->binlog_pos, - router->binlog_name, router->binlog_position))); + MXS_ERROR("Slave reached end of file for binlog file %s at %lu " + "which is not the file currently being downloaded. " + "Master binlog is %s, %lu. This may be caused by a " + "previous failure of the master.", + slave->binlogfile, (unsigned long)slave->binlog_pos, + router->binlog_name, router->binlog_position); if (blr_slave_fake_rotate(router, slave)) { spinlock_acquire(&slave->catch_lock); @@ -2246,9 +2208,8 @@ ROUTER_INSTANCE *router = slave->router; } else { - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, "Ignored callback due to slave state %s", - blrs_states[slave->state]))); + MXS_DEBUG("Ignored callback due to slave state %s", + blrs_states[slave->state]); } } @@ -2385,13 +2346,12 @@ char err_msg[BINLOG_ERROR_MSG_LEN+1]; if ((record = blr_read_binlog(router, file, 4, &hdr, err_msg)) == NULL) { if (hdr.ok != SLAVE_POS_READ_OK) { - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "Slave %s:%i, server-id %d, binlog '%s', blr_read_binlog failure: %s", - slave->dcb->remote, - slave->port, - slave->serverid, - slave->binlogfile, - err_msg))); + MXS_ERROR("Slave %s:%i, server-id %d, binlog '%s', blr_read_binlog failure: %s", + slave->dcb->remote, + slave->port, + slave->serverid, + slave->binlogfile, + err_msg); } blr_close_binlog(router, file); @@ -2610,12 +2570,12 @@ blr_slave_disconnect_server(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave, int se { /* server_id found */ server_found = 1; - LOGIF(LM, (skygw_log_write(LOGFILE_MESSAGE, "%s: Slave %s, server id %d, disconnected by %s@%s", - router->service->name, - sptr->dcb->remote, - server_id, - slave->dcb->user, - slave->dcb->remote))); + MXS_NOTICE("%s: Slave %s, server id %d, disconnected by %s@%s", + router->service->name, + sptr->dcb->remote, + server_id, + slave->dcb->user, + slave->dcb->remote); /* send server_id with disconnect state to client */ n = blr_slave_send_disconnected_server(router, slave, server_id, 1); @@ -2640,9 +2600,9 @@ blr_slave_disconnect_server(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave, int se } if (n == 0) { - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, "Error: gwbuf memory allocation in " - "DISCONNECT SERVER server_id [%d]", - sptr->serverid))); + MXS_ERROR("gwbuf memory allocation in " + "DISCONNECT SERVER server_id [%d]", + sptr->serverid); blr_slave_send_error(router, slave, "Memory allocation error for DISCONNECT SERVER"); } @@ -2690,9 +2650,9 @@ blr_slave_disconnect_all(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave) len = 5 + strlen(server_id) + strlen(state) + 1; if ((pkt = gwbuf_alloc(len)) == NULL) { - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, "Error: gwbuf memory allocation in " - "DISCONNECT ALL for [%s], server_id [%d]", - sptr->dcb->remote, sptr->serverid))); + MXS_ERROR("gwbuf memory allocation in " + "DISCONNECT ALL for [%s], server_id [%d]", + sptr->dcb->remote, sptr->serverid); spinlock_release(&router->lock); @@ -2701,9 +2661,9 @@ blr_slave_disconnect_all(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave) return 1; } - LOGIF(LM, (skygw_log_write(LOGFILE_MESSAGE, "%s: Slave %s, server id %d, disconnected by %s@%s", - router->service->name, - sptr->dcb->remote, sptr->serverid, slave->dcb->user, slave->dcb->remote))); + MXS_NOTICE("%s: Slave %s, server id %d, disconnected by %s@%s", + router->service->name, + sptr->dcb->remote, sptr->serverid, slave->dcb->user, slave->dcb->remote); ptr = GWBUF_DATA(pkt); encode_value(ptr, len - 4, 24); // Add length of data packet @@ -2870,15 +2830,14 @@ blr_stop_slave(ROUTER_INSTANCE* router, ROUTER_SLAVE* slave) spinlock_release(&router->lock); - LOGIF(LM, (skygw_log_write( - LOGFILE_MESSAGE, - "%s: STOP SLAVE executed by %s@%s. Disconnecting from master %s:%d, read up to log %s, pos %lu, transaction safe pos %lu", - router->service->name, - slave->dcb->user, - slave->dcb->remote, - router->service->dbref->server->name, - router->service->dbref->server->port, - router->binlog_name, router->current_pos, router->binlog_position))); + MXS_NOTICE("%s: STOP SLAVE executed by %s@%s. Disconnecting from master %s:%d, " + "read up to log %s, pos %lu, transaction safe pos %lu", + router->service->name, + slave->dcb->user, + slave->dcb->remote, + router->service->dbref->server->name, + router->service->dbref->server->port, + router->binlog_name, router->current_pos, router->binlog_position); if (router->trx_safe && router->pending_transaction) { char message[BINLOG_ERROR_MSG_LEN+1] = ""; @@ -2943,16 +2902,14 @@ blr_start_slave(ROUTER_INSTANCE* router, ROUTER_SLAVE* slave) truncate(file, router->last_safe_pos); /* Log it */ - LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, - "Warning: a transaction is still opened at pos %lu" - " File %s will be truncated. " - "Next binlog file is %s at pos %d, " - "START SLAVE is required again.", - router->last_safe_pos, - router->prevbinlog, - router->binlog_name, - 4))); + MXS_WARNING("A transaction is still opened at pos %lu" + " File %s will be truncated. " + "Next binlog file is %s at pos %d, " + "START SLAVE is required again.", + router->last_safe_pos, + router->prevbinlog, + router->binlog_name, + 4); spinlock_acquire(&router->lock); @@ -2983,16 +2940,15 @@ blr_start_slave(ROUTER_INSTANCE* router, ROUTER_SLAVE* slave) blr_start_master(router); - LOGIF(LM, (skygw_log_write( - LOGFILE_MESSAGE, - "%s: START SLAVE executed by %s@%s. Trying connection to master %s:%d, binlog %s, pos %lu, transaction safe pos %lu", - router->service->name, - slave->dcb->user, - slave->dcb->remote, - router->service->dbref->server->name, - router->service->dbref->server->port, - router->binlog_name, - router->current_pos, router->binlog_position))); + MXS_NOTICE("%s: START SLAVE executed by %s@%s. Trying connection to master %s:%d, " + "binlog %s, pos %lu, transaction safe pos %lu", + router->service->name, + slave->dcb->user, + slave->dcb->remote, + router->service->dbref->server->name, + router->service->dbref->server->port, + router->binlog_name, + router->current_pos, router->binlog_position); /* File path for router cached authentication data */ strcpy(path, router->binlogdir); @@ -3005,10 +2961,8 @@ blr_start_slave(ROUTER_INSTANCE* router, ROUTER_SLAVE* slave) if (loaded < 0) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Unable to load users for service %s", - router->service->name))); + MXS_ERROR("Unable to load users for service %s", + router->service->name); } else { /* update cached data */ if (loaded > 0) @@ -3096,7 +3050,7 @@ int blr_handle_change_master(ROUTER_INSTANCE* router, char *command, char *error if ((cmd_string = strdup(cmd_ptr + 2)) == NULL) { strncpy(error, "error allocating memory for statement parsing", BINLOG_ERROR_MSG_LEN); - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, "%s: %s", router->service->name, error))); + MXS_ERROR("%s: %s", router->service->name, error); return -1; } @@ -3109,7 +3063,7 @@ int blr_handle_change_master(ROUTER_INSTANCE* router, char *command, char *error free(cmd_string); if (parse_ret) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, "%s CHANGE MASTER TO parse error: %s", router->service->name, error))); + MXS_ERROR("%s CHANGE MASTER TO parse error: %s", router->service->name, error); blr_master_free_parsed_options(&change_master); @@ -3121,7 +3075,7 @@ int blr_handle_change_master(ROUTER_INSTANCE* router, char *command, char *error if (!current_master) { strncpy(error, "error allocating memory for blr_master_get_config", BINLOG_ERROR_MSG_LEN); - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, "%s: %s", router->service->name, error))); + MXS_ERROR("%s: %s", router->service->name, error); blr_master_free_parsed_options(&change_master); @@ -3170,7 +3124,7 @@ int blr_handle_change_master(ROUTER_INSTANCE* router, char *command, char *error strcpy(error, "Router is not configured for master connection, MASTER_LOG_FILE is required"); } - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, "%s: %s", router->service->name, error))); + MXS_ERROR("%s: %s", router->service->name, error); /* restore previous master_host and master_port */ blr_master_restore_config(router, current_master); @@ -3191,7 +3145,7 @@ int blr_handle_change_master(ROUTER_INSTANCE* router, char *command, char *error /* if errors returned */ if (strlen(error)) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, "%s: %s", router->service->name, error))); + MXS_ERROR("%s: %s", router->service->name, error); /* restore previous master_host and master_port */ blr_master_restore_config(router, current_master); @@ -3242,7 +3196,7 @@ int blr_handle_change_master(ROUTER_INSTANCE* router, char *command, char *error /* return an error or set new binlog name at pos 4 */ if (return_error) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, "%s: %s", router->service->name, error))); + MXS_ERROR("%s: %s", router->service->name, error); /* restore previous master_host and master_port */ blr_master_restore_config(router, current_master); @@ -3269,9 +3223,9 @@ int blr_handle_change_master(ROUTER_INSTANCE* router, char *command, char *error close(router->binlog_fd); router->binlog_fd = -1; - LOGIF(LT, (skygw_log_write(LOGFILE_TRACE, "%s: New MASTER_LOG_FILE is [%s]", - router->service->name, - router->binlog_name))); + MXS_INFO("%s: New MASTER_LOG_FILE is [%s]", + router->service->name, + router->binlog_name); } } else { /** @@ -3305,7 +3259,7 @@ int blr_handle_change_master(ROUTER_INSTANCE* router, char *command, char *error /* log error and return */ if (return_error) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, "%s: %s", router->service->name, error))); + MXS_ERROR("%s: %s", router->service->name, error); /* restore previous master_host and master_port */ blr_master_restore_config(router, current_master); @@ -3329,27 +3283,31 @@ int blr_handle_change_master(ROUTER_INSTANCE* router, char *command, char *error memset(router->binlog_name, '\0', sizeof(router->binlog_name)); strncpy(router->binlog_name, master_logfile, BINLOG_FNAMELEN); - LOGIF(LT, (skygw_log_write(LOGFILE_TRACE, "%s: New MASTER_LOG_FILE is [%s]", - router->service->name, - router->binlog_name))); + MXS_INFO("%s: New MASTER_LOG_FILE is [%s]", + router->service->name, + router->binlog_name); } - LOGIF(LT, (skygw_log_write(LOGFILE_TRACE, "%s: New MASTER_LOG_POS is [%lu]", - router->service->name, - router->current_pos))); + MXS_INFO("%s: New MASTER_LOG_POS is [%lu]", + router->service->name, + router->current_pos); } } /* Log config changes (without passwords) */ - LOGIF(LM, (skygw_log_write(LOGFILE_MESSAGE, "%s: 'CHANGE MASTER TO executed'. Previous state MASTER_HOST='%s', MASTER_PORT=%i, MASTER_LOG_FILE='%s', MASTER_LOG_POS=%lu, MASTER_USER='%s'. New state is MASTER_HOST='%s', MASTER_PORT=%i, MASTER_LOG_FILE='%s', MASTER_LOG_POS=%lu, MASTER_USER='%s'", - router->service->name, - current_master->host,current_master->port, current_master->logfile, current_master->pos, current_master->user, - router->service->dbref->server->name, - router->service->dbref->server->port, - router->binlog_name, - router->current_pos, - router->user))); + MXS_NOTICE("%s: 'CHANGE MASTER TO executed'. Previous state " + "MASTER_HOST='%s', MASTER_PORT=%i, MASTER_LOG_FILE='%s', " + "MASTER_LOG_POS=%lu, MASTER_USER='%s'. New state is MASTER_HOST='%s', " + "MASTER_PORT=%i, MASTER_LOG_FILE='%s', MASTER_LOG_POS=%lu, MASTER_USER='%s'", + router->service->name, + current_master->host, current_master->port, current_master->logfile, + current_master->pos, current_master->user, + router->service->dbref->server->name, + router->service->dbref->server->port, + router->binlog_name, + router->current_pos, + router->user); blr_master_free_config(current_master); @@ -3389,9 +3347,9 @@ blr_set_master_hostname(ROUTER_INSTANCE *router, char *hostname) { server_update_address(router->service->dbref->server, ptr); - LOGIF(LT, (skygw_log_write(LOGFILE_TRACE, "%s: New MASTER_HOST is [%s]", - router->service->name, - router->service->dbref->server->name))); + MXS_INFO("%s: New MASTER_HOST is [%s]", + router->service->name, + router->service->dbref->server->name); return 1; } @@ -3418,9 +3376,9 @@ blr_set_master_port(ROUTER_INSTANCE *router, char *port) { if (new_port) { server_update_port(router->service->dbref->server, new_port); - LOGIF(LT, (skygw_log_write(LOGFILE_TRACE, "%s: New MASTER_PORT is [%i]", - router->service->name, - router->service->dbref->server->port))); + MXS_INFO("%s: New MASTER_PORT is [%i]", + router->service->name, + router->service->dbref->server->port); return 1; } @@ -3654,9 +3612,9 @@ blr_set_master_user(ROUTER_INSTANCE *router, char *user) { } router->user = strdup(ptr); - LOGIF(LT, (skygw_log_write(LOGFILE_TRACE, "%s: New MASTER_USER is [%s]", - router->service->name, - router->user))); + MXS_INFO("%s: New MASTER_USER is [%s]", + router->service->name, + router->user); return 1; } @@ -4088,9 +4046,8 @@ char *sep = " ,="; return -1; } else if (strcasecmp(word, "LIKE") == 0) { if ((word = strtok_r(NULL, sep, &brkb)) == NULL) { - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "%s: Missing LIKE clause in SHOW [GLOBAL] VARIABLES.", - router->service->name))); + MXS_ERROR("%s: Missing LIKE clause in SHOW [GLOBAL] VARIABLES.", + router->service->name); return -1; } else if (strcasecmp(word, "'SERVER_ID'") == 0) { if (router->set_master_server_id) { @@ -4265,9 +4222,8 @@ char *sep = " ,="; return -1; } else if (strcasecmp(word, "LIKE") == 0) { if ((word = strtok_r(NULL, sep, &brkb)) == NULL) { - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "%s: Missing LIKE clause in SHOW [GLOBAL] STATUS.", - router->service->name))); + MXS_ERROR("%s: Missing LIKE clause in SHOW [GLOBAL] STATUS.", + router->service->name); return -1; } else if (strcasecmp(word, "'Uptime'") == 0) { char uptime[41]=""; @@ -4444,11 +4400,10 @@ time_t t_now = time(0); /* skip servers with state = 0 */ if ( (sptr->state == BLRS_DUMPING) && (sptr->heartbeat > 0) && ((t_now + 1 - sptr->lastReply) >= sptr->heartbeat) ) { - LOGIF(LM, (skygw_log_write( - LOGFILE_MESSAGE, "Sending Heartbeat to slave server-id %d in State %d, cstate %d. " - "Heartbeat interval is %d, last event time is %lu", - sptr->serverid, sptr->state, sptr->cstate, sptr->heartbeat, - (unsigned long)sptr->lastReply))); + MXS_NOTICE("Sending Heartbeat to slave server-id %d in State %d, cstate %d. " + "Heartbeat interval is %d, last event time is %lu", + sptr->serverid, sptr->state, sptr->cstate, sptr->heartbeat, + (unsigned long)sptr->lastReply); blr_slave_send_heartbeat(router, sptr); diff --git a/server/modules/routing/binlog/maxbinlogcheck.c b/server/modules/routing/binlog/maxbinlogcheck.c index 6706c0b65..f6d03ee13 100644 --- a/server/modules/routing/binlog/maxbinlogcheck.c +++ b/server/modules/routing/binlog/maxbinlogcheck.c @@ -129,8 +129,7 @@ int main(int argc, char **argv) { mxs_log_set_priority_enabled(LOG_DEBUG, debug_out); if ((inst = calloc(1, sizeof(ROUTER_INSTANCE))) == NULL) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Error: Memory allocation failed for ROUTER_INSTANCE"))); + MXS_ERROR("Memory allocation failed for ROUTER_INSTANCE"); mxs_log_flush_sync(); mxs_log_finish(); @@ -152,9 +151,8 @@ int main(int argc, char **argv) { if (fd == -1) { - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "Failed to open binlog file %s: %s", - path, strerror(errno)))); + MXS_ERROR("Failed to open binlog file %s: %s", + path, strerror(errno)); mxs_log_flush_sync(); mxs_log_finish(); @@ -175,14 +173,12 @@ int main(int argc, char **argv) { else strncpy(inst->binlog_name, path, BINLOG_FNAMELEN); - LOGIF(LM, (skygw_log_write_flush(LOGFILE_MESSAGE, - "maxbinlogcheck %s", binlog_check_version))); + MXS_NOTICE("maxbinlogcheck %s", binlog_check_version); if (fstat(inst->binlog_fd, &statb) == 0) filelen = statb.st_size; - LOGIF(LM, (skygw_log_write_flush(LOGFILE_MESSAGE, - "Checking %s (%s), size %lu bytes", path, inst->binlog_name, filelen))); + MXS_NOTICE("Checking %s (%s), size %lu bytes", path, inst->binlog_name, filelen); /* read binary log */ ret = blr_read_events_all_events(inst, fix_file, debug_out); @@ -191,8 +187,7 @@ int main(int argc, char **argv) { mxs_log_flush_sync(); - LOGIF(LM, (skygw_log_write_flush(LOGFILE_MESSAGE, - "Check retcode: %i, Binlog Pos = %lu", ret, inst->binlog_position))); + MXS_NOTICE("Check retcode: %i, Binlog Pos = %lu", ret, inst->binlog_position); mxs_log_flush_sync(); mxs_log_finish(); From 3f8739ebfdde2ee2b10e7b0d71bd09b31a842aa4 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Wed, 18 Nov 2015 13:23:16 +0200 Subject: [PATCH 04/21] LOGIFs removed from binlog test. --- server/modules/routing/binlog/test/testbinlog.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/server/modules/routing/binlog/test/testbinlog.c b/server/modules/routing/binlog/test/testbinlog.c index 257994351..5ce86066c 100644 --- a/server/modules/routing/binlog/test/testbinlog.c +++ b/server/modules/routing/binlog/test/testbinlog.c @@ -124,8 +124,7 @@ int main(int argc, char **argv) { } if ((inst = calloc(1, sizeof(ROUTER_INSTANCE))) == NULL) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Error: Memory allocation FAILED for ROUTER_INSTANCE"))); + MXS_ERROR("Memory allocation FAILED for ROUTER_INSTANCE"); mxs_log_flush_sync(); mxs_log_finish(); @@ -137,7 +136,7 @@ int main(int argc, char **argv) { inst->user = service->credentials.name; inst->password = service->credentials.authdata; - LOGIF(LM, (skygw_log_write_flush(LOGFILE_MESSAGE, "testbinlog v1.0"))); + MXS_NOTICE("testbinlog v1.0"); if (inst->fileroot == NULL) inst->fileroot = strdup(BINLOG_NAME_ROOT); From 7d9324ee12d651d31f0b87071c661c522cea8103 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Wed, 18 Nov 2015 10:33:58 +0200 Subject: [PATCH 05/21] Formatted regexfilter Formatted regexfilter according to the style guide and removed trailing whitespace. --- server/modules/filter/regexfilter.c | 431 +++++++++++++++------------- 1 file changed, 226 insertions(+), 205 deletions(-) diff --git a/server/modules/filter/regexfilter.c b/server/modules/filter/regexfilter.c index ab35c0af2..05ffea41a 100644 --- a/server/modules/filter/regexfilter.c +++ b/server/modules/filter/regexfilter.c @@ -15,6 +15,7 @@ * * Copyright MariaDB Corporation Ab 2014 */ + #define PCRE2_CODE_UNIT_WIDTH 8 #include #include @@ -33,43 +34,46 @@ * * A simple regular expression query rewrite filter. * Two parameters should be defined in the filter configuration - * match= - * replace= + * match= + * replace= * Two optional parameters - * source= - * user= + * source= + * user= * - * Date Who Description - * 19/06/2014 Mark Riddoch Addition of source and user parameters + * Date Who Description + * 19/06/2014 Mark Riddoch Addition of source and user parameters * @endverbatim */ -MODULE_INFO info = { - MODULE_API_FILTER, - MODULE_GA, - FILTER_VERSION, - "A query rewrite filter that uses regular expressions to rewite queries" +MODULE_INFO info = +{ + MODULE_API_FILTER, + MODULE_GA, + FILTER_VERSION, + "A query rewrite filter that uses regular expressions to rewite queries" }; static char *version_str = "V1.1.0"; -static FILTER *createInstance(char **options, FILTER_PARAMETER **params); -static void *newSession(FILTER *instance, SESSION *session); -static void closeSession(FILTER *instance, void *session); -static void freeSession(FILTER *instance, void *session); -static void setDownstream(FILTER *instance, void *fsession, DOWNSTREAM *downstream); -static int routeQuery(FILTER *instance, void *fsession, GWBUF *queue); -static void diagnostic(FILTER *instance, void *fsession, DCB *dcb); +static FILTER *createInstance(char **options, FILTER_PARAMETER **params); +static void *newSession(FILTER *instance, SESSION *session); +static void closeSession(FILTER *instance, void *session); +static void freeSession(FILTER *instance, void *session); +static void setDownstream(FILTER *instance, void *fsession, DOWNSTREAM *downstream); +static int routeQuery(FILTER *instance, void *fsession, GWBUF *queue); +static void diagnostic(FILTER *instance, void *fsession, DCB *dcb); -static char *regex_replace(const char *sql, pcre2_code *re, pcre2_match_data *study, const char *replace); +static char *regex_replace(const char *sql, pcre2_code *re, pcre2_match_data *study, + const char *replace); -static FILTER_OBJECT MyObject = { +static FILTER_OBJECT MyObject = +{ createInstance, newSession, closeSession, freeSession, setDownstream, - NULL, // No Upstream requirement + NULL, // No Upstream requirement routeQuery, NULL, diagnostic, @@ -102,7 +106,7 @@ typedef struct int active; /* Is filter active */ } REGEX_SESSION; -void log_match(REGEX_INSTANCE* inst,char* re, char* old, char* new); +void log_match(REGEX_INSTANCE* inst, char* re, char* old, char* new); void log_nomatch(REGEX_INSTANCE* inst, char* re, char* old); /** @@ -113,7 +117,7 @@ void log_nomatch(REGEX_INSTANCE* inst, char* re, char* old); char * version() { - return version_str; + return version_str; } /** @@ -136,7 +140,7 @@ ModuleInit() FILTER_OBJECT * GetModuleObject() { - return &MyObject; + return &MyObject; } /** @@ -168,13 +172,13 @@ void free_instance(REGEX_INSTANCE *instance) /** * Create an instance of the filter for a particular service * within MaxScale. - * - * @param options The options for this filter - * @param params The array of name/value pair parameters for the filter + * + * @param options The options for this filter + * @param params The array of name/value pair parameters for the filter * * @return The instance data for this new instance */ -static FILTER * +static FILTER * createInstance(char **options, FILTER_PARAMETER **params) { REGEX_INSTANCE *my_instance; @@ -183,54 +187,66 @@ createInstance(char **options, FILTER_PARAMETER **params) char *logfile = NULL; const char *errmsg; - if ((my_instance = calloc(1, sizeof(REGEX_INSTANCE))) != NULL) - { - my_instance->match = NULL; - my_instance->replace = NULL; + if ((my_instance = calloc(1, sizeof(REGEX_INSTANCE))) != NULL) + { + my_instance->match = NULL; + my_instance->replace = NULL; - for (i = 0; params && params[i]; i++) - { - if (!strcmp(params[i]->name, "match")) - my_instance->match = strdup(params[i]->value); - else if (!strcmp(params[i]->name, "replace")) - my_instance->replace = strdup(params[i]->value); - else if (!strcmp(params[i]->name, "source")) - my_instance->source = strdup(params[i]->value); - else if (!strcmp(params[i]->name, "user")) - my_instance->user = strdup(params[i]->value); - else if (!strcmp(params[i]->name, "log_trace")) - my_instance->log_trace = config_truth_value(params[i]->value); - else if (!strcmp(params[i]->name, "log_file")) - { - if(logfile) - free(logfile); - logfile = strdup(params[i]->value); - } - else if (!filter_standard_parameter(params[i]->name)) - { - MXS_ERROR("regexfilter: Unexpected parameter '%s'.", - params[i]->name); - } - } + for (i = 0; params && params[i]; i++) + { + if (!strcmp(params[i]->name, "match")) + { + my_instance->match = strdup(params[i]->value); + } + else if (!strcmp(params[i]->name, "replace")) + { + my_instance->replace = strdup(params[i]->value); + } + else if (!strcmp(params[i]->name, "source")) + { + my_instance->source = strdup(params[i]->value); + } + else if (!strcmp(params[i]->name, "user")) + { + my_instance->user = strdup(params[i]->value); + } + else if (!strcmp(params[i]->name, "log_trace")) + { + my_instance->log_trace = config_truth_value(params[i]->value); + } + else if (!strcmp(params[i]->name, "log_file")) + { + if (logfile) + { + free(logfile); + } + logfile = strdup(params[i]->value); + } + else if (!filter_standard_parameter(params[i]->name)) + { + MXS_ERROR("regexfilter: Unexpected parameter '%s'.", + params[i]->name); + } + } - if (options) - { - for (i = 0; options[i]; i++) - { - if (!strcasecmp(options[i], "ignorecase")) - { - cflags |= PCRE2_CASELESS; - } - else if (!strcasecmp(options[i], "case")) - { - cflags &= ~PCRE2_CASELESS; - } - else - { - MXS_ERROR("regexfilter: unsupported option '%s'.", - options[i]); - } - } + if (options) + { + for (i = 0; options[i]; i++) + { + if (!strcasecmp(options[i], "ignorecase")) + { + cflags |= PCRE2_CASELESS; + } + else if (!strcasecmp(options[i], "case")) + { + cflags &= ~PCRE2_CASELESS; + } + else + { + MXS_ERROR("regexfilter: unsupported option '%s'.", + options[i]); + } + } } if (logfile != NULL) @@ -248,19 +264,19 @@ createInstance(char **options, FILTER_PARAMETER **params) } free(logfile); - if (my_instance->match == NULL || my_instance->replace == NULL) - { - free_instance(my_instance); - return NULL; - } + if (my_instance->match == NULL || my_instance->replace == NULL) + { + free_instance(my_instance); + return NULL; + } - if ((my_instance->re = pcre2_compile((PCRE2_SPTR)my_instance->match, + if ((my_instance->re = pcre2_compile((PCRE2_SPTR) my_instance->match, PCRE2_ZERO_TERMINATED, cflags, &errnumber, &erroffset, NULL)) == NULL) - { + { char errbuffer[1024]; pcre2_get_error_message(errnumber, (PCRE2_UCHAR*) & errbuffer, sizeof(errbuffer)); MXS_ERROR("regexfilter: Compiling regular expression '%s' failed at %lu: %s", @@ -269,62 +285,64 @@ createInstance(char **options, FILTER_PARAMETER **params) return NULL; } - if((my_instance->match_data = pcre2_match_data_create_from_pattern( - my_instance->re, NULL)) == NULL) + if ((my_instance->match_data = + pcre2_match_data_create_from_pattern(my_instance->re, NULL)) == NULL) { MXS_ERROR("regexfilter: Failure to create PCRE2 matching data. " "This is most likely caused by a lack of available memory."); free_instance(my_instance); return NULL; } - } - return (FILTER *)my_instance; + } + return(FILTER *) my_instance; } /** * Associate a new session with this instance of the filter. * - * @param instance The filter instance data - * @param session The session itself + * @param instance The filter instance data + * @param session The session itself * @return Session specific data for this session */ -static void * +static void * newSession(FILTER *instance, SESSION *session) { -REGEX_INSTANCE *my_instance = (REGEX_INSTANCE *)instance; -REGEX_SESSION *my_session; -char *remote, *user; + REGEX_INSTANCE *my_instance = (REGEX_INSTANCE *) instance; + REGEX_SESSION *my_session; + char *remote, *user; - if ((my_session = calloc(1, sizeof(REGEX_SESSION))) != NULL) - { - my_session->no_change = 0; - my_session->replacements = 0; - my_session->active = 1; - if (my_instance->source - && (remote = session_get_remote(session)) != NULL) - { - if (strcmp(remote, my_instance->source)) - my_session->active = 0; - } + if ((my_session = calloc(1, sizeof(REGEX_SESSION))) != NULL) + { + my_session->no_change = 0; + my_session->replacements = 0; + my_session->active = 1; + if (my_instance->source + && (remote = session_get_remote(session)) != NULL) + { + if (strcmp(remote, my_instance->source)) + { + my_session->active = 0; + } + } - if (my_instance->user && (user = session_getUser(session)) - && strcmp(user, my_instance->user)) - { - my_session->active = 0; - } - } + if (my_instance->user && (user = session_getUser(session)) + && strcmp(user, my_instance->user)) + { + my_session->active = 0; + } + } - return my_session; + return my_session; } /** * Close a session with the filter, this is the mechanism * by which a filter may cleanup data structure etc. * - * @param instance The filter instance data - * @param session The session being closed + * @param instance The filter instance data + * @param session The session being closed */ -static void +static void closeSession(FILTER *instance, void *session) { } @@ -332,29 +350,28 @@ closeSession(FILTER *instance, void *session) /** * Free the memory associated with this filter session. * - * @param instance The filter instance data - * @param session The session being closed + * @param instance The filter instance data + * @param session The session being closed */ static void freeSession(FILTER *instance, void *session) { - free(session); - return; + free(session); + return; } /** * Set the downstream component for this filter. * - * @param instance The filter instance data - * @param session The session being closed - * @param downstream The downstream filter or router + * @param instance The filter instance data + * @param session The session being closed + * @param downstream The downstream filter or router */ static void setDownstream(FILTER *instance, void *session, DOWNSTREAM *downstream) { -REGEX_SESSION *my_session = (REGEX_SESSION *)session; - - my_session->down = *downstream; + REGEX_SESSION *my_session = (REGEX_SESSION *) session; + my_session->down = *downstream; } /** @@ -363,52 +380,52 @@ REGEX_SESSION *my_session = (REGEX_SESSION *)session; * query shoudl normally be passed to the downstream component * (filter or router) in the filter chain. * - * @param instance The filter instance data - * @param session The filter session - * @param queue The query data + * @param instance The filter instance data + * @param session The filter session + * @param queue The query data */ -static int +static int routeQuery(FILTER *instance, void *session, GWBUF *queue) { -REGEX_INSTANCE *my_instance = (REGEX_INSTANCE *)instance; -REGEX_SESSION *my_session = (REGEX_SESSION *)session; -char *sql, *newsql; + REGEX_INSTANCE *my_instance = (REGEX_INSTANCE *) instance; + REGEX_SESSION *my_session = (REGEX_SESSION *) session; + char *sql, *newsql; - if (modutil_is_SQL(queue)) - { - if (queue->next != NULL) - { - queue = gwbuf_make_contiguous(queue); - } - if ((sql = modutil_get_SQL(queue)) != NULL) - { - newsql = regex_replace(sql, - my_instance->re, - my_instance->match_data, - my_instance->replace); - if (newsql) - { - queue = modutil_replace_SQL(queue, newsql); - queue = gwbuf_make_contiguous(queue); - spinlock_acquire(&my_session->lock); - log_match(my_instance,my_instance->match,sql,newsql); - spinlock_release(&my_session->lock); - free(newsql); - my_session->replacements++; - } - else - { - spinlock_acquire(&my_session->lock); - log_nomatch(my_instance,my_instance->match,sql); - spinlock_release(&my_session->lock); - my_session->no_change++; - } - free(sql); - } - - } - return my_session->down.routeQuery(my_session->down.instance, - my_session->down.session, queue); + if (modutil_is_SQL(queue)) + { + if (queue->next != NULL) + { + queue = gwbuf_make_contiguous(queue); + } + if ((sql = modutil_get_SQL(queue)) != NULL) + { + newsql = regex_replace(sql, + my_instance->re, + my_instance->match_data, + my_instance->replace); + if (newsql) + { + queue = modutil_replace_SQL(queue, newsql); + queue = gwbuf_make_contiguous(queue); + spinlock_acquire(&my_session->lock); + log_match(my_instance, my_instance->match, sql, newsql); + spinlock_release(&my_session->lock); + free(newsql); + my_session->replacements++; + } + else + { + spinlock_acquire(&my_session->lock); + log_nomatch(my_instance, my_instance->match, sql); + spinlock_release(&my_session->lock); + my_session->no_change++; + } + free(sql); + } + + } + return my_session->down.routeQuery(my_session->down.instance, + my_session->down.session, queue); } /** @@ -418,43 +435,47 @@ char *sql, *newsql; * instance as a whole, otherwise print diagnostics for the * particular session. * - * @param instance The filter instance - * @param fsession Filter session, may be NULL - * @param dcb The DCB for diagnostic output + * @param instance The filter instance + * @param fsession Filter session, may be NULL + * @param dcb The DCB for diagnostic output */ -static void +static void diagnostic(FILTER *instance, void *fsession, DCB *dcb) { -REGEX_INSTANCE *my_instance = (REGEX_INSTANCE *)instance; -REGEX_SESSION *my_session = (REGEX_SESSION *)fsession; + REGEX_INSTANCE *my_instance = (REGEX_INSTANCE *) instance; + REGEX_SESSION *my_session = (REGEX_SESSION *) fsession; - dcb_printf(dcb, "\t\tSearch and replace: s/%s/%s/\n", - my_instance->match, my_instance->replace); - if (my_session) - { - dcb_printf(dcb, "\t\tNo. of queries unaltered by filter: %d\n", - my_session->no_change); - dcb_printf(dcb, "\t\tNo. of queries altered by filter: %d\n", - my_session->replacements); - } - if (my_instance->source) - dcb_printf(dcb, - "\t\tReplacement limited to connections from %s\n", - my_instance->source); - if (my_instance->user) - dcb_printf(dcb, - "\t\tReplacement limit to user %s\n", - my_instance->user); + dcb_printf(dcb, "\t\tSearch and replace: s/%s/%s/\n", + my_instance->match, my_instance->replace); + if (my_session) + { + dcb_printf(dcb, "\t\tNo. of queries unaltered by filter: %d\n", + my_session->no_change); + dcb_printf(dcb, "\t\tNo. of queries altered by filter: %d\n", + my_session->replacements); + } + if (my_instance->source) + { + dcb_printf(dcb, + "\t\tReplacement limited to connections from %s\n", + my_instance->source); + } + if (my_instance->user) + { + dcb_printf(dcb, + "\t\tReplacement limit to user %s\n", + my_instance->user); + } } /** * Perform a regular expression match and substitution on the SQL * - * @param sql The original SQL text - * @param re The compiled regular expression + * @param sql The original SQL text + * @param re The compiled regular expression * @param match_data The PCRE2 matching data buffer - * @param replace The replacement text - * @return The replaced text or NULL if no replacement was done. + * @param replace The replacement text + * @return The replaced text or NULL if no replacement was done. */ static char * regex_replace(const char *sql, pcre2_code *re, pcre2_match_data *match_data, const char *replace) @@ -463,16 +484,16 @@ regex_replace(const char *sql, pcre2_code *re, pcre2_match_data *match_data, con size_t result_size; /** This should never fail with rc == 0 because we used pcre2_match_data_create_from_pattern() */ - if (pcre2_match(re, (PCRE2_SPTR)sql, PCRE2_ZERO_TERMINATED, 0, 0, match_data, NULL)) + if (pcre2_match(re, (PCRE2_SPTR) sql, PCRE2_ZERO_TERMINATED, 0, 0, match_data, NULL)) { result_size = strlen(sql) + strlen(replace); result = malloc(result_size); while (result && - pcre2_substitute(re, (PCRE2_SPTR)sql, PCRE2_ZERO_TERMINATED, 0, + pcre2_substitute(re, (PCRE2_SPTR) sql, PCRE2_ZERO_TERMINATED, 0, PCRE2_SUBSTITUTE_GLOBAL, match_data, NULL, - (PCRE2_SPTR)replace, PCRE2_ZERO_TERMINATED, - (PCRE2_UCHAR*)result, (PCRE2_SIZE*)&result_size) == PCRE2_ERROR_NOMEMORY) + (PCRE2_SPTR) replace, PCRE2_ZERO_TERMINATED, + (PCRE2_UCHAR*) result, (PCRE2_SIZE*) & result_size) == PCRE2_ERROR_NOMEMORY) { char *tmp; if ((tmp = realloc(result, (result_size *= 1.5))) == NULL) @@ -496,14 +517,14 @@ regex_replace(const char *sql, pcre2_code *re, pcre2_match_data *match_data, con */ void log_match(REGEX_INSTANCE* inst, char* re, char* old, char* new) { - if(inst->logfile) + if (inst->logfile) { - fprintf(inst->logfile,"Matched %s: [%s] -> [%s]\n",re,old,new); - fflush(inst->logfile); + fprintf(inst->logfile, "Matched %s: [%s] -> [%s]\n", re, old, new); + fflush(inst->logfile); } - if(inst->log_trace) + if (inst->log_trace) { - MXS_INFO("Match %s: [%s] -> [%s]",re,old,new); + MXS_INFO("Match %s: [%s] -> [%s]", re, old, new); } } @@ -515,13 +536,13 @@ void log_match(REGEX_INSTANCE* inst, char* re, char* old, char* new) */ void log_nomatch(REGEX_INSTANCE* inst, char* re, char* old) { - if(inst->logfile) + if (inst->logfile) { - fprintf(inst->logfile,"No match %s: [%s]\n",re,old); - fflush(inst->logfile); + fprintf(inst->logfile, "No match %s: [%s]\n", re, old); + fflush(inst->logfile); } - if(inst->log_trace) + if (inst->log_trace) { - MXS_INFO("No match %s: [%s]",re,old); + MXS_INFO("No match %s: [%s]", re, old); } } From e24504c4270029fe0726f8156bb126664dc7036e Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Wed, 18 Nov 2015 13:45:10 +0200 Subject: [PATCH 06/21] Formatted topfilter Topfilter is now formatted according to the style guide. --- server/modules/filter/topfilter.c | 758 ++++++++++++++++-------------- 1 file changed, 401 insertions(+), 357 deletions(-) diff --git a/server/modules/filter/topfilter.c b/server/modules/filter/topfilter.c index 457375a83..0949e9f15 100644 --- a/server/modules/filter/topfilter.c +++ b/server/modules/filter/topfilter.c @@ -31,11 +31,12 @@ * file to which the queries are logged. A serial number is appended to this * name in order that each session logs to a different file. * - * Date Who Description - * 18/06/2014 Mark Riddoch Addition of source and user filters + * Date Who Description + * 18/06/2014 Mark Riddoch Addition of source and user filters * * @endverbatim */ + #include #include #include @@ -49,11 +50,12 @@ #include #include -MODULE_INFO info = { - MODULE_API_FILTER, - MODULE_GA, - FILTER_VERSION, - "A top N query logging filter" +MODULE_INFO info = +{ + MODULE_API_FILTER, + MODULE_GA, + FILTER_VERSION, + "A top N query logging filter" }; static char *version_str = "V1.0.1"; @@ -61,18 +63,19 @@ static char *version_str = "V1.0.1"; /* * The filter entry points */ -static FILTER *createInstance(char **options, FILTER_PARAMETER **); -static void *newSession(FILTER *instance, SESSION *session); -static void closeSession(FILTER *instance, void *session); -static void freeSession(FILTER *instance, void *session); -static void setDownstream(FILTER *instance, void *fsession, DOWNSTREAM *downstream); -static void setUpstream(FILTER *instance, void *fsession, UPSTREAM *upstream); -static int routeQuery(FILTER *instance, void *fsession, GWBUF *queue); -static int clientReply(FILTER *instance, void *fsession, GWBUF *queue); -static void diagnostic(FILTER *instance, void *fsession, DCB *dcb); +static FILTER *createInstance(char **options, FILTER_PARAMETER **); +static void *newSession(FILTER *instance, SESSION *session); +static void closeSession(FILTER *instance, void *session); +static void freeSession(FILTER *instance, void *session); +static void setDownstream(FILTER *instance, void *fsession, DOWNSTREAM *downstream); +static void setUpstream(FILTER *instance, void *fsession, UPSTREAM *upstream); +static int routeQuery(FILTER *instance, void *fsession, GWBUF *queue); +static int clientReply(FILTER *instance, void *fsession, GWBUF *queue); +static void diagnostic(FILTER *instance, void *fsession, DCB *dcb); -static FILTER_OBJECT MyObject = { +static FILTER_OBJECT MyObject = +{ createInstance, newSession, closeSession, @@ -92,24 +95,26 @@ static FILTER_OBJECT MyObject = { * To this base a session number is attached such that each session will * have a unique name. */ -typedef struct { - int sessions; /* Session count */ - int topN; /* Number of queries to store */ - char *filebase; /* Base of fielname to log into */ - char *source; /* The source of the client connection */ - char *user; /* A user name to filter on */ - char *match; /* Optional text to match against */ - regex_t re; /* Compiled regex text */ - char *exclude; /* Optional text to match against for exclusion */ - regex_t exre; /* Compiled regex nomatch text */ +typedef struct +{ + int sessions; /* Session count */ + int topN; /* Number of queries to store */ + char *filebase; /* Base of fielname to log into */ + char *source; /* The source of the client connection */ + char *user; /* A user name to filter on */ + char *match; /* Optional text to match against */ + regex_t re; /* Compiled regex text */ + char *exclude; /* Optional text to match against for exclusion */ + regex_t exre; /* Compiled regex nomatch text */ } TOPN_INSTANCE; /** * Structure to hold the Top N queries */ -typedef struct topnq { - struct timeval duration; - char *sql; +typedef struct topnq +{ + struct timeval duration; + char *sql; } TOPNQ; /** @@ -120,21 +125,22 @@ typedef struct topnq { * * It also holds the file descriptor to which queries are written. */ -typedef struct { - DOWNSTREAM down; - UPSTREAM up; - int active; - char *clientHost; - char *userName; - char *filename; - int fd; - struct timeval start; - char *current; - TOPNQ **top; - int n_statements; - struct timeval total; - struct timeval connect; - struct timeval disconnect; +typedef struct +{ + DOWNSTREAM down; + UPSTREAM up; + int active; + char *clientHost; + char *userName; + char *filename; + int fd; + struct timeval start; + char *current; + TOPNQ **top; + int n_statements; + struct timeval total; + struct timeval connect; + struct timeval disconnect; } TOPN_SESSION; /** @@ -145,7 +151,7 @@ typedef struct { char * version() { - return version_str; + return version_str; } /** @@ -168,95 +174,101 @@ ModuleInit() FILTER_OBJECT * GetModuleObject() { - return &MyObject; + return &MyObject; } /** * Create an instance of the filter for a particular service * within MaxScale. - * - * @param options The options for this filter - * @param params The array of name/value pair parameters for the filter + * + * @param options The options for this filter + * @param params The array of name/value pair parameters for the filter * * @return The instance data for this new instance */ -static FILTER * +static FILTER * createInstance(char **options, FILTER_PARAMETER **params) { -int i; -TOPN_INSTANCE *my_instance; + int i; + TOPN_INSTANCE *my_instance; - if ((my_instance = calloc(1, sizeof(TOPN_INSTANCE))) != NULL) - { - my_instance->topN = 10; - my_instance->match = NULL; - my_instance->exclude = NULL; - my_instance->source = NULL; - my_instance->user = NULL; - my_instance->filebase = strdup("top"); - for (i = 0; params && params[i]; i++) - { - if (!strcmp(params[i]->name, "count")) - my_instance->topN = atoi(params[i]->value); - else if (!strcmp(params[i]->name, "filebase")) - { - free(my_instance->filebase); - my_instance->filebase = strdup(params[i]->value); - } - else if (!strcmp(params[i]->name, "match")) - { - my_instance->match = strdup(params[i]->value); - } - else if (!strcmp(params[i]->name, "exclude")) - { - my_instance->exclude = strdup(params[i]->value); - } - else if (!strcmp(params[i]->name, "source")) - my_instance->source = strdup(params[i]->value); - else if (!strcmp(params[i]->name, "user")) - my_instance->user = strdup(params[i]->value); - else if (!filter_standard_parameter(params[i]->name)) - { - MXS_ERROR("topfilter: Unexpected parameter '%s'.", - params[i]->name); - } - } - if (options) - { - MXS_ERROR("topfilter: Options are not supported by this " - " filter. They will be ignored."); - } - my_instance->sessions = 0; - if (my_instance->match && - regcomp(&my_instance->re, my_instance->match, REG_ICASE)) - { - MXS_ERROR("topfilter: Invalid regular expression '%s'" - " for the match parameter.", - my_instance->match); - free(my_instance->match); - free(my_instance->source); - free(my_instance->user); - free(my_instance->filebase); - free(my_instance); - return NULL; - } - if (my_instance->exclude && - regcomp(&my_instance->exre, my_instance->exclude, - REG_ICASE)) - { - MXS_ERROR("qlafilter: Invalid regular expression '%s'" - " for the nomatch paramter.\n", - my_instance->match); - regfree(&my_instance->re); - free(my_instance->match); - free(my_instance->source); - free(my_instance->user); - free(my_instance->filebase); - free(my_instance); - return NULL; - } - } - return (FILTER *)my_instance; + if ((my_instance = calloc(1, sizeof(TOPN_INSTANCE))) != NULL) + { + my_instance->topN = 10; + my_instance->match = NULL; + my_instance->exclude = NULL; + my_instance->source = NULL; + my_instance->user = NULL; + my_instance->filebase = strdup("top"); + for (i = 0; params && params[i]; i++) + { + if (!strcmp(params[i]->name, "count")) + { + my_instance->topN = atoi(params[i]->value); + } + else if (!strcmp(params[i]->name, "filebase")) + { + free(my_instance->filebase); + my_instance->filebase = strdup(params[i]->value); + } + else if (!strcmp(params[i]->name, "match")) + { + my_instance->match = strdup(params[i]->value); + } + else if (!strcmp(params[i]->name, "exclude")) + { + my_instance->exclude = strdup(params[i]->value); + } + else if (!strcmp(params[i]->name, "source")) + { + my_instance->source = strdup(params[i]->value); + } + else if (!strcmp(params[i]->name, "user")) + { + my_instance->user = strdup(params[i]->value); + } + else if (!filter_standard_parameter(params[i]->name)) + { + MXS_ERROR("topfilter: Unexpected parameter '%s'.", + params[i]->name); + } + } + if (options) + { + MXS_ERROR("topfilter: Options are not supported by this " + " filter. They will be ignored."); + } + my_instance->sessions = 0; + if (my_instance->match && + regcomp(&my_instance->re, my_instance->match, REG_ICASE)) + { + MXS_ERROR("topfilter: Invalid regular expression '%s'" + " for the match parameter.", + my_instance->match); + free(my_instance->match); + free(my_instance->source); + free(my_instance->user); + free(my_instance->filebase); + free(my_instance); + return NULL; + } + if (my_instance->exclude && + regcomp(&my_instance->exre, my_instance->exclude, + REG_ICASE)) + { + MXS_ERROR("qlafilter: Invalid regular expression '%s'" + " for the nomatch paramter.\n", + my_instance->match); + regfree(&my_instance->re); + free(my_instance->match); + free(my_instance->source); + free(my_instance->user); + free(my_instance->filebase); + free(my_instance); + return NULL; + } + } + return(FILTER *) my_instance; } /** @@ -264,63 +276,75 @@ TOPN_INSTANCE *my_instance; * * Create the file to log to and open it. * - * @param instance The filter instance data - * @param session The session itself + * @param instance The filter instance data + * @param session The session itself * @return Session specific data for this session */ -static void * +static void * newSession(FILTER *instance, SESSION *session) { -TOPN_INSTANCE *my_instance = (TOPN_INSTANCE *)instance; -TOPN_SESSION *my_session; -int i; -char *remote, *user; + TOPN_INSTANCE *my_instance = (TOPN_INSTANCE *) instance; + TOPN_SESSION *my_session; + int i; + char *remote, *user; - if ((my_session = calloc(1, sizeof(TOPN_SESSION))) != NULL) - { - if ((my_session->filename = - (char *)malloc(strlen(my_instance->filebase) + 20)) - == NULL) - { - free(my_session); - return NULL; - } - sprintf(my_session->filename, "%s.%d", my_instance->filebase, - my_instance->sessions); - atomic_add(&my_instance->sessions,1); - my_session->top = (TOPNQ **)calloc(my_instance->topN + 1, - sizeof(TOPNQ *)); - for (i = 0; i < my_instance->topN; i++) - { - my_session->top[i] = (TOPNQ *)calloc(1, sizeof(TOPNQ)); - my_session->top[i]->sql = NULL; - } - my_session->n_statements = 0; - my_session->total.tv_sec = 0; - my_session->total.tv_usec = 0; - my_session->current = NULL; - if ((remote = session_get_remote(session)) != NULL) - my_session->clientHost = strdup(remote); - else - my_session->clientHost = NULL; - if ((user = session_getUser(session)) != NULL) - my_session->userName = strdup(user); - else - my_session->userName = NULL; - my_session->active = 1; - if (my_instance->source && my_session->clientHost && strcmp(my_session->clientHost, - my_instance->source)) - my_session->active = 0; - if (my_instance->user && my_session->userName && strcmp(my_session->userName, - my_instance->user)) - my_session->active = 0; + if ((my_session = calloc(1, sizeof(TOPN_SESSION))) != NULL) + { + if ((my_session->filename = + (char *) malloc(strlen(my_instance->filebase) + 20)) + == NULL) + { + free(my_session); + return NULL; + } + sprintf(my_session->filename, "%s.%d", my_instance->filebase, + my_instance->sessions); + atomic_add(&my_instance->sessions, 1); + my_session->top = (TOPNQ **) calloc(my_instance->topN + 1, + sizeof(TOPNQ *)); + for (i = 0; i < my_instance->topN; i++) + { + my_session->top[i] = (TOPNQ *) calloc(1, sizeof(TOPNQ)); + my_session->top[i]->sql = NULL; + } + my_session->n_statements = 0; + my_session->total.tv_sec = 0; + my_session->total.tv_usec = 0; + my_session->current = NULL; + if ((remote = session_get_remote(session)) != NULL) + { + my_session->clientHost = strdup(remote); + } + else + { + my_session->clientHost = NULL; + } + if ((user = session_getUser(session)) != NULL) + { + my_session->userName = strdup(user); + } + else + { + my_session->userName = NULL; + } + my_session->active = 1; + if (my_instance->source && my_session->clientHost && strcmp(my_session->clientHost, + my_instance->source)) + { + my_session->active = 0; + } + if (my_instance->user && my_session->userName && strcmp(my_session->userName, + my_instance->user)) + { + my_session->active = 0; + } - sprintf(my_session->filename, "%s.%d", my_instance->filebase, - my_instance->sessions); - gettimeofday(&my_session->connect, NULL); - } + sprintf(my_session->filename, "%s.%d", my_instance->filebase, + my_instance->sessions); + gettimeofday(&my_session->connect, NULL); + } - return my_session; + return my_session; } /** @@ -328,110 +352,114 @@ char *remote, *user; * by which a filter may cleanup data structure etc. * In the case of the TOPN filter we simple close the file descriptor. * - * @param instance The filter instance data - * @param session The session being closed + * @param instance The filter instance data + * @param session The session being closed */ -static void +static void closeSession(FILTER *instance, void *session) { -TOPN_INSTANCE *my_instance = (TOPN_INSTANCE *)instance; -TOPN_SESSION *my_session = (TOPN_SESSION *)session; -struct timeval diff; -int i; -FILE *fp; -int statements; + TOPN_INSTANCE *my_instance = (TOPN_INSTANCE *) instance; + TOPN_SESSION *my_session = (TOPN_SESSION *) session; + struct timeval diff; + int i; + FILE *fp; + int statements; - gettimeofday(&my_session->disconnect, NULL); - timersub((&my_session->disconnect), &(my_session->connect), &diff); - if ((fp = fopen(my_session->filename, "w")) != NULL) - { - statements = my_session->n_statements != 0?my_session->n_statements:1; + gettimeofday(&my_session->disconnect, NULL); + timersub((&my_session->disconnect), &(my_session->connect), &diff); + if ((fp = fopen(my_session->filename, "w")) != NULL) + { + statements = my_session->n_statements != 0 ? my_session->n_statements : 1; - fprintf(fp, "Top %d longest running queries in session.\n", - my_instance->topN); - fprintf(fp, "==========================================\n\n"); - fprintf(fp, "Time (sec) | Query\n"); - fprintf(fp, "-----------+-----------------------------------------------------------------\n"); - for (i = 0; i < my_instance->topN; i++) - { - if (my_session->top[i]->sql) - { - fprintf(fp, "%10.3f | %s\n", - (double)((my_session->top[i]->duration.tv_sec * 1000) - + (my_session->top[i]->duration.tv_usec / 1000)) / 1000, - my_session->top[i]->sql); - } - } - fprintf(fp, "-----------+-----------------------------------------------------------------\n"); - fprintf(fp, "\n\nSession started %s", - asctime(localtime(&my_session->connect.tv_sec))); - if (my_session->clientHost) - fprintf(fp, "Connection from %s\n", - my_session->clientHost); - if (my_session->userName) - fprintf(fp, "Username %s\n", - my_session->userName); - fprintf(fp, "\nTotal of %d statements executed.\n", - statements); - fprintf(fp, "Total statement execution time %5d.%d seconds\n", - (int)my_session->total.tv_sec, - (int)my_session->total.tv_usec / 1000); - fprintf(fp, "Average statement execution time %9.3f seconds\n", - (double)((my_session->total.tv_sec * 1000) - + (my_session->total.tv_usec / 1000)) - / (1000 * statements)); - fprintf(fp, "Total connection time %5d.%d seconds\n", - (int)diff.tv_sec, (int)diff.tv_usec / 1000); - fclose(fp); - } + fprintf(fp, "Top %d longest running queries in session.\n", + my_instance->topN); + fprintf(fp, "==========================================\n\n"); + fprintf(fp, "Time (sec) | Query\n"); + fprintf(fp, "-----------+-----------------------------------------------------------------\n"); + for (i = 0; i < my_instance->topN; i++) + { + if (my_session->top[i]->sql) + { + fprintf(fp, "%10.3f | %s\n", + (double) ((my_session->top[i]->duration.tv_sec * 1000) + + (my_session->top[i]->duration.tv_usec / 1000)) / 1000, + my_session->top[i]->sql); + } + } + fprintf(fp, "-----------+-----------------------------------------------------------------\n"); + fprintf(fp, "\n\nSession started %s", + asctime(localtime(&my_session->connect.tv_sec))); + if (my_session->clientHost) + { + fprintf(fp, "Connection from %s\n", + my_session->clientHost); + } + if (my_session->userName) + { + fprintf(fp, "Username %s\n", + my_session->userName); + } + fprintf(fp, "\nTotal of %d statements executed.\n", + statements); + fprintf(fp, "Total statement execution time %5d.%d seconds\n", + (int) my_session->total.tv_sec, + (int) my_session->total.tv_usec / 1000); + fprintf(fp, "Average statement execution time %9.3f seconds\n", + (double) ((my_session->total.tv_sec * 1000) + + (my_session->total.tv_usec / 1000)) + / (1000 * statements)); + fprintf(fp, "Total connection time %5d.%d seconds\n", + (int) diff.tv_sec, (int) diff.tv_usec / 1000); + fclose(fp); + } } /** * Free the memory associated with the session * - * @param instance The filter instance - * @param session The filter session + * @param instance The filter instance + * @param session The filter session */ static void freeSession(FILTER *instance, void *session) { -TOPN_SESSION *my_session = (TOPN_SESSION *)session; + TOPN_SESSION *my_session = (TOPN_SESSION *) session; - free(my_session->filename); - free(session); - return; + free(my_session->filename); + free(session); + return; } /** * Set the downstream filter or router to which queries will be * passed from this filter. * - * @param instance The filter instance data - * @param session The filter session - * @param downstream The downstream filter or router. + * @param instance The filter instance data + * @param session The filter session + * @param downstream The downstream filter or router. */ static void setDownstream(FILTER *instance, void *session, DOWNSTREAM *downstream) { -TOPN_SESSION *my_session = (TOPN_SESSION *)session; + TOPN_SESSION *my_session = (TOPN_SESSION *) session; - my_session->down = *downstream; + my_session->down = *downstream; } /** * Set the upstream filter or session to which results will be * passed from this filter. * - * @param instance The filter instance data - * @param session The filter session - * @param upstream The upstream filter or session. + * @param instance The filter instance data + * @param session The filter session + * @param upstream The upstream filter or session. */ static void setUpstream(FILTER *instance, void *session, UPSTREAM *upstream) { -TOPN_SESSION *my_session = (TOPN_SESSION *)session; + TOPN_SESSION *my_session = (TOPN_SESSION *) session; - my_session->up = *upstream; + my_session->up = *upstream; } /** @@ -440,104 +468,112 @@ TOPN_SESSION *my_session = (TOPN_SESSION *)session; * query should normally be passed to the downstream component * (filter or router) in the filter chain. * - * @param instance The filter instance data - * @param session The filter session - * @param queue The query data + * @param instance The filter instance data + * @param session The filter session + * @param queue The query data */ -static int +static int routeQuery(FILTER *instance, void *session, GWBUF *queue) { -TOPN_INSTANCE *my_instance = (TOPN_INSTANCE *)instance; -TOPN_SESSION *my_session = (TOPN_SESSION *)session; -char *ptr; + TOPN_INSTANCE *my_instance = (TOPN_INSTANCE *) instance; + TOPN_SESSION *my_session = (TOPN_SESSION *) session; + char *ptr; - if (my_session->active) - { - if (queue->next != NULL) - { - queue = gwbuf_make_contiguous(queue); - } - if ((ptr = modutil_get_SQL(queue)) != NULL) - { - if ((my_instance->match == NULL || - regexec(&my_instance->re, ptr, 0, NULL, 0) == 0) && - (my_instance->exclude == NULL || - regexec(&my_instance->exre,ptr,0,NULL, 0) != 0)) - { - my_session->n_statements++; - if (my_session->current) - free(my_session->current); - gettimeofday(&my_session->start, NULL); - my_session->current = ptr; - } - else - { - free(ptr); - } - } - } - /* Pass the query downstream */ - return my_session->down.routeQuery(my_session->down.instance, - my_session->down.session, queue); + if (my_session->active) + { + if (queue->next != NULL) + { + queue = gwbuf_make_contiguous(queue); + } + if ((ptr = modutil_get_SQL(queue)) != NULL) + { + if ((my_instance->match == NULL || + regexec(&my_instance->re, ptr, 0, NULL, 0) == 0) && + (my_instance->exclude == NULL || + regexec(&my_instance->exre, ptr, 0, NULL, 0) != 0)) + { + my_session->n_statements++; + if (my_session->current) + { + free(my_session->current); + } + gettimeofday(&my_session->start, NULL); + my_session->current = ptr; + } + else + { + free(ptr); + } + } + } + /* Pass the query downstream */ + return my_session->down.routeQuery(my_session->down.instance, + my_session->down.session, queue); } static int cmp_topn(const void *va, const void *vb) { - TOPNQ **a = (TOPNQ **)va; - TOPNQ **b = (TOPNQ **)vb; + TOPNQ **a = (TOPNQ **) va; + TOPNQ **b = (TOPNQ **) vb; - if ((*b)->duration.tv_sec == (*a)->duration.tv_sec) - return (*b)->duration.tv_usec - (*a)->duration.tv_usec; - return (*b)->duration.tv_sec - (*a)->duration.tv_sec; + if ((*b)->duration.tv_sec == (*a)->duration.tv_sec) + { + return(*b)->duration.tv_usec - (*a)->duration.tv_usec; + } + return(*b)->duration.tv_sec - (*a)->duration.tv_sec; } static int clientReply(FILTER *instance, void *session, GWBUF *reply) { -TOPN_INSTANCE *my_instance = (TOPN_INSTANCE *)instance; -TOPN_SESSION *my_session = (TOPN_SESSION *)session; -struct timeval tv, diff; -int i, inserted; + TOPN_INSTANCE *my_instance = (TOPN_INSTANCE *) instance; + TOPN_SESSION *my_session = (TOPN_SESSION *) session; + struct timeval tv, diff; + int i, inserted; - if (my_session->current) - { - gettimeofday(&tv, NULL); - timersub(&tv, &(my_session->start), &diff); + if (my_session->current) + { + gettimeofday(&tv, NULL); + timersub(&tv, &(my_session->start), &diff); - timeradd(&(my_session->total), &diff, &(my_session->total)); + timeradd(&(my_session->total), &diff, &(my_session->total)); - inserted = 0; - for (i = 0; i < my_instance->topN; i++) - { - if (my_session->top[i]->sql == NULL) - { - my_session->top[i]->sql = my_session->current; - my_session->top[i]->duration = diff; - inserted = 1; - break; - } - } + inserted = 0; + for (i = 0; i < my_instance->topN; i++) + { + if (my_session->top[i]->sql == NULL) + { + my_session->top[i]->sql = my_session->current; + my_session->top[i]->duration = diff; + inserted = 1; + break; + } + } - if (inserted == 0 && ((diff.tv_sec > my_session->top[my_instance->topN-1]->duration.tv_sec) || (diff.tv_sec == my_session->top[my_instance->topN-1]->duration.tv_sec && diff.tv_usec > my_session->top[my_instance->topN-1]->duration.tv_usec ))) - { - free(my_session->top[my_instance->topN-1]->sql); - my_session->top[my_instance->topN-1]->sql = my_session->current; - my_session->top[my_instance->topN-1]->duration = diff; - inserted = 1; - } + if (inserted == 0 && ((diff.tv_sec > my_session->top[my_instance->topN - 1]->duration.tv_sec) || (diff.tv_sec == my_session->top[my_instance->topN - 1]->duration.tv_sec && diff.tv_usec > my_session->top[my_instance->topN - 1]->duration.tv_usec))) + { + free(my_session->top[my_instance->topN - 1]->sql); + my_session->top[my_instance->topN - 1]->sql = my_session->current; + my_session->top[my_instance->topN - 1]->duration = diff; + inserted = 1; + } - if (inserted) - qsort(my_session->top, my_instance->topN, - sizeof(TOPNQ *), cmp_topn); - else - free(my_session->current); - my_session->current = NULL; - } + if (inserted) + { + qsort(my_session->top, my_instance->topN, + sizeof(TOPNQ *), cmp_topn); + } + else + { + free(my_session->current); + } + my_session->current = NULL; + } - /* Pass the result upstream */ - return my_session->up.clientReply(my_session->up.instance, - my_session->up.session, reply); + /* Pass the result upstream */ + return my_session->up.clientReply(my_session->up.instance, + my_session->up.session, reply); } /** @@ -547,47 +583,55 @@ int i, inserted; * instance as a whole, otherwise print diagnostics for the * particular session. * - * @param instance The filter instance - * @param fsession Filter session, may be NULL - * @param dcb The DCB for diagnostic output + * @param instance The filter instance + * @param fsession Filter session, may be NULL + * @param dcb The DCB for diagnostic output */ -static void +static void diagnostic(FILTER *instance, void *fsession, DCB *dcb) { -TOPN_INSTANCE *my_instance = (TOPN_INSTANCE *)instance; -TOPN_SESSION *my_session = (TOPN_SESSION *)fsession; -int i; + TOPN_INSTANCE *my_instance = (TOPN_INSTANCE *) instance; + TOPN_SESSION *my_session = (TOPN_SESSION *) fsession; + int i; - dcb_printf(dcb, "\t\tReport size %d\n", - my_instance->topN); - if (my_instance->source) - dcb_printf(dcb, "\t\tLimit logging to connections from %s\n", - my_instance->source); - if (my_instance->user) - dcb_printf(dcb, "\t\tLimit logging to user %s\n", - my_instance->user); - if (my_instance->match) - dcb_printf(dcb, "\t\tInclude queries that match %s\n", - my_instance->match); - if (my_instance->exclude) - dcb_printf(dcb, "\t\tExclude queries that match %s\n", - my_instance->exclude); - if (my_session) - { - dcb_printf(dcb, "\t\tLogging to file %s.\n", - my_session->filename); - dcb_printf(dcb, "\t\tCurrent Top %d:\n", my_instance->topN); - for (i = 0; i < my_instance->topN; i++) - { - if (my_session->top[i]->sql) - { - dcb_printf(dcb, "\t\t%d place:\n", i + 1); - dcb_printf(dcb, "\t\t\tExecution time: %.3f seconds\n", - (double)((my_session->top[i]->duration.tv_sec * 1000) - + (my_session->top[i]->duration.tv_usec / 1000)) / 1000); - dcb_printf(dcb, "\t\t\tSQL: %s\n", - my_session->top[i]->sql); - } - } - } + dcb_printf(dcb, "\t\tReport size %d\n", + my_instance->topN); + if (my_instance->source) + { + dcb_printf(dcb, "\t\tLimit logging to connections from %s\n", + my_instance->source); + } + if (my_instance->user) + { + dcb_printf(dcb, "\t\tLimit logging to user %s\n", + my_instance->user); + } + if (my_instance->match) + { + dcb_printf(dcb, "\t\tInclude queries that match %s\n", + my_instance->match); + } + if (my_instance->exclude) + { + dcb_printf(dcb, "\t\tExclude queries that match %s\n", + my_instance->exclude); + } + if (my_session) + { + dcb_printf(dcb, "\t\tLogging to file %s.\n", + my_session->filename); + dcb_printf(dcb, "\t\tCurrent Top %d:\n", my_instance->topN); + for (i = 0; i < my_instance->topN; i++) + { + if (my_session->top[i]->sql) + { + dcb_printf(dcb, "\t\t%d place:\n", i + 1); + dcb_printf(dcb, "\t\t\tExecution time: %.3f seconds\n", + (double) ((my_session->top[i]->duration.tv_sec * 1000) + + (my_session->top[i]->duration.tv_usec / 1000)) / 1000); + dcb_printf(dcb, "\t\t\tSQL: %s\n", + my_session->top[i]->sql); + } + } + } } From a7c0952e66cce417ec6134a0adcfef5b5f1ca76b Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Wed, 18 Nov 2015 14:18:00 +0200 Subject: [PATCH 07/21] Formatted tee filter Tee filter formatted according to the style guide. --- server/modules/filter/tee.c | 1431 ++++++++++++++++++----------------- 1 file changed, 738 insertions(+), 693 deletions(-) diff --git a/server/modules/filter/tee.c b/server/modules/filter/tee.c index 880bc5c24..fc97e7bbb 100644 --- a/server/modules/filter/tee.c +++ b/server/modules/filter/tee.c @@ -45,6 +45,7 @@ * * @endverbatim */ + #include #include #include @@ -63,44 +64,47 @@ #include #include -#define MYSQL_COM_QUIT 0x01 -#define MYSQL_COM_INITDB 0x02 -#define MYSQL_COM_FIELD_LIST 0x04 -#define MYSQL_COM_CHANGE_USER 0x11 -#define MYSQL_COM_STMT_PREPARE 0x16 -#define MYSQL_COM_STMT_EXECUTE 0x17 +#define MYSQL_COM_QUIT 0x01 +#define MYSQL_COM_INITDB 0x02 +#define MYSQL_COM_FIELD_LIST 0x04 +#define MYSQL_COM_CHANGE_USER 0x11 +#define MYSQL_COM_STMT_PREPARE 0x16 +#define MYSQL_COM_STMT_EXECUTE 0x17 #define MYSQL_COM_STMT_SEND_LONG_DATA 0x18 -#define MYSQL_COM_STMT_CLOSE 0x19 -#define MYSQL_COM_STMT_RESET 0x1a -#define MYSQL_COM_CONNECT 0x1b +#define MYSQL_COM_STMT_CLOSE 0x19 +#define MYSQL_COM_STMT_RESET 0x1a +#define MYSQL_COM_CONNECT 0x1b -#define REPLY_TIMEOUT_SECOND 5 -#define REPLY_TIMEOUT_MILLISECOND 1 -#define PARENT 0 -#define CHILD 1 +#define REPLY_TIMEOUT_SECOND 5 +#define REPLY_TIMEOUT_MILLISECOND 1 +#define PARENT 0 +#define CHILD 1 #ifdef SS_DEBUG static int debug_seq = 0; #endif -static unsigned char required_packets[] = { - MYSQL_COM_QUIT, - MYSQL_COM_INITDB, - MYSQL_COM_FIELD_LIST, - MYSQL_COM_CHANGE_USER, - MYSQL_COM_STMT_PREPARE, - MYSQL_COM_STMT_EXECUTE, - MYSQL_COM_STMT_SEND_LONG_DATA, - MYSQL_COM_STMT_CLOSE, - MYSQL_COM_STMT_RESET, - MYSQL_COM_CONNECT, - 0 }; +static unsigned char required_packets[] = +{ + MYSQL_COM_QUIT, + MYSQL_COM_INITDB, + MYSQL_COM_FIELD_LIST, + MYSQL_COM_CHANGE_USER, + MYSQL_COM_STMT_PREPARE, + MYSQL_COM_STMT_EXECUTE, + MYSQL_COM_STMT_SEND_LONG_DATA, + MYSQL_COM_STMT_CLOSE, + MYSQL_COM_STMT_RESET, + MYSQL_COM_CONNECT, + 0 +}; -MODULE_INFO info = { - MODULE_API_FILTER, - MODULE_GA, - FILTER_VERSION, - "A tee piece in the filter plumbing" +MODULE_INFO info = +{ + MODULE_API_FILTER, + MODULE_GA, + FILTER_VERSION, + "A tee piece in the filter plumbing" }; static char *version_str = "V1.0.0"; @@ -108,17 +112,18 @@ static char *version_str = "V1.0.0"; /* * The filter entry points */ -static FILTER *createInstance(char **options, FILTER_PARAMETER **); -static void *newSession(FILTER *instance, SESSION *session); -static void closeSession(FILTER *instance, void *session); -static void freeSession(FILTER *instance, void *session); -static void setDownstream(FILTER *instance, void *fsession, DOWNSTREAM *downstream); -static void setUpstream(FILTER *instance, void *fsession, UPSTREAM *upstream); -static int routeQuery(FILTER *instance, void *fsession, GWBUF *queue); -static int clientReply(FILTER *instance, void *fsession, GWBUF *queue); -static void diagnostic(FILTER *instance, void *fsession, DCB *dcb); +static FILTER *createInstance(char **options, FILTER_PARAMETER **); +static void *newSession(FILTER *instance, SESSION *session); +static void closeSession(FILTER *instance, void *session); +static void freeSession(FILTER *instance, void *session); +static void setDownstream(FILTER *instance, void *fsession, DOWNSTREAM *downstream); +static void setUpstream(FILTER *instance, void *fsession, UPSTREAM *upstream); +static int routeQuery(FILTER *instance, void *fsession, GWBUF *queue); +static int clientReply(FILTER *instance, void *fsession, GWBUF *queue); +static void diagnostic(FILTER *instance, void *fsession, DCB *dcb); -static FILTER_OBJECT MyObject = { +static FILTER_OBJECT MyObject = +{ createInstance, newSession, closeSession, @@ -134,52 +139,53 @@ static FILTER_OBJECT MyObject = { * The instance structure for the TEE filter - this holds the configuration * information for the filter. */ -typedef struct { - SERVICE *service; /* The service to duplicate requests to */ - char *source; /* The source of the client connection */ - char *userName; /* The user name to filter on */ - char *match; /* Optional text to match against */ - regex_t re; /* Compiled regex text */ - char *nomatch; /* Optional text to match against for exclusion */ - regex_t nore; /* Compiled regex nomatch text */ +typedef struct +{ + SERVICE *service; /* The service to duplicate requests to */ + char *source; /* The source of the client connection */ + char *userName; /* The user name to filter on */ + char *match; /* Optional text to match against */ + regex_t re; /* Compiled regex text */ + char *nomatch; /* Optional text to match against for exclusion */ + regex_t nore; /* Compiled regex nomatch text */ } TEE_INSTANCE; /** * The session structure for this TEE filter. - * This stores the downstream filter information, such that the + * This stores the downstream filter information, such that the * filter is able to pass the query on to the next filter (or router) * in the chain. * * It also holds the file descriptor to which queries are written. */ -typedef struct { - DOWNSTREAM down; /* The downstream filter */ - UPSTREAM up; /* The upstream filter */ - +typedef struct +{ + DOWNSTREAM down; /* The downstream filter */ + UPSTREAM up; /* The upstream filter */ FILTER_DEF* dummy_filterdef; - int active; /* filter is active? */ - bool use_ok; - int client_multistatement; - bool multipacket[2]; - unsigned char command; - bool waiting[2]; /* if the client is waiting for a reply */ - int eof[2]; - int replies[2]; /* Number of queries received */ - int reply_packets[2]; /* Number of OK, ERR, LOCAL_INFILE_REQUEST or RESULT_SET packets received */ - DCB *branch_dcb; /* Client DCB for "branch" service */ - SESSION *branch_session;/* The branch service session */ - TEE_INSTANCE *instance; - int n_duped; /* Number of duplicated queries */ - int n_rejected; /* Number of rejected queries */ - int residual; /* Any outstanding SQL text */ - GWBUF* tee_replybuf; /* Buffer for reply */ - GWBUF* tee_partials[2]; - GWBUF* queue; - SPINLOCK tee_lock; - DCB* client_dcb; + int active; /* filter is active? */ + bool use_ok; + int client_multistatement; + bool multipacket[2]; + unsigned char command; + bool waiting[2]; /* if the client is waiting for a reply */ + int eof[2]; + int replies[2]; /* Number of queries received */ + int reply_packets[2]; /* Number of OK, ERR, LOCAL_INFILE_REQUEST or RESULT_SET packets received */ + DCB *branch_dcb; /* Client DCB for "branch" service */ + SESSION *branch_session; /* The branch service session */ + TEE_INSTANCE *instance; + int n_duped; /* Number of duplicated queries */ + int n_rejected; /* Number of rejected queries */ + int residual; /* Any outstanding SQL text */ + GWBUF* tee_replybuf; /* Buffer for reply */ + GWBUF* tee_partials[2]; + GWBUF* queue; + SPINLOCK tee_lock; + DCB* client_dcb; #ifdef SS_DEBUG - long d_id; + long d_id; #endif } TEE_SESSION; @@ -188,7 +194,7 @@ typedef struct orphan_session_tt SESSION* session; /*< The child branch session whose parent was freed before * the child session was in a suitable state. */ struct orphan_session_tt* next; -}orphan_session_t; +} orphan_session_t; #ifdef SS_DEBUG static SPINLOCK debug_lock; @@ -203,9 +209,9 @@ static int detect_loops(TEE_INSTANCE *instance, HASHTABLE* ht, SERVICE* session) int internal_route(DCB* dcb); GWBUF* clone_query(TEE_INSTANCE* my_instance, TEE_SESSION* my_session, GWBUF* buffer); int route_single_query(TEE_INSTANCE* my_instance, - TEE_SESSION* my_session, - GWBUF* buffer, - GWBUF* clone); + TEE_SESSION* my_session, + GWBUF* buffer, + GWBUF* clone); int reset_session_state(TEE_SESSION* my_session, GWBUF* buffer); void create_orphan(SESSION* ses); @@ -217,13 +223,11 @@ orphan_free(void* data) #ifdef SS_DEBUG int o_stopping = 0, o_ready = 0, o_freed = 0; #endif - while(ptr) + while (ptr) { - if(ptr->session->state == SESSION_STATE_TO_BE_FREED) + if (ptr->session->state == SESSION_STATE_TO_BE_FREED) { - - - if(ptr == allOrphans) + if (ptr == allOrphans) { tmp = ptr; allOrphans = ptr->next; @@ -231,38 +235,39 @@ orphan_free(void* data) else { tmp = allOrphans; - while(tmp && tmp->next != ptr) + while (tmp && tmp->next != ptr) + { tmp = tmp->next; - if(tmp) + } + if (tmp) { tmp->next = ptr->next; tmp = ptr; } } - } - + /* * The session has been unlinked from all the DCBs and it is ready to be freed. */ - - if(ptr->session->state == SESSION_STATE_STOPPING && + + if (ptr->session->state == SESSION_STATE_STOPPING && ptr->session->refcount == 0 && ptr->session->client == NULL) { ptr->session->state = SESSION_STATE_TO_BE_FREED; } #ifdef SS_DEBUG - else if(ptr->session->state == SESSION_STATE_STOPPING) + else if (ptr->session->state == SESSION_STATE_STOPPING) { o_stopping++; } - else if(ptr->session->state == SESSION_STATE_ROUTER_READY) + else if (ptr->session->state == SESSION_STATE_ROUTER_READY) { o_ready++; } #endif ptr = ptr->next; - if(tmp) + if (tmp) { tmp->next = finished; finished = tmp; @@ -273,13 +278,15 @@ orphan_free(void* data) spinlock_release(&orphanLock); #ifdef SS_DEBUG - if(o_stopping + o_ready > 0) + if (o_stopping + o_ready > 0) + { MXS_DEBUG("tee.c: %d orphans in " "SESSION_STATE_STOPPING, %d orphans in " "SESSION_STATE_ROUTER_READY. ", o_stopping, o_ready); + } #endif - while(finished) + while (finished) { #ifdef SS_DEBUG o_freed++; @@ -309,7 +316,7 @@ orphan_free(void* data) char * version() { - return version_str; + return version_str; } /** @@ -336,102 +343,106 @@ ModuleInit() FILTER_OBJECT * GetModuleObject() { - return &MyObject; + return &MyObject; } /** * Create an instance of the filter for a particular service * within MaxScale. - * + * * @param options The options for this filter * @param params The array of name/value pair parameters for the filter * * @return The instance data for this new instance */ -static FILTER * +static FILTER * createInstance(char **options, FILTER_PARAMETER **params) { -TEE_INSTANCE *my_instance; -int i; + TEE_INSTANCE *my_instance; + int i; - if ((my_instance = calloc(1, sizeof(TEE_INSTANCE))) != NULL) - { - if (options) - { - MXS_ERROR("tee: The tee filter has been passed an option, " - "this filter does not support any options."); - } - my_instance->service = NULL; - my_instance->source = NULL; - my_instance->userName = NULL; - my_instance->match = NULL; - my_instance->nomatch = NULL; - if (params) - { - for (i = 0; params[i]; i++) - { - if (!strcmp(params[i]->name, "service")) - { - if ((my_instance->service = service_find(params[i]->value)) == NULL) - { - MXS_ERROR("tee: service '%s' not found.\n", - params[i]->value); - } - } - else if (!strcmp(params[i]->name, "match")) - { - my_instance->match = strdup(params[i]->value); - } - else if (!strcmp(params[i]->name, "exclude")) - { - my_instance->nomatch = strdup(params[i]->value); - } - else if (!strcmp(params[i]->name, "source")) - my_instance->source = strdup(params[i]->value); - else if (!strcmp(params[i]->name, "user")) - my_instance->userName = strdup(params[i]->value); - else if (!filter_standard_parameter(params[i]->name)) - { - MXS_ERROR("tee: Unexpected parameter '%s'.", - params[i]->name); - } - } - } - if (my_instance->service == NULL) - { - free(my_instance->match); - free(my_instance->source); - free(my_instance); - return NULL; - } + if ((my_instance = calloc(1, sizeof(TEE_INSTANCE))) != NULL) + { + if (options) + { + MXS_ERROR("tee: The tee filter has been passed an option, " + "this filter does not support any options."); + } + my_instance->service = NULL; + my_instance->source = NULL; + my_instance->userName = NULL; + my_instance->match = NULL; + my_instance->nomatch = NULL; + if (params) + { + for (i = 0; params[i]; i++) + { + if (!strcmp(params[i]->name, "service")) + { + if ((my_instance->service = service_find(params[i]->value)) == NULL) + { + MXS_ERROR("tee: service '%s' not found.\n", + params[i]->value); + } + } + else if (!strcmp(params[i]->name, "match")) + { + my_instance->match = strdup(params[i]->value); + } + else if (!strcmp(params[i]->name, "exclude")) + { + my_instance->nomatch = strdup(params[i]->value); + } + else if (!strcmp(params[i]->name, "source")) + { + my_instance->source = strdup(params[i]->value); + } + else if (!strcmp(params[i]->name, "user")) + { + my_instance->userName = strdup(params[i]->value); + } + else if (!filter_standard_parameter(params[i]->name)) + { + MXS_ERROR("tee: Unexpected parameter '%s'.", + params[i]->name); + } + } + } + if (my_instance->service == NULL) + { + free(my_instance->match); + free(my_instance->source); + free(my_instance); + return NULL; + } - if (my_instance->match && - regcomp(&my_instance->re, my_instance->match, REG_ICASE)) - { - MXS_ERROR("tee: Invalid regular expression '%s'" - " for the match parameter.", - my_instance->match); - free(my_instance->match); - free(my_instance->source); - free(my_instance); - return NULL; - } - if (my_instance->nomatch && - regcomp(&my_instance->nore, my_instance->nomatch, - REG_ICASE)) - { - MXS_ERROR("tee: Invalid regular expression '%s'" - " for the nomatch paramter.\n", - my_instance->match); - if (my_instance->match) - regfree(&my_instance->re); - free(my_instance->match); - free(my_instance->source); - free(my_instance); - return NULL; - } - } - return (FILTER *)my_instance; + if (my_instance->match && + regcomp(&my_instance->re, my_instance->match, REG_ICASE)) + { + MXS_ERROR("tee: Invalid regular expression '%s'" + " for the match parameter.", + my_instance->match); + free(my_instance->match); + free(my_instance->source); + free(my_instance); + return NULL; + } + if (my_instance->nomatch && + regcomp(&my_instance->nore, my_instance->nomatch, + REG_ICASE)) + { + MXS_ERROR("tee: Invalid regular expression '%s'" + " for the nomatch paramter.\n", + my_instance->match); + if (my_instance->match) + regfree(&my_instance->re); + free(my_instance->match); + free(my_instance->source); + free(my_instance); + return NULL; + } + } + return(FILTER *) my_instance; } /** @@ -443,138 +454,138 @@ int i; * @param session The session itself * @return Session specific data for this session */ -static void * +static void * newSession(FILTER *instance, SESSION *session) { -TEE_INSTANCE *my_instance = (TEE_INSTANCE *)instance; -TEE_SESSION *my_session; -char *remote, *userName; + TEE_INSTANCE *my_instance = (TEE_INSTANCE *) instance; + TEE_SESSION *my_session; + char *remote, *userName; - if (strcmp(my_instance->service->name, session->service->name) == 0) - { - MXS_ERROR("%s: Recursive use of tee filter in service.", - session->service->name); - my_session = NULL; - goto retblock; - } - - HASHTABLE* ht = hashtable_alloc(100,simple_str_hash,strcmp); - bool is_loop = detect_loops(my_instance,ht,session->service); - hashtable_free(ht); - - if(is_loop) - { - MXS_ERROR("%s: Recursive use of tee filter in service.", - session->service->name); - my_session = NULL; - goto retblock; - } - - if ((my_session = calloc(1, sizeof(TEE_SESSION))) != NULL) - { - my_session->active = 1; - my_session->residual = 0; - my_session->tee_replybuf = NULL; - my_session->client_dcb = session->client; - my_session->instance = my_instance; - my_session->client_multistatement = false; - my_session->queue = NULL; - spinlock_init(&my_session->tee_lock); - if (my_instance->source && - (remote = session_get_remote(session)) != NULL) - { - if (strcmp(remote, my_instance->source)) - { - my_session->active = 0; - - MXS_WARNING("Tee filter is not active."); - } - } - userName = session_getUser(session); - - if (my_instance->userName && - userName && - strcmp(userName, my_instance->userName)) - { - my_session->active = 0; - - MXS_WARNING("Tee filter is not active."); - } - - if (my_session->active) - { - DCB* dcb; - SESSION* ses; - FILTER_DEF* dummy; - UPSTREAM* dummy_upstream; - - if ((dcb = dcb_clone(session->client)) == NULL) - { - freeSession(instance, (void *)my_session); - my_session = NULL; - - MXS_ERROR("Creating client DCB for Tee " - "filter failed. Terminating session."); - - goto retblock; - } + if (strcmp(my_instance->service->name, session->service->name) == 0) + { + MXS_ERROR("%s: Recursive use of tee filter in service.", + session->service->name); + my_session = NULL; + goto retblock; + } - if((dummy = filter_alloc("tee_dummy","tee_dummy")) == NULL) - { - dcb_close(dcb); - freeSession(instance, (void *)my_session); - my_session = NULL; - MXS_ERROR("tee: Allocating memory for " - "dummy filter definition failed." - " Terminating session."); - - goto retblock; - } - - - - if ((ses = session_alloc(my_instance->service, dcb)) == NULL) - { - filter_free(dummy); - dcb_close(dcb); - freeSession(instance, (void *)my_session); - my_session = NULL; - MXS_ERROR("Creating client session for Tee " - "filter failed. Terminating session."); - - goto retblock; - } - - ss_dassert(ses->ses_is_child); + HASHTABLE* ht = hashtable_alloc(100, simple_str_hash, strcmp); + bool is_loop = detect_loops(my_instance, ht, session->service); + hashtable_free(ht); - dummy->obj = GetModuleObject(); - dummy->filter = NULL; - my_session->branch_session = ses; - my_session->branch_dcb = dcb; - my_session->dummy_filterdef = dummy; + if (is_loop) + { + MXS_ERROR("%s: Recursive use of tee filter in service.", + session->service->name); + my_session = NULL; + goto retblock; + } - if((dummy_upstream = filterUpstream( - dummy, my_session, &ses->tail)) == NULL) - { - filter_free(dummy); - closeSession(instance,(void*)my_session); - dcb_close(dcb); - free(my_session); - MXS_ERROR("tee: Allocating memory for" - "dummy upstream failed." - " Terminating session."); + if ((my_session = calloc(1, sizeof(TEE_SESSION))) != NULL) + { + my_session->active = 1; + my_session->residual = 0; + my_session->tee_replybuf = NULL; + my_session->client_dcb = session->client; + my_session->instance = my_instance; + my_session->client_multistatement = false; + my_session->queue = NULL; + spinlock_init(&my_session->tee_lock); + if (my_instance->source && + (remote = session_get_remote(session)) != NULL) + { + if (strcmp(remote, my_instance->source)) + { + my_session->active = 0; - return NULL; - } - - ses->tail = *dummy_upstream; - MySQLProtocol* protocol = (MySQLProtocol*)session->client->protocol; - my_session->use_ok = protocol->client_capabilities & (1 << 6); - free(dummy_upstream); - } - } + MXS_WARNING("Tee filter is not active."); + } + } + userName = session_getUser(session); + + if (my_instance->userName && + userName && + strcmp(userName, my_instance->userName)) + { + my_session->active = 0; + + MXS_WARNING("Tee filter is not active."); + } + + if (my_session->active) + { + DCB* dcb; + SESSION* ses; + FILTER_DEF* dummy; + UPSTREAM* dummy_upstream; + + if ((dcb = dcb_clone(session->client)) == NULL) + { + freeSession(instance, (void *) my_session); + my_session = NULL; + + MXS_ERROR("Creating client DCB for Tee " + "filter failed. Terminating session."); + + goto retblock; + } + + if ((dummy = filter_alloc("tee_dummy", "tee_dummy")) == NULL) + { + dcb_close(dcb); + freeSession(instance, (void *) my_session); + my_session = NULL; + MXS_ERROR("tee: Allocating memory for " + "dummy filter definition failed." + " Terminating session."); + + goto retblock; + } + + + + if ((ses = session_alloc(my_instance->service, dcb)) == NULL) + { + filter_free(dummy); + dcb_close(dcb); + freeSession(instance, (void *) my_session); + my_session = NULL; + MXS_ERROR("Creating client session for Tee " + "filter failed. Terminating session."); + + goto retblock; + } + + ss_dassert(ses->ses_is_child); + + dummy->obj = GetModuleObject(); + dummy->filter = NULL; + my_session->branch_session = ses; + my_session->branch_dcb = dcb; + my_session->dummy_filterdef = dummy; + + if ((dummy_upstream = filterUpstream( + dummy, my_session, &ses->tail)) == NULL) + { + filter_free(dummy); + closeSession(instance, (void*) my_session); + dcb_close(dcb); + free(my_session); + MXS_ERROR("tee: Allocating memory for" + "dummy upstream failed." + " Terminating session."); + + return NULL; + } + + ses->tail = *dummy_upstream; + MySQLProtocol* protocol = (MySQLProtocol*) session->client->protocol; + my_session->use_ok = protocol->client_capabilities & (1 << 6); + free(dummy_upstream); + } + } retblock: - return my_session; + return my_session; } /** @@ -586,56 +597,56 @@ retblock: * @param instance The filter instance data * @param session The session being closed */ -static void +static void closeSession(FILTER *instance, void *session) { -TEE_SESSION *my_session = (TEE_SESSION *)session; -ROUTER_OBJECT *router; -void *router_instance, *rsession; -SESSION *bsession; + TEE_SESSION *my_session = (TEE_SESSION *) session; + ROUTER_OBJECT *router; + void *router_instance, *rsession; + SESSION *bsession; #ifdef SS_DEBUG -MXS_INFO("Tee close: %d", atomic_add(&debug_seq,1)); + MXS_INFO("Tee close: %d", atomic_add(&debug_seq, 1)); #endif - if (my_session->active) - { - - if ((bsession = my_session->branch_session) != NULL) - { - CHK_SESSION(bsession); - spinlock_acquire(&bsession->ses_lock); - - if (bsession->state != SESSION_STATE_STOPPING) - { - bsession->state = SESSION_STATE_STOPPING; - } - router = bsession->service->router; - router_instance = bsession->service->router_instance; - rsession = bsession->router_session; - spinlock_release(&bsession->ses_lock); - - /** Close router session and all its connections */ - router->closeSession(router_instance, rsession); - } - /* No need to free the session, this is done as - * a side effect of closing the client DCB of the - * session. - */ + if (my_session->active) + { - if(my_session->waiting[PARENT]) - { - if(my_session->command != 0x01 && - my_session->client_dcb && - my_session->client_dcb->state == DCB_STATE_POLLING) - { - MXS_INFO("Tee session closed mid-query."); - GWBUF* errbuf = modutil_create_mysql_err_msg(1,0,1,"00000","Session closed."); - my_session->client_dcb->func.write(my_session->client_dcb,errbuf); - } - } + if ((bsession = my_session->branch_session) != NULL) + { + CHK_SESSION(bsession); + spinlock_acquire(&bsession->ses_lock); + + if (bsession->state != SESSION_STATE_STOPPING) + { + bsession->state = SESSION_STATE_STOPPING; + } + router = bsession->service->router; + router_instance = bsession->service->router_instance; + rsession = bsession->router_session; + spinlock_release(&bsession->ses_lock); + + /** Close router session and all its connections */ + router->closeSession(router_instance, rsession); + } + /* No need to free the session, this is done as + * a side effect of closing the client DCB of the + * session. + */ + + if (my_session->waiting[PARENT]) + { + if (my_session->command != 0x01 && + my_session->client_dcb && + my_session->client_dcb->state == DCB_STATE_POLLING) + { + MXS_INFO("Tee session closed mid-query."); + GWBUF* errbuf = modutil_create_mysql_err_msg(1, 0, 1, "00000", "Session closed."); + my_session->client_dcb->func.write(my_session->client_dcb, errbuf); + } + } - my_session->active = 0; - } + my_session->active = 0; + } } /** @@ -647,55 +658,58 @@ MXS_INFO("Tee close: %d", atomic_add(&debug_seq,1)); static void freeSession(FILTER *instance, void *session) { -TEE_SESSION *my_session = (TEE_SESSION *)session; -SESSION* ses = my_session->branch_session; -session_state_t state; + TEE_SESSION *my_session = (TEE_SESSION *) session; + SESSION* ses = my_session->branch_session; + session_state_t state; #ifdef SS_DEBUG -MXS_INFO("Tee free: %d", atomic_add(&debug_seq,1)); + MXS_INFO("Tee free: %d", atomic_add(&debug_seq, 1)); #endif - if (ses != NULL) - { - state = ses->state; - - if (state == SESSION_STATE_ROUTER_READY) - { - session_free(ses); - } - else if (state == SESSION_STATE_TO_BE_FREED) - { - /** Free branch router session */ - ses->service->router->freeSession( - ses->service->router_instance, - ses->router_session); - /** Free memory of branch client session */ - ses->state = SESSION_STATE_FREE; - free(ses); - /** This indicates that branch session is not available anymore */ - my_session->branch_session = NULL; - } - else if(state == SESSION_STATE_STOPPING) - { - create_orphan(ses); - } - } - if (my_session->dummy_filterdef) - { - filter_free(my_session->dummy_filterdef); - } - if(my_session->tee_replybuf) - gwbuf_free(my_session->tee_replybuf); - free(session); - - orphan_free(NULL); + if (ses != NULL) + { + state = ses->state; - return; + if (state == SESSION_STATE_ROUTER_READY) + { + session_free(ses); + } + else if (state == SESSION_STATE_TO_BE_FREED) + { + /** Free branch router session */ + ses->service->router->freeSession( + ses->service->router_instance, + ses->router_session); + /** Free memory of branch client session */ + ses->state = SESSION_STATE_FREE; + free(ses); + /** This indicates that branch session is not available anymore */ + my_session->branch_session = NULL; + } + else if (state == SESSION_STATE_STOPPING) + { + create_orphan(ses); + } + } + if (my_session->dummy_filterdef) + { + filter_free(my_session->dummy_filterdef); + } + if (my_session->tee_replybuf) + { + gwbuf_free(my_session->tee_replybuf); + } + free(session); + + orphan_free(NULL); + + return; } + /** * Set the downstream filter or router to which queries will be * passed from this filter. * * @param instance The filter instance data - * @param session The filter session + * @param session The filter session * @param downstream The downstream filter or router. */ static void @@ -710,7 +724,7 @@ setDownstream(FILTER *instance, void *session, DOWNSTREAM *downstream) * passed from this filter. * * @param instance The filter instance data - * @param session The filter session + * @param session The filter session * @param downstream The downstream filter or router. */ static void @@ -738,62 +752,64 @@ setUpstream(FILTER *instance, void *session, UPSTREAM *upstream) * @param session The filter session * @param queue The query data */ -static int +static int routeQuery(FILTER *instance, void *session, GWBUF *queue) { - TEE_INSTANCE *my_instance = (TEE_INSTANCE *)instance; - TEE_SESSION *my_session = (TEE_SESSION *)session; - char *ptr; - int rval; - GWBUF *buffer = NULL, *clone = NULL; - unsigned char command = gwbuf_length(queue) >= 5 ? - *((unsigned char*)queue->start + 4) : 1; + TEE_INSTANCE *my_instance = (TEE_INSTANCE *) instance; + TEE_SESSION *my_session = (TEE_SESSION *) session; + char *ptr; + int rval; + GWBUF *buffer = NULL, *clone = NULL; + unsigned char command = gwbuf_length(queue) >= 5 ? + *((unsigned char*) queue->start + 4) : 1; #ifdef SS_DEBUG - int prev_debug_seq = atomic_add(&debug_seq,1); + int prev_debug_seq = atomic_add(&debug_seq, 1); MXS_INFO("Tee routeQuery: %d : %s", prev_debug_seq, - ((char*)queue->start + 5)); + ((char*) queue->start + 5)); #endif spinlock_acquire(&my_session->tee_lock); - if(!my_session->active) + if (!my_session->active) { - MXS_INFO("Tee: Received a reply when the session was closed."); - gwbuf_free(queue); - spinlock_release(&my_session->tee_lock); - return 0; + MXS_INFO("Tee: Received a reply when the session was closed."); + gwbuf_free(queue); + spinlock_release(&my_session->tee_lock); + return 0; } - if(my_session->queue) + if (my_session->queue) { - my_session->queue = gwbuf_append(my_session->queue,queue); - buffer = modutil_get_next_MySQL_packet(&my_session->queue); + my_session->queue = gwbuf_append(my_session->queue, queue); + buffer = modutil_get_next_MySQL_packet(&my_session->queue); } else { - buffer = modutil_get_next_MySQL_packet(&queue); - my_session->queue = queue; + buffer = modutil_get_next_MySQL_packet(&queue); + my_session->queue = queue; } - if(buffer == NULL) + if (buffer == NULL) { - spinlock_release(&my_session->tee_lock); - return 1; + spinlock_release(&my_session->tee_lock); + return 1; } - - clone = clone_query(my_instance, my_session,buffer); + + clone = clone_query(my_instance, my_session, buffer); spinlock_release(&my_session->tee_lock); /* Reset session state */ - if(!reset_session_state(my_session,buffer)) - return 0; + if (!reset_session_state(my_session, buffer)) + { + return 0; + } /** Route query downstream */ spinlock_acquire(&my_session->tee_lock); - rval = route_single_query(my_instance,my_session,buffer,clone); + rval = route_single_query(my_instance, my_session, buffer, clone); spinlock_release(&my_session->tee_lock); return rval; @@ -801,29 +817,32 @@ routeQuery(FILTER *instance, void *session, GWBUF *queue) int count_replies(GWBUF* buffer) { - unsigned char* ptr = (unsigned char*)buffer->start; + unsigned char* ptr = (unsigned char*) buffer->start; unsigned char* end = (unsigned char*) buffer->end; int pktlen, eof = 0; int replies = 0; - while(ptr < end) + while (ptr < end) { - pktlen = MYSQL_GET_PACKET_LEN(ptr) + 4; - if(PTR_IS_OK(ptr) || PTR_IS_ERR(ptr) || PTR_IS_LOCAL_INFILE(ptr)) - { - replies++; - ptr += pktlen; - } - else - { - while(ptr < end && eof < 2) - { - pktlen = MYSQL_GET_PACKET_LEN(ptr) + 4; - if(PTR_IS_EOF(ptr) || PTR_IS_ERR(ptr)) eof++; - ptr += pktlen; - } - if(eof == 2) replies++; - eof = 0; - } + pktlen = MYSQL_GET_PACKET_LEN(ptr) + 4; + if (PTR_IS_OK(ptr) || PTR_IS_ERR(ptr) || PTR_IS_LOCAL_INFILE(ptr)) + { + replies++; + ptr += pktlen; + } + else + { + while (ptr < end && eof < 2) + { + pktlen = MYSQL_GET_PACKET_LEN(ptr) + 4; + if (PTR_IS_EOF(ptr) || PTR_IS_ERR(ptr)) eof++; + ptr += pktlen; + } + if (eof == 2) + { + replies++; + } + eof = 0; + } } return replies; @@ -832,14 +851,22 @@ int count_replies(GWBUF* buffer) int lenenc_length(uint8_t* ptr) { char val = *ptr; - if(val < 251) - return 1; - else if(val == 0xfc) - return 3; - else if(val == 0xfd) - return 4; + if (val < 251) + { + return 1; + } + else if (val == 0xfc) + { + return 3; + } + else if (val == 0xfd) + { + return 4; + } else - return 9; + { + return 9; + } } uint16_t get_response_flags(uint8_t* datastart, bool ok_packet) @@ -850,17 +877,17 @@ uint16_t get_response_flags(uint8_t* datastart, bool ok_packet) ptr += 4; - if(ok_packet) + if (ok_packet) { - ptr += lenenc_length(ptr); - ptr += lenenc_length(ptr); - memcpy(&rval,ptr,sizeof(uint8_t)*2); + ptr += lenenc_length(ptr); + ptr += lenenc_length(ptr); + memcpy(&rval, ptr, sizeof(uint8_t)*2); } else { - /** This is an EOF packet*/ - ptr += 2; - memcpy(&rval,ptr,sizeof(uint8_t)*2); + /** This is an EOF packet*/ + ptr += 2; + memcpy(&rval, ptr, sizeof(uint8_t)*2); } return rval; @@ -877,21 +904,21 @@ uint16_t get_response_flags(uint8_t* datastart, bool ok_packet) * @param reply The response data */ static int -clientReply (FILTER* instance, void *session, GWBUF *reply) +clientReply(FILTER* instance, void *session, GWBUF *reply) { int rc, branch, eof; TEE_SESSION *my_session = (TEE_SESSION *) session; - bool route = false,mpkt; + bool route = false, mpkt; GWBUF *complete = NULL; unsigned char *ptr; uint16_t flags = 0; int min_eof = my_session->command != 0x04 ? 2 : 1; int more_results = 0; #ifdef SS_DEBUG - int prev_debug_seq = atomic_add(&debug_seq,1); + int prev_debug_seq = atomic_add(&debug_seq, 1); ptr = (unsigned char*) reply->start; MXS_INFO("Tee clientReply [%s] [%s] [%s]: %d", - instance ? "parent":"child", + instance ? "parent" : "child", my_session->active ? "open" : "closed", PTR_IS_ERR(ptr) ? "ERR" : PTR_IS_OK(ptr) ? "OK" : "RSET", prev_debug_seq); @@ -899,20 +926,20 @@ clientReply (FILTER* instance, void *session, GWBUF *reply) spinlock_acquire(&my_session->tee_lock); - if(!my_session->active) + if (!my_session->active) { - MXS_INFO("Tee: Failed to return reply, session is closed"); - gwbuf_free(reply); - rc = 0; - if(my_session->waiting[PARENT]) - { - GWBUF* errbuf = modutil_create_mysql_err_msg(1,0,1,"0000","Session closed."); - my_session->waiting[PARENT] = false; - my_session->up.clientReply (my_session->up.instance, - my_session->up.session, - errbuf); - } - goto retblock; + MXS_INFO("Tee: Failed to return reply, session is closed"); + gwbuf_free(reply); + rc = 0; + if (my_session->waiting[PARENT]) + { + GWBUF* errbuf = modutil_create_mysql_err_msg(1, 0, 1, "0000", "Session closed."); + my_session->waiting[PARENT] = false; + my_session->up.clientReply(my_session->up.instance, + my_session->up.session, + errbuf); + } + goto retblock; } branch = instance == NULL ? CHILD : PARENT; @@ -921,166 +948,166 @@ clientReply (FILTER* instance, void *session, GWBUF *reply) my_session->tee_partials[branch] = gwbuf_make_contiguous(my_session->tee_partials[branch]); complete = modutil_get_complete_packets(&my_session->tee_partials[branch]); - if(complete == NULL) + if (complete == NULL) { - /** Incomplete packet */ - MXS_DEBUG("tee.c: Incomplete packet, " + /** Incomplete packet */ + MXS_DEBUG("tee.c: Incomplete packet, " "waiting for a complete packet before forwarding."); - rc = 1; - goto retblock; + rc = 1; + goto retblock; } - + complete = gwbuf_make_contiguous(complete); - if(my_session->tee_partials[branch] && - GWBUF_EMPTY(my_session->tee_partials[branch])) + if (my_session->tee_partials[branch] && + GWBUF_EMPTY(my_session->tee_partials[branch])) { gwbuf_free(my_session->tee_partials[branch]); my_session->tee_partials[branch] = NULL; } ptr = (unsigned char*) complete->start; - - if(my_session->replies[branch] == 0) + + if (my_session->replies[branch] == 0) { - MXS_INFO("Tee: First reply to a query for [%s].",branch == PARENT ? "PARENT":"CHILD"); - /* Reply is in a single packet if it is an OK, ERR or LOCAL_INFILE packet. - * Otherwise the reply is a result set and the amount of packets is unknown. - */ - if(PTR_IS_ERR(ptr) || PTR_IS_LOCAL_INFILE(ptr) || - PTR_IS_OK(ptr) || !my_session->multipacket[branch] ) - { - my_session->waiting[branch] = false; - my_session->multipacket[branch] = false; - if(PTR_IS_OK(ptr)) - { - flags = get_response_flags(ptr,true); - more_results = (flags & 0x08) && my_session->client_multistatement; - if(more_results) - { - MXS_INFO("Tee: [%s] waiting for more results.",branch == PARENT ? "PARENT":"CHILD"); - } - } - } + MXS_INFO("Tee: First reply to a query for [%s].", branch == PARENT ? "PARENT" : "CHILD"); + /* Reply is in a single packet if it is an OK, ERR or LOCAL_INFILE packet. + * Otherwise the reply is a result set and the amount of packets is unknown. + */ + if (PTR_IS_ERR(ptr) || PTR_IS_LOCAL_INFILE(ptr) || + PTR_IS_OK(ptr) || !my_session->multipacket[branch]) + { + my_session->waiting[branch] = false; + my_session->multipacket[branch] = false; + if (PTR_IS_OK(ptr)) + { + flags = get_response_flags(ptr, true); + more_results = (flags & 0x08) && my_session->client_multistatement; + if (more_results) + { + MXS_INFO("Tee: [%s] waiting for more results.", branch == PARENT ? "PARENT" : "CHILD"); + } + } + } #ifdef SS_DEBUG - else - { - MXS_DEBUG("tee.c: [%ld] Waiting for a result set from %s session.", + else + { + MXS_DEBUG("tee.c: [%ld] Waiting for a result set from %s session.", my_session->d_id, - branch == PARENT?"parent":"child"); - } + branch == PARENT ? "parent" : "child"); + } #endif } - if(my_session->waiting[branch]) + if (my_session->waiting[branch]) { - eof = modutil_count_signal_packets(complete,my_session->use_ok,my_session->eof[branch] > 0,&more_results); - more_results &= my_session->client_multistatement; - my_session->eof[branch] += eof; + eof = modutil_count_signal_packets(complete, my_session->use_ok, my_session->eof[branch] > 0, &more_results); + more_results &= my_session->client_multistatement; + my_session->eof[branch] += eof; - if(my_session->eof[branch] >= min_eof) - { + if (my_session->eof[branch] >= min_eof) + { #ifdef SS_DEBUG - MXS_DEBUG("tee.c [%ld] %s received last EOF packet", + MXS_DEBUG("tee.c [%ld] %s received last EOF packet", my_session->d_id, - branch == PARENT?"parent":"child"); + branch == PARENT ? "parent" : "child"); #endif - my_session->waiting[branch] = more_results; - if(more_results) - { - my_session->eof[branch] = 0; - } - } + my_session->waiting[branch] = more_results; + if (more_results) + { + my_session->eof[branch] = 0; + } + } } - if(branch == PARENT) + if (branch == PARENT) { - my_session->tee_replybuf = gwbuf_append(my_session->tee_replybuf,complete); + my_session->tee_replybuf = gwbuf_append(my_session->tee_replybuf, complete); } else { - gwbuf_free(complete); + gwbuf_free(complete); } my_session->replies[branch]++; rc = 1; mpkt = my_session->multipacket[PARENT] || my_session->multipacket[CHILD]; - if(my_session->tee_replybuf != NULL) - { + if (my_session->tee_replybuf != NULL) + { - if(my_session->branch_session == NULL) - { - rc = 0; - gwbuf_free(my_session->tee_replybuf); - my_session->tee_replybuf = NULL; - MXS_ERROR("Tee child session was closed."); - } + if (my_session->branch_session == NULL) + { + rc = 0; + gwbuf_free(my_session->tee_replybuf); + my_session->tee_replybuf = NULL; + MXS_ERROR("Tee child session was closed."); + } - if(mpkt) - { + if (mpkt) + { - if(my_session->waiting[PARENT]) - { - route = true; + if (my_session->waiting[PARENT]) + { + route = true; - } - else if(my_session->eof[PARENT] >= min_eof && - my_session->eof[CHILD] >= min_eof) - { - route = true; + } + else if (my_session->eof[PARENT] >= min_eof && + my_session->eof[CHILD] >= min_eof) + { + route = true; #ifdef SS_DEBUG - MXS_DEBUG("tee.c:[%ld] Routing final packet of response set.",my_session->d_id); + MXS_DEBUG("tee.c:[%ld] Routing final packet of response set.", my_session->d_id); #endif - } - } - else if(!my_session->waiting[PARENT] && - !my_session->waiting[CHILD]) - { + } + } + else if (!my_session->waiting[PARENT] && + !my_session->waiting[CHILD]) + { #ifdef SS_DEBUG - MXS_DEBUG("tee.c:[%ld] Routing single packet response.",my_session->d_id); + MXS_DEBUG("tee.c:[%ld] Routing single packet response.", my_session->d_id); #endif - route = true; - } + route = true; + } } - if(route) + if (route) { #ifdef SS_DEBUG - MXS_DEBUG("tee.c:[%ld] Routing buffer '%p' parent(waiting [%s] replies [%d] eof[%d])" + MXS_DEBUG("tee.c:[%ld] Routing buffer '%p' parent(waiting [%s] replies [%d] eof[%d])" " child(waiting [%s] replies[%d] eof [%d])", - my_session->d_id, - my_session->tee_replybuf, - my_session->waiting[PARENT] ? "true":"false", - my_session->replies[PARENT], - my_session->eof[PARENT], - my_session->waiting[CHILD]?"true":"false", - my_session->replies[CHILD], - my_session->eof[CHILD]); + my_session->d_id, + my_session->tee_replybuf, + my_session->waiting[PARENT] ? "true" : "false", + my_session->replies[PARENT], + my_session->eof[PARENT], + my_session->waiting[CHILD] ? "true" : "false", + my_session->replies[CHILD], + my_session->eof[CHILD]); #endif - - rc = my_session->up.clientReply (my_session->up.instance, - my_session->up.session, - my_session->tee_replybuf); - my_session->tee_replybuf = NULL; + + rc = my_session->up.clientReply(my_session->up.instance, + my_session->up.session, + my_session->tee_replybuf); + my_session->tee_replybuf = NULL; } - if(my_session->queue && - !my_session->waiting[PARENT] && - !my_session->waiting[CHILD]) + if (my_session->queue && + !my_session->waiting[PARENT] && + !my_session->waiting[CHILD]) { - GWBUF* buffer = modutil_get_next_MySQL_packet(&my_session->queue); - GWBUF* clone = clone_query(my_session->instance,my_session,buffer); - reset_session_state(my_session,buffer); - route_single_query(my_session->instance,my_session,buffer,clone); - MXS_INFO("tee: routing queued query"); + GWBUF* buffer = modutil_get_next_MySQL_packet(&my_session->queue); + GWBUF* clone = clone_query(my_session->instance, my_session, buffer); + reset_session_state(my_session, buffer); + route_single_query(my_session->instance, my_session, buffer, clone); + MXS_INFO("tee: routing queued query"); } - retblock: +retblock: spinlock_release(&my_session->tee_lock); - + return rc; } @@ -1095,33 +1122,41 @@ clientReply (FILTER* instance, void *session, GWBUF *reply) * @param fsession Filter session, may be NULL * @param dcb The DCB for diagnostic output */ -static void +static void diagnostic(FILTER *instance, void *fsession, DCB *dcb) { -TEE_INSTANCE *my_instance = (TEE_INSTANCE *)instance; -TEE_SESSION *my_session = (TEE_SESSION *)fsession; + TEE_INSTANCE *my_instance = (TEE_INSTANCE *) instance; + TEE_SESSION *my_session = (TEE_SESSION *) fsession; - if (my_instance->source) - dcb_printf(dcb, "\t\tLimit to connections from %s\n", - my_instance->source); - dcb_printf(dcb, "\t\tDuplicate statements to service %s\n", - my_instance->service->name); - if (my_instance->userName) - dcb_printf(dcb, "\t\tLimit to user %s\n", - my_instance->userName); - if (my_instance->match) - dcb_printf(dcb, "\t\tInclude queries that match %s\n", - my_instance->match); - if (my_instance->nomatch) - dcb_printf(dcb, "\t\tExclude queries that match %s\n", - my_instance->nomatch); - if (my_session) - { - dcb_printf(dcb, "\t\tNo. of statements duplicated: %d.\n", - my_session->n_duped); - dcb_printf(dcb, "\t\tNo. of statements rejected: %d.\n", - my_session->n_rejected); - } + if (my_instance->source) + { + dcb_printf(dcb, "\t\tLimit to connections from %s\n", + my_instance->source); + } + dcb_printf(dcb, "\t\tDuplicate statements to service %s\n", + my_instance->service->name); + if (my_instance->userName) + { + dcb_printf(dcb, "\t\tLimit to user %s\n", + my_instance->userName); + } + if (my_instance->match) + { + dcb_printf(dcb, "\t\tInclude queries that match %s\n", + my_instance->match); + } + if (my_instance->nomatch) + { + dcb_printf(dcb, "\t\tExclude queries that match %s\n", + my_instance->nomatch); + } + if (my_session) + { + dcb_printf(dcb, "\t\tNo. of statements duplicated: %d.\n", + my_session->n_duped); + dcb_printf(dcb, "\t\tNo. of statements rejected: %d.\n", + my_session->n_rejected); + } } /** @@ -1135,46 +1170,52 @@ TEE_SESSION *my_session = (TEE_SESSION *)fsession; static int packet_is_required(GWBUF *queue) { -uint8_t *ptr; -int i; + uint8_t *ptr; + int i; - ptr = GWBUF_DATA(queue); - if (GWBUF_LENGTH(queue) > 4) - for (i = 0; required_packets[i]; i++) - if (ptr[4] == required_packets[i]) - return 1; - return 0; + ptr = GWBUF_DATA(queue); + if (GWBUF_LENGTH(queue) > 4) + { + for (i = 0; required_packets[i]; i++) + { + if (ptr[4] == required_packets[i]) + { + return 1; + } + } + } + return 0; } /** * Detects possible loops in the query cloning chain. */ -int detect_loops(TEE_INSTANCE *instance,HASHTABLE* ht, SERVICE* service) +int detect_loops(TEE_INSTANCE *instance, HASHTABLE* ht, SERVICE* service) { SERVICE* svc = service; int i; - if(ht == NULL) + if (ht == NULL) { return -1; } - if(hashtable_add(ht,(void*)service->name,(void*)true) == 0) + if (hashtable_add(ht, (void*) service->name, (void*) true) == 0) { return true; } - - for(i = 0;in_filters;i++) + + for (i = 0; i < svc->n_filters; i++) { - if(strcmp(svc->filters[i]->module,"tee") == 0) + if (strcmp(svc->filters[i]->module, "tee") == 0) { /* * Found a Tee filter, recurse down its path * if the service name isn't already in the hashtable. */ - TEE_INSTANCE* ninst = (TEE_INSTANCE*)svc->filters[i]->filter; - if(ninst == NULL) + TEE_INSTANCE* ninst = (TEE_INSTANCE*) svc->filters[i]->filter; + if (ninst == NULL) { /** * This tee instance hasn't been initialized yet and full @@ -1184,14 +1225,14 @@ int detect_loops(TEE_INSTANCE *instance,HASHTABLE* ht, SERVICE* service) } SERVICE* tgt = ninst->service; - if(detect_loops((TEE_INSTANCE*)svc->filters[i]->filter,ht,tgt)) + if (detect_loops((TEE_INSTANCE*) svc->filters[i]->filter, ht, tgt)) { return true; } - + } } - + return false; } @@ -1202,7 +1243,7 @@ int internal_route(DCB* dcb) /** This was set in the newSession function*/ TEE_SESSION* session = dcb->data; - return routeQuery((FILTER*)session->instance,session,buffer); + return routeQuery((FILTER*) session->instance, session, buffer); } /** @@ -1217,42 +1258,42 @@ GWBUF* clone_query(TEE_INSTANCE* my_instance, TEE_SESSION* my_session, GWBUF* bu GWBUF* clone = NULL; int residual = 0; char* ptr; - - if (my_session->branch_session && - my_session->branch_session->state == SESSION_STATE_ROUTER_READY) - { - if (my_session->residual) - { - clone = gwbuf_clone_all(buffer); - if (my_session->residual < GWBUF_LENGTH(clone)) - { - GWBUF_RTRIM(clone, GWBUF_LENGTH(clone) - residual); - } - my_session->residual -= GWBUF_LENGTH(clone); + if (my_session->branch_session && + my_session->branch_session->state == SESSION_STATE_ROUTER_READY) + { + if (my_session->residual) + { + clone = gwbuf_clone_all(buffer); - if (my_session->residual < 0) - { - my_session->residual = 0; - } - } - else if (my_session->active && (ptr = modutil_get_SQL(buffer)) != NULL) - { - if ((my_instance->match == NULL || - regexec(&my_instance->re, ptr, 0, NULL, 0) == 0) && - (my_instance->nomatch == NULL || - regexec(&my_instance->nore,ptr,0,NULL, 0) != 0)) - { - clone = gwbuf_clone_all(buffer); - my_session->residual = residual; - } - free(ptr); - } - else if (packet_is_required(buffer)) - { - clone = gwbuf_clone_all(buffer); - } - } + if (my_session->residual < GWBUF_LENGTH(clone)) + { + GWBUF_RTRIM(clone, GWBUF_LENGTH(clone) - residual); + } + my_session->residual -= GWBUF_LENGTH(clone); + + if (my_session->residual < 0) + { + my_session->residual = 0; + } + } + else if (my_session->active && (ptr = modutil_get_SQL(buffer)) != NULL) + { + if ((my_instance->match == NULL || + regexec(&my_instance->re, ptr, 0, NULL, 0) == 0) && + (my_instance->nomatch == NULL || + regexec(&my_instance->nore, ptr, 0, NULL, 0) != 0)) + { + clone = gwbuf_clone_all(buffer); + my_session->residual = residual; + } + free(ptr); + } + else if (packet_is_required(buffer)) + { + clone = gwbuf_clone_all(buffer); + } + } return clone; } @@ -1269,43 +1310,43 @@ GWBUF* clone_query(TEE_INSTANCE* my_instance, TEE_SESSION* my_session, GWBUF* bu int route_single_query(TEE_INSTANCE* my_instance, TEE_SESSION* my_session, GWBUF* buffer, GWBUF* clone) { int rval = 0; - if(!my_session->active || - my_session->branch_session == NULL || - my_session->branch_session->state != SESSION_STATE_ROUTER_READY) + if (!my_session->active || + my_session->branch_session == NULL || + my_session->branch_session->state != SESSION_STATE_ROUTER_READY) { - rval = 0; - my_session->active = 0; - return rval; + rval = 0; + my_session->active = 0; + return rval; } rval = my_session->down.routeQuery(my_session->down.instance, - my_session->down.session, - buffer); + my_session->down.session, + buffer); if (clone) { - my_session->n_duped++; + my_session->n_duped++; - if (my_session->branch_session->state == SESSION_STATE_ROUTER_READY) - { - SESSION_ROUTE_QUERY(my_session->branch_session, clone); - } - else - { - /** Close tee session */ - my_session->active = 0; - rval = 0; - MXS_INFO("Closed tee filter session: Child session in invalid state."); - gwbuf_free(clone); - } + if (my_session->branch_session->state == SESSION_STATE_ROUTER_READY) + { + SESSION_ROUTE_QUERY(my_session->branch_session, clone); + } + else + { + /** Close tee session */ + my_session->active = 0; + rval = 0; + MXS_INFO("Closed tee filter session: Child session in invalid state."); + gwbuf_free(clone); + } } else { - if (my_session->active) - { - MXS_INFO("Closed tee filter session: Child session is NULL."); - my_session->active = 0; - rval = 0; - } - my_session->n_rejected++; + if (my_session->active) + { + MXS_INFO("Closed tee filter session: Child session is NULL."); + my_session->active = 0; + rval = 0; + } + my_session->n_rejected++; } return rval; } @@ -1318,47 +1359,51 @@ int route_single_query(TEE_INSTANCE* my_instance, TEE_SESSION* my_session, GWBUF */ int reset_session_state(TEE_SESSION* my_session, GWBUF* buffer) { - if(gwbuf_length(buffer) < 5) - return 0; + if (gwbuf_length(buffer) < 5) + { + return 0; + } - unsigned char command = *((unsigned char*)buffer->start + 4); + unsigned char command = *((unsigned char*) buffer->start + 4); - switch(command) - { - case 0x1b: - my_session->client_multistatement = *((unsigned char*) buffer->start + 5); - MXS_INFO("tee: client %s multistatements", - my_session->client_multistatement ? "enabled":"disabled"); + switch (command) + { + case 0x1b: + my_session->client_multistatement = *((unsigned char*) buffer->start + 5); + MXS_INFO("tee: client %s multistatements", + my_session->client_multistatement ? "enabled" : "disabled"); case 0x03: case 0x16: case 0x17: case 0x04: case 0x0a: - memset(my_session->multipacket,(char)true,2*sizeof(bool)); + memset(my_session->multipacket, (char) true, 2 * sizeof(bool)); break; default: - memset(my_session->multipacket,(char)false,2*sizeof(bool)); + memset(my_session->multipacket, (char) false, 2 * sizeof(bool)); break; - } + } - memset(my_session->replies,0,2*sizeof(int)); - memset(my_session->reply_packets,0,2*sizeof(int)); - memset(my_session->eof,0,2*sizeof(int)); - memset(my_session->waiting,1,2*sizeof(bool)); - my_session->command = command; + memset(my_session->replies, 0, 2 * sizeof(int)); + memset(my_session->reply_packets, 0, 2 * sizeof(int)); + memset(my_session->eof, 0, 2 * sizeof(int)); + memset(my_session->waiting, 1, 2 * sizeof(bool)); + my_session->command = command; - return 1; + return 1; } void create_orphan(SESSION* ses) { orphan_session_t* orphan; - if((orphan = malloc(sizeof(orphan_session_t))) == NULL) + if ((orphan = malloc(sizeof(orphan_session_t))) == NULL) { MXS_ERROR("Failed to " "allocate memory for orphan session struct, " "child session might leak memory."); - }else{ + } + else + { orphan->session = ses; spinlock_acquire(&orphanLock); orphan->next = allOrphans; From 036fd6f16ce7defb4d79cb5bcf2cd8d437abdf68 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Wed, 18 Nov 2015 14:31:02 +0200 Subject: [PATCH 08/21] Formatted qlafilter Qlafilter formatted according to the style guide. --- server/modules/filter/qlafilter.c | 539 ++++++++++++++++-------------- 1 file changed, 284 insertions(+), 255 deletions(-) diff --git a/server/modules/filter/qlafilter.c b/server/modules/filter/qlafilter.c index 1b72326ea..89adf4849 100644 --- a/server/modules/filter/qlafilter.c +++ b/server/modules/filter/qlafilter.c @@ -31,13 +31,14 @@ * file to which the queries are logged. A serial number is appended to this * name in order that each session logs to a different file. * - * Date Who Description - * 03/06/2014 Mark Riddoch Initial implementation - * 11/06/2014 Mark Riddoch Addition of source and match parameters - * 19/06/2014 Mark Riddoch Addition of user parameter + * Date Who Description + * 03/06/2014 Mark Riddoch Initial implementation + * 11/06/2014 Mark Riddoch Addition of source and match parameters + * 19/06/2014 Mark Riddoch Addition of user parameter * * @endverbatim */ + #include #include #include @@ -52,11 +53,12 @@ #include #include -MODULE_INFO info = { - MODULE_API_FILTER, - MODULE_GA, - FILTER_VERSION, - "A simple query logging filter" +MODULE_INFO info = +{ + MODULE_API_FILTER, + MODULE_GA, + FILTER_VERSION, + "A simple query logging filter" }; static char *version_str = "V1.1.1"; @@ -64,24 +66,25 @@ static char *version_str = "V1.1.1"; /* * The filter entry points */ -static FILTER *createInstance(char **options, FILTER_PARAMETER **); -static void *newSession(FILTER *instance, SESSION *session); -static void closeSession(FILTER *instance, void *session); -static void freeSession(FILTER *instance, void *session); -static void setDownstream(FILTER *instance, void *fsession, DOWNSTREAM *downstream); -static int routeQuery(FILTER *instance, void *fsession, GWBUF *queue); -static void diagnostic(FILTER *instance, void *fsession, DCB *dcb); +static FILTER *createInstance(char **options, FILTER_PARAMETER **); +static void *newSession(FILTER *instance, SESSION *session); +static void closeSession(FILTER *instance, void *session); +static void freeSession(FILTER *instance, void *session); +static void setDownstream(FILTER *instance, void *fsession, DOWNSTREAM *downstream); +static int routeQuery(FILTER *instance, void *fsession, GWBUF *queue); +static void diagnostic(FILTER *instance, void *fsession, DCB *dcb); -static FILTER_OBJECT MyObject = { +static FILTER_OBJECT MyObject = +{ createInstance, newSession, closeSession, freeSession, setDownstream, - NULL, // No Upstream requirement + NULL, // No Upstream requirement routeQuery, - NULL, // No client reply + NULL, // No client reply diagnostic, }; @@ -93,30 +96,32 @@ static FILTER_OBJECT MyObject = { * To this base a session number is attached such that each session will * have a unique name. */ -typedef struct { - int sessions; /* The count of sessions */ - char *filebase; /* The filename base */ - char *source; /* The source of the client connection */ - char *userName; /* The user name to filter on */ - char *match; /* Optional text to match against */ - regex_t re; /* Compiled regex text */ - char *nomatch; /* Optional text to match against for exclusion */ - regex_t nore; /* Compiled regex nomatch text */ +typedef struct +{ + int sessions; /* The count of sessions */ + char *filebase; /* The filename base */ + char *source; /* The source of the client connection */ + char *userName; /* The user name to filter on */ + char *match; /* Optional text to match against */ + regex_t re; /* Compiled regex text */ + char *nomatch; /* Optional text to match against for exclusion */ + regex_t nore; /* Compiled regex nomatch text */ } QLA_INSTANCE; /** * The session structure for this QLA filter. - * This stores the downstream filter information, such that the + * This stores the downstream filter information, such that the * filter is able to pass the query on to the next filter (or router) * in the chain. * * It also holds the file descriptor to which queries are written. */ -typedef struct { - DOWNSTREAM down; - char *filename; - FILE *fp; - int active; +typedef struct +{ + DOWNSTREAM down; + char *filename; + FILE *fp; + int active; } QLA_SESSION; /** @@ -127,7 +132,7 @@ typedef struct { char * version() { - return version_str; + return version_str; } /** @@ -150,100 +155,112 @@ ModuleInit() FILTER_OBJECT * GetModuleObject() { - return &MyObject; + return &MyObject; } /** * Create an instance of the filter for a particular service * within MaxScale. - * - * @param options The options for this filter - * @param params The array of name/value pair parameters for the filter + * + * @param options The options for this filter + * @param params The array of name/value pair parameters for the filter * * @return The instance data for this new instance */ -static FILTER * +static FILTER * createInstance(char **options, FILTER_PARAMETER **params) { -QLA_INSTANCE *my_instance; -int i; + QLA_INSTANCE *my_instance; + int i; - if ((my_instance = calloc(1, sizeof(QLA_INSTANCE))) != NULL) - { - if (options){ - my_instance->filebase = strdup(options[0]); - }else{ - my_instance->filebase = strdup("qla"); - } - my_instance->source = NULL; - my_instance->userName = NULL; - my_instance->match = NULL; - my_instance->nomatch = NULL; - if (params) - { - for (i = 0; params[i]; i++) - { - if (!strcmp(params[i]->name, "match")) - { - my_instance->match = strdup(params[i]->value); - } - else if (!strcmp(params[i]->name, "exclude")) - { - my_instance->nomatch = strdup(params[i]->value); - } - else if (!strcmp(params[i]->name, "source")) - my_instance->source = strdup(params[i]->value); - else if (!strcmp(params[i]->name, "user")) - my_instance->userName = strdup(params[i]->value); - else if (!strcmp(params[i]->name, "filebase")) - { - if (my_instance->filebase){ - free(my_instance->filebase); - my_instance->filebase = NULL; - } - my_instance->filebase = strdup(params[i]->value); - } - else if (!filter_standard_parameter(params[i]->name)) - { - MXS_ERROR("qlafilter: Unexpected parameter '%s'.", - params[i]->name); - } - } - } - my_instance->sessions = 0; - if (my_instance->match && - regcomp(&my_instance->re, my_instance->match, REG_ICASE)) - { - MXS_ERROR("qlafilter: Invalid regular expression '%s'" - " for the match parameter.\n", - my_instance->match); - free(my_instance->match); - free(my_instance->source); - if(my_instance->filebase){ + if ((my_instance = calloc(1, sizeof(QLA_INSTANCE))) != NULL) + { + if (options) + { + my_instance->filebase = strdup(options[0]); + } + else + { + my_instance->filebase = strdup("qla"); + } + my_instance->source = NULL; + my_instance->userName = NULL; + my_instance->match = NULL; + my_instance->nomatch = NULL; + if (params) + { + for (i = 0; params[i]; i++) + { + if (!strcmp(params[i]->name, "match")) + { + my_instance->match = strdup(params[i]->value); + } + else if (!strcmp(params[i]->name, "exclude")) + { + my_instance->nomatch = strdup(params[i]->value); + } + else if (!strcmp(params[i]->name, "source")) + { + my_instance->source = strdup(params[i]->value); + } + else if (!strcmp(params[i]->name, "user")) + { + my_instance->userName = strdup(params[i]->value); + } + else if (!strcmp(params[i]->name, "filebase")) + { + if (my_instance->filebase) + { free(my_instance->filebase); + my_instance->filebase = NULL; } - free(my_instance); - return NULL; - } - if (my_instance->nomatch && - regcomp(&my_instance->nore, my_instance->nomatch, - REG_ICASE)) - { + my_instance->filebase = strdup(params[i]->value); + } + else if (!filter_standard_parameter(params[i]->name)) + { + MXS_ERROR("qlafilter: Unexpected parameter '%s'.", + params[i]->name); + } + } + } + my_instance->sessions = 0; + if (my_instance->match && + regcomp(&my_instance->re, my_instance->match, REG_ICASE)) + { + MXS_ERROR("qlafilter: Invalid regular expression '%s'" + " for the match parameter.\n", + my_instance->match); + free(my_instance->match); + free(my_instance->source); + if (my_instance->filebase) + { + free(my_instance->filebase); + } + free(my_instance); + return NULL; + } + if (my_instance->nomatch && + regcomp(&my_instance->nore, my_instance->nomatch, + REG_ICASE)) + { MXS_ERROR("qlafilter: Invalid regular expression '%s'" " for the nomatch paramter.", my_instance->match); - if (my_instance->match) - regfree(&my_instance->re); - free(my_instance->match); - free(my_instance->source); - if(my_instance->filebase){ - free(my_instance->filebase); - } - free(my_instance); - return NULL; - } - } - return (FILTER *)my_instance; + if (my_instance->match) + { + regfree(&my_instance->re); + } + free(my_instance->match); + free(my_instance->source); + if (my_instance->filebase) + { + free(my_instance->filebase); + } + free(my_instance); + return NULL; + } + } + return(FILTER *) my_instance; } /** @@ -251,80 +268,82 @@ int i; * * Create the file to log to and open it. * - * @param instance The filter instance data - * @param session The session itself + * @param instance The filter instance data + * @param session The session itself * @return Session specific data for this session */ -static void * +static void * newSession(FILTER *instance, SESSION *session) { -QLA_INSTANCE *my_instance = (QLA_INSTANCE *)instance; -QLA_SESSION *my_session; -char *remote, *userName; + QLA_INSTANCE *my_instance = (QLA_INSTANCE *) instance; + QLA_SESSION *my_session; + char *remote, *userName; - if ((my_session = calloc(1, sizeof(QLA_SESSION))) != NULL) - { - if ((my_session->filename = - (char *)malloc(strlen(my_instance->filebase) + 20)) - == NULL) - { - char errbuf[STRERROR_BUFLEN]; - MXS_ERROR("Memory allocation for qla filter " - "file name failed due to %d, %s.", - errno, - strerror_r(errno, errbuf, sizeof(errbuf))); - free(my_session); - return NULL; - } - my_session->active = 1; - - if (my_instance->source - && (remote = session_get_remote(session)) != NULL) - { - if (strcmp(remote, my_instance->source)) - my_session->active = 0; - } - userName = session_getUser(session); - - if (my_instance->userName && - userName && - strcmp(userName,my_instance->userName)) - { - my_session->active = 0; - } - sprintf(my_session->filename, "%s.%d", - my_instance->filebase, - my_instance->sessions); + if ((my_session = calloc(1, sizeof(QLA_SESSION))) != NULL) + { + if ((my_session->filename = + (char *) malloc(strlen(my_instance->filebase) + 20)) + == NULL) + { + char errbuf[STRERROR_BUFLEN]; + MXS_ERROR("Memory allocation for qla filter " + "file name failed due to %d, %s.", + errno, + strerror_r(errno, errbuf, sizeof(errbuf))); + free(my_session); + return NULL; + } + my_session->active = 1; + + if (my_instance->source + && (remote = session_get_remote(session)) != NULL) + { + if (strcmp(remote, my_instance->source)) + { + my_session->active = 0; + } + } + userName = session_getUser(session); + + if (my_instance->userName && + userName && + strcmp(userName, my_instance->userName)) + { + my_session->active = 0; + } + sprintf(my_session->filename, "%s.%d", + my_instance->filebase, + my_instance->sessions); // Multiple sessions can try to update my_instance->sessions simultaneously - atomic_add(&(my_instance->sessions), 1); - - if (my_session->active) - { - my_session->fp = fopen(my_session->filename, "w"); - - if (my_session->fp == NULL) - { - char errbuf[STRERROR_BUFLEN]; - MXS_ERROR("Opening output file for qla " - "fileter failed due to %d, %s", - errno, - strerror_r(errno, errbuf, sizeof(errbuf))); - free(my_session->filename); - free(my_session); - my_session = NULL; - } - } - } - else - { + atomic_add(&(my_instance->sessions), 1); + + if (my_session->active) + { + my_session->fp = fopen(my_session->filename, "w"); + + if (my_session->fp == NULL) + { char errbuf[STRERROR_BUFLEN]; - MXS_ERROR("Memory allocation for qla filter failed due to " - "%d, %s.", + MXS_ERROR("Opening output file for qla " + "fileter failed due to %d, %s", errno, strerror_r(errno, errbuf, sizeof(errbuf))); - } - return my_session; + free(my_session->filename); + free(my_session); + my_session = NULL; + } + } + } + else + { + char errbuf[STRERROR_BUFLEN]; + MXS_ERROR("Memory allocation for qla filter failed due to " + "%d, %s.", + errno, + strerror_r(errno, errbuf, sizeof(errbuf))); + } + return my_session; } /** @@ -332,48 +351,50 @@ char *remote, *userName; * by which a filter may cleanup data structure etc. * In the case of the QLA filter we simple close the file descriptor. * - * @param instance The filter instance data - * @param session The session being closed + * @param instance The filter instance data + * @param session The session being closed */ -static void +static void closeSession(FILTER *instance, void *session) { -QLA_SESSION *my_session = (QLA_SESSION *)session; + QLA_SESSION *my_session = (QLA_SESSION *) session; - if (my_session->active && my_session->fp) - fclose(my_session->fp); + if (my_session->active && my_session->fp) + { + fclose(my_session->fp); + } } /** * Free the memory associated with the session * - * @param instance The filter instance - * @param session The filter session + * @param instance The filter instance + * @param session The filter session */ static void freeSession(FILTER *instance, void *session) { -QLA_SESSION *my_session = (QLA_SESSION *)session; + QLA_SESSION *my_session = (QLA_SESSION *) session; - free(my_session->filename); - free(session); - return; + free(my_session->filename); + free(session); + return; } /** * Set the downstream filter or router to which queries will be * passed from this filter. * - * @param instance The filter instance data - * @param session The filter session - * @param downstream The downstream filter or router. + * @param instance The filter instance data + * @param session The filter session + * @param downstream The downstream filter or router. */ static void setDownstream(FILTER *instance, void *session, DOWNSTREAM *downstream) { -QLA_SESSION *my_session = (QLA_SESSION *)session; + QLA_SESSION *my_session = (QLA_SESSION *) session; - my_session->down = *downstream; + my_session->down = *downstream; } /** @@ -382,48 +403,48 @@ QLA_SESSION *my_session = (QLA_SESSION *)session; * query should normally be passed to the downstream component * (filter or router) in the filter chain. * - * @param instance The filter instance data - * @param session The filter session - * @param queue The query data + * @param instance The filter instance data + * @param session The filter session + * @param queue The query data */ -static int +static int 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 = 0; -struct tm t; -struct timeval tv; + QLA_INSTANCE *my_instance = (QLA_INSTANCE *) instance; + QLA_SESSION *my_session = (QLA_SESSION *) session; + char *ptr; + int length = 0; + struct tm t; + struct timeval tv; - if (my_session->active) - { - if (queue->next != NULL) - { - queue = gwbuf_make_contiguous(queue); - } - if ((ptr = modutil_get_SQL(queue)) != NULL) - { - if ((my_instance->match == NULL || - regexec(&my_instance->re, ptr, 0, NULL, 0) == 0) && - (my_instance->nomatch == NULL || - regexec(&my_instance->nore,ptr,0,NULL, 0) != 0)) - { - gettimeofday(&tv, NULL); - localtime_r(&tv.tv_sec, &t); - fprintf(my_session->fp, - "%02d:%02d:%02d.%-3d %d/%02d/%d, ", - t.tm_hour, t.tm_min, t.tm_sec, (int)(tv.tv_usec / 1000), - t.tm_mday, t.tm_mon + 1, 1900 + t.tm_year); - fprintf(my_session->fp,"%s\n",ptr); - - } - free(ptr); - } - } - /* Pass the query downstream */ - return my_session->down.routeQuery(my_session->down.instance, - my_session->down.session, queue); + if (my_session->active) + { + if (queue->next != NULL) + { + queue = gwbuf_make_contiguous(queue); + } + if ((ptr = modutil_get_SQL(queue)) != NULL) + { + if ((my_instance->match == NULL || + regexec(&my_instance->re, ptr, 0, NULL, 0) == 0) && + (my_instance->nomatch == NULL || + regexec(&my_instance->nore, ptr, 0, NULL, 0) != 0)) + { + gettimeofday(&tv, NULL); + localtime_r(&tv.tv_sec, &t); + fprintf(my_session->fp, + "%02d:%02d:%02d.%-3d %d/%02d/%d, ", + t.tm_hour, t.tm_min, t.tm_sec, (int) (tv.tv_usec / 1000), + t.tm_mday, t.tm_mon + 1, 1900 + t.tm_year); + fprintf(my_session->fp, "%s\n", ptr); + + } + free(ptr); + } + } + /* Pass the query downstream */ + return my_session->down.routeQuery(my_session->down.instance, + my_session->down.session, queue); } /** @@ -433,31 +454,39 @@ struct timeval tv; * instance as a whole, otherwise print diagnostics for the * particular session. * - * @param instance The filter instance - * @param fsession Filter session, may be NULL - * @param dcb The DCB for diagnostic output + * @param instance The filter instance + * @param fsession Filter session, may be NULL + * @param dcb The DCB for diagnostic output */ -static void +static void diagnostic(FILTER *instance, void *fsession, DCB *dcb) { -QLA_INSTANCE *my_instance = (QLA_INSTANCE *)instance; -QLA_SESSION *my_session = (QLA_SESSION *)fsession; + QLA_INSTANCE *my_instance = (QLA_INSTANCE *) instance; + QLA_SESSION *my_session = (QLA_SESSION *) fsession; - if (my_session) - { - dcb_printf(dcb, "\t\tLogging to file %s.\n", - my_session->filename); - } - if (my_instance->source) - dcb_printf(dcb, "\t\tLimit logging to connections from %s\n", - my_instance->source); - if (my_instance->userName) - dcb_printf(dcb, "\t\tLimit logging to user %s\n", - my_instance->userName); - if (my_instance->match) - dcb_printf(dcb, "\t\tInclude queries that match %s\n", - my_instance->match); - if (my_instance->nomatch) - dcb_printf(dcb, "\t\tExclude queries that match %s\n", - my_instance->nomatch); + if (my_session) + { + dcb_printf(dcb, "\t\tLogging to file %s.\n", + my_session->filename); + } + if (my_instance->source) + { + dcb_printf(dcb, "\t\tLimit logging to connections from %s\n", + my_instance->source); + } + if (my_instance->userName) + { + dcb_printf(dcb, "\t\tLimit logging to user %s\n", + my_instance->userName); + } + if (my_instance->match) + { + dcb_printf(dcb, "\t\tInclude queries that match %s\n", + my_instance->match); + } + if (my_instance->nomatch) + { + dcb_printf(dcb, "\t\tExclude queries that match %s\n", + my_instance->nomatch); + } } From cbeead7c434ed2abbae1cb7c400dbebb8a995c2a Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Wed, 18 Nov 2015 14:44:05 +0200 Subject: [PATCH 09/21] Formatted namedserverfilter Namedserverfilter formatted according to the style guide. --- server/modules/filter/namedserverfilter.c | 397 +++++++++++----------- 1 file changed, 207 insertions(+), 190 deletions(-) diff --git a/server/modules/filter/namedserverfilter.c b/server/modules/filter/namedserverfilter.c index c634d8198..a7a9a09e2 100644 --- a/server/modules/filter/namedserverfilter.c +++ b/server/modules/filter/namedserverfilter.c @@ -15,6 +15,7 @@ * * Copyright MariaDB Corporation Ab 2014 */ + #include #include #include @@ -32,42 +33,44 @@ * * A simple regular expression based query routing filter. * Two parameters should be defined in the filter configuration - * match= - * server= + * match= + * server= * Two optional parameters - * source= - * user= + * source= + * user= * - * Date Who Description - * 22/01/2015 Mark Riddoch Written as example based on regex filter + * Date Who Description + * 22/01/2015 Mark Riddoch Written as example based on regex filter * @endverbatim */ -MODULE_INFO info = { - MODULE_API_FILTER, - MODULE_GA, - FILTER_VERSION, - "A routing hint filter that uses regular expressions to direct queries" +MODULE_INFO info = +{ + MODULE_API_FILTER, + MODULE_GA, + FILTER_VERSION, + "A routing hint filter that uses regular expressions to direct queries" }; static char *version_str = "V1.1.0"; -static FILTER *createInstance(char **options, FILTER_PARAMETER **params); -static void *newSession(FILTER *instance, SESSION *session); -static void closeSession(FILTER *instance, void *session); -static void freeSession(FILTER *instance, void *session); -static void setDownstream(FILTER *instance, void *fsession, DOWNSTREAM *downstream); -static int routeQuery(FILTER *instance, void *fsession, GWBUF *queue); -static void diagnostic(FILTER *instance, void *fsession, DCB *dcb); +static FILTER *createInstance(char **options, FILTER_PARAMETER **params); +static void *newSession(FILTER *instance, SESSION *session); +static void closeSession(FILTER *instance, void *session); +static void freeSession(FILTER *instance, void *session); +static void setDownstream(FILTER *instance, void *fsession, DOWNSTREAM *downstream); +static int routeQuery(FILTER *instance, void *fsession, GWBUF *queue); +static void diagnostic(FILTER *instance, void *fsession, DCB *dcb); -static FILTER_OBJECT MyObject = { +static FILTER_OBJECT MyObject = +{ createInstance, newSession, closeSession, freeSession, setDownstream, - NULL, // No Upstream requirement + NULL, // No Upstream requirement routeQuery, NULL, diagnostic, @@ -76,23 +79,25 @@ static FILTER_OBJECT MyObject = { /** * Instance structure */ -typedef struct { - char *source; /* Source address to restrict matches */ - char *user; /* User name to restrict matches */ - char *match; /* Regular expression to match */ - char *server; /* Server to route to */ - int cflags; /* Regexec compile flags */ - regex_t re; /* Compiled regex text */ +typedef struct +{ + char *source; /* Source address to restrict matches */ + char *user; /* User name to restrict matches */ + char *match; /* Regular expression to match */ + char *server; /* Server to route to */ + int cflags; /* Regexec compile flags */ + regex_t re; /* Compiled regex text */ } REGEXHINT_INSTANCE; /** * The session structuee for this regex filter */ -typedef struct { - DOWNSTREAM down; /* The downstream filter */ - int n_diverted; /* No. of statements diverted */ - int n_undiverted; /* No. of statements not diverted */ - int active; /* Is filter active */ +typedef struct +{ + DOWNSTREAM down; /* The downstream filter */ + int n_diverted; /* No. of statements diverted */ + int n_undiverted; /* No. of statements not diverted */ + int active; /* Is filter active */ } REGEXHINT_SESSION; /** @@ -103,7 +108,7 @@ typedef struct { char * version() { - return version_str; + return version_str; } /** @@ -126,134 +131,142 @@ ModuleInit() FILTER_OBJECT * GetModuleObject() { - return &MyObject; + return &MyObject; } /** * Create an instance of the filter for a particular service * within MaxScale. - * - * @param options The options for this filter - * @param params The array of name/value pair parameters for the filter + * + * @param options The options for this filter + * @param params The array of name/value pair parameters for the filter * * @return The instance data for this new instance */ -static FILTER * +static FILTER * createInstance(char **options, FILTER_PARAMETER **params) { -REGEXHINT_INSTANCE *my_instance; -int i, cflags = REG_ICASE; + REGEXHINT_INSTANCE *my_instance; + int i, cflags = REG_ICASE; - if ((my_instance = calloc(1, sizeof(REGEXHINT_INSTANCE))) != NULL) - { - my_instance->match = NULL; - my_instance->server = NULL; + if ((my_instance = calloc(1, sizeof(REGEXHINT_INSTANCE))) != NULL) + { + my_instance->match = NULL; + my_instance->server = NULL; - for (i = 0; params && params[i]; i++) - { - if (!strcmp(params[i]->name, "match")) - my_instance->match = strdup(params[i]->value); - else if (!strcmp(params[i]->name, "server")) - my_instance->server = strdup(params[i]->value); - else if (!strcmp(params[i]->name, "source")) - my_instance->source = strdup(params[i]->value); - else if (!strcmp(params[i]->name, "user")) - my_instance->user = strdup(params[i]->value); - else if (!filter_standard_parameter(params[i]->name)) - { - MXS_ERROR("namedserverfilter: Unexpected parameter '%s'.", - params[i]->name); - } - } + for (i = 0; params && params[i]; i++) + { + if (!strcmp(params[i]->name, "match")) + { + my_instance->match = strdup(params[i]->value); + } + else if (!strcmp(params[i]->name, "server")) + { + my_instance->server = strdup(params[i]->value); + } + else if (!strcmp(params[i]->name, "source")) + { + my_instance->source = strdup(params[i]->value); + } + else if (!strcmp(params[i]->name, "user")) + { + my_instance->user = strdup(params[i]->value); + } + else if (!filter_standard_parameter(params[i]->name)) + { + MXS_ERROR("namedserverfilter: Unexpected parameter '%s'.", + params[i]->name); + } + } - if (options) - { - for (i = 0; options[i]; i++) - { - if (!strcasecmp(options[i], "ignorecase")) - { - cflags |= REG_ICASE; - } - else if (!strcasecmp(options[i], "case")) - { - cflags &= ~REG_ICASE; - } - else - { - MXS_ERROR("namedserverfilter: unsupported option '%s'.", - options[i]); - } - } - } - my_instance->cflags = cflags; + if (options) + { + for (i = 0; options[i]; i++) + { + if (!strcasecmp(options[i], "ignorecase")) + { + cflags |= REG_ICASE; + } + else if (!strcasecmp(options[i], "case")) + { + cflags &= ~REG_ICASE; + } + else + { + MXS_ERROR("namedserverfilter: unsupported option '%s'.", + options[i]); + } + } + } + my_instance->cflags = cflags; - if (my_instance->match == NULL || my_instance->server == NULL) - { - MXS_ERROR("namedserverfilter: Missing required configured" - " option. You must specify a match and server " - "option as a minimum."); - free(my_instance); - return NULL; - } + if (my_instance->match == NULL || my_instance->server == NULL) + { + MXS_ERROR("namedserverfilter: Missing required configured" + " option. You must specify a match and server " + "option as a minimum."); + free(my_instance); + return NULL; + } - if (regcomp(&my_instance->re, my_instance->match, - my_instance->cflags)) - { - MXS_ERROR("namedserverfilter: Invalid regular expression '%s'.\n", - my_instance->match); - free(my_instance->match); - free(my_instance->server); - free(my_instance); - return NULL; - } - } - return (FILTER *)my_instance; + if (regcomp(&my_instance->re, my_instance->match, + my_instance->cflags)) + { + MXS_ERROR("namedserverfilter: Invalid regular expression '%s'.\n", + my_instance->match); + free(my_instance->match); + free(my_instance->server); + free(my_instance); + return NULL; + } + } + return(FILTER *) my_instance; } /** * Associate a new session with this instance of the filter. * - * @param instance The filter instance data - * @param session The session itself + * @param instance The filter instance data + * @param session The session itself * @return Session specific data for this session */ -static void * +static void * newSession(FILTER *instance, SESSION *session) { -REGEXHINT_INSTANCE *my_instance = (REGEXHINT_INSTANCE *)instance; -REGEXHINT_SESSION *my_session; -char *remote, *user; + REGEXHINT_INSTANCE *my_instance = (REGEXHINT_INSTANCE *) instance; + REGEXHINT_SESSION *my_session; + char *remote, *user; - if ((my_session = calloc(1, sizeof(REGEXHINT_SESSION))) != NULL) - { - my_session->n_diverted = 0; - my_session->n_undiverted = 0; - my_session->active = 1; - if (my_instance->source - && (remote = session_get_remote(session)) != NULL) - { - if (strcmp(remote, my_instance->source)) - my_session->active = 0; - } + if ((my_session = calloc(1, sizeof(REGEXHINT_SESSION))) != NULL) + { + my_session->n_diverted = 0; + my_session->n_undiverted = 0; + my_session->active = 1; + if (my_instance->source + && (remote = session_get_remote(session)) != NULL) + { + if (strcmp(remote, my_instance->source)) + my_session->active = 0; + } - if (my_instance->user && (user = session_getUser(session)) - && strcmp(user, my_instance->user)) - { - my_session->active = 0; - } - } + if (my_instance->user && (user = session_getUser(session)) + && strcmp(user, my_instance->user)) + { + my_session->active = 0; + } + } - return my_session; + return my_session; } /** * Close a session with the filter, this is the mechanism * by which a filter may cleanup data structure etc. * - * @param instance The filter instance data - * @param session The session being closed + * @param instance The filter instance data + * @param session The session being closed */ -static void +static void closeSession(FILTER *instance, void *session) { } @@ -261,29 +274,28 @@ closeSession(FILTER *instance, void *session) /** * Free the memory associated with this filter session. * - * @param instance The filter instance data - * @param session The session being closed + * @param instance The filter instance data + * @param session The session being closed */ static void freeSession(FILTER *instance, void *session) { - free(session); - return; + free(session); + return; } /** * Set the downstream component for this filter. * - * @param instance The filter instance data - * @param session The session being closed - * @param downstream The downstream filter or router + * @param instance The filter instance data + * @param session The session being closed + * @param downstream The downstream filter or router */ static void setDownstream(FILTER *instance, void *session, DOWNSTREAM *downstream) { -REGEXHINT_SESSION *my_session = (REGEXHINT_SESSION *)session; - - my_session->down = *downstream; + REGEXHINT_SESSION *my_session = (REGEXHINT_SESSION *) session; + my_session->down = *downstream; } /** @@ -296,40 +308,41 @@ REGEXHINT_SESSION *my_session = (REGEXHINT_SESSION *)session; * filter definition matches the SQL text then add the hint * "Route to named server" with the name defined in the server parameter * - * @param instance The filter instance data - * @param session The filter session - * @param queue The query data + * @param instance The filter instance data + * @param session The filter session + * @param queue The query data */ -static int +static int routeQuery(FILTER *instance, void *session, GWBUF *queue) { -REGEXHINT_INSTANCE *my_instance = (REGEXHINT_INSTANCE *)instance; -REGEXHINT_SESSION *my_session = (REGEXHINT_SESSION *)session; -char *sql; + REGEXHINT_INSTANCE *my_instance = (REGEXHINT_INSTANCE *) instance; + REGEXHINT_SESSION *my_session = (REGEXHINT_SESSION *) session; + char *sql; - if (modutil_is_SQL(queue)) - { - if (queue->next != NULL) - { - queue = gwbuf_make_contiguous(queue); - } - if ((sql = modutil_get_SQL(queue)) != NULL) - { - if (regexec(&my_instance->re,sql,0,NULL, 0) == 0) - { - queue->hint = hint_create_route(queue->hint, - HINT_ROUTE_TO_NAMED_SERVER, - my_instance->server); - my_session->n_diverted++; - } - else - my_session->n_undiverted++; - free(sql); - } - - } - return my_session->down.routeQuery(my_session->down.instance, - my_session->down.session, queue); + if (modutil_is_SQL(queue)) + { + if (queue->next != NULL) + { + queue = gwbuf_make_contiguous(queue); + } + if ((sql = modutil_get_SQL(queue)) != NULL) + { + if (regexec(&my_instance->re, sql, 0, NULL, 0) == 0) + { + queue->hint = hint_create_route(queue->hint, + HINT_ROUTE_TO_NAMED_SERVER, + my_instance->server); + my_session->n_diverted++; + } + else + { + my_session->n_undiverted++; + } + free(sql); + } + } + return my_session->down.routeQuery(my_session->down.instance, + my_session->down.session, queue); } /** @@ -339,31 +352,35 @@ char *sql; * instance as a whole, otherwise print diagnostics for the * particular session. * - * @param instance The filter instance - * @param fsession Filter session, may be NULL - * @param dcb The DCB for diagnostic output + * @param instance The filter instance + * @param fsession Filter session, may be NULL + * @param dcb The DCB for diagnostic output */ -static void +static void diagnostic(FILTER *instance, void *fsession, DCB *dcb) { -REGEXHINT_INSTANCE *my_instance = (REGEXHINT_INSTANCE *)instance; -REGEXHINT_SESSION *my_session = (REGEXHINT_SESSION *)fsession; + REGEXHINT_INSTANCE *my_instance = (REGEXHINT_INSTANCE *) instance; + REGEXHINT_SESSION *my_session = (REGEXHINT_SESSION *) fsession; - dcb_printf(dcb, "\t\tMatch and route: /%s/ -> %s\n", - my_instance->match, my_instance->server); - if (my_session) - { - dcb_printf(dcb, "\t\tNo. of queries diverted by filter: %d\n", - my_session->n_diverted); - dcb_printf(dcb, "\t\tNo. of queries not diverted by filter: %d\n", - my_session->n_undiverted); - } - if (my_instance->source) - dcb_printf(dcb, - "\t\tReplacement limited to connections from %s\n", - my_instance->source); - if (my_instance->user) - dcb_printf(dcb, - "\t\tReplacement limit to user %s\n", - my_instance->user); + dcb_printf(dcb, "\t\tMatch and route: /%s/ -> %s\n", + my_instance->match, my_instance->server); + if (my_session) + { + dcb_printf(dcb, "\t\tNo. of queries diverted by filter: %d\n", + my_session->n_diverted); + dcb_printf(dcb, "\t\tNo. of queries not diverted by filter: %d\n", + my_session->n_undiverted); + } + if (my_instance->source) + { + dcb_printf(dcb, + "\t\tReplacement limited to connections from %s\n", + my_instance->source); + } + if (my_instance->user) + { + dcb_printf(dcb, + "\t\tReplacement limit to user %s\n", + my_instance->user); + } } From 3e3770fa820660e370738513238d660b83ff19b0 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Wed, 18 Nov 2015 14:46:24 +0200 Subject: [PATCH 10/21] ss_dassert() no longer uses skygw_log_write. Use of skygw_log_write() in ss_dassert and ss_info_dassert replaced with the use of MXS_ERROR(). In addition, ss_dassert and ss_info_dassert are now expressions that require a trailing ;. --- server/core/test/testusers.c | 2 +- utils/skygw_debug.h | 14 ++++++-------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/server/core/test/testusers.c b/server/core/test/testusers.c index fcc933b1a..efb0a9c87 100644 --- a/server/core/test/testusers.c +++ b/server/core/test/testusers.c @@ -59,7 +59,7 @@ int result, count; "testusers : Initialise the user table."); users = users_alloc(); mxs_log_flush_sync(); - ss_info_dassert(NULL != users, "Allocating user table should not return NULL.") + ss_info_dassert(NULL != users, "Allocating user table should not return NULL."); ss_dfprintf(stderr, "\t..done\nAdd a user"); count = users_add(users, "username", "authorisation"); mxs_log_flush_sync(); diff --git a/utils/skygw_debug.h b/utils/skygw_debug.h index 359d98cdd..7a4a40de6 100644 --- a/utils/skygw_debug.h +++ b/utils/skygw_debug.h @@ -52,14 +52,12 @@ #if defined(SS_DEBUG) && defined(LOG_ASSERT) #include -# define ss_dassert(exp) if(!(exp)){(skygw_log_write(LE,\ - "debug assert %s:%d\n", \ - (char*)__FILE__, \ - __LINE__));mxs_log_flush_sync();assert(exp);} -#define ss_info_dassert(exp,info) if(!(exp)){(skygw_log_write(LE,\ - "debug assert %s:%d %s\n", \ - (char*)__FILE__, \ - __LINE__,info));mxs_log_flush_sync();assert(exp);} +# define ss_dassert(exp) do { if(!(exp)){\ + MXS_ERROR("debug assert %s:%d\n", (char*)__FILE__, __LINE__);\ + mxs_log_flush_sync(); assert(exp);} } while (false) +#define ss_info_dassert(exp,info) do { if(!(exp)){\ + MXS_ERROR("debug assert %s:%d %s\n", (char*)__FILE__, __LINE__, info);\ + mxs_log_flush_sync();assert(exp);} } while (false) # define ss_debug(exp) exp # define ss_dfprintf fprintf # define ss_dfflush fflush From ee7793312b5a5146a96dc6a48da7a8a50d015b0f Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Wed, 18 Nov 2015 20:51:11 +0200 Subject: [PATCH 11/21] Broken error message fixed in readwritesplit.c When converting the skygw_ logging calls to MXS_ equivalents, some part of the error message got lost. --- server/modules/routing/readwritesplit/readwritesplit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index 83204966f..67669d1fa 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -4584,7 +4584,7 @@ static void rwsplit_process_router_options( { if ((value = strchr(options[i], '=')) == NULL) { - MXS_ERROR("router option \"%s\" for " + MXS_ERROR("Unsupported router option \"%s\" for " "readwritesplit router.", options[i]); } From 0345f3622d73b7d4f76714db591d8c3eb70da80a Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Wed, 18 Nov 2015 15:08:50 +0200 Subject: [PATCH 12/21] LOGIF and skygw_log_write removed. All places where LOGIF and skygw_log_write were used have been updated to use the new logging macros instead. Consequently, they can now be removed. --- log_manager/log_manager.cc | 12 ++- log_manager/log_manager.h | 33 ++------ log_manager/test/testlog.c | 160 +++++++++++++++++------------------ log_manager/test/testorder.c | 4 +- 4 files changed, 93 insertions(+), 116 deletions(-) diff --git a/log_manager/log_manager.cc b/log_manager/log_manager.cc index 81b386d66..01a17178d 100644 --- a/log_manager/log_manager.cc +++ b/log_manager/log_manager.cc @@ -2208,13 +2208,11 @@ static bool thr_flush_file(logmanager_t *lm, filewriter_t *fwr) if (!succ) { - 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))); + MXS_ERROR("Log rotation failed. " + "Creating replacement file %s " + "failed. Continuing " + "logging to existing file.", + lf->lf_full_file_name); } return true; } diff --git a/log_manager/log_manager.h b/log_manager/log_manager.h index 2047d8462..751ad8647 100644 --- a/log_manager/log_manager.h +++ b/log_manager/log_manager.h @@ -96,15 +96,6 @@ extern __thread log_info_t tls_log_info; // TODO: Add this at a later stage. #define MXS_LOG_PRIORITY_IS_ENABLED(priority) false -/** - * Execute the given command if specified log is enabled in general or - * if the log is enabled for the current session. - */ -#define LOGIF(id,cmd) if (LOG_IS_ENABLED(id)) \ - { \ - cmd; \ - } - /** * LOG_AUGMENT_WITH_FUNCTION Each logged line is suffixed with [function-name]. */ @@ -130,23 +121,15 @@ void mxs_log_set_augmentation(int bits); int mxs_log_message(int priority, const char* file, int line, const char* function, const char* format, ...) __attribute__((format(printf, 5, 6))); - -inline int mxs_log_id_to_priority(logfile_id_t id) -{ - if (id & LOGFILE_ERROR) return LOG_ERR; - if (id & LOGFILE_MESSAGE) return LOG_NOTICE; - if (id & LOGFILE_TRACE) return LOG_INFO; - if (id & LOGFILE_DEBUG) return LOG_DEBUG; - return LOG_ERR; -} - -#define skygw_log_write(id, format, ...)\ - mxs_log_message(mxs_log_id_to_priority(id), __FILE__, __LINE__, __func__, format, ##__VA_ARGS__) - -#define skygw_log_write_flush(id, format, ...) skygw_log_write(id, format, ##__VA_ARGS__) - /** - * Helper, not to be called directly. + * Log an error, warning, notice, info, or debug message. + * + * @param priority One of the syslog constants (LOG_ERR, LOG_WARNING, ...) + * @param format The printf format of the message. + * @param ... Arguments, depending on the format. + * + * NOTE: Should typically not be called directly. Use some of the + * MXS_ERROR, MXS_WARNING, etc. macros instead. */ #define MXS_LOG_MESSAGE(priority, format, ...)\ mxs_log_message(priority, __FILE__, __LINE__, __func__, format, ##__VA_ARGS__) diff --git a/log_manager/test/testlog.c b/log_manager/test/testlog.c index 6983067ea..38b5e0603 100644 --- a/log_manager/test/testlog.c +++ b/log_manager/test/testlog.c @@ -162,27 +162,26 @@ int main(int argc, char* argv[]) t = time(NULL); tm = *(localtime(&t)); - err = skygw_log_write_flush(LOGFILE_ERROR, - "%04d %02d/%02d %02d.%02d.%02d", - tm.tm_year+1900, - tm.tm_mon+1, - tm.tm_mday, - tm.tm_hour, - tm.tm_min, - tm.tm_sec); + err = MXS_ERROR("%04d %02d/%02d %02d.%02d.%02d", + tm.tm_year+1900, + tm.tm_mon+1, + tm.tm_mday, + tm.tm_hour, + tm.tm_min, + tm.tm_sec); mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); logstr = ("First write with flush."); - err = skygw_log_write_flush(LOGFILE_ERROR, "%s", logstr); + err = MXS_ERROR("%s", logstr); logstr = ("Second write with flush."); - err = skygw_log_write_flush(LOGFILE_ERROR, "%s", logstr); + err = MXS_ERROR("%s", logstr); logstr = ("Third write, no flush."); - err = skygw_log_write(LOGFILE_ERROR, "%s", logstr); + err = MXS_ERROR("%s", logstr); logstr = ("Fourth write, no flush. Next flush only."); - err = skygw_log_write(LOGFILE_ERROR, "%s", logstr); + err = MXS_ERROR("%s", logstr); err = mxs_log_flush(); @@ -190,57 +189,57 @@ int main(int argc, char* argv[]) #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); #endif - err = skygw_log_write(LOGFILE_TRACE, logstr, "TraceyTracey", 3, 7); + err = MXS_INFO(logstr, "TraceyTracey", 3, 7); mxs_log_flush(); #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); #endif logstr = "My name is Tracey Tracey 47 years and 7 months."; - err = skygw_log_write(LOGFILE_TRACE, "%s", logstr); + err = MXS_INFO("%s", logstr); #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); #endif logstr = "My name is Stacey %s"; - err = skygw_log_write_flush(LOGFILE_TRACE, logstr, " "); + err = MXS_INFO(logstr, " "); mxs_log_finish(); #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); #endif logstr = "My name is Philip"; - err = skygw_log_write(LOGFILE_TRACE, "%s", logstr); + err = MXS_INFO("%s", logstr); #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); #endif logstr = "Philip."; - err = skygw_log_write(LOGFILE_TRACE, "%s", logstr); + err = MXS_INFO("%s", logstr); #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); #endif logstr = "Ph%dlip."; - err = skygw_log_write(LOGFILE_TRACE, logstr, 1); + err = MXS_INFO(logstr, 1); mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); logstr = ("A terrible error has occurred!"); - err = skygw_log_write_flush(LOGFILE_ERROR, "%s", logstr); + err = MXS_ERROR("%s", logstr); logstr = ("Hi, how are you?"); - err = skygw_log_write(LOGFILE_MESSAGE, "%s", logstr); + err = MXS_NOTICE("%s", logstr); logstr = ("I'm doing fine!"); - err = skygw_log_write(LOGFILE_MESSAGE, "%s", logstr); + err = MXS_NOTICE("%s", logstr); logstr = ("Rather more surprising, at least at first sight, is the fact that a reference to " "a[i] can also be written as *(a+i). In evaluating a[i], C converts it to *(a+i) " "immediately; the two forms are equivalent. Applying the operators & to both parts " "of this equivalence, it follows that &a[i] and a+i are also identical: a+i is the " "address of the i-th element beyond a."); - err = skygw_log_write(LOGFILE_ERROR, "%s", logstr); + err = MXS_ERROR("%s", logstr); logstr = ("I was wondering, you know, it has been such a lovely weather whole morning and I " "thought that would you like to come to my place and have a little piece of cheese " "with us. Just me and my mom - and you, of course. Then, if you wish, we could " "listen to the radio and keep company for our little Steven, my mom's cat, you know."); - err = skygw_log_write(LOGFILE_MESSAGE, "%s", logstr); + err = MXS_NOTICE("%s", logstr); mxs_log_finish(); #if defined(TEST1) @@ -369,60 +368,60 @@ int main(int argc, char* argv[]) ss_dassert(succp); logstr = ("\tTEST 3 - test enabling and disabling logs."); - err = skygw_log_write(LOGFILE_ERROR, "%s", logstr); + err = MXS_ERROR("%s", logstr); ss_dassert(err == 0); skygw_log_disable(LOGFILE_TRACE); logstr = ("1.\tWrite once to ERROR and twice to MESSAGE log."); - err = skygw_log_write(LOGFILE_MESSAGE, "%s", logstr); + err = MXS_NOTICE("%s", logstr); ss_dassert(err == 0); - err = skygw_log_write(LOGFILE_TRACE, "%s", logstr); + err = MXS_INFO("%s", logstr); ss_dassert(err == 0); - err = skygw_log_write(LOGFILE_ERROR, "%s", logstr); + err = MXS_ERROR("%s", logstr); ss_dassert(err == 0); skygw_log_enable(LOGFILE_TRACE); logstr = ("2.\tWrite to once to ERROR, twice to MESSAGE and " "three times to TRACE log."); - err = skygw_log_write(LOGFILE_MESSAGE, "%s", logstr); + err = MXS_NOTICE("%s", logstr); ss_dassert(err == 0); - err = skygw_log_write(LOGFILE_TRACE, "%s", logstr); + err = MXS_INFO("%s", logstr); ss_dassert(err == 0); - err = skygw_log_write(LOGFILE_ERROR, "%s", logstr); + err = MXS_ERROR("%s", logstr); ss_dassert(err == 0); skygw_log_disable(LOGFILE_ERROR); logstr = ("3.\tWrite to once to MESSAGE and twice to TRACE log."); - err = skygw_log_write(LOGFILE_MESSAGE, "%s", logstr); + err = MXS_NOTICE("%s", logstr); ss_dassert(err == 0); - err = skygw_log_write(LOGFILE_TRACE, "%s", logstr); + err = MXS_INFO("%s", logstr); ss_dassert(err == 0); - err = skygw_log_write(LOGFILE_ERROR, "%s", logstr); + err = MXS_ERROR("%s", logstr); ss_dassert(err == 0); skygw_log_disable(LOGFILE_MESSAGE); skygw_log_disable(LOGFILE_TRACE); logstr = ("4.\tWrite to none."); - err = skygw_log_write(LOGFILE_MESSAGE, "%s", logstr); + err = MXS_NOTICE("%s", logstr); ss_dassert(err == 0); - err = skygw_log_write(LOGFILE_TRACE, "%s", logstr); + err = MXS_INFO("%s", logstr); ss_dassert(err == 0); - err = skygw_log_write(LOGFILE_ERROR, "%s", logstr); + err = MXS_ERROR("%s", logstr); ss_dassert(err == 0); skygw_log_enable(LOGFILE_ERROR); skygw_log_enable(LOGFILE_MESSAGE); logstr = ("4.\tWrite once to ERROR and twice to MESSAGE log."); - err = skygw_log_write(LOGFILE_MESSAGE, "%s", logstr); + err = MXS_NOTICE("%s", logstr); ss_dassert(err == 0); - err = skygw_log_write(LOGFILE_TRACE, "%s", logstr); + err = MXS_INFO("%s", logstr); ss_dassert(err == 0); - err = skygw_log_write(LOGFILE_ERROR, "%s", logstr); + err = MXS_ERROR("%s", logstr); ss_dassert(err == 0); mxs_log_finish(); @@ -436,32 +435,32 @@ int main(int argc, char* argv[]) skygw_log_enable(LOGFILE_TRACE); #endif logstr = ("\tTEST 4 - test spreading logs down to other logs."); - err = skygw_log_write(LOGFILE_ERROR, "%s", logstr); + err = MXS_ERROR("%s", logstr); ss_dassert(err == 0); logstr = ("1.\tWrite to ERROR and thus also to MESSAGE and TRACE logs."); - err = skygw_log_write(LOGFILE_ERROR, "%s", logstr); + err = MXS_ERROR("%s", logstr); ss_dassert(err == 0); logstr = ("2.\tWrite to MESSAGE and thus to TRACE logs."); - err = skygw_log_write(LOGFILE_MESSAGE, "%s", logstr); + err = MXS_NOTICE("%s", logstr); ss_dassert(err == 0); skygw_log_enable(LOGFILE_TRACE); logstr = ("3.\tWrite to TRACE log only."); - err = skygw_log_write(LOGFILE_TRACE, "%s", logstr); + err = MXS_INFO("%s", logstr); ss_dassert(err == 0); skygw_log_disable(LOGFILE_MESSAGE); logstr = ("4.\tWrite to ERROR and thus also to TRACE log. " "MESSAGE is disabled."); - err = skygw_log_write(LOGFILE_ERROR, "%s", logstr); + err = MXS_ERROR("%s", logstr); ss_dassert(err == 0); logstr = ("5.\tThis should not appear anywhere since MESSAGE " "is disabled."); - err = skygw_log_write(LOGFILE_MESSAGE, "%s", logstr); + err = MXS_NOTICE("%s", logstr); ss_dassert(err == 0); mxs_log_finish(); @@ -472,51 +471,48 @@ int main(int argc, char* argv[]) skygw_log_enable(LOGFILE_TRACE); #endif logstr = ("6.\tWrite to ERROR and thus also to MESSAGE and TRACE logs."); - err = skygw_log_write_flush(LOGFILE_ERROR, "%s", logstr); + err = MXS_ERROR("%s", logstr); ss_dassert(err == 0); logstr = ("7.\tWrite to MESSAGE and thus to TRACE logs."); - err = skygw_log_write_flush(LOGFILE_MESSAGE, "%s", logstr); + err = MXS_NOTICE("%s", logstr); ss_dassert(err == 0); logstr = ("8.\tWrite to TRACE log only."); skygw_log_enable(LOGFILE_TRACE); - err = skygw_log_write_flush(LOGFILE_TRACE, "%s", logstr); + err = MXS_INFO("%s", logstr); ss_dassert(err == 0); skygw_log_disable(LOGFILE_MESSAGE); logstr = ("9.\tWrite to ERROR and thus also to TRACE log. " "MESSAGE is disabled"); - err = skygw_log_write_flush(LOGFILE_ERROR, "%s", logstr); + err = MXS_ERROR("%s", logstr); ss_dassert(err == 0); logstr = ("10.\tThis should not appear anywhere since MESSAGE is " "disabled."); - err = skygw_log_write_flush(LOGFILE_MESSAGE, "%s", logstr); + err = MXS_NOTICE("%s", logstr); ss_dassert(err == 0); skygw_log_enable(LOGFILE_MESSAGE); - err = skygw_log_write(LOGFILE_ERROR, - "11.\tWrite to all logs some formattings : " - "%d %s %d", - (int)3, - "foo", - (int)3); - err = skygw_log_write(LOGFILE_MESSAGE, - "12.\tWrite to MESSAGE and TRACE log some " - "formattings " - ": %d %s %d", - (int)3, - "foo", - (int)3); - err = skygw_log_write(LOGFILE_TRACE, - "13.\tWrite to TRACE log some formattings " - ": %d %s %d", - (int)3, - "foo", - (int)3); + err = MXS_ERROR("11.\tWrite to all logs some formattings : " + "%d %s %d", + (int)3, + "foo", + (int)3); + err = MXS_ERROR("12.\tWrite to MESSAGE and TRACE log some " + "formattings " + ": %d %s %d", + (int)3, + "foo", + (int)3); + err = MXS_ERROR("13.\tWrite to TRACE log some formattings " + ": %d %s %d", + (int)3, + "foo", + (int)3); ss_dassert(err == 0); @@ -542,7 +538,7 @@ static void* thr_run(void* data) mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); mxs_log_flush(); logstr = ("Hi, how are you?"); - err = skygw_log_write(LOGFILE_MESSAGE, "%s", logstr); + err = MXS_NOTICE("%s", logstr); if (err != 0) { @@ -561,10 +557,10 @@ static void* thr_run(void* data) TEST_ERROR("Error, log write failed."); } ss_dassert(err == 0); - err = skygw_log_write(LOGFILE_MESSAGE, "%s", logstr); + err = MXS_NOTICE("%s", logstr); mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); logstr = ("Testing. One, two, three\n"); - err = skygw_log_write(LOGFILE_ERROR, "%s", logstr); + err = MXS_ERROR("%s", logstr); if (err != 0) { TEST_ERROR("Error, log write failed."); @@ -578,7 +574,7 @@ static void* thr_run(void* data) #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); #endif - err = skygw_log_write(LOGFILE_TRACE, "%s", logstr); + err = MXS_INFO("%s", logstr); if (err != 0) { TEST_ERROR("Error, log write failed."); @@ -591,7 +587,7 @@ static void* thr_run(void* data) "immediately; the two forms are equivalent. Applying the operatos & to both parts " "of this equivalence, it follows that &a[i] and a+i are also identical: a+i is the " "address of the i-th element beyond a."); - err = skygw_log_write(LOGFILE_ERROR, "%s", logstr); + err = MXS_ERROR("%s", logstr); if (err != 0) { TEST_ERROR("Error, log write failed."); @@ -603,7 +599,7 @@ static void* thr_run(void* data) mxs_log_finish(); mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); logstr = ("..and you?"); - err = skygw_log_write(LOGFILE_MESSAGE, "%s", logstr); + err = MXS_NOTICE("%s", logstr); if (err != 0) { TEST_ERROR("Error, log write failed."); @@ -615,7 +611,7 @@ static void* thr_run(void* data) #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); #endif - err = skygw_log_write(LOGFILE_TRACE, "%s", logstr); + err = MXS_INFO("%s", logstr); if (err != 0) { TEST_ERROR("Error, log write failed."); @@ -627,7 +623,7 @@ static void* thr_run(void* data) "immediately; the two forms are equivalent. Applying the operatos & to both parts " "of this equivalence, it follows that &a[i] and a+i are also identical: a+i is the " "address of the i-th element beyond a."); - err = skygw_log_write(LOGFILE_ERROR, "%s", logstr); + err = MXS_ERROR("%s", logstr); if (err != 0) { TEST_ERROR("Error, log write failed."); @@ -635,7 +631,7 @@ static void* thr_run(void* data) ss_dassert(err == 0); mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); logstr = ("..... and you too?"); - err = skygw_log_write(LOGFILE_MESSAGE, "%s", logstr); + err = MXS_NOTICE("%s", logstr); if (err != 0) { TEST_ERROR("Error, log write failed."); @@ -651,7 +647,7 @@ static void* thr_run(void* data) #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); #endif - err = skygw_log_write(LOGFILE_TRACE, "%s", logstr); + err = MXS_INFO("%s", logstr); if (err != 0) { TEST_ERROR("Error, log write failed."); @@ -660,7 +656,7 @@ static void* thr_run(void* data) mxs_log_finish(); mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); logstr = ("Testing. One, two, three, four\n"); - err = skygw_log_write(LOGFILE_ERROR, "%s", logstr); + err = MXS_ERROR("%s", logstr); if (err != 0) { TEST_ERROR("Error, log write failed."); @@ -669,7 +665,7 @@ static void* thr_run(void* data) mxs_log_finish(); mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); logstr = ("Testing. One, two, three, .. where was I?\n"); - err = skygw_log_write(LOGFILE_ERROR, "%s", logstr); + err = MXS_ERROR("%s", logstr); if (err != 0) { TEST_ERROR("Error, log write failed."); @@ -726,7 +722,7 @@ static void* thr_run_morelog(void* data) for (i = 0; i < NITER; i++) { char* str = logs[rand() % nmsg]; - err = skygw_log_write((logfile_id_t)(rand()%(LOGFILE_LAST+1)), + err = MXS_LOG_MESSAGE((int)(rand() % (LOG_DEBUG+1)), "%s - iteration # %d", str, i); diff --git a/log_manager/test/testorder.c b/log_manager/test/testorder.c index 4bb23074e..7c757f9e7 100644 --- a/log_manager/test/testorder.c +++ b/log_manager/test/testorder.c @@ -124,11 +124,11 @@ int main(int argc, char** argv) memset(message + block_size - 1, '\0', 1); if (interval > 0 && i % interval == 0) { - err = skygw_log_write_flush(LOGFILE_ERROR, "%s", message); + err = MXS_ERROR("%s", message); } else { - err = skygw_log_write(LOGFILE_ERROR, "%s", message); + err = MXS_ERROR("%s", message); } if (err) { From 6613723a1f9a38a34ce53567ce92e6a2733de753 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Wed, 18 Nov 2015 23:11:35 +0200 Subject: [PATCH 13/21] Update error message when startup fails Claiming that the loading of maxscale.cnf failed in case of any error was misleading. Maxscale may not succeed in opening it, reading it or processing it. --- server/core/gateway.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/server/core/gateway.c b/server/core/gateway.c index 4bc1cbe48..85641572b 100644 --- a/server/core/gateway.c +++ b/server/core/gateway.c @@ -1828,10 +1828,11 @@ int main(int argc, char **argv) if (!config_load(cnf_file_path)) { - char* fprerr = "Failed to load MaxScale configuration " + char* fprerr = + "Failed to open, read or process the MaxScale configuration " "file. Exiting. See the error log for details."; print_log_n_stderr(false, !daemon_mode, fprerr, fprerr, 0); - MXS_ERROR("Failed to load MaxScale configuration file %s. " + MXS_ERROR("Failed to open, read or process the MaxScale configuration file %s. " "Exiting.", cnf_file_path); rc = MAXSCALE_BADCONFIG; From 90d2dc336c3d61343968f13ca382b5ca140a4349 Mon Sep 17 00:00:00 2001 From: MassimilianoPinto Date: Thu, 19 Nov 2015 08:58:49 +0100 Subject: [PATCH 14/21] Missing lock release added Missing lock release added and log message update --- server/modules/routing/binlog/blr_slave.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/server/modules/routing/binlog/blr_slave.c b/server/modules/routing/binlog/blr_slave.c index 6cc941587..331e41bea 100644 --- a/server/modules/routing/binlog/blr_slave.c +++ b/server/modules/routing/binlog/blr_slave.c @@ -2099,6 +2099,9 @@ char read_errmsg[BINLOG_ERROR_MSG_LEN+1]; spinlock_release(&slave->catch_lock); spinlock_release(&router->binlog_lock); state_change = 1; + } else { + spinlock_release(&slave->catch_lock); + spinlock_release(&router->binlog_lock); } } @@ -4400,9 +4403,9 @@ time_t t_now = time(0); /* skip servers with state = 0 */ if ( (sptr->state == BLRS_DUMPING) && (sptr->heartbeat > 0) && ((t_now + 1 - sptr->lastReply) >= sptr->heartbeat) ) { - MXS_NOTICE("Sending Heartbeat to slave server-id %d in State %d, cstate %d. " + MXS_NOTICE("Sending Heartbeat to slave server-id %d. " "Heartbeat interval is %d, last event time is %lu", - sptr->serverid, sptr->state, sptr->cstate, sptr->heartbeat, + sptr->serverid, sptr->heartbeat, (unsigned long)sptr->lastReply); blr_slave_send_heartbeat(router, sptr); From 84d2c72db2c9daa7cdc33ecd373577548b116460 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Thu, 19 Nov 2015 05:34:36 +0200 Subject: [PATCH 15/21] Formatted mqfilter Mqfilter formatted according to the style guide. --- server/modules/filter/mqfilter.c | 2185 ++++++++++++++++-------------- 1 file changed, 1170 insertions(+), 1015 deletions(-) diff --git a/server/modules/filter/mqfilter.c b/server/modules/filter/mqfilter.c index 1587240bd..eace7fcb8 100644 --- a/server/modules/filter/mqfilter.c +++ b/server/modules/filter/mqfilter.c @@ -18,7 +18,7 @@ /** * @file mqfilter.c - * MQ Filter - AMQP Filter. + * MQ Filter - AMQP Filter. * A filter that logs and publishes canonized queries on to a RabbitMQ server. * * The filter reads the routed query, forms a canonized version of it and publishes the @@ -28,7 +28,7 @@ * * The filter makes no attempt to deal with queries that do not fit * in a single GWBUF or result sets that span multiple GWBUFs. - * + * * To use a SSL connection the CA certificate, the client certificate and the client public key must be provided. * By default this filter uses a TCP connection. *@verbatim @@ -49,7 +49,7 @@ * ssl_CA_cert Path to the CA certificate in PEM format * ssl_client_cert Path to the client cerificate in PEM format * ssl_client_key Path to the client public key in PEM format - * + * * The logging trigger levels are: * all Log everything * source Trigger on statements originating from a particular source (database user and host combination) @@ -80,11 +80,12 @@ #include #include -MODULE_INFO info = { - MODULE_API_FILTER, - MODULE_ALPHA_RELEASE, - FILTER_VERSION, - "A RabbitMQ query logging filter" +MODULE_INFO info = +{ + MODULE_API_FILTER, + MODULE_ALPHA_RELEASE, + FILTER_VERSION, + "A RabbitMQ query logging filter" }; static char *version_str = "V1.0.2"; @@ -93,46 +94,49 @@ static int hktask_id = 0; /* * The filter entry points */ -static FILTER *createInstance(char **options, FILTER_PARAMETER **); -static void *newSession(FILTER *instance, SESSION *session); -static void closeSession(FILTER *instance, void *session); -static void freeSession(FILTER *instance, void *session); -static void setDownstream(FILTER *instance, void *fsession, DOWNSTREAM *downstream); -static void setUpstream(FILTER *instance, void *fsession, UPSTREAM *upstream); -static int routeQuery(FILTER *instance, void *fsession, GWBUF *queue); -static int clientReply(FILTER *instance, void *fsession, GWBUF *queue); -static void diagnostic(FILTER *instance, void *fsession, DCB *dcb); +static FILTER *createInstance(char **options, FILTER_PARAMETER **); +static void *newSession(FILTER *instance, SESSION *session); +static void closeSession(FILTER *instance, void *session); +static void freeSession(FILTER *instance, void *session); +static void setDownstream(FILTER *instance, void *fsession, DOWNSTREAM *downstream); +static void setUpstream(FILTER *instance, void *fsession, UPSTREAM *upstream); +static int routeQuery(FILTER *instance, void *fsession, GWBUF *queue); +static int clientReply(FILTER *instance, void *fsession, GWBUF *queue); +static void diagnostic(FILTER *instance, void *fsession, DCB *dcb); -static FILTER_OBJECT MyObject = { - createInstance, - newSession, - closeSession, - freeSession, - setDownstream, - setUpstream, - routeQuery, - clientReply, - diagnostic, +static FILTER_OBJECT MyObject = +{ + createInstance, + newSession, + closeSession, + freeSession, + setDownstream, + setUpstream, + routeQuery, + clientReply, + diagnostic, }; /** *Structure used to store messages and their properties. */ -typedef struct mqmessage_t { - amqp_basic_properties_t *prop; - char *msg; - struct mqmessage_t *next; -}mqmessage; +typedef struct mqmessage_t +{ + amqp_basic_properties_t *prop; + char *msg; + struct mqmessage_t *next; +} mqmessage; /** *Logging trigger levels */ -enum log_trigger_t{ - TRG_ALL = 0x00, - TRG_SOURCE = 0x01, - TRG_SCHEMA = 0x02, - TRG_OBJECT = 0x04 +enum log_trigger_t +{ + TRG_ALL = 0x00, + TRG_SOURCE = 0x01, + TRG_SCHEMA = 0x02, + TRG_OBJECT = 0x04 }; /** @@ -146,92 +150,94 @@ enum log_trigger_t{ * logging_source_host Comma-separated list of hostnames to log * @endverbatim */ -typedef struct source_trigger_t{ - char** user; - int usize; - char** host; - int hsize; -}SRC_TRIG; +typedef struct source_trigger_t +{ + char** user; + int usize; + char** host; + int hsize; +} SRC_TRIG; /** * Schema logging trigger * * Log only those queries that target a specific database. - * + * * Trigger options: * logging_schema Comma-separated list of databases */ -typedef struct schema_trigger_t{ - char** objects; - int size; -}SHM_TRIG; - +typedef struct schema_trigger_t +{ + char** objects; + int size; +} SHM_TRIG; /** * Database object logging trigger * * Log only those queries that target specific database objects. - *@verbatim + *@verbatim * Trigger options: * logging_object Comma-separated list of database objects *@endverbatim */ -typedef struct object_trigger_t{ - char** objects; - int size; -}OBJ_TRIG; +typedef struct object_trigger_t +{ + char** objects; + int size; +} OBJ_TRIG; /** * Statistics for the mqfilter. */ -typedef struct mqstats_t{ +typedef struct mqstats_t +{ int n_msg; /*< Total number of messages */ int n_sent; /*< Number of sent messages */ int n_queued; /*< Number of unsent messages */ - -}MQSTATS; - +} MQSTATS; /** * A instance structure, containing the hostname, login credentials, * virtual host location and the names of the exchange and the key. * Also contains the paths to the CA certificate and client certificate and key. - * + * * Default values assume that a local RabbitMQ server is running on port 5672 with the default * user 'guest' and the password 'guest' using a default exchange named 'default_exchange' with a - * routing key named 'key'. Type of the exchange is 'direct' by default and all queries are logged. - * + * routing key named 'key'. Type of the exchange is 'direct' by default and all queries are logged. + * */ -typedef struct { - int port; - char *hostname; - char *username; - char *password; - char *vhost; - char *exchange; - char *exchange_type; - char *key; - char *queue; - bool use_ssl; - bool log_all; - bool strict_logging; - char *ssl_CA_cert; - char *ssl_client_cert; - char *ssl_client_key; - amqp_connection_state_t conn; /**The connection object*/ - amqp_socket_t* sock; /**The currently active socket*/ - amqp_channel_t channel; /**The current channel in use*/ - int conn_stat; /**state of the connection to the server*/ - int rconn_intv; /**delay for reconnects, in seconds*/ - time_t last_rconn; /**last reconnect attempt*/ - SPINLOCK rconn_lock; - SPINLOCK msg_lock; - mqmessage* messages; - enum log_trigger_t trgtype; - SRC_TRIG* src_trg; - SHM_TRIG* shm_trg; - OBJ_TRIG* obj_trg; - MQSTATS stats; +typedef struct +{ + int port; + char *hostname; + char *username; + char *password; + char *vhost; + char *exchange; + char *exchange_type; + char *key; + char *queue; + bool use_ssl; + bool log_all; + bool strict_logging; + char *ssl_CA_cert; + char *ssl_client_cert; + char *ssl_client_key; + amqp_connection_state_t conn; /**The connection object*/ + amqp_socket_t* sock; /**The currently active socket*/ + amqp_channel_t channel; /**The current channel in use*/ + int conn_stat; /**state of the connection to the server*/ + int rconn_intv; /**delay for reconnects, in seconds*/ + time_t last_rconn; /**last reconnect attempt*/ + SPINLOCK rconn_lock; + SPINLOCK msg_lock; + mqmessage* messages; + enum log_trigger_t trgtype; + SRC_TRIG* src_trg; + SHM_TRIG* shm_trg; + OBJ_TRIG* obj_trg; + MQSTATS stats; } MQ_INSTANCE; /** @@ -243,18 +249,18 @@ typedef struct { * Also holds the necessary session connection information. * */ -typedef struct { - char* uid; /**Unique identifier used to tag messages*/ - char* db; /**The currently active database*/ - DOWNSTREAM down; - UPSTREAM up; - SESSION* session; - bool was_query; /**True if the previous routeQuery call had valid content*/ +typedef struct +{ + char* uid; /**Unique identifier used to tag messages*/ + char* db; /**The currently active database*/ + DOWNSTREAM down; + UPSTREAM up; + SESSION* session; + bool was_query; /**True if the previous routeQuery call had valid content*/ } MQ_SESSION; void sendMessage(void* data); - /** * Implementation of the mandatory version entry point * @@ -263,7 +269,7 @@ void sendMessage(void* data); char * version() { - return version_str; + return version_str; } /** @@ -286,134 +292,154 @@ ModuleInit() FILTER_OBJECT * GetModuleObject() { - return &MyObject; + return &MyObject; } /** - * Internal function used to initialize the connection to + * Internal function used to initialize the connection to * the RabbitMQ server. Also used to reconnect to the server * in case the connection fails and to redeclare exchanges * and queues if they are lost - * + * */ -static int +static int init_conn(MQ_INSTANCE *my_instance) -{ - int rval = 0; - int amqp_ok = AMQP_STATUS_OK; +{ + int rval = 0; + int amqp_ok = AMQP_STATUS_OK; - if(my_instance->use_ssl){ + if (my_instance->use_ssl) + { - if((my_instance->sock = amqp_ssl_socket_new(my_instance->conn)) != NULL){ + if ((my_instance->sock = amqp_ssl_socket_new(my_instance->conn)) != NULL) + { - if((amqp_ok = amqp_ssl_socket_set_cacert(my_instance->sock,my_instance->ssl_CA_cert)) != AMQP_STATUS_OK){ - MXS_ERROR("Failed to set CA certificate: %s", amqp_error_string2(amqp_ok)); - goto cleanup; - } - if((amqp_ok = amqp_ssl_socket_set_key(my_instance->sock, - my_instance->ssl_client_cert, - my_instance->ssl_client_key)) != AMQP_STATUS_OK){ - MXS_ERROR("Failed to set client certificate and key: %s", amqp_error_string2(amqp_ok)); - goto cleanup; - } - }else{ + if ((amqp_ok = amqp_ssl_socket_set_cacert(my_instance->sock, my_instance->ssl_CA_cert)) != AMQP_STATUS_OK) + { + MXS_ERROR("Failed to set CA certificate: %s", amqp_error_string2(amqp_ok)); + goto cleanup; + } + if ((amqp_ok = amqp_ssl_socket_set_key(my_instance->sock, + my_instance->ssl_client_cert, + my_instance->ssl_client_key)) != AMQP_STATUS_OK) + { + MXS_ERROR("Failed to set client certificate and key: %s", amqp_error_string2(amqp_ok)); + goto cleanup; + } + } + else + { + + amqp_ok = AMQP_STATUS_SSL_CONNECTION_FAILED; + MXS_ERROR("SSL socket creation failed."); + goto cleanup; + } + + /**SSL is not used, falling back to TCP*/ + } + else if ((my_instance->sock = amqp_tcp_socket_new(my_instance->conn)) == NULL) + { + MXS_ERROR("TCP socket creation failed."); + goto cleanup; - amqp_ok = AMQP_STATUS_SSL_CONNECTION_FAILED; - MXS_ERROR("SSL socket creation failed."); - goto cleanup; } - /**SSL is not used, falling back to TCP*/ - }else if((my_instance->sock = amqp_tcp_socket_new(my_instance->conn)) == NULL){ - MXS_ERROR("TCP socket creation failed."); - goto cleanup; - - } - - /**Socket creation was successful, trying to open the socket*/ - if((amqp_ok = amqp_socket_open(my_instance->sock,my_instance->hostname,my_instance->port)) != AMQP_STATUS_OK){ - MXS_ERROR("Failed to open socket: %s", amqp_error_string2(amqp_ok)); - goto cleanup; - } - amqp_rpc_reply_t reply; - reply = amqp_login(my_instance->conn,my_instance->vhost,0,AMQP_DEFAULT_FRAME_SIZE,0,AMQP_SASL_METHOD_PLAIN,my_instance->username,my_instance->password); - if(reply.reply_type != AMQP_RESPONSE_NORMAL){ - MXS_ERROR("Login to RabbitMQ server failed."); - goto cleanup; - } - amqp_channel_open(my_instance->conn,my_instance->channel); - reply = amqp_get_rpc_reply(my_instance->conn); - if(reply.reply_type != AMQP_RESPONSE_NORMAL){ - MXS_ERROR("Channel creation failed."); - goto cleanup; - } - - amqp_exchange_declare(my_instance->conn,my_instance->channel, - amqp_cstring_bytes(my_instance->exchange), - amqp_cstring_bytes(my_instance->exchange_type), - 0, 1, - amqp_empty_table); - - reply = amqp_get_rpc_reply(my_instance->conn); - - if(reply.reply_type != AMQP_RESPONSE_NORMAL){ - MXS_ERROR("Exchange declaration failed,trying to redeclare the exchange."); - if(reply.reply_type == AMQP_RESPONSE_SERVER_EXCEPTION){ - if(reply.reply.id == AMQP_CHANNEL_CLOSE_METHOD){ - amqp_send_method(my_instance->conn,my_instance->channel,AMQP_CHANNEL_CLOSE_OK_METHOD,NULL); - }else if(reply.reply.id == AMQP_CONNECTION_CLOSE_METHOD){ - amqp_send_method(my_instance->conn,my_instance->channel,AMQP_CONNECTION_CLOSE_OK_METHOD,NULL); - } - - my_instance->channel++; - amqp_channel_open(my_instance->conn,my_instance->channel); - - amqp_exchange_delete(my_instance->conn,my_instance->channel,amqp_cstring_bytes(my_instance->exchange),0); - amqp_exchange_declare(my_instance->conn,my_instance->channel, - amqp_cstring_bytes(my_instance->exchange), - amqp_cstring_bytes(my_instance->exchange_type), - 0, 1, - amqp_empty_table); - reply = amqp_get_rpc_reply(my_instance->conn); - } - if(reply.reply_type != AMQP_RESPONSE_NORMAL){ - MXS_ERROR("Exchange redeclaration failed."); + /**Socket creation was successful, trying to open the socket*/ + if ((amqp_ok = amqp_socket_open(my_instance->sock, my_instance->hostname, my_instance->port)) != AMQP_STATUS_OK) + { + MXS_ERROR("Failed to open socket: %s", amqp_error_string2(amqp_ok)); goto cleanup; } - } - - if(my_instance->queue){ - - - - amqp_queue_declare(my_instance->conn,my_instance->channel, - amqp_cstring_bytes(my_instance->queue), - 0, 1, 0, 0, - amqp_empty_table); - reply = amqp_get_rpc_reply(my_instance->conn); - if(reply.reply_type != AMQP_RESPONSE_NORMAL){ - MXS_ERROR("Queue declaration failed."); + amqp_rpc_reply_t reply; + reply = amqp_login(my_instance->conn, my_instance->vhost, 0, AMQP_DEFAULT_FRAME_SIZE, 0, AMQP_SASL_METHOD_PLAIN, my_instance->username, my_instance->password); + if (reply.reply_type != AMQP_RESPONSE_NORMAL) + { + MXS_ERROR("Login to RabbitMQ server failed."); + goto cleanup; + } + amqp_channel_open(my_instance->conn, my_instance->channel); + reply = amqp_get_rpc_reply(my_instance->conn); + if (reply.reply_type != AMQP_RESPONSE_NORMAL) + { + MXS_ERROR("Channel creation failed."); goto cleanup; } - - amqp_queue_bind(my_instance->conn,my_instance->channel, - amqp_cstring_bytes(my_instance->queue), - amqp_cstring_bytes(my_instance->exchange), - amqp_cstring_bytes(my_instance->key), - amqp_empty_table); - reply = amqp_get_rpc_reply(my_instance->conn); - if(reply.reply_type != AMQP_RESPONSE_NORMAL){ - MXS_ERROR("Failed to bind queue to exchange."); - goto cleanup; + amqp_exchange_declare(my_instance->conn, my_instance->channel, + amqp_cstring_bytes(my_instance->exchange), + amqp_cstring_bytes(my_instance->exchange_type), + 0, 1, + amqp_empty_table); + + reply = amqp_get_rpc_reply(my_instance->conn); + + if (reply.reply_type != AMQP_RESPONSE_NORMAL) + { + MXS_ERROR("Exchange declaration failed,trying to redeclare the exchange."); + if (reply.reply_type == AMQP_RESPONSE_SERVER_EXCEPTION) + { + if (reply.reply.id == AMQP_CHANNEL_CLOSE_METHOD) + { + amqp_send_method(my_instance->conn, my_instance->channel, AMQP_CHANNEL_CLOSE_OK_METHOD, NULL); + } + else if (reply.reply.id == AMQP_CONNECTION_CLOSE_METHOD) + { + amqp_send_method(my_instance->conn, my_instance->channel, AMQP_CONNECTION_CLOSE_OK_METHOD, NULL); + } + + my_instance->channel++; + amqp_channel_open(my_instance->conn, my_instance->channel); + + amqp_exchange_delete(my_instance->conn, my_instance->channel, amqp_cstring_bytes(my_instance->exchange), 0); + amqp_exchange_declare(my_instance->conn, my_instance->channel, + amqp_cstring_bytes(my_instance->exchange), + amqp_cstring_bytes(my_instance->exchange_type), + 0, 1, + amqp_empty_table); + reply = amqp_get_rpc_reply(my_instance->conn); + } + if (reply.reply_type != AMQP_RESPONSE_NORMAL) + { + MXS_ERROR("Exchange redeclaration failed."); + goto cleanup; + } } - } - rval = 1; - cleanup: + if (my_instance->queue) + { + + + + amqp_queue_declare(my_instance->conn, my_instance->channel, + amqp_cstring_bytes(my_instance->queue), + 0, 1, 0, 0, + amqp_empty_table); + reply = amqp_get_rpc_reply(my_instance->conn); + if (reply.reply_type != AMQP_RESPONSE_NORMAL) + { + MXS_ERROR("Queue declaration failed."); + goto cleanup; + } + + + amqp_queue_bind(my_instance->conn, my_instance->channel, + amqp_cstring_bytes(my_instance->queue), + amqp_cstring_bytes(my_instance->exchange), + amqp_cstring_bytes(my_instance->key), + amqp_empty_table); + reply = amqp_get_rpc_reply(my_instance->conn); + if (reply.reply_type != AMQP_RESPONSE_NORMAL) + { + MXS_ERROR("Failed to bind queue to exchange."); + goto cleanup; + } + } + rval = 1; + +cleanup: + + return rval; - return rval; - } /** @@ -427,264 +453,329 @@ init_conn(MQ_INSTANCE *my_instance) */ char** parse_optstr(char* str, char* tok, int* szstore) { - char *lasts, *tk = str; - char **arr; - int i = 0, size = 1; - - - while((tk = strpbrk(tk + 1,tok))){ - size++; - } + char *lasts, *tk = str; + char **arr; + int i = 0, size = 1; - arr = malloc(sizeof(char*)*size); - if(arr == NULL){ - MXS_ERROR("Cannot allocate enough memory."); - *szstore = 0; - return NULL; - } - - *szstore = size; - tk = strtok_r(str,tok, &lasts); - while(tk && i < size){ - arr[i++] = strdup(tk); - tk = strtok_r(NULL,tok,&lasts); - } - return arr; + while ((tk = strpbrk(tk + 1, tok))) + { + size++; + } + + arr = malloc(sizeof(char*)*size); + + if (arr == NULL) + { + MXS_ERROR("Cannot allocate enough memory."); + *szstore = 0; + return NULL; + } + + *szstore = size; + tk = strtok_r(str, tok, &lasts); + while (tk && i < size) + { + arr[i++] = strdup(tk); + tk = strtok_r(NULL, tok, &lasts); + } + return arr; } /** * Create an instance of the filter for a particular service * within MaxScale. - * + * * @param options The options for this filter * * @return The instance data for this new instance */ -static FILTER * +static FILTER * createInstance(char **options, FILTER_PARAMETER **params) { - MQ_INSTANCE *my_instance; - int paramcount = 0, parammax = 64, i = 0, x = 0, arrsize = 0; - FILTER_PARAMETER** paramlist; - char** arr; - char taskname[512]; - - if ((my_instance = calloc(1, sizeof(MQ_INSTANCE)))) + MQ_INSTANCE *my_instance; + int paramcount = 0, parammax = 64, i = 0, x = 0, arrsize = 0; + FILTER_PARAMETER** paramlist; + char** arr; + char taskname[512]; + + if ((my_instance = calloc(1, sizeof(MQ_INSTANCE)))) { - spinlock_init(&my_instance->rconn_lock); - spinlock_init(&my_instance->msg_lock); - uid_gen = 0; - paramlist = malloc(sizeof(FILTER_PARAMETER*)*64); + spinlock_init(&my_instance->rconn_lock); + spinlock_init(&my_instance->msg_lock); + uid_gen = 0; + paramlist = malloc(sizeof(FILTER_PARAMETER*)*64); - if((my_instance->conn = amqp_new_connection()) == NULL){ + if ((my_instance->conn = amqp_new_connection()) == NULL) + { + return NULL; + } + my_instance->channel = 1; + my_instance->last_rconn = time(NULL); + my_instance->conn_stat = AMQP_STATUS_OK; + my_instance->rconn_intv = 1; + my_instance->port = 5672; + my_instance->trgtype = TRG_ALL; + my_instance->log_all = false; + my_instance->strict_logging = true; + + for (i = 0; params[i]; i++) + { + if (!strcmp(params[i]->name, "hostname")) + { + my_instance->hostname = strdup(params[i]->value); + } + else if (!strcmp(params[i]->name, "username")) + { + my_instance->username = strdup(params[i]->value); + } + else if (!strcmp(params[i]->name, "password")) + { + my_instance->password = strdup(params[i]->value); + } + else if (!strcmp(params[i]->name, "vhost")) + { + my_instance->vhost = strdup(params[i]->value); + } + else if (!strcmp(params[i]->name, "port")) + { + my_instance->port = atoi(params[i]->value); + } + else if (!strcmp(params[i]->name, "exchange")) + { + my_instance->exchange = strdup(params[i]->value); + } + else if (!strcmp(params[i]->name, "key")) + { + my_instance->key = strdup(params[i]->value); + } + else if (!strcmp(params[i]->name, "queue")) + { + my_instance->queue = strdup(params[i]->value); + } + else if (!strcmp(params[i]->name, "ssl_client_certificate")) + { + + my_instance->ssl_client_cert = strdup(params[i]->value); + } + else if (!strcmp(params[i]->name, "ssl_client_key")) + { + + my_instance->ssl_client_key = strdup(params[i]->value); + } + else if (!strcmp(params[i]->name, "ssl_CA_cert")) + { + + my_instance->ssl_CA_cert = strdup(params[i]->value); + } + else if (!strcmp(params[i]->name, "exchange_type")) + { + + my_instance->exchange_type = strdup(params[i]->value); + } + else if (!strcmp(params[i]->name, "logging_trigger")) + { + + arr = parse_optstr(params[i]->value, ",", &arrsize); + + for (x = 0; x < arrsize; x++) + { + if (!strcmp(arr[x], "source")) + { + my_instance->trgtype |= TRG_SOURCE; + } + else if (!strcmp(arr[x], "schema")) + { + my_instance->trgtype |= TRG_SCHEMA; + } + else if (!strcmp(arr[x], "object")) + { + my_instance->trgtype |= TRG_OBJECT; + } + else if (!strcmp(arr[x], "all")) + { + my_instance->trgtype = TRG_ALL; + } + else + { + MXS_ERROR("Unknown option for 'logging_trigger':%s.", arr[x]); + } + } + + if (arrsize > 0) + { + free(arr); + } + arrsize = 0; - return NULL; - } - my_instance->channel = 1; - my_instance->last_rconn = time(NULL); - my_instance->conn_stat = AMQP_STATUS_OK; - my_instance->rconn_intv = 1; - my_instance->port = 5672; - my_instance->trgtype = TRG_ALL; - my_instance->log_all = false; - my_instance->strict_logging = true; - for(i = 0;params[i];i++){ - if(!strcmp(params[i]->name,"hostname")){ - my_instance->hostname = strdup(params[i]->value); - }else if(!strcmp(params[i]->name,"username")){ - my_instance->username = strdup(params[i]->value); - }else if(!strcmp(params[i]->name,"password")){ - my_instance->password = strdup(params[i]->value); - }else if(!strcmp(params[i]->name,"vhost")){ - my_instance->vhost = strdup(params[i]->value); - }else if(!strcmp(params[i]->name,"port")){ - my_instance->port = atoi(params[i]->value); - }else if(!strcmp(params[i]->name,"exchange")){ - my_instance->exchange = strdup(params[i]->value); - }else if(!strcmp(params[i]->name,"key")){ - my_instance->key = strdup(params[i]->value); - }else if(!strcmp(params[i]->name,"queue")){ - my_instance->queue = strdup(params[i]->value); - } - else if(!strcmp(params[i]->name,"ssl_client_certificate")){ + } + else if (strstr(params[i]->name, "logging_")) + { - my_instance->ssl_client_cert = strdup(params[i]->value); - - }else if(!strcmp(params[i]->name,"ssl_client_key")){ + if (paramcount < parammax) + { + paramlist[paramcount] = malloc(sizeof(FILTER_PARAMETER)); + paramlist[paramcount]->name = strdup(params[i]->name); + paramlist[paramcount]->value = strdup(params[i]->value); + paramcount++; + } + } + } - my_instance->ssl_client_key = strdup(params[i]->value); - - }else if(!strcmp(params[i]->name,"ssl_CA_cert")){ + if (my_instance->trgtype & TRG_SOURCE) + { - my_instance->ssl_CA_cert = strdup(params[i]->value); + my_instance->src_trg = (SRC_TRIG*) malloc(sizeof(SRC_TRIG)); + my_instance->src_trg->user = NULL; + my_instance->src_trg->host = NULL; + my_instance->src_trg->usize = 0; + my_instance->src_trg->hsize = 0; - }else if(!strcmp(params[i]->name,"exchange_type")){ + } - my_instance->exchange_type = strdup(params[i]->value); + if (my_instance->trgtype & TRG_SCHEMA) + { - }else if(!strcmp(params[i]->name,"logging_trigger")){ - - arr = parse_optstr(params[i]->value,",",&arrsize); + my_instance->shm_trg = (SHM_TRIG*) malloc(sizeof(SHM_TRIG)); + my_instance->shm_trg->objects = NULL; + my_instance->shm_trg->size = 0; - for(x = 0;xtrgtype |= TRG_SOURCE; - }else if(!strcmp(arr[x],"schema")){ - my_instance->trgtype |= TRG_SCHEMA; - }else if(!strcmp(arr[x],"object")){ - my_instance->trgtype |= TRG_OBJECT; - }else if(!strcmp(arr[x],"all")){ - my_instance->trgtype = TRG_ALL; - }else{ - MXS_ERROR("Unknown option for 'logging_trigger':%s.",arr[x]); - } - } + } - if(arrsize > 0){ - free(arr); - } - arrsize = 0; - + if (my_instance->trgtype & TRG_OBJECT) + { + my_instance->obj_trg = (OBJ_TRIG*) malloc(sizeof(OBJ_TRIG)); + my_instance->obj_trg->objects = NULL; + my_instance->obj_trg->size = 0; - }else if(strstr(params[i]->name,"logging_")){ + } - if(paramcount < parammax){ - paramlist[paramcount] = malloc(sizeof(FILTER_PARAMETER)); - paramlist[paramcount]->name = strdup(params[i]->name); - paramlist[paramcount]->value = strdup(params[i]->value); - paramcount++; - } - - } + for (i = 0; i < paramcount; i++) + { - } + if (!strcmp(paramlist[i]->name, "logging_source_user")) + { - if(my_instance->trgtype & TRG_SOURCE){ + if (my_instance->src_trg) + { + my_instance->src_trg->user = parse_optstr(paramlist[i]->value, ",", &arrsize); + my_instance->src_trg->usize = arrsize; + arrsize = 0; + } - my_instance->src_trg = (SRC_TRIG*)malloc(sizeof(SRC_TRIG)); - my_instance->src_trg->user = NULL; - my_instance->src_trg->host = NULL; - my_instance->src_trg->usize = 0; - my_instance->src_trg->hsize = 0; + } + else if (!strcmp(paramlist[i]->name, "logging_source_host")) + { - } + if (my_instance->src_trg) + { + my_instance->src_trg->host = parse_optstr(paramlist[i]->value, ",", &arrsize); + my_instance->src_trg->hsize = arrsize; + arrsize = 0; + } - if(my_instance->trgtype & TRG_SCHEMA){ + } + else if (!strcmp(paramlist[i]->name, "logging_schema")) + { - my_instance->shm_trg = (SHM_TRIG*)malloc(sizeof(SHM_TRIG)); - my_instance->shm_trg->objects = NULL; - my_instance->shm_trg->size = 0; + if (my_instance->shm_trg) + { + my_instance->shm_trg->objects = parse_optstr(paramlist[i]->value, ",", &arrsize); + my_instance->shm_trg->size = arrsize; + arrsize = 0; + } - } + } + else if (!strcmp(paramlist[i]->name, "logging_object")) + { - if(my_instance->trgtype & TRG_OBJECT){ + if (my_instance->obj_trg) + { + my_instance->obj_trg->objects = parse_optstr(paramlist[i]->value, ",", &arrsize); + my_instance->obj_trg->size = arrsize; + arrsize = 0; + } - my_instance->obj_trg = (OBJ_TRIG*)malloc(sizeof(OBJ_TRIG)); - my_instance->obj_trg->objects = NULL; - my_instance->obj_trg->size = 0; + } + else if (!strcmp(paramlist[i]->name, "logging_log_all")) + { + if (config_truth_value(paramlist[i]->value)) + { + my_instance->log_all = true; + } + } + else if (!strcmp(paramlist[i]->name, "logging_strict")) + { + if (!config_truth_value(paramlist[i]->value)) + { + my_instance->strict_logging = false; + } + } + free(paramlist[i]->name); + free(paramlist[i]->value); + free(paramlist[i]); + } - } + free(paramlist); - for(i = 0;ihostname == NULL) + { + my_instance->hostname = strdup("localhost"); + } + if (my_instance->username == NULL) + { + my_instance->username = strdup("guest"); + } + if (my_instance->password == NULL) + { + my_instance->password = strdup("guest"); + } + if (my_instance->vhost == NULL) + { + my_instance->vhost = strdup("/"); + } + if (my_instance->exchange == NULL) + { + my_instance->exchange = strdup("default_exchange"); + } + if (my_instance->key == NULL) + { + my_instance->key = strdup("key"); + } + if (my_instance->exchange_type == NULL) + { + my_instance->exchange_type = strdup("direct"); + } - if(!strcmp(paramlist[i]->name,"logging_source_user")){ - - if(my_instance->src_trg){ - my_instance->src_trg->user = parse_optstr(paramlist[i]->value,",",&arrsize); - my_instance->src_trg->usize = arrsize; - arrsize = 0; - } + if (my_instance->ssl_client_cert != NULL && + my_instance->ssl_client_key != NULL && + my_instance->ssl_CA_cert != NULL) + { + my_instance->use_ssl = true; + } + else + { + my_instance->use_ssl = false; + } - }else if(!strcmp(paramlist[i]->name,"logging_source_host")){ - - if(my_instance->src_trg){ - my_instance->src_trg->host = parse_optstr(paramlist[i]->value,",",&arrsize); - my_instance->src_trg->hsize = arrsize; - arrsize = 0; - } + if (my_instance->use_ssl) + { + amqp_set_initialize_ssl_library(0); /**Assume the underlying SSL library is already initialized*/ + } - }else if(!strcmp(paramlist[i]->name,"logging_schema")){ - - if(my_instance->shm_trg){ - my_instance->shm_trg->objects = parse_optstr(paramlist[i]->value,",",&arrsize); - my_instance->shm_trg->size = arrsize; - arrsize = 0; - } + /**Connect to the server*/ + init_conn(my_instance); - }else if(!strcmp(paramlist[i]->name,"logging_object")){ - - if(my_instance->obj_trg){ - my_instance->obj_trg->objects = parse_optstr(paramlist[i]->value,",",&arrsize); - my_instance->obj_trg->size = arrsize; - arrsize = 0; - } - - }else if(!strcmp(paramlist[i]->name,"logging_log_all")){ - if(config_truth_value(paramlist[i]->value)){ - my_instance->log_all = true; - } - }else if(!strcmp(paramlist[i]->name,"logging_strict")){ - if(!config_truth_value(paramlist[i]->value)){ - my_instance->strict_logging = false; - } - } - free(paramlist[i]->name); - free(paramlist[i]->value); - free(paramlist[i]); - } - - free(paramlist); - - if(my_instance->hostname == NULL){ - my_instance->hostname = strdup("localhost"); - } - if(my_instance->username == NULL){ - my_instance->username = strdup("guest"); - } - if(my_instance->password == NULL){ - my_instance->password = strdup("guest"); - } - if(my_instance->vhost == NULL){ - my_instance->vhost = strdup("/"); - } - if(my_instance->exchange == NULL){ - my_instance->exchange = strdup("default_exchange"); - } - if(my_instance->key == NULL){ - my_instance->key = strdup("key"); - } - if(my_instance->exchange_type == NULL){ - my_instance->exchange_type = strdup("direct"); - } - - if(my_instance->ssl_client_cert != NULL && - my_instance->ssl_client_key != NULL && - my_instance->ssl_CA_cert != NULL){ - my_instance->use_ssl = true; - }else{ - my_instance->use_ssl = false; - } - - if(my_instance->use_ssl){ - amqp_set_initialize_ssl_library(0);/**Assume the underlying SSL library is already initialized*/ - } - - /**Connect to the server*/ - init_conn(my_instance); - - snprintf(taskname,511,"mqtask%d",atomic_add(&hktask_id,1)); - hktask_add(taskname,sendMessage,(void*)my_instance,5); + snprintf(taskname, 511, "mqtask%d", atomic_add(&hktask_id, 1)); + hktask_add(taskname, sendMessage, (void*) my_instance, 5); } - return (FILTER *)my_instance; + return(FILTER *) my_instance; } - - /** * Declares a persistent, non-exclusive and non-passive queue that * auto-deletes after all the messages have been consumed. @@ -692,38 +783,39 @@ createInstance(char **options, FILTER_PARAMETER **params) * @param qname Name of the queue to be declared * @return Returns 0 if an error occurred, 1 if successful */ -int declareQueue(MQ_INSTANCE *my_instance, MQ_SESSION* my_session, char* qname) +int declareQueue(MQ_INSTANCE *my_instance, MQ_SESSION* my_session, char* qname) { - int success = 1; - amqp_rpc_reply_t reply; + int success = 1; + amqp_rpc_reply_t reply; - spinlock_acquire(&my_instance->rconn_lock); + spinlock_acquire(&my_instance->rconn_lock); - amqp_queue_declare(my_instance->conn,my_instance->channel, - amqp_cstring_bytes(qname), - 0, 1, 0, 1, - amqp_empty_table); - reply = amqp_get_rpc_reply(my_instance->conn); - if(reply.reply_type != AMQP_RESPONSE_NORMAL){ - success = 0; - MXS_ERROR("Queue declaration failed."); - - } + amqp_queue_declare(my_instance->conn, my_instance->channel, + amqp_cstring_bytes(qname), + 0, 1, 0, 1, + amqp_empty_table); + reply = amqp_get_rpc_reply(my_instance->conn); + if (reply.reply_type != AMQP_RESPONSE_NORMAL) + { + success = 0; + MXS_ERROR("Queue declaration failed."); - - amqp_queue_bind(my_instance->conn,my_instance->channel, - amqp_cstring_bytes(qname), - amqp_cstring_bytes(my_instance->exchange), - amqp_cstring_bytes(my_session->uid), - amqp_empty_table); - reply = amqp_get_rpc_reply(my_instance->conn); - if(reply.reply_type != AMQP_RESPONSE_NORMAL){ - success = 0; - MXS_ERROR("Failed to bind queue to exchange."); - - } - spinlock_release(&my_instance->rconn_lock); - return success; + } + + amqp_queue_bind(my_instance->conn, my_instance->channel, + amqp_cstring_bytes(qname), + amqp_cstring_bytes(my_instance->exchange), + amqp_cstring_bytes(my_session->uid), + amqp_empty_table); + reply = amqp_get_rpc_reply(my_instance->conn); + if (reply.reply_type != AMQP_RESPONSE_NORMAL) + { + success = 0; + MXS_ERROR("Failed to bind queue to exchange."); + + } + spinlock_release(&my_instance->rconn_lock); + return success; } /** @@ -734,93 +826,93 @@ int declareQueue(MQ_INSTANCE *my_instance, MQ_SESSION* my_session, char* qname) */ void sendMessage(void* data) { - MQ_INSTANCE *instance = (MQ_INSTANCE*)data; - mqmessage *tmp; - int err_num; - - spinlock_acquire(&instance->rconn_lock); - if(instance->conn_stat != AMQP_STATUS_OK){ - - if(difftime(time(NULL),instance->last_rconn) > instance->rconn_intv){ - - instance->last_rconn = time(NULL); - - if(init_conn(instance)){ - instance->rconn_intv = 1.0; - instance->conn_stat = AMQP_STATUS_OK; - - }else{ - instance->rconn_intv += 5.0; - MXS_ERROR("Failed to reconnect to the MQRabbit server "); - } - } - err_num = instance->conn_stat; - } - spinlock_release(&instance->rconn_lock); - - if(err_num != AMQP_STATUS_OK) - { - /** No connection to the broker */ - return; - } - - spinlock_acquire(&instance->msg_lock); - tmp = instance->messages; - - if(tmp == NULL) - { - spinlock_release(&instance->msg_lock); - return; - } - - instance->messages = instance->messages->next; - spinlock_release(&instance->msg_lock); - - while(tmp){ - - err_num = amqp_basic_publish(instance->conn,instance->channel, - amqp_cstring_bytes(instance->exchange), - amqp_cstring_bytes(instance->key), - 0,0,tmp->prop,amqp_cstring_bytes(tmp->msg)); + MQ_INSTANCE *instance = (MQ_INSTANCE*) data; + mqmessage *tmp; + int err_num; spinlock_acquire(&instance->rconn_lock); - instance->conn_stat = err_num; - spinlock_release(&instance->rconn_lock); - - if(err_num == AMQP_STATUS_OK){ - /**Message was sent successfully*/ - free(tmp->prop); - free(tmp->msg); - free(tmp); - - atomic_add(&instance->stats.n_sent,1); - atomic_add(&instance->stats.n_queued,-1); - spinlock_acquire(&instance->msg_lock); - tmp = instance->messages; - - if(tmp == NULL) - { - spinlock_release(&instance->msg_lock); - return; - } - - instance->messages = instance->messages->next; - spinlock_release(&instance->msg_lock); - } - else + if (instance->conn_stat != AMQP_STATUS_OK) { - spinlock_acquire(&instance->msg_lock); - tmp->next = instance->messages; - instance->messages = tmp; - spinlock_release(&instance->msg_lock); - return; + if (difftime(time(NULL), instance->last_rconn) > instance->rconn_intv) + { + instance->last_rconn = time(NULL); + + if (init_conn(instance)) + { + instance->rconn_intv = 1.0; + instance->conn_stat = AMQP_STATUS_OK; + } + else + { + instance->rconn_intv += 5.0; + MXS_ERROR("Failed to reconnect to the MQRabbit server "); + } + } + err_num = instance->conn_stat; } - - } + spinlock_release(&instance->rconn_lock); + if (err_num != AMQP_STATUS_OK) + { + /** No connection to the broker */ + return; + } + + spinlock_acquire(&instance->msg_lock); + tmp = instance->messages; + + if (tmp == NULL) + { + spinlock_release(&instance->msg_lock); + return; + } + + instance->messages = instance->messages->next; + spinlock_release(&instance->msg_lock); + + while (tmp) + { + err_num = amqp_basic_publish(instance->conn, instance->channel, + amqp_cstring_bytes(instance->exchange), + amqp_cstring_bytes(instance->key), + 0, 0, tmp->prop, amqp_cstring_bytes(tmp->msg)); + + spinlock_acquire(&instance->rconn_lock); + instance->conn_stat = err_num; + spinlock_release(&instance->rconn_lock); + + if (err_num == AMQP_STATUS_OK) + { + /**Message was sent successfully*/ + free(tmp->prop); + free(tmp->msg); + free(tmp); + + atomic_add(&instance->stats.n_sent, 1); + atomic_add(&instance->stats.n_queued, -1); + spinlock_acquire(&instance->msg_lock); + tmp = instance->messages; + + if (tmp == NULL) + { + spinlock_release(&instance->msg_lock); + return; + } + + instance->messages = instance->messages->next; + spinlock_release(&instance->msg_lock); + } + else + { + spinlock_acquire(&instance->msg_lock); + tmp->next = instance->messages; + instance->messages = tmp; + spinlock_release(&instance->msg_lock); + return; + } + } } - /** * Push a new message on the stack to be broadcasted later. * The message assumes ownership of the memory allocated to the message content and properties. @@ -829,33 +921,32 @@ void sendMessage(void* data) */ void pushMessage(MQ_INSTANCE *instance, amqp_basic_properties_t* prop, char* msg) { - - mqmessage* newmsg = calloc(1,sizeof(mqmessage)); - if(newmsg){ - - newmsg->msg = msg; - newmsg->prop = prop; - - }else{ - MXS_ERROR("Cannot allocate enough memory."); - free(prop); - free(msg); - return; - } - spinlock_acquire(&instance->msg_lock); - - newmsg->next = instance->messages; - instance->messages = newmsg; + mqmessage* newmsg = calloc(1, sizeof(mqmessage)); + if (newmsg) + { + newmsg->msg = msg; + newmsg->prop = prop; + } + else + { + MXS_ERROR("Cannot allocate enough memory."); + free(prop); + free(msg); + return; + } - spinlock_release(&instance->msg_lock); - - atomic_add(&instance->stats.n_msg,1); - atomic_add(&instance->stats.n_queued,1); + spinlock_acquire(&instance->msg_lock); + + newmsg->next = instance->messages; + instance->messages = newmsg; + + spinlock_release(&instance->msg_lock); + + atomic_add(&instance->stats.n_msg, 1); + atomic_add(&instance->stats.n_queued, 1); } - - /** * Associate a new session with this instance of the filter and opens * a connection to the server and prepares the exchange and the queue for use. @@ -865,31 +956,31 @@ void pushMessage(MQ_INSTANCE *instance, amqp_basic_properties_t* prop, char* msg * @param session The session itself * @return Session specific data for this session */ -static void * +static void * newSession(FILTER *instance, SESSION *session) { - MQ_SESSION *my_session; - MYSQL_session* sessauth; + MQ_SESSION *my_session; + MYSQL_session* sessauth; - if ((my_session = calloc(1, sizeof(MQ_SESSION))) != NULL){ - - my_session->was_query = false; - my_session->uid = NULL; - my_session->session = session; - sessauth = my_session->session->data; - if(sessauth->db && strnlen(sessauth->db,128)>0){ - my_session->db = strdup(sessauth->db); - }else{ - my_session->db = NULL; + if ((my_session = calloc(1, sizeof(MQ_SESSION))) != NULL) + { + my_session->was_query = false; + my_session->uid = NULL; + my_session->session = session; + sessauth = my_session->session->data; + if (sessauth->db && strnlen(sessauth->db, 128) > 0) + { + my_session->db = strdup(sessauth->db); + } + else + { + my_session->db = NULL; + } } - - } - return my_session; + return my_session; } - - /** * Close a session with the filter, this is the mechanism * by which a filter may cleanup data structure etc. @@ -898,10 +989,8 @@ newSession(FILTER *instance, SESSION *session) * @param instance The filter instance data * @param session The session being closed */ -static void -closeSession(FILTER *instance, void *session) -{ -} +static void +closeSession(FILTER *instance, void *session){ } /** * Free the memory associated with the session @@ -912,11 +1001,11 @@ closeSession(FILTER *instance, void *session) static void freeSession(FILTER *instance, void *session) { - MQ_SESSION *my_session = (MQ_SESSION *)session; - free(my_session->uid); - free(my_session->db); - free(my_session); - return; + MQ_SESSION *my_session = (MQ_SESSION *) session; + free(my_session->uid); + free(my_session->db); + free(my_session); + return; } /** @@ -924,23 +1013,22 @@ freeSession(FILTER *instance, void *session) * passed from this filter. * * @param instance The filter instance data - * @param session The filter session + * @param session The filter session * @param downstream The downstream filter or router. */ static void setDownstream(FILTER *instance, void *session, DOWNSTREAM *downstream) { - MQ_SESSION *my_session = (MQ_SESSION *)session; - my_session->down = *downstream; + MQ_SESSION *my_session = (MQ_SESSION *) session; + my_session->down = *downstream; } -static void setUpstream(FILTER *instance, void *session, UPSTREAM *upstream) +static void setUpstream(FILTER *instance, void *session, UPSTREAM *upstream) { - MQ_SESSION *my_session = (MQ_SESSION *)session; - my_session->up = *upstream; + MQ_SESSION *my_session = (MQ_SESSION *) session; + my_session->up = *upstream; } - /** * Generates a unique key using a number of unique unsigned integers. * @param array The array that is used @@ -948,11 +1036,12 @@ static void setUpstream(FILTER *instance, void *session, UPSTREAM *upstream) */ void genkey(char* array, int size) { - int i = 0; - for(i = 0;istart + 4)) == 0x02){ - if(my_session->db){ - free(my_session->db); - } - plen = pktlen(queue->start); - my_session->db = calloc(plen,sizeof(char)); - memcpy(my_session->db,queue->start + 5,plen - 1); - } - - if(modutil_is_SQL(queue)){ - - /**Parse the query*/ - - if (!query_is_parsed(queue)){ - success = parse_query(queue); + /**The user is changing databases*/ + if (*((char*) (queue->start + 4)) == 0x02) + { + if (my_session->db) + { + free(my_session->db); + } + plen = pktlen(queue->start); + my_session->db = calloc(plen, sizeof(char)); + memcpy(my_session->db, queue->start + 5, plen - 1); } - if(!success){ - MXS_ERROR("Parsing query failed."); - goto send_downstream; - } + if (modutil_is_SQL(queue)) + { - if(!my_instance->log_all){ - if(!skygw_is_real_query(queue)){ - goto send_downstream; - } - } + /**Parse the query*/ - if(my_instance->trgtype == TRG_ALL){ - MXS_INFO("Trigger is TRG_ALL"); - schema_ok = true; - src_ok = true; - obj_ok = true; - goto validate_triggers; - } - - if(my_instance->trgtype & TRG_SOURCE && my_instance->src_trg){ - - if(session_isvalid(my_session->session)){ - - sessusr = session_getUser(my_session->session); - sesshost = session_get_remote(my_session->session); - - /**Username was configured*/ - if(my_instance->src_trg->usize > 0){ - for(i = 0;isrc_trg->usize;i++){ + if (!query_is_parsed(queue)) + { + success = parse_query(queue); + } - if(strcmp(my_instance->src_trg->user[i],sessusr) == 0) - { - MXS_INFO("Trigger is TRG_SOURCE: user: %s = %s",my_instance->src_trg->user[i],sessusr); + if (!success) + { + MXS_ERROR("Parsing query failed."); + goto send_downstream; + } + + if (!my_instance->log_all) + { + if (!skygw_is_real_query(queue)) + { + goto send_downstream; + } + } + + if (my_instance->trgtype == TRG_ALL) + { + MXS_INFO("Trigger is TRG_ALL"); + schema_ok = true; + src_ok = true; + obj_ok = true; + goto validate_triggers; + } + + if (my_instance->trgtype & TRG_SOURCE && my_instance->src_trg) + { + if (session_isvalid(my_session->session)) + { + sessusr = session_getUser(my_session->session); + sesshost = session_get_remote(my_session->session); + + /**Username was configured*/ + if (my_instance->src_trg->usize > 0) + { + for (i = 0; i < my_instance->src_trg->usize; i++) + { + if (strcmp(my_instance->src_trg->user[i], sessusr) == 0) + { + MXS_INFO("Trigger is TRG_SOURCE: user: %s = %s", my_instance->src_trg->user[i], sessusr); + src_ok = true; + break; + } + } + } + + /**If username was not matched, try to match hostname*/ + + if (!src_ok && my_instance->src_trg->hsize > 0) + { + + for (i = 0; i < my_instance->src_trg->hsize; i++) + { + + if (strcmp(my_instance->src_trg->host[i], sesshost) == 0) + { + MXS_INFO("Trigger is TRG_SOURCE: host: %s = %s", my_instance->src_trg->host[i], sesshost); + src_ok = true; + break; + } + } + } + } + + if (src_ok && !my_instance->strict_logging) + { + schema_ok = true; + obj_ok = true; + goto validate_triggers; + } + } + else + { + src_ok = true; + } + + if (my_instance->trgtype & TRG_SCHEMA && my_instance->shm_trg) + { + int tbsz = 0, z; + char** tblnames = skygw_get_table_names(queue, &tbsz, true); + char* tmp; + bool all_remotes = true; + + for (z = 0; z < tbsz; z++) + { + if ((tmp = strchr(tblnames[z], '.')) != NULL) + { + char *lasts; + tmp = strtok_r(tblnames[z], ".", &lasts); + for (i = 0; i < my_instance->shm_trg->size; i++) + { + + if (strcmp(tmp, my_instance->shm_trg->objects[i]) == 0) + { + + MXS_INFO("Trigger is TRG_SCHEMA: %s = %s", tmp, my_instance->shm_trg->objects[i]); + + schema_ok = true; + break; + } + } + } + else + { + all_remotes = false; + } + free(tblnames[z]); + } + free(tblnames); + + if (!schema_ok && !all_remotes && my_session->db && strlen(my_session->db) > 0) + { + + for (i = 0; i < my_instance->shm_trg->size; i++) + { + + if (strcmp(my_session->db, my_instance->shm_trg->objects[i]) == 0) + { + + MXS_INFO("Trigger is TRG_SCHEMA: %s = %s", my_session->db, my_instance->shm_trg->objects[i]); + + schema_ok = true; + break; + } + } + } + + if (schema_ok && !my_instance->strict_logging) + { src_ok = true; - break; - } - - } + obj_ok = true; + goto validate_triggers; + } - - } + } + else + { + schema_ok = true; + } - /**If username was not matched, try to match hostname*/ - if(!src_ok && my_instance->src_trg->hsize > 0){ + if (my_instance->trgtype & TRG_OBJECT && my_instance->obj_trg) + { - for(i = 0;isrc_trg->hsize;i++){ - - if(strcmp(my_instance->src_trg->host[i],sesshost) == 0) - { - MXS_INFO("Trigger is TRG_SOURCE: host: %s = %s",my_instance->src_trg->host[i],sesshost); - src_ok = true; - break; - } - - } + sesstbls = skygw_get_table_names(queue, &dbcount, false); - } + for (j = 0; j < dbcount; j++) + { + char* tbnm = NULL; - } + if ((strchr(sesstbls[j], '.')) != NULL) + { + char *lasts; + tbnm = strtok_r(sesstbls[j], ".", &lasts); + tbnm = strtok_r(NULL, ".", &lasts); + } + else + { + tbnm = sesstbls[j]; + } - if(src_ok && !my_instance->strict_logging){ - schema_ok = true; - obj_ok = true; - goto validate_triggers; - } - }else{ - src_ok = true; + for (i = 0; i < my_instance->obj_trg->size; i++) + { + + + if (!strcmp(tbnm, my_instance->obj_trg->objects[i])) + { + obj_ok = true; + MXS_INFO("Trigger is TRG_OBJECT: %s = %s", my_instance->obj_trg->objects[i], sesstbls[j]); + break; + } + + } + + } + if (dbcount > 0) + { + for (j = 0; j < dbcount; j++) + { + free(sesstbls[j]); + } + free(sesstbls); + dbcount = 0; + } + + if (obj_ok && !my_instance->strict_logging) + { + src_ok = true; + schema_ok = true; + goto validate_triggers; + } + + } + else + { + obj_ok = true; + } + + +validate_triggers: + + if (src_ok && schema_ok && obj_ok) + { + + /** + * Something matched the trigger, log the query + */ + + MXS_INFO("Routing message to: %s:%d %s as %s/%s, exchange: %s<%s> key:%s queue:%s", + my_instance->hostname, my_instance->port, + my_instance->vhost, my_instance->username, + my_instance->password, my_instance->exchange, + my_instance->exchange_type, my_instance->key, + my_instance->queue); + + if (my_session->uid == NULL) + { + + my_session->uid = calloc(33, sizeof(char)); + + if (!my_session->uid) + { + MXS_ERROR("Out of memory."); + } + else + { + genkey(my_session->uid, 32); + } + + } + + if (queue->next != NULL) + { + queue = gwbuf_make_contiguous(queue); + } + + if (modutil_extract_SQL(queue, &ptr, &length)) + { + + my_session->was_query = true; + + if ((prop = malloc(sizeof(amqp_basic_properties_t)))) + { + prop->_flags = AMQP_BASIC_CONTENT_TYPE_FLAG | + AMQP_BASIC_DELIVERY_MODE_FLAG | + AMQP_BASIC_MESSAGE_ID_FLAG | + AMQP_BASIC_CORRELATION_ID_FLAG; + prop->content_type = amqp_cstring_bytes("text/plain"); + prop->delivery_mode = AMQP_DELIVERY_PERSISTENT; + prop->correlation_id = amqp_cstring_bytes(my_session->uid); + prop->message_id = amqp_cstring_bytes("query"); + } + + + + if (success) + { + + /**Try to convert to a canonical form and use the plain query if unsuccessful*/ + if ((canon_q = skygw_get_canonical(queue)) == NULL) + { + MXS_ERROR("Cannot form canonical query."); + } + + } + + memset(t_buf, 0, 128); + sprintf(t_buf, "%lu|", (unsigned long) time(NULL)); + + int qlen = strnlen(canon_q, length) + strnlen(t_buf, 128); + if ((combined = malloc((qlen + 1) * sizeof(char))) == NULL) + { + MXS_ERROR("Out of memory"); + } + strcpy(combined, t_buf); + strncat(combined, canon_q, length); + + pushMessage(my_instance, prop, combined); + free(canon_q); + } + + } + + /** Pass the query downstream */ } - - - - if(my_instance->trgtype & TRG_SCHEMA && my_instance->shm_trg){ - int tbsz = 0,z; - char** tblnames = skygw_get_table_names(queue,&tbsz,true); - char* tmp; - bool all_remotes = true; - - for(z = 0;zshm_trg->size; i++){ - - if(strcmp(tmp,my_instance->shm_trg->objects[i]) == 0){ - - MXS_INFO("Trigger is TRG_SCHEMA: %s = %s",tmp,my_instance->shm_trg->objects[i]); - - schema_ok = true; - break; - } - } - }else{ - all_remotes = false; - } - free(tblnames[z]); - } - free(tblnames); - - if(!schema_ok && !all_remotes && my_session->db && strlen(my_session->db)>0){ - - for(i = 0; ishm_trg->size; i++){ - - if(strcmp(my_session->db,my_instance->shm_trg->objects[i]) == 0){ - - MXS_INFO("Trigger is TRG_SCHEMA: %s = %s",my_session->db,my_instance->shm_trg->objects[i]); - - schema_ok = true; - break; - } - } - } - - if(schema_ok && !my_instance->strict_logging){ - src_ok = true; - obj_ok = true; - goto validate_triggers; - } - - }else{ - schema_ok = true; - } - - - if(my_instance->trgtype & TRG_OBJECT && my_instance->obj_trg){ - - sesstbls = skygw_get_table_names(queue,&dbcount,false); - - for(j = 0; jobj_trg->size; i++){ - - - if(!strcmp(tbnm,my_instance->obj_trg->objects[i])){ - obj_ok = true; - MXS_INFO("Trigger is TRG_OBJECT: %s = %s",my_instance->obj_trg->objects[i],sesstbls[j]); - break; - } - - } - - } - if(dbcount > 0){ - for(j = 0; jstrict_logging){ - src_ok = true; - schema_ok = true; - goto validate_triggers; - } - - }else{ - obj_ok = true; - } - - - validate_triggers: - - if(src_ok&&schema_ok&&obj_ok){ - - /** - * Something matched the trigger, log the query - */ - - MXS_INFO("Routing message to: %s:%d %s as %s/%s, exchange: %s<%s> key:%s queue:%s", - my_instance->hostname,my_instance->port, - my_instance->vhost,my_instance->username, - my_instance->password,my_instance->exchange, - my_instance->exchange_type,my_instance->key, - my_instance->queue); - - if(my_session->uid == NULL){ - - my_session->uid = calloc(33,sizeof(char)); - - if(!my_session->uid){ - MXS_ERROR("Out of memory."); - }else{ - genkey(my_session->uid,32); - } - - } - - if (queue->next != NULL) - { - queue = gwbuf_make_contiguous(queue); - } - - if(modutil_extract_SQL(queue, &ptr, &length)){ - - my_session->was_query = true; - - if((prop = malloc(sizeof(amqp_basic_properties_t)))){ - prop->_flags = AMQP_BASIC_CONTENT_TYPE_FLAG | - AMQP_BASIC_DELIVERY_MODE_FLAG | - AMQP_BASIC_MESSAGE_ID_FLAG | - AMQP_BASIC_CORRELATION_ID_FLAG; - prop->content_type = amqp_cstring_bytes("text/plain"); - prop->delivery_mode = AMQP_DELIVERY_PERSISTENT; - prop->correlation_id = amqp_cstring_bytes(my_session->uid); - prop->message_id = amqp_cstring_bytes("query"); - } - - - - if(success){ - - /**Try to convert to a canonical form and use the plain query if unsuccessful*/ - if((canon_q = skygw_get_canonical(queue)) == NULL){ - MXS_ERROR("Cannot form canonical query."); - } - - } - - memset(t_buf,0,128); - sprintf(t_buf, "%lu|",(unsigned long)time(NULL)); - - int qlen = strnlen(canon_q,length) + strnlen(t_buf,128); - if((combined = malloc((qlen+1)*sizeof(char))) == NULL){ - MXS_ERROR("Out of memory"); - } - strcpy(combined,t_buf); - strncat(combined,canon_q,length); - - pushMessage(my_instance,prop,combined); - free(canon_q); - } - - } - - /** Pass the query downstream */ - } - send_downstream: - return my_session->down.routeQuery(my_session->down.instance, - my_session->down.session, queue); +send_downstream: + return my_session->down.routeQuery(my_session->down.instance, + my_session->down.session, queue); } /** @@ -1276,49 +1405,61 @@ routeQuery(FILTER *instance, void *session, GWBUF *queue) */ unsigned int leitoi(unsigned char* c) { - unsigned char* ptr = c; - unsigned int sz = *ptr; - if(*ptr < 0xfb) return sz; - if(*ptr == 0xfc){ - sz = *++ptr; - sz += (*++ptr << 8); - }else if(*ptr == 0xfd){ - sz = *++ptr; - sz += (*++ptr << 8); - sz += (*++ptr << 8); - }else{ - sz = *++ptr; - sz += (*++ptr << 8); - sz += (*++ptr << 8); - sz += (*++ptr << 8); - sz += (*++ptr << 8); - sz += (*++ptr << 8); - sz += (*++ptr << 8); - sz += (*++ptr << 8); - sz += (*++ptr << 8); - } - return sz; + unsigned char* ptr = c; + unsigned int sz = *ptr; + if (*ptr < 0xfb) return sz; + if (*ptr == 0xfc) + { + sz = *++ptr; + sz += (*++ptr << 8); + } + else if (*ptr == 0xfd) + { + sz = *++ptr; + sz += (*++ptr << 8); + sz += (*++ptr << 8); + } + else + { + sz = *++ptr; + sz += (*++ptr << 8); + sz += (*++ptr << 8); + sz += (*++ptr << 8); + sz += (*++ptr << 8); + sz += (*++ptr << 8); + sz += (*++ptr << 8); + sz += (*++ptr << 8); + sz += (*++ptr << 8); + } + return sz; } /** - * Converts a length-encoded integer into a standard unsigned integer + * Converts a length-encoded integer into a standard unsigned integer * and advances the pointer to the next unrelated byte. * * @param c Pointer to the first byte of a length-encoded integer */ unsigned int consume_leitoi(unsigned char** c) { - unsigned int rval = leitoi(*c); - if(**c == 0xfc){ - *c += 3; - }else if(**c == 0xfd){ - *c += 4; - }else if(**c == 0xfe){ - *c += 9; - }else{ - *c += 1; - } - return rval; + unsigned int rval = leitoi(*c); + if (**c == 0xfc) + { + *c += 3; + } + else if (**c == 0xfd) + { + *c += 4; + } + else if (**c == 0xfe) + { + *c += 9; + } + else + { + *c += 1; + } + return rval; } /** @@ -1329,13 +1470,14 @@ unsigned int consume_leitoi(unsigned char** c) */ char* consume_lestr(unsigned char** c) { - unsigned int slen = consume_leitoi(c); - char *str = calloc((slen + 1), sizeof(char)); - if(str){ - memcpy(str,*c,slen); - *c += slen; - } - return str; + unsigned int slen = consume_leitoi(c); + char *str = calloc((slen + 1), sizeof(char)); + if (str) + { + memcpy(str, *c, slen); + *c += slen; + } + return str; } /** @@ -1345,11 +1487,10 @@ char* consume_lestr(unsigned char** c) */ unsigned int is_eof(void* p) { - unsigned char* ptr = (unsigned char*) p; - return *(ptr) == 0x05 && *(ptr + 1) == 0x00 && *(ptr + 2) == 0x00 && *(ptr + 4) == 0xfe; + unsigned char* ptr = (unsigned char*) p; + return *(ptr) == 0x05 && *(ptr + 1) == 0x00 && *(ptr + 2) == 0x00 && *(ptr + 4) == 0xfe; } - /** * The clientReply entry point. This is passed the response buffer * to which the filter should be applied. Once processed the @@ -1359,127 +1500,142 @@ unsigned int is_eof(void* p) * The function tries to extract a SQL query response out of the response buffer, * adds a timestamp to it and publishes the resulting string on the exchange. * The message is tagged with the same identifier that the query was. - * + * * @param instance The filter instance data * @param session The filter session * @param reply The response data */ static int clientReply(FILTER* instance, void *session, GWBUF *reply) { - MQ_SESSION *my_session = (MQ_SESSION *)session; - MQ_INSTANCE *my_instance = (MQ_INSTANCE *)instance; - char t_buf[128],*combined; - unsigned int pkt_len = pktlen(reply->sbuf->data), offset = 0; - amqp_basic_properties_t *prop; + MQ_SESSION *my_session = (MQ_SESSION *) session; + MQ_INSTANCE *my_instance = (MQ_INSTANCE *) instance; + char t_buf[128], *combined; + unsigned int pkt_len = pktlen(reply->sbuf->data), offset = 0; + amqp_basic_properties_t *prop; - if (my_session->was_query){ + if (my_session->was_query) + { - int packet_ok = 0, was_last = 0; + int packet_ok = 0, was_last = 0; - my_session->was_query = false; + my_session->was_query = false; - if(pkt_len > 0){ - if((prop = malloc(sizeof(amqp_basic_properties_t)))){ - prop->_flags = AMQP_BASIC_CONTENT_TYPE_FLAG | - AMQP_BASIC_DELIVERY_MODE_FLAG | - AMQP_BASIC_MESSAGE_ID_FLAG | - AMQP_BASIC_CORRELATION_ID_FLAG; - prop->content_type = amqp_cstring_bytes("text/plain"); - prop->delivery_mode = AMQP_DELIVERY_PERSISTENT; - prop->correlation_id = amqp_cstring_bytes(my_session->uid); - prop->message_id = amqp_cstring_bytes("reply"); - } - if(!(combined = calloc(GWBUF_LENGTH(reply) + 256,sizeof(char)))){ - MXS_ERROR("Out of memory"); - } + if (pkt_len > 0) + { + if ((prop = malloc(sizeof(amqp_basic_properties_t)))) + { + prop->_flags = AMQP_BASIC_CONTENT_TYPE_FLAG | + AMQP_BASIC_DELIVERY_MODE_FLAG | + AMQP_BASIC_MESSAGE_ID_FLAG | + AMQP_BASIC_CORRELATION_ID_FLAG; + prop->content_type = amqp_cstring_bytes("text/plain"); + prop->delivery_mode = AMQP_DELIVERY_PERSISTENT; + prop->correlation_id = amqp_cstring_bytes(my_session->uid); + prop->message_id = amqp_cstring_bytes("reply"); + } + if (!(combined = calloc(GWBUF_LENGTH(reply) + 256, sizeof(char)))) + { + MXS_ERROR("Out of memory"); + } - memset(t_buf,0,128); - sprintf(t_buf,"%lu|",(unsigned long)time(NULL)); - - - memcpy(combined + offset,t_buf,strnlen(t_buf,40)); - offset += strnlen(t_buf,40); + memset(t_buf, 0, 128); + sprintf(t_buf, "%lu|", (unsigned long) time(NULL)); - if(*(reply->sbuf->data + 4) == 0x00){ /**OK packet*/ - unsigned int aff_rows = 0, l_id = 0, s_flg = 0, wrn = 0; - unsigned char *ptr = (unsigned char*)(reply->sbuf->data + 5); - pkt_len = pktlen(reply->sbuf->data); - aff_rows = consume_leitoi(&ptr); - l_id = consume_leitoi(&ptr); - s_flg |= *ptr++; - s_flg |= (*ptr++ << 8); - wrn |= *ptr++; - wrn |= (*ptr++ << 8); - sprintf(combined + offset,"OK - affected_rows: %d " - " last_insert_id: %d " - " status_flags: %#0x " - " warnings: %d ", - aff_rows,l_id,s_flg,wrn); - offset += strnlen(combined,GWBUF_LENGTH(reply) + 256) - offset; - if(pkt_len > 7){ - int plen = consume_leitoi(&ptr); - if(plen > 0){ - sprintf(combined + offset," message: %.*s\n",plen,ptr); - } - } + memcpy(combined + offset, t_buf, strnlen(t_buf, 40)); + offset += strnlen(t_buf, 40); - packet_ok = 1; - was_last = 1; + if (*(reply->sbuf->data + 4) == 0x00) + { /**OK packet*/ + unsigned int aff_rows = 0, l_id = 0, s_flg = 0, wrn = 0; + unsigned char *ptr = (unsigned char*) (reply->sbuf->data + 5); + pkt_len = pktlen(reply->sbuf->data); + aff_rows = consume_leitoi(&ptr); + l_id = consume_leitoi(&ptr); + s_flg |= *ptr++; + s_flg |= (*ptr++ << 8); + wrn |= *ptr++; + wrn |= (*ptr++ << 8); + sprintf(combined + offset, "OK - affected_rows: %d " + " last_insert_id: %d " + " status_flags: %#0x " + " warnings: %d ", + aff_rows, l_id, s_flg, wrn); + offset += strnlen(combined, GWBUF_LENGTH(reply) + 256) - offset; - }else if(*(reply->sbuf->data + 4) == 0xff){ /**ERR packet*/ + if (pkt_len > 7) + { + int plen = consume_leitoi(&ptr); + if (plen > 0) + { + sprintf(combined + offset, " message: %.*s\n", plen, ptr); + } + } - sprintf(combined + offset,"ERROR - message: %.*s", - (int)(reply->end - ((void*)(reply->sbuf->data + 13))), - (char *)reply->sbuf->data + 13); - packet_ok = 1; - was_last = 1; - - }else if(*(reply->sbuf->data + 4) == 0xfb){ /**LOCAL_INFILE request packet*/ - - unsigned char *rset = (unsigned char*)reply->sbuf->data; - strcpy(combined + offset,"LOCAL_INFILE: "); - strncat(combined + offset,(const char*)rset+5,pktlen(rset)); - packet_ok = 1; - was_last = 1; - - }else{ /**Result set*/ - - unsigned char *rset = (unsigned char*)(reply->sbuf->data + 4); - char *tmp; - unsigned int col_cnt = consume_leitoi(&rset); + packet_ok = 1; + was_last = 1; - tmp = calloc(256,sizeof(char)); - sprintf(tmp,"Columns: %d",col_cnt); - memcpy(combined + offset,tmp,strnlen(tmp,256)); - offset += strnlen(tmp,256); - memcpy(combined + offset,"\n",1); - offset++; - free(tmp); - - packet_ok = 1; - was_last = 1; - - } - if(packet_ok){ + } + else if (*(reply->sbuf->data + 4) == 0xff) + { /**ERR packet*/ - pushMessage(my_instance,prop,combined); + sprintf(combined + offset, "ERROR - message: %.*s", + (int) (reply->end - ((void*) (reply->sbuf->data + 13))), + (char *) reply->sbuf->data + 13); + packet_ok = 1; + was_last = 1; - if(was_last){ + } + else if (*(reply->sbuf->data + 4) == 0xfb) + { /**LOCAL_INFILE request packet*/ - /**Successful reply received and sent, releasing uid*/ - - free(my_session->uid); - my_session->uid = NULL; + unsigned char *rset = (unsigned char*) reply->sbuf->data; + strcpy(combined + offset, "LOCAL_INFILE: "); + strncat(combined + offset, (const char*) rset + 5, pktlen(rset)); + packet_ok = 1; + was_last = 1; + + } + else + { /**Result set*/ + + unsigned char *rset = (unsigned char*) (reply->sbuf->data + 4); + char *tmp; + unsigned int col_cnt = consume_leitoi(&rset); + + tmp = calloc(256, sizeof(char)); + sprintf(tmp, "Columns: %d", col_cnt); + memcpy(combined + offset, tmp, strnlen(tmp, 256)); + offset += strnlen(tmp, 256); + memcpy(combined + offset, "\n", 1); + offset++; + free(tmp); + + packet_ok = 1; + was_last = 1; + + } + if (packet_ok) + { + + pushMessage(my_instance, prop, combined); + + if (was_last) + { + + /**Successful reply received and sent, releasing uid*/ + + free(my_session->uid); + my_session->uid = NULL; + + } + } + } - } - } } - } - - return my_session->up.clientReply(my_session->up.instance, - my_session->up.session, reply); + return my_session->up.clientReply(my_session->up.instance, + my_session->up.session, reply); } /** @@ -1492,25 +1648,24 @@ static int clientReply(FILTER* instance, void *session, GWBUF *reply) * @param fsession Filter session, may be NULL * @param dcb The DCB for diagnostic output */ -static void +static void diagnostic(FILTER *instance, void *fsession, DCB *dcb) { - MQ_INSTANCE *my_instance = (MQ_INSTANCE *)instance; + MQ_INSTANCE *my_instance = (MQ_INSTANCE *) instance; - if (my_instance) + if (my_instance) { - dcb_printf(dcb, "Connecting to %s:%d as '%s'.\nVhost: %s\tExchange: %s\nKey: %s\tQueue: %s\n\n", - my_instance->hostname,my_instance->port, - my_instance->username, - my_instance->vhost, my_instance->exchange, - my_instance->key, my_instance->queue - ); - dcb_printf(dcb, "%-16s%-16s%-16s\n", - "Messages","Queued","Sent"); - dcb_printf(dcb, "%-16d%-16d%-16d\n", - my_instance->stats.n_msg, - my_instance->stats.n_queued, - my_instance->stats.n_sent); + dcb_printf(dcb, "Connecting to %s:%d as '%s'.\nVhost: %s\tExchange: %s\nKey: %s\tQueue: %s\n\n", + my_instance->hostname, my_instance->port, + my_instance->username, + my_instance->vhost, my_instance->exchange, + my_instance->key, my_instance->queue + ); + dcb_printf(dcb, "%-16s%-16s%-16s\n", + "Messages", "Queued", "Sent"); + dcb_printf(dcb, "%-16d%-16d%-16d\n", + my_instance->stats.n_msg, + my_instance->stats.n_queued, + my_instance->stats.n_sent); } } - From 6164b7f301f5864f072c0afcb5007f8834a91b7e Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Thu, 19 Nov 2015 15:36:40 +0200 Subject: [PATCH 16/21] Fixed unsafe use of localtime Since localtime is not thread-safe it should not be used in multithreaded contexts. For this reason all calls to localtime were changed to localtime_r in code where concurrency issues were possible. Internal tests were left unchanged because they aren't multithreaded. --- log_manager/test/testlog.c | 2 +- server/core/dcb.c | 12 +++++----- server/core/gateway.c | 35 ++++++------------------------ server/core/load_utils.c | 3 ++- server/modules/filter/dbfwfilter.c | 18 ++++++++------- server/modules/filter/topfilter.c | 7 ++++-- server/modules/protocol/httpd.c | 4 +++- server/modules/routing/webserver.c | 7 +++++- utils/skygw_utils.cc | 6 ++--- 9 files changed, 43 insertions(+), 51 deletions(-) diff --git a/log_manager/test/testlog.c b/log_manager/test/testlog.c index 38b5e0603..c2d907d89 100644 --- a/log_manager/test/testlog.c +++ b/log_manager/test/testlog.c @@ -161,7 +161,7 @@ int main(int argc, char* argv[]) ss_dassert(succp); t = time(NULL); - tm = *(localtime(&t)); + localtime_r(&t, &tm); err = MXS_ERROR("%04d %02d/%02d %02d.%02d.%02d", tm.tm_year+1900, tm.tm_mon+1, diff --git a/server/core/dcb.c b/server/core/dcb.c index b4a35012a..10e436aaa 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -1986,9 +1986,9 @@ dprintOneDCB(DCB *pdcb, DCB *dcb) if (dcb->persistentstart) { char buff[20]; - struct tm * timeinfo; - timeinfo = localtime (&dcb->persistentstart); - strftime(buff, sizeof(buff), "%b %d %H:%M:%S", timeinfo); + struct tm timeinfo; + localtime_r(&dcb->persistentstart, &timeinfo); + strftime(buff, sizeof(buff), "%b %d %H:%M:%S", &timeinfo); dcb_printf(pdcb, "\t\tAdded to persistent pool: %s\n", buff); } } @@ -2160,9 +2160,9 @@ dprintDCB(DCB *pdcb, DCB *dcb) if (dcb->persistentstart) { char buff[20]; - struct tm * timeinfo; - timeinfo = localtime (&dcb->persistentstart); - strftime(buff, sizeof(buff), "%b %d %H:%M:%S", timeinfo); + struct tm timeinfo; + localtime_r(&dcb->persistentstart, &timeinfo); + strftime(buff, sizeof(buff), "%b %d %H:%M:%S", &timeinfo); dcb_printf(pdcb, "\t\tAdded to persistent pool: %s\n", buff); } } diff --git a/server/core/gateway.c b/server/core/gateway.c index 85641572b..27d6ae0e0 100644 --- a/server/core/gateway.c +++ b/server/core/gateway.c @@ -516,6 +516,8 @@ static bool file_write_footer( return succp; } +// Documentation says 26 bytes is enough, but 32 is a nice round number. +#define ASCTIME_BUF_LEN 32 static bool file_write_header( FILE* outfile) { @@ -524,10 +526,10 @@ static bool file_write_header( size_t len2; size_t len3; const char* header_buf1; - char* header_buf2 = NULL; + char header_buf2[ASCTIME_BUF_LEN]; const char* header_buf3; - time_t* t = NULL; - struct tm* tm = NULL; + time_t t; + struct tm tm; #if defined(LAPTOP_TEST) struct timespec ts1; ts1.tv_sec = 0; @@ -538,23 +540,10 @@ static bool file_write_header( return true; #endif - if ((t = (time_t *)malloc(sizeof(time_t))) == NULL) { - goto return_succp; - } - - if ((tm = (struct tm *)malloc(sizeof(struct tm))) == NULL) { - goto return_succp; - } - - *t = time(NULL); - *tm = *localtime(t); + localtime_r(&t, &tm); header_buf1 = "\n\nMariaDB Corporation MaxScale " MAXSCALE_VERSION "\t"; - header_buf2 = strdup(asctime(tm)); - - if (header_buf2 == NULL) { - goto return_succp; - } + asctime_r(&tm, header_buf2); header_buf3 = "------------------------------------------------------\n"; len1 = strlen(header_buf1); @@ -570,16 +559,6 @@ static bool file_write_header( succp = true; -return_succp: - if (tm != NULL) { - free(tm); - } - if (t != NULL) { - free(t); - } - if (header_buf2 != NULL) { - free(header_buf2); - } return succp; } diff --git a/server/core/load_utils.c b/server/core/load_utils.c index 3f0259776..39e2db952 100644 --- a/server/core/load_utils.c +++ b/server/core/load_utils.c @@ -530,7 +530,8 @@ module_feedback_send(void* data) { int http_send = 0; now = time(NULL); - now_tm = localtime(&now); + struct tm now_result; + now_tm = localtime_r(&now, &now_result); hour = now_tm->tm_hour; FEEDBACK_CONF *feedback_config = (FEEDBACK_CONF *) data; diff --git a/server/modules/filter/dbfwfilter.c b/server/modules/filter/dbfwfilter.c index 6fee69669..8a35813ad 100644 --- a/server/modules/filter/dbfwfilter.c +++ b/server/modules/filter/dbfwfilter.c @@ -1653,15 +1653,15 @@ GWBUF* gen_dummy_error(FW_SESSION* session, char* msg) bool inside_timerange(TIMERANGE* comp) { - struct tm* tm_now; + struct tm tm_now; struct tm tm_before, tm_after; time_t before, after, now, time_now; double to_before, to_after; time(&time_now); - tm_now = localtime(&time_now); - memcpy(&tm_before, tm_now, sizeof(struct tm)); - memcpy(&tm_after, tm_now, sizeof(struct tm)); + localtime_r(&time_now, &tm_now); + memcpy(&tm_before, &tm_now, sizeof(struct tm)); + memcpy(&tm_after, &tm_now, sizeof(struct tm)); tm_before.tm_sec = comp->start.tm_sec; @@ -1674,7 +1674,7 @@ bool inside_timerange(TIMERANGE* comp) before = mktime(&tm_before); after = mktime(&tm_after); - now = mktime(tm_now); + now = mktime(&tm_now); to_before = difftime(now, before); to_after = difftime(now, after); @@ -1730,10 +1730,10 @@ bool rule_matches(FW_INSTANCE* my_instance, FW_SESSION* my_session, GWBUF *queue QUERYSPEED* queryspeed = NULL; QUERYSPEED* rule_qs = NULL; time_t time_now; - struct tm* tm_now; + struct tm tm_now; time(&time_now); - tm_now = localtime(&time_now); + localtime_r(&time_now, &tm_now); matches = false; is_sql = modutil_is_SQL(queue) || modutil_is_SQL_prepare(queue); @@ -1781,7 +1781,9 @@ bool rule_matches(FW_INSTANCE* my_instance, FW_SESSION* my_session, GWBUF *queue { matches = true; msg = strdup("Permission denied at this time."); - MXS_INFO("dbfwfilter: rule '%s': query denied at: %s", rulelist->rule->name, asctime(tm_now)); + char buffer[32]; // asctime documentation requires 26 + asctime_r(&tm_now, buffer); + MXS_INFO("dbfwfilter: rule '%s': query denied at: %s", rulelist->rule->name, buffer); goto queryresolved; } else diff --git a/server/modules/filter/topfilter.c b/server/modules/filter/topfilter.c index 0949e9f15..768050947 100644 --- a/server/modules/filter/topfilter.c +++ b/server/modules/filter/topfilter.c @@ -387,8 +387,11 @@ closeSession(FILTER *instance, void *session) } } fprintf(fp, "-----------+-----------------------------------------------------------------\n"); - fprintf(fp, "\n\nSession started %s", - asctime(localtime(&my_session->connect.tv_sec))); + struct tm tm; + localtime_r(&my_session->connect.tv_sec, &tm); + char buffer[32]; // asctime_r documentation requires 26 + asctime_r(&tm, buffer); + fprintf(fp, "\n\nSession started %s", buffer); if (my_session->clientHost) { fprintf(fp, "Connection from %s\n", diff --git a/server/modules/protocol/httpd.c b/server/modules/protocol/httpd.c index 5d4aaeb7f..042a20366 100644 --- a/server/modules/protocol/httpd.c +++ b/server/modules/protocol/httpd.c @@ -491,7 +491,9 @@ static void httpd_send_headers(DCB *dcb, int final) const char *fmt = "%a, %d %b %Y %H:%M:%S GMT"; time_t httpd_current_time = time(NULL); - strftime(date, sizeof(date), fmt, localtime(&httpd_current_time)); + struct tm tm; + localtime_r(&httpd_current_time, &tm); + strftime(date, sizeof(date), fmt, &tm); dcb_printf(dcb, "HTTP/1.1 200 OK\r\nDate: %s\r\nServer: %s\r\nConnection: close\r\nContent-Type: application/json\r\n", date, HTTP_SERVER_STRING); diff --git a/server/modules/routing/webserver.c b/server/modules/routing/webserver.c index af00a4e7b..3b94fa41b 100644 --- a/server/modules/routing/webserver.c +++ b/server/modules/routing/webserver.c @@ -334,8 +334,13 @@ char date[64] = ""; const char *fmt = "%a, %d %b %Y %H:%M:%S GMT"; time_t httpd_current_time = time(NULL); + struct tm tm; + char buffer[32]; // asctime_r documentation requires 26 - strftime(date, sizeof(date), fmt, localtime(&httpd_current_time)); + localtime_r(&http_current_time, &tm); + asctime_r(&tm, buffer); + + strftime(date, sizeof(date), fmt, buffer); dcb_printf(dcb, "HTTP/1.1 200 OK\r\nDate: %s\r\nServer: %s\r\nConnection: close\r\nContent-Type: text/html\r\n", date, "MaxScale"); diff --git a/utils/skygw_utils.cc b/utils/skygw_utils.cc index a082d1cf8..e04617cad 100644 --- a/utils/skygw_utils.cc +++ b/utils/skygw_utils.cc @@ -639,7 +639,7 @@ size_t snprint_timestamp( /** Generate timestamp */ t = time(NULL); - tm = *(localtime(&t)); + localtime_r(&t, &tm); snprintf(p_ts, MIN(tslen,timestamp_len), timestamp_formatstr, @@ -687,7 +687,7 @@ size_t snprint_timestamp_hp( /** Generate timestamp */ gettimeofday(&tv,NULL); - tm = *(localtime(&tv.tv_sec)); + localtime_r(&tv.tv_sec, &tm); usec = tv.tv_usec/1000; snprintf(p_ts, MIN(tslen,timestamp_len_hp), @@ -1709,7 +1709,7 @@ static bool file_write_header( t = (time_t *)malloc(sizeof(time_t)); tm = (struct tm *)malloc(sizeof(struct tm)); *t = time(NULL); - *tm = *localtime(t); + localtime_r(t, tm); CHK_FILE(file); header_buf1 = "\n\nMariaDB Corporation MaxScale\t"; From 422d6f5ab2a7f5ac4b51b4d5b2aa52e36c9e3999 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Thu, 19 Nov 2015 18:28:29 +0200 Subject: [PATCH 17/21] Updated readwritesplit default values The combination of only one slave being used and the slave_selection_criteria being LEAST_CURRENT_OPERATIONS can possibly cause a connection pileup on one slave server. This would skew the query distribution heavily towards the first available slave even if multiple slave were being used. Having the maximum number of slave servers to be equal to the total amount of available slaves allows for a more even and responsive distribution of the query traffic. --- Documentation/Routers/ReadWriteSplit.md | 2 +- server/modules/routing/readwritesplit/readwritesplit.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Documentation/Routers/ReadWriteSplit.md b/Documentation/Routers/ReadWriteSplit.md index c6e5f456f..18a7aa3d4 100644 --- a/Documentation/Routers/ReadWriteSplit.md +++ b/Documentation/Routers/ReadWriteSplit.md @@ -52,7 +52,7 @@ passwd= ### `max_slave_connections` -**`max_slave_connections`** sets the maximum number of slaves a router session uses at any moment. Default value is `1`. +**`max_slave_connections`** sets the maximum number of slaves a router session uses at any moment. The default is to use all available slaves. max_slave_connections= diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index 67669d1fa..a02f46c05 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -698,12 +698,12 @@ createInstance(SERVICE *service, char **options) router->rwsplit_config.rw_max_sescmd_history_size = 0; } - /** - * Set default value for max_slave_connections and for slave selection - * criteria. If parameter is set in config file max_slave_connections - * will be overwritten. + /** + * Set default value for max_slave_connections as 100%. This way + * LEAST_CURRENT_OPERATIONS allows us to balance evenly across all the + * configured slaves. */ - router->rwsplit_config.rw_max_slave_conn_count = CONFIG_MAX_SLAVE_CONN; + router->rwsplit_config.rw_max_slave_conn_count = nservers; if (router->rwsplit_config.rw_slave_select_criteria == UNDEFINED_CRITERIA) { From 47e2e4d3e05b2ee0a0ce352dd93bcf49116aa98c Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Sat, 21 Nov 2015 03:44:06 +0200 Subject: [PATCH 18/21] Configuration parameters were uninitialized The creation of a CONFIG_PARAM didn't initialize the qdf_param_type value which was later used when adding parameters to the monitors. --- server/core/config.c | 1 + 1 file changed, 1 insertion(+) diff --git a/server/core/config.c b/server/core/config.c index bbde33d69..2fe378dc2 100644 --- a/server/core/config.c +++ b/server/core/config.c @@ -279,6 +279,7 @@ handler(void *userdata, const char *section, const char *name, const char *value param->name = strdup(name); param->value = strdup(value); param->next = ptr->parameters; + param->qfd_param_type = UNDEFINED_TYPE; ptr->parameters = param; return 1; From 37f8374a10817b8ae1d434099f58404aa8e955ca Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Sat, 21 Nov 2015 15:21:23 +0200 Subject: [PATCH 19/21] Fixed multiline configuration processing The regular expression used when cleaning multiline configuration parameters didn't match trailing backslash characters in pathnames. This caused them to be added to the next line causing a possible error. --- server/core/config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/core/config.c b/server/core/config.c index 2fe378dc2..b68c6733d 100644 --- a/server/core/config.c +++ b/server/core/config.c @@ -146,7 +146,7 @@ char* config_clean_string_list(char* str) int re_err; size_t err_offset; - if ((re = pcre2_compile((PCRE2_SPTR) "[[:space:],]*([^,]+)\\b[[:space:],]*", PCRE2_ZERO_TERMINATED, 0, + if ((re = pcre2_compile((PCRE2_SPTR) "[[:space:],]*([^,]*[^[:space:],])[[:space:],]*", PCRE2_ZERO_TERMINATED, 0, &re_err, &err_offset, NULL)) == NULL || (data = pcre2_match_data_create_from_pattern(re, NULL)) == NULL) { From 1b9920ef10a04a697fb114967d1a309366a3459c Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Mon, 23 Nov 2015 09:25:50 +0200 Subject: [PATCH 20/21] Add notice about previous failure to unlock. In blr_slave.c under certain conditions, two locks were not released. That was fixed in another change, and with this change a notice will be logged if that branch is entered. That way it will be possible to find out whether this may have been the cause of earlier lock-ups. --- server/modules/routing/binlog/blr_slave.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/server/modules/routing/binlog/blr_slave.c b/server/modules/routing/binlog/blr_slave.c index 331e41bea..01a3d84ea 100644 --- a/server/modules/routing/binlog/blr_slave.c +++ b/server/modules/routing/binlog/blr_slave.c @@ -2099,7 +2099,11 @@ char read_errmsg[BINLOG_ERROR_MSG_LEN+1]; spinlock_release(&slave->catch_lock); spinlock_release(&router->binlog_lock); state_change = 1; - } else { + } + else + { + MXS_NOTICE("Execution entered branch were locks previously were NOT " + "released. Previously this would have caused a lock-up."); spinlock_release(&slave->catch_lock); spinlock_release(&router->binlog_lock); } From 23b2ce004bec79788a60c1e2e3846ff288fe812f Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Sun, 22 Nov 2015 19:03:21 +0200 Subject: [PATCH 21/21] Added support for MariaDB 10.1 embedded library The code used in the query classifier was not compatible with 10.1 version of MariaDB and needed to be fine tuned in order for it to work with all supported versions of MariaDB. --- cmake/FindMySQL.cmake | 15 +++++++++++++-- query_classifier/query_classifier.cc | 4 ++-- server/core/CMakeLists.txt | 4 ++-- server/modules/routing/binlog/CMakeLists.txt | 2 +- 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/cmake/FindMySQL.cmake b/cmake/FindMySQL.cmake index 43aec0bfa..4010c8e20 100644 --- a/cmake/FindMySQL.cmake +++ b/cmake/FindMySQL.cmake @@ -15,9 +15,9 @@ endif() file(READ ${MYSQL_VERSION_H} MYSQL_VERSION_CONTENTS) string(REGEX REPLACE ".*MYSQL_SERVER_VERSION[^0-9.]+([0-9.]+).*" "\\1" MYSQL_VERSION ${MYSQL_VERSION_CONTENTS}) -string(REGEX REPLACE ".*MYSQL_COMPILATION_COMMENT.+\"(.+)\".*" "\\1" MYSQL_PROVIDER ${MYSQL_VERSION_CONTENTS}) +string(REGEX REPLACE ".*MYSQL_COMPILATION_COMMENT[[:space:]]+\"(.+)\".*" "\\1" MYSQL_PROVIDER ${MYSQL_VERSION_CONTENTS}) string(TOLOWER ${MYSQL_PROVIDER} MYSQL_PROVIDER) -if(MYSQL_PROVIDER MATCHES "mariadb") +if(MYSQL_PROVIDER MATCHES "[mM]aria[dD][bB]") set(MYSQL_PROVIDER "MariaDB" CACHE INTERNAL "The MySQL provider") elseif(MYSQL_PROVIDER MATCHES "mysql") set(MYSQL_PROVIDER "MySQL" CACHE INTERNAL "The MySQL provider") @@ -36,6 +36,17 @@ if(MYSQL_VERSION VERSION_LESS 5.5.41) message(WARNING "MySQL version is ${MYSQL_VERSION}. Minimum supported version is 5.5.41.") endif() +if(NOT (MYSQL_VERSION VERSION_LESS 10.1)) + + # 10.1 needs lzma + find_library(HAVE_LIBLZMA NAMES lzma) + if(NOT HAVE_LIBLZMA) + message(FATAL_ERROR "Could not find liblzma") + endif() + set(LZMA_LINK_FLAGS "lzma" CACHE STRING "liblzma link flags") +endif() + + if (DEFINED EMBEDDED_LIB) if( NOT (IS_DIRECTORY ${EMBEDDED_LIB}) ) debugmsg("EMBEDDED_LIB is not a directory: ${EMBEDDED_LIB}") diff --git a/query_classifier/query_classifier.cc b/query_classifier/query_classifier.cc index 8cefd370d..b4301c519 100644 --- a/query_classifier/query_classifier.cc +++ b/query_classifier/query_classifier.cc @@ -352,7 +352,7 @@ static bool create_parse_tree( failp = TRUE; goto return_here; } - mysql_reset_thd_for_next_command(thd); + thd->reset_for_next_command(); /** * Set some database to thd so that parsing won't fail because of @@ -804,7 +804,7 @@ static bool skygw_stmt_causes_implicit_commit( switch (lex->sql_command) { case SQLCOM_DROP_TABLE: - succp = !(lex->drop_temporary); + succp = !(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE); break; case SQLCOM_ALTER_TABLE: case SQLCOM_CREATE_TABLE: diff --git a/server/core/CMakeLists.txt b/server/core/CMakeLists.txt index 9687ee699..53004c811 100644 --- a/server/core/CMakeLists.txt +++ b/server/core/CMakeLists.txt @@ -5,7 +5,7 @@ if(BUILD_TESTS OR BUILD_TOOLS) elseif(WITH_TCMALLOC) target_link_libraries(fullcore ${TCMALLOC_LIBRARIES}) endif() - target_link_libraries(fullcore ${CURL_LIBRARIES} utils log_manager pthread ${EMBEDDED_LIB} ${PCRE_LINK_FLAGS} ssl aio rt crypt dl crypto inih z m stdc++) + target_link_libraries(fullcore ${CURL_LIBRARIES} utils log_manager pthread ${LZMA_LINK_FLAGS} ${EMBEDDED_LIB} ${PCRE_LINK_FLAGS} ssl aio rt crypt dl crypto inih z m stdc++) add_dependencies(fullcore pcre2) endif() @@ -22,7 +22,7 @@ elseif(WITH_TCMALLOC) target_link_libraries(maxscale ${TCMALLOC_LIBRARIES}) endif() -target_link_libraries(maxscale ${EMBEDDED_LIB} ${PCRE_LINK_FLAGS} ${CURL_LIBRARIES} log_manager utils ssl aio pthread crypt dl crypto inih z rt m stdc++) +target_link_libraries(maxscale ${LZMA_LINK_FLAGS} ${EMBEDDED_LIB} ${PCRE_LINK_FLAGS} ${CURL_LIBRARIES} log_manager utils ssl aio pthread crypt dl crypto inih z rt m stdc++) install(TARGETS maxscale DESTINATION ${MAXSCALE_BINDIR}) add_executable(maxkeys maxkeys.c spinlock.c secrets.c utils.c gwdirs.c random_jkiss.c ${CMAKE_SOURCE_DIR}/log_manager/log_manager.cc) diff --git a/server/modules/routing/binlog/CMakeLists.txt b/server/modules/routing/binlog/CMakeLists.txt index dda5889d3..11ba80dcb 100644 --- a/server/modules/routing/binlog/CMakeLists.txt +++ b/server/modules/routing/binlog/CMakeLists.txt @@ -20,7 +20,7 @@ add_executable(maxbinlogcheck maxbinlogcheck.c blr_file.c blr_cache.c blr_master ${CMAKE_SOURCE_DIR}/log_manager/log_manager.cc) -target_link_libraries(maxbinlogcheck utils ssl pthread ${EMBEDDED_LIB} ${PCRE_LINK_FLAGS} aio rt crypt dl crypto inih z m stdc++ ${CURL_LIBRARIES}) +target_link_libraries(maxbinlogcheck utils ssl pthread ${LZMA_LINK_FLAGS} ${EMBEDDED_LIB} ${PCRE_LINK_FLAGS} aio rt crypt dl crypto inih z m stdc++ ${CURL_LIBRARIES}) install(TARGETS maxbinlogcheck DESTINATION bin)