List:Commits« Previous MessageNext Message »
From:tomas Date:April 6 2006 4:47pm
Subject:bk commit into 5.1 tree (tomas:1.2004)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of tomas. When tomas does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.2004 06/04/06 18:46:36 tomas@stripped +6 -0
  Support for ndb multi-node shutdown

  storage/ndb/src/mgmsrv/Services.cpp
    1.57 06/04/06 18:46:22 tomas@stripped +20 -17
    Support for ndb multi-node shutdown

  storage/ndb/src/mgmsrv/MgmtSrvr.hpp
    1.41 06/04/06 18:46:21 tomas@stripped +8 -5
    Support for ndb multi-node shutdown

  storage/ndb/src/mgmsrv/MgmtSrvr.cpp
    1.87 06/04/06 18:46:21 tomas@stripped +133 -69
    Support for ndb multi-node shutdown

  storage/ndb/src/mgmclient/CommandInterpreter.cpp
    1.59 06/04/06 18:46:21 tomas@stripped +177 -55
    Support for ndb multi-node shutdown

  storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp
    1.27 06/04/06 18:46:20 tomas@stripped +5 -0
    Support for ndb multi-node shutdown

  storage/ndb/include/kernel/signaldata/StopReq.hpp
    1.5 06/04/06 18:46:20 tomas@stripped +2 -1
    Support for ndb multi-node shutdown

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	tomas
# Host:	poseidon.ndb.mysql.com
# Root:	/home/tomas/wl2325-alcatel

--- 1.4/storage/ndb/include/kernel/signaldata/StopReq.hpp	2006-04-05 16:05:35 +02:00
+++ 1.5/storage/ndb/include/kernel/signaldata/StopReq.hpp	2006-04-06 18:46:20 +02:00
@@ -92,7 +92,7 @@
   friend class Ndbcntr;
 
 public:
-  STATIC_CONST( SignalLength = 2 );
+  STATIC_CONST( SignalLength = 3 );
   
   enum ErrorCode {
     OK = 0,
@@ -107,6 +107,7 @@
 public:
   Uint32 senderData;
   Uint32 errorCode;
+  Uint32 masterNodeId;
 };
 
 inline

--- 1.26/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp	2006-04-05 16:05:36 +02:00
+++ 1.27/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp	2006-04-06 18:46:20 +02:00
@@ -2161,6 +2161,7 @@
     else
       ref->errorCode = StopRef::NodeShutdownInProgress;
     ref->senderData = senderData;
+    ref->masterNodeId = cmasterNodeId;
     
     if (senderRef != RNIL)
       sendSignal(senderRef, GSN_STOP_REF, signal, StopRef::SignalLength, JBB);
@@ -2172,6 +2173,7 @@
     jam();
     ref->errorCode = StopRef::UnsupportedNodeShutdown;
     ref->senderData = senderData;
+    ref->masterNodeId = cmasterNodeId;
     if (senderRef != RNIL)
       sendSignal(senderRef, GSN_STOP_REF, signal, StopRef::SignalLength, JBB);
     return;
@@ -2182,6 +2184,7 @@
     jam();
     ref->errorCode = StopRef::MultiNodeShutdownNotMaster;
     ref->senderData = senderData;
+    ref->masterNodeId = cmasterNodeId;
     if (senderRef != RNIL)
       sendSignal(senderRef, GSN_STOP_REF, signal, StopRef::SignalLength, JBB);
     return;
@@ -2325,6 +2328,7 @@
   
   ref->senderData = stopReq.senderData;
   ref->errorCode = StopRef::NodeShutdownWouldCauseSystemCrash;
+  ref->masterNodeId = cntr.cmasterNodeId;
   
   const BlockReference bref = stopReq.senderRef;
   if (bref != RNIL)
@@ -2473,6 +2477,7 @@
   StopRef * const stopRef = (StopRef *)&signal->theData[0];
   stopRef->senderData = c_stopRec.stopReq.senderData;
   stopRef->errorCode = StopRef::TransactionAbortFailed;
