Configuration.cpp 23.6 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
#include <ndb_global.h>
18
#include <ndb_opts.h>
19

20 21 22 23 24 25 26 27 28 29 30
#include "Configuration.hpp"
#include <ErrorHandlingMacros.hpp>
#include "GlobalData.hpp"

#include <ConfigRetriever.hpp>
#include <IPCConfig.hpp>
#include <ndb_version.h>
#include <NdbMem.h>
#include <NdbOut.hpp>
#include <WatchDog.hpp>

31 32 33 34 35 36
#include <mgmapi_configuration.hpp>
#include <mgmapi_config_parameters_debug.h>
#include <kernel_config_parameters.h>

#include <kernel_types.h>
#include <ndb_limits.h>
unknown's avatar
unknown committed
37
#include <ndbapi_limits.h>
38 39
#include "pc.hpp"
#include <LogLevel.hpp>
unknown's avatar
unknown committed
40
#include <NdbSleep.h>
41

42 43 44 45
extern "C" {
  void ndbSetOwnVersion();
}

46 47 48
#include <EventLogger.hpp>
extern EventLogger g_eventLogger;

49
enum ndbd_options {
50
  OPT_INITIAL = NDB_STD_OPTIONS_LAST,
51
  OPT_NODAEMON,
52 53 54
  OPT_FOREGROUND,
  OPT_NOWAIT_NODES,
  OPT_INITIAL_START
55 56 57
};

NDB_STD_OPTS_VARS;
58 59
// XXX should be my_bool ???
static int _daemon, _no_daemon, _foreground,  _initial, _no_start;
unknown's avatar
unknown committed
60 61 62 63 64 65
static int _initialstart;
static const char* _nowait_nodes;

extern Uint32 g_start_type;
extern NdbNodeBitmask g_nowait_nodes;

66 67
const char *load_default_groups[]= { "mysql_cluster","ndbd",0 };

68 69 70 71 72 73
/**
 * Arguments to NDB process
 */ 
