diff options
author | Sergei Golubchik <serg@mariadb.org> | 2014-08-21 18:11:46 +0200 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2014-10-11 18:53:06 +0200 |
commit | 7f5e51b940d65cf541403a50af74163b9aed5cb8 (patch) | |
tree | e540d3cd4d678cd276a9d496490ac5e527f30a78 /storage/ndb/src/mgmsrv | |
parent | 57dd1f6f3fcbc7a46e1b3e71257987315f7aa687 (diff) | |
download | mariadb-git-7f5e51b940d65cf541403a50af74163b9aed5cb8.tar.gz |
MDEV-34 delete storage/ndb and sql/*ndb* (and collateral changes)
remove:
* NDB from everywhere
* IM from mtr-v1
* packaging/rpm-oel and packaging/rpm-uln
* few unused spec files
* plug.in file
* .bzrignore
Diffstat (limited to 'storage/ndb/src/mgmsrv')
22 files changed, 0 insertions, 11921 deletions
diff --git a/storage/ndb/src/mgmsrv/Config.cpp b/storage/ndb/src/mgmsrv/Config.cpp deleted file mode 100644 index f7461375d0f..00000000000 --- a/storage/ndb/src/mgmsrv/Config.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/* Copyright (c) 2003-2005 MySQL AB - Use is subject to license terms - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ - -#include "Config.hpp" -#include <ctype.h> -#include <string.h> -#include "MgmtErrorReporter.hpp" -#include <Properties.hpp> - -//***************************************************************************** -// Ctor / Dtor -//***************************************************************************** - -Config::Config() { - m_oldConfig = 0; - m_configValues = 0; -} - -Config::~Config() { - if(m_configValues != 0){ - free(m_configValues); - } - - if(m_oldConfig != 0) - delete m_oldConfig; -} - -/*****************************************************************************/ - -void -Config::printAllNameValuePairs(NdbOut &out, - const Properties *prop, - const char* s) const { - Properties::Iterator it(prop); - const Properties * section = m_info.getInfo(s); - for (const char* n = it.first(); n != NULL; n = it.next()) { - Uint32 int_value; - const char* str_value; - Uint64 int_64; - - if(!section->contains(n)) - continue; - if (m_info.getStatus(section, n) == ConfigInfo::CI_INTERNAL) - continue; - if (m_info.getStatus(section, n) == ConfigInfo::CI_DEPRICATED) - continue; - if (m_info.getStatus(section, n) == ConfigInfo::CI_NOTIMPLEMENTED) - continue; - - out << n << ": "; - - switch (m_info.getType(section, n)) { - case ConfigInfo::CI_INT: - MGM_REQUIRE(prop->get(n, &int_value)); - out << int_value; - break; - - case ConfigInfo::CI_INT64: - MGM_REQUIRE(prop->get(n, &int_64)); - out << int_64; - break; - - case ConfigInfo::CI_BOOL: - MGM_REQUIRE(prop->get(n, &int_value)); - if (int_value) { - out << "Y"; - } else { - out << "N"; - } - break; - case ConfigInfo::CI_STRING: - MGM_REQUIRE(prop->get(n, &str_value)); - out << str_value; - break; - case ConfigInfo::CI_SECTION: - out << "SECTION"; - break; - } - out << endl; - } -} - -/*****************************************************************************/ - -void Config::printConfigFile(NdbOut &out) const { -#if 0 - Uint32 noOfNodes, noOfConnections, noOfComputers; - MGM_REQUIRE(get("NoOfNodes", &noOfNodes)); - MGM_REQUIRE(get("NoOfConnections", &noOfConnections)); - MGM_REQUIRE(get("NoOfComputers", &noOfComputers)); - - out << - "######################################################################" << - endl << - "#" << endl << - "# NDB Cluster System configuration" << endl << - "#" << endl << - "######################################################################" << - endl << - "# No of nodes (DB, API or MGM): " << noOfNodes << endl << - "# No of connections: " << noOfConnections << endl << - "######################################################################" << - endl; - - /************************** - * Print COMPUTER configs * - **************************/ - const char * name; - Properties::Iterator it(this); - for(name = it.first(); name != NULL; name = it.next()){ - if(strncasecmp("Computer_", name, 9) == 0){ - - const Properties *prop; - out << endl << "[COMPUTER]" << endl; - MGM_REQUIRE(get(name, &prop)); - printAllNameValuePairs(out, prop, "COMPUTER"); - - out << endl << - "###################################################################" << - endl; - - } else if(strncasecmp("Node_", name, 5) == 0){ - /********************** - * Print NODE configs * - **********************/ - const Properties *prop; - const char *s; - - MGM_REQUIRE(get(name, &prop)); - MGM_REQUIRE(prop->get("Type", &s)); - out << endl << "[" << s << "]" << endl; - printAllNameValuePairs(out, prop, s); - - out << endl << - "###################################################################" << - endl; - } else if(strncasecmp("Connection_", name, 11) == 0){ - /**************************** - * Print CONNECTION configs * - ****************************/ - const Properties *prop; - const char *s; - - MGM_REQUIRE(get(name, &prop)); - MGM_REQUIRE(prop->get("Type", &s)); - out << endl << "[" << s << "]" << endl; - printAllNameValuePairs(out, prop, s); - - out << endl << - "###################################################################" << - endl; - } else if(strncasecmp("SYSTEM", name, strlen("SYSTEM")) == 0) { - /************************ - * Print SYSTEM configs * - ************************/ - const Properties *prop; - - MGM_REQUIRE(get(name, &prop)); - out << endl << "[SYSTEM]" << endl; - printAllNameValuePairs(out, prop, "SYSTEM"); - - out << endl << - "###################################################################" << - endl; - } - } -#endif -} diff --git a/storage/ndb/src/mgmsrv/Config.hpp b/storage/ndb/src/mgmsrv/Config.hpp deleted file mode 100644 index 31ebd7f219f..00000000000 --- a/storage/ndb/src/mgmsrv/Config.hpp +++ /dev/null @@ -1,82 +0,0 @@ -/* Copyright (c) 2003-2006 MySQL AB - Use is subject to license terms - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ - -#ifndef Config_H -#define Config_H - -#include <LogLevel.hpp> - -#include <kernel_types.h> - -#include <NdbOut.hpp> -#include <ndb_limits.h> -#include <Properties.hpp> -#include <ConfigInfo.hpp> - -class ConfigInfo; - -/** - * @class Config - * @brief Cluster Configuration (corresponds to initial configuration file) - * - * Contains all cluster configuration parameters. - * - * The information includes all configurable parameters for a NDB cluster: - * - DB, API and MGM nodes with all their properties, - * - Connections between nodes and computers the nodes will execute on. - * - * The following categories (sections) of configuration parameters exists: - * - COMPUTER, DB, MGM, API, TCP, SCI, SHM - * - */ - -class Config { -public: - /** - * Constructor which loads the object with an Properties object - */ - Config(); - virtual ~Config(); - - /** - * Prints the configuration in configfile format - */ - void printConfigFile(NdbOut &out = ndbout) const; - void printConfigFile(OutputStream &out) const { - NdbOut ndb(out); - printConfigFile(ndb); - } - - /** - * Info - */ - const ConfigInfo * getConfigInfo() const { return &m_info;} -private: - ConfigInfo m_info; - - void printAllNameValuePairs(NdbOut &out, - const Properties *prop, - const char* section) const; - - /** - * Information about parameters (min, max values etc) - */ -public: - Properties * m_oldConfig; - struct ndb_mgm_configuration * m_configValues; -}; - -#endif // Config_H diff --git a/storage/ndb/src/mgmsrv/ConfigInfo.cpp b/storage/ndb/src/mgmsrv/ConfigInfo.cpp deleted file mode 100644 index 10dd8bd34c6..00000000000 --- a/storage/ndb/src/mgmsrv/ConfigInfo.cpp +++ /dev/null @@ -1,3827 +0,0 @@ -/* Copyright (c) 2003-2007 MySQL AB - Use is subject to license terms - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ - -#include <ndb_global.h> -#ifndef NDB_MGMAPI -#include <ndb_opt_defaults.h> - -#include <NdbTCP.h> -#include "ConfigInfo.hpp" -#include <mgmapi_config_parameters.h> -#include <ndb_limits.h> -#include "InitConfigFileParser.hpp" -#include <m_string.h> - -extern my_bool opt_ndb_shm; -extern my_bool opt_core; - -#else -#include "ConfigInfo.hpp" -#include <mgmapi_config_parameters.h> -#endif /* NDB_MGMAPI */ - -#define MAX_LINE_LENGTH 255 -#define KEY_INTERNAL 0 -#define MAX_INT_RNIL 0xfffffeff -#define MAX_PORT_NO 65535 - -#define _STR_VALUE(x) #x -#define STR_VALUE(x) _STR_VALUE(x) - -/**************************************************************************** - * Section names - ****************************************************************************/ - -#define DB_TOKEN_PRINT "ndbd(DB)" -#define MGM_TOKEN_PRINT "ndb_mgmd(MGM)" -#define API_TOKEN_PRINT "mysqld(API)" - -#define DB_TOKEN "DB" -#define MGM_TOKEN "MGM" -#define API_TOKEN "API" - -#ifndef NDB_MGMAPI -const ConfigInfo::AliasPair -ConfigInfo::m_sectionNameAliases[]={ - {API_TOKEN, "MYSQLD"}, - {DB_TOKEN, "NDBD"}, - {MGM_TOKEN, "NDB_MGMD"}, - {0, 0} -}; - -const char* -ConfigInfo::m_sectionNames[]={ - "SYSTEM", - "COMPUTER", - - DB_TOKEN, - MGM_TOKEN, - API_TOKEN, - - "TCP", - "SCI", - "SHM" -}; -const int ConfigInfo::m_noOfSectionNames = -sizeof(m_sectionNames)/sizeof(char*); - - -/**************************************************************************** - * Section Rules declarations - ****************************************************************************/ -static bool transformComputer(InitConfigFileParser::Context & ctx, const char *); -static bool transformSystem(InitConfigFileParser::Context & ctx, const char *); -static bool transformNode(InitConfigFileParser::Context & ctx, const char *); -static bool checkConnectionSupport(InitConfigFileParser::Context & ctx, const char *); -static bool transformConnection(InitConfigFileParser::Context & ctx, const char *); -static bool applyDefaultValues(InitConfigFileParser::Context & ctx, const char *); -static bool checkMandatory(InitConfigFileParser::Context & ctx, const char *); -static bool fixPortNumber(InitConfigFileParser::Context & ctx, const char *); -static bool fixShmKey(InitConfigFileParser::Context & ctx, const char *); -static bool checkDbConstraints(InitConfigFileParser::Context & ctx, const char *); -static bool checkConnectionConstraints(InitConfigFileParser::Context &, const char *); -static bool checkTCPConstraints(InitConfigFileParser::Context &, const char *); -static bool fixNodeHostname(InitConfigFileParser::Context & ctx, const char * data); -static bool fixHostname(InitConfigFileParser::Context & ctx, const char * data); -static bool fixNodeId(InitConfigFileParser::Context & ctx, const char * data); -static bool fixDepricated(InitConfigFileParser::Context & ctx, const char *); -static bool saveInConfigValues(InitConfigFileParser::Context & ctx, const char *); -static bool fixFileSystemPath(InitConfigFileParser::Context & ctx, const char * data); -static bool fixBackupDataDir(InitConfigFileParser::Context & ctx, const char * data); -static bool fixShmUniqueId(InitConfigFileParser::Context & ctx, const char * data); -static bool checkLocalhostHostnameMix(InitConfigFileParser::Context & ctx, const char * data); - -const ConfigInfo::SectionRule -ConfigInfo::m_SectionRules[] = { - { "SYSTEM", transformSystem, 0 }, - { "COMPUTER", transformComputer, 0 }, - - { DB_TOKEN, transformNode, 0 }, - { API_TOKEN, transformNode, 0 }, - { MGM_TOKEN, transformNode, 0 }, - - { MGM_TOKEN, fixShmUniqueId, 0 }, - - { "TCP", checkConnectionSupport, 0 }, - { "SHM", checkConnectionSupport, 0 }, - { "SCI", checkConnectionSupport, 0 }, - - { "TCP", transformConnection, 0 }, - { "SHM", transformConnection, 0 }, - { "SCI", transformConnection, 0 }, - - { DB_TOKEN, fixNodeHostname, 0 }, - { API_TOKEN, fixNodeHostname, 0 }, - { MGM_TOKEN, fixNodeHostname, 0 }, - - { "TCP", fixNodeId, "NodeId1" }, - { "TCP", fixNodeId, "NodeId2" }, - { "SHM", fixNodeId, "NodeId1" }, - { "SHM", fixNodeId, "NodeId2" }, - { "SCI", fixNodeId, "NodeId1" }, - { "SCI", fixNodeId, "NodeId2" }, - - { "TCP", fixHostname, "HostName1" }, - { "TCP", fixHostname, "HostName2" }, - { "SHM", fixHostname, "HostName1" }, - { "SHM", fixHostname, "HostName2" }, - { "SCI", fixHostname, "HostName1" }, - { "SCI", fixHostname, "HostName2" }, - { "SHM", fixHostname, "HostName1" }, - { "SHM", fixHostname, "HostName2" }, - - { "TCP", fixPortNumber, 0 }, // has to come after fixHostName - { "SHM", fixPortNumber, 0 }, // has to come after fixHostName - { "SCI", fixPortNumber, 0 }, // has to come after fixHostName - - { "*", applyDefaultValues, "user" }, - { "*", fixDepricated, 0 }, - { "*", applyDefaultValues, "system" }, - - { "SHM", fixShmKey, 0 }, // has to come after apply default values - - { DB_TOKEN, checkLocalhostHostnameMix, 0 }, - { API_TOKEN, checkLocalhostHostnameMix, 0 }, - { MGM_TOKEN, checkLocalhostHostnameMix, 0 }, - - { DB_TOKEN, fixFileSystemPath, 0 }, - { DB_TOKEN, fixBackupDataDir, 0 }, - - { DB_TOKEN, checkDbConstraints, 0 }, - - { "TCP", checkConnectionConstraints, 0 }, - { "SHM", checkConnectionConstraints, 0 }, - { "SCI", checkConnectionConstraints, 0 }, - - { "TCP", checkTCPConstraints, "HostName1" }, - { "TCP", checkTCPConstraints, "HostName2" }, - { "SCI", checkTCPConstraints, "HostName1" }, - { "SCI", checkTCPConstraints, "HostName2" }, - { "SHM", checkTCPConstraints, "HostName1" }, - { "SHM", checkTCPConstraints, "HostName2" }, - - { "*", checkMandatory, 0 }, - - { DB_TOKEN, saveInConfigValues, 0 }, - { API_TOKEN, saveInConfigValues, 0 }, - { MGM_TOKEN, saveInConfigValues, 0 }, - - { "TCP", saveInConfigValues, 0 }, - { "SHM", saveInConfigValues, 0 }, - { "SCI", saveInConfigValues, 0 } -}; -const int ConfigInfo::m_NoOfRules = sizeof(m_SectionRules)/sizeof(SectionRule); - -/**************************************************************************** - * Config Rules declarations - ****************************************************************************/ -static bool sanity_checks(Vector<ConfigInfo::ConfigRuleSection>§ions, - struct InitConfigFileParser::Context &ctx, - const char * rule_data); -static bool add_node_connections(Vector<ConfigInfo::ConfigRuleSection>§ions, - struct InitConfigFileParser::Context &ctx, - const char * rule_data); -static bool set_connection_priorities(Vector<ConfigInfo::ConfigRuleSection>§ions, - struct InitConfigFileParser::Context &ctx, - const char * rule_data); -static bool check_node_vs_replicas(Vector<ConfigInfo::ConfigRuleSection>§ions, - struct InitConfigFileParser::Context &ctx, - const char * rule_data); - -const ConfigInfo::ConfigRule -ConfigInfo::m_ConfigRules[] = { - { sanity_checks, 0 }, - { add_node_connections, 0 }, - { set_connection_priorities, 0 }, - { check_node_vs_replicas, 0 }, - { 0, 0 } -}; - -struct DepricationTransform { - const char * m_section; - const char * m_oldName; - const char * m_newName; - double m_add; - double m_mul; -}; - -static -const DepricationTransform f_deprication[] = { - { DB_TOKEN, "Discless", "Diskless", 0, 1 }, - { DB_TOKEN, "Id", "NodeId", 0, 1 }, - { API_TOKEN, "Id", "NodeId", 0, 1 }, - { MGM_TOKEN, "Id", "NodeId", 0, 1 }, - { 0, 0, 0, 0, 0} -}; -#endif /* NDB_MGMAPI */ - -/** - * The default constructors create objects with suitable values for the - * configuration parameters. - * - * Some are however given the value MANDATORY which means that the value - * must be specified in the configuration file. - * - * Min and max values are also given for some parameters. - * - Attr1: Name in file (initial config file) - * - Attr2: Name in prop (properties object) - * - Attr3: Name of Section (in init config file) - * - Attr4: Updateable - * - Attr5: Type of parameter (INT or BOOL) - * - Attr6: Default Value (number only) - * - Attr7: Min value - * - Attr8: Max value - * - * Parameter constraints are coded in file Config.cpp. - * - * ******************************************************************* - * Parameters used under development should be marked "NOTIMPLEMENTED" - * ******************************************************************* - */ - -const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { - - /**************************************************************************** - * COMPUTER - ***************************************************************************/ - { - KEY_INTERNAL, - "COMPUTER", - "COMPUTER", - "Computer section", - ConfigInfo::CI_INTERNAL, - false, - ConfigInfo::CI_SECTION, - 0, - 0, 0 }, - - { - KEY_INTERNAL, - "Id", - "COMPUTER", - "Name of computer", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_STRING, - MANDATORY, - 0, 0 }, - - { - KEY_INTERNAL, - "HostName", - "COMPUTER", - "Hostname of computer (e.g. mysql.com)", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_STRING, - MANDATORY, - 0, 0 }, - - { - KEY_INTERNAL, - "ByteOrder", - "COMPUTER", - 0, - ConfigInfo::CI_DEPRICATED, - false, - ConfigInfo::CI_STRING, - UNDEFINED, - 0, - 0 }, - - /**************************************************************************** - * SYSTEM - ***************************************************************************/ - { - CFG_SECTION_SYSTEM, - "SYSTEM", - "SYSTEM", - "System section", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_SECTION, - (const char *)CFG_SECTION_SYSTEM, - 0, 0 }, - - { - CFG_SYS_NAME, - "Name", - "SYSTEM", - "Name of system (NDB Cluster)", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_STRING, - MANDATORY, - 0, 0 }, - - { - CFG_SYS_PRIMARY_MGM_NODE, - "PrimaryMGMNode", - "SYSTEM", - "Node id of Primary "MGM_TOKEN_PRINT" node", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "0", - "0", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_SYS_CONFIG_GENERATION, - "ConfigGenerationNumber", - "SYSTEM", - "Configuration generation number", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "0", - "0", - STR_VALUE(MAX_INT_RNIL) }, - - /*************************************************************************** - * DB - ***************************************************************************/ - { - CFG_SECTION_NODE, - DB_TOKEN, - DB_TOKEN, - "Node section", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_SECTION, - (const char *)NODE_TYPE_DB, - 0, 0 - }, - - { - CFG_NODE_HOST, - "HostName", - DB_TOKEN, - "Name of computer for this node", - ConfigInfo::CI_INTERNAL, - false, - ConfigInfo::CI_STRING, - "localhost", - 0, 0 }, - - { - CFG_NODE_SYSTEM, - "System", - DB_TOKEN, - "Name of system for this node", - ConfigInfo::CI_INTERNAL, - false, - ConfigInfo::CI_STRING, - UNDEFINED, - 0, 0 }, - - { - KEY_INTERNAL, - "Id", - DB_TOKEN, - "", - ConfigInfo::CI_DEPRICATED, - false, - ConfigInfo::CI_INT, - MANDATORY, - "1", - STR_VALUE(MAX_DATA_NODE_ID) }, - - { - CFG_NODE_ID, - "NodeId", - DB_TOKEN, - "Number identifying the database node ("DB_TOKEN_PRINT")", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - MANDATORY, - "1", - STR_VALUE(MAX_DATA_NODE_ID) }, - - { - KEY_INTERNAL, - "ServerPort", - DB_TOKEN, - "Port used to setup transporter", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - UNDEFINED, - "1", - STR_VALUE(MAX_PORT_NO) }, - - { - CFG_DB_NO_REPLICAS, - "NoOfReplicas", - DB_TOKEN, - "Number of copies of all data in the database (1-4)", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - MANDATORY, - "1", - "4" }, - - { - CFG_DB_NO_ATTRIBUTES, - "MaxNoOfAttributes", - DB_TOKEN, - "Total number of attributes stored in database. I.e. sum over all tables", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "1000", - "32", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_DB_NO_TABLES, - "MaxNoOfTables", - DB_TOKEN, - "Total number of tables stored in the database", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "128", - "8", - STR_VALUE(MAX_TABLES) }, - - { - CFG_DB_NO_ORDERED_INDEXES, - "MaxNoOfOrderedIndexes", - DB_TOKEN, - "Total number of ordered indexes that can be defined in the system", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "128", - "0", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_DB_NO_UNIQUE_HASH_INDEXES, - "MaxNoOfUniqueHashIndexes", - DB_TOKEN, - "Total number of unique hash indexes that can be defined in the system", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "64", - "0", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_DB_NO_INDEXES, - "MaxNoOfIndexes", - DB_TOKEN, - "Total number of indexes that can be defined in the system", - ConfigInfo::CI_DEPRICATED, - false, - ConfigInfo::CI_INT, - "128", - "0", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_DB_NO_INDEX_OPS, - "MaxNoOfConcurrentIndexOperations", - DB_TOKEN, - "Total number of index operations that can execute simultaneously on one "DB_TOKEN_PRINT" node", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "8K", - "0", - STR_VALUE(MAX_INT_RNIL) - }, - - { - CFG_DB_NO_TRIGGERS, - "MaxNoOfTriggers", - DB_TOKEN, - "Total number of triggers that can be defined in the system", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "768", - "0", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_DB_NO_TRIGGER_OPS, - "MaxNoOfFiredTriggers", - DB_TOKEN, - "Total number of triggers that can fire simultaneously in one "DB_TOKEN_PRINT" node", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "4000", - "0", - STR_VALUE(MAX_INT_RNIL) }, - - { - KEY_INTERNAL, - "ExecuteOnComputer", - DB_TOKEN, - "String referencing an earlier defined COMPUTER", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_STRING, - UNDEFINED, - 0, 0 }, - - { - CFG_DB_NO_SAVE_MSGS, - "MaxNoOfSavedMessages", - DB_TOKEN, - "Max number of error messages in error log and max number of trace files", - ConfigInfo::CI_USED, - true, - ConfigInfo::CI_INT, - "25", - "0", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_DB_MEMLOCK, - "LockPagesInMainMemory", - DB_TOKEN, - "If set to yes, then NDB Cluster data will not be swapped out to disk", - ConfigInfo::CI_USED, - true, - ConfigInfo::CI_INT, - "0", - "0", - "2" }, - - { - CFG_DB_WATCHDOG_INTERVAL, - "TimeBetweenWatchDogCheck", - DB_TOKEN, - "Time between execution checks inside a database node", - ConfigInfo::CI_USED, - true, - ConfigInfo::CI_INT, - "6000", - "70", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_DB_WATCHDOG_INTERVAL_INITIAL, - "TimeBetweenWatchDogCheckInitial", - DB_TOKEN, - "Time between execution checks inside a database node in the early start phases when memory is allocated", - ConfigInfo::CI_USED, - true, - ConfigInfo::CI_INT, - "6000", - "70", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_DB_STOP_ON_ERROR, - "StopOnError", - DB_TOKEN, - "If set to N, "DB_TOKEN_PRINT" automatically restarts/recovers in case of node failure", - ConfigInfo::CI_USED, - true, - ConfigInfo::CI_BOOL, - "true", - "false", - "true" }, - - { - CFG_DB_STOP_ON_ERROR_INSERT, - "RestartOnErrorInsert", - DB_TOKEN, - "See src/kernel/vm/Emulator.hpp NdbRestartType for details", - ConfigInfo::CI_INTERNAL, - true, - ConfigInfo::CI_INT, - "2", - "0", - "4" }, - - { - CFG_DB_NO_OPS, - "MaxNoOfConcurrentOperations", - DB_TOKEN, - "Max number of operation records in transaction coordinator", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "32k", - "32", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_DB_NO_LOCAL_OPS, - "MaxNoOfLocalOperations", - DB_TOKEN, - "Max number of operation records defined in the local storage node", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - UNDEFINED, - "32", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_DB_NO_LOCAL_SCANS, - "MaxNoOfLocalScans", - DB_TOKEN, - "Max number of fragment scans in parallel in the local storage node", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - UNDEFINED, - "32", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_DB_BATCH_SIZE, - "BatchSizePerLocalScan", - DB_TOKEN, - "Used to calculate the number of lock records for scan with hold lock", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - STR_VALUE(DEF_BATCH_SIZE), - "1", - STR_VALUE(MAX_PARALLEL_OP_PER_SCAN) }, - - { - CFG_DB_NO_TRANSACTIONS, - "MaxNoOfConcurrentTransactions", - DB_TOKEN, - "Max number of transaction executing concurrently on the "DB_TOKEN_PRINT" node", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "4096", - "32", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_DB_NO_SCANS, - "MaxNoOfConcurrentScans", - DB_TOKEN, - "Max number of scans executing concurrently on the "DB_TOKEN_PRINT" node", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "256", - "2", - "500" }, - - { - CFG_DB_TRANS_BUFFER_MEM, - "TransactionBufferMemory", - DB_TOKEN, - "Dynamic buffer space (in bytes) for key and attribute data allocated for each "DB_TOKEN_PRINT" node", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "1M", - "1K", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_DB_INDEX_MEM, - "IndexMemory", - DB_TOKEN, - "Number bytes on each "DB_TOKEN_PRINT" node allocated for storing indexes", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT64, - "18M", - "1M", - "1024G" }, - - { - CFG_DB_DATA_MEM, - "DataMemory", - DB_TOKEN, - "Number bytes on each "DB_TOKEN_PRINT" node allocated for storing data", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT64, - "80M", - "1M", - "1024G" }, - - { - CFG_DB_UNDO_INDEX_BUFFER, - "UndoIndexBuffer", - DB_TOKEN, - "Number bytes on each "DB_TOKEN_PRINT" node allocated for writing UNDO logs for index part", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "2M", - "1M", - STR_VALUE(MAX_INT_RNIL)}, - - { - CFG_DB_UNDO_DATA_BUFFER, - "UndoDataBuffer", - DB_TOKEN, - "Number bytes on each "DB_TOKEN_PRINT" node allocated for writing UNDO logs for data part", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "16M", - "1M", - STR_VALUE(MAX_INT_RNIL)}, - - { - CFG_DB_REDO_BUFFER, - "RedoBuffer", - DB_TOKEN, - "Number bytes on each "DB_TOKEN_PRINT" node allocated for writing REDO logs", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "8M", - "1M", - STR_VALUE(MAX_INT_RNIL)}, - - { - CFG_DB_LONG_SIGNAL_BUFFER, - "LongMessageBuffer", - DB_TOKEN, - "Number bytes on each "DB_TOKEN_PRINT" node allocated for internal long messages", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "1M", - "512k", - STR_VALUE(MAX_INT_RNIL)}, - - { - CFG_DB_DISK_PAGE_BUFFER_MEMORY, - "DiskPageBufferMemory", - DB_TOKEN, - "Number bytes on each "DB_TOKEN_PRINT" node allocated for disk page buffer cache", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT64, - "64M", - "4M", - "1024G" }, - - { - CFG_DB_SGA, - "SharedGlobalMemory", - DB_TOKEN, - "Total number bytes on each "DB_TOKEN_PRINT" node allocated for any use", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT64, - "20M", - "0", - "65536G" }, // 32k pages * 32-bit i value - - { - CFG_DB_START_PARTIAL_TIMEOUT, - "StartPartialTimeout", - DB_TOKEN, - "Time to wait before trying to start wo/ all nodes. 0=Wait forever", - ConfigInfo::CI_USED, - true, - ConfigInfo::CI_INT, - "30000", - "0", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_DB_START_PARTITION_TIMEOUT, - "StartPartitionedTimeout", - DB_TOKEN, - "Time to wait before trying to start partitioned. 0=Wait forever", - ConfigInfo::CI_USED, - true, - ConfigInfo::CI_INT, - "60000", - "0", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_DB_START_FAILURE_TIMEOUT, - "StartFailureTimeout", - DB_TOKEN, - "Time to wait before terminating. 0=Wait forever", - ConfigInfo::CI_USED, - true, - ConfigInfo::CI_INT, - "0", - "0", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_DB_HEARTBEAT_INTERVAL, - "HeartbeatIntervalDbDb", - DB_TOKEN, - "Time between "DB_TOKEN_PRINT"-"DB_TOKEN_PRINT" heartbeats. "DB_TOKEN_PRINT" considered dead after 3 missed HBs", - ConfigInfo::CI_USED, - true, - ConfigInfo::CI_INT, - "1500", - "10", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_DB_API_HEARTBEAT_INTERVAL, - "HeartbeatIntervalDbApi", - DB_TOKEN, - "Time between "API_TOKEN_PRINT"-"DB_TOKEN_PRINT" heartbeats. "API_TOKEN_PRINT" connection closed after 3 missed HBs", - ConfigInfo::CI_USED, - true, - ConfigInfo::CI_INT, - "1500", - "100", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_DB_LCP_INTERVAL, - "TimeBetweenLocalCheckpoints", - DB_TOKEN, - "Time between taking snapshots of the database (expressed in 2log of bytes)", - ConfigInfo::CI_USED, - true, - ConfigInfo::CI_INT, - "20", - "0", - "31" }, - - { - CFG_DB_GCP_INTERVAL, - "TimeBetweenGlobalCheckpoints", - DB_TOKEN, - "Time between doing group commit of transactions to disk", - ConfigInfo::CI_USED, - true, - ConfigInfo::CI_INT, - "2000", - "10", - "32000" }, - - { - CFG_DB_NO_REDOLOG_FILES, - "NoOfFragmentLogFiles", - DB_TOKEN, - "No of 16 Mbyte Redo log files in each of 4 file sets belonging to "DB_TOKEN_PRINT" node", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "16", - "3", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_DB_REDOLOG_FILE_SIZE, - "FragmentLogFileSize", - DB_TOKEN, - "Size of each Redo log file", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "16M", - "4M", - "1G" }, - - { - CFG_DB_MAX_OPEN_FILES, - "MaxNoOfOpenFiles", - DB_TOKEN, - "Max number of files open per "DB_TOKEN_PRINT" node.(One thread is created per file)", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "0", - "20", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_DB_INITIAL_OPEN_FILES, - "InitialNoOfOpenFiles", - DB_TOKEN, - "Initial number of files open per "DB_TOKEN_PRINT" node.(One thread is created per file)", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "27", - "20", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_DB_TRANSACTION_CHECK_INTERVAL, - "TimeBetweenInactiveTransactionAbortCheck", - DB_TOKEN, - "Time between inactive transaction checks", - ConfigInfo::CI_USED, - true, - ConfigInfo::CI_INT, - "1000", - "1000", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_DB_TRANSACTION_INACTIVE_TIMEOUT, - "TransactionInactiveTimeout", - DB_TOKEN, - "Time application can wait before executing another transaction part (ms).\n" - "This is the time the transaction coordinator waits for the application\n" - "to execute or send another part (query, statement) of the transaction.\n" - "If the application takes too long time, the transaction gets aborted.\n" - "Timeout set to 0 means that we don't timeout at all on application wait.", - ConfigInfo::CI_USED, - true, - ConfigInfo::CI_INT, - STR_VALUE(MAX_INT_RNIL), - "0", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_DB_TRANSACTION_DEADLOCK_TIMEOUT, - "TransactionDeadlockDetectionTimeout", - DB_TOKEN, - "Time transaction can be executing in a DB node (ms).\n" - "This is the time the transaction coordinator waits for each database node\n" - "of the transaction to execute a request. If the database node takes too\n" - "long time, the transaction gets aborted.", - ConfigInfo::CI_USED, - true, - ConfigInfo::CI_INT, - "1200", - "50", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_DB_LCP_DISC_PAGES_TUP_SR, - "NoOfDiskPagesToDiskDuringRestartTUP", - DB_TOKEN, - "DiskCheckpointSpeedSr", - ConfigInfo::CI_DEPRICATED, - true, - ConfigInfo::CI_INT, - "40", - "1", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_DB_LCP_DISC_PAGES_TUP, - "NoOfDiskPagesToDiskAfterRestartTUP", - DB_TOKEN, - "DiskCheckpointSpeed", - ConfigInfo::CI_DEPRICATED, - true, - ConfigInfo::CI_INT, - "40", - "1", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_DB_LCP_DISC_PAGES_ACC_SR, - "NoOfDiskPagesToDiskDuringRestartACC", - DB_TOKEN, - "DiskCheckpointSpeedSr", - ConfigInfo::CI_DEPRICATED, - true, - ConfigInfo::CI_INT, - "20", - "1", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_DB_LCP_DISC_PAGES_ACC, - "NoOfDiskPagesToDiskAfterRestartACC", - DB_TOKEN, - "DiskCheckpointSpeed", - ConfigInfo::CI_DEPRICATED, - true, - ConfigInfo::CI_INT, - "20", - "1", - STR_VALUE(MAX_INT_RNIL) }, - - - { - CFG_DB_DISCLESS, - "Diskless", - DB_TOKEN, - "Run wo/ disk", - ConfigInfo::CI_USED, - true, - ConfigInfo::CI_BOOL, - "false", - "false", - "true"}, - - { - KEY_INTERNAL, - "Discless", - DB_TOKEN, - "Diskless", - ConfigInfo::CI_DEPRICATED, - true, - ConfigInfo::CI_BOOL, - "false", - "false", - "true"}, - - - - { - CFG_DB_ARBIT_TIMEOUT, - "ArbitrationTimeout", - DB_TOKEN, - "Max time (milliseconds) database partion waits for arbitration signal", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "3000", - "10", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_NODE_DATADIR, - "DataDir", - DB_TOKEN, - "Data directory for this node", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_STRING, - MYSQLCLUSTERDIR, - 0, 0 }, - - { - CFG_DB_FILESYSTEM_PATH, - "FileSystemPath", - DB_TOKEN, - "Path to directory where the "DB_TOKEN_PRINT" node stores its data (directory must exist)", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_STRING, - UNDEFINED, - 0, 0 }, - - { - CFG_LOGLEVEL_STARTUP, - "LogLevelStartup", - DB_TOKEN, - "Node startup info printed on stdout", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "1", - "0", - "15" }, - - { - CFG_LOGLEVEL_SHUTDOWN, - "LogLevelShutdown", - DB_TOKEN, - "Node shutdown info printed on stdout", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "0", - "0", - "15" }, - - { - CFG_LOGLEVEL_STATISTICS, - "LogLevelStatistic", - DB_TOKEN, - "Transaction, operation, transporter info printed on stdout", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "0", - "0", - "15" }, - - { - CFG_LOGLEVEL_CHECKPOINT, - "LogLevelCheckpoint", - DB_TOKEN, - "Local and Global checkpoint info printed on stdout", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "0", - "0", - "15" }, - - { - CFG_LOGLEVEL_NODERESTART, - "LogLevelNodeRestart", - DB_TOKEN, - "Node restart, node failure info printed on stdout", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "0", - "0", - "15" }, - - { - CFG_LOGLEVEL_CONNECTION, - "LogLevelConnection", - DB_TOKEN, - "Node connect/disconnect info printed on stdout", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "0", - "0", - "15" }, - - { - CFG_LOGLEVEL_CONGESTION, - "LogLevelCongestion", - DB_TOKEN, - "Congestion info printed on stdout", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "0", - "0", - "15" }, - - { - CFG_LOGLEVEL_ERROR, - "LogLevelError", - DB_TOKEN, - "Transporter, heartbeat errors printed on stdout", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "0", - "0", - "15" }, - - { - CFG_LOGLEVEL_INFO, - "LogLevelInfo", - DB_TOKEN, - "Heartbeat and log info printed on stdout", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "0", - "0", - "15" }, - - /** - * Backup - */ - { - CFG_DB_PARALLEL_BACKUPS, - "ParallelBackups", - DB_TOKEN, - "Maximum number of parallel backups", - ConfigInfo::CI_NOTIMPLEMENTED, - false, - ConfigInfo::CI_INT, - "1", - "1", - "1" }, - - { - CFG_DB_BACKUP_DATADIR, - "BackupDataDir", - DB_TOKEN, - "Path to where to store backups", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_STRING, - UNDEFINED, - 0, 0 }, - - { - CFG_DB_DISK_SYNCH_SIZE, - "DiskSyncSize", - DB_TOKEN, - "Data written to a file before a synch is forced", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "4M", - "32k", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_DB_CHECKPOINT_SPEED, - "DiskCheckpointSpeed", - DB_TOKEN, - "Bytes per second allowed to be written by checkpoint", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "10M", - "1M", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_DB_CHECKPOINT_SPEED_SR, - "DiskCheckpointSpeedInRestart", - DB_TOKEN, - "Bytes per second allowed to be written by checkpoint during restart", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "100M", - "1M", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_DB_BACKUP_MEM, - "BackupMemory", - DB_TOKEN, - "Total memory allocated for backups per node (in bytes)", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "4M", // sum of BackupDataBufferSize and BackupLogBufferSize - "0", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_DB_BACKUP_DATA_BUFFER_MEM, - "BackupDataBufferSize", - DB_TOKEN, - "Default size of databuffer for a backup (in bytes)", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "2M", // remember to change BackupMemory - "0", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_DB_BACKUP_LOG_BUFFER_MEM, - "BackupLogBufferSize", - DB_TOKEN, - "Default size of logbuffer for a backup (in bytes)", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "2M", // remember to change BackupMemory - "0", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_DB_BACKUP_WRITE_SIZE, - "BackupWriteSize", - DB_TOKEN, - "Default size of filesystem writes made by backup (in bytes)", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "32K", - "2K", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_DB_BACKUP_MAX_WRITE_SIZE, - "BackupMaxWriteSize", - DB_TOKEN, - "Max size of filesystem writes made by backup (in bytes)", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "256K", - "2K", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_DB_STRING_MEMORY, - "StringMemory", - DB_TOKEN, - "Default size of string memory (0 -> 5% of max 1-100 -> %of max, >100 -> actual bytes)", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "0", - "0", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_DB_MAX_ALLOCATE, - "MaxAllocate", - DB_TOKEN, - "Maximum size of allocation to use when allocating memory for tables", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "32M", - "1M", - "1G" }, - - { - CFG_DB_MEMREPORT_FREQUENCY, - "MemReportFrequency", - DB_TOKEN, - "Frequency of mem reports in seconds, 0 = only when passing %-limits", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "0", - "0", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_DB_O_DIRECT, - "ODirect", - DB_TOKEN, - "Use O_DIRECT file write/read when possible", - ConfigInfo::CI_USED, - true, - ConfigInfo::CI_BOOL, - "false", - "false", - "true"}, - - /*************************************************************************** - * API - ***************************************************************************/ - { - CFG_SECTION_NODE, - API_TOKEN, - API_TOKEN, - "Node section", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_SECTION, - (const char *)NODE_TYPE_API, - 0, 0 - }, - - { - CFG_NODE_HOST, - "HostName", - API_TOKEN, - "Name of computer for this node", - ConfigInfo::CI_INTERNAL, - false, - ConfigInfo::CI_STRING, - "", - 0, 0 }, - - { - CFG_NODE_SYSTEM, - "System", - API_TOKEN, - "Name of system for this node", - ConfigInfo::CI_INTERNAL, - false, - ConfigInfo::CI_STRING, - UNDEFINED, - 0, 0 }, - - { - KEY_INTERNAL, - "Id", - API_TOKEN, - "", - ConfigInfo::CI_DEPRICATED, - false, - ConfigInfo::CI_INT, - MANDATORY, - "1", - STR_VALUE(MAX_NODES_ID) }, - - { - CFG_NODE_ID, - "NodeId", - API_TOKEN, - "Number identifying application node ("API_TOKEN_PRINT")", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - MANDATORY, - "1", - STR_VALUE(MAX_NODES_ID) }, - - { - KEY_INTERNAL, - "ExecuteOnComputer", - API_TOKEN, - "String referencing an earlier defined COMPUTER", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_STRING, - UNDEFINED, - 0, 0 }, - - { - CFG_NODE_ARBIT_RANK, - "ArbitrationRank", - API_TOKEN, - "If 0, then "API_TOKEN_PRINT" is not arbitrator. Kernel selects arbitrators in order 1, 2", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "0", - "0", - "2" }, - - { - CFG_NODE_ARBIT_DELAY, - "ArbitrationDelay", - API_TOKEN, - "When asked to arbitrate, arbitrator waits this long before voting (msec)", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "0", - "0", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_MAX_SCAN_BATCH_SIZE, - "MaxScanBatchSize", - "API", - "The maximum collective batch size for one scan", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - STR_VALUE(MAX_SCAN_BATCH_SIZE), - "32k", - "16M" }, - - { - CFG_BATCH_BYTE_SIZE, - "BatchByteSize", - "API", - "The default batch size in bytes", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - STR_VALUE(SCAN_BATCH_SIZE), - "1k", - "1M" }, - - { - CFG_BATCH_SIZE, - "BatchSize", - "API", - "The default batch size in number of records", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - STR_VALUE(DEF_BATCH_SIZE), - "1", - STR_VALUE(MAX_PARALLEL_OP_PER_SCAN) }, - - /**************************************************************************** - * MGM - ***************************************************************************/ - { - CFG_SECTION_NODE, - MGM_TOKEN, - MGM_TOKEN, - "Node section", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_SECTION, - (const char *)NODE_TYPE_MGM, - 0, 0 - }, - - { - CFG_NODE_HOST, - "HostName", - MGM_TOKEN, - "Name of computer for this node", - ConfigInfo::CI_INTERNAL, - false, - ConfigInfo::CI_STRING, - "", - 0, 0 }, - - { - CFG_NODE_DATADIR, - "DataDir", - MGM_TOKEN, - "Data directory for this node", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_STRING, - MYSQLCLUSTERDIR, - 0, 0 }, - - { - CFG_NODE_SYSTEM, - "System", - MGM_TOKEN, - "Name of system for this node", - ConfigInfo::CI_INTERNAL, - false, - ConfigInfo::CI_STRING, - UNDEFINED, - 0, 0 }, - - { - KEY_INTERNAL, - "Id", - MGM_TOKEN, - "", - ConfigInfo::CI_DEPRICATED, - false, - ConfigInfo::CI_INT, - MANDATORY, - "1", - STR_VALUE(MAX_NODES_ID) }, - - { - CFG_NODE_ID, - "NodeId", - MGM_TOKEN, - "Number identifying the management server node ("MGM_TOKEN_PRINT")", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - MANDATORY, - "1", - STR_VALUE(MAX_NODES_ID) }, - - { - CFG_LOG_DESTINATION, - "LogDestination", - MGM_TOKEN, - "String describing where logmessages are sent", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_STRING, - 0, - 0, 0 }, - - { - KEY_INTERNAL, - "ExecuteOnComputer", - MGM_TOKEN, - "String referencing an earlier defined COMPUTER", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_STRING, - 0, - 0, 0 }, - - { - KEY_INTERNAL, - "MaxNoOfSavedEvents", - MGM_TOKEN, - "", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "100", - "0", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_MGM_PORT, - "PortNumber", - MGM_TOKEN, - "Port number to give commands to/fetch configurations from management server", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - NDB_PORT, - "0", - STR_VALUE(MAX_PORT_NO) }, - - { - KEY_INTERNAL, - "PortNumberStats", - MGM_TOKEN, - "Port number used to get statistical information from a management server", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - UNDEFINED, - "0", - STR_VALUE(MAX_PORT_NO) }, - - { - CFG_NODE_ARBIT_RANK, - "ArbitrationRank", - MGM_TOKEN, - "If 0, then "MGM_TOKEN_PRINT" is not arbitrator. Kernel selects arbitrators in order 1, 2", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "1", - "0", - "2" }, - - { - CFG_NODE_ARBIT_DELAY, - "ArbitrationDelay", - MGM_TOKEN, - "", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "0", - "0", - STR_VALUE(MAX_INT_RNIL) }, - - /**************************************************************************** - * TCP - ***************************************************************************/ - { - CFG_SECTION_CONNECTION, - "TCP", - "TCP", - "Connection section", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_SECTION, - (const char *)CONNECTION_TYPE_TCP, - 0, 0 - }, - - { - CFG_CONNECTION_HOSTNAME_1, - "HostName1", - "TCP", - "Name/IP of computer on one side of the connection", - ConfigInfo::CI_INTERNAL, - false, - ConfigInfo::CI_STRING, - UNDEFINED, - 0, 0 }, - - { - CFG_CONNECTION_HOSTNAME_2, - "HostName2", - "TCP", - "Name/IP of computer on one side of the connection", - ConfigInfo::CI_INTERNAL, - false, - ConfigInfo::CI_STRING, - UNDEFINED, - 0, 0 }, - - { - CFG_CONNECTION_NODE_1, - "NodeId1", - "TCP", - "Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_STRING, - MANDATORY, - 0, 0 }, - - { - CFG_CONNECTION_NODE_2, - "NodeId2", - "TCP", - "Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_STRING, - MANDATORY, - 0, 0 }, - - { - CFG_CONNECTION_GROUP, - "Group", - "TCP", - "", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "55", - "0", "200" }, - - { - CFG_CONNECTION_NODE_ID_SERVER, - "NodeIdServer", - "TCP", - "", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - MANDATORY, - "1", "63" }, - - { - CFG_CONNECTION_SEND_SIGNAL_ID, - "SendSignalId", - "TCP", - "Sends id in each signal. Used in trace files.", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_BOOL, - "true", - "false", - "true" }, - - - { - CFG_CONNECTION_CHECKSUM, - "Checksum", - "TCP", - "If checksum is enabled, all signals between nodes are checked for errors", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_BOOL, - "false", - "false", - "true" }, - - { - CFG_CONNECTION_SERVER_PORT, - "PortNumber", - "TCP", - "Port used for this transporter", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - MANDATORY, - "0", - STR_VALUE(MAX_PORT_NO) }, - - { - CFG_TCP_SEND_BUFFER_SIZE, - "SendBufferMemory", - "TCP", - "Bytes of buffer for signals sent from this node", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "256K", - "64K", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_TCP_RECEIVE_BUFFER_SIZE, - "ReceiveBufferMemory", - "TCP", - "Bytes of buffer for signals received by this node", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "64K", - "16K", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_TCP_PROXY, - "Proxy", - "TCP", - "", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_STRING, - UNDEFINED, - 0, 0 }, - - { - CFG_CONNECTION_NODE_1_SYSTEM, - "NodeId1_System", - "TCP", - "System for node 1 in connection", - ConfigInfo::CI_INTERNAL, - false, - ConfigInfo::CI_STRING, - UNDEFINED, - 0, 0 }, - - { - CFG_CONNECTION_NODE_2_SYSTEM, - "NodeId2_System", - "TCP", - "System for node 2 in connection", - ConfigInfo::CI_INTERNAL, - false, - ConfigInfo::CI_STRING, - UNDEFINED, - 0, 0 }, - - - /**************************************************************************** - * SHM - ***************************************************************************/ - { - CFG_SECTION_CONNECTION, - "SHM", - "SHM", - "Connection section", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_SECTION, - (const char *)CONNECTION_TYPE_SHM, - 0, 0 }, - - { - CFG_CONNECTION_HOSTNAME_1, - "HostName1", - "SHM", - "Name/IP of computer on one side of the connection", - ConfigInfo::CI_INTERNAL, - false, - ConfigInfo::CI_STRING, - UNDEFINED, - 0, 0 }, - - { - CFG_CONNECTION_HOSTNAME_2, - "HostName2", - "SHM", - "Name/IP of computer on one side of the connection", - ConfigInfo::CI_INTERNAL, - false, - ConfigInfo::CI_STRING, - UNDEFINED, - 0, 0 }, - - { - CFG_CONNECTION_SERVER_PORT, - "PortNumber", - "SHM", - "Port used for this transporter", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - MANDATORY, - "0", - STR_VALUE(MAX_PORT_NO) }, - - { - CFG_SHM_SIGNUM, - "Signum", - "SHM", - "Signum to be used for signalling", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - UNDEFINED, - "0", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_CONNECTION_NODE_1, - "NodeId1", - "SHM", - "Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_STRING, - MANDATORY, - 0, 0 }, - - { - CFG_CONNECTION_NODE_2, - "NodeId2", - "SHM", - "Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_STRING, - MANDATORY, - 0, 0 }, - - { - CFG_CONNECTION_GROUP, - "Group", - "SHM", - "", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "35", - "0", "200" }, - - { - CFG_CONNECTION_NODE_ID_SERVER, - "NodeIdServer", - "SHM", - "", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - MANDATORY, - "1", "63" }, - - { - CFG_CONNECTION_SEND_SIGNAL_ID, - "SendSignalId", - "SHM", - "Sends id in each signal. Used in trace files.", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_BOOL, - "false", - "false", - "true" }, - - - { - CFG_CONNECTION_CHECKSUM, - "Checksum", - "SHM", - "If checksum is enabled, all signals between nodes are checked for errors", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_BOOL, - "true", - "false", - "true" }, - - { - CFG_SHM_KEY, - "ShmKey", - "SHM", - "A shared memory key", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - UNDEFINED, - "0", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_SHM_BUFFER_MEM, - "ShmSize", - "SHM", - "Size of shared memory segment", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "1M", - "64K", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_CONNECTION_NODE_1_SYSTEM, - "NodeId1_System", - "SHM", - "System for node 1 in connection", - ConfigInfo::CI_INTERNAL, - false, - ConfigInfo::CI_STRING, - UNDEFINED, - 0, 0 }, - - { - CFG_CONNECTION_NODE_2_SYSTEM, - "NodeId2_System", - "SHM", - "System for node 2 in connection", - ConfigInfo::CI_INTERNAL, - false, - ConfigInfo::CI_STRING, - UNDEFINED, - 0, 0 }, - - /**************************************************************************** - * SCI - ***************************************************************************/ - { - CFG_SECTION_CONNECTION, - "SCI", - "SCI", - "Connection section", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_SECTION, - (const char *)CONNECTION_TYPE_SCI, - 0, 0 - }, - - { - CFG_CONNECTION_NODE_1, - "NodeId1", - "SCI", - "Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_STRING, - MANDATORY, - "0", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_CONNECTION_NODE_2, - "NodeId2", - "SCI", - "Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_STRING, - MANDATORY, - "0", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_CONNECTION_GROUP, - "Group", - "SCI", - "", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "15", - "0", "200" }, - - { - CFG_CONNECTION_NODE_ID_SERVER, - "NodeIdServer", - "SCI", - "", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - MANDATORY, - "1", "63" }, - - { - CFG_CONNECTION_HOSTNAME_1, - "HostName1", - "SCI", - "Name/IP of computer on one side of the connection", - ConfigInfo::CI_INTERNAL, - false, - ConfigInfo::CI_STRING, - UNDEFINED, - 0, 0 }, - - { - CFG_CONNECTION_HOSTNAME_2, - "HostName2", - "SCI", - "Name/IP of computer on one side of the connection", - ConfigInfo::CI_INTERNAL, - false, - ConfigInfo::CI_STRING, - UNDEFINED, - 0, 0 }, - - { - CFG_CONNECTION_SERVER_PORT, - "PortNumber", - "SCI", - "Port used for this transporter", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - MANDATORY, - "0", - STR_VALUE(MAX_PORT_NO) }, - - { - CFG_SCI_HOST1_ID_0, - "Host1SciId0", - "SCI", - "SCI-node id for adapter 0 on Host1 (a computer can have two adapters)", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - MANDATORY, - "0", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_SCI_HOST1_ID_1, - "Host1SciId1", - "SCI", - "SCI-node id for adapter 1 on Host1 (a computer can have two adapters)", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "0", - "0", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_SCI_HOST2_ID_0, - "Host2SciId0", - "SCI", - "SCI-node id for adapter 0 on Host2 (a computer can have two adapters)", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - MANDATORY, - "0", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_SCI_HOST2_ID_1, - "Host2SciId1", - "SCI", - "SCI-node id for adapter 1 on Host2 (a computer can have two adapters)", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "0", - "0", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_CONNECTION_SEND_SIGNAL_ID, - "SendSignalId", - "SCI", - "Sends id in each signal. Used in trace files.", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_BOOL, - "true", - "false", - "true" }, - - { - CFG_CONNECTION_CHECKSUM, - "Checksum", - "SCI", - "If checksum is enabled, all signals between nodes are checked for errors", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_BOOL, - "false", - "false", - "true" }, - - { - CFG_SCI_SEND_LIMIT, - "SendLimit", - "SCI", - "Transporter send buffer contents are sent when this no of bytes is buffered", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "8K", - "128", - "32K" }, - - { - CFG_SCI_BUFFER_MEM, - "SharedBufferSize", - "SCI", - "Size of shared memory segment", - ConfigInfo::CI_USED, - false, - ConfigInfo::CI_INT, - "1M", - "64K", - STR_VALUE(MAX_INT_RNIL) }, - - { - CFG_CONNECTION_NODE_1_SYSTEM, - "NodeId1_System", - "SCI", - "System for node 1 in connection", - ConfigInfo::CI_INTERNAL, - false, - ConfigInfo::CI_STRING, - UNDEFINED, - 0, 0 }, - - { - CFG_CONNECTION_NODE_2_SYSTEM, - "NodeId2_System", - "SCI", - "System for node 2 in connection", - ConfigInfo::CI_INTERNAL, - false, - ConfigInfo::CI_STRING, - UNDEFINED, - 0, 0 } -}; - -const int ConfigInfo::m_NoOfParams = sizeof(m_ParamInfo) / sizeof(ParamInfo); - -#ifndef NDB_MGMAPI -/**************************************************************************** - * Ctor - ****************************************************************************/ -static void require(bool v) -{ - if(!v) - { - if (opt_core) - abort(); - else - exit(-1); - } -} - -ConfigInfo::ConfigInfo() - : m_info(true), m_systemDefaults(true) -{ - int i; - Properties *section; - const Properties *oldpinfo; - - for (i=0; i<m_NoOfParams; i++) { - const ParamInfo & param = m_ParamInfo[i]; - Uint64 default_uint64; - bool default_bool; - - // Create new section if it did not exist - if (!m_info.getCopy(param._section, §ion)) { - Properties newsection(true); - m_info.put(param._section, &newsection); - - // Get copy of section - m_info.getCopy(param._section, §ion); - } - - // Create pinfo (parameter info) entry - Properties pinfo(true); - pinfo.put("Id", param._paramId); - pinfo.put("Fname", param._fname); - pinfo.put("Description", param._description); - pinfo.put("Updateable", param._updateable); - pinfo.put("Type", param._type); - pinfo.put("Status", param._status); - - if(param._default == MANDATORY){ - pinfo.put("Mandatory", (Uint32)1); - } - - switch (param._type) { - case CI_BOOL: - { - bool tmp_bool; - require(InitConfigFileParser::convertStringToBool(param._min, tmp_bool)); - pinfo.put64("Min", tmp_bool); - require(InitConfigFileParser::convertStringToBool(param._max, tmp_bool)); - pinfo.put64("Max", tmp_bool); - break; - } - case CI_INT: - case CI_INT64: - { - Uint64 tmp_uint64; - require(InitConfigFileParser::convertStringToUint64(param._min, tmp_uint64)); - pinfo.put64("Min", tmp_uint64); - require(InitConfigFileParser::convertStringToUint64(param._max, tmp_uint64)); - pinfo.put64("Max", tmp_uint64); - break; - } - case CI_SECTION: - pinfo.put("SectionType", (Uint32)UintPtr(param._default)); - break; - case CI_STRING: - break; - } - - // Check that pinfo is really new - if (section->get(param._fname, &oldpinfo)) { - ndbout << "Error: Parameter " << param._fname - << " defined twice in section " << param._section - << "." << endl; - require(false); - } - - // Add new pinfo to section - section->put(param._fname, &pinfo); - - // Replace section with modified section - m_info.put(param._section, section, true); - delete section; - - if(param._type != ConfigInfo::CI_SECTION){ - Properties * p; - if(!m_systemDefaults.getCopy(param._section, &p)){ - p = new Properties(true); - } - if(param._default != UNDEFINED && - param._default != MANDATORY){ - switch (param._type) - { - case CI_SECTION: - break; - case CI_STRING: - require(p->put(param._fname, param._default)); - break; - case CI_BOOL: - { - require(InitConfigFileParser::convertStringToBool(param._default, default_bool)); - require(p->put(param._fname, default_bool)); - break; - } - case CI_INT: - case CI_INT64: - { - require(InitConfigFileParser::convertStringToUint64(param._default, default_uint64)); - require(p->put(param._fname, default_uint64)); - break; - } - } - } - require(m_systemDefaults.put(param._section, p, true)); - delete p; - } - } - - for (i=0; i<m_NoOfParams; i++) { - if(m_ParamInfo[i]._section == NULL){ - ndbout << "Check that each entry has a section failed." << endl; - ndbout << "Parameter \"" << m_ParamInfo[i]._fname << endl; - ndbout << "Edit file " << __FILE__ << "." << endl; - require(false); - } - - if(m_ParamInfo[i]._type == ConfigInfo::CI_SECTION) - continue; - - const Properties * p = getInfo(m_ParamInfo[i]._section); - if (!p || !p->contains(m_ParamInfo[i]._fname)) { - ndbout << "Check that each pname has an fname failed." << endl; - ndbout << "Parameter \"" << m_ParamInfo[i]._fname - << "\" does not exist in section \"" - << m_ParamInfo[i]._section << "\"." << endl; - ndbout << "Edit file " << __FILE__ << "." << endl; - require(false); - } - } -} - -/**************************************************************************** - * Getters - ****************************************************************************/ -inline void warning(const char * src, const char * arg){ - ndbout << "Illegal call to ConfigInfo::" << src << "() - " << arg << endl; - require(false); -} - -const Properties * -ConfigInfo::getInfo(const char * section) const { - const Properties * p; - if(!m_info.get(section, &p)){ - return 0; - // warning("getInfo", section); - } - return p; -} - -const Properties * -ConfigInfo::getDefaults(const char * section) const { - const Properties * p; - if(!m_systemDefaults.get(section, &p)){ - return 0; - //warning("getDefaults", section); - } - return p; -} - -static -Uint64 -getInfoInt(const Properties * section, - const char* fname, const char * type){ - Uint32 val32; - const Properties * p; - if (section->get(fname, &p) && p->get(type, &val32)) { - return val32; - } - - Uint64 val64; - if(p && p->get(type, &val64)){ - return val64; - } - - section->print(); - if(section->get(fname, &p)){ - p->print(); - } - - warning(type, fname); - return 0; -} - -static -const char * -getInfoString(const Properties * section, - const char* fname, const char * type){ - const char* val; - const Properties * p; - if (section->get(fname, &p) && p->get(type, &val)) { - return val; - } - warning(type, fname); - return val; -} - -Uint64 -ConfigInfo::getMax(const Properties * section, const char* fname) const { - return getInfoInt(section, fname, "Max"); -} - -Uint64 -ConfigInfo::getMin(const Properties * section, const char* fname) const { - return getInfoInt(section, fname, "Min"); -} - -Uint64 -ConfigInfo::getDefault(const Properties * section, const char* fname) const { - return getInfoInt(section, fname, "Default"); -} - -const char* -ConfigInfo::getDescription(const Properties * section, - const char* fname) const { - return getInfoString(section, fname, "Description"); -} - -bool -ConfigInfo::isSection(const char * section) const { - for (int i = 0; i<m_noOfSectionNames; i++) { - if(!strcasecmp(section, m_sectionNames[i])) return true; - } - return false; -} - -const char* -ConfigInfo::nameToAlias(const char * name) { - for (int i = 0; m_sectionNameAliases[i].name != 0; i++) - if(!strcasecmp(name, m_sectionNameAliases[i].name)) - return m_sectionNameAliases[i].alias; - return 0; -} - -const char* -ConfigInfo::getAlias(const char * section) { - for (int i = 0; m_sectionNameAliases[i].name != 0; i++) - if(!strcasecmp(section, m_sectionNameAliases[i].alias)) - return m_sectionNameAliases[i].name; - return 0; -} - -bool -ConfigInfo::verify(const Properties * section, const char* fname, - Uint64 value) const { - Uint64 min, max; - - min = getInfoInt(section, fname, "Min"); - max = getInfoInt(section, fname, "Max"); - if(min > max){ - warning("verify", fname); - } - if (value >= min && value <= max) - return true; - else - return false; -} - -ConfigInfo::Type -ConfigInfo::getType(const Properties * section, const char* fname) const { - return (ConfigInfo::Type) getInfoInt(section, fname, "Type"); -} - -ConfigInfo::Status -ConfigInfo::getStatus(const Properties * section, const char* fname) const { - return (ConfigInfo::Status) getInfoInt(section, fname, "Status"); -} - -/**************************************************************************** - * Printers - ****************************************************************************/ - -void ConfigInfo::print() const { - Properties::Iterator it(&m_info); - for (const char* n = it.first(); n != NULL; n = it.next()) { - print(n); - } -} - -void ConfigInfo::print(const char* section) const { - ndbout << "****** " << section << " ******" << endl << endl; - const Properties * sec = getInfo(section); - Properties::Iterator it(sec); - for (const char* n = it.first(); n != NULL; n = it.next()) { - // Skip entries with different F- and P-names - if (getStatus(sec, n) == ConfigInfo::CI_INTERNAL) continue; - if (getStatus(sec, n) == ConfigInfo::CI_DEPRICATED) continue; - if (getStatus(sec, n) == ConfigInfo::CI_NOTIMPLEMENTED) continue; - print(sec, n); - } -} - -void ConfigInfo::print(const Properties * section, - const char* parameter) const { - ndbout << parameter; - // ndbout << getDescription(section, parameter) << endl; - switch (getType(section, parameter)) { - case ConfigInfo::CI_BOOL: - ndbout << " (Boolean value)" << endl; - ndbout << getDescription(section, parameter) << endl; - if (getDefault(section, parameter) == false) { - ndbout << "Default: N (Legal values: Y, N)" << endl; - } else if (getDefault(section, parameter) == true) { - ndbout << "Default: Y (Legal values: Y, N)" << endl; - } else if (getDefault(section, parameter) == (UintPtr)MANDATORY) { - ndbout << "MANDATORY (Legal values: Y, N)" << endl; - } else { - ndbout << "UNKNOWN" << endl; - } - ndbout << endl; - break; - - case ConfigInfo::CI_INT: - case ConfigInfo::CI_INT64: - ndbout << " (Non-negative Integer)" << endl; - ndbout << getDescription(section, parameter) << endl; - if (getDefault(section, parameter) == (UintPtr)MANDATORY) { - ndbout << "MANDATORY ("; - } else if (getDefault(section, parameter) == (UintPtr)UNDEFINED) { - ndbout << "UNDEFINED ("; - } else { - ndbout << "Default: " << getDefault(section, parameter) << " ("; - } - ndbout << "Min: " << getMin(section, parameter) << ", "; - ndbout << "Max: " << getMax(section, parameter) << ")" << endl; - ndbout << endl; - break; - - case ConfigInfo::CI_STRING: - ndbout << " (String)" << endl; - ndbout << getDescription(section, parameter) << endl; - if (getDefault(section, parameter) == (UintPtr)MANDATORY) { - ndbout << "MANDATORY" << endl; - } else { - ndbout << "No default value" << endl; - } - ndbout << endl; - break; - case ConfigInfo::CI_SECTION: - break; - } -} - -/**************************************************************************** - * Section Rules - ****************************************************************************/ - -/** - * Node rule: Add "Type" and update "NoOfNodes" - */ -bool -transformNode(InitConfigFileParser::Context & ctx, const char * data){ - - Uint32 id, line; - if(!ctx.m_currentSection->get("NodeId", &id) && !ctx.m_currentSection->get("Id", &id)){ - Uint32 nextNodeId= 1; - ctx.m_userProperties.get("NextNodeId", &nextNodeId); - id= nextNodeId; - while (ctx.m_userProperties.get("AllocatedNodeId_", id, &line)) - id++; - if (id != nextNodeId) - { - fprintf(stderr,"Cluster configuration warning line %d: " - "Could not use next node id %d for section [%s], " - "using next unused node id %d.\n", - ctx.m_sectionLineno, nextNodeId, ctx.fname, id); - } - ctx.m_currentSection->put("NodeId", id); - } else if(ctx.m_userProperties.get("AllocatedNodeId_", id, &line)) { - ctx.reportError("Duplicate nodeid in section " - "[%s] starting at line: %d. Previously used on line %d.", - ctx.fname, ctx.m_sectionLineno, line); - return false; - } - - if(id >= MAX_NODES) - { - ctx.reportError("too many nodes configured, only up to %d nodes supported.", - MAX_NODES); - return false; - } - - // next node id _always_ next numbers after last used id - ctx.m_userProperties.put("NextNodeId", id+1, true); - - ctx.m_userProperties.put("AllocatedNodeId_", id, ctx.m_sectionLineno); - BaseString::snprintf(ctx.pname, sizeof(ctx.pname), "Node_%d", id); - - ctx.m_currentSection->put("Type", ctx.fname); - - Uint32 nodes = 0; - ctx.m_userProperties.get("NoOfNodes", &nodes); - ctx.m_userProperties.put("NoOfNodes", ++nodes, true); - - /** - * Update count (per type) - */ - nodes = 0; - ctx.m_userProperties.get(ctx.fname, &nodes); - ctx.m_userProperties.put(ctx.fname, ++nodes, true); - - return true; -} - -static bool checkLocalhostHostnameMix(InitConfigFileParser::Context & ctx, const char * data) -{ - DBUG_ENTER("checkLocalhostHostnameMix"); - const char * hostname= 0; - ctx.m_currentSection->get("HostName", &hostname); - if (hostname == 0 || hostname[0] == 0) - DBUG_RETURN(true); - - Uint32 localhost_used= 0; - if(!strcmp(hostname, "localhost") || !strcmp(hostname, "127.0.0.1")){ - localhost_used= 1; - ctx.m_userProperties.put("$computer-localhost-used", localhost_used); - if(!ctx.m_userProperties.get("$computer-localhost", &hostname)) - DBUG_RETURN(true); - } else { - ctx.m_userProperties.get("$computer-localhost-used", &localhost_used); - ctx.m_userProperties.put("$computer-localhost", hostname); - } - - if (localhost_used) { - ctx.reportError("Mixing of localhost (default for [NDBD]HostName) with other hostname(%s) is illegal", - hostname); - DBUG_RETURN(false); - } - - DBUG_RETURN(true); -} - -bool -fixNodeHostname(InitConfigFileParser::Context & ctx, const char * data) -{ - const char * hostname; - DBUG_ENTER("fixNodeHostname"); - - if (ctx.m_currentSection->get("HostName", &hostname)) - DBUG_RETURN(checkLocalhostHostnameMix(ctx,0)); - - const char * compId; - if(!ctx.m_currentSection->get("ExecuteOnComputer", &compId)) - DBUG_RETURN(true); - - const Properties * computer; - char tmp[255]; - BaseString::snprintf(tmp, sizeof(tmp), "Computer_%s", compId); - if(!ctx.m_config->get(tmp, &computer)){ - ctx.reportError("Computer \"%s\" not declared" - "- [%s] starting at line: %d", - compId, ctx.fname, ctx.m_sectionLineno); - DBUG_RETURN(false); - } - - if(!computer->get("HostName", &hostname)){ - ctx.reportError("HostName missing in [COMPUTER] (Id: %d) " - " - [%s] starting at line: %d", - compId, ctx.fname, ctx.m_sectionLineno); - DBUG_RETURN(false); - } - - require(ctx.m_currentSection->put("HostName", hostname)); - DBUG_RETURN(checkLocalhostHostnameMix(ctx,0)); -} - -bool -fixFileSystemPath(InitConfigFileParser::Context & ctx, const char * data){ - DBUG_ENTER("fixFileSystemPath"); - - const char * path; - if (ctx.m_currentSection->get("FileSystemPath", &path)) - DBUG_RETURN(true); - - if (ctx.m_currentSection->get("DataDir", &path)) { - require(ctx.m_currentSection->put("FileSystemPath", path)); - DBUG_RETURN(true); - } - - require(false); - DBUG_RETURN(false); -} - -bool -fixBackupDataDir(InitConfigFileParser::Context & ctx, const char * data){ - - const char * path; - if (ctx.m_currentSection->get("BackupDataDir", &path)) - return true; - - if (ctx.m_currentSection->get("FileSystemPath", &path)) { - require(ctx.m_currentSection->put("BackupDataDir", path)); - return true; - } - - require(false); - return false; -} - -/** - * Connection rule: Check support of connection - */ -bool -checkConnectionSupport(InitConfigFileParser::Context & ctx, const char * data) -{ - int error= 0; - if (strcasecmp("TCP",ctx.fname) == 0) - { - // always enabled - } - else if (strcasecmp("SHM",ctx.fname) == 0) - { -#ifndef NDB_SHM_TRANSPORTER - error= 1; -#endif - } - else if (strcasecmp("SCI",ctx.fname) == 0) - { -#ifndef NDB_SCI_TRANSPORTER - error= 1; -#endif - } - - if (error) - { - ctx.reportError("Binary not compiled with this connection support, " - "[%s] starting at line: %d", - ctx.fname, ctx.m_sectionLineno); - return false; - } - return true; -} - -/** - * Connection rule: Update "NoOfConnections" - */ -bool -transformConnection(InitConfigFileParser::Context & ctx, const char * data) -{ - Uint32 connections = 0; - ctx.m_userProperties.get("NoOfConnections", &connections); - BaseString::snprintf(ctx.pname, sizeof(ctx.pname), "Connection_%d", connections); - ctx.m_userProperties.put("NoOfConnections", ++connections, true); - - ctx.m_currentSection->put("Type", ctx.fname); - return true; -} - -/** - * System rule: Just add it - */ -bool -transformSystem(InitConfigFileParser::Context & ctx, const char * data){ - - const char * name; - if(!ctx.m_currentSection->get("Name", &name)){ - ctx.reportError("Mandatory parameter Name missing from section " - "[%s] starting at line: %d", - ctx.fname, ctx.m_sectionLineno); - return false; - } - - ndbout << "transformSystem " << name << endl; - - BaseString::snprintf(ctx.pname, sizeof(ctx.pname), "SYSTEM_%s", name); - - return true; -} - -/** - * Computer rule: Update "NoOfComputers", add "Type" - */ -bool -transformComputer(InitConfigFileParser::Context & ctx, const char * data){ - const char * id; - if(!ctx.m_currentSection->get("Id", &id)){ - ctx.reportError("Mandatory parameter Id missing from section " - "[%s] starting at line: %d", - ctx.fname, ctx.m_sectionLineno); - return false; - } - BaseString::snprintf(ctx.pname, sizeof(ctx.pname), "Computer_%s", id); - - Uint32 computers = 0; - ctx.m_userProperties.get("NoOfComputers", &computers); - ctx.m_userProperties.put("NoOfComputers", ++computers, true); - - const char * hostname = 0; - ctx.m_currentSection->get("HostName", &hostname); - if(!hostname){ - return true; - } - - return checkLocalhostHostnameMix(ctx,0); -} - -/** - * Apply default values - */ -void -applyDefaultValues(InitConfigFileParser::Context & ctx, - const Properties * defaults) -{ - DBUG_ENTER("applyDefaultValues"); - if(defaults != NULL){ - Properties::Iterator it(defaults); - - for(const char * name = it.first(); name != NULL; name = it.next()){ - (void) ctx.m_info->getStatus(ctx.m_currentInfo, name); - if(!ctx.m_currentSection->contains(name)){ - switch (ctx.m_info->getType(ctx.m_currentInfo, name)){ - case ConfigInfo::CI_INT: - case ConfigInfo::CI_BOOL:{ - Uint32 val = 0; - ::require(defaults->get(name, &val)); - ctx.m_currentSection->put(name, val); - DBUG_PRINT("info",("%s=%d #default",name,val)); - break; - } - case ConfigInfo::CI_INT64:{ - Uint64 val = 0; - ::require(defaults->get(name, &val)); - ctx.m_currentSection->put64(name, val); - DBUG_PRINT("info",("%s=%lld #default",name,val)); - break; - } - case ConfigInfo::CI_STRING:{ - const char * val; - ::require(defaults->get(name, &val)); - ctx.m_currentSection->put(name, val); - DBUG_PRINT("info",("%s=%s #default",name,val)); - break; - } - case ConfigInfo::CI_SECTION: - break; - } - } -#ifndef DBUG_OFF - else - { - switch (ctx.m_info->getType(ctx.m_currentInfo, name)){ - case ConfigInfo::CI_INT: - case ConfigInfo::CI_BOOL:{ - Uint32 val = 0; - ::require(ctx.m_currentSection->get(name, &val)); - DBUG_PRINT("info",("%s=%d",name,val)); - break; - } - case ConfigInfo::CI_INT64:{ - Uint64 val = 0; - ::require(ctx.m_currentSection->get(name, &val)); - DBUG_PRINT("info",("%s=%lld",name,val)); - break; - } - case ConfigInfo::CI_STRING:{ - const char * val; - ::require(ctx.m_currentSection->get(name, &val)); - DBUG_PRINT("info",("%s=%s",name,val)); - break; - } - case ConfigInfo::CI_SECTION: - break; - } - } -#endif - } - } - DBUG_VOID_RETURN; -} - -bool -applyDefaultValues(InitConfigFileParser::Context & ctx, const char * data){ - - if(strcmp(data, "user") == 0) - applyDefaultValues(ctx, ctx.m_userDefaults); - else if (strcmp(data, "system") == 0) - applyDefaultValues(ctx, ctx.m_systemDefaults); - else - return false; - - return true; -} - -/** - * Check that a section contains all MANDATORY parameters - */ -bool -checkMandatory(InitConfigFileParser::Context & ctx, const char * data){ - - Properties::Iterator it(ctx.m_currentInfo); - for(const char * name = it.first(); name != NULL; name = it.next()){ - const Properties * info = NULL; - ::require(ctx.m_currentInfo->get(name, &info)); - Uint32 val; - if(info->get("Mandatory", &val)){ - const char * fname; - ::require(info->get("Fname", &fname)); - if(!ctx.m_currentSection->contains(fname)){ - ctx.reportError("Mandatory parameter %s missing from section " - "[%s] starting at line: %d", - fname, ctx.fname, ctx.m_sectionLineno); - return false; - } - } - } - return true; -} - -/** - * Connection rule: Fix node id - * - * Transform a string "NodeidX" (e.g. "uppsala.32") - * into a Uint32 "NodeIdX" (e.g. 32) and a string "SystemX" (e.g. "uppsala"). - */ -static bool fixNodeId(InitConfigFileParser::Context & ctx, const char * data) -{ - char buf[] = "NodeIdX"; buf[6] = data[sizeof("NodeI")]; - char sysbuf[] = "SystemX"; sysbuf[6] = data[sizeof("NodeI")]; - const char* nodeId; - if(!ctx.m_currentSection->get(buf, &nodeId)) - { - ctx.reportError("Mandatory parameter %s missing from section" - "[%s] starting at line: %d", - buf, ctx.fname, ctx.m_sectionLineno); - return false; - } - - char tmpLine[MAX_LINE_LENGTH]; - strncpy(tmpLine, nodeId, MAX_LINE_LENGTH); - char* token1 = strtok(tmpLine, "."); - char* token2 = strtok(NULL, "."); - Uint32 id; - - if(!token1) - { - ctx.reportError("Value for mandatory parameter %s missing from section " - "[%s] starting at line: %d", - buf, ctx.fname, ctx.m_sectionLineno); - return false; - } - if (token2 == NULL) { // Only a number given - errno = 0; - char* p; - id = strtol(token1, &p, 10); - if (errno != 0 || id <= 0x0 || id > MAX_NODES) - { - ctx.reportError("Illegal value for mandatory parameter %s from section " - "[%s] starting at line: %d", - buf, ctx.fname, ctx.m_sectionLineno); - return false; - } - require(ctx.m_currentSection->put(buf, id, true)); - } else { // A pair given (e.g. "uppsala.32") - errno = 0; - char* p; - id = strtol(token2, &p, 10); - if (errno != 0 || id <= 0x0 || id > MAX_NODES) - { - ctx.reportError("Illegal value for mandatory parameter %s from section " - "[%s] starting at line: %d", - buf, ctx.fname, ctx.m_sectionLineno); - return false; - } - require(ctx.m_currentSection->put(buf, id, true)); - require(ctx.m_currentSection->put(sysbuf, token1)); - } - return true; -} - -/** - * Connection rule: Fix hostname - * - * Unless Hostname is not already specified, do steps: - * -# Via Connection's NodeId lookup Node - * -# Via Node's ExecuteOnComputer lookup Hostname - * -# Add HostName to Connection - */ -static bool -fixHostname(InitConfigFileParser::Context & ctx, const char * data){ - - char buf[] = "NodeIdX"; buf[6] = data[sizeof("HostNam")]; - char sysbuf[] = "SystemX"; sysbuf[6] = data[sizeof("HostNam")]; - - if(!ctx.m_currentSection->contains(data)){ - Uint32 id = 0; - require(ctx.m_currentSection->get(buf, &id)); - - const Properties * node; - if(!ctx.m_config->get("Node", id, &node)) - { - ctx.reportError("Unknown node: \"%d\" specified in connection " - "[%s] starting at line: %d", - id, ctx.fname, ctx.m_sectionLineno); - return false; - } - - const char * hostname; - require(node->get("HostName", &hostname)); - require(ctx.m_currentSection->put(data, hostname)); - } - return true; -} - -/** - * Connection rule: Fix port number (using a port number adder) - */ -static bool -fixPortNumber(InitConfigFileParser::Context & ctx, const char * data){ - - DBUG_ENTER("fixPortNumber"); - - Uint32 id1, id2; - const char *hostName1; - const char *hostName2; - require(ctx.m_currentSection->get("NodeId1", &id1)); - require(ctx.m_currentSection->get("NodeId2", &id2)); - require(ctx.m_currentSection->get("HostName1", &hostName1)); - require(ctx.m_currentSection->get("HostName2", &hostName2)); - DBUG_PRINT("info",("NodeId1=%d HostName1=\"%s\"",id1,hostName1)); - DBUG_PRINT("info",("NodeId2=%d HostName2=\"%s\"",id2,hostName2)); - - const Properties *node1, *node2; - require(ctx.m_config->get("Node", id1, &node1)); - require(ctx.m_config->get("Node", id2, &node2)); - - const char *type1, *type2; - require(node1->get("Type", &type1)); - require(node2->get("Type", &type2)); - - /* add NodeIdServer info */ - { - Uint32 nodeIdServer = id1 < id2 ? id1 : id2; - if(strcmp(type1, API_TOKEN) == 0 || strcmp(type2, MGM_TOKEN) == 0) - nodeIdServer = id2; - else if(strcmp(type2, API_TOKEN) == 0 || strcmp(type1, MGM_TOKEN) == 0) - nodeIdServer = id1; - ctx.m_currentSection->put("NodeIdServer", nodeIdServer); - - if (id2 == nodeIdServer) { - { - const char *tmp= hostName1; - hostName1= hostName2; - hostName2= tmp; - } - { - Uint32 tmp= id1; - id1= id2; - id2= tmp; - } - { - const Properties *tmp= node1; - node1= node2; - node2= tmp; - } - { - const char *tmp= type1; - type1= type2; - type2= tmp; - } - } - } - - BaseString hostname(hostName1); - - if (hostname.c_str()[0] == 0) { - ctx.reportError("Hostname required on nodeid %d since it will " - "act as server.", id1); - DBUG_RETURN(false); - } - - Uint32 port= 0; - if(strcmp(type1, MGM_TOKEN)==0) - node1->get("PortNumber",&port); - else if(strcmp(type2, MGM_TOKEN)==0) - node2->get("PortNumber",&port); - - if (!port && - !node1->get("ServerPort", &port) && - !ctx.m_userProperties.get("ServerPort_", id1, &port)) - { - Uint32 base= 0; - /* - * If the connection doesn't involve an mgm server, - * and a default port number has been set, behave the old - * way of allocating port numbers for transporters. - */ - if(ctx.m_userDefaults && ctx.m_userDefaults->get("PortNumber", &base)) - { - Uint32 adder= 0; - { - BaseString server_port_adder(hostname); - server_port_adder.append("_ServerPortAdder"); - ctx.m_userProperties.get(server_port_adder.c_str(), &adder); - ctx.m_userProperties.put(server_port_adder.c_str(), adder+1, true); - } - - if (!ctx.m_userProperties.get("ServerPortBase", &base)){ - if(!(ctx.m_userDefaults && - ctx.m_userDefaults->get("PortNumber", &base)) && - !ctx.m_systemDefaults->get("PortNumber", &base)) { - base= strtoll(NDB_TCP_BASE_PORT,0,0); - } - ctx.m_userProperties.put("ServerPortBase", base); - } - - port= base + adder; - ctx.m_userProperties.put("ServerPort_", id1, port); - } - } - - if(ctx.m_currentSection->contains("PortNumber")) { - ndbout << "PortNumber should no longer be specificied " - << "per connection, please remove from config. " - << "Will be changed to " << port << endl; - ctx.m_currentSection->put("PortNumber", port, true); - } - else - { - ctx.m_currentSection->put("PortNumber", port); - } - - DBUG_PRINT("info", ("connection %d-%d port %d host %s", - id1, id2, port, hostname.c_str())); - - DBUG_RETURN(true); -} - -static bool -fixShmUniqueId(InitConfigFileParser::Context & ctx, const char * data) -{ - DBUG_ENTER("fixShmUniqueId"); - Uint32 nodes= 0; - ctx.m_userProperties.get(ctx.fname, &nodes); - if (nodes == 1) // first management server - { - Uint32 portno= atoi(NDB_PORT); - ctx.m_currentSection->get("PortNumber", &portno); - ctx.m_userProperties.put("ShmUniqueId", portno); - } - DBUG_RETURN(true); -} - -static -bool -fixShmKey(InitConfigFileParser::Context & ctx, const char *) -{ - DBUG_ENTER("fixShmKey"); - { - static int last_signum= -1; - Uint32 signum; - if(!ctx.m_currentSection->get("Signum", &signum)) - { - signum= OPT_NDB_SHM_SIGNUM_DEFAULT; - if (signum <= 0) - { - ctx.reportError("Unable to set default parameter for [SHM]Signum" - " please specify [SHM DEFAULT]Signum"); - return false; - } - ctx.m_currentSection->put("Signum", signum); - DBUG_PRINT("info",("Added Signum=%u", signum)); - } - if ( last_signum != (int)signum && last_signum >= 0 ) - { - ctx.reportError("All shared memory transporters must have same [SHM]Signum defined." - " Use [SHM DEFAULT]Signum"); - return false; - } - last_signum= (int)signum; - } - { - Uint32 id1= 0, id2= 0, key= 0; - require(ctx.m_currentSection->get("NodeId1", &id1)); - require(ctx.m_currentSection->get("NodeId2", &id2)); - if(!ctx.m_currentSection->get("ShmKey", &key)) - { - require(ctx.m_userProperties.get("ShmUniqueId", &key)); - key= key << 16 | (id1 > id2 ? id1 << 8 | id2 : id2 << 8 | id1); - ctx.m_currentSection->put("ShmKey", key); - DBUG_PRINT("info",("Added ShmKey=0x%x", key)); - } - } - DBUG_RETURN(true); -} - -/** - * DB Node rule: Check various constraints - */ -static bool -checkDbConstraints(InitConfigFileParser::Context & ctx, const char *){ - - Uint32 t1 = 0, t2 = 0; - ctx.m_currentSection->get("MaxNoOfConcurrentOperations", &t1); - ctx.m_currentSection->get("MaxNoOfConcurrentTransactions", &t2); - - if (t1 < t2) { - ctx.reportError("MaxNoOfConcurrentOperations must be greater than " - "MaxNoOfConcurrentTransactions - [%s] starting at line: %d", - ctx.fname, ctx.m_sectionLineno); - return false; - } - - Uint32 replicas = 0, otherReplicas; - ctx.m_currentSection->get("NoOfReplicas", &replicas); - if(ctx.m_userProperties.get("NoOfReplicas", &otherReplicas)){ - if(replicas != otherReplicas){ - ctx.reportError("NoOfReplicas defined differently on different nodes" - " - [%s] starting at line: %d", - ctx.fname, ctx.m_sectionLineno); - return false; - } - } else { - ctx.m_userProperties.put("NoOfReplicas", replicas); - } - - /** - * In kernel, will calculate the MaxNoOfMeataTables use the following sum: - * Uint32 noOfMetaTables = noOfTables + noOfOrderedIndexes + - * noOfUniqueHashIndexes + 2 - * 2 is the number of the SysTables. - * So must check that the sum does't exceed the max value of Uint32. - */ - Uint32 noOfTables = 0, - noOfOrderedIndexes = 0, - noOfUniqueHashIndexes = 0; - ctx.m_currentSection->get("MaxNoOfTables", &noOfTables); - ctx.m_currentSection->get("MaxNoOfOrderedIndexes", &noOfOrderedIndexes); - ctx.m_currentSection->get("MaxNoOfUniqueHashIndexes", &noOfUniqueHashIndexes); - - Uint64 sum= (Uint64)noOfTables + noOfOrderedIndexes + noOfUniqueHashIndexes; - - if (sum > ((Uint32)~0 - 2)) { - ctx.reportError("The sum of MaxNoOfTables, MaxNoOfOrderedIndexes and" - " MaxNoOfUniqueHashIndexes must not exceed %u - [%s]" - " starting at line: %d", - ((Uint32)~0 - 2), ctx.fname, ctx.m_sectionLineno); - return false; - } - - return true; -} - -/** - * Connection rule: Check varius constraints - */ -static bool -checkConnectionConstraints(InitConfigFileParser::Context & ctx, const char *){ - - Uint32 id1 = 0, id2 = 0; - ctx.m_currentSection->get("NodeId1", &id1); - ctx.m_currentSection->get("NodeId2", &id2); - - if(id1 == id2){ - ctx.reportError("Illegal connection from node to itself" - " - [%s] starting at line: %d", - ctx.fname, ctx.m_sectionLineno); - return false; - } - - const Properties * node1; - if(!ctx.m_config->get("Node", id1, &node1)){ - ctx.reportError("Connection refering to undefined node: %d" - " - [%s] starting at line: %d", - id1, ctx.fname, ctx.m_sectionLineno); - return false; - } - - const Properties * node2; - if(!ctx.m_config->get("Node", id2, &node2)){ - ctx.reportError("Connection refering to undefined node: %d" - " - [%s] starting at line: %d", - id2, ctx.fname, ctx.m_sectionLineno); - return false; - } - - const char * type1; - const char * type2; - require(node1->get("Type", &type1)); - require(node2->get("Type", &type2)); - - /** - * Report error if the following are true - * -# None of the nodes is of type DB - * -# Not both of them are MGMs - */ - if((strcmp(type1, DB_TOKEN) != 0 && strcmp(type2, DB_TOKEN) != 0) && - !(strcmp(type1, MGM_TOKEN) == 0 && strcmp(type2, MGM_TOKEN) == 0)) - { - ctx.reportError("Invalid connection between node %d (%s) and node %d (%s)" - " - [%s] starting at line: %d", - id1, type1, id2, type2, - ctx.fname, ctx.m_sectionLineno); - return false; - } - - return true; -} - -static bool -checkTCPConstraints(InitConfigFileParser::Context & ctx, const char * data){ - - const char * host; - struct in_addr addr; - if(ctx.m_currentSection->get(data, &host) && strlen(host) && - Ndb_getInAddr(&addr, host)){ - ctx.reportError("Unable to lookup/illegal hostname %s" - " - [%s] starting at line: %d", - host, ctx.fname, ctx.m_sectionLineno); - return false; - } - return true; -} - -static -bool -transform(InitConfigFileParser::Context & ctx, - Properties & dst, - const char * oldName, - const char * newName, - double add, double mul){ - - if(ctx.m_currentSection->contains(newName)){ - ctx.reportError("Both %s and %s specified" - " - [%s] starting at line: %d", - oldName, newName, - ctx.fname, ctx.m_sectionLineno); - return false; - } - - PropertiesType oldType; - require(ctx.m_currentSection->getTypeOf(oldName, &oldType)); - ConfigInfo::Type newType = ctx.m_info->getType(ctx.m_currentInfo, newName); - - if(!((oldType == PropertiesType_Uint32 || oldType == PropertiesType_Uint64) - && (newType == ConfigInfo::CI_INT || newType == ConfigInfo::CI_INT64 || newType == ConfigInfo::CI_BOOL))){ - ndbout << "oldType: " << (int)oldType << ", newType: " << (int)newType << endl; - ctx.reportError("Unable to handle type conversion w.r.t deprication %s %s" - "- [%s] starting at line: %d", - oldName, newName, - ctx.fname, ctx.m_sectionLineno); - return false; - } - Uint64 oldVal; - require(ctx.m_currentSection->get(oldName, &oldVal)); - - Uint64 newVal = (Uint64)((Int64)oldVal * mul + add); - if(!ctx.m_info->verify(ctx.m_currentInfo, newName, newVal)){ - ctx.reportError("Unable to handle deprication, new value not within bounds" - "%s %s - [%s] starting at line: %d", - oldName, newName, - ctx.fname, ctx.m_sectionLineno); - return false; - } - - if(newType == ConfigInfo::CI_INT || newType == ConfigInfo::CI_BOOL){ - require(dst.put(newName, (Uint32)newVal)); - } else if(newType == ConfigInfo::CI_INT64) { - require(dst.put64(newName, newVal)); - } - return true; -} - -static bool -fixDepricated(InitConfigFileParser::Context & ctx, const char * data){ - const char * name; - /** - * Transform old values to new values - * Transform new values to old values (backward compatible) - */ - Properties tmp(true); - Properties::Iterator it(ctx.m_currentSection); - for (name = it.first(); name != NULL; name = it.next()) { - const DepricationTransform * p = &f_deprication[0]; - while(p->m_section != 0){ - if(strcmp(p->m_section, ctx.fname) == 0){ - double mul = p->m_mul; - double add = p->m_add; - if(strcasecmp(name, p->m_oldName) == 0){ - if(!transform(ctx, tmp, name, p->m_newName, add, mul)){ - return false; - } - } else if(strcasecmp(name, p->m_newName) == 0) { - if(!transform(ctx, tmp, name, p->m_oldName, -add/mul,1.0/mul)){ - return false; - } - } - } - p++; - } - } - - Properties::Iterator it2(&tmp); - for (name = it2.first(); name != NULL; name = it2.next()) { - PropertiesType type; - require(tmp.getTypeOf(name, &type)); - switch(type){ - case PropertiesType_Uint32:{ - Uint32 val; - require(tmp.get(name, &val)); - ::require(ctx.m_currentSection->put(name, val)); - break; - } - case PropertiesType_char:{ - const char * val; - require(tmp.get(name, &val)); - ::require(ctx.m_currentSection->put(name, val)); - break; - } - case PropertiesType_Uint64:{ - Uint64 val; - require(tmp.get(name, &val)); - ::require(ctx.m_currentSection->put64(name, val)); - break; - } - case PropertiesType_Properties: - default: - ::require(false); - } - } - return true; -} - -extern int g_print_full_config; - -static bool -saveInConfigValues(InitConfigFileParser::Context & ctx, const char * data){ - const Properties * sec; - if(!ctx.m_currentInfo->get(ctx.fname, &sec)){ - require(false); - return false; - } - - do { - const char *secName; - Uint32 id, status, typeVal; - require(sec->get("Fname", &secName)); - require(sec->get("Id", &id)); - require(sec->get("Status", &status)); - require(sec->get("SectionType", &typeVal)); - - if(id == KEY_INTERNAL || status == ConfigInfo::CI_INTERNAL){ - ndbout_c("skipping section %s", ctx.fname); - break; - } - - if (g_print_full_config) - { - const char *alias= ConfigInfo::nameToAlias(ctx.fname); - printf("[%s]\n", alias ? alias : ctx.fname); - } - - Uint32 no = 0; - ctx.m_userProperties.get("$Section", id, &no); - ctx.m_userProperties.put("$Section", id, no+1, true); - - ctx.m_configValues.openSection(id, no); - ctx.m_configValues.put(CFG_TYPE_OF_SECTION, typeVal); - - Properties::Iterator it(ctx.m_currentSection); - for (const char* n = it.first(); n != NULL; n = it.next()) { - const Properties * info; - if(!ctx.m_currentInfo->get(n, &info)) - continue; - - id = 0; - info->get("Id", &id); - - if(id == KEY_INTERNAL) - continue; - - bool ok = true; - PropertiesType type; - require(ctx.m_currentSection->getTypeOf(n, &type)); - switch(type){ - case PropertiesType_Uint32:{ - Uint32 val; - require(ctx.m_currentSection->get(n, &val)); - ok = ctx.m_configValues.put(id, val); - if (g_print_full_config) - printf("%s=%u\n", n, val); - break; - } - case PropertiesType_Uint64:{ - Uint64 val; - require(ctx.m_currentSection->get(n, &val)); - ok = ctx.m_configValues.put64(id, val); - if (g_print_full_config) - printf("%s=%llu\n", n, val); - break; - } - case PropertiesType_char:{ - const char * val; - require(ctx.m_currentSection->get(n, &val)); - ok = ctx.m_configValues.put(id, val); - if (g_print_full_config) - printf("%s=%s\n", n, val); - break; - } - default: - require(false); - } - require(ok); - } - ctx.m_configValues.closeSection(); - } while(0); - return true; -} - -static bool -sanity_checks(Vector<ConfigInfo::ConfigRuleSection>§ions, - struct InitConfigFileParser::Context &ctx, - const char * rule_data) -{ - Uint32 db_nodes = 0; - Uint32 mgm_nodes = 0; - Uint32 api_nodes = 0; - if (!ctx.m_userProperties.get("DB", &db_nodes)) { - ctx.reportError("At least one database node (ndbd) should be defined in config file"); - return false; - } - if (!ctx.m_userProperties.get("MGM", &mgm_nodes)) { - ctx.reportError("At least one management server node (ndb_mgmd) should be defined in config file"); - return false; - } - if (!ctx.m_userProperties.get("API", &api_nodes)) { - ctx.reportError("At least one application node (for the mysqld) should be defined in config file"); - return false; - } - return true; -} - -static void -add_a_connection(Vector<ConfigInfo::ConfigRuleSection>§ions, - struct InitConfigFileParser::Context &ctx, - Uint32 nodeId1, Uint32 nodeId2, bool use_shm) -{ - ConfigInfo::ConfigRuleSection s; - const char *hostname1= 0, *hostname2= 0; - const Properties *tmp; - - require(ctx.m_config->get("Node", nodeId1, &tmp)); - tmp->get("HostName", &hostname1); - - require(ctx.m_config->get("Node", nodeId2, &tmp)); - tmp->get("HostName", &hostname2); - - char buf[16]; - s.m_sectionData= new Properties(true); - BaseString::snprintf(buf, sizeof(buf), "%u", nodeId1); - s.m_sectionData->put("NodeId1", buf); - BaseString::snprintf(buf, sizeof(buf), "%u", nodeId2); - s.m_sectionData->put("NodeId2", buf); - - if (use_shm && - hostname1 && hostname1[0] && - hostname2 && hostname2[0] && - strcmp(hostname1,hostname2) == 0) - { - s.m_sectionType= BaseString("SHM"); - DBUG_PRINT("info",("adding SHM connection %d %d",nodeId1,nodeId2)); - } - else - { - s.m_sectionType= BaseString("TCP"); - DBUG_PRINT("info",("adding TCP connection %d %d",nodeId1,nodeId2)); - } - - sections.push_back(s); -} - -static bool -add_node_connections(Vector<ConfigInfo::ConfigRuleSection>§ions, - struct InitConfigFileParser::Context &ctx, - const char * rule_data) -{ - DBUG_ENTER("add_node_connections"); - Uint32 i; - Properties * props= ctx.m_config; - Properties p_connections(true); - Properties p_connections2(true); - - for (i = 0;; i++){ - const Properties * tmp; - Uint32 nodeId1, nodeId2; - - if(!props->get("Connection", i, &tmp)) break; - - if(!tmp->get("NodeId1", &nodeId1)) continue; - p_connections.put("", nodeId1, nodeId1); - if(!tmp->get("NodeId2", &nodeId2)) continue; - p_connections.put("", nodeId2, nodeId2); - - p_connections2.put("", nodeId1 + nodeId2<<16, nodeId1); - p_connections2.put("", nodeId2 + nodeId1<<16, nodeId2); - } - - Uint32 nNodes; - ctx.m_userProperties.get("NoOfNodes", &nNodes); - - Properties p_db_nodes(true); - Properties p_api_nodes(true); - Properties p_mgm_nodes(true); - - Uint32 i_db= 0, i_api= 0, i_mgm= 0, n; - for (i= 0, n= 0; n < nNodes; i++){ - const Properties * tmp; - if(!props->get("Node", i, &tmp)) continue; - n++; - - const char * type; - if(!tmp->get("Type", &type)) continue; - - if (strcmp(type,DB_TOKEN) == 0) - p_db_nodes.put("", i_db++, i); - else if (strcmp(type,API_TOKEN) == 0) - p_api_nodes.put("", i_api++, i); - else if (strcmp(type,MGM_TOKEN) == 0) - p_mgm_nodes.put("", i_mgm++, i); - } - - Uint32 nodeId1, nodeId2, dummy; - - for (i= 0; p_db_nodes.get("", i, &nodeId1); i++){ - for (Uint32 j= i+1;; j++){ - if(!p_db_nodes.get("", j, &nodeId2)) break; - if(!p_connections2.get("", nodeId1+nodeId2<<16, &dummy)) { - add_a_connection(sections,ctx,nodeId1,nodeId2,opt_ndb_shm); - } - } - } - - for (i= 0; p_api_nodes.get("", i, &nodeId1); i++){ - if(!p_connections.get("", nodeId1, &dummy)) { - for (Uint32 j= 0;; j++){ - if(!p_db_nodes.get("", j, &nodeId2)) break; - add_a_connection(sections,ctx,nodeId1,nodeId2,opt_ndb_shm); - } - } - } - - for (i= 0; p_mgm_nodes.get("", i, &nodeId1); i++){ - if(!p_connections.get("", nodeId1, &dummy)) { - for (Uint32 j= 0;; j++){ - if(!p_db_nodes.get("", j, &nodeId2)) break; - add_a_connection(sections,ctx,nodeId1,nodeId2,0); - } - } - } - - DBUG_RETURN(true); -} - -static bool set_connection_priorities(Vector<ConfigInfo::ConfigRuleSection>§ions, - struct InitConfigFileParser::Context &ctx, - const char * rule_data) -{ - DBUG_ENTER("set_connection_priorities"); - DBUG_RETURN(true); -} - -static bool -check_node_vs_replicas(Vector<ConfigInfo::ConfigRuleSection>§ions, - struct InitConfigFileParser::Context &ctx, - const char * rule_data) -{ - Uint32 db_nodes= 0; - Uint32 replicas= 0; - Uint32 db_host_count= 0; - bool with_arbitration_rank= false; - ctx.m_userProperties.get(DB_TOKEN, &db_nodes); - ctx.m_userProperties.get("NoOfReplicas", &replicas); - if((db_nodes % replicas) != 0){ - ctx.reportError("Invalid no of db nodes wrt no of replicas.\n" - "No of nodes must be dividable with no or replicas"); - return false; - } - // check that node groups and arbitrators are ok - // just issue warning if not - if(replicas > 1){ - Properties * props= ctx.m_config; - Properties p_db_hosts(true); // store hosts which db nodes run on - Properties p_arbitrators(true); // store hosts which arbitrators run on - // arbitrator should not run together with db node on same host - Uint32 i, n, group= 0, i_group= 0; - Uint32 n_nodes; - BaseString node_group_warning, arbitration_warning; - const char *arbit_warn_fmt= - "\n arbitrator with id %d and db node with id %d on same host %s"; - const char *arbit_warn_fmt2= - "\n arbitrator with id %d has no hostname specified"; - - ctx.m_userProperties.get("NoOfNodes", &n_nodes); - for (i= 0, n= 0; n < n_nodes; i++){ - const Properties * tmp; - if(!props->get("Node", i, &tmp)) continue; - n++; - - const char * type; - if(!tmp->get("Type", &type)) continue; - - const char* host= 0; - tmp->get("HostName", &host); - - if (strcmp(type,DB_TOKEN) == 0) - { - { - Uint32 ii; - if (!p_db_hosts.get(host,&ii)) - db_host_count++; - p_db_hosts.put(host,i); - if (p_arbitrators.get(host,&ii)) - { - arbitration_warning.appfmt(arbit_warn_fmt, ii, i, host); - p_arbitrators.remove(host); // only one warning per db node - } - } - { - unsigned j; - BaseString str, str2; - str.assfmt("#group%d_",group); - p_db_hosts.put(str.c_str(),i_group,host); - str2.assfmt("##group%d_",group); - p_db_hosts.put(str2.c_str(),i_group,i); - for (j= 0; j < i_group; j++) - { - const char *other_host; - p_db_hosts.get(str.c_str(),j,&other_host); - if (strcmp(host,other_host) == 0) { - unsigned int other_i, c= 0; - p_db_hosts.get(str2.c_str(),j,&other_i); - p_db_hosts.get(str.c_str(),&c); - if (c == 0) // first warning in this node group - node_group_warning.appfmt(" Node group %d", group); - c|= 1 << j; - p_db_hosts.put(str.c_str(),c); - node_group_warning.appfmt(",\n db node with id %d and id %d " - "on same host %s", other_i, i, host); - } - } - i_group++; - DBUG_ASSERT(i_group <= replicas); - if (i_group == replicas) - { - unsigned c= 0; - p_db_hosts.get(str.c_str(),&c); - if (c+1 == (1u << (replicas-1))) // all nodes on same machine - node_group_warning.append(".\n Host failure will " - "cause complete cluster shutdown."); - else if (c > 0) - node_group_warning.append(".\n Host failure may " - "cause complete cluster shutdown."); - group++; - i_group= 0; - } - } - } - else if (strcmp(type,API_TOKEN) == 0 || - strcmp(type,MGM_TOKEN) == 0) - { - Uint32 rank; - if(tmp->get("ArbitrationRank", &rank) && rank > 0) - { - with_arbitration_rank = true; //check whether MGM or API node configured with rank >0 - if(host && host[0] != 0) - { - Uint32 ii; - p_arbitrators.put(host,i); - if (p_db_hosts.get(host,&ii)) - { - arbitration_warning.appfmt(arbit_warn_fmt, i, ii, host); - } - } - else - { - arbitration_warning.appfmt(arbit_warn_fmt2, i); - } - } - } - } - if (db_host_count > 1 && node_group_warning.length() > 0) - ctx.reportWarning("Cluster configuration warning:\n%s",node_group_warning.c_str()); - if (!with_arbitration_rank) - { - ctx.reportWarning("Cluster configuration warning:" - "\n Neither %s nor %s nodes are configured with arbitrator," - "\n may cause complete cluster shutdown in case of host failure.", - MGM_TOKEN, API_TOKEN); - } - if (db_host_count > 1 && arbitration_warning.length() > 0) - ctx.reportWarning("Cluster configuration warning:%s%s",arbitration_warning.c_str(), - "\n Running arbitrator on the same host as a database node may" - "\n cause complete cluster shutdown in case of host failure."); - } - return true; -} - -template class Vector<ConfigInfo::ConfigRuleSection>; -#endif /* NDB_MGMAPI */ diff --git a/storage/ndb/src/mgmsrv/ConfigInfo.hpp b/storage/ndb/src/mgmsrv/ConfigInfo.hpp deleted file mode 100644 index e1ecb7d7965..00000000000 --- a/storage/ndb/src/mgmsrv/ConfigInfo.hpp +++ /dev/null @@ -1,152 +0,0 @@ -/* Copyright (c) 2003-2007 MySQL AB - Use is subject to license terms - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ - -#ifndef ConfigInfo_H -#define ConfigInfo_H - -#ifndef NDB_MGMAPI -#include <kernel_types.h> -#include <Properties.hpp> -#include <ndb_limits.h> -#include <NdbOut.hpp> -#include "InitConfigFileParser.hpp" -#endif /* NDB_MGMAPI */ - -/** - * A MANDATORY parameters must be specified in the config file - * An UNDEFINED parameter may or may not be specified in the config file - */ - -// Default value for mandatory params. -#define MANDATORY ((char*)~(UintPtr)0) -// Default value for undefined params. -#define UNDEFINED ((char*) 0) - -/** - * @class ConfigInfo - * @brief Metainformation about ALL cluster configuration parameters - * - * Use the getters to find out metainformation about parameters. - */ -class ConfigInfo { -public: - enum Type { CI_BOOL, CI_INT, CI_INT64, CI_STRING, CI_SECTION }; - enum Status { CI_USED, ///< Active - CI_DEPRICATED, ///< Can be, but shouldn't - CI_NOTIMPLEMENTED, ///< Is ignored. - CI_INTERNAL ///< Not configurable by the user - }; - - /** - * Entry for one configuration parameter - */ - struct ParamInfo { - Uint32 _paramId; - const char* _fname; - const char* _section; - const char* _description; - Status _status; - bool _updateable; - Type _type; - const char* _default; - const char* _min; - const char* _max; - }; - -#ifndef NDB_MGMAPI - struct AliasPair{ - const char * name; - const char * alias; - }; - - /** - * Entry for one section rule - */ - struct SectionRule { - const char * m_section; - bool (* m_sectionRule)(struct InitConfigFileParser::Context &, - const char * m_ruleData); - const char * m_ruleData; - }; - - /** - * Entry for config rule - */ - struct ConfigRuleSection { - BaseString m_sectionType; - Properties * m_sectionData; - }; - - struct ConfigRule { - bool (* m_configRule)(Vector<ConfigRuleSection>&, - struct InitConfigFileParser::Context &, - const char * m_ruleData); - const char * m_ruleData; - }; - - ConfigInfo(); - - /** - * Checks if the suggested value is valid for the suggested parameter - * (i.e. if it is >= than min and <= than max). - * - * @param section Init Config file section name - * @param fname Name of parameter - * @param value Value to check - * @return true if parameter value is valid. - * - * @note Result is not defined if section/name are wrong! - */ - bool verify(const Properties* secti, const char* fname, Uint64 value) const; - static const char* nameToAlias(const char*); - static const char* getAlias(const char*); - bool isSection(const char*) const; - - const char* getDescription(const Properties * sec, const char* fname) const; - Type getType(const Properties * section, const char* fname) const; - Status getStatus(const Properties* section, const char* fname) const; - Uint64 getMin(const Properties * section, const char* fname) const; - Uint64 getMax(const Properties * section, const char* fname) const; - Uint64 getDefault(const Properties * section, const char* fname) const; - - const Properties * getInfo(const char * section) const; - const Properties * getDefaults(const char * section) const; - - void print() const; - void print(const char* section) const; - void print(const Properties * section, const char* parameter) const; - -private: - Properties m_info; - Properties m_systemDefaults; - - static const AliasPair m_sectionNameAliases[]; - static const char* m_sectionNames[]; - static const int m_noOfSectionNames; -#endif /* NDB_MGMAPI */ - -public: - static const ParamInfo m_ParamInfo[]; - static const int m_NoOfParams; - -#ifndef NDB_MGMAPI - static const SectionRule m_SectionRules[]; - static const ConfigRule m_ConfigRules[]; - static const int m_NoOfRules; -#endif /* NDB_MGMAPI */ -}; - -#endif // ConfigInfo_H diff --git a/storage/ndb/src/mgmsrv/ERROR_codes.txt b/storage/ndb/src/mgmsrv/ERROR_codes.txt deleted file mode 100644 index 44a6047c05e..00000000000 --- a/storage/ndb/src/mgmsrv/ERROR_codes.txt +++ /dev/null @@ -1,29 +0,0 @@ -Next Session 10 -Next Global 10001 - - -#define MGM_ERROR_MAX_INJECT_SESSION_ONLY 10000 -Errors < 10000 are per-session only - in MgmApiSession. - -Others are for the whole mgm server. - -Error 0 is no error - -TIMEOUTS --------- - -num where type testing - -1 get config sleep begin -2 get config sleep middle parsable -3 get config mangle halfway through encoded properties - -4 end session sleep before reply - -5 node status sleep before reply -6 node status sleep during parsable reply -7 node status sleep after parsable, before status reply -8 node status sleep partway through status reporting -9 node status sleep end of status printing - -10000 events PING no ping don't send pings to event listeners diff --git a/storage/ndb/src/mgmsrv/InitConfigFileParser.cpp b/storage/ndb/src/mgmsrv/InitConfigFileParser.cpp deleted file mode 100644 index c44cb37880a..00000000000 --- a/storage/ndb/src/mgmsrv/InitConfigFileParser.cpp +++ /dev/null @@ -1,953 +0,0 @@ -/* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ - -#include <ndb_global.h> - -#include "InitConfigFileParser.hpp" -#include "Config.hpp" -#include "MgmtErrorReporter.hpp" -#include <NdbOut.hpp> -#include "ConfigInfo.hpp" -#include <m_string.h> - -const int MAX_LINE_LENGTH = 1024; // Max length of line of text in config file -static void trim(char *); - -static void require(bool v) { if(!v) abort();} - -//**************************************************************************** -// Ctor / Dtor -//**************************************************************************** -InitConfigFileParser::InitConfigFileParser(FILE * out) -{ - m_info = new ConfigInfo(); - m_errstream = out ? out : stdout; -} - -InitConfigFileParser::~InitConfigFileParser() { - delete m_info; -} - -//**************************************************************************** -// Read Config File -//**************************************************************************** -InitConfigFileParser::Context::Context(const ConfigInfo * info, FILE * out) - : m_userProperties(true), m_configValues(1000, 20) { - - m_config = new Properties(true); - m_defaults = new Properties(true); - m_errstream = out; -} - -InitConfigFileParser::Context::~Context(){ - if(m_config != 0) - delete m_config; - - if(m_defaults != 0) - delete m_defaults; -} - -Config * -InitConfigFileParser::parseConfig(const char * filename) { - FILE * file = fopen(filename, "r"); - if(file == 0){ - fprintf(m_errstream, "Error opening file: %s\n", filename); - return 0; - } - - Config * ret = parseConfig(file); - fclose(file); - return ret; -} - -Config * -InitConfigFileParser::parseConfig(FILE * file) { - - char line[MAX_LINE_LENGTH]; - - Context ctx(m_info, m_errstream); - ctx.m_lineno = 0; - ctx.m_currentSection = 0; - - /************* - * Open file * - *************/ - if (file == NULL) { - return 0; - } - - /*********************** - * While lines to read * - ***********************/ - while (fgets(line, MAX_LINE_LENGTH, file)) { - ctx.m_lineno++; - - trim(line); - - if (isEmptyLine(line)) // Skip if line is empty or comment - continue; - - // End with NULL instead of newline - if (line[strlen(line)-1] == '\n') - line[strlen(line)-1] = '\0'; - - /******************************** - * 1. Parse new default section * - ********************************/ - if (char* section = parseDefaultSectionHeader(line)) { - if(!storeSection(ctx)){ - free(section); - ctx.reportError("Could not store previous default section " - "of configuration file."); - return 0; - } - BaseString::snprintf(ctx.fname, sizeof(ctx.fname), section); free(section); - ctx.type = InitConfigFileParser::DefaultSection; - ctx.m_sectionLineno = ctx.m_lineno; - ctx.m_currentSection = new Properties(true); - ctx.m_userDefaults = NULL; - require((ctx.m_currentInfo = m_info->getInfo(ctx.fname)) != 0); - require((ctx.m_systemDefaults = m_info->getDefaults(ctx.fname)) != 0); - continue; - } - - /************************ - * 2. Parse new section * - ************************/ - if (char* section = parseSectionHeader(line)) { - if(!storeSection(ctx)){ - free(section); - ctx.reportError("Could not store previous section " - "of configuration file."); - return 0; - } - BaseString::snprintf(ctx.fname, sizeof(ctx.fname), section); - free(section); - ctx.type = InitConfigFileParser::Section; - ctx.m_sectionLineno = ctx.m_lineno; - ctx.m_currentSection = new Properties(true); - ctx.m_userDefaults = getSection(ctx.fname, ctx.m_defaults); - require((ctx.m_currentInfo = m_info->getInfo(ctx.fname)) != 0); - require((ctx.m_systemDefaults = m_info->getDefaults(ctx.fname)) != 0); - continue; - } - - /**************************** - * 3. Parse name-value pair * - ****************************/ - if (!parseNameValuePair(ctx, line)) { - ctx.reportError("Could not parse name-value pair in config file."); - return 0; - } - } - - if (ferror(file)){ - ctx.reportError("Failure in reading"); - return 0; - } - - if(!storeSection(ctx)) { - ctx.reportError("Could not store section of configuration file."); - return 0; - } - - return run_config_rules(ctx); -} - -Config* -InitConfigFileParser::run_config_rules(Context& ctx) -{ - for(size_t i = 0; ConfigInfo::m_ConfigRules[i].m_configRule != 0; i++){ - ctx.type = InitConfigFileParser::Undefined; - ctx.m_currentSection = 0; - ctx.m_userDefaults = 0; - ctx.m_currentInfo = 0; - ctx.m_systemDefaults = 0; - - Vector<ConfigInfo::ConfigRuleSection> tmp; - if(!(* ConfigInfo::m_ConfigRules[i].m_configRule)(tmp, ctx, - ConfigInfo::m_ConfigRules[i].m_ruleData)) - return 0; - - for(size_t j = 0; j<tmp.size(); j++){ - BaseString::snprintf(ctx.fname, sizeof(ctx.fname), tmp[j].m_sectionType.c_str()); - ctx.type = InitConfigFileParser::Section; - ctx.m_currentSection = tmp[j].m_sectionData; - ctx.m_userDefaults = getSection(ctx.fname, ctx.m_defaults); - require((ctx.m_currentInfo = m_info->getInfo(ctx.fname)) != 0); - require((ctx.m_systemDefaults = m_info->getDefaults(ctx.fname)) != 0); - if(!storeSection(ctx)) - return 0; - } - } - - Uint32 nConnections = 0; - Uint32 nComputers = 0; - Uint32 nNodes = 0; - Uint32 nExtConnections = 0; - const char * system = "?"; - ctx.m_userProperties.get("NoOfConnections", &nConnections); - ctx.m_userProperties.get("NoOfComputers", &nComputers); - ctx.m_userProperties.get("NoOfNodes", &nNodes); - ctx.m_userProperties.get("ExtNoOfConnections", &nExtConnections); - ctx.m_userProperties.get("ExtSystem", &system); - ctx.m_config->put("NoOfConnections", nConnections); - ctx.m_config->put("NoOfComputers", nComputers); - ctx.m_config->put("NoOfNodes", nNodes); - - char tmpLine[MAX_LINE_LENGTH]; - BaseString::snprintf(tmpLine, MAX_LINE_LENGTH, - "EXTERNAL SYSTEM_%s:NoOfConnections", system); - ctx.m_config->put(tmpLine, nExtConnections); - - Config * ret = new Config(); - ret->m_configValues = (struct ndb_mgm_configuration*)ctx.m_configValues.getConfigValues(); - ret->m_oldConfig = ctx.m_config; ctx.m_config = 0; - return ret; -} - -//**************************************************************************** -// Parse Name-Value Pair -//**************************************************************************** - -bool InitConfigFileParser::parseNameValuePair(Context& ctx, const char* line) -{ - if (ctx.m_currentSection == NULL){ - ctx.reportError("Value specified outside section"); - return false; - } - - // ************************************* - // Split string at first occurrence of - // '=' or ':' - // ************************************* - - Vector<BaseString> tmp_string_split; - if (BaseString(line).split(tmp_string_split, - "=:", 2) != 2) - { - ctx.reportError("Parse error"); - return false; - } - - // ************************************* - // Remove all after # - // ************************************* - - Vector<BaseString> tmp_string_split2; - tmp_string_split[1].split(tmp_string_split2, - "#", 2); - tmp_string_split[1]=tmp_string_split2[0]; - - // ************************************* - // Remove leading and trailing chars - // ************************************* - { - for (int i = 0; i < 2; i++) - tmp_string_split[i].trim("\r\n \t"); - } - - // ************************************* - // First in split is fname - // ************************************* - - const char *fname= tmp_string_split[0].c_str(); - - if (!ctx.m_currentInfo->contains(fname)) { - ctx.reportError("[%s] Unknown parameter: %s", ctx.fname, fname); - return false; - } - ConfigInfo::Status status = m_info->getStatus(ctx.m_currentInfo, fname); - if (status == ConfigInfo::CI_NOTIMPLEMENTED) { - ctx.reportWarning("[%s] %s not yet implemented", ctx.fname, fname); - } - if (status == ConfigInfo::CI_DEPRICATED) { - const char * desc = m_info->getDescription(ctx.m_currentInfo, fname); - if(desc && desc[0]){ - ctx.reportWarning("[%s] %s is depricated, use %s instead", - ctx.fname, fname, desc); - } else if (desc == 0){ - ctx.reportWarning("[%s] %s is depricated", ctx.fname, fname); - } - } - - // *********************** - // Store name-value pair - // *********************** - - return storeNameValuePair(ctx, fname, tmp_string_split[1].c_str()); -} - - -//**************************************************************************** -// STORE NAME-VALUE pair in properties section -//**************************************************************************** - -bool -InitConfigFileParser::storeNameValuePair(Context& ctx, - const char* fname, - const char* value) { - - const char * pname = fname; - - if (ctx.m_currentSection->contains(pname)) { - ctx.reportError("[%s] Parameter %s specified twice", ctx.fname, fname); - return false; - } - - // *********************** - // Store name-value pair - // *********************** - - const ConfigInfo::Type type = m_info->getType(ctx.m_currentInfo, fname); - switch(type){ - case ConfigInfo::CI_BOOL: { - bool value_bool; - if (!convertStringToBool(value, value_bool)) { - ctx.reportError("Illegal boolean value for parameter %s", fname); - return false; - } - MGM_REQUIRE(ctx.m_currentSection->put(pname, value_bool)); - break; - } - case ConfigInfo::CI_INT: - case ConfigInfo::CI_INT64:{ - Uint64 value_int; - if (!convertStringToUint64(value, value_int)) { - ctx.reportError("Illegal integer value for parameter %s", fname); - return false; - } - if (!m_info->verify(ctx.m_currentInfo, fname, value_int)) { - ctx.reportError("Illegal value %s for parameter %s.\n" - "Legal values are between %Lu and %Lu", value, fname, - m_info->getMin(ctx.m_currentInfo, fname), - m_info->getMax(ctx.m_currentInfo, fname)); - return false; - } - if(type == ConfigInfo::CI_INT){ - MGM_REQUIRE(ctx.m_currentSection->put(pname, (Uint32)value_int)); - } else { - MGM_REQUIRE(ctx.m_currentSection->put64(pname, value_int)); - } - break; - } - case ConfigInfo::CI_STRING: - MGM_REQUIRE(ctx.m_currentSection->put(pname, value)); - break; - case ConfigInfo::CI_SECTION: - abort(); - } - return true; -} - -//**************************************************************************** -// Is Empty Line -//**************************************************************************** - -bool InitConfigFileParser::isEmptyLine(const char* line) const { - int i; - - // Check if it is a comment line - if (line[0] == '#') return true; - - // Check if it is a line with only spaces - for (i = 0; i < MAX_LINE_LENGTH && line[i] != '\n' && line[i] != '\0'; i++) { - if (line[i] != ' ' && line[i] != '\t') return false; - } - return true; -} - -//**************************************************************************** -// Convert String to Int -//**************************************************************************** -bool InitConfigFileParser::convertStringToUint64(const char* s, - Uint64& val, - Uint32 log10base) { - if (s == NULL) - return false; - if (strlen(s) == 0) - return false; - - errno = 0; - char* p; - Int64 v = strtoll(s, &p, log10base); - if (errno != 0) - return false; - - long mul = 0; - if (p != &s[strlen(s)]){ - char * tmp = strdup(p); - trim(tmp); - switch(tmp[0]){ - case 'k': - case 'K': - mul = 10; - break; - case 'M': - mul = 20; - break; - case 'G': - mul = 30; - break; - default: - free(tmp); - return false; - } - free(tmp); - } - - val = (v << mul); - return true; -} - -bool InitConfigFileParser::convertStringToBool(const char* s, bool& val) { - if (s == NULL) return false; - if (strlen(s) == 0) return false; - - if (!strcmp(s, "Y") || !strcmp(s, "y") || - !strcmp(s, "Yes") || !strcmp(s, "YES") || !strcmp(s, "yes") || - !strcmp(s, "True") || !strcmp(s, "TRUE") || !strcmp(s, "true") || - !strcmp(s, "1")) { - val = true; - return true; - } - - if (!strcmp(s, "N") || !strcmp(s, "n") || - !strcmp(s, "No") || !strcmp(s, "NO") || !strcmp(s, "no") || - !strcmp(s, "False") || !strcmp(s, "FALSE") || !strcmp(s, "false") || - !strcmp(s, "0")) { - val = false; - return true; - } - - return false; // Failure to convert -} - -//**************************************************************************** -// Parse Section Header -//**************************************************************************** -static void -trim(char * str){ - int len = strlen(str); - for(len--; - (str[len] == '\r' || str[len] == '\n' || - str[len] == ' ' || str[len] == '\t') && - len > 0; - len--) - str[len] = 0; - - int pos = 0; - while(str[pos] == ' ' || str[pos] == '\t') - pos++; - - if(str[pos] == '\"' && str[len] == '\"') { - pos++; - str[len] = 0; - len--; - } - - memmove(str, &str[pos], len - pos + 2); -} - -char* -InitConfigFileParser::parseSectionHeader(const char* line) const { - char * tmp = strdup(line); - - if(tmp[0] != '['){ - free(tmp); - return NULL; - } - - if(tmp[strlen(tmp)-1] != ']'){ - free(tmp); - return NULL; - } - tmp[strlen(tmp)-1] = 0; - - tmp[0] = ' '; - trim(tmp); - - // Get the correct header name if an alias - { - const char *tmp_alias= m_info->getAlias(tmp); - if (tmp_alias) { - free(tmp); - tmp= strdup(tmp_alias); - } - } - - // Lookup token among sections - if(!m_info->isSection(tmp)) { - free(tmp); - return NULL; - } - if(m_info->getInfo(tmp)) return tmp; - - free(tmp); - return NULL; -} - -//**************************************************************************** -// Parse Default Section Header -//**************************************************************************** - -char* -InitConfigFileParser::parseDefaultSectionHeader(const char* line) const { - static char token1[MAX_LINE_LENGTH], token2[MAX_LINE_LENGTH]; - - int no = sscanf(line, "[%120[A-Z_a-z] %120[A-Z_a-z]]", token1, token2); - - // Not correct no of tokens - if (no != 2) return NULL; - - // Not correct keyword at end - if (!strcasecmp(token2, "DEFAULT") == 0) return NULL; - - const char *token1_alias= m_info->getAlias(token1); - if (token1_alias == 0) - token1_alias= token1; - - if(m_info->getInfo(token1_alias)){ - return strdup(token1_alias); - } - - // Did not find section - return NULL; -} - -const Properties * -InitConfigFileParser::getSection(const char * name, const Properties * src){ - const Properties * p; - if(src && src->get(name, &p)) - return p; - - return 0; -} - -//**************************************************************************** -// STORE section -//**************************************************************************** -bool -InitConfigFileParser::storeSection(Context& ctx){ - if(ctx.m_currentSection == NULL) - return true; - for(int i = strlen(ctx.fname) - 1; i>=0; i--){ - ctx.fname[i] = toupper(ctx.fname[i]); - } - BaseString::snprintf(ctx.pname, sizeof(ctx.pname), ctx.fname); - char buf[255]; - if(ctx.type == InitConfigFileParser::Section) - BaseString::snprintf(buf, sizeof(buf), "%s", ctx.fname); - if(ctx.type == InitConfigFileParser::DefaultSection) - BaseString::snprintf(buf, sizeof(buf), "%s DEFAULT", ctx.fname); - BaseString::snprintf(ctx.fname, sizeof(ctx.fname), buf); - if(ctx.type == InitConfigFileParser::Section){ - for(int i = 0; i<m_info->m_NoOfRules; i++){ - const ConfigInfo::SectionRule & rule = m_info->m_SectionRules[i]; - if(!strcmp(rule.m_section, "*") || !strcmp(rule.m_section, ctx.fname)){ - if(!(* rule.m_sectionRule)(ctx, rule.m_ruleData)){ - return false; - } - } - } - } - if(ctx.type == InitConfigFileParser::DefaultSection && - !ctx.m_defaults->put(ctx.pname, ctx.m_currentSection)) - { - ctx.reportError("Duplicate default section not allowed"); - return false; - } - if(ctx.type == InitConfigFileParser::Section) - require(ctx.m_config->put(ctx.pname, ctx.m_currentSection)); - delete ctx.m_currentSection; ctx.m_currentSection = NULL; - return true; -} - -void -InitConfigFileParser::Context::reportError(const char * fmt, ...){ - va_list ap; - char buf[1000]; - - va_start(ap, fmt); - if (fmt != 0) - BaseString::vsnprintf(buf, sizeof(buf)-1, fmt, ap); - va_end(ap); - fprintf(m_errstream, "Error line %d: %s\n", - m_lineno, buf); - - //m_currentSection->print(); -} - -void -InitConfigFileParser::Context::reportWarning(const char * fmt, ...){ - va_list ap; - char buf[1000]; - - va_start(ap, fmt); - if (fmt != 0) - BaseString::vsnprintf(buf, sizeof(buf)-1, fmt, ap); - va_end(ap); - fprintf(m_errstream, "Warning line %d: %s\n", - m_lineno, buf); -} - -#include <my_sys.h> -#include <my_getopt.h> - -static int order = 1; -static -my_bool -parse_mycnf_opt(int, const struct my_option * opt, char * value) -{ - long *app_type= (long*) &opt->app_type; - if(opt->comment) - (*app_type)++; - else - *app_type = order++; - return 0; -} - -bool -InitConfigFileParser::store_in_properties(Vector<struct my_option>& options, - InitConfigFileParser::Context& ctx, - const char * name) -{ - for(unsigned i = 0; i<options.size(); i++) - { - if(options[i].comment && - options[i].app_type && - strcmp(options[i].comment, name) == 0) - { - Uint64 value_int; - switch(options[i].var_type){ - case GET_INT: - value_int = *(Uint32*)options[i].value; - break; - case GET_LL: - value_int = *(Uint64*)options[i].value; - break; - case GET_STR: - ctx.m_currentSection->put(options[i].name, *(char**)options[i].value); - continue; - default: - abort(); - } - - const char * fname = options[i].name; - if (!m_info->verify(ctx.m_currentInfo, fname, value_int)) { - ctx.reportError("Illegal value %lld for parameter %s.\n" - "Legal values are between %Lu and %Lu", - value_int, fname, - m_info->getMin(ctx.m_currentInfo, fname), - m_info->getMax(ctx.m_currentInfo, fname)); - return false; - } - - ConfigInfo::Status status = m_info->getStatus(ctx.m_currentInfo, fname); - if (status == ConfigInfo::CI_DEPRICATED) { - const char * desc = m_info->getDescription(ctx.m_currentInfo, fname); - if(desc && desc[0]){ - ctx.reportWarning("[%s] %s is depricated, use %s instead", - ctx.fname, fname, desc); - } else if (desc == 0){ - ctx.reportWarning("[%s] %s is depricated", ctx.fname, fname); - } - } - - if (options[i].var_type == GET_INT) - ctx.m_currentSection->put(options[i].name, (Uint32)value_int); - else - ctx.m_currentSection->put64(options[i].name, value_int); - } - } - return true; -} - -bool -InitConfigFileParser::handle_mycnf_defaults(Vector<struct my_option>& options, - InitConfigFileParser::Context& ctx, - const char * name) -{ - strcpy(ctx.fname, name); - ctx.type = InitConfigFileParser::DefaultSection; - ctx.m_currentSection = new Properties(true); - ctx.m_userDefaults = NULL; - require((ctx.m_currentInfo = m_info->getInfo(ctx.fname)) != 0); - require((ctx.m_systemDefaults = m_info->getDefaults(ctx.fname)) != 0); - if(store_in_properties(options, ctx, name)) - return storeSection(ctx); - return false; -} - -static -int -load_defaults(Vector<struct my_option>& options, const char* groups[]) -{ - int argc = 1; - const char * argv[] = { "ndb_mgmd", 0, 0, 0, 0 }; - BaseString file; - BaseString extra_file; - BaseString group_suffix; - - const char *save_file = my_defaults_file; - const char *save_extra_file = my_defaults_extra_file; - const char *save_group_suffix = my_defaults_group_suffix; - - if (my_defaults_file) - { - file.assfmt("--defaults-file=%s", my_defaults_file); - argv[argc++] = file.c_str(); - } - - if (my_defaults_extra_file) - { - extra_file.assfmt("--defaults-extra-file=%s", my_defaults_extra_file); - argv[argc++] = extra_file.c_str(); - } - - if (my_defaults_group_suffix) - { - group_suffix.assfmt("--defaults-group-suffix=%s", - my_defaults_group_suffix); - argv[argc++] = group_suffix.c_str(); - } - - char ** tmp = (char**)argv; - int ret = load_defaults("my", groups, &argc, &tmp); - - my_defaults_file = save_file; - my_defaults_extra_file = save_extra_file; - my_defaults_group_suffix = save_group_suffix; - - if (ret == 0) - { - return handle_options(&argc, &tmp, options.getBase(), parse_mycnf_opt); - } - - return ret; -} - -bool -InitConfigFileParser::load_mycnf_groups(Vector<struct my_option> & options, - InitConfigFileParser::Context& ctx, - const char * name, - const char *groups[]) -{ - unsigned i; - Vector<struct my_option> copy; - for(i = 0; i<options.size(); i++) - { - if(options[i].comment && strcmp(options[i].comment, name) == 0) - { - options[i].app_type = 0; - copy.push_back(options[i]); - } - } - - struct my_option end; - bzero(&end, sizeof(end)); - copy.push_back(end); - - if (load_defaults(copy, groups)) - return false; - - return store_in_properties(copy, ctx, name); -} - -Config * -InitConfigFileParser::parse_mycnf() -{ - int i; - Config * res = 0; - Vector<struct my_option> options; - for(i = 0; i<ConfigInfo::m_NoOfParams; i++) - { - { - struct my_option opt; - bzero(&opt, sizeof(opt)); - const ConfigInfo::ParamInfo& param = ConfigInfo::m_ParamInfo[i]; - switch(param._type){ - case ConfigInfo::CI_BOOL: - opt.value = (uchar **)malloc(sizeof(int)); - opt.var_type = GET_INT; - break; - case ConfigInfo::CI_INT: - opt.value = (uchar**)malloc(sizeof(int)); - opt.var_type = GET_INT; - break; - case ConfigInfo::CI_INT64: - opt.value = (uchar**)malloc(sizeof(Int64)); - opt.var_type = GET_LL; - break; - case ConfigInfo::CI_STRING: - opt.value = (uchar**)malloc(sizeof(char *)); - opt.var_type = GET_STR; - break; - default: - continue; - } - opt.name = param._fname; - opt.id = 256; - opt.app_type = 0; - opt.arg_type = REQUIRED_ARG; - opt.comment = param._section; - options.push_back(opt); - } - } - - struct my_option *ndbd, *ndb_mgmd, *mysqld, *api; - - /** - * Add ndbd, ndb_mgmd, api/mysqld - */ - Uint32 idx = options.size(); - { - struct my_option opt; - bzero(&opt, sizeof(opt)); - opt.name = "ndbd"; - opt.id = 256; - opt.value = (uchar**)malloc(sizeof(char*)); - opt.var_type = GET_STR; - opt.arg_type = REQUIRED_ARG; - options.push_back(opt); - - opt.name = "ndb_mgmd"; - opt.id = 256; - opt.value = (uchar**)malloc(sizeof(char*)); - opt.var_type = GET_STR; - opt.arg_type = REQUIRED_ARG; - options.push_back(opt); - - opt.name = "mysqld"; - opt.id = 256; - opt.value = (uchar**)malloc(sizeof(char*)); - opt.var_type = GET_STR; - opt.arg_type = REQUIRED_ARG; - options.push_back(opt); - - opt.name = "ndbapi"; - opt.id = 256; - opt.value = (uchar**)malloc(sizeof(char*)); - opt.var_type = GET_STR; - opt.arg_type = REQUIRED_ARG; - options.push_back(opt); - - bzero(&opt, sizeof(opt)); - options.push_back(opt); - - ndbd = &options[idx]; - ndb_mgmd = &options[idx+1]; - mysqld = &options[idx+2]; - api = &options[idx+3]; - } - - Context ctx(m_info, m_errstream); - const char *groups[]= { "cluster_config", 0 }; - if (load_defaults(options, groups)) - goto end; - - ctx.m_lineno = 0; - if(!handle_mycnf_defaults(options, ctx, "DB")) - goto end; - if(!handle_mycnf_defaults(options, ctx, "API")) - goto end; - if(!handle_mycnf_defaults(options, ctx, "MGM")) - goto end; - if(!handle_mycnf_defaults(options, ctx, "TCP")) - goto end; - if(!handle_mycnf_defaults(options, ctx, "SHM")) - goto end; - if(!handle_mycnf_defaults(options, ctx, "SCI")) - goto end; - - { - struct sect { struct my_option* src; const char * name; } sections[] = - { - { ndb_mgmd, "MGM" } - ,{ ndbd, "DB" } - ,{ mysqld, "API" } - ,{ api, "API" } - ,{ 0, 0 }, { 0, 0 } - }; - - for(i = 0; sections[i].src; i++) - { - for(int j = i + 1; sections[j].src; j++) - { - if (sections[j].src->app_type < sections[i].src->app_type) - { - sect swap = sections[i]; - sections[i] = sections[j]; - sections[j] = swap; - } - } - } - - ctx.type = InitConfigFileParser::Section; - ctx.m_sectionLineno = ctx.m_lineno; - for(i = 0; sections[i].src; i++) - { - if (sections[i].src->app_type) - { - strcpy(ctx.fname, sections[i].name); - BaseString str(*(char**)sections[i].src->value); - Vector<BaseString> list; - str.split(list, ","); - - const char * defaults_groups[] = { 0, 0, 0 }; - for(unsigned j = 0; j<list.size(); j++) - { - BaseString group_idx; - BaseString group_host; - group_idx.assfmt("%s.%s.%d", groups[0], - sections[i].src->name, j + 1); - group_host.assfmt("%s.%s.%s", groups[0], - sections[i].src->name, list[j].c_str()); - defaults_groups[0] = group_idx.c_str(); - if(list[j].length()) - defaults_groups[1] = group_host.c_str(); - else - defaults_groups[1] = 0; - - ctx.m_currentSection = new Properties(true); - ctx.m_userDefaults = getSection(ctx.fname, ctx.m_defaults); - require((ctx.m_currentInfo = m_info->getInfo(ctx.fname)) != 0); - require((ctx.m_systemDefaults = m_info->getDefaults(ctx.fname))!= 0); - ctx.m_currentSection->put("HostName", list[j].c_str()); - if(!load_mycnf_groups(options, ctx, sections[i].name, - defaults_groups)) - goto end; - - if(!storeSection(ctx)) - goto end; - } - } - } - } - - res = run_config_rules(ctx); - -end: - for(i = 0; options[i].name; i++) - free(options[i].value); - - return res; -} - -template class Vector<struct my_option>; - -/* - See include/my_getopt.h for the declaration of struct my_option -*/ diff --git a/storage/ndb/src/mgmsrv/InitConfigFileParser.hpp b/storage/ndb/src/mgmsrv/InitConfigFileParser.hpp deleted file mode 100644 index 19ceafafda7..00000000000 --- a/storage/ndb/src/mgmsrv/InitConfigFileParser.hpp +++ /dev/null @@ -1,145 +0,0 @@ -/* Copyright (c) 2003-2005 MySQL AB - Use is subject to license terms - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ - -#ifndef InitConfigFileParser_H -#define InitConfigFileParser_H - -#include <ndb_global.h> - -#include <Properties.hpp> -#include <ConfigValues.hpp> - -class Config; -class ConfigInfo; - -/** - * @class InitConfigFileParser - * @brief Reads initial config file and returns Config object - * - * This class contains one public method InitConfigFileParser::parseConfig, - * which reads an initial configuration file and returns a Config - * object if the config file has correct syntax and semantic. - */ -class InitConfigFileParser { - FILE * m_errstream; -public: - /** - * Constructor - */ - InitConfigFileParser(FILE * errstream = stdout); - ~InitConfigFileParser(); - - /** - * Reads the initial configuration file, checks syntax and semantic - * and stores internally the values of all parameters. - * - * @returns Config or NULL on failure - * @note must be freed by caller - */ - Config * parseConfig(FILE * file); - Config * parseConfig(const char * filename); - Config * parse_mycnf(); - - /** - * Parser context struct - */ - enum ContextSectionType { Undefined, Section, DefaultSection }; - - /** - * Context = Which section in init config file we are currently parsing - */ - struct Context { - Context(const ConfigInfo *, FILE * out); - ~Context(); - - ContextSectionType type; ///< Section type (e.g. default section,section) - char fname[256]; ///< Section name occuring in init config file - char pname[256]; ///< Section name stored in properties object - Uint32 m_lineno; ///< Current line no in config file - Uint32 m_sectionLineno; ///< Where did current section start - - const ConfigInfo * m_info; // The config info - Properties * m_config; // The config object - Properties * m_defaults; // The user defaults - - Properties * m_currentSection; // The current section I'm in - const Properties * m_userDefaults; // The defaults of this section - const Properties * m_systemDefaults; // The syst. defaults for this section - const Properties * m_currentInfo; // The "info" for this section - - Properties m_userProperties; // User properties (temporary values) - ConfigValuesFactory m_configValues; // - - public: - FILE * m_errstream; - void reportError(const char * msg, ...); - void reportWarning(const char * msg, ...); - }; - - static bool convertStringToUint64(const char* s, Uint64& val, Uint32 log10base = 0); - static bool convertStringToBool(const char* s, bool& val); - -private: - /** - * Check if line only contains space/comments - * @param line: The line to check - * @return true if spaces/comments only, false otherwise - */ - bool isEmptyLine(const char* line) const; - - /** - * Checks if line contains a section header - * @param line: String to search - * @return section header if matching some section header, NULL otherwise - */ - char* parseSectionHeader(const char* line) const; - - /** - * Checks if line contains a default header - * @param line: String to search - * @return section header if matching some section header, NULL otherwise - */ - char* parseDefaultSectionHeader(const char* line) const; - - bool parseNameValuePair(Context&, const char* line); - bool storeNameValuePair(Context&, const char* fname, const char* value); - - bool storeSection(Context&); - - const Properties* getSection(const char * name, const Properties* src); - - /** - * Information about parameters (min, max values etc) - */ - ConfigInfo* m_info; - - bool handle_mycnf_defaults(Vector<struct my_option>& options, - InitConfigFileParser::Context& ctx, - const char * name); - - bool load_mycnf_groups(Vector<struct my_option> & options, - InitConfigFileParser::Context& ctx, - const char * name, - const char *groups[]); - - bool store_in_properties(Vector<struct my_option>& options, - InitConfigFileParser::Context& ctx, - const char * name); - - Config* run_config_rules(Context& ctx); -}; - -#endif // InitConfigFileParser_H diff --git a/storage/ndb/src/mgmsrv/Makefile.am b/storage/ndb/src/mgmsrv/Makefile.am deleted file mode 100644 index 48524061d66..00000000000 --- a/storage/ndb/src/mgmsrv/Makefile.am +++ /dev/null @@ -1,73 +0,0 @@ -# Copyright (C) 2004-2006 MySQL AB -# Use is subject to license terms -# -# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -MYSQLDATAdir = $(localstatedir) -MYSQLSHAREdir = $(pkgdatadir) -MYSQLBASEdir= $(prefix) -#MYSQLCLUSTERdir= $(prefix)/mysql-cluster -MYSQLCLUSTERdir= . - -ndbbin_PROGRAMS = ndb_mgmd - -ndb_mgmd_SOURCES = \ - MgmtSrvr.cpp \ - MgmtSrvrGeneralSignalHandling.cpp \ - main.cpp \ - Services.cpp \ - convertStrToInt.cpp \ - SignalQueue.cpp \ - MgmtSrvrConfig.cpp \ - ConfigInfo.cpp \ - InitConfigFileParser.cpp \ - Config.cpp - -INCLUDES_LOC = -I$(top_srcdir)/storage/ndb/src/ndbapi \ - -I$(top_srcdir)/storage/ndb/src/mgmapi \ - -I$(top_srcdir)/storage/ndb/src/common/mgmcommon \ - -I$(top_srcdir)/storage/ndb/src/mgmclient - -LDADD_LOC = $(top_builddir)/storage/ndb/src/mgmclient/CommandInterpreter.lo \ - $(top_builddir)/storage/ndb/src/libndbclient.la \ - $(top_builddir)/dbug/libdbug.a \ - $(top_builddir)/mysys/libmysys.a \ - $(top_builddir)/strings/libmystrings.a \ - @readline_link@ \ - @NDB_SCI_LIBS@ \ - @TERMCAP_LIB@ - -DEFS_LOC = -DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \ - -DMYSQL_DATADIR="\"$(MYSQLDATAdir)\"" \ - -DSHAREDIR="\"$(MYSQLSHAREdir)\"" \ - -DMYSQLCLUSTERDIR="\"$(MYSQLCLUSTERdir)\"" - -include $(top_srcdir)/storage/ndb/config/common.mk.am -include $(top_srcdir)/storage/ndb/config/type_ndbapi.mk.am - -ndb_mgmd_LDFLAGS = @ndb_bin_am_ldflags@ - -windoze-dsp: ndb_mgmd.dsp - -ndb_mgmd.dsp: Makefile \ - $(top_srcdir)/storage/ndb/config/win-prg.am \ - $(top_srcdir)/storage/ndb/config/win-name \ - $(top_srcdir)/storage/ndb/config/win-includes \ - $(top_srcdir)/storage/ndb/config/win-sources \ - $(top_srcdir)/storage/ndb/config/win-libraries - cat $(top_srcdir)/storage/ndb/config/win-prg.am > $@ - @$(top_srcdir)/storage/ndb/config/win-name $@ $(ndbbin_PROGRAMS) - @$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES) - @$(top_srcdir)/storage/ndb/config/win-sources $@ $(ndb_mgmd_SOURCES) - @$(top_srcdir)/storage/ndb/config/win-libraries $@ LINK $(LDADD) diff --git a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp deleted file mode 100644 index 6a9377bdd73..00000000000 --- a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp +++ /dev/null @@ -1,3017 +0,0 @@ -/* Copyright (c) 2003-2007 MySQL AB - Use is subject to license terms - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ - -#include <ndb_global.h> -#include <my_pthread.h> - -#include "MgmtSrvr.hpp" -#include "MgmtErrorReporter.hpp" -#include "ndb_mgmd_error.h" -#include <ConfigRetriever.hpp> - -#include <NdbOut.hpp> -#include <NdbApiSignal.hpp> -#include <kernel_types.h> -#include <RefConvert.hpp> -#include <BlockNumbers.h> -#include <GlobalSignalNumbers.h> -#include <signaldata/TestOrd.hpp> -#include <signaldata/TamperOrd.hpp> -#include <signaldata/StartOrd.hpp> -#include <signaldata/ApiVersion.hpp> -#include <signaldata/ResumeReq.hpp> -#include <signaldata/SetLogLevelOrd.hpp> -#include <signaldata/EventSubscribeReq.hpp> -#include <signaldata/EventReport.hpp> -#include <signaldata/DumpStateOrd.hpp> -#include <signaldata/BackupSignalData.hpp> -#include <signaldata/ManagementServer.hpp> -#include <signaldata/NFCompleteRep.hpp> -#include <signaldata/NodeFailRep.hpp> -#include <signaldata/AllocNodeId.hpp> -#include <NdbSleep.h> -#include <EventLogger.hpp> -#include <DebuggerNames.hpp> -#include <ndb_version.h> - -#include <SocketServer.hpp> -#include <NdbConfig.h> - -#include <NdbAutoPtr.hpp> - -#include <ndberror.h> - -#include <mgmapi.h> -#include <mgmapi_configuration.hpp> -#include <mgmapi_config_parameters.h> -#include <m_string.h> - -#include <SignalSender.hpp> - -//#define MGM_SRV_DEBUG -#ifdef MGM_SRV_DEBUG -#define DEBUG(x) do ndbout << x << endl; while(0) -#else -#define DEBUG(x) -#endif - -int g_errorInsert; -#define ERROR_INSERTED(x) (g_errorInsert == x) - -#define INIT_SIGNAL_SENDER(ss,nodeId) \ - SignalSender ss(theFacade); \ - ss.lock(); /* lock will be released on exit */ \ - {\ - int result = okToSendTo(nodeId, true);\ - if (result != 0) {\ - return result;\ - }\ - } - -extern int g_no_nodeid_checks; -extern my_bool opt_core; - -static void require(bool v) -{ - if(!v) - { - if (opt_core) - abort(); - else - exit(-1); - } -} - -void * -MgmtSrvr::logLevelThread_C(void* m) -{ - MgmtSrvr *mgm = (MgmtSrvr*)m; - mgm->logLevelThreadRun(); - return 0; -} - -extern EventLogger g_eventLogger; - -#ifdef NOT_USED -static NdbOut& -operator<<(NdbOut& out, const LogLevel & ll) -{ - out << "[LogLevel: "; - for(size_t i = 0; i<LogLevel::LOGLEVEL_CATEGORIES; i++) - out << ll.getLogLevel((LogLevel::EventCategory)i) << " "; - out << "]"; - return out; -} -#endif - -void -MgmtSrvr::logLevelThreadRun() -{ - while (!_isStopThread) - { - Vector<NodeId> failed_started_nodes; - Vector<EventSubscribeReq> failed_log_level_requests; - - /** - * Handle started nodes - */ - m_started_nodes.lock(); - if (m_started_nodes.size() > 0) - { - // calculate max log level - EventSubscribeReq req; - { - LogLevel tmp; - m_event_listner.lock(); - for(int i = m_event_listner.m_clients.size() - 1; i >= 0; i--) - tmp.set_max(m_event_listner[i].m_logLevel); - m_event_listner.unlock(); - req = tmp; - } - req.blockRef = _ownReference; - while (m_started_nodes.size() > 0) - { - Uint32 node = m_started_nodes[0]; - m_started_nodes.erase(0, false); - m_started_nodes.unlock(); - - if (setEventReportingLevelImpl(node, req)) - { - failed_started_nodes.push_back(node); - } - else - { - SetLogLevelOrd ord; - ord = m_nodeLogLevel[node]; - setNodeLogLevelImpl(node, ord); - } - m_started_nodes.lock(); - } - } - m_started_nodes.unlock(); - - m_log_level_requests.lock(); - while (m_log_level_requests.size() > 0) - { - EventSubscribeReq req = m_log_level_requests[0]; - m_log_level_requests.erase(0, false); - m_log_level_requests.unlock(); - - if(req.blockRef == 0) - { - req.blockRef = _ownReference; - if (setEventReportingLevelImpl(0, req)) - { - failed_log_level_requests.push_back(req); - } - } - else - { - SetLogLevelOrd ord; - ord = req; - if (setNodeLogLevelImpl(req.blockRef, ord)) - { - failed_log_level_requests.push_back(req); - } - } - m_log_level_requests.lock(); - } - m_log_level_requests.unlock(); - - if(!ERROR_INSERTED(10000)) - m_event_listner.check_listeners(); - - Uint32 sleeptime = _logLevelThreadSleep; - if (failed_started_nodes.size()) - { - m_started_nodes.lock(); - for (Uint32 i = 0; i<failed_started_nodes.size(); i++) - m_started_nodes.push_back(failed_started_nodes[i], false); - m_started_nodes.unlock(); - failed_started_nodes.clear(); - sleeptime = 100; - } - - if (failed_log_level_requests.size()) - { - m_log_level_requests.lock(); - for (Uint32 i = 0; i<failed_log_level_requests.size(); i++) - m_log_level_requests.push_back(failed_log_level_requests[i], false); - m_log_level_requests.unlock(); - failed_log_level_requests.clear(); - sleeptime = 100; - } - - NdbSleep_MilliSleep(sleeptime); - } -} - -void -MgmtSrvr::startEventLog() -{ - NdbMutex_Lock(m_configMutex); - - g_eventLogger.setCategory("MgmSrvr"); - - ndb_mgm_configuration_iterator - iter(* _config->m_configValues, CFG_SECTION_NODE); - - if(iter.find(CFG_NODE_ID, _ownNodeId) != 0){ - NdbMutex_Unlock(m_configMutex); - return; - } - - const char * tmp; - char errStr[100]; - int err= 0; - BaseString logdest; - char *clusterLog= NdbConfig_ClusterLogFileName(_ownNodeId); - NdbAutoPtr<char> tmp_aptr(clusterLog); - - if(iter.get(CFG_LOG_DESTINATION, &tmp) == 0){ - logdest.assign(tmp); - } - NdbMutex_Unlock(m_configMutex); - - if(logdest.length() == 0 || logdest == "") { - logdest.assfmt("FILE:filename=%s,maxsize=1000000,maxfiles=6", - clusterLog); - } - errStr[0]='\0'; - if(!g_eventLogger.addHandler(logdest, &err, sizeof(errStr), errStr)) { - ndbout << "Warning: could not add log destination \"" - << logdest.c_str() << "\". Reason: "; - if(err) - ndbout << strerror(err); - if(err && errStr[0]!='\0') - ndbout << ", "; - if(errStr[0]!='\0') - ndbout << errStr; - ndbout << endl; - } -} - -void -MgmtSrvr::stopEventLog() -{ - g_eventLogger.close(); -} - -bool -MgmtSrvr::setEventLogFilter(int severity, int enable) -{ - Logger::LoggerLevel level = (Logger::LoggerLevel)severity; - if (enable > 0) { - g_eventLogger.enable(level); - } else if (enable == 0) { - g_eventLogger.disable(level); - } else if (g_eventLogger.isEnable(level)) { - g_eventLogger.disable(level); - } else { - g_eventLogger.enable(level); - } - return g_eventLogger.isEnable(level); -} - -bool -MgmtSrvr::isEventLogFilterEnabled(int severity) -{ - return g_eventLogger.isEnable((Logger::LoggerLevel)severity); -} - -int MgmtSrvr::translateStopRef(Uint32 errCode) -{ - switch(errCode){ - case StopRef::NodeShutdownInProgress: - return NODE_SHUTDOWN_IN_PROGESS; - break; - case StopRef::SystemShutdownInProgress: - return SYSTEM_SHUTDOWN_IN_PROGRESS; - break; - case StopRef::NodeShutdownWouldCauseSystemCrash: - return NODE_SHUTDOWN_WOULD_CAUSE_SYSTEM_CRASH; - break; - case StopRef::UnsupportedNodeShutdown: - return UNSUPPORTED_NODE_SHUTDOWN; - break; - } - return 4999; -} - -int -MgmtSrvr::getNodeCount(enum ndb_mgm_node_type type) const -{ - int count = 0; - NodeId nodeId = 0; - - while (getNextNodeId(&nodeId, type)) { - count++; - } - return count; -} - -int -MgmtSrvr::getPort() const -{ - if(NdbMutex_Lock(m_configMutex)) - return 0; - - ndb_mgm_configuration_iterator - iter(* _config->m_configValues, CFG_SECTION_NODE); - - if(iter.find(CFG_NODE_ID, getOwnNodeId()) != 0){ - ndbout << "Could not retrieve configuration for Node " - << getOwnNodeId() << " in config file." << endl - << "Have you set correct NodeId for this node?" << endl; - NdbMutex_Unlock(m_configMutex); - return 0; - } - - unsigned type; - if(iter.get(CFG_TYPE_OF_SECTION, &type) != 0 || - type != NODE_TYPE_MGM){ - ndbout << "Local node id " << getOwnNodeId() - << " is not defined as management server" << endl - << "Have you set correct NodeId for this node?" << endl; - NdbMutex_Unlock(m_configMutex); - return 0; - } - - Uint32 port = 0; - if(iter.get(CFG_MGM_PORT, &port) != 0){ - ndbout << "Could not find PortNumber in the configuration file." << endl; - NdbMutex_Unlock(m_configMutex); - return 0; - } - - NdbMutex_Unlock(m_configMutex); - - return port; -} - -/* Constructor */ -int MgmtSrvr::init() -{ - if ( _ownNodeId > 0) - return 0; - return -1; -} - -MgmtSrvr::MgmtSrvr(SocketServer *socket_server, - const char *config_filename, - const char *connect_string) : - _blockNumber(1), // Hard coded block number since it makes it easy to send - // signals to other management servers. - m_socket_server(socket_server), - _ownReference(0), - theSignalIdleList(NULL), - theWaitState(WAIT_SUBSCRIBE_CONF), - m_local_mgm_handle(0), - m_event_listner(this), - m_master_node(0) -{ - - DBUG_ENTER("MgmtSrvr::MgmtSrvr"); - - _ownNodeId= 0; - - _config = NULL; - - _isStopThread = false; - _logLevelThread = NULL; - _logLevelThreadSleep = 500; - - theFacade = 0; - - m_newConfig = NULL; - if (config_filename) - m_configFilename.assign(config_filename); - - m_nextConfigGenerationNumber = 0; - - m_config_retriever= new ConfigRetriever(connect_string, - NDB_VERSION, NDB_MGM_NODE_TYPE_MGM); - // if connect_string explicitly given or - // no config filename is given then - // first try to allocate nodeid from another management server - if ((connect_string || config_filename == NULL) && - (m_config_retriever->do_connect(0,0,0) == 0)) - { - int tmp_nodeid= 0; - tmp_nodeid= m_config_retriever->allocNodeId(0 /*retry*/,0 /*delay*/); - if (tmp_nodeid == 0) - { - ndbout_c(m_config_retriever->getErrorString()); - require(false); - } - // read config from other managent server - _config= fetchConfig(); - if (_config == 0) - { - ndbout << m_config_retriever->getErrorString() << endl; - require(false); - } - _ownNodeId= tmp_nodeid; - } - - if (_ownNodeId == 0) - { - // read config locally - _config= readConfig(); - if (_config == 0) { - if (config_filename != NULL) - ndbout << "Invalid configuration file: " << config_filename << endl; - else - ndbout << "Invalid configuration file" << endl; - exit(-1); - } - } - - theMgmtWaitForResponseCondPtr = NdbCondition_Create(); - - m_configMutex = NdbMutex_Create(); - - /** - * Fill the nodeTypes array - */ - for(Uint32 i = 0; i<MAX_NODES; i++) { - nodeTypes[i] = (enum ndb_mgm_node_type)-1; - m_connect_address[i].s_addr= 0; - } - - { - ndb_mgm_configuration_iterator - iter(* _config->m_configValues, CFG_SECTION_NODE); - - for(iter.first(); iter.valid(); iter.next()){ - unsigned type, id; - if(iter.get(CFG_TYPE_OF_SECTION, &type) != 0) - continue; - - if(iter.get(CFG_NODE_ID, &id) != 0) - continue; - - MGM_REQUIRE(id < MAX_NODES); - - switch(type){ - case NODE_TYPE_DB: - nodeTypes[id] = NDB_MGM_NODE_TYPE_NDB; - break; - case NODE_TYPE_API: - nodeTypes[id] = NDB_MGM_NODE_TYPE_API; - break; - case NODE_TYPE_MGM: - nodeTypes[id] = NDB_MGM_NODE_TYPE_MGM; - break; - default: - break; - } - } - } - - _props = NULL; - BaseString error_string; - - if ((m_node_id_mutex = NdbMutex_Create()) == 0) - { - ndbout << "mutex creation failed line = " << __LINE__ << endl; - require(false); - } - - if (_ownNodeId == 0) // we did not get node id from other server - { - NodeId tmp= m_config_retriever->get_configuration_nodeid(); - int error_code; - - if (!alloc_node_id(&tmp, NDB_MGM_NODE_TYPE_MGM, - 0, 0, error_code, error_string)){ - ndbout << "Unable to obtain requested nodeid: " - << error_string.c_str() << endl; - require(false); - } - _ownNodeId = tmp; - } - - { - DBUG_PRINT("info", ("verifyConfig")); - if (!m_config_retriever->verifyConfig(_config->m_configValues, - _ownNodeId)) - { - ndbout << m_config_retriever->getErrorString() << endl; - require(false); - } - } - - // Setup clusterlog as client[0] in m_event_listner - { - Ndb_mgmd_event_service::Event_listener se; - se.m_socket = NDB_INVALID_SOCKET; - for(size_t t = 0; t<LogLevel::LOGLEVEL_CATEGORIES; t++){ - se.m_logLevel.setLogLevel((LogLevel::EventCategory)t, 7); - } - se.m_logLevel.setLogLevel(LogLevel::llError, 15); - se.m_logLevel.setLogLevel(LogLevel::llConnection, 8); - se.m_logLevel.setLogLevel(LogLevel::llBackup, 15); - m_event_listner.m_clients.push_back(se); - m_event_listner.m_logLevel = se.m_logLevel; - } - - DBUG_VOID_RETURN; -} - - -//**************************************************************************** -//**************************************************************************** -bool -MgmtSrvr::check_start() -{ - if (_config == 0) { - DEBUG("MgmtSrvr.cpp: _config is NULL."); - return false; - } - - return true; -} - -bool -MgmtSrvr::start(BaseString &error_string) -{ - int mgm_connect_result; - - DBUG_ENTER("MgmtSrvr::start"); - if (_props == NULL) { - if (!check_start()) { - error_string.append("MgmtSrvr.cpp: check_start() failed."); - DBUG_RETURN(false); - } - } - theFacade= new TransporterFacade(); - - if(theFacade == 0) { - DEBUG("MgmtSrvr.cpp: theFacade is NULL."); - error_string.append("MgmtSrvr.cpp: theFacade is NULL."); - DBUG_RETURN(false); - } - if ( theFacade->start_instance - (_ownNodeId, (ndb_mgm_configuration*)_config->m_configValues) < 0) { - DEBUG("MgmtSrvr.cpp: TransporterFacade::start_instance < 0."); - DBUG_RETURN(false); - } - - MGM_REQUIRE(_blockNumber == 1); - - // Register ourself at TransporterFacade to be able to receive signals - // and to be notified when a database process has died. - _blockNumber = theFacade->open(this, - signalReceivedNotification, - nodeStatusNotification); - - if(_blockNumber == -1){ - DEBUG("MgmtSrvr.cpp: _blockNumber is -1."); - error_string.append("MgmtSrvr.cpp: _blockNumber is -1."); - theFacade->stop_instance(); - theFacade = 0; - DBUG_RETURN(false); - } - - if((mgm_connect_result= connect_to_self()) < 0) - { - ndbout_c("Unable to connect to our own ndb_mgmd (Error %d)", - mgm_connect_result); - ndbout_c("This is probably a bug."); - } - - /* - set api reg req frequency quite high: - - 100 ms interval to make sure we have fairly up-to-date - info from the nodes. This to make sure that this info - is not dependent on heart beat settings in the - configuration - */ - theFacade->theClusterMgr->set_max_api_reg_req_interval(100); - - TransporterRegistry *reg = theFacade->get_registry(); - for(unsigned int i=0;i<reg->m_transporter_interface.size();i++) { - BaseString msg; - DBUG_PRINT("info",("Setting dynamic port %d->%d : %d", - reg->get_localNodeId(), - reg->m_transporter_interface[i].m_remote_nodeId, - reg->m_transporter_interface[i].m_s_service_port - ) - ); - int res = setConnectionDbParameter((int)reg->get_localNodeId(), - (int)reg->m_transporter_interface[i] - .m_remote_nodeId, - (int)CFG_CONNECTION_SERVER_PORT, - reg->m_transporter_interface[i] - .m_s_service_port, - msg); - DBUG_PRINT("info",("Set result: %d: %s",res,msg.c_str())); - } - - _ownReference = numberToRef(_blockNumber, _ownNodeId); - - startEventLog(); - // Set the initial confirmation count for subscribe requests confirm - // from NDB nodes in the cluster. - // - // Loglevel thread - _logLevelThread = NdbThread_Create(logLevelThread_C, - (void**)this, - 32768, - "MgmtSrvr_Loglevel", - NDB_THREAD_PRIO_LOW); - - DBUG_RETURN(true); -} - - -//**************************************************************************** -//**************************************************************************** -MgmtSrvr::~MgmtSrvr() -{ - if(theFacade != 0){ - theFacade->stop_instance(); - delete theFacade; - theFacade = 0; - } - - stopEventLog(); - - NdbMutex_Destroy(m_node_id_mutex); - NdbCondition_Destroy(theMgmtWaitForResponseCondPtr); - NdbMutex_Destroy(m_configMutex); - - if(m_newConfig != NULL) - free(m_newConfig); - - if(_config != NULL) - delete _config; - - // End set log level thread - void* res = 0; - _isStopThread = true; - - if (_logLevelThread != NULL) { - NdbThread_WaitFor(_logLevelThread, &res); - NdbThread_Destroy(&_logLevelThread); - } - - if (m_config_retriever) - delete m_config_retriever; -} - -//**************************************************************************** -//**************************************************************************** - -int MgmtSrvr::okToSendTo(NodeId nodeId, bool unCond) -{ - if(nodeId == 0 || getNodeType(nodeId) != NDB_MGM_NODE_TYPE_NDB) - return WRONG_PROCESS_TYPE; - // Check if we have contact with it - if(unCond){ - if(theFacade->theClusterMgr->getNodeInfo(nodeId).m_api_reg_conf) - return 0; - } - else if (theFacade->get_node_alive(nodeId) == true) - return 0; - return NO_CONTACT_WITH_PROCESS; -} - -void report_unknown_signal(SimpleSignal *signal) -{ - g_eventLogger.error("Unknown signal received. SignalNumber: " - "%i from (%d, %x)", - signal->readSignalNumber(), - refToNode(signal->header.theSendersBlockRef), - refToBlock(signal->header.theSendersBlockRef)); -} - -/***************************************************************************** - * Starting and stopping database nodes - ****************************************************************************/ - -int -MgmtSrvr::start(int nodeId) -{ - INIT_SIGNAL_SENDER(ss,nodeId); - - SimpleSignal ssig; - StartOrd* const startOrd = CAST_PTR(StartOrd, ssig.getDataPtrSend()); - ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_START_ORD, StartOrd::SignalLength); - startOrd->restartInfo = 0; - - return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED; -} - -/***************************************************************************** - * Version handling - *****************************************************************************/ - -int -MgmtSrvr::versionNode(int nodeId, Uint32 &version, const char **address) -{ - version= 0; - if (getOwnNodeId() == nodeId) - { - /** - * If we're inquiring about our own node id, - * We know what version we are (version implies connected for mgm) - * but would like to find out from elsewhere what address they're using - * to connect to us. This means that secondary mgm servers - * can list ip addresses for mgm servers. - * - * If we don't get an address (i.e. no db nodes), - * we get the address from the configuration. - */ - sendVersionReq(nodeId, version, address); - version= NDB_VERSION; - if(!*address) - { - ndb_mgm_configuration_iterator - iter(*_config->m_configValues, CFG_SECTION_NODE); - unsigned tmp= 0; - for(iter.first();iter.valid();iter.next()) - { - if(iter.get(CFG_NODE_ID, &tmp)) require(false); - if((unsigned)nodeId!=tmp) - continue; - if(iter.get(CFG_NODE_HOST, address)) require(false); - break; - } - } - } - else if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_NDB) - { - ClusterMgr::Node node= theFacade->theClusterMgr->getNodeInfo(nodeId); - if(node.connected) - version= node.m_info.m_version; - *address= get_connect_address(nodeId); - } - else if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_API || - getNodeType(nodeId) == NDB_MGM_NODE_TYPE_MGM) - { - return sendVersionReq(nodeId, version, address); - } - - return 0; -} - -int -MgmtSrvr::sendVersionReq(int v_nodeId, Uint32 &version, const char **address) -{ - SignalSender ss(theFacade); - ss.lock(); - - SimpleSignal ssig; - ApiVersionReq* req = CAST_PTR(ApiVersionReq, ssig.getDataPtrSend()); - req->senderRef = ss.getOwnRef(); - req->nodeId = v_nodeId; - ssig.set(ss, TestOrd::TraceAPI, QMGR, GSN_API_VERSION_REQ, - ApiVersionReq::SignalLength); - - int do_send = 1; - NodeId nodeId; - - while (1) - { - if (do_send) - { - bool next; - nodeId = 0; - - while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true && - okToSendTo(nodeId, true) != 0); - - const ClusterMgr::Node &node= - theFacade->theClusterMgr->getNodeInfo(nodeId); - if(next && node.m_state.startLevel != NodeState::SL_STARTED) - { - NodeId tmp=nodeId; - while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true && - okToSendTo(nodeId, true) != 0); - if(!next) - nodeId= tmp; - } - - if(!next) return NO_CONTACT_WITH_DB_NODES; - - if (ss.sendSignal(nodeId, &ssig) != SEND_OK) { - return SEND_OR_RECEIVE_FAILED; - } - do_send = 0; - } - - SimpleSignal *signal = ss.waitFor(); - - int gsn = signal->readSignalNumber(); - switch (gsn) { - case GSN_API_VERSION_CONF: { - const ApiVersionConf * const conf = - CAST_CONSTPTR(ApiVersionConf, signal->getDataPtr()); - assert((int) conf->nodeId == v_nodeId); - version = conf->version; - struct in_addr in; - in.s_addr= conf->inet_addr; - *address= inet_ntoa(in); - return 0; - } - case GSN_NF_COMPLETEREP:{ - const NFCompleteRep * const rep = - CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr()); - if (rep->failedNodeId == nodeId) - do_send = 1; // retry with other node - continue; - } - case GSN_NODE_FAILREP:{ - const NodeFailRep * const rep = - CAST_CONSTPTR(NodeFailRep, signal->getDataPtr()); - if (NodeBitmask::get(rep->theNodes,nodeId)) - do_send = 1; // retry with other node - continue; - } - default: - report_unknown_signal(signal); - return SEND_OR_RECEIVE_FAILED; - } - break; - } // while(1) - - return 0; -} - -int MgmtSrvr::sendStopMgmd(NodeId nodeId, - bool abort, - bool stop, - bool restart, - bool nostart, - bool initialStart) -{ - const char* hostname; - Uint32 port; - BaseString connect_string; - - { - Guard g(m_configMutex); - { - ndb_mgm_configuration_iterator - iter(* _config->m_configValues, CFG_SECTION_NODE); - - if(iter.first()) return SEND_OR_RECEIVE_FAILED; - if(iter.find(CFG_NODE_ID, nodeId)) return SEND_OR_RECEIVE_FAILED; - if(iter.get(CFG_NODE_HOST, &hostname)) return SEND_OR_RECEIVE_FAILED; - } - { - ndb_mgm_configuration_iterator - iter(* _config->m_configValues, CFG_SECTION_NODE); - - if(iter.first()) return SEND_OR_RECEIVE_FAILED; - if(iter.find(CFG_NODE_ID, nodeId)) return SEND_OR_RECEIVE_FAILED; - if(iter.get(CFG_MGM_PORT, &port)) return SEND_OR_RECEIVE_FAILED; - } - if( strlen(hostname) == 0 ) - return SEND_OR_RECEIVE_FAILED; - } - connect_string.assfmt("%s:%u",hostname,port); - - DBUG_PRINT("info",("connect string: %s",connect_string.c_str())); - - NdbMgmHandle h= ndb_mgm_create_handle(); - if ( h && connect_string.length() > 0 ) - { - ndb_mgm_set_connectstring(h,connect_string.c_str()); - if(ndb_mgm_connect(h,1,0,0)) - { - DBUG_PRINT("info",("failed ndb_mgm_connect")); - return SEND_OR_RECEIVE_FAILED; - } - if(!restart) - { - if(ndb_mgm_stop(h, 1, (const int*)&nodeId) < 0) - { - return SEND_OR_RECEIVE_FAILED; - } - } - else - { - int nodes[1]; - nodes[0]= (int)nodeId; - if(ndb_mgm_restart2(h, 1, nodes, initialStart, nostart, abort) < 0) - { - return SEND_OR_RECEIVE_FAILED; - } - } - } - ndb_mgm_destroy_handle(&h); - - return 0; -} - -/* - * Common method for handeling all STOP_REQ signalling that - * is used by Stopping, Restarting and Single user commands - * - * In the event that we need to stop a mgmd, we create a mgm - * client connection to that mgmd and stop it that way. - * This allows us to stop mgm servers when there isn't any real - * distributed communication up. - * - * node_ids.size()==0 means to stop all DB nodes. - * MGM nodes will *NOT* be stopped. - * - * If we work out we should be stopping or restarting ourselves, - * we return <0 in stopSelf for restart, >0 for stop - * and 0 for do nothing. - */ - -int MgmtSrvr::sendSTOP_REQ(const Vector<NodeId> &node_ids, - NodeBitmask &stoppedNodes, - Uint32 singleUserNodeId, - bool abort, - bool stop, - bool restart, - bool nostart, - bool initialStart, - int* stopSelf) -{ - int error = 0; - DBUG_ENTER("MgmtSrvr::sendSTOP_REQ"); - DBUG_PRINT("enter", ("no of nodes: %d singleUseNodeId: %d " - "abort: %d stop: %d restart: %d " - "nostart: %d initialStart: %d", - node_ids.size(), singleUserNodeId, - abort, stop, restart, nostart, initialStart)); - - stoppedNodes.clear(); - - SignalSender ss(theFacade); - ss.lock(); // lock will be released on exit - - SimpleSignal ssig; - StopReq* const stopReq = CAST_PTR(StopReq, ssig.getDataPtrSend()); - ssig.set(ss, TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ, StopReq::SignalLength); - - NdbNodeBitmask notstarted; - for (Uint32 i = 0; i<node_ids.size(); i++) - { - Uint32 nodeId = node_ids[i]; - ClusterMgr::Node node = theFacade->theClusterMgr->getNodeInfo(nodeId); - if (node.m_state.startLevel != NodeState::SL_STARTED) - notstarted.set(nodeId); - } - - stopReq->requestInfo = 0; - stopReq->apiTimeout = 5000; - stopReq->transactionTimeout = 1000; - stopReq->readOperationTimeout = 1000; - stopReq->operationTimeout = 1000; - stopReq->senderData = 12; - stopReq->senderRef = ss.getOwnRef(); - if (singleUserNodeId) - { - stopReq->singleuser = 1; - stopReq->singleUserApi = singleUserNodeId; - StopReq::setSystemStop(stopReq->requestInfo, false); - StopReq::setPerformRestart(stopReq->requestInfo, false); - StopReq::setStopAbort(stopReq->requestInfo, false); - } - else - { - stopReq->singleuser = 0; - StopReq::setSystemStop(stopReq->requestInfo, stop); - StopReq::setPerformRestart(stopReq->requestInfo, restart); - StopReq::setStopAbort(stopReq->requestInfo, abort); - StopReq::setNoStart(stopReq->requestInfo, nostart); - StopReq::setInitialStart(stopReq->requestInfo, initialStart); - } - - // send the signals - NodeBitmask nodes; - NodeId nodeId= 0; - int use_master_node= 0; - int do_send= 0; - *stopSelf= 0; - NdbNodeBitmask nodes_to_stop; - { - for (unsigned i= 0; i < node_ids.size(); i++) - { - nodeId= node_ids[i]; - ndbout << "asked to stop " << nodeId << endl; - - if ((getNodeType(nodeId) != NDB_MGM_NODE_TYPE_MGM) - &&(getNodeType(nodeId) != NDB_MGM_NODE_TYPE_NDB)) - return WRONG_PROCESS_TYPE; - - if (getNodeType(nodeId) != NDB_MGM_NODE_TYPE_MGM) - nodes_to_stop.set(nodeId); - else if (nodeId != getOwnNodeId()) - { - error= sendStopMgmd(nodeId, abort, stop, restart, - nostart, initialStart); - if (error == 0) - stoppedNodes.set(nodeId); - } - else - { - ndbout << "which is me" << endl; - *stopSelf= (restart)? -1 : 1; - stoppedNodes.set(nodeId); - } - } - } - int no_of_nodes_to_stop= nodes_to_stop.count(); - if (node_ids.size()) - { - if (no_of_nodes_to_stop) - { - do_send= 1; - if (no_of_nodes_to_stop == 1) - { - nodeId= nodes_to_stop.find(0); - } - else // multi node stop, send to master - { - use_master_node= 1; - nodes_to_stop.copyto(NdbNodeBitmask::Size, stopReq->nodes); - StopReq::setStopNodes(stopReq->requestInfo, 1); - } - } - } - else - { - nodeId= 0; - while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) - { - if(okToSendTo(nodeId, true) == 0) - { - SendStatus result = ss.sendSignal(nodeId, &ssig); - if (result == SEND_OK) - nodes.set(nodeId); - } - } - } - - // now wait for the replies - while (!nodes.isclear() || do_send) - { - if (do_send) - { - int r; - assert(nodes.count() == 0); - if (use_master_node) - nodeId= m_master_node; - if ((r= okToSendTo(nodeId, true)) != 0) - { - bool next; - if (!use_master_node) - DBUG_RETURN(r); - m_master_node= nodeId= 0; - while((next= getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true && - (r= okToSendTo(nodeId, true)) != 0); - if (!next) - DBUG_RETURN(NO_CONTACT_WITH_DB_NODES); - } - if (ss.sendSignal(nodeId, &ssig) != SEND_OK) - DBUG_RETURN(SEND_OR_RECEIVE_FAILED); - nodes.set(nodeId); - do_send= 0; - } - SimpleSignal *signal = ss.waitFor(); - int gsn = signal->readSignalNumber(); - switch (gsn) { - case GSN_STOP_REF:{ - const StopRef * const ref = CAST_CONSTPTR(StopRef, signal->getDataPtr()); - const NodeId nodeId = refToNode(signal->header.theSendersBlockRef); -#ifdef VM_TRACE - ndbout_c("Node %d refused stop", nodeId); -#endif - assert(nodes.get(nodeId)); - nodes.clear(nodeId); - if (ref->errorCode == StopRef::MultiNodeShutdownNotMaster) - { - assert(use_master_node); - m_master_node= ref->masterNodeId; - do_send= 1; - continue; - } - error = translateStopRef(ref->errorCode); - break; - } - case GSN_STOP_CONF:{ -#ifdef NOT_USED - const StopConf * const ref = CAST_CONSTPTR(StopConf, signal->getDataPtr()); -#endif - const NodeId nodeId = refToNode(signal->header.theSendersBlockRef); -#ifdef VM_TRACE - ndbout_c("Node %d single user mode", nodeId); -#endif - assert(nodes.get(nodeId)); - if (singleUserNodeId != 0) - { - stoppedNodes.set(nodeId); - } - else - { - assert(no_of_nodes_to_stop > 1); - stoppedNodes.bitOR(nodes_to_stop); - } - nodes.clear(nodeId); - break; - } - case GSN_NF_COMPLETEREP:{ - const NFCompleteRep * const rep = - CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr()); -#ifdef VM_TRACE - ndbout_c("sendSTOP_REQ Node %d fail completed", rep->failedNodeId); -#endif - nodes.clear(rep->failedNodeId); // clear the failed node - if (singleUserNodeId == 0) - stoppedNodes.set(rep->failedNodeId); - break; - } - case GSN_NODE_FAILREP:{ - const NodeFailRep * const rep = - CAST_CONSTPTR(NodeFailRep, signal->getDataPtr()); - NdbNodeBitmask mask; - mask.assign(NdbNodeBitmask::Size, rep->theNodes); - mask.bitAND(notstarted); - nodes.bitANDC(mask); - - if (singleUserNodeId == 0) - stoppedNodes.bitOR(mask); - break; - } - default: - report_unknown_signal(signal); -#ifdef VM_TRACE - ndbout_c("Unknown signal %d", gsn); -#endif - DBUG_RETURN(SEND_OR_RECEIVE_FAILED); - } - } - if (error && *stopSelf) - { - *stopSelf= 0; - } - DBUG_RETURN(error); -} - -/* - * Stop one nodes - */ - -int MgmtSrvr::stopNodes(const Vector<NodeId> &node_ids, - int *stopCount, bool abort, int* stopSelf) -{ - if (!abort) - { - NodeId nodeId = 0; - ClusterMgr::Node node; - while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) - { - node = theFacade->theClusterMgr->getNodeInfo(nodeId); - if((node.m_state.startLevel != NodeState::SL_STARTED) && - (node.m_state.startLevel != NodeState::SL_NOTHING)) - return OPERATION_NOT_ALLOWED_START_STOP; - } - } - NodeBitmask nodes; - int ret= sendSTOP_REQ(node_ids, - nodes, - 0, - abort, - false, - false, - false, - false, - stopSelf); - if (stopCount) - *stopCount= nodes.count(); - return ret; -} - -int MgmtSrvr::shutdownMGM(int *stopCount, bool abort, int *stopSelf) -{ - NodeId nodeId = 0; - int error; - - while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_MGM)) - { - if(nodeId==getOwnNodeId()) - continue; - error= sendStopMgmd(nodeId, abort, true, false, - false, false); - if (error == 0) - *stopCount++; - } - - *stopSelf= 1; - *stopCount++; - - return 0; -} - -/* - * Perform DB nodes shutdown. - * MGM servers are left in their current state - */ - -int MgmtSrvr::shutdownDB(int * stopCount, bool abort) -{ - NodeBitmask nodes; - Vector<NodeId> node_ids; - - int tmp; - - int ret = sendSTOP_REQ(node_ids, - nodes, - 0, - abort, - true, - false, - false, - false, - &tmp); - if (stopCount) - *stopCount = nodes.count(); - return ret; -} - -/* - * Enter single user mode on all live nodes - */ - -int MgmtSrvr::enterSingleUser(int * stopCount, Uint32 singleUserNodeId) -{ - if (getNodeType(singleUserNodeId) != NDB_MGM_NODE_TYPE_API) - return NODE_NOT_API_NODE; - NodeId nodeId = 0; - ClusterMgr::Node node; - while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) - { - node = theFacade->theClusterMgr->getNodeInfo(nodeId); - if((node.m_state.startLevel != NodeState::SL_STARTED) && - (node.m_state.startLevel != NodeState::SL_NOTHING)) - return OPERATION_NOT_ALLOWED_START_STOP; - } - NodeBitmask nodes; - Vector<NodeId> node_ids; - int stopSelf; - int ret = sendSTOP_REQ(node_ids, - nodes, - singleUserNodeId, - false, - false, - false, - false, - false, - &stopSelf); - if (stopCount) - *stopCount = nodes.count(); - return ret; -} - -/* - * Perform node restart - */ - -int MgmtSrvr::restartNodes(const Vector<NodeId> &node_ids, - int * stopCount, bool nostart, - bool initialStart, bool abort, - int *stopSelf) -{ - NodeBitmask nodes; - int ret= sendSTOP_REQ(node_ids, - nodes, - 0, - abort, - false, - true, - true, - initialStart, - stopSelf); - - if (ret) - return ret; - - if (stopCount) - *stopCount = nodes.count(); - - // start up the nodes again - int waitTime = 12000; - NDB_TICKS maxTime = NdbTick_CurrentMillisecond() + waitTime; - for (unsigned i = 0; i < node_ids.size(); i++) - { - NodeId nodeId= node_ids[i]; - enum ndb_mgm_node_status s; - s = NDB_MGM_NODE_STATUS_NO_CONTACT; -#ifdef VM_TRACE - ndbout_c("Waiting for %d not started", nodeId); -#endif - while (s != NDB_MGM_NODE_STATUS_NOT_STARTED && waitTime > 0) - { - Uint32 startPhase = 0, version = 0, dynamicId = 0, nodeGroup = 0; - Uint32 connectCount = 0; - bool system; - const char *address; - status(nodeId, &s, &version, &startPhase, - &system, &dynamicId, &nodeGroup, &connectCount, &address); - NdbSleep_MilliSleep(100); - waitTime = (maxTime - NdbTick_CurrentMillisecond()); - } - } - - if (nostart) - return 0; - - for (unsigned i = 0; i < node_ids.size(); i++) - { - (void) start(node_ids[i]); - } - return 0; -} - -/* - * Perform restart of all DB nodes - */ - -int MgmtSrvr::restartDB(bool nostart, bool initialStart, - bool abort, int * stopCount) -{ - NodeBitmask nodes; - Vector<NodeId> node_ids; - int tmp; - - int ret = sendSTOP_REQ(node_ids, - nodes, - 0, - abort, - true, - true, - true, - initialStart, - &tmp); - - if (ret) - return ret; - - if (stopCount) - *stopCount = nodes.count(); - -#ifdef VM_TRACE - ndbout_c("Stopped %d nodes", nodes.count()); -#endif - /** - * Here all nodes were correctly stopped, - * so we wait for all nodes to be contactable - */ - int waitTime = 12000; - NodeId nodeId = 0; - NDB_TICKS maxTime = NdbTick_CurrentMillisecond() + waitTime; - - while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) { - if (!nodes.get(nodeId)) - continue; - enum ndb_mgm_node_status s; - s = NDB_MGM_NODE_STATUS_NO_CONTACT; -#ifdef VM_TRACE - ndbout_c("Waiting for %d not started", nodeId); -#endif - while (s != NDB_MGM_NODE_STATUS_NOT_STARTED && waitTime > 0) { - Uint32 startPhase = 0, version = 0, dynamicId = 0, nodeGroup = 0; - Uint32 connectCount = 0; - bool system; - const char *address; - status(nodeId, &s, &version, &startPhase, - &system, &dynamicId, &nodeGroup, &connectCount, &address); - NdbSleep_MilliSleep(100); - waitTime = (maxTime - NdbTick_CurrentMillisecond()); - } - } - - if(nostart) - return 0; - - /** - * Now we start all database nodes (i.e. we make them non-idle) - * We ignore the result we get from the start command. - */ - nodeId = 0; - while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) { - if (!nodes.get(nodeId)) - continue; - int result; - result = start(nodeId); - DEBUG("Starting node " << nodeId << " with result " << result); - /** - * Errors from this call are deliberately ignored. - * Maybe the user only wanted to restart a subset of the nodes. - * It is also easy for the user to check which nodes have - * started and which nodes have not. - */ - } - - return 0; -} - -int -MgmtSrvr::exitSingleUser(int * stopCount, bool abort) -{ - NodeId nodeId = 0; - int count = 0; - - SignalSender ss(theFacade); - ss.lock(); // lock will be released on exit - - SimpleSignal ssig; - ResumeReq* const resumeReq = - CAST_PTR(ResumeReq, ssig.getDataPtrSend()); - ssig.set(ss,TestOrd::TraceAPI, NDBCNTR, GSN_RESUME_REQ, - ResumeReq::SignalLength); - resumeReq->senderData = 12; - resumeReq->senderRef = ss.getOwnRef(); - - while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)){ - if(okToSendTo(nodeId, true) == 0){ - SendStatus result = ss.sendSignal(nodeId, &ssig); - if (result == SEND_OK) - count++; - } - } - - if(stopCount != 0) - * stopCount = count; - - return 0; -} - -/***************************************************************************** - * Status - ****************************************************************************/ - -#include <ClusterMgr.hpp> - -void -MgmtSrvr::updateStatus() -{ - theFacade->theClusterMgr->forceHB(); -} - -int -MgmtSrvr::status(int nodeId, - ndb_mgm_node_status * _status, - Uint32 * version, - Uint32 * _phase, - bool * _system, - Uint32 * dynamic, - Uint32 * nodegroup, - Uint32 * connectCount, - const char **address) -{ - if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_API || - getNodeType(nodeId) == NDB_MGM_NODE_TYPE_MGM) { - versionNode(nodeId, *version, address); - } else { - *address= get_connect_address(nodeId); - } - - const ClusterMgr::Node node = - theFacade->theClusterMgr->getNodeInfo(nodeId); - - if(!node.connected){ - * _status = NDB_MGM_NODE_STATUS_NO_CONTACT; - return 0; - } - - if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_NDB) { - * version = node.m_info.m_version; - } - - * dynamic = node.m_state.dynamicId; - * nodegroup = node.m_state.nodeGroup; - * connectCount = node.m_info.m_connectCount; - - switch(node.m_state.startLevel){ - case NodeState::SL_CMVMI: - * _status = NDB_MGM_NODE_STATUS_NOT_STARTED; - * _phase = 0; - return 0; - break; - case NodeState::SL_STARTING: - * _status = NDB_MGM_NODE_STATUS_STARTING; - * _phase = node.m_state.starting.startPhase; - return 0; - break; - case NodeState::SL_STARTED: - * _status = NDB_MGM_NODE_STATUS_STARTED; - * _phase = 0; - return 0; - break; - case NodeState::SL_STOPPING_1: - * _status = NDB_MGM_NODE_STATUS_SHUTTING_DOWN; - * _phase = 1; - * _system = node.m_state.stopping.systemShutdown != 0; - return 0; - break; - case NodeState::SL_STOPPING_2: - * _status = NDB_MGM_NODE_STATUS_SHUTTING_DOWN; - * _phase = 2; - * _system = node.m_state.stopping.systemShutdown != 0; - return 0; - break; - case NodeState::SL_STOPPING_3: - * _status = NDB_MGM_NODE_STATUS_SHUTTING_DOWN; - * _phase = 3; - * _system = node.m_state.stopping.systemShutdown != 0; - return 0; - break; - case NodeState::SL_STOPPING_4: - * _status = NDB_MGM_NODE_STATUS_SHUTTING_DOWN; - * _phase = 4; - * _system = node.m_state.stopping.systemShutdown != 0; - return 0; - break; - case NodeState::SL_SINGLEUSER: - * _status = NDB_MGM_NODE_STATUS_SINGLEUSER; - * _phase = 0; - return 0; - break; - default: - * _status = NDB_MGM_NODE_STATUS_UNKNOWN; - * _phase = 0; - return 0; - } - - return -1; -} - -int -MgmtSrvr::setEventReportingLevelImpl(int nodeId_arg, - const EventSubscribeReq& ll) -{ - SignalSender ss(theFacade); - NdbNodeBitmask nodes; - nodes.clear(); - while (1) - { - Uint32 nodeId, max; - ss.lock(); - SimpleSignal ssig; - EventSubscribeReq * dst = - CAST_PTR(EventSubscribeReq, ssig.getDataPtrSend()); - ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_EVENT_SUBSCRIBE_REQ, - EventSubscribeReq::SignalLength); - *dst = ll; - - if (nodeId_arg == 0) - { - // all nodes - nodeId = 1; - max = MAX_NDB_NODES; - } - else - { - // only one node - max = nodeId = nodeId_arg; - } - // first make sure nodes are sendable - for(; nodeId <= max; nodeId++) - { - if (nodeTypes[nodeId] != NODE_TYPE_DB) - continue; - if (okToSendTo(nodeId, true)) - { - if (theFacade->theClusterMgr->getNodeInfo(nodeId).connected == false) - { - // node not connected we can safely skip this one - continue; - } - // api_reg_conf not recevied yet, need to retry - return SEND_OR_RECEIVE_FAILED; - } - } - - if (nodeId_arg == 0) - { - // all nodes - nodeId = 1; - max = MAX_NDB_NODES; - } - else - { - // only one node - max = nodeId = nodeId_arg; - } - // now send to all sendable nodes nodes - // note, lock is held, so states have not changed - for(; (Uint32) nodeId <= max; nodeId++) - { - if (nodeTypes[nodeId] != NODE_TYPE_DB) - continue; - if (theFacade->theClusterMgr->getNodeInfo(nodeId).connected == false) - continue; // node is not connected, skip - if (ss.sendSignal(nodeId, &ssig) == SEND_OK) - nodes.set(nodeId); - else if (max == nodeId) - { - return SEND_OR_RECEIVE_FAILED; - } - } - break; - } - - if (nodes.isclear()) - { - return SEND_OR_RECEIVE_FAILED; - } - - int error = 0; - while (!nodes.isclear()) - { - Uint32 nodeId; - SimpleSignal *signal = ss.waitFor(); - int gsn = signal->readSignalNumber(); - nodeId = refToNode(signal->header.theSendersBlockRef); - switch (gsn) { - case GSN_EVENT_SUBSCRIBE_CONF:{ - nodes.clear(nodeId); - break; - } - case GSN_EVENT_SUBSCRIBE_REF:{ - nodes.clear(nodeId); - error = 1; - break; - } - // Since sending okToSend(true), - // there is no guarantee that NF_COMPLETEREP will come - // i.e listen also to NODE_FAILREP - case GSN_NODE_FAILREP: { - const NodeFailRep * const rep = - CAST_CONSTPTR(NodeFailRep, signal->getDataPtr()); - NdbNodeBitmask mask; - mask.assign(NdbNodeBitmask::Size, rep->theNodes); - nodes.bitANDC(mask); - break; - } - - case GSN_NF_COMPLETEREP:{ - const NFCompleteRep * const rep = - CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr()); - nodes.clear(rep->failedNodeId); - break; - } - default: - report_unknown_signal(signal); - return SEND_OR_RECEIVE_FAILED; - } - } - if (error) - return SEND_OR_RECEIVE_FAILED; - return 0; -} - -//**************************************************************************** -//**************************************************************************** -int -MgmtSrvr::setNodeLogLevelImpl(int nodeId, const SetLogLevelOrd & ll) -{ - INIT_SIGNAL_SENDER(ss,nodeId); - - SimpleSignal ssig; - ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_SET_LOGLEVELORD, - SetLogLevelOrd::SignalLength); - SetLogLevelOrd* const dst = CAST_PTR(SetLogLevelOrd, ssig.getDataPtrSend()); - *dst = ll; - - return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED; -} - -//**************************************************************************** -//**************************************************************************** - -int -MgmtSrvr::insertError(int nodeId, int errorNo) -{ - int block; - - if (errorNo < 0) { - return INVALID_ERROR_NUMBER; - } - - SignalSender ss(theFacade); - ss.lock(); /* lock will be released on exit */ - - if(getNodeType(nodeId) == NDB_MGM_NODE_TYPE_NDB) - { - block= CMVMI; - } - else if(nodeId == _ownNodeId) - { - g_errorInsert= errorNo; - return 0; - } - else if(getNodeType(nodeId) == NDB_MGM_NODE_TYPE_MGM) - block= _blockNumber; - else - return WRONG_PROCESS_TYPE; - - SimpleSignal ssig; - ssig.set(ss,TestOrd::TraceAPI, block, GSN_TAMPER_ORD, - TamperOrd::SignalLength); - TamperOrd* const tamperOrd = CAST_PTR(TamperOrd, ssig.getDataPtrSend()); - tamperOrd->errorNo = errorNo; - - return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED; -} - - - -//**************************************************************************** -//**************************************************************************** - -int -MgmtSrvr::setTraceNo(int nodeId, int traceNo) -{ - if (traceNo < 0) { - return INVALID_TRACE_NUMBER; - } - - INIT_SIGNAL_SENDER(ss,nodeId); - - SimpleSignal ssig; - ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength); - TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend()); - testOrd->clear(); - // Assume TRACE command causes toggling. Not really defined... ? TODO - testOrd->setTraceCommand(TestOrd::Toggle, - (TestOrd::TraceSpecification)traceNo); - - return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED; -} - -//**************************************************************************** -//**************************************************************************** - -int -MgmtSrvr::getBlockNumber(const BaseString &blockName) -{ - short bno = getBlockNo(blockName.c_str()); - if(bno != 0) - return bno; - return -1; -} - -//**************************************************************************** -//**************************************************************************** - -int -MgmtSrvr::setSignalLoggingMode(int nodeId, LogMode mode, - const Vector<BaseString>& blocks) -{ - INIT_SIGNAL_SENDER(ss,nodeId); - - // Convert from MgmtSrvr format... - - TestOrd::Command command; - if (mode == Off) { - command = TestOrd::Off; - } - else { - command = TestOrd::On; - } - - TestOrd::SignalLoggerSpecification logSpec; - switch (mode) { - case In: - logSpec = TestOrd::InputSignals; - break; - case Out: - logSpec = TestOrd::OutputSignals; - break; - case InOut: - logSpec = TestOrd::InputOutputSignals; - break; - case Off: - // In MgmtSrvr interface it's just possible to switch off all logging, both - // "in" and "out" (this should probably be changed). - logSpec = TestOrd::InputOutputSignals; - break; - default: - ndbout_c("Unexpected value %d, MgmtSrvr::setSignalLoggingMode, line %d", - (unsigned)mode, __LINE__); - assert(false); - return -1; - } - - SimpleSignal ssig; - ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength); - - TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend()); - testOrd->clear(); - - if (blocks.size() == 0 || blocks[0] == "ALL") { - // Logg command for all blocks - testOrd->addSignalLoggerCommand(command, logSpec); - } else { - for(unsigned i = 0; i < blocks.size(); i++){ - int blockNumber = getBlockNumber(blocks[i]); - if (blockNumber == -1) { - return INVALID_BLOCK_NAME; - } - testOrd->addSignalLoggerCommand(blockNumber, command, logSpec); - } // for - } // else - - return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED; -} - -/***************************************************************************** - * Signal tracing - *****************************************************************************/ -int MgmtSrvr::startSignalTracing(int nodeId) -{ - INIT_SIGNAL_SENDER(ss,nodeId); - - SimpleSignal ssig; - ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength); - - TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend()); - testOrd->clear(); - testOrd->setTestCommand(TestOrd::On); - - return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED; -} - -int -MgmtSrvr::stopSignalTracing(int nodeId) -{ - INIT_SIGNAL_SENDER(ss,nodeId); - - SimpleSignal ssig; - ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength); - TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend()); - testOrd->clear(); - testOrd->setTestCommand(TestOrd::Off); - - return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED; -} - - -/***************************************************************************** - * Dump state - *****************************************************************************/ - -int -MgmtSrvr::dumpState(int nodeId, const char* args) -{ - // Convert the space separeted args - // string to an int array - Uint32 args_array[25]; - Uint32 numArgs = 0; - - char buf[10]; - int b = 0; - memset(buf, 0, 10); - for (size_t i = 0; i <= strlen(args); i++){ - if (args[i] == ' ' || args[i] == 0){ - args_array[numArgs] = atoi(buf); - numArgs++; - memset(buf, 0, 10); - b = 0; - } else { - buf[b] = args[i]; - b++; - } - } - - return dumpState(nodeId, args_array, numArgs); -} - -int -MgmtSrvr::dumpState(int nodeId, const Uint32 args[], Uint32 no) -{ - INIT_SIGNAL_SENDER(ss,nodeId); - - const Uint32 len = no > 25 ? 25 : no; - - SimpleSignal ssig; - DumpStateOrd * const dumpOrd = - CAST_PTR(DumpStateOrd, ssig.getDataPtrSend()); - ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_DUMP_STATE_ORD, len); - for(Uint32 i = 0; i<25; i++){ - if (i < len) - dumpOrd->args[i] = args[i]; - else - dumpOrd->args[i] = 0; - } - - return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED; -} - - -//**************************************************************************** -//**************************************************************************** - -const char* MgmtSrvr::getErrorText(int errorCode, char *buf, int buf_sz) -{ - ndb_error_string(errorCode, buf, buf_sz); - buf[buf_sz-1]= 0; - return buf; -} - -void -MgmtSrvr::handleReceivedSignal(NdbApiSignal* signal) -{ - // The way of handling a received signal is taken from the Ndb class. - int gsn = signal->readSignalNumber(); - - switch (gsn) { - case GSN_EVENT_SUBSCRIBE_CONF: - break; - case GSN_EVENT_SUBSCRIBE_REF: - break; - case GSN_EVENT_REP: - { - eventReport(signal->getDataPtr()); - break; - } - - case GSN_NF_COMPLETEREP: - break; - case GSN_NODE_FAILREP: - break; - - case GSN_TAMPER_ORD: - ndbout << "TAMPER ORD" << endl; - break; - - default: - g_eventLogger.error("Unknown signal received. SignalNumber: " - "%i from (%d, %x)", - gsn, - refToNode(signal->theSendersBlockRef), - refToBlock(signal->theSendersBlockRef)); - } - - if (theWaitState == NO_WAIT) { - NdbCondition_Signal(theMgmtWaitForResponseCondPtr); - } -} - -void -MgmtSrvr::handleStatus(NodeId nodeId, bool alive, bool nfComplete) -{ - DBUG_ENTER("MgmtSrvr::handleStatus"); - Uint32 theData[25]; - EventReport *rep = (EventReport *)theData; - - theData[1] = nodeId; - if (alive) { - if (nodeTypes[nodeId] == NODE_TYPE_DB) - { - m_started_nodes.push_back(nodeId); - } - rep->setEventType(NDB_LE_Connected); - } else { - rep->setEventType(NDB_LE_Disconnected); - if(nfComplete) - { - DBUG_VOID_RETURN; - } - } - rep->setNodeId(_ownNodeId); - eventReport(theData); - DBUG_VOID_RETURN; -} - -//**************************************************************************** -//**************************************************************************** - -void -MgmtSrvr::signalReceivedNotification(void* mgmtSrvr, - NdbApiSignal* signal, - LinearSectionPtr ptr[3]) -{ - ((MgmtSrvr*)mgmtSrvr)->handleReceivedSignal(signal); -} - - -//**************************************************************************** -//**************************************************************************** -void -MgmtSrvr::nodeStatusNotification(void* mgmSrv, Uint32 nodeId, - bool alive, bool nfComplete) -{ - DBUG_ENTER("MgmtSrvr::nodeStatusNotification"); - DBUG_PRINT("enter",("nodeid= %d, alive= %d, nfComplete= %d", nodeId, alive, nfComplete)); - ((MgmtSrvr*)mgmSrv)->handleStatus(nodeId, alive, nfComplete); - DBUG_VOID_RETURN; -} - -enum ndb_mgm_node_type -MgmtSrvr::getNodeType(NodeId nodeId) const -{ - if(nodeId >= MAX_NODES) - return (enum ndb_mgm_node_type)-1; - - return nodeTypes[nodeId]; -} - -const char *MgmtSrvr::get_connect_address(Uint32 node_id) -{ - if (m_connect_address[node_id].s_addr == 0 && - theFacade && theFacade->theTransporterRegistry && - theFacade->theClusterMgr && - getNodeType(node_id) == NDB_MGM_NODE_TYPE_NDB) - { - const ClusterMgr::Node &node= - theFacade->theClusterMgr->getNodeInfo(node_id); - if (node.connected) - { - m_connect_address[node_id]= - theFacade->theTransporterRegistry->get_connect_address(node_id); - } - } - return inet_ntoa(m_connect_address[node_id]); -} - -void -MgmtSrvr::get_connected_nodes(NodeBitmask &connected_nodes) const -{ - if (theFacade && theFacade->theClusterMgr) - { - for(Uint32 i = 0; i < MAX_NODES; i++) - { - if (getNodeType(i) == NDB_MGM_NODE_TYPE_NDB) - { - const ClusterMgr::Node &node= theFacade->theClusterMgr->getNodeInfo(i); - connected_nodes.bitOR(node.m_state.m_connected_nodes); - } - } - } -} - -int -MgmtSrvr::alloc_node_id_req(NodeId free_node_id, enum ndb_mgm_node_type type) -{ - SignalSender ss(theFacade); - ss.lock(); // lock will be released on exit - - SimpleSignal ssig; - AllocNodeIdReq* req = CAST_PTR(AllocNodeIdReq, ssig.getDataPtrSend()); - ssig.set(ss, TestOrd::TraceAPI, QMGR, GSN_ALLOC_NODEID_REQ, - AllocNodeIdReq::SignalLength); - - req->senderRef = ss.getOwnRef(); - req->senderData = 19; - req->nodeId = free_node_id; - req->nodeType = type; - - int do_send = 1; - NodeId nodeId = 0; - while (1) - { - if (nodeId == 0) - { - bool next; - while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true && - theFacade->get_node_alive(nodeId) == false); - if (!next) - return NO_CONTACT_WITH_DB_NODES; - do_send = 1; - } - if (do_send) - { - if (ss.sendSignal(nodeId, &ssig) != SEND_OK) { - return SEND_OR_RECEIVE_FAILED; - } - do_send = 0; - } - - SimpleSignal *signal = ss.waitFor(); - - int gsn = signal->readSignalNumber(); - switch (gsn) { - case GSN_ALLOC_NODEID_CONF: - { -#ifdef NOT_USED - const AllocNodeIdConf * const conf = - CAST_CONSTPTR(AllocNodeIdConf, signal->getDataPtr()); -#endif - return 0; - } - case GSN_ALLOC_NODEID_REF: - { - const AllocNodeIdRef * const ref = - CAST_CONSTPTR(AllocNodeIdRef, signal->getDataPtr()); - if (ref->errorCode == AllocNodeIdRef::NotMaster || - ref->errorCode == AllocNodeIdRef::Busy || - ref->errorCode == AllocNodeIdRef::NodeFailureHandlingNotCompleted) - { - do_send = 1; - nodeId = refToNode(ref->masterRef); - if (!theFacade->get_node_alive(nodeId)) - nodeId = 0; - if (ref->errorCode != AllocNodeIdRef::NotMaster) - { - /* sleep for a while (100ms) before retrying */ - NdbSleep_MilliSleep(100); - } - continue; - } - return ref->errorCode; - } - case GSN_NF_COMPLETEREP: - { - const NFCompleteRep * const rep = - CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr()); -#ifdef VM_TRACE - ndbout_c("Node %d fail completed", rep->failedNodeId); -#endif - if (rep->failedNodeId == nodeId) - { - do_send = 1; - nodeId = 0; - } - continue; - } - case GSN_NODE_FAILREP:{ - // ignore NF_COMPLETEREP will come - continue; - } - default: - report_unknown_signal(signal); - return SEND_OR_RECEIVE_FAILED; - } - } - return 0; -} - -bool -MgmtSrvr::alloc_node_id(NodeId * nodeId, - enum ndb_mgm_node_type type, - struct sockaddr *client_addr, - SOCKET_SIZE_TYPE *client_addr_len, - int &error_code, BaseString &error_string, - int log_event) -{ - DBUG_ENTER("MgmtSrvr::alloc_node_id"); - DBUG_PRINT("enter", ("nodeid: %d type: %d client_addr: 0x%ld", - *nodeId, type, (long) client_addr)); - if (g_no_nodeid_checks) { - if (*nodeId == 0) { - error_string.appfmt("no-nodeid-checks set in management server.\n" - "node id must be set explicitly in connectstring"); - error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH; - DBUG_RETURN(false); - } - DBUG_RETURN(true); - } - Guard g(m_node_id_mutex); - int no_mgm= 0; - NodeBitmask connected_nodes(m_reserved_nodes); - get_connected_nodes(connected_nodes); - { - for(Uint32 i = 0; i < MAX_NODES; i++) - if (getNodeType(i) == NDB_MGM_NODE_TYPE_MGM) - no_mgm++; - } - bool found_matching_id= false; - bool found_matching_type= false; - bool found_free_node= false; - unsigned id_found= 0; - const char *config_hostname= 0; - struct in_addr config_addr= {0}; - int r_config_addr= -1; - unsigned type_c= 0; - - if(NdbMutex_Lock(m_configMutex)) - { - // should not happen - error_string.appfmt("unable to lock configuration mutex"); - error_code = NDB_MGM_ALLOCID_ERROR; - DBUG_RETURN(false); - } - ndb_mgm_configuration_iterator - iter(* _config->m_configValues, CFG_SECTION_NODE); - for(iter.first(); iter.valid(); iter.next()) { - unsigned tmp= 0; - if(iter.get(CFG_NODE_ID, &tmp)) require(false); - if (*nodeId && *nodeId != tmp) - continue; - found_matching_id= true; - if(iter.get(CFG_TYPE_OF_SECTION, &type_c)) require(false); - if(type_c != (unsigned)type) - continue; - found_matching_type= true; - if (connected_nodes.get(tmp)) - continue; - found_free_node= true; - if(iter.get(CFG_NODE_HOST, &config_hostname)) require(false); - if (config_hostname && config_hostname[0] == 0) - config_hostname= 0; - else if (client_addr) { - // check hostname compatability - const void *tmp_in= &(((sockaddr_in*)client_addr)->sin_addr); - if((r_config_addr= Ndb_getInAddr(&config_addr, config_hostname)) != 0 - || memcmp(&config_addr, tmp_in, sizeof(config_addr)) != 0) { - struct in_addr tmp_addr; - if(Ndb_getInAddr(&tmp_addr, "localhost") != 0 - || memcmp(&tmp_addr, tmp_in, sizeof(config_addr)) != 0) { - // not localhost -#if 0 - ndbout << "MgmtSrvr::getFreeNodeId compare failed for \"" - << config_hostname - << "\" id=" << tmp << endl; -#endif - continue; - } - // connecting through localhost - // check if config_hostname is local - if (!SocketServer::tryBind(0,config_hostname)) { - continue; - } - } - } else { // client_addr == 0 - if (!SocketServer::tryBind(0,config_hostname)) { - continue; - } - } - if (*nodeId != 0 || - type != NDB_MGM_NODE_TYPE_MGM || - no_mgm == 1) { // any match is ok - - if (config_hostname == 0 && - *nodeId == 0 && - type != NDB_MGM_NODE_TYPE_MGM) - { - if (!id_found) // only set if not set earlier - id_found= tmp; - continue; /* continue looking for a nodeid with specified - * hostname - */ - } - assert(id_found == 0); - id_found= tmp; - break; - } - if (id_found) { // mgmt server may only have one match - error_string.appfmt("Ambiguous node id's %d and %d.\n" - "Suggest specifying node id in connectstring,\n" - "or specifying unique host names in config file.", - id_found, tmp); - NdbMutex_Unlock(m_configMutex); - error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH; - DBUG_RETURN(false); - } - if (config_hostname == 0) { - error_string.appfmt("Ambiguity for node id %d.\n" - "Suggest specifying node id in connectstring,\n" - "or specifying unique host names in config file,\n" - "or specifying just one mgmt server in config file.", - tmp); - error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH; - DBUG_RETURN(false); - } - id_found= tmp; // mgmt server matched, check for more matches - } - NdbMutex_Unlock(m_configMutex); - - if (id_found && client_addr != 0) - { - int res = alloc_node_id_req(id_found, type); - unsigned save_id_found = id_found; - switch (res) - { - case 0: - // ok continue - break; - case NO_CONTACT_WITH_DB_NODES: - // ok continue - break; - default: - // something wrong - id_found = 0; - break; - - } - if (id_found == 0) - { - char buf[128]; - ndb_error_string(res, buf, sizeof(buf)); - error_string.appfmt("Cluster refused allocation of id %d. Error: %d (%s).", - save_id_found, res, buf); - g_eventLogger.warning("Cluster refused allocation of id %d. " - "Connection from ip %s. " - "Returned error string \"%s\"", save_id_found, - inet_ntoa(((struct sockaddr_in *)(client_addr))->sin_addr), - error_string.c_str()); - DBUG_RETURN(false); - } - } - - if (id_found) - { - *nodeId= id_found; - DBUG_PRINT("info", ("allocating node id %d",*nodeId)); - { - int r= 0; - if (client_addr) - m_connect_address[id_found]= - ((struct sockaddr_in *)client_addr)->sin_addr; - else if (config_hostname) - r= Ndb_getInAddr(&(m_connect_address[id_found]), config_hostname); - else { - char name[256]; - r= gethostname(name, sizeof(name)); - if (r == 0) { - name[sizeof(name)-1]= 0; - r= Ndb_getInAddr(&(m_connect_address[id_found]), name); - } - } - if (r) - m_connect_address[id_found].s_addr= 0; - } - m_reserved_nodes.set(id_found); - if (theFacade && id_found != theFacade->ownId()) - { - /** - * Make sure we're ready to accept connections from this node - */ - theFacade->lock_mutex(); - theFacade->doConnect(id_found); - theFacade->unlock_mutex(); - } - - char tmp_str[128]; - m_reserved_nodes.getText(tmp_str); - g_eventLogger.info("Mgmt server state: nodeid %d reserved for ip %s, " - "m_reserved_nodes %s.", - id_found, get_connect_address(id_found), tmp_str); - DBUG_RETURN(true); - } - - if (found_matching_type && !found_free_node) { - // we have a temporary error which might be due to that - // we have got the latest connect status from db-nodes. Force update. - updateStatus(); - } - - BaseString type_string, type_c_string; - { - const char *alias, *str; - alias= ndb_mgm_get_node_type_alias_string(type, &str); - type_string.assfmt("%s(%s)", alias, str); - alias= ndb_mgm_get_node_type_alias_string((enum ndb_mgm_node_type)type_c, - &str); - type_c_string.assfmt("%s(%s)", alias, str); - } - - if (*nodeId == 0) - { - if (found_matching_id) - { - if (found_matching_type) - { - if (found_free_node) - { - error_string.appfmt("Connection done from wrong host ip %s.", - (client_addr)? - inet_ntoa(((struct sockaddr_in *) - (client_addr))->sin_addr):""); - error_code = NDB_MGM_ALLOCID_ERROR; - } - else - { - error_string.appfmt("No free node id found for %s.", - type_string.c_str()); - error_code = NDB_MGM_ALLOCID_ERROR; - } - } - else - { - error_string.appfmt("No %s node defined in config file.", - type_string.c_str()); - error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH; - } - } - else - { - error_string.append("No nodes defined in config file."); - error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH; - } - } - else - { - if (found_matching_id) - { - if (found_matching_type) - { - if (found_free_node) - { - // have to split these into two since inet_ntoa overwrites itself - error_string.appfmt("Connection with id %d done from wrong host ip %s,", - *nodeId, inet_ntoa(((struct sockaddr_in *) - (client_addr))->sin_addr)); - error_string.appfmt(" expected %s(%s).", config_hostname, - r_config_addr ? - "lookup failed" : inet_ntoa(config_addr)); - error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH; - } - else - { - error_string.appfmt("Id %d already allocated by another node.", - *nodeId); - error_code = NDB_MGM_ALLOCID_ERROR; - } - } - else - { - error_string.appfmt("Id %d configured as %s, connect attempted as %s.", - *nodeId, type_c_string.c_str(), - type_string.c_str()); - error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH; - } - } - else - { - error_string.appfmt("No node defined with id=%d in config file.", - *nodeId); - error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH; - } - } - - if (log_event || error_code == NDB_MGM_ALLOCID_CONFIG_MISMATCH) - { - g_eventLogger.warning("Allocate nodeid (%d) failed. Connection from ip %s." - " Returned error string \"%s\"", - *nodeId, - client_addr != 0 - ? inet_ntoa(((struct sockaddr_in *) - (client_addr))->sin_addr) - : "<none>", - error_string.c_str()); - - NodeBitmask connected_nodes2; - get_connected_nodes(connected_nodes2); - BaseString tmp_connected, tmp_not_connected; - for(Uint32 i = 0; i < MAX_NODES; i++) - { - if (connected_nodes2.get(i)) - { - if (!m_reserved_nodes.get(i)) - tmp_connected.appfmt(" %d", i); - } - else if (m_reserved_nodes.get(i)) - { - tmp_not_connected.appfmt(" %d", i); - } - } - if (tmp_connected.length() > 0) - g_eventLogger.info("Mgmt server state: node id's %s connected but not reserved", - tmp_connected.c_str()); - if (tmp_not_connected.length() > 0) - g_eventLogger.info("Mgmt server state: node id's %s not connected but reserved", - tmp_not_connected.c_str()); - } - DBUG_RETURN(false); -} - -bool -MgmtSrvr::getNextNodeId(NodeId * nodeId, enum ndb_mgm_node_type type) const -{ - NodeId tmp = * nodeId; - - tmp++; - while(nodeTypes[tmp] != type && tmp < MAX_NODES) - tmp++; - - if(tmp == MAX_NODES){ - return false; - } - - * nodeId = tmp; - return true; -} - -#include "Services.hpp" - -void -MgmtSrvr::eventReport(const Uint32 * theData) -{ - const EventReport * const eventReport = (EventReport *)&theData[0]; - - NodeId nodeId = eventReport->getNodeId(); - Ndb_logevent_type type = eventReport->getEventType(); - // Log event - g_eventLogger.log(type, theData, nodeId, - &m_event_listner[0].m_logLevel); - m_event_listner.log(type, theData, nodeId); -} - -/*************************************************************************** - * Backup - ***************************************************************************/ - -int -MgmtSrvr::startBackup(Uint32& backupId, int waitCompleted) -{ - SignalSender ss(theFacade); - ss.lock(); // lock will be released on exit - - NodeId nodeId = m_master_node; - if (okToSendTo(nodeId, false) != 0) - { - bool next; - nodeId = m_master_node = 0; - while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true && - okToSendTo(nodeId, false) != 0); - if(!next) - return NO_CONTACT_WITH_DB_NODES; - } - - SimpleSignal ssig; - BackupReq* req = CAST_PTR(BackupReq, ssig.getDataPtrSend()); - ssig.set(ss, TestOrd::TraceAPI, BACKUP, GSN_BACKUP_REQ, - BackupReq::SignalLength); - - req->senderData = 19; - req->backupDataLen = 0; - assert(waitCompleted < 3); - req->flags = waitCompleted & 0x3; - - BackupEvent event; - int do_send = 1; - while (1) { - if (do_send) - { - if (ss.sendSignal(nodeId, &ssig) != SEND_OK) { - return SEND_OR_RECEIVE_FAILED; - } - if (waitCompleted == 0) - return 0; - do_send = 0; - } - SimpleSignal *signal = ss.waitFor(); - - int gsn = signal->readSignalNumber(); - switch (gsn) { - case GSN_BACKUP_CONF:{ - const BackupConf * const conf = - CAST_CONSTPTR(BackupConf, signal->getDataPtr()); - event.Event = BackupEvent::BackupStarted; - event.Started.BackupId = conf->backupId; - event.Nodes = conf->nodes; -#ifdef VM_TRACE - ndbout_c("Backup(%d) master is %d", conf->backupId, - refToNode(signal->header.theSendersBlockRef)); -#endif - backupId = conf->backupId; - if (waitCompleted == 1) - return 0; - // wait for next signal - break; - } - case GSN_BACKUP_COMPLETE_REP:{ - const BackupCompleteRep * const rep = - CAST_CONSTPTR(BackupCompleteRep, signal->getDataPtr()); -#ifdef VM_TRACE - ndbout_c("Backup(%d) completed", rep->backupId); -#endif - event.Event = BackupEvent::BackupCompleted; - event.Completed.BackupId = rep->backupId; - - event.Completed.NoOfBytes = rep->noOfBytesLow; - event.Completed.NoOfLogBytes = rep->noOfLogBytes; - event.Completed.NoOfRecords = rep->noOfRecordsLow; - event.Completed.NoOfLogRecords = rep->noOfLogRecords; - event.Completed.stopGCP = rep->stopGCP; - event.Completed.startGCP = rep->startGCP; - event.Nodes = rep->nodes; - - if (signal->header.theLength >= BackupCompleteRep::SignalLength) - { - event.Completed.NoOfBytes += ((Uint64)rep->noOfBytesHigh) << 32; - event.Completed.NoOfRecords += ((Uint64)rep->noOfRecordsHigh) << 32; - } - - backupId = rep->backupId; - return 0; - } - case GSN_BACKUP_REF:{ - const BackupRef * const ref = - CAST_CONSTPTR(BackupRef, signal->getDataPtr()); - if(ref->errorCode == BackupRef::IAmNotMaster){ - m_master_node = nodeId = refToNode(ref->masterRef); -#ifdef VM_TRACE - ndbout_c("I'm not master resending to %d", nodeId); -#endif - do_send = 1; // try again - if (!theFacade->get_node_alive(nodeId)) - m_master_node = nodeId = 0; - continue; - } - event.Event = BackupEvent::BackupFailedToStart; - event.FailedToStart.ErrorCode = ref->errorCode; - return ref->errorCode; - } - case GSN_BACKUP_ABORT_REP:{ - const BackupAbortRep * const rep = - CAST_CONSTPTR(BackupAbortRep, signal->getDataPtr()); - event.Event = BackupEvent::BackupAborted; - event.Aborted.Reason = rep->reason; - event.Aborted.BackupId = rep->backupId; - event.Aborted.ErrorCode = rep->reason; -#ifdef VM_TRACE - ndbout_c("Backup %d aborted", rep->backupId); -#endif - return rep->reason; - } - case GSN_NF_COMPLETEREP:{ - const NFCompleteRep * const rep = - CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr()); -#ifdef VM_TRACE - ndbout_c("Node %d fail completed", rep->failedNodeId); -#endif - if (rep->failedNodeId == nodeId || - waitCompleted == 1) - return 1326; - // wait for next signal - // master node will report aborted backup - break; - } - case GSN_NODE_FAILREP:{ - const NodeFailRep * const rep = - CAST_CONSTPTR(NodeFailRep, signal->getDataPtr()); - if (NodeBitmask::get(rep->theNodes,nodeId) || - waitCompleted == 1) - return 1326; - // wait for next signal - // master node will report aborted backup - break; - } - default: - report_unknown_signal(signal); - return SEND_OR_RECEIVE_FAILED; - } - } -} - -int -MgmtSrvr::abortBackup(Uint32 backupId) -{ - SignalSender ss(theFacade); - ss.lock(); // lock will be released on exit - - bool next; - NodeId nodeId = 0; - while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true && - theFacade->get_node_alive(nodeId) == false); - - if(!next){ - return NO_CONTACT_WITH_DB_NODES; - } - - SimpleSignal ssig; - - AbortBackupOrd* ord = CAST_PTR(AbortBackupOrd, ssig.getDataPtrSend()); - ssig.set(ss, TestOrd::TraceAPI, BACKUP, GSN_ABORT_BACKUP_ORD, - AbortBackupOrd::SignalLength); - - ord->requestType = AbortBackupOrd::ClientAbort; - ord->senderData = 19; - ord->backupId = backupId; - - return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED; -} - - -MgmtSrvr::Allocated_resources::Allocated_resources(MgmtSrvr &m) - : m_mgmsrv(m) -{ - m_reserved_nodes.clear(); - m_alloc_timeout= 0; -} - -MgmtSrvr::Allocated_resources::~Allocated_resources() -{ - Guard g(m_mgmsrv.m_node_id_mutex); - if (!m_reserved_nodes.isclear()) { - m_mgmsrv.m_reserved_nodes.bitANDC(m_reserved_nodes); - // node has been reserved, force update signal to ndb nodes - m_mgmsrv.updateStatus(); - - char tmp_str[128]; - m_mgmsrv.m_reserved_nodes.getText(tmp_str); - g_eventLogger.info("Mgmt server state: nodeid %d freed, m_reserved_nodes %s.", - get_nodeid(), tmp_str); - } -} - -void -MgmtSrvr::Allocated_resources::reserve_node(NodeId id, NDB_TICKS timeout) -{ - m_reserved_nodes.set(id); - m_alloc_timeout= NdbTick_CurrentMillisecond() + timeout; -} - -bool -MgmtSrvr::Allocated_resources::is_timed_out(NDB_TICKS tick) -{ - if (m_alloc_timeout && tick > m_alloc_timeout) - { - g_eventLogger.info("Mgmt server state: nodeid %d timed out.", - get_nodeid()); - return true; - } - return false; -} - -NodeId -MgmtSrvr::Allocated_resources::get_nodeid() const -{ - for(Uint32 i = 0; i < MAX_NODES; i++) - { - if (m_reserved_nodes.get(i)) - return i; - } - return 0; -} - -int -MgmtSrvr::setDbParameter(int node, int param, const char * value, - BaseString& msg){ - - if(NdbMutex_Lock(m_configMutex)) - return -1; - - /** - * Check parameter - */ - ndb_mgm_configuration_iterator - iter(* _config->m_configValues, CFG_SECTION_NODE); - if(iter.first() != 0){ - msg.assign("Unable to find node section (iter.first())"); - NdbMutex_Unlock(m_configMutex); - return -1; - } - - Uint32 type = NODE_TYPE_DB + 1; - if(node != 0){ - if(iter.find(CFG_NODE_ID, node) != 0){ - msg.assign("Unable to find node (iter.find())"); - NdbMutex_Unlock(m_configMutex); - return -1; - } - if(iter.get(CFG_TYPE_OF_SECTION, &type) != 0){ - msg.assign("Unable to get node type(iter.get(CFG_TYPE_OF_SECTION))"); - NdbMutex_Unlock(m_configMutex); - return -1; - } - } else { - do { - if(iter.get(CFG_TYPE_OF_SECTION, &type) != 0){ - msg.assign("Unable to get node type(iter.get(CFG_TYPE_OF_SECTION))"); - NdbMutex_Unlock(m_configMutex); - return -1; - } - if(type == NODE_TYPE_DB) - break; - } while(iter.next() == 0); - } - - if(type != NODE_TYPE_DB){ - msg.assfmt("Invalid node type or no such node (%d %d)", - type, NODE_TYPE_DB); - NdbMutex_Unlock(m_configMutex); - return -1; - } - - int p_type; - unsigned val_32; - Uint64 val_64; - const char * val_char; - do { - p_type = 0; - if(iter.get(param, &val_32) == 0){ - val_32 = atoi(value); - break; - } - - p_type++; - if(iter.get(param, &val_64) == 0){ - val_64 = strtoll(value, 0, 10); - break; - } - p_type++; - if(iter.get(param, &val_char) == 0){ - val_char = value; - break; - } - msg.assign("Could not get parameter"); - NdbMutex_Unlock(m_configMutex); - return -1; - } while(0); - - bool res = false; - do { - int ret = iter.get(CFG_TYPE_OF_SECTION, &type); - assert(ret == 0); - - if(type != NODE_TYPE_DB) - continue; - - Uint32 node; - ret = iter.get(CFG_NODE_ID, &node); - assert(ret == 0); - - ConfigValues::Iterator i2(_config->m_configValues->m_config, - iter.m_config); - switch(p_type){ - case 0: - res = i2.set(param, val_32); - ndbout_c("Updating node %d param: %d to %d", node, param, val_32); - break; - case 1: - res = i2.set(param, val_64); - ndbout_c("Updating node %d param: %d to %u", node, param, val_32); - break; - case 2: - res = i2.set(param, val_char); - ndbout_c("Updating node %d param: %d to %s", node, param, val_char); - break; - default: - require(false); - } - assert(res); - } while(node == 0 && iter.next() == 0); - - msg.assign("Success"); - NdbMutex_Unlock(m_configMutex); - return 0; -} -int -MgmtSrvr::setConnectionDbParameter(int node1, - int node2, - int param, - int value, - BaseString& msg){ - Uint32 current_value,new_value; - - DBUG_ENTER("MgmtSrvr::setConnectionDbParameter"); - - if(NdbMutex_Lock(m_configMutex)) - { - DBUG_RETURN(-1); - } - - ndb_mgm_configuration_iterator - iter(* _config->m_configValues, CFG_SECTION_CONNECTION); - - if(iter.first() != 0){ - msg.assign("Unable to find connection section (iter.first())"); - NdbMutex_Unlock(m_configMutex); - DBUG_RETURN(-1); - } - - for(;iter.valid();iter.next()) { - Uint32 n1,n2; - iter.get(CFG_CONNECTION_NODE_1, &n1); - iter.get(CFG_CONNECTION_NODE_2, &n2); - if((n1 == (unsigned)node1 && n2 == (unsigned)node2) - || (n1 == (unsigned)node2 && n2 == (unsigned)node1)) - break; - } - if(!iter.valid()) { - msg.assign("Unable to find connection between nodes"); - NdbMutex_Unlock(m_configMutex); - DBUG_RETURN(-2); - } - - if(iter.get(param, ¤t_value) != 0) { - msg.assign("Unable to get current value of parameter"); - NdbMutex_Unlock(m_configMutex); - DBUG_RETURN(-3); - } - - ConfigValues::Iterator i2(_config->m_configValues->m_config, - iter.m_config); - - if(i2.set(param, (unsigned)value) == false) { - msg.assign("Unable to set new value of parameter"); - NdbMutex_Unlock(m_configMutex); - DBUG_RETURN(-4); - } - - if(iter.get(param, &new_value) != 0) { - msg.assign("Unable to get parameter after setting it."); - NdbMutex_Unlock(m_configMutex); - DBUG_RETURN(-5); - } - - msg.assfmt("%u -> %u",current_value,new_value); - NdbMutex_Unlock(m_configMutex); - DBUG_RETURN(1); -} - - -int -MgmtSrvr::getConnectionDbParameter(int node1, - int node2, - int param, - int *value, - BaseString& msg){ - DBUG_ENTER("MgmtSrvr::getConnectionDbParameter"); - - if(NdbMutex_Lock(m_configMutex)) - { - DBUG_RETURN(-1); - } - - ndb_mgm_configuration_iterator - iter(* _config->m_configValues, CFG_SECTION_CONNECTION); - - if(iter.first() != 0){ - msg.assign("Unable to find connection section (iter.first())"); - NdbMutex_Unlock(m_configMutex); - DBUG_RETURN(-1); - } - - for(;iter.valid();iter.next()) { - Uint32 n1=0,n2=0; - iter.get(CFG_CONNECTION_NODE_1, &n1); - iter.get(CFG_CONNECTION_NODE_2, &n2); - if((n1 == (unsigned)node1 && n2 == (unsigned)node2) - || (n1 == (unsigned)node2 && n2 == (unsigned)node1)) - break; - } - if(!iter.valid()) { - msg.assign("Unable to find connection between nodes"); - NdbMutex_Unlock(m_configMutex); - DBUG_RETURN(-1); - } - - if(iter.get(param, (Uint32*)value) != 0) { - msg.assign("Unable to get current value of parameter"); - NdbMutex_Unlock(m_configMutex); - DBUG_RETURN(-1); - } - - msg.assfmt("%d",*value); - NdbMutex_Unlock(m_configMutex); - DBUG_RETURN(1); -} - -void MgmtSrvr::transporter_connect(NDB_SOCKET_TYPE sockfd) -{ - if (theFacade->get_registry()->connect_server(sockfd)) - { - /** - * Force an update_connections() so that the - * ClusterMgr and TransporterFacade is up to date - * with the new connection. - * Important for correct node id reservation handling - */ - NdbMutex_Lock(theFacade->theMutexPtr); - theFacade->get_registry()->update_connections(); - NdbMutex_Unlock(theFacade->theMutexPtr); - } -} - -int MgmtSrvr::connect_to_self(void) -{ - int r= 0; - m_local_mgm_handle= ndb_mgm_create_handle(); - snprintf(m_local_mgm_connect_string,sizeof(m_local_mgm_connect_string), - "localhost:%u",getPort()); - ndb_mgm_set_connectstring(m_local_mgm_handle, m_local_mgm_connect_string); - - if((r= ndb_mgm_connect(m_local_mgm_handle, 0, 0, 0)) < 0) - { - ndb_mgm_destroy_handle(&m_local_mgm_handle); - return r; - } - // TransporterRegistry now owns this NdbMgmHandle and will destroy it. - theFacade->get_registry()->set_mgm_handle(m_local_mgm_handle); - - return 0; -} - -template class MutexVector<unsigned short>; -template class MutexVector<Ndb_mgmd_event_service::Event_listener>; -template class Vector<EventSubscribeReq>; -template class MutexVector<EventSubscribeReq>; diff --git a/storage/ndb/src/mgmsrv/MgmtSrvr.hpp b/storage/ndb/src/mgmsrv/MgmtSrvr.hpp deleted file mode 100644 index 255a3e962ea..00000000000 --- a/storage/ndb/src/mgmsrv/MgmtSrvr.hpp +++ /dev/null @@ -1,648 +0,0 @@ -/* Copyright (c) 2003-2007 MySQL AB - Use is subject to license terms - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ - -#ifndef MgmtSrvr_H -#define MgmtSrvr_H - -#include <kernel_types.h> -#include "Config.hpp" -#include <NdbCondition.h> -#include <mgmapi.h> - -#include <NdbTCP.h> -#include <ConfigRetriever.hpp> -#include <Vector.hpp> -#include <NodeBitmask.hpp> -#include <signaldata/ManagementServer.hpp> -#include <ndb_version.h> -#include <EventLogger.hpp> -#include <signaldata/EventSubscribeReq.hpp> - -#include <SignalSender.hpp> - -/** - * @desc Block number for Management server. - * @todo This should probably be somewhere else. I don't know where atm. - */ -#define MGMSRV 1 - -#define MGM_ERROR_MAX_INJECT_SESSION_ONLY 10000 - -extern int g_errorInsert; - -class ConfigInfoServer; -class NdbApiSignal; -class Config; -class SetLogLevelOrd; -class SocketServer; - -class Ndb_mgmd_event_service : public EventLoggerBase -{ - friend class MgmtSrvr; -public: - struct Event_listener : public EventLoggerBase { - Event_listener() {} - NDB_SOCKET_TYPE m_socket; - Uint32 m_parsable; - }; - -private: - class MgmtSrvr * m_mgmsrv; - MutexVector<Event_listener> m_clients; -public: - Ndb_mgmd_event_service(class MgmtSrvr * m) : m_clients(5) { - m_mgmsrv = m; - } - - void add_listener(const Event_listener&); - void check_listeners(); - void update_max_log_level(const LogLevel&); - void update_log_level(const LogLevel&); - - void log(int eventType, const Uint32* theData, NodeId nodeId); - - void stop_sessions(); - - Event_listener& operator[](unsigned i) { return m_clients[i]; } - const Event_listener& operator[](unsigned i) const { return m_clients[i]; } - void lock() { m_clients.lock(); } - void unlock(){ m_clients.unlock(); } -}; - -/** - * @class MgmtSrvr - * @brief Main class for the management server. - * - * It has one interface to be used by a local client. - * With the methods it's possible to send different kind of commands to - * DB processes, as log level, set trace number etc. - * - * A MgmtSrvr creates a ConfigInfoServer which serves request on TCP sockets. - * The requests come typical from DB and API processes which want - * to fetch its configuration parameters. The MgmtSrvr knows about the - * configuration by reading a configuration file. - * - * The MgmtSrvr class corresponds in some ways to the Ndb class in API. - * It creates a TransporterFacade, receives signals and defines signals - * to send and receive. - */ -class MgmtSrvr { - -public: - // some compilers need all of this - class Allocated_resources; - friend class Allocated_resources; - class Allocated_resources { - public: - Allocated_resources(class MgmtSrvr &m); - ~Allocated_resources(); - // methods to reserve/allocate resources which - // will be freed when running destructor - void reserve_node(NodeId id, NDB_TICKS timeout); - bool is_timed_out(NDB_TICKS tick); - bool is_reserved(NodeId nodeId) { return m_reserved_nodes.get(nodeId); } - bool is_reserved(NodeBitmask mask) { return !mask.bitAND(m_reserved_nodes).isclear(); } - bool isclear() { return m_reserved_nodes.isclear(); } - NodeId get_nodeid() const; - private: - MgmtSrvr &m_mgmsrv; - NodeBitmask m_reserved_nodes; - NDB_TICKS m_alloc_timeout; - }; - NdbMutex *m_node_id_mutex; - - /** - * Start/initate the event log. - */ - void startEventLog(); - - /** - * Stop the event log. - */ - void stopEventLog(); - - /** - * Enable/disable eventlog log levels/severities. - * - * @param serverity the log level/serverity. - * @return true if the severity was enabled. - */ - bool setEventLogFilter(int severity, int enable); - - /** - * Returns true if the log level/severity is enabled. - * - * @param severity the severity level. - */ - bool isEventLogFilterEnabled(int severity); - - /** - * This enum specifies the different signal loggig modes possible to set - * with the setSignalLoggingMode method. - */ - enum LogMode {In, Out, InOut, Off}; - - /* Constructor */ - - MgmtSrvr(SocketServer *socket_server, - const char *config_filename, /* Where to save config */ - const char *connect_string); - int init(); - NodeId getOwnNodeId() const {return _ownNodeId;}; - - /** - * Read (initial) config file, create TransporterFacade, - * define signals, create ConfigInfoServer. - * @return true if succeeded, otherwise false - */ - bool check_start(); // may be run before start to check that some things are ok - bool start(BaseString &error_string); - - ~MgmtSrvr(); - - /** - * Get status on a node. - * address may point to a common area (e.g. from inet_addr) - * There is no gaurentee that it is preserved across calls. - * Copy the string if you are not going to use it immediately. - */ - int status(int nodeId, - ndb_mgm_node_status * status, - Uint32 * version, - Uint32 * phase, - bool * systemShutdown, - Uint32 * dynamicId, - Uint32 * nodeGroup, - Uint32 * connectCount, - const char **address); - - // All the functions below may return any of this error codes: - // NO_CONTACT_WITH_PROCESS, PROCESS_NOT_CONFIGURED, WRONG_PROCESS_TYPE, - // COULD_NOT_ALLOCATE_MEMORY, SEND_OR_RECEIVE_FAILED - - /** - * Save a configuration to permanent storage - */ - int saveConfig(const Config *); - - /** - * Save the running configuration - */ - int saveConfig() { - return saveConfig(_config); - }; - - /** - * Read configuration from file, or from another MGM server - */ - Config *readConfig(); - - /** - * Fetch configuration from another MGM server - */ - Config *fetchConfig(); - - /** - * Stop a node - * - * @param processId: Id of the DB process to stop - * @return 0 if succeeded, otherwise: as stated above, plus: - */ - int stopNodes(const Vector<NodeId> &node_ids, int *stopCount, bool abort, - int *stopSelf); - - int shutdownMGM(int *stopCount, bool abort, int *stopSelf); - - /** - * shutdown the DB nodes - */ - int shutdownDB(int * cnt = 0, bool abort = false); - - /** - * print version info about a node - * - * @param processId: Id of the DB process to stop - * @return 0 if succeeded, otherwise: as stated above, plus: - */ - int versionNode(int nodeId, Uint32 &version, const char **address); - - /** - * Maintenance on the system - */ - int enterSingleUser(int * cnt = 0, Uint32 singleuserNodeId = 0); - - - /** - * Resume from maintenance on the system - */ - int exitSingleUser(int * cnt = 0, bool abort = false); - - /** - * Start DB process. - * @param processId: Id of the DB process to start - * @return 0 if succeeded, otherwise: as stated above, plus: - */ - int start(int processId); - - /** - * Restart nodes - * @param processId: Id of the DB process to start - */ - int restartNodes(const Vector<NodeId> &node_ids, - int *stopCount, bool nostart, - bool initialStart, bool abort, int *stopSelf); - - /** - * Restart all DB nodes - */ - int restartDB(bool nostart, bool initialStart, - bool abort = false, - int * stopCount = 0); - - struct BackupEvent { - enum Event { - BackupStarted = 1, - BackupFailedToStart = 2, - BackupCompleted = 3, - BackupAborted = 4 - } Event; - - NdbNodeBitmask Nodes; - union { - struct { - Uint32 BackupId; - } Started ; - struct { - Uint32 ErrorCode; - } FailedToStart ; - struct { - Uint64 NoOfBytes; - Uint64 NoOfRecords; - Uint32 BackupId; - Uint32 NoOfLogBytes; - Uint32 NoOfLogRecords; - Uint32 startGCP; - Uint32 stopGCP; - } Completed ; - struct { - Uint32 BackupId; - Uint32 Reason; - Uint32 ErrorCode; - } Aborted ; - }; - }; - - /** - * Backup functionallity - */ - int startBackup(Uint32& backupId, int waitCompleted= 2); - int abortBackup(Uint32 backupId); - int performBackup(Uint32* backupId); - - //************************************************************************** - // Description: Set event report level for a DB process - // Parameters: - // processId: Id of the DB process - // level: Event report level - // isResend: Flag to indicate for resending log levels during node restart - // Returns: 0 if succeeded, otherwise: as stated above, plus: - // INVALID_LEVEL - //************************************************************************** - - int setEventReportingLevelImpl(int processId, const EventSubscribeReq& ll); - int setNodeLogLevelImpl(int processId, const SetLogLevelOrd & ll); - - /** - * Insert an error in a DB process. - * @param processId: Id of the DB process - * @param errorNo: The error number. > 0. - * @return 0 if succeeded, otherwise: as stated above, plus: - * INVALID_ERROR_NUMBER - */ - int insertError(int processId, int errorNo); - - - - int setTraceNo(int processId, int traceNo); - //************************************************************************** - // Description: Set trace number in a DB process. - // Parameters: - // processId: Id of the DB process - // trace: Trace number - // Returns: 0 if succeeded, otherwise: as stated above, plus: - // INVALID_TRACE_NUMBER - //************************************************************************** - - - int setSignalLoggingMode(int processId, LogMode mode, - const Vector<BaseString> &blocks); - - int setSignalLoggingMode(int processId, LogMode mode, - BaseString &block) { - Vector<BaseString> v; - v.push_back(block); - return setSignalLoggingMode(processId, mode, v); - } - //************************************************************************** - // Description: Set signal logging mode for blocks in a DB process. - // Parameters: - // processId: Id of the DB process - // mode: The log mode - // blocks: Which blocks to be affected (container of strings) - // Returns: 0 if succeeded, otherwise: as stated above, plus: - // INVALID_BLOCK_NAME - //************************************************************************** - - - int startSignalTracing(int processId); - //************************************************************************** - // Description: Start signal tracing for a DB process. - // Parameters: - // processId: Id of the DB process - // Returns: 0 if succeeded, otherwise: as stated above. - //************************************************************************** - - - int stopSignalTracing(int processId); - //************************************************************************** - // Description: Stop signal tracing for a DB process. - // Parameters: - // processId: Id of the DB process - // Returns: 0 if succeeded, otherwise: as stated above. - //************************************************************************** - - /** - * Dump State - */ - int dumpState(int processId, const Uint32 args[], Uint32 argNo); - int dumpState(int processId, const char* args); - - /** - * Get next node id (node id gt that _nodeId) - * of specified type and save it in _nodeId - * - * @return false if none found - */ - bool getNextNodeId(NodeId * _nodeId, enum ndb_mgm_node_type type) const ; - bool alloc_node_id(NodeId * _nodeId, enum ndb_mgm_node_type type, - struct sockaddr *client_addr, - SOCKET_SIZE_TYPE *client_addr_len, - int &error_code, BaseString &error_string, - int log_event = 1); - - /** - * - */ - enum ndb_mgm_node_type getNodeType(NodeId) const; - - /** - * Get error text - * - * @param errorCode: Error code to get a match error text for. - * @return The error text. - */ - const char* getErrorText(int errorCode, char *buf, int buf_sz); - - /** - * Get configuration - */ - const Config * getConfig() const; - - /** - * Returns the node count for the specified node type. - * - * @param type The node type. - * @return The number of nodes of the specified type. - */ - int getNodeCount(enum ndb_mgm_node_type type) const; - - /** - * Returns the port number. - * @return port number. - */ - int getPort() const; - - int setDbParameter(int node, int parameter, const char * value, BaseString&); - int setConnectionDbParameter(int node1, int node2, int param, int value, - BaseString& msg); - int getConnectionDbParameter(int node1, int node2, int param, - int *value, BaseString& msg); - - int connect_to_self(void); - - void transporter_connect(NDB_SOCKET_TYPE sockfd); - - ConfigRetriever *get_config_retriever() { return m_config_retriever; }; - - const char *get_connect_address(Uint32 node_id); - void get_connected_nodes(NodeBitmask &connected_nodes) const; - SocketServer *get_socket_server() { return m_socket_server; } - - void updateStatus(); - - //************************************************************************** -private: - //************************************************************************** - - int sendStopMgmd(NodeId nodeId, - bool abort, - bool stop, - bool restart, - bool nostart, - bool initialStart); - - int sendSTOP_REQ(const Vector<NodeId> &node_ids, - NodeBitmask &stoppedNodes, - Uint32 singleUserNodeId, - bool abort, - bool stop, - bool restart, - bool nostart, - bool initialStart, - int *stopSelf); - - /** - * Check if it is possible to send a signal to a (DB) process - * - * @param processId: Id of the process to send to - * @return 0 OK, 1 process dead, 2 API or MGMT process, 3 not configured - */ - int okToSendTo(NodeId nodeId, bool unCond = false); - - /** - * Get block number for a block - * - * @param blockName: Block to get number for - * @return -1 if block not found, otherwise block number - */ - int getBlockNumber(const BaseString &blockName); - - int alloc_node_id_req(NodeId free_node_id, enum ndb_mgm_node_type type); - //************************************************************************** - - int _blockNumber; - NodeId _ownNodeId; - SocketServer *m_socket_server; - - BlockReference _ownReference; - NdbMutex *m_configMutex; - const Config * _config; - Config * m_newConfig; - BaseString m_configFilename; - Uint32 m_nextConfigGenerationNumber; - - NodeBitmask m_reserved_nodes; - struct in_addr m_connect_address[MAX_NODES]; - - //************************************************************************** - // Specific signal handling methods - //************************************************************************** - - static void defineSignals(int blockNumber); - //************************************************************************** - // Description: Define all signals to be sent or received for a block - // Parameters: - // blockNumber: The block number send/receive - // Returns: - - //************************************************************************** - - void handleReceivedSignal(NdbApiSignal* signal); - //************************************************************************** - // Description: This method is called from "another" thread when a signal - // is received. If expect the received signal and succeed to handle it - // we signal with a condition variable to the waiting - // thread (receiveOptimisedResponse) that the signal has arrived. - // Parameters: - // signal: The recieved signal - // Returns: - - //************************************************************************** - - void handleStatus(NodeId nodeId, bool alive, bool nfComplete); - //************************************************************************** - // Description: Handle the death of a process - // Parameters: - // processId: Id of the dead process. - // Returns: - - //************************************************************************** - - //************************************************************************** - // Specific signal handling data - //************************************************************************** - - - //************************************************************************** - //************************************************************************** - // General signal handling methods - // This functions are more or less copied from the Ndb class. - - - /** - * WaitSignalType defines states where each state define a set of signals - * we accept to receive. - * The state is set after we have sent a signal. - * When a signal arrives we first check current state (handleReceivedSignal) - * to verify that we expect the arrived signal. - * It's only then we are in state accepting the arrived signal - * we handle the signal. - */ - enum WaitSignalType { - NO_WAIT, // We don't expect to receive any signal - WAIT_SUBSCRIBE_CONF // Accept event subscription confirmation - }; - - /** - * This function is called from "outside" of MgmtSrvr - * when a signal is sent to MgmtSrvr. - * @param mgmtSrvr: The MgmtSrvr object which shall recieve the signal. - * @param signal: The received signal. - */ - static void signalReceivedNotification(void* mgmtSrvr, - NdbApiSignal* signal, - struct LinearSectionPtr ptr[3]); - - /** - * Called from "outside" of MgmtSrvr when a DB process has died. - * @param mgmtSrvr: The MgmtSrvr object wreceiveOptimisedResponsehich - * shall receive the notification. - * @param processId: Id of the dead process. - */ - static void nodeStatusNotification(void* mgmSrv, Uint32 nodeId, - bool alive, bool nfCompleted); - - /** - * An event from <i>nodeId</i> has arrived - */ - void eventReport(const Uint32 * theData); - - - //************************************************************************** - //************************************************************************** - // General signal handling data - - STATIC_CONST( WAIT_FOR_RESPONSE_TIMEOUT = 300000 ); // Milliseconds - // Max time to wait for a signal to arrive - - NdbApiSignal* theSignalIdleList; - // List of unused signals - - Uint32 theWaitNode; - WaitSignalType theWaitState; - // State denoting a set of signals we accept to recieve. - - NdbCondition* theMgmtWaitForResponseCondPtr; - // Condition variable used when we wait for a signal to arrive/a - // signal arrives. - // We wait in receiveOptimisedResponse and signal in handleReceivedSignal. - - NdbMgmHandle m_local_mgm_handle; - char m_local_mgm_connect_string[20]; - class TransporterFacade * theFacade; - - int sendVersionReq( int processId, Uint32 &version, const char **address); - int translateStopRef(Uint32 errCode); - - bool _isStopThread; - int _logLevelThreadSleep; - MutexVector<NodeId> m_started_nodes; - MutexVector<EventSubscribeReq> m_log_level_requests; - LogLevel m_nodeLogLevel[MAX_NODES]; - enum ndb_mgm_node_type nodeTypes[MAX_NODES]; - friend class MgmApiSession; - friend class Ndb_mgmd_event_service; - Ndb_mgmd_event_service m_event_listner; - - NodeId m_master_node; - - /** - * Handles the thread wich upon a 'Node is started' event will - * set the node's previous loglevel settings. - */ - struct NdbThread* _logLevelThread; - static void *logLevelThread_C(void *); - void logLevelThreadRun(); - - Config *_props; - - ConfigRetriever *m_config_retriever; -}; - -inline -const Config * -MgmtSrvr::getConfig() const { - return _config; -} - -#endif // MgmtSrvr_H diff --git a/storage/ndb/src/mgmsrv/MgmtSrvrConfig.cpp b/storage/ndb/src/mgmsrv/MgmtSrvrConfig.cpp deleted file mode 100644 index eee317d780b..00000000000 --- a/storage/ndb/src/mgmsrv/MgmtSrvrConfig.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright (c) 2003-2005 MySQL AB - Use is subject to license terms - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ - -#include <signaldata/TestOrd.hpp> -#include <OutputStream.hpp> - -#include "MgmtSrvr.hpp" -#include "SignalQueue.hpp" -#include <InitConfigFileParser.hpp> -#include <ConfigRetriever.hpp> -#include <ndb_version.h> - -/** - * Save a configuration to the running configuration file - */ -int -MgmtSrvr::saveConfig(const Config *conf) { - BaseString newfile; - newfile.appfmt("%s.new", m_configFilename.c_str()); - - /* Open and write to the new config file */ - FILE *f = fopen(newfile.c_str(), "w"); - if(f == NULL) { - /** @todo Send something apropriate to the log */ - return -1; - } - FileOutputStream stream(f); - conf->printConfigFile(stream); - - fclose(f); - - /* Rename file to real name */ - rename(newfile.c_str(), m_configFilename.c_str()); - - return 0; -} - -Config * -MgmtSrvr::readConfig() { - Config *conf; - InitConfigFileParser parser; - if (m_configFilename.length()) - { - conf = parser.parseConfig(m_configFilename.c_str()); - } - else - { - ndbout_c("Reading cluster configuration using my.cnf"); - conf = parser.parse_mycnf(); - } - return conf; -} - -Config * -MgmtSrvr::fetchConfig() { - struct ndb_mgm_configuration * tmp = m_config_retriever->getConfig(); - if(tmp != 0){ - Config * conf = new Config(); - conf->m_configValues = tmp; - return conf; - } - return 0; -} diff --git a/storage/ndb/src/mgmsrv/MgmtSrvrGeneralSignalHandling.cpp b/storage/ndb/src/mgmsrv/MgmtSrvrGeneralSignalHandling.cpp deleted file mode 100644 index e80d5b3dcab..00000000000 --- a/storage/ndb/src/mgmsrv/MgmtSrvrGeneralSignalHandling.cpp +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright (c) 2003, 2005 MySQL AB - Use is subject to license terms - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ - -//****************************************************************************** -// General signal handling methods -// All implementations stolen from the Ndb class. -// Some kind of reuse should be preferred. -//****************************************************************************** - diff --git a/storage/ndb/src/mgmsrv/Services.cpp b/storage/ndb/src/mgmsrv/Services.cpp deleted file mode 100644 index 3b8e08cf4dd..00000000000 --- a/storage/ndb/src/mgmsrv/Services.cpp +++ /dev/null @@ -1,1818 +0,0 @@ -/* Copyright (c) 2003-2007 MySQL AB - Use is subject to license terms - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ - -#include <ndb_global.h> -#include <ctype.h> - -#include <uucode.h> -#include <socket_io.h> -#include <util/version.h> -#include <mgmapi.h> -#include <EventLogger.hpp> -#include <signaldata/SetLogLevelOrd.hpp> -#include <LogLevel.hpp> -#include <BaseString.hpp> - -#include <ConfigValues.hpp> -#include <mgmapi_configuration.hpp> -#include <Vector.hpp> -#include "Services.hpp" -#include "../mgmapi/ndb_logevent.hpp" - -#include <base64.h> -#include <ndberror.h> - -extern bool g_StopServer; -extern bool g_RestartServer; -extern EventLogger g_eventLogger; - -static const unsigned int MAX_READ_TIMEOUT = 1000 ; -static const unsigned int MAX_WRITE_TIMEOUT = 100 ; - -/** - const char * name; - const char * realName; - const Type type; - const ArgType argType; - const ArgRequired argRequired; - const ArgMinMax argMinMax; - const int minVal; - const int maxVal; - void (T::* function)(const class Properties & args); - const char * description; -*/ - -#define MGM_CMD(name, fun, desc) \ - { name, \ - 0, \ - ParserRow<MgmApiSession>::Cmd, \ - ParserRow<MgmApiSession>::String, \ - ParserRow<MgmApiSession>::Optional, \ - ParserRow<MgmApiSession>::IgnoreMinMax, \ - 0, 0, \ - fun, \ - desc, 0 } - -#define MGM_ARG(name, type, opt, desc) \ - { name, \ - 0, \ - ParserRow<MgmApiSession>::Arg, \ - ParserRow<MgmApiSession>::type, \ - ParserRow<MgmApiSession>::opt, \ - ParserRow<MgmApiSession>::IgnoreMinMax, \ - 0, 0, \ - 0, \ - desc, 0 } - -#define MGM_ARG2(name, type, opt, min, max, desc) \ - { name, \ - 0, \ - ParserRow<MgmApiSession>::Arg, \ - ParserRow<MgmApiSession>::type, \ - ParserRow<MgmApiSession>::opt, \ - ParserRow<MgmApiSession>::IgnoreMinMax, \ - min, max, \ - 0, \ - desc, 0 } - -#define MGM_END() \ - { 0, \ - 0, \ - ParserRow<MgmApiSession>::Arg, \ - ParserRow<MgmApiSession>::Int, \ - ParserRow<MgmApiSession>::Optional, \ - ParserRow<MgmApiSession>::IgnoreMinMax, \ - 0, 0, \ - 0, \ - 0, 0 } - -#define MGM_CMD_ALIAS(name, realName, fun) \ - { name, \ - realName, \ - ParserRow<MgmApiSession>::CmdAlias, \ - ParserRow<MgmApiSession>::Int, \ - ParserRow<MgmApiSession>::Optional, \ - ParserRow<MgmApiSession>::IgnoreMinMax, \ - 0, 0, \ - 0, \ - 0, 0 } - -#define MGM_ARG_ALIAS(name, realName, fun) \ - { name, \ - realName, \ - ParserRow<MgmApiSession>::ArgAlias, \ - ParserRow<MgmApiSession>::Int, \ - ParserRow<MgmApiSession>::Optional, \ - ParserRow<MgmApiSession>::IgnoreMinMax, \ - 0, 0, \ - 0, \ - 0, 0 } - -const -ParserRow<MgmApiSession> commands[] = { - MGM_CMD("get config", &MgmApiSession::getConfig, ""), - MGM_ARG("version", Int, Mandatory, "Configuration version number"), - MGM_ARG("node", Int, Optional, "Node ID"), - - MGM_CMD("get nodeid", &MgmApiSession::get_nodeid, ""), - MGM_ARG("version", Int, Mandatory, "Configuration version number"), - MGM_ARG("nodetype", Int, Mandatory, "Node type"), - MGM_ARG("transporter", String, Optional, "Transporter type"), - MGM_ARG("nodeid", Int, Optional, "Node ID"), - MGM_ARG("user", String, Mandatory, "Password"), - MGM_ARG("password", String, Mandatory, "Password"), - MGM_ARG("public key", String, Mandatory, "Public key"), - MGM_ARG("endian", String, Optional, "Endianness"), - MGM_ARG("name", String, Optional, "Name of connection"), - MGM_ARG("timeout", Int, Optional, "Timeout in seconds"), - MGM_ARG("log_event", Int, Optional, "Log failure in cluster log"), - - MGM_CMD("get version", &MgmApiSession::getVersion, ""), - - MGM_CMD("get status", &MgmApiSession::getStatus, ""), - - MGM_CMD("get info clusterlog", &MgmApiSession::getInfoClusterLog, ""), - MGM_CMD("get cluster loglevel", &MgmApiSession::getClusterLogLevel, ""), - - MGM_CMD("restart node", &MgmApiSession::restart_v1, ""), - MGM_ARG("node", String, Mandatory, "Nodes to restart"), - MGM_ARG("initialstart", Int, Optional, "Initial start"), - MGM_ARG("nostart", Int, Optional, "No start"), - MGM_ARG("abort", Int, Optional, "Abort"), - - MGM_CMD("restart node v2", &MgmApiSession::restart_v2, ""), - MGM_ARG("node", String, Mandatory, "Nodes to restart"), - MGM_ARG("initialstart", Int, Optional, "Initial start"), - MGM_ARG("nostart", Int, Optional, "No start"), - MGM_ARG("abort", Int, Optional, "Abort"), - - MGM_CMD("restart all", &MgmApiSession::restartAll, ""), - MGM_ARG("initialstart", Int, Optional, "Initial start"), - MGM_ARG("nostart", Int, Optional, "No start"), - MGM_ARG("abort", Int, Optional, "Abort"), - - MGM_CMD("insert error", &MgmApiSession::insertError, ""), - MGM_ARG("node", Int, Mandatory, "Node to receive error"), - MGM_ARG("error", Int, Mandatory, "Errorcode to insert"), - - MGM_CMD("set trace", &MgmApiSession::setTrace, ""), - MGM_ARG("node", Int, Mandatory, "Node"), - MGM_ARG("trace", Int, Mandatory, "Trace number"), - - MGM_CMD("log signals", &MgmApiSession::logSignals, ""), - MGM_ARG("node", Int, Mandatory, "Node"), - MGM_ARG("blocks", String, Mandatory, "Blocks (space separated)"), - MGM_ARG("in", Int, Mandatory, "Log input signals"), - MGM_ARG("out", Int, Mandatory, "Log output signals"), - - MGM_CMD("start signallog", &MgmApiSession::startSignalLog, ""), - MGM_ARG("node", Int, Mandatory, "Node"), - - MGM_CMD("stop signallog", &MgmApiSession::stopSignalLog, ""), - MGM_ARG("node", Int, Mandatory, "Node"), - - MGM_CMD("dump state", &MgmApiSession::dumpState, ""), - MGM_ARG("node", Int, Mandatory ,"Node"), - MGM_ARG("args", String, Mandatory, "Args(space separated int's)"), - - MGM_CMD("start backup", &MgmApiSession::startBackup, ""), - MGM_ARG("completed", Int, Optional ,"Wait until completed"), - - MGM_CMD("abort backup", &MgmApiSession::abortBackup, ""), - MGM_ARG("id", Int, Mandatory, "Backup id"), - - MGM_CMD("stop", &MgmApiSession::stop_v1, ""), - MGM_ARG("node", String, Mandatory, "Node"), - MGM_ARG("abort", Int, Mandatory, "Node"), - - MGM_CMD("stop v2", &MgmApiSession::stop_v2, ""), - MGM_ARG("node", String, Mandatory, "Node"), - MGM_ARG("abort", Int, Mandatory, "Node"), - - MGM_CMD("stop all", &MgmApiSession::stopAll, ""), - MGM_ARG("abort", Int, Mandatory, "Node"), - MGM_ARG("stop", String, Optional, "MGM/DB or both"), - - MGM_CMD("enter single user", &MgmApiSession::enterSingleUser, ""), - MGM_ARG("nodeId", Int, Mandatory, "Node"), - - MGM_CMD("exit single user", &MgmApiSession::exitSingleUser, ""), - - - MGM_CMD("start", &MgmApiSession::start, ""), - MGM_ARG("node", Int, Mandatory, "Node"), - - MGM_CMD("start all", &MgmApiSession::startAll, ""), - - MGM_CMD("bye", &MgmApiSession::bye, ""), - - MGM_CMD("end session", &MgmApiSession::endSession, ""), - - MGM_CMD("set loglevel", &MgmApiSession::setLogLevel, ""), - MGM_ARG("node", Int, Mandatory, "Node"), - MGM_ARG("category", Int, Mandatory, "Event category"), - MGM_ARG("level", Int, Mandatory, "Log level (0-15)"), - - MGM_CMD("set cluster loglevel", &MgmApiSession::setClusterLogLevel, ""), - MGM_ARG("node", Int, Mandatory, "Node"), - MGM_ARG("category", Int, Mandatory, "Event category"), - MGM_ARG("level", Int, Mandatory, "Log level (0-15)"), - - MGM_CMD("set logfilter", &MgmApiSession::setLogFilter, ""), - MGM_ARG("level", Int, Mandatory, "Severety level"), - MGM_ARG("enable", Int, Mandatory, "1=disable, 0=enable, -1=toggle"), - - MGM_CMD("set parameter", &MgmApiSession::setParameter, ""), - MGM_ARG("node", String, Mandatory, "Node"), - MGM_ARG("parameter", String, Mandatory, "Parameter"), - MGM_ARG("value", String, Mandatory, "Value"), - - MGM_CMD("set connection parameter", - &MgmApiSession::setConnectionParameter, ""), - MGM_ARG("node1", String, Mandatory, "Node1 ID"), - MGM_ARG("node2", String, Mandatory, "Node2 ID"), - MGM_ARG("param", String, Mandatory, "Parameter"), - MGM_ARG("value", String, Mandatory, "Value"), - - MGM_CMD("get connection parameter", - &MgmApiSession::getConnectionParameter, ""), - MGM_ARG("node1", String, Mandatory, "Node1 ID"), - MGM_ARG("node2", String, Mandatory, "Node2 ID"), - MGM_ARG("param", String, Mandatory, "Parameter"), - - MGM_CMD("listen event", &MgmApiSession::listen_event, ""), - MGM_ARG("node", Int, Optional, "Node"), - MGM_ARG("parsable", Int, Optional, "Parsable"), - MGM_ARG("filter", String, Mandatory, "Event category"), - - MGM_CMD("purge stale sessions", &MgmApiSession::purge_stale_sessions, ""), - - MGM_CMD("check connection", &MgmApiSession::check_connection, ""), - - MGM_CMD("transporter connect", &MgmApiSession::transporter_connect, ""), - - MGM_CMD("get mgmd nodeid", &MgmApiSession::get_mgmd_nodeid, ""), - - MGM_CMD("report event", &MgmApiSession::report_event, ""), - MGM_ARG("length", Int, Mandatory, "Length"), - MGM_ARG("data", String, Mandatory, "Data"), - - MGM_CMD("list sessions", &MgmApiSession::listSessions, ""), - - MGM_CMD("get session id", &MgmApiSession::getSessionId, ""), - - MGM_CMD("get session", &MgmApiSession::getSession, ""), - MGM_ARG("id", Int, Mandatory, "SessionID"), - - MGM_END() -}; - -struct PurgeStruct -{ - NodeBitmask free_nodes;/* free nodes as reported - * by ndbd in apiRegReqConf - */ - BaseString *str; - NDB_TICKS tick; -}; - -#define ERROR_INSERTED(x) (g_errorInsert == x || m_errorInsert == x) - -#define SLEEP_ERROR_INSERTED(x) if(ERROR_INSERTED(x)){NdbSleep_SecSleep(10);} - -MgmApiSession::MgmApiSession(class MgmtSrvr & mgm, NDB_SOCKET_TYPE sock, Uint64 session_id) - : SocketServer::Session(sock), m_mgmsrv(mgm) -{ - DBUG_ENTER("MgmApiSession::MgmApiSession"); - m_input = new SocketInputStream(sock, 30000); - m_output = new SocketOutputStream(sock, 30000); - m_parser = new Parser_t(commands, *m_input, true, true, true); - m_allocated_resources= new MgmtSrvr::Allocated_resources(m_mgmsrv); - m_stopSelf= 0; - m_ctx= NULL; - m_session_id= session_id; - m_mutex= NdbMutex_Create(); - m_errorInsert= 0; - DBUG_VOID_RETURN; -} - -MgmApiSession::~MgmApiSession() -{ - DBUG_ENTER("MgmApiSession::~MgmApiSession"); - if (m_input) - delete m_input; - if (m_output) - delete m_output; - if (m_parser) - delete m_parser; - if (m_allocated_resources) - delete m_allocated_resources; - if(m_socket != NDB_INVALID_SOCKET) - { - NDB_CLOSE_SOCKET(m_socket); - m_socket= NDB_INVALID_SOCKET; - } - if(m_stopSelf < 0) - g_RestartServer= true; - if(m_stopSelf) - g_StopServer= true; - NdbMutex_Destroy(m_mutex); - DBUG_VOID_RETURN; -} - -void -MgmApiSession::runSession() -{ - DBUG_ENTER("MgmApiSession::runSession"); - - Parser_t::Context ctx; - ctx.m_mutex= m_mutex; - m_ctx= &ctx; - bool stop= false; - while(!stop) { - NdbMutex_Lock(m_mutex); - - m_input->reset_timeout(); - m_output->reset_timeout(); - - m_parser->run(ctx, *this); - - if(ctx.m_currentToken == 0) - { - NdbMutex_Unlock(m_mutex); - break; - } - - switch(ctx.m_status) { - case Parser_t::UnknownCommand: - break; - default: - break; - } - - stop= m_stop; - NdbMutex_Unlock(m_mutex); - }; - - NdbMutex_Lock(m_mutex); - m_ctx= NULL; - if(m_socket != NDB_INVALID_SOCKET) - { - NDB_CLOSE_SOCKET(m_socket); - m_socket= NDB_INVALID_SOCKET; - } - NdbMutex_Unlock(m_mutex); - DBUG_VOID_RETURN; -} - -static Properties * -backward(const char * base, const Properties* reply){ - Properties * ret = new Properties(); - Properties::Iterator it(reply); - for(const char * name = it.first(); name != 0; name=it.next()){ - PropertiesType type; - reply->getTypeOf(name, &type); - switch(type){ - case PropertiesType_Uint32:{ - Uint32 val; - reply->get(name, &val); - ret->put(name, val); - } - break; - case PropertiesType_char: - { - const char * val; - reply->get(name, &val); - ret->put(name, val); - if(!strcmp(name, "Type") && !strcmp(val, "DB")){ - ret->put("NoOfDiskBufferPages", (unsigned)0); - ret->put("NoOfDiskFiles", (unsigned)0); - ret->put("NoOfDiskClusters", (unsigned)0); - ret->put("NoOfFreeDiskClusters", (unsigned)0); - ret->put("NoOfDiskClustersPerDiskFile", (unsigned)0); - ret->put("NoOfConcurrentCheckpointsDuringRestart", (unsigned)1); - ret->put("NoOfConcurrentCheckpointsAfterRestart", (unsigned)1); - ret->put("NoOfConcurrentProcessesHandleTakeover", (unsigned)1); - } - } - break; - case PropertiesType_Properties: - { - const Properties * recurse; - reply->get(name, &recurse); - Properties * val = backward(name, recurse); - ret->put(name, val); - } - break; - case PropertiesType_Uint64: - break; - } - } - return ret; -} - -void -MgmApiSession::get_nodeid(Parser_t::Context &, - const class Properties &args) -{ - const char *cmd= "get nodeid reply"; - Uint32 version, nodeid= 0, nodetype= 0xff; - Uint32 timeout= 20; // default seconds timeout - const char * transporter; - const char * user; - const char * password; - const char * public_key; - const char * endian= NULL; - const char * name= NULL; - Uint32 log_event= 1; - bool log_event_version; - union { long l; char c[sizeof(long)]; } endian_check; - - args.get("version", &version); - args.get("nodetype", &nodetype); - args.get("transporter", &transporter); - args.get("nodeid", &nodeid); - args.get("user", &user); - args.get("password", &password); - args.get("public key", &public_key); - args.get("endian", &endian); - args.get("name", &name); - args.get("timeout", &timeout); - /* for backwards compatability keep track if client uses new protocol */ - log_event_version= args.get("log_event", &log_event); - - endian_check.l = 1; - if(endian - && strcmp(endian,(endian_check.c[sizeof(long)-1])?"big":"little")!=0) { - m_output->println(cmd); - m_output->println("result: Node does not have the same endianness as the management server."); - m_output->println(""); - return; - } - - bool compatible; - switch (nodetype) { - case NODE_TYPE_MGM: - case NODE_TYPE_API: - compatible = ndbCompatible_mgmt_api(NDB_VERSION, version); - break; - case NODE_TYPE_DB: - compatible = ndbCompatible_mgmt_ndb(NDB_VERSION, version); - break; - default: - m_output->println(cmd); - m_output->println("result: unknown nodetype %d", nodetype); - m_output->println(""); - return; - } - - struct sockaddr_in addr; - SOCKET_SIZE_TYPE addrlen= sizeof(addr); - int r = getpeername(m_socket, (struct sockaddr*)&addr, &addrlen); - if (r != 0 ) { - m_output->println(cmd); - m_output->println("result: getpeername(%d) failed, err= %d", m_socket, r); - m_output->println(""); - return; - } - - NodeId tmp= nodeid; - if(tmp == 0 || !m_allocated_resources->is_reserved(tmp)){ - BaseString error_string; - int error_code; - NDB_TICKS tick= 0; - /* only report error on second attempt as not to clog the cluster log */ - while (!m_mgmsrv.alloc_node_id(&tmp, (enum ndb_mgm_node_type)nodetype, - (struct sockaddr*)&addr, &addrlen, - error_code, error_string, - tick == 0 ? 0 : log_event)) - { - /* NDB_MGM_ALLOCID_CONFIG_MISMATCH is a non retriable error */ - if (tick == 0 && error_code != NDB_MGM_ALLOCID_CONFIG_MISMATCH) - { - // attempt to free any timed out reservations - tick= NdbTick_CurrentMillisecond(); - struct PurgeStruct ps; - m_mgmsrv.get_connected_nodes(ps.free_nodes); - // invert connected_nodes to get free nodes - ps.free_nodes.bitXORC(NodeBitmask()); - ps.str= 0; - ps.tick= tick; - m_mgmsrv.get_socket_server()-> - foreachSession(stop_session_if_timed_out,&ps); - m_mgmsrv.get_socket_server()->checkSessions(); - error_string = ""; - continue; - } - const char *alias; - const char *str; - alias= ndb_mgm_get_node_type_alias_string((enum ndb_mgm_node_type) - nodetype, &str); - m_output->println(cmd); - m_output->println("result: %s", error_string.c_str()); - /* only use error_code protocol if client knows about it */ - if (log_event_version) - m_output->println("error_code: %d", error_code); - m_output->println(""); - return; - } - } - -#if 0 - if (!compatible){ - m_output->println(cmd); - m_output->println("result: incompatible version mgmt 0x%x and node 0x%x", - NDB_VERSION, version); - m_output->println(""); - return; - } -#endif - - m_output->println(cmd); - m_output->println("nodeid: %u", tmp); - m_output->println("result: Ok"); - m_output->println(""); - m_allocated_resources->reserve_node(tmp, timeout*1000); - - if (name) - g_eventLogger.info("Node %d: %s", tmp, name); - - return; -} - -void -MgmApiSession::getConfig(Parser_t::Context &, - const class Properties &args) -{ - Uint32 version, node = 0; - - args.get("version", &version); - args.get("node", &node); - - const Config *conf = m_mgmsrv.getConfig(); - if(conf == NULL) { - m_output->println("get config reply"); - m_output->println("result: Could not fetch configuration"); - m_output->println(""); - return; - } - - if(node != 0){ - bool compatible; - switch (m_mgmsrv.getNodeType(node)) { - case NDB_MGM_NODE_TYPE_NDB: - compatible = ndbCompatible_mgmt_ndb(NDB_VERSION, version); - break; - case NDB_MGM_NODE_TYPE_API: - case NDB_MGM_NODE_TYPE_MGM: - compatible = ndbCompatible_mgmt_api(NDB_VERSION, version); - break; - default: - m_output->println("get config"); - m_output->println("result: unrecognignized node type"); - m_output->println(""); - return; - } - - if (!compatible){ - m_output->println("get config"); - m_output->println("result: incompatible version mgmt 0x%x and node 0x%x", - NDB_VERSION, version); - m_output->println(""); - return; - } - } - - NdbMutex_Lock(m_mgmsrv.m_configMutex); - const ConfigValues * cfg = &conf->m_configValues->m_config; - - UtilBuffer src; - cfg->pack(src); - NdbMutex_Unlock(m_mgmsrv.m_configMutex); - - char *tmp_str = (char *) malloc(base64_needed_encoded_length(src.length())); - (void) base64_encode(src.get_data(), src.length(), tmp_str); - - SLEEP_ERROR_INSERTED(1); - - m_output->println("get config reply"); - m_output->println("result: Ok"); - m_output->println("Content-Length: %d", strlen(tmp_str)); - m_output->println("Content-Type: ndbconfig/octet-stream"); - SLEEP_ERROR_INSERTED(2); - m_output->println("Content-Transfer-Encoding: base64"); - m_output->println(""); - if(ERROR_INSERTED(3)) - { - int l= strlen(tmp_str); - tmp_str[l/2]='\0'; - m_output->println(tmp_str); - NdbSleep_SecSleep(10); - } - m_output->println(tmp_str); - - free(tmp_str); - return; -} - -void -MgmApiSession::insertError(Parser<MgmApiSession>::Context &, - Properties const &args) { - Uint32 node = 0, error = 0; - int result= 0; - - args.get("node", &node); - args.get("error", &error); - - if(node==m_mgmsrv.getOwnNodeId() - && error < MGM_ERROR_MAX_INJECT_SESSION_ONLY) - { - m_errorInsert= error; - if(error==0) - g_errorInsert= error; - } - else - { - result= m_mgmsrv.insertError(node, error); - } - - m_output->println("insert error reply"); - if(result != 0) - m_output->println("result: %s", get_error_text(result)); - else - m_output->println("result: Ok"); - m_output->println(""); -} - -void -MgmApiSession::setTrace(Parser<MgmApiSession>::Context &, - Properties const &args) { - Uint32 node = 0, trace = 0; - - args.get("node", &node); - args.get("trace", &trace); - - int result = m_mgmsrv.setTraceNo(node, trace); - - m_output->println("set trace reply"); - if(result != 0) - m_output->println("result: %s", get_error_text(result)); - else - m_output->println("result: Ok"); - m_output->println(""); -} - -void -MgmApiSession::getVersion(Parser<MgmApiSession>::Context &, - Properties const &) { - m_output->println("version"); - m_output->println("id: %d", NDB_VERSION); - m_output->println("major: %d", getMajor(NDB_VERSION)); - m_output->println("minor: %d", getMinor(NDB_VERSION)); - m_output->println("string: %s", NDB_VERSION_STRING); - m_output->println(""); -} - -void -MgmApiSession::startBackup(Parser<MgmApiSession>::Context &, - Properties const &args) { - DBUG_ENTER("MgmApiSession::startBackup"); - unsigned backupId; - Uint32 completed= 2; - int result; - - args.get("completed", &completed); - - result = m_mgmsrv.startBackup(backupId, completed); - - m_output->println("start backup reply"); - if(result != 0) - { - m_output->println("result: %s", get_error_text(result)); - } - else{ - m_output->println("result: Ok"); - if (completed) - m_output->println("id: %d", backupId); - } - m_output->println(""); - DBUG_VOID_RETURN; -} - -void -MgmApiSession::abortBackup(Parser<MgmApiSession>::Context &, - Properties const &args) { - Uint32 id = 0; - - args.get("id", &id); - - int result = m_mgmsrv.abortBackup(id); - - m_output->println("abort backup reply"); - if(result != 0) - m_output->println("result: %s", get_error_text(result)); - else - m_output->println("result: Ok"); - m_output->println(""); -} - -/*****************************************************************************/ - -void -MgmApiSession::dumpState(Parser<MgmApiSession>::Context &, - Properties const &args) { - Uint32 node; - BaseString args_str; - - args.get("node", &node); - args.get("args", args_str); - - int result = m_mgmsrv.dumpState(node, args_str.c_str()); - m_output->println("dump state reply"); - if(result != 0) - m_output->println("result: %s", get_error_text(result)); - else - m_output->println("result: Ok"); - m_output->println(""); -} - - -void -MgmApiSession::bye(Parser<MgmApiSession>::Context &, - Properties const &) { - m_stop = true; -} - -void -MgmApiSession::endSession(Parser<MgmApiSession>::Context &, - Properties const &) { - if(m_allocated_resources) - delete m_allocated_resources; - - m_allocated_resources= new MgmtSrvr::Allocated_resources(m_mgmsrv); - - SLEEP_ERROR_INSERTED(4); - m_output->println("end session reply"); -} - -void -MgmApiSession::getClusterLogLevel(Parser<MgmApiSession>::Context & , Properties const &) { - const char* names[] = { "startup", - "shutdown", - "statistics", - "checkpoint", - "noderestart", - "connection", - "info", - "warning", - "error", - "congestion", - "debug", - "backup" }; - - int loglevel_count = (CFG_MAX_LOGLEVEL - CFG_MIN_LOGLEVEL + 1) ; - LogLevel::EventCategory category; - - m_output->println("get cluster loglevel"); - for(int i = 0; i < loglevel_count; i++) { - category = (LogLevel::EventCategory) i; - m_output->println("%s: %d", names[i], m_mgmsrv.m_event_listner[0].m_logLevel.getLogLevel(category)); - } - m_output->println(""); -} - -void -MgmApiSession::setClusterLogLevel(Parser<MgmApiSession>::Context &, - Properties const &args) { - const char *reply= "set cluster loglevel reply"; - Uint32 node, level, cat; - BaseString errorString; - DBUG_ENTER("MgmApiSession::setClusterLogLevel"); - args.get("node", &node); - args.get("category", &cat); - args.get("level", &level); - - DBUG_PRINT("enter",("node=%d, category=%d, level=%d", node, cat, level)); - - if(level > NDB_MGM_MAX_LOGLEVEL) { - m_output->println(reply); - m_output->println("result: Invalid loglevel %d", level); - m_output->println(""); - DBUG_VOID_RETURN; - } - - LogLevel::EventCategory category= - (LogLevel::EventCategory)(cat-(int)CFG_MIN_LOGLEVEL); - - m_mgmsrv.m_event_listner.lock(); - if (m_mgmsrv.m_event_listner[0].m_logLevel.setLogLevel(category,level)) - { - m_output->println(reply); - m_output->println("result: Invalid category %d", category); - m_output->println(""); - m_mgmsrv.m_event_listner.unlock(); - DBUG_VOID_RETURN; - } - m_mgmsrv.m_event_listner.unlock(); - - { - LogLevel tmp; - m_mgmsrv.m_event_listner.update_max_log_level(tmp); - } - - m_output->println(reply); - m_output->println("result: Ok"); - m_output->println(""); - DBUG_VOID_RETURN; -} - -void -MgmApiSession::setLogLevel(Parser<MgmApiSession>::Context &, - Properties const &args) { - Uint32 node = 0, level = 0, cat; - BaseString errorString; - SetLogLevelOrd logLevel; - logLevel.clear(); - args.get("node", &node); - args.get("category", &cat); - args.get("level", &level); - - if(level > NDB_MGM_MAX_LOGLEVEL) { - m_output->println("set loglevel reply"); - m_output->println("result: Invalid loglevel", errorString.c_str()); - m_output->println(""); - return; - } - - LogLevel::EventCategory category= - (LogLevel::EventCategory)(cat-(int)CFG_MIN_LOGLEVEL); - - { - LogLevel ll; - ll.setLogLevel(category,level); - m_mgmsrv.m_event_listner.update_max_log_level(ll); - } - - m_output->println("set loglevel reply"); - m_output->println("result: Ok"); - m_output->println(""); -} - -void -MgmApiSession::stopSignalLog(Parser<MgmApiSession>::Context &, - Properties const &args) { - Uint32 node; - - args.get("node", &node); - - int result = m_mgmsrv.stopSignalTracing(node); - - m_output->println("stop signallog"); - if(result != 0) - m_output->println("result: %s", get_error_text(result)); - else - m_output->println("result: Ok"); - m_output->println(""); -} - -void -MgmApiSession::restart_v1(Parser<MgmApiSession>::Context &, - Properties const &args) { - restart(args,1); -} - -void -MgmApiSession::restart_v2(Parser<MgmApiSession>::Context &, - Properties const &args) { - restart(args,2); -} - -void -MgmApiSession::restart(Properties const &args, int version) { - Uint32 - nostart = 0, - initialstart = 0, - abort = 0; - char *nodes_str; - Vector<NodeId> nodes; - - args.get("initialstart", &initialstart); - args.get("nostart", &nostart); - args.get("abort", &abort); - args.get("node", (const char **)&nodes_str); - - char *p, *last; - for((p = strtok_r(nodes_str, " ", &last)); - p; - (p = strtok_r(NULL, " ", &last))) { - nodes.push_back(atoi(p)); - } - - int restarted = 0; - int result= m_mgmsrv.restartNodes(nodes, - &restarted, - nostart != 0, - initialstart != 0, - abort != 0, - &m_stopSelf); - - m_output->println("restart reply"); - if(result != 0){ - m_output->println("result: %d-%s", result, get_error_text(result)); - } else - m_output->println("result: Ok"); - m_output->println("restarted: %d", restarted); - if(version>1) - m_output->println("disconnect: %d", (m_stopSelf)?1:0); - m_output->println(""); -} - -void -MgmApiSession::restartAll(Parser<MgmApiSession>::Context &, - Properties const &args) -{ - Uint32 nostart = 0; - Uint32 initialstart = 0; - Uint32 abort = 0; - - args.get("initialstart", &initialstart); - args.get("abort", &abort); - args.get("nostart", &nostart); - - int count = 0; - int result = m_mgmsrv.restartDB(nostart, initialstart, abort, &count); - - m_output->println("restart reply"); - if(result != 0) - m_output->println("result: %s", get_error_text(result)); - else - m_output->println("result: Ok"); - m_output->println("restarted: %d", count); - m_output->println(""); -} - -static void -printNodeStatus(OutputStream *output, - MgmtSrvr &mgmsrv, - enum ndb_mgm_node_type type) { - NodeId nodeId = 0; - while(mgmsrv.getNextNodeId(&nodeId, type)) { - enum ndb_mgm_node_status status; - Uint32 startPhase = 0, - version = 0, - dynamicId = 0, - nodeGroup = 0, - connectCount = 0; - bool system; - const char *address= NULL; - mgmsrv.status(nodeId, &status, &version, &startPhase, - &system, &dynamicId, &nodeGroup, &connectCount, - &address); - output->println("node.%d.type: %s", - nodeId, - ndb_mgm_get_node_type_string(type)); - output->println("node.%d.status: %s", - nodeId, - ndb_mgm_get_node_status_string(status)); - output->println("node.%d.version: %d", nodeId, version); - output->println("node.%d.startphase: %d", nodeId, startPhase); - output->println("node.%d.dynamic_id: %d", nodeId, dynamicId); - output->println("node.%d.node_group: %d", nodeId, nodeGroup); - output->println("node.%d.connect_count: %d", nodeId, connectCount); - output->println("node.%d.address: %s", nodeId, address ? address : ""); - } - -} - -void -MgmApiSession::getStatus(Parser<MgmApiSession>::Context &, - Properties const &) { - int noOfNodes = 0; - - NodeId nodeId = 0; - while(m_mgmsrv.getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)){ - noOfNodes++; - } - nodeId = 0; - while(m_mgmsrv.getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_API)){ - noOfNodes++; - } - nodeId = 0; - while(m_mgmsrv.getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_MGM)){ - noOfNodes++; - } - SLEEP_ERROR_INSERTED(5); - m_output->println("node status"); - SLEEP_ERROR_INSERTED(6); - m_output->println("nodes: %d", noOfNodes); - m_mgmsrv.updateStatus(); - SLEEP_ERROR_INSERTED(7); - printNodeStatus(m_output, m_mgmsrv, NDB_MGM_NODE_TYPE_NDB); - printNodeStatus(m_output, m_mgmsrv, NDB_MGM_NODE_TYPE_MGM); - SLEEP_ERROR_INSERTED(8); - printNodeStatus(m_output, m_mgmsrv, NDB_MGM_NODE_TYPE_API); - SLEEP_ERROR_INSERTED(9); - - nodeId = 0; - - m_output->println(""); -} - -void -MgmApiSession::getInfoClusterLog(Parser<MgmApiSession>::Context &, - Properties const &) { - const char* names[] = { "enabled", - "debug", - "info", - "warning", - "error", - "critical", - "alert" }; - - m_output->println("clusterlog"); - for(int i = 0; i < 7; i++) { - m_output->println("%s: %d", - names[i], m_mgmsrv.isEventLogFilterEnabled(i)); - } - m_output->println(""); -} - -void -MgmApiSession::stop_v1(Parser<MgmApiSession>::Context &, - Properties const &args) { - stop(args,1); -} - -void -MgmApiSession::stop_v2(Parser<MgmApiSession>::Context &, - Properties const &args) { - stop(args,2); -} - -void -MgmApiSession::stop(Properties const &args, int version) { - Uint32 abort; - char *nodes_str; - Vector<NodeId> nodes; - - args.get("node", (const char **)&nodes_str); - if(nodes_str == NULL) - { - m_output->println("stop reply"); - m_output->println("result: empty node list"); - m_output->println(""); - return; - } - args.get("abort", &abort); - - char *p, *last; - for((p = strtok_r(nodes_str, " ", &last)); - p; - (p = strtok_r(NULL, " ", &last))) { - nodes.push_back(atoi(p)); - } - - int stopped= 0; - int result= 0; - if (nodes.size()) - result= m_mgmsrv.stopNodes(nodes, &stopped, abort != 0, &m_stopSelf); - - m_output->println("stop reply"); - if(result != 0) - m_output->println("result: %s", get_error_text(result)); - else - m_output->println("result: Ok"); - m_output->println("stopped: %d", stopped); - if(version>1) - m_output->println("disconnect: %d", (m_stopSelf)?1:0); - m_output->println(""); -} - -void -MgmApiSession::stopAll(Parser<MgmApiSession>::Context &, - Properties const &args) { - int stopped[2] = {0,0}; - Uint32 abort; - args.get("abort", &abort); - - BaseString stop; - const char* tostop= "db"; - int ver=1; - if (args.get("stop", stop)) - { - tostop= stop.c_str(); - ver= 2; - } - - int result= 0; - if(strstr(tostop,"db")) - result= m_mgmsrv.shutdownDB(&stopped[0], abort != 0); - if(!result && strstr(tostop,"mgm")) - result= m_mgmsrv.shutdownMGM(&stopped[1], abort!=0, &m_stopSelf); - - m_output->println("stop reply"); - if(result != 0) - m_output->println("result: %s", get_error_text(result)); - else - m_output->println("result: Ok"); - m_output->println("stopped: %d", stopped[0]+stopped[1]); - if(ver >1) - m_output->println("disconnect: %d", (m_stopSelf)?1:0); - m_output->println(""); -} - -void -MgmApiSession::enterSingleUser(Parser<MgmApiSession>::Context &, - Properties const &args) { - int stopped = 0; - Uint32 nodeId = 0; - int result= 0; - args.get("nodeId", &nodeId); - - result = m_mgmsrv.enterSingleUser(&stopped, nodeId); - m_output->println("enter single user reply"); - if(result != 0) { - m_output->println("result: %s", get_error_text(result)); - } - else { - m_output->println("result: Ok"); - } - m_output->println(""); -} - -void -MgmApiSession::exitSingleUser(Parser<MgmApiSession>::Context &, - Properties const &args) { - int stopped = 0; - int result = m_mgmsrv.exitSingleUser(&stopped, false); - m_output->println("exit single user reply"); - if(result != 0) - m_output->println("result: %s", get_error_text(result)); - else - m_output->println("result: Ok"); - m_output->println(""); -} - - -void -MgmApiSession::startSignalLog(Parser<MgmApiSession>::Context &, - Properties const &args) { - Uint32 node; - - args.get("node", &node); - - int result = m_mgmsrv.startSignalTracing(node); - - m_output->println("start signallog reply"); - if(result != 0) - m_output->println("result: %s", get_error_text(result)); - else - m_output->println("result: Ok"); - m_output->println(""); -} - -void -MgmApiSession::logSignals(Parser<MgmApiSession>::Context &, - Properties const &args) { - Uint32 node = 0, in = 0, out = 0; - // BaseString blocks; - BaseString blockList; - char * blockName; - args.get("node", &node); - args.get("in", &in); - args.get("out", &out); - args.get("blocks", blockList); - // fast fix - pekka - char buf[200]; - BaseString::snprintf(buf, 200, "%s", blockList.c_str()); - Vector<BaseString> blocks; - - blockName=strtok(buf,"|"); - while( blockName != NULL) - { - blocks.push_back(blockName); - blockName=strtok(NULL,"|"); - } - - - if(in > 1 || out > 1) - return; /* Invalid arguments */ - - const MgmtSrvr::LogMode modes[] = { - MgmtSrvr::Off, - MgmtSrvr::Out, - MgmtSrvr::In, - MgmtSrvr::InOut, - }; - MgmtSrvr::LogMode mode = modes[in<<1 | out]; - - int result = m_mgmsrv.setSignalLoggingMode(node, mode, blocks); - - m_output->println("log signals reply"); - if(result != 0) - m_output->println("result: %s", get_error_text(result)); - else - m_output->println("result: Ok"); - m_output->println(""); -} - -void -MgmApiSession::start(Parser<MgmApiSession>::Context &, - Properties const &args) { - Uint32 node; - - args.get("node", &node); - - int result = m_mgmsrv.start(node); - - m_output->println("start reply"); - if(result != 0) - m_output->println("result: %s", get_error_text(result)); - else - m_output->println("result: Ok"); - m_output->println(""); -} - -void -MgmApiSession::startAll(Parser<MgmApiSession>::Context &, - Properties const &) { - NodeId node = 0; - int started = 0; - - while(m_mgmsrv.getNextNodeId(&node, NDB_MGM_NODE_TYPE_NDB)) - if(m_mgmsrv.start(node) == 0) - started++; - - m_output->println("start reply"); - m_output->println("result: Ok"); - m_output->println("started: %d", started); - m_output->println(""); -} - -void -MgmApiSession::setLogFilter(Parser_t::Context &ctx, - const class Properties &args) { - Uint32 severity; - Uint32 enable; - - args.get("level", &severity); - args.get("enable", &enable); - - int result = m_mgmsrv.setEventLogFilter(severity, enable); - - m_output->println("set logfilter reply"); - m_output->println("result: %d", result); - m_output->println(""); -} - -#ifdef NOT_USED - -static NdbOut& -operator<<(NdbOut& out, const LogLevel & ll) -{ - out << "[LogLevel: "; - for(size_t i = 0; i<LogLevel::LOGLEVEL_CATEGORIES; i++) - out << ll.getLogLevel((LogLevel::EventCategory)i) << " "; - out << "]"; - return out; -} -#endif - -void -Ndb_mgmd_event_service::log(int eventType, const Uint32* theData, NodeId nodeId){ - - Uint32 threshold; - LogLevel::EventCategory cat; - Logger::LoggerLevel severity; - EventLoggerBase::EventTextFunction textF; - int i, n; - DBUG_ENTER("Ndb_mgmd_event_service::log"); - DBUG_PRINT("enter",("eventType=%d, nodeid=%d", eventType, nodeId)); - - if (EventLoggerBase::event_lookup(eventType,cat,threshold,severity,textF)) - DBUG_VOID_RETURN; - - char m_text[512]; - EventLogger::getText(m_text, sizeof(m_text), - textF, theData, nodeId); - - BaseString str("log event reply\n"); - str.appfmt("type=%d\n", eventType); - str.appfmt("time=%d\n", 0); - str.appfmt("source_nodeid=%d\n", nodeId); - for (i= 0; ndb_logevent_body[i].token; i++) - { - if ( ndb_logevent_body[i].type != eventType) - continue; - int val= theData[ndb_logevent_body[i].index]; - if (ndb_logevent_body[i].index_fn) - val= (*(ndb_logevent_body[i].index_fn))(val); - str.appfmt("%s=%d\n",ndb_logevent_body[i].token, val); - if(strcmp(ndb_logevent_body[i].token,"error") == 0) - { - int m_text_len= strlen(m_text); - if(sizeof(m_text)-m_text_len-3 > 0) - { - BaseString::snprintf(m_text+m_text_len, 4 , " - "); - ndb_error_string(val, m_text+(m_text_len+3), sizeof(m_text)-m_text_len-3); - } - } - } - - Vector<NDB_SOCKET_TYPE> copy; - m_clients.lock(); - for(i = m_clients.size() - 1; i >= 0; i--) - { - if(threshold <= m_clients[i].m_logLevel.getLogLevel(cat)) - { - if(m_clients[i].m_socket==NDB_INVALID_SOCKET) - continue; - - SocketOutputStream out(m_clients[i].m_socket); - - int r; - if (m_clients[i].m_parsable) - r= out.println(str.c_str()); - else - r= out.println(m_text); - - if (r<0) - { - copy.push_back(m_clients[i].m_socket); - m_clients.erase(i, false); - } - } - } - m_clients.unlock(); - - if ((n= (int)copy.size())) - { - for(i= 0; i < n; i++) - NDB_CLOSE_SOCKET(copy[i]); - - LogLevel tmp; tmp.clear(); - m_clients.lock(); - for(i= m_clients.size() - 1; i >= 0; i--) - tmp.set_max(m_clients[i].m_logLevel); - m_clients.unlock(); - update_log_level(tmp); - } - DBUG_VOID_RETURN; -} - -void -Ndb_mgmd_event_service::update_max_log_level(const LogLevel &log_level) -{ - LogLevel tmp = log_level; - m_clients.lock(); - for(int i = m_clients.size() - 1; i >= 0; i--) - tmp.set_max(m_clients[i].m_logLevel); - m_clients.unlock(); - update_log_level(tmp); -} - -void -Ndb_mgmd_event_service::update_log_level(const LogLevel &tmp) -{ - m_logLevel = tmp; - EventSubscribeReq req; - req = tmp; - // send update to all nodes - req.blockRef = 0; - m_mgmsrv->m_log_level_requests.push_back(req); -} - -void -Ndb_mgmd_event_service::check_listeners() -{ - int i, n= 0; - DBUG_ENTER("Ndb_mgmd_event_service::check_listeners"); - m_clients.lock(); - for(i= m_clients.size() - 1; i >= 0; i--) - { - if(m_clients[i].m_socket==NDB_INVALID_SOCKET) - continue; - - SocketOutputStream out(m_clients[i].m_socket); - - DBUG_PRINT("info",("%d %d",i,m_clients[i].m_socket)); - - if(out.println("<PING>") < 0) - { - NDB_CLOSE_SOCKET(m_clients[i].m_socket); - m_clients.erase(i, false); - n=1; - } - } - if (n) - { - LogLevel tmp; tmp.clear(); - for(i= m_clients.size() - 1; i >= 0; i--) - tmp.set_max(m_clients[i].m_logLevel); - update_log_level(tmp); - } - m_clients.unlock(); - DBUG_VOID_RETURN; -} - -void -Ndb_mgmd_event_service::add_listener(const Event_listener& client) -{ - DBUG_ENTER("Ndb_mgmd_event_service::add_listener"); - DBUG_PRINT("enter",("client.m_socket: %d", client.m_socket)); - - check_listeners(); - - m_clients.push_back(client); - update_max_log_level(client.m_logLevel); - - DBUG_VOID_RETURN; -} - -void -Ndb_mgmd_event_service::stop_sessions(){ - m_clients.lock(); - for(int i = m_clients.size() - 1; i >= 0; i--){ - if(m_clients[i].m_socket != NDB_INVALID_SOCKET){ - NDB_CLOSE_SOCKET(m_clients[i].m_socket); - m_clients.erase(i); - } - } - m_clients.unlock(); -} - -void -MgmApiSession::setParameter(Parser_t::Context &, - Properties const &args) { - BaseString node, param, value; - args.get("node", node); - args.get("parameter", param); - args.get("value", value); - - BaseString result; - int ret = m_mgmsrv.setDbParameter(atoi(node.c_str()), - atoi(param.c_str()), - value.c_str(), - result); - - m_output->println("set parameter reply"); - m_output->println("message: %s", result.c_str()); - m_output->println("result: %d", ret); - m_output->println(""); -} - -void -MgmApiSession::setConnectionParameter(Parser_t::Context &ctx, - Properties const &args) { - BaseString node1, node2, param, value; - args.get("node1", node1); - args.get("node2", node2); - args.get("param", param); - args.get("value", value); - - BaseString result; - int ret = m_mgmsrv.setConnectionDbParameter(atoi(node1.c_str()), - atoi(node2.c_str()), - atoi(param.c_str()), - atoi(value.c_str()), - result); - - m_output->println("set connection parameter reply"); - m_output->println("message: %s", result.c_str()); - m_output->println("result: %s", (ret>0)?"Ok":"Failed"); - m_output->println(""); -} - -void -MgmApiSession::getConnectionParameter(Parser_t::Context &ctx, - Properties const &args) { - BaseString node1, node2, param; - int value = 0; - - args.get("node1", node1); - args.get("node2", node2); - args.get("param", param); - - BaseString result; - int ret = m_mgmsrv.getConnectionDbParameter(atoi(node1.c_str()), - atoi(node2.c_str()), - atoi(param.c_str()), - &value, - result); - - m_output->println("get connection parameter reply"); - m_output->println("value: %d", value); - m_output->println("result: %s", (ret>0)?"Ok":result.c_str()); - m_output->println(""); -} - -void -MgmApiSession::listen_event(Parser<MgmApiSession>::Context & ctx, - Properties const & args) { - Uint32 parsable= 0; - BaseString node, param, value; - args.get("node", node); - args.get("filter", param); - args.get("parsable", &parsable); - - int result = 0; - BaseString msg; - - Ndb_mgmd_event_service::Event_listener le; - le.m_parsable = parsable; - le.m_socket = m_socket; - - Vector<BaseString> list; - param.trim(); - param.split(list, " ,"); - for(size_t i = 0; i<list.size(); i++){ - Vector<BaseString> spec; - list[i].trim(); - list[i].split(spec, "=:"); - if(spec.size() != 2){ - msg.appfmt("Invalid filter specification: >%s< >%s< %d", - param.c_str(), list[i].c_str(), spec.size()); - result = -1; - goto done; - } - - spec[0].trim().ndb_toupper(); - int category = ndb_mgm_match_event_category(spec[0].c_str()); - if(category == NDB_MGM_ILLEGAL_EVENT_CATEGORY){ - category = atoi(spec[0].c_str()); - if(category < NDB_MGM_MIN_EVENT_CATEGORY || - category > NDB_MGM_MAX_EVENT_CATEGORY){ - msg.appfmt("Unknown category: >%s<", spec[0].c_str()); - result = -1; - goto done; - } - } - - int level = atoi(spec[1].c_str()); - if(level < 0 || level > NDB_MGM_MAX_LOGLEVEL){ - msg.appfmt("Invalid level: >%s<", spec[1].c_str()); - result = -1; - goto done; - } - category -= CFG_MIN_LOGLEVEL; - le.m_logLevel.setLogLevel((LogLevel::EventCategory)category, level); - } - - if(list.size() == 0){ - msg.appfmt("Empty filter specification"); - result = -1; - goto done; - } - -done: - m_output->println("listen event"); - m_output->println("result: %d", result); - if(result != 0) - m_output->println("msg: %s", msg.c_str()); - m_output->println(""); - - if(result==0) - { - m_mgmsrv.m_event_listner.add_listener(le); - m_stop = true; - m_socket = NDB_INVALID_SOCKET; - } -} - -void -MgmApiSession::stop_session_if_not_connected(SocketServer::Session *_s, void *data) -{ - MgmApiSession *s= (MgmApiSession *)_s; - struct PurgeStruct &ps= *(struct PurgeStruct *)data; - if (s->m_allocated_resources->is_reserved(ps.free_nodes)) - { - if (ps.str) - ps.str->appfmt(" %d", s->m_allocated_resources->get_nodeid()); - s->stopSession(); - } -} - -void -MgmApiSession::stop_session_if_timed_out(SocketServer::Session *_s, void *data) -{ - MgmApiSession *s= (MgmApiSession *)_s; - struct PurgeStruct &ps= *(struct PurgeStruct *)data; - if (s->m_allocated_resources->is_reserved(ps.free_nodes) && - s->m_allocated_resources->is_timed_out(ps.tick)) - { - s->stopSession(); - } -} - -void -MgmApiSession::purge_stale_sessions(Parser_t::Context &ctx, - const class Properties &args) -{ - struct PurgeStruct ps; - BaseString str; - ps.str = &str; - - m_mgmsrv.get_connected_nodes(ps.free_nodes); - ps.free_nodes.bitXORC(NodeBitmask()); // invert connected_nodes to get free nodes - - m_mgmsrv.get_socket_server()->foreachSession(stop_session_if_not_connected,&ps); - m_mgmsrv.get_socket_server()->checkSessions(); - - m_output->println("purge stale sessions reply"); - if (str.length() > 0) - m_output->println("purged:%s",str.c_str()); - m_output->println("result: Ok"); - m_output->println(""); -} - -void -MgmApiSession::check_connection(Parser_t::Context &ctx, - const class Properties &args) -{ - SLEEP_ERROR_INSERTED(1); - m_output->println("check connection reply"); - SLEEP_ERROR_INSERTED(2); - m_output->println("result: Ok"); - SLEEP_ERROR_INSERTED(3); - m_output->println(""); -} - -void -MgmApiSession::transporter_connect(Parser_t::Context &ctx, - Properties const &args) -{ - m_mgmsrv.transporter_connect(m_socket); - - m_stop= true; - m_stopped= true; // force a stop (no closing socket) - m_socket= NDB_INVALID_SOCKET; // so nobody closes it -} - -void -MgmApiSession::get_mgmd_nodeid(Parser_t::Context &ctx, - Properties const &args) -{ - m_output->println("get mgmd nodeid reply"); - m_output->println("nodeid:%u",m_mgmsrv.getOwnNodeId()); - SLEEP_ERROR_INSERTED(1); - - m_output->println(""); -} - -void -MgmApiSession::report_event(Parser_t::Context &ctx, - Properties const &args) -{ - Uint32 length; - const char *data_string; - Uint32 data[25]; - - args.get("length", &length); - args.get("data", &data_string); - - BaseString tmp(data_string); - Vector<BaseString> item; - tmp.split(item, " "); - for (int i = 0; (Uint32) i < length ; i++) - { - sscanf(item[i].c_str(), "%u", data+i); - } - - m_mgmsrv.eventReport(data); - m_output->println("report event reply"); - m_output->println("result: ok"); - m_output->println(""); -} - -void -MgmApiSession::list_session(SocketServer::Session *_s, void *data) -{ - MgmApiSession *s= (MgmApiSession *)_s; - MgmApiSession *lister= (MgmApiSession*) data; - - if(s!=lister) - NdbMutex_Lock(s->m_mutex); - - Uint64 id= s->m_session_id; - lister->m_output->println("session: %llu",id); - lister->m_output->println("session.%llu.m_stopSelf: %d",id,s->m_stopSelf); - lister->m_output->println("session.%llu.m_stop: %d",id,s->m_stop); - lister->m_output->println("session.%llu.allocated.nodeid: %d",id,s->m_allocated_resources->get_nodeid()); - if(s->m_ctx) - { - int l= strlen(s->m_ctx->m_tokenBuffer); - char *buf= (char*) malloc(2*l+1); - char *b= buf; - for(int i=0; i<l;i++) - if(s->m_ctx->m_tokenBuffer[i]=='\n') - { - *b++='\\'; - *b++='n'; - } - else - { - *b++= s->m_ctx->m_tokenBuffer[i]; - } - *b= '\0'; - - lister->m_output->println("session.%llu.parser.buffer.len: %u",id,l); - lister->m_output->println("session.%llu.parser.buffer: %s",id,buf); - lister->m_output->println("session.%llu.parser.status: %d",id,s->m_ctx->m_status); - - free(buf); - } - - if(s!=lister) - NdbMutex_Unlock(s->m_mutex); -} - -void -MgmApiSession::listSessions(Parser_t::Context &ctx, - Properties const &args) { - m_mgmsrv.get_socket_server()->foreachSession(list_session,(void*)this); - - m_output->println(""); -} - -void -MgmApiSession::getSessionId(Parser_t::Context &ctx, - Properties const &args) { - m_output->println("get session id reply"); - m_output->println("id: %llu",m_session_id); - m_output->println(""); -} - -struct get_session_param { - MgmApiSession *l; - Uint64 id; - int found; -}; - -void -MgmApiSession::get_session(SocketServer::Session *_s, void *data) -{ - struct get_session_param *p= (struct get_session_param*)data; - MgmApiSession *s= (MgmApiSession *)_s; - - if(s!=p->l) - NdbMutex_Lock(s->m_mutex); - - if(p->id != s->m_session_id) - { - if(s!=p->l) - NdbMutex_Unlock(s->m_mutex); - return; - } - - p->found= true; - p->l->m_output->println("id: %llu",s->m_session_id); - p->l->m_output->println("m_stopSelf: %d",s->m_stopSelf); - p->l->m_output->println("m_stop: %d",s->m_stop); - p->l->m_output->println("nodeid: %d",s->m_allocated_resources->get_nodeid()); - if(s->m_ctx) - { - int l= strlen(s->m_ctx->m_tokenBuffer); - p->l->m_output->println("parser_buffer_len: %u",l); - p->l->m_output->println("parser_status: %d",s->m_ctx->m_status); - } - - if(s!=p->l) - NdbMutex_Unlock(s->m_mutex); -} - -void -MgmApiSession::getSession(Parser_t::Context &ctx, - Properties const &args) { - Uint64 id; - struct get_session_param p; - - args.get("id", &id); - - p.l= this; - p.id= id; - p.found= false; - - m_output->println("get session reply"); - m_mgmsrv.get_socket_server()->foreachSession(get_session,(void*)&p); - - if(p.found==false) - m_output->println("id: 0"); - - m_output->println(""); -} - -template class MutexVector<int>; -template class Vector<ParserRow<MgmApiSession> const*>; diff --git a/storage/ndb/src/mgmsrv/Services.hpp b/storage/ndb/src/mgmsrv/Services.hpp deleted file mode 100644 index 6020ac60f4f..00000000000 --- a/storage/ndb/src/mgmsrv/Services.hpp +++ /dev/null @@ -1,136 +0,0 @@ -/* Copyright (c) 2003-2007 MySQL AB - Use is subject to license terms - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ - -#ifndef MGMAPI_SERVICE_HPP -#define MGMAPI_SERVICE_HPP - -#include <SocketServer.hpp> -#include <NdbSleep.h> -#include <Parser.hpp> -#include <OutputStream.hpp> -#include <InputStream.hpp> - -#include "MgmtSrvr.hpp" - -class MgmApiSession : public SocketServer::Session -{ - static void stop_session_if_timed_out(SocketServer::Session *_s, void *data); - static void stop_session_if_not_connected(SocketServer::Session *_s, void *data); - static void list_session(SocketServer::Session *_s, void *data); - static void get_session(SocketServer::Session *_s, void *data); -private: - typedef Parser<MgmApiSession> Parser_t; - - class MgmtSrvr & m_mgmsrv; - InputStream *m_input; - OutputStream *m_output; - Parser_t *m_parser; - MgmtSrvr::Allocated_resources *m_allocated_resources; - char m_err_str[1024]; - int m_stopSelf; // -1 is restart, 0 do nothing, 1 stop - NdbMutex *m_mutex; - - // for listing sessions and other fun: - Parser_t::Context *m_ctx; - Uint64 m_session_id; - - int m_errorInsert; - - const char *get_error_text(int err_no) - { return m_mgmsrv.getErrorText(err_no, m_err_str, sizeof(m_err_str)); } - -public: - MgmApiSession(class MgmtSrvr & mgm, NDB_SOCKET_TYPE sock, Uint64 session_id); - virtual ~MgmApiSession(); - void runSession(); - - void getConfig(Parser_t::Context &ctx, const class Properties &args); - - void get_nodeid(Parser_t::Context &ctx, const class Properties &args); - void getVersion(Parser_t::Context &ctx, const class Properties &args); - void getStatus(Parser_t::Context &ctx, const class Properties &args); - void getInfoClusterLog(Parser_t::Context &ctx, const class Properties &args); - void restart(const class Properties &args, int version); - void restart_v1(Parser_t::Context &ctx, const class Properties &args); - void restart_v2(Parser_t::Context &ctx, const class Properties &args); - void restartAll(Parser_t::Context &ctx, const class Properties &args); - void insertError(Parser_t::Context &ctx, const class Properties &args); - void setTrace(Parser_t::Context &ctx, const class Properties &args); - void logSignals(Parser_t::Context &ctx, const class Properties &args); - void startSignalLog(Parser_t::Context &ctx, const class Properties &args); - void stopSignalLog(Parser_t::Context &ctx, const class Properties &args); - void dumpState(Parser_t::Context &ctx, const class Properties &args); - void startBackup(Parser_t::Context &ctx, const class Properties &args); - void abortBackup(Parser_t::Context &ctx, const class Properties &args); - void enterSingleUser(Parser_t::Context &ctx, const class Properties &args); - void exitSingleUser(Parser_t::Context &ctx, const class Properties &args); - void stop_v1(Parser_t::Context &ctx, const class Properties &args); - void stop_v2(Parser_t::Context &ctx, const class Properties &args); - void stop(const class Properties &args, int version); - void stopAll(Parser_t::Context &ctx, const class Properties &args); - void start(Parser_t::Context &ctx, const class Properties &args); - void startAll(Parser_t::Context &ctx, const class Properties &args); - void bye(Parser_t::Context &ctx, const class Properties &args); - void endSession(Parser_t::Context &ctx, const class Properties &args); - void setLogLevel(Parser_t::Context &ctx, const class Properties &args); - void getClusterLogLevel(Parser_t::Context &ctx, - const class Properties &args); - void setClusterLogLevel(Parser_t::Context &ctx, - const class Properties &args); - void setLogFilter(Parser_t::Context &ctx, const class Properties &args); - - void setParameter(Parser_t::Context &ctx, const class Properties &args); - void setConnectionParameter(Parser_t::Context &ctx, - const class Properties &args); - void getConnectionParameter(Parser_t::Context &ctx, - Properties const &args); - - void listen_event(Parser_t::Context &ctx, const class Properties &args); - - void purge_stale_sessions(Parser_t::Context &ctx, const class Properties &args); - void check_connection(Parser_t::Context &ctx, const class Properties &args); - - void transporter_connect(Parser_t::Context &ctx, Properties const &args); - - void get_mgmd_nodeid(Parser_t::Context &ctx, Properties const &args); - - void report_event(Parser_t::Context &ctx, Properties const &args); - - void listSessions(Parser_t::Context &ctx, Properties const &args); - - void getSessionId(Parser_t::Context &ctx, Properties const &args); - void getSession(Parser_t::Context &ctx, Properties const &args); -}; - -class MgmApiService : public SocketServer::Service { - class MgmtSrvr * m_mgmsrv; - Uint64 m_next_session_id; // Protected by m_sessions mutex it SocketServer -public: - MgmApiService(){ - m_mgmsrv = 0; - m_next_session_id= 1; - } - - void setMgm(class MgmtSrvr * mgmsrv){ - m_mgmsrv = mgmsrv; - } - - SocketServer::Session * newSession(NDB_SOCKET_TYPE socket){ - return new MgmApiSession(* m_mgmsrv, socket, m_next_session_id++); - } -}; - -#endif diff --git a/storage/ndb/src/mgmsrv/SignalQueue.cpp b/storage/ndb/src/mgmsrv/SignalQueue.cpp deleted file mode 100644 index a8b993d2760..00000000000 --- a/storage/ndb/src/mgmsrv/SignalQueue.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/* Copyright (c) 2003-2005 MySQL AB - Use is subject to license terms - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ - -#include <ndb_global.h> -#include "SignalQueue.hpp" - -SignalQueue::SignalQueue() { - m_mutex = NdbMutex_Create(); - m_cond = NdbCondition_Create(); - m_signalQueueHead = NULL; -} - -SignalQueue::~SignalQueue() { - { - Guard g(m_mutex); - while(m_signalQueueHead != NULL) - delete pop(); - } - NdbMutex_Destroy(m_mutex); - m_mutex = NULL; - NdbCondition_Destroy(m_cond); - m_cond = NULL; -} - -NdbApiSignal * -SignalQueue::pop() { - NdbApiSignal *ret; - - if(m_signalQueueHead == NULL) - return NULL; - - ret = m_signalQueueHead->signal; - - QueueEntry *old = m_signalQueueHead; - m_signalQueueHead = m_signalQueueHead->next; - - delete old; - - return ret; -} - -void -SignalQueue::receive(void *me, NdbApiSignal *signal) { - SignalQueue *q = (SignalQueue *)me; - q->receive(signal); -} - -void -SignalQueue::receive(NdbApiSignal *signal) { - QueueEntry *n = new QueueEntry(); - n->signal = signal; - n->next = NULL; - - Guard guard(m_mutex); - - if(m_signalQueueHead == NULL) { - m_signalQueueHead = n; - NdbCondition_Broadcast(m_cond); - return; - } - - QueueEntry *cur = m_signalQueueHead; - - while(cur->next != NULL) - cur = cur->next; - - cur->next = n; - - NdbCondition_Broadcast(m_cond); -} - -NdbApiSignal * -SignalQueue::waitFor(int gsn, NodeId nodeid, Uint32 timeout) { - Guard g(m_mutex); - - if(m_signalQueueHead == NULL) - NdbCondition_WaitTimeout(m_cond, m_mutex, timeout); - - if(m_signalQueueHead == NULL) - return NULL; - - if(gsn != 0 && - m_signalQueueHead->signal->readSignalNumber() != gsn) - return NULL; - - if(nodeid != 0 && - refToNode(m_signalQueueHead->signal->theSendersBlockRef) != nodeid) - return NULL; - - return pop(); -} diff --git a/storage/ndb/src/mgmsrv/SignalQueue.hpp b/storage/ndb/src/mgmsrv/SignalQueue.hpp deleted file mode 100644 index e73bb25daab..00000000000 --- a/storage/ndb/src/mgmsrv/SignalQueue.hpp +++ /dev/null @@ -1,100 +0,0 @@ -/* Copyright (c) 2003-2005 MySQL AB - Use is subject to license terms - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ - -#ifndef __SIGNALQUEUE_HPP_INCLUDED__ -#define __SIGNALQUEUE_HPP_INCLUDED__ - -#include <NdbApiSignal.hpp> -#include <NdbMutex.h> -#include <NdbCondition.h> -#include <Vector.hpp> - -/* XXX Look for an already existing definition */ -#define DEFAULT_TIMEOUT 5000 - -class SignalQueue { -public: - typedef void (* SignalHandler)(void *obj, int gsn, NdbApiSignal *signal); - - SignalQueue(); - ~SignalQueue(); - - /** - * Static wrapper making it possible to call receive without knowing the - * type of the receiver - */ - static void receive(void *me, NdbApiSignal *signal); - - /** - * Enqueues a signal, and notifies any thread waiting for signals. - */ - void receive(NdbApiSignal *signal); - - NdbApiSignal *waitFor(int gsn, - NodeId nodeid = 0, - Uint32 timeout = DEFAULT_TIMEOUT); - template<class T> bool waitFor(Vector<T> &t, - T **handler, - NdbApiSignal **signal, - Uint32 timeout = DEFAULT_TIMEOUT); -private: - NdbMutex *m_mutex; /* Locks all data in SignalQueue */ - NdbCondition *m_cond; /* Notifies about new signal in the queue */ - - /** - * Returns the last recently received signal. Must be called with - * m_mutex locked. - * The caller takes responsibility for deleting the returned object. - * - * @returns NULL if failed, or a received signal - */ - NdbApiSignal *pop(); - - class QueueEntry { - public: - NdbApiSignal *signal; - QueueEntry *next; - }; - QueueEntry *m_signalQueueHead; /** Head of the queue. - * New entries added on the tail - */ -}; - -template<class T> bool -SignalQueue::waitFor(Vector<T> &t, - T **handler, - NdbApiSignal **signal, - Uint32 timeout) { - Guard g(m_mutex); - - if(m_signalQueueHead == NULL) - NdbCondition_WaitTimeout(m_cond, m_mutex, timeout); - - if(m_signalQueueHead == NULL) - return false; - - for(size_t i = 0; i < t.size(); i++) { - if(t[i].check(m_signalQueueHead->signal)) { - * handler = &t[i]; - * signal = pop(); - return true; - } - } - - return false; -} - -#endif /* !__SIGNALQUEUE_HPP_INCLUDED__ */ diff --git a/storage/ndb/src/mgmsrv/convertStrToInt.cpp b/storage/ndb/src/mgmsrv/convertStrToInt.cpp deleted file mode 100644 index 1ca0eeb8da7..00000000000 --- a/storage/ndb/src/mgmsrv/convertStrToInt.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright (c) 2003-2005 MySQL AB - Use is subject to license terms - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ - -#include <ndb_global.h> - -bool convert(const char* s, int& val) { - - if (s == NULL) { - return false; - } - - if (strlen(s) == 0) { - return false; - } - - errno = 0; - char* p; - long v = strtol(s, &p, 10); - if (errno != 0) { - return false; - } - if (p != &s[strlen(s)]) { - return false; - } - - val = v; - return true; -} - - diff --git a/storage/ndb/src/mgmsrv/convertStrToInt.hpp b/storage/ndb/src/mgmsrv/convertStrToInt.hpp deleted file mode 100644 index dd144705da9..00000000000 --- a/storage/ndb/src/mgmsrv/convertStrToInt.hpp +++ /dev/null @@ -1,25 +0,0 @@ -/* Copyright (c) 2003, 2005 MySQL AB - Use is subject to license terms - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ - -//****************************************************************************** -// Description: -// -// Author: Peter Lind -//****************************************************************************** - -extern bool convert(const char* s, int& val); - - diff --git a/storage/ndb/src/mgmsrv/main.cpp b/storage/ndb/src/mgmsrv/main.cpp deleted file mode 100644 index 7cf286db969..00000000000 --- a/storage/ndb/src/mgmsrv/main.cpp +++ /dev/null @@ -1,382 +0,0 @@ -/* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ - -#include <ndb_global.h> -#include <ndb_opts.h> - -#include "MgmtSrvr.hpp" -#include "EventLogger.hpp" -#include <Config.hpp> -#include "InitConfigFileParser.hpp" -#include <SocketServer.hpp> -#include "Services.hpp" -#include <version.h> -#include <kernel_types.h> -#include <Properties.hpp> -#include <NdbOut.hpp> -#include <NdbMain.h> -#include <NdbDaemon.h> -#include <NdbConfig.h> -#include <NdbHost.h> -#include <ndb_version.h> -#include <ConfigRetriever.hpp> -#include <mgmapi_config_parameters.h> - -#include <NdbAutoPtr.hpp> - -#include <ndb_mgmclient.hpp> - -#undef DEBUG -#define DEBUG(x) ndbout << x << endl; - -const char progname[] = "mgmtsrvr"; -const char *load_default_groups[]= { "mysql_cluster","ndb_mgmd",0 }; - -// copied from mysql.cc to get readline -extern "C" { -#if defined( __WIN__) -#include <conio.h> -#else -#include <readline/readline.h> -extern "C" int add_history(const char *command); /* From readline directory */ -#define HAVE_READLINE -#endif -} - -static int -read_and_execute(Ndb_mgmclient* com, const char * prompt, int _try_reconnect) -{ - static char *line_read = (char *)NULL; - - /* If the buffer has already been allocated, return the memory - to the free pool. */ - if (line_read) - { - free (line_read); - line_read = (char *)NULL; - } -#ifdef HAVE_READLINE - /* Get a line from the user. */ - line_read = readline (prompt); - /* If the line has any text in it, save it on the history. */ - if (line_read && *line_read) - add_history (line_read); -#else - static char linebuffer[254]; - fputs(prompt, stdout); - linebuffer[sizeof(linebuffer)-1]=0; - line_read = fgets(linebuffer, sizeof(linebuffer)-1, stdin); - if (line_read == linebuffer) { - char *q=linebuffer; - while (*q > 31) q++; - *q=0; - line_read= strdup(linebuffer); - } -#endif - return com->execute(line_read,_try_reconnect); -} - -/** - * @struct MgmGlobals - * @brief Global Variables used in the management server - *****************************************************************************/ - -/** Command line arguments */ -static int opt_daemon; // NOT bool, bool need not be int -static int opt_non_interactive; -static int opt_interactive; -static const char * opt_config_filename= 0; -static int opt_mycnf = 0; - -struct MgmGlobals { - MgmGlobals(); - ~MgmGlobals(); - - /** Stuff found in environment or in local config */ - NodeId localNodeId; - bool use_specific_ip; - char * interface_name; - short unsigned int port; - - /** The Mgmt Server */ - MgmtSrvr * mgmObject; - - /** The Socket Server */ - SocketServer * socketServer; -}; - -int g_no_nodeid_checks= 0; -int g_print_full_config; -static MgmGlobals *glob= 0; - -/****************************************************************************** - * Function prototypes - ******************************************************************************/ -/** - * Global variables - */ -bool g_StopServer; -bool g_RestartServer; -extern EventLogger g_eventLogger; - -enum ndb_mgmd_options { - OPT_INTERACTIVE = NDB_STD_OPTIONS_LAST, - OPT_NO_NODEID_CHECKS, - OPT_NO_DAEMON -}; -NDB_STD_OPTS_VARS; - -static struct my_option my_long_options[] = -{ - NDB_STD_OPTS("ndb_mgmd"), - { "config-file", 'f', "Specify cluster configuration file", - &opt_config_filename, &opt_config_filename, 0, - GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, - { "print-full-config", 'P', "Print full config and exit", - &g_print_full_config, &g_print_full_config, 0, - GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, - { "daemon", 'd', "Run ndb_mgmd in daemon mode (default)", - &opt_daemon, &opt_daemon, 0, - GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0 }, - { "interactive", OPT_INTERACTIVE, - "Run interactive. Not supported but provided for testing purposes", - &opt_interactive, &opt_interactive, 0, - GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, - { "no-nodeid-checks", OPT_NO_NODEID_CHECKS, - "Do not provide any node id checks", - &g_no_nodeid_checks, &g_no_nodeid_checks, 0, - GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, - { "nodaemon", OPT_NO_DAEMON, - "Don't run as daemon, but don't read from stdin", - &opt_non_interactive, &opt_non_interactive, 0, - GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, - { "mycnf", 256, - "Read cluster config from my.cnf", - &opt_mycnf, &opt_mycnf, 0, - GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} -}; - -static void short_usage_sub(void) -{ - printf("Usage: %s [OPTIONS]\n", my_progname); -} -static void usage() -{ - short_usage_sub(); - ndb_std_print_version(); - print_defaults(MYSQL_CONFIG_NAME,load_default_groups); - puts(""); - my_print_help(my_long_options); - my_print_variables(my_long_options); -} - -/* - * MAIN - */ -int main(int argc, char** argv) -{ - - NDB_INIT(argv[0]); - - load_defaults("my",load_default_groups,&argc,&argv); - - int ho_error; -#ifndef DBUG_OFF - opt_debug= "d:t:O,/tmp/ndb_mgmd.trace"; -#endif - if ((ho_error=handle_options(&argc, &argv, my_long_options, - ndb_std_get_one_option))) - exit(ho_error); - -start: - glob= new MgmGlobals; - - if (opt_interactive || - opt_non_interactive || - g_print_full_config) { - opt_daemon= 0; - } - - if (opt_mycnf && opt_config_filename) - { - ndbout_c("Both --mycnf and -f is not supported"); - return 0; - } - - if (opt_mycnf == 0 && opt_config_filename == 0) - { - struct stat buf; - if (stat("config.ini", &buf) != -1) - opt_config_filename = "config.ini"; - } - - glob->socketServer = new SocketServer(); - - MgmApiService * mapi = new MgmApiService(); - - glob->mgmObject = new MgmtSrvr(glob->socketServer, - opt_config_filename, - opt_connect_str); - - if (g_print_full_config) - goto the_end; - - if (glob->mgmObject->init()) - goto error_end; - - my_setwd(NdbConfig_get_path(0), MYF(0)); - - glob->localNodeId= glob->mgmObject->getOwnNodeId(); - if (glob->localNodeId == 0) { - goto error_end; - } - - glob->port= glob->mgmObject->getPort(); - - if (glob->port == 0) - goto error_end; - - glob->interface_name = 0; - glob->use_specific_ip = false; - - if(!glob->use_specific_ip){ - int count= 5; // no of retries for tryBind - while(!glob->socketServer->tryBind(glob->port, glob->interface_name)){ - if (--count > 0) { - NdbSleep_MilliSleep(1000); - continue; - } - ndbout_c("Unable to setup port: %s:%d!\n" - "Please check if the port is already used,\n" - "(perhaps a ndb_mgmd is already running),\n" - "and if you are executing on the correct computer", - (glob->interface_name ? glob->interface_name : "*"), glob->port); - goto error_end; - } - free(glob->interface_name); - glob->interface_name = 0; - } - - if(!glob->socketServer->setup(mapi, &glob->port, glob->interface_name)) - { - ndbout_c("Unable to setup management port: %d!\n" - "Please check if the port is already used,\n" - "(perhaps a ndb_mgmd is already running),\n" - "and if you are executing on the correct computer", - glob->port); - delete mapi; - goto error_end; - } - - if(!glob->mgmObject->check_start()){ - ndbout_c("Unable to check start management server."); - ndbout_c("Probably caused by illegal initial configuration file."); - goto error_end; - } - - if (opt_daemon) { - // Become a daemon - char *lockfile= NdbConfig_PidFileName(glob->localNodeId); - char *logfile= NdbConfig_StdoutFileName(glob->localNodeId); - NdbAutoPtr<char> tmp_aptr1(lockfile), tmp_aptr2(logfile); - - if (NdbDaemon_Make(lockfile, logfile, 0) == -1) { - ndbout << "Cannot become daemon: " << NdbDaemon_ErrorText << endl; - return 1; - } - } - -#ifndef NDB_WIN32 - signal(SIGPIPE, SIG_IGN); -#endif - { - BaseString error_string; - if(!glob->mgmObject->start(error_string)){ - ndbout_c("Unable to start management server."); - ndbout_c("Probably caused by illegal initial configuration file."); - ndbout_c(error_string.c_str()); - goto error_end; - } - } - - //glob->mgmObject->saveConfig(); - mapi->setMgm(glob->mgmObject); - - char msg[256]; - BaseString::snprintf(msg, sizeof(msg), - "NDB Cluster Management Server. %s", NDB_VERSION_STRING); - ndbout_c(msg); - g_eventLogger.info(msg); - - BaseString::snprintf(msg, 256, "Id: %d, Command port: %d", - glob->localNodeId, glob->port); - ndbout_c(msg); - g_eventLogger.info(msg); - - g_StopServer = false; - g_RestartServer= false; - glob->socketServer->startServer(); - - if(opt_interactive) { - BaseString con_str; - if(glob->interface_name) - con_str.appfmt("host=%s:%d", glob->interface_name, glob->port); - else - con_str.appfmt("localhost:%d", glob->port); - Ndb_mgmclient com(con_str.c_str(), 1); - while(g_StopServer != true && read_and_execute(&com, "ndb_mgm> ", 1)); - } else - { - while(g_StopServer != true) - NdbSleep_MilliSleep(500); - } - - if(g_RestartServer) - g_eventLogger.info("Restarting server..."); - else - g_eventLogger.info("Shutting down server..."); - glob->socketServer->stopServer(); - // We disconnect from the ConfigRetreiver mgmd when we delete glob below - glob->socketServer->stopSessions(true); - g_eventLogger.info("Shutdown complete"); - the_end: - delete glob; - if(g_RestartServer) - goto start; - ndb_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0); - return 0; - error_end: - delete glob; - ndb_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0); - return 1; -} - -MgmGlobals::MgmGlobals(){ - // Default values - port = 0; - interface_name = 0; - socketServer = 0; - mgmObject = 0; -} - -MgmGlobals::~MgmGlobals(){ - if (socketServer) - delete socketServer; - if (mgmObject) - delete mgmObject; - if (interface_name) - free(interface_name); -} diff --git a/storage/ndb/src/mgmsrv/mkconfig/Makefile b/storage/ndb/src/mgmsrv/mkconfig/Makefile deleted file mode 100644 index 43574eefbd1..00000000000 --- a/storage/ndb/src/mgmsrv/mkconfig/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -include .defs.mk - -TYPE := ndbapi - -BIN_TARGET := mkconfig -BIN_TARGET_ARCHIVES := logger trace mgmsrvcommon portlib general - -SOURCES := mkconfig.cpp - -CCFLAGS_LOC += -I.. -I$(call fixpath,$(NDB_TOP)/src/common/mgmcommon) -CFLAGS_mkconfig.cpp := -I$(call fixpath,$(NDB_TOP)/src/mgmapi) - -include $(NDB_TOP)/Epilogue.mk diff --git a/storage/ndb/src/mgmsrv/mkconfig/mkconfig.cpp b/storage/ndb/src/mgmsrv/mkconfig/mkconfig.cpp deleted file mode 100644 index 90e179e7f4f..00000000000 --- a/storage/ndb/src/mgmsrv/mkconfig/mkconfig.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright (c) 2003-2005 MySQL AB - Use is subject to license terms - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ - -#include <ndb_global.h> -#include <ndb_version.h> -#include <mgmapi_configuration.hpp> - -#include <NdbMain.h> -#include <Properties.hpp> - -#include "InitConfigFileParser.hpp" -#include <Config.hpp> - -void usage(const char * prg){ - ndbout << "Usage " << prg << ": <Init config> <Binary file>" << endl; - -} - -NDB_COMMAND(mkconfig, - "mkconfig", "mkconfig", - "Make a binary configuration from a config file", 16384){ - ndb_init(); - if(argc < 3){ - usage(argv[0]); - return 0; - } - - InitConfigFileParser parser; - Config* _cp; - - if ((_cp = parser.parseConfig(argv[1])) == 0) - return false; - - ConfigValues* cp = &_cp->m_configValues->m_config; - Uint32 sz = cp->getPackedSize(); - UtilBuffer buf; - if(!cp->pack(buf)) - return -1; - - FILE * f = fopen(argv[2], "w"); - if(fwrite(buf.get_data(), 1, buf.length(), f) != sz){ - fclose(f); - unlink(argv[2]); - return -1; - } - fclose(f); - return 0; -} diff --git a/storage/ndb/src/mgmsrv/ndb_mgmd_error.h b/storage/ndb/src/mgmsrv/ndb_mgmd_error.h deleted file mode 100644 index 61302ea6945..00000000000 --- a/storage/ndb/src/mgmsrv/ndb_mgmd_error.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright (C) 2007 MySQL AB - Use is subject to license terms - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ - -#ifndef NDB_MGMD_ERROR_H -#define NDB_MGMD_ERROR_H - -#define NO_CONTACT_WITH_PROCESS 5000 -#define WRONG_PROCESS_TYPE 5002 -#define SEND_OR_RECEIVE_FAILED 5005 -#define INVALID_ERROR_NUMBER 5007 -#define INVALID_TRACE_NUMBER 5008 -#define INVALID_BLOCK_NAME 5010 -#define NODE_SHUTDOWN_IN_PROGESS 5026 -#define SYSTEM_SHUTDOWN_IN_PROGRESS 5027 -#define NODE_SHUTDOWN_WOULD_CAUSE_SYSTEM_CRASH 5028 -#define NO_CONTACT_WITH_DB_NODES 5030 -#define UNSUPPORTED_NODE_SHUTDOWN 5031 -#define NODE_NOT_API_NODE 5062 -#define OPERATION_NOT_ALLOWED_START_STOP 5063 - -#endif |