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

« back to all changes in this revision

Viewing changes to storage/ndb/src/mgmsrv/ConfigInfo.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
#ifndef NDB_MGMAPI
 
18
#include <ndb_opt_defaults.h>
 
19
 
 
20
#include <NdbTCP.h>
 
21
#include "ConfigInfo.hpp"
 
22
#include <mgmapi_config_parameters.h>
 
23
#include <ndb_limits.h>
 
24
#include "InitConfigFileParser.hpp"
 
25
#include <m_string.h>
 
26
 
 
27
extern my_bool opt_ndb_shm;
 
28
extern my_bool opt_core;
 
29
 
 
30
#else
 
31
#include "ConfigInfo.hpp"
 
32
#include <mgmapi_config_parameters.h>
 
33
#endif /* NDB_MGMAPI */
 
34
 
 
35
#define MAX_LINE_LENGTH 255
 
36
#define KEY_INTERNAL 0
 
37
#define MAX_INT_RNIL 0xfffffeff
 
38
#define MAX_PORT_NO 65535
 
39
 
 
40
#define _STR_VALUE(x) #x
 
41
#define STR_VALUE(x) _STR_VALUE(x)
 
42
 
 
43
/****************************************************************************
 
44
 * Section names
 
45
 ****************************************************************************/
 
46
 
 
47
#define DB_TOKEN_PRINT  "ndbd(DB)"
 
48
#define MGM_TOKEN_PRINT "ndb_mgmd(MGM)"
 
49
#define API_TOKEN_PRINT "mysqld(API)"
 
50
 
 
51
#define DB_TOKEN "DB"
 
52
#define MGM_TOKEN "MGM"
 
53
#define API_TOKEN "API"
 
54
 
 
55
#ifndef NDB_MGMAPI
 
56
const ConfigInfo::AliasPair
 
57
ConfigInfo::m_sectionNameAliases[]={
 
58
  {API_TOKEN, "MYSQLD"},
 
59
  {DB_TOKEN,  "NDBD"},
 
60
  {MGM_TOKEN, "NDB_MGMD"},
 
61
  {0, 0}
 
62
};
 
63
 
 
64
const char* 
 
65
ConfigInfo::m_sectionNames[]={
 
66
  "SYSTEM",
 
67
  "COMPUTER",
 
68
 
 
69
  DB_TOKEN,
 
70
  MGM_TOKEN,
 
71
  API_TOKEN,
 
72
 
 
73
  "TCP",
 
74
  "SCI",
 
75
  "SHM"
 
76
};
 
77
const int ConfigInfo::m_noOfSectionNames = 
 
78
sizeof(m_sectionNames)/sizeof(char*);
 
79
 
 
80
 
 
81
/****************************************************************************
 
82
 * Section Rules declarations
 
83
 ****************************************************************************/
 
84
static bool transformComputer(InitConfigFileParser::Context & ctx, const char *);
 
85
static bool transformSystem(InitConfigFileParser::Context & ctx, const char *);
 
86
static bool transformNode(InitConfigFileParser::Context & ctx, const char *);
 
87
static bool checkConnectionSupport(InitConfigFileParser::Context & ctx, const char *);
 
88
static bool transformConnection(InitConfigFileParser::Context & ctx, const char *);
 
89
static bool applyDefaultValues(InitConfigFileParser::Context & ctx, const char *);
 
90
static bool checkMandatory(InitConfigFileParser::Context & ctx, const char *);
 
91
static bool fixPortNumber(InitConfigFileParser::Context & ctx, const char *);
 
92
static bool fixShmKey(InitConfigFileParser::Context & ctx, const char *);
 
93
static bool checkDbConstraints(InitConfigFileParser::Context & ctx, const char *);
 
94
static bool checkConnectionConstraints(InitConfigFileParser::Context &, const char *);
 
95
static bool checkTCPConstraints(InitConfigFileParser::Context &, const char *);
 
96
static bool fixNodeHostname(InitConfigFileParser::Context & ctx, const char * data);
 
97
static bool fixHostname(InitConfigFileParser::Context & ctx, const char * data);
 
98
static bool fixNodeId(InitConfigFileParser::Context & ctx, const char * data);
 
99
static bool fixDepricated(InitConfigFileParser::Context & ctx, const char *);
 
100
static bool saveInConfigValues(InitConfigFileParser::Context & ctx, const char *);
 
101
static bool fixFileSystemPath(InitConfigFileParser::Context & ctx, const char * data);
 
102
static bool fixBackupDataDir(InitConfigFileParser::Context & ctx, const char * data);
 
103
static bool fixShmUniqueId(InitConfigFileParser::Context & ctx, const char * data);
 
104
static bool checkLocalhostHostnameMix(InitConfigFileParser::Context & ctx, const char * data);
 
105
 
 
106
const ConfigInfo::SectionRule 
 
107
ConfigInfo::m_SectionRules[] = {
 
108
  { "SYSTEM", transformSystem, 0 },
 
109
  { "COMPUTER", transformComputer, 0 },
 
110
 
 
111
  { DB_TOKEN,   transformNode, 0 },
 
112
  { API_TOKEN,  transformNode, 0 },
 
113
  { MGM_TOKEN,  transformNode, 0 },
 
114
 
 
115
  { MGM_TOKEN,  fixShmUniqueId, 0 },
 
116
 
 
117
  { "TCP",  checkConnectionSupport, 0 },
 
118
  { "SHM",  checkConnectionSupport, 0 },
 
119
  { "SCI",  checkConnectionSupport, 0 },
 
120
 
 
121
  { "TCP",  transformConnection, 0 },
 
122
  { "SHM",  transformConnection, 0 },
 
123
  { "SCI",  transformConnection, 0 },
 
124
 
 
125
  { DB_TOKEN,   fixNodeHostname, 0 },
 
126
  { API_TOKEN,  fixNodeHostname, 0 },
 
127
  { MGM_TOKEN,  fixNodeHostname, 0 },
 
128
 
 
129
  { "TCP",  fixNodeId, "NodeId1" },
 
130
  { "TCP",  fixNodeId, "NodeId2" },
 
131
  { "SHM",  fixNodeId, "NodeId1" },
 
132
  { "SHM",  fixNodeId, "NodeId2" },
 
133
  { "SCI",  fixNodeId, "NodeId1" },
 
134
  { "SCI",  fixNodeId, "NodeId2" },
 
135
 
 
136
  { "TCP",  fixHostname, "HostName1" },
 
137
  { "TCP",  fixHostname, "HostName2" },
 
138
  { "SHM",  fixHostname, "HostName1" },
 
139
  { "SHM",  fixHostname, "HostName2" },
 
140
  { "SCI",  fixHostname, "HostName1" },
 
141
  { "SCI",  fixHostname, "HostName2" },
 
142
  { "SHM",  fixHostname, "HostName1" },
 
143
  { "SHM",  fixHostname, "HostName2" },
 
144
 
 
145
  { "TCP",  fixPortNumber, 0 }, // has to come after fixHostName
 
146
  { "SHM",  fixPortNumber, 0 }, // has to come after fixHostName
 
147
  { "SCI",  fixPortNumber, 0 }, // has to come after fixHostName
 
148
 
 
149
  { "*",    applyDefaultValues, "user" },
 
150
  { "*",    fixDepricated, 0 },
 
151
  { "*",    applyDefaultValues, "system" },
 
152
 
 
153
  { "SHM",  fixShmKey, 0 }, // has to come after apply default values
 
154
 
 
155
  { DB_TOKEN,   checkLocalhostHostnameMix, 0 },
 
156
  { API_TOKEN,  checkLocalhostHostnameMix, 0 },
 
157
  { MGM_TOKEN,  checkLocalhostHostnameMix, 0 },
 
158
 
 
159
  { DB_TOKEN,   fixFileSystemPath, 0 },
 
160
  { DB_TOKEN,   fixBackupDataDir, 0 },
 
161
 
 
162
  { DB_TOKEN,   checkDbConstraints, 0 },
 
163
 
 
164
  { "TCP",  checkConnectionConstraints, 0 },
 
165
  { "SHM",  checkConnectionConstraints, 0 },
 
166
  { "SCI",  checkConnectionConstraints, 0 },
 
167
 
 
168
  { "TCP",  checkTCPConstraints, "HostName1" },
 
169
  { "TCP",  checkTCPConstraints, "HostName2" },
 
170
  { "SCI",  checkTCPConstraints, "HostName1" },
 
171
  { "SCI",  checkTCPConstraints, "HostName2" },
 
172
  { "SHM",  checkTCPConstraints, "HostName1" },
 
173
  { "SHM",  checkTCPConstraints, "HostName2" },
 
174
  
 
175
  { "*",    checkMandatory, 0 },
 
176
  
 
177
  { DB_TOKEN,   saveInConfigValues, 0 },
 
178
  { API_TOKEN,  saveInConfigValues, 0 },
 
179
  { MGM_TOKEN,  saveInConfigValues, 0 },
 
180
 
 
181
  { "TCP",  saveInConfigValues, 0 },
 
182
  { "SHM",  saveInConfigValues, 0 },
 
183
  { "SCI",  saveInConfigValues, 0 }
 
184
};
 
185
const int ConfigInfo::m_NoOfRules = sizeof(m_SectionRules)/sizeof(SectionRule);
 
186
 
 
187
/****************************************************************************
 
188
 * Config Rules declarations
 
189
 ****************************************************************************/
 
190
static bool sanity_checks(Vector<ConfigInfo::ConfigRuleSection>&sections, 
 
191
                          struct InitConfigFileParser::Context &ctx, 
 
192
                          const char * rule_data);
 
193
static bool add_node_connections(Vector<ConfigInfo::ConfigRuleSection>&sections, 
 
194
                                 struct InitConfigFileParser::Context &ctx, 
 
195
                                 const char * rule_data);
 
196
static bool set_connection_priorities(Vector<ConfigInfo::ConfigRuleSection>&sections, 
 
197
                                 struct InitConfigFileParser::Context &ctx, 
 
198
                                 const char * rule_data);
 
199
static bool check_node_vs_replicas(Vector<ConfigInfo::ConfigRuleSection>&sections, 
 
200
                            struct InitConfigFileParser::Context &ctx, 
 
201
                            const char * rule_data);
 
202
 
 
203
const ConfigInfo::ConfigRule 
 
204
ConfigInfo::m_ConfigRules[] = {
 
205
  { sanity_checks, 0 },
 
206
  { add_node_connections, 0 },
 
207
  { set_connection_priorities, 0 },
 
208
  { check_node_vs_replicas, 0 },
 
209
  { 0, 0 }
 
210
};
 
211
          
 
212
struct DepricationTransform {
 
213
  const char * m_section;
 
214
  const char * m_oldName;
 
215
  const char * m_newName;
 
216
  double m_add;
 
217
  double m_mul;
 
218
};
 
219
 
 
220
static
 
221
const DepricationTransform f_deprication[] = {
 
222
  { DB_TOKEN, "Discless", "Diskless", 0, 1 },
 
223
  { DB_TOKEN, "Id", "NodeId", 0, 1 },
 
224
  { API_TOKEN, "Id", "NodeId", 0, 1 },
 
225
  { MGM_TOKEN, "Id", "NodeId", 0, 1 },
 
226
  { 0, 0, 0, 0, 0}
 
227
};
 
228
#endif /* NDB_MGMAPI */
 
229
 
 
230
/**
 
231
 * The default constructors create objects with suitable values for the
 
232
 * configuration parameters. 
 
233
 *
 
234
 * Some are however given the value MANDATORY which means that the value
 
235
 * must be specified in the configuration file. 
 
236
 *
 
237
 * Min and max values are also given for some parameters.
 
238
 * - Attr1:  Name in file (initial config file)
 
239
 * - Attr2:  Name in prop (properties object)
 
240
 * - Attr3:  Name of Section (in init config file)
 
241
 * - Attr4:  Updateable
 
242
 * - Attr5:  Type of parameter (INT or BOOL)
 
243
 * - Attr6:  Default Value (number only)
 
244
 * - Attr7:  Min value
 
245
 * - Attr8:  Max value
 
246
 * 
 
247
 * Parameter constraints are coded in file Config.cpp.
 
248
 *
 
249
 * *******************************************************************
 
250
 * Parameters used under development should be marked "NOTIMPLEMENTED"
 
251
 * *******************************************************************
 
252
 */
 
