List:Commits« Previous MessageNext Message »
From:Magnus Blåudd Date:April 1 2009 11:48am
Subject:bzr commit into mysql-5.1-telco-7.0 branch (magnus.blaudd:2865)
View as plain text  
#At file:///home/msvensson/mysql/tmp/0y7aGkwZ6P/7.0-atrt/ based on revid:jack@stripped4309-3ywt3htkjxd4evef

 2865 Magnus Blåudd	2009-04-01 [merge]
      Merge

    modified:
      storage/ndb/include/mgmapi/mgmapi_error.h
      storage/ndb/include/mgmcommon/ConfigRetriever.hpp
      storage/ndb/src/common/mgmcommon/ConfigRetriever.cpp
      storage/ndb/src/kernel/ndbd.cpp
      storage/ndb/src/kernel/vm/Configuration.cpp
      storage/ndb/src/kernel/vm/Configuration.hpp
      storage/ndb/src/mgmapi/mgmapi.cpp
      storage/ndb/src/mgmapi/mgmapi_error.c
      storage/ndb/src/mgmapi/mgmapi_internal.h
      storage/ndb/src/mgmsrv/Config.cpp
      storage/ndb/src/mgmsrv/Config.hpp
      storage/ndb/src/mgmsrv/ConfigManager.cpp
      storage/ndb/src/mgmsrv/ConfigManager.hpp
      storage/ndb/src/mgmsrv/MgmtSrvr.cpp
      storage/ndb/src/mgmsrv/MgmtSrvr.hpp
      storage/ndb/src/mgmsrv/Services.cpp
      storage/ndb/src/ndbapi/SignalSender.cpp
      storage/ndb/src/ndbapi/SignalSender.hpp
      storage/ndb/src/ndbapi/ndb_cluster_connection.cpp
      storage/ndb/test/ndbapi/testMgm.cpp