+  stopRef->masterNodeId = cmasterNodeId;
   sendSignal(c_stopRec.stopReq.senderRef, GSN_STOP_REF, signal, StopRef::SignalLength, JBB);
 }
 

--- 1.58/storage/ndb/src/mgmclient/CommandInterpreter.cpp	2005-10-07 10:58:07 +02:00
+++ 1.59/storage/ndb/src/mgmclient/CommandInterpreter.cpp	2006-04-06 18:46:21 +02:00
@@ -18,6 +18,7 @@
 #include <my_sys.h>
 #include <Vector.hpp>
 #include <mgmapi.h>
+#include <util/BaseString.hpp>
 
 class MgmtSrvr;
 
@@ -63,6 +64,9 @@
    */
   void analyseAfterFirstToken(int processId, char* allAfterFirstTokenCstr);
 
+  void executeCommand(Vector<BaseString> &command_list,
+                      unsigned command_pos,
+                      int *node_ids, int no_of_nodes);
   /**
    *   Parse the block specification part of the LOG* commands,
    *   things after LOG*: [BLOCK = {ALL|<blockName>+}]
@@ -97,10 +101,14 @@
 
 public:
   void executeStop(int processId, const char* parameters, bool all);
+  void executeStop(Vector<BaseString> &command_list, unsigned command_pos,
+                   int *node_ids, int no_of_nodes);
   void executeEnterSingleUser(char* parameters);
   void executeExitSingleUser(char* parameters);
   void executeStart(int processId, const char* parameters, bool all);
   void executeRestart(int processId, const char* parameters, bool all);
+  void executeRestart(Vector<BaseString> &command_list, unsigned command_pos,
+                      int *node_ids, int no_of_nodes);
   void executeLogLevel(int processId, const char* parameters, bool all);
   void executeError(int processId, const char* parameters, bool all);
   void executeLog(int processId, const char* parameters, bool all);
@@ -583,9 +591,16 @@
     }
   } while (do_continue);
   // if there is anything in the line proceed
+  Vector<BaseString> command_list;
+  {
+    BaseString tmp(line);
+    tmp.split(command_list);
+    for (unsigned i= 0; i < command_list.size();)
+      command_list[i].c_str()[0] ? i++ : (command_list.erase(i),0);
+  }
   char* firstToken = strtok(line, " ");
   char* allAfterFirstToken = strtok(NULL, "");
-  
+
   if (strcasecmp(firstToken, "HELP") == 0 ||
       strcasecmp(firstToken, "?") == 0) {
     executeHelp(allAfterFirstToken);
@@ -656,22 +671,45 @@
     analyseAfterFirstToken(-1, allAfterFirstToken);
   } else {
     /**
-     * First token should be a digit, node ID
+     * First tokens should be digits, node ID's
      */
-    int nodeId;
-
-    if (! convert(firstToken, nodeId)) {
+    int node_ids[MAX_NODES];
+    unsigned pos;
+    for (pos= 0; pos < command_list.size(); pos++)
+    {
+      int node_id;
+      if (convert(command_list[pos].c_str(), node_id))
+      {
+        if (node_id <= 0) {
+          ndbout << "Invalid node ID: " << command_list[pos].c_str()
+                 << "." << endl;
+          DBUG_RETURN(true);
+        }
+        node_ids[pos]= node_id;
+        continue;
+      }
+      break;
+    }
+    int no_of_nodes= pos;
+    if (no_of_nodes == 0)
+    {
+      /* No digit found */
       invalid_command(_line);
       DBUG_RETURN(true);
     }
-
-    if (nodeId <= 0) {
-      ndbout << "Invalid node ID: " << firstToken << "." << endl;
+    if (pos == command_list.size())
+    {
+      /* No command found */
+      invalid_command(_line);
       DBUG_RETURN(true);
     }
-    
-    analyseAfterFirstToken(nodeId, allAfterFirstToken);
-    
+    if (no_of_nodes == 1)
+    {
+      analyseAfterFirstToken(node_ids[0], allAfterFirstToken);
+      DBUG_RETURN(true);
+    }
+    executeCommand(command_list, pos, node_ids, no_of_nodes);
+    DBUG_RETURN(true);
   }
   DBUG_RETURN(true);
 }
