~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

Viewing changes to storage/ndb/src/kernel/vm/Configuration.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2003 MySQL AB
 
2
 
 
3
   This program is free software; you can redistribute it and/or modify
 
4
   it under the terms of the GNU General Public License as published by
 
5
   the Free Software Foundation; version 2 of the License.
 
6
 
 
7
   This program is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
   GNU General Public License for more details.
 
11
 
 
12
   You should have received a copy of the GNU General Public License
 
13
   along with this program; if not, write to the Free Software
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
15
 
 
16
#include <ndb_global.h>
 
17
#include <ndb_opts.h>
 
18
 
 
19
#include "Configuration.hpp"
 
20
#include <ErrorHandlingMacros.hpp>
 
21
#include "GlobalData.hpp"
 
22
 
 
23
#include <ConfigRetriever.hpp>
 
24
#include <IPCConfig.hpp>
 
25
#include <ndb_version.h>
 
26
#include <NdbMem.h>
 
27
#include <NdbOut.hpp>
 
28
#include <WatchDog.hpp>
 
29
 
 
30
#include <mgmapi_configuration.hpp>
 
31
#include <mgmapi_config_parameters_debug.h>
 
32
#include <kernel_config_parameters.h>
 
33
 
 
34
#include <kernel_types.h>
 
35
#include <ndb_limits.h>
 
36
#include <ndbapi_limits.h>
 
37
#include "pc.hpp"
 
38
#include <LogLevel.hpp>
 
39
#include <NdbSleep.h>
 
40
 
 
41
extern "C" {
 
42
  void ndbSetOwnVersion();
 
43
}
 
44
 
 
45
#include <EventLogger.hpp>
 
46
extern EventLogger g_eventLogger;
 
47
 
 
48
enum ndbd_options {
 
49
  OPT_INITIAL = NDB_STD_OPTIONS_LAST,
 
50
  OPT_NODAEMON,
 
51
  OPT_FOREGROUND,
 
52
  OPT_NOWAIT_NODES,
 
53
  OPT_INITIAL_START
 
54
};
 
55
 
 
56
NDB_STD_OPTS_VARS;
 
57
// XXX should be my_bool ???
 
58
static int _daemon, _no_daemon, _foreground,  _initial, _no_start;
 
59
static int _initialstart;
 
60
static const char* _nowait_nodes = 0;
 
61
static const char* _bind_address = 0;
 
62
 
 
63
extern Uint32 g_start_type;
 
64
extern NdbNodeBitmask g_nowait_nodes;
 
65
 
 
66
const char *load_default_groups[]= { "mysql_cluster","ndbd",0 };
 
67
 
 
68
/**
 
69
 * Arguments to NDB process
 
70
 */ 
 
71
static struct my_option my_long_options[] =
 
