MgmtSrvr.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:59k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #include <ndb_global.h>
  14. #include <my_pthread.h>
  15. #include "MgmtSrvr.hpp"
  16. #include "MgmtErrorReporter.hpp"
  17. #include <ConfigRetriever.hpp>
  18. #include <NdbOut.hpp>
  19. #include <NdbApiSignal.hpp>
  20. #include <kernel_types.h>
  21. #include <RefConvert.hpp>
  22. #include <BlockNumbers.h>
  23. #include <GlobalSignalNumbers.h>
  24. #include <signaldata/TestOrd.hpp>
  25. #include <signaldata/TamperOrd.hpp>
  26. #include <signaldata/StartOrd.hpp>
  27. #include <signaldata/ApiVersion.hpp>
  28. #include <signaldata/ResumeReq.hpp>
  29. #include <signaldata/SetLogLevelOrd.hpp>
  30. #include <signaldata/EventSubscribeReq.hpp>
  31. #include <signaldata/EventReport.hpp>
  32. #include <signaldata/DumpStateOrd.hpp>
  33. #include <signaldata/BackupSignalData.hpp>
  34. #include <signaldata/GrepImpl.hpp>
  35. #include <signaldata/ManagementServer.hpp>
  36. #include <signaldata/NFCompleteRep.hpp>
  37. #include <signaldata/NodeFailRep.hpp>
  38. #include <NdbSleep.h>
  39. #include <EventLogger.hpp>
  40. #include <DebuggerNames.hpp>
  41. #include <ndb_version.h>
  42. #include <SocketServer.hpp>
  43. #include <NdbConfig.h>
  44. #include <NdbAutoPtr.hpp>
  45. #include <ndberror.h>
  46. #include <mgmapi.h>
  47. #include <mgmapi_configuration.hpp>
  48. #include <mgmapi_config_parameters.h>
  49. #include <m_string.h>
  50. #include <SignalSender.hpp>
  51. //#define MGM_SRV_DEBUG
  52. #ifdef MGM_SRV_DEBUG
  53. #define DEBUG(x) do ndbout << x << endl; while(0)
  54. #else
  55. #define DEBUG(x)
  56. #endif
  57. #define INIT_SIGNAL_SENDER(ss,nodeId) 
  58.   SignalSender ss(theFacade); 
  59.   ss.lock(); /* lock will be released on exit */ 
  60.   {
  61.     int result = okToSendTo(nodeId, true);
  62.     if (result != 0) {
  63.       return result;
  64.     }
  65.   }
  66. extern int global_flag_send_heartbeat_now;
  67. extern int g_no_nodeid_checks;
  68. extern my_bool opt_core;
  69. static void require(bool v)
  70. {
  71.   if(!v)
  72.   {
  73.     if (opt_core)
  74.       abort();
  75.     else
  76.       exit(-1);
  77.   }
  78. }
  79. void *
  80. MgmtSrvr::logLevelThread_C(void* m)
  81. {
  82.   MgmtSrvr *mgm = (MgmtSrvr*)m;
  83.   mgm->logLevelThreadRun();
  84.   return 0;
  85. }
  86. extern EventLogger g_eventLogger;
  87. static NdbOut&
  88. operator<<(NdbOut& out, const LogLevel & ll)
  89. {
  90.   out << "[LogLevel: ";
  91.   for(size_t i = 0; i<LogLevel::LOGLEVEL_CATEGORIES; i++)
  92.     out << ll.getLogLevel((LogLevel::EventCategory)i) << " ";
  93.   out << "]";
  94.   return out;
  95. }
  96. void
  97. MgmtSrvr::logLevelThreadRun() 
  98. {
  99.   while (!_isStopThread) {
  100.     /**
  101.      * Handle started nodes
  102.      */
  103.     EventSubscribeReq req;
  104.     req = m_event_listner[0].m_logLevel;
  105.     req.blockRef = _ownReference;
  106.     SetLogLevelOrd ord;
  107.     
  108.     m_started_nodes.lock();
  109.     while(m_started_nodes.size() > 0){
  110.       Uint32 node = m_started_nodes[0];
  111.       m_started_nodes.erase(0, false);
  112.       m_started_nodes.unlock();
  113.       setEventReportingLevelImpl(node, req);
  114.       
  115.       ord = m_nodeLogLevel[node];
  116.       setNodeLogLevelImpl(node, ord);
  117.       
  118.       m_started_nodes.lock();
  119.     }  
  120.     m_started_nodes.unlock();
  121.     
  122.     m_log_level_requests.lock();
  123.     while(m_log_level_requests.size() > 0){
  124.       req = m_log_level_requests[0];
  125.       m_log_level_requests.erase(0, false);
  126.       m_log_level_requests.unlock();
  127.       
  128.       LogLevel tmp;
  129.       tmp = req;
  130.       
  131.       if(req.blockRef == 0){
  132. req.blockRef = _ownReference;
  133. setEventReportingLevelImpl(0, req);
  134.       } else {
  135. ord = req;
  136. setNodeLogLevelImpl(req.blockRef, ord);
  137.       }
  138.       m_log_level_requests.lock();
  139.     }      
  140.     m_log_level_requests.unlock();
  141.     NdbSleep_MilliSleep(_logLevelThreadSleep);  
  142.   }
  143. }
  144. void
  145. MgmtSrvr::startEventLog() 
  146. {
  147.   g_eventLogger.setCategory("MgmSrvr");
  148.   ndb_mgm_configuration_iterator * iter = ndb_mgm_create_configuration_iterator
  149.     ((ndb_mgm_configuration*)_config->m_configValues, CFG_SECTION_NODE);
  150.   if(iter == 0)
  151.     return ;
  152.   
  153.   if(ndb_mgm_find(iter, CFG_NODE_ID, _ownNodeId) != 0){
  154.     ndb_mgm_destroy_iterator(iter);
  155.     return ;
  156.   }
  157.   
  158.   const char * tmp;
  159.   BaseString logdest;
  160.   char *clusterLog= NdbConfig_ClusterLogFileName(_ownNodeId);
  161.   NdbAutoPtr<char> tmp_aptr(clusterLog);
  162.   if(ndb_mgm_get_string_parameter(iter, CFG_LOG_DESTINATION, &tmp) == 0){
  163.     logdest.assign(tmp);
  164.   }
  165.   ndb_mgm_destroy_iterator(iter);
  166.   
  167.   if(logdest.length() == 0 || logdest == "") {
  168.     logdest.assfmt("FILE:filename=%s,maxsize=1000000,maxfiles=6", 
  169.    clusterLog);
  170.   }
  171.   if(!g_eventLogger.addHandler(logdest)) {
  172.     ndbout << "Warning: could not add log destination ""
  173.    << logdest.c_str() << """ << endl;
  174.   }
  175. }
  176. void 
  177. MgmtSrvr::stopEventLog() 
  178. {
  179.   // Nothing yet
  180. }
  181. class ErrorItem 
  182. {
  183. public:
  184.   int _errorCode;
  185.   const char * _errorText;
  186. };
  187. bool
  188. MgmtSrvr::setEventLogFilter(int severity, int enable)
  189. {
  190.   Logger::LoggerLevel level = (Logger::LoggerLevel)severity;
  191.   if (enable > 0) {
  192.     g_eventLogger.enable(level);
  193.   } else if (enable == 0) {
  194.     g_eventLogger.disable(level);
  195.   } else if (g_eventLogger.isEnable(level)) {
  196.     g_eventLogger.disable(level);
  197.   } else {
  198.     g_eventLogger.enable(level);
  199.   }
  200.   return g_eventLogger.isEnable(level);
  201. }
  202. bool 
  203. MgmtSrvr::isEventLogFilterEnabled(int severity) 
  204. {
  205.   return g_eventLogger.isEnable((Logger::LoggerLevel)severity);
  206. }
  207. static ErrorItem errorTable[] = 
  208. {
  209.   {MgmtSrvr::NO_CONTACT_WITH_PROCESS, "No contact with the process (dead ?)."},
  210.   {MgmtSrvr::PROCESS_NOT_CONFIGURED, "The process is not configured."},
  211.   {MgmtSrvr::WRONG_PROCESS_TYPE, 
  212.    "The process has wrong type. Expected a DB process."},
  213.   {MgmtSrvr::COULD_NOT_ALLOCATE_MEMORY, "Could not allocate memory."},
  214.   {MgmtSrvr::SEND_OR_RECEIVE_FAILED, "Send to process or receive failed."},
  215.   {MgmtSrvr::INVALID_LEVEL, "Invalid level. Should be between 1 and 30."},
  216.   {MgmtSrvr::INVALID_ERROR_NUMBER, "Invalid error number. Should be >= 0."},
  217.   {MgmtSrvr::INVALID_TRACE_NUMBER, "Invalid trace number."},
  218.   {MgmtSrvr::NOT_IMPLEMENTED, "Not implemented."},
  219.   {MgmtSrvr::INVALID_BLOCK_NAME, "Invalid block name"},
  220.   {MgmtSrvr::CONFIG_PARAM_NOT_EXIST, 
  221.    "The configuration parameter does not exist for the process type."},
  222.   {MgmtSrvr::CONFIG_PARAM_NOT_UPDATEABLE, 
  223.    "The configuration parameter is not possible to update."},
  224.   {MgmtSrvr::VALUE_WRONG_FORMAT_INT_EXPECTED, 
  225.    "Incorrect value. Expected integer."},
  226.   {MgmtSrvr::VALUE_TOO_LOW, "Value is too low."},
  227.   {MgmtSrvr::VALUE_TOO_HIGH, "Value is too high."},
  228.   {MgmtSrvr::VALUE_WRONG_FORMAT_BOOL_EXPECTED, 
  229.    "Incorrect value. Expected TRUE or FALSE."},
  230.   {MgmtSrvr::CONFIG_FILE_OPEN_WRITE_ERROR, 
  231.    "Could not open configuration file for writing."},
  232.   {MgmtSrvr::CONFIG_FILE_OPEN_READ_ERROR, 
  233.    "Could not open configuration file for reading."},
  234.   {MgmtSrvr::CONFIG_FILE_WRITE_ERROR, 
  235.    "Write error when writing configuration file."},
  236.   {MgmtSrvr::CONFIG_FILE_READ_ERROR, 
  237.    "Read error when reading configuration file."},
  238.   {MgmtSrvr::CONFIG_FILE_CLOSE_ERROR, "Could not close configuration file."},
  239.   {MgmtSrvr::CONFIG_CHANGE_REFUSED_BY_RECEIVER, 
  240.    "The change was refused by the receiving process."},
  241.   {MgmtSrvr::COULD_NOT_SYNC_CONFIG_CHANGE_AGAINST_PHYSICAL_MEDIUM, 
  242.    "The change could not be synced against physical medium."},
  243.   {MgmtSrvr::CONFIG_FILE_CHECKSUM_ERROR, 
  244.    "The config file is corrupt. Checksum error."},
  245.   {MgmtSrvr::NOT_POSSIBLE_TO_SEND_CONFIG_UPDATE_TO_PROCESS_TYPE, 
  246.    "It is not possible to send an update of a configuration variable "
  247.    "to this kind of process."},
  248.   {5026, "Node shutdown in progress" },
  249.   {5027, "System shutdown in progress" },
  250.   {5028, "Node shutdown would cause system crash" },
  251.   {5029, "Only one shutdown at a time is possible via mgm server" },
  252.   {5060, "Operation not allowed in single user mode." }, 
  253.   {5061, "DB is not in single user mode." },
  254.   {5062, "The specified node is not an API node." },
  255.   {5063, 
  256.    "Cannot enter single user mode. DB nodes in inconsistent startlevel."},
  257.   {MgmtSrvr::NO_CONTACT_WITH_DB_NODES, "No contact with database nodes" }
  258. };
  259. int MgmtSrvr::translateStopRef(Uint32 errCode)
  260. {
  261.   switch(errCode){
  262.   case StopRef::NodeShutdownInProgress:
  263.     return 5026;
  264.     break;
  265.   case StopRef::SystemShutdownInProgress:
  266.     return 5027;
  267.     break;
  268.   case StopRef::NodeShutdownWouldCauseSystemCrash:
  269.     return 5028;
  270.     break;
  271.   }
  272.   return 4999;
  273. }
  274. static int noOfErrorCodes = sizeof(errorTable) / sizeof(ErrorItem);
  275. int 
  276. MgmtSrvr::getNodeCount(enum ndb_mgm_node_type type) const 
  277. {
  278.   int count = 0;
  279.   NodeId nodeId = 0;
  280.   while (getNextNodeId(&nodeId, type)) {
  281.     count++;
  282.   }
  283.   return count;
  284. }
  285. int 
  286. MgmtSrvr::getPort() const {
  287.   const Properties *mgmProps;
  288.   
  289.   ndb_mgm_configuration_iterator * iter = 
  290.     ndb_mgm_create_configuration_iterator(_config->m_configValues, 
  291.   CFG_SECTION_NODE);
  292.   if(iter == 0)
  293.     return 0;
  294.   if(ndb_mgm_find(iter, CFG_NODE_ID, getOwnNodeId()) != 0){
  295.     ndbout << "Could not retrieve configuration for Node " 
  296.    << getOwnNodeId() << " in config file." << endl 
  297.    << "Have you set correct NodeId for this node?" << endl;
  298.     ndb_mgm_destroy_iterator(iter);
  299.     return 0;
  300.   }
  301.   unsigned type;
  302.   if(ndb_mgm_get_int_parameter(iter, CFG_TYPE_OF_SECTION, &type) != 0 ||
  303.      type != NODE_TYPE_MGM){
  304.     ndbout << "Local node id " << getOwnNodeId()
  305.    << " is not defined as management server" << endl
  306.    << "Have you set correct NodeId for this node?" << endl;
  307.     ndb_mgm_destroy_iterator(iter);
  308.     return 0;
  309.   }
  310.   
  311.   Uint32 port = 0;
  312.   if(ndb_mgm_get_int_parameter(iter, CFG_MGM_PORT, &port) != 0){
  313.     ndbout << "Could not find PortNumber in the configuration file." << endl;
  314.     ndb_mgm_destroy_iterator(iter);
  315.     return 0;
  316.   }
  317.   ndb_mgm_destroy_iterator(iter);
  318.   
  319.   return port;
  320. }
  321. /* Constructor */
  322. int MgmtSrvr::init()
  323. {
  324.   if ( _ownNodeId > 0)
  325.     return 0;
  326.   return -1;
  327. }
  328. MgmtSrvr::MgmtSrvr(SocketServer *socket_server,
  329.    const char *config_filename,
  330.    const char *connect_string) :
  331.   _blockNumber(1), // Hard coded block number since it makes it easy to send
  332.                    // signals to other management servers.
  333.   m_socket_server(socket_server),
  334.   _ownReference(0),
  335.   theSignalIdleList(NULL),
  336.   theWaitState(WAIT_SUBSCRIBE_CONF),
  337.   m_event_listner(this)
  338. {
  339.     
  340.   DBUG_ENTER("MgmtSrvr::MgmtSrvr");
  341.   _ownNodeId= 0;
  342.   _config     = NULL;
  343.   _isStopThread        = false;
  344.   _logLevelThread      = NULL;
  345.   _logLevelThreadSleep = 500;
  346.   theFacade = 0;
  347.   m_newConfig = NULL;
  348.   if (config_filename)
  349.     m_configFilename.assign(config_filename);
  350.   else
  351.     m_configFilename.assign("config.ini");
  352.   m_nextConfigGenerationNumber = 0;
  353.   m_config_retriever= new ConfigRetriever(connect_string,
  354.   NDB_VERSION, NDB_MGM_NODE_TYPE_MGM);
  355.   // if connect_string explicitly given or
  356.   // no config filename is given then
  357.   // first try to allocate nodeid from another management server
  358.   if ((connect_string || config_filename == NULL) &&
  359.       (m_config_retriever->do_connect(0,0,0) == 0))
  360.   {
  361.     int tmp_nodeid= 0;
  362.     tmp_nodeid= m_config_retriever->allocNodeId(0 /*retry*/,0 /*delay*/);
  363.     if (tmp_nodeid == 0)
  364.     {
  365.       ndbout_c(m_config_retriever->getErrorString());
  366.       require(false);
  367.     }
  368.     // read config from other managent server
  369.     _config= fetchConfig();
  370.     if (_config == 0)
  371.     {
  372.       ndbout << m_config_retriever->getErrorString() << endl;
  373.       require(false);
  374.     }
  375.     _ownNodeId= tmp_nodeid;
  376.   }
  377.   if (_ownNodeId == 0)
  378.   {
  379.     // read config locally
  380.     _config= readConfig();
  381.     if (_config == 0) {
  382.       ndbout << "Unable to read config file" << endl;
  383.       require(false);
  384.     }
  385.   }
  386.   theMgmtWaitForResponseCondPtr = NdbCondition_Create();
  387.   m_configMutex = NdbMutex_Create();
  388.   /**
  389.    * Fill the nodeTypes array
  390.    */
  391.   for(Uint32 i = 0; i<MAX_NODES; i++) {
  392.     nodeTypes[i] = (enum ndb_mgm_node_type)-1;
  393.     m_connect_address[i].s_addr= 0;
  394.   }
  395.   {
  396.     ndb_mgm_configuration_iterator
  397.       *iter = ndb_mgm_create_configuration_iterator(_config->m_configValues,
  398.     CFG_SECTION_NODE);
  399.     for(ndb_mgm_first(iter); ndb_mgm_valid(iter); ndb_mgm_next(iter)){
  400.       unsigned type, id;
  401.       if(ndb_mgm_get_int_parameter(iter, CFG_TYPE_OF_SECTION, &type) != 0)
  402. continue;
  403.       
  404.       if(ndb_mgm_get_int_parameter(iter, CFG_NODE_ID, &id) != 0)
  405. continue;
  406.       
  407.       MGM_REQUIRE(id < MAX_NODES);
  408.       
  409.       switch(type){
  410.       case NODE_TYPE_DB:
  411. nodeTypes[id] = NDB_MGM_NODE_TYPE_NDB;
  412. break;
  413.       case NODE_TYPE_API:
  414. nodeTypes[id] = NDB_MGM_NODE_TYPE_API;
  415. break;
  416.       case NODE_TYPE_MGM:
  417. nodeTypes[id] = NDB_MGM_NODE_TYPE_MGM;
  418. break;
  419.       case NODE_TYPE_REP:
  420. nodeTypes[id] = NDB_MGM_NODE_TYPE_REP;
  421. break;
  422.       case NODE_TYPE_EXT_REP:
  423.       default:
  424. break;
  425.       }
  426.     }
  427.     ndb_mgm_destroy_iterator(iter);
  428.   }
  429.   _props = NULL;
  430.   BaseString error_string;
  431.   if ((m_node_id_mutex = NdbMutex_Create()) == 0)
  432.   {
  433.     ndbout << "mutex creation failed line = " << __LINE__ << endl;
  434.     require(false);
  435.   }
  436.   if (_ownNodeId == 0) // we did not get node id from other server
  437.   {
  438.     NodeId tmp= m_config_retriever->get_configuration_nodeid();
  439.     if (!alloc_node_id(&tmp, NDB_MGM_NODE_TYPE_MGM,
  440.        0, 0, error_string)){
  441.       ndbout << "Unable to obtain requested nodeid: "
  442.      << error_string.c_str() << endl;
  443.       require(false);
  444.     }
  445.     _ownNodeId = tmp;
  446.   }
  447.   {
  448.     DBUG_PRINT("info", ("verifyConfig"));
  449.     if (!m_config_retriever->verifyConfig(_config->m_configValues,
  450.   _ownNodeId))
  451.     {
  452.       ndbout << m_config_retriever->getErrorString() << endl;
  453.       require(false);
  454.     }
  455.   }
  456.   // Setup clusterlog as client[0] in m_event_listner
  457.   {
  458.     Ndb_mgmd_event_service::Event_listener se;
  459.     se.m_socket = NDB_INVALID_SOCKET;
  460.     for(size_t t = 0; t<LogLevel::LOGLEVEL_CATEGORIES; t++){
  461.       se.m_logLevel.setLogLevel((LogLevel::EventCategory)t, 7);
  462.     }
  463.     se.m_logLevel.setLogLevel(LogLevel::llError, 15);
  464.     se.m_logLevel.setLogLevel(LogLevel::llConnection, 8);
  465.     se.m_logLevel.setLogLevel(LogLevel::llBackup, 15);
  466.     m_event_listner.m_clients.push_back(se);
  467.     m_event_listner.m_logLevel = se.m_logLevel;
  468.   }
  469.   
  470.   DBUG_VOID_RETURN;
  471. }
  472. //****************************************************************************
  473. //****************************************************************************
  474. bool 
  475. MgmtSrvr::check_start() 
  476. {
  477.   if (_config == 0) {
  478.     DEBUG("MgmtSrvr.cpp: _config is NULL.");
  479.     return false;
  480.   }
  481.   return true;
  482. }
  483. bool 
  484. MgmtSrvr::start(BaseString &error_string)
  485. {
  486.   DBUG_ENTER("MgmtSrvr::start");
  487.   if (_props == NULL) {
  488.     if (!check_start()) {
  489.       error_string.append("MgmtSrvr.cpp: check_start() failed.");
  490.       DBUG_RETURN(false);
  491.     }
  492.   }
  493.   theFacade= TransporterFacade::theFacadeInstance= new TransporterFacade();
  494.   
  495.   if(theFacade == 0) {
  496.     DEBUG("MgmtSrvr.cpp: theFacade is NULL.");
  497.     error_string.append("MgmtSrvr.cpp: theFacade is NULL.");
  498.     DBUG_RETURN(false);
  499.   }  
  500.   if ( theFacade->start_instance
  501.        (_ownNodeId, (ndb_mgm_configuration*)_config->m_configValues) < 0) {
  502.     DEBUG("MgmtSrvr.cpp: TransporterFacade::start_instance < 0.");
  503.     DBUG_RETURN(false);
  504.   }
  505.   MGM_REQUIRE(_blockNumber == 1);
  506.   // Register ourself at TransporterFacade to be able to receive signals
  507.   // and to be notified when a database process has died.
  508.   _blockNumber = theFacade->open(this,
  509.  signalReceivedNotification,
  510.  nodeStatusNotification);
  511.   
  512.   if(_blockNumber == -1){
  513.     DEBUG("MgmtSrvr.cpp: _blockNumber is -1.");
  514.     error_string.append("MgmtSrvr.cpp: _blockNumber is -1.");
  515.     theFacade->stop_instance();
  516.     theFacade = 0;
  517.     DBUG_RETURN(false);
  518.   }
  519.   
  520.   _ownReference = numberToRef(_blockNumber, _ownNodeId);
  521.   
  522.   startEventLog();
  523.   // Set the initial confirmation count for subscribe requests confirm
  524.   // from NDB nodes in the cluster.
  525.   //
  526.   // Loglevel thread
  527.   _logLevelThread = NdbThread_Create(logLevelThread_C,
  528.      (void**)this,
  529.      32768,
  530.      "MgmtSrvr_Loglevel",
  531.      NDB_THREAD_PRIO_LOW);
  532.   DBUG_RETURN(true);
  533. }
  534. //****************************************************************************
  535. //****************************************************************************
  536. MgmtSrvr::~MgmtSrvr() 
  537. {
  538.   if(theFacade != 0){
  539.     theFacade->stop_instance();
  540.     delete theFacade;
  541.     theFacade = 0;
  542.   }
  543.   stopEventLog();
  544.   NdbMutex_Destroy(m_node_id_mutex);
  545.   NdbCondition_Destroy(theMgmtWaitForResponseCondPtr);
  546.   NdbMutex_Destroy(m_configMutex);
  547.   if(m_newConfig != NULL)
  548.     free(m_newConfig);
  549.   if(_config != NULL)
  550.     delete _config;
  551.   // End set log level thread
  552.   void* res = 0;
  553.   _isStopThread = true;
  554.   if (_logLevelThread != NULL) {
  555.     NdbThread_WaitFor(_logLevelThread, &res);
  556.     NdbThread_Destroy(&_logLevelThread);
  557.   }
  558.   if (m_config_retriever)
  559.     delete m_config_retriever;
  560. }
  561. //****************************************************************************
  562. //****************************************************************************
  563. int MgmtSrvr::okToSendTo(NodeId nodeId, bool unCond) 
  564. {
  565.   if(nodeId == 0)
  566.     return 0;
  567.   if (getNodeType(nodeId) != NDB_MGM_NODE_TYPE_NDB)
  568.     return WRONG_PROCESS_TYPE;
  569.   
  570.   // Check if we have contact with it
  571.   if(unCond){
  572.     if(theFacade->theClusterMgr->getNodeInfo(nodeId).connected)
  573.       return 0;
  574.     return NO_CONTACT_WITH_PROCESS;
  575.   }
  576.   if (theFacade->get_node_alive(nodeId) == 0) {
  577.     return NO_CONTACT_WITH_PROCESS;
  578.   } else {
  579.     return 0;
  580.   }
  581. }
  582. void report_unknown_signal(SimpleSignal *signal)
  583. {
  584.   g_eventLogger.error("Unknown signal received. SignalNumber: "
  585.       "%i from (%d, %x)",
  586.       signal->readSignalNumber(),
  587.       refToNode(signal->header.theSendersBlockRef),
  588.       refToBlock(signal->header.theSendersBlockRef));
  589. }
  590. /*****************************************************************************
  591.  * Starting and stopping database nodes
  592.  ****************************************************************************/
  593. int 
  594. MgmtSrvr::start(int nodeId)
  595. {
  596.   INIT_SIGNAL_SENDER(ss,nodeId);
  597.   
  598.   SimpleSignal ssig;
  599.   StartOrd* const startOrd = CAST_PTR(StartOrd, ssig.getDataPtrSend());
  600.   ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_START_ORD, StartOrd::SignalLength);
  601.   startOrd->restartInfo = 0;
  602.   
  603.   return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
  604. }
  605. /*****************************************************************************
  606.  * Version handling
  607.  *****************************************************************************/
  608. int 
  609. MgmtSrvr::versionNode(int nodeId, Uint32 &version, const char **address)
  610. {
  611.   version= 0;
  612.   if (getOwnNodeId() == nodeId)
  613.   {
  614.     /**
  615.      * If we're inquiring about our own node id,
  616.      * We know what version we are (version implies connected for mgm)
  617.      * but would like to find out from elsewhere what address they're using
  618.      * to connect to us. This means that secondary mgm servers
  619.      * can list ip addresses for mgm servers.
  620.      *
  621.      * If we don't get an address (i.e. no db nodes),
  622.      * we get the address from the configuration.
  623.      */
  624.     sendVersionReq(nodeId, version, address);
  625.     version= NDB_VERSION;
  626.     if(!*address)
  627.     {
  628.       ndb_mgm_configuration_iterator
  629. iter(*_config->m_configValues, CFG_SECTION_NODE);
  630.       unsigned tmp= 0;
  631.       for(iter.first();iter.valid();iter.next())
  632.       {
  633. if(iter.get(CFG_NODE_ID, &tmp)) require(false);
  634. if((unsigned)nodeId!=tmp)
  635.   continue;
  636. if(iter.get(CFG_NODE_HOST, address)) require(false);
  637. break;
  638.       }
  639.     }
  640.   }
  641.   else if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_NDB)
  642.   {
  643.     ClusterMgr::Node node= theFacade->theClusterMgr->getNodeInfo(nodeId);
  644.     if(node.connected)
  645.       version= node.m_info.m_version;
  646.     *address= get_connect_address(nodeId);
  647.   }
  648.   else if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_API ||
  649.    getNodeType(nodeId) == NDB_MGM_NODE_TYPE_MGM)
  650.   {
  651.     return sendVersionReq(nodeId, version, address);
  652.   }
  653.   return 0;
  654. }
  655. int 
  656. MgmtSrvr::sendVersionReq(int v_nodeId, Uint32 &version, const char **address)
  657. {
  658.   SignalSender ss(theFacade);
  659.   ss.lock();
  660.   SimpleSignal ssig;
  661.   ApiVersionReq* req = CAST_PTR(ApiVersionReq, ssig.getDataPtrSend());
  662.   req->senderRef = ss.getOwnRef();
  663.   req->nodeId = v_nodeId;
  664.   ssig.set(ss, TestOrd::TraceAPI, QMGR, GSN_API_VERSION_REQ, 
  665.    ApiVersionReq::SignalLength);
  666.   int do_send = 1;
  667.   NodeId nodeId;
  668.   while (1)
  669.   {
  670.     if (do_send)
  671.     {
  672.       bool next;
  673.       nodeId = 0;
  674.       while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true &&
  675.     okToSendTo(nodeId, true) != 0);
  676.       const ClusterMgr::Node &node=
  677. theFacade->theClusterMgr->getNodeInfo(nodeId);
  678.       if(next && node.m_state.startLevel != NodeState::SL_STARTED)
  679.       {
  680. NodeId tmp=nodeId;
  681. while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true &&
  682.       okToSendTo(nodeId, true) != 0);
  683. if(!next)
  684.   nodeId= tmp;
  685.       }
  686.       if(!next) return NO_CONTACT_WITH_DB_NODES;
  687.       if (ss.sendSignal(nodeId, &ssig) != SEND_OK) {
  688. return SEND_OR_RECEIVE_FAILED;
  689.       }
  690.       do_send = 0;
  691.     }
  692.     SimpleSignal *signal = ss.waitFor();
  693.     int gsn = signal->readSignalNumber();
  694.     switch (gsn) {
  695.     case GSN_API_VERSION_CONF: {
  696.       const ApiVersionConf * const conf = 
  697. CAST_CONSTPTR(ApiVersionConf, signal->getDataPtr());
  698.       assert(conf->nodeId == v_nodeId);
  699.       version = conf->version;
  700.       struct in_addr in;
  701.       in.s_addr= conf->inet_addr;
  702.       *address= inet_ntoa(in);
  703.       return 0;
  704.     }
  705.     case GSN_NF_COMPLETEREP:{
  706.       const NFCompleteRep * const rep =
  707. CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr());
  708.       if (rep->failedNodeId == nodeId)
  709. do_send = 1; // retry with other node
  710.       continue;
  711.     }
  712.     case GSN_NODE_FAILREP:{
  713.       const NodeFailRep * const rep =
  714. CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
  715.       if (NodeBitmask::get(rep->theNodes,nodeId))
  716. do_send = 1; // retry with other node
  717.       continue;
  718.     }
  719.     default:
  720.       report_unknown_signal(signal);
  721.       return SEND_OR_RECEIVE_FAILED;
  722.     }
  723.     break;
  724.   } // while(1)
  725.   return 0;
  726. }
  727. /*
  728.  * Common method for handeling all STOP_REQ signalling that
  729.  * is used by Stopping, Restarting and Single user commands
  730.  */
  731. int MgmtSrvr::sendSTOP_REQ(NodeId nodeId,
  732.    NodeBitmask &stoppedNodes,
  733.    Uint32 singleUserNodeId,
  734.    bool abort,
  735.    bool stop,
  736.    bool restart,
  737.    bool nostart,
  738.    bool initialStart)
  739. {
  740.   stoppedNodes.clear();
  741.   SignalSender ss(theFacade);
  742.   ss.lock(); // lock will be released on exit
  743.   SimpleSignal ssig;
  744.   StopReq* const stopReq = CAST_PTR(StopReq, ssig.getDataPtrSend());
  745.   ssig.set(ss, TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ, StopReq::SignalLength);
  746.   stopReq->requestInfo = 0;
  747.   stopReq->apiTimeout = 5000;
  748.   stopReq->transactionTimeout = 1000;
  749.   stopReq->readOperationTimeout = 1000;
  750.   stopReq->operationTimeout = 1000;
  751.   stopReq->senderData = 12;
  752.   stopReq->senderRef = ss.getOwnRef();
  753.   if (singleUserNodeId)
  754.   {
  755.     stopReq->singleuser = 1;
  756.     stopReq->singleUserApi = singleUserNodeId;
  757.     StopReq::setSystemStop(stopReq->requestInfo, false);
  758.     StopReq::setPerformRestart(stopReq->requestInfo, false);
  759.     StopReq::setStopAbort(stopReq->requestInfo, false);
  760.   }
  761.   else
  762.   {
  763.     stopReq->singleuser = 0;
  764.     StopReq::setSystemStop(stopReq->requestInfo, stop);
  765.     StopReq::setPerformRestart(stopReq->requestInfo, restart);
  766.     StopReq::setStopAbort(stopReq->requestInfo, abort);
  767.     StopReq::setNoStart(stopReq->requestInfo, nostart);
  768.     StopReq::setInitialStart(stopReq->requestInfo, initialStart);
  769.   }
  770.   // send the signals
  771.   NodeBitmask nodes;
  772.   if (nodeId)
  773.   {
  774.     {
  775.       int r;
  776.       if((r = okToSendTo(nodeId, true)) != 0)
  777. return r;
  778.     }
  779.     {
  780.       if (ss.sendSignal(nodeId, &ssig) != SEND_OK)
  781. return SEND_OR_RECEIVE_FAILED;
  782.     }
  783.     nodes.set(nodeId);
  784.   }
  785.   else
  786.     while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB))
  787.     {
  788.       if(okToSendTo(nodeId, true) == 0)
  789.       {
  790. SendStatus result = ss.sendSignal(nodeId, &ssig);
  791. if (result == SEND_OK)
  792.   nodes.set(nodeId);
  793.       }
  794.     }
  795.   // now wait for the replies
  796.   int error = 0;
  797.   while (!nodes.isclear())
  798.   {
  799.     SimpleSignal *signal = ss.waitFor();
  800.     int gsn = signal->readSignalNumber();
  801.     switch (gsn) {
  802.     case GSN_STOP_REF:{
  803.       const StopRef * const ref = CAST_CONSTPTR(StopRef, signal->getDataPtr());
  804.       const NodeId nodeId = refToNode(signal->header.theSendersBlockRef);
  805. #ifdef VM_TRACE
  806.       ndbout_c("Node %d refused stop", nodeId);
  807. #endif
  808.       assert(nodes.get(nodeId));
  809.       nodes.clear(nodeId);
  810.       error = translateStopRef(ref->errorCode);
  811.       break;
  812.     }
  813.     case GSN_STOP_CONF:{
  814.       const StopConf * const ref = CAST_CONSTPTR(StopConf, signal->getDataPtr());
  815.       const NodeId nodeId = refToNode(signal->header.theSendersBlockRef);
  816. #ifdef VM_TRACE
  817.       ndbout_c("Node %d single user mode", nodeId);
  818. #endif
  819.       assert(nodes.get(nodeId));
  820.       assert(singleUserNodeId != 0);
  821.       nodes.clear(nodeId);
  822.       stoppedNodes.set(nodeId);
  823.       break;
  824.     }
  825.     case GSN_NF_COMPLETEREP:{
  826.       const NFCompleteRep * const rep =
  827. CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr());
  828. #ifdef VM_TRACE
  829.       ndbout_c("Node %d fail completed", rep->failedNodeId);
  830. #endif
  831.       break;
  832.     }
  833.     case GSN_NODE_FAILREP:{
  834.       const NodeFailRep * const rep =
  835. CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
  836.       NodeBitmask failedNodes;
  837.       failedNodes.assign(NodeBitmask::Size, rep->theNodes);
  838. #ifdef VM_TRACE
  839.       {
  840. ndbout << "Failed nodes:";
  841. for (unsigned i = 0; i < 32*NodeBitmask::Size; i++)
  842.   if(failedNodes.get(i))
  843.     ndbout << " " << i;
  844. ndbout << endl;
  845.       }
  846. #endif
  847.       failedNodes.bitAND(nodes);
  848.       if (!failedNodes.isclear())
  849.       {
  850. nodes.bitANDC(failedNodes); // clear the failed nodes
  851. if (singleUserNodeId == 0)
  852.   stoppedNodes.bitOR(failedNodes);
  853.       }
  854.       break;
  855.     }
  856.     default:
  857.       report_unknown_signal(signal);
  858. #ifdef VM_TRACE
  859.       ndbout_c("Unknown signal %d", gsn);
  860. #endif
  861.       return SEND_OR_RECEIVE_FAILED;
  862.     }
  863.   }
  864.   return error;
  865. }
  866. /*
  867.  * Stop one node
  868.  */
  869. int MgmtSrvr::stopNode(int nodeId, bool abort)
  870. {
  871.   NodeBitmask nodes;
  872.   return sendSTOP_REQ(nodeId,
  873.       nodes,
  874.       0,
  875.       abort,
  876.       false,
  877.       false,
  878.       false,
  879.       false);
  880. }
  881. /*
  882.  * Perform system shutdown
  883.  */
  884. int MgmtSrvr::stop(int * stopCount, bool abort)
  885. {
  886.   NodeBitmask nodes;
  887.   int ret = sendSTOP_REQ(0,
  888.  nodes,
  889.  0,
  890.  abort,
  891.  true,
  892.  false,
  893.  false,
  894.  false);
  895.   if (stopCount)
  896.     *stopCount = nodes.count();
  897.   return ret;
  898. }
  899. /*
  900.  * Enter single user mode on all live nodes
  901.  */
  902. int MgmtSrvr::enterSingleUser(int * stopCount, Uint32 singleUserNodeId)
  903. {
  904.   if (getNodeType(singleUserNodeId) != NDB_MGM_NODE_TYPE_API)
  905.     return 5062;
  906.   NodeId nodeId = 0;
  907.   ClusterMgr::Node node;
  908.   while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB))
  909.   {
  910.     node = theFacade->theClusterMgr->getNodeInfo(nodeId);
  911.     if((node.m_state.startLevel != NodeState::SL_STARTED) && 
  912.        (node.m_state.startLevel != NodeState::SL_NOTHING))
  913.       return 5063;
  914.   }
  915.   NodeBitmask nodes;
  916.   int ret = sendSTOP_REQ(0,
  917.  nodes,
  918.  singleUserNodeId,
  919.  false,
  920.  false,
  921.  false,
  922.  false,
  923.  false);
  924.   if (stopCount)
  925.     *stopCount = nodes.count();
  926.   return ret;
  927. }
  928. /*
  929.  * Perform node restart
  930.  */
  931. int MgmtSrvr::restartNode(int nodeId, bool nostart, bool initialStart, 
  932.   bool abort)
  933. {
  934.   NodeBitmask nodes;
  935.   return sendSTOP_REQ(nodeId,
  936.       nodes,
  937.       0,
  938.       abort,
  939.       false,
  940.       true,
  941.       nostart,
  942.       initialStart);
  943. }
  944. /*
  945.  * Perform system restart
  946.  */
  947. int MgmtSrvr::restart(bool nostart, bool initialStart, 
  948.       bool abort, int * stopCount )
  949. {
  950.   NodeBitmask nodes;
  951.   int ret = sendSTOP_REQ(0,
  952.  nodes,
  953.  0,
  954.  abort,
  955.  true,
  956.  true,
  957.  true,
  958.  initialStart);
  959.   if (ret)
  960.     return ret;
  961.   if (stopCount)
  962.     *stopCount = nodes.count();
  963. #ifdef VM_TRACE
  964.     ndbout_c("Stopped %d nodes", nodes.count());
  965. #endif
  966.   /**
  967.    * Here all nodes were correctly stopped,
  968.    * so we wait for all nodes to be contactable
  969.    */
  970.   int waitTime = 12000;
  971.   NodeId nodeId = 0;
  972.   NDB_TICKS maxTime = NdbTick_CurrentMillisecond() + waitTime;
  973.   ndbout_c(" %d", nodes.get(1));
  974.   ndbout_c(" %d", nodes.get(2));
  975.   while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) {
  976.     if (!nodes.get(nodeId))
  977.       continue;
  978.     enum ndb_mgm_node_status s;
  979.     s = NDB_MGM_NODE_STATUS_NO_CONTACT;
  980. #ifdef VM_TRACE
  981.     ndbout_c("Waiting for %d not started", nodeId);
  982. #endif
  983.     while (s != NDB_MGM_NODE_STATUS_NOT_STARTED && waitTime > 0) {
  984.       Uint32 startPhase = 0, version = 0, dynamicId = 0, nodeGroup = 0;
  985.       Uint32 connectCount = 0;
  986.       bool system;
  987.       const char *address;
  988.       status(nodeId, &s, &version, &startPhase, 
  989.      &system, &dynamicId, &nodeGroup, &connectCount, &address);
  990.       NdbSleep_MilliSleep(100);  
  991.       waitTime = (maxTime - NdbTick_CurrentMillisecond());
  992.     }
  993.   }
  994.   
  995.   if(nostart)
  996.     return 0;
  997.   
  998.   /**
  999.    * Now we start all database nodes (i.e. we make them non-idle)
  1000.    * We ignore the result we get from the start command.
  1001.    */
  1002.   nodeId = 0;
  1003.   while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) {
  1004.     if (!nodes.get(nodeId))
  1005.       continue;
  1006.     int result;
  1007.     result = start(nodeId);
  1008.     DEBUG("Starting node " << nodeId << " with result " << result);
  1009.     /**
  1010.      * Errors from this call are deliberately ignored.
  1011.      * Maybe the user only wanted to restart a subset of the nodes.
  1012.      * It is also easy for the user to check which nodes have 
  1013.      * started and which nodes have not.
  1014.      */
  1015.   }
  1016.   
  1017.   return 0;
  1018. }
  1019. int
  1020. MgmtSrvr::exitSingleUser(int * stopCount, bool abort)
  1021. {
  1022.   NodeId nodeId = 0;
  1023.   int count = 0;
  1024.   SignalSender ss(theFacade);
  1025.   ss.lock(); // lock will be released on exit
  1026.   SimpleSignal ssig;
  1027.   ResumeReq* const resumeReq = 
  1028.     CAST_PTR(ResumeReq, ssig.getDataPtrSend());
  1029.   ssig.set(ss,TestOrd::TraceAPI, NDBCNTR, GSN_RESUME_REQ, 
  1030.    ResumeReq::SignalLength);
  1031.   resumeReq->senderData = 12;
  1032.   resumeReq->senderRef = ss.getOwnRef();
  1033.   while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)){
  1034.     if(okToSendTo(nodeId, true) == 0){
  1035.       SendStatus result = ss.sendSignal(nodeId, &ssig);
  1036.       if (result == SEND_OK)
  1037. count++;
  1038.     }
  1039.   }
  1040.   if(stopCount != 0)
  1041.     * stopCount = count;
  1042.   return 0;
  1043. }
  1044. /*****************************************************************************
  1045.  * Status
  1046.  ****************************************************************************/
  1047. #include <ClusterMgr.hpp>
  1048. int 
  1049. MgmtSrvr::status(int nodeId, 
  1050.                  ndb_mgm_node_status * _status, 
  1051.  Uint32 * version,
  1052.  Uint32 * _phase, 
  1053.  bool * _system,
  1054.  Uint32 * dynamic,
  1055.  Uint32 * nodegroup,
  1056.  Uint32 * connectCount,
  1057.  const char **address)
  1058. {
  1059.   if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_API ||
  1060.       getNodeType(nodeId) == NDB_MGM_NODE_TYPE_MGM) {
  1061.     versionNode(nodeId, *version, address);
  1062.   } else {
  1063.     *address= get_connect_address(nodeId);
  1064.   }
  1065.   const ClusterMgr::Node node = 
  1066.     theFacade->theClusterMgr->getNodeInfo(nodeId);
  1067.   if(!node.connected){
  1068.     * _status = NDB_MGM_NODE_STATUS_NO_CONTACT;
  1069.     return 0;
  1070.   }
  1071.   
  1072.   if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_NDB) {
  1073.     * version = node.m_info.m_version;
  1074.   }
  1075.   * dynamic = node.m_state.dynamicId;
  1076.   * nodegroup = node.m_state.nodeGroup;
  1077.   * connectCount = node.m_info.m_connectCount;
  1078.   
  1079.   switch(node.m_state.startLevel){
  1080.   case NodeState::SL_CMVMI:
  1081.     * _status = NDB_MGM_NODE_STATUS_NOT_STARTED;
  1082.     * _phase = 0;
  1083.     return 0;
  1084.     break;
  1085.   case NodeState::SL_STARTING:
  1086.     * _status     = NDB_MGM_NODE_STATUS_STARTING;
  1087.     * _phase = node.m_state.starting.startPhase;
  1088.     return 0;
  1089.     break;
  1090.   case NodeState::SL_STARTED:
  1091.     * _status = NDB_MGM_NODE_STATUS_STARTED;
  1092.     * _phase = 0;
  1093.     return 0;
  1094.     break;
  1095.   case NodeState::SL_STOPPING_1:
  1096.     * _status = NDB_MGM_NODE_STATUS_SHUTTING_DOWN;
  1097.     * _phase = 1;
  1098.     * _system = node.m_state.stopping.systemShutdown != 0;
  1099.     return 0;
  1100.     break;
  1101.   case NodeState::SL_STOPPING_2:
  1102.     * _status = NDB_MGM_NODE_STATUS_SHUTTING_DOWN;
  1103.     * _phase = 2;
  1104.     * _system = node.m_state.stopping.systemShutdown != 0;
  1105.     return 0;
  1106.     break;
  1107.   case NodeState::SL_STOPPING_3:
  1108.     * _status = NDB_MGM_NODE_STATUS_SHUTTING_DOWN;
  1109.     * _phase = 3;
  1110.     * _system = node.m_state.stopping.systemShutdown != 0;
  1111.     return 0;
  1112.     break;
  1113.   case NodeState::SL_STOPPING_4:
  1114.     * _status = NDB_MGM_NODE_STATUS_SHUTTING_DOWN;
  1115.     * _phase = 4;
  1116.     * _system = node.m_state.stopping.systemShutdown != 0;
  1117.     return 0;
  1118.     break;
  1119.   case NodeState::SL_SINGLEUSER:
  1120.     * _status = NDB_MGM_NODE_STATUS_SINGLEUSER;
  1121.     * _phase  = 0;
  1122.     return 0;
  1123.     break;
  1124.   default:
  1125.     * _status = NDB_MGM_NODE_STATUS_UNKNOWN;
  1126.     * _phase = 0;
  1127.     return 0;
  1128.   }
  1129.   
  1130.   return -1;
  1131. }
  1132. int 
  1133. MgmtSrvr::setEventReportingLevelImpl(int nodeId, 
  1134.      const EventSubscribeReq& ll)
  1135. {
  1136.   INIT_SIGNAL_SENDER(ss,nodeId);
  1137.   SimpleSignal ssig;
  1138.   EventSubscribeReq * dst = 
  1139.     CAST_PTR(EventSubscribeReq, ssig.getDataPtrSend());
  1140.   ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_EVENT_SUBSCRIBE_REQ,
  1141.    EventSubscribeReq::SignalLength);
  1142.   *dst = ll;
  1143.   send(ss,ssig,nodeId,NODE_TYPE_DB);
  1144. #if 0
  1145.   while (1)
  1146.   {
  1147.     SimpleSignal *signal = ss.waitFor();
  1148.     int gsn = signal->readSignalNumber();
  1149.     switch (gsn) { 
  1150.     case GSN_EVENT_SUBSCRIBE_CONF:{
  1151.       break;
  1152.     }
  1153.     case GSN_EVENT_SUBSCRIBE_REF:{
  1154.       return SEND_OR_RECEIVE_FAILED;
  1155.     }
  1156.     case GSN_NF_COMPLETEREP:{
  1157.       const NFCompleteRep * const rep =
  1158. CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr());
  1159.       if (rep->failedNodeId == nodeId)
  1160. return SEND_OR_RECEIVE_FAILED;
  1161.       break;
  1162.     }
  1163.     case GSN_NODE_FAILREP:{
  1164.       const NodeFailRep * const rep =
  1165. CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
  1166.       if (NodeBitmask::get(rep->theNodes,nodeId))
  1167. return SEND_OR_RECEIVE_FAILED;
  1168.       break;
  1169.     }
  1170.     default:
  1171.       report_unknown_signal(signal);
  1172.       return SEND_OR_RECEIVE_FAILED;
  1173.     }
  1174.   }
  1175. #endif
  1176.   return 0;
  1177. }
  1178. //****************************************************************************
  1179. //****************************************************************************
  1180. int 
  1181. MgmtSrvr::setNodeLogLevelImpl(int nodeId, const SetLogLevelOrd & ll)
  1182. {
  1183.   INIT_SIGNAL_SENDER(ss,nodeId);
  1184.   SimpleSignal ssig;
  1185.   ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_SET_LOGLEVELORD,
  1186.    SetLogLevelOrd::SignalLength);
  1187.   SetLogLevelOrd* const dst = CAST_PTR(SetLogLevelOrd, ssig.getDataPtrSend());
  1188.   *dst = ll;
  1189.   
  1190.   return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
  1191. }
  1192. int
  1193. MgmtSrvr::send(SignalSender &ss, SimpleSignal &ssig, Uint32 node, Uint32 node_type){
  1194.   Uint32 max = (node == 0) ? MAX_NODES : node + 1;
  1195.   
  1196.   for(; node < max; node++){
  1197.     while(nodeTypes[node] != (int)node_type && node < max) node++;
  1198.     if(nodeTypes[node] != (int)node_type)
  1199.       break;
  1200.     ss.sendSignal(node, &ssig);
  1201.   }
  1202.   return 0;
  1203. }
  1204. //****************************************************************************
  1205. //****************************************************************************
  1206. int 
  1207. MgmtSrvr::insertError(int nodeId, int errorNo) 
  1208. {
  1209.   if (errorNo < 0) {
  1210.     return INVALID_ERROR_NUMBER;
  1211.   }
  1212.   INIT_SIGNAL_SENDER(ss,nodeId);
  1213.   
  1214.   SimpleSignal ssig;
  1215.   ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TAMPER_ORD, 
  1216.    TamperOrd::SignalLength);
  1217.   TamperOrd* const tamperOrd = CAST_PTR(TamperOrd, ssig.getDataPtrSend());
  1218.   tamperOrd->errorNo = errorNo;
  1219.   return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
  1220. }
  1221. //****************************************************************************
  1222. //****************************************************************************
  1223. int 
  1224. MgmtSrvr::setTraceNo(int nodeId, int traceNo)
  1225. {
  1226.   if (traceNo < 0) {
  1227.     return INVALID_TRACE_NUMBER;
  1228.   }
  1229.   INIT_SIGNAL_SENDER(ss,nodeId);
  1230.   SimpleSignal ssig;
  1231.   ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
  1232.   TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend());
  1233.   testOrd->clear();
  1234.   // Assume TRACE command causes toggling. Not really defined... ? TODO
  1235.   testOrd->setTraceCommand(TestOrd::Toggle, 
  1236.    (TestOrd::TraceSpecification)traceNo);
  1237.   return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
  1238. }
  1239. //****************************************************************************
  1240. //****************************************************************************
  1241. int 
  1242. MgmtSrvr::getBlockNumber(const BaseString &blockName) 
  1243. {
  1244.   short bno = getBlockNo(blockName.c_str());
  1245.   if(bno != 0)
  1246.     return bno;
  1247.   return -1;
  1248. }
  1249. //****************************************************************************
  1250. //****************************************************************************
  1251. int 
  1252. MgmtSrvr::setSignalLoggingMode(int nodeId, LogMode mode, 
  1253.        const Vector<BaseString>& blocks)
  1254. {
  1255.   INIT_SIGNAL_SENDER(ss,nodeId);
  1256.   // Convert from MgmtSrvr format...
  1257.   TestOrd::Command command;
  1258.   if (mode == Off) {
  1259.     command = TestOrd::Off;
  1260.   }
  1261.   else {
  1262.     command = TestOrd::On;
  1263.   }
  1264.   TestOrd::SignalLoggerSpecification logSpec;
  1265.   switch (mode) {
  1266.   case In:
  1267.     logSpec = TestOrd::InputSignals;
  1268.     break;
  1269.   case Out:
  1270.     logSpec = TestOrd::OutputSignals;
  1271.     break;
  1272.   case InOut:
  1273.     logSpec = TestOrd::InputOutputSignals;
  1274.     break;
  1275.   case Off:
  1276.     // In MgmtSrvr interface it's just possible to switch off all logging, both
  1277.     // "in" and "out" (this should probably be changed).
  1278.     logSpec = TestOrd::InputOutputSignals;
  1279.     break;
  1280.   default:
  1281.     ndbout_c("Unexpected value %d, MgmtSrvr::setSignalLoggingMode, line %d",
  1282.      (unsigned)mode, __LINE__);
  1283.     assert(false);
  1284.     return -1;
  1285.   }
  1286.   SimpleSignal ssig;
  1287.   ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
  1288.   TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend());
  1289.   testOrd->clear();
  1290.   
  1291.   if (blocks.size() == 0 || blocks[0] == "ALL") {
  1292.     // Logg command for all blocks
  1293.     testOrd->addSignalLoggerCommand(command, logSpec);
  1294.   } else {
  1295.     for(unsigned i = 0; i < blocks.size(); i++){
  1296.       int blockNumber = getBlockNumber(blocks[i]);
  1297.       if (blockNumber == -1) {
  1298.         return INVALID_BLOCK_NAME;
  1299.       }
  1300.       testOrd->addSignalLoggerCommand(blockNumber, command, logSpec);
  1301.     } // for
  1302.   } // else
  1303.   return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
  1304. }
  1305. /*****************************************************************************
  1306.  * Signal tracing
  1307.  *****************************************************************************/
  1308. int MgmtSrvr::startSignalTracing(int nodeId)
  1309. {
  1310.   INIT_SIGNAL_SENDER(ss,nodeId);
  1311.   
  1312.   SimpleSignal ssig;
  1313.   ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
  1314.   TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend());
  1315.   testOrd->clear();
  1316.   testOrd->setTestCommand(TestOrd::On);
  1317.   return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
  1318. }
  1319. int 
  1320. MgmtSrvr::stopSignalTracing(int nodeId) 
  1321. {
  1322.   INIT_SIGNAL_SENDER(ss,nodeId);
  1323.   SimpleSignal ssig;
  1324.   ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
  1325.   TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend());
  1326.   testOrd->clear();
  1327.   testOrd->setTestCommand(TestOrd::Off);
  1328.   return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
  1329. }
  1330. /*****************************************************************************
  1331.  * Dump state
  1332.  *****************************************************************************/
  1333. int
  1334. MgmtSrvr::dumpState(int nodeId, const char* args)
  1335. {
  1336.   // Convert the space separeted args 
  1337.   // string to an int array
  1338.   Uint32 args_array[25];
  1339.   Uint32 numArgs = 0;
  1340.   char buf[10];  
  1341.   int b  = 0;
  1342.   memset(buf, 0, 10);
  1343.   for (size_t i = 0; i <= strlen(args); i++){
  1344.     if (args[i] == ' ' || args[i] == 0){
  1345.       args_array[numArgs] = atoi(buf);
  1346.       numArgs++;
  1347.       memset(buf, 0, 10);
  1348.       b = 0;
  1349.     } else {
  1350.       buf[b] = args[i];
  1351.       b++;
  1352.     }    
  1353.   }
  1354.   
  1355.   return dumpState(nodeId, args_array, numArgs);
  1356. }
  1357. int
  1358. MgmtSrvr::dumpState(int nodeId, const Uint32 args[], Uint32 no)
  1359. {
  1360.   INIT_SIGNAL_SENDER(ss,nodeId);
  1361.   const Uint32 len = no > 25 ? 25 : no;
  1362.   
  1363.   SimpleSignal ssig;
  1364.   DumpStateOrd * const dumpOrd = 
  1365.     CAST_PTR(DumpStateOrd, ssig.getDataPtrSend());
  1366.   ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_DUMP_STATE_ORD, len);
  1367.   for(Uint32 i = 0; i<25; i++){
  1368.     if (i < len)
  1369.       dumpOrd->args[i] = args[i];
  1370.     else
  1371.       dumpOrd->args[i] = 0;
  1372.   }
  1373.   
  1374.   return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
  1375. }
  1376. //****************************************************************************
  1377. //****************************************************************************
  1378. const char* MgmtSrvr::getErrorText(int errorCode, char *buf, int buf_sz)
  1379. {
  1380.   for (int i = 0; i < noOfErrorCodes; ++i) {
  1381.     if (errorCode == errorTable[i]._errorCode) {
  1382.       BaseString::snprintf(buf, buf_sz, errorTable[i]._errorText);
  1383.       buf[buf_sz-1]= 0;
  1384.       return buf;
  1385.     }
  1386.   }
  1387.   ndb_error_string(errorCode, buf, buf_sz);
  1388.   buf[buf_sz-1]= 0;
  1389.   return buf;
  1390. }
  1391. void 
  1392. MgmtSrvr::handleReceivedSignal(NdbApiSignal* signal)
  1393. {
  1394.   // The way of handling a received signal is taken from the Ndb class.
  1395.   int returnCode;
  1396.   int gsn = signal->readSignalNumber();
  1397.   switch (gsn) {
  1398.   case GSN_EVENT_SUBSCRIBE_CONF:
  1399.     break;
  1400.   case GSN_EVENT_SUBSCRIBE_REF:
  1401.     break;
  1402.   case GSN_EVENT_REP:
  1403.     eventReport(refToNode(signal->theSendersBlockRef), signal->getDataPtr());
  1404.     break;
  1405.   case GSN_NF_COMPLETEREP:
  1406.     break;
  1407.   case GSN_NODE_FAILREP:
  1408.     break;
  1409.   default:
  1410.     g_eventLogger.error("Unknown signal received. SignalNumber: "
  1411. "%i from (%d, %x)",
  1412. gsn,
  1413. refToNode(signal->theSendersBlockRef),
  1414. refToBlock(signal->theSendersBlockRef));
  1415.   }
  1416.   
  1417.   if (theWaitState == NO_WAIT) {
  1418.     NdbCondition_Signal(theMgmtWaitForResponseCondPtr);
  1419.   }
  1420. }
  1421. void
  1422. MgmtSrvr::handleStatus(NodeId nodeId, bool alive, bool nfComplete)
  1423. {
  1424.   DBUG_ENTER("MgmtSrvr::handleStatus");
  1425.   Uint32 theData[25];
  1426.   theData[1] = nodeId;
  1427.   if (alive) {
  1428.     m_started_nodes.push_back(nodeId);
  1429.     theData[0] = EventReport::Connected;
  1430.   } else {
  1431.     theData[0] = EventReport::Disconnected;
  1432.     if(nfComplete)
  1433.     {
  1434.       DBUG_VOID_RETURN;
  1435.     }
  1436.   }
  1437.   
  1438.   eventReport(_ownNodeId, theData);
  1439.   DBUG_VOID_RETURN;
  1440. }
  1441. //****************************************************************************
  1442. //****************************************************************************
  1443. void 
  1444. MgmtSrvr::signalReceivedNotification(void* mgmtSrvr, 
  1445.                                      NdbApiSignal* signal,
  1446.      LinearSectionPtr ptr[3]) 
  1447. {
  1448.   ((MgmtSrvr*)mgmtSrvr)->handleReceivedSignal(signal);
  1449. }
  1450. //****************************************************************************
  1451. //****************************************************************************
  1452. void 
  1453. MgmtSrvr::nodeStatusNotification(void* mgmSrv, Uint32 nodeId, 
  1454.  bool alive, bool nfComplete)
  1455. {
  1456.   DBUG_ENTER("MgmtSrvr::nodeStatusNotification");
  1457.   DBUG_PRINT("enter",("nodeid= %d, alive= %d, nfComplete= %d", nodeId, alive, nfComplete));
  1458.   ((MgmtSrvr*)mgmSrv)->handleStatus(nodeId, alive, nfComplete);
  1459.   DBUG_VOID_RETURN;
  1460. }
  1461. enum ndb_mgm_node_type 
  1462. MgmtSrvr::getNodeType(NodeId nodeId) const 
  1463. {
  1464.   if(nodeId >= MAX_NODES)
  1465.     return (enum ndb_mgm_node_type)-1;
  1466.   
  1467.   return nodeTypes[nodeId];
  1468. }
  1469. const char *MgmtSrvr::get_connect_address(Uint32 node_id)
  1470. {
  1471.   if (m_connect_address[node_id].s_addr == 0 &&
  1472.       theFacade && theFacade->theTransporterRegistry &&
  1473.       theFacade->theClusterMgr &&
  1474.       getNodeType(node_id) == NDB_MGM_NODE_TYPE_NDB) 
  1475.   {
  1476.     const ClusterMgr::Node &node=
  1477.       theFacade->theClusterMgr->getNodeInfo(node_id);
  1478.     if (node.connected)
  1479.     {
  1480.       m_connect_address[node_id]=
  1481. theFacade->theTransporterRegistry->get_connect_address(node_id);
  1482.     }
  1483.   }
  1484.   return inet_ntoa(m_connect_address[node_id]);  
  1485. }
  1486. void
  1487. MgmtSrvr::get_connected_nodes(NodeBitmask &connected_nodes) const
  1488. {
  1489.   if (theFacade && theFacade->theClusterMgr) 
  1490.   {
  1491.     for(Uint32 i = 0; i < MAX_NODES; i++)
  1492.     {
  1493.       if (getNodeType(i) == NDB_MGM_NODE_TYPE_NDB)
  1494.       {
  1495. const ClusterMgr::Node &node= theFacade->theClusterMgr->getNodeInfo(i);
  1496. if (node.connected)
  1497. {
  1498.   connected_nodes.bitOR(node.m_state.m_connected_nodes);
  1499. }
  1500.       }
  1501.     }
  1502.   }
  1503. }
  1504. bool
  1505. MgmtSrvr::alloc_node_id(NodeId * nodeId, 
  1506. enum ndb_mgm_node_type type,
  1507. struct sockaddr *client_addr, 
  1508. SOCKET_SIZE_TYPE *client_addr_len,
  1509. BaseString &error_string)
  1510. {
  1511.   DBUG_ENTER("MgmtSrvr::alloc_node_id");
  1512.   DBUG_PRINT("enter", ("nodeid=%d, type=%d, client_addr=%d",
  1513.        *nodeId, type, client_addr));
  1514.   if (g_no_nodeid_checks) {
  1515.     if (*nodeId == 0) {
  1516.       error_string.appfmt("no-nodeid-checks set in management server.n"
  1517.   "node id must be set explicitly in connectstring");
  1518.       DBUG_RETURN(false);
  1519.     }
  1520.     DBUG_RETURN(true);
  1521.   }
  1522.   Guard g(m_node_id_mutex);
  1523.   int no_mgm= 0;
  1524.   NodeBitmask connected_nodes(m_reserved_nodes);
  1525.   get_connected_nodes(connected_nodes);
  1526.   {
  1527.     for(Uint32 i = 0; i < MAX_NODES; i++)
  1528.       if (getNodeType(i) == NDB_MGM_NODE_TYPE_MGM)
  1529. no_mgm++;
  1530.   }
  1531.   bool found_matching_id= false;
  1532.   bool found_matching_type= false;
  1533.   bool found_free_node= false;
  1534.   unsigned id_found= 0;
  1535.   const char *config_hostname= 0;
  1536.   struct in_addr config_addr= {0};
  1537.   int r_config_addr= -1;
  1538.   unsigned type_c= 0;
  1539.   ndb_mgm_configuration_iterator
  1540.     iter(*(ndb_mgm_configuration *)_config->m_configValues, CFG_SECTION_NODE);
  1541.   for(iter.first(); iter.valid(); iter.next()) {
  1542.     unsigned tmp= 0;
  1543.     if(iter.get(CFG_NODE_ID, &tmp)) require(false);
  1544.     if (*nodeId && *nodeId != tmp)
  1545.       continue;
  1546.     found_matching_id= true;
  1547.     if(iter.get(CFG_TYPE_OF_SECTION, &type_c)) require(false);
  1548.     if(type_c != (unsigned)type)
  1549.       continue;
  1550.     found_matching_type= true;
  1551.     if (connected_nodes.get(tmp))
  1552.       continue;
  1553.     found_free_node= true;
  1554.     if(iter.get(CFG_NODE_HOST, &config_hostname)) require(false);
  1555.     if (config_hostname && config_hostname[0] == 0)
  1556.       config_hostname= 0;
  1557.     else if (client_addr) {
  1558.       // check hostname compatability
  1559.       const void *tmp_in= &(((sockaddr_in*)client_addr)->sin_addr);
  1560.       if((r_config_addr= Ndb_getInAddr(&config_addr, config_hostname)) != 0
  1561.  || memcmp(&config_addr, tmp_in, sizeof(config_addr)) != 0) {
  1562. struct in_addr tmp_addr;
  1563. if(Ndb_getInAddr(&tmp_addr, "localhost") != 0
  1564.    || memcmp(&tmp_addr, tmp_in, sizeof(config_addr)) != 0) {
  1565.   // not localhost
  1566. #if 0
  1567.   ndbout << "MgmtSrvr::getFreeNodeId compare failed for ""
  1568.  << config_hostname
  1569.  << "" id=" << tmp << endl;
  1570. #endif
  1571.   continue;
  1572. }
  1573. // connecting through localhost
  1574. // check if config_hostname is local
  1575. if (!SocketServer::tryBind(0,config_hostname)) {
  1576.   continue;
  1577. }
  1578.       }
  1579.     } else { // client_addr == 0
  1580.       if (!SocketServer::tryBind(0,config_hostname)) {
  1581. continue;
  1582.       }
  1583.     }
  1584.     if (*nodeId != 0 ||
  1585. type != NDB_MGM_NODE_TYPE_MGM ||
  1586. no_mgm == 1) { // any match is ok
  1587.       if (config_hostname == 0 &&
  1588.   *nodeId == 0 &&
  1589.   type != NDB_MGM_NODE_TYPE_MGM)
  1590.       {
  1591. if (!id_found) // only set if not set earlier
  1592.   id_found= tmp;
  1593. continue; /* continue looking for a nodeid with specified
  1594.    * hostname
  1595.    */
  1596.       }
  1597.       assert(id_found == 0);
  1598.       id_found= tmp;
  1599.       break;
  1600.     }
  1601.     if (id_found) { // mgmt server may only have one match
  1602.       error_string.appfmt("Ambiguous node id's %d and %d.n"
  1603.   "Suggest specifying node id in connectstring,n"
  1604.   "or specifying unique host names in config file.",
  1605.   id_found, tmp);
  1606.       DBUG_RETURN(false);
  1607.     }
  1608.     if (config_hostname == 0) {
  1609.       error_string.appfmt("Ambiguity for node id %d.n"
  1610.   "Suggest specifying node id in connectstring,n"
  1611.   "or specifying unique host names in config file,n"
  1612.   "or specifying just one mgmt server in config file.",
  1613.   tmp);
  1614.       DBUG_RETURN(false);
  1615.     }
  1616.     id_found= tmp; // mgmt server matched, check for more matches
  1617.   }
  1618.   if (id_found)
  1619.   {
  1620.     *nodeId= id_found;
  1621.     DBUG_PRINT("info", ("allocating node id %d",*nodeId));
  1622.     {
  1623.       int r= 0;
  1624.       if (client_addr)
  1625. m_connect_address[id_found]=
  1626.   ((struct sockaddr_in *)client_addr)->sin_addr;
  1627.       else if (config_hostname)
  1628. r= Ndb_getInAddr(&(m_connect_address[id_found]), config_hostname);
  1629.       else {
  1630. char name[256];
  1631. r= gethostname(name, sizeof(name));
  1632. if (r == 0) {
  1633.   name[sizeof(name)-1]= 0;
  1634.   r= Ndb_getInAddr(&(m_connect_address[id_found]), name);
  1635. }
  1636.       }
  1637.       if (r)
  1638. m_connect_address[id_found].s_addr= 0;
  1639.     }
  1640.     m_reserved_nodes.set(id_found);
  1641.     char tmp_str[128];
  1642.     m_reserved_nodes.getText(tmp_str);
  1643.     g_eventLogger.info("Mgmt server state: nodeid %d reserved for ip %s, m_reserved_nodes %s.",
  1644.        id_found, get_connect_address(id_found), tmp_str);
  1645.     DBUG_RETURN(true);
  1646.   }
  1647.   if (found_matching_type && !found_free_node) {
  1648.     // we have a temporary error which might be due to that 
  1649.     // we have got the latest connect status from db-nodes.  Force update.
  1650.     global_flag_send_heartbeat_now= 1;
  1651.   }
  1652.   BaseString type_string, type_c_string;
  1653.   {
  1654.     const char *alias, *str;
  1655.     alias= ndb_mgm_get_node_type_alias_string(type, &str);
  1656.     type_string.assfmt("%s(%s)", alias, str);
  1657.     alias= ndb_mgm_get_node_type_alias_string((enum ndb_mgm_node_type)type_c,
  1658.       &str);
  1659.     type_c_string.assfmt("%s(%s)", alias, str);
  1660.   }
  1661.   if (*nodeId == 0) {
  1662.     if (found_matching_id)
  1663.       if (found_matching_type)
  1664. if (found_free_node)
  1665.   error_string.appfmt("Connection done from wrong host ip %s.",
  1666.       (client_addr)?
  1667.         inet_ntoa(((struct sockaddr_in *)
  1668.  (client_addr))->sin_addr):"");
  1669. else
  1670.   error_string.appfmt("No free node id found for %s.",
  1671.       type_string.c_str());
  1672.       else
  1673. error_string.appfmt("No %s node defined in config file.",
  1674.     type_string.c_str());
  1675.     else
  1676.       error_string.append("No nodes defined in config file.");
  1677.   } else {
  1678.     if (found_matching_id)
  1679.       if (found_matching_type)
  1680. if (found_free_node) {
  1681.   // have to split these into two since inet_ntoa overwrites itself
  1682.   error_string.appfmt("Connection with id %d done from wrong host ip %s,",
  1683.       *nodeId, inet_ntoa(((struct sockaddr_in *)
  1684.   (client_addr))->sin_addr));
  1685.   error_string.appfmt(" expected %s(%s).", config_hostname,
  1686.       r_config_addr ?
  1687.       "lookup failed" : inet_ntoa(config_addr));
  1688. } else
  1689.   error_string.appfmt("Id %d already allocated by another node.",
  1690.       *nodeId);
  1691.       else
  1692. error_string.appfmt("Id %d configured as %s, connect attempted as %s.",
  1693.     *nodeId, type_c_string.c_str(),
  1694.     type_string.c_str());
  1695.     else
  1696.       error_string.appfmt("No node defined with id=%d in config file.",
  1697.   *nodeId);
  1698.   }
  1699.   g_eventLogger.warning("Allocate nodeid (%d) failed. Connection from ip %s. "
  1700. "Returned error string "%s"",
  1701. *nodeId,
  1702. client_addr != 0 ? inet_ntoa(((struct sockaddr_in *)(client_addr))->sin_addr) : "<none>",
  1703. error_string.c_str());
  1704.   NodeBitmask connected_nodes2;
  1705.   get_connected_nodes(connected_nodes2);
  1706.   {
  1707.     BaseString tmp_connected, tmp_not_connected;
  1708.     for(Uint32 i = 0; i < MAX_NODES; i++)
  1709.     {
  1710.       if (connected_nodes2.get(i))
  1711.       {
  1712. if (!m_reserved_nodes.get(i))
  1713.   tmp_connected.appfmt(" %d", i);
  1714.       }
  1715.       else if (m_reserved_nodes.get(i))
  1716.       {
  1717. tmp_not_connected.appfmt(" %d", i);
  1718.       }
  1719.     }
  1720.     if (tmp_connected.length() > 0)
  1721.       g_eventLogger.info("Mgmt server state: node id's %s connected but not reserved", 
  1722.  tmp_connected.c_str());
  1723.     if (tmp_not_connected.length() > 0)
  1724.       g_eventLogger.info("Mgmt server state: node id's %s not connected but reserved",
  1725.  tmp_not_connected.c_str());
  1726.   }
  1727.   DBUG_RETURN(false);
  1728. }
  1729. bool
  1730. MgmtSrvr::getNextNodeId(NodeId * nodeId, enum ndb_mgm_node_type type) const 
  1731. {
  1732.   NodeId tmp = * nodeId;
  1733.   tmp++;
  1734.   while(nodeTypes[tmp] != type && tmp < MAX_NODES)
  1735.     tmp++;
  1736.   
  1737.   if(tmp == MAX_NODES){
  1738.     return false;
  1739.   }
  1740.   * nodeId = tmp;
  1741.   return true;
  1742. }
  1743. #include "Services.hpp"
  1744. void
  1745. MgmtSrvr::eventReport(NodeId nodeId, const Uint32 * theData)
  1746. {
  1747.   const EventReport * const eventReport = (EventReport *)&theData[0];
  1748.   
  1749.   EventReport::EventType type = eventReport->getEventType();
  1750.   // Log event
  1751.   g_eventLogger.log(type, theData, nodeId, 
  1752.     &m_event_listner[0].m_logLevel);  
  1753.   m_event_listner.log(type, theData, nodeId);
  1754. }
  1755. /***************************************************************************
  1756.  * Backup
  1757.  ***************************************************************************/
  1758. int
  1759. MgmtSrvr::startBackup(Uint32& backupId, int waitCompleted)
  1760. {
  1761.   SignalSender ss(theFacade);
  1762.   ss.lock(); // lock will be released on exit
  1763.   bool next;
  1764.   NodeId nodeId = 0;
  1765.   while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true &&
  1766. theFacade->get_node_alive(nodeId) == false);
  1767.   
  1768.   if(!next) return NO_CONTACT_WITH_DB_NODES;
  1769.   SimpleSignal ssig;
  1770.   BackupReq* req = CAST_PTR(BackupReq, ssig.getDataPtrSend());
  1771.   ssig.set(ss, TestOrd::TraceAPI, BACKUP, GSN_BACKUP_REQ, 
  1772.    BackupReq::SignalLength);
  1773.   
  1774.   req->senderData = 19;
  1775.   req->backupDataLen = 0;
  1776.   assert(waitCompleted < 3);
  1777.   req->flags = waitCompleted & 0x3;
  1778.   BackupEvent event;
  1779.   int do_send = 1;
  1780.   while (1) {
  1781.     if (do_send)
  1782.     {
  1783.       if (ss.sendSignal(nodeId, &ssig) != SEND_OK) {
  1784. return SEND_OR_RECEIVE_FAILED;
  1785.       }
  1786.       if (waitCompleted == 0)
  1787. return 0;
  1788.       do_send = 0;
  1789.     }
  1790.     SimpleSignal *signal = ss.waitFor();
  1791.     int gsn = signal->readSignalNumber();
  1792.     switch (gsn) {
  1793.     case GSN_BACKUP_CONF:{
  1794.       const BackupConf * const conf = 
  1795. CAST_CONSTPTR(BackupConf, signal->getDataPtr());
  1796.       event.Event = BackupEvent::BackupStarted;
  1797.       event.Started.BackupId = conf->backupId;
  1798.       event.Nodes = conf->nodes;
  1799. #ifdef VM_TRACE
  1800.       ndbout_c("Backup(%d) master is %d", conf->backupId,
  1801.        refToNode(signal->header.theSendersBlockRef));
  1802. #endif
  1803.       backupId = conf->backupId;
  1804.       if (waitCompleted == 1)
  1805. return 0;
  1806.       // wait for next signal
  1807.       break;
  1808.     }
  1809.     case GSN_BACKUP_COMPLETE_REP:{
  1810.       const BackupCompleteRep * const rep = 
  1811. CAST_CONSTPTR(BackupCompleteRep, signal->getDataPtr());
  1812. #ifdef VM_TRACE
  1813.       ndbout_c("Backup(%d) completed %d", rep->backupId);
  1814. #endif
  1815.       event.Event = BackupEvent::BackupCompleted;
  1816.       event.Completed.BackupId = rep->backupId;
  1817.     
  1818.       event.Completed.NoOfBytes = rep->noOfBytes;
  1819.       event.Completed.NoOfLogBytes = rep->noOfLogBytes;
  1820.       event.Completed.NoOfRecords = rep->noOfRecords;
  1821.       event.Completed.NoOfLogRecords = rep->noOfLogRecords;
  1822.       event.Completed.stopGCP = rep->stopGCP;
  1823.       event.Completed.startGCP = rep->startGCP;
  1824.       event.Nodes = rep->nodes;
  1825.       backupId = rep->backupId;
  1826.       return 0;
  1827.     }
  1828.     case GSN_BACKUP_REF:{
  1829.       const BackupRef * const ref = 
  1830. CAST_CONSTPTR(BackupRef, signal->getDataPtr());
  1831.       if(ref->errorCode == BackupRef::IAmNotMaster){
  1832. nodeId = refToNode(ref->masterRef);
  1833. #ifdef VM_TRACE
  1834. ndbout_c("I'm not master resending to %d", nodeId);
  1835. #endif
  1836. do_send = 1; // try again
  1837. continue;
  1838.       }
  1839.       event.Event = BackupEvent::BackupFailedToStart;
  1840.       event.FailedToStart.ErrorCode = ref->errorCode;
  1841.       return ref->errorCode;
  1842.     }
  1843.     case GSN_BACKUP_ABORT_REP:{
  1844.       const BackupAbortRep * const rep = 
  1845. CAST_CONSTPTR(BackupAbortRep, signal->getDataPtr());
  1846.       event.Event = BackupEvent::BackupAborted;
  1847.       event.Aborted.Reason = rep->reason;
  1848.       event.Aborted.BackupId = rep->backupId;
  1849.       event.Aborted.ErrorCode = rep->reason;
  1850. #ifdef VM_TRACE
  1851.       ndbout_c("Backup %d aborted", rep->backupId);
  1852. #endif
  1853.       return rep->reason;
  1854.     }
  1855.     case GSN_NF_COMPLETEREP:{
  1856.       const NFCompleteRep * const rep =
  1857. CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr());
  1858. #ifdef VM_TRACE
  1859.       ndbout_c("Node %d fail completed", rep->failedNodeId);
  1860. #endif
  1861.       if (rep->failedNodeId == nodeId ||
  1862.   waitCompleted == 1)
  1863. return 1326;
  1864.       // wait for next signal
  1865.       // master node will report aborted backup
  1866.       break;
  1867.     }
  1868.     case GSN_NODE_FAILREP:{
  1869.       const NodeFailRep * const rep =
  1870. CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
  1871.       if (NodeBitmask::get(rep->theNodes,nodeId) ||
  1872.   waitCompleted == 1)
  1873. return 1326;
  1874.       // wait for next signal
  1875.       // master node will report aborted backup
  1876.       break;
  1877.     }
  1878.     default:
  1879.       report_unknown_signal(signal);
  1880.       return SEND_OR_RECEIVE_FAILED;
  1881.     }
  1882.   }
  1883. }
  1884. int 
  1885. MgmtSrvr::abortBackup(Uint32 backupId)
  1886. {
  1887.   SignalSender ss(theFacade);
  1888.   bool next;
  1889.   NodeId nodeId = 0;
  1890.   while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true &&
  1891. theFacade->get_node_alive(nodeId) == false);
  1892.   
  1893.   if(!next){
  1894.     return NO_CONTACT_WITH_DB_NODES;
  1895.   }
  1896.   
  1897.   SimpleSignal ssig;
  1898.   AbortBackupOrd* ord = CAST_PTR(AbortBackupOrd, ssig.getDataPtrSend());
  1899.   ssig.set(ss, TestOrd::TraceAPI, BACKUP, GSN_ABORT_BACKUP_ORD, 
  1900.    AbortBackupOrd::SignalLength);
  1901.   
  1902.   ord->requestType = AbortBackupOrd::ClientAbort;
  1903.   ord->senderData = 19;
  1904.   ord->backupId = backupId;
  1905.   
  1906.   return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
  1907. }
  1908. /*****************************************************************************
  1909.  * Global Replication
  1910.  *****************************************************************************/
  1911. int
  1912. MgmtSrvr::repCommand(Uint32* repReqId, Uint32 request, bool waitCompleted)
  1913. {
  1914.   require(false);
  1915.   return 0;
  1916. }
  1917. MgmtSrvr::Allocated_resources::Allocated_resources(MgmtSrvr &m)
  1918.   : m_mgmsrv(m)
  1919. {
  1920. }
  1921. MgmtSrvr::Allocated_resources::~Allocated_resources()
  1922. {
  1923.   Guard g(m_mgmsrv.m_node_id_mutex);
  1924.   if (!m_reserved_nodes.isclear()) {
  1925.     m_mgmsrv.m_reserved_nodes.bitANDC(m_reserved_nodes); 
  1926.     // node has been reserved, force update signal to ndb nodes
  1927.     global_flag_send_heartbeat_now= 1;
  1928.     char tmp_str[128];
  1929.     m_mgmsrv.m_reserved_nodes.getText(tmp_str);
  1930.     g_eventLogger.info("Mgmt server state: nodeid %d freed, m_reserved_nodes %s.",
  1931.        get_nodeid(), tmp_str);
  1932.   }
  1933. }
  1934. void
  1935. MgmtSrvr::Allocated_resources::reserve_node(NodeId id)
  1936. {
  1937.   m_reserved_nodes.set(id);
  1938. }
  1939. NodeId
  1940. MgmtSrvr::Allocated_resources::get_nodeid() const
  1941. {
  1942.   for(Uint32 i = 0; i < MAX_NODES; i++)
  1943.   {
  1944.     if (m_reserved_nodes.get(i))
  1945.       return i;
  1946.   }
  1947.   return 0;
  1948. }
  1949. int
  1950. MgmtSrvr::setDbParameter(int node, int param, const char * value,
  1951.  BaseString& msg){
  1952.   /**
  1953.    * Check parameter
  1954.    */
  1955.   ndb_mgm_configuration_iterator iter(* _config->m_configValues, 
  1956.       CFG_SECTION_NODE);
  1957.   if(iter.first() != 0){
  1958.     msg.assign("Unable to find node section (iter.first())");
  1959.     return -1;
  1960.   }
  1961.   
  1962.   Uint32 type = NODE_TYPE_DB + 1;
  1963.   if(node != 0){
  1964.     if(iter.find(CFG_NODE_ID, node) != 0){
  1965.       msg.assign("Unable to find node (iter.find())");
  1966.       return -1;
  1967.     }
  1968.     if(iter.get(CFG_TYPE_OF_SECTION, &type) != 0){
  1969.       msg.assign("Unable to get node type(iter.get(CFG_TYPE_OF_SECTION))");
  1970.       return -1;
  1971.     }
  1972.   } else {
  1973.     do {
  1974.       if(iter.get(CFG_TYPE_OF_SECTION, &type) != 0){
  1975. msg.assign("Unable to get node type(iter.get(CFG_TYPE_OF_SECTION))");
  1976. return -1;
  1977.       }
  1978.       if(type == NODE_TYPE_DB)
  1979. break;
  1980.     } while(iter.next() == 0);
  1981.   }
  1982.   
  1983.   if(type != NODE_TYPE_DB){
  1984.     msg.assfmt("Invalid node type or no such node (%d %d)", 
  1985.        type, NODE_TYPE_DB);
  1986.     return -1;
  1987.   }
  1988.   int p_type;
  1989.   unsigned val_32;
  1990.   Uint64 val_64;
  1991.   const char * val_char;
  1992.   do {
  1993.     p_type = 0;
  1994.     if(iter.get(param, &val_32) == 0){
  1995.       val_32 = atoi(value);
  1996.       break;
  1997.     }
  1998.     
  1999.     p_type++;
  2000.     if(iter.get(param, &val_64) == 0){
  2001.       val_64 = strtoll(value, 0, 10);
  2002.       break;
  2003.     }
  2004.     p_type++;
  2005.     if(iter.get(param, &val_char) == 0){
  2006.       val_char = value;
  2007.       break;
  2008.     }
  2009.     msg.assign("Could not get parameter");
  2010.     return -1;
  2011.   } while(0);
  2012.   
  2013.   bool res = false;
  2014.   do {
  2015.     int ret = iter.get(CFG_TYPE_OF_SECTION, &type);
  2016.     assert(ret == 0);
  2017.     
  2018.     if(type != NODE_TYPE_DB)
  2019.       continue;
  2020.     
  2021.     Uint32 node;
  2022.     ret = iter.get(CFG_NODE_ID, &node);
  2023.     assert(ret == 0);
  2024.     
  2025.     ConfigValues::Iterator i2(_config->m_configValues->m_config, 
  2026.       iter.m_config);
  2027.     switch(p_type){
  2028.     case 0:
  2029.       res = i2.set(param, val_32);
  2030.       ndbout_c("Updating node %d param: %d to %d",  node, param, val_32);
  2031.       break;
  2032.     case 1:
  2033.       res = i2.set(param, val_64);
  2034.       ndbout_c("Updating node %d param: %d to %Ld",  node, param, val_32);
  2035.       break;
  2036.     case 2:
  2037.       res = i2.set(param, val_char);
  2038.       ndbout_c("Updating node %d param: %d to %s",  node, param, val_char);
  2039.       break;
  2040.     default:
  2041.       require(false);
  2042.     }
  2043.     assert(res);
  2044.   } while(node == 0 && iter.next() == 0);
  2045.   msg.assign("Success");
  2046.   return 0;
  2047. }
  2048. template class MutexVector<unsigned short>;
  2049. template class MutexVector<Ndb_mgmd_event_service::Event_listener>;
  2050. template class MutexVector<EventSubscribeReq>;