@@ -741,6 +779,27 @@
   ndbout << endl;
 }
 
+void
+CommandInterpreter::executeCommand(Vector<BaseString> &command_list,
+                                   unsigned command_pos,
+                                   int *node_ids, int no_of_nodes)
+{
+  const char *cmd= command_list[command_pos].c_str();
+  if (strcasecmp("STOP", cmd) == 0)
+  {
+    executeStop(command_list, command_pos+1, node_ids, no_of_nodes);
+    return;
+  }
+  if (strcasecmp("RESTART", cmd) == 0)
+  {
+    executeRestart(command_list, command_pos+1, node_ids, no_of_nodes);
+    return;
+  }
+  ndbout_c("Invalid command: '%s' after multi node id list. "
+           "Expected STOP or RESTART.", cmd);
+  return;
+}
+
 /**
  * Get next nodeid larger than the give node_id. node_id will be
  * set to the next node_id in the list. node_id should be set
@@ -1331,24 +1390,60 @@
 //*****************************************************************************
 
 void
-CommandInterpreter::executeStop(int processId, const char *, bool all) 
+CommandInterpreter::executeStop(int processId, const char *parameters,
+                                bool all) 
 {
-  int result = 0;
-  if(all) {
-    result = ndb_mgm_stop(m_mgmsrv, 0, 0);
-  } else {
-    result = ndb_mgm_stop(m_mgmsrv, 1, &processId);
+  Vector<BaseString> command_list;
+  if (parameters)
+  {
+    BaseString tmp(parameters);
+    tmp.split(command_list);
+    for (unsigned i= 0; i < command_list.size();)
+      command_list[i].c_str()[0] ? i++ : (command_list.erase(i),0);
   }
-  if (result < 0) {
-    ndbout << "Shutdown failed." << endl;
+  if (all)
+    executeStop(command_list, 0, 0, 0);
+  else
+    executeStop(command_list, 0, &processId, 1);
+}
+
+void
+CommandInterpreter::executeStop(Vector<BaseString> &command_list,
+                                unsigned command_pos,
+                                int *node_ids, int no_of_nodes)
+{
+  int abort= 0;
+  for (; command_pos < command_list.size(); command_pos++)
+  {
+    const char *item= command_list[command_pos].c_str();
+    if (strcasecmp(item, "-A") == 0)
+    {
+      abort= 1;
+      continue;
+    }
+    ndbout_c("Invalid option: %s. Expecting -A after STOP",
+             item);
+    return;
+  }
+
+  int result= ndb_mgm_stop2(m_mgmsrv, no_of_nodes, node_ids, abort);
+  if (result < 0)
+  {
+    ndbout_c("Shutdown failed.");
     printError();
-  } else
+  }
+  else
+  {
+    if (node_ids == 0)
+      ndbout_c("NDB Cluster has shutdown.");
+    else
     {
-      if(all)
-	ndbout << "NDB Cluster has shutdown." << endl;
-      else
-	ndbout << "Node " << processId << " has shutdown." << endl;
+      ndbout << "Node";
+      for (int i= 0; i < no_of_nodes; i++)
+        ndbout << " " << node_ids[i];
+      ndbout_c(" has shutdown.");
     }
+  }
 }
 
 void
@@ -1414,47 +1509,74 @@
 
 void
 CommandInterpreter::executeRestart(int processId, const char* parameters,
-				   bool all) 
+				   bool all)
+{
+  Vector<BaseString> command_list;
+  if (parameters)
+  {
+    BaseString tmp(parameters);
+    tmp.split(command_list);
+    for (unsigned i= 0; i < command_list.size();)
+      command_list[i].c_str()[0] ? i++ : (command_list.erase(i),0);
+  }
+  if (all)
+    executeRestart(command_list, 0, 0, 0);
+  else
+    executeRestart(command_list, 0, &processId, 1);
+}
+
+void
+CommandInterpreter::executeRestart(Vector<BaseString> &command_list,
+                                   unsigned command_pos,
+                                   int *node_ids, int no_of_nodes)
 {
   int result;
-  int nostart = 0;
-  int initialstart = 0;
-  int abort = 0;
-
-  if(parameters != 0 && strlen(parameters) != 0){
-    char * tmpString = my_strdup(parameters,MYF(MY_WME));
-    My_auto_ptr<char> ap1(tmpString);
-    char * tmpPtr = 0;
-    char * item = strtok_r(tmpString, " ", &tmpPtr);
-    while(item != NULL){
-      if(strcasecmp(item, "-N") == 0)
-	nostart = 1;
-      if(strcasecmp(item, "-I") == 0)
-	initialstart = 1;
-      if(strcasecmp(item, "-A") == 0)
-	abort = 1;
-      item = strtok_r(NULL, " ", &tmpPtr);
+  int nostart= 0;
+  int initialstart= 0;
+  int abort= 0;
+
+  for (; command_pos < command_list.size(); command_pos++)
+  {
+    const char *item= command_list[command_pos].c_str();
+    if (strcasecmp(item, "-N") == 0)
+    {
+      nostart= 1;
+      continue;
+    }
+    if (strcasecmp(item, "-I") == 0)
+    {
+      initialstart= 1;
+      continue;
+    }
+    if (strcasecmp(item, "-A") == 0)
+    {
+      abort= 1;
+      continue;
     }
+    ndbout_c("Invalid option: %s. Expecting -A,-N or -I after RESTART",
+             item);
+    return;
   }
 
-  if(all) {
-    result = ndb_mgm_restart2(m_mgmsrv, 0, NULL, initialstart, nostart, abort);
-  } else {
-    int v[1];
-    v[0] = processId;
-    result = ndb_mgm_restart2(m_mgmsrv, 1, v, initialstart, nostart, abort);
-  }
+  result= ndb_mgm_restart2(m_mgmsrv, no_of_nodes, node_ids,
+                           initialstart, nostart, abort);
   
   if (result <= 0) {
-    ndbout.println("Restart failed.", result);
+    ndbout_c("Restart failed.");
     printError();
-  } else
+  }
+  else
+  {
+    if (node_ids == 0)
+      ndbout_c("NDB Cluster is being restarted.");
+    else
     {
-      if(all)
-	ndbout << "NDB Cluster is being restarted." << endl;
-      else
-	ndbout_c("Node %d is being restarted.", processId);
+      ndbout << "Node";
+      for (int i= 0; i < no_of_nodes; i++)
+        ndbout << " " << node_ids[i];
+      ndbout_c(" is being restarted");
     }
+  }
 }
 
 void

--- 1.86/storage/ndb/src/mgmsrv/MgmtSrvr.cpp	2006-01-27 17:43:28 +01:00
+++ 1.87/storage/ndb/src/mgmsrv/MgmtSrvr.cpp	2006-04-06 18:46:21 +02:00
@@ -281,6 +281,7 @@
   {5027, "System shutdown in progress" },
   {5028, "Node shutdown would cause system crash" },
   {5029, "Only one shutdown at a time is possible via mgm server" },
+  {5031, "Unsupported multi node shutdown. Abort option required." },
   {5060, "Operation not allowed in single user mode." }, 
   {5061, "DB is not in single user mode." },
   {5062, "The specified node is not an API node." },
@@ -301,6 +302,9 @@
   case StopRef::NodeShutdownWouldCauseSystemCrash:
     return 5028;
     break;
+  case StopRef::UnsupportedNodeShutdown:
+    return 5030;
+    break;
   }
   return 4999;
 }
@@ -375,7 +379,8 @@
   _ownReference(0),
   theSignalIdleList(NULL),
   theWaitState(WAIT_SUBSCRIBE_CONF),
-  m_event_listner(this)
+  m_event_listner(this),
+  m_master_node(0)
 {
     
   DBUG_ENTER("MgmtSrvr::MgmtSrvr");
@@ -652,23 +657,16 @@
 
 int MgmtSrvr::okToSendTo(NodeId nodeId, bool unCond) 
 {
-  if(nodeId == 0)
-    return 0;
-
-  if (getNodeType(nodeId) != NDB_MGM_NODE_TYPE_NDB)
+  if(nodeId == 0 || getNodeType(nodeId) != NDB_MGM_NODE_TYPE_NDB)
     return WRONG_PROCESS_TYPE;
-  
   // Check if we have contact with it
   if(unCond){
     if(theFacade->theClusterMgr->getNodeInfo(nodeId).connected)
       return 0;
-    return NO_CONTACT_WITH_PROCESS;
   }
-  if (theFacade->get_node_alive(nodeId) == 0) {
-    return NO_CONTACT_WITH_PROCESS;
-  } else {
+  else if (theFacade->get_node_alive(nodeId) == true)
     return 0;
-  }
+  return NO_CONTACT_WITH_PROCESS;
 }
 
 void report_unknown_signal(SimpleSignal *signal)
@@ -838,7 +836,7 @@
  * is used by Stopping, Restarting and Single user commands
  */
 
