1 /*
2 Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is also distributed with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have included with MySQL.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25 #ifndef NODE_STATE_HPP
26 #define NODE_STATE_HPP
27
28 #include <NdbOut.hpp>
29 #include <NodeBitmask.hpp>
30
31 struct NodeStatePOD
32 {
33 enum StartLevel {
34 /**
35 * SL_NOTHING
36 * Nothing is started
37 */
38 SL_NOTHING = 0,
39
40 /**
41 * SL_CMVMI
42 * CMVMI is started
43 * Listening to management server
44 * Qmgr knows nothing...
45 */
46 SL_CMVMI = 1,
47
48 /**
49 * SL_STARTING
50 * All blocks are starting
51 * Initial or restart
52 * During this phase is <b>startPhase</b> valid
53 */
54 SL_STARTING = 2,
55
56 /**
57 * The database is started open for connections
58 */
59 SL_STARTED = 3,
60
61 SL_SINGLEUSER = 4,
62
63 /**
64 * SL_STOPPING_1 - Inform API
65 * API is informed not to start transactions on node
66 * The database is about to close
67 *
68 * New TcSeize(s) are refused (TcSeizeRef)
69 */
70 SL_STOPPING_1 = 5,
71
72 /**
73 * SL_STOPPING_2 - Close TC
74 * New transactions(TC) are refused
75 */
76 SL_STOPPING_2 = 6,
77
78
79
80
81 /**
82 * SL_STOPPING_3 - Wait for reads in LQH
83 * No transactions are running in TC
84 * New scans(s) and read(s) are refused in LQH
85 * NS: The node is not Primary for any fragment
86 * NS: No node is allow to start
87 */
88 SL_STOPPING_3 = 7,
89
90 /**
91 * SL_STOPPING_4 - Close LQH
92 * Node is out of DIGETNODES
93 * Insert/Update/Delete can still be running in LQH
94 * GCP is refused
95 * Node is not startable w.o Node Recovery
96 */
97 SL_STOPPING_4 = 8
98 };
99
100 enum StartType {
101 ST_INITIAL_START = 0,
102 ST_SYSTEM_RESTART = 1,
103 ST_NODE_RESTART = 2,
104 ST_INITIAL_NODE_RESTART = 3,
105 ST_ILLEGAL_TYPE = 4
106 };
107
108 /**
109 * Length in 32-bit words
110 */
111 STATIC_CONST( DataLength = 8 + NodeBitmask::Size );
112
113 /**
114 * Constructor(s)
115 */
116 void init();
117
118 /**
119 * Current start level
120 */
121 Uint32 startLevel;
122
123 /**
124 * Node group
125 */
126 Uint32 nodeGroup; // valid when startLevel == SL_STARTING
127
128 /**
129 * Dynamic id
130 */
131 union {
132 Uint32 dynamicId; // valid when startLevel == SL_STARTING to API
133 Uint32 masterNodeId; // When from cntr
134 };
135
136 /**
137 *
138 */
139 union {
140 struct {
141 Uint32 startPhase; // valid when startLevel == SL_STARTING
142 Uint32 restartType; // valid when startLevel == SL_STARTING
143 } starting;
144 struct {
145 Uint32 systemShutdown; // valid when startLevel == SL_STOPPING_{X}
146 Uint32 timeout;
147 Uint32 alarmTime;
148 } stopping;
149
150
151 };
152 Uint32 singleUserMode;
153 Uint32 singleUserApi; //the single user node
154
155 BitmaskPOD<NodeBitmask::Size> m_connected_nodes;
156
157 void setDynamicId(Uint32 dynamic);
158 void setNodeGroup(Uint32 group);
159 void setSingleUser(Uint32 s);
160 void setSingleUserApi(Uint32 n);
161
162
163 /**
164 * Is a node restart in progress (ordinary or initial)
165 */
166 bool getNodeRestartInProgress() const;
167
168 /**
169 * Is a system restart ongoing
170 */
171 bool getSystemRestartInProgress() const;
172
173 /**
174 * Are we started
175 */
getStartedNodeStatePOD176 bool getStarted() const {
177 return startLevel == SL_STARTED || startLevel == SL_SINGLEUSER;
178 }
179
180 /**
181 * Is in single user mode?
182 */
183 bool getSingleUserMode() const;
184
185 /**
186 * Is in single user mode
187 */
188 Uint32 getSingleUserApi() const;
189 };
190
191 class NodeState : public NodeStatePOD
192 {
193 public:
194 NodeState();
195 NodeState(StartLevel);
196 NodeState(StartLevel, bool systemShutdown);
197 NodeState(StartLevel, Uint32 startPhase, StartType);
198
199 NodeState& operator=(const NodeStatePOD&);
200 };
201
202 inline
NodeState()203 NodeState::NodeState(){
204 init();
205 }
206
207 inline
208 void
init()209 NodeStatePOD::init(){
210 startLevel = SL_CMVMI;
211 nodeGroup = 0xFFFFFFFF;
212 dynamicId = 0xFFFFFFFF;
213 singleUserMode = 0;
214 singleUserApi = 0xFFFFFFFF;
215 m_connected_nodes.clear();
216 }
217
218 inline
NodeState(StartLevel sl)219 NodeState::NodeState(StartLevel sl){
220 init();
221 startLevel = sl;
222 singleUserMode = 0;
223 singleUserApi = 0xFFFFFFFF;
224 }
225
226 inline
NodeState(StartLevel sl,Uint32 sp,StartType typeOfStart)227 NodeState::NodeState(StartLevel sl, Uint32 sp, StartType typeOfStart){
228 init();
229 startLevel = sl;
230 starting.startPhase = sp;
231 starting.restartType = typeOfStart;
232 singleUserMode = 0;
233 singleUserApi = 0xFFFFFFFF;
234 }
235
236 inline
NodeState(StartLevel sl,bool sys)237 NodeState::NodeState(StartLevel sl, bool sys){
238 init();
239 startLevel = sl;
240 stopping.systemShutdown = sys;
241 singleUserMode = 0;
242 singleUserApi = 0xFFFFFFFF;
243 }
244
245 inline
setDynamicId(Uint32 dynamic)246 void NodeStatePOD::setDynamicId(Uint32 dynamic){
247 dynamicId = dynamic;
248 }
249
250 inline
setNodeGroup(Uint32 group)251 void NodeStatePOD::setNodeGroup(Uint32 group){
252 nodeGroup = group;
253 }
254
255 inline
setSingleUser(Uint32 s)256 void NodeStatePOD::setSingleUser(Uint32 s) {
257 singleUserMode = s;
258 }
259
260 inline
setSingleUserApi(Uint32 n)261 void NodeStatePOD::setSingleUserApi(Uint32 n) {
262 singleUserApi = n;
263 }
264 inline
getNodeRestartInProgress() const265 bool NodeStatePOD::getNodeRestartInProgress() const {
266 return startLevel == SL_STARTING &&
267 (starting.restartType == ST_NODE_RESTART ||
268 starting.restartType == ST_INITIAL_NODE_RESTART);
269 }
270
271 inline
getSingleUserMode() const272 bool NodeStatePOD::getSingleUserMode() const {
273 return singleUserMode;
274 }
275
276 inline
getSingleUserApi() const277 Uint32 NodeStatePOD::getSingleUserApi() const {
278 return singleUserApi;
279 }
280
281 inline
getSystemRestartInProgress() const282 bool NodeStatePOD::getSystemRestartInProgress() const {
283 return startLevel == SL_STARTING && starting.restartType == ST_SYSTEM_RESTART;
284 }
285
286 inline
287 NdbOut &
operator <<(NdbOut & ndbout,const NodeStatePOD & state)288 operator<<(NdbOut& ndbout, const NodeStatePOD & state){
289 ndbout << "[NodeState: startLevel: ";
290 switch(state.startLevel){
291 case NodeState::SL_NOTHING:
292 ndbout << "<NOTHING> ]";
293 break;
294 case NodeState::SL_CMVMI:
295 ndbout << "<CMVMI> ]";
296 break;
297 case NodeState::SL_STARTING:
298 ndbout << "<STARTING type: ";
299 switch(state.starting.restartType){
300 case NodeState::ST_INITIAL_START:
301 ndbout << " INITIAL START";
302 break;
303 case NodeState::ST_SYSTEM_RESTART:
304 ndbout << " SYSTEM RESTART ";
305 break;
306 case NodeState::ST_NODE_RESTART:
307 ndbout << " NODE RESTART ";
308 break;
309 case NodeState::ST_INITIAL_NODE_RESTART:
310 ndbout << " INITIAL NODE RESTART ";
311 break;
312 case NodeState::ST_ILLEGAL_TYPE:
313 default:
314 ndbout << " UNKNOWN " << state.starting.restartType;
315 }
316 ndbout << " phase: " << state.starting.startPhase << "> ]";
317 break;
318 case NodeState::SL_STARTED:
319 ndbout << "<STARTED> ]";
320 break;
321 case NodeState::SL_STOPPING_1:
322 ndbout << "<STOPPING 1 sys: " << state.stopping.systemShutdown << "> ]";
323 break;
324 case NodeState::SL_STOPPING_2:
325 ndbout << "<STOPPING 2 sys: " << state.stopping.systemShutdown << "> ]";
326 break;
327 case NodeState::SL_STOPPING_3:
328 ndbout << "<STOPPING 3 sys: " << state.stopping.systemShutdown << "> ]";
329 break;
330 case NodeState::SL_STOPPING_4:
331 ndbout << "<STOPPING 4 sys: " << state.stopping.systemShutdown << "> ]";
332 break;
333 default:
334 ndbout << "<UNKNOWN " << state.startLevel << "> ]";
335 }
336 return ndbout;
337 }
338
339 inline
340 NodeState&
operator =(const NodeStatePOD & ns)341 NodeState::operator=(const NodeStatePOD& ns)
342 {
343 startLevel = ns.startLevel;
344 nodeGroup = ns.nodeGroup;
345 dynamicId = ns.dynamicId;
346 // masterNodeId is union with dynamicId
347 starting.startPhase = ns.starting.startPhase;
348 starting.restartType = ns.starting.restartType;
349 // stopping.systemShutdown is union with starting.startPhase
350 // stopping.timeout is union with starting.restartType
351 stopping.alarmTime = ns.stopping.alarmTime;
352 singleUserMode = ns.singleUserMode;
353 singleUserApi = ns.singleUserApi;
354 m_connected_nodes.assign(ns.m_connected_nodes);
355 return * this;
356 }
357 #endif
358