summaryrefslogtreecommitdiff
path: root/sql/wsrep_check_opts.cc
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2014-09-28 11:08:07 +0200
committerSergei Golubchik <serg@mariadb.org>2014-10-01 23:48:35 +0200
commit13af416a82796648dffdffbda0da6d60513d7ddf (patch)
tree95fc7d93a25b541d7deae6041255dbcb9cdc9bc4 /sql/wsrep_check_opts.cc
parent425dc6d2fd80531d553e25790f6a6e7e199445f6 (diff)
downloadmariadb-git-13af416a82796648dffdffbda0da6d60513d7ddf.tar.gz
cleanup: wsrep_check_opts
Diffstat (limited to 'sql/wsrep_check_opts.cc')
-rw-r--r--sql/wsrep_check_opts.cc405
1 files changed, 64 insertions, 341 deletions
diff --git a/sql/wsrep_check_opts.cc b/sql/wsrep_check_opts.cc
index 5ec18c79978..a4c12e7deb2 100644
--- a/sql/wsrep_check_opts.cc
+++ b/sql/wsrep_check_opts.cc
@@ -1,4 +1,5 @@
/* Copyright 2011 Codership Oy <http://www.codership.com>
+ Copyright 2014 SkySQL 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
@@ -13,367 +14,89 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-//#include <mysqld.h>
-#include <sql_class.h>
-//#include <sql_plugin.h>
-//#include <set_var.h>
+#include "mysqld.h"
+#include "sys_vars_shared.h"
+#include "wsrep.h"
+#include "wsrep_sst.h"
+//#include <sql_class.h>
+//#include "wsrep_mysqld.h"
-#include "wsrep_mysqld.h"
+extern char *my_bind_addr_str;
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <ctype.h>
-
-/* This file is about checking for correctness of mysql configuration options */
-
-struct opt
-{
- const char* const name;
- const char* value;
-};
-
-/* A list of options to check.
- * At first we assume default values and then see if they are changed on CLI or
- * in my.cnf */
-static struct opt opts[] =
-{
- { "wsrep_slave_threads", "1" }, // mysqld.cc
- { "bind_address", "0.0.0.0" }, // mysqld.cc
- { "wsrep_sst_method", "rsync" }, // mysqld.cc
- { "wsrep_sst_receive_address","AUTO"}, // mysqld.cc
- { "binlog_format", "ROW" }, // mysqld.cc
- { "wsrep_provider", "none" }, // mysqld.cc
- { "query_cache_type", "0" }, // mysqld.cc
- { "query_cache_size", "0" }, // mysqld.cc
- { "locked_in_memory", "0" }, // mysqld.cc
- { "wsrep_cluster_address", "0" }, // mysqld.cc
- { "locks_unsafe_for_binlog", "0" }, // ha_innodb.cc
- { "autoinc_lock_mode", "1" }, // ha_innodb.cc
- { 0, 0 }
-};
-
-enum
-{
- WSREP_SLAVE_THREADS,
- BIND_ADDRESS,
- WSREP_SST_METHOD,
- WSREP_SST_RECEIVE_ADDRESS,
- BINLOG_FORMAT,
- WSREP_PROVIDER,
- QUERY_CACHE_TYPE,
- QUERY_CACHE_SIZE,
- LOCKED_IN_MEMORY,
- WSREP_CLUSTER_ADDRESS,
- LOCKS_UNSAFE_FOR_BINLOG,
- AUTOINC_LOCK_MODE
-};
-
-
-/* A class to make a copy of argv[] vector */
-struct argv_copy
-{
- int const argc_;
- char** argv_;
-
- argv_copy (int const argc, const char* const argv[]) :
- argc_ (argc),
- argv_ (reinterpret_cast<char**>(calloc(argc_, sizeof(char*))))
- {
- if (argv_)
- {
- for (int i = 0; i < argc_; ++i)
- {
- argv_[i] = strdup(argv[i]);
-
- if (!argv_[i])
- {
- argv_free (); // free whatever bee allocated
- return;
- }
- }
- }
- }
-
- ~argv_copy () { argv_free (); }
-
-private:
- argv_copy (const argv_copy&);
- argv_copy& operator= (const argv_copy&);
-
- void argv_free()
- {
- if (argv_)
- {
- for (int i = 0; (i < argc_) && argv_[i] ; ++i) free (argv_[i]);
- free (argv_);
- argv_ = 0;
- }
- }
-};
-
-/* a short corresponding to '--' byte sequence */
-static short const long_opt_prefix ('-' + ('-' << 8));
-
-/* Normalizes long options to have '_' instead of '-' */
-static int
-normalize_opts (argv_copy& a)
+int wsrep_check_opts()
{
- if (a.argv_)
+ if (wsrep_slave_threads > 1)
+ {
+ sys_var *autoinc_lock_mode=
+ intern_find_sys_var(STRING_WITH_LEN("innodb_autoinc_lock_mode"));
+ bool is_null;
+ if (autoinc_lock_mode &&
+ autoinc_lock_mode->val_int(&is_null, 0, OPT_GLOBAL, 0) != 2)
{
- for (int i = 0; i < a.argc_; ++i)
- {
- char* ptr = a.argv_[i];
- if (long_opt_prefix == *(short*)ptr) // long option
- {
- ptr += 2;
- const char* end = strchr(ptr, '=');
-
- if (!end) end = ptr + strlen(ptr);
-
- for (; ptr != end; ++ptr) if ('-' == *ptr) *ptr = '_';
- }
- }
-
- return 0;
+ WSREP_ERROR("Parallel applying (wsrep_slave_threads > 1) requires"
+ " innodb_autoinc_lock_mode = 2.");
+ return 1;
}
- return EINVAL;
-}
-
-/* Find required options in the argument list and change their values */
-static int
-find_opts (argv_copy& a, struct opt* const opts)
-{
- for (int i = 0; i < a.argc_; ++i)
- {
- char* ptr = a.argv_[i] + 2; // we're interested only in long options
-
- struct opt* opt = opts;
- for (; 0 != opt->name; ++opt)
- {
- if (!strstr(ptr, opt->name)) continue; // try next option
-
- /* 1. try to find value after the '=' */
- opt->value = strchr(ptr, '=') + 1;
-
- /* 2. if no '=', try next element in the argument vector */
- if (reinterpret_cast<void*>(1) == opt->value)
- {
- /* also check that the next element is not an option itself */
- if (i + 1 < a.argc_ && *(a.argv_[i + 1]) != '-')
- {
- ++i;
- opt->value = a.argv_[i];
- }
- else opt->value = ""; // no value supplied (like boolean opt)
- }
-
- break; // option found, break inner loop
- }
- }
-
- return 0;
-}
-
-/* Parses string for an integer. Returns 0 on success. */
-int get_long_long (const struct opt& opt, long long* const val, int const base)
-{
- const char* const str = opt.value;
-
- if ('\0' != *str)
- {
- char* endptr;
-
- *val = strtoll (str, &endptr, base);
-
- if ('k' == *endptr || 'K' == *endptr)
- {
- *val *= 1024L;
- endptr++;
- }
- else if ('m' == *endptr || 'M' == *endptr)
- {
- *val *= 1024L * 1024L;
- endptr++;
- }
- else if ('g' == *endptr || 'G' == *endptr)
- {
- *val *= 1024L * 1024L * 1024L;
- endptr++;
- }
-
- if ('\0' == *endptr) return 0; // the whole string was a valid integer
- }
-
- WSREP_ERROR ("Bad value for *%s: '%s'. Should be integer.",
- opt.name, opt.value);
-
- return EINVAL;
-}
-
-/* This is flimzy coz hell knows how mysql interprets boolean strings...
- * and, no, I'm not going to become versed in how mysql handles options -
- * I'd rather sing.
-
- Aha, http://dev.mysql.com/doc/refman/5.1/en/dynamic-system-variables.html:
- Variables that have a type of “boolean” can be set to 0, 1, ON or OFF. (If you
- set them on the command line or in an option file, use the numeric values.)
-
- So it is '0' for FALSE, '1' or empty string for TRUE
-
- */
-int get_bool (const struct opt& opt, bool* const val)
-{
- const char* str = opt.value;
-
- while (isspace(*str)) ++str; // skip initial whitespaces
-
- ssize_t str_len = strlen(str);
- switch (str_len)
- {
- case 0:
- *val = true;
- return 0;
- case 1:
- if ('0' == *str || '1' == *str)
- {
- *val = ('1' == *str);
- return 0;
- }
- }
-
- WSREP_ERROR ("Bad value for *%s: '%s'. Should be '0', '1' or empty string.",
- opt.name, opt.value);
-
- return EINVAL;
-}
-
-static int
-check_opts (int const argc, const char* const argv[], struct opt opts[])
-{
- /* First, make a copy of argv to be able to manipulate it */
- argv_copy a(argc, argv);
-
- if (!a.argv_)
- {
- WSREP_ERROR ("Could not copy argv vector: not enough memory.");
- return ENOMEM;
- }
-
- int err = normalize_opts (a);
- if (err)
- {
- WSREP_ERROR ("Failed to normalize options.");
- return err;
- }
-
- err = find_opts (a, opts);
- if (err)
- {
- WSREP_ERROR ("Failed to parse options.");
- return err;
- }
-
- /* At this point we have updated default values in our option list to
- what has been specified on the command line / my.cnf */
-
- long long slave_threads;
- err = get_long_long (opts[WSREP_SLAVE_THREADS], &slave_threads, 10);
- if (err) return err;
-
- int rcode = 0;
-
- if (slave_threads > 1)
- /* Need to check AUTOINC_LOCK_MODE and LOCKS_UNSAFE_FOR_BINLOG */
- {
- long long autoinc_lock_mode;
- err = get_long_long (opts[AUTOINC_LOCK_MODE], &autoinc_lock_mode, 10);
- if (err) return err;
-
- bool locks_unsafe_for_binlog;
- err = get_bool (opts[LOCKS_UNSAFE_FOR_BINLOG],&locks_unsafe_for_binlog);
- if (err) return err;
-
- if (autoinc_lock_mode != 2)
- {
- WSREP_ERROR ("Parallel applying (wsrep_slave_threads > 1) requires"
- " innodb_autoinc_lock_mode = 2.");
- rcode = EINVAL;
- }
- }
-
- bool locked_in_memory;
- err = get_bool (opts[LOCKED_IN_MEMORY], &locked_in_memory);
- if (err) { WSREP_ERROR("get_bool error: %s", strerror(err)); return err; }
if (locked_in_memory)
{
- WSREP_ERROR ("Memory locking is not supported (locked_in_memory=%s)",
- locked_in_memory ? "ON" : "OFF");
- rcode = EINVAL;
+ WSREP_ERROR("Memory locking is not supported (locked_in_memory=ON)");
+ return 1;
}
- if (!strcasecmp(opts[WSREP_SST_METHOD].value,"mysqldump"))
+ if (!strcasecmp(wsrep_sst_method, "mysqldump"))
{
- if (!strcasecmp(opts[BIND_ADDRESS].value, "127.0.0.1") ||
- !strcasecmp(opts[BIND_ADDRESS].value, "localhost"))
- {
- WSREP_ERROR ("wsrep_sst_method is set to 'mysqldump' yet "
- "mysqld bind_address is set to '%s', which makes it "
- "impossible to receive state transfer from another "
- "node, since mysqld won't accept such connections. "
- "If you wish to use mysqldump state transfer method, "
- "set bind_address to allow mysql client connections "
- "from other cluster members (e.g. 0.0.0.0).",
- opts[BIND_ADDRESS].value);
- rcode = EINVAL;
- }
+ if (!strcasecmp(my_bind_addr_str, "127.0.0.1") ||
+ !strcasecmp(my_bind_addr_str, "localhost"))
+ {
+ WSREP_ERROR("wsrep_sst_method is set to 'mysqldump' yet "
+ "mysqld bind_address is set to '%s', which makes it "
+ "impossible to receive state transfer from another "
+ "node, since mysqld won't accept such connections. "
+ "If you wish to use mysqldump state transfer method, "
+ "set bind_address to allow mysql client connections "
+ "from other cluster members (e.g. 0.0.0.0).",
+ my_bind_addr_str);
+ return 1;
+ }
}
else
{
- // non-mysqldump SST requires wsrep_cluster_address on startup
- if (strlen(opts[WSREP_CLUSTER_ADDRESS].value) == 0)
- {
- WSREP_ERROR ("%s SST method requires wsrep_cluster_address to be "
- "configured on startup.",opts[WSREP_SST_METHOD].value);
- rcode = EINVAL;
- }
+ // non-mysqldump SST requires wsrep_cluster_address on startup
+ if (!wsrep_cluster_address || !wsrep_cluster_address[0])
+ {
+ WSREP_ERROR ("%s SST method requires wsrep_cluster_address to be "
+ "configured on startup.", wsrep_sst_method);
+ return 1;
+ }
}
- if (strcasecmp(opts[WSREP_SST_RECEIVE_ADDRESS].value, "AUTO"))
+ if (strcasecmp(wsrep_sst_receive_address, "AUTO"))
{
- if (!strncasecmp(opts[WSREP_SST_RECEIVE_ADDRESS].value,
- "127.0.0.1", strlen("127.0.0.1")) ||
- !strncasecmp(opts[WSREP_SST_RECEIVE_ADDRESS].value,
- "localhost", strlen("localhost")))
- {
- WSREP_WARN ("wsrep_sst_receive_address is set to '%s' which "
- "makes it impossible for another host to reach this "
- "one. Please set it to the address which this node "
- "can be connected at by other cluster members.",
- opts[WSREP_SST_RECEIVE_ADDRESS].value);
-// rcode = EINVAL;
- }
+ if (!strncasecmp(wsrep_sst_receive_address, STRING_WITH_LEN("127.0.0.1")) ||
+ !strncasecmp(wsrep_sst_receive_address, STRING_WITH_LEN("localhost")))
+ {
+ WSREP_WARN("wsrep_sst_receive_address is set to '%s' which "
+ "makes it impossible for another host to reach this "
+ "one. Please set it to the address which this node "
+ "can be connected at by other cluster members.",
+ wsrep_sst_receive_address);
+ }
}
- if (strcasecmp(opts[WSREP_PROVIDER].value, "none"))
+ if (strcasecmp(wsrep_provider, "NONE"))
{
- if (strcasecmp(opts[BINLOG_FORMAT].value, "ROW"))
- {
- WSREP_ERROR ("Only binlog_format = 'ROW' is currently supported. "
- "Configured value: '%s'. Please adjust your "
- "configuration.", opts[BINLOG_FORMAT].value);
-
- rcode = EINVAL;
- }
+ if (global_system_variables.binlog_format != BINLOG_FORMAT_ROW)
+ {
+ WSREP_ERROR("Only binlog_format = 'ROW' is currently supported. "
+ "Configured value: '%s'. Please adjust your "
+ "configuration.",
+ binlog_format_names[global_system_variables.binlog_format]);
+
+ return 1;
+ }
}
-
- return rcode;
-}
-
-int
-wsrep_check_opts (int const argc, char* const* const argv)
-{
- return check_opts (argc, argv, opts);
+ }
+ return 0;
}