00001 /* Copyright (C) 2003 MySQL AB 00002 00003 This program is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU General Public License as published by 00005 the Free Software Foundation; either version 2 of the License, or 00006 (at your option) any later version. 00007 00008 This program is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 GNU General Public License for more details. 00012 00013 You should have received a copy of the GNU General Public License 00014 along with this program; if not, write to the Free Software 00015 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 00016 00017 #include <ndb_global.h> 00018 #include <my_pthread.h> 00019 00020 #include "MgmtSrvr.hpp" 00021 #include "MgmtErrorReporter.hpp" 00022 #include <ConfigRetriever.hpp> 00023 00024 #include <NdbOut.hpp> 00025 #include <NdbApiSignal.hpp> 00026 #include <kernel_types.h> 00027 #include <RefConvert.hpp> 00028 #include <BlockNumbers.h> 00029 #include <GlobalSignalNumbers.h> 00030 #include <signaldata/TestOrd.hpp> 00031 #include <signaldata/TamperOrd.hpp> 00032 #include <signaldata/StartOrd.hpp> 00033 #include <signaldata/ApiVersion.hpp> 00034 #include <signaldata/ResumeReq.hpp> 00035 #include <signaldata/SetLogLevelOrd.hpp> 00036 #include <signaldata/EventSubscribeReq.hpp> 00037 #include <signaldata/EventReport.hpp> 00038 #include <signaldata/DumpStateOrd.hpp> 00039 #include <signaldata/BackupSignalData.hpp> 00040 #include <signaldata/ManagementServer.hpp> 00041 #include <signaldata/NFCompleteRep.hpp> 00042 #include <signaldata/NodeFailRep.hpp> 00043 #include <signaldata/AllocNodeId.hpp> 00044 #include <NdbSleep.h> 00045 #include <EventLogger.hpp> 00046 #include <DebuggerNames.hpp> 00047 #include <ndb_version.h> 00048 00049 #include <SocketServer.hpp> 00050 #include <NdbConfig.h> 00051 00052 #include <NdbAutoPtr.hpp> 00053 00054 #include <ndberror.h> 00055 00056 #include <mgmapi.h> 00057 #include <mgmapi_configuration.hpp> 00058 #include <mgmapi_config_parameters.h> 00059 #include <m_string.h> 00060 00061 #include <SignalSender.hpp> 00062 00063 //#define MGM_SRV_DEBUG 00064 #ifdef MGM_SRV_DEBUG 00065 #define DEBUG(x) do ndbout << x << endl; while(0) 00066 #else 00067 #define DEBUG(x) 00068 #endif 00069 00070 #define INIT_SIGNAL_SENDER(ss,nodeId) \ 00071 SignalSender ss(theFacade); \ 00072 ss.lock(); /* lock will be released on exit */ \ 00073 {\ 00074 int result = okToSendTo(nodeId, true);\ 00075 if (result != 0) {\ 00076 return result;\ 00077 }\ 00078 } 00079 00080 extern int global_flag_send_heartbeat_now; 00081 extern int g_no_nodeid_checks; 00082 extern my_bool opt_core; 00083 00084 static void require(bool v) 00085 { 00086 if(!v) 00087 { 00088 if (opt_core) 00089 abort(); 00090 else 00091 exit(-1); 00092 } 00093 } 00094 00095 void * 00096 MgmtSrvr::logLevelThread_C(void* m) 00097 { 00098 MgmtSrvr *mgm = (MgmtSrvr*)m; 00099 mgm->logLevelThreadRun(); 00100 return 0; 00101 } 00102 00103 extern EventLogger g_eventLogger; 00104 00105 static NdbOut& 00106 operator<<(NdbOut& out, const LogLevel & ll) 00107 { 00108 out << "[LogLevel: "; 00109 for(size_t i = 0; i<LogLevel::LOGLEVEL_CATEGORIES; i++) 00110 out << ll.getLogLevel((LogLevel::EventCategory)i) << " "; 00111 out << "]"; 00112 return out; 00113 } 00114 00115 void 00116 MgmtSrvr::logLevelThreadRun() 00117 { 00118 while (!_isStopThread) { 00122 m_started_nodes.lock(); 00123 if (m_started_nodes.size() > 0) 00124 { 00125 // calculate max log level 00126 EventSubscribeReq req; 00127 { 00128 LogLevel tmp; 00129 m_event_listner.lock(); 00130 for(int i = m_event_listner.m_clients.size() - 1; i >= 0; i--) 00131 tmp.set_max(m_event_listner[i].m_logLevel); 00132 m_event_listner.unlock(); 00133 req = tmp; 00134 } 00135 req.blockRef = _ownReference; 00136 while (m_started_nodes.size() > 0) 00137 { 00138 Uint32 node = m_started_nodes[0]; 00139 m_started_nodes.erase(0, false); 00140 m_started_nodes.unlock(); 00141 00142 setEventReportingLevelImpl(node, req); 00143 00144 SetLogLevelOrd ord; 00145 ord = m_nodeLogLevel[node]; 00146 setNodeLogLevelImpl(node, ord); 00147 00148 m_started_nodes.lock(); 00149 } 00150 } 00151 m_started_nodes.unlock(); 00152 00153 m_log_level_requests.lock(); 00154 while (m_log_level_requests.size() > 0) 00155 { 00156 EventSubscribeReq req = m_log_level_requests[0]; 00157 m_log_level_requests.erase(0, false); 00158 m_log_level_requests.unlock(); 00159 00160 if(req.blockRef == 0){ 00161 req.blockRef = _ownReference; 00162 setEventReportingLevelImpl(0, req); 00163 } else { 00164 SetLogLevelOrd ord; 00165 ord = req; 00166 setNodeLogLevelImpl(req.blockRef, ord); 00167 } 00168 m_log_level_requests.lock(); 00169 } 00170 m_log_level_requests.unlock(); 00171 NdbSleep_MilliSleep(_logLevelThreadSleep); 00172 } 00173 } 00174 00175 void 00176 MgmtSrvr::startEventLog() 00177 { 00178 NdbMutex_Lock(m_configMutex); 00179 00180 g_eventLogger.setCategory("MgmSrvr"); 00181 00182 ndb_mgm_configuration_iterator 00183 iter(* _config->m_configValues, CFG_SECTION_NODE); 00184 00185 if(iter.find(CFG_NODE_ID, _ownNodeId) != 0){ 00186 NdbMutex_Unlock(m_configMutex); 00187 return; 00188 } 00189 00190 const char * tmp; 00191 char errStr[100]; 00192 int err= 0; 00193 BaseString logdest; 00194 char *clusterLog= NdbConfig_ClusterLogFileName(_ownNodeId); 00195 NdbAutoPtr<char> tmp_aptr(clusterLog); 00196 00197 if(iter.get(CFG_LOG_DESTINATION, &tmp) == 0){ 00198 logdest.assign(tmp); 00199 } 00200 NdbMutex_Unlock(m_configMutex); 00201 00202 if(logdest.length() == 0 || logdest == "") { 00203 logdest.assfmt("FILE:filename=%s,maxsize=1000000,maxfiles=6", 00204 clusterLog); 00205 } 00206 errStr[0]='\0'; 00207 if(!g_eventLogger.addHandler(logdest, &err, sizeof(errStr), errStr)) { 00208 ndbout << "Warning: could not add log destination \"" 00209 << logdest.c_str() << "\". Reason: "; 00210 if(err) 00211 ndbout << strerror(err); 00212 if(err && errStr[0]!='\0') 00213 ndbout << ", "; 00214 if(errStr[0]!='\0') 00215 ndbout << errStr; 00216 ndbout << endl; 00217 } 00218 } 00219 00220 void 00221 MgmtSrvr::stopEventLog() 00222 { 00223 // Nothing yet 00224 } 00225 00226 class ErrorItem 00227 { 00228 public: 00229 int _errorCode; 00230 const char * _errorText; 00231 }; 00232 00233 bool 00234 MgmtSrvr::setEventLogFilter(int severity, int enable) 00235 { 00236 Logger::LoggerLevel level = (Logger::LoggerLevel)severity; 00237 if (enable > 0) { 00238 g_eventLogger.enable(level); 00239 } else if (enable == 0) { 00240 g_eventLogger.disable(level); 00241 } else if (g_eventLogger.isEnable(level)) { 00242 g_eventLogger.disable(level); 00243 } else { 00244 g_eventLogger.enable(level); 00245 } 00246 return g_eventLogger.isEnable(level); 00247 } 00248 00249 bool 00250 MgmtSrvr::isEventLogFilterEnabled(int severity) 00251 { 00252 return g_eventLogger.isEnable((Logger::LoggerLevel)severity); 00253 } 00254 00255 static ErrorItem errorTable[] = 00256 { 00257 {MgmtSrvr::NO_CONTACT_WITH_PROCESS, "No contact with the process (dead ?)."}, 00258 {MgmtSrvr::PROCESS_NOT_CONFIGURED, "The process is not configured."}, 00259 {MgmtSrvr::WRONG_PROCESS_TYPE, 00260 "The process has wrong type. Expected a DB process."}, 00261 {MgmtSrvr::COULD_NOT_ALLOCATE_MEMORY, "Could not allocate memory."}, 00262 {MgmtSrvr::SEND_OR_RECEIVE_FAILED, "Send to process or receive failed."}, 00263 {MgmtSrvr::INVALID_LEVEL, "Invalid level. Should be between 1 and 30."}, 00264 {MgmtSrvr::INVALID_ERROR_NUMBER, "Invalid error number. Should be >= 0."}, 00265 {MgmtSrvr::INVALID_TRACE_NUMBER, "Invalid trace number."}, 00266 {MgmtSrvr::NOT_IMPLEMENTED, "Not implemented."}, 00267 {MgmtSrvr::INVALID_BLOCK_NAME, "Invalid block name"}, 00268 00269 {MgmtSrvr::CONFIG_PARAM_NOT_EXIST, 00270 "The configuration parameter does not exist for the process type."}, 00271 {MgmtSrvr::CONFIG_PARAM_NOT_UPDATEABLE, 00272 "The configuration parameter is not possible to update."}, 00273 {MgmtSrvr::VALUE_WRONG_FORMAT_INT_EXPECTED, 00274 "Incorrect value. Expected integer."}, 00275 {MgmtSrvr::VALUE_TOO_LOW, "Value is too low."}, 00276 {MgmtSrvr::VALUE_TOO_HIGH, "Value is too high."}, 00277 {MgmtSrvr::VALUE_WRONG_FORMAT_BOOL_EXPECTED, 00278 "Incorrect value. Expected TRUE or FALSE."}, 00279 00280 {MgmtSrvr::CONFIG_FILE_OPEN_WRITE_ERROR, 00281 "Could not open configuration file for writing."}, 00282 {MgmtSrvr::CONFIG_FILE_OPEN_READ_ERROR, 00283 "Could not open configuration file for reading."}, 00284 {MgmtSrvr::CONFIG_FILE_WRITE_ERROR, 00285 "Write error when writing configuration file."}, 00286 {MgmtSrvr::CONFIG_FILE_READ_ERROR, 00287 "Read error when reading configuration file."}, 00288 {MgmtSrvr::CONFIG_FILE_CLOSE_ERROR, "Could not close configuration file."}, 00289 00290 {MgmtSrvr::CONFIG_CHANGE_REFUSED_BY_RECEIVER, 00291 "The change was refused by the receiving process."}, 00292 {MgmtSrvr::COULD_NOT_SYNC_CONFIG_CHANGE_AGAINST_PHYSICAL_MEDIUM, 00293 "The change could not be synced against physical medium."}, 00294 {MgmtSrvr::CONFIG_FILE_CHECKSUM_ERROR, 00295 "The config file is corrupt. Checksum error."}, 00296 {MgmtSrvr::NOT_POSSIBLE_TO_SEND_CONFIG_UPDATE_TO_PROCESS_TYPE, 00297 "It is not possible to send an update of a configuration variable " 00298 "to this kind of process."}, 00299 {MgmtSrvr::NODE_SHUTDOWN_IN_PROGESS, "Node shutdown in progress" }, 00300 {MgmtSrvr::SYSTEM_SHUTDOWN_IN_PROGRESS, "System shutdown in progress" }, 00301 {MgmtSrvr::NODE_SHUTDOWN_WOULD_CAUSE_SYSTEM_CRASH, 00302 "Node shutdown would cause system crash" }, 00303 {MgmtSrvr::UNSUPPORTED_NODE_SHUTDOWN, 00304 "Unsupported multi node shutdown. Abort option required." }, 00305 {MgmtSrvr::NODE_NOT_API_NODE, "The specified node is not an API node." }, 00306 {MgmtSrvr::OPERATION_NOT_ALLOWED_START_STOP, 00307 "Operation not allowed while nodes are starting or stopping."}, 00308 {MgmtSrvr::NO_CONTACT_WITH_DB_NODES, "No contact with database nodes" } 00309 }; 00310 00311 int MgmtSrvr::translateStopRef(Uint32 errCode) 00312 { 00313 switch(errCode){ 00314 case StopRef::NodeShutdownInProgress: 00315 return NODE_SHUTDOWN_IN_PROGESS; 00316 break; 00317 case StopRef::SystemShutdownInProgress: 00318 return SYSTEM_SHUTDOWN_IN_PROGRESS; 00319 break; 00320 case StopRef::NodeShutdownWouldCauseSystemCrash: 00321 return NODE_SHUTDOWN_WOULD_CAUSE_SYSTEM_CRASH; 00322 break; 00323 case StopRef::UnsupportedNodeShutdown: 00324 return UNSUPPORTED_NODE_SHUTDOWN; 00325 break; 00326 } 00327 return 4999; 00328 } 00329 00330 static int noOfErrorCodes = sizeof(errorTable) / sizeof(ErrorItem); 00331 00332 int 00333 MgmtSrvr::getNodeCount(enum ndb_mgm_node_type type) const 00334 { 00335 int count = 0; 00336 NodeId nodeId = 0; 00337 00338 while (getNextNodeId(&nodeId, type)) { 00339 count++; 00340 } 00341 return count; 00342 } 00343 00344 int 00345 MgmtSrvr::getPort() const 00346 { 00347 if(NdbMutex_Lock(m_configMutex)) 00348 return 0; 00349 00350 ndb_mgm_configuration_iterator 00351 iter(* _config->m_configValues, CFG_SECTION_NODE); 00352 00353 if(iter.find(CFG_NODE_ID, getOwnNodeId()) != 0){ 00354 ndbout << "Could not retrieve configuration for Node " 00355 << getOwnNodeId() << " in config file." << endl 00356 << "Have you set correct NodeId for this node?" << endl; 00357 NdbMutex_Unlock(m_configMutex); 00358 return 0; 00359 } 00360 00361 unsigned type; 00362 if(iter.get(CFG_TYPE_OF_SECTION, &type) != 0 || 00363 type != NODE_TYPE_MGM){ 00364 ndbout << "Local node id " << getOwnNodeId() 00365 << " is not defined as management server" << endl 00366 << "Have you set correct NodeId for this node?" << endl; 00367 NdbMutex_Unlock(m_configMutex); 00368 return 0; 00369 } 00370 00371 Uint32 port = 0; 00372 if(iter.get(CFG_MGM_PORT, &port) != 0){ 00373 ndbout << "Could not find PortNumber in the configuration file." << endl; 00374 NdbMutex_Unlock(m_configMutex); 00375 return 0; 00376 } 00377 00378 NdbMutex_Unlock(m_configMutex); 00379 00380 return port; 00381 } 00382 00383 /* Constructor */ 00384 int MgmtSrvr::init() 00385 { 00386 if ( _ownNodeId > 0) 00387 return 0; 00388 return -1; 00389 } 00390 00391 MgmtSrvr::MgmtSrvr(SocketServer *socket_server, 00392 const char *config_filename, 00393 const char *connect_string) : 00394 _blockNumber(1), // Hard coded block number since it makes it easy to send 00395 // signals to other management servers. 00396 m_socket_server(socket_server), 00397 _ownReference(0), 00398 theSignalIdleList(NULL), 00399 theWaitState(WAIT_SUBSCRIBE_CONF), 00400 m_local_mgm_handle(0), 00401 m_event_listner(this), 00402 m_master_node(0) 00403 { 00404 00405 DBUG_ENTER("MgmtSrvr::MgmtSrvr"); 00406 00407 _ownNodeId= 0; 00408 00409 _config = NULL; 00410 00411 _isStopThread = false; 00412 _logLevelThread = NULL; 00413 _logLevelThreadSleep = 500; 00414 00415 theFacade = 0; 00416 00417 m_newConfig = NULL; 00418 if (config_filename) 00419 m_configFilename.assign(config_filename); 00420 00421 m_nextConfigGenerationNumber = 0; 00422 00423 m_config_retriever= new ConfigRetriever(connect_string, 00424 NDB_VERSION, NDB_MGM_NODE_TYPE_MGM); 00425 // if connect_string explicitly given or 00426 // no config filename is given then 00427 // first try to allocate nodeid from another management server 00428 if ((connect_string || config_filename == NULL) && 00429 (m_config_retriever->do_connect(0,0,0) == 0)) 00430 { 00431 int tmp_nodeid= 0; 00432 tmp_nodeid= m_config_retriever->allocNodeId(0 /*retry*/,0 /*delay*/); 00433 if (tmp_nodeid == 0) 00434 { 00435 ndbout_c(m_config_retriever->getErrorString()); 00436 require(false); 00437 } 00438 // read config from other managent server 00439 _config= fetchConfig(); 00440 if (_config == 0) 00441 { 00442 ndbout << m_config_retriever->getErrorString() << endl; 00443 require(false); 00444 } 00445 _ownNodeId= tmp_nodeid; 00446 } 00447 00448 if (_ownNodeId == 0) 00449 { 00450 // read config locally 00451 _config= readConfig(); 00452 if (_config == 0) { 00453 ndbout << "Unable to read config file" << endl; 00454 exit(-1); 00455 } 00456 } 00457 00458 theMgmtWaitForResponseCondPtr = NdbCondition_Create(); 00459 00460 m_configMutex = NdbMutex_Create(); 00461 00465 for(Uint32 i = 0; i<MAX_NODES; i++) { 00466 nodeTypes[i] = (enum ndb_mgm_node_type)-1; 00467 m_connect_address[i].s_addr= 0; 00468 } 00469 00470 { 00471 ndb_mgm_configuration_iterator 00472 iter(* _config->m_configValues, CFG_SECTION_NODE); 00473 00474 for(iter.first(); iter.valid(); iter.next()){ 00475 unsigned type, id; 00476 if(iter.get(CFG_TYPE_OF_SECTION, &type) != 0) 00477 continue; 00478 00479 if(iter.get(CFG_NODE_ID, &id) != 0) 00480 continue; 00481 00482 MGM_REQUIRE(id < MAX_NODES); 00483 00484 switch(type){ 00485 case NODE_TYPE_DB: 00486 nodeTypes[id] = NDB_MGM_NODE_TYPE_NDB; 00487 break; 00488 case NODE_TYPE_API: 00489 nodeTypes[id] = NDB_MGM_NODE_TYPE_API; 00490 break; 00491 case NODE_TYPE_MGM: 00492 nodeTypes[id] = NDB_MGM_NODE_TYPE_MGM; 00493 break; 00494 default: 00495 break; 00496 } 00497 } 00498 } 00499 00500 _props = NULL; 00501 BaseString error_string; 00502 00503 if ((m_node_id_mutex = NdbMutex_Create()) == 0) 00504 { 00505 ndbout << "mutex creation failed line = " << __LINE__ << endl; 00506 require(false); 00507 } 00508 00509 if (_ownNodeId == 0) // we did not get node id from other server 00510 { 00511 NodeId tmp= m_config_retriever->get_configuration_nodeid(); 00512 int error_code; 00513 00514 if (!alloc_node_id(&tmp, NDB_MGM_NODE_TYPE_MGM, 00515 0, 0, error_code, error_string)){ 00516 ndbout << "Unable to obtain requested nodeid: " 00517 << error_string.c_str() << endl; 00518 require(false); 00519 } 00520 _ownNodeId = tmp; 00521 } 00522 00523 { 00524 DBUG_PRINT("info", ("verifyConfig")); 00525 if (!m_config_retriever->verifyConfig(_config->m_configValues, 00526 _ownNodeId)) 00527 { 00528 ndbout << m_config_retriever->getErrorString() << endl; 00529 require(false); 00530 } 00531 } 00532 00533 // Setup clusterlog as client[0] in m_event_listner 00534 { 00535 Ndb_mgmd_event_service::Event_listener se; 00536 se.m_socket = NDB_INVALID_SOCKET; 00537 for(size_t t = 0; t<LogLevel::LOGLEVEL_CATEGORIES; t++){ 00538 se.m_logLevel.setLogLevel((LogLevel::EventCategory)t, 7); 00539 } 00540 se.m_logLevel.setLogLevel(LogLevel::llError, 15); 00541 se.m_logLevel.setLogLevel(LogLevel::llConnection, 8); 00542 se.m_logLevel.setLogLevel(LogLevel::llBackup, 15); 00543 m_event_listner.m_clients.push_back(se); 00544 m_event_listner.m_logLevel = se.m_logLevel; 00545 } 00546 00547 DBUG_VOID_RETURN; 00548 } 00549 00550 00551 //**************************************************************************** 00552 //**************************************************************************** 00553 bool 00554 MgmtSrvr::check_start() 00555 { 00556 if (_config == 0) { 00557 DEBUG("MgmtSrvr.cpp: _config is NULL."); 00558 return false; 00559 } 00560 00561 return true; 00562 } 00563 00564 bool 00565 MgmtSrvr::start(BaseString &error_string) 00566 { 00567 int mgm_connect_result; 00568 00569 DBUG_ENTER("MgmtSrvr::start"); 00570 if (_props == NULL) { 00571 if (!check_start()) { 00572 error_string.append("MgmtSrvr.cpp: check_start() failed."); 00573 DBUG_RETURN(false); 00574 } 00575 } 00576 theFacade= new TransporterFacade(); 00577 00578 if(theFacade == 0) { 00579 DEBUG("MgmtSrvr.cpp: theFacade is NULL."); 00580 error_string.append("MgmtSrvr.cpp: theFacade is NULL."); 00581 DBUG_RETURN(false); 00582 } 00583 if ( theFacade->start_instance 00584 (_ownNodeId, (ndb_mgm_configuration*)_config->m_configValues) < 0) { 00585 DEBUG("MgmtSrvr.cpp: TransporterFacade::start_instance < 0."); 00586 DBUG_RETURN(false); 00587 } 00588 00589 MGM_REQUIRE(_blockNumber == 1); 00590 00591 // Register ourself at TransporterFacade to be able to receive signals 00592 // and to be notified when a database process has died. 00593 _blockNumber = theFacade->open(this, 00594 signalReceivedNotification, 00595 nodeStatusNotification); 00596 00597 if(_blockNumber == -1){ 00598 DEBUG("MgmtSrvr.cpp: _blockNumber is -1."); 00599 error_string.append("MgmtSrvr.cpp: _blockNumber is -1."); 00600 theFacade->stop_instance(); 00601 theFacade = 0; 00602 DBUG_RETURN(false); 00603 } 00604 00605 if((mgm_connect_result= connect_to_self()) < 0) 00606 { 00607 ndbout_c("Unable to connect to our own ndb_mgmd (Error %d)", 00608 mgm_connect_result); 00609 ndbout_c("This is probably a bug."); 00610 } 00611 00612 TransporterRegistry *reg = theFacade->get_registry(); 00613 for(unsigned int i=0;i<reg->m_transporter_interface.size();i++) { 00614 BaseString msg; 00615 DBUG_PRINT("info",("Setting dynamic port %d->%d : %d", 00616 reg->get_localNodeId(), 00617 reg->m_transporter_interface[i].m_remote_nodeId, 00618 reg->m_transporter_interface[i].m_s_service_port 00619 ) 00620 ); 00621 int res = setConnectionDbParameter((int)reg->get_localNodeId(), 00622 (int)reg->m_transporter_interface[i] 00623 .m_remote_nodeId, 00624 (int)CFG_CONNECTION_SERVER_PORT, 00625 reg->m_transporter_interface[i] 00626 .m_s_service_port, 00627 msg); 00628 DBUG_PRINT("info",("Set result: %d: %s",res,msg.c_str())); 00629 } 00630 00631 _ownReference = numberToRef(_blockNumber, _ownNodeId); 00632 00633 startEventLog(); 00634 // Set the initial confirmation count for subscribe requests confirm 00635 // from NDB nodes in the cluster. 00636 // 00637 // Loglevel thread 00638 _logLevelThread = NdbThread_Create(logLevelThread_C, 00639 (void**)this, 00640 32768, 00641 "MgmtSrvr_Loglevel", 00642 NDB_THREAD_PRIO_LOW); 00643 00644 DBUG_RETURN(true); 00645 } 00646 00647 00648 //**************************************************************************** 00649 //**************************************************************************** 00650 MgmtSrvr::~MgmtSrvr() 00651 { 00652 if(theFacade != 0){ 00653 theFacade->stop_instance(); 00654 delete theFacade; 00655 theFacade = 0; 00656 } 00657 00658 stopEventLog(); 00659 00660 NdbMutex_Destroy(m_node_id_mutex); 00661 NdbCondition_Destroy(theMgmtWaitForResponseCondPtr); 00662 NdbMutex_Destroy(m_configMutex); 00663 00664 if(m_newConfig != NULL) 00665 free(m_newConfig); 00666 00667 if(_config != NULL) 00668 delete _config; 00669 00670 // End set log level thread 00671 void* res = 0; 00672 _isStopThread = true; 00673 00674 if (_logLevelThread != NULL) { 00675 NdbThread_WaitFor(_logLevelThread, &res); 00676 NdbThread_Destroy(&_logLevelThread); 00677 } 00678 00679 if (m_config_retriever) 00680 delete m_config_retriever; 00681 } 00682 00683 //**************************************************************************** 00684 //**************************************************************************** 00685 00686 int MgmtSrvr::okToSendTo(NodeId nodeId, bool unCond) 00687 { 00688 if(nodeId == 0 || getNodeType(nodeId) != NDB_MGM_NODE_TYPE_NDB) 00689 return WRONG_PROCESS_TYPE; 00690 // Check if we have contact with it 00691 if(unCond){ 00692 if(theFacade->theClusterMgr->getNodeInfo(nodeId).connected) 00693 return 0; 00694 } 00695 else if (theFacade->get_node_alive(nodeId) == true) 00696 return 0; 00697 return NO_CONTACT_WITH_PROCESS; 00698 } 00699 00700 void report_unknown_signal(SimpleSignal *signal) 00701 { 00702 g_eventLogger.error("Unknown signal received. SignalNumber: " 00703 "%i from (%d, %x)", 00704 signal->readSignalNumber(), 00705 refToNode(signal->header.theSendersBlockRef), 00706 refToBlock(signal->header.theSendersBlockRef)); 00707 } 00708 00709 /***************************************************************************** 00710 * Starting and stopping database nodes 00711 ****************************************************************************/ 00712 00713 int 00714 MgmtSrvr::start(int nodeId) 00715 { 00716 INIT_SIGNAL_SENDER(ss,nodeId); 00717 00718 SimpleSignal ssig; 00719 StartOrd* const startOrd = CAST_PTR(StartOrd, ssig.getDataPtrSend()); 00720 ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_START_ORD, StartOrd::SignalLength); 00721 startOrd->restartInfo = 0; 00722 00723 return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED; 00724 } 00725 00726 /***************************************************************************** 00727 * Version handling 00728 *****************************************************************************/ 00729 00730 int 00731 MgmtSrvr::versionNode(int nodeId, Uint32 &version, const char **address) 00732 { 00733 version= 0; 00734 if (getOwnNodeId() == nodeId) 00735 { 00746 sendVersionReq(nodeId, version, address); 00747 version= NDB_VERSION; 00748 if(!*address) 00749 { 00750 ndb_mgm_configuration_iterator 00751 iter(*_config->m_configValues, CFG_SECTION_NODE); 00752 unsigned tmp= 0; 00753 for(iter.first();iter.valid();iter.next()) 00754 { 00755 if(iter.get(CFG_NODE_ID, &tmp)) require(false); 00756 if((unsigned)nodeId!=tmp) 00757 continue; 00758 if(iter.get(CFG_NODE_HOST, address)) require(false); 00759 break; 00760 } 00761 } 00762 } 00763 else if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_NDB) 00764 { 00765 ClusterMgr::Node node= theFacade->theClusterMgr->getNodeInfo(nodeId); 00766 if(node.connected) 00767 version= node.m_info.m_version; 00768 *address= get_connect_address(nodeId); 00769 } 00770 else if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_API || 00771 getNodeType(nodeId) == NDB_MGM_NODE_TYPE_MGM) 00772 { 00773 return sendVersionReq(nodeId, version, address); 00774 } 00775 00776 return 0; 00777 } 00778 00779 int 00780 MgmtSrvr::sendVersionReq(int v_nodeId, Uint32 &version, const char **address) 00781 { 00782 SignalSender ss(theFacade); 00783 ss.lock(); 00784 00785 SimpleSignal ssig; 00786 ApiVersionReq* req = CAST_PTR(ApiVersionReq, ssig.getDataPtrSend()); 00787 req->senderRef = ss.getOwnRef(); 00788 req->nodeId = v_nodeId; 00789 ssig.set(ss, TestOrd::TraceAPI, QMGR, GSN_API_VERSION_REQ, 00790 ApiVersionReq::SignalLength); 00791 00792 int do_send = 1; 00793 NodeId nodeId; 00794 00795 while (1) 00796 { 00797 if (do_send) 00798 { 00799 bool next; 00800 nodeId = 0; 00801 00802 while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true && 00803 okToSendTo(nodeId, true) != 0); 00804 00805 const ClusterMgr::Node &node= 00806 theFacade->theClusterMgr->getNodeInfo(nodeId); 00807 if(next && node.m_state.startLevel != NodeState::SL_STARTED) 00808 { 00809 NodeId tmp=nodeId; 00810 while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true && 00811 okToSendTo(nodeId, true) != 0); 00812 if(!next) 00813 nodeId= tmp; 00814 } 00815 00816 if(!next) return NO_CONTACT_WITH_DB_NODES; 00817 00818 if (ss.sendSignal(nodeId, &ssig) != SEND_OK) { 00819 return SEND_OR_RECEIVE_FAILED; 00820 } 00821 do_send = 0; 00822 } 00823 00824 SimpleSignal *signal = ss.waitFor(); 00825 00826 int gsn = signal->readSignalNumber(); 00827 switch (gsn) { 00828 case GSN_API_VERSION_CONF: { 00829 const ApiVersionConf * const conf = 00830 CAST_CONSTPTR(ApiVersionConf, signal->getDataPtr()); 00831 assert(conf->nodeId == v_nodeId); 00832 version = conf->version; 00833 struct in_addr in; 00834 in.s_addr= conf->inet_addr; 00835 *address= inet_ntoa(in); 00836 return 0; 00837 } 00838 case GSN_NF_COMPLETEREP:{ 00839 const NFCompleteRep * const rep = 00840 CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr()); 00841 if (rep->failedNodeId == nodeId) 00842 do_send = 1; // retry with other node 00843 continue; 00844 } 00845 case GSN_NODE_FAILREP:{ 00846 const NodeFailRep * const rep = 00847 CAST_CONSTPTR(NodeFailRep, signal->getDataPtr()); 00848 if (NodeBitmask::get(rep->theNodes,nodeId)) 00849 do_send = 1; // retry with other node 00850 continue; 00851 } 00852 default: 00853 report_unknown_signal(signal); 00854 return SEND_OR_RECEIVE_FAILED; 00855 } 00856 break; 00857 } // while(1) 00858 00859 return 0; 00860 } 00861 00862 int MgmtSrvr::sendStopMgmd(NodeId nodeId, 00863 bool abort, 00864 bool stop, 00865 bool restart, 00866 bool nostart, 00867 bool initialStart) 00868 { 00869 const char* hostname; 00870 Uint32 port; 00871 BaseString connect_string; 00872 00873 { 00874 Guard g(m_configMutex); 00875 { 00876 ndb_mgm_configuration_iterator 00877 iter(* _config->m_configValues, CFG_SECTION_NODE); 00878 00879 if(iter.first()) return SEND_OR_RECEIVE_FAILED; 00880 if(iter.find(CFG_NODE_ID, nodeId)) return SEND_OR_RECEIVE_FAILED; 00881 if(iter.get(CFG_NODE_HOST, &hostname)) return SEND_OR_RECEIVE_FAILED; 00882 } 00883 { 00884 ndb_mgm_configuration_iterator 00885 iter(* _config->m_configValues, CFG_SECTION_NODE); 00886 00887 if(iter.first()) return SEND_OR_RECEIVE_FAILED; 00888 if(iter.find(CFG_NODE_ID, nodeId)) return SEND_OR_RECEIVE_FAILED; 00889 if(iter.get(CFG_MGM_PORT, &port)) return SEND_OR_RECEIVE_FAILED; 00890 } 00891 if( strlen(hostname) == 0 ) 00892 return SEND_OR_RECEIVE_FAILED; 00893 } 00894 connect_string.assfmt("%s:%u",hostname,port); 00895 00896 DBUG_PRINT("info",("connect string: %s",connect_string.c_str())); 00897 00898 NdbMgmHandle h= ndb_mgm_create_handle(); 00899 if ( h && connect_string.length() > 0 ) 00900 { 00901 ndb_mgm_set_connectstring(h,connect_string.c_str()); 00902 if(ndb_mgm_connect(h,1,0,0)) 00903 { 00904 DBUG_PRINT("info",("failed ndb_mgm_connect")); 00905 return SEND_OR_RECEIVE_FAILED; 00906 } 00907 if(!restart) 00908 { 00909 if(ndb_mgm_stop(h, 1, (const int*)&nodeId) < 0) 00910 { 00911 return SEND_OR_RECEIVE_FAILED; 00912 } 00913 } 00914 else 00915 { 00916 int nodes[1]; 00917 nodes[0]= (int)nodeId; 00918 if(ndb_mgm_restart2(h, 1, nodes, initialStart, nostart, abort) < 0) 00919 { 00920 return SEND_OR_RECEIVE_FAILED; 00921 } 00922 } 00923 } 00924 ndb_mgm_destroy_handle(&h); 00925 00926 return 0; 00927 } 00928 00929 /* 00930 * Common method for handeling all STOP_REQ signalling that 00931 * is used by Stopping, Restarting and Single user commands 00932 * 00933 * In the event that we need to stop a mgmd, we create a mgm 00934 * client connection to that mgmd and stop it that way. 00935 * This allows us to stop mgm servers when there isn't any real 00936 * distributed communication up. 00937 * 00938 * node_ids.size()==0 means to stop all DB nodes. 00939 * MGM nodes will *NOT* be stopped. 00940 * 00941 * If we work out we should be stopping or restarting ourselves, 00942 * we return <0 in stopSelf for restart, >0 for stop 00943 * and 0 for do nothing. 00944 */ 00945 00946 int MgmtSrvr::sendSTOP_REQ(const Vector<NodeId> &node_ids, 00947 NodeBitmask &stoppedNodes, 00948 Uint32 singleUserNodeId, 00949 bool abort, 00950 bool stop, 00951 bool restart, 00952 bool nostart, 00953 bool initialStart, 00954 int* stopSelf) 00955 { 00956 int error = 0; 00957 DBUG_ENTER("MgmtSrvr::sendSTOP_REQ"); 00958 DBUG_PRINT("enter", ("no of nodes: %d singleUseNodeId: %d " 00959 "abort: %d stop: %d restart: %d " 00960 "nostart: %d initialStart: %d", 00961 node_ids.size(), singleUserNodeId, 00962 abort, stop, restart, nostart, initialStart)); 00963 00964 stoppedNodes.clear(); 00965 00966 SignalSender ss(theFacade); 00967 ss.lock(); // lock will be released on exit 00968 00969 SimpleSignal ssig; 00970 StopReq* const stopReq = CAST_PTR(StopReq, ssig.getDataPtrSend()); 00971 ssig.set(ss, TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ, StopReq::SignalLength); 00972 00973 stopReq->requestInfo = 0; 00974 stopReq->apiTimeout = 5000; 00975 stopReq->transactionTimeout = 1000; 00976 stopReq->readOperationTimeout = 1000; 00977 stopReq->operationTimeout = 1000; 00978 stopReq->senderData = 12; 00979 stopReq->senderRef = ss.getOwnRef(); 00980 if (singleUserNodeId) 00981 { 00982 stopReq->singleuser = 1; 00983 stopReq->singleUserApi = singleUserNodeId; 00984 StopReq::setSystemStop(stopReq->requestInfo, false); 00985 StopReq::setPerformRestart(stopReq->requestInfo, false); 00986 StopReq::setStopAbort(stopReq->requestInfo, false); 00987 } 00988 else 00989 { 00990 stopReq->singleuser = 0; 00991 StopReq::setSystemStop(stopReq->requestInfo, stop); 00992 StopReq::setPerformRestart(stopReq->requestInfo, restart); 00993 StopReq::setStopAbort(stopReq->requestInfo, abort); 00994 StopReq::setNoStart(stopReq->requestInfo, nostart); 00995 StopReq::setInitialStart(stopReq->requestInfo, initialStart); 00996 } 00997 00998 // send the signals 00999 NodeBitmask nodes; 01000 NodeId nodeId= 0; 01001 int use_master_node= 0; 01002 int do_send= 0; 01003 *stopSelf= 0; 01004 NdbNodeBitmask nodes_to_stop; 01005 { 01006 for (unsigned i= 0; i < node_ids.size(); i++) 01007 { 01008 nodeId= node_ids[i]; 01009 ndbout << "asked to stop " << nodeId << endl; 01010 if (getNodeType(nodeId) != NDB_MGM_NODE_TYPE_MGM) 01011 nodes_to_stop.set(nodeId); 01012 else if (nodeId != getOwnNodeId()) 01013 { 01014 error= sendStopMgmd(nodeId, abort, stop, restart, 01015 nostart, initialStart); 01016 if (error == 0) 01017 stoppedNodes.set(nodeId); 01018 } 01019 else 01020 { 01021 ndbout << "which is me" << endl; 01022 *stopSelf= (restart)? -1 : 1; 01023 stoppedNodes.set(nodeId); 01024 } 01025 } 01026 } 01027 int no_of_nodes_to_stop= nodes_to_stop.count(); 01028 if (node_ids.size()) 01029 { 01030 if (no_of_nodes_to_stop) 01031 { 01032 do_send= 1; 01033 if (no_of_nodes_to_stop == 1) 01034 { 01035 nodeId= nodes_to_stop.find(0); 01036 } 01037 else // multi node stop, send to master 01038 { 01039 use_master_node= 1; 01040 nodes_to_stop.copyto(NdbNodeBitmask::Size, stopReq->nodes); 01041 StopReq::setStopNodes(stopReq->requestInfo, 1); 01042 } 01043 } 01044 } 01045 else 01046 { 01047 nodeId= 0; 01048 while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) 01049 { 01050 if(okToSendTo(nodeId, true) == 0) 01051 { 01052 SendStatus result = ss.sendSignal(nodeId, &ssig); 01053 if (result == SEND_OK) 01054 nodes.set(nodeId); 01055 } 01056 } 01057 } 01058 01059 // now wait for the replies 01060 while (!nodes.isclear() || do_send) 01061 { 01062 if (do_send) 01063 { 01064 int r; 01065 assert(nodes.count() == 0); 01066 if (use_master_node) 01067 nodeId= m_master_node; 01068 if ((r= okToSendTo(nodeId, true)) != 0) 01069 { 01070 bool next; 01071 if (!use_master_node) 01072 DBUG_RETURN(r); 01073 m_master_node= nodeId= 0; 01074 while((next= getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true && 01075 (r= okToSendTo(nodeId, true)) != 0); 01076 if (!next) 01077 DBUG_RETURN(NO_CONTACT_WITH_DB_NODES); 01078 } 01079 if (ss.sendSignal(nodeId, &ssig) != SEND_OK) 01080 DBUG_RETURN(SEND_OR_RECEIVE_FAILED); 01081 nodes.set(nodeId); 01082 do_send= 0; 01083 } 01084 SimpleSignal *signal = ss.waitFor(); 01085 int gsn = signal->readSignalNumber(); 01086 switch (gsn) { 01087 case GSN_STOP_REF:{ 01088 const StopRef * const ref = CAST_CONSTPTR(StopRef, signal->getDataPtr()); 01089 const NodeId nodeId = refToNode(signal->header.theSendersBlockRef); 01090 #ifdef VM_TRACE 01091 ndbout_c("Node %d refused stop", nodeId); 01092 #endif 01093 assert(nodes.get(nodeId)); 01094 nodes.clear(nodeId); 01095 if (ref->errorCode == StopRef::MultiNodeShutdownNotMaster) 01096 { 01097 assert(use_master_node); 01098 m_master_node= ref->masterNodeId; 01099 do_send= 1; 01100 continue; 01101 } 01102 error = translateStopRef(ref->errorCode); 01103 break; 01104 } 01105 case GSN_STOP_CONF:{ 01106 const StopConf * const ref = CAST_CONSTPTR(StopConf, signal->getDataPtr()); 01107 const NodeId nodeId = refToNode(signal->header.theSendersBlockRef); 01108 #ifdef VM_TRACE 01109 ndbout_c("Node %d single user mode", nodeId); 01110 #endif 01111 assert(nodes.get(nodeId)); 01112 if (singleUserNodeId != 0) 01113 { 01114 stoppedNodes.set(nodeId); 01115 } 01116 else 01117 { 01118 assert(no_of_nodes_to_stop > 1); 01119 stoppedNodes.bitOR(nodes_to_stop); 01120 } 01121 nodes.clear(nodeId); 01122 break; 01123 } 01124 case GSN_NF_COMPLETEREP:{ 01125 const NFCompleteRep * const rep = 01126 CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr()); 01127 #ifdef VM_TRACE 01128 ndbout_c("sendSTOP_REQ Node %d fail completed", rep->failedNodeId); 01129 #endif 01130 nodes.clear(rep->failedNodeId); // clear the failed node 01131 if (singleUserNodeId == 0) 01132 stoppedNodes.set(rep->failedNodeId); 01133 break; 01134 } 01135 case GSN_NODE_FAILREP:{ 01136 const NodeFailRep * const rep = 01137 CAST_CONSTPTR(NodeFailRep, signal->getDataPtr()); 01138 break; 01139 } 01140 default: 01141 report_unknown_signal(signal); 01142 #ifdef VM_TRACE 01143 ndbout_c("Unknown signal %d", gsn); 01144 #endif 01145 DBUG_RETURN(SEND_OR_RECEIVE_FAILED); 01146 } 01147 } 01148 if (error && *stopSelf) 01149 { 01150 *stopSelf= 0; 01151 } 01152 DBUG_RETURN(error); 01153 } 01154 01155 /* 01156 * Stop one nodes 01157 */ 01158 01159 int MgmtSrvr::stopNodes(const Vector<NodeId> &node_ids, 01160 int *stopCount, bool abort, int* stopSelf) 01161 { 01162 if (!abort) 01163 { 01164 NodeId nodeId = 0; 01165 ClusterMgr::Node node; 01166 while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) 01167 { 01168 node = theFacade->theClusterMgr->getNodeInfo(nodeId); 01169 if((node.m_state.startLevel != NodeState::SL_STARTED) && 01170 (node.m_state.startLevel != NodeState::SL_NOTHING)) 01171 return OPERATION_NOT_ALLOWED_START_STOP; 01172 } 01173 } 01174 NodeBitmask nodes; 01175 int ret= sendSTOP_REQ(node_ids, 01176 nodes, 01177 0, 01178 abort, 01179 false, 01180 false, 01181 false, 01182 false, 01183 stopSelf); 01184 if (stopCount) 01185 *stopCount= nodes.count(); 01186 return ret; 01187 } 01188 01189 int MgmtSrvr::shutdownMGM(int *stopCount, bool abort, int *stopSelf) 01190 { 01191 NodeId nodeId = 0; 01192 int error; 01193 01194 while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_MGM)) 01195 { 01196 if(nodeId==getOwnNodeId()) 01197 continue; 01198 error= sendStopMgmd(nodeId, abort, true, false, 01199 false, false); 01200 if (error == 0) 01201 *stopCount++; 01202 } 01203 01204 *stopSelf= 1; 01205 *stopCount++; 01206 01207 return 0; 01208 } 01209 01210 /* 01211 * Perform DB nodes shutdown. 01212 * MGM servers are left in their current state 01213 */ 01214 01215 int MgmtSrvr::shutdownDB(int * stopCount, bool abort) 01216 { 01217 NodeBitmask nodes; 01218 Vector<NodeId> node_ids; 01219 01220 int tmp; 01221 01222 int ret = sendSTOP_REQ(node_ids, 01223 nodes, 01224 0, 01225 abort, 01226 true, 01227 false, 01228 false, 01229 false, 01230 &tmp); 01231 if (stopCount) 01232 *stopCount = nodes.count(); 01233 return ret; 01234 } 01235 01236 /* 01237 * Enter single user mode on all live nodes 01238 */ 01239 01240 int MgmtSrvr::enterSingleUser(int * stopCount, Uint32 singleUserNodeId) 01241 { 01242 if (getNodeType(singleUserNodeId) != NDB_MGM_NODE_TYPE_API) 01243 return NODE_NOT_API_NODE; 01244 NodeId nodeId = 0; 01245 ClusterMgr::Node node; 01246 while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) 01247 { 01248 node = theFacade->theClusterMgr->getNodeInfo(nodeId); 01249 if((node.m_state.startLevel != NodeState::SL_STARTED) && 01250 (node.m_state.startLevel != NodeState::SL_NOTHING)) 01251 return OPERATION_NOT_ALLOWED_START_STOP; 01252 } 01253 NodeBitmask nodes; 01254 Vector<NodeId> node_ids; 01255 int stopSelf; 01256 int ret = sendSTOP_REQ(node_ids, 01257 nodes, 01258 singleUserNodeId, 01259 false, 01260 false, 01261 false, 01262 false, 01263 false, 01264 &stopSelf); 01265 if (stopCount) 01266 *stopCount = nodes.count(); 01267 return ret; 01268 } 01269 01270 /* 01271 * Perform node restart 01272 */ 01273 01274 int MgmtSrvr::restartNodes(const Vector<NodeId> &node_ids, 01275 int * stopCount, bool nostart, 01276 bool initialStart, bool abort, 01277 int *stopSelf) 01278 { 01279 NodeBitmask nodes; 01280 int ret= sendSTOP_REQ(node_ids, 01281 nodes, 01282 0, 01283 abort, 01284 false, 01285 true, 01286 true, 01287 initialStart, 01288 stopSelf); 01289 01290 if (ret) 01291 return ret; 01292 01293 if (stopCount) 01294 *stopCount = nodes.count(); 01295 01296 // start up the nodes again 01297 int waitTime = 12000; 01298 NDB_TICKS maxTime = NdbTick_CurrentMillisecond() + waitTime; 01299 for (unsigned i = 0; i < node_ids.size(); i++) 01300 { 01301 NodeId nodeId= node_ids[i]; 01302 enum ndb_mgm_node_status s; 01303 s = NDB_MGM_NODE_STATUS_NO_CONTACT; 01304 #ifdef VM_TRACE 01305 ndbout_c("Waiting for %d not started", nodeId); 01306 #endif 01307 while (s != NDB_MGM_NODE_STATUS_NOT_STARTED && waitTime > 0) 01308 { 01309 Uint32 startPhase = 0, version = 0, dynamicId = 0, nodeGroup = 0; 01310 Uint32 connectCount = 0; 01311 bool system; 01312 const char *address; 01313 status(nodeId, &s, &version, &startPhase, 01314 &system, &dynamicId, &nodeGroup, &connectCount, &address); 01315 NdbSleep_MilliSleep(100); 01316 waitTime = (maxTime - NdbTick_CurrentMillisecond()); 01317 } 01318 } 01319 01320 if (nostart) 01321 return 0; 01322 01323 for (unsigned i = 0; i < node_ids.size(); i++) 01324 { 01325 int result = start(node_ids[i]); 01326 } 01327 return 0; 01328 } 01329 01330 /* 01331 * Perform restart of all DB nodes 01332 */ 01333 01334 int MgmtSrvr::restartDB(bool nostart, bool initialStart, 01335 bool abort, int * stopCount) 01336 { 01337 NodeBitmask nodes; 01338 Vector<NodeId> node_ids; 01339 int tmp; 01340 01341 int ret = sendSTOP_REQ(node_ids, 01342 nodes, 01343 0, 01344 abort, 01345 true, 01346 true, 01347 true, 01348 initialStart, 01349 &tmp); 01350 01351 if (ret) 01352 return ret; 01353 01354 if (stopCount) 01355 *stopCount = nodes.count(); 01356 01357 #ifdef VM_TRACE 01358 ndbout_c("Stopped %d nodes", nodes.count()); 01359 #endif 01360 01364 int waitTime = 12000; 01365 NodeId nodeId = 0; 01366 NDB_TICKS maxTime = NdbTick_CurrentMillisecond() + waitTime; 01367 01368 ndbout_c(" %d", nodes.get(1)); 01369 ndbout_c(" %d", nodes.get(2)); 01370 01371 while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) { 01372 if (!nodes.get(nodeId)) 01373 continue; 01374 enum ndb_mgm_node_status s; 01375 s = NDB_MGM_NODE_STATUS_NO_CONTACT; 01376 #ifdef VM_TRACE 01377 ndbout_c("Waiting for %d not started", nodeId); 01378 #endif 01379 while (s != NDB_MGM_NODE_STATUS_NOT_STARTED && waitTime > 0) { 01380 Uint32 startPhase = 0, version = 0, dynamicId = 0, nodeGroup = 0; 01381 Uint32 connectCount = 0; 01382 bool system; 01383 const char *address; 01384 status(nodeId, &s, &version, &startPhase, 01385 &system, &dynamicId, &nodeGroup, &connectCount, &address); 01386 NdbSleep_MilliSleep(100); 01387 waitTime = (maxTime - NdbTick_CurrentMillisecond()); 01388 } 01389 } 01390 01391 if(nostart) 01392 return 0; 01393 01398 nodeId = 0; 01399 while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) { 01400 if (!nodes.get(nodeId)) 01401 continue; 01402 int result; 01403 result = start(nodeId); 01404 DEBUG("Starting node " << nodeId << " with result " << result); 01411 } 01412 01413 return 0; 01414 } 01415 01416 int 01417 MgmtSrvr::exitSingleUser(int * stopCount, bool abort) 01418 { 01419 NodeId nodeId = 0; 01420 int count = 0; 01421 01422 SignalSender ss(theFacade); 01423 ss.lock(); // lock will be released on exit 01424 01425 SimpleSignal ssig; 01426 ResumeReq* const resumeReq = 01427 CAST_PTR(ResumeReq, ssig.getDataPtrSend()); 01428 ssig.set(ss,TestOrd::TraceAPI, NDBCNTR, GSN_RESUME_REQ, 01429 ResumeReq::SignalLength); 01430 resumeReq->senderData = 12; 01431 resumeReq->senderRef = ss.getOwnRef(); 01432 01433 while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)){ 01434 if(okToSendTo(nodeId, true) == 0){ 01435 SendStatus result = ss.sendSignal(nodeId, &ssig); 01436 if (result == SEND_OK) 01437 count++; 01438 } 01439 } 01440 01441 if(stopCount != 0) 01442 * stopCount = count; 01443 01444 return 0; 01445 } 01446 01447 /***************************************************************************** 01448 * Status 01449 ****************************************************************************/ 01450 01451 #include <ClusterMgr.hpp> 01452 01453 int 01454 MgmtSrvr::status(int nodeId, 01455 ndb_mgm_node_status * _status, 01456 Uint32 * version, 01457 Uint32 * _phase, 01458 bool * _system, 01459 Uint32 * dynamic, 01460 Uint32 * nodegroup, 01461 Uint32 * connectCount, 01462 const char **address) 01463 { 01464 if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_API || 01465 getNodeType(nodeId) == NDB_MGM_NODE_TYPE_MGM) { 01466 versionNode(nodeId, *version, address); 01467 } else { 01468 *address= get_connect_address(nodeId); 01469 } 01470 01471 const ClusterMgr::Node node = 01472 theFacade->theClusterMgr->getNodeInfo(nodeId); 01473 01474 if(!node.connected){ 01475 * _status = NDB_MGM_NODE_STATUS_NO_CONTACT; 01476 return 0; 01477 } 01478 01479 if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_NDB) { 01480 * version = node.m_info.m_version; 01481 } 01482 01483 * dynamic = node.m_state.dynamicId; 01484 * nodegroup = node.m_state.nodeGroup; 01485 * connectCount = node.m_info.m_connectCount; 01486 01487 switch(node.m_state.startLevel){ 01488 case NodeState::SL_CMVMI: 01489 * _status = NDB_MGM_NODE_STATUS_NOT_STARTED; 01490 * _phase = 0; 01491 return 0; 01492 break; 01493 case NodeState::SL_STARTING: 01494 * _status = NDB_MGM_NODE_STATUS_STARTING; 01495 * _phase = node.m_state.starting.startPhase; 01496 return 0; 01497 break; 01498 case NodeState::SL_STARTED: 01499 * _status = NDB_MGM_NODE_STATUS_STARTED; 01500 * _phase = 0; 01501 return 0; 01502 break; 01503 case NodeState::SL_STOPPING_1: 01504 * _status = NDB_MGM_NODE_STATUS_SHUTTING_DOWN; 01505 * _phase = 1; 01506 * _system = node.m_state.stopping.systemShutdown != 0; 01507 return 0; 01508 break; 01509 case NodeState::SL_STOPPING_2: 01510 * _status = NDB_MGM_NODE_STATUS_SHUTTING_DOWN; 01511 * _phase = 2; 01512 * _system = node.m_state.stopping.systemShutdown != 0; 01513 return 0; 01514 break; 01515 case NodeState::SL_STOPPING_3: 01516 * _status = NDB_MGM_NODE_STATUS_SHUTTING_DOWN; 01517 * _phase = 3; 01518 * _system = node.m_state.stopping.systemShutdown != 0; 01519 return 0; 01520 break; 01521 case NodeState::SL_STOPPING_4: 01522 * _status = NDB_MGM_NODE_STATUS_SHUTTING_DOWN; 01523 * _phase = 4; 01524 * _system = node.m_state.stopping.systemShutdown != 0; 01525 return 0; 01526 break; 01527 case NodeState::SL_SINGLEUSER: 01528 * _status = NDB_MGM_NODE_STATUS_SINGLEUSER; 01529 * _phase = 0; 01530 return 0; 01531 break; 01532 default: 01533 * _status = NDB_MGM_NODE_STATUS_UNKNOWN; 01534 * _phase = 0; 01535 return 0; 01536 } 01537 01538 return -1; 01539 } 01540 01541 int 01542 MgmtSrvr::setEventReportingLevelImpl(int nodeId, 01543 const EventSubscribeReq& ll) 01544 { 01545 SignalSender ss(theFacade); 01546 ss.lock(); 01547 01548 SimpleSignal ssig; 01549 EventSubscribeReq * dst = 01550 CAST_PTR(EventSubscribeReq, ssig.getDataPtrSend()); 01551 ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_EVENT_SUBSCRIBE_REQ, 01552 EventSubscribeReq::SignalLength); 01553 *dst = ll; 01554 01555 NodeBitmask nodes; 01556 nodes.clear(); 01557 Uint32 max = (nodeId == 0) ? (nodeId = 1, MAX_NDB_NODES) : nodeId; 01558 for(; nodeId <= max; nodeId++) 01559 { 01560 if (nodeTypes[nodeId] != NODE_TYPE_DB) 01561 continue; 01562 if (okToSendTo(nodeId, true)) 01563 continue; 01564 if (ss.sendSignal(nodeId, &ssig) == SEND_OK) 01565 { 01566 nodes.set(nodeId); 01567 } 01568 } 01569 01570 int error = 0; 01571 while (!nodes.isclear()) 01572 { 01573 SimpleSignal *signal = ss.waitFor(); 01574 int gsn = signal->readSignalNumber(); 01575 nodeId = refToNode(signal->header.theSendersBlockRef); 01576 switch (gsn) { 01577 case GSN_EVENT_SUBSCRIBE_CONF:{ 01578 nodes.clear(nodeId); 01579 break; 01580 } 01581 case GSN_EVENT_SUBSCRIBE_REF:{ 01582 nodes.clear(nodeId); 01583 error = 1; 01584 break; 01585 } 01586 case GSN_NF_COMPLETEREP:{ 01587 const NFCompleteRep * const rep = 01588 CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr()); 01589 nodes.clear(rep->failedNodeId); 01590 break; 01591 } 01592 case GSN_NODE_FAILREP:{ 01593 // ignore, NF_COMPLETEREP will arrive later 01594 break; 01595 } 01596 default: 01597 report_unknown_signal(signal); 01598 return SEND_OR_RECEIVE_FAILED; 01599 } 01600 } 01601 if (error) 01602 return SEND_OR_RECEIVE_FAILED; 01603 return 0; 01604 } 01605 01606 //**************************************************************************** 01607 //**************************************************************************** 01608 int 01609 MgmtSrvr::setNodeLogLevelImpl(int nodeId, const SetLogLevelOrd & ll) 01610 { 01611 INIT_SIGNAL_SENDER(ss,nodeId); 01612 01613 SimpleSignal ssig; 01614 ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_SET_LOGLEVELORD, 01615 SetLogLevelOrd::SignalLength); 01616 SetLogLevelOrd* const dst = CAST_PTR(SetLogLevelOrd, ssig.getDataPtrSend()); 01617 *dst = ll; 01618 01619 return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED; 01620 } 01621 01622 //**************************************************************************** 01623 //**************************************************************************** 01624 01625 int 01626 MgmtSrvr::insertError(int nodeId, int errorNo) 01627 { 01628 if (errorNo < 0) { 01629 return INVALID_ERROR_NUMBER; 01630 } 01631 01632 INIT_SIGNAL_SENDER(ss,nodeId); 01633 01634 SimpleSignal ssig; 01635 ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TAMPER_ORD, 01636 TamperOrd::SignalLength); 01637 TamperOrd* const tamperOrd = CAST_PTR(TamperOrd, ssig.getDataPtrSend()); 01638 tamperOrd->errorNo = errorNo; 01639 01640 return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED; 01641 } 01642 01643 01644 01645 //**************************************************************************** 01646 //**************************************************************************** 01647 01648 int 01649 MgmtSrvr::setTraceNo(int nodeId, int traceNo) 01650 { 01651 if (traceNo < 0) { 01652 return INVALID_TRACE_NUMBER; 01653 } 01654 01655 INIT_SIGNAL_SENDER(ss,nodeId); 01656 01657 SimpleSignal ssig; 01658 ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength); 01659 TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend()); 01660 testOrd->clear(); 01661 // Assume TRACE command causes toggling. Not really defined... ? TODO 01662 testOrd->setTraceCommand(TestOrd::Toggle, 01663 (TestOrd::TraceSpecification)traceNo); 01664 01665 return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED; 01666 } 01667 01668 //**************************************************************************** 01669 //**************************************************************************** 01670 01671 int 01672 MgmtSrvr::getBlockNumber(const BaseString &blockName) 01673 { 01674 short bno = getBlockNo(blockName.c_str()); 01675 if(bno != 0) 01676 return bno; 01677 return -1; 01678 } 01679 01680 //**************************************************************************** 01681 //**************************************************************************** 01682 01683 int 01684 MgmtSrvr::setSignalLoggingMode(int nodeId, LogMode mode, 01685 const Vector<BaseString>& blocks) 01686 { 01687 INIT_SIGNAL_SENDER(ss,nodeId); 01688 01689 // Convert from MgmtSrvr format... 01690 01691 TestOrd::Command command; 01692 if (mode == Off) { 01693 command = TestOrd::Off; 01694 } 01695 else { 01696 command = TestOrd::On; 01697 } 01698 01699 TestOrd::SignalLoggerSpecification logSpec; 01700 switch (mode) { 01701 case In: 01702 logSpec = TestOrd::InputSignals; 01703 break; 01704 case Out: 01705 logSpec = TestOrd::OutputSignals; 01706 break; 01707 case InOut: 01708 logSpec = TestOrd::InputOutputSignals; 01709 break; 01710 case Off: 01711 // In MgmtSrvr interface it's just possible to switch off all logging, both 01712 // "in" and "out" (this should probably be changed). 01713 logSpec = TestOrd::InputOutputSignals; 01714 break; 01715 default: 01716 ndbout_c("Unexpected value %d, MgmtSrvr::setSignalLoggingMode, line %d", 01717 (unsigned)mode, __LINE__); 01718 assert(false); 01719 return -1; 01720 } 01721 01722 SimpleSignal ssig; 01723 ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength); 01724 01725 TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend()); 01726 testOrd->clear(); 01727 01728 if (blocks.size() == 0 || blocks[0] == "ALL") { 01729 // Logg command for all blocks 01730 testOrd->addSignalLoggerCommand(command, logSpec); 01731 } else { 01732 for(unsigned i = 0; i < blocks.size(); i++){ 01733 int blockNumber = getBlockNumber(blocks[i]); 01734 if (blockNumber == -1) { 01735 return INVALID_BLOCK_NAME; 01736 } 01737 testOrd->addSignalLoggerCommand(blockNumber, command, logSpec); 01738 } // for 01739 } // else 01740 01741 return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED; 01742 } 01743 01744 /***************************************************************************** 01745 * Signal tracing 01746 *****************************************************************************/ 01747 int MgmtSrvr::startSignalTracing(int nodeId) 01748 { 01749 INIT_SIGNAL_SENDER(ss,nodeId); 01750 01751 SimpleSignal ssig; 01752 ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength); 01753 01754 TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend()); 01755 testOrd->clear(); 01756 testOrd->setTestCommand(TestOrd::On); 01757 01758 return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED; 01759 } 01760 01761 int 01762 MgmtSrvr::stopSignalTracing(int nodeId) 01763 { 01764 INIT_SIGNAL_SENDER(ss,nodeId); 01765 01766 SimpleSignal ssig; 01767 ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength); 01768 TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend()); 01769 testOrd->clear(); 01770 testOrd->setTestCommand(TestOrd::Off); 01771 01772 return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED; 01773 } 01774 01775 01776 /***************************************************************************** 01777 * Dump state 01778 *****************************************************************************/ 01779 01780 int 01781 MgmtSrvr::dumpState(int nodeId, const char* args) 01782 { 01783 // Convert the space separeted args 01784 // string to an int array 01785 Uint32 args_array[25]; 01786 Uint32 numArgs = 0; 01787 01788 char buf[10]; 01789 int b = 0; 01790 memset(buf, 0, 10); 01791 for (size_t i = 0; i <= strlen(args); i++){ 01792 if (args[i] == ' ' || args[i] == 0){ 01793 args_array[numArgs] = atoi(buf); 01794 numArgs++; 01795 memset(buf, 0, 10); 01796 b = 0; 01797 } else { 01798 buf[b] = args[i]; 01799 b++; 01800 } 01801 } 01802 01803 return dumpState(nodeId, args_array, numArgs); 01804 } 01805 01806 int 01807 MgmtSrvr::dumpState(int nodeId, const Uint32 args[], Uint32 no) 01808 { 01809 INIT_SIGNAL_SENDER(ss,nodeId); 01810 01811 const Uint32 len = no > 25 ? 25 : no; 01812 01813 SimpleSignal ssig; 01814 DumpStateOrd * const dumpOrd = 01815 CAST_PTR(DumpStateOrd, ssig.getDataPtrSend()); 01816 ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_DUMP_STATE_ORD, len); 01817 for(Uint32 i = 0; i<25; i++){ 01818 if (i < len) 01819 dumpOrd->args[i] = args[i]; 01820 else 01821 dumpOrd->args[i] = 0; 01822 } 01823 01824 return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED; 01825 } 01826 01827 01828 //**************************************************************************** 01829 //**************************************************************************** 01830 01831 const char* MgmtSrvr::getErrorText(int errorCode, char *buf, int buf_sz) 01832 { 01833 01834 for (int i = 0; i < noOfErrorCodes; ++i) { 01835 if (errorCode == errorTable[i]._errorCode) { 01836 BaseString::snprintf(buf, buf_sz, errorTable[i]._errorText); 01837 buf[buf_sz-1]= 0; 01838 return buf; 01839 } 01840 } 01841 01842 ndb_error_string(errorCode, buf, buf_sz); 01843 buf[buf_sz-1]= 0; 01844 01845 return buf; 01846 } 01847 01848 void 01849 MgmtSrvr::handleReceivedSignal(NdbApiSignal* signal) 01850 { 01851 // The way of handling a received signal is taken from the Ndb class. 01852 int gsn = signal->readSignalNumber(); 01853 01854 switch (gsn) { 01855 case GSN_EVENT_SUBSCRIBE_CONF: 01856 break; 01857 case GSN_EVENT_SUBSCRIBE_REF: 01858 break; 01859 case GSN_EVENT_REP: 01860 { 01861 eventReport(signal->getDataPtr()); 01862 break; 01863 } 01864 01865 case GSN_NF_COMPLETEREP: 01866 break; 01867 case GSN_NODE_FAILREP: 01868 break; 01869 01870 default: 01871 g_eventLogger.error("Unknown signal received. SignalNumber: " 01872 "%i from (%d, %x)", 01873 gsn, 01874 refToNode(signal->theSendersBlockRef), 01875 refToBlock(signal->theSendersBlockRef)); 01876 } 01877 01878 if (theWaitState == NO_WAIT) { 01879 NdbCondition_Signal(theMgmtWaitForResponseCondPtr); 01880 } 01881 } 01882 01883 void 01884 MgmtSrvr::handleStatus(NodeId nodeId, bool alive, bool nfComplete) 01885 { 01886 DBUG_ENTER("MgmtSrvr::handleStatus"); 01887 Uint32 theData[25]; 01888 EventReport *rep = (EventReport *)theData; 01889 01890 theData[1] = nodeId; 01891 if (alive) { 01892 m_started_nodes.push_back(nodeId); 01893 rep->setEventType(NDB_LE_Connected); 01894 } else { 01895 rep->setEventType(NDB_LE_Connected); 01896 if(nfComplete) 01897 { 01898 DBUG_VOID_RETURN; 01899 } 01900 } 01901 rep->setNodeId(_ownNodeId); 01902 eventReport(theData); 01903 DBUG_VOID_RETURN; 01904 } 01905 01906 //**************************************************************************** 01907 //**************************************************************************** 01908 01909 void 01910 MgmtSrvr::signalReceivedNotification(void* mgmtSrvr, 01911 NdbApiSignal* signal, 01912 LinearSectionPtr ptr[3]) 01913 { 01914 ((MgmtSrvr*)mgmtSrvr)->handleReceivedSignal(signal); 01915 } 01916 01917 01918 //**************************************************************************** 01919 //**************************************************************************** 01920 void 01921 MgmtSrvr::nodeStatusNotification(void* mgmSrv, Uint32 nodeId, 01922 bool alive, bool nfComplete) 01923 { 01924 DBUG_ENTER("MgmtSrvr::nodeStatusNotification"); 01925 DBUG_PRINT("enter",("nodeid= %d, alive= %d, nfComplete= %d", nodeId, alive, nfComplete)); 01926 ((MgmtSrvr*)mgmSrv)->handleStatus(nodeId, alive, nfComplete); 01927 DBUG_VOID_RETURN; 01928 } 01929 01930 enum ndb_mgm_node_type 01931 MgmtSrvr::getNodeType(NodeId nodeId) const 01932 { 01933 if(nodeId >= MAX_NODES) 01934 return (enum ndb_mgm_node_type)-1; 01935 01936 return nodeTypes[nodeId]; 01937 } 01938 01939 const char *MgmtSrvr::get_connect_address(Uint32 node_id) 01940 { 01941 if (m_connect_address[node_id].s_addr == 0 && 01942 theFacade && theFacade->theTransporterRegistry && 01943 theFacade->theClusterMgr && 01944 getNodeType(node_id) == NDB_MGM_NODE_TYPE_NDB) 01945 { 01946 const ClusterMgr::Node &node= 01947 theFacade->theClusterMgr->getNodeInfo(node_id); 01948 if (node.connected) 01949 { 01950 m_connect_address[node_id]= 01951 theFacade->theTransporterRegistry->get_connect_address(node_id); 01952 } 01953 } 01954 return inet_ntoa(m_connect_address[node_id]); 01955 } 01956 01957 void 01958 MgmtSrvr::get_connected_nodes(NodeBitmask &connected_nodes) const 01959 { 01960 if (theFacade && theFacade->theClusterMgr) 01961 { 01962 for(Uint32 i = 0; i < MAX_NODES; i++) 01963 { 01964 if (getNodeType(i) == NDB_MGM_NODE_TYPE_NDB) 01965 { 01966 const ClusterMgr::Node &node= theFacade->theClusterMgr->getNodeInfo(i); 01967 connected_nodes.bitOR(node.m_state.m_connected_nodes); 01968 } 01969 } 01970 } 01971 } 01972 01973 int 01974 MgmtSrvr::alloc_node_id_req(NodeId free_node_id, enum ndb_mgm_node_type type) 01975 { 01976 SignalSender ss(theFacade); 01977 ss.lock(); // lock will be released on exit 01978 01979 SimpleSignal ssig; 01980 AllocNodeIdReq* req = CAST_PTR(AllocNodeIdReq, ssig.getDataPtrSend()); 01981 ssig.set(ss, TestOrd::TraceAPI, QMGR, GSN_ALLOC_NODEID_REQ, 01982 AllocNodeIdReq::SignalLength); 01983 01984 req->senderRef = ss.getOwnRef(); 01985 req->senderData = 19; 01986 req->nodeId = free_node_id; 01987 req->nodeType = type; 01988 01989 int do_send = 1; 01990 NodeId nodeId = 0; 01991 while (1) 01992 { 01993 if (nodeId == 0) 01994 { 01995 bool next; 01996 while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true && 01997 theFacade->get_node_alive(nodeId) == false); 01998 if (!next) 01999 return NO_CONTACT_WITH_DB_NODES; 02000 do_send = 1; 02001 } 02002 if (do_send) 02003 { 02004 if (ss.sendSignal(nodeId, &ssig) != SEND_OK) { 02005 return SEND_OR_RECEIVE_FAILED; 02006 } 02007 do_send = 0; 02008 } 02009 02010 SimpleSignal *signal = ss.waitFor(); 02011 02012 int gsn = signal->readSignalNumber(); 02013 switch (gsn) { 02014 case GSN_ALLOC_NODEID_CONF: 02015 { 02016 const AllocNodeIdConf * const conf = 02017 CAST_CONSTPTR(AllocNodeIdConf, signal->getDataPtr()); 02018 return 0; 02019 } 02020 case GSN_ALLOC_NODEID_REF: 02021 { 02022 const AllocNodeIdRef * const ref = 02023 CAST_CONSTPTR(AllocNodeIdRef, signal->getDataPtr()); 02024 if (ref->errorCode == AllocNodeIdRef::NotMaster || 02025 ref->errorCode == AllocNodeIdRef::Busy) 02026 { 02027 do_send = 1; 02028 nodeId = refToNode(ref->masterRef); 02029 continue; 02030 } 02031 return ref->errorCode; 02032 } 02033 case GSN_NF_COMPLETEREP: 02034 { 02035 const NFCompleteRep * const rep = 02036 CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr()); 02037 #ifdef VM_TRACE 02038 ndbout_c("Node %d fail completed", rep->failedNodeId); 02039 #endif 02040 if (rep->failedNodeId == nodeId) 02041 nodeId = 0; 02042 continue; 02043 } 02044 case GSN_NODE_FAILREP:{ 02045 // ignore NF_COMPLETEREP will come 02046 continue; 02047 } 02048 default: 02049 report_unknown_signal(signal); 02050 return SEND_OR_RECEIVE_FAILED; 02051 } 02052 } 02053 return 0; 02054 } 02055 02056 bool 02057 MgmtSrvr::alloc_node_id(NodeId * nodeId, 02058 enum ndb_mgm_node_type type, 02059 struct sockaddr *client_addr, 02060 SOCKET_SIZE_TYPE *client_addr_len, 02061 int &error_code, BaseString &error_string, 02062 int log_event) 02063 { 02064 DBUG_ENTER("MgmtSrvr::alloc_node_id"); 02065 DBUG_PRINT("enter", ("nodeid=%d, type=%d, client_addr=%d", 02066 *nodeId, type, client_addr)); 02067 if (g_no_nodeid_checks) { 02068 if (*nodeId == 0) { 02069 error_string.appfmt("no-nodeid-checks set in management server.\n" 02070 "node id must be set explicitly in connectstring"); 02071 error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH; 02072 DBUG_RETURN(false); 02073 } 02074 DBUG_RETURN(true); 02075 } 02076 Guard g(m_node_id_mutex); 02077 int no_mgm= 0; 02078 NodeBitmask connected_nodes(m_reserved_nodes); 02079 get_connected_nodes(connected_nodes); 02080 { 02081 for(Uint32 i = 0; i < MAX_NODES; i++) 02082 if (getNodeType(i) == NDB_MGM_NODE_TYPE_MGM) 02083 no_mgm++; 02084 } 02085 bool found_matching_id= false; 02086 bool found_matching_type= false; 02087 bool found_free_node= false; 02088 unsigned id_found= 0; 02089 const char *config_hostname= 0; 02090 struct in_addr config_addr= {0}; 02091 int r_config_addr= -1; 02092 unsigned type_c= 0; 02093 02094 if(NdbMutex_Lock(m_configMutex)) 02095 { 02096 // should not happen 02097 error_string.appfmt("unable to lock configuration mutex"); 02098 error_code = NDB_MGM_ALLOCID_ERROR; 02099 DBUG_RETURN(false); 02100 } 02101 ndb_mgm_configuration_iterator 02102 iter(* _config->m_configValues, CFG_SECTION_NODE); 02103 for(iter.first(); iter.valid(); iter.next()) { 02104 unsigned tmp= 0; 02105 if(iter.get(CFG_NODE_ID, &tmp)) require(false); 02106 if (*nodeId && *nodeId != tmp) 02107 continue; 02108 found_matching_id= true; 02109 if(iter.get(CFG_TYPE_OF_SECTION, &type_c)) require(false); 02110 if(type_c != (unsigned)type) 02111 continue; 02112 found_matching_type= true; 02113 if (connected_nodes.get(tmp)) 02114 continue; 02115 found_free_node= true; 02116 if(iter.get(CFG_NODE_HOST, &config_hostname)) require(false); 02117 if (config_hostname && config_hostname[0] == 0) 02118 config_hostname= 0; 02119 else if (client_addr) { 02120 // check hostname compatability 02121 const void *tmp_in= &(((sockaddr_in*)client_addr)->sin_addr); 02122 if((r_config_addr= Ndb_getInAddr(&config_addr, config_hostname)) != 0 02123 || memcmp(&config_addr, tmp_in, sizeof(config_addr)) != 0) { 02124 struct in_addr tmp_addr; 02125 if(Ndb_getInAddr(&tmp_addr, "localhost") != 0 02126 || memcmp(&tmp_addr, tmp_in, sizeof(config_addr)) != 0) { 02127 // not localhost 02128 #if 0 02129 ndbout << "MgmtSrvr::getFreeNodeId compare failed for \"" 02130 << config_hostname 02131 << "\" id=" << tmp << endl; 02132 #endif 02133 continue; 02134 } 02135 // connecting through localhost 02136 // check if config_hostname is local 02137 if (!SocketServer::tryBind(0,config_hostname)) { 02138 continue; 02139 } 02140 } 02141 } else { // client_addr == 0 02142 if (!SocketServer::tryBind(0,config_hostname)) { 02143 continue; 02144 } 02145 } 02146 if (*nodeId != 0 || 02147 type != NDB_MGM_NODE_TYPE_MGM || 02148 no_mgm == 1) { // any match is ok 02149 02150 if (config_hostname == 0 && 02151 *nodeId == 0 && 02152 type != NDB_MGM_NODE_TYPE_MGM) 02153 { 02154 if (!id_found) // only set if not set earlier 02155 id_found= tmp; 02156 continue; /* continue looking for a nodeid with specified 02157 * hostname 02158 */ 02159 } 02160 assert(id_found == 0); 02161 id_found= tmp; 02162 break; 02163 } 02164 if (id_found) { // mgmt server may only have one match 02165 error_string.appfmt("Ambiguous node id's %d and %d.\n" 02166 "Suggest specifying node id in connectstring,\n" 02167 "or specifying unique host names in config file.", 02168 id_found, tmp); 02169 NdbMutex_Unlock(m_configMutex); 02170 error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH; 02171 DBUG_RETURN(false); 02172 } 02173 if (config_hostname == 0) { 02174 error_string.appfmt("Ambiguity for node id %d.\n" 02175 "Suggest specifying node id in connectstring,\n" 02176 "or specifying unique host names in config file,\n" 02177 "or specifying just one mgmt server in config file.", 02178 tmp); 02179 error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH; 02180 DBUG_RETURN(false); 02181 } 02182 id_found= tmp; // mgmt server matched, check for more matches 02183 } 02184 NdbMutex_Unlock(m_configMutex); 02185 02186 if (id_found && client_addr != 0) 02187 { 02188 int res = alloc_node_id_req(id_found, type); 02189 unsigned save_id_found = id_found; 02190 switch (res) 02191 { 02192 case 0: 02193 // ok continue 02194 break; 02195 case NO_CONTACT_WITH_DB_NODES: 02196 // ok continue 02197 break; 02198 default: 02199 // something wrong 02200 id_found = 0; 02201 break; 02202 02203 } 02204 if (id_found == 0) 02205 { 02206 char buf[128]; 02207 ndb_error_string(res, buf, sizeof(buf)); 02208 error_string.appfmt("Cluster refused allocation of id %d. Error: %d (%s).", 02209 save_id_found, res, buf); 02210 g_eventLogger.warning("Cluster refused allocation of id %d. " 02211 "Connection from ip %s. " 02212 "Returned error string \"%s\"", save_id_found, 02213 inet_ntoa(((struct sockaddr_in *)(client_addr))->sin_addr), 02214 error_string.c_str()); 02215 DBUG_RETURN(false); 02216 } 02217 } 02218 02219 if (id_found) 02220 { 02221 *nodeId= id_found; 02222 DBUG_PRINT("info", ("allocating node id %d",*nodeId)); 02223 { 02224 int r= 0; 02225 if (client_addr) 02226 m_connect_address[id_found]= 02227 ((struct sockaddr_in *)client_addr)->sin_addr; 02228 else if (config_hostname) 02229 r= Ndb_getInAddr(&(m_connect_address[id_found]), config_hostname); 02230 else { 02231 char name[256]; 02232 r= gethostname(name, sizeof(name)); 02233 if (r == 0) { 02234 name[sizeof(name)-1]= 0; 02235 r= Ndb_getInAddr(&(m_connect_address[id_found]), name); 02236 } 02237 } 02238 if (r) 02239 m_connect_address[id_found].s_addr= 0; 02240 } 02241 m_reserved_nodes.set(id_found); 02242 if (theFacade && id_found != theFacade->ownId()) 02243 { 02247 theFacade->lock_mutex(); 02248 theFacade->doConnect(id_found); 02249 theFacade->unlock_mutex(); 02250 } 02251 02252 char tmp_str[128]; 02253 m_reserved_nodes.getText(tmp_str); 02254 g_eventLogger.info("Mgmt server state: nodeid %d reserved for ip %s, " 02255 "m_reserved_nodes %s.", 02256 id_found, get_connect_address(id_found), tmp_str); 02257 DBUG_RETURN(true); 02258 } 02259 02260 if (found_matching_type && !found_free_node) { 02261 // we have a temporary error which might be due to that 02262 // we have got the latest connect status from db-nodes. Force update. 02263 global_flag_send_heartbeat_now= 1; 02264 } 02265 02266 BaseString type_string, type_c_string; 02267 { 02268 const char *alias, *str; 02269 alias= ndb_mgm_get_node_type_alias_string(type, &str); 02270 type_string.assfmt("%s(%s)", alias, str); 02271 alias= ndb_mgm_get_node_type_alias_string((enum ndb_mgm_node_type)type_c, 02272 &str); 02273 type_c_string.assfmt("%s(%s)", alias, str); 02274 } 02275 02276 if (*nodeId == 0) 02277 { 02278 if (found_matching_id) 02279 { 02280 if (found_matching_type) 02281 { 02282 if (found_free_node) 02283 { 02284 error_string.appfmt("Connection done from wrong host ip %s.", 02285 (client_addr)? 02286 inet_ntoa(((struct sockaddr_in *) 02287 (client_addr))->sin_addr):""); 02288 error_code = NDB_MGM_ALLOCID_ERROR; 02289 } 02290 else 02291 { 02292 error_string.appfmt("No free node id found for %s.", 02293 type_string.c_str()); 02294 error_code = NDB_MGM_ALLOCID_ERROR; 02295 } 02296 } 02297 else 02298 { 02299 error_string.appfmt("No %s node defined in config file.", 02300 type_string.c_str()); 02301 error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH; 02302 } 02303 } 02304 else 02305 { 02306 error_string.append("No nodes defined in config file."); 02307 error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH; 02308 } 02309 } 02310 else 02311 { 02312 if (found_matching_id) 02313 { 02314 if (found_matching_type) 02315 { 02316 if (found_free_node) 02317 { 02318 // have to split these into two since inet_ntoa overwrites itself 02319 error_string.appfmt("Connection with id %d done from wrong host ip %s,", 02320 *nodeId, inet_ntoa(((struct sockaddr_in *) 02321 (client_addr))->sin_addr)); 02322 error_string.appfmt(" expected %s(%s).", config_hostname, 02323 r_config_addr ? 02324 "lookup failed" : inet_ntoa(config_addr)); 02325 error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH; 02326 } 02327 else 02328 { 02329 error_string.appfmt("Id %d already allocated by another node.", 02330 *nodeId); 02331 error_code = NDB_MGM_ALLOCID_ERROR; 02332 } 02333 } 02334 else 02335 { 02336 error_string.appfmt("Id %d configured as %s, connect attempted as %s.", 02337 *nodeId, type_c_string.c_str(), 02338 type_string.c_str()); 02339 error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH; 02340 } 02341 } 02342 else 02343 { 02344 error_string.appfmt("No node defined with id=%d in config file.", 02345 *nodeId); 02346 error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH; 02347 } 02348 } 02349 02350 if (log_event || error_code == NDB_MGM_ALLOCID_CONFIG_MISMATCH) 02351 { 02352 g_eventLogger.warning("Allocate nodeid (%d) failed. Connection from ip %s." 02353 " Returned error string \"%s\"", 02354 *nodeId, 02355 client_addr != 0 02356 ? inet_ntoa(((struct sockaddr_in *) 02357 (client_addr))->sin_addr) 02358 : "<none>", 02359 error_string.c_str()); 02360 02361 NodeBitmask connected_nodes2; 02362 get_connected_nodes(connected_nodes2); 02363 BaseString tmp_connected, tmp_not_connected; 02364 for(Uint32 i = 0; i < MAX_NODES; i++) 02365 { 02366 if (connected_nodes2.get(i)) 02367 { 02368 if (!m_reserved_nodes.get(i)) 02369 tmp_connected.appfmt(" %d", i); 02370 } 02371 else if (m_reserved_nodes.get(i)) 02372 { 02373 tmp_not_connected.appfmt(" %d", i); 02374 } 02375 } 02376 if (tmp_connected.length() > 0) 02377 g_eventLogger.info("Mgmt server state: node id's %s connected but not reserved", 02378 tmp_connected.c_str()); 02379 if (tmp_not_connected.length() > 0) 02380 g_eventLogger.info("Mgmt server state: node id's %s not connected but reserved", 02381 tmp_not_connected.c_str()); 02382 } 02383 DBUG_RETURN(false); 02384 } 02385 02386 bool 02387 MgmtSrvr::getNextNodeId(NodeId * nodeId, enum ndb_mgm_node_type type) const 02388 { 02389 NodeId tmp = * nodeId; 02390 02391 tmp++; 02392 while(nodeTypes[tmp] != type && tmp < MAX_NODES) 02393 tmp++; 02394 02395 if(tmp == MAX_NODES){ 02396 return false; 02397 } 02398 02399 * nodeId = tmp; 02400 return true; 02401 } 02402 02403 #include "Services.hpp" 02404 02405 void 02406 MgmtSrvr::eventReport(const Uint32 * theData) 02407 { 02408 const EventReport * const eventReport = (EventReport *)&theData[0]; 02409 02410 NodeId nodeId = eventReport->getNodeId(); 02411 Ndb_logevent_type type = eventReport->getEventType(); 02412 // Log event 02413 g_eventLogger.log(type, theData, nodeId, 02414 &m_event_listner[0].m_logLevel); 02415 m_event_listner.log(type, theData, nodeId); 02416 } 02417 02418 /*************************************************************************** 02419 * Backup 02420 ***************************************************************************/ 02421 02422 int 02423 MgmtSrvr::startBackup(Uint32& backupId, int waitCompleted) 02424 { 02425 SignalSender ss(theFacade); 02426 ss.lock(); // lock will be released on exit 02427 02428 NodeId nodeId = m_master_node; 02429 if (okToSendTo(nodeId, false) != 0) 02430 { 02431 bool next; 02432 nodeId = m_master_node = 0; 02433 while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true && 02434 okToSendTo(nodeId, false) != 0); 02435 if(!next) 02436 return NO_CONTACT_WITH_DB_NODES; 02437 } 02438 02439 SimpleSignal ssig; 02440 BackupReq* req = CAST_PTR(BackupReq, ssig.getDataPtrSend()); 02441 ssig.set(ss, TestOrd::TraceAPI, BACKUP, GSN_BACKUP_REQ, 02442 BackupReq::SignalLength); 02443 02444 req->senderData = 19; 02445 req->backupDataLen = 0; 02446 assert(waitCompleted < 3); 02447 req->flags = waitCompleted & 0x3; 02448 02449 BackupEvent event; 02450 int do_send = 1; 02451 while (1) { 02452 if (do_send) 02453 { 02454 if (ss.sendSignal(nodeId, &ssig) != SEND_OK) { 02455 return SEND_OR_RECEIVE_FAILED; 02456 } 02457 if (waitCompleted == 0) 02458 return 0; 02459 do_send = 0; 02460 } 02461 SimpleSignal *signal = ss.waitFor(); 02462 02463 int gsn = signal->readSignalNumber(); 02464 switch (gsn) { 02465 case GSN_BACKUP_CONF:{ 02466 const BackupConf * const conf = 02467 CAST_CONSTPTR(BackupConf, signal->getDataPtr()); 02468 event.Event = BackupEvent::BackupStarted; 02469 event.Started.BackupId = conf->backupId; 02470 event.Nodes = conf->nodes; 02471 #ifdef VM_TRACE 02472 ndbout_c("Backup(%d) master is %d", conf->backupId, 02473 refToNode(signal->header.theSendersBlockRef)); 02474 #endif 02475 backupId = conf->backupId; 02476 if (waitCompleted == 1) 02477 return 0; 02478 // wait for next signal 02479 break; 02480 } 02481 case GSN_BACKUP_COMPLETE_REP:{ 02482 const BackupCompleteRep * const rep = 02483 CAST_CONSTPTR(BackupCompleteRep, signal->getDataPtr()); 02484 #ifdef VM_TRACE 02485 ndbout_c("Backup(%d) completed %d", rep->backupId); 02486 #endif 02487 event.Event = BackupEvent::BackupCompleted; 02488 event.Completed.BackupId = rep->backupId; 02489 02490 event.Completed.NoOfBytes = rep->noOfBytesLow; 02491 event.Completed.NoOfLogBytes = rep->noOfLogBytes; 02492 event.Completed.NoOfRecords = rep->noOfRecordsLow; 02493 event.Completed.NoOfLogRecords = rep->noOfLogRecords; 02494 event.Completed.stopGCP = rep->stopGCP; 02495 event.Completed.startGCP = rep->startGCP; 02496 event.Nodes = rep->nodes; 02497 02498 if (signal->header.theLength >= BackupCompleteRep::SignalLength) 02499 { 02500 event.Completed.NoOfBytes += ((Uint64)rep->noOfBytesHigh) << 32; 02501 event.Completed.NoOfRecords += ((Uint64)rep->noOfRecordsHigh) << 32; 02502 } 02503 02504 backupId = rep->backupId; 02505 return 0; 02506 } 02507 case GSN_BACKUP_REF:{ 02508 const BackupRef * const ref = 02509 CAST_CONSTPTR(BackupRef, signal->getDataPtr()); 02510 if(ref->errorCode == BackupRef::IAmNotMaster){ 02511 m_master_node = nodeId = refToNode(ref->masterRef); 02512 #ifdef VM_TRACE 02513 ndbout_c("I'm not master resending to %d", nodeId); 02514 #endif 02515 do_send = 1; // try again 02516 continue; 02517 } 02518 event.Event = BackupEvent::BackupFailedToStart; 02519 event.FailedToStart.ErrorCode = ref->errorCode; 02520 return ref->errorCode; 02521 } 02522 case GSN_BACKUP_ABORT_REP:{ 02523 const BackupAbortRep * const rep = 02524 CAST_CONSTPTR(BackupAbortRep, signal->getDataPtr()); 02525 event.Event = BackupEvent::BackupAborted; 02526 event.Aborted.Reason = rep->reason; 02527 event.Aborted.BackupId = rep->backupId; 02528 event.Aborted.ErrorCode = rep->reason; 02529 #ifdef VM_TRACE 02530 ndbout_c("Backup %d aborted", rep->backupId); 02531 #endif 02532 return rep->reason; 02533 } 02534 case GSN_NF_COMPLETEREP:{ 02535 const NFCompleteRep * const rep = 02536 CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr()); 02537 #ifdef VM_TRACE 02538 ndbout_c("Node %d fail completed", rep->failedNodeId); 02539 #endif 02540 if (rep->failedNodeId == nodeId || 02541 waitCompleted == 1) 02542 return 1326; 02543 // wait for next signal 02544 // master node will report aborted backup 02545 break; 02546 } 02547 case GSN_NODE_FAILREP:{ 02548 const NodeFailRep * const rep = 02549 CAST_CONSTPTR(NodeFailRep, signal->getDataPtr()); 02550 if (NodeBitmask::get(rep->theNodes,nodeId) || 02551 waitCompleted == 1) 02552 return 1326; 02553 // wait for next signal 02554 // master node will report aborted backup 02555 break; 02556 } 02557 default: 02558 report_unknown_signal(signal); 02559 return SEND_OR_RECEIVE_FAILED; 02560 } 02561 } 02562 } 02563 02564 int 02565 MgmtSrvr::abortBackup(Uint32 backupId) 02566 { 02567 SignalSender ss(theFacade); 02568 ss.lock(); // lock will be released on exit 02569 02570 bool next; 02571 NodeId nodeId = 0; 02572 while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true && 02573 theFacade->get_node_alive(nodeId) == false); 02574 02575 if(!next){ 02576 return NO_CONTACT_WITH_DB_NODES; 02577 } 02578 02579 SimpleSignal ssig; 02580 02581 AbortBackupOrd* ord = CAST_PTR(AbortBackupOrd, ssig.getDataPtrSend()); 02582 ssig.set(ss, TestOrd::TraceAPI, BACKUP, GSN_ABORT_BACKUP_ORD, 02583 AbortBackupOrd::SignalLength); 02584 02585 ord->requestType = AbortBackupOrd::ClientAbort; 02586 ord->senderData = 19; 02587 ord->backupId = backupId; 02588 02589 return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED; 02590 } 02591 02592 02593 MgmtSrvr::Allocated_resources::Allocated_resources(MgmtSrvr &m) 02594 : m_mgmsrv(m) 02595 { 02596 m_reserved_nodes.clear(); 02597 m_alloc_timeout= 0; 02598 } 02599 02600 MgmtSrvr::Allocated_resources::~Allocated_resources() 02601 { 02602 Guard g(m_mgmsrv.m_node_id_mutex); 02603 if (!m_reserved_nodes.isclear()) { 02604 m_mgmsrv.m_reserved_nodes.bitANDC(m_reserved_nodes); 02605 // node has been reserved, force update signal to ndb nodes 02606 global_flag_send_heartbeat_now= 1; 02607 02608 char tmp_str[128]; 02609 m_mgmsrv.m_reserved_nodes.getText(tmp_str); 02610 g_eventLogger.info("Mgmt server state: nodeid %d freed, m_reserved_nodes %s.", 02611 get_nodeid(), tmp_str); 02612 } 02613 } 02614 02615 void 02616 MgmtSrvr::Allocated_resources::reserve_node(NodeId id, NDB_TICKS timeout) 02617 { 02618 m_reserved_nodes.set(id); 02619 m_alloc_timeout= NdbTick_CurrentMillisecond() + timeout; 02620 } 02621 02622 bool 02623 MgmtSrvr::Allocated_resources::is_timed_out(NDB_TICKS tick) 02624 { 02625 if (m_alloc_timeout && tick > m_alloc_timeout) 02626 { 02627 g_eventLogger.info("Mgmt server state: nodeid %d timed out.", 02628 get_nodeid()); 02629 return true; 02630 } 02631 return false; 02632 } 02633 02634 NodeId 02635 MgmtSrvr::Allocated_resources::get_nodeid() const 02636 { 02637 for(Uint32 i = 0; i < MAX_NODES; i++) 02638 { 02639 if (m_reserved_nodes.get(i)) 02640 return i; 02641 } 02642 return 0; 02643 } 02644 02645 int 02646 MgmtSrvr::setDbParameter(int node, int param, const char * value, 02647 BaseString& msg){ 02648 02649 if(NdbMutex_Lock(m_configMutex)) 02650 return -1; 02651 02655 ndb_mgm_configuration_iterator 02656 iter(* _config->m_configValues, CFG_SECTION_NODE); 02657 if(iter.first() != 0){ 02658 msg.assign("Unable to find node section (iter.first())"); 02659 NdbMutex_Unlock(m_configMutex); 02660 return -1; 02661 } 02662 02663 Uint32 type = NODE_TYPE_DB + 1; 02664 if(node != 0){ 02665 if(iter.find(CFG_NODE_ID, node) != 0){ 02666 msg.assign("Unable to find node (iter.find())"); 02667 NdbMutex_Unlock(m_configMutex); 02668 return -1; 02669 } 02670 if(iter.get(CFG_TYPE_OF_SECTION, &type) != 0){ 02671 msg.assign("Unable to get node type(iter.get(CFG_TYPE_OF_SECTION))"); 02672 NdbMutex_Unlock(m_configMutex); 02673 return -1; 02674 } 02675 } else { 02676 do { 02677 if(iter.get(CFG_TYPE_OF_SECTION, &type) != 0){ 02678 msg.assign("Unable to get node type(iter.get(CFG_TYPE_OF_SECTION))"); 02679 NdbMutex_Unlock(m_configMutex); 02680 return -1; 02681 } 02682 if(type == NODE_TYPE_DB) 02683 break; 02684 } while(iter.next() == 0); 02685 } 02686 02687 if(type != NODE_TYPE_DB){ 02688 msg.assfmt("Invalid node type or no such node (%d %d)", 02689 type, NODE_TYPE_DB); 02690 NdbMutex_Unlock(m_configMutex); 02691 return -1; 02692 } 02693 02694 int p_type; 02695 unsigned val_32; 02696 Uint64 val_64; 02697 const char * val_char; 02698 do { 02699 p_type = 0; 02700 if(iter.get(param, &val_32) == 0){ 02701 val_32 = atoi(value); 02702 break; 02703 } 02704 02705 p_type++; 02706 if(iter.get(param, &val_64) == 0){ 02707 val_64 = strtoll(value, 0, 10); 02708 break; 02709 } 02710 p_type++; 02711 if(iter.get(param, &val_char) == 0){ 02712 val_char = value; 02713 break; 02714 } 02715 msg.assign("Could not get parameter"); 02716 NdbMutex_Unlock(m_configMutex); 02717 return -1; 02718 } while(0); 02719 02720 bool res = false; 02721 do { 02722 int ret = iter.get(CFG_TYPE_OF_SECTION, &type); 02723 assert(ret == 0); 02724 02725 if(type != NODE_TYPE_DB) 02726 continue; 02727 02728 Uint32 node; 02729 ret = iter.get(CFG_NODE_ID, &node); 02730 assert(ret == 0); 02731 02732 ConfigValues::Iterator i2(_config->m_configValues->m_config, 02733 iter.m_config); 02734 switch(p_type){ 02735 case 0: 02736 res = i2.set(param, val_32); 02737 ndbout_c("Updating node %d param: %d to %d", node, param, val_32); 02738 break; 02739 case 1: 02740 res = i2.set(param, val_64); 02741 ndbout_c("Updating node %d param: %d to %Ld", node, param, val_32); 02742 break; 02743 case 2: 02744 res = i2.set(param, val_char); 02745 ndbout_c("Updating node %d param: %d to %s", node, param, val_char); 02746 break; 02747 default: 02748 require(false); 02749 } 02750 assert(res); 02751 } while(node == 0 && iter.next() == 0); 02752 02753 msg.assign("Success"); 02754 NdbMutex_Unlock(m_configMutex); 02755 return 0; 02756 } 02757 int 02758 MgmtSrvr::setConnectionDbParameter(int node1, 02759 int node2, 02760 int param, 02761 int value, 02762 BaseString& msg){ 02763 Uint32 current_value,new_value; 02764 02765 DBUG_ENTER("MgmtSrvr::setConnectionDbParameter"); 02766 02767 if(NdbMutex_Lock(m_configMutex)) 02768 { 02769 DBUG_RETURN(-1); 02770 } 02771 02772 ndb_mgm_configuration_iterator 02773 iter(* _config->m_configValues, CFG_SECTION_CONNECTION); 02774 02775 if(iter.first() != 0){ 02776 msg.assign("Unable to find connection section (iter.first())"); 02777 NdbMutex_Unlock(m_configMutex); 02778 DBUG_RETURN(-1); 02779 } 02780 02781 for(;iter.valid();iter.next()) { 02782 Uint32 n1,n2; 02783 iter.get(CFG_CONNECTION_NODE_1, &n1); 02784 iter.get(CFG_CONNECTION_NODE_2, &n2); 02785 if((n1 == (unsigned)node1 && n2 == (unsigned)node2) 02786 || (n1 == (unsigned)node2 && n2 == (unsigned)node1)) 02787 break; 02788 } 02789 if(!iter.valid()) { 02790 msg.assign("Unable to find connection between nodes"); 02791 NdbMutex_Unlock(m_configMutex); 02792 DBUG_RETURN(-2); 02793 } 02794 02795 if(iter.get(param, ¤t_value) != 0) { 02796 msg.assign("Unable to get current value of parameter"); 02797 NdbMutex_Unlock(m_configMutex); 02798 DBUG_RETURN(-3); 02799 } 02800 02801 ConfigValues::Iterator i2(_config->m_configValues->m_config, 02802 iter.m_config); 02803 02804 if(i2.set(param, (unsigned)value) == false) { 02805 msg.assign("Unable to set new value of parameter"); 02806 NdbMutex_Unlock(m_configMutex); 02807 DBUG_RETURN(-4); 02808 } 02809 02810 if(iter.get(param, &new_value) != 0) { 02811 msg.assign("Unable to get parameter after setting it."); 02812 NdbMutex_Unlock(m_configMutex); 02813 DBUG_RETURN(-5); 02814 } 02815 02816 msg.assfmt("%u -> %u",current_value,new_value); 02817 NdbMutex_Unlock(m_configMutex); 02818 DBUG_RETURN(1); 02819 } 02820 02821 02822 int 02823 MgmtSrvr::getConnectionDbParameter(int node1, 02824 int node2, 02825 int param, 02826 int *value, 02827 BaseString& msg){ 02828 DBUG_ENTER("MgmtSrvr::getConnectionDbParameter"); 02829 02830 if(NdbMutex_Lock(m_configMutex)) 02831 { 02832 DBUG_RETURN(-1); 02833 } 02834 02835 ndb_mgm_configuration_iterator 02836 iter(* _config->m_configValues, CFG_SECTION_CONNECTION); 02837 02838 if(iter.first() != 0){ 02839 msg.assign("Unable to find connection section (iter.first())"); 02840 NdbMutex_Unlock(m_configMutex); 02841 DBUG_RETURN(-1); 02842 } 02843 02844 for(;iter.valid();iter.next()) { 02845 Uint32 n1=0,n2=0; 02846 iter.get(CFG_CONNECTION_NODE_1, &n1); 02847 iter.get(CFG_CONNECTION_NODE_2, &n2); 02848 if((n1 == (unsigned)node1 && n2 == (unsigned)node2) 02849 || (n1 == (unsigned)node2 && n2 == (unsigned)node1)) 02850 break; 02851 } 02852 if(!iter.valid()) { 02853 msg.assign("Unable to find connection between nodes"); 02854 NdbMutex_Unlock(m_configMutex); 02855 DBUG_RETURN(-1); 02856 } 02857 02858 if(iter.get(param, (Uint32*)value) != 0) { 02859 msg.assign("Unable to get current value of parameter"); 02860 NdbMutex_Unlock(m_configMutex); 02861 DBUG_RETURN(-1); 02862 } 02863 02864 msg.assfmt("%d",*value); 02865 NdbMutex_Unlock(m_configMutex); 02866 DBUG_RETURN(1); 02867 } 02868 02869 void MgmtSrvr::transporter_connect(NDB_SOCKET_TYPE sockfd) 02870 { 02871 if (theFacade->get_registry()->connect_server(sockfd)) 02872 { 02879 NdbMutex_Lock(theFacade->theMutexPtr); 02880 theFacade->get_registry()->update_connections(); 02881 NdbMutex_Unlock(theFacade->theMutexPtr); 02882 } 02883 } 02884 02885 int MgmtSrvr::connect_to_self(void) 02886 { 02887 int r= 0; 02888 m_local_mgm_handle= ndb_mgm_create_handle(); 02889 snprintf(m_local_mgm_connect_string,sizeof(m_local_mgm_connect_string), 02890 "localhost:%u",getPort()); 02891 ndb_mgm_set_connectstring(m_local_mgm_handle, m_local_mgm_connect_string); 02892 02893 if((r= ndb_mgm_connect(m_local_mgm_handle, 0, 0, 0)) < 0) 02894 { 02895 ndb_mgm_destroy_handle(&m_local_mgm_handle); 02896 return r; 02897 } 02898 // TransporterRegistry now owns this NdbMgmHandle and will destroy it. 02899 theFacade->get_registry()->set_mgm_handle(m_local_mgm_handle); 02900 02901 return 0; 02902 } 02903 02904 02905 02906 template class MutexVector<unsigned short>; 02907 template class MutexVector<Ndb_mgmd_event_service::Event_listener>; 02908 template class MutexVector<EventSubscribeReq>;
1.4.7