72
{
 
73
  NDB_STD_OPTS("ndbd"),
 
74
  { "initial", OPT_INITIAL,
 
75
    "Perform initial start of ndbd, including cleaning the file system. "
 
76
    "Consult documentation before using this",
 
77
    (uchar**) &_initial, (uchar**) &_initial, 0,
 
78
    GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
 
79
  { "nostart", 'n',
 
80
    "Don't start ndbd immediately. Ndbd will await command from ndb_mgmd",
 
81
    (uchar**) &_no_start, (uchar**) &_no_start, 0,
 
82
    GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
 
83
  { "daemon", 'd', "Start ndbd as daemon (default)",
 
84
    (uchar**) &_daemon, (uchar**) &_daemon, 0,
 
85
    GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0 },
 
86
  { "nodaemon", OPT_NODAEMON,
 
87
    "Do not start ndbd as daemon, provided for testing purposes",
 
88
    (uchar**) &_no_daemon, (uchar**) &_no_daemon, 0,
 
89
    GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
 
90
  { "foreground", OPT_FOREGROUND,
 
91
    "Run real ndbd in foreground, provided for debugging purposes"
 
92
    " (implies --nodaemon)",
 
93
    (uchar**) &_foreground, (uchar**) &_foreground, 0,
 
94
    GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
 
95
  { "nowait-nodes", OPT_NOWAIT_NODES, 
 
96
    "Nodes that will not be waited for during start",
 
97
    (uchar**) &_nowait_nodes, (uchar**) &_nowait_nodes, 0,
 
98
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
 
99
  { "initial-start", OPT_INITIAL_START, 
 
100
    "Perform initial start",
 
101
    (uchar**) &_initialstart, (uchar**) &_initialstart, 0,
 
102
    GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
 
103
  { "bind-address", OPT_NOWAIT_NODES, 
 
104
    "Local bind address",
 
105
    (uchar**) &_bind_address, (uchar**) &_bind_address, 0,
 
106
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
 
107
  { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
 
108
};
 
109
static void short_usage_sub(void)
 
110
{
 
111
  printf("Usage: %s [OPTIONS]\n", my_progname);
 
112
}
 
113
static void usage()
 
114
{
 
115
  short_usage_sub();
 
116
  ndb_std_print_version();
 
117
  print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
 
118
  puts("");
 
119
  my_print_help(my_long_options);
 
120
  my_print_variables(my_long_options);
 
121
}
 
122
 
 
123
bool
 
124
Configuration::init(int argc, char** argv)
 
125
{  
 
126
  load_defaults("my",load_default_groups,&argc,&argv);
 
127
 
 
128
  int ho_error;
 
129
#ifndef DBUG_OFF
 
130
  opt_debug= "d:t:O,/tmp/ndbd.trace";
 
131
#endif
 
132
  if ((ho_error=handle_options(&argc, &argv, my_long_options,
 
133
                               ndb_std_get_one_option)))
 
134
    exit(ho_error);
 
135
 
 
136
  if (_no_daemon || _foreground) {
 
137
    _daemon= 0;
 
138
  }
 
139
 
 
140
  DBUG_PRINT("info", ("no_start=%d", _no_start));
 
141
  DBUG_PRINT("info", ("initial=%d", _initial));
 
142
  DBUG_PRINT("info", ("daemon=%d", _daemon));
 
143
  DBUG_PRINT("info", ("foreground=%d", _foreground));
 
144
  DBUG_PRINT("info", ("connect_str=%s", opt_connect_str));
 
145
 
 
146
  ndbSetOwnVersion();
 
147
 
 
148
  // Check the start flag
 
149
  if (_no_start)
 
150
    globalData.theRestartFlag = initial_state;
 
151
  else 
 
152
    globalData.theRestartFlag = perform_start;
 
153
 
 
154
  // Check the initial flag
 
155
  if (_initial)
 
156
    _initialStart = true;
 
157
  
 
158
  // Check connectstring
 
159
  if (opt_connect_str)
 
160
    _connectString = strdup(opt_connect_str);
 
161
  
 
162
  // Check daemon flag
 
163
  if (_daemon)
 
164
    _daemonMode = true;
 
165
  if (_foreground)
 
166
    _foregroundMode = true;
 
167
 
 
168
  // Save programname
 
169
  if(argc > 0 && argv[0] != 0)
 
170
    _programName = strdup(argv[0]);
 
171
  else
 
172
    _programName = strdup("");
 
173
  
 
174
  globalData.ownId= 0;
 
175
 
 
176
  if (_nowait_nodes)
 
177
  {
 
178
    BaseString str(_nowait_nodes);
 
179
    Vector<BaseString> arr;
 
180
    str.split(arr, ",");
 
181
    for (Uint32 i = 0; i<arr.size(); i++)
 
182
    {
 
183
      char *endptr = 0;
 
184
      long val = strtol(arr[i].c_str(), &endptr, 10);
 
185
      if (*endptr)
 
186
      {
 
187
        ndbout_c("Unable to parse nowait-nodes argument: %s : %s", 
 
188
                 arr[i].c_str(), _nowait_nodes);
 
189
        exit(-1);
 
190
      }
 
191
      if (! (val > 0 && val < MAX_NDB_NODES))
 
192
      {
 
193
        ndbout_c("Invalid nodeid specified in nowait-nodes: %ld : %s", 
 
194
                 val, _nowait_nodes);
 
195
        exit(-1);
 
196
      }
 
197
      g_nowait_nodes.set(val);
 
198
    }
 
199
  }
 
200
 
 
201
  if (_initialstart)
 
202
  {
 
203
    _initialStart = true;
 
204
    g_start_type |= (1 << NodeState::ST_INITIAL_START);
 
205
  }
 
206
  
 
207
  return true;
 
208
}
 
209
 
 
210
Configuration::Configuration()
 
211
{
 
212
  _programName = 0;
 
213
  _connectString = 0;
 
214
  _fsPath = 0;
 
215
  _backupPath = 0;
 
216
  _initialStart = false;
 
217
  _daemonMode = false;
 
218
  _foregroundMode = false;
 
219
  m_config_retriever= 0;
 
220
  m_clusterConfig= 0;
 
221
  m_clusterConfigIter= 0;
 
222
  m_logLevel= 0;
 
223
}
 
224
 
 
225
Configuration::~Configuration(){
 
226
  if (opt_connect_str)
 
227
    free(_connectString);
 
228
 
 
229
  if(_programName != NULL)
 
230
    free(_programName);
 
231
 
 
232
  if(_fsPath != NULL)
 
233
    free(_fsPath);
 
234
 
 
235
  if(_backupPath != NULL)
 
236
    free(_backupPath);
 
237
 
 
238
  if (m_config_retriever) {
 
239
    delete m_config_retriever;
 
240
  }
 
241
 
 
242
  if(m_logLevel) {
 
243
    delete m_logLevel;
 
244
  }
 
245
}
 
246
 
 
247
void
 
248
Configuration::closeConfiguration(bool end_session){
 
249
  m_config_retriever->end_session(end_session);
 
250
  if (m_config_retriever) {
 
251
    delete m_config_retriever;
 
252
  }
 
253
  m_config_retriever= 0;
 
254
}
 
255
 
 
256
void
 
257
Configuration::fetch_configuration(){
 
258
  /**
 
259
   * Fetch configuration from management server
 
260
   */
 
261
  if (m_config_retriever) {
 
262
    delete m_config_retriever;
 
263
  }
 
264
 
 
265
  m_mgmd_port= 0;
 
266
  m_config_retriever= new ConfigRetriever(getConnectString(),
 
267
                                          NDB_VERSION, 
 
268
                                          NODE_TYPE_DB,
 
269
                                          _bind_address);
 
270
 
 
271
  if (m_config_retriever->hasError())
 
272
  {
 
273
    ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG,
 
274
              "Could not connect initialize handle to management server",
 
275
              m_config_retriever->getErrorString());
 
276
  }
 
277
 
 
278
  if(m_config_retriever->do_connect(12,5,1) == -1){
 
279
    const char * s = m_config_retriever->getErrorString();
 
280
    if(s == 0)
 
281
      s = "No error given!";
 
282
    /* Set stop on error to true otherwise NDB will
 
283
       go into an restart loop...
 
284
    */
 
285
    ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Could not connect to ndb_mgmd", s);
 
286
  }
 
287
  
 
288
  m_mgmd_port= m_config_retriever->get_mgmd_port();
 
289
  m_mgmd_host.assign(m_config_retriever->get_mgmd_host());
 
290
 
 
291
  ConfigRetriever &cr= *m_config_retriever;
 
292
  
 
293
  /**
 
294
   * if we have a nodeid set (e.g in a restart situation)
 
295
   * reuse it
 
296
   */
 
297
  if (globalData.ownId)
 
298
    cr.setNodeId(globalData.ownId);
 
299
 
 
300
  globalData.ownId = cr.allocNodeId(globalData.ownId ? 10 : 2 /*retry*/,
 
301
                                    3 /*delay*/);
 
302
  
 
303
  if(globalData.ownId == 0){
 
304
    ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, 
 
305
              "Unable to alloc node id", m_config_retriever->getErrorString());
 
306
  }
 
307
  
 
308
  ndb_mgm_configuration * p = cr.getConfig();
 
309
  if(p == 0){
 
310
    const char * s = cr.getErrorString();
 
311
    if(s == 0)
 
312
      s = "No error given!";
 
313
    
 
314
    /* Set stop on error to true otherwise NDB will
 
315
       go into an restart loop...
 
316
    */
 
317
    
 
318
    ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Could not fetch configuration"
 
319
              "/invalid configuration", s);
 
320
  }
 
321
  if(m_clusterConfig)
 
322
    free(m_clusterConfig);
 
323
  
 
324
  m_clusterConfig = p;
 
325
  
 
326
  ndb_mgm_configuration_iterator iter(* p, CFG_SECTION_NODE);
 
327
  if (iter.find(CFG_NODE_ID, globalData.ownId)){
 
328
    ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Invalid configuration fetched", "DB missing");
 
329
  }
 
330
  
 
331
  if(iter.get(CFG_DB_STOP_ON_ERROR, &_stopOnError)){
 
332
    ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Invalid configuration fetched", 
 
333
              "StopOnError missing");
 
334
  }
 
335
 
 
336
  m_mgmds.clear();
 
337
  for(ndb_mgm_first(&iter); ndb_mgm_valid(&iter); ndb_mgm_next(&iter))
 
338
  {
 
339
    Uint32 nodeType, port;
 
340
    char const *hostname;
 
341
 
 
342
    ndb_mgm_get_int_parameter(&iter,CFG_TYPE_OF_SECTION,&nodeType);
 
343
 
 
344
    if (nodeType != NodeInfo::MGM)
 
345
      continue;
 
346
 
 
347
    if (ndb_mgm_get_string_parameter(&iter,CFG_NODE_HOST, &hostname) ||
 
348
        ndb_mgm_get_int_parameter(&iter,CFG_MGM_PORT, &port) ||
 
349
        hostname == 0 || hostname[0] == 0)
 
350
    {
 
351
      continue;
 
352
    }
 
353
    BaseString connectstring(hostname);
 
354
    connectstring.appfmt(":%d", port);
 
355
 
 
356
    m_mgmds.push_back(connectstring);
 
357
  }
 
358
}
 
359
 
 
360
static char * get_and_validate_path(ndb_mgm_configuration_iterator &iter,
 
361
                                    Uint32 param, const char *param_string)
 
362
 
363
  const char* path = NULL;
 
364
  if(iter.get(param, &path)){
 
365
    ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Invalid configuration fetched missing ", 
 
366
              param_string);
 
367
  } 
 
368
  
 
369
  if(path == 0 || strlen(path) == 0){
 
370
    ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG,
 
371
              "Invalid configuration fetched. Configuration does not contain valid ",
 
372
              param_string);
 
373
  }
 
374
  
 
375
  // check that it is pointing on a valid directory
 
376
  // 
 
377
  char buf2[PATH_MAX];
 
378
  memset(buf2, 0,sizeof(buf2));
 
379
#ifdef NDB_WIN32
 
380
  char* szFilePart;
 
381
  if(!GetFullPathName(path, sizeof(buf2), buf2, &szFilePart) ||
 
382
     (GetFileAttributes(buf2) & FILE_ATTRIBUTE_READONLY))
 
383
#else
 
384
  if((::realpath(path, buf2) == NULL)||
 
385
       (::access(buf2, W_OK) != 0))
 
386
#endif
 
387
  {
 
388
    ERROR_SET(fatal, NDBD_EXIT_AFS_INVALIDPATH, path, param_string);
 
389
  }
 
390
  
 
391
  if (strcmp(&buf2[strlen(buf2) - 1], DIR_SEPARATOR))
 
392
    strcat(buf2, DIR_SEPARATOR);
 
393
  
 
394
  return strdup(buf2);
 
395
}
 
396
 
 
397
void
 
398
Configuration::setupConfiguration(){
 
399
 
 
400
  DBUG_ENTER("Configuration::setupConfiguration");
 
401
 
 
402
  ndb_mgm_configuration * p = m_clusterConfig;
 
403
 
 
404
  /**
 
405
   * Configure transporters
 
406
   */
 
407
  {  
 
408
    int res = IPCConfig::configureTransporters(globalData.ownId,
 
409
                                               * p, 
 
410
                                               globalTransporterRegistry);
 
411
    if(res <= 0){
 
412
      ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Invalid configuration fetched", 
 
413
                "No transporters configured");
 
414
    }
 
415
  }
 
416
 
 
417
  /**
 
418
   * Setup cluster configuration data
 
419
   */
 
420
  ndb_mgm_configuration_iterator iter(* p, CFG_SECTION_NODE);
 
421
  if (iter.find(CFG_NODE_ID, globalData.ownId)){
 
422
    ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Invalid configuration fetched", "DB missing");
 
423
  }
 
424
 
 
425
  unsigned type;
 
426
  if(!(iter.get(CFG_TYPE_OF_SECTION, &type) == 0 && type == NODE_TYPE_DB)){
 
427
    ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Invalid configuration fetched",
 
428
              "I'm wrong type of node");
 
429
  }
 
