From 70eef7aaa84ace2c41f98148a236c81605cc1da4 Mon Sep 17 00:00:00 2001 From: VilhoRaatikka Date: Mon, 17 Nov 2014 15:33:13 +0200 Subject: [PATCH 1/3] Fix to bug #513, http://bugs.skysql.com/show_bug.cgi?id=513 --- log_manager/test/testorder.c | 6 ++-- server/core/gateway.c | 9 ++++-- server/modules/filter/test/harness_common.c | 11 +++++-- server/modules/protocol/mysql_client.c | 9 ++++-- server/modules/protocol/mysql_common.c | 2 +- utils/skygw_utils.cc | 32 ++++++++++++++++----- 6 files changed, 52 insertions(+), 17 deletions(-) diff --git a/log_manager/test/testorder.c b/log_manager/test/testorder.c index f9bf14213..da87c5325 100644 --- a/log_manager/test/testorder.c +++ b/log_manager/test/testorder.c @@ -33,7 +33,8 @@ int main(int argc, char** argv) char *message; char** optstr; long msg_index = 1; - + struct timespec ts1; + ts1.tv_sec = 0; memset(cwd,0,1024); if( argc <4){ @@ -95,7 +96,8 @@ int main(int argc, char** argv) fprintf(stderr,"Error: log_manager returned %d",err); break; } - usleep(100); + ts1.tv_nsec = 100*1000000; + nanosleep(&ts1, NULL); } skygw_log_flush(LOGFILE_ERROR); diff --git a/server/core/gateway.c b/server/core/gateway.c index 090b433a3..7e2e49dcd 100644 --- a/server/core/gateway.c +++ b/server/core/gateway.c @@ -382,7 +382,12 @@ static bool file_write_header( const char* header_buf3; time_t* t = NULL; struct tm* tm = NULL; - +#if defined(LAPTOP_TEST) + struct timespec ts1; + ts1.tv_sec = 0; + ts1.tv_nsec = DISKWRITE_LATENCY*1000000; +#endif + if ((t = (time_t *)malloc(sizeof(time_t))) == NULL) { goto return_succp; } @@ -406,7 +411,7 @@ static bool file_write_header( len2 = strlen(header_buf2); len3 = strlen(header_buf3); #if defined(LAPTOP_TEST) - usleep(DISKWRITE_LATENCY); + nanosleep(&ts1, NULL); #else wbytes1=fwrite((void*)header_buf1, len1, 1, outfile); wbytes2=fwrite((void*)header_buf2, len2, 1, outfile); diff --git a/server/modules/filter/test/harness_common.c b/server/modules/filter/test/harness_common.c index fe782bc0d..c12989259 100644 --- a/server/modules/filter/test/harness_common.c +++ b/server/modules/filter/test/harness_common.c @@ -820,6 +820,8 @@ void route_buffers() while(instance.buff_ind < instance.buffer_count){ pthread_mutex_unlock(&instance.work_mtx); while(instance.last_ind < instance.session_count){ + struct timespec ts1; + ts1.tv_sec = 0; tprg = ((bprg + (float)instance.last_ind)/fin); if(!instance.verbose){ @@ -828,7 +830,8 @@ void route_buffers() trig += step; } } - usleep(100); + ts1.tv_nsec = 100*1000000; + nanosleep(&ts1, NULL); } pthread_mutex_lock(&instance.work_mtx); instance.buff_ind++; @@ -863,6 +866,9 @@ void work_buffer(void* thr_num) index < instance.session_count && instance.buff_ind < instance.buffer_count) { + struct timespec ts1; + ts1.tv_sec = 0; + instance.head->instance->routeQuery(instance.head->filter, instance.head->session[index], instance.buffer[instance.buff_ind]); @@ -872,7 +878,8 @@ void work_buffer(void* thr_num) fake_ok); } atomic_add(&instance.last_ind,1); - usleep(1000*instance.rt_delay); + ts1.tv_nsec = 1000*instance.rt_delay*1000000; + nanosleep(&ts1, NULL); } } diff --git a/server/modules/protocol/mysql_client.c b/server/modules/protocol/mysql_client.c index 77ef7c9ef..2366ca39f 100644 --- a/server/modules/protocol/mysql_client.c +++ b/server/modules/protocol/mysql_client.c @@ -1111,7 +1111,7 @@ int gw_MySQLAccept(DCB *listener) int sendbuf = GW_BACKEND_SO_SNDBUF; socklen_t optlen = sizeof(sendbuf); int eno = 0; - int syseno = 0; + int syseno = 0; int i = 0; CHK_DCB(listener); @@ -1151,6 +1151,8 @@ int gw_MySQLAccept(DCB *listener) } else if (eno == ENFILE || eno == EMFILE) { + struct timespec ts1; + ts1.tv_sec = 0; /** * Exceeded system's (ENFILE) or processes * (EMFILE) max. number of files limit. @@ -1173,8 +1175,9 @@ int gw_MySQLAccept(DCB *listener) strerror(eno)))); } i++; - usleep(100*i*i); - + ts1.tv_nsec = 100*i*i*1000000; + nanosleep(&ts1, NULL); + if (i<10) { goto retry_accept; } diff --git a/server/modules/protocol/mysql_common.c b/server/modules/protocol/mysql_common.c index 8b12dbf86..9ca3617b5 100644 --- a/server/modules/protocol/mysql_common.c +++ b/server/modules/protocol/mysql_common.c @@ -1847,7 +1847,7 @@ void protocol_add_srv_command( MySQLProtocol* p, mysql_server_cmd_t cmd) { -#if defined(SS_DEBUG) +#if defined(EXTRA_SS_DEBUG) server_command_t* c; #endif spinlock_acquire(&p->protocol_lock); diff --git a/utils/skygw_utils.cc b/utils/skygw_utils.cc index 088e76ae3..f08462fb4 100644 --- a/utils/skygw_utils.cc +++ b/utils/skygw_utils.cc @@ -1224,12 +1224,16 @@ void acquire_lock( int* l) { register int misscount = 0; + struct timespec ts1; + ts1.tv_sec = 0; while (atomic_add(l, 1) != 0) { atomic_add(l, -1); misscount += 1; - if (misscount > 10) { - usleep(rand()%misscount); + if (misscount > 10) + { + ts1.tv_nsec = (rand()%misscount)*1000000; + nanosleep(&ts1, NULL); } } } @@ -1636,7 +1640,12 @@ static bool file_write_header( const char* header_buf4; time_t* t; struct tm* tm; - +#if defined(LAPTOP_TEST) + struct timespec ts1; + ts1.tv_sec = 0; + ts1.tv_nsec = DISKWRITE_LATENCY*1000000; +#endif + t = (time_t *)malloc(sizeof(time_t)); tm = (struct tm *)malloc(sizeof(struct tm)); *t = time(NULL); @@ -1662,7 +1671,7 @@ static bool file_write_header( len3 = strlen(header_buf3); len4 = strlen(header_buf4); #if defined(LAPTOP_TEST) - usleep(DISKWRITE_LATENCY); + nanosleep(&ts1, NULL); #else wbytes1=fwrite((void*)header_buf1, len1, 1, file->sf_file); wbytes2=fwrite((void*)header_buf2, len2, 1, file->sf_file); @@ -1709,7 +1718,12 @@ static bool file_write_footer( const char* header_buf1; char* header_buf3 = NULL; const char* header_buf4; - +#if defined(LAPTOP_TEST) + struct timespec ts1; + ts1.tv_sec = 0; + ts1.tv_nsec = DISKWRITE_LATENCY*1000000; +#endif + CHK_FILE(file); if (shutdown) @@ -1734,7 +1748,7 @@ static bool file_write_footer( len1 = strlen(header_buf1); len4 = strlen(header_buf4); #if defined(LAPTOP_TEST) - usleep(DISKWRITE_LATENCY); + nanosleep(&ts1, NULL); #else wbytes3=fwrite((void*)header_buf3, tslen, 1, file->sf_file); wbytes1=fwrite((void*)header_buf1, len1, 1, file->sf_file); @@ -1784,11 +1798,15 @@ int skygw_file_write( size_t nwritten; int fd; static int writecount; +#else + struct timespec ts1; + ts1.tv_sec = 0; + ts1.tv_nsec = DISKWRITE_LATENCY*1000000; #endif CHK_FILE(file); #if defined(LAPTOP_TEST) - usleep(DISKWRITE_LATENCY); + nanosleep(&ts1, NULL); #else nwritten = fwrite(data, nbytes, 1, file->sf_file); From 0b988e0f497680a1a436a226e0cd8afa3a930a1d Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Mon, 17 Nov 2014 18:42:20 +0200 Subject: [PATCH 2/3] Added a dummy session and dcb to the filter harness. Added tests for regexfilter. --- server/modules/filter/test/CMakeLists.txt | 5 +- server/modules/filter/test/harness.h | 17 +- server/modules/filter/test/harness_common.c | 113 ++++++++++-- server/modules/filter/test/harness_ui.c | 4 +- server/modules/filter/test/harness_util.c | 36 +++- server/modules/filter/test/hint_testing.cnf | 162 ------------------ server/modules/filter/test/regextest.cnf | 5 + server/modules/filter/test/regextest.expected | 3 + server/modules/filter/test/regextest.input | 3 + 9 files changed, 167 insertions(+), 181 deletions(-) create mode 100644 server/modules/filter/test/regextest.cnf create mode 100755 server/modules/filter/test/regextest.expected create mode 100644 server/modules/filter/test/regextest.input diff --git a/server/modules/filter/test/CMakeLists.txt b/server/modules/filter/test/CMakeLists.txt index 1813a5a26..9c87ee926 100644 --- a/server/modules/filter/test/CMakeLists.txt +++ b/server/modules/filter/test/CMakeLists.txt @@ -10,4 +10,7 @@ add_executable(harness_ui harness_ui.c harness_common.c) add_executable(harness harness_util.c harness_common.c ${CORE}) target_link_libraries(harness_ui fullcore log_manager utils) target_link_libraries(harness fullcore) -add_test(TestHintfilter /bin/sh -c "MAXSCALE_HOME=\"${CMAKE_BINARY_DIR}\" ${CMAKE_CURRENT_BINARY_DIR}/harness -i ${CMAKE_CURRENT_SOURCE_DIR}/hint_testing.input -o ${CMAKE_CURRENT_BINARY_DIR}/hint_testing.output -c ${CMAKE_CURRENT_SOURCE_DIR}/hint_testing.cnf -t 1 -s 1 && diff ${CMAKE_CURRENT_SOURCE_DIR}/hint_testing.expected ${CMAKE_CURRENT_BINARY_DIR}/hint_testing.output;exit $?") \ No newline at end of file +execute_process(COMMAND ${CMAKE_COMMAND} -E copy ${ERRMSG} ${CMAKE_CURRENT_BINARY_DIR}) +add_test(TestHintfilter /bin/sh -c "MAXSCALE_HOME=\"${CMAKE_BINARY_DIR}\" ${CMAKE_CURRENT_BINARY_DIR}/harness -i ${CMAKE_CURRENT_SOURCE_DIR}/hint_testing.input -o ${CMAKE_CURRENT_BINARY_DIR}/hint_testing.output -c ${CMAKE_CURRENT_SOURCE_DIR}/hint_testing.cnf -t 1 -s 1 -e ${CMAKE_CURRENT_SOURCE_DIR}/hint_testing.expected") + +add_test(TestRegexfilter /bin/sh -c "MAXSCALE_HOME=\"${CMAKE_BINARY_DIR}\" ${CMAKE_CURRENT_BINARY_DIR}/harness -i ${CMAKE_CURRENT_SOURCE_DIR}/regextest.input -o ${CMAKE_CURRENT_BINARY_DIR}/regextest.output -c ${CMAKE_CURRENT_SOURCE_DIR}/regextest.cnf -t 1 -s 1 -e ${CMAKE_CURRENT_SOURCE_DIR}/regextest.expected") \ No newline at end of file diff --git a/server/modules/filter/test/harness.h b/server/modules/filter/test/harness.h index c30c266c2..85713d07a 100644 --- a/server/modules/filter/test/harness.h +++ b/server/modules/filter/test/harness.h @@ -69,6 +69,9 @@ #include #include #include +#include +#include + /** * A single name-value pair and a link to the next item in the * configuration. @@ -117,6 +120,7 @@ typedef struct int running; int verbose; /**Whether to print to stdout*/ int infile; /**A file where the queries are loaded from*/ + int expected; int error; char* mod_dir; /**Module directory absolute path*/ char* infile_name; @@ -125,6 +129,7 @@ typedef struct FILTERCHAIN* head; /**The head of the filter chain*/ FILTERCHAIN* tail; /**The tail of the filter chain*/ GWBUF** buffer; /**Buffers that are fed to the filter chain*/ + SESSION* session; int buffer_count; int session_count; DOWNSTREAM dummyrouter; /**Dummy downstream router for data extraction*/ @@ -172,7 +177,7 @@ typedef packet_t PACKET; /** * Initialize the static instance. */ -int harness_init(int argc,char** argv); +int harness_init(int argc,char** argv,HARNESS_INSTANCE** inst); /** * Frees all the query buffers @@ -359,4 +364,14 @@ GWBUF* gen_packet(PACKET pkt); */ int process_opts(int argc, char** argv); +/** + * Compares the contents of two files. + * This function resets the offsets of the file descriptors and leaves them in an + * undefined state. + * @param a The first file + * @param b The second file + * @return 0 if the files do not differ and 1 if they do or an error occurred. + */ +int compare_files(int a, int b); + #endif diff --git a/server/modules/filter/test/harness_common.c b/server/modules/filter/test/harness_common.c index fe782bc0d..0de1dc2a4 100644 --- a/server/modules/filter/test/harness_common.c +++ b/server/modules/filter/test/harness_common.c @@ -1,7 +1,22 @@ #include -int harness_init(int argc, char** argv){ + +int dcbfun(struct dcb* dcb, GWBUF * buffer) +{ + printf("Data was written to client DCB.\n"); + return 1; +} + +int harness_init(int argc, char** argv, HARNESS_INSTANCE** inst){ + + int i = 0; + MYSQL_session* mysqlsess; + DCB* dcb; + char cwd[1024]; + char tmp[2048]; + char** optstr; + if(!(argc == 2 && strcmp(argv[1],"-h") == 0)){ skygw_logmanager_init(0,NULL); } @@ -14,13 +29,37 @@ int harness_init(int argc, char** argv){ return 1; } + *inst = &instance; instance.running = 1; instance.infile = -1; instance.outfile = -1; + instance.expected = -1; instance.buff_ind = -1; instance.last_ind = -1; instance.sess_ind = -1; + instance.session = calloc(1,sizeof(SESSION)); + dcb = calloc(1,sizeof(DCB)); + mysqlsess = calloc(1,sizeof(MYSQL_session)); + sprintf(mysqlsess->user,"dummyuser"); + sprintf(mysqlsess->db,"dummydb"); + dcb->func.write = dcbfun; + dcb->remote = strdup("0.0.0.0"); + dcb->user = strdup("user"); + instance.session->client = (void*)dcb; + instance.session->data = (void*)mysqlsess; + + getcwd(cwd,sizeof(cwd)); + sprintf(tmp,"%s",cwd); + + optstr = (char**)malloc(sizeof(char*)*4); + optstr[0] = strdup("log_manager"); + optstr[1] = strdup("-j"); + optstr[2] = strdup(tmp); + optstr[3] = NULL; + skygw_logmanager_init( 3, optstr); + free(optstr); + process_opts(argc,argv); if(!(instance.thrpool = malloc(instance.thrcount * sizeof(pthread_t)))){ @@ -84,15 +123,17 @@ void free_buffers() } int open_file(char* str, unsigned int write) { - int mode; + int mode,fd; if(write){ mode = O_RDWR|O_CREAT; }else{ mode = O_RDONLY; } - - return open(str,mode,S_IRWXU|S_IRGRP|S_IXGRP|S_IXOTH); + if((fd = open(str,mode,S_IRWXU|S_IRGRP|S_IXGRP|S_IXOTH)) < 0){ + printf("Error %d: %s\n",errno,strerror(errno)); + } + return fd; } @@ -608,6 +649,8 @@ int load_filter(FILTERCHAIN* fc, CONFIG* cnf) { FILTER_PARAMETER** fparams = NULL; int i, paramc = -1; + int sess_err = 0; + int x; if(cnf == NULL){ fparams = read_params(¶mc); @@ -672,16 +715,19 @@ int load_filter(FILTERCHAIN* fc, CONFIG* cnf) } } - int sess_err = 0; if(cnf && fc && fc->instance){ fc->filter = (FILTER*)fc->instance->createInstance(NULL,fparams); - + if(fc->filter == NULL){ + printf("Error loading filter:%s: createInstance returned NULL.\n",fc->name); + sess_err = 1; + goto error; + } for(i = 0;isession[i] = fc->instance->newSession(fc->filter, fc->session[i])) && + if((fc->session[i] = fc->instance->newSession(fc->filter, instance.session)) && (fc->down[i] = calloc(1,sizeof(DOWNSTREAM))) && (fc->up[i] = calloc(1,sizeof(UPSTREAM)))){ @@ -693,7 +739,7 @@ int load_filter(FILTERCHAIN* fc, CONFIG* cnf) fc->instance->setUpstream(fc->filter, fc->session[i], fc->up[i]); }else{ skygw_log_write(LOGFILE_MESSAGE, - "Warning: The filter %s does not support client relies.\n",fc->name); + "Warning: The filter %s does not support client replies.\n",fc->name); } if(fc->next && fc->next->next){ @@ -746,8 +792,8 @@ int load_filter(FILTERCHAIN* fc, CONFIG* cnf) } } - - int x; + error: + if(fparams){ for(x = 0;xinstance->routeQuery(instance.head->filter, + if(instance.head->instance->routeQuery(instance.head->filter, instance.head->session[index], - instance.buffer[instance.buff_ind]); + instance.buffer[instance.buff_ind]) == 0){ + if(instance.outfile > 0){ + const char* msg = "Query returned 0.\n"; + write(instance.outfile,msg,strlen(msg)); + } + } if(instance.tail->instance->clientReply){ instance.tail->instance->clientReply(instance.tail->filter, instance.tail->session[index], @@ -932,7 +983,7 @@ GWBUF* gen_packet(PACKET pkt) int process_opts(int argc, char** argv) { int fd, buffsize = 1024; - int rd,rdsz, rval; + int rd,rdsz, rval = 0; size_t fsize; char *buff = calloc(buffsize,sizeof(char)), *tok = NULL; @@ -985,10 +1036,18 @@ int process_opts(int argc, char** argv) close(fd); return 1; } + char* conf_name = NULL; - while((rd = getopt(argc,argv,"m:c:i:o:s:t:d:qh")) > 0){ + rval = 0; + + while((rd = getopt(argc,argv,"e:m:c:i:o:s:t:d:qh")) > 0){ switch(rd){ + case 'e': + instance.expected = open_file(optarg,0); + printf("Expected output is read from: %s\n",optarg); + break; + case 'o': instance.outfile = open_file(optarg,1); printf("Output is written to: %s\n",optarg); @@ -1053,6 +1112,7 @@ int process_opts(int argc, char** argv) } } printf("\n"); + if(conf_name && load_config(conf_name)){ load_query(); }else{ @@ -1061,5 +1121,30 @@ int process_opts(int argc, char** argv) free(conf_name); close(fd); + return rval; +} + +int compare_files(int a,int b) +{ + char in[4098]; + char exp[4098]; + int line = 1; + + if(a < 1 || b < 1){ + return 1; + } + + if(lseek(a,0,SEEK_SET) < 0 || + lseek(b,0,SEEK_SET) < 0){ + return 1; + } + + while(fdgets(a,in,4098) && fdgets(b,exp,4098)){ + if(strcmp(in,exp)){ + printf("The files differ at line %d:\n%s\n-------------------------------------\n%s\n",line,in,exp); + return 1; + } + line++; + } return 0; } diff --git a/server/modules/filter/test/harness_ui.c b/server/modules/filter/test/harness_ui.c index 9b38f648c..8921a88bc 100755 --- a/server/modules/filter/test/harness_ui.c +++ b/server/modules/filter/test/harness_ui.c @@ -6,9 +6,9 @@ int main(int argc, char** argv){ char* tk; FILTERCHAIN* tmp_chn; FILTERCHAIN* del_chn; - + HARNESS_INSTANCE* hinstance; - if(harness_init(argc,argv)){ + if(harness_init(argc,argv,&hinstance)){ printf("Error: Initialization failed.\n"); skygw_log_write(LOGFILE_ERROR,"Error: Initialization failed.\n"); skygw_logmanager_done(); diff --git a/server/modules/filter/test/harness_util.c b/server/modules/filter/test/harness_util.c index fb6905445..04b7e1b9b 100644 --- a/server/modules/filter/test/harness_util.c +++ b/server/modules/filter/test/harness_util.c @@ -1,7 +1,38 @@ +#include +#include #include + int main(int argc,char** argv) { - if(harness_init(argc,argv) || instance.error){ + + static char* server_options[] = { + "MariaDB Corporation MaxScale", + "--datadir=./", + "--language=./", + "--skip-innodb", + "--default-storage-engine=myisam", + NULL + }; + + const int num_elements = (sizeof(server_options) / sizeof(char *)) - 1; + + static char* server_groups[] = { + "embedded", + "server", + "server", + NULL + }; + + + HARNESS_INSTANCE* inst; + + if(mysql_library_init(num_elements, server_options, server_groups)){ + printf("Embedded server init failed.\n"); + return 1; + } + + + if(harness_init(argc,argv,&inst) || inst->error){ printf("Error: Initialization failed.\n"); skygw_log_write(LOGFILE_ERROR,"Error: Initialization failed.\n"); skygw_logmanager_done(); @@ -10,5 +41,8 @@ int main(int argc,char** argv) } route_buffers(); + if(inst->expected){ + return compare_files(inst->outfile,inst->expected); + } return 0; } diff --git a/server/modules/filter/test/hint_testing.cnf b/server/modules/filter/test/hint_testing.cnf index 347d9c6a6..5d4319bb8 100755 --- a/server/modules/filter/test/hint_testing.cnf +++ b/server/modules/filter/test/hint_testing.cnf @@ -1,165 +1,3 @@ -# -# Example MaxScale.cnf configuration file -# -# -# -# Number of server threads -# Valid options are: -# threads= - -[maxscale] -threads=1 - -# Define a monitor that can be used to determine the state and role of -# the servers. -# -# Valid options are: -# -# module= -# servers=,,... -# user = -# passwd= -# monitor_interval= - -[MySQL Monitor] -type=monitor -module=mysqlmon -servers=server1,server2,server3,server4 -user=maxuser -passwd=maxpwd - -# A series of service definition -# -# Valid options are: -# -# router= -# servers=,,... -# user= -# passwd= -# enable_root_user=<0 or 1, default is 0> -# version_string= -# -# Valid router modules currently are: -# readwritesplit, readconnroute and debugcli - - -[RW Split Router] -type=service -router=readwritesplit -servers=server1,server2,server3,server4 -max_slave_connections=90% -user=maxuser -passwd=maxpwd -#filters=MQ - -[RW Split Hint Router] -type=service -router=readwritesplit -servers=server1,server2,server3,server4 -max_slave_connections=90% -user=maxuser -passwd=maxpwd -filters=Hint - - -[Read Connection Router] -type=service -router=readconnroute -router_options=master -servers=server1 -user=maxuser -passwd=maxpwd - - -[HTTPD Router] -type=service -router=testroute -servers=server1,server2,server3 - -[Debug Interface] -type=service -router=debugcli - - [Hint] type=filter module=hintfilter - -#[MQ] -#type=filter -#module=mqfilter -#exchange=x1 -#key=k1 -#queue=q1 -#port=5673 - -# Listener definitions for the services -# -# Valid options are: -# -# service= -# protocol= -# port= -# address=
-# socket= - -[RW Split Listener] -type=listener -service=RW Split Router -protocol=MySQLClient -port=4006 - -[RW Split Hint Listener] -type=listener -service=RW Split Hint Router -protocol=MySQLClient -port=4009 - -[Read Connection Listener] -type=listener -service=Read Connection Router -protocol=MySQLClient -port=4008 -#socket=/tmp/readconn.sock - -[Debug Listener] -type=listener -service=Debug Interface -protocol=telnetd -port=4442 -#address=127.0.0.1 - -[HTTPD Listener] -type=listener -service=HTTPD Router -protocol=HTTPD -port=6444 - -# Definition of the servers - -[server1] -type=server -address=127.0.0.1 -port=3000 -protocol=MySQLBackend - -[server2] -type=server -address=127.0.0.1 -port=3001 -protocol=MySQLBackend - -[server3] -type=server -address=127.0.0.1 -port=3002 -protocol=MySQLBackend - -[server4] -type=server -address=127.0.0.1 -port=3003 -protocol=MySQLBackend diff --git a/server/modules/filter/test/regextest.cnf b/server/modules/filter/test/regextest.cnf new file mode 100644 index 000000000..1033a8696 --- /dev/null +++ b/server/modules/filter/test/regextest.cnf @@ -0,0 +1,5 @@ +[Regex] +type=filter +module=regexfilter +match=wrong +replace=right diff --git a/server/modules/filter/test/regextest.expected b/server/modules/filter/test/regextest.expected new file mode 100755 index 000000000..609b3393e --- /dev/null +++ b/server/modules/filter/test/regextest.expected @@ -0,0 +1,3 @@ +select * from mysql.right; +select right from test.table; +select * from test.table where name='right'; diff --git a/server/modules/filter/test/regextest.input b/server/modules/filter/test/regextest.input new file mode 100644 index 000000000..ab31b0ad3 --- /dev/null +++ b/server/modules/filter/test/regextest.input @@ -0,0 +1,3 @@ +select * from mysql.wrong; +select wrong from test.table; +select * from test.table where name='wrong'; \ No newline at end of file From a30fc0c7879adf21012ae1dd66ca2b7118cefa26 Mon Sep 17 00:00:00 2001 From: VilhoRaatikka Date: Mon, 17 Nov 2014 23:27:14 +0200 Subject: [PATCH 3/3] MAX-328, Add session identifier to trace log entries. Session id is given to session in session_alloc and stored to thread's local storage variable when thread picks a new event from epoll_wait. --- log_manager/log_manager.cc | 42 +++++++++++++++++++++++++++++++------- server/core/dcb.c | 15 ++++++++++++++ server/core/poll.c | 9 ++++++++ server/core/session.c | 29 ++++++++++++++++++++++++++ server/include/dcb.h | 11 +++------- server/include/session.h | 1 + 6 files changed, 92 insertions(+), 15 deletions(-) diff --git a/log_manager/log_manager.cc b/log_manager/log_manager.cc index a875bd2ad..04c96b353 100644 --- a/log_manager/log_manager.cc +++ b/log_manager/log_manager.cc @@ -57,6 +57,10 @@ static simple_mutex_t msg_mutex; * actual library calls such as skygw_log_write. */ int lm_enabled_logfiles_bitmask = 0; +/** + * Thread-specific variable for session id which is used in trace logging. + */ +__thread size_t tls_sesid = 0; /** * BUFSIZ comes from the system. It equals with block size or @@ -720,17 +724,29 @@ static int logmanager_write_log( { /** Length of string that will be written, limited by bufsize */ int safe_str_len; + /** Length of session id */ + int sesid_str_len; + + /** 2 braces and 2 spaces */ + if (id == LOGFILE_TRACE && tls_sesid > 0) + { + sesid_str_len = 2+2+get_decimal_len(tls_sesid); + } + else + { + sesid_str_len = 0; + } timestamp_len = get_timestamp_len(); /** Findout how much can be safely written with current block size */ - if (timestamp_len-1+str_len > lf->lf_buf_size) + if (timestamp_len-1+sesid_str_len-1+str_len > lf->lf_buf_size) { safe_str_len = lf->lf_buf_size; } else { - safe_str_len = timestamp_len-1+str_len; + safe_str_len = timestamp_len-1+sesid_str_len-1+str_len; } /** * Seek write position and register to block buffer. @@ -761,7 +777,7 @@ static int logmanager_write_log( simple_mutex_unlock(&msg_mutex); } #endif - + /** Book space for log string from buffer */ wp = blockbuf_get_writepos(&bb, id, safe_str_len, @@ -783,16 +799,28 @@ static int logmanager_write_log( */ timestamp_len = snprint_timestamp(wp, timestamp_len); - - + if (id == LOGFILE_TRACE) + { + /** + * Write session id + */ + snprintf(wp+timestamp_len, sesid_str_len, "[%lu] ", tls_sesid); + sesid_str_len -= 1; /*< remove terminating char */ + } /** * Write next string to overwrite terminating null character * of the timestamp string. */ if (use_valist) { - vsnprintf(wp+timestamp_len, safe_str_len-timestamp_len, str, valist); + vsnprintf(wp+timestamp_len+sesid_str_len, + safe_str_len-timestamp_len-sesid_str_len, + str, + valist); } else { - snprintf(wp+timestamp_len, safe_str_len-timestamp_len, "%s", str); + snprintf(wp+timestamp_len+sesid_str_len, + safe_str_len-timestamp_len-sesid_str_len, + "%s", + str); } /** write to syslog */ diff --git a/server/core/dcb.c b/server/core/dcb.c index 244b50c06..641691e72 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -90,6 +90,21 @@ static int dcb_null_close(DCB *dcb); static int dcb_null_auth(DCB *dcb, SERVER *server, SESSION *session, GWBUF *buf); static int dcb_isvalid_nolock(DCB *dcb); +size_t dcb_get_session_id( + DCB* dcb) +{ + size_t rval; + + if (dcb != NULL && dcb->session != NULL) + { + rval = dcb->session->ses_id; + } + else + { + rval = 0; + } + return rval; +} /** * Return the pointer to the lsit of zombie DCB's * diff --git a/server/core/poll.c b/server/core/poll.c index 36e118b72..378147ac4 100644 --- a/server/core/poll.c +++ b/server/core/poll.c @@ -41,6 +41,8 @@ extern int lm_enabled_logfiles_bitmask; +extern __thread size_t tls_sesid; + /** * @file poll.c - Abstraction of the epoll functionality * @@ -677,6 +679,7 @@ uint32_t ev; #else atomic_add(&pollStats.n_write, 1); + LOGIF(LT, (tls_sesid = dcb_get_session_id(dcb))); dcb->func.write_ready(dcb); #endif } else { @@ -712,6 +715,7 @@ uint32_t ev; dcb->fd))); atomic_add( &pollStats.n_accept, 1); + LOGIF(LT, (tls_sesid = dcb_get_session_id(dcb))); dcb->func.accept(dcb); } else @@ -724,6 +728,7 @@ uint32_t ev; dcb, dcb->fd))); atomic_add(&pollStats.n_read, 1); + LOGIF(LT, (tls_sesid = dcb_get_session_id(dcb))); dcb->func.read(dcb); } #if MUTEX_BLOCK @@ -759,6 +764,7 @@ uint32_t ev; strerror(eno)))); } atomic_add(&pollStats.n_error, 1); + LOGIF(LT, (tls_sesid = dcb_get_session_id(dcb))); dcb->func.error(dcb); } @@ -783,6 +789,7 @@ uint32_t ev; { dcb->flags |= DCBF_HUNG; spinlock_release(&dcb->dcb_initlock); + LOGIF(LT, (tls_sesid = dcb_get_session_id(dcb))); dcb->func.hangup(dcb); } else @@ -811,12 +818,14 @@ uint32_t ev; { dcb->flags |= DCBF_HUNG; spinlock_release(&dcb->dcb_initlock); + LOGIF(LT, (tls_sesid = dcb_get_session_id(dcb))); dcb->func.hangup(dcb); } else spinlock_release(&dcb->dcb_initlock); } #endif + LOGIF(LT, tls_sesid = 0); spinlock_acquire(&pollqlock); if (dcb->evq.pending_events == 0) diff --git a/server/core/session.c b/server/core/session.c index 7170c6bcc..9283fffa8 100644 --- a/server/core/session.c +++ b/server/core/session.c @@ -43,7 +43,10 @@ #include #include +/** Defined in log_manager.cc */ extern int lm_enabled_logfiles_bitmask; +/** Global session id; updated safely by holding session_spin */ +static size_t session_id; static SPINLOCK session_spin = SPINLOCK_INIT; static SESSION *allSessions = NULL; @@ -216,10 +219,29 @@ session_alloc(SERVICE *service, DCB *client_dcb) session->state = SESSION_STATE_ROUTER_READY; spinlock_release(&session->ses_lock); spinlock_acquire(&session_spin); + session->ses_id = ++session_id; /*< assign an id and increase */ session->next = allSessions; allSessions = session; spinlock_release(&session_spin); + if (session->client->user == NULL) + { + LOGIF(LT, (skygw_log_write( + LOGFILE_TRACE, + "Started session [%lu] for %s service ", + session->ses_id, + service->name))); + } + else + { + LOGIF(LT, (skygw_log_write( + LOGFILE_TRACE, + "Started %s client session [%lu] for '%s' from %s", + service->name, + session->ses_id, + session->client->user, + session->client->remote))); + } atomic_add(&service->stats.n_sessions, 1); atomic_add(&service->stats.n_current, 1); CHK_SESSION(session); @@ -352,6 +374,13 @@ bool session_free( } free(session->filters); } + + LOGIF(LT, (skygw_log_write( + LOGFILE_TRACE, + "Stopped %s client session [%lu]", + session->service->name, + session->ses_id))); + free(session); succp = true; diff --git a/server/include/dcb.h b/server/include/dcb.h index 86aef5920..0695a6e57 100644 --- a/server/include/dcb.h +++ b/server/include/dcb.h @@ -307,16 +307,11 @@ int dcb_remove_callback(DCB *, DCB_REASON, int (*)(struct dcb *, DCB_REASON, vo void *); int dcb_isvalid(DCB *); /* Check the DCB is in the linked list */ -bool dcb_set_state( - DCB* dcb, - dcb_state_t new_state, - dcb_state_t* old_state); -void dcb_call_foreach (DCB_REASON reason); +bool dcb_set_state(DCB* dcb, dcb_state_t new_state, dcb_state_t* old_state); +void dcb_call_foreach (DCB_REASON reason); +size_t dcb_get_session_id(DCB* dcb);; -void dcb_call_foreach ( - DCB_REASON reason); - /** * DCB flags values */ diff --git a/server/include/session.h b/server/include/session.h index 86de23782..a1733c873 100644 --- a/server/include/session.h +++ b/server/include/session.h @@ -110,6 +110,7 @@ typedef struct session { #endif SPINLOCK ses_lock; session_state_t state; /**< Current descriptor state */ + size_t ses_id; /**< unique session identifier */ struct dcb *client; /**< The client connection */ void *data; /**< The session data */ void *router_session;/**< The router instance data */