diff options
author | unknown <joreland@mysql.com> | 2004-05-27 11:36:09 +0200 |
---|---|---|
committer | unknown <joreland@mysql.com> | 2004-05-27 11:36:09 +0200 |
commit | 0aee1b0ad6fc959fd10e7fdf96920328aaa5db91 (patch) | |
tree | 25a975842ec69bd8a85ea76406696c8aeb6e0d85 | |
parent | 489aa9be1ce31a0b7f4e8901faa818b21a8f7c7a (diff) | |
parent | d887ce18a45e2211dd9c81e04e0b40cf071da386 (diff) | |
download | mariadb-git-0aee1b0ad6fc959fd10e7fdf96920328aaa5db91.tar.gz |
Merge mysql.com:/home/jonas/src/mysql-4.1-ndb
into mysql.com:/home/jonas/src/mysql-4.1-ndb-jonas
ndb/src/kernel/blocks/dblqh/Dblqh.hpp:
Auto merged
ndb/Epilogue.mk_old:
Auto merged
ndb/src/common/debugger/signaldata/Makefile_old:
Auto merged
ndb/src/common/mgmcommon/Makefile_old:
Auto merged
ndb/src/common/util/Makefile_old:
Auto merged
ndb/src/kernel/Makefile_old:
Auto merged
ndb/src/kernel/blocks/dblqh/DblqhMain.cpp:
Auto merged
ndb/src/kernel/ndb-main/Main.cpp:
Auto merged
ndb/src/kernel/ndb-main/Makefile_old:
Auto merged
ndb/src/kernel/vm/Makefile_old:
Auto merged
ndb/src/mgmapi/Makefile_old:
Auto merged
ndb/src/mgmclient/Makefile_old:
Auto merged
ndb/src/mgmsrv/Makefile_old:
Auto merged
ndb/src/mgmsrv/MgmtSrvr.cpp:
Auto merged
ndb/src/ndbapi/ClusterMgr.cpp:
Auto merged
ndb/src/ndbapi/Makefile_old:
Auto merged
ndb/src/ndbapi/Ndb.cpp:
Auto merged
ndb/src/ndbapi/Ndbif.cpp:
Auto merged
ndb/src/ndbapi/Ndbinit.cpp:
Auto merged
ndb/src/ndbapi/TransporterFacade.cpp:
Auto merged
ndb/src/ndbapi/TransporterFacade.hpp:
Auto merged
ndb/test/ndbapi/testDict.cpp:
Auto merged
ndb/test/ndbapi/testSystemRestart.cpp:
Auto merged
ndb/test/ndbapi/testTimeout.cpp:
Auto merged
ndb/test/src/Makefile_old:
Auto merged
132 files changed, 8394 insertions, 6727 deletions
diff --git a/ndb/Epilogue.mk_old b/ndb/Epilogue.mk_old index bcdc54a87f1..36d9ebd6751 100644 --- a/ndb/Epilogue.mk_old +++ b/ndb/Epilogue.mk_old @@ -90,6 +90,7 @@ CCFLAGS_LOC += \ -I$(call fixpath,$(NDB_TOP)/include/transporter) \ -I$(call fixpath,$(NDB_TOP)/include/debugger) \ -I$(call fixpath,$(NDB_TOP)/include/mgmcommon) \ + -I$(call fixpath,$(NDB_TOP)/include/mgmapi) \ -I$(call fixpath,$(NDB_TOP)/include/ndbapi) \ -I$(call fixpath,$(NDB_TOP)/include/util) \ -I$(call fixpath,$(NDB_TOP)/include/portlib) \ @@ -105,6 +106,7 @@ CCFLAGS_LOC += \ -I$(call fixpath,$(NDB_TOP)/include/transporter) \ -I$(call fixpath,$(NDB_TOP)/include/debugger) \ -I$(call fixpath,$(NDB_TOP)/include/mgmcommon) \ + -I$(call fixpath,$(NDB_TOP)/include/mgmapi) \ -I$(call fixpath,$(NDB_TOP)/include/ndbapi) \ -I$(call fixpath,$(NDB_TOP)/include/util) \ -I$(call fixpath,$(NDB_TOP)/include/portlib) \ diff --git a/ndb/include/kernel/BlockNumbers.h b/ndb/include/kernel/BlockNumbers.h index 84c3fc656a9..e89a82ee0cb 100644 --- a/ndb/include/kernel/BlockNumbers.h +++ b/ndb/include/kernel/BlockNumbers.h @@ -37,6 +37,7 @@ #define DBTUP 0xF9 #define DBDICT 0xFA #define NDBCNTR 0xFB +#define CNTR 0xFB #define QMGR 0xFC #define NDBFS 0xFD #define CMVMI 0xFE diff --git a/ndb/include/kernel/GlobalSignalNumbers.h b/ndb/include/kernel/GlobalSignalNumbers.h index 87385de1f14..7b70f4c3ac0 100644 --- a/ndb/include/kernel/GlobalSignalNumbers.h +++ b/ndb/include/kernel/GlobalSignalNumbers.h @@ -177,43 +177,43 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES; #define GSN_API_FAILCONF 113 #define GSN_API_FAILREQ 114 -#define GSN_APPL_CHANGEREP 115 +#define GSN_CNTR_START_REQ 115 // 116 not unused -#define GSN_APPL_HB 117 -#define GSN_APPL_HBREQ 118 -#define GSN_APPL_REGCONF 119 -#define GSN_APPL_REGREF 120 -#define GSN_APPL_REGREQ 121 -#define GSN_APPL_RUN 122 -#define GSN_APPL_STARTCONF 123 -#define GSN_APPL_STARTREG 124 +#define GSN_CNTR_START_REF 117 +#define GSN_CNTR_START_CONF 118 +#define GSN_CNTR_START_REP 119 +// 120 unused +// 121 unused +// 122 unused +// 123 unused +// 124 unused #define GSN_CHECK_LCP_STOP 125 -#define GSN_CLOSE_COMCONF 126 -#define GSN_CLOSE_COMREQ 127 -#define GSN_CM_ACKADD 128 -#define GSN_CM_ACKALARM 129 -#define GSN_CM_ADD 130 -#define GSN_CM_APPCHG 131 +#define GSN_CLOSE_COMCONF 126 // local +#define GSN_CLOSE_COMREQ 127 // local +#define GSN_CM_ACKADD 128 // distr. +// 129 unused +#define GSN_CM_ADD 130 // distr. +// 131 unused // 132 not unused // 133 not unused -#define GSN_CM_HEARTBEAT 134 -#define GSN_CM_INFOCONF 135 -#define GSN_CM_INFOREQ 136 -#define GSN_CM_INIT 137 -#define GSN_CM_NODEINFOCONF 138 -#define GSN_CM_NODEINFOREF 139 -#define GSN_CM_NODEINFOREQ 140 -#define GSN_CM_REGCONF 141 -#define GSN_CM_REGREF 142 -#define GSN_CM_REGREQ 143 -#define GSN_CM_RUN 144 -#define GSN_CMVMI_CFGCONF 145 -#define GSN_CMVMI_CFGREQ 146 -#define GSN_CNTR_CHANGEREP 147 -#define GSN_CNTR_MASTERCONF 148 -#define GSN_CNTR_MASTERREF 149 -#define GSN_CNTR_MASTERREQ 150 -#define GSN_CNTR_WAITREP 151 +#define GSN_CM_HEARTBEAT 134 // distr. +// 135 unused +// 136 unused +// 137 unused +#define GSN_CM_NODEINFOCONF 138 // distr. +#define GSN_CM_NODEINFOREF 139 // distr. +#define GSN_CM_NODEINFOREQ 140 // distr. +#define GSN_CM_REGCONF 141 // distr. +#define GSN_CM_REGREF 142 // distr. +#define GSN_CM_REGREQ 143 // distr. +// 144 unused +// 145 unused +// 146 unused +#define GSN_CM_ADD_REP 147 // local +// 148 unused +// 149 unused +// 150 unused +#define GSN_CNTR_WAITREP 151 // distr. #define GSN_COMMIT 152 #define GSN_COMMIT_FAILCONF 153 #define GSN_COMMIT_FAILREQ 154 @@ -426,11 +426,13 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES; #define GSN_NEXT_SCANREF 331 #define GSN_NEXT_SCANREQ 332 #define GSN_NEXTOPERATION 333 -#define GSN_SIZEALT_ACK 334 -#define GSN_SIZEALT_REP 335 -#define GSN_NODE_STATESCONF 336 -#define GSN_NODE_STATESREF 337 -#define GSN_NODE_STATESREQ 338 + +#define GSN_READ_CONFIG_REQ 334 // new name for sizealt, local +#define GSN_READ_CONFIG_CONF 335 // new name for sizealt, local + +// 336 unused +// 337 unused +// 338 unused #define GSN_OPEN_COMCONF 339 #define GSN_OPEN_COMREF 340 #define GSN_OPEN_COMREQ 341 @@ -511,8 +513,8 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES; #define GSN_TEST_ORD 407 #define GSN_TESTSIG 408 #define GSN_TIME_SIGNAL 409 -#define GSN_VOTE_MASTERORD 410 -// 411 unused +// 410 unused +// 411 unused // 412 unused #define GSN_TUP_ABORTREQ 414 #define GSN_TUP_ADD_ATTCONF 415 @@ -580,7 +582,7 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES; #define GSN_CHECKNODEGROUPSREQ 471 #define GSN_CHECKNODEGROUPSCONF 472 -#define GSN_ARBIT_CFG 473 +// 473 unused #define GSN_ARBIT_PREPREQ 474 #define GSN_ARBIT_PREPCONF 475 #define GSN_ARBIT_PREPREF 476 diff --git a/ndb/include/kernel/LogLevel.hpp b/ndb/include/kernel/LogLevel.hpp index 3363dc2befd..10cd0d43bee 100644 --- a/ndb/include/kernel/LogLevel.hpp +++ b/ndb/include/kernel/LogLevel.hpp @@ -18,6 +18,7 @@ #define _LOG_LEVEL_HPP #include <ndb_global.h> +#include <mgmapi_config_parameters.h> /** * @@ -45,53 +46,60 @@ public: */ LogLevel & operator= (const LogLevel &); + static const Uint32 MIN_LOGLEVEL_ID = CFG_LOGLEVEL_STARTUP; + enum EventCategory { /** * Events during all kind of startups */ - llStartUp = 0, + llStartUp = CFG_LOGLEVEL_STARTUP - MIN_LOGLEVEL_ID, /** * Events during shutdown */ - llShutdown = 1, + llShutdown = CFG_LOGLEVEL_SHUTDOWN - MIN_LOGLEVEL_ID, /** * Transaction statistics * Job level * TCP/IP speed */ - llStatistic = 2, + llStatistic = CFG_LOGLEVEL_STATISTICS - MIN_LOGLEVEL_ID, /** * Checkpoints */ - llCheckpoint = 3, + llCheckpoint = CFG_LOGLEVEL_CHECKPOINT - MIN_LOGLEVEL_ID, /** * Events during node restart */ - llNodeRestart = 4, + llNodeRestart = CFG_LOGLEVEL_NODERESTART - MIN_LOGLEVEL_ID, /** * Events related to connection / communication */ - llConnection = 5, + llConnection = CFG_LOGLEVEL_CONNECTION - MIN_LOGLEVEL_ID, /** * Assorted event w.r.t unexpected happenings */ - llError = 6, + llError = CFG_LOGLEVEL_ERROR - MIN_LOGLEVEL_ID, + + /** + * Assorted event w.r.t warning + */ + llWarning = CFG_LOGLEVEL_WARNING - MIN_LOGLEVEL_ID, /** * Assorted event w.r.t information */ - llInfo = 7, + llInfo = CFG_LOGLEVEL_INFO - MIN_LOGLEVEL_ID, /** * Events related to global replication */ - llGrep = 8 + llGrep = CFG_LOGLEVEL_GREP - MIN_LOGLEVEL_ID }; struct LogLevelCategoryName { @@ -107,7 +115,7 @@ public: /** * No of categories */ -#define _LOGLEVEL_CATEGORIES 9 +#define _LOGLEVEL_CATEGORIES 10 static const Uint32 LOGLEVEL_CATEGORIES = _LOGLEVEL_CATEGORIES; void clear(); diff --git a/ndb/include/kernel/kernel_config_parameters.h b/ndb/include/kernel/kernel_config_parameters.h new file mode 100644 index 00000000000..2f63efa4b6c --- /dev/null +++ b/ndb/include/kernel/kernel_config_parameters.h @@ -0,0 +1,56 @@ +#ifndef DB_CONFIG_PARAMTERS_H +#define DB_CONFIG_PARAMTERS_H + +#define PRIVATE_BASE 14000 + +#define CFG_ACC_DIR_RANGE (PRIVATE_BASE + 1) +#define CFG_ACC_DIR_ARRAY (PRIVATE_BASE + 2) +#define CFG_ACC_FRAGMENT (PRIVATE_BASE + 3) +#define CFG_ACC_OP_RECS (PRIVATE_BASE + 4) +#define CFG_ACC_OVERFLOW_RECS (PRIVATE_BASE + 5) +#define CFG_ACC_PAGE8 (PRIVATE_BASE + 6) +#define CFG_ACC_ROOT_FRAG (PRIVATE_BASE + 7) +#define CFG_ACC_TABLE (PRIVATE_BASE + 8) +#define CFG_ACC_SCAN (PRIVATE_BASE + 9) + +#define CFG_DICT_ATTRIBUTE (PRIVATE_BASE + 10) +#define CFG_DICT_CONNECT (PRIVATE_BASE + 11) +#define CFG_DICT_FRAG_CONNECT (PRIVATE_BASE + 12) +#define CFG_DICT_TABLE (PRIVATE_BASE + 13) +#define CFG_DICT_TC_CONNECT (PRIVATE_BASE + 14) + +#define CFG_DIH_API_CONNECT (PRIVATE_BASE + 15) +#define CFG_DIH_CONNECT (PRIVATE_BASE + 16) +#define CFG_DIH_FRAG_CONNECT (PRIVATE_BASE + 17) +#define CFG_DIH_MORE_NODES (PRIVATE_BASE + 18) +#define CFG_DIH_REPLICAS (PRIVATE_BASE + 19) +#define CFG_DIH_TABLE (PRIVATE_BASE + 20) + +#define CFG_LQH_FRAG (PRIVATE_BASE + 21) +#define CFG_LQH_CONNECT (PRIVATE_BASE + 22) +#define CFG_LQH_TABLE (PRIVATE_BASE + 23) +#define CFG_LQH_TC_CONNECT (PRIVATE_BASE + 24) +#define CFG_LQH_REPLICAS (PRIVATE_BASE + 25) +#define CFG_LQH_LOG_FILES (PRIVATE_BASE + 26) +#define CFG_LQH_SCAN (PRIVATE_BASE + 27) + +#define CFG_TC_API_CONNECT (PRIVATE_BASE + 28) +#define CFG_TC_TC_CONNECT (PRIVATE_BASE + 29) +#define CFG_TC_TABLE (PRIVATE_BASE + 30) +#define CFG_TC_SCAN (PRIVATE_BASE + 31) +#define CFG_TC_LOCAL_SCAN (PRIVATE_BASE + 32) + +#define CFG_TUP_FRAG (PRIVATE_BASE + 33) +#define CFG_TUP_OP_RECS (PRIVATE_BASE + 34) +#define CFG_TUP_PAGE (PRIVATE_BASE + 35) +#define CFG_TUP_PAGE_RANGE (PRIVATE_BASE + 36) +#define CFG_TUP_TABLE (PRIVATE_BASE + 37) +#define CFG_TUP_TABLE_DESC (PRIVATE_BASE + 38) +#define CFG_TUP_STORED_PROC (PRIVATE_BASE + 39) + +#define CFG_TUX_INDEX (PRIVATE_BASE + 40) +#define CFG_TUX_FRAGMENT (PRIVATE_BASE + 41) +#define CFG_TUX_ATTRIBUTE (PRIVATE_BASE + 42) +#define CFG_TUX_SCAN_OP (PRIVATE_BASE + 43) + +#endif diff --git a/ndb/include/kernel/signaldata/CheckNodeGroups.hpp b/ndb/include/kernel/signaldata/CheckNodeGroups.hpp index 9b2f847e128..b3e79949c68 100644 --- a/ndb/include/kernel/signaldata/CheckNodeGroups.hpp +++ b/ndb/include/kernel/signaldata/CheckNodeGroups.hpp @@ -37,13 +37,11 @@ public: Uint32 requestType; // direct flag, output code Uint32 output; }; - union { - Uint32 nodeId; // nodeId input for GetNodeGroupMembers - NodeBitmask mask; /* set of NDB nodes, input for ArbitCheck, - * output for GetNodeGroupMembers - */ - }; + Uint32 nodeId; // nodeId input for GetNodeGroupMembers + NodeBitmask mask; /* set of NDB nodes, input for ArbitCheck, + * output for GetNodeGroupMembers + */ enum RequestType { Direct = 0x1, ArbitCheck = 0x2, @@ -57,7 +55,7 @@ public: Partitioning = 3 // possible network partitioning }; - STATIC_CONST( SignalLength = 2 + NodeBitmask::Size ); + STATIC_CONST( SignalLength = 3 + NodeBitmask::Size ); }; #endif diff --git a/ndb/include/kernel/signaldata/CntrStart.hpp b/ndb/include/kernel/signaldata/CntrStart.hpp new file mode 100644 index 00000000000..abdd1003c0f --- /dev/null +++ b/ndb/include/kernel/signaldata/CntrStart.hpp @@ -0,0 +1,69 @@ +#ifndef CNTR_START_HPP +#define CNTR_START_HPP + +#include <NodeBitmask.hpp> + +/** + * + */ +class CntrStartReq { + /** + * Sender(s) / Reciver(s) + */ + friend class Ndbcntr; + + friend bool printCNTR_START_REQ(FILE*, const Uint32 *, Uint32, Uint16); + +public: + STATIC_CONST( SignalLength = 3 ); +private: + + Uint32 nodeId; + Uint32 startType; + Uint32 lastGci; +}; + +class CntrStartRef { + /** + * Sender(s) / Reciver(s) + */ + friend class Ndbcntr; + + friend bool printCNTR_START_REF(FILE*, const Uint32 *, Uint32, Uint16); +public: + STATIC_CONST( SignalLength = 2 ); + + enum ErrorCode { + OK = 0, + NotMaster = 1, + StopInProgress = 2 + }; +private: + + Uint32 errorCode; + Uint32 masterNodeId; +}; + +class CntrStartConf { + /** + * Sender(s) / Reciver(s) + */ + friend class Ndbcntr; + friend struct UpgradeStartup; + + friend bool printCNTR_START_CONF(FILE*, const Uint32 *, Uint32, Uint16); + +public: + STATIC_CONST( SignalLength = 4 + 2 * NdbNodeBitmask::Size ); + +private: + + Uint32 startType; + Uint32 startGci; + Uint32 masterNodeId; + Uint32 noStartNodes; + Uint32 startedNodes[NdbNodeBitmask::Size]; + Uint32 startingNodes[NdbNodeBitmask::Size]; +}; + +#endif diff --git a/ndb/include/kernel/signaldata/EventSubscribeReq.hpp b/ndb/include/kernel/signaldata/EventSubscribeReq.hpp index 2ac62be19a3..fd2821ea31d 100644 --- a/ndb/include/kernel/signaldata/EventSubscribeReq.hpp +++ b/ndb/include/kernel/signaldata/EventSubscribeReq.hpp @@ -39,7 +39,7 @@ class EventSubscribeReq { friend class MgmtSrvr; public: - STATIC_CONST( SignalLength = 14 ); + STATIC_CONST( SignalLength = 22 ); private: /** * Note: If you use the same blockRef as you have used earlier, @@ -53,8 +53,8 @@ private: */ Uint32 noOfEntries; - Uint32 theCategories[6]; - Uint32 theLevels[6]; + Uint32 theCategories[10]; + Uint32 theLevels[10]; }; #endif diff --git a/ndb/include/kernel/signaldata/FsOpenReq.hpp b/ndb/include/kernel/signaldata/FsOpenReq.hpp index b84d78ba9dd..906bb947128 100644 --- a/ndb/include/kernel/signaldata/FsOpenReq.hpp +++ b/ndb/include/kernel/signaldata/FsOpenReq.hpp @@ -39,6 +39,7 @@ class FsOpenReq { friend class Backup; friend class Dbdict; friend class Ndbcntr; // For initial start... + friend class Dbdih; /** * For printing diff --git a/ndb/include/kernel/signaldata/ReadConfig.hpp b/ndb/include/kernel/signaldata/ReadConfig.hpp new file mode 100644 index 00000000000..0835b252a32 --- /dev/null +++ b/ndb/include/kernel/signaldata/ReadConfig.hpp @@ -0,0 +1,24 @@ +#ifndef READ_CONFIG_HPP +#define READ_CONFIG_HPP + +/** + */ +class ReadConfigReq { +public: + STATIC_CONST( SignalLength = 3 ); + + Uint32 senderRef; + Uint32 senderData; + Uint32 noOfParameters; // 0 Means read all relevant for block + Uint32 parameters[1]; // see mgmapi_config_parameters.h +}; + +class ReadConfigConf { +public: + STATIC_CONST( SignalLength = 2 ); + + Uint32 senderRef; + Uint32 senderData; +}; + +#endif diff --git a/ndb/include/kernel/signaldata/ReadNodesConf.hpp b/ndb/include/kernel/signaldata/ReadNodesConf.hpp index f3176cbf0e8..0507007f71a 100644 --- a/ndb/include/kernel/signaldata/ReadNodesConf.hpp +++ b/ndb/include/kernel/signaldata/ReadNodesConf.hpp @@ -48,11 +48,13 @@ class ReadNodesConf { friend class Suma; friend class Grep; + friend bool printREAD_NODES_CONF(FILE*, const Uint32 *, Uint32, Uint16); public: - STATIC_CONST( SignalLength = 2 + 6*NodeBitmask::Size ); + STATIC_CONST( SignalLength = 3 + 5*NdbNodeBitmask::Size ); private: Uint32 noOfNodes; + Uint32 ndynamicId; /** * @@ -63,47 +65,21 @@ private: /** * This array defines all the ndb nodes in the system */ - Uint32 allNodes[NodeBitmask::Size]; - - /** - * This array describes wheather the nodes are currently active - * - * NOTE Not valid when send from Qmgr - */ - Uint32 inactiveNodes[NodeBitmask::Size]; + union { + Uint32 allNodes[NdbNodeBitmask::Size]; + Uint32 definedNodes[NdbNodeBitmask::Size]; + }; /** - * This array describes the version id of the nodes - * The version id is a 4 bit number + * This array describes wheather the nodes are currently active * * NOTE Not valid when send from Qmgr */ - Uint32 theVersionIds[4*NodeBitmask::Size]; + Uint32 inactiveNodes[NdbNodeBitmask::Size]; - static void setVersionId(NodeId, Uint8 versionId, Uint32 theVersionIds[]); - static Uint8 getVersionId(NodeId, const Uint32 theVersionIds[]); + Uint32 clusterNodes[NdbNodeBitmask::Size]; // From Qmgr + Uint32 startingNodes[NdbNodeBitmask::Size]; // From Cntr + Uint32 startedNodes[NdbNodeBitmask::Size]; // From Cntr }; -inline -void -ReadNodesConf::setVersionId(NodeId nodeId, Uint8 versionId, - Uint32 theVersionIds[]){ - const int word = nodeId >> 3; - const int shift = (nodeId & 7) << 2; - - const Uint32 mask = ~(((Uint32)15) << shift); - const Uint32 tmp = theVersionIds[word]; - - theVersionIds[word] = (tmp & mask) | ((((Uint32)versionId) & 15) << shift); -} - -inline -Uint8 -ReadNodesConf::getVersionId(NodeId nodeId, const Uint32 theVersionIds[]){ - const int word = nodeId >> 3; - const int shift = (nodeId & 7) << 2; - - return (theVersionIds[word] >> shift) & 15; -} - #endif diff --git a/ndb/include/kernel/signaldata/SetLogLevelOrd.hpp b/ndb/include/kernel/signaldata/SetLogLevelOrd.hpp index 680e9b25a49..c3be808cc41 100644 --- a/ndb/include/kernel/signaldata/SetLogLevelOrd.hpp +++ b/ndb/include/kernel/signaldata/SetLogLevelOrd.hpp @@ -18,6 +18,7 @@ #define SET_LOGLEVEL_ORD_HPP #include <LogLevel.hpp> +#include "SignalData.hpp" /** * diff --git a/ndb/include/kernel/signaldata/UpgradeStartup.hpp b/ndb/include/kernel/signaldata/UpgradeStartup.hpp new file mode 100644 index 00000000000..badc7ca0e4d --- /dev/null +++ b/ndb/include/kernel/signaldata/UpgradeStartup.hpp @@ -0,0 +1,36 @@ +#ifndef NDB_UPGRADE_STARTUP +#define NDB_UPGRADE_STARTUP + +struct UpgradeStartup { + + static void installEXEC(SimulatedBlock*); + + static const Uint32 GSN_CM_APPCHG = 131; + static const Uint32 GSN_CNTR_MASTERCONF = 148; + static const Uint32 GSN_CNTR_MASTERREF = 149; + static const Uint32 GSN_CNTR_MASTERREQ = 150; + + static void sendCmAppChg(Ndbcntr&, Signal *, Uint32 startLevel); + static void execCM_APPCHG(SimulatedBlock& block, Signal*); + static void sendCntrMasterReq(Ndbcntr& cntr, Signal* signal, Uint32 n); + static void execCNTR_MASTER_REPLY(SimulatedBlock & block, Signal* signal); + + struct CntrMasterReq { + STATIC_CONST( SignalLength = 4 + NdbNodeBitmask::Size ); + + Uint32 userBlockRef; + Uint32 userNodeId; + Uint32 typeOfStart; + Uint32 noRestartNodes; + Uint32 theNodes[NdbNodeBitmask::Size]; + }; + + struct CntrMasterConf { + STATIC_CONST( SignalLength = 1 + NdbNodeBitmask::Size ); + + Uint32 noStartNodes; + Uint32 theNodes[NdbNodeBitmask::Size]; + }; +}; + +#endif diff --git a/ndb/include/mgmapi/mgmapi.h b/ndb/include/mgmapi/mgmapi.h index 0ecb19eaa76..7b2f728bda8 100644 --- a/ndb/include/mgmapi/mgmapi.h +++ b/ndb/include/mgmapi/mgmapi.h @@ -84,9 +84,10 @@ extern "C" { NDB_MGM_NODE_TYPE_API = 0, /*/< An application node (API)*/ NDB_MGM_NODE_TYPE_NDB = 1, /*/< A database node (DB)*/ NDB_MGM_NODE_TYPE_MGM = 2, /*/< A management server node (MGM)*/ + NDB_MGM_NODE_TYPE_REP = 3, ///< A replication node NDB_MGM_NODE_TYPE_MIN = 0, /*/< Min valid value*/ - NDB_MGM_NODE_TYPE_MAX = 2 /*/< Max valid value*/ + NDB_MGM_NODE_TYPE_MAX = 3 /*/< Max valid value*/ }; /** @@ -199,6 +200,8 @@ extern "C" { int node_group; ///< Node group of node ///< (only valid for DB nodes) int version; ///< Internal version number + int connect_count; ///< No of times node has connected + ///< or disconnected to the mgm srv }; /** @@ -654,6 +657,36 @@ extern "C" { int ndb_mgm_exit_single_user(NdbMgmHandle handle, struct ndb_mgm_reply* reply); + /** + * Get configuration + * @param handle NDB management handle. + * @param version Version of configuration, 0 means latest + * @see MAKE_VERSION + * @Note the caller must free the pointer returned. + */ + struct ndb_mgm_configuration * ndb_mgm_get_configuration(NdbMgmHandle handle, + unsigned version); + /** + * Config iterator + */ + typedef struct ndb_mgm_configuration_iterator ndb_mgm_configuration_iterator; + + ndb_mgm_configuration_iterator* ndb_mgm_create_configuration_iterator + (struct ndb_mgm_configuration *, unsigned type_of_section); + void ndb_mgm_destroy_iterator(ndb_mgm_configuration_iterator*); + + int ndb_mgm_first(ndb_mgm_configuration_iterator*); + int ndb_mgm_next(ndb_mgm_configuration_iterator*); + int ndb_mgm_valid(const ndb_mgm_configuration_iterator*); + int ndb_mgm_find(ndb_mgm_configuration_iterator*, + int param, unsigned value); + + int ndb_mgm_get_int_parameter(const ndb_mgm_configuration_iterator*, + int param, unsigned * value); + int ndb_mgm_get_int64_parameter(const ndb_mgm_configuration_iterator*, + int param, unsigned long long * value); + int ndb_mgm_get_string_parameter(const ndb_mgm_configuration_iterator*, + int param, const char ** value); #ifdef __cplusplus } #endif diff --git a/ndb/include/mgmapi/mgmapi_config_parameters.h b/ndb/include/mgmapi/mgmapi_config_parameters.h new file mode 100644 index 00000000000..9ad0967854f --- /dev/null +++ b/ndb/include/mgmapi/mgmapi_config_parameters.h @@ -0,0 +1,142 @@ +#ifndef MGMAPI_CONFIG_PARAMTERS_H +#define MGMAPI_CONFIG_PARAMTERS_H + + +#define CFG_SYS_NAME 3 +#define CFG_SYS_PRIMARY_MGM_NODE 1 +#define CFG_SYS_CONFIG_GENERATION 2 +#define CFG_SYS_REPLICATION_ROLE 7 + +#define CFG_NODE_ID 3 +#define CFG_NODE_BYTE_ORDER 4 +#define CFG_NODE_HOST 5 +#define CFG_NODE_SYSTEM 6 + +/** + * DB config parameters + */ +#define CFG_DB_NO_SAVE_MSGS 100 + +#define CFG_DB_NO_REPLICAS 101 +#define CFG_DB_NO_TABLES 102 +#define CFG_DB_NO_ATTRIBUTES 103 +#define CFG_DB_NO_INDEXES 104 +#define CFG_DB_NO_TRIGGERS 105 + +#define CFG_DB_NO_TRANSACTIONS 106 +#define CFG_DB_NO_OPS 107 +#define CFG_DB_NO_SCANS 108 +#define CFG_DB_NO_TRIGGER_OPS 109 +#define CFG_DB_NO_INDEX_OPS 110 + +#define CFG_DB_TRANS_BUFFER_MEM 111 +#define CFG_DB_DATA_MEM 112 +#define CFG_DB_INDEX_MEM 113 +#define CFG_DB_MEMLOCK 114 + +#define CFG_DB_START_PARTIAL_TIMEOUT 115 +#define CFG_DB_START_PARTITION_TIMEOUT 116 +#define CFG_DB_START_FAILURE_TIMEOUT 117 + +#define CFG_DB_HEARTBEAT_INTERVAL 118 +#define CFG_DB_API_HEARTBEAT_INTERVAL 119 +#define CFG_DB_LCP_INTERVAL 120 +#define CFG_DB_GCP_INTERVAL 121 +#define CFG_DB_ARBIT_TIMEOUT 122 + +#define CFG_DB_WATCHDOG_INTERVAL 123 +#define CFG_DB_STOP_ON_ERROR 124 + +#define CFG_DB_FILESYSTEM_PATH 125 +#define CFG_DB_NO_REDOLOG_FILES 126 +#define CFG_DB_DISC_BANDWIDTH 127 +#define CFG_DB_SR_DISC_BANDWITH 128 + +#define CFG_DB_TRANSACTION_CHECK_INTERVAL 129 +#define CFG_DB_TRANSACTION_INACTIVE_TIMEOUT 130 +#define CFG_DB_TRANSACTION_DEADLOCK_TIMEOUT 131 + +#define CFG_DB_PARALLEL_BACKUPS 132 +#define CFG_DB_BACKUP_MEM 133 +#define CFG_DB_BACKUP_DATA_BUFFER_MEM 134 +#define CFG_DB_BACKUP_LOG_BUFFER_MEM 135 +#define CFG_DB_BACKUP_WRITE_SIZE 136 + +#define CFG_LOGLEVEL_STARTUP 137 +#define CFG_LOGLEVEL_SHUTDOWN 138 +#define CFG_LOGLEVEL_STATISTICS 139 +#define CFG_LOGLEVEL_CHECKPOINT 140 +#define CFG_LOGLEVEL_NODERESTART 141 +#define CFG_LOGLEVEL_CONNECTION 142 +#define CFG_LOGLEVEL_INFO 143 +#define CFG_LOGLEVEL_WARNING 144 +#define CFG_LOGLEVEL_ERROR 145 +#define CFG_LOGLEVEL_GREP 146 +#define CFG_LOG_DESTINATION 147 + +#define CFG_NODE_ARBIT_RANK 200 +#define CFG_NODE_ARBIT_DELAY 201 + +#define CFG_MGM_PORT 300 + +#define CFG_CONNECTION_NODE_1 400 +#define CFG_CONNECTION_NODE_2 401 +#define CFG_CONNECTION_SEND_SIGNAL_ID 402 +#define CFG_CONNECTION_CHECKSUM 403 +#define CFG_CONNECTION_NODE_1_SYSTEM 404 +#define CFG_CONNECTION_NODE_2_SYSTEM 405 + +#define CFG_TCP_HOSTNAME_1 450 +#define CFG_TCP_HOSTNAME_2 451 +#define CFG_TCP_SERVER 452 +#define CFG_TCP_SERVER_PORT 453 +#define CFG_TCP_SEND_BUFFER_SIZE 454 +#define CFG_TCP_RECEIVE_BUFFER_SIZE 455 +#define CFG_TCP_PROXY 456 + +#define CFG_SHM_SEND_SIGNAL_ID 500 +#define CFG_SHM_CHECKSUM 501 +#define CFG_SHM_KEY 502 +#define CFG_SHM_BUFFER_MEM 503 + +#define CFG_SCI_ID_0 550 +#define CFG_SCI_ID_1 551 +#define CFG_SCI_SEND_LIMIT 552 +#define CFG_SCI_BUFFER_MEM 553 +#define CFG_SCI_NODE1_ADAPTERS 554 +#define CFG_SCI_NODE1_ADAPTER0 555 +#define CFG_SCI_NODE1_ADAPTER1 556 +#define CFG_SCI_NODE2_ADAPTERS 554 +#define CFG_SCI_NODE2_ADAPTER0 555 +#define CFG_SCI_NODE2_ADAPTER1 556 + +#define CFG_OSE_HOSTNAME_1 600 +#define CFG_OSE_HOSTNAME_2 601 +#define CFG_OSE_PRIO_A_SIZE 602 +#define CFG_OSE_PRIO_B_SIZE 603 +#define CFG_OSE_RECEIVE_ARRAY_SIZE 604 + +#define CFG_REP_HEARTBEAT_INTERVAL 700 + +/** + * Internal + */ +#define CFG_DB_STOP_ON_ERROR_INSERT 1 + +#define CFG_TYPE_OF_SECTION 999 +#define CFG_SECTION_SYSTEM 1000 +#define CFG_SECTION_NODE 2000 +#define CFG_SECTION_CONNECTION 3000 + +#define NODE_TYPE_DB 0 +#define NODE_TYPE_API 1 +#define NODE_TYPE_MGM 2 +#define NODE_TYPE_REP 3 +#define NODE_TYPE_EXT_REP 4 + +#define CONNECTION_TYPE_TCP 0 +#define CONNECTION_TYPE_SHM 1 +#define CONNECTION_TYPE_SCI 2 +#define CONNECTION_TYPE_OSE 3 + +#endif diff --git a/ndb/include/mgmapi/mgmapi_config_parameters_debug.h b/ndb/include/mgmapi/mgmapi_config_parameters_debug.h new file mode 100644 index 00000000000..0241dca90ef --- /dev/null +++ b/ndb/include/mgmapi/mgmapi_config_parameters_debug.h @@ -0,0 +1,8 @@ +#ifndef MGMAPI_CONFIG_PARAMTERS_DEBUG_H +#define MGMAPI_CONFIG_PARAMTERS_DEBUG_H + +#include "mgmapi_config_parameters.h" + +#define CFG_DB_STOP_ON_ERROR_INSERT 1 + +#endif diff --git a/ndb/include/mgmcommon/ConfigRetriever.hpp b/ndb/include/mgmcommon/ConfigRetriever.hpp index ff60e730d45..50d333b54dd 100644 --- a/ndb/include/mgmcommon/ConfigRetriever.hpp +++ b/ndb/include/mgmcommon/ConfigRetriever.hpp @@ -18,7 +18,7 @@ #define ConfigRetriever_H #include <ndb_types.h> -#include <Properties.hpp> +#include <mgmapi.h> /** * @class ConfigRetriever @@ -44,11 +44,11 @@ public: * to establish a connection. This is repeated until a connection is * established, so the function hangs until a connection is established. * - * @return Properties object if succeeded, + * @return ndb_mgm_configuration object if succeeded, * NULL if erroneous local config file or configuration error. */ - class Properties * getConfig(const char * nodeType, int versionId); - + struct ndb_mgm_configuration * getConfig(int versionId, int nodeType); + const char * getErrorString(); /** @@ -71,22 +71,17 @@ public: * @return Node id of this node (as stated in local config or connectString) */ inline Uint32 getOwnNodeId() { return _ownNodeId; } - - /** - * Get configuration object - */ - class Properties * getConfig(int versionId); + /** * Get config using socket */ - class Properties * getConfig(const char * mgmhost, unsigned int port, - Uint32 nodeId, int versionId); + struct ndb_mgm_configuration * getConfig(const char * mgmhost, short port, + int versionId); /** * Get config from file */ - class Properties * getConfig(const char * filename, Uint32 nodeId, - int versionId); + struct ndb_mgm_configuration * getConfig(const char * file, int versionId); private: char * errorString; enum ErrorType { @@ -97,18 +92,17 @@ private: void setError(ErrorType, const char * errorMsg); - /** - * Verifies that received configuration is correct - */ - bool verifyProperties(const char* nodeType, Properties *p, - Uint32 nodeId, int versionId); - char * _localConfigFileName; struct LocalConfig * _localConfig; int _ownNodeId; char * m_connectString; char * m_defaultConnectString; + + /** + * Verify config + */ + bool verifyConfig(const struct ndb_mgm_configuration *, int type); }; #endif diff --git a/ndb/include/mgmcommon/IPCConfig.hpp b/ndb/include/mgmcommon/IPCConfig.hpp index 626242865cb..ebe65b53b59 100644 --- a/ndb/include/mgmcommon/IPCConfig.hpp +++ b/ndb/include/mgmcommon/IPCConfig.hpp @@ -58,6 +58,10 @@ public: void print() const { props->print(); } + static Uint32 configureTransporters(Uint32 nodeId, + const class ndb_mgm_configuration &, + class TransporterRegistry &); + private: NodeId the_ownId; Properties * props; diff --git a/ndb/include/util/Base64.hpp b/ndb/include/util/Base64.hpp index a8678da946c..1156636eec8 100644 --- a/ndb/include/util/Base64.hpp +++ b/ndb/include/util/Base64.hpp @@ -20,7 +20,8 @@ #include <UtilBuffer.hpp> #include <BaseString.hpp> -int base64_encode(UtilBuffer &src, BaseString &dst); -int base64_decode(BaseString &src, UtilBuffer &dst); +int base64_encode(const UtilBuffer &src, BaseString &dst); +int base64_decode(const BaseString &src, UtilBuffer &dst); +int base64_decode(const char * s, size_t len, UtilBuffer &dst); #endif /* !__BASE64_HPP_INCLUDED__ */ diff --git a/ndb/include/util/Bitmask.hpp b/ndb/include/util/Bitmask.hpp index 00255d3a86b..7355742f845 100644 --- a/ndb/include/util/Bitmask.hpp +++ b/ndb/include/util/Bitmask.hpp @@ -134,7 +134,7 @@ public: /** * getText - Return as hex-digits (only for debug routines). */ - static void getText(unsigned size, const Uint32 data[], char* buf); + static char* getText(unsigned size, const Uint32 data[], char* buf); }; inline bool @@ -302,9 +302,10 @@ BitmaskImpl::setField(unsigned size, Uint32 data[], set(size, data, pos + i, val & (1 << i)); } -inline void +inline char * BitmaskImpl::getText(unsigned size, const Uint32 data[], char* buf) { + char * org = buf; const char* const hex = "0123456789abcdef"; for (int i = (size-1); i >= 0; i--) { Uint32 x = data[i]; @@ -315,6 +316,7 @@ BitmaskImpl::getText(unsigned size, const Uint32 data[], char* buf) buf += 8; } *buf = 0; + return org; } /** @@ -333,7 +335,7 @@ public: Uint32 data[size]; #if 0 Data & operator=(const Bitmask<size> & src) { - src.assign(size, data); + src.copyto(size, data); return *this; } #endif @@ -346,6 +348,8 @@ public: STATIC_CONST( NotFound = BitmaskImpl::NotFound ); STATIC_CONST( TextLength = size * 8 ); + Bitmask() { clear();} + /** * assign - Set all bits in <em>dst</em> to corresponding in <em>src/<em> */ @@ -359,9 +363,9 @@ public: void assign(const Bitmask<size> & src); /** - * assign <em>dst</em> of size <em>sz</em> to <em>this</em> + * copy this to <em>dst</em> */ - void assign(unsigned sz, Uint32 dst[]) const; + void copyto(unsigned sz, Uint32 dst[]) const; /** * assign <em>this</em> according to <em>src/em> @@ -469,7 +473,7 @@ public: /** * getText - Return as hex-digits (only for debug routines). */ - static void getText(const Uint32 data[], char* buf); + static char* getText(const Uint32 data[], char* buf); char* getText(char* buf) const; }; @@ -498,12 +502,12 @@ template <unsigned size> inline void Bitmask<size>::assign(const Bitmask<size> & src) { - assign(rep.data, src); + assign(rep.data, src.rep.data); } template <unsigned size> inline void -Bitmask<size>::assign(unsigned sz, Uint32 dst[]) const +Bitmask<size>::copyto(unsigned sz, Uint32 dst[]) const { BitmaskImpl::assign(sz, dst, rep.data); } @@ -716,18 +720,17 @@ Bitmask<size>::bitXOR(const Bitmask<size>& mask2) } template <unsigned size> -void +char * Bitmask<size>::getText(const Uint32 data[], char* buf) { - BitmaskImpl::getText(size, data, buf); + return BitmaskImpl::getText(size, data, buf); } template <unsigned size> inline char * Bitmask<size>::getText(char* buf) const { - getText(rep.data, buf); - return buf; + return getText(rep.data, buf); } template <unsigned size> diff --git a/ndb/include/util/ConfigValues.hpp b/ndb/include/util/ConfigValues.hpp new file mode 100644 index 00000000000..48e1363bf4a --- /dev/null +++ b/ndb/include/util/ConfigValues.hpp @@ -0,0 +1,252 @@ +#ifndef __CONFIG_VALUES_HPP +#define __CONFIG_VALUES_HPP + +#include <ndb_types.h> +#include <UtilBuffer.hpp> + +class ConfigValues { + friend class ConfigValuesFactory; + ConfigValues(Uint32 sz, Uint32 data); + +public: + ~ConfigValues(); + + enum ValueType { + InvalidType = 0, + IntType = 1, + StringType = 2, + SectionType = 3, + Int64Type = 4 + }; + + struct Entry { + Uint32 m_key; + ValueType m_type; + union { + Uint32 m_int; + const char * m_string; + Uint64 m_int64; + }; + }; + + class ConstIterator { + friend class ConfigValuesFactory; + const ConfigValues & m_cfg; + protected: + Uint32 m_currentSection; + public: + ConstIterator(const ConfigValues&c) : m_cfg(c) { m_currentSection = 0;} + + bool openSection(Uint32 key, Uint32 no); + bool closeSection(); + + bool get(Uint32 key, Entry *) const; + + bool get(Uint32 key, Uint32 * value) const; + bool get(Uint32 key, Uint64 * value) const; + bool get(Uint32 key, const char ** value) const; + bool getTypeOf(Uint32 key, ValueType * type) const; + + Uint32 get(Uint32 key, Uint32 notFound) const; + Uint64 get64(Uint32 key, Uint64 notFound) const; + const char * get(Uint32 key, const char * notFound) const; + ValueType getTypeOf(Uint32 key) const; + }; + + class Iterator : public ConstIterator { + ConfigValues & m_cfg; + public: + Iterator(ConfigValues&c) : ConstIterator(c), m_cfg(c) {} + + bool set(Uint32 key, Uint32 value); + bool set(Uint32 key, Uint64 value); + bool set(Uint32 key, const char * value); + }; + + Uint32 getPackedSize() const; // get size in bytes needed to pack + Uint32 pack(UtilBuffer&) const; + Uint32 pack(void * dst, Uint32 len) const;// pack into dst(of len %d); + +private: + friend class Iterator; + friend class ConstIterator; + + bool getByPos(Uint32 pos, Entry *) const; + Uint64 & get64(Uint32 index) const; + char * & getString(Uint32 index) const; + + Uint32 m_size; + Uint32 m_dataSize; + Uint32 m_stringCount; + Uint32 m_int64Count; + + Uint32 m_values[1]; + void * m_data[1]; +}; + +class ConfigValuesFactory { + Uint32 m_currentSection; +public: + Uint32 m_sectionCounter; + Uint32 m_freeKeys; + Uint32 m_freeData; + +public: + ConfigValuesFactory(Uint32 keys = 50, Uint32 data = 10); // Initial + ConfigValuesFactory(ConfigValues * m_cfg); // + + ConfigValues * m_cfg; + ConfigValues * getConfigValues(); + + bool openSection(Uint32 key, Uint32 no); + bool put(const ConfigValues::Entry & ); + bool put(Uint32 key, Uint32 value); + bool put64(Uint32 key, Uint64 value); + bool put(Uint32 key, const char * value); + bool closeSection(); + + void expand(Uint32 freeKeys, Uint32 freeData); + void shrink(); + + bool unpack(const UtilBuffer&); + bool unpack(const void * src, Uint32 len); + + static ConfigValues * extractCurrentSection(const ConfigValues::ConstIterator &); + +private: + static ConfigValues * create(Uint32 keys, Uint32 data); + void put(const ConfigValues & src); +}; + +inline +bool +ConfigValues::ConstIterator::get(Uint32 key, Uint32 * value) const { + Entry tmp; + if(get(key, &tmp) && tmp.m_type == IntType){ + * value = tmp.m_int; + return true; + } + return false; +} + +inline +bool +ConfigValues::ConstIterator::get(Uint32 key, Uint64 * value) const { + Entry tmp; + if(get(key, &tmp) && tmp.m_type == Int64Type){ + * value = tmp.m_int64; + return true; + } + return false; +} + +inline +bool +ConfigValues::ConstIterator::get(Uint32 key, const char ** value) const { + Entry tmp; + if(get(key, &tmp) && tmp.m_type == StringType){ + * value = tmp.m_string; + return true; + } + return false; +} + +inline +bool +ConfigValues::ConstIterator::getTypeOf(Uint32 key, ValueType * type) const{ + Entry tmp; + if(get(key, &tmp)){ + * type = tmp.m_type; + return true; + } + return false; +} + +inline +Uint32 +ConfigValues::ConstIterator::get(Uint32 key, Uint32 notFound) const { + Entry tmp; + if(get(key, &tmp) && tmp.m_type == IntType){ + return tmp.m_int; + } + return notFound; +} + +inline +Uint64 +ConfigValues::ConstIterator::get64(Uint32 key, Uint64 notFound) const { + Entry tmp; + if(get(key, &tmp) && tmp.m_type == Int64Type){ + return tmp.m_int64; + } + return notFound; +} + +inline +const char * +ConfigValues::ConstIterator::get(Uint32 key, const char * notFound) const { + Entry tmp; + if(get(key, &tmp) && tmp.m_type == StringType){ + return tmp.m_string; + } + return notFound; +} + +inline +ConfigValues::ValueType +ConfigValues::ConstIterator::getTypeOf(Uint32 key) const{ + Entry tmp; + if(get(key, &tmp)){ + return tmp.m_type; + } + return ConfigValues::InvalidType; +} + +inline +bool +ConfigValuesFactory::put(Uint32 key, Uint32 val){ + ConfigValues::Entry tmp; + tmp.m_key = key; + tmp.m_type = ConfigValues::IntType; + tmp.m_int = val; + return put(tmp); +} + +inline +bool +ConfigValuesFactory::put64(Uint32 key, Uint64 val){ + ConfigValues::Entry tmp; + tmp.m_key = key; + tmp.m_type = ConfigValues::Int64Type; + tmp.m_int64 = val; + return put(tmp); +} + +inline +bool +ConfigValuesFactory::put(Uint32 key, const char * val){ + ConfigValues::Entry tmp; + tmp.m_key = key; + tmp.m_type = ConfigValues::StringType; + tmp.m_string = val; + return put(tmp); +} + +inline +Uint32 +ConfigValues::pack(UtilBuffer& buf) const { + Uint32 len = getPackedSize(); + void * tmp = buf.append(len); + if(tmp == 0){ + return 0; + } + return pack(tmp, len); +} + +inline +bool +ConfigValuesFactory::unpack(const UtilBuffer& buf){ + return unpack(buf.get_data(), buf.length()); +} + +#endif diff --git a/ndb/include/util/Properties.hpp b/ndb/include/util/Properties.hpp index ff5d1338c79..2c30f7f7e3c 100644 --- a/ndb/include/util/Properties.hpp +++ b/ndb/include/util/Properties.hpp @@ -22,9 +22,10 @@ #include <UtilBuffer.hpp> enum PropertiesType { - PropertiesType_Uint32, - PropertiesType_char, - PropertiesType_Properties + PropertiesType_Uint32 = 0, + PropertiesType_char = 1, + PropertiesType_Properties = 2, + PropertiesType_Uint64 = 3 }; /** @@ -36,6 +37,7 @@ enum PropertiesType { */ struct Property { Property(const char* name, Uint32 val); + Property(const char* name, Uint64 val); Property(const char* name, const char * value); Property(const char* name, const class Properties * value); ~Property(); @@ -75,6 +77,7 @@ public: void put(const Property *, int len); bool put(const char * name, Uint32 value, bool replace = false); + bool put64(const char * name, Uint64 value, bool replace = false); bool put(const char * name, const char * value, bool replace = false); bool put(const char * name, const Properties * value, bool replace = false); @@ -84,6 +87,7 @@ public: * Compare get(name, no) */ bool put(const char *, Uint32 no, Uint32, bool replace = false); + bool put64(const char *, Uint32 no, Uint64, bool replace = false); bool put(const char *, Uint32 no, const char *, bool replace = false); bool put(const char *, Uint32 no, const Properties *, bool replace = false); @@ -94,6 +98,7 @@ public: bool contains(const char * name) const; bool get(const char * name, Uint32 * value) const; + bool get(const char * name, Uint64 * value) const; bool get(const char * name, const char ** value) const; bool get(const char * name, BaseString & value) const; bool get(const char * name, const Properties ** value) const; @@ -109,6 +114,7 @@ public: bool contains(const char * name, Uint32 no) const; bool get(const char * name, Uint32 no, Uint32 * value) const; + bool get(const char * name, Uint32 no, Uint64 * value) const; bool get(const char * name, Uint32 no, const char ** value) const; bool get(const char * name, Uint32 no, const Properties ** value) const; @@ -230,11 +236,12 @@ Properties::unpack(UtilBuffer &buf) { inline bool Properties::pack(UtilBuffer &buf) const { Uint32 size = getPackedSize(); - char *tmp_buf = new char[size]; + void *tmp_buf = buf.append(size); + if(tmp_buf == 0) + return false; bool ret = pack((Uint32 *)tmp_buf); if(ret == false) return false; - buf.append(tmp_buf, size); return true; } diff --git a/ndb/include/util/UtilBuffer.hpp b/ndb/include/util/UtilBuffer.hpp index b357fa0fdf2..f43fc960a16 100644 --- a/ndb/include/util/UtilBuffer.hpp +++ b/ndb/include/util/UtilBuffer.hpp @@ -63,6 +63,15 @@ public: return 0; }; + void * append(size_t l){ + if(grow(len+l) != 0) + return 0; + + void * ret = (char*)data+len; + len += l; + return ret; + } + int assign(const void * d, size_t l) { if (data) free(data); data = NULL; diff --git a/ndb/src/common/debugger/LogLevel.cpp b/ndb/src/common/debugger/LogLevel.cpp index 5348924bbbb..f9e2f318432 100644 --- a/ndb/src/common/debugger/LogLevel.cpp +++ b/ndb/src/common/debugger/LogLevel.cpp @@ -17,13 +17,14 @@ #include <LogLevel.hpp> const LogLevel::LogLevelCategoryName LogLevel::LOGLEVEL_CATEGORY_NAME[] = { - {"LogLevelStartup"}, - {"LogLevelShutdown"}, - {"LogLevelStatistic"}, - {"LogLevelCheckpoint"}, - {"LogLevelNodeRestart"}, - {"LogLevelConnection"}, - {"LogLevelError"}, - {"LogLevelInfo"}, - {"LogLevelGrep"} + { "LogLevelStartup" }, + { "LogLevelShutdown" }, + { "LogLevelStatistic" }, + { "LogLevelCheckpoint" }, + { "LogLevelNodeRestart" }, + { "LogLevelConnection" }, + { "LogLevelError" }, + { "LogLevelWarning" }, + { "LogLevelInfo" }, + { "LogLevelGrep" } }; diff --git a/ndb/src/common/debugger/signaldata/CntrStart.cpp b/ndb/src/common/debugger/signaldata/CntrStart.cpp new file mode 100644 index 00000000000..154013f40b0 --- /dev/null +++ b/ndb/src/common/debugger/signaldata/CntrStart.cpp @@ -0,0 +1,37 @@ +#include <signaldata/CntrStart.hpp> + +bool +printCNTR_START_REQ(FILE * output, const Uint32 * theData, + Uint32 len, Uint16 receiverBlockNo) { + const CntrStartReq * const sig = (CntrStartReq *)theData; + fprintf(output, " nodeId: %x\n", sig->nodeId); + fprintf(output, " startType: %x\n", sig->startType); + fprintf(output, " lastGci: %x\n", sig->lastGci); + return true; +} + +bool +printCNTR_START_REF(FILE * output, const Uint32 * theData, + Uint32 len, Uint16 receiverBlockNo) { + const CntrStartRef * const sig = (CntrStartRef *)theData; + fprintf(output, " errorCode: %x\n", sig->errorCode); + fprintf(output, " masterNodeId: %x\n", sig->masterNodeId); + return true; +} + +bool +printCNTR_START_CONF(FILE * output, const Uint32 * theData, + Uint32 len, Uint16 receiverBlockNo) { + const CntrStartConf * const sig = (CntrStartConf *)theData; + fprintf(output, " startType: %x\n", sig->startType); + fprintf(output, " startGci: %x\n", sig->startGci); + fprintf(output, " masterNodeId: %x\n", sig->masterNodeId); + fprintf(output, " noStartNodes: %x\n", sig->noStartNodes); + + char buf[32*NdbNodeBitmask::Size+1]; + fprintf(output, " startedNodes: %s\n", + BitmaskImpl::getText(NdbNodeBitmask::Size, sig->startedNodes, buf)); + fprintf(output, " startingNodes: %s\n", + BitmaskImpl::getText(NdbNodeBitmask::Size, sig->startingNodes, buf)); + return true; +} diff --git a/ndb/src/common/debugger/signaldata/Makefile_old b/ndb/src/common/debugger/signaldata/Makefile_old index 5e86aaf97c0..bd00667b482 100644 --- a/ndb/src/common/debugger/signaldata/Makefile_old +++ b/ndb/src/common/debugger/signaldata/Makefile_old @@ -25,6 +25,7 @@ SOURCES = TcKeyReq.cpp TcKeyConf.cpp TcKeyRef.cpp \ CopyGCI.cpp SystemError.cpp StartRec.cpp NFCompleteRep.cpp \ FailRep.cpp DisconnectRep.cpp SignalDroppedRep.cpp \ SumaImpl.cpp NdbSttor.cpp CreateFragmentation.cpp \ + CntrStart.cpp ReadNodesConf.cpp \ UtilLock.cpp TuxMaint.cpp TupAccess.cpp AccLock.cpp \ LqhTrans.cpp diff --git a/ndb/src/common/debugger/signaldata/ReadNodesConf.cpp b/ndb/src/common/debugger/signaldata/ReadNodesConf.cpp new file mode 100644 index 00000000000..103f4a884f1 --- /dev/null +++ b/ndb/src/common/debugger/signaldata/ReadNodesConf.cpp @@ -0,0 +1,24 @@ +#include <signaldata/ReadNodesConf.hpp> + +bool +printREAD_NODES_CONF(FILE * output, const Uint32 * theData, + Uint32 len, Uint16 receiverBlockNo) { + const ReadNodesConf * const sig = (ReadNodesConf *)theData; + fprintf(output, " noOfNodes: %x\n", sig->noOfNodes); + fprintf(output, " ndynamicId: %x\n", sig->ndynamicId); + fprintf(output, " masterNodeId: %x\n", sig->masterNodeId); + + char buf[32*NdbNodeBitmask::Size+1]; + fprintf(output, " allNodes(defined): %s\n", + BitmaskImpl::getText(NdbNodeBitmask::Size, sig->allNodes, buf)); + fprintf(output, " inactiveNodes: %s\n", + BitmaskImpl::getText(NdbNodeBitmask::Size, sig->inactiveNodes, buf)); + fprintf(output, " clusterNodes: %s\n", + BitmaskImpl::getText(NdbNodeBitmask::Size, sig->clusterNodes, buf)); + fprintf(output, " startedNodes: %s\n", + BitmaskImpl::getText(NdbNodeBitmask::Size, sig->startedNodes, buf)); + fprintf(output, " startingNodes: %s\n", + BitmaskImpl::getText(NdbNodeBitmask::Size, sig->startingNodes, buf)); + return true; +} + diff --git a/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp b/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp index 2236d0c0af1..d49e316ad38 100644 --- a/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp +++ b/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp @@ -70,6 +70,8 @@ #include <signaldata/NdbSttor.hpp> #include <signaldata/CreateFragmentation.hpp> #include <signaldata/UtilLock.hpp> +#include <signaldata/CntrStart.hpp> +#include <signaldata/ReadNodesConf.hpp> #include <signaldata/TuxMaint.hpp> #include <signaldata/TupAccess.hpp> #include <signaldata/AccLock.hpp> @@ -240,6 +242,12 @@ SignalDataPrintFunctions[] = { ,{ GSN_UTIL_UNLOCK_REQ, printUTIL_UNLOCK_REQ } ,{ GSN_UTIL_UNLOCK_REF, printUTIL_UNLOCK_REF } ,{ GSN_UTIL_UNLOCK_CONF, printUTIL_UNLOCK_CONF } + ,{ GSN_CNTR_START_REQ, printCNTR_START_REQ } + ,{ GSN_CNTR_START_REF, printCNTR_START_REF } + ,{ GSN_CNTR_START_CONF, printCNTR_START_CONF } + + ,{ GSN_READ_NODESCONF, printREAD_NODES_CONF } + ,{ GSN_TUX_MAINT_REQ, printTUX_MAINT_REQ } ,{ GSN_TUP_READ_ATTRS, printTUP_READ_ATTRS } ,{ GSN_TUP_QUERY_TH, printTUP_QUERY_TH } diff --git a/ndb/src/common/debugger/signaldata/SignalNames.cpp b/ndb/src/common/debugger/signaldata/SignalNames.cpp index 4e5c8603db1..377a588dbb0 100644 --- a/ndb/src/common/debugger/signaldata/SignalNames.cpp +++ b/ndb/src/common/debugger/signaldata/SignalNames.cpp @@ -101,40 +101,23 @@ const GsnName SignalNames [] = { ,{ GSN_ADD_FRAGREQ, "ADD_FRAGREQ" } ,{ GSN_API_FAILCONF, "API_FAILCONF" } ,{ GSN_API_FAILREQ, "API_FAILREQ" } - ,{ GSN_APPL_CHANGEREP, "APPL_CHANGEREP" } - // ,{ GSN_APPL_ERROR, "APPL_ERROR" } - ,{ GSN_APPL_HB, "APPL_HB" } - ,{ GSN_APPL_HBREQ, "APPL_HBREQ" } - ,{ GSN_APPL_REGCONF, "APPL_REGCONF" } - ,{ GSN_APPL_REGREF, "APPL_REGREF" } - ,{ GSN_APPL_REGREQ, "APPL_REGREQ" } - ,{ GSN_APPL_RUN, "APPL_RUN" } - ,{ GSN_APPL_STARTCONF, "APPL_STARTCONF" } - ,{ GSN_APPL_STARTREG, "APPL_STARTREG" } ,{ GSN_CHECK_LCP_STOP, "CHECK_LCP_STOP" } ,{ GSN_CLOSE_COMCONF, "CLOSE_COMCONF" } ,{ GSN_CLOSE_COMREQ, "CLOSE_COMREQ" } ,{ GSN_CM_ACKADD, "CM_ACKADD" } - ,{ GSN_CM_ACKALARM, "CM_ACKALARM" } ,{ GSN_CM_ADD, "CM_ADD" } - ,{ GSN_CM_APPCHG, "CM_APPCHG" } + ,{ GSN_CM_ADD_REP, "CM_ADD_REP" } ,{ GSN_CM_HEARTBEAT, "CM_HEARTBEAT" } - ,{ GSN_CM_INFOCONF, "CM_INFOCONF" } - ,{ GSN_CM_INFOREQ, "CM_INFOREQ" } - ,{ GSN_CM_INIT, "CM_INIT" } ,{ GSN_CM_NODEINFOCONF, "CM_NODEINFOCONF" } ,{ GSN_CM_NODEINFOREF, "CM_NODEINFOREF" } ,{ GSN_CM_NODEINFOREQ, "CM_NODEINFOREQ" } ,{ GSN_CM_REGCONF, "CM_REGCONF" } ,{ GSN_CM_REGREF, "CM_REGREF" } ,{ GSN_CM_REGREQ, "CM_REGREQ" } - ,{ GSN_CM_RUN, "CM_RUN" } - ,{ GSN_CMVMI_CFGCONF, "CMVMI_CFGCONF" } - ,{ GSN_CMVMI_CFGREQ, "CMVMI_CFGREQ" } - ,{ GSN_CNTR_CHANGEREP, "CNTR_CHANGEREP" } - ,{ GSN_CNTR_MASTERCONF, "CNTR_MASTERCONF" } - ,{ GSN_CNTR_MASTERREF, "CNTR_MASTERREF" } - ,{ GSN_CNTR_MASTERREQ, "CNTR_MASTERREQ" } + ,{ GSN_CNTR_START_REQ, "CNTR_START_REQ" } + ,{ GSN_CNTR_START_REF, "CNTR_START_REF" } + ,{ GSN_CNTR_START_CONF, "CNTR_START_CONF" } + ,{ GSN_CNTR_START_REP, "CNTR_START_REP" } ,{ GSN_CNTR_WAITREP, "CNTR_WAITREP" } ,{ GSN_COMMIT, "COMMIT" } ,{ GSN_COMMIT_FAILCONF, "COMMIT_FAILCONF" } @@ -294,9 +277,6 @@ const GsnName SignalNames [] = { ,{ GSN_NEXT_SCANREQ, "NEXT_SCANREQ" } ,{ GSN_NEXTOPERATION, "NEXTOPERATION" } ,{ GSN_NF_COMPLETEREP, "NF_COMPLETEREP" } - ,{ GSN_NODE_STATESCONF, "NODE_STATESCONF" } - ,{ GSN_NODE_STATESREF, "NODE_STATESREF" } - ,{ GSN_NODE_STATESREQ, "NODE_STATESREQ" } ,{ GSN_OPEN_COMCONF, "OPEN_COMCONF" } ,{ GSN_OPEN_COMREF, "OPEN_COMREF" } ,{ GSN_OPEN_COMREQ, "OPEN_COMREQ" } @@ -318,8 +298,8 @@ const GsnName SignalNames [] = { ,{ GSN_SEND_PACKED, "SEND_PACKED" } ,{ GSN_SET_LOGLEVELORD, "SET_LOGLEVELORD" } ,{ GSN_SHRINKCHECK2, "SHRINKCHECK2" } - ,{ GSN_SIZEALT_ACK, "SIZEALT_ACK" } - ,{ GSN_SIZEALT_REP, "SIZEALT_REP" } + ,{ GSN_READ_CONFIG_REQ, "READ_CONFIG_REQ" } + ,{ GSN_READ_CONFIG_CONF, "READ_CONFIG_CONF" } ,{ GSN_SR_FRAGIDCONF, "SR_FRAGIDCONF" } ,{ GSN_SR_FRAGIDREF, "SR_FRAGIDREF" } ,{ GSN_SR_FRAGIDREQ, "SR_FRAGIDREQ" } @@ -396,7 +376,6 @@ const GsnName SignalNames [] = { ,{ GSN_UPDATE_TOCONF, "UPDATE_TOCONF" } ,{ GSN_UPDATE_TOREF, "UPDATE_TOREF" } ,{ GSN_UPDATE_TOREQ, "UPDATE_TOREQ" } - ,{ GSN_VOTE_MASTERORD, "VOTE_MASTERORD" } ,{ GSN_TUP_ALLOCREQ, "TUP_ALLOCREQ" } ,{ GSN_LQH_ALLOCREQ, "LQH_ALLOCREQ" } ,{ GSN_TUP_DEALLOCREQ, "TUP_DEALLOCREQ" } @@ -428,7 +407,6 @@ const GsnName SignalNames [] = { ,{ GSN_CHECKNODEGROUPSREQ, "CHECKNODEGROUPSREQ" } ,{ GSN_CHECKNODEGROUPSCONF, "CHECKNODEGROUPSCONF" } - ,{ GSN_ARBIT_CFG, "ARBIT_CFG" } ,{ GSN_ARBIT_PREPREQ, "ARBIT_PREPREQ" } ,{ GSN_ARBIT_PREPCONF, "ARBIT_PREPCONF" } ,{ GSN_ARBIT_PREPREF, "ARBIT_PREPREF" } diff --git a/ndb/src/common/mgmcommon/Config.cpp b/ndb/src/common/mgmcommon/Config.cpp index 5492394ee4a..c0819b9f463 100644 --- a/ndb/src/common/mgmcommon/Config.cpp +++ b/ndb/src/common/mgmcommon/Config.cpp @@ -26,23 +26,17 @@ //***************************************************************************** Config::Config() { - m_info = new ConfigInfo(); -} - -Config::Config(const Config & org) : - Properties(org) { - - m_info = new ConfigInfo(); -} - -Config::Config(const Properties & org) : - Properties(org) { - - m_info = new ConfigInfo(); + m_oldConfig = 0; + m_configValues = 0; } Config::~Config() { - delete m_info; + if(m_configValues != 0){ + free(m_configValues); + } + + if(m_oldConfig != 0) + delete m_oldConfig; } /*****************************************************************************/ @@ -52,25 +46,33 @@ Config::printAllNameValuePairs(NdbOut &out, const Properties *prop, const char* s) const { Properties::Iterator it(prop); - const Properties * section = m_info->getInfo(s); + 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 (m_info->getStatus(section, n) == ConfigInfo::INTERNAL) + if(!section->contains(n)) continue; - if (m_info->getStatus(section, n) == ConfigInfo::DEPRICATED) + if (m_info.getStatus(section, n) == ConfigInfo::INTERNAL) continue; - if (m_info->getStatus(section, n) == ConfigInfo::NOTIMPLEMENTED) + if (m_info.getStatus(section, n) == ConfigInfo::DEPRICATED) + continue; + if (m_info.getStatus(section, n) == ConfigInfo::NOTIMPLEMENTED) continue; out << n << ": "; - switch (m_info->getType(section, n)) { + switch (m_info.getType(section, n)) { case ConfigInfo::INT: MGM_REQUIRE(prop->get(n, &int_value)); out << int_value; break; + + case ConfigInfo::INT64: + MGM_REQUIRE(prop->get(n, &int_64)); + out << int_64; + break; case ConfigInfo::BOOL: MGM_REQUIRE(prop->get(n, &int_value)); @@ -92,6 +94,7 @@ Config::printAllNameValuePairs(NdbOut &out, /*****************************************************************************/ void Config::printConfigFile(NdbOut &out) const { +#if 0 Uint32 noOfNodes, noOfConnections, noOfComputers; MGM_REQUIRE(get("NoOfNodes", &noOfNodes)); MGM_REQUIRE(get("NoOfConnections", &noOfConnections)); @@ -172,15 +175,12 @@ void Config::printConfigFile(NdbOut &out) const { endl; } } -} - -const -ConfigInfo* Config::getConfigInfo() const { - return m_info; +#endif } Uint32 Config::getGenerationNumber() const { +#if 0 Uint32 ret; const Properties *prop = NULL; @@ -191,10 +191,14 @@ Config::getGenerationNumber() const { return ret; return 0; +#else + return 0; +#endif } int Config::setGenerationNumber(Uint32 gen) { +#if 0 Properties *prop = NULL; getCopy("SYSTEM", &prop); @@ -205,12 +209,16 @@ Config::setGenerationNumber(Uint32 gen) { return 0; } return -1; +#else + return -1; +#endif } bool Config::change(const BaseString §ion, const BaseString ¶m, const BaseString &value) { +#if 0 const char *name; Properties::Iterator it(this); @@ -252,4 +260,7 @@ Config::change(const BaseString §ion, } } return true; +#else + return false; +#endif } diff --git a/ndb/src/common/mgmcommon/Config.hpp b/ndb/src/common/mgmcommon/Config.hpp index 284256d9ed6..26fd53dbed2 100644 --- a/ndb/src/common/mgmcommon/Config.hpp +++ b/ndb/src/common/mgmcommon/Config.hpp @@ -17,7 +17,6 @@ #ifndef Config_H #define Config_H -#include <signaldata/ConfigParamId.hpp> #include <LogLevel.hpp> #include <kernel_types.h> @@ -25,6 +24,9 @@ #include <NdbOut.hpp> #include <ndb_limits.h> #include <Properties.hpp> +#include "ConfigInfo.hpp" + +class ConfigInfo; /** * @class Config @@ -38,14 +40,14 @@ * * The following categories (sections) of configuration parameters exists: * - COMPUTER, DB, MGM, API, TCP, SCI, SHM, OSE + * */ -class Config : public Properties { + +class Config { public: /** * Constructor which loads the object with an Properties object */ - Config(const Config & org); - Config(const Properties & org); Config(); virtual ~Config(); @@ -58,8 +60,6 @@ public: printConfigFile(ndb); } - const class ConfigInfo* getConfigInfo() const; - Uint32 getGenerationNumber() const; int setGenerationNumber(Uint32); @@ -69,7 +69,13 @@ public: const BaseString ¶m, const BaseString &value); + + /** + * Info + */ + const ConfigInfo * getConfigInfo() const { return &m_info;} private: + ConfigInfo m_info; void printAllNameValuePairs(NdbOut &out, const Properties *prop, @@ -78,7 +84,9 @@ private: /** * Information about parameters (min, max values etc) */ - const class ConfigInfo* m_info; +public: + Properties * m_oldConfig; + struct ndb_mgm_configuration * m_configValues; }; #endif // Config_H diff --git a/ndb/src/common/mgmcommon/ConfigInfo.cpp b/ndb/src/common/mgmcommon/ConfigInfo.cpp index da6024d946f..57d1a2fe8fd 100644 --- a/ndb/src/common/mgmcommon/ConfigInfo.cpp +++ b/ndb/src/common/mgmcommon/ConfigInfo.cpp @@ -15,7 +15,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ConfigInfo.hpp" +#include <mgmapi_config_parameters.h> + #define MAX_LINE_LENGTH 255 +#define KEY_INTERNAL 0 /**************************************************************************** * Section names @@ -56,9 +59,12 @@ bool fixPortNumber(InitConfigFileParser::Context & ctx, const char *); bool fixShmkey(InitConfigFileParser::Context & ctx, const char *); bool checkDbConstraints(InitConfigFileParser::Context & ctx, const char *); bool checkConnectionConstraints(InitConfigFileParser::Context &, const char *); +bool fixNodeHostname(InitConfigFileParser::Context & ctx, const char * data); bool fixHostname(InitConfigFileParser::Context & ctx, const char * data); bool fixNodeId(InitConfigFileParser::Context & ctx, const char * data); bool fixExtConnection(InitConfigFileParser::Context & ctx, const char * data); +bool fixDepricated(InitConfigFileParser::Context & ctx, const char *); +bool saveInConfigValues(InitConfigFileParser::Context & ctx, const char *); const ConfigInfo::SectionRule ConfigInfo::m_SectionRules[] = { @@ -79,21 +85,12 @@ ConfigInfo::m_SectionRules[] = { { "TCP", fixPortNumber, 0 }, //{ "SHM", fixShmKey, 0 }, - - { "COMPUTER", applyDefaultValues, 0 }, - - { "DB", applyDefaultValues, 0 }, - { "API", applyDefaultValues, 0 }, - { "MGM", applyDefaultValues, 0 }, - { "REP", applyDefaultValues, 0 }, - { "EXTERNAL REP", applyDefaultValues, 0 }, - - { "TCP", applyDefaultValues, 0 }, - { "SHM", applyDefaultValues, 0 }, - { "SCI", applyDefaultValues, 0 }, - { "OSE", applyDefaultValues, 0 }, - { "DB", checkDbConstraints, 0 }, + { "DB", fixNodeHostname, 0 }, + { "API", fixNodeHostname, 0 }, + { "MGM", fixNodeHostname, 0 }, + { "REP", fixNodeHostname, 0 }, + //{ "EXTERNAL REP", fixNodeHostname, 0 }, { "TCP", fixNodeId, "NodeId1" }, { "TCP", fixNodeId, "NodeId2" }, @@ -103,6 +100,11 @@ ConfigInfo::m_SectionRules[] = { { "SCI", fixNodeId, "NodeId2" }, { "OSE", fixNodeId, "NodeId1" }, { "OSE", fixNodeId, "NodeId2" }, + + { "TCP", fixHostname, "HostName1" }, + { "TCP", fixHostname, "HostName2" }, + { "OSE", fixHostname, "HostName1" }, + { "OSE", fixHostname, "HostName2" }, /** * fixExtConnection must be after fixNodeId @@ -112,6 +114,12 @@ ConfigInfo::m_SectionRules[] = { { "SCI", fixExtConnection, 0 }, { "OSE", fixExtConnection, 0 }, + { "*", applyDefaultValues, "user" }, + { "*", fixDepricated, 0 }, + { "*", applyDefaultValues, "system" }, + + { "DB", checkDbConstraints, 0 }, + /** * checkConnectionConstraints must be after fixExtConnection */ @@ -120,24 +128,50 @@ ConfigInfo::m_SectionRules[] = { { "SCI", checkConnectionConstraints, 0 }, { "OSE", checkConnectionConstraints, 0 }, - { "COMPUTER", checkMandatory, 0 }, - { "DB", checkMandatory, 0 }, - { "API", checkMandatory, 0 }, - { "MGM", checkMandatory, 0 }, - { "REP", checkMandatory, 0 }, + { "*", checkMandatory, 0 }, + + { "DB", saveInConfigValues, 0 }, + { "API", saveInConfigValues, 0 }, + { "MGM", saveInConfigValues, 0 }, + { "REP", saveInConfigValues, 0 }, + + { "TCP", saveInConfigValues, 0 }, + { "SHM", saveInConfigValues, 0 }, + { "SCI", saveInConfigValues, 0 }, + { "OSE", saveInConfigValues, 0 } +}; +const int ConfigInfo::m_NoOfRules = sizeof(m_SectionRules)/sizeof(SectionRule); - { "TCP", checkMandatory, 0 }, - { "SHM", checkMandatory, 0 }, - { "SCI", checkMandatory, 0 }, - { "OSE", checkMandatory, 0 }, +struct DepricationTransform { + const char * m_section; + const char * m_oldName; + const char * m_newName; + double m_add; + double m_mul; +}; - { "TCP", fixHostname, "HostName1" }, - { "TCP", fixHostname, "HostName2" }, - { "OSE", fixHostname, "HostName1" }, - { "OSE", fixHostname, "HostName2" }, +static +const DepricationTransform f_deprication[] = { + { "DB", "NoOfIndexPages", "IndexMemory", 0, 8192 } + ,{ "DB", "MemorySpaceIndexes", "IndexMemory", 0, 8192 } + ,{ "DB", "NoOfDataPages", "DataMemory", 0, 8192 } + ,{ "DB", "MemorySpaceTuples", "DataMemory", 0, 8192 } + ,{ "DB", "TransactionInactiveTimeBeforeAbort", "TransactionInactiveTimeout", + 0, 1 } + ,{ "TCP", "ProcessId1", "NodeId1", 0, 1} + ,{ "TCP", "ProcessId2", "NodeId2", 0, 1} + ,{ "TCP", "SendBufferSize", "SendBufferMemory", 0, 16384 } + ,{ "TCP", "MaxReceiveSize", "ReceiveBufferMemory", 0, 16384 } + + ,{ "SHM", "ProcessId1", "NodeId1", 0, 1} + ,{ "SHM", "ProcessId2", "NodeId2", 0, 1} + ,{ "SCI", "ProcessId1", "NodeId1", 0, 1} + ,{ "SCI", "ProcessId2", "NodeId2", 0, 1} + ,{ "OSE", "ProcessId1", "NodeId1", 0, 1} + ,{ "OSE", "ProcessId2", "NodeId2", 0, 1} + ,{ 0, 0, 0, 0, 0} }; -const int ConfigInfo::m_NoOfRules = sizeof(m_SectionRules)/sizeof(SectionRule); /** * The default constructors create objects with suitable values for the @@ -166,224 +200,340 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { /**************************************************************************** * COMPUTER - ****************************************************************************/ - - {"Id", - "Id", - "COMPUTER", - "Name of computer", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - MANDATORY, - 0, - 0}, - - {"HostName", - "HostName", - "COMPUTER", - "Hostname of computer (e.g. mysql.com)", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - MANDATORY, - 0, - 0x7FFFFFFF}, - - {"ByteOrder", - "ByteOrder", - "COMPUTER", - "Not yet implemented", - ConfigInfo::USED, // Actually not used, but since it is MANDATORY, - // we don't want any warning message - false, - ConfigInfo::STRING, - MANDATORY, // Big == 0, Little == 1, NotSet == 2 (?) - 0, - 0x7FFFFFFF}, + ***************************************************************************/ + { + KEY_INTERNAL, + "COMPUTER", + "COMPUTER", + "Computer section", + ConfigInfo::INTERNAL, + false, + ConfigInfo::SECTION, + 0, + 0, 0 }, + + { + KEY_INTERNAL, + "Id", + "COMPUTER", + "Name of computer", + ConfigInfo::USED, + false, + ConfigInfo::STRING, + MANDATORY, + 0, + 0 }, + + { + KEY_INTERNAL, + "HostName", + "COMPUTER", + "Hostname of computer (e.g. alzato.com)", + ConfigInfo::USED, + false, + ConfigInfo::STRING, + MANDATORY, + 0, + 0x7FFFFFFF }, + + { + CFG_NODE_BYTE_ORDER, + "ByteOrder", + "COMPUTER", + "Not yet implemented", + ConfigInfo::USED, // Actually not used, but since it is MANDATORY, + // we don't want any warning message + false, + ConfigInfo::STRING, + MANDATORY, // Big == 0, Little == 1, NotSet == 2 (?) + 0, + 1 }, /**************************************************************************** - * DB - ****************************************************************************/ - - {"Id", - "Id", - "DB", - "Number identifying the database node (DB)", - ConfigInfo::USED, - false, - ConfigInfo::INT, - MANDATORY, - 1, - (MAX_NODES - 1)}, - - {"Type", - "Type", - "DB", - "Type of node (Should have value DB)", - ConfigInfo::INTERNAL, - false, - ConfigInfo::STRING, - 0, - 0, - 0}, - - {"NoOfReplicas", - "NoOfReplicas", - "DB", - "Number of copies of all data in the database (1-4)", - ConfigInfo::USED, - false, - ConfigInfo::INT, - MANDATORY, - 1, - 4}, - - {"MaxNoOfAttributes", - "MaxNoOfAttributes", - "DB", - "Total number of attributes stored in database. I.e. sum over all tables", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 1000, - 32, - 4096}, + * SYSTEM + ***************************************************************************/ + { + CFG_SECTION_SYSTEM, + "SYSTEM", + "SYSTEM", + "System section", + ConfigInfo::USED, + false, + ConfigInfo::SECTION, + CFG_SECTION_SYSTEM, + 0, + 0 }, + + { + CFG_SYS_NAME, + "Name", + "SYSTEM", + "Name of system (NDB Cluster)", + ConfigInfo::USED, + false, + ConfigInfo::STRING, + MANDATORY, + 0, + 0 }, - {"MaxNoOfTables", - "MaxNoOfTables", - "DB", - "Total number of tables stored in the database", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 32, - 8, - 128}, + { + CFG_SYS_REPLICATION_ROLE, + "ReplicationRole", + "SYSTEM", + "Role in Global Replication (None, Primary, or Standby)", + ConfigInfo::USED, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0 }, - {"MaxNoOfIndexes", - "MaxNoOfIndexes", - "DB", - "Total number of indexes that can be defined in the system", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 128, - 0, - 2048}, - - {"MaxNoOfConcurrentIndexOperations", - "MaxNoOfConcurrentIndexOperations", - "DB", - "Total number of index operations that can execute simultaneously on one DB node", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 8192, - 0, - 1000000 + { + CFG_SYS_PRIMARY_MGM_NODE, + "PrimaryMGMNode", + "SYSTEM", + "Node id of Primary MGM node", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 0, + 0, + 0x7FFFFFFF }, + + { + CFG_SYS_CONFIG_GENERATION, + "ConfigGenerationNumber", + "SYSTEM", + "Configuration generation number", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 0, + 0, + 0x7FFFFFFF }, + + /*************************************************************************** + * DB + ***************************************************************************/ + { + CFG_SECTION_NODE, + "DB", + "DB", + "Node section", + ConfigInfo::USED, + false, + ConfigInfo::SECTION, + NODE_TYPE_DB, + 0, 0 }, - {"MaxNoOfTriggers", - "MaxNoOfTriggers", - "DB", - "Total number of triggers that can be defined in the system", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 768, - 0, - 2432}, - - {"MaxNoOfFiredTriggers", - "MaxNoOfFiredTriggers", - "DB", - "Total number of triggers that can fire simultaneously in one DB node", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 1000, - 0, - 1000000}, - - {"ExecuteOnComputer", - "ExecuteOnComputer", - "DB", - "String referencing an earlier defined COMPUTER", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - MANDATORY, - 0, - 0x7FFFFFFF}, + { + CFG_NODE_HOST, + "HostName", + "DB", + "Name of computer for this node", + ConfigInfo::INTERNAL, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_NODE_SYSTEM, + "System", + "DB", + "Name of system for this node", + ConfigInfo::INTERNAL, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_NODE_ID, + "Id", + "DB", + "Number identifying the database node (DB)", + ConfigInfo::USED, + false, + ConfigInfo::INT, + MANDATORY, + 1, + (MAX_NODES - 1) }, + + { + CFG_DB_NO_REPLICAS, + "NoOfReplicas", + "DB", + "Number of copies of all data in the database (1-4)", + ConfigInfo::USED, + false, + ConfigInfo::INT, + MANDATORY, + 1, + 2 }, + + { + CFG_DB_NO_ATTRIBUTES, + "MaxNoOfAttributes", + "DB", + "Total number of attributes stored in database. I.e. sum over all tables", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 1000, + 32, + 4096 }, - {"MaxNoOfSavedMessages", - "MaxNoOfSavedMessages", - "DB", - "Max number of error messages in error log and max number of trace files", - ConfigInfo::USED, - true, - ConfigInfo::INT, - 25, - 0, - 0x7FFFFFFF}, - - {"LockPagesInMainMemory", - "LockPagesInMainMemory", - "DB", - "If set to yes, then NDB Cluster data will not be swapped out to disk", - ConfigInfo::USED, - true, - ConfigInfo::BOOL, - false, - 0, - 0x7FFFFFFF}, - - {"SleepWhenIdle", - "SleepWhenIdle", - "DB", - "?", - ConfigInfo::DEPRICATED, - true, - ConfigInfo::BOOL, - true, - 0, - 0x7FFFFFFF}, - - {"NoOfSignalsToExecuteBetweenCommunicationInterfacePoll", - "NoOfSignalsToExecuteBetweenCommunicationInterfacePoll", - "DB", - "?", - ConfigInfo::DEPRICATED, - true, - ConfigInfo::INT, - 20, - 1, - 0x7FFFFFFF}, + { + CFG_DB_NO_TABLES, + "MaxNoOfTables", + "DB", + "Total number of tables stored in the database", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 32, + 8, + 128 }, - {"TimeBetweenWatchDogCheck", - "TimeBetweenWatchDogCheck", - "DB", - "Time between execution checks inside a database node", - ConfigInfo::USED, - true, - ConfigInfo::INT, - 4000, - 70, - 0x7FFFFFFF}, - - {"StopOnError", - "StopOnError", - "DB", - "If set to N, the DB automatically restarts/recovers in case of node failure", - ConfigInfo::USED, - true, - ConfigInfo::BOOL, - true, - 0, - 0x7FFFFFFF}, - - { "RestartOnErrorInsert", + { + CFG_DB_NO_INDEXES, + "MaxNoOfIndexes", + "DB", + "Total number of indexes that can be defined in the system", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 128, + 0, + 2048 }, + + { + CFG_DB_NO_INDEX_OPS, + "MaxNoOfConcurrentIndexOperations", + "DB", + "Total number of index operations that can execute simultaneously on one DB node", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 8192, + 0, + 1000000 + }, + + { + CFG_DB_NO_TRIGGERS, + "MaxNoOfTriggers", + "DB", + "Total number of triggers that can be defined in the system", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 768, + 0, + 2432 }, + + { + CFG_DB_NO_TRIGGER_OPS, + "MaxNoOfFiredTriggers", + "DB", + "Total number of triggers that can fire simultaneously in one DB node", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 1000, + 0, + 1000000 }, + + { + KEY_INTERNAL, + "ExecuteOnComputer", + "DB", + "String referencing an earlier defined COMPUTER", + ConfigInfo::USED, + false, + ConfigInfo::STRING, + MANDATORY, + 0, + 0x7FFFFFFF }, + + { + CFG_DB_NO_SAVE_MSGS, + "MaxNoOfSavedMessages", + "DB", + "Max number of error messages in error log and max number of trace files", + ConfigInfo::USED, + true, + ConfigInfo::INT, + 25, + 0, + 0x7FFFFFFF }, + + { + CFG_DB_MEMLOCK, + "LockPagesInMainMemory", + "DB", + "If set to yes, then NDB Cluster data will not be swapped out to disk", + ConfigInfo::USED, + true, + ConfigInfo::BOOL, + false, + 0, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "SleepWhenIdle", + "DB", + 0, + ConfigInfo::DEPRICATED, + true, + ConfigInfo::BOOL, + true, + 0, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "NoOfSignalsToExecuteBetweenCommunicationInterfacePoll", + "DB", + 0, + ConfigInfo::DEPRICATED, + true, + ConfigInfo::INT, + 20, + 1, + 0x7FFFFFFF }, + + { + CFG_DB_WATCHDOG_INTERVAL, + "TimeBetweenWatchDogCheck", + "DB", + "Time between execution checks inside a database node", + ConfigInfo::USED, + true, + ConfigInfo::INT, + 4000, + 70, + 0x7FFFFFFF }, + + { + CFG_DB_STOP_ON_ERROR, + "StopOnError", + "DB", + "If set to N, the DB automatically restarts/recovers in case of node failure", + ConfigInfo::USED, + true, + ConfigInfo::BOOL, + true, + 0, + 0x7FFFFFFF }, + + { + CFG_DB_STOP_ON_ERROR_INSERT, "RestartOnErrorInsert", "DB", "See src/kernel/vm/Emulator.hpp NdbRestartType for details", @@ -394,41 +544,45 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { 0, 4 }, - {"MaxNoOfConcurrentOperations", - "MaxNoOfConcurrentOperations", - "DB", - "Max no of op:s on DB (op:s within a transaction are concurrently executed)", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 8192, - 32, - 1000000}, - - {"MaxNoOfConcurrentTransactions", - "MaxNoOfConcurrentTransactions", - "DB", - "Max number of transaction executing concurrently on the DB node", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 4096, - 32, - 1000000}, - - {"MaxNoOfConcurrentScans", - "MaxNoOfConcurrentScans", - "DB", - "Max number of scans executing concurrently on the DB node", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 25, - 2, - 500}, - - {"TransactionBufferMemory", - "TransactionBufferMemory", + { + CFG_DB_NO_OPS, + "MaxNoOfConcurrentOperations", + "DB", + "Max no of op:s on DB (op:s within a transaction are concurrently executed)", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 8192, + 32, + 1000000 }, + + { + CFG_DB_NO_TRANSACTIONS, + "MaxNoOfConcurrentTransactions", + "DB", + "Max number of transaction executing concurrently on the DB node", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 4096, + 32, + 1000000 }, + + { + CFG_DB_NO_SCANS, + "MaxNoOfConcurrentScans", + "DB", + "Max number of scans executing concurrently on the DB node", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 25, + 2, + 500 }, + + { + CFG_DB_TRANS_BUFFER_MEM, + "TransactionBufferMemory", "DB", "Dynamic buffer space (in bytes) for key and attribute data allocated for each DB node", ConfigInfo::USED, @@ -436,437 +590,429 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { ConfigInfo::INT, 1024000, 1024, - 0x7FFFFFFF}, + 0x7FFFFFFF }, - {"NoOfIndexPages", - "NoOfIndexPages", - "DB", - "Number of 8k byte pages on each DB node for storing indexes", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 3000, - 128, - 192000}, - - {"MemorySpaceIndexes", - "NoOfIndexPages", - "DB", - "Depricated", - ConfigInfo::DEPRICATED, - false, - ConfigInfo::INT, - UNDEFINED, - 128, - 192000}, - - {"NoOfDataPages", - "NoOfDataPages", - "DB", - "Number of 8k byte pages on each DB node for storing data", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 10000, - 128, - 400000}, - - {"MemorySpaceTuples", - "NoOfDataPages", - "DB", - "Depricated", - ConfigInfo::DEPRICATED, - false, - ConfigInfo::INT, - UNDEFINED, - 128, - 400000}, - - {"NoOfDiskBufferPages", - "NoOfDiskBufferPages", - "DB", - "?", - ConfigInfo::NOTIMPLEMENTED, - false, - ConfigInfo::INT, - 0, - 0, - 0}, - - {"MemoryDiskPages", - "NoOfDiskBufferPages", - "DB", - "?", - ConfigInfo::DEPRICATED, - false, - ConfigInfo::INT, - UNDEFINED, - 0, - 0}, - - {"NoOfFreeDiskClusters", - "NoOfFreeDiskClusters", - "DB", - "?", - ConfigInfo::NOTIMPLEMENTED, - false, - ConfigInfo::INT, - 0, - 0, - 0}, - - {"NoOfDiskClusters", - "NoOfDiskClusters", - "DB", - "?", - ConfigInfo::NOTIMPLEMENTED, - false, - ConfigInfo::INT, - 0, - 0, - 0x7FFFFFFF}, + { + CFG_DB_INDEX_MEM, + "IndexMemory", + "DB", + "Number bytes on each DB node allocated for storing indexes", + ConfigInfo::USED, + false, + ConfigInfo::INT64, + 3000 * 8192, + 128 * 8192, + 192000 * 8192 }, + + { + KEY_INTERNAL, + "NoOfIndexPages", + "DB", + "IndexMemory", + ConfigInfo::DEPRICATED, + false, + ConfigInfo::INT, + 3000, + 128, + 192000 }, + + { + KEY_INTERNAL, + "MemorySpaceIndexes", + "DB", + "IndexMemory", + ConfigInfo::DEPRICATED, + false, + ConfigInfo::INT, + UNDEFINED, + 128, + 192000 }, + + { + CFG_DB_DATA_MEM, + "DataMemory", + "DB", + "Number bytes on each DB node allocated for storing data", + ConfigInfo::USED, + false, + ConfigInfo::INT64, + 10000 * 8192, + 128 * 8192, + 400000 * 8192 }, + + { + KEY_INTERNAL, + "NoOfDataPages", + "DB", + "DataMemory", + ConfigInfo::DEPRICATED, + false, + ConfigInfo::INT, + 10000, + 128, + 400000 }, + + { + KEY_INTERNAL, + "MemorySpaceTuples", + "DB", + "DataMemory", + ConfigInfo::DEPRICATED, + false, + ConfigInfo::INT, + UNDEFINED, + 128, + 400000 }, - {"TimeToWaitAlive", - "TimeToWaitAlive", - "DB", - "Time to wait for other nodes to become alive during initial system start", - ConfigInfo::USED, - true, - ConfigInfo::INT, - 25, - 2, - 4000}, - - {"HeartbeatIntervalDbDb", - "HeartbeatIntervalDbDb", - "DB", - "Time between DB-to-DB heartbeats. DB considered dead after 3 missed HBs", - ConfigInfo::USED, - true, - ConfigInfo::INT, - 1500, - 10, - 0x7FFFFFFF}, - - {"HeartbeatIntervalDbApi", - "HeartbeatIntervalDbApi", - "DB", - "Time between API-to-DB heartbeats. API connection closed after 3 missed HBs", - ConfigInfo::USED, - true, - ConfigInfo::INT, - 1500, - 100, - 0x7FFFFFFF}, - - {"TimeBetweenLocalCheckpoints", - "TimeBetweenLocalCheckpoints", - "DB", - "Time between taking snapshots of the database (expressed in 2log of bytes)", - ConfigInfo::USED, - true, - ConfigInfo::INT, - 20, - 0, - 31}, - - {"TimeBetweenGlobalCheckpoints", - "TimeBetweenGlobalCheckpoints", - "DB", - "Time between doing group commit of transactions to disk", - ConfigInfo::USED, - true, - ConfigInfo::INT, - 2000, - 10, - 32000}, - - {"NoOfFragmentLogFiles", - "NoOfFragmentLogFiles", - "DB", - "No of 16 Mbyte Redo log files in each of 4 file sets belonging to DB node", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 8, - 1, - 0x7FFFFFFF}, - - {"MaxNoOfOpenFiles", - "MaxNoOfOpenFiles", - "DB", - "Max number of files open per DB node.(One thread is created per file)", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 40, - 20, - 256}, - - {"NoOfConcurrentCheckpointsDuringRestart", - "NoOfConcurrentCheckpointsDuringRestart", - "DB", - "?", - ConfigInfo::USED, - true, - ConfigInfo::INT, - 1, - 1, - 4}, + { + CFG_DB_START_PARTIAL_TIMEOUT, + "StartPartialTimeout", + "DB", + "Time to wait before trying to start wo/ all nodes. 0=Wait forever", + ConfigInfo::USED, + true, + ConfigInfo::INT, + 30000, + 0, + ~0 }, + + { + CFG_DB_START_PARTITION_TIMEOUT, + "StartPartitionedTimeout", + "DB", + "Time to wait before trying to start partitioned. 0=Wait forever", + ConfigInfo::USED, + true, + ConfigInfo::INT, + 60000, + 0, + ~0 }, - {"TimeBetweenInactiveTransactionAbortCheck", - "TimeBetweenInactiveTransactionAbortCheck", - "DB", - "Time between inactive transaction checks", - ConfigInfo::USED, - true, - ConfigInfo::INT, - 1000, - 1000, - 0x7FFFFFFF}, + { + CFG_DB_START_FAILURE_TIMEOUT, + "StartFailureTimeout", + "DB", + "Time to wait before terminating. 0=Wait forever", + ConfigInfo::USED, + true, + ConfigInfo::INT, + 5*60000, + 0, + ~0 }, - {"TransactionInactiveTimeout", - "TransactionInactiveTimeout", - "DB", - "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::USED, - true, - ConfigInfo::INT, - 3000, - 0, - 0x7FFFFFFF}, - - {"TransactionDeadlockDetectionTimeout", - "TransactionDeadlockDetectionTimeout", - "DB", - "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::USED, - true, - ConfigInfo::INT, - 3000, - 50, - 0x7FFFFFFF}, - - {"TransactionInactiveTimeBeforeAbort", - "TransactionInactiveTimeBeforeAbort", - "DB", - "Time a transaction can be inactive before getting aborted (ms)", - ConfigInfo::DEPRICATED, - true, - ConfigInfo::INT, - 3000, - 20, - 0x7FFFFFFF}, - - {"NoOfConcurrentProcessesHandleTakeover", - "NoOfConcurrentProcessesHandleTakeover", - "DB", - "?", - ConfigInfo::USED, - true, - ConfigInfo::INT, - 1, - 1, - 15}, + { + KEY_INTERNAL, + "TimeToWaitAlive", + "DB", + "Start{Partial/Partitioned/Failure}Time", + ConfigInfo::DEPRICATED, + true, + ConfigInfo::INT, + 25, + 2, + 4000 }, + + { + CFG_DB_HEARTBEAT_INTERVAL, + "HeartbeatIntervalDbDb", + "DB", + "Time between DB-DB heartbeats. DB considered dead after 3 missed HBs", + ConfigInfo::USED, + true, + ConfigInfo::INT, + 1500, + 10, + 0x7FFFFFFF }, + + { + CFG_DB_API_HEARTBEAT_INTERVAL, + "HeartbeatIntervalDbApi", + "DB", + "Time between API-DB heartbeats. API connection closed after 3 missed HBs", + ConfigInfo::USED, + true, + ConfigInfo::INT, + 1500, + 100, + 0x7FFFFFFF }, + + { + CFG_DB_LCP_INTERVAL, + "TimeBetweenLocalCheckpoints", + "DB", + "Time between taking snapshots of the database (expressed in 2log of bytes)", + ConfigInfo::USED, + true, + ConfigInfo::INT, + 20, + 0, + 31 }, + + { + CFG_DB_GCP_INTERVAL, + "TimeBetweenGlobalCheckpoints", + "DB", + "Time between doing group commit of transactions to disk", + ConfigInfo::USED, + true, + ConfigInfo::INT, + 2000, + 10, + 32000 }, + + { + CFG_DB_NO_REDOLOG_FILES, + "NoOfFragmentLogFiles", + "DB", + "No of 16 Mbyte Redo log files in each of 4 file sets belonging to DB node", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 8, + 1, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "MaxNoOfOpenFiles", + "DB", + "Max number of files open per DB node.(One thread is created per file)", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 40, + 20, + 256 }, + - {"NoOfConcurrentCheckpointsAfterRestart", - "NoOfConcurrentCheckpointsAfterRestart", - "DB", - "?", - ConfigInfo::USED, - true, - ConfigInfo::INT, - 1, - 1, - 4}, + { + CFG_DB_TRANSACTION_CHECK_INTERVAL, + "TimeBetweenInactiveTransactionAbortCheck", + "DB", + "Time between inactive transaction checks", + ConfigInfo::USED, + true, + ConfigInfo::INT, + 1000, + 1000, + 0x7FFFFFFF }, - {"NoOfDiskPagesToDiskDuringRestartTUP", - "NoOfDiskPagesToDiskDuringRestartTUP", - "DB", - "?", - ConfigInfo::USED, - true, - ConfigInfo::INT, - 50, - 1, - 0x7FFFFFFF}, - - {"NoOfDiskPagesToDiskAfterRestartTUP", - "NoOfDiskPagesToDiskAfterRestartTUP", - "DB", - "?", - ConfigInfo::USED, - true, - ConfigInfo::INT, - 10, - 1, - 0x7FFFFFFF}, - - {"NoOfDiskPagesToDiskDuringRestartACC", - "NoOfDiskPagesToDiskDuringRestartACC", - "DB", - "?", - ConfigInfo::USED, - true, - ConfigInfo::INT, - 25, - 1, - 0x7FFFFFFF}, - - {"NoOfDiskPagesToDiskAfterRestartACC", - "NoOfDiskPagesToDiskAfterRestartACC", - "DB", - "?", - ConfigInfo::USED, - true, - ConfigInfo::INT, - 5, - 1, - 0x7FFFFFFF}, + { + CFG_DB_TRANSACTION_INACTIVE_TIMEOUT, + "TransactionInactiveTimeout", + "DB", + "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::USED, + true, + ConfigInfo::INT, + 3000, + 0, + 0x7FFFFFFF }, + + { + CFG_DB_TRANSACTION_DEADLOCK_TIMEOUT, + "TransactionDeadlockDetectionTimeout", + "DB", + "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::USED, + true, + ConfigInfo::INT, + 3000, + 50, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "TransactionInactiveTimeBeforeAbort", + "DB", + "TransactionInactiveTimeout", + ConfigInfo::DEPRICATED, + true, + ConfigInfo::INT, + 3000, + 20, + 0x7FFFFFFF }, - {"NoOfDiskClustersPerDiskFile", - "NoOfDiskClustersPerDiskFile", - "DB", - "?", - ConfigInfo::NOTIMPLEMENTED, - false, - ConfigInfo::INT, - 0, - 0, - 0x7FFFFFFF}, + { + KEY_INTERNAL, + "NoOfDiskPagesToDiskDuringRestartTUP", + "DB", + "?", + ConfigInfo::USED, + true, + ConfigInfo::INT, + 50, + 1, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "NoOfDiskPagesToDiskAfterRestartTUP", + "DB", + "?", + ConfigInfo::USED, + true, + ConfigInfo::INT, + 10, + 1, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "NoOfDiskPagesToDiskDuringRestartACC", + "DB", + "?", + ConfigInfo::USED, + true, + ConfigInfo::INT, + 25, + 1, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "NoOfDiskPagesToDiskAfterRestartACC", + "DB", + "?", + ConfigInfo::USED, + true, + ConfigInfo::INT, + 5, + 1, + 0x7FFFFFFF }, - {"NoOfDiskFiles", - "NoOfDiskFiles", - "DB", - "?", - ConfigInfo::NOTIMPLEMENTED, - false, - ConfigInfo::INT, - 0, - 0, - 0x7FFFFFFF}, - - {"ArbitrationTimeout", - "ArbitrationTimeout", - "DB", - "Max time (milliseconds) database partion waits for arbitration signal", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 1000, - 10, - 0x7FFFFFFF}, - - {"FileSystemPath", - "FileSystemPath", - "DB", - "Path to directory where the DB node stores its data (directory must exist)", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - UNDEFINED, - 0, - 0x7FFFFFFF}, - - {"LogLevelStartup", - "LogLevelStartup", - "DB", - "Node startup info printed on stdout", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 1, - 0, - 15}, + { + CFG_DB_ARBIT_TIMEOUT, + "ArbitrationTimeout", + "DB", + "Max time (milliseconds) database partion waits for arbitration signal", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 1000, + 10, + 0x7FFFFFFF }, + + { + CFG_DB_FILESYSTEM_PATH, + "FileSystemPath", + "DB", + "Path to directory where the DB node stores its data (directory must exist)", + ConfigInfo::USED, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_LOGLEVEL_STARTUP, + "LogLevelStartup", + "DB", + "Node startup info printed on stdout", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 1, + 0, + 15 }, - {"LogLevelShutdown", - "LogLevelShutdown", - "DB", - "Node shutdown info printed on stdout", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 0, - 0, - 15}, - - {"LogLevelStatistic", - "LogLevelStatistic", - "DB", - "Transaction, operation, transporter info printed on stdout", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 0, - 0, - 15}, - - {"LogLevelCheckpoint", - "LogLevelCheckpoint", - "DB", - "Local and Global checkpoint info printed on stdout", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 0, - 0, - 15}, - - {"LogLevelNodeRestart", - "LogLevelNodeRestart", - "DB", - "Node restart, node failure info printed on stdout", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 0, - 0, - 15}, - - {"LogLevelConnection", - "LogLevelConnection", - "DB", - "Node connect/disconnect info printed on stdout", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 0, - 0, - 15}, - - {"LogLevelError", - "LogLevelError", - "DB", - "Transporter, heartbeat errors printed on stdout", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 0, - 0, - 15}, - - {"LogLevelInfo", - "LogLevelInfo", - "DB", - "Heartbeat and log info printed on stdout", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 0, - 0, - 15}, + { + CFG_LOGLEVEL_SHUTDOWN, + "LogLevelShutdown", + "DB", + "Node shutdown info printed on stdout", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 0, + 0, + 15 }, + + { + CFG_LOGLEVEL_STATISTICS, + "LogLevelStatistic", + "DB", + "Transaction, operation, transporter info printed on stdout", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 0, + 0, + 15 }, + + { + CFG_LOGLEVEL_CHECKPOINT, + "LogLevelCheckpoint", + "DB", + "Local and Global checkpoint info printed on stdout", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 0, + 0, + 15 }, + + { + CFG_LOGLEVEL_NODERESTART, + "LogLevelNodeRestart", + "DB", + "Node restart, node failure info printed on stdout", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 0, + 0, + 15 }, + + { + CFG_LOGLEVEL_CONNECTION, + "LogLevelConnection", + "DB", + "Node connect/disconnect info printed on stdout", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 0, + 0, + 15 }, + + { + CFG_LOGLEVEL_ERROR, + "LogLevelError", + "DB", + "Transporter, heartbeat errors printed on stdout", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 0, + 0, + 15 }, + + { + CFG_LOGLEVEL_INFO, + "LogLevelInfo", + "DB", + "Heartbeat and log info printed on stdout", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 0, + 0, + 15 }, /** * Backup */ - { "ParallelBackups", + { + CFG_DB_PARALLEL_BACKUPS, "ParallelBackups", "DB", "Maximum number of parallel backups", @@ -877,7 +1023,8 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { 1, 1 }, - { "BackupMemory", + { + CFG_DB_BACKUP_MEM, "BackupMemory", "DB", "Total memory allocated for backups per node (in bytes)", @@ -888,7 +1035,8 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { 0, 0x7FFFFFFF }, - { "BackupDataBufferSize", + { + CFG_DB_BACKUP_DATA_BUFFER_MEM, "BackupDataBufferSize", "DB", "Default size of databuffer for a backup (in bytes)", @@ -899,7 +1047,8 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { 0, 0x7FFFFFFF }, - { "BackupLogBufferSize", + { + CFG_DB_BACKUP_LOG_BUFFER_MEM, "BackupLogBufferSize", "DB", "Default size of logbuffer for a backup (in bytes)", @@ -910,7 +1059,8 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { 0, 0x7FFFFFFF }, - { "BackupWriteSize", + { + CFG_DB_BACKUP_WRITE_SIZE, "BackupWriteSize", "DB", "Default size of filesystem writes made by backup (in bytes)", @@ -921,967 +1071,1098 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { 0, 0x7FFFFFFF }, - /**************************************************************************** + /*************************************************************************** * REP - ****************************************************************************/ - - {"Id", - "Id", - "REP", - "Number identifying replication node (REP)", - ConfigInfo::USED, - false, - ConfigInfo::INT, - MANDATORY, - 1, - (MAX_NODES - 1)}, - - {"Type", - "Type", - "REP", - "Type of node (Should have value REP)", - ConfigInfo::INTERNAL, - false, - ConfigInfo::STRING, - 0, - 0, - 0}, - - {"ExecuteOnComputer", - "ExecuteOnComputer", - "REP", - "String referencing an earlier defined COMPUTER", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - MANDATORY, - 0, - 0x7FFFFFFF}, + ***************************************************************************/ + { + CFG_SECTION_NODE, + "REP", + "REP", + "Node section", + ConfigInfo::USED, + false, + ConfigInfo::SECTION, + NODE_TYPE_REP, + 0, 0 + }, - /**************************************************************************** - * EXTERNAL REP - ****************************************************************************/ - - {"Id", - "Id", - "EXTERNAL REP", - "Number identifying external (i.e. in another NDB Cluster) replication node (REP)", - ConfigInfo::USED, - false, - ConfigInfo::INT, - MANDATORY, - 1, - (MAX_NODES - 1)}, - - {"Type", - "Type", - "EXTERNAL REP", - "Type of node (Should have value REP)", - ConfigInfo::INTERNAL, - false, - ConfigInfo::STRING, - 0, - 0, - 0}, - - {"System", - "System", - "EXTERNAL REP", - "System name of system hosting node", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - 0, - 0, - 0}, - - {"HeartbeatIntervalRepRep", - "HeartbeatIntervalRepRep", - "EXTERNAL REP", - "Time between REP-REP heartbeats. Connection closed after 3 missed HBs", - ConfigInfo::USED, - true, - ConfigInfo::INT, - 3000, - 100, - 0x7FFFFFFF}, + { + CFG_NODE_HOST, + "HostName", + "REP", + "Name of computer for this node", + ConfigInfo::INTERNAL, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, - /**************************************************************************** + { + CFG_NODE_SYSTEM, + "System", + "REP", + "Name of system for this node", + ConfigInfo::INTERNAL, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_NODE_ID, + "Id", + "REP", + "Number identifying replication node (REP)", + ConfigInfo::USED, + false, + ConfigInfo::INT, + MANDATORY, + 1, + (MAX_NODES - 1) }, + + { + KEY_INTERNAL, + "ExecuteOnComputer", + "REP", + "String referencing an earlier defined COMPUTER", + ConfigInfo::USED, + false, + ConfigInfo::STRING, + MANDATORY, + 0, + 0x7FFFFFFF }, + + { + CFG_REP_HEARTBEAT_INTERVAL, + "HeartbeatIntervalRepRep", + "REP", + "Time between REP-REP heartbeats. Connection closed after 3 missed HBs", + ConfigInfo::USED, + true, + ConfigInfo::INT, + 3000, + 100, + 0x7FFFFFFF }, + + /*************************************************************************** * API - ****************************************************************************/ - - {"Id", - "Id", - "API", - "Number identifying application node (API)", - ConfigInfo::USED, - false, - ConfigInfo::INT, - MANDATORY, - 1, - (MAX_NODES - 1)}, - - {"Type", - "Type", - "API", - "Type of node (Should have value API)", - ConfigInfo::INTERNAL, - false, - ConfigInfo::STRING, - 0, - 0, - 0}, - - {"ExecuteOnComputer", - "ExecuteOnComputer", - "API", - "String referencing an earlier defined COMPUTER", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - MANDATORY, - 0, - 0x7FFFFFFF}, - - {"MaxNoOfSavedMessages", - "MaxNoOfSavedMessages", - "API", - "Max number of error messages in error log and max number of trace files", - ConfigInfo::USED, - true, - ConfigInfo::INT, - 25, - 0, - 0x7FFFFFFF}, - - {"SleepWhenIdle", - "SleepWhenIdle", - "API", - "?", - ConfigInfo::DEPRICATED, - true, - ConfigInfo::BOOL, - true, - 0, - 0x7FFFFFFF}, - - {"ArbitrationRank", - "ArbitrationRank", - "API", - "If 0, then API is not arbitrator. Kernel selects arbitrators in order 1, 2", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 2, - 0, - 2}, - - {"ArbitrationDelay", - "ArbitrationDelay", - "API", - "When asked to arbitrate, arbitrator waits this long before voting (msec)", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 0, - 0, - 0x7FFFFFFF}, + ***************************************************************************/ + { + CFG_SECTION_NODE, + "API", + "API", + "Node section", + ConfigInfo::USED, + false, + ConfigInfo::SECTION, + NODE_TYPE_API, + 0, 0 + }, + + { + CFG_NODE_HOST, + "HostName", + "API", + "Name of computer for this node", + ConfigInfo::INTERNAL, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_NODE_SYSTEM, + "System", + "API", + "Name of system for this node", + ConfigInfo::INTERNAL, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_NODE_ID, + "Id", + "API", + "Number identifying application node (API)", + ConfigInfo::USED, + false, + ConfigInfo::INT, + MANDATORY, + 1, + (MAX_NODES - 1) }, + + { + KEY_INTERNAL, + "ExecuteOnComputer", + "API", + "String referencing an earlier defined COMPUTER", + ConfigInfo::USED, + false, + ConfigInfo::STRING, + MANDATORY, + 0, + 0x7FFFFFFF }, + + { + CFG_NODE_ARBIT_RANK, + "ArbitrationRank", + "API", + "If 0, then API is not arbitrator. Kernel selects arbitrators in order 1, 2", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 2, + 0, + 2 }, + + { + CFG_NODE_ARBIT_DELAY, + "ArbitrationDelay", + "API", + "When asked to arbitrate, arbitrator waits this long before voting (msec)", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 0, + 0, + 0x7FFFFFFF }, /**************************************************************************** * MGM - ****************************************************************************/ - - {"Id", - "Id", - "MGM", - "Number identifying the management server node (MGM)", - ConfigInfo::USED, - false, - ConfigInfo::INT, - MANDATORY, - 1, - (MAX_NODES - 1)}, + ***************************************************************************/ + { + CFG_SECTION_NODE, + "MGM", + "MGM", + "Node section", + ConfigInfo::USED, + false, + ConfigInfo::SECTION, + NODE_TYPE_MGM, + 0, 0 + }, + + { + CFG_NODE_HOST, + "HostName", + "MGM", + "Name of computer for this node", + ConfigInfo::INTERNAL, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_NODE_SYSTEM, + "System", + "MGM", + "Name of system for this node", + ConfigInfo::INTERNAL, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_NODE_ID, + "Id", + "MGM", + "Number identifying the management server node (MGM)", + ConfigInfo::USED, + false, + ConfigInfo::INT, + MANDATORY, + 1, + (MAX_NODES - 1) }, - {"Type", - "Type", - "MGM", - "Type of node (Should have value MGM)", - ConfigInfo::INTERNAL, - false, - ConfigInfo::STRING, - 0, - 0, - 0}, - - {"ExecuteOnComputer", - "ExecuteOnComputer", - "MGM", - "String referencing an earlier defined COMPUTER", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - MANDATORY, - 0, - 0x7FFFFFFF}, - - // SHOULD THIS REALLY BE DEFINABLE FOR MGM ??? - {"MaxNoOfSavedMessages", - "MaxNoOfSavedMessages", - "MGM", - "Max number of error messages in error log and max number of trace files", - ConfigInfo::DEPRICATED, - true, - ConfigInfo::INT, - 25, - 0, - 0x7FFFFFFF}, + { + CFG_LOG_DESTINATION, + "LogDestination", + "MGM", + "String describing where logmessages are sent", + ConfigInfo::USED, + false, + ConfigInfo::STRING, + 0, + 0, + 0x7FFFFFFF }, - {"MaxNoOfSavedEvents", - "MaxNoOfSavedEvents", - "MGM", - "", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 100, - 0, - 0x7FFFFFFF}, - - {"PortNumber", - "PortNumber", - "MGM", - "Port number to give commands to/fetch configurations from management server", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 2200, - 0, - 0x7FFFFFFF}, - - {"PortNumberStats", - "PortNumberStats", - "MGM", - "Port number used to get statistical information from a management server", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 2199, - 0, - 0x7FFFFFFF}, - - {"ArbitrationRank", - "ArbitrationRank", - "MGM", - "If 0, then MGM is not arbitrator. Kernel selects arbitrators in order 1, 2", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 2, - 0, - 2}, - - {"ArbitrationDelay", - "ArbitrationDelay", - "MGM", - "", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 0, - 0, - 0x7FFFFFFF}, - - /***************************************************************************** - * SYSTEM - ****************************************************************************/ - - {"Name", - "Name", - "SYSTEM", - "Name of system (NDB Cluster)", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - MANDATORY, - 0, - 0}, - - {"ReplicationRole", - "ReplicationRole", - "SYSTEM", - "Role in Global Replication (None, Primary, or Standby)", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - UNDEFINED, - 0, - 0}, - - {"LogDestination", - "LogDestination", - "MGM", - "String describing where logmessages are sent", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - 0, - 0, - 0x7FFFFFFF}, - - {"PrimaryMGMNode", - "PrimaryMGMNode", - "SYSTEM", - "Node id of Primary MGM node", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 0, - 0, - 0x7FFFFFFF}, - - {"ConfigGenerationNumber", - "ConfigGenerationNumber", - "SYSTEM", - "Configuration generation number", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 0, - 0, - 0x7FFFFFFF}, - - {"Name", - "Name", - "EXTERNAL SYSTEM", - "Name of external system (another NDB Cluster)", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - MANDATORY, - 0, - 0}, - - /***************************************************************************** + { + KEY_INTERNAL, + "ExecuteOnComputer", + "MGM", + "String referencing an earlier defined COMPUTER", + ConfigInfo::USED, + false, + ConfigInfo::STRING, + MANDATORY, + 0, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "MaxNoOfSavedEvents", + "MGM", + "", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 100, + 0, + 0x7FFFFFFF }, + + { + CFG_MGM_PORT, + "PortNumber", + "MGM", + "Port number to give commands to/fetch configurations from management server", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 2200, + 0, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "PortNumberStats", + "MGM", + "Port number used to get statistical information from a management server", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 2199, + 0, + 0x7FFFFFFF }, + + { + CFG_NODE_ARBIT_RANK, + "ArbitrationRank", + "MGM", + "If 0, then MGM is not arbitrator. Kernel selects arbitrators in order 1, 2", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 2, + 0, + 2 }, + + { + CFG_NODE_ARBIT_DELAY, + "ArbitrationDelay", + "MGM", + "", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 0, + 0, + 0x7FFFFFFF }, + + /**************************************************************************** * TCP - ****************************************************************************/ - - {"Type", - "Type", - "TCP", - "", - ConfigInfo::INTERNAL, - false, - ConfigInfo::STRING, - 0, - 0, - 0x7FFFFFFF}, - - {"HostName1", - "HostName1", - "TCP", - "Name of computer on one side of the connection", - ConfigInfo::INTERNAL, - false, - ConfigInfo::STRING, - UNDEFINED, - 0, - 0x7FFFFFFF}, - - {"HostName2", - "HostName2", - "TCP", - "Name of computer on one side of the connection", - ConfigInfo::INTERNAL, - false, - ConfigInfo::STRING, - UNDEFINED, - 0, - 0x7FFFFFFF}, - - {"NodeId1", - "NodeId1", - "TCP", - "Id of node (DB, API or MGM) on one side of the connection", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - MANDATORY, - 0, - 0x7FFFFFFF}, - - {"ProcessId1", - "NodeId1", - "TCP", - "Depricated", - ConfigInfo::DEPRICATED, - false, - ConfigInfo::INT, - UNDEFINED, - 0, - 0x7FFFFFFF}, - - {"NodeId2", - "NodeId2", - "TCP", - "Id of node (DB, API or MGM) on one side of the connection", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - MANDATORY, - 0, - 0x7FFFFFFF}, - - {"ProcessId2", - "NodeId2", - "TCP", - "Depricated", - ConfigInfo::DEPRICATED, - false, - ConfigInfo::INT, - UNDEFINED, - 0, - 0x7FFFFFFF}, - - {"IpAddress1", - "HostName1", - "TCP", - "IP address of first node in connection.", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - UNDEFINED, - 0, - 0x7FFFFFFF}, - - {"IpAddress2", - "HostName2", - "TCP", - "IP address of second node in connection.", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - UNDEFINED, - 0, - 0}, - - {"SendSignalId", - "SendSignalId", - "TCP", - "Sends id in each signal. Used in trace files.", - ConfigInfo::USED, - false, - ConfigInfo::BOOL, - true, - 0, - 0x7FFFFFFF}, - - {"Compression", - "Compression", - "TCP", - "If compression is enabled, then all signals between nodes are compressed", - ConfigInfo::USED, - false, - ConfigInfo::BOOL, - false, - 0, - 0x7FFFFFFF}, - - {"Checksum", - "Checksum", - "TCP", - "If checksum is enabled, all signals between nodes are checked for errors", - ConfigInfo::USED, - false, - ConfigInfo::BOOL, - false, - 0, - 0x7FFFFFFF}, - - {"PortNumber", - "PortNumber", - "TCP", - "Port used for this transporter", - ConfigInfo::USED, - false, - ConfigInfo::INT, - MANDATORY, - 0, - 0x7FFFFFFF}, - - {"SendBufferSize", - "SendBufferSize", - "TCP", - "Size of buffer for signals sent from this node (in no of signals)", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 16, - 1, - 0x7FFFFFFF}, + ***************************************************************************/ + { + CFG_SECTION_CONNECTION, + "TCP", + "TCP", + "Connection section", + ConfigInfo::USED, + false, + ConfigInfo::SECTION, + CONNECTION_TYPE_TCP, + 0, 0 + }, + + { + CFG_TCP_HOSTNAME_1, + "HostName1", + "TCP", + "Name/IP of computer on one side of the connection", + ConfigInfo::INTERNAL, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_TCP_HOSTNAME_2, + "HostName2", + "TCP", + "Name/IP of computer on one side of the connection", + ConfigInfo::INTERNAL, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_CONNECTION_NODE_1, + "NodeId1", + "TCP", + "Id of node (DB, API or MGM) on one side of the connection", + ConfigInfo::USED, + false, + ConfigInfo::STRING, + MANDATORY, + 0, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "ProcessId1", + "TCP", + "NodeId1", + ConfigInfo::DEPRICATED, + false, + ConfigInfo::INT, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_CONNECTION_NODE_2, + "NodeId2", + "TCP", + "Id of node (DB, API or MGM) on one side of the connection", + ConfigInfo::USED, + false, + ConfigInfo::STRING, + MANDATORY, + 0, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "ProcessId2", + "TCP", + "NodeId2", + ConfigInfo::DEPRICATED, + false, + ConfigInfo::INT, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "IpAddress1", + "TCP", + "HostName1", + ConfigInfo::DEPRICATED, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "IpAddress2", + "TCP", + "HostName2", + ConfigInfo::DEPRICATED, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0 }, + + { + CFG_CONNECTION_SEND_SIGNAL_ID, + "SendSignalId", + "TCP", + "Sends id in each signal. Used in trace files.", + ConfigInfo::USED, + false, + ConfigInfo::BOOL, + true, + 0, + 0x7FFFFFFF }, + + + { + CFG_CONNECTION_CHECKSUM, + "Checksum", + "TCP", + "If checksum is enabled, all signals between nodes are checked for errors", + ConfigInfo::USED, + false, + ConfigInfo::BOOL, + false, + 0, + 0x7FFFFFFF }, + + { + CFG_TCP_SERVER_PORT, + "PortNumber", + "TCP", + "Port used for this transporter", + ConfigInfo::USED, + false, + ConfigInfo::INT, + MANDATORY, + 0, + 0x7FFFFFFF }, + + { + CFG_TCP_SEND_BUFFER_SIZE, + "SendBufferMemory", + "TCP", + "Bytes of buffer for signals sent from this node", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 16 * 16384, + 1 * 16384, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "SendBufferSize", + "TCP", + "SendBufferMemory", + ConfigInfo::DEPRICATED, + false, + ConfigInfo::INT, + 16, + 1, + 0x7FFFFFFF }, - {"MaxReceiveSize", - "MaxReceiveSize", - "TCP", - "Size of buffer for signals received by this node (in no of signals)", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 4, - 1, - 0x7FFFFFFF}, - - {"Proxy", - "Proxy", - "TCP", - "", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - UNDEFINED, - 0, - 0}, - - /***************************************************************************** - * SHM - ****************************************************************************/ - - {"Type", - "Type", - "SHM", - "", - ConfigInfo::INTERNAL, - false, - ConfigInfo::STRING, - 0, - 0, - 0x7FFFFFFF}, + { + CFG_TCP_RECEIVE_BUFFER_SIZE, + "ReceiveBufferMemory", + "TCP", + "Bytes of buffer for signals received by this node", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 4 * 16384, + 1 * 16384, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "MaxReceiveSize", + "TCP", + "ReceiveBufferMemory", + ConfigInfo::DEPRICATED, + false, + ConfigInfo::INT, + 4, + 1, + 0x7FFFFFFF }, + + { + CFG_TCP_PROXY, + "Proxy", + "TCP", + "", + ConfigInfo::USED, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0 }, + + { + KEY_INTERNAL, + "Compression", + "TCP", + 0, + ConfigInfo::DEPRICATED, + false, + ConfigInfo::BOOL, + false, + 0, + 0x7FFFFFFF }, + + + { + CFG_CONNECTION_NODE_1_SYSTEM, + "NodeId1_System", + "TCP", + "System for node 1 in connection", + ConfigInfo::INTERNAL, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_CONNECTION_NODE_2_SYSTEM, + "NodeId2_System", + "TCP", + "System for node 2 in connection", + ConfigInfo::INTERNAL, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, - {"NodeId1", - "NodeId1", - "SHM", - "Id of node (DB, API or MGM) on one side of the connection", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - MANDATORY, - 0, - 0x7FFFFFFF}, + + /**************************************************************************** + * SHM + ***************************************************************************/ + { + CFG_SECTION_CONNECTION, + "SHM", + "SHM", + "Connection section", + ConfigInfo::USED, + false, + ConfigInfo::SECTION, + CONNECTION_TYPE_SHM, + 0, 0 + }, + + { + CFG_CONNECTION_NODE_1, + "NodeId1", + "SHM", + "Id of node (DB, API or MGM) on one side of the connection", + ConfigInfo::USED, + false, + ConfigInfo::STRING, + MANDATORY, + 0, + 0x7FFFFFFF }, - {"ProcessId1", - "NodeId1", - "SHM", - "Depricated", - ConfigInfo::DEPRICATED, - false, - ConfigInfo::STRING, - UNDEFINED, - 0, - 0x7FFFFFFF}, + { + KEY_INTERNAL, + "ProcessId1", + "SHM", + "NodeId1", + ConfigInfo::DEPRICATED, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, - {"NodeId2", - "NodeId2", - "SHM", - "Id of node (DB, API or MGM) on one side of the connection", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - MANDATORY, - 0, - 0x7FFFFFFF}, + { + CFG_CONNECTION_NODE_2, + "NodeId2", + "SHM", + "Id of node (DB, API or MGM) on one side of the connection", + ConfigInfo::USED, + false, + ConfigInfo::STRING, + MANDATORY, + 0, + 0x7FFFFFFF }, - {"ProcessId2", - "NodeId2", - "SHM", - "Depricated", - ConfigInfo::DEPRICATED, - false, - ConfigInfo::STRING, - UNDEFINED, - 0, - 0x7FFFFFFF}, + { + KEY_INTERNAL, + "ProcessId2", + "SHM", + "NodeId1", + ConfigInfo::DEPRICATED, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, - {"SendSignalId", - "SendSignalId", - "SHM", - "Sends id in each signal. Used in trace files.", - ConfigInfo::USED, - false, - ConfigInfo::BOOL, - false, - 0, - 0x7FFFFFFF}, + { + CFG_CONNECTION_SEND_SIGNAL_ID, + "SendSignalId", + "SHM", + "Sends id in each signal. Used in trace files.", + ConfigInfo::USED, + false, + ConfigInfo::BOOL, + false, + 0, + 0x7FFFFFFF }, - {"Compression", - "Compression", - "SHM", - "If compression is enabled, then all signals between nodes are compressed", - ConfigInfo::USED, - false, - ConfigInfo::BOOL, - false, - 0, - 0x7FFFFFFF}, - {"Checksum", - "Checksum", - "SHM", - "If checksum is enabled, all signals between nodes are checked for errors", - ConfigInfo::USED, - false, - ConfigInfo::BOOL, - true, - 0, - 0x7FFFFFFF}, + { + CFG_CONNECTION_CHECKSUM, + "Checksum", + "SHM", + "If checksum is enabled, all signals between nodes are checked for errors", + ConfigInfo::USED, + false, + ConfigInfo::BOOL, + true, + 0, + 0x7FFFFFFF }, - {"ShmKey", - "ShmKey", - "SHM", - "A shared memory key", - ConfigInfo::USED, - false, - ConfigInfo::INT, - MANDATORY, - 0, - 0x7FFFFFFF }, + { + CFG_SHM_KEY, + "ShmKey", + "SHM", + "A shared memory key", + ConfigInfo::USED, + false, + ConfigInfo::INT, + MANDATORY, + 0, + 0x7FFFFFFF }, - {"ShmSize", - "ShmSize", - "SHM", - "Size of shared memory segment", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 1048576, - 4096, - 0x7FFFFFFF}, + { + CFG_SHM_BUFFER_MEM, + "ShmSize", + "SHM", + "Size of shared memory segment", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 1048576, + 4096, + 0x7FFFFFFF }, - /***************************************************************************** + { + KEY_INTERNAL, + "Compression", + "SHM", + 0, + ConfigInfo::DEPRICATED, + false, + ConfigInfo::BOOL, + false, + 0, + 0x7FFFFFFF }, + + { + CFG_CONNECTION_NODE_1_SYSTEM, + "NodeId1_System", + "SHM", + "System for node 1 in connection", + ConfigInfo::INTERNAL, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_CONNECTION_NODE_2_SYSTEM, + "NodeId2_System", + "SHM", + "System for node 2 in connection", + ConfigInfo::INTERNAL, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + /**************************************************************************** * SCI - ****************************************************************************/ - - {"NodeId1", - "NodeId1", - "SCI", - "Id of node (DB, API or MGM) on one side of the connection", - ConfigInfo::USED, - false, - ConfigInfo::INT, - MANDATORY, - 0, - 0x7FFFFFFF}, - - {"ProcessId1", - "NodeId1", - "SCI", - "Depricated", - ConfigInfo::DEPRICATED, - false, - ConfigInfo::INT, - UNDEFINED, - 0, - 0x7FFFFFFF}, - - {"NodeId2", - "NodeId2", - "SCI", - "Id of node (DB, API or MGM) on one side of the connection", - ConfigInfo::USED, - false, - ConfigInfo::INT, - MANDATORY, - 0, - 0x7FFFFFFF}, - - {"ProcessId2", - "NodeId2", - "SCI", - "Depricated", - ConfigInfo::DEPRICATED, - false, - ConfigInfo::INT, - UNDEFINED, - 0, - 0x7FFFFFFF}, - - {"SciId0", - "SciId0", - "SCI", - "Local SCI-node id for adapter 0 (a computer can have two adapters)", - ConfigInfo::USED, - false, - ConfigInfo::INT, - MANDATORY, - 0, - 0x7FFFFFFF}, - - {"SciId1", - "SciId1", - "SCI", - "Local SCI-node id for adapter 1 (a computer can have two adapters)", - ConfigInfo::USED, - false, - ConfigInfo::INT, - MANDATORY, - 0, - 0x7FFFFFFF}, - - {"SendSignalId", - "SendSignalId", - "SCI", - "Sends id in each signal. Used in trace files.", - ConfigInfo::USED, - false, - ConfigInfo::BOOL, - true, - 0, - 0x7FFFFFFF}, - - {"Compression", - "Compression", - "SCI", - "If compression is enabled, then all signals between nodes are compressed", - ConfigInfo::USED, - false, - ConfigInfo::BOOL, - false, - 0, - 0x7FFFFFFF}, - - {"Checksum", - "Checksum", - "SCI", - "If checksum is enabled, all signals between nodes are checked for errors", - ConfigInfo::USED, - false, - ConfigInfo::BOOL, - false, - 0, - 0x7FFFFFFF}, - - {"SendLimit", - "SendLimit", - "SCI", - "Transporter send buffer contents are sent when this no of bytes is buffered", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 2048, - 512, - 0x7FFFFFFF}, - - {"SharedBufferSize", - "SharedBufferSize", - "SCI", - "Size of shared memory segment", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 1048576, - 262144, - 0x7FFFFFFF}, - - {"Node1_NoOfAdapters", - "Node1_NoOfAdapters", - "SCI", - "", - ConfigInfo::DEPRICATED, - false, - ConfigInfo::INT, - UNDEFINED, - 0, - 0x7FFFFFFF}, - - {"Node2_NoOfAdapters", - "Node2_NoOfAdapters", - "SCI", - "", - ConfigInfo::DEPRICATED, - false, - ConfigInfo::INT, - UNDEFINED, - 0, - 0x7FFFFFFF}, - - {"Node1_Adapter", - "Node1_Adapter", - "SCI", - "", - ConfigInfo::DEPRICATED, - false, - ConfigInfo::INT, - UNDEFINED, - 0, - 0x7FFFFFFF}, - - {"Node2_Adapter", - "Node2_Adapter", - "SCI", - "", - ConfigInfo::DEPRICATED, - false, - ConfigInfo::INT, - UNDEFINED, - 0, - 0x7FFFFFFF}, - - /***************************************************************************** + ***************************************************************************/ + { + CFG_SECTION_CONNECTION, + "SCI", + "SCI", + "Connection section", + ConfigInfo::USED, + false, + ConfigInfo::SECTION, + CONNECTION_TYPE_SCI, + 0, 0 + }, + + { + CFG_CONNECTION_NODE_1, + "NodeId1", + "SCI", + "Id of node (DB, API or MGM) on one side of the connection", + ConfigInfo::USED, + false, + ConfigInfo::INT, + MANDATORY, + 0, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "ProcessId1", + "SCI", + "NodeId1", + ConfigInfo::DEPRICATED, + false, + ConfigInfo::INT, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_CONNECTION_NODE_2, + "NodeId2", + "SCI", + "Id of node (DB, API or MGM) on one side of the connection", + ConfigInfo::USED, + false, + ConfigInfo::INT, + MANDATORY, + 0, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "ProcessId2", + "SCI", + "NodeId2", + ConfigInfo::DEPRICATED, + false, + ConfigInfo::INT, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_SCI_ID_0, + "SciId0", + "SCI", + "Local SCI-node id for adapter 0 (a computer can have two adapters)", + ConfigInfo::USED, + false, + ConfigInfo::INT, + MANDATORY, + 0, + 0x7FFFFFFF }, + + { + CFG_SCI_ID_1, + "SciId1", + "SCI", + "Local SCI-node id for adapter 1 (a computer can have two adapters)", + ConfigInfo::USED, + false, + ConfigInfo::INT, + MANDATORY, + 0, + 0x7FFFFFFF }, + + { + CFG_CONNECTION_SEND_SIGNAL_ID, + "SendSignalId", + "SCI", + "Sends id in each signal. Used in trace files.", + ConfigInfo::USED, + false, + ConfigInfo::BOOL, + true, + 0, + 0x7FFFFFFF }, + + { + CFG_CONNECTION_CHECKSUM, + "Checksum", + "SCI", + "If checksum is enabled, all signals between nodes are checked for errors", + ConfigInfo::USED, + false, + ConfigInfo::BOOL, + false, + 0, + 0x7FFFFFFF }, + + { + CFG_SCI_SEND_LIMIT, + "SendLimit", + "SCI", + "Transporter send buffer contents are sent when this no of bytes is buffered", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 2048, + 512, + 0x7FFFFFFF }, + + { + CFG_SCI_BUFFER_MEM, + "SharedBufferSize", + "SCI", + "Size of shared memory segment", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 1048576, + 262144, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "Node1_NoOfAdapters", + "SCI", + 0, + ConfigInfo::DEPRICATED, + false, + ConfigInfo::INT, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "Node2_NoOfAdapters", + "SCI", + 0, + ConfigInfo::DEPRICATED, + false, + ConfigInfo::INT, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "Node1_Adapter", + "SCI", + 0, + ConfigInfo::DEPRICATED, + false, + ConfigInfo::INT, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "Node2_Adapter", + "SCI", + 0, + ConfigInfo::DEPRICATED, + false, + ConfigInfo::INT, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "Compression", + "SCI", + 0, + ConfigInfo::DEPRICATED, + false, + ConfigInfo::BOOL, + false, + 0, + 0x7FFFFFFF }, + + { + CFG_CONNECTION_NODE_1_SYSTEM, + "NodeId1_System", + "SCI", + "System for node 1 in connection", + ConfigInfo::INTERNAL, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_CONNECTION_NODE_2_SYSTEM, + "NodeId2_System", + "SCI", + "System for node 2 in connection", + ConfigInfo::INTERNAL, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + /**************************************************************************** * OSE - ****************************************************************************/ - - {"Type", - "Type", - "OSE", - "", - ConfigInfo::INTERNAL, - false, - ConfigInfo::STRING, - 0, - 0, - 0x7FFFFFFF}, - - {"HostName1", - "HostName1", - "OSE", - "Name of computer on one side of the connection", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - UNDEFINED, - 0, - 0x7FFFFFFF}, - - {"HostName2", - "HostName2", - "OSE", - "Name of computer on one side of the connection", - ConfigInfo::USED, - false, - ConfigInfo::STRING, - UNDEFINED, - 0, - 0x7FFFFFFF}, - - {"NodeId1", - "NodeId1", - "OSE", - "Id of node (DB, API or MGM) on one side of the connection", - ConfigInfo::USED, - false, - ConfigInfo::INT, - MANDATORY, - 0, - 0x7FFFFFFF}, - - {"ProcessId1", - "NodeId1", - "OSE", - "Depricated", - ConfigInfo::DEPRICATED, - false, - ConfigInfo::INT, - UNDEFINED, - 0, - 0x7FFFFFFF}, - - {"NodeId2", - "NodeId2", - "OSE", - "Id of node (DB, API or MGM) on one side of the connection", - ConfigInfo::DEPRICATED, - false, - ConfigInfo::INT, - UNDEFINED, - 0, - 0x7FFFFFFF}, - - {"ProcessId2", - "NodeId2", - "OSE", - "Depricated", - ConfigInfo::USED, - false, - ConfigInfo::INT, - MANDATORY, - 0, - 0x7FFFFFFF}, - - {"SendSignalId", - "SendSignalId", - "OSE", - "Sends id in each signal. Used in trace files.", - ConfigInfo::USED, - false, - ConfigInfo::BOOL, - true, - 0, - 0x7FFFFFFF}, - - {"Compression", - "Compression", - "OSE", - "If compression is enabled, then all signals between nodes are compressed", - ConfigInfo::USED, - false, - ConfigInfo::BOOL, - false, - 0, - 0x7FFFFFFF}, - - {"Checksum", - "Checksum", - "OSE", - "If checksum is enabled, all signals between nodes are checked for errors", - ConfigInfo::USED, - false, - ConfigInfo::BOOL, - false, - 0, - 0x7FFFFFFF}, - - // Should not be part of OSE ? - {"SharedBufferSize", - "SharedBufferSize", - "OSE", - "?", - ConfigInfo::DEPRICATED, - false, - ConfigInfo::INT, - UNDEFINED, - 2000, - 0x7FFFFFFF}, - - {"PrioASignalSize", - "PrioASignalSize", - "OSE", - "Size of priority A signals (in bytes)", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 1000, - 0, - 0x7FFFFFFF}, - - {"PrioBSignalSize", - "PrioBSignalSize", - "OSE", - "Size of priority B signals (in bytes)", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 1000, - 0, - 0x7FFFFFFF}, - - {"ReceiveArraySize", - "ReceiveArraySize", - "OSE", - "Number of OSE signals checked for correct ordering (in no of OSE signals)", - ConfigInfo::USED, - false, - ConfigInfo::INT, - 10, - 0, - 0x7FFFFFFF} + ***************************************************************************/ + { + CFG_SECTION_CONNECTION, + "OSE", + "OSE", + "Connection section", + ConfigInfo::USED, + false, + ConfigInfo::SECTION, + CONNECTION_TYPE_OSE, + 0, 0 + }, + + { + CFG_OSE_HOSTNAME_1, + "HostName1", + "OSE", + "Name of computer on one side of the connection", + ConfigInfo::USED, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_OSE_HOSTNAME_2, + "HostName2", + "OSE", + "Name of computer on one side of the connection", + ConfigInfo::USED, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_CONNECTION_NODE_1, + "NodeId1", + "OSE", + "Id of node (DB, API or MGM) on one side of the connection", + ConfigInfo::USED, + false, + ConfigInfo::INT, + MANDATORY, + 0, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "ProcessId1", + "OSE", + "NodeId1", + ConfigInfo::DEPRICATED, + false, + ConfigInfo::INT, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_CONNECTION_NODE_2, + "NodeId2", + "OSE", + "Id of node (DB, API or MGM) on one side of the connection", + ConfigInfo::USED, + false, + ConfigInfo::INT, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "ProcessId2", + "OSE", + "NodeId2", + ConfigInfo::DEPRICATED, + false, + ConfigInfo::INT, + MANDATORY, + 0, + 0x7FFFFFFF }, + + { + CFG_CONNECTION_SEND_SIGNAL_ID, + "SendSignalId", + "OSE", + "Sends id in each signal. Used in trace files.", + ConfigInfo::USED, + false, + ConfigInfo::BOOL, + true, + 0, + 0x7FFFFFFF }, + + { + CFG_CONNECTION_CHECKSUM, + "Checksum", + "OSE", + "If checksum is enabled, all signals between nodes are checked for errors", + ConfigInfo::USED, + false, + ConfigInfo::BOOL, + false, + 0, + 0x7FFFFFFF }, + + { + CFG_OSE_PRIO_A_SIZE, + "PrioASignalSize", + "OSE", + "Size of priority A signals (in bytes)", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 1000, + 0, + 0x7FFFFFFF }, + + { + CFG_OSE_PRIO_B_SIZE, + "PrioBSignalSize", + "OSE", + "Size of priority B signals (in bytes)", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 1000, + 0, + 0x7FFFFFFF }, + + { + CFG_OSE_RECEIVE_ARRAY_SIZE, + "ReceiveArraySize", + "OSE", + "Number of OSE signals checked for correct ordering (in no of OSE signals)", + ConfigInfo::USED, + false, + ConfigInfo::INT, + 10, + 0, + 0x7FFFFFFF }, + + { + KEY_INTERNAL, + "Compression", + "OSE", + 0, + ConfigInfo::DEPRICATED, + false, + ConfigInfo::BOOL, + false, + 0, + 0x7FFFFFFF }, + + { + CFG_CONNECTION_NODE_1_SYSTEM, + "NodeId1_System", + "OSE", + "System for node 1 in connection", + ConfigInfo::INTERNAL, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, + + { + CFG_CONNECTION_NODE_2_SYSTEM, + "NodeId2_System", + "OSE", + "System for node 2 in connection", + ConfigInfo::INTERNAL, + false, + ConfigInfo::STRING, + UNDEFINED, + 0, + 0x7FFFFFFF }, }; const int ConfigInfo::m_NoOfParams = sizeof(m_ParamInfo) / sizeof(ParamInfo); @@ -1908,21 +2189,21 @@ ConfigInfo::ConfigInfo() { newsection.setCaseInsensitiveNames(true); m_info.put(param._section, &newsection); } - + // Get copy of section m_info.getCopy(param._section, §ion); // Create pinfo (parameter info) entry Properties pinfo; + pinfo.put("Id", param._paramId); pinfo.put("Fname", param._fname); - pinfo.put("Pname", param._pname); pinfo.put("Description", param._description); pinfo.put("Updateable", param._updateable); pinfo.put("Type", param._type); pinfo.put("Status", param._status); - pinfo.put("Default", param._default); - pinfo.put("Min", param._min); - pinfo.put("Max", param._max); + pinfo.put64("Default", param._default); + pinfo.put64("Min", param._min); + pinfo.put64("Max", param._max); // Check that pinfo is really new if (section->get(param._fname, &oldpinfo)) { @@ -1937,8 +2218,8 @@ ConfigInfo::ConfigInfo() { // Replace section with modified section m_info.put(param._section, section, true); - - { + + if(param._type != ConfigInfo::SECTION){ Properties * p; if(!m_systemDefaults.getCopy(param._section, &p)){ p = new Properties(); @@ -1947,26 +2228,28 @@ ConfigInfo::ConfigInfo() { if(param._type != STRING && param._default != UNDEFINED && param._default != MANDATORY){ - require(p->put(param._pname, param._default)); + require(p->put(param._fname, param._default)); } require(m_systemDefaults.put(param._section, p, true)); delete p; } } - + for (int i=0; i<m_NoOfParams; i++) { if(m_ParamInfo[i]._section == NULL){ - ndbout << "Check that each pname has an fname failed." << endl; - ndbout << "Parameter \"" << m_ParamInfo[i]._pname - << "\" does not exist in section \"" - << m_ParamInfo[i]._section << "\"." << endl; + ndbout << "Check that each entry has a section failed." << endl; + ndbout << "Parameter \"" << m_ParamInfo[i]._fname << endl; ndbout << "Edit file " << __FILE__ << "." << endl; exit(-1); } + + if(m_ParamInfo[i]._type == ConfigInfo::SECTION) + continue; + const Properties * p = getInfo(m_ParamInfo[i]._section); - if (!p || !p->contains(m_ParamInfo[i]._pname)) { + if (!p || !p->contains(m_ParamInfo[i]._fname)) { ndbout << "Check that each pname has an fname failed." << endl; - ndbout << "Parameter \"" << m_ParamInfo[i]._pname + ndbout << "Parameter \"" << m_ParamInfo[i]._fname << "\" does not exist in section \"" << m_ParamInfo[i]._section << "\"." << endl; ndbout << "Edit file " << __FILE__ << "." << endl; @@ -2002,16 +2285,27 @@ ConfigInfo::getDefaults(const char * section) const { } static -Uint32 +Uint64 getInfoInt(const Properties * section, const char* fname, const char * type){ - Uint32 val; + Uint32 val32; const Properties * p; - if (section->get(fname, &p) && p->get(type, &val)) { - return val; + 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 val; + return 0; } static @@ -2027,27 +2321,22 @@ getInfoString(const Properties * section, return val; } -Uint32 +Uint64 ConfigInfo::getMax(const Properties * section, const char* fname) const { return getInfoInt(section, fname, "Max"); } -Uint32 +Uint64 ConfigInfo::getMin(const Properties * section, const char* fname) const { return getInfoInt(section, fname, "Min"); } -Uint32 +Uint64 ConfigInfo::getDefault(const Properties * section, const char* fname) const { return getInfoInt(section, fname, "Default"); } const char* -ConfigInfo::getPName(const Properties * section, const char* fname) const { - return getInfoString(section, fname, "Pname"); -} - -const char* ConfigInfo::getDescription(const Properties * section, const char* fname) const { return getInfoString(section, fname, "Description"); @@ -2063,8 +2352,8 @@ ConfigInfo::isSection(const char * section) const { bool ConfigInfo::verify(const Properties * section, const char* fname, - Uint32 value) const { - Uint32 min, max; min = max + 1; + Uint64 value) const { + Uint64 min, max; min = max + 1; min = getInfoInt(section, fname, "Min"); max = getInfoInt(section, fname, "Max"); @@ -2104,7 +2393,6 @@ void ConfigInfo::print(const char* section) const { Properties::Iterator it(sec); for (const char* n = it.first(); n != NULL; n = it.next()) { // Skip entries with different F- and P-names - if (strcmp(n, getPName(sec, n))) continue; if (getStatus(sec, n) == ConfigInfo::INTERNAL) continue; if (getStatus(sec, n) == ConfigInfo::DEPRICATED) continue; if (getStatus(sec, n) == ConfigInfo::NOTIMPLEMENTED) continue; @@ -2114,7 +2402,7 @@ void ConfigInfo::print(const char* section) const { void ConfigInfo::print(const Properties * section, const char* parameter) const { - ndbout << getPName(section, parameter); + ndbout << parameter; // ndbout << getDescription(section, parameter) << endl; switch (getType(section, parameter)) { case ConfigInfo::BOOL: @@ -2133,6 +2421,7 @@ void ConfigInfo::print(const Properties * section, break; case ConfigInfo::INT: + case ConfigInfo::INT64: ndbout << " (Non-negative Integer)" << endl; ndbout << getDescription(section, parameter) << endl; if (getDefault(section, parameter) == MANDATORY) { @@ -2189,6 +2478,37 @@ transformNode(InitConfigFileParser::Context & ctx, const char * data){ } bool +fixNodeHostname(InitConfigFileParser::Context & ctx, const char * data){ + + const char * compId; + if(!ctx.m_currentSection->get("ExecuteOnComputer", &compId)){ + ctx.reportError("Parameter \"ExecuteOnComputer\" missing from section " + "[%s] starting at line: %d", + ctx.fname, ctx.m_sectionLineno); + return false; + } + + const Properties * computer; + char tmp[255]; + 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); + } + + const char * hostname; + if(!computer->get("HostName", &hostname)){ + ctx.reportError("HostName missing in [COMPUTER] Id: %s" + "- [%s] starting at line: %d", + compId, ctx.fname, ctx.m_sectionLineno); + } + + require(ctx.m_currentSection->put("HostName", hostname)); + return true; +} + +bool transformExtNode(InitConfigFileParser::Context & ctx, const char * data){ Uint32 id; @@ -2301,6 +2621,7 @@ applyDefaultValues(InitConfigFileParser::Context & ctx, Properties::Iterator it(defaults); for(const char * name = it.first(); name != NULL; name = it.next()){ + ConfigInfo::Status st = 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::INT: @@ -2310,6 +2631,12 @@ applyDefaultValues(InitConfigFileParser::Context & ctx, ctx.m_currentSection->put(name, val); break; } + case ConfigInfo::INT64:{ + Uint64 val = 0; + ::require(defaults->get(name, &val)); + ctx.m_currentSection->put64(name, val); + break; + } case ConfigInfo::STRING:{ const char * val; ::require(defaults->get(name, &val)); @@ -2325,9 +2652,13 @@ applyDefaultValues(InitConfigFileParser::Context & ctx, bool applyDefaultValues(InitConfigFileParser::Context & ctx, const char * data){ - applyDefaultValues(ctx, ctx.m_userDefaults); - applyDefaultValues(ctx, ctx.m_systemDefaults); - + 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; } @@ -2343,11 +2674,9 @@ checkMandatory(InitConfigFileParser::Context & ctx, const char * data){ ::require(ctx.m_currentInfo->get(name, &info)); Uint32 val; if(info->get("Default", &val) && val == MANDATORY){ - const char * pname; const char * fname; - ::require(info->get("Pname", &pname)); ::require(info->get("Fname", &fname)); - if(!ctx.m_currentSection->contains(pname)){ + 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); @@ -2493,20 +2822,12 @@ fixHostname(InitConfigFileParser::Context & ctx, const char * data){ if(!ctx.m_currentSection->contains(data)){ Uint32 id = 0; require(ctx.m_currentSection->get(buf, &id)); - + const Properties * node; require(ctx.m_config->get("Node", id, &node)); - const char * compId; - require(node->get("ExecuteOnComputer", &compId)); - - const Properties * computer; - char tmp[255]; - snprintf(tmp, sizeof(tmp), "Computer_%s", compId); - require(ctx.m_config->get(tmp, &computer)); - const char * hostname; - require(computer->get("HostName", &hostname)); + require(node->get("HostName", &hostname)); require(ctx.m_currentSection->put(data, hostname)); } return true; @@ -2627,3 +2948,180 @@ checkConnectionConstraints(InitConfigFileParser::Context & ctx, const char *){ } 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::INT || newType == ConfigInfo::INT64))){ + 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)(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::INT){ + require(dst.put(newName, (Uint32)newVal)); + } else { + require(dst.put64(newName, newVal)); + } + return true; +} + +bool +fixDepricated(InitConfigFileParser::Context & ctx, const char * data){ + /** + * Transform old values to new values + * Transform new values to old values (backward compatible) + */ + Properties tmp; + Properties::Iterator it(ctx.m_currentSection); + for (const char* 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(strcmp(name, p->m_oldName) == 0){ + if(!transform(ctx, tmp, name, p->m_newName, add, mul)){ + return false; + } + } else if(strcmp(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 (const char* 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: + abort(); + } + } + return true; +} + +bool +saveInConfigValues(InitConfigFileParser::Context & ctx, const char * data){ + const Properties * sec; + if(!ctx.m_currentInfo->get(ctx.fname, &sec)){ + abort(); + 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("Default", &typeVal)); + + if(id == KEY_INTERNAL || status == ConfigInfo::INTERNAL){ + ndbout_c("skipping section %s", ctx.fname); + break; + } + + 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; + + Uint32 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); + break; + } + case PropertiesType_Uint64:{ + Uint64 val; + require(ctx.m_currentSection->get(n, &val)); + ok = ctx.m_configValues.put64(id, val); + break; + } + case PropertiesType_char:{ + const char * val; + require(ctx.m_currentSection->get(n, &val)); + ok = ctx.m_configValues.put(id, val); + break; + } + default: + abort(); + } + } + ctx.m_configValues.closeSection(); + } while(0); + return true; +} diff --git a/ndb/src/common/mgmcommon/ConfigInfo.hpp b/ndb/src/common/mgmcommon/ConfigInfo.hpp index 43041a3f772..b5e011ed398 100644 --- a/ndb/src/common/mgmcommon/ConfigInfo.hpp +++ b/ndb/src/common/mgmcommon/ConfigInfo.hpp @@ -27,8 +27,8 @@ * A MANDATORY parameters must be specified in the config file * An UNDEFINED parameter may or may not be specified in the config file */ -static const Uint32 MANDATORY = ~0; // Default value for mandatory params. -static const Uint32 UNDEFINED = (~0)-1; // Default value for undefined params. +static const Uint64 MANDATORY = ~0; // Default value for mandatory params. +static const Uint64 UNDEFINED = (~0)-1; // Default value for undefined params. /** * @class ConfigInfo @@ -38,27 +38,27 @@ static const Uint32 UNDEFINED = (~0)-1; // Default value for undefined params. */ class ConfigInfo { public: - enum Type {BOOL, INT, STRING}; - enum Status {USED, ///< Active - DEPRICATED, ///< Can be, but should not be used anymore - NOTIMPLEMENTED, ///< Can not be used currently. Is ignored. - INTERNAL ///< Not configurable by the user + enum Type { BOOL, INT, INT64, STRING, SECTION }; + enum Status { USED, ///< Active + DEPRICATED, ///< Can be, but shouldn't + NOTIMPLEMENTED, ///< Is ignored. + INTERNAL ///< Not configurable by the user }; /** * Entry for one configuration parameter */ struct ParamInfo { + Uint32 _paramId; const char* _fname; - const char* _pname; const char* _section; const char* _description; Status _status; bool _updateable; Type _type; - Uint32 _default; - Uint32 _min; - Uint32 _max; + Uint64 _default; + Uint64 _min; + Uint64 _max; }; /** @@ -84,16 +84,15 @@ public: * * @note Result is not defined if section/name are wrong! */ - bool verify(const Properties* section, const char* fname, Uint32 value) const; + bool verify(const Properties* secti, const char* fname, Uint64 value) const; bool isSection(const char*) const; - const char* getPName(const Properties * section, const char* fname) const; - const char* getDescription(const Properties * section, const char* fname) 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; - Uint32 getMin(const Properties * section, const char* fname) const; - Uint32 getMax(const Properties * section, const char* fname) const; - Uint32 getDefault(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; diff --git a/ndb/src/common/mgmcommon/ConfigRetriever.cpp b/ndb/src/common/mgmcommon/ConfigRetriever.cpp index 04dc5466bbc..d2c622593de 100644 --- a/ndb/src/common/mgmcommon/ConfigRetriever.cpp +++ b/ndb/src/common/mgmcommon/ConfigRetriever.cpp @@ -33,6 +33,12 @@ #include <socket_io.h> #include <NdbConfig.h> +#include <NdbAutoPtr.hpp> + +#include <mgmapi.h> +#include <mgmapi_config_parameters.h> +#include <ConfigValues.hpp> +#include <NdbHost.h> //**************************************************************************** //**************************************************************************** @@ -83,41 +89,10 @@ ConfigRetriever::init(bool onlyNodeId) { //**************************************************************************** //**************************************************************************** - -Properties * -ConfigRetriever::getConfig(const char * nodeType, int versionId) { - Properties * p = getConfig(versionId); - - if (p == 0) { - char err_buf[255]; - snprintf(err_buf, sizeof(err_buf), - "No configuration retrieved for this %s node ", nodeType); - setError(CR_ERROR, err_buf); - return 0; - } - - const Uint32 nodeId = _ownNodeId; - - if (strcmp(nodeType, "DB") == 0) { - if (!verifyProperties("DB", p, nodeId, versionId)) return 0; - } else if (strcmp(nodeType, "API") == 0) { - if (!verifyProperties("API", p, nodeId, versionId)) return 0; - } else if (strcmp(nodeType, "REP") == 0) { - if (!verifyProperties("REP", p, nodeId, versionId)) return 0; - } else if (strcmp(nodeType, "MGM") == 0) { - if (!verifyProperties("MGM", p, nodeId, versionId)) return 0; - } else { - return 0; - } - - return p; -} - - //**************************************************************************** //**************************************************************************** -Properties * -ConfigRetriever::getConfig(int verId) { +struct ndb_mgm_configuration* +ConfigRetriever::getConfig(int verId, int nodeType) { int res = init(); if (res == -1) { @@ -125,7 +100,7 @@ ConfigRetriever::getConfig(int verId) { } if (_localConfig->items == 0){ - setError(CR_ERROR, "No Management Servers configured in local config file"); + setError(CR_ERROR,"No Management Servers configured in local config file"); return 0; } @@ -136,14 +111,13 @@ ConfigRetriever::getConfig(int verId) { Uint32 type = CR_ERROR; for (int i = 0; i<_localConfig->items; i++){ MgmtSrvrId * m = _localConfig->ids[i]; - Properties * p = 0; - const Uint32 nodeId = _ownNodeId; + struct ndb_mgm_configuration * p = 0; switch(m->type){ case MgmId_TCP: - p = getConfig(m->data.tcp.remoteHost, m->data.tcp.port, nodeId, verId); + p = getConfig(m->data.tcp.remoteHost, m->data.tcp.port, verId); break; case MgmId_File: - p = getConfig(m->data.file.filename, nodeId, verId); + p = getConfig(m->data.file.filename, verId); break; default: setError(CR_ERROR, "Unknown error type"); @@ -151,6 +125,10 @@ ConfigRetriever::getConfig(int verId) { } if (p != 0) { + if(!verifyConfig(p, nodeType)){ + free(p); + return 0; + } return p; } if(latestErrorType == CR_RETRY) @@ -161,110 +139,49 @@ ConfigRetriever::getConfig(int verId) { REPORT_WARNING("Failed to retrieve cluster configuration"); ndbout << "(Cause of failure: " << getErrorString() << ")" << endl; ndbout << "Attempt " << retry << " of " << retry_max << ". " - << "Trying again in "<<retry_interval<<" seconds..." << endl << endl; + << "Trying again in "<< retry_interval <<" seconds..." + << endl << endl; NdbSleep_SecSleep(retry_interval); } else { break; } retry++; - + } while (retry <= retry_max); return 0; } -int global_ndb_check = 0; // set to one in ndb main; -Properties * +ndb_mgm_configuration * ConfigRetriever::getConfig(const char * mgmhost, - unsigned int port, - Uint32 nodeId, + short port, int versionId){ - const int socketTimeout = 10000; - int result; - const NDB_SOCKET_TYPE sockfd = socket(AF_INET, SOCK_STREAM, 0); - if (sockfd == NDB_INVALID_SOCKET) { - setError(CR_RETRY, "Could not create socket to Management Server"); + + NdbMgmHandle h; + h = ndb_mgm_create_handle(); + if (h == NULL) { + setError(CR_ERROR, "Unable to allocate mgm handle"); return 0; } - char err_buf[255]; - struct sockaddr_in servaddr; - memset(&servaddr, 0, sizeof(servaddr)); - servaddr.sin_family = AF_INET; - servaddr.sin_port = htons(port); - // Convert ip address presentation format to numeric format - result = Ndb_getInAddr(&servaddr.sin_addr, mgmhost); - if (result != 0) { - snprintf(err_buf, sizeof(err_buf), - "Name lookup failed: host \"%s\"", mgmhost); - setError(CR_ERROR, err_buf); + BaseString tmp; + tmp.assfmt("%s:%d", mgmhost, port); + if (ndb_mgm_connect(h, tmp.c_str()) != 0) { + setError(CR_RETRY, ndb_mgm_get_latest_error_desc(h)); + ndb_mgm_destroy_handle(&h); return 0; } - result = connect(sockfd, (struct sockaddr*) &servaddr, sizeof(servaddr)); - if (result == -1) { - snprintf(err_buf, sizeof(err_buf), - "Failed to connect to \"%s:%d\"", mgmhost, port); - setError(CR_RETRY, err_buf); - NDB_CLOSE_SOCKET(sockfd); - return 0; + ndb_mgm_configuration * conf = ndb_mgm_get_configuration(h, versionId); + if(conf == 0){ + setError(CR_ERROR, ndb_mgm_get_latest_error_desc(h)); } - - if(println_socket(sockfd, 1000, "GET CONFIG %d %d" , - versionId, nodeId) != 0){ - NDB_CLOSE_SOCKET(sockfd); - setError(CR_ERROR, "IO error, write"); - return 0; - } - - char buf[255]; - { - const int tmp = readln_socket(sockfd, socketTimeout, buf, 255); - if(tmp == -1){ - NDB_CLOSE_SOCKET(sockfd); - setError(CR_ERROR, "IO error, read"); - return 0; - } - if(tmp == 0){ - snprintf(err_buf, 256, - "IO error, failed request: " - "GET CONFIG %d %d", versionId, nodeId); - NDB_CLOSE_SOCKET(sockfd); - setError(CR_ERROR, err_buf); - return 0; - } - } + ndb_mgm_disconnect(h); + ndb_mgm_destroy_handle(&h); - int status, version, node, bytes, bytesUU; - if(sscanf(buf, "GET CONFIG %d %d %d %d %d", - &status, &version, &node, &bytes, &bytesUU) != 5){ - NDB_CLOSE_SOCKET(sockfd); - snprintf(err_buf, sizeof(err_buf), - "Invalid response: %s", buf); - setError(CR_ERROR, err_buf); - return 0; - } - - if(status != 0){ - NDB_CLOSE_SOCKET(sockfd); - if (status == 1){ - snprintf(err_buf, sizeof(err_buf), - "Management Server: Requested version id is invalid"); - } else if (status == 2){ - snprintf(err_buf, sizeof(err_buf), - "Management Server: Node with id %d has not been specified", - nodeId); - } else if (status == 3){ - snprintf(err_buf, sizeof(err_buf), "Management Server: Internal error"); - } else { - snprintf(err_buf, sizeof(err_buf), - "Management Server returned unknown error: %d", status); - } - setError(CR_ERROR, err_buf); - return 0; - } - + return conf; +#if 0 bool compatible; if (global_ndb_check) compatible = ndbCompatible_ndb_mgmt(versionId, version); @@ -278,90 +195,11 @@ ConfigRetriever::getConfig(const char * mgmhost, setError(CR_ERROR, err_buf); return 0; } - - if(node != (int)nodeId){ - NDB_CLOSE_SOCKET(sockfd); - snprintf(err_buf, sizeof(err_buf), "Management Server: Invalid node id. " - "Node id from server: %d Own node id: %d", node, nodeId); - setError(CR_ERROR, err_buf); - return 0; - } - - if(readln_socket(sockfd, socketTimeout, buf, 255) == -1){ - NDB_CLOSE_SOCKET(sockfd); - setError(CR_ERROR, "IO error, read"); - return 0; - } - - if(strncmp("begin", buf, strlen("begin")) != 0){ - NDB_CLOSE_SOCKET(sockfd); - snprintf(err_buf, sizeof(err_buf), - "Invalid response: %s", buf); - setError(CR_ERROR, err_buf); - return 0; - } - - char* bufUU = new char[bytesUU]; - int read = 0; - int start = 0; - do { - if((read = read_socket(sockfd, socketTimeout, &bufUU[start], bytesUU-start)) == -1){ - delete[] bufUU; - NDB_CLOSE_SOCKET(sockfd); - setError(CR_ERROR, "IO error, read(bufUU)"); - return 0; - } - start += read; - } while(start < bytesUU); - - Uint32 * buf2 = new Uint32[bytes/4+1]; // Properties byte size - char * dst = (char *)buf2; - int sz = 0; - start = 0; - - for (int i = 0; i < bytesUU; i++) { - if (bufUU[i] == '\n') { - bufUU[i] = 0; - if (bufUU[i-1] == '\r') { - bufUU[i-1] = 0; - } - sz = uudecode_mem(dst, bytes, &bufUU[start]); - dst += sz; - start = i + 1; // Next row - } - } - - delete[] bufUU; - - if(sz < 0){ - delete []buf2; - NDB_CLOSE_SOCKET(sockfd); - setError(CR_ERROR, "IO error, sz < 0"); - return 0; - } - - Properties * p = new Properties(); - if(!p->unpack(buf2, bytes+4)){ - snprintf(buf, sizeof(buf), "Error while unpacking %d,%d", - p->getPropertiesErrno(), - p->getOSErrno()); - setError(CR_ERROR, buf); - delete []buf2; - delete p; - return 0; - } - delete []buf2; - - NDB_CLOSE_SOCKET(sockfd); - - return p; - +#endif } -Properties * -ConfigRetriever::getConfig(const char * filename, - Uint32 nodeId, - int versionId){ +ndb_mgm_configuration * +ConfigRetriever::getConfig(const char * filename, int versionId){ struct stat sbuf; const int res = stat(filename, &sbuf); @@ -389,74 +227,19 @@ ConfigRetriever::getConfig(const char * filename, return 0; } - Properties * p = new Properties(); - if(!p->unpack(buf2, bytes+4)){ + ConfigValuesFactory cvf; + if(!cvf.unpack(buf2, bytes)){ char buf[255]; - snprintf(buf, sizeof(buf), "Error while unpacking %d,%d", - p->getPropertiesErrno(), - p->getOSErrno()); + snprintf(buf, sizeof(buf), "Error while unpacking"); setError(CR_ERROR, buf); delete []buf2; - delete p; return 0; } delete [] buf2; - return p; + return (ndb_mgm_configuration*)cvf.m_cfg; } -bool -ConfigRetriever::verifyProperties(const char* nodeType, Properties * p, - Uint32 nodeId, int versionId){ - - Uint32 t = 0; - const Properties *tmp; - const char *type; - - if (p == 0) return false; - - bool compatible = false; - if (p->get("Version", &t)) - if (global_ndb_check) - compatible = ndbCompatible_ndb_mgmt(versionId, t); - else - compatible = ndbCompatible_api_mgmt(versionId, t); - - if(!compatible){ // if(!p->get("Version", &t) || versionId != (int)t){ - setError(CR_ERROR, "Invalid configuration version"); - delete p; - return false; - } - - if(!p->get("LocalNodeId", &t) || nodeId != t){ - setError(CR_ERROR, "Invalid node identity in configuration"); - delete p; - return false; - } - - if(!p->get("Node", nodeId, &tmp)){ - setError(CR_ERROR, "Internal error while processing configuration"); - ndbout_c("nodeId = %d", nodeId); - p->print(); - delete p; - return false; - } - - if(!tmp->get("Type", &type) || strcmp(type, nodeType)) { - if (!(!strcmp(type, "REP") && !strcmp(nodeType, "API"))) { - char buf[1024]; - snprintf(buf, sizeof(buf), - "Configuration error: Node with id %d is not of type %s.\n" - "Check local config file: %s", nodeId, nodeType, - _localConfigFileName); - setError(CR_ERROR, buf); - return false; - } - } - - return true; -} - void ConfigRetriever::setError(ErrorType et, const char * s){ if(errorString != 0){ @@ -509,3 +292,82 @@ ConfigRetriever::setDefaultConnectString(const char * defaultConnectString) { m_defaultConnectString = 0; } } + +bool +ConfigRetriever::verifyConfig(const struct ndb_mgm_configuration * conf, + int type){ + char buf[255]; + ndb_mgm_configuration_iterator * it; + it = ndb_mgm_create_configuration_iterator((struct ndb_mgm_configuration *)conf, CFG_SECTION_NODE); + + if(it == 0){ + snprintf(buf, 255, "Unable to create config iterator"); + setError(CR_ERROR, buf); + return false; + + } + NdbAutoPtr<ndb_mgm_configuration_iterator> ptr(it); + + if(ndb_mgm_find(it, CFG_NODE_ID, getOwnNodeId()) != 0){ + snprintf(buf, 255, "Unable to find node with id: %d", getOwnNodeId()); + setError(CR_ERROR, buf); + return false; + } + + const char * hostname; + if(ndb_mgm_get_string_parameter(it, CFG_NODE_HOST, &hostname)){ + snprintf(buf, 255, "Unable to get hostname(%d) from config",CFG_NODE_HOST); + setError(CR_ERROR, buf); + return false; + } + + char localhost[MAXHOSTNAMELEN]; + if(NdbHost_GetHostName(localhost) != 0){ + snprintf(buf, 255, "Unable to own hostname"); + setError(CR_ERROR, buf); + return false; + } + + do { + if(strcasecmp(hostname, localhost) == 0) + break; + + if(strcasecmp(hostname, "localhost") == 0) + break; + + struct in_addr local, config; + bool b1 = false, b2 = false, b3 = false; + b1 = Ndb_getInAddr(&local, localhost) == 0; + b2 = Ndb_getInAddr(&config, hostname) == 0; + b3 = memcmp(&local, &config, sizeof(local)) == 0; + + if(b1 && b2 && b3) + break; + + b1 = Ndb_getInAddr(&local, "localhost") == 0; + b3 = memcmp(&local, &config, sizeof(local)) == 0; + if(b1 && b2 && b3) + break; + + snprintf(buf, 255, "Local hostname(%s) and config hostname(%s) dont match", + localhost, hostname); + setError(CR_ERROR, buf); + return false; + } while(false); + + unsigned int _type; + if(ndb_mgm_get_int_parameter(it, CFG_TYPE_OF_SECTION, &_type)){ + snprintf(buf, 255, "Unable to get type of node(%d) from config", + CFG_TYPE_OF_SECTION); + setError(CR_ERROR, buf); + return false; + } + + if(_type != type){ + snprintf(buf, 255, "Supplied node type(%d) and config node type(%d) " + " don't match", type, _type); + setError(CR_ERROR, buf); + return false; + } + return true; +} diff --git a/ndb/src/common/mgmcommon/IPCConfig.cpp b/ndb/src/common/mgmcommon/IPCConfig.cpp index f75cf806cc0..ba5fe7ace80 100644 --- a/ndb/src/common/mgmcommon/IPCConfig.cpp +++ b/ndb/src/common/mgmcommon/IPCConfig.cpp @@ -17,10 +17,14 @@ #include "IPCConfig.hpp" #include <NdbOut.hpp> #include <NdbHost.h> + #include <TransporterDefinitions.hpp> #include <TransporterRegistry.hpp> #include <Properties.hpp> +#include <mgmapi_configuration.hpp> +#include <mgmapi_config_parameters.h> + #if defined DEBUG_TRANSPORTER #define DEBUG(t) ndbout << __FILE__ << ":" << __LINE__ << ":" << t << endl; #else @@ -334,3 +338,158 @@ IPCConfig::getNodeType(NodeId id) const { return out; } + +Uint32 +IPCConfig::configureTransporters(Uint32 nodeId, + const class ndb_mgm_configuration & config, + class TransporterRegistry & tr){ + + Uint32 noOfTransportersCreated = 0; + ndb_mgm_configuration_iterator iter(config, CFG_SECTION_CONNECTION); + + for(iter.first(); iter.valid(); iter.next()){ + + Uint32 nodeId1, nodeId2, remoteNodeId; + if(iter.get(CFG_CONNECTION_NODE_1, &nodeId1)) continue; + if(iter.get(CFG_CONNECTION_NODE_2, &nodeId2)) continue; + + if(nodeId1 != nodeId && nodeId2 != nodeId) continue; + remoteNodeId = (nodeId == nodeId1 ? nodeId2 : nodeId1); + + Uint32 sendSignalId = 1; + Uint32 checksum = 1; + if(iter.get(CFG_CONNECTION_SEND_SIGNAL_ID, &sendSignalId)) continue; + if(iter.get(CFG_CONNECTION_CHECKSUM, &checksum)) continue; + + Uint32 type = ~0; + if(iter.get(CFG_TYPE_OF_SECTION, &type)) continue; + + switch(type){ + case CONNECTION_TYPE_SHM:{ + SHM_TransporterConfiguration conf; + conf.localNodeId = nodeId; + conf.remoteNodeId = remoteNodeId; + conf.byteOrder = 0; + conf.compression = 0; + conf.checksum = checksum; + conf.signalId = sendSignalId; + + if(iter.get(CFG_SHM_KEY, &conf.shmKey)) break; + if(iter.get(CFG_SHM_BUFFER_MEM, &conf.shmSize)) break; + + if(!tr.createTransporter(&conf)){ + ndbout << "Failed to create SHM Transporter from: " + << conf.localNodeId << " to: " << conf.remoteNodeId << endl; + } else { + noOfTransportersCreated++; + } + break; + } + case CONNECTION_TYPE_SCI:{ + SCI_TransporterConfiguration conf; + conf.localNodeId = nodeId; + conf.remoteNodeId = remoteNodeId; + conf.byteOrder = 0; + conf.compression = 0; + conf.checksum = checksum; + conf.signalId = sendSignalId; + + if(iter.get(CFG_SCI_SEND_LIMIT, &conf.sendLimit)) break; + if(iter.get(CFG_SCI_BUFFER_MEM, &conf.bufferSize)) break; + + if(nodeId == nodeId1){ + if(iter.get(CFG_SCI_NODE1_ADAPTERS, &conf.nLocalAdapters)) break; + if(iter.get(CFG_SCI_NODE2_ADAPTERS, &conf.nRemoteAdapters)) break; + if(iter.get(CFG_SCI_NODE2_ADAPTER0, &conf.remoteSciNodeId0)) break; + if(conf.nRemoteAdapters > 1){ + if(iter.get(CFG_SCI_NODE2_ADAPTER1, &conf.remoteSciNodeId1)) break; + } + } else { + if(iter.get(CFG_SCI_NODE2_ADAPTERS, &conf.nLocalAdapters)) break; + if(iter.get(CFG_SCI_NODE1_ADAPTERS, &conf.nRemoteAdapters)) break; + if(iter.get(CFG_SCI_NODE1_ADAPTER0, &conf.remoteSciNodeId0)) break; + if(conf.nRemoteAdapters > 1){ + if(iter.get(CFG_SCI_NODE1_ADAPTER1, &conf.remoteSciNodeId1)) break; + } + } + + if(!tr.createTransporter(&conf)){ + ndbout << "Failed to create SCI Transporter from: " + << conf.localNodeId << " to: " << conf.remoteNodeId << endl; + } else { + noOfTransportersCreated++; + continue; + } + } + case CONNECTION_TYPE_TCP:{ + TCP_TransporterConfiguration conf; + + const char * host1, * host2; + if(iter.get(CFG_TCP_HOSTNAME_1, &host1)) break; + if(iter.get(CFG_TCP_HOSTNAME_2, &host2)) break; + + if(iter.get(CFG_TCP_SERVER_PORT, &conf.port)) break; + if(iter.get(CFG_TCP_SEND_BUFFER_SIZE, &conf.sendBufferSize)) break; + if(iter.get(CFG_TCP_RECEIVE_BUFFER_SIZE, &conf.maxReceiveSize)) break; + + const char * proxy; + if (!iter.get(CFG_TCP_PROXY, &proxy)) { + if (strlen(proxy) > 0 && nodeId2 == nodeId) { + // TODO handle host:port + conf.port = atoi(proxy); + } + } + + conf.localNodeId = nodeId; + conf.remoteNodeId = remoteNodeId; + conf.localHostName = (nodeId == nodeId1 ? host1 : host2); + conf.remoteHostName = (nodeId == nodeId1 ? host2 : host1); + conf.byteOrder = 0; + conf.compression = 0; + conf.checksum = checksum; + conf.signalId = sendSignalId; + + if(!tr.createTransporter(&conf)){ + ndbout << "Failed to create TCP Transporter from: " + << nodeId << " to: " << remoteNodeId << endl; + } else { + noOfTransportersCreated++; + } + case CONNECTION_TYPE_OSE:{ + OSE_TransporterConfiguration conf; + + const char * host1, * host2; + if(iter.get(CFG_OSE_HOSTNAME_1, &host1)) break; + if(iter.get(CFG_OSE_HOSTNAME_2, &host2)) break; + + if(iter.get(CFG_OSE_PRIO_A_SIZE, &conf.prioASignalSize)) break; + if(iter.get(CFG_OSE_PRIO_B_SIZE, &conf.prioBSignalSize)) break; + if(iter.get(CFG_OSE_RECEIVE_ARRAY_SIZE, &conf.receiveBufferSize)) break; + + conf.localNodeId = nodeId; + conf.remoteNodeId = remoteNodeId; + conf.localHostName = (nodeId == nodeId1 ? host1 : host2); + conf.remoteHostName = (nodeId == nodeId1 ? host2 : host1); + conf.byteOrder = 0; + conf.compression = 0; + conf.checksum = checksum; + conf.signalId = sendSignalId; + + if(!tr.createTransporter(&conf)){ + ndbout << "Failed to create OSE Transporter from: " + << nodeId << " to: " << remoteNodeId << endl; + } else { + noOfTransportersCreated++; + } + } + default: + ndbout << "Unknown transporter type from: " << nodeId << + " to: " << remoteNodeId << endl; + break; + } + } + } + + return noOfTransportersCreated; +} + diff --git a/ndb/src/common/mgmcommon/InitConfigFileParser.cpp b/ndb/src/common/mgmcommon/InitConfigFileParser.cpp index 62c4bd28857..d01b8189545 100644 --- a/ndb/src/common/mgmcommon/InitConfigFileParser.cpp +++ b/ndb/src/common/mgmcommon/InitConfigFileParser.cpp @@ -30,51 +30,66 @@ static void require(bool v) { if(!v) abort();} //**************************************************************************** // Ctor / Dtor //**************************************************************************** -InitConfigFileParser::InitConfigFileParser(const char* initialConfigFileName){ - - m_initConfigStream = fopen(initialConfigFileName, "r"); +InitConfigFileParser::InitConfigFileParser(){ m_info = new ConfigInfo(); - m_config = new Config(); - m_defaults = new Properties(); - m_defaults->setCaseInsensitiveNames(true); } InitConfigFileParser::~InitConfigFileParser() { - if (m_initConfigStream != NULL) fclose(m_initConfigStream); - delete m_info; - delete m_config; - delete m_defaults; } //**************************************************************************** // Read Config File //**************************************************************************** -bool InitConfigFileParser::readConfigFile() { +InitConfigFileParser::Context::Context(const ConfigInfo * info) + : m_configValues(1000, 20) { + + m_config = new Properties(); + m_defaults = new Properties(); +} + +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){ + ndbout << "Error opening file: " << filename << endl; + return 0; + } + + Config * ret = parseConfig(file); + fclose(file); + return ret; +} + +Config * +InitConfigFileParser::parseConfig(FILE * file) { char line[MAX_LINE_LENGTH]; - Context ctx; + Context ctx(m_info); ctx.m_lineno = 0; ctx.m_currentSection = 0; - ctx.m_info = m_info; - ctx.m_config = m_config; - ctx.m_defaults = m_defaults; - /************* * Open file * *************/ - if (m_initConfigStream == NULL) { - ctx.reportError("Could not open file."); - return false; + if (file == NULL) { + return 0; } /*********************** * While lines to read * ***********************/ - while (fgets(line, MAX_LINE_LENGTH, m_initConfigStream)) { + while (fgets(line, MAX_LINE_LENGTH, file)) { ctx.m_lineno++; trim(line); @@ -94,7 +109,7 @@ bool InitConfigFileParser::readConfigFile() { free(section); ctx.reportError("Could not store previous default section " "of configuration file."); - return false; + return 0; } snprintf(ctx.fname, sizeof(ctx.fname), section); free(section); @@ -115,7 +130,7 @@ bool InitConfigFileParser::readConfigFile() { free(section); ctx.reportError("Could not store previous section " "of configuration file."); - return false; + return 0; } snprintf(ctx.fname, sizeof(ctx.fname), section); @@ -123,7 +138,7 @@ bool InitConfigFileParser::readConfigFile() { ctx.type = InitConfigFileParser::Section; ctx.m_sectionLineno = ctx.m_lineno; ctx.m_currentSection = new Properties(); - ctx.m_userDefaults = getSection(ctx.fname, m_defaults); + ctx.m_userDefaults = getSection(ctx.fname, ctx.m_defaults); ctx.m_currentInfo = m_info->getInfo(ctx.fname); ctx.m_systemDefaults = m_info->getDefaults(ctx.fname); continue; @@ -134,13 +149,18 @@ bool InitConfigFileParser::readConfigFile() { ****************************/ if (!parseNameValuePair(ctx, line)) { ctx.reportError("Could not parse name-value pair in config file."); - return false; + 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 false; + return 0; } Uint32 nConnections = 0; @@ -153,21 +173,20 @@ bool InitConfigFileParser::readConfigFile() { ctx.m_userProperties.get("NoOfNodes", &nNodes); ctx.m_userProperties.get("ExtNoOfConnections", &nExtConnections); ctx.m_userProperties.get("ExtSystem", &system); - m_config->put("NoOfConnections", nConnections); - m_config->put("NoOfComputers", nComputers); - m_config->put("NoOfNodes", nNodes); + ctx.m_config->put("NoOfConnections", nConnections); + ctx.m_config->put("NoOfComputers", nComputers); + ctx.m_config->put("NoOfNodes", nNodes); char tmpLine[MAX_LINE_LENGTH]; snprintf(tmpLine, MAX_LINE_LENGTH, "EXTERNAL SYSTEM_"); strncat(tmpLine, system, MAX_LINE_LENGTH); strncat(tmpLine, ":NoOfConnections", MAX_LINE_LENGTH); - m_config->put(tmpLine, nExtConnections); + ctx.m_config->put(tmpLine, nExtConnections); - if (ferror(m_initConfigStream)) { - ctx.reportError("Failure in reading"); - return false; - } - return true; + 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; } //**************************************************************************** @@ -216,7 +235,13 @@ bool InitConfigFileParser::parseNameValuePair(Context& ctx, const char* line) { ctx.reportWarning("[%s] %s not yet implemented", ctx.fname, fname); } if (status == ConfigInfo::DEPRICATED) { - ctx.reportWarning("[%s] %s is depricated", ctx.fname, fname); + const char * desc = m_info->getDescription(ctx.m_currentInfo, fname); + if(desc){ + ctx.reportWarning("[%s] %s is depricated, use %s instead", + ctx.fname, fname, desc); + } else { + ctx.reportWarning("[%s] %s is depricated", ctx.fname, fname); + } } // ****************************************** @@ -249,7 +274,7 @@ InitConfigFileParser::storeNameValuePair(Context& ctx, const char* fname, const char* value) { - const char * pname = m_info->getPName(ctx.m_currentInfo, fname); + const char * pname = fname; if (ctx.m_currentSection->contains(pname)) { ctx.reportError("[%s] Parameter %s specified twice", ctx.fname, fname); @@ -260,7 +285,8 @@ InitConfigFileParser::storeNameValuePair(Context& ctx, // Store name-value pair // *********************** - switch(m_info->getType(ctx.m_currentInfo, fname)){ + const ConfigInfo::Type type = m_info->getType(ctx.m_currentInfo, fname); + switch(type){ case ConfigInfo::BOOL: { bool value_bool; if (!convertStringToBool(value, value_bool)) { @@ -270,9 +296,10 @@ InitConfigFileParser::storeNameValuePair(Context& ctx, MGM_REQUIRE(ctx.m_currentSection->put(pname, value_bool)); break; } - case ConfigInfo::INT:{ - Uint32 value_int; - if (!convertStringToUint32(value, value_int)) { + case ConfigInfo::INT: + case ConfigInfo::INT64:{ + Uint64 value_int; + if (!convertStringToUint64(value, value_int)) { ctx.reportError("Illegal integer value for parameter %s", fname); return false; } @@ -283,7 +310,11 @@ InitConfigFileParser::storeNameValuePair(Context& ctx, m_info->getMax(ctx.m_currentInfo, fname)); return false; } - MGM_REQUIRE(ctx.m_currentSection->put(pname, value_int)); + if(type == ConfigInfo::INT){ + MGM_REQUIRE(ctx.m_currentSection->put(pname, (Uint32)value_int)); + } else { + MGM_REQUIRE(ctx.m_currentSection->put64(pname, value_int)); + } break; } case ConfigInfo::STRING: @@ -313,8 +344,8 @@ bool InitConfigFileParser::isEmptyLine(const char* line) const { //**************************************************************************** // Convert String to Int //**************************************************************************** -bool InitConfigFileParser::convertStringToUint32(const char* s, - Uint32& val, +bool InitConfigFileParser::convertStringToUint64(const char* s, + Uint64& val, Uint32 log10base) { if (s == NULL) return false; @@ -323,7 +354,7 @@ bool InitConfigFileParser::convertStringToUint32(const char* s, errno = 0; char* p; - long v = strtol(s, &p, 10); + long long v = strtoll(s, &p, 10); if (errno != 0) return false; @@ -359,14 +390,16 @@ bool InitConfigFileParser::convertStringToBool(const char* s, bool& val) { 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, "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, "False") || !strcmp(s, "FALSE") || !strcmp(s, "false") || + !strcmp(s, "0")) { val = false; return true; } @@ -375,21 +408,6 @@ bool InitConfigFileParser::convertStringToBool(const char* s, bool& val) { } //**************************************************************************** -// Get Config -//**************************************************************************** -const Config* InitConfigFileParser::getConfig() { - Uint32 nConnections = 0; - Uint32 nComputers = 0; - Uint32 nNodes = 0; - m_config->get("NoOfConnections", &nConnections); - m_config->get("NoOfComputers", &nComputers); - m_config->get("NoOfNodes", &nNodes); - - return m_config; -} - - -//**************************************************************************** // Parse Section Header //**************************************************************************** static void @@ -495,19 +513,22 @@ InitConfigFileParser::storeSection(Context& ctx){ snprintf(buf, sizeof(buf), "%s DEFAULT", ctx.fname); snprintf(ctx.fname, sizeof(ctx.fname), buf); - for(int i = 0; i<m_info->m_NoOfRules; i++){ - const ConfigInfo::SectionRule & rule = m_info->m_SectionRules[i]; - if(strcmp(rule.m_section, ctx.fname) == 0) - if(!(* rule.m_sectionRule)(ctx, rule.m_ruleData)){ - return false; + 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) - require(m_defaults->put(ctx.pname, ctx.m_currentSection)); + require(ctx.m_defaults->put(ctx.pname, ctx.m_currentSection)); if(ctx.type == InitConfigFileParser::Section) - require(m_config->put(ctx.pname, ctx.m_currentSection)); + require(ctx.m_config->put(ctx.pname, ctx.m_currentSection)); delete ctx.m_currentSection; ctx.m_currentSection = NULL; diff --git a/ndb/src/common/mgmcommon/InitConfigFileParser.hpp b/ndb/src/common/mgmcommon/InitConfigFileParser.hpp index f4f27abb055..6b7482c12ae 100644 --- a/ndb/src/common/mgmcommon/InitConfigFileParser.hpp +++ b/ndb/src/common/mgmcommon/InitConfigFileParser.hpp @@ -20,6 +20,7 @@ #include <ndb_global.h> #include <Properties.hpp> +#include <ConfigValues.hpp> class Config; class ConfigInfo; @@ -28,18 +29,40 @@ class ConfigInfo; * @class InitConfigFileParser * @brief Reads initial config file and returns Config object * - * This class contains one public method InitConfigFileParser::getConfig, + * 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 { public: + /** + * Constructor + */ + InitConfigFileParser(); + ~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); + + /** + * Parser context struct + */ enum ContextSectionType { Undefined, Section, DefaultSection }; /** * Context = Which section in init config file we are currently parsing */ struct Context { + Context(const ConfigInfo *); + ~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 @@ -47,8 +70,8 @@ public: Uint32 m_sectionLineno; ///< Where did current section start const ConfigInfo * m_info; // The config info - const Properties * m_config; // The config object - const Properties * m_defaults; // The user defaults + 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 @@ -56,36 +79,13 @@ public: const Properties * m_currentInfo; // The "info" for this section Properties m_userProperties; // User properties (temporary values) + ConfigValuesFactory m_configValues; // public: void reportError(const char * msg, ...); void reportWarning(const char * msg, ...); }; - - /** - * Constructor - * @param initialConfigFileName: Name of the initial configuration file - */ - InitConfigFileParser(const char* initialConfigFileName); - ~InitConfigFileParser(); - - /** - * Reads the initial configuration file, checks syntax and semantic - * and stores internally the values of all parameters. - * - * @returns true if succeeded, o/w false (e.g. incorrect config file) - */ - bool readConfigFile(); - - /** - * Get config. Must execute InitConfigFileParser::readConfigFile first. - * - * @returns Config if succeeded, o/w NULL - */ - const Config* getConfig(); - - private: /** * Check if line only contains space/comments @@ -111,33 +111,16 @@ private: bool parseNameValuePair(Context&, const char* line); bool storeNameValuePair(Context&, const char* fname, const char* value); - bool convertStringToUint32(const char* s, Uint32& val, Uint32 log10base = 0); + bool convertStringToUint64(const char* s, Uint64& val, Uint32 log10base = 0); bool convertStringToBool(const char* s, bool& val); + bool storeSection(Context&); const Properties* getSection(const char * name, const Properties* src); - /*************************************************************************** - * VARIABLES - ***************************************************************************/ - FILE* m_initConfigStream; - /** * Information about parameters (min, max values etc) */ - const ConfigInfo* m_info; - - /** - * Configuration from initial configuration file - * (returned by InitConfigFileParser::readConfigFile) - */ - Config* m_config; - - /** - * Default values specified in default sections - */ - Properties* m_defaults; - - bool storeSection(Context&); + ConfigInfo* m_info; }; #endif // InitConfigFileParser_H diff --git a/ndb/src/common/mgmcommon/Makefile_old b/ndb/src/common/mgmcommon/Makefile_old index 2db7be01d60..c7bfda7e3bf 100644 --- a/ndb/src/common/mgmcommon/Makefile_old +++ b/ndb/src/common/mgmcommon/Makefile_old @@ -5,6 +5,7 @@ TYPE := ndbapi mgmapiclient PIC_ARCHIVE := Y ARCHIVE_TARGET := mgmsrvcommon +# Removed temporary DIRS := printConfig SOURCES = \ @@ -17,6 +18,8 @@ SOURCES = \ SOURCES.c = NdbConfig.c +CFLAGS_IPCConfig.cpp := -I$(call fixpath,$(NDB_TOP)/src/mgmapi) + include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/common/mgmcommon/printConfig/Makefile b/ndb/src/common/mgmcommon/printConfig/Makefile index 9194316da87..77e8943e2c6 100644 --- a/ndb/src/common/mgmcommon/printConfig/Makefile +++ b/ndb/src/common/mgmcommon/printConfig/Makefile @@ -7,8 +7,10 @@ BIN_TARGET_ARCHIVES := general portlib CCFLAGS_LOC += -I.. -SOURCES := printConfig.cpp +SOURCES := printConfig.cpp ../ConfigRetriever.cpp -SOURCES.c := ../ConfigRetriever.c ../NdbConfig.c ../LocalConfig.c +SOURCES.c := ../NdbConfig.c ../LocalConfig.c + +CFLAGS_printConfig.cpp := -I$(call fixpath,$(NDB_TOP)/src/mgmapi) include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/common/mgmcommon/printConfig/printConfig.cpp b/ndb/src/common/mgmcommon/printConfig/printConfig.cpp index daa287cc44d..7cedbb451e2 100644 --- a/ndb/src/common/mgmcommon/printConfig/printConfig.cpp +++ b/ndb/src/common/mgmcommon/printConfig/printConfig.cpp @@ -18,6 +18,7 @@ #include <ndb_global.h> #include <NdbMain.h> +#include <mgmapi.h> #include <ConfigRetriever.hpp> #include <Properties.hpp> #include <NdbOut.hpp> @@ -50,9 +51,9 @@ NDB_COMMAND(printConfig, return 0; } - Properties * p = 0; ConfigRetriever c; - + struct ndb_mgm_configuration * p = 0; + if(strcmp("host", argv[1]) == 0){ int verId = 0; if(argc > 5) @@ -64,7 +65,6 @@ NDB_COMMAND(printConfig, p = c.getConfig(argv[2], atoi(argv[3]), - atoi(argv[4]), verId); } else if (strcmp("file", argv[1]) == 0){ int verId = 0; @@ -79,12 +79,11 @@ NDB_COMMAND(printConfig, } if(p != 0){ - p->print(stdout); + // + free(p); } else { ndbout << "Configuration not found: " << c.getErrorString() << endl; } - delete p; - return 0; } diff --git a/ndb/src/common/util/Base64.cpp b/ndb/src/common/util/Base64.cpp index 482d0b10ad2..f7a490d427d 100644 --- a/ndb/src/common/util/Base64.cpp +++ b/ndb/src/common/util/Base64.cpp @@ -22,89 +22,186 @@ static char base64_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789+/"; int -base64_encode(UtilBuffer &src, BaseString &dst) { - char *s = (char *)src.get_data(); - int i = 0; +base64_encode(const UtilBuffer &src, BaseString &dst) { + const unsigned char *s = (const unsigned char *)src.get_data(); + size_t i = 0; + size_t len = 0; + size_t src_len = src.length(); + while(i < src_len) { + if(len == 76){ + len = 0; + dst.append('\n'); + } - while(i < src.length()) { - int c; + unsigned c; c = s[i++]; c <<= 8; - if(i < src.length()) + if(i < src_len) c += s[i]; c <<= 8; i++; - if(i < src.length()) + if(i < src_len) c += s[i]; i++; - + dst.append(base64_table[(c >> 18) & 0x3f]); dst.append(base64_table[(c >> 12) & 0x3f]); - if(i > (src.length() + 1)) + if(i > (src_len + 1)) dst.append('='); else dst.append(base64_table[(c >> 6) & 0x3f]); - if(i > src.length()) + if(i > src_len) dst.append('='); else dst.append(base64_table[(c >> 0) & 0x3f]); + + len += 4; } return 0; } -static inline int -pos(char c) { +static inline unsigned +pos(unsigned char c) { return strchr(base64_table, c) - base64_table; } int -base64_decode(BaseString &src, UtilBuffer &dst) { - size_t size; - size = (src.length() * 3) / 4; +base64_decode(const BaseString &src, UtilBuffer &dst) { + return base64_decode(src.c_str(), src.length(), dst); +} + +#define SKIP_SPACE(src, i, size){ \ + while(i < size && isspace(* src)){ \ + i++; \ + src++; \ + } \ + if(i == size){ \ + i = size + 1; \ + break; \ + } \ +} + +int +base64_decode(const char * src, size_t size, UtilBuffer &dst) { size_t i = 0; - const char *s = src.c_str(); - while(i < size) { - int c = 0; + while(i < size){ + unsigned c = 0; int mark = 0; - c += pos(*s++); + + SKIP_SPACE(src, i, size); + + c += pos(*src++); c <<= 6; i++; - c += pos(*s++); + SKIP_SPACE(src, i, size); + + c += pos(*src++); c <<= 6; i++; - if(*s != '=') - c += pos(*s++); + SKIP_SPACE(src, i, size); + + if(* src != '=') + c += pos(*src++); else { - size--; - mark++; + i = size; + mark = 2; + c <<= 6; + goto end; } c <<= 6; i++; - if(*s != '=') - c += pos(*s++); + SKIP_SPACE(src, i, size); + + if(*src != '=') + c += pos(*src++); else { - size--; - mark++; + i = size; + mark = 1; + goto end; } - /* c <<= 6; */ i++; + end: char b[3]; - - b[0] = (c >> 16) & 0xff; b[1] = (c >> 8) & 0xff; b[2] = (c >> 0) & 0xff; - + dst.append((void *)b, 3-mark); } + + if(i != size){ + abort(); + return -1; + } return 0; } + +#ifdef __TEST__B64 +/** + * USER_FLAGS="-D__TEST__B64" make Base64.o && g++ Base64.o BaseString.o + */ +inline +void +require(bool b){ + if(!b) + abort(); +} + +int +main(void){ + for(int i = 0; i < 500; i++){ + const size_t len = rand() % 10000 + 1; + UtilBuffer src; + for(size_t j = 0; j<len; j++){ + char c = rand(); + src.append(&c, 1); + } + require(src.length() == len); + + BaseString str; + require(base64_encode(src, str) == 0); + + if(str.length() == 3850){ + printf(">%s<\n", str.c_str()); + } + + UtilBuffer dst; + require(base64_decode(str, dst) == 0); + require(dst.length() == src.length()); + + const char * c_src = (char*)src.get_data(); + const char * c_dst = (char*)dst.get_data(); + if(memcmp(src.get_data(), dst.get_data(), src.length()) != 0){ + printf("-- src --\n"); + for(int i2 = 0; i2<len; i2++){ + unsigned char c = c_src[i2]; + printf("%.2x ", (unsigned)c); + if((i2 % 8) == 7) + printf("\n"); + } + printf("\n"); + + printf("-- dst --\n"); + for(int i2 = 0; i2<len; i2++){ + unsigned char c = c_dst[i2]; + printf("%.2x ", (unsigned)c); + if((i2 % 8) == 7) + printf("\n"); + } + printf("\n"); + abort(); + } + } + return 0; +} + +#endif diff --git a/ndb/src/common/util/ConfigValues.cpp b/ndb/src/common/util/ConfigValues.cpp new file mode 100644 index 00000000000..6c07f25931d --- /dev/null +++ b/ndb/src/common/util/ConfigValues.cpp @@ -0,0 +1,743 @@ +#include <ConfigValues.hpp> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <new> +#include <NdbOut.hpp> +#include <NdbTCP.h> + +static Uint32 hash(Uint32 key, Uint32 size); +static Uint32 nextHash(Uint32 key, Uint32 size, Uint32 pos, Uint32 count); +static bool findKey(const Uint32 * vals, Uint32 sz, Uint32 key, Uint32 * pos); + +/** + * Key + * + * t = Type - 4 bits 0-15 + * s = Section - 14 bits 0-16383 + * k = Key value - 14 bits 0-16383 + * + * 1111111111222222222233 + * 01234567890123456789012345678901 + * kkkkkkkkkkkkkkssssssssssssssoooo + */ +#define KP_TYPE_MASK (15) +#define KP_TYPE_SHIFT (28) +#define KP_SECTION_MASK (0x3FFF) +#define KP_SECTION_SHIFT (14) +#define KP_KEYVAL_MASK (0x3FFF) +#define KP_KEYVAL_SHIFT (0) +#define KP_MASK (0x0FFFFFFF) + +static const Uint32 CFV_KEY_PARENT = (KP_KEYVAL_MASK - 1); +static const Uint32 CFV_KEY_FREE = ~0; + +static const char Magic[] = { 'N', 'D', 'B', 'C', 'O', 'N', 'F', 'V' }; + +//#define DEBUG_CV +#ifdef DEBUG_CV +#define DEBUG +#else +#define DEBUG if(0) +#endif + +inline +ConfigValues::ValueType +getTypeOf(Uint32 k) { + return (ConfigValues::ValueType)((k >> KP_TYPE_SHIFT) & KP_TYPE_MASK); +} + +ConfigValues::ConfigValues(Uint32 sz, Uint32 dsz){ + m_size = sz; + m_dataSize = dsz; + m_stringCount = 0; + m_int64Count = 0; + for(Uint32 i = 0; i<m_size; i++){ + m_values[i << 1] = CFV_KEY_FREE; + } +} + +ConfigValues::~ConfigValues(){ + for(Uint32 i = 0; i<m_stringCount; i++){ + free(getString(i)); + } +} + +bool +ConfigValues::ConstIterator::get(Uint32 key, Entry * result) const { + Uint32 pos; + if(!findKey(m_cfg.m_values, m_cfg.m_size, key | m_currentSection, &pos)){ + return false; + } + + result->m_key = key; + return m_cfg.getByPos(pos, result); +} + +bool +ConfigValues::getByPos(Uint32 pos, Entry * result) const { + assert(pos < (2 * m_size)); + Uint32 keypart = m_values[pos]; + Uint32 val = m_values[pos+1]; + + switch(::getTypeOf(keypart)){ + case IntType: + case SectionType: + result->m_int = val; + break; + case StringType: + result->m_string = getString(val); + break; + case Int64Type: + result->m_int64 = get64(val); + break; + case InvalidType: + default: + return false; + } + + result->m_type = ::getTypeOf(keypart); + + return true; +} + +Uint64 & +ConfigValues::get64(Uint32 index) const { + assert(index < m_int64Count); + Uint64 * ptr = (Uint64*)(&m_values[m_size << 1]); + return ptr[index]; +} + +char * & +ConfigValues::getString(Uint32 index) const { + assert(index < m_stringCount); + char ** ptr = (char**)(((char *)&(m_values[m_size << 1])) + m_dataSize); + return ptr[-index]; +} + +bool +ConfigValues::ConstIterator::openSection(Uint32 key, Uint32 no){ + Uint32 curr = m_currentSection; + + Entry tmp; + if(get(key, &tmp) && tmp.m_type == SectionType){ + m_currentSection = tmp.m_int; + if(get(no, &tmp) && tmp.m_type == IntType){ + m_currentSection = tmp.m_int; + /** + * Validate + */ + if(get(CFV_KEY_PARENT, &tmp)){ + return true; + } + } + } + + m_currentSection = curr; + return false; +} + +bool +ConfigValues::ConstIterator::closeSection() { + + Entry tmp; + if(get(CFV_KEY_PARENT, &tmp) && tmp.m_type == IntType){ + m_currentSection = tmp.m_int; + return true; + } + + return false; +} + +bool +ConfigValues::Iterator::set(Uint32 key, Uint32 value){ + Uint32 pos; + if(!findKey(m_cfg.m_values, m_cfg.m_size, key | m_currentSection, &pos)){ + return false; + } + + if(::getTypeOf(m_cfg.m_values[pos]) != IntType){ + return false; + } + + m_cfg.m_values[pos+1] = value; + return true; +} + +bool +ConfigValues::Iterator::set(Uint32 key, Uint64 value){ + Uint32 pos; + if(!findKey(m_cfg.m_values, m_cfg.m_size, key | m_currentSection, &pos)){ + return false; + } + + if(::getTypeOf(m_cfg.m_values[pos]) != Int64Type){ + return false; + } + + m_cfg.get64(m_cfg.m_values[pos+1]) = value; + return true; +} + +bool +ConfigValues::Iterator::set(Uint32 key, const char * value){ + Uint32 pos; + if(!findKey(m_cfg.m_values, m_cfg.m_size, key | m_currentSection, &pos)){ + return false; + } + + if(::getTypeOf(m_cfg.m_values[pos]) != StringType){ + return false; + } + + char * & str = m_cfg.getString(m_cfg.m_values[pos+1]); + free(str); + str = strdup(value); + return true; +} + +static +bool +findKey(const Uint32 * values, Uint32 sz, Uint32 key, Uint32 * _pos){ + Uint32 pos = hash(key, sz); + Uint32 count = 0; + while((values[pos] & KP_MASK) != key && count < sz){ + pos = nextHash(key, sz, pos, ++count); + } + + if((values[pos] & KP_MASK)== key){ + *_pos = pos; + return true; + } + return false; +} + +static +Uint32 +hash(Uint32 key, Uint32 size){ + Uint32 tmp = (key >> 16) ^ (key & 0xFFFF); + return (((tmp << 16) | tmp) % size) << 1; +} + +static +Uint32 +nextHash(Uint32 key, Uint32 size, Uint32 pos, Uint32 count){ + Uint32 p = (pos >> 1); + if((key % size) != 0) + p += key; + else + p += 1; + return (p % size) << 1; +} + +static +Uint32 +directory(Uint32 sz){ + const Uint32 _input = sz; + if((sz & 1) == 0) + sz ++; + + bool prime = false; + while(!prime){ + prime = true; + for(Uint32 n = 3; n*n <= sz; n += 2){ + if((sz % n) == 0){ + prime = false; + sz += 2; + break; + } + } + } + DEBUG printf("directory %d -> %d\n", _input, sz); + return sz; +} + +ConfigValuesFactory::ConfigValuesFactory(Uint32 keys, Uint32 data){ + m_sectionCounter = (1 << KP_SECTION_SHIFT); + m_freeKeys = directory(keys); + m_freeData = data; + m_currentSection = 0; + m_cfg = create(m_freeKeys, data); +} + +ConfigValuesFactory::ConfigValuesFactory(ConfigValues * cfg){ + m_cfg = cfg; + m_freeKeys = 0; + m_freeData = m_cfg->m_dataSize; + m_sectionCounter = (1 << KP_SECTION_SHIFT); + m_currentSection = 0; + const Uint32 sz = 2 * m_cfg->m_size; + for(Uint32 i = 0; i<sz; i += 2){ + const Uint32 key = m_cfg->m_values[i]; + if(key == CFV_KEY_FREE){ + m_freeKeys++; + } else { + switch(::getTypeOf(key)){ + case ConfigValues::IntType: + case ConfigValues::SectionType: + break; + case ConfigValues::Int64Type: + m_freeData -= sizeof(Uint64); + break; + case ConfigValues::StringType: + m_freeData -= sizeof(char *); + break; + case ConfigValues::InvalidType: + abort(); + } + Uint32 sec = key & (KP_SECTION_MASK << KP_SECTION_SHIFT); + m_sectionCounter = (sec > m_sectionCounter ? sec : m_sectionCounter); + } + } +} + +ConfigValues * +ConfigValuesFactory::create(Uint32 keys, Uint32 data){ + Uint32 sz = sizeof(ConfigValues); + sz += (2 * keys * sizeof(Uint32)); + sz += data; + + void * tmp = malloc(sz); + return new (tmp) ConfigValues(keys, data); +} + +void +ConfigValuesFactory::expand(Uint32 fk, Uint32 fs){ + if(m_freeKeys >= fk && m_freeData >= fs){ + return ; + } + + m_freeKeys = (m_freeKeys >= fk ? m_cfg->m_size : fk + m_cfg->m_size); + m_freeData = (m_freeData >= fs ? m_cfg->m_dataSize : fs + m_cfg->m_dataSize); + m_freeKeys = directory(m_freeKeys); + + ConfigValues * m_tmp = m_cfg; + m_cfg = create(m_freeKeys, m_freeData); + put(* m_tmp); + m_tmp->~ConfigValues(); + free(m_tmp); +} + +void +ConfigValuesFactory::shrink(){ + if(m_freeKeys == 0 && m_freeData == 0){ + return ; + } + + m_freeKeys = m_cfg->m_size - m_freeKeys; + m_freeData = m_cfg->m_dataSize - m_freeData; + m_freeKeys = directory(m_freeKeys); + + ConfigValues * m_tmp = m_cfg; + m_cfg = create(m_freeKeys, m_freeData); + put(* m_tmp); + m_tmp->~ConfigValues(); + free(m_tmp); +} + +bool +ConfigValuesFactory::openSection(Uint32 key, Uint32 no){ + ConfigValues::Entry tmp; + const Uint32 parent = m_currentSection; + + ConfigValues::ConstIterator iter(* m_cfg); + iter.m_currentSection = m_currentSection; + if(!iter.get(key, &tmp)){ + + tmp.m_key = key; + tmp.m_type = ConfigValues::SectionType; + tmp.m_int = m_sectionCounter; + m_sectionCounter += (1 << KP_SECTION_SHIFT); + + if(!put(tmp)){ + return false; + } + } + + if(tmp.m_type != ConfigValues::SectionType){ + return false; + } + + m_currentSection = tmp.m_int; + + tmp.m_key = no; + tmp.m_type = ConfigValues::IntType; + tmp.m_int = m_sectionCounter; + if(!put(tmp)){ + m_currentSection = parent; + return false; + } + m_sectionCounter += (1 << KP_SECTION_SHIFT); + + m_currentSection = tmp.m_int; + tmp.m_type = ConfigValues::IntType; + tmp.m_key = CFV_KEY_PARENT; + tmp.m_int = parent; + if(!put(tmp)){ + m_currentSection = parent; + return false; + } + + return true; +} + +bool +ConfigValuesFactory::closeSection(){ + ConfigValues::ConstIterator iter(* m_cfg); + iter.m_currentSection = m_currentSection; + const bool b = iter.closeSection(); + m_currentSection = iter.m_currentSection; + return b; +} + +bool +ConfigValuesFactory::put(const ConfigValues::Entry & entry){ + + if(m_freeKeys == 0 || + (entry.m_type == ConfigValues::StringType && m_freeData < sizeof(char *)) + || (entry.m_type == ConfigValues::Int64Type && m_freeData < 8 )){ + + DEBUG ndbout_c("m_freeKeys = %d, m_freeData = %d -> expand", + m_freeKeys, m_freeData); + + expand(31, 20); + } + + const Uint32 tmp = entry.m_key | m_currentSection; + const Uint32 sz = m_cfg->m_size; + Uint32 pos = hash(tmp, sz); + Uint32 count = 0; + Uint32 val = m_cfg->m_values[pos]; + + while((val & KP_MASK) != tmp && val != CFV_KEY_FREE && count < sz){ + pos = nextHash(tmp, sz, pos, ++count); + val = m_cfg->m_values[pos]; + } + + if((val & KP_MASK) == tmp){ + DEBUG ndbout_c("key %x already found at pos: %d", tmp, pos); + return false; + } + + if(count >= sz){ + pos = hash(tmp, sz); + count = 0; + Uint32 val = m_cfg->m_values[pos]; + + printf("key: %d, (key %% size): %d\n", entry.m_key, (entry.m_key % sz)); + printf("pos: %d", pos); + while((val & KP_MASK) != tmp && val != CFV_KEY_FREE && count < sz){ + pos = nextHash(tmp, sz, pos, ++count); + val = m_cfg->m_values[pos]; + printf(" %d", pos); + } + printf("\n"); + + abort(); + printf("Full\n"); + return false; + } + + assert(pos < (sz << 1)); + + Uint32 key = tmp; + key |= (entry.m_type << KP_TYPE_SHIFT); + m_cfg->m_values[pos] = key; + switch(entry.m_type){ + case ConfigValues::IntType: + case ConfigValues::SectionType: + m_cfg->m_values[pos+1] = entry.m_int; + m_freeKeys--; + DEBUG printf("Putting at: %d(%d) (loop = %d) key: %d value: %d\n", + pos, sz, count, + (key >> KP_KEYVAL_SHIFT) & KP_KEYVAL_MASK, + entry.m_int); + return true; + case ConfigValues::StringType:{ + Uint32 index = m_cfg->m_stringCount++; + m_cfg->m_values[pos+1] = index; + m_cfg->getString(index) = strdup(entry.m_string); + m_freeKeys--; + m_freeData -= sizeof(char *); + DEBUG printf("Putting at: %d(%d) (loop = %d) key: %d value(%d): %s\n", + pos, sz, count, + (key >> KP_KEYVAL_SHIFT) & KP_KEYVAL_MASK, + index, + entry.m_string); + return true; + } + case ConfigValues::Int64Type:{ + Uint32 index = m_cfg->m_int64Count++; + m_cfg->m_values[pos+1] = index; + m_cfg->get64(index) = entry.m_int64; + m_freeKeys--; + m_freeData -= 8; + DEBUG printf("Putting at: %d(%d) (loop = %d) key: %d value64(%d): %lld\n", + pos, sz, count, + (key >> KP_KEYVAL_SHIFT) & KP_KEYVAL_MASK, + index, + entry.m_int64); + return true; + } + case ConfigValues::InvalidType: + default: + return false; + } + return false; +} + +void +ConfigValuesFactory::put(const ConfigValues & cfg){ + + Uint32 curr = m_currentSection; + m_currentSection = 0; + + ConfigValues::Entry tmp; + for(Uint32 i = 0; i < 2 * cfg.m_size; i += 2){ + if(cfg.m_values[i] != CFV_KEY_FREE){ + tmp.m_key = cfg.m_values[i]; + cfg.getByPos(i, &tmp); + put(tmp); + } + } + + m_currentSection = curr; +} + +ConfigValues * +ConfigValuesFactory::extractCurrentSection(const ConfigValues::ConstIterator & cfg){ + ConfigValuesFactory * fac = new ConfigValuesFactory(20, 20); + Uint32 curr = cfg.m_currentSection; + + ConfigValues::Entry tmp; + for(Uint32 i = 0; i < 2 * cfg.m_cfg.m_size; i += 2){ + Uint32 keypart = cfg.m_cfg.m_values[i]; + const Uint32 sec = keypart & (KP_SECTION_MASK << KP_SECTION_SHIFT); + const Uint32 key = keypart & KP_KEYVAL_MASK; + if(sec == curr && key != CFV_KEY_PARENT){ + tmp.m_key = cfg.m_cfg.m_values[i]; + cfg.m_cfg.getByPos(i, &tmp); + tmp.m_key = key; + fac->put(tmp); + } + } + + ConfigValues * ret = fac->m_cfg; + delete fac; + return ret; +} + +ConfigValues * +ConfigValuesFactory::getConfigValues(){ + ConfigValues * ret = m_cfg; + m_cfg = create(10, 10); + return ret; +} + +static int +mod4(unsigned int i){ + int res = i + (4 - (i % 4)); + return res; +} + +Uint32 +ConfigValues::getPackedSize() const { + + Uint32 size = 0; + for(Uint32 i = 0; i < 2 * m_size; i += 2){ + Uint32 key = m_values[i]; + if(key != CFV_KEY_FREE){ + switch(::getTypeOf(key)){ + case IntType: + case SectionType: + size += 8; + break; + case Int64Type: + size += 12; + break; + case StringType: + size += 8; // key + len + size += mod4(strlen(getString(m_values[i+1])) + 1); + break; + case InvalidType: + default: + abort(); + } + } + } + + return size + sizeof(Magic) + 4; // checksum also +} + +Uint32 +ConfigValues::pack(void * _dst, Uint32 _len) const { + + char * dst = (char*)_dst; + memcpy(dst, Magic, sizeof(Magic)); dst += sizeof(Magic); + + for(Uint32 i = 0; i < 2 * m_size; i += 2){ + Uint32 key = m_values[i]; + Uint32 val = m_values[i+1]; + if(key != CFV_KEY_FREE){ + switch(::getTypeOf(key)){ + case IntType: + case SectionType: + * (Uint32*)dst = htonl(key); dst += 4; + * (Uint32*)dst = htonl(val); dst += 4; + break; + case Int64Type:{ + Uint64 i64 = get64(val); + Uint32 hi = (i64 >> 32); + Uint32 lo = (i64 & 0xFFFFFFFF); + * (Uint32*)dst = htonl(key); dst += 4; + * (Uint32*)dst = htonl(hi); dst += 4; + * (Uint32*)dst = htonl(lo); dst += 4; + } + break; + case StringType:{ + const char * str = getString(val); + Uint32 len = strlen(str) + 1; + * (Uint32*)dst = htonl(key); dst += 4; + * (Uint32*)dst = htonl(len); dst += 4; + memcpy(dst, str, len); + memset(dst+len, 0, mod4(len) - len); + dst += mod4(len); + } + break; + case InvalidType: + default: + abort(); + } + } + } + + const Uint32 * sum = (Uint32*)_dst; + const Uint32 len = ((Uint32*)dst) - sum; + Uint32 chk = 0; + for(Uint32 i = 0; i<len; i++){ + chk ^= htonl(sum[i]); + } + + * (Uint32*)dst = htonl(chk); dst += 4; + return 4 * (len + 1); +} + +bool +ConfigValuesFactory::unpack(const void * _src, Uint32 len){ + + if(len < sizeof(Magic) + 4){ + DEBUG abort(); + return false; + } + + if(memcmp(_src, Magic, sizeof(Magic)) != 0){ + DEBUG abort(); + return false; + } + + const char * src = (const char *)_src; + + { + Uint32 len32 = (len >> 2); + const Uint32 * tmp = (const Uint32*)_src; + Uint32 chk = 0; + for(Uint32 i = 0; (i+1)<len32; i++){ + chk ^= ntohl(tmp[i]); + } + + if(chk != ntohl(tmp[len32-1])){ + DEBUG abort(); + return false; + } + } + + const char * end = src + len - 4; + src += sizeof(Magic); + + ConfigValues::Entry entry; + while(end - src > 4){ + Uint32 tmp = ntohl(* (const Uint32 *)src); src += 4; + entry.m_key = tmp & KP_MASK; + entry.m_type = ::getTypeOf(tmp); + switch(entry.m_type){ + case ConfigValues::IntType: + case ConfigValues::SectionType: + entry.m_int = ntohl(* (const Uint32 *)src); src += 4; + break; + case ConfigValues::Int64Type:{ + Uint64 hi = ntohl(* (const Uint32 *)src); src += 4; + Uint64 lo = ntohl(* (const Uint32 *)src); src += 4; + entry.m_int64 = (hi <<32) | lo; + } + break; + case ConfigValues::StringType:{ + Uint32 s_len = ntohl(* (const Uint32 *)src); src += 4; + size_t s_len2 = strnlen((const char*)src, s_len); + if(s_len2 + 1 != s_len){ + DEBUG abort(); + return false; + } + + entry.m_string = (const char*)src; src+= mod4(s_len); + } + break; + case ConfigValues::InvalidType: + default: + DEBUG abort(); + return false; + } + if(!put(entry)){ + DEBUG abort(); + return false; + } + } + if(src != end){ + DEBUG abort(); + return false; + } + return true; +} + +#ifdef __TEST_CV_HASH_HPP + +int +main(void){ + srand(time(0)); + for(int t = 0; t<100; t++){ + const size_t len = directory(rand() % 1000); + + printf("size = %d\n", len); + unsigned * buf = new unsigned[len]; + for(size_t key = 0; key<len; key++){ + Uint32 p = hash(key, len); + for(size_t j = 0; j<len; j++){ + buf[j] = p; + p = nextHash(key, len, p, j+1); + } + + for(size_t j = 0; j<len; j++){ + Uint32 pos = buf[j]; + int unique = 0; + for(size_t k = j + 1; k<len; k++){ + if(pos == buf[k]){ + if(unique > 0) + printf("size=%d key=%d pos(%d)=%d buf[%d]=%d\n", len, key, j, pos, k, buf[k]); + unique ++; + } + } + if(unique > 1){ + printf("key = %d size = %d not uniqe!!\n", key, len); + for(size_t k = 0; k<len; k++){ + printf("%d ", buf[k]); + } + printf("\n"); + } + } + } + delete[] buf; + } + return 0; +} + +#endif diff --git a/ndb/src/common/util/Makefile_old b/ndb/src/common/util/Makefile_old index e8ca2b87c20..65093396246 100644 --- a/ndb/src/common/util/Makefile_old +++ b/ndb/src/common/util/Makefile_old @@ -8,7 +8,7 @@ ARCHIVE_TARGET := general SOURCES = File.cpp md5_hash.cpp Properties.cpp socket_io.cpp \ SimpleProperties.cpp Parser.cpp InputStream.cpp SocketServer.cpp \ OutputStream.cpp NdbOut.cpp BaseString.cpp Base64.cpp \ - NdbSqlUtil.cpp new.cpp + NdbSqlUtil.cpp ConfigValues.cpp new.cpp SOURCES.c = uucode.c random.c getarg.c version.c @@ -20,7 +20,7 @@ ifeq ($(NDB_OS), OSE) endif SOURCES.c += strdup.c strlcat.c strlcpy.c -DIRS := testSimpleProperties +DIRS := testSimpleProperties testProperties testConfigValues include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/common/util/Properties.cpp b/ndb/src/common/util/Properties.cpp index 2ab008142ba..3e41056ac18 100644 --- a/ndb/src/common/util/Properties.cpp +++ b/ndb/src/common/util/Properties.cpp @@ -21,6 +21,12 @@ #include <NdbTCP.h> #include <NdbOut.hpp> +static +char * f_strdup(const char * s){ + if(!s) return 0; + return strdup(s); +} + /** * Note has to be a multiple of 4 bytes */ @@ -36,6 +42,7 @@ struct PropertyImpl{ ~PropertyImpl(); PropertyImpl(const char * name, Uint32 value); + PropertyImpl(const char * name, Uint64 value); PropertyImpl(const char * name, const char * value); PropertyImpl(const char * name, const Properties * value); @@ -167,6 +174,11 @@ Properties::put(const char * name, Uint32 value, bool replace){ return ::put(impl, name, value, replace); } +bool +Properties::put64(const char * name, Uint64 value, bool replace){ + return ::put(impl, name, value, replace); +} + bool Properties::put(const char * name, const char * value, bool replace){ return ::put(impl, name, value, replace); @@ -208,6 +220,40 @@ Properties::get(const char * name, Uint32 * value) const { setErrno(E_PROPERTIES_OK); return true; } + + if(nvp->valueType == PropertiesType_Uint64){ + Uint64 tmp = * (Uint64 *)nvp->value; + Uint64 max = 1; max <<= 32; + if(tmp < max){ + * value = (Uint32)tmp; + setErrno(E_PROPERTIES_OK); + return true; + } + } + setErrno(E_PROPERTIES_INVALID_TYPE); + return false; +} + +bool +Properties::get(const char * name, Uint64 * value) const { + PropertyImpl * nvp = impl->get(name); + if(nvp == 0){ + setErrno(E_PROPERTIES_NO_SUCH_ELEMENT); + return false; + } + + if(nvp->valueType == PropertiesType_Uint32){ + Uint32 tmp = * (Uint32 *)nvp->value; + * value = (Uint64)tmp; + setErrno(E_PROPERTIES_OK); + return true; + } + + if(nvp->valueType == PropertiesType_Uint64){ + * value = * (Uint64 *)nvp->value; + setErrno(E_PROPERTIES_OK); + return true; + } setErrno(E_PROPERTIES_INVALID_TYPE); return false; } @@ -263,7 +309,7 @@ Properties::getCopy(const char * name, char ** value) const { } if(nvp->valueType == PropertiesType_char){ - * value = strdup((const char *)nvp->value); + * value = f_strdup((const char *)nvp->value); setErrno(E_PROPERTIES_OK); return true; } @@ -313,6 +359,10 @@ Properties::print(FILE * out, const char * prefix) const{ fprintf(out, "%s%s = (Uint32) %d\n", buf, impl->content[i]->name, *(Uint32 *)impl->content[i]->value); break; + case PropertiesType_Uint64: + fprintf(out, "%s%s = (Uint64) %lld\n", buf, impl->content[i]->name, + *(Uint64 *)impl->content[i]->value); + break; case PropertiesType_char: fprintf(out, "%s%s = (char*) \"%s\"\n", buf, impl->content[i]->name, (char *)impl->content[i]->value); @@ -598,11 +648,18 @@ PropertiesImpl::getPackedSize(Uint32 pLen) const { sz += 4; // Name Len sz += 4; // Value Len sz += mod4(pLen + strlen(content[i]->name)); // Name - if(content[i]->valueType == PropertiesType_char){ + switch(content[i]->valueType){ + case PropertiesType_char: sz += mod4(strlen((char *)content[i]->value)); - } else if(content[i]->valueType == PropertiesType_Uint32){ + break; + case PropertiesType_Uint32: sz += mod4(4); - } else { + break; + case PropertiesType_Uint64: + sz += mod4(8); + break; + case PropertiesType_Properties: + default: assert(0); } } @@ -700,6 +757,9 @@ PropertiesImpl::pack(Uint32 *& buf, const char * prefix, Uint32 pLen) const { case PropertiesType_Uint32: valLenData = 4; break; + case PropertiesType_Uint64: + valLenData = 8; + break; case PropertiesType_char: valLenData = strlen((char *)content[i]->value); break; @@ -722,6 +782,14 @@ PropertiesImpl::pack(Uint32 *& buf, const char * prefix, Uint32 pLen) const { case PropertiesType_Uint32: * (Uint32 *)valBuf = htonl(* (Uint32 *)content[i]->value); break; + case PropertiesType_Uint64:{ + Uint64 val = * (Uint64 *)content[i]->value; + Uint32 hi = (val >> 32); + Uint32 lo = (val & 0xFFFFFFFF); + * (Uint32 *)valBuf = htonl(hi); + * (Uint32 *)(valBuf + 4) = htonl(lo); + } + break; case PropertiesType_char: memcpy(valBuf, content[i]->value, strlen((char*)content[i]->value)); break; @@ -788,6 +856,12 @@ PropertiesImpl::unpack(const Uint32 * buf, Uint32 &bufLen, Properties * top, case PropertiesType_Uint32: res3 = top->put(nameBuf, ntohl(* (Uint32 *)valBuf), true); break; + case PropertiesType_Uint64:{ + Uint64 hi = ntohl(* (Uint32 *)valBuf); + Uint64 lo = ntohl(* (Uint32 *)(valBuf + 4)); + res3 = top->put64(nameBuf, (hi << 32) + lo, true); + } + break; case PropertiesType_char: res3 = top->put(nameBuf, valBuf, true); break; @@ -808,6 +882,9 @@ PropertyImpl::~PropertyImpl(){ case PropertiesType_Uint32: delete (Uint32 *)value; break; + case PropertiesType_Uint64: + delete (Uint64 *)value; + break; case PropertiesType_char: free((char *)value); break; @@ -822,6 +899,8 @@ PropertyImpl::copyPropertyImpl(const PropertyImpl & org){ switch(org.valueType){ case PropertiesType_Uint32: return new PropertyImpl(org.name, * (Uint32 *)org.value); + case PropertiesType_Uint64: + return new PropertyImpl(org.name, * (Uint64 *)org.value); break; case PropertiesType_char: return new PropertyImpl(org.name, (char *)org.value); @@ -836,21 +915,28 @@ PropertyImpl::copyPropertyImpl(const PropertyImpl & org){ } PropertyImpl::PropertyImpl(const char * _name, Uint32 _value){ - this->name = strdup(_name); + this->name = f_strdup(_name); this->value = new Uint32; * ((Uint32 *)this->value) = _value; this->valueType = PropertiesType_Uint32; } +PropertyImpl::PropertyImpl(const char * _name, Uint64 _value){ + this->name = f_strdup(_name); + this->value = new Uint64; + * ((Uint64 *)this->value) = _value; + this->valueType = PropertiesType_Uint64; +} + PropertyImpl::PropertyImpl(const char * _name, const char * _value){ - this->name = strdup(_name); - this->value = strdup(_value); + this->name = f_strdup(_name); + this->value = f_strdup(_value); this->valueType = PropertiesType_char; } PropertyImpl::PropertyImpl(const char * _name, const Properties * _value){ - this->name = strdup(_name); + this->name = f_strdup(_name); this->value = new Properties(* _value); this->valueType = PropertiesType_Properties; } @@ -902,6 +988,16 @@ Properties::put(const char * name, Uint32 no, Uint32 val, bool replace){ return res; } +bool +Properties::put64(const char * name, Uint32 no, Uint64 val, bool replace){ + size_t tmp_len = strlen(name)+20; + char * tmp = (char*)malloc(tmp_len); + snprintf(tmp, tmp_len, "%s_%d", name, no); + bool res = put(tmp, val, replace); + free(tmp); + return res; +} + bool Properties::put(const char * name, Uint32 no, const char * val, bool replace){ @@ -957,6 +1053,16 @@ Properties::get(const char * name, Uint32 no, Uint32 * value) const{ return res; } +bool +Properties::get(const char * name, Uint32 no, Uint64 * value) const{ + size_t tmp_len = strlen(name)+20; + char * tmp = (char*)malloc(tmp_len); + snprintf(tmp, tmp_len, "%s_%d", name, no); + bool res = get(tmp, value); + free(tmp); + return res; +} + bool Properties::get(const char * name, Uint32 no, const char ** value) const { diff --git a/ndb/src/common/util/socket_io.cpp b/ndb/src/common/util/socket_io.cpp index 8def7ebe91b..97bb4863a67 100644 --- a/ndb/src/common/util/socket_io.cpp +++ b/ndb/src/common/util/socket_io.cpp @@ -202,13 +202,13 @@ vprintln_socket(NDB_SOCKET_TYPE socket, int timeout_millis, size_t size = sizeof(buf); if (fmt != 0) { - size = vsnprintf(buf, sizeof(buf)-1, fmt, ap); + size = vsnprintf(buf, sizeof(buf), fmt, ap); /* Check if the output was truncated */ - if(size >= sizeof(buf)) { + if(size >= sizeof(buf)-1) { buf2 = (char *)malloc(size+2); if(buf2 == NULL) return -1; - vsnprintf(buf2, size, fmt, ap); + vsnprintf(buf2, size+1, fmt, ap); } else size = sizeof(buf); } else diff --git a/ndb/src/common/util/testConfigValues/Makefile b/ndb/src/common/util/testConfigValues/Makefile new file mode 100644 index 00000000000..5b7400f5ee3 --- /dev/null +++ b/ndb/src/common/util/testConfigValues/Makefile @@ -0,0 +1,12 @@ +include .defs.mk + +TYPE := util + +BIN_TARGET := testConfigValues +BIN_TARGET_ARCHIVES := portlib general + +SOURCES := testConfigValues.cpp + +CCFLAGS_LOC += -I$(call fixpath,$(NDB_TOP)/include/util) + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/common/util/testConfigValues/testConfigValues.cpp b/ndb/src/common/util/testConfigValues/testConfigValues.cpp new file mode 100644 index 00000000000..362deb1ddad --- /dev/null +++ b/ndb/src/common/util/testConfigValues/testConfigValues.cpp @@ -0,0 +1,122 @@ +#include <ConfigValues.hpp> +#include <NdbOut.hpp> +#include <stdlib.h> +#include <string.h> + +#define CF_NODES 1 +#define CF_LOG_PAGES 2 +#define CF_MEM_PAGES 3 +#define CF_START_TO 4 +#define CF_STOP_TO 5 + +void print(Uint32 i, ConfigValues::ConstIterator & cf){ + ndbout_c("---"); + for(Uint32 j = 2; j<=7; j++){ + switch(cf.getTypeOf(j)){ + case ConfigValues::IntType: + ndbout_c("Node %d : CFG(%d) : %d", + i, j, cf.get(j, 999)); + break; + case ConfigValues::Int64Type: + ndbout_c("Node %d : CFG(%d) : %lld (64)", + i, j, cf.get64(j, 999)); + break; + case ConfigValues::StringType: + ndbout_c("Node %d : CFG(%d) : %s", + i, j, cf.get(j, "<NOT FOUND>")); + break; + default: + ndbout_c("Node %d : CFG(%d) : TYPE: %d", + i, j, cf.getTypeOf(j)); + } + } +} + +void print(Uint32 i, ConfigValues & _cf){ + ConfigValues::ConstIterator cf(_cf); + print(i, cf); +} + +void +print(ConfigValues & _cf){ + ConfigValues::ConstIterator cf(_cf); + Uint32 i = 0; + while(cf.openSection(CF_NODES, i)){ + print(i, cf); + cf.closeSection(); + i++; + } +} + +inline +void +require(bool b){ + if(!b) + abort(); +} + +int +main(void){ + + { + ConfigValuesFactory cvf(10, 20); + cvf.openSection(1, 0); + cvf.put(2, 12); + cvf.put64(3, 13); + cvf.put(4, 14); + cvf.put64(5, 15); + cvf.put(6, "Keso"); + cvf.put(7, "Kent"); + cvf.closeSection(); + + cvf.openSection(1, 1); + cvf.put(2, 22); + cvf.put64(3, 23); + cvf.put(4, 24); + cvf.put64(5, 25); + cvf.put(6, "Kalle"); + cvf.put(7, "Anka"); + cvf.closeSection(); + + ndbout_c("-- print --"); + print(* cvf.m_cfg); + + cvf.shrink(); + ndbout_c("shrink\n-- print --"); + print(* cvf.m_cfg); + cvf.expand(10, 10); + ndbout_c("expand\n-- print --"); + print(* cvf.m_cfg); + + ndbout_c("packed size: %d", cvf.m_cfg->getPackedSize()); + + ConfigValues::ConstIterator iter(* cvf.m_cfg); + iter.openSection(CF_NODES, 0); + ConfigValues * cfg2 = ConfigValuesFactory::extractCurrentSection(iter); + print(99, * cfg2); + + cvf.shrink(); + ndbout_c("packed size: %d", cfg2->getPackedSize()); + + UtilBuffer buf; + Uint32 l1 = cvf.m_cfg->pack(buf); + Uint32 l2 = cvf.m_cfg->getPackedSize(); + require(l1 == l2); + + ConfigValuesFactory cvf2; + require(cvf2.unpack(buf)); + UtilBuffer buf2; + cvf2.shrink(); + Uint32 l3 = cvf2.m_cfg->pack(buf2); + require(l1 == l3); + + ndbout_c("unpack\n-- print --"); + print(* cvf2.m_cfg); + + cfg2->~ConfigValues();; + cvf.m_cfg->~ConfigValues(); + free(cfg2); + free(cvf.m_cfg); + } + return 0; +} diff --git a/ndb/src/common/util/testProperties/Makefile b/ndb/src/common/util/testProperties/Makefile index 00b4465b69d..343c07a49e7 100644 --- a/ndb/src/common/util/testProperties/Makefile +++ b/ndb/src/common/util/testProperties/Makefile @@ -1,12 +1,9 @@ include .defs.mk -TYPE := +TYPE := util BIN_TARGET := keso -BIN_TARGET_ARCHIVES := portlib general SOURCES := testProperties.cpp -CCFLAGS_LOC += -I$(call fixpath,$(NDB_TOP)/include/util) - include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/common/util/testProperties/testProperties.cpp b/ndb/src/common/util/testProperties/testProperties.cpp index 3aa2af92c5b..e445f7ca3e4 100644 --- a/ndb/src/common/util/testProperties/testProperties.cpp +++ b/ndb/src/common/util/testProperties/testProperties.cpp @@ -63,12 +63,6 @@ readFromFile(Properties & p, const char *fname, bool uu = true){ return res; } -Property defs[] = { - Property("Rolf", 123) - ,Property("Keso", "Kent") -}; - - void putALot(Properties & tmp){ int i = 123; tmp.put("LockPagesInMainMemory", i++); @@ -124,7 +118,6 @@ main(void){ p.put("Ank4", "anka"); putALot(p); - //p.put(defs, 2); Properties tmp; tmp.put("Type", "TCP"); tmp.put("OwnNodeId", 1); @@ -136,8 +129,8 @@ main(void){ tmp.put("Compression", (Uint32)false); tmp.put("Checksum", 1); - tmp.put("SendBufferSize", 2000); - tmp.put("MaxReceiveSize", 1000); + tmp.put64("SendBufferSize", 2000); + tmp.put64("MaxReceiveSize", 1000); tmp.put("PortNumber", 1233); putALot(tmp); diff --git a/ndb/src/kernel/Makefile_old b/ndb/src/kernel/Makefile_old index 11261c047a6..d1f1741aca4 100644 --- a/ndb/src/kernel/Makefile_old +++ b/ndb/src/kernel/Makefile_old @@ -1,5 +1,5 @@ include .defs.mk -DIRS := error blocks vm ndb-main +DIRS := error vm ndb-main blocks include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/kernel/blocks/ERROR_codes.txt b/ndb/src/kernel/blocks/ERROR_codes.txt index 331333c101e..92dbfd067f7 100644 --- a/ndb/src/kernel/blocks/ERROR_codes.txt +++ b/ndb/src/kernel/blocks/ERROR_codes.txt @@ -4,7 +4,7 @@ Next NDBFS 2000 Next DBACC 3001 Next DBTUP 4007 Next DBLQH 5036 -Next DBDICT 6003 +Next DBDICT 6006 Next DBDIH 7173 Next DBTC 8035 Next CMVMI 9000 @@ -12,7 +12,6 @@ Next BACKUP 10022 Next DBUTIL 11002 Next DBTUX 12001 Next SUMA 13001 -Next DBDICT 14003 TESTING NODE FAILURE, ARBITRATION --------------------------------- @@ -425,6 +424,6 @@ Ordered index: Dbdict: ------- -14000 Crash in participant @ CreateTabReq::Prepare -14001 Crash in participant @ CreateTabReq::Commit -14002 Crash in participant @ CreateTabReq::CreateDrop +6003 Crash in participant @ CreateTabReq::Prepare +6004 Crash in participant @ CreateTabReq::Commit +6005 Crash in participant @ CreateTabReq::CreateDrop diff --git a/ndb/src/kernel/blocks/Start.txt b/ndb/src/kernel/blocks/Start.txt index 545296d44f1..3e805ebab55 100644 --- a/ndb/src/kernel/blocks/Start.txt +++ b/ndb/src/kernel/blocks/Start.txt @@ -60,8 +60,8 @@ Cluster participant - including info in DIH_RESTART_REF/CONF 4) Wait until - -a) Receiving CNTR_MASTER_CONF -> continue -b) Receiving CNTR_MASTER_REF -> P = node specified in REF, goto 3 +b) Receiving CNTR_START_CONF -> continue +b) Receiving CNTR_START_REF -> P = node specified in REF, goto 3 c) TimeToWaitAlive has passed -> Failure to start 4) Run ndb-startphase 1 @@ -70,18 +70,23 @@ c) TimeToWaitAlive has passed -> Failure to start Initial start/System restart NdbCntr (on qmgr president node) 1) Wait until - -a) Receiving all CNTR_MASTER_REQ (all = those in READ_NODES_CONF) -b) TimeToWaitAlive has passed -> Failure to start +a) Receiving CNTR_START_REQ with GCI > than own GCI + send CNTR_START_REF to all waiting nodes +b) Receiving all CNTR_START_REQ (for all defined nodes) +c) TimeToWait has passed and partition win +d) TimeToWait has passed and partitioning + and configuration "start with partition" = true -2) Wait until - -a) Enough nodes (at least 1 in each node group and 1 full node group) - has sent me CNTR_MASTER_REQ -b) TimeToWaitAlive has passed -> Failure to start +2) Send CNTR_START_CONF to all nodes "with filesystem" + +3) Wait until - + Receiving CNTR_START_REP for all starting nodes -3) Decide what kind of start to perform (initial / system restart) - Decide who should be the master (the one with greatest GCI) - Send CNTR_MASTER_CONF(initial/system restart) to all nodes included in start +4) Start waiting nodes (if any) +NOTE: +1c) Partition win = 1 node in each node group and 1 full node group +1d) Pattitioning = at least 1 node in each node group -- Running NdbCntr @@ -90,8 +95,3 @@ When receiving CNTR_MASTER_REQ 2) If I'm master Coordinate parallell node restarts send CNTR_MASTER_CONF (node restart) - -NOTE: -2a Specified with a command line/config parameter the system could - start using only one node in each node group (if possible w.r.t LCP/GCP) - diff --git a/ndb/src/kernel/blocks/backup/BackupInit.cpp b/ndb/src/kernel/blocks/backup/BackupInit.cpp index 1997e560bb9..36ce1857144 100644 --- a/ndb/src/kernel/blocks/backup/BackupInit.cpp +++ b/ndb/src/kernel/blocks/backup/BackupInit.cpp @@ -38,14 +38,14 @@ Backup::Backup(const Configuration & conf) : c_nodePool.setSize(MAX_NDB_NODES); c_masterNodeId = getOwnNodeId(); - const Properties * p = conf.getOwnProperties(); + const ndb_mgm_configuration_iterator * p = conf.getOwnConfigIterator(); ndbrequire(p != 0); Uint32 noBackups = 0, noTables = 0, noAttribs = 0; - p->get("ParallelBackups", &noBackups); - ndbrequire(p->get("MaxNoOfTables", &noTables)); - ndbrequire(p->get("MaxNoOfAttributes", &noAttribs)); - + ndb_mgm_get_int_parameter(p, CFG_DB_PARALLEL_BACKUPS, &noBackups); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_NO_TABLES, &noTables)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_NO_ATTRIBUTES, &noAttribs)); + // To allow for user tables AND SYSTAB // See ClusterConfig //TODO get this infor from NdbCntr @@ -65,7 +65,7 @@ Backup::Backup(const Configuration & conf) : c_fragmentPool.setSize(noBackups * 2 * NO_OF_FRAG_PER_NODE * noTables); Uint32 szMem = 0; - p->get("BackupMemory", &szMem); + ndb_mgm_get_int_parameter(p, CFG_DB_BACKUP_MEM, &szMem); Uint32 noPages = (szMem + sizeof(Page32) - 1) / sizeof(Page32); // We need to allocate an additional of 2 pages. 1 page because of a bug in // ArrayPool and another one for DICTTAINFO. @@ -74,9 +74,9 @@ Backup::Backup(const Configuration & conf) : Uint32 szDataBuf = (2 * 1024 * 1024); Uint32 szLogBuf = (2 * 1024 * 1024); Uint32 szWrite = 32768; - p->get("BackupDataBufferSize", &szDataBuf); - p->get("BackupLogBufferSize", &szLogBuf); - p->get("BackupWriteSize", &szWrite); + ndb_mgm_get_int_parameter(p, CFG_DB_BACKUP_DATA_BUFFER_MEM, &szDataBuf); + ndb_mgm_get_int_parameter(p, CFG_DB_BACKUP_LOG_BUFFER_MEM, &szLogBuf); + ndb_mgm_get_int_parameter(p, CFG_DB_BACKUP_WRITE_SIZE, &szWrite); c_defaults.m_logBufferSize = szLogBuf; c_defaults.m_dataBufferSize = szDataBuf; diff --git a/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp b/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp index cd6198eff23..7eb7f995eb7 100644 --- a/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp +++ b/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp @@ -16,7 +16,6 @@ #include "Cmvmi.hpp" -#include <ClusterConfiguration.hpp> #include <Configuration.hpp> #include <kernel_types.h> #include <TransporterRegistry.hpp> @@ -31,15 +30,11 @@ #include <signaldata/TestOrd.hpp> #include <signaldata/EventReport.hpp> #include <signaldata/TamperOrd.hpp> -#include <signaldata/SetVarReq.hpp> #include <signaldata/StartOrd.hpp> -#include <signaldata/CmvmiCfgConf.hpp> -#include <signaldata/CmInit.hpp> #include <signaldata/CloseComReqConf.hpp> #include <signaldata/SetLogLevelOrd.hpp> #include <signaldata/EventSubscribeReq.hpp> #include <signaldata/DumpStateOrd.hpp> -#include <signaldata/ArbitSignalData.hpp> #include <signaldata/DisconnectRep.hpp> #include <EventLogger.hpp> @@ -55,8 +50,7 @@ EventLogger g_eventLogger; Cmvmi::Cmvmi(const Configuration & conf) : SimulatedBlock(CMVMI, conf) ,theConfig((Configuration&)conf) - ,theCConfig(conf.clusterConfiguration()), - subscribers(subscriberPool) + ,subscribers(subscriberPool) { BLOCK_CONSTRUCTOR(Cmvmi); @@ -67,14 +61,10 @@ Cmvmi::Cmvmi(const Configuration & conf) : addRecSignal(GSN_NDB_TAMPER, &Cmvmi::execNDB_TAMPER, true); addRecSignal(GSN_SET_LOGLEVELORD, &Cmvmi::execSET_LOGLEVELORD); addRecSignal(GSN_EVENT_REP, &Cmvmi::execEVENT_REP); - addRecSignal(GSN_STTOR, &Cmvmi::execSTTOR_Local); - addRecSignal(GSN_CM_RUN, &Cmvmi::execCM_RUN); - addRecSignal(GSN_CM_INFOREQ, &Cmvmi::execCM_INFOREQ); - addRecSignal(GSN_CMVMI_CFGREQ, &Cmvmi::execCMVMI_CFGREQ); + addRecSignal(GSN_STTOR, &Cmvmi::execSTTOR); addRecSignal(GSN_CLOSE_COMREQ, &Cmvmi::execCLOSE_COMREQ); addRecSignal(GSN_ENABLE_COMORD, &Cmvmi::execENABLE_COMORD); addRecSignal(GSN_OPEN_COMREQ, &Cmvmi::execOPEN_COMREQ); - addRecSignal(GSN_SIZEALT_ACK, &Cmvmi::execSIZEALT_ACK); addRecSignal(GSN_TEST_ORD, &Cmvmi::execTEST_ORD); addRecSignal(GSN_STATISTICS_REQ, &Cmvmi::execSTATISTICS_REQ); @@ -93,16 +83,28 @@ Cmvmi::Cmvmi(const Configuration & conf) : subscriberPool.setSize(5); - const ClusterConfiguration::ClusterData & clData = - theConfig.clusterConfigurationData() ; + const ndb_mgm_configuration_iterator * db = theConfig.getOwnConfigIterator(); + for(unsigned j = 0; j<LogLevel::LOGLEVEL_CATEGORIES; j++){ + Uint32 logLevel; + if(!ndb_mgm_get_int_parameter(db, LogLevel::MIN_LOGLEVEL_ID+j, &logLevel)){ + clogLevel.setLogLevel((LogLevel::EventCategory)j, + logLevel); + } + } - clogLevel = clData.SizeAltData.logLevel; - - for(Uint32 i= 0; i< clData.SizeAltData.noOfNodes; i++ ){ + ndb_mgm_configuration_iterator * iter = theConfig.getClusterConfigIterator(); + for(ndb_mgm_first(iter); ndb_mgm_valid(iter); ndb_mgm_next(iter)){ jam(); - const Uint32 nodeId = clData.nodeData[i].nodeId; - switch(clData.nodeData[i].nodeType){ + Uint32 nodeId; + Uint32 nodeType; + + ndbrequire(!ndb_mgm_get_int_parameter(iter,CFG_NODE_ID, &nodeId)); + ndbrequire(!ndb_mgm_get_int_parameter(iter,CFG_TYPE_OF_SECTION,&nodeType)); + + switch(nodeType){ case NodeInfo::DB: + c_dbNodes.set(nodeId); + break; case NodeInfo::API: case NodeInfo::MGM: case NodeInfo::REP: @@ -110,7 +112,7 @@ Cmvmi::Cmvmi(const Configuration & conf) : default: ndbrequire(false); } - setNodeInfo(nodeId).m_type = clData.nodeData[i].nodeType; + setNodeInfo(nodeId).m_type = nodeType; } } @@ -278,121 +280,42 @@ Cmvmi::cancelSubscription(NodeId nodeId){ void Cmvmi::sendSTTORRY(Signal* signal) { - if( theStartPhase == 1 ) { - const ClusterConfiguration::ClusterData & clusterConf = - theConfig.clusterConfigurationData() ; - const int myNodeId = globalData.ownId; - int MyNodeFound = 0; - - jam(); - - CmInit * const cmInit = (CmInit *)&signal->theData[0]; - - cmInit->heartbeatDbDb = clusterConf.ispValues[0][2]; - cmInit->heartbeatDbApi = clusterConf.ispValues[0][3]; - cmInit->arbitTimeout = clusterConf.ispValues[0][5]; - - NodeBitmask::clear(cmInit->allNdbNodes); - for(unsigned int i = 0; i < clusterConf.SizeAltData.noOfNodes; i++ ) { - jam(); - if (clusterConf.nodeData[i].nodeType == NodeInfo::DB){ - jam(); - const NodeId nodeId = clusterConf.nodeData[i].nodeId; - if (nodeId == myNodeId) { - jam(); - MyNodeFound = 1; - }//if - NodeBitmask::set(cmInit->allNdbNodes, nodeId); - }//if - }//for - - if (MyNodeFound == 0) { - ERROR_SET(fatal, ERR_NODE_NOT_IN_CONFIG, "", ""); - }//if - - sendSignal(QMGR_REF, GSN_CM_INIT, signal, CmInit::SignalLength, JBB); - - // these do not fit into CM_INIT - ArbitSignalData* const sd = (ArbitSignalData*)&signal->theData[0]; - for (unsigned rank = 1; rank <= 2; rank++) { - sd->sender = myNodeId; - sd->code = rank; - sd->node = 0; - sd->ticket.clear(); - sd->mask.clear(); - for (int i = 0; i < MAX_NODES; i++) { - if (clusterConf.nodeData[i].arbitRank == rank) - sd->mask.set(clusterConf.nodeData[i].nodeId); - } - sendSignal(QMGR_REF, GSN_ARBIT_CFG, signal, - ArbitSignalData::SignalLength, JBB); - } - } else { - jam(); - signal->theData[0] = theSignalKey; - signal->theData[3] = 1; - signal->theData[4] = 3; - signal->theData[5] = 255; - sendSignal(NDBCNTR_REF, GSN_STTORRY, signal,6, JBB); - } + jam(); + signal->theData[3] = 1; + signal->theData[4] = 3; + signal->theData[5] = 8; + signal->theData[6] = 255; + sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 7, JBB); }//Cmvmi::sendSTTORRY -// Received a restart signal. -// Answer it like any other block -// PR0 : StartCase -// DR0 : StartPhase -// DR1 : ? -// DR2 : ? -// DR3 : ? -// DR4 : ? -// DR5 : SignalKey - -void Cmvmi::execSTTOR_Local(Signal* signal) +void Cmvmi::execSTTOR(Signal* signal) { - theStartPhase = signal->theData[1]; - theSignalKey = signal->theData[6]; + Uint32 theStartPhase = signal->theData[1]; - const ClusterConfiguration::ClusterData & clusterConf = - theConfig.clusterConfigurationData(); jamEntry(); - if (theStartPhase == 1 && clusterConf.SizeAltData.exist == true){ + if (theStartPhase == 1){ jam(); - signalCount = 0; - execSIZEALT_ACK(signal); + sendSTTORRY(signal); return; } else if (theStartPhase == 3) { jam(); globalData.activateSendPacked = 1; sendSTTORRY(signal); - } else { - jam(); + } else if (theStartPhase == 8){ + /*---------------------------------------------------*/ + /* Open com to API + REP nodes */ + /*---------------------------------------------------*/ + signal->theData[0] = 0; // no answer + signal->theData[1] = 0; // no id + signal->theData[2] = NodeInfo::API; + execOPEN_COMREQ(signal); + signal->theData[0] = 0; // no answer + signal->theData[1] = 0; // no id + signal->theData[2] = NodeInfo::REP; + execOPEN_COMREQ(signal); + globalData.theStartLevel = NodeState::SL_STARTED; sendSTTORRY(signal); - } -} - -void Cmvmi::execSIZEALT_ACK(Signal* signal) -{ - const ClusterConfiguration::ClusterData & clusterConf = - theConfig.clusterConfigurationData(); - jamEntry(); - - if (signalCount < NDB_SIZEALT_OFF){ - jam(); - BlockNumber blockNo = clusterConf.SizeAltData.blockNo[signalCount]; - signal->theData[0] = CMVMI_REF; - - /** - * This send SizeAlt(s) to blocks - * Definition of data content can be found in SignalData/XXXSizeAltReq.H - */ - const unsigned int noOfWords = 20; - for(unsigned int i = 1; i<noOfWords; i++){ - signal->theData[i] = clusterConf.SizeAltData.varSize[signalCount][i].nrr; - } - - signalCount++; - sendSignal(numberToRef(blockNo, 0), GSN_SIZEALT_REP, signal,21, JBB); } else { jam(); @@ -408,90 +331,6 @@ void Cmvmi::execSIZEALT_ACK(Signal* signal) } } -void Cmvmi::execCM_INFOREQ(Signal* signal) -{ - int id = signal->theData[1]; - const BlockReference userRef = signal->theData[0]; - const ClusterConfiguration::ClusterData & clusterConf = - theConfig.clusterConfigurationData(); - const int myNodeId = globalData.ownId; - - jamEntry(); - signal->theData[0] = id; - - for(unsigned int i= 0; i< clusterConf.SizeAltData.noOfNodes; i++ ) { - jam(); - if (clusterConf.nodeData[i].nodeType == NodeInfo::DB){ - NodeId nodeId = clusterConf.nodeData[i].nodeId; - if (nodeId != myNodeId) { - jam(); - globalTransporterRegistry.setPerformState(nodeId, PerformConnect); - } - } - } - - sendSignal(userRef, GSN_CM_INFOCONF, signal, 1, JBB); -} - -void Cmvmi::execCM_RUN(Signal* signal) -{ - jamEntry(); - if (signal->theData[0] == 0) { - jam(); - signal->theData[0] = theSignalKey; - signal->theData[3] = 1; - signal->theData[4] = 3; - signal->theData[5] = 255; - sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 6, JBB); - } else { - globalData.theStartLevel = NodeState::SL_STARTED; - - // Connect to all application nodes. - // Enable communication with all NDB blocks. - - const ClusterConfiguration::ClusterData & clusterConf = - theConfig.clusterConfigurationData(); - jam(); - for(unsigned int i= 0; i< clusterConf.SizeAltData.noOfNodes; i++ ) { - NodeId nodeId = clusterConf.nodeData[i].nodeId; - jam(); - if (clusterConf.nodeData[i].nodeType != NodeInfo::DB && - clusterConf.nodeData[i].nodeType != NodeInfo::MGM){ - - jam(); - globalTransporterRegistry.setPerformState(nodeId, PerformConnect); - globalTransporterRegistry.setIOState(nodeId, HaltIO); - //----------------------------------------------------- - // Report that the connection to the node is opened - //----------------------------------------------------- - signal->theData[0] = EventReport::CommunicationOpened; - signal->theData[1] = clusterConf.nodeData[i].nodeId; - sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB); - //----------------------------------------------------- - } - } - } -} - -void Cmvmi::execCMVMI_CFGREQ(Signal* signal) -{ - const BlockReference userRef = signal->theData[0]; - const ClusterConfiguration::ClusterData & clusterConf = - theConfig.clusterConfigurationData(); - - int theStart_phase = signal->theData[1]; - - jamEntry(); - - CmvmiCfgConf * const cfgConf = (CmvmiCfgConf *)&signal->theData[0]; - - cfgConf->startPhase = theStart_phase; - for(unsigned int i = 0; i<CmvmiCfgConf::NO_OF_WORDS; i++) - cfgConf->theData[i] = clusterConf.ispValues[theStart_phase][i]; - - sendSignal(userRef, GSN_CMVMI_CFGCONF, signal, CmvmiCfgConf::LENGTH,JBB ); -} - void Cmvmi::execCLOSE_COMREQ(Signal* signal) { // Close communication with the node and halt input/output from @@ -540,21 +379,42 @@ void Cmvmi::execOPEN_COMREQ(Signal* signal) const BlockReference userRef = signal->theData[0]; Uint32 tStartingNode = signal->theData[1]; - + Uint32 tData2 = signal->theData[2]; jamEntry(); + + const Uint32 len = signal->getLength(); + if(len == 2){ + globalTransporterRegistry.setPerformState(tStartingNode, PerformConnect); + globalTransporterRegistry.setIOState(tStartingNode, HaltIO); + + //----------------------------------------------------- + // Report that the connection to the node is opened + //----------------------------------------------------- + signal->theData[0] = EventReport::CommunicationOpened; + signal->theData[1] = tStartingNode; + sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB); + //----------------------------------------------------- + } else { + for(unsigned int i = 1; i < MAX_NODES; i++ ) { + jam(); + if (i != getOwnNodeId() && getNodeInfo(i).m_type == tData2){ + jam(); + globalTransporterRegistry.setPerformState(i, PerformConnect); + globalTransporterRegistry.setIOState(i, HaltIO); + + signal->theData[0] = EventReport::CommunicationOpened; + signal->theData[1] = i; + sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB); + } + } + } + if (userRef != 0) { jam(); - signal->theData[0] = signal->theData[1]; - sendSignal(userRef, GSN_OPEN_COMCONF, signal, 2,JBA); + signal->theData[0] = tStartingNode; + signal->theData[1] = tData2; + sendSignal(userRef, GSN_OPEN_COMCONF, signal, len - 1,JBA); } - globalTransporterRegistry.setPerformState(tStartingNode, PerformConnect); - //----------------------------------------------------- - // Report that the connection to the node is opened - //----------------------------------------------------- - signal->theData[0] = EventReport::CommunicationOpened; - signal->theData[1] = tStartingNode; - sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB); - //----------------------------------------------------- } void Cmvmi::execENABLE_COMORD(Signal* signal) @@ -888,18 +748,11 @@ Cmvmi::execSTART_ORD(Signal* signal) { /** * Open connections to management servers */ - - const ClusterConfiguration::ClusterData & clusterConf = - theConfig.clusterConfigurationData() ; - - for(unsigned int i= 0; i < clusterConf.SizeAltData.noOfNodes; i++ ){ - NodeId nodeId = clusterConf.nodeData[i].nodeId; - - if (clusterConf.nodeData[i].nodeType == NodeInfo::MGM){ - - if(globalTransporterRegistry.performState(nodeId) != PerformIO){ - globalTransporterRegistry.setPerformState(nodeId, PerformConnect); - globalTransporterRegistry.setIOState(nodeId, NoHalt); + for(unsigned int i = 1; i < MAX_NODES; i++ ){ + if (getNodeInfo(i).m_type == NodeInfo::MGM){ + if(globalTransporterRegistry.performState(i) != PerformIO){ + globalTransporterRegistry.setPerformState(i, PerformConnect); + globalTransporterRegistry.setIOState(i, NoHalt); } } } @@ -922,17 +775,10 @@ Cmvmi::execSTART_ORD(Signal* signal) { // Disconnect all nodes as part of the system restart. // We need to ensure that we are starting up // without any connected nodes. - const ClusterConfiguration::ClusterData & clusterConf = - theConfig.clusterConfigurationData() ; - const int myNodeId = globalData.ownId; - - for(unsigned int i= 0; i < clusterConf.SizeAltData.noOfNodes; i++ ){ - NodeId nodeId = clusterConf.nodeData[i].nodeId; - if (myNodeId != nodeId && - clusterConf.nodeData[i].nodeType != NodeInfo::MGM){ - - globalTransporterRegistry.setPerformState(nodeId, PerformDisconnect); - globalTransporterRegistry.setIOState(nodeId, HaltIO); + for(unsigned int i = 1; i < MAX_NODES; i++ ){ + if (i != getOwnNodeId() && getNodeInfo(i).m_type != NodeInfo::MGM){ + globalTransporterRegistry.setPerformState(i, PerformDisconnect); + globalTransporterRegistry.setIOState(i, HaltIO); } } @@ -963,6 +809,7 @@ void Cmvmi::execTAMPER_ORD(Signal* signal) void Cmvmi::execSET_VAR_REQ(Signal* signal) { +#if 0 SetVarReq* const setVarReq = (SetVarReq*)&signal->theData[0]; ConfigParamId var = setVarReq->variable(); @@ -1047,7 +894,7 @@ void Cmvmi::execSET_VAR_REQ(Signal* signal) sendSignal(mgmtSrvr, GSN_SET_VAR_REF, signal, 0, JBB); } // switch - +#endif }//execSET_VAR_REQ() @@ -1068,7 +915,7 @@ void Cmvmi::execSET_VAR_REF(Signal* signal) void Cmvmi::handleSET_VAR_REQ(Signal* signal) { - +#if 0 SetVarReq* const setVarReq = (SetVarReq*)&signal->theData[0]; ConfigParamId var = setVarReq->variable(); int val = setVarReq->value(); @@ -1109,7 +956,7 @@ void Cmvmi::handleSET_VAR_REQ(Signal* signal) { sendSignal(CMVMI_REF, GSN_SET_VAR_REF, signal, 1, JBB); return; } // switch - +#endif } #ifdef VM_TRACE @@ -1184,14 +1031,9 @@ Cmvmi::execDUMP_STATE_ORD(Signal* signal) DumpStateOrd * const & dumpState = (DumpStateOrd *)&signal->theData[0]; if (dumpState->args[0] == DumpStateOrd::CmvmiDumpConnections){ - const ClusterConfiguration::ClusterData & clusterConf = - theConfig.clusterConfigurationData() ; - - for(unsigned int i= 0; i < clusterConf.SizeAltData.noOfNodes; i++ ){ - NodeId nodeId = clusterConf.nodeData[i].nodeId; - + for(unsigned int i = 1; i < MAX_NODES; i++ ){ const char* nodeTypeStr = ""; - switch(clusterConf.nodeData[i].nodeType){ + switch(getNodeInfo(i).m_type){ case NodeInfo::DB: nodeTypeStr = "DB"; break; @@ -1204,12 +1046,18 @@ Cmvmi::execDUMP_STATE_ORD(Signal* signal) case NodeInfo::REP: nodeTypeStr = "REP"; break; + case NodeInfo::INVALID: + nodeTypeStr = 0; + break; default: nodeTypeStr = "<UNKNOWN>"; } + if(nodeTypeStr == 0) + continue; + const char* actionStr = ""; - switch (globalTransporterRegistry.performState(nodeId)){ + switch (globalTransporterRegistry.performState(i)){ case PerformNothing: actionStr = "does nothing"; break; @@ -1228,18 +1076,18 @@ Cmvmi::execDUMP_STATE_ORD(Signal* signal) } infoEvent("Connection to %d (%s) %s", - nodeId, + i, nodeTypeStr, actionStr); } } - + if (dumpState->args[0] == DumpStateOrd::CmvmiDumpLongSignalMemory){ infoEvent("Cmvmi: g_sectionSegmentPool size: %d free: %d", g_sectionSegmentPool.getSize(), g_sectionSegmentPool.getNoOfFree()); } - + if (dumpState->args[0] == DumpStateOrd::CmvmiSetRestartOnErrorInsert){ if(signal->getLength() == 1) theConfig.setRestartOnErrorInsert((int)NRT_NoStart_Restart); @@ -1372,15 +1220,7 @@ Cmvmi::execTESTSIG(Signal* signal){ return; } - NodeReceiverGroup rg; rg.m_block = CMVMI; - const ClusterConfiguration::ClusterData & clusterConf = - theConfig.clusterConfigurationData() ; - for(unsigned int i = 0; i < clusterConf.SizeAltData.noOfNodes; i++ ){ - NodeId nodeId = clusterConf.nodeData[i].nodeId; - if (clusterConf.nodeData[i].nodeType == NodeInfo::DB){ - rg.m_nodes.set(nodeId); - } - } + NodeReceiverGroup rg(CMVMI, c_dbNodes); if(signal->getSendersBlockRef() == ref){ /** @@ -1550,6 +1390,26 @@ Cmvmi::execTESTSIG(Signal* signal){ } break; } + case 13:{ + ndbrequire(signal->getNoOfSections() == 0); + Uint32 loop = signal->theData[9]; + if(loop > 0){ + signal->theData[9] --; + sendSignal(CMVMI_REF, GSN_TESTSIG, signal, signal->length(), JBB); + return; + } + sendSignal(ref, GSN_TESTSIG, signal, signal->length(), JBB); + return; + } + case 14:{ + Uint32 count = signal->theData[8]; + signal->theData[10] = count * rg.m_nodes.count(); + for(Uint32 i = 0; i<count; i++){ + sendSignal(rg, GSN_TESTSIG, signal, signal->length(), JBB); + } + return; + } + default: ndbrequire(false); } diff --git a/ndb/src/kernel/blocks/cmvmi/Cmvmi.hpp b/ndb/src/kernel/blocks/cmvmi/Cmvmi.hpp index 4f42c2efc93..1c91f564749 100644 --- a/ndb/src/kernel/blocks/cmvmi/Cmvmi.hpp +++ b/ndb/src/kernel/blocks/cmvmi/Cmvmi.hpp @@ -48,10 +48,7 @@ private: void execNDB_TAMPER(Signal* signal); void execSET_LOGLEVELORD(Signal* signal); void execEVENT_REP(Signal* signal); - void execSTTOR_Local(Signal* signal); - void execCM_RUN(Signal* signal); - void execCM_INFOREQ(Signal* signal); - void execCMVMI_CFGREQ(Signal* signal); + void execSTTOR(Signal* signal); void execCLOSE_COMREQ(Signal* signal); void execENABLE_COMORD(Signal* signal); void execOPEN_COMREQ(Signal* signal); @@ -75,17 +72,13 @@ private: void execTESTSIG(Signal* signal); - int signalCount; - int theSignalKey; - int theStartPhase; - int theNumberOfNodes; - char theErrorMessage[256]; void sendSTTORRY(Signal* signal); LogLevel clogLevel; + NdbNodeBitmask c_dbNodes; + class Configuration & theConfig; - const class ClusterConfiguration & theCConfig; /** * This struct defines the data needed for a EVENT_REP subscriber diff --git a/ndb/src/kernel/blocks/dbacc/Dbacc.hpp b/ndb/src/kernel/blocks/dbacc/Dbacc.hpp index fef41be88c4..6ba2d083e58 100644 --- a/ndb/src/kernel/blocks/dbacc/Dbacc.hpp +++ b/ndb/src/kernel/blocks/dbacc/Dbacc.hpp @@ -958,7 +958,7 @@ private: void execDROP_TAB_REQ(Signal* signal); void execFSREMOVECONF(Signal* signal); void execFSREMOVEREF(Signal* signal); - void execSIZEALT_REP(Signal* signal); + void execREAD_CONFIG_REQ(Signal* signal); void execSET_VAR_REQ(Signal* signal); void execDUMP_STATE_ORD(Signal* signal); @@ -1000,7 +1000,6 @@ private: void initScanFragmentPart(Signal* signal); Uint32 checkScanExpand(Signal* signal); Uint32 checkScanShrink(Signal* signal); - void sendInitialiseRecords(Signal* signal); void initialiseDirRec(Signal* signal); void initialiseDirRangeRec(Signal* signal); void initialiseFragRec(Signal* signal); @@ -1174,7 +1173,7 @@ private: void srReadPagesLab(Signal* signal); void srDoUndoLab(Signal* signal); void ndbrestart1Lab(Signal* signal); - void initialiseRecordsLab(Signal* signal); + void initialiseRecordsLab(Signal* signal, Uint32 returnRef, Uint32 retData); void srReadPagesAllocLab(Signal* signal); void checkNextBucketLab(Signal* signal); void endsavepageLab(Signal* signal); diff --git a/ndb/src/kernel/blocks/dbacc/DbaccInit.cpp b/ndb/src/kernel/blocks/dbacc/DbaccInit.cpp index 107420c7148..90e914987c3 100644 --- a/ndb/src/kernel/blocks/dbacc/DbaccInit.cpp +++ b/ndb/src/kernel/blocks/dbacc/DbaccInit.cpp @@ -179,7 +179,7 @@ Dbacc::Dbacc(const class Configuration & conf): addRecSignal(GSN_DROP_TAB_REQ, &Dbacc::execDROP_TAB_REQ); addRecSignal(GSN_FSREMOVECONF, &Dbacc::execFSREMOVECONF); addRecSignal(GSN_FSREMOVEREF, &Dbacc::execFSREMOVEREF); - addRecSignal(GSN_SIZEALT_REP, &Dbacc::execSIZEALT_REP); + addRecSignal(GSN_READ_CONFIG_REQ, &Dbacc::execREAD_CONFIG_REQ, true); addRecSignal(GSN_SET_VAR_REQ, &Dbacc::execSET_VAR_REQ); initData(); diff --git a/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp b/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp index ea8d808458b..02474f6bee0 100644 --- a/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp +++ b/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp @@ -20,13 +20,11 @@ #include <signaldata/AccFrag.hpp> #include <signaldata/AccScan.hpp> #include <signaldata/AccLock.hpp> -#include <signaldata/AccSizeAltReq.hpp> #include <signaldata/EventReport.hpp> #include <signaldata/FsConf.hpp> #include <signaldata/FsRef.hpp> #include <signaldata/FsRemoveReq.hpp> #include <signaldata/DropTab.hpp> -#include <signaldata/SetVarReq.hpp> #include <signaldata/DumpStateOrd.hpp> // TO_DO_RONM is a label for comments on what needs to be improved in future versions @@ -127,7 +125,7 @@ void Dbacc::execCONTINUEB(Signal* signal) break; case ZINITIALISE_RECORDS: jam(); - initialiseRecordsLab(signal); + initialiseRecordsLab(signal, signal->theData[3], signal->theData[4]); return; break; case ZSR_READ_PAGES_ALLOC: @@ -496,9 +494,6 @@ void Dbacc::execFSWRITEREF(Signal* signal) void Dbacc::execNDB_STTOR(Signal* signal) { Uint32 tstartphase; - Uint32 tconfig1; - Uint32 tconfig2; - Uint32 tlqhConfig1; Uint32 tStartType; jamEntry(); @@ -506,9 +501,6 @@ void Dbacc::execNDB_STTOR(Signal* signal) cmynodeid = signal->theData[1]; tstartphase = signal->theData[2]; tStartType = signal->theData[3]; - tlqhConfig1 = signal->theData[10]; /* DBLQH */ - tconfig1 = signal->theData[16]; /* DBACC */ - tconfig2 = signal->theData[17]; /* DBACC */ switch (tstartphase) { case ZSPH1: jam(); @@ -534,21 +526,7 @@ void Dbacc::execNDB_STTOR(Signal* signal) //--------------------------------------------- csystemRestart = ZFALSE; }//if - if (tconfig1 > 0) { - jam(); - clblPagesPerTick = tconfig1; - } else { - jam(); - clblPagesPerTick = 1; - }//if - clblPageCounter = clblPagesPerTick; - if (tconfig2 > 0) { - jam(); - clblPagesPerTickAfterSr = tconfig2; - } else { - jam(); - clblPagesPerTickAfterSr = 1; - }//if + signal->theData[0] = ZLOAD_BAL_LCP_TIMER; sendSignalWithDelay(cownBlockref, GSN_CONTINUEB, signal, 100, 1); break; @@ -606,98 +584,86 @@ void Dbacc::ndbrestart1Lab(Signal* signal) for (Uint32 tmp = 0; tmp < ZMAX_UNDO_VERSION; tmp++) { csrVersList[tmp] = RNIL; }//for - tdata0 = 0; - initialiseRecordsLab(signal); return; }//Dbacc::ndbrestart1Lab() -void Dbacc::initialiseRecordsLab(Signal* signal) +void Dbacc::initialiseRecordsLab(Signal* signal, Uint32 ref, Uint32 data) { switch (tdata0) { case 0: jam(); initialiseTableRec(signal); - sendInitialiseRecords(signal); break; case 1: jam(); initialiseFsConnectionRec(signal); - sendInitialiseRecords(signal); break; case 2: jam(); initialiseFsOpRec(signal); - sendInitialiseRecords(signal); break; case 3: jam(); initialiseLcpConnectionRec(signal); - sendInitialiseRecords(signal); break; case 4: jam(); initialiseDirRec(signal); - sendInitialiseRecords(signal); break; case 5: jam(); initialiseDirRangeRec(signal); - sendInitialiseRecords(signal); break; case 6: jam(); initialiseFragRec(signal); - sendInitialiseRecords(signal); break; case 7: jam(); initialiseOverflowRec(signal); - sendInitialiseRecords(signal); break; case 8: jam(); initialiseOperationRec(signal); - sendInitialiseRecords(signal); break; case 9: jam(); initialisePageRec(signal); - sendInitialiseRecords(signal); break; case 10: jam(); initialiseRootfragRec(signal); - sendInitialiseRecords(signal); break; case 11: jam(); initialiseScanRec(signal); - sendInitialiseRecords(signal); break; case 12: jam(); initialiseSrVerRec(signal); - signal->theData[0] = cownBlockref; - sendSignal(CMVMI_REF, GSN_SIZEALT_ACK, signal, 1, JBB); + + { + ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend(); + conf->senderRef = reference(); + conf->senderData = data; + sendSignal(ref, GSN_READ_CONFIG_CONF, signal, + ReadConfigConf::SignalLength, JBB); + } return; break; default: ndbrequire(false); break; }//switch - return; -}//Dbacc::initialiseRecordsLab() -/* --------------------------------------------------------------------------------- */ -/* SEND REAL-TIME BREAK DURING INITIALISATION OF VARIABLES DURING SYSTEM RESTART.*/ -/* --------------------------------------------------------------------------------- */ -void Dbacc::sendInitialiseRecords(Signal* signal) -{ signal->theData[0] = ZINITIALISE_RECORDS; signal->theData[1] = tdata0 + 1; signal->theData[2] = 0; - sendSignal(cownBlockref, GSN_CONTINUEB, signal, 3, JBB); -}//Dbacc::sendInitialiseRecords() + signal->theData[3] = ref; + signal->theData[4] = data; + sendSignal(reference(), GSN_CONTINUEB, signal, 5, JBB); + return; +}//Dbacc::initialiseRecordsLab() /* *********************************<< */ /* NDB_STTORRY */ @@ -712,23 +678,41 @@ void Dbacc::ndbsttorryLab(Signal* signal) /* *********************************<< */ /* SIZEALT_REP SIZE ALTERATION */ /* *********************************<< */ -void Dbacc::execSIZEALT_REP(Signal* signal) +void Dbacc::execREAD_CONFIG_REQ(Signal* signal) { - Uint32 tsizealtBlockRef; - + const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr(); + Uint32 ref = req->senderRef; + Uint32 senderData = req->senderData; + ndbrequire(req->noOfParameters == 0); + jamEntry(); - tsizealtBlockRef = signal->theData[AccSizeAltReq::IND_BLOCK_REF]; - cdirrangesize = signal->theData[AccSizeAltReq::IND_DIR_RANGE]; - cdirarraysize = signal->theData[AccSizeAltReq::IND_DIR_ARRAY]; - cfragmentsize = signal->theData[AccSizeAltReq::IND_FRAGMENT]; - coprecsize = signal->theData[AccSizeAltReq::IND_OP_RECS]; - coverflowrecsize = signal->theData[AccSizeAltReq::IND_OVERFLOW_RECS]; - cpagesize = signal->theData[AccSizeAltReq::IND_PAGE8]; - crootfragmentsize = signal->theData[AccSizeAltReq::IND_ROOT_FRAG]; - ctablesize = signal->theData[AccSizeAltReq::IND_TABLE]; - cscanRecSize = signal->theData[AccSizeAltReq::IND_SCAN]; + + const ndb_mgm_configuration_iterator * p = + theConfiguration.getOwnConfigIterator(); + ndbrequire(p != 0); + + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_ACC_DIR_RANGE, &cdirrangesize)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_ACC_DIR_ARRAY, &cdirarraysize)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_ACC_FRAGMENT, &cfragmentsize)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_ACC_OP_RECS, &coprecsize)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_ACC_OVERFLOW_RECS, + &coverflowrecsize)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_ACC_PAGE8, &cpagesize)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_ACC_ROOT_FRAG, + &crootfragmentsize)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_ACC_TABLE, &ctablesize)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_ACC_SCAN, &cscanRecSize)); initRecords(); ndbrestart1Lab(signal); + + clblPagesPerTick = 50; + //ndb_mgm_get_int_parameter(p, CFG_DB_, &clblPagesPerTick); + + clblPagesPerTickAfterSr = 50; + //ndb_mgm_get_int_parameter(p, CFG_DB_, &clblPagesPerTickAfterSr); + + tdata0 = 0; + initialiseRecordsLab(signal, ref, senderData); return; }//Dbacc::execSIZEALT_REP() @@ -13260,6 +13244,7 @@ Dbacc::execDUMP_STATE_ORD(Signal* signal) void Dbacc::execSET_VAR_REQ(Signal* signal) { +#if 0 SetVarReq* const setVarReq = (SetVarReq*)&signal->theData[0]; ConfigParamId var = setVarReq->variable(); int val = setVarReq->value(); @@ -13280,6 +13265,6 @@ void Dbacc::execSET_VAR_REQ(Signal* signal) default: sendSignal(CMVMI_REF, GSN_SET_VAR_REF, signal, 1, JBB); } // switch - +#endif }//execSET_VAR_REQ() diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp index 8cf15b6bef2..084f41e4166 100644 --- a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp +++ b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp @@ -27,7 +27,6 @@ #include <SimpleProperties.hpp> #include <AttributeHeader.hpp> #include <signaldata/DictSchemaInfo.hpp> -#include <signaldata/DictSizeAltReq.hpp> #include <signaldata/DictTabInfo.hpp> #include <signaldata/DropTabFile.hpp> @@ -1042,10 +1041,10 @@ Dbdict::Dbdict(const class Configuration & conf): { BLOCK_CONSTRUCTOR(Dbdict); - const Properties * p = conf.getOwnProperties(); + const ndb_mgm_configuration_iterator * p = conf.getOwnConfigIterator(); ndbrequire(p != 0); - p->get("MaxNoOfTriggers", &c_maxNoOfTriggers); + ndb_mgm_get_int_parameter(p, CFG_DB_NO_TRIGGERS, &c_maxNoOfTriggers); // Transit signals addRecSignal(GSN_DUMP_STATE_ORD, &Dbdict::execDUMP_STATE_ORD); addRecSignal(GSN_GET_TABINFOREQ, &Dbdict::execGET_TABINFOREQ); @@ -1161,7 +1160,7 @@ Dbdict::Dbdict(const class Configuration & conf): addRecSignal(GSN_LQHADDATTREF, &Dbdict::execLQHADDATTREF); addRecSignal(GSN_LQHFRAGREF, &Dbdict::execLQHFRAGREF); addRecSignal(GSN_NDB_STTOR, &Dbdict::execNDB_STTOR); - addRecSignal(GSN_SIZEALT_REP, &Dbdict::execSIZEALT_REP); + addRecSignal(GSN_READ_CONFIG_REQ, &Dbdict::execREAD_CONFIG_REQ, true); addRecSignal(GSN_STTOR, &Dbdict::execSTTOR); addRecSignal(GSN_TC_SCHVERCONF, &Dbdict::execTC_SCHVERCONF); addRecSignal(GSN_NODE_FAILREP, &Dbdict::execNODE_FAILREP); @@ -1524,7 +1523,6 @@ void Dbdict::execSTTOR(Signal* signal) c_startPhase = signal->theData[1]; switch (c_startPhase) { case 1: - initCommonData(); break; case 3: c_restartType = signal->theData[7]; /* valid if 3 */ @@ -1551,14 +1549,22 @@ void Dbdict::sendSTTORRY(Signal* signal) /* ---------------------------------------------------------------- */ // We receive information about sizes of records. /* ---------------------------------------------------------------- */ -void Dbdict::execSIZEALT_REP(Signal* signal) +void Dbdict::execREAD_CONFIG_REQ(Signal* signal) { + const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr(); + Uint32 ref = req->senderRef; + Uint32 senderData = req->senderData; + ndbrequire(req->noOfParameters == 0); + jamEntry(); - BlockReference tblockref; - tblockref = signal->theData[DictSizeAltReq::IND_BLOCK_REF]; - Uint32 attributesize = signal->theData[DictSizeAltReq::IND_ATTRIBUTE]; -// Uint32 connectsize = signal->theData[DictSizeAltReq::IND_CONNECT]; - Uint32 tablerecSize = signal->theData[DictSizeAltReq::IND_TABLE]; + + const ndb_mgm_configuration_iterator * p = + theConfiguration.getOwnConfigIterator(); + ndbrequire(p != 0); + + Uint32 attributesize, tablerecSize; + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DICT_ATTRIBUTE,&attributesize)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DICT_TABLE, &tablerecSize)); c_attributeRecordPool.setSize(attributesize); c_attributeRecordHash.setSize(64); @@ -1594,9 +1600,14 @@ void Dbdict::execSIZEALT_REP(Signal* signal) bat[1].bits.q = ZLOG_SIZE_OF_PAGES_IN_WORDS; // 2**13 = 8192 elements bat[1].bits.v = 5; // 32 bits per element + initCommonData(); initRecords(); - signal->theData[0] = DBDICT_REF; - sendSignal(tblockref, GSN_SIZEALT_ACK, signal, 2, JBB); + + ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend(); + conf->senderRef = reference(); + conf->senderData = senderData; + sendSignal(ref, GSN_READ_CONFIG_CONF, signal, + ReadConfigConf::SignalLength, JBB); }//execSIZEALT_REP() /* ---------------------------------------------------------------- */ @@ -2390,7 +2401,7 @@ Dbdict::execGET_TABINFO_CONF(Signal* signal){ SegmentedSectionPtr tabInfoPtr; signal->getSection(tabInfoPtr, GetTabInfoConf::DICT_TAB_INFO); - + CreateTableRecordPtr createTabPtr; ndbrequire(c_opCreateTable.find(createTabPtr, senderData)); ndbrequire(!createTabPtr.isNull()); @@ -2412,7 +2423,10 @@ Dbdict::execGET_TABINFO_CONF(Signal* signal){ callback.m_callbackFunction = safe_cast(&Dbdict::restartCreateTab_writeTableConf); + signal->header.m_noOfSections = 0; writeTableFile(signal, createTabPtr.p->m_tablePtrI, tabInfoPtr, &callback); + signal->setSection(tabInfoPtr, 0); + releaseSections(signal); } void @@ -3820,15 +3834,15 @@ Dbdict::execCREATE_TAB_REQ(Signal* signal){ CreateTabReq::RequestType rt = (CreateTabReq::RequestType)req->requestType; switch(rt){ case CreateTabReq::CreateTablePrepare: - CRASH_INSERTION2(14000, getOwnNodeId() != c_masterNodeId); + CRASH_INSERTION2(6003, getOwnNodeId() != c_masterNodeId); createTab_prepare(signal, req); return; case CreateTabReq::CreateTableCommit: - CRASH_INSERTION2(14001, getOwnNodeId() != c_masterNodeId); + CRASH_INSERTION2(6004, getOwnNodeId() != c_masterNodeId); createTab_commit(signal, req); return; case CreateTabReq::CreateTableDrop: - CRASH_INSERTION2(14002, getOwnNodeId() != c_masterNodeId); + CRASH_INSERTION2(6005, getOwnNodeId() != c_masterNodeId); createTab_drop(signal, req); return; } @@ -3928,9 +3942,9 @@ Dbdict::createTab_writeSchemaConf1(Signal* signal, SegmentedSectionPtr tabInfoPtr; getSection(tabInfoPtr, createTabPtr.p->m_tabInfoPtrI); - writeTableFile(signal, createTabPtr.p->m_tablePtrI, tabInfoPtr, &callback); + createTabPtr.p->m_tabInfoPtrI = RNIL; signal->setSection(tabInfoPtr, 0); releaseSections(signal); } @@ -11498,7 +11512,7 @@ Dbdict::initSchemaFile(SchemaFile * sf, Uint32 fileSz){ ndbrequire(noEntries > MAX_TABLES); sf->NoOfTableEntries = noEntries; - memset(sf->TableEntries, 0, sizeof(noEntries*sizeof(SchemaFile::TableEntry))); + memset(sf->TableEntries, 0, noEntries*sizeof(SchemaFile::TableEntry)); memset(&(sf->TableEntries[noEntries]), 0, slack); computeChecksum(sf); } diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.hpp b/ndb/src/kernel/blocks/dbdict/Dbdict.hpp index 44086b19efd..68214785234 100644 --- a/ndb/src/kernel/blocks/dbdict/Dbdict.hpp +++ b/ndb/src/kernel/blocks/dbdict/Dbdict.hpp @@ -467,7 +467,7 @@ private: void execFSWRITECONF(Signal* signal); void execFSWRITEREF(Signal* signal); void execNDB_STTOR(Signal* signal); - void execSIZEALT_REP(Signal* signal); + void execREAD_CONFIG_REQ(Signal* signal); void execSTTOR(Signal* signal); void execTC_SCHVERCONF(Signal* signal); void execNODE_FAILREP(Signal* signal); diff --git a/ndb/src/kernel/blocks/dbdih/Dbdih.hpp b/ndb/src/kernel/blocks/dbdih/Dbdih.hpp index 4ec699cebec..e029af70574 100644 --- a/ndb/src/kernel/blocks/dbdih/Dbdih.hpp +++ b/ndb/src/kernel/blocks/dbdih/Dbdih.hpp @@ -312,7 +312,6 @@ public: Bitmask<1> m_nodefailSteps; Uint32 activeTabptr; Uint32 nextNode; - Uint32 ndbversion; Uint32 nodeGroup; SignalCounter m_NF_COMPLETE_REP; @@ -663,7 +662,7 @@ private: void execSTOP_ME_REF(Signal *); void execSTOP_ME_CONF(Signal *); - void execSIZEALT_REP(Signal *); + void execREAD_CONFIG_REQ(Signal *); void execUNBLO_DICTCONF(Signal *); void execCOPY_ACTIVECONF(Signal *); void execTAB_COMMITREQ(Signal *); @@ -685,7 +684,6 @@ private: void execNDB_STARTREQ(Signal *); void execGETGCIREQ(Signal *); void execDIH_RESTARTREQ(Signal *); - void execCNTR_CHANGEREP(Signal *); void execSTART_RECCONF(Signal *); void execSTART_FRAGCONF(Signal *); void execADD_FRAGCONF(Signal *); @@ -798,6 +796,7 @@ private: void closeFileDelete(Signal *, FileRecordPtr regFilePtr); void createFileRw(Signal *, FileRecordPtr regFilePtr); void openFileRw(Signal *, FileRecordPtr regFilePtr); + void openFileRo(Signal *, FileRecordPtr regFilePtr); void seizeFile(FileRecordPtr& regFilePtr); void releaseFile(Uint32 fileIndex); @@ -969,7 +968,7 @@ private: void checkCopyTab(NodeRecordPtr failedNodePtr); void initCommonData(); - void initialiseRecordsLab(Signal *, Uint32 stepNo); + void initialiseRecordsLab(Signal *, Uint32 stepNo, Uint32, Uint32); void findReplica(ReplicaRecordPtr& regReplicaPtr, Fragmentstore* fragPtrP, Uint32 nodeId); @@ -1409,7 +1408,6 @@ private: Uint32 startNode; Uint32 wait; Uint32 failNr; - Uint32 ndbVersion; bool activeState; bool blockLcp; bool blockGcp; diff --git a/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp b/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp index b115cc0297a..df47237ae59 100644 --- a/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp +++ b/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp @@ -179,7 +179,7 @@ Dbdih::Dbdih(const class Configuration & config): addRecSignal(GSN_START_LCP_REQ, &Dbdih::execSTART_LCP_REQ); addRecSignal(GSN_START_LCP_CONF, &Dbdih::execSTART_LCP_CONF); - addRecSignal(GSN_SIZEALT_REP, &Dbdih::execSIZEALT_REP); + addRecSignal(GSN_READ_CONFIG_REQ, &Dbdih::execREAD_CONFIG_REQ, true); addRecSignal(GSN_UNBLO_DICTCONF, &Dbdih::execUNBLO_DICTCONF); addRecSignal(GSN_COPY_ACTIVECONF, &Dbdih::execCOPY_ACTIVECONF); addRecSignal(GSN_TAB_COMMITREQ, &Dbdih::execTAB_COMMITREQ); @@ -201,7 +201,6 @@ Dbdih::Dbdih(const class Configuration & config): addRecSignal(GSN_NDB_STARTREQ, &Dbdih::execNDB_STARTREQ); addRecSignal(GSN_GETGCIREQ, &Dbdih::execGETGCIREQ); addRecSignal(GSN_DIH_RESTARTREQ, &Dbdih::execDIH_RESTARTREQ); - addRecSignal(GSN_CNTR_CHANGEREP, &Dbdih::execCNTR_CHANGEREP); addRecSignal(GSN_START_RECCONF, &Dbdih::execSTART_RECCONF); addRecSignal(GSN_START_FRAGCONF, &Dbdih::execSTART_FRAGCONF); addRecSignal(GSN_ADD_FRAGCONF, &Dbdih::execADD_FRAGCONF); diff --git a/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp b/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp index cefbb3e66a3..0ce1f1e4bbe 100644 --- a/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp +++ b/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp @@ -32,7 +32,6 @@ #include <signaldata/DictStart.hpp> #include <signaldata/DiGetNodes.hpp> #include <signaldata/DihContinueB.hpp> -#include <signaldata/DihSizeAltReq.hpp> #include <signaldata/DihSwitchReplica.hpp> #include <signaldata/DumpStateOrd.hpp> #include <signaldata/EmptyLcp.hpp> @@ -45,7 +44,6 @@ #include <signaldata/NFCompleteRep.hpp> #include <signaldata/NodeFailRep.hpp> #include <signaldata/ReadNodesConf.hpp> -#include <signaldata/SetVarReq.hpp> #include <signaldata/StartFragReq.hpp> #include <signaldata/StartInfo.hpp> #include <signaldata/StartMe.hpp> @@ -68,7 +66,7 @@ #include <signaldata/DictTabInfo.hpp> #include <signaldata/CreateFragmentation.hpp> #include <signaldata/LqhFrag.hpp> - +#include <signaldata/FsOpenReq.hpp> #include <DebuggerNames.hpp> #define SYSFILE ((Sysfile *)&sysfileData[0]) @@ -212,7 +210,7 @@ void Dbdih::sendINCL_NODEREQ(Signal* signal, Uint32 nodeId) signal->theData[0] = reference(); signal->theData[1] = c_nodeStartMaster.startNode; signal->theData[2] = c_nodeStartMaster.failNr; - signal->theData[3] = c_nodeStartMaster.ndbVersion; + signal->theData[3] = 0; signal->theData[4] = currentgcp; sendSignal(nodeDihRef, GSN_INCL_NODEREQ, signal, 5, JBB); }//Dbdih::sendINCL_NODEREQ() @@ -291,13 +289,6 @@ void Dbdih::sendUPDATE_TOREQ(Signal* signal, Uint32 nodeId) sendSignal(ref, GSN_UPDATE_TOREQ, signal, UpdateToReq::SignalLength, JBB); }//sendUPDATE_TOREQ() -void Dbdih::execCNTR_CHANGEREP(Signal* signal) -{ - (void)signal; // Don't want compiler warning - jamEntry(); - return; -}//Dbdih::execCNTR_CHANGEREP() - void Dbdih::execCONTINUEB(Signal* signal) { jamEntry(); @@ -542,7 +533,10 @@ void Dbdih::execCONTINUEB(Signal* signal) } case DihContinueB::ZINITIALISE_RECORDS: jam(); - initialiseRecordsLab(signal, signal->theData[1]); + initialiseRecordsLab(signal, + signal->theData[1], + signal->theData[2], + signal->theData[3]); return; break; case DihContinueB::ZSTART_PERMREQ_AGAIN: @@ -1023,17 +1017,30 @@ void Dbdih::execGETGCIREQ(Signal* signal) sendSignal(userRef, GSN_GETGCICONF, signal, 2, JBB); }//Dbdih::execGETGCIREQ() -void Dbdih::execSIZEALT_REP(Signal* signal) +void Dbdih::execREAD_CONFIG_REQ(Signal* signal) { + const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr(); + Uint32 ref = req->senderRef; + Uint32 senderData = req->senderData; + ndbrequire(req->noOfParameters == 0); + jamEntry(); - capiConnectFileSize = signal->theData[DihSizeAltReq::IND_API_CONNECT]; - cconnectFileSize = signal->theData[DihSizeAltReq::IND_CONNECT]; - cfragstoreFileSize = signal->theData[DihSizeAltReq::IND_FRAG_CONNECT]; - creplicaFileSize = signal->theData[DihSizeAltReq::IND_REPLICAS]; - ctabFileSize = signal->theData[DihSizeAltReq::IND_TABLE]; - cfileFileSize = (2 * ctabFileSize) + 2; + + const ndb_mgm_configuration_iterator * p = + theConfiguration.getOwnConfigIterator(); + ndbrequire(p != 0); + + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DIH_API_CONNECT, + &capiConnectFileSize)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DIH_CONNECT,&cconnectFileSize)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DIH_FRAG_CONNECT, + &cfragstoreFileSize)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DIH_REPLICAS, + &creplicaFileSize)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DIH_TABLE, &ctabFileSize)) + cfileFileSize = (2 * ctabFileSize) + 2; initRecords(); - initialiseRecordsLab(signal, 0); + initialiseRecordsLab(signal, 0, ref, senderData); return; }//Dbdih::execSIZEALT_REP() @@ -1158,11 +1165,8 @@ void Dbdih::execNDB_STTOR(Signal* signal) Uint32 ownNodeId = signal->theData[1]; /* OWN PROCESSOR ID*/ Uint32 phase = signal->theData[2]; /* INTERNAL START PHASE*/ Uint32 typestart = signal->theData[3]; - const Uint32 tconfig1 = signal->theData[8]; - const Uint32 tconfig2 = signal->theData[9]; cstarttype = typestart; - cstartPhase = phase; switch (phase){ @@ -1171,10 +1175,6 @@ void Dbdih::execNDB_STTOR(Signal* signal) /*----------------------------------------------------------------------*/ /* Set the delay between local checkpoints in ndb startphase 1. */ /*----------------------------------------------------------------------*/ - c_lcpState.clcpDelay = tconfig1 > 31 ? 31 : tconfig1; - - cminHotSpareNodes = tconfig2 > 2 ? 2 : tconfig2; - cownNodeId = ownNodeId; /*-----------------------------------------------------------------------*/ // Compute all static block references in this node as part of @@ -1193,8 +1193,6 @@ void Dbdih::execNDB_STTOR(Signal* signal) // Set the number of replicas, maximum is 4 replicas. // Read the ndb nodes from the configuration. /*-----------------------------------------------------------------------*/ - cnoReplicas = tconfig1 > 4 ? 4 : tconfig1; - cgcpDelay = tconfig2 > 60000 ? 60000 : (tconfig2 < 10 ? 10 : tconfig2); /*-----------------------------------------------------------------------*/ // For node restarts we will also add a request for permission @@ -1261,7 +1259,7 @@ void Dbdih::execNDB_STTOR(Signal* signal) */ StartMeReq * req = (StartMeReq*)&signal->theData[0]; req->startingRef = reference(); - req->startingVersion = NDB_VERSION; + req->startingVersion = 0; // Obsolete sendSignal(cmasterdihref, GSN_START_MEREQ, signal, StartMeReq::SignalLength, JBB); return; @@ -1623,7 +1621,8 @@ void Dbdih::execSTART_PERMREQ(Signal* signal) c_nodeStartMaster.startInfoErrorCode = 0; c_nodeStartMaster.startNode = nodeId; c_nodeStartMaster.activeState = true; - + c_nodeStartMaster.m_outstandingGsn = GSN_START_INFOREQ; + setNodeStatus(nodeId, NodeRecord::STARTING); /** * But if it's a NodeState::ST_INITIAL_NODE_RESTART @@ -1704,13 +1703,11 @@ void Dbdih::execSTART_MEREQ(Signal* signal) jamEntry(); const BlockReference Tblockref = req->startingRef; const Uint32 Tnodeid = refToNode(Tblockref); - const Uint32 TndbVersion = req->startingVersion; ndbrequire(isMaster()); ndbrequire(c_nodeStartMaster.startNode == Tnodeid); ndbrequire(getNodeStatus(Tnodeid) == NodeRecord::STARTING); - c_nodeStartMaster.ndbVersion = TndbVersion; sendSTART_RECREQ(signal, Tnodeid); }//Dbdih::execSTART_MEREQ() @@ -2011,7 +2008,6 @@ void Dbdih::execINCL_NODEREQ(Signal* signal) Uint32 retRef = signal->theData[0]; Uint32 nodeId = signal->theData[1]; Uint32 tnodeStartFailNr = signal->theData[2]; - Uint32 TndbVersion = signal->theData[3]; currentgcp = signal->theData[4]; CRASH_INSERTION(7127); cnewgcp = currentgcp; @@ -2063,7 +2059,6 @@ void Dbdih::execINCL_NODEREQ(Signal* signal) nodePtr.p->nodeStatus = NodeRecord::ALIVE; nodePtr.p->useInTransactions = true; nodePtr.p->m_inclDihLcp = true; - nodePtr.p->ndbversion = TndbVersion; removeDeadNode(nodePtr); insertAlive(nodePtr); @@ -3391,7 +3386,8 @@ void Dbdih::readGciFileLab(Signal* signal) filePtr.i = crestartInfoFile[0]; ptrCheckGuard(filePtr, cfileFileSize, fileRecord); filePtr.p->reqStatus = FileRecord::OPENING_GCP; - openFileRw(signal, filePtr); + + openFileRo(signal, filePtr); }//Dbdih::readGciFileLab() void Dbdih::openingGcpLab(Signal* signal, FileRecordPtr filePtr) @@ -3455,6 +3451,7 @@ void Dbdih::selectMasterCandidateAndSend(Signal* signal) signal->theData[0] = masterCandidateId; signal->theData[1] = gci; sendSignal(cntrlblockref, GSN_DIH_RESTARTCONF, signal, 2, JBB); + setNodeGroups(); }//Dbdih::selectMasterCandidate() /* ------------------------------------------------------------------------- */ @@ -3472,7 +3469,7 @@ void Dbdih::openingGcpErrorLab(Signal* signal, FileRecordPtr filePtr) /* --------------------------------------------------------------------- */ filePtr.i = crestartInfoFile[1]; ptrCheckGuard(filePtr, cfileFileSize, fileRecord); - openFileRw(signal, filePtr); + openFileRo(signal, filePtr); filePtr.p->reqStatus = FileRecord::OPENING_GCP; } else { jam(); @@ -3762,6 +3759,7 @@ void Dbdih::checkCopyTab(NodeRecordPtr failedNodePtr) c_COPY_TABREQ_Counter.clearWaitingFor(failedNodePtr.i); c_nodeStartMaster.wait = ZFALSE; break; + case GSN_START_INFOREQ: case GSN_START_PERMCONF: case GSN_DICTSTARTREQ: case GSN_START_MECONF: @@ -10863,6 +10861,26 @@ void Dbdih::initCommonData() c_nodeStartMaster.wait = ZFALSE; memset(&sysfileData[0], 0, sizeof(sysfileData)); + + const ndb_mgm_configuration_iterator * p = + theConfiguration.getOwnConfigIterator(); + ndbrequire(p != 0); + + c_lcpState.clcpDelay = 20; + ndb_mgm_get_int_parameter(p, CFG_DB_LCP_INTERVAL, &c_lcpState.clcpDelay); + c_lcpState.clcpDelay = c_lcpState.clcpDelay > 31 ? 31 : c_lcpState.clcpDelay; + + cminHotSpareNodes = 0; + //ndb_mgm_get_int_parameter(p, CFG_DB_MIN_HOT_SPARES, &cminHotSpareNodes); + cminHotSpareNodes = cminHotSpareNodes > 2 ? 2 : cminHotSpareNodes; + + cnoReplicas = 1; + ndb_mgm_get_int_parameter(p, CFG_DB_NO_REPLICAS, &cnoReplicas); + cnoReplicas = cnoReplicas > 4 ? 4 : cnoReplicas; + + cgcpDelay = 2000; + ndb_mgm_get_int_parameter(p, CFG_DB_GCP_INTERVAL, &cgcpDelay); + cgcpDelay = cgcpDelay > 60000 ? 60000 : (cgcpDelay < 10 ? 10 : cgcpDelay); }//Dbdih::initCommonData() void Dbdih::initFragstore(FragmentstorePtr fragPtr) @@ -10901,7 +10919,6 @@ void Dbdih::initNodeState(NodeRecordPtr nodePtr) nodePtr.p->nodeStatus = NodeRecord::NOT_IN_CLUSTER; nodePtr.p->useInTransactions = false; nodePtr.p->copyCompleted = false; - nodePtr.p->ndbversion = 0xffff; }//Dbdih::initNodeState() /*************************************************************************/ @@ -11070,44 +11087,43 @@ void Dbdih::initTableFile(TabRecordPtr tabPtr) /* --------------------------------------------------------------------- */ }//Dbdih::initTableFile() -void Dbdih::initialiseRecordsLab(Signal* signal, Uint32 stepNo) +void Dbdih::initialiseRecordsLab(Signal* signal, + Uint32 stepNo, Uint32 retRef, Uint32 retData) { switch (stepNo) { case 0: jam(); initCommonData(); break; - case 1: - { - ApiConnectRecordPtr apiConnectptr; - jam(); - /******** INTIALIZING API CONNECT RECORDS ********/ - for (apiConnectptr.i = 0; apiConnectptr.i < capiConnectFileSize; apiConnectptr.i++) { - ptrAss(apiConnectptr, apiConnectRecord); - apiConnectptr.p->nextApi = RNIL; - }//for - jam(); - break; - } - case 2: - { - ConnectRecordPtr connectPtr; - jam(); - /****** CONNECT ******/ - for (connectPtr.i = 0; connectPtr.i < cconnectFileSize; connectPtr.i++) { - ptrAss(connectPtr, connectRecord); - connectPtr.p->userpointer = RNIL; - connectPtr.p->userblockref = ZNIL; - connectPtr.p->connectState = ConnectRecord::FREE; - connectPtr.p->table = RNIL; - connectPtr.p->nfConnect = connectPtr.i + 1; - }//for - connectPtr.i = cconnectFileSize - 1; + case 1:{ + ApiConnectRecordPtr apiConnectptr; + jam(); + /******** INTIALIZING API CONNECT RECORDS ********/ + for (apiConnectptr.i = 0; apiConnectptr.i < capiConnectFileSize; apiConnectptr.i++) { + ptrAss(apiConnectptr, apiConnectRecord); + apiConnectptr.p->nextApi = RNIL; + }//for + jam(); + break; + } + case 2:{ + ConnectRecordPtr connectPtr; + jam(); + /****** CONNECT ******/ + for (connectPtr.i = 0; connectPtr.i < cconnectFileSize; connectPtr.i++) { ptrAss(connectPtr, connectRecord); - connectPtr.p->nfConnect = RNIL; - cfirstconnect = 0; - break; - } + connectPtr.p->userpointer = RNIL; + connectPtr.p->userblockref = ZNIL; + connectPtr.p->connectState = ConnectRecord::FREE; + connectPtr.p->table = RNIL; + connectPtr.p->nfConnect = connectPtr.i + 1; + }//for + connectPtr.i = cconnectFileSize - 1; + ptrAss(connectPtr, connectRecord); + connectPtr.p->nfConnect = RNIL; + cfirstconnect = 0; + break; + } case 3: { FileRecordPtr filePtr; @@ -11208,8 +11224,12 @@ void Dbdih::initialiseRecordsLab(Signal* signal, Uint32 stepNo) initTakeOver(takeOverPtr); releaseTakeOver(takeOverPtr.i); }//for - signal->theData[0] = DBDIH_REF; - sendSignal(CMVMI_REF, GSN_SIZEALT_ACK, signal, 2, JBB); + + ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend(); + conf->senderRef = reference(); + conf->senderData = retData; + sendSignal(retRef, GSN_READ_CONFIG_CONF, signal, + ReadConfigConf::SignalLength, JBB); return; break; } @@ -11218,12 +11238,14 @@ void Dbdih::initialiseRecordsLab(Signal* signal, Uint32 stepNo) break; }//switch jam(); - /* ------------------------------------------------------------------------- */ - /* SEND REAL-TIME BREAK DURING INIT OF VARIABLES DURING SYSTEM RESTART. */ - /* ------------------------------------------------------------------------- */ + /* ---------------------------------------------------------------------- */ + /* SEND REAL-TIME BREAK DURING INIT OF VARIABLES DURING SYSTEM RESTART. */ + /* ---------------------------------------------------------------------- */ signal->theData[0] = DihContinueB::ZINITIALISE_RECORDS; signal->theData[1] = stepNo + 1; - sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB); + signal->theData[2] = retRef; + signal->theData[3] = retData; + sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB); }//Dbdih::initialiseRecordsLab() /*************************************************************************/ @@ -11512,8 +11534,6 @@ void Dbdih::makePrnList(ReadNodesConf * readNodes, Uint32 nodeArray[]) nodePtr.p->nodeStatus = NodeRecord::DEAD; insertDeadNode(nodePtr); }//if - nodePtr.p->ndbversion = readNodes->getVersionId(nodePtr.i, - readNodes->theVersionIds); }//for }//Dbdih::makePrnList() @@ -11563,7 +11583,19 @@ void Dbdih::openFileRw(Signal* signal, FileRecordPtr filePtr) signal->theData[3] = filePtr.p->fileName[1]; signal->theData[4] = filePtr.p->fileName[2]; signal->theData[5] = filePtr.p->fileName[3]; - signal->theData[6] = ZOPEN_READ_WRITE; + signal->theData[6] = FsOpenReq::OM_READWRITE; + sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, 7, JBA); +}//Dbdih::openFileRw() + +void Dbdih::openFileRo(Signal* signal, FileRecordPtr filePtr) +{ + signal->theData[0] = reference(); + signal->theData[1] = filePtr.i; + signal->theData[2] = filePtr.p->fileName[0]; + signal->theData[3] = filePtr.p->fileName[1]; + signal->theData[4] = filePtr.p->fileName[2]; + signal->theData[5] = filePtr.p->fileName[3]; + signal->theData[6] = FsOpenReq::OM_READONLY; sendSignal(NDBFS_REF, GSN_FSOPENREQ, signal, 7, JBA); }//Dbdih::openFileRw() @@ -12502,7 +12534,10 @@ void Dbdih::setNodeGroups() }//for for (sngNodeptr.i = 1; sngNodeptr.i < MAX_NDB_NODES; sngNodeptr.i++) { ptrAss(sngNodeptr, nodeRecord); - switch (sngNodeptr.p->activeStatus) { + Sysfile::ActiveStatus s = + (Sysfile::ActiveStatus)Sysfile::getNodeStatus(sngNodeptr.i, + SYSFILE->nodeStatus); + switch (s){ case Sysfile::NS_Active: case Sysfile::NS_ActiveMissed_1: case Sysfile::NS_ActiveMissed_2: @@ -12911,8 +12946,7 @@ Dbdih::execDUMP_STATE_ORD(Signal* signal) cnoHotSpare, c_nodeStartMaster.startNode, c_nodeStartMaster.wait); }//if if (signal->theData[0] == 7007) { - infoEvent("c_nodeStartMaster.failNr = %d, c_nodeStartMaster.ndbVersion = %d", - c_nodeStartMaster.failNr, c_nodeStartMaster.ndbVersion); + infoEvent("c_nodeStartMaster.failNr = %d", c_nodeStartMaster.failNr); infoEvent("c_nodeStartMaster.startInfoErrorCode = %d", c_nodeStartMaster.startInfoErrorCode); infoEvent("c_nodeStartMaster.blockLcp = %d, c_nodeStartMaster.blockGcp = %d", @@ -13391,7 +13425,7 @@ Dbdih::execNDB_TAMPER(Signal* signal) }//Dbdih::execNDB_TAMPER() void Dbdih::execSET_VAR_REQ(Signal* signal) { - +#if 0 SetVarReq* const setVarReq = (SetVarReq*)&signal->theData[0]; ConfigParamId var = setVarReq->variable(); int val = setVarReq->value(); @@ -13411,6 +13445,7 @@ void Dbdih::execSET_VAR_REQ(Signal* signal) { default: sendSignal(CMVMI_REF, GSN_SET_VAR_REF, signal, 1, JBB); } // switch +#endif } void Dbdih::execBLOCK_COMMIT_ORD(Signal* signal){ diff --git a/ndb/src/kernel/blocks/dblqh/Dblqh.hpp b/ndb/src/kernel/blocks/dblqh/Dblqh.hpp index ed1c0414d18..824f74c59af 100644 --- a/ndb/src/kernel/blocks/dblqh/Dblqh.hpp +++ b/ndb/src/kernel/blocks/dblqh/Dblqh.hpp @@ -2109,7 +2109,7 @@ private: void execCHECK_LCP_STOP(Signal* signal); void execSEND_PACKED(Signal* signal); void execTUP_ATTRINFO(Signal* signal); - void execSIZEALT_REP(Signal* signal); + void execREAD_CONFIG_REQ(Signal* signal); void execLQHFRAGREQ(Signal* signal); void execLQHADDATTREQ(Signal* signal); void execTUP_ADD_ATTCONF(Signal* signal); @@ -2328,7 +2328,6 @@ private: void initialiseLogPage(Signal* signal); void initialiseLogPart(Signal* signal); void initialisePageRef(Signal* signal); - void sendInitialiseRecords(Signal* signal, Uint32 data); void initialiseScanrec(Signal* signal); void initialiseTabrec(Signal* signal); void initialiseTcrec(Signal* signal); @@ -2462,7 +2461,6 @@ private: void closeCopyRequestLab(Signal* signal); void closeScanRequestLab(Signal* signal); void scanTcConnectLab(Signal* signal, Uint32 startTcCon, Uint32 fragId); - void returnInitialiseRecordsLab(Signal* signal); void initGcpRecLab(Signal* signal); void prepareContinueAfterBlockedLab(Signal* signal); void commitContinueAfterBlockedLab(Signal* signal); @@ -2479,7 +2477,7 @@ private: void accFragRefLab(Signal* signal); void rwConcludedLab(Signal* signal); void sendsttorryLab(Signal* signal); - void initialiseRecordsLab(Signal* signal, Uint32 data); + void initialiseRecordsLab(Signal* signal, Uint32 data, Uint32, Uint32); void startphase2Lab(Signal* signal, Uint32 config); void startphase3Lab(Signal* signal); void startphase4Lab(Signal* signal); diff --git a/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp b/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp index cb1698ec8c0..d5f40ec143c 100644 --- a/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp +++ b/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp @@ -220,7 +220,7 @@ Dblqh::Dblqh(const class Configuration & conf): addRecSignal(GSN_CHECK_LCP_STOP, &Dblqh::execCHECK_LCP_STOP); addRecSignal(GSN_SEND_PACKED, &Dblqh::execSEND_PACKED); addRecSignal(GSN_TUP_ATTRINFO, &Dblqh::execTUP_ATTRINFO); - addRecSignal(GSN_SIZEALT_REP, &Dblqh::execSIZEALT_REP); + addRecSignal(GSN_READ_CONFIG_REQ, &Dblqh::execREAD_CONFIG_REQ, true); addRecSignal(GSN_LQHFRAGREQ, &Dblqh::execLQHFRAGREQ); addRecSignal(GSN_LQHADDATTREQ, &Dblqh::execLQHADDATTREQ); addRecSignal(GSN_TUP_ADD_ATTCONF, &Dblqh::execTUP_ADD_ATTCONF); diff --git a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp index 6cc72d2f0ab..613f9ccea11 100644 --- a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp +++ b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp @@ -32,14 +32,12 @@ #include <signaldata/GCPSave.hpp> #include <signaldata/TcKeyRef.hpp> #include <signaldata/LqhKey.hpp> -#include <signaldata/LqhSizeAltReq.hpp> #include <signaldata/NextScan.hpp> #include <signaldata/NFCompleteRep.hpp> #include <signaldata/NodeFailRep.hpp> #include <signaldata/ReadNodesConf.hpp> #include <signaldata/RelTabMem.hpp> #include <signaldata/ScanFrag.hpp> -#include <signaldata/SetVarReq.hpp> #include <signaldata/SrFragidConf.hpp> #include <signaldata/StartFragReq.hpp> #include <signaldata/StartRec.hpp> @@ -333,7 +331,7 @@ void Dblqh::execCONTINUEB(Signal* signal) break; case ZINITIALISE_RECORDS: jam(); - initialiseRecordsLab(signal, data0); + initialiseRecordsLab(signal, data0, data2, signal->theData[4]); return; break; case ZINIT_GCP_REC: @@ -467,7 +465,6 @@ void Dblqh::execNDB_STTOR(Signal* signal) Uint32 ownNodeId = signal->theData[1]; /* START PHASE*/ cstartPhase = signal->theData[2]; /* MY NODE ID */ cstartType = signal->theData[3]; /* START TYPE */ - Uint32 config1 = signal->theData[10]; /* CONFIG INFO LQH */ switch (cstartPhase) { case ZSTART_PHASE1: @@ -488,7 +485,7 @@ void Dblqh::execNDB_STTOR(Signal* signal) // Dont setAPIVersion LqhKeyReq::setMarkerFlag(preComputedRequestInfoMask, 1); //preComputedRequestInfoMask = 0x003d7fff; - startphase1Lab(signal, config1, ownNodeId); + startphase1Lab(signal, /* dummy */ ~0, ownNodeId); signal->theData[0] = ZOPERATION_EVENT_REP; signal->theData[1] = 1; @@ -497,7 +494,7 @@ void Dblqh::execNDB_STTOR(Signal* signal) break; case ZSTART_PHASE2: jam(); - startphase2Lab(signal, config1); + startphase2Lab(signal, /* dummy */ ~0); return; break; case ZSTART_PHASE3: @@ -539,17 +536,12 @@ void Dblqh::sttorStartphase1Lab(Signal* signal) /* */ /* INITIATE ALL RECORDS WITHIN THE BLOCK */ /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ -void Dblqh::startphase1Lab(Signal* signal, Uint32 config, Uint32 ownNodeId) +void Dblqh::startphase1Lab(Signal* signal, Uint32 _dummy, Uint32 ownNodeId) { UintR Ti; HostRecordPtr ThostPtr; /* ------- INITIATE ALL RECORDS ------- */ - if (config == 0) { - jam(); - config = 1; - }//if - cnoLogFiles = config; cownNodeid = ownNodeId; caccBlockref = calcAccBlockRef (cownNodeid); ctupBlockref = calcTupBlockRef (cownNodeid); @@ -576,15 +568,8 @@ void Dblqh::startphase1Lab(Signal* signal, Uint32 config, Uint32 ownNodeId) /* EVERY CONNECTION RECORD IN LQH IS ASSIGNED TO ONE ACC CONNECTION RECORD */ /* AND ONE TUP CONNECTION RECORD. */ /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ -void Dblqh::startphase2Lab(Signal* signal, Uint32 config) +void Dblqh::startphase2Lab(Signal* signal, Uint32 _dummy) { - if (config == 0) { - jam(); - config = 1; - } else if (config > 4) { - jam(); - config = 4; - }//if cmaxWordsAtNodeRec = MAX_NO_WORDS_OUTSTANDING_COPY_FRAGMENT; /* -- ACC AND TUP CONNECTION PROCESS -- */ tcConnectptr.i = 0; @@ -836,30 +821,38 @@ void Dblqh::execREAD_NODESREF(Signal* signal) /* *************** */ /* SIZEALT_REP > */ /* *************** */ -void Dblqh::execSIZEALT_REP(Signal* signal) +void Dblqh::execREAD_CONFIG_REQ(Signal* signal) { + const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr(); + Uint32 ref = req->senderRef; + Uint32 senderData = req->senderData; + ndbrequire(req->noOfParameters == 0); + jamEntry(); - cfragrecFileSize = signal->theData[LqhSizeAltReq::IND_FRAG]; - ctabrecFileSize = signal->theData[LqhSizeAltReq::IND_TABLE]; - ctcConnectrecFileSize = signal->theData[LqhSizeAltReq::IND_TC_CONNECT]; - clogFileFileSize = signal->theData[LqhSizeAltReq::IND_LOG_FILES]; - cscanrecFileSize = signal->theData[LqhSizeAltReq::IND_SCAN]; + + const ndb_mgm_configuration_iterator * p = + theConfiguration.getOwnConfigIterator(); + ndbrequire(p != 0); + + cnoLogFiles = 8; + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_NO_REDOLOG_FILES, + &cnoLogFiles)); + ndbrequire(cnoLogFiles > 0); + + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_LQH_FRAG, &cfragrecFileSize)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_LQH_TABLE, &ctabrecFileSize)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_LQH_TC_CONNECT, + &ctcConnectrecFileSize)); + clogFileFileSize = 4 * cnoLogFiles; + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_LQH_SCAN, &cscanrecFileSize)); cmaxAccOps = cscanrecFileSize * MAX_PARALLEL_SCANS_PER_FRAG; + initRecords(); - initialiseRecordsLab(signal, 0); + initialiseRecordsLab(signal, 0, ref, senderData); return; }//Dblqh::execSIZEALT_REP() -void Dblqh::returnInitialiseRecordsLab(Signal* signal) -{ - signal->theData[0] = DBLQH_REF; - sendSignal(CMVMI_REF, GSN_SIZEALT_ACK, signal, 2, JBB); - - - return; -}//Dblqh::returnInitialiseRecordsLab() - /* ########################################################################## */ /* ####### ADD/DELETE FRAGMENT MODULE ####### */ /* THIS MODULE IS USED BY DICTIONARY TO CREATE NEW FRAGMENTS AND DELETE */ @@ -16032,7 +16025,8 @@ void Dblqh::initialisePageRef(Signal* signal) * * TAKES CARE OF INITIATION OF ALL RECORDS IN THIS BLOCK. * ========================================================================= */ -void Dblqh::initialiseRecordsLab(Signal* signal, Uint32 data) +void Dblqh::initialiseRecordsLab(Signal* signal, Uint32 data, + Uint32 retRef, Uint32 retData) { switch (data) { case 0: @@ -16070,90 +16064,81 @@ void Dblqh::initialiseRecordsLab(Signal* signal, Uint32 data) csrExecUndoLogState = EULS_IDLE; c_lcpId = 0; cnoOfFragsCheckpointed = 0; - sendInitialiseRecords(signal, data); break; case 1: jam(); initialiseAddfragrec(signal); - sendInitialiseRecords(signal, data); break; case 2: jam(); initialiseAttrbuf(signal); - sendInitialiseRecords(signal, data); break; case 3: jam(); initialiseDatabuf(signal); - sendInitialiseRecords(signal, data); break; case 4: jam(); initialiseFragrec(signal); - sendInitialiseRecords(signal,data); break; case 5: jam(); initialiseGcprec(signal); initialiseLcpRec(signal); initialiseLcpLocrec(signal); - sendInitialiseRecords(signal, data); break; case 6: jam(); initialiseLogPage(signal); - sendInitialiseRecords(signal, data); break; case 7: jam(); initialiseLfo(signal); - sendInitialiseRecords(signal, data); break; case 8: jam(); initialiseLogFile(signal); initialiseLogPart(signal); - sendInitialiseRecords(signal, data); break; case 9: jam(); initialisePageRef(signal); - sendInitialiseRecords(signal, data); break; case 10: jam(); initialiseScanrec(signal); - sendInitialiseRecords(signal, data); break; case 11: jam(); initialiseTabrec(signal); - sendInitialiseRecords(signal, data); break; case 12: jam(); initialiseTcNodeFailRec(signal); initialiseTcrec(signal); - returnInitialiseRecordsLab(signal); + { + ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend(); + conf->senderRef = reference(); + conf->senderData = retData; + sendSignal(retRef, GSN_READ_CONFIG_CONF, signal, + ReadConfigConf::SignalLength, JBB); + } return; break; default: ndbrequire(false); break; }//switch - return; -}//Dblqh::initialiseRecordsLab() -/* -------------------------------------------------------------------------- - * SEND REAL-TIME BREAK SIGNAL DURING INITIALISATION IN SYSTEM RESTART. - * ------------------------------------------------------------------------- */ -void Dblqh::sendInitialiseRecords(Signal* signal, Uint32 data) -{ signal->theData[0] = ZINITIALISE_RECORDS; signal->theData[1] = data + 1; signal->theData[2] = 0; - sendSignal(DBLQH_REF, GSN_CONTINUEB, signal, 3, JBB); -}//Dblqh::sendInitialiseRecords() + signal->theData[3] = retRef; + signal->theData[4] = retData; + sendSignal(DBLQH_REF, GSN_CONTINUEB, signal, 5, JBB); + + return; +}//Dblqh::initialiseRecordsLab() /* ========================================================================== * ======= INITIATE TC CONNECTION RECORD ======= @@ -18020,7 +18005,7 @@ Dblqh::execDUMP_STATE_ORD(Signal* signal) void Dblqh::execSET_VAR_REQ(Signal* signal) { - +#if 0 SetVarReq* const setVarReq = (SetVarReq*)&signal->theData[0]; ConfigParamId var = setVarReq->variable(); @@ -18038,7 +18023,7 @@ void Dblqh::execSET_VAR_REQ(Signal* signal) default: sendSignal(CMVMI_REF, GSN_SET_VAR_REF, signal, 1, JBB); } // switch - +#endif }//execSET_VAR_REQ() diff --git a/ndb/src/kernel/blocks/dbtc/Dbtc.hpp b/ndb/src/kernel/blocks/dbtc/Dbtc.hpp index 3fc79120942..c87712e1887 100644 --- a/ndb/src/kernel/blocks/dbtc/Dbtc.hpp +++ b/ndb/src/kernel/blocks/dbtc/Dbtc.hpp @@ -955,7 +955,6 @@ public: LqhTransState lqhTransStatus; TakeOverState takeOverStatus; bool inPackedList; - UintR ndbVersion; UintR noOfPackedWordsLqh; UintR packedWordsLqh[26]; UintR noOfWordsTCKEYCONF; @@ -1336,7 +1335,7 @@ private: void execSCAN_TABINFO(Signal* signal); void execSCAN_FRAGCONF(Signal* signal); void execSCAN_FRAGREF(Signal* signal); - void execSIZEALT_REP(Signal* signal); + void execREAD_CONFIG_REQ(Signal* signal); void execLQH_TRANSCONF(Signal* signal); void execCOMPLETECONF(Signal* signal); void execCOMMITCONF(Signal* signal); @@ -1496,7 +1495,6 @@ private: AttrbufRecord * const regAttrPtr, UintR TBref); void sendContinueTimeOutControl(Signal* signal, Uint32 TapiConPtr); - void sendInitialiseRecords(Signal* signal, UintR Tnext); void sendKeyinfo(Signal* signal, BlockReference TBRef, Uint32 len); void sendlqhkeyreq(Signal* signal, BlockReference TBRef); void sendSystemError(Signal* signal); @@ -1613,7 +1611,6 @@ private: void scanCompletedLab(Signal* signal); void scanFragError(Signal* signal, Uint32 errorCode); void diverify010Lab(Signal* signal); - void returnInitialiseRecordsLab(Signal* signal); void intstartphase2x010Lab(Signal* signal); void intstartphase3x010Lab(Signal* signal); void sttorryLab(Signal* signal); @@ -1627,7 +1624,7 @@ private: void completeTransAtTakeOverDoLast(Signal* signal, UintR TtakeOverInd); void completeTransAtTakeOverDoOne(Signal* signal, UintR TtakeOverInd); void timeOutLoopStartLab(Signal* signal, Uint32 apiConnectPtr); - void initialiseRecordsLab(Signal* signal, UintR Tdata0); + void initialiseRecordsLab(Signal* signal, UintR Tdata0, Uint32, Uint32); void tckeyreq020Lab(Signal* signal); void intstartphase2x020Lab(Signal* signal); void intstartphase1x010Lab(Signal* signal); diff --git a/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp b/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp index 0982ae5bff5..61ecca513f0 100644 --- a/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp +++ b/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp @@ -182,19 +182,24 @@ Dbtc::Dbtc(const class Configuration & conf): BLOCK_CONSTRUCTOR(Dbtc); - const Properties * p = conf.getOwnProperties(); + const ndb_mgm_configuration_iterator * p = conf.getOwnConfigIterator(); ndbrequire(p != 0); Uint32 transactionBufferMemory = 0; Uint32 maxNoOfIndexes = 0, maxNoOfConcurrentIndexOperations = 0; Uint32 maxNoOfTriggers = 0, maxNoOfFiredTriggers = 0; - p->get("TransactionBufferMemory", &transactionBufferMemory); - p->get("MaxNoOfIndexes", &maxNoOfIndexes); - p->get("MaxNoOfConcurrentIndexOperations", &maxNoOfConcurrentIndexOperations); - p->get("MaxNoOfTriggers", &maxNoOfTriggers); - p->get("MaxNoOfFiredTriggers", &maxNoOfFiredTriggers); - + ndb_mgm_get_int_parameter(p, CFG_DB_TRANS_BUFFER_MEM, + &transactionBufferMemory); + ndb_mgm_get_int_parameter(p, CFG_DB_NO_INDEXES, + &maxNoOfIndexes); + ndb_mgm_get_int_parameter(p, CFG_DB_NO_INDEX_OPS, + &maxNoOfConcurrentIndexOperations); + ndb_mgm_get_int_parameter(p, CFG_DB_NO_TRIGGERS, + &maxNoOfTriggers); + ndb_mgm_get_int_parameter(p, CFG_DB_NO_TRIGGER_OPS, + &maxNoOfFiredTriggers); + c_transactionBufferSpace = transactionBufferMemory / AttributeBuffer::getSegmentSize(); c_maxNumberOfIndexes = maxNoOfIndexes; @@ -247,7 +252,7 @@ Dbtc::Dbtc(const class Configuration & conf): addRecSignal(GSN_SCAN_TABREQ, &Dbtc::execSCAN_TABREQ); addRecSignal(GSN_SCAN_FRAGCONF, &Dbtc::execSCAN_FRAGCONF); addRecSignal(GSN_SCAN_FRAGREF, &Dbtc::execSCAN_FRAGREF); - addRecSignal(GSN_SIZEALT_REP, &Dbtc::execSIZEALT_REP); + addRecSignal(GSN_READ_CONFIG_REQ, &Dbtc::execREAD_CONFIG_REQ, true); addRecSignal(GSN_LQH_TRANSCONF, &Dbtc::execLQH_TRANSCONF); addRecSignal(GSN_COMPLETECONF, &Dbtc::execCOMPLETECONF); addRecSignal(GSN_COMMITCONF, &Dbtc::execCOMMITCONF); diff --git a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp index feb5712d9d3..1c916c2754c 100644 --- a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp +++ b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp @@ -29,8 +29,6 @@ #include <signaldata/AttrInfo.hpp> #include <signaldata/TransIdAI.hpp> #include <signaldata/TcRollbackRep.hpp> -#include <signaldata/TcSizeAltReq.hpp> -#include <signaldata/SetVarReq.hpp> #include <signaldata/NodeFailRep.hpp> #include <signaldata/ReadNodesConf.hpp> #include <signaldata/NFCompleteRep.hpp> @@ -108,6 +106,7 @@ void Dbtc::execCONTINUEB(Signal* signal) tcase = signal->theData[0]; UintR Tdata0 = signal->theData[1]; UintR Tdata1 = signal->theData[2]; + UintR Tdata2 = signal->theData[3]; switch (tcase) { case TcContinueB::ZRETURN_FROM_QUEUED_DELIVERY: jam(); @@ -138,7 +137,7 @@ void Dbtc::execCONTINUEB(Signal* signal) return; case TcContinueB::ZINITIALISE_RECORDS: jam(); - initialiseRecordsLab(signal, Tdata0); + initialiseRecordsLab(signal, Tdata0, Tdata2, signal->theData[4]); return; case TcContinueB::ZSEND_COMMIT_LOOP: jam(); @@ -497,15 +496,30 @@ void Dbtc::execALTER_TAB_REQ(Signal * signal) /* ***************************************************************************/ /* START / RESTART */ /* ***************************************************************************/ -void Dbtc::execSIZEALT_REP(Signal* signal) +void Dbtc::execREAD_CONFIG_REQ(Signal* signal) { + const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr(); + Uint32 ref = req->senderRef; + Uint32 senderData = req->senderData; + ndbrequire(req->noOfParameters == 0); + jamEntry(); - tblockref = signal->theData[TcSizeAltReq::IND_BLOCK_REF]; - const UintR apiConnect = signal->theData[TcSizeAltReq::IND_API_CONNECT]; - const UintR tcConnect = signal->theData[TcSizeAltReq::IND_TC_CONNECT]; - const UintR tables = signal->theData[TcSizeAltReq::IND_TABLE]; - const UintR localScan = signal->theData[TcSizeAltReq::IND_LOCAL_SCAN]; - const UintR tcScan = signal->theData[TcSizeAltReq::IND_TC_SCAN]; + + const ndb_mgm_configuration_iterator * p = + theConfiguration.getOwnConfigIterator(); + ndbrequire(p != 0); + + UintR apiConnect; + UintR tcConnect; + UintR tables; + UintR localScan; + UintR tcScan; + + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TC_API_CONNECT, &apiConnect)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TC_TC_CONNECT, &tcConnect)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TC_TABLE, &tables)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TC_LOCAL_SCAN, &localScan)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TC_SCAN, &tcScan)); ccacheFilesize = (apiConnect/3) + 1; capiConnectFilesize = apiConnect; @@ -516,14 +530,22 @@ void Dbtc::execSIZEALT_REP(Signal* signal) cscanFragrecFileSize = localScan; initRecords(); - initialiseRecordsLab(signal, (UintR)0); -}//Dbtc::execSIZEALT_REP() + initialiseRecordsLab(signal, 0, ref, senderData); -void Dbtc::returnInitialiseRecordsLab(Signal* signal) -{ - signal->theData[0] = DBTC_REF; - sendSignal(CMVMI_REF, GSN_SIZEALT_ACK, signal, 2, JBB); -}//Dbtc::returnInitialiseRecordsLab() + Uint32 val = 3000; + ndb_mgm_get_int_parameter(p, CFG_DB_TRANSACTION_DEADLOCK_TIMEOUT, &val); + set_timeout_value(val); + + val = 3000; + ndb_mgm_get_int_parameter(p, CFG_DB_TRANSACTION_INACTIVE_TIMEOUT, &val); + set_appl_timeout_value(val); + + val = 1; + //ndb_mgm_get_int_parameter(p, CFG_DB_PARALLEL_TRANSACTION_TAKEOVER, &val); + set_no_parallel_takeover(val); + + ctimeOutCheckDelay = 50; // 500ms +}//Dbtc::execSIZEALT_REP() void Dbtc::execSTTOR(Signal* signal) { @@ -568,19 +590,13 @@ void Dbtc::execNDB_STTOR(Signal* signal) tnodeid = signal->theData[1]; tndbstartphase = signal->theData[2]; /* START PHASE */ tstarttype = signal->theData[3]; /* START TYPE */ - Uint32 config1 = signal->theData[12]; /* CONFIG INFO TC */ - Uint32 config2 = signal->theData[13]; /* CONFIG INFO TC */ switch (tndbstartphase) { case ZINTSPH1: jam(); - ctimeOutCheckDelay = 50; // 500ms - set_timeout_value(config1); - set_no_parallel_takeover(config2); intstartphase1x010Lab(signal); return; case ZINTSPH2: jam(); - set_appl_timeout_value(config2); intstartphase2x010Lab(signal); return; case ZINTSPH3: @@ -747,10 +763,8 @@ void Dbtc::execREAD_NODESCONF(Signal* signal) if (NodeBitmask::get(readNodes->allNodes, i)) { hostptr.i = i; ptrCheckGuard(hostptr, chostFilesize, hostRecord); - + hostptr.p->takeOverStatus = TOS_IDLE; - hostptr.p->ndbVersion = ReadNodesConf::getVersionId - (i, readNodes->theVersionIds); if (NodeBitmask::get(readNodes->inactiveNodes, i)) { jam(); @@ -10032,7 +10046,6 @@ void Dbtc::inithost(Signal* signal) hostptr.p->inPackedList = false; hostptr.p->takeOverStatus = TOS_NOT_DEFINED; hostptr.p->lqhTransStatus = LTS_IDLE; - hostptr.p->ndbVersion = ZNIL; hostptr.p->noOfWordsTCKEYCONF = 0; hostptr.p->noOfWordsTCINDXCONF = 0; hostptr.p->noOfPackedWordsLqh = 0; @@ -10040,7 +10053,8 @@ void Dbtc::inithost(Signal* signal) }//for }//Dbtc::inithost() -void Dbtc::initialiseRecordsLab(Signal* signal, UintR Tdata0) +void Dbtc::initialiseRecordsLab(Signal* signal, UintR Tdata0, + Uint32 retRef, Uint32 retData) { switch (Tdata0) { case 0: @@ -10090,7 +10104,14 @@ void Dbtc::initialiseRecordsLab(Signal* signal, UintR Tdata0) case 11: jam(); initTcFail(signal); - returnInitialiseRecordsLab(signal); + + { + ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend(); + conf->senderRef = reference(); + conf->senderData = retData; + sendSignal(retRef, GSN_READ_CONFIG_CONF, signal, + ReadConfigConf::SignalLength, JBB); + } return; break; default: @@ -10099,10 +10120,19 @@ void Dbtc::initialiseRecordsLab(Signal* signal, UintR Tdata0) return; break; }//switch - sendInitialiseRecords(signal, (Tdata0 + 1)); - return; -}//Dbtc::initialiseRecordsLab() + signal->theData[0] = TcContinueB::ZINITIALISE_RECORDS; + signal->theData[1] = Tdata0 + 1; + signal->theData[2] = 0; + signal->theData[3] = retRef; + signal->theData[4] = retData; + sendSignal(DBTC_REF, GSN_CONTINUEB, signal, 5, JBB); +} + +/* ========================================================================= */ +/* ======= INITIALISE_SCANREC ======= */ +/* */ +/* ========================================================================= */ void Dbtc::initialiseScanrec(Signal* signal) { ndbrequire(cscanrecFileSize > 0); @@ -10529,18 +10559,6 @@ void Dbtc::sendContinueTimeOutControl(Signal* signal, Uint32 TapiConPtr) sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB); }//Dbtc::sendContinueTimeOutControl() -/* ------------------------------------------------------------------------- - * SEND REAL-TIME BREAK DURING INITIALISATION OF VARIABLES DURING - * SYSTEM RESTART. - * ------------------------------------------------------------------------- */ -void Dbtc::sendInitialiseRecords(Signal* signal, UintR Tnext) -{ - signal->theData[0] = TcContinueB::ZINITIALISE_RECORDS; - signal->theData[1] = Tnext; - signal->theData[2] = 0; - sendSignal(DBTC_REF, GSN_CONTINUEB, signal, 3, JBB); -}//Dbtc::sendInitialiseRecords() - void Dbtc::sendKeyinfo(Signal* signal, BlockReference TBRef, Uint32 len) { signal->theData[0] = tcConnectptr.i; @@ -10861,7 +10879,7 @@ Dbtc::execDUMP_STATE_ORD(Signal* signal) void Dbtc::execSET_VAR_REQ(Signal* signal) { - +#if 0 SetVarReq* const setVarReq = (SetVarReq*)&signal->theData[0]; ConfigParamId var = setVarReq->variable(); int val = setVarReq->value(); @@ -10886,7 +10904,7 @@ void Dbtc::execSET_VAR_REQ(Signal* signal) default: sendSignal(CMVMI_REF, GSN_SET_VAR_REF, signal, 1, JBB); } // switch - +#endif } void Dbtc::execABORT_ALL_REQ(Signal* signal) @@ -10933,7 +10951,6 @@ void Dbtc::execABORT_ALL_REQ(Signal* signal) c_abortRec.oldTimeOutValue = ctimeOutValue; ctimeOutValue = 0; - const Uint32 sleepTime = (2 * 10 * ctimeOutCheckDelay + 199) / 200; checkAbortAllTimeout(signal, (sleepTime == 0 ? 1 : sleepTime)); diff --git a/ndb/src/kernel/blocks/dbtup/Dbtup.hpp b/ndb/src/kernel/blocks/dbtup/Dbtup.hpp index 053b853fa82..c09c8984ce2 100644 --- a/ndb/src/kernel/blocks/dbtup/Dbtup.hpp +++ b/ndb/src/kernel/blocks/dbtup/Dbtup.hpp @@ -1029,7 +1029,7 @@ private: void execFSREADCONF(Signal* signal); void execFSREADREF(Signal* signal); void execNDB_STTOR(Signal* signal); - void execSIZEALT_REP(Signal* signal); + void execREAD_CONFIG_REQ(Signal* signal); void execSET_VAR_REQ(Signal* signal); void execDROP_TAB_REQ(Signal* signal); void execALTER_TAB_REQ(Signal* signal); @@ -1900,7 +1900,7 @@ private: void releaseTabDescr(Tablerec* const regTabPtr); void getFragmentrec(FragrecordPtr& regFragPtr, Uint32 fragId, Tablerec* const regTabPtr); - void initialiseRecordsLab(Signal* signal, Uint32 switchData); + void initialiseRecordsLab(Signal* signal, Uint32 switchData, Uint32, Uint32); void initializeAttrbufrec(); void initializeCheckpointInfoRec(); void initializeDiskBufferSegmentRecord(); diff --git a/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp b/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp index 982e1b8df24..095ea412701 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp @@ -27,10 +27,8 @@ #include <signaldata/FsConf.hpp> #include <signaldata/FsRef.hpp> #include <signaldata/FsRemoveReq.hpp> -#include <signaldata/SetVarReq.hpp> #include <signaldata/TupCommit.hpp> #include <signaldata/TupKey.hpp> -#include <signaldata/TupSizeAltReq.hpp> #include <signaldata/DropTab.hpp> #include <new> @@ -118,7 +116,7 @@ Dbtup::Dbtup(const class Configuration & conf) addRecSignal(GSN_FSREADCONF, &Dbtup::execFSREADCONF); addRecSignal(GSN_FSREADREF, &Dbtup::execFSREADREF); addRecSignal(GSN_NDB_STTOR, &Dbtup::execNDB_STTOR); - addRecSignal(GSN_SIZEALT_REP, &Dbtup::execSIZEALT_REP); + addRecSignal(GSN_READ_CONFIG_REQ, &Dbtup::execREAD_CONFIG_REQ, true); addRecSignal(GSN_SET_VAR_REQ, &Dbtup::execSET_VAR_REQ); // Trigger Signals @@ -538,7 +536,8 @@ void Dbtup::execCONTINUEB(Signal* signal) break; case ZINITIALISE_RECORDS: ljam(); - initialiseRecordsLab(signal, dataPtr); + initialiseRecordsLab(signal, dataPtr, + signal->theData[2], signal->theData[3]); break; case ZREL_FRAG: ljam(); @@ -610,22 +609,37 @@ void Dbtup::execSTTOR(Signal* signal) // SIZE_ALTREP INITIALIZE DATA STRUCTURES, FILES AND DS VARIABLES, GET READY FOR EXTERNAL // CONNECTIONS. /************************************************************************************************/ -void Dbtup::execSIZEALT_REP(Signal* signal) +void Dbtup::execREAD_CONFIG_REQ(Signal* signal) { - BlockReference tsizealtBlockRef; - + const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr(); + Uint32 ref = req->senderRef; + Uint32 senderData = req->senderData; + ndbrequire(req->noOfParameters == 0); + ljamEntry(); - tsizealtBlockRef = signal->theData[TupSizeAltReq::IND_BLOCK_REF]; - cnoOfFragrec = signal->theData[TupSizeAltReq::IND_FRAG]; - cnoOfOprec = signal->theData[TupSizeAltReq::IND_OP_RECS]; + + const ndb_mgm_configuration_iterator * p = + theConfiguration.getOwnConfigIterator(); + ndbrequire(p != 0); + + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_FRAG, &cnoOfFragrec)); + + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_OP_RECS, &cnoOfOprec)); + // MemorySpaceTuples is specified in 8k pages, divide by 4 for 32k pages - Uint64 noOfWords = (signal->theData[TupSizeAltReq::IND_PAGE] * 2048) + (ZWORDS_ON_PAGE - 1); - Uint64 noOfPages = noOfWords / (Uint64)ZWORDS_ON_PAGE; - cnoOfPage = (Uint32)noOfPages; - initPageRangeSize(signal->theData[TupSizeAltReq::IND_PAGE_RANGE]); - cnoOfTablerec = signal->theData[TupSizeAltReq::IND_TABLE]; - cnoOfTabDescrRec = signal->theData[TupSizeAltReq::IND_TABLE_DESC]; - Uint32 noOfStoredProc = signal->theData[TupSizeAltReq::IND_STORED_PROC]; + Uint32 tmp; + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_PAGE, &tmp)); + Uint64 pages = (tmp * 2048 + (ZWORDS_ON_PAGE - 1))/ (Uint64)ZWORDS_ON_PAGE; + cnoOfPage = (Uint32)pages; + + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_PAGE_RANGE, &tmp)); + initPageRangeSize(tmp); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_TABLE, &cnoOfTablerec)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_TABLE_DESC, + &cnoOfTabDescrRec)); + Uint32 noOfStoredProc; + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_STORED_PROC, + &noOfStoredProc)); cnoOfTabDescrRec = (cnoOfTabDescrRec & 0xFFFFFFF0) + 16; c_storedProcPool.setSize(noOfStoredProc); @@ -639,7 +653,14 @@ void Dbtup::execSIZEALT_REP(Signal* signal) cnoOfLocalLogInfo = 0; cnoFreeUndoSeg = 0; - initialiseRecordsLab(signal, 0); + initialiseRecordsLab(signal, 0, ref, senderData); + + clblPagesPerTick = 50; + //ndb_mgm_get_int_parameter(p, CFG_DB_, &clblPagesPerTick); + + clblPagesPerTickAfterSr = 50; + //ndb_mgm_get_int_parameter(p, CFG_DB_, &clblPagesPerTickAfterSr); + }//Dbtup::execSIZEALT_REP() void Dbtup::initRecords() @@ -732,7 +753,8 @@ void Dbtup::initRecords() bat[2].bits.v = 5; }//Dbtup::initRecords() -void Dbtup::initialiseRecordsLab(Signal* signal, Uint32 switchData) +void Dbtup::initialiseRecordsLab(Signal* signal, Uint32 switchData, + Uint32 retRef, Uint32 retData) { switch (switchData) { case 0: @@ -794,19 +816,24 @@ void Dbtup::initialiseRecordsLab(Signal* signal, Uint32 switchData) case 14: ljam(); initializeRestartInfoRec(); - signal->theData[0] = cownref; - sendSignal(CMVMI_REF, GSN_SIZEALT_ACK, signal, 1, JBB); + + { + ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend(); + conf->senderRef = reference(); + conf->senderData = retData; + sendSignal(retRef, GSN_READ_CONFIG_CONF, signal, + ReadConfigConf::SignalLength, JBB); + } return; default: ndbrequire(false); break; }//switch -/******************************************************************************/ -/* SEND REAL-TIME BREAK DURING INITIALISATION OF VARIABLES IN SYSTEM RESTART */ -/******************************************************************************/ signal->theData[0] = ZINITIALISE_RECORDS; signal->theData[1] = switchData + 1; - sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB); + signal->theData[2] = retRef; + signal->theData[3] = retData; + sendSignal(reference(), GSN_CONTINUEB, signal, 4, JBB); return; }//Dbtup::initialiseRecordsLab() @@ -816,8 +843,6 @@ void Dbtup::execNDB_STTOR(Signal* signal) cndbcntrRef = signal->theData[0]; Uint32 ownNodeId = signal->theData[1]; Uint32 startPhase = signal->theData[2]; - Uint32 data1 = signal->theData[14]; - Uint32 data2 = signal->theData[15]; switch (startPhase) { case ZSTARTPHASE1: ljam(); @@ -829,7 +854,7 @@ void Dbtup::execNDB_STTOR(Signal* signal) break; case ZSTARTPHASE3: ljam(); - startphase3Lab(signal, data1, data2); + startphase3Lab(signal, ~0, ~0); break; case ZSTARTPHASE4: ljam(); @@ -856,20 +881,6 @@ void Dbtup::execNDB_STTOR(Signal* signal) void Dbtup::startphase3Lab(Signal* signal, Uint32 config1, Uint32 config2) { - if (config1 > 0) { - ljam(); - clblPagesPerTick = config1; - } else { - ljam(); - clblPagesPerTick = 1; - }//if - if (config2 > 0) { - ljam(); - clblPagesPerTickAfterSr = config2; - } else { - ljam(); - clblPagesPerTickAfterSr = 1; - }//if clblPageCounter = clblPagesPerTick; signal->theData[0] = ZLOAD_BAL_LCP_TIMER; sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 100, 1); @@ -1291,6 +1302,7 @@ void Dbtup::seizePendingFileOpenInfoRecord(PendingFileOpenInfoPtr& pfoiPtr) void Dbtup::execSET_VAR_REQ(Signal* signal) { +#if 0 SetVarReq* const setVarReq = (SetVarReq*)signal->getDataPtrSend(); ConfigParamId var = setVarReq->variable(); int val = setVarReq->value(); @@ -1310,7 +1322,7 @@ void Dbtup::execSET_VAR_REQ(Signal* signal) default: sendSignal(CMVMI_REF, GSN_SET_VAR_REF, signal, 1, JBB); } // switch - +#endif }//execSET_VAR_REQ() diff --git a/ndb/src/kernel/blocks/dbtux/Dbtux.hpp b/ndb/src/kernel/blocks/dbtux/Dbtux.hpp index b73af5b0d76..e871fc86dea 100644 --- a/ndb/src/kernel/blocks/dbtux/Dbtux.hpp +++ b/ndb/src/kernel/blocks/dbtux/Dbtux.hpp @@ -28,7 +28,6 @@ // signal classes #include <signaldata/DictTabInfo.hpp> #include <signaldata/TuxContinueB.hpp> -#include <signaldata/TuxSizeAltReq.hpp> #include <signaldata/BuildIndx.hpp> #include <signaldata/TupFrag.hpp> #include <signaldata/AlterIndx.hpp> @@ -620,7 +619,7 @@ private: */ void execCONTINUEB(Signal* signal); void execSTTOR(Signal* signal); - void execSIZEALT_REP(Signal* signal); + void execREAD_CONFIG_REQ(Signal* signal); // utils void copyAttrs(Data dst, ConstData src, CopyPar& copyPar); diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp index 32d66422d5c..082b243bcb1 100644 --- a/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp +++ b/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp @@ -16,6 +16,8 @@ #define DBTUX_GEN_CPP #include "Dbtux.hpp" +#include <signaldata/TuxContinueB.hpp> +#include <signaldata/TuxContinueB.hpp> Dbtux::Dbtux(const Configuration& conf) : SimulatedBlock(DBTUX, conf), @@ -42,7 +44,7 @@ Dbtux::Dbtux(const Configuration& conf) : */ addRecSignal(GSN_CONTINUEB, &Dbtux::execCONTINUEB); addRecSignal(GSN_STTOR, &Dbtux::execSTTOR); - addRecSignal(GSN_SIZEALT_REP, &Dbtux::execSIZEALT_REP); + addRecSignal(GSN_READ_CONFIG_REQ, &Dbtux::execREAD_CONFIG_REQ, true); /* * DbtuxMeta.cpp */ @@ -143,18 +145,32 @@ Dbtux::execSTTOR(Signal* signal) } void -Dbtux::execSIZEALT_REP(Signal* signal) +Dbtux::execREAD_CONFIG_REQ(Signal* signal) { jamEntry(); - const Uint32* data = signal->getDataPtr(); - BlockReference sender = data[TuxSizeAltReq::IND_BLOCK_REF]; - const Uint32 nIndex = data[TuxSizeAltReq::IND_INDEX]; - const Uint32 nFragment = data[TuxSizeAltReq::IND_FRAGMENT]; - const Uint32 nAttribute = data[TuxSizeAltReq::IND_ATTRIBUTE]; + + const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr(); + Uint32 ref = req->senderRef; + Uint32 senderData = req->senderData; + ndbrequire(req->noOfParameters == 0); + + Uint32 nIndex; + Uint32 nFragment; + Uint32 nAttribute; + Uint32 nScanOp; + + const ndb_mgm_configuration_iterator * p = + theConfiguration.getOwnConfigIterator(); + ndbrequire(p != 0); + + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUX_INDEX, &nIndex)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUX_FRAGMENT, &nFragment)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUX_ATTRIBUTE, &nAttribute)); + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUX_SCAN_OP, &nScanOp)); + const Uint32 nDescPage = (nIndex + nAttribute + DescPageSize - 1) / DescPageSize; - const Uint32 nScanOp = data[TuxSizeAltReq::IND_SCAN]; const Uint32 nScanBoundWords = nScanOp * ScanBoundSegmentSize * 4; - // allocate records + c_indexPool.setSize(nIndex); c_fragPool.setSize(nFragment); c_descPagePool.setSize(nDescPage); @@ -179,7 +195,11 @@ Dbtux::execSIZEALT_REP(Signal* signal) // allocate buffers c_keyBuffer = (Uint32*)allocRecord("c_keyBuffer", sizeof(Uint64), (MaxAttrDataSize + 1) >> 1); // ack - sendSignal(sender, GSN_SIZEALT_ACK, signal, 1, JBB); + ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend(); + conf->senderRef = reference(); + conf->senderData = senderData; + sendSignal(ref, GSN_READ_CONFIG_CONF, signal, + ReadConfigConf::SignalLength, JBB); } // utils diff --git a/ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp b/ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp index a481573e370..639d300d6df 100644 --- a/ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp +++ b/ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp @@ -21,10 +21,13 @@ #include <pc.hpp> #include <SimulatedBlock.hpp> #include <ndb_limits.h> -#include <signaldata/CmvmiCfgConf.hpp> #include <signaldata/StopReq.hpp> #include <signaldata/ResumeReq.hpp> #include <signaldata/DictTabInfo.hpp> +#include <signaldata/CntrStart.hpp> +#include <signaldata/CheckNodeGroups.hpp> + +#include <signaldata/UpgradeStartup.hpp> #include <NodeState.hpp> #include <NdbTick.h> @@ -39,70 +42,13 @@ ----------------- */ #define ZNO_NDB_BLOCKS 6 /* ACC, DICT, DIH, LQH, TC, TUP */ -#define ZDELAY_NODERESTART 5 /* MASTER REFUSED NODERESTART, WAIT SEC */ -#define ZDELAY_START 25 /* WAIT SECONDS FOR OTHER NODES, RESTART*/ -#define ZHB_INTERVAL 10 /* HEART BEAT INTERVAL TIME MS */ -#define ZNO_NDB_NODES 1 -#define ZHB_TYPE 1 - -//------- ERROR CODES ----------------------------------------- -#define ZERROR_ALREADY_EXISTS 901 -#define ZERROR_DOESNT_EXIST 902 -#define ZERROR_VALUE_OUT_OF_RANGE 903 -#define ZERROR_NOT_STARTED 904 -#define ZERROR_NODE_RESTART 905 -#define ZERROR_NO_RESTART_NODES 906 -#define ZERROR_STARTPHASE_VALUE 907 -#define ZERROR_CNTR_MASTERREQ 908 -#define ZERROR_CNTR_MASTERREF 909 -#define ZERROR_CNTR_MASTERCONF 910 -#define ZERROR_NOT_RUNNING 911 -#define ZERROR_CNTR_WAITREP 912 + #define ZNOT_AVAILABLE 913 -#define ZERROR_DISK_FAILURE 914 -#define ZERROR_TOO_MANY_NODES 915 -#define ZERROR_TYPEOFSTART 916 -#define ZERROR_CTYPE_OF_START 917 -#define ZERROR_ZSTART 918 -#define ZERROR_AT_SELECT_START 919 -#define ZERROR_CNTR_CHANGEREP 920 -#define ZERR_DETECT_NODERESTART_1 921 -#define ZERR_DETECT_NODERESTART_2 922 -#define ZERROR_CONTINUEB 923 -#define ZERR_APPL_REGREF 924 -#define ZERR_DICTADDATTRREF 925 -#define ZERR_DICTPREPAREREF 926 -#define ZERR_DICTRELEASEREF 927 -#define ZERR_DICTTABREF 928 -#define ZERR_DICTSEIZEREF 929 -#define ZERR_NDB_STARTREF 930 -#define ZERR_NODE_STATESREF 931 -#define ZERR_READ_NODESREF 932 -#define ZERR_TCKEYREF 933 -#define ZERR_TCRELEASEREF 934 -#define ZERR_TCSEIZEREF 935 -#define ZNOTVALIDSTATE_1 936 -#define ZNOTVALIDSTATE_2 937 -#define ZNODE_FAILURE_DURING_RESTART 938 -#define ZSTART_IN_PROGRESS_ERROR 939 -#define ZCOULD_NOT_OCCUR_ERROR 940 -#define ZTOO_MANY_NODES_ERROR 941 -#define ZNODE_RESTART_ONGOING_ERROR 942 -#define ZWE_ARE_DECLARED_DEAD_ERROR 943 -#define ZTIME_OUT_ERROR 944 -#define ZTYPE_OF_START_ERROR 945 -#define ZMASTER_CONFLICT_ERROR 946 -#define ZNODE_CONFLICT_ERROR 947 //------- OTHERS --------------------------------------------- -#define ZCONTINUEB_1 1 -#define ZCONTINUEB_2 2 -#define ZSHUTDOWN 3 - -#define ZAPPL_SUBTYPE 0 -#define ZNAME_OF_APPL "NDB" -#define ZVOTING 2 -#define ZSIZE_CFG_BLOCK_REC 8 +#define ZSTARTUP 1 +#define ZSHUTDOWN 2 + #define ZSIZE_NDB_BLOCKS_REC 16 /* MAX BLOCKS IN NDB */ #define ZSIZE_SYSTAB 2048 #define ZSTART_PHASE_1 1 @@ -124,28 +70,10 @@ #define ZWAITPOINT_7_1 7 #define ZWAITPOINT_7_2 8 #define ZSYSTAB_VERSION 1 -/* -------- SIGNAL CONSTANTS ----------------------------------- -*/ -#define ZNOT_MASTER 0 -/* REASON OF CNTR_MASTERREF */ -#define ZTOO_FEW_NODES 1 -#define ZNEW_MASTER 0 -#define ZDELETE_NODE 1 -#define ZSYSTAB_EXIST 3 -#define ZVOTE_NEW_NODE 4 -#define ZVARIABLE_NO 1 -#define ZAMOUNT_PAGES 8 #endif class Ndbcntr: public SimulatedBlock { public: - // State values - enum State { - NOT_ACTIVE = 0, - ACTIVE = 1 - }; - // Records /* FSREADREQ FSWRITEREQ */ @@ -154,59 +82,27 @@ public: * ------------------------------------------------------------ */ -/** - * CFG_BLOCK_REC CONTAINS ALL CONFIG DATA SENT IN EACH NDB_STTOR - * SOME OTHER CONFIG DATA IS STORED IN RECORD 0 - * - * WHEN CFG_BLOCK_PTR = ZSTART_PHASE_X ( CINTERNAL_STARTPHASE ) - * WORD 0 DICT_1 - * WORD 1 DICT_2 - * WORD 2 DIH_1 - * WORD 3 DIH_2 - * WORD 4 LQH_1 - * WORD 5 LQH_2 - * WORD 6 TC_1 - * WORD 7 TC_2 - * WORD 8 TUP_1 - * WORD 9 TUP_2 - * WORD 10 ACC_1 - * WORD 11 ACC_2 - * - * CFG_BLOCK_PTR = 0 - * WORD 0 CDELAY_START - * WORD 1 CDELAY_NODERESTART - *------------------------------------------------------------------------*/ - struct CfgBlockRec { - UintR cfgData[CmvmiCfgConf::NO_OF_WORDS]; - }; /* p2c: size = 64 bytes */ + struct StartRecord { + Uint64 m_startTime; + + void reset(); + NdbNodeBitmask m_starting; + NdbNodeBitmask m_waiting; // == (m_withLog | m_withoutLog) + NdbNodeBitmask m_withLog; + NdbNodeBitmask m_withoutLog; + Uint32 m_lastGci; + Uint32 m_lastGciNodeId; + + Uint64 m_startPartialTimeout; + Uint64 m_startPartitionedTimeout; + Uint64 m_startFailureTimeout; + struct { + Uint32 m_nodeId; + Uint32 m_lastGci; + } m_logNodes[MAX_NDB_NODES]; + Uint32 m_logNodesCount; + } c_start; - typedef Ptr<CfgBlockRec> CfgBlockRecPtr; - -/*------------------------------------------------------------------------*/ -// CONTAIN INFO ABOUT ALL NODES IN CLUSTER. NODE_PTR ARE USED AS NODE NUMBER. -// IF THE STATE ARE ZDELETE THEN THE NODE DOESN'T EXIST. NODES ARE ALLOWED -// TO REGISTER (ZADD) DURING RESTART. -// WHEN THE SYSTEM IS RUNNING THE MASTER WILL CHECK IF ANY NODE HAS MADE A -// CNTR_MASTERREQ AND TAKE CARE OF THE -// REQUEST. TO CONFIRM THE REQ, THE MASTER DEMANDS THAT ALL RUNNING NODES HAS -// VOTED FOR THE NEW NODE. -// NODE_PTR:MASTER_REQ IS USED DURING RESTART TO LOG POSTPONED -// CNTR_MASTERREQ'S -/*------------------------------------------------------------------------*/ - struct NodeRec { - UintR dynamicId; - BlockReference cntrBlockref; - Uint16 masterReq; - Uint16 state; - Uint16 ndbVersion; - Uint16 subType; - Uint8 votes; - Uint8 voter; - UintR nodeDefined; - }; /* p2c: size = 16 bytes */ - - typedef Ptr<NodeRec> NodeRecPtr; - struct NdbBlocksRec { BlockReference blockref; }; /* p2c: size = 2 bytes */ @@ -266,16 +162,14 @@ private: void execCONTINUEB(Signal* signal); void execREAD_NODESCONF(Signal* signal); void execREAD_NODESREF(Signal* signal); - void execCNTR_MASTERREQ(Signal* signal); - void execCNTR_MASTERCONF(Signal* signal); - void execCNTR_MASTERREF(Signal* signal); + void execCM_ADD_REP(Signal* signal); + void execCNTR_START_REQ(Signal* signal); + void execCNTR_START_REF(Signal* signal); + void execCNTR_START_CONF(Signal* signal); + void execCNTR_START_REP(Signal* signal); void execCNTR_WAITREP(Signal* signal); - void execNODE_STATESREQ(Signal* signal); - void execNODE_STATESCONF(Signal* signal); - void execNODE_STATESREF(Signal* signal); void execNODE_FAILREP(Signal* signal); void execSYSTEM_ERROR(Signal* signal); - void execVOTE_MASTERORD(Signal* signal); // Received signals void execDUMP_STATE_ORD(Signal* signal); @@ -295,12 +189,7 @@ private: void execNDB_STTORRY(Signal* signal); void execNDB_STARTCONF(Signal* signal); void execREAD_NODESREQ(Signal* signal); - void execAPPL_REGCONF(Signal* signal); - void execAPPL_REGREF(Signal* signal); - void execAPPL_CHANGEREP(Signal* signal); - void execAPPL_STARTCONF(Signal* signal); void execNDB_STARTREF(Signal* signal); - void execCMVMI_CFGCONF(Signal* signal); void execSET_VAR_REQ(Signal* signal); void execSTOP_PERM_REF(Signal* signal); @@ -323,19 +212,17 @@ private: // Statement blocks void sendCreateTabReq(Signal* signal, const char* buffer, Uint32 bufLen); void startInsertTransactions(Signal* signal); - UintR checkNodelist(Signal* signal, Uint16 TnoRestartNodes); - void chooseRestartNodes(Signal* signal); - void copyCfgVariables(Signal* signal); - void deleteNode(Signal* signal); - void detectNoderestart(Signal* signal); - void getStartNodes(Signal* signal); void initData(Signal* signal); - void replyMasterconfToAll(Signal* signal); void resetStartVariables(Signal* signal); - void sendCntrMasterreq(Signal* signal); + void sendCntrStartReq(Signal* signal); + void sendCntrStartRef(Signal*, Uint32 nodeId, CntrStartRef::ErrorCode); void sendNdbSttor(Signal* signal); void sendSttorry(Signal* signal); + bool trySystemRestart(Signal* signal); + void startWaitingNodes(Signal* signal); + CheckNodeGroups::Output checkNodeGroups(Signal*, const NdbNodeBitmask &); + // Generated statement blocks void systemErrorLab(Signal* signal); @@ -367,13 +254,6 @@ private: void ph7ALab(Signal* signal); void ph8ALab(Signal* signal); - void masterreq010Lab(Signal* signal, - Uint16 TnoRestartNodes, - Uint16 TuserNodeId); - void masterreq020Lab(Signal* signal); - void masterreq030Lab(Signal* signal, - Uint16 TnoRestartNodes, - Uint16 TuserNodeId); void waitpoint41Lab(Signal* signal); void waitpoint51Lab(Signal* signal); @@ -401,62 +281,40 @@ private: * NODE_PTR:MASTER_REQ IS USED DURING RESTART TO LOG * POSTPONED CNTR_MASTERREQ'S *------------------------------------------------------------------------*/ - CfgBlockRec *cfgBlockRec; - NodeRec *nodeRec; NdbBlocksRec *ndbBlocksRec; - NodeRecPtr nodePtr; -/* -2.4 COMMON STORED VARIABLES -*/ - Uint16 cstartNodes[MAX_NDB_NODES]; - BlockReference ccmvmiBlockref; - BlockReference cqmgrBlockref; - BlockReference cdictBlockref; - BlockReference cdihBlockref; - BlockReference clqhBlockref; - BlockReference cownBlockref; - BlockReference ctcBlockref; - UintR cnoNdbNodes; - UintR capplStartconfFlag; + + /* + 2.4 COMMON STORED VARIABLES + */ UintR cgciSystab; UintR ckey; - UintR cnoRegNodes; - UintR cnoRunNodes; - UintR cnoNeedNodes; - UintR cnoWaitrep; + //UintR csystabId; UintR cnoWaitrep6; UintR cnoWaitrep7; - //UintR csystabId; UintR ctcConnectionP; UintR ctcReqInfo; - UintR clastGci; - UintR cmasterLastGci; - UintR cmasterCurrentId; - Uint16 cmasterDihId; + Uint8 ctransidPhase; Uint16 cresponses; - Uint16 cdelayStart; + Uint8 cstartPhase; Uint16 cinternalStartphase; + Uint16 cmasterNodeId; - Uint16 cmasterCandidateId; Uint16 cndbBlocksCount; Uint16 cnoStartNodes; - Uint16 cnoVoters; - Uint16 cstartProgressFlag; - Uint16 cqmgrConnectionP; - Uint16 csignalKey; + UintR cnoWaitrep; NodeState::StartType ctypeOfStart; - Uint16 cmasterVoters; Uint16 cdynamicNodeId; - Uint8 cwaitContinuebFlag; - Uint8 cstartPhase; - Uint8 ctransidPhase; Uint32 c_fsRemoveCount; Uint32 c_nodeGroup; void clearFilesystem(Signal* signal); void execFSREMOVEREF(Signal* signal); void execFSREMOVECONF(Signal* signal); + + NdbNodeBitmask c_allDefinedNodes; + NdbNodeBitmask c_clusterNodes; // All members of qmgr cluster + NdbNodeBitmask c_startedNodes; // All cntr started nodes public: struct StopRecord { @@ -495,6 +353,8 @@ private: void execSTART_ORD(Signal* signal); void execSTTORRY(Signal* signal); void sendNextSTTOR(Signal* signal); + void execREAD_CONFIG_CONF(Signal* signal); + void sendNextREAD_CONFIG_REQ(Signal* signal); BlockNumber number() const { return cntr.number(); } void progError(int line, int cause, const char * extra) { @@ -508,6 +368,9 @@ private: void execSTTORRY(Signal* signal); void execSTART_ORD(Signal* signal); + void execREAD_CONFIG_CONF(Signal*); + + friend struct UpgradeStartup; }; #endif diff --git a/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp b/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp index 9af6359876b..1069cf93b06 100644 --- a/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp +++ b/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp @@ -27,8 +27,6 @@ void Ndbcntr::initData() { // Records with constant sizes - cfgBlockRec = new CfgBlockRec[ZSIZE_CFG_BLOCK_REC]; - nodeRec = new NodeRec[MAX_NDB_NODES]; ndbBlocksRec = new NdbBlocksRec[ZSIZE_NDB_BLOCKS_REC]; }//Ndbcntr::initData() @@ -51,17 +49,15 @@ Ndbcntr::Ndbcntr(const class Configuration & conf): addRecSignal(GSN_CONTINUEB, &Ndbcntr::execCONTINUEB); addRecSignal(GSN_READ_NODESCONF, &Ndbcntr::execREAD_NODESCONF); addRecSignal(GSN_READ_NODESREF, &Ndbcntr::execREAD_NODESREF); - addRecSignal(GSN_CNTR_MASTERREQ, &Ndbcntr::execCNTR_MASTERREQ); - addRecSignal(GSN_CNTR_MASTERCONF, &Ndbcntr::execCNTR_MASTERCONF); - addRecSignal(GSN_CNTR_MASTERREF, &Ndbcntr::execCNTR_MASTERREF); + addRecSignal(GSN_CM_ADD_REP, &Ndbcntr::execCM_ADD_REP); + addRecSignal(GSN_CNTR_START_REQ, &Ndbcntr::execCNTR_START_REQ); + addRecSignal(GSN_CNTR_START_REF, &Ndbcntr::execCNTR_START_REF); + addRecSignal(GSN_CNTR_START_CONF, &Ndbcntr::execCNTR_START_CONF); addRecSignal(GSN_CNTR_WAITREP, &Ndbcntr::execCNTR_WAITREP); - addRecSignal(GSN_NODE_STATESREQ, &Ndbcntr::execNODE_STATESREQ); - addRecSignal(GSN_NODE_STATESCONF, &Ndbcntr::execNODE_STATESCONF); - addRecSignal(GSN_NODE_STATESREF, &Ndbcntr::execNODE_STATESREF); + addRecSignal(GSN_CNTR_START_REP, &Ndbcntr::execCNTR_START_REP); addRecSignal(GSN_NODE_FAILREP, &Ndbcntr::execNODE_FAILREP); addRecSignal(GSN_SYSTEM_ERROR , &Ndbcntr::execSYSTEM_ERROR); - addRecSignal(GSN_VOTE_MASTERORD, &Ndbcntr::execVOTE_MASTERORD); - + // Received signals addRecSignal(GSN_DUMP_STATE_ORD, &Ndbcntr::execDUMP_STATE_ORD); addRecSignal(GSN_STTOR, &Ndbcntr::execSTTOR); @@ -80,12 +76,7 @@ Ndbcntr::Ndbcntr(const class Configuration & conf): addRecSignal(GSN_NDB_STTORRY, &Ndbcntr::execNDB_STTORRY); addRecSignal(GSN_NDB_STARTCONF, &Ndbcntr::execNDB_STARTCONF); addRecSignal(GSN_READ_NODESREQ, &Ndbcntr::execREAD_NODESREQ); - addRecSignal(GSN_APPL_REGCONF, &Ndbcntr::execAPPL_REGCONF); - addRecSignal(GSN_APPL_REGREF, &Ndbcntr::execAPPL_REGREF); - addRecSignal(GSN_APPL_CHANGEREP, &Ndbcntr::execAPPL_CHANGEREP); - addRecSignal(GSN_APPL_STARTCONF, &Ndbcntr::execAPPL_STARTCONF); addRecSignal(GSN_NDB_STARTREF, &Ndbcntr::execNDB_STARTREF); - addRecSignal(GSN_CMVMI_CFGCONF, &Ndbcntr::execCMVMI_CFGCONF); addRecSignal(GSN_SET_VAR_REQ, &Ndbcntr::execSET_VAR_REQ); addRecSignal(GSN_STOP_PERM_REF, &Ndbcntr::execSTOP_PERM_REF); @@ -107,18 +98,18 @@ Ndbcntr::Ndbcntr(const class Configuration & conf): addRecSignal(GSN_START_ORD, &Ndbcntr::execSTART_ORD); addRecSignal(GSN_STTORRY, &Ndbcntr::execSTTORRY); + addRecSignal(GSN_READ_CONFIG_CONF, &Ndbcntr::execREAD_CONFIG_CONF); addRecSignal(GSN_FSREMOVEREF, &Ndbcntr::execFSREMOVEREF); addRecSignal(GSN_FSREMOVECONF, &Ndbcntr::execFSREMOVECONF); initData(); ctypeOfStart = NodeState::ST_ILLEGAL_TYPE; + c_start.m_startTime = NdbTick_CurrentMillisecond(); }//Ndbcntr::Ndbcntr() Ndbcntr::~Ndbcntr() { - delete []cfgBlockRec; - delete []nodeRec; delete []ndbBlocksRec; }//Ndbcntr::~Ndbcntr() diff --git a/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp b/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp index 4211645ace6..b5a5d0948bb 100644 --- a/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp +++ b/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp @@ -23,13 +23,10 @@ #include <signaldata/DictTabInfo.hpp> #include <signaldata/CreateTable.hpp> #include <signaldata/ReadNodesConf.hpp> -#include <signaldata/CntrMasterReq.hpp> -#include <signaldata/CntrMasterConf.hpp> #include <signaldata/NodeFailRep.hpp> #include <signaldata/TcKeyReq.hpp> #include <signaldata/TcKeyConf.hpp> #include <signaldata/EventReport.hpp> -#include <signaldata/SetVarReq.hpp> #include <signaldata/NodeStateSignalData.hpp> #include <signaldata/StopPerm.hpp> #include <signaldata/StopMe.hpp> @@ -39,9 +36,11 @@ #include <signaldata/AbortAll.hpp> #include <signaldata/SystemError.hpp> #include <signaldata/NdbSttor.hpp> +#include <signaldata/CntrStart.hpp> #include <signaldata/DumpStateOrd.hpp> #include <signaldata/FsRemoveReq.hpp> +#include <signaldata/ReadConfig.hpp> #include <AttributeHeader.hpp> #include <Configuration.hpp> @@ -50,8 +49,6 @@ #include <NdbOut.hpp> #include <NdbTick.h> -#define ZSYSTEM_RUN 256 - /** * ALL_BLOCKS Used during start phases and while changing node state * @@ -60,25 +57,27 @@ struct BlockInfo { BlockReference Ref; // BlockReference Uint32 NextSP; // Next start phase + Uint32 ErrorInsertStart; + Uint32 ErrorInsertStop; }; static BlockInfo ALL_BLOCKS[] = { - { DBTC_REF, 1 }, - { DBDIH_REF, 1 }, - { DBLQH_REF, 1 }, - { DBACC_REF, 1 }, - { DBTUP_REF, 1 }, - { DBDICT_REF, 1 }, - { NDBFS_REF, 0 }, - { NDBCNTR_REF, 0 }, - { QMGR_REF, 1 }, - { CMVMI_REF, 1 }, + { DBTC_REF, 1 , 8000, 8035 }, + { DBDIH_REF, 1 , 7000, 7173 }, + { DBLQH_REF, 1 , 5000, 5030 }, + { DBACC_REF, 1 , 3000, 3999 }, + { DBTUP_REF, 1 , 4000, 4007 }, + { DBDICT_REF, 1 , 6000, 6003 }, + { NDBFS_REF, 0 , 2000, 2999 }, + { NDBCNTR_REF, 0 , 1000, 1999 }, + { QMGR_REF, 1 , 1, 999 }, + { CMVMI_REF, 1 , 9000, 9999 }, { TRIX_REF, 1 }, - { BACKUP_REF, 1 }, - { DBUTIL_REF, 1 }, - { SUMA_REF, 1 }, + { BACKUP_REF, 1 , 10000, 10999 }, + { DBUTIL_REF, 1 , 11000, 11999 }, + { SUMA_REF, 1 , 13000, 13999 }, { GREP_REF, 1 }, - { DBTUX_REF, 1 } + { DBTUX_REF, 1 , 12000, 12999 } }; static const Uint32 ALL_BLOCKS_SZ = sizeof(ALL_BLOCKS)/sizeof(BlockInfo); @@ -91,33 +90,27 @@ void Ndbcntr::execCONTINUEB(Signal* signal) jamEntry(); UintR Ttemp1 = signal->theData[0]; switch (Ttemp1) { - case ZCONTINUEB_1: - jam(); - if (cwaitContinuebFlag == ZFALSE) { - jam(); -/*******************************/ -/* SIGNAL NOT WANTED ANYMORE */ -/*******************************/ - return; - } else { + case ZSTARTUP:{ + if(getNodeState().startLevel == NodeState::SL_STARTED){ jam(); -/*******************************/ -/* START ALREADY IN PROGRESS */ -/*******************************/ - if (cstartProgressFlag == ZVOTING) { - jam(); - systemErrorLab(signal); - return; - }//if - if (ctypeOfStart == NodeState::ST_NODE_RESTART) { - jam(); - systemErrorLab(signal); - return; - }//if - ph2ELab(signal); return; - }//if + } + + if(cmasterNodeId == getOwnNodeId() && c_start.m_starting.isclear()){ + jam(); + trySystemRestart(signal); + // Fall-through + } + + Uint64 now = NdbTick_CurrentMillisecond(); + if(c_start.m_startFailureTimeout > now){ + ndbrequire(false); + } + + signal->theData[0] = ZSTARTUP; + sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 1000, 1); break; + } case ZSHUTDOWN: jam(); c_stopRec.checkTimeout(signal); @@ -189,28 +182,18 @@ void Ndbcntr::execSYSTEM_ERROR(Signal* signal) return; }//Ndbcntr::execSYSTEM_ERROR() -/*---------------------------------------------------------------------------*/ -/* The STTOR signal is on level C, we use CONTINUEB to get into level B */ -/*---------------------------------------------------------------------------*/ -/**************************** >----------------------------------------------*/ -/* STTOR > SENDER : MISSRA */ -/**************************** >------------------+ RECEIVER : NDBCNTR */ - /* INPUT : CSTART_PHASE */ - /* CSIGNAL_KEY */ - /*---------------------------*/ -/*******************************/ -/* STTOR */ -/*******************************/ void Ndbcntr::execSTTOR(Signal* signal) { jamEntry(); cstartPhase = signal->theData[1]; - csignalKey = signal->theData[6]; NodeState newState(NodeState::SL_STARTING, cstartPhase, (NodeState::StartType)ctypeOfStart); updateNodeState(signal, newState); + cndbBlocksCount = 0; + cinternalStartphase = cstartPhase - 1; + switch (cstartPhase) { case 0: if(theConfiguration.getInitialStart()){ @@ -244,6 +227,7 @@ void Ndbcntr::execSTTOR(Signal* signal) case 6: jam(); getNodeGroup(signal); + // Fall through break; case ZSTART_PHASE_8: jam(); @@ -327,80 +311,37 @@ void Ndbcntr::execNDB_STTORRY(Signal* signal) }//switch }//Ndbcntr::execNDB_STTORRY() -/* -4.2 START PHASE 1 */ -/*###########################################################################*/ -/*LOAD OUR BLOCK REFERENCE AND OUR NODE ID. LOAD NODE IDS OF ALL NODES IN */ -/* CLUSTER CALCULATE BLOCK REFERENCES OF ALL BLOCKS IN THIS NODE */ -/*---------------------------------------------------------------------------*/ -/*******************************/ -/* STTOR */ -/*******************************/ void Ndbcntr::startPhase1Lab(Signal* signal) { jamEntry(); initData(signal); - cownBlockref = calcNdbCntrBlockRef(0); - cnoRunNodes = 0; - cnoRegNodes = 0; - - NdbBlocksRecPtr ndbBlocksPtr; cdynamicNodeId = 0; - cownBlockref = calcNdbCntrBlockRef(getOwnNodeId()); - cqmgrBlockref = calcQmgrBlockRef(getOwnNodeId()); - cdictBlockref = calcDictBlockRef(getOwnNodeId()); - cdihBlockref = calcDihBlockRef(getOwnNodeId()); - clqhBlockref = calcLqhBlockRef(getOwnNodeId()); - ctcBlockref = calcTcBlockRef(getOwnNodeId()); - ccmvmiBlockref = numberToRef(CMVMI, getOwnNodeId()); + NdbBlocksRecPtr ndbBlocksPtr; ndbBlocksPtr.i = 0; ptrAss(ndbBlocksPtr, ndbBlocksRec); - ndbBlocksPtr.p->blockref = clqhBlockref; + ndbBlocksPtr.p->blockref = DBLQH_REF; ndbBlocksPtr.i = 1; ptrAss(ndbBlocksPtr, ndbBlocksRec); - ndbBlocksPtr.p->blockref = cdictBlockref; + ndbBlocksPtr.p->blockref = DBDICT_REF; ndbBlocksPtr.i = 2; ptrAss(ndbBlocksPtr, ndbBlocksRec); - ndbBlocksPtr.p->blockref = calcTupBlockRef(getOwnNodeId()); + ndbBlocksPtr.p->blockref = DBTUP_REF; ndbBlocksPtr.i = 3; ptrAss(ndbBlocksPtr, ndbBlocksRec); - ndbBlocksPtr.p->blockref = calcAccBlockRef(getOwnNodeId()); + ndbBlocksPtr.p->blockref = DBACC_REF; ndbBlocksPtr.i = 4; ptrAss(ndbBlocksPtr, ndbBlocksRec); - ndbBlocksPtr.p->blockref = ctcBlockref; + ndbBlocksPtr.p->blockref = DBTC_REF; ndbBlocksPtr.i = 5; ptrAss(ndbBlocksPtr, ndbBlocksRec); - ndbBlocksPtr.p->blockref = cdihBlockref; + ndbBlocksPtr.p->blockref = DBDIH_REF; sendSttorry(signal); return; } -/* -4.3 START PHASE 2 */ -/*###########################################################################*/ -// SEND A REGISTATION REQUEST TO QMGR AND WAIT FOR REPLY APPL_REGCONF OR -// APPL_REGREF COLLECT ALL OTHER NDB NODES -// AND THEIR STATES FIND OUT WHAT KIND OF START THIS NODE ARE GOING TO PERFORM -// IF THIS IS A SYSTEM OR INITIAL -// RESTART THEN FIND OUT WHO IS THE MASTER IF THIS NODE BECOME THE CNTR MASTER -// THEN COLLECT CNTR_MASTERREQ FROM -// ALL OTHER REGISTRATED CNTR THE MASTER WILL SEND BACK A CNTR_MASTERCONF WITH -// FINAL DECISSION ABOUT WHAT TYPE -// OF START AND WHICH NODES ARE APPROVED TO PARTICIPATE IN THE START IF THE -// RECEIVER OF CNTR_MASTERREQ HAVE A -// BETTER CHOICE OF MASTER THEN SEND CNTR_MASTERREF. NEW NODES ARE ALWAYS -// ALLOWED TO REGISTER, EVEN DURING -// RESTART BUT THEY WILL BE IGNORED UNTIL THE START HAVE FINISHED. -// SEND SIGNAL NDBSTTOR TO ALL BLOCKS, ACC, DICT, DIH, LQH, TC AND TUP -// SEND SIGNAL APPL_REGREQ TO QMGR IN THIS NODE AND WAIT FOR REPLY -// APPL_REGCONF OR APPL_REGREF */ -/*--------------------------------------------------------------------------*/ -/*******************************/ -/* READ_NODESREF */ -/*******************************/ void Ndbcntr::execREAD_NODESREF(Signal* signal) { jamEntry(); @@ -408,25 +349,6 @@ void Ndbcntr::execREAD_NODESREF(Signal* signal) return; }//Ndbcntr::execREAD_NODESREF() -/*******************************/ -/* APPL_REGREF */ -/*******************************/ -void Ndbcntr::execAPPL_REGREF(Signal* signal) -{ - jamEntry(); - systemErrorLab(signal); - return; -}//Ndbcntr::execAPPL_REGREF() - -/*******************************/ -/* CNTR_MASTERREF */ -/*******************************/ -void Ndbcntr::execCNTR_MASTERREF(Signal* signal) -{ - jamEntry(); - systemErrorLab(signal); - return; -}//Ndbcntr::execCNTR_MASTERREF() /*******************************/ /* NDB_STARTREF */ @@ -443,17 +365,11 @@ void Ndbcntr::execNDB_STARTREF(Signal* signal) /*******************************/ void Ndbcntr::startPhase2Lab(Signal* signal) { - cinternalStartphase = cstartPhase - 1; -/*--------------------------------------*/ -/* CASE: CSTART_PHASE = ZSTART_PHASE_2 */ -/*--------------------------------------*/ - cndbBlocksCount = 0; - cwaitContinuebFlag = ZFALSE; -/* NOT WAITING FOR SIGNAL CONTINUEB */ - - clastGci = 0; - signal->theData[0] = cownBlockref; - sendSignal(cdihBlockref, GSN_DIH_RESTARTREQ, signal, 1, JBB); + c_start.m_lastGci = 0; + c_start.m_lastGciNodeId = getOwnNodeId(); + + signal->theData[0] = reference(); + sendSignal(DBDIH_REF, GSN_DIH_RESTARTREQ, signal, 1, JBB); return; }//Ndbcntr::startPhase2Lab() @@ -463,8 +379,8 @@ void Ndbcntr::startPhase2Lab(Signal* signal) void Ndbcntr::execDIH_RESTARTCONF(Signal* signal) { jamEntry(); - cmasterDihId = signal->theData[0]; - clastGci = signal->theData[1]; + //cmasterDihId = signal->theData[0]; + c_start.m_lastGci = signal->theData[1]; ctypeOfStart = NodeState::ST_SYSTEM_RESTART; ph2ALab(signal); return; @@ -488,370 +404,449 @@ void Ndbcntr::ph2ALab(Signal* signal) /* from QMGR */ /* READ_NODESREQ */ /******************************/ - signal->theData[0] = cownBlockref; - sendSignal(cqmgrBlockref, GSN_READ_NODESREQ, signal, 1, JBB); + signal->theData[0] = reference(); + sendSignal(QMGR_REF, GSN_READ_NODESREQ, signal, 1, JBB); return; }//Ndbcntr::ph2ALab() +inline +Uint64 +setTimeout(Uint64 time, Uint32 timeoutValue){ + if(timeoutValue == 0) + return ~0; + return time + timeoutValue; +} + /*******************************/ /* READ_NODESCONF */ /*******************************/ void Ndbcntr::execREAD_NODESCONF(Signal* signal) { jamEntry(); - ReadNodesConf * const readNodes = (ReadNodesConf *)&signal->theData[0]; + const ReadNodesConf * readNodes = (ReadNodesConf *)&signal->theData[0]; - for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { - jam(); - ptrAss(nodePtr, nodeRec); - if(NodeBitmask::get(readNodes->allNodes, nodePtr.i)){ - jam(); - nodePtr.p->nodeDefined = ZTRUE; - } else { - jam(); - nodePtr.p->nodeDefined = ZFALSE; - }//if - }//for + cmasterNodeId = readNodes->masterNodeId; + cdynamicNodeId = readNodes->ndynamicId; + + /** + * All defined nodes... + */ + c_allDefinedNodes.assign(NdbNodeBitmask::Size, readNodes->allNodes); + c_clusterNodes.assign(NdbNodeBitmask::Size, readNodes->clusterNodes); - CfgBlockRecPtr cfgBlockPtr; + Uint32 to_1 = 30000; + Uint32 to_2 = 0; + Uint32 to_3 = 0; + + const ndb_mgm_configuration_iterator * p = + theConfiguration.getOwnConfigIterator(); + + ndbrequire(p != 0); + ndb_mgm_get_int_parameter(p, CFG_DB_START_PARTIAL_TIMEOUT, &to_1); + ndb_mgm_get_int_parameter(p, CFG_DB_START_PARTITION_TIMEOUT, &to_2); + ndb_mgm_get_int_parameter(p, CFG_DB_START_FAILURE_TIMEOUT, &to_3); + + c_start.m_startPartialTimeout = setTimeout(c_start.m_startTime, to_1); + c_start.m_startPartitionedTimeout = setTimeout(c_start.m_startTime, to_2); + c_start.m_startFailureTimeout = setTimeout(c_start.m_startTime, to_3); + + if(getNodeInfo(cmasterNodeId).m_version < MAKE_VERSION(3,5,0)){ + /** + * Old NDB running + */ + UpgradeStartup::sendCmAppChg(* this, signal, 0); // ADD + return; + } + + sendCntrStartReq(signal); - cfgBlockPtr.i = 0; - ptrAss(cfgBlockPtr, cfgBlockRec); - signal->theData[0] = cownBlockref; - signal->theData[1] = cfgBlockPtr.i; - sendSignal(ccmvmiBlockref, GSN_CMVMI_CFGREQ, signal, 2, JBB); return; } -/*******************************/ -/* CMVMI_CFGCONF */ -/*******************************/ -void Ndbcntr::execCMVMI_CFGCONF(Signal* signal) -{ - CfgBlockRecPtr cfgBlockPtr; +void +Ndbcntr::execCM_ADD_REP(Signal* signal){ + jamEntry(); + c_clusterNodes.set(signal->theData[0]); +} + +void +Ndbcntr::sendCntrStartReq(Signal * signal){ jamEntry(); - CmvmiCfgConf * const cfgConf = (CmvmiCfgConf *)&signal->theData[0]; + CntrStartReq * req = (CntrStartReq*)signal->getDataPtrSend(); + req->startType = ctypeOfStart; + req->lastGci = c_start.m_lastGci; + req->nodeId = getOwnNodeId(); + sendSignal(calcNdbCntrBlockRef(cmasterNodeId), GSN_CNTR_START_REQ, + signal, CntrStartReq::SignalLength, JBB); +} - cfgBlockPtr.i = cfgConf->startPhase; - ptrCheckGuard(cfgBlockPtr, ZSIZE_CFG_BLOCK_REC, cfgBlockRec); - for(unsigned int i = 0; i<CmvmiCfgConf::NO_OF_WORDS; i++) - cfgBlockPtr.p->cfgData[i] = cfgConf->theData[i]; +void +Ndbcntr::execCNTR_START_REF(Signal * signal){ + jamEntry(); + const CntrStartRef * ref = (CntrStartRef*)signal->getDataPtr(); - if (cfgBlockPtr.i < 4) { + switch(ref->errorCode){ + case CntrStartRef::NotMaster: jam(); - cfgBlockPtr.i = cfgBlockPtr.i + 1; - signal->theData[0] = cownBlockref; - signal->theData[1] = cfgBlockPtr.i; - sendSignal(ccmvmiBlockref, GSN_CMVMI_CFGREQ, signal, 2, JBB); + cmasterNodeId = ref->masterNodeId; + sendCntrStartReq(signal); return; - } + } + ndbrequire(false); +} + +void +Ndbcntr::StartRecord::reset(){ + m_starting.clear(); + m_waiting.clear(); + m_withLog.clear(); + m_withoutLog.clear(); + m_lastGci = m_lastGciNodeId = 0; + m_startPartialTimeout = ~0; + m_startPartitionedTimeout = ~0; + m_startFailureTimeout = ~0; - jam(); + m_logNodesCount = 0; +} + +void +Ndbcntr::execCNTR_START_CONF(Signal * signal){ + jamEntry(); + const CntrStartConf * conf = (CntrStartConf*)signal->getDataPtr(); + + cnoStartNodes = conf->noStartNodes; + ctypeOfStart = (NodeState::StartType)conf->startType; + c_start.m_lastGci = conf->startGci; + cmasterNodeId = conf->masterNodeId; + NdbNodeBitmask tmp; + tmp.assign(NdbNodeBitmask::Size, conf->startedNodes); + c_startedNodes.bitOR(tmp); + c_start.m_starting.assign(NdbNodeBitmask::Size, conf->startingNodes); + ph2GLab(signal); + + UpgradeStartup::sendCmAppChg(* this, signal, 2); //START +} + +/** + * Tried with parallell nr, but it crashed in DIH + * so I turned it off, as I don't want to debug DIH now... + * Jonas 19/11-03 + * + * After trying for 2 hours, I gave up. + * DIH is not designed to support it, and + * it requires quite of lot of changes to + * make it work + * Jonas 5/12-03 + */ +#define PARALLELL_NR 0 - cfgBlockPtr.i = 0; - ptrAss(cfgBlockPtr, cfgBlockRec); +#if PARALLELL_NR +const bool parallellNR = true; +#else +const bool parallellNR = false; +#endif + +void +Ndbcntr::execCNTR_START_REP(Signal* signal){ + jamEntry(); + Uint32 nodeId = signal->theData[0]; + c_startedNodes.set(nodeId); + c_start.m_starting.clear(nodeId); - cdelayStart = cfgBlockPtr.p->cfgData[0]; + if(!c_start.m_starting.isclear()){ + jam(); + return; + } - signal->theData[0] = cownBlockref; - signal->theData[1] = strlen(ZNAME_OF_APPL) | (ZNAME_OF_APPL[0] << 8); - signal->theData[2] = ZNAME_OF_APPL[1] | (ZNAME_OF_APPL[2] << 8); - signal->theData[9] = ZAPPL_SUBTYPE; - signal->theData[10] = 0; //NDB_VERSION; - sendSignal(cqmgrBlockref, GSN_APPL_REGREQ, signal, 11, JBB); - return; /* WAIT FOR APPL_REGCONF */ -}//Ndbcntr::execCMVMI_CFGCONF() + if(cmasterNodeId != getOwnNodeId()){ + c_start.reset(); + return; + } -/*******************************/ -/* APPL_REGCONF */ -/*******************************/ -void Ndbcntr::execAPPL_REGCONF(Signal* signal) -{ - jamEntry(); - cqmgrConnectionP = signal->theData[0]; - cnoNdbNodes = signal->theData[1]; - if(ctypeOfStart == NodeState::ST_INITIAL_START){ - cmasterCandidateId = signal->theData[2]; - } else { - cmasterCandidateId = ZNIL; + if(c_start.m_waiting.isclear()){ + c_start.reset(); + return; } - nodePtr.i = getOwnNodeId(); - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); + startWaitingNodes(signal); +} + +void +Ndbcntr::execCNTR_START_REQ(Signal * signal){ + jamEntry(); + const CntrStartReq * req = (CntrStartReq*)signal->getDataPtr(); - /*----------------------------------------------------------------------*/ - /* CALCULATE HOW MANY NODES THAT WE NEED TO PERFORM A START. MAKE A */ - /* DECISION ABOUT WAITING FOR MORE NODES OR TO CONTINUE AT ONCE */ - /*----------------------------------------------------------------------*/ - nodePtr.p->state = ZADD; - nodePtr.p->ndbVersion = 0; //NDB_VERSION; - nodePtr.p->subType = ZAPPL_SUBTYPE; - nodePtr.p->dynamicId = signal->theData[3]; - // Save dynamic nodeid in global variable - cdynamicNodeId = nodePtr.p->dynamicId; - cnoRegNodes = cnoRegNodes + 1; - switch((NodeState::StartType)ctypeOfStart){ - case NodeState::ST_INITIAL_START: + const Uint32 nodeId = req->nodeId; + const Uint32 lastGci = req->lastGci; + const NodeState::StartType st = (NodeState::StartType)req->startType; + + if(cmasterNodeId == 0){ jam(); - cnoNeedNodes = cnoNdbNodes; - break; - case NodeState::ST_SYSTEM_RESTART: - if (cnoNdbNodes == 2) { - jam(); - /*--------------------------------------*/ - /* NEED > 50% OF ALL NODES. */ - /* WE WILL SEND CONTINUEB WHEN THE WE */ - /* RECEIVE THE FIRST APPL_CHANGEREP. */ - /*--------------------------------------*/ - cnoNeedNodes = 1; /* IF ONLY 2 NODES IN CLUSTER, 1 WILL DO*/ - } else { - jam(); - cnoNeedNodes = (cnoNdbNodes >> 1) + 1; - }//if - break; - case NodeState::ST_NODE_RESTART: - case NodeState::ST_INITIAL_NODE_RESTART: - break; - default: - ndbrequire(false); - }//if + // Has not completed READNODES yet + sendSignalWithDelay(reference(), GSN_CNTR_START_REQ, signal, 100, + signal->getLength()); + return; + } - /*--------------------------------------------------------------*/ - /* WE CAN COME HERE ALSO IN A NODE RESTART IF THE */ - /* REGISTRATION OF A RUNNING NODE HAPPENS TO ARRIVE BEFORE*/ - /* THE APPL_REGCONF SIGNAL. */ - /* IN THAT CASE CNO_NEED_NODES = ZNIL IF NOT NODE_STATE */ - /* SIGNAL HAS RETURNED THE PROPER VALUE. IN BOTH CASES WE */ - /* DO NOT NEED TO ASSIGN IT HERE. */ - /*--------------------------------------------------------------*/ - ph2CLab(signal); - return; -}//Ndbcntr::execAPPL_REGCONF() - -/*--------------------------------------------------------------*/ -/* CHECK THAT WE GOT ALL NODES REGISTRATED AS WE NEED FOR THIS */ -/* KIND OF START. WE ALWAYS END UP HERE AFTER HANDLING OF */ -/* APPL_CHANGEREP AND NODE_STATESCONF */ -/*--------------------------------------------------------------*/ -void Ndbcntr::ph2CLab(Signal* signal) -{ - NodeRecPtr ownNodePtr; - ownNodePtr.i = getOwnNodeId(); - ptrCheckGuard(ownNodePtr, MAX_NDB_NODES, nodeRec); - if (ownNodePtr.p->state != ZADD) { + if(cmasterNodeId != getOwnNodeId()){ jam(); + sendCntrStartRef(signal, nodeId, CntrStartRef::NotMaster); return; - }//if - switch (ctypeOfStart) { - case NodeState::ST_INITIAL_START: + } + + const NodeState & nodeState = getNodeState(); + switch(nodeState.startLevel){ + case NodeState::SL_NOTHING: + case NodeState::SL_CMVMI: jam(); - if (cnoRegNodes == cnoNeedNodes) { - jam(); - ph2ELab(signal); -/*******************************/ -/* ALL NODES ADDED */ -/*******************************/ - return; - }//if + ndbrequire(false); + case NodeState::SL_STARTING: + case NodeState::SL_STARTED: + break; + + case NodeState::SL_STOPPING_1: + case NodeState::SL_STOPPING_2: + case NodeState::SL_STOPPING_3: + case NodeState::SL_STOPPING_4: + jam(); + sendCntrStartRef(signal, nodeId, CntrStartRef::StopInProgress); + return; + } + + /** + * Am I starting (or started) + */ + const bool starting = (nodeState.startLevel != NodeState::SL_STARTED); + + c_start.m_waiting.set(nodeId); + switch(st){ + case NodeState::ST_INITIAL_START: + c_start.m_withoutLog.set(nodeId); break; case NodeState::ST_SYSTEM_RESTART: - ndbrequire(cnoRunNodes == 0); - if (cnoRegNodes == cnoNdbNodes) { + c_start.m_withLog.set(nodeId); + if(starting && lastGci > c_start.m_lastGci){ jam(); - /*******************************/ - /* ALL NODES ADDED */ - /*******************************/ - ph2ELab(signal); + CntrStartRef * ref = (CntrStartRef*)signal->getDataPtrSend(); + ref->errorCode = CntrStartRef::NotMaster; + ref->masterNodeId = nodeId; + NodeReceiverGroup rg (NDBCNTR, c_start.m_waiting); + sendSignal(rg, GSN_CNTR_START_REF, signal, + CntrStartRef::SignalLength, JBB); return; - }//if - if (cwaitContinuebFlag == ZFALSE) { - if (cnoRegNodes == cnoNeedNodes) { - jam(); - /****************************************/ - /* ENOUGH NODES ADDED, WAIT CDELAY_START*/ - /****************************************/ - cwaitContinuebFlag = ZTRUE; - /*******************************/ - /* A DELAY SIGNAL TO MYSELF */ - /*******************************/ - signal->theData[0] = ZCONTINUEB_1; - sendSignalWithDelay(cownBlockref, GSN_CONTINUEB, - signal, cdelayStart * 1000, 1); - return; - }//if - }//if + } + if(starting){ + Uint32 i = c_start.m_logNodesCount++; + c_start.m_logNodes[i].m_nodeId = nodeId; + c_start.m_logNodes[i].m_lastGci = req->lastGci; + } break; case NodeState::ST_NODE_RESTART: case NodeState::ST_INITIAL_NODE_RESTART: - jam(); - if (cnoNeedNodes <= cnoRunNodes) { - /*----------------------------------------------*/ - /* GOT ALL RUNNING NODES */ - /* " =< " :NODES MAY HAVE FINISHED A NODERESTART*/ - /* WHILE WE WERE WAITING FOR NODE_STATESCONF */ - /*----------------------------------------------*/ - if (cnoRegNodes != (cnoRunNodes + 1)) { - jam(); - systemErrorLab(signal); - return; - }//if - getStartNodes(signal); - cwaitContinuebFlag = ZFALSE; - cstartProgressFlag = ZTRUE; - /*--------------------------------------------------------------*/ - /* IF SOMEONE ELSE IS PERFORMING NODERESTART THEN WE GOT A REF */ - /* AND WE HAVE TO MAKE A NEW NODE_STATESREQ */ - /*--------------------------------------------------------------*/ - sendCntrMasterreq(signal); - }//if - break; - default: - jam(); - systemErrorLab(signal); - return; - break; - }//switch - /*--------------------------------------------------------------*/ - /* WAIT FOR THE CONTINUEB SIGNAL */ - /* AND / OR MORE NODES TO REGISTER */ - /*--------------------------------------------------------------*/ - return; -}//Ndbcntr::ph2CLab() + case NodeState::ST_ILLEGAL_TYPE: + ndbrequire(false); + } -/*******************************/ -/* CONTINUEB */ -/*******************************/ -/*--------------------------------------------------------------*/ -/* WE COME HERE ONLY IN SYSTEM RESTARTS AND INITIAL START. FOR */ -/* INITIAL START WE HAVE ALREADY CALCULATED THE MASTER. FOR */ -/* SYSTEM RESTART WE NEED TO PERFORM A VOTING SCHEME TO AGREE */ -/* ON A COMMON MASTER. WE GET OUR VOTE FROM DIH AND THE RESTART */ -/* INFORMATION IN DIH. */ -/*--------------------------------------------------------------*/ -void Ndbcntr::ph2ELab(Signal* signal) -{ - cwaitContinuebFlag = ZFALSE; -/*--------------------------------------*/ -/* JMP TO THIS WHEN ENOUGH NO OF */ -/* NODES ADDED */ -/*--------------------------------------*/ -/*--------------------------------------*/ -/* IGNORE CONTINUEB SIGNAL */ -/* CONTINUEB SIGNALS WILL EXIT AT */ -/* SIGNAL RECEPTION */ -/*--------------------------------------*/ - if (cnoRegNodes >= cnoNeedNodes) { + const bool startInProgress = !c_start.m_starting.isclear(); + + if((starting && startInProgress) || (startInProgress && !parallellNR)){ jam(); - getStartNodes(signal); - if (ctypeOfStart == NodeState::ST_INITIAL_START) { - if (cmasterCandidateId != getOwnNodeId()) { - jam(); -/*--------------------------------------*/ -/* THIS NODE IS NOT THE MASTER */ -/* DON'T SEND ANY MORE CNTR_MASTERREQ */ -/* VOTE FOR MASTER */ -/*--------------------------------------*/ - cstartProgressFlag = ZTRUE; - sendCntrMasterreq(signal); - resetStartVariables(signal); - } else { - jam(); - masterreq020Lab(signal); - }//if - } else if (ctypeOfStart == NodeState::ST_SYSTEM_RESTART) { - jam(); -/*--------------------------------------------------------------*/ -/* WE START THE SELECTION OF MASTER PROCESS. IF WE HAVE NOT */ -/* COMPLETED THIS BEFORE THE TIME OUT WE WILL TRY A NEW RESTART.*/ -/*--------------------------------------------------------------*/ - cwaitContinuebFlag = ZTRUE; - cstartProgressFlag = ZVOTING; - for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { - jam(); - ptrAss(nodePtr, nodeRec); - if (nodePtr.p->state == ZADD) { - jam(); - signal->theData[0] = getOwnNodeId(); - signal->theData[1] = cmasterDihId; - signal->theData[2] = clastGci; - sendSignal(nodePtr.p->cntrBlockref, GSN_VOTE_MASTERORD, - signal, 3, JBB); - }//if - }//for - } else { - jam(); - systemErrorLab(signal); - }//if + // We're already starting together with a bunch of nodes + // Let this node wait... + return; + } + + if(starting){ + trySystemRestart(signal); } else { - jam(); -/*--------------------------------------------------------------*/ -/* TOO FEW NODES TO START */ -/* WE HAVE WAITED FOR THE GIVEN TIME OUT AND NOT ENOUGH NODES */ -/* HAS REGISTERED. WE WILL CRASH AND RENEW THE ATTEMPT TO START */ -/* THE SYSTEM. */ -/*--------------------------------------------------------------*/ - systemErrorLab(signal); - }//if + startWaitingNodes(signal); + } + return; -}//Ndbcntr::ph2ELab() +} -/*******************************/ -/* MASTER NODE CONFIRMS REQ */ -/* CNTR_MASTERCONF */ -/*******************************/ -void Ndbcntr::execCNTR_MASTERCONF(Signal* signal) -{ +void +Ndbcntr::startWaitingNodes(Signal * signal){ + +#if ! PARALLELL_NR + const Uint32 nodeId = c_start.m_waiting.find(0); + const Uint32 Tref = calcNdbCntrBlockRef(nodeId); + ndbrequire(nodeId != c_start.m_waiting.NotFound); + + NodeState::StartType nrType = NodeState::ST_NODE_RESTART; + if(c_start.m_withoutLog.get(nodeId)){ + nrType = NodeState::ST_INITIAL_NODE_RESTART; + } + + /** + * Let node perform restart + */ + CntrStartConf * conf = (CntrStartConf*)signal->getDataPtrSend(); + conf->noStartNodes = 1; + conf->startType = nrType; + conf->startGci = ~0; // Not used + conf->masterNodeId = getOwnNodeId(); + BitmaskImpl::clear(NdbNodeBitmask::Size, conf->startingNodes); + BitmaskImpl::set(NdbNodeBitmask::Size, conf->startingNodes, nodeId); + c_startedNodes.copyto(NdbNodeBitmask::Size, conf->startedNodes); + sendSignal(Tref, GSN_CNTR_START_CONF, signal, + CntrStartConf::SignalLength, JBB); + + c_start.m_waiting.clear(nodeId); + c_start.m_withLog.clear(nodeId); + c_start.m_withoutLog.clear(nodeId); + c_start.m_starting.set(nodeId); +#else + // Parallell nr + + c_start.m_starting = c_start.m_waiting; + c_start.m_waiting.clear(); + + CntrStartConf * conf = (CntrStartConf*)signal->getDataPtrSend(); + conf->noStartNodes = 1; + conf->startGci = ~0; // Not used + conf->masterNodeId = getOwnNodeId(); + c_start.m_starting.copyto(NdbNodeBitmask::Size, conf->startingNodes); + c_startedNodes.copyto(NdbNodeBitmask::Size, conf->startedNodes); + + char buf[100]; + if(!c_start.m_withLog.isclear()){ + ndbout_c("Starting nodes w/ log: %s", c_start.m_withLog.getText(buf)); + + NodeReceiverGroup rg(NDBCNTR, c_start.m_withLog); + conf->startType = NodeState::ST_NODE_RESTART; + + sendSignal(rg, GSN_CNTR_START_CONF, signal, + CntrStartConf::SignalLength, JBB); + } + + if(!c_start.m_withoutLog.isclear()){ + ndbout_c("Starting nodes wo/ log: %s", c_start.m_withoutLog.getText(buf)); + NodeReceiverGroup rg(NDBCNTR, c_start.m_withoutLog); + conf->startType = NodeState::ST_INITIAL_NODE_RESTART; + + sendSignal(rg, GSN_CNTR_START_CONF, signal, + CntrStartConf::SignalLength, JBB); + } + + c_start.m_waiting.clear(); + c_start.m_withLog.clear(); + c_start.m_withoutLog.clear(); +#endif +} + +void +Ndbcntr::sendCntrStartRef(Signal * signal, + Uint32 nodeId, CntrStartRef::ErrorCode code){ + CntrStartRef * ref = (CntrStartRef*)signal->getDataPtrSend(); + ref->errorCode = code; + ref->masterNodeId = cmasterNodeId; + sendSignal(calcNdbCntrBlockRef(nodeId), GSN_CNTR_START_REF, signal, + CntrStartRef::SignalLength, JBB); +} + +CheckNodeGroups::Output +Ndbcntr::checkNodeGroups(Signal* signal, const NdbNodeBitmask & mask){ + CheckNodeGroups* sd = (CheckNodeGroups*)&signal->theData[0]; + sd->blockRef = reference(); + sd->requestType = CheckNodeGroups::Direct | CheckNodeGroups::ArbitCheck; + sd->mask = mask; + EXECUTE_DIRECT(DBDIH, GSN_CHECKNODEGROUPSREQ, signal, + CheckNodeGroups::SignalLength); jamEntry(); + return (CheckNodeGroups::Output)sd->output; +} - CntrMasterConf * const cntrMasterConf = - (CntrMasterConf *)&signal->theData[0]; +bool +Ndbcntr::trySystemRestart(Signal* signal){ + /** + * System restart something + */ + const bool allNodes = c_start.m_waiting.equal(c_allDefinedNodes); + const bool allClusterNodes = c_start.m_waiting.equal(c_clusterNodes); + const Uint64 now = NdbTick_CurrentMillisecond(); - cnoStartNodes = cntrMasterConf->noStartNodes; - int index = 0; - unsigned i; - for (i = 1; i < MAX_NDB_NODES; i++) { + if(!allClusterNodes){ jam(); - if (NodeBitmask::get(cntrMasterConf->theNodes, i)) { - jam(); - cstartNodes[index] = i; - index++; - }//if - }//for - if (cnoStartNodes != index) { + return false; + } + + if(!allNodes && c_start.m_startPartialTimeout > now){ jam(); - systemErrorLab(signal); - }//if - ph2FLab(signal); - return; -}//Ndbcntr::execCNTR_MASTERCONF() + return false; + } -void Ndbcntr::ph2FLab(Signal* signal) -{ -/*--------------------------------------------------------------*/ -//The nodes have been selected and we now know which nodes are -// included in the system restart. We can reset wait for CONTINUEB -// flag to ensure system is not restarted when CONTINUEB after the -// delay. -/*--------------------------------------------------------------*/ - cmasterNodeId = cmasterCandidateId; - cwaitContinuebFlag = ZFALSE; - ph2GLab(signal); - return; -}//Ndbcntr::ph2FLab() + NodeState::StartType srType = NodeState::ST_SYSTEM_RESTART; + if(c_start.m_waiting.equal(c_start.m_withoutLog)){ + if(!allNodes){ + jam(); + return false; + } + srType = NodeState::ST_INITIAL_START; + c_start.m_starting = c_start.m_withoutLog; // Used for starting... + c_start.m_withoutLog.clear(); + } else { + + CheckNodeGroups::Output wLog = checkNodeGroups(signal, c_start.m_withLog); + + switch (wLog) { + case CheckNodeGroups::Win: + jam(); + break; + case CheckNodeGroups::Lose: + jam(); + // If we lose with all nodes, then we're in trouble + ndbrequire(!allNodes); + return false; + break; + case CheckNodeGroups::Partitioning: + jam(); + bool allowPartition = (c_start.m_startPartitionedTimeout != (Uint64)~0); + + if(allNodes){ + jam(); + if(allowPartition){ + jam(); + break; + } + ndbrequire(false); // All nodes -> partitioning, which is not allowed + } + + if(c_start.m_startPartitionedTimeout > now){ + jam(); + return false; + } + break; + } + + // For now only with the "logged"-ones. + // Let the others do node restart afterwards... + c_start.m_starting = c_start.m_withLog; + c_start.m_withLog.clear(); + } + + /** + * Okidoki, we try to start + */ + CntrStartConf * conf = (CntrStartConf*)signal->getDataPtr(); + conf->noStartNodes = c_start.m_starting.count(); + conf->startType = srType; + conf->startGci = c_start.m_lastGci; + conf->masterNodeId = c_start.m_lastGciNodeId; + c_start.m_starting.copyto(NdbNodeBitmask::Size, conf->startingNodes); + c_startedNodes.copyto(NdbNodeBitmask::Size, conf->startedNodes); + + ndbrequire(c_start.m_lastGciNodeId == getOwnNodeId()); + + NodeReceiverGroup rg(NDBCNTR, c_start.m_starting); + sendSignal(rg, GSN_CNTR_START_CONF, signal, CntrStartConf::SignalLength,JBB); + + c_start.m_waiting.bitANDC(c_start.m_starting); + + return true; +} -/*--------------------------------------*/ -/* RECEIVED CNTR_MASTERCONF */ -/*--------------------------------------*/ -/*******************************/ -/* NDB_STTORRY */ -/*******************************/ -/*---------------------------------------------------------------------------*/ -// NOW WE CAN START NDB START PHASE 1. IN THIS PHASE ALL BLOCKS -// (EXCEPT DIH THAT INITIALISED WHEN -// RECEIVING DIH_RESTARTREQ) WILL INITIALISE THEIR DATA, COMMON VARIABLES, -// LINKED LISTS AND RECORD VARIABLES. -/*---------------------------------------------------------------------------*/ void Ndbcntr::ph2GLab(Signal* signal) { if (cndbBlocksCount < ZNO_NDB_BLOCKS) { @@ -879,11 +874,6 @@ void Ndbcntr::ph2GLab(Signal* signal) /*******************************/ void Ndbcntr::startPhase3Lab(Signal* signal) { - cinternalStartphase = cstartPhase - 1; -/*--------------------------------------*/ -/* CASE: CSTART_PHASE = ZSTART_PHASE_3 */ -/*--------------------------------------*/ - cndbBlocksCount = 0; ph3ALab(signal); return; }//Ndbcntr::startPhase3Lab() @@ -893,29 +883,12 @@ void Ndbcntr::startPhase3Lab(Signal* signal) /*******************************/ void Ndbcntr::ph3ALab(Signal* signal) { - Uint16 tnoStartNodes; - if (cndbBlocksCount < ZNO_NDB_BLOCKS) { jam(); sendNdbSttor(signal); return; }//if -/*******************************/ -/*< APPL_STARTREG <*/ -/*******************************/ - if (ctypeOfStart == NodeState::ST_NODE_RESTART) { - jam(); - tnoStartNodes = 1; - } else if (ctypeOfStart == NodeState::ST_INITIAL_NODE_RESTART) { - jam(); - tnoStartNodes = 1; - } else { - jam(); - tnoStartNodes = cnoStartNodes; - }//if - signal->theData[0] = cqmgrConnectionP; - signal->theData[1] = tnoStartNodes; - sendSignal(cqmgrBlockref, GSN_APPL_STARTREG, signal, 2, JBB); + sendSttorry(signal); return; }//Ndbcntr::ph3ALab() @@ -933,49 +906,12 @@ void Ndbcntr::ph3ALab(Signal* signal) /*******************************/ void Ndbcntr::startPhase4Lab(Signal* signal) { - cinternalStartphase = cstartPhase - 1; -/*--------------------------------------*/ -/* CASE: CSTART_PHASE = ZSTART_PHASE_4 */ -/*--------------------------------------*/ - cndbBlocksCount = 0; - cnoWaitrep = 0; - if (capplStartconfFlag != ZTRUE) { - jam(); -/*------------------------------------------------------*/ -/* HAVE WE ALREADY RECEIVED APPL_STARTCONF */ -/*------------------------------------------------------*/ - return; - }//if ph4ALab(signal); - return; }//Ndbcntr::startPhase4Lab() -/*******************************/ -/* APPL_STARTCONF */ -/*******************************/ -void Ndbcntr::execAPPL_STARTCONF(Signal* signal) -{ - jamEntry(); - if (cstartPhase == ZSTART_PHASE_4) { - jam(); - ph4ALab(signal); - return; - } else { - jam(); - capplStartconfFlag = ZTRUE; -//------------------------------------------------ -/* FLAG WILL BE CHECKED WHEN WE RECEIVED STTOR */ -/* SIGNAL MAY BE RECEIVED IN STARTPHASE 3 */ -//------------------------------------------------ - return; - }//if -}//Ndbcntr::execAPPL_STARTCONF() void Ndbcntr::ph4ALab(Signal* signal) { - nodePtr.i = getOwnNodeId(); - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); - nodePtr.p->state = ZSTART; ph4BLab(signal); return; }//Ndbcntr::ph4ALab() @@ -1014,6 +950,7 @@ void Ndbcntr::waitpoint41Lab(Signal* signal) cnoWaitrep++; if (cnoWaitrep == cnoStartNodes) { jam(); + cnoWaitrep = 0; /*---------------------------------------------------------------------------*/ // NDB_STARTREQ STARTS UP ALL SET UP OF DISTRIBUTION INFORMATION IN DIH AND // DICT. AFTER SETTING UP THIS @@ -1025,9 +962,9 @@ void Ndbcntr::waitpoint41Lab(Signal* signal) // 3) EXECUTING THE FRAGMENT REDO LOG FROM ONE OR SEVERAL NODES TO // RESTORE THE RESTART CONFIGURATION OF DATA IN NDB CLUSTER. /*---------------------------------------------------------------------------*/ - signal->theData[0] = cownBlockref; + signal->theData[0] = reference(); signal->theData[1] = ctypeOfStart; - sendSignal(cdihBlockref, GSN_NDB_STARTREQ, signal, 2, JBB); + sendSignal(DBDIH_REF, GSN_NDB_STARTREQ, signal, 2, JBB); }//if } else { jam(); @@ -1037,11 +974,10 @@ void Ndbcntr::waitpoint41Lab(Signal* signal) /* SLAVES WONT DO ANYTHING UNTIL THEY */ /* RECEIVE A WAIT REPORT FROM THE MASTER*/ /*--------------------------------------*/ - nodePtr.i = cmasterNodeId; - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); signal->theData[0] = getOwnNodeId(); signal->theData[1] = ZWAITPOINT_4_1; - sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_WAITREP, signal, 2, JBB); + sendSignal(calcNdbCntrBlockRef(cmasterNodeId), + GSN_CNTR_WAITREP, signal, 2, JBB); }//if return; }//Ndbcntr::waitpoint41Lab() @@ -1052,23 +988,11 @@ void Ndbcntr::waitpoint41Lab(Signal* signal) void Ndbcntr::execNDB_STARTCONF(Signal* signal) { jamEntry(); - UintR guard0; - UintR Ttemp1; - guard0 = cnoStartNodes - 1; - arrGuard(guard0, MAX_NDB_NODES); - for (Ttemp1 = 0; Ttemp1 <= guard0; Ttemp1++) { - jam(); - if (cstartNodes[Ttemp1] != getOwnNodeId()) { - jam(); - nodePtr.i = cstartNodes[Ttemp1]; - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); - signal->theData[0] = getOwnNodeId(); - signal->theData[1] = ZWAITPOINT_4_2; - sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_WAITREP, signal, 2, JBB); - }//if - }//for - sendSttorry(signal); + NodeReceiverGroup rg(NDBCNTR, c_start.m_starting); + signal->theData[0] = getOwnNodeId(); + signal->theData[1] = ZWAITPOINT_4_2; + sendSignal(rg, GSN_CNTR_WAITREP, signal, 2, JBB); return; }//Ndbcntr::execNDB_STARTCONF() @@ -1084,9 +1008,6 @@ void Ndbcntr::execNDB_STARTCONF(Signal* signal) /*******************************/ void Ndbcntr::startPhase5Lab(Signal* signal) { - cinternalStartphase = cstartPhase - 1; - cndbBlocksCount = 0; - cnoWaitrep = 0; ph5ALab(signal); return; }//Ndbcntr::startPhase5Lab() @@ -1147,16 +1068,17 @@ void Ndbcntr::ph5ALab(Signal* signal) // SEND NDB START PHASE 5 IN NODE RESTARTS TO COPY DATA TO THE NEWLY // STARTED NODE. /*----------------------------------------------------------------------*/ - req->senderRef = cownBlockref; + req->senderRef = reference(); req->nodeId = getOwnNodeId(); req->internalStartPhase = cinternalStartphase; req->typeOfStart = ctypeOfStart; req->masterNodeId = cmasterNodeId; + //#define TRACE_STTOR #ifdef TRACE_STTOR ndbout_c("sending NDB_STTOR(%d) to DIH", cinternalStartphase); #endif - sendSignal(cdihBlockref, GSN_NDB_STTOR, signal, + sendSignal(DBDIH_REF, GSN_NDB_STTOR, signal, NdbSttor::SignalLength, JBB); return; case NodeState::ST_INITIAL_START: @@ -1170,11 +1092,10 @@ void Ndbcntr::ph5ALab(Signal* signal) /* RECEIVE A WAIT REPORT FROM THE MASTER*/ /* WHEN THE MASTER HAS FINISHED HIS WORK*/ /*--------------------------------------*/ - nodePtr.i = cmasterNodeId; - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); signal->theData[0] = getOwnNodeId(); signal->theData[1] = ZWAITPOINT_5_2; - sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_WAITREP, signal, 2, JBB); + sendSignal(calcNdbCntrBlockRef(cmasterNodeId), + GSN_CNTR_WAITREP, signal, 2, JBB); return; default: ndbrequire(false); @@ -1198,8 +1119,10 @@ void Ndbcntr::waitpoint52Lab(Signal* signal) /*--------------------------------------*/ if (cnoWaitrep == cnoStartNodes) { jam(); + cnoWaitrep = 0; + NdbSttor * const req = (NdbSttor*)signal->getDataPtrSend(); - req->senderRef = cownBlockref; + req->senderRef = reference(); req->nodeId = getOwnNodeId(); req->internalStartPhase = cinternalStartphase; req->typeOfStart = ctypeOfStart; @@ -1207,7 +1130,7 @@ void Ndbcntr::waitpoint52Lab(Signal* signal) #ifdef TRACE_STTOR ndbout_c("sending NDB_STTOR(%d) to DIH", cinternalStartphase); #endif - sendSignal(cdihBlockref, GSN_NDB_STTOR, signal, + sendSignal(DBDIH_REF, GSN_NDB_STTOR, signal, NdbSttor::SignalLength, JBB); }//if return; @@ -1218,28 +1141,19 @@ void Ndbcntr::waitpoint52Lab(Signal* signal) /*******************************/ void Ndbcntr::ph6ALab(Signal* signal) { - UintR guard0; - UintR Ttemp1; - if ((ctypeOfStart == NodeState::ST_NODE_RESTART) || (ctypeOfStart == NodeState::ST_INITIAL_NODE_RESTART)) { jam(); waitpoint51Lab(signal); return; }//if - guard0 = cnoStartNodes - 1; - arrGuard(guard0, MAX_NDB_NODES); - for (Ttemp1 = 0; Ttemp1 <= guard0; Ttemp1++) { - jam(); - if (cstartNodes[Ttemp1] != getOwnNodeId()) { - jam(); - nodePtr.i = cstartNodes[Ttemp1]; - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); - signal->theData[0] = getOwnNodeId(); - signal->theData[1] = ZWAITPOINT_5_1; - sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_WAITREP, signal, 2, JBB); - }//if - }//for + + NodeReceiverGroup rg(NDBCNTR, c_start.m_starting); + rg.m_nodes.clear(getOwnNodeId()); + signal->theData[0] = getOwnNodeId(); + signal->theData[1] = ZWAITPOINT_5_1; + sendSignal(rg, GSN_CNTR_WAITREP, signal, 2, JBB); + waitpoint51Lab(signal); return; }//Ndbcntr::ph6ALab() @@ -1283,28 +1197,18 @@ void Ndbcntr::waitpoint61Lab(Signal* signal) cnoWaitrep6++; if (cnoWaitrep6 == cnoStartNodes) { jam(); - Uint32 guard0 = cnoStartNodes - 1; - arrGuard(guard0, MAX_NDB_NODES); - for (Uint32 Ttemp1 = 0; Ttemp1 <= guard0; Ttemp1++) { - jam(); - if (cstartNodes[Ttemp1] != getOwnNodeId()) { - jam(); - nodePtr.i = cstartNodes[Ttemp1]; - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); - signal->theData[0] = getOwnNodeId(); - signal->theData[1] = ZWAITPOINT_6_2; - sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_WAITREP, signal, 2, JBB); - } - } + NodeReceiverGroup rg(NDBCNTR, c_start.m_starting); + rg.m_nodes.clear(getOwnNodeId()); + signal->theData[0] = getOwnNodeId(); + signal->theData[1] = ZWAITPOINT_6_2; + sendSignal(rg, GSN_CNTR_WAITREP, signal, 2, JBB); sendSttorry(signal); } } else { jam(); - nodePtr.i = cmasterNodeId; - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); signal->theData[0] = getOwnNodeId(); signal->theData[1] = ZWAITPOINT_6_1; - sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_WAITREP, signal, 2, JBB); + sendSignal(calcNdbCntrBlockRef(cmasterNodeId), GSN_CNTR_WAITREP, signal, 2, JBB); } } @@ -1339,28 +1243,18 @@ void Ndbcntr::waitpoint71Lab(Signal* signal) cnoWaitrep7++; if (cnoWaitrep7 == cnoStartNodes) { jam(); - Uint32 guard0 = cnoStartNodes - 1; - arrGuard(guard0, MAX_NDB_NODES); - for (Uint32 Ttemp1 = 0; Ttemp1 <= guard0; Ttemp1++) { - jam(); - if (cstartNodes[Ttemp1] != getOwnNodeId()) { - jam(); - nodePtr.i = cstartNodes[Ttemp1]; - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); - signal->theData[0] = getOwnNodeId(); - signal->theData[1] = ZWAITPOINT_7_2; - sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_WAITREP, signal, 2, JBB); - } - } + NodeReceiverGroup rg(NDBCNTR, c_start.m_starting); + rg.m_nodes.clear(getOwnNodeId()); + signal->theData[0] = getOwnNodeId(); + signal->theData[1] = ZWAITPOINT_7_2; + sendSignal(rg, GSN_CNTR_WAITREP, signal, 2, JBB); sendSttorry(signal); } } else { jam(); - nodePtr.i = cmasterNodeId; - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); signal->theData[0] = getOwnNodeId(); signal->theData[1] = ZWAITPOINT_7_1; - sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_WAITREP, signal, 2, JBB); + sendSignal(calcNdbCntrBlockRef(cmasterNodeId), GSN_CNTR_WAITREP, signal, 2, JBB); } } @@ -1378,315 +1272,11 @@ void Ndbcntr::ph8ALab(Signal* signal) // NODES WHICH PERFORM A NODE RESTART NEEDS TO GET THE DYNAMIC ID'S // OF THE OTHER NODES HERE. /*---------------------------------------------------------------------------*/ - signal->theData[0] = cqmgrConnectionP; - sendSignal(cqmgrBlockref, GSN_APPL_RUN, signal, 1, JBB); - nodePtr.i = getOwnNodeId(); - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); - nodePtr.p->state = ZRUN; - cnoRunNodes = cnoRunNodes + 1; sendSttorry(signal); - cstartProgressFlag = ZFALSE; - ctypeOfStart = (NodeState::StartType)ZSYSTEM_RUN; resetStartVariables(signal); return; }//Ndbcntr::ph8BLab() -/* -4.7 HANDLE GLOBAL EVENTS, NOT BOUNDED TO INITIALSTART OR SYSTEM RESTART */ -/*#######################################################################*/ -/*******************************/ -/* APPL_CHANGEREP */ -/*******************************/ -void Ndbcntr::execAPPL_CHANGEREP(Signal* signal) -{ - jamEntry(); - Uint16 TapplEvent = signal->theData[0]; - Uint16 TapplVersion = signal->theData[1]; - Uint16 TapplNodeId = signal->theData[2]; - Uint16 TapplSubType = signal->theData[3]; - - nodePtr.i = TapplNodeId; - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); - nodePtr.p->subType = TapplSubType; - nodePtr.p->ndbVersion = TapplVersion; - nodePtr.p->dynamicId = signal->theData[4]; - - switch (TapplEvent) { - case ZADD: -/*----------------------------*/ -/* ADD A NEW NDB NODE TO FILE */ -/*----------------------------*/ - if (nodePtr.p->state == ZREMOVE) { - jam(); - if (cnoRegNodes == cnoNdbNodes) { - jam(); -/*----------------------------------------------*/ -/* DON'T ACCEPT MORE NODES THAN SYSFILE.CFG SPEC*/ -/*----------------------------------------------*/ - systemErrorLab(signal); - return; - }//if - nodePtr.p->state = ZADD; - cnoRegNodes = cnoRegNodes + 1; - } else { - jam(); - systemErrorLab(signal); - return; - }//if - if (cstartProgressFlag == ZFALSE) { -/*----------------------------------------------*/ -/* FLAG = TRUE WHEN CNTR_MASTERREQ IS SENT */ -/*----------------------------------------------*/ - switch (ctypeOfStart) { - case NodeState::ST_INITIAL_START: - case NodeState::ST_SYSTEM_RESTART: - jam(); - ph2CLab(signal); -/*----------------------------------------------*/ -/* CHECK IF READY TO MAKE A CNTR_MASTERREQ */ -/*----------------------------------------------*/ - break; - case NodeState::ST_NODE_RESTART: - case NodeState::ST_INITIAL_NODE_RESTART: - jam(); -/*------------------------------------------------------------------------*/ -/* THIS SHOULD NEVER OCCUR SINCE WE HAVE ALREADY BEEN ALLOWED TO */ -/* START OUR NODE. THE NEXT NODE CANNOT START UNTIL WE ARE FINISHED */ -/*------------------------------------------------------------------------*/ - systemErrorLab(signal); - break; - case ZSYSTEM_RUN: - jam(); - /*empty*/; - break; - default: - jam(); -/*------------------------------------------------------------------------*/ -/* NO PARTICULAR ACTION IS NEEDED. THE NODE WILL PERFORM A NODE */ -/* RESTART BUT NO ACTION IS NEEDED AT THIS STAGE IN THE RESTART. */ -/*------------------------------------------------------------------------*/ - systemErrorLab(signal); - break; - }//switch - } else { - jam(); -/*--------------------------------------------------------------------------*/ -// WHEN A RESTART IS IN PROGRESS THERE IS A POSSIBILITY THAT A NODE -// REGISTER AND -// THINKS THAT HE WOULD BE THE MASTER (LOWER NODE ID) BUT THE OTHER NODE IS -// ALREADY RUNNING THE RESTART. THIS WILL BE DETECTED WHEN HE ATTEMPTS A -// CNTR_MASTERREQ AND RECEIVES A REFUSE SIGNAL IN RETURN. THIS WILL CAUSE HIM -// TO CRASH. IF HE ATTEMPTS TO JOIN AS A NON-MASTER HE WILL WAIT FOR THE MASTER. -// IN THIS CASE IT IS BETTER TO SHOT HIM DOWN. FOR SAFETY REASONS WE WILL ALWAYS -// SHOT HIM DOWN. -/*--------------------------------------------------------------------------*/ - const BlockReference tblockref = calcNdbCntrBlockRef(nodePtr.i); - - SystemError * const sysErr = (SystemError*)&signal->theData[0]; - sysErr->errorCode = SystemError::StartInProgressError; - sysErr->errorRef = reference(); - sendSignal(tblockref, GSN_SYSTEM_ERROR, signal, SystemError::SignalLength, JBA); - }//if - break; - case ZSTART: - jam(); - if (nodePtr.p->state != ZADD) { - jam(); - systemErrorLab(signal); - return; - }//if - nodePtr.p->state = ZSTART; - break; - case ZRUN: - if (nodePtr.p->state == ZREMOVE) { - jam(); - cnoRegNodes = cnoRegNodes + 1; - } else { - jam(); - if (nodePtr.p->state != ZSTART) { - jam(); -/*----------------------------------------------*/ -/* STATE ZADD OR ZRUN -> ZRUN NOT ALLOWED */ -/*----------------------------------------------*/ - systemErrorLab(signal); - return; - }//if - }//if - cnoRunNodes = cnoRunNodes + 1; - nodePtr.p->state = ZRUN; - switch (ctypeOfStart) { - case NodeState::ST_INITIAL_START: - jam(); - detectNoderestart(signal); - if (ctypeOfStart == NodeState::ST_NODE_RESTART) { - jam(); -/*--------------------------------------------------------------------------*/ -/* WE DISCOVERED THAT WE ARE TRYING TO PERFORM A INITIAL START WHEN THERE */ -/* ARE ALREADY RUNNING NODES. THIS MEANS THAT THE NODE HAS CLEANED THE */ -/* FILE SYSTEM AND CONTAINS NO DATA. THIS IS AN INITIAL NODE RESTART WHICH */ -/* IS NECESSARY TO START A NODE THAT HAS BEEN TAKEN OVER. */ -/*--------------------------------------------------------------------------*/ - ctypeOfStart = NodeState::ST_INITIAL_NODE_RESTART; - }//if - break; - case NodeState::ST_SYSTEM_RESTART: - jam(); - detectNoderestart(signal); -/*----------------------------------------------*/ -/* SHOULD THIS NODE PERFORM A NODE RESTART? */ -/* THEN CHANGE CTYPE_OF_START TO NodeState::ST_NODE_RESTART */ -/* AND SEND NODE_STATESREQ. */ -/* WAIT FOR NODE_STATESCONF. */ -/*----------------------------------------------*/ - break; - case NodeState::ST_NODE_RESTART: - case NodeState::ST_INITIAL_NODE_RESTART: - jam(); -/*----------------------------------------------*/ -/* IF WE ARE WAITING FOR NODE_STATESCONF, THIS */ -/* JUMP WILL EXIT BECAUSE CNO_NEED_NODES = ZNIL */ -/* UNTIL WE RECEIVE NODE_STATESCONF */ -/*----------------------------------------------*/ - ph2CLab(signal); - break; - case ZSYSTEM_RUN: - jam(); - break; - default: - jam(); - systemErrorLab(signal); - break; - }//switch - break; - default: - jam(); - systemErrorLab(signal); - break; - }//switch - return; -}//Ndbcntr::execAPPL_CHANGEREP() - -/*--------------------------------------------------------------------------*/ -// A NODE HAS ADDED HAS VOTE ON WHICH MASTER IS TO BE CHOOSEN IN A SYSTEM -// RESTART. WHEN ALL VOTES HAVE -// BEEN ADDED THEN WE ARE PREPARED TO CHOOSE MASTER AND CONTINUE WITH THE -// RESTART PROCESSING. -/*--------------------------------------------------------------------------*/ - -/*******************************/ -/* VOT_MASTERORD */ -/*******************************/ -void Ndbcntr::execVOTE_MASTERORD(Signal* signal) -{ - jamEntry(); - nodePtr.i = signal->theData[0]; - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); - UintR TmasterCandidateId = signal->theData[1]; - UintR TlastGci = signal->theData[2]; - if (ctypeOfStart != NodeState::ST_SYSTEM_RESTART) { - jam(); - progError(__LINE__, - ERR_SR_RESTARTCONFLICT, - "One ore more nodes probably requested an initial SR"); - return; - }//if - cmasterVoters = cmasterVoters + 1; - if (cmasterVoters == 1) { - jam(); - cmasterCurrentId = TmasterCandidateId; - cmasterLastGci = TlastGci; - } else { - if (cmasterLastGci < TlastGci) { - jam(); - cmasterCurrentId = TmasterCandidateId; - cmasterLastGci = TlastGci; - } else if (cmasterLastGci == TlastGci) { - jam(); - if (cmasterCurrentId != TmasterCandidateId) { - jam(); - systemErrorLab(signal); - return; - }//if - }//if - }//if - if (cstartProgressFlag == ZVOTING) { -/*--------------------------------------------------------------------------*/ -// UNLESS START PROGRESS FLAG IS SET TO VOTING WE HAVE NOT YET REACHED A -// STATE WHERE WE ARE READY TO -// PROCEED WITH THE SYSTEM RESTART. OUR OWN NOTE HAVE AT LEAST NOT BEEN -// CAST INTO THE BALLOT YET. -/*--------------------------------------------------------------------------*/ - if (cmasterVoters == cnoRegNodes) { - cmasterCandidateId = cmasterCurrentId; - if (cmasterCandidateId == getOwnNodeId()) { - jam(); - masterreq020Lab(signal); - return; - } else { - jam(); - cstartProgressFlag = ZTRUE; - sendCntrMasterreq(signal); - resetStartVariables(signal); - }//if - }//if - }//if - return; -}//Ndbcntr::execVOTE_MASTERORD() - -/*******************************/ -/* CNTR_MASTERREQ */ -/*******************************/ -void Ndbcntr::execCNTR_MASTERREQ(Signal* signal) -{ - Uint16 ttypeOfStart; - - jamEntry(); - - CntrMasterReq * const cntrMasterReq = - (CntrMasterReq *)&signal->theData[0]; - -//----------------------------------------------- -// cntrMasterReq->userBlockRef NOT USED -//----------------------------------------------- - Uint16 TuserNodeId = cntrMasterReq->userNodeId; - ttypeOfStart = cntrMasterReq->typeOfStart; - Uint16 TnoRestartNodes = cntrMasterReq->noRestartNodes; - int index = 0; - unsigned i; - for (i = 1; i < MAX_NDB_NODES; i++) { - jam(); - if (NodeBitmask::get(cntrMasterReq->theNodes, i)) { - jam(); - cstartNodes[index] = i; - index++; - }//if - }//for - if (TnoRestartNodes != index) { - jam(); - systemErrorLab(signal); - }//if - switch (ttypeOfStart) { - case NodeState::ST_INITIAL_START: - case NodeState::ST_SYSTEM_RESTART: - jam(); -//-------------------------------- -/* ELECTION OF MASTER AT */ -/* INITIAL OR SYSTEM RESTART */ -//-------------------------------- - masterreq010Lab(signal, TnoRestartNodes, TuserNodeId); - break; - case NodeState::ST_NODE_RESTART: - case NodeState::ST_INITIAL_NODE_RESTART: - jam(); - masterreq030Lab(signal, TnoRestartNodes, TuserNodeId); - break; - default: - jam(); - systemErrorLab(signal); - break; - }//switch -}//Ndbcntr::execCNTR_MASTERREQ() - /*******************************/ /* CNTR_WAITREP */ /*******************************/ @@ -1736,243 +1326,102 @@ void Ndbcntr::execCNTR_WAITREP(Signal* signal) }//switch }//Ndbcntr::execCNTR_WAITREP() -/* -4.7.4 MASTERREQ_010 ( CASE: INITIALSTART OR SYSTEMRESTART ) */ -/*--------------------------------------------------------------------------*/ -// ELECTION OF MASTER AND ELECTION OF PARTICIPANTS IN START. SENDER OF -// CNTR_MASTERREQ THINKS THAT THIS NODE -// SHOULD BE THE MASTER. WE CAN'T MAKE A DECISION ABOUT WHO THE MASTER -// SHOULD BE UNTIL TIMELIMIT HAS EXPIRED AND -// THAT AT LEAST CNO_NEED_NODES ARE ZADD IN NODE_PTR_REC. IF THIS NODE IS -// MASTER THEN MAKE SURE THAT ALL NODES IN -// THE CLUSTER COMES TO AN AGREEMENT ABOUT A SUBSET OF NODES THAT SATISFIES -// THE NUMBER CNO_NEED_NODES. THERE IS -// A POSSIBILITY THAT THE RECEIVER OF CNTR_MASTERREQ DOESN'T HAS CHOOSEN -// A MASTER, THEN THE RECEIVER CAN'T -// EITHER CONFIRM OR REFUSE JUST STORE THE VOTES OF THE CLUSTERMEMBERS. -// IF THIS NODE BECOME AWARE OF THAT ANOTHER NODE IS MASTER THEN CHECK IF -// ANYONE HAS VOTED (SENT CNTR_MASTERREQ) */ -// AND THEN SEND THEM CNTR_MASTERREF BACK. -/*--------------------------------------------------------------------------*/ -void Ndbcntr::masterreq010Lab(Signal* signal, - Uint16 TnoRestartNodes, - Uint16 TuserNodeId) -{ - UintR guard0; - UintR Ttemp1; - - nodePtr.i = TuserNodeId; - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); - if (cstartProgressFlag == ZTRUE) { - jam(); -/*--------------------------------------*/ -/* RESTART ALREADY IN PROGRESS */ -/*--------------------------------------*/ - if (ctypeOfStart == NodeState::ST_INITIAL_START) { - jam(); - systemErrorLab(signal); - return; - }//if - signal->theData[0] = cownBlockref; - signal->theData[1] = getOwnNodeId(); - signal->theData[2] = ZSTART_IN_PROGRESS_ERROR; - sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_MASTERREF, signal, 3, JBB); - return; - }//if - cnoVoters = cnoVoters + 1; - nodePtr.p->voter = ZTRUE; - guard0 = TnoRestartNodes - 1; - arrGuard(guard0, MAX_NDB_NODES); - for (Ttemp1 = 0; Ttemp1 <= guard0; Ttemp1++) { - jam(); - nodePtr.i = cstartNodes[Ttemp1]; - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); - nodePtr.p->votes = nodePtr.p->votes + 1; - }//for - masterreq020Lab(signal); - return; -}//Ndbcntr::masterreq010Lab() - -/*----------------------------------------------------------------------*/ -/* WHEN WE JUST WANT TO CHECK OUR VOTES IT IS POSSIBLE TO JUMP TO THIS */ -/* LABEL. IF WE HAVEN'T RECEIVED ANY VOTES SINCE OUR LASTCHECK WE WILL */ -/* JUST PERFORM AN EXIT */ -/*----------------------------------------------------------------------*/ -void Ndbcntr::masterreq020Lab(Signal* signal) -{ - if (cmasterCandidateId == ZNIL) { - jam(); -/*--------------------------------------*/ -/* MASTER UNKNOWN */ -/*--------------------------------------*/ - return; - } else if (cmasterCandidateId == getOwnNodeId()) { - jam(); -/*--------------------------------------*/ -/* SATISFIED WHEN WE HAVE AS MANY VOTERS*/ -/* AS RESTARTNODES - 1, DIFFERENT NODES?*/ -/* <- CNO_START_NODES, ALL NODES AGREED */ -/* ON THESE CNO_START_NODES */ -/*--------------------------------------*/ - if ((cnoStartNodes - 1) == cnoVoters) { - chooseRestartNodes(signal); - if (cnoStartNodes >= cnoNeedNodes) { - jam(); - cstartProgressFlag = ZTRUE; -/*--------------------------------------*/ -/* DON'T SEND ANY MORE CNTR_MASTERREQ */ -/*--------------------------------------*/ - replyMasterconfToAll(signal); -/*--------------------------------------*/ -/* SEND CONF TO ALL PASSED REQ */ -/* DON'T SEND ANYTHING TO REJECTED NODES*/ -/* BLOCK THEM UNTIL SYSTEM IS RUNNING */ -/* CONTINUE RESTART */ -/*--------------------------------------*/ - ph2FLab(signal); - } else { - jam(); - systemErrorLab(signal); - }//if - }//if - } else { - jam(); -/*----------------------------------------------------------------------*/ -/* WE RECEIVED A REQUEST TO A MASTER WHILE NOT BEING MASTER. THIS */ -/* MUST BE AN ERROR INDICATION. WE CRASH. */ -/*----------------------------------------------------------------------*/ - systemErrorLab(signal); - }//if - return; /* WAIT FOR MORE CNTR_MASTERREQ */ -}//Ndbcntr::masterreq020Lab() - -void Ndbcntr::masterreq030Lab(Signal* signal, - Uint16 TnoRestartNodes, - Uint16 TuserNodeId) -{ - UintR TretCode; - if (cmasterNodeId == getOwnNodeId()) { - jam(); - TretCode = checkNodelist(signal, TnoRestartNodes); - nodePtr.i = TuserNodeId; - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); - if (TretCode == 1) { - jam(); -/*******************************************************<*/ -/* CSTART_NODES IS OVERWRITTEN IN RECEIVING BLOCK, */ -/* SO WE MUST SEND CNTR_MASTERCONF TO THE SAME */ -/* CSTART_NODES AS WE RECEIVED IN CNTR_MASTERREQ */ -/*******************************************************<*/ - - CntrMasterConf * const cntrMasterConf = - (CntrMasterConf *)&signal->theData[0]; - NodeBitmask::clear(cntrMasterConf->theNodes); - for (int i = 0; i < TnoRestartNodes; i++){ - jam(); - UintR Tnode = cstartNodes[i]; - arrGuard(Tnode, MAX_NDB_NODES); - NodeBitmask::set(cntrMasterConf->theNodes, Tnode); - }//for - cntrMasterConf->noStartNodes = TnoRestartNodes; - sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_MASTERCONF, - signal, CntrMasterConf::SignalLength, JBB); - } else { - jam(); - signal->theData[0] = cownBlockref; - signal->theData[1] = getOwnNodeId(); - signal->theData[2] = ZTOO_FEW_NODES; - sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_MASTERREF, signal, 3, JBB); - }//if - } else { - jam(); - nodePtr.i = TuserNodeId; - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); - signal->theData[0] = cownBlockref; - signal->theData[1] = getOwnNodeId(); - signal->theData[2] = ZNOT_MASTER; - sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_MASTERREF, signal, 3, JBB); - }//if - return; -}//Ndbcntr::masterreq030Lab() - /*******************************/ /* NODE_FAILREP */ /*******************************/ void Ndbcntr::execNODE_FAILREP(Signal* signal) { - UintR TfailureNr; - UintR TnoOfNodes; - UintR TreadNodes[MAX_NDB_NODES]; - jamEntry(); + const NodeFailRep * nodeFail = (NodeFailRep *)&signal->theData[0]; + NdbNodeBitmask allFailed; + allFailed.assign(NdbNodeBitmask::Size, nodeFail->theNodes); + + NdbNodeBitmask failedStarted = c_startedNodes; + NdbNodeBitmask failedStarting = c_start.m_starting; + NdbNodeBitmask failedWaiting = c_start.m_waiting; + + failedStarted.bitAND(allFailed); + failedStarting.bitAND(allFailed); + failedWaiting.bitAND(allFailed); + + const bool tMasterFailed = allFailed.get(cmasterNodeId); + const bool tStarted = !failedStarted.isclear(); + const bool tStarting = !failedStarting.isclear(); + const bool tWaiting = !failedWaiting.isclear(); + + if(tMasterFailed){ + jam(); + /** + * If master has failed choose qmgr president as master + */ + cmasterNodeId = nodeFail->masterNodeId; + } + + /** + * Clear node bitmasks from failed nodes + */ + c_start.m_starting.bitANDC(allFailed); + c_start.m_waiting.bitANDC(allFailed); + c_start.m_withLog.bitANDC(allFailed); + c_start.m_withoutLog.bitANDC(allFailed); + c_clusterNodes.bitANDC(allFailed); + c_startedNodes.bitANDC(allFailed); + const NodeState & st = getNodeState(); if(st.startLevel == st.SL_STARTING){ - if(!st.getNodeRestartInProgress()){ + jam(); + + const Uint32 phase = st.starting.startPhase; + + const bool tStartConf = (phase > 2) || (phase == 2 && cndbBlocksCount > 0); + + if(tMasterFailed){ progError(__LINE__, ERR_SR_OTHERNODEFAILED, - "Unhandled node failure during system restart"); + "Unhandled node failure during restart"); + } + + if(tStartConf && tStarting){ + // One of other starting nodes has crashed... + progError(__LINE__, + ERR_SR_OTHERNODEFAILED, + "Unhandled node failure of starting node during restart"); } - } - - { - NodeFailRep * const nodeFail = (NodeFailRep *)&signal->theData[0]; - TfailureNr = nodeFail->failNo; - TnoOfNodes = nodeFail->noOfNodes; - unsigned index = 0; - unsigned i; - for (i = 0; i < MAX_NDB_NODES; i++) { - jam(); - if (NodeBitmask::get(nodeFail->theNodes, i)) { - jam(); - TreadNodes[index] = i; - index++; - ndbrequire(getOwnNodeId() != i); - }//if + if(tStartConf && tStarted){ + // One of other started nodes has crashed... + progError(__LINE__, + ERR_SR_OTHERNODEFAILED, + "Unhandled node failure of started node during restart"); + } + + Uint32 nodeId = 0; + while(!allFailed.isclear()){ + nodeId = allFailed.find(nodeId + 1); + allFailed.clear(nodeId); + signal->theData[0] = nodeId; + sendSignal(QMGR_REF, GSN_NDB_FAILCONF, signal, 1, JBB); }//for - ndbrequire(TnoOfNodes == index); + + return; } - for (Uint32 i = 0; i < TnoOfNodes; i++) { - jam(); - nodePtr.i = TreadNodes[i]; - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); - signal->theData[0] = EventReport::NODE_FAILREP; - signal->theData[1] = nodePtr.i; - signal->theData[2] = nodePtr.p->state; - sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB); - if (nodePtr.p->state != ZREMOVE) { - jam(); - deleteNode(signal); - }//if - }//for + ndbrequire(!allFailed.get(getOwnNodeId())); -/*******************************/ -/*< NODE_FAILREP <*/ -/*******************************/ - NodeFailRep * const nodeFail = (NodeFailRep *)&signal->theData[0]; - - nodeFail->failNo = TfailureNr; - nodeFail->masterNodeId = cmasterNodeId; + NodeFailRep * rep = (NodeFailRep *)&signal->theData[0]; + rep->masterNodeId = cmasterNodeId; - nodeFail->noOfNodes = TnoOfNodes; - NodeBitmask::clear(nodeFail->theNodes); - for (unsigned i = 0; i < TnoOfNodes; i++) { - jam(); - NodeBitmask::set(nodeFail->theNodes, TreadNodes[i]); - }//for - - sendSignal(ctcBlockref, GSN_NODE_FAILREP, signal, + sendSignal(DBTC_REF, GSN_NODE_FAILREP, signal, NodeFailRep::SignalLength, JBB); - sendSignal(clqhBlockref, GSN_NODE_FAILREP, signal, + sendSignal(DBLQH_REF, GSN_NODE_FAILREP, signal, NodeFailRep::SignalLength, JBB); - sendSignal(cdihBlockref, GSN_NODE_FAILREP, signal, + sendSignal(DBDIH_REF, GSN_NODE_FAILREP, signal, NodeFailRep::SignalLength, JBB); - sendSignal(cdictBlockref, GSN_NODE_FAILREP, signal, + sendSignal(DBDICT_REF, GSN_NODE_FAILREP, signal, NodeFailRep::SignalLength, JBB); sendSignal(BACKUP_REF, GSN_NODE_FAILREP, signal, @@ -1983,80 +1432,25 @@ void Ndbcntr::execNODE_FAILREP(Signal* signal) sendSignal(GREP_REF, GSN_NODE_FAILREP, signal, NodeFailRep::SignalLength, JBB); - return; -}//Ndbcntr::execNODE_FAILREP() -/*******************************/ -/* NODE_STATESCONF */ -/*******************************/ -void Ndbcntr::execNODE_STATESCONF(Signal* signal) -{ - jamEntry(); - cmasterCandidateId = signal->theData[0]; - cnoNeedNodes = signal->theData[1]; -/*----------------------------------------------------------------------*/ -// Now that we have knowledge of how many nodes are needed we will call -// ph2CLab to ensure that node restart continues if we already received -// all APPL_CHANGEREP signals. -/*----------------------------------------------------------------------*/ - ph2CLab(signal); - return; -}//Ndbcntr::execNODE_STATESCONF() - -/*******************************/ -/* NODE_STATESREF */ -/*******************************/ -void Ndbcntr::execNODE_STATESREF(Signal* signal) -{ - jamEntry(); - systemErrorLab(signal); - return; -}//Ndbcntr::execNODE_STATESREF() + Uint32 nodeId = 0; + while(!allFailed.isclear()){ + nodeId = allFailed.find(nodeId + 1); + allFailed.clear(nodeId); + signal->theData[0] = EventReport::NODE_FAILREP; + signal->theData[1] = nodeId; + signal->theData[2] = 0; + sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB); + }//for -/*******************************/ -/* NODE_STATESREQ */ -/*******************************/ -void Ndbcntr::execNODE_STATESREQ(Signal* signal) -{ - UintR TnoNeedNodes = 0; - NodeRecPtr TNodePtr; - jamEntry(); - BlockReference TuserBlockref = signal->theData[0]; -/*----------------------------------------------------------------------*/ -// IF WE ARE RUNNING, WE WILL ANSWER THIS SIGNAL WITH THE AMOUNT OF NODES -// THAT ARE IN THE RUN STATE OR START STATE. -/*----------------------------------------------------------------------*/ - TNodePtr.i = getOwnNodeId(); - ptrCheckGuard(TNodePtr, MAX_NDB_NODES, nodeRec); - if (TNodePtr.p->state == ZRUN) { - jam(); - for (TNodePtr.i = 1; TNodePtr.i < MAX_NDB_NODES; TNodePtr.i++) { - jam(); - ptrAss(TNodePtr, nodeRec); - if ((TNodePtr.p->state == ZRUN) || - (TNodePtr.p->state == ZSTART)) { - jam(); - TnoNeedNodes++; - }//if - }//for - signal->theData[0] = cmasterNodeId; - signal->theData[1] = TnoNeedNodes; - sendSignal(TuserBlockref, GSN_NODE_STATESCONF, signal, 2, JBB); - } else { - jam(); - signal->theData[0] = ZERROR_NOT_RUNNING; - sendSignal(TuserBlockref, GSN_NODE_STATESREF, signal, 1, JBB); - }//if return; -}//Ndbcntr::execNODE_STATESREQ() +}//Ndbcntr::execNODE_FAILREP() /*******************************/ /* READ_NODESREQ */ /*******************************/ void Ndbcntr::execREAD_NODESREQ(Signal* signal) { - UintR TnoNodes = 0; - NodeRecPtr TNodePtr; jamEntry(); /*----------------------------------------------------------------------*/ @@ -2067,59 +1461,36 @@ void Ndbcntr::execREAD_NODESREQ(Signal* signal) BlockReference TuserBlockref = signal->theData[0]; ReadNodesConf * const readNodes = (ReadNodesConf *)&signal->theData[0]; - if (cstartPhase > ZSTART_PHASE_2) { - ndbrequire(cstartProgressFlag == ZTRUE); - - NodeBitmask::clear(readNodes->allNodes); - NodeBitmask::clear(readNodes->inactiveNodes); - - /** - * Add started nodes - */ - for (int i = 0; i < cnoStartNodes; i++){ - jam(); - TNodePtr.i = cstartNodes[i]; - ptrCheckGuard(TNodePtr, MAX_NDB_NODES, nodeRec); - - NodeBitmask::set(readNodes->allNodes, TNodePtr.i); - readNodes->setVersionId(TNodePtr.i, TNodePtr.p->ndbVersion, - readNodes->theVersionIds); - TnoNodes++; - }//for - - /** - * Sometimes add myself - */ - if ((ctypeOfStart == NodeState::ST_NODE_RESTART) || - (ctypeOfStart == NodeState::ST_INITIAL_NODE_RESTART)) { - jam(); - - NodeBitmask::set(readNodes->allNodes, getOwnNodeId()); - readNodes->setVersionId(getOwnNodeId(), NDB_VERSION, - readNodes->theVersionIds); - TnoNodes++; - }//if - /** - * Check all nodes which are defined but not already added - */ - for (TNodePtr.i = 1; TNodePtr.i < MAX_NDB_NODES; TNodePtr.i++) { - jam(); - ptrAss(TNodePtr, nodeRec); - if ((TNodePtr.p->nodeDefined == ZTRUE) && - (NodeBitmask::get(readNodes->allNodes, TNodePtr.i) == false)){ - jam(); + /** + * Prepare inactiveNodes bitmask. + * The concept as such is by the way pretty useless. + * It makes parallell starts more or less impossible... + */ + NdbNodeBitmask tmp1; + tmp1.bitOR(c_startedNodes); + if(!getNodeState().getNodeRestartInProgress()){ + tmp1.bitOR(c_start.m_starting); + } else { + tmp1.set(getOwnNodeId()); + } - NodeBitmask::set(readNodes->allNodes, TNodePtr.i); - NodeBitmask::set(readNodes->inactiveNodes, TNodePtr.i); - readNodes->setVersionId(TNodePtr.i, NDB_VERSION, - readNodes->theVersionIds); - - TnoNodes++; - }//if - }//for - - readNodes->noOfNodes = TnoNodes; - readNodes->masterNodeId = cmasterNodeId; + NdbNodeBitmask tmp2; + tmp2.bitOR(c_allDefinedNodes); + tmp2.bitANDC(tmp1); + /** + * Fill in return signal + */ + tmp2.copyto(NdbNodeBitmask::Size, readNodes->inactiveNodes); + c_allDefinedNodes.copyto(NdbNodeBitmask::Size, readNodes->allNodes); + c_clusterNodes.copyto(NdbNodeBitmask::Size, readNodes->clusterNodes); + c_startedNodes.copyto(NdbNodeBitmask::Size, readNodes->startedNodes); + c_start.m_starting.copyto(NdbNodeBitmask::Size, readNodes->startingNodes); + + readNodes->noOfNodes = c_allDefinedNodes.count(); + readNodes->masterNodeId = cmasterNodeId; + readNodes->ndynamicId = cdynamicNodeId; + if (cstartPhase > ZSTART_PHASE_2) { + jam(); sendSignal(TuserBlockref, GSN_READ_NODESCONF, signal, ReadNodesConf::SignalLength, JBB); @@ -2237,8 +1608,8 @@ void Ndbcntr::startInsertTransactions(Signal* signal) ckey = 1; ctransidPhase = ZTRUE; - signal->theData[1] = cownBlockref; - sendSignal(ctcBlockref, GSN_TCSEIZEREQ, signal, 2, JBB); + signal->theData[1] = reference(); + sendSignal(DBTC_REF, GSN_TCSEIZEREQ, signal, 2, JBB); return; }//Ndbcntr::startInsertTransactions() @@ -2312,7 +1683,7 @@ void Ndbcntr::crSystab7Lab(Signal* signal) AttributeHeader::init(&tAIDataPtr[2], 1, 2); tAIDataPtr[3] = (tkey << 16); tAIDataPtr[4] = 1; - sendSignal(ctcBlockref, GSN_TCKEYREQ, signal, + sendSignal(DBTC_REF, GSN_TCKEYREQ, signal, TcKeyReq::StaticLength + 6, JBB); }//for ckey = ckey + RowsPerCommit; @@ -2335,7 +1706,7 @@ void Ndbcntr::execTCKEYCONF(Signal* signal) Uint32 transId2 = keyConf->transId2; signal->theData[0] = transId1; signal->theData[1] = transId2; - sendSignal(ctcBlockref, GSN_TC_COMMIT_ACK, signal, 2, JBB); + sendSignal(DBTC_REF, GSN_TC_COMMIT_ACK, signal, 2, JBB); }//if cresponses = cresponses + TcKeyConf::getNoOfOperations(confInfo); @@ -2363,8 +1734,8 @@ void Ndbcntr::crSystab8Lab(Signal* signal) return; }//if signal->theData[0] = ctcConnectionP; - signal->theData[1] = cownBlockref; - sendSignal(ctcBlockref, GSN_TCRELEASEREQ, signal, 2, JBB); + signal->theData[1] = reference(); + sendSignal(DBTC_REF, GSN_TCRELEASEREQ, signal, 2, JBB); return; }//Ndbcntr::crSystab8Lab() @@ -2380,8 +1751,8 @@ void Ndbcntr::execTCRELEASECONF(Signal* signal) void Ndbcntr::crSystab9Lab(Signal* signal) { - signal->theData[1] = cownBlockref; - sendSignalWithDelay(cdihBlockref, GSN_GETGCIREQ, signal, 100, 2); + signal->theData[1] = reference(); + sendSignalWithDelay(DBDIH_REF, GSN_GETGCIREQ, signal, 100, 2); return; }//Ndbcntr::crSystab9Lab() @@ -2435,309 +1806,28 @@ void Ndbcntr::execTCSEIZEREF(Signal* signal) return; }//Ndbcntr::execTCSEIZEREF() -/* -4.10 SUBROUTINES */ -/*##########################################################################*/ -/* -4.10.1 CHECK_NODELIST */ -/*---------------------------------------------------------------------------*/ -/*CHECK THAT ALL THE NEW NODE HAS DETECTED ALL RUNNING NODES */ -/*INPUT: CSTART_NODES */ -/* TNO_RESTART_NODES */ -/* TUSER_NODE_ID */ -/*RET: CNODE_RESTART */ -/*---------------------------------------------------------------------------*/ -UintR Ndbcntr::checkNodelist(Signal* signal, Uint16 TnoRestartNodes) -{ - UintR guard1; - UintR Ttemp1; - - if (cnoRunNodes == TnoRestartNodes) { - jam(); - guard1 = TnoRestartNodes - 1; - arrGuard(guard1, MAX_NDB_NODES); - for (Ttemp1 = 0; Ttemp1 <= guard1; Ttemp1++) { - jam(); - nodePtr.i = cstartNodes[Ttemp1]; - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); - if (nodePtr.p->state != ZRUN) { - jam(); - return 0; - }//if - }//for - return 1; - }//if - return 0; -}//Ndbcntr::checkNodelist() - -/*---------------------------------------------------------------------------*/ -// SELECT NODES THAT ARE IN THE STATE TO PERFORM A INITIALSTART OR -// SYSTEMRESTART. -// THIS SUBROUTINE CAN ONLY BE INVOKED BY THE MASTER NODE. -// TO BE CHOOSEN A NODE NEED AS MANY VOTES AS THERE ARE VOTERS, AND OF -// COURSE THE NODE HAS TO BE KNOWN BY THE -// MASTER -// INPUT: NODE_REC -// CNO_NEED_NODES -// RETURN:CNO_START_NODES -// CSTART_NODES -/*---------------------------------------------------------------------------*/ -void Ndbcntr::chooseRestartNodes(Signal* signal) -{ - cnoStartNodes = 0; - for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { - ptrAss(nodePtr, nodeRec); - if (nodePtr.p->votes == cnoVoters) { - jam(); - if (nodePtr.p->state == ZADD) { - jam(); - arrGuard(cnoStartNodes, MAX_NDB_NODES); - cstartNodes[cnoStartNodes] = nodePtr.i; - cnoStartNodes++; - }//if - } else { - jam(); - if (nodePtr.p->votes > 0) { - jam(); - systemErrorLab(signal); - return; - }//if - }//if - }//for -}//Ndbcntr::chooseRestartNodes() - -/* -4.10.6 DELETE_NODE */ -/*---------------------------------------------------------------------------*/ -// INPUT: NODE_PTR -/*---------------------------------------------------------------------------*/ -void Ndbcntr::deleteNode(Signal* signal) -{ - UintR tminDynamicId; - - if (nodePtr.p->state == ZRUN) { - jam(); - cnoRunNodes = cnoRunNodes - 1; - }//if - nodePtr.p->state = ZREMOVE; - nodePtr.p->votes = 0; - nodePtr.p->voter = ZFALSE; - cnoRegNodes--; - if (nodePtr.i == cmasterNodeId) { - jam(); - cmasterNodeId = ZNIL; -/*---------------------------------------------------------------------------*/ -// IF MASTER HAVE CRASHED WE NEED TO SELECT A NEW MASTER. -/*---------------------------------------------------------------------------*/ - for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { - jam(); - ptrAss(nodePtr, nodeRec); - if (nodePtr.p->state == ZRUN) { - if (cmasterNodeId == ZNIL) { - jam(); - cmasterNodeId = nodePtr.i; - tminDynamicId = nodePtr.p->dynamicId; - } else { - jam(); - if (nodePtr.p->dynamicId < tminDynamicId) { - jam(); - cmasterNodeId = nodePtr.i; - tminDynamicId = nodePtr.p->dynamicId; - }//if - }//if - }//if - }//for - }//if -}//Ndbcntr::deleteNode() - -/*---------------------------------------------------------------------------*/ -// A NEW NODE TRIES TO DETECT A NODE RESTART. NodeState::ST_NODE_RESTART IS A POSSIBLE -// STATE ONLY WHEN THE SYSTEM IS RUNNING. -// IF THE SYSTEM IS RUNNING THEN -// CTYPE_OF_START = NodeState::ST_SYSTEM_RESTART UNTIL THE FIRST NODE HAS REGISTERED. -// IF SYSTEM IS */ -// RUNNING THE FIRST NODE TO REGISTER WILL BE ZRUN AND CTYPE_OF_START -// WILL BE CHANGED */ -// TO NodeState::ST_NODE_RESTART AT PH_2C. WHEN A NodeState::ST_NODE_RESTART IS DETECTED THE NEW NODE -// HAS TO SEND */ -// A CNTR_MASTERREQ TO THE MASTER -/*---------------------------------------------------------------------------*/ -void Ndbcntr::detectNoderestart(Signal* signal) -{ - NodeRecPtr ownNodePtr; - ownNodePtr.i = getOwnNodeId(); - ptrCheckGuard(ownNodePtr, MAX_NDB_NODES, nodeRec); - if (ownNodePtr.p->state != ZADD) { - if (ownNodePtr.p->state != ZREMOVE) { - jam(); - return; - }//if - }//if - ctypeOfStart = NodeState::ST_NODE_RESTART; -/*----------------------------------------------*/ -/* THIS NODE WILL PERFORM A NODE RESTART */ -/* REQUEST OF ALL NODES STATES IN SYSTEM */ -// The purpose of this signal is to ensure that -// the starting node knows when it has received -// all APPL_CHANGEREP signals and thus can continue -// to the next step of the node restart. Thus we -// need to know the amount of nodes that are in the -// RUN state and in the START state (more than one -// node can be copying data simultaneously in the -// cluster. -/*----------------------------------------------*/ - signal->theData[0] = cownBlockref; - sendSignal(nodePtr.p->cntrBlockref, GSN_NODE_STATESREQ, signal, 1, JBB); - cnoNeedNodes = ZNIL; -/*---------------------------------*/ -/* PREVENT TO SEND NODE_STATESREQ */ -/*---------------------------------------------------------------------------*/ -/* WE NEED TO WATCH THE NODE RESTART WITH A TIME OUT TO NOT WAIT FOR EVER. */ -/*---------------------------------------------------------------------------*/ - cwaitContinuebFlag = ZTRUE; - signal->theData[0] = ZCONTINUEB_1; - sendSignalWithDelay(cownBlockref, GSN_CONTINUEB, signal, 3 * 1000, 1); -}//Ndbcntr::detectNoderestart() - -/*---------------------------------------------------------------------------*/ -// SCAN NODE_REC FOR APPROPRIATE NODES FOR A START. -// SYSTEMRESTART AND INITALSTART DEMANDS NODES OF STATE ZADD. -// NODERESTART DEMANDS NODE OF THE STATE ZRUN. -// INPUT: CTYPE_OF_START, NODE_REC -// RETURN: CSTART_NODES(), CNO_START_NODES, CMASTER_CANDIDATE_ID -// (SYSTEMRESTART AND INITALSTART) -/*---------------------------------------------------------------------------*/ -void Ndbcntr::getStartNodes(Signal* signal) -{ - UintR Ttemp1; - if ((ctypeOfStart == NodeState::ST_NODE_RESTART) || - (ctypeOfStart == NodeState::ST_INITIAL_NODE_RESTART)) { - jam(); - Ttemp1 = ZRUN; - } else { - jam(); -/*---------------------------------*/ -/* SYSTEM RESTART AND INITIAL START*/ -/*---------------------------------*/ - Ttemp1 = ZADD; - }//if - cnoStartNodes = 0; - for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { - jam(); - ptrAss(nodePtr, nodeRec); - if (nodePtr.p->state == Ttemp1) { - jam(); - cstartNodes[cnoStartNodes] = nodePtr.i;/*OVERWRITTEN AT CNTR_MASTERCONF*/ - cnoStartNodes++; - }//if - }//for -}//Ndbcntr::getStartNodes() /*---------------------------------------------------------------------------*/ /*INITIALIZE VARIABLES AND RECORDS */ /*---------------------------------------------------------------------------*/ void Ndbcntr::initData(Signal* signal) { - cmasterNodeId = ZNIL; - cmasterCandidateId = ZNIL; - cmasterVoters = 0; - cstartProgressFlag = ZFALSE; - capplStartconfFlag = ZFALSE; - cnoVoters = 0; + c_start.reset(); + cmasterNodeId = 0; cnoStartNodes = 0; - for (nodePtr.i = 0; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { - ptrAss(nodePtr, nodeRec); - nodePtr.p->cntrBlockref = calcNdbCntrBlockRef(nodePtr.i); - nodePtr.p->state = ZREMOVE; - nodePtr.p->dynamicId = 0; - nodePtr.p->votes = 0; /* USED BY MASTER */ - nodePtr.p->voter = ZFALSE; /* USED BY MASTER */ - nodePtr.p->masterReq = ZFALSE; /* USED BY MASTER */ - }//for + cnoWaitrep = 0; }//Ndbcntr::initData() -/*---------------------------------------------------------------------------*/ -// THE MASTER NODE HAS CHOOSEN THE NODES WHO WERE QUALIFIED TO -// PARTICIPATE IN A INITIALSTART OR SYSTEMRESTART. -// THIS SUBROTINE SENDS A CNTR_MASTERCONF TO THESE NODES -/*---------------------------------------------------------------------------*/ -void Ndbcntr::replyMasterconfToAll(Signal* signal) -{ - if (cnoStartNodes > 1) { - /** - * Construct a MasterConf signal - */ - - CntrMasterConf * const cntrMasterConf = - (CntrMasterConf *)&signal->theData[0]; - NodeBitmask::clear(cntrMasterConf->theNodes); - - cntrMasterConf->noStartNodes = cnoStartNodes; - - for(int i = 0; i<cnoStartNodes; i++) - NodeBitmask::set(cntrMasterConf->theNodes, cstartNodes[i]); - - /** - * Then distribute it to everyone but myself - */ - for(int i = 0; i<cnoStartNodes; i++){ - const NodeId nodeId = cstartNodes[i]; - if(nodeId != getOwnNodeId()){ - sendSignal(numberToRef(number(), nodeId), - GSN_CNTR_MASTERCONF, - signal, CntrMasterConf::SignalLength, JBB); - } - } - } -}//Ndbcntr::replyMasterconfToAll() /*---------------------------------------------------------------------------*/ /*RESET VARIABLES USED DURING THE START */ /*---------------------------------------------------------------------------*/ void Ndbcntr::resetStartVariables(Signal* signal) { - for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { - ptrAss(nodePtr, nodeRec); - nodePtr.p->votes = 0; - nodePtr.p->voter = ZFALSE; - nodePtr.p->masterReq = ZFALSE; - }//for - cnoVoters = 0; cnoStartNodes = 0; cnoWaitrep6 = cnoWaitrep7 = 0; }//Ndbcntr::resetStartVariables() -/*---------------------------------------------------------------------------*/ -// SENDER OF THIS SIGNAL HAS CHOOSEN A MASTER NODE AND SENDS A REQUEST -// TO THE MASTER_CANDIDATE AS AN VOTE FOR -// THE MASTER. THE SIGNAL ALSO INCLUDES VOTES FOR NODES WHICH SENDER -// THINKS SHOULD PARTICIPATE IN THE START. -// INPUT: CNO_START_NODES -// CSTART_NODES -/*---------------------------------------------------------------------------*/ -void Ndbcntr::sendCntrMasterreq(Signal* signal) -{ - nodePtr.i = cmasterCandidateId; - ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); -/*--------------------------------------------------------------*/ -/* O:INITIALSTART, 1:SYSTEMRESTART (ELECTION OF MASTER) */ -/* 2:NODE RESTART (SENDER NODE NOT INCLUDED IN CSTART_NODES) */ -/*--------------------------------------------------------------*/ - CntrMasterReq * const cntrMasterReq = (CntrMasterReq*)&signal->theData[0]; - NodeBitmask::clear(cntrMasterReq->theNodes); - for (int i = 0; i < cnoStartNodes; i++){ - jam(); - UintR Tnode = cstartNodes[i]; - arrGuard(Tnode, MAX_NDB_NODES); - NodeBitmask::set(cntrMasterReq->theNodes, Tnode); - }//for - cntrMasterReq->userBlockRef = cownBlockref; - cntrMasterReq->userNodeId = getOwnNodeId(); - cntrMasterReq->typeOfStart = ctypeOfStart; - cntrMasterReq->noRestartNodes = cnoStartNodes; - sendSignal(nodePtr.p->cntrBlockref, GSN_CNTR_MASTERREQ, - signal, CntrMasterReq::SignalLength, JBB); -}//Ndbcntr::sendCntrMasterreq() /*---------------------------------------------------------------------------*/ // SEND THE SIGNAL @@ -2745,25 +1835,24 @@ void Ndbcntr::sendCntrMasterreq(Signal* signal) /*---------------------------------------------------------------------------*/ void Ndbcntr::sendNdbSttor(Signal* signal) { - CfgBlockRecPtr cfgBlockPtr; NdbBlocksRecPtr ndbBlocksPtr; ndbBlocksPtr.i = cndbBlocksCount; ptrCheckGuard(ndbBlocksPtr, ZSIZE_NDB_BLOCKS_REC, ndbBlocksRec); - cfgBlockPtr.i = cinternalStartphase; - ptrCheckGuard(cfgBlockPtr, ZSIZE_CFG_BLOCK_REC, cfgBlockRec); + NdbSttor * const req = (NdbSttor*)signal->getDataPtrSend(); - req->senderRef = cownBlockref; + req->senderRef = reference(); req->nodeId = getOwnNodeId(); req->internalStartPhase = cinternalStartphase; req->typeOfStart = ctypeOfStart; req->masterNodeId = cmasterNodeId; for (int i = 0; i < 16; i++) { - req->config[i] = cfgBlockPtr.p->cfgData[i]; + // Garbage + req->config[i] = 0x88776655; + //cfgBlockPtr.p->cfgData[i]; } - //#define TRACE_STTOR //#define MAX_STARTPHASE 2 #ifdef TRACE_STTOR ndbout_c("sending NDB_STTOR(%d) to %s", @@ -2779,9 +1868,6 @@ void Ndbcntr::sendNdbSttor(Signal* signal) /*---------------------------------------------------------------------------*/ void Ndbcntr::sendSttorry(Signal* signal) { - signal->theData[0] = csignalKey; - signal->theData[1] = 3; - signal->theData[2] = 2; signal->theData[3] = ZSTART_PHASE_1; signal->theData[4] = ZSTART_PHASE_2; signal->theData[5] = ZSTART_PHASE_3; @@ -2801,9 +1887,8 @@ Ndbcntr::execDUMP_STATE_ORD(Signal* signal) DumpStateOrd * const & dumpState = (DumpStateOrd *)&signal->theData[0]; if(signal->theData[0] == 13){ infoEvent("Cntr: cstartPhase = %d, cinternalStartphase = %d, block = %d", - cstartPhase, cinternalStartphase, cndbBlocksCount); - infoEvent("Cntr: cmasterNodeId = %d, cmasterCandidateId = %d", - cmasterNodeId, cmasterCandidateId); + cstartPhase, cinternalStartphase, cndbBlocksCount); + infoEvent("Cntr: cmasterNodeId = %d", cmasterNodeId); } if (dumpState->args[0] == DumpStateOrd::NdbcntrTestStopOnError){ @@ -2823,6 +1908,7 @@ Ndbcntr::execDUMP_STATE_ORD(Signal* signal) }//Ndbcntr::execDUMP_STATE_ORD() void Ndbcntr::execSET_VAR_REQ(Signal* signal) { +#if 0 SetVarReq* const setVarReq = (SetVarReq*)&signal->theData[0]; ConfigParamId var = setVarReq->variable(); @@ -2835,6 +1921,7 @@ void Ndbcntr::execSET_VAR_REQ(Signal* signal) { default: sendSignal(CMVMI_REF, GSN_SET_VAR_REF, signal, 1, JBB); }// switch +#endif }//Ndbcntr::execSET_VAR_REQ() void Ndbcntr::updateNodeState(Signal* signal, const NodeState& newState) const{ @@ -2947,7 +2034,7 @@ Ndbcntr::execSTOP_REQ(Signal* signal){ } updateNodeState(signal, newState); signal->theData[0] = ZSHUTDOWN; - sendSignalWithDelay(cownBlockref, GSN_CONTINUEB, signal, 100, 1); + sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 1); } void @@ -2991,14 +2078,9 @@ Ndbcntr::StopRecord::checkNodeFail(Signal* signal){ /** * Check if I can survive me stopping */ - NodeBitmask ndbMask; ndbMask.clear(); - NodeRecPtr aPtr; - for(aPtr.i = 1; aPtr.i < MAX_NDB_NODES; aPtr.i++){ - ptrAss(aPtr, cntr.nodeRec); - if(aPtr.i != cntr.getOwnNodeId() && aPtr.p->state == ZRUN){ - ndbMask.set(aPtr.i); - } - } + NodeBitmask ndbMask; + ndbMask.assign(cntr.c_startedNodes); + ndbMask.clear(cntr.getOwnNodeId()); CheckNodeGroups* sd = (CheckNodeGroups*)&signal->theData[0]; sd->blockRef = cntr.reference(); @@ -3194,7 +2276,7 @@ void Ndbcntr::execSTOP_ME_CONF(Signal* signal){ c_stopRec.stopInitiatedTime = NdbTick_CurrentMillisecond(); signal->theData[0] = ZSHUTDOWN; - sendSignalWithDelay(cownBlockref, GSN_CONTINUEB, signal, 100, 1); + sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 1); } void @@ -3255,6 +2337,11 @@ void Ndbcntr::execSTTORRY(Signal* signal){ c_missra.execSTTORRY(signal); } +void Ndbcntr::execREAD_CONFIG_CONF(Signal* signal){ + jamEntry(); + c_missra.execREAD_CONFIG_CONF(signal); +} + void Ndbcntr::execSTART_ORD(Signal* signal){ jamEntry(); ndbrequire(NO_OF_BLOCKS == ALL_BLOCKS_SZ); @@ -3299,7 +2386,38 @@ void Ndbcntr::Missra::execSTART_ORD(Signal* signal){ signal->theData[0] = EventReport::NDBStartStarted; signal->theData[1] = NDB_VERSION; cntr.sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB); + + currentBlockIndex = 0; + sendNextREAD_CONFIG_REQ(signal); +} + +void Ndbcntr::Missra::sendNextREAD_CONFIG_REQ(Signal* signal){ + + if(currentBlockIndex < ALL_BLOCKS_SZ){ + jam(); + + ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtrSend(); + req->senderData = 0; + req->senderRef = cntr.reference(); + req->noOfParameters = 0; + + const BlockReference ref = ALL_BLOCKS[currentBlockIndex].Ref; + +#if 0 + ndbout_c("sending READ_CONFIG_REQ to %s(ref=%x index=%d)", + getBlockName( refToBlock(ref)), + ref, + currentBlockIndex); +#endif + + cntr.sendSignal(ref, GSN_READ_CONFIG_REQ, signal, + ReadConfigReq::SignalLength, JBB); + return; + } + /** + * Finished... + */ currentStartPhase = 0; for(Uint32 i = 0; i<NO_OF_BLOCKS; i++){ if(ALL_BLOCKS[i].NextSP < currentStartPhase) @@ -3307,10 +2425,19 @@ void Ndbcntr::Missra::execSTART_ORD(Signal* signal){ } currentBlockIndex = 0; - sendNextSTTOR(signal); } +void Ndbcntr::Missra::execREAD_CONFIG_CONF(Signal* signal){ + const ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtr(); + + const Uint32 ref = conf->senderRef; + ndbrequire(refToBlock(ALL_BLOCKS[currentBlockIndex].Ref) == refToBlock(ref)); + + currentBlockIndex++; + sendNextREAD_CONFIG_REQ(signal); +} + void Ndbcntr::Missra::execSTTORRY(Signal* signal){ const BlockReference ref = signal->senderBlockRef(); ndbrequire(refToBlock(ref) == refToBlock(ALL_BLOCKS[currentBlockIndex].Ref)); @@ -3365,8 +2492,8 @@ void Ndbcntr::Missra::sendNextSTTOR(Signal* signal){ currentBlockIndex); #endif - cntr.sendSignal(ref, GSN_STTOR, - signal, 8, JBB); + cntr.sendSignal(ref, GSN_STTOR, signal, 8, JBB); + return; } } @@ -3391,4 +2518,136 @@ void Ndbcntr::Missra::sendNextSTTOR(Signal* signal){ NodeState newState(NodeState::SL_STARTED); cntr.updateNodeState(signal, newState); + + /** + * Backward + */ + UpgradeStartup::sendCmAppChg(cntr, signal, 3); //RUN + + NdbNodeBitmask nodes = cntr.c_clusterNodes; + Uint32 node = 0; + while((node = nodes.find(node+1)) != NdbNodeBitmask::NotFound){ + if(cntr.getNodeInfo(node).m_version < MAKE_VERSION(3,5,0)){ + nodes.clear(node); + } + } + + NodeReceiverGroup rg(NDBCNTR, nodes); + signal->theData[0] = cntr.getOwnNodeId(); + cntr.sendSignal(rg, GSN_CNTR_START_REP, signal, 1, JBB); +} + +/** + * Backward compatible code + */ +void +UpgradeStartup::sendCmAppChg(Ndbcntr& cntr, Signal* signal, Uint32 startLevel){ + + signal->theData[0] = startLevel; + signal->theData[1] = cntr.getOwnNodeId(); + signal->theData[2] = 3 | ('N' << 8); + signal->theData[3] = 'D' | ('B' << 8); + signal->theData[4] = 0; + signal->theData[5] = 0; + signal->theData[6] = 0; + signal->theData[7] = 0; + signal->theData[8] = 0; + signal->theData[9] = 0; + signal->theData[10] = 0; + signal->theData[11] = 0; + + NdbNodeBitmask nodes = cntr.c_clusterNodes; + nodes.clear(cntr.getOwnNodeId()); + Uint32 node = 0; + while((node = nodes.find(node+1)) != NdbNodeBitmask::NotFound){ + if(cntr.getNodeInfo(node).m_version < MAKE_VERSION(3,5,0)){ + cntr.sendSignal(cntr.calcQmgrBlockRef(node), + GSN_CM_APPCHG, signal, 12, JBB); + } else { + cntr.c_startedNodes.set(node); // Fake started + } + } +} + +void +UpgradeStartup::execCM_APPCHG(SimulatedBlock & block, Signal* signal){ + Uint32 state = signal->theData[0]; + Uint32 nodeId = signal->theData[1]; + if(block.number() == QMGR){ + Ndbcntr& cntr = * (Ndbcntr*)globalData.getBlock(CNTR); + switch(state){ + case 0: // ZADD + break; + case 2: // ZSTART + break; + case 3: // ZRUN{ + cntr.c_startedNodes.set(nodeId); + + Uint32 recv = cntr.c_startedNodes.count(); + Uint32 cnt = cntr.c_clusterNodes.count(); + if(recv + 1 == cnt){ //+1 == own node + /** + * Check master + */ + sendCntrMasterReq(cntr, signal, 0); + } + return; + } + } + block.progError(0,0); +} + +void +UpgradeStartup::sendCntrMasterReq(Ndbcntr& cntr, Signal* signal, Uint32 n){ + Uint32 node = cntr.c_startedNodes.find(n); + if(node != NdbNodeBitmask::NotFound && + (node == cntr.getOwnNodeId() || + cntr.getNodeInfo(node).m_version >= MAKE_VERSION(3,5,0))){ + node = cntr.c_startedNodes.find(node+1); + } + + if(node == NdbNodeBitmask::NotFound){ + cntr.progError(0,0); + } + + CntrMasterReq * const cntrMasterReq = (CntrMasterReq*)&signal->theData[0]; + cntr.c_clusterNodes.copyto(NdbNodeBitmask::Size, cntrMasterReq->theNodes); + NdbNodeBitmask::clear(cntrMasterReq->theNodes, cntr.getOwnNodeId()); + cntrMasterReq->userBlockRef = 0; + cntrMasterReq->userNodeId = cntr.getOwnNodeId(); + cntrMasterReq->typeOfStart = NodeState::ST_INITIAL_NODE_RESTART; + cntrMasterReq->noRestartNodes = cntr.c_clusterNodes.count() - 1; + cntr.sendSignal(cntr.calcNdbCntrBlockRef(node), GSN_CNTR_MASTERREQ, + signal, CntrMasterReq::SignalLength, JBB); +} + +void +UpgradeStartup::execCNTR_MASTER_REPLY(SimulatedBlock & block, Signal* signal){ + Uint32 gsn = signal->header.theVerId_signalNumber; + Uint32 node = refToNode(signal->getSendersBlockRef()); + if(block.number() == CNTR){ + Ndbcntr& cntr = (Ndbcntr&)block; + switch(gsn){ + case GSN_CNTR_MASTERREF: + sendCntrMasterReq(cntr, signal, node + 1); + return; + break; + case GSN_CNTR_MASTERCONF:{ + CntrStartConf* conf = (CntrStartConf*)signal->getDataPtrSend(); + conf->startGci = 0; + conf->masterNodeId = node; + conf->noStartNodes = 1; + conf->startType = NodeState::ST_INITIAL_NODE_RESTART; + NodeBitmask mask; + mask.clear(); + mask.copyto(NdbNodeBitmask::Size, conf->startedNodes); + mask.clear(); + mask.set(cntr.getOwnNodeId()); + mask.copyto(NdbNodeBitmask::Size, conf->startingNodes); + cntr.execCNTR_START_CONF(signal); + return; + } + } + } + block.progError(0,0); } diff --git a/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp b/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp index 36322ffad1e..c763d3b4786 100644 --- a/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp +++ b/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp @@ -60,10 +60,11 @@ Ndbfs::Ndbfs(const Configuration & conf) : theFileSystemPath = conf.fileSystemPath(); theRequestPool = new Pool<Request>; - const Properties * p = conf.getOwnProperties(); + const ndb_mgm_configuration_iterator * p = conf.getOwnConfigIterator(); ndbrequire(p != 0); - ndbrequire(p->get("MaxNoOfOpenFiles", &m_maxFiles)); + m_maxOpenedFiles = 40; + //ndb_mgm_get_int_parameter(p, CFG_DB_MAX_OPEN_FILES, &m_maxFiles); // Create idle AsyncFiles Uint32 noIdleFiles = 16; diff --git a/ndb/src/kernel/blocks/qmgr/Qmgr.hpp b/ndb/src/kernel/blocks/qmgr/Qmgr.hpp index 7d2abd34ebe..0ff7cea6d9f 100644 --- a/ndb/src/kernel/blocks/qmgr/Qmgr.hpp +++ b/ndb/src/kernel/blocks/qmgr/Qmgr.hpp @@ -22,6 +22,8 @@ #include <NdbTick.h> #include <SimulatedBlock.hpp> #include <NodeBitmask.hpp> +#include <SignalCounter.hpp> + #include <signaldata/EventReport.hpp> #include <signaldata/ArbitSignalData.hpp> #include <signaldata/CmRegSignalData.hpp> @@ -33,24 +35,10 @@ #ifdef QMGR_C #define NO_REG_APP 1 -/* Boolean flags --------------------------------*/ -#define ZNULL 0xfffe /* Delay values, ms -----------------------------*/ #define ZDELAY_REGREQ 1000 -/* Phase of QMGR node ------------------------*/ -#define ZINIT 1 /* All nodes start in phase INIT */ -#define ZWAITING 2 /* Node is connecting to cluster */ -#define ZRUNNING 3 /* Node is running in the cluster */ -#define ZBLOCKED 4 /* Node is blocked from the cluster */ -#define ZWAIT_PRESIDENT 5 -#define ZDEAD 6 -#define ZAPI_ACTIVE 7 /* API IS RUNNING IN NODE */ -#define ZFAIL_CLOSING 8 /* API/NDB IS DISCONNECTING */ -#define ZPREPARE_FAIL 9 /* PREPARATION FOR FAILURE */ -#define ZAPI_INACTIVE 10 /* Inactive API */ - /* Type of refuse in CM_NODEINFOREF -------------*/ #define ZNOT_RUNNING 0 @@ -100,18 +88,40 @@ public: WAITING_FOR_FAILCONF2 = 2, WAITING_FOR_NDB_FAILCONF = 3 }; + + enum Phase { + ZINIT = 1, /* All nodes start in phase INIT */ + ZSTARTING = 2, /* Node is connecting to cluster */ + ZRUNNING = 3, /* Node is running in the cluster */ + ZPREPARE_FAIL = 4, /* PREPARATION FOR FAILURE */ + ZFAIL_CLOSING = 5, /* API/NDB IS DISCONNECTING */ + ZAPI_ACTIVE = 6, /* API IS RUNNING IN NODE */ + ZAPI_INACTIVE = 7 /* Inactive API */ + }; + + struct StartRecord { + void reset(){ m_startKey++; m_startNode = 0;} + Uint32 m_startKey; + Uint32 m_startNode; + Uint64 m_startTimeout; + + Uint32 m_gsn; + SignalCounter m_nodes; + } c_start; + + NdbNodeBitmask c_definedNodes; // DB nodes in config + NdbNodeBitmask c_clusterNodes; // DB nodes in cluster + NodeBitmask c_connectedNodes; // All kinds of connected nodes + Uint32 c_maxDynamicId; // Records struct NodeRec { UintR ndynamicId; - UintR phase; + Phase phase; UintR alarmCount; - bool m_connected; QmgrState sendPrepFailReqStatus; QmgrState sendCommitFailReqStatus; - QmgrState sendCmAddPrepStatus; - QmgrState sendCmAddCommitStatus; QmgrState sendPresToStatus; FailState failState; BlockReference rcv[2]; // remember which failconf we have received @@ -122,18 +132,6 @@ public: typedef Ptr<NodeRec> NodeRecPtr; - struct RegApp { - NdbNodeBitmask m_runNodes; - char name[15 + 1]; - UintR noofapps; - UintR noofpending; - BlockReference blockref; - Uint16 version; - Uint16 activity; - }; - - typedef Ptr<RegApp> RegAppPtr; - enum ArbitState { ARBIT_NULL = 0, ARBIT_INIT = 1, // create new ticket @@ -191,7 +189,6 @@ private: void execCM_HEARTBEAT(Signal* signal); void execCM_ADD(Signal* signal); void execCM_ACKADD(Signal* signal); - void execCM_APPCHG(Signal* signal); void execCM_REGREQ(Signal* signal); void execCM_REGCONF(Signal* signal); void execCM_REGREF(Signal* signal); @@ -214,10 +211,6 @@ private: void execCONNECT_REP(Signal* signal); void execNDB_FAILCONF(Signal* signal); void execSTTOR(Signal* signal); - void execAPPL_REGREQ(Signal* signal); - void execAPPL_STARTREG(Signal* signal); - void execAPPL_RUN(Signal* signal); - void execCM_INIT(Signal* signal); void execCM_INFOCONF(Signal* signal); void execCLOSE_COMCONF(Signal* signal); void execAPI_REGREQ(Signal* signal); @@ -242,53 +235,31 @@ private: // Statement blocks void node_failed(Signal* signal, Uint16 aFailedNode); void checkStartInterface(Signal* signal); - void applchangerep(Signal* signal, - UintR aRegApp, - Uint16 aNode, - UintR aType, - UintR aVersion); - void cmappAdd(Signal* signal, - UintR aRegApp, - Uint16 aNode, - UintR aType, - UintR aVersion); - void cmappStart(Signal* signal, - UintR aRegApp, - Uint16 aNode, - UintR aType, - UintR aVersion); void failReport(Signal* signal, Uint16 aFailedNode, UintR aSendFailRep, FailRep::FailCause failCause); void findNeighbours(Signal* signal); Uint16 translateDynamicIdToNodeId(Signal* signal, UintR TdynamicId); - UintR getDynamicId(Signal* signal); + void initData(Signal* signal); - void prepareAdd(Signal* signal, Uint16 addNode); - void sendappchg(Signal* signal, UintR aRegApp, Uint16 aNode); void sendCloseComReq(Signal* signal, BlockReference TBRef, Uint16 TfailNo); void sendPrepFailReq(Signal* signal, Uint16 aNode); void sendApiFailReq(Signal* signal, Uint16 aFailedNode); void sendApiRegRef(Signal*, Uint32 ref, ApiRegRef::ErrorCode); // Generated statement blocks + void startphase1(Signal* signal); void electionWon(); void cmInfoconf010Lab(Signal* signal); void apiHbHandlingLab(Signal* signal); void timerHandlingLab(Signal* signal); void hbReceivedLab(Signal* signal); - void cmAdd010Lab(Signal* signal); - void cmAckadd010Lab(Signal* signal); - void cmAppchg010Lab(Signal* signal); void sendCmRegrefLab(Signal* signal, BlockReference ref, CmRegRef::ErrorCode); void systemErrorBecauseOtherNodeFailed(Signal* signal, NodeId); void systemErrorLab(Signal* signal, const char* message = NULL); - void cmRegref010Lab(Signal* signal); - void cmNodeinforeq010Lab(Signal* signal); - void cmNodeinfoconf010Lab(Signal* signal); void prepFailReqLab(Signal* signal); void prepFailConfLab(Signal* signal); void prepFailRefLab(Signal* signal); @@ -300,13 +271,10 @@ private: void presToConfLab(Signal* signal); void sendSttorryLab(Signal* signal); void sttor020Lab(Signal* signal); - void applRegreq010Lab(Signal* signal); - void applStartreg010Lab(Signal* signal); - void applRun010Lab(Signal* signal); - void cmInit010Lab(Signal* signal); void closeComConfLab(Signal* signal); void apiRegReqLab(Signal* signal); - void regreqTimelimitLab(Signal* signal, UintR callTime); + void regreqTimeLimitLab(Signal* signal); + void regreqTimeMasterLimitLab(Signal* signal); void cmRegreq010Lab(Signal* signal); void cmRegconf010Lab(Signal* signal); void sttor010Lab(Signal* signal); @@ -347,6 +315,12 @@ private: bool checkAPIVersion(NodeId, Uint32 nodeVersion, Uint32 ownVersion) const; bool checkNDBVersion(NodeId, Uint32 nodeVersion, Uint32 ownVersion) const; + void cmAddPrepare(Signal* signal, NodeRecPtr nodePtr, const NodeRec* self); + void sendCmAckAdd(Signal *, Uint32 nodeId, CmAdd::RequestType); + void joinedCluster(Signal* signal, NodeRecPtr nodePtr); + void sendCmRegReq(Signal * signal, Uint32 nodeId); + void sendCmNodeInfoReq(Signal* signal, Uint32 nodeId, const NodeRec * self); + private: void sendPrepFailReqRef(Signal* signal, Uint32 dstBlockRef, @@ -364,7 +338,6 @@ private: /**** Common stored variables ****/ NodeRec *nodeRec; - RegApp * regApp; ArbitRec arbitRec; /* Block references ------------------------------*/ @@ -377,27 +350,17 @@ private: /* Counters --------------------------------------*/ Uint16 cnoOfNodes; /* Static node counter */ - Uint16 cclustersize; /* Currently not used */ /* Status flags ----------------------------------*/ - Uint16 cstartseq; /* Marks what startseq we are in according to - STTOR */ + Uint32 c_restartPartialTimeout; - Uint16 cpresidentBusy; /* Only used by the president, ZTRUE / ZFALSE */ - Uint16 cacceptRegreq; /* Used by president, ZTRUE / ZFALSE */ - Uint16 cwaitContinuebPhase1; - Uint16 cwaitContinuebPhase2; Uint16 creadyDistCom; - - UintR cstartNo; Uint16 c_regReqReqSent; Uint16 c_regReqReqRecv; Uint64 c_stopElectionTime; Uint16 cpresidentCandidate; Uint16 cdelayRegreq; Uint16 cpresidentAlive; - Uint16 csignalkey; - Uint16 cstartNode; Uint16 cnoFailedNodes; Uint16 cnoPrepFailedNodes; Uint16 cnoCommitFailedNodes; @@ -410,7 +373,6 @@ private: UintR cfailureNr; QmgrState ctoStatus; - UintR ccm_infoconfCounter; UintR cLqhTimeSignalCount; bool cHbSent; NDB_TICKS clatestTransactionCheck; @@ -421,68 +383,10 @@ private: class Timer hb_api_timer; - UintR cnodemask[NdbNodeBitmask::Size]; Uint16 cfailedNodes[MAX_NDB_NODES]; Uint16 cprepFailedNodes[MAX_NDB_NODES]; Uint16 ccommitFailedNodes[MAX_NDB_NODES]; - /***************************************************************************/ - /* RECORD NODE_REC: The NodeList contains information about all other nodes - * in the cluster. - * Member variables: - * NTYPE [ ZACTIVE, - * ZPASSIVE, Marks the level of activity the - * node will show in the cluster. - * ZLISTENER ] - * PHASE [ ZINIT, = Initial face, before node is added - * to cluster - * ZWAITING, = Node is added to the cluster and - * ready to run - * ZRUNNING, = Node is up and running. - * ZBLOCKED = Node is not in the cluster - * ZAPI_ACTIVE = Node has an active application - * ZFAIL_CLOSING = Node is disconnecting - * ZDEAD ] = Node has been declared as dead - * ALARM_COUNT No of times an alarm has been sent before it is - * acknowledged - ***************************************************************************/ - /************************************************************************* - * RECORD REG_APP: The REG_APP record is used to store information about - * each registered application running on the current node. - * Member variables: - * BLOCKREF Reference of application block to receive cluster - * signals - * PTR Not used today but may be used by appl. in future - * NAME Unique name of application, max 15 char. long - * SUBTYPE Provided as a mechanism for applications to have - * more than one type running in the same application - * ring. i.e. NDB & NDB-API - * VERSION Version no. of application. Two different versions - * will be handled as different applications. - * TYPE [ ZACTIVE, - * ZPASSIVE, - * ZLISTENER ] Type of member in the cluster - * ACTIVITY [ ZADD, Application has been registered on - * node. - * ZSTART, Application is ready to start - * running distributed. - * ZRUN, Application is running actively. - * ZDELETE ] Application is beeing removed from - * the node. - * HBDELAY Delay time for periodic intervalls. - * STATUS Heartbeat status, indicates if app is responding - * to HBREQ. - * RUNNODES() If value is ZTRUE -> app. is also running on the - * indexed node. - * NOOFAPPS No. of applications left to register themselves as - * ready to start, STATUS = ZSTART before we can send - * APPL_STARTCONF. - * NOOFPENDING No. of apps that have registered themselfs as ready - * to start before this app has. We need this since - * we set NOOFAPPS when we receive the local - * APPL_START. NOOFPENDING is subtracted from NOOFAPPS - * when NOOFAPPS is set. - **************************************************************************/ - }; + #endif diff --git a/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp b/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp index ffc1448548d..b0f1088779c 100644 --- a/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp +++ b/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp @@ -18,7 +18,6 @@ #define QMGR_C #include "Qmgr.hpp" -#include <Configuration.hpp> #define DEBUG(x) { ndbout << "Qmgr::" << x << endl; } @@ -29,10 +28,13 @@ void Qmgr::initData() // Records with constant sizes nodeRec = new NodeRec[MAX_NODES]; - regApp = new RegApp[NO_REG_APP]; - cclustersize = 0; cnoCommitFailedNodes = 0; + c_maxDynamicId = 0; + c_clusterNodes.clear(); + + Uint32 hbDBAPI = 500; + setHbApiDelay(hbDBAPI); }//Qmgr::initData() void Qmgr::initRecords() @@ -52,7 +54,6 @@ Qmgr::Qmgr(const class Configuration & conf) addRecSignal(GSN_CM_HEARTBEAT, &Qmgr::execCM_HEARTBEAT); addRecSignal(GSN_CM_ADD, &Qmgr::execCM_ADD); addRecSignal(GSN_CM_ACKADD, &Qmgr::execCM_ACKADD); - addRecSignal(GSN_CM_APPCHG, &Qmgr::execCM_APPCHG); addRecSignal(GSN_CM_REGREQ, &Qmgr::execCM_REGREQ); addRecSignal(GSN_CM_REGCONF, &Qmgr::execCM_REGCONF); addRecSignal(GSN_CM_REGREF, &Qmgr::execCM_REGREF); @@ -67,16 +68,11 @@ Qmgr::Qmgr(const class Configuration & conf) addRecSignal(GSN_FAIL_REP, &Qmgr::execFAIL_REP); addRecSignal(GSN_PRES_TOREQ, &Qmgr::execPRES_TOREQ); addRecSignal(GSN_PRES_TOCONF, &Qmgr::execPRES_TOCONF); - addRecSignal(GSN_CM_INFOCONF, &Qmgr::execCM_INFOCONF); // Received signals addRecSignal(GSN_CONNECT_REP, &Qmgr::execCONNECT_REP); addRecSignal(GSN_NDB_FAILCONF, &Qmgr::execNDB_FAILCONF); addRecSignal(GSN_STTOR, &Qmgr::execSTTOR); - addRecSignal(GSN_APPL_REGREQ, &Qmgr::execAPPL_REGREQ); - addRecSignal(GSN_APPL_STARTREG, &Qmgr::execAPPL_STARTREG); - addRecSignal(GSN_APPL_RUN, &Qmgr::execAPPL_RUN); - addRecSignal(GSN_CM_INIT, &Qmgr::execCM_INIT); addRecSignal(GSN_CLOSE_COMCONF, &Qmgr::execCLOSE_COMCONF); addRecSignal(GSN_API_REGREQ, &Qmgr::execAPI_REGREQ); addRecSignal(GSN_API_VERSION_REQ, &Qmgr::execAPI_VERSION_REQ); @@ -86,7 +82,6 @@ Qmgr::Qmgr(const class Configuration & conf) addRecSignal(GSN_SET_VAR_REQ, &Qmgr::execSET_VAR_REQ); // Arbitration signals - addRecSignal(GSN_ARBIT_CFG, &Qmgr::execARBIT_CFG); addRecSignal(GSN_ARBIT_PREPREQ, &Qmgr::execARBIT_PREPREQ); addRecSignal(GSN_ARBIT_PREPCONF, &Qmgr::execARBIT_PREPCONF); addRecSignal(GSN_ARBIT_PREPREF, &Qmgr::execARBIT_PREPREF); @@ -97,18 +92,11 @@ Qmgr::Qmgr(const class Configuration & conf) addRecSignal(GSN_ARBIT_STOPREP, &Qmgr::execARBIT_STOPREP); initData(); - - const ClusterConfiguration::ClusterData & clusterConf = - theConfiguration.clusterConfigurationData() ; - setHbDelay(clusterConf.ispValues[0][2]); //cmInit->heartbeatDbDb); - setHbApiDelay(clusterConf.ispValues[0][3]); //;cmInit->heartbeatDbApi); - setArbitTimeout(clusterConf.ispValues[0][5]); //cmInit->arbitTimeout); }//Qmgr::Qmgr() Qmgr::~Qmgr() { delete []nodeRec; - delete []regApp; }//Qmgr::~Qmgr() diff --git a/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp b/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp index 0f82f8def6f..ac29614bc70 100644 --- a/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp +++ b/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp @@ -20,7 +20,6 @@ #include <pc.hpp> #include <NdbTick.h> #include <signaldata/EventReport.hpp> -#include <signaldata/SetVarReq.hpp> #include <signaldata/StartOrd.hpp> #include <signaldata/CmInit.hpp> #include <signaldata/CloseComReqConf.hpp> @@ -42,6 +41,20 @@ #include <NdbOut.hpp> #endif +//#define DEBUG_QMGR_START +#ifdef DEBUG_QMGR_START +#include <DebuggerNames.hpp> +#define DEBUG(x) ndbout << "QMGR " << __LINE__ << ": " << x << endl +#define DEBUG_START(gsn, node, msg) DEBUG(getSignalName(gsn) << " to: " << node << " - " << msg) +#define DEBUG_START2(gsn, rg, msg) { char nodes[255]; DEBUG(getSignalName(gsn) << " to: " << rg.m_nodes.getText(nodes) << " - " << msg); } +#define DEBUG_START3(signal, msg) DEBUG(getSignalName(signal->header.theVerId_signalNumber) << " from " << refToNode(signal->getSendersBlockRef()) << " - " << msg); +#else +#define DEBUG(x) +#define DEBUG_START(gsn, node, msg) +#define DEBUG_START2(gsn, rg, msg) +#define DEBUG_START3(signal, msg) +#endif + // Signal entries and statement blocks /* 4 P R O G R A M */ /*******************************/ @@ -72,32 +85,27 @@ void Qmgr::execCM_NODEINFOREF(Signal* signal) /*******************************/ void Qmgr::execCONTINUEB(Signal* signal) { - UintR tdata0; - UintR tcontinuebType; - jamEntry(); - tcontinuebType = signal->theData[0]; - tdata0 = signal->theData[1]; + const Uint32 tcontinuebType = signal->theData[0]; + const Uint32 tdata0 = signal->theData[1]; + const Uint32 tdata1 = signal->theData[2]; switch (tcontinuebType) { case ZREGREQ_TIMELIMIT: jam(); - if (cstartNo == tdata0) { + if (c_start.m_startKey != tdata0 || c_start.m_startNode != tdata1) { jam(); - regreqTimelimitLab(signal, signal->theData[2]); return; - } + }//if + regreqTimeLimitLab(signal); break; case ZREGREQ_MASTER_TIMELIMIT: jam(); - if (cstartNo != tdata0) { + if (c_start.m_startKey != tdata0 || c_start.m_startNode != tdata1) { jam(); return; }//if - if (cpresidentBusy != ZTRUE) { - jam(); - return; - }//if - failReportLab(signal, cstartNode, FailRep::ZSTART_IN_REGREQ); + //regreqMasterTimeLimitLab(signal); + failReportLab(signal, c_start.m_startNode, FailRep::ZSTART_IN_REGREQ); return; break; case ZTIMER_HANDLING: @@ -173,15 +181,23 @@ void Qmgr::execPRES_TOREQ(Signal* signal) void Qmgr::execSTTOR(Signal* signal) { jamEntry(); - cstartseq = signal->theData[1]; - csignalkey = signal->theData[6]; - if (cstartseq == 1) { - jam(); + + switch(signal->theData[1]){ + case 1: initData(signal); + startphase1(signal); + return; + case 7: + cactivateApiCheck = 1; + /** + * Start arbitration thread. This could be done as soon as + * we have all nodes (or a winning majority). + */ + if (cpresident == getOwnNodeId()) + handleArbitStart(signal); + break; } - setNodeInfo(getOwnNodeId()).m_version = NDB_VERSION; - sendSttorryLab(signal); return; }//Qmgr::execSTTOR() @@ -191,85 +207,32 @@ void Qmgr::sendSttorryLab(Signal* signal) /****************************<*/ /*< STTORRY <*/ /****************************<*/ - signal->theData[0] = csignalkey; - signal->theData[1] = 3; - signal->theData[2] = 2; - signal->theData[3] = 2; + signal->theData[3] = 7; signal->theData[4] = 255; sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 5, JBB); return; }//Qmgr::sendSttorryLab() -/* -4.2.2 CM_INIT */ -/**-------------------------------------------------------------------------- - * This signal is sent by the CLUSTERCTRL block. - * It initiates the QMGR and provides needed info about the - * cluster configuration (read from file). - * - * The signal starts all QMGR functions. - * It is possible to register applications before this but the QMGR will - * not be active before the registration face is complete. - * - * The CM_INIT will result in a one CM_NODEINFOREQ for each ndb node. - * We will also send a CONTINUEB to ourselves as a timelimit. - * If anyone sends a REF, CONF or a ( REQ with a lower NODENO than us ) during - * this time, we are not the president . - *--------------------------------------------------------------------------*/ -/*******************************/ -/* CM_INIT */ -/*******************************/ -void Qmgr::execCM_INIT(Signal* signal) +void Qmgr::startphase1(Signal* signal) { jamEntry(); - CmInit * const cmInit = (CmInit *)&signal->theData[0]; - - for(unsigned int i = 0; i<NdbNodeBitmask::Size; i++) - cnodemask[i] = cmInit->allNdbNodes[i]; - - cnoOfNodes = 0; - setHbDelay(cmInit->heartbeatDbDb); - setHbApiDelay(cmInit->heartbeatDbApi); - setArbitTimeout(cmInit->arbitTimeout); - arbitRec.state = ARBIT_NULL; // start state for all nodes - arbitRec.apiMask[0].clear(); // prepare for ARBIT_CFG NodeRecPtr nodePtr; - for (nodePtr.i = 0; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { - jam(); - ptrAss(nodePtr, nodeRec); - if (NdbNodeBitmask::get(cnodemask, nodePtr.i)) { - jam(); - - nodePtr.p->blockRef = calcQmgrBlockRef(nodePtr.i); - nodePtr.p->phase = ZINIT; /* Not added to cluster */ - cnoOfNodes = cnoOfNodes + 1; /* Should never be changed after this loop. */ - ndbrequire(getNodeInfo(nodePtr.i).m_type == NodeInfo::DB); - } else { - jam(); - nodePtr.p->phase = ZBLOCKED; - }//if - }//for - for (nodePtr.i = MAX_NDB_NODES; nodePtr.i < MAX_NODES; nodePtr.i++) { - jam(); - ptrAss(nodePtr, nodeRec); - nodePtr.p->phase = ZBLOCKED; - }//for - nodePtr.i = getOwnNodeId(); ptrAss(nodePtr, nodeRec); - nodePtr.p->phase = ZINIT; - nodePtr.p->m_connected = true; + nodePtr.p->phase = ZSTARTING; + nodePtr.p->blockRef = reference(); + c_connectedNodes.set(nodePtr.i); - /****************************<*/ - /*< CM_INFOREQ <*/ - /****************************<*/ - signal->theData[0] = reference(); - signal->theData[1] = getOwnNodeId(); - sendSignal(CMVMI_REF, GSN_CM_INFOREQ, signal, 2, JBB); + signal->theData[0] = 0; // no answer + signal->theData[1] = 0; // no id + signal->theData[2] = NodeInfo::DB; + sendSignal(CMVMI_REF, GSN_OPEN_COMREQ, signal, 3, JBB); + + execCM_INFOCONF(signal); return; -}//Qmgr::execCM_INIT() +} void Qmgr::setHbDelay(UintR aHbDelay) { @@ -293,11 +256,46 @@ void Qmgr::setArbitTimeout(UintR aArbitTimeout) void Qmgr::execCONNECT_REP(Signal* signal) { - NodeRecPtr connectNodePtr; - connectNodePtr.i = signal->theData[0]; - ptrCheckGuard(connectNodePtr, MAX_NODES, nodeRec); - connectNodePtr.p->m_connected = true; + const Uint32 nodeId = signal->theData[0]; + c_connectedNodes.set(nodeId); + NodeRecPtr nodePtr; + nodePtr.i = getOwnNodeId(); + ptrCheckGuard(nodePtr, MAX_NODES, nodeRec); + switch(nodePtr.p->phase){ + case ZSTARTING: + jam(); + break; + case ZRUNNING: + case ZPREPARE_FAIL: + case ZFAIL_CLOSING: + jam(); + return; + case ZINIT: + ndbrequire(false); + case ZAPI_ACTIVE: + case ZAPI_INACTIVE: + return; + } + + if(!c_start.m_nodes.isWaitingFor(nodeId)){ + jam(); + return; + } + + switch(c_start.m_gsn){ + case GSN_CM_REGREQ: + jam(); + sendCmRegReq(signal, nodeId); + return; + case GSN_CM_NODEINFOREQ:{ + jam(); + sendCmNodeInfoReq(signal, nodeId, nodePtr.p); + return; + } + default: + return; + } return; }//Qmgr::execCONNECT_REP() @@ -310,25 +308,22 @@ void Qmgr::execCM_INFOCONF(Signal* signal) cpresidentCandidate = getOwnNodeId(); cpresidentAlive = ZFALSE; c_stopElectionTime = NdbTick_CurrentMillisecond(); - c_stopElectionTime += 30000; // 30s + c_stopElectionTime += c_restartPartialTimeout; cmInfoconf010Lab(signal); -#if 0 - /*****************************************************/ - /* Allow the CLUSTER CONTROL to send STTORRY */ - /* CM_RUN */ - /* so we can receive APPL_REGREQ from applications. */ - /*****************************************************/ - signal->theData[0] = 0; - sendSignal(CMVMI_REF, GSN_CM_RUN, signal, 1, JBB); -#endif return; }//Qmgr::execCM_INFOCONF() void Qmgr::cmInfoconf010Lab(Signal* signal) { + c_start.m_startKey = 0; + c_start.m_startNode = getOwnNodeId(); + c_start.m_nodes.clearWaitingFor(); + c_start.m_gsn = GSN_CM_REGREQ; + NodeRecPtr nodePtr; c_regReqReqSent = c_regReqReqRecv = 0; + cnoOfNodes = 0; for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { jam(); ptrAss(nodePtr, nodeRec); @@ -336,19 +331,15 @@ void Qmgr::cmInfoconf010Lab(Signal* signal) if(getNodeInfo(nodePtr.i).getType() != NodeInfo::DB) continue; - if(!nodePtr.p->m_connected) + c_start.m_nodes.setWaitingFor(nodePtr.i); + cnoOfNodes++; + + if(!c_connectedNodes.get(nodePtr.i)) continue; - c_regReqReqSent++; - CmRegReq * const cmRegReq = (CmRegReq *)&signal->theData[0]; - cmRegReq->blockRef = reference(); - cmRegReq->nodeId = getOwnNodeId(); - cmRegReq->version = NDB_VERSION; - sendSignal(nodePtr.p->blockRef, GSN_CM_REGREQ, signal, - CmRegReq::SignalLength, JBB); + sendCmRegReq(signal, nodePtr.i); } - cstartNo = cstartNo + 1; - + //---------------------------------------- /* Wait for a while. When it returns */ /* we will check if we got any CM_REGREF*/ @@ -356,14 +347,26 @@ void Qmgr::cmInfoconf010Lab(Signal* signal) /* own). */ //---------------------------------------- signal->theData[0] = ZREGREQ_TIMELIMIT; - signal->theData[1] = cstartNo; - signal->theData[2] = 0; - sendSignalWithDelay(QMGR_REF, GSN_CONTINUEB, signal, 3 * cdelayRegreq, 3); - cwaitContinuebPhase1 = ZTRUE; + signal->theData[1] = c_start.m_startKey; + signal->theData[2] = c_start.m_startNode; + sendSignalWithDelay(QMGR_REF, GSN_CONTINUEB, signal, 3000, 3); + creadyDistCom = ZTRUE; return; }//Qmgr::cmInfoconf010Lab() +void +Qmgr::sendCmRegReq(Signal * signal, Uint32 nodeId){ + c_regReqReqSent++; + CmRegReq * const cmRegReq = (CmRegReq *)&signal->theData[0]; + cmRegReq->blockRef = reference(); + cmRegReq->nodeId = getOwnNodeId(); + cmRegReq->version = NDB_VERSION; + const Uint32 ref = calcQmgrBlockRef(nodeId); + sendSignal(ref, GSN_CM_REGREQ, signal, CmRegReq::SignalLength, JBB); + DEBUG_START(GSN_CM_REGREQ, nodeId, ""); +} + /* 4.4.11 CM_REGREQ */ /**-------------------------------------------------------------------------- @@ -403,6 +406,8 @@ void Qmgr::cmInfoconf010Lab(Signal* signal) /*******************************/ void Qmgr::execCM_REGREQ(Signal* signal) { + DEBUG_START3(signal, ""); + NodeRecPtr addNodePtr; jamEntry(); @@ -451,27 +456,15 @@ void Qmgr::execCM_REGREQ(Signal* signal) return; }//if - if (cpresidentBusy == ZTRUE) { + if (c_start.m_startNode != 0){ jam(); /** - * President busy by adding another node + * President busy by adding another node */ sendCmRegrefLab(signal, Tblockref, CmRegRef::ZBUSY_PRESIDENT); return; }//if - if (cacceptRegreq == ZFALSE && - getNodeState().startLevel != NodeState::SL_STARTING) { - jam(); - /** - * These checks are really confusing! - * The variables that is being checked are probably not - * set in the correct places. - */ - sendCmRegrefLab(signal, Tblockref, CmRegRef::ZBUSY); - return; - }//if - if (ctoStatus == Q_ACTIVE) { jam(); /** @@ -481,7 +474,7 @@ void Qmgr::execCM_REGREQ(Signal* signal) return; }//if - if (addNodePtr.p->phase == ZBLOCKED) { + if (getNodeInfo(addNodePtr.i).m_type != NodeInfo::DB) { jam(); /** * The new node is not in config file @@ -489,9 +482,11 @@ void Qmgr::execCM_REGREQ(Signal* signal) sendCmRegrefLab(signal, Tblockref, CmRegRef::ZNOT_IN_CFG); return; } - - if (addNodePtr.p->phase != ZINIT) { + + Phase phase = addNodePtr.p->phase; + if (phase != ZINIT){ jam(); + DEBUG("phase = " << phase); sendCmRegrefLab(signal, Tblockref, CmRegRef::ZNOT_DEAD); return; }//if @@ -506,45 +501,56 @@ void Qmgr::execCM_REGREQ(Signal* signal) * THE SIGNAL ARRIVES. IF IT HAS CHANGED THEN WE SIMPLY IGNORE * THE TIMED SIGNAL. */ - cpresidentBusy = ZTRUE; /** - * Indicates that we are busy with node start/restart and do - * not accept another start until this node is up and running - * (cpresidentBusy is released a little too early to use for this - * purpose). + * Update start record */ - cacceptRegreq = ZFALSE; - cstartNo = cstartNo + 1; - cstartNode = addNodePtr.i; - signal->theData[0] = ZREGREQ_MASTER_TIMELIMIT; - signal->theData[1] = cstartNo; - sendSignalWithDelay(QMGR_REF, GSN_CONTINUEB, signal, 30000, 2); - UintR TdynId = getDynamicId(signal); /* <- CDYNAMIC_ID */ - prepareAdd(signal, addNodePtr.i); - setNodeInfo(addNodePtr.i).m_version = startingVersion; - + c_start.m_startKey++; + c_start.m_startNode = addNodePtr.i; + /** - * Send "prepare for adding a new node" to all - * running nodes in cluster + the new node. - * Give permission to the new node to join the - * cluster + * Assign dynamic id */ - /*******************************/ - /*< CM_REGCONF <*/ - /*******************************/ + UintR TdynId = ++c_maxDynamicId; + setNodeInfo(addNodePtr.i).m_version = startingVersion; + addNodePtr.p->ndynamicId = TdynId; + /** + * Reply with CM_REGCONF + */ CmRegConf * const cmRegConf = (CmRegConf *)&signal->theData[0]; - cmRegConf->presidentBlockRef = reference(); cmRegConf->presidentNodeId = getOwnNodeId(); cmRegConf->presidentVersion = getNodeInfo(getOwnNodeId()).m_version; cmRegConf->dynamicId = TdynId; - for(unsigned int i = 0; i<NdbNodeBitmask::Size; i++) - cmRegConf->allNdbNodes[i] = cnodemask[i]; - + c_clusterNodes.copyto(NdbNodeBitmask::Size, cmRegConf->allNdbNodes); sendSignal(Tblockref, GSN_CM_REGCONF, signal, CmRegConf::SignalLength, JBB); + DEBUG_START(GSN_CM_REGCONF, refToNode(Tblockref), ""); + + /** + * Send CmAdd to all nodes (including starting) + */ + c_start.m_nodes = c_clusterNodes; + c_start.m_nodes.setWaitingFor(addNodePtr.i); + c_start.m_gsn = GSN_CM_ADD; + + NodeReceiverGroup rg(QMGR, c_start.m_nodes); + CmAdd * const cmAdd = (CmAdd*)signal->getDataPtrSend(); + cmAdd->requestType = CmAdd::Prepare; + cmAdd->startingNodeId = addNodePtr.i; + cmAdd->startingVersion = startingVersion; + sendSignal(rg, GSN_CM_ADD, signal, CmAdd::SignalLength, JBA); + DEBUG_START2(GSN_CM_ADD, rg, "Prepare"); + + /** + * Set timer + */ + return; + signal->theData[0] = ZREGREQ_MASTER_TIMELIMIT; + signal->theData[1] = c_start.m_startKey; + sendSignalWithDelay(QMGR_REF, GSN_CONTINUEB, signal, 30000, 2); + return; }//Qmgr::execCM_REGREQ() @@ -555,9 +561,10 @@ void Qmgr::sendCmRegrefLab(Signal* signal, BlockReference TBRef, ref->blockRef = reference(); ref->nodeId = getOwnNodeId(); ref->errorCode = Terror; - ref->presidentCandidate = cpresidentCandidate; + ref->presidentCandidate = (cpresident == ZNIL ? cpresidentCandidate : cpresident); sendSignal(TBRef, GSN_CM_REGREF, signal, CmRegRef::SignalLength, JBB); + DEBUG_START(GSN_CM_REGREF, refToNode(TBRef), ""); return; }//Qmgr::sendCmRegrefLab() @@ -575,14 +582,13 @@ void Qmgr::sendCmRegrefLab(Signal* signal, BlockReference TBRef, /*******************************/ void Qmgr::execCM_REGCONF(Signal* signal) { + DEBUG_START3(signal, ""); + NodeRecPtr myNodePtr; NodeRecPtr nodePtr; - NodeRecPtr presidentNodePtr; jamEntry(); - CmRegConf * const cmRegConf = (CmRegConf *)&signal->theData[0]; - cwaitContinuebPhase1 = ZFALSE; - cwaitContinuebPhase2 = ZTRUE; + const CmRegConf * const cmRegConf = (CmRegConf *)&signal->theData[0]; if (!ndbCompatible_ndb_ndb(NDB_VERSION, cmRegConf->presidentVersion)) { jam(); @@ -592,46 +598,12 @@ void Qmgr::execCM_REGCONF(Signal* signal) return; } - /** - * Check if all necessary connections has been established - */ - for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { - jam(); - if (NodeBitmask::get(cmRegConf->allNdbNodes, nodePtr.i) == true){ - jam(); - ptrAss(nodePtr, nodeRec); - if (!nodePtr.p->m_connected) { - jam(); - - /** - * Missing connection - */ -#ifdef VM_TRACE - ndbout_c("Resending CM_REGCONF, node %d is not connected", nodePtr.i); - ndbout << " presidentBlockRef="<<cmRegConf->presidentBlockRef<<endl - << " presidentNodeId="<<cmRegConf->presidentNodeId<<endl - << " presidentVersion="<<cmRegConf->presidentVersion<<endl - << " dynamicId="<<cmRegConf->dynamicId<<endl; -#endif - for(unsigned int i = 0; i<NdbNodeBitmask::Size; i++) { - jam(); -#ifdef VM_TRACE - ndbout << " " << i << ": " - << hex << cmRegConf->allNdbNodes[i]<<endl; -#endif - } - sendSignalWithDelay(reference(), GSN_CM_REGCONF, signal, 100, - signal->getLength()); - return; - } - } - } - + cpdistref = cmRegConf->presidentBlockRef; cpresident = cmRegConf->presidentNodeId; UintR TdynamicId = cmRegConf->dynamicId; - for(unsigned int i = 0; i<NdbNodeBitmask::Size; i++) - cnodemask[i] = cmRegConf->allNdbNodes[i]; + c_maxDynamicId = TdynamicId; + c_clusterNodes.assign(NdbNodeBitmask::Size, cmRegConf->allNdbNodes); /*--------------------------------------------------------------*/ // Send this as an EVENT REPORT to inform about hearing about @@ -646,67 +618,40 @@ void Qmgr::execCM_REGCONF(Signal* signal) myNodePtr.i = getOwnNodeId(); ptrCheckGuard(myNodePtr, MAX_NDB_NODES, nodeRec); myNodePtr.p->ndynamicId = TdynamicId; - presidentNodePtr.i = cpresident; - ptrCheckGuard(presidentNodePtr, MAX_NDB_NODES, nodeRec); - cpdistref = presidentNodePtr.p->blockRef; - - CmNodeInfoReq * const req = (CmNodeInfoReq*)signal->getDataPtrSend(); - req->nodeId = getOwnNodeId(); - req->dynamicId = myNodePtr.p->ndynamicId; - req->version = getNodeInfo(getOwnNodeId()).m_version; for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { jam(); - if (NdbNodeBitmask::get(cnodemask, nodePtr.i) == true){ + if (c_clusterNodes.get(nodePtr.i)){ jam(); ptrAss(nodePtr, nodeRec); - switch(nodePtr.p->phase){ - case ZINIT: /* All nodes start in phase INIT */ - jam(); - break; - case ZWAITING: /* Node is connecting to cluster */ - jam(); - break; - case ZRUNNING: /* Node is running in the cluster */ - jam(); - break; - case ZBLOCKED: /* Node is blocked from the cluster */ - jam(); - break; - case ZWAIT_PRESIDENT: - jam(); - break; - case ZDEAD: - jam(); - break; - case ZAPI_ACTIVE: /* API IS RUNNING IN NODE */ - jam(); - break; - case ZFAIL_CLOSING: /* API/NDB IS DISCONNECTING */ - jam(); - break; - case ZPREPARE_FAIL: /* PREPARATION FOR FAILURE */ - jam(); - break; - case ZAPI_INACTIVE: /* Inactive API */ - jam(); - break; - default: + + ndbrequire(nodePtr.p->phase == ZINIT); + nodePtr.p->phase = ZRUNNING; + + if(c_connectedNodes.get(nodePtr.i)){ jam(); - ndbout << "phase="<<nodePtr.p->phase<<endl; - break; + sendCmNodeInfoReq(signal, nodePtr.i, myNodePtr.p); } - ndbrequire(nodePtr.p->phase == ZINIT); - ndbrequire(nodePtr.i != getOwnNodeId()); - nodePtr.p->phase = ZWAITING; - - sendSignal(nodePtr.p->blockRef, GSN_CM_NODEINFOREQ, - signal, CmNodeInfoReq::SignalLength, JBB); } } + + c_start.m_gsn = GSN_CM_NODEINFOREQ; + c_start.m_nodes = c_clusterNodes; + return; }//Qmgr::execCM_REGCONF() +void +Qmgr::sendCmNodeInfoReq(Signal* signal, Uint32 nodeId, const NodeRec * self){ + CmNodeInfoReq * const req = (CmNodeInfoReq*)signal->getDataPtrSend(); + req->nodeId = getOwnNodeId(); + req->dynamicId = self->ndynamicId; + req->version = getNodeInfo(getOwnNodeId()).m_version; + const Uint32 ref = calcQmgrBlockRef(nodeId); + sendSignal(ref,GSN_CM_NODEINFOREQ, signal, CmNodeInfoReq::SignalLength, JBB); + DEBUG_START(GSN_CM_NODEINFOREQ, nodeId, ""); +} + /* 4.4.11 CM_REGREF */ /**-------------------------------------------------------------------------- @@ -735,9 +680,11 @@ void Qmgr::execCM_REGREF(Signal* signal) UintR TrefuseReason = signal->theData[2]; Uint32 candidate = signal->theData[3]; + DEBUG_START3(signal, TrefuseReason); + if(candidate != cpresidentCandidate){ jam(); - c_regReqReqRecv = c_regReqReqSent + 1; + c_regReqReqRecv = ~0; } switch (TrefuseReason) { @@ -758,25 +705,16 @@ void Qmgr::execCM_REGREF(Signal* signal) break; case CmRegRef::ZNOT_DEAD: jam(); - if(TaddNodeno == getOwnNodeId() && cpresident == getOwnNodeId()){ - jam(); - cwaitContinuebPhase1 = ZFALSE; - cwaitContinuebPhase2 = ZFALSE; - return; - } progError(__LINE__, ERR_NODE_NOT_DEAD); break; case CmRegRef::ZELECTION: jam(); - if (cwaitContinuebPhase1 == ZFALSE) { - jam(); - signal->theData[3] = 1; - } else if (cpresidentCandidate > TaddNodeno) { + if (cpresidentCandidate > TaddNodeno) { jam(); -//---------------------------------------- -/* We may already have a candidate */ -/* choose the lowest nodeno */ -//---------------------------------------- + //---------------------------------------- + /* We may already have a candidate */ + /* choose the lowest nodeno */ + //---------------------------------------- signal->theData[3] = 2; cpresidentCandidate = TaddNodeno; } else { @@ -808,16 +746,19 @@ void Qmgr::execCM_REGREF(Signal* signal) if(cpresidentAlive == ZTRUE){ jam(); + DEBUG(""); return; } if(c_regReqReqSent != c_regReqReqRecv){ jam(); + DEBUG( c_regReqReqSent << " != " << c_regReqReqRecv); return; } if(cpresidentCandidate != getOwnNodeId()){ jam(); + DEBUG(""); return; } @@ -829,10 +770,8 @@ void Qmgr::execCM_REGREF(Signal* signal) jam(); electionWon(); -#if 1 - signal->theData[0] = 0; - sendSignal(CMVMI_REF, GSN_CM_RUN, signal, 1, JBB); -#endif + sendSttorryLab(signal); + /** * Start timer handling */ @@ -851,14 +790,18 @@ Qmgr::electionWon(){ ptrCheckGuard(myNodePtr, MAX_NDB_NODES, nodeRec); myNodePtr.p->phase = ZRUNNING; + cpdistref = reference(); - cclustersize = 1; cneighbourl = ZNIL; cneighbourh = ZNIL; myNodePtr.p->ndynamicId = 1; - + c_maxDynamicId = 1; + c_clusterNodes.clear(); + c_clusterNodes.set(getOwnNodeId()); + cpresidentAlive = ZTRUE; c_stopElectionTime = ~0; + c_start.reset(); } /* @@ -870,38 +813,11 @@ Qmgr::electionWon(){ /* CONTINUEB > SENDER: Own block, Own node */ /****************************>-------+INPUT : TCONTINUEB_TYPE */ /*--------------------------------------------------------------*/ -void Qmgr::regreqTimelimitLab(Signal* signal, UintR callTime) +void Qmgr::regreqTimeLimitLab(Signal* signal) { - if (cwaitContinuebPhase1 == ZFALSE) { - if (cwaitContinuebPhase2 == ZFALSE) { - jam(); - return; - } else { - jam(); - if (callTime < 10) { - /*-------------------------------------------------------------*/ - // We experienced a time-out of inclusion. Give it another few - // seconds before crashing. - /*-------------------------------------------------------------*/ - signal->theData[0] = ZREGREQ_TIMELIMIT; - signal->theData[1] = cstartNo; - signal->theData[2] = callTime + 1; - sendSignalWithDelay(QMGR_REF, GSN_CONTINUEB, signal, 3000, 3); - return; - }//if - /*-------------------------------------------------------------*/ - /* WE HAVE COME HERE BECAUSE THE INCLUSION SUFFERED FROM */ - /* TIME OUT. WE CRASH AND RESTART. */ - /*-------------------------------------------------------------*/ - systemErrorLab(signal); - return; - }//if - } else { - jam(); - cwaitContinuebPhase1 = ZFALSE; - }//if - - cmInfoconf010Lab(signal); + if(cpresident == ZNIL){ + cmInfoconf010Lab(signal); + } }//Qmgr::regreqTimelimitLab() /**--------------------------------------------------------------------------- @@ -917,32 +833,37 @@ void Qmgr::regreqTimelimitLab(Signal* signal, UintR callTime) /*******************************/ void Qmgr::execCM_NODEINFOCONF(Signal* signal) { - NodeRecPtr replyNodePtr; - NodeRecPtr nodePtr; + DEBUG_START3(signal, ""); + jamEntry(); CmNodeInfoConf * const conf = (CmNodeInfoConf*)signal->getDataPtr(); - replyNodePtr.i = conf->nodeId; - ptrCheckGuard(replyNodePtr, MAX_NDB_NODES, nodeRec); - replyNodePtr.p->ndynamicId = conf->dynamicId; - setNodeInfo(replyNodePtr.i).m_version = conf->version; - replyNodePtr.p->phase = ZRUNNING; - + const Uint32 nodeId = conf->nodeId; + const Uint32 dynamicId = conf->dynamicId; + const Uint32 version = conf->version; + + NodeRecPtr nodePtr; + nodePtr.i = getOwnNodeId(); + ptrAss(nodePtr, nodeRec); + ndbrequire(nodePtr.p->phase == ZSTARTING); + ndbrequire(c_start.m_gsn = GSN_CM_NODEINFOREQ); + c_start.m_nodes.clearWaitingFor(nodeId); + /** - * A node in the cluster has replied nodeinfo about himself. - * He is already running in the cluster. + * Update node info */ - for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { + NodeRecPtr replyNodePtr; + replyNodePtr.i = nodeId; + ptrCheckGuard(replyNodePtr, MAX_NDB_NODES, nodeRec); + replyNodePtr.p->ndynamicId = dynamicId; + replyNodePtr.p->blockRef = signal->getSendersBlockRef(); + setNodeInfo(replyNodePtr.i).m_version = version; + + if(!c_start.m_nodes.done()){ jam(); - ptrAss(nodePtr, nodeRec); - if (nodePtr.p->phase == ZWAITING) { - if (nodePtr.i != getOwnNodeId()) { - jam(); - return; - }//if - }//if - }//for + return; + } /**********************************************<*/ /* Send an ack. back to the president. */ @@ -953,11 +874,7 @@ void Qmgr::execCM_NODEINFOCONF(Signal* signal) /* for CM_ADD (commit) from president to become */ /* a running node in the cluster. */ /**********************************************<*/ - CmAckAdd * const cmAckAdd = (CmAckAdd*)signal->getDataPtrSend(); - cmAckAdd->requestType = CmAdd::Prepare; - cmAckAdd->senderNodeId = getOwnNodeId(); - cmAckAdd->startingNodeId = getOwnNodeId(); - sendSignal(cpdistref, GSN_CM_ACKADD, signal, CmAckAdd::SignalLength, JBA); + sendCmAckAdd(signal, getOwnNodeId(), CmAdd::Prepare); return; }//Qmgr::execCM_NODEINFOCONF() @@ -970,59 +887,99 @@ void Qmgr::execCM_NODEINFOCONF(Signal* signal) /*******************************/ void Qmgr::execCM_NODEINFOREQ(Signal* signal) { - NodeRecPtr addNodePtr; - NodeRecPtr myNodePtr; jamEntry(); + const Uint32 Tblockref = signal->getSendersBlockRef(); + + NodeRecPtr nodePtr; + nodePtr.i = getOwnNodeId(); + ptrAss(nodePtr, nodeRec); + if(nodePtr.p->phase != ZRUNNING){ + jam(); + signal->theData[0] = reference(); + signal->theData[1] = getOwnNodeId(); + signal->theData[2] = ZNOT_RUNNING; + sendSignal(Tblockref, GSN_CM_NODEINFOREF, signal, 3, JBB); + return; + } + + NodeRecPtr addNodePtr; CmNodeInfoReq * const req = (CmNodeInfoReq*)signal->getDataPtr(); addNodePtr.i = req->nodeId; ptrCheckGuard(addNodePtr, MAX_NDB_NODES, nodeRec); addNodePtr.p->ndynamicId = req->dynamicId; + addNodePtr.p->blockRef = signal->getSendersBlockRef(); setNodeInfo(addNodePtr.i).m_version = req->version; - - const BlockReference Tblockref = signal->getSendersBlockRef(); + c_maxDynamicId = req->dynamicId; - myNodePtr.i = getOwnNodeId(); - ptrCheckGuard(myNodePtr, MAX_NDB_NODES, nodeRec); - if (myNodePtr.p->phase == ZRUNNING) { - if (addNodePtr.p->phase == ZWAITING) { - jam(); - /* President have prepared us */ - /****************************<*/ - /*< CM_NODEINFOCONF <*/ - /****************************<*/ - CmNodeInfoConf * const conf = (CmNodeInfoConf*)signal->getDataPtrSend(); - conf->nodeId = getOwnNodeId(); - conf->dynamicId = myNodePtr.p->ndynamicId; - conf->version = getNodeInfo(getOwnNodeId()).m_version; - sendSignal(Tblockref, GSN_CM_NODEINFOCONF, signal, - CmNodeInfoConf::SignalLength, JBB); - /****************************************/ - /* Send an ack. back to the president */ - /* CM_ACKADD */ - /****************************************/ - CmAckAdd * const cmAckAdd = (CmAckAdd*)signal->getDataPtrSend(); - cmAckAdd->requestType = CmAdd::Prepare; - cmAckAdd->senderNodeId = getOwnNodeId(); - cmAckAdd->startingNodeId = addNodePtr.i; - sendSignal(cpdistref, GSN_CM_ACKADD, signal, CmAckAdd::SignalLength, JBA); - } else { - jam(); - addNodePtr.p->phase = ZWAIT_PRESIDENT; - }//if - } else { - jam(); - /****************************<*/ - /*< CM_NODEINFOREF <*/ - /****************************<*/ - signal->theData[0] = myNodePtr.p->blockRef; - signal->theData[1] = myNodePtr.i; - signal->theData[2] = ZNOT_RUNNING; - sendSignal(Tblockref, GSN_CM_NODEINFOREF, signal, 3, JBB); - }//if - return; + cmAddPrepare(signal, addNodePtr, nodePtr.p); }//Qmgr::execCM_NODEINFOREQ() +void +Qmgr::cmAddPrepare(Signal* signal, NodeRecPtr nodePtr, const NodeRec * self){ + jam(); + + switch(nodePtr.p->phase){ + case ZINIT: + jam(); + nodePtr.p->phase = ZSTARTING; + return; + case ZFAIL_CLOSING: + jam(); +#ifdef VM_TRACE + ndbout_c("Enabling communication to CM_ADD node state=%d", + nodePtr.p->phase); +#endif + nodePtr.p->phase = ZSTARTING; + nodePtr.p->failState = NORMAL; + signal->theData[0] = 0; + signal->theData[1] = nodePtr.i; + sendSignal(CMVMI_REF, GSN_OPEN_COMREQ, signal, 2, JBA); + return; + case ZSTARTING: + break; + case ZRUNNING: + case ZPREPARE_FAIL: + case ZAPI_ACTIVE: + case ZAPI_INACTIVE: + ndbrequire(false); + } + + sendCmAckAdd(signal, nodePtr.i, CmAdd::Prepare); + + /* President have prepared us */ + CmNodeInfoConf * conf = (CmNodeInfoConf*)signal->getDataPtrSend(); + conf->nodeId = getOwnNodeId(); + conf->dynamicId = self->ndynamicId; + conf->version = getNodeInfo(getOwnNodeId()).m_version; + sendSignal(nodePtr.p->blockRef, GSN_CM_NODEINFOCONF, signal, + CmNodeInfoConf::SignalLength, JBB); + DEBUG_START(GSN_CM_NODEINFOCONF, refToNode(nodePtr.p->blockRef), ""); +} + +void +Qmgr::sendCmAckAdd(Signal * signal, Uint32 nodeId, CmAdd::RequestType type){ + + CmAckAdd * cmAckAdd = (CmAckAdd*)signal->getDataPtrSend(); + cmAckAdd->requestType = type; + cmAckAdd->startingNodeId = nodeId; + cmAckAdd->senderNodeId = getOwnNodeId(); + sendSignal(cpdistref, GSN_CM_ACKADD, signal, CmAckAdd::SignalLength, JBA); + DEBUG_START(GSN_CM_ACKADD, cpresident, ""); + + switch(type){ + case CmAdd::Prepare: + return; + case CmAdd::AddCommit: + case CmAdd::CommitNew: + break; + } + + signal->theData[0] = nodeId; + EXECUTE_DIRECT(NDBCNTR, GSN_CM_ADD_REP, signal, 1); + jamEntry(); +} + /* 4.4.11 CM_ADD */ /**-------------------------------------------------------------------------- @@ -1040,156 +997,130 @@ void Qmgr::execCM_NODEINFOREQ(Signal* signal) void Qmgr::execCM_ADD(Signal* signal) { NodeRecPtr addNodePtr; - NodeRecPtr nodePtr; - NodeRecPtr myNodePtr; jamEntry(); + NodeRecPtr nodePtr; + nodePtr.i = getOwnNodeId(); + ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); + CmAdd * const cmAdd = (CmAdd*)signal->getDataPtr(); const CmAdd::RequestType type = (CmAdd::RequestType)cmAdd->requestType; addNodePtr.i = cmAdd->startingNodeId; //const Uint32 startingVersion = cmAdd->startingVersion; ptrCheckGuard(addNodePtr, MAX_NDB_NODES, nodeRec); - if(addNodePtr.p->phase == ZFAIL_CLOSING){ + DEBUG_START3(signal, type); + + if(nodePtr.p->phase == ZSTARTING){ jam(); -#ifdef VM_TRACE - ndbout_c("Enabling communication to CM_ADD node state=%d", - addNodePtr.p->phase); -#endif - addNodePtr.p->failState = NORMAL; - signal->theData[0] = 0; - signal->theData[1] = addNodePtr.i; - sendSignal(CMVMI_REF, GSN_OPEN_COMREQ, signal, 2, JBA); + /** + * We are joining... + */ + ndbrequire(addNodePtr.i == nodePtr.i); + switch(type){ + case CmAdd::Prepare: + ndbrequire(c_start.m_gsn = GSN_CM_NODEINFOREQ); + /** + * Wait for CM_NODEINFO_CONF + */ + return; + case CmAdd::CommitNew: + /** + * Tata. we're in the cluster + */ + joinedCluster(signal, addNodePtr); + return; + case CmAdd::AddCommit: + ndbrequire(false); + } } - + switch (type) { case CmAdd::Prepare: - jam(); - if (addNodePtr.i != getOwnNodeId()) { - jam(); - if (addNodePtr.p->phase == ZWAIT_PRESIDENT) { - jam(); - /****************************<*/ - /*< CM_NODEINFOCONF <*/ - /****************************<*/ - myNodePtr.i = getOwnNodeId(); - ptrCheckGuard(myNodePtr, MAX_NDB_NODES, nodeRec); - - CmNodeInfoConf * const conf = (CmNodeInfoConf*)signal->getDataPtrSend(); - conf->nodeId = getOwnNodeId(); - conf->dynamicId = myNodePtr.p->ndynamicId; - conf->version = getNodeInfo(getOwnNodeId()).m_version; - sendSignal(addNodePtr.p->blockRef, GSN_CM_NODEINFOCONF, signal, - CmNodeInfoConf::SignalLength, JBB); - /****************************<*/ - /* Send an ack. back to the president */ - /*< CM_ACKADD <*/ - /****************************<*/ - CmAckAdd * const cmAckAdd = (CmAckAdd*)signal->getDataPtrSend(); - cmAckAdd->requestType = CmAdd::Prepare; - cmAckAdd->senderNodeId = getOwnNodeId(); - cmAckAdd->startingNodeId = addNodePtr.i; - sendSignal(cpdistref, GSN_CM_ACKADD, signal, CmAckAdd::SignalLength, JBA); - }//if - // ----------------------------------------- - /* Wait for the new node's CM_NODEINFOREQ.*/ - // ----------------------------------------- - addNodePtr.p->phase = ZWAITING; - }//if + cmAddPrepare(signal, addNodePtr, nodePtr.p); break; case CmAdd::AddCommit:{ jam(); + ndbrequire(addNodePtr.p->phase == ZSTARTING); addNodePtr.p->phase = ZRUNNING; addNodePtr.p->alarmCount = 0; + c_clusterNodes.set(addNodePtr.i); findNeighbours(signal); - /**----------------------------------------------------------------------- + + /** * SEND A HEARTBEAT IMMEDIATELY TO DECREASE THE RISK THAT WE MISS EARLY * HEARTBEATS. - *-----------------------------------------------------------------------*/ + */ sendHeartbeat(signal); - /*-----------------------------------------------------------------------*/ - /* ENABLE COMMUNICATION WITH ALL BLOCKS WITH THE NEWLY ADDED NODE. */ - /*-----------------------------------------------------------------------*/ + + /** + * ENABLE COMMUNICATION WITH ALL BLOCKS WITH THE NEWLY ADDED NODE + */ signal->theData[0] = addNodePtr.i; sendSignal(CMVMI_REF, GSN_ENABLE_COMORD, signal, 1, JBA); - /****************************<*/ - /*< CM_ACKADD <*/ - /****************************<*/ - CmAckAdd * const cmAckAdd = (CmAckAdd*)signal->getDataPtrSend(); - cmAckAdd->requestType = CmAdd::AddCommit; - cmAckAdd->senderNodeId = getOwnNodeId(); - cmAckAdd->startingNodeId = addNodePtr.i; - sendSignal(cpdistref, GSN_CM_ACKADD, signal, CmAckAdd::SignalLength, JBA); + + sendCmAckAdd(signal, addNodePtr.i, CmAdd::AddCommit); + if(getOwnNodeId() != cpresident){ + jam(); + c_start.reset(); + } break; } - case CmAdd::CommitNew:{ + case CmAdd::CommitNew: jam(); - /*-----------------------------------------------------------------------*/ - /* WE HAVE BEEN INCLUDED IN THE CLUSTER WE CAN START BEING PART OF THE - * HEARTBEAT PROTOCOL AND WE WILL ALSO ENABLE COMMUNICATION WITH ALL - * NODES IN THE CLUSTER. - *-----------------------------------------------------------------------*/ - addNodePtr.p->phase = ZRUNNING; - addNodePtr.p->alarmCount = 0; - findNeighbours(signal); - /**----------------------------------------------------------------------- - * SEND A HEARTBEAT IMMEDIATELY TO DECREASE THE RISK THAT WE MISS EARLY - * HEARTBEATS. - *-----------------------------------------------------------------------*/ - sendHeartbeat(signal); - cwaitContinuebPhase2 = ZFALSE; - /**----------------------------------------------------------------------- - * ENABLE COMMUNICATION WITH ALL BLOCKS IN THE CURRENT CLUSTER AND SET - * THE NODES IN THE CLUSTER TO BE RUNNING. - *-----------------------------------------------------------------------*/ - for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { - jam(); - ptrAss(nodePtr, nodeRec); - if ((nodePtr.p->phase == ZRUNNING) && - (nodePtr.i != getOwnNodeId())) { - /*-------------------------------------------------------------------*/ - // Enable full communication to all other nodes. Not really necessary - // to open communication to ourself. - /*-------------------------------------------------------------------*/ - jam(); - signal->theData[0] = nodePtr.i; - sendSignal(CMVMI_REF, GSN_ENABLE_COMORD, signal, 1, JBA); - }//if - }//for - - /****************************<*/ - /*< CM_ACKADD <*/ - /****************************<*/ - CmAckAdd * const cmAckAdd = (CmAckAdd*)signal->getDataPtrSend(); - cmAckAdd->requestType = CmAdd::CommitNew; - cmAckAdd->senderNodeId = getOwnNodeId(); - cmAckAdd->startingNodeId = addNodePtr.i; - sendSignal(cpdistref, GSN_CM_ACKADD, signal, CmAckAdd::SignalLength, JBA); - -#if 1 - /**********************************************<*/ - /* Allow the CLUSTER CONTROL to send STTORRY */ - /* so we can receive CM_REG from applications. */ - /**********************************************<*/ - signal->theData[0] = 0; - sendSignal(CMVMI_REF, GSN_CM_RUN, signal, 1, JBB); -#endif - - /** - * Start timer handling - */ - signal->theData[0] = ZTIMER_HANDLING; - sendSignal(QMGR_REF, GSN_CONTINUEB, signal, 10, JBB); + ndbrequire(false); } - break; - default: - jam(); - /*empty*/; - break; - }//switch - return; + }//Qmgr::execCM_ADD() +void +Qmgr::joinedCluster(Signal* signal, NodeRecPtr nodePtr){ + /** + * WE HAVE BEEN INCLUDED IN THE CLUSTER WE CAN START BEING PART OF THE + * HEARTBEAT PROTOCOL AND WE WILL ALSO ENABLE COMMUNICATION WITH ALL + * NODES IN THE CLUSTER. + */ + nodePtr.p->phase = ZRUNNING; + nodePtr.p->alarmCount = 0; + findNeighbours(signal); + c_clusterNodes.set(nodePtr.i); + c_start.reset(); + + /** + * SEND A HEARTBEAT IMMEDIATELY TO DECREASE THE RISK + * THAT WE MISS EARLY HEARTBEATS. + */ + sendHeartbeat(signal); + + /** + * ENABLE COMMUNICATION WITH ALL BLOCKS IN THE CURRENT CLUSTER AND SET + * THE NODES IN THE CLUSTER TO BE RUNNING. + */ + for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { + jam(); + ptrAss(nodePtr, nodeRec); + if ((nodePtr.p->phase == ZRUNNING) && (nodePtr.i != getOwnNodeId())) { + /*-------------------------------------------------------------------*/ + // Enable full communication to all other nodes. Not really necessary + // to open communication to ourself. + /*-------------------------------------------------------------------*/ + jam(); + signal->theData[0] = nodePtr.i; + sendSignal(CMVMI_REF, GSN_ENABLE_COMORD, signal, 1, JBA); + }//if + }//for + + sendSttorryLab(signal); + + /** + * Start timer handling + */ + signal->theData[0] = ZTIMER_HANDLING; + sendSignal(QMGR_REF, GSN_CONTINUEB, signal, 10, JBB); + + sendCmAckAdd(signal, getOwnNodeId(), CmAdd::CommitNew); +} + /* 4.10.7 CM_ACKADD - PRESIDENT IS RECEIVER - */ /*---------------------------------------------------------------------------*/ /* Entry point for an ack add signal. @@ -1198,7 +1129,6 @@ void Qmgr::execCM_ADD(Signal* signal) void Qmgr::execCM_ACKADD(Signal* signal) { NodeRecPtr addNodePtr; - NodeRecPtr nodePtr; NodeRecPtr senderNodePtr; jamEntry(); @@ -1206,109 +1136,86 @@ void Qmgr::execCM_ACKADD(Signal* signal) const CmAdd::RequestType type = (CmAdd::RequestType)cmAckAdd->requestType; addNodePtr.i = cmAckAdd->startingNodeId; senderNodePtr.i = cmAckAdd->senderNodeId; + + DEBUG_START3(signal, type); + if (cpresident != getOwnNodeId()) { jam(); /*-----------------------------------------------------------------------*/ /* IF WE ARE NOT PRESIDENT THEN WE SHOULD NOT RECEIVE THIS MESSAGE. */ /*------------------------------------------------------------_----------*/ + warningEvent("Received CM_ACKADD from %d president=%d", + senderNodePtr.i, cpresident); return; }//if - if (cpresidentBusy != ZTRUE) { - jam(); - /**---------------------------------------------------------------------- - * WE ARE PRESIDENT BUT WE ARE NOT BUSY ADDING ANY NODE. THUS WE MUST - * HAVE STOPPED THIS ADDING OF THIS NODE. - *----------------------------------------------------------------------*/ - return; - }//if - if (addNodePtr.i != cstartNode) { + + if (addNodePtr.i != c_start.m_startNode) { jam(); /*----------------------------------------------------------------------*/ /* THIS IS NOT THE STARTING NODE. WE ARE ACTIVE NOW WITH ANOTHER START. */ /*----------------------------------------------------------------------*/ + warningEvent("Received CM_ACKADD from %d with startNode=%d != own %d", + senderNodePtr.i, addNodePtr.i, c_start.m_startNode); return; }//if + + ndbrequire(c_start.m_gsn == GSN_CM_ADD); + c_start.m_nodes.clearWaitingFor(senderNodePtr.i); + if(!c_start.m_nodes.done()){ + jam(); + return; + } + switch (type) { case CmAdd::Prepare:{ jam(); - ptrCheckGuard(senderNodePtr, MAX_NDB_NODES, nodeRec); - senderNodePtr.p->sendCmAddPrepStatus = Q_NOT_ACTIVE; - for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { - jam(); - ptrAss(nodePtr, nodeRec); - /* Check if all prepare are acknowledged*/ - if (nodePtr.p->sendCmAddPrepStatus == Q_ACTIVE) { - jam(); - return; /* Wait for more acknowledge's */ - }//if - }//for + /*----------------------------------------------------------------------*/ /* ALL RUNNING NODES HAVE PREPARED THE INCLUSION OF THIS NEW NODE. */ /*----------------------------------------------------------------------*/ + c_start.m_gsn = GSN_CM_ADD; + c_start.m_nodes = c_clusterNodes; + CmAdd * const cmAdd = (CmAdd*)signal->getDataPtrSend(); cmAdd->requestType = CmAdd::AddCommit; cmAdd->startingNodeId = addNodePtr.i; cmAdd->startingVersion = getNodeInfo(addNodePtr.i).m_version; - for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { - jam(); - ptrAss(nodePtr, nodeRec); - if (nodePtr.p->phase == ZRUNNING) { - jam(); - sendSignal(nodePtr.p->blockRef, GSN_CM_ADD, signal, - CmAdd::SignalLength, JBA); - nodePtr.p->sendCmAddCommitStatus = Q_ACTIVE; - }//if - }//for + NodeReceiverGroup rg(QMGR, c_clusterNodes); + sendSignal(rg, GSN_CM_ADD, signal, CmAdd::SignalLength, JBA); + DEBUG_START2(GSN_CM_ADD, rg, "AddCommit"); return; - break; } case CmAdd::AddCommit:{ jam(); - ptrCheckGuard(senderNodePtr, MAX_NDB_NODES, nodeRec); - senderNodePtr.p->sendCmAddCommitStatus = Q_NOT_ACTIVE; - for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { - jam(); - ptrAss(nodePtr, nodeRec); - /* Check to see if we need to wait for */ - if (nodePtr.p->sendCmAddCommitStatus == Q_ACTIVE) { - jam(); - /* any more ack. commit add. */ - return; /* Exit and continue waiting. */ - }//if - }//for + /****************************************/ /* Send commit to the new node so he */ /* will change PHASE into ZRUNNING */ /****************************************/ + c_start.m_gsn = GSN_CM_ADD; + c_start.m_nodes.clearWaitingFor(); + c_start.m_nodes.setWaitingFor(addNodePtr.i); + CmAdd * const cmAdd = (CmAdd*)signal->getDataPtrSend(); cmAdd->requestType = CmAdd::CommitNew; cmAdd->startingNodeId = addNodePtr.i; cmAdd->startingVersion = getNodeInfo(addNodePtr.i).m_version; - ptrCheckGuard(addNodePtr, MAX_NDB_NODES, nodeRec); - sendSignal(addNodePtr.p->blockRef, GSN_CM_ADD, signal, + sendSignal(calcQmgrBlockRef(addNodePtr.i), GSN_CM_ADD, signal, CmAdd::SignalLength, JBA); - break; + DEBUG_START(GSN_CM_ADD, addNodePtr.i, "CommitNew"); + return; } case CmAdd::CommitNew: jam(); - /*----------------------------------------------------------------------*/ - /* Increment the amount of nodes in the cluster in waiting mode. */ - /* President now ready for more CM_REGREQ */ - /*----------------------------------------------------------------------*/ - cclustersize = cclustersize + 1; /** * Tell arbitration about new node. */ handleArbitNdbAdd(signal, addNodePtr.i); - cpresidentBusy = ZFALSE; - break; - default: - jam(); - /*empty*/; - break; + c_start.reset(); + return; }//switch - return; + ndbrequire(false); }//Qmgr::execCM_ACKADD() /**------------------------------------------------------------------------- @@ -1433,51 +1340,30 @@ void Qmgr::findNeighbours(Signal* signal) /*---------------------------------------------------------------------------*/ void Qmgr::initData(Signal* signal) { - RegAppPtr localRegAppptr; - - for (localRegAppptr.i = 0; - localRegAppptr.i < NO_REG_APP; localRegAppptr.i++) { - ptrAss(localRegAppptr, regApp); - localRegAppptr.p->version = 0; - localRegAppptr.p->blockref = 0; - memset(localRegAppptr.p->name, 0, sizeof(localRegAppptr.p->name)); - localRegAppptr.p->activity = ZREMOVE; - localRegAppptr.p->noofapps = 0; - localRegAppptr.p->noofpending = 0; - localRegAppptr.p->m_runNodes.clear(); - }//for - NodeRecPtr nodePtr; for (nodePtr.i = 1; nodePtr.i < MAX_NODES; nodePtr.i++) { ptrAss(nodePtr, nodeRec); nodePtr.p->ndynamicId = 0; - /* Subr NEXT_DYNAMIC_ID will use this to find */ - /* a unique higher value than any of these */ - - /* Not in config file */ - nodePtr.p->phase = ZBLOCKED; + if(getNodeInfo(nodePtr.i).m_type == NodeInfo::DB){ + nodePtr.p->phase = ZINIT; + c_definedNodes.set(nodePtr.i); + } else { + nodePtr.p->phase = ZAPI_INACTIVE; + } + nodePtr.p->alarmCount = 0; nodePtr.p->sendPrepFailReqStatus = Q_NOT_ACTIVE; nodePtr.p->sendCommitFailReqStatus = Q_NOT_ACTIVE; - nodePtr.p->sendCmAddPrepStatus = Q_NOT_ACTIVE; - nodePtr.p->sendCmAddCommitStatus = Q_NOT_ACTIVE; nodePtr.p->sendPresToStatus = Q_NOT_ACTIVE; - nodePtr.p->m_connected = false; nodePtr.p->failState = NORMAL; nodePtr.p->rcv[0] = 0; nodePtr.p->rcv[1] = 0; }//for - ccm_infoconfCounter = 0; cfailureNr = 1; ccommitFailureNr = 1; cprepareFailureNr = 1; cnoFailedNodes = 0; cnoPrepFailedNodes = 0; - cwaitContinuebPhase1 = ZFALSE; - cwaitContinuebPhase2 = ZFALSE; - cstartNo = 0; - cpresidentBusy = ZFALSE; - cacceptRegreq = ZTRUE; creadyDistCom = ZFALSE; cpresident = ZNIL; cpresidentCandidate = ZNIL; @@ -1496,55 +1382,58 @@ void Qmgr::initData(Signal* signal) // catch-all for missing initializations memset(&arbitRec, 0, sizeof(arbitRec)); -}//Qmgr::initData() -/* -4.10.7 PREPARE_ADD */ -/**-------------------------------------------------------------------------- - * President sends CM_ADD to prepare all running nodes to add a new node. - * Even the president node will get a CM_ADD (prepare). - * The new node will make REQs to all running nodes after it has received the - * CM_REGCONF. The president will just coordinate the adding of new nodes. - * The CM_ADD (prepare) is sent to the cluster before the CM_REGCONF signal - * to the new node. - * - * At the same time we will store all running nodes in CNODEMASK, - * which will be sent to the new node - * Scan the NODE_REC for all running nodes and create a nodemask where - * each bit represents a node. - * --------------------------------------------------------------------------*/ -void Qmgr::prepareAdd(Signal* signal, Uint16 anAddedNode) -{ - NodeRecPtr nodePtr; - NdbNodeBitmask::clear(cnodemask); + /** + * Timeouts + */ + const ndb_mgm_configuration_iterator * p = + theConfiguration.getOwnConfigIterator(); + ndbrequire(p != 0); - CmAdd * const cmAdd = (CmAdd*)signal->getDataPtrSend(); - cmAdd->requestType = CmAdd::Prepare; - cmAdd->startingNodeId = anAddedNode; - cmAdd->startingVersion = getNodeInfo(anAddedNode).m_version; - for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { - jam(); - ptrAss(nodePtr, nodeRec); - if (nodePtr.p->phase == ZRUNNING) { - jam(); - /* We found a node to prepare. */ - NdbNodeBitmask::set(cnodemask, nodePtr.i); - sendSignal(nodePtr.p->blockRef, GSN_CM_ADD, signal, CmAdd::SignalLength, JBA); - nodePtr.p->sendCmAddPrepStatus = Q_ACTIVE; - }//if - }//for + Uint32 hbDBDB = 1500; + Uint32 hbDBAPI = 1500; + Uint32 arbitTimeout = 1000; + c_restartPartialTimeout = 30000; + ndb_mgm_get_int_parameter(p, CFG_DB_HEARTBEAT_INTERVAL, &hbDBDB); + ndb_mgm_get_int_parameter(p, CFG_DB_API_HEARTBEAT_INTERVAL, &hbDBAPI); + ndb_mgm_get_int_parameter(p, CFG_DB_ARBIT_TIMEOUT, &arbitTimeout); + ndb_mgm_get_int_parameter(p, CFG_DB_START_PARTIAL_TIMEOUT, + &c_restartPartialTimeout); + if(c_restartPartialTimeout == 0){ + c_restartPartialTimeout = ~0; + } + + setHbDelay(hbDBDB); + setHbApiDelay(hbDBAPI); + setArbitTimeout(arbitTimeout); + + arbitRec.state = ARBIT_NULL; // start state for all nodes + arbitRec.apiMask[0].clear(); // prepare for ARBIT_CFG + + ArbitSignalData* const sd = (ArbitSignalData*)&signal->theData[0]; + for (unsigned rank = 1; rank <= 2; rank++) { + sd->sender = getOwnNodeId(); + sd->code = rank; + sd->node = 0; + sd->ticket.clear(); + sd->mask.clear(); + ndb_mgm_configuration_iterator * iter = + theConfiguration.getClusterConfigIterator(); + for (ndb_mgm_first(iter); ndb_mgm_valid(iter); ndb_mgm_next(iter)) { + Uint32 tmp = 0; + if (ndb_mgm_get_int_parameter(iter, CFG_NODE_ARBIT_RANK, &tmp) == 0 && + tmp == rank){ + Uint32 nodeId = 0; + ndbrequire(!ndb_mgm_get_int_parameter(iter, CFG_NODE_ID, &nodeId)); + sd->mask.set(nodeId); + } + } + + execARBIT_CFG(signal); + } + setNodeInfo(getOwnNodeId()).m_version = NDB_VERSION; +}//Qmgr::initData() - NodeRecPtr addNodePtr; - addNodePtr.i = anAddedNode; - ptrCheckGuard(addNodePtr, MAX_NDB_NODES, nodeRec); - /*****************************< - * We send to the node to be added a CM_ADD as well. - * We want him to send an ack when he has - * received all CM_NODEINFOCONF. - */ - sendSignal(addNodePtr.p->blockRef, GSN_CM_ADD, signal, CmAdd::SignalLength, JBA); - addNodePtr.p->sendCmAddPrepStatus = Q_ACTIVE; -}//Qmgr::prepareAdd() /**--------------------------------------------------------------------------- * HERE WE RECEIVE THE JOB TABLE SIGNAL EVERY 10 MILLISECONDS. @@ -1695,22 +1584,23 @@ void Qmgr::apiHbHandlingLab(Signal* signal) NodeRecPtr TnodePtr; for (TnodePtr.i = 1; TnodePtr.i < MAX_NODES; TnodePtr.i++) { + const Uint32 nodeId = TnodePtr.i; ptrAss(TnodePtr, nodeRec); - const NodeInfo::NodeType type = getNodeInfo(TnodePtr.i).getType(); + const NodeInfo::NodeType type = getNodeInfo(nodeId).getType(); if(type == NodeInfo::DB) continue; if(type == NodeInfo::INVALID) continue; - if (TnodePtr.p->m_connected && TnodePtr.p->phase != ZAPI_INACTIVE){ + if (TnodePtr.p->phase == ZAPI_ACTIVE){ jam(); TnodePtr.p->alarmCount ++; - + if(TnodePtr.p->alarmCount > 2){ signal->theData[0] = EventReport::MissedHeartbeat; - signal->theData[1] = TnodePtr.i; + signal->theData[1] = nodeId; signal->theData[2] = TnodePtr.p->alarmCount - 1; sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB); } @@ -1725,10 +1615,10 @@ void Qmgr::apiHbHandlingLab(Signal* signal) /* We call node_failed to release all connections for this api node */ /*------------------------------------------------------------------*/ signal->theData[0] = EventReport::DeadDueToHeartbeat; - signal->theData[1] = TnodePtr.i; + signal->theData[1] = nodeId; sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB); - node_failed(signal, TnodePtr.i); + node_failed(signal, nodeId); }//if }//if }//for @@ -1748,7 +1638,7 @@ void Qmgr::checkStartInterface(Signal* signal) if (nodePtr.p->phase == ZFAIL_CLOSING) { jam(); nodePtr.p->alarmCount = nodePtr.p->alarmCount + 1; - if (nodePtr.p->m_connected) { + if (c_connectedNodes.get(nodePtr.i)){ jam(); /*-------------------------------------------------------------------*/ // We need to ensure that the connection is not restored until it has @@ -1766,11 +1656,12 @@ void Qmgr::checkStartInterface(Signal* signal) nodePtr.p->failState = NORMAL; if (getNodeInfo(nodePtr.i).m_type != NodeInfo::DB){ jam(); - nodePtr.p->phase = ZBLOCKED; + nodePtr.p->phase = ZAPI_INACTIVE; } else { jam(); nodePtr.p->phase = ZINIT; }//if + nodePtr.p->alarmCount = 0; signal->theData[0] = 0; signal->theData[1] = nodePtr.i; @@ -1908,13 +1799,13 @@ void Qmgr::execNDB_FAILCONF(Signal* signal) for (nodePtr.i = 1; nodePtr.i < MAX_NODES; nodePtr.i++) { jam(); ptrAss(nodePtr, nodeRec); - if ((nodePtr.p->phase == ZAPI_ACTIVE) && nodePtr.p->m_connected) { + if (nodePtr.p->phase == ZAPI_ACTIVE){ jam(); sendSignal(nodePtr.p->blockRef, GSN_NF_COMPLETEREP, signal, NFCompleteRep::SignalLength, JBA); }//if }//for - }//if + } return; }//Qmgr::execNDB_FAILCONF() @@ -1923,14 +1814,28 @@ void Qmgr::execNDB_FAILCONF(Signal* signal) /*******************************/ void Qmgr::execDISCONNECT_REP(Signal* signal) { + jamEntry(); const DisconnectRep * const rep = (DisconnectRep *)&signal->theData[0]; - NodeRecPtr failedNodePtr; + const Uint32 nodeId = rep->nodeId; + c_connectedNodes.clear(nodeId); - jamEntry(); - failedNodePtr.i = rep->nodeId; - ptrCheckGuard(failedNodePtr, MAX_NODES, nodeRec); - failedNodePtr.p->m_connected = false; - node_failed(signal, failedNodePtr.i); + NodeRecPtr nodePtr; + nodePtr.i = getOwnNodeId(); + ptrCheckGuard(nodePtr, MAX_NODES, nodeRec); + switch(nodePtr.p->phase){ + case ZRUNNING: + jam(); + break; + case ZINIT: + case ZSTARTING: + case ZPREPARE_FAIL: + case ZFAIL_CLOSING: + case ZAPI_ACTIVE: + case ZAPI_INACTIVE: + ndbrequire(false); + } + + node_failed(signal, nodeId); }//DISCONNECT_REP void Qmgr::node_failed(Signal* signal, Uint16 aFailedNode) @@ -1957,6 +1862,9 @@ void Qmgr::node_failed(Signal* signal, Uint16 aFailedNode) case ZFAIL_CLOSING: jam(); return; + case ZSTARTING: + c_start.reset(); + // Fall-through default: jam(); /*---------------------------------------------------------------------*/ @@ -1987,11 +1895,11 @@ void Qmgr::node_failed(Signal* signal, Uint16 aFailedNode) jam(); if (failedNodePtr.p->phase != ZFAIL_CLOSING){ jam(); - //-------------------------------------------------------------------------- + //------------------------------------------------------------------------- // The API was active and has now failed. We need to initiate API failure // handling. If the API had already failed then we can ignore this // discovery. - //-------------------------------------------------------------------------- + //------------------------------------------------------------------------- failedNodePtr.p->phase = ZFAIL_CLOSING; sendApiFailReq(signal, aFailedNode); @@ -2056,11 +1964,6 @@ void Qmgr::execAPI_REGREQ(Signal* signal) apiRegConf->qmgrRef = reference(); apiRegConf->apiHeartbeatFrequency = (chbApiDelay / 10); apiRegConf->version = NDB_VERSION; - - - // if(apiNodePtr.i == getNodeState.single. && NodeState::SL_MAINTENANCE) - // apiRegConf->nodeState = NodeState::SL_STARTED; - //else apiRegConf->nodeState = getNodeState(); { NodeRecPtr nodePtr; @@ -2079,7 +1982,7 @@ void Qmgr::execAPI_REGREQ(Signal* signal) if ((getNodeState().startLevel == NodeState::SL_STARTED || getNodeState().getSingleUserMode()) - && apiNodePtr.p->phase == ZBLOCKED) { + && apiNodePtr.p->phase == ZAPI_INACTIVE) { jam(); /**---------------------------------------------------------------------- * THE API NODE IS REGISTERING. WE WILL ACCEPT IT BY CHANGING STATE AND @@ -2186,15 +2089,6 @@ void Qmgr::failReportLab(Signal* signal, Uint16 aFailedNode, failReport(signal, failedNodePtr.i, (UintR)ZTRUE, aFailCause); if (cpresident == getOwnNodeId()) { jam(); - if (cpresidentBusy == ZTRUE) { - jam(); -/**------------------------------------------------------------------- -* ALL STARTING NODES ARE CRASHED WHEN AN ALIVE NODE FAILS DURING ITS -* START-UP. AS PRESIDENT OF THE CLUSTER IT IS OUR DUTY TO INFORM OTHERS -* ABOUT THIS. -*---------------------------------------------------------------------*/ - failReport(signal, cstartNode, (UintR)ZTRUE, FailRep::ZOTHER_NODE_WHEN_WE_START); - }//if if (ctoStatus == Q_NOT_ACTIVE) { jam(); /**-------------------------------------------------------------------- @@ -2525,9 +2419,7 @@ void Qmgr::execCOMMIT_FAILREQ(Signal* signal) return; }//if UintR guard0; - UintR Ti; UintR Tj; - RegAppPtr localRegAppptr; /** * Block commit until node failures has stabilized @@ -2547,37 +2439,19 @@ void Qmgr::execCOMMIT_FAILREQ(Signal* signal) * SIGNAL. WE CAN HEAR IT SEVERAL TIMES IF THE PRESIDENTS KEEP FAILING. *-----------------------------------------------------------------------*/ ccommitFailureNr = TfailureNr; - for (localRegAppptr.i = 0; - localRegAppptr.i < NO_REG_APP; localRegAppptr.i++) { + NodeFailRep * const nodeFail = (NodeFailRep *)&signal->theData[0]; + + nodeFail->failNo = ccommitFailureNr; + nodeFail->noOfNodes = cnoCommitFailedNodes; + nodeFail->masterNodeId = cpresident; + NodeBitmask::clear(nodeFail->theNodes); + for(unsigned i = 0; i < cnoCommitFailedNodes; i++) { jam(); - ptrAss(localRegAppptr, regApp); - if (localRegAppptr.p->activity != ZREMOVE) { - /*------------------------------------------------------------------*/ - // We need to remove the failed nodes from the set of running nodes - // in the registered application. - //------------------------------------------------------------------*/ - for (Ti = 0; Ti < cnoCommitFailedNodes; Ti++) { - jam(); - arrGuard(ccommitFailedNodes[Ti], MAX_NDB_NODES); - localRegAppptr.p->m_runNodes.clear(ccommitFailedNodes[Ti]); - }//for - /*------------------------------------------------------------------*/ - // Send a signal to the registered application to inform him of the - // node failure(s). - /*------------------------------------------------------------------*/ - NodeFailRep * const nodeFail = (NodeFailRep *)&signal->theData[0]; + NodeBitmask::set(nodeFail->theNodes, ccommitFailedNodes[i]); + }//if + sendSignal(NDBCNTR_REF, GSN_NODE_FAILREP, signal, + NodeFailRep::SignalLength, JBB); - nodeFail->failNo = ccommitFailureNr; - nodeFail->noOfNodes = cnoCommitFailedNodes; - NodeBitmask::clear(nodeFail->theNodes); - for(unsigned i = 0; i < cnoCommitFailedNodes; i++) { - jam(); - NodeBitmask::set(nodeFail->theNodes, ccommitFailedNodes[i]); - }//if - sendSignal(localRegAppptr.p->blockref, GSN_NODE_FAILREP, signal, - NodeFailRep::SignalLength, JBB); - }//if - }//for guard0 = cnoCommitFailedNodes - 1; arrGuard(guard0, MAX_NDB_NODES); /**-------------------------------------------------------------------- @@ -2591,6 +2465,7 @@ void Qmgr::execCOMMIT_FAILREQ(Signal* signal) nodePtr.p->phase = ZFAIL_CLOSING; nodePtr.p->failState = WAITING_FOR_NDB_FAILCONF; nodePtr.p->alarmCount = 0; + c_clusterNodes.clear(nodePtr.i); }//for /*----------------------------------------------------------------------*/ /* WE INFORM THE API'S WE HAVE CONNECTED ABOUT THE FAILED NODES. */ @@ -2753,226 +2628,31 @@ void Qmgr::execPRES_TOCONF(Signal* signal) /*--------------------------------------------------------------------------*/ void Qmgr::execREAD_NODESREQ(Signal* signal) { - NodeRecPtr nodePtr; - UintR TnoOfNodes = 0; + jamEntry(); + BlockReference TBref = signal->theData[0]; ReadNodesConf * const readNodes = (ReadNodesConf *)&signal->theData[0]; - NodeBitmask::clear(readNodes->allNodes); - for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { - jam(); - ptrAss(nodePtr, nodeRec); - if (getNodeInfo(nodePtr.i).getType() == NodeInfo::DB){ - jam(); - TnoOfNodes++; - NodeBitmask::set(readNodes->allNodes, nodePtr.i); - }//if - }//for - readNodes->noOfNodes = TnoOfNodes; - sendSignal(TBref, GSN_READ_NODESCONF, signal, - ReadNodesConf::SignalLength, JBB); -}//Qmgr::execREAD_NODESREQ() -/*-------------------------------------------------------------------------- - * Signal from an application requesting to be monitored in the cluster. - * APPL_REGREQ can be entered at any time during the life of the QMGR. - * It can be entered any number of times. - * If QMGR is ZRUNNING a CM_APPCHG will be sent to all active nodes. - *---------------------------------------------------------------------------*/ -void Qmgr::execAPPL_REGREQ(Signal* signal) -{ NodeRecPtr nodePtr; - NodeRecPtr myNodePtr; - RegAppPtr lRegApptr; - char Tappname[16]; - jamEntry(); - BlockReference Tappref = signal->theData[0]; - Tappname[0] = signal->theData[1] >> 8; - Tappname[1] = signal->theData[2]; - Tappname[2] = signal->theData[2] >> 8; - Tappname[3] = signal->theData[3]; - Tappname[4] = signal->theData[3] >> 8; - Tappname[5] = signal->theData[4]; - Tappname[6] = signal->theData[4] >> 8; - Tappname[7] = signal->theData[5]; - Tappname[8] = signal->theData[5] >> 8; - Tappname[9] = signal->theData[6]; - Tappname[10] = signal->theData[6] >> 8; - Tappname[11] = signal->theData[7]; - Tappname[12] = signal->theData[7] >> 8; - Tappname[13] = signal->theData[8]; - Tappname[14] = signal->theData[8] >> 8; - Tappname[signal->theData[1] & 0xFF] = 0; - UintR Tversion = signal->theData[10]; - Uint16 Tnodeno = refToNode(Tappref); - if (Tnodeno == 0) { - jam(); - /* Fix for all not distributed applications. */ - Tnodeno = getOwnNodeId(); - }//if - if (getOwnNodeId() == Tnodeno) { - jam(); - /* Local application */ - UintR Tfound = RNIL; - for (lRegApptr.i = NO_REG_APP-1; (Uint16)~lRegApptr.i; lRegApptr.i--) { - jam(); - ptrAss(lRegApptr, regApp); - if (lRegApptr.p->activity == ZREMOVE) { - Tfound = lRegApptr.i; - break; - }//if - }//for - if (Tfound != RNIL) { - jam(); - /* If there was a slot available we */ - /* register the application */ - lRegApptr.i = Tfound; - ptrCheckGuard(lRegApptr, NO_REG_APP, regApp); - lRegApptr.p->blockref = Tappref; - strcpy(lRegApptr.p->name, Tappname); - lRegApptr.p->version = Tversion; - lRegApptr.p->activity = ZADD; - myNodePtr.i = getOwnNodeId(); - ptrCheckGuard(myNodePtr, MAX_NDB_NODES, nodeRec); - /****************************<*/ - /*< APPL_REGCONF <*/ - /****************************<*/ - signal->theData[0] = lRegApptr.i; - signal->theData[1] = cnoOfNodes; - signal->theData[2] = cpresident; - signal->theData[3] = myNodePtr.p->ndynamicId; - sendSignal(lRegApptr.p->blockref, GSN_APPL_REGCONF, signal, 4, JBB); - if (myNodePtr.p->phase == ZRUNNING) { - jam(); - /* Check to see if any further action */ - for (nodePtr.i = 1; - nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { - jam(); - ptrAss(nodePtr, nodeRec); - /* is needed at this time */ - if (nodePtr.p->phase == ZRUNNING) { - jam(); - sendappchg(signal, lRegApptr.i, nodePtr.i); - }//if - }//for - }//if - } else { - jam(); - /****************************<*/ - /*< APPL_REGREF <*/ - /****************************<*/ - signal->theData[0] = ZERRTOOMANY; - sendSignal(Tappref, GSN_APPL_REGREF, signal, 1, JBB); - }//if - } else { - jam(); - /* TOO MANY REGISTERED APPLICATIONS */ - systemErrorLab(signal); - }//if - return; -}//Qmgr::execAPPL_REGREQ() - -/* -4.4.11 APPL_STARTREG */ -/**-------------------------------------------------------------------------- - * Signal from an application indicating that it is ready to start running - * distributed. If the application is running alone or if all other - * applications of the same kind already have registered as STARTING then - * APPL_STARTCONF will be sent to the application as soon as phase four of - * STTOR is reached. - *--------------------------------------------------------------------------*/ -/*******************************/ -/* APPL_STARTREG */ -/*******************************/ -void Qmgr::execAPPL_STARTREG(Signal* signal) -{ - RegAppPtr lRegApptr; - NodeRecPtr myNodePtr; - UintR TnodeId; - jamEntry(); - lRegApptr.i = signal->theData[0]; - ptrCheckGuard(lRegApptr, NO_REG_APP, regApp); - UintR Tcounter = signal->theData[1]; + nodePtr.i = getOwnNodeId(); + ptrCheckGuard(nodePtr, MAX_NDB_NODES, nodeRec); - lRegApptr.p->activity = ZSTART; - /* Application is ready to start. */ + NdbNodeBitmask tmp = c_definedNodes; + tmp.bitANDC(c_clusterNodes); - /* Calculate how many apps we wait for */ - lRegApptr.p->noofapps = (Tcounter - 1) - lRegApptr.p->noofpending; - /* send info to all other running nodes in the */ - myNodePtr.i = getOwnNodeId(); - ptrCheckGuard(myNodePtr, MAX_NDB_NODES, nodeRec); - /* cluster indicating the status change of the */ - if (myNodePtr.p->phase == ZRUNNING) { - /* application. */ - for (TnodeId = 1; TnodeId < MAX_NDB_NODES; TnodeId++) { - jam(); - if (lRegApptr.p->m_runNodes.get(TnodeId)){ - jam(); - sendappchg(signal, lRegApptr.i, TnodeId); - }//if - }//for - }//if - /****************************<*/ - /*< APPL_STARTCONF <*/ - /****************************<*/ - if (lRegApptr.p->noofapps == 0) { - jam(); - sendSignal(lRegApptr.p->blockref, GSN_APPL_STARTCONF, signal, 1, JBB); - }//if - return; -}//Qmgr::execAPPL_STARTREG() - -/* - 4.4.11 APPL_RUN */ -/*--------------------------------------------------------------------------*/ -/* Signal from an application announcing that it is running. */ -/*--------------------------------------------------------------------------*/ -/*******************************/ -/* APPL_RUN */ -/*******************************/ -void Qmgr::execAPPL_RUN(Signal* signal) -{ - RegAppPtr lRegApptr; - NodeRecPtr myNodePtr; - UintR TnodeId; - jamEntry(); - lRegApptr.i = signal->theData[0]; - ptrCheckGuard(lRegApptr, NO_REG_APP, regApp); - lRegApptr.p->activity = ZRUN; - /* Flag the application as running. */ - myNodePtr.i = getOwnNodeId(); - ptrCheckGuard(myNodePtr, MAX_NDB_NODES, nodeRec); - if (myNodePtr.p->phase == ZRUNNING) { - /* If we are running send the appl. status */ - for (TnodeId = 1; TnodeId < MAX_NDB_NODES; TnodeId++) { - jam(); - /* change to all other running nodes. */ - if (lRegApptr.p->m_runNodes.get(TnodeId)){ - jam(); - sendappchg(signal, lRegApptr.i, TnodeId); - }//if - }//for - }//if - /****************************<*/ - /*< CM_RUN <*/ - /****************************<*/ - /*---------------------------------------------------*/ - /* Inform the CLUSTER CONTROL of NDB started */ - /* so we can connect to API nodes. */ - /*---------------------------------------------------*/ - signal->theData[0] = 1; - sendSignal(CMVMI_REF, GSN_CM_RUN, signal, 1, JBB); - cactivateApiCheck = 1; - /** - * Start arbitration thread. This could be done as soon as - * we have all nodes (or a winning majority). - */ - if (cpresident == getOwnNodeId()) - handleArbitStart(signal); - return; -}//Qmgr::execAPPL_RUN() + readNodes->noOfNodes = c_definedNodes.count(); + readNodes->masterNodeId = cpresident; + readNodes->ndynamicId = nodePtr.p->ndynamicId; + c_definedNodes.copyto(NdbNodeBitmask::Size, readNodes->definedNodes); + c_clusterNodes.copyto(NdbNodeBitmask::Size, readNodes->clusterNodes); + tmp.copyto(NdbNodeBitmask::Size, readNodes->inactiveNodes); + NdbNodeBitmask::clear(readNodes->startingNodes); + NdbNodeBitmask::clear(readNodes->startedNodes); + sendSignal(TBref, GSN_READ_NODESCONF, signal, + ReadNodesConf::SignalLength, JBB); +}//Qmgr::execREAD_NODESREQ() void Qmgr::systemErrorBecauseOtherNodeFailed(Signal* signal, NodeId failedNodeId) { @@ -3003,234 +2683,6 @@ void Qmgr::systemErrorLab(Signal* signal, const char * message) return; }//Qmgr::systemErrorLab() -/* -4.4.11 CM_APPCHG */ -/*---------------------------------------------------------------------------*/ -/*Signal between two QMGRs used to announce any changes of state for an appl.*/ -/*---------------------------------------------------------------------------*/ -/*******************************/ -/* CM_APPCHG */ -/*******************************/ -void Qmgr::execCM_APPCHG(Signal* signal) -{ - RegAppPtr lRegApptr; - char Tappname[16]; - jamEntry(); - UintR Ttype = signal->theData[0]; - Uint16 Tnodeno = signal->theData[1]; - Tappname[0] = signal->theData[2] >> 8; - Tappname[1] = signal->theData[3]; - Tappname[2] = signal->theData[3] >> 8; - Tappname[3] = signal->theData[4]; - Tappname[4] = signal->theData[4] >> 8; - Tappname[5] = signal->theData[5]; - Tappname[6] = signal->theData[5] >> 8; - Tappname[7] = signal->theData[6]; - Tappname[8] = signal->theData[6] >> 8; - Tappname[9] = signal->theData[7]; - Tappname[10] = signal->theData[7] >> 8; - Tappname[11] = signal->theData[8]; - Tappname[12] = signal->theData[8] >> 8; - Tappname[13] = signal->theData[9]; - Tappname[14] = signal->theData[9] >> 8; - Tappname[signal->theData[2] & 0xFF] = 0; - UintR Tversion = signal->theData[11]; - switch (Ttype) { - case ZADD: - jam(); - /* A new application has started on the sending node */ - for (lRegApptr.i = NO_REG_APP-1; (Uint16)~lRegApptr.i; lRegApptr.i--) { - jam(); - /* We are hosting this application */ - ptrAss(lRegApptr, regApp); - if (strcmp(lRegApptr.p->name, Tappname) == 0) { - cmappAdd(signal, lRegApptr.i, Tnodeno, Ttype, Tversion); - }//if - }//for - break; - - case ZSTART: - jam(); - /* A registered application is ready to start on the sending node */ - for (lRegApptr.i = NO_REG_APP-1; (Uint16)~lRegApptr.i; lRegApptr.i--) { - jam(); - ptrAss(lRegApptr, regApp); - if (strcmp(lRegApptr.p->name, Tappname) == 0) { - cmappStart(signal, lRegApptr.i, Tnodeno, Ttype, Tversion); - }//if - }//for - break; - - case ZRUN: - /* A registered application on the sending node has started to run */ - jam(); - for (lRegApptr.i = NO_REG_APP-1; (Uint16)~lRegApptr.i; lRegApptr.i--) { - jam(); - ptrAss(lRegApptr, regApp); - if (strcmp(lRegApptr.p->name, Tappname) == 0) { - arrGuard(Tnodeno, MAX_NDB_NODES); - lRegApptr.p->m_runNodes.set(Tnodeno); - applchangerep(signal, lRegApptr.i, Tnodeno, Ttype, Tversion); - }//if - }//for - cacceptRegreq = ZTRUE; /* We can now start accepting new CM_REGREQ */ - /* since the new node is running */ - break; - - case ZREMOVE: - /* A registered application has been deleted on the sending node */ - jam(); - for (lRegApptr.i = NO_REG_APP-1; (Uint16)~lRegApptr.i; lRegApptr.i--) { - jam(); - ptrAss(lRegApptr, regApp); - if (strcmp(lRegApptr.p->name, Tappname) == 0) { - applchangerep(signal, lRegApptr.i, Tnodeno, Ttype, Tversion); - }//if - }//for - break; - - default: - jam(); - /*empty*/; - break; - }//switch - return; -}//Qmgr::execCM_APPCHG() - -/**-------------------------------------------------------------------------- - * INPUT REG_APPPTR - * TNODENO - *--------------------------------------------------------------------------*/ -void Qmgr::applchangerep(Signal* signal, - UintR aRegApp, - Uint16 aNode, - UintR aType, - UintR aVersion) -{ - RegAppPtr lRegApptr; - NodeRecPtr localNodePtr; - lRegApptr.i = aRegApp; - ptrCheckGuard(lRegApptr, NO_REG_APP, regApp); - if (lRegApptr.p->blockref != 0) { - jam(); - localNodePtr.i = aNode; - ptrCheckGuard(localNodePtr, MAX_NDB_NODES, nodeRec); - /****************************************/ - /* Send a report of changes on another */ - /* node to the local application */ - /****************************************/ - signal->theData[0] = aType; - signal->theData[1] = aVersion; - signal->theData[2] = localNodePtr.i; - signal->theData[4] = localNodePtr.p->ndynamicId; - sendSignal(lRegApptr.p->blockref, GSN_APPL_CHANGEREP, signal, 5, JBB); - }//if -}//Qmgr::applchangerep() - -/* - 4.10.7 CMAPP_ADD */ -/**-------------------------------------------------------------------------- - * We only map applications of the same version. We have the same application - * and version locally. - * INPUT REG_APPPTR - * TNODENO Sending node - * TVERSION Version of application - * OUTPUT REG_APPPTR, TNODENO ( not changed) - *---------------------------------------------------------------------------*/ -void Qmgr::cmappAdd(Signal* signal, - UintR aRegApp, - Uint16 aNode, - UintR aType, - UintR aVersion) -{ - RegAppPtr lRegApptr; - lRegApptr.i = aRegApp; - ptrCheckGuard(lRegApptr, NO_REG_APP, regApp); - if (lRegApptr.p->version == aVersion) { - jam(); - arrGuard(aNode, MAX_NDB_NODES); - if (lRegApptr.p->m_runNodes.get(aNode) == false){ - jam(); - /* Check if we already have added it. */ - /*-------------------------------------------------------*/ - /* Since we only add remote applications, if we also are */ - /* hosting them we need to send a reply indicating that */ - /* we also are hosting the application. */ - /*-------------------------------------------------------*/ - sendappchg(signal, lRegApptr.i, aNode); - lRegApptr.p->m_runNodes.set(aNode); - /*---------------------------------------*/ - /* Add the remote node to the the local */ - /* nodes memberlist. */ - /* Inform the local application of the */ - /* new application running remotely. */ - /*---------------------------------------*/ - applchangerep(signal, lRegApptr.i, aNode, aType, aVersion); - }//if - }//if -}//Qmgr::cmappAdd() - -/* -4.10.7 CMAPP_START */ -/**-------------------------------------------------------------------------- - * Inform the local application of the change in node state on the remote node - * INPUT REG_APPPTR - * OUTPUT - - *---------------------------------------------------------------------------*/ -void Qmgr::cmappStart(Signal* signal, - UintR aRegApp, - Uint16 aNode, - UintR aType, - UintR aVersion) -{ - RegAppPtr lRegApptr; - lRegApptr.i = aRegApp; - ptrCheckGuard(lRegApptr, NO_REG_APP, regApp); - if (lRegApptr.p->version == aVersion) { - applchangerep(signal, lRegApptr.i, aNode, aType, aVersion); - if (lRegApptr.p->activity == ZSTART) { - jam(); - //---------------------------------------- - /* If the local application is already */ - /* in START face then we do some checks.*/ - //---------------------------------------- - if (lRegApptr.p->noofapps > 0) { - jam(); - //---------------------------------------- - /* Check if we need to decrement the no */ - /* of apps. */ - /* This indicates how many startsignals */ - /* from apps remaining before we can */ - /* send a APPL_STARTCONF. */ - //---------------------------------------- - lRegApptr.p->noofapps--; - }//if - if (lRegApptr.p->noofapps == 0) { - jam(); - //---------------------------------------- - /* All applications have registered as */ - /* ready to start. */ - //---------------------------------------- - /****************************<*/ - /*< APPL_STARTCONF <*/ - /****************************<*/ - sendSignal(lRegApptr.p->blockref, GSN_APPL_STARTCONF, signal, 1, JBB); - }//if - } else { - jam(); - /**-------------------------------------------------------------------- - * Add the ready node to the nodes pending counter. - * This counter is used to see how many remote nodes that are waiting - * for this node to enter the start face. - * It is used when the appl. sends a APPL_STARTREG signal. - *---------------------------------------------------------------------*/ - if (lRegApptr.p->activity == ZADD) { - jam(); - lRegApptr.p->noofpending++; - }//if - }//if - }//if -}//Qmgr::cmappStart() /**--------------------------------------------------------------------------- * A FAILURE HAVE BEEN DISCOVERED ON A NODE. WE NEED TO CLEAR A @@ -3249,17 +2701,6 @@ void Qmgr::failReport(Signal* signal, failedNodePtr.i = aFailedNode; ptrCheckGuard(failedNodePtr, MAX_NDB_NODES, nodeRec); - if (((cpresidentBusy == ZTRUE) || - (cacceptRegreq == ZFALSE)) && - (cstartNode == aFailedNode)) { - jam(); -/*----------------------------------------------------------------------*/ -// A node crashed keeping the president busy and that ensures that there -// is no acceptance of regreq's which is not acceptable after its crash. -/*----------------------------------------------------------------------*/ - cpresidentBusy = ZFALSE; - cacceptRegreq = ZTRUE; - }//if if (failedNodePtr.p->phase == ZRUNNING) { jam(); /* WE ALSO NEED TO ADD HERE SOME CODE THAT GETS OUR NEW NEIGHBOURS. */ @@ -3278,8 +2719,6 @@ void Qmgr::failReport(Signal* signal, }//if }//if failedNodePtr.p->phase = ZPREPARE_FAIL; - failedNodePtr.p->sendCmAddPrepStatus = Q_NOT_ACTIVE; - failedNodePtr.p->sendCmAddCommitStatus = Q_NOT_ACTIVE; failedNodePtr.p->sendPrepFailReqStatus = Q_NOT_ACTIVE; failedNodePtr.p->sendCommitFailReqStatus = Q_NOT_ACTIVE; failedNodePtr.p->sendPresToStatus = Q_NOT_ACTIVE; @@ -3412,74 +2851,6 @@ Uint16 Qmgr::translateDynamicIdToNodeId(Signal* signal, UintR TdynamicId) return TtdiNodeId; }//Qmgr::translateDynamicIdToNodeId() - -/* -4.10.7 GET_DYNAMIC_ID */ -/**-------------------------------------------------------------------------- - * FIND THE CLOSEST HIGHER DYNAMIC ID AMONG THE RUNNING NODES. ADD ONE TO - * THAT VALUE AND WE HAVE CREATED A NEW, UNIQUE AND HIGHER DYNAMIC VALUE THAN - * ANYONE ELSE IN THE CLUSTER.THIS WAY WE DON'T HAVE TO KEEP TRACK OF VARIABLE - * THAT HOLDS THE LAST USED DYNAMIC ID, ESPECIALLY WE DON'T NEED TO INFORM - * ANY VICE PRESIDENTS ABOUT THAT DYNAMIC VARIABLE. - * INPUT - - * RET CDYNAMIC_ID USED AS A TEMPORARY VARIABLE TO PASS THE VALUE TO THE - * CALLER OF THIS SUBROUTINE - *---------------------------------------------------------------------------*/ -UintR Qmgr::getDynamicId(Signal* signal) -{ - NodeRecPtr nodePtr; - UintR TdynamicId = 0; - for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) { - jam(); - ptrAss(nodePtr, nodeRec); - if (nodePtr.p->phase == ZRUNNING) { - if (nodePtr.p->ndynamicId > TdynamicId) { - jam(); - TdynamicId = nodePtr.p->ndynamicId; - }//if - }//if - }//for - TdynamicId++; - return TdynamicId; -}//Qmgr::getDynamicId() - -/* -4.10.7 SENDAPPCHG */ -/*---------------------------------------------------------------------------*/ -/* We only send changes to external nodes. */ -/* INPUT: TNODENO */ -/* REG_APPPTR */ -/*---------------------------------------------------------------------------*/ -void Qmgr::sendappchg(Signal* signal, UintR aRegApp, Uint16 aNode) -{ - NodeRecPtr localNodePtr; - RegAppPtr lRegApptr; - if (aNode != getOwnNodeId()) { - jam(); - localNodePtr.i = aNode; - ptrCheckGuard(localNodePtr, MAX_NDB_NODES, nodeRec); - lRegApptr.i = aRegApp; - ptrCheckGuard(lRegApptr, NO_REG_APP, regApp); - /****************************************/ - /* Signal any application changes to */ - /* the receiving node */ - /****************************************/ - signal->theData[0] = lRegApptr.p->activity; - signal->theData[1] = getOwnNodeId(); - signal->theData[2] = strlen(lRegApptr.p->name)|(lRegApptr.p->name[0] << 8); - signal->theData[3] = lRegApptr.p->name[1] | (lRegApptr.p->name[2] << 8); - signal->theData[4] = lRegApptr.p->name[3] | (lRegApptr.p->name[4] << 8); - signal->theData[5] = lRegApptr.p->name[5] | (lRegApptr.p->name[6] << 8); - signal->theData[6] = lRegApptr.p->name[7] | (lRegApptr.p->name[8] << 8); - signal->theData[7] = lRegApptr.p->name[9] | (lRegApptr.p->name[10] << 8); - signal->theData[8] = lRegApptr.p->name[11] | (lRegApptr.p->name[12] << 8); - signal->theData[9] = lRegApptr.p->name[13] | (lRegApptr.p->name[14] << 8); - signal->theData[10] = 0; - signal->theData[11] = lRegApptr.p->version; - sendSignal(localNodePtr.p->blockRef, GSN_CM_APPCHG, signal, 12, JBA); - }//if -}//Qmgr::sendappchg() - /**-------------------------------------------------------------------------- * WHEN RECEIVING PREPARE FAILURE REQUEST WE WILL IMMEDIATELY CLOSE * COMMUNICATION WITH ALL THOSE NODES. @@ -4450,14 +3821,10 @@ Qmgr::execDUMP_STATE_ORD(Signal* signal) { switch (signal->theData[0]) { case 1: - infoEvent("creadyDistCom = %d, cpresident = %d, cpresidentBusy = %d\n", - creadyDistCom, cpresident, cpresidentBusy); - infoEvent("cacceptRegreq = %d, ccm_infoconfCounter = %d\n", - cacceptRegreq, ccm_infoconfCounter); - infoEvent("cstartNo = %d, cstartNode = %d, cwaitC..phase1 = %d\n", - cstartNo, cstartNode, cwaitContinuebPhase1); - infoEvent("cwaitC..phase2 = %d, cpresidentAlive = %d, cpresidentCand = %d\n" - ,cwaitContinuebPhase2, cpresidentAlive, cpresidentCandidate); + infoEvent("creadyDistCom = %d, cpresident = %d\n", + creadyDistCom, cpresident); + infoEvent("cpresidentAlive = %d, cpresidentCand = %d\n", + cpresidentAlive, cpresidentCandidate); infoEvent("ctoStatus = %d\n", ctoStatus); for(Uint32 i = 1; i<MAX_NDB_NODES; i++){ if(getNodeInfo(i).getType() == NodeInfo::DB){ @@ -4469,18 +3836,15 @@ Qmgr::execDUMP_STATE_ORD(Signal* signal) case ZINIT: sprintf(buf, "Node %d: ZINIT(%d)", i, nodePtr.p->phase); break; - case ZBLOCKED: - sprintf(buf, "Node %d: ZBLOCKED(%d)", i, nodePtr.p->phase); - break; - case ZWAITING: - sprintf(buf, "Node %d: ZWAITING(%d)", i, nodePtr.p->phase); - break; - case ZWAIT_PRESIDENT: - sprintf(buf, "Node %d: ZWAIT_PRESIDENT(%d)", i, nodePtr.p->phase); + case ZSTARTING: + sprintf(buf, "Node %d: ZSTARTING(%d)", i, nodePtr.p->phase); break; case ZRUNNING: sprintf(buf, "Node %d: ZRUNNING(%d)", i, nodePtr.p->phase); break; + case ZPREPARE_FAIL: + sprintf(buf, "Node %d: ZPREPARE_FAIL(%d)", i, nodePtr.p->phase); + break; case ZFAIL_CLOSING: sprintf(buf, "Node %d: ZFAIL_CLOSING(%d)", i, nodePtr.p->phase); break; @@ -4490,9 +3854,6 @@ Qmgr::execDUMP_STATE_ORD(Signal* signal) case ZAPI_ACTIVE: sprintf(buf, "Node %d: ZAPI_ACTIVE(%d)", i, nodePtr.p->phase); break; - case ZPREPARE_FAIL: - sprintf(buf, "Node %d: ZPREPARE_FAIL(%d)", i, nodePtr.p->phase); - break; default: sprintf(buf, "Node %d: <UNKNOWN>(%d)", i, nodePtr.p->phase); break; @@ -4507,6 +3868,7 @@ Qmgr::execDUMP_STATE_ORD(Signal* signal) void Qmgr::execSET_VAR_REQ(Signal* signal) { +#if 0 SetVarReq* const setVarReq = (SetVarReq*)&signal->theData[0]; ConfigParamId var = setVarReq->variable(); UintR val = setVarReq->value(); @@ -4530,4 +3892,5 @@ void Qmgr::execSET_VAR_REQ(Signal* signal) default: sendSignal(CMVMI_REF, GSN_SET_VAR_REF, signal, 1, JBB); }// switch +#endif }//execSET_VAR_REQ() diff --git a/ndb/src/kernel/ndb-main/Main.cpp b/ndb/src/kernel/ndb-main/Main.cpp index 2ac32ada4ec..e8014b63d08 100644 --- a/ndb/src/kernel/ndb-main/Main.cpp +++ b/ndb/src/kernel/ndb-main/Main.cpp @@ -52,10 +52,7 @@ void systemInfo(const Configuration & conf, const char programName[] = "NDB Kernel"; -extern int global_ndb_check; NDB_MAIN(ndb_kernel){ - - global_ndb_check = 1; // Print to stdout/console g_eventLogger.createConsoleHandler(); @@ -130,9 +127,7 @@ NDB_MAIN(ndb_kernel){ } g_eventLogger.info("Angel pid: %d ndb pid: %d", getppid(), getpid()); - - systemInfo(* theConfig, - theConfig->clusterConfigurationData().SizeAltData.logLevel); + systemInfo(* theConfig, * theConfig->m_logLevel); // Load blocks globalEmulatorData.theSimBlockList->load(* theConfig); @@ -147,6 +142,7 @@ NDB_MAIN(ndb_kernel){ char buf[255]; strcpy(buf, homePath); FILE * signalLog = fopen(strncat(buf,"Signal.log", 255), "a"); + globalSignalLoggers.setOwnNodeId(globalData.ownId); globalSignalLoggers.setOutputStream(signalLog); #endif diff --git a/ndb/src/kernel/ndb-main/Makefile_old b/ndb/src/kernel/ndb-main/Makefile_old index 29b7ea7e708..08fc125cb00 100644 --- a/ndb/src/kernel/ndb-main/Makefile_old +++ b/ndb/src/kernel/ndb-main/Makefile_old @@ -11,7 +11,7 @@ BIN_TARGET_ARCHIVES := mgmapi \ error \ trace \ signaldataprint \ - mgmsrvcommon \ + mgmsrvcommon mgmapi \ portlib \ logger \ general diff --git a/ndb/src/kernel/ndb-main/SimBlockList.cpp b/ndb/src/kernel/ndb-main/SimBlockList.cpp index 9e1d28a7fce..bc6262e0723 100644 --- a/ndb/src/kernel/ndb-main/SimBlockList.cpp +++ b/ndb/src/kernel/ndb-main/SimBlockList.cpp @@ -32,6 +32,7 @@ #include <Suma.hpp> #include <Grep.hpp> #include <Dbtux.hpp> +#include <NdbEnv.h> enum SIMBLOCKLIST_DUMMY { A_VALUE = 0 }; @@ -68,10 +69,20 @@ SimBlockList::load(const Configuration & conf){ theList[i] = 0; Dbdict* dbdict = 0; Dbdih* dbdih = 0; - + + SimulatedBlock * fs = 0; + { + char buf[100]; + if(NdbEnv_GetEnv("NDB_NOFS", buf, 100) == 0){ + fs = new (A_VALUE) Ndbfs(conf); + } else { + fs = new (A_VALUE) VoidFs(conf); + } + } + theList[0] = new (A_VALUE) Dbacc(conf); theList[1] = new (A_VALUE) Cmvmi(conf); - theList[2] = new (A_VALUE) Ndbfs(conf); + theList[2] = fs; theList[3] = dbdict = new (A_VALUE) Dbdict(conf); theList[4] = dbdih = new (A_VALUE) Dbdih(conf); theList[5] = new (A_VALUE) Dblqh(conf); diff --git a/ndb/src/kernel/vm/Configuration.cpp b/ndb/src/kernel/vm/Configuration.cpp index 706d75509f2..c97ad951cf3 100644 --- a/ndb/src/kernel/vm/Configuration.cpp +++ b/ndb/src/kernel/vm/Configuration.cpp @@ -27,6 +27,15 @@ #include <getarg.h> +#include <mgmapi_configuration.hpp> +#include <mgmapi_config_parameters_debug.h> +#include <kernel_config_parameters.h> + +#include <kernel_types.h> +#include <ndb_limits.h> +#include "pc.hpp" +#include <LogLevel.hpp> + extern "C" { void ndbSetOwnVersion(); } @@ -122,10 +131,8 @@ Configuration::init(int argc, const char** argv){ return true; } -Configuration::Configuration(): - the_clusterConfigurationData() +Configuration::Configuration() { - m_ownProperties = 0; _programName = 0; _connectString = 0; _fsPath = 0; @@ -134,8 +141,6 @@ Configuration::Configuration(): } Configuration::~Configuration(){ - delete m_ownProperties; - if(_programName != NULL) free(_programName); @@ -143,12 +148,6 @@ Configuration::~Configuration(){ free(_fsPath); } -const -ClusterConfiguration& -Configuration::clusterConfiguration() const { - return the_clusterConfigurationData; -} - void Configuration::setupConfiguration(){ /** @@ -157,7 +156,7 @@ Configuration::setupConfiguration(){ ConfigRetriever cr; cr.setConnectString(_connectString); stopOnError(true); - Properties * p = cr.getConfig("DB", NDB_VERSION); + ndb_mgm_configuration * p = cr.getConfig(NDB_VERSION, NODE_TYPE_DB); if(p == 0){ const char * s = cr.getErrorString(); if(s == 0) @@ -171,56 +170,46 @@ Configuration::setupConfiguration(){ "/invalid configuration", s); } + Uint32 nodeId = globalData.ownId = cr.getOwnNodeId(); + /** * Configure transporters */ { - IPCConfig * theIPC = new IPCConfig(p); - - if(theIPC->init() != 0){ - ERROR_SET(fatal, ERR_INVALID_CONFIG, "Invalid configuration fetched", ""); - } - - if(theIPC->configureTransporters(&globalTransporterRegistry) <= 0){ + int res = IPCConfig::configureTransporters(nodeId, + * p, + globalTransporterRegistry); + if(res <= 0){ ERROR_SET(fatal, ERR_INVALID_CONFIG, "Invalid configuration fetched", "No transporters configured"); } - - globalData.ownId = theIPC->ownId(); - delete theIPC; } /** * Setup cluster configuration data */ - const Properties * db = 0; - if (!p->get("Node", globalData.ownId, &db)) { + ndb_mgm_configuration_iterator iter(* p, CFG_SECTION_NODE); + if (iter.find(CFG_NODE_ID, globalData.ownId)){ ERROR_SET(fatal, ERR_INVALID_CONFIG, "Invalid configuration fetched", "DB missing"); } - const char * type; - if(!(db->get("Type", &type) && strcmp(type, "DB") == 0)){ + + unsigned type; + if(!(iter.get(CFG_TYPE_OF_SECTION, &type) == 0 && type == NODE_TYPE_DB)){ ERROR_SET(fatal, ERR_INVALID_CONFIG, "Invalid configuration fetched", "I'm wrong type of node"); } - /** - * Save properties object to use in getOwnProperties() - */ - m_ownProperties = new Properties(* db); - - the_clusterConfigurationData.init(* p, * db); - - if(!db->get("MaxNoOfSavedMessages", &_maxErrorLogs)){ + if(iter.get(CFG_DB_NO_SAVE_MSGS, &_maxErrorLogs)){ ERROR_SET(fatal, ERR_INVALID_CONFIG, "Invalid configuration fetched", "MaxNoOfSavedMessages missing"); } - if(!db->get("LockPagesInMainMemory", &_lockPagesInMainMemory)){ + if(iter.get(CFG_DB_MEMLOCK, &_lockPagesInMainMemory)){ ERROR_SET(fatal, ERR_INVALID_CONFIG, "Invalid configuration fetched", "LockPagesInMainMemory missing"); } - if(!db->get("TimeBetweenWatchDogCheck", &_timeBetweenWatchDogCheck)){ + if(iter.get(CFG_DB_WATCHDOG_INTERVAL, &_timeBetweenWatchDogCheck)){ ERROR_SET(fatal, ERR_INVALID_CONFIG, "Invalid configuration fetched", "TimeBetweenWatchDogCheck missing"); } @@ -230,16 +219,16 @@ Configuration::setupConfiguration(){ */ { const char* pFileSystemPath = NULL; - if(!db->get("FileSystemPath", &pFileSystemPath)){ + if(iter.get(CFG_DB_FILESYSTEM_PATH, &pFileSystemPath)){ ERROR_SET(fatal, ERR_INVALID_CONFIG, "Invalid configuration fetched", "FileSystemPath missing"); } - + if(pFileSystemPath == 0 || strlen(pFileSystemPath) == 0){ ERROR_SET(fatal, ERR_INVALID_CONFIG, "Invalid configuration fetched", "Configuration does not contain valid filesystem path"); } - + if(pFileSystemPath[strlen(pFileSystemPath) - 1] == '/') _fsPath = strdup(pFileSystemPath); else { @@ -248,19 +237,17 @@ Configuration::setupConfiguration(){ strcat(_fsPath, "/"); } } - - if(!db->get("StopOnError", &_stopOnError)){ + + if(iter.get(CFG_DB_STOP_ON_ERROR, &_stopOnError)){ ERROR_SET(fatal, ERR_INVALID_CONFIG, "Invalid configuration fetched", "StopOnError missing"); } - - if(!db->get("RestartOnErrorInsert", &m_restartOnErrorInsert)){ + + if(iter.get(CFG_DB_STOP_ON_ERROR_INSERT, &m_restartOnErrorInsert)){ ERROR_SET(fatal, ERR_INVALID_CONFIG, "Invalid configuration fetched", "RestartOnErrorInsert missing"); } - delete p; - /** * Create the watch dog thread */ @@ -269,7 +256,14 @@ Configuration::setupConfiguration(){ t = globalEmulatorData.theWatchDog ->setCheckInterval(t); _timeBetweenWatchDogCheck = t; } + + ConfigValues* cf = ConfigValuesFactory::extractCurrentSection(iter.m_config); + + m_clusterConfig = p; + m_clusterConfigIter = ndb_mgm_create_configuration_iterator + (p, CFG_SECTION_NODE); + calcSizeAlt(cf); } bool @@ -282,12 +276,6 @@ Configuration::timeBetweenWatchDogCheck() const { return _timeBetweenWatchDogCheck; } -const -ClusterConfiguration::ClusterData& -Configuration::clusterConfigurationData() const { - return the_clusterConfigurationData.clusterData(); -} - void Configuration::timeBetweenWatchDogCheck(int value) { _timeBetweenWatchDogCheck = value; @@ -313,11 +301,6 @@ Configuration::stopOnError(bool val){ _stopOnError = val; } -const Properties * -Configuration::getOwnProperties() const { - return m_ownProperties; -} - int Configuration::getRestartOnErrorInsert() const { return m_restartOnErrorInsert; @@ -335,6 +318,350 @@ Configuration::getConnectStringCopy() const { return 0; } +const ndb_mgm_configuration_iterator * +Configuration::getOwnConfigIterator() const { + return m_ownConfigIterator; +} + +ndb_mgm_configuration_iterator * +Configuration::getClusterConfigIterator() const { + return m_clusterConfigIter; +} + +void +Configuration::calcSizeAlt(ConfigValues * ownConfig){ + const char * msg = "Invalid configuration fetched"; + char buf[255]; + + unsigned int noOfTables = 0; + unsigned int noOfIndexes = 0; + unsigned int noOfReplicas = 0; + unsigned int noOfDBNodes = 0; + unsigned int noOfAPINodes = 0; + unsigned int noOfMGMNodes = 0; + unsigned int noOfNodes = 0; + unsigned int noOfAttributes = 0; + unsigned int noOfOperations = 0; + unsigned int noOfTransactions = 0; + unsigned int noOfIndexPages = 0; + unsigned int noOfDataPages = 0; + unsigned int noOfScanRecords = 0; + m_logLevel = new LogLevel(); + + /** + * {"NoOfConcurrentCheckpointsDuringRestart", &cd.ispValues[1][5] }, + * {"NoOfConcurrentCheckpointsAfterRestart", &cd.ispValues[2][4] }, + * {"NoOfConcurrentProcessesHandleTakeover", &cd.ispValues[1][7] }, + * {"TimeToWaitAlive", &cd.ispValues[0][0] }, + */ + struct AttribStorage { int paramId; Uint32 * storage; }; + AttribStorage tmp[] = { + { CFG_DB_NO_SCANS, &noOfScanRecords }, + { CFG_DB_NO_TABLES, &noOfTables }, + { CFG_DB_NO_INDEXES, &noOfIndexes }, + { CFG_DB_NO_REPLICAS, &noOfReplicas }, + { CFG_DB_NO_ATTRIBUTES, &noOfAttributes }, + { CFG_DB_NO_OPS, &noOfOperations }, + { CFG_DB_NO_TRANSACTIONS, &noOfTransactions } +#if 0 + { "NoOfDiskPagesToDiskDuringRestartTUP", &cd.ispValues[3][8] }, + { "NoOfDiskPagesToDiskAfterRestartTUP", &cd.ispValues[3][9] }, + { "NoOfDiskPagesToDiskDuringRestartACC", &cd.ispValues[3][10] }, + { "NoOfDiskPagesToDiskAfterRestartACC", &cd.ispValues[3][11] }, +#endif + }; + + ndb_mgm_configuration_iterator db(*(ndb_mgm_configuration*)ownConfig, 0); + + const int sz = sizeof(tmp)/sizeof(AttribStorage); + for(int i = 0; i<sz; i++){ + if(ndb_mgm_get_int_parameter(&db, tmp[i].paramId, tmp[i].storage)){ + snprintf(buf, sizeof(buf), "ConfigParam: %d not found", tmp[i].paramId); + ERROR_SET(fatal, ERR_INVALID_CONFIG, msg, buf); + } + } + + Uint64 indexMem = 0, dataMem = 0; + ndb_mgm_get_int64_parameter(&db, CFG_DB_DATA_MEM, &dataMem); + ndb_mgm_get_int64_parameter(&db, CFG_DB_INDEX_MEM, &indexMem); + if(dataMem == 0){ + snprintf(buf, sizeof(buf), "ConfigParam: %d not found", CFG_DB_DATA_MEM); + ERROR_SET(fatal, ERR_INVALID_CONFIG, msg, buf); + } + + if(indexMem == 0){ + snprintf(buf, sizeof(buf), "ConfigParam: %d not found", CFG_DB_INDEX_MEM); + ERROR_SET(fatal, ERR_INVALID_CONFIG, msg, buf); + } + + noOfDataPages = (dataMem / 8192); + noOfIndexPages = (indexMem / 8192); + + for(unsigned j = 0; j<LogLevel::LOGLEVEL_CATEGORIES; j++){ + Uint32 tmp; + if(!ndb_mgm_get_int_parameter(&db, LogLevel::MIN_LOGLEVEL_ID+j, &tmp)){ + m_logLevel->setLogLevel((LogLevel::EventCategory)j, tmp); + } + } + + // tmp + ndb_mgm_configuration_iterator * p = m_clusterConfigIter; + + Uint32 nodeNo = noOfNodes = 0; + NodeBitmask nodes; + for(ndb_mgm_first(p); ndb_mgm_valid(p); ndb_mgm_next(p), nodeNo++){ + + Uint32 nodeId; + Uint32 nodeType; + + if(ndb_mgm_get_int_parameter(p, CFG_NODE_ID, &nodeId)){ + ERROR_SET(fatal, ERR_INVALID_CONFIG, msg, "Node data (Id) missing"); + } + + if(ndb_mgm_get_int_parameter(p, CFG_TYPE_OF_SECTION, &nodeType)){ + ERROR_SET(fatal, ERR_INVALID_CONFIG, msg, "Node data (Type) missing"); + } + + if(nodeId > MAX_NODES || nodeId == 0){ + snprintf(buf, sizeof(buf), + "Invalid node id: %d", nodeId); + ERROR_SET(fatal, ERR_INVALID_CONFIG, msg, buf); + } + + if(nodes.get(nodeId)){ + snprintf(buf, sizeof(buf), "Two node can not have the same node id: %d", + nodeId); + ERROR_SET(fatal, ERR_INVALID_CONFIG, msg, buf); + } + nodes.set(nodeId); + + switch(nodeType){ + case NODE_TYPE_DB: + noOfDBNodes++; // No of NDB processes + + if(nodeId > MAX_NDB_NODES){ + snprintf(buf, sizeof(buf), "Maximum node id for a ndb node is: %d", + MAX_NDB_NODES); + ERROR_SET(fatal, ERR_INVALID_CONFIG, msg, buf); + } + break; + case NODE_TYPE_API: + noOfAPINodes++; // No of API processes + break; + case NODE_TYPE_REP: + break; + case NODE_TYPE_MGM: + noOfMGMNodes++; // No of MGM processes + break; + case NODE_TYPE_EXT_REP: + break; + default: + snprintf(buf, sizeof(buf), "Unknown node type: %d", nodeType); + ERROR_SET(fatal, ERR_INVALID_CONFIG, msg, buf); + } + } + noOfNodes = nodeNo; + + /** + * Do size calculations + */ + ConfigValuesFactory cfg(ownConfig); + + noOfTables++; // Remove impact of system table + noOfTables += noOfIndexes; // Indexes are tables too + noOfAttributes += 2; // ---"---- + noOfTables *= 2; // Remove impact of Dict need 2 ids for each table + + if (noOfDBNodes > 15) { + noOfDBNodes = 15; + }//if + Uint32 noOfLocalScanRecords = (noOfDBNodes * noOfScanRecords) + 1; + Uint32 noOfTCScanRecords = noOfScanRecords; + + { + /** + * Acc Size Alt values + */ + // Can keep 65536 pages (= 0.5 GByte) + cfg.put(CFG_ACC_DIR_RANGE, + 4 * NO_OF_FRAG_PER_NODE * noOfTables* noOfReplicas); + + cfg.put(CFG_ACC_DIR_ARRAY, + (noOfIndexPages >> 8) + + 4 * NO_OF_FRAG_PER_NODE * noOfTables* noOfReplicas); + + cfg.put(CFG_ACC_FRAGMENT, + 2 * NO_OF_FRAG_PER_NODE * noOfTables* noOfReplicas); + + /*-----------------------------------------------------------------------*/ + // The extra operation records added are used by the scan and node + // recovery process. + // Node recovery process will have its operations dedicated to ensure + // that they never have a problem with allocation of the operation record. + // The remainder are allowed for use by the scan processes. + /*-----------------------------------------------------------------------*/ + cfg.put(CFG_ACC_OP_RECS, + noOfReplicas*((16 * noOfOperations) / 10 + 50) + + (noOfLocalScanRecords * MAX_PARALLEL_SCANS_PER_FRAG) + + NODE_RECOVERY_SCAN_OP_RECORDS); + + cfg.put(CFG_ACC_OVERFLOW_RECS, + noOfIndexPages + + 2 * NO_OF_FRAG_PER_NODE * noOfTables* noOfReplicas); + + cfg.put(CFG_ACC_PAGE8, + noOfIndexPages + 32); + + cfg.put(CFG_ACC_ROOT_FRAG, + NO_OF_FRAG_PER_NODE * noOfTables* noOfReplicas); + + cfg.put(CFG_ACC_TABLE, noOfTables); + + cfg.put(CFG_ACC_SCAN, noOfLocalScanRecords); + } + + { + /** + * Dict Size Alt values + */ + cfg.put(CFG_DICT_ATTRIBUTE, + noOfAttributes); + + cfg.put(CFG_DICT_CONNECT, + noOfOperations + 32); + + cfg.put(CFG_DICT_FRAG_CONNECT, + NO_OF_FRAG_PER_NODE * noOfDBNodes * noOfReplicas); + + cfg.put(CFG_DICT_TABLE, + noOfTables); + + cfg.put(CFG_DICT_TC_CONNECT, + 2* noOfOperations); + } + + { + /** + * Dih Size Alt values + */ + cfg.put(CFG_DIH_API_CONNECT, + 2 * noOfTransactions); + + cfg.put(CFG_DIH_CONNECT, + noOfOperations + 46); + + cfg.put(CFG_DIH_FRAG_CONNECT, + NO_OF_FRAG_PER_NODE * noOfTables * noOfDBNodes); + + int temp; + temp = noOfReplicas - 2; + if (temp < 0) + temp = 1; + else + temp++; + cfg.put(CFG_DIH_MORE_NODES, + temp * NO_OF_FRAG_PER_NODE * + noOfTables * noOfDBNodes); + + cfg.put(CFG_DIH_REPLICAS, + NO_OF_FRAG_PER_NODE * noOfTables * + noOfDBNodes * noOfReplicas); + + cfg.put(CFG_DIH_TABLE, + noOfTables); + } + + { + /** + * Lqh Size Alt values + */ + cfg.put(CFG_LQH_FRAG, + NO_OF_FRAG_PER_NODE * noOfTables * noOfReplicas); + + cfg.put(CFG_LQH_CONNECT, + noOfReplicas*((11 * noOfOperations) / 10 + 50)); + + cfg.put(CFG_LQH_TABLE, + noOfTables); + + cfg.put(CFG_LQH_TC_CONNECT, + noOfReplicas*((16 * noOfOperations) / 10 + 50)); + + cfg.put(CFG_LQH_REPLICAS, + noOfReplicas); + + cfg.put(CFG_LQH_SCAN, + noOfLocalScanRecords); + } + + { + /** + * Tc Size Alt values + */ + cfg.put(CFG_TC_API_CONNECT, + 3 * noOfTransactions); + + cfg.put(CFG_TC_TC_CONNECT, + noOfOperations + 16 + noOfTransactions); + + cfg.put(CFG_TC_TABLE, + noOfTables); + + cfg.put(CFG_TC_LOCAL_SCAN, + noOfLocalScanRecords); + + cfg.put(CFG_TC_SCAN, + noOfTCScanRecords); + } + + { + /** + * Tup Size Alt values + */ + cfg.put(CFG_TUP_FRAG, + 2 * NO_OF_FRAG_PER_NODE * noOfTables* noOfReplicas); + + cfg.put(CFG_TUP_OP_RECS, + noOfReplicas*((16 * noOfOperations) / 10 + 50)); + + cfg.put(CFG_TUP_PAGE, + noOfDataPages); + + cfg.put(CFG_TUP_PAGE_RANGE, + 4 * NO_OF_FRAG_PER_NODE * noOfTables* noOfReplicas); + + cfg.put(CFG_TUP_TABLE, + noOfTables); + + cfg.put(CFG_TUP_TABLE_DESC, + 4 * NO_OF_FRAG_PER_NODE * noOfAttributes* noOfReplicas + + 12 * NO_OF_FRAG_PER_NODE * noOfTables* noOfReplicas ); + + cfg.put(CFG_TUP_STORED_PROC, + noOfLocalScanRecords); + } + + { + /** + * Tux Size Alt values + */ + cfg.put(CFG_TUX_INDEX, + noOfTables); + + cfg.put(CFG_TUX_FRAGMENT, + 2 * NO_OF_FRAG_PER_NODE * noOfTables * noOfReplicas); + + cfg.put(CFG_TUX_ATTRIBUTE, + noOfIndexes * 4); + + cfg.put(CFG_TUX_SCAN_OP, noOfLocalScanRecords); + } + + m_ownConfig = (ndb_mgm_configuration*)cfg.getConfigValues(); + m_ownConfigIterator = ndb_mgm_create_configuration_iterator + (m_ownConfig, 0); +} + void Configuration::setInitialStart(bool val){ _initialStart = val; diff --git a/ndb/src/kernel/vm/Configuration.hpp b/ndb/src/kernel/vm/Configuration.hpp index 3f96bb454c5..1706ad05867 100644 --- a/ndb/src/kernel/vm/Configuration.hpp +++ b/ndb/src/kernel/vm/Configuration.hpp @@ -17,7 +17,8 @@ #ifndef Configuration_H #define Configuration_H -#include "ClusterConfiguration.hpp" +#include <mgmapi.h> +#include <ndb_types.h> class Configuration { public: @@ -46,35 +47,36 @@ public: void setRestartOnErrorInsert(int); // Cluster configuration - const ClusterConfiguration::ClusterData& clusterConfigurationData() const; - const ClusterConfiguration& clusterConfiguration() const; - const char * programName() const; const char * fileSystemPath() const; char * getConnectStringCopy() const; /** - * Return Properties for own node - */ - const Properties * getOwnProperties() const; - - /** * */ bool getInitialStart() const; void setInitialStart(bool val); bool getDaemonMode() const; - + + const ndb_mgm_configuration_iterator * getOwnConfigIterator() const; + + class LogLevel * m_logLevel; private: + friend class Cmvmi; + friend class Qmgr; + ndb_mgm_configuration_iterator * getClusterConfigIterator() const; + Uint32 _stopOnError; Uint32 m_restartOnErrorInsert; Uint32 _maxErrorLogs; Uint32 _lockPagesInMainMemory; Uint32 _timeBetweenWatchDogCheck; + ndb_mgm_configuration * m_ownConfig; + ndb_mgm_configuration * m_clusterConfig; - ClusterConfiguration the_clusterConfigurationData; - const Properties * m_ownProperties; + ndb_mgm_configuration_iterator * m_clusterConfigIter; + ndb_mgm_configuration_iterator * m_ownConfigIterator; /** * arguments to NDB process @@ -84,6 +86,8 @@ private: bool _initialStart; char * _connectString; bool _daemonMode; + + void calcSizeAlt(class ConfigValues * ); }; inline diff --git a/ndb/src/kernel/vm/FastScheduler.cpp b/ndb/src/kernel/vm/FastScheduler.cpp index e9ca4834562..eca456d26dd 100644 --- a/ndb/src/kernel/vm/FastScheduler.cpp +++ b/ndb/src/kernel/vm/FastScheduler.cpp @@ -316,14 +316,14 @@ APZJobBuffer::signal2buffer(Signal* signal, void APZJobBuffer::insert(const SignalHeader * const sh, const Uint32 * const theData, const Uint32 secPtrI[3]){ - Uint32 tOccupancy = theOccupancy; + Uint32 tOccupancy = theOccupancy + 1; Uint32 myWPtr = wPtr; register BufferEntry& buf = buffer[myWPtr]; if (tOccupancy < bufSize) { Uint32 cond = (++myWPtr == bufSize) - 1; wPtr = myWPtr & cond; - theOccupancy = tOccupancy + 1; + theOccupancy = tOccupancy; buf.header = * sh; const Uint32 len = buf.header.theLength; @@ -342,8 +342,9 @@ APZJobBuffer::insert(const SignalHeader * const sh, }//if } APZJobBuffer::APZJobBuffer() - : rPtr(0), wPtr(0), theOccupancy(0), bufSize(0), buffer(NULL), memRef(NULL) + : bufSize(0), buffer(NULL), memRef(NULL) { + clear(); } APZJobBuffer::~APZJobBuffer() @@ -354,9 +355,11 @@ APZJobBuffer::~APZJobBuffer() void APZJobBuffer::newBuffer(int size) { - buffer = new BufferEntry[size]; + buffer = new BufferEntry[size + 1]; // +1 to support "overrrun" if(buffer){ +#ifndef NDB_PURIFY ::memset(buffer, 0, (size * sizeof(BufferEntry))); +#endif bufSize = size; } else bufSize = 0; @@ -474,10 +477,11 @@ FastScheduler::reportDoJobStatistics(Uint32 tMeanLoopCount) { signal.theData[0] = EventReport::JobStatistic; signal.theData[1] = tMeanLoopCount; + memset(&signal.header, 0, sizeof(SignalHeader)); signal.header.theLength = 2; signal.header.theSendersSignalId = 0; signal.header.theSendersBlockRef = numberToRef(0, 0); - + execute(&signal, JBA, CMVMI, GSN_EVENT_REP); } diff --git a/ndb/src/kernel/vm/FastScheduler.hpp b/ndb/src/kernel/vm/FastScheduler.hpp index 586a7ea27ad..9749dab5d85 100644 --- a/ndb/src/kernel/vm/FastScheduler.hpp +++ b/ndb/src/kernel/vm/FastScheduler.hpp @@ -43,7 +43,7 @@ class BufferEntry { public: SignalHeader header; - Uint32 theDataRegister[28]; + Uint32 theDataRegister[25]; }; class APZJobBuffer @@ -68,7 +68,6 @@ public: void retrieveDump(Signal *signal, Uint32 myRptr); void clear(); - bool isEmpty() const; Uint32 getOccupancy() const; Uint32 getReadPtr() const; @@ -313,13 +312,13 @@ void APZJobBuffer::insert(Signal* signal, BlockNumber bnr, GlobalSignalNumber gsn) { - Uint32 tOccupancy = theOccupancy; + Uint32 tOccupancy = theOccupancy + 1; Uint32 myWPtr = wPtr; if (tOccupancy < bufSize) { register BufferEntry& buf = buffer[myWPtr]; Uint32 cond = (++myWPtr == bufSize) - 1; wPtr = myWPtr & cond; - theOccupancy = tOccupancy + 1; + theOccupancy = tOccupancy; signal2buffer(signal, bnr, gsn, buf); //--------------------------------------------------------- // Prefetch of buffer[wPtr] is done here. We prefetch for @@ -343,11 +342,4 @@ APZJobBuffer::insert(Signal* signal, BlockNumber bnr, signal2buffer(signal, bnr, gsn, buf); } -inline -bool -APZJobBuffer::isEmpty() const -{ - return (theOccupancy == 0); -} - #endif diff --git a/ndb/src/kernel/vm/Makefile_old b/ndb/src/kernel/vm/Makefile_old index 3f448b77b17..a162f3672ce 100644 --- a/ndb/src/kernel/vm/Makefile_old +++ b/ndb/src/kernel/vm/Makefile_old @@ -13,17 +13,18 @@ SOURCES = \ TransporterCallback.cpp \ Emulator.cpp \ Configuration.cpp \ - ClusterConfiguration.cpp \ WatchDog.cpp \ SimplePropertiesSection.cpp \ SectionReader.cpp \ MetaData.cpp \ Mutex.cpp SafeCounter.cpp +CFLAGS_Configuration.cpp := -I$(call fixpath,$(NDB_TOP)/src/mgmapi) + DIRS := testCopy testDataBuffer testSimplePropertiesSection + ifneq ($(USE_EDITLINE), N) DIRS += testLongSig endif - include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/kernel/vm/SignalCounter.hpp b/ndb/src/kernel/vm/SignalCounter.hpp index d572551ea92..ea770324aa6 100644 --- a/ndb/src/kernel/vm/SignalCounter.hpp +++ b/ndb/src/kernel/vm/SignalCounter.hpp @@ -21,6 +21,8 @@ #include <ErrorReporter.hpp> class SignalCounter { + friend struct NodeReceiverGroup; + private: Uint32 m_count; NdbNodeBitmask m_nodes; diff --git a/ndb/src/kernel/vm/SimulatedBlock.cpp b/ndb/src/kernel/vm/SimulatedBlock.cpp index e3f087d7d74..a6a8a6242cd 100644 --- a/ndb/src/kernel/vm/SimulatedBlock.cpp +++ b/ndb/src/kernel/vm/SimulatedBlock.cpp @@ -60,7 +60,8 @@ SimulatedBlock::SimulatedBlock(BlockNumber blockNumber, c_fragmentIdCounter = 1; c_fragSenderRunning = false; - const Properties * p = conf.getOwnProperties(); + Properties tmp; + const Properties * p = &tmp; ndbrequire(p != 0); Uint32 count = 10; @@ -98,7 +99,9 @@ SimulatedBlock::SimulatedBlock(BlockNumber blockNumber, for(GlobalSignalNumber i = 0; i<=MAX_GSN; i++) theExecArray[i] = 0; + installSimulatedBlockFunctions(); + UpgradeStartup::installEXEC(this); CLEAR_ERROR_INSERT_VALUE; } @@ -127,6 +130,7 @@ SimulatedBlock::installSimulatedBlockFunctions(){ a[GSN_UTIL_LOCK_CONF] = &SimulatedBlock::execUTIL_LOCK_CONF; a[GSN_UTIL_UNLOCK_REF] = &SimulatedBlock::execUTIL_UNLOCK_REF; a[GSN_UTIL_UNLOCK_CONF] = &SimulatedBlock::execUTIL_UNLOCK_CONF; + a[GSN_READ_CONFIG_REQ] = &SimulatedBlock::execREAD_CONFIG_REQ; } void @@ -182,7 +186,7 @@ SimulatedBlock::sendSignal(BlockReference ref, Uint32 tSignalId = signal->header.theSignalId; - if ((length == 0) || (length > 25) || (recBlock == 0)) { + if ((length == 0) || (length + noOfSections > 25) || (recBlock == 0)) { signal_error(gsn, length, recBlock, __FILE__, __LINE__); return; }//if @@ -263,7 +267,7 @@ SimulatedBlock::sendSignal(NodeReceiverGroup rg, signal->header.theSendersSignalId = tSignalId; signal->header.theSendersBlockRef = reference(); - if ((length == 0) || (length > 25) || (recBlock == 0)) { + if ((length == 0) || (length + noOfSections > 25) || (recBlock == 0)) { signal_error(gsn, length, recBlock, __FILE__, __LINE__); return; }//if @@ -371,7 +375,7 @@ SimulatedBlock::sendSignal(BlockReference ref, Uint32 tSignalId = signal->header.theSignalId; Uint32 tFragInfo = signal->header.m_fragmentInfo; - if ((length == 0) || (length > 25) || (recBlock == 0)) { + if ((length == 0) || (length + noOfSections > 25) || (recBlock == 0)) { signal_error(gsn, length, recBlock, __FILE__, __LINE__); return; }//if @@ -464,7 +468,7 @@ SimulatedBlock::sendSignal(NodeReceiverGroup rg, signal->header.theSendersBlockRef = reference(); signal->header.m_noOfSections = noOfSections; - if ((length == 0) || (length > 25) || (recBlock == 0)) { + if ((length == 0) || (length + noOfSections > 25) || (recBlock == 0)) { signal_error(gsn, length, recBlock, __FILE__, __LINE__); return; }//if @@ -1338,7 +1342,7 @@ SimulatedBlock::sendFirstFragment(FragmentSendInfo & info, */ return true; } - + /** * Setup info object */ @@ -1724,9 +1728,52 @@ void SimulatedBlock::execUTIL_UNLOCK_CONF(Signal* signal){ c_mutexMgr.execUTIL_UNLOCK_CONF(signal); } +void +SimulatedBlock::execREAD_CONFIG_REQ(Signal* signal){ + const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr(); + + Uint32 ref = req->senderRef; + Uint32 senderData = req->senderData; + + ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend(); + conf->senderRef = reference(); + conf->senderData = senderData; + sendSignal(ref, GSN_READ_CONFIG_CONF, signal, + ReadConfigConf::SignalLength, JBB); +} + void SimulatedBlock::ignoreMutexUnlockCallback(Signal* signal, Uint32 ptrI, Uint32 retVal){ c_mutexMgr.release(ptrI); } +void +UpgradeStartup::installEXEC(SimulatedBlock* block){ + SimulatedBlock::ExecFunction * a = block->theExecArray; + switch(block->number()){ + case QMGR: + a[UpgradeStartup::GSN_CM_APPCHG] = &SimulatedBlock::execUPGRADE; + break; + case CNTR: + a[UpgradeStartup::GSN_CNTR_MASTERREF] = &SimulatedBlock::execUPGRADE; + a[UpgradeStartup::GSN_CNTR_MASTERCONF] = &SimulatedBlock::execUPGRADE; + break; + } +} + +void +SimulatedBlock::execUPGRADE(Signal* signal){ + Uint32 gsn = signal->header.theVerId_signalNumber; + switch(gsn){ + case UpgradeStartup::GSN_CM_APPCHG: + UpgradeStartup::execCM_APPCHG(* this, signal); + break; + case UpgradeStartup::GSN_CNTR_MASTERREF: + UpgradeStartup::execCNTR_MASTER_REPLY(* this, signal); + break; + case UpgradeStartup::GSN_CNTR_MASTERCONF: + UpgradeStartup::execCNTR_MASTER_REPLY(* this, signal); + break; + } +} diff --git a/ndb/src/kernel/vm/SimulatedBlock.hpp b/ndb/src/kernel/vm/SimulatedBlock.hpp index 42b8a3034f5..491d432625e 100644 --- a/ndb/src/kernel/vm/SimulatedBlock.hpp +++ b/ndb/src/kernel/vm/SimulatedBlock.hpp @@ -45,6 +45,16 @@ #include "SafeCounter.hpp" #include "MetaData.hpp" +#include <mgmapi.h> +#include <mgmapi_config_parameters.h> +#include <mgmapi_config_parameters_debug.h> +#include <kernel_config_parameters.h> +#include <Configuration.hpp> + +#include <signaldata/ReadConfig.hpp> +#include <signaldata/UpgradeStartup.hpp> + + /** * Something for filesystem access */ @@ -70,6 +80,7 @@ class SimulatedBlock { friend class MutexManager; friend class SafeCounter; friend class SafeCounterManager; + friend struct UpgradeStartup; public: friend class BlockComponent; virtual ~SimulatedBlock(); @@ -378,7 +389,7 @@ private: void execSIGNAL_DROPPED_REP(Signal* signal); void execCONTINUE_FRAGMENTED(Signal* signal); - + Uint32 c_fragmentIdCounter; ArrayPool<FragmentInfo> c_fragmentInfoPool; DLHashTable<FragmentInfo> c_fragmentInfoHash; @@ -404,7 +415,9 @@ private: void execUTIL_UNLOCK_REF(Signal* signal); void execUTIL_UNLOCK_CONF(Signal* signal); + void execREAD_CONFIG_REQ(Signal* signal); protected: + void execUPGRADE(Signal* signal); // Variable for storing inserted errors, see pc.H ERROR_INSERT_VARIABLE; diff --git a/ndb/src/kernel/vm/TransporterCallback.cpp b/ndb/src/kernel/vm/TransporterCallback.cpp index 3798e4040c8..eb7d138895c 100644 --- a/ndb/src/kernel/vm/TransporterCallback.cpp +++ b/ndb/src/kernel/vm/TransporterCallback.cpp @@ -206,6 +206,7 @@ execute(void * callbackObj, LinearSectionPtr ptr[3]){ const Uint32 secCount = header->m_noOfSections; + const Uint32 length = header->theLength; #ifdef TRACE_DISTRIBUTED ndbout_c("recv: %s(%d) from (%s, %d)", @@ -225,6 +226,11 @@ execute(void * callbackObj, case 1: ok &= import(secPtr[0], ptr[0].p, ptr[0].sz); } + + /** + * Check that we haven't received a too long signal + */ + ok &= (length + secCount <= 25); Uint32 secPtrI[3]; if(ok){ @@ -234,6 +240,7 @@ execute(void * callbackObj, secPtrI[0] = secPtr[0].i; secPtrI[1] = secPtr[1].i; secPtrI[2] = secPtr[2].i; + globalScheduler.execute(header, prio, theData, secPtrI); return; } diff --git a/ndb/src/kernel/vm/VMSignal.hpp b/ndb/src/kernel/vm/VMSignal.hpp index 45e731f2079..9111ee7949c 100644 --- a/ndb/src/kernel/vm/VMSignal.hpp +++ b/ndb/src/kernel/vm/VMSignal.hpp @@ -34,6 +34,7 @@ struct NodeReceiverGroup { NodeReceiverGroup(); NodeReceiverGroup(Uint32 blockRef); NodeReceiverGroup(Uint32 blockNo, const NodeBitmask &); + NodeReceiverGroup(Uint32 blockNo, const class SignalCounter &); NodeReceiverGroup& operator=(BlockReference ref); @@ -171,6 +172,14 @@ NodeReceiverGroup::NodeReceiverGroup(Uint32 blockNo, const NodeBitmask & nodes){ m_nodes = nodes; } +#include "SignalCounter.hpp" + +inline +NodeReceiverGroup::NodeReceiverGroup(Uint32 blockNo, const SignalCounter & nodes){ + m_block = blockNo; + m_nodes = nodes.m_nodes; +} + inline NodeReceiverGroup& NodeReceiverGroup::operator=(BlockReference blockRef){ diff --git a/ndb/src/kernel/vm/pc.hpp b/ndb/src/kernel/vm/pc.hpp index 873a986bc35..849799a47f3 100644 --- a/ndb/src/kernel/vm/pc.hpp +++ b/ndb/src/kernel/vm/pc.hpp @@ -116,12 +116,6 @@ #define arrGuard(ind, size) #endif -// ------- EVENT STATES OF A NODE ----------------------------- -#define ZADD 0 /* New application added */ -#define ZREMOVE 1 /* An application has been removed */ -#define ZSTART 2 /* An application is ready to start */ -#define ZRUN 3 /* An application has started to run */ - // -------- ERROR INSERT MACROS ------- #ifdef ERROR_INSERT #define ERROR_INSERT_VARIABLE UintR cerrorInsert diff --git a/ndb/src/kernel/vm/testLongSig/testLongSig.cpp b/ndb/src/kernel/vm/testLongSig/testLongSig.cpp index af4e2ca6e24..1d1fb8ebc82 100644 --- a/ndb/src/kernel/vm/testLongSig/testLongSig.cpp +++ b/ndb/src/kernel/vm/testLongSig/testLongSig.cpp @@ -39,6 +39,7 @@ print_help(){ ndbout << "11 - Sending of CONTINUEB fragmented signals w/ linear sections" << endl; ndbout << "12 - As but using receiver group" << endl; + ndbout << "13 - Send 100 * 1000 25 len signals wo/ sections" << endl; ndbout << "r - Recive signal from anyone" << endl; ndbout << "a - Run tests 1 - 12 with variable sizes - 10 loops" << endl; ndbout << "b - Run tests 1 - 12 with variable sizes - 100 loops" << endl; @@ -103,7 +104,7 @@ main(void){ data[5] = 70; data[6] = 123; data[7] = 10; - const Uint32 theDataLen = 8; + const Uint32 theDataLen = 18; for(Uint32 i = 0; i<70; i++) sec0[i] = i; @@ -198,6 +199,38 @@ main(void){ delete ret1; count--; } + } else if (data[1] == 13) { + const Uint32 count = 3500; + const Uint32 loop = 1000; + + signal1.set(ss, 0, CMVMI, GSN_TESTSIG, 25); + signal1.header.m_fragmentInfo = 0; + signal1.header.m_noOfSections = 0; + signal1.theData[1] = 14; + signal1.theData[3] = 0; // Print + signal1.theData[8] = count; + signal1.theData[9] = loop; + Uint32 nodeId = ss.getAliveNode(); + ndbout_c("Sending 25 len signal to node %d", nodeId); + ss.sendSignal(nodeId, &signal1); + + Uint32 total; + { + SimpleSignal * ret1 = ss.waitFor((Uint16)nodeId); + ndbout_c("received from node %d", + refToNode(ret1->header.theSendersBlockRef)); + total = ret1->theData[10] - 1; + delete ret1; + } + + do { + ndbout << "Waiting for " << total << " signals... " << flush; + SimpleSignal * ret1 = ss.waitFor((Uint16)nodeId); + ndbout_c("received from node %d", + refToNode(ret1->header.theSendersBlockRef)); + delete ret1; + total --; + } while(total > 0); } else { print_help(); } @@ -218,7 +251,6 @@ runTest(SignalSender & ss, Uint32 count, bool verbose){ sec2[i] = i * i; } - sig.set(ss, 0, CMVMI, GSN_TESTSIG, 8); sig.theData[0] = ss.getOwnRef(); sig.theData[1] = 1; // TestType sig.theData[2] = 128; // FragSize @@ -236,6 +268,8 @@ runTest(SignalSender & ss, Uint32 count, bool verbose){ sig.ptr[1].sz = randRange(1, 256); sig.ptr[2].sz = randRange(1, 256); sig.header.m_noOfSections = secs; + const Uint32 len = 5 + (secs > 0 ? 1 : 0) * (25 - 5 - 7); + sig.set(ss, 0, CMVMI, GSN_TESTSIG, len); ndbout << "Loop " << loop << " #secs = " << secs << " sizes = [ "; unsigned min = 256; unsigned max = 0; @@ -248,7 +282,7 @@ runTest(SignalSender & ss, Uint32 count, bool verbose){ sum += sz; sig.theData[5+i] = sz; } - ndbout_c("]"); + ndbout_c("] len = %d", len); for(int test = 1; test <= 12; test++){ sig.theData[1] = test; Uint32 nodeId = ss.getAliveNode(); diff --git a/ndb/src/mgmapi/Makefile_old b/ndb/src/mgmapi/Makefile_old index 9e7ba4f5ac7..fa734f998e6 100644 --- a/ndb/src/mgmapi/Makefile_old +++ b/ndb/src/mgmapi/Makefile_old @@ -15,7 +15,7 @@ LIB_TARGET := MGM_API LIB_TARGET_ARCHIVES := $(ARCHIVE_TARGET) general portlib # Source files of non-templated classes (.C files) -SOURCES = mgmapi.cpp +SOURCES = mgmapi.cpp mgmapi_configuration.cpp CCFLAGS_LOC += -I$(call fixpath,$(NDB_TOP)/include/mgmapi) \ -I$(call fixpath,$(NDB_TOP)/src/common/mgmcommon) diff --git a/ndb/src/mgmapi/mgmapi.cpp b/ndb/src/mgmapi/mgmapi.cpp index fcdfe943fb1..72ba282ad13 100644 --- a/ndb/src/mgmapi/mgmapi.cpp +++ b/ndb/src/mgmapi/mgmapi.cpp @@ -19,6 +19,7 @@ #include <NdbTCP.h> #include "mgmapi.h" #include "mgmapi_debug.h" +#include "mgmapi_configuration.hpp" #include <socket_io.h> #include <NdbOut.hpp> @@ -26,6 +27,7 @@ #include <Parser.hpp> #include <OutputStream.hpp> #include <InputStream.hpp> +#include <Base64.hpp> #define MGM_CMD(name, fun, desc) \ @@ -93,15 +95,20 @@ struct ndb_mgm_handle { #endif }; -#define SET_ERROR(h, e, s) \ - { \ - char tmp[NDB_MGM_MAX_ERR_DESC_SIZE]; \ - snprintf(tmp, NDB_MGM_MAX_ERR_DESC_SIZE, " (mgmapi.cpp:%d)", __LINE__); \ - strncpy(h->last_error_desc, s, NDB_MGM_MAX_ERR_DESC_SIZE); \ - strncat(h->last_error_desc, tmp, NDB_MGM_MAX_ERR_DESC_SIZE); \ - h->last_error = e; \ - h->last_error_line = __LINE__; \ - } +#define SET_ERROR(h, e, s) setError(h, e, __LINE__, s) + +static +void +setError(NdbMgmHandle h, int error, int error_line, const char * msg, ...){ + + h->last_error = error; \ + h->last_error_line = error_line; + + va_list ap; + va_start(ap, msg); + vsnprintf(h->last_error_desc, sizeof(h->last_error_desc), msg, ap); + va_end(ap); +} #define CHECK_HANDLE(handle, ret) \ if(handle == 0) { \ @@ -185,9 +192,12 @@ ndb_mgm_get_latest_error(const NdbMgmHandle h) return h->last_error; } -/** - * Get latest error line associated with a handle - */ +extern "C" +const char * +ndb_mgm_get_latest_error_desc(const NdbMgmHandle h){ + return h->last_error_desc; +} + extern "C" int ndb_mgm_get_latest_error_line(const NdbMgmHandle h) @@ -207,13 +217,6 @@ ndb_mgm_get_latest_error_msg(const NdbMgmHandle h) return "Error"; // Unknown Error message } -extern "C" -const char * -ndb_mgm_get_latest_error_desc(const NdbMgmHandle h) -{ - return h->last_error_desc; -} - static int parse_connect_string(const char * connect_string, @@ -372,7 +375,8 @@ ndb_mgm_connect(NdbMgmHandle handle, const char * mgmsrv) // Convert ip address presentation format to numeric format const int res1 = Ndb_getInAddr(&servaddr.sin_addr, handle->hostname); if (res1 != 0) { - SET_ERROR(handle, NDB_MGM_ILLEGAL_IP_ADDRESS, ""); + DEBUG("Ndb_getInAddr(...) == -1"); + setError(handle, EINVAL, __LINE__, "Invalid hostname/address"); return -1; } @@ -380,7 +384,8 @@ ndb_mgm_connect(NdbMgmHandle handle, const char * mgmsrv) sizeof(servaddr)); if (res2 == -1) { NDB_CLOSE_SOCKET(sockfd); - SET_ERROR(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, ""); + setError(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, __LINE__, "Unable to connect to %s", + mgmsrv); return -1; } @@ -389,7 +394,7 @@ ndb_mgm_connect(NdbMgmHandle handle, const char * mgmsrv) return 0; } - + /** * Disconnect from a mgm server */ @@ -514,6 +519,8 @@ status_ackumulate(struct ndb_mgm_node_state * state, state->node_group = atoi(value); } else if(strcmp("version", field) == 0){ state->version = atoi(value); + } else if(strcmp("connect_count", field) == 0){ + state->connect_count = atoi(value); } else { ndbout_c("Unknown field: %s", field); } @@ -1422,10 +1429,103 @@ ndb_mgm_abort_backup(NdbMgmHandle handle, unsigned int backupId, return 0; } +extern "C" +struct ndb_mgm_configuration * +ndb_mgm_get_configuration(NdbMgmHandle handle, unsigned int version) { + + CHECK_HANDLE(handle, 0); + CHECK_CONNECTED(handle, 0); + + Properties args; + args.put("version", version); + + const ParserRow<ParserDummy> reply[] = { + MGM_CMD("get config reply", NULL, ""), + MGM_ARG("result", String, Mandatory, "Error message"), + MGM_ARG("Content-Length", Int, Optional, "Content length in bytes"), + MGM_ARG("Content-Type", String, Optional, "Type (octet-stream)"), + MGM_ARG("Content-Transfer-Encoding", String, Optional, "Encoding(base64)"), + MGM_END() + }; + + const Properties *prop; + prop = ndb_mgm_call(handle, reply, "get config", &args); + + if(prop == NULL) { + SET_ERROR(handle, EIO, "Unable to fetch config"); + return 0; + } + + do { + const char * buf; + if(!prop->get("result", &buf) || strcmp(buf, "Ok") != 0){ + ndbout_c("ERROR Message: %s\n", buf); + break; + } + + buf = "<Unspecified>"; + if(!prop->get("Content-Type", &buf) || + strcmp(buf, "ndbconfig/octet-stream") != 0){ + ndbout_c("Unhandled response type: %s", buf); + break; + } + + buf = "<Unspecified>"; + if(!prop->get("Content-Transfer-Encoding", &buf) + || strcmp(buf, "base64") != 0){ + ndbout_c("Unhandled encoding: %s", buf); + break; + } + + buf = "<Content-Length Unspecified>"; + Uint32 len = 0; + if(!prop->get("Content-Length", &len)){ + ndbout_c("Invalid response: %s\n", buf); + break; + } + + len += 1; // Trailing \n + + char* buf64 = new char[len]; + int read = 0; + size_t start = 0; + do { + if((read = read_socket(handle->socket, handle->read_timeout, + &buf64[start], len-start)) == -1){ + delete[] buf64; + buf64 = 0; + break; + } + start += read; + } while(start < len); + if(buf64 == 0) + break; + + UtilBuffer tmp; + const int res = base64_decode(buf64, len-1, tmp); + delete[] buf64; + if(res != 0){ + ndbout_c("Failed to decode buffer"); + break; + } + + ConfigValuesFactory cvf; + const int res2 = cvf.unpack(tmp); + if(!res2){ + ndbout_c("Failed to unpack buffer"); + break; + } + + return (ndb_mgm_configuration*)cvf.m_cfg; + } while(0); + + delete prop; + return 0; +} + /***************************************************************************** * Global Replication - *****************************************************************************/ - + ******************************************************************************/ extern "C" int ndb_mgm_rep_command(NdbMgmHandle handle, unsigned int request, diff --git a/ndb/src/mgmapi/mgmapi_configuration.cpp b/ndb/src/mgmapi/mgmapi_configuration.cpp new file mode 100644 index 00000000000..ae7fe2c294c --- /dev/null +++ b/ndb/src/mgmapi/mgmapi_configuration.cpp @@ -0,0 +1,157 @@ +#include <mgmapi.h> +#include "mgmapi_configuration.hpp" +#include <new> + +ndb_mgm_configuration_iterator::ndb_mgm_configuration_iterator +(const ndb_mgm_configuration & conf, unsigned type_of_section) + : m_config(conf.m_config) +{ + m_sectionNo = ~0; + m_typeOfSection = type_of_section; + first(); +} + +ndb_mgm_configuration_iterator::~ndb_mgm_configuration_iterator(){ + reset(); +} + +void +ndb_mgm_configuration_iterator::reset(){ + if(m_sectionNo != (Uint32)~0){ + m_config.closeSection(); + } +} + + +int +ndb_mgm_configuration_iterator::enter(){ + bool ok = m_config.openSection(m_typeOfSection, m_sectionNo); + if(ok){ + return 0; + } + + reset(); + m_sectionNo = ~0; + return -1; +} + +int +ndb_mgm_configuration_iterator::first(){ + reset(); + m_sectionNo = 0; + return enter(); +} + +int +ndb_mgm_configuration_iterator::next(){ + reset(); + m_sectionNo++; + return enter(); +} + +int +ndb_mgm_configuration_iterator::valid() const { + return m_sectionNo != (Uint32)~0; +} + +int +ndb_mgm_configuration_iterator::find(int param, unsigned search){ + unsigned val = search + 1; + + while(get(param, &val) == 0 && val != search){ + if(next() != 0) + break; + } + + if(val == search) + return 0; + + return -1; +} + +int +ndb_mgm_configuration_iterator::get(int param, unsigned * value) const { + return m_config.get(param, value) != true; + +} + +int +ndb_mgm_configuration_iterator::get(int param, + unsigned long long * value) const{ + return m_config.get(param, value) != true; +} + +int +ndb_mgm_configuration_iterator::get(int param, const char ** value) const { + return m_config.get(param, value) != true; +} + +/** + * Published C interface + */ +extern "C" +ndb_mgm_configuration_iterator* +ndb_mgm_create_configuration_iterator(ndb_mgm_configuration * conf, + unsigned type_of_section){ + ndb_mgm_configuration_iterator* iter = (ndb_mgm_configuration_iterator*) + malloc(sizeof(ndb_mgm_configuration_iterator)); + if(iter == 0) + return 0; + + return new(iter) ndb_mgm_configuration_iterator(* conf, type_of_section); +} + + +extern "C" +void ndb_mgm_destroy_iterator(ndb_mgm_configuration_iterator* iter){ + if(iter != 0){ + iter->~ndb_mgm_configuration_iterator(); + free(iter); + } +} + +extern "C" +int +ndb_mgm_first(ndb_mgm_configuration_iterator* iter){ + return iter->first(); +} + +extern "C" +int +ndb_mgm_next(ndb_mgm_configuration_iterator* iter){ + return iter->next(); +} + +extern "C" +int +ndb_mgm_valid(const ndb_mgm_configuration_iterator* iter){ + return iter->valid(); +} + +extern "C" +int +ndb_mgm_get_int_parameter(const ndb_mgm_configuration_iterator* iter, + int param, unsigned * value){ + return iter->get(param, value); +} + +extern "C" +int +ndb_mgm_get_int64_parameter(const ndb_mgm_configuration_iterator* iter, + int param, unsigned long long * value){ + return iter->get(param, value); +} + +extern "C" +int +ndb_mgm_get_string_parameter(const ndb_mgm_configuration_iterator* iter, + int param, const char ** value){ + return iter->get(param, value); +} + +extern "C" +int +ndb_mgm_find(ndb_mgm_configuration_iterator* iter, + int param, unsigned search){ + return iter->find(param, search); +} diff --git a/ndb/src/mgmapi/mgmapi_configuration.hpp b/ndb/src/mgmapi/mgmapi_configuration.hpp new file mode 100644 index 00000000000..c7feffd3a4e --- /dev/null +++ b/ndb/src/mgmapi/mgmapi_configuration.hpp @@ -0,0 +1,32 @@ +#ifndef MGMAPI_CONFIGURATION_HPP +#define MGMAPI_CONFIGURATION_HPP + +#include <ConfigValues.hpp> + +struct ndb_mgm_configuration { + ConfigValues m_config; +}; + +struct ndb_mgm_configuration_iterator { + Uint32 m_sectionNo; + Uint32 m_typeOfSection; + ConfigValues::ConstIterator m_config; + + ndb_mgm_configuration_iterator(const ndb_mgm_configuration &, unsigned type); + ~ndb_mgm_configuration_iterator(); + + int first(); + int next(); + int valid() const; + int find(int param, unsigned value); + + int get(int param, unsigned * value) const ; + int get(int param, unsigned long long * value) const ; + int get(int param, const char ** value) const ; + + // + void reset(); + int enter(); +}; + +#endif diff --git a/ndb/src/mgmapi/test/keso.c b/ndb/src/mgmapi/test/keso.c index d5086b20b6a..d2675b2ca8a 100644 --- a/ndb/src/mgmapi/test/keso.c +++ b/ndb/src/mgmapi/test/keso.c @@ -29,6 +29,7 @@ static int testConnect(NdbMgmHandle h, struct ndb_mgm_reply* reply); static int testDisconnect(NdbMgmHandle h, struct ndb_mgm_reply* reply); static int testStatus(NdbMgmHandle h, struct ndb_mgm_reply* reply); +static int testGetConfig(NdbMgmHandle h, struct ndb_mgm_reply* reply); #ifdef VM_TRACE static int testLogSignals(NdbMgmHandle h, struct ndb_mgm_reply* reply); static int testStartSignalLog(NdbMgmHandle h, struct ndb_mgm_reply* reply); @@ -152,6 +153,19 @@ int testDisconnect(NdbMgmHandle h, struct ndb_mgm_reply* reply) { } static +int testGetConfig(NdbMgmHandle h, struct ndb_mgm_reply* reply) { + int i = 0; + struct ndb_mgm_configuration * config = ndb_mgm_get_configuration(h, 0); + if (config != NULL) { + free(config); + } else { + ndbout_c("Unable to get config"); + return -1; + } + return 0; +} + +static int testStatus(NdbMgmHandle h, struct ndb_mgm_reply* reply) { int i = 0; struct ndb_mgm_cluster_state* cluster = ndb_mgm_get_status(h); diff --git a/ndb/src/mgmclient/Makefile_old b/ndb/src/mgmclient/Makefile_old index 9f9a6344ab9..d1b2d60a52a 100644 --- a/ndb/src/mgmclient/Makefile_old +++ b/ndb/src/mgmclient/Makefile_old @@ -4,7 +4,7 @@ TYPE := ndbapi BIN_TARGET := mgmtclient BIN_TARGET_LIBS := -BIN_TARGET_ARCHIVES := trace logger general mgmapi mgmsrvcommon portlib repapi +BIN_TARGET_ARCHIVES := trace logger mgmapi general mgmsrvcommon portlib repapi BIN_TARGET_ARCHIVES += editline diff --git a/ndb/src/mgmsrv/CommandInterpreter.cpp b/ndb/src/mgmsrv/CommandInterpreter.cpp index 8a7293b8434..cda613a5ef2 100644 --- a/ndb/src/mgmsrv/CommandInterpreter.cpp +++ b/ndb/src/mgmsrv/CommandInterpreter.cpp @@ -453,14 +453,15 @@ void CommandInterpreter::executeShow(char* parameters) { return; } else if (strcmp(parameters, "PROPERTIES") == 0 || strcmp(parameters, "PROP") == 0) { - _mgmtSrvr.getConfig()->print(); + ndbout << "_mgmtSrvr.getConfig()->print();" << endl; /* XXX */ } else if (strcmp(parameters, "CONFIGURATION") == 0 || strcmp(parameters, "CONFIG") == 0){ + ndbout << "_mgmtSrvr.getConfigFile()->print();" << endl; /* XXX */ _mgmtSrvr.getConfig()->printConfigFile(); } else if (strcmp(parameters, "PARAMETERS") == 0 || strcmp(parameters, "PARAMS") == 0 || strcmp(parameters, "PARAM") == 0) { - _mgmtSrvr.getConfig()->getConfigInfo()->print(); + ndbout << "_mgmtSrvr.getConfigInfo()->print();" << endl; /* XXX */ } else { ndbout << "Invalid argument." << endl; } @@ -773,11 +774,11 @@ void CommandInterpreter::executeStatus(int processId, } ndb_mgm_node_status status; - Uint32 startPhase, version, dynamicId, nodeGroup; + Uint32 startPhase, version, dynamicId, nodeGroup, connectCount; bool system; int result = _mgmtSrvr.status(processId, &status, &version, &startPhase, &system, - &dynamicId, &nodeGroup); + &dynamicId, &nodeGroup, &connectCount); if(result != 0){ ndbout << _mgmtSrvr.getErrorText(result) << endl; return; diff --git a/ndb/src/mgmsrv/Makefile_old b/ndb/src/mgmsrv/Makefile_old index b10bdb64d30..c99875ae8b6 100644 --- a/ndb/src/mgmsrv/Makefile_old +++ b/ndb/src/mgmsrv/Makefile_old @@ -1,10 +1,10 @@ include .defs.mk -TYPE := ndbapi +TYPE := ndbapi mgmapiclient BIN_TARGET := mgmtsrvr BIN_TARGET_LIBS := -BIN_TARGET_ARCHIVES := mgmapi NDB_API mgmsrvcommon +BIN_TARGET_ARCHIVES := NDB_API mgmsrvcommon mgmapi general ifneq ($(USE_EDITLINE), N) BIN_TARGET_ARCHIVES += editline @@ -31,6 +31,7 @@ SOURCES += CommandInterpreter.cpp endif CCFLAGS_LOC += -I$(call fixpath,$(NDB_TOP)/src/ndbapi) \ + -I$(call fixpath,$(NDB_TOP)/src/mgmapi) \ -I$(call fixpath,$(NDB_TOP)/include/mgmapi) \ -I$(call fixpath,$(NDB_TOP)/src/common/mgmcommon) diff --git a/ndb/src/mgmsrv/MgmtSrvr.cpp b/ndb/src/mgmsrv/MgmtSrvr.cpp index 34ef9dbb08e..713433cb8e9 100644 --- a/ndb/src/mgmsrv/MgmtSrvr.cpp +++ b/ndb/src/mgmsrv/MgmtSrvr.cpp @@ -28,7 +28,6 @@ #include <GlobalSignalNumbers.h> #include <signaldata/TestOrd.hpp> #include <signaldata/TamperOrd.hpp> -#include <signaldata/SetVarReq.hpp> #include <signaldata/StartOrd.hpp> #include <signaldata/ApiVersion.hpp> #include <signaldata/ResumeReq.hpp> @@ -48,6 +47,10 @@ #include "NodeLogLevel.hpp" #include <NdbConfig.h> +#include <mgmapi.h> +#include <mgmapi_configuration.hpp> +#include <mgmapi_config_parameters.h> + //#define MGM_SRV_DEBUG #ifdef MGM_SRV_DEBUG #define DEBUG(x) do ndbout << x << endl; while(0) @@ -224,19 +227,33 @@ void MgmtSrvr::startEventLog() { g_EventLogger.setCategory("MgmSrvr"); - const Properties *mgmProps; - _config->get("Node", _ownNodeId, &mgmProps); + + ndb_mgm_configuration_iterator * iter = ndb_mgm_create_configuration_iterator + ((ndb_mgm_configuration*)_config->m_configValues, CFG_SECTION_NODE); + if(iter == 0) + return ; + + if(ndb_mgm_find(iter, CFG_NODE_ID, _ownNodeId) != 0){ + ndb_mgm_destroy_iterator(iter); + return ; + } + + const char * tmp; BaseString logdest; char clusterLog[MAXPATHLEN]; - NdbConfig_ClusterLogFileName(clusterLog, sizeof(clusterLog)); - - mgmProps->get("LogDestination", logdest); - + + + if(ndb_mgm_get_string_parameter(iter, CFG_LOG_DESTINATION, &tmp) == 0){ + logdest.assign(tmp); + } + ndb_mgm_destroy_iterator(iter); + if(logdest.length()==0) { - logdest.assfmt("FILE:filename=%s,maxsize=1000000,maxfiles=6", clusterLog); + logdest.assfmt("FILE:filename=%s,maxsize=1000000,maxfiles=6", + clusterLog); } - + if(!g_EventLogger.addHandler(logdest)) { ndbout << "ERROR: cannot parse \"" << logdest << "\"" << endl; exit(1); @@ -374,8 +391,8 @@ MgmtSrvr::getNodeCount(enum ndb_mgm_node_type type) const } int -MgmtSrvr::getStatPort() const -{ +MgmtSrvr::getStatPort() const { +#if 0 const Properties *mgmProps; if(!getConfig()->get("Node", _ownNodeId, &mgmProps)) return -1; @@ -385,12 +402,16 @@ MgmtSrvr::getStatPort() const return -1; return tmp; +#else + return -1; +#endif } /* Constructor */ MgmtSrvr::MgmtSrvr(NodeId nodeId, const BaseString &configFilename, - const BaseString &ndb_config_filename): + const BaseString &ndb_config_filename, + Config * config): _blockNumber(1), // Hard coded block number since it makes it easy to send // signals to other management servers. _ownReference(0), @@ -415,8 +436,8 @@ MgmtSrvr::MgmtSrvr(NodeId nodeId, m_nextConfigGenerationNumber = 0; - _config = readConfig(); - + _config = (config == 0 ? readConfig() : config); + theMgmtWaitForResponseCondPtr = NdbCondition_Create(); m_configMutex = NdbMutex_Create(); @@ -427,31 +448,38 @@ MgmtSrvr::MgmtSrvr(NodeId nodeId, for(Uint32 i = 0; i<MAX_NODES; i++) nodeTypes[i] = (enum ndb_mgm_node_type)-1; - Properties::Iterator it(_config); - const char * name; - for(name = it.first(); name != NULL; name = it.next()){ - if(strncmp(name, "Node_", strlen("Node_")) == 0){ - const Properties * tmp; + ndb_mgm_configuration_iterator * iter = ndb_mgm_create_configuration_iterator + (config->m_configValues, CFG_SECTION_NODE); + for(ndb_mgm_first(iter); ndb_mgm_valid(iter); ndb_mgm_next(iter)){ + unsigned type, id; + if(ndb_mgm_get_int_parameter(iter, CFG_TYPE_OF_SECTION, &type) != 0) + continue; - _config->get(name, &tmp); - - Uint32 nodeId; - BaseString type; - MGM_REQUIRE(tmp->get("Id", &nodeId)); - MGM_REQUIRE(tmp->get("Type", type)); - MGM_REQUIRE(nodeId < MAX_NODES); + if(ndb_mgm_get_int_parameter(iter, CFG_NODE_ID, &id) != 0) + continue; + + MGM_REQUIRE(id < MAX_NODES); - if(type == "MGM") - nodeTypes[nodeId] = NDB_MGM_NODE_TYPE_MGM; - if(type == "API") - nodeTypes[nodeId] = NDB_MGM_NODE_TYPE_API; - if(type == "DB") - nodeTypes[nodeId] = NDB_MGM_NODE_TYPE_NDB; - if(type == "REP") - nodeTypes[nodeId] = NDB_MGM_NODE_TYPE_API; + 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; + case NODE_TYPE_REP: + nodeTypes[id] = NDB_MGM_NODE_TYPE_REP; + break; + case NODE_TYPE_EXT_REP: + default: + break; } } - + ndb_mgm_destroy_iterator(iter); + m_statisticsListner = NULL; _nodeLogLevelList = new NodeLogLevelList(); @@ -471,13 +499,6 @@ MgmtSrvr::check_start() return false; } - _props = new Config(* _config); - if (_props == 0) { - DEBUG("MgmtSrvr.cpp: Object props is NULL."); - return false; - } - MGM_REQUIRE(_props->put("LocalNodeId", _ownNodeId, true)); - return true; } @@ -488,11 +509,10 @@ MgmtSrvr::start() if (!check_start()) return false; } + theFacade = TransporterFacade::start_instance + (_ownNodeId, + (ndb_mgm_configuration*)_config->m_configValues); - theFacade = TransporterFacade::start_instance(_props, NULL); - delete _props; - _props = NULL; - if(theFacade == 0) { DEBUG("MgmtSrvr.cpp: theFacade is NULL."); return false; @@ -505,14 +525,14 @@ MgmtSrvr::start() _blockNumber = theFacade->open(this, signalReceivedNotification, nodeStatusNotification); - + if(_blockNumber == -1){ DEBUG("MgmtSrvr.cpp: _blockNumber is -1."); theFacade->stop_instance(); theFacade = 0; return false; } - + _ownReference = numberToRef(_blockNumber, _ownNodeId); startEventLog(); @@ -557,7 +577,11 @@ MgmtSrvr::~MgmtSrvr() NdbMutex_Destroy(m_configMutex); if(m_newConfig != NULL) - delete m_newConfig; + free(m_newConfig); + + if(_config != NULL) + delete _config; + delete _nodeLogLevelList; delete _clusterLogLevelList; @@ -812,9 +836,10 @@ MgmtSrvr::restart(bool nostart, bool initalStart, bool abort, s = NDB_MGM_NODE_STATUS_NO_CONTACT; while (s == NDB_MGM_NODE_STATUS_NO_CONTACT && waitTime > 0) { Uint32 startPhase = 0, version = 0, dynamicId = 0, nodeGroup = 0; + Uint32 connectCount = 0; bool system; status(nodeId, &s, &version, &startPhase, - &system, &dynamicId, &nodeGroup); + &system, &dynamicId, &nodeGroup, &connectCount); NdbSleep_MilliSleep(100); waitTime = (maxTime - NdbTick_CurrentMillisecond()); } @@ -1297,7 +1322,8 @@ MgmtSrvr::status(int processId, Uint32 * _phase, bool * _system, Uint32 * dynamic, - Uint32 * nodegroup) + Uint32 * nodegroup, + Uint32 * connectCount) { if (getNodeType(processId) == NDB_MGM_NODE_TYPE_API) { if(versionNode(processId, false,0,0) ==0) @@ -1324,7 +1350,8 @@ MgmtSrvr::status(int processId, * 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; @@ -1375,11 +1402,11 @@ MgmtSrvr::status(int processId, * _phase = 0; return 0; } - + return -1; } - - + + //**************************************************************************** //**************************************************************************** int @@ -1949,7 +1976,7 @@ MgmtSrvr::handleReceivedSignal(NdbApiSignal* signal) BackupEvent event; event.Event = BackupEvent::BackupStarted; event.Started.BackupId = conf->backupId; - event.Started.Nodes = conf->nodes; + event.Nodes = conf->nodes; #ifdef VM_TRACE ndbout_c("Backup master is %d", refToNode(signal->theSendersBlockRef)); #endif @@ -2012,7 +2039,7 @@ MgmtSrvr::handleReceivedSignal(NdbApiSignal* signal) event.Completed.stopGCP = rep->stopGCP; event.Completed.startGCP = rep->startGCP; - event.Completed.Nodes = rep->nodes; + event.Nodes = rep->nodes; backupCallback(event); } @@ -2169,8 +2196,9 @@ MgmtSrvr::getNextNodeId(NodeId * nodeId, enum ndb_mgm_node_type type) const while(nodeTypes[tmp] != type && tmp < MAX_NODES) tmp++; - if(tmp == MAX_NODES) + if(tmp == MAX_NODES){ return false; + } * nodeId = tmp; return true; @@ -2529,8 +2557,8 @@ MgmtSrvr::getStuff() } NodeId -MgmtSrvr::getPrimaryNode() const -{ +MgmtSrvr::getPrimaryNode() const { +#if 0 Uint32 tmp; const Properties *prop = NULL; @@ -2541,4 +2569,7 @@ MgmtSrvr::getPrimaryNode() const prop->get("PrimaryMGMNode", &tmp); return tmp; +#else + return 0; +#endif } diff --git a/ndb/src/mgmsrv/MgmtSrvr.hpp b/ndb/src/mgmsrv/MgmtSrvr.hpp index ce8765d6c73..1d394a14857 100644 --- a/ndb/src/mgmsrv/MgmtSrvr.hpp +++ b/ndb/src/mgmsrv/MgmtSrvr.hpp @@ -27,6 +27,7 @@ #include <NodeBitmask.hpp> #include <signaldata/ManagementServer.hpp> #include "SignalQueue.hpp" +#include <ndb_version.h> #include "NodeLogLevelList.hpp" @@ -151,7 +152,8 @@ public: /* Constructor */ MgmtSrvr(NodeId nodeId, /* Local nodeid */ const BaseString &config_filename, /* Where to save config */ - const BaseString &ndb_config_filename); /* Ndb.cfg filename */ + const BaseString &ndb_config_filename, /* Ndb.cfg filename */ + Config * config); /** * Read (initial) config file, create TransporterFacade, @@ -169,7 +171,8 @@ public: Uint32 * phase, bool * systemShutdown, Uint32 * dynamicId, - Uint32 * nodeGroup); + Uint32 * nodeGroup, + Uint32 * connectCount); // All the functions below may return any of this error codes: // NO_CONTACT_WITH_PROCESS, PROCESS_NOT_CONFIGURED, WRONG_PROCESS_TYPE, @@ -307,10 +310,10 @@ public: BackupAborted = 4 } Event; + NdbNodeBitmask Nodes; union { struct { Uint32 BackupId; - NdbNodeBitmask Nodes; } Started ; struct { Uint32 ErrorCode; @@ -321,7 +324,6 @@ public: Uint32 NoOfRecords; Uint32 NoOfLogBytes; Uint32 NoOfLogRecords; - NdbNodeBitmask Nodes; Uint32 startGCP; Uint32 stopGCP; } Completed ; @@ -522,7 +524,7 @@ private: int _blockNumber; NodeId _ownNodeId; BlockReference _ownReference; - NdbMutex *m_configMutex; + NdbMutex *m_configMutex; const Config * _config; Config * m_newConfig; BaseString m_configFilename; diff --git a/ndb/src/mgmsrv/MgmtSrvrConfig.cpp b/ndb/src/mgmsrv/MgmtSrvrConfig.cpp index f4e53409b30..10316bd2851 100644 --- a/ndb/src/mgmsrv/MgmtSrvrConfig.cpp +++ b/ndb/src/mgmsrv/MgmtSrvrConfig.cpp @@ -275,31 +275,30 @@ MgmtSrvr::readConfig() { Config *conf = NULL; if(m_configFilename.length() != 0) { /* Use config file */ - InitConfigFileParser parser(m_configFilename.c_str()); - - if(!parser.readConfigFile()) { + InitConfigFileParser parser; + conf = parser.parseConfig(m_configFilename.c_str()); + + if(conf == NULL) { /* Try to get configuration from other MGM server */ - ConfigRetriever cr; - cr.setLocalConfigFileName(m_localNdbConfigFilename.c_str()); - conf = new Config(*cr.getConfig("MGM", NDB_VERSION)); - } else { - conf = new Config(*parser.getConfig()); + return fetchConfig(); } - - if(conf == NULL) - return NULL; } return conf; } Config * MgmtSrvr::fetchConfig() { - Config *conf = NULL; ConfigRetriever cr; cr.setLocalConfigFileName(m_localNdbConfigFilename.c_str()); - conf = new Config(*cr.getConfig("MGM", NDB_VERSION)); + struct ndb_mgm_configuration * tmp = cr.getConfig(NDB_VERSION, + NODE_TYPE_MGM); + if(tmp != 0){ + Config * conf = new Config(); + conf->m_configValues = tmp; + return conf; + } - return conf; + return 0; } bool diff --git a/ndb/src/mgmsrv/Services.cpp b/ndb/src/mgmsrv/Services.cpp index 24f41fe64bf..739eef90c52 100644 --- a/ndb/src/mgmsrv/Services.cpp +++ b/ndb/src/mgmsrv/Services.cpp @@ -26,6 +26,9 @@ #include <BaseString.hpp> #include <Base64.hpp> +#include <ConfigValues.hpp> +#include <mgmapi_configuration.hpp> + #include "Services.hpp" static const unsigned int MAX_READ_TIMEOUT = 1000 ; @@ -275,12 +278,60 @@ MgmApiSession::getConfig_old(Parser_t::Context &ctx) { } #endif /* MGM_GET_CONFIG_BACKWARDS_COMPAT */ +inline void require(bool b){ if(!b) abort(); } + void MgmApiSession::getConfig(Parser_t::Context &ctx, const class Properties &args) { getConfig_common(ctx, args); } +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::getConfig_common(Parser_t::Context &, const class Properties &args, @@ -290,92 +341,100 @@ MgmApiSession::getConfig_common(Parser_t::Context &, args.get("version", &version); args.get("node", &node); -#if 0 - if(version != 0) { - m_output->println("get config"); - m_output->println("result: Invalid version number"); - m_output->println(""); - return; - } -#endif - const Config *conf = m_mgmsrv.getConfig(); if(conf == NULL) { - m_output->println("get config"); + m_output->println("get config reply"); m_output->println("result: Could not fetch configuration"); m_output->println(""); return; } - 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; - } - - Properties *reply = new Properties(*conf); - reply->put("Version", NDB_VERSION); // reply->put("Version", version); - reply->put("LocalNodeId", node); + if(version > 0 && version < makeVersion(3, 5, 0) && compat){ + Properties *reply = backward("", conf->m_oldConfig); + reply->put("Version", version); + reply->put("LocalNodeId", node); -#ifdef MGM_GET_CONFIG_BACKWARDS_COMPAT - if(compat) { + backward("", reply); + //reply->print(); + const Uint32 size = reply->getPackedSize(); Uint32 *buffer = new Uint32[size/4+1]; reply->pack(buffer); delete reply; - + const int uurows = (size + 44)/45; char * uubuf = new char[uurows * 62+5]; - + const int uusz = uuencode_mem(uubuf, (char *)buffer, size); delete[] buffer; - + m_output->println("GET CONFIG %d %d %d %d %d", - 0, NDB_VERSION, node, size, uusz);// 0, version, node, size, uusz); - + 0, version, node, size, uusz); + m_output->println("begin 664 Ndb_cfg.bin"); - + /* XXX Need to write directly to the socket, because the uubuf is not * NUL-terminated. This could/should probably be done in a nicer way. */ write_socket(m_socket, MAX_WRITE_TIMEOUT, uubuf, uusz); delete[] uubuf; - + m_output->println("end"); m_output->println(""); - } else { -#endif /* MGM_GET_CONFIG_BACKWARDS_COMPAT */ - - UtilBuffer buffer; - BaseString str; - reply->pack(buffer); - delete reply; - base64_encode(buffer, str); + return; + } - m_output->println("config: %s", str.c_str()); - m_output->println(""); -#ifdef MGM_GET_CONFIG_BACKWARDS_COMPAT + if(compat){ + m_output->println("GET CONFIG %d %d %d %d %d",1, version, 0, 0, 0); + return; } -#endif /* MGM_GET_CONFIG_BACKWARDS_COMPAT */ + + 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; + } + } + + const ConfigValues * cfg = &conf->m_configValues->m_config; + const Uint32 size = cfg->getPackedSize(); + + UtilBuffer src; + cfg->pack(src); + + BaseString str; + int res = base64_encode(src, str); + + m_output->println("get config reply"); + m_output->println("result: Ok"); + m_output->println("Content-Length: %d", str.length()); + m_output->println("Content-Type: ndbconfig/octet-stream"); + m_output->println("Content-Transfer-Encoding: base64"); + m_output->println(""); + m_output->println(str.c_str()); + m_output->println(""); + + return; } void @@ -756,10 +815,14 @@ printNodeStatus(OutputStream *output, NodeId nodeId = 0; while(mgmsrv.getNextNodeId(&nodeId, type)) { enum ndb_mgm_node_status status; - Uint32 startPhase = 0, version = 0, dynamicId = 0, nodeGroup = 0; + Uint32 startPhase = 0, + version = 0, + dynamicId = 0, + nodeGroup = 0, + connectCount = 0; bool system; mgmsrv.status(nodeId, &status, &version, &startPhase, - &system, &dynamicId, &nodeGroup); + &system, &dynamicId, &nodeGroup, &connectCount); output->println("node.%d.type: %s", nodeId, ndb_mgm_get_node_type_string(type)); @@ -770,6 +833,7 @@ printNodeStatus(OutputStream *output, 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); } } diff --git a/ndb/src/mgmsrv/main.cpp b/ndb/src/mgmsrv/main.cpp index 91b443f61a2..d9eb0001c44 100644 --- a/ndb/src/mgmsrv/main.cpp +++ b/ndb/src/mgmsrv/main.cpp @@ -34,6 +34,7 @@ #include <NdbHost.h> #include <ndb_version.h> #include <ConfigRetriever.hpp> +#include <mgmapi_config_parameters.h> #include <getarg.h> #if defined NDB_OSE || defined NDB_SOFTOSE @@ -191,7 +192,10 @@ NDB_MAIN(mgmsrv){ glob.mgmObject = new MgmtSrvr(glob.localNodeId, BaseString(glob.config_filename), - BaseString(glob.local_config_filename == 0 ? "" : glob.local_config_filename)); + BaseString(glob.local_config_filename == 0 ? "" : glob.local_config_filename), + glob.cluster_config); + + glob.cluster_config = 0; if(!glob.mgmObject->check_start()){ ndbout_c("Unable to start management server."); @@ -321,18 +325,21 @@ readGlobalConfig() { return false; /* Use config file */ - InitConfigFileParser parser(glob.config_filename); - - if(parser.readConfigFile()) { - glob.cluster_config = new Config(*parser.getConfig()); - } else { - /* Try to get configuration from other MGM server */ + InitConfigFileParser parser; + glob.cluster_config = parser.parseConfig(glob.config_filename); + if(glob.cluster_config == 0){ + /** + * Try to get configuration from other MGM server + * Note: Only new format + */ + glob.cluster_config = new Config(); + ConfigRetriever cr; cr.setLocalConfigFileName(glob.local_config_filename); - Properties* mgmconf = cr.getConfig("MGM", NDB_VERSION); - if (mgmconf == NULL) + glob.cluster_config->m_configValues = cr.getConfig(NDB_VERSION, + NODE_TYPE_MGM); + if (glob.cluster_config->m_configValues == NULL) return false; - glob.cluster_config = new Config(*mgmconf); } return true; } @@ -350,15 +357,23 @@ static bool setPortNo(){ const Properties *mgmProps; - if(!glob.cluster_config->get("Node", glob.localNodeId, &mgmProps)){ + ndb_mgm_configuration_iterator * iter = + ndb_mgm_create_configuration_iterator(glob.cluster_config->m_configValues, + CFG_SECTION_NODE); + if(iter == 0) + return false; + + if(ndb_mgm_find(iter, CFG_NODE_ID, glob.localNodeId) != 0){ ndbout << "Could not retrieve configuration for Node " << glob.localNodeId << " in config file." << endl << "Have you set correct NodeId for this node?" << endl; + ndb_mgm_destroy_iterator(iter); return false; } - BaseString type; - if(!mgmProps->get("Type", type) || strcasecmp(type.c_str(), "MGM") != 0){ + unsigned type; + if(ndb_mgm_get_int_parameter(iter, CFG_TYPE_OF_SECTION, &type) != 0 || + type != NODE_TYPE_MGM){ ndbout << "Local node id " << glob.localNodeId << " is not defined as management server" << endl << "Have you set correct NodeId for this node?" << endl; @@ -369,7 +384,7 @@ setPortNo(){ * Set Port * ************/ Uint32 tmp = 0; - if (!mgmProps->get("PortNumber", &tmp)){ + if(ndb_mgm_get_int_parameter(iter, CFG_MGM_PORT, &tmp) != 0){ ndbout << "Could not find PortNumber in the configuration file." << endl; return false; } @@ -378,15 +393,18 @@ setPortNo(){ /***************** * Set Stat Port * *****************/ +#if 0 if (!mgmProps->get("PortNumberStats", &tmp)){ ndbout << "Could not find PortNumberStats in the configuration file." << endl; return false; } glob.port_stats = tmp; +#endif - BaseString host; - if(!mgmProps->get("ExecuteOnComputer", host)){ +#if 0 + const char * host; + if(ndb_mgm_get_string_parameter(iter, mgmProps->get("ExecuteOnComputer", host)){ ndbout << "Failed to find \"ExecuteOnComputer\" for my node" << endl; ndbout << "Unable to verify own hostname" << endl; return false; @@ -422,8 +440,11 @@ setPortNo(){ return true; } - glob.use_specific_ip = false; glob.interface_name = strdup(hostname); - +#endif + + glob.interface_name = 0; + glob.use_specific_ip = false; + return true; } diff --git a/ndb/src/mgmsrv/mkconfig/Makefile b/ndb/src/mgmsrv/mkconfig/Makefile index d35f68a5648..43574eefbd1 100644 --- a/ndb/src/mgmsrv/mkconfig/Makefile +++ b/ndb/src/mgmsrv/mkconfig/Makefile @@ -3,12 +3,11 @@ include .defs.mk TYPE := ndbapi BIN_TARGET := mkconfig -BIN_TARGET_ARCHIVES := logger general trace mgmsrvcommon portlib +BIN_TARGET_ARCHIVES := logger trace mgmsrvcommon portlib general SOURCES := mkconfig.cpp CCFLAGS_LOC += -I.. -I$(call fixpath,$(NDB_TOP)/src/common/mgmcommon) - -OBJECTS_LOC := ../convertStrToInt.o +CFLAGS_mkconfig.cpp := -I$(call fixpath,$(NDB_TOP)/src/mgmapi) include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/src/mgmsrv/mkconfig/mkconfig.cpp b/ndb/src/mgmsrv/mkconfig/mkconfig.cpp index 224c82aa8a1..3b2046d7b49 100644 --- a/ndb/src/mgmsrv/mkconfig/mkconfig.cpp +++ b/ndb/src/mgmsrv/mkconfig/mkconfig.cpp @@ -16,6 +16,7 @@ #include <ndb_global.h> #include <ndb_version.h> +#include <mgmapi_configuration.hpp> #include <NdbMain.h> #include <Properties.hpp> @@ -36,25 +37,20 @@ NDB_COMMAND(mkconfig, return 0; } - InitConfigFileParser parser(argv[1]); - Config* cp; + InitConfigFileParser parser; + Config* _cp; - if (!parser.readConfigFile()) + if ((_cp = parser.parseConfig(argv[1])) == 0) return false; - cp = (Config *) parser.getConfig(); - if (cp == NULL) - return false; - - cp->put("VersionId", (Uint32)NDB_VERSION); - + ConfigValues* cp = &_cp->m_configValues->m_config; Uint32 sz = cp->getPackedSize(); - Uint32 * buf = new Uint32[sz]; + UtilBuffer buf; if(!cp->pack(buf)) return -1; - + FILE * f = fopen(argv[2], "w"); - if(fwrite(buf, 1, sz, f) != sz){ + if(fwrite(buf.get_data(), 1, buf.length(), f) != sz){ fclose(f); unlink(argv[2]); return -1; diff --git a/ndb/src/ndbapi/ClusterMgr.cpp b/ndb/src/ndbapi/ClusterMgr.cpp index 57967e5534f..b26d550fe31 100644 --- a/ndb/src/ndbapi/ClusterMgr.cpp +++ b/ndb/src/ndbapi/ClusterMgr.cpp @@ -32,6 +32,10 @@ #include <signaldata/NFCompleteRep.hpp> #include <signaldata/ApiRegSignalData.hpp> +#include <mgmapi.h> +#include <mgmapi_configuration.hpp> +#include <mgmapi_config_parameters.h> + // Just a C wrapper for threadMain extern "C" void* @@ -69,32 +73,49 @@ ClusterMgr::~ClusterMgr(){ } void -ClusterMgr::init(const IPCConfig & config){ - NodeId tmp = 0; - while(config.getNextRemoteNodeId(tmp)) { +ClusterMgr::init(ndb_mgm_configuration_iterator & iter){ + for(iter.first(); iter.valid(); iter.next()){ + Uint32 tmp = 0; + if(iter.get(CFG_NODE_ID, &tmp)) + continue; + theNodes[tmp].defined = true; #if 0 ndbout << "--------------------------------------" << endl; - config.print(); ndbout << "--------------------------------------" << endl; ndbout_c("ClusterMgr: Node %d defined as %s", tmp, config.getNodeType(tmp)); #endif - if(strcmp(config.getNodeType(tmp), "DB") == 0) { + + unsigned type; + if(iter.get(CFG_TYPE_OF_SECTION, &type)) + continue; + + switch(type){ + case NODE_TYPE_DB: theNodes[tmp].m_info.m_type = NodeInfo::DB; - } else if(strcmp(config.getNodeType(tmp), "API") == 0) { + break; + case NODE_TYPE_API: theNodes[tmp].m_info.m_type = NodeInfo::API; - } else if(strcmp(config.getNodeType(tmp), "MGM") == 0) { + break; + case NODE_TYPE_MGM: theNodes[tmp].m_info.m_type = NodeInfo::MGM; - } else if(strcmp(config.getNodeType(tmp), "REP") == 0) { + break; + case NODE_TYPE_REP: theNodes[tmp].m_info.m_type = NodeInfo::REP; - } else if(strcmp(config.getNodeType(tmp), "EXTERNAL REP") == 0) { + break; + case NODE_TYPE_EXT_REP: theNodes[tmp].m_info.m_type = NodeInfo::REP; - theNodes[tmp].hbFrequency = config.getREPHBFrequency(tmp); - assert(100 <= theNodes[tmp].hbFrequency && - theNodes[tmp].hbFrequency < 60 * 60 * 1000); - } else { + { + Uint32 hbFreq = 10000; + //ndb_mgm_get_int_parameter(iter, CFG_, &hbFreq); + theNodes[tmp].hbFrequency = hbFreq; + assert(100 <= hbFreq && hbFreq < 60 * 60 * 1000); + } + break; + default: + type = type; #if 0 - ndbout_c("ClusterMgr: Unknown node type: %s", config.getNodeType(tmp)); + ndbout_c("ClusterMgr: Unknown node type: %d", type); #endif } } @@ -162,45 +183,43 @@ ClusterMgr::threadMain( ){ const NodeId nodeId = i; Node & theNode = theNodes[nodeId]; - if (theNode.defined == true) { -#if 0 - ndbout_c("ClusterMgr: compatible %d", (int)nodeId); -#endif + if (!theNode.defined) + continue; - if (theNode.connected == false){ - theFacade.doConnect(nodeId); - continue; + if (theNode.connected == false){ + theFacade.doConnect(nodeId); + continue; + } + + if (!theNode.compatible){ + continue; + } + + theNode.hbCounter += timeSlept; + if (theNode.hbCounter >= theNode.hbFrequency){ + /** + * It is now time to send a new Heartbeat + */ + theNode.hbSent++; + theNode.hbCounter = 0; + /** + * If the node is of type REP, + * then the receiver of the signal should be API_CLUSTERMGR + */ + if (theNode.m_info.m_type == NodeInfo::REP) { + signal.theReceiversBlockNumber = API_CLUSTERMGR; } - -#if 0 - ndbout_c("ClusterMgr: connected %d", (int)nodeId); +#if 0 + ndbout_c("ClusterMgr: Sending API_REGREQ to node %d", (int)nodeId); #endif - - theNode.hbCounter += timeSlept; - if (theNode.hbCounter >= theNode.hbFrequency){ - /** - * It is now time to send a new Heartbeat - */ - theNode.hbSent++; - theNode.hbCounter = 0; - /** - * If the node is of type REP, - * then the receiver of the signal should be API_CLUSTERMGR - */ - if (theNode.m_info.m_type == NodeInfo::REP) { - signal.theReceiversBlockNumber = API_CLUSTERMGR; - } -#if 0 - ndbout_c("ClusterMgr: Sending API_REGREQ to node %d", (int)nodeId); -#endif - theFacade.sendSignalUnCond(&signal, nodeId); - }//if - - if (theNode.hbSent == 4 && theNode.hbFrequency > 0){ - reportNodeFailed(i); - }//if - }//if(defined) - }//for + theFacade.sendSignalUnCond(&signal, nodeId); + }//if + + if (theNode.hbSent == 4 && theNode.hbFrequency > 0){ + reportNodeFailed(i); + }//if + } + /** * End of secure area. Let other threads in */ @@ -281,6 +300,10 @@ ClusterMgr::execAPI_REGCONF(const Uint32 * theData){ const ApiRegConf * const apiRegConf = (ApiRegConf *)&theData[0]; const NodeId nodeId = refToNode(apiRegConf->qmgrRef); +#if 0 + ndbout_c("ClusterMgr: Recd API_REGCONF from node %d", nodeId); +#endif + assert(nodeId > 0 && nodeId < MAX_NODES); Node & node = theNodes[nodeId]; diff --git a/ndb/src/ndbapi/ClusterMgr.hpp b/ndb/src/ndbapi/ClusterMgr.hpp index 7b7b947742b..cc3cf66c8aa 100644 --- a/ndb/src/ndbapi/ClusterMgr.hpp +++ b/ndb/src/ndbapi/ClusterMgr.hpp @@ -40,7 +40,7 @@ class ClusterMgr { public: ClusterMgr(class TransporterFacade &); ~ClusterMgr(); - void init(const IPCConfig & config); + void init(struct ndb_mgm_configuration_iterator & config); void reportConnected(NodeId nodeId); void reportDisconnected(NodeId nodeId); @@ -114,7 +114,7 @@ ClusterMgr::getNoOfConnectedNodes() const { return noOfConnectedNodes; } -/******************************************************************************/ +/*****************************************************************************/ /** * @class ArbitMgr diff --git a/ndb/src/ndbapi/Makefile_old b/ndb/src/ndbapi/Makefile_old index f4c82e5d6ba..f2dd21fdaa3 100644 --- a/ndb/src/ndbapi/Makefile_old +++ b/ndb/src/ndbapi/Makefile_old @@ -15,13 +15,16 @@ LIB_TARGET_ARCHIVES := $(ARCHIVE_TARGET) \ transporter \ general \ signaldataprint \ - mgmsrvcommon \ + mgmapi mgmsrvcommon \ portlib \ logger \ trace DIRS := signal-sender +CFLAGS_TransporterFacade.cpp := -I$(call fixpath,$(NDB_TOP)/src/mgmapi) +CFLAGS_ClusterMgr.cpp := -I$(call fixpath,$(NDB_TOP)/src/mgmapi) + # Source files of non-templated classes (.cpp files) SOURCES = \ TransporterFacade.cpp \ diff --git a/ndb/src/ndbapi/Ndb.cpp b/ndb/src/ndbapi/Ndb.cpp index fe21b4e02a4..9caf9f37afb 100644 --- a/ndb/src/ndbapi/Ndb.cpp +++ b/ndb/src/ndbapi/Ndb.cpp @@ -474,6 +474,19 @@ Ndb::closeTransaction(NdbConnection* aConnection) //----------------------------------------------------- // closeTransaction called on non-existing transaction //----------------------------------------------------- + + if(aConnection->theError.code == 4008){ + /** + * When a SCAN timed-out, returning the NdbConnection leads + * to reuse. And TC crashes when the API tries to reuse it to + * something else... + */ +#ifdef VM_TRACE + printf("Scan timeout:ed NdbConnection-> not returning it-> memory leak\n"); +#endif + return; + } + #ifdef VM_TRACE printf("Non-existing transaction into closeTransaction\n"); abort(); diff --git a/ndb/src/ndbapi/Ndbif.cpp b/ndb/src/ndbapi/Ndbif.cpp index 2d722e12129..a05eb4c54c3 100644 --- a/ndb/src/ndbapi/Ndbif.cpp +++ b/ndb/src/ndbapi/Ndbif.cpp @@ -88,7 +88,7 @@ Ndb::init(int aMaxNoOfTransactions) theMyRef = numberToRef(theNdbBlockNumber, theNode); for (i = 1; i < MAX_NDB_NODES; i++){ - if (theFacade->getIsNodeDefined(i)){ + if (theFacade->getIsDbNode(i)){ theDBnodes[theNoOfDBnodes] = i; theNoOfDBnodes++; } diff --git a/ndb/src/ndbapi/Ndbinit.cpp b/ndb/src/ndbapi/Ndbinit.cpp index 042faa431a0..1d9d6fee5e4 100644 --- a/ndb/src/ndbapi/Ndbinit.cpp +++ b/ndb/src/ndbapi/Ndbinit.cpp @@ -137,7 +137,7 @@ Ndb::Ndb( const char* aDataBase , const char* aDataBaseSchema) : TransporterFacade * m_facade = 0; if(theNoOfNdbObjects == 0){ - if ((m_facade = TransporterFacade::start_instance(0,ndbConnectString)) == 0) + if ((m_facade = TransporterFacade::start_instance(ndbConnectString)) == 0) theInitState = InitConfigError; } else { m_facade = TransporterFacade::instance(); diff --git a/ndb/src/ndbapi/TransporterFacade.cpp b/ndb/src/ndbapi/TransporterFacade.cpp index 7806e482f1f..e725144a8f8 100644 --- a/ndb/src/ndbapi/TransporterFacade.cpp +++ b/ndb/src/ndbapi/TransporterFacade.cpp @@ -28,6 +28,8 @@ #include "API.hpp" #include <ConfigRetriever.hpp> +#include <mgmapi_config_parameters.h> +#include <mgmapi_configuration.hpp> #include <NdbConfig.h> #include <ndb_version.h> #include <SignalLoggerManager.hpp> @@ -331,39 +333,40 @@ atexit_stop_instance(){ * Which is protected by a mutex */ TransporterFacade* -TransporterFacade::start_instance(Properties* props, const char *connectString) -{ - bool ownProps = false; - if (props == NULL) { - // TransporterFacade used from API get config from mgmt srvr - ConfigRetriever configRetriever; - configRetriever.setConnectString(connectString); - props = configRetriever.getConfig("API", NDB_VERSION); - if (props == 0) { - ndbout << "Configuration error: "; - const char* erString = configRetriever.getErrorString(); - if (erString == 0) { - erString = "No error specified!"; - } - ndbout << erString << endl; - return NULL; +TransporterFacade::start_instance(const char * connectString){ + + // TransporterFacade used from API get config from mgmt srvr + ConfigRetriever configRetriever; + configRetriever.setConnectString(connectString); + ndb_mgm_configuration * props = configRetriever.getConfig(NDB_VERSION, + NODE_TYPE_API); + if (props == 0) { + ndbout << "Configuration error: "; + const char* erString = configRetriever.getErrorString(); + if (erString == 0) { + erString = "No error specified!"; } - props->put("LocalNodeId", configRetriever.getOwnNodeId()); - props->put("LocalNodeType", "API"); - - ownProps = true; + ndbout << erString << endl; + return 0; } - TransporterFacade* tf = new TransporterFacade(); + const int nodeId = configRetriever.getOwnNodeId(); - if (! tf->init(props)) { + TransporterFacade * tf = start_instance(nodeId, props); + + free(props); + return tf; +} + +TransporterFacade* +TransporterFacade::start_instance(int nodeId, + const ndb_mgm_configuration* props) +{ + TransporterFacade* tf = new TransporterFacade(); + if (! tf->init(nodeId, props)) { delete tf; return NULL; } - if (ownProps) { - delete props; - } - /** * Install atexit handler */ @@ -498,61 +501,65 @@ TransporterFacade::TransporterFacade() : } bool -TransporterFacade::init(Properties* props) +TransporterFacade::init(Uint32 nodeId, const ndb_mgm_configuration* props) { - IPCConfig config(props); - - if (config.init() != 0) { - TRP_DEBUG( "IPCConfig object config failed to init()" ); - return false; - } - theOwnId = config.ownId(); - + theOwnId = nodeId; theTransporterRegistry = new TransporterRegistry(this); - if(config.configureTransporters(theTransporterRegistry) <= 0) { + + const int res = IPCConfig::configureTransporters(nodeId, + * props, + * theTransporterRegistry); + if(res <= 0){ TRP_DEBUG( "configureTransporters returned 0 or less" ); return false; } + ndb_mgm_configuration_iterator iter(* props, CFG_SECTION_NODE); + iter.first(); theClusterMgr = new ClusterMgr(* this); - theClusterMgr->init(config); - - theReceiveThread = NdbThread_Create(runReceiveResponse_C, - (void**)this, - 32768, - "ndb_receive", - NDB_THREAD_PRIO_LOW); - - theSendThread = NdbThread_Create(runSendRequest_C, - (void**)this, - 32768, - "ndb_send", - NDB_THREAD_PRIO_LOW); - - theClusterMgr->startThread(); + theClusterMgr->init(iter); /** * Unless there is a "Name", the initiated transporter is within * an NDB Cluster. (If "Name" is defined, then the transporter * is used to connect to a different system, i.e. NDB Cluster.) */ +#if 0 if (!props->contains("Name")) { - const Properties* p = 0; - if(!props->get("Node", ownId(), &p)) { +#endif + iter.first(); + if(iter.find(CFG_NODE_ID, nodeId)){ TRP_DEBUG( "Node info missing from config." ); return false; } Uint32 rank = 0; - if (p->get("ArbitrationRank", &rank) && rank > 0) { + if(!iter.get(CFG_NODE_ARBIT_RANK, &rank) && rank>0){ theArbitMgr = new ArbitMgr(* this); theArbitMgr->setRank(rank); Uint32 delay = 0; - p->get("ArbitrationDelay", &delay); + iter.get(CFG_NODE_ARBIT_DELAY, &delay); theArbitMgr->setDelay(delay); } + +#if 0 } +#endif + + theReceiveThread = NdbThread_Create(runReceiveResponse_C, + (void**)this, + 32768, + "ndb_receive", + NDB_THREAD_PRIO_LOW); + + theSendThread = NdbThread_Create(runSendRequest_C, + (void**)this, + 32768, + "ndb_send", + NDB_THREAD_PRIO_LOW); + theClusterMgr->startThread(); + #ifdef API_TRACE signalLogger.logOn(true, 0, SignalLoggerManager::LogInOut); #endif diff --git a/ndb/src/ndbapi/TransporterFacade.hpp b/ndb/src/ndbapi/TransporterFacade.hpp index 1fe72debe1c..4b76cbe864a 100644 --- a/ndb/src/ndbapi/TransporterFacade.hpp +++ b/ndb/src/ndbapi/TransporterFacade.hpp @@ -27,8 +27,8 @@ class ClusterMgr; class ArbitMgr; -class Properties; class IPCConfig; +struct ndb_mgm_configuration; class Ndb; class NdbApiSignal; @@ -51,10 +51,11 @@ class TransporterFacade public: TransporterFacade(); virtual ~TransporterFacade(); - bool init(Properties* props); + bool init(Uint32, const ndb_mgm_configuration *); static TransporterFacade* instance(); - static TransporterFacade* start_instance(Properties* ipcConfig, const char *connectString); + static TransporterFacade* start_instance(int, const ndb_mgm_configuration*); + static TransporterFacade* start_instance(const char *connectString); static void stop_instance(); /** @@ -79,7 +80,7 @@ public: // Is node available for running transactions bool get_node_alive(NodeId nodeId) const; bool get_node_stopping(NodeId nodeId) const; - bool getIsNodeDefined(NodeId nodeId) const; + bool getIsDbNode(NodeId nodeId) const; bool getIsNodeSendable(NodeId nodeId) const; Uint32 getNodeGrp(NodeId nodeId) const; Uint32 getNodeSequence(NodeId nodeId) const; @@ -255,8 +256,10 @@ TransporterFacade::check_send_size(Uint32 node_id, Uint32 send_size) inline bool -TransporterFacade::getIsNodeDefined(NodeId n) const { - return theClusterMgr->getNodeInfo(n).defined; +TransporterFacade::getIsDbNode(NodeId n) const { + return + theClusterMgr->getNodeInfo(n).defined && + theClusterMgr->getNodeInfo(n).m_info.m_type == NodeInfo::DB; } inline diff --git a/ndb/src/ndbapi/signal-sender/SignalSender.cpp b/ndb/src/ndbapi/signal-sender/SignalSender.cpp index e642848dcee..680d0c23b4a 100644 --- a/ndb/src/ndbapi/signal-sender/SignalSender.cpp +++ b/ndb/src/ndbapi/signal-sender/SignalSender.cpp @@ -71,7 +71,7 @@ SimpleSignal::print(FILE * out){ SignalSender::SignalSender(const char * connectString){ m_cond = NdbCondition_Create(); - theFacade = TransporterFacade::start_instance(0,connectString); + theFacade = TransporterFacade::start_instance(connectString); m_blockNo = theFacade->open(this, execSignal, execNodeStatus); assert(m_blockNo > 0); } diff --git a/ndb/src/rep/adapters/ExtNDB.cpp b/ndb/src/rep/adapters/ExtNDB.cpp index 036406828be..6642b750b57 100644 --- a/ndb/src/rep/adapters/ExtNDB.cpp +++ b/ndb/src/rep/adapters/ExtNDB.cpp @@ -72,22 +72,26 @@ ExtNDB::init(const char * connectString) "ExtNDB_Service", NDB_THREAD_PRIO_LOW); - ConfigRetriever configRetriever; - configRetriever.setConnectString(connectString); +#if 0 + /** + * I don't see that this does anything + * + * Jonas 13/2-04 + */ + ConfigRetriever cr; cr.setConnectString(connectString); - Properties* config = configRetriever.getConfig("REP", REP_VERSION_ID); + ndb_mgm_configuration * config = cr.getConfig(NDB_VERSION, NODE_TYPE_REP); if (config == 0) { ndbout << "ExtNDB: Configuration error: "; - const char* erString = configRetriever.getErrorString(); + const char* erString = cr.getErrorString(); if (erString == 0) { erString = "No error specified!"; } ndbout << erString << endl; return false; } - m_ownNodeId = configRetriever.getOwnNodeId(); - config->put("LocalNodeId", m_ownNodeId); - config->put("LocalNodeType", "REP"); + NdbAutoPtr autoPtr(config); + m_ownNodeId = r.getOwnNodeId(); /** * Check which GREPs to connect to (in configuration) @@ -117,6 +121,7 @@ ExtNDB::init(const char * connectString) } } } +#endif m_transporterFacade = TransporterFacade::instance(); @@ -142,7 +147,7 @@ ExtNDB::init(const char * connectString) m_ownBlockNo); for (Uint32 i=1; i<MAX_NDB_NODES; i++) { - if (m_transporterFacade->getIsNodeDefined(i) && + if (m_transporterFacade->getIsDbNode(i) && m_transporterFacade->getIsNodeSendable(i)) { Uint32 nodeGrp = m_transporterFacade->getNodeGrp(i); diff --git a/ndb/src/rep/state/RepState.hpp b/ndb/src/rep/state/RepState.hpp index e88151d5609..06bbca19f7e 100644 --- a/ndb/src/rep/state/RepState.hpp +++ b/ndb/src/rep/state/RepState.hpp @@ -22,6 +22,7 @@ #include <rep/repapi/repapi.h> #include <rep/ExtSender.hpp> #include <rep/adapters/AppNDB.hpp> +#include <Properties.hpp> #include "Channel.hpp" #include "Interval.hpp" diff --git a/ndb/src/rep/transfer/TransPS.cpp b/ndb/src/rep/transfer/TransPS.cpp index d43555a0ce5..11fb0203cbc 100644 --- a/ndb/src/rep/transfer/TransPS.cpp +++ b/ndb/src/rep/transfer/TransPS.cpp @@ -47,6 +47,8 @@ TransPS::~TransPS() void TransPS::init(TransporterFacade * tf, const char * connectString) { + abort(); +#ifdef NOT_FUNCTIONAL m_signalExecThread = NdbThread_Create(signalExecThread_C, (void **)this, 32768, @@ -128,6 +130,7 @@ TransPS::init(TransporterFacade * tf, const char * connectString) m_repSender->setNodeId(extRepNodeId); m_repSender->setOwnRef(m_ownRef); m_repSender->setTransporterFacade(tf); +#endif } /***************************************************************************** diff --git a/ndb/src/rep/transfer/TransSS.cpp b/ndb/src/rep/transfer/TransSS.cpp index 719271df238..376c6375bc4 100644 --- a/ndb/src/rep/transfer/TransSS.cpp +++ b/ndb/src/rep/transfer/TransSS.cpp @@ -52,6 +52,8 @@ TransSS::~TransSS() void TransSS::init(const char * connectString) { + abort(); +#ifdef NOT_FUNCTIONAL m_signalExecThread = NdbThread_Create(signalExecThread_C, (void **)this, 32768, @@ -139,6 +141,7 @@ TransSS::init(const char * connectString) m_repSender->setNodeId(extRepNodeId); m_repSender->setOwnRef(m_ownRef); m_repSender->setTransporterFacade(m_transporterFacade); +#endif } /***************************************************************************** diff --git a/ndb/test/include/NdbConfig.hpp b/ndb/test/include/NdbConfig.hpp index f13872f4d64..19439fafbb2 100644 --- a/ndb/test/include/NdbConfig.hpp +++ b/ndb/test/include/NdbConfig.hpp @@ -17,29 +17,22 @@ #ifndef NDBT_CONFIG_HPP #define NDBT_CONFIG_HPP +#include <ndb_types.h> #include <mgmapi.h> #include <Vector.hpp> #include <NdbRestarter.hpp> -#include <Properties.hpp> +#include <mgmapi_config_parameters.h> -class NdbConfig : public NdbRestarter{ +class NdbConfig : public NdbRestarter { public: NdbConfig(int own_id, const char* addr = 0) : NdbRestarter(addr), ownNodeId(own_id) {}; - bool getProperty(unsigned int node_id, const char* type, - const char * name, Uint32 * value) const; - bool getProperty(unsigned int node_id, const char* type, - const char * name, const char ** value) const; - - bool getHostName(unsigned int node_id, - const char ** hostname) const; -protected: - bool getPropsForNode(unsigned int node_id, - const char* type, - const Properties ** props) const; + bool getProperty(unsigned nodeid, unsigned type, unsigned key, Uint32 * val); + bool getHostName(unsigned int node_id, const char ** hostname); + //protected: int ownNodeId; }; diff --git a/ndb/test/include/NdbRestarter.hpp b/ndb/test/include/NdbRestarter.hpp index cfd5409bb69..b4c29a87eff 100644 --- a/ndb/test/include/NdbRestarter.hpp +++ b/ndb/test/include/NdbRestarter.hpp @@ -89,7 +89,9 @@ protected: const char* host; int port; NdbMgmHandle handle; - + ndb_mgm_configuration * m_config; +protected: + ndb_mgm_configuration * getConfig(); }; #endif diff --git a/ndb/test/ndbapi/testDict.cpp b/ndb/test/ndbapi/testDict.cpp index 06614690b8d..1451c942362 100644 --- a/ndb/test/ndbapi/testDict.cpp +++ b/ndb/test/ndbapi/testDict.cpp @@ -1003,9 +1003,9 @@ int runGetPrimaryKey(NDBT_Context* ctx, NDBT_Step* step){ int NF_codes[] = { - 14000 - ,14001 - //,14002 + 6003 + ,6004 + //,6005 }; int diff --git a/ndb/test/ndbapi/testSystemRestart.cpp b/ndb/test/ndbapi/testSystemRestart.cpp index 1b8a35487cb..61e086ff941 100644 --- a/ndb/test/ndbapi/testSystemRestart.cpp +++ b/ndb/test/ndbapi/testSystemRestart.cpp @@ -805,6 +805,207 @@ int runSystemRestart5(NDBT_Context* ctx, NDBT_Step* step){ return result; } +int runSystemRestart6(NDBT_Context* ctx, NDBT_Step* step){ + Ndb* pNdb = GETNDB(step); + int result = NDBT_OK; + int timeout = 300; + Uint32 loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + NdbRestarter restarter; + Uint32 i = 1; + + const Uint32 nodeCount = restarter.getNumDbNodes(); + if(nodeCount < 2){ + g_info << "SR6 - Needs atleast 2 nodes to test" << endl; + return NDBT_OK; + } + + Vector<int> nodeIds; + for(Uint32 i = 0; i<nodeCount; i++) + nodeIds.push_back(restarter.getDbNodeId(i)); + + Uint32 currentRestartNodeIndex = 0; + UtilTransactions utilTrans(*ctx->getTab()); + HugoTransactions hugoTrans(*ctx->getTab()); + + while(i<=loops && result != NDBT_FAILED){ + + g_info << "Loop " << i << "/"<< loops <<" started" << endl; + /** + * 1. Load data + * 2. Restart all node -nostart + * 3. Restart some nodes -i -nostart + * 4. Start all nodes verify records + */ + g_info << "Loading records..." << endl; + hugoTrans.loadTable(pNdb, records); + + CHECK(restarter.restartAll(false, true, false) == 0); + + Uint32 nodeId = nodeIds[currentRestartNodeIndex]; + currentRestartNodeIndex = (currentRestartNodeIndex + 1 ) % nodeCount; + + CHECK(restarter.restartOneDbNode(nodeId, true, true,false) == 0); + CHECK(restarter.waitClusterNoStart(timeout) == 0); + CHECK(restarter.startAll() == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + CHECK(pNdb->waitUntilReady(timeout) == 0); + int count = records - 1; + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == records); + CHECK(utilTrans.clearTable(pNdb) == 0); + i++; + } + + g_info << "runSystemRestart6 finished" << endl; + + return result; +} + +int runSystemRestart7(NDBT_Context* ctx, NDBT_Step* step){ + Ndb* pNdb = GETNDB(step); + int result = NDBT_OK; + Uint32 loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + NdbRestarter restarter; + Uint32 i = 1; + + const Uint32 nodeCount = restarter.getNumDbNodes(); + if(nodeCount < 2){ + g_info << "SR8 - Needs atleast 2 nodes to test" << endl; + return NDBT_OK; + } + + Vector<int> nodeIds; + for(Uint32 i = 0; i<nodeCount; i++) + nodeIds.push_back(restarter.getDbNodeId(i)); + + int a_nodeIds[64]; + if(nodeCount > 64) + abort(); + + Uint32 currentRestartNodeIndex = 1; + UtilTransactions utilTrans(*ctx->getTab()); + HugoTransactions hugoTrans(*ctx->getTab()); + + while(i<=loops && result != NDBT_FAILED){ + + g_info << "Loop " << i << "/"<< loops <<" started" << endl; + /** + * 1. Load data + * 2. Restart all node -nostart + * 3. Start all but one node + * 4. Wait for startphase >= 2 + * 5. Start last node + * 6. Verify records + */ + g_info << "Loading records..." << endl; + hugoTrans.loadTable(pNdb, records); + + CHECK(restarter.restartAll(false, true, false) == 0); + + int nodeId = nodeIds[currentRestartNodeIndex]; + currentRestartNodeIndex = (currentRestartNodeIndex + 1 ) % nodeCount; + + Uint32 j = 0; + for(Uint32 k = 0; k<nodeCount; k++){ + if(nodeIds[k] != nodeId){ + a_nodeIds[j++] = nodeIds[k]; + } + } + + CHECK(restarter.startNodes(a_nodeIds, nodeCount - 1) == 0); + CHECK(restarter.waitNodesStarted(a_nodeIds, nodeCount - 1, 120) == 0); + CHECK(pNdb->waitUntilReady(5) == 0); + int count = records - 1; + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == records); + + CHECK(restarter.startNodes(&nodeId, 1) == 0); + CHECK(restarter.waitNodesStarted(&nodeId, 1, 120) == 0); + + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == records); + CHECK(utilTrans.clearTable(pNdb) == 0); + + i++; + } + + g_info << "runSystemRestart7 finished" << endl; + + return result; +} + +int runSystemRestart8(NDBT_Context* ctx, NDBT_Step* step){ + Ndb* pNdb = GETNDB(step); + int result = NDBT_OK; + int timeout = 300; + Uint32 loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + NdbRestarter restarter; + Uint32 i = 1; + + const Uint32 nodeCount = restarter.getNumDbNodes(); + if(nodeCount < 2){ + g_info << "SR8 - Needs atleast 2 nodes to test" << endl; + return NDBT_OK; + } + + Vector<int> nodeIds; + for(Uint32 i = 0; i<nodeCount; i++) + nodeIds.push_back(restarter.getDbNodeId(i)); + + int a_nodeIds[64]; + if(nodeCount > 64) + abort(); + + Uint32 currentRestartNodeIndex = 1; + UtilTransactions utilTrans(*ctx->getTab()); + HugoTransactions hugoTrans(*ctx->getTab()); + + while(i<=loops && result != NDBT_FAILED){ + + g_info << "Loop " << i << "/"<< loops <<" started" << endl; + /** + * 1. Load data + * 2. Restart all node -nostart + * 3. Start all but one node + * 4. Verify records + * 5. Start last node + * 6. Verify records + */ + g_info << "Loading records..." << endl; + hugoTrans.loadTable(pNdb, records); + + CHECK(restarter.restartAll(false, true, false) == 0); + + int nodeId = nodeIds[currentRestartNodeIndex]; + currentRestartNodeIndex = (currentRestartNodeIndex + 1 ) % nodeCount; + + Uint32 j = 0; + for(Uint32 k = 0; k<nodeCount; k++){ + if(nodeIds[k] != nodeId){ + a_nodeIds[j++] = nodeIds[k]; + } + } + + CHECK(restarter.startNodes(a_nodeIds, nodeCount-1) == 0); + CHECK(restarter.waitNodesStartPhase(a_nodeIds, nodeCount-1, 3, 120) == 0); + CHECK(restarter.startNodes(&nodeId, 1) == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + + int count = records - 1; + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == records); + CHECK(utilTrans.clearTable(pNdb) == 0); + i++; + } + + g_info << "runSystemRestart7 finished" << endl; + + return result; +} + int runWaitStarted(NDBT_Context* ctx, NDBT_Step* step){ NdbRestarter restarter; @@ -817,8 +1018,13 @@ int runWaitStarted(NDBT_Context* ctx, NDBT_Step* step){ int runClearTable(NDBT_Context* ctx, NDBT_Step* step){ int records = ctx->getNumRecords(); - UtilTransactions utilTrans(*ctx->getTab()); - if (utilTrans.clearTable2(GETNDB(step), records) != 0){ + Ndb* pNdb = GETNDB(step); + if(pNdb->waitUntilReady(5) != 0){ + return NDBT_FAILED; + } + + UtilTransactions utilTrans(*ctx->getTab()); + if (utilTrans.clearTable2(pNdb, records) != 0){ return NDBT_FAILED; } return NDBT_OK; @@ -933,6 +1139,43 @@ TESTCASE("SR5", STEP(runSystemRestart5); FINALIZER(runClearTable); } +TESTCASE("SR6", + "Perform system restart with some nodes having FS others wo/\n" + "* 1. Load data\n" + "* 2. Restart all node -nostart\n" + "* 3. Restart some nodes -i -nostart\n" + "* 4. Start all nodes verify records\n"){ + INITIALIZER(runWaitStarted); + INITIALIZER(runClearTable); + STEP(runSystemRestart6); + FINALIZER(runClearTable); +} +TESTCASE("SR7", + "Perform partition win system restart\n" + "* 1. Load data\n" + "* 2. Restart all node -nostart\n" + "* 3. Start all but one node\n" + "* 4. Verify records\n" + "* 5. Start last node\n" + "* 6. Verify records\n"){ + INITIALIZER(runWaitStarted); + INITIALIZER(runClearTable); + STEP(runSystemRestart7); + FINALIZER(runClearTable); +} +TESTCASE("SR8", + "Perform partition win system restart with other nodes delayed\n" + "* 1. Load data\n" + "* 2. Restart all node -nostart\n" + "* 3. Start all but one node\n" + "* 4. Wait for startphase >= 2\n" + "* 5. Start last node\n" + "* 6. Verify records\n"){ + INITIALIZER(runWaitStarted); + INITIALIZER(runClearTable); + STEP(runSystemRestart8); + FINALIZER(runClearTable); +} NDBT_TESTSUITE_END(testSystemRestart); int main(int argc, const char** argv){ diff --git a/ndb/test/ndbapi/testTimeout.cpp b/ndb/test/ndbapi/testTimeout.cpp index de1d2cfc40b..8a7866880b3 100644 --- a/ndb/test/ndbapi/testTimeout.cpp +++ b/ndb/test/ndbapi/testTimeout.cpp @@ -57,8 +57,8 @@ int runTimeoutTrans(NDBT_Context* ctx, NDBT_Step* step){ int stepNo = step->getStepNo(); Uint32 timeoutVal; if (!conf.getProperty(nodeId, - "DB", - "TransactionInactiveTimeout", + NODE_TYPE_DB, + CFG_DB_TRANSACTION_INACTIVE_TIMEOUT, &timeoutVal)){ return NDBT_FAILED; } @@ -103,8 +103,8 @@ int runDontTimeoutTrans(NDBT_Context* ctx, NDBT_Step* step){ int stepNo = step->getStepNo(); Uint32 timeoutVal; if (!conf.getProperty(nodeId, - "DB", - "TransactionInactiveTimeout", + NODE_TYPE_DB, + CFG_DB_TRANSACTION_INACTIVE_TIMEOUT, &timeoutVal)){ return NDBT_FAILED; } @@ -151,8 +151,8 @@ int runBuddyTransNoTimeout(NDBT_Context* ctx, NDBT_Step* step){ int stepNo = step->getStepNo(); Uint32 timeoutVal; if (!conf.getProperty(nodeId, - "DB", - "TransactionInactiveTimeout", + NODE_TYPE_DB, + CFG_DB_TRANSACTION_INACTIVE_TIMEOUT, &timeoutVal)){ return NDBT_FAILED; } diff --git a/ndb/test/src/Makefile_old b/ndb/test/src/Makefile_old index 2b634bcd3cd..2738ce1aba2 100644 --- a/ndb/test/src/Makefile_old +++ b/ndb/test/src/Makefile_old @@ -15,10 +15,12 @@ SOURCES = NDBT_ReturnCodes.cpp \ SOURCES.c = CFLAGS_NdbRestarter.cpp := -I$(call fixpath,$(NDB_TOP)/src/common/mgmcommon) -CFLAGS_NdbBackup.cpp := -I$(call fixpath,$(NDB_TOP)/include/mgmcommon) -CFLAGS_NdbConfig.cpp := -I$(call fixpath,$(NDB_TOP)/include/mgmcommon) +CFLAGS_NdbConfig.cpp := -I$(call fixpath,$(NDB_TOP)/include/mgmcommon) \ + -I$(call fixpath,$(NDB_TOP)/src/mgmapi) CFLAGS_NdbRestarts.cpp := -I$(call fixpath,$(NDB_TOP)/include/kernel) -CFLAGS_NdbBackup.cpp += -I$(call fixpath,$(NDB_TOP)/include/kernel) +CFLAGS_NdbBackup.cpp := -I$(call fixpath,$(NDB_TOP)/include/mgmcommon) \ + -I$(call fixpath,$(NDB_TOP)/src/mgmapi) \ + -I$(call fixpath,$(NDB_TOP)/include/kernel) CFLAGS_NdbGrep.cpp += -I$(call fixpath,$(NDB_TOP)/include/kernel) -I$(call fixpath,$(NDB_TOP)/include/mgmcommon) include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/src/NdbBackup.cpp b/ndb/test/src/NdbBackup.cpp index 6cbb69508f5..13dc67748a5 100644 --- a/ndb/test/src/NdbBackup.cpp +++ b/ndb/test/src/NdbBackup.cpp @@ -19,7 +19,6 @@ #include <NdbOut.hpp> #include <NDBT_Output.hpp> #include <NdbConfig.h> -#include <ConfigRetriever.hpp> #include <ndb_version.h> #include <NDBT.hpp> #include <NdbSleep.h> @@ -32,6 +31,10 @@ << " (Line: " << __LINE__ << ")" << "- " << _xx << endl; \ return NDBT_FAILED; } } +#include <ConfigRetriever.hpp> +#include <mgmapi.h> +#include <mgmapi_config_parameters.h> +#include <mgmapi_configuration.hpp> int NdbBackup::start(unsigned int & _backup_id){ @@ -68,16 +71,12 @@ NdbBackup::getFileSystemPathForNode(int _node_id){ */ ConfigRetriever cr; - - Properties * p = cr.getConfig(host, - port, - _node_id, - NDB_VERSION); + ndb_mgm_configuration * p = cr.getConfig(host, port, 0); if(p == 0){ const char * s = cr.getErrorString(); if(s == 0) s = "No error given!"; - + ndbout << "Could not fetch configuration" << endl; ndbout << s << endl; return NULL; @@ -86,19 +85,19 @@ NdbBackup::getFileSystemPathForNode(int _node_id){ /** * Setup cluster configuration data */ - const Properties * db = 0; - if (!p->get("Node", _node_id, &db)) { + ndb_mgm_configuration_iterator iter(* p, CFG_SECTION_NODE); + if (iter.find(CFG_NODE_ID, _node_id)){ ndbout << "Invalid configuration fetched, DB missing" << endl; return NULL; } - const char * type; - if(!(db->get("Type", &type) && strcmp(type, "DB") == 0)){ + unsigned int type; + if(!iter.get(CFG_TYPE_OF_SECTION, &type) || type != NODE_TYPE_DB){ ndbout <<"Invalid configuration fetched, I'm wrong type of node" << endl; return NULL; } - + const char * path; - if (!db->get("FileSystemPath", &path)){ + if (iter.get(CFG_DB_FILESYSTEM_PATH, &path)){ ndbout << "FileSystemPath not found" << endl; return NULL; } diff --git a/ndb/test/src/NdbConfig.cpp b/ndb/test/src/NdbConfig.cpp index 3a254bc1577..2fb466d1b8f 100644 --- a/ndb/test/src/NdbConfig.cpp +++ b/ndb/test/src/NdbConfig.cpp @@ -17,144 +17,67 @@ #include "NdbConfig.hpp" #include <NdbOut.hpp> #include <NDBT_Output.hpp> +#include <assert.h> #include <NdbConfig.h> #include <ConfigRetriever.hpp> #include <ndb_version.h> - - +#include <mgmapi.h> +#include <mgmapi_config_parameters.h> +#include <mgmapi_configuration.hpp> bool -NdbConfig::getPropsForNode(unsigned int node_id, - const char* type, - const Properties ** props) const { - - /** - * Fetch configuration from management server - */ - ConfigRetriever cr; - - - Properties * p = cr.getConfig(host, - port, - node_id, - NDB_VERSION); +NdbConfig::getHostName(unsigned int node_id, const char ** hostname) { + + ndb_mgm_configuration * p = getConfig(); if(p == 0){ - const char * s = cr.getErrorString(); - if(s == 0) - s = "No error given!"; - - ndbout << "Could not fetch configuration" << endl; - ndbout << s << endl; return false; - } + } /** * Setup cluster configuration data */ - if (!p->get("Node", node_id, props)) { - ndbout << "Invalid configuration fetched no info for nodeId = " - << node_id << endl; + ndb_mgm_configuration_iterator iter(* p, CFG_SECTION_NODE); + if (iter.find(CFG_NODE_ID, node_id)){ + ndbout << "Invalid configuration fetched, DB missing" << endl; return false; } - const char * str; - if(!((*props)->get("Type", &str) && strcmp(str, type) == 0)){ - ndbout <<"Invalid configuration fetched, type != " << type << endl; - return false; - } - return true; -} - -bool -NdbConfig::getProperty(unsigned int node_id, - const char* type, - const char* name, - const char ** value) const { - const Properties * db = 0; - - if(!getPropsForNode(node_id, type, &db)){ + if (iter.get(CFG_NODE_HOST, hostname)){ + ndbout << "Host not found" << endl; return false; } - if (!db->get(name, value)){ - ndbout << name << " not found" << endl; - return false; - } - return true; } bool -NdbConfig::getProperty(unsigned int node_id, - const char* type, - const char* name, - Uint32 * value) const { - const Properties * db = 0; - - if(!getPropsForNode(node_id, type, &db)){ - return false; - } - - if (!db->get(name, value)){ - ndbout << name << " not found" << endl; - return false; - } - - return true; -} - - -bool -NdbConfig::getHostName(unsigned int node_id, - const char ** hostname) const { - /** - * Fetch configuration from management server - */ - ConfigRetriever cr; - - - Properties * p = cr.getConfig(host, - port, - node_id, - NDB_VERSION); +NdbConfig::getProperty(unsigned nodeid, + unsigned type, unsigned key, Uint32 * val){ + ndb_mgm_configuration * p = getConfig(); if(p == 0){ - const char * s = cr.getErrorString(); - if(s == 0) - s = "No error given!"; - - ndbout << "Could not fetch configuration" << endl; - ndbout << s << endl; return false; - } + } /** * Setup cluster configuration data */ - const Properties * node_props; - if (!p->get("Node", node_id, &node_props)) { - ndbout << "Invalid configuration fetched no info for node = " - << node_id << endl; - return false; - } - const char* computer_id_str; - if (!node_props->get("ExecuteOnComputer", &computer_id_str)){ - ndbout << "ExecuteOnComputer not found" << endl; + ndb_mgm_configuration_iterator iter(* p, CFG_SECTION_NODE); + if (iter.find(CFG_NODE_ID, nodeid)){ + ndbout << "Invalid configuration fetched, DB missing" << endl; return false; } - - const Properties * comp_props; - if (!p->get("Computer", atoi(computer_id_str), &comp_props)) { - ndbout << "Invalid configuration fetched no info for computer = " - << node_id << endl; + unsigned _type; + if (iter.get(CFG_TYPE_OF_SECTION, &_type) || type != _type){ + ndbout << "No such node in configuration" << endl; return false; } - if (!comp_props->get("HostName", hostname)){ - ndbout << "HostName not found" << endl; + + if (iter.get(key, val)){ + ndbout << "No such key: " << key << " in configuration" << endl; return false; } - - + return true; } diff --git a/ndb/test/src/NdbRestarter.cpp b/ndb/test/src/NdbRestarter.cpp index cc2fab46cc5..b731cccb259 100644 --- a/ndb/test/src/NdbRestarter.cpp +++ b/ndb/test/src/NdbRestarter.cpp @@ -36,7 +36,8 @@ NdbRestarter::NdbRestarter(const char* _addr): addr(_addr), host(NULL), port(-1), - handle(NULL) + handle(NULL), + m_config(0) { if (addr == NULL){ LocalConfig lcfg; @@ -661,3 +662,13 @@ int NdbRestarter::exitSingleUserMode(){ } return reply.return_code; } + +ndb_mgm_configuration* +NdbRestarter::getConfig(){ + if(m_config) return m_config; + + if (!isConnected()) + return 0; + m_config = ndb_mgm_get_configuration(handle, 0); + return m_config; +} |