1
/* Copyright (C) 2003 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
20
#include <ndb_limits.h>
21
#include <NdbThread.h>
23
#include <NdbCondition.h>
24
#include <signaldata/ArbitSignalData.hpp>
25
#include <signaldata/NodeStateSignalData.hpp>
26
#include <NodeInfo.hpp>
27
#include <NodeState.hpp>
29
extern "C" void* runClusterMgr_C(void * me);
36
friend void* runClusterMgr_C(void * me);
37
friend void execute(void *, struct SignalHeader * const,
38
Uint8, Uint32 * const, LinearSectionPtr ptr[3]);
40
ClusterMgr(class TransporterFacade &);
42
void init(struct ndb_mgm_configuration_iterator & config);
44
void reportConnected(NodeId nodeId);
45
void reportDisconnected(NodeId nodeId);
47
bool checkUpgradeCompatability(Uint32 nodeVersion);
53
void set_max_api_reg_req_interval(unsigned int millisec) { m_max_api_reg_req_interval = millisec; }
59
class TransporterFacade & theFacade;
63
CS_waiting_for_clean_cache = 0,
64
CS_waiting_for_first_connect,
70
bool connected; // Transporter connected
71
bool compatible; // Version is compatible
72
bool nfCompleteRep; // NF Complete Rep has arrived
73
bool m_alive; // Node is alive
74
bool m_api_reg_conf;// API_REGCONF has arrived
82
Uint32 hbFrequency; // Heartbeat frequence
83
Uint32 hbCounter; // # milliseconds passed since last hb sent
86
const Node & getNodeInfo(NodeId) const;
87
Uint32 getNoOfConnectedNodes() const;
88
bool isClusterAlive() const;
89
void hb_received(NodeId);
91
Uint32 m_connect_count;
93
Uint32 m_max_api_reg_req_interval;
94
Uint32 noOfAliveNodes;
95
Uint32 noOfConnectedNodes;
96
Node theNodes[MAX_NODES];
97
NdbThread* theClusterMgrThread;
99
NodeBitmask waitForHBFromNodes; // used in forcing HBs
100
NdbCondition* waitForHBCond;
103
enum Cluster_state m_cluster_state;
105
* Used for controlling start/stop of the thread
107
NdbMutex* clusterMgrThreadMutex;
109
void showState(NodeId nodeId);
110
void reportNodeFailed(NodeId nodeId, bool disconnect = false);
115
void execAPI_REGREQ (const Uint32 * theData);
116
void execAPI_REGCONF (const Uint32 * theData);
117
void execAPI_REGREF (const Uint32 * theData);
118
void execNODE_FAILREP (const Uint32 * theData);
119
void execNF_COMPLETEREP(const Uint32 * theData);
121
inline void set_node_alive(Node& node, bool alive){
122
if(node.m_alive && !alive)
124
assert(noOfAliveNodes);
127
else if(!node.m_alive && alive)
131
node.m_alive = alive;
136
const ClusterMgr::Node &
137
ClusterMgr::getNodeInfo(NodeId nodeId) const {
138
return theNodes[nodeId];
143
ClusterMgr::getNoOfConnectedNodes() const {
144
return noOfConnectedNodes;
149
ClusterMgr::isClusterAlive() const {
150
return noOfAliveNodes != 0;
154
ClusterMgr::hb_received(NodeId nodeId) {
155
theNodes[nodeId].m_info.m_heartbeat_cnt= 0;
158
/*****************************************************************************/
162
* Arbitration manager. Runs in separate thread.
163
* Started only by a request from the kernel.
166
extern "C" void* runArbitMgr_C(void* me);
171
ArbitMgr(class TransporterFacade &);
174
inline void setRank(unsigned n) { theRank = n; }
175
inline void setDelay(unsigned n) { theDelay = n; }
177
void doStart(const Uint32* theData);
178
void doChoose(const Uint32* theData);
179
void doStop(const Uint32* theData);
181
friend void* runArbitMgr_C(void* me);
184
class TransporterFacade & theFacade;
189
NdbThread* theThread;
190
NdbMutex* theThreadMutex; // not really needed
193
GlobalSignalNumber gsn;
194
ArbitSignalData data;
199
inline void init(GlobalSignalNumber aGsn, const Uint32* aData) {
202
memcpy(&data, aData, sizeof(data));
204
memset(&data, 0, sizeof(data));
207
inline void setTimestamp() {
208
timestamp = NdbTick_CurrentMillisecond();
211
inline NDB_TICKS getTimediff() {
212
NDB_TICKS now = NdbTick_CurrentMillisecond();
213
return now < timestamp ? 0 : now - timestamp;
217
NdbMutex* theInputMutex;
218
NdbCondition* theInputCond;
220
bool theInputFull; // the predicate
221
ArbitSignal theInputBuffer; // shared buffer
223
void sendSignalToThread(ArbitSignal& aSignal);
225
enum State { // thread states
227
StateStarted, // thread started
228
StateChoose1, // received one valid REQ
229
StateChoose2, // received two valid REQs
230
StateFinished // finished one way or other
234
enum Stop { // stop code in ArbitSignal.data.code
235
StopExit = 1, // at API exit
236
StopRequest = 2, // request from kernel
237
StopRestart = 3 // stop before restart
240
void threadStart(ArbitSignal& aSignal); // handle thread events
241
void threadChoose(ArbitSignal& aSignal);
242
void threadTimeout();
243
void threadStop(ArbitSignal& aSignal);
245
ArbitSignal theStartReq;
246
ArbitSignal theChooseReq1;
247
ArbitSignal theChooseReq2;
248
ArbitSignal theStopOrd;
250
void sendStartConf(ArbitSignal& aSignal, Uint32);
251
void sendChooseRef(ArbitSignal& aSignal, Uint32);
252
void sendChooseConf(ArbitSignal& aSignal, Uint32);
253
void sendStopRep(ArbitSignal& aSignal, Uint32);
255
void sendSignalToQmgr(ArbitSignal& aSignal);