430
  
 
431
  if(iter.get(CFG_DB_NO_SAVE_MSGS, &_maxErrorLogs)){
 
432
    ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Invalid configuration fetched", 
 
433
              "MaxNoOfSavedMessages missing");
 
434
  }
 
435
  
 
436
  if(iter.get(CFG_DB_MEMLOCK, &_lockPagesInMainMemory)){
 
437
    ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Invalid configuration fetched", 
 
438
              "LockPagesInMainMemory missing");
 
439
  }
 
440
 
 
441
  if(iter.get(CFG_DB_WATCHDOG_INTERVAL, &_timeBetweenWatchDogCheck)){
 
442
    ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Invalid configuration fetched", 
 
443
              "TimeBetweenWatchDogCheck missing");
 
444
  }
 
445
 
 
446
  if(iter.get(CFG_DB_WATCHDOG_INTERVAL_INITIAL, &_timeBetweenWatchDogCheckInitial)){
 
447
    ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Invalid configuration fetched", 
 
448
              "TimeBetweenWatchDogCheckInitial missing");
 
449
  }
 
450
 
 
451
  /**
 
452
   * Get paths
 
453
   */  
 
454
  if (_fsPath)
 
455
    free(_fsPath);
 
456
  _fsPath= get_and_validate_path(iter, CFG_DB_FILESYSTEM_PATH, "FileSystemPath");
 