=== modified file 'storage/ndb/include/mgmapi/mgmapi_error.h'
--- a/storage/ndb/include/mgmapi/mgmapi_error.h	2008-12-18 09:43:26 +0000
+++ b/storage/ndb/include/mgmapi/mgmapi_error.h	2009-03-26 09:11:40 +0000
@@ -75,6 +75,8 @@ extern "C" {
     /* Service errors - Configuration change */
     /** Unable to start config change */
     NDB_MGM_CONFIG_CHANGE_FAILED = 4011,
+    /** Unable to get configuration */
+    NDB_MGM_GET_CONFIG_FAILED = 4012,
 
     /* Usage errors */
     /** Usage error */

=== modified file 'storage/ndb/include/mgmcommon/ConfigRetriever.hpp'
--- a/storage/ndb/include/mgmcommon/ConfigRetriever.hpp	2009-03-04 10:07:03 +0000
+++ b/storage/ndb/include/mgmcommon/ConfigRetriever.hpp	2009-03-26 08:33:33 +0000
@@ -27,7 +27,7 @@
 class ConfigRetriever {
 public:
   ConfigRetriever(const char * _connect_string,
-		  Uint32 version, Uint32 nodeType,
+                  Uint32 version, ndb_mgm_node_type nodeType,
 		  const char * _bind_address = 0,
                   int timeout_ms = 30000);
   ~ConfigRetriever();
@@ -96,7 +96,7 @@ private:
 
   bool m_end_session;
   Uint32 m_version;
-  Uint32 m_node_type;
+  ndb_mgm_node_type m_node_type;
   NdbMgmHandle m_handle;
 };
 

=== modified file 'storage/ndb/src/common/mgmcommon/ConfigRetriever.cpp'
--- a/storage/ndb/src/common/mgmcommon/ConfigRetriever.cpp	2009-03-05 06:42:20 +0000
+++ b/storage/ndb/src/common/mgmcommon/ConfigRetriever.cpp	2009-03-26 09:11:40 +0000
@@ -23,6 +23,7 @@
 #include <mgmapi.h>
 #include <mgmapi_config_parameters.h>
 #include <mgmapi_configuration.hpp>
+#include <mgmapi_internal.h>
 #include <ConfigValues.hpp>
 
 
@@ -30,7 +31,8 @@
 //****************************************************************************
 
 ConfigRetriever::ConfigRetriever(const char * _connect_string,
-				 Uint32 version, Uint32 node_type,
+				 Uint32 version,
+                                 ndb_mgm_node_type node_type,
 				 const char * _bindaddress,
                                  int timeout_ms) :
   m_end_session(true),
@@ -157,8 +159,10 @@ ConfigRetriever::getConfig(Uint32 nodeid
 ndb_mgm_configuration *
 ConfigRetriever::getConfig(NdbMgmHandle mgm_handle)
 {
-  ndb_mgm_configuration * conf = ndb_mgm_get_configuration(mgm_handle,
-                                                           m_version);
+  ndb_mgm_configuration * conf =
+    ndb_mgm_get_configuration2(mgm_handle,
+                               m_version,
+                               m_node_type);
   if(conf == 0)
   {
     BaseString tmp(ndb_mgm_get_latest_error_msg(mgm_handle));

=== modified file 'storage/ndb/src/kernel/ndbd.cpp'
--- a/storage/ndb/src/kernel/ndbd.cpp	2009-03-18 11:51:30 +0000
+++ b/storage/ndb/src/kernel/ndbd.cpp	2009-04-01 11:47:56 +0000
@@ -73,9 +73,6 @@ systemInfo(const Configuration & config,
   if(logLevel.getLogLevel(LogLevel::llStartUp) > 0){
     g_eventLogger->info("NDB Cluster -- DB node %d", globalData.ownId);
     g_eventLogger->info("%s --", NDB_VERSION_STRING);
-    if (config.get_mgmd_host())
-      g_eventLogger->info("Configuration fetched at %s port %d",
-                          config.get_mgmd_host(), config.get_mgmd_port());
 #ifdef NDB_SOLARIS
     g_eventLogger->info("NDB is running on a machine with %d processor(s) at %d MHz",
                         processor, speed);

=== modified file 'storage/ndb/src/kernel/vm/Configuration.cpp'
--- a/storage/ndb/src/kernel/vm/Configuration.cpp	2009-03-04 10:40:00 +0000
+++ b/storage/ndb/src/kernel/vm/Configuration.cpp	2009-03-26 09:13:22 +0000
@@ -121,10 +121,9 @@ Configuration::fetch_configuration(const
     delete m_config_retriever;
   }
 
-  m_mgmd_port= 0;
   m_config_retriever= new ConfigRetriever(_connect_string,
-					  NDB_VERSION, 
-					  NODE_TYPE_DB,
+                                          NDB_VERSION,
+                                          NDB_MGM_NODE_TYPE_NDB,
 					  _bind_address);
 
   if (m_config_retriever->hasError())
@@ -143,9 +142,6 @@ Configuration::fetch_configuration(const
     */
     ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Could not connect to ndb_mgmd", s);
   }
-  
-  m_mgmd_port= m_config_retriever->get_mgmd_port();
-  m_mgmd_host.assign(m_config_retriever->get_mgmd_host());
 
   ConfigRetriever &cr= *m_config_retriever;
   
@@ -181,7 +177,21 @@ Configuration::fetch_configuration(const
     free(m_clusterConfig);
   
   m_clusterConfig = p;
-  
+
+  {
+    Uint32 generation;
+    ndb_mgm_configuration_iterator sys_iter(*p, CFG_SECTION_SYSTEM);
+    if (sys_iter.get(CFG_SYS_CONFIG_GENERATION, &generation)) {
+      ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG,
+                "Invalid configuration fetched", "generation missing");
+    }
+
+    g_eventLogger->info("Configuration fetched from '%s:%d', generation: %d",
+                        m_config_retriever->get_mgmd_host(),
+                        m_config_retriever->get_mgmd_port(),
+                        generation);
+  }
+
   ndb_mgm_configuration_iterator iter(* p, CFG_SECTION_NODE);
   if (iter.find(CFG_NODE_ID, globalData.ownId)){
     ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Invalid configuration fetched", "DB missing");

=== modified file 'storage/ndb/src/kernel/vm/Configuration.hpp'
--- a/storage/ndb/src/kernel/vm/Configuration.hpp	2009-03-04 10:40:00 +0000
+++ b/storage/ndb/src/kernel/vm/Configuration.hpp	2009-03-26 09:13:22 +0000
@@ -122,8 +122,6 @@ public:
 
   const ndb_mgm_configuration_iterator * getOwnConfigIterator() const;
 
-  Uint32 get_mgmd_port() const {return m_mgmd_port;};
-  const char *get_mgmd_host() const {return m_mgmd_host.c_str();};
   ConfigRetriever* get_config_retriever() { return m_config_retriever; };
 
   class LogLevel * m_logLevel;
@@ -167,8 +165,6 @@ private:
   char * _fsPath;
   char * _backupPath;
   bool _initialStart;
-  Uint32 m_mgmd_port;
-  BaseString m_mgmd_host;
   bool _daemonMode; // if not, angel in foreground
 
   void calcSizeAlt(class ConfigValues * );

=== modified file 'storage/ndb/src/mgmapi/mgmapi.cpp'
--- a/storage/ndb/src/mgmapi/mgmapi.cpp	2008-12-18 10:38:41 +0000
+++ b/storage/ndb/src/mgmapi/mgmapi.cpp	2009-03-26 09:11:40 +0000
@@ -2302,13 +2302,16 @@ ndb_mgm_abort_backup(NdbMgmHandle handle
 
 extern "C"
 struct ndb_mgm_configuration *
-ndb_mgm_get_configuration(NdbMgmHandle handle, unsigned int version) {
+ndb_mgm_get_configuration2(NdbMgmHandle handle, unsigned int version,
+                           enum ndb_mgm_node_type nodetype)
+{
   CHECK_HANDLE(handle, 0);
   SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_get_configuration");
   CHECK_CONNECTED(handle, 0);
 
   Properties args;
   args.put("version", version);
+  args.put("nodetype", nodetype);
 
   const ParserRow<ParserDummy> reply[] = {
     MGM_CMD("get config reply", NULL, ""),
@@ -2324,9 +2327,10 @@ ndb_mgm_get_configuration(NdbMgmHandle h
   CHECK_REPLY(handle, prop, 0);
   
   do {
-    const char * buf;
+    const char * buf = "<unknown error>";
     if(!prop->get("result", &buf) || strcmp(buf, "Ok") != 0){
       fprintf(handle->errstream, "ERROR Message: %s\n\n", buf);
+      SET_ERROR(handle, NDB_MGM_GET_CONFIG_FAILED, buf);
       break;
     }
 
@@ -2401,6 +2405,14 @@ ndb_mgm_get_configuration(NdbMgmHandle h
 }
 
 extern "C"
+struct ndb_mgm_configuration *
+ndb_mgm_get_configuration(NdbMgmHandle handle, unsigned int version)
+{
+  return ndb_mgm_get_configuration2(handle, version,
+                                    NDB_MGM_NODE_TYPE_UNKNOWN);
+}
+
+extern "C"
 void
 ndb_mgm_destroy_configuration(struct ndb_mgm_configuration *cfg)
 {

=== modified file 'storage/ndb/src/mgmapi/mgmapi_error.c'
--- a/storage/ndb/src/mgmapi/mgmapi_error.c	2008-12-18 10:38:41 +0000
+++ b/storage/ndb/src/mgmapi/mgmapi_error.c	2009-03-26 09:11:40 +0000
@@ -46,7 +46,9 @@ const struct Ndb_Mgm_Error_Msg ndb_mgm_e
   /* Service errors - Configuration change */
   { NDB_MGM_CONFIG_CHANGE_FAILED,
     "Failed to complete configuration change" },
-  
+  { NDB_MGM_GET_CONFIG_FAILED,
+    "Failed to get configuration" },
+
   /* Usage errors */
   { NDB_MGM_USAGE_ERROR,
     "Usage error" }

=== modified file 'storage/ndb/src/mgmapi/mgmapi_internal.h'
--- a/storage/ndb/src/mgmapi/mgmapi_internal.h	2008-11-19 13:42:48 +0000
+++ b/storage/ndb/src/mgmapi/mgmapi_internal.h	2009-03-26 09:11:40 +0000
@@ -82,6 +82,19 @@ extern "C" {
 
   NDB_SOCKET_TYPE _ndb_mgm_get_socket(NdbMgmHandle handle);
 
+  /**
+   * Get configuration
+   *
+   * @param   handle    NDB management handle.
+   * @param   version   version of this node
+   * @param   nodetype   type of this node
+   */
+  struct ndb_mgm_configuration *
+  ndb_mgm_get_configuration2(NdbMgmHandle handle,
+                             unsigned version,
+                             enum ndb_mgm_node_type nodetype);
+
+
 #ifdef __cplusplus
 }
 #endif

=== modified file 'storage/ndb/src/mgmsrv/Config.cpp'
--- a/storage/ndb/src/mgmsrv/Config.cpp	2009-03-14 20:42:04 +0000
+++ b/storage/ndb/src/mgmsrv/Config.cpp	2009-03-26 08:31:32 +0000
@@ -777,3 +777,25 @@ void Config::getConnectString(BaseString
   ndbout << connectstring << endl;
 }
 
+
+void
+Config::get_nodemask(NodeBitmask& mask,
+                     ndb_mgm_node_type type) const
+{
+  mask.clear();
+  ConfigIter it(this, CFG_SECTION_NODE);
+  for (; it.valid(); it.next())
+  {
+    Uint32 node_type;
+    require(it.get(CFG_TYPE_OF_SECTION, &node_type) == 0);
+
+    if (type == NDB_MGM_NODE_TYPE_UNKNOWN || // UNKOWN -> add all nodes to mask
+        type == (ndb_mgm_node_type)node_type)
+    {
+      Uint32 nodeid;
+      require(it.get(CFG_NODE_ID, &nodeid) == 0);
+      mask.set(nodeid);
+    }
+  }
+}
+

=== modified file 'storage/ndb/src/mgmsrv/Config.hpp'
--- a/storage/ndb/src/mgmsrv/Config.hpp	2008-12-16 16:30:58 +0000
+++ b/storage/ndb/src/mgmsrv/Config.hpp	2009-03-26 08:31:32 +0000
@@ -16,7 +16,9 @@
 #ifndef Config_H
 #define Config_H
 
+#include <kernel/NodeBitmask.hpp>
 #include "ConfigInfo.hpp"
+#include <mgmapi.h>
 #include <mgmapi_configuration.hpp>
 
 
@@ -113,6 +115,13 @@ public:
   */
   bool equal(const Config*, const unsigned* exclude = NULL) const;
 
+  /*
+    Return bitmask of all defined nodes of a certain type
+    returns all defined nodes by default.
+   */
+  void get_nodemask(NodeBitmask& mask,
+                    ndb_mgm_node_type type = NDB_MGM_NODE_TYPE_UNKNOWN) const;
+
   struct ndb_mgm_configuration * m_configValues;
   struct ndb_mgm_configuration * values(void) const { return m_configValues; };
 

=== modified file 'storage/ndb/src/mgmsrv/ConfigManager.cpp'
--- a/storage/ndb/src/mgmsrv/ConfigManager.cpp	2009-02-23 09:59:06 +0000
+++ b/storage/ndb/src/mgmsrv/ConfigManager.cpp	2009-03-26 09:15:15 +0000
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008 Sun Microsystems, Inc.
+/* Copyright (C) 2008-2009 Sun Microsystems, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
 #include "DirIterator.hpp"
 
 #include <NdbConfig.h>
-
+#include <NdbSleep.h>
 #include <SignalSender.hpp>
 #include <NdbApiSignal.hpp>
 #include <signaldata/NFCompleteRep.hpp>
@@ -41,6 +41,27 @@ _require(bool v, const char* expr, const
 }
 #define require(v)  _require((v), #v, __FILE__, __LINE__)
 
+
+static void
+nodes2str(const NodeBitmask nodes, BaseString& to)
+{
+  unsigned found = 0;
+  const char* delimiter = "";
+  for (int i = 1; i < MAX_NODES; i++)
+  {
+    if (nodes.get(i))
+    {
+      to.appfmt("%s%d", delimiter, i);
+      found++;
+      if (found < nodes.count() - 1)
+        delimiter = ", ";
+      else
+        delimiter = " and ";
+    }
+  }
+}
+
+
 extern "C" const char* opt_connect_str;
 
 ConfigManager::ConfigManager(const MgmtSrvr::MgmtOpts& opts,
@@ -55,7 +76,6 @@ ConfigManager::ConfigManager(const MgmtS
                      NDB_VERSION,
                      NDB_MGM_NODE_TYPE_MGM,
                      opts.bind_address),
-  m_config_change_state(CCS_IDLE),
   m_config_state(CS_UNINITIALIZED),
   m_previous_state(CS_UNINITIALIZED),
   m_config_change_error(ConfigChangeRef::OK),
@@ -315,7 +335,7 @@ ConfigManager::init(void)
 
   if (m_config_retriever.hasError())
   {
-    g_eventLogger->error(m_config_retriever.getErrorString());
+    g_eventLogger->error("%s", m_config_retriever.getErrorString());
     DBUG_RETURN(false);
   }
 
@@ -419,6 +439,9 @@ ConfigManager::init(void)
                           m_opts.mycnf ? "my.cnf" : m_opts.config_filename);
       m_new_config = new Config(conf); // Copy config
       m_config_state = CS_INITIAL;
+
+      if (!init_checkers(m_new_config))
+        DBUG_RETURN(false);
     }
     else
     {
@@ -434,7 +457,6 @@ ConfigManager::init(void)
 
       /* Use the fetched config for now */
       set_config(conf);
-      m_new_config = new Config(conf); // Copy config
 
       if (m_config->getGeneration() == 0)
       {
@@ -443,6 +465,10 @@ ConfigManager::init(void)
                             "Will try to set it when all ndb_mgmd(s) started",
                             m_config->getGeneration(), m_config->getName());
         m_config_state= CS_INITIAL;
+        m_new_config = new Config(conf); // Copy config
+
+        if (!init_checkers(m_new_config))
+          DBUG_RETURN(false);
       }
       else
       {
@@ -615,7 +641,7 @@ ConfigManager::config_ok(const Config* c
   assert(m_node_id);
   if (!m_config_retriever.verifyConfig(conf->m_configValues, m_node_id))
   {
-    g_eventLogger->error(m_config_retriever.getErrorString());
+    g_eventLogger->error("%s", m_config_retriever.getErrorString());
     return false;
   }
 
@@ -869,6 +895,19 @@ ConfigManager::execCONFIG_CHANGE_IMPL_RE
 }
 
 
+void ConfigManager::set_config_change_state(ConfigChangeState::States state)
+{
+  if (state == ConfigChangeState::IDLE)
+  {
+    // Rebuild m_all_mgm so that each node in config is included
+    // new mgm nodes might have been added
+    m_config->get_nodemask(m_all_mgm, NDB_MGM_NODE_TYPE_MGM);
+  }
+
+  m_config_change_state.m_current_state = state;
+}
+
+
 void
 ConfigManager::execCONFIG_CHANGE_IMPL_REF(SignalSender& ss, SimpleSignal* sig)
 {
@@ -886,9 +925,9 @@ ConfigManager::execCONFIG_CHANGE_IMPL_RE
 
   switch(m_config_change_state){
 
-  case CCS_PREPARING:{
+  case ConfigChangeState::PREPARING:{
     /* Got ref while preparing */
-    m_config_change_state = CCS_ABORT;
+    set_config_change_state(ConfigChangeState::ABORT);
     m_waiting_for.clear(nodeId);
     if (!m_waiting_for.isclear())
       return;
@@ -907,18 +946,18 @@ ConfigManager::execCONFIG_CHANGE_IMPL_RE
                                   GSN_CONFIG_CHANGE_IMPL_REQ,
                                   ConfigChangeImplReq::SignalLength);
     if (m_waiting_for.isclear())
-      m_config_change_state = CCS_IDLE;
+      set_config_change_state(ConfigChangeState::IDLE);
     else
-      m_config_change_state = CCS_ABORTING;
+      set_config_change_state(ConfigChangeState::ABORTING);
     break;
   }
 
-  case CCS_COMITTING:
+  case ConfigChangeState::COMITTING:
     /* Got ref while comitting, impossible */
     abort();
     break;
 
-  case CCS_ABORT:{
+  case ConfigChangeState::ABORT:{
     /* Got ref(another) while already decided to abort */
     m_waiting_for.clear(nodeId);
     if (!m_waiting_for.isclear())
@@ -938,13 +977,13 @@ ConfigManager::execCONFIG_CHANGE_IMPL_RE
                                   GSN_CONFIG_CHANGE_IMPL_REQ,
                                   ConfigChangeImplReq::SignalLength);
     if (m_waiting_for.isclear())
-      m_config_change_state = CCS_IDLE;
+      set_config_change_state(ConfigChangeState::IDLE);
     else
-      m_config_change_state = CCS_ABORTING;
+      set_config_change_state(ConfigChangeState::ABORTING);
     break;
   }
 
-  case CCS_ABORTING:
+  case ConfigChangeState::ABORTING:
     /* Got ref while aborting, impossible */
     abort();
     break;
@@ -966,7 +1005,7 @@ ConfigManager::execCONFIG_CHANGE_IMPL_CO
   g_eventLogger->debug("Got CONFIG_CHANGE_IMPL_CONF from node %d", nodeId);
 
   switch(m_config_change_state){
-  case CCS_PREPARING:{
+  case ConfigChangeState::PREPARING:{
     require(conf->requestType == ConfigChangeImplReq::Prepare);
     m_waiting_for.clear(nodeId);
     if (!m_waiting_for.isclear())
@@ -986,13 +1025,13 @@ ConfigManager::execCONFIG_CHANGE_IMPL_CO
                                   GSN_CONFIG_CHANGE_IMPL_REQ,
                                   ConfigChangeImplReq::SignalLength);
     if (m_waiting_for.isclear())
-      m_config_change_state = CCS_IDLE;
+      set_config_change_state(ConfigChangeState::IDLE);
     else
-      m_config_change_state = CCS_COMITTING;
+      set_config_change_state(ConfigChangeState::COMITTING);
     break;
   }
 
-  case CCS_COMITTING:{
+  case ConfigChangeState::COMITTING:{
     require(conf->requestType == ConfigChangeImplReq::Commit);
 
     m_waiting_for.clear(nodeId);
@@ -1012,11 +1051,11 @@ ConfigManager::execCONFIG_CHANGE_IMPL_CO
       sendConfigChangeConf(ss, m_client_ref);
     }
     m_client_ref = RNIL;
-    m_config_change_state = CCS_IDLE;
+    set_config_change_state(ConfigChangeState::IDLE);
     break;
   }
 
-  case CCS_ABORT:{
+  case ConfigChangeState::ABORT:{
     m_waiting_for.clear(nodeId);
     if (!m_waiting_for.isclear())
       return;
@@ -1034,13 +1073,13 @@ ConfigManager::execCONFIG_CHANGE_IMPL_CO
                                   GSN_CONFIG_CHANGE_IMPL_REQ,
                                   ConfigChangeImplReq::SignalLength);
     if (m_waiting_for.isclear())
-        m_config_change_state = CCS_IDLE;
+      set_config_change_state(ConfigChangeState::IDLE);
     else
-      m_config_change_state = CCS_ABORTING;
+      set_config_change_state(ConfigChangeState::ABORTING);
     break;
   }
 
-  case CCS_ABORTING:{
+  case ConfigChangeState::ABORTING:{
     m_waiting_for.clear(nodeId);
     if (!m_waiting_for.isclear())
       return;
@@ -1063,7 +1102,7 @@ ConfigManager::execCONFIG_CHANGE_IMPL_CO
     }
     m_config_change_error= ConfigChangeRef::OK;
     m_client_ref = RNIL;
-    m_config_change_state = CCS_IDLE;
+    set_config_change_state(ConfigChangeState::IDLE);
     break;
   }
 
@@ -1160,7 +1199,7 @@ ConfigManager::sendConfigChangeImplReq(S
   req->length = buf.length();
 
   require(m_waiting_for.isclear());
-  require(m_config_change_state == CCS_IDLE);
+  require(m_config_change_state == ConfigChangeState::IDLE);
 
   g_eventLogger->debug("Sending CONFIG_CHANGE_IMPL_REQ(prepare)");
   unsigned i = 0;
@@ -1192,7 +1231,7 @@ ConfigManager::sendConfigChangeImplReq(S
       // Some nodes got prepare, set state to
       // abort and continue abort when result
       // of prepare arrives
-      m_config_change_state = CCS_ABORT;
+      set_config_change_state(ConfigChangeState::ABORT);
       return false;
     }
 
@@ -1202,7 +1241,7 @@ ConfigManager::sendConfigChangeImplReq(S
 
   // Prepare has been sent to all mgm nodes
   // continue and wait for prepare conf(s)
-  m_config_change_state = CCS_PREPARING;
+  set_config_change_state(ConfigChangeState::PREPARING);
   return true;
 
 }
@@ -1230,7 +1269,7 @@ ConfigManager::execCONFIG_CHANGE_REQ(Sig
     return;
   }
 
-  if (m_config_change_state != CCS_IDLE)
+  if (m_config_change_state != ConfigChangeState::IDLE)
   {
     sendConfigChangeRef(ss, from, ConfigChangeRef::ConfigChangeOnGoing);
     return;
@@ -1470,14 +1509,17 @@ ConfigManager::run()
   SignalSender ss(m_facade, MGM_CONFIG_MAN);
   ss.lock();
 
-  ss.getNodes(m_all_mgm, NodeInfo::MGM);
+  // Build bitmaks of all mgm nodes in config
+  m_config->get_nodemask(m_all_mgm, NDB_MGM_NODE_TYPE_MGM);
 
   m_started.set(m_facade->ownId());
 
+  start_checkers();
+
   while (!is_stopped())
   {
 
-    if (m_config_change_state == CCS_IDLE)
+    if (m_config_change_state == ConfigChangeState::IDLE)
     {
       bool print_state = false;
       if (m_previous_state != m_config_state)
@@ -1543,8 +1585,9 @@ ConfigManager::run()
         not_checked.bitANDC(m_checked);
         sendConfigCheckReq(ss, not_checked);
       }
-    }
 
+      handle_exclude_nodes();
+    }
 
     SimpleSignal *sig = ss.waitFor((Uint32)1000);
     if (!sig)
@@ -1581,7 +1624,7 @@ ConfigManager::run()
       m_checked.clear(nodeId);
       m_defragger.node_failed(nodeId);
 
-      if (m_config_change_state != CCS_IDLE)
+      if (m_config_change_state != ConfigChangeState::IDLE)
       {
         g_eventLogger->info("Node %d failed during config change!!",
                             nodeId);
@@ -1636,6 +1679,7 @@ ConfigManager::run()
       break;
     }
   }
+  stop_checkers();
 }
 
 
@@ -1719,15 +1763,21 @@ ConfigManager::fetch_config(void)
                            "returned!");
       abort();
     }
-    g_eventLogger->info("Connected...");
+    g_eventLogger->info("Connected to '%s:%d'...",
+                        m_config_retriever.get_mgmd_host(),
+                        m_config_retriever.get_mgmd_port());
 
   }
 
   // read config from other management server
   ndb_mgm_configuration * tmp =
     m_config_retriever.getConfig(m_config_retriever.get_mgmHandle());
+
+  // Disconnect from other mgmd
+  m_config_retriever.disconnect();
+
   if (tmp == NULL) {
-    g_eventLogger->error(m_config_retriever.getErrorString());
+    g_eventLogger->error("%s", m_config_retriever.getErrorString());
     DBUG_RETURN(false);
   }
 
@@ -1898,18 +1948,229 @@ ConfigManager::load_saved_config(const B
 
 
 bool
-ConfigManager::get_packed_config(UtilBuffer& pack_buf)
+ConfigManager::get_packed_config(ndb_mgm_node_type nodetype,
+                                 BaseString& buf64, BaseString& error)
 {
   Guard g(m_config_mutex);
 
-  /* Only allow the config to be exported if it's been confirmed */
-  if (m_config_state != CS_CONFIRMED)
-    return false;
+  /*
+    Only allow the config to be exported if it's been confirmed
+    or if another mgmd is asking for it
+  */
+  switch(m_config_state)
+  {
+  case CS_INITIAL:
+    if (nodetype == NDB_MGM_NODE_TYPE_MGM)
+      ; // allow other mgmd to fetch initial configuration
+    else
+    {
+      NodeBitmask not_started(m_all_mgm);
+      not_started.bitANDC(m_started);
+
+      error.assign("The cluster configuration is not yet confirmed "
+                   "by all defined management servers. "
+                   "This management server is still waiting for node ");
+      nodes2str(not_started, error);
+      error.append(" to connect.");
+      return false;
+    }
+    break;
+
+  case CS_CONFIRMED:
+    // OK
+    break;
+
+  default:
+    error.assign("get_packed_config, unknown config state: %d",
+                 m_config_state);
+     return false;
+    break;
+
+  }
 
   require(m_config);
-  return m_config->pack(pack_buf);
+  return m_config->pack64(buf64);
+}
+
+
+bool
+ConfigManager::init_checkers(const Config* config)
+{
+
+  // Init one thread for each other mgmd
+  // in the config and check which version it has. If version
+  // does not have config manager, set this node to ignore
+  // that node in the config change protocol
+
+  BaseString connect_string;
+  ConfigIter iter(config, CFG_SECTION_NODE);
+  for (iter.first(); iter.valid(); iter.next())
+  {
+
+    // Only MGM nodes
+    Uint32 type;
+    if (iter.get(CFG_TYPE_OF_SECTION, &type) ||
+        type != NODE_TYPE_MGM)
+      continue;
+
+    // Not this node
+    Uint32 nodeid;
+    if(iter.get(CFG_NODE_ID, &nodeid) ||
+       nodeid == m_node_id)
+      continue;
+
+    const char* hostname;
+    Uint32 port;
+    require(!iter.get(CFG_NODE_HOST, &hostname));
+    require(!iter.get(CFG_MGM_PORT, &port));
+    connect_string.assfmt("%s:%u",hostname,port);
+
+    ConfigChecker* checker =
+      new ConfigChecker(*this, connect_string.c_str(),
+                        m_opts.bind_address, nodeid);
+    if (!checker)
+    {
+      g_eventLogger->error("Failed to create ConfigChecker");
+      return false;
+    }
+
+    if (!checker->init())
+      return false;
+
+    m_checkers.push_back(checker);
+  }
+  return true;
+}
+
+
+void
+ConfigManager::start_checkers(void)
+{
+  for (unsigned i = 0; i < m_checkers.size(); i++)
+    m_checkers[i]->start();
+}
+
+
+void
+ConfigManager::stop_checkers(void)
+{
+  for (unsigned i = 0; i < m_checkers.size(); i++)
+  {
+    ConfigChecker* checker = m_checkers[i];
+    ndbout << "stop checker " << i << endl;
+    checker->stop();
+    delete checker;
+  }
+}
+
+
+ConfigManager::ConfigChecker::ConfigChecker(ConfigManager& manager,
+                                            const char* connect_string,
+                                            const char * bindaddress,
+                                            NodeId nodeid) :
+  MgmtThread("ConfigChecker"),
+  m_manager(manager),
+  m_config_retriever(connect_string, NDB_VERSION,
+                     NDB_MGM_NODE_TYPE_MGM, bindaddress),
+  m_connect_string(connect_string),
+  m_nodeid(nodeid)
+{
+}
+
+
+bool
+ConfigManager::ConfigChecker::init()
+{
+  if (m_config_retriever.hasError())
+  {
+    g_eventLogger->error("%s", m_config_retriever.getErrorString());
+    return false;
+  }
+
+  return true;
+}
+
+
+void
+ConfigManager::ConfigChecker::run()
+{
+  // Connect to other mgmd inifintely until thread is stopped
+  // or connect suceeds
+  g_eventLogger->debug("ConfigChecker, connecting to '%s'",
+                       m_connect_string.c_str());
+  while(m_config_retriever.do_connect(0 /* retry */,
+                                      1 /* delay */,
+                                      0 /* verbose */) != 0)
+  {
+    if (is_stopped())
+    {
+      g_eventLogger->debug("ConfigChecker, thread is stopped");
+      return; // Thread is stopped
+    }
+
+    NdbSleep_SecSleep(1);
+  }
+
+  // Connected
+  g_eventLogger->debug("ConfigChecker, connected to '%s'",
+                       m_connect_string.c_str());
+
+  // Check version
+  int major, minor, build;
+  char ver_str[50];
+  if (!ndb_mgm_get_version(m_config_retriever.get_mgmHandle(),
+                           &major, &minor, &build,
+                           sizeof(ver_str), ver_str))
+  {
+    g_eventLogger->error("Could not get version from mgmd on '%s'",
+                         m_connect_string.c_str());
+    return;
+  }
+  g_eventLogger->debug("mgmd on '%s' has version %d.%d.%d",
+                       m_connect_string.c_str(), major, minor, build);
+
+  // Versions prior to 7 don't have ConfigManager
+  // exclude it from config change protocol
+  if (major < 7)
+  {
+    g_eventLogger->info("Excluding node %d with version %d.%d.%d from "
+                        "config change protocol",
+                        m_nodeid, major, minor, build);
+    m_manager.m_exclude_nodes.push_back(m_nodeid);
+  }
+
+  return;
+}
+
+
+void
+ConfigManager::handle_exclude_nodes(void)
+{
+
+  if (!m_waiting_for.isclear())
+    return; // Other things going on
+
+  switch (m_config_state)
+  {
+  case CS_INITIAL:
+    m_exclude_nodes.lock();
+    for (unsigned i = 0; i < m_exclude_nodes.size(); i++)
+    {
+      NodeId nodeid = m_exclude_nodes[i];
+      g_eventLogger->debug("Handle exclusion of node %d", nodeid);
+      m_all_mgm.clear(nodeid);
+    }
+    m_exclude_nodes.unlock();
+    break;
+
+  default:
+    break;
+  }
+  m_exclude_nodes.clear();
+
 }
 
 
 template class Vector<ConfigSubscriber*>;
+template class Vector<ConfigManager::ConfigChecker*>;
 

=== modified file 'storage/ndb/src/mgmsrv/ConfigManager.hpp'
--- a/storage/ndb/src/mgmsrv/ConfigManager.hpp	2009-02-23 09:59:06 +0000
+++ b/storage/ndb/src/mgmsrv/ConfigManager.hpp	2009-03-26 09:11:40 +0000
@@ -39,14 +39,23 @@ class ConfigManager : public MgmtThread 
 
   ConfigRetriever m_config_retriever;
 
-  enum ConfigChangeState {
-    CCS_IDLE,
-    CCS_PREPARING,
-    CCS_COMITTING,
-    CCS_ABORT,
-    CCS_ABORTING
+  struct ConfigChangeState {
+    enum States {
+      IDLE,
+      PREPARING,
+      COMITTING,
+      ABORT,
+      ABORTING
+    } m_current_state;
+
+    ConfigChangeState() :
+      m_current_state(IDLE) {}
+
+    operator int() const { return m_current_state; }
   } m_config_change_state;
 
+  void set_config_change_state(ConfigChangeState::States state);
+
   enum ConfigState {
     CS_UNINITIALIZED,
 
@@ -139,6 +148,32 @@ class ConfigManager : public MgmtThread 
                           Uint32, Uint32, ConfigState, ConfigState) const;
   void sendConfigCheckConf(SignalSender& ss, BlockReference to) const;
 
+  /*
+    ConfigChecker - for connecting to other mgm nodes without
+    transporter
+  */
+  class ConfigChecker : public MgmtThread {
+    ConfigManager& m_manager;
+    ConfigRetriever m_config_retriever;
+    BaseString m_connect_string;
+    NodeId m_nodeid;
+  public:
+    ConfigChecker(); // Not implemented
+    ConfigChecker(const ConfigChecker&); // Not implemented
+    ConfigChecker(ConfigManager& manager,
+                  const char* connect_string,
+                  const char* bind_address,
+                  NodeId nodeid);
+    bool init();
+    virtual void run();
+  };
+  bool init_checkers(const Config* config);
+  void start_checkers();
+  void stop_checkers();
+  Vector<ConfigChecker*> m_checkers;
+  MutexVector<NodeId> m_exclude_nodes;
+  void handle_exclude_nodes(void);
+
 public:
   ConfigManager(const MgmtSrvr::MgmtOpts&,
                 const char* configdir);
@@ -155,9 +190,10 @@ public:
   int add_config_change_subscriber(ConfigSubscriber*);
 
   /*
-    Retrieve the current configuration in packed format
+    Retrieve the current configuration in base64 packed format
    */
-  bool get_packed_config(UtilBuffer& pack_buf);
+  bool get_packed_config(ndb_mgm_node_type nodetype,
+                         BaseString& buf64, BaseString& error);
 
   static Config* load_config(const char* config_filename, bool mycnf,
                              BaseString& msg);

=== modified file 'storage/ndb/src/mgmsrv/MgmtSrvr.cpp'
--- a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp	2009-04-01 08:42:02 +0000
+++ b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp	2009-04-01 11:47:56 +0000
@@ -795,9 +795,10 @@ MgmtSrvr::config_changed(NodeId node_id,
 
 
 bool
-MgmtSrvr::getPackedConfig(UtilBuffer& pack_buf)
+MgmtSrvr::get_packed_config(ndb_mgm_node_type node_type,
+                            BaseString& buf64, BaseString& error)
 {
-  return m_config_manager->get_packed_config(pack_buf);
+  return m_config_manager->get_packed_config(node_type, buf64, error);
 }
 
 
@@ -3969,7 +3970,7 @@ MgmtSrvr::change_config(Config& new_conf
   req->length = buf.length();
 
   NodeBitmask mgm_nodes;
-  ss.getNodes(mgm_nodes, NodeInfo::MGM);
+  m_local_config->get_nodemask(mgm_nodes, NDB_MGM_NODE_TYPE_MGM);
 
   NodeId nodeId= ss.find_confirmed_node(mgm_nodes);
   if (nodeId == 0)

=== modified file 'storage/ndb/src/mgmsrv/MgmtSrvr.hpp'
--- a/storage/ndb/src/mgmsrv/MgmtSrvr.hpp	2009-04-01 08:42:02 +0000
+++ b/storage/ndb/src/mgmsrv/MgmtSrvr.hpp	2009-04-01 11:47:56 +0000
@@ -354,11 +354,6 @@ public:
   bool change_config(Config& new_config, BaseString& msg);
 
   /**
-   *
-   */
-  enum ndb_mgm_node_type getNodeType(NodeId) const;
-
-  /**
    *   Get error text
    * 
    *   @param   errorCode: Error code to get a match error text for.
@@ -528,6 +523,8 @@ private:
   
   NodeId m_master_node;
 
+  ndb_mgm_node_type getNodeType(NodeId) const;
+
   /**
    * Handles the thread wich upon a 'Node is started' event will
    * set the node's previous loglevel settings.
@@ -539,10 +536,9 @@ private:
 
 
 public:
-  /*
-    Get packed copy of configuration in the supplied buffer
-  */
-  bool getPackedConfig(UtilBuffer& pack_buf);
+  /* Get copy of configuration packed with base64 */
+  bool get_packed_config(ndb_mgm_node_type nodetype,
+                         BaseString& buf64, BaseString& error);
 
   void print_config(const char* section_filter = NULL,
                     NodeId nodeid_filter = 0,

=== modified file 'storage/ndb/src/mgmsrv/Services.cpp'
--- a/storage/ndb/src/mgmsrv/Services.cpp	2009-04-01 08:42:02 +0000
+++ b/storage/ndb/src/mgmsrv/Services.cpp	2009-04-01 11:47:56 +0000
@@ -123,6 +123,7 @@ ParserRow<MgmApiSession> commands[] = {
   MGM_CMD("get config", &MgmApiSession::getConfig, ""),
     MGM_ARG("version", Int, Mandatory, "Configuration version number"),
     MGM_ARG("node", Int, Optional, "Node ID"),
+    MGM_ARG("nodetype", Int, Optional, "Type of requesting node"),
 
   MGM_CMD("get nodeid", &MgmApiSession::get_nodeid, ""),
     MGM_ARG("version", Int, Mandatory, "Configuration version number"),
@@ -586,69 +587,42 @@ void
 MgmApiSession::getConfig(Parser_t::Context &,
                          const class Properties &args)
 {
-  Uint32 version, node = 0;
+  Uint32 nodetype = NDB_MGM_NODE_TYPE_UNKNOWN;
 
-  args.get("version", &version);
-  args.get("node", &node);
+  // Ignoring mandatory parameter "version"
+  // Ignoring optional parameter "node"
+  args.get("nodetype", &nodetype);
 
-  if(node != 0){
-    bool compatible;
-    switch (m_mgmsrv.getNodeType(node)) {
-    case NDB_MGM_NODE_TYPE_NDB:
-      compatible = ndbCompatible_mgmt_ndb(NDB_VERSION, version);
-      break;
-    case NDB_MGM_NODE_TYPE_API:
-    case NDB_MGM_NODE_TYPE_MGM:
-      compatible = ndbCompatible_mgmt_api(NDB_VERSION, version);
-      break;
-    default:
-      m_output->println("get config");
-      m_output->println("result: unrecognignized node type");
-      m_output->println("");
-      return;
-    }
-    
-    if (!compatible){
-      m_output->println("get config");
-      m_output->println("result: incompatible version mgmt 0x%x and node 0x%x",
-			NDB_VERSION, version);
-      m_output->println("");
-      return;
-    }
-  }  
+  SLEEP_ERROR_INSERTED(1);
+  m_output->println("get config reply");
+
+  BaseString pack64, error;
 
   UtilBuffer packed;
-  if (!m_mgmsrv.getPackedConfig(packed))
+  if (!m_mgmsrv.get_packed_config((ndb_mgm_node_type)nodetype,
+                                  pack64, error))
   {
-    m_output->println("get config reply");
-    m_output->println("result: Could not fetch configuration");
+    m_output->println("result: %s", error.c_str());
     m_output->println("");
     return;
   }
 
-  char *tmp_str =
-    (char *) malloc(base64_needed_encoded_length(packed.length()));
-  (void) base64_encode(packed.get_data(), packed.length(), tmp_str);
-
-  SLEEP_ERROR_INSERTED(1);
-
-  m_output->println("get config reply");
   m_output->println("result: Ok");
-  m_output->println("Content-Length: %ld", strlen(tmp_str));
+  m_output->println("Content-Length: %ld", pack64.length());
   m_output->println("Content-Type: ndbconfig/octet-stream");
   SLEEP_ERROR_INSERTED(2);
   m_output->println("Content-Transfer-Encoding: base64");
-  m_output->println("");
+  m_output->print("\n");
+
   if(ERROR_INSERTED(3))
   {
-    int l= strlen(tmp_str);
-    tmp_str[l/2]='\0';
-    m_output->println(tmp_str);
-    NdbSleep_SecSleep(10);
+    // Return only half the packed config
+    BaseString half64 = pack64.substr(0, pack64.length());
+    m_output->println(half64.c_str());
+    return;
   }
-  m_output->println(tmp_str);
-
-  free(tmp_str);
+  m_output->println(pack64.c_str());
+  m_output->print("\n");
   return;
 }
 

=== modified file 'storage/ndb/src/ndbapi/SignalSender.cpp'
--- a/storage/ndb/src/ndbapi/SignalSender.cpp	2009-02-23 09:59:06 +0000
+++ b/storage/ndb/src/ndbapi/SignalSender.cpp	2009-03-26 08:31:32 +0000
@@ -138,25 +138,6 @@ SignalSender::getNoOfConnectedNodes() co
 }
 
 
-void
-SignalSender::getNodes(NodeBitmask& mask,
-                       NodeInfo::NodeType type)
-{
-  mask.clear();
-  for(Uint32 i = 1; i < MAX_NODES; i++)
-  {
-    const ClusterMgr::Node& node= getNodeInfo(i);
-    if(!node.defined)
-      continue;
-    if(type == NodeInfo::INVALID || // INVALID -> add all nodes to mask
-       node.m_info.getType() == type)
-    {
-      mask.set(i);
-    }
-  }
-}
-
-
 NodeBitmask
 SignalSender::broadcastSignal(NodeBitmask mask,
                               SimpleSignal& sig,

=== modified file 'storage/ndb/src/ndbapi/SignalSender.hpp'
--- a/storage/ndb/src/ndbapi/SignalSender.hpp	2009-02-23 09:59:06 +0000
+++ b/storage/ndb/src/ndbapi/SignalSender.hpp	2009-03-26 08:31:32 +0000
@@ -68,13 +68,6 @@ public:
   const ClusterMgr::Node &getNodeInfo(Uint16 nodeId) const;
   Uint32 getNoOfConnectedNodes() const;
 
-  /*
-    Return bitmask of all defined nodes of a certain type
-    returns all defined nodes by default.
-   */
-  void getNodes(NodeBitmask& mask,
-                NodeInfo::NodeType type = NodeInfo::INVALID);
-
   NodeId find_confirmed_node(const NodeBitmask& mask);
   NodeId find_connected_node(const NodeBitmask& mask);
   NodeId find_alive_node(const NodeBitmask& mask);

=== modified file 'storage/ndb/src/ndbapi/ndb_cluster_connection.cpp'
--- a/storage/ndb/src/ndbapi/ndb_cluster_connection.cpp	2009-03-14 20:42:04 +0000
+++ b/storage/ndb/src/ndbapi/ndb_cluster_connection.cpp	2009-03-26 08:33:33 +0000
@@ -353,7 +353,7 @@ Ndb_cluster_connection_impl(const char *
     ndb_print_state_mutex= NdbMutex_Create();
 #endif
   m_config_retriever=
-    new ConfigRetriever(connect_string, NDB_VERSION, NODE_TYPE_API);
+    new ConfigRetriever(connect_string, NDB_VERSION, NDB_MGM_NODE_TYPE_API);
   if (m_config_retriever->hasError())
   {
     m_latest_error= 1;

=== modified file 'storage/ndb/test/ndbapi/testMgm.cpp'
--- a/storage/ndb/test/ndbapi/testMgm.cpp	2009-04-01 08:42:02 +0000
+++ b/storage/ndb/test/ndbapi/testMgm.cpp	2009-04-01 11:47:56 +0000
@@ -641,13 +641,21 @@ int runSetConfig(NDBT_Context* ctx, NDBT
     struct ndb_mgm_configuration* conf=
       ndb_mgm_get_configuration(mgmd.handle(), 0);
     if (!conf)
+    {
+      g_err << "ndb_mgm_get_configuration failed, error: "
+            << ndb_mgm_get_latest_error_msg(mgmd.handle()) << endl;
       return NDBT_FAILED;
+    }
 
     int r= ndb_mgm_set_configuration(mgmd.handle(), conf);
     free(conf);
 
     if (r != 0)
+    {
+      g_err << "ndb_mgm_set_configuration failed, error: "
+            << ndb_mgm_get_latest_error_msg(mgmd.handle()) << endl;
       return NDBT_FAILED;
+    }
   }
   return NDBT_OK;
 }
@@ -1595,10 +1603,12 @@ int runTestReloadConfig(NDBT_Context* ct
   if (!show_variables(mgmd, variables))
     return NDBT_FAILED;
 
+  variables.print();
+
   const char* mycnf_str;
   if (!variables.get("mycnf", &mycnf_str))
     abort();
-  bool uses_mycnf = strcmp(mycnf_str, "1");
+  bool uses_mycnf = (strcmp(mycnf_str, "yes") == 0);
 
   int result= NDBT_FAILED;
   if (

Attachment: [text/bzr-bundle] bzr/magnus.blaudd@sun.com-20090401114756-trlmn310xod5veuv.bundle
Thread
bzr commit into mysql-5.1-telco-7.0 branch (magnus.blaudd:2865)Magnus Blåudd1 Apr