summaryrefslogtreecommitdiff
path: root/server-tools/instance-manager/instance_map.cc
diff options
context:
space:
mode:
Diffstat (limited to 'server-tools/instance-manager/instance_map.cc')
-rw-r--r--server-tools/instance-manager/instance_map.cc649
1 files changed, 0 insertions, 649 deletions
diff --git a/server-tools/instance-manager/instance_map.cc b/server-tools/instance-manager/instance_map.cc
deleted file mode 100644
index b137370b50a..00000000000
--- a/server-tools/instance-manager/instance_map.cc
+++ /dev/null
@@ -1,649 +0,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; version 2 of the License.
-
- 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 "buffer.h"
-#include "instance.h"
-#include "log.h"
-#include "mysqld_error.h"
-#include "mysql_manager_error.h"
-#include "options.h"
-#include "priv.h"
-
-C_MODE_START
-
-/**
- HASH-routines: get key of instance for storing in hash.
-*/
-
-static uchar* get_instance_key(const uchar* u, size_t* len,
- my_bool __attribute__((unused)) t)
-{
- const Instance *instance= (const Instance *) u;
- *len= instance->options.instance_name.length;
- return (uchar *) instance->options.instance_name.str;
-}
-
-/**
- HASH-routines: cleanup handler.
-*/
-
-static void delete_instance(void *u)
-{
- Instance *instance= (Instance *) u;
- delete instance;
-}
-
-/**
- The option handler to pass to the process_default_option_files function.
-
- SYNOPSIS
- 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)
-{
- const 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.
-*/
- /*
- Process a given option and assign it to appropricate instance. This is
- required for the option handler, passed to my_search_option_files().
- */
-
-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, (uchar *) 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 constructor.
-*/
-
-Instance_map::Instance_map()
-{
- pthread_mutex_init(&LOCK_instance_map, 0);
-}
-
-
-/**
- Initialize Instance_map internals.
-*/
-
-bool Instance_map::init()
-{
- return hash_init(&hash, default_charset_info, START_HASH_SIZE, 0, 0,
- get_instance_key, delete_instance, 0);
-}
-
-
-/**
- Reset Instance_map data.
-*/
-
-bool Instance_map::reset()
-{
- hash_free(&hash);
- return init();
-}
-
-
-/**
- Instance_map destructor.
-*/
-
-Instance_map::~Instance_map()
-{
- lock();
-
- /*
- NOTE: it's necessary to synchronize on each instance before removal,
- because Instance-monitoring thread can be still alive an hold the mutex
- (because it is detached and we have no control over it).
- */
-
- while (true)
- {
- Iterator it(this);
- Instance *instance= it.next();
-
- if (!instance)
- break;
-
- instance->lock();
- instance->unlock();
-
- remove_instance(instance);
- }
-
- hash_free(&hash);
- unlock();
-
- pthread_mutex_destroy(&LOCK_instance_map);
-}
-
-
-/**
- Lock Instance_map.
-*/
-
-void Instance_map::lock()
-{
- pthread_mutex_lock(&LOCK_instance_map);
-}
-
-
-/**
- Unlock Instance_map.
-*/
-
-void Instance_map::unlock()
-{
- pthread_mutex_unlock(&LOCK_instance_map);
-}
-
-
-/**
- Check if there is an active instance or not.
-*/
-
-bool Instance_map::is_there_active_instance()
-{
- Instance *instance;
- Iterator iterator(this);
-
- while ((instance= iterator.next()))
- {
- bool active_instance_found;
-
- instance->lock();
- active_instance_found= instance->is_active();
- instance->unlock();
-
- if (active_instance_found)
- return TRUE;
- }
-
- return FALSE;
-}
-
-
-/**
- Add an instance into the internal hash.
-
- MT-NOTE: Instance Map must be locked before calling the operation.
-*/
-
-int Instance_map::add_instance(Instance *instance)
-{
- return my_hash_insert(&hash, (uchar *) instance);
-}
-
-
-/**
- Remove instance from the internal hash.
-
- MT-NOTE: Instance Map must be locked before calling the operation.
-*/
-
-int Instance_map::remove_instance(Instance *instance)
-{
- return hash_delete(&hash, (uchar *) instance);
-}
-
-
-/**
- Create a new instance and register it in the internal hash.
-
- MT-NOTE: Instance Map must be locked before calling the operation.
-*/
-
-int Instance_map::create_instance(const LEX_STRING *instance_name,
- const Named_value_arr *options)
-{
- Instance *instance= new Instance();
-
- if (!instance)
- {
- log_error("Can not allocate instance (name: '%s').",
- (const char *) instance_name->str);
- return ER_OUT_OF_RESOURCES;
- }
-
- if (instance->init(instance_name))
- {
- log_error("Can not initialize instance (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("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())
- {
- log_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("Can not register instance (name: '%s').",
- (const char *) instance_name->str);
- delete instance;
- return ER_OUT_OF_RESOURCES;
- }
-
- return 0;
-}
-
-
-/**
- Return a pointer to the instance or NULL, if there is no such instance.
-
- MT-NOTE: Instance Map must be locked before calling the operation.
-*/
-
-Instance * Instance_map::find(const LEX_STRING *name)
-{
- return (Instance *) hash_search(&hash, (uchar *) name->str, name->length);
-}
-
-
-/**
- Init instances command line arguments after all options have been loaded.
-*/
-
-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())
- 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("Can 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("Can 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,
- Options::default_directories))
- log_info("Falling back to compiled-in defaults.");
-
- return complete_initialization();
-}
-
-
-/*************************************************************************
- {{{ Instance_map::Iterator implementation.
-*************************************************************************/
-
-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;
-}
-
-/*************************************************************************
- }}}
-*************************************************************************/
-
-
-/**
- Create a new configuration section for mysqld-instance in the config file.
-
- SYNOPSIS
- 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("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("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, (uchar*)NEWLINE, NEWLINE_LEN, MYF(MY_NABP)) ||
- my_write(cnf_file, (uchar*)"[", 1, MYF(MY_NABP)) ||
- my_write(cnf_file, (uchar*)instance_name->str, instance_name->length,
- MYF(MY_NABP)) ||
- my_write(cnf_file, (uchar*)"]", 1, MYF(MY_NABP)) ||
- my_write(cnf_file, (uchar*)NEWLINE, NEWLINE_LEN, MYF(MY_NABP)))
- {
- log_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, (uchar*)option_str, option_str_len, MYF(MY_NABP)) ||
- my_write(cnf_file, (uchar*)NEWLINE, NEWLINE_LEN, MYF(MY_NABP)))
- {
- log_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;
-}