static struct my_option my_long_options[] =
{
  NDB_STD_OPTS("ndbd"),
74
  { "initial", OPT_INITIAL,
75 76 77 78 79 80 81 82 83 84 85
    "Perform initial start of ndbd, including cleaning the file system. "
    "Consult documentation before using this",
    (gptr*) &_initial, (gptr*) &_initial, 0,
    GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
  { "nostart", 'n',
    "Don't start ndbd immediately. Ndbd will await command from ndb_mgmd",
    (gptr*) &_no_start, (gptr*) &_no_start, 0,
    GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
  { "daemon", 'd', "Start ndbd as daemon (default)",
    (gptr*) &_daemon, (gptr*) &_daemon, 0,
    GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0 },
86
  { "nodaemon", OPT_NODAEMON,
87 88 89
    "Do not start ndbd as daemon, provided for testing purposes",
    (gptr*) &_no_daemon, (gptr*) &_no_daemon, 0,
    GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
90 91 92 93 94
  { "foreground", OPT_FOREGROUND,
    "Run real ndbd in foreground, provided for debugging purposes"
    " (implies --nodaemon)",
    (gptr*) &_foreground, (gptr*) &_foreground, 0,
    GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
95
  { "nowait-nodes", OPT_NOWAIT_NODES, 
unknown's avatar
unknown committed
96 97 98
    "Nodes that will not be waited for during start",
    (gptr*) &_nowait_nodes, (gptr*) &_nowait_nodes, 0,
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
99
  { "initial-start", OPT_INITIAL_START, 
unknown's avatar
unknown committed
100 101 102
    "Perform initial start",
    (gptr*) &_initialstart, (gptr*) &_initialstart, 0,
    GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
103 104 105 106 107 108 109 110 111
  { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
static void short_usage_sub(void)
{
  printf("Usage: %s [OPTIONS]\n", my_progname);
}
static void usage()
{
  short_usage_sub();
112
  ndb_std_print_version();
113 114
  print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
  puts("");
115 116 117 118 119 120 121 122 123 124
  my_print_help(my_long_options);
  my_print_variables(my_long_options);
}

bool
Configuration::init(int argc, char** argv)
{  
  load_defaults("my",load_default_groups,&argc,&argv);

  int ho_error;
125 126 127 128 129
#ifndef DBUG_OFF
  opt_debug= "d:t:O,/tmp/ndbd.trace";
#endif
  if ((ho_error=handle_options(&argc, &argv, my_long_options,
			       ndb_std_get_one_option)))
130 131
    exit(ho_error);

132
  if (_no_daemon || _foreground) {
unknown's avatar
unknown committed
133 134
    _daemon= 0;
  }
135

136 137
  DBUG_PRINT("info", ("no_start=%d", _no_start));
  DBUG_PRINT("info", ("initial=%d", _initial));
unknown's avatar
unknown committed
138
  DBUG_PRINT("info", ("daemon=%d", _daemon));
139
  DBUG_PRINT("info", ("foreground=%d", _foreground));
140
  DBUG_PRINT("info", ("connect_str=%s", opt_connect_str));
141

142 143 144
  ndbSetOwnVersion();

  // Check the start flag
145
  if (_no_start)
146
    globalData.theRestartFlag = initial_state;
147 148
  else 
    globalData.theRestartFlag = perform_start;
149 150 151 152 153 154

  // Check the initial flag
  if (_initial)
    _initialStart = true;
  
  // Check connectstring
155 156
  if (opt_connect_str)
    _connectString = strdup(opt_connect_str);
157
  
unknown's avatar
unknown committed
158 159
  // Check daemon flag
  if (_daemon)
160
    _daemonMode = true;
161 162
  if (_foreground)
    _foregroundMode = true;
163 164 165 166 167 168 169

  // Save programname
  if(argc > 0 && argv[0] != 0)
    _programName = strdup(argv[0]);
  else
    _programName = strdup("");
  
unknown's avatar
unknown committed
170 171
  globalData.ownId= 0;

unknown's avatar
unknown committed
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
  if (_nowait_nodes)
  {
    BaseString str(_nowait_nodes);
    Vector<BaseString> arr;
    str.split(arr, ",");
    for (Uint32 i = 0; i<arr.size(); i++)
    {
      char *endptr = 0;
      long val = strtol(arr[i].c_str(), &endptr, 10);
      if (*endptr)
      {
	ndbout_c("Unable to parse nowait-nodes argument: %s : %s", 
		 arr[i].c_str(), _nowait_nodes);
	exit(-1);
      }
      if (! (val > 0 && val < MAX_NDB_NODES))
      {
	ndbout_c("Invalid nodeid specified in nowait-nodes: %d : %s", 
		 val, _nowait_nodes);
	exit(-1);
      }
      g_nowait_nodes.set(val);
    }
  }

  if (_initialstart)
  {
    _initialStart = true;
    g_start_type |= (1 << NodeState::ST_INITIAL_START);
  }
  
203 204 205
  return true;
}

206
Configuration::Configuration()
207 208 209 210
{
  _programName = 0;
  _connectString = 0;
  _fsPath = 0;
unknown's avatar
unknown committed
211
  _backupPath = 0;
212 213
  _initialStart = false;
  _daemonMode = false;
214
  _foregroundMode = false;
215
  m_config_retriever= 0;
unknown's avatar
unknown committed
216
  m_clusterConfig= 0;
217
  m_clusterConfigIter= 0;
unknown's avatar
unknown committed
218
  m_logLevel= 0;
219 220 221
}

Configuration::~Configuration(){
unknown's avatar
unknown committed
222 223 224
  if (opt_connect_str)
    free(_connectString);

225 226 227 228 229
  if(_programName != NULL)
    free(_programName);

  if(_fsPath != NULL)
    free(_fsPath);
230

unknown's avatar
unknown committed
231 232 233
  if(_backupPath != NULL)
    free(_backupPath);

234 235 236
  if (m_config_retriever) {
    delete m_config_retriever;
  }
unknown's avatar
unknown committed
237 238 239 240

  if(m_logLevel) {
    delete m_logLevel;
  }
241 242 243
}

void
244 245
Configuration::closeConfiguration(bool end_session){
  m_config_retriever->end_session(end_session);
246 247 248 249
  if (m_config_retriever) {
    delete m_config_retriever;
  }
  m_config_retriever= 0;
250 251 252
}

void
253
Configuration::fetch_configuration(){
254 255 256
  /**
   * Fetch configuration from management server
   */
257 258 259 260
  if (m_config_retriever) {
    delete m_config_retriever;
  }

261
  m_mgmd_port= 0;
262 263 264 265 266
  m_config_retriever= new ConfigRetriever(getConnectString(),
					  NDB_VERSION, NODE_TYPE_DB);

  if (m_config_retriever->hasError())
  {
unknown's avatar
unknown committed
267
    ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG,
268 269 270 271 272
	      "Could not connect initialize handle to management server",
	      m_config_retriever->getErrorString());
  }

  if(m_config_retriever->do_connect(12,5,1) == -1){
unknown's avatar
unknown committed
273 274 275 276 277 278
    const char * s = m_config_retriever->getErrorString();
    if(s == 0)
      s = "No error given!";
    /* Set stop on error to true otherwise NDB will
       go into an restart loop...
    */
unknown's avatar
unknown committed
279
    ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Could not connect to ndb_mgmd", s);
unknown's avatar
unknown committed
280 281
  }
  
282 283
  m_mgmd_port= m_config_retriever->get_mgmd_port();
  m_mgmd_host.assign(m_config_retriever->get_mgmd_host());
284

unknown's avatar
unknown committed
285 286
  ConfigRetriever &cr= *m_config_retriever;
  
unknown's avatar
unknown committed
287 288 289 290 291 292 293
  /**
   * if we have a nodeid set (e.g in a restart situation)
   * reuse it
   */
  if (globalData.ownId)
    cr.setNodeId(globalData.ownId);

294 295
  globalData.ownId = cr.allocNodeId(globalData.ownId ? 10 : 2 /*retry*/,
                                    3 /*delay*/);
unknown's avatar
unknown committed
296 297
  
  if(globalData.ownId == 0){
unknown's avatar
unknown committed
298
    ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, 
unknown's avatar
unknown committed
299 300 301 302
	      "Unable to alloc node id", m_config_retriever->getErrorString());
  }
  
  ndb_mgm_configuration * p = cr.getConfig();
303 304 305 306
  if(p == 0){
    const char * s = cr.getErrorString();
    if(s == 0)
      s = "No error given!";
unknown's avatar
unknown committed
307
    
308 309
    /* Set stop on error to true otherwise NDB will
       go into an restart loop...
unknown's avatar
unknown committed
310 311
    */
    
unknown's avatar
unknown committed
312
    ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Could not fetch configuration"
313 314
	      "/invalid configuration", s);
  }
unknown's avatar
unknown committed
315 316 317 318 319 320 321
  if(m_clusterConfig)
    free(m_clusterConfig);
  
  m_clusterConfig = p;
  
  ndb_mgm_configuration_iterator iter(* p, CFG_SECTION_NODE);
  if (iter.find(CFG_NODE_ID, globalData.ownId)){
unknown's avatar
unknown committed
322
    ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Invalid configuration fetched", "DB missing");
unknown's avatar
unknown committed
323 324 325
  }
  
  if(iter.get(CFG_DB_STOP_ON_ERROR, &_stopOnError)){
unknown's avatar
unknown committed
326
    ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Invalid configuration fetched", 
unknown's avatar
unknown committed
327 328
	      "StopOnError missing");
  }
unknown's avatar
unknown committed
329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351

  m_mgmds.clear();
  for(ndb_mgm_first(&iter); ndb_mgm_valid(&iter); ndb_mgm_next(&iter))
  {
    Uint32 nodeType, port;
    char const *hostname;

    ndb_mgm_get_int_parameter(&iter,CFG_TYPE_OF_SECTION,&nodeType);

    if (nodeType != NodeInfo::MGM)
      continue;

    if (ndb_mgm_get_string_parameter(&iter,CFG_NODE_HOST, &hostname) ||
	ndb_mgm_get_int_parameter(&iter,CFG_MGM_PORT, &port) ||
	hostname == 0 || hostname[0] == 0)
    {
      continue;
    }
    BaseString connectstring(hostname);
    connectstring.appfmt(":%d", port);

    m_mgmds.push_back(connectstring);
  }
unknown's avatar
unknown committed
352
}
353

unknown's avatar
unknown committed
354 355 356 357 358
static char * get_and_validate_path(ndb_mgm_configuration_iterator &iter,
				    Uint32 param, const char *param_string)
{ 
  const char* path = NULL;
  if(iter.get(param, &path)){
unknown's avatar
unknown committed
359
    ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Invalid configuration fetched missing ", 
unknown's avatar
unknown committed
360 361 362 363
	      param_string);
  } 
  
  if(path == 0 || strlen(path) == 0){
unknown's avatar
unknown committed
364
    ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG,
unknown's avatar
unknown committed
365 366 367 368 369 370 371 372 373 374
	      "Invalid configuration fetched. Configuration does not contain valid ",
	      param_string);
  }
  
  // check that it is pointing on a valid directory
  // 
  char buf2[PATH_MAX];
  memset(buf2, 0,sizeof(buf2));
#ifdef NDB_WIN32
  char* szFilePart;
unknown's avatar
unknown committed
375
  if(!GetFullPathName(path, sizeof(buf2), buf2, &szFilePart) ||
unknown's avatar
unknown committed
376
     (GetFileAttributes(buf2) & FILE_ATTRIBUTE_READONLY))
unknown's avatar
unknown committed
377
#else
unknown's avatar
unknown committed
378
  if((::realpath(path, buf2) == NULL)||
unknown's avatar
unknown committed
379 380
       (::access(buf2, W_OK) != 0))
#endif
unknown's avatar
unknown committed
381
  {
382
    ERROR_SET(fatal, NDBD_EXIT_AFS_INVALIDPATH, path, param_string);
unknown's avatar
unknown committed
383 384
  }
  
unknown's avatar
unknown committed
385 386
  if (strcmp(&buf2[strlen(buf2) - 1], DIR_SEPARATOR))
    strcat(buf2, DIR_SEPARATOR);
unknown's avatar
unknown committed
387
  
unknown's avatar
unknown committed
388 389 390
  return strdup(buf2);
}

unknown's avatar
unknown committed
391 392
void
Configuration::setupConfiguration(){
unknown's avatar
unknown committed
393 394 395

  DBUG_ENTER("Configuration::setupConfiguration");

unknown's avatar
unknown committed
396
  ndb_mgm_configuration * p = m_clusterConfig;
397

398 399 400 401
  /**
   * Configure transporters
   */
  {  
unknown's avatar
unknown committed
402
    int res = IPCConfig::configureTransporters(globalData.ownId,
403 404 405
					       * p, 
					       globalTransporterRegistry);
    if(res <= 0){
unknown's avatar
unknown committed
406
      ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Invalid configuration fetched", 
407 408 409 410 411 412 413
		"No transporters configured");
    }
  }

  /**
   * Setup cluster configuration data
   */
414 415
  ndb_mgm_configuration_iterator iter(* p, CFG_SECTION_NODE);
  if (iter.find(CFG_NODE_ID, globalData.ownId)){
unknown's avatar
unknown committed
416
    ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Invalid configuration fetched", "DB missing");
417
  }
418 419 420

  unsigned type;
  if(!(iter.get(CFG_TYPE_OF_SECTION, &type) == 0 && type == NODE_TYPE_DB)){
unknown's avatar
unknown committed
421
    ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Invalid configuration fetched",
422 423 424
	      "I'm wrong type of node");
  }
  
425
  if(iter.get(CFG_DB_NO_SAVE_MSGS, &_maxErrorLogs)){
unknown's avatar
unknown committed
426
    ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Invalid configuration fetched", 
427 428 429
	      "MaxNoOfSavedMessages missing");
  }
  
