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 MgmtSrvr_H 26 #define MgmtSrvr_H 27 28 #include "Config.hpp" 29 #include "ConfigSubscriber.hpp" 30 31 #include <mgmapi.h> 32 #include <Vector.hpp> 33 #include <NodeBitmask.hpp> 34 #include <ndb_version.h> 35 #include <EventLogger.hpp> 36 37 #include <SignalSender.hpp> 38 39 #define MGM_ERROR_MAX_INJECT_SESSION_ONLY 10000 40 41 class SetLogLevelOrd; 42 43 class Ndb_mgmd_event_service : public EventLoggerBase 44 { 45 friend class MgmtSrvr; 46 public: 47 struct Event_listener : public EventLoggerBase { Event_listenerNdb_mgmd_event_service::Event_listener48 Event_listener() {} 49 NDB_SOCKET_TYPE m_socket; 50 Uint32 m_parsable; 51 }; 52 53 private: 54 class MgmtSrvr * m_mgmsrv; 55 MutexVector<Event_listener> m_clients; 56 public: Ndb_mgmd_event_service(class MgmtSrvr * m)57 Ndb_mgmd_event_service(class MgmtSrvr * m) : m_clients(5) { 58 m_mgmsrv = m; 59 } 60 61 void add_listener(const Event_listener&); 62 void check_listeners(); 63 void update_max_log_level(const LogLevel&); 64 void update_log_level(const LogLevel&); 65 66 void log(int eventType, const Uint32* theData, Uint32 len, NodeId nodeId); 67 68 void stop_sessions(); 69 operator [](unsigned i)70 Event_listener& operator[](unsigned i) { return m_clients[i]; } operator [](unsigned i) const71 const Event_listener& operator[](unsigned i) const { return m_clients[i]; } lock()72 void lock() { m_clients.lock(); } unlock()73 void unlock(){ m_clients.unlock(); } 74 }; 75 76 77 78 /** 79 @class MgmtSrvr 80 @brief Main class for the management server. 81 */ 82 class MgmtSrvr : private ConfigSubscriber, public trp_client { 83 84 public: 85 // some compilers need all of this 86 class Allocated_resources; 87 friend class Allocated_resources; 88 class Allocated_resources { 89 public: 90 Allocated_resources(class MgmtSrvr &m); 91 ~Allocated_resources(); 92 // methods to reserve/allocate resources which 93 // will be freed when running destructor 94 void reserve_node(NodeId id, NDB_TICKS timeout); 95 bool is_timed_out(NDB_TICKS tick); is_reserved(NodeId nodeId)96 bool is_reserved(NodeId nodeId) { return m_reserved_nodes.get(nodeId); } is_reserved(NodeBitmask mask)97 bool is_reserved(NodeBitmask mask) { return !mask.bitAND(m_reserved_nodes).isclear(); } isclear()98 bool isclear() { return m_reserved_nodes.isclear(); } 99 NodeId get_nodeid() const; 100 private: 101 MgmtSrvr &m_mgmsrv; 102 NodeBitmask m_reserved_nodes; 103 NDB_TICKS m_alloc_timeout; 104 }; 105 106 /** 107 * This enum specifies the different signal loggig modes possible to set 108 * with the setSignalLoggingMode method. 109 */ 110 enum LogMode {In, Out, InOut, Off}; 111 112 /** 113 @struct MgmtOpts 114 @brief Options used to control how the management server is started 115 */ 116 117 struct MgmtOpts { 118 int daemon; 119 int non_interactive; 120 int interactive; 121 const char* config_filename; 122 int mycnf; 123 int config_cache; 124 const char* bind_address; 125 int no_nodeid_checks; 126 int print_full_config; 127 const char* configdir; 128 int verbose; MgmtOptsMgmtSrvr::MgmtOpts129 MgmtOpts() : configdir(MYSQLCLUSTERDIR) {}; 130 int reload; 131 int initial; 132 NodeBitmask nowait_nodes; 133 }; 134 135 MgmtSrvr(); // Not implemented 136 MgmtSrvr(const MgmtSrvr&); // Not implemented 137 MgmtSrvr(const MgmtOpts&); 138 139 ~MgmtSrvr(); 140 141 private: 142 /* Function used from 'init' */ 143 const char* check_configdir() const; 144 145 public: 146 /* 147 To be called after constructor. 148 */ 149 bool init(); 150 151 /* 152 To be called after 'init', starts up the services 153 this server will expose 154 */ 155 bool start(void); 156 private: 157 /* Functions used from 'start' */ 158 bool start_transporter(const Config*); 159 bool start_mgm_service(const Config*); 160 bool connect_to_self(void); 161 162 public: 163 getOwnNodeId() const164 NodeId getOwnNodeId() const {return _ownNodeId;}; 165 166 /** 167 * Get status on a node. 168 * address may point to a common area (e.g. from inet_addr) 169 * There is no guarentee that it is preserved across calls. 170 * Copy the string if you are not going to use it immediately. 171 */ 172 int status(int nodeId, 173 ndb_mgm_node_status * status, 174 Uint32 * version, 175 Uint32 * mysql_version, 176 Uint32 * phase, 177 bool * systemShutdown, 178 Uint32 * dynamicId, 179 Uint32 * nodeGroup, 180 Uint32 * connectCount, 181 const char **address); 182 183 /** 184 * Stop a list of nodes 185 */ 186 int stopNodes(const Vector<NodeId> &node_ids, int *stopCount, bool abort, 187 bool force, int *stopSelf); 188 189 int shutdownMGM(int *stopCount, bool abort, int *stopSelf); 190 191 /** 192 * shutdown the DB nodes 193 */ 194 int shutdownDB(int * cnt = 0, bool abort = false); 195 196 /** 197 * Maintenance on the system 198 */ 199 int enterSingleUser(int * cnt = 0, Uint32 singleuserNodeId = 0); 200 201 202 /** 203 * Resume from maintenance on the system 204 */ 205 int exitSingleUser(int * cnt = 0, bool abort = false); 206 207 /** 208 * Start DB process. 209 * @param processId: Id of the DB process to start 210 * @return 0 if succeeded, otherwise: as stated above, plus: 211 */ 212 int start(int processId); 213 214 /** 215 * Restart a list of nodes 216 */ 217 int restartNodes(const Vector<NodeId> &node_ids, 218 int *stopCount, bool nostart, 219 bool initialStart, bool abort, bool force, 220 int *stopSelf); 221 222 /** 223 * Restart all DB nodes 224 */ 225 int restartDB(bool nostart, bool initialStart, 226 bool abort = false, 227 int * stopCount = 0); 228 229 /** 230 * Backup functionallity 231 */ 232 int startBackup(Uint32& backupId, int waitCompleted= 2, Uint32 input_backupId= 0, Uint32 backuppoint= 0); 233 int abortBackup(Uint32 backupId); 234 int performBackup(Uint32* backupId); 235 236 //************************************************************************** 237 // Description: Set event report level for a DB process 238 // Parameters: 239 // processId: Id of the DB process 240 // level: Event report level 241 // isResend: Flag to indicate for resending log levels during node restart 242 // Returns: 0 if succeeded, otherwise: as stated above, plus: 243 // INVALID_LEVEL 244 //************************************************************************** 245 246 int setEventReportingLevelImpl(int processId, const EventSubscribeReq& ll); 247 int setNodeLogLevelImpl(int processId, const SetLogLevelOrd & ll); 248 249 /** 250 * Insert an error in a DB process. 251 * @param processId: Id of the DB process 252 * @param errorNo: The error number. > 0. 253 * @return 0 if succeeded, otherwise: as stated above, plus: 254 * INVALID_ERROR_NUMBER 255 */ 256 int insertError(int processId, int errorNo); 257 258 259 260 int setTraceNo(int processId, int traceNo); 261 //************************************************************************** 262 // Description: Set trace number in a DB process. 263 // Parameters: 264 // processId: Id of the DB process 265 // trace: Trace number 266 // Returns: 0 if succeeded, otherwise: as stated above, plus: 267 // INVALID_TRACE_NUMBER 268 //************************************************************************** 269 270 271 int setSignalLoggingMode(int processId, LogMode mode, 272 const Vector<BaseString> &blocks); 273 setSignalLoggingMode(int processId,LogMode mode,BaseString & block)274 int setSignalLoggingMode(int processId, LogMode mode, 275 BaseString &block) { 276 Vector<BaseString> v; 277 v.push_back(block); 278 return setSignalLoggingMode(processId, mode, v); 279 } 280 //************************************************************************** 281 // Description: Set signal logging mode for blocks in a DB process. 282 // Parameters: 283 // processId: Id of the DB process 284 // mode: The log mode 285 // blocks: Which blocks to be affected (container of strings) 286 // Returns: 0 if succeeded, otherwise: as stated above, plus: 287 // INVALID_BLOCK_NAME 288 //************************************************************************** 289 290 291 int startSignalTracing(int processId); 292 //************************************************************************** 293 // Description: Start signal tracing for a DB process. 294 // Parameters: 295 // processId: Id of the DB process 296 // Returns: 0 if succeeded, otherwise: as stated above. 297 //************************************************************************** 298 299 300 int stopSignalTracing(int processId); 301 //************************************************************************** 302 // Description: Stop signal tracing for a DB process. 303 // Parameters: 304 // processId: Id of the DB process 305 // Returns: 0 if succeeded, otherwise: as stated above. 306 //************************************************************************** 307 308 /** 309 * Dump State 310 */ 311 int dumpState(int processId, const Uint32 args[], Uint32 argNo); 312 int dumpState(int processId, const char* args); 313 314 /** 315 * Get next node id (node id gt than _nodeId) 316 * of specified type and save it in _nodeId 317 * 318 * @return false if none found 319 */ 320 bool getNextNodeId(NodeId * _nodeId, enum ndb_mgm_node_type type) const ; 321 bool alloc_node_id(NodeId * _nodeId, enum ndb_mgm_node_type type, 322 const struct sockaddr *client_addr, 323 SOCKET_SIZE_TYPE *client_addr_len, 324 int &error_code, BaseString &error_string, 325 int log_event = 1, 326 int timeout_s = 20); 327 328 bool change_config(Config& new_config, BaseString& msg); 329 330 /** 331 * Get error text 332 * 333 * @param errorCode: Error code to get a match error text for. 334 * @return The error text. 335 */ 336 const char* getErrorText(int errorCode, char *buf, int buf_sz); 337 338 private: 339 void config_changed(NodeId, const Config*); 340 void setClusterLog(const Config* conf); 341 public: 342 343 /** 344 * Returns the port number where MgmApiService is started 345 * @return port number. 346 */ getPort() const347 int getPort() const { return m_port; }; 348 349 int setDbParameter(int node, int parameter, const char * value, BaseString&); 350 int setConnectionDbParameter(int node1, int node2, int param, int value, 351 BaseString& msg); 352 int getConnectionDbParameter(int node1, int node2, int param, 353 int *value, BaseString& msg); 354 355 bool transporter_connect(NDB_SOCKET_TYPE sockfd, BaseString& errormsg); 356 357 const char *get_connect_address(Uint32 node_id); 358 void get_connected_nodes(NodeBitmask &connected_nodes) const; get_socket_server()359 SocketServer *get_socket_server() { return &m_socket_server; } 360 361 void updateStatus(); 362 363 int createNodegroup(int *nodes, int count, int *ng); 364 int dropNodegroup(int ng); 365 366 int startSchemaTrans(SignalSender& ss, NodeId & out_nodeId, 367 Uint32 transId, Uint32 & out_transKey); 368 int endSchemaTrans(SignalSender& ss, NodeId nodeId, 369 Uint32 transId, Uint32 transKey, Uint32 flags); 370 371 private: 372 int guess_master_node(SignalSender&); 373 374 void status_api(int nodeId, 375 ndb_mgm_node_status& node_status, 376 Uint32& version, Uint32& mysql_version, 377 const char **address); 378 void status_mgmd(NodeId node_id, 379 ndb_mgm_node_status& node_status, 380 Uint32& version, Uint32& mysql_version, 381 const char **address); 382 383 int sendVersionReq(int processId, Uint32 &version, 384 Uint32& mysql_version, const char **address); 385 386 int sendStopMgmd(NodeId nodeId, 387 bool abort, 388 bool stop, 389 bool restart, 390 bool nostart, 391 bool initialStart); 392 393 int sendall_STOP_REQ(NodeBitmask &stoppedNodes, 394 bool abort, 395 bool stop, 396 bool restart, 397 bool nostart, 398 bool initialStart); 399 400 int sendSTOP_REQ(const Vector<NodeId> &node_ids, 401 NodeBitmask &stoppedNodes, 402 bool abort, 403 bool stop, 404 bool restart, 405 bool nostart, 406 bool initialStart, 407 int *stopSelf); 408 409 /** 410 * Check if it is possible to send a signal to a (DB) process 411 * 412 * @param processId: Id of the process to send to 413 * @return 0 OK, 1 process dead, 2 API or MGMT process, 3 not configured 414 */ 415 int okToSendTo(NodeId nodeId, bool unCond = false); 416 417 /** 418 * Get block number for a block 419 * 420 * @param blockName: Block to get number for 421 * @return -1 if block not found, otherwise block number 422 */ 423 int getBlockNumber(const BaseString &blockName); 424 425 int alloc_node_id_req(NodeId free_node_id, 426 enum ndb_mgm_node_type type, 427 Uint32 timeout_ms); 428 429 bool is_any_node_starting(void); 430 bool is_any_node_stopping(void); 431 bool is_cluster_single_user(void); 432 433 //************************************************************************** 434 435 const MgmtOpts& m_opts; 436 int _blockNumber; 437 NodeId _ownNodeId; 438 Uint32 m_port; 439 SocketServer m_socket_server; 440 441 NdbMutex* m_local_config_mutex; 442 const Config* m_local_config; 443 444 NdbMutex *m_node_id_mutex; 445 446 BlockReference _ownReference; 447 448 class ConfigManager* m_config_manager; 449 450 bool m_need_restart; 451 452 NodeBitmask m_reserved_nodes; 453 struct in_addr m_connect_address[MAX_NODES]; 454 455 /** 456 * trp_client interface 457 */ 458 virtual void trp_deliver_signal(const NdbApiSignal* signal, 459 const struct LinearSectionPtr ptr[3]); 460 virtual void trp_node_status(Uint32 nodeId, Uint32 event); 461 462 /** 463 * An event from <i>nodeId</i> has arrived 464 */ 465 void eventReport(const Uint32 * theData, Uint32 len); 466 467 class TransporterFacade * theFacade; 468 469 bool _isStopThread; 470 int _logLevelThreadSleep; 471 MutexVector<NodeId> m_started_nodes; 472 MutexVector<EventSubscribeReq> m_log_level_requests; 473 LogLevel m_nodeLogLevel[MAX_NODES]; 474 enum ndb_mgm_node_type nodeTypes[MAX_NODES]; 475 friend class MgmApiSession; 476 friend class Ndb_mgmd_event_service; 477 Ndb_mgmd_event_service m_event_listner; 478 479 NodeId m_master_node; 480 481 ndb_mgm_node_type getNodeType(NodeId) const; 482 483 /** 484 * Handles the thread wich upon a 'Node is started' event will 485 * set the node's previous loglevel settings. 486 */ 487 struct NdbThread* _logLevelThread; 488 static void *logLevelThread_C(void *); 489 void logLevelThreadRun(); 490 void report_unknown_signal(SimpleSignal *signal); 491 492 void make_sync_req(SignalSender& ss, Uint32 nodeId); 493 public: 494 /* Get copy of configuration packed with base64 */ 495 bool get_packed_config(ndb_mgm_node_type nodetype, 496 BaseString& buf64, BaseString& error); 497 498 /* Get copy of configuration packed with base64 from node nodeid */ 499 bool get_packed_config_from_node(NodeId nodeid, 500 BaseString& buf64, BaseString& error); 501 502 void print_config(const char* section_filter = NULL, 503 NodeId nodeid_filter = 0, 504 const char* param_filter = NULL, 505 NdbOut& out = ndbout); 506 507 bool reload_config(const char* config_filename, 508 bool mycnf, BaseString& msg); 509 510 void show_variables(NdbOut& out = ndbout); 511 512 struct nodeid_and_host 513 { 514 unsigned id; 515 BaseString host; 516 }; 517 int find_node_type(unsigned node_id, enum ndb_mgm_node_type type, 518 const struct sockaddr *client_addr, 519 NodeBitmask &nodes, 520 NodeBitmask &exact_nodes, 521 Vector<nodeid_and_host> &nodes_info, 522 int &error_code, BaseString &error_string); 523 int try_alloc(unsigned id, const char *, enum ndb_mgm_node_type type, 524 const struct sockaddr *client_addr, Uint32 timeout_ms); 525 526 BaseString m_version_string; get_version_string(void) const527 const char* get_version_string(void) const { 528 return m_version_string.c_str(); 529 } 530 531 bool request_events(NdbNodeBitmask nodes, Uint32 reports_per_node, 532 Uint32 dump_type, 533 Vector<SimpleSignal>& events); 534 }; 535 536 #endif // MgmtSrvr_H 537