253
 
 
254
const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = {
 
255
 
 
256
  /****************************************************************************
 
257
   * COMPUTER
 
258
   ***************************************************************************/
 
259
  {
 
260
    KEY_INTERNAL,
 
261
    "COMPUTER",
 
262
    "COMPUTER",
 
263
    "Computer section",
 
264
    ConfigInfo::CI_INTERNAL,
 
265
    false,
 
266
    ConfigInfo::CI_SECTION,
 
267
    0,
 
268
    0, 0 },
 
269
  
 
270
  {
 
271
    KEY_INTERNAL,
 
272
    "Id",
 
273
    "COMPUTER",
 
274
    "Name of computer",
 
275
    ConfigInfo::CI_USED,
 
276
    false,
 
277
    ConfigInfo::CI_STRING,
 
278
    MANDATORY,
 
279
    0, 0 },
 
280
 
 
281
  {
 
282
    KEY_INTERNAL,
 
283
    "HostName",
 
284
    "COMPUTER",
 
285
    "Hostname of computer (e.g. mysql.com)",
 
286
    ConfigInfo::CI_USED,
 
287
    false,
 
288
    ConfigInfo::CI_STRING,
 
289
    MANDATORY,
 
290
    0, 0 },
 
291
 
 
292
  {
 
293
    KEY_INTERNAL,
 
294
    "ByteOrder",
 
295
    "COMPUTER",
 
296
    0,
 
297
    ConfigInfo::CI_DEPRICATED,
 
298
    false,
 
299
    ConfigInfo::CI_STRING,
 
300
    UNDEFINED,
 
301
    0,
 
302
    0 },
 
303
  
 
304
  /****************************************************************************
 
305
   * SYSTEM
 
306
   ***************************************************************************/
 
307
  {
 
308
    CFG_SECTION_SYSTEM,
 
309
    "SYSTEM",
 
310
    "SYSTEM",
 
311
    "System section",
 
312
    ConfigInfo::CI_USED,
 
313
    false,
 
314
    ConfigInfo::CI_SECTION,
 
315
    (const char *)CFG_SECTION_SYSTEM,
 
316
    0, 0 },
 
317
 
 
318
  {
 
319
    CFG_SYS_NAME,
 
320
    "Name",
 
321
    "SYSTEM",
 
322
    "Name of system (NDB Cluster)",
 
323
    ConfigInfo::CI_USED,
 
324
    false,
 
325
    ConfigInfo::CI_STRING,
 
326
    MANDATORY,
 
327
    0, 0 },
 
328
  
 
329
  {
 
330
    CFG_SYS_PRIMARY_MGM_NODE,
 
331
    "PrimaryMGMNode",
 
332
    "SYSTEM",
 
333
    "Node id of Primary "MGM_TOKEN_PRINT" node",
 
334
    ConfigInfo::CI_USED,
 
335
    false,
 
336
    ConfigInfo::CI_INT,
 
337
    "0",
 
338
    "0",
 
339
    STR_VALUE(MAX_INT_RNIL) },
 
340
 
 
341
  {
 
342
    CFG_SYS_CONFIG_GENERATION,
 
343
    "ConfigGenerationNumber",
 
344
    "SYSTEM",
 
345
    "Configuration generation number",
 
346
    ConfigInfo::CI_USED,
 
347
    false,
 
348
    ConfigInfo::CI_INT,
 
349
    "0",
 
350
    "0",
 
351
    STR_VALUE(MAX_INT_RNIL) },
 
352
 
 
353
  /***************************************************************************
 
354
   * DB
 
355
   ***************************************************************************/
 
356
  {
 
357
    CFG_SECTION_NODE,
 
358
    DB_TOKEN,
 
359
    DB_TOKEN,
 
360
    "Node section",
 
361
    ConfigInfo::CI_USED,
 
362
    false,
 
363
    ConfigInfo::CI_SECTION,
 
364
    (const char *)NODE_TYPE_DB, 
 
365
    0, 0
 
366
  },
 
367
 
 
368
  {
 
369
    CFG_NODE_HOST,
 
370
    "HostName",
 
371
    DB_TOKEN,
 
372
    "Name of computer for this node",
 
373
    ConfigInfo::CI_INTERNAL,
 
374
    false,
 
375
    ConfigInfo::CI_STRING,
 
376
    "localhost",
 
377
    0, 0 },
 
378
 
 
379
  {
 
380
    CFG_NODE_SYSTEM,
 
381
    "System",
 
382
    DB_TOKEN,
 
383
    "Name of system for this node",
 
384
    ConfigInfo::CI_INTERNAL,
 
385
    false,
 
386
    ConfigInfo::CI_STRING,
 
387
    UNDEFINED,
 
388
    0, 0 },
 
389
 
 
390
  {
 
391
    KEY_INTERNAL,
 
392
    "Id",
 
393
    DB_TOKEN,
 
394
    "",
 
395
    ConfigInfo::CI_DEPRICATED,
 
396
    false,
 
397
    ConfigInfo::CI_INT,
 
398
    MANDATORY,
 
399
    "1",
 
400
    STR_VALUE(MAX_DATA_NODE_ID) },
 
401
 
 
402
  {
 
403
    CFG_NODE_ID,
 
404
    "NodeId",
 
405
    DB_TOKEN,
 
406
    "Number identifying the database node ("DB_TOKEN_PRINT")",
 
407
    ConfigInfo::CI_USED,
 
408
    false,
 
409
    ConfigInfo::CI_INT,
 
410
    MANDATORY,
 
411
    "1",
 
412
    STR_VALUE(MAX_DATA_NODE_ID) },
 
413
 
 
414
  {
 
415
    KEY_INTERNAL,
 
416
    "ServerPort",
 
417
    DB_TOKEN,
 
418
    "Port used to setup transporter",
 
419
    ConfigInfo::CI_USED,
 
420
    false,
 
421
    ConfigInfo::CI_INT,
 
422
    UNDEFINED,
 
423
    "1",
 
424
    STR_VALUE(MAX_PORT_NO) },
 
425
 
 
426
  {
 
427
    CFG_DB_NO_REPLICAS,
 
428
    "NoOfReplicas",
 
429
    DB_TOKEN,
 
430
    "Number of copies of all data in the database (1-4)",
 
431
    ConfigInfo::CI_USED,
 
432
    false,
 
433
    ConfigInfo::CI_INT,
 
434
    MANDATORY,
 
435
    "1",
 
436
    "4" },
 
437
 
 
438
  {
 
439
    CFG_DB_NO_ATTRIBUTES,
 
440
    "MaxNoOfAttributes",
 
441
    DB_TOKEN,
 
442
    "Total number of attributes stored in database. I.e. sum over all tables",
 
443
    ConfigInfo::CI_USED,
 
444
    false,
 
445
    ConfigInfo::CI_INT,
 
446
    "1000",
 
447
    "32",
 
448
    STR_VALUE(MAX_INT_RNIL) },
 
449
  
 
450
  {
 
451
    CFG_DB_NO_TABLES,
 
452
    "MaxNoOfTables",
 
453
    DB_TOKEN,
 
454
    "Total number of tables stored in the database",
 
455
    ConfigInfo::CI_USED,
 
456
    false,
 
457
    ConfigInfo::CI_INT,
 
458
    "128",
 
459
    "8",
 
460
    STR_VALUE(MAX_TABLES) },
 
461
  
 
462
  {
 
463
    CFG_DB_NO_ORDERED_INDEXES,
 
464
    "MaxNoOfOrderedIndexes",
 
465
    DB_TOKEN,
 
466
    "Total number of ordered indexes that can be defined in the system",
 
467
    ConfigInfo::CI_USED,
 
468
    false,
 
469
    ConfigInfo::CI_INT,
 
470
    "128",
 
471
    "0",
 
472
    STR_VALUE(MAX_INT_RNIL) },
 
473
 
 
474
  {
 
475
    CFG_DB_NO_UNIQUE_HASH_INDEXES,
 
476
    "MaxNoOfUniqueHashIndexes",
 
477
    DB_TOKEN,
 
478
    "Total number of unique hash indexes that can be defined in the system",
 
479
    ConfigInfo::CI_USED,
 
480
    false,
 
481
    ConfigInfo::CI_INT,
 
482
    "64",
 
483
    "0",
 
484
    STR_VALUE(MAX_INT_RNIL) },
 
485
 
 
486
  {
 
487
    CFG_DB_NO_INDEXES,
 
488
    "MaxNoOfIndexes",
 
489
    DB_TOKEN,
 
490
    "Total number of indexes that can be defined in the system",
 
491
    ConfigInfo::CI_DEPRICATED,
 
492
    false,
 
493
    ConfigInfo::CI_INT,
 
494
    "128",
 
495
    "0",
 
496
    STR_VALUE(MAX_INT_RNIL) },
 
497
 
 
498
  {
 
499
    CFG_DB_NO_INDEX_OPS,
 
500
    "MaxNoOfConcurrentIndexOperations",
 
501
    DB_TOKEN,
 
502
    "Total number of index operations that can execute simultaneously on one "DB_TOKEN_PRINT" node",
 
503
    ConfigInfo::CI_USED,
 
504
    false,
 
505
    ConfigInfo::CI_INT,
 
506
    "8K",
 
507
    "0",
 
508
    STR_VALUE(MAX_INT_RNIL) 
 
509
   },
 
510
 
 
511
  {
 
512
    CFG_DB_NO_TRIGGERS,
 
513
    "MaxNoOfTriggers",
 
514
    DB_TOKEN,
 
515
    "Total number of triggers that can be defined in the system",
 
516
    ConfigInfo::CI_USED,
 
517
    false,
 
518
    ConfigInfo::CI_INT,
 
519
    "768",
 
520
    "0",
 
521
    STR_VALUE(MAX_INT_RNIL) },
 
522
 
 
523
  {
 
524
    CFG_DB_NO_TRIGGER_OPS,
 
525
    "MaxNoOfFiredTriggers",
 
526
    DB_TOKEN,
 
527
    "Total number of triggers that can fire simultaneously in one "DB_TOKEN_PRINT" node",
 
528
    ConfigInfo::CI_USED,
 
529
    false,
 
530
    ConfigInfo::CI_INT,
 
531
    "4000",
 
532
    "0",
 
533
    STR_VALUE(MAX_INT_RNIL) },
 
534
 
 
535
  {
 
536
    KEY_INTERNAL,
 
537
    "ExecuteOnComputer",
 
538
    DB_TOKEN,
 
539
    "String referencing an earlier defined COMPUTER",
 
540
    ConfigInfo::CI_USED,
 
541
    false,
 
542
    ConfigInfo::CI_STRING,
 
543
    UNDEFINED,
 
544
    0, 0 },
 
545
  
 
546
  {
 
547
    CFG_DB_NO_SAVE_MSGS,
 
548
    "MaxNoOfSavedMessages",
 
549
    DB_TOKEN,
 
550
    "Max number of error messages in error log and max number of trace files",
 
551
    ConfigInfo::CI_USED,
 
552
    true,
 
553
    ConfigInfo::CI_INT,
 
554
    "25",
 
555
    "0",
 
556
    STR_VALUE(MAX_INT_RNIL) },
 
557
 
 
558
  {
 
559
    CFG_DB_MEMLOCK,
 
560
    "LockPagesInMainMemory",
 
561
    DB_TOKEN,
 
562
    "If set to yes, then NDB Cluster data will not be swapped out to disk",
 
563
    ConfigInfo::CI_USED,
 
564
    true,
 
565
    ConfigInfo::CI_INT,
 
566
    "0",
 
567
    "0",
 
568
    "2" },
 
569
 
 
570
  {
 
571
    CFG_DB_WATCHDOG_INTERVAL,
 
572
    "TimeBetweenWatchDogCheck",
 
573
    DB_TOKEN,
 
574
    "Time between execution checks inside a database node",
 
575
    ConfigInfo::CI_USED,
 
576
    true,
 
577
    ConfigInfo::CI_INT,
 
578
    "6000",
 
579
    "70",
 
580
    STR_VALUE(MAX_INT_RNIL) },
 
581
 
 
582
  {
 
583
    CFG_DB_WATCHDOG_INTERVAL_INITIAL,
 
584
    "TimeBetweenWatchDogCheckInitial",
 
585
    DB_TOKEN,
 
586
    "Time between execution checks inside a database node in the early start phases when memory is allocated",
 
587
    ConfigInfo::CI_USED,
 
588
    true,
 
589
    ConfigInfo::CI_INT,
 
590
    "6000",
 
591
    "70",
 
592
    STR_VALUE(MAX_INT_RNIL) },
 
593
 
 
594
  {
 
595
    CFG_DB_STOP_ON_ERROR,
 
596
    "StopOnError",
 
597
    DB_TOKEN,
 
598
    "If set to N, "DB_TOKEN_PRINT" automatically restarts/recovers in case of node failure",
 
599
    ConfigInfo::CI_USED,
 
600
    true,
 
601
    ConfigInfo::CI_BOOL,
 
602
    "true",
 
603
    "false",
 
604
    "true" },
 
605
 
 
606
  { 
 
607
    CFG_DB_STOP_ON_ERROR_INSERT,
 
608
    "RestartOnErrorInsert",
 
609
    DB_TOKEN,
 
610
    "See src/kernel/vm/Emulator.hpp NdbRestartType for details",
 
611
    ConfigInfo::CI_INTERNAL,
 
612
    true,
 
613
    ConfigInfo::CI_INT,
 
614
    "2",
 
615
    "0",
 
616
    "4" },
 
617
  
 
618
  {
 
619
    CFG_DB_NO_OPS,
 
620
    "MaxNoOfConcurrentOperations",
 
621
    DB_TOKEN,
 
622
    "Max number of operation records in transaction coordinator",
 
623
    ConfigInfo::CI_USED,
 
624
    false,
 
625
    ConfigInfo::CI_INT,
 
626
    "32k",
 
627
    "32",
 
628
    STR_VALUE(MAX_INT_RNIL) },
 
629
 
 
630
  {
 
631
    CFG_DB_NO_LOCAL_OPS,
 
632
    "MaxNoOfLocalOperations",
 
633
    DB_TOKEN,
 
634
    "Max number of operation records defined in the local storage node",
 
635
    ConfigInfo::CI_USED,
 
636
    false,
 
637
    ConfigInfo::CI_INT,
 
638
    UNDEFINED,
 
639
    "32",
 
640
    STR_VALUE(MAX_INT_RNIL) },
 
641
 
 
642
  {
 
643
    CFG_DB_NO_LOCAL_SCANS,
 
644
    "MaxNoOfLocalScans",
 
645
    DB_TOKEN,
 
646
    "Max number of fragment scans in parallel in the local storage node",
 
647
    ConfigInfo::CI_USED,
 
648
    false,
 
649
    ConfigInfo::CI_INT,
 
650
    UNDEFINED,
 
651
    "32",
 
652
    STR_VALUE(MAX_INT_RNIL) },
 
653
 
 
654
  {
 
655
    CFG_DB_BATCH_SIZE,
 
656
    "BatchSizePerLocalScan",
 
657
    DB_TOKEN,
 
658
    "Used to calculate the number of lock records for scan with hold lock",
 
659
    ConfigInfo::CI_USED,
 
660
    false,
 
661
    ConfigInfo::CI_INT,
 
662
    STR_VALUE(DEF_BATCH_SIZE),
 
663
    "1",
 
664
    STR_VALUE(MAX_PARALLEL_OP_PER_SCAN) },
 
665
 
 
666
  {
 
667
    CFG_DB_NO_TRANSACTIONS,
 
668
    "MaxNoOfConcurrentTransactions",
 
669
    DB_TOKEN,
 
670
    "Max number of transaction executing concurrently on the "DB_TOKEN_PRINT" node",
 
671
    ConfigInfo::CI_USED,
 
672
    false,
 
673
    ConfigInfo::CI_INT,
 
674
    "4096",
 
675
    "32",
 
676
    STR_VALUE(MAX_INT_RNIL) },
 
677
 
 
678
  {
 
679
    CFG_DB_NO_SCANS,
 
680
    "MaxNoOfConcurrentScans",
 
681
    DB_TOKEN,
 
682
    "Max number of scans executing concurrently on the "DB_TOKEN_PRINT" node",
 
683
    ConfigInfo::CI_USED,
 
684
    false,
 
685
    ConfigInfo::CI_INT,
 
686
    "256",
 
687
    "2",
 
688
    "500" },
 
689
 
 
690
  {
 
691
    CFG_DB_TRANS_BUFFER_MEM,
 
692
    "TransactionBufferMemory",
 
693
    DB_TOKEN,
 
694
    "Dynamic buffer space (in bytes) for key and attribute data allocated for each "DB_TOKEN_PRINT" node",
 
695
    ConfigInfo::CI_USED,
 
696
    false,
 
697
    ConfigInfo::CI_INT,
 
698
    "1M",
 
699
    "1K",
 
700
    STR_VALUE(MAX_INT_RNIL) },
 
701
 
 
702
  {
 
703
    CFG_DB_INDEX_MEM,
 
704
    "IndexMemory",
 
705
    DB_TOKEN,
 
706
    "Number bytes on each "DB_TOKEN_PRINT" node allocated for storing indexes",
 
707
    ConfigInfo::CI_USED,
 
708
    false,
 
709
    ConfigInfo::CI_INT64,
 
710
    "18M",
 
711
    "1M",
 
712
    "1024G" },
 
713
 
 
714
  {
 
715
    CFG_DB_DATA_MEM,
 
716
    "DataMemory",
 
717
    DB_TOKEN,
 
718
    "Number bytes on each "DB_TOKEN_PRINT" node allocated for storing data",
 
719
    ConfigInfo::CI_USED,
 
720
    false,
 
721
    ConfigInfo::CI_INT64,
 
722
    "80M",
 
723
    "1M",
 
724
    "1024G" },
 
725
 
 
726
  {
 
727
    CFG_DB_UNDO_INDEX_BUFFER,
 
728
    "UndoIndexBuffer",
 
729
    DB_TOKEN,
 
730
    "Number bytes on each "DB_TOKEN_PRINT" node allocated for writing UNDO logs for index part",
 
731
    ConfigInfo::CI_USED,
 
732
    false,
 
733
    ConfigInfo::CI_INT,
 
734
    "2M",
 
735
    "1M",
 
736
    STR_VALUE(MAX_INT_RNIL)},
 
737
 
 
738
  {
 
739
    CFG_DB_UNDO_DATA_BUFFER,
 
740
    "UndoDataBuffer",
 
741
    DB_TOKEN,
 
742
    "Number bytes on each "DB_TOKEN_PRINT" node allocated for writing UNDO logs for data part",
 
743
    ConfigInfo::CI_USED,
 
744
    false,
 
745
    ConfigInfo::CI_INT,
 
746
    "16M",
 
747
    "1M",
 
748
    STR_VALUE(MAX_INT_RNIL)},
 
749
 
 
750
  {
 
751
    CFG_DB_REDO_BUFFER,
 
752
    "RedoBuffer",
 
753
    DB_TOKEN,
 
754
    "Number bytes on each "DB_TOKEN_PRINT" node allocated for writing REDO logs",
 
755
    ConfigInfo::CI_USED,
 
756
    false,
 
757
    ConfigInfo::CI_INT,
 
758
    "8M",
 
759
    "1M",
 
760
    STR_VALUE(MAX_INT_RNIL)},
 
761
 
 
762
  {
 
763
    CFG_DB_LONG_SIGNAL_BUFFER,
 
764
    "LongMessageBuffer",
 
765
    DB_TOKEN,
 
766
    "Number bytes on each "DB_TOKEN_PRINT" node allocated for internal long messages",
 
767
    ConfigInfo::CI_USED,
 
768
    false,
 
769
    ConfigInfo::CI_INT,
 
770
    "1M",
 
771
    "512k",
 
772
    STR_VALUE(MAX_INT_RNIL)},
 
773
 
 
774
  {
 
775
    CFG_DB_DISK_PAGE_BUFFER_MEMORY,
 
776
    "DiskPageBufferMemory",
 
777
    DB_TOKEN,
 
778
    "Number bytes on each "DB_TOKEN_PRINT" node allocated for disk page buffer cache",
 
779
    ConfigInfo::CI_USED,
 
780
    false,
 
781
    ConfigInfo::CI_INT64,
 
782
    "64M",
 
783
    "4M",
 
784
    "1024G" },
 
785
 
 
786
  {
 
787
    CFG_DB_SGA,
 
788
    "SharedGlobalMemory",
 
789
    DB_TOKEN,
 
790
    "Total number bytes on each "DB_TOKEN_PRINT" node allocated for any use",
 
791
    ConfigInfo::CI_USED,
 
792
    false,
 
793
    ConfigInfo::CI_INT64,
 
794
    "20M",
 
795
    "0",
 
796
    "65536G" }, // 32k pages * 32-bit i value
 
797
  
 
798
  {
 
799
    CFG_DB_START_PARTIAL_TIMEOUT,
 
800
    "StartPartialTimeout",
 
801
    DB_TOKEN,
 
802
    "Time to wait before trying to start wo/ all nodes. 0=Wait forever",
 
803
    ConfigInfo::CI_USED,
 
804
    true,
 
805
    ConfigInfo::CI_INT,
 
806
    "30000",
 
807
    "0",
 
808
    STR_VALUE(MAX_INT_RNIL) },
 
809
 
 
810
  {
 
811
    CFG_DB_START_PARTITION_TIMEOUT,
 
812
    "StartPartitionedTimeout",
 
813
    DB_TOKEN,
 
814
    "Time to wait before trying to start partitioned. 0=Wait forever",
 
815
    ConfigInfo::CI_USED,
 
816
    true,
 
817
    ConfigInfo::CI_INT,
 
818
    "60000",
 
819
    "0",
 
820
    STR_VALUE(MAX_INT_RNIL) },
 
821
  
 
822
  {
 
823
    CFG_DB_START_FAILURE_TIMEOUT,
 
824
    "StartFailureTimeout",
 
825
    DB_TOKEN,
 
826
    "Time to wait before terminating. 0=Wait forever",
 
827
    ConfigInfo::CI_USED,
 
828
    true,
 
829
    ConfigInfo::CI_INT,
 
830
    "0",
 
831
    "0",
 
832
    STR_VALUE(MAX_INT_RNIL) },
 
833
  
 
834
  {
 
835
    CFG_DB_HEARTBEAT_INTERVAL,
 
836
    "HeartbeatIntervalDbDb",
 
837
    DB_TOKEN,
 
838
    "Time between "DB_TOKEN_PRINT"-"DB_TOKEN_PRINT" heartbeats. "DB_TOKEN_PRINT" considered dead after 3 missed HBs",
 
839
    ConfigInfo::CI_USED,
 
840
    true,
 
841
    ConfigInfo::CI_INT,
 
842
    "1500",
 
843
    "10",
 
844
    STR_VALUE(MAX_INT_RNIL) },
 
845
 
 
846
  {
 
847
    CFG_DB_API_HEARTBEAT_INTERVAL,
 
848
    "HeartbeatIntervalDbApi",
 
849
    DB_TOKEN,
 
850
    "Time between "API_TOKEN_PRINT"-"DB_TOKEN_PRINT" heartbeats. "API_TOKEN_PRINT" connection closed after 3 missed HBs",
 
851
    ConfigInfo::CI_USED,
 
852
    true,
 
853
    ConfigInfo::CI_INT,
 
854
    "1500",
 
855
    "100",
 
856
    STR_VALUE(MAX_INT_RNIL) },
 
857
 
 
858
  {
 
859
    CFG_DB_LCP_INTERVAL,
 
860
    "TimeBetweenLocalCheckpoints",
 
861
    DB_TOKEN,
 
862
    "Time between taking snapshots of the database (expressed in 2log of bytes)",
 
863
    ConfigInfo::CI_USED,
 
864
    true,
 
865
    ConfigInfo::CI_INT,
 
866
    "20",
 
867
    "0",
 
868
    "31" },
 
869
 
 
870
  {
 
871
    CFG_DB_GCP_INTERVAL,
 
872
    "TimeBetweenGlobalCheckpoints",
 
873
    DB_TOKEN,
 
874
    "Time between doing group commit of transactions to disk",
 
875
    ConfigInfo::CI_USED,
 
876
    true,
 
877
    ConfigInfo::CI_INT,
 
878
    "2000",
 
879
    "10",
 
880
    "32000" },
 
881
 
 
882
  {
 
883
    CFG_DB_NO_REDOLOG_FILES,
 
884
    "NoOfFragmentLogFiles",
 
885
    DB_TOKEN,
 
886
    "No of 16 Mbyte Redo log files in each of 4 file sets belonging to "DB_TOKEN_PRINT" node",
 
887
    ConfigInfo::CI_USED,
 
888
    false,
 
889
    ConfigInfo::CI_INT,
 
890
    "16",
 
891
    "3",
 
892
    STR_VALUE(MAX_INT_RNIL) },
 
893
 
 
894
  {
 
895
    CFG_DB_REDOLOG_FILE_SIZE,
 
896
    "FragmentLogFileSize",
 
897
    DB_TOKEN,
 
898
    "Size of each Redo log file",
 
899
    ConfigInfo::CI_USED,
 
900
    false,
 
901
    ConfigInfo::CI_INT,
 
902
    "16M",
 
903
    "4M",
 
904
    "1G" },
 
905
 
 
906
  {
 
907
    CFG_DB_MAX_OPEN_FILES,
 
908
    "MaxNoOfOpenFiles",
 
909
    DB_TOKEN,
 
910
    "Max number of files open per "DB_TOKEN_PRINT" node.(One thread is created per file)",
 
911
    ConfigInfo::CI_USED,
 
912
    false,
 
913
    ConfigInfo::CI_INT,
 
914
    "0",
 
915
    "20",
 
916
    STR_VALUE(MAX_INT_RNIL) },
 
917
  
 
918
  {
 
919
    CFG_DB_INITIAL_OPEN_FILES,
 
920
    "InitialNoOfOpenFiles",
 
921
    DB_TOKEN,
 
922
    "Initial number of files open per "DB_TOKEN_PRINT" node.(One thread is created per file)",
 
923
    ConfigInfo::CI_USED,
 
924
    false,
 
925
    ConfigInfo::CI_INT,
 
926
    "27",
 
927
    "20",
 
928
    STR_VALUE(MAX_INT_RNIL) },
 
929
  
 
930
  {
 
931
    CFG_DB_TRANSACTION_CHECK_INTERVAL,
 
932
    "TimeBetweenInactiveTransactionAbortCheck",
 
933
    DB_TOKEN,
 
934
    "Time between inactive transaction checks",
 
935
    ConfigInfo::CI_USED,
 
936
    true,
 
937
    ConfigInfo::CI_INT,
 
938
    "1000",
 
939
    "1000",
 
940
    STR_VALUE(MAX_INT_RNIL) },
 
941
  
 
942
  {
 
943
    CFG_DB_TRANSACTION_INACTIVE_TIMEOUT,
 
944
    "TransactionInactiveTimeout",
 
945
    DB_TOKEN,
 
946
    "Time application can wait before executing another transaction part (ms).\n"
 
947
    "This is the time the transaction coordinator waits for the application\n"
 
948
    "to execute or send another part (query, statement) of the transaction.\n"
 
949
    "If the application takes too long time, the transaction gets aborted.\n"
 
950
    "Timeout set to 0 means that we don't timeout at all on application wait.",
 
951
    ConfigInfo::CI_USED,
 
952
    true,
 
953
    ConfigInfo::CI_INT,
 
954
    STR_VALUE(MAX_INT_RNIL),
 
955
    "0",
 
956
    STR_VALUE(MAX_INT_RNIL) },
 
957
 
 
958
  {
 
959
    CFG_DB_TRANSACTION_DEADLOCK_TIMEOUT,
 
960
    "TransactionDeadlockDetectionTimeout",
 
961
    DB_TOKEN,
 
962
    "Time transaction can be executing in a DB node (ms).\n"
 
963
    "This is the time the transaction coordinator waits for each database node\n"
 
964
    "of the transaction to execute a request. If the database node takes too\n"
 
965
    "long time, the transaction gets aborted.",
 
966
    ConfigInfo::CI_USED,
 
967
    true,
 
968
    ConfigInfo::CI_INT,
 
969
    "1200",
 
970
    "50",
 
971
    STR_VALUE(MAX_INT_RNIL) },
 
972
 
 
973
  {
 
974
    CFG_DB_LCP_DISC_PAGES_TUP_SR,
 
975
    "NoOfDiskPagesToDiskDuringRestartTUP",
 
976
    DB_TOKEN,
 
977
    "DiskCheckpointSpeedSr",
 
978
    ConfigInfo::CI_DEPRICATED,
 
979
    true,
 
980
    ConfigInfo::CI_INT,
 
981
    "40",
 
982
    "1",
 
983
    STR_VALUE(MAX_INT_RNIL) },
 
984
 
 
985
  {
 
986
    CFG_DB_LCP_DISC_PAGES_TUP,
 
987
    "NoOfDiskPagesToDiskAfterRestartTUP",
 
988
    DB_TOKEN,
 
989
    "DiskCheckpointSpeed",
 
990
    ConfigInfo::CI_DEPRICATED,
 
991
    true,
 
992
    ConfigInfo::CI_INT,
 
993
    "40",
 
994
    "1",
 
995
    STR_VALUE(MAX_INT_RNIL) },
 
996
 
 
997
  {
 
998
    CFG_DB_LCP_DISC_PAGES_ACC_SR,
 
999
    "NoOfDiskPagesToDiskDuringRestartACC",
 
1000
    DB_TOKEN,
 
1001
    "DiskCheckpointSpeedSr",
 
1002
    ConfigInfo::CI_DEPRICATED,
 
1003
    true,
 
1004
    ConfigInfo::CI_INT,
 
1005
    "20",
 
1006
    "1",
 
1007
    STR_VALUE(MAX_INT_RNIL) },
 
1008
 
 
1009
  {
 
1010
    CFG_DB_LCP_DISC_PAGES_ACC,
 
1011
    "NoOfDiskPagesToDiskAfterRestartACC",
 
1012
    DB_TOKEN,
 
1013
    "DiskCheckpointSpeed",
 
1014
    ConfigInfo::CI_DEPRICATED,
 
1015
    true,
 
1016
    ConfigInfo::CI_INT,
 
1017
    "20",
 
1018
    "1",
 
1019
    STR_VALUE(MAX_INT_RNIL) },
 
1020
  
 
1021
 
 
1022
  {
 
1023
    CFG_DB_DISCLESS,
 
1024
    "Diskless",
 
1025
    DB_TOKEN,
 
1026
    "Run wo/ disk",
 
1027
    ConfigInfo::CI_USED,
 
1028
    true,
 
1029
    ConfigInfo::CI_BOOL,
 
1030
    "false",
 
1031
    "false",
 
1032
    "true"},
 
1033
 
 
1034
  {
 
1035
    KEY_INTERNAL,
 
1036
    "Discless",
 
1037
    DB_TOKEN,
 
1038
    "Diskless",
 
1039
    ConfigInfo::CI_DEPRICATED,
 
1040
    true,
 
1041
    ConfigInfo::CI_BOOL,
 
1042
    "false",
 
1043
    "false",
 
1044
    "true"},
 
1045
  
 
1046
 
 
1047
  
 
1048
  {
 
1049
    CFG_DB_ARBIT_TIMEOUT,
 
1050
    "ArbitrationTimeout",
 
1051
    DB_TOKEN,
 
1052
    "Max time (milliseconds) database partion waits for arbitration signal",
 
1053
    ConfigInfo::CI_USED,
 
1054
    false,
 
1055
    ConfigInfo::CI_INT,
 
1056
    "3000",
 
1057
    "10",
 
1058
    STR_VALUE(MAX_INT_RNIL) },
 
1059
 
 
1060
  {
 
1061
    CFG_NODE_DATADIR,
 
1062
    "DataDir",
 
1063
    DB_TOKEN,
 
1064
    "Data directory for this node",
 
1065
    ConfigInfo::CI_USED,
 
1066
    false,
 
1067
    ConfigInfo::CI_STRING,
 
1068
    MYSQLCLUSTERDIR,
 
1069
    0, 0 },
 
1070
 
 
1071
  {
 
1072
    CFG_DB_FILESYSTEM_PATH,
 
1073
    "FileSystemPath",
 
1074
    DB_TOKEN,
 
1075
    "Path to directory where the "DB_TOKEN_PRINT" node stores its data (directory must exist)",
 
1076
    ConfigInfo::CI_USED,
 
1077
    false,
 
1078
    ConfigInfo::CI_STRING,
 
1079
    UNDEFINED,
 
1080
    0, 0 },
 
1081
 
 
1082
  {
 
1083
    CFG_LOGLEVEL_STARTUP,
 
1084
    "LogLevelStartup",
 
1085
    DB_TOKEN,
 
1086
    "Node startup info printed on stdout",
 
1087
    ConfigInfo::CI_USED,
 
1088
    false,
 
1089
    ConfigInfo::CI_INT,
 
1090
    "1",
 
1091
    "0",
 
1092
    "15" },
 
1093
  
 
1094
  {
 
1095
    CFG_LOGLEVEL_SHUTDOWN,
 
1096
    "LogLevelShutdown",
 
1097
    DB_TOKEN,
 
1098
    "Node shutdown info printed on stdout",
 
1099
    ConfigInfo::CI_USED,
 
1100
    false,
 
1101
    ConfigInfo::CI_INT,
 
1102
    "0",
 
1103
    "0",
 
1104
    "15" },
 
1105
 
 
1106
  {
 
1107
    CFG_LOGLEVEL_STATISTICS,
 
1108
    "LogLevelStatistic",
 
1109
    DB_TOKEN,
 
1110
    "Transaction, operation, transporter info printed on stdout",
 
1111
    ConfigInfo::CI_USED,
 
1112
    false,
 
1113
    ConfigInfo::CI_INT,
 
1114
    "0",
 
1115
    "0",
 
1116
    "15" },
 
1117
 
 
1118
  {
 
1119
    CFG_LOGLEVEL_CHECKPOINT,
 
1120
    "LogLevelCheckpoint",
 
1121
    DB_TOKEN,
 
1122
    "Local and Global checkpoint info printed on stdout",
 
1123
    ConfigInfo::CI_USED,
 
1124
    false,
 
1125
    ConfigInfo::CI_INT,
 
1126
    "0",
 
1127
    "0",
 
1128
    "15" },
 
1129
 
 
1130
  {
 
1131
    CFG_LOGLEVEL_NODERESTART,
 
1132
    "LogLevelNodeRestart",
 
1133
    DB_TOKEN,
 
1134
    "Node restart, node failure info printed on stdout",
 
1135
    ConfigInfo::CI_USED,
 
1136
    false,
 
1137
    ConfigInfo::CI_INT,
 
1138
    "0",
 
1139
    "0",
 
1140
    "15" },
 
1141
 
 
1142
  {
 
1143
    CFG_LOGLEVEL_CONNECTION,
 
1144
    "LogLevelConnection",
 
1145
    DB_TOKEN,
 
1146
    "Node connect/disconnect info printed on stdout",
 
1147
    ConfigInfo::CI_USED,
 
1148
    false,
 
1149
    ConfigInfo::CI_INT,
 
1150
    "0",
 
1151
    "0",
 
1152
    "15" },
 
1153
 
 
1154
  {
 
1155
    CFG_LOGLEVEL_CONGESTION,
 
1156
    "LogLevelCongestion",
 
1157
    DB_TOKEN,
 
1158
    "Congestion info printed on stdout",
 
1159
    ConfigInfo::CI_USED,
 
1160
    false,
 
1161
    ConfigInfo::CI_INT,
 
1162
    "0",
 
1163
    "0",
 
1164
    "15" },
 
1165
 
 
1166
  {
 
1167
    CFG_LOGLEVEL_ERROR,
 
1168
    "LogLevelError",
 
1169
    DB_TOKEN,
 
1170
    "Transporter, heartbeat errors printed on stdout",
 
1171
    ConfigInfo::CI_USED,
 
1172
    false,
 
1173
    ConfigInfo::CI_INT,
 
1174
    "0",
 
1175
    "0",
 
1176
    "15" },
 
1177
 
 
1178
  {
 
1179
    CFG_LOGLEVEL_INFO,
 
1180
    "LogLevelInfo",
 
1181
    DB_TOKEN,
 
1182
    "Heartbeat and log info printed on stdout",
 
1183
    ConfigInfo::CI_USED,
 
1184
    false,
 
1185
    ConfigInfo::CI_INT,
 
1186
    "0",
 
1187
    "0",
 
1188
    "15" },
 
1189
 
 
1190
  /**
 
1191
   * Backup
 
1192
   */
 
1193
  { 
 
1194
    CFG_DB_PARALLEL_BACKUPS,
 
1195
    "ParallelBackups",
 
1196
    DB_TOKEN,
 
1197
    "Maximum number of parallel backups",
 
1198
    ConfigInfo::CI_NOTIMPLEMENTED,
 
1199
    false,
 
1200
    ConfigInfo::CI_INT,
 
1201
    "1",
 
1202
    "1",
 
1203
    "1" },
 
1204
  
 
1205
  { 
 
1206
    CFG_DB_BACKUP_DATADIR,
 
1207
    "BackupDataDir",
 
1208
    DB_TOKEN,
 
1209
    "Path to where to store backups",
 
1210
    ConfigInfo::CI_USED,
 
1211
    false,
 
1212
    ConfigInfo::CI_STRING,
 
1213
    UNDEFINED,
 
1214
    0, 0 },
 
1215
  
 
1216
  { 
 
1217
    CFG_DB_DISK_SYNCH_SIZE,
 
1218
    "DiskSyncSize",
 
1219
    DB_TOKEN,
 
1220
    "Data written to a file before a synch is forced",
 
1221
    ConfigInfo::CI_USED,
 
1222
    false,
 
1223
    ConfigInfo::CI_INT,
 
1224
    "4M",
 
1225
    "32k",
 
1226
    STR_VALUE(MAX_INT_RNIL) },
 
1227
  
 
1228
  { 
 
1229
    CFG_DB_CHECKPOINT_SPEED,
 
1230
    "DiskCheckpointSpeed",
 
1231
    DB_TOKEN,
 
1232
    "Bytes per second allowed to be written by checkpoint",
 
1233
    ConfigInfo::CI_USED,
 
1234
    false,
 
1235
    ConfigInfo::CI_INT,
 
1236
    "10M",
 
1237
    "1M",
 
1238
    STR_VALUE(MAX_INT_RNIL) },
 
1239
  
 
1240
  { 
 
1241
    CFG_DB_CHECKPOINT_SPEED_SR,
 
1242
    "DiskCheckpointSpeedInRestart",
 
1243
    DB_TOKEN,
 
1244
    "Bytes per second allowed to be written by checkpoint during restart",
 
1245
    ConfigInfo::CI_USED,
 
1246
    false,
 
1247
    ConfigInfo::CI_INT,
 
1248
    "100M",
 
1249
    "1M",
 
1250
    STR_VALUE(MAX_INT_RNIL) },
 
1251
  
 
1252
  { 
 
1253
    CFG_DB_BACKUP_MEM,
 
1254
    "BackupMemory",
 
1255
    DB_TOKEN,
 
1256
    "Total memory allocated for backups per node (in bytes)",
 
1257
    ConfigInfo::CI_USED,
 
1258
    false,
 
1259
    ConfigInfo::CI_INT,
 
1260
    "4M", // sum of BackupDataBufferSize and BackupLogBufferSize
 
1261
    "0",
 
1262
    STR_VALUE(MAX_INT_RNIL) },
 
1263
  
 
1264
  { 
 
1265
    CFG_DB_BACKUP_DATA_BUFFER_MEM,
 
1266
    "BackupDataBufferSize",
 
1267
    DB_TOKEN,
 
1268
    "Default size of databuffer for a backup (in bytes)",
 
1269
    ConfigInfo::CI_USED,
 
1270
    false,
 
1271
    ConfigInfo::CI_INT,
 
1272
    "2M", // remember to change BackupMemory
 
1273
    "0",
 
1274
    STR_VALUE(MAX_INT_RNIL) },
 
1275
 
 
1276
  { 
 
1277
    CFG_DB_BACKUP_LOG_BUFFER_MEM,
 
1278
    "BackupLogBufferSize",
 
1279
    DB_TOKEN,
 
1280
    "Default size of logbuffer for a backup (in bytes)",
 
1281
    ConfigInfo::CI_USED,
 
1282
    false,
 
1283
    ConfigInfo::CI_INT,
 
1284
    "2M", // remember to change BackupMemory
 
1285
    "0",
 
1286
    STR_VALUE(MAX_INT_RNIL) },
 
1287
 
 
1288
  { 
 
1289
    CFG_DB_BACKUP_WRITE_SIZE,
 
1290
    "BackupWriteSize",
 
1291
    DB_TOKEN,
 
1292
    "Default size of filesystem writes made by backup (in bytes)",
 
1293
    ConfigInfo::CI_USED,
 
1294
    false,
 
1295
    ConfigInfo::CI_INT,
 
1296
    "32K",
 
1297
    "2K",
 
1298
    STR_VALUE(MAX_INT_RNIL) },
 
1299
 
 
1300
  { 
 
1301
    CFG_DB_BACKUP_MAX_WRITE_SIZE,
 
1302
    "BackupMaxWriteSize",
 
1303
    DB_TOKEN,
 
1304
    "Max size of filesystem writes made by backup (in bytes)",
 
1305
    ConfigInfo::CI_USED,
 
1306
    false,
 
1307
    ConfigInfo::CI_INT,
 
1308
    "256K",
 
1309
    "2K",
 
1310
    STR_VALUE(MAX_INT_RNIL) },
 
1311
 
 
1312
  { 
 
1313
    CFG_DB_STRING_MEMORY,
 
1314
    "StringMemory",
 
1315
    DB_TOKEN,
 
1316
    "Default size of string memory (0 -> 5% of max 1-100 -> %of max, >100 -> actual bytes)",
 
1317
    ConfigInfo::CI_USED,
 
1318
    false,
 
1319
    ConfigInfo::CI_INT,
 
1320
    "0",
 
1321
    "0",
 
1322
    STR_VALUE(MAX_INT_RNIL) },
 
1323
 
 
1324
  { 
 
1325
    CFG_DB_MAX_ALLOCATE,
 
1326
    "MaxAllocate",
 
1327
    DB_TOKEN,
 
1328
    "Maximum size of allocation to use when allocating memory for tables",
 
1329
    ConfigInfo::CI_USED,
 
1330
    false,
 
1331
    ConfigInfo::CI_INT,
 
1332
    "32M",
 
1333
    "1M",
 
1334
    "1G" },
 
1335
 
 
1336
  { 
 
1337
    CFG_DB_MEMREPORT_FREQUENCY,
 
1338
    "MemReportFrequency",
 
1339
    DB_TOKEN,
 
1340
    "Frequency of mem reports in seconds, 0 = only when passing %-limits",
 
1341
    ConfigInfo::CI_USED,
 
1342
    false,
 
1343
    ConfigInfo::CI_INT,
 
1344
    "0",
 
1345
    "0",
 
1346
    STR_VALUE(MAX_INT_RNIL) },
 
1347
  
 
1348
  {
 
1349
    CFG_DB_O_DIRECT,
 
1350
    "ODirect",
 
1351
    DB_TOKEN,
 
1352
    "Use O_DIRECT file write/read when possible",
 
1353
    ConfigInfo::CI_USED,
 
1354
    true,
 
1355
    ConfigInfo::CI_BOOL,
 
1356
    "false",
 
1357
    "false",
 
1358
    "true"},
 
1359
 
 
1360
  /***************************************************************************
 
1361
   * API
 
1362
   ***************************************************************************/
 
1363
  {
 
1364
    CFG_SECTION_NODE,
 
1365
    API_TOKEN,
 
1366
    API_TOKEN,
 
1367
    "Node section",
 
1368
    ConfigInfo::CI_USED,
 
1369
    false,
 
1370
    ConfigInfo::CI_SECTION,
 
1371
    (const char *)NODE_TYPE_API, 
 
1372
    0, 0
 
1373
  },
 
1374
 
 
1375
  {
 
1376
    CFG_NODE_HOST,
 
1377
    "HostName",
 
1378
    API_TOKEN,
 
1379
    "Name of computer for this node",
 
1380
    ConfigInfo::CI_INTERNAL,
 
1381
    false,
 
1382
    ConfigInfo::CI_STRING,
 
1383
    "",
 
1384
    0, 0 },
 
1385
 
 
1386
  {
 
1387
    CFG_NODE_SYSTEM,
 
1388
    "System",
 
1389
    API_TOKEN,
 
1390
    "Name of system for this node",
 
1391
    ConfigInfo::CI_INTERNAL,
 
1392
    false,
 
1393
    ConfigInfo::CI_STRING,
 
1394
    UNDEFINED,
 
1395
    0, 0 },
 
1396
 
 
1397
  {
 
1398
    KEY_INTERNAL,
 
1399
    "Id",
 
1400
    API_TOKEN,
 
1401
    "",
 
1402
    ConfigInfo::CI_DEPRICATED,
 
1403
    false,
 
1404
    ConfigInfo::CI_INT,
 
1405
    MANDATORY,
 
1406
    "1",
 
1407
    STR_VALUE(MAX_NODES_ID) },
 
1408
 
 
1409
  {
 
1410
    CFG_NODE_ID,
 
1411
    "NodeId",
 
1412
    API_TOKEN,
 
1413
    "Number identifying application node ("API_TOKEN_PRINT")",
 
1414
    ConfigInfo::CI_USED,
 
1415
    false,
 
1416
    ConfigInfo::CI_INT,
 
1417
    MANDATORY,
 
1418
    "1",
 
1419
    STR_VALUE(MAX_NODES_ID) },
 
1420
 
 
1421
  {
 
1422
    KEY_INTERNAL,
 
1423
    "ExecuteOnComputer",
 
1424
    API_TOKEN,
 
1425
    "String referencing an earlier defined COMPUTER",
 
1426
    ConfigInfo::CI_USED,
 
1427
    false,
 
1428
    ConfigInfo::CI_STRING,
 
1429
    UNDEFINED,
 
1430
    0, 0 },
 
1431
 
 
1432
  {
 
1433
    CFG_NODE_ARBIT_RANK,
 
1434
    "ArbitrationRank",
 
1435
    API_TOKEN,
 
1436
    "If 0, then "API_TOKEN_PRINT" is not arbitrator. Kernel selects arbitrators in order 1, 2",
 
1437
    ConfigInfo::CI_USED,
 
1438
    false,
 
1439
    ConfigInfo::CI_INT,
 
1440
    "0",
 
1441
    "0",
 
1442
    "2" },
 
1443
 
 
1444
  {
 
1445
    CFG_NODE_ARBIT_DELAY,
 
1446
    "ArbitrationDelay",
 
1447
    API_TOKEN,
 
1448
    "When asked to arbitrate, arbitrator waits this long before voting (msec)",
 
1449
    ConfigInfo::CI_USED,
 
1450
    false,
 
1451
    ConfigInfo::CI_INT,
 
1452
    "0",
 
1453
    "0",
 
1454
    STR_VALUE(MAX_INT_RNIL) },
 
1455
 
 
1456
  {
 
1457
    CFG_MAX_SCAN_BATCH_SIZE,
 
1458
    "MaxScanBatchSize",
 
1459
    "API",
 
1460
    "The maximum collective batch size for one scan",
 
1461
    ConfigInfo::CI_USED,
 
1462
    false,
 
1463
    ConfigInfo::CI_INT,
 
1464
    STR_VALUE(MAX_SCAN_BATCH_SIZE),
 
1465
    "32k",
 
1466
    "16M" },
 
1467
  
 
1468
  {
 
1469
    CFG_BATCH_BYTE_SIZE,
 
1470
    "BatchByteSize",
 
1471
    "API",
 
1472
    "The default batch size in bytes",
 
1473
    ConfigInfo::CI_USED,
 
1474
    false,
 
1475
    ConfigInfo::CI_INT,
 
1476
    STR_VALUE(SCAN_BATCH_SIZE),
 
1477
    "1k",
 
1478
    "1M" },
 
1479
 
 
1480
  {
 
1481
    CFG_BATCH_SIZE,
 
1482
    "BatchSize",
 
1483
    "API",
 
1484
    "The default batch size in number of records",
 
1485
    ConfigInfo::CI_USED,
 
1486
    false,
 
1487
    ConfigInfo::CI_INT,
 
1488
    STR_VALUE(DEF_BATCH_SIZE),
 
1489
    "1",
 
1490
    STR_VALUE(MAX_PARALLEL_OP_PER_SCAN) },
 
1491
 
 
1492
  /****************************************************************************
 
1493
   * MGM
 
1494
   ***************************************************************************/
 
1495
  {
 
1496
    CFG_SECTION_NODE,
 
1497
    MGM_TOKEN,
 
1498
    MGM_TOKEN,
 
1499
    "Node section",
 
1500
    ConfigInfo::CI_USED,
 
1501
    false,
 
1502
    ConfigInfo::CI_SECTION,
 
1503
    (const char *)NODE_TYPE_MGM, 
 
1504
    0, 0
 
1505
  },
 
1506
 
 
1507
  {
 
1508
    CFG_NODE_HOST,
 
1509
    "HostName",
 
1510
    MGM_TOKEN,
 
1511
    "Name of computer for this node",
 
1512
    ConfigInfo::CI_INTERNAL,
 
1513
    false,
 
1514
    ConfigInfo::CI_STRING,
 
1515
    "",
 
1516
    0, 0 },
 
1517
 
 
1518
  {
 
1519
    CFG_NODE_DATADIR,
 
1520
    "DataDir",
 
1521
    MGM_TOKEN,
 
1522
    "Data directory for this node",
 
1523
    ConfigInfo::CI_USED,
 
1524
    false,
 
1525
    ConfigInfo::CI_STRING,
 
1526
    MYSQLCLUSTERDIR,
 
1527
    0, 0 },
 
1528
 
 
1529
  {
 
1530
    CFG_NODE_SYSTEM,
 
1531
    "System",
 
1532
    MGM_TOKEN,
 
1533
    "Name of system for this node",
 
1534
    ConfigInfo::CI_INTERNAL,
 
1535
    false,
 
1536
    ConfigInfo::CI_STRING,
 
1537
    UNDEFINED,
 
1538
    0, 0 },
 
1539
 
 
1540
  {
 
1541
    KEY_INTERNAL,
 
1542
    "Id",
 
1543
    MGM_TOKEN,
 
1544
    "",
 
1545
    ConfigInfo::CI_DEPRICATED,
 
1546
    false,
 
1547
    ConfigInfo::CI_INT,
 
1548
    MANDATORY,
 
1549
    "1",
 
1550
    STR_VALUE(MAX_NODES_ID) },
 
1551
  
 
1552
  {
 
1553
    CFG_NODE_ID,
 
1554
    "NodeId",
 
1555
    MGM_TOKEN,
 
1556
    "Number identifying the management server node ("MGM_TOKEN_PRINT")",
 
1557
    ConfigInfo::CI_USED,
 
1558
    false,
 
1559
    ConfigInfo::CI_INT,
 
1560
    MANDATORY,
 
1561
    "1",
 
1562
    STR_VALUE(MAX_NODES_ID) },
 
1563
  
 
1564
  {
 
1565
    CFG_LOG_DESTINATION,
 
1566
    "LogDestination",
 
1567
    MGM_TOKEN,
 
1568
    "String describing where logmessages are sent",
 
1569
    ConfigInfo::CI_USED,
 
1570
    false,
 
1571
    ConfigInfo::CI_STRING,
 
1572
    0,
 
1573
    0, 0 },
 
1574
  
 
1575
  {
 
1576
    KEY_INTERNAL,
 
1577
    "ExecuteOnComputer",
 
1578
    MGM_TOKEN,
 
1579
    "String referencing an earlier defined COMPUTER",
 
1580
    ConfigInfo::CI_USED,
 
1581
    false,
 
1582
    ConfigInfo::CI_STRING,
 
1583
    0,
 
1584
    0, 0 },
 
1585
 
 
1586
  {
 
1587
    KEY_INTERNAL,
 
1588
    "MaxNoOfSavedEvents",
 
1589
    MGM_TOKEN,
 
1590
    "",
 
1591
    ConfigInfo::CI_USED,
 
1592
    false,
 
1593
    ConfigInfo::CI_INT,
 
1594
    "100",
 
1595
    "0",
 
1596
    STR_VALUE(MAX_INT_RNIL) },
 
1597
 
 
1598
  {
 
1599
    CFG_MGM_PORT,
 
1600
    "PortNumber",
 
1601
    MGM_TOKEN,
 
1602
    "Port number to give commands to/fetch configurations from management server",
 
1603
    ConfigInfo::CI_USED,
 
1604
    false,
 
1605
    ConfigInfo::CI_INT,
 
1606
    NDB_PORT,
 
1607
    "0",
 
1608
    STR_VALUE(MAX_PORT_NO) },
 
1609
 
 
1610
  {
 
1611
    KEY_INTERNAL,
 
1612
    "PortNumberStats",
 
1613
    MGM_TOKEN,
 
1614
    "Port number used to get statistical information from a management server",
 
1615
    ConfigInfo::CI_USED,
 
1616
    false,
 
1617
    ConfigInfo::CI_INT,
 
1618
    UNDEFINED,
 
1619
    "0",
 
1620
    STR_VALUE(MAX_PORT_NO) },
 
1621
 
 
1622
  {
 
1623
    CFG_NODE_ARBIT_RANK,
 
1624
    "ArbitrationRank",
 
1625
    MGM_TOKEN,
 
1626
    "If 0, then "MGM_TOKEN_PRINT" is not arbitrator. Kernel selects arbitrators in order 1, 2",
 
1627
    ConfigInfo::CI_USED,
 
1628
    false,
 
1629
    ConfigInfo::CI_INT,
 
1630
    "1",
 
1631
    "0",
 
1632
    "2" },
 
1633
 
 
1634
  {
 
1635
    CFG_NODE_ARBIT_DELAY,
 
1636
    "ArbitrationDelay",
 
1637
    MGM_TOKEN,
 
1638
    "",
 
1639
    ConfigInfo::CI_USED,
 
1640
    false,
 
1641
    ConfigInfo::CI_INT,
 
1642
    "0",
 
1643
    "0",
 
1644
    STR_VALUE(MAX_INT_RNIL) },
 
1645
 
 
1646
  /****************************************************************************
 
1647
   * TCP
 
1648
   ***************************************************************************/
 
1649
  {
 
1650
    CFG_SECTION_CONNECTION,
 
1651
    "TCP",
 
1652
    "TCP",
 
1653
    "Connection section",
 
1654
    ConfigInfo::CI_USED,
 
1655
    false,
 
1656
    ConfigInfo::CI_SECTION,
 
1657
    (const char *)CONNECTION_TYPE_TCP, 
 
1658
    0, 0
 
1659
  },
 
1660
 
 
1661
  {
 
1662
    CFG_CONNECTION_HOSTNAME_1,
 
1663
    "HostName1",
 
1664
    "TCP",
 
1665
    "Name/IP of computer on one side of the connection",
 
1666
    ConfigInfo::CI_INTERNAL,
 
1667
    false,
 
1668
    ConfigInfo::CI_STRING,
 
1669
    UNDEFINED,
 
1670
    0, 0 },
 
1671
 
 
1672
  {
 
1673
    CFG_CONNECTION_HOSTNAME_2,
 
1674
    "HostName2",
 
1675
    "TCP",
 
1676
    "Name/IP of computer on one side of the connection",
 
1677
    ConfigInfo::CI_INTERNAL,
 
1678
    false,
 
1679
    ConfigInfo::CI_STRING,
 
1680
    UNDEFINED,
 
1681
    0, 0 },
 
1682
 
 
1683
  {
 
1684
    CFG_CONNECTION_NODE_1,
 
1685
    "NodeId1",
 
1686
    "TCP",
 
1687
    "Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection",
 
1688
    ConfigInfo::CI_USED,
 
1689
    false,
 
1690
    ConfigInfo::CI_STRING,
 
1691
    MANDATORY,
 
1692
    0, 0 },
 
1693
 
 
1694
  {
 
1695
    CFG_CONNECTION_NODE_2,
 
1696
    "NodeId2",
 
1697
    "TCP",
 
1698
    "Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection",
 
1699
    ConfigInfo::CI_USED,
 
1700
    false,
 
1701
    ConfigInfo::CI_STRING,
 
1702
    MANDATORY,
 
1703
    0, 0 },
 
1704
 
 
1705
  {
 
1706
    CFG_CONNECTION_GROUP,
 
1707
    "Group",
 
1708
    "TCP",
 
1709
    "",
 
1710
    ConfigInfo::CI_USED,
 
1711
    false,
 
1712
    ConfigInfo::CI_INT,
 
1713
    "55",
 
1714
    "0", "200" },
 
1715
 
 
1716
  {
 
1717
    CFG_CONNECTION_NODE_ID_SERVER,
 
1718
    "NodeIdServer",
 
1719
    "TCP",
 
1720
    "",
 
1721
    ConfigInfo::CI_USED,
 
1722
    false,
 
1723
    ConfigInfo::CI_INT,
 
1724
    MANDATORY,
 
1725
    "1", "63" },
 
1726
 
 
1727
  {
 
1728
    CFG_CONNECTION_SEND_SIGNAL_ID,
 
1729
    "SendSignalId",
 
1730
    "TCP",
 
1731
    "Sends id in each signal.  Used in trace files.",
 
1732
    ConfigInfo::CI_USED,
 
1733
    false,
 
1734
    ConfigInfo::CI_BOOL,
 
1735
    "true",
 
1736
    "false",
 
1737
    "true" },
 
1738
 
 
1739
 
 
1740
  {
 
1741
    CFG_CONNECTION_CHECKSUM,
 
1742
    "Checksum",
 
1743
    "TCP",
 
1744
    "If checksum is enabled, all signals between nodes are checked for errors",
 
1745
    ConfigInfo::CI_USED,
 
1746
    false,
 
1747
    ConfigInfo::CI_BOOL,
 
1748
    "false",
 
1749
    "false",
 
1750
    "true" },
 
1751
 
 
1752
  {
 
1753
    CFG_CONNECTION_SERVER_PORT,
 
1754
    "PortNumber",
 
1755
    "TCP",
 
1756
    "Port used for this transporter",
 
1757
    ConfigInfo::CI_USED,
 
1758
    false,
 
1759
    ConfigInfo::CI_INT,
 
1760
    MANDATORY,
 
1761
    "0",
 
1762
    STR_VALUE(MAX_PORT_NO) },
 
1763
 
 
1764
  {
 
1765
    CFG_TCP_SEND_BUFFER_SIZE,
 
1766
    "SendBufferMemory",
 
1767
    "TCP",
 
1768
    "Bytes of buffer for signals sent from this node",
 
1769
    ConfigInfo::CI_USED,
 
1770
    false,
 
1771
    ConfigInfo::CI_INT,
 
1772
    "256K",
 
1773
    "64K",
 
1774
    STR_VALUE(MAX_INT_RNIL) },
 
1775
 
 
1776
  {
 
1777
    CFG_TCP_RECEIVE_BUFFER_SIZE,
 
1778
    "ReceiveBufferMemory",
 
1779
    "TCP",
 
1780
    "Bytes of buffer for signals received by this node",
 
1781
    ConfigInfo::CI_USED,
 
1782
    false,
 
1783
    ConfigInfo::CI_INT,
 
1784
    "64K",
 
1785
    "16K",
 
1786
    STR_VALUE(MAX_INT_RNIL) },
 
1787
 
 
1788
  {
 
1789
    CFG_TCP_PROXY,
 
1790
    "Proxy",
 
1791
    "TCP",
 
1792
    "",
 
1793
    ConfigInfo::CI_USED,
 
1794
    false,
 
1795
    ConfigInfo::CI_STRING,
 
1796
    UNDEFINED,
 
1797
    0, 0 },
 
1798
 
 
1799
  {
 
1800
    CFG_CONNECTION_NODE_1_SYSTEM,
 
1801
    "NodeId1_System",
 
1802
    "TCP",
 
1803
    "System for node 1 in connection",
 
1804
    ConfigInfo::CI_INTERNAL,
 
1805
    false,
 
1806
    ConfigInfo::CI_STRING,
 
1807
    UNDEFINED,
 
1808
    0, 0 },
 
1809
 
 
1810
  {
 
1811
    CFG_CONNECTION_NODE_2_SYSTEM,
 
1812
    "NodeId2_System",
 
1813
    "TCP",
 
1814
    "System for node 2 in connection",
 
1815
    ConfigInfo::CI_INTERNAL,
 
1816
    false,
 
1817
    ConfigInfo::CI_STRING,
 
1818
    UNDEFINED,
 
1819
    0, 0 },
 
1820
  
 
1821
 
 
1822
  /****************************************************************************
 
1823
   * SHM
 
1824
   ***************************************************************************/
 
1825
  {
 
1826
    CFG_SECTION_CONNECTION,
 
1827
    "SHM",
 
1828
    "SHM",
 
1829
    "Connection section",
 
1830
    ConfigInfo::CI_USED,
 
1831
    false,
 
1832
    ConfigInfo::CI_SECTION,
 
1833
    (const char *)CONNECTION_TYPE_SHM, 
 
1834
    0, 0 },
 
1835
 
 
1836
  {
 
1837
    CFG_CONNECTION_HOSTNAME_1,
 
1838
    "HostName1",
 
1839
    "SHM",
 
1840
    "Name/IP of computer on one side of the connection",
 
1841
    ConfigInfo::CI_INTERNAL,
 
1842
    false,
 
1843
    ConfigInfo::CI_STRING,
 
1844
    UNDEFINED,
 
1845
    0, 0 },
 
1846
 
 
1847
  {
 
1848
    CFG_CONNECTION_HOSTNAME_2,
 
1849
    "HostName2",
 
1850
    "SHM",
 
1851
    "Name/IP of computer on one side of the connection",
 
1852
    ConfigInfo::CI_INTERNAL,
 
1853
    false,
 
1854
    ConfigInfo::CI_STRING,
 
1855
    UNDEFINED,
 
1856
    0, 0 },
 
1857
 
 
1858
  {
 
1859
    CFG_CONNECTION_SERVER_PORT,
 
1860
    "PortNumber",
 
1861
    "SHM",
 
1862
    "Port used for this transporter",
 
1863
    ConfigInfo::CI_USED,
 
1864
    false,
 
1865
    ConfigInfo::CI_INT,
 
1866
    MANDATORY,
 
1867
    "0", 
 
1868
    STR_VALUE(MAX_PORT_NO) },
 
1869
 
 
1870
  {
 
1871
    CFG_SHM_SIGNUM,
 
1872
    "Signum",
 
1873
    "SHM",
 
1874
    "Signum to be used for signalling",
 
1875
    ConfigInfo::CI_USED,
 
1876
    false,
 
1877
    ConfigInfo::CI_INT,
 
1878
    UNDEFINED,
 
1879
    "0", 
 
1880
    STR_VALUE(MAX_INT_RNIL) },
 
1881
 
 
1882
  {
 
1883
    CFG_CONNECTION_NODE_1,
 
1884
    "NodeId1",
 
1885
    "SHM",
 
1886
    "Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection",
 
1887
    ConfigInfo::CI_USED,
 
1888
    false,
 
1889
    ConfigInfo::CI_STRING,
 
1890
    MANDATORY,
 
1891
    0, 0 },
 
1892
  
 
1893
  {
 
1894
    CFG_CONNECTION_NODE_2,
 
1895
    "NodeId2",
 
1896
    "SHM",
 
1897
    "Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection",
 
1898
    ConfigInfo::CI_USED,
 
1899
    false,
 
1900
    ConfigInfo::CI_STRING,
 
1901
    MANDATORY,
 
1902
    0, 0 },
 
1903
  
 
1904
  {
 
1905
    CFG_CONNECTION_GROUP,
 
1906
    "Group",
 
1907
    "SHM",
 
1908
    "",
 
1909
    ConfigInfo::CI_USED,
 
1910
    false,
 
1911
    ConfigInfo::CI_INT,
 
1912
    "35",
 
1913
    "0", "200" },
 
1914
 
 
1915
  {
 
1916
    CFG_CONNECTION_NODE_ID_SERVER,
 
1917
    "NodeIdServer",
 
1918
    "SHM",
 
1919
    "",
 
1920
    ConfigInfo::CI_USED,
 
1921
    false,
 
1922
    ConfigInfo::CI_INT,
 
1923
    MANDATORY,
 
1924
    "1", "63" },
 
1925
 
 
1926
  {
 
1927
    CFG_CONNECTION_SEND_SIGNAL_ID,
 
1928
    "SendSignalId",
 
1929
    "SHM",
 
1930
    "Sends id in each signal.  Used in trace files.",
 
1931
    ConfigInfo::CI_USED,
 
1932
    false,
 
1933
    ConfigInfo::CI_BOOL,
 
1934
    "false",
 
1935
    "false",
 
1936
    "true" },
 
1937
  
 
1938
  
 
1939
  {
 
1940
    CFG_CONNECTION_CHECKSUM,
 
1941
    "Checksum",
 
1942
    "SHM",
 
1943
    "If checksum is enabled, all signals between nodes are checked for errors",
 
1944
    ConfigInfo::CI_USED,
 
1945
    false,
 
1946
    ConfigInfo::CI_BOOL,
 
1947
    "true",
 
1948
    "false",
 
1949
    "true" },
 
1950
  
 
1951
  {
 
1952
    CFG_SHM_KEY,
 
1953
    "ShmKey",
 
1954
    "SHM",
 
1955
    "A shared memory key",
 
1956
    ConfigInfo::CI_USED,
 
1957
    false,
 
1958
    ConfigInfo::CI_INT,
 
1959
    UNDEFINED,
 
1960
    "0",
 
1961
    STR_VALUE(MAX_INT_RNIL) },
 
1962
  
 
1963
  {
 
1964
    CFG_SHM_BUFFER_MEM,
 
1965
    "ShmSize",
 
1966
    "SHM",
 
1967
    "Size of shared memory segment",
 
1968
    ConfigInfo::CI_USED,
 
1969
    false,
 
1970
    ConfigInfo::CI_INT,
 
1971
    "1M",
 
1972
    "64K",
 
1973
    STR_VALUE(MAX_INT_RNIL) },
 
1974
 
 
1975
  {
 
1976
    CFG_CONNECTION_NODE_1_SYSTEM,
 
1977
    "NodeId1_System",
 
1978
    "SHM",
 
1979
    "System for node 1 in connection",
 
1980
    ConfigInfo::CI_INTERNAL,
 
1981
    false,
 
1982
    ConfigInfo::CI_STRING,
 
1983
    UNDEFINED,
 
1984
    0, 0 },
 
1985
 
 
1986
  {
 
1987
    CFG_CONNECTION_NODE_2_SYSTEM,
 
1988
    "NodeId2_System",
 
1989
    "SHM",
 
1990
    "System for node 2 in connection",
 
1991
    ConfigInfo::CI_INTERNAL,
 
1992
    false,
 
1993
    ConfigInfo::CI_STRING,
 
1994
    UNDEFINED,
 
1995
    0, 0 },
 
1996
 
 
1997
  /****************************************************************************
 
1998
   * SCI
 
1999
   ***************************************************************************/
 
2000
  {
 
2001
    CFG_SECTION_CONNECTION,
 
2002
    "SCI",
 
2003
    "SCI",
 
2004
    "Connection section",
 
2005
    ConfigInfo::CI_USED,
 
2006
    false,
 
2007
    ConfigInfo::CI_SECTION,
 
2008
    (const char *)CONNECTION_TYPE_SCI, 
 
2009
    0, 0 
 
2010
  },
 
2011
 
 
2012
  {
 
2013
    CFG_CONNECTION_NODE_1,
 
2014
    "NodeId1",
 
2015
    "SCI",
 
2016
    "Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection",
 
2017
    ConfigInfo::CI_USED,
 
2018
    false,
 
2019
    ConfigInfo::CI_STRING,
 
2020
    MANDATORY,
 
2021
    "0",
 
2022
    STR_VALUE(MAX_INT_RNIL) },
 
2023
 
 
2024
  {
 
2025
    CFG_CONNECTION_NODE_2,
 
2026
    "NodeId2",
 
2027
    "SCI",
 
2028
    "Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection",
 
2029
    ConfigInfo::CI_USED,
 
2030
    false,
 
2031
    ConfigInfo::CI_STRING,
 
2032
    MANDATORY,
 
2033
    "0",
 
2034
    STR_VALUE(MAX_INT_RNIL) },
 
2035
 
 
2036
  {
 
2037
    CFG_CONNECTION_GROUP,
 
2038
    "Group",
 
2039
    "SCI",
 
2040
    "",
 
2041
    ConfigInfo::CI_USED,
 
2042
    false,
 
2043
    ConfigInfo::CI_INT,
 
2044
    "15",
 
2045
    "0", "200" },
 
2046
 
 
2047
  {
 
2048
    CFG_CONNECTION_NODE_ID_SERVER,
 
2049
    "NodeIdServer",
 
2050
    "SCI",
 
2051
    "",
 
2052
    ConfigInfo::CI_USED,
 
2053
    false,
 
2054
    ConfigInfo::CI_INT,
 
2055
    MANDATORY,
 
2056
    "1", "63" },
 
2057
 
 
2058
  {
 
2059
    CFG_CONNECTION_HOSTNAME_1,
 
2060
    "HostName1",
 
2061
    "SCI",
 
2062
    "Name/IP of computer on one side of the connection",
 
2063
    ConfigInfo::CI_INTERNAL,
 
2064
    false,
 
2065
    ConfigInfo::CI_STRING,
 
2066
    UNDEFINED,
 
2067
    0, 0 },
 
2068
 
 
2069
  {
 
2070
    CFG_CONNECTION_HOSTNAME_2,
 
2071
    "HostName2",
 
2072
    "SCI",
 
2073
    "Name/IP of computer on one side of the connection",
 
2074
    ConfigInfo::CI_INTERNAL,
 
2075
    false,
 
2076
    ConfigInfo::CI_STRING,
 
2077
    UNDEFINED,
 
2078
    0, 0 },
 
2079
 
 
2080
  {
 
2081
    CFG_CONNECTION_SERVER_PORT,
 
2082
    "PortNumber",
 
2083
    "SCI",
 
2084
    "Port used for this transporter",
 
2085
    ConfigInfo::CI_USED,
 
2086
    false,
 
2087
    ConfigInfo::CI_INT,
 
2088
    MANDATORY,
 
2089
    "0", 
 
2090
    STR_VALUE(MAX_PORT_NO) },
 
2091
 
 
2092
  {
 
2093
    CFG_SCI_HOST1_ID_0,
 
2094
    "Host1SciId0",
 
2095
    "SCI",
 
2096
    "SCI-node id for adapter 0 on Host1 (a computer can have two adapters)",
 
2097
    ConfigInfo::CI_USED,
 
2098
    false,
 
2099
    ConfigInfo::CI_INT,
 
2100
    MANDATORY,
 
2101
    "0",
 
2102
    STR_VALUE(MAX_INT_RNIL) },
 
2103
 
 
2104
  {
 
2105
    CFG_SCI_HOST1_ID_1,
 
2106
    "Host1SciId1",
 
2107
    "SCI",
 
2108
    "SCI-node id for adapter 1 on Host1 (a computer can have two adapters)",
 
2109
    ConfigInfo::CI_USED,
 
2110
    false,
 
2111
    ConfigInfo::CI_INT,
 
2112
    "0",
 
2113
    "0",
 
2114
    STR_VALUE(MAX_INT_RNIL) },
 
2115
 
 
2116
  {
 
2117
    CFG_SCI_HOST2_ID_0,
 
2118
    "Host2SciId0",
 
2119
    "SCI",
 
2120
    "SCI-node id for adapter 0 on Host2 (a computer can have two adapters)",
 
2121
    ConfigInfo::CI_USED,
 
2122
    false,
 
2123
    ConfigInfo::CI_INT,
 
2124
    MANDATORY,
 
2125
    "0",
 
2126
    STR_VALUE(MAX_INT_RNIL) },
 
2127
 
 
2128
  {
 
2129
    CFG_SCI_HOST2_ID_1,
 
2130
    "Host2SciId1",
 
2131
    "SCI",
 
2132
    "SCI-node id for adapter 1 on Host2 (a computer can have two adapters)",
 
2133
    ConfigInfo::CI_USED,
 
2134
    false,
 
2135
    ConfigInfo::CI_INT,
 
2136
    "0",
 
2137
    "0",
 
2138
    STR_VALUE(MAX_INT_RNIL) },
 
2139
 
 
2140
  {
 
2141
    CFG_CONNECTION_SEND_SIGNAL_ID,
 
2142
    "SendSignalId",
 
2143
    "SCI",
 
2144
    "Sends id in each signal.  Used in trace files.",
 
2145
    ConfigInfo::CI_USED,
 
2146
    false,
 
2147
    ConfigInfo::CI_BOOL,
 
2148
    "true",
 
2149
    "false",
 
2150
    "true" },
 
2151
 
 
2152
  {
 
2153
    CFG_CONNECTION_CHECKSUM,
 
2154
    "Checksum",
 
2155
    "SCI",
 
2156
    "If checksum is enabled, all signals between nodes are checked for errors",
 
2157
    ConfigInfo::CI_USED,
 
2158
    false,
 
2159
    ConfigInfo::CI_BOOL,
 
2160
    "false",
 
2161
    "false",
 
2162
    "true" },
 
2163
 
 
2164
  {
 
2165
    CFG_SCI_SEND_LIMIT,
 
2166
    "SendLimit",
 
2167
    "SCI",
 
2168
    "Transporter send buffer contents are sent when this no of bytes is buffered",
 
2169
    ConfigInfo::CI_USED,
 
2170
    false,
 
2171
    ConfigInfo::CI_INT,
 
2172
    "8K",
 
2173
    "128",
 
2174
    "32K" },
 
2175
 
 
2176
  {
 
2177
    CFG_SCI_BUFFER_MEM,
 
2178
    "SharedBufferSize",
 
2179
    "SCI",
 
2180
    "Size of shared memory segment",
 
2181
    ConfigInfo::CI_USED,
 
2182
    false,
 
2183
    ConfigInfo::CI_INT,
 
2184
    "1M",
 
2185
    "64K",
 
2186
    STR_VALUE(MAX_INT_RNIL) },
 
2187
 
 
2188
  {
 
2189
    CFG_CONNECTION_NODE_1_SYSTEM,
 
2190
    "NodeId1_System",
 
2191
    "SCI",
 
2192
    "System for node 1 in connection",
 
2193
    ConfigInfo::CI_INTERNAL,
 
2194
    false,
 
2195
    ConfigInfo::CI_STRING,
 
2196
    UNDEFINED,
 
2197
    0, 0 },
 
2198
 
 
2199
  {
 
2200
    CFG_CONNECTION_NODE_2_SYSTEM,
 
2201
    "NodeId2_System",
 
2202
    "SCI",
 
2203
    "System for node 2 in connection",
 
2204
    ConfigInfo::CI_INTERNAL,
 
2205
    false,
 
2206
    ConfigInfo::CI_STRING,
 
2207
    UNDEFINED,
 
2208
    0, 0 }
 
2209
};
 
