1 /*
2    Copyright (c) 2003, 2021, Oracle and/or its affiliates.
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 #define JAM_FILE_ID 1
32 
33 
34 struct NodeStatePOD
35 {
36   enum StartLevel {
37     /**
38      * SL_NOTHING
39      *   Nothing is started
40      */
41     SL_NOTHING    = 0,
42 
43     /**
44      * SL_CMVMI
45      *   CMVMI is started
46      *   Listening to management server
47      *   Qmgr knows nothing...
48      */
49     SL_CMVMI = 1,
50 
51     /**
52      * SL_STARTING
53      *   All blocks are starting
54      *   Initial or restart
55      *   During this phase is <b>startPhase</b> valid
56      */
57     SL_STARTING = 2,
58 
59     /**
60      * The database is started open for connections
61      */
62     SL_STARTED = 3,
63 
64     SL_SINGLEUSER = 4,
65 
66     /**
67      * SL_STOPPING_1 - Inform API
68      *   API is informed not to start transactions on node
69      *	 The database is about to close
70      *
71      *   New TcSeize(s) are refused (TcSeizeRef)
72      */
73     SL_STOPPING_1 = 5,
74 
75     /**
76      * SL_STOPPING_2 - Close TC
77      *   New transactions(TC) are refused
78      */
79     SL_STOPPING_2 = 6,
80 
81 
82 
83 
84     /**
85      * SL_STOPPING_3 - Wait for reads in LQH
86      *   No transactions are running in TC
87      *   New scans(s) and read(s) are refused in LQH
88      *   NS: The node is not Primary for any fragment
89      *   NS: No node is allow to start
90      */
91     SL_STOPPING_3 = 7,
92 
93     /**
94      * SL_STOPPING_4 - Close LQH
95      *   Node is out of DIGETNODES
96      *   Insert/Update/Delete can still be running in LQH
97      *   GCP is refused
98      *   Node is not startable w.o Node Recovery
99      */
100     SL_STOPPING_4 = 8
101   };
102 
103   enum StartType {
104     ST_INITIAL_START = 0,
105     ST_SYSTEM_RESTART = 1,
106     ST_NODE_RESTART = 2,
107     ST_INITIAL_NODE_RESTART = 3,
108     ST_ILLEGAL_TYPE = 4
109   };
110 
111   /**
112    * Length in 32-bit words
113    */
114   STATIC_CONST( DataLength = 8 + NodeBitmask::Size );
115 
116   /**
117    * Constructor(s)
118    */
119   void init();
120 
121   /**
122    * Current start level
123    */
124   Uint32 startLevel;
125 
126   /**
127    * Node group
128    */
129   Uint32 nodeGroup;  // valid when startLevel == SL_STARTING
130 
131   /**
132    * Dynamic id
133    */
134   union {
135     Uint32 dynamicId;    // valid when startLevel == SL_STARTING to API
136     Uint32 masterNodeId; // When from cntr
137   };
138 
139   /**
140    *
141    */
142   union {
143     struct {
144       Uint32 startPhase;     // valid when startLevel == SL_STARTING
145       Uint32 restartType;    // valid when startLevel == SL_STARTING
146     } starting;
147     struct {
148       Uint32 systemShutdown; // valid when startLevel == SL_STOPPING_{X}
149       Uint32 timeout;
150       Uint32 alarmTime;
151     } stopping;
152 
153 
154   };
155   Uint32 singleUserMode;
156   Uint32 singleUserApi;          //the single user node
157 
158   BitmaskPOD<NodeBitmask::Size> m_connected_nodes;
159 
160   void setDynamicId(Uint32 dynamic);
161   void setNodeGroup(Uint32 group);
162   void setSingleUser(Uint32 s);
163   void setSingleUserApi(Uint32 n);
164 
165 
166   /**
167    * Is a node restart in progress (ordinary or initial)
168    */
169   bool getNodeRestartInProgress() const;
170 
171   /**
172    * Is a system restart ongoing
173    */
174   bool getSystemRestartInProgress() const;
175 
176   /**
177    * Are we started
178    */
getStartedNodeStatePOD179   bool getStarted() const {
180     return startLevel == SL_STARTED || startLevel == SL_SINGLEUSER;
181   }
182 
183   /**
184    * Is in single user mode?
185    */
186   bool getSingleUserMode() const;
187 
188   /**
189    * Is in single user mode
190    */
191   Uint32 getSingleUserApi() const;
192 };
193 
194 class NodeState : public NodeStatePOD
195 {
196 public:
197   NodeState();
198   NodeState(StartLevel);
199   NodeState(StartLevel, bool systemShutdown);
200   NodeState(StartLevel, Uint32 startPhase, StartType);
201 
202   NodeState& operator=(const NodeStatePOD&);
203 };
204 
205 inline
NodeState()206 NodeState::NodeState(){
207   init();
208 }
209 
210 inline
211 void
init()212 NodeStatePOD::init(){
213   startLevel = SL_CMVMI;
214   nodeGroup = 0xFFFFFFFF;
215   dynamicId = 0xFFFFFFFF;
216   singleUserMode = 0;
217   singleUserApi = 0xFFFFFFFF;
218   m_connected_nodes.clear();
219 }
220 
221 inline
NodeState(StartLevel sl)222 NodeState::NodeState(StartLevel sl){
223   init();
224   startLevel = sl;
225   singleUserMode = 0;
226   singleUserApi = 0xFFFFFFFF;
227 }
228 
229 inline
NodeState(StartLevel sl,Uint32 sp,StartType typeOfStart)230 NodeState::NodeState(StartLevel sl, Uint32 sp, StartType typeOfStart){
231   init();
232   startLevel = sl;
233   starting.startPhase = sp;
234   starting.restartType = typeOfStart;
235   singleUserMode = 0;
236   singleUserApi = 0xFFFFFFFF;
237 }
238 
239 inline
NodeState(StartLevel sl,bool sys)240 NodeState::NodeState(StartLevel sl, bool sys){
241   init();
242   startLevel = sl;
243   stopping.systemShutdown = sys;
244   singleUserMode = 0;
245   singleUserApi = 0xFFFFFFFF;
246 }
247 
248 inline
setDynamicId(Uint32 dynamic)249 void NodeStatePOD::setDynamicId(Uint32 dynamic){
250   dynamicId = dynamic;
251 }
252 
253 inline
setNodeGroup(Uint32 group)254 void NodeStatePOD::setNodeGroup(Uint32 group){
255   nodeGroup = group;
256 }
257 
258 inline
setSingleUser(Uint32 s)259 void NodeStatePOD::setSingleUser(Uint32 s) {
260   singleUserMode = s;
261 }
262 
263 inline
setSingleUserApi(Uint32 n)264 void NodeStatePOD::setSingleUserApi(Uint32 n) {
265   singleUserApi = n;
266 }
267 inline
getNodeRestartInProgress() const268 bool NodeStatePOD::getNodeRestartInProgress() const {
269   return startLevel == SL_STARTING &&
270     (starting.restartType == ST_NODE_RESTART ||
271      starting.restartType == ST_INITIAL_NODE_RESTART);
272 }
273 
274 inline
getSingleUserMode() const275 bool NodeStatePOD::getSingleUserMode() const {
276   return singleUserMode;
277 }
278 
279 inline
getSingleUserApi() const280 Uint32 NodeStatePOD::getSingleUserApi() const {
281   return singleUserApi;
282 }
283 
284 inline
getSystemRestartInProgress() const285 bool NodeStatePOD::getSystemRestartInProgress() const {
286   return startLevel == SL_STARTING && starting.restartType == ST_SYSTEM_RESTART;
287 }
288 
289 inline
290 NdbOut &
operator <<(NdbOut & ndbout,const NodeStatePOD & state)291 operator<<(NdbOut& ndbout, const NodeStatePOD & state){
292   ndbout << "[NodeState: startLevel: ";
293   switch(state.startLevel){
294   case NodeState::SL_NOTHING:
295     ndbout << "<NOTHING> ]";
296     break;
297   case NodeState::SL_CMVMI:
298     ndbout << "<CMVMI> ]";
299     break;
300   case NodeState::SL_STARTING:
301     ndbout << "<STARTING type: ";
302     switch(state.starting.restartType){
303     case NodeState::ST_INITIAL_START:
304       ndbout << " INITIAL START";
305       break;
306     case NodeState::ST_SYSTEM_RESTART:
307       ndbout << " SYSTEM RESTART ";
308       break;
309     case NodeState::ST_NODE_RESTART:
310       ndbout << " NODE RESTART ";
311       break;
312     case NodeState::ST_INITIAL_NODE_RESTART:
313       ndbout << " INITIAL NODE RESTART ";
314       break;
315     case NodeState::ST_ILLEGAL_TYPE:
316     default:
317       ndbout << " UNKNOWN " << state.starting.restartType;
318     }
319     ndbout << " phase: " << state.starting.startPhase << "> ]";
320     break;
321   case NodeState::SL_STARTED:
322     ndbout << "<STARTED> ]";
323     break;
324   case NodeState::SL_STOPPING_1:
325     ndbout << "<STOPPING 1 sys: " << state.stopping.systemShutdown << "> ]";
326     break;
327   case NodeState::SL_STOPPING_2:
328     ndbout << "<STOPPING 2 sys: " << state.stopping.systemShutdown << "> ]";
329     break;
330   case NodeState::SL_STOPPING_3:
331     ndbout << "<STOPPING 3 sys: " << state.stopping.systemShutdown << "> ]";
332     break;
333   case NodeState::SL_STOPPING_4:
334     ndbout << "<STOPPING 4 sys: " << state.stopping.systemShutdown << "> ]";
335     break;
336   default:
337     ndbout << "<UNKNOWN " << state.startLevel << "> ]";
338   }
339   return ndbout;
340 }
341 
342 inline
343 NodeState&
operator =(const NodeStatePOD & ns)344 NodeState::operator=(const NodeStatePOD& ns)
345 {
346   startLevel = ns.startLevel;
347   nodeGroup  = ns.nodeGroup;
348   dynamicId  = ns.dynamicId;
349   // masterNodeId is union with dynamicId
350   starting.startPhase = ns.starting.startPhase;
351   starting.restartType = ns.starting.restartType;
352   // stopping.systemShutdown is union with starting.startPhase
353   // stopping.timeout is union with starting.restartType
354   stopping.alarmTime = ns.stopping.alarmTime;
355   singleUserMode = ns.singleUserMode;
356   singleUserApi  = ns.singleUserApi;
357   m_connected_nodes.assign(ns.m_connected_nodes);
358   return * this;
359 }
360 
361 #undef JAM_FILE_ID
362 
363 #endif
364