mirror of
https://github.com/MariaDB/server.git
synced 2025-01-22 14:54:20 +01:00
8b4fcf6e3b
- WL#3158: IM: Instance configuration extensions; - WL#3159: IM: --bootstrap and --start-default-instance modes The following new statements have been added: - CREATE INSTANCE; - DROP INSTANCE; The behaviour of the following statements have been changed: - SET; - UNSET; - FLUSH INSTANCES; - SHOW INSTANCES; - SHOW INSTANCE OPTIONS; BitKeeper/deleted/.del-im_options_set.imtest~b53d9d60e5684833: Delete: mysql-test/t/im_options_set.imtest BitKeeper/deleted/.del-im_options_set.result~59278f56be61d921: Delete: mysql-test/r/im_options_set.result BitKeeper/deleted/.del-im_options_unset.imtest~768eb186b51d0048: Delete: mysql-test/t/im_options_unset.imtest BitKeeper/deleted/.del-im_options_unset.result~20a4790cd3c70a4f: Delete: mysql-test/r/im_options_unset.result client/get_password.c: Change prototype to avoid casting when using C-strings (char *). include/m_string.h: Moved LEX_STRING to global header from sql/ to be accessible from all components (IM for one). include/my_sys.h: Added constants for modify_defaults_file(). include/mysql_com.h: Removed duplicated declarations. my_sys.h should be used instead. libmysql/get_password.c: Change prototype to avoid casting when using C-strings (char *). mysql-test/mysql-test-run.pl: Added environment variables to be used from tests. mysql-test/r/im_daemon_life_cycle.result: Column name has been changed in SHOW INSTANCES. mysql-test/r/im_life_cycle.result: 1. Column name has been changed in SHOW INSTANCES. 2. Removed redundant SHOW INSTANCE STATUS statements. mysql-test/r/im_utils.result: Updated the result file. mysql-test/t/im_daemon_life_cycle-im.opt: Set minimal monitoring interval for Instance Manager to speed up testing. mysql-test/t/im_daemon_life_cycle.imtest: Get Instance Manager and managed mysqld-instances enough time to start. mysql-test/t/im_life_cycle.imtest: 1. Polishing; 2. Fixed a test error in 1.1.2. mysql-test/t/im_utils.imtest: Get Instance Manager and managed mysqld-instances enough time to start. mysys/default.c: Pass the name of the section to the handler function as well. mysys/default_modify.c: Added REMOVE_SECTION functionality. server-tools/instance-manager/IMService.cpp: Polishing: be more verbose. server-tools/instance-manager/IMService.h: Polishing: added copyright. server-tools/instance-manager/Makefile.am: Added new files. server-tools/instance-manager/WindowsService.cpp: Polishing: according to The Coding Style, TRUE/FALSE must be used instead of true/false. server-tools/instance-manager/WindowsService.h: Polishing: added copyright. server-tools/instance-manager/command.h: Polishing: provide a comment for the main operation of "Command" class. server-tools/instance-manager/commands.cc: 1. Added support for CREATE INSTANCE, DROP INSTANCE statements; 2. Added "deprecated" column in output of SHOW INSTANCE OPTIONS; 3. Modified the behaviour of SET/UNSET, FLUSH INSTANCES statements; server-tools/instance-manager/commands.h: 1. Added support for CREATE INSTANCE, DROP INSTANCE statements; 2. Added "deprecated" column in output of SHOW INSTANCE OPTIONS; 3. Modified the behaviour of SET/UNSET, FLUSH INSTANCES statements; server-tools/instance-manager/guardian.cc: Added operations to retrieve state of managed instances. server-tools/instance-manager/guardian.h: Added operations to retrieve state of managed instances. server-tools/instance-manager/instance.cc: 1. Provided an operation to check validity of instance name. 2. Added an attribute to distiguish mysqld-instances, whose configuration should be kept backward-compatible. server-tools/instance-manager/instance.h: 1. Provided an operation to check validity of instance name. 2. Added an attribute to distiguish mysqld-instances, whose configuration should be kept backward-compatible. server-tools/instance-manager/instance_map.cc: 1. Used the operation to check validity of instance name; 2. Added operations to manage instances. server-tools/instance-manager/instance_map.h: Added operations to manage instances. server-tools/instance-manager/instance_options.cc: Changed Instance_options so that it will be possible to manage options on the fly. server-tools/instance-manager/instance_options.h: Changed Instance_options so that it will be possible to manage options on the fly. server-tools/instance-manager/listener.cc: 1. Remove reference to the instance of Options; 2. Use new Options naming scheme. server-tools/instance-manager/listener.h: Remove reference to the instance of Options; server-tools/instance-manager/log.cc: Polishing: use TRUE/FALSE instead of true/false. server-tools/instance-manager/manager.cc: Added a common for IM operation to work with configuration file. server-tools/instance-manager/manager.h: Added a common for IM operation to work with configuration file. server-tools/instance-manager/messages.cc: Added messages for new errors. server-tools/instance-manager/mysql_connection.cc: 1. Move a constant to common place. 2. Polishing. server-tools/instance-manager/mysql_manager_error.h: Added new errors. server-tools/instance-manager/mysqlmanager.cc: 1. Use error code from Options::load(); 2. Eliminate type-casting warning on Windows. server-tools/instance-manager/options.cc: Added support for user-management command-line options. server-tools/instance-manager/options.h: Added support for user-management command-line options. server-tools/instance-manager/parse.cc: 1. Added support of new statements: - CREATE INSTANCE; - DROP INSTANCE. 2. Modified SET/UNSET. server-tools/instance-manager/parse.h: 1. Added support of new statements: - CREATE INSTANCE; - DROP INSTANCE. 2. Modified SET/UNSET. server-tools/instance-manager/parse_output.cc: Sorted out header files. server-tools/instance-manager/parse_output.h: Sorted out header files. server-tools/instance-manager/portability.h: 1. Added constants for Windows. 2. Moved system-dependent defines from instance_options.cc. server-tools/instance-manager/priv.cc: Updated version. server-tools/instance-manager/priv.h: Added some global constants. server-tools/instance-manager/protocol.cc: Replaced NAME_WITH_LENGTH by LEX_STRING. server-tools/instance-manager/protocol.h: Replaced NAME_WITH_LENGTH by LEX_STRING. server-tools/instance-manager/thread_registry.cc: Polishing: use TRUE/FALSE instead of true/false. server-tools/instance-manager/user_map.cc: Added support for managing password database. server-tools/instance-manager/user_map.h: Added support for managing password database. sql/sp.cc: Replaced LEX_STRING_WITH_INIT by LEX_STRING + struct initialization. sql/sp_head.cc: Replaced LEX_STRING_WITH_INIT by LEX_STRING + struct initialization. sql/spatial.cc: Removed LEX_STRING_WITH_INIT. sql/spatial.h: Removed LEX_STRING_WITH_INIT. sql/sql_string.h: Moved STRING_WITH_LEN() macro out from sql (to m_string.h). sql/sql_trigger.cc: Moved STRING_WITH_LEN() macro out from sql (to m_string.h). sql/structs.h: Removed LEX_STRING_WITH_INIT. support-files/mysql.server.sh: Instruct Instance Manager to work in mysqld-safe compatible mode for backward compatibility. mysql-test/r/im_cmd_line.result: Added result file. mysql-test/r/im_instance_conf.result: Added result file. mysql-test/r/im_options.result: Added result file. mysql-test/t/im_cmd_line.imtest: IM command-line options test. mysql-test/t/im_instance_conf-im.opt: Set minimal monitoring interval for Instance Manager to speed up testing. mysql-test/t/im_instance_conf.imtest: Added a new test case for checking instance-management. mysql-test/t/im_life_cycle-im.opt: Set minimal monitoring interval for Instance Manager to speed up testing. mysql-test/t/im_options.imtest: Join im_options_set and im_options_unset and add new tests. mysql-test/t/im_utils-im.opt: Set minimal monitoring interval for Instance Manager to speed up testing. server-tools/instance-manager/exit_codes.h: New file for defining exit codes for user-management mode. server-tools/instance-manager/user_management_commands.cc: User-management commands implementation. server-tools/instance-manager/user_management_commands.h: User-management command declarations.
626 lines
17 KiB
C++
626 lines
17 KiB
C++
/* 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 */
|
|
|
|
#if defined(__GNUC__) && defined(USE_PRAGMA_IMPLEMENTATION)
|
|
#pragma implementation
|
|
#endif
|
|
|
|
#include "instance_map.h"
|
|
|
|
#include <my_global.h>
|
|
#include <m_ctype.h>
|
|
#include <mysql_com.h>
|
|
#include <m_string.h>
|
|
|
|
#include "buffer.h"
|
|
#include "guardian.h"
|
|
#include "instance.h"
|
|
#include "log.h"
|
|
#include "manager.h"
|
|
#include "mysqld_error.h"
|
|
#include "mysql_manager_error.h"
|
|
#include "options.h"
|
|
#include "priv.h"
|
|
|
|
/*
|
|
Note: As we are going to suppost different types of connections,
|
|
we shouldn't have connection-specific functions. To avoid it we could
|
|
put such functions to the Command-derived class instead.
|
|
The command could be easily constructed for a specific connection if
|
|
we would provide a special factory for each connection.
|
|
*/
|
|
|
|
C_MODE_START
|
|
|
|
/* Procedure needed for HASH initialization */
|
|
|
|
static byte* get_instance_key(const byte* u, uint* len,
|
|
my_bool __attribute__((unused)) t)
|
|
{
|
|
const Instance *instance= (const Instance *) u;
|
|
*len= instance->options.instance_name.length;
|
|
return (byte *) instance->options.instance_name.str;
|
|
}
|
|
|
|
static void delete_instance(void *u)
|
|
{
|
|
Instance *instance= (Instance *) u;
|
|
delete instance;
|
|
}
|
|
|
|
/*
|
|
The option handler to pass to the process_default_option_files finction.
|
|
|
|
SYNOPSYS
|
|
process_option()
|
|
ctx Handler context. Here it is an instance_map structure.
|
|
group_name The name of the group the option belongs to.
|
|
option The very option to be processed. It is already
|
|
prepared to be used in argv (has -- prefix)
|
|
|
|
DESCRIPTION
|
|
|
|
This handler checks whether a group is an instance group and adds
|
|
an option to the appropriate instance class. If this is the first
|
|
occurence of an instance name, we'll also create the instance
|
|
with such name and add it to the instance map.
|
|
|
|
RETURN
|
|
0 - ok
|
|
1 - error occured
|
|
*/
|
|
|
|
static int process_option(void *ctx, const char *group, const char *option)
|
|
{
|
|
Instance_map *map= (Instance_map*) ctx;
|
|
LEX_STRING group_str;
|
|
|
|
group_str.str= (char *) group;
|
|
group_str.length= strlen(group);
|
|
|
|
return map->process_one_option(&group_str, option);
|
|
}
|
|
|
|
C_MODE_END
|
|
|
|
|
|
/*
|
|
Parse option string.
|
|
|
|
SYNOPSIS
|
|
parse_option()
|
|
option_str [IN] option string (e.g. "--name=value")
|
|
option_name_buf [OUT] parsed name of the option.
|
|
Must be of (MAX_OPTION_LEN + 1) size.
|
|
option_value_buf [OUT] parsed value of the option.
|
|
Must be of (MAX_OPTION_LEN + 1) size.
|
|
|
|
DESCRIPTION
|
|
This is an auxiliary function and should not be used externally. It is
|
|
intended to parse whole option string into option name and option value.
|
|
*/
|
|
|
|
static void parse_option(const char *option_str,
|
|
char *option_name_buf,
|
|
char *option_value_buf)
|
|
{
|
|
char *eq_pos;
|
|
const char *ptr= option_str;
|
|
|
|
while (*ptr == '-')
|
|
++ptr;
|
|
|
|
strmake(option_name_buf, ptr, MAX_OPTION_LEN + 1);
|
|
|
|
eq_pos= strchr(ptr, '=');
|
|
if (eq_pos)
|
|
{
|
|
option_name_buf[eq_pos - ptr]= 0;
|
|
strmake(option_value_buf, eq_pos + 1, MAX_OPTION_LEN + 1);
|
|
}
|
|
else
|
|
{
|
|
option_value_buf[0]= 0;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
Process one option from the configuration file.
|
|
|
|
SYNOPSIS
|
|
Instance_map::process_one_option()
|
|
group group name
|
|
option option string (e.g. "--name=value")
|
|
|
|
DESCRIPTION
|
|
This is an auxiliary function and should not be used externally.
|
|
It is used only by flush_instances(), which pass it to
|
|
process_option(). The caller ensures proper locking
|
|
of the instance map object.
|
|
*/
|
|
|
|
int Instance_map::process_one_option(const LEX_STRING *group,
|
|
const char *option)
|
|
{
|
|
Instance *instance= NULL;
|
|
|
|
if (!Instance::is_name_valid(group))
|
|
{
|
|
/*
|
|
Current section name is not a valid instance name.
|
|
We should skip it w/o error.
|
|
*/
|
|
return 0;
|
|
}
|
|
|
|
if (!(instance= (Instance *) hash_search(&hash, (byte *) group->str,
|
|
group->length)))
|
|
{
|
|
if (!(instance= new Instance()))
|
|
return 1;
|
|
|
|
if (instance->init(group) || add_instance(instance))
|
|
{
|
|
delete instance;
|
|
return 1;
|
|
}
|
|
|
|
if (instance->is_mysqld_compatible())
|
|
log_info("Warning: instance name '%s' is mysqld-compatible.",
|
|
(const char *) group->str);
|
|
|
|
log_info("mysqld instance '%s' has been added successfully.",
|
|
(const char *) group->str);
|
|
}
|
|
|
|
if (option)
|
|
{
|
|
char option_name[MAX_OPTION_LEN + 1];
|
|
char option_value[MAX_OPTION_LEN + 1];
|
|
|
|
parse_option(option, option_name, option_value);
|
|
|
|
if (instance->is_mysqld_compatible() &&
|
|
Instance_options::is_option_im_specific(option_name))
|
|
{
|
|
log_info("Warning: configuration of mysqld-compatible instance '%s' "
|
|
"contains IM-specific option '%s'. "
|
|
"This breaks backward compatibility for the configuration file.",
|
|
(const char *) group->str,
|
|
(const char *) option_name);
|
|
}
|
|
|
|
Named_value option(option_name, option_value);
|
|
|
|
if (instance->options.set_option(&option))
|
|
return 1; /* the instance'll be deleted when we destroy the map */
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
Instance_map::Instance_map(const char *default_mysqld_path_arg):
|
|
mysqld_path(default_mysqld_path_arg)
|
|
{
|
|
pthread_mutex_init(&LOCK_instance_map, 0);
|
|
}
|
|
|
|
|
|
int Instance_map::init()
|
|
{
|
|
return hash_init(&hash, default_charset_info, START_HASH_SIZE, 0, 0,
|
|
get_instance_key, delete_instance, 0);
|
|
}
|
|
|
|
Instance_map::~Instance_map()
|
|
{
|
|
pthread_mutex_lock(&LOCK_instance_map);
|
|
hash_free(&hash);
|
|
pthread_mutex_unlock(&LOCK_instance_map);
|
|
pthread_mutex_destroy(&LOCK_instance_map);
|
|
}
|
|
|
|
|
|
void Instance_map::lock()
|
|
{
|
|
pthread_mutex_lock(&LOCK_instance_map);
|
|
}
|
|
|
|
|
|
void Instance_map::unlock()
|
|
{
|
|
pthread_mutex_unlock(&LOCK_instance_map);
|
|
}
|
|
|
|
/*
|
|
Re-read instance configuration file.
|
|
|
|
SYNOPSIS
|
|
Instance_map::flush_instances()
|
|
|
|
DESCRIPTION
|
|
This function will:
|
|
- clear the current list of instances. This removes both
|
|
running and stopped instances.
|
|
- load a new instance configuration from the file.
|
|
- pass on the new map to the guardian thread: it will start
|
|
all instances that are marked `guarded' and not yet started.
|
|
Note, as the check whether an instance is started is currently
|
|
very simple (returns TRUE if there is a MySQL server running
|
|
at the given port), this function has some peculiar
|
|
side-effects:
|
|
* if the port number of a running instance was changed, the
|
|
old instance is forgotten, even if it was running. The new
|
|
instance will be started at the new port.
|
|
* if the configuration was changed in a way that two
|
|
instances swapped their port numbers, the guardian thread
|
|
will not notice that and simply report that both instances
|
|
are configured successfully and running.
|
|
In order to avoid such side effects one should never call
|
|
FLUSH INSTANCES without prior stop of all running instances.
|
|
|
|
NOTE: The operation should be invoked with the following locks acquired:
|
|
- Guardian_thread;
|
|
- Instance_map;
|
|
*/
|
|
|
|
int Instance_map::flush_instances()
|
|
{
|
|
int rc;
|
|
|
|
/*
|
|
Guardian thread relies on the instance map repository for guarding
|
|
instances. This is why refreshing instance map, we need (1) to stop
|
|
guardian (2) reload the instance map (3) reinitialize the guardian
|
|
with new instances.
|
|
*/
|
|
hash_free(&hash);
|
|
hash_init(&hash, default_charset_info, START_HASH_SIZE, 0, 0,
|
|
get_instance_key, delete_instance, 0);
|
|
|
|
rc= load();
|
|
guardian->init();
|
|
return rc;
|
|
}
|
|
|
|
|
|
bool Instance_map::is_there_active_instance()
|
|
{
|
|
Instance *instance;
|
|
Iterator iterator(this);
|
|
|
|
while ((instance= iterator.next()))
|
|
{
|
|
if (guardian->find_instance_node(instance) != NULL ||
|
|
instance->is_running())
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
int Instance_map::add_instance(Instance *instance)
|
|
{
|
|
return my_hash_insert(&hash, (byte *) instance);
|
|
}
|
|
|
|
|
|
int Instance_map::remove_instance(Instance *instance)
|
|
{
|
|
return hash_delete(&hash, (byte *) instance);
|
|
}
|
|
|
|
|
|
int Instance_map::create_instance(const LEX_STRING *instance_name,
|
|
const Named_value_arr *options)
|
|
{
|
|
Instance *instance= new Instance();
|
|
|
|
if (!instance)
|
|
{
|
|
log_error("Error: can not initialize (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').",
|
|
(const char *) instance_name->str);
|
|
delete instance;
|
|
return ER_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
for (int i= 0; options && i < options->get_size(); ++i)
|
|
{
|
|
Named_value option= options->get_element(i);
|
|
|
|
if (instance->is_mysqld_compatible() &&
|
|
Instance_options::is_option_im_specific(option.get_name()))
|
|
{
|
|
log_error("Error: IM-option (%s) can not be used "
|
|
"in configuration of mysqld-compatible instance (%s).",
|
|
(const char *) option.get_name(),
|
|
(const char *) instance_name->str);
|
|
delete instance;
|
|
return ER_INCOMPATIBLE_OPTION;
|
|
}
|
|
|
|
instance->options.set_option(&option);
|
|
}
|
|
|
|
if (instance->is_mysqld_compatible())
|
|
log_info("Warning: instance name '%s' is mysqld-compatible.",
|
|
(const char *) instance_name->str);
|
|
|
|
if (instance->complete_initialization(this, mysqld_path))
|
|
{
|
|
log_error("Error: can not complete initialization of instance (name: '%s').",
|
|
(const char *) instance_name->str);
|
|
delete instance;
|
|
return ER_OUT_OF_RESOURCES;
|
|
/* TODO: return more appropriate error code in this case. */
|
|
}
|
|
|
|
if (add_instance(instance))
|
|
{
|
|
log_error("Error: can not register instance (name: '%s').",
|
|
(const char *) instance_name->str);
|
|
delete instance;
|
|
return ER_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
Instance * Instance_map::find(const LEX_STRING *name)
|
|
{
|
|
return (Instance *) hash_search(&hash, (byte *) name->str, name->length);
|
|
}
|
|
|
|
|
|
bool Instance_map::complete_initialization()
|
|
{
|
|
bool mysqld_found;
|
|
|
|
/* Complete initialization of all registered instances. */
|
|
|
|
for (uint i= 0; i < hash.records; ++i)
|
|
{
|
|
Instance *instance= (Instance *) hash_element(&hash, i);
|
|
|
|
if (instance->complete_initialization(this, mysqld_path))
|
|
return TRUE;
|
|
}
|
|
|
|
/* That's all if we are runnning in an ordinary mode. */
|
|
|
|
if (!Options::Main::mysqld_safe_compatible)
|
|
return FALSE;
|
|
|
|
/* In mysqld-compatible mode we must ensure that there 'mysqld' instance. */
|
|
|
|
mysqld_found= find(&Instance::DFLT_INSTANCE_NAME) != NULL;
|
|
|
|
if (mysqld_found)
|
|
return FALSE;
|
|
|
|
if (create_instance(&Instance::DFLT_INSTANCE_NAME, NULL))
|
|
{
|
|
log_error("Error: could not create default instance.");
|
|
return TRUE;
|
|
}
|
|
|
|
switch (create_instance_in_file(&Instance::DFLT_INSTANCE_NAME, NULL))
|
|
{
|
|
case 0:
|
|
case ER_CONF_FILE_DOES_NOT_EXIST:
|
|
/*
|
|
Continue if the instance has been added to the config file
|
|
successfully, or the config file just does not exist.
|
|
*/
|
|
break;
|
|
|
|
default:
|
|
log_error("Error: could not add default instance to the config file.");
|
|
|
|
Instance *instance= find(&Instance::DFLT_INSTANCE_NAME);
|
|
|
|
if (instance)
|
|
remove_instance(instance); /* instance is deleted here. */
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/* load options from config files and create appropriate instance structures */
|
|
|
|
int Instance_map::load()
|
|
{
|
|
int argc= 1;
|
|
/* this is a dummy variable for search_option_files() */
|
|
uint args_used= 0;
|
|
const char *argv_options[3];
|
|
char **argv= (char **) &argv_options;
|
|
char defaults_file_arg[FN_REFLEN];
|
|
|
|
/* the name of the program may be orbitrary here in fact */
|
|
argv_options[0]= "mysqlmanager";
|
|
|
|
/*
|
|
If the option file was forced by the user when starting
|
|
the IM with --defaults-file=xxxx, make sure it is also
|
|
passed as --defaults-file, not only as Options::config_file.
|
|
This is important for option files given with relative path:
|
|
e.g. --defaults-file=my.cnf.
|
|
Otherwise my_search_option_files will treat "my.cnf" as a group
|
|
name and start looking for files named "my.cnf.cnf" in all
|
|
default dirs. Which is not what we want.
|
|
*/
|
|
if (Options::Main::is_forced_default_file)
|
|
{
|
|
snprintf(defaults_file_arg, FN_REFLEN, "--defaults-file=%s",
|
|
Options::Main::config_file);
|
|
|
|
argv_options[1]= defaults_file_arg;
|
|
argv_options[2]= '\0';
|
|
|
|
argc= 2;
|
|
}
|
|
else
|
|
argv_options[1]= '\0';
|
|
|
|
/*
|
|
If the routine failed, we'll simply fallback to defaults in
|
|
complete_initialization().
|
|
*/
|
|
if (my_search_option_files(Options::Main::config_file, &argc,
|
|
(char ***) &argv, &args_used,
|
|
process_option, (void*) this))
|
|
log_info("Falling back to compiled-in defaults");
|
|
|
|
return complete_initialization();
|
|
}
|
|
|
|
|
|
/*--- Implementaton of the Instance map iterator class ---*/
|
|
|
|
|
|
void Instance_map::Iterator::go_to_first()
|
|
{
|
|
current_instance=0;
|
|
}
|
|
|
|
|
|
Instance *Instance_map::Iterator::next()
|
|
{
|
|
if (current_instance < instance_map->hash.records)
|
|
return (Instance *) hash_element(&instance_map->hash, current_instance++);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
const char *Instance_map::get_instance_state_name(Instance *instance)
|
|
{
|
|
LIST *instance_node;
|
|
|
|
if (!instance->is_configured())
|
|
return "misconfigured";
|
|
|
|
if ((instance_node= guardian->find_instance_node(instance)) != NULL)
|
|
{
|
|
/* The instance is managed by Guardian: we can report precise state. */
|
|
|
|
return Guardian_thread::get_instance_state_name(
|
|
guardian->get_instance_state(instance_node));
|
|
}
|
|
|
|
/* The instance is not managed by Guardian: we can report status only. */
|
|
|
|
return instance->is_running() ? "online" : "offline";
|
|
}
|
|
|
|
|
|
/*
|
|
Create a new configuration section for mysqld-instance in the config file.
|
|
|
|
SYNOPSYS
|
|
create_instance_in_file()
|
|
instance_name mysqld-instance name
|
|
options options for the new mysqld-instance
|
|
|
|
RETURN
|
|
0 On success
|
|
ER_CONF_FILE_DOES_NOT_EXIST If config file does not exist
|
|
ER_ACCESS_OPTION_FILE If config file is not writable or some I/O
|
|
error ocurred during writing configuration
|
|
*/
|
|
|
|
int create_instance_in_file(const LEX_STRING *instance_name,
|
|
const Named_value_arr *options)
|
|
{
|
|
File cnf_file;
|
|
|
|
if (my_access(Options::Main::config_file, W_OK))
|
|
{
|
|
log_error("Error: configuration file (%s) does not exist.",
|
|
(const char *) Options::Main::config_file);
|
|
return ER_CONF_FILE_DOES_NOT_EXIST;
|
|
}
|
|
|
|
cnf_file= my_open(Options::Main::config_file, O_WRONLY | O_APPEND, MYF(0));
|
|
|
|
if (cnf_file <= 0)
|
|
{
|
|
log_error("Error: can not open configuration file (%s): %s.",
|
|
(const char *) Options::Main::config_file,
|
|
(const char *) strerror(errno));
|
|
return ER_ACCESS_OPTION_FILE;
|
|
}
|
|
|
|
if (my_write(cnf_file, (byte*)NEWLINE, NEWLINE_LEN, MYF(MY_NABP)) ||
|
|
my_write(cnf_file, (byte*)"[", 1, MYF(MY_NABP)) ||
|
|
my_write(cnf_file, (byte*)instance_name->str, instance_name->length,
|
|
MYF(MY_NABP)) ||
|
|
my_write(cnf_file, (byte*)"]", 1, MYF(MY_NABP)) ||
|
|
my_write(cnf_file, (byte*)NEWLINE, NEWLINE_LEN, MYF(MY_NABP)))
|
|
{
|
|
log_error("Error: can not write to configuration file (%s): %s.",
|
|
(const char *) Options::Main::config_file,
|
|
(const char *) strerror(errno));
|
|
my_close(cnf_file, MYF(0));
|
|
return ER_ACCESS_OPTION_FILE;
|
|
}
|
|
|
|
for (int i= 0; options && i < options->get_size(); ++i)
|
|
{
|
|
char option_str[MAX_OPTION_STR_LEN];
|
|
char *ptr;
|
|
int option_str_len;
|
|
Named_value option= options->get_element(i);
|
|
|
|
ptr= strxnmov(option_str, MAX_OPTION_LEN + 1, option.get_name(), NullS);
|
|
|
|
if (option.get_value()[0])
|
|
ptr= strxnmov(ptr, MAX_OPTION_LEN + 2, "=", option.get_value(), NullS);
|
|
|
|
option_str_len= ptr - option_str;
|
|
|
|
if (my_write(cnf_file, (byte*)option_str, option_str_len, MYF(MY_NABP)) ||
|
|
my_write(cnf_file, (byte*)NEWLINE, NEWLINE_LEN, MYF(MY_NABP)))
|
|
{
|
|
log_error("Error: can not write to configuration file (%s): %s.",
|
|
(const char *) Options::Main::config_file,
|
|
(const char *) strerror(errno));
|
|
my_close(cnf_file, MYF(0));
|
|
return ER_ACCESS_OPTION_FILE;
|
|
}
|
|
}
|
|
|
|
my_close(cnf_file, MYF(0));
|
|
|
|
return 0;
|
|
}
|