457
  if (_backupPath)
 
458
    free(_backupPath);
 
459
  _backupPath= get_and_validate_path(iter, CFG_DB_BACKUP_DATADIR, "BackupDataDir");
 
460
 
 
461
  if(iter.get(CFG_DB_STOP_ON_ERROR_INSERT, &m_restartOnErrorInsert)){
 
462
    ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, "Invalid configuration fetched", 
 
463
              "RestartOnErrorInsert missing");
 
464
  }
 
465
 
 
466
  /**
 
467
   * Create the watch dog thread
 
468
   */
 
469
  { 
 
470
    if (_timeBetweenWatchDogCheckInitial < _timeBetweenWatchDogCheck)
 
471
      _timeBetweenWatchDogCheckInitial = _timeBetweenWatchDogCheck;
 
472
 
 
473
    Uint32 t = _timeBetweenWatchDogCheckInitial;
 
474
    t = globalEmulatorData.theWatchDog ->setCheckInterval(t);
 
475
    _timeBetweenWatchDogCheckInitial = t;
 
476
  }
 
477
  
 
478
  ConfigValues* cf = ConfigValuesFactory::extractCurrentSection(iter.m_config);
 
479
 
 
480
  if(m_clusterConfigIter)
 
481
    ndb_mgm_destroy_iterator(m_clusterConfigIter);
 