430
  if(iter.get(CFG_DB_MEMLOCK, &_lockPagesInMainMemory)){
unknown's avatar
unknown committed
431
    ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Invalid configuration fetched", 
432 433 434
	      "LockPagesInMainMemory missing");
  }

435
  if(iter.get(CFG_DB_WATCHDOG_INTERVAL, &_timeBetweenWatchDogCheck)){
unknown's avatar
unknown committed
436
    ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Invalid configuration fetched", 
437 438 439 440
	      "TimeBetweenWatchDogCheck missing");
  }

  /**
unknown's avatar
unknown committed
441
   * Get paths
442
   */  
unknown's avatar
unknown committed
443 444 445 446 447 448 449
  if (_fsPath)
    free(_fsPath);
  _fsPath= get_and_validate_path(iter, CFG_DB_FILESYSTEM_PATH, "FileSystemPath");
  if (_backupPath)
    free(_backupPath);
  _backupPath= get_and_validate_path(iter, CFG_DB_BACKUP_DATADIR, "BackupDataDir");

450
  if(iter.get(CFG_DB_STOP_ON_ERROR_INSERT, &m_restartOnErrorInsert)){
unknown's avatar
unknown committed
451
    ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Invalid configuration fetched", 
452 453 454 455 456 457 458 459 460 461 462
	      "RestartOnErrorInsert missing");
  }

  /**
   * Create the watch dog thread
   */
  { 
    Uint32 t = _timeBetweenWatchDogCheck;
    t = globalEmulatorData.theWatchDog ->setCheckInterval(t);
    _timeBetweenWatchDogCheck = t;
  }
