From ab737dc84901621990fee9decbafad2b40c86e18 Mon Sep 17 00:00:00 2001 From: MassimilianoPinto Date: Tue, 17 Nov 2015 15:26:50 +0100 Subject: [PATCH 01/20] Documentation update Documentation update with new option: send_slave_heartbeat --- .../Tutorials/Replication-Proxy-Binlog-Router-Tutorial.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/Tutorials/Replication-Proxy-Binlog-Router-Tutorial.md b/Documentation/Tutorials/Replication-Proxy-Binlog-Router-Tutorial.md index d170cd827..30fe5ca24 100644 --- a/Documentation/Tutorials/Replication-Proxy-Binlog-Router-Tutorial.md +++ b/Documentation/Tutorials/Replication-Proxy-Binlog-Router-Tutorial.md @@ -104,6 +104,12 @@ The password of the above user. If the password is not explicitly given then the This defines the value of the heartbeat interval in seconds for the connection to the master. MaxScale requests the master to ensure that a binlog event is sent at least every heartbeat period. If there are no real binlog events to send the master will sent a special heartbeat event. The default value for the heartbeat period is every 5 minutes. The current interval value is reported in the diagnostic output. +### send_slave_heartbeat + +This defines whether (on | off) MaxSclale sends to the slave the heartbeat packet when there are no real binlog events to send. The default value if 'off', no heartbeat event is sent to slave server. If value is 'on' the interval value (requested by the slave during registration) is reported in the diagnostic output and the packect is send after the time interval without any event to send. + +### send_slave_heartbeat + ### burstsize This parameter is used to define the maximum amount of data that will be sent to a slave by MaxScale when that slave is lagging behind the master. In this situation the slave is said to be in "catchup mode", this parameter is designed to both prevent flooding of that slave and also to prevent threads within MaxScale spending disproportionate amounts of time with slaves that are lagging behind the master. The burst size can be defined in Kb, Mb or Gb by adding the qualifier K, M or G to the number given. The default value of burstsize is 1Mb and will be used if burstsize is not given in the router options. From 521165d20a96bf2eff3880eb5f601a33ab0b823d Mon Sep 17 00:00:00 2001 From: MassimilianoPinto Date: Tue, 17 Nov 2015 15:29:15 +0100 Subject: [PATCH 02/20] Documentation update Documentation update --- .../Tutorials/Replication-Proxy-Binlog-Router-Tutorial.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/Documentation/Tutorials/Replication-Proxy-Binlog-Router-Tutorial.md b/Documentation/Tutorials/Replication-Proxy-Binlog-Router-Tutorial.md index 30fe5ca24..5e83a5da8 100644 --- a/Documentation/Tutorials/Replication-Proxy-Binlog-Router-Tutorial.md +++ b/Documentation/Tutorials/Replication-Proxy-Binlog-Router-Tutorial.md @@ -108,8 +108,6 @@ This defines the value of the heartbeat interval in seconds for the connection t This defines whether (on | off) MaxSclale sends to the slave the heartbeat packet when there are no real binlog events to send. The default value if 'off', no heartbeat event is sent to slave server. If value is 'on' the interval value (requested by the slave during registration) is reported in the diagnostic output and the packect is send after the time interval without any event to send. -### send_slave_heartbeat - ### burstsize This parameter is used to define the maximum amount of data that will be sent to a slave by MaxScale when that slave is lagging behind the master. In this situation the slave is said to be in "catchup mode", this parameter is designed to both prevent flooding of that slave and also to prevent threads within MaxScale spending disproportionate amounts of time with slaves that are lagging behind the master. The burst size can be defined in Kb, Mb or Gb by adding the qualifier K, M or G to the number given. The default value of burstsize is 1Mb and will be used if burstsize is not given in the router options. From 86db0f8754f72e7de5557ac90ba03efa8c3aa245 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Wed, 18 Nov 2015 04:35:03 +0200 Subject: [PATCH 03/20] Fixed event names being truncated A buffer was allocated for strlen(event) characters leading to the name always being truncated by one character. The use of a buffer was unnecessary and was fixed by using the mon_get_event_name function directly. --- server/modules/monitor/monitor_common.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/server/modules/monitor/monitor_common.c b/server/modules/monitor/monitor_common.c index ba65f4192..4a56056ba 100644 --- a/server/modules/monitor/monitor_common.c +++ b/server/modules/monitor/monitor_common.c @@ -314,11 +314,9 @@ bool mon_print_fail_status( void monitor_launch_script(MONITOR* mon, MONITOR_SERVERS* ptr, char* script) { char nodelist[PATH_MAX + MON_ARG_MAX + 1] = {'\0'}; - char event[strlen(mon_get_event_name(ptr))]; char initiator[strlen(ptr->server->name) + 24]; // Extra space for port snprintf(initiator, sizeof(initiator), "%s:%d", ptr->server->name, ptr->server->port); - snprintf(event, sizeof(event), "%s", mon_get_event_name(ptr)); mon_append_node_names(mon->databases, nodelist, PATH_MAX + MON_ARG_MAX); EXTERNCMD* cmd = externcmd_allocate(script); @@ -330,7 +328,7 @@ void monitor_launch_script(MONITOR* mon, MONITOR_SERVERS* ptr, char* script) } externcmd_substitute_arg(cmd, "[$]INITIATOR", initiator); - externcmd_substitute_arg(cmd, "[$]EVENT", event); + externcmd_substitute_arg(cmd, "[$]EVENT", mon_get_event_name(ptr)); externcmd_substitute_arg(cmd, "[$]NODELIST", nodelist); if (externcmd_execute(cmd)) From da74bb7c3f294b3c8473c584e7fe4d337a70b78b Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Wed, 18 Nov 2015 07:52:10 +0200 Subject: [PATCH 04/20] Formatted dbfwfilter according to the style guide Fixed indentation, bracket alignment and other minor things. --- server/modules/filter/dbfwfilter.c | 2751 +++++++++++++++------------- 1 file changed, 1433 insertions(+), 1318 deletions(-) diff --git a/server/modules/filter/dbfwfilter.c b/server/modules/filter/dbfwfilter.c index 7334011a4..6fee69669 100644 --- a/server/modules/filter/dbfwfilter.c +++ b/server/modules/filter/dbfwfilter.c @@ -44,7 +44,7 @@ * users John@192.168.% Jane@192.168.0.1 match any rules block_salary *@endcode * - * The 'match' keyword controls the way rules are matched. If it is set to + * The 'match' keyword controls the way rules are matched. If it is set to * 'any' the first active rule that is triggered will cause the query to be denied. * If it is set to 'all' all the active rules need to match before the query is denied. * @@ -54,9 +54,9 @@ * rule NAME deny [wildcard | columns VALUE ... | regex REGEX | limit_queries COUNT TIMEPERIOD HOLDOFF | no_where_clause] [at_times VALUE...] [on_queries [select|update|insert|delete]] *@endcode * @subsection secUser User syntax - * This is the syntax used when linking users to rules. It takes one or more - * combinations of username and network, either the value any or all, - * depending on how you want to match the rules, and one or more rule names. + * This is the syntax used when linking users to rules. It takes one or more + * combinations of username and network, either the value any or all, + * depending on how you want to match the rules, and one or more rule names. *@code{.unparsed} * users NAME ... match [any|all|strict_all] rules RULE ... *@endcode @@ -77,16 +77,18 @@ #include #include -MODULE_INFO info = { +MODULE_INFO info = +{ MODULE_API_FILTER, - MODULE_ALPHA_RELEASE, - FILTER_VERSION, - "Firewall Filter" + MODULE_ALPHA_RELEASE, + FILTER_VERSION, + "Firewall Filter" }; static char *version_str = "V1.0.0"; -static char* required_rules[] = { +static char* required_rules[] = +{ "wildcard", "columns", "regex", @@ -97,153 +99,162 @@ static char* required_rules[] = { /* * 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, - routeQuery, - NULL, - diagnostic, + newSession, + closeSession, + freeSession, + setDownstream, + NULL, + routeQuery, + NULL, + diagnostic, }; - /** * Rule types */ -typedef enum { +typedef enum +{ RT_UNDEFINED = 0x00, /*< Undefined rule */ RT_COLUMN, /*< Column name rule*/ - RT_THROTTLE, /*< Query speed rule */ - RT_PERMISSION, /*< Simple denying rule */ - RT_WILDCARD, /*< Wildcard denial rule */ - RT_REGEX, /*< Regex matching rule */ - RT_CLAUSE /*< WHERE-clause requirement rule */ -}ruletype_t; + RT_THROTTLE, /*< Query speed rule */ + RT_PERMISSION, /*< Simple denying rule */ + RT_WILDCARD, /*< Wildcard denial rule */ + RT_REGEX, /*< Regex matching rule */ + RT_CLAUSE /*< WHERE-clause requirement rule */ +} ruletype_t; -const char* rule_names[] = { +const char* rule_names[] = +{ "UNDEFINED", - "COLUMN", - "THROTTLE", - "PERMISSION", - "WILDCARD", - "REGEX", - "CLAUSE" + "COLUMN", + "THROTTLE", + "PERMISSION", + "WILDCARD", + "REGEX", + "CLAUSE" }; - /** * Linked list of strings. */ -typedef struct strlink_t{ +typedef struct strlink_t +{ struct strlink_t *next; /*< Next node in the list */ char* value; /*< Value of the current node */ -}STRLINK; +} STRLINK; /** * A structure defining a range of time */ -typedef struct timerange_t{ - struct timerange_t* next; /*< Next node in the list */ +typedef struct timerange_t +{ + struct timerange_t* next; /*< Next node in the list */ struct tm start; /*< Start of the time range */ struct tm end; /*< End of the time range */ -}TIMERANGE; +} TIMERANGE; /** * Query speed measurement and limitation structure */ -typedef struct queryspeed_t{ +typedef struct queryspeed_t +{ time_t first_query; /*< Time when the first query occurred */ time_t triggered; /*< Time when the limit was exceeded */ double period; /*< Measurement interval in seconds */ - double cooldown;/*< Time the user is denied access for */ + double cooldown; /*< Time the user is denied access for */ int count; /*< Number of queries done */ int limit; /*< Maximum number of queries */ long id; /*< Unique id of the rule */ bool active; /*< If the rule has been triggered */ struct queryspeed_t* next; /*< Next node in the list */ -}QUERYSPEED; - +} QUERYSPEED; /** * A structure used to identify individual rules and to store their contents - * + * * Each type of rule has different requirements that are expressed as void pointers. * This allows to match an arbitrary set of rules against a user. */ -typedef struct rule_t{ - void* data; /*< Actual implementation of the rule */ - char* name; /*< Name of the rule */ - ruletype_t type;/*< Type of the rule */ - skygw_query_op_t on_queries;/*< Types of queries to inspect */ - bool allow;/*< Allow or deny the query if this rule matches */ - int times_matched;/*< Number of times this rule has been matched */ - TIMERANGE* active;/*< List of times when this rule is active */ -}RULE; +typedef struct rule_t +{ + void* data; /*< Actual implementation of the rule */ + char* name; /*< Name of the rule */ + ruletype_t type; /*< Type of the rule */ + skygw_query_op_t on_queries; /*< Types of queries to inspect */ + bool allow; /*< Allow or deny the query if this rule matches */ + int times_matched; /*< Number of times this rule has been matched */ + TIMERANGE* active; /*< List of times when this rule is active */ +} RULE; /** * Linked list of pointers to a global pool of RULE structs */ -typedef struct rulelist_t{ - RULE* rule; /*< The rule structure */ - struct rulelist_t* next;/*< Next node in the list */ -}RULELIST; +typedef struct rulelist_t +{ + RULE* rule; /*< The rule structure */ + struct rulelist_t* next; /*< Next node in the list */ +} RULELIST; -typedef struct user_t{ - char* name;/*< Name of the user */ - SPINLOCK lock;/*< User spinlock */ - QUERYSPEED* qs_limit;/*< The query speed structure unique to this user */ - RULELIST* rules_or;/*< If any of these rules match the action is triggered */ - RULELIST* rules_and;/*< All of these rules must match for the action to trigger */ +typedef struct user_t +{ + char* name; /*< Name of the user */ + SPINLOCK lock; /*< User spinlock */ + QUERYSPEED* qs_limit; /*< The query speed structure unique to this user */ + RULELIST* rules_or; /*< If any of these rules match the action is triggered */ + RULELIST* rules_and; /*< All of these rules must match for the action to trigger */ RULELIST* rules_strict_and; /*< rules that skip the rest of the rules if one of them * fails. This is only for rules paired with 'match strict_all'. */ - -}USER; + +} USER; /** * Linked list of IP adresses and subnet masks */ -typedef struct iprange_t{ - struct iprange_t* next;/*< Next node in the list */ - uint32_t ip;/*< IP address */ - uint32_t mask;/*< Network mask */ -}IPRANGE; +typedef struct iprange_t +{ + struct iprange_t* next; /*< Next node in the list */ + uint32_t ip; /*< IP address */ + uint32_t mask; /*< Network mask */ +} IPRANGE; /** * The Firewall filter instance. */ -typedef struct { - HASHTABLE* htable; /*< User hashtable */ - RULELIST* rules;/*< List of all the rules */ - STRLINK* userstrings;/*< Temporary list of raw strings of users */ - bool def_op;/*< Default operation mode, defaults to deny */ - SPINLOCK* lock;/*< Instance spinlock */ - long idgen; /*< UID generator */ - int regflags; +typedef struct +{ + HASHTABLE* htable; /*< User hashtable */ + RULELIST* rules; /*< List of all the rules */ + STRLINK* userstrings; /*< Temporary list of raw strings of users */ + bool def_op; /*< Default operation mode, defaults to deny */ + SPINLOCK* lock; /*< Instance spinlock */ + long idgen; /*< UID generator */ + int regflags; } FW_INSTANCE; /** * The session structure for Firewall filter. */ -typedef struct { - SESSION* session;/*< Client session structure */ - char* errmsg;/*< Rule specific error message */ - DOWNSTREAM down;/*< Next object in the downstream chain */ - UPSTREAM up;/*< Next object in the upstream chain */ +typedef struct +{ + SESSION* session; /*< Client session structure */ + char* errmsg; /*< Rule specific error message */ + DOWNSTREAM down; /*< Next object in the downstream chain */ + UPSTREAM up; /*< Next object in the upstream chain */ } FW_SESSION; static int hashkeyfun(void* key); -static int hashcmpfun (void *, void *); +static int hashcmpfun(void *, void *); /** * Hashtable key hashing function. Uses a simple string hashing algorithm. @@ -251,70 +262,74 @@ static int hashcmpfun (void *, void *); * @return The hash value of the key */ static int hashkeyfun( - void* key) + void* key) { - if(key == NULL){ - return 0; - } - unsigned int hash = 0,c = 0; - char* ptr = (char*)key; - while((c = *ptr++)){ - hash = c + (hash << 6) + (hash << 16) - hash; - } - return hash; + if (key == NULL) + { + return 0; + } + unsigned int hash = 0, c = 0; + char* ptr = (char*) key; + while ((c = *ptr++)) + { + hash = c + (hash << 6) + (hash << 16) - hash; + } + return hash; } + /** - * Hashtable entry comparison function. Does a string matching operation on the - * two keys. This function assumes the values are pointers to null-terminated + * Hashtable entry comparison function. Does a string matching operation on the + * two keys. This function assumes the values are pointers to null-terminated * character arrays. * @param v1 The first key * @param v2 The second key * @return Zero if the values are equal. Non-zero in other cases. */ static int hashcmpfun( - void* v1, - void* v2) + void* v1, + void* v2) { - char* i1 = (char*) v1; - char* i2 = (char*) v2; + char* i1 = (char*) v1; + char* i2 = (char*) v2; - return strcmp(i1,i2); + return strcmp(i1, i2); } - void* rlistdup(void* fval) { - - RULELIST *rule = NULL, - *ptr = (RULELIST*)fval; + + RULELIST *rule = NULL, + *ptr = (RULELIST*) fval; - while(ptr){ - RULELIST* tmp = (RULELIST*)malloc(sizeof(RULELIST)); - tmp->next = rule; - tmp->rule = ptr->rule; - rule = tmp; - ptr = ptr->next; - } - - return (void*)rule; + while (ptr) + { + RULELIST* tmp = (RULELIST*) malloc(sizeof(RULELIST)); + tmp->next = rule; + tmp->rule = ptr->rule; + rule = tmp; + ptr = ptr->next; + } + + return(void*) rule; } static void* hrulefree(void* fval) { - RULELIST *ptr = (RULELIST*)fval; - while(ptr){ - RULELIST *tmp = ptr; - ptr = ptr->next; - free(tmp); - } - return NULL; + RULELIST *ptr = (RULELIST*) fval; + while (ptr) + { + RULELIST *tmp = ptr; + ptr = ptr->next; + free(tmp); + } + return NULL; } static void* huserfree(void* fval) { - USER* value = (USER*)fval; + USER* value = (USER*) fval; hrulefree(value->rules_and); hrulefree(value->rules_or); @@ -334,29 +349,34 @@ static void* huserfree(void* fval) char* strip_tags(char* str) { - assert(str != NULL); + assert(str != NULL); - char *ptr = str,*re_start = NULL; - bool found = false; - while(*ptr != '\0'){ + char *ptr = str, *re_start = NULL; + bool found = false; + while (*ptr != '\0') + { - if(*ptr == '"' || - *ptr == '\''){ - if(found){ - *ptr = '\0'; - memmove(str,re_start,ptr - re_start); - break; - }else{ - *ptr = ' '; - re_start = ptr + 1; - found = true; - } - } - ptr++; + if (*ptr == '"' || + *ptr == '\'') + { + if (found) + { + *ptr = '\0'; + memmove(str, re_start, ptr - re_start); + break; + } + else + { + *ptr = ' '; + re_start = ptr + 1; + found = true; + } + } + ptr++; - } + } - return str; + return str; } /** @@ -367,78 +387,95 @@ char* strip_tags(char* str) */ char* next_ip_class(char* str) { - assert(str != NULL); + assert(str != NULL); - /**The least specific form is reached*/ - if(*str == '%'){ - return NULL; - } + /**The least specific form is reached*/ + if (*str == '%') + { + return NULL; + } - char* ptr = strchr(str,'\0'); + char* ptr = strchr(str, '\0'); - if(ptr == NULL){ - return NULL; - } + if (ptr == NULL) + { + return NULL; + } - while(ptr > str){ - ptr--; - if(*ptr == '.' && *(ptr+1) != '%'){ - break; - } - } - - if(ptr == str){ - *ptr++ = '%'; - *ptr = '\0'; - return str; - } + while (ptr > str) + { + ptr--; + if (*ptr == '.' && *(ptr + 1) != '%') + { + break; + } + } - *++ptr = '%'; - *++ptr = '\0'; + if (ptr == str) + { + *ptr++ = '%'; + *ptr = '\0'; + return str; + } + + *++ptr = '%'; + *++ptr = '\0'; - return str; + return str; } + /** * Parses the strign for the types of queries this rule should be applied to. * @param str String to parse * @param rule Poiter to a rule * @return True if the string was parses successfully, false if an error occurred */ -bool parse_querytypes(char* str,RULE* rule) +bool parse_querytypes(char* str, RULE* rule) { - char buffer[512]; - char *ptr,*dest; - bool done = false; - rule->on_queries = 0; - ptr = str; - dest = buffer; + char buffer[512]; + char *ptr, *dest; + bool done = false; + rule->on_queries = 0; + ptr = str; + dest = buffer; - while(ptr - buffer < 512) + while (ptr - buffer < 512) { - if(*ptr == '|' || *ptr == ' ' || (done = *ptr == '\0')){ + if (*ptr == '|' || *ptr == ' ' || (done = *ptr == '\0')) + { *dest = '\0'; - if(strcmp(buffer,"select") == 0){ + if (strcmp(buffer, "select") == 0) + { rule->on_queries |= QUERY_OP_SELECT; - }else if(strcmp(buffer,"insert") == 0){ + } + else if (strcmp(buffer, "insert") == 0) + { rule->on_queries |= QUERY_OP_INSERT; - }else if(strcmp(buffer,"update") == 0){ + } + else if (strcmp(buffer, "update") == 0) + { rule->on_queries |= QUERY_OP_UPDATE; - }else if(strcmp(buffer,"delete") == 0){ + } + else if (strcmp(buffer, "delete") == 0) + { rule->on_queries |= QUERY_OP_DELETE; } - if(done){ + if (done) + { return true; } dest = buffer; ptr++; - }else{ + } + else + { *dest++ = *ptr++; } } - return false; + return false; } /** @@ -449,17 +486,27 @@ bool parse_querytypes(char* str,RULE* rule) */ bool check_time(char* str) { - assert(str != NULL); + assert(str != NULL); - char* ptr = str; - int colons = 0,numbers = 0,dashes = 0; - while(*ptr && ptr - str < 18){ - if(isdigit(*ptr)){numbers++;} - else if(*ptr == ':'){colons++;} - else if(*ptr == '-'){dashes++;} - ptr++; - } - return numbers == 12 && colons == 4 && dashes == 1; + char* ptr = str; + int colons = 0, numbers = 0, dashes = 0; + while (*ptr && ptr - str < 18) + { + if (isdigit(*ptr)) + { + numbers++; + } + else if (*ptr == ':') + { + colons++; + } + else if (*ptr == '-') + { + dashes++; + } + ptr++; + } + return numbers == 12 && colons == 4 && dashes == 1; } @@ -528,21 +575,22 @@ static TIMERANGE* parse_time(const char* str) */ TIMERANGE* split_reverse_time(TIMERANGE* tr) { - TIMERANGE* tmp = NULL; - - if(IS_RVRS_TIME(tr)){ - tmp = (TIMERANGE*)calloc(1,sizeof(TIMERANGE)); - tmp->next = tr; - tmp->start.tm_hour = 0; - tmp->start.tm_min = 0; - tmp->start.tm_sec = 0; - tmp->end = tr->end; - tr->end.tm_hour = 23; - tr->end.tm_min = 59; - tr->end.tm_sec = 59; - } + TIMERANGE* tmp = NULL; - return tmp; + if (IS_RVRS_TIME(tr)) + { + tmp = (TIMERANGE*) calloc(1, sizeof(TIMERANGE)); + tmp->next = tr; + tmp->start.tm_hour = 0; + tmp->start.tm_min = 0; + tmp->start.tm_sec = 0; + tmp->end = tr->end; + tr->end.tm_hour = 23; + tr->end.tm_min = 59; + tr->end.tm_sec = 59; + } + + return tmp; } /** @@ -550,18 +598,16 @@ TIMERANGE* split_reverse_time(TIMERANGE* tr) * * @return version string of the module */ -char * -version() +char * version() { - return version_str; + return version_str; } /** -* The module initialisation routine, called when the module -* is first loaded. -*/ -void -ModuleInit() + * The module initialisation routine, called when the module + * is first loaded. + */ +void ModuleInit() { } @@ -573,10 +619,9 @@ ModuleInit() * * @return The module object */ -FILTER_OBJECT * -GetModuleObject() +FILTER_OBJECT * GetModuleObject() { - return &MyObject; + return &MyObject; } /** @@ -588,16 +633,18 @@ GetModuleObject() */ RULE* find_rule(char* tok, FW_INSTANCE* instance) { - RULELIST* rlist = instance->rules; + RULELIST* rlist = instance->rules; - while(rlist){ - if(strcmp(rlist->rule->name,tok) == 0){ - return rlist->rule; - } - rlist = rlist->next; - } - MXS_ERROR("Rule not found: %s",tok); - return NULL; + while (rlist) + { + if (strcmp(rlist->rule->name, tok) == 0) + { + return rlist->rule; + } + rlist = rlist->next; + } + MXS_ERROR("Rule not found: %s", tok); + return NULL; } /** @@ -607,19 +654,19 @@ RULE* find_rule(char* tok, FW_INSTANCE* instance) */ void add_users(char* rule, FW_INSTANCE* instance) { - assert(rule != NULL && instance != NULL); + assert(rule != NULL && instance != NULL); - STRLINK* link = calloc(1,sizeof(STRLINK)); - if(link == NULL){ - MXS_ERROR("Memory allocation failed"); - return; - } - link->next = instance->userstrings; - link->value = strdup(rule); - instance->userstrings = link; + STRLINK* link = calloc(1, sizeof(STRLINK)); + if (link == NULL) + { + MXS_ERROR("Memory allocation failed"); + return; + } + link->next = instance->userstrings; + link->value = strdup(rule); + instance->userstrings = link; } - /** * Parses the list of rule strings for users and links them against the listed rules. * Only adds those rules that are found. If the rule isn't found a message is written to the error log. @@ -628,195 +675,207 @@ void add_users(char* rule, FW_INSTANCE* instance) */ bool link_rules(char* orig, FW_INSTANCE* instance) { - - /**Apply rules to users*/ - bool match_any = true; - bool rval = true; - char *rule = strdup(orig); - char *tok, *ruleptr, *userptr, *modeptr; - char *saveptr = NULL; - RULELIST* rulelist = NULL; - bool strict = false; - userptr = strstr(rule,"users "); - modeptr = strstr(rule," match "); - ruleptr = strstr(rule," rules "); + /**Apply rules to users*/ - if((userptr == NULL || ruleptr == NULL || modeptr == NULL)|| - (userptr > modeptr || userptr > ruleptr || modeptr > ruleptr)) { - MXS_ERROR("dbfwfilter: Rule syntax incorrect, right keywords not found in the correct order: %s",orig); + bool match_any = true; + bool rval = true; + char *rule = strdup(orig); + char *tok, *ruleptr, *userptr, *modeptr; + char *saveptr = NULL; + RULELIST* rulelist = NULL; + bool strict = false; + userptr = strstr(rule, "users "); + modeptr = strstr(rule, " match "); + ruleptr = strstr(rule, " rules "); + + if ((userptr == NULL || ruleptr == NULL || modeptr == NULL) || + (userptr > modeptr || userptr > ruleptr || modeptr > ruleptr)) + { + MXS_ERROR("dbfwfilter: Rule syntax incorrect, right keywords not found in the correct order: %s", orig); + rval = false; + goto parse_err; + } + + *modeptr++ = '\0'; + *ruleptr++ = '\0'; + + tok = strtok_r(modeptr, " ", &saveptr); + + if (tok == NULL) + { + MXS_ERROR("dbfwfilter: Rule syntax incorrect, right keywords not found in the correct order: %s", orig); + rval = false; + goto parse_err; + } + + if (strcmp(tok, "match") == 0) + { + tok = strtok_r(NULL, " ", &saveptr); + if (tok == NULL) + { + MXS_ERROR("dbfwfilter: Rule syntax incorrect, missing keyword after 'match': %s", orig); rval = false; goto parse_err; - } - - *modeptr++ = '\0'; - *ruleptr++ = '\0'; - - tok = strtok_r(modeptr," ",&saveptr); + } + if (strcmp(tok, "any") == 0) + { + match_any = true; + } + else if (strcmp(tok, "all") == 0) + { + match_any = false; + } + else if (strcmp(tok, "strict_all") == 0) + { + match_any = false; + strict = true; + } + else + { + MXS_ERROR("dbfwfilter: Rule syntax incorrect, 'match' was not followed by correct keyword: %s", orig); + rval = false; + goto parse_err; + } + } + else + { + MXS_ERROR("dbfwfilter: Rule syntax incorrect, bad token: %s", tok); + rval = false; + goto parse_err; + } - if(tok == NULL) - { - MXS_ERROR("dbfwfilter: Rule syntax incorrect, right keywords not found in the correct order: %s",orig); - rval = false; - goto parse_err; - } + tok = strtok_r(NULL, " ", &saveptr); - if(strcmp(tok,"match") == 0){ - tok = strtok_r(NULL," ",&saveptr); - if(tok == NULL) - { - MXS_ERROR("dbfwfilter: Rule syntax incorrect, missing keyword after 'match': %s",orig); - rval = false; - goto parse_err; - } - if(strcmp(tok,"any") == 0){ - match_any = true; - }else if(strcmp(tok,"all") == 0){ - match_any = false; - }else if(strcmp(tok,"strict_all") == 0){ - match_any = false; - strict = true; - }else{ - MXS_ERROR("dbfwfilter: Rule syntax incorrect, 'match' was not followed by correct keyword: %s",orig); - rval = false; - goto parse_err; - } - } - else - { - MXS_ERROR("dbfwfilter: Rule syntax incorrect, bad token: %s",tok); - rval = false; - goto parse_err; - } + if (tok != NULL) + { + MXS_ERROR("dbfwfilter: Rule syntax incorrect, extra token found after 'match' keyword: %s", orig); + rval = false; + goto parse_err; + } - tok = strtok_r(NULL," ",&saveptr); + tok = strtok_r(ruleptr, " ", &saveptr); - if(tok != NULL) - { - MXS_ERROR("dbfwfilter: Rule syntax incorrect, extra token found after 'match' keyword: %s",orig); - rval = false; - goto parse_err; - } + if (tok == NULL) + { + MXS_ERROR("dbfwfilter: Rule syntax incorrect, no rules given: %s", orig); + rval = false; + goto parse_err; + } - tok = strtok_r(ruleptr," ",&saveptr); + tok = strtok_r(NULL, " ", &saveptr); - if(tok == NULL) - { - MXS_ERROR("dbfwfilter: Rule syntax incorrect, no rules given: %s",orig); - rval = false; - goto parse_err; - } + if (tok == NULL) + { + MXS_ERROR("dbfwfilter: Rule syntax incorrect, no rules given: %s", orig); + rval = false; + goto parse_err; + } - tok = strtok_r(NULL," ",&saveptr); + while (tok) + { + RULE* rule_found = NULL; - if(tok == NULL) - { - MXS_ERROR("dbfwfilter: Rule syntax incorrect, no rules given: %s",orig); - rval = false; - goto parse_err; - } + if ((rule_found = find_rule(tok, instance)) != NULL) + { + RULELIST* tmp_rl = (RULELIST*) calloc(1, sizeof(RULELIST)); + tmp_rl->rule = rule_found; + tmp_rl->next = rulelist; + rulelist = tmp_rl; - while(tok) - { - RULE* rule_found = NULL; + } + else + { + MXS_ERROR("dbfwfilter: Rule syntax incorrect, could not find rule '%s'.", tok); + rval = false; + goto parse_err; + } + tok = strtok_r(NULL, " ", &saveptr); + } - if((rule_found = find_rule(tok,instance)) != NULL) - { - RULELIST* tmp_rl = (RULELIST*)calloc(1,sizeof(RULELIST)); - tmp_rl->rule = rule_found; - tmp_rl->next = rulelist; - rulelist = tmp_rl; + /** + * Apply this list of rules to all the listed users + */ - } - else - { - MXS_ERROR("dbfwfilter: Rule syntax incorrect, could not find rule '%s'.",tok); - rval = false; - goto parse_err; - } - tok = strtok_r(NULL," ",&saveptr); - } + *(ruleptr) = '\0'; + userptr = strtok_r(rule, " ", &saveptr); + userptr = strtok_r(NULL, " ", &saveptr); - /** - * Apply this list of rules to all the listed users - */ + if (userptr == NULL) + { + MXS_ERROR("dbfwfilter: Rule syntax incorrect, no users given: %s", orig); + rval = false; + goto parse_err; + } - *(ruleptr) = '\0'; - userptr = strtok_r(rule," ",&saveptr); - userptr = strtok_r(NULL," ",&saveptr); + if (rulelist == NULL) + { + MXS_ERROR("dbfwfilter: Rule syntax incorrect, no rules found: %s", orig); + rval = false; + goto parse_err; + } - if(userptr == NULL) - { - MXS_ERROR("dbfwfilter: Rule syntax incorrect, no users given: %s",orig); - rval = false; - goto parse_err; - } - - if(rulelist == NULL) - { - MXS_ERROR("dbfwfilter: Rule syntax incorrect, no rules found: %s",orig); - rval = false; - goto parse_err; - } - - while(userptr) - { + while (userptr) + { USER* user; - RULELIST *tl = NULL,*tail = NULL; + RULELIST *tl = NULL, *tail = NULL; - if((user = (USER*)hashtable_fetch(instance->htable,userptr)) == NULL){ + if ((user = (USER*) hashtable_fetch(instance->htable, userptr)) == NULL) + { /**New user*/ - user = (USER*)calloc(1,sizeof(USER)); + user = (USER*) calloc(1, sizeof(USER)); - if(user == NULL){ - MXS_ERROR("dbfwfilter: failed to allocate memory when parsing rules."); - rval = false; - goto parse_err; + if (user == NULL) + { + MXS_ERROR("dbfwfilter: failed to allocate memory when parsing rules."); + rval = false; + goto parse_err; } spinlock_init(&user->lock); } - user->name = (char*)strdup(userptr); + user->name = (char*) strdup(userptr); user->qs_limit = NULL; - tl = (RULELIST*)rlistdup(rulelist); + tl = (RULELIST*) rlistdup(rulelist); tail = tl; - while(tail && tail->next){ + while (tail && tail->next) + { tail = tail->next; } - - if(match_any){ + + if (match_any) + { tail->next = user->rules_or; user->rules_or = tl; - }else if(strict){ - tail->next = user->rules_and; - user->rules_strict_and = tl; } - else - { - tail->next = user->rules_and; - user->rules_and = tl; - } - - hashtable_add(instance->htable, - (void *)userptr, - (void *)user); - - userptr = strtok_r(NULL," ",&saveptr); - } - parse_err: - - free(rule); - - while(rulelist) + else if (strict) { - RULELIST *tmp = rulelist; - rulelist = rulelist->next; - free(tmp); + tail->next = user->rules_and; + user->rules_strict_and = tl; } - return rval; + else + { + tail->next = user->rules_and; + user->rules_and = tl; + } + + hashtable_add(instance->htable, (void *) userptr, (void *) user); + userptr = strtok_r(NULL, " ", &saveptr); + } +parse_err: + + free(rule); + + while (rulelist) + { + RULELIST *tmp = rulelist; + rulelist = rulelist->next; + free(tmp); + } + return rval; } /** @@ -825,17 +884,18 @@ bool link_rules(char* orig, FW_INSTANCE* instance) */ void tr_free(TIMERANGE* tr) { - TIMERANGE *node,*tmp; + TIMERANGE *node, *tmp; node = tr; - while(node) + while (node) { - tmp = node; - node = node->next; - free(tmp); + tmp = node; + node = node->next; + free(tmp); } } + /** * Parse the configuration value either as a new rule or a list of users. * @param rule The string to parse @@ -847,266 +907,276 @@ bool parse_rule(char* rule, FW_INSTANCE* instance) char *rulecpy = strdup(rule); char *saveptr = NULL; - char *tok = strtok_r(rulecpy," ,",&saveptr); - bool allow,deny,mode; + char *tok = strtok_r(rulecpy, " ,", &saveptr); + bool allow, deny, mode; RULE* ruledef = NULL; bool rval = true; - bool req_defined,oq_def,at_def; + bool req_defined, oq_def, at_def; int i; req_defined = oq_def = at_def = false; - if(tok == NULL) + if (tok == NULL) { - MXS_ERROR("dbfwfilter: Rule parsing failed, no rule: %s",rule); - rval = false; - goto retblock; + MXS_ERROR("dbfwfilter: Rule parsing failed, no rule: %s", rule); + rval = false; + goto retblock; } - if(strcmp("rule",tok) == 0) + if (strcmp("rule", tok) == 0) { - /**Define a new rule*/ + /**Define a new rule*/ - tok = strtok_r(NULL," ,",&saveptr); + tok = strtok_r(NULL, " ,", &saveptr); - if(tok == NULL) - { - MXS_ERROR("dbfwfilter: Rule parsing failed, incomplete rule: %s",rule); - rval = false; - goto retblock; - } + if (tok == NULL) + { + MXS_ERROR("dbfwfilter: Rule parsing failed, incomplete rule: %s", rule); + rval = false; + goto retblock; + } - RULELIST* rlist = NULL; + RULELIST* rlist = NULL; - ruledef = (RULE*)calloc(1,sizeof(RULE)); + ruledef = (RULE*) calloc(1, sizeof(RULE)); - if(ruledef == NULL) - { - MXS_ERROR("Memory allocation failed."); - rval = false; - goto retblock; - } + if (ruledef == NULL) + { + MXS_ERROR("Memory allocation failed."); + rval = false; + goto retblock; + } - rlist = (RULELIST*)calloc(1,sizeof(RULELIST)); + rlist = (RULELIST*) calloc(1, sizeof(RULELIST)); - if(rlist == NULL) - { - free(ruledef); - MXS_ERROR("Memory allocation failed."); - rval = false; - goto retblock; - } + if (rlist == NULL) + { + free(ruledef); + MXS_ERROR("Memory allocation failed."); + rval = false; + goto retblock; + } - ruledef->name = strdup(tok); - ruledef->type = RT_UNDEFINED; - ruledef->on_queries = QUERY_OP_UNDEFINED; - rlist->rule = ruledef; - rlist->next = instance->rules; - instance->rules = rlist; + ruledef->name = strdup(tok); + ruledef->type = RT_UNDEFINED; + ruledef->on_queries = QUERY_OP_UNDEFINED; + rlist->rule = ruledef; + rlist->next = instance->rules; + instance->rules = rlist; - }else if(strcmp("users",tok) == 0) + } + else if (strcmp("users", tok) == 0) { - /**Apply rules to users*/ - add_users(rule, instance); - goto retblock; + /**Apply rules to users*/ + add_users(rule, instance); + goto retblock; } else { - MXS_ERROR("Unknown token in rule '%s': %s",rule,tok); - rval = false; - goto retblock; + MXS_ERROR("Unknown token in rule '%s': %s", rule, tok); + rval = false; + goto retblock; } - tok = strtok_r(NULL, " ,",&saveptr); + tok = strtok_r(NULL, " ,", &saveptr); - if(tok == NULL) + if (tok == NULL) { - MXS_ERROR("dbfwfilter: Rule parsing failed, no allow or deny: %s",rule); - rval = false; - goto retblock; + MXS_ERROR("dbfwfilter: Rule parsing failed, no allow or deny: %s", rule); + rval = false; + goto retblock; } - if((allow = (strcmp(tok,"allow") == 0)) || - (deny = (strcmp(tok,"deny") == 0))) + if ((allow = (strcmp(tok, "allow") == 0)) || + (deny = (strcmp(tok, "deny") == 0))) { - mode = allow ? true:false; - ruledef->allow = mode; - ruledef->type = RT_PERMISSION; - tok = strtok_r(NULL, " ,",&saveptr); + mode = allow ? true : false; + ruledef->allow = mode; + ruledef->type = RT_PERMISSION; + tok = strtok_r(NULL, " ,", &saveptr); - while(tok) - { - reparse_rule: - - for(i = 0;required_rules[i] != NULL;i++) - { - if(strcmp(tok,required_rules[i]) == 0) - { - if(req_defined) - { - MXS_ERROR("dbfwfilter: Rule parsing failed, Multiple non-optional rules: %s",rule); - rval = false; - goto retblock; - } - else - { - req_defined = true; - } - } - } + while (tok) + { +reparse_rule: - if(strcmp(tok,"wildcard") == 0) + for (i = 0; required_rules[i] != NULL; i++) + { + if (strcmp(tok, required_rules[i]) == 0) + { + if (req_defined) + { + MXS_ERROR("dbfwfilter: Rule parsing failed, Multiple non-optional rules: %s", rule); + rval = false; + goto retblock; + } + else + { + req_defined = true; + } + } + } + + if (strcmp(tok, "wildcard") == 0) { ruledef->type = RT_WILDCARD; } - else if(strcmp(tok,"columns") == 0) + else if (strcmp(tok, "columns") == 0) { - STRLINK *tail = NULL,*current; + STRLINK *tail = NULL, *current; ruledef->type = RT_COLUMN; - tok = strtok_r(NULL, " ,",&saveptr); - while(tok && strcmp(tok,"at_times") != 0 && - strcmp(tok,"on_queries") != 0){ + tok = strtok_r(NULL, " ,", &saveptr); + while (tok && strcmp(tok, "at_times") != 0 && + strcmp(tok, "on_queries") != 0) + { current = malloc(sizeof(STRLINK)); current->value = strdup(tok); current->next = tail; tail = current; - tok = strtok_r(NULL, " ,",&saveptr); + tok = strtok_r(NULL, " ,", &saveptr); } - ruledef->data = (void*)tail; + ruledef->data = (void*) tail; continue; } - else if(strcmp(tok,"at_times") == 0) + else if (strcmp(tok, "at_times") == 0) { - if(at_def) - { - MXS_ERROR("dbfwfilter: Rule parsing failed, multiple 'at_times' tokens: %s",rule); - rval = false; - goto retblock; - } - at_def = true; - tok = strtok_r(NULL, " ,",&saveptr); + if (at_def) + { + MXS_ERROR("dbfwfilter: Rule parsing failed, multiple 'at_times' tokens: %s", rule); + rval = false; + goto retblock; + } + + at_def = true; + tok = strtok_r(NULL, " ,", &saveptr); TIMERANGE *tr = NULL; - while(tok){ - if(strcmp(tok,"on_queries") == 0) - break; - if(!check_time(tok)) - { - MXS_ERROR("dbfwfilter: Rule parsing failed, malformed time definition: %s",tok); - rval = false; - goto retblock; - } + + while (tok) + { + if (strcmp(tok, "on_queries") == 0) + break; + if (!check_time(tok)) + { + MXS_ERROR("dbfwfilter: Rule parsing failed, malformed time definition: %s", tok); + rval = false; + goto retblock; + } TIMERANGE *tmp = parse_time(tok); - if(tmp == NULL) - { - MXS_ERROR("dbfwfilter: Rule parsing failed, unexpected characters after time definition."); - rval = false; - tr_free(tr); - goto retblock; - } + if (tmp == NULL) + { + MXS_ERROR("dbfwfilter: Rule parsing failed, unexpected characters after time definition."); + rval = false; + tr_free(tr); + goto retblock; + } - if(IS_RVRS_TIME(tmp)) - { + if (IS_RVRS_TIME(tmp)) + { tmp = split_reverse_time(tmp); } + tmp->next = tr; tr = tmp; - tok = strtok_r(NULL, " ,",&saveptr); + tok = strtok_r(NULL, " ,", &saveptr); } ruledef->active = tr; - if(tok && strcmp(tok,"on_queries") == 0) - goto reparse_rule; + if (tok && strcmp(tok, "on_queries") == 0) + { + goto reparse_rule; + } } - else if(strcmp(tok,"regex") == 0) + else if (strcmp(tok, "regex") == 0) { bool escaped = false; regex_t *re; char* start, *str; - tok = strtok_r(NULL," ",&saveptr); - char delim = '\''; - int n_char = 0; + tok = strtok_r(NULL, " ", &saveptr); + char delim = '\''; + int n_char = 0; - if(tok == NULL) - { - MXS_ERROR("dbfwfilter: Rule parsing failed, No regex string."); - rval = false; - goto retblock; - } + if (tok == NULL) + { + MXS_ERROR("dbfwfilter: Rule parsing failed, No regex string."); + rval = false; + goto retblock; + } - if(*tok != '\'' && *tok != '\"') - { - MXS_ERROR("dbfwfilter: Rule parsing failed, regex string not quoted."); - rval = false; - goto retblock; - } + if (*tok != '\'' && *tok != '\"') + { + MXS_ERROR("dbfwfilter: Rule parsing failed, regex string not quoted."); + rval = false; + goto retblock; + } - while(*tok == '\'' || *tok == '"') - { + while (*tok == '\'' || *tok == '"') + { delim = *tok; tok++; } start = tok; - while(isspace(*tok) || *tok == delim) - { + while (isspace(*tok) || *tok == delim) + { tok++; } - while(n_char < 2048) - { + while (n_char < 2048) + { - /** Hard-coded regex length cap */ + /** Hard-coded regex length cap */ - if((*tok == delim) && !escaped) - { + if ((*tok == delim) && !escaped) + { break; } escaped = (*tok == '\\'); tok++; - n_char++; + n_char++; } - if(n_char >= 2048) - { - MXS_ERROR("dbfwfilter: Failed to parse rule, regular expression length is over 2048 characters."); - rval = false; + if (n_char >= 2048) + { + MXS_ERROR("dbfwfilter: Failed to parse rule, regular expression length is over 2048 characters."); + rval = false; goto retblock; - } + } - str = calloc(((tok - start) + 1),sizeof(char)); - if(str == NULL) + str = calloc(((tok - start) + 1), sizeof(char)); + if (str == NULL) { MXS_ERROR("Fatal Error: malloc returned NULL."); - rval = false; + rval = false; goto retblock; } - re = (regex_t*)malloc(sizeof(regex_t)); + re = (regex_t*) malloc(sizeof(regex_t)); - if(re == NULL){ + if (re == NULL) + { MXS_ERROR("Fatal Error: malloc returned NULL."); - rval = false; + rval = false; free(str); goto retblock; } - memcpy(str, start, (tok-start)); + memcpy(str, start, (tok - start)); - if(regcomp(re, str,REG_NOSUB|instance->regflags)){ + if (regcomp(re, str, REG_NOSUB | instance->regflags)) + { MXS_ERROR("dbfwfilter: Invalid regular expression '%s'.", str); - rval = false; + rval = false; free(re); - goto retblock; + goto retblock; } else { @@ -1116,140 +1186,147 @@ bool parse_rule(char* rule, FW_INSTANCE* instance) free(str); } - else if(strcmp(tok,"limit_queries") == 0) + else if (strcmp(tok, "limit_queries") == 0) { - QUERYSPEED* qs = (QUERYSPEED*)calloc(1,sizeof(QUERYSPEED)); - char *errptr = NULL; + QUERYSPEED* qs = (QUERYSPEED*) calloc(1, sizeof(QUERYSPEED)); + char *errptr = NULL; spinlock_acquire(instance->lock); qs->id = ++instance->idgen; spinlock_release(instance->lock); - tok = strtok_r(NULL," ",&saveptr); - if(tok == NULL){ + tok = strtok_r(NULL, " ", &saveptr); + if (tok == NULL) + { free(qs); - rval = false; - MXS_ERROR("dbfwfilter: Missing parameter in limit_queries: '%s'.", rule); + rval = false; + MXS_ERROR("dbfwfilter: Missing parameter in limit_queries: '%s'.", rule); goto retblock; } - qs->limit = strtol(tok,&errptr,0); + qs->limit = strtol(tok, &errptr, 0); - if(errptr && *errptr != '\0') - { - free(qs); - rval = false; - MXS_ERROR("dbfwfilter: Rule parsing failed, not a number: '%s'.", tok); - goto retblock; - } - - if(qs->limit < 1){ + if (errptr && *errptr != '\0') + { free(qs); - rval = false; - MXS_ERROR("dbfwfilter: Bad query amount: %s", tok); + rval = false; + MXS_ERROR("dbfwfilter: Rule parsing failed, not a number: '%s'.", tok); goto retblock; } - errptr = NULL; - tok = strtok_r(NULL," ",&saveptr); - - if(tok == NULL){ + if (qs->limit < 1) + { free(qs); - rval = false; - MXS_ERROR("dbfwfilter: Missing parameter in limit_queries: '%s'.", rule); + rval = false; + MXS_ERROR("dbfwfilter: Bad query amount: %s", tok); goto retblock; } - qs->period = strtod(tok,&errptr); + errptr = NULL; + tok = strtok_r(NULL, " ", &saveptr); - if(errptr && *errptr != '\0') - { - free(qs); - rval = false; - MXS_ERROR("dbfwfilter: Rule parsing failed, not a number: '%s'.", tok); - goto retblock; - } - - if(qs->period < 1){ + if (tok == NULL) + { free(qs); - rval = false; - MXS_ERROR("dbfwfilter: Bad time period: %s", tok); + rval = false; + MXS_ERROR("dbfwfilter: Missing parameter in limit_queries: '%s'.", rule); goto retblock; } - errptr = NULL; - tok = strtok_r(NULL," ",&saveptr); + qs->period = strtod(tok, &errptr); - if(tok == NULL){ + if (errptr && *errptr != '\0') + { free(qs); - rval = false; - MXS_ERROR("dbfwfilter: Missing parameter in limit_queries: '%s'.", rule); + rval = false; + MXS_ERROR("dbfwfilter: Rule parsing failed, not a number: '%s'.", tok); goto retblock; } - qs->cooldown = strtod(tok,&errptr); - if(errptr && *errptr != '\0') - { - free(qs); - rval = false; - MXS_ERROR("dbfwfilter: Rule parsing failed, not a number: '%s'.", tok); - goto retblock; - } - - if(qs->cooldown < 1){ + if (qs->period < 1) + { free(qs); - rval = false; - MXS_ERROR("dbfwfilter: Bad blocking period: %s", tok); + rval = false; + MXS_ERROR("dbfwfilter: Bad time period: %s", tok); + goto retblock; + } + + errptr = NULL; + tok = strtok_r(NULL, " ", &saveptr); + + if (tok == NULL) + { + free(qs); + rval = false; + MXS_ERROR("dbfwfilter: Missing parameter in limit_queries: '%s'.", rule); + goto retblock; + } + qs->cooldown = strtod(tok, &errptr); + + if (errptr && *errptr != '\0') + { + free(qs); + rval = false; + MXS_ERROR("dbfwfilter: Rule parsing failed, not a number: '%s'.", tok); + goto retblock; + } + + if (qs->cooldown < 1) + { + free(qs); + rval = false; + MXS_ERROR("dbfwfilter: Bad blocking period: %s", tok); goto retblock; } ruledef->type = RT_THROTTLE; - ruledef->data = (void*)qs; + ruledef->data = (void*) qs; } - else if(strcmp(tok,"no_where_clause") == 0) + else if (strcmp(tok, "no_where_clause") == 0) { ruledef->type = RT_CLAUSE; - ruledef->data = (void*)mode; + ruledef->data = (void*) mode; } - else if(strcmp(tok,"on_queries") == 0) + else if (strcmp(tok, "on_queries") == 0) { - if(oq_def) - { - MXS_ERROR("dbfwfilter: Rule parsing failed, multiple 'on_queries' tokens: %s",rule); - rval = false; - goto retblock; - } - oq_def = true; - tok = strtok_r(NULL," ",&saveptr); + if (oq_def) + { + MXS_ERROR("dbfwfilter: Rule parsing failed, multiple 'on_queries' tokens: %s", rule); + rval = false; + goto retblock; + } + oq_def = true; + tok = strtok_r(NULL, " ", &saveptr); - if(tok == NULL) - { + if (tok == NULL) + { MXS_ERROR("dbfwfilter: Missing parameter for 'on_queries'."); - rval = false; - goto retblock; - } + rval = false; + goto retblock; + } - if(!parse_querytypes(tok,ruledef)){ + if (!parse_querytypes(tok, ruledef)) + { MXS_ERROR("dbfwfilter: Invalid query type requirements: %s.", tok); - rval = false; - goto retblock; - } + rval = false; + goto retblock; + } } - else - { + else + { MXS_ERROR("dbfwfilter: Unknown rule type: %s", tok); rval = false; goto retblock; - } - tok = strtok_r(NULL," ,",&saveptr); - } + } + tok = strtok_r(NULL, " ,", &saveptr); + } - goto retblock; + goto retblock; } - retblock: - free(rulecpy); +retblock: + free(rulecpy); return rval; } @@ -1258,14 +1335,20 @@ bool is_comment(char* str) { char *ptr = str; - while(*ptr != '\0') + while (*ptr != '\0') { - if(isspace(*ptr)) - ptr++; - else if(*ptr == '#') - return true; - else - return false; + if (isspace(*ptr)) + { + ptr++; + } + else if (*ptr == '#') + { + return true; + } + else + { + return false; + } } return true; } @@ -1273,169 +1356,177 @@ bool is_comment(char* str) /** * 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) { - FW_INSTANCE *my_instance; - int i; - HASHTABLE* ht; - STRLINK *ptr,*tmp; - char *filename = NULL, *nl; - char buffer[2048]; - FILE* file; - bool err = false; + FW_INSTANCE *my_instance; + int i; + HASHTABLE* ht; + STRLINK *ptr, *tmp; + char *filename = NULL, *nl; + char buffer[2048]; + FILE* file; + bool err = false; - if ((my_instance = calloc(1, sizeof(FW_INSTANCE))) == NULL || - (my_instance->lock = (SPINLOCK*)malloc(sizeof(SPINLOCK))) == NULL){ - MXS_ERROR("Memory allocation for firewall filter failed."); - return NULL; - } - - spinlock_init(my_instance->lock); + if ((my_instance = calloc(1, sizeof(FW_INSTANCE))) == NULL || + (my_instance->lock = (SPINLOCK*) malloc(sizeof(SPINLOCK))) == NULL) + { + MXS_ERROR("Memory allocation for firewall filter failed."); + return NULL; + } - if((ht = hashtable_alloc(100, hashkeyfun, hashcmpfun)) == NULL){ - MXS_ERROR("Unable to allocate hashtable."); - free(my_instance); - return NULL; - } + spinlock_init(my_instance->lock); - hashtable_memory_fns(ht,(HASHMEMORYFN)strdup,NULL,(HASHMEMORYFN)free,huserfree); - - my_instance->htable = ht; - my_instance->def_op = true; - my_instance->userstrings = NULL; - my_instance->regflags = 0; - - for(i = 0;params[i];i++){ - if(strcmp(params[i]->name, "rules") == 0){ - if(filename) - free(filename); - filename = strdup(params[i]->value); - } - } + if ((ht = hashtable_alloc(100, hashkeyfun, hashcmpfun)) == NULL) + { + MXS_ERROR("Unable to allocate hashtable."); + free(my_instance); + return NULL; + } - if(options) - { - for(i = 0;options[i];i++) - { - if(strcmp(options[i],"ignorecase") == 0) - { - my_instance->regflags |= REG_ICASE; - } - } - } - - if(filename == NULL) + hashtable_memory_fns(ht, (HASHMEMORYFN) strdup, NULL, (HASHMEMORYFN) free, huserfree); + + my_instance->htable = ht; + my_instance->def_op = true; + my_instance->userstrings = NULL; + my_instance->regflags = 0; + + for (i = 0; params[i]; i++) + { + if (strcmp(params[i]->name, "rules") == 0) { - MXS_ERROR("Unable to find rule file for firewall filter. Please provide the path with" - " rules="); - hashtable_free(my_instance->htable); - free(my_instance); - return NULL; + if (filename) + { + free(filename); + } + filename = strdup(params[i]->value); } - - if((file = fopen(filename,"rb")) == NULL ){ - MXS_ERROR("Error while opening rule file for firewall filter."); - hashtable_free(my_instance->htable); - free(my_instance); - free(filename); - return NULL; - } + } + + if (options) + { + for (i = 0; options[i]; i++) + { + if (strcmp(options[i], "ignorecase") == 0) + { + my_instance->regflags |= REG_ICASE; + } + } + } + + if (filename == NULL) + { + MXS_ERROR("Unable to find rule file for firewall filter. Please provide the path with" + " rules="); + hashtable_free(my_instance->htable); + free(my_instance); + return NULL; + } + + if ((file = fopen(filename, "rb")) == NULL) + { + MXS_ERROR("Error while opening rule file for firewall filter."); + hashtable_free(my_instance->htable); + free(my_instance); + free(filename); + return NULL; + } - bool file_empty = true; + bool file_empty = true; - while(!feof(file)) + while (!feof(file)) { - if(fgets(buffer,2048,file) == NULL){ - if(ferror(file)){ + if (fgets(buffer, 2048, file) == NULL) + { + if (ferror(file)) + { MXS_ERROR("Error while reading rule file for firewall filter."); fclose(file); hashtable_free(my_instance->htable); free(my_instance); return NULL; } - - if(feof(file)){ + + if (feof(file)) + { break; } - } - - if((nl = strchr(buffer,'\n')) != NULL && ((char*)nl - (char*)buffer) < 2048){ + } + + if ((nl = strchr(buffer, '\n')) != NULL && ((char*) nl - (char*) buffer) < 2048) + { *nl = '\0'; } - - if(strnlen(buffer,2048) < 1 || is_comment(buffer)) - { - continue; - } - file_empty = false; + if (strnlen(buffer, 2048) < 1 || is_comment(buffer)) + { + continue; + } - if(!parse_rule(buffer,my_instance)) - { - fclose(file); - err = true; - goto retblock; - } + file_empty = false; + + if (!parse_rule(buffer, my_instance)) + { + fclose(file); + err = true; + goto retblock; + } } - if(file_empty) - { - MXS_ERROR("dbfwfilter: File is empty: %s", filename); - free(filename); - err = true; - goto retblock; - } + if (file_empty) + { + MXS_ERROR("dbfwfilter: File is empty: %s", filename); + free(filename); + err = true; + goto retblock; + } - fclose(file); - free(filename); + fclose(file); + free(filename); - /**Apply the rules to users*/ - ptr = my_instance->userstrings; + /**Apply the rules to users*/ + ptr = my_instance->userstrings; - if(ptr == NULL) - { - MXS_ERROR("dbfwfilter: No 'users' line found."); - err = true; - goto retblock; - } + if (ptr == NULL) + { + MXS_ERROR("dbfwfilter: No 'users' line found."); + err = true; + goto retblock; + } - while(ptr){ + while (ptr) + { + if (!link_rules(ptr->value, my_instance)) + { + MXS_ERROR("dbfwfilter: Failed to parse rule: %s", ptr->value); + err = true; + } + tmp = ptr; + ptr = ptr->next; + free(tmp->value); + free(tmp); + } - if(!link_rules(ptr->value,my_instance)) - { - MXS_ERROR("dbfwfilter: Failed to parse rule: %s",ptr->value); - err = true; - } - tmp = ptr; - ptr = ptr->next; - free(tmp->value); - free(tmp); - } +retblock: - retblock: + if (err) + { + hrulefree(my_instance->rules); + hashtable_free(my_instance->htable); + free(my_instance); + my_instance = NULL; + } - if(err) - { - hrulefree(my_instance->rules); - hashtable_free(my_instance->htable); - free(my_instance); - my_instance = NULL; - } - - return (FILTER *)my_instance; + return(FILTER *) my_instance; } - - - /** * Associate a new session with this instance of the filter. * @@ -1443,20 +1534,19 @@ createInstance(char **options, FILTER_PARAMETER **params) * @param session The session itself * @return Session specific data for this session */ -static void * +static void * newSession(FILTER *instance, SESSION *session) { - FW_SESSION *my_session; + FW_SESSION *my_session; - if ((my_session = calloc(1, sizeof(FW_SESSION))) == NULL){ - return NULL; - } - my_session->session = session; - return my_session; + if ((my_session = calloc(1, sizeof(FW_SESSION))) == NULL) + { + return NULL; + } + my_session->session = session; + return my_session; } - - /** * Close a session with the filter, this is the mechanism * by which a filter may cleanup data structure etc. @@ -1464,10 +1554,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 @@ -1478,12 +1566,12 @@ closeSession(FILTER *instance, void *session) static void freeSession(FILTER *instance, void *session) { - FW_SESSION *my_session = (FW_SESSION *)session; - if(my_session->errmsg){ - free(my_session->errmsg); - - } - free(my_session); + FW_SESSION *my_session = (FW_SESSION *) session; + if (my_session->errmsg) + { + free(my_session->errmsg); + } + free(my_session); } /** @@ -1491,14 +1579,14 @@ 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) { - FW_SESSION *my_session = (FW_SESSION *)session; - my_session->down = *downstream; + FW_SESSION *my_session = (FW_SESSION *) session; + my_session->down = *downstream; } /** @@ -1509,94 +1597,92 @@ setDownstream(FILTER *instance, void *session, DOWNSTREAM *downstream) */ GWBUF* gen_dummy_error(FW_SESSION* session, char* msg) { - GWBUF* buf; - char* errmsg; - DCB* dcb; - MYSQL_session* mysql_session; - unsigned int errlen; - - if(session == NULL || session->session == NULL || - session->session->data == NULL || - session->session->client == NULL) - { - MXS_ERROR("Firewall filter session missing data."); - return NULL; - } - - dcb = session->session->client; - mysql_session = (MYSQL_session*)session->session->data; - errlen = msg != NULL ? strlen(msg) : 0; - errmsg = (char*)malloc((512 + errlen)*sizeof(char)); - - if(errmsg == NULL){ - MXS_ERROR("Memory allocation failed."); - return NULL; - } + GWBUF* buf; + char* errmsg; + DCB* dcb; + MYSQL_session* mysql_session; + unsigned int errlen; - - if(mysql_session->db[0] == '\0') + if (session == NULL || session->session == NULL || + session->session->data == NULL || + session->session->client == NULL) { - sprintf(errmsg, - "Access denied for user '%s'@'%s'", - dcb->user, - dcb->remote); - }else - { - sprintf(errmsg, - "Access denied for user '%s'@'%s' to database '%s'", - dcb->user, - dcb->remote, - mysql_session->db); + MXS_ERROR("Firewall filter session missing data."); + return NULL; } - if(msg != NULL){ - char* ptr = strchr(errmsg,'\0'); - sprintf(ptr,": %s",msg); - - } - - buf = modutil_create_mysql_err_msg(1,0,1141,"HY000", (const char*)errmsg); - free(errmsg); - - return buf; + dcb = session->session->client; + mysql_session = (MYSQL_session*) session->session->data; + errlen = msg != NULL ? strlen(msg) : 0; + errmsg = (char*) malloc((512 + errlen) * sizeof(char)); + + if (errmsg == NULL) + { + MXS_ERROR("Memory allocation failed."); + return NULL; + } + + + if (mysql_session->db[0] == '\0') + { + sprintf(errmsg, "Access denied for user '%s'@'%s'", dcb->user, dcb->remote); + } + else + { + sprintf(errmsg, "Access denied for user '%s'@'%s' to database '%s'", + dcb->user, dcb->remote, mysql_session->db); + } + + if (msg != NULL) + { + char* ptr = strchr(errmsg, '\0'); + sprintf(ptr, ": %s", msg); + + } + + buf = modutil_create_mysql_err_msg(1, 0, 1141, "HY000", (const char*) errmsg); + free(errmsg); + + return buf; } /** * Checks if the timerange object is active. * @return Whether the timerange is active - */ + */ bool inside_timerange(TIMERANGE* comp) { - 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)); + struct tm* tm_now; + struct tm tm_before, tm_after; + time_t before, after, now, time_now; + double to_before, to_after; - - tm_before.tm_sec = comp->start.tm_sec; - tm_before.tm_min = comp->start.tm_min; - tm_before.tm_hour = comp->start.tm_hour; - tm_after.tm_sec = comp->end.tm_sec; - tm_after.tm_min = comp->end.tm_min; - tm_after.tm_hour = comp->end.tm_hour; - - - before = mktime(&tm_before); - after = mktime(&tm_after); - now = mktime(tm_now); - to_before = difftime(now,before); - to_after = difftime(now,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)); - if(to_before > 0.0 && to_after < 0.0){ - return true; - } - return false; + + tm_before.tm_sec = comp->start.tm_sec; + tm_before.tm_min = comp->start.tm_min; + tm_before.tm_hour = comp->start.tm_hour; + tm_after.tm_sec = comp->end.tm_sec; + tm_after.tm_min = comp->end.tm_min; + tm_after.tm_hour = comp->end.tm_hour; + + + before = mktime(&tm_before); + after = mktime(&tm_after); + now = mktime(tm_now); + to_before = difftime(now, before); + to_after = difftime(now, after); + + if (to_before > 0.0 && to_after < 0.0) + { + return true; + } + return false; } /** @@ -1606,22 +1692,21 @@ bool inside_timerange(TIMERANGE* comp) */ bool rule_is_active(RULE* rule) { - TIMERANGE* times; - if(rule->active != NULL){ - - times = (TIMERANGE*)rule->active; - - while(times){ - - if(inside_timerange(times)){ - return true; - } - - times = times->next; - } - return false; - } - return true; + TIMERANGE* times; + if (rule->active != NULL) + { + times = (TIMERANGE*) rule->active; + while (times) + { + if (inside_timerange(times)) + { + return true; + } + times = times->next; + } + return false; + } + return true; } /** @@ -1635,250 +1720,256 @@ bool rule_is_active(RULE* rule) */ bool rule_matches(FW_INSTANCE* my_instance, FW_SESSION* my_session, GWBUF *queue, USER* user, RULELIST *rulelist, char* query) { - char *ptr,*where,*msg = NULL; - char emsg[512]; + char *ptr, *where, *msg = NULL; + char emsg[512]; - unsigned char* memptr = (unsigned char*)queue->start; - bool is_sql, is_real, matches; - skygw_query_op_t optype = QUERY_OP_UNDEFINED; - STRLINK* strln = NULL; - QUERYSPEED* queryspeed = NULL; - QUERYSPEED* rule_qs = NULL; - time_t time_now; - struct tm* tm_now; + unsigned char* memptr = (unsigned char*) queue->start; + bool is_sql, is_real, matches; + skygw_query_op_t optype = QUERY_OP_UNDEFINED; + STRLINK* strln = NULL; + QUERYSPEED* queryspeed = NULL; + QUERYSPEED* rule_qs = NULL; + time_t time_now; + struct tm* tm_now; - time(&time_now); - tm_now = localtime(&time_now); + time(&time_now); + tm_now = localtime(&time_now); - matches = false; - is_sql = modutil_is_SQL(queue) || modutil_is_SQL_prepare(queue); - - if(is_sql){ - if(!query_is_parsed(queue)){ - parse_query(queue); - } - optype = query_classifier_get_operation(queue); - is_real = skygw_is_real_query(queue); + matches = false; + is_sql = modutil_is_SQL(queue) || modutil_is_SQL_prepare(queue); - } + if (is_sql) + { + if (!query_is_parsed(queue)) + { + parse_query(queue); + } + optype = query_classifier_get_operation(queue); + is_real = skygw_is_real_query(queue); - if(rulelist->rule->on_queries == QUERY_OP_UNDEFINED || rulelist->rule->on_queries & optype){ + } - switch(rulelist->rule->type){ - - case RT_UNDEFINED: - MXS_ERROR("Undefined rule type found."); - break; - - case RT_REGEX: - - if(query && regexec(rulelist->rule->data,query,0,NULL,0) == 0){ - - matches = true; - - if(!rulelist->rule->allow){ - msg = strdup("Permission denied, query matched regular expression."); - MXS_INFO("dbfwfilter: rule '%s': regex matched on query",rulelist->rule->name); - goto queryresolved; - }else{ - break; - } - } - - break; - - case RT_PERMISSION: - if(!rulelist->rule->allow){ - matches = true; - msg = strdup("Permission denied at this time."); - MXS_INFO("dbfwfilter: rule '%s': query denied at: %s",rulelist->rule->name,asctime(tm_now)); - goto queryresolved; - }else{ + if (rulelist->rule->on_queries == QUERY_OP_UNDEFINED || rulelist->rule->on_queries & optype) + { + switch (rulelist->rule->type) + { + case RT_UNDEFINED: + MXS_ERROR("Undefined rule type found."); break; - } - break; - - case RT_COLUMN: - - if(is_sql && is_real) - { - where = skygw_get_affected_fields(queue); - if(where != NULL){ - char* saveptr; - char* tok = strtok_r(where," ",&saveptr); - while(tok) - { - strln = (STRLINK*)rulelist->rule->data; - while(strln) - { - if(strcasecmp(tok,strln->value) == 0) - { - matches = true; - if(!rulelist->rule->allow) - { - sprintf(emsg,"Permission denied to column '%s'.",strln->value); - MXS_INFO("dbfwfilter: rule '%s': query targets forbidden column: %s", - rulelist->rule->name,strln->value); - msg = strdup(emsg); - goto queryresolved; - } - else - break; - } - strln = strln->next; - } - tok = strtok_r(NULL,",",&saveptr); - } - free(where); + case RT_REGEX: + if (query && regexec(rulelist->rule->data, query, 0, NULL, 0) == 0) + { + + matches = true; + + if (!rulelist->rule->allow) + { + msg = strdup("Permission denied, query matched regular expression."); + MXS_INFO("dbfwfilter: rule '%s': regex matched on query", rulelist->rule->name); + goto queryresolved; + } + else + { + break; + } } - } - - break; + break; - case RT_WILDCARD: - - - if(is_sql && is_real){ - char * strptr; - where = skygw_get_affected_fields(queue); - - if(where != NULL){ - strptr = where; - - if(strchr(strptr,'*')){ - - matches = true; - msg = strdup("Usage of wildcard denied."); - MXS_INFO("dbfwfilter: rule '%s': query contains a wildcard.",rulelist->rule->name); - goto queryresolved; - } - free(where); - } - } - - break; - - case RT_THROTTLE: - - /** - * Check if this is the first time this rule is matched and if so, allocate - * and initialize a new QUERYSPEED struct for this session. - */ - - spinlock_acquire(my_instance->lock); - rule_qs = (QUERYSPEED*)rulelist->rule->data; - spinlock_release(my_instance->lock); - - spinlock_acquire(&user->lock); - queryspeed = user->qs_limit; - spinlock_release(&user->lock); - - while(queryspeed){ - if(queryspeed->id == rule_qs->id){ + case RT_PERMISSION: + if (!rulelist->rule->allow) + { + matches = true; + msg = strdup("Permission denied at this time."); + MXS_INFO("dbfwfilter: rule '%s': query denied at: %s", rulelist->rule->name, asctime(tm_now)); + goto queryresolved; + } + else + { break; } - queryspeed = queryspeed->next; - } - - - - if(queryspeed == NULL){ + break; - /**No match found*/ - queryspeed = (QUERYSPEED*)calloc(1,sizeof(QUERYSPEED)); - queryspeed->period = rule_qs->period; - queryspeed->cooldown = rule_qs->cooldown; - queryspeed->limit = rule_qs->limit; - queryspeed->id = rule_qs->id; - queryspeed->next = user->qs_limit; - user->qs_limit = queryspeed; - } - - if(queryspeed->active) - { - if(difftime(time_now,queryspeed->triggered) < queryspeed->cooldown) - { - - double blocked_for = queryspeed->cooldown - difftime(time_now,queryspeed->triggered); - - sprintf(emsg,"Queries denied for %f seconds",blocked_for); - MXS_INFO("dbfwfilter: rule '%s': user denied for %f seconds",rulelist->rule->name,blocked_for); - msg = strdup(emsg); - - matches = true; - } - else - { - queryspeed->active = false; - queryspeed->count = 0; - - } - } - else - { - if(queryspeed->count >= queryspeed->limit) - { - queryspeed->triggered = time_now; - matches = true; - queryspeed->active = true; - - MXS_INFO("dbfwfilter: rule '%s': query limit triggered (%d queries in %f seconds), " - "denying queries from user for %f seconds.", - rulelist->rule->name, - queryspeed->limit, - queryspeed->period, - queryspeed->cooldown); - double blocked_for = queryspeed->cooldown - difftime(time_now,queryspeed->triggered); - sprintf(emsg,"Queries denied for %f seconds",blocked_for); - msg = strdup(emsg); - } - else if(queryspeed->count > 0 && - difftime(time_now,queryspeed->first_query) <= queryspeed->period) - { - queryspeed->count++; - } - else - { - queryspeed->first_query = time_now; - queryspeed->count = 1; - } - } - - break; + case RT_COLUMN: + if (is_sql && is_real) + { + where = skygw_get_affected_fields(queue); + if (where != NULL) + { + char* saveptr; + char* tok = strtok_r(where, " ", &saveptr); + while (tok) + { + strln = (STRLINK*) rulelist->rule->data; + while (strln) + { + if (strcasecmp(tok, strln->value) == 0) + { + matches = true; - case RT_CLAUSE: + if (!rulelist->rule->allow) + { + sprintf(emsg, "Permission denied to column '%s'.", strln->value); + MXS_INFO("dbfwfilter: rule '%s': query targets forbidden column: %s", + rulelist->rule->name, strln->value); + msg = strdup(emsg); + goto queryresolved; + } + else + { + break; + } + } + strln = strln->next; + } + tok = strtok_r(NULL, ",", &saveptr); + } + free(where); + } + } + break; - if(is_sql && is_real && - !skygw_query_has_clause(queue)) - { - matches = true; - msg = strdup("Required WHERE/HAVING clause is missing."); - MXS_INFO("dbfwfilter: rule '%s': query has no where/having clause, query is denied.", - rulelist->rule->name); - } - break; - - default: - break; + case RT_WILDCARD: + if (is_sql && is_real) + { + char * strptr; + where = skygw_get_affected_fields(queue); + + if (where != NULL) + { + strptr = where; + + if (strchr(strptr, '*')) + { + + matches = true; + msg = strdup("Usage of wildcard denied."); + MXS_INFO("dbfwfilter: rule '%s': query contains a wildcard.", rulelist->rule->name); + goto queryresolved; + } + free(where); + } + } + break; + + case RT_THROTTLE: + /** + * Check if this is the first time this rule is matched and if so, allocate + * and initialize a new QUERYSPEED struct for this session. + */ + spinlock_acquire(my_instance->lock); + rule_qs = (QUERYSPEED*) rulelist->rule->data; + spinlock_release(my_instance->lock); + + spinlock_acquire(&user->lock); + queryspeed = user->qs_limit; + spinlock_release(&user->lock); + + while (queryspeed) + { + if (queryspeed->id == rule_qs->id) + { + break; + } + queryspeed = queryspeed->next; + } + + if (queryspeed == NULL) + { + + /**No match found*/ + queryspeed = (QUERYSPEED*) calloc(1, sizeof(QUERYSPEED)); + queryspeed->period = rule_qs->period; + queryspeed->cooldown = rule_qs->cooldown; + queryspeed->limit = rule_qs->limit; + queryspeed->id = rule_qs->id; + queryspeed->next = user->qs_limit; + user->qs_limit = queryspeed; + } + + if (queryspeed->active) + { + if (difftime(time_now, queryspeed->triggered) < queryspeed->cooldown) + { + + double blocked_for = queryspeed->cooldown - difftime(time_now, queryspeed->triggered); + + sprintf(emsg, "Queries denied for %f seconds", blocked_for); + MXS_INFO("dbfwfilter: rule '%s': user denied for %f seconds", rulelist->rule->name, blocked_for); + msg = strdup(emsg); + matches = true; + } + else + { + queryspeed->active = false; + queryspeed->count = 0; + } + } + else + { + if (queryspeed->count >= queryspeed->limit) + { + queryspeed->triggered = time_now; + matches = true; + queryspeed->active = true; + + MXS_INFO("dbfwfilter: rule '%s': query limit triggered (%d queries in %f seconds), " + "denying queries from user for %f seconds.", + rulelist->rule->name, + queryspeed->limit, + queryspeed->period, + queryspeed->cooldown); + double blocked_for = queryspeed->cooldown - difftime(time_now, queryspeed->triggered); + sprintf(emsg, "Queries denied for %f seconds", blocked_for); + msg = strdup(emsg); + } + else if (queryspeed->count > 0 && + difftime(time_now, queryspeed->first_query) <= queryspeed->period) + { + queryspeed->count++; + } + else + { + queryspeed->first_query = time_now; + queryspeed->count = 1; + } + } + break; + + case RT_CLAUSE: + if (is_sql && is_real && + !skygw_query_has_clause(queue)) + { + matches = true; + msg = strdup("Required WHERE/HAVING clause is missing."); + MXS_INFO("dbfwfilter: rule '%s': query has no where/having " + "clause, query is denied.", rulelist->rule->name); + } + break; + + default: + break; } } - queryresolved: - if(msg){ - if(my_session->errmsg){ - free(my_session->errmsg); - } - - my_session->errmsg = msg; - } - - if(matches){ - rulelist->rule->times_matched++; - } - - return matches; +queryresolved: + if (msg) + { + if (my_session->errmsg) + { + free(my_session->errmsg); + } + + my_session->errmsg = msg; + } + + if (matches) + { + rulelist->rule->times_matched++; + } + + return matches; } /** @@ -1891,48 +1982,53 @@ bool rule_matches(FW_INSTANCE* my_instance, FW_SESSION* my_session, GWBUF *queue */ bool check_match_any(FW_INSTANCE* my_instance, FW_SESSION* my_session, GWBUF *queue, USER* user) { - bool is_sql, rval = false; - int qlen; - char *fullquery = NULL,*ptr; - unsigned char* memptr = (unsigned char*)queue->start; - RULELIST* rulelist; - is_sql = modutil_is_SQL(queue) || modutil_is_SQL_prepare(queue); - - if(is_sql){ - if(!query_is_parsed(queue)){ - parse_query(queue); - } + bool is_sql, rval = false; + int qlen; + char *fullquery = NULL, *ptr; + unsigned char* memptr = (unsigned char*) queue->start; + RULELIST* rulelist; + is_sql = modutil_is_SQL(queue) || modutil_is_SQL_prepare(queue); - qlen = gw_mysql_get_byte3(memptr); - qlen = qlen < 0xffffff ? qlen : 0xffffff; - fullquery = malloc((qlen) * sizeof(char)); - memcpy(fullquery,memptr + 5,qlen - 1); - memset(fullquery + qlen - 1,0,1); - } + if (is_sql) + { + if (!query_is_parsed(queue)) + { + parse_query(queue); + } - if((rulelist = user->rules_or) == NULL) - { - goto retblock; - } + qlen = gw_mysql_get_byte3(memptr); + qlen = qlen < 0xffffff ? qlen : 0xffffff; + fullquery = malloc((qlen) * sizeof(char)); + memcpy(fullquery, memptr + 5, qlen - 1); + memset(fullquery + qlen - 1, 0, 1); + } - while(rulelist){ - - if(!rule_is_active(rulelist->rule)){ - rulelist = rulelist->next; - continue; - } - if((rval = rule_matches(my_instance,my_session,queue,user,rulelist,fullquery))){ - goto retblock; - } - - rulelist = rulelist->next; - } + if ((rulelist = user->rules_or) == NULL) + { + goto retblock; + } - retblock: + while (rulelist) + { - free(fullquery); + if (!rule_is_active(rulelist->rule)) + { + rulelist = rulelist->next; + continue; + } + if ((rval = rule_matches(my_instance, my_session, queue, user, rulelist, fullquery))) + { + goto retblock; + } - return rval; + rulelist = rulelist->next; + } + +retblock: + + free(fullquery); + + return rval; } /** @@ -1943,72 +2039,77 @@ bool check_match_any(FW_INSTANCE* my_instance, FW_SESSION* my_session, GWBUF *qu * @param user The user whose rulelist is checked * @return True if the query matches all of the rules otherwise false */ -bool check_match_all(FW_INSTANCE* my_instance, FW_SESSION* my_session, GWBUF *queue, USER* user,bool strict_all) +bool check_match_all(FW_INSTANCE* my_instance, FW_SESSION* my_session, GWBUF *queue, USER* user, bool strict_all) { - bool is_sql, rval = true; - bool have_active_rule = false; - int qlen; - unsigned char* memptr = (unsigned char*)queue->start; - char *fullquery = NULL,*ptr; - - RULELIST* rulelist; - is_sql = modutil_is_SQL(queue) || modutil_is_SQL_prepare(queue); + bool is_sql, rval = true; + bool have_active_rule = false; + int qlen; + unsigned char* memptr = (unsigned char*) queue->start; + char *fullquery = NULL, *ptr; - if(is_sql){ - if(!query_is_parsed(queue)){ - parse_query(queue); - } + RULELIST* rulelist; + is_sql = modutil_is_SQL(queue) || modutil_is_SQL_prepare(queue); - qlen = gw_mysql_get_byte3(memptr); - qlen = qlen < 0xffffff ? qlen : 0xffffff; - fullquery = malloc((qlen) * sizeof(char)); - memcpy(fullquery,memptr + 5,qlen - 1); - memset(fullquery + qlen - 1,0,1); - } - - if(strict_all) - { - rulelist = user->rules_strict_and; - } - else - { - rulelist = user->rules_and; - } - - if(rulelist == NULL) - { - rval = false; - goto retblock; - } - - while(rulelist){ - - if(!rule_is_active(rulelist->rule)){ - rulelist = rulelist->next; - continue; - } + if (is_sql) + { + if (!query_is_parsed(queue)) + { + parse_query(queue); + } - have_active_rule = true; + qlen = gw_mysql_get_byte3(memptr); + qlen = qlen < 0xffffff ? qlen : 0xffffff; + fullquery = malloc((qlen) * sizeof(char)); + memcpy(fullquery, memptr + 5, qlen - 1); + memset(fullquery + qlen - 1, 0, 1); + } - if(!rule_matches(my_instance,my_session,queue,user,rulelist,fullquery)){ - rval = false; - if(strict_all) - break; - } - rulelist = rulelist->next; - } + if (strict_all) + { + rulelist = user->rules_strict_and; + } + else + { + rulelist = user->rules_and; + } - if(!have_active_rule) - { - /** No active rules */ - rval = false; - } + if (rulelist == NULL) + { + rval = false; + goto retblock; + } - retblock: - - free(fullquery); - - return rval; + while (rulelist) + { + + if (!rule_is_active(rulelist->rule)) + { + rulelist = rulelist->next; + continue; + } + + have_active_rule = true; + + if (!rule_matches(my_instance, my_session, queue, user, rulelist, fullquery)) + { + rval = false; + if (strict_all) + { + break; + } + } + rulelist = rulelist->next; + } + + if (!have_active_rule) + { + /** No active rules */ + rval = false; + } + +retblock: + free(fullquery); + return rval; } /** @@ -2021,94 +2122,105 @@ bool check_match_all(FW_INSTANCE* my_instance, FW_SESSION* my_session, GWBUF *qu * @param session The filter session * @param queue The query data */ -static int +static int routeQuery(FILTER *instance, void *session, GWBUF *queue) { - FW_SESSION *my_session = (FW_SESSION *)session; - FW_INSTANCE *my_instance = (FW_INSTANCE *)instance; - bool accept = my_instance->def_op; - char *msg = NULL, *fullquery = NULL,*ipaddr; - char uname_addr[128]; - DCB* dcb = my_session->session->client; - USER* user = NULL; - GWBUF* forward; - ipaddr = strdup(dcb->remote); - sprintf(uname_addr,"%s@%s",dcb->user,ipaddr); + FW_SESSION *my_session = (FW_SESSION *) session; + FW_INSTANCE *my_instance = (FW_INSTANCE *) instance; + bool accept = my_instance->def_op; + char *msg = NULL, *fullquery = NULL, *ipaddr; + char uname_addr[128]; + DCB* dcb = my_session->session->client; + USER* user = NULL; + GWBUF* forward; + ipaddr = strdup(dcb->remote); + sprintf(uname_addr, "%s@%s", dcb->user, ipaddr); - if(modutil_is_SQL(queue) && modutil_count_statements(queue) > 1) - { - if(my_session->errmsg) - free(my_session->errmsg); + if (modutil_is_SQL(queue) && modutil_count_statements(queue) > 1) + { + if (my_session->errmsg) + { + free(my_session->errmsg); + } + my_session->errmsg = strdup("This filter does not support multi-statements."); + accept = false; + goto queryresolved; + } - my_session->errmsg = strdup("This filter does not support multi-statements."); - accept = false; - goto queryresolved; - } - - if((user = (USER*)hashtable_fetch(my_instance->htable, uname_addr)) == NULL){ - while(user == NULL && next_ip_class(ipaddr)){ - sprintf(uname_addr,"%s@%s",dcb->user,ipaddr); - user = (USER*)hashtable_fetch(my_instance->htable, uname_addr); - } - } - - if(user == NULL){ - strcpy(ipaddr,dcb->remote); - - do{ - sprintf(uname_addr,"%%@%s",ipaddr); - user = (USER*)hashtable_fetch(my_instance->htable, uname_addr); - }while(user == NULL && next_ip_class(ipaddr)); - } - - if(user == NULL){ - - /** - *No rules matched, do default operation. - */ - - goto queryresolved; - } + if ((user = (USER*) hashtable_fetch(my_instance->htable, uname_addr)) == NULL) + { + while (user == NULL && next_ip_class(ipaddr)) + { + sprintf(uname_addr, "%s@%s", dcb->user, ipaddr); + user = (USER*) hashtable_fetch(my_instance->htable, uname_addr); + } + } - if(check_match_any(my_instance,my_session,queue,user)){ - accept = false; - goto queryresolved; - } + if (user == NULL) + { + strcpy(ipaddr, dcb->remote); + do + { + sprintf(uname_addr, "%%@%s", ipaddr); + user = (USER*) hashtable_fetch(my_instance->htable, uname_addr); + } + while (user == NULL && next_ip_class(ipaddr)); + } + + if (user == NULL) + { + /** + *No rules matched, do default operation. + */ + + goto queryresolved; + } + + if (check_match_any(my_instance, my_session, queue, user)) + { + accept = false; + goto queryresolved; + } + + if (check_match_all(my_instance, my_session, queue, user, false)) + { + accept = false; + goto queryresolved; + } + + if (check_match_all(my_instance, my_session, queue, user, true)) + { + accept = false; + goto queryresolved; + } - if(check_match_all(my_instance,my_session,queue,user,false)){ - accept = false; - goto queryresolved; - } - - if(check_match_all(my_instance,my_session,queue,user,true)){ - accept = false; - goto queryresolved; - } - queryresolved: - free(ipaddr); - free(fullquery); + free(ipaddr); + free(fullquery); - if(accept){ + if (accept) + { + return my_session->down.routeQuery(my_session->down.instance, + my_session->down.session, queue); + } + else + { + gwbuf_free(queue); - return my_session->down.routeQuery(my_session->down.instance, - my_session->down.session, queue); - }else{ - - gwbuf_free(queue); + if (my_session->errmsg) + { + msg = my_session->errmsg; + } + forward = gen_dummy_error(my_session, msg); - if(my_session->errmsg){ - msg = my_session->errmsg; - } - forward = gen_dummy_error(my_session,msg); - - if(my_session->errmsg){ - free(my_session->errmsg); - my_session->errmsg = NULL; - } - return dcb->func.write(dcb,forward); - } + if (my_session->errmsg) + { + free(my_session->errmsg); + my_session->errmsg = NULL; + } + return dcb->func.write(dcb, forward); + } } /** @@ -2121,28 +2233,32 @@ queryresolved: * @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) { - FW_INSTANCE *my_instance = (FW_INSTANCE *)instance; + FW_INSTANCE *my_instance = (FW_INSTANCE *) instance; RULELIST* rules; int type; - - if (my_instance) + + if (my_instance) { spinlock_acquire(my_instance->lock); rules = my_instance->rules; - + dcb_printf(dcb, "Firewall Filter\n"); - dcb_printf(dcb, "%-24s%-24s%-24s\n","Rule","Type","Times Matched"); - while(rules){ - if((int)rules->rule->type > 0 && - (int)rules->rule->type < sizeof(rule_names)/sizeof(char**)){ - type = (int)rules->rule->type; - }else{ + dcb_printf(dcb, "%-24s%-24s%-24s\n", "Rule", "Type", "Times Matched"); + while (rules) + { + if ((int) rules->rule->type > 0 && + (int) rules->rule->type < sizeof(rule_names) / sizeof(char**)) + { + type = (int) rules->rule->type; + } + else + { type = 0; } - dcb_printf(dcb,"%-24s%-24s%-24d\n", + dcb_printf(dcb, "%-24s%-24s%-24d\n", rules->rule->name, rule_names[type], rules->rule->times_matched); @@ -2161,54 +2277,53 @@ int main(int argc, char** argv) bool have_icase = false; char *home; char cwd[PATH_MAX]; - char* opts[2] = {NULL,NULL}; + char* opts[2] = {NULL, NULL}; FILTER_PARAMETER ruleparam; - FILTER_PARAMETER* paramlist[2]; + FILTER_PARAMETER * paramlist[2]; opterr = 0; - while((ch = getopt(argc,argv,"h?")) != -1) + while ((ch = getopt(argc, argv, "h?")) != -1) { - switch(ch) + switch (ch) { - case '?': - case 'h': - printf("Usage: %s [OPTION]... RULEFILE\n" - "Options:\n" - "\t-?\tPrint this information\n", - argv[0]); - return 0; - default: - printf("Unknown option '%c'.\n",ch); - return 1; + case '?': + case 'h': + printf("Usage: %s [OPTION]... RULEFILE\n" + "Options:\n" + "\t-?\tPrint this information\n", + argv[0]); + return 0; + default: + printf("Unknown option '%c'.\n", ch); + return 1; } } - if(argc < 2) + if (argc < 2) { printf("Usage: %s [OPTION]... RULEFILE\n" - "-?\tPrint this information\n", + "-?\tPrint this information\n", argv[0]); return 1; } - home = malloc(sizeof(char)*(PATH_MAX+1)); - if(getcwd(home,PATH_MAX) == NULL) + home = malloc(sizeof(char)*(PATH_MAX + 1)); + if (getcwd(home, PATH_MAX) == NULL) { - free(home); - home = NULL; + free(home); + home = NULL; } - printf("Log files written to: %s\n",home?home:"/tpm"); + printf("Log files written to: %s\n", home ? home : "/tpm"); int argc_ = 2; - char* argv_[] = - { - "log_manager", - "-o", - NULL - }; + char* argv_[] ={ + "log_manager", + "-o", + NULL + }; - mxs_log_init(argc_,argv_); + mxs_log_init(argc_, argv_); init_test_env(home); @@ -2217,13 +2332,13 @@ int main(int argc, char** argv) paramlist[0] = &ruleparam; paramlist[1] = NULL; - if(createInstance(opts,paramlist)) + if (createInstance(opts, paramlist)) { - printf("Rule parsing was successful.\n"); + printf("Rule parsing was successful.\n"); } else { - printf("Failed to parse rule. Read the error log for the reason of the failure.\n"); + printf("Failed to parse rule. Read the error log for the reason of the failure.\n"); } mxs_log_flush_sync(); From eb0cf745ca069ef58f263bb5477e1b8058b6599b Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Wed, 18 Nov 2015 11:49:44 +0200 Subject: [PATCH 05/20] 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 06/20] 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 07/20] 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 08/20] 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 09/20] 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 10/20] 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 11/20] 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 12/20] 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 13/20] 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 14/20] 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 15/20] 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 16/20] 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 17/20] 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 18/20] 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 19/20] 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 20/20] 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";