1 /* Copyright (c) 2003-2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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
);