From c03d28b893af064364b0ae92971663801a136dc8 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 6 Aug 2005 16:58:36 +0500 Subject: [PATCH 1/9] Bug#12371 executing prepared statement fails (illegal mix of collations) item.cc: item.h: Adding Item_param::safe_charset_converter, not to return collation mix error if parameter can be converted into operation character set. ctype_utf8.result: adding test case ctype_utf8.test: adding test case sql/item.h: Bug #12371 executing prepared statement fails (illegal mix of collations) Adding Item_param::safe_charset_converter, not to returm collation mix error if parameter can be converted into operation character set. sql/item.cc: Bug #12371 executing prepared statement fails (illegal mix of collations) mysql-test/t/ctype_utf8.test: adding test case mysql-test/r/ctype_utf8.result: adding --- mysql-test/r/ctype_utf8.result | 9 +++++++++ mysql-test/t/ctype_utf8.test | 12 ++++++++++++ sql/item.cc | 20 ++++++++++++++++++++ sql/item.h | 1 + 4 files changed, 42 insertions(+) diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index bb3222ca98b..a98beb36ef1 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -993,6 +993,15 @@ select * from t1 where a like "%abc\d%"; a abcd drop table t1; +set names utf8; +create table t1 (a char(3), b varchar(10)); +insert into t1 values ('bar','kostja'); +prepare my_stmt from "select * from t1 where a=?"; +set @a:='bar'; +execute my_stmt using @a; +a b +bar kostja +drop table t1; CREATE TABLE t1 ( a varchar(255) NOT NULL default '', KEY a (a) diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index a09618df7c0..ede9665941a 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -831,6 +831,18 @@ select * from t1 where a like "%abc\d%"; drop table t1; +# +# Bug #12371 executing prepared statement fails (illegal mix of collations) +# +set names utf8; +create table t1 (a char(3), b varchar(10)); +insert into t1 values ('bar','kostja'); +prepare my_stmt from "select * from t1 where a=?"; +set @a:='bar'; +execute my_stmt using @a; +drop table t1; + + # # Bug#9557 MyISAM utf8 table crash # diff --git a/sql/item.cc b/sql/item.cc index 84dbc382a52..969604d6834 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -284,6 +284,26 @@ Item *Item_string::safe_charset_converter(CHARSET_INFO *tocs) } +Item *Item_param::safe_charset_converter(CHARSET_INFO *tocs) +{ + if (const_item()) + { + Item_string *conv; + uint conv_errors; + String tmp, cstr, *ostr= val_str(&tmp); + cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs, &conv_errors); + if (conv_errors || !(conv= new Item_string(cstr.ptr(), cstr.length(), + cstr.charset(), + collation.derivation))) + return NULL; + conv->str_value.copy(); + conv->str_value.shrink_to_length(); + return conv; + } + return NULL; +} + + bool Item_string::eq(const Item *item, bool binary_cmp) const { if (type() == item->type() && item->basic_const_item()) diff --git a/sql/item.h b/sql/item.h index 825b37fe64c..e49ee485de0 100644 --- a/sql/item.h +++ b/sql/item.h @@ -617,6 +617,7 @@ public: basic_const_item returned TRUE. */ Item *new_item(); + Item *safe_charset_converter(CHARSET_INFO *tocs); /* Implement by-value equality evaluation if parameter value is set and is a basic constant (integer, real or string). From d2c97cdee09944225768b4e1def38c7518273bd0 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 9 Aug 2005 12:17:28 -0700 Subject: [PATCH 2/9] Fix 'source' command in mysql client to handle delimiter command in sourced file properly. (Bug #11523) client/mysql.cc: Rename read_lines() to read_and_execute() and change interface so it is clear when we are reading and processing lines interactively versus in batch mode or from a file being sourced. mysql-test/r/mysql.result: Add results mysql-test/t/mysql_delimiter.sql: Add new test mysql-test/t/mysql_delimiter_source.sql: New BitKeeper file ``mysql-test/t/mysql_delimiter_source.sql'' --- client/mysql.cc | 16 ++++++++-------- mysql-test/r/mysql.result | 4 ++++ mysql-test/t/mysql_delimiter.sql | 5 ++++- mysql-test/t/mysql_delimiter_source.sql | 8 ++++++++ 4 files changed, 24 insertions(+), 9 deletions(-) create mode 100644 mysql-test/t/mysql_delimiter_source.sql diff --git a/client/mysql.cc b/client/mysql.cc index b8655d7c5f5..c9460aa958d 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -203,7 +203,7 @@ static int com_nopager(String *str, char*), com_pager(String *str, char*), com_edit(String *str,char*), com_shell(String *str, char *); #endif -static int read_lines(bool execute_commands); +static int read_and_execute(bool interactive); static int sql_connect(char *host,char *database,char *user,char *password, uint silent); static int put_info(const char *str,INFO_TYPE info,uint error=0, @@ -468,7 +468,7 @@ int main(int argc,char *argv[]) "Type 'help [[%]function name[%]]' to get help on usage of function.\n"); #endif put_info(buff,INFO_INFO); - status.exit_status=read_lines(1); // read lines and execute them + status.exit_status= read_and_execute(!status.batch); if (opt_outfile) end_tee(); mysql_end(0); @@ -948,7 +948,7 @@ static int get_options(int argc, char **argv) return(0); } -static int read_lines(bool execute_commands) +static int read_and_execute(bool interactive) { #if defined( __WIN__) || defined(OS2) || defined(__NETWARE__) char linebuffer[254]; @@ -963,7 +963,7 @@ static int read_lines(bool execute_commands) for (;;) { - if (status.batch || !execute_commands) + if (!interactive) { line=batch_readline(status.line_buff); line_number++; @@ -1041,7 +1041,7 @@ static int read_lines(bool execute_commands) Check if line is a mysql command line (We want to allow help, print and clear anywhere at line start */ - if (execute_commands && (named_cmds || glob_buffer.is_empty()) + if ((named_cmds || glob_buffer.is_empty()) && !in_string && (com=find_command(line,0))) { if ((*com->func)(&glob_buffer,line) > 0) @@ -1049,7 +1049,7 @@ static int read_lines(bool execute_commands) if (glob_buffer.is_empty()) // If buffer was emptied in_string=0; #ifdef HAVE_READLINE - if (status.add_to_history && not_in_history(line)) + if (interactive && status.add_to_history && not_in_history(line)) add_history(line); #endif continue; @@ -1059,7 +1059,7 @@ static int read_lines(bool execute_commands) } /* if in batch mode, send last query even if it doesn't end with \g or go */ - if ((status.batch || !execute_commands) && !status.exit_status) + if (!interactive && !status.exit_status) { remove_cntrl(glob_buffer); if (!glob_buffer.is_empty()) @@ -2777,7 +2777,7 @@ static int com_source(String *buffer, char *line) status.line_buff=line_buff; status.file_name=source_name; glob_buffer.length(0); // Empty command buffer - error=read_lines(0); // Read lines from file + error= read_and_execute(false); status=old_status; // Continue as before my_fclose(sql_file,MYF(0)); batch_readline_end(line_buff); diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result index dbb47152926..eeb6abd9f41 100644 --- a/mysql-test/r/mysql.result +++ b/mysql-test/r/mysql.result @@ -31,6 +31,10 @@ a Test delimiter delimiter a 1 +Tables_in_test +t1 +t2 +t3 Test delimiter : from command line a diff --git a/mysql-test/t/mysql_delimiter.sql b/mysql-test/t/mysql_delimiter.sql index 4ea481a84e2..fa80c980b29 100644 --- a/mysql-test/t/mysql_delimiter.sql +++ b/mysql-test/t/mysql_delimiter.sql @@ -45,4 +45,7 @@ delimiter delimiter select * from t1 delimiter delimiter ; # Reset delimiter - +# +# Bug #11523: \d works differently than delimiter +# +source t/mysql_delimiter_source.sql diff --git a/mysql-test/t/mysql_delimiter_source.sql b/mysql-test/t/mysql_delimiter_source.sql new file mode 100644 index 00000000000..f645091f3d4 --- /dev/null +++ b/mysql-test/t/mysql_delimiter_source.sql @@ -0,0 +1,8 @@ +delimiter // +create table t2 (a int) // +delimiter ; +\d // +create table t3 (a int) // +\d ; +show tables; +drop table t2, t3; From 8767335309e0212b6b8c9fc5220fcdedb0ffee1e Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 23 Aug 2005 16:37:21 -0700 Subject: [PATCH 3/9] Fix typo in mysql_fix_privilege_tables.sql (Bug #12705) scripts/mysql_fix_privilege_tables.sql: Fix typo --- scripts/mysql_fix_privilege_tables.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/mysql_fix_privilege_tables.sql b/scripts/mysql_fix_privilege_tables.sql index f67bab44514..45f3b8533b5 100644 --- a/scripts/mysql_fix_privilege_tables.sql +++ b/scripts/mysql_fix_privilege_tables.sql @@ -509,7 +509,7 @@ ALTER TABLE proc MODIFY name char(64) DEFAULT '' NOT NULL, 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE' - ) DEFAULT '' NOT NULL + ) DEFAULT '' NOT NULL, DEFAULT CHARACTER SET utf8; # Correct the character set and collation From afe5507c751bae8ce0726a1888c4d14407089c53 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 29 Aug 2005 12:19:08 +0200 Subject: [PATCH 4/9] fix for bug #12490 (all-in-one patch) (Packets out of order if calling HELP CONTENTS from Stored Procedure) mysql-test/r/sp-error.result: results of test of bug 12490 mysql-test/t/sp-error.test: test for bug 12490 (Packets out of order if calling HELP CONTENTS from Stored Procedure) sql/sql_yacc.yy: disable HELP in SP (fixes bug 12490) --- mysql-test/r/sp-error.result | 8 ++++++++ mysql-test/t/sp-error.test | 13 +++++++++++++ sql/sql_yacc.yy | 12 ++++++++++-- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index 4ac29a07757..23644f57353 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -748,6 +748,14 @@ end| call bug11394(2, 1)| ERROR HY000: Recursive stored routines are not allowed. drop procedure bug11394| +CREATE PROCEDURE BUG_12490() HELP CONTENTS; +ERROR 0A000: HELP is not allowed in stored procedures +CREATE FUNCTION BUG_12490() RETURNS INT HELP CONTENTS; +ERROR 0A000: HELP is not allowed in stored procedures +CREATE TABLE t_bug_12490(a int); +CREATE TRIGGER BUG_12490 BEFORE UPDATE ON t_bug_12490 FOR EACH ROW HELP CONTENTS; +ERROR 0A000: HELP is not allowed in stored procedures +DROP TABLE t_bug_12490; drop function if exists bug11834_1; drop function if exists bug11834_2; create function bug11834_1() returns int return 10; diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index f68ea1b31a3..5921d59b284 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -1079,6 +1079,19 @@ call bug11394(2, 1)| drop procedure bug11394| delimiter ;| + +# +# BUG 12490 (Packets out of order if calling HELP CONTENTS from Stored Procedure) +# +--error 1314 +CREATE PROCEDURE BUG_12490() HELP CONTENTS; +--error 1314 +CREATE FUNCTION BUG_12490() RETURNS INT HELP CONTENTS; +CREATE TABLE t_bug_12490(a int); +--error 1314 +CREATE TRIGGER BUG_12490 BEFORE UPDATE ON t_bug_12490 FOR EACH ROW HELP CONTENTS; +DROP TABLE t_bug_12490; + # # Bug#11834 "Re-execution of prepared statement with dropped function # crashes server". Also tests handling of prepared stmts which use diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 6b447396dec..c1f4236604a 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1016,11 +1016,19 @@ execute_var_ident: '@' ident_or_text /* help */ help: - HELP_SYM ident_or_text + HELP_SYM + { + if (Lex->sphead) + { + my_error(ER_SP_BADSTATEMENT, MYF(0), "HELP"); + YYABORT; + } + } + ident_or_text { LEX *lex= Lex; lex->sql_command= SQLCOM_HELP; - lex->help_arg= $2.str; + lex->help_arg= $3.str; }; /* change master */ From 593f03d94b638420810b64d9ec1b8ddfabbae909 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 29 Aug 2005 16:49:01 +0500 Subject: [PATCH 5/9] ctype_utf8.result, ctype_utf8.test, item.cc: Bug#12371 executing prepared statement fails (illegal mix of collations) After review fixes. sql/item.cc: Bug#12371 executing prepared statement fails (illegal mix of collations) After review fixes. mysql-test/t/ctype_utf8.test: Bug#12371 executing prepared statement fails (illegal mix of collations) After review fixes. mysql-test/r/ctype_utf8.result: Bug#12371 executing prepared statement fails (illegal mix of collations) After review fixes. --- mysql-test/r/ctype_utf8.result | 3 +++ mysql-test/t/ctype_utf8.test | 2 ++ sql/item.cc | 8 +++++++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index a98beb36ef1..748361d3178 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -1001,6 +1001,9 @@ set @a:='bar'; execute my_stmt using @a; a b bar kostja +set @a:=NULL; +execute my_stmt using @a; +a b drop table t1; CREATE TABLE t1 ( a varchar(255) NOT NULL default '', diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index ede9665941a..e6342777839 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -840,6 +840,8 @@ insert into t1 values ('bar','kostja'); prepare my_stmt from "select * from t1 where a=?"; set @a:='bar'; execute my_stmt using @a; +set @a:=NULL; +execute my_stmt using @a; drop table t1; diff --git a/sql/item.cc b/sql/item.cc index 53640c4e44a..2d4f9138a51 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -290,7 +290,13 @@ Item *Item_param::safe_charset_converter(CHARSET_INFO *tocs) { Item_string *conv; uint conv_errors; - String tmp, cstr, *ostr= val_str(&tmp); + char buf[MAX_FIELD_WIDTH]; + String tmp(buf, sizeof(buf), &my_charset_bin); + String cstr, *ostr= val_str(&tmp); + /* + As safe_charset_converter is not executed for + a parameter bound to NULL, ostr should never be 0. + */ cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs, &conv_errors); if (conv_errors || !(conv= new Item_string(cstr.ptr(), cstr.length(), cstr.charset(), From c38e297b64826a772eeed012a9a9615866aade89 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 29 Aug 2005 15:45:03 +0200 Subject: [PATCH 6/9] fix for bug #12841 (Server crash on DO IFNULL(NULL,NULL) (fixes also "SELECT CAST(IFNULL(NULL,NULL) as DECIMAL)" unreported crash) (new revampled fix with suggestions from Igor) mysql-test/r/select.result: result of test for bug 12841 mysql-test/t/select.test: test for bug #12841 (Server crash on DO IFNULL(NULL,NULL) sql/item_func.cc: don't use the return value of ::str_op() without checking it whether checking it for NULL. (fixes bug #12841 as well as another not reported bug, but existing one - test case added). All other places where ::str_op() is used are safe. --- mysql-test/r/select.result | 10 ++++++++++ mysql-test/t/select.test | 9 +++++++++ sql/item_func.cc | 13 +++++++++---- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 83682d87504..0d5c1aed485 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -2875,6 +2875,16 @@ b a t1_val t2_val 1 1 1 1 1 2 2 1 drop table t1, t2, t3; +DO IFNULL(NULL, NULL); +SELECT CAST(IFNULL(NULL, NULL) AS DECIMAL); +CAST(IFNULL(NULL, NULL) AS DECIMAL) +NULL +SELECT ABS(IFNULL(NULL, NULL)); +ABS(IFNULL(NULL, NULL)) +NULL +SELECT IFNULL(NULL, NULL); +IFNULL(NULL, NULL) +NULL create table t1 (a char(1)); create table t2 (a char(1)); insert into t1 values ('a'),('b'),('c'); diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index ebd382b1df1..fad01ac9acf 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -2445,6 +2445,15 @@ select * from t1 natural join t3 natural join t2; drop table t1, t2, t3; +# +# Bug #12841: Server crash on DO IFNULL(NULL,NULL) +# +# (testing returning of int, decimal, real, string) +DO IFNULL(NULL, NULL); +SELECT CAST(IFNULL(NULL, NULL) AS DECIMAL); +SELECT ABS(IFNULL(NULL, NULL)); +SELECT IFNULL(NULL, NULL); + # # Bug #6495 Illogical requirement for column qualification in NATURAL join # diff --git a/sql/item_func.cc b/sql/item_func.cc index 80808c0ac87..8125264ab15 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -734,11 +734,13 @@ longlong Item_func_numhybrid::val_int() case STRING_RESULT: { int err_not_used; - String *res= str_op(&str_value); + String *res; + if (!(res= str_op(&str_value))) + return 0; + char *end= (char*) res->ptr() + res->length(); CHARSET_INFO *cs= str_value.charset(); - return (res ? (*(cs->cset->strtoll10))(cs, res->ptr(), &end, - &err_not_used) : 0); + return (*(cs->cset->strtoll10))(cs, res->ptr(), &end, &err_not_used); } default: DBUG_ASSERT(0); @@ -769,7 +771,10 @@ my_decimal *Item_func_numhybrid::val_decimal(my_decimal *decimal_value) } case STRING_RESULT: { - String *res= str_op(&str_value); + String *res; + if (!(res= str_op(&str_value))) + return NULL; + str2my_decimal(E_DEC_FATAL_ERROR, (char*) res->ptr(), res->length(), res->charset(), decimal_value); break; From 04af59a36c1a18d153a224970732acd6f8f525c8 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 29 Aug 2005 21:00:43 +0200 Subject: [PATCH 7/9] fix for bug 12207 (alter table discard tablespace on MyISAM table causes ERROR 2013). (all-in-one approved patch) mysql-test/r/alter_table.result: result for test for bug #12207 (alter table discard database works on mysiam and causes error 2013) mysql-test/t/alter_table.test: test for bug #12207 (alter table discard tablescpae on MyISAM table causes ERROR 2013) sql/sql_table.cc: send all error message to table->file->print_error() thus not missing handing of some (like engine not supported). fix for bug #12207 (alter table discard tablespace on MyISAM table causes ERROR 2013) --- mysql-test/r/alter_table.result | 4 ++++ mysql-test/t/alter_table.test | 8 ++++++++ sql/sql_table.cc | 6 +++--- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result index 9f127181fc2..dd7c5ed4407 100644 --- a/mysql-test/r/alter_table.result +++ b/mysql-test/r/alter_table.result @@ -523,6 +523,10 @@ alter table t1 drop key no_such_key; ERROR 42000: Can't DROP 'no_such_key'; check that column/key exists alter table t1 drop key a; drop table t1; +CREATE TABLE T12207(a int) ENGINE=MYISAM; +ALTER TABLE T12207 DISCARD TABLESPACE; +ERROR HY000: Table storage engine for 'T12207' doesn't have this option +DROP TABLE T12207; create table t1 (a text) character set koi8r; insert into t1 values (_koi8r'ΤΕΣΤ'); select hex(a) from t1; diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test index a237b21f403..003662fc956 100644 --- a/mysql-test/t/alter_table.test +++ b/mysql-test/t/alter_table.test @@ -337,6 +337,14 @@ alter table t1 drop key no_such_key; alter table t1 drop key a; drop table t1; +# +# BUG 12207 alter table ... discard table space on MyISAM table causes ERROR 2013 (HY000) +# +CREATE TABLE T12207(a int) ENGINE=MYISAM; +--error 1031 +ALTER TABLE T12207 DISCARD TABLESPACE; +DROP TABLE T12207; + # # Bug #6479 ALTER TABLE ... changing charset fails for TEXT columns # diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 8874a70327e..d7609bc2f58 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2820,15 +2820,15 @@ mysql_discard_or_import_tablespace(THD *thd, err: close_thread_tables(thd); thd->tablespace_op=FALSE; + if (error == 0) { send_ok(thd); DBUG_RETURN(0); } - if (error == HA_ERR_ROW_IS_REFERENCED) - my_error(ER_ROW_IS_REFERENCED, MYF(0)); - + table->file->print_error(error, MYF(0)); + DBUG_RETURN(-1); } From 26b6b1b2a284c6c0dfb9b744407022f7c4c29303 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 29 Aug 2005 23:29:35 +0400 Subject: [PATCH 8/9] Cleanup the instance manager code. BitKeeper/deleted/.del-factory.h~c1679505d3a6dd53: Delete: server-tools/instance-manager/factory.h BitKeeper/deleted/.del-factory.cc~6836cccd4cd35b4d: Delete: server-tools/instance-manager/factory.cc server-tools/instance-manager/Makefile.am: - remove Commands_factory: it'll be needed when we add support for NNTP/HTTP connections, currently it only adds unnecessary complexity. server-tools/instance-manager/commands.cc: - fix coding style: no else after return; fix comments, make one place a bit faster. server-tools/instance-manager/guardian.cc: - fix coding style and comments. - we must register the current thread in the thread registry before entering pthread_cond_timedwait, because at shutdown the thread registry will try to kick out of wait all blocked threads. Unregistered threads are not awakened by the registry. This fixes the failinig assert in Thread_registry::~Thread_registry at shutdown, when shutdown is requested and there is an instance monitored by Guardian. server-tools/instance-manager/guardian.h: - fix coding style: enums must start with enum_ server-tools/instance-manager/instance.h: - move comment to the variable it comments server-tools/instance-manager/instance_map.cc: - cleanup server-tools/instance-manager/instance_options.cc: - cleanup; no else after return (fix coding style). server-tools/instance-manager/manager.cc: - fix alignment; make some code easier to read. server-tools/instance-manager/mysql_connection.cc: - remove Commands_factory server-tools/instance-manager/options.cc: - fix a possible crash when the instance manager is started with --no-defaults --defaults-file=~/.my.cnf: if we return without cloning saved_argv by calling load_defaults, Options::cleanup will crash on attempt to free_defaults(saved_argv); server-tools/instance-manager/parse.cc: - get rid of Commands_factory server-tools/instance-manager/parse.h: - get rid of Commands_factory server-tools/instance-manager/parse_output.cc: - in parse_output_and_get_value return error also if the specified pattern was not found, or the command failed to execute. server-tools/instance-manager/portability.h: - fix coding style (// comments are allowed only at ends of lines) server-tools/instance-manager/thread_registry.cc: - implement Thread_registry::cond_timedwait server-tools/instance-manager/thread_registry.h: - implement Thread_registry::cond_timedwait; remove unused out parameter from Thread_registry::cond_wait. server-tools/instance-manager/user_map.cc: - safety: newline can take 2 bytes. --- server-tools/instance-manager/Makefile.am | 1 - server-tools/instance-manager/commands.cc | 52 ++++----- server-tools/instance-manager/factory.cc | 100 ------------------ server-tools/instance-manager/factory.h | 61 ----------- server-tools/instance-manager/guardian.cc | 19 ++-- server-tools/instance-manager/guardian.h | 6 +- server-tools/instance-manager/instance.h | 2 +- server-tools/instance-manager/instance_map.cc | 21 ++-- .../instance-manager/instance_options.cc | 74 +++++-------- server-tools/instance-manager/manager.cc | 23 ++-- .../instance-manager/mysql_connection.cc | 5 +- server-tools/instance-manager/options.cc | 4 +- server-tools/instance-manager/parse.cc | 65 +++++------- server-tools/instance-manager/parse.h | 5 +- server-tools/instance-manager/parse_output.cc | 19 ++-- server-tools/instance-manager/portability.h | 2 +- .../instance-manager/thread_registry.cc | 29 ++++- .../instance-manager/thread_registry.h | 6 +- server-tools/instance-manager/user_map.cc | 2 +- 19 files changed, 157 insertions(+), 339 deletions(-) delete mode 100644 server-tools/instance-manager/factory.cc delete mode 100644 server-tools/instance-manager/factory.h diff --git a/server-tools/instance-manager/Makefile.am b/server-tools/instance-manager/Makefile.am index 4de0aac3d23..b872adca09d 100644 --- a/server-tools/instance-manager/Makefile.am +++ b/server-tools/instance-manager/Makefile.am @@ -70,7 +70,6 @@ mysqlmanager_SOURCES= command.cc command.h mysqlmanager.cc \ user_map.h user_map.cc \ messages.h messages.cc \ commands.h commands.cc \ - factory.h factory.cc \ instance.h instance.cc \ instance_map.h instance_map.cc\ instance_options.h instance_options.cc \ diff --git a/server-tools/instance-manager/commands.cc b/server-tools/instance-manager/commands.cc index 0f801c8cc7e..1cf888eab45 100644 --- a/server-tools/instance-manager/commands.cc +++ b/server-tools/instance-manager/commands.cc @@ -461,7 +461,8 @@ int Show_instance_log::execute(struct st_net *net, ulong connection_id) /* Instance has no such log */ if (logpath == NULL) return ER_NO_SUCH_LOG; - else if (*logpath == '\0') + + if (*logpath == '\0') return ER_GUESS_LOGFILE; @@ -571,6 +572,7 @@ int Show_instance_log_files::execute(struct st_net *net, ulong connection_id) if ((instance= instance_map-> find(instance_name, strlen(instance_name))) == NULL) goto err; + { /* We have alike structure in instance_options.cc. We use such to be able @@ -686,7 +688,7 @@ Set_option::Set_option(Instance_map *instance_map_arg, option. RETURN - ER_BAD_INSTANCE_NAME The instance name specified is not valid + ER_OUT_OF_RESOURCES out of resources ER_ACCESS_OPTION_FILE Cannot access the option file 0 - ok */ @@ -694,22 +696,14 @@ Set_option::Set_option(Instance_map *instance_map_arg, int Set_option::correct_file(int skip) { int error; + const static int mysys_to_im_error[]= { 0, ER_OUT_OF_RESOURCES, + ER_ACCESS_OPTION_FILE }; error= modify_defaults_file(Options::config_file, option, option_value, instance_name, skip); - switch (error) - { - case 0: - return 0; /* everything was fine */ - case 1: - return ER_OUT_OF_RESOURCES; - case 2: - return ER_ACCESS_OPTION_FILE; - default: - DBUG_ASSERT(0); /* should never get here */ - } + DBUG_ASSERT(error >= 0 && error <= 2); - return 0; /* keep compiler happy */ + return mysys_to_im_error[error]; } @@ -725,10 +719,9 @@ int Set_option::correct_file(int skip) 1 - error occured */ - int Set_option::do_command(struct st_net *net) { - int error= 0; + int error; /* we must hold the instance_map mutex while changing config file */ instance_map->lock(); @@ -746,16 +739,14 @@ int Set_option::execute(struct st_net *net, ulong connection_id) int val; val= do_command(net); + if (val == 0) - { net_send_ok(net, connection_id, NULL); - return 0; - } return val; } - else - return ER_BAD_INSTANCE_NAME; + + return ER_BAD_INSTANCE_NAME; } @@ -785,16 +776,15 @@ int Stop_instance::execute(struct st_net *net, ulong connection_id) if (instance == 0) return ER_BAD_INSTANCE_NAME; /* haven't found an instance */ - else - { - if (!(instance->options.nonguarded)) - instance_map->guardian-> - stop_guard(instance); - if ((err_code= instance->stop())) - return err_code; - net_send_ok(net, connection_id, NULL); - return 0; - } + + if (!(instance->options.nonguarded)) + instance_map->guardian->stop_guard(instance); + + if ((err_code= instance->stop())) + return err_code; + + net_send_ok(net, connection_id, NULL); + return 0; } diff --git a/server-tools/instance-manager/factory.cc b/server-tools/instance-manager/factory.cc deleted file mode 100644 index 58ac32a9feb..00000000000 --- a/server-tools/instance-manager/factory.cc +++ /dev/null @@ -1,100 +0,0 @@ -/* Copyright (C) 2004 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#include "factory.h" - - -Show_instances *Command_factory::new_Show_instances() -{ - return new Show_instances(&instance_map); -} - - -Flush_instances *Command_factory::new_Flush_instances() -{ - return new Flush_instances(&instance_map); -} - - -Show_instance_status *Command_factory:: - new_Show_instance_status(const char *name, uint len) -{ - return new Show_instance_status(&instance_map, name, len); -} - - -Show_instance_options *Command_factory:: - new_Show_instance_options(const char *name, uint len) -{ - return new Show_instance_options(&instance_map, name, len); -} - - -Start_instance *Command_factory:: - new_Start_instance(const char *name, uint len) -{ - return new Start_instance(&instance_map, name, len); -} - - -Stop_instance *Command_factory::new_Stop_instance(const char *name, uint len) -{ - return new Stop_instance(&instance_map, name, len); -} - - -Syntax_error *Command_factory::new_Syntax_error() -{ - return new Syntax_error(); -} - - -Set_option *Command_factory:: - new_Set_option(const char* name, uint len, - const char *option_arg, uint option_len, - const char *option_value_arg, uint option_value_len) -{ - return new Set_option(&instance_map, name, len, option_arg, - option_len, option_value_arg, option_value_len); -} - - -Unset_option *Command_factory:: - new_Unset_option(const char* name, uint len, - const char *option_arg, uint option_len, - const char *option_value_arg, uint option_value_len) -{ - return new Unset_option(&instance_map, name, len, option_arg, - option_len, option_value_arg, option_value_len); -} - - -Show_instance_log *Command_factory:: - new_Show_instance_log(const char *name, uint len, - Log_type log_type_arg, - const char *size, const char *offset) -{ - return new Show_instance_log(&instance_map, name, len, - log_type_arg, size, offset); -} - - -Show_instance_log_files *Command_factory:: - new_Show_instance_log_files(const char *name, uint len) -{ - return new Show_instance_log_files(&instance_map, name, len); -} - diff --git a/server-tools/instance-manager/factory.h b/server-tools/instance-manager/factory.h deleted file mode 100644 index 14073eb5007..00000000000 --- a/server-tools/instance-manager/factory.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_FACTORY_H -#define INCLUDES_MYSQL_INSTANCE_MANAGER_FACTORY_H -/* Copyright (C) 2004 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#include "command.h" -#include "commands.h" -#include "instance_map.h" - -/* - This class could be used to handle various protocols. We could pass to - the parser various derived classes. I.e Mylsq_command_factory, - Http_command_factory e.t.c. Also see comment in the instance_map.cc -*/ - -class Show_instances; - -class Command_factory -{ -public: - Command_factory(Instance_map &instance_map): instance_map(instance_map) - {} - - Show_instances *new_Show_instances (); - Flush_instances *new_Flush_instances (); - Syntax_error *new_Syntax_error (); - Show_instance_status *new_Show_instance_status (const char *name, uint len); - Show_instance_options *new_Show_instance_options (const char *name, uint len); - Start_instance *new_Start_instance (const char *name, uint len); - Stop_instance *new_Stop_instance (const char *name, uint len); - Show_instance_log *new_Show_instance_log (const char *name, uint len, - Log_type log_type_arg, - const char *size, - const char *offset); - Set_option *new_Set_option (const char *name, uint len, - const char *option_arg, uint option_len, - const char *option_value_arg, - uint option_value_len); - Unset_option *new_Unset_option (const char *name, uint len, - const char *option_arg, uint option_len, - const char *option_value_arg, - uint option_value_len); - Show_instance_log_files *new_Show_instance_log_files (const char *name, - uint len); - - Instance_map &instance_map; -}; -#endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_FACTORY_H */ diff --git a/server-tools/instance-manager/guardian.cc b/server-tools/instance-manager/guardian.cc index b8580711524..17f4204185a 100644 --- a/server-tools/instance-manager/guardian.cc +++ b/server-tools/instance-manager/guardian.cc @@ -122,8 +122,7 @@ void Guardian_thread::process_instance(Instance *instance, } else { - switch (current_node->state) - { + switch (current_node->state) { case NOT_STARTED: instance->start(); current_node->last_checked= current_time; @@ -149,7 +148,8 @@ void Guardian_thread::process_instance(Instance *instance, log_info("guardian: starting instance %s", instance->options.instance_name); } - else current_node->state= CRASHED; + else + current_node->state= CRASHED; break; case CRASHED: /* just regular restarts */ if (current_time - current_node->last_checked > @@ -219,7 +219,8 @@ void Guardian_thread::run() /* check the loop predicate before sleeping */ if (!(shutdown_requested && (!(guarded_instances)))) - pthread_cond_timedwait(&COND_guardian, &LOCK_guardian, &timeout); + thread_registry.cond_timedwait(&thread_info, &COND_guardian, + &LOCK_guardian, &timeout); } stopped= TRUE; @@ -365,18 +366,20 @@ int Guardian_thread::stop_guard(Instance *instance) } /* - Start Guardian shutdown. Attempt to start instances if requested. + An internal method which is called at shutdown to unregister instances and + attempt to stop them if requested. SYNOPSYS stop_instances() stop_instances_arg whether we should stop instances at shutdown DESCRIPTION - Loops through the guarded_instances list and prepares them for shutdown. If stop_instances was requested, we need to issue a stop command and change - the state accordingly. Otherwise we could simply delete an entry. - NOTE: Guardian should be locked by the calling function + the state accordingly. Otherwise we simply delete an entry. + + NOTE + Guardian object should be locked by the calling function. RETURN 0 - ok diff --git a/server-tools/instance-manager/guardian.h b/server-tools/instance-manager/guardian.h index e8992722f3c..758c4a3f3bc 100644 --- a/server-tools/instance-manager/guardian.h +++ b/server-tools/instance-manager/guardian.h @@ -62,8 +62,8 @@ class Guardian_thread: public Guardian_thread_args { public: /* states of an instance */ - enum INSTANCE_STATE { NOT_STARTED= 1, STARTING, STARTED, JUST_CRASHED, - CRASHED, CRASHED_AND_ABANDONED, STOPPING }; + enum enum_instance_state { NOT_STARTED= 1, STARTING, STARTED, JUST_CRASHED, + CRASHED, CRASHED_AND_ABANDONED, STOPPING }; /* The Guardian list node structure. Guardian utilizes it to store @@ -74,7 +74,7 @@ public: { Instance *instance; /* state of an instance (i.e. STARTED, CRASHED, etc.) */ - INSTANCE_STATE state; + enum_instance_state state; /* the amount of attemts to restart instance (cleaned up at success) */ int restart_counter; /* triggered at a crash */ diff --git a/server-tools/instance-manager/instance.h b/server-tools/instance-manager/instance.h index cbcfee0c7ef..003cbca8cef 100644 --- a/server-tools/instance-manager/instance.h +++ b/server-tools/instance-manager/instance.h @@ -49,12 +49,12 @@ public: Instance_options options; private: + int crashed; /* Mutex protecting the instance. Currently we use it to avoid the double start of the instance. This happens when the instance is starting and we issue the start command once more. */ - int crashed; pthread_mutex_t LOCK_instance; /* This condition variable is used to wake threads waiting for instance to diff --git a/server-tools/instance-manager/instance_map.cc b/server-tools/instance-manager/instance_map.cc index 69eadd7e765..b3a207ae79f 100644 --- a/server-tools/instance-manager/instance_map.cc +++ b/server-tools/instance-manager/instance_map.cc @@ -91,22 +91,20 @@ static int process_option(void *ctx, const char *group, const char *option) if ((instance= map->find(group, strlen(group))) == NULL) { if ((instance= new Instance) == 0) - goto err_new_instance; - if (instance->init(group)) - goto err; - if (map->add_instance(instance)) goto err; + if (instance->init(group) || map->add_instance(instance)) + goto err_instance; } if (instance->options.add_option(option)) - goto err; + goto err; /* the instance'll be deleted when we destroy the map */ } return 0; -err: +err_instance: delete instance; -err_new_instance: +err: return 1; } @@ -122,10 +120,8 @@ mysqld_path(default_mysqld_path_arg) int Instance_map::init() { - if (hash_init(&hash, default_charset_info, START_HASH_SIZE, 0, 0, - get_instance_key, delete_instance, 0)) - return 1; - return 0; + return hash_init(&hash, default_charset_info, START_HASH_SIZE, 0, 0, + get_instance_key, delete_instance, 0); } Instance_map::~Instance_map() @@ -217,10 +213,9 @@ int Instance_map::complete_initialization() } return 0; -err: - return 1; err_instance: delete instance; +err: return 1; } diff --git a/server-tools/instance-manager/instance_options.cc b/server-tools/instance-manager/instance_options.cc index 998bf470c8d..124195aad37 100644 --- a/server-tools/instance-manager/instance_options.cc +++ b/server-tools/instance-manager/instance_options.cc @@ -51,13 +51,9 @@ static inline int create_mysqld_command(Buffer *buf, /* here the '\0' character is copied from the option string */ buf->append(position, option, option_len); - if (buf->is_error()) - return 1; + return buf->is_error(); } - else - return 1; - - return 0; + return 1; } @@ -96,10 +92,8 @@ int Instance_options::get_default_option(char *result, size_t result_len, /* +2 eats first "--" from the option string (E.g. "--datadir") */ rc= parse_output_and_get_value(cmd.buffer, option_name + 2, result, result_len, GET_VALUE); - - return rc; err: - return 1; + return rc; } @@ -142,11 +136,8 @@ int Instance_options::fill_instance_version() result[strlen(result) - NEWLINE_LEN]= '\0'; mysqld_version= strdup_root(&alloc, result); } - - return rc; - err: - return 1; + return rc; } @@ -194,13 +185,15 @@ int Instance_options::fill_log_options() /* compute hostname and datadir for the instance */ if (mysqld_datadir == NULL) { - if (get_default_option(datadir, - MAX_LOG_OPTION_LENGTH, "--datadir")) + if (get_default_option(datadir, MAX_LOG_OPTION_LENGTH, "--datadir")) goto err; } - else /* below is safe, as --datadir always has a value */ - strmake(datadir, strchr(mysqld_datadir, '=') + 1, - MAX_LOG_OPTION_LENGTH - 1); + else + { + /* below is safe, as --datadir always has a value */ + strmake(datadir, + strchr(mysqld_datadir, '=') + 1, MAX_LOG_OPTION_LENGTH - 1); + } if (gethostname(hostname,sizeof(hostname)-1) < 0) strmov(hostname, "mysql"); @@ -230,15 +223,12 @@ int Instance_options::fill_log_options() MY_UNPACK_FILENAME | MY_SAFE_PATH); - if ((MAX_LOG_OPTION_LENGTH - strlen(full_name)) > + if ((MAX_LOG_OPTION_LENGTH - strlen(full_name)) <= strlen(log_files->default_suffix)) - { - strmov(full_name + strlen(full_name), - log_files->default_suffix); - } - else goto err; + strmov(full_name + strlen(full_name), log_files->default_suffix); + /* If there were specified two identical logfiles options, we would loose some memory in MEM_ROOT here. However @@ -254,8 +244,7 @@ int Instance_options::fill_log_options() fn_format(full_name, argv[i] +log_files->length + 1, datadir, "", MY_UNPACK_FILENAME | MY_SAFE_PATH); - if (!(*(log_files->value)= - strdup_root(&alloc, full_name))) + if (!(*(log_files->value)= strdup_root(&alloc, full_name))) goto err; } } @@ -263,10 +252,8 @@ int Instance_options::fill_log_options() } return 0; - err: return 1; - } @@ -294,7 +281,7 @@ int Instance_options::get_pid_filename(char *result) const char *pid_file= mysqld_pid_file; char datadir[MAX_PATH_LEN]; - if (!(mysqld_datadir)) + if (mysqld_datadir == NULL) { /* we might get an error here if we have wrong path to the mysqld binary */ if (get_default_option(datadir, sizeof(datadir), "--datadir")) @@ -333,8 +320,7 @@ pid_t Instance_options::get_pid() my_fclose(pid_file_stream, MYF(0)); return pid; } - else - return 0; + return 0; } @@ -343,11 +329,8 @@ int Instance_options::complete_initialization(const char *default_path, { const char *tmp; - if (!(mysqld_path)) - { - if (!(mysqld_path= strdup_root(&alloc, default_path))) - goto err; - } + if (!mysqld_path && !(mysqld_path= strdup_root(&alloc, default_path))) + goto err; mysqld_path_len= strlen(mysqld_path); @@ -395,9 +378,10 @@ int Instance_options::complete_initialization(const char *default_path, goto err; /* we need to reserve space for the final zero + possible default options */ - if (!(argv= (char**) alloc_root(&alloc, (options_array.elements + 1 - + MAX_NUMBER_OF_DEFAULT_OPTIONS) * sizeof(char*)))) - goto err; + if (!(argv= (char**) + alloc_root(&alloc, (options_array.elements + 1 + + MAX_NUMBER_OF_DEFAULT_OPTIONS) * sizeof(char*)))) + goto err; /* the path must be first in the argv */ if (add_to_argv(mysqld_path)) @@ -465,8 +449,8 @@ int Instance_options::add_option(const char* option) for (selected_options= options; selected_options->name; selected_options++) { - if (!strncmp(tmp, selected_options->name, selected_options->length)) - switch(selected_options->type){ + if (strncmp(tmp, selected_options->name, selected_options->length) == 0) + switch (selected_options->type) { case SAVE_WHOLE_AND_ADD: *(selected_options->value)= tmp; insert_dynamic(&options_array,(gptr) &tmp); @@ -496,7 +480,7 @@ int Instance_options::add_to_argv(const char* option) { DBUG_ASSERT(filled_default_options < MAX_NUMBER_OF_DEFAULT_OPTIONS); - if ((option)) + if (option) argv[filled_default_options++]= (char*) option; return 0; } @@ -508,9 +492,7 @@ void Instance_options::print_argv() int i; printf("printing out an instance %s argv:\n", instance_name); for (i=0; argv[i] != NULL; i++) - { printf("argv: %s\n", argv[i]); - } } @@ -526,10 +508,10 @@ int Instance_options::init(const char *instance_name_arg) init_alloc_root(&alloc, MEM_ROOT_BLOCK_SIZE, 0); if (my_init_dynamic_array(&options_array, sizeof(char*), 0, 32)) - goto err; + goto err; if (!(instance_name= strmake_root(&alloc, (char*) instance_name_arg, - instance_name_len))) + instance_name_len))) goto err; return 0; diff --git a/server-tools/instance-manager/manager.cc b/server-tools/instance-manager/manager.cc index 09d30e1312f..a42a25eadf3 100644 --- a/server-tools/instance-manager/manager.cc +++ b/server-tools/instance-manager/manager.cc @@ -39,17 +39,14 @@ static int create_pid_file(const char *pid_file_name) { if (FILE *pid_file= my_fopen(pid_file_name, O_WRONLY | O_CREAT | O_BINARY, MYF(0))) - { - fprintf(pid_file, "%d\n", (int) getpid()); - my_fclose(pid_file, MYF(0)); - } - else - { - log_error("can't create pid file %s: errno=%d, %s", - pid_file_name, errno, strerror(errno)); - return 1; - } - return 0; + { + fprintf(pid_file, "%d\n", (int) getpid()); + my_fclose(pid_file, MYF(0)); + return 0; + } + log_error("can't create pid file %s: errno=%d, %s", + pid_file_name, errno, strerror(errno)); + return 1; } #ifndef __WIN__ @@ -136,7 +133,7 @@ void manager(const Options &options) instance_map.guardian= &guardian_thread; if (instance_map.init() || user_map.init()) - return; + return; if (instance_map.load()) @@ -145,7 +142,7 @@ void manager(const Options &options) "the wrong config file options. For instance, missing mysqld " "binary. Aborting."); return; - } + } if (user_map.load(options.password_file_name)) return; diff --git a/server-tools/instance-manager/mysql_connection.cc b/server-tools/instance-manager/mysql_connection.cc index 05fb6d4e0fb..c0f15eb6a63 100644 --- a/server-tools/instance-manager/mysql_connection.cc +++ b/server-tools/instance-manager/mysql_connection.cc @@ -39,8 +39,6 @@ #include -Command *parse_command(Command_factory * factory, const char *text); - Mysql_connection_thread_args::Mysql_connection_thread_args( struct st_vio *vio_arg, Thread_registry &thread_registry_arg, @@ -336,8 +334,7 @@ int Mysql_connection_thread::dispatch_command(enum enum_server_command command, { log_info("query for connection %d : ----\n%s\n-------------------------", connection_id,packet); - Command_factory commands_factory(instance_map); - if (Command *command= parse_command(&commands_factory, packet)) + if (Command *command= parse_command(&instance_map, packet)) { int res= 0; log_info("query for connection %d successefully parsed",connection_id); diff --git a/server-tools/instance-manager/options.cc b/server-tools/instance-manager/options.cc index 6fd11471fc6..334b67e5d37 100644 --- a/server-tools/instance-manager/options.cc +++ b/server-tools/instance-manager/options.cc @@ -244,8 +244,6 @@ C_MODE_END int Options::load(int argc, char **argv) { - saved_argv= argv; - if (argc >= 2) { if (is_prefix(argv[1], "--defaults-file=")) @@ -267,6 +265,8 @@ int Options::load(int argc, char **argv) if (setup_windows_defaults()) goto err; #endif + /* load_defaults will reset saved_argv with a new allocated list */ + saved_argv= argv; /* config-file options are prepended to command-line ones */ load_defaults(config_file, default_groups, &argc, diff --git a/server-tools/instance-manager/parse.cc b/server-tools/instance-manager/parse.cc index ed3bfd6bba0..d83af2b9cf0 100644 --- a/server-tools/instance-manager/parse.cc +++ b/server-tools/instance-manager/parse.cc @@ -15,7 +15,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "parse.h" -#include "factory.h" +#include "commands.h" #include @@ -114,7 +114,7 @@ int get_text_id(const char **text, uint *word_len, const char **id) } -Command *parse_command(Command_factory *factory, const char *text) +Command *parse_command(Instance_map *map, const char *text) { uint word_len; const char *instance_name; @@ -147,10 +147,10 @@ Command *parse_command(Command_factory *factory, const char *text) if (word_len) goto syntax_error; - command= (tok1 == TOK_START) ? (Command *) - factory->new_Start_instance(instance_name, instance_name_len): - (Command *) - factory->new_Stop_instance(instance_name, instance_name_len); + if (tok1 == TOK_START) + command= new Start_instance(map, instance_name, instance_name_len); + else + command= new Stop_instance(map, instance_name, instance_name_len); break; case TOK_FLUSH: if (shift_token(&text, &word_len) != TOK_INSTANCES) @@ -160,7 +160,7 @@ Command *parse_command(Command_factory *factory, const char *text) if (word_len) goto syntax_error; - command= factory->new_Flush_instances(); + command= new Flush_instances(map); break; case TOK_UNSET: skip= true; @@ -201,13 +201,13 @@ Command *parse_command(Command_factory *factory, const char *text) goto syntax_error; if (skip) - command= factory->new_Unset_option(instance_name, instance_name_len, - option, option_len, option_value, - option_value_len); + command= new Unset_option(map, instance_name, instance_name_len, + option, option_len, option_value, + option_value_len); else - command= factory->new_Set_option(instance_name, instance_name_len, - option, option_len, option_value, - option_value_len); + command= new Set_option(map, instance_name, instance_name_len, + option, option_len, option_value, + option_value_len); break; case TOK_SHOW: switch (shift_token(&text, &word_len)) { @@ -215,7 +215,7 @@ Command *parse_command(Command_factory *factory, const char *text) get_word(&text, &word_len); if (word_len) goto syntax_error; - command= factory->new_Show_instances(); + command= new Show_instances(map); break; case TOK_INSTANCE: switch (Token tok2= shift_token(&text, &word_len)) { @@ -227,12 +227,12 @@ Command *parse_command(Command_factory *factory, const char *text) get_word(&text, &word_len); if (word_len) goto syntax_error; - command= (tok2 == TOK_STATUS) ? (Command *) - factory->new_Show_instance_status(instance_name, - instance_name_len): - (Command *) - factory->new_Show_instance_options(instance_name, - instance_name_len); + if (tok2 == TOK_STATUS) + command= new Show_instance_status(map, instance_name, + instance_name_len); + else + command= new Show_instance_options(map, instance_name, + instance_name_len); break; default: goto syntax_error; @@ -252,9 +252,8 @@ Command *parse_command(Command_factory *factory, const char *text) /* check that this is the end of the command */ if (word_len) goto syntax_error; - command= (Command *) - factory->new_Show_instance_log_files(instance_name, - instance_name_len); + command= new Show_instance_log_files(map, instance_name, + instance_name_len); break; case TOK_ERROR: case TOK_GENERAL: @@ -288,22 +287,16 @@ Command *parse_command(Command_factory *factory, const char *text) get_word(&text, &word_len); if (!word_len) goto syntax_error; - command= (Command *) - factory->new_Show_instance_log(instance_name, - instance_name_len, - log_type, - log_size, - text); + command= new Show_instance_log(map, instance_name, + instance_name_len, log_type, + log_size, text); //get_text_id(&text, &log_size_len, &log_size); break; case '\0': - command= (Command *) - factory->new_Show_instance_log(instance_name, - instance_name_len, - log_type, - log_size, - NULL); + command= new Show_instance_log(map, instance_name, + instance_name_len, log_type, + log_size, NULL); break; /* this is ok */ default: goto syntax_error; @@ -324,7 +317,7 @@ Command *parse_command(Command_factory *factory, const char *text) break; default: syntax_error: - command= factory->new_Syntax_error(); + command= new Syntax_error(); } return command; } diff --git a/server-tools/instance-manager/parse.h b/server-tools/instance-manager/parse.h index 7d13691e7eb..3da53e3a61e 100644 --- a/server-tools/instance-manager/parse.h +++ b/server-tools/instance-manager/parse.h @@ -20,7 +20,7 @@ #include class Command; -class Command_factory; +class Instance_map; enum Log_type { @@ -29,7 +29,7 @@ enum Log_type IM_LOG_SLOW }; -Command *parse_command(Command_factory *factory, const char *text); +Command *parse_command(Instance_map *instance_map, const char *text); /* define kinds of the word seek method */ enum { ALPHANUM= 1, NONSPACE }; @@ -62,5 +62,4 @@ inline void get_word(const char **text, uint *word_len, *word_len= word_end - *text; } - #endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_PARSE_H */ diff --git a/server-tools/instance-manager/parse_output.cc b/server-tools/instance-manager/parse_output.cc index 98074c47d64..4ec9a71bfd2 100644 --- a/server-tools/instance-manager/parse_output.cc +++ b/server-tools/instance-manager/parse_output.cc @@ -43,8 +43,8 @@ if flag is GET_VALUE. Return the rest of the parsed string otherwise. RETURN - 0 - ok - 1 - error occured + 0 - ok, the word has been found + 1 - error occured or the word is not found */ int parse_output_and_get_value(const char *command, const char *word, @@ -56,9 +56,15 @@ int parse_output_and_get_value(const char *command, const char *word, /* should be enough to store the string from the output */ enum { MAX_LINE_LEN= 512 }; char linebuf[MAX_LINE_LEN]; + int rc= 1; wordlen= strlen(word); + /* + Successful return of popen does not tell us whether the command has been + executed successfully: if the command was not found, we'll get EOF + when reading the output buffer below. + */ if (!(output= popen(command, "r"))) goto err; @@ -95,10 +101,9 @@ int parse_output_and_get_value(const char *command, const char *word, strmake(result, linep, found_word_len); } else /* currently there are only two options */ - { strmake(result, linep, input_buffer_len - 1); - } - goto pclose; + rc= 0; + break; } } @@ -106,9 +111,7 @@ pclose: /* we are not interested in the termination status */ pclose(output); - return 0; - err: - return 1; + return rc; } diff --git a/server-tools/instance-manager/portability.h b/server-tools/instance-manager/portability.h index 133d99eb111..c2b4e8b7467 100644 --- a/server-tools/instance-manager/portability.h +++ b/server-tools/instance-manager/portability.h @@ -8,7 +8,7 @@ #define SIGKILL 9 #define SHUT_RDWR 0x2 -//TODO: fix this +/*TODO: fix this */ #define DEFAULT_MONITORING_INTERVAL 20 #define DEFAULT_PORT 2273 #define PROTOCOL_VERSION 10 diff --git a/server-tools/instance-manager/thread_registry.cc b/server-tools/instance-manager/thread_registry.cc index 0d47664a89a..a7384c0fa13 100644 --- a/server-tools/instance-manager/thread_registry.cc +++ b/server-tools/instance-manager/thread_registry.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2003 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* cOPYRIght (C) 2003 MySQL AB & MySQL Finland AB & TCX DataKonsult AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -122,11 +122,10 @@ void Thread_registry::unregister_thread(Thread_info *info) */ int Thread_registry::cond_wait(Thread_info *info, pthread_cond_t *cond, - pthread_mutex_t *mutex, bool *is_shutdown) + pthread_mutex_t *mutex) { pthread_mutex_lock(&LOCK_thread_registry); - *is_shutdown= shutdown_in_progress; - if (*is_shutdown) + if (shutdown_in_progress) { pthread_mutex_unlock(&LOCK_thread_registry); return 0; @@ -137,7 +136,27 @@ int Thread_registry::cond_wait(Thread_info *info, pthread_cond_t *cond, int rc= pthread_cond_wait(cond, mutex); pthread_mutex_lock(&LOCK_thread_registry); info->current_cond= 0; - *is_shutdown= shutdown_in_progress; + pthread_mutex_unlock(&LOCK_thread_registry); + return rc; +} + + +int Thread_registry::cond_timedwait(Thread_info *info, pthread_cond_t *cond, + pthread_mutex_t *mutex, + struct timespec *wait_time) +{ + pthread_mutex_lock(&LOCK_thread_registry); + if (shutdown_in_progress) + { + pthread_mutex_unlock(&LOCK_thread_registry); + return 0; + } + info->current_cond= cond; + pthread_mutex_unlock(&LOCK_thread_registry); + /* sic: race condition here, cond can be signaled in deliver_shutdown */ + int rc= pthread_cond_timedwait(cond, mutex, wait_time); + pthread_mutex_lock(&LOCK_thread_registry); + info->current_cond= 0; pthread_mutex_unlock(&LOCK_thread_registry); return rc; } diff --git a/server-tools/instance-manager/thread_registry.h b/server-tools/instance-manager/thread_registry.h index a25c692b77f..28899810f23 100644 --- a/server-tools/instance-manager/thread_registry.h +++ b/server-tools/instance-manager/thread_registry.h @@ -23,7 +23,7 @@ stop all running threads, cleanup and exit. Note, that a thread can't be shut down nicely if it doesn't want to be. - That's why to perform clean shutdown, all threads consituting a process + That's why to perform clean shutdown, all threads constituting a process must observe certain rules. Here we use the rules, described in Butenhof book 'Programming with POSIX threads', namely: - all user signals are handled in 'signal thread' in synchronous manner @@ -94,7 +94,9 @@ public: void request_shutdown(); inline bool is_shutdown(); int cond_wait(Thread_info *info, pthread_cond_t *cond, - pthread_mutex_t *mutex, bool *is_shutdown); + pthread_mutex_t *mutex); + int cond_timedwait(Thread_info *info, pthread_cond_t *cond, + pthread_mutex_t *mutex, struct timespec *wait_time); private: Thread_info head; bool shutdown_in_progress; diff --git a/server-tools/instance-manager/user_map.cc b/server-tools/instance-manager/user_map.cc index 4e47127bba1..d13eb681d05 100644 --- a/server-tools/instance-manager/user_map.cc +++ b/server-tools/instance-manager/user_map.cc @@ -128,7 +128,7 @@ int User_map::load(const char *password_file_name) char line[USERNAME_LENGTH + SCRAMBLED_PASSWORD_CHAR_LENGTH + 2 + /* for possible quotes */ 1 + /* for ':' */ - 1 + /* for newline */ + 2 + /* for newline */ 1]; /* for trailing zero */ User *user; int rc= 1; From a5403486b5f2ec05e7f4df4c4b44b3a0722283f5 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 29 Aug 2005 23:32:47 +0400 Subject: [PATCH 9/9] Remove a no longer used header. --- server-tools/instance-manager/mysql_connection.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/server-tools/instance-manager/mysql_connection.cc b/server-tools/instance-manager/mysql_connection.cc index c0f15eb6a63..dfa12f6f6e2 100644 --- a/server-tools/instance-manager/mysql_connection.cc +++ b/server-tools/instance-manager/mysql_connection.cc @@ -29,7 +29,6 @@ #include "protocol.h" #include "messages.h" #include "command.h" -#include "factory.h" #include "parse.h" #include