summaryrefslogtreecommitdiff
path: root/server-tools/instance-manager
diff options
context:
space:
mode:
Diffstat (limited to 'server-tools/instance-manager')
-rw-r--r--server-tools/instance-manager/buffer.cc9
-rw-r--r--server-tools/instance-manager/buffer.h4
-rw-r--r--server-tools/instance-manager/command.cc4
-rw-r--r--server-tools/instance-manager/command.h6
-rw-r--r--server-tools/instance-manager/commands.cc261
-rw-r--r--server-tools/instance-manager/commands.h23
-rw-r--r--server-tools/instance-manager/factory.cc12
-rw-r--r--server-tools/instance-manager/guardian.cc58
-rw-r--r--server-tools/instance-manager/guardian.h10
-rw-r--r--server-tools/instance-manager/instance.cc2
-rw-r--r--server-tools/instance-manager/instance_map.cc273
-rw-r--r--server-tools/instance-manager/instance_map.h25
-rw-r--r--server-tools/instance-manager/listener.cc7
-rw-r--r--server-tools/instance-manager/manager.cc2
-rw-r--r--server-tools/instance-manager/mysql_connection.cc4
-rw-r--r--server-tools/instance-manager/protocol.cc6
16 files changed, 401 insertions, 305 deletions
diff --git a/server-tools/instance-manager/buffer.cc b/server-tools/instance-manager/buffer.cc
index 66267e4af18..212260bf9e0 100644
--- a/server-tools/instance-manager/buffer.cc
+++ b/server-tools/instance-manager/buffer.cc
@@ -27,7 +27,7 @@
SYNOPSYS
append()
- position start position in the buffer
+ position start position in the buffer
string string to be put in the buffer
len_arg the length of the string. This way we can avoid some
strlens.
@@ -43,12 +43,12 @@
1 - The buffer came to 16Mb barrier
*/
-int Buffer::append(char *position, const char *string, uint len_arg)
+int Buffer::append(uint position, const char *string, uint len_arg)
{
- if (reserve(position - buffer, len_arg))
+ if (reserve(position, len_arg))
return 1;
- strnmov(position, string, len_arg);
+ strnmov(buffer + position, string, len_arg);
return 0;
}
@@ -89,3 +89,4 @@ int Buffer::reserve(uint position, uint len_arg)
}
return 0;
}
+
diff --git a/server-tools/instance-manager/buffer.h b/server-tools/instance-manager/buffer.h
index dbf72e34bf0..66860bd67b5 100644
--- a/server-tools/instance-manager/buffer.h
+++ b/server-tools/instance-manager/buffer.h
@@ -35,7 +35,7 @@ private:
enum { BUFFER_INITIAL_SIZE= 4096 };
/* maximum buffer size is 16Mb */
enum { MAX_BUFFER_SIZE= 16777216 };
- uint buffer_size;
+ size_t buffer_size;
public:
Buffer()
{
@@ -50,7 +50,7 @@ public:
public:
char *buffer;
- int append(char *start_pos, const char *string, uint len_arg);
+ int append(uint position, const char *string, uint len_arg);
int reserve(uint position, uint len_arg);
};
diff --git a/server-tools/instance-manager/command.cc b/server-tools/instance-manager/command.cc
index 87260f9e17b..9f7d08d9fda 100644
--- a/server-tools/instance-manager/command.cc
+++ b/server-tools/instance-manager/command.cc
@@ -21,8 +21,8 @@
#include "command.h"
-Command::Command(Command_factory *factory_arg)
- :factory(factory_arg)
+Command::Command(Instance_map *imap_arg)
+ :instance_map(imap_arg)
{}
Command::~Command()
diff --git a/server-tools/instance-manager/command.h b/server-tools/instance-manager/command.h
index 9b981ecd163..8ae4e33b92f 100644
--- a/server-tools/instance-manager/command.h
+++ b/server-tools/instance-manager/command.h
@@ -24,7 +24,7 @@
/* Class responsible for allocation of im commands. */
-class Command_factory;
+class Instance_map;
/*
Command - entry point for any command.
@@ -34,14 +34,14 @@ class Command_factory;
class Command
{
public:
- Command(Command_factory *factory_arg= 0);
+ Command(Instance_map *instance_map_arg= 0);
virtual ~Command();
/* method of executing: */
virtual int execute(struct st_net *net, ulong connection_id) = 0;
protected:
- Command_factory *factory;
+ Instance_map *instance_map;
};
#endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_COMMAND_H */
diff --git a/server-tools/instance-manager/commands.cc b/server-tools/instance-manager/commands.cc
index 30d8f0794a0..357b9a47d4d 100644
--- a/server-tools/instance-manager/commands.cc
+++ b/server-tools/instance-manager/commands.cc
@@ -15,18 +15,81 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "command.h"
-#include "factory.h"
#include "commands.h"
#include "instance.h"
#include "instance_map.h"
#include "messages.h"
+#include "protocol.h"
+#include "buffer.h"
+#include <m_string.h>
/* implementation for Show_instances: */
+
+/*
+ The method sends a list of instances in the instance map to the client.
+
+ SYNOPSYS
+ Show_instances::do_command()
+ net The network connection to the client.
+
+ RETURN
+ 0 - ok
+ 1 - error occured
+*/
+
+int Show_instances::do_command(struct st_net *net)
+{
+ Buffer send_buff; /* buffer for packets */
+ LIST name, status;
+ NAME_WITH_LENGTH name_field, status_field;
+ LIST *field_list;
+ uint position=0;
+
+ name_field.name= (char *) "instance_name";
+ name_field.length= 20;
+ name.data= &name_field;
+ status_field.name= (char *) "status";
+ status_field.length= 20;
+ status.data= &status_field;
+ field_list= list_add(NULL, &status);
+ field_list= list_add(field_list, &name);
+
+ send_fields(net, field_list);
+
+ {
+ Instance *instance;
+ Imap_iterator iterator(instance_map);
+
+ instance_map->lock();
+ while (instance= iterator.next())
+ {
+ position= 0;
+ store_to_string(&send_buff, instance->options.instance_name, &position);
+ if (instance->is_running())
+ store_to_string(&send_buff, (char *) "online", &position);
+ else
+ store_to_string(&send_buff, (char *) "offline", &position);
+ if (my_net_write(net, send_buff.buffer, (uint) position))
+ goto err;
+ }
+ instance_map->unlock();
+ }
+ if (send_eof(net))
+ goto err;
+ if (net_flush(net))
+ goto err;
+
+ return 0;
+err:
+ return 1;
+}
+
+
int Show_instances::execute(struct st_net *net, ulong connection_id)
{
- if (factory->instance_map.show_instances(net))
+ if (do_command(net))
return ER_OUT_OF_RESOURCES;
return 0;
@@ -37,7 +100,7 @@ int Show_instances::execute(struct st_net *net, ulong connection_id)
int Flush_instances::execute(struct st_net *net, ulong connection_id)
{
- if (factory->instance_map.flush_instances())
+ if (instance_map->flush_instances())
return ER_OUT_OF_RESOURCES;
net_send_ok(net, connection_id);
@@ -47,14 +110,14 @@ int Flush_instances::execute(struct st_net *net, ulong connection_id)
/* implementation for Show_instance_status: */
-Show_instance_status::Show_instance_status(Command_factory *factory,
+Show_instance_status::Show_instance_status(Instance_map *imap_arg,
const char *name, uint len)
- :Command(factory)
+ :Command(imap_arg)
{
Instance *instance;
/* we make a search here, since we don't want t store the name */
- if (instance= factory->instance_map.find(name, len))
+ if (instance= instance_map->find(name, len))
{
instance_name= instance->options.instance_name;
}
@@ -63,11 +126,80 @@ Show_instance_status::Show_instance_status(Command_factory *factory,
}
+/*
+ The method sends a table with a status of requested instance to the client.
+
+ SYNOPSYS
+ Show_instance_status::do_command()
+ net The network connection to the client.
+ instance_name The name of the instance.
+
+ RETURN
+ 0 - ok
+ 1 - error occured
+*/
+
+
+int Show_instance_status::do_command(struct st_net *net,
+ const char *instance_name)
+{
+ enum { MAX_VERSION_LENGTH= 40 };
+ Buffer send_buff; /* buffer for packets */
+ LIST name, status, version;
+ LIST *field_list;
+ NAME_WITH_LENGTH name_field, status_field, version_field;
+ uint position=0;
+
+ /* create list of the fileds to be passed to send_fields */
+ name_field.name= (char *) "instance_name";
+ name_field.length= 20;
+ name.data= &name_field;
+ status_field.name= (char *) "status";
+ status_field.length= 20;
+ status.data= &status_field;
+ version_field.name= (char *) "version";
+ version_field.length= MAX_VERSION_LENGTH;
+ version.data= &version_field;
+ field_list= list_add(NULL, &version);
+ field_list= list_add(field_list, &status);
+ field_list= list_add(field_list, &name);
+
+ send_fields(net, field_list);
+
+ {
+ Instance *instance;
+
+ store_to_string(&send_buff, (char *) instance_name, &position);
+ if ((instance= instance_map->find(instance_name, strlen(instance_name))) == NULL)
+ goto err;
+ if (instance->is_running())
+ {
+ store_to_string(&send_buff, (char *) "online", &position);
+ store_to_string(&send_buff, mysql_get_server_info(&(instance->mysql)), &position);
+ }
+ else
+ {
+ store_to_string(&send_buff, (char *) "offline", &position);
+ store_to_string(&send_buff, (char *) "unknown", &position);
+ }
+
+
+ my_net_write(net, send_buff.buffer, (uint) position);
+ }
+
+ send_eof(net);
+ net_flush(net);
+
+err:
+ return 0;
+}
+
+
int Show_instance_status::execute(struct st_net *net, ulong connection_id)
{
if (instance_name != NULL)
{
- if (factory->instance_map.show_instance_status(net, instance_name))
+ if (do_command(net, instance_name))
return ER_OUT_OF_RESOURCES;
return 0;
}
@@ -80,14 +212,14 @@ int Show_instance_status::execute(struct st_net *net, ulong connection_id)
/* Implementation for Show_instance_options */
-Show_instance_options::Show_instance_options(Command_factory *factory,
+Show_instance_options::Show_instance_options(Instance_map *imap_arg,
const char *name, uint len):
- Command(factory)
+ Command(imap_arg)
{
Instance *instance;
/* we make a search here, since we don't want t store the name */
- if (instance= (factory->instance_map).find(name, len))
+ if (instance= instance_map->find(name, len))
{
instance_name= instance->options.instance_name;
}
@@ -96,11 +228,99 @@ Show_instance_options::Show_instance_options(Command_factory *factory,
}
+int Show_instance_options::do_command(struct st_net *net,
+ const char *instance_name)
+{
+ enum { MAX_VERSION_LENGTH= 40 };
+ Buffer send_buff; /* buffer for packets */
+ LIST name, option;
+ LIST *field_list;
+ NAME_WITH_LENGTH name_field, option_field;
+ uint position=0;
+
+ /* create list of the fileds to be passed to send_fields */
+ name_field.name= (char *) "option_name";
+ name_field.length= 20;
+ name.data= &name_field;
+ option_field.name= (char *) "value";
+ option_field.length= 20;
+ option.data= &option_field;
+ field_list= list_add(NULL, &option);
+ field_list= list_add(field_list, &name);
+
+ send_fields(net, field_list);
+
+ {
+ Instance *instance;
+
+ if ((instance= instance_map->
+ find(instance_name, strlen(instance_name))) == NULL)
+ goto err;
+ store_to_string(&send_buff, (char *) "instance_name", &position);
+ store_to_string(&send_buff, (char *) instance_name, &position);
+ my_net_write(net, send_buff.buffer, (uint) position);
+ if (instance->options.mysqld_path != NULL)
+ {
+ position= 0;
+ store_to_string(&send_buff, (char *) "mysqld_path", &position);
+ store_to_string(&send_buff,
+ (char *) instance->options.mysqld_path,
+ &position);
+ my_net_write(net, send_buff.buffer, (uint) position);
+ }
+
+ if (instance->options.mysqld_user != NULL)
+ {
+ position= 0;
+ store_to_string(&send_buff, (char *) "admin_user", &position);
+ store_to_string(&send_buff,
+ (char *) instance->options.mysqld_user,
+ &position);
+ my_net_write(net, send_buff.buffer, (uint) position);
+ }
+
+ if (instance->options.mysqld_password != NULL)
+ {
+ position= 0;
+ store_to_string(&send_buff, (char *) "admin_password", &position);
+ store_to_string(&send_buff,
+ (char *) instance->options.mysqld_password,
+ &position);
+ my_net_write(net, send_buff.buffer, (uint) position);
+ }
+
+ /* loop through the options stored in DYNAMIC_ARRAY */
+ for (int i= 0; i < instance->options.options_array.elements; i++)
+ {
+ char *tmp_option, *option_value;
+ get_dynamic(&(instance->options.options_array), (gptr) &tmp_option, i);
+ option_value= strchr(tmp_option, '=');
+ /* split the option string into two parts */
+ *option_value= 0;
+ position= 0;
+ store_to_string(&send_buff, tmp_option + 2, &position);
+ store_to_string(&send_buff, option_value + 1, &position);
+ /* join name and the value into the same option again */
+ *option_value= '=';
+ my_net_write(net, send_buff.buffer, (uint) position);
+ }
+ }
+
+ send_eof(net);
+ net_flush(net);
+
+ return 0;
+
+err:
+ return 1;
+}
+
+
int Show_instance_options::execute(struct st_net *net, ulong connection_id)
{
if (instance_name != NULL)
{
- if (factory->instance_map.show_instance_options(net, instance_name))
+ if (do_command(net, instance_name))
return ER_OUT_OF_RESOURCES;
return 0;
}
@@ -113,12 +333,12 @@ int Show_instance_options::execute(struct st_net *net, ulong connection_id)
/* Implementation for Start_instance */
-Start_instance::Start_instance(Command_factory *factory,
+Start_instance::Start_instance(Instance_map *imap_arg,
const char *name, uint len)
- :Command(factory)
+ :Command(imap_arg)
{
/* we make a search here, since we don't want t store the name */
- if (instance= factory->instance_map.find(name, len))
+ if (instance= instance_map->find(name, len))
instance_name= instance->options.instance_name;
}
@@ -136,8 +356,7 @@ int Start_instance::execute(struct st_net *net, ulong connection_id)
return err_code;
if (instance->options.is_guarded != NULL)
- factory->instance_map.guardian->guard(instance->options.instance_name,
- instance->options.instance_name_len);
+ instance_map->guardian->guard(instance);
net_send_ok(net, connection_id);
return 0;
@@ -147,12 +366,12 @@ int Start_instance::execute(struct st_net *net, ulong connection_id)
/* Implementation for Stop_instance: */
-Stop_instance::Stop_instance(Command_factory *factory,
+Stop_instance::Stop_instance(Instance_map *imap_arg,
const char *name, uint len)
- :Command(factory)
+ :Command(imap_arg)
{
/* we make a search here, since we don't want t store the name */
- if (instance= factory->instance_map.find(name, len))
+ if (instance= instance_map->find(name, len))
instance_name= instance->options.instance_name;
}
@@ -168,8 +387,8 @@ int Stop_instance::execute(struct st_net *net, ulong connection_id)
else
{
if (instance->options.is_guarded != NULL)
- factory->instance_map.guardian->
- stop_guard(instance_name, instance->options.instance_name_len);
+ instance_map->guardian->
+ stop_guard(instance);
if (err_code= instance->stop())
return err_code;
diff --git a/server-tools/instance-manager/commands.h b/server-tools/instance-manager/commands.h
index 09df4fc9260..8b53b21bbac 100644
--- a/server-tools/instance-manager/commands.h
+++ b/server-tools/instance-manager/commands.h
@@ -27,9 +27,10 @@
class Show_instances : public Command
{
public:
- Show_instances(Command_factory *factory): Command(factory)
+ Show_instances(Instance_map *imap_arg): Command(imap_arg)
{}
+ int do_command(struct st_net *net);
int execute(struct st_net *net, ulong connection_id);
};
@@ -42,7 +43,7 @@ public:
class Flush_instances : public Command
{
public:
- Flush_instances(Command_factory *factory): Command(factory)
+ Flush_instances(Instance_map *imap_arg): Command(imap_arg)
{}
int execute(struct st_net *net, ulong connection_id);
@@ -58,8 +59,8 @@ class Show_instance_status : public Command
{
public:
- Show_instance_status(Command_factory *factory, const char *name, uint len);
-
+ Show_instance_status(Instance_map *imap_arg, const char *name, uint len);
+ int do_command(struct st_net *net, const char *instance_name);
int execute(struct st_net *net, ulong connection_id);
const char *instance_name;
};
@@ -74,9 +75,10 @@ class Show_instance_options : public Command
{
public:
- Show_instance_options(Command_factory *factory, const char *name, uint len);
+ Show_instance_options(Instance_map *imap_arg, const char *name, uint len);
int execute(struct st_net *net, ulong connection_id);
+ int do_command(struct st_net *net, const char *instance_name);
const char *instance_name;
};
@@ -89,11 +91,11 @@ public:
class Start_instance : public Command
{
public:
- Start_instance(Command_factory *factory, const char *name, uint len);
+ Start_instance(Instance_map *imap_arg, const char *name, uint len);
- Instance *instance;
int execute(struct st_net *net, ulong connection_id);
const char *instance_name;
+ Instance *instance;
};
@@ -105,7 +107,7 @@ public:
class Stop_instance : public Command
{
public:
- Stop_instance(Command_factory *factory, const char *name, uint len);
+ Stop_instance(Instance_map *imap_arg, const char *name, uint len);
Instance *instance;
int execute(struct st_net *net, ulong connection_id);
@@ -114,7 +116,10 @@ public:
/*
- Syntax error command.
+ Syntax error command. This command is issued if parser reported a syntax error.
+ We need it to distinguish the parse error and the situation when parser internal
+ error occured. E.g. parsing failed because we hadn't had enought memory. In the
+ latter case parse_command() should return an error.
*/
class Syntax_error : public Command
diff --git a/server-tools/instance-manager/factory.cc b/server-tools/instance-manager/factory.cc
index 691aca0c7ea..cde5d0564aa 100644
--- a/server-tools/instance-manager/factory.cc
+++ b/server-tools/instance-manager/factory.cc
@@ -23,35 +23,35 @@
Show_instances *Command_factory::new_Show_instances()
{
- return new Show_instances(this);
+ return new Show_instances(&instance_map);
}
Flush_instances *Command_factory::new_Flush_instances()
{
- return new Flush_instances(this);
+ 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(this, name, 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(this, name, 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(this, name, 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(this, name, len);
+ return new Stop_instance(&instance_map, name, len);
}
Syntax_error *Command_factory::new_Syntax_error()
diff --git a/server-tools/instance-manager/guardian.cc b/server-tools/instance-manager/guardian.cc
index f13b98cbf20..5a4d0bade74 100644
--- a/server-tools/instance-manager/guardian.cc
+++ b/server-tools/instance-manager/guardian.cc
@@ -21,6 +21,8 @@
#include "guardian.h"
#include "instance_map.h"
+#include "mysql_manager_error.h"
+#include "log.h"
#include <string.h>
C_MODE_START
@@ -46,6 +48,7 @@ Guardian_thread::Guardian_thread(Thread_registry &thread_registry_arg,
thread_registry.register_thread(&thread_info);
init_alloc_root(&alloc, MEM_ROOT_BLOCK_SIZE, 0);
guarded_instances= NULL;
+ starting_instances= NULL;
}
@@ -76,7 +79,6 @@ void Guardian_thread::run()
{
Instance *instance;
LIST *loop;
- int i= 0;
my_thread_init();
@@ -88,9 +90,12 @@ void Guardian_thread::run()
{
instance= (Instance *) loop->data;
/* instance-> start already checks whether instance is running */
- instance->start();
+ if (instance->start() != ER_INSTANCE_ALREADY_STARTED)
+ log_info("guardian attempted to restart instance %s",
+ instance->options.instance_name);
loop= loop->next;
}
+ move_to_list(&starting_instances, &guarded_instances);
pthread_mutex_unlock(&LOCK_guardian);
sleep(monitoring_interval);
}
@@ -99,6 +104,24 @@ void Guardian_thread::run()
}
+int Guardian_thread::start()
+{
+ Instance *instance;
+ Imap_iterator iterator(instance_map);
+
+ instance_map->lock();
+ while (instance= iterator.next())
+ {
+ if ((instance->options.is_guarded != NULL) && (instance->is_running()))
+ if (guard(instance))
+ return 1;
+ }
+ instance_map->unlock();
+
+ return 0;
+}
+
+
/*
Start instance guarding
@@ -116,20 +139,38 @@ void Guardian_thread::run()
1 - error occured
*/
-int Guardian_thread::guard(const char *instance_name, uint name_len)
+
+int Guardian_thread::guard(Instance *instance)
+{
+ return add_instance_to_list(instance, &starting_instances);
+}
+
+
+void Guardian_thread::move_to_list(LIST **from, LIST **to)
+{
+ LIST *tmp;
+
+ while (*from)
+ {
+ tmp= rest(*from);
+ *to= list_add(*to, *from);
+ *from= tmp;
+ }
+}
+
+
+int Guardian_thread::add_instance_to_list(Instance *instance, LIST **list)
{
LIST *node;
- Instance *instance;
node= (LIST *) alloc_root(&alloc, sizeof(LIST));
if (node == NULL)
return 1;
- instance= instance_map->find(instance_name, name_len);
/* we store the pointers to instances from the instance_map's MEM_ROOT */
node->data= (void *) instance;
pthread_mutex_lock(&LOCK_guardian);
- guarded_instances= list_add(guarded_instances, node);
+ *list= list_add(*list, node);
pthread_mutex_unlock(&LOCK_guardian);
return 0;
@@ -143,12 +184,9 @@ int Guardian_thread::guard(const char *instance_name, uint name_len)
a piece of the MEM_ROOT).
*/
-int Guardian_thread::stop_guard(const char *instance_name, uint name_len)
+int Guardian_thread::stop_guard(Instance *instance)
{
LIST *node;
- Instance *instance;
-
- instance= instance_map->find(instance_name, name_len);
pthread_mutex_lock(&LOCK_guardian);
node= guarded_instances;
diff --git a/server-tools/instance-manager/guardian.h b/server-tools/instance-manager/guardian.h
index 5d0cdcd7c92..0ae2161f1dc 100644
--- a/server-tools/instance-manager/guardian.h
+++ b/server-tools/instance-manager/guardian.h
@@ -66,13 +66,19 @@ public:
~Guardian_thread();
void run();
int init();
- int guard(const char *instance_name, uint name_len);
- int stop_guard(const char *instance_name, uint name_len);
+ int start();
+ int guard(Instance *instance);
+ int stop_guard(Instance *instance);
+
+private:
+ int add_instance_to_list(Instance *instance, LIST **list);
+ void move_to_list(LIST **from, LIST **to);
private:
pthread_mutex_t LOCK_guardian;
Thread_info thread_info;
LIST *guarded_instances;
+ LIST *starting_instances;
MEM_ROOT alloc;
enum { MEM_ROOT_BLOCK_SIZE= 512 };
};
diff --git a/server-tools/instance-manager/instance.cc b/server-tools/instance-manager/instance.cc
index 689cea2d786..1b9ce09d782 100644
--- a/server-tools/instance-manager/instance.cc
+++ b/server-tools/instance-manager/instance.cc
@@ -20,6 +20,7 @@
#include "instance.h"
#include "mysql_manager_error.h"
+#include "log.h"
#include <my_sys.h>
#include <signal.h>
#include <m_string.h>
@@ -43,6 +44,7 @@ int Instance::start()
if (!is_running())
{
+ log_info("trying to start instance %s", options.instance_name);
switch (fork()) {
case 0:
if (fork()) /* zombie protection */
diff --git a/server-tools/instance-manager/instance_map.cc b/server-tools/instance-manager/instance_map.cc
index 89731eb27b9..aa81194b1d4 100644
--- a/server-tools/instance-manager/instance_map.cc
+++ b/server-tools/instance-manager/instance_map.cc
@@ -127,253 +127,29 @@ Instance_map::~Instance_map()
}
-int Instance_map::flush_instances()
+int Instance_map::lock()
{
- int rc;
-
pthread_mutex_lock(&LOCK_instance_map);
- hash_free(&hash);
- hash_init(&hash, default_charset_info, START_HASH_SIZE, 0, 0,
- get_instance_key, delete_instance, 0);
- rc= load();
- pthread_mutex_unlock(&LOCK_instance_map);
- return rc;
}
-int Instance_map::show_instance_options(struct st_net *net,
- const char *instance_name)
+int Instance_map::unlock()
{
- enum { MAX_VERSION_LENGTH= 40 };
- Buffer send_buff; /* buffer for packets */
- LIST name, option;
- LIST *field_list;
- NAME_WITH_LENGTH name_field, option_field;
- uint position=0;
-
- /* create list of the fileds to be passed to send_fields */
- name_field.name= (char *) "option_name";
- name_field.length= 20;
- name.data= &name_field;
- option_field.name= (char *) "value";
- option_field.length= 20;
- option.data= &option_field;
- field_list= list_add(NULL, &option);
- field_list= list_add(field_list, &name);
-
- send_fields(net, field_list);
-
- {
- Instance *instance;
-
- if ((instance= find(instance_name, strlen(instance_name))) == NULL)
- goto err;
- store_to_string(&send_buff, (char *) "instance_name", &position);
- store_to_string(&send_buff, (char *) instance_name, &position);
- my_net_write(net, send_buff.buffer, (uint) position);
- if (instance->options.mysqld_path != NULL)
- {
- position= 0;
- store_to_string(&send_buff, (char *) "mysqld_path", &position);
- store_to_string(&send_buff,
- (char *) instance->options.mysqld_path,
- &position);
- my_net_write(net, send_buff.buffer, (uint) position);
- }
-
- if (instance->options.mysqld_user != NULL)
- {
- position= 0;
- store_to_string(&send_buff, (char *) "admin_user", &position);
- store_to_string(&send_buff,
- (char *) instance->options.mysqld_user,
- &position);
- my_net_write(net, send_buff.buffer, (uint) position);
- }
-
- if (instance->options.mysqld_password != NULL)
- {
- position= 0;
- store_to_string(&send_buff, (char *) "admin_password", &position);
- store_to_string(&send_buff,
- (char *) instance->options.mysqld_password,
- &position);
- my_net_write(net, send_buff.buffer, (uint) position);
- }
-
- /* loop through the options stored in DYNAMIC_ARRAY */
- for (int i= 0; i < instance->options.options_array.elements; i++)
- {
- char *tmp_option, *option_value;
- get_dynamic(&(instance->options.options_array), (gptr) &tmp_option, i);
- option_value= strchr(tmp_option, '=');
- /* split the option string into two parts */
- *option_value= 0;
- position= 0;
- store_to_string(&send_buff, tmp_option + 2, &position);
- store_to_string(&send_buff, option_value + 1, &position);
- /* join name and the value into the same option again */
- *option_value= '=';
- my_net_write(net, send_buff.buffer, (uint) position);
- }
- }
-
- send_eof(net);
- net_flush(net);
-
- return 0;
-
-err:
- return 1;
-}
-
-/* return the list of running guarded instances */
-int Instance_map::init_guardian()
-{
- Instance *instance;
- uint i= 0;
-
- while (i < hash.records)
- {
- instance= (Instance *) hash_element(&hash, i);
- if ((instance->options.is_guarded != NULL) && (instance->is_running()))
- if (guardian->guard(instance->options.instance_name,
- instance->options.instance_name_len))
- return 1;
- i++;
- }
-
- return 0;
-}
-
-
-/*
- The method sends a list of instances in the instance map to the client.
-
- SYNOPSYS
- show_instances()
- net The network connection to the client.
-
- RETURN
- 0 - ok
- 1 - error occured
-*/
-
-int Instance_map::show_instances(struct st_net *net)
-{
- Buffer send_buff; /* buffer for packets */
- LIST name, status;
- NAME_WITH_LENGTH name_field, status_field;
- LIST *field_list;
- uint position=0;
-
- name_field.name= (char *) "instance_name";
- name_field.length= 20;
- name.data= &name_field;
- status_field.name= (char *) "status";
- status_field.length= 20;
- status.data= &status_field;
- field_list= list_add(NULL, &status);
- field_list= list_add(field_list, &name);
-
- send_fields(net, field_list);
-
- {
- Instance *instance;
- uint i= 0;
-
- pthread_mutex_lock(&LOCK_instance_map);
- while (i < hash.records)
- {
- position= 0;
- instance= (Instance *) hash_element(&hash, i);
- store_to_string(&send_buff, instance->options.instance_name, &position);
- if (instance->is_running())
- store_to_string(&send_buff, (char *) "online", &position);
- else
- store_to_string(&send_buff, (char *) "offline", &position);
- if (my_net_write(net, send_buff.buffer, (uint) position))
- goto err;
- i++;
- }
- pthread_mutex_unlock(&LOCK_instance_map);
- }
- if (send_eof(net))
- goto err;
- if (net_flush(net))
- goto err;
-
- return 0;
-err:
- return 1;
+ pthread_mutex_unlock(&LOCK_instance_map);
}
-/*
- The method sends a table with a status of requested instance to the client.
-
- SYNOPSYS
- show_instance_status()
- net The network connection to the client.
- instance_name The name of the instance.
-
- RETURN
- 0 - ok
- 1 - error occured
-*/
-
-int Instance_map::show_instance_status(struct st_net *net,
- const char *instance_name)
+int Instance_map::flush_instances()
{
- enum { MAX_VERSION_LENGTH= 40 };
- Buffer send_buff; /* buffer for packets */
- LIST name, status, version;
- LIST *field_list;
- NAME_WITH_LENGTH name_field, status_field, version_field;
- uint position=0;
-
- /* create list of the fileds to be passed to send_fields */
- name_field.name= (char *) "instance_name";
- name_field.length= 20;
- name.data= &name_field;
- status_field.name= (char *) "status";
- status_field.length= 20;
- status.data= &status_field;
- version_field.name= (char *) "version";
- version_field.length= MAX_VERSION_LENGTH;
- version.data= &version_field;
- field_list= list_add(NULL, &version);
- field_list= list_add(field_list, &status);
- field_list= list_add(field_list, &name);
-
- send_fields(net, field_list);
-
- {
- Instance *instance;
-
- store_to_string(&send_buff, (char *) instance_name, &position);
- if ((instance= find(instance_name, strlen(instance_name))) == NULL)
- goto err;
- if (instance->is_running())
- {
- store_to_string(&send_buff, (char *) "online", &position);
- store_to_string(&send_buff, mysql_get_server_info(&(instance->mysql)), &position);
- }
- else
- {
- store_to_string(&send_buff, (char *) "offline", &position);
- store_to_string(&send_buff, (char *) "unknown", &position);
- }
-
-
- my_net_write(net, send_buff.buffer, (uint) position);
- }
-
- send_eof(net);
- net_flush(net);
+ int rc;
-err:
- return 0;
+ pthread_mutex_lock(&LOCK_instance_map);
+ hash_free(&hash);
+ hash_init(&hash, default_charset_info, START_HASH_SIZE, 0, 0,
+ get_instance_key, delete_instance, 0);
+ rc= load();
+ pthread_mutex_unlock(&LOCK_instance_map);
+ return rc;
}
@@ -448,3 +224,28 @@ int Instance_map::load()
return error;
}
+
+
+Instance *Instance_map::get_instance(uint instance_number)
+{
+ if (instance_number < hash.records)
+ return (Instance *) hash_element(&hash, instance_number);
+ else
+ return NULL;
+}
+
+
+/*--- Implementaton of the Instance map iterator class (Imap_iterator) ---*/
+
+
+void Imap_iterator::go_to_first()
+{
+ current_instance=0;
+}
+
+
+Instance *Imap_iterator::next()
+{
+ return instance_map->get_instance(current_instance++);
+}
+
diff --git a/server-tools/instance-manager/instance_map.h b/server-tools/instance-manager/instance_map.h
index 965261f2920..193376c6f23 100644
--- a/server-tools/instance-manager/instance_map.h
+++ b/server-tools/instance-manager/instance_map.h
@@ -43,12 +43,11 @@ public:
Instance *find(const char *name, uint name_len);
Instance *find(uint instance_number);
- int show_instances(struct st_net *net);
- int show_instance_status(struct st_net *net, const char *instance_name);
- int show_instance_options(struct st_net *net, const char *instance_name);
int flush_instances();
- int init_guardian();
int cleanup();
+ int lock();
+ int unlock();
+ Instance *get_instance(uint instance_number);
Instance_map();
~Instance_map();
@@ -73,4 +72,22 @@ private:
HASH hash;
};
+
+/* Instance_map iterator */
+
+class Imap_iterator
+{
+private:
+ uint current_instance;
+ Instance_map *instance_map;
+public:
+ Imap_iterator(Instance_map *instance_map_arg) :
+ instance_map(instance_map_arg), current_instance(0)
+ {}
+
+ void go_to_first();
+ Instance *next();
+};
+
+
#endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_INSTANCE_MAP_H */
diff --git a/server-tools/instance-manager/listener.cc b/server-tools/instance-manager/listener.cc
index ddd03726917..4a13dc39ec7 100644
--- a/server-tools/instance-manager/listener.cc
+++ b/server-tools/instance-manager/listener.cc
@@ -129,8 +129,12 @@ void Listener_thread::run()
thread_registry.request_shutdown();
return;
}
+ /* set the socket nonblocking */
flags= fcntl(ip_socket, F_GETFL, 0);
fcntl(ip_socket, F_SETFL, flags | O_NONBLOCK);
+ /* make shure that instances won't be listening our sockets */
+ flags= fcntl(ip_socket, F_GETFD, 0);
+ fcntl(ip_socket, F_SETFD, flags | FD_CLOEXEC);
log_info("accepting connections on ip socket");
@@ -180,6 +184,9 @@ void Listener_thread::run()
/* set the socket nonblocking */
flags= fcntl(unix_socket, F_GETFL, 0);
fcntl(unix_socket, F_SETFL, flags | O_NONBLOCK);
+ /* make shure that instances won't be listening our sockets */
+ flags= fcntl(unix_socket, F_GETFD, 0);
+ fcntl(unix_socket, F_SETFD, flags | FD_CLOEXEC);
}
log_info("accepting connections on unix socket %s",
unix_socket_address.sun_path);
diff --git a/server-tools/instance-manager/manager.cc b/server-tools/instance-manager/manager.cc
index 11a3289adbf..1c23aa602d4 100644
--- a/server-tools/instance-manager/manager.cc
+++ b/server-tools/instance-manager/manager.cc
@@ -161,7 +161,7 @@ void manager(const Options &options)
alarm structures initialization as we have to use net_* functions while
making the list. And they in their turn need alarms for timeout suppport.
*/
- instance_map.init_guardian();
+ guardian_thread.start();
while (!shutdown_complete)
{
diff --git a/server-tools/instance-manager/mysql_connection.cc b/server-tools/instance-manager/mysql_connection.cc
index 2a617675c26..0ebcb0eea8d 100644
--- a/server-tools/instance-manager/mysql_connection.cc
+++ b/server-tools/instance-manager/mysql_connection.cc
@@ -319,10 +319,10 @@ int Mysql_connection_thread::dispatch_command(enum enum_server_command command,
{
switch (command) {
case COM_QUIT: // client exit
- log_info("query for connection %d received quit command",connection_id);
+ log_info("query for connection %d received quit command", connection_id);
return 1;
case COM_PING:
- log_info("query for connection %d received ping command",connection_id);
+ log_info("query for connection %d received ping command", connection_id);
net_send_ok(&net, connection_id);
break;
case COM_QUERY:
diff --git a/server-tools/instance-manager/protocol.cc b/server-tools/instance-manager/protocol.cc
index f32d8558fbf..2f1f95a5f05 100644
--- a/server-tools/instance-manager/protocol.cc
+++ b/server-tools/instance-manager/protocol.cc
@@ -101,14 +101,14 @@ char *net_store_length(char *pkg, uint length)
void store_to_string(Buffer *buf, const char *string, uint *position)
{
- char* currpos;
+ uint currpos;
uint string_len;
string_len= strlen(string);
buf->reserve(*position, 2);
- currpos= net_store_length(buf->buffer + *position, string_len);
+ currpos= (net_store_length(buf->buffer + *position, string_len) - buf->buffer);
buf->append(currpos, string, string_len);
- *position= *position + string_len + (currpos - buf->buffer - *position);
+ *position= *position + string_len + (currpos - *position);
}