MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MgmtSrvr.cpp
1 /*
2  Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 #include <ndb_global.h>
19 
20 #include "MgmtSrvr.hpp"
21 #include "ndb_mgmd_error.h"
22 #include "Services.hpp"
23 #include "ConfigManager.hpp"
24 #include "Defragger.hpp"
25 
26 #include <NdbOut.hpp>
27 #include <NdbApiSignal.hpp>
28 #include <kernel_types.h>
29 #include <GlobalSignalNumbers.h>
30 #include <signaldata/TestOrd.hpp>
31 #include <signaldata/TamperOrd.hpp>
32 #include <signaldata/StartOrd.hpp>
33 #include <signaldata/ApiVersion.hpp>
34 #include <signaldata/ResumeReq.hpp>
35 #include <signaldata/SetLogLevelOrd.hpp>
36 #include <signaldata/EventSubscribeReq.hpp>
37 #include <signaldata/EventReport.hpp>
38 #include <signaldata/DumpStateOrd.hpp>
39 #include <signaldata/BackupSignalData.hpp>
40 #include <signaldata/NFCompleteRep.hpp>
41 #include <signaldata/NodeFailRep.hpp>
42 #include <signaldata/AllocNodeId.hpp>
43 #include <signaldata/SchemaTrans.hpp>
44 #include <signaldata/CreateNodegroup.hpp>
45 #include <signaldata/DropNodegroup.hpp>
46 #include <signaldata/Sync.hpp>
47 #include <signaldata/GetConfig.hpp>
48 #include <NdbSleep.h>
49 #include <portlib/NdbDir.hpp>
50 #include <EventLogger.hpp>
51 #include <DebuggerNames.hpp>
52 #include <ndb_version.h>
53 
54 #include <SocketServer.hpp>
55 #include <NdbConfig.h>
56 
57 #include <NdbAutoPtr.hpp>
58 #include <NdbDir.hpp>
59 #include <ndberror.h>
60 
61 #include <mgmapi.h>
62 #include <mgmapi_configuration.hpp>
63 #include <mgmapi_config_parameters.h>
64 
65 #include <SignalSender.hpp>
66 
67 int g_errorInsert;
68 #define ERROR_INSERTED(x) (g_errorInsert == x)
69 
70 #define INIT_SIGNAL_SENDER(ss,nodeId) \
71  SignalSender ss(theFacade); \
72  ss.lock(); /* lock will be released on exit */ \
73  {\
74  int result = okToSendTo(nodeId, true);\
75  if (result != 0) {\
76  return result;\
77  }\
78  }
79 
80 extern "C" my_bool opt_core;
81 
82 void *
83 MgmtSrvr::logLevelThread_C(void* m)
84 {
85  MgmtSrvr *mgm = (MgmtSrvr*)m;
86  mgm->logLevelThreadRun();
87  return 0;
88 }
89 
90 extern EventLogger * g_eventLogger;
91 
92 #ifdef NOT_USED
93 static NdbOut&
94 operator<<(NdbOut& out, const LogLevel & ll)
95 {
96  out << "[LogLevel: ";
97  for(size_t i = 0; i<LogLevel::LOGLEVEL_CATEGORIES; i++)
98  out << ll.getLogLevel((LogLevel::EventCategory)i) << " ";
99  out << "]";
100  return out;
101 }
102 #endif
103 
104 void
105 MgmtSrvr::logLevelThreadRun()
106 {
107  while (!_isStopThread)
108  {
109  Vector<NodeId> failed_started_nodes;
110  Vector<EventSubscribeReq> failed_log_level_requests;
111 
115  m_started_nodes.lock();
116  if (m_started_nodes.size() > 0)
117  {
118  // calculate max log level
119  EventSubscribeReq req;
120  {
121  LogLevel tmp;
122  m_event_listner.lock();
123  for(int i = m_event_listner.m_clients.size() - 1; i >= 0; i--)
124  tmp.set_max(m_event_listner[i].m_logLevel);
125  m_event_listner.unlock();
126  req.assign(tmp);
127  }
128  req.blockRef = _ownReference;
129  while (m_started_nodes.size() > 0)
130  {
131  Uint32 node = m_started_nodes[0];
132  m_started_nodes.erase(0, false);
133  m_started_nodes.unlock();
134 
135  if (setEventReportingLevelImpl(node, req))
136  {
137  failed_started_nodes.push_back(node);
138  }
139  else
140  {
141  SetLogLevelOrd ord;
142  ord.assign(m_nodeLogLevel[node]);
143  setNodeLogLevelImpl(node, ord);
144  }
145  m_started_nodes.lock();
146  }
147  }
148  m_started_nodes.unlock();
149 
150  m_log_level_requests.lock();
151  while (m_log_level_requests.size() > 0)
152  {
153  EventSubscribeReq req = m_log_level_requests[0];
154  m_log_level_requests.erase(0, false);
155  m_log_level_requests.unlock();
156 
157  if(req.blockRef == 0)
158  {
159  req.blockRef = _ownReference;
160  if (setEventReportingLevelImpl(0, req))
161  {
162  failed_log_level_requests.push_back(req);
163  }
164  }
165  else
166  {
167  SetLogLevelOrd ord;
168  ord.assign(req);
169  if (setNodeLogLevelImpl(req.blockRef, ord))
170  {
171  failed_log_level_requests.push_back(req);
172  }
173  }
174  m_log_level_requests.lock();
175  }
176  m_log_level_requests.unlock();
177 
178  if(!ERROR_INSERTED(10000))
179  m_event_listner.check_listeners();
180 
181  Uint32 sleeptime = _logLevelThreadSleep;
182  if (failed_started_nodes.size())
183  {
184  m_started_nodes.lock();
185  for (Uint32 i = 0; i<failed_started_nodes.size(); i++)
186  m_started_nodes.push_back(failed_started_nodes[i], false);
187  m_started_nodes.unlock();
188  failed_started_nodes.clear();
189  sleeptime = 100;
190  }
191 
192  if (failed_log_level_requests.size())
193  {
194  m_log_level_requests.lock();
195  for (Uint32 i = 0; i<failed_log_level_requests.size(); i++)
196  m_log_level_requests.push_back(failed_log_level_requests[i], false);
197  m_log_level_requests.unlock();
198  failed_log_level_requests.clear();
199  sleeptime = 100;
200  }
201 
202  NdbSleep_MilliSleep(sleeptime);
203  }
204 }
205 
206 
207 static int
208 translateStopRef(Uint32 errCode)
209 {
210  switch(errCode){
211  case StopRef::NodeShutdownInProgress:
212  return NODE_SHUTDOWN_IN_PROGESS;
213  break;
214  case StopRef::SystemShutdownInProgress:
215  return SYSTEM_SHUTDOWN_IN_PROGRESS;
216  break;
217  case StopRef::NodeShutdownWouldCauseSystemCrash:
218  return NODE_SHUTDOWN_WOULD_CAUSE_SYSTEM_CRASH;
219  break;
220  case StopRef::UnsupportedNodeShutdown:
221  return UNSUPPORTED_NODE_SHUTDOWN;
222  break;
223  }
224  return 4999;
225 }
226 
227 
228 MgmtSrvr::MgmtSrvr(const MgmtOpts& opts) :
229  m_opts(opts),
230  _blockNumber(-1),
231  _ownNodeId(0),
232  m_port(0),
233  m_local_config(NULL),
234  _ownReference(0),
235  m_config_manager(NULL),
236  m_need_restart(false),
237  theFacade(NULL),
238  _isStopThread(false),
239  _logLevelThreadSleep(500),
240  m_event_listner(this),
241  m_master_node(0),
242  _logLevelThread(NULL),
243  m_version_string(ndbGetOwnVersionString())
244 {
245  DBUG_ENTER("MgmtSrvr::MgmtSrvr");
246 
247  m_local_config_mutex= NdbMutex_Create();
248  m_node_id_mutex = NdbMutex_Create();
249  if (!m_local_config_mutex || !m_node_id_mutex)
250  {
251  g_eventLogger->error("Failed to create MgmtSrvr mutexes");
252  require(false);
253  }
254 
255  /* Init node arrays */
256  for(Uint32 i = 0; i<MAX_NODES; i++) {
257  nodeTypes[i] = (enum ndb_mgm_node_type)-1;
258  m_connect_address[i].s_addr= 0;
259  }
260 
261  /* Setup clusterlog as client[0] in m_event_listner */
262  {
264  my_socket_invalidate(&(se.m_socket));
265  for(size_t t = 0; t<LogLevel::LOGLEVEL_CATEGORIES; t++){
266  se.m_logLevel.setLogLevel((LogLevel::EventCategory)t, 7);
267  }
268  se.m_logLevel.setLogLevel(LogLevel::llError, 15);
269  se.m_logLevel.setLogLevel(LogLevel::llConnection, 8);
270  se.m_logLevel.setLogLevel(LogLevel::llBackup, 15);
271  m_event_listner.m_clients.push_back(se);
272  m_event_listner.m_logLevel = se.m_logLevel;
273  }
274 
275  DBUG_VOID_RETURN;
276 }
277 
278 
279 /*
280  check_configdir
281 
282  Make sure configdir exist and try to create it if not
283 
284 */
285 
286 const char*
287 MgmtSrvr::check_configdir() const
288 {
289  if (m_opts.configdir &&
290  strcmp(m_opts.configdir, MYSQLCLUSTERDIR) != 0)
291  {
292  // Specified on commmand line
293  if (access(m_opts.configdir, F_OK))
294  {
295  g_eventLogger->error("Directory '%s' specified with --configdir " \
296  "does not exist. Either create it or pass " \
297  "the path to an already existing directory.",
298  m_opts.configdir);
299  return NULL;
300  }
301  return m_opts.configdir;
302  }
303  else
304  {
305  // Compiled in path MYSQLCLUSTERDIR
306  if (access(MYSQLCLUSTERDIR, F_OK))
307  {
308  g_eventLogger->info("The default config directory '%s' " \
309  "does not exist. Trying to create it...",
310  MYSQLCLUSTERDIR);
311 
312  if (!NdbDir::create(MYSQLCLUSTERDIR) ||
313  access(MYSQLCLUSTERDIR, F_OK))
314  {
315  g_eventLogger->error("Could not create directory '%s'. " \
316  "Either create it manually or " \
317  "specify a different directory with " \
318  "--configdir=<path>",
319  MYSQLCLUSTERDIR);
320  return NULL;
321  }
322 
323  g_eventLogger->info("Sucessfully created config directory");
324  }
325  return MYSQLCLUSTERDIR;
326  }
327 }
328 
329 
330 bool
331 MgmtSrvr::init()
332 {
333  DBUG_ENTER("MgmtSrvr::init");
334 
335  const char* configdir;
336  if (!(configdir= check_configdir()))
337  DBUG_RETURN(false);
338 
339  if (!(m_config_manager= new ConfigManager(m_opts, configdir)))
340  {
341  g_eventLogger->error("Failed to create ConfigManager");
342  DBUG_RETURN(false);
343  }
344 
345  if (m_config_manager->add_config_change_subscriber(this) < 0)
346  {
347  g_eventLogger->error("Failed to add MgmtSrvr as config change subscriber");
348  DBUG_RETURN(false);
349  }
350 
351  if (!m_config_manager->init())
352  {
353  DBUG_RETURN(false);
354  }
355 
356  /* 'config_changed' should have been called from 'init' */
357  require(m_local_config != 0);
358 
359  if (m_opts.print_full_config)
360  {
361  print_config();
362  DBUG_RETURN(false);
363  }
364 
365  assert(_ownNodeId);
366 
367  /* Reserve the node id with ourself */
368  NodeId nodeId= _ownNodeId;
369  int error_code;
370  BaseString error_string;
371  if (!alloc_node_id(&nodeId, NDB_MGM_NODE_TYPE_MGM,
372  0, 0, /* client_addr, len */
373  error_code, error_string,
374  0 /* log_event */ ))
375  {
376  g_eventLogger->error("INTERNAL ERROR: Could not allocate nodeid: %d, " \
377  "error: %d, '%s'",
378  _ownNodeId, error_code, error_string.c_str());
379  DBUG_RETURN(false);
380  }
381 
382  if (nodeId != _ownNodeId)
383  {
384  g_eventLogger->error("INTERNAL ERROR: Nodeid %d allocated " \
385  "when %d was requested",
386  nodeId, _ownNodeId);
387  DBUG_RETURN(false);
388  }
389 
390  DBUG_RETURN(true);
391 }
392 
393 
394 bool
395 MgmtSrvr::start_transporter(const Config* config)
396 {
397  DBUG_ENTER("MgmtSrvr::start_transporter");
398 
399  theFacade= new TransporterFacade(0);
400  if (theFacade == 0)
401  {
402  g_eventLogger->error("Could not create TransporterFacade.");
403  DBUG_RETURN(false);
404  }
405 
406  assert(_blockNumber == -1); // Blocknumber shouldn't been allocated yet
407 
408  /*
409  Register ourself at TransporterFacade to be able to receive signals
410  and to be notified when a database process has died.
411  */
412  Uint32 res;
413  if ((res = open(theFacade)) == 0)
414  {
415  g_eventLogger->error("Failed to open block in TransporterFacade");
416  theFacade->stop_instance();
417  delete theFacade;
418  theFacade = 0;
419  DBUG_RETURN(false);
420  }
421  _blockNumber = refToBlock(res);
422 
426  m_config_manager->set_facade(theFacade);
427 
428  if (theFacade->start_instance(_ownNodeId,
429  config->m_configValues) < 0)
430  {
431  g_eventLogger->error("Failed to start transporter");
432  delete theFacade;
433  theFacade = 0;
434  DBUG_RETURN(false);
435  }
436 
437  _ownReference = numberToRef(_blockNumber, _ownNodeId);
438 
439  /*
440  set api reg req frequency quite high:
441 
442  100 ms interval to make sure we have fairly up-to-date
443  info from the nodes. This to make sure that this info
444  is not dependent on heartbeat settings in the
445  configuration
446  */
447  theFacade->ext_set_max_api_reg_req_interval(100);
448 
449  DBUG_RETURN(true);
450 }
451 
452 
453 bool
454 MgmtSrvr::start_mgm_service(const Config* config)
455 {
456  DBUG_ENTER("MgmtSrvr::start_mgm_service");
457 
458  assert(m_port == 0);
459  {
460  // Find the portnumber to use for mgm service
461  ConfigIter iter(config, CFG_SECTION_NODE);
462 
463  if(iter.find(CFG_NODE_ID, _ownNodeId) != 0){
464  g_eventLogger->error("Could not find node %d in config", _ownNodeId);
465  DBUG_RETURN(false);
466  }
467 
468  unsigned type;
469  if(iter.get(CFG_TYPE_OF_SECTION, &type) != 0 ||
470  type != NODE_TYPE_MGM){
471  g_eventLogger->error("Node %d is not defined as management server",
472  _ownNodeId);
473  DBUG_RETURN(false);
474  }
475 
476  if(iter.get(CFG_MGM_PORT, &m_port) != 0){
477  g_eventLogger->error("PortNumber not defined for node %d", _ownNodeId);
478  DBUG_RETURN(false);
479  }
480  }
481 
482  unsigned short port= m_port;
483  DBUG_PRINT("info", ("Using port %d", port));
484  if (port == 0)
485  {
486  g_eventLogger->error("Could not find out which port to use"\
487  " for management service");
488  DBUG_RETURN(false);
489  }
490 
491  {
492  int count= 5; // no of retries for tryBind
493  while(!m_socket_server.tryBind(port, m_opts.bind_address))
494  {
495  if (--count > 0)
496  {
497  NdbSleep_SecSleep(1);
498  continue;
499  }
500  g_eventLogger->error("Unable to bind management service port: %s:%d!\n"
501  "Please check if the port is already used,\n"
502  "(perhaps a ndb_mgmd is already running),\n"
503  "and if you are executing on the correct computer",
504  (m_opts.bind_address ? m_opts.bind_address : "*"),
505  port);
506  DBUG_RETURN(false);
507  }
508  }
509 
510  {
511  MgmApiService * mapi = new MgmApiService(*this);
512  if (mapi == NULL)
513  {
514  g_eventLogger->error("Could not allocate MgmApiService");
515  DBUG_RETURN(false);
516  }
517 
518  if(!m_socket_server.setup(mapi, &port, m_opts.bind_address))
519  {
520  delete mapi; // Will be deleted by SocketServer in all other cases
521  g_eventLogger->error("Unable to setup management service port: %s:%d!\n"
522  "Please check if the port is already used,\n"
523  "(perhaps a ndb_mgmd is already running),\n"
524  "and if you are executing on the correct computer",
525  (m_opts.bind_address ? m_opts.bind_address : "*"),
526  port);
527  DBUG_RETURN(false);
528  }
529 
530  if (port != m_port)
531  {
532  g_eventLogger->error("Couldn't start management service on the "\
533  "requested port: %d. Got port: %d instead",
534  m_port, port);
535  DBUG_RETURN(false);
536  }
537  }
538 
539  m_socket_server.startServer();
540 
541  g_eventLogger->info("Id: %d, Command port: %s:%d",
542  _ownNodeId,
543  m_opts.bind_address ? m_opts.bind_address : "*",
544  port);
545  DBUG_RETURN(true);
546 }
547 
548 
549 bool
550 MgmtSrvr::start()
551 {
552  DBUG_ENTER("MgmtSrvr::start");
553 
554  Guard g(m_local_config_mutex);
555 
556  /* Start transporter */
557  if(!start_transporter(m_local_config))
558  {
559  g_eventLogger->error("Failed to start transporter!");
560  DBUG_RETURN(false);
561  }
562 
563  /* Start mgm service */
564  if (!start_mgm_service(m_local_config))
565  {
566  g_eventLogger->error("Failed to start mangement service!");
567  DBUG_RETURN(false);
568  }
569 
570  /* Use local MGM port for TransporterRegistry */
571  if(!connect_to_self())
572  {
573  g_eventLogger->error("Failed to connect to ourself!");
574  DBUG_RETURN(false);
575  }
576 
577  /* Start config manager */
578  if (!m_config_manager->start())
579  {
580  g_eventLogger->error("Failed to start ConfigManager");
581  DBUG_RETURN(false);
582  }
583 
584  /* Loglevel thread */
585  assert(_isStopThread == false);
586  _logLevelThread = NdbThread_Create(logLevelThread_C,
587  (void**)this,
588  0, // default stack size
589  "MgmtSrvr_Loglevel",
590  NDB_THREAD_PRIO_LOW);
591 
592  DBUG_RETURN(true);
593 }
594 
595 
596 void
597 MgmtSrvr::setClusterLog(const Config* config)
598 {
599  DBUG_ASSERT(_ownNodeId);
600 
601  ConfigIter iter(config, CFG_SECTION_NODE);
602  require(iter.find(CFG_NODE_ID, _ownNodeId) == 0);
603 
604  // Update DataDir from config
605  const char *datadir;
606  require(iter.get(CFG_NODE_DATADIR, &datadir) == 0);
607  NdbConfig_SetPath(datadir);
608 
609  if (NdbDir::chdir(NdbConfig_get_path(NULL)) != 0)
610  {
611  g_eventLogger->warning("Cannot change directory to '%s', error: %d",
612  NdbConfig_get_path(NULL), errno);
613  // Ignore error
614  }
615 
616  // Get log destination from config
617  BaseString logdest;
618  const char *value;
619  if(iter.get(CFG_LOG_DESTINATION, &value) == 0){
620  logdest.assign(value);
621  }
622 
623  bool logdest_configured = true;
624  if(logdest.length() == 0 || logdest == "") {
625  // No LogDestination set, use default settings
626  char *clusterLog= NdbConfig_ClusterLogFileName(_ownNodeId);
627  logdest.assfmt("FILE:filename=%s,maxsize=1000000,maxfiles=6",
628  clusterLog);
629  free(clusterLog);
630  logdest_configured = false;
631  }
632 
633  g_eventLogger->close();
634 
635  int err= 0;
636  char errStr[100]= {0};
637  if(!g_eventLogger->addHandler(logdest, &err, sizeof(errStr), errStr)) {
638  ndbout << "Warning: could not add log destination '"
639  << logdest.c_str() << "'. Reason: ";
640  if(err)
641  ndbout << strerror(err);
642  if(err && errStr[0]!='\0')
643  ndbout << ", ";
644  if(errStr[0]!='\0')
645  ndbout << errStr;
646  ndbout << endl;
647  }
648 
649  if (logdest_configured == false &&
650  m_opts.non_interactive)
651  {
652  g_eventLogger->createConsoleHandler();
653  }
654 
655 #ifdef _WIN32
656  /* Output to Windows event log */
657  g_eventLogger->createEventLogHandler("MySQL Cluster Management Server");
658 #endif
659 
660  if (m_opts.verbose)
661  g_eventLogger->enable(Logger::LL_DEBUG);
662 }
663 
664 
665 void
666 MgmtSrvr::config_changed(NodeId node_id, const Config* new_config)
667 {
668  DBUG_ENTER("MgmtSrvr::config_changed");
669 
670  Guard g(m_local_config_mutex);
671 
672  // Don't allow nodeid to change, once it's been set
673  require(_ownNodeId == 0 || _ownNodeId == node_id);
674 
675  _ownNodeId= node_id;
676 
677  if (m_local_config)
678  delete m_local_config;
679 
680  m_local_config= new Config(new_config); // Copy
681  require(m_local_config != 0);
682 
683  /* Rebuild node arrays */
684  ConfigIter iter(m_local_config, CFG_SECTION_NODE);
685  for(Uint32 i = 0; i<MAX_NODES; i++) {
686 
687  m_connect_address[i].s_addr= 0;
688 
689  if (iter.first())
690  continue;
691 
692  if (iter.find(CFG_NODE_ID, i) == 0){
693  unsigned type;
694  require(iter.get(CFG_TYPE_OF_SECTION, &type) == 0);
695 
696  switch(type){
697  case NODE_TYPE_DB:
698  nodeTypes[i] = NDB_MGM_NODE_TYPE_NDB;
699  break;
700  case NODE_TYPE_API:
701  nodeTypes[i] = NDB_MGM_NODE_TYPE_API;
702  break;
703  case NODE_TYPE_MGM:
704  nodeTypes[i] = NDB_MGM_NODE_TYPE_MGM;
705  break;
706  default:
707  break;
708  }
709  }
710  else
711  {
712  nodeTypes[i] = (enum ndb_mgm_node_type)-1;
713  }
714 
715  }
716 
717  // Setup cluster log
718  setClusterLog(m_local_config);
719 
720  if (theFacade)
721  {
722  if (!theFacade->configure(_ownNodeId,
723  m_local_config->m_configValues))
724  {
725  g_eventLogger->warning("Could not reconfigure everything online, "
726  "this node need a restart");
727  m_need_restart= true;
728  }
729  }
730 
731  DBUG_VOID_RETURN;
732 }
733 
734 
735 bool
736 MgmtSrvr::get_packed_config(ndb_mgm_node_type node_type,
737  BaseString& buf64, BaseString& error)
738 {
739  return m_config_manager->get_packed_config(node_type, &buf64, error);
740 }
741 
742 bool
743 MgmtSrvr::get_packed_config_from_node(NodeId nodeId,
744  BaseString& buf64, BaseString& error)
745 {
746  DBUG_ENTER("get_packed_config_from_node");
747 
748  if (nodeId >= MAX_NODES_ID)
749  {
750  error.assfmt("Nodeid %d is greater than max nodeid %d. ",
751  nodeId, MAX_NODES_ID);
752  DBUG_RETURN(false);
753  }
754 
755  if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_UNKNOWN)
756  {
757  error.assfmt("Nodeid %d does not exist. ", nodeId);
758  DBUG_RETURN(false);
759  }
760 
761  if (getNodeType(nodeId) != NDB_MGM_NODE_TYPE_NDB)
762  {
763  error.assfmt("Node %d is not a data node. ", nodeId);
764  DBUG_RETURN(false);
765  }
766 
767  trp_node node = getNodeInfo(nodeId);
768 
769  if (!node.m_alive)
770  {
771  error.assfmt("Data node %d is not alive. ", nodeId);
772  DBUG_RETURN(false);
773  }
774 
775  const Uint32 version = node.m_info.m_version;
776 
777  if (!ndbd_get_config_supported(version))
778  {
779  error.assfmt("Data node %d (version %d.%d.%d) does not support getting config. ",
780  nodeId, ndbGetMajor(version),
781  ndbGetMinor(version), ndbGetBuild(version));
782  DBUG_RETURN(false);
783  }
784 
785  INIT_SIGNAL_SENDER(ss,nodeId);
786 
787  SimpleSignal ssig;
788  GetConfigReq* req = CAST_PTR(GetConfigReq, ssig.getDataPtrSend());
789  req->senderRef = ss.getOwnRef();
790  req->nodeId = nodeId;
791 
792  g_eventLogger->debug("Sending GET_CONFIG_REQ to %d", nodeId);
793 
794  ssig.set(ss, TestOrd::TraceAPI, CMVMI, GSN_GET_CONFIG_REQ,
795  GetConfigReq::SignalLength);
796  if ((ss.sendSignal(nodeId, &ssig)) != SEND_OK)
797  {
798  DBUG_RETURN(false);
799  }
800 
801  Defragger defragger;
802  while (true)
803  {
804  SimpleSignal *signal = ss.waitFor();
805  int gsn = signal->readSignalNumber();
806 
807  switch (gsn)
808  {
809  case GSN_GET_CONFIG_CONF:
810  {
811  if (refToNode(signal->header.theSendersBlockRef) != nodeId)
812  {
813  error.assfmt("Internal Error: Reply from wrong node %d, expected from %d. ",
814  refToNode(signal->header.theSendersBlockRef),
815  nodeId);
816  DBUG_RETURN(false);
817  }
818 
819  const GetConfigConf * const conf =
820  CAST_CONSTPTR(GetConfigConf, signal->getDataPtr());
821 
822  if (signal->header.m_noOfSections != 1)
823  {
824  error.assfmt("Internal Error: Wrong number of sections %d received, expected %d. ",
825  signal->header.m_noOfSections, 1);
826  DBUG_RETURN(false);
827  }
828 
829  if (defragger.defragment(signal))
830  {
832  require(cf.unpack(signal->ptr[0].p, conf->configLength));
833 
834  Config received_config(cf.getConfigValues());
835  if (!received_config.pack64(buf64))
836  {
837  error.assign("Failed to pack64");
838  DBUG_RETURN(false);
839  }
840  DBUG_RETURN(true);
841  }
842  // wait until all fragments are received
843  continue;
844  }
845 
846  case GSN_GET_CONFIG_REF:
847  {
848  if (refToNode(ssig.header.theSendersBlockRef) != nodeId)
849  {
850  error.assfmt("Internal Error: Reply from wrong node %d, expected from %d. ",
851  refToNode(signal->header.theSendersBlockRef),
852  nodeId);
853  DBUG_RETURN(false);
854  }
855  const GetConfigRef * const ref =
856  CAST_CONSTPTR(GetConfigRef, signal->getDataPtr());
857  error.assfmt("Error in retrieving config from node %d: Internal error: %d",
858  nodeId, ref->error);
859 
860  DBUG_RETURN(false);
861  }
862 
863  case GSN_NF_COMPLETEREP:
864  {
865  const NFCompleteRep * rep = CAST_CONSTPTR(NFCompleteRep,
866  signal->getDataPtr());
867  if (rep->failedNodeId == nodeId)
868  {
869  error.assfmt("Node %d is not available", nodeId);
870  DBUG_RETURN(false);
871  }
872  continue;
873  }
874 
875  case GSN_NODE_FAILREP:
876  {
877  // Wait until GSN_NODE_COMPLETEREP is received.
878  continue;
879  }
880 
881  case GSN_API_REGCONF:
882  case GSN_TAKE_OVERTCCONF:
883  case GSN_CONNECT_REP:
884  // Ignore
885  continue;
886 
887  default:
888  report_unknown_signal(signal);
889  DBUG_RETURN(false);
890  }
891  }
892  // Should never come here
893  require(false);
894  DBUG_RETURN(false);
895 }
896 
897 MgmtSrvr::~MgmtSrvr()
898 {
899  /* Stop log level thread */
900  void* res = 0;
901  _isStopThread = true;
902 
903  if (_logLevelThread != NULL) {
904  NdbThread_WaitFor(_logLevelThread, &res);
905  NdbThread_Destroy(&_logLevelThread);
906  }
907 
908  /* Stop mgm service, don't allow new connections */
909  m_socket_server.stopServer();
910 
911  /* Stop all active session */
912  if (!m_socket_server.stopSessions(true,
913  2 * MgmApiSession::SOCKET_TIMEOUT))
914  {
915  g_eventLogger->error("Failed to wait for all sessions to stop, "
916  "continuing with shutdown anyway.");
917  }
918 
919  /* Stop config manager */
920  if (m_config_manager != 0)
921  {
922  m_config_manager->stop();
923  delete m_config_manager;
924  m_config_manager= 0;
925  }
926 
927  this->close(); // close trp_client before stopping TransporterFacade
928 
929  // Stop transporter
930  if(theFacade != 0){
931  theFacade->stop_instance();
932  delete theFacade;
933  theFacade = 0;
934  }
935 
936  delete m_local_config;
937 
938  NdbMutex_Destroy(m_local_config_mutex);
939  NdbMutex_Destroy(m_node_id_mutex);
940 }
941 
942 
943 //****************************************************************************
944 //****************************************************************************
945 
946 int MgmtSrvr::okToSendTo(NodeId nodeId, bool unCond)
947 {
948  if(nodeId == 0 || getNodeType(nodeId) != NDB_MGM_NODE_TYPE_NDB)
949  return WRONG_PROCESS_TYPE;
950  // Check if we have contact with it
951  if(unCond){
952  if (getNodeInfo(nodeId).is_confirmed())
953  return 0;
954  }
955  else if (getNodeInfo(nodeId).m_alive == true)
956  return 0;
957  return NO_CONTACT_WITH_PROCESS;
958 }
959 
960 void
961 MgmtSrvr::report_unknown_signal(SimpleSignal *signal)
962 {
963  signal->print();
964  g_eventLogger->error("Unknown signal received. SignalNumber: "
965  "%i from (%d, 0x%x)",
966  signal->readSignalNumber(),
967  refToNode(signal->header.theSendersBlockRef),
968  refToBlock(signal->header.theSendersBlockRef));
969  assert(false);
970 }
971 
972 /*****************************************************************************
973  * Starting and stopping database nodes
974  ****************************************************************************/
975 
976 int
977 MgmtSrvr::start(int nodeId)
978 {
979  INIT_SIGNAL_SENDER(ss,nodeId);
980 
981  SimpleSignal ssig;
982  StartOrd* const startOrd = CAST_PTR(StartOrd, ssig.getDataPtrSend());
983  ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_START_ORD, StartOrd::SignalLength);
984  startOrd->restartInfo = 0;
985 
986  return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
987 }
988 
989 /*****************************************************************************
990  * Version handling
991  *****************************************************************************/
992 
993 void
994 MgmtSrvr::status_api(int nodeId,
995  ndb_mgm_node_status& node_status,
996  Uint32& version, Uint32& mysql_version,
997  const char **address)
998 {
999  assert(getNodeType(nodeId) == NDB_MGM_NODE_TYPE_API);
1000  assert(version == 0 && mysql_version == 0);
1001 
1002  if (sendVersionReq(nodeId, version, mysql_version, address) != 0)
1003  {
1004  // Couldn't get version from any NDB node.
1005  assert(version == 0);
1006  node_status = NDB_MGM_NODE_STATUS_UNKNOWN;
1007  return;
1008  }
1009 
1010  if (version)
1011  {
1012  assert(mysql_version);
1013  node_status = NDB_MGM_NODE_STATUS_CONNECTED;
1014  }
1015  else
1016  {
1017  assert(mysql_version == 0);
1018  node_status = NDB_MGM_NODE_STATUS_NO_CONTACT;
1019  }
1020  return;
1021 }
1022 
1023 
1024 int
1025 MgmtSrvr::sendVersionReq(int v_nodeId,
1026  Uint32 &version,
1027  Uint32& mysql_version,
1028  const char **address)
1029 {
1030  SignalSender ss(theFacade);
1031  ss.lock();
1032 
1033  SimpleSignal ssig;
1034  ApiVersionReq* req = CAST_PTR(ApiVersionReq, ssig.getDataPtrSend());
1035  req->senderRef = ss.getOwnRef();
1036  req->nodeId = v_nodeId;
1037  ssig.set(ss, TestOrd::TraceAPI, QMGR,
1038  GSN_API_VERSION_REQ, ApiVersionReq::SignalLength);
1039 
1040  NodeId nodeId = 0;
1041  bool do_send = true;
1042  while(true)
1043  {
1044  if (do_send)
1045  {
1046  nodeId = ss.get_an_alive_node();
1047  if (nodeId == 0)
1048  {
1049  return NO_CONTACT_WITH_DB_NODES;
1050  }
1051 
1052  if (ss.sendSignal(nodeId, &ssig) != SEND_OK)
1053  {
1054  return SEND_OR_RECEIVE_FAILED;
1055  }
1056 
1057  do_send = false;
1058  }
1059 
1060  SimpleSignal *signal = ss.waitFor();
1061 
1062  switch (signal->readSignalNumber()) {
1063  case GSN_API_VERSION_CONF: {
1064  const ApiVersionConf * const conf =
1065  CAST_CONSTPTR(ApiVersionConf, signal->getDataPtr());
1066 
1067  assert((int) conf->nodeId == v_nodeId);
1068 
1069  version = conf->version;
1070  mysql_version = conf->mysql_version;
1071  if (version < NDBD_SPLIT_VERSION)
1072  mysql_version = 0;
1073  struct in_addr in;
1074  in.s_addr= conf->inet_addr;
1075  *address= inet_ntoa(in);
1076 
1077  return 0;
1078  }
1079 
1080  case GSN_NF_COMPLETEREP:{
1081  const NFCompleteRep * const rep =
1082  CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr());
1083  if (rep->failedNodeId == nodeId)
1084  do_send = true; // retry with other node
1085  continue;
1086  }
1087 
1088  case GSN_NODE_FAILREP:{
1089  const NodeFailRep * const rep =
1090  CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
1091  if (NdbNodeBitmask::get(rep->theNodes,nodeId))
1092  do_send = true; // retry with other node
1093  continue;
1094  }
1095  case GSN_API_REGCONF:
1096  case GSN_TAKE_OVERTCCONF:
1097  case GSN_CONNECT_REP:
1098  // Ignore
1099  continue;
1100  default:
1101  report_unknown_signal(signal);
1102  return SEND_OR_RECEIVE_FAILED;
1103  }
1104  }
1105 
1106  // Should never come here
1107  require(false);
1108  return -1;
1109 }
1110 
1111 
1112 int MgmtSrvr::sendStopMgmd(NodeId nodeId,
1113  bool abort,
1114  bool stop,
1115  bool restart,
1116  bool nostart,
1117  bool initialStart)
1118 {
1119  const char* hostname;
1120  Uint32 port;
1121  BaseString connect_string;
1122 
1123  {
1124  Guard g(m_local_config_mutex);
1125  {
1126  ConfigIter iter(m_local_config, CFG_SECTION_NODE);
1127 
1128  if(iter.first()) return SEND_OR_RECEIVE_FAILED;
1129  if(iter.find(CFG_NODE_ID, nodeId)) return SEND_OR_RECEIVE_FAILED;
1130  if(iter.get(CFG_NODE_HOST, &hostname)) return SEND_OR_RECEIVE_FAILED;
1131  }
1132  {
1133  ConfigIter iter(m_local_config, CFG_SECTION_NODE);
1134 
1135  if(iter.first()) return SEND_OR_RECEIVE_FAILED;
1136  if(iter.find(CFG_NODE_ID, nodeId)) return SEND_OR_RECEIVE_FAILED;
1137  if(iter.get(CFG_MGM_PORT, &port)) return SEND_OR_RECEIVE_FAILED;
1138  }
1139  if( strlen(hostname) == 0 )
1140  return SEND_OR_RECEIVE_FAILED;
1141 
1142  }
1143  connect_string.assfmt("%s:%u",hostname,port);
1144 
1145  DBUG_PRINT("info",("connect string: %s",connect_string.c_str()));
1146 
1148  if ( h && connect_string.length() > 0 )
1149  {
1150  ndb_mgm_set_connectstring(h,connect_string.c_str());
1151  if(ndb_mgm_connect(h,1,0,0))
1152  {
1153  DBUG_PRINT("info",("failed ndb_mgm_connect"));
1155  return SEND_OR_RECEIVE_FAILED;
1156  }
1157  if(!restart)
1158  {
1159  int nodes[1];
1160  nodes[0]= (int)nodeId;
1161  if(ndb_mgm_stop(h, 1, nodes) < 0)
1162  {
1164  return SEND_OR_RECEIVE_FAILED;
1165  }
1166  }
1167  else
1168  {
1169  int nodes[1];
1170  nodes[0]= (int)nodeId;
1171  if(ndb_mgm_restart2(h, 1, nodes, initialStart, nostart, abort) < 0)
1172  {
1174  return SEND_OR_RECEIVE_FAILED;
1175  }
1176  }
1177  }
1179 
1180  return 0;
1181 }
1182 
1188 int
1189 MgmtSrvr::sendall_STOP_REQ(NodeBitmask &stoppedNodes,
1190  bool abort,
1191  bool stop,
1192  bool restart,
1193  bool nostart,
1194  bool initialStart)
1195 {
1196  int error = 0;
1197  DBUG_ENTER("MgmtSrvr::sendall_STOP_REQ");
1198  DBUG_PRINT("enter", ("abort: %d stop: %d restart: %d "
1199  "nostart: %d initialStart: %d",
1200  abort, stop, restart, nostart, initialStart));
1201 
1202  stoppedNodes.clear();
1203 
1204  SignalSender ss(theFacade);
1205  ss.lock(); // lock will be released on exit
1206 
1207  SimpleSignal ssig;
1208  StopReq* const stopReq = CAST_PTR(StopReq, ssig.getDataPtrSend());
1209  ssig.set(ss, TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ, StopReq::SignalLength);
1210 
1211  stopReq->requestInfo = 0;
1212  stopReq->apiTimeout = 5000;
1213  stopReq->transactionTimeout = 1000;
1214  stopReq->readOperationTimeout = 1000;
1215  stopReq->operationTimeout = 1000;
1216  stopReq->senderData = 12;
1217  stopReq->senderRef = ss.getOwnRef();
1218  stopReq->singleuser = 0;
1219  StopReq::setSystemStop(stopReq->requestInfo, stop);
1220  StopReq::setPerformRestart(stopReq->requestInfo, restart);
1221  StopReq::setStopAbort(stopReq->requestInfo, abort);
1222  StopReq::setNoStart(stopReq->requestInfo, nostart);
1223  StopReq::setInitialStart(stopReq->requestInfo, initialStart);
1224 
1225  // send the signals
1226  int failed = 0;
1227  NodeBitmask nodes;
1228  {
1229  NodeId nodeId = 0;
1230  while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB))
1231  {
1232  if (okToSendTo(nodeId, true) == 0)
1233  {
1234  SendStatus result = ss.sendSignal(nodeId, &ssig);
1235  if (result == SEND_OK)
1236  nodes.set(nodeId);
1237  else
1238  failed++;
1239  }
1240  }
1241  }
1242 
1243  if (nodes.isclear() && failed > 0)
1244  {
1245  DBUG_RETURN(SEND_OR_RECEIVE_FAILED);
1246  }
1247 
1248  // now wait for the replies
1249  while (!nodes.isclear())
1250  {
1251  SimpleSignal *signal = ss.waitFor();
1252  int gsn = signal->readSignalNumber();
1253  switch (gsn) {
1254  case GSN_STOP_REF:
1255  {
1256  const StopRef * const ref = CAST_CONSTPTR(StopRef, signal->getDataPtr());
1257  const NodeId nodeId = refToNode(signal->header.theSendersBlockRef);
1258 #ifdef VM_TRACE
1259  ndbout_c("Node %d refused stop", nodeId);
1260 #endif
1261  assert(nodes.get(nodeId));
1262  nodes.clear(nodeId);
1263  error = translateStopRef(ref->errorCode);
1264  break;
1265  }
1266  case GSN_STOP_CONF:
1267  {
1268  const NodeId nodeId = refToNode(signal->header.theSendersBlockRef);
1269  assert(nodes.get(nodeId));
1270  nodes.clear(nodeId);
1271  break;
1272  }
1273  case GSN_NF_COMPLETEREP:
1274  {
1275  const NFCompleteRep * rep = CAST_CONSTPTR(NFCompleteRep,
1276  signal->getDataPtr());
1277  nodes.clear(rep->failedNodeId); // clear the failed node
1278  stoppedNodes.set(rep->failedNodeId);
1279  break;
1280  }
1281  case GSN_NODE_FAILREP:
1282  {
1283  const NodeFailRep * rep = CAST_CONSTPTR(NodeFailRep,
1284  signal->getDataPtr());
1285  NodeBitmask mask;
1286  mask.assign(NdbNodeBitmask::Size, rep->theNodes);
1287  nodes.bitANDC(mask);
1288  stoppedNodes.bitOR(mask);
1289  break;
1290  }
1291  case GSN_API_REGCONF:
1292  case GSN_TAKE_OVERTCCONF:
1293  case GSN_CONNECT_REP:
1294  continue;
1295  default:
1296  report_unknown_signal(signal);
1297  DBUG_RETURN(SEND_OR_RECEIVE_FAILED);
1298  }
1299  }
1300 
1301  DBUG_RETURN(error);
1302 }
1303 
1304 int
1305 MgmtSrvr::guess_master_node(SignalSender& ss)
1306 {
1310  NodeId guess = m_master_node;
1311  if (guess != 0)
1312  {
1313  trp_node node = ss.getNodeInfo(guess);
1314  if (node.m_state.startLevel == NodeState::SL_STARTED)
1315  return guess;
1316  }
1317 
1321  guess = 0;
1322  while(getNextNodeId(&guess, NDB_MGM_NODE_TYPE_NDB))
1323  {
1324  trp_node node = ss.getNodeInfo(guess);
1325  if (node.m_state.startLevel == NodeState::SL_STARTED)
1326  {
1327  return guess;
1328  }
1329  }
1330 
1334  guess = 0;
1335  while(getNextNodeId(&guess, NDB_MGM_NODE_TYPE_NDB))
1336  {
1337  trp_node node = ss.getNodeInfo(guess);
1338  if (node.is_confirmed())
1339  {
1340  return guess;
1341  }
1342  }
1343 
1347  guess = 0;
1348  while(getNextNodeId(&guess, NDB_MGM_NODE_TYPE_NDB))
1349  {
1350  trp_node node = ss.getNodeInfo(guess);
1351  if (node.is_connected())
1352  {
1353  return guess;
1354  }
1355  }
1356 
1357  return 0; // give up
1358 }
1359 
1360 /*
1361  * Common method for handeling all STOP_REQ signalling that
1362  * is used by Stopping, Restarting and Single user commands
1363  *
1364  * In the event that we need to stop a mgmd, we create a mgm
1365  * client connection to that mgmd and stop it that way.
1366  * This allows us to stop mgm servers when there isn't any real
1367  * distributed communication up.
1368  *
1369  * node_ids.size()==0 means to stop all DB nodes.
1370  * MGM nodes will *NOT* be stopped.
1371  *
1372  * If we work out we should be stopping or restarting ourselves,
1373  * we return <0 in stopSelf for restart, >0 for stop
1374  * and 0 for do nothing.
1375  */
1376 
1377 int MgmtSrvr::sendSTOP_REQ(const Vector<NodeId> &node_ids,
1378  NodeBitmask &stoppedNodes,
1379  bool abort,
1380  bool stop,
1381  bool restart,
1382  bool nostart,
1383  bool initialStart,
1384  int* stopSelf)
1385 {
1386  int error = 0;
1387  DBUG_ENTER("MgmtSrvr::sendSTOP_REQ");
1388  DBUG_PRINT("enter", ("no of nodes: %d "
1389  "abort: %d stop: %d restart: %d "
1390  "nostart: %d initialStart: %d",
1391  node_ids.size(),
1392  abort, stop, restart, nostart, initialStart));
1393 
1394  stoppedNodes.clear();
1395  *stopSelf= 0;
1396 
1397  NodeBitmask ndb_nodes_to_stop;
1398  NodeBitmask mgm_nodes_to_stop;
1399 
1400  SignalSender ss(theFacade);
1401  ss.lock(); // lock will be released on exit
1402 
1406  for (unsigned i = 0; i < node_ids.size(); i++)
1407  {
1408  switch(getNodeType(node_ids[i])){
1409  case NDB_MGM_NODE_TYPE_MGM:
1410  mgm_nodes_to_stop.set(node_ids[i]);
1411  break;
1412  case NDB_MGM_NODE_TYPE_NDB:
1413  ndb_nodes_to_stop.set(node_ids[i]);
1414  break;
1415  default:
1416  DBUG_RETURN(WRONG_PROCESS_TYPE);
1417  }
1418  }
1419 
1423  for (Uint32 i = mgm_nodes_to_stop.find(0);
1424  i != mgm_nodes_to_stop.NotFound;
1425  i = mgm_nodes_to_stop.find(i + 1))
1426  {
1427  if (i != getOwnNodeId())
1428  {
1429  error= sendStopMgmd(i, abort, stop, restart,
1430  nostart, initialStart);
1431  if (error == 0)
1432  {
1433  stoppedNodes.set(i);
1434  }
1435  }
1436  else
1437  {
1438  g_eventLogger->info("Stopping this node");
1439  * stopSelf = (restart)? -1 : 1;
1440  stoppedNodes.set(i);
1441  }
1442  }
1443 
1447  SimpleSignal ssig;
1448  StopReq* const stopReq = CAST_PTR(StopReq, ssig.getDataPtrSend());
1449  ssig.set(ss, TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ, StopReq::SignalLength);
1450 
1451  stopReq->requestInfo = 0;
1452  stopReq->apiTimeout = 5000;
1453  stopReq->transactionTimeout = 1000;
1454  stopReq->readOperationTimeout = 1000;
1455  stopReq->operationTimeout = 1000;
1456  stopReq->senderData = 12;
1457  stopReq->senderRef = ss.getOwnRef();
1458  stopReq->singleuser = 0;
1459  StopReq::setSystemStop(stopReq->requestInfo, stop);
1460  StopReq::setPerformRestart(stopReq->requestInfo, restart);
1461  StopReq::setStopAbort(stopReq->requestInfo, abort);
1462  StopReq::setNoStart(stopReq->requestInfo, nostart);
1463  StopReq::setInitialStart(stopReq->requestInfo, initialStart);
1464 
1465  int use_master_node = 0;
1466  int do_send = 0;
1467  if (ndb_nodes_to_stop.count() > 1)
1468  {
1469  do_send = 1;
1470  use_master_node = 1;
1471  ndb_nodes_to_stop.copyto(NdbNodeBitmask::Size, stopReq->nodes);
1472  StopReq::setStopNodes(stopReq->requestInfo, 1);
1473  }
1474  else if (ndb_nodes_to_stop.count() == 1)
1475  {
1476  Uint32 nodeId = ndb_nodes_to_stop.find(0);
1477  if (okToSendTo(nodeId, true) == 0)
1478  {
1479  SendStatus result = ss.sendSignal(nodeId, &ssig);
1480  if (result != SEND_OK)
1481  {
1482  DBUG_RETURN(SEND_OR_RECEIVE_FAILED);
1483  }
1484  }
1485  else
1486  {
1487  DBUG_RETURN(SEND_OR_RECEIVE_FAILED);
1488  }
1489  }
1490 
1491 
1492  // now wait for the replies
1493  Uint32 sendNodeId = ndb_nodes_to_stop.find(0);
1494  while (!stoppedNodes.contains(ndb_nodes_to_stop))
1495  {
1496  if (do_send)
1497  {
1498  assert(use_master_node);
1499  sendNodeId = guess_master_node(ss);
1500  if (okToSendTo(sendNodeId, true) != 0)
1501  {
1502  DBUG_RETURN(SEND_OR_RECEIVE_FAILED);
1503  }
1504 
1505  if (ss.sendSignal(sendNodeId, &ssig) != SEND_OK)
1506  {
1507  DBUG_RETURN(SEND_OR_RECEIVE_FAILED);
1508  }
1509  do_send = 0;
1510  }
1511 
1512  SimpleSignal *signal = ss.waitFor();
1513  int gsn = signal->readSignalNumber();
1514  switch (gsn) {
1515  case GSN_STOP_REF:{
1516  const StopRef * const ref = CAST_CONSTPTR(StopRef, signal->getDataPtr());
1517  const NodeId nodeId = refToNode(signal->header.theSendersBlockRef);
1518  assert(nodeId == sendNodeId);
1519  if (ref->errorCode == StopRef::MultiNodeShutdownNotMaster)
1520  {
1521  assert(use_master_node);
1522  m_master_node= ref->masterNodeId;
1523  do_send = 1;
1524  continue;
1525  }
1526  DBUG_RETURN(translateStopRef(ref->errorCode));
1527  break;
1528  }
1529  case GSN_STOP_CONF:{
1530 #ifdef NOT_USED
1531  const StopConf * const ref = CAST_CONSTPTR(StopConf, signal->getDataPtr());
1532 #endif
1533  const NodeId nodeId = refToNode(signal->header.theSendersBlockRef);
1534  assert(nodeId == sendNodeId);
1535  stoppedNodes.bitOR(ndb_nodes_to_stop);
1536  break;
1537  }
1538  case GSN_NF_COMPLETEREP:{
1539  const NFCompleteRep * const rep =
1540  CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr());
1541  stoppedNodes.set(rep->failedNodeId);
1542  break;
1543  }
1544  case GSN_NODE_FAILREP:{
1545  const NodeFailRep * const rep =
1546  CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
1547  NodeBitmask mask;
1548  mask.assign(NdbNodeBitmask::Size, rep->theNodes);
1549  stoppedNodes.bitOR(mask);
1550  break;
1551  }
1552  case GSN_API_REGCONF:
1553  case GSN_TAKE_OVERTCCONF:
1554  case GSN_CONNECT_REP:
1555  continue;
1556  default:
1557  report_unknown_signal(signal);
1558  DBUG_RETURN(SEND_OR_RECEIVE_FAILED);
1559  }
1560  }
1561  if (error && *stopSelf)
1562  {
1563  *stopSelf= 0;
1564  }
1565  DBUG_RETURN(error);
1566 }
1567 
1568 /*
1569  * Stop one nodes
1570  */
1571 
1573  int *stopCount, bool abort, bool force,
1574  int* stopSelf)
1575 {
1576  if (force || abort)
1577  ; // Skip node state checks
1578  else if (is_any_node_starting())
1579  {
1580  /* Refuse to stop since some node(s) are starting */
1581  return OPERATION_NOT_ALLOWED_START_STOP;
1582  }
1583 
1584  NodeBitmask nodes;
1585  int ret = 0;
1586  if (node_ids.size() > 0)
1587  {
1588  ret = sendSTOP_REQ(node_ids, nodes,
1589  abort, false, false, false, false,
1590  stopSelf);
1591  }
1592  else
1593  {
1594  ret = sendall_STOP_REQ(nodes,
1595  abort, false, false, false, false);
1596  }
1597 
1598  if (stopCount)
1599  *stopCount= nodes.count();
1600  return ret;
1601 }
1602 
1603 int MgmtSrvr::shutdownMGM(int *stopCount, bool abort, int *stopSelf)
1604 {
1605  NodeId nodeId = 0;
1606  int error;
1607 
1608  while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_MGM))
1609  {
1610  if(nodeId==getOwnNodeId())
1611  continue;
1612  error= sendStopMgmd(nodeId, abort, true, false,
1613  false, false);
1614  if (error == 0)
1615  (*stopCount)++;
1616  }
1617 
1618  *stopSelf= 1;
1619  (*stopCount)++;
1620 
1621  return 0;
1622 }
1623 
1624 /*
1625  * Perform DB nodes shutdown.
1626  * MGM servers are left in their current state
1627  */
1628 
1629 int MgmtSrvr::shutdownDB(int * stopCount, bool abort)
1630 {
1631  NodeBitmask nodes;
1632 
1633  int ret = sendall_STOP_REQ(nodes,
1634  abort,
1635  true,
1636  false,
1637  false,
1638  false);
1639 
1640  if (stopCount)
1641  *stopCount = nodes.count();
1642  return ret;
1643 }
1644 
1645 /*
1646  * Enter single user mode on all live nodes
1647  */
1648 
1649 int MgmtSrvr::enterSingleUser(int * stopCount, Uint32 apiNodeId)
1650 {
1651  if (getNodeType(apiNodeId) != NDB_MGM_NODE_TYPE_API)
1652  return NODE_NOT_API_NODE;
1653 
1654  // Init
1655  if (stopCount)
1656  {
1657  * stopCount = 0;
1658  }
1659 
1660  SignalSender ss(theFacade);
1661  ss.lock(); // lock will be released on exit
1662 
1663  SimpleSignal ssig;
1664  StopReq* const stopReq = CAST_PTR(StopReq, ssig.getDataPtrSend());
1665  ssig.set(ss, TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ, StopReq::SignalLength);
1666 
1667  stopReq->requestInfo = 0;
1668  stopReq->apiTimeout = 5000;
1669  stopReq->transactionTimeout = 1000;
1670  stopReq->readOperationTimeout = 1000;
1671  stopReq->operationTimeout = 1000;
1672  stopReq->senderData = 12;
1673  stopReq->senderRef = ss.getOwnRef();
1674  stopReq->singleuser = 1;
1675  stopReq->singleUserApi = apiNodeId;
1676  StopReq::setSystemStop(stopReq->requestInfo, false);
1677  StopReq::setPerformRestart(stopReq->requestInfo, false);
1678  StopReq::setStopAbort(stopReq->requestInfo, false);
1679 
1680  NodeBitmask nodes;
1681  {
1682  NodeId nodeId = 0;
1683  Uint32 failed = 0;
1684  while (getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB))
1685  {
1686  if (okToSendTo(nodeId, true) == 0)
1687  {
1688  SendStatus result = ss.sendSignal(nodeId, &ssig);
1689  if (result == SEND_OK)
1690  nodes.set(nodeId);
1691  else
1692  failed++;
1693  }
1694  else
1695  {
1696  failed++;
1697  }
1698  }
1699  if (nodes.isclear())
1700  {
1701  if (failed)
1702  {
1703  return SEND_OR_RECEIVE_FAILED;
1704  }
1705  return NO_CONTACT_WITH_DB_NODES;
1706  }
1707  }
1708 
1709  int error = 0;
1710  int ok = 0;
1711  while (!nodes.isclear())
1712  {
1713  SimpleSignal *signal = ss.waitFor();
1714  int gsn = signal->readSignalNumber();
1715  switch (gsn) {
1716  case GSN_STOP_REF:
1717  {
1718  const StopRef * const ref = CAST_CONSTPTR(StopRef, signal->getDataPtr());
1719  nodes.clear(refToNode(signal->header.theSendersBlockRef));
1720  error = translateStopRef(ref->errorCode);
1721  break;
1722  }
1723  case GSN_STOP_CONF:
1724  {
1725  ok++;
1726  nodes.clear(refToNode(signal->header.theSendersBlockRef));
1727  break;
1728  }
1729  case GSN_NF_COMPLETEREP:
1730  {
1731  const NFCompleteRep * rep = CAST_CONSTPTR(NFCompleteRep,
1732  signal->getDataPtr());
1733  nodes.clear(rep->failedNodeId);
1734  break;
1735  }
1736 
1737  case GSN_NODE_FAILREP:
1738  {
1739  const NodeFailRep * rep = CAST_CONSTPTR(NodeFailRep,
1740  signal->getDataPtr());
1741  NodeBitmask mask;
1742  mask.assign(NdbNodeBitmask::Size, rep->theNodes);
1743  nodes.bitANDC(mask);
1744  break;
1745  }
1746  case GSN_API_REGCONF:
1747  case GSN_TAKE_OVERTCCONF:
1748  case GSN_CONNECT_REP:
1749  continue;
1750 
1751  default:
1752  report_unknown_signal(signal);
1753  return SEND_OR_RECEIVE_FAILED;
1754  }
1755  }
1756 
1757  if (stopCount)
1758  {
1759  * stopCount = ok;
1760  }
1761 
1762  return error;
1763 }
1764 
1765 /*
1766  * Perform node restart
1767  */
1768 
1769 bool MgmtSrvr::is_any_node_stopping()
1770 {
1771  NodeId nodeId = 0;
1772  trp_node node;
1773  while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB))
1774  {
1775  node = getNodeInfo(nodeId);
1776  if((node.m_state.startLevel == NodeState::SL_STOPPING_1) ||
1777  (node.m_state.startLevel == NodeState::SL_STOPPING_2) ||
1778  (node.m_state.startLevel == NodeState::SL_STOPPING_3) ||
1779  (node.m_state.startLevel == NodeState::SL_STOPPING_4))
1780  return true; // At least one node was stopping
1781  }
1782  return false; // No node was stopping
1783 }
1784 
1785 bool MgmtSrvr::is_any_node_starting()
1786 {
1787  NodeId nodeId = 0;
1788  trp_node node;
1789  while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB))
1790  {
1791  node = getNodeInfo(nodeId);
1792  if((node.m_state.startLevel == NodeState::SL_STARTING))
1793  return true; // At least one node was starting
1794  }
1795  return false; // No node was starting
1796 }
1797 
1798 bool MgmtSrvr::is_cluster_single_user()
1799 {
1800  NodeId nodeId = 0;
1801  trp_node node;
1802  while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB))
1803  {
1804  node = getNodeInfo(nodeId);
1805  if((node.m_state.startLevel == NodeState::SL_SINGLEUSER))
1806  return true; // Cluster is in single user modes
1807  }
1808  return false; // Cluster is not in single user mode
1809 }
1810 
1812  int * stopCount, bool nostart,
1813  bool initialStart, bool abort,
1814  bool force,
1815  int *stopSelf)
1816 {
1817  if (is_cluster_single_user())
1818  {
1819  /*
1820  Refuse to restart since cluster is in single user mode
1821  and when the node is restarting it would not be allowed to
1822  join cluster, see BUG#31056
1823  */
1824  return OPERATION_NOT_ALLOWED_START_STOP;
1825  }
1826 
1827  if (force || abort)
1828  ; // Skip node state checks
1829  else if (is_any_node_starting())
1830  {
1831  /* Refuse to restart since some node(s) are starting */
1832  return OPERATION_NOT_ALLOWED_START_STOP;
1833  }
1834 
1835  NodeBitmask nodes;
1836  int ret = 0;
1837  if (node_ids.size() > 0)
1838  {
1839  ret = sendSTOP_REQ(node_ids, nodes,
1840  abort, false, true, true, initialStart,
1841  stopSelf);
1842  }
1843  else
1844  {
1845  ret = sendall_STOP_REQ(nodes,
1846  abort, false, true, true, initialStart);
1847  }
1848 
1849  if (ret)
1850  return ret;
1851 
1852  if (stopCount)
1853  *stopCount = nodes.count();
1854 
1855  // start up the nodes again
1856  const NDB_TICKS waitTime = 12000;
1857  const NDB_TICKS startTime = NdbTick_CurrentMillisecond();
1858  for (unsigned i = 0; i < node_ids.size(); i++)
1859  {
1860  NodeId nodeId= node_ids[i];
1861  enum ndb_mgm_node_status s;
1863 #ifdef VM_TRACE
1864  ndbout_c("Waiting for %d not started", nodeId);
1865 #endif
1866  while (s != NDB_MGM_NODE_STATUS_NOT_STARTED &&
1867  (NdbTick_CurrentMillisecond() - startTime) < waitTime)
1868  {
1869  Uint32 startPhase = 0, version = 0, dynamicId = 0, nodeGroup = 0;
1870  Uint32 mysql_version = 0;
1871  Uint32 connectCount = 0;
1872  bool system;
1873  const char *address= NULL;
1874  status(nodeId, &s, &version, &mysql_version, &startPhase,
1875  &system, &dynamicId, &nodeGroup, &connectCount, &address);
1876  NdbSleep_MilliSleep(100);
1877  }
1878  }
1879 
1880  if (nostart)
1881  return 0;
1882 
1883  /*
1884  verify that no nodes are stopping before starting as this would cause
1885  the starting node to shutdown
1886  */
1887  int retry= 600*10;
1888  for (;is_any_node_stopping();)
1889  {
1890  if (--retry)
1891  break;
1892  NdbSleep_MilliSleep(100);
1893  }
1894 
1895  /*
1896  start the nodes
1897  */
1898  for (unsigned i = 0; i < node_ids.size(); i++)
1899  {
1900  (void) start(node_ids[i]);
1901  }
1902  return 0;
1903 }
1904 
1905 /*
1906  * Perform restart of all DB nodes
1907  */
1908 
1909 int MgmtSrvr::restartDB(bool nostart, bool initialStart,
1910  bool abort, int * stopCount)
1911 {
1912  NodeBitmask nodes;
1913 
1914  int ret = sendall_STOP_REQ(nodes,
1915  abort,
1916  true,
1917  true,
1918  true,
1919  initialStart);
1920 
1921  if (ret)
1922  return ret;
1923 
1924  if (stopCount)
1925  *stopCount = nodes.count();
1926 
1927 #ifdef VM_TRACE
1928  ndbout_c("Stopped %d nodes", nodes.count());
1929 #endif
1930 
1934  NodeId nodeId = 0;
1935  const NDB_TICKS waitTime = 12000;
1936  const NDB_TICKS startTime = NdbTick_CurrentMillisecond();
1937 
1938  while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) {
1939  if (!nodes.get(nodeId))
1940  continue;
1941  enum ndb_mgm_node_status s;
1943 #ifdef VM_TRACE
1944  ndbout_c("Waiting for %d not started", nodeId);
1945 #endif
1946  while (s != NDB_MGM_NODE_STATUS_NOT_STARTED &&
1947  (NdbTick_CurrentMillisecond() - startTime) < waitTime)
1948  {
1949  Uint32 startPhase = 0, version = 0, dynamicId = 0, nodeGroup = 0;
1950  Uint32 mysql_version = 0;
1951  Uint32 connectCount = 0;
1952  bool system;
1953  const char *address;
1954  status(nodeId, &s, &version, &mysql_version, &startPhase,
1955  &system, &dynamicId, &nodeGroup, &connectCount, &address);
1956  NdbSleep_MilliSleep(100);
1957  }
1958  }
1959 
1960  if(nostart)
1961  return 0;
1962 
1967  nodeId = 0;
1968  while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) {
1969  if (!nodes.get(nodeId))
1970  continue;
1971  int result;
1972  result = start(nodeId);
1973  g_eventLogger->debug("Started node %d with result %d", nodeId, result);
1980  }
1981 
1982  return 0;
1983 }
1984 
1985 int
1986 MgmtSrvr::exitSingleUser(int * stopCount, bool abort)
1987 {
1988  NodeId nodeId = 0;
1989  int count = 0;
1990 
1991  SignalSender ss(theFacade);
1992  ss.lock(); // lock will be released on exit
1993 
1994  SimpleSignal ssig;
1995  ResumeReq* const resumeReq =
1996  CAST_PTR(ResumeReq, ssig.getDataPtrSend());
1997 
1998  ssig.set(ss,TestOrd::TraceAPI, NDBCNTR, GSN_RESUME_REQ,
1999  ResumeReq::SignalLength);
2000  resumeReq->senderData = 12;
2001  resumeReq->senderRef = ss.getOwnRef();
2002 
2003  while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)){
2004  if(okToSendTo(nodeId, true) == 0){
2005  SendStatus result = ss.sendSignal(nodeId, &ssig);
2006  if (result == SEND_OK)
2007  count++;
2008  }
2009  }
2010 
2011  if(stopCount != 0)
2012  * stopCount = count;
2013 
2014  return 0;
2015 }
2016 
2017 /*****************************************************************************
2018  * Status
2019  ****************************************************************************/
2020 
2021 void
2022 MgmtSrvr::updateStatus()
2023 {
2024  theFacade->ext_forceHB();
2025 }
2026 
2027 
2028 void
2029 MgmtSrvr::status_mgmd(NodeId node_id,
2030  ndb_mgm_node_status& node_status,
2031  Uint32& version, Uint32& mysql_version,
2032  const char **address)
2033 {
2034  assert(getNodeType(node_id) == NDB_MGM_NODE_TYPE_MGM);
2035 
2036  if (node_id == getOwnNodeId())
2037  {
2038  /*
2039  Special case to get version of own node
2040  - version and mysql_version is hardcoded
2041  - address should be the address seen from ndbd(if it's connected)
2042  else use HostName from config
2043  */
2044  Uint32 tmp_version = 0, tmp_mysql_version = 0;
2045  sendVersionReq(node_id, tmp_version, tmp_mysql_version, address);
2046  // Check that the version returned is equal to compiled in version
2047  assert(tmp_version == 0 ||
2048  (tmp_version == NDB_VERSION &&
2049  tmp_mysql_version == NDB_MYSQL_VERSION_D));
2050 
2051  version = NDB_VERSION;
2052  mysql_version = NDB_MYSQL_VERSION_D;
2053  if(!*address)
2054  {
2055  // No address returned from ndbd -> get HostName from config
2056  Guard g(m_local_config_mutex);
2057  ConfigIter iter(m_local_config, CFG_SECTION_NODE);
2058  require(iter.find(CFG_NODE_ID, node_id) == 0);
2059  require(iter.get(CFG_NODE_HOST, address) == 0);
2060 
2061  /*
2062  Try to convert HostName to numerical ip address
2063  (to get same output as if ndbd had replied)
2064  */
2065  struct in_addr addr;
2066  if (Ndb_getInAddr(&addr, *address) == 0)
2067  *address = inet_ntoa(addr);
2068  }
2069 
2070  node_status = NDB_MGM_NODE_STATUS_CONNECTED;
2071  return;
2072  }
2073 
2074  /*
2075  MGM nodes are connected directly to all other MGM
2076  node(s), return status as seen by ClusterMgr
2077  */
2078  const trp_node node = getNodeInfo(node_id);
2079  if(node.is_connected())
2080  {
2081  version = node.m_info.m_version;
2082  mysql_version = node.m_info.m_mysql_version;
2083  node_status = NDB_MGM_NODE_STATUS_CONNECTED;
2084  *address= get_connect_address(node_id);
2085  }
2086  else
2087  {
2088  version = 0;
2089  mysql_version = 0;
2090  node_status = NDB_MGM_NODE_STATUS_NO_CONTACT;
2091  }
2092 
2093  return;
2094 }
2095 
2096 int
2097 MgmtSrvr::status(int nodeId,
2098  ndb_mgm_node_status * _status,
2099  Uint32 * version,
2100  Uint32 * mysql_version,
2101  Uint32 * _phase,
2102  bool * _system,
2103  Uint32 * dynamic,
2104  Uint32 * nodegroup,
2105  Uint32 * connectCount,
2106  const char **address)
2107 {
2108  switch(getNodeType(nodeId)){
2109  case NDB_MGM_NODE_TYPE_API:
2110  status_api(nodeId, *_status, *version, *mysql_version, address);
2111  return 0;
2112  break;
2113 
2114  case NDB_MGM_NODE_TYPE_MGM:
2115  status_mgmd(nodeId, *_status, *version, *mysql_version, address);
2116  return 0;
2117  break;
2118 
2119  case NDB_MGM_NODE_TYPE_NDB:
2120  break;
2121 
2122  default:
2123  abort();
2124  break;
2125  }
2126 
2127  const trp_node node = getNodeInfo(nodeId);
2128  assert(getNodeType(nodeId) == NDB_MGM_NODE_TYPE_NDB &&
2129  node.m_info.getType() == NodeInfo::DB);
2130 
2131  if(!node.is_connected()){
2132  * _status = NDB_MGM_NODE_STATUS_NO_CONTACT;
2133  return 0;
2134  }
2135 
2136  * version = node.m_info.m_version;
2137  * mysql_version = node.m_info.m_mysql_version;
2138 
2139  *address= get_connect_address(nodeId);
2140 
2141  * dynamic = node.m_state.dynamicId;
2142  * nodegroup = node.m_state.nodeGroup;
2143  * connectCount = node.m_info.m_connectCount;
2144 
2145  switch(node.m_state.startLevel){
2146  case NodeState::SL_CMVMI:
2147  * _status = NDB_MGM_NODE_STATUS_NOT_STARTED;
2148  * _phase = 0;
2149  return 0;
2150  break;
2152  * _status = NDB_MGM_NODE_STATUS_STARTING;
2153  * _phase = node.m_state.starting.startPhase;
2154  return 0;
2155  break;
2156  case NodeState::SL_STARTED:
2157  * _status = NDB_MGM_NODE_STATUS_STARTED;
2158  * _phase = 0;
2159  return 0;
2160  break;
2163  * _phase = 1;
2164  * _system = node.m_state.stopping.systemShutdown != 0;
2165  return 0;
2166  break;
2169  * _phase = 2;
2170  * _system = node.m_state.stopping.systemShutdown != 0;
2171  return 0;
2172  break;
2175  * _phase = 3;
2176  * _system = node.m_state.stopping.systemShutdown != 0;
2177  return 0;
2178  break;
2181  * _phase = 4;
2182  * _system = node.m_state.stopping.systemShutdown != 0;
2183  return 0;
2184  break;
2185  case NodeState::SL_SINGLEUSER:
2186  * _status = NDB_MGM_NODE_STATUS_SINGLEUSER;
2187  * _phase = 0;
2188  return 0;
2189  break;
2190  default:
2191  * _status = NDB_MGM_NODE_STATUS_UNKNOWN;
2192  * _phase = 0;
2193  return 0;
2194  }
2195 
2196  return -1;
2197 }
2198 
2199 int
2200 MgmtSrvr::setEventReportingLevelImpl(int nodeId_arg,
2201  const EventSubscribeReq& ll)
2202 {
2203  SignalSender ss(theFacade);
2204  NdbNodeBitmask nodes;
2205  nodes.clear();
2206  while (1)
2207  {
2208  Uint32 nodeId, max;
2209  ss.lock();
2210  SimpleSignal ssig;
2211  EventSubscribeReq * dst =
2212  CAST_PTR(EventSubscribeReq, ssig.getDataPtrSend());
2213  ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_EVENT_SUBSCRIBE_REQ,
2214  EventSubscribeReq::SignalLength);
2215  *dst = ll;
2216 
2217  if (nodeId_arg == 0)
2218  {
2219  // all nodes
2220  nodeId = 1;
2221  max = MAX_NDB_NODES;
2222  }
2223  else
2224  {
2225  // only one node
2226  max = nodeId = nodeId_arg;
2227  }
2228  // first make sure nodes are sendable
2229  for(; nodeId <= max; nodeId++)
2230  {
2231  if (nodeTypes[nodeId] != NODE_TYPE_DB)
2232  continue;
2233  if (okToSendTo(nodeId, true))
2234  {
2235  if (getNodeInfo(nodeId).is_connected() == false)
2236  {
2237  // node not connected we can safely skip this one
2238  continue;
2239  }
2240  // api_reg_conf not recevied yet, need to retry
2241  return SEND_OR_RECEIVE_FAILED;
2242  }
2243  }
2244 
2245  if (nodeId_arg == 0)
2246  {
2247  // all nodes
2248  nodeId = 1;
2249  max = MAX_NDB_NODES;
2250  }
2251  else
2252  {
2253  // only one node
2254  max = nodeId = nodeId_arg;
2255  }
2256  // now send to all sendable nodes nodes
2257  // note, lock is held, so states have not changed
2258  for(; (Uint32) nodeId <= max; nodeId++)
2259  {
2260  if (nodeTypes[nodeId] != NODE_TYPE_DB)
2261  continue;
2262  if (getNodeInfo(nodeId).is_connected() == false)
2263  continue; // node is not connected, skip
2264  if (ss.sendSignal(nodeId, &ssig) == SEND_OK)
2265  nodes.set(nodeId);
2266  else if (max == nodeId)
2267  {
2268  return SEND_OR_RECEIVE_FAILED;
2269  }
2270  }
2271  break;
2272  }
2273 
2274  if (nodes.isclear())
2275  {
2276  return SEND_OR_RECEIVE_FAILED;
2277  }
2278 
2279  int error = 0;
2280  while (!nodes.isclear())
2281  {
2282  Uint32 nodeId;
2283  SimpleSignal *signal = ss.waitFor();
2284  int gsn = signal->readSignalNumber();
2285  nodeId = refToNode(signal->header.theSendersBlockRef);
2286  switch (gsn) {
2287  case GSN_EVENT_SUBSCRIBE_CONF:{
2288  nodes.clear(nodeId);
2289  break;
2290  }
2291  case GSN_EVENT_SUBSCRIBE_REF:{
2292  nodes.clear(nodeId);
2293  error = 1;
2294  break;
2295  }
2296  // Since sending okToSend(true),
2297  // there is no guarantee that NF_COMPLETEREP will come
2298  // i.e listen also to NODE_FAILREP
2299  case GSN_NODE_FAILREP: {
2300  const NodeFailRep * const rep =
2301  CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
2302  NdbNodeBitmask mask;
2303  mask.assign(NdbNodeBitmask::Size, rep->theNodes);
2304  nodes.bitANDC(mask);
2305  break;
2306  }
2307 
2308  case GSN_NF_COMPLETEREP:{
2309  const NFCompleteRep * const rep =
2310  CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr());
2311  nodes.clear(rep->failedNodeId);
2312  break;
2313  }
2314  case GSN_API_REGCONF:
2315  case GSN_TAKE_OVERTCCONF:
2316  case GSN_CONNECT_REP:
2317  continue;
2318  default:
2319  report_unknown_signal(signal);
2320  return SEND_OR_RECEIVE_FAILED;
2321  }
2322  }
2323  if (error)
2324  return SEND_OR_RECEIVE_FAILED;
2325  return 0;
2326 }
2327 
2328 //****************************************************************************
2329 //****************************************************************************
2330 int
2331 MgmtSrvr::setNodeLogLevelImpl(int nodeId, const SetLogLevelOrd & ll)
2332 {
2333  INIT_SIGNAL_SENDER(ss,nodeId);
2334 
2335  SimpleSignal ssig;
2336  ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_SET_LOGLEVELORD,
2337  SetLogLevelOrd::SignalLength);
2338  SetLogLevelOrd* const dst = CAST_PTR(SetLogLevelOrd, ssig.getDataPtrSend());
2339  *dst = ll;
2340 
2341  return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
2342 }
2343 
2344 //****************************************************************************
2345 //****************************************************************************
2346 
2347 int
2348 MgmtSrvr::insertError(int nodeId, int errorNo)
2349 {
2350  int block;
2351 
2352  if (errorNo < 0) {
2353  return INVALID_ERROR_NUMBER;
2354  }
2355 
2356  SignalSender ss(theFacade);
2357  ss.lock(); /* lock will be released on exit */
2358 
2359  if(getNodeType(nodeId) == NDB_MGM_NODE_TYPE_NDB)
2360  {
2361  block= CMVMI;
2362  }
2363  else if(nodeId == _ownNodeId)
2364  {
2365  g_errorInsert= errorNo;
2366  return 0;
2367  }
2368  else if(getNodeType(nodeId) == NDB_MGM_NODE_TYPE_MGM)
2369  block= _blockNumber;
2370  else
2371  return WRONG_PROCESS_TYPE;
2372 
2373  SimpleSignal ssig;
2374  ssig.set(ss,TestOrd::TraceAPI, block, GSN_TAMPER_ORD,
2375  TamperOrd::SignalLength);
2376  TamperOrd* const tamperOrd = CAST_PTR(TamperOrd, ssig.getDataPtrSend());
2377  tamperOrd->errorNo = errorNo;
2378 
2379  int res = ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 :SEND_OR_RECEIVE_FAILED;
2380 
2381  if (res == 0)
2382  {
2387  make_sync_req(ss, Uint32(nodeId));
2388  }
2389 
2390  return res;
2391 }
2392 
2393 
2394 int
2395 MgmtSrvr::startSchemaTrans(SignalSender& ss, NodeId & out_nodeId,
2396  Uint32 transId, Uint32 & out_transKey)
2397 {
2398  SimpleSignal ssig;
2399 
2400  ssig.set(ss, 0, DBDICT, GSN_SCHEMA_TRANS_BEGIN_REQ,
2401  SchemaTransBeginReq::SignalLength);
2402 
2403  SchemaTransBeginReq* req =
2404  CAST_PTR(SchemaTransBeginReq, ssig.getDataPtrSend());
2405 
2406  req->clientRef = ss.getOwnRef();
2407  req->transId = transId;
2408  req->requestInfo = 0;
2409 
2410  NodeId nodeId = ss.get_an_alive_node();
2411 
2412 retry:
2413  if (ss.get_node_alive(nodeId) == false)
2414  {
2415  nodeId = ss.get_an_alive_node();
2416  }
2417 
2418  if (ss.sendSignal(nodeId, &ssig) != SEND_OK)
2419  {
2420  return SEND_OR_RECEIVE_FAILED;
2421  }
2422 
2423  while (true)
2424  {
2425  SimpleSignal *signal = ss.waitFor();
2426  int gsn = signal->readSignalNumber();
2427  switch (gsn) {
2428  case GSN_SCHEMA_TRANS_BEGIN_CONF: {
2429  const SchemaTransBeginConf * conf =
2430  CAST_CONSTPTR(SchemaTransBeginConf, signal->getDataPtr());
2431  out_transKey = conf->transKey;
2432  out_nodeId = nodeId;
2433  return 0;
2434  }
2435  case GSN_SCHEMA_TRANS_BEGIN_REF: {
2436  const SchemaTransBeginRef * ref =
2437  CAST_CONSTPTR(SchemaTransBeginRef, signal->getDataPtr());
2438 
2439  switch(ref->errorCode){
2440  case SchemaTransBeginRef::NotMaster:
2441  nodeId = ref->masterNodeId;
2442  // Fall-through
2443  case SchemaTransBeginRef::Busy:
2444  case SchemaTransBeginRef::BusyWithNR:
2445  goto retry;
2446  default:
2447  return ref->errorCode;
2448  }
2449  }
2450  case GSN_NF_COMPLETEREP:
2451  // ignore
2452  break;
2453  case GSN_NODE_FAILREP:{
2454  const NodeFailRep * const rep =
2455  CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
2456  if (NdbNodeBitmask::get(rep->theNodes, nodeId))
2457  {
2458  nodeId++;
2459  goto retry;
2460  }
2461  break;
2462  }
2463  case GSN_API_REGCONF:
2464  case GSN_TAKE_OVERTCCONF:
2465  case GSN_CONNECT_REP:
2466  break;
2467  default:
2468  report_unknown_signal(signal);
2469  return SEND_OR_RECEIVE_FAILED;
2470  }
2471  }
2472 }
2473 
2474 int
2475 MgmtSrvr::endSchemaTrans(SignalSender& ss, NodeId nodeId,
2476  Uint32 transId, Uint32 transKey,
2477  Uint32 flags)
2478 {
2479  SimpleSignal ssig;
2480 
2481  ssig.set(ss, 0, DBDICT, GSN_SCHEMA_TRANS_END_REQ,
2482  SchemaTransEndReq::SignalLength);
2483 
2484  SchemaTransEndReq* req =
2485  CAST_PTR(SchemaTransEndReq, ssig.getDataPtrSend());
2486 
2487  req->clientRef = ss.getOwnRef();
2488  req->transId = transId;
2489  req->requestInfo = 0;
2490  req->transKey = transKey;
2491  req->flags = flags;
2492 
2493  if (ss.sendSignal(nodeId, &ssig) != SEND_OK)
2494  {
2495  return SEND_OR_RECEIVE_FAILED;
2496  }
2497 
2498  while (true)
2499  {
2500  SimpleSignal *signal = ss.waitFor();
2501  int gsn = signal->readSignalNumber();
2502  switch (gsn) {
2503  case GSN_SCHEMA_TRANS_END_CONF: {
2504  return 0;
2505  }
2506  case GSN_SCHEMA_TRANS_END_REF: {
2507  const SchemaTransEndRef * ref =
2508  CAST_CONSTPTR(SchemaTransEndRef, signal->getDataPtr());
2509  return ref->errorCode;
2510  }
2511  case GSN_NF_COMPLETEREP:
2512  // ignore
2513  break;
2514  case GSN_NODE_FAILREP:{
2515  const NodeFailRep * const rep =
2516  CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
2517  if (NdbNodeBitmask::get(rep->theNodes, nodeId))
2518  {
2519  return -1;
2520  }
2521  break;
2522  }
2523  case GSN_API_REGCONF:
2524  case GSN_TAKE_OVERTCCONF:
2525  case GSN_CONNECT_REP:
2526  break;
2527  default:
2528  report_unknown_signal(signal);
2529  return SEND_OR_RECEIVE_FAILED;
2530  }
2531  }
2532 }
2533 
2534 int
2535 MgmtSrvr::createNodegroup(int *nodes, int count, int *ng)
2536 {
2537  int res;
2538  SignalSender ss(theFacade);
2539  ss.lock();
2540 
2541  Uint32 transId = rand();
2542  Uint32 transKey;
2543  NodeId nodeId;
2544 
2545  if ((res = startSchemaTrans(ss, nodeId, transId, transKey)))
2546  {
2547  return res;
2548  }
2549 
2550  SimpleSignal ssig;
2551  ssig.set(ss, 0, DBDICT, GSN_CREATE_NODEGROUP_REQ,
2552  CreateNodegroupReq::SignalLength);
2553 
2554  CreateNodegroupReq* req =
2555  CAST_PTR(CreateNodegroupReq, ssig.getDataPtrSend());
2556 
2557  req->transId = transId;
2558  req->transKey = transKey;
2559  req->nodegroupId = RNIL;
2560  req->senderData = 77;
2561  req->senderRef = ss.getOwnRef();
2562  bzero(req->nodes, sizeof(req->nodes));
2563 
2564  if (ng)
2565  {
2566  if (* ng != -1)
2567  {
2568  req->nodegroupId = * ng;
2569  }
2570  }
2571  for (int i = 0; i<count && i<(int)NDB_ARRAY_SIZE(req->nodes); i++)
2572  {
2573  req->nodes[i] = nodes[i];
2574  }
2575 
2576  if (ss.sendSignal(nodeId, &ssig) != SEND_OK)
2577  {
2578  return SEND_OR_RECEIVE_FAILED;
2579  }
2580 
2581  bool wait = true;
2582  while (wait)
2583  {
2584  SimpleSignal *signal = ss.waitFor();
2585  int gsn = signal->readSignalNumber();
2586  switch (gsn) {
2587  case GSN_CREATE_NODEGROUP_CONF: {
2588  const CreateNodegroupConf * conf =
2589  CAST_CONSTPTR(CreateNodegroupConf, signal->getDataPtr());
2590 
2591  if (ng)
2592  {
2593  * ng = conf->nodegroupId;
2594  }
2595 
2596  wait = false;
2597  break;
2598  }
2599  case GSN_CREATE_NODEGROUP_REF:{
2600  const CreateNodegroupRef * ref =
2601  CAST_CONSTPTR(CreateNodegroupRef, signal->getDataPtr());
2602  Uint32 err = ref->errorCode;
2603  endSchemaTrans(ss, nodeId, transId, transKey,
2604  SchemaTransEndReq::SchemaTransAbort);
2605  return err;
2606  }
2607  case GSN_NF_COMPLETEREP:
2608  // ignore
2609  break;
2610  case GSN_NODE_FAILREP:{
2611  const NodeFailRep * const rep =
2612  CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
2613  if (NdbNodeBitmask::get(rep->theNodes, nodeId))
2614  {
2615  return SchemaTransBeginRef::Nodefailure;
2616  }
2617  break;
2618  }
2619  case GSN_API_REGCONF:
2620  case GSN_TAKE_OVERTCCONF:
2621  case GSN_CONNECT_REP:
2622  break;
2623  default:
2624  report_unknown_signal(signal);
2625  return SEND_OR_RECEIVE_FAILED;
2626  }
2627  }
2628 
2629  return endSchemaTrans(ss, nodeId, transId, transKey, 0);
2630 }
2631 
2632 int
2633 MgmtSrvr::dropNodegroup(int ng)
2634 {
2635  int res;
2636  SignalSender ss(theFacade);
2637  ss.lock();
2638 
2639  Uint32 transId = rand();
2640  Uint32 transKey;
2641  NodeId nodeId;
2642 
2643  if ((res = startSchemaTrans(ss, nodeId, transId, transKey)))
2644  {
2645  return res;
2646  }
2647 
2648  SimpleSignal ssig;
2649  ssig.set(ss, 0, DBDICT, GSN_DROP_NODEGROUP_REQ, DropNodegroupReq::SignalLength);
2650 
2651  DropNodegroupReq* req =
2652  CAST_PTR(DropNodegroupReq, ssig.getDataPtrSend());
2653 
2654  req->transId = transId;
2655  req->transKey = transKey;
2656  req->nodegroupId = ng;
2657  req->senderData = 77;
2658  req->senderRef = ss.getOwnRef();
2659 
2660  if (ss.sendSignal(nodeId, &ssig) != SEND_OK)
2661  {
2662  return SEND_OR_RECEIVE_FAILED;
2663  }
2664 
2665  bool wait = true;
2666  while (wait)
2667  {
2668  SimpleSignal *signal = ss.waitFor();
2669  int gsn = signal->readSignalNumber();
2670  switch (gsn) {
2671  case GSN_DROP_NODEGROUP_CONF: {
2672  wait = false;
2673  break;
2674  }
2675  case GSN_DROP_NODEGROUP_REF:
2676  {
2677  const DropNodegroupRef * ref =
2678  CAST_CONSTPTR(DropNodegroupRef, signal->getDataPtr());
2679  endSchemaTrans(ss, nodeId, transId, transKey,
2680  SchemaTransEndReq::SchemaTransAbort);
2681  return ref->errorCode;
2682  }
2683  case GSN_NF_COMPLETEREP:
2684  // ignore
2685  break;
2686  case GSN_NODE_FAILREP:{
2687  const NodeFailRep * const rep =
2688  CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
2689  if (NdbNodeBitmask::get(rep->theNodes, nodeId))
2690  {
2691  return SchemaTransBeginRef::Nodefailure;
2692  }
2693  break;
2694  }
2695  case GSN_API_REGCONF:
2696  case GSN_TAKE_OVERTCCONF:
2697  case GSN_CONNECT_REP:
2698  break;
2699  default:
2700  report_unknown_signal(signal);
2701  return SEND_OR_RECEIVE_FAILED;
2702  }
2703  }
2704 
2705  return endSchemaTrans(ss, nodeId, transId, transKey, 0);
2706 }
2707 
2708 
2709 //****************************************************************************
2710 //****************************************************************************
2711 
2712 int
2713 MgmtSrvr::setTraceNo(int nodeId, int traceNo)
2714 {
2715  if (traceNo < 0) {
2716  return INVALID_TRACE_NUMBER;
2717  }
2718 
2719  INIT_SIGNAL_SENDER(ss,nodeId);
2720 
2721  SimpleSignal ssig;
2722  ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
2723  TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend());
2724  testOrd->clear();
2725  // Assume TRACE command causes toggling. Not really defined... ? TODO
2726  testOrd->setTraceCommand(TestOrd::Toggle,
2727  (TestOrd::TraceSpecification)traceNo);
2728 
2729  return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
2730 }
2731 
2732 //****************************************************************************
2733 //****************************************************************************
2734 
2735 int
2736 MgmtSrvr::getBlockNumber(const BaseString &blockName)
2737 {
2738  short bno = getBlockNo(blockName.c_str());
2739  if(bno != 0)
2740  return bno;
2741  return -1;
2742 }
2743 
2744 //****************************************************************************
2745 //****************************************************************************
2746 
2747 int
2748 MgmtSrvr::setSignalLoggingMode(int nodeId, LogMode mode,
2749  const Vector<BaseString>& blocks)
2750 {
2751  INIT_SIGNAL_SENDER(ss,nodeId);
2752 
2753  // Convert from MgmtSrvr format...
2754 
2755  TestOrd::Command command;
2756  if (mode == Off) {
2757  command = TestOrd::Off;
2758  }
2759  else {
2760  command = TestOrd::On;
2761  }
2762 
2763  TestOrd::SignalLoggerSpecification logSpec;
2764  switch (mode) {
2765  case In:
2766  logSpec = TestOrd::InputSignals;
2767  break;
2768  case Out:
2769  logSpec = TestOrd::OutputSignals;
2770  break;
2771  case InOut:
2772  logSpec = TestOrd::InputOutputSignals;
2773  break;
2774  case Off:
2775  // In MgmtSrvr interface it's just possible to switch off all logging, both
2776  // "in" and "out" (this should probably be changed).
2777  logSpec = TestOrd::InputOutputSignals;
2778  break;
2779  default:
2780  ndbout_c("Unexpected value %d, MgmtSrvr::setSignalLoggingMode, line %d",
2781  (unsigned)mode, __LINE__);
2782  assert(false);
2783  return -1;
2784  }
2785 
2786  SimpleSignal ssig;
2787  ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
2788 
2789  TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend());
2790  testOrd->clear();
2791 
2792  if (blocks.size() == 0 || blocks[0] == "ALL") {
2793  // Logg command for all blocks
2794  testOrd->addSignalLoggerCommand(command, logSpec);
2795  } else {
2796  for(unsigned i = 0; i < blocks.size(); i++){
2797  int blockNumber = getBlockNumber(blocks[i]);
2798  if (blockNumber == -1) {
2799  return INVALID_BLOCK_NAME;
2800  }
2801  testOrd->addSignalLoggerCommand(blockNumber, command, logSpec);
2802  } // for
2803  } // else
2804 
2805  return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
2806 }
2807 
2808 /*****************************************************************************
2809  * Signal tracing
2810  *****************************************************************************/
2811 int MgmtSrvr::startSignalTracing(int nodeId)
2812 {
2813  INIT_SIGNAL_SENDER(ss,nodeId);
2814 
2815  SimpleSignal ssig;
2816  ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
2817 
2818  TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend());
2819  testOrd->clear();
2820  testOrd->setTestCommand(TestOrd::On);
2821 
2822  return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
2823 }
2824 
2825 int
2826 MgmtSrvr::stopSignalTracing(int nodeId)
2827 {
2828  INIT_SIGNAL_SENDER(ss,nodeId);
2829 
2830  SimpleSignal ssig;
2831  ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
2832  TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend());
2833  testOrd->clear();
2834  testOrd->setTestCommand(TestOrd::Off);
2835 
2836  return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
2837 }
2838 
2839 
2840 /*****************************************************************************
2841  * Dump state
2842  *****************************************************************************/
2843 
2844 int
2845 MgmtSrvr::dumpState(int nodeId, const char* args)
2846 {
2847  // Convert the space separeted args
2848  // string to an int array
2849  Uint32 args_array[25];
2850  Uint32 numArgs = 0;
2851 
2852  char buf[10];
2853  int b = 0;
2854  memset(buf, 0, 10);
2855  for (size_t i = 0; i <= strlen(args); i++){
2856  if (args[i] == ' ' || args[i] == 0){
2857  args_array[numArgs] = atoi(buf);
2858  numArgs++;
2859  memset(buf, 0, 10);
2860  b = 0;
2861  } else {
2862  buf[b] = args[i];
2863  b++;
2864  }
2865  }
2866 
2867  return dumpState(nodeId, args_array, numArgs);
2868 }
2869 
2870 int
2871 MgmtSrvr::dumpState(int nodeId, const Uint32 args[], Uint32 no)
2872 {
2873  INIT_SIGNAL_SENDER(ss,nodeId);
2874 
2875  const Uint32 len = no > 25 ? 25 : no;
2876 
2877  SimpleSignal ssig;
2878  DumpStateOrd * const dumpOrd =
2879  CAST_PTR(DumpStateOrd, ssig.getDataPtrSend());
2880  ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_DUMP_STATE_ORD, len);
2881  for(Uint32 i = 0; i<25; i++){
2882  if (i < len)
2883  dumpOrd->args[i] = args[i];
2884  else
2885  dumpOrd->args[i] = 0;
2886  }
2887 
2888  int res = ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 :SEND_OR_RECEIVE_FAILED;
2889 
2890  if (res == 0)
2891  {
2896  make_sync_req(ss, Uint32(nodeId));
2897  }
2898 
2899  return res;
2900 
2901 }
2902 
2903 
2904 //****************************************************************************
2905 //****************************************************************************
2906 
2907 const char* MgmtSrvr::getErrorText(int errorCode, char *buf, int buf_sz)
2908 {
2909  ndb_error_string(errorCode, buf, buf_sz);
2910  buf[buf_sz-1]= 0;
2911  return buf;
2912 }
2913 
2914 
2915 void
2916 MgmtSrvr::trp_deliver_signal(const NdbApiSignal* signal,
2917  const LinearSectionPtr ptr[3])
2918 {
2919  int gsn = signal->readSignalNumber();
2920 
2921  switch (gsn) {
2922  case GSN_EVENT_REP:
2923  {
2924  eventReport(signal->getDataPtr(), signal->getLength());
2925  break;
2926  }
2927 
2928  case GSN_NF_COMPLETEREP:
2929  break;
2930  case GSN_TAMPER_ORD:
2931  ndbout << "TAMPER ORD" << endl;
2932  break;
2933  case GSN_API_REGCONF:
2934  case GSN_TAKE_OVERTCCONF:
2935  break;
2936  case GSN_CONNECT_REP:{
2937  Uint32 nodeId = signal->getDataPtr()[0];
2938 
2939  union {
2940  Uint32 theData[25];
2941  EventReport repData;
2942  };
2943  EventReport * rep = &repData;
2944  theData[1] = nodeId;
2945  rep->setEventType(NDB_LE_Connected);
2946 
2947  if (nodeTypes[nodeId] == NODE_TYPE_DB)
2948  {
2949  m_started_nodes.push_back(nodeId);
2950  }
2951  rep->setEventType(NDB_LE_Connected);
2952  rep->setNodeId(_ownNodeId);
2953  eventReport(theData, 1);
2954  return;
2955  }
2956  case GSN_NODE_FAILREP:
2957  {
2958  union {
2959  Uint32 theData[25];
2960  EventReport repData;
2961  };
2962  bzero(theData, sizeof(theData));
2963  EventReport * event = &repData;
2964  event->setEventType(NDB_LE_Disconnected);
2965  event->setNodeId(_ownNodeId);
2966 
2967  const NodeFailRep *rep = CAST_CONSTPTR(NodeFailRep,
2968  signal->getDataPtr());
2969  for (Uint32 i = NdbNodeBitmask::find_first(rep->theNodes);
2970  i != NdbNodeBitmask::NotFound;
2971  i = NdbNodeBitmask::find_next(rep->theNodes, i + 1))
2972  {
2973  theData[1] = i;
2974  eventReport(theData, 1);
2975  }
2976  return;
2977  }
2978  default:
2979  g_eventLogger->error("Unknown signal received. SignalNumber: "
2980  "%i from (%d, 0x%x)",
2981  gsn,
2982  refToNode(signal->theSendersBlockRef),
2983  refToBlock(signal->theSendersBlockRef));
2984  assert(false);
2985  }
2986 }
2987 
2988 
2989 void
2990 MgmtSrvr::trp_node_status(Uint32 nodeId, Uint32 _event)
2991 {
2992 }
2993 
2994 enum ndb_mgm_node_type
2995 MgmtSrvr::getNodeType(NodeId nodeId) const
2996 {
2997  if(nodeId >= MAX_NODES)
2998  return (enum ndb_mgm_node_type)-1;
2999 
3000  return nodeTypes[nodeId];
3001 }
3002 
3003 const char *MgmtSrvr::get_connect_address(Uint32 node_id)
3004 {
3005  if (theFacade &&
3006  m_connect_address[node_id].s_addr == 0 &&
3007  (getNodeType(node_id) == NDB_MGM_NODE_TYPE_MGM ||
3008  getNodeType(node_id) == NDB_MGM_NODE_TYPE_NDB))
3009  {
3010  const trp_node &node= getNodeInfo(node_id);
3011  if (node.is_connected())
3012  {
3013  m_connect_address[node_id] = theFacade->ext_get_connect_address(node_id);
3014  }
3015  }
3016  return inet_ntoa(m_connect_address[node_id]);
3017 }
3018 
3019 void
3020 MgmtSrvr::get_connected_nodes(NodeBitmask &connected_nodes) const
3021 {
3022  if (theFacade)
3023  {
3024  for(Uint32 i = 0; i < MAX_NDB_NODES; i++)
3025  {
3026  if (getNodeType(i) == NDB_MGM_NODE_TYPE_NDB)
3027  {
3028  const trp_node &node= getNodeInfo(i);
3029  connected_nodes.bitOR(node.m_state.m_connected_nodes);
3030  }
3031  }
3032  }
3033 }
3034 
3035 int
3036 MgmtSrvr::alloc_node_id_req(NodeId free_node_id,
3037  enum ndb_mgm_node_type type,
3038  Uint32 timeout_ms)
3039 {
3040  SignalSender ss(theFacade);
3041  ss.lock(); // lock will be released on exit
3042 
3043  SimpleSignal ssig;
3044  AllocNodeIdReq* req = CAST_PTR(AllocNodeIdReq, ssig.getDataPtrSend());
3045  ssig.set(ss, TestOrd::TraceAPI, QMGR, GSN_ALLOC_NODEID_REQ,
3046  AllocNodeIdReq::SignalLength);
3047 
3048  req->senderRef = ss.getOwnRef();
3049  req->senderData = 19;
3050  req->nodeId = free_node_id;
3051  req->nodeType = type;
3052  req->timeout = timeout_ms;
3053 
3054  int do_send = 1;
3055  NodeId nodeId = 0;
3056  while (1)
3057  {
3058  if (nodeId == 0)
3059  {
3060  bool next;
3061  while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true &&
3062  getNodeInfo(nodeId).m_alive == false);
3063  if (!next)
3064  return NO_CONTACT_WITH_DB_NODES;
3065  do_send = 1;
3066  }
3067  if (do_send)
3068  {
3069  if (ss.sendSignal(nodeId, &ssig) != SEND_OK) {
3070  return SEND_OR_RECEIVE_FAILED;
3071  }
3072  do_send = 0;
3073  }
3074 
3075  SimpleSignal *signal = ss.waitFor();
3076 
3077  int gsn = signal->readSignalNumber();
3078  switch (gsn) {
3079  case GSN_ALLOC_NODEID_CONF:
3080  {
3081 #ifdef NOT_USED
3082  const AllocNodeIdConf * const conf =
3083  CAST_CONSTPTR(AllocNodeIdConf, signal->getDataPtr());
3084 #endif
3085  return 0;
3086  }
3087  case GSN_ALLOC_NODEID_REF:
3088  {
3089  const AllocNodeIdRef * const ref =
3090  CAST_CONSTPTR(AllocNodeIdRef, signal->getDataPtr());
3091  if (ref->errorCode == AllocNodeIdRef::NotMaster ||
3092  ref->errorCode == AllocNodeIdRef::Busy ||
3093  ref->errorCode == AllocNodeIdRef::NodeFailureHandlingNotCompleted)
3094  {
3095  do_send = 1;
3096  nodeId = refToNode(ref->masterRef);
3097  if (!getNodeInfo(nodeId).m_alive)
3098  nodeId = 0;
3099  if (ref->errorCode != AllocNodeIdRef::NotMaster)
3100  {
3101  /* sleep for a while (100ms) before retrying */
3102  ss.unlock();
3103  NdbSleep_MilliSleep(100);
3104  ss.lock();
3105  }
3106  continue;
3107  }
3108  return ref->errorCode;
3109  }
3110  case GSN_NF_COMPLETEREP:
3111  {
3112  continue;
3113  }
3114  case GSN_NODE_FAILREP:{
3119  const NodeFailRep * const rep =
3120  CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
3121  if (NdbNodeBitmask::get(rep->theNodes, nodeId))
3122  {
3123  do_send = 1;
3124  nodeId = 0;
3125  }
3126  continue;
3127  }
3128  case GSN_API_REGCONF:
3129  case GSN_TAKE_OVERTCCONF:
3130  case GSN_CONNECT_REP:
3131  continue;
3132  default:
3133  report_unknown_signal(signal);
3134  return SEND_OR_RECEIVE_FAILED;
3135  }
3136  }
3137  return 0;
3138 }
3139 
3140 static int
3141 match_hostname(const struct sockaddr *clnt_addr,
3142  const char *config_hostname)
3143 {
3144  struct in_addr config_addr= {0};
3145  if (clnt_addr)
3146  {
3147  const struct in_addr *clnt_in_addr = &((sockaddr_in*)clnt_addr)->sin_addr;
3148 
3149  if (Ndb_getInAddr(&config_addr, config_hostname) != 0
3150  || memcmp(&config_addr, clnt_in_addr, sizeof(config_addr)) != 0)
3151  {
3152  struct in_addr tmp_addr;
3153  if (Ndb_getInAddr(&tmp_addr, "localhost") != 0
3154  || memcmp(&tmp_addr, clnt_in_addr, sizeof(config_addr)) != 0)
3155  {
3156  // not localhost
3157  return -1;
3158  }
3159 
3160  // connecting through localhost
3161  // check if config_hostname is local
3162  if (!SocketServer::tryBind(0, config_hostname))
3163  return -1;
3164  }
3165  }
3166  else
3167  {
3168  if (!SocketServer::tryBind(0, config_hostname))
3169  return -1;
3170  }
3171  return 0;
3172 }
3173 
3174 int
3175 MgmtSrvr::find_node_type(unsigned node_id, enum ndb_mgm_node_type type,
3176  const struct sockaddr *client_addr,
3177  NodeBitmask &nodes,
3178  NodeBitmask &exact_nodes,
3179  Vector<struct nodeid_and_host> &nodes_info,
3180  int &error_code, BaseString &error_string)
3181 {
3182  const char *found_config_hostname= 0;
3183  unsigned type_c= (unsigned)type;
3184 
3185  Guard g(m_local_config_mutex);
3186 
3187  ConfigIter iter(m_local_config, CFG_SECTION_NODE);
3188  for(iter.first(); iter.valid(); iter.next())
3189  {
3190  unsigned id;
3191  if (iter.get(CFG_NODE_ID, &id))
3192  require(false);
3193  if (node_id && node_id != id)
3194  continue;
3195  if (iter.get(CFG_TYPE_OF_SECTION, &type_c))
3196  require(false);
3197  if (type_c != (unsigned)type)
3198  {
3199  if (!node_id)
3200  continue;
3201  goto error;
3202  }
3203  const char *config_hostname= 0;
3204  if (iter.get(CFG_NODE_HOST, &config_hostname))
3205  require(false);
3206  if (config_hostname == 0 || config_hostname[0] == 0)
3207  {
3208  config_hostname= "";
3209  }
3210  else
3211  {
3212  found_config_hostname= config_hostname;
3213  if (match_hostname(client_addr, config_hostname))
3214  {
3215  if (!node_id)
3216  continue;
3217  goto error;
3218  }
3219  exact_nodes.set(id);
3220  }
3221  nodes.set(id);
3222  struct nodeid_and_host a= {id, config_hostname};
3223  nodes_info.push_back(a);
3224  if (node_id)
3225  break;
3226  }
3227  if (nodes_info.size() != 0)
3228  {
3229  return 0;
3230  }
3231 
3232  error:
3233  /*
3234  lock on m_configMutex held because found_config_hostname may have
3235  reference inot config structure
3236  */
3237  error_code= NDB_MGM_ALLOCID_CONFIG_MISMATCH;
3238  if (node_id)
3239  {
3240  if (type_c != (unsigned) type)
3241  {
3242  BaseString type_string, type_c_string;
3243  const char *alias, *str;
3244  alias= ndb_mgm_get_node_type_alias_string(type, &str);
3245  type_string.assfmt("%s(%s)", alias, str);
3247  &str);
3248  type_c_string.assfmt("%s(%s)", alias, str);
3249  error_string.appfmt("Id %d configured as %s, connect attempted as %s.",
3250  node_id, type_c_string.c_str(),
3251  type_string.c_str());
3252  return -1;
3253  }
3254  if (found_config_hostname)
3255  {
3256  struct in_addr config_addr= {0};
3257  int r_config_addr= Ndb_getInAddr(&config_addr, found_config_hostname);
3258  error_string.appfmt("Connection with id %d done from wrong host ip %s,",
3259  node_id, inet_ntoa(((struct sockaddr_in *)
3260  (client_addr))->sin_addr));
3261  error_string.appfmt(" expected %s(%s).", found_config_hostname,
3262  r_config_addr ?
3263  "lookup failed" : inet_ntoa(config_addr));
3264  return -1;
3265  }
3266  error_string.appfmt("No node defined with id=%d in config file.", node_id);
3267  return -1;
3268  }
3269 
3270  // node_id == 0 and nodes_info.size() == 0
3271  if (found_config_hostname)
3272  {
3273  error_string.appfmt("Connection done from wrong host ip %s.",
3274  (client_addr)?
3275  inet_ntoa(((struct sockaddr_in *)
3276  (client_addr))->sin_addr):"");
3277  return -1;
3278  }
3279 
3280  error_string.append("No nodes defined in config file.");
3281  return -1;
3282 }
3283 
3284 int
3285 MgmtSrvr::try_alloc(unsigned id, const char *config_hostname,
3286  enum ndb_mgm_node_type type,
3287  const struct sockaddr *client_addr,
3288  Uint32 timeout_ms)
3289 {
3290  if (theFacade && theFacade->ext_isConnected(id))
3291  {
3292  return -1;
3293  }
3294  if (client_addr != 0)
3295  {
3296  int res = alloc_node_id_req(id, type, timeout_ms);
3297  switch (res)
3298  {
3299  case 0:
3300  // ok continue
3301  break;
3302  case NO_CONTACT_WITH_DB_NODES:
3303  // ok continue
3304  break;
3305  default:
3306  // something wrong
3307  return -1;
3308  }
3309  }
3310 
3311  DBUG_PRINT("info", ("allocating node id %d",id));
3312  {
3313  int r= 0;
3314  if (client_addr)
3315  {
3316  m_connect_address[id]= ((struct sockaddr_in *)client_addr)->sin_addr;
3317  }
3318  else if (config_hostname)
3319  {
3320  r= Ndb_getInAddr(&(m_connect_address[id]), config_hostname);
3321  }
3322  else
3323  {
3324  char name[256];
3325  r= gethostname(name, sizeof(name));
3326  if (r == 0)
3327  {
3328  name[sizeof(name)-1]= 0;
3329  r= Ndb_getInAddr(&(m_connect_address[id]), name);
3330  }
3331  }
3332  if (r)
3333  {
3334  m_connect_address[id].s_addr= 0;
3335  }
3336  }
3337  if (theFacade && id != theFacade->ownId())
3338  {
3342  theFacade->ext_doConnect(id);
3343  }
3344 
3345  g_eventLogger->info("Mgmt server state: nodeid %d reserved for ip %s, "
3346  "m_reserved_nodes %s.",
3347  id, get_connect_address(id),
3348  BaseString::getPrettyText(m_reserved_nodes).c_str());
3349 
3350  return 0;
3351 }
3352 
3353 bool
3354 MgmtSrvr::alloc_node_id(NodeId * nodeId,
3355  enum ndb_mgm_node_type type,
3356  const struct sockaddr *client_addr,
3357  SOCKET_SIZE_TYPE *client_addr_len,
3358  int &error_code, BaseString &error_string,
3359  int log_event,
3360  int timeout_s)
3361 {
3362  DBUG_ENTER("MgmtSrvr::alloc_node_id");
3363  DBUG_PRINT("enter", ("nodeid: %d type: %d client_addr: 0x%ld",
3364  *nodeId, type, (long) client_addr));
3365  if (m_opts.no_nodeid_checks) {
3366  if (*nodeId == 0) {
3367  error_string.appfmt("no-nodeid-checks set in management server. "
3368  "node id must be set explicitly in connectstring");
3369  error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH;
3370  DBUG_RETURN(false);
3371  }
3372  DBUG_RETURN(true);
3373  }
3374 
3375  Uint32 timeout_ms = Uint32(1000 * timeout_s);
3376  Uint64 stop = NdbTick_CurrentMillisecond() + timeout_ms;
3377  BaseString getconfig_message;
3378  while (!m_config_manager->get_packed_config(type, 0, getconfig_message))
3379  {
3383  if (NdbTick_CurrentMillisecond() > stop)
3384  {
3385  error_code = NDB_MGM_ALLOCID_ERROR;
3386  error_string.append("Unable to allocate nodeid as configuration"
3387  " not yet confirmed");
3388  DBUG_RETURN(false);
3389  }
3390 
3391  NdbSleep_MilliSleep(20);
3392  }
3393 
3394  Guard g(m_node_id_mutex);
3395 
3396  NodeBitmask connected_nodes;
3397  get_connected_nodes(connected_nodes);
3398 
3399  NodeBitmask nodes, exact_nodes;
3400  Vector<struct nodeid_and_host> nodes_info;
3401 
3402  /* find all nodes with correct type */
3403  if (find_node_type(*nodeId, type, client_addr, nodes, exact_nodes, nodes_info,
3404  error_code, error_string))
3405  goto error;
3406 
3407  // nodes_info.size() == 0 handled inside find_node_type
3408  DBUG_ASSERT(nodes_info.size() != 0);
3409 
3410  if (type == NDB_MGM_NODE_TYPE_MGM && nodes_info.size() > 1)
3411  {
3412  // mgmt server may only have one match
3413  error_string.appfmt("Ambiguous node id's %d and %d. "
3414  "Suggest specifying node id in connectstring, "
3415  "or specifying unique host names in config file.",
3416  nodes_info[0].id, nodes_info[1].id);
3417  error_code= NDB_MGM_ALLOCID_CONFIG_MISMATCH;
3418  goto error;
3419  }
3420 
3421  /* remove connected and reserved nodes from possible nodes to allocate */
3422  nodes.bitANDC(connected_nodes);
3423  nodes.bitANDC(m_reserved_nodes);
3424 
3425  /* first try all nodes with exact match of hostname */
3426  for (Uint32 i = 0; i < nodes_info.size(); i++)
3427  {
3428  unsigned id= nodes_info[i].id;
3429  if (!nodes.get(id))
3430  continue;
3431 
3432  if (!exact_nodes.get(id))
3433  continue;
3434 
3435  const char *config_hostname= nodes_info[i].host.c_str();
3440  m_reserved_nodes.set(id);
3441  NdbMutex_Unlock(m_node_id_mutex);
3442  if (!try_alloc(id, config_hostname, type, client_addr, timeout_ms))
3443  {
3444  NdbMutex_Lock(m_node_id_mutex);
3445  // success
3446  *nodeId= id;
3447  DBUG_RETURN(true);
3448  }
3449  NdbMutex_Lock(m_node_id_mutex);
3450  m_reserved_nodes.clear(id);
3451  }
3452 
3453  /* now try the open nodes */
3454  for (Uint32 i = 0; i < nodes_info.size(); i++)
3455  {
3456  unsigned id= nodes_info[i].id;
3457  if (!nodes.get(id))
3458  continue;
3459 
3463  if (exact_nodes.get(id))
3464  continue;
3465 
3470  m_reserved_nodes.set(id);
3471  NdbMutex_Unlock(m_node_id_mutex);
3472  if (!try_alloc(id, NULL, type, client_addr, timeout_ms))
3473  {
3474  NdbMutex_Lock(m_node_id_mutex);
3475  // success
3476  *nodeId= id;
3477  DBUG_RETURN(true);
3478  }
3479  NdbMutex_Lock(m_node_id_mutex);
3480  m_reserved_nodes.clear(id);
3481  }
3482 
3483  /*
3484  there are nodes with correct type available but
3485  allocation failed for some reason
3486  */
3487  if (*nodeId)
3488  {
3489  error_string.appfmt("Id %d already allocated by another node.",
3490  *nodeId);
3491  }
3492  else
3493  {
3494  const char *alias, *str;
3495  alias= ndb_mgm_get_node_type_alias_string(type, &str);
3496  error_string.appfmt("No free node id found for %s(%s).",
3497  alias, str);
3498  }
3499  error_code = NDB_MGM_ALLOCID_ERROR;
3500 
3501  error:
3502  if (error_code != NDB_MGM_ALLOCID_CONFIG_MISMATCH)
3503  {
3504  // we have a temporary error which might be due to that
3505  // we have got the latest connect status from db-nodes. Force update.
3506  updateStatus();
3507  }
3508 
3509  if (log_event || error_code == NDB_MGM_ALLOCID_CONFIG_MISMATCH)
3510  {
3511  g_eventLogger->warning("Allocate nodeid (%d) failed. Connection from ip %s."
3512  " Returned error string \"%s\"",
3513  *nodeId,
3514  client_addr != 0
3515  ? inet_ntoa(((struct sockaddr_in *)
3516  (client_addr))->sin_addr)
3517  : "<none>",
3518  error_string.c_str());
3519 
3520  BaseString tmp_connected, tmp_not_connected;
3521  for(Uint32 i = 0; i < MAX_NODES; i++)
3522  {
3523  if (connected_nodes.get(i))
3524  {
3525  if (!m_reserved_nodes.get(i))
3526  {
3527  tmp_connected.appfmt("%d ", i);
3528  }
3529  }
3530  else if (m_reserved_nodes.get(i))
3531  {
3532  tmp_not_connected.appfmt("%d ", i);
3533  }
3534  }
3535 
3536  if (tmp_connected.length() > 0)
3537  {
3538  g_eventLogger->info
3539  ("Mgmt server state: node id's %sconnected but not reserved",
3540  tmp_connected.c_str());
3541  }
3542 
3543  if (tmp_not_connected.length() > 0)
3544  {
3545  g_eventLogger->info
3546  ("Mgmt server state: node id's %snot connected but reserved",
3547  tmp_not_connected.c_str());
3548  }
3549  }
3550  DBUG_RETURN(false);
3551 }
3552 
3553 
3554 bool
3555 MgmtSrvr::getNextNodeId(NodeId * nodeId, enum ndb_mgm_node_type type) const
3556 {
3557  NodeId tmp = * nodeId;
3558 
3559  tmp++;
3560  while(nodeTypes[tmp] != type && tmp < MAX_NODES)
3561  tmp++;
3562 
3563  if(tmp == MAX_NODES){
3564  return false;
3565  }
3566 
3567  * nodeId = tmp;
3568  return true;
3569 }
3570 
3571 #include "Services.hpp"
3572 
3573 void
3574 MgmtSrvr::eventReport(const Uint32 * theData, Uint32 len)
3575 {
3576  const EventReport * const eventReport = (EventReport *)&theData[0];
3577 
3578  NodeId nodeId = eventReport->getNodeId();
3579  Ndb_logevent_type type = eventReport->getEventType();
3580  // Log event
3581  g_eventLogger->log(type, theData, len, nodeId,
3582  &m_event_listner[0].m_logLevel);
3583  m_event_listner.log(type, theData, len, nodeId);
3584 }
3585 
3586 /***************************************************************************
3587  * Backup
3588  ***************************************************************************/
3589 
3590 int
3591 MgmtSrvr::startBackup(Uint32& backupId, int waitCompleted, Uint32 input_backupId, Uint32 backuppoint)
3592 {
3593  SignalSender ss(theFacade);
3594  ss.lock(); // lock will be released on exit
3595 
3596  NodeId nodeId = m_master_node;
3597  if (okToSendTo(nodeId, false) != 0)
3598  {
3599  bool next;
3600  nodeId = m_master_node = 0;
3601  while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true &&
3602  okToSendTo(nodeId, false) != 0);
3603  if(!next)
3604  return NO_CONTACT_WITH_DB_NODES;
3605  }
3606 
3607  SimpleSignal ssig;
3608  BackupReq* req = CAST_PTR(BackupReq, ssig.getDataPtrSend());
3609  /*
3610  * Single-threaded backup. Set instance key 1. In the kernel
3611  * this maps to main instance 0 or worker instance 1 (if MT LQH).
3612  */
3613  BlockNumber backupBlockNo = numberToBlock(BACKUP, 1);
3614  if(input_backupId > 0)
3615  {
3616  ssig.set(ss, TestOrd::TraceAPI, backupBlockNo, GSN_BACKUP_REQ,
3617  BackupReq::SignalLength);
3618  req->inputBackupId = input_backupId;
3619  }
3620  else
3621  ssig.set(ss, TestOrd::TraceAPI, backupBlockNo, GSN_BACKUP_REQ,
3622  BackupReq::SignalLength - 1);
3623 
3624  req->senderData = 19;
3625  req->backupDataLen = 0;
3626  assert(waitCompleted < 3);
3627  req->flags = waitCompleted & 0x3;
3628  if(backuppoint == 1)
3629  req->flags |= BackupReq::USE_UNDO_LOG;
3630 
3631  int do_send = 1;
3632  while (1) {
3633  if (do_send)
3634  {
3635  if (ss.sendSignal(nodeId, &ssig) != SEND_OK) {
3636  return SEND_OR_RECEIVE_FAILED;
3637  }
3638  if (waitCompleted == 0)
3639  return 0;
3640  do_send = 0;
3641  }
3642  SimpleSignal *signal = ss.waitFor();
3643 
3644  int gsn = signal->readSignalNumber();
3645  switch (gsn) {
3646  case GSN_BACKUP_CONF:{
3647  const BackupConf * const conf =
3648  CAST_CONSTPTR(BackupConf, signal->getDataPtr());
3649 #ifdef VM_TRACE
3650  ndbout_c("Backup(%d) master is %d", conf->backupId,
3651  refToNode(signal->header.theSendersBlockRef));
3652 #endif
3653  backupId = conf->backupId;
3654  if (waitCompleted == 1)
3655  return 0;
3656  // wait for next signal
3657  break;
3658  }
3659  case GSN_BACKUP_COMPLETE_REP:{
3660  const BackupCompleteRep * const rep =
3661  CAST_CONSTPTR(BackupCompleteRep, signal->getDataPtr());
3662 #ifdef VM_TRACE
3663  ndbout_c("Backup(%d) completed", rep->backupId);
3664 #endif
3665  backupId = rep->backupId;
3666  return 0;
3667  }
3668  case GSN_BACKUP_REF:{
3669  const BackupRef * const ref =
3670  CAST_CONSTPTR(BackupRef, signal->getDataPtr());
3671  if(ref->errorCode == BackupRef::IAmNotMaster){
3672  m_master_node = nodeId = refToNode(ref->masterRef);
3673 #ifdef VM_TRACE
3674  ndbout_c("I'm not master resending to %d", nodeId);
3675 #endif
3676  do_send = 1; // try again
3677  if (!getNodeInfo(nodeId).m_alive)
3678  m_master_node = nodeId = 0;
3679  continue;
3680  }
3681  return ref->errorCode;
3682  }
3683  case GSN_BACKUP_ABORT_REP:{
3684  const BackupAbortRep * const rep =
3685  CAST_CONSTPTR(BackupAbortRep, signal->getDataPtr());
3686 #ifdef VM_TRACE
3687  ndbout_c("Backup %d aborted", rep->backupId);
3688 #endif
3689  return rep->reason;
3690  }
3691  case GSN_NF_COMPLETEREP:{
3692  const NFCompleteRep * const rep =
3693  CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr());
3694 #ifdef VM_TRACE
3695  ndbout_c("Node %d fail completed", rep->failedNodeId);
3696 #endif
3697  if (rep->failedNodeId == nodeId ||
3698  waitCompleted == 1)
3699  return 1326;
3700  // wait for next signal
3701  // master node will report aborted backup
3702  break;
3703  }
3704  case GSN_NODE_FAILREP:{
3705  const NodeFailRep * const rep =
3706  CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
3707  if (NdbNodeBitmask::get(rep->theNodes,nodeId) ||
3708  waitCompleted == 1)
3709  return 1326;
3710  // wait for next signal
3711  // master node will report aborted backup
3712  break;
3713  }
3714  case GSN_API_REGCONF:
3715  case GSN_TAKE_OVERTCCONF:
3716  case GSN_CONNECT_REP:
3717  continue;
3718  default:
3719  report_unknown_signal(signal);
3720  return SEND_OR_RECEIVE_FAILED;
3721  }
3722  }
3723 }
3724 
3725 int
3726 MgmtSrvr::abortBackup(Uint32 backupId)
3727 {
3728  SignalSender ss(theFacade);
3729  ss.lock(); // lock will be released on exit
3730 
3731  bool next;
3732  NodeId nodeId = 0;
3733  while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true &&
3734  getNodeInfo(nodeId).m_alive == false);
3735 
3736  if(!next){
3737  return NO_CONTACT_WITH_DB_NODES;
3738  }
3739 
3740  SimpleSignal ssig;
3741 
3742  AbortBackupOrd* ord = CAST_PTR(AbortBackupOrd, ssig.getDataPtrSend());
3743  /*
3744  * Single-threaded backup. Set instance key 1. In the kernel
3745  * this maps to main instance 0 or worker instance 1 (if MT LQH).
3746  */
3747  BlockNumber backupBlockNo = numberToBlock(BACKUP, 1);
3748  ssig.set(ss, TestOrd::TraceAPI, backupBlockNo, GSN_ABORT_BACKUP_ORD,
3749  AbortBackupOrd::SignalLength);
3750 
3751  ord->requestType = AbortBackupOrd::ClientAbort;
3752  ord->senderData = 19;
3753  ord->backupId = backupId;
3754 
3755  return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
3756 }
3757 
3758 
3759 MgmtSrvr::Allocated_resources::Allocated_resources(MgmtSrvr &m)
3760  : m_mgmsrv(m)
3761 {
3762  m_reserved_nodes.clear();
3763  m_alloc_timeout= 0;
3764 }
3765 
3767 {
3768  if (m_reserved_nodes.isclear())
3769  {
3774  return;
3775  }
3776 
3777  Guard g(m_mgmsrv.m_node_id_mutex);
3778  m_mgmsrv.m_reserved_nodes.bitANDC(m_reserved_nodes);
3779 
3780  // node has been reserved, force update signal to ndb nodes
3781  m_mgmsrv.updateStatus();
3782 
3783  g_eventLogger->
3784  info("Mgmt server state: nodeid %d freed, m_reserved_nodes %s.",
3785  get_nodeid(),
3786  BaseString::getPrettyText(m_mgmsrv.m_reserved_nodes).c_str());
3787 }
3788 
3789 void
3790 MgmtSrvr::Allocated_resources::reserve_node(NodeId id, NDB_TICKS timeout)
3791 {
3792  m_reserved_nodes.set(id);
3793  m_alloc_timeout= NdbTick_CurrentMillisecond() + timeout;
3794 }
3795 
3796 bool
3797 MgmtSrvr::Allocated_resources::is_timed_out(NDB_TICKS tick)
3798 {
3799  if (m_alloc_timeout && tick > m_alloc_timeout)
3800  {
3801  g_eventLogger->info("Mgmt server state: nodeid %d timed out.",
3802  get_nodeid());
3803  return true;
3804  }
3805  return false;
3806 }
3807 
3808 NodeId
3809 MgmtSrvr::Allocated_resources::get_nodeid() const
3810 {
3811  for(Uint32 i = 0; i < MAX_NODES; i++)
3812  {
3813  if (m_reserved_nodes.get(i))
3814  return i;
3815  }
3816  return 0;
3817 }
3818 
3819 int
3820 MgmtSrvr::setDbParameter(int node, int param, const char * value,
3821  BaseString& msg)
3822 {
3823 
3824  Guard g(m_local_config_mutex);
3825 
3829  ConfigIter iter(m_local_config, CFG_SECTION_NODE);
3830  if(iter.first() != 0){
3831  msg.assign("Unable to find node section (iter.first())");
3832  return -1;
3833  }
3834 
3835  Uint32 type = NODE_TYPE_DB + 1;
3836  if(node != 0){
3837  // Set parameter only in the specified node
3838  if(iter.find(CFG_NODE_ID, node) != 0){
3839  msg.assign("Unable to find node (iter.find())");
3840  return -1;
3841  }
3842  if(iter.get(CFG_TYPE_OF_SECTION, &type) != 0){
3843  msg.assign("Unable to get node type(iter.get(CFG_TYPE_OF_SECTION))");
3844  return -1;
3845  }
3846  } else {
3847  // Set parameter in all DB nodes
3848  do {
3849  if(iter.get(CFG_TYPE_OF_SECTION, &type) != 0){
3850  msg.assign("Unable to get node type(iter.get(CFG_TYPE_OF_SECTION))");
3851  return -1;
3852  }
3853  if(type == NODE_TYPE_DB)
3854  break;
3855  } while(iter.next() == 0);
3856  }
3857 
3858  if(type != NODE_TYPE_DB){
3859  msg.assfmt("Invalid node type or no such node (%d %d)",
3860  type, NODE_TYPE_DB);
3861  return -1;
3862  }
3863 
3864  int p_type;
3865  unsigned val_32;
3866  Uint64 val_64;
3867  const char * val_char;
3868  do {
3869  p_type = 0;
3870  if(iter.get(param, &val_32) == 0){
3871  val_32 = atoi(value);
3872  break;
3873  }
3874 
3875  p_type++;
3876  if(iter.get(param, &val_64) == 0){
3877  val_64 = strtoll(value, 0, 10);
3878  break;
3879  }
3880  p_type++;
3881  if(iter.get(param, &val_char) == 0){
3882  val_char = value;
3883  break;
3884  }
3885  msg.assign("Could not get parameter");
3886  return -1;
3887  } while(0);
3888 
3889  bool res = false;
3890  do {
3891  int ret = iter.get(CFG_TYPE_OF_SECTION, &type);
3892  assert(ret == 0);
3893 
3894  if(type != NODE_TYPE_DB)
3895  continue;
3896 
3897  Uint32 node;
3898  ret = iter.get(CFG_NODE_ID, &node);
3899  assert(ret == 0);
3900 
3901  ConfigValues::Iterator i2(m_local_config->m_configValues->m_config,
3902  iter.m_config);
3903  switch(p_type){
3904  case 0:
3905  res = i2.set(param, val_32);
3906  ndbout_c("Updating node %d param: %d to %d", node, param, val_32);
3907  break;
3908  case 1:
3909  res = i2.set(param, val_64);
3910  ndbout_c("Updating node %d param: %d to %u", node, param, val_32);
3911  break;
3912  case 2:
3913  res = i2.set(param, val_char);
3914  ndbout_c("Updating node %d param: %d to %s", node, param, val_char);
3915  break;
3916  default:
3917  require(false);
3918  }
3919  assert(res);
3920  } while(node == 0 && iter.next() == 0);
3921 
3922  msg.assign("Success");
3923  return 0;
3924 }
3925 
3926 
3927 int
3928 MgmtSrvr::setConnectionDbParameter(int node1, int node2,
3929  int param, int value,
3930  BaseString& msg)
3931 {
3932  DBUG_ENTER("MgmtSrvr::setConnectionDbParameter");
3933  DBUG_PRINT("enter", ("node1: %d, node2: %d, param: %d, value: %d",
3934  node1, node2, param, value));
3935 
3936  // This function only supports setting dynamic ports
3937  if (param != CFG_CONNECTION_SERVER_PORT)
3938  {
3939  msg.assign("Only param CFG_CONNECTION_SERVER_PORT can be set");
3940  DBUG_RETURN(-1);
3941  }
3942 
3943  if (!m_config_manager->set_dynamic_port(node1, node2, value, msg))
3944  DBUG_RETURN(-1);
3945 
3946  DBUG_PRINT("exit", ("Set parameter(%d) to %d for %d -> %d",
3947  param, value, node1, node2));
3948  DBUG_RETURN(1);
3949 }
3950 
3951 
3952 int
3953 MgmtSrvr::getConnectionDbParameter(int node1, int node2,
3954  int param, int *value,
3955  BaseString& msg)
3956 {
3957  DBUG_ENTER("MgmtSrvr::getConnectionDbParameter");
3958  DBUG_PRINT("enter", ("node1: %d, node2: %d, param: %d",
3959  node1, node2, param));
3960 
3961  // This function only supports asking about dynamic ports
3962  if (param != CFG_CONNECTION_SERVER_PORT)
3963  {
3964  msg.assign("Only param CFG_CONNECTION_SERVER_PORT can be retrieved");
3965  DBUG_RETURN(-1);
3966  }
3967 
3968  if (!m_config_manager->get_dynamic_port(node1, node2, value, msg))
3969  DBUG_RETURN(-1);
3970 
3971  DBUG_PRINT("exit", ("Return parameter(%d): %u for %d -> %d, msg: %s",
3972  param, *value, node1, node2, msg.c_str()));
3973  DBUG_RETURN(1);
3974 }
3975 
3976 
3977 bool
3978 MgmtSrvr::transporter_connect(NDB_SOCKET_TYPE sockfd, BaseString& msg)
3979 {
3980  DBUG_ENTER("MgmtSrvr::transporter_connect");
3981  TransporterRegistry* tr= theFacade->get_registry();
3982  if (!tr->connect_server(sockfd, msg))
3983  DBUG_RETURN(false);
3984 
3985  /*
3986  Force an update_connections() so that the
3987  ClusterMgr and TransporterFacade is up to date
3988  with the new connection.
3989  Important for correct node id reservation handling
3990  */
3991  theFacade->ext_update_connections();
3992 
3993  DBUG_RETURN(true);
3994 }
3995 
3996 
3997 bool MgmtSrvr::connect_to_self()
3998 {
3999  BaseString buf;
4000  NdbMgmHandle mgm_handle= ndb_mgm_create_handle();
4001 
4002  buf.assfmt("%s:%u",
4003  m_opts.bind_address ? m_opts.bind_address : "localhost",
4004  m_port);
4005  ndb_mgm_set_connectstring(mgm_handle, buf.c_str());
4006 
4007  if(ndb_mgm_connect(mgm_handle, 0, 0, 0) < 0)
4008  {
4009  g_eventLogger->warning("%d %s",
4010  ndb_mgm_get_latest_error(mgm_handle),
4011  ndb_mgm_get_latest_error_desc(mgm_handle));
4012  ndb_mgm_destroy_handle(&mgm_handle);
4013  return false;
4014  }
4015  // TransporterRegistry now owns the handle and will destroy it.
4016  theFacade->get_registry()->set_mgm_handle(mgm_handle);
4017 
4018  return true;
4019 }
4020 
4021 
4022 bool
4023 MgmtSrvr::change_config(Config& new_config, BaseString& msg)
4024 {
4025  SignalSender ss(theFacade);
4026  ss.lock();
4027 
4028  SimpleSignal ssig;
4029  UtilBuffer buf;
4030  new_config.pack(buf);
4031  ssig.ptr[0].p = (Uint32*)buf.get_data();
4032  ssig.ptr[0].sz = (buf.length() + 3) / 4;
4033  ssig.header.m_noOfSections = 1;
4034 
4035  ConfigChangeReq *req= CAST_PTR(ConfigChangeReq, ssig.getDataPtrSend());
4036  req->length = buf.length();
4037 
4038  NodeBitmask mgm_nodes;
4039  m_local_config->get_nodemask(mgm_nodes, NDB_MGM_NODE_TYPE_MGM);
4040 
4041  NodeId nodeId= ss.find_confirmed_node(mgm_nodes);
4042  if (nodeId == 0)
4043  {
4044  msg = "INTERNAL ERROR Could not find any mgmd!";
4045  return false;
4046  }
4047 
4048  if (ss.sendFragmentedSignal(nodeId, ssig,
4049  MGM_CONFIG_MAN, GSN_CONFIG_CHANGE_REQ,
4050  ConfigChangeReq::SignalLength) != 0)
4051  {
4052  msg.assfmt("Could not start configuration change, send to "
4053  "node %d failed", nodeId);
4054  return false;
4055  }
4056  mgm_nodes.clear(nodeId);
4057 
4058  bool done = false;
4059  while(!done)
4060  {
4061  SimpleSignal *signal= ss.waitFor();
4062 
4063  switch(signal->readSignalNumber()){
4064  case GSN_CONFIG_CHANGE_CONF:
4065  done= true;
4066  break;
4067  case GSN_CONFIG_CHANGE_REF:
4068  {
4069  const ConfigChangeRef * const ref =
4070  CAST_CONSTPTR(ConfigChangeRef, signal->getDataPtr());
4071  g_eventLogger->debug("Got CONFIG_CHANGE_REF, error: %d", ref->errorCode);
4072  switch(ref->errorCode)
4073  {
4074  case ConfigChangeRef::NotMaster:{
4075  // Retry with next node if any
4076  NodeId nodeId= ss.find_confirmed_node(mgm_nodes);
4077  if (nodeId == 0)
4078  {
4079  msg = "INTERNAL ERROR Could not find any mgmd!";
4080  return false;
4081  }
4082 
4083  if (ss.sendFragmentedSignal(nodeId, ssig,
4084  MGM_CONFIG_MAN, GSN_CONFIG_CHANGE_REQ,
4085  ConfigChangeReq::SignalLength) != 0)
4086  {
4087  msg.assfmt("Could not start configuration change, send to "
4088  "node %d failed", nodeId);
4089  return false;
4090  }
4091  mgm_nodes.clear(nodeId);
4092  break;
4093  }
4094 
4095  default:
4096  msg = ConfigChangeRef::errorMessage(ref->errorCode);
4097  return false;
4098  }
4099 
4100  break;
4101  }
4102 
4103  case GSN_API_REGCONF:
4104  case GSN_TAKE_OVERTCCONF:
4105  case GSN_CONNECT_REP:
4106  // Ignore;
4107  break;
4108 
4109 
4110  case GSN_NODE_FAILREP:
4111  // ignore, NF_COMPLETEREP will come
4112  break;
4113 
4114  case GSN_NF_COMPLETEREP:
4115  {
4116  NodeId nodeId = refToNode(signal->header.theSendersBlockRef);
4117  msg.assign("Node %d failed during configuration change", nodeId);
4118  return false;
4119  break;
4120  }
4121 
4122  default:
4123  report_unknown_signal(signal);
4124  return false;
4125 
4126  }
4127  }
4128 
4129  g_eventLogger->info("Config change completed");
4130 
4131  return true;
4132 }
4133 
4134 
4135 void
4136 MgmtSrvr::print_config(const char* section_filter, NodeId nodeid_filter,
4137  const char* param_filter,
4138  NdbOut& out)
4139 {
4140  Guard g(m_local_config_mutex);
4141  m_local_config->print(section_filter, nodeid_filter,
4142  param_filter, out);
4143 }
4144 
4145 
4146 bool
4147 MgmtSrvr::reload_config(const char* config_filename, bool mycnf,
4148  BaseString& msg)
4149 {
4150  if (config_filename && mycnf)
4151  {
4152  msg = "ERROR: Both mycnf and config_filename is not supported";
4153  return false;
4154  }
4155 
4156  if (config_filename)
4157  {
4158  if (m_opts.mycnf)
4159  {
4160  msg.assfmt("ERROR: Can't switch to use config.ini '%s' when "
4161  "node was started from my.cnf", config_filename);
4162  return false;
4163  }
4164  }
4165  else
4166  {
4167  if (mycnf)
4168  {
4169  // Reload from my.cnf
4170  if (!m_opts.mycnf)
4171  {
4172  if (m_opts.config_filename)
4173  {
4174  msg.assfmt("ERROR: Can't switch to use my.cnf when "
4175  "node was started from '%s'", m_opts.config_filename);
4176  return false;
4177  }
4178  }
4179  }
4180  else
4181  {
4182  /* No config file name supplied and not told to use mycnf */
4183  if (m_opts.config_filename)
4184  {
4185  g_eventLogger->info("No config file name supplied, using '%s'",
4186  m_opts.config_filename);
4187  config_filename = m_opts.config_filename;
4188  }
4189  else
4190  {
4191  msg = "ERROR: Neither config file name or mycnf available";
4192  return false;
4193  }
4194  }
4195  }
4196 
4197  Config* new_conf_ptr;
4198  if ((new_conf_ptr= ConfigManager::load_config(config_filename,
4199  mycnf, msg)) == NULL)
4200  return false;
4201  Config new_conf(new_conf_ptr);
4202 
4203  {
4204  Guard g(m_local_config_mutex);
4205 
4206  /* Copy the necessary values from old to new config */
4207  if (!new_conf.setGeneration(m_local_config->getGeneration()) ||
4208  !new_conf.setName(m_local_config->getName()) ||
4209  !new_conf.setPrimaryMgmNode(m_local_config->getPrimaryMgmNode()))
4210  {
4211  msg = "Failed to initialize reloaded config";
4212  return false;
4213  }
4214  }
4215 
4216  if (!change_config(new_conf, msg))
4217  return false;
4218  return true;
4219 }
4220 
4221 void
4222 MgmtSrvr::show_variables(NdbOut& out)
4223 {
4224  out << "daemon: " << yes_no(m_opts.daemon) << endl;
4225  out << "non_interactive: " << yes_no(m_opts.non_interactive) << endl;
4226  out << "interactive: " << yes_no(m_opts.interactive) << endl;
4227  out << "config_filename: " << str_null(m_opts.config_filename) << endl;
4228  out << "mycnf: " << yes_no(m_opts.mycnf) << endl;
4229  out << "bind_address: " << str_null(m_opts.bind_address) << endl;
4230  out << "no_nodeid_checks: " << yes_no(m_opts.no_nodeid_checks) << endl;
4231  out << "print_full_config: " << yes_no(m_opts.print_full_config) << endl;
4232  out << "configdir: " << str_null(m_opts.configdir) << endl;
4233  out << "verbose: " << yes_no(m_opts.verbose) << endl;
4234  out << "reload: " << yes_no(m_opts.reload) << endl;
4235 
4236  out << "nodeid: " << _ownNodeId << endl;
4237  out << "blocknumber: " << hex <<_blockNumber << endl;
4238  out << "own_reference: " << hex << _ownReference << endl;
4239  out << "port: " << m_port << endl;
4240  out << "need_restart: " << m_need_restart << endl;
4241  out << "is_stop_thread: " << _isStopThread << endl;
4242  out << "log_level_thread_sleep: " << _logLevelThreadSleep << endl;
4243  out << "master_node: " << m_master_node << endl;
4244 }
4245 
4246 void
4247 MgmtSrvr::make_sync_req(SignalSender& ss, Uint32 nodeId)
4248 {
4249  const trp_node node = ss.getNodeInfo(nodeId);
4250  if (!ndbd_sync_req_support(node.m_info.m_version))
4251  {
4252  /* The node hasn't got SYNC_REQ support */
4253  return;
4254  }
4255 
4265  SimpleSignal ssig;
4266  SyncReq* req = CAST_PTR(SyncReq, ssig.getDataPtrSend());
4267  req->senderRef = ss.getOwnRef();
4268  req->senderData = 12;
4269  req->prio = 1; // prio b
4270  ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_SYNC_REQ, SyncReq::SignalLength);
4271 
4272  if (ss.sendSignal(nodeId, &ssig) != SEND_OK)
4273  {
4274  return;
4275  }
4276 
4277  while (true)
4278  {
4279  SimpleSignal *signal = ss.waitFor();
4280 
4281  int gsn = signal->readSignalNumber();
4282  switch (gsn) {
4283  case GSN_SYNC_REF:
4284  case GSN_SYNC_CONF:
4285  return;
4286 
4287  case GSN_NF_COMPLETEREP:{
4288  const NFCompleteRep * const rep =
4289  CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr());
4290  if (rep->failedNodeId == nodeId)
4291  return;
4292  break;
4293  }
4294 
4295  case GSN_NODE_FAILREP:{
4296  const NodeFailRep * const rep =
4297  CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
4298  if (NdbNodeBitmask::get(rep->theNodes,nodeId))
4299  return;
4300  break;
4301  }
4302  case GSN_API_REGCONF:
4303  case GSN_TAKE_OVERTCCONF:
4304  case GSN_CONNECT_REP:
4305  break;
4306  default:
4307  return;
4308  }
4309  }
4310 }
4311 
4312 
4313 bool
4314 MgmtSrvr::request_events(NdbNodeBitmask nodes, Uint32 reports_per_node,
4315  Uint32 dump_type,
4316  Vector<SimpleSignal>& events)
4317 {
4318  int nodes_counter[MAX_NDB_NODES];
4319  SignalSender ss(theFacade);
4320  ss.lock();
4321 
4322  // Send the dump command to all requested NDB nodes
4323  const bool all = nodes.isclear();
4324  for (int i = 1; i < MAX_NDB_NODES; i++)
4325  {
4326  // Check if node should be involved
4327  if (!all && !nodes.get(i))
4328  continue;
4329 
4330  // Only request from confirmed DB nodes
4331  const trp_node node = ss.getNodeInfo(i);
4332  if (node.m_info.getType() != NodeInfo::DB ||
4333  !node.is_confirmed())
4334  {
4335  nodes.clear(i);
4336  continue;
4337  }
4338 
4339  SimpleSignal ssig;
4340  DumpStateOrd * const dumpOrd = (DumpStateOrd*)ssig.getDataPtrSend();
4341 
4342  dumpOrd->args[0] = dump_type;
4343  dumpOrd->args[1] = ss.getOwnRef(); // Return to sender
4344 
4345  if (ss.sendSignal(i, ssig, CMVMI, GSN_DUMP_STATE_ORD, 2) == SEND_OK)
4346  {
4347  nodes.set(i);
4348  nodes_counter[i] = (int)reports_per_node;
4349  }
4350  }
4351 
4352 
4353  while (true)
4354  {
4355  // Check if all nodes are done
4356  if (nodes.isclear())
4357  break;
4358 
4359  SimpleSignal *signal = ss.waitFor();
4360  switch (signal->readSignalNumber()) {
4361  case GSN_EVENT_REP:{
4362  const NodeId nodeid = refToNode(signal->header.theSendersBlockRef);
4363  const EventReport * const event =
4364  (const EventReport*)signal->getDataPtr();
4365 
4366  if (!nodes.get(nodeid))
4367  {
4368  // The reporting node was not expected
4369  assert(false);
4370  return false;
4371  }
4372 
4373  if (event->getEventType() == NDB_LE_SavedEvent &&
4374  signal->getDataPtr()[1] == 0)
4375  {
4376  nodes_counter[nodeid] = 1;
4377  }
4378  else
4379  {
4380  // Save signal
4381  events.push_back(SimpleSignal(*signal));
4382  }
4383 
4384  // Check if node is done
4385  nodes_counter[nodeid]--;
4386  if (nodes_counter[nodeid] == 0)
4387  nodes.clear(nodeid);
4388 
4389  break;
4390  }
4391 
4392  case GSN_NODE_FAILREP:{
4393  const NodeFailRep * const rep =
4394  (const NodeFailRep*)signal->getDataPtr();
4395  for (NodeId i = 1; i < MAX_NDB_NODES; i++)
4396  {
4397  if (NdbNodeBitmask::get(rep->theNodes, i))
4398  {
4399  nodes.clear(i);
4400 
4401  // Remove any previous reports from this node
4402  // it should not be reported
4403  for (unsigned j = 0; j < events.size(); j++)
4404  {
4405  const SimpleSignal& ssig = events[j];
4406  const NodeId nodeid = refToNode(ssig.header.theSendersBlockRef);
4407  if (nodeid == i)
4408  {
4409  events.erase(j);
4410  j--;
4411  }
4412  }
4413  }
4414  }
4415  break;
4416  }
4417 
4418  default:
4419  // Ignore all other signals
4420  break;
4421  }
4422  }
4423  ss.unlock();
4424 
4425  return true;
4426 }
4427 
4428 template class MutexVector<NodeId>;
4430 template class Vector<EventSubscribeReq>;
4431 template class MutexVector<EventSubscribeReq>;
4432 template class Vector< Vector<BaseString> >;
4433 template class Vector<MgmtSrvr::nodeid_and_host>;
4434 template class Vector<Defragger::DefragBuffer*>;