-int MgmtSrvr::sendSTOP_REQ(NodeId nodeId,
+int MgmtSrvr::sendSTOP_REQ(const Vector<NodeId> &node_ids,
 			   NodeBitmask &stoppedNodes,
 			   Uint32 singleUserNodeId,
 			   bool abort,
@@ -847,6 +845,12 @@
 			   bool nostart,
 			   bool initialStart)
 {
+  DBUG_ENTER("MgmtSrvr::sendSTOP_REQ");
+  DBUG_PRINT("enter", ("no of nodes: %d  singleUseNodeId: %d  "
+                       "abort: %d  stop: %d  restart: %d  "
+                       "nostart: %d  initialStart: %d",
+                       node_ids.size(), singleUserNodeId,
+                       abort, stop, restart, nostart, initialStart));
   stoppedNodes.clear();
 
   SignalSender ss(theFacade);
@@ -883,20 +887,29 @@
 
   // send the signals
   NodeBitmask nodes;
-  if (nodeId)
+  NodeId nodeId;
+  int use_master_node= 0;
+  int do_send= 0;
+  NdbNodeBitmask nodes_to_stop;
   {
+    for (unsigned i= 0; i < node_ids.size(); i++)
+      nodes_to_stop.set(node_ids[i]);
+  }
+  if (node_ids.size())
+  {
+    do_send= 1;
+    if (node_ids.size() == 1)
+      nodeId= node_ids[0];
+    else // multi node stop, send to master
     {
-      int r;
-      if((r = okToSendTo(nodeId, true)) != 0)
-	return r;
+      use_master_node= 1;
+      nodes_to_stop.copyto(NdbNodeBitmask::Size, stopReq->nodes);
+      StopReq::setStopNodes(stopReq->requestInfo, 1);
     }
-    {
-      if (ss.sendSignal(nodeId, &ssig) != SEND_OK)
-	return SEND_OR_RECEIVE_FAILED;
-    }
-    nodes.set(nodeId);
   }
-  else
+  else // send stop to all one by one
+  {
+    nodeId= 0;
     while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB))
     {
       if(okToSendTo(nodeId, true) == 0)
@@ -906,11 +919,33 @@
 	  nodes.set(nodeId);
       }
     }
