ConfigRetriever.cpp 8.84 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/* Copyright (C) 2003 MySQL AB

   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
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

17 18 19
#include <ndb_global.h>
#include <ndb_version.h>

20
#include <ConfigRetriever.hpp>
21
#include <SocketServer.hpp>
22 23 24 25 26 27 28 29 30 31 32 33 34 35

#include <NdbSleep.h>
#include <NdbOut.hpp>

#include <NdbTCP.h>
#include <NdbEnv.h>
#include "MgmtErrorReporter.hpp"

#include <uucode.h>
#include <Properties.hpp>

#include <socket_io.h>
#include <NdbConfig.h>

36 37 38 39
#include <NdbAutoPtr.hpp>
 
#include <mgmapi.h>
#include <mgmapi_config_parameters.h>
40
#include <mgmapi_configuration.hpp>
41 42
#include <ConfigValues.hpp>
#include <NdbHost.h>
43 44 45 46

//****************************************************************************
//****************************************************************************

47
ConfigRetriever::ConfigRetriever(const char * _connect_string,
48 49
				 Uint32 version, Uint32 node_type)
{
unknown's avatar
unknown committed
50 51
  m_version = version;
  m_node_type = node_type;
52
  _ownNodeId= 0;
53

54
  m_handle= ndb_mgm_create_handle();
55

56 57 58 59 60 61 62 63 64 65 66 67
  if (m_handle == 0) {
    setError(CR_ERROR, "Unable to allocate mgm handle");
    return;
  }

  if (ndb_mgm_set_connectstring(m_handle, _connect_string))
  {
    setError(CR_ERROR, ndb_mgm_get_latest_error_desc(m_handle));
    return;
  }
  resetError();
}
68

69 70
ConfigRetriever::~ConfigRetriever()
{
71 72 73 74
  if (m_handle) {
    ndb_mgm_disconnect(m_handle);
    ndb_mgm_destroy_handle(&m_handle);
  }
75 76
}

77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
Uint32 
ConfigRetriever::get_configuration_nodeid() const
{
  return ndb_mgm_get_configuration_nodeid(m_handle);
}

Uint32 ConfigRetriever::get_mgmd_port() const
{
  return ndb_mgm_get_connected_port(m_handle);
}

const char *ConfigRetriever::get_mgmd_host() const
{
  return ndb_mgm_get_connected_host(m_handle);
}
92

unknown's avatar
unknown committed
93 94 95 96
const char *ConfigRetriever::get_connectstring(char *buf, int buf_sz) const
{
  return ndb_mgm_get_connectstring(m_handle, buf, buf_sz);
}
97 98 99 100

//****************************************************************************
//****************************************************************************
 
unknown's avatar
unknown committed
101
int
102 103 104 105 106 107
ConfigRetriever::do_connect(int no_retries,
			    int retry_delay_in_seconds, int verbose)
{
  return
    (ndb_mgm_connect(m_handle,no_retries,retry_delay_in_seconds,verbose)==0) ?
    0 : -1;
108 109
}

unknown's avatar
unknown committed
110 111 112 113 114 115
//****************************************************************************
//****************************************************************************
//****************************************************************************
//****************************************************************************
struct ndb_mgm_configuration*
ConfigRetriever::getConfig() {
116

unknown's avatar
unknown committed
117
  struct ndb_mgm_configuration * p = 0;
118

119
  if(m_handle != 0)
unknown's avatar
unknown committed
120
    p = getConfig(m_handle);
121

unknown's avatar
unknown committed
122
  if(p == 0)
123
    return 0;
unknown's avatar
unknown committed
124
  
125
  if(!verifyConfig(p, _ownNodeId)){
unknown's avatar
unknown committed
126 127
    free(p);
    p= 0;
128
  }
unknown's avatar
unknown committed
129 130 131
  
  return p;
}
132

unknown's avatar
unknown committed
133 134 135 136
ndb_mgm_configuration *
ConfigRetriever::getConfig(NdbMgmHandle m_handle){
  
  ndb_mgm_configuration * conf = ndb_mgm_get_configuration(m_handle,m_version);
137
  if(conf == 0){
138
    setError(CR_ERROR, ndb_mgm_get_latest_error_desc(m_handle));
unknown's avatar
unknown committed
139 140
    return 0;
  }
141

142
  return conf;
143
}
unknown's avatar
unknown committed
144

145
ndb_mgm_configuration *
unknown's avatar
unknown committed
146
ConfigRetriever::getConfig(const char * filename){
unknown's avatar
unknown committed
147
#ifndef NDB_WIN32	
148 149 150 151 152

  struct stat sbuf;
  const int res = stat(filename, &sbuf);
  if(res != 0){
    char buf[255];
153
    BaseString::snprintf(buf, sizeof(buf), "Could not find file: \"%s\"", filename);
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
    setError(CR_ERROR, buf);
    return 0;
  }
  const Uint32 bytes = sbuf.st_size;
  
  Uint32 * buf2 = new Uint32[bytes/4+1];
  
  FILE * f = fopen(filename, "rb");
  if(f == 0){
    setError(CR_ERROR, "Failed to open file");
    delete []buf2;
    return 0;
  }
  Uint32 sz = fread(buf2, 1, bytes, f);
  fclose(f);
  if(sz != bytes){
    setError(CR_ERROR, "Failed to read file");
    delete []buf2;
    return 0;
  }
  
175 176
  ConfigValuesFactory cvf;
  if(!cvf.unpack(buf2, bytes)){
177
    char buf[255];
178
    BaseString::snprintf(buf, sizeof(buf), "Error while unpacking"); 
179 180 181 182 183
    setError(CR_ERROR, buf);
    delete []buf2;
    return 0;
  }
  delete [] buf2;
184
  return (ndb_mgm_configuration*)cvf.m_cfg;
unknown's avatar
unknown committed
185 186 187
#else
  return 0;
#endif
188 189 190 191
}			   

void
ConfigRetriever::setError(ErrorType et, const char * s){
unknown's avatar
unknown committed
192
  errorString.assign(s ? s : "");
193 194 195
  latestErrorType = et;
}

196 197 198 199 200 201 202 203 204 205
void
ConfigRetriever::resetError(){
  setError(CR_NO_ERROR,0);
}

int
ConfigRetriever::hasError()
{
  return latestErrorType != CR_NO_ERROR;
}
206 207 208

const char * 
ConfigRetriever::getErrorString(){
unknown's avatar
unknown committed
209
  return errorString.c_str();
210 211
}

212
bool
213
ConfigRetriever::verifyConfig(const struct ndb_mgm_configuration * conf, Uint32 nodeid){
unknown's avatar
unknown committed
214

215 216
  char buf[255];
  ndb_mgm_configuration_iterator * it;
217 218
  it = ndb_mgm_create_configuration_iterator((struct ndb_mgm_configuration *)conf,
					     CFG_SECTION_NODE);
219 220

  if(it == 0){
221
    BaseString::snprintf(buf, 255, "Unable to create config iterator");
222 223 224 225 226 227
    setError(CR_ERROR, buf);
    return false;
    
  }
  NdbAutoPtr<ndb_mgm_configuration_iterator> ptr(it);
  
228
  if(ndb_mgm_find(it, CFG_NODE_ID, nodeid) != 0){
229
    BaseString::snprintf(buf, 255, "Unable to find node with id: %d", nodeid);
230 231 232 233 234 235
    setError(CR_ERROR, buf);
    return false;
  }
     
  const char * hostname;
  if(ndb_mgm_get_string_parameter(it, CFG_NODE_HOST, &hostname)){
236
    BaseString::snprintf(buf, 255, "Unable to get hostname(%d) from config",CFG_NODE_HOST);
237 238 239 240
    setError(CR_ERROR, buf);
    return false;
  }

241 242 243 244 245
  const char * datadir;
  if(!ndb_mgm_get_string_parameter(it, CFG_NODE_DATADIR, &datadir)){
    NdbConfig_SetPath(datadir);
  }

246 247
  if (hostname && hostname[0] != 0 &&
      !SocketServer::tryBind(0,hostname)) {
248
    BaseString::snprintf(buf, 255, "Config hostname(%s) don't match a local interface,"
249 250
	     " tried to bind, error = %d - %s",
	     hostname, errno, strerror(errno));
251 252 253 254 255 256
    setError(CR_ERROR, buf);
    return false;
  }

  unsigned int _type;
  if(ndb_mgm_get_int_parameter(it, CFG_TYPE_OF_SECTION, &_type)){
257
    BaseString::snprintf(buf, 255, "Unable to get type of node(%d) from config",
258 259 260 261 262
	     CFG_TYPE_OF_SECTION);
    setError(CR_ERROR, buf);
    return false;
  }
  
unknown's avatar
unknown committed
263
  if(_type != m_node_type){
264 265 266 267 268 269 270 271
    const char *type_s, *alias_s, *type_s2, *alias_s2;
    alias_s= ndb_mgm_get_node_type_alias_string((enum ndb_mgm_node_type)m_node_type,
						&type_s);
    alias_s2= ndb_mgm_get_node_type_alias_string((enum ndb_mgm_node_type)_type,
						 &type_s2);
    BaseString::snprintf(buf, 255, "This node type %s(%s) and config "
			 "node type %s(%s) don't match for nodeid %d", 
			 alias_s, type_s, alias_s2, type_s2, nodeid);
272 273 274
    setError(CR_ERROR, buf);
    return false;
  }
unknown's avatar
unknown committed
275

276 277 278 279 280 281 282 283 284 285 286 287 288 289
  /**
   * Check hostnames
   */
  ndb_mgm_configuration_iterator iter(* conf, CFG_SECTION_CONNECTION);
  for(iter.first(); iter.valid(); iter.next()){

    Uint32 type = CONNECTION_TYPE_TCP + 1;
    if(iter.get(CFG_TYPE_OF_SECTION, &type)) continue;
    if(type != CONNECTION_TYPE_TCP) continue;
    
    Uint32 nodeId1, nodeId2, remoteNodeId;
    if(iter.get(CFG_CONNECTION_NODE_1, &nodeId1)) continue;
    if(iter.get(CFG_CONNECTION_NODE_2, &nodeId2)) continue;
    
290 291
    if(nodeId1 != nodeid && nodeId2 != nodeid) continue;
    remoteNodeId = (nodeid == nodeId1 ? nodeId2 : nodeId1);
292 293 294 295

    const char * name;
    struct in_addr addr;
    BaseString tmp;
296
    if(!iter.get(CFG_CONNECTION_HOSTNAME_1, &name) && strlen(name)){
297 298 299
      if(Ndb_getInAddr(&addr, name) != 0){
	tmp.assfmt("Unable to lookup/illegal hostname %s, "
		   "connection from node %d to node %d",
300
		   name, nodeid, remoteNodeId);
301 302 303 304 305
	setError(CR_ERROR, tmp.c_str());
	return false;
      }
    }

306
    if(!iter.get(CFG_CONNECTION_HOSTNAME_2, &name) && strlen(name)){
307 308 309
      if(Ndb_getInAddr(&addr, name) != 0){
	tmp.assfmt("Unable to lookup/illegal hostname %s, "
		   "connection from node %d to node %d",
310
		   name, nodeid, remoteNodeId);
311 312 313 314 315
	setError(CR_ERROR, tmp.c_str());
	return false;
      }
    }
  }
316 317
  return true;
}
unknown's avatar
unknown committed
318

unknown's avatar
unknown committed
319 320 321 322 323 324
int
ConfigRetriever::setNodeId(Uint32 nodeid)
{
  return ndb_mgm_set_configuration_nodeid(m_handle, nodeid);
}

unknown's avatar
unknown committed
325
Uint32
326 327 328 329 330 331 332 333 334 335 336 337 338 339
ConfigRetriever::allocNodeId(int no_retries, int retry_delay_in_seconds)
{
  _ownNodeId= 0;
  if(m_handle != 0)
  {
    while (1)
    {
      int res= ndb_mgm_alloc_nodeid(m_handle, m_version, m_node_type);
      if(res >= 0)
	return _ownNodeId= (Uint32)res;
      if (no_retries == 0)
	break;
      no_retries--;
      NdbSleep_SecSleep(retry_delay_in_seconds);
unknown's avatar
unknown committed
340
    }
341 342 343 344
    setError(CR_ERROR, ndb_mgm_get_latest_error_desc(m_handle));
  } else
    setError(CR_ERROR, "management server handle not initialized");    
  return 0;
unknown's avatar
unknown committed
345
}