summaryrefslogtreecommitdiff
path: root/server-tools/instance-manager/commands.cc
diff options
context:
space:
mode:
authorpetr@mysql.com <>2004-12-09 04:22:28 +0300
committerpetr@mysql.com <>2004-12-09 04:22:28 +0300
commitfd94614f34efe8211ccba70498d37db55e42952f (patch)
tree6b81e45da104e71d355f27b8abaf834a2f10eeab /server-tools/instance-manager/commands.cc
parentaa2f11611029dc0598566d87b6ccbfb796480477 (diff)
parentd2115d133db498ee80943e66e5f4d715d9586a83 (diff)
downloadmariadb-git-fd94614f34efe8211ccba70498d37db55e42952f.tar.gz
merge
Diffstat (limited to 'server-tools/instance-manager/commands.cc')
-rw-r--r--server-tools/instance-manager/commands.cc421
1 files changed, 421 insertions, 0 deletions
diff --git a/server-tools/instance-manager/commands.cc b/server-tools/instance-manager/commands.cc
new file mode 100644
index 00000000000..2ac97382aa8
--- /dev/null
+++ b/server-tools/instance-manager/commands.cc
@@ -0,0 +1,421 @@
+/* Copyright (C) 2004 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include "command.h"
+#include "commands.h"
+#include "instance.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;
+ Instance_map::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 (do_command(net))
+ return ER_OUT_OF_RESOURCES;
+
+ return 0;
+}
+
+
+/* implementation for Flush_instances: */
+
+int Flush_instances::execute(struct st_net *net, ulong connection_id)
+{
+ if (instance_map->flush_instances())
+ return ER_OUT_OF_RESOURCES;
+
+ net_send_ok(net, connection_id);
+ return 0;
+}
+
+
+/* implementation for Show_instance_status: */
+
+Show_instance_status::Show_instance_status(Instance_map *instance_map_arg,
+ const char *name, uint len)
+ :Command(instance_map_arg)
+{
+ Instance *instance;
+
+ /* we make a search here, since we don't want t store the name */
+ if (instance= instance_map->find(name, len))
+ {
+ instance_name= instance->options.instance_name;
+ }
+ else
+ instance_name= NULL;
+}
+
+
+/*
+ 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);
+ }
+
+
+ if (my_net_write(net, send_buff.buffer, (uint) position))
+ goto err;
+ }
+
+ send_eof(net);
+ net_flush(net);
+
+ return 0;
+
+err:
+ return 1;
+}
+
+
+int Show_instance_status::execute(struct st_net *net, ulong connection_id)
+{
+ if (instance_name != NULL)
+ {
+ if (do_command(net, instance_name))
+ return ER_OUT_OF_RESOURCES;
+ return 0;
+ }
+ else
+ {
+ return ER_BAD_INSTANCE_NAME;
+ }
+}
+
+
+/* Implementation for Show_instance_options */
+
+Show_instance_options::Show_instance_options(Instance_map *instance_map_arg,
+ const char *name, uint len):
+ Command(instance_map_arg)
+{
+ Instance *instance;
+
+ /* we make a search here, since we don't want t store the name */
+ if (instance= instance_map->find(name, len))
+ {
+ instance_name= instance->options.instance_name;
+ }
+ else
+ instance_name= NULL;
+}
+
+
+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);
+ if (my_net_write(net, send_buff.buffer, (uint) position))
+ goto err;
+ 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);
+ if (my_net_write(net, send_buff.buffer, (uint) position))
+ goto err;
+ }
+
+ if (instance->options.is_guarded != NULL)
+ {
+ position= 0;
+ store_to_string(&send_buff, (char *) "guarded", &position);
+ store_to_string(&send_buff, "", &position);
+ if (my_net_write(net, send_buff.buffer, (uint) position))
+ goto err;
+ }
+
+ 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);
+ if (my_net_write(net, send_buff.buffer, (uint) position))
+ goto err;
+ }
+
+ 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);
+ if (my_net_write(net, send_buff.buffer, (uint) position))
+ goto err;
+ }
+
+ /* 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= '=';
+ if (my_net_write(net, send_buff.buffer, (uint) position))
+ goto err;
+ }
+ }
+
+ 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 (do_command(net, instance_name))
+ return ER_OUT_OF_RESOURCES;
+ return 0;
+ }
+ else
+ {
+ return ER_BAD_INSTANCE_NAME;
+ }
+}
+
+
+/* Implementation for Start_instance */
+
+Start_instance::Start_instance(Instance_map *instance_map_arg,
+ const char *name, uint len)
+ :Command(instance_map_arg)
+{
+ /* we make a search here, since we don't want t store the name */
+ if (instance= instance_map->find(name, len))
+ instance_name= instance->options.instance_name;
+}
+
+
+int Start_instance::execute(struct st_net *net, ulong connection_id)
+{
+ uint err_code;
+ if (instance == 0)
+ {
+ return ER_BAD_INSTANCE_NAME; /* haven't found an instance */
+ }
+ else
+ {
+ if (err_code= instance->start())
+ return err_code;
+
+ if (instance->options.is_guarded != NULL)
+ instance_map->guardian->guard(instance);
+
+ net_send_ok(net, connection_id);
+ return 0;
+ }
+}
+
+
+/* Implementation for Stop_instance: */
+
+Stop_instance::Stop_instance(Instance_map *instance_map_arg,
+ const char *name, uint len)
+ :Command(instance_map_arg)
+{
+ /* we make a search here, since we don't want t store the name */
+ if (instance= instance_map->find(name, len))
+ instance_name= instance->options.instance_name;
+}
+
+
+int Stop_instance::execute(struct st_net *net, ulong connection_id)
+{
+ uint err_code;
+
+ if (instance == 0)
+ {
+ return ER_BAD_INSTANCE_NAME; /* haven't found an instance */
+ }
+ else
+ {
+ if (instance->options.is_guarded != NULL)
+ instance_map->guardian->
+ stop_guard(instance);
+ if (err_code= instance->stop())
+ return err_code;
+ printf("instance was stopped\n");
+ net_send_ok(net, connection_id);
+ return 0;
+ }
+}
+
+
+int Syntax_error::execute(struct st_net *net, ulong connection_id)
+{
+ return ER_SYNTAX_ERROR;
+}