-
+  }
   // now wait for the replies
   int error = 0;
-  while (!nodes.isclear())
+  while (!nodes.isclear() || do_send)
   {
+    if (do_send)
+    {
+      int r;
+      assert(nodes.count() == 0);
+      if (use_master_node)
+        nodeId= m_master_node;
+      if ((r= okToSendTo(nodeId, true)) != 0)
+      {
+        bool next;
+        if (!use_master_node)
+          DBUG_RETURN(r);
+        m_master_node= nodeId= 0;
+        while((next= getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true &&
+              (r= okToSendTo(nodeId, true)) != 0);
+        if (!next)
+          DBUG_RETURN(NO_CONTACT_WITH_DB_NODES);
+      }
+      if (ss.sendSignal(nodeId, &ssig) != SEND_OK)
+        DBUG_RETURN(SEND_OR_RECEIVE_FAILED);
+      nodes.set(nodeId);
+      do_send= 0;
+    }
     SimpleSignal *signal = ss.waitFor();
     int gsn = signal->readSignalNumber();
     switch (gsn) {
@@ -922,6 +957,13 @@
 #endif
       assert(nodes.get(nodeId));
       nodes.clear(nodeId);
+      if (ref->errorCode == StopRef::MultiNodeShutdownNotMaster)
+      {
+        assert(use_master_node);
+        m_master_node= ref->masterNodeId;
+        do_send= 1;
+        continue;
+      }
       error = translateStopRef(ref->errorCode);
       break;
     }
@@ -932,9 +974,16 @@
       ndbout_c("Node %d single user mode", nodeId);
 #endif
       assert(nodes.get(nodeId));
-      assert(singleUserNodeId != 0);
+      if (singleUserNodeId != 0)
+      {
+        stoppedNodes.set(nodeId);
+      }
+      else
+      {
+        assert(node_ids.size() > 1);
+        stoppedNodes.bitOR(nodes_to_stop);
+      }
       nodes.clear(nodeId);
-      stoppedNodes.set(nodeId);
       break;
     }
     case GSN_NF_COMPLETEREP:{
@@ -973,27 +1022,31 @@
 #ifdef VM_TRACE
       ndbout_c("Unknown signal %d", gsn);
 #endif
-      return SEND_OR_RECEIVE_FAILED;
+      DBUG_RETURN(SEND_OR_RECEIVE_FAILED);
     }
   }