482
  m_clusterConfigIter = ndb_mgm_create_configuration_iterator
 
483
    (p, CFG_SECTION_NODE);
 
484
 
 
485
  calcSizeAlt(cf);
 
486
 
 
487
  DBUG_VOID_RETURN;
 
488
}
 
489
 
 
490
Uint32
 
491
Configuration::lockPagesInMainMemory() const {
 
492
  return _lockPagesInMainMemory;
 
493
}
 
494
 
 
495
int 
 
496
Configuration::timeBetweenWatchDogCheck() const {
 
497
  return _timeBetweenWatchDogCheck;
 
498
}
 
499
 
 
500
void 
 
501
Configuration::timeBetweenWatchDogCheck(int value) {
 
502
  _timeBetweenWatchDogCheck = value;
 
503
}
 
504
 
 
505
int 
 
506
Configuration::maxNoOfErrorLogs() const {
 
507
  return _maxErrorLogs;
 
508
}
 
509
 
 
510
void 
 
511
Configuration::maxNoOfErrorLogs(int val){
 
512
  _maxErrorLogs = val;
 
513
}
 
514
 
 
515
bool
 
516
Configuration::stopOnError() const {
 
517
  return _stopOnError;
 
518
}
 
519
 
 
520
void 
 
521
Configuration::stopOnError(bool val){
 
522
  _stopOnError = val;
 
523
}
 
524
 
 
525
int
 
526
Configuration::getRestartOnErrorInsert() const {
 
527
  return m_restartOnErrorInsert;
 
528
}
 
529
 
 
530
void
 
531
Configuration::setRestartOnErrorInsert(int i){
 
532
  m_restartOnErrorInsert = i;
 
533
}
 
534
 
 
535
const char *
 
536
Configuration::getConnectString() const {
 
537
  return _connectString;
 
538
}
 
539
 
 
540
char *
 
541
Configuration::getConnectStringCopy() const {
 
542
  if(_connectString != 0)
 
543
    return strdup(_connectString);
 
544
  return 0;
 
545
}
 
546
 
 
547
const ndb_mgm_configuration_iterator * 
 
548
Configuration::getOwnConfigIterator() const {
 
549
  return m_ownConfigIterator;
 
550
}
 
551
  
 
552
ndb_mgm_configuration_iterator * 
 
553
Configuration::getClusterConfigIterator() const {
 
554
  return m_clusterConfigIter;
 
555
}
 
556
 
 
557
void
 
558
Configuration::calcSizeAlt(ConfigValues * ownConfig){
 
559
  const char * msg = "Invalid configuration fetched";
 
560
  char buf[255];
 
561
 
 
562
  unsigned int noOfTables = 0;
 
563
  unsigned int noOfUniqueHashIndexes = 0;
 
564
  unsigned int noOfOrderedIndexes = 0;
 
565
  unsigned int noOfTriggers = 0;
 
566
  unsigned int noOfReplicas = 0;
 
567
  unsigned int noOfDBNodes = 0;
 
568
  unsigned int noOfAPINodes = 0;
 
569
  unsigned int noOfMGMNodes = 0;
 
570
  unsigned int noOfNodes = 0;
 
571
  unsigned int noOfAttributes = 0;
 
572
  unsigned int noOfOperations = 0;
 
573
  unsigned int noOfLocalOperations = 0;
 
574
  unsigned int noOfTransactions = 0;
 
575
  unsigned int noOfIndexPages = 0;
 
576
  unsigned int noOfDataPages = 0;
 
577
  unsigned int noOfScanRecords = 0;
 
578
  unsigned int noOfLocalScanRecords = 0;
 
579
  unsigned int noBatchSize = 0;
 
580
  m_logLevel = new LogLevel();
 
581
  
 
582
  struct AttribStorage { int paramId; Uint32 * storage; bool computable; };
 
583
  AttribStorage tmp[] = {
 
584
    { CFG_DB_NO_SCANS, &noOfScanRecords, false },
 
585
    { CFG_DB_NO_LOCAL_SCANS, &noOfLocalScanRecords, true },
 
586
    { CFG_DB_BATCH_SIZE, &noBatchSize, false },
 
587
    { CFG_DB_NO_TABLES, &noOfTables, false },
 
588
    { CFG_DB_NO_ORDERED_INDEXES, &noOfOrderedIndexes, false },
 
589
    { CFG_DB_NO_UNIQUE_HASH_INDEXES, &noOfUniqueHashIndexes, false },
 
590
    { CFG_DB_NO_TRIGGERS, &noOfTriggers, true },
 
591
    { CFG_DB_NO_REPLICAS, &noOfReplicas, false },
 
592
    { CFG_DB_NO_ATTRIBUTES, &noOfAttributes, false },
 
593
    { CFG_DB_NO_OPS, &noOfOperations, false },
 
594
    { CFG_DB_NO_LOCAL_OPS, &noOfLocalOperations, true },
 
595
    { CFG_DB_NO_TRANSACTIONS, &noOfTransactions, false }
 
596
  };
 
597
 
 
598
  ndb_mgm_configuration_iterator db(*(ndb_mgm_configuration*)ownConfig, 0);
 
599
  
 
600
  const int sz = sizeof(tmp)/sizeof(AttribStorage);
 
601
  for(int i = 0; i<sz; i++){
 
602
    if(ndb_mgm_get_int_parameter(&db, tmp[i].paramId, tmp[i].storage)){
 
603
      if (tmp[i].computable) {
 
604
        *tmp[i].storage = 0;
 
605
      } else {
 
606
        BaseString::snprintf(buf, sizeof(buf),"ConfigParam: %d not found", tmp[i].paramId);
 
607
        ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, msg, buf);
 
608
      }
 
609
    }
 
610
  }
 
611
 
 
612
  Uint64 indexMem = 0, dataMem = 0;
 
613
  ndb_mgm_get_int64_parameter(&db, CFG_DB_DATA_MEM, &dataMem);
 
614
  ndb_mgm_get_int64_parameter(&db, CFG_DB_INDEX_MEM, &indexMem);
 
615
  if(dataMem == 0){
 
616
    BaseString::snprintf(buf, sizeof(buf), "ConfigParam: %d not found", CFG_DB_DATA_MEM);
 
617
    ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, msg, buf);
 
618
  }
 
619
 
 
620
  if(indexMem == 0){
 
621
    BaseString::snprintf(buf, sizeof(buf), "ConfigParam: %d not found", CFG_DB_INDEX_MEM);
 
622
    ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, msg, buf);
 
623
  }
 
624
 
 
625
  noOfDataPages = (dataMem / 32768);
 
626
  noOfIndexPages = (indexMem / 8192);
 
627
 
 
628
  for(unsigned j = 0; j<LogLevel::LOGLEVEL_CATEGORIES; j++){
 
629
    Uint32 tmp;
 
630
    if(!ndb_mgm_get_int_parameter(&db, CFG_MIN_LOGLEVEL+j, &tmp)){
 
631
      m_logLevel->setLogLevel((LogLevel::EventCategory)j, tmp);
 
632
    }
 
633
  }
 
634
  
 
635
  // tmp
 
636
  ndb_mgm_configuration_iterator * p = m_clusterConfigIter;
 
637
 
 
638
  Uint32 nodeNo = noOfNodes = 0;
 
639
  NodeBitmask nodes;
 
640
  for(ndb_mgm_first(p); ndb_mgm_valid(p); ndb_mgm_next(p), nodeNo++){
 
641
    
 
642
    Uint32 nodeId;
 
643
    Uint32 nodeType;
 
644
    
 
645
    if(ndb_mgm_get_int_parameter(p, CFG_NODE_ID, &nodeId)){
 
646
      ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, msg, "Node data (Id) missing");
 
647
    }
 
648
    
 
649
    if(ndb_mgm_get_int_parameter(p, CFG_TYPE_OF_SECTION, &nodeType)){
 
650
      ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, msg, "Node data (Type) missing");
 
651
    }
 
652
    
 
653
    if(nodeId > MAX_NODES || nodeId == 0){
 
654
      BaseString::snprintf(buf, sizeof(buf),
 
655
               "Invalid node id: %d", nodeId);
 
656
      ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, msg, buf);
 
657
    }
 
658
    
 
659
    if(nodes.get(nodeId)){
 
660
      BaseString::snprintf(buf, sizeof(buf), "Two node can not have the same node id: %d",
 
661
               nodeId);
 
662
      ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, msg, buf);
 
663
    }
 
664
    nodes.set(nodeId);
 
665
        
 
666
    switch(nodeType){
 
667
    case NODE_TYPE_DB:
 
668
      noOfDBNodes++; // No of NDB processes
 
669
      
 
670
      if(nodeId > MAX_NDB_NODES){
 
671
                  BaseString::snprintf(buf, sizeof(buf), "Maximum node id for a ndb node is: %d", 
 
672
                 MAX_NDB_NODES);
 
673
        ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, msg, buf);
 
674
      }
 
675
      break;
 
676
    case NODE_TYPE_API:
 
677
      noOfAPINodes++; // No of API processes
 
678
      break;
 
679
    case NODE_TYPE_MGM:
 
680
      noOfMGMNodes++; // No of MGM processes
 
681
      break;
 
682
    default:
 
683
      BaseString::snprintf(buf, sizeof(buf), "Unknown node type: %d", nodeType);
 
684
      ERROR_SET(fatal, NDBD_EXIT_INVALID_CONFIG, msg, buf);
 
685
    }
 
686
  }
 
687
  noOfNodes = nodeNo;
 
688
 
 
689
  noOfTables+= 2; // Add System tables
 
690
  noOfAttributes += 9;  // Add System table attributes
 
691
 
 
692
  ConfigValues::Iterator it2(*ownConfig, db.m_config);
 
