/* Copyright (C) 2003 MySQL AB 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; either version 2 of the License, or (at your option) any later version. 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef SYSFILE_HPP #define SYSFILE_HPP #include <ndb_types.h> #include <ndb_limits.h> #include <NodeBitmask.hpp> /** * No bits in Sysfile to represent nodeid */ #define NODEID_BITS 8 /** * Constant representing that node do not belong to * any node group */ #define NO_NODE_GROUP_ID ((1 << NODEID_BITS) - 1) /** * Dummy macro to make emacs indent better */ #define _F(x) x /** * No of 32 bits word in sysfile * * 5 + * MAX_NDB_NODES + // lastCompletedGCI * NODE_ARRAY_SIZE(MAX_NDB_NODES, 4) + // nodeStatus * NODE_ARRAY_SIZE(MAX_NDB_NODES, NODEID_BITS) + // nodeGroups * NODE_ARRAY_SIZE(MAX_NDB_NODES, NODEID_BITS) + // takeOver * NodeBitmask::NDB_NODE_BITMASK_SIZE // Lcp Active */ #define _SYSFILE_SIZE32 (5 + \ MAX_NDB_NODES + \ NODE_ARRAY_SIZE(MAX_NDB_NODES, 4) + \ NODE_ARRAY_SIZE(MAX_NDB_NODES, NODEID_BITS) + \ NODE_ARRAY_SIZE(MAX_NDB_NODES, NODEID_BITS) + \ _NDB_NODE_BITMASK_SIZE) /** * This struct defines the format of P<X>.sysfile */ struct Sysfile { public: /** * No of 32 bits words in the sysfile */ STATIC_CONST( SYSFILE_SIZE32 = _SYSFILE_SIZE32 ); Uint32 systemRestartBits; static bool getInitialStartOngoing(const Uint32 & systemRestartBits); static void setInitialStartOngoing(Uint32 & systemRestartBits); static void clearInitialStartOngoing(Uint32 & systemRestartBits); static bool getRestartOngoing(const Uint32 & systemRestartBits); static void setRestartOngoing(Uint32 & systemRestartBits); static void clearRestartOngoing(Uint32 & systemRestartBits); static bool getLCPOngoing(const Uint32 & systemRestartBits); static void setLCPOngoing(Uint32 & systemRestartBits); static void clearLCPOngoing(Uint32 & systemRestartBits); Uint32 keepGCI; Uint32 oldestRestorableGCI; Uint32 newestRestorableGCI; Uint32 latestLCP_ID; /** * Last completed GCI for each node */ Uint32 lastCompletedGCI[MAX_NDB_NODES]; /** * Active status bits * * It takes 4 bits to represent it */ enum ActiveStatus { NS_Active = 0 ,NS_ActiveMissed_1 = 1 ,NS_ActiveMissed_2 = 2 ,NS_ActiveMissed_3 = 3 ,NS_HotSpare = 4 ,NS_NotActive_NotTakenOver = 5 ,NS_TakeOver = 6 ,NS_NotActive_TakenOver = 7 ,NS_NotDefined = 8 ,NS_Standby = 9 }; STATIC_CONST( NODE_STATUS_SIZE = NODE_ARRAY_SIZE(MAX_NDB_NODES, 4) ); Uint32 nodeStatus[NODE_STATUS_SIZE]; static Uint32 getNodeStatus(NodeId, const Uint32 nodeStatus[]); static void setNodeStatus(NodeId, Uint32 nodeStatus[], Uint32 status); /** * The node group of each node * Sizeof(NodeGroup) = 8 Bit */ STATIC_CONST( NODE_GROUPS_SIZE = NODE_ARRAY_SIZE(MAX_NDB_NODES, NODEID_BITS) ); Uint32 nodeGroups[NODE_GROUPS_SIZE]; static Uint16 getNodeGroup(NodeId, const Uint32 nodeGroups[]); static void setNodeGroup(NodeId, Uint32 nodeGroups[], Uint16 group); /** * Any node can take over for any node */ STATIC_CONST( TAKE_OVER_SIZE = NODE_ARRAY_SIZE(MAX_NDB_NODES, NODEID_BITS) ); Uint32 takeOver[TAKE_OVER_SIZE]; static NodeId getTakeOverNode(NodeId, const Uint32 takeOver[]); static void setTakeOverNode(NodeId, Uint32 takeOver[], NodeId toNode); /** * Is a node running a LCP */ Uint32 lcpActive[NdbNodeBitmask::Size]; }; #if (MAX_NDB_NODES > (1<<NODEID_BITS)) #error "Sysfile node id is too small" #endif /** * Restart Info * * i = Initial start completed * r = Crash during system restart * l = Crash during local checkpoint * 1111111111222222222233 * 01234567890123456789012345678901 * irl */ inline bool Sysfile::getInitialStartOngoing(const Uint32 & systemRestartBits){ return systemRestartBits & 1; } inline void Sysfile::setInitialStartOngoing(Uint32 & systemRestartBits){ systemRestartBits |= 1; } inline void Sysfile::clearInitialStartOngoing(Uint32 & systemRestartBits){ systemRestartBits &= ~1; } inline bool Sysfile::getRestartOngoing(const Uint32 & systemRestartBits){ return (systemRestartBits & 2) != 0; } inline void Sysfile::setRestartOngoing(Uint32 & systemRestartBits){ systemRestartBits |= 2; } inline void Sysfile::clearRestartOngoing(Uint32 & systemRestartBits){ systemRestartBits &= ~2; } inline bool Sysfile::getLCPOngoing(const Uint32 & systemRestartBits){ return systemRestartBits & 4; } inline void Sysfile::setLCPOngoing(Uint32 & systemRestartBits){ systemRestartBits |= 4; } inline void Sysfile::clearLCPOngoing(Uint32 & systemRestartBits){ systemRestartBits &= ~4; } inline Uint32 Sysfile::getNodeStatus(NodeId nodeId, const Uint32 nodeStatus[]){ const int word = nodeId >> 3; const int shift = (nodeId & 7) << 2; return (nodeStatus[word] >> shift) & 15; } inline void Sysfile::setNodeStatus(NodeId nodeId, Uint32 nodeStatus[], Uint32 status){ const int word = nodeId >> 3; const int shift = (nodeId & 7) << 2; const Uint32 mask = ~(((Uint32)15) << shift); const Uint32 tmp = nodeStatus[word]; nodeStatus[word] = (tmp & mask) | ((status & 15) << shift); } inline Uint16 Sysfile::getNodeGroup(NodeId nodeId, const Uint32 nodeGroups[]){ const int word = nodeId >> 2; const int shift = (nodeId & 3) << 3; return (nodeGroups[word] >> shift) & 255; } inline void Sysfile::setNodeGroup(NodeId nodeId, Uint32 nodeGroups[], Uint16 group){ const int word = nodeId >> 2; const int shift = (nodeId & 3) << 3; const Uint32 mask = ~(((Uint32)255) << shift); const Uint32 tmp = nodeGroups[word]; nodeGroups[word] = (tmp & mask) | ((group & 255) << shift); } inline NodeId Sysfile::getTakeOverNode(NodeId nodeId, const Uint32 takeOver[]){ const int word = nodeId >> 2; const int shift = (nodeId & 3) << 3; return (takeOver[word] >> shift) & 255; } inline void Sysfile::setTakeOverNode(NodeId nodeId, Uint32 takeOver[], NodeId toNode){ const int word = nodeId >> 2; const int shift = (nodeId & 3) << 3; const Uint32 mask = ~(((Uint32)255) << shift); const Uint32 tmp = takeOver[word]; takeOver[word] = (tmp & mask) | ((toNode & 255) << shift); } #endif