2210
 
 
2211
const int ConfigInfo::m_NoOfParams = sizeof(m_ParamInfo) / sizeof(ParamInfo);
 
2212
 
 
2213
#ifndef NDB_MGMAPI
 
2214
/****************************************************************************
 
2215
 * Ctor
 
2216
 ****************************************************************************/
 
2217
static void require(bool v)
 
2218
{
 
2219
  if(!v)
 
2220
  {
 
2221
    if (opt_core)
 
2222
      abort();
 
2223
    else
 
2224
      exit(-1);
 
2225
  }
 
2226
}
 
2227
 
 
2228
ConfigInfo::ConfigInfo()
 
2229
  : m_info(true), m_systemDefaults(true)
 
2230
{
 
2231
  int i;
 
2232
  Properties *section;
 
2233
  const Properties *oldpinfo;
 
2234
 
 
2235
  for (i=0; i<m_NoOfParams; i++) {
 
2236
    const ParamInfo & param = m_ParamInfo[i];
 
2237
    Uint64 default_uint64;
 
2238
    bool   default_bool;
 
2239
    
 
2240
    // Create new section if it did not exist
 
2241
    if (!m_info.getCopy(param._section, &section)) {
 
2242
      Properties newsection(true);
 
2243
      m_info.put(param._section, &newsection);
 
2244
 
 
2245
      // Get copy of section
 
2246
      m_info.getCopy(param._section, &section);
 
2247
    }
 
2248
 
 
2249
    // Create pinfo (parameter info) entry 
 
2250
    Properties pinfo(true); 
 
2251
    pinfo.put("Id",          param._paramId);
 
2252
    pinfo.put("Fname",       param._fname);
 
2253
    pinfo.put("Description", param._description);
 
2254
    pinfo.put("Updateable",  param._updateable);
 
2255
    pinfo.put("Type",        param._type);
 
2256
    pinfo.put("Status",      param._status);
 
2257
 
 
2258
    if(param._default == MANDATORY){
 
2259
      pinfo.put("Mandatory", (Uint32)1);
 
2260
    }
 
2261
 
 
2262
    switch (param._type) {
 
2263
      case CI_BOOL:
 
2264
      {
 
2265
        bool tmp_bool;
 
2266
        require(InitConfigFileParser::convertStringToBool(param._min, tmp_bool));
 
2267
        pinfo.put64("Min", tmp_bool);
 
2268
        require(InitConfigFileParser::convertStringToBool(param._max, tmp_bool));
 
2269
        pinfo.put64("Max", tmp_bool);
 
2270
        break;
 
2271
      }
 
2272
      case CI_INT:
 
2273
      case CI_INT64:
 
2274
      {
 
2275
        Uint64 tmp_uint64;
 
2276
        require(InitConfigFileParser::convertStringToUint64(param._min, tmp_uint64));
 
2277
        pinfo.put64("Min", tmp_uint64);
 
2278
        require(InitConfigFileParser::convertStringToUint64(param._max, tmp_uint64));
 
2279
        pinfo.put64("Max", tmp_uint64);
 
2280
        break;
 
2281
      }
 
2282
      case CI_SECTION:
 
2283
        pinfo.put("SectionType", (Uint32)UintPtr(param._default));
 
2284
        break;
 
2285
      case CI_STRING:
 
2286
        break;
 
2287
    }
 
2288
 
 
2289
    // Check that pinfo is really new
 
2290
    if (section->get(param._fname, &oldpinfo)) {
 
2291
      ndbout << "Error: Parameter " << param._fname
 
2292
             << " defined twice in section " << param._section
 
2293
             << "." << endl;
 
2294
      require(false);
 
2295
    }
 
2296
    
 
2297
    // Add new pinfo to section
 
2298
    section->put(param._fname, &pinfo);
 
2299
 
 
2300
    // Replace section with modified section
 
2301
    m_info.put(param._section, section, true);
 
2302
    delete section;
 
2303
    
 
2304
    if(param._type != ConfigInfo::CI_SECTION){
 
2305
      Properties * p;
 
2306
      if(!m_systemDefaults.getCopy(param._section, &p)){
 
2307
        p = new Properties(true);
 
2308
      }
 
2309
      if(param._default != UNDEFINED &&
 
2310
         param._default != MANDATORY){
 
2311
        switch (param._type)
 
2312
        {
 
2313
          case CI_SECTION:
 
2314
            break;
 
2315
          case CI_STRING:
 
2316
            require(p->put(param._fname, param._default));
 
2317
            break;
 
2318
          case CI_BOOL:
 
2319
            {
 
2320
              require(InitConfigFileParser::convertStringToBool(param._default, default_bool));
 
2321
              require(p->put(param._fname, default_bool));
 
2322
              break;
 
2323
            }
 
2324
          case CI_INT:
 
2325
          case CI_INT64:
 
2326
            {
 
2327
              require(InitConfigFileParser::convertStringToUint64(param._default, default_uint64));
 
2328
              require(p->put(param._fname, default_uint64));
 
2329
              break;
 
2330
            }
 
2331
        }
 
2332
      }
 
2333
      require(m_systemDefaults.put(param._section, p, true));
 
2334
      delete p;
 
2335
    }
 
2336
  }
 
2337
  
 
2338
  for (i=0; i<m_NoOfParams; i++) {
 
2339
    if(m_ParamInfo[i]._section == NULL){
 
2340
      ndbout << "Check that each entry has a section failed." << endl;
 
2341
      ndbout << "Parameter \"" << m_ParamInfo[i]._fname << endl; 
 
2342
      ndbout << "Edit file " << __FILE__ << "." << endl;
 
2343
      require(false);
 
2344
    }
 
2345
    
 
2346
    if(m_ParamInfo[i]._type == ConfigInfo::CI_SECTION)
 
2347
      continue;
 
2348
 
 
2349
    const Properties * p = getInfo(m_ParamInfo[i]._section);
 
2350
    if (!p || !p->contains(m_ParamInfo[i]._fname)) {
 
2351
      ndbout << "Check that each pname has an fname failed." << endl;
 
2352
      ndbout << "Parameter \"" << m_ParamInfo[i]._fname 
 
2353
             << "\" does not exist in section \"" 
 
2354
             << m_ParamInfo[i]._section << "\"." << endl;
 
2355
      ndbout << "Edit file " << __FILE__ << "." << endl;
 
2356
      require(false);
 
2357
    }
 
2358
  }
 
2359
}
 
