From: kpettersson Date: July 11 2007 8:18am Subject: bk commit into 5.1 tree (Kristofer.Pettersson:1.2528) BUG#28012 List-Archive: http://lists.mysql.com/commits/30656 Message-Id: <200707110818.l6B8HuYe006494@mail.mysql.com> Below is the list of changes that have just been committed into a local 5.1 repository of Kristofer Pettersson. When Kristofer Pettersson does a push these changes will be propagated to the main repository and, within 24 hours after the push, to the public repository. For information on how to access the public repository see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html ChangeSet@stripped, 2007-07-10 17:26:34+02:00, Kristofer.Pettersson@naruto. +2 -0 Bug#28012 Patch : IM crashes instead of reporting an error when mysqldpath is bad If an instance object failed to initialize during program start, the instance manager program would crash. Because of this the program would crash if an incorrect mysqld path option was supplied in the configuration file. This patch prevents the program from crash and makes it show an error message instead. server-tools/instance-manager/instance.cc@stripped, 2007-07-10 17:26:28+02:00, Kristofer.Pettersson@naruto. +12 -7 - Added code to verify that the instance object was initialized before any attempt is made to start the associated process. - Added additional error messages on a startup failure. - Instance:init method will now return TRUE on an error during instance initialization. server-tools/instance-manager/parse_output.cc@stripped, 2007-07-10 17:26:28+02:00, Kristofer.Pettersson@naruto. +110 -21 - The windows function _popen does not always return NULL on a failure. A windows specific implementation of parse_output_and_get_value was added which uses the recommend method for creating process pipes in a windows environment. diff -Nrup a/server-tools/instance-manager/instance.cc b/server-tools/instance-manager/instance.cc --- a/server-tools/instance-manager/instance.cc 2007-02-23 12:13:48 +01:00 +++ b/server-tools/instance-manager/instance.cc 2007-07-10 17:26:28 +02:00 @@ -156,9 +156,9 @@ static bool start_process(Instance_optio My_process_info *pi) { STARTUPINFO si; - ZeroMemory(&si, sizeof(STARTUPINFO)); si.cb= sizeof(STARTUPINFO); + ZeroMemory(pi, sizeof(PROCESS_INFORMATION)); int cmdlen= 0; @@ -190,6 +190,7 @@ static bool start_process(Instance_optio NULL, /* Use parent's starting directory */ &si, /* Pointer to STARTUPINFO structure */ pi); /* Pointer to PROCESS_INFORMATION structure */ + delete cmdline; return !result; @@ -321,6 +322,15 @@ void Instance_monitor::start_and_monitor My_process_info mysqld_process_info; Thread_info monitor_thread_info; + instance->lock(); + if (!instance->configured) + { + log_info("Instance '%s': Has failed to initialize.", + (const char *) instance->get_name()->str); + return; + } + instance->unlock(); + log_info("Instance '%s': Monitor: started.", (const char *) instance->get_name()->str); @@ -345,7 +355,6 @@ void Instance_monitor::start_and_monitor instance->lock(); instance->monitoring_thread_active= FALSE; instance->unlock(); - return; } @@ -537,11 +546,7 @@ bool Instance::init(const LEX_STRING *na bool Instance::complete_initialization() { configured= ! options.complete_initialization(); - return FALSE; - /* - TODO: return actual status (from - Instance_options::complete_initialization()) here. - */ + return !configured; } /************************************************************************** diff -Nrup a/server-tools/instance-manager/parse_output.cc b/server-tools/instance-manager/parse_output.cc --- a/server-tools/instance-manager/parse_output.cc 2006-12-23 20:19:48 +01:00 +++ b/server-tools/instance-manager/parse_output.cc 2007-07-10 17:26:28 +02:00 @@ -39,29 +39,27 @@ void trim_space(const char **text, uint *word_len= (end - start)+1; } -/* - Parse output of the given command - - SYNOPSIS - parse_output_and_get_value() - - command the command to execue with popen. - word the word to look for (usually an option name) - result the buffer to store the next word (option value) - input_buffer_len self-explanatory - flag this equals to GET_LINE if we want to get all the line after - the matched word and GET_VALUE otherwise. - - DESCRIPTION - - Parse output of the "command". Find the "word" and return the next one - if flag is GET_VALUE. Return the rest of the parsed string otherwise. - - RETURN - 0 - ok, the word has been found - 1 - error occured or the word is not found +/** + @brief Parse output of the given command + + @param command The command to execue with popen. + @param word The word to look for (usually an option name) + @param[out] result The buffer to store the next word (option value) + @param input_buffer_len Length of the input buffer + @param flag This equals to GET_LINE if we want to get all the line after + the matched word and GET_VALUE otherwise. + + Parse output of the "command". Find the "word" and return the next one + if flag is GET_VALUE. Return the rest of the parsed string otherwise. + + @note This function has a separate windows implementation. + + @return The error status code. + @retval 0 Ok, the word has been found. + @retval 1 Error occured or the word is not found. */ +#ifndef __WIN__ int parse_output_and_get_value(const char *command, const char *word, char *result, size_t input_buffer_len, uint flag) @@ -125,4 +123,95 @@ int parse_output_and_get_value(const cha err: return rc; } +#else +int parse_output_and_get_value(const char *command, const char *word, + char *result, size_t input_buffer_len, + uint flag) +{ + uint wordlen; + /* 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); + + HANDLE hChildStdoutRd, hChildStdoutWr; + + SECURITY_ATTRIBUTES saAttr; + saAttr.nLength= sizeof(SECURITY_ATTRIBUTES); + saAttr.bInheritHandle= TRUE; + saAttr.lpSecurityDescriptor= NULL; + + if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0)) + goto err; + + SetHandleInformation(hChildStdoutRd, HANDLE_FLAG_INHERIT, 0); + + STARTUPINFO siStartInfo; + ZeroMemory(&siStartInfo, sizeof(STARTUPINFO)); + siStartInfo.cb= sizeof(STARTUPINFO); + siStartInfo.hStdError= hChildStdoutWr; + siStartInfo.hStdOutput= hChildStdoutWr; + siStartInfo.dwFlags |= STARTF_USESTDHANDLES; + + PROCESS_INFORMATION piProcInfo; + BOOL retval; + + retval= CreateProcess(NULL, /* Application name */ + (char*)command, /* Command line */ + NULL, /* Process security attributes */ + NULL, /* Primary thread security attributes */ + TRUE, /* Handles are inherited */ + 0, /* Creation flags */ + NULL, /* Use parent's environment */ + NULL, /* Use parent's current directory */ + &siStartInfo, /* STARTUPINFO pointer */ + &piProcInfo); /* Receives PROCESS_INFORMATION */ + + if (!retval) + goto err; + + DWORD dw_read_count; + while (ReadFile(hChildStdoutRd, linebuf, + sizeof(linebuf)-1, &dw_read_count, NULL) && + dw_read_count != 0) + { + uint found_word_len= 0; + char *linep= linebuf; + + linebuf[sizeof(linebuf) - 1]= '\0'; /* safety */ + + /* + Find the word(s) we are looking for in the line + */ + if ((linep= strstr(linep, word))) + { + /* + If we have found our word(s), then move linep past the word(s) + */ + linep+= wordlen; + if (flag & GET_VALUE) + { + trim_space((const char**) &linep, &found_word_len); + if (input_buffer_len <= found_word_len) + goto err; + strmake(result, linep, found_word_len); + } + else /* currently there are only two options */ + strmake(result, linep, input_buffer_len - 1); + rc= 0; + break; + } + } + + /* Close all handles */ + CloseHandle(piProcInfo.hProcess); + CloseHandle(piProcInfo.hThread); + CloseHandle(hChildStdoutWr); + CloseHandle(hChildStdoutRd); +err: + return rc; +} +#endif