-  return error;
+  DBUG_RETURN(error);
 }
 
 /*
- * Stop one node
+ * Stop nodes
  */
 
-int MgmtSrvr::stopNode(int nodeId, bool abort)
+int MgmtSrvr::stopNodes(const Vector<NodeId> &node_ids,
+                        int *stopCount, bool abort)
 {
   NodeBitmask nodes;
-  return sendSTOP_REQ(nodeId,
-		      nodes,
-		      0,
-		      abort,
-		      false,
-		      false,
-		      false,
-		      false);
+  int ret= sendSTOP_REQ(node_ids,
+                        nodes,
+                        0,
+                        abort,
+                        false,
+                        false,
+                        false,
+                        false);
+  if (stopCount)
+    *stopCount= nodes.count();
+  return ret;
 }
 
 /*
@@ -1003,7 +1056,8 @@
 int MgmtSrvr::stop(int * stopCount, bool abort)
 {
   NodeBitmask nodes;
-  int ret = sendSTOP_REQ(0,
+  Vector<NodeId> node_ids;
+  int ret = sendSTOP_REQ(node_ids,
 			 nodes,
 			 0,
 			 abort,
@@ -1034,7 +1088,8 @@
       return 5063;
   }
   NodeBitmask nodes;
-  int ret = sendSTOP_REQ(0,
+  Vector<NodeId> node_ids;
+  int ret = sendSTOP_REQ(node_ids,
 			 nodes,
 			 singleUserNodeId,
 			 false,
@@ -1051,18 +1106,22 @@
  * Perform node restart
  */
 
