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 ARBIT_SIGNAL_DATA_H 26 #define ARBIT_SIGNAL_DATA_H 27 28 #include <string.h> 29 #include <NodeBitmask.hpp> 30 #include <NdbTick.h> 31 #include <NdbHost.h> 32 #include "SignalData.hpp" 33 #include "SignalDataPrint.hpp" 34 35 #define JAM_FILE_ID 23 36 37 38 /** 39 * The ticket. 40 */ 41 class ArbitTicket { 42 private: 43 Uint32 data[2]; 44 45 public: 46 STATIC_CONST( DataLength = 2 ); 47 STATIC_CONST( TextLength = DataLength * 8 ); // hex digits 48 clear()49 inline void clear() { 50 data[0] = 0; 51 data[1] = 0; 52 } 53 update()54 inline void update() { 55 Uint16 cnt = data[0] & 0xFFFF; // previous count 56 Uint16 pid = NdbHost_GetProcessId(); 57 data[0] = (pid << 16) | (cnt + 1); 58 data[1] = (Uint32)NdbTick_CurrentMillisecond(); 59 } 60 match(ArbitTicket & aTicket) const61 inline bool match(ArbitTicket& aTicket) const { 62 return 63 data[0] == aTicket.data[0] && 64 data[1] == aTicket.data[1]; 65 } 66 getText(char * buf,size_t buf_len) const67 inline void getText(char *buf, size_t buf_len) const { 68 BaseString::snprintf(buf, buf_len, "%08x%08x", data[0], data[1]); 69 } 70 71 /* inline char* getText() const { 72 static char buf[TextLength + 1]; 73 getText(buf, sizeof(buf)); 74 return buf; 75 } */ 76 }; 77 78 /** 79 * Result codes. Part of signal data. Each signal uses only 80 * a subset but a common namespace is convenient. 81 */ 82 class ArbitCode { 83 public: 84 STATIC_CONST( ErrTextLength = 80 ); 85 86 enum { 87 NoInfo = 0, 88 89 // CFG signals 90 CfgRank1 = 1, // these have to be 1 and 2 91 CfgRank2 = 2, 92 93 // QMGR continueB thread state 94 ThreadStart = 11, // continueB thread started 95 96 // PREP signals 97 PrepPart1 = 21, // zero old ticket 98 PrepPart2 = 22, // get new ticket 99 PrepAtrun = 23, // late joiner gets ticket at RUN time 100 101 // arbitrator state 102 ApiStart = 31, // arbitrator thread started 103 ApiFail = 32, // arbitrator died 104 ApiExit = 33, // arbitrator reported it will exit 105 106 // arbitration result 107 LoseNodes = 41, // lose on ndb node count 108 WinNodes = 42, // win on ndb node count 109 WinGroups = 43, // we win, no need for arbitration 110 LoseGroups = 44, // we lose, missing node group 111 Partitioning = 45, // possible network partitioning 112 WinChoose = 46, // positive reply 113 LoseChoose = 47, // negative reply 114 LoseNorun = 48, // arbitrator required but not running 115 LoseNocfg = 49, // arbitrator required but none configured 116 WinWaitExternal = 50, // continue after external arbitration wait 117 118 // general error codes 119 ErrTicket = 91, // invalid arbitrator-ticket 120 ErrToomany = 92, // too many requests 121 ErrState = 93, // invalid state 122 ErrTimeout = 94, // timeout waiting for signals 123 ErrUnknown = 95 // unknown error 124 }; 125 getErrText(Uint32 code,char * buf,size_t buf_len)126 static inline void getErrText(Uint32 code, char* buf, size_t buf_len) { 127 switch (code) { 128 case ErrTicket: 129 BaseString::snprintf(buf, buf_len, "invalid arbitrator-ticket"); 130 break; 131 case ErrToomany: 132 BaseString::snprintf(buf, buf_len, "too many requests"); 133 break; 134 case ErrState: 135 BaseString::snprintf(buf, buf_len, "invalid state"); 136 break; 137 case ErrTimeout: 138 BaseString::snprintf(buf, buf_len, "timeout"); 139 break; 140 default: 141 BaseString::snprintf(buf, buf_len, "unknown error [code=%u]", code); 142 break; 143 } 144 } 145 }; 146 147 /** 148 * Common class for arbitration signal data. 149 */ 150 class ArbitSignalData { 151 public: 152 Uint32 sender; // sender's node id (must be word 0) 153 Uint32 code; // result code or other info 154 Uint32 node; // arbitrator node id 155 ArbitTicket ticket; // ticket 156 NodeBitmaskPOD mask; // set of nodes 157 158 STATIC_CONST( SignalLength = 3 + ArbitTicket::DataLength + NodeBitmask::Size ); 159 match(ArbitSignalData & aData) const160 inline bool match(ArbitSignalData& aData) const { 161 return 162 node == aData.node && 163 ticket.match(aData.ticket); 164 } 165 }; 166 167 168 #undef JAM_FILE_ID 169 170 #endif 171