2360
 
 
2361
/****************************************************************************
 
2362
 * Getters
 
2363
 ****************************************************************************/
 
2364
inline void warning(const char * src, const char * arg){
 
2365
  ndbout << "Illegal call to ConfigInfo::" << src << "() - " << arg << endl;
 
2366
  require(false);
 
2367
}
 
2368
 
 
2369
const Properties * 
 
2370
ConfigInfo::getInfo(const char * section) const {
 
2371
  const Properties * p;
 
2372
  if(!m_info.get(section, &p)){
 
2373
    return 0;
 
2374
    //    warning("getInfo", section);
 
2375
  }
 
2376
  return p;
 
2377
}
 
2378
 
 
2379
const Properties * 
 
2380
ConfigInfo::getDefaults(const char * section) const {
 
2381
  const Properties * p;
 
2382
  if(!m_systemDefaults.get(section, &p)){
 
2383
    return 0;
 
2384
    //warning("getDefaults", section);
 
2385
  }
 
2386
  return p;
 
2387
}
 
2388
 
 
2389
static
 
2390
Uint64
 
2391
getInfoInt(const Properties * section, 
 
2392
           const char* fname, const char * type){
 
2393
  Uint32 val32;
 
2394
  const Properties * p;
 
2395
  if (section->get(fname, &p) && p->get(type, &val32)) {
 
2396
    return val32;
 
2397
  }
 
2398
 
 
2399
  Uint64 val64;
 
2400
  if(p && p->get(type, &val64)){
 
2401
    return val64;
 
2402
  }
 
2403
  
 
2404
  section->print();
 
2405
  if(section->get(fname, &p)){
 
2406
    p->print();
 
2407
  }
 
2408
 
 
2409
  warning(type, fname);
 
2410
  return 0;
 
2411
}
 
