Commit 26b6b1b2 authored by unknown's avatar unknown

Cleanup the instance manager code.


BitKeeper/deleted/.del-factory.h~c1679505d3a6dd53:
  Delete: server-tools/instance-manager/factory.h
BitKeeper/deleted/.del-factory.cc~6836cccd4cd35b4d:
  Delete: server-tools/instance-manager/factory.cc
server-tools/instance-manager/Makefile.am:
  - remove Commands_factory: it'll be needed when we add support
  for NNTP/HTTP connections, currently it only adds unnecessary
  complexity.
server-tools/instance-manager/commands.cc:
  - fix coding style: no else after return; fix comments, make
  one place a bit faster.
server-tools/instance-manager/guardian.cc:
  - fix coding style and comments.
  - we must register the current thread in the thread registry
    before entering pthread_cond_timedwait, because at shutdown
    the thread registry will try to kick out of wait all blocked 
    threads. Unregistered threads are not awakened by the registry. 
    This fixes the failinig assert in Thread_registry::~Thread_registry
    at shutdown, when shutdown is requested and there is an
    instance monitored by Guardian.
server-tools/instance-manager/guardian.h:
  - fix coding style: enums must start with enum_
server-tools/instance-manager/instance.h:
  - move comment to the variable it comments
server-tools/instance-manager/instance_map.cc:
  - cleanup
server-tools/instance-manager/instance_options.cc:
  - cleanup; no else after return (fix coding style).
server-tools/instance-manager/manager.cc:
  - fix alignment; make some code easier to read.
server-tools/instance-manager/mysql_connection.cc:
  - remove Commands_factory
server-tools/instance-manager/options.cc:
  - fix a possible crash when the instance manager is started with
  --no-defaults --defaults-file=~/.my.cnf: if we return
  without cloning saved_argv by calling load_defaults, Options::cleanup
  will crash on attempt to free_defaults(saved_argv);
server-tools/instance-manager/parse.cc:
  - get rid of Commands_factory
server-tools/instance-manager/parse.h:
  - get rid of Commands_factory
server-tools/instance-manager/parse_output.cc:
  - in parse_output_and_get_value return error also if the specified
    pattern was not found, or the command failed to execute.