463 464 465
  
  ConfigValues* cf = ConfigValuesFactory::extractCurrentSection(iter.m_config);

466 467
  if(m_clusterConfigIter)
    ndb_mgm_destroy_iterator(m_clusterConfigIter);
468 469
  m_clusterConfigIter = ndb_mgm_create_configuration_iterator
    (p, CFG_SECTION_NODE);
470

471
  calcSizeAlt(cf);
unknown's avatar
unknown committed
472 473

  DBUG_VOID_RETURN;
474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520
}

bool 
Configuration::lockPagesInMainMemory() const {
  return _lockPagesInMainMemory;
}

int 
Configuration::timeBetweenWatchDogCheck() const {
  return _timeBetweenWatchDogCheck;
}

void 
Configuration::timeBetweenWatchDogCheck(int value) {
  _timeBetweenWatchDogCheck = value;
}

int 
Configuration::maxNoOfErrorLogs() const {
  return _maxErrorLogs;
}

void 
Configuration::maxNoOfErrorLogs(int val){
  _maxErrorLogs = val;
}

bool
Configuration::stopOnError() const {
  return _stopOnError;
}

void 
Configuration::stopOnError(bool val){
  _stopOnError = val;
}

int
Configuration::getRestartOnErrorInsert() const {
  return m_restartOnErrorInsert;
}

