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

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #include <ndb_global.h>
  14. #include <ndb_version.h>
  15. #include <ConfigRetriever.hpp>
  16. #include <SocketServer.hpp>
  17. #include <NdbSleep.h>
  18. #include <NdbOut.hpp>
  19. #include <NdbTCP.h>
  20. #include <NdbEnv.h>
  21. #include "MgmtErrorReporter.hpp"
  22. #include <uucode.h>
  23. #include <Properties.hpp>
  24. #include <socket_io.h>
  25. #include <NdbConfig.h>
  26. #include <NdbAutoPtr.hpp>
  27.  
  28. #include <mgmapi.h>
  29. #include <mgmapi_config_parameters.h>
  30. #include <mgmapi_configuration.hpp>
  31. #include <ConfigValues.hpp>
  32. #include <NdbHost.h>
  33. //****************************************************************************
  34. //****************************************************************************
  35. ConfigRetriever::ConfigRetriever(const char * _connect_string,
  36.  Uint32 version, Uint32 node_type)
  37. {
  38.   DBUG_ENTER("ConfigRetriever::ConfigRetriever");
  39.   m_version = version;
  40.   m_node_type = node_type;
  41.   _ownNodeId= 0;
  42.   m_handle= ndb_mgm_create_handle();
  43.   if (m_handle == 0) {
  44.     setError(CR_ERROR, "Unable to allocate mgm handle");
  45.     DBUG_VOID_RETURN;
  46.   }
  47.   if (ndb_mgm_set_connectstring(m_handle, _connect_string))
  48.   {
  49.     setError(CR_ERROR, ndb_mgm_get_latest_error_desc(m_handle));
  50.     DBUG_VOID_RETURN;
  51.   }
  52.   resetError();
  53.   DBUG_VOID_RETURN;
  54. }
  55. ConfigRetriever::~ConfigRetriever()
  56. {
  57.   DBUG_ENTER("ConfigRetriever::~ConfigRetriever");
  58.   if (m_handle) {
  59.     ndb_mgm_disconnect(m_handle);
  60.     ndb_mgm_destroy_handle(&m_handle);
  61.   }
  62.   DBUG_VOID_RETURN;
  63. }
  64. Uint32 
  65. ConfigRetriever::get_configuration_nodeid() const
  66. {
  67.   return ndb_mgm_get_configuration_nodeid(m_handle);
  68. }
  69. Uint32 ConfigRetriever::get_mgmd_port() const
  70. {
  71.   return ndb_mgm_get_connected_port(m_handle);
  72. }
  73. const char *ConfigRetriever::get_mgmd_host() const
  74. {
  75.   return ndb_mgm_get_connected_host(m_handle);
  76. }
  77. const char *ConfigRetriever::get_connectstring(char *buf, int buf_sz) const
  78. {
  79.   return ndb_mgm_get_connectstring(m_handle, buf, buf_sz);
  80. }
  81. //****************************************************************************
  82. //****************************************************************************
  83.  
  84. int
  85. ConfigRetriever::do_connect(int no_retries,
  86.     int retry_delay_in_seconds, int verbose)
  87. {
  88.   return
  89.     (ndb_mgm_connect(m_handle,no_retries,retry_delay_in_seconds,verbose)==0) ?
  90.     0 : -1;
  91. }
  92. //****************************************************************************
  93. //****************************************************************************
  94. //****************************************************************************
  95. //****************************************************************************
  96. struct ndb_mgm_configuration*
  97. ConfigRetriever::getConfig() {
  98.   struct ndb_mgm_configuration * p = 0;
  99.   if(m_handle != 0)
  100.     p = getConfig(m_handle);
  101.   if(p == 0)
  102.     return 0;
  103.   
  104.   if(!verifyConfig(p, _ownNodeId)){
  105.     free(p);
  106.     p= 0;
  107.   }
  108.   
  109.   return p;
  110. }
  111. ndb_mgm_configuration *
  112. ConfigRetriever::getConfig(NdbMgmHandle m_handle)
  113. {
  114.   ndb_mgm_configuration * conf = ndb_mgm_get_configuration(m_handle,m_version);
  115.   if(conf == 0)
  116.   {
  117.     setError(CR_ERROR, ndb_mgm_get_latest_error_desc(m_handle));
  118.     return 0;
  119.   }
  120.   return conf;
  121. }
  122. ndb_mgm_configuration *
  123. ConfigRetriever::getConfig(const char * filename){
  124. #ifndef NDB_WIN32
  125.   struct stat sbuf;
  126.   const int res = stat(filename, &sbuf);
  127.   if(res != 0){
  128.     char buf[255];
  129.     BaseString::snprintf(buf, sizeof(buf), "Could not find file: "%s"", filename);
  130.     setError(CR_ERROR, buf);
  131.     return 0;
  132.   }
  133.   const Uint32 bytes = sbuf.st_size;
  134.   
  135.   Uint32 * buf2 = new Uint32[bytes/4+1];
  136.   
  137.   FILE * f = fopen(filename, "rb");
  138.   if(f == 0){
  139.     setError(CR_ERROR, "Failed to open file");
  140.     delete []buf2;
  141.     return 0;
  142.   }
  143.   Uint32 sz = fread(buf2, 1, bytes, f);
  144.   fclose(f);
  145.   if(sz != bytes){
  146.     setError(CR_ERROR, "Failed to read file");
  147.     delete []buf2;
  148.     return 0;
  149.   }
  150.   
  151.   ConfigValuesFactory cvf;
  152.   if(!cvf.unpack(buf2, bytes)){
  153.     char buf[255];
  154.     BaseString::snprintf(buf, sizeof(buf), "Error while unpacking"); 
  155.     setError(CR_ERROR, buf);
  156.     delete []buf2;
  157.     return 0;
  158.   }
  159.   delete [] buf2;
  160.   return (ndb_mgm_configuration*)cvf.m_cfg;
  161. #else
  162.   return 0;
  163. #endif
  164. }    
  165. void
  166. ConfigRetriever::setError(ErrorType et, const char * s){
  167.   errorString.assign(s ? s : "");
  168.   latestErrorType = et;
  169. }
  170. void
  171. ConfigRetriever::resetError(){
  172.   setError(CR_NO_ERROR,0);
  173. }
  174. int
  175. ConfigRetriever::hasError()
  176. {
  177.   return latestErrorType != CR_NO_ERROR;
  178. }
  179. const char * 
  180. ConfigRetriever::getErrorString(){
  181.   return errorString.c_str();
  182. }
  183. bool
  184. ConfigRetriever::verifyConfig(const struct ndb_mgm_configuration * conf, Uint32 nodeid){
  185.   char buf[255];
  186.   ndb_mgm_configuration_iterator * it;
  187.   it = ndb_mgm_create_configuration_iterator((struct ndb_mgm_configuration *)conf,
  188.      CFG_SECTION_NODE);
  189.   if(it == 0){
  190.     BaseString::snprintf(buf, 255, "Unable to create config iterator");
  191.     setError(CR_ERROR, buf);
  192.     return false;
  193.     
  194.   }
  195.   NdbAutoPtr<ndb_mgm_configuration_iterator> ptr(it);
  196.   
  197.   if(ndb_mgm_find(it, CFG_NODE_ID, nodeid) != 0){
  198.     BaseString::snprintf(buf, 255, "Unable to find node with id: %d", nodeid);
  199.     setError(CR_ERROR, buf);
  200.     return false;
  201.   }
  202.      
  203.   const char * hostname;
  204.   if(ndb_mgm_get_string_parameter(it, CFG_NODE_HOST, &hostname)){
  205.     BaseString::snprintf(buf, 255, "Unable to get hostname(%d) from config",CFG_NODE_HOST);
  206.     setError(CR_ERROR, buf);
  207.     return false;
  208.   }
  209.   const char * datadir;
  210.   if(!ndb_mgm_get_string_parameter(it, CFG_NODE_DATADIR, &datadir)){
  211.     NdbConfig_SetPath(datadir);
  212.   }
  213.   if (hostname && hostname[0] != 0 &&
  214.       !SocketServer::tryBind(0,hostname)) {
  215.     BaseString::snprintf(buf, 255, "Config hostname(%s) don't match a local interface,"
  216.      " tried to bind, error = %d - %s",
  217.      hostname, errno, strerror(errno));
  218.     setError(CR_ERROR, buf);
  219.     return false;
  220.   }
  221.   unsigned int _type;
  222.   if(ndb_mgm_get_int_parameter(it, CFG_TYPE_OF_SECTION, &_type)){
  223.     BaseString::snprintf(buf, 255, "Unable to get type of node(%d) from config",
  224.      CFG_TYPE_OF_SECTION);
  225.     setError(CR_ERROR, buf);
  226.     return false;
  227.   }
  228.   
  229.   if(_type != m_node_type){
  230.     const char *type_s, *alias_s, *type_s2, *alias_s2;
  231.     alias_s= ndb_mgm_get_node_type_alias_string((enum ndb_mgm_node_type)m_node_type,
  232. &type_s);
  233.     alias_s2= ndb_mgm_get_node_type_alias_string((enum ndb_mgm_node_type)_type,
  234.  &type_s2);
  235.     BaseString::snprintf(buf, 255, "This node type %s(%s) and config "
  236.  "node type %s(%s) don't match for nodeid %d", 
  237.  alias_s, type_s, alias_s2, type_s2, nodeid);
  238.     setError(CR_ERROR, buf);
  239.     return false;
  240.   }
  241.   /**
  242.    * Check hostnames
  243.    */
  244.   ndb_mgm_configuration_iterator iter(* conf, CFG_SECTION_CONNECTION);
  245.   for(iter.first(); iter.valid(); iter.next()){
  246.     Uint32 type = CONNECTION_TYPE_TCP + 1;
  247.     if(iter.get(CFG_TYPE_OF_SECTION, &type)) continue;
  248.     if(type != CONNECTION_TYPE_TCP) continue;
  249.     
  250.     Uint32 nodeId1, nodeId2, remoteNodeId;
  251.     if(iter.get(CFG_CONNECTION_NODE_1, &nodeId1)) continue;
  252.     if(iter.get(CFG_CONNECTION_NODE_2, &nodeId2)) continue;
  253.     
  254.     if(nodeId1 != nodeid && nodeId2 != nodeid) continue;
  255.     remoteNodeId = (nodeid == nodeId1 ? nodeId2 : nodeId1);
  256.     const char * name;
  257.     struct in_addr addr;
  258.     BaseString tmp;
  259.     if(!iter.get(CFG_CONNECTION_HOSTNAME_1, &name) && strlen(name)){
  260.       if(Ndb_getInAddr(&addr, name) != 0){
  261. tmp.assfmt("Unable to lookup/illegal hostname %s, "
  262.    "connection from node %d to node %d",
  263.    name, nodeid, remoteNodeId);
  264. setError(CR_ERROR, tmp.c_str());
  265. return false;
  266.       }
  267.     }
  268.     if(!iter.get(CFG_CONNECTION_HOSTNAME_2, &name) && strlen(name)){
  269.       if(Ndb_getInAddr(&addr, name) != 0){
  270. tmp.assfmt("Unable to lookup/illegal hostname %s, "
  271.    "connection from node %d to node %d",
  272.    name, nodeid, remoteNodeId);
  273. setError(CR_ERROR, tmp.c_str());
  274. return false;
  275.       }
  276.     }
  277.   }
  278.   return true;
  279. }
  280. int
  281. ConfigRetriever::setNodeId(Uint32 nodeid)
  282. {
  283.   return ndb_mgm_set_configuration_nodeid(m_handle, nodeid);
  284. }
  285. Uint32
  286. ConfigRetriever::allocNodeId(int no_retries, int retry_delay_in_seconds)
  287. {
  288.   _ownNodeId= 0;
  289.   if(m_handle != 0)
  290.   {
  291.     while (1)
  292.     {
  293.       int res= ndb_mgm_alloc_nodeid(m_handle, m_version, m_node_type);
  294.       if(res >= 0)
  295. return _ownNodeId= (Uint32)res;
  296.       if (no_retries == 0)
  297. break;
  298.       no_retries--;
  299.       NdbSleep_SecSleep(retry_delay_in_seconds);
  300.     }
  301.     setError(CR_ERROR, ndb_mgm_get_latest_error_desc(m_handle));
  302.   } else
  303.     setError(CR_ERROR, "management server handle not initialized");    
  304.   return 0;
  305. }