-int MgmtSrvr::restartNode(int nodeId, bool nostart, bool initialStart, 
-			  bool abort)
+int MgmtSrvr::restartNodes(const Vector<NodeId> &node_ids,
+                           int * stopCount, bool nostart,
+                           bool initialStart, bool abort)
 {
   NodeBitmask nodes;
-  return sendSTOP_REQ(nodeId,
-		      nodes,
-		      0,
-		      abort,
-		      false,
-		      true,
-		      nostart,
-		      initialStart);
+  int ret= sendSTOP_REQ(node_ids,
+                        nodes,
+                        0,
+                        abort,
+                        false,
+                        true,
+                        nostart,
+                        initialStart);
+  if (stopCount)
+    *stopCount = nodes.count();
+  return ret;
 }
 
 /*
@@ -1073,7 +1132,8 @@
 		      bool abort, int * stopCount )
 {
   NodeBitmask nodes;
-  int ret = sendSTOP_REQ(0,
+  Vector<NodeId> node_ids;
+  int ret = sendSTOP_REQ(node_ids,
 			 nodes,
 			 0,
 			 abort,
@@ -1719,20 +1779,20 @@
   req->nodeId = free_node_id;
 
   int do_send = 1;
-  NodeId nodeId = 0;
+  NodeId nodeId = m_master_node;
   while (1)
   {
-    if (nodeId == 0)
-    {
-      bool next;
-      while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true &&
-            theFacade->get_node_alive(nodeId) == false);
-      if (!next)
-        return NO_CONTACT_WITH_DB_NODES;
-      do_send = 1;
-    }
     if (do_send)
     {
+      if (okToSendTo(nodeId, false) != 0)
+      {
+        bool next;
+        m_master_node = nodeId = 0;
+        while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true &&
+              okToSendTo(nodeId, false) != 0);
+        if (!next)
+          return NO_CONTACT_WITH_DB_NODES;
+      }
       if (ss.sendSignal(nodeId, &ssig) != SEND_OK) {
         return SEND_OR_RECEIVE_FAILED;
       }
@@ -1757,7 +1817,7 @@
           ref->errorCode == AllocNodeIdRef::Busy)
       {
         do_send = 1;
-        nodeId = refToNode(ref->masterRef);
+        m_master_node = nodeId = refToNode(ref->masterRef);
         continue;
       }
       return ref->errorCode;
@@ -2111,12 +2171,16 @@
   SignalSender ss(theFacade);
   ss.lock(); // lock will be released on exit
 
-  bool next;
-  NodeId nodeId = 0;
-  while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true &&
-	theFacade->get_node_alive(nodeId) == false);
-  
-  if(!next) return NO_CONTACT_WITH_DB_NODES;
+  NodeId nodeId = m_master_node;
+  if (okToSendTo(nodeId, false) != 0)
+  {
+    bool next;
+    nodeId = m_master_node = 0;
+    while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true &&
+          okToSendTo(nodeId, false) != 0);
+    if(!next)
+      return NO_CONTACT_WITH_DB_NODES;
+  }
 
   SimpleSignal ssig;
   BackupReq* req = CAST_PTR(BackupReq, ssig.getDataPtrSend());
@@ -2184,7 +2248,7 @@
       const BackupRef * const ref = 
 	CAST_CONSTPTR(BackupRef, signal->getDataPtr());
       if(ref->errorCode == BackupRef::IAmNotMaster){
-	nodeId = refToNode(ref->masterRef);
+	m_master_node = nodeId = refToNode(ref->masterRef);
 #ifdef VM_TRACE
 	ndbout_c("I'm not master resending to %d", nodeId);
 #endif

--- 1.40/storage/ndb/src/mgmsrv/MgmtSrvr.hpp	2006-01-27 17:43:28 +01:00
+++ 1.41/storage/ndb/src/mgmsrv/MgmtSrvr.hpp	2006-04-06 18:46:21 +02:00
@@ -252,7 +252,7 @@
    *   @param   processId: Id of the DB process to stop
    *   @return  0 if succeeded, otherwise: as stated above, plus:
    */