2412
 
 
2413
static
 
2414
const char *
 
2415
getInfoString(const Properties * section, 
 
2416
              const char* fname, const char * type){
 
2417
  const char* val;
 
2418
  const Properties * p;
 
2419
  if (section->get(fname, &p) && p->get(type, &val)) {
 
2420
    return val;
 
2421
  }
 
2422
  warning(type, fname);
 
2423
  return val;
 
2424
}
 
2425
 
 
2426
Uint64
 
2427
ConfigInfo::getMax(const Properties * section, const char* fname) const {
 
2428
  return getInfoInt(section, fname, "Max");
 
2429
}
 
2430
 
 
2431
Uint64
 
2432
ConfigInfo::getMin(const Properties * section, const char* fname) const {
 
2433
  return getInfoInt(section, fname, "Min");
 
2434
}
 
2435
 
 
2436
Uint64
 
2437
ConfigInfo::getDefault(const Properties * section, const char* fname) const {
 
2438
  return getInfoInt(section, fname, "Default");
 
2439
}
 
2440
 
 
2441
const char*
 
2442
ConfigInfo::getDescription(const Properties * section, 
 
2443
                           const char* fname) const {
 
2444
  return getInfoString(section, fname, "Description");
 
2445
}
 
2446
 
 
2447
bool
 
2448
ConfigInfo::isSection(const char * section) const {
 
2449
  for (int i = 0; i<m_noOfSectionNames; i++) {
 
2450
    if(!strcasecmp(section, m_sectionNames[i])) return true;
 
2451
  }
 
2452
  return false;
 
2453
}
 
2454
 
 
2455
const char*
 
2456
ConfigInfo::nameToAlias(const char * name) {
 
2457
  for (int i = 0; m_sectionNameAliases[i].name != 0; i++)
 
2458
    if(!strcasecmp(name, m_sectionNameAliases[i].name))
 
2459
      return m_sectionNameAliases[i].alias;
 
2460
  return 0;
 
2461
}
 
2462
 
 
2463
const char*
 
2464
ConfigInfo::getAlias(const char * section) {
 
2465
  for (int i = 0; m_sectionNameAliases[i].name != 0; i++)
 
2466
    if(!strcasecmp(section, m_sectionNameAliases[i].alias))
 
2467
      return m_sectionNameAliases[i].name;
 
2468
  return 0;
 
2469
}
 
2470
 
 
2471
bool
 
2472
ConfigInfo::verify(const Properties * section, const char* fname, 
 
2473
                   Uint64 value) const {
 
2474
  Uint64 min, max;
 
2475
 
 
2476
  min = getInfoInt(section, fname, "Min");
 
2477
  max = getInfoInt(section, fname, "Max");
 
2478
  if(min > max){
 
2479
    warning("verify", fname);
 
2480
  }
 
2481
  if (value >= min && value <= max)
 
2482
    return true;
 
2483
  else 
 
2484
    return false;
 
2485
}
 
2486
 
 
2487
ConfigInfo::Type 
 
2488
ConfigInfo::getType(const Properties * section, const char* fname) const {
 
2489
  return (ConfigInfo::Type) getInfoInt(section, fname, "Type");
 
2490
}
 
2491
 
 
2492
ConfigInfo::Status
 
2493
ConfigInfo::getStatus(const Properties * section, const char* fname) const {
 
2494
  return (ConfigInfo::Status) getInfoInt(section, fname, "Status");
 
2495
}
 
2496
 
 
2497
/****************************************************************************
 
2498
 * Printers
 
2499
 ****************************************************************************/
 
2500
 
 
2501
void ConfigInfo::print() const {
 
2502
  Properties::Iterator it(&m_info);
 
2503
  for (const char* n = it.first(); n != NULL; n = it.next()) {
 
2504
    print(n);
 
2505
  }
 
2506
}
 
2507
 
 
2508
void ConfigInfo::print(const char* section) const {
 
2509
  ndbout << "****** " << section << " ******" << endl << endl;
 
2510
  const Properties * sec = getInfo(section);
 
2511
  Properties::Iterator it(sec);
 
2512
  for (const char* n = it.first(); n != NULL; n = it.next()) {
 
2513
    // Skip entries with different F- and P-names
 
2514
    if (getStatus(sec, n) == ConfigInfo::CI_INTERNAL) continue;
 
2515
    if (getStatus(sec, n) == ConfigInfo::CI_DEPRICATED) continue;
 
2516
    if (getStatus(sec, n) == ConfigInfo::CI_NOTIMPLEMENTED) continue;
 
2517
    print(sec, n);
 
2518
  }
 
2519
}
 