693
  it2.set(CFG_DB_NO_TABLES, noOfTables);
 
694
  it2.set(CFG_DB_NO_ATTRIBUTES, noOfAttributes);
 
695
  {
 
696
    Uint32 neededNoOfTriggers =   /* types: Insert/Update/Delete/Custom */
 
697
      3 * noOfUniqueHashIndexes + /* for unique hash indexes, I/U/D */
 
698
      3 * NDB_MAX_ACTIVE_EVENTS + /* for events in suma, I/U/D */
 
699
      3 * noOfTables +            /* for backup, I/U/D */
 
700
      noOfOrderedIndexes;         /* for ordered indexes, C */
 
701
    if (noOfTriggers < neededNoOfTriggers)
 
702
    {
 
703
      noOfTriggers= neededNoOfTriggers;
 
704
      it2.set(CFG_DB_NO_TRIGGERS, noOfTriggers);
 
705
    }
 
706
  }
 
707
 
 
708
  /**
 
709
   * Do size calculations
 
710
   */
 
711
  ConfigValuesFactory cfg(ownConfig);
 
712
 
 
713
  Uint32 noOfMetaTables= noOfTables + noOfOrderedIndexes +
 
714
                           noOfUniqueHashIndexes;
 
715
  Uint32 noOfMetaTablesDict= noOfMetaTables;
 
716
  if (noOfMetaTablesDict > MAX_TABLES)
 
717
    noOfMetaTablesDict= MAX_TABLES;
 
718
 
 
719
  {
 
720
    /**
 
721
     * Dict Size Alt values
 
722
     */
 
723
    cfg.put(CFG_DICT_ATTRIBUTE, 
 
724
            noOfAttributes);
 
725
 
 
726
    cfg.put(CFG_DICT_TABLE,
 
727
            noOfMetaTablesDict);
 
728
  }
 
729
 
 
730
 
 
731
  if (noOfLocalScanRecords == 0) {
 
732
    noOfLocalScanRecords = (noOfDBNodes * noOfScanRecords) + 1;
 
733
  }
 
734
  if (noOfLocalOperations == 0) {
 
735
    noOfLocalOperations= (11 * noOfOperations) / 10;
 
736
  }
 
737
  Uint32 noOfTCScanRecords = noOfScanRecords;
 
738
 
 
739
  {
 
740
    Uint32 noOfAccTables= noOfMetaTables/*noOfTables+noOfUniqueHashIndexes*/;
 
741
    /**
 
742
     * Acc Size Alt values
 
743
     */
 
744
    // Can keep 65536 pages (= 0.5 GByte)
 
745
    cfg.put(CFG_ACC_DIR_RANGE, 
 
746
            2 * NO_OF_FRAG_PER_NODE * noOfAccTables* noOfReplicas); 
 
747
    
 
748
    cfg.put(CFG_ACC_DIR_ARRAY,
 
749
            (noOfIndexPages >> 8) + 
 
750
            2 * NO_OF_FRAG_PER_NODE * noOfAccTables* noOfReplicas);
 
751
    
 
752
    cfg.put(CFG_ACC_FRAGMENT,
 
753
            NO_OF_FRAG_PER_NODE * noOfAccTables* noOfReplicas);
 
754
    
 
755
    /*-----------------------------------------------------------------------*/
 
756
    // The extra operation records added are used by the scan and node 
 
757
    // recovery process. 
 
758
    // Node recovery process will have its operations dedicated to ensure
 
759
    // that they never have a problem with allocation of the operation record.
 
760
    // The remainder are allowed for use by the scan processes.
 
761
    /*-----------------------------------------------------------------------*/
 
762
    cfg.put(CFG_ACC_OP_RECS,
 
763
            (noOfLocalOperations + 50) + 
 
764
            (noOfLocalScanRecords * noBatchSize) +
 
765
            NODE_RECOVERY_SCAN_OP_RECORDS);
 
766
    
 
767
    cfg.put(CFG_ACC_OVERFLOW_RECS,
 
768
            noOfIndexPages + 
 
769
            NO_OF_FRAG_PER_NODE * noOfAccTables* noOfReplicas);
 
770
    
 
771
    cfg.put(CFG_ACC_PAGE8, 
 
772
            noOfIndexPages + 32);
 
773
    
 
774
    cfg.put(CFG_ACC_TABLE, noOfAccTables);
 
775
    
 
776
    cfg.put(CFG_ACC_SCAN, noOfLocalScanRecords);
 
777
  }
 
