From: Maitrayi Sabaratnam Date: July 1 2011 5:30pm Subject: bzr push into mysql-5.1-telco-7.0 branch (maitrayi.sabaratnam:4495 to 4496) List-Archive: http://lists.mysql.com/commits/140079 Message-Id: <20110701173019.22726.qmail@asator03> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 4496 Maitrayi Sabaratnam 2011-07-01 60097: NDB_CONFIG TO DUMP CONFIG VERSION FOR DATA NODES added: storage/ndb/include/kernel/signaldata/GetConfig.hpp storage/ndb/src/common/debugger/signaldata/GetConfig.cpp modified: mysql-test/suite/ndb/r/ndb_config.result mysql-test/suite/ndb/t/ndb_config.test storage/ndb/include/kernel/GlobalSignalNumbers.h storage/ndb/include/kernel/signaldata/SignalData.hpp storage/ndb/include/mgmapi/mgmapi.h storage/ndb/include/ndb_version.h.in storage/ndb/src/common/debugger/signaldata/CMakeLists.txt storage/ndb/src/common/debugger/signaldata/Makefile.am storage/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp storage/ndb/src/common/debugger/signaldata/SignalNames.cpp storage/ndb/src/common/mgmcommon/ConfigRetriever.cpp storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.hpp storage/ndb/src/kernel/vm/Configuration.cpp storage/ndb/src/kernel/vm/Configuration.hpp storage/ndb/src/mgmapi/mgmapi.cpp storage/ndb/src/mgmapi/mgmapi_internal.h storage/ndb/src/mgmsrv/Defragger.hpp storage/ndb/src/mgmsrv/MgmtSrvr.cpp storage/ndb/src/mgmsrv/MgmtSrvr.hpp storage/ndb/src/mgmsrv/Services.cpp storage/ndb/test/ndbapi/testMgm.cpp storage/ndb/tools/ndb_config.cpp 4495 magnus.blaudd@stripped 2011-07-01 [merge] Merge added: mysql-test/suite/ndb/bug12712109.ini modified: mysql-test/suite/ndb/r/ndb_config.result mysql-test/suite/ndb/t/ndb_config.test storage/ndb/src/mgmsrv/ConfigInfo.cpp === modified file 'mysql-test/suite/ndb/r/ndb_config.result' --- a/mysql-test/suite/ndb/r/ndb_config.result 2011-07-01 09:16:46 +0000 +++ b/mysql-test/suite/ndb/r/ndb_config.result 2011-07-01 17:15:00 +0000 @@ -39,3 +39,5 @@ tcp,3,4,55,3 tcp,3,5,55,3 tcp,3,6,55,3 t 2,37-48 1,1-2 == 19 == bug12712109 10485760 10485760 10485760 10485760 10485760 +1 +1 === modified file 'mysql-test/suite/ndb/t/ndb_config.test' --- a/mysql-test/suite/ndb/t/ndb_config.test 2011-07-01 09:16:46 +0000 +++ b/mysql-test/suite/ndb/t/ndb_config.test 2011-07-01 17:15:00 +0000 @@ -64,3 +64,8 @@ echo == 18 == bug56185; echo == 19 == bug12712109; --exec $NDB_CONFIG --config-file=$MYSQL_TEST_DIR/suite/ndb/bug12712109.ini --query=OverloadLimit --connections 2>&1 +# Read config generation number from nodes +# From management server +--exec $NDB_CONFIG --system --query=ConfigGenerationNumber +# From a data node +--exec $NDB_CONFIG --system --config-from-node=2 --query=ConfigGenerationNumber === modified file 'storage/ndb/include/kernel/GlobalSignalNumbers.h' --- a/storage/ndb/include/kernel/GlobalSignalNumbers.h 2011-05-19 09:16:32 +0000 +++ b/storage/ndb/include/kernel/GlobalSignalNumbers.h 2011-07-01 17:15:00 +0000 @@ -111,9 +111,10 @@ extern const GlobalSignalNumber NO_OF_SI #define GSN_CONFIG_CHECK_REF 52 #define GSN_CONFIG_CHECK_CONF 53 -/* 54 unused */ -/* 55 unused */ -/* 56 unused */ +#define GSN_GET_CONFIG_REQ 54 +#define GSN_GET_CONFIG_REF 55 +#define GSN_GET_CONFIG_CONF 56 + /* 57 unused */ /* 58 unused */ /* 59 unused */ === added file 'storage/ndb/include/kernel/signaldata/GetConfig.hpp' --- a/storage/ndb/include/kernel/signaldata/GetConfig.hpp 1970-01-01 00:00:00 +0000 +++ b/storage/ndb/include/kernel/signaldata/GetConfig.hpp 2011-07-01 17:15:00 +0000 @@ -0,0 +1,75 @@ +/* + Copyright (c) 2011, 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 St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef GET_CONFIG_HPP +#define GET_CONFIG_HPP + +#include "SignalData.hpp" + +/** + * GetConfig - Get the node's current configuration + * + * Successfull return = GET_CONFIG_CONF - a long signal + */ +class GetConfigReq { + /** + * Sender(s) / Reciver(s) + */ + // Blocks + friend class Cmvmi; + friend class MgmtSrvr; + friend bool printGET_CONFIG_REQ(FILE *, const Uint32 *, Uint32, Uint16); + + STATIC_CONST( SignalLength = 2 ); + + Uint32 nodeId; // Node id of the receiver node + Uint32 senderRef; +}; + +class GetConfigRef { + /** + * Sender/Receiver + */ + friend class Cmvmi; + friend class MgmtSrvr; + friend bool printGET_CONFIG_REF(FILE *, const Uint32 *, Uint32, Uint16); + + STATIC_CONST( SignalLength = 1 ); + + Uint32 error; + + enum ErrorCode { + WrongSender = 1, + WrongNodeId = 2, + NoConfig = 3 + }; +}; + +class GetConfigConf { + /** + * Sender(s) / Reciver(s) + */ + // Blocks + friend class Cmvmi; + friend class MgmtSrvr; + friend bool printGET_CONFIG_CONF(FILE *, const Uint32 *, Uint32, Uint16); + + STATIC_CONST( SignalLength = 1 ); + + Uint32 configLength; // config blob size +}; +#endif === modified file 'storage/ndb/include/kernel/signaldata/SignalData.hpp' --- a/storage/ndb/include/kernel/signaldata/SignalData.hpp 2011-05-19 09:16:32 +0000 +++ b/storage/ndb/include/kernel/signaldata/SignalData.hpp 2011-07-01 17:15:00 +0000 @@ -317,4 +317,8 @@ GSN_PRINT_SIGNATURE(printINDEX_STAT_IMPL GSN_PRINT_SIGNATURE(printINDEX_STAT_IMPL_REF); GSN_PRINT_SIGNATURE(printINDEX_STAT_REP); +GSN_PRINT_SIGNATURE(printGET_CONFIG_REQ); +GSN_PRINT_SIGNATURE(printGET_CONFIG_REF); +GSN_PRINT_SIGNATURE(printGET_CONFIG_CONF); + #endif === modified file 'storage/ndb/include/mgmapi/mgmapi.h' --- a/storage/ndb/include/mgmapi/mgmapi.h 2011-06-21 13:10:37 +0000 +++ b/storage/ndb/include/mgmapi/mgmapi.h 2011-07-01 17:15:00 +0000 @@ -710,6 +710,18 @@ extern "C" { int num_args, struct ndb_mgm_reply* reply); + /** + * Get the current configuration from a node. + * + * @param handle the NDB management handle. + * @param nodeId of the node for which the configuration is requested. + * @return the current configuration from the requested node. + */ + struct ndb_mgm_configuration * + ndb_mgm_get_configuration_from_node(NdbMgmHandle handle, + int nodeid); + + /** @} *********************************************************************/ /** * @name Functions: Start/stop nodes === modified file 'storage/ndb/include/ndb_version.h.in' --- a/storage/ndb/include/ndb_version.h.in 2011-05-25 13:19:02 +0000 +++ b/storage/ndb/include/ndb_version.h.in 2011-07-01 17:15:00 +0000 @@ -676,4 +676,21 @@ ndb_refresh_tuple(Uint32 x) } } +#define NDBD_GET_CONFIG_SUPPORT_70 NDB_MAKE_VERSION(7,0,27) +#define NDBD_GET_CONFIG_SUPPORT_71 NDB_MAKE_VERSION(7,1,16) + +static +inline +int +ndbd_get_config_supported(Uint32 x) +{ + const Uint32 major = (x >> 16) & 0xFF; + const Uint32 minor = (x >> 8) & 0xFF; + + if (major == 7 && minor == 0) + return x >= NDBD_GET_CONFIG_SUPPORT_70; + + return x >= NDBD_GET_CONFIG_SUPPORT_71; +} + #endif === modified file 'storage/ndb/src/common/debugger/signaldata/CMakeLists.txt' --- a/storage/ndb/src/common/debugger/signaldata/CMakeLists.txt 2011-06-21 13:58:00 +0000 +++ b/storage/ndb/src/common/debugger/signaldata/CMakeLists.txt 2011-07-01 17:15:00 +0000 @@ -45,5 +45,5 @@ ADD_CONVENIENCE_LIBRARY(ndbsignaldata ScanFrag.cpp ApiVersion.cpp LocalRouteOrd.cpp DbinfoScan.cpp NodePing.cpp - IndexStatSignal.cpp) + IndexStatSignal.cpp GetConfig.cpp) === added file 'storage/ndb/src/common/debugger/signaldata/GetConfig.cpp' --- a/storage/ndb/src/common/debugger/signaldata/GetConfig.cpp 1970-01-01 00:00:00 +0000 +++ b/storage/ndb/src/common/debugger/signaldata/GetConfig.cpp 2011-07-01 17:15:00 +0000 @@ -0,0 +1,48 @@ +/* + Copyright (c) 2011, 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 St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +bool +printGET_CONFIG_REQ(FILE * output, const Uint32 * theData, + Uint32 len, Uint16 receiverBlockNo) +{ + const GetConfigReq* sig = (const GetConfigReq*)theData; + fprintf(output, " nodeId : %u senderRef : %x\n", + sig->nodeId, + sig->senderRef); + return true; +} + +bool +printGET_CONFIG_REF(FILE * output, const Uint32 * theData, + Uint32 len, Uint16 receiverBlockNo) { + const GetConfigRef* sig = (const GetConfigRef*)theData; + fprintf(output, " error : %u\n", + sig->error); + return true; +} + + +bool +printGET_CONFIG_CONF(FILE * output, const Uint32 * theData, + Uint32 len, Uint16 receiverBlockNo) { + const GetConfigConf* sig = (const GetConfigConf*)theData; + fprintf(output, " Config size : %u\n", + sig->configLength); + return true; +} === modified file 'storage/ndb/src/common/debugger/signaldata/Makefile.am' --- a/storage/ndb/src/common/debugger/signaldata/Makefile.am 2011-05-19 09:16:32 +0000 +++ b/storage/ndb/src/common/debugger/signaldata/Makefile.am 2011-07-01 17:15:00 +0000 @@ -47,7 +47,7 @@ libsignaldataprint_la_SOURCES = \ CreateIndxImpl.cpp DropIndxImpl.cpp AlterIndxImpl.cpp \ BuildIndx.cpp BuildIndxImpl.cpp ApiVersion.cpp \ LocalRouteOrd.cpp DbinfoScan.cpp NodePing.cpp \ - IndexStatSignal.cpp + IndexStatSignal.cpp GetConfig.cpp include $(top_srcdir)/storage/ndb/config/common.mk.am include $(top_srcdir)/storage/ndb/config/type_ndbapi.mk.am === modified file 'storage/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp' --- a/storage/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp 2011-05-19 09:16:32 +0000 +++ b/storage/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp 2011-07-01 17:15:00 +0000 @@ -268,6 +268,10 @@ SignalDataPrintFunctions[] = { ,{ GSN_INDEX_STAT_IMPL_REF, printINDEX_STAT_IMPL_REF } ,{ GSN_INDEX_STAT_REP, printINDEX_STAT_REP } + ,{ GSN_GET_CONFIG_REQ, printGET_CONFIG_REQ } + ,{ GSN_GET_CONFIG_REF, printGET_CONFIG_REF } + ,{ GSN_GET_CONFIG_CONF, printGET_CONFIG_CONF } + ,{ 0, 0 } }; === modified file 'storage/ndb/src/common/debugger/signaldata/SignalNames.cpp' --- a/storage/ndb/src/common/debugger/signaldata/SignalNames.cpp 2011-05-19 09:16:32 +0000 +++ b/storage/ndb/src/common/debugger/signaldata/SignalNames.cpp 2011-07-01 17:15:00 +0000 @@ -771,5 +771,9 @@ const GsnName SignalNames [] = { ,{ GSN_INDEX_STAT_IMPL_CONF, "INDEX_STAT_IMPL_CONF" } ,{ GSN_INDEX_STAT_IMPL_REF, "INDEX_STAT_IMPL_REF" } ,{ GSN_INDEX_STAT_REP, "INDEX_STAT_REP" } + + ,{ GSN_GET_CONFIG_REQ, "GET_CONFIG_REQ" } + ,{ GSN_GET_CONFIG_REF, "GET_CONFIG_REF" } + ,{ GSN_GET_CONFIG_CONF, "GET_CONFIG_CONF" } }; const unsigned short NO_OF_SIGNAL_NAMES = sizeof(SignalNames)/sizeof(GsnName); === modified file 'storage/ndb/src/common/mgmcommon/ConfigRetriever.cpp' --- a/storage/ndb/src/common/mgmcommon/ConfigRetriever.cpp 2011-02-01 23:27:25 +0000 +++ b/storage/ndb/src/common/mgmcommon/ConfigRetriever.cpp 2011-07-01 17:15:00 +0000 @@ -170,10 +170,12 @@ ConfigRetriever::getConfig(Uint32 nodeid ndb_mgm_configuration * ConfigRetriever::getConfig(NdbMgmHandle mgm_handle) { + const int from_node = 0; ndb_mgm_configuration * conf = ndb_mgm_get_configuration2(mgm_handle, m_version, - m_node_type); + m_node_type, + from_node); if(conf == 0) { BaseString tmp(ndb_mgm_get_latest_error_msg(mgm_handle)); === modified file 'storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp' --- a/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp 2011-05-25 15:03:11 +0000 +++ b/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp 2011-07-01 17:15:00 +0000 @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -124,6 +125,8 @@ Cmvmi::Cmvmi(Block_context& ctx) : addRecSignal(GSN_ALLOC_MEM_REF, &Cmvmi::execALLOC_MEM_REF); addRecSignal(GSN_ALLOC_MEM_CONF, &Cmvmi::execALLOC_MEM_CONF); + addRecSignal(GSN_GET_CONFIG_REQ, &Cmvmi::execGET_CONFIG_REQ); + subscriberPool.setSize(5); c_syncReqPool.setSize(5); @@ -3171,3 +3174,57 @@ Cmvmi::execROUTE_ORD(Signal* signal) warningEvent("Unable to route GSN: %d from %x to %x", gsn, srcRef, dstRef); } + + +void Cmvmi::execGET_CONFIG_REQ(Signal *signal) +{ + jamEntry(); + const GetConfigReq* const req = (const GetConfigReq *)signal->getDataPtr(); + + Uint32 error = 0; + Uint32 retRef = req->senderRef; // mgm servers ref + + if (retRef != signal->header.theSendersBlockRef) + { + error = GetConfigRef::WrongSender; + } + + if (req->nodeId != getOwnNodeId()) + { + error = GetConfigRef::WrongNodeId; + } + + const Uint32 config_length = m_ctx.m_config.m_clusterConfigPacked.length(); + if (config_length == 0) + { + error = GetConfigRef::NoConfig; + } + + if (error) + { + warningEvent("execGET_CONFIG_REQ: failed %u", error); + GetConfigRef *ref = (GetConfigRef *)signal->getDataPtrSend(); + ref->error = error; + sendSignal(retRef, GSN_GET_CONFIG_REF, signal, + GetConfigRef::SignalLength, JBB); + return; + } + + const Uint32 nSections= 1; + LinearSectionPtr ptr[3]; + ptr[0].p = (Uint32*)(m_ctx.m_config.m_clusterConfigPacked.get_data()); + ptr[0].sz = (config_length + 3) / 4; + + GetConfigConf *conf = (GetConfigConf *)signal->getDataPtrSend(); + + conf->configLength = config_length; + + sendFragmentedSignal(retRef, + GSN_GET_CONFIG_CONF, + signal, + GetConfigConf::SignalLength, + JBB, + ptr, + nSections, + TheEmptyCallback); +} === modified file 'storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.hpp' --- a/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.hpp 2011-02-01 23:27:25 +0000 +++ b/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.hpp 2011-07-01 17:15:00 +0000 @@ -78,6 +78,8 @@ private: void execALLOC_MEM_REF(Signal*); void execALLOC_MEM_CONF(Signal*); + void execGET_CONFIG_REQ(Signal*); + char theErrorMessage[256]; void sendSTTORRY(Signal* signal); === modified file 'storage/ndb/src/kernel/vm/Configuration.cpp' --- a/storage/ndb/src/kernel/vm/Configuration.cpp 2011-04-12 11:59:36 +0000 +++ b/storage/ndb/src/kernel/vm/Configuration.cpp 2011-07-01 17:15:00 +0000 @@ -32,6 +32,8 @@ #include #include +#include + #include #include @@ -191,6 +193,9 @@ Configuration::fetch_configuration(const m_clusterConfig = p; + const ConfigValues * cfg = (ConfigValues*)m_clusterConfig; + cfg->pack(m_clusterConfigPacked); + { Uint32 generation; ndb_mgm_configuration_iterator sys_iter(*p, CFG_SECTION_SYSTEM); === modified file 'storage/ndb/src/kernel/vm/Configuration.hpp' --- a/storage/ndb/src/kernel/vm/Configuration.hpp 2011-04-12 11:59:36 +0000 +++ b/storage/ndb/src/kernel/vm/Configuration.hpp 2011-07-01 17:15:00 +0000 @@ -26,6 +26,7 @@ #include #include #include +#include enum ThreadTypes { @@ -147,6 +148,7 @@ private: ndb_mgm_configuration * m_ownConfig; ndb_mgm_configuration * m_clusterConfig; + UtilBuffer m_clusterConfigPacked; ndb_mgm_configuration_iterator * m_clusterConfigIter; ndb_mgm_configuration_iterator * m_ownConfigIterator; === modified file 'storage/ndb/src/mgmapi/mgmapi.cpp' --- a/storage/ndb/src/mgmapi/mgmapi.cpp 2011-06-21 13:10:37 +0000 +++ b/storage/ndb/src/mgmapi/mgmapi.cpp 2011-07-01 17:15:00 +0000 @@ -2068,6 +2068,15 @@ ndb_mgm_dump_state(NdbMgmHandle handle, } extern "C" +struct ndb_mgm_configuration * +ndb_mgm_get_configuration_from_node(NdbMgmHandle handle, + int nodeid) +{ + return ndb_mgm_get_configuration2(handle, 0, + NDB_MGM_NODE_TYPE_UNKNOWN, nodeid); +} + +extern "C" int ndb_mgm_start_signallog(NdbMgmHandle handle, int nodeId, struct ndb_mgm_reply* reply) @@ -2466,7 +2475,7 @@ ndb_mgm_abort_backup(NdbMgmHandle handle extern "C" struct ndb_mgm_configuration * ndb_mgm_get_configuration2(NdbMgmHandle handle, unsigned int version, - enum ndb_mgm_node_type nodetype) + enum ndb_mgm_node_type nodetype, int from_node) { DBUG_ENTER("ndb_mgm_get_configuration2"); @@ -2487,6 +2496,20 @@ ndb_mgm_get_configuration2(NdbMgmHandle args.put("nodetype", nodetype); } + if (check_version_ge(handle->mgmd_version(), + NDB_MAKE_VERSION(7,1,16), + NDB_MAKE_VERSION(7,0,27), + 0)) + { + args.put("from_node", from_node); + } + else + { + SET_ERROR(handle, NDB_MGM_GET_CONFIG_FAILED, + "The mgm server does not support getting config from_node"); + DBUG_RETURN(0); + } + const ParserRow reply[] = { MGM_CMD("get config reply", NULL, ""), MGM_ARG("result", String, Mandatory, "Error message"), === modified file 'storage/ndb/src/mgmapi/mgmapi_internal.h' --- a/storage/ndb/src/mgmapi/mgmapi_internal.h 2011-02-01 23:27:25 +0000 +++ b/storage/ndb/src/mgmapi/mgmapi_internal.h 2011-07-01 17:15:00 +0000 @@ -94,7 +94,8 @@ extern "C" { struct ndb_mgm_configuration * ndb_mgm_get_configuration2(NdbMgmHandle handle, unsigned version, - enum ndb_mgm_node_type nodetype); + enum ndb_mgm_node_type nodetype, + int from_node = 0); #ifdef __cplusplus === modified file 'storage/ndb/src/mgmsrv/Defragger.hpp' --- a/storage/ndb/src/mgmsrv/Defragger.hpp 2011-02-02 00:40:07 +0000 +++ b/storage/ndb/src/mgmsrv/Defragger.hpp 2011-07-01 17:15:00 +0000 @@ -61,7 +61,14 @@ class Defragger { public: Defragger() {}; - ~Defragger() {}; + ~Defragger() + { + for (size_t i = m_buffers.size(); i > 0; --i) + { + delete m_buffers[i-1]; // free the memory of the fragment + } + // m_buffers will be freed by ~Vector + }; /* return true when complete signal received @@ -113,13 +120,12 @@ public: clear any unassembled signal buffers from node */ void node_failed(NodeId nodeId) { - for (size_t i = 0; i < m_buffers.size(); i++) + for (size_t i = m_buffers.size(); i > 0; --i) { - DefragBuffer* dbuf = m_buffers[i]; - if (dbuf->m_node_id == nodeId) + if (m_buffers[i-1]->m_node_id == nodeId) { - delete dbuf; // MASV ? - m_buffers.erase(i); + delete m_buffers[i]; // free the memory of the signal fragment + m_buffers.erase(i); // remove the reference from the vector. } } } === modified file 'storage/ndb/src/mgmsrv/MgmtSrvr.cpp' --- a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp 2011-06-27 06:26:01 +0000 +++ b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp 2011-07-01 17:15:00 +0000 @@ -21,6 +21,7 @@ #include "ndb_mgmd_error.h" #include "Services.hpp" #include "ConfigManager.hpp" +#include "Defragger.hpp" #include #include @@ -43,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -737,6 +739,159 @@ MgmtSrvr::get_packed_config(ndb_mgm_node return m_config_manager->get_packed_config(node_type, &buf64, error); } +bool +MgmtSrvr::get_packed_config_from_node(NodeId nodeId, + BaseString& buf64, BaseString& error) +{ + DBUG_ENTER("get_packed_config_from_node"); + + if (nodeId >= MAX_NODES_ID) + { + error.assfmt("Nodeid %d is greater than max nodeid %d. ", + nodeId, MAX_NODES_ID); + DBUG_RETURN(false); + } + + if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_UNKNOWN) + { + error.assfmt("Nodeid %d does not exist. ", nodeId); + DBUG_RETURN(false); + } + + if (getNodeType(nodeId) != NDB_MGM_NODE_TYPE_NDB) + { + error.assfmt("Node %d is not an NDB node. ", nodeId); + DBUG_RETURN(false); + } + + trp_node node = getNodeInfo(nodeId); + + if (!node.m_alive) + { + error.assfmt("Data node %d is not alive. ", nodeId); + DBUG_RETURN(false); + } + + const Uint32 version = node.m_info.m_version; + + if (!ndbd_get_config_supported(version)) + { + error.assfmt("Data node %d (version %d.%d.%d) does not support getting config. ", + nodeId, ndbGetMajor(version), + ndbGetMinor(version), ndbGetBuild(version)); + DBUG_RETURN(false); + } + + INIT_SIGNAL_SENDER(ss,nodeId); + + SimpleSignal ssig; + GetConfigReq* req = CAST_PTR(GetConfigReq, ssig.getDataPtrSend()); + req->senderRef = ss.getOwnRef(); + req->nodeId = nodeId; + + g_eventLogger->debug("Sending GET_CONFIG_REQ to %d", nodeId); + + ssig.set(ss, TestOrd::TraceAPI, CMVMI, GSN_GET_CONFIG_REQ, + GetConfigReq::SignalLength); + if ((ss.sendSignal(nodeId, &ssig)) != SEND_OK) + { + DBUG_RETURN(false); + } + + Defragger defragger; + while (true) + { + SimpleSignal *signal = ss.waitFor(); + int gsn = signal->readSignalNumber(); + + switch (gsn) + { + case GSN_GET_CONFIG_CONF: + { + if (refToNode(signal->header.theSendersBlockRef) != nodeId) + { + error.assfmt("Internal Error: Reply from wrong node %d, expected from %d. ", + refToNode(signal->header.theSendersBlockRef), + nodeId); + DBUG_RETURN(false); + } + + const GetConfigConf * const conf = + CAST_CONSTPTR(GetConfigConf, signal->getDataPtr()); + + if (signal->header.m_noOfSections != 1) + { + error.assfmt("Internal Error: Wrong number of sections %d received, expected %d. ", + signal->header.m_noOfSections, 1); + DBUG_RETURN(false); + } + + if (defragger.defragment(signal)) + { + ConfigValuesFactory cf; + require(cf.unpack(signal->ptr[0].p, conf->configLength)); + + Config received_config(cf.getConfigValues()); + if (!received_config.pack64(buf64)) + { + error.assign("Failed to pack64"); + DBUG_RETURN(false); + } + DBUG_RETURN(true); + } + // wait until all fragments are received + continue; + } + + case GSN_GET_CONFIG_REF: + { + if (refToNode(ssig.header.theSendersBlockRef) != nodeId) + { + error.assfmt("Internal Error: Reply from wrong node %d, expected from %d. ", + refToNode(signal->header.theSendersBlockRef), + nodeId); + DBUG_RETURN(false); + } + const GetConfigRef * const ref = + CAST_CONSTPTR(GetConfigRef, signal->getDataPtr()); + error.assfmt("Error in retrieving config from node %d: Internal error: %d", + nodeId, ref->error); + + DBUG_RETURN(false); + } + + case GSN_NF_COMPLETEREP: + { + const NFCompleteRep * rep = CAST_CONSTPTR(NFCompleteRep, + signal->getDataPtr()); + if (rep->failedNodeId == nodeId) + { + error.assfmt("Node %d is not available", nodeId); + DBUG_RETURN(false); + } + continue; + } + + case GSN_NODE_FAILREP: + { + // Wait until GSN_NODE_COMPLETEREP is received. + continue; + } + + case GSN_API_REGCONF: + case GSN_TAKE_OVERTCCONF: + case GSN_CONNECT_REP: + // Ignore + continue; + + default: + report_unknown_signal(signal); + DBUG_RETURN(SEND_OR_RECEIVE_FAILED); + } + } + // Should never come here + require(false); +} MgmtSrvr::~MgmtSrvr() { @@ -3957,7 +4112,7 @@ MgmtSrvr::change_config(Config& new_conf case GSN_NF_COMPLETEREP: { NodeId nodeId = refToNode(signal->header.theSendersBlockRef); - msg.assign("Node %d failed uring configuration change", nodeId); + msg.assign("Node %d failed during configuration change", nodeId); return false; break; } === modified file 'storage/ndb/src/mgmsrv/MgmtSrvr.hpp' --- a/storage/ndb/src/mgmsrv/MgmtSrvr.hpp 2011-06-21 13:10:37 +0000 +++ b/storage/ndb/src/mgmsrv/MgmtSrvr.hpp 2011-07-01 17:15:00 +0000 @@ -488,6 +488,10 @@ public: bool get_packed_config(ndb_mgm_node_type nodetype, BaseString& buf64, BaseString& error); + /* Get copy of configuration packed with base64 from node nodeid */ + bool get_packed_config_from_node(NodeId nodeid, + BaseString& buf64, BaseString& error); + void print_config(const char* section_filter = NULL, NodeId nodeid_filter = 0, const char* param_filter = NULL, === modified file 'storage/ndb/src/mgmsrv/Services.cpp' --- a/storage/ndb/src/mgmsrv/Services.cpp 2011-06-01 07:40:49 +0000 +++ b/storage/ndb/src/mgmsrv/Services.cpp 2011-07-01 17:15:00 +0000 @@ -126,6 +126,7 @@ ParserRow commands[] = { MGM_ARG("version", Int, Mandatory, "Configuration version number"), MGM_ARG("node", Int, Optional, "Node ID"), MGM_ARG("nodetype", Int, Optional, "Type of requesting node"), + MGM_ARG("from_node", Int, Optional, "Node to get config from"), MGM_CMD("get nodeid", &MgmApiSession::get_nodeid, ""), MGM_ARG("version", Int, Mandatory, "Configuration version number"), @@ -608,10 +609,12 @@ MgmApiSession::getConfig(Parser_t::Conte const class Properties &args) { Uint32 nodetype = NDB_MGM_NODE_TYPE_UNKNOWN; + Uint32 from_node = 0; // Ignoring mandatory parameter "version" // Ignoring optional parameter "node" args.get("nodetype", &nodetype); + args.get("from_node", &from_node); SLEEP_ERROR_INSERTED(1); m_output->println("get config reply"); @@ -619,8 +622,14 @@ MgmApiSession::getConfig(Parser_t::Conte BaseString pack64, error; UtilBuffer packed; - if (!m_mgmsrv.get_packed_config((ndb_mgm_node_type)nodetype, - pack64, error)) + + bool success = + (from_node == 0 || from_node == m_mgmsrv.getOwnNodeId()) ? + m_mgmsrv.get_packed_config((ndb_mgm_node_type)nodetype, + pack64, error) : + m_mgmsrv.get_packed_config_from_node(from_node, + pack64, error); + if (!success) { m_output->println("result: %s", error.c_str()); m_output->print("\n"); === modified file 'storage/ndb/test/ndbapi/testMgm.cpp' --- a/storage/ndb/test/ndbapi/testMgm.cpp 2011-02-22 08:40:01 +0000 +++ b/storage/ndb/test/ndbapi/testMgm.cpp 2011-07-01 17:15:00 +0000 @@ -23,6 +23,7 @@ #include #include #include +#include /* Tests that only need the mgmd(s) started @@ -714,6 +715,174 @@ int runGetConfigUntilStopped(NDBT_Contex } +// Find a random node of a given type. + +static bool +get_nodeid_of_type(NdbMgmd& mgmd, ndb_mgm_node_type type, int *nodeId) +{ + ndb_mgm_node_type + node_types[2] = { type, + NDB_MGM_NODE_TYPE_UNKNOWN }; + + ndb_mgm_cluster_state *cs = ndb_mgm_get_status2(mgmd.handle(), node_types); + if (cs == NULL) + { + g_err << "ndb_mgm_get_status2 failed, error: " + << ndb_mgm_get_latest_error(mgmd.handle()) << " " + << ndb_mgm_get_latest_error_msg(mgmd.handle()) << endl; + return false; + } + + int noOfNodes = cs->no_of_nodes; + int randomnode = myRandom48(noOfNodes); + ndb_mgm_node_state *ns = cs->node_states + randomnode; + assert(ns->node_type == (Uint32)type); + assert(ns->node_id); + + *nodeId = ns->node_id; + g_info << "Got node id " << *nodeId << " of type " << type << endl; + + free(cs); + return true; +} + + +// Ensure getting config from an illegal node fails. +// Return true in that case. + +static bool +get_config_from_illegal_node(NdbMgmd& mgmd, int nodeId) +{ + struct ndb_mgm_configuration* conf= + ndb_mgm_get_configuration_from_node(mgmd.handle(), nodeId); + + // Get conf from an illegal node should fail. + if (ndb_mgm_get_latest_error(mgmd.handle()) != NDB_MGM_GET_CONFIG_FAILED) + { + g_err << "ndb_mgm_get_configuration from illegal node " + << nodeId << " not failed, error: " + << ndb_mgm_get_latest_error(mgmd.handle()) << " " + << ndb_mgm_get_latest_error_msg(mgmd.handle()) << endl; + return false; + } + + if (conf) + { + // Should not get a conf from an illegal node. + g_err << "ndb_mgm_get_configuration from illegal node: " + << nodeId << ", error: " + << ndb_mgm_get_latest_error(mgmd.handle()) << " " + << ndb_mgm_get_latest_error_msg(mgmd.handle()) << endl; + free(conf); + return false; + } + return true; +} + + +// Check get_config from a non-existing node fails. + +static bool +check_get_config_illegal_node(NdbMgmd& mgmd) +{ + // Find a node that does not exist + Config conf; + if (!mgmd.get_config(conf)) + return false; + + int nodeId = 0; + for(Uint32 i= 1; i < MAX_NODES; i++){ + ConfigIter iter(&conf, CFG_SECTION_NODE); + if (iter.find(CFG_NODE_ID, i) != 0){ + nodeId = i; + break; + } + } + if (nodeId == 0) + return true; // All nodes probably defined + + return get_config_from_illegal_node(mgmd, nodeId); +} + + + +// Check get_config from a non-NDB/MGM node type fails + +static bool +check_get_config_wrong_type(NdbMgmd& mgmd) +{ + int nodeId = 0; + + if (get_nodeid_of_type(mgmd, NDB_MGM_NODE_TYPE_API, &nodeId)) + { + return get_config_from_illegal_node(mgmd, nodeId); + } + // No API nodes found. + return true; +} + +/* Find management node or a random data node, and get config from it. + * Also ensure failure when getting config from + * an illegal node (a non-NDB/MGM type, nodeid not defined, + * or nodeid > MAX_NODES). + */ +int runGetConfigFromNode(NDBT_Context* ctx, NDBT_Step* step) +{ + NdbMgmd mgmd; + if (!mgmd.connect()) + return NDBT_FAILED; + + if (!check_get_config_wrong_type(mgmd) || + !check_get_config_illegal_node(mgmd) || + !get_config_from_illegal_node(mgmd, MAX_NODES + 2)) + { + return NDBT_FAILED; + } + + int loops= ctx->getNumLoops(); + for (int l= 0; l < loops; l++) + { + /* Get config from a node of type: + * NDB_MGM_NODE_TYPE_NDB or NDB_MGM_NODE_TYPE_MGM + */ + int myChoice = myRandom48(2); + ndb_mgm_node_type randomAllowedType = (myChoice) ? + NDB_MGM_NODE_TYPE_NDB : + NDB_MGM_NODE_TYPE_MGM; + int nodeId = 0; + if (get_nodeid_of_type(mgmd, randomAllowedType, &nodeId)) + { + struct ndb_mgm_configuration* conf = + ndb_mgm_get_configuration_from_node(mgmd.handle(), nodeId); + if (!conf) + { + g_err << "ndb_mgm_get_configuration_from_node " + << nodeId << " failed, error: " + << ndb_mgm_get_latest_error(mgmd.handle()) << " " + << ndb_mgm_get_latest_error_msg(mgmd.handle()) << endl; + return NDBT_FAILED; + } + free(conf); + } + else + { + // ignore + } + } + return NDBT_OK; +} + + +int runGetConfigFromNodeUntilStopped(NDBT_Context* ctx, NDBT_Step* step) +{ + int result= NDBT_OK; + while(!ctx->isTestStopped() && + (result= runGetConfigFromNode(ctx, step)) == NDBT_OK) + ; + return result; +} + + int runTestStatus(NDBT_Context* ctx, NDBT_Step* step) { ndb_mgm_node_type types[2] = { @@ -2659,6 +2828,7 @@ TESTCASE("Stress", STEP(runTestGetNodeIdUntilStopped); STEP(runSetConfigUntilStopped); STEPS(runGetConfigUntilStopped, 10); + STEPS(runGetConfigFromNodeUntilStopped, 10); STEPS(runTestStatusUntilStopped, 10); STEPS(runTestGetVersionUntilStopped, 5); STEP(runSleepAndStop); @@ -2668,6 +2838,7 @@ TESTCASE("Stress2", STEP(runTestGetNodeIdUntilStopped); STEPS(runTestSetConfigParallelUntilStopped, 5); STEPS(runGetConfigUntilStopped, 10); + STEPS(runGetConfigFromNodeUntilStopped, 10); STEPS(runTestStatusUntilStopped, 10); STEPS(runTestGetVersionUntilStopped, 5); STEP(runSleepAndStop); === modified file 'storage/ndb/tools/ndb_config.cpp' --- a/storage/ndb/tools/ndb_config.cpp 2011-05-24 11:51:39 +0000 +++ b/storage/ndb/tools/ndb_config.cpp 2011-07-01 17:15:00 +0000 @@ -16,7 +16,45 @@ */ /** - * ndb_config --nodes --query=nodeid --type=ndbd --host=local1 + * Description of config variables, including their min, max, default + * values can be printed (--configinfo). This can also be printed + * in xml format (--xml). + * + * Config can be retrieved from only one of the following sources: + ** config stored at mgmd (default. The options --config_from_node=0, + ** or --config_from_node=1 also give the same results.) + ** config stored at a data node (--config_from_node) + ** my.cnf (--mycnf=) + ** config.file (--config_file= + * + * Config variables are displayed from only one of the following + * sections of the retrieved config: + ** CFG_SECTION_NODE (default, or --nodes) + ** CFG_SECTION_CONNECTION (--connections) + ** CFG_SECTION_SYSTEM (--system) + */ + +/** + * Examples: + * Get config from mgmd (default): + ** Display results from section CFG_SECTION_NODE (default) + *** ndb_config --nodes --query=nodeid --type=ndbd --host=local1 + *** ndb_config --query=nodeid,host + * + ** Display results from section CFG_SECTION_SYSTEM + *** ndb_config --system --query=ConfigGenerationNumber + * + ** Display results from section CFG_SECTION_CONNECTION + *** ndb_config --connections --query=type + * + * Get config from eg. node 2, which is a data node: + * + ** ndb_config --config_from_node=2 --system --query=ConfigGenerationNumber + ** ndb_config --config_from_node=2 --connections --query=type + ** ndb_config --config_from_node=2 --query=id,NoOfFragmentLogFiles + * + ** Display results for only node 2: + *** ndb_config --config_from_node=2 --query=id,NoOfFragmentLogFiles --nodeid=2 */ #include @@ -36,7 +74,7 @@ static int g_verbose = 0; static int try_reconnect = 3; -static int g_nodes, g_connections, g_section; +static int g_nodes, g_connections, g_system, g_section; static const char * g_query = 0; static int g_nodeid = 0; @@ -48,6 +86,7 @@ static const char * g_config_file = 0; static int g_mycnf = 0; static int g_configinfo = 0; static int g_xml = 0; +static int g_config_from_node = 0; const char *load_default_groups[]= { "mysql_cluster",0 }; @@ -62,6 +101,9 @@ static struct my_option my_long_options[ { "connections", NDB_OPT_NOSHORT, "Print connections", (uchar**) &g_connections, (uchar**) &g_connections, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + { "system", NDB_OPT_NOSHORT, "Print system", + (uchar**) &g_system, (uchar**) &g_system, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, { "query", 'q', "Query option(s)", (uchar**) &g_query, (uchar**) &g_query, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -95,6 +137,9 @@ static struct my_option my_long_options[ { "xml", NDB_OPT_NOSHORT, "Print configinfo in xml format", (uchar**) &g_xml, (uchar**) &g_xml, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + { "config_from_node", NDB_OPT_NOSHORT, "Use current config from node with given nodeid", + (uchar**) &g_config_from_node, (uchar**) &g_config_from_node, + 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -154,7 +199,7 @@ static int parse_query(Vector&, static int parse_where(Vector&, int &argc, char**& argv); static int eval(const Iter&, const Vector&); static int apply(const Iter&, const Vector&); -static ndb_mgm_configuration* fetch_configuration(); +static ndb_mgm_configuration* fetch_configuration(int from_node); static ndb_mgm_configuration* load_configuration(); @@ -178,23 +223,47 @@ main(int argc, char** argv){ exit(0); } - if (g_nodes && g_connections) + if ((g_nodes && g_connections) || + g_system && (g_nodes || g_connections)) { fprintf(stderr, - "Only one option of --nodes and --connections allowed\n"); + "Error: Only one of the section-options: --nodes, --connections, --system is allowed.\n"); + exit(255); + } + + /* There is no explicit option for the user to set + * 'retrieving config from mgmd', but this is the default. + * Therefore will not contradict with other sources. + */ + + if ((g_config_file && g_mycnf) || + g_config_from_node && (g_config_file || g_mycnf)) + { + fprintf(stderr, + "Error: Config should be retrieved from only one of the following sources:\n"); + fprintf(stderr, + "\tconfig stored at mgmd (default),\n"); + fprintf(stderr, + "\tconfig stored at a data node (--config_from_node=), \n"); + fprintf(stderr, + "\tmy.cnf(--mycnf=),\n"); + fprintf(stderr, + "\tconfig.file (--config_file=).\n"); exit(255); } g_section = CFG_SECTION_NODE; //default if (g_connections) g_section = CFG_SECTION_CONNECTION; + else if (g_system) + g_section = CFG_SECTION_SYSTEM; ndb_mgm_configuration * conf = 0; if (g_config_file || g_mycnf) conf = load_configuration(); else - conf = fetch_configuration(); + conf = fetch_configuration(g_config_from_node); if (conf == 0) { @@ -289,7 +358,9 @@ parse_query(Vector& select, int (g_section == CFG_SECTION_NODE && (strcmp(ConfigInfo::m_ParamInfo[p]._section, "DB") == 0 || strcmp(ConfigInfo::m_ParamInfo[p]._section, "API") == 0 || - strcmp(ConfigInfo::m_ParamInfo[p]._section, "MGM") == 0))) + strcmp(ConfigInfo::m_ParamInfo[p]._section, "MGM") == 0)) + || + (g_section == CFG_SECTION_SYSTEM)) { if(strcasecmp(ConfigInfo::m_ParamInfo[p]._fname, str) == 0) { @@ -496,8 +567,8 @@ ConnectionTypeApply::apply(const Iter& i } static ndb_mgm_configuration* -fetch_configuration() -{ +fetch_configuration(int from_node) +{ ndb_mgm_configuration* conf = 0; NdbMgmHandle mgm = ndb_mgm_create_handle(); if(mgm == NULL) { @@ -532,11 +603,17 @@ fetch_configuration() ndb_mgm_get_connected_port(mgm)); } - conf = ndb_mgm_get_configuration(mgm, 0); + if (from_node > 1) + { + conf = ndb_mgm_get_configuration_from_node(mgm, from_node); + } + else + conf = ndb_mgm_get_configuration(mgm, 0); + if(conf == 0) { - fprintf(stderr, "Could not get configuration"); - fprintf(stderr, "code: %d, msg: %s\n", + fprintf(stderr, "Could not get configuration, "); + fprintf(stderr, "error code: %d, error msg: %s\n", ndb_mgm_get_latest_error(mgm), ndb_mgm_get_latest_error_msg(mgm)); } No bundle (reason: useless for push emails).