server-tools/instance-manager/portability.h:
  - fix coding style (// comments are allowed only at ends of lines)
server-tools/instance-manager/thread_registry.cc:
  - implement Thread_registry::cond_timedwait
server-tools/instance-manager/thread_registry.h:
  - implement Thread_registry::cond_timedwait; remove
    unused out parameter from Thread_registry::cond_wait.
server-tools/instance-manager/user_map.cc:
  - safety: newline can take 2 bytes.
parent 7efa8d9b
...@@ -70,7 +70,6 @@ mysqlmanager_SOURCES= command.cc command.h mysqlmanager.cc \ ...@@ -70,7 +70,6 @@ mysqlmanager_SOURCES= command.cc command.h mysqlmanager.cc \
user_map.h user_map.cc \ user_map.h user_map.cc \
messages.h messages.cc \ messages.h messages.cc \
commands.h commands.cc \ commands.h commands.cc \
factory.h factory.cc \
instance.h instance.cc \ instance.h instance.cc \
instance_map.h instance_map.cc\ instance_map.h instance_map.cc\
instance_options.h instance_options.cc \ instance_options.h instance_options.cc \
......
...@@ -461,7 +461,8 @@ int Show_instance_log::execute(struct st_net *net, ulong connection_id) ...@@ -461,7 +461,8 @@ int Show_instance_log::execute(struct st_net *net, ulong connection_id)
/* Instance has no such log */ /* Instance has no such log */
if (logpath == NULL) if (logpath == NULL)
return ER_NO_SUCH_LOG; return ER_NO_SUCH_LOG;
else if (*logpath == '\0')
if (*logpath == '\0')
return ER_GUESS_LOGFILE; return ER_GUESS_LOGFILE;
...@@ -571,6 +572,7 @@ int Show_instance_log_files::execute(struct st_net *net, ulong connection_id) ...@@ -571,6 +572,7 @@ int Show_instance_log_files::execute(struct st_net *net, ulong connection_id)
if ((instance= instance_map-> if ((instance= instance_map->
find(instance_name, strlen(instance_name))) == NULL) find(instance_name, strlen(instance_name))) == NULL)
goto err; goto err;
{ {
/* /*
We have alike structure in instance_options.cc. We use such to be able We have alike structure in instance_options.cc. We use such to be able
...@@ -686,7 +688,7 @@ Set_option::Set_option(Instance_map *instance_map_arg, ...@@ -686,7 +688,7 @@ Set_option::Set_option(Instance_map *instance_map_arg,
option. option.
RETURN RETURN
ER_BAD_INSTANCE_NAME The instance name specified is not valid ER_OUT_OF_RESOURCES out of resources
ER_ACCESS_OPTION_FILE Cannot access the option file ER_ACCESS_OPTION_FILE Cannot access the option file
0 - ok 0 - ok
*/ */
...@@ -694,22 +696,14 @@ Set_option::Set_option(Instance_map *instance_map_arg, ...@@ -694,22 +696,14 @@ Set_option::Set_option(Instance_map *instance_map_arg,
int Set_option::correct_file(int skip) int Set_option::correct_file(int skip)
{ {
int error; int error;
const static int mysys_to_im_error[]= { 0, ER_OUT_OF_RESOURCES,
ER_ACCESS_OPTION_FILE };
error= modify_defaults_file(Options::config_file, option, error= modify_defaults_file(Options::config_file, option,
option_value, instance_name, skip); option_value, instance_name, skip);
switch (error) DBUG_ASSERT(error >= 0 && error <= 2);
{
case 0:
return 0; /* everything was fine */
case 1:
return ER_OUT_OF_RESOURCES;
case 2:
return ER_ACCESS_OPTION_FILE;
default:
DBUG_ASSERT(0); /* should never get here */
}
return 0; /* keep compiler happy */ return mysys_to_im_error[error];
} }
...@@ -725,10 +719,9 @@ int Set_option::correct_file(int skip) ...@@ -725,10 +719,9 @@ int Set_option::correct_file(int skip)
1 - error occured 1 - error occured
*/ */
int Set_option::do_command(struct st_net *net) int Set_option::do_command(struct st_net *net)
{ {
int error= 0; int error;
/* we must hold the instance_map mutex while changing config file */ /* we must hold the instance_map mutex while changing config file */
instance_map->lock(); instance_map->lock();
...@@ -746,15 +739,13 @@ int Set_option::execute(struct st_net *net, ulong connection_id) ...@@ -746,15 +739,13 @@ int Set_option::execute(struct st_net *net, ulong connection_id)
int val; int val;
val= do_command(net); val= do_command(net);
if (val == 0) if (val == 0)
{
net_send_ok(net, connection_id, NULL); net_send_ok(net, connection_id, NULL);
return 0;
}
return val; return val;
} }
else
return ER_BAD_INSTANCE_NAME; return ER_BAD_INSTANCE_NAME;
} }
...@@ -785,16 +776,15 @@ int Stop_instance::execute(struct st_net *net, ulong connection_id) ...@@ -785,16 +776,15 @@ int Stop_instance::execute(struct st_net *net, ulong connection_id)
if (instance == 0) if (instance == 0)
return ER_BAD_INSTANCE_NAME; /* haven't found an instance */ return ER_BAD_INSTANCE_NAME; /* haven't found an instance */
else
{
if (!(instance->options.nonguarded)) if (!(instance->options.nonguarded))
instance_map->guardian-> instance_map->guardian->stop_guard(instance);
stop_guard(instance);
if ((err_code= instance->stop())) if ((err_code= instance->stop()))
return err_code; return err_code;
net_send_ok(net, connection_id, NULL); net_send_ok(net, connection_id, NULL);
return 0; return 0;
}
} }
......
/* Copyright (C) 2004 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "factory.h"
Show_instances *Command_factory::new_Show_instances()
{
return new Show_instances(&instance_map);
}
Flush_instances *Command_factory::new_Flush_instances()
{
return new Flush_instances(&instance_map);
}
Show_instance_status *Command_factory::
new_Show_instance_status(const char *name, uint len)
{
return new Show_instance_status(&instance_map, name, len);
}
Show_instance_options *Command_factory::
new_Show_instance_options(const char *name, uint len)
{
return new Show_instance_options(&instance_map, name, len);
}
Start_instance *Command_factory::
new_Start_instance(const char *name, uint len)
{
return new Start_instance(&instance_map, name, len);
}
Stop_instance *Command_factory::new_Stop_instance(const char *name, uint len)
{
return new Stop_instance(&instance_map, name, len);
}
Syntax_error *Command_factory::new_Syntax_error()
{
return new Syntax_error();
}
Set_option *Command_factory::
new_Set_option(const char* name, uint len,
const char *option_arg, uint option_len,
const char *option_value_arg, uint option_value_len)
{
return new Set_option(&instance_map, name, len, option_arg,
option_len, option_value_arg, option_value_len);
}
Unset_option *Command_factory::
new_Unset_option(const char* name, uint len,
const char *option_arg, uint option_len,
const char *option_value_arg, uint option_value_len)
{
return new Unset_option(&instance_map, name, len, option_arg,
option_len, option_value_arg, option_value_len);
}
Show_instance_log *Command_factory::
new_Show_instance_log(const char *name, uint len,
Log_type log_type_arg,
const char *size, const char *offset)
{
return new Show_instance_log(&instance_map, name, len,
log_type_arg, size, offset);
}
Show_instance_log_files *Command_factory::
new_Show_instance_log_files(const char *name, uint len)
{
return new Show_instance_log_files(&instance_map, name, len);
}
#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_FACTORY_H
#define INCLUDES_MYSQL_INSTANCE_MANAGER_FACTORY_H
/* Copyright (C) 2004 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "command.h"
#include "commands.h"
#include "instance_map.h"
/*
This class could be used to handle various protocols. We could pass to
the parser various derived classes. I.e Mylsq_command_factory,
Http_command_factory e.t.c. Also see comment in the instance_map.cc
*/
class Show_instances;
class Command_factory
{
public:
Command_factory(Instance_map &instance_map): instance_map(instance_map)
{}
Show_instances *new_Show_instances ();
Flush_instances *new_Flush_instances ();
Syntax_error *new_Syntax_error ();
Show_instance_status *new_Show_instance_status (const char *name, uint len);
Show_instance_options *new_Show_instance_options (const char *name, uint len);
Start_instance *new_Start_instance (const char *name, uint len);
Stop_instance *new_Stop_instance (const char *name, uint len);
Show_instance_log *new_Show_instance_log (const char *name, uint len,
Log_type log_type_arg,
const char *size,
const char *offset);
Set_option *new_Set_option (const char *name, uint len,
const char *option_arg, uint option_len,
const char *option_value_arg,
uint option_value_len);
Unset_option *new_Unset_option (const char *name, uint len,
const char *option_arg, uint option_len,
const char *option_value_arg,
uint option_value_len);
Show_instance_log_files *new_Show_instance_log_files (const char *name,
uint len);
Instance_map &instance_map;
};
#endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_FACTORY_H */
...@@ -122,8 +122,7 @@ void Guardian_thread::process_instance(Instance *instance, ...@@ -122,8 +122,7 @@ void Guardian_thread::process_instance(Instance *instance,
} }
else else
{ {
switch (current_node->state) switch (current_node->state) {
{
case NOT_STARTED: case NOT_STARTED:
instance->start(); instance->start();
current_node->last_checked= current_time; current_node->last_checked= current_time;
...@@ -149,7 +148,8 @@ void Guardian_thread::process_instance(Instance *instance, ...@@ -149,7 +148,8 @@ void Guardian_thread::process_instance(Instance *instance,
log_info("guardian: starting instance %s", log_info("guardian: starting instance %s",
instance->options.instance_name); instance->options.instance_name);
} }
else current_node->state= CRASHED; else
current_node->state= CRASHED;
break; break;
case CRASHED: /* just regular restarts */ case CRASHED: /* just regular restarts */
if (current_time - current_node->last_checked > if (current_time - current_node->last_checked >
...@@ -219,7 +219,8 @@ void Guardian_thread::run() ...@@ -219,7 +219,8 @@ void Guardian_thread::run()
/* check the loop predicate before sleeping */ /* check the loop predicate before sleeping */
if (!(shutdown_requested && (!(guarded_instances)))) if (!(shutdown_requested && (!(guarded_instances))))
pthread_cond_timedwait(&COND_guardian, &LOCK_guardian, &timeout); thread_registry.cond_timedwait(&thread_info, &COND_guardian,
&LOCK_guardian, &timeout);
} }
stopped= TRUE; stopped= TRUE;
...@@ -365,18 +366,20 @@ int Guardian_thread::stop_guard(Instance *instance) ...@@ -365,18 +366,20 @@ int Guardian_thread::stop_guard(Instance *instance)
} }
/* /*
Start Guardian shutdown. Attempt to start instances if requested. An internal method which is called at shutdown to unregister instances and
attempt to stop them if requested.
SYNOPSYS SYNOPSYS
stop_instances() stop_instances()
stop_instances_arg whether we should stop instances at shutdown stop_instances_arg whether we should stop instances at shutdown
DESCRIPTION DESCRIPTION
Loops through the guarded_instances list and prepares them for shutdown. Loops through the guarded_instances list and prepares them for shutdown.
If stop_instances was requested, we need to issue a stop command and change If stop_instances was requested, we need to issue a stop command and change
the state accordingly. Otherwise we could simply delete an entry. the state accordingly. Otherwise we simply delete an entry.
NOTE: Guardian should be locked by the calling function
NOTE
Guardian object should be locked by the calling function.
RETURN RETURN
0 - ok 0 - ok
......
...@@ -62,7 +62,7 @@ class Guardian_thread: public Guardian_thread_args ...@@ -62,7 +62,7 @@ class Guardian_thread: public Guardian_thread_args
{ {
public: public:
/* states of an instance */ /* states of an instance */
enum INSTANCE_STATE { NOT_STARTED= 1, STARTING, STARTED, JUST_CRASHED, enum enum_instance_state { NOT_STARTED= 1, STARTING, STARTED, JUST_CRASHED,
CRASHED, CRASHED_AND_ABANDONED, STOPPING }; CRASHED, CRASHED_AND_ABANDONED, STOPPING };
/* /*
...@@ -74,7 +74,7 @@ public: ...@@ -74,7 +74,7 @@ public:
{ {
Instance *instance; Instance *instance;
/* state of an instance (i.e. STARTED, CRASHED, etc.) */ /* state of an instance (i.e. STARTED, CRASHED, etc.) */
INSTANCE_STATE state; enum_instance_state state;
/* the amount of attemts to restart instance (cleaned up at success) */ /* the amount of attemts to restart instance (cleaned up at success) */
int restart_counter; int restart_counter;
/* triggered at a crash */ /* triggered at a crash */
......
...@@ -49,12 +49,12 @@ public: ...@@ -49,12 +49,12 @@ public:
Instance_options options; Instance_options options;
private: private:
int crashed;
/* /*
Mutex protecting the instance. Currently we use it to avoid the Mutex protecting the instance. Currently we use it to avoid the
double start of the instance. This happens when the instance is starting double start of the instance. This happens when the instance is starting
and we issue the start command once more. and we issue the start command once more.
*/ */
int crashed;
pthread_mutex_t LOCK_instance; pthread_mutex_t LOCK_instance;
/* /*
This condition variable is used to wake threads waiting for instance to This condition variable is used to wake threads waiting for instance to
......
...@@ -91,22 +91,20 @@ static int process_option(void *ctx, const char *group, const char *option) ...@@ -91,22 +91,20 @@ static int process_option(void *ctx, const char *group, const char *option)
if ((instance= map->find(group, strlen(group))) == NULL) if ((instance= map->find(group, strlen(group))) == NULL)
{ {
if ((instance= new Instance) == 0) if ((instance= new Instance) == 0)
goto err_new_instance;
if (instance->init(group))
goto err;
if (map->add_instance(instance))
goto err; goto err;
if (instance->init(group) || map->add_instance(instance))
goto err_instance;
} }
if (instance->options.add_option(option)) if (instance->options.add_option(option))
goto err; goto err; /* the instance'll be deleted when we destroy the map */
} }
return 0; return 0;
err: err_instance:
delete instance; delete instance;
err_new_instance: err:
return 1; return 1;
} }
...@@ -122,10 +120,8 @@ mysqld_path(default_mysqld_path_arg) ...@@ -122,10 +120,8 @@ mysqld_path(default_mysqld_path_arg)
int Instance_map::init() int Instance_map::init()
{ {
if (hash_init(&hash, default_charset_info, START_HASH_SIZE, 0, 0, return hash_init(&hash, default_charset_info, START_HASH_SIZE, 0, 0,
get_instance_key, delete_instance, 0)) get_instance_key, delete_instance, 0);
return 1;
return 0;
} }
Instance_map::~Instance_map() Instance_map::~Instance_map()
...@@ -217,10 +213,9 @@ int Instance_map::complete_initialization() ...@@ -217,10 +213,9 @@ int Instance_map::complete_initialization()
} }
return 0; return 0;
err:
return 1;
err_instance: err_instance:
delete instance; delete instance;
err:
return 1; return 1;
} }
......
...@@ -51,13 +51,9 @@ static inline int create_mysqld_command(Buffer *buf, ...@@ -51,13 +51,9 @@ static inline int create_mysqld_command(Buffer *buf,
/* here the '\0' character is copied from the option string */ /* here the '\0' character is copied from the option string */
buf->append(position, option, option_len); buf->append(position, option, option_len);
if (buf->is_error()) return buf->is_error();
return 1;
} }
else
return 1; return 1;
return 0;
} }
...@@ -96,10 +92,8 @@ int Instance_options::get_default_option(char *result, size_t result_len, ...@@ -96,10 +92,8 @@ int Instance_options::get_default_option(char *result, size_t result_len,
/* +2 eats first "--" from the option string (E.g. "--datadir") */ /* +2 eats first "--" from the option string (E.g. "--datadir") */
rc= parse_output_and_get_value(cmd.buffer, option_name + 2, rc= parse_output_and_get_value(cmd.buffer, option_name + 2,
result, result_len, GET_VALUE); result, result_len, GET_VALUE);
return rc;
err: err:
return 1; return rc;
} }
...@@ -142,11 +136,8 @@ int Instance_options::fill_instance_version() ...@@ -142,11 +136,8 @@ int Instance_options::fill_instance_version()
result[strlen(result) - NEWLINE_LEN]= '\0'; result[strlen(result) - NEWLINE_LEN]= '\0';
mysqld_version= strdup_root(&alloc, result); mysqld_version= strdup_root(&alloc, result);
} }
return rc;
err: err:
return 1; return rc;
} }
...@@ -194,13 +185,15 @@ int Instance_options::fill_log_options() ...@@ -194,13 +185,15 @@ int Instance_options::fill_log_options()
/* compute hostname and datadir for the instance */ /* compute hostname and datadir for the instance */
if (mysqld_datadir == NULL) if (mysqld_datadir == NULL)
{ {
if (get_default_option(datadir, if (get_default_option(datadir, MAX_LOG_OPTION_LENGTH, "--datadir"))
MAX_LOG_OPTION_LENGTH, "--datadir"))
goto err; goto err;
} }
else /* below is safe, as --datadir always has a value */ else
strmake(datadir, strchr(mysqld_datadir, '=') + 1, {
MAX_LOG_OPTION_LENGTH - 1); /* below is safe, as --datadir always has a value */
strmake(datadir,
strchr(mysqld_datadir, '=') + 1, MAX_LOG_OPTION_LENGTH - 1);
}
if (gethostname(hostname,sizeof(hostname)-1) < 0) if (gethostname(hostname,sizeof(hostname)-1) < 0)
strmov(hostname, "mysql"); strmov(hostname, "mysql");
...@@ -230,15 +223,12 @@ int Instance_options::fill_log_options() ...@@ -230,15 +223,12 @@ int Instance_options::fill_log_options()
MY_UNPACK_FILENAME | MY_SAFE_PATH); MY_UNPACK_FILENAME | MY_SAFE_PATH);
if ((MAX_LOG_OPTION_LENGTH - strlen(full_name)) > if ((MAX_LOG_OPTION_LENGTH - strlen(full_name)) <=
strlen(log_files->default_suffix)) strlen(log_files->default_suffix))
{
strmov(full_name + strlen(full_name),
log_files->default_suffix);
}
else
goto err; goto err;
strmov(full_name + strlen(full_name), log_files->default_suffix);
/* /*
If there were specified two identical logfiles options, If there were specified two identical logfiles options,
we would loose some memory in MEM_ROOT here. However we would loose some memory in MEM_ROOT here. However
...@@ -254,8 +244,7 @@ int Instance_options::fill_log_options() ...@@ -254,8 +244,7 @@ int Instance_options::fill_log_options()
fn_format(full_name, argv[i] +log_files->length + 1, fn_format(full_name, argv[i] +log_files->length + 1,
datadir, "", MY_UNPACK_FILENAME | MY_SAFE_PATH); datadir, "", MY_UNPACK_FILENAME | MY_SAFE_PATH);
if (!(*(log_files->value)= if (!(*(log_files->value)= strdup_root(&alloc, full_name)))
strdup_root(&alloc, full_name)))
goto err; goto err;
} }
} }
...@@ -263,10 +252,8 @@ int Instance_options::fill_log_options() ...@@ -263,10 +252,8 @@ int Instance_options::fill_log_options()
} }
return 0; return 0;
err: err:
return 1; return 1;
} }
...@@ -294,7 +281,7 @@ int Instance_options::get_pid_filename(char *result) ...@@ -294,7 +281,7 @@ int Instance_options::get_pid_filename(char *result)
const char *pid_file= mysqld_pid_file; const char *pid_file= mysqld_pid_file;
char datadir[MAX_PATH_LEN]; char datadir[MAX_PATH_LEN];
if (!(mysqld_datadir)) if (mysqld_datadir == NULL)
{ {
/* we might get an error here if we have wrong path to the mysqld binary */ /* we might get an error here if we have wrong path to the mysqld binary */
if (get_default_option(datadir, sizeof(datadir), "--datadir")) if (get_default_option(datadir, sizeof(datadir), "--datadir"))
...@@ -333,7 +320,6 @@ pid_t Instance_options::get_pid() ...@@ -333,7 +320,6 @@ pid_t Instance_options::get_pid()
my_fclose(pid_file_stream, MYF(0)); my_fclose(pid_file_stream, MYF(0));
return pid; return pid;
} }
else
return 0; return 0;
} }
...@@ -343,11 +329,8 @@ int Instance_options::complete_initialization(const char *default_path, ...@@ -343,11 +329,8 @@ int Instance_options::complete_initialization(const char *default_path,
{ {
const char *tmp; const char *tmp;
if (!(mysqld_path)) if (!mysqld_path && !(mysqld_path= strdup_root(&alloc, default_path)))
{
if (!(mysqld_path= strdup_root(&alloc, default_path)))
goto err; goto err;
}
mysqld_path_len= strlen(mysqld_path); mysqld_path_len= strlen(mysqld_path);
...@@ -395,7 +378,8 @@ int Instance_options::complete_initialization(const char *default_path, ...@@ -395,7 +378,8 @@ int Instance_options::complete_initialization(const char *default_path,
goto err; goto err;
/* we need to reserve space for the final zero + possible default options */ /* we need to reserve space for the final zero + possible default options */
if (!(argv= (char**) alloc_root(&alloc, (options_array.elements + 1 if (!(argv= (char**)
alloc_root(&alloc, (options_array.elements + 1
+ MAX_NUMBER_OF_DEFAULT_OPTIONS) * sizeof(char*)))) + MAX_NUMBER_OF_DEFAULT_OPTIONS) * sizeof(char*))))
goto err; goto err;
...@@ -465,8 +449,8 @@ int Instance_options::add_option(const char* option) ...@@ -465,8 +449,8 @@ int Instance_options::add_option(const char* option)
for (selected_options= options; selected_options->name; selected_options++) for (selected_options= options; selected_options->name; selected_options++)
{ {
if (!strncmp(tmp, selected_options->name, selected_options->length)) if (strncmp(tmp, selected_options->name, selected_options->length) == 0)
switch(selected_options->type){ switch (selected_options->type) {
case SAVE_WHOLE_AND_ADD: case SAVE_WHOLE_AND_ADD:
*(selected_options->value)= tmp; *(selected_options->value)= tmp;
insert_dynamic(&options_array,(gptr) &tmp); insert_dynamic(&options_array,(gptr) &tmp);
...@@ -496,7 +480,7 @@ int Instance_options::add_to_argv(const char* option) ...@@ -496,7 +480,7 @@ int Instance_options::add_to_argv(const char* option)
{ {
DBUG_ASSERT(filled_default_options < MAX_NUMBER_OF_DEFAULT_OPTIONS); DBUG_ASSERT(filled_default_options < MAX_NUMBER_OF_DEFAULT_OPTIONS);
if ((option)) if (option)
argv[filled_default_options++]= (char*) option; argv[filled_default_options++]= (char*) option;
return 0; return 0;
} }
...@@ -508,9 +492,7 @@ void Instance_options::print_argv() ...@@ -508,9 +492,7 @@ void Instance_options::print_argv()
int i; int i;
printf("printing out an instance %s argv:\n", instance_name); printf("printing out an instance %s argv:\n", instance_name);
for (i=0; argv[i] != NULL; i++) for (i=0; argv[i] != NULL; i++)
{
printf("argv: %s\n", argv[i]); printf("argv: %s\n", argv[i]);
}
} }
......
...@@ -42,14 +42,11 @@ static int create_pid_file(const char *pid_file_name) ...@@ -42,14 +42,11 @@ static int create_pid_file(const char *pid_file_name)
{ {
fprintf(pid_file, "%d\n", (int) getpid()); fprintf(pid_file, "%d\n", (int) getpid());
my_fclose(pid_file, MYF(0)); my_fclose(pid_file, MYF(0));
return 0;
} }
else
{
log_error("can't create pid file %s: errno=%d, %s", log_error("can't create pid file %s: errno=%d, %s",
pid_file_name, errno, strerror(errno)); pid_file_name, errno, strerror(errno));
return 1; return 1;
}
return 0;
} }
#ifndef __WIN__ #ifndef __WIN__
......
...@@ -39,8 +39,6 @@ ...@@ -39,8 +39,6 @@
#include <my_sys.h> #include <my_sys.h>
Command *parse_command(Command_factory * factory, const char *text);
Mysql_connection_thread_args::Mysql_connection_thread_args( Mysql_connection_thread_args::Mysql_connection_thread_args(
struct st_vio *vio_arg, struct st_vio *vio_arg,
Thread_registry &thread_registry_arg, Thread_registry &thread_registry_arg,
...@@ -336,8 +334,7 @@ int Mysql_connection_thread::dispatch_command(enum enum_server_command command, ...@@ -336,8 +334,7 @@ int Mysql_connection_thread::dispatch_command(enum enum_server_command command,
{ {
log_info("query for connection %d : ----\n%s\n-------------------------", log_info("query for connection %d : ----\n%s\n-------------------------",
connection_id,packet); connection_id,packet);
Command_factory commands_factory(instance_map); if (Command *command= parse_command(&instance_map, packet))
if (Command *command= parse_command(&commands_factory, packet))
{ {
int res= 0; int res= 0;
log_info("query for connection %d successefully parsed",connection_id); log_info("query for connection %d successefully parsed",connection_id);
......
...@@ -244,8 +244,6 @@ C_MODE_END ...@@ -244,8 +244,6 @@ C_MODE_END
int Options::load(int argc, char **argv) int Options::load(int argc, char **argv)
{ {
saved_argv= argv;
if (argc >= 2) if (argc >= 2)
{ {
if (is_prefix(argv[1], "--defaults-file=")) if (is_prefix(argv[1], "--defaults-file="))
...@@ -267,6 +265,8 @@ int Options::load(int argc, char **argv) ...@@ -267,6 +265,8 @@ int Options::load(int argc, char **argv)
if (setup_windows_defaults()) if (setup_windows_defaults())
goto err; goto err;
#endif #endif
/* load_defaults will reset saved_argv with a new allocated list */
saved_argv= argv;
/* config-file options are prepended to command-line ones */ /* config-file options are prepended to command-line ones */
load_defaults(config_file, default_groups, &argc, load_defaults(config_file, default_groups, &argc,
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "parse.h" #include "parse.h"
#include "factory.h" #include "commands.h"
#include <string.h> #include <string.h>
...@@ -114,7 +114,7 @@ int get_text_id(const char **text, uint *word_len, const char **id) ...@@ -114,7 +114,7 @@ int get_text_id(const char **text, uint *word_len, const char **id)
} }
Command *parse_command(Command_factory *factory, const char *text) Command *parse_command(Instance_map *map, const char *text)
{ {
uint word_len; uint word_len;
const char *instance_name; const char *instance_name;
...@@ -147,10 +147,10 @@ Command *parse_command(Command_factory *factory, const char *text) ...@@ -147,10 +147,10 @@ Command *parse_command(Command_factory *factory, const char *text)
if (word_len) if (word_len)
goto syntax_error; goto syntax_error;
command= (tok1 == TOK_START) ? (Command *) if (tok1 == TOK_START)
factory->new_Start_instance(instance_name, instance_name_len): command= new Start_instance(map, instance_name, instance_name_len);
(Command *) else
factory->new_Stop_instance(instance_name, instance_name_len); command= new Stop_instance(map, instance_name, instance_name_len);
break; break;
case TOK_FLUSH: case TOK_FLUSH:
if (shift_token(&text, &word_len) != TOK_INSTANCES) if (shift_token(&text, &word_len) != TOK_INSTANCES)
...@@ -160,7 +160,7 @@ Command *parse_command(Command_factory *factory, const char *text) ...@@ -160,7 +160,7 @@ Command *parse_command(Command_factory *factory, const char *text)
if (word_len) if (word_len)
goto syntax_error; goto syntax_error;
command= factory->new_Flush_instances(); command= new Flush_instances(map);
break; break;
case TOK_UNSET: case TOK_UNSET:
skip= true; skip= true;
...@@ -201,11 +201,11 @@ Command *parse_command(Command_factory *factory, const char *text) ...@@ -201,11 +201,11 @@ Command *parse_command(Command_factory *factory, const char *text)
goto syntax_error; goto syntax_error;
if (skip) if (skip)
command= factory->new_Unset_option(instance_name, instance_name_len, command= new Unset_option(map, instance_name, instance_name_len,
option, option_len, option_value, option, option_len, option_value,
option_value_len); option_value_len);
else else
command= factory->new_Set_option(instance_name, instance_name_len, command= new Set_option(map, instance_name, instance_name_len,
option, option_len, option_value, option, option_len, option_value,
option_value_len); option_value_len);
break; break;
...@@ -215,7 +215,7 @@ Command *parse_command(Command_factory *factory, const char *text) ...@@ -215,7 +215,7 @@ Command *parse_command(Command_factory *factory, const char *text)
get_word(&text, &word_len); get_word(&text, &word_len);
if (word_len) if (word_len)
goto syntax_error; goto syntax_error;
command= factory->new_Show_instances(); command= new Show_instances(map);
break; break;
case TOK_INSTANCE: case TOK_INSTANCE:
switch (Token tok2= shift_token(&text, &word_len)) { switch (Token tok2= shift_token(&text, &word_len)) {
...@@ -227,11 +227,11 @@ Command *parse_command(Command_factory *factory, const char *text) ...@@ -227,11 +227,11 @@ Command *parse_command(Command_factory *factory, const char *text)
get_word(&text, &word_len); get_word(&text, &word_len);
if (word_len) if (word_len)
goto syntax_error; goto syntax_error;
command= (tok2 == TOK_STATUS) ? (Command *) if (tok2 == TOK_STATUS)
factory->new_Show_instance_status(instance_name, command= new Show_instance_status(map, instance_name,
instance_name_len): instance_name_len);
(Command *) else
factory->new_Show_instance_options(instance_name, command= new Show_instance_options(map, instance_name,
instance_name_len); instance_name_len);
break; break;
default: default:
...@@ -252,8 +252,7 @@ Command *parse_command(Command_factory *factory, const char *text) ...@@ -252,8 +252,7 @@ Command *parse_command(Command_factory *factory, const char *text)
/* check that this is the end of the command */ /* check that this is the end of the command */
if (word_len) if (word_len)
goto syntax_error; goto syntax_error;
command= (Command *) command= new Show_instance_log_files(map, instance_name,
factory->new_Show_instance_log_files(instance_name,
instance_name_len); instance_name_len);
break; break;
case TOK_ERROR: case TOK_ERROR:
...@@ -288,22 +287,16 @@ Command *parse_command(Command_factory *factory, const char *text) ...@@ -288,22 +287,16 @@ Command *parse_command(Command_factory *factory, const char *text)
get_word(&text, &word_len); get_word(&text, &word_len);
if (!word_len) if (!word_len)
goto syntax_error; goto syntax_error;
command= (Command *) command= new Show_instance_log(map, instance_name,
factory->new_Show_instance_log(instance_name, instance_name_len, log_type,
instance_name_len, log_size, text);
log_type,
log_size,
text);
//get_text_id(&text, &log_size_len, &log_size); //get_text_id(&text, &log_size_len, &log_size);
break; break;
case '\0': case '\0':
command= (Command *) command= new Show_instance_log(map, instance_name,
factory->new_Show_instance_log(instance_name, instance_name_len, log_type,
instance_name_len, log_size, NULL);
log_type,
log_size,
NULL);
break; /* this is ok */ break; /* this is ok */
default: default:
goto syntax_error; goto syntax_error;
...@@ -324,7 +317,7 @@ Command *parse_command(Command_factory *factory, const char *text) ...@@ -324,7 +317,7 @@ Command *parse_command(Command_factory *factory, const char *text)
break; break;
default: default:
syntax_error: syntax_error:
command= factory->new_Syntax_error(); command= new Syntax_error();
} }
return command; return command;
} }
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#include <my_sys.h> #include <my_sys.h>
class Command; class Command;
class Command_factory; class Instance_map;
enum Log_type enum Log_type
{ {
...@@ -29,7 +29,7 @@ enum Log_type ...@@ -29,7 +29,7 @@ enum Log_type
IM_LOG_SLOW IM_LOG_SLOW
}; };
Command *parse_command(Command_factory *factory, const char *text); Command *parse_command(Instance_map *instance_map, const char *text);
/* define kinds of the word seek method */ /* define kinds of the word seek method */
enum { ALPHANUM= 1, NONSPACE }; enum { ALPHANUM= 1, NONSPACE };
...@@ -62,5 +62,4 @@ inline void get_word(const char **text, uint *word_len, ...@@ -62,5 +62,4 @@ inline void get_word(const char **text, uint *word_len,
*word_len= word_end - *text; *word_len= word_end - *text;
} }
#endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_PARSE_H */ #endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_PARSE_H */
...@@ -43,8 +43,8 @@ ...@@ -43,8 +43,8 @@
if flag is GET_VALUE. Return the rest of the parsed string otherwise. if flag is GET_VALUE. Return the rest of the parsed string otherwise.
RETURN RETURN
0 - ok 0 - ok, the word has been found
1 - error occured 1 - error occured or the word is not found
*/ */
int parse_output_and_get_value(const char *command, const char *word, int parse_output_and_get_value(const char *command, const char *word,
...@@ -56,9 +56,15 @@ int parse_output_and_get_value(const char *command, const char *word, ...@@ -56,9 +56,15 @@ int parse_output_and_get_value(const char *command, const char *word,
/* should be enough to store the string from the output */ /* should be enough to store the string from the output */
enum { MAX_LINE_LEN= 512 }; enum { MAX_LINE_LEN= 512 };
char linebuf[MAX_LINE_LEN]; char linebuf[MAX_LINE_LEN];
int rc= 1;
wordlen= strlen(word); wordlen= strlen(word);
/*
Successful return of popen does not tell us whether the command has been
executed successfully: if the command was not found, we'll get EOF
when reading the output buffer below.
*/
if (!(output= popen(command, "r"))) if (!(output= popen(command, "r")))
goto err; goto err;
...@@ -95,10 +101,9 @@ int parse_output_and_get_value(const char *command, const char *word, ...@@ -95,10 +101,9 @@ int parse_output_and_get_value(const char *command, const char *word,
strmake(result, linep, found_word_len); strmake(result, linep, found_word_len);
} }
else /* currently there are only two options */ else /* currently there are only two options */
{
strmake(result, linep, input_buffer_len - 1); strmake(result, linep, input_buffer_len - 1);
} rc= 0;
goto pclose; break;
} }
} }
...@@ -106,9 +111,7 @@ pclose: ...@@ -106,9 +111,7 @@ pclose:
/* we are not interested in the termination status */ /* we are not interested in the termination status */
pclose(output); pclose(output);
return 0;
err: err:
return 1; return rc;
} }
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#define SIGKILL 9 #define SIGKILL 9
#define SHUT_RDWR 0x2 #define SHUT_RDWR 0x2
//TODO: fix this /*TODO: fix this */
#define DEFAULT_MONITORING_INTERVAL 20 #define DEFAULT_MONITORING_INTERVAL 20
#define DEFAULT_PORT 2273 #define DEFAULT_PORT 2273
#define PROTOCOL_VERSION 10 #define PROTOCOL_VERSION 10
......
/* Copyright (C) 2003 MySQL AB & MySQL Finland AB & TCX DataKonsult AB /* cOPYRIght (C) 2003 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
...@@ -122,11 +122,10 @@ void Thread_registry::unregister_thread(Thread_info *info) ...@@ -122,11 +122,10 @@ void Thread_registry::unregister_thread(Thread_info *info)
*/ */
int Thread_registry::cond_wait(Thread_info *info, pthread_cond_t *cond, int Thread_registry::cond_wait(Thread_info *info, pthread_cond_t *cond,
pthread_mutex_t *mutex, bool *is_shutdown) pthread_mutex_t *mutex)
{ {
pthread_mutex_lock(&LOCK_thread_registry); pthread_mutex_lock(&LOCK_thread_registry);
*is_shutdown= shutdown_in_progress; if (shutdown_in_progress)
if (*is_shutdown)
{ {
pthread_mutex_unlock(&LOCK_thread_registry); pthread_mutex_unlock(&LOCK_thread_registry);
return 0; return 0;
...@@ -137,7 +136,27 @@ int Thread_registry::cond_wait(Thread_info *info, pthread_cond_t *cond, ...@@ -137,7 +136,27 @@ int Thread_registry::cond_wait(Thread_info *info, pthread_cond_t *cond,
int rc= pthread_cond_wait(cond, mutex); int rc= pthread_cond_wait(cond, mutex);
pthread_mutex_lock(&LOCK_thread_registry); pthread_mutex_lock(&LOCK_thread_registry);
info->current_cond= 0; info->current_cond= 0;
*is_shutdown= shutdown_in_progress; pthread_mutex_unlock(&LOCK_thread_registry);
return rc;
}
int Thread_registry::cond_timedwait(Thread_info *info, pthread_cond_t *cond,
pthread_mutex_t *mutex,
struct timespec *wait_time)
{
pthread_mutex_lock(&LOCK_thread_registry);
if (shutdown_in_progress)
{
pthread_mutex_unlock(&LOCK_thread_registry);
return 0;
}
info->current_cond= cond;
pthread_mutex_unlock(&LOCK_thread_registry);
/* sic: race condition here, cond can be signaled in deliver_shutdown */
int rc= pthread_cond_timedwait(cond, mutex, wait_time);
pthread_mutex_lock(&LOCK_thread_registry);
info->current_cond= 0;
pthread_mutex_unlock(&LOCK_thread_registry); pthread_mutex_unlock(&LOCK_thread_registry);
return rc; return rc;
} }
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
stop all running threads, cleanup and exit. stop all running threads, cleanup and exit.
Note, that a thread can't be shut down nicely if it doesn't want to be. Note, that a thread can't be shut down nicely if it doesn't want to be.
That's why to perform clean shutdown, all threads consituting a process That's why to perform clean shutdown, all threads constituting a process
must observe certain rules. Here we use the rules, described in Butenhof must observe certain rules. Here we use the rules, described in Butenhof
book 'Programming with POSIX threads', namely: book 'Programming with POSIX threads', namely:
- all user signals are handled in 'signal thread' in synchronous manner - all user signals are handled in 'signal thread' in synchronous manner
...@@ -94,7 +94,9 @@ public: ...@@ -94,7 +94,9 @@ public:
void request_shutdown(); void request_shutdown();
inline bool is_shutdown(); inline bool is_shutdown();
int cond_wait(Thread_info *info, pthread_cond_t *cond, int cond_wait(Thread_info *info, pthread_cond_t *cond,
pthread_mutex_t *mutex, bool *is_shutdown); pthread_mutex_t *mutex);
int cond_timedwait(Thread_info *info, pthread_cond_t *cond,
pthread_mutex_t *mutex, struct timespec *wait_time);
private: private:
Thread_info head; Thread_info head;
bool shutdown_in_progress; bool shutdown_in_progress;
......
...@@ -128,7 +128,7 @@ int User_map::load(const char *password_file_name) ...@@ -128,7 +128,7 @@ int User_map::load(const char *password_file_name)
char line[USERNAME_LENGTH + SCRAMBLED_PASSWORD_CHAR_LENGTH + char line[USERNAME_LENGTH + SCRAMBLED_PASSWORD_CHAR_LENGTH +
2 + /* for possible quotes */ 2 + /* for possible quotes */
1 + /* for ':' */ 1 + /* for ':' */
1 + /* for newline */ 2 + /* for newline */
1]; /* for trailing zero */ 1]; /* for trailing zero */
User *user; User *user;
int rc= 1; int rc= 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment