From cb2974156823977fd2c700c64ff0867183b3f744 Mon Sep 17 00:00:00 2001 From: Shishir Jaiswal Date: Mon, 16 May 2016 13:46:49 +0530 Subject: Bug#21977380 - POSSIBLE BUFFER OVERFLOW ISSUES DESCRIPTION =========== Buffer overflow is reported in a lot of code sections spanning across server, client programs, Regex libraries etc. If not handled appropriately, they can cause abnormal behaviour. ANALYSIS ======== The reported casea are the ones which are likely to result in SEGFAULT, MEMORY LEAK etc. FIX === - sprintf() has been replaced by my_snprintf() to avoid buffer overflow. - my_free() is done after checking if the pointer isn't NULL already and setting it to NULL thereafter at few places. - Buffer is ensured to be large enough to hold the data. - 'unsigned int' (aka 'uint') is replaced with 'size_t' to avoid wraparound. - Memory is freed (if not done so) after its alloced and used. - Inserted assert() for size check in InnoDb memcached code (from 5.6 onwards) - Other minor changes --- client/mysqlcheck.c | 42 ++++++++++++++++++++++++++---------------- client/mysqldump.c | 49 +++++++++++++++++++++++++++---------------------- client/mysqlshow.c | 36 +++++++++++++++++++----------------- 3 files changed, 72 insertions(+), 55 deletions(-) (limited to 'client') diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index a564e871281..55b941e7f1a 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -213,13 +213,13 @@ static int process_selected_tables(char *db, char **table_names, int tables); static int process_all_tables_in_db(char *database); static int process_one_db(char *database); static int use_db(char *database); -static int handle_request_for_tables(char *tables, uint length); +static int handle_request_for_tables(char *tables, size_t length); static int dbConnect(char *host, char *user,char *passwd); static void dbDisconnect(char *host); static void DBerror(MYSQL *mysql, const char *when); static void safe_exit(int error); static void print_result(); -static uint fixed_name_length(const char *name); +static size_t fixed_name_length(const char *name); static char *fix_table_name(char *dest, char *src); int what_to_do = 0; @@ -486,7 +486,7 @@ static int process_selected_tables(char *db, char **table_names, int tables) *end++= ','; } *--end = 0; - handle_request_for_tables(table_names_comma_sep + 1, (uint) (tot_length - 1)); + handle_request_for_tables(table_names_comma_sep + 1, tot_length - 1); my_free(table_names_comma_sep); } else @@ -496,10 +496,10 @@ static int process_selected_tables(char *db, char **table_names, int tables) } /* process_selected_tables */ -static uint fixed_name_length(const char *name) +static size_t fixed_name_length(const char *name) { const char *p; - uint extra_length= 2; /* count the first/last backticks */ + size_t extra_length= 2; /* count the first/last backticks */ for (p= name; *p; p++) { @@ -508,7 +508,7 @@ static uint fixed_name_length(const char *name) else if (*p == '.') extra_length+= 2; } - return (uint) ((p - name) + extra_length); + return (size_t) ((p - name) + extra_length); } @@ -564,7 +564,7 @@ static int process_all_tables_in_db(char *database) */ char *tables, *end; - uint tot_length = 0; + size_t tot_length = 0; while ((row = mysql_fetch_row(res))) tot_length+= fixed_name_length(row[0]) + 2; @@ -622,7 +622,9 @@ static int fix_table_storage_name(const char *name) int rc= 0; if (strncmp(name, "#mysql50#", 9)) return 1; - sprintf(qbuf, "RENAME TABLE `%s` TO `%s`", name, name + 9); + my_snprintf(qbuf, sizeof(qbuf), "RENAME TABLE `%s` TO `%s`", + name, name + 9); + rc= run_query(qbuf); if (verbose) printf("%-50s %s\n", name, rc ? "FAILED" : "OK"); @@ -635,7 +637,8 @@ static int fix_database_storage_name(const char *name) int rc= 0; if (strncmp(name, "#mysql50#", 9)) return 1; - sprintf(qbuf, "ALTER DATABASE `%s` UPGRADE DATA DIRECTORY NAME", name); + my_snprintf(qbuf, sizeof(qbuf), "ALTER DATABASE `%s` UPGRADE DATA DIRECTORY " + "NAME", name); rc= run_query(qbuf); if (verbose) printf("%-50s %s\n", name, rc ? "FAILED" : "OK"); @@ -653,7 +656,7 @@ static int rebuild_table(char *name) ptr= strmov(query, "ALTER TABLE "); ptr= fix_table_name(ptr, name); ptr= strxmov(ptr, " FORCE", NullS); - if (mysql_real_query(sock, query, (uint)(ptr - query))) + if (mysql_real_query(sock, query, (ulong)(ptr - query))) { fprintf(stderr, "Failed to %s\n", query); fprintf(stderr, "Error: %s\n", mysql_error(sock)); @@ -702,10 +705,10 @@ static int disable_binlog() return run_query(stmt); } -static int handle_request_for_tables(char *tables, uint length) +static int handle_request_for_tables(char *tables, size_t length) { char *query, *end, options[100], message[100]; - uint query_length= 0; + size_t query_length= 0, query_size= sizeof(char)*(length+110); const char *op = 0; options[0] = 0; @@ -736,10 +739,14 @@ static int handle_request_for_tables(char *tables, uint length) return fix_table_storage_name(tables); } - if (!(query =(char *) my_malloc((sizeof(char)*(length+110)), MYF(MY_WME)))) + if (!(query =(char *) my_malloc(query_size, MYF(MY_WME)))) + { return 1; + } if (opt_all_in_1) { + DBUG_ASSERT(strlen(op)+strlen(tables)+strlen(options)+8+1 <= query_size); + /* No backticks here as we added them before */ query_length= sprintf(query, "%s TABLE %s %s", op, tables, options); } @@ -750,7 +757,7 @@ static int handle_request_for_tables(char *tables, uint length) ptr= strmov(strmov(query, op), " TABLE "); ptr= fix_table_name(ptr, tables); ptr= strxmov(ptr, " ", options, NullS); - query_length= (uint) (ptr - query); + query_length= (size_t) (ptr - query); } if (mysql_real_query(sock, query, query_length)) { @@ -834,7 +841,10 @@ static void print_result() prev_alter[0]= 0; } else - strcpy(prev_alter, alter_txt); + { + strncpy(prev_alter, alter_txt, MAX_ALTER_STR_SIZE-1); + prev_alter[MAX_ALTER_STR_SIZE-1]= 0; + } } } } @@ -978,7 +988,7 @@ int main(int argc, char **argv) process_databases(argv); if (opt_auto_repair) { - uint i; + size_t i; if (!opt_silent && (tables4repair.elements || tables4rebuild.elements)) puts("\nRepairing tables"); diff --git a/client/mysqldump.c b/client/mysqldump.c index 6c4fec313c5..00265def489 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -86,7 +86,7 @@ static void add_load_option(DYNAMIC_STRING *str, const char *option, const char *option_value); -static ulong find_set(TYPELIB *lib, const char *x, uint length, +static ulong find_set(TYPELIB *lib, const char *x, size_t length, char **err_pos, uint *err_len); static char *alloc_query_str(ulong size); @@ -852,7 +852,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), opt_set_charset= 0; opt_compatible_mode_str= argument; opt_compatible_mode= find_set(&compatible_mode_typelib, - argument, (uint) strlen(argument), + argument, strlen(argument), &err_ptr, &err_len); if (err_len) { @@ -862,7 +862,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), } #if !defined(DBUG_OFF) { - uint size_for_sql_mode= 0; + size_t size_for_sql_mode= 0; const char **ptr; for (ptr= compatible_mode_names; *ptr; ptr++) size_for_sql_mode+= strlen(*ptr); @@ -1138,8 +1138,8 @@ static int fetch_db_collation(const char *db_name, break; } - strncpy(db_cl_name, db_cl_row[0], db_cl_size); - db_cl_name[db_cl_size - 1]= 0; /* just in case. */ + strncpy(db_cl_name, db_cl_row[0], db_cl_size-1); + db_cl_name[db_cl_size - 1]= 0; } while (FALSE); @@ -1150,7 +1150,7 @@ static int fetch_db_collation(const char *db_name, static char *my_case_str(const char *str, - uint str_len, + size_t str_len, const char *token, uint token_len) { @@ -1366,7 +1366,7 @@ static int switch_character_set_results(MYSQL *mysql, const char *cs_name) */ static char *cover_definer_clause(const char *stmt_str, - uint stmt_length, + size_t stmt_length, const char *definer_version_str, uint definer_version_length, const char *stmt_version_str, @@ -1548,14 +1548,14 @@ static void dbDisconnect(char *host) } /* dbDisconnect */ -static void unescape(FILE *file,char *pos,uint length) +static void unescape(FILE *file,char *pos, size_t length) { char *tmp; DBUG_ENTER("unescape"); if (!(tmp=(char*) my_malloc(length*2+1, MYF(MY_WME)))) die(EX_MYSQLERR, "Couldn't allocate memory"); - mysql_real_escape_string(&mysql_connection, tmp, pos, length); + mysql_real_escape_string(&mysql_connection, tmp, pos, (ulong)length); fputc('\'', file); fputs(tmp, file); fputc('\'', file); @@ -1669,7 +1669,7 @@ static char *quote_for_like(const char *name, char *buff) Quote '<' '>' '&' '\"' chars and print a string to the xml_file. */ -static void print_quoted_xml(FILE *xml_file, const char *str, ulong len, +static void print_quoted_xml(FILE *xml_file, const char *str, size_t len, my_bool is_attribute_name) { const char *end; @@ -1928,7 +1928,7 @@ static void print_xml_row(FILE *xml_file, const char *row_name, squeezed to a single hyphen. */ -static void print_xml_comment(FILE *xml_file, ulong len, +static void print_xml_comment(FILE *xml_file, size_t len, const char *comment_string) { const char* end; @@ -2045,7 +2045,7 @@ static uint dump_events_for_db(char *db) DBUG_ENTER("dump_events_for_db"); DBUG_PRINT("enter", ("db: '%s'", db)); - mysql_real_escape_string(mysql, db_name_buff, db, strlen(db)); + mysql_real_escape_string(mysql, db_name_buff, db, (ulong)strlen(db)); /* nice comments */ print_comment(sql_file, 0, @@ -2164,6 +2164,11 @@ static uint dump_events_for_db(char *db) (const char *) (query_str != NULL ? query_str : row[3]), (const char *) delimiter); + if(query_str) + { + my_free(query_str); + query_str= NULL; + } restore_time_zone(sql_file, delimiter); restore_sql_mode(sql_file, delimiter); @@ -2257,7 +2262,7 @@ static uint dump_routines_for_db(char *db) DBUG_ENTER("dump_routines_for_db"); DBUG_PRINT("enter", ("db: '%s'", db)); - mysql_real_escape_string(mysql, db_name_buff, db, strlen(db)); + mysql_real_escape_string(mysql, db_name_buff, db, (ulong)strlen(db)); /* nice comments */ print_comment(sql_file, 0, @@ -2311,9 +2316,9 @@ static uint dump_routines_for_db(char *db) if the user has EXECUTE privilege he see routine names, but NOT the routine body of other routines that are not the creator of! */ - DBUG_PRINT("info",("length of body for %s row[2] '%s' is %d", + DBUG_PRINT("info",("length of body for %s row[2] '%s' is %zu", routine_name, row[2] ? row[2] : "(null)", - row[2] ? (int) strlen(row[2]) : 0)); + row[2] ? strlen(row[2]) : 0)); if (row[2] == NULL) { print_comment(sql_file, 1, "\n-- insufficient privileges to %s\n", @@ -3873,7 +3878,7 @@ static int dump_tablespaces_for_tables(char *db, char **table_names, int tables) int i; char name_buff[NAME_LEN*2+3]; - mysql_real_escape_string(mysql, name_buff, db, strlen(db)); + mysql_real_escape_string(mysql, name_buff, db, (ulong)strlen(db)); init_dynamic_string_checked(&where, " AND TABLESPACE_NAME IN (" "SELECT DISTINCT TABLESPACE_NAME FROM" @@ -3886,7 +3891,7 @@ static int dump_tablespaces_for_tables(char *db, char **table_names, int tables) for (i=0 ; imax_length) length=field->max_length; @@ -500,7 +501,8 @@ static int list_tables(MYSQL *mysql,const char *db,const char *table) { const char *header; - uint head_length, counter = 0; + size_t head_length; + uint counter = 0; char query[NAME_LEN + 100], rows[NAME_LEN], fields[16]; MYSQL_FIELD *field; MYSQL_RES *result; @@ -537,7 +539,7 @@ list_tables(MYSQL *mysql,const char *db,const char *table) putchar('\n'); header="Tables"; - head_length=(uint) strlen(header); + head_length= strlen(header); field=mysql_fetch_field(result); if (head_length < field->max_length) head_length=field->max_length; @@ -766,10 +768,10 @@ list_fields(MYSQL *mysql,const char *db,const char *table, *****************************************************************************/ static void -print_header(const char *header,uint head_length,...) +print_header(const char *header,size_t head_length,...) { va_list args; - uint length,i,str_length,pre_space; + size_t length,i,str_length,pre_space; const char *field; va_start(args,head_length); @@ -792,10 +794,10 @@ print_header(const char *header,uint head_length,...) putchar('|'); for (;;) { - str_length=(uint) strlen(field); + str_length= strlen(field); if (str_length > length) str_length=length+1; - pre_space=(uint) (((int) length-(int) str_length)/2)+1; + pre_space= ((length- str_length)/2)+1; for (i=0 ; i < pre_space ; i++) putchar(' '); for (i = 0 ; i < str_length ; i++) @@ -829,11 +831,11 @@ print_header(const char *header,uint head_length,...) static void -print_row(const char *header,uint head_length,...) +print_row(const char *header,size_t head_length,...) { va_list args; const char *field; - uint i,length,field_length; + size_t i,length,field_length; va_start(args,head_length); field=header; length=head_length; @@ -842,7 +844,7 @@ print_row(const char *header,uint head_length,...) putchar('|'); putchar(' '); fputs(field,stdout); - field_length=(uint) strlen(field); + field_length= strlen(field); for (i=field_length ; i <= length ; i++) putchar(' '); if (!(field=va_arg(args,char *))) @@ -856,10 +858,10 @@ print_row(const char *header,uint head_length,...) static void -print_trailer(uint head_length,...) +print_trailer(size_t head_length,...) { va_list args; - uint length,i; + size_t length,i; va_start(args,head_length); length=head_length; @@ -902,7 +904,7 @@ static void print_res_top(MYSQL_RES *result) mysql_field_seek(result,0); while((field = mysql_fetch_field(result))) { - if ((length=(uint) strlen(field->name)) > field->max_length) + if ((length= strlen(field->name)) > field->max_length) field->max_length=length; else length=field->max_length; -- cgit v1.2.1 From 5dc6a77b409291140e072470673589982a6623a2 Mon Sep 17 00:00:00 2001 From: Arun Kuruvila Date: Mon, 30 May 2016 15:20:08 +0530 Subject: Bug#23035296: MAIN.MYSQLDUMP FAILS BECUASE OF UNEXPECTED ERROR MESSAGE Description:- Mtr test, "main.mysqldump" is failing with an assert when "mysqlimport" client utility is executed with the option "--use_threads". Analysis:- "mysqlimport" uses the option, "--use_threads", to spawn worker threads to complete its job in parallel. But currently the main thread is not waiting for the worker threads to complete its cleanup, rather just wait for the worker threads to say its done doing its job. So the cleanup is done in a race between the worker threads and the main thread. This lead to an assertion failure. Fix:- "my_thread_join()" is introduced in the main thread to join all the worker threads it have spawned. This will let the main thread to wait for all the worker threads to complete its cleanup before calling "my_end()". --- client/mysqlimport.c | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) (limited to 'client') diff --git a/client/mysqlimport.c b/client/mysqlimport.c index 416159abd81..3e8f694d96d 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -592,7 +592,7 @@ error: pthread_cond_signal(&count_threshhold); pthread_mutex_unlock(&counter_mutex); mysql_thread_end(); - + pthread_exit(0); return 0; } @@ -615,15 +615,30 @@ int main(int argc, char **argv) if (opt_use_threads && !lock_tables) { - pthread_t mainthread; /* Thread descriptor */ - pthread_attr_t attr; /* Thread attributes */ + char **save_argv; + uint worker_thread_count= 0, table_count= 0, i= 0; + pthread_t *worker_threads; /* Thread descriptor */ + pthread_attr_t attr; /* Thread attributes */ pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, - PTHREAD_CREATE_DETACHED); + PTHREAD_CREATE_JOINABLE); pthread_mutex_init(&counter_mutex, NULL); pthread_cond_init(&count_threshhold, NULL); + /* Count the number of tables. This number denotes the total number + of threads spawn. + */ + save_argv= argv; + for (table_count= 0; *argv != NULL; argv++) + table_count++; + argv= save_argv; + + if (!(worker_threads= (pthread_t*) my_malloc(table_count * + sizeof(*worker_threads), + MYF(0)))) + return -2; + for (counter= 0; *argv != NULL; argv++) /* Loop through tables */ { pthread_mutex_lock(&counter_mutex); @@ -638,15 +653,16 @@ int main(int argc, char **argv) counter++; pthread_mutex_unlock(&counter_mutex); /* now create the thread */ - if (pthread_create(&mainthread, &attr, worker_thread, - (void *)*argv) != 0) + if (pthread_create(&worker_threads[worker_thread_count], &attr, + worker_thread, (void *)*argv) != 0) { pthread_mutex_lock(&counter_mutex); counter--; pthread_mutex_unlock(&counter_mutex); - fprintf(stderr,"%s: Could not create thread\n", - my_progname); + fprintf(stderr,"%s: Could not create thread\n", my_progname); + continue; } + worker_thread_count++; } /* @@ -664,6 +680,14 @@ int main(int argc, char **argv) pthread_mutex_destroy(&counter_mutex); pthread_cond_destroy(&count_threshhold); pthread_attr_destroy(&attr); + + for(i= 0; i < worker_thread_count; i++) + { + if (pthread_join(worker_threads[i], NULL)) + fprintf(stderr,"%s: Could not join worker thread.\n", my_progname); + } + + my_free(worker_threads); } else { -- cgit v1.2.1 From 96d90250c66d9159522582a541c87e3c9d8b8d08 Mon Sep 17 00:00:00 2001 From: Arun Kuruvila Date: Thu, 2 Jun 2016 15:02:46 +0530 Subject: Bug#23035296: MAIN.MYSQLDUMP FAILS BECUASE OF UNEXPECTED ERROR MESSAGE Post push patch to fix test case failure. --- client/mysqlimport.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'client') diff --git a/client/mysqlimport.c b/client/mysqlimport.c index 3e8f694d96d..81eb5a37fde 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -30,6 +30,7 @@ /* Global Thread counter */ uint counter; +pthread_mutex_t init_mutex; pthread_mutex_t counter_mutex; pthread_cond_t count_threshhold; @@ -417,8 +418,13 @@ static MYSQL *db_connect(char *host, char *database, MYSQL *mysql; if (verbose) fprintf(stdout, "Connecting to %s\n", host ? host : "localhost"); + pthread_mutex_lock(&init_mutex); if (!(mysql= mysql_init(NULL))) + { + pthread_mutex_unlock(&init_mutex); return 0; + } + pthread_mutex_unlock(&init_mutex); if (opt_compress) mysql_options(mysql,MYSQL_OPT_COMPRESS,NullS); if (opt_local_file) @@ -623,6 +629,7 @@ int main(int argc, char **argv) pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + pthread_mutex_init(&init_mutex, NULL); pthread_mutex_init(&counter_mutex, NULL); pthread_cond_init(&count_threshhold, NULL); @@ -677,6 +684,7 @@ int main(int argc, char **argv) pthread_cond_timedwait(&count_threshhold, &counter_mutex, &abstime); } pthread_mutex_unlock(&counter_mutex); + pthread_mutex_destroy(&init_mutex); pthread_mutex_destroy(&counter_mutex); pthread_cond_destroy(&count_threshhold); pthread_attr_destroy(&attr); -- cgit v1.2.1 From df0d8efaf25a69990cf422d55011c1c0eebdec51 Mon Sep 17 00:00:00 2001 From: Arun Kuruvila Date: Fri, 3 Jun 2016 12:50:23 +0530 Subject: Bug#23035296: MAIN.MYSQLDUMP FAILS BECUASE OF UNEXPECTED ERROR MESSAGE Post push patch to fix test case failure. --- client/mysqlimport.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'client') diff --git a/client/mysqlimport.c b/client/mysqlimport.c index 81eb5a37fde..5841c0b855a 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -418,13 +418,19 @@ static MYSQL *db_connect(char *host, char *database, MYSQL *mysql; if (verbose) fprintf(stdout, "Connecting to %s\n", host ? host : "localhost"); - pthread_mutex_lock(&init_mutex); - if (!(mysql= mysql_init(NULL))) + if (opt_use_threads && !lock_tables) { + pthread_mutex_lock(&init_mutex); + if (!(mysql= mysql_init(NULL))) + { + pthread_mutex_unlock(&init_mutex); + return 0; + } pthread_mutex_unlock(&init_mutex); - return 0; } - pthread_mutex_unlock(&init_mutex); + else + if (!(mysql= mysql_init(NULL))) + return 0; if (opt_compress) mysql_options(mysql,MYSQL_OPT_COMPRESS,NullS); if (opt_local_file) -- cgit v1.2.1 From a3f642415a8f8c52ed8a6b38ba5b48f814ab6bd8 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 8 Aug 2016 12:58:27 +0200 Subject: MDEV-6128:[PATCH] mysqlcheck wrongly escapes '.' in table names a correct fix: * store properly quoted table names in tables4repair/etc lists * tell handle_request_for_tables whether the name is aalready properly quoted * test cases for all uses of fix_table_name() --- client/mysqlcheck.c | 67 +++++++++++++++++++++-------------------------------- 1 file changed, 27 insertions(+), 40 deletions(-) (limited to 'client') diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index 75f841f3c5e..a07fc773726 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -232,7 +232,7 @@ static int process_selected_tables(char *db, char **table_names, int tables); static int process_all_tables_in_db(char *database); static int process_one_db(char *database); static int use_db(char *database); -static int handle_request_for_tables(char *tables, size_t length, my_bool view); +static int handle_request_for_tables(char *, size_t, my_bool, my_bool); static int dbConnect(char *host, char *user,char *passwd); static void dbDisconnect(char *host); static void DBerror(MYSQL *mysql, const char *when); @@ -566,7 +566,7 @@ static int process_selected_tables(char *db, char **table_names, int tables) } *--end = 0; handle_request_for_tables(table_names_comma_sep + 1, tot_length - 1, - opt_do_views != 0); + opt_do_views != 0, opt_all_in_1); my_free(table_names_comma_sep); } else @@ -577,7 +577,7 @@ static int process_selected_tables(char *db, char **table_names, int tables) view= is_view(table); if (view < 0) continue; - handle_request_for_tables(table, table_len, (view == 1)); + handle_request_for_tables(table, table_len, view == 1, opt_all_in_1); } DBUG_RETURN(0); } /* process_selected_tables */ @@ -605,13 +605,9 @@ static char *fix_table_name(char *dest, char *src) *dest++= '`'; for (; *src; src++) { - switch (*src) { - case '`': /* escape backtick character */ + if (*src == '`') *dest++= '`'; - /* fall through */ - default: - *dest++= *src; - } + *dest++= *src; } *dest++= '`'; @@ -700,9 +696,9 @@ static int process_all_tables_in_db(char *database) *--end = 0; *--views_end = 0; if (tot_length) - handle_request_for_tables(tables + 1, tot_length - 1, FALSE); + handle_request_for_tables(tables + 1, tot_length - 1, FALSE, opt_all_in_1); if (tot_views_length) - handle_request_for_tables(views + 1, tot_views_length - 1, TRUE); + handle_request_for_tables(views + 1, tot_views_length - 1, TRUE, opt_all_in_1); my_free(tables); my_free(views); } @@ -728,7 +724,7 @@ static int process_all_tables_in_db(char *database) !strcmp(row[0], "slow_log"))) continue; /* Skip logging tables */ - handle_request_for_tables(row[0], fixed_name_length(row[0]), view); + handle_request_for_tables(row[0], fixed_name_length(row[0]), view, opt_all_in_1); } } mysql_free_result(res); @@ -787,13 +783,11 @@ static int rebuild_table(char *name) int rc= 0; DBUG_ENTER("rebuild_table"); - query= (char*)my_malloc(sizeof(char) * (12 + fixed_name_length(name) + 6 + 1), + query= (char*)my_malloc(sizeof(char) * (12 + strlen(name) + 6 + 1), MYF(MY_WME)); if (!query) DBUG_RETURN(1); - ptr= strmov(query, "ALTER TABLE "); - ptr= fix_table_name(ptr, name); - ptr= strxmov(ptr, " FORCE", NullS); + ptr= strxmov(query, "ALTER TABLE ", name, " FORCE", NullS); if (mysql_real_query(sock, query, (ulong)(ptr - query))) { fprintf(stderr, "Failed to %s\n", query); @@ -849,7 +843,8 @@ static int disable_binlog() return run_query(stmt); } -static int handle_request_for_tables(char *tables, size_t length, my_bool view) +static int handle_request_for_tables(char *tables, size_t length, + my_bool view, my_bool dont_quote) { char *query, *end, options[100], message[100]; char table_name_buff[NAME_CHAR_LEN*2*2+1], *table_name; @@ -907,7 +902,7 @@ static int handle_request_for_tables(char *tables, size_t length, my_bool view) if (!(query =(char *) my_malloc(query_size, MYF(MY_WME)))) DBUG_RETURN(1); - if (opt_all_in_1) + if (dont_quote) { DBUG_ASSERT(strlen(op)+strlen(tables)+strlen(options)+8+1 <= query_size); @@ -950,6 +945,13 @@ static int handle_request_for_tables(char *tables, size_t length, my_bool view) DBUG_RETURN(0); } +static void insert_table_name(DYNAMIC_ARRAY *arr, char *in, size_t dblen) +{ + char buf[NAME_LEN*2+2]; + in[dblen]= 0; + my_snprintf(buf, sizeof(buf), "%`s.%`s", in, in + dblen + 1); + insert_dynamic(arr, (uchar*) buf); +} static void print_result() { @@ -957,16 +959,13 @@ static void print_result() MYSQL_ROW row; char prev[(NAME_LEN+9)*3+2]; char prev_alter[MAX_ALTER_STR_SIZE]; - char *db_name; - uint length_of_db; + size_t length_of_db= strlen(sock->db); uint i; my_bool found_error=0, table_rebuild=0; DYNAMIC_ARRAY *array4repair= &tables4repair; DBUG_ENTER("print_result"); res = mysql_use_result(sock); - db_name= sock->db; - length_of_db= strlen(db_name); prev[0] = '\0'; prev_alter[0]= 0; @@ -990,16 +989,10 @@ static void print_result() if (prev_alter[0]) insert_dynamic(&alter_table_cmds, (uchar*) prev_alter); else - { - char *table_name= prev + (length_of_db+1); - insert_dynamic(&tables4rebuild, (uchar*) table_name); - } + insert_table_name(&tables4rebuild, prev, length_of_db); } else - { - char *table_name= prev + (length_of_db+1); - insert_dynamic(array4repair, (uchar*) table_name); - } + insert_table_name(array4repair, prev, length_of_db); } array4repair= &tables4repair; found_error=0; @@ -1066,16 +1059,10 @@ static void print_result() if (prev_alter[0]) insert_dynamic(&alter_table_cmds, (uchar*) prev_alter); else - { - char *table_name= prev + (length_of_db+1); - insert_dynamic(&tables4rebuild, (uchar*) table_name); - } + insert_table_name(&tables4rebuild, prev, length_of_db); } else - { - char *table_name= prev + (length_of_db+1); - insert_dynamic(array4repair, (uchar*) table_name); - } + insert_table_name(array4repair, prev, length_of_db); } mysql_free_result(res); DBUG_VOID_RETURN; @@ -1209,7 +1196,7 @@ int main(int argc, char **argv) for (i = 0; i < tables4repair.elements ; i++) { char *name= (char*) dynamic_array_ptr(&tables4repair, i); - handle_request_for_tables(name, fixed_name_length(name), FALSE); + handle_request_for_tables(name, fixed_name_length(name), FALSE, TRUE); } for (i = 0; i < tables4rebuild.elements ; i++) rebuild_table((char*) dynamic_array_ptr(&tables4rebuild, i)); @@ -1220,7 +1207,7 @@ int main(int argc, char **argv) for (i = 0; i < views4repair.elements ; i++) { char *name= (char*) dynamic_array_ptr(&views4repair, i); - handle_request_for_tables(name, fixed_name_length(name), TRUE); + handle_request_for_tables(name, fixed_name_length(name), TRUE, TRUE); } } ret= test(first_error); -- cgit v1.2.1 From b51109693e6abb0e58256192a648cdd158d47615 Mon Sep 17 00:00:00 2001 From: Monty Date: Mon, 22 Aug 2016 10:16:00 +0300 Subject: MDEV-10630 rpl.rpl_mdev6020 fails in buildbot with timeout The issue was that when running with valgrind the wait for master_pos_Wait() was not long enough. This patch also fixes two other failures that could affect rpl_mdev6020: - check_if_conflicting_replication_locks() didn't properly check domains - 'did_mark_start_commit' was after signals to other threads was sent which could get the variable read too early. --- client/mysqltest.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'client') diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 84d5abc1a67..66bcb6462e7 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -181,6 +181,7 @@ static uint my_end_arg= 0; static uint opt_tail_lines= 0; static uint opt_connect_timeout= 0; +static uint opt_wait_for_pos_timeout= 0; static char delimiter[MAX_DELIMITER_LENGTH]= ";"; static uint delimiter_length= 1; @@ -4659,7 +4660,7 @@ void do_sync_with_master2(struct st_command *command, long offset, MYSQL_ROW row; MYSQL *mysql= cur_con->mysql; char query_buf[FN_REFLEN+128]; - int timeout= 300; /* seconds */ + int timeout= opt_wait_for_pos_timeout; if (!master_pos.file[0]) die("Calling 'sync_with_master' without calling 'save_master_pos'"); @@ -7098,6 +7099,10 @@ static struct my_option my_long_options[] = "Number of seconds before connection timeout.", &opt_connect_timeout, &opt_connect_timeout, 0, GET_UINT, REQUIRED_ARG, 120, 0, 3600 * 12, 0, 0, 0}, + {"wait_for_pos_timeout", 0, + "Number of seconds to wait for master_pos_wait", + &opt_wait_for_pos_timeout, &opt_wait_for_pos_timeout, 0, GET_UINT, + REQUIRED_ARG, 300, 0, 3600 * 12, 0, 0, 0}, {"plugin_dir", 0, "Directory for client-side plugins.", &opt_plugin_dir, &opt_plugin_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, -- cgit v1.2.1