2520
 
 
2521
void ConfigInfo::print(const Properties * section, 
 
2522
                       const char* parameter) const {
 
2523
  ndbout << parameter;
 
2524
  //  ndbout << getDescription(section, parameter) << endl;
 
2525
  switch (getType(section, parameter)) {
 
2526
  case ConfigInfo::CI_BOOL:
 
2527
    ndbout << " (Boolean value)" << endl;
 
2528
    ndbout << getDescription(section, parameter) << endl;
 
2529
    if (getDefault(section, parameter) == false) {
 
2530
      ndbout << "Default: N (Legal values: Y, N)" << endl; 
 
2531
    } else if (getDefault(section, parameter) == true) {
 
2532
      ndbout << "Default: Y (Legal values: Y, N)" << endl;
 
2533
    } else if (getDefault(section, parameter) == (UintPtr)MANDATORY) {
 
2534
      ndbout << "MANDATORY (Legal values: Y, N)" << endl;
 
2535
    } else {
 
2536
      ndbout << "UNKNOWN" << endl;
 
2537
    }
 
2538
    ndbout << endl;
 
2539
    break;    
 
2540
    
 
2541
  case ConfigInfo::CI_INT:
 
2542
  case ConfigInfo::CI_INT64:
 
2543
    ndbout << " (Non-negative Integer)" << endl;
 
2544
    ndbout << getDescription(section, parameter) << endl;
 
2545
    if (getDefault(section, parameter) == (UintPtr)MANDATORY) {
 
2546
      ndbout << "MANDATORY (";
 
2547
    } else if (getDefault(section, parameter) == (UintPtr)UNDEFINED) {
 
2548
      ndbout << "UNDEFINED (";
 
2549
    } else {
 
2550
      ndbout << "Default: " << getDefault(section, parameter) << " (";
 
2551
    }
 
2552
    ndbout << "Min: " << getMin(section, parameter) << ", ";
 
2553
    ndbout << "Max: " << getMax(section, parameter) << ")" << endl;
 
2554
    ndbout << endl;
 
2555
    break;
 
2556
    
 
2557
  case ConfigInfo::CI_STRING:
 
2558
    ndbout << " (String)" << endl;
 
2559
    ndbout << getDescription(section, parameter) << endl;
 
2560
    if (getDefault(section, parameter) == (UintPtr)MANDATORY) {
 
2561
      ndbout << "MANDATORY" << endl;
 
2562
    } else {
 
2563
      ndbout << "No default value" << endl;
 
2564
    }
 
2565
    ndbout << endl;
 
2566
    break;
 
2567
  case ConfigInfo::CI_SECTION:
 
2568
    break;
 
2569
  }
 
2570
}
 
2571
 
 
2572
/****************************************************************************
 
2573
 * Section Rules
 
2574
 ****************************************************************************/
 
2575
 
 
2576
/**
 
2577
 * Node rule: Add "Type" and update "NoOfNodes"
 
2578
 */
 
2579
bool
 
2580
transformNode(InitConfigFileParser::Context & ctx, const char * data){
 
2581
 
 
2582
  Uint32 id, line;
 
2583
  if(!ctx.m_currentSection->get("NodeId", &id) && !ctx.m_currentSection->get("Id", &id)){
 
2584
    Uint32 nextNodeId= 1;
 
2585
    ctx.m_userProperties.get("NextNodeId", &nextNodeId);
 
2586
    id= nextNodeId;
 
2587
    while (ctx.m_userProperties.get("AllocatedNodeId_", id, &line))
 
2588
      id++;
 
2589
    if (id != nextNodeId)
 
2590
    {
 
2591
      fprintf(stderr,"Cluster configuration warning line %d: "
 
2592
               "Could not use next node id %d for section [%s], "
 
2593
               "using next unused node id %d.\n",
 
2594
               ctx.m_sectionLineno, nextNodeId, ctx.fname, id);
 
2595
    }
 
2596
    ctx.m_currentSection->put("NodeId", id);
 
2597
  } else if(ctx.m_userProperties.get("AllocatedNodeId_", id, &line)) {
 
2598
    ctx.reportError("Duplicate nodeid in section "
 
2599
                    "[%s] starting at line: %d. Previously used on line %d.",
 
2600
                    ctx.fname, ctx.m_sectionLineno, line);
 
2601
    return false;
 
2602
  }
 
2603
 
 
2604
  if(id >= MAX_NODES)
 
2605
  {
 
2606
    ctx.reportError("too many nodes configured, only up to %d nodes supported.",
 
2607
            MAX_NODES);
 
2608
    return false;
 
2609
  } 
 
2610
 
 
2611
  // next node id _always_ next numbers after last used id
 
2612
  ctx.m_userProperties.put("NextNodeId", id+1, true);
 
2613
 
 
2614
  ctx.m_userProperties.put("AllocatedNodeId_", id, ctx.m_sectionLineno);
 
2615
  BaseString::snprintf(ctx.pname, sizeof(ctx.pname), "Node_%d", id);
 
2616
  
 
2617
  ctx.m_currentSection->put("Type", ctx.fname);
 
2618
 
 
2619
  Uint32 nodes = 0;
 
2620
  ctx.m_userProperties.get("NoOfNodes", &nodes);
 
2621
  ctx.m_userProperties.put("NoOfNodes", ++nodes, true);
 
2622
 
 
2623
  /**
 
2624
   * Update count (per type)
 
2625
   */
 
2626
  nodes = 0;
 
2627
  ctx.m_userProperties.get(ctx.fname, &nodes);
 
2628
  ctx.m_userProperties.put(ctx.fname, ++nodes, true);
 
2629
 
 
2630
  return true;
 
2631
}
 
2632
 
 
2633
static bool checkLocalhostHostnameMix(InitConfigFileParser::Context & ctx, const char * data)
 
2634
{
 
2635
  DBUG_ENTER("checkLocalhostHostnameMix");
 
2636
  const char * hostname= 0;
 
2637
  ctx.m_currentSection->get("HostName", &hostname);
 
2638
  if (hostname == 0 || hostname[0] == 0)
 
2639
    DBUG_RETURN(true);
 
2640
 
 
2641
  Uint32 localhost_used= 0;
 
2642
  if(!strcmp(hostname, "localhost") || !strcmp(hostname, "127.0.0.1")){
 
2643
    localhost_used= 1;
 
2644
    ctx.m_userProperties.put("$computer-localhost-used", localhost_used);
 
2645
    if(!ctx.m_userProperties.get("$computer-localhost", &hostname))
 
2646
      DBUG_RETURN(true);
 
2647
  } else {
 
2648
    ctx.m_userProperties.get("$computer-localhost-used", &localhost_used);
 
2649
    ctx.m_userProperties.put("$computer-localhost", hostname);
 
2650
  }
 
2651
 
 
2652
  if (localhost_used) {
 
2653
    ctx.reportError("Mixing of localhost (default for [NDBD]HostName) with other hostname(%s) is illegal",
 
2654
                    hostname);
 
2655
    DBUG_RETURN(false);
 
2656
  }
 
2657
 
 
2658
  DBUG_RETURN(true);
 
2659
}
 
2660
 
 
2661
bool
 
2662
fixNodeHostname(InitConfigFileParser::Context & ctx, const char * data)
 
2663
{
 
2664
  const char * hostname;
 
2665
  DBUG_ENTER("fixNodeHostname");
 
2666
 
 
2667
  if (ctx.m_currentSection->get("HostName", &hostname))
 
2668
    DBUG_RETURN(checkLocalhostHostnameMix(ctx,0));
 
2669
 
 
2670
  const char * compId;
 
2671
  if(!ctx.m_currentSection->get("ExecuteOnComputer", &compId))
 
2672
    DBUG_RETURN(true);
 
2673
  
 
2674
  const Properties * computer;
 
2675
  char tmp[255];
 
2676
  BaseString::snprintf(tmp, sizeof(tmp), "Computer_%s", compId);
 
2677
  if(!ctx.m_config->get(tmp, &computer)){
 
2678
    ctx.reportError("Computer \"%s\" not declared"
 
2679
                    "- [%s] starting at line: %d",
 
2680
                    compId, ctx.fname, ctx.m_sectionLineno);
 
2681
    DBUG_RETURN(false);
 
2682
  }
 
2683
  
 
2684
  if(!computer->get("HostName", &hostname)){
 
2685
    ctx.reportError("HostName missing in [COMPUTER] (Id: %d) "
 
2686
                    " - [%s] starting at line: %d",
 
2687
                    compId, ctx.fname, ctx.m_sectionLineno);
 
2688
    DBUG_RETURN(false);
 
2689
  }
 
2690
  
 
2691
  require(ctx.m_currentSection->put("HostName", hostname));
 
2692
  DBUG_RETURN(checkLocalhostHostnameMix(ctx,0));
 
2693
}
 
2694
 
 
2695
bool
 
2696
fixFileSystemPath(InitConfigFileParser::Context & ctx, const char * data){
 
2697
  DBUG_ENTER("fixFileSystemPath");
 
2698
 
 
2699
  const char * path;
 
2700
  if (ctx.m_currentSection->get("FileSystemPath", &path))
 
2701
    DBUG_RETURN(true);
 
2702
 
 
2703
  if (ctx.m_currentSection->get("DataDir", &path)) {
 
2704
    require(ctx.m_currentSection->put("FileSystemPath", path));
 
2705
    DBUG_RETURN(true);
 
2706
  }
 
2707
 
 
2708
  require(false);
 
2709
  DBUG_RETURN(false);
 
2710
}
 
2711
 
 
2712
bool
 
2713
fixBackupDataDir(InitConfigFileParser::Context & ctx, const char * data){
 
2714
  
 
2715
  const char * path;
 
2716
  if (ctx.m_currentSection->get("BackupDataDir", &path))
 
2717
    return true;
 
2718
 
 
2719
  if (ctx.m_currentSection->get("FileSystemPath", &path)) {
 
2720
    require(ctx.m_currentSection->put("BackupDataDir", path));
 
2721
    return true;
 
2722
  }
 
2723
 
 
2724
  require(false);
 
2725
  return false;
 
2726
}
 
2727
 
 
2728
/**
 
2729
 * Connection rule: Check support of connection
 
2730
 */
 
2731
bool
 
2732
checkConnectionSupport(InitConfigFileParser::Context & ctx, const char * data)
 
2733
{
 
2734
  int error= 0;
 
2735
  if (strcasecmp("TCP",ctx.fname) == 0)
 
2736
  {
 
2737
    // always enabled
 
2738
  }
 
2739
  else if (strcasecmp("SHM",ctx.fname) == 0)
 
2740
  {
 
2741
#ifndef NDB_SHM_TRANSPORTER
 
2742
    error= 1;
 
2743
#endif
 
2744
  }
 
2745
  else if (strcasecmp("SCI",ctx.fname) == 0)
 
2746
  {
 
2747
#ifndef NDB_SCI_TRANSPORTER
 
2748
    error= 1;
 
2749
#endif
 
2750
  }
 
2751
 
 
2752
  if (error)
 
2753
  {
 
2754
    ctx.reportError("Binary not compiled with this connection support, "
 
2755
                    "[%s] starting at line: %d",
 
2756
                    ctx.fname, ctx.m_sectionLineno);
 
2757
    return false;
 
2758
  }
 
2759
  return true;
 
2760
}
 
2761
 
 
2762
/**
 
2763
 * Connection rule: Update "NoOfConnections"
 
2764
 */
 
2765
bool
 
2766
transformConnection(InitConfigFileParser::Context & ctx, const char * data)
 
2767
{
 
2768
  Uint32 connections = 0;
 
2769
  ctx.m_userProperties.get("NoOfConnections", &connections);
 
2770
  BaseString::snprintf(ctx.pname, sizeof(ctx.pname), "Connection_%d", connections);
 
2771
  ctx.m_userProperties.put("NoOfConnections", ++connections, true);
 
2772
  
 
2773
  ctx.m_currentSection->put("Type", ctx.fname);
 
2774
  return true;
 
2775
}
 
2776
 
 
2777
/**
 
2778
 * System rule: Just add it
 
2779
 */
 
2780
bool
 
2781
transformSystem(InitConfigFileParser::Context & ctx, const char * data){
 
2782
 
 
2783
  const char * name;
 
2784
  if(!ctx.m_currentSection->get("Name", &name)){
 
2785
    ctx.reportError("Mandatory parameter Name missing from section "
 
2786
                    "[%s] starting at line: %d",
 
2787
                    ctx.fname, ctx.m_sectionLineno);
 
2788
    return false;
 
2789
  }
 
2790
 
 
2791
  ndbout << "transformSystem " << name << endl;
 
2792
 
 
2793
  BaseString::snprintf(ctx.pname, sizeof(ctx.pname), "SYSTEM_%s", name);
 
2794
  
 
2795
  return true;
 
2796
}
 
2797
 
 
2798
/**
 
2799
 * Computer rule: Update "NoOfComputers", add "Type"
 
2800
 */
 
2801
bool
 
2802
transformComputer(InitConfigFileParser::Context & ctx, const char * data){
 
2803
  const char * id;
 
2804
  if(!ctx.m_currentSection->get("Id", &id)){
 
2805
    ctx.reportError("Mandatory parameter Id missing from section "
 
2806
                    "[%s] starting at line: %d",
 
2807
                    ctx.fname, ctx.m_sectionLineno);
 
2808
    return false;
 
2809
  }
 
2810
  BaseString::snprintf(ctx.pname, sizeof(ctx.pname), "Computer_%s", id);
 
2811
  
 
2812
  Uint32 computers = 0;
 
2813
  ctx.m_userProperties.get("NoOfComputers", &computers);
 
2814
  ctx.m_userProperties.put("NoOfComputers", ++computers, true);
 
2815
  
 
2816
  const char * hostname = 0;
 
2817
  ctx.m_currentSection->get("HostName", &hostname);
 
2818
  if(!hostname){
 
2819
    return true;
 
2820
  }
 
2821
  
 
2822
  return checkLocalhostHostnameMix(ctx,0);
 
2823
}
 
2824
 
 
2825
/**
 
2826
 * Apply default values
 
2827
 */
 
2828
void 
 
2829
applyDefaultValues(InitConfigFileParser::Context & ctx,
 
2830
                   const Properties * defaults)
 
2831
{
 
2832
  DBUG_ENTER("applyDefaultValues");
 
2833
  if(defaults != NULL){
 
2834
    Properties::Iterator it(defaults);
 
2835
 
 
2836
    for(const char * name = it.first(); name != NULL; name = it.next()){
 
2837
      (void) ctx.m_info->getStatus(ctx.m_currentInfo, name);
 
2838
      if(!ctx.m_currentSection->contains(name)){
 
2839
        switch (ctx.m_info->getType(ctx.m_currentInfo, name)){
 
2840
        case ConfigInfo::CI_INT:
 
2841
        case ConfigInfo::CI_BOOL:{
 
2842
          Uint32 val = 0;
 
2843
          ::require(defaults->get(name, &val));
 
2844
          ctx.m_currentSection->put(name, val);
 
2845
          DBUG_PRINT("info",("%s=%d #default",name,val));
 
2846
          break;
 
2847
        }
 
2848
        case ConfigInfo::CI_INT64:{
 
2849
          Uint64 val = 0;
 
2850
          ::require(defaults->get(name, &val));
 
2851
          ctx.m_currentSection->put64(name, val);
 
2852
          DBUG_PRINT("info",("%s=%lld #default",name,val));
 
2853
          break;
 
2854
        }
 
2855
        case ConfigInfo::CI_STRING:{
 
2856
          const char * val;
 
2857
          ::require(defaults->get(name, &val));
 
2858
          ctx.m_currentSection->put(name, val);
 
2859
          DBUG_PRINT("info",("%s=%s #default",name,val));
 
2860
          break;
 
2861
        }
 
2862
        case ConfigInfo::CI_SECTION:
 
2863
          break;
 
2864
        }
 
2865
      }
 
2866
#ifndef DBUG_OFF
 
2867
      else
 
2868
      {
 
2869
        switch (ctx.m_info->getType(ctx.m_currentInfo, name)){
 
2870
        case ConfigInfo::CI_INT:
 
2871
        case ConfigInfo::CI_BOOL:{
 
2872
          Uint32 val = 0;
 
2873
          ::require(ctx.m_currentSection->get(name, &val));
 
2874
          DBUG_PRINT("info",("%s=%d",name,val));
 
2875
          break;
 
2876
        }
 
2877
        case ConfigInfo::CI_INT64:{
 
2878
          Uint64 val = 0;
 
2879
          ::require(ctx.m_currentSection->get(name, &val));
 
2880
          DBUG_PRINT("info",("%s=%lld",name,val));
 
2881
          break;
 
2882
        }
 
2883
        case ConfigInfo::CI_STRING:{
 
2884
          const char * val;
 
2885
          ::require(ctx.m_currentSection->get(name, &val));
 
2886
          DBUG_PRINT("info",("%s=%s",name,val));
 
2887
          break;
 
2888
        }
 
2889
        case ConfigInfo::CI_SECTION:
 
2890
          break;
 
2891
        }
 
2892
      }
 
2893
#endif
 
2894
    }
 
2895
  }
 
2896
  DBUG_VOID_RETURN;
 
2897
}
 
2898
 
 
2899
bool
 
2900
applyDefaultValues(InitConfigFileParser::Context & ctx, const char * data){
 
2901
  
 
2902
  if(strcmp(data, "user") == 0)
 
2903
    applyDefaultValues(ctx, ctx.m_userDefaults);
 
2904
  else if (strcmp(data, "system") == 0)
 
2905
    applyDefaultValues(ctx, ctx.m_systemDefaults);
 
2906
  else 
 
2907
    return false;
 
2908
 
 
2909
  return true;
 
2910
}
 
2911
 
 
2912
/**
 
2913
 * Check that a section contains all MANDATORY parameters
 
2914
 */
 
2915
bool
 
2916
checkMandatory(InitConfigFileParser::Context & ctx, const char * data){
 
2917
 
 
2918
  Properties::Iterator it(ctx.m_currentInfo);
 
2919
  for(const char * name = it.first(); name != NULL; name = it.next()){
 
2920
    const Properties * info = NULL;
 
2921
    ::require(ctx.m_currentInfo->get(name, &info));
 
2922
    Uint32 val;
 
2923
    if(info->get("Mandatory", &val)){
 
2924
      const char * fname;
 
2925
      ::require(info->get("Fname", &fname));
 
2926
      if(!ctx.m_currentSection->contains(fname)){
 
2927
        ctx.reportError("Mandatory parameter %s missing from section "
 
2928
                        "[%s] starting at line: %d",
 
2929
                        fname, ctx.fname, ctx.m_sectionLineno);
 
2930
        return false;
 
2931
      }
 
2932
    }
 
2933
  }
 
2934
  return true;
 
2935
}
 
2936
 
 
2937
/**
 
2938
 * Connection rule: Fix node id
 
2939
 *
 
2940
 * Transform a string "NodeidX" (e.g. "uppsala.32") 
 
2941
 * into a Uint32 "NodeIdX" (e.g. 32) and a string "SystemX" (e.g. "uppsala").
 
2942
 */
 
2943
static bool fixNodeId(InitConfigFileParser::Context & ctx, const char * data)
 
2944
{
 
2945
  char buf[] = "NodeIdX";  buf[6] = data[sizeof("NodeI")];
 
2946
  char sysbuf[] = "SystemX";  sysbuf[6] = data[sizeof("NodeI")];
 
2947
  const char* nodeId;
 
2948
  if(!ctx.m_currentSection->get(buf, &nodeId))
 
2949
  {
 
2950
    ctx.reportError("Mandatory parameter %s missing from section"
 
2951
                    "[%s] starting at line: %d",
 
2952
                    buf, ctx.fname, ctx.m_sectionLineno);
 
2953
    return false;
 
2954
  }
 
2955
 
 
2956
  char tmpLine[MAX_LINE_LENGTH];
 
2957
  strncpy(tmpLine, nodeId, MAX_LINE_LENGTH);
 
2958
  char* token1 = strtok(tmpLine, ".");
 
2959
  char* token2 = strtok(NULL, ".");
 
2960
  Uint32 id;
 
2961
  
 
2962
  if(!token1)
 
2963
  {
 
2964
    ctx.reportError("Value for mandatory parameter %s missing from section "
 
2965
                    "[%s] starting at line: %d",
 
2966
                    buf, ctx.fname, ctx.m_sectionLineno);
 
2967
    return false;
 
2968
  }
 
2969
  if (token2 == NULL) {                // Only a number given
 
2970
    errno = 0;
 
2971
    char* p;
 
2972
    id = strtol(token1, &p, 10);
 
2973
    if (errno != 0 || id <= 0x0  || id > MAX_NODES)
 
2974
    {
 
2975
      ctx.reportError("Illegal value for mandatory parameter %s from section "
 
2976
                    "[%s] starting at line: %d",
 
2977
                    buf, ctx.fname, ctx.m_sectionLineno);
 
2978
      return false;
 
2979
    }
 
2980
    require(ctx.m_currentSection->put(buf, id, true));
 
2981
  } else {                             // A pair given (e.g. "uppsala.32")
 
2982
    errno = 0;
 
2983
    char* p;
 
2984
    id = strtol(token2, &p, 10);
 
2985
    if (errno != 0 || id <= 0x0  || id > MAX_NODES)
 
2986
    {
 
2987
      ctx.reportError("Illegal value for mandatory parameter %s from section "
 
2988
                    "[%s] starting at line: %d",
 
2989
                    buf, ctx.fname, ctx.m_sectionLineno);
 
2990
      return false;
 
2991
    }
 
2992
    require(ctx.m_currentSection->put(buf, id, true));
 
2993
    require(ctx.m_currentSection->put(sysbuf, token1));
 
2994
  }
 
2995
  return true;
 
2996
}
 
2997
 
 
2998
/**
 
2999
 * Connection rule: Fix hostname
 
3000
 * 
 
3001
 * Unless Hostname is not already specified, do steps:
 
3002
 * -# Via Connection's NodeId lookup Node
 
3003
 * -# Via Node's ExecuteOnComputer lookup Hostname
 
3004
 * -# Add HostName to Connection
 
3005
 */
 
3006
static bool
 
3007
fixHostname(InitConfigFileParser::Context & ctx, const char * data){
 
3008
  
 
3009
  char buf[] = "NodeIdX"; buf[6] = data[sizeof("HostNam")];
 
3010
  char sysbuf[] = "SystemX"; sysbuf[6] = data[sizeof("HostNam")];
 
3011
  
 
3012
  if(!ctx.m_currentSection->contains(data)){
 
3013
    Uint32 id = 0;
 
3014
    require(ctx.m_currentSection->get(buf, &id));
 
3015
    
 
3016
    const Properties * node;
 
3017
    if(!ctx.m_config->get("Node", id, &node))
 
3018
    {
 
3019
      ctx.reportError("Unknown node: \"%d\" specified in connection "
 
3020
                      "[%s] starting at line: %d",
 
3021
                      id, ctx.fname, ctx.m_sectionLineno);
 
3022
      return false;
 
3023
    }
 
3024
    
 
3025
    const char * hostname;
 
3026
    require(node->get("HostName", &hostname));
 
3027
    require(ctx.m_currentSection->put(data, hostname));
 
3028
  }
 
3029
  return true;
 
3030
}
 
3031
 
 
3032
/**
 
3033
 * Connection rule: Fix port number (using a port number adder)
 
3034
 */
 
3035
static bool
 
3036
fixPortNumber(InitConfigFileParser::Context & ctx, const char * data){
 
3037
 
 
3038
  DBUG_ENTER("fixPortNumber");
 
3039
 
 
3040
  Uint32 id1, id2;
 
3041
  const char *hostName1;
 
3042
  const char *hostName2;
 
3043
  require(ctx.m_currentSection->get("NodeId1", &id1));
 
3044
  require(ctx.m_currentSection->get("NodeId2", &id2));
 
3045
  require(ctx.m_currentSection->get("HostName1", &hostName1));
 
3046
  require(ctx.m_currentSection->get("HostName2", &hostName2));
 
3047
  DBUG_PRINT("info",("NodeId1=%d HostName1=\"%s\"",id1,hostName1));
 
3048
  DBUG_PRINT("info",("NodeId2=%d HostName2=\"%s\"",id2,hostName2));
 
3049
 
 
3050
  const Properties *node1, *node2;
 
3051
  require(ctx.m_config->get("Node", id1, &node1));
 
3052
  require(ctx.m_config->get("Node", id2, &node2));
 
3053
 
 
3054
  const char *type1, *type2;
 
3055
  require(node1->get("Type", &type1));
 
3056
  require(node2->get("Type", &type2));
 
3057
 
 
3058
  /* add NodeIdServer info */
 
3059
  {
 
3060
    Uint32 nodeIdServer = id1 < id2 ? id1 : id2;
 
3061
    if(strcmp(type1, API_TOKEN) == 0 || strcmp(type2, MGM_TOKEN) == 0)
 
3062
      nodeIdServer = id2;
 
3063
    else if(strcmp(type2, API_TOKEN) == 0 || strcmp(type1, MGM_TOKEN) == 0)
 
3064
      nodeIdServer = id1;
 
3065
    ctx.m_currentSection->put("NodeIdServer", nodeIdServer);
 
3066
 
 
3067
    if (id2 == nodeIdServer) {
 
3068
      {
 
3069
        const char *tmp= hostName1;
 
3070
        hostName1= hostName2;
 
3071
        hostName2= tmp;
 
3072
      }
 
3073
      {
 
3074
        Uint32 tmp= id1;
 
3075
        id1= id2;
 
3076
        id2= tmp;
 
3077
      }
 
3078
      {
 
3079
        const Properties *tmp= node1;
 
3080
        node1= node2;
 
3081
        node2= tmp;
 
3082
      }
 
3083
      {
 
3084
        const char *tmp= type1;
 
3085
        type1= type2;
 
3086
        type2= tmp;
 
3087
      }
 
3088
    }
 
3089
  }
 
3090
 
 
3091
  BaseString hostname(hostName1);
 
3092
  
 
3093
  if (hostname.c_str()[0] == 0) {
 
3094
    ctx.reportError("Hostname required on nodeid %d since it will "
 
3095
                    "act as server.", id1);
 
3096
    DBUG_RETURN(false);
 
3097
  }
 
3098
 
 
3099
  Uint32 port= 0;
 
3100
  if(strcmp(type1, MGM_TOKEN)==0)
 
3101
    node1->get("PortNumber",&port);
 
3102
  else if(strcmp(type2, MGM_TOKEN)==0)
 
3103
    node2->get("PortNumber",&port);
 
3104
 
 
3105
  if (!port && 
 
3106
      !node1->get("ServerPort", &port) &&
 
3107
      !ctx.m_userProperties.get("ServerPort_", id1, &port))
 
3108
  {
 
3109
    Uint32 base= 0;
 
3110
    /*
 
3111
     * If the connection doesn't involve an mgm server,
 
3112
     * and a default port number has been set, behave the old
 
3113
     * way of allocating port numbers for transporters.
 
3114
     */
 
3115
    if(ctx.m_userDefaults && ctx.m_userDefaults->get("PortNumber", &base))
 
3116
    {
 
3117
      Uint32 adder= 0;
 
3118
      {
 
3119
        BaseString server_port_adder(hostname);
 
3120
        server_port_adder.append("_ServerPortAdder");
 
3121
        ctx.m_userProperties.get(server_port_adder.c_str(), &adder);
 
3122
        ctx.m_userProperties.put(server_port_adder.c_str(), adder+1, true);
 
3123
      }
 
3124
      
 
3125
      if (!ctx.m_userProperties.get("ServerPortBase", &base)){
 
3126
        if(!(ctx.m_userDefaults &&
 
3127
           ctx.m_userDefaults->get("PortNumber", &base)) &&
 
3128
           !ctx.m_systemDefaults->get("PortNumber", &base)) {
 
3129
          base= strtoll(NDB_TCP_BASE_PORT,0,0);
 
3130
        }
 
3131
        ctx.m_userProperties.put("ServerPortBase", base);
 
3132
      }
 
3133
 
 
3134
      port= base + adder;
 
3135
      ctx.m_userProperties.put("ServerPort_", id1, port);
 
3136
    }
 
3137
  }
 
3138
 
 
3139
  if(ctx.m_currentSection->contains("PortNumber")) {
 
3140
    ndbout << "PortNumber should no longer be specificied "
 
3141
           << "per connection, please remove from config. "
 
3142
           << "Will be changed to " << port << endl;
 
3143
    ctx.m_currentSection->put("PortNumber", port, true);
 
3144
  } 
 
3145
  else
 
3146
  {
 
3147
    ctx.m_currentSection->put("PortNumber", port);
 
3148
  }
 
3149
 
 
3150
  DBUG_PRINT("info", ("connection %d-%d port %d host %s",
 
3151
                      id1, id2, port, hostname.c_str()));
 
3152
 
 
3153
  DBUG_RETURN(true);
 
3154
}
 
3155
 
 
3156
static bool 
 
3157
fixShmUniqueId(InitConfigFileParser::Context & ctx, const char * data)
 
3158
{
 
3159
  DBUG_ENTER("fixShmUniqueId");
 
3160
  Uint32 nodes= 0;
 
3161
  ctx.m_userProperties.get(ctx.fname, &nodes);
 
3162
  if (nodes == 1) // first management server
 
3163
  {
 
3164
    Uint32 portno= atoi(NDB_PORT);
 
3165
    ctx.m_currentSection->get("PortNumber", &portno);
 
3166
    ctx.m_userProperties.put("ShmUniqueId", portno);
 
3167
  }
 
3168
  DBUG_RETURN(true);
 
3169
}
 
3170
 
 
3171
static 
 
3172
bool 
 
3173
fixShmKey(InitConfigFileParser::Context & ctx, const char *)
 
3174
{
 
3175
  DBUG_ENTER("fixShmKey");
 
3176
  {
 
3177
    static int last_signum= -1;
 
3178
    Uint32 signum;
 
3179
    if(!ctx.m_currentSection->get("Signum", &signum))
 
3180
    {
 
3181
      signum= OPT_NDB_SHM_SIGNUM_DEFAULT;
 
3182
      if (signum <= 0)
 
3183
      {
 
3184
          ctx.reportError("Unable to set default parameter for [SHM]Signum"
 
3185
                          " please specify [SHM DEFAULT]Signum");
 
3186
          return false;
 
3187
      }
 
3188
      ctx.m_currentSection->put("Signum", signum);
 
3189
      DBUG_PRINT("info",("Added Signum=%u", signum));
 
3190
    }
 
3191
    if ( last_signum != (int)signum && last_signum >= 0 )
 
3192
    {
 
3193
      ctx.reportError("All shared memory transporters must have same [SHM]Signum defined."
 
3194
                      " Use [SHM DEFAULT]Signum");
 
3195
      return false;
 
3196
    }
 
3197
    last_signum= (int)signum;
 
3198
  }
 
3199
  {
 
3200
    Uint32 id1= 0, id2= 0, key= 0;
 
3201
    require(ctx.m_currentSection->get("NodeId1", &id1));
 
3202
    require(ctx.m_currentSection->get("NodeId2", &id2));
 
3203
    if(!ctx.m_currentSection->get("ShmKey", &key))
 
3204
    {
 
3205
      require(ctx.m_userProperties.get("ShmUniqueId", &key));
 
3206
      key= key << 16 | (id1 > id2 ? id1 << 8 | id2 : id2 << 8 | id1);
 
3207
      ctx.m_currentSection->put("ShmKey", key);
 
3208
      DBUG_PRINT("info",("Added ShmKey=0x%x", key));
 
3209
    }
 
3210
  }
 
3211
  DBUG_RETURN(true);
 
3212
}
 
3213
 
 
3214
/**
 
3215
 * DB Node rule: Check various constraints
 
3216
 */
 
3217
static bool
 
3218
checkDbConstraints(InitConfigFileParser::Context & ctx, const char *){
 
3219
 
 
3220
  Uint32 t1 = 0, t2 = 0;
 
3221
  ctx.m_currentSection->get("MaxNoOfConcurrentOperations", &t1);
 
3222
  ctx.m_currentSection->get("MaxNoOfConcurrentTransactions", &t2);
 
3223
  
 
3224
  if (t1 < t2) {
 
3225
    ctx.reportError("MaxNoOfConcurrentOperations must be greater than "
 
3226
                    "MaxNoOfConcurrentTransactions - [%s] starting at line: %d",
 
3227
                    ctx.fname, ctx.m_sectionLineno);
 
3228
    return false;
 
3229
  }
 
3230
 
 
3231
  Uint32 replicas = 0, otherReplicas;
 
3232
  ctx.m_currentSection->get("NoOfReplicas", &replicas);
 
3233
  if(ctx.m_userProperties.get("NoOfReplicas", &otherReplicas)){
 
3234
    if(replicas != otherReplicas){
 
3235
      ctx.reportError("NoOfReplicas defined differently on different nodes"
 
3236
                      " - [%s] starting at line: %d",
 
3237
                      ctx.fname, ctx.m_sectionLineno);
 
3238
      return false;
 
3239
    }
 
3240
  } else {
 
3241
    ctx.m_userProperties.put("NoOfReplicas", replicas);
 
3242
  }
 
3243
 
 
3244
  /**
 
3245
   * In kernel, will calculate the MaxNoOfMeataTables use the following sum:
 
3246
   * Uint32 noOfMetaTables = noOfTables + noOfOrderedIndexes + 
 
3247
   *                         noOfUniqueHashIndexes + 2
 
3248
   * 2 is the number of the SysTables.
 
3249
   * So must check that the sum does't exceed the max value of Uint32.
 
3250
   */
 
3251
  Uint32 noOfTables = 0,
 
3252
         noOfOrderedIndexes = 0,
 
3253
         noOfUniqueHashIndexes = 0;
 
3254
  ctx.m_currentSection->get("MaxNoOfTables", &noOfTables);
 
3255
  ctx.m_currentSection->get("MaxNoOfOrderedIndexes", &noOfOrderedIndexes);
 
3256
  ctx.m_currentSection->get("MaxNoOfUniqueHashIndexes", &noOfUniqueHashIndexes);
 
3257
 
 
3258
  Uint64 sum= (Uint64)noOfTables + noOfOrderedIndexes + noOfUniqueHashIndexes;
 
3259
  
 
3260
  if (sum > ((Uint32)~0 - 2)) {
 
3261
    ctx.reportError("The sum of MaxNoOfTables, MaxNoOfOrderedIndexes and"
 
3262
                    " MaxNoOfUniqueHashIndexes must not exceed %u - [%s]"
 
3263
                    " starting at line: %d",
 
3264
                    ((Uint32)~0 - 2), ctx.fname, ctx.m_sectionLineno);
 
3265
    return false;
 
3266
  } 
 
3267
 
 
3268
  return true;
 
3269
}
 
3270
 
 
3271
/**
 
3272
 * Connection rule: Check varius constraints
 
3273
 */
 
3274
static bool
 
3275
checkConnectionConstraints(InitConfigFileParser::Context & ctx, const char *){
 
3276
 
 
3277
  Uint32 id1 = 0, id2 = 0;
 
3278
  ctx.m_currentSection->get("NodeId1", &id1);
 
3279
  ctx.m_currentSection->get("NodeId2", &id2);
 
3280
  
 
3281
  if(id1 == id2){
 
3282
    ctx.reportError("Illegal connection from node to itself"
 
3283
                    " - [%s] starting at line: %d",
 
3284
                    ctx.fname, ctx.m_sectionLineno);
 
3285
    return false;
 
3286
  }
 
3287
 
 
3288
  const Properties * node1;
 
3289
  if(!ctx.m_config->get("Node", id1, &node1)){
 
3290
    ctx.reportError("Connection refering to undefined node: %d"
 
3291
                    " - [%s] starting at line: %d",
 
3292
                    id1, ctx.fname, ctx.m_sectionLineno);
 
3293
    return false;
 
3294
  }
 
3295
 
 
3296
  const Properties * node2;
 
3297
  if(!ctx.m_config->get("Node", id2, &node2)){
 
3298
    ctx.reportError("Connection refering to undefined node: %d"
 
3299
                    " - [%s] starting at line: %d",
 
3300
                    id2, ctx.fname, ctx.m_sectionLineno);
 
3301
    return false;
 
3302
  }
 
3303
 
 
3304
  const char * type1;
 
3305
  const char * type2;
 
3306
  require(node1->get("Type", &type1));
 
3307
  require(node2->get("Type", &type2));
 
3308
 
 
3309
  /**
 
3310
   * Report error if the following are true
 
3311
   * -# None of the nodes is of type DB
 
3312
   * -# Not both of them are MGMs
 
3313
   */
 
3314
  if((strcmp(type1, DB_TOKEN) != 0 && strcmp(type2, DB_TOKEN) != 0) &&
 
3315
     !(strcmp(type1, MGM_TOKEN) == 0 && strcmp(type2, MGM_TOKEN) == 0))
 
3316
  {
 
3317
    ctx.reportError("Invalid connection between node %d (%s) and node %d (%s)"
 
3318
                    " - [%s] starting at line: %d",
 
3319
                    id1, type1, id2, type2, 
 
3320
                    ctx.fname, ctx.m_sectionLineno);
 
3321
    return false;
 
3322
  }
 
3323
 
 
3324
  return true;
 
3325
}
 
3326
 
 
3327
static bool
 
3328
checkTCPConstraints(InitConfigFileParser::Context & ctx, const char * data){
 
3329
  
 
3330
  const char * host;
 
3331
  struct in_addr addr;
 
3332
  if(ctx.m_currentSection->get(data, &host) && strlen(host) && 
 
3333
     Ndb_getInAddr(&addr, host)){
 
3334
    ctx.reportError("Unable to lookup/illegal hostname %s"
 
3335
                    " - [%s] starting at line: %d",
 
3336
                    host, ctx.fname, ctx.m_sectionLineno);
 
3337
    return false;
 
3338
  }
 
3339
  return true;
 
3340
}
 
3341
 
 
3342
static
 
3343
bool
 
3344
transform(InitConfigFileParser::Context & ctx,
 
3345
          Properties & dst, 
 
3346
          const char * oldName,
 
3347
          const char * newName,
 
3348
          double add, double mul){
 
3349
  
 
3350
  if(ctx.m_currentSection->contains(newName)){
 
3351
    ctx.reportError("Both %s and %s specified"
 
3352
                    " - [%s] starting at line: %d",
 
3353
                    oldName, newName,
 
3354
                    ctx.fname, ctx.m_sectionLineno);
 
3355
    return false;
 
3356
  }
 
3357
  
 
3358
  PropertiesType oldType;
 
3359
  require(ctx.m_currentSection->getTypeOf(oldName, &oldType));
 
3360
  ConfigInfo::Type newType = ctx.m_info->getType(ctx.m_currentInfo, newName);  
 
3361
 
 
3362
  if(!((oldType == PropertiesType_Uint32 || oldType == PropertiesType_Uint64) 
 
3363
       && (newType == ConfigInfo::CI_INT || newType == ConfigInfo::CI_INT64 || newType == ConfigInfo::CI_BOOL))){
 
3364
    ndbout << "oldType: " << (int)oldType << ", newType: " << (int)newType << endl;
 
3365
    ctx.reportError("Unable to handle type conversion w.r.t deprication %s %s"
 
3366
                    "- [%s] starting at line: %d",
 
3367
                    oldName, newName,
 
3368
                    ctx.fname, ctx.m_sectionLineno);
 
3369
    return false;
 
3370
  }
 
3371
  Uint64 oldVal;
 
3372
  require(ctx.m_currentSection->get(oldName, &oldVal));
 
3373
 
 
3374
  Uint64 newVal = (Uint64)((Int64)oldVal * mul + add);
 
3375
  if(!ctx.m_info->verify(ctx.m_currentInfo, newName, newVal)){
 
3376
    ctx.reportError("Unable to handle deprication, new value not within bounds"
 
3377
                    "%s %s - [%s] starting at line: %d",
 
3378
                    oldName, newName,
 
3379
                    ctx.fname, ctx.m_sectionLineno);
 
3380
    return false;
 
3381
  }
 
3382
 
 
3383
  if(newType == ConfigInfo::CI_INT || newType == ConfigInfo::CI_BOOL){
 
3384
    require(dst.put(newName, (Uint32)newVal));
 
3385
  } else if(newType == ConfigInfo::CI_INT64) {
 
3386
    require(dst.put64(newName, newVal));    
 
3387
  }
 
3388
  return true;
 
3389
}
 
3390
 
 
3391
static bool
 