void
Configuration::setRestartOnErrorInsert(int i){
  m_restartOnErrorInsert = i;
}

521 522 523 524 525
const char *
Configuration::getConnectString() const {
  return _connectString;
}

526 527 528 529 530 531
char *
Configuration::getConnectStringCopy() const {
  if(_connectString != 0)
    return strdup(_connectString);
  return 0;
}
532

533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548
const ndb_mgm_configuration_iterator * 
Configuration::getOwnConfigIterator() const {
  return m_ownConfigIterator;
}
  
ndb_mgm_configuration_iterator * 
Configuration::getClusterConfigIterator() const {
  return m_clusterConfigIter;
}

void
Configuration::calcSizeAlt(ConfigValues * ownConfig){
  const char * msg = "Invalid configuration fetched";
  char buf[255];

  unsigned int noOfTables = 0;
unknown's avatar
unknown committed
549 550
  unsigned int noOfUniqueHashIndexes = 0;
  unsigned int noOfOrderedIndexes = 0;
unknown's avatar
unknown committed
551
  unsigned int noOfTriggers = 0;
552 553 554 555 556 557 558
  unsigned int noOfReplicas = 0;
  unsigned int noOfDBNodes = 0;
  unsigned int noOfAPINodes = 0;
  unsigned int noOfMGMNodes = 0;
  unsigned int noOfNodes = 0;
  unsigned int noOfAttributes = 0;
  unsigned int noOfOperations = 0;
unknown's avatar
unknown committed
559
  unsigned int noOfLocalOperations = 0;
560 561 562 563
  unsigned int noOfTransactions = 0;
  unsigned int noOfIndexPages = 0;
  unsigned int noOfDataPages = 0;
  unsigned int noOfScanRecords = 0;
unknown's avatar
unknown committed
564 565
  unsigned int noOfLocalScanRecords = 0;
  unsigned int noBatchSize = 0;
566 567
  m_logLevel = new LogLevel();
  
unknown's avatar
unknown committed
568
  struct AttribStorage { int paramId; Uint32 * storage; bool computable; };
569
  AttribStorage tmp[] = {
unknown's avatar
unknown committed
570 571 572 573 574 575
    { CFG_DB_NO_SCANS, &noOfScanRecords, false },
    { CFG_DB_NO_LOCAL_SCANS, &noOfLocalScanRecords, true },
    { CFG_DB_BATCH_SIZE, &noBatchSize, false },
    { CFG_DB_NO_TABLES, &noOfTables, false },
    { CFG_DB_NO_ORDERED_INDEXES, &noOfOrderedIndexes, false },
    { CFG_DB_NO_UNIQUE_HASH_INDEXES, &noOfUniqueHashIndexes, false },
unknown's avatar
unknown committed
576
    { CFG_DB_NO_TRIGGERS, &noOfTriggers, true },
unknown's avatar
unknown committed
577 578 579 580 581
    { CFG_DB_NO_REPLICAS, &noOfReplicas, false },
    { CFG_DB_NO_ATTRIBUTES, &noOfAttributes, false },
    { CFG_DB_NO_OPS, &noOfOperations, false },
    { CFG_DB_NO_LOCAL_OPS, &noOfLocalOperations, true },
    { CFG_DB_NO_TRANSACTIONS, &noOfTransactions, false }
582 583 584 585 586 587 588
  };

  ndb_mgm_configuration_iterator db(*(ndb_mgm_configuration*)ownConfig, 0);
  
  const int sz = sizeof(tmp)/sizeof(AttribStorage);
  for(int i = 0; i<sz; i++){
    if(ndb_mgm_get_int_parameter(&db, tmp[i].paramId, tmp[i].storage)){
unknown's avatar
unknown committed
589 590
      if (tmp[i].computable) {
        *tmp[i].storage = 0;
591
      } else {
592
        BaseString::snprintf(buf, sizeof(buf),"ConfigParam: %d not found", tmp[i].paramId);
unknown's avatar
unknown committed
593
        ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, msg, buf);
594
      }
595 596 597 598 599 600 601
    }
  }

  Uint64 indexMem = 0, dataMem = 0;
  ndb_mgm_get_int64_parameter(&db, CFG_DB_DATA_MEM, &dataMem);
  ndb_mgm_get_int64_parameter(&db, CFG_DB_INDEX_MEM, &indexMem);
  if(dataMem == 0){
602
    BaseString::snprintf(buf, sizeof(buf), "ConfigParam: %d not found", CFG_DB_DATA_MEM);
unknown's avatar
unknown committed
603
    ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, msg, buf);
