/* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef NODE_STATE_HPP #define NODE_STATE_HPP #include #include #define JAM_FILE_ID 1 struct NodeStatePOD { enum StartLevel { /** * SL_NOTHING * Nothing is started */ SL_NOTHING = 0, /** * SL_CMVMI * CMVMI is started * Listening to management server * Qmgr knows nothing... */ SL_CMVMI = 1, /** * SL_STARTING * All blocks are starting * Initial or restart * During this phase is startPhase valid */ SL_STARTING = 2, /** * The database is started open for connections */ SL_STARTED = 3, SL_SINGLEUSER = 4, /** * SL_STOPPING_1 - Inform API * API is informed not to start transactions on node * The database is about to close * * New TcSeize(s) are refused (TcSeizeRef) */ SL_STOPPING_1 = 5, /** * SL_STOPPING_2 - Close TC * New transactions(TC) are refused */ SL_STOPPING_2 = 6, /** * SL_STOPPING_3 - Wait for reads in LQH * No transactions are running in TC * New scans(s) and read(s) are refused in LQH * NS: The node is not Primary for any fragment * NS: No node is allow to start */ SL_STOPPING_3 = 7, /** * SL_STOPPING_4 - Close LQH * Node is out of DIGETNODES * Insert/Update/Delete can still be running in LQH * GCP is refused * Node is not startable w.o Node Recovery */ SL_STOPPING_4 = 8 }; enum StartType { ST_INITIAL_START = 0, ST_SYSTEM_RESTART = 1, ST_NODE_RESTART = 2, ST_INITIAL_NODE_RESTART = 3, ST_ILLEGAL_TYPE = 4 }; /** * Length in 32-bit words */ STATIC_CONST( DataLength = 8 + NodeBitmask::Size ); /** * Constructor(s) */ void init(); /** * Current start level */ Uint32 startLevel; /** * Node group */ Uint32 nodeGroup; // valid when startLevel == SL_STARTING /** * Dynamic id */ union { Uint32 dynamicId; // valid when startLevel == SL_STARTING to API Uint32 masterNodeId; // When from cntr }; /** * */ union { struct { Uint32 startPhase; // valid when startLevel == SL_STARTING Uint32 restartType; // valid when startLevel == SL_STARTING } starting; struct { Uint32 systemShutdown; // valid when startLevel == SL_STOPPING_{X} Uint32 timeout; Uint32 alarmTime; } stopping; }; Uint32 singleUserMode; Uint32 singleUserApi; //the single user node BitmaskPOD m_connected_nodes; void setDynamicId(Uint32 dynamic); void setNodeGroup(Uint32 group); void setSingleUser(Uint32 s); void setSingleUserApi(Uint32 n); /** * Is a node restart in progress (ordinary or initial) */ bool getNodeRestartInProgress() const; /** * Is a system restart ongoing */ bool getSystemRestartInProgress() const; /** * Are we started */ bool getStarted() const { return startLevel == SL_STARTED || startLevel == SL_SINGLEUSER; } /** * Is in single user mode? */ bool getSingleUserMode() const; /** * Is in single user mode */ Uint32 getSingleUserApi() const; }; class NodeState : public NodeStatePOD { public: NodeState(); NodeState(StartLevel); NodeState(StartLevel, bool systemShutdown); NodeState(StartLevel, Uint32 startPhase, StartType); NodeState& operator=(const NodeStatePOD&); }; inline NodeState::NodeState(){ init(); } inline void NodeStatePOD::init(){ startLevel = SL_CMVMI; nodeGroup = 0xFFFFFFFF; dynamicId = 0xFFFFFFFF; singleUserMode = 0; singleUserApi = 0xFFFFFFFF; m_connected_nodes.clear(); } inline NodeState::NodeState(StartLevel sl){ init(); startLevel = sl; singleUserMode = 0; singleUserApi = 0xFFFFFFFF; } inline NodeState::NodeState(StartLevel sl, Uint32 sp, StartType typeOfStart){ init(); startLevel = sl; starting.startPhase = sp; starting.restartType = typeOfStart; singleUserMode = 0; singleUserApi = 0xFFFFFFFF; } inline NodeState::NodeState(StartLevel sl, bool sys){ init(); startLevel = sl; stopping.systemShutdown = sys; singleUserMode = 0; singleUserApi = 0xFFFFFFFF; } inline void NodeStatePOD::setDynamicId(Uint32 dynamic){ dynamicId = dynamic; } inline void NodeStatePOD::setNodeGroup(Uint32 group){ nodeGroup = group; } inline void NodeStatePOD::setSingleUser(Uint32 s) { singleUserMode = s; } inline void NodeStatePOD::setSingleUserApi(Uint32 n) { singleUserApi = n; } inline bool NodeStatePOD::getNodeRestartInProgress() const { return startLevel == SL_STARTING && (starting.restartType == ST_NODE_RESTART || starting.restartType == ST_INITIAL_NODE_RESTART); } inline bool NodeStatePOD::getSingleUserMode() const { return singleUserMode; } inline Uint32 NodeStatePOD::getSingleUserApi() const { return singleUserApi; } inline bool NodeStatePOD::getSystemRestartInProgress() const { return startLevel == SL_STARTING && starting.restartType == ST_SYSTEM_RESTART; } inline NdbOut & operator<<(NdbOut& ndbout, const NodeStatePOD & state){ ndbout << "[NodeState: startLevel: "; switch(state.startLevel){ case NodeState::SL_NOTHING: ndbout << " ]"; break; case NodeState::SL_CMVMI: ndbout << " ]"; break; case NodeState::SL_STARTING: ndbout << " ]"; break; case NodeState::SL_STARTED: ndbout << " ]"; break; case NodeState::SL_STOPPING_1: ndbout << " ]"; break; case NodeState::SL_STOPPING_2: ndbout << " ]"; break; case NodeState::SL_STOPPING_3: ndbout << " ]"; break; case NodeState::SL_STOPPING_4: ndbout << " ]"; break; default: ndbout << " ]"; } return ndbout; } inline NodeState& NodeState::operator=(const NodeStatePOD& ns) { startLevel = ns.startLevel; nodeGroup = ns.nodeGroup; dynamicId = ns.dynamicId; // masterNodeId is union with dynamicId starting.startPhase = ns.starting.startPhase; starting.restartType = ns.starting.restartType; // stopping.systemShutdown is union with starting.startPhase // stopping.timeout is union with starting.restartType stopping.alarmTime = ns.stopping.alarmTime; singleUserMode = ns.singleUserMode; singleUserApi = ns.singleUserApi; m_connected_nodes.assign(ns.m_connected_nodes); return * this; } #undef JAM_FILE_ID #endif