3392
fixDepricated(InitConfigFileParser::Context & ctx, const char * data){
 
3393
  const char * name;
 
3394
  /**
 
3395
   * Transform old values to new values
 
3396
   * Transform new values to old values (backward compatible)
 
3397
   */
 
3398
  Properties tmp(true);
 
3399
  Properties::Iterator it(ctx.m_currentSection);
 
3400
  for (name = it.first(); name != NULL; name = it.next()) {
 
3401
    const DepricationTransform * p = &f_deprication[0];
 
3402
    while(p->m_section != 0){
 
3403
      if(strcmp(p->m_section, ctx.fname) == 0){
 
3404
        double mul = p->m_mul;
 
3405
        double add = p->m_add;
 
3406
        if(strcasecmp(name, p->m_oldName) == 0){
 
3407
          if(!transform(ctx, tmp, name, p->m_newName, add, mul)){
 
3408
            return false;
 
3409
          }
 
3410
        } else if(strcasecmp(name, p->m_newName) == 0) {
 
3411
          if(!transform(ctx, tmp, name, p->m_oldName, -add/mul,1.0/mul)){
 
3412
            return false;
 
3413
          }
 
3414
        }
 
3415
      }
 
3416
      p++;
 
3417
    }
 
3418
  }
 
3419
  
 
3420
  Properties::Iterator it2(&tmp);
 
3421
  for (name = it2.first(); name != NULL; name = it2.next()) {
 
3422
    PropertiesType type;
 
3423
    require(tmp.getTypeOf(name, &type));
 
3424
    switch(type){
 
3425
    case PropertiesType_Uint32:{
 
3426
      Uint32 val;
 
3427
      require(tmp.get(name, &val));
 
3428
      ::require(ctx.m_currentSection->put(name, val));
 
3429
      break;
 
3430
    }
 
3431
    case PropertiesType_char:{
 
3432
      const char * val;
 
3433
      require(tmp.get(name, &val));
 
3434
      ::require(ctx.m_currentSection->put(name, val));
 
3435
      break;
 
3436
    }
 
3437
    case PropertiesType_Uint64:{
 
3438
      Uint64 val;
 
3439
      require(tmp.get(name, &val));
 
3440
      ::require(ctx.m_currentSection->put64(name, val));
 
3441
      break;
 
3442
    }
 
3443
    case PropertiesType_Properties:
 
3444
    default:
 
3445
      ::require(false);
 
3446
    }
 
3447
  }
 
3448
  return true;
 
3449
}
 
3450
 
 
3451
extern int g_print_full_config;
 
3452
 
 
3453
static bool
 
3454
saveInConfigValues(InitConfigFileParser::Context & ctx, const char * data){
 
3455
  const Properties * sec;
 
3456
  if(!ctx.m_currentInfo->get(ctx.fname, &sec)){
 
3457
    require(false);
 
3458
    return false;
 
3459
  }
 
3460
  
 
3461
  do {
 
3462
    const char *secName;
 
3463
    Uint32 id, status, typeVal;
 
3464
    require(sec->get("Fname", &secName));
 
3465
    require(sec->get("Id", &id));
 
3466
    require(sec->get("Status", &status));
 
3467
    require(sec->get("SectionType", &typeVal));
 
3468
    
 
3469
    if(id == KEY_INTERNAL || status == ConfigInfo::CI_INTERNAL){
 
3470
      ndbout_c("skipping section %s", ctx.fname);
 
3471
      break;
 
3472
    }
 
3473
    
 
3474
    if (g_print_full_config)
 
3475
    {
 
3476
      const char *alias= ConfigInfo::nameToAlias(ctx.fname);
 
3477
      printf("[%s]\n", alias ? alias : ctx.fname);
 
3478
    }
 
3479
 
 
3480
    Uint32 no = 0;
 
3481
    ctx.m_userProperties.get("$Section", id, &no);
 
3482
    ctx.m_userProperties.put("$Section", id, no+1, true);
 
3483
    
 
3484
    ctx.m_configValues.openSection(id, no);
 
3485
    ctx.m_configValues.put(CFG_TYPE_OF_SECTION, typeVal);
 
3486
    
 
3487
    Properties::Iterator it(ctx.m_currentSection);
 
3488
    for (const char* n = it.first(); n != NULL; n = it.next()) {
 
3489
      const Properties * info;
 
3490
      if(!ctx.m_currentInfo->get(n, &info))
 
3491
        continue;
 
3492
 
 
3493
      id = 0;
 
3494
      info->get("Id", &id);
 
3495
      
 
3496
      if(id == KEY_INTERNAL)
 
3497
        continue;
 
3498
 
 
3499
      bool ok = true;
 
3500
      PropertiesType type;
 
3501
      require(ctx.m_currentSection->getTypeOf(n, &type));
 
3502
      switch(type){
 
3503
      case PropertiesType_Uint32:{
 
3504
        Uint32 val;
 
3505
        require(ctx.m_currentSection->get(n, &val));
 
3506
        ok = ctx.m_configValues.put(id, val);
 
3507
        if (g_print_full_config)
 
3508
          printf("%s=%u\n", n, val);
 
3509
        break;
 
3510
      }
 
3511
      case PropertiesType_Uint64:{
 
3512
        Uint64 val;
 
3513
        require(ctx.m_currentSection->get(n, &val));
 
3514
        ok = ctx.m_configValues.put64(id, val);
 
3515
        if (g_print_full_config)
 
3516
          printf("%s=%llu\n", n, val);
 
3517
        break;
 
3518
      }
 
3519
      case PropertiesType_char:{
 
3520
        const char * val;
 
3521
        require(ctx.m_currentSection->get(n, &val));
 
3522
        ok = ctx.m_configValues.put(id, val);
 
3523
        if (g_print_full_config)
 
3524
          printf("%s=%s\n", n, val);
 
3525
        break;
 
3526
      }
 
3527
      default:
 
3528
        require(false);
 
3529
      }
 
3530
      require(ok);
 
3531
    }
 
3532
    ctx.m_configValues.closeSection();
 
3533
  } while(0);
 
3534
  return true;
 
3535
}
 
3536
 
 
3537
static bool
 
3538
sanity_checks(Vector<ConfigInfo::ConfigRuleSection>&sections, 
 
3539
              struct InitConfigFileParser::Context &ctx, 
 
3540
              const char * rule_data)
 
3541
{
 
3542
  Uint32 db_nodes = 0;
 
3543
  Uint32 mgm_nodes = 0;
 
3544
  Uint32 api_nodes = 0;
 
3545
  if (!ctx.m_userProperties.get("DB", &db_nodes)) {
 
3546
    ctx.reportError("At least one database node (ndbd) should be defined in config file");
 
3547
    return false;
 
3548
  }
 
3549
  if (!ctx.m_userProperties.get("MGM", &mgm_nodes)) {
 
3550
    ctx.reportError("At least one management server node (ndb_mgmd) should be defined in config file");
 
3551
    return false;
 
3552
  }
 
3553
  if (!ctx.m_userProperties.get("API", &api_nodes)) {
 
3554
    ctx.reportError("At least one application node (for the mysqld) should be defined in config file");
 
3555
    return false;
 
3556
  }
 
3557
  return true;
 
3558
}
 
3559
 
 
3560
static void
 
3561
add_a_connection(Vector<ConfigInfo::ConfigRuleSection>&sections,
 
3562
                 struct InitConfigFileParser::Context &ctx,
 
3563
                 Uint32 nodeId1, Uint32 nodeId2, bool use_shm)
 
3564
{
 
3565
  ConfigInfo::ConfigRuleSection s;
 
3566
  const char *hostname1= 0, *hostname2= 0;
 
3567
  const Properties *tmp;
 
3568
  
 
3569
  require(ctx.m_config->get("Node", nodeId1, &tmp));
 
3570
  tmp->get("HostName", &hostname1);
 
3571
  
 
3572
  require(ctx.m_config->get("Node", nodeId2, &tmp));
 
3573
  tmp->get("HostName", &hostname2);
 
3574
  
 
3575
  char buf[16];
 
3576
  s.m_sectionData= new Properties(true);
 
3577
  BaseString::snprintf(buf, sizeof(buf), "%u", nodeId1);
 
3578
  s.m_sectionData->put("NodeId1", buf);
 
3579
  BaseString::snprintf(buf, sizeof(buf), "%u", nodeId2);
 
3580
  s.m_sectionData->put("NodeId2", buf);
 
3581
 
 
3582
  if (use_shm &&
 
3583
      hostname1 && hostname1[0] &&
 
3584
      hostname2 && hostname2[0] &&
 
3585
      strcmp(hostname1,hostname2) == 0)
 
3586
  {
 
3587
    s.m_sectionType= BaseString("SHM");
 
3588
    DBUG_PRINT("info",("adding SHM connection %d %d",nodeId1,nodeId2));
 
3589
  }
 
3590
  else
 
3591
  {
 
3592
    s.m_sectionType= BaseString("TCP");
 
3593
    DBUG_PRINT("info",("adding TCP connection %d %d",nodeId1,nodeId2));
 
3594
  }
 
3595
 
 
3596
  sections.push_back(s);
 
3597
}
 
3598
 
 
3599
static bool
 
3600
add_node_connections(Vector<ConfigInfo::ConfigRuleSection>&sections, 
 
3601
                   struct InitConfigFileParser::Context &ctx, 
 
3602
                   const char * rule_data)
 
3603
{
 
3604
  DBUG_ENTER("add_node_connections");
 
3605
  Uint32 i;
 
3606
  Properties * props= ctx.m_config;
 
3607
  Properties p_connections(true);
 
3608
  Properties p_connections2(true);
 
3609
 
 
3610
  for (i = 0;; i++){
 
3611
    const Properties * tmp;
 
3612
    Uint32 nodeId1, nodeId2;
 
3613
 
 
3614
    if(!props->get("Connection", i, &tmp)) break;
 
3615
 
 
3616
    if(!tmp->get("NodeId1", &nodeId1)) continue;
 
3617
    p_connections.put("", nodeId1, nodeId1);
 
3618
    if(!tmp->get("NodeId2", &nodeId2)) continue;
 
3619
    p_connections.put("", nodeId2, nodeId2);
 
3620
 
 
3621
    p_connections2.put("", nodeId1 + nodeId2<<16, nodeId1);
 
3622
    p_connections2.put("", nodeId2 + nodeId1<<16, nodeId2);
 
3623
  }
 
3624
 
 
3625
  Uint32 nNodes;
 
3626
  ctx.m_userProperties.get("NoOfNodes", &nNodes);
 
3627
 
 
3628
  Properties p_db_nodes(true);
 
3629
  Properties p_api_nodes(true);
 
3630
  Properties p_mgm_nodes(true);
 
3631
 
 
3632
  Uint32 i_db= 0, i_api= 0, i_mgm= 0, n;
 
3633
  for (i= 0, n= 0; n < nNodes; i++){
 
3634
    const Properties * tmp;
 
3635
    if(!props->get("Node", i, &tmp)) continue;
 
3636
    n++;
 
3637
 
 
3638
    const char * type;
 
3639
    if(!tmp->get("Type", &type)) continue;
 
3640
 
 
3641
    if (strcmp(type,DB_TOKEN) == 0)
 
3642
      p_db_nodes.put("", i_db++, i);
 
3643
    else if (strcmp(type,API_TOKEN) == 0)
 
3644
      p_api_nodes.put("", i_api++, i);
 
3645
    else if (strcmp(type,MGM_TOKEN) == 0)
 
3646
      p_mgm_nodes.put("", i_mgm++, i);
 
3647
  }
 
3648
 
 
3649
  Uint32 nodeId1, nodeId2, dummy;
 
3650
 
 
3651
  for (i= 0; p_db_nodes.get("", i, &nodeId1); i++){
 
3652
    for (Uint32 j= i+1;; j++){
 
3653
      if(!p_db_nodes.get("", j, &nodeId2)) break;
 
3654
      if(!p_connections2.get("", nodeId1+nodeId2<<16, &dummy)) {
 
3655
        add_a_connection(sections,ctx,nodeId1,nodeId2,opt_ndb_shm);
 
3656
      }
 
3657
    }
 
3658
  }
 
3659
 
 
3660
  for (i= 0; p_api_nodes.get("", i, &nodeId1); i++){
 
3661
    if(!p_connections.get("", nodeId1, &dummy)) {
 
3662
      for (Uint32 j= 0;; j++){
 
3663
        if(!p_db_nodes.get("", j, &nodeId2)) break;
 
3664
        add_a_connection(sections,ctx,nodeId1,nodeId2,opt_ndb_shm);
 
3665
      }
 
3666
    }
 
3667
  }
 
3668
 
 
3669
  for (i= 0; p_mgm_nodes.get("", i, &nodeId1); i++){
 
3670
    if(!p_connections.get("", nodeId1, &dummy)) {
 
3671
      for (Uint32 j= 0;; j++){
 
3672
        if(!p_db_nodes.get("", j, &nodeId2)) break;
 
3673
        add_a_connection(sections,ctx,nodeId1,nodeId2,0);
 
3674
      }
 
3675
    }
 
3676
  }
 
3677
 
 
3678
  DBUG_RETURN(true);
 
3679
}
 
3680
 
 
3681
static bool set_connection_priorities(Vector<ConfigInfo::ConfigRuleSection>&sections, 
 
3682
                                 struct InitConfigFileParser::Context &ctx, 
 
3683
                                 const char * rule_data)
 
3684
{
 
3685
  DBUG_ENTER("set_connection_priorities");
 
3686
  DBUG_RETURN(true);
 
3687
}
 
3688
 
 
3689
static bool
 
3690
check_node_vs_replicas(Vector<ConfigInfo::ConfigRuleSection>&sections, 
 
3691
                       struct InitConfigFileParser::Context &ctx, 
 
3692
                       const char * rule_data)
 
3693
{
 
3694
  Uint32 db_nodes= 0;
 
3695
  Uint32 replicas= 0;
 
3696
  Uint32 db_host_count= 0;
 
3697
  bool  with_arbitration_rank= false;
 
3698
  ctx.m_userProperties.get(DB_TOKEN, &db_nodes);
 
3699
  ctx.m_userProperties.get("NoOfReplicas", &replicas);
 
3700
  if((db_nodes % replicas) != 0){
 
3701
    ctx.reportError("Invalid no of db nodes wrt no of replicas.\n"
 
3702
                    "No of nodes must be dividable with no or replicas");
 
3703
    return false;
 
3704
  }
 
3705
  // check that node groups and arbitrators are ok
 
3706
  // just issue warning if not
 
3707
  if(replicas > 1){
 
3708
    Properties * props= ctx.m_config;
 
3709
    Properties p_db_hosts(true); // store hosts which db nodes run on
 
3710
    Properties p_arbitrators(true); // store hosts which arbitrators run on
 
3711
    // arbitrator should not run together with db node on same host
 
3712
    Uint32 i, n, group= 0, i_group= 0;
 
3713
    Uint32 n_nodes;
 
3714
    BaseString node_group_warning, arbitration_warning;
 
3715
    const char *arbit_warn_fmt=
 
3716
      "\n  arbitrator with id %d and db node with id %d on same host %s";
 
3717
    const char *arbit_warn_fmt2=
 
3718
      "\n  arbitrator with id %d has no hostname specified";
 
3719
 
 
3720
    ctx.m_userProperties.get("NoOfNodes", &n_nodes);
 
3721
    for (i= 0, n= 0; n < n_nodes; i++){
 
3722
      const Properties * tmp;
 
3723
      if(!props->get("Node", i, &tmp)) continue;
 
3724
      n++;
 
3725
 
 
3726
      const char * type;
 
3727
      if(!tmp->get("Type", &type)) continue;
 
3728
 
 
3729
      const char* host= 0;
 
3730
      tmp->get("HostName", &host);
 
3731
 
 
3732
      if (strcmp(type,DB_TOKEN) == 0)
 
3733
      { 
 
3734
        { 
 
3735
          Uint32 ii; 
 
3736
          if (!p_db_hosts.get(host,&ii)) 
 
3737
            db_host_count++; 
 
3738
          p_db_hosts.put(host,i); 
 
3739
          if (p_arbitrators.get(host,&ii)) 
 
3740
          { 
 
3741
            arbitration_warning.appfmt(arbit_warn_fmt, ii, i, host); 
 
3742
            p_arbitrators.remove(host); // only one warning per db node 
 
3743
          } 
 
3744
        } 
 
3745
        { 
 
3746
          unsigned j; 
 
3747
          BaseString str, str2; 
 
3748
          str.assfmt("#group%d_",group); 
 
3749
          p_db_hosts.put(str.c_str(),i_group,host); 
 
3750
          str2.assfmt("##group%d_",group); 
 
3751
          p_db_hosts.put(str2.c_str(),i_group,i); 
 
3752
          for (j= 0; j < i_group; j++) 
 
3753
          { 
 
3754
            const char *other_host; 
 
3755
            p_db_hosts.get(str.c_str(),j,&other_host); 
 
3756
            if (strcmp(host,other_host) == 0) { 
 
3757
              unsigned int other_i, c= 0; 
 
3758
              p_db_hosts.get(str2.c_str(),j,&other_i); 
 
3759
              p_db_hosts.get(str.c_str(),&c); 
 
3760
              if (c == 0) // first warning in this node group 
 
3761
                node_group_warning.appfmt("  Node group %d", group); 
 
3762
              c|= 1 << j; 
 
3763
              p_db_hosts.put(str.c_str(),c); 
 
3764
              node_group_warning.appfmt(",\n    db node with id %d and id %d " 
 
3765
              "on same host %s", other_i, i, host); 
 
3766
            } 
 
3767
          } 
 
3768
          i_group++; 
 
3769
          DBUG_ASSERT(i_group <= replicas); 
 
3770
          if (i_group == replicas) 
 
3771
          { 
 
3772
            unsigned c= 0; 
 
3773
            p_db_hosts.get(str.c_str(),&c); 
 
3774
            if (c+1 == (1u << (replicas-1))) // all nodes on same machine 
 
3775
              node_group_warning.append(".\n    Host failure will " 
 
3776
              "cause complete cluster shutdown."); 
 
3777
            else if (c > 0) 
 
3778
              node_group_warning.append(".\n    Host failure may " 
 
3779
              "cause complete cluster shutdown."); 
 
3780
            group++; 
 
3781
            i_group= 0; 
 
3782
          } 
 
3783
        }
 
3784
      }
 
3785
      else if (strcmp(type,API_TOKEN) == 0 ||
 
3786
               strcmp(type,MGM_TOKEN) == 0)
 
3787
      { 
 
3788
        Uint32 rank; 
 
3789
        if(tmp->get("ArbitrationRank", &rank) && rank > 0) 
 
3790
        { 
 
3791
          with_arbitration_rank = true;  //check whether MGM or API node configured with rank >0 
 
3792
          if(host && host[0] != 0) 
 
3793
          { 
 
3794
            Uint32 ii; 
 
3795
            p_arbitrators.put(host,i); 
 
3796
            if (p_db_hosts.get(host,&ii)) 
 
3797
            { 
 
3798
              arbitration_warning.appfmt(arbit_warn_fmt, i, ii, host); 
 
3799
            } 
 
3800
          } 
 
3801
          else 
 
3802
          { 
 
3803
            arbitration_warning.appfmt(arbit_warn_fmt2, i); 
 
3804
          } 
 
3805
        }
 
3806
      }
 
3807
    }
 
3808
    if (db_host_count > 1 && node_group_warning.length() > 0)
 
3809
      ctx.reportWarning("Cluster configuration warning:\n%s",node_group_warning.c_str());
 
3810
    if (!with_arbitration_rank) 
 
3811
    {
 
3812
      ctx.reportWarning("Cluster configuration warning:" 
 
3813
         "\n  Neither %s nor %s nodes are configured with arbitrator,"
 
3814
         "\n  may cause complete cluster shutdown in case of host failure.", 
 
3815
         MGM_TOKEN, API_TOKEN);
 
3816
    }
 
3817
    if (db_host_count > 1 && arbitration_warning.length() > 0)
 
3818
      ctx.reportWarning("Cluster configuration warning:%s%s",arbitration_warning.c_str(),
 
3819
               "\n  Running arbitrator on the same host as a database node may"
 
3820
               "\n  cause complete cluster shutdown in case of host failure.");
 
3821
  }
 
3822
  return true;
 
3823
}
 
3824
 
 
3825
template class Vector<ConfigInfo::ConfigRuleSection>;
 
3826
#endif /* NDB_MGMAPI */