604 605 606
  }

  if(indexMem == 0){
607
    BaseString::snprintf(buf, sizeof(buf), "ConfigParam: %d not found", CFG_DB_INDEX_MEM);
unknown's avatar
unknown committed
608
    ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, msg, buf);
609 610
  }

611
  noOfDataPages = (dataMem / 32768);
612 613 614 615
  noOfIndexPages = (indexMem / 8192);

  for(unsigned j = 0; j<LogLevel::LOGLEVEL_CATEGORIES; j++){
    Uint32 tmp;
616
    if(!ndb_mgm_get_int_parameter(&db, CFG_MIN_LOGLEVEL+j, &tmp)){
617 618 619 620 621 622 623 624 625 626 627 628 629 630 631
      m_logLevel->setLogLevel((LogLevel::EventCategory)j, tmp);
    }
  }
  
  // tmp
  ndb_mgm_configuration_iterator * p = m_clusterConfigIter;

  Uint32 nodeNo = noOfNodes = 0;
  NodeBitmask nodes;
  for(ndb_mgm_first(p); ndb_mgm_valid(p); ndb_mgm_next(p), nodeNo++){
    
    Uint32 nodeId;
    Uint32 nodeType;
    
    if(ndb_mgm_get_int_parameter(p, CFG_NODE_ID, &nodeId)){
unknown's avatar
unknown committed
632
      ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, msg, "Node data (Id) missing");
633 634 635
    }
    
    if(ndb_mgm_get_int_parameter(p, CFG_TYPE_OF_SECTION, &nodeType)){
unknown's avatar
unknown committed
636
      ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, msg, "Node data (Type) missing");
637 638 639
    }
    
    if(nodeId > MAX_NODES || nodeId == 0){
640
      BaseString::snprintf(buf, sizeof(buf),
641
	       "Invalid node id: %d", nodeId);
unknown's avatar
unknown committed
642
      ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, msg, buf);
643 644 645
    }
    
    if(nodes.get(nodeId)){
646
      BaseString::snprintf(buf, sizeof(buf), "Two node can not have the same node id: %d",
647
	       nodeId);
unknown's avatar
unknown committed
648
      ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, msg, buf);
649 650 651 652 653 654 655 656
    }
    nodes.set(nodeId);
        
    switch(nodeType){
    case NODE_TYPE_DB:
      noOfDBNodes++; // No of NDB processes
      
      if(nodeId > MAX_NDB_NODES){
unknown's avatar
unknown committed
657
		  BaseString::snprintf(buf, sizeof(buf), "Maximum node id for a ndb node is: %d", 
658
		 MAX_NDB_NODES);
unknown's avatar
unknown committed
659
	ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, msg, buf);
660 661 662 663 664 665 666 667 668 669 670 671 672
      }
      break;
    case NODE_TYPE_API:
      noOfAPINodes++; // No of API processes
      break;
    case NODE_TYPE_REP:
      break;
    case NODE_TYPE_MGM:
      noOfMGMNodes++; // No of MGM processes
      break;
    case NODE_TYPE_EXT_REP:
      break;
    default:
673
      BaseString::snprintf(buf, sizeof(buf), "Unknown node type: %d", nodeType);
unknown's avatar
unknown committed
674
      ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, msg, buf);
675 676 677
    }
  }
  noOfNodes = nodeNo;
678 679

  noOfTables+= 2; // Add System tables
680
  noOfAttributes += 9;  // Add System table attributes
681 682 683 684

  ConfigValues::Iterator it2(*ownConfig, db.m_config);
  it2.set(CFG_DB_NO_TABLES, noOfTables);
  it2.set(CFG_DB_NO_ATTRIBUTES, noOfAttributes);
unknown's avatar
unknown committed
685
  {
unknown's avatar
unknown committed
686 687 688 689 690
    Uint32 neededNoOfTriggers =   /* types: Insert/Update/Delete/Custom */
      3 * noOfUniqueHashIndexes + /* for unique hash indexes, I/U/D */
      3 * NDB_MAX_ACTIVE_EVENTS + /* for events in suma, I/U/D */
      3 * noOfTables +            /* for backup, I/U/D */
      noOfOrderedIndexes;         /* for ordered indexes, C */
unknown's avatar
unknown committed
691 692 693 694 695 696
    if (noOfTriggers < neededNoOfTriggers)
    {
      noOfTriggers= neededNoOfTriggers;
      it2.set(CFG_DB_NO_TRIGGERS, noOfTriggers);
    }
  }