778
  
 
779
  {
 
780
    /**
 
781
     * Dih Size Alt values
 
782
     */
 
783
    cfg.put(CFG_DIH_API_CONNECT, 
 
784
            2 * noOfTransactions);
 
785
    
 
786
    cfg.put(CFG_DIH_CONNECT, 
 
787
            noOfOperations + noOfTransactions + 46);
 
788
    
 
789
    Uint32 noFragPerTable= ((noOfDBNodes + NO_OF_FRAGS_PER_CHUNK - 1) >>
 
790
                           LOG_NO_OF_FRAGS_PER_CHUNK) <<
 
791
                           LOG_NO_OF_FRAGS_PER_CHUNK;
 
792
 
 
793
    cfg.put(CFG_DIH_FRAG_CONNECT, 
 
794
            noFragPerTable *  noOfMetaTables);
 
795
    
 
796
    int temp;
 
797
    temp = noOfReplicas - 2;
 
798
    if (temp < 0)
 
799
      temp = 1;
 
800
    else
 
801
      temp++;
 
802
    cfg.put(CFG_DIH_MORE_NODES, 
 
803
            temp * NO_OF_FRAG_PER_NODE *
 
804
            noOfMetaTables *  noOfDBNodes);
 
805
 
 
806
    cfg.put(CFG_DIH_REPLICAS, 
 
807
            NO_OF_FRAG_PER_NODE * noOfMetaTables *
 
808
            noOfDBNodes * noOfReplicas);
 
809
 
 
810
    cfg.put(CFG_DIH_TABLE, 
 
811
            noOfMetaTables);
 
812
  }
 
813
  
 
814
  {
 
815
    /**
 
816
     * Lqh Size Alt values
 
817
     */
 
818
    cfg.put(CFG_LQH_FRAG, 
 
819
            NO_OF_FRAG_PER_NODE * noOfMetaTables * noOfReplicas);
 
820
    
 
821
    cfg.put(CFG_LQH_TABLE, 
 
822
            noOfMetaTables);
 
823
 
 
824
    cfg.put(CFG_LQH_TC_CONNECT, 
 
825
            noOfLocalOperations + 50);
 
826
    
 
827
    cfg.put(CFG_LQH_SCAN, 
 
828
            noOfLocalScanRecords);
 
829
  }
 
830
  
 
831
  {
 
832
    /**
 
833
     * Tc Size Alt values
 
834
     */
 
835
    cfg.put(CFG_TC_API_CONNECT, 
 
836
            3 * noOfTransactions);
 
837
    
 
838
    cfg.put(CFG_TC_TC_CONNECT, 
 
839
            (2 * noOfOperations) + 16 + noOfTransactions);
 
840
    
 
841
    cfg.put(CFG_TC_TABLE, 
 
842
            noOfMetaTables);
 
843
    
 
844
    cfg.put(CFG_TC_LOCAL_SCAN, 
 
845
            noOfLocalScanRecords);
 
846
    
 
847
    cfg.put(CFG_TC_SCAN, 
 
848
            noOfTCScanRecords);
 
849
  }
 
850
  
 
851
  {
 
852
    /**
 
853
     * Tup Size Alt values
 
854
     */
 
855
    cfg.put(CFG_TUP_FRAG, 
 
856
            NO_OF_FRAG_PER_NODE * noOfMetaTables* noOfReplicas);
 
857
    
 
858
    cfg.put(CFG_TUP_OP_RECS, 
 
859
            noOfLocalOperations + 50);
 
860
    
 
861
    cfg.put(CFG_TUP_PAGE, 
 
862
            noOfDataPages);
 
863
    
 
864
    cfg.put(CFG_TUP_PAGE_RANGE, 
 
865
            2 * NO_OF_FRAG_PER_NODE * noOfMetaTables* noOfReplicas);
 
866
    
 
867
    cfg.put(CFG_TUP_TABLE, 
 
868
            noOfMetaTables);
 
869
    
 
870
    cfg.put(CFG_TUP_TABLE_DESC, 
 
871
            6 * NO_OF_FRAG_PER_NODE * noOfAttributes * noOfReplicas +
 
872
            10 * NO_OF_FRAG_PER_NODE * noOfMetaTables * noOfReplicas );
 
873
    
 
874
    cfg.put(CFG_TUP_STORED_PROC,
 
875
            noOfLocalScanRecords);
 
876
  }
 
877
 
 
878
  {
 
879
    /**
 
880
     * Tux Size Alt values
 
881
     */
 
882
    cfg.put(CFG_TUX_INDEX, 
 
883
            noOfMetaTables /*noOfOrderedIndexes*/);
 
884
    
 
885
    cfg.put(CFG_TUX_FRAGMENT,
 
886
            NO_OF_FRAG_PER_NODE * noOfOrderedIndexes * noOfReplicas);
 
887
    
 
888
    cfg.put(CFG_TUX_ATTRIBUTE, 
 
889
            noOfOrderedIndexes * 4);
 
890
 
 
891
    cfg.put(CFG_TUX_SCAN_OP, noOfLocalScanRecords); 
 
892
  }
 
893
 
 
894
  m_ownConfig = (ndb_mgm_configuration*)cfg.getConfigValues();
 
895
  m_ownConfigIterator = ndb_mgm_create_configuration_iterator
 
896
    (m_ownConfig, 0);
 
897
}
 
898
 
 
899
void
 
900
Configuration::setInitialStart(bool val){
 
901
  _initialStart = val;
 
902
}