-  int stopNode(int nodeId, bool abort = false);
+  int stopNodes(const Vector<NodeId> &node_ids, int *stopCount, bool abort);
 
   /**
    *   Stop the system
@@ -286,11 +286,12 @@
  int start(int processId);
 
   /**
-   *   Restart a node
+   *   Restart nodes
    *   @param processId: Id of the DB process to start
    */
-  int restartNode(int processId, bool nostart, bool initialStart, 
-		  bool abort = false);
+  int restartNodes(const Vector<NodeId> &node_ids,
+                   int *stopCount, bool nostart,
+                   bool initialStart, bool abort);
   
   /**
    *   Restart the system
@@ -482,7 +483,7 @@
 
   int send(SignalSender &ss, SimpleSignal &ssig, Uint32 node, Uint32 node_type);
 
-  int sendSTOP_REQ(NodeId nodeId,
+  int sendSTOP_REQ(const Vector<NodeId> &node_ids,
 		   NodeBitmask &stoppedNodes,
 		   Uint32 singleUserNodeId,
 		   bool abort,
@@ -640,6 +641,8 @@
   friend class Ndb_mgmd_event_service;
   Ndb_mgmd_event_service m_event_listner;
   
+  NodeId m_master_node;
+
   /**
    * Handles the thread wich upon a 'Node is started' event will
    * set the node's previous loglevel settings.

--- 1.56/storage/ndb/src/mgmsrv/Services.cpp	2006-01-20 16:13:46 +01:00
+++ 1.57/storage/ndb/src/mgmsrv/Services.cpp	2006-04-06 18:46:22 +02:00
@@ -872,14 +872,11 @@
   }
 
   int restarted = 0;
-  int result = 0;
-
-  for(size_t i = 0; i < nodes.size(); i++)
-    if((result = m_mgmsrv.restartNode(nodes[i],
-				      nostart != 0,
-				      initialstart != 0,
-				      abort != 0)) == 0)
-      restarted++;
+  int result= m_mgmsrv.restartNodes(nodes,
+                                    &restarted,
+                                    nostart != 0,
+                                    initialstart != 0,
+                                    abort != 0);
   
   m_output->println("restart reply");
   if(result != 0){
@@ -1004,7 +1001,12 @@
 
   args.get("node", (const char **)&nodes_str);
   if(nodes_str == NULL)
+  {
+    m_output->println("stop reply");
+    m_output->println("result: empty node list");
+    m_output->println("");
     return;
+  }
   args.get("abort", &abort);
 
   char *p, *last;
@@ -1016,7 +1018,6 @@
 
   int stop_self= 0;
   size_t i;
-
   for(i=0; i < nodes.size(); i++) {
     if (nodes[i] == m_mgmsrv.getOwnNodeId()) {
       stop_self= 1;
@@ -1026,23 +1027,25 @@
 	m_output->println("");
 	return;
       }
+      nodes.erase(i);
+      break;
     }
   }
 
-  int stopped = 0, result = 0;
-  
-  for(i=0; i < nodes.size(); i++)
-    if (nodes[i] != m_mgmsrv.getOwnNodeId()) {
-      if((result = m_mgmsrv.stopNode(nodes[i], abort != 0)) == 0)
-	stopped++;
-    } else
-      stopped++;
+  int stopped= 0;
+  int result= 0;
+  if (nodes.size())
+    result= m_mgmsrv.stopNodes(nodes, &stopped, abort != 0);
 
   m_output->println("stop reply");
   if(result != 0)
     m_output->println("result: %s", get_error_text(result));
   else
+  {
     m_output->println("result: Ok");
+    if (stop_self)
+      stopped++;
+  }
   m_output->println("stopped: %d", stopped);
   m_output->println("");
 
Thread
bk commit into 5.1 tree (tomas:1.2004)tomas6 Apr