summaryrefslogtreecommitdiff
path: root/server-tools
diff options
context:
space:
mode:
authorkostja@bodhi.local <>2006-11-18 01:34:44 +0300
committerkostja@bodhi.local <>2006-11-18 01:34:44 +0300
commit2fc4562d63960efe6c887158b7d4a5a3fb91e053 (patch)
tree8edacec17e19484691a25cc8da80c303515238f9 /server-tools
parentd2248d973e672eda139f8ca73f3769cba0aa4971 (diff)
downloadmariadb-git-2fc4562d63960efe6c887158b7d4a5a3fb91e053.tar.gz
Port cleanups, trivial refactoring and code rearrangements from
Alik's patch for BUG#22306: STOP INSTANCE can not be applied for instances in Crashed, Failed and Abandoned" to ease review process. Evaluate global variable linuxthreads before starting threads to avoid a race.
Diffstat (limited to 'server-tools')
-rw-r--r--server-tools/instance-manager/buffer.cc4
-rw-r--r--server-tools/instance-manager/command.h2
-rw-r--r--server-tools/instance-manager/commands.cc12
-rw-r--r--server-tools/instance-manager/commands.h26
-rw-r--r--server-tools/instance-manager/guardian.cc41
-rw-r--r--server-tools/instance-manager/instance.cc540
-rw-r--r--server-tools/instance-manager/instance.h14
-rw-r--r--server-tools/instance-manager/instance_map.cc27
-rw-r--r--server-tools/instance-manager/instance_map.h7
-rw-r--r--server-tools/instance-manager/instance_options.cc96
-rw-r--r--server-tools/instance-manager/instance_options.h19
-rw-r--r--server-tools/instance-manager/listener.cc23
-rw-r--r--server-tools/instance-manager/log.cc2
-rw-r--r--server-tools/instance-manager/manager.cc59
-rw-r--r--server-tools/instance-manager/manager.h11
-rw-r--r--server-tools/instance-manager/mysqlmanager.cc29
-rw-r--r--server-tools/instance-manager/parse_output.cc2
-rw-r--r--server-tools/instance-manager/priv.cc5
-rw-r--r--server-tools/instance-manager/priv.h3
-rw-r--r--server-tools/instance-manager/user_management_commands.cc10
-rw-r--r--server-tools/instance-manager/user_management_commands.h2
-rw-r--r--server-tools/instance-manager/user_map.cc2
22 files changed, 511 insertions, 425 deletions
diff --git a/server-tools/instance-manager/buffer.cc b/server-tools/instance-manager/buffer.cc
index 8039ab24481..e1a57a53087 100644
--- a/server-tools/instance-manager/buffer.cc
+++ b/server-tools/instance-manager/buffer.cc
@@ -27,7 +27,7 @@ const uint Buffer::MAX_BUFFER_SIZE= 16777216;
/*
Puts the given string to the buffer.
- SYNOPSYS
+ SYNOPSIS
append()
position start position in the buffer
string string to be put in the buffer
@@ -59,7 +59,7 @@ int Buffer::append(uint position, const char *string, uint len_arg)
Checks whether the current buffer size is ok to put a string of the length
"len_arg" starting from "position" and reallocs it if no.
- SYNOPSYS
+ SYNOPSIS
reserve()
position the number starting byte on the buffer to store a buffer
len_arg the length of the string.
diff --git a/server-tools/instance-manager/command.h b/server-tools/instance-manager/command.h
index 7f5ec78f0d2..e5f7d6e97e6 100644
--- a/server-tools/instance-manager/command.h
+++ b/server-tools/instance-manager/command.h
@@ -43,7 +43,7 @@ public:
/*
This operation incapsulates behaviour of the command.
- SYNOPSYS
+ SYNOPSIS
net The network connection to the client.
connection_id Client connection ID
diff --git a/server-tools/instance-manager/commands.cc b/server-tools/instance-manager/commands.cc
index 671b3f6b524..b7637a270fa 100644
--- a/server-tools/instance-manager/commands.cc
+++ b/server-tools/instance-manager/commands.cc
@@ -49,7 +49,7 @@ static const int modify_defaults_to_im_error[]= { 0, ER_OUT_OF_RESOURCES,
/*
Add a string to a buffer.
- SYNOPSYS
+ SYNOPSIS
put_to_buff()
buff buffer to add the string
str string to add
@@ -590,7 +590,7 @@ Create_instance::Create_instance(const LEX_STRING *instance_name_arg)
/*
This operation initializes Create_instance object.
- SYNOPSYS
+ SYNOPSIS
text [IN/OUT] a pointer to the text containing instance options.
RETURN
@@ -607,7 +607,7 @@ bool Create_instance::init(const char **text)
/*
This operation parses CREATE INSTANCE options.
- SYNOPSYS
+ SYNOPSIS
text [IN/OUT] a pointer to the text containing instance options.
RETURN
@@ -1255,7 +1255,7 @@ bool Abstract_option_cmd::init(const char **text)
Correct the option file. The "skip" option is used to remove the found
option.
- SYNOPSYS
+ SYNOPSIS
Abstract_option_cmd::correct_file()
skip Skip the option, being searched while writing the result file.
That is, to delete it.
@@ -1395,7 +1395,7 @@ int Abstract_option_cmd::execute_impl(st_net *net, ulong connection_id)
/*
This operation parses SET options.
- SYNOPSYS
+ SYNOPSIS
text [IN/OUT] a pointer to the text containing options.
RETURN
@@ -1569,7 +1569,7 @@ int Set_option::process_option(Instance *instance, Named_value *option)
/*
This operation parses UNSET options.
- SYNOPSYS
+ SYNOPSIS
text [IN/OUT] a pointer to the text containing options.
RETURN
diff --git a/server-tools/instance-manager/commands.h b/server-tools/instance-manager/commands.h
index e275c7c2549..ba151344e3f 100644
--- a/server-tools/instance-manager/commands.h
+++ b/server-tools/instance-manager/commands.h
@@ -32,16 +32,12 @@
/*
Print all instances of this instance manager.
- Grammar: SHOW ISTANCES
+ Grammar: SHOW INSTANCES
*/
-class Show_instances : public Command
+class Show_instances: public Command
{
public:
- Show_instances()
- { }
-
-public:
int execute(st_net *net, ulong connection_id);
private:
@@ -58,10 +54,6 @@ private:
class Flush_instances : public Command
{
public:
- Flush_instances()
- { }
-
-public:
int execute(st_net *net, ulong connection_id);
};
@@ -103,7 +95,7 @@ private:
/*
Print status of an instance.
- Grammar: SHOW ISTANCE STATUS <instance_name>
+ Grammar: SHOW INSTANCE STATUS <instance_name>
*/
class Show_instance_status : public Abstract_instance_cmd
@@ -319,10 +311,6 @@ private:
class Set_option : public Abstract_option_cmd
{
-public:
- Set_option()
- { }
-
protected:
virtual bool parse_args(const char **text);
virtual int process_option(Instance *instance, Named_value *option);
@@ -336,10 +324,6 @@ protected:
class Unset_option: public Abstract_option_cmd
{
-public:
- Unset_option()
- { }
-
protected:
virtual bool parse_args(const char **text);
virtual int process_option(Instance *instance, Named_value *option);
@@ -358,10 +342,6 @@ protected:
class Syntax_error : public Command
{
public:
- Syntax_error()
- { }
-
-public:
int execute(st_net *net, ulong connection_id);
};
diff --git a/server-tools/instance-manager/guardian.cc b/server-tools/instance-manager/guardian.cc
index 1015e68158a..e601ce0111c 100644
--- a/server-tools/instance-manager/guardian.cc
+++ b/server-tools/instance-manager/guardian.cc
@@ -91,7 +91,7 @@ Guardian::~Guardian()
void Guardian::request_shutdown()
{
pthread_mutex_lock(&LOCK_guardian);
- /* stop instances or just clean up Guardian repository */
+ /* STOP Instances or just clean up Guardian repository */
stop_instances();
shutdown_requested= TRUE;
pthread_mutex_unlock(&LOCK_guardian);
@@ -110,23 +110,14 @@ void Guardian::process_instance(Instance *instance,
if (current_node->state == STOPPING)
{
- /* this branch is executed during shutdown */
- if (instance->options.shutdown_delay)
- {
- /*
- NOTE: it is important to check shutdown_delay here, but use
- shutdown_delay_val. The idea is that if the option is unset,
- shutdown_delay will be NULL, but shutdown_delay_val will not be reset.
- */
- waitchild= instance->options.shutdown_delay_val;
- }
+ waitchild= instance->options.get_shutdown_delay();
/* this returns TRUE if and only if an instance was stopped for sure */
if (instance->is_crashed())
*guarded_instances= list_delete(*guarded_instances, node);
else if ( (uint) (current_time - current_node->last_checked) > waitchild)
{
- instance->kill_instance(SIGKILL);
+ instance->kill_mysqld(SIGKILL);
/*
Later we do node= node->next. This is ok, as we are only removing
the node from the list. The pointer to the next one is still valid.
@@ -137,20 +128,20 @@ void Guardian::process_instance(Instance *instance,
return;
}
- if (instance->is_running())
+ if (instance->is_mysqld_running())
{
/* The instance can be contacted on it's port */
/* If STARTING also check that pidfile has been created */
if (current_node->state == STARTING &&
- current_node->instance->options.get_pid() == 0)
+ current_node->instance->options.load_pid() == 0)
{
/* Pid file not created yet, don't go to STARTED state yet */
}
else if (current_node->state != STARTED)
{
/* clear status fields */
- log_info("guardian: instance '%s' is running, set state to STARTED.",
+ log_info("Guardian: '%s' is running, set state to STARTED.",
(const char *) instance->options.instance_name.str);
current_node->restart_counter= 0;
current_node->crash_moment= 0;
@@ -161,7 +152,7 @@ void Guardian::process_instance(Instance *instance,
{
switch (current_node->state) {
case NOT_STARTED:
- log_info("guardian: starting instance '%s'...",
+ log_info("Guardian: starting '%s'...",
(const char *) instance->options.instance_name.str);
/* NOTE, set state to STARTING _before_ start() is called */
@@ -186,7 +177,7 @@ void Guardian::process_instance(Instance *instance,
if (instance->is_crashed())
{
instance->start();
- log_info("guardian: starting instance '%s'...",
+ log_info("Guardian: starting '%s'...",
(const char *) instance->options.instance_name.str);
}
}
@@ -204,14 +195,15 @@ void Guardian::process_instance(Instance *instance,
instance->start();
current_node->last_checked= current_time;
current_node->restart_counter++;
- log_info("guardian: restarting instance '%s'...",
+ log_info("Guardian: restarting '%s'...",
(const char *) instance->options.instance_name.str);
}
}
else
{
- log_info("guardian: cannot start instance %s. Abandoning attempts "
- "to (re)start it", instance->options.instance_name.str);
+ log_info("Guardian: can not start '%s'. "
+ "Abandoning attempts to (re)start it",
+ (const char *) instance->options.instance_name.str);
current_node->state= CRASHED_AND_ABANDONED;
}
}
@@ -226,13 +218,12 @@ void Guardian::process_instance(Instance *instance,
/*
- Run guardian thread
+ Main function of Guardian thread.
SYNOPSIS
run()
DESCRIPTION
-
Check for all guarded instances and restart them if needed. If everything
is fine go and sleep for some time.
*/
@@ -436,7 +427,7 @@ int Guardian::stop_instances()
If instance is running or was running (and now probably hanging),
request stop.
*/
- if (current_node->instance->is_running() ||
+ if (current_node->instance->is_mysqld_running() ||
(current_node->state == STARTED))
{
current_node->state= STOPPING;
@@ -446,7 +437,7 @@ int Guardian::stop_instances()
/* otherwise remove it from the list */
guarded_instances= list_delete(guarded_instances, node);
/* But try to kill it anyway. Just in case */
- current_node->instance->kill_instance(SIGTERM);
+ current_node->instance->kill_mysqld(SIGTERM);
node= node->next;
}
return 0;
@@ -499,5 +490,5 @@ bool Guardian::is_active(Instance *instance)
if (guarded)
return true;
- return instance->is_running();
+ return instance->is_mysqld_running();
}
diff --git a/server-tools/instance-manager/instance.cc b/server-tools/instance-manager/instance.cc
index e91dfab7ad9..84986c8c5ec 100644
--- a/server-tools/instance-manager/instance.cc
+++ b/server-tools/instance-manager/instance.cc
@@ -20,7 +20,6 @@
#include "instance.h"
-#include <my_global.h>
#include <mysql.h>
#include <signal.h>
@@ -29,21 +28,15 @@
#endif
#include "guardian.h"
-#include "instance_map.h"
+#include "manager.h"
#include "log.h"
#include "mysql_manager_error.h"
#include "portability.h"
#include "priv.h"
#include "thread_registry.h"
+#include "instance_map.h"
-
-const LEX_STRING
-Instance::DFLT_INSTANCE_NAME= { C_STRING_WITH_LEN("mysqld") };
-
-static const char * const INSTANCE_NAME_PREFIX= Instance::DFLT_INSTANCE_NAME.str;
-static const int INSTANCE_NAME_PREFIX_LEN= Instance::DFLT_INSTANCE_NAME.length;
-
-
+/* {{{ Platform-specific functions. */
#ifndef __WIN__
typedef pid_t My_process_info;
@@ -73,15 +66,16 @@ private:
void Instance_monitor::run()
{
- start_and_monitor_instance(&instance->options, instance->get_map(),
- &instance->thread_registry);
+ start_and_monitor_instance(&instance->options,
+ Manager::get_instance_map(),
+ Manager::get_thread_registry());
delete this;
}
/*
Wait for an instance
- SYNOPSYS
+ SYNOPSIS
wait_process()
pi Pointer to the process information structure
(platform-dependent).
@@ -139,11 +133,10 @@ static int wait_process(My_process_info *pi)
}
#endif
-
/*
Launch an instance
- SYNOPSYS
+ SYNOPSIS
start_process()
instance_options Pointer to the options of the instance to be
launched.
@@ -151,13 +144,13 @@ static int wait_process(My_process_info *pi)
(platform-dependent).
RETURN
- 0 - Success
- 1 - Cannot create an instance
+ FALSE - Success
+ TRUE - Cannot create an instance
*/
#ifndef __WIN__
-static int start_process(Instance_options *instance_options,
- My_process_info *pi)
+static bool start_process(Instance_options *instance_options,
+ My_process_info *pi)
{
#ifndef __QNX__
*pi= fork();
@@ -177,15 +170,16 @@ static int start_process(Instance_options *instance_options,
/* exec never returns */
exit(1);
case -1:
- log_info("cannot create a new process to start instance '%s'.",
+ log_info("Instance '%s': can not start mysqld: fork() failed.",
(const char *) instance_options->instance_name.str);
- return 1;
+ return TRUE;
}
- return 0;
+
+ return FALSE;
}
#else
-static int start_process(Instance_options *instance_options,
- My_process_info *pi)
+static bool start_process(Instance_options *instance_options,
+ My_process_info *pi)
{
STARTUPINFO si;
@@ -200,7 +194,7 @@ static int start_process(Instance_options *instance_options,
char *cmdline= new char[cmdlen];
if (cmdline == NULL)
- return 1;
+ return TRUE;
cmdline[0]= 0;
for (int i= 0; instance_options->argv[i] != 0; i++)
@@ -224,14 +218,87 @@ static int start_process(Instance_options *instance_options,
pi); /* Pointer to PROCESS_INFORMATION structure */
delete cmdline;
- return (!result);
+ return !result;
+}
+#endif
+
+#ifdef __WIN__
+
+BOOL SafeTerminateProcess(HANDLE hProcess, UINT uExitCode)
+{
+ DWORD dwTID, dwCode, dwErr= 0;
+ HANDLE hProcessDup= INVALID_HANDLE_VALUE;
+ HANDLE hRT= NULL;
+ HINSTANCE hKernel= GetModuleHandle("Kernel32");
+ BOOL bSuccess= FALSE;
+
+ BOOL bDup= DuplicateHandle(GetCurrentProcess(),
+ hProcess, GetCurrentProcess(), &hProcessDup,
+ PROCESS_ALL_ACCESS, FALSE, 0);
+
+ // Detect the special case where the process is
+ // already dead...
+ if (GetExitCodeProcess((bDup) ? hProcessDup : hProcess, &dwCode) &&
+ (dwCode == STILL_ACTIVE))
+ {
+ FARPROC pfnExitProc;
+
+ pfnExitProc= GetProcAddress(hKernel, "ExitProcess");
+
+ hRT= CreateRemoteThread((bDup) ? hProcessDup : hProcess, NULL, 0,
+ (LPTHREAD_START_ROUTINE)pfnExitProc,
+ (PVOID)uExitCode, 0, &dwTID);
+
+ if (hRT == NULL)
+ dwErr= GetLastError();
+ }
+ else
+ dwErr= ERROR_PROCESS_ABORTED;
+
+ if (hRT)
+ {
+ // Must wait process to terminate to
+ // guarantee that it has exited...
+ WaitForSingleObject((bDup) ? hProcessDup : hProcess, INFINITE);
+
+ CloseHandle(hRT);
+ bSuccess= TRUE;
+ }
+
+ if (bDup)
+ CloseHandle(hProcessDup);
+
+ if (!bSuccess)
+ SetLastError(dwErr);
+
+ return bSuccess;
+}
+
+int kill(pid_t pid, int signum)
+{
+ HANDLE processhandle= ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
+ if (signum == SIGTERM)
+ ::SafeTerminateProcess(processhandle, 0);
+ else
+ ::TerminateProcess(processhandle, -1);
+ return 0;
}
#endif
+/* }}} */
+
+/* {{{ Static constants. */
+
+const LEX_STRING
+Instance::DFLT_INSTANCE_NAME= { C_STRING_WITH_LEN("mysqld") };
+
+/* }}} */
+
+
/*
Fork child, exec an instance and monitor it.
- SYNOPSYS
+ SYNOPSIS
start_and_monitor_instance()
old_instance_options Pointer to the options of the instance to be
launched. This info is likely to become obsolete
@@ -246,6 +313,13 @@ static int start_process(Instance_options *instance_options,
set appropriate flags and wake all threads waiting for instance
to stop.
+ NOTE
+ A separate thread for starting/monitoring instance is a simple way
+ to avoid all pitfalls of the threads implementation in the OS (e.g.
+ LinuxThreads). For one, with such a thread we don't have to process
+ SIGCHLD, which is a tricky business if we want to do it in a
+ portable way.
+
RETURN
Function returns no value
*/
@@ -261,8 +335,8 @@ start_and_monitor_instance(Instance_options *old_instance_options,
My_process_info process_info;
Thread_info thread_info;
- log_info("Monitoring thread (instance: '%s'): started.",
- (const char *) instance_name.get_c_str());
+ log_info("Instance '%s': Monitor: started.",
+ (const char *) instance->get_name()->str);
if (!old_instance_options->nonguarded)
{
@@ -285,8 +359,8 @@ start_and_monitor_instance(Instance_options *old_instance_options,
are using is destroyed. (E.g. by "FLUSH INSTANCES")
*/
- log_info("starting instance %s...",
- (const char *) instance_name.get_c_str());
+ log_info("Instance '%s': Monitor: starting mysqld...",
+ (const char *) instance->get_name()->str);
if (start_process(old_instance_options, &process_info))
{
@@ -297,8 +371,10 @@ start_and_monitor_instance(Instance_options *old_instance_options,
/* allow users to delete instances */
instance_map->unlock();
- /* don't check for return value */
- wait_process(&process_info);
+ log_info("Instance '%s': Monitor: waiting for mysqld to stop...",
+ (const char *) instance->get_name()->str);
+
+ wait_process(&process_info); /* Don't check for return value. */
instance_map->lock();
@@ -312,16 +388,17 @@ start_and_monitor_instance(Instance_options *old_instance_options,
if (!old_instance_options->nonguarded)
thread_registry->unregister_thread(&thread_info);
- log_info("Monitoring thread (instance: '%s'): finished.",
- (const char *) instance_name.get_c_str());
+ log_info("Instance '%s': Monitor: finished.",
+ (const char *) instance->get_name()->str);
}
bool Instance::is_name_valid(const LEX_STRING *name)
{
- const char *name_suffix= name->str + INSTANCE_NAME_PREFIX_LEN;
+ const char *name_suffix= name->str + DFLT_INSTANCE_NAME.length;
- if (strncmp(name->str, INSTANCE_NAME_PREFIX, INSTANCE_NAME_PREFIX_LEN) != 0)
+ if (strncmp(name->str, Instance::DFLT_INSTANCE_NAME.str,
+ Instance::DFLT_INSTANCE_NAME.length) != 0)
return FALSE;
return *name_suffix == 0 || my_isdigit(default_charset_info, *name_suffix);
@@ -330,31 +407,139 @@ bool Instance::is_name_valid(const LEX_STRING *name)
bool Instance::is_mysqld_compatible_name(const LEX_STRING *name)
{
- return strcmp(name->str, INSTANCE_NAME_PREFIX) == 0;
+ return strcmp(name->str, DFLT_INSTANCE_NAME.str) == 0;
}
-Instance_map *Instance::get_map()
+
+/* {{{ Constructor & destructor */
+
+Instance::Instance()
+ :crashed(FALSE),
+ configured(FALSE)
{
- return instance_map;
+ pthread_mutex_init(&LOCK_instance, 0);
+ pthread_cond_init(&COND_instance_stopped, 0);
}
-void Instance::remove_pid()
+Instance::~Instance()
{
- int pid;
- if ((pid= options.get_pid()) != 0) /* check the pidfile */
- if (options.unlink_pidfile()) /* remove stalled pidfile */
- log_error("cannot remove pidfile for instance '%s', this might be "
- "since IM lacks permmissions or hasn't found the pidifle",
- (const char *) options.instance_name.str);
+ log_info("Instance '%s': destroying...", (const char *) get_name()->str);
+
+ pthread_cond_destroy(&COND_instance_stopped);
+ pthread_mutex_destroy(&LOCK_instance);
}
+/* }}} */
+
+/*
+ Initialize instance options.
+
+ SYNOPSIS
+ init()
+ name_arg name of the instance
+
+ RETURN:
+ FALSE - ok
+ TRUE - error
+*/
+
+bool Instance::init(const LEX_STRING *name_arg)
+{
+ mysqld_compatible= is_mysqld_compatible_name(name_arg);
+
+ return options.init(name_arg);
+}
+
+
+/*
+ Complete instance options initialization.
+
+ SYNOPSIS
+ complete_initialization()
+
+ RETURN
+ FALSE - ok
+ TRUE - error
+*/
+
+bool Instance::complete_initialization()
+{
+ configured= ! options.complete_initialization();
+ return FALSE;
+ /*
+ TODO: return actual status (from
+ Instance_options::complete_initialization()) here.
+ */
+}
+
+/*
+ Determine if mysqld is accepting connections.
+
+ SYNOPSIS
+ is_mysqld_running()
+
+ DESCRIPTION
+ Try to connect to mysqld with fake login/password to check whether it is
+ accepting connections or not.
+
+ MT-NOTE: this operation must be called under acquired LOCK_instance.
+
+ RETURN
+ TRUE - mysqld is alive and accept connections
+ FALSE - otherwise.
+*/
+
+bool Instance::is_mysqld_running()
+{
+ MYSQL mysql;
+ uint port= options.get_mysqld_port(); /* 0 if not specified. */
+ const char *socket= NULL;
+ static const char *password= "check_connection";
+ static const char *username= "MySQL_Instance_Manager";
+ static const char *access_denied_message= "Access denied for user";
+ bool return_val;
+
+ if (options.mysqld_socket)
+ socket= options.mysqld_socket;
+
+ /* no port was specified => instance falled back to default value */
+ if (!port && !options.mysqld_socket)
+ port= SERVER_DEFAULT_PORT;
+
+ pthread_mutex_lock(&LOCK_instance);
+
+ mysql_init(&mysql);
+ /* try to connect to a server with a fake username/password pair */
+ if (mysql_real_connect(&mysql, LOCAL_HOST, username,
+ password,
+ NullS, port,
+ socket, 0))
+ {
+ /*
+ We have successfully connected to the server using fake
+ username/password. Write a warning to the logfile.
+ */
+ log_error("Instance '%s': was able to log into mysqld.",
+ (const char *) get_name()->str);
+ pthread_mutex_unlock(&LOCK_instance);
+ return_val= TRUE; /* server is alive */
+ }
+ else
+ return_val= test(!strncmp(access_denied_message, mysql_error(&mysql),
+ sizeof(access_denied_message) - 1));
+
+ mysql_close(&mysql);
+ pthread_mutex_unlock(&LOCK_instance);
+
+ return return_val;
+}
/*
The method starts an instance.
- SYNOPSYS
+ SYNOPSIS
start()
RETURN
@@ -372,7 +557,7 @@ int Instance::start()
pthread_mutex_unlock(&LOCK_instance);
- if (configured && !is_running())
+ if (configured && !is_mysqld_running())
{
Instance_monitor *instance_monitor;
remove_pid();
@@ -399,7 +584,7 @@ int Instance::start()
The method sets the crash flag and wakes all waiters on
COND_instance_stopped and COND_guardian
- SYNOPSYS
+ SYNOPSIS
set_crash_flag_n_wake_all()
DESCRIPTION
@@ -425,97 +610,14 @@ void Instance::set_crash_flag_n_wake_all()
*/
pthread_cond_signal(&COND_instance_stopped);
/* wake guardian */
- pthread_cond_signal(&instance_map->guardian->COND_guardian);
-}
-
-
-
-Instance::Instance(Thread_registry &thread_registry_arg):
- thread_registry(thread_registry_arg), crashed(FALSE), configured(FALSE)
-{
- pthread_mutex_init(&LOCK_instance, 0);
- pthread_cond_init(&COND_instance_stopped, 0);
-}
-
-
-Instance::~Instance()
-{
- pthread_cond_destroy(&COND_instance_stopped);
- pthread_mutex_destroy(&LOCK_instance);
-}
-
-
-bool Instance::is_crashed()
-{
- bool val;
- pthread_mutex_lock(&LOCK_instance);
- val= crashed;
- pthread_mutex_unlock(&LOCK_instance);
- return val;
-}
-
-
-bool Instance::is_running()
-{
- MYSQL mysql;
- uint port= 0;
- const char *socket= NULL;
- static const char *password= "check_connection";
- static const char *username= "MySQL_Instance_Manager";
- static const char *access_denied_message= "Access denied for user";
- bool return_val;
-
- if (options.mysqld_port)
- {
- /*
- NOTE: it is important to check mysqld_port here, but use
- mysqld_port_val. The idea is that if the option is unset, mysqld_port
- will be NULL, but mysqld_port_val will not be reset.
- */
- port= options.mysqld_port_val;
- }
-
- if (options.mysqld_socket)
- socket= options.mysqld_socket;
-
- /* no port was specified => instance falled back to default value */
- if (!options.mysqld_port && !options.mysqld_socket)
- port= SERVER_DEFAULT_PORT;
-
- pthread_mutex_lock(&LOCK_instance);
-
- mysql_init(&mysql);
- /* try to connect to a server with a fake username/password pair */
- if (mysql_real_connect(&mysql, LOCAL_HOST, username,
- password,
- NullS, port,
- socket, 0))
- {
- /*
- We have successfully connected to the server using fake
- username/password. Write a warning to the logfile.
- */
- log_info("The Instance Manager was able to log into you server "
- "with faked compiled-in password while checking server status. "
- "Looks like something is wrong.");
- pthread_mutex_unlock(&LOCK_instance);
- return_val= TRUE; /* server is alive */
- }
- else
- return_val= test(!strncmp(access_denied_message, mysql_error(&mysql),
- sizeof(access_denied_message) - 1));
-
- mysql_close(&mysql);
- pthread_mutex_unlock(&LOCK_instance);
-
- return return_val;
+ pthread_cond_signal(&Manager::get_guardian()->COND_guardian);
}
/*
Stop an instance.
- SYNOPSYS
+ SYNOPSIS
stop()
RETURN:
@@ -529,19 +631,11 @@ int Instance::stop()
struct timespec timeout;
uint waitchild= (uint) DEFAULT_SHUTDOWN_DELAY;
- if (is_running())
+ if (is_mysqld_running())
{
- if (options.shutdown_delay)
- {
- /*
- NOTE: it is important to check shutdown_delay here, but use
- shutdown_delay_val. The idea is that if the option is unset,
- shutdown_delay will be NULL, but shutdown_delay_val will not be reset.
- */
- waitchild= options.shutdown_delay_val;
- }
+ waitchild= options.get_shutdown_delay();
- kill_instance(SIGTERM);
+ kill_mysqld(SIGTERM);
/* sleep on condition to wait for SIGCHLD */
timeout.tv_sec= time(NULL) + waitchild;
@@ -549,7 +643,7 @@ int Instance::stop()
if (pthread_mutex_lock(&LOCK_instance))
return ER_STOP_INSTANCE;
- while (options.get_pid() != 0) /* while server isn't stopped */
+ while (options.load_pid() != 0) /* while server isn't stopped */
{
int status;
@@ -562,7 +656,7 @@ int Instance::stop()
pthread_mutex_unlock(&LOCK_instance);
- kill_instance(SIGKILL);
+ kill_mysqld(SIGKILL);
return 0;
}
@@ -570,120 +664,84 @@ int Instance::stop()
return ER_INSTANCE_IS_NOT_STARTED;
}
-#ifdef __WIN__
-BOOL SafeTerminateProcess(HANDLE hProcess, UINT uExitCode)
-{
- DWORD dwTID, dwCode, dwErr= 0;
- HANDLE hProcessDup= INVALID_HANDLE_VALUE;
- HANDLE hRT= NULL;
- HINSTANCE hKernel= GetModuleHandle("Kernel32");
- BOOL bSuccess= FALSE;
-
- BOOL bDup= DuplicateHandle(GetCurrentProcess(),
- hProcess, GetCurrentProcess(), &hProcessDup,
- PROCESS_ALL_ACCESS, FALSE, 0);
-
- // Detect the special case where the process is
- // already dead...
- if (GetExitCodeProcess((bDup) ? hProcessDup : hProcess, &dwCode) &&
- (dwCode == STILL_ACTIVE))
- {
- FARPROC pfnExitProc;
-
- pfnExitProc= GetProcAddress(hKernel, "ExitProcess");
+/*
+ Send signal to mysqld.
- hRT= CreateRemoteThread((bDup) ? hProcessDup : hProcess, NULL, 0,
- (LPTHREAD_START_ROUTINE)pfnExitProc,
- (PVOID)uExitCode, 0, &dwTID);
+ SYNOPSIS
+ kill_mysqld()
+*/
- if (hRT == NULL)
- dwErr= GetLastError();
- }
- else
- dwErr= ERROR_PROCESS_ABORTED;
+void Instance::kill_mysqld(int signum)
+{
+ pid_t mysqld_pid= options.load_pid();
- if (hRT)
+ if (mysqld_pid == 0)
{
- // Must wait process to terminate to
- // guarantee that it has exited...
- WaitForSingleObject((bDup) ? hProcessDup : hProcess, INFINITE);
-
- CloseHandle(hRT);
- bSuccess= TRUE;
+ log_info("Instance '%s': no pid file to send a signal (%d).",
+ (const char *) get_name()->str,
+ (int) signum);
+ return;
}
- if (bDup)
- CloseHandle(hProcessDup);
-
- if (!bSuccess)
- SetLastError(dwErr);
+ log_info("Instance '%s': sending %d to %d...",
+ (const char *) get_name()->str,
+ (int) signum,
+ (int) mysqld_pid);
- return bSuccess;
-}
-
-int kill(pid_t pid, int signum)
-{
- HANDLE processhandle= ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
- if (signum == SIGTERM)
- ::SafeTerminateProcess(processhandle, 0);
- else
- ::TerminateProcess(processhandle, -1);
- return 0;
-}
-#endif
+ if (kill(mysqld_pid, signum))
+ {
+ log_info("Instance '%s': kill() failed.",
+ (const char *) get_name()->str);
+ return;
+ }
-void Instance::kill_instance(int signum)
-{
- pid_t pid;
- /* if there are no pid, everything seems to be fine */
- if ((pid= options.get_pid()) != 0) /* get pid from pidfile */
+ /* Kill suceeded */
+ if (signum == SIGKILL) /* really killed instance with SIGKILL */
{
- if (kill(pid, signum) == 0)
- {
- /* Kill suceeded */
- if (signum == SIGKILL) /* really killed instance with SIGKILL */
- {
- log_error("The instance '%s' is being stopped forcibly. Normally"
- "it should not happen. Probably the instance has been"
- "hanging. You should also check your IM setup",
- (const char *) options.instance_name.str);
- /* After sucessful hard kill the pidfile need to be removed */
- options.unlink_pidfile();
- }
- }
+ log_error("The instance '%s' is being stopped forcibly. Normally"
+ "it should not happen. Probably the instance has been"
+ "hanging. You should also check your IM setup",
+ (const char *) options.instance_name.str);
+ /* After sucessful hard kill the pidfile need to be removed */
+ options.unlink_pidfile();
}
- return;
}
/*
- Initialize instance parameters.
+ Return crashed flag.
- SYNOPSYS
- Instance::init()
- name_arg name of the instance
+ SYNOPSIS
+ is_crashed()
- RETURN:
- 0 ok
- !0 error
+ RETURN
+ TRUE - mysqld crashed
+ FALSE - mysqld hasn't crashed yet
*/
-int Instance::init(const LEX_STRING *name_arg)
+bool Instance::is_crashed()
{
- mysqld_compatible= is_mysqld_compatible_name(name_arg);
-
- return options.init(name_arg);
+ bool val;
+ pthread_mutex_lock(&LOCK_instance);
+ val= crashed;
+ pthread_mutex_unlock(&LOCK_instance);
+ return val;
}
+/*
+ Remove pid file.
+*/
-int Instance::complete_initialization(Instance_map *instance_map_arg,
- const char *mysqld_path)
+void Instance::remove_pid()
{
- instance_map= instance_map_arg;
- configured= !options.complete_initialization(mysqld_path);
- return 0;
- /*
- TODO: return actual status (from
- Instance_options::complete_initialization()) here.
- */
+ int mysqld_pid= options.load_pid();
+
+ if (mysqld_pid == 0)
+ return;
+
+ if (options.unlink_pidfile())
+ {
+ log_error("Instance '%s': can not unlink pid file.",
+ (const char *) options.instance_name.str);
+ }
}
diff --git a/server-tools/instance-manager/instance.h b/server-tools/instance-manager/instance.h
index 329eaa68b1a..412d01acc46 100644
--- a/server-tools/instance-manager/instance.h
+++ b/server-tools/instance-manager/instance.h
@@ -88,21 +88,19 @@ public:
static bool is_mysqld_compatible_name(const LEX_STRING *name);
public:
- Instance(Thread_registry &thread_registry_arg);
+ Instance();
~Instance();
- int init(const LEX_STRING *name_arg);
- int complete_initialization(Instance_map *instance_map_arg,
- const char *mysqld_path);
+ bool init(const LEX_STRING *name_arg);
+ bool complete_initialization();
- bool is_running();
+ bool is_mysqld_running();
int start();
int stop();
/* send a signal to the instance */
- void kill_instance(int signo);
+ void kill_mysqld(int signo);
bool is_crashed();
void set_crash_flag_n_wake_all();
- Instance_map *get_map();
/*
The operation is intended to check if the instance is mysqld-compatible
@@ -121,7 +119,6 @@ public:
public:
enum { DEFAULT_SHUTDOWN_DELAY= 35 };
Instance_options options;
- Thread_registry &thread_registry;
private:
/* This attributes is a flag, specifies if the instance has been crashed. */
@@ -155,7 +152,6 @@ private:
stop in Instance::stop()
*/
pthread_cond_t COND_instance_stopped;
- Instance_map *instance_map;
void remove_pid();
};
diff --git a/server-tools/instance-manager/instance_map.cc b/server-tools/instance-manager/instance_map.cc
index f0fb8b9669e..e13101e8a49 100644
--- a/server-tools/instance-manager/instance_map.cc
+++ b/server-tools/instance-manager/instance_map.cc
@@ -63,7 +63,7 @@ static void delete_instance(void *u)
/*
The option handler to pass to the process_default_option_files finction.
- SYNOPSYS
+ SYNOPSIS
process_option()
ctx Handler context. Here it is an instance_map structure.
group_name The name of the group the option belongs to.
@@ -169,7 +169,7 @@ int Instance_map::process_one_option(const LEX_STRING *group,
if (!(instance= (Instance *) hash_search(&hash, (byte *) group->str,
group->length)))
{
- if (!(instance= new Instance(thread_registry)))
+ if (!(instance= new Instance()))
return 1;
if (instance->init(group) || add_instance(instance))
@@ -213,16 +213,13 @@ int Instance_map::process_one_option(const LEX_STRING *group,
}
-Instance_map::Instance_map(const char *default_mysqld_path_arg,
- Thread_registry &thread_registry_arg):
- mysqld_path(default_mysqld_path_arg),
- thread_registry(thread_registry_arg)
+Instance_map::Instance_map()
{
pthread_mutex_init(&LOCK_instance_map, 0);
}
-int Instance_map::init()
+bool Instance_map::init()
{
return hash_init(&hash, default_charset_info, START_HASH_SIZE, 0, 0,
get_instance_key, delete_instance, 0);
@@ -310,7 +307,7 @@ bool Instance_map::is_there_active_instance()
while ((instance= iterator.next()))
{
if (guardian->find_instance_node(instance) != NULL ||
- instance->is_running())
+ instance->is_mysqld_running())
{
return TRUE;
}
@@ -335,18 +332,18 @@ int Instance_map::remove_instance(Instance *instance)
int Instance_map::create_instance(const LEX_STRING *instance_name,
const Named_value_arr *options)
{
- Instance *instance= new Instance(thread_registry);
+ Instance *instance= new Instance();
if (!instance)
{
- log_error("Error: can not initialize (name: '%s').",
+ log_error("Error: can not allocate instance (name: '%s').",
(const char *) instance_name->str);
return ER_OUT_OF_RESOURCES;
}
if (instance->init(instance_name))
{
- log_error("Error: can not initialize (name: '%s').",
+ log_error("Error: can not initialize instance (name: '%s').",
(const char *) instance_name->str);
delete instance;
return ER_OUT_OF_RESOURCES;
@@ -374,7 +371,7 @@ int Instance_map::create_instance(const LEX_STRING *instance_name,
log_info("Warning: instance name '%s' is mysqld-compatible.",
(const char *) instance_name->str);
- if (instance->complete_initialization(this, mysqld_path))
+ if (instance->complete_initialization())
{
log_error("Error: can not complete initialization of instance (name: '%s').",
(const char *) instance_name->str);
@@ -411,7 +408,7 @@ bool Instance_map::complete_initialization()
{
Instance *instance= (Instance *) hash_element(&hash, i);
- if (instance->complete_initialization(this, mysqld_path))
+ if (instance->complete_initialization())
return TRUE;
}
@@ -543,14 +540,14 @@ const char *Instance_map::get_instance_state_name(Instance *instance)
/* The instance is not managed by Guardian: we can report status only. */
- return instance->is_running() ? "online" : "offline";
+ return instance->is_mysqld_running() ? "online" : "offline";
}
/*
Create a new configuration section for mysqld-instance in the config file.
- SYNOPSYS
+ SYNOPSIS
create_instance_in_file()
instance_name mysqld-instance name
options options for the new mysqld-instance
diff --git a/server-tools/instance-manager/instance_map.h b/server-tools/instance-manager/instance_map.h
index 48fc8edc5ad..69d225c89f7 100644
--- a/server-tools/instance-manager/instance_map.h
+++ b/server-tools/instance-manager/instance_map.h
@@ -75,7 +75,7 @@ public:
void lock();
void unlock();
- int init();
+ bool init();
/*
Process a given option and assign it to appropricate instance. This is
@@ -105,8 +105,7 @@ public:
int create_instance(const LEX_STRING *instance_name,
const Named_value_arr *options);
- Instance_map(const char *default_mysqld_path_arg,
- Thread_registry &thread_registry_arg);
+ Instance_map();
~Instance_map();
/*
@@ -132,8 +131,6 @@ private:
enum { START_HASH_SIZE = 16 };
pthread_mutex_t LOCK_instance_map;
HASH hash;
-
- Thread_registry &thread_registry;
};
#endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_INSTANCE_MAP_H */
diff --git a/server-tools/instance-manager/instance_options.cc b/server-tools/instance-manager/instance_options.cc
index 00da6660703..cbdf0a61258 100644
--- a/server-tools/instance-manager/instance_options.cc
+++ b/server-tools/instance-manager/instance_options.cc
@@ -29,6 +29,7 @@
#include "buffer.h"
#include "instance.h"
#include "log.h"
+#include "options.h"
#include "parse_output.h"
#include "priv.h"
@@ -82,8 +83,12 @@ bool Instance_options::is_option_im_specific(const char *option_name)
Instance_options::Instance_options()
:mysqld_version(NULL), mysqld_socket(NULL), mysqld_datadir(NULL),
- mysqld_pid_file(NULL), mysqld_port(NULL), mysqld_port_val(0),
- nonguarded(NULL), shutdown_delay(NULL), shutdown_delay_val(0),
+ mysqld_pid_file(NULL),
+ nonguarded(NULL),
+ mysqld_port(NULL),
+ mysqld_port_val(0),
+ shutdown_delay(NULL),
+ shutdown_delay_val(0),
filled_default_options(0)
{
mysqld_path.str= NULL;
@@ -99,7 +104,7 @@ Instance_options::Instance_options()
/*
Get compiled-in value of default_option
- SYNOPSYS
+ SYNOPSIS
get_default_option()
result buffer to put found value
result_len buffer size
@@ -139,7 +144,7 @@ err:
/*
Fill mysqld_version option (used at initialization stage)
- SYNOPSYS
+ SYNOPSIS
fill_instance_version()
DESCRIPTION
@@ -182,7 +187,7 @@ int Instance_options::fill_instance_version()
err:
if (rc)
log_error("fill_instance_version: Failed to get version of '%s'",
- mysqld_path.str);
+ (const char *) mysqld_path.str);
return rc;
}
@@ -190,7 +195,7 @@ err:
/*
Fill mysqld_real_path
- SYNOPSYS
+ SYNOPSIS
fill_mysqld_real_path()
DESCRIPTION
@@ -242,7 +247,7 @@ err:
/*
Fill various log options
- SYNOPSYS
+ SYNOPSIS
fill_log_options()
DESCRIPTION
@@ -355,7 +360,7 @@ err:
/*
Get the full pid file name with path
- SYNOPSYS
+ SYNOPSIS
get_pid_filaname()
result buffer to sotre the pidfile value
@@ -396,7 +401,7 @@ int Instance_options::unlink_pidfile()
}
-pid_t Instance_options::get_pid()
+pid_t Instance_options::load_pid()
{
FILE *pid_file_stream;
@@ -415,7 +420,7 @@ pid_t Instance_options::get_pid()
}
-int Instance_options::complete_initialization(const char *default_path)
+bool Instance_options::complete_initialization()
{
int arg_idx;
const char *tmp;
@@ -423,10 +428,14 @@ int Instance_options::complete_initialization(const char *default_path)
if (!mysqld_path.str)
{
- // Need one extra byte, as convert_dirname() adds a slash at the end.
- if (!(mysqld_path.str= alloc_root(&alloc, strlen(default_path) + 2)))
- goto err;
- strcpy(mysqld_path.str, default_path);
+ /* Need one extra byte, as convert_dirname() adds a slash at the end. */
+ mysqld_path.str= alloc_root(&alloc,
+ strlen(Options::Main::default_mysqld_path) + 2);
+
+ if (! mysqld_path.str)
+ return TRUE;
+
+ strcpy(mysqld_path.str, Options::Main::default_mysqld_path);
}
// it's safe to cast this to char* since this is a buffer we are allocating
@@ -442,7 +451,7 @@ int Instance_options::complete_initialization(const char *default_path)
shutdown_delay_val= atoi(shutdown_delay);
if (!(tmp= strdup_root(&alloc, "--no-defaults")))
- goto err;
+ return TRUE;
if (!mysqld_pid_file)
{
@@ -477,21 +486,21 @@ int Instance_options::complete_initialization(const char *default_path)
}
if (get_pid_filename(pid_file_with_path))
- goto err;
+ return TRUE;
/* we need to reserve space for the final zero + possible default options */
if (!(argv= (char**)
alloc_root(&alloc, (get_num_options() + 1
+ MAX_NUMBER_OF_DEFAULT_OPTIONS) * sizeof(char*))))
- goto err;
+ return TRUE;
filled_default_options= 0;
/* the path must be first in the argv */
if (add_to_argv(mysqld_path.str))
- goto err;
+ return TRUE;
if (add_to_argv(tmp))
- goto err;
+ return TRUE;
arg_idx= filled_default_options;
for (int opt_idx= 0; opt_idx < get_num_options(); ++opt_idx)
@@ -514,12 +523,9 @@ int Instance_options::complete_initialization(const char *default_path)
argv[arg_idx]= 0;
if (fill_log_options() || fill_mysqld_real_path() || fill_instance_version())
- goto err;
-
- return 0;
+ return TRUE;
-err:
- return 1;
+ return FALSE;
}
@@ -636,26 +642,26 @@ void Instance_options::print_argv()
/*
We execute this function to initialize some options.
- Return value: 0 - ok. 1 - unable to allocate memory.
+
+ RETURN
+ FALSE - ok
+ TRUE - memory allocation error
*/
-int Instance_options::init(const LEX_STRING *instance_name_arg)
+bool Instance_options::init(const LEX_STRING *instance_name_arg)
{
instance_name.length= instance_name_arg->length;
init_alloc_root(&alloc, MEM_ROOT_BLOCK_SIZE, 0);
if (options.init())
- goto err;
+ return TRUE;
if (!(instance_name.str= strmake_root(&alloc, instance_name_arg->str,
instance_name_arg->length)))
- goto err;
-
- return 0;
+ return TRUE;
-err:
- return 1;
+ return FALSE;
}
@@ -663,3 +669,29 @@ Instance_options::~Instance_options()
{
free_root(&alloc, MYF(0));
}
+
+
+uint Instance_options::get_shutdown_delay() const
+{
+ static const uint DEFAULT_SHUTDOWN_DELAY= 35;
+
+ /*
+ NOTE: it is important to check shutdown_delay here, but use
+ shutdown_delay_val. The idea is that if the option is unset,
+ shutdown_delay will be NULL, but shutdown_delay_val will not be reset.
+ */
+
+ return shutdown_delay ? shutdown_delay_val : DEFAULT_SHUTDOWN_DELAY;
+}
+
+int Instance_options::get_mysqld_port() const
+{
+ /*
+ NOTE: it is important to check mysqld_port here, but use mysqld_port_val.
+ The idea is that if the option is unset, mysqld_port will be NULL, but
+ mysqld_port_val will not be reset.
+ */
+
+ return mysqld_port ? mysqld_port_val : 0;
+}
+
diff --git a/server-tools/instance-manager/instance_options.h b/server-tools/instance-manager/instance_options.h
index c3b0a16a40d..b788faacb34 100644
--- a/server-tools/instance-manager/instance_options.h
+++ b/server-tools/instance-manager/instance_options.h
@@ -45,8 +45,9 @@ public:
public:
Instance_options();
~Instance_options();
+
/* fills in argv */
- int complete_initialization(const char *default_path);
+ bool complete_initialization();
bool set_option(Named_value *option);
void unset_option(const char *option_name);
@@ -55,12 +56,15 @@ public:
inline Named_value get_option(int idx) const;
public:
- int init(const LEX_STRING *instance_name_arg);
- pid_t get_pid();
+ bool init(const LEX_STRING *instance_name_arg);
+ pid_t load_pid();
int get_pid_filename(char *result);
int unlink_pidfile();
void print_argv();
+ uint get_shutdown_delay() const;
+ int get_mysqld_port() const;
+
public:
/*
We need this value to be greater or equal then FN_REFLEN found in
@@ -79,14 +83,10 @@ public:
const char *mysqld_socket;
const char *mysqld_datadir;
const char *mysqld_pid_file;
- const char *mysqld_port;
- uint mysqld_port_val;
LEX_STRING instance_name;
LEX_STRING mysqld_path;
LEX_STRING mysqld_real_path;
const char *nonguarded;
- const char *shutdown_delay;
- uint shutdown_delay_val;
/* log enums are defined in parse.h */
char *logs[3];
@@ -102,6 +102,11 @@ private:
int find_option(const char *option_name);
private:
+ const char *mysqld_port;
+ uint mysqld_port_val;
+ const char *shutdown_delay;
+ uint shutdown_delay_val;
+
uint filled_default_options;
MEM_ROOT alloc;
diff --git a/server-tools/instance-manager/listener.cc b/server-tools/instance-manager/listener.cc
index b749f234560..d5271175e9c 100644
--- a/server-tools/instance-manager/listener.cc
+++ b/server-tools/instance-manager/listener.cc
@@ -85,14 +85,7 @@ void Listener::run()
log_info("Listener: started.");
#ifndef __WIN__
- /* we use this var to check whether we are running on LinuxThreads */
- pid_t thread_pid;
-
- thread_pid= getpid();
-
struct sockaddr_un unix_socket_address;
- /* set global variable */
- linuxthreads= (thread_pid != manager_pid);
#endif
thread_registry->register_thread(&thread_info);
@@ -151,10 +144,12 @@ void Listener::run()
{
set_no_inherit(client_fd);
- Vio *vio= vio_new(client_fd, socket_index == 0 ?
- VIO_TYPE_SOCKET : VIO_TYPE_TCPIP,
- socket_index == 0 ? 1 : 0);
- if (vio != 0)
+ struct st_vio *vio=
+ vio_new(client_fd,
+ socket_index == 0 ? VIO_TYPE_SOCKET : VIO_TYPE_TCPIP,
+ socket_index == 0 ? 1 : 0);
+
+ if (vio != NULL)
handle_new_mysql_connection(vio);
else
{
@@ -318,12 +313,12 @@ create_unix_socket(struct sockaddr_un &unix_socket_address)
/*
Create new mysql connection. Created thread is responsible for deletion of
- the Mysql_connection_thread_args and Vio instances passed to it.
- SYNOPSYS
+ the Mysql_connection and Vio instances passed to it.
+ SYNOPSIS
handle_new_mysql_connection()
*/
-void Listener::handle_new_mysql_connection(Vio *vio)
+void Listener::handle_new_mysql_connection(struct st_vio *vio)
{
Mysql_connection *mysql_connection=
new Mysql_connection(thread_registry, user_map,
diff --git a/server-tools/instance-manager/log.cc b/server-tools/instance-manager/log.cc
index 7214cde7193..e3880caadd0 100644
--- a/server-tools/instance-manager/log.cc
+++ b/server-tools/instance-manager/log.cc
@@ -33,7 +33,7 @@
/*
Format log entry and write it to the given stream.
- SYNOPSYS
+ SYNOPSIS
log()
*/
diff --git a/server-tools/instance-manager/manager.cc b/server-tools/instance-manager/manager.cc
index 8c6bffa8d97..4fb4efef87e 100644
--- a/server-tools/instance-manager/manager.cc
+++ b/server-tools/instance-manager/manager.cc
@@ -93,17 +93,17 @@ int my_sigwait(const sigset_t *set, int *sig)
#endif
-void stop_all(Guardian *guardian, Thread_registry *registry)
+void Manager::stop_all_threads()
{
/*
Let guardian thread know that it should break it's processing cycle,
once it wakes up.
*/
- guardian->request_shutdown();
+ p_guardian->request_shutdown();
/* wake guardian */
- pthread_cond_signal(&guardian->COND_guardian);
+ pthread_cond_signal(&p_guardian->COND_guardian);
/* stop all threads */
- registry->deliver_shutdown();
+ p_thread_registry->deliver_shutdown();
}
/**********************************************************************
@@ -112,6 +112,9 @@ void stop_all(Guardian *guardian, Thread_registry *registry)
Guardian *Manager::p_guardian;
Instance_map *Manager::p_instance_map;
+Thread_registry *Manager::p_thread_registry;
+User_map *Manager::p_user_map;
+pid_t Manager::manager_pid;
/*
manager - entry point to the main instance manager process: start
@@ -137,8 +140,7 @@ int Manager::main()
*/
User_map user_map;
- Instance_map instance_map(Options::Main::default_mysqld_path,
- thread_registry);
+ Instance_map instance_map;
Guardian guardian(&thread_registry, &instance_map,
Options::Main::monitoring_interval);
@@ -147,6 +149,8 @@ int Manager::main()
manager_pid= getpid();
p_instance_map= &instance_map;
p_guardian= instance_map.guardian= &guardian;
+ p_thread_registry= &thread_registry;
+ p_user_map= &user_map;
/* Initialize instance map. */
@@ -199,14 +203,11 @@ int Manager::main()
NOTE: To work nicely with LinuxThreads, the signal thread is the first
thread in the process.
- NOTE:
- After init_thr_alarm() call it's possible to call thr_alarm() (from
- different threads), that results in sending ALARM signal to the alarm
- thread (which can be the main thread). That signal can interrupt
- blocking calls.
-
- In other words, a blocking call can be interrupted in the main thread
- after init_thr_alarm().
+ NOTE: After init_thr_alarm() call it's possible to call thr_alarm()
+ (from different threads), that results in sending ALARM signal to the
+ alarm thread (which can be the main thread). That signal can interrupt
+ blocking calls. In other words, a blocking call can be interrupted in
+ the main thread after init_thr_alarm().
*/
sigset_t mask;
@@ -230,11 +231,12 @@ int Manager::main()
*/
if (guardian.start_detached())
{
- log_error("manager(): Failed to create the guardian thread");
+ log_error("Error: can not start Guardian thread.");
goto err;
}
/* Load instances. */
+
{
instance_map.guardian->lock();
instance_map.lock();
@@ -246,19 +248,18 @@ int Manager::main()
if (flush_instances_status)
{
- log_error("Cannot init instances repository. This might be caused by "
- "the wrong config file options. For instance, missing mysqld "
- "binary. Aborting.");
- stop_all(&guardian, &thread_registry);
+ log_error("Error: can not init instances repository.");
+ stop_all_threads();
goto err;
}
}
- /* start the listener */
+ /* Initialize the Listener. */
+
if (listener.start_detached())
{
- log_error("manager(): set_stacksize_n_create_thread(listener) failed");
- stop_all(&guardian, &thread_registry);
+ log_error("Error: can not start Listener thread.");
+ stop_all_threads();
goto err;
}
@@ -268,7 +269,9 @@ int Manager::main()
*/
pthread_cond_signal(&guardian.COND_guardian);
- log_info("Main loop: started.");
+ /* Main loop. */
+
+ log_info("Manager: started.");
while (!shutdown_complete)
{
@@ -277,8 +280,8 @@ int Manager::main()
if ((status= my_sigwait(&mask, &signo)) != 0)
{
- log_error("sigwait() failed");
- stop_all(&guardian, &thread_registry);
+ log_error("Error: sigwait() failed");
+ stop_all_threads();
goto err;
}
@@ -304,7 +307,7 @@ int Manager::main()
Bug #14164 IM tests fail on MacOS X (powermacg5)
*/
#ifdef IGNORE_SIGHUP_SIGQUIT
- if ( SIGHUP == signo )
+ if (SIGHUP == signo)
continue;
#endif
if (THR_SERVER_ALARM == signo)
@@ -312,7 +315,7 @@ int Manager::main()
else
#endif
{
- log_info("Main loop: got shutdown signal.");
+ log_info("Manager: got shutdown signal.");
if (!guardian.is_stopped())
{
@@ -327,7 +330,7 @@ int Manager::main()
}
}
- log_info("Main loop: finished.");
+ log_info("Manager: finished.");
rc= 0;
diff --git a/server-tools/instance-manager/manager.h b/server-tools/instance-manager/manager.h
index 5abe029a3d8..1f2b2cf6926 100644
--- a/server-tools/instance-manager/manager.h
+++ b/server-tools/instance-manager/manager.h
@@ -19,9 +19,12 @@
#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
#pragma interface
#endif
+#include <my_global.h>
class Guardian;
class Instance_map;
+class Thread_registry;
+class User_map;
class Manager
{
@@ -33,12 +36,18 @@ public:
*/
static Instance_map *get_instance_map() { return p_instance_map; }
static Guardian *get_guardian() { return p_guardian; }
+ static Thread_registry *get_thread_registry() { return p_thread_registry; }
+ static User_map *get_user_map() { return p_user_map; }
+ static pid_t get_manager_pid() { return manager_pid; }
private:
- static int manager_impl();
+ static void stop_all_threads();
private:
+ static pid_t manager_pid;
static Guardian *p_guardian;
static Instance_map *p_instance_map;
+ static Thread_registry *p_thread_registry;
+ static User_map *p_user_map;
};
#endif // INCLUDES_MYSQL_INSTANCE_MANAGER_MANAGER_H
diff --git a/server-tools/instance-manager/mysqlmanager.cc b/server-tools/instance-manager/mysqlmanager.cc
index 475c7a3ab9f..e4cdedc0e0e 100644
--- a/server-tools/instance-manager/mysqlmanager.cc
+++ b/server-tools/instance-manager/mysqlmanager.cc
@@ -71,6 +71,7 @@ static void daemonize(const char *log_file_name);
static void angel();
static struct passwd *check_user(const char *user);
static int set_user(const char *user, struct passwd *user_info);
+static bool check_if_linuxthreads();
#endif
@@ -110,6 +111,9 @@ int main(int argc, char *argv[])
}
}
+ if (check_if_linuxthreads())
+ goto main_end; /* out of resources */
+
if (Options::Daemon::run_as_service)
{
/* forks, and returns only in child */
@@ -232,7 +236,7 @@ static void init_environment(char *progname)
#ifndef __WIN__
/*
Become a UNIX service
- SYNOPSYS
+ SYNOPSIS
daemonize()
*/
@@ -392,4 +396,27 @@ spawn:
}
}
+extern "C" {
+static void *check_if_linuxthreads_thread_func(void *arg)
+{
+ pid_t main_pid= *(pid_t*) arg;
+ linuxthreads= getpid() != main_pid;
+ return NULL;
+}
+} /* extern "C" */
+
+
+static bool check_if_linuxthreads()
+{
+ pid_t pid= getpid();
+ pthread_t thread_id;
+ int rc;
+
+ rc= pthread_create(&thread_id, NULL, check_if_linuxthreads_thread_func,
+ (void*) &pid);
+ if (rc == 0)
+ rc= pthread_join(thread_id, NULL);
+
+ return test(rc);
+}
#endif
diff --git a/server-tools/instance-manager/parse_output.cc b/server-tools/instance-manager/parse_output.cc
index 643a50625a1..9213de82e1d 100644
--- a/server-tools/instance-manager/parse_output.cc
+++ b/server-tools/instance-manager/parse_output.cc
@@ -43,7 +43,7 @@ void trim_space(const char **text, uint *word_len)
/*
Parse output of the given command
- SYNOPSYS
+ SYNOPSIS
parse_output_and_get_value()
command the command to execue with popen.
diff --git a/server-tools/instance-manager/priv.cc b/server-tools/instance-manager/priv.cc
index 934684a1a06..08af904a311 100644
--- a/server-tools/instance-manager/priv.cc
+++ b/server-tools/instance-manager/priv.cc
@@ -22,14 +22,13 @@
#include "log.h"
-/* the pid of the manager process (of the signal thread on the LinuxThreads) */
-pid_t manager_pid;
-
+#ifndef __WIN__
/*
This flag is set if mysqlmanager has detected that it is running on the
system using LinuxThreads
*/
bool linuxthreads;
+#endif
/*
The following string must be less then 80 characters, as
diff --git a/server-tools/instance-manager/priv.h b/server-tools/instance-manager/priv.h
index 7ac8ac73c6f..702769e0b07 100644
--- a/server-tools/instance-manager/priv.h
+++ b/server-tools/instance-manager/priv.h
@@ -50,9 +50,6 @@ const int MAX_VERSION_LENGTH= 160;
const int MAX_INSTANCE_NAME_SIZE= FN_REFLEN;
-/* the pid of the manager process (of the signal thread on the LinuxThreads) */
-extern pid_t manager_pid;
-
#ifndef __WIN__
/*
This flag is set if mysqlmanager has detected that it is running on the
diff --git a/server-tools/instance-manager/user_management_commands.cc b/server-tools/instance-manager/user_management_commands.cc
index 20ebeb0d6bf..a32a4e94415 100644
--- a/server-tools/instance-manager/user_management_commands.cc
+++ b/server-tools/instance-manager/user_management_commands.cc
@@ -20,7 +20,7 @@
This function must not be used in user-management command implementations.
Use get_user_name() instead.
- SYNOPSYS
+ SYNOPSIS
get_user_name_impl()
RETURN
@@ -58,7 +58,7 @@ static char *get_user_name_impl()
(not empty, not exceeds USERNAME_LENGTH). Report to stderr if something is
wrong.
- SYNOPSYS
+ SYNOPSIS
get_user_name()
user_name [OUT] on success contains user name
@@ -102,7 +102,7 @@ static bool get_user_name(LEX_STRING *user_name)
The password is retrieved from command-line options (if specified) or from
console.
- SYNOPSYS
+ SYNOPSIS
get_password()
RETURN
@@ -131,7 +131,7 @@ static const char *get_password()
/*
Load password file into user map.
- SYNOPSYS
+ SYNOPSIS
load_password_file()
user_map target user map
@@ -160,7 +160,7 @@ static int load_password_file(User_map *user_map)
/*
Save user map into password file.
- SYNOPSYS
+ SYNOPSIS
save_password_file()
user_map user map
diff --git a/server-tools/instance-manager/user_management_commands.h b/server-tools/instance-manager/user_management_commands.h
index 8d820be5ec7..343d967ec1e 100644
--- a/server-tools/instance-manager/user_management_commands.h
+++ b/server-tools/instance-manager/user_management_commands.h
@@ -49,7 +49,7 @@ public:
/*
Executes user-management command.
- SYNOPSYS
+ SYNOPSIS
execute()
RETURN
diff --git a/server-tools/instance-manager/user_map.cc b/server-tools/instance-manager/user_map.cc
index a90dd489c4e..bdc43bd8556 100644
--- a/server-tools/instance-manager/user_map.cc
+++ b/server-tools/instance-manager/user_map.cc
@@ -159,7 +159,7 @@ User_map::~User_map()
/*
Load password database.
- SYNOPSYS
+ SYNOPSIS
load()
password_file_name [IN] password file path
err_msg [OUT] error message