697

698 699 700 701 702
  /**
   * Do size calculations
   */
  ConfigValuesFactory cfg(ownConfig);

703 704
  Uint32 noOfMetaTables= noOfTables + noOfOrderedIndexes +
                           noOfUniqueHashIndexes;
705 706 707
  Uint32 noOfMetaTablesDict= noOfMetaTables;
  if (noOfMetaTablesDict > MAX_TABLES)
    noOfMetaTablesDict= MAX_TABLES;
708 709 710 711 712 713 714 715

  {
    /**
     * Dict Size Alt values
     */
    cfg.put(CFG_DICT_ATTRIBUTE, 
	    noOfAttributes);

716 717
    cfg.put(CFG_DICT_TABLE,
	    noOfMetaTablesDict);
718 719 720
  }


unknown's avatar
unknown committed
721 722 723 724 725 726
  if (noOfLocalScanRecords == 0) {
    noOfLocalScanRecords = (noOfDBNodes * noOfScanRecords) + 1;
  }
  if (noOfLocalOperations == 0) {
    noOfLocalOperations= (11 * noOfOperations) / 10;
  }
727 728 729
  Uint32 noOfTCScanRecords = noOfScanRecords;

  {
730
    Uint32 noOfAccTables= noOfMetaTables/*noOfTables+noOfUniqueHashIndexes*/;
731 732 733 734 735
    /**
     * Acc Size Alt values
     */
    // Can keep 65536 pages (= 0.5 GByte)
    cfg.put(CFG_ACC_DIR_RANGE, 
unknown's avatar
unknown committed
736
	    4 * NO_OF_FRAG_PER_NODE * noOfAccTables* noOfReplicas); 
737 738 739
    
    cfg.put(CFG_ACC_DIR_ARRAY,
	    (noOfIndexPages >> 8) + 
unknown's avatar
unknown committed
740
	    4 * NO_OF_FRAG_PER_NODE * noOfAccTables* noOfReplicas);
741 742
    
    cfg.put(CFG_ACC_FRAGMENT,
unknown's avatar
unknown committed
743
	    2 * NO_OF_FRAG_PER_NODE * noOfAccTables* noOfReplicas);
744 745 746 747 748 749 750 751 752
    
    /*-----------------------------------------------------------------------*/
    // The extra operation records added are used by the scan and node 
    // recovery process. 
    // Node recovery process will have its operations dedicated to ensure
    // that they never have a problem with allocation of the operation record.
    // The remainder are allowed for use by the scan processes.
    /*-----------------------------------------------------------------------*/
    cfg.put(CFG_ACC_OP_RECS,
unknown's avatar
unknown committed
753 754
	    (noOfLocalOperations + 50) + 
	    (noOfLocalScanRecords * noBatchSize) +
755 756 757 758
	    NODE_RECOVERY_SCAN_OP_RECORDS);
    
    cfg.put(CFG_ACC_OVERFLOW_RECS,
	    noOfIndexPages + 
unknown's avatar
unknown committed
759
	    2 * NO_OF_FRAG_PER_NODE * noOfAccTables* noOfReplicas);
760 761 762 763 764
    
    cfg.put(CFG_ACC_PAGE8, 
	    noOfIndexPages + 32);
    
    cfg.put(CFG_ACC_ROOT_FRAG, 
unknown's avatar
unknown committed
765
	    NO_OF_FRAG_PER_NODE * noOfAccTables* noOfReplicas);
766
    
unknown's avatar
unknown committed
767
    cfg.put(CFG_ACC_TABLE, noOfAccTables);
768 769 770 771 772 773 774 775 776 777 778 779
    
    cfg.put(CFG_ACC_SCAN, noOfLocalScanRecords);
  }
  
  {
    /**
     * Dih Size Alt values
     */
    cfg.put(CFG_DIH_API_CONNECT, 
	    2 * noOfTransactions);
    
    cfg.put(CFG_DIH_CONNECT, 
780
	    noOfOperations + noOfTransactions + 46);
781
    
782 783 784 785
    Uint32 noFragPerTable= ((noOfDBNodes + NO_OF_FRAGS_PER_CHUNK - 1) >>
                           LOG_NO_OF_FRAGS_PER_CHUNK) <<
                           LOG_NO_OF_FRAGS_PER_CHUNK;

786
    cfg.put(CFG_DIH_FRAG_CONNECT, 
787
	    noFragPerTable *  noOfMetaTables);
788 789 790 791 792 793 794 795 796
    
    int temp;
    temp = noOfReplicas - 2;
    if (temp < 0)
      temp = 1;
    else
      temp++;
    cfg.put(CFG_DIH_MORE_NODES, 
	    temp * NO_OF_FRAG_PER_NODE *
unknown's avatar
unknown committed
797
	    noOfMetaTables *  noOfDBNodes);
798

799
    cfg.put(CFG_DIH_REPLICAS, 
unknown's avatar
unknown committed
800
	    NO_OF_FRAG_PER_NODE * noOfMetaTables *
801 802 803
	    noOfDBNodes * noOfReplicas);

    cfg.put(CFG_DIH_TABLE, 
unknown's avatar
unknown committed
804
	    noOfMetaTables);
805 806 807 808 809 810 811
  }
  
  {
    /**
     * Lqh Size Alt values
     */
    cfg.put(CFG_LQH_FRAG, 
unknown's avatar
unknown committed
812
	    NO_OF_FRAG_PER_NODE * noOfMetaTables * noOfReplicas);
813 814
    
    cfg.put(CFG_LQH_TABLE, 
unknown's avatar
unknown committed
815
	    noOfMetaTables);
816 817

    cfg.put(CFG_LQH_TC_CONNECT, 
unknown's avatar
unknown committed
818
	    noOfLocalOperations + 50);
819 820 821 822 823 824 825 826 827 828 829 830 831
    
    cfg.put(CFG_LQH_SCAN, 
	    noOfLocalScanRecords);
  }
  
  {
    /**
     * Tc Size Alt values
     */
    cfg.put(CFG_TC_API_CONNECT, 
	    3 * noOfTransactions);
    
    cfg.put(CFG_TC_TC_CONNECT, 
832
	    (2 * noOfOperations) + 16 + noOfTransactions);
833 834
    
    cfg.put(CFG_TC_TABLE, 
unknown's avatar
unknown committed
835
	    noOfMetaTables);
836 837 838 839 840 841 842 843 844 845 846 847 848
    
    cfg.put(CFG_TC_LOCAL_SCAN, 
	    noOfLocalScanRecords);
    
    cfg.put(CFG_TC_SCAN, 
	    noOfTCScanRecords);
  }
  
  {
    /**
     * Tup Size Alt values
     */
    cfg.put(CFG_TUP_FRAG, 
unknown's avatar
unknown committed
849
	    2 * NO_OF_FRAG_PER_NODE * noOfMetaTables* noOfReplicas);
850 851
    
    cfg.put(CFG_TUP_OP_RECS, 
unknown's avatar
unknown committed
852
	    noOfLocalOperations + 50);
853 854 855 856 857
    
    cfg.put(CFG_TUP_PAGE, 
	    noOfDataPages);
    
    cfg.put(CFG_TUP_PAGE_RANGE, 
unknown's avatar
unknown committed
858
	    4 * NO_OF_FRAG_PER_NODE * noOfMetaTables* noOfReplicas);
859 860
    
    cfg.put(CFG_TUP_TABLE, 
unknown's avatar
unknown committed
861
	    noOfMetaTables);
862 863
    
    cfg.put(CFG_TUP_TABLE_DESC, 
864 865
	    2 * 6 * NO_OF_FRAG_PER_NODE * noOfAttributes * noOfReplicas +
	    2 * 10 * NO_OF_FRAG_PER_NODE * noOfMetaTables * noOfReplicas );
866 867 868 869 870 871 872 873 874 875
    
    cfg.put(CFG_TUP_STORED_PROC,
	    noOfLocalScanRecords);
  }

  {
    /**
     * Tux Size Alt values
     */
    cfg.put(CFG_TUX_INDEX, 
876
	    noOfMetaTables /*noOfOrderedIndexes*/);
877
    
878
    cfg.put(CFG_TUX_FRAGMENT,
unknown's avatar
unknown committed
879
	    2 * NO_OF_FRAG_PER_NODE * noOfOrderedIndexes * noOfReplicas);
880 881
    
    cfg.put(CFG_TUX_ATTRIBUTE, 
unknown's avatar
unknown committed
882
	    noOfOrderedIndexes * 4);
883 884 885 886 887 888 889 890 891

    cfg.put(CFG_TUX_SCAN_OP, noOfLocalScanRecords); 
  }

  m_ownConfig = (ndb_mgm_configuration*)cfg.getConfigValues();
  m_ownConfigIterator = ndb_mgm_create_configuration_iterator
    (m_ownConfig, 0);
}

892 893 894 895
void
Configuration::setInitialStart(bool val){
  _initialStart = val;
}