1
/* Copyright (C) 2003 MySQL AB
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.
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.
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 */
16
#include <ndb_global.h>
18
#include <ndb_opt_defaults.h>
21
#include "ConfigInfo.hpp"
22
#include <mgmapi_config_parameters.h>
23
#include <ndb_limits.h>
24
#include "InitConfigFileParser.hpp"
27
extern my_bool opt_ndb_shm;
28
extern my_bool opt_core;
31
#include "ConfigInfo.hpp"
32
#include <mgmapi_config_parameters.h>
33
#endif /* NDB_MGMAPI */
35
#define MAX_LINE_LENGTH 255
36
#define KEY_INTERNAL 0
37
#define MAX_INT_RNIL 0xfffffeff
38
#define MAX_PORT_NO 65535
40
#define _STR_VALUE(x) #x
41
#define STR_VALUE(x) _STR_VALUE(x)
43
/****************************************************************************
45
****************************************************************************/
47
#define DB_TOKEN_PRINT "ndbd(DB)"
48
#define MGM_TOKEN_PRINT "ndb_mgmd(MGM)"
49
#define API_TOKEN_PRINT "mysqld(API)"
52
#define MGM_TOKEN "MGM"
53
#define API_TOKEN "API"
56
const ConfigInfo::AliasPair
57
ConfigInfo::m_sectionNameAliases[]={
58
{API_TOKEN, "MYSQLD"},
60
{MGM_TOKEN, "NDB_MGMD"},
65
ConfigInfo::m_sectionNames[]={
77
const int ConfigInfo::m_noOfSectionNames =
78
sizeof(m_sectionNames)/sizeof(char*);
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);
106
const ConfigInfo::SectionRule
107
ConfigInfo::m_SectionRules[] = {
108
{ "SYSTEM", transformSystem, 0 },
109
{ "COMPUTER", transformComputer, 0 },
111
{ DB_TOKEN, transformNode, 0 },
112
{ API_TOKEN, transformNode, 0 },
113
{ MGM_TOKEN, transformNode, 0 },
115
{ MGM_TOKEN, fixShmUniqueId, 0 },
117
{ "TCP", checkConnectionSupport, 0 },
118
{ "SHM", checkConnectionSupport, 0 },
119
{ "SCI", checkConnectionSupport, 0 },
121
{ "TCP", transformConnection, 0 },
122
{ "SHM", transformConnection, 0 },
123
{ "SCI", transformConnection, 0 },
125
{ DB_TOKEN, fixNodeHostname, 0 },
126
{ API_TOKEN, fixNodeHostname, 0 },
127
{ MGM_TOKEN, fixNodeHostname, 0 },
129
{ "TCP", fixNodeId, "NodeId1" },
130
{ "TCP", fixNodeId, "NodeId2" },
131
{ "SHM", fixNodeId, "NodeId1" },
132
{ "SHM", fixNodeId, "NodeId2" },
133
{ "SCI", fixNodeId, "NodeId1" },
134
{ "SCI", fixNodeId, "NodeId2" },
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" },
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
149
{ "*", applyDefaultValues, "user" },
150
{ "*", fixDepricated, 0 },
151
{ "*", applyDefaultValues, "system" },
153
{ "SHM", fixShmKey, 0 }, // has to come after apply default values
155
{ DB_TOKEN, checkLocalhostHostnameMix, 0 },
156
{ API_TOKEN, checkLocalhostHostnameMix, 0 },
157
{ MGM_TOKEN, checkLocalhostHostnameMix, 0 },
159
{ DB_TOKEN, fixFileSystemPath, 0 },
160
{ DB_TOKEN, fixBackupDataDir, 0 },
162
{ DB_TOKEN, checkDbConstraints, 0 },
164
{ "TCP", checkConnectionConstraints, 0 },
165
{ "SHM", checkConnectionConstraints, 0 },
166
{ "SCI", checkConnectionConstraints, 0 },
168
{ "TCP", checkTCPConstraints, "HostName1" },
169
{ "TCP", checkTCPConstraints, "HostName2" },
170
{ "SCI", checkTCPConstraints, "HostName1" },
171
{ "SCI", checkTCPConstraints, "HostName2" },
172
{ "SHM", checkTCPConstraints, "HostName1" },
173
{ "SHM", checkTCPConstraints, "HostName2" },
175
{ "*", checkMandatory, 0 },
177
{ DB_TOKEN, saveInConfigValues, 0 },
178
{ API_TOKEN, saveInConfigValues, 0 },
179
{ MGM_TOKEN, saveInConfigValues, 0 },
181
{ "TCP", saveInConfigValues, 0 },
182
{ "SHM", saveInConfigValues, 0 },
183
{ "SCI", saveInConfigValues, 0 }
185
const int ConfigInfo::m_NoOfRules = sizeof(m_SectionRules)/sizeof(SectionRule);
187
/****************************************************************************
188
* Config Rules declarations
189
****************************************************************************/
190
static bool sanity_checks(Vector<ConfigInfo::ConfigRuleSection>§ions,
191
struct InitConfigFileParser::Context &ctx,
192
const char * rule_data);
193
static bool add_node_connections(Vector<ConfigInfo::ConfigRuleSection>§ions,
194
struct InitConfigFileParser::Context &ctx,
195
const char * rule_data);
196
static bool set_connection_priorities(Vector<ConfigInfo::ConfigRuleSection>§ions,
197
struct InitConfigFileParser::Context &ctx,
198
const char * rule_data);
199
static bool check_node_vs_replicas(Vector<ConfigInfo::ConfigRuleSection>§ions,
200
struct InitConfigFileParser::Context &ctx,
201
const char * rule_data);
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 },
212
struct DepricationTransform {
213
const char * m_section;
214
const char * m_oldName;
215
const char * m_newName;
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 },
228
#endif /* NDB_MGMAPI */
231
* The default constructors create objects with suitable values for the
232
* configuration parameters.
234
* Some are however given the value MANDATORY which means that the value
235
* must be specified in the configuration file.
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)
247
* Parameter constraints are coded in file Config.cpp.
249
* *******************************************************************
250
* Parameters used under development should be marked "NOTIMPLEMENTED"
251
* *******************************************************************
254
const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = {
256
/****************************************************************************
258
***************************************************************************/
264
ConfigInfo::CI_INTERNAL,
266
ConfigInfo::CI_SECTION,
277
ConfigInfo::CI_STRING,
285
"Hostname of computer (e.g. mysql.com)",
288
ConfigInfo::CI_STRING,
297
ConfigInfo::CI_DEPRICATED,
299
ConfigInfo::CI_STRING,
304
/****************************************************************************
306
***************************************************************************/
314
ConfigInfo::CI_SECTION,
315
(const char *)CFG_SECTION_SYSTEM,
322
"Name of system (NDB Cluster)",
325
ConfigInfo::CI_STRING,
330
CFG_SYS_PRIMARY_MGM_NODE,
333
"Node id of Primary "MGM_TOKEN_PRINT" node",
339
STR_VALUE(MAX_INT_RNIL) },
342
CFG_SYS_CONFIG_GENERATION,
343
"ConfigGenerationNumber",
345
"Configuration generation number",
351
STR_VALUE(MAX_INT_RNIL) },
353
/***************************************************************************
355
***************************************************************************/
363
ConfigInfo::CI_SECTION,
364
(const char *)NODE_TYPE_DB,
372
"Name of computer for this node",
373
ConfigInfo::CI_INTERNAL,
375
ConfigInfo::CI_STRING,
383
"Name of system for this node",
384
ConfigInfo::CI_INTERNAL,
386
ConfigInfo::CI_STRING,
395
ConfigInfo::CI_DEPRICATED,
400
STR_VALUE(MAX_DATA_NODE_ID) },
406
"Number identifying the database node ("DB_TOKEN_PRINT")",
412
STR_VALUE(MAX_DATA_NODE_ID) },
418
"Port used to setup transporter",
424
STR_VALUE(MAX_PORT_NO) },
430
"Number of copies of all data in the database (1-4)",
439
CFG_DB_NO_ATTRIBUTES,
442
"Total number of attributes stored in database. I.e. sum over all tables",
448
STR_VALUE(MAX_INT_RNIL) },
454
"Total number of tables stored in the database",
460
STR_VALUE(MAX_TABLES) },
463
CFG_DB_NO_ORDERED_INDEXES,
464
"MaxNoOfOrderedIndexes",
466
"Total number of ordered indexes that can be defined in the system",
472
STR_VALUE(MAX_INT_RNIL) },
475
CFG_DB_NO_UNIQUE_HASH_INDEXES,
476
"MaxNoOfUniqueHashIndexes",
478
"Total number of unique hash indexes that can be defined in the system",
484
STR_VALUE(MAX_INT_RNIL) },
490
"Total number of indexes that can be defined in the system",
491
ConfigInfo::CI_DEPRICATED,
496
STR_VALUE(MAX_INT_RNIL) },
500
"MaxNoOfConcurrentIndexOperations",
502
"Total number of index operations that can execute simultaneously on one "DB_TOKEN_PRINT" node",
508
STR_VALUE(MAX_INT_RNIL)
515
"Total number of triggers that can be defined in the system",
521
STR_VALUE(MAX_INT_RNIL) },
524
CFG_DB_NO_TRIGGER_OPS,
525
"MaxNoOfFiredTriggers",
527
"Total number of triggers that can fire simultaneously in one "DB_TOKEN_PRINT" node",
533
STR_VALUE(MAX_INT_RNIL) },
539
"String referencing an earlier defined COMPUTER",
542
ConfigInfo::CI_STRING,
548
"MaxNoOfSavedMessages",
550
"Max number of error messages in error log and max number of trace files",
556
STR_VALUE(MAX_INT_RNIL) },
560
"LockPagesInMainMemory",
562
"If set to yes, then NDB Cluster data will not be swapped out to disk",
571
CFG_DB_WATCHDOG_INTERVAL,
572
"TimeBetweenWatchDogCheck",
574
"Time between execution checks inside a database node",
580
STR_VALUE(MAX_INT_RNIL) },
583
CFG_DB_WATCHDOG_INTERVAL_INITIAL,
584
"TimeBetweenWatchDogCheckInitial",
586
"Time between execution checks inside a database node in the early start phases when memory is allocated",
592
STR_VALUE(MAX_INT_RNIL) },
595
CFG_DB_STOP_ON_ERROR,
598
"If set to N, "DB_TOKEN_PRINT" automatically restarts/recovers in case of node failure",
607
CFG_DB_STOP_ON_ERROR_INSERT,
608
"RestartOnErrorInsert",
610
"See src/kernel/vm/Emulator.hpp NdbRestartType for details",
611
ConfigInfo::CI_INTERNAL,
620
"MaxNoOfConcurrentOperations",
622
"Max number of operation records in transaction coordinator",
628
STR_VALUE(MAX_INT_RNIL) },
632
"MaxNoOfLocalOperations",
634
"Max number of operation records defined in the local storage node",
640
STR_VALUE(MAX_INT_RNIL) },
643
CFG_DB_NO_LOCAL_SCANS,
646
"Max number of fragment scans in parallel in the local storage node",
652
STR_VALUE(MAX_INT_RNIL) },
656
"BatchSizePerLocalScan",
658
"Used to calculate the number of lock records for scan with hold lock",
662
STR_VALUE(DEF_BATCH_SIZE),
664
STR_VALUE(MAX_PARALLEL_OP_PER_SCAN) },
667
CFG_DB_NO_TRANSACTIONS,
668
"MaxNoOfConcurrentTransactions",
670
"Max number of transaction executing concurrently on the "DB_TOKEN_PRINT" node",
676
STR_VALUE(MAX_INT_RNIL) },
680
"MaxNoOfConcurrentScans",
682
"Max number of scans executing concurrently on the "DB_TOKEN_PRINT" node",
691
CFG_DB_TRANS_BUFFER_MEM,
692
"TransactionBufferMemory",
694
"Dynamic buffer space (in bytes) for key and attribute data allocated for each "DB_TOKEN_PRINT" node",
700
STR_VALUE(MAX_INT_RNIL) },
706
"Number bytes on each "DB_TOKEN_PRINT" node allocated for storing indexes",
709
ConfigInfo::CI_INT64,
718
"Number bytes on each "DB_TOKEN_PRINT" node allocated for storing data",
721
ConfigInfo::CI_INT64,
727
CFG_DB_UNDO_INDEX_BUFFER,
730
"Number bytes on each "DB_TOKEN_PRINT" node allocated for writing UNDO logs for index part",
736
STR_VALUE(MAX_INT_RNIL)},
739
CFG_DB_UNDO_DATA_BUFFER,
742
"Number bytes on each "DB_TOKEN_PRINT" node allocated for writing UNDO logs for data part",
748
STR_VALUE(MAX_INT_RNIL)},
754
"Number bytes on each "DB_TOKEN_PRINT" node allocated for writing REDO logs",
760
STR_VALUE(MAX_INT_RNIL)},
763
CFG_DB_LONG_SIGNAL_BUFFER,
766
"Number bytes on each "DB_TOKEN_PRINT" node allocated for internal long messages",
772
STR_VALUE(MAX_INT_RNIL)},
775
CFG_DB_DISK_PAGE_BUFFER_MEMORY,
776
"DiskPageBufferMemory",
778
"Number bytes on each "DB_TOKEN_PRINT" node allocated for disk page buffer cache",
781
ConfigInfo::CI_INT64,
788
"SharedGlobalMemory",
790
"Total number bytes on each "DB_TOKEN_PRINT" node allocated for any use",
793
ConfigInfo::CI_INT64,
796
"65536G" }, // 32k pages * 32-bit i value
799
CFG_DB_START_PARTIAL_TIMEOUT,
800
"StartPartialTimeout",
802
"Time to wait before trying to start wo/ all nodes. 0=Wait forever",
808
STR_VALUE(MAX_INT_RNIL) },
811
CFG_DB_START_PARTITION_TIMEOUT,
812
"StartPartitionedTimeout",
814
"Time to wait before trying to start partitioned. 0=Wait forever",
820
STR_VALUE(MAX_INT_RNIL) },
823
CFG_DB_START_FAILURE_TIMEOUT,
824
"StartFailureTimeout",
826
"Time to wait before terminating. 0=Wait forever",
832
STR_VALUE(MAX_INT_RNIL) },
835
CFG_DB_HEARTBEAT_INTERVAL,
836
"HeartbeatIntervalDbDb",
838
"Time between "DB_TOKEN_PRINT"-"DB_TOKEN_PRINT" heartbeats. "DB_TOKEN_PRINT" considered dead after 3 missed HBs",
844
STR_VALUE(MAX_INT_RNIL) },
847
CFG_DB_API_HEARTBEAT_INTERVAL,
848
"HeartbeatIntervalDbApi",
850
"Time between "API_TOKEN_PRINT"-"DB_TOKEN_PRINT" heartbeats. "API_TOKEN_PRINT" connection closed after 3 missed HBs",
856
STR_VALUE(MAX_INT_RNIL) },
860
"TimeBetweenLocalCheckpoints",
862
"Time between taking snapshots of the database (expressed in 2log of bytes)",
872
"TimeBetweenGlobalCheckpoints",
874
"Time between doing group commit of transactions to disk",
883
CFG_DB_NO_REDOLOG_FILES,
884
"NoOfFragmentLogFiles",
886
"No of 16 Mbyte Redo log files in each of 4 file sets belonging to "DB_TOKEN_PRINT" node",
892
STR_VALUE(MAX_INT_RNIL) },
895
CFG_DB_REDOLOG_FILE_SIZE,
896
"FragmentLogFileSize",
898
"Size of each Redo log file",
907
CFG_DB_MAX_OPEN_FILES,
910
"Max number of files open per "DB_TOKEN_PRINT" node.(One thread is created per file)",
916
STR_VALUE(MAX_INT_RNIL) },
919
CFG_DB_INITIAL_OPEN_FILES,
920
"InitialNoOfOpenFiles",
922
"Initial number of files open per "DB_TOKEN_PRINT" node.(One thread is created per file)",
928
STR_VALUE(MAX_INT_RNIL) },
931
CFG_DB_TRANSACTION_CHECK_INTERVAL,
932
"TimeBetweenInactiveTransactionAbortCheck",
934
"Time between inactive transaction checks",
940
STR_VALUE(MAX_INT_RNIL) },
943
CFG_DB_TRANSACTION_INACTIVE_TIMEOUT,
944
"TransactionInactiveTimeout",
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.",
954
STR_VALUE(MAX_INT_RNIL),
956
STR_VALUE(MAX_INT_RNIL) },
959
CFG_DB_TRANSACTION_DEADLOCK_TIMEOUT,
960
"TransactionDeadlockDetectionTimeout",
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.",
971
STR_VALUE(MAX_INT_RNIL) },
974
CFG_DB_LCP_DISC_PAGES_TUP_SR,
975
"NoOfDiskPagesToDiskDuringRestartTUP",
977
"DiskCheckpointSpeedSr",
978
ConfigInfo::CI_DEPRICATED,
983
STR_VALUE(MAX_INT_RNIL) },
986
CFG_DB_LCP_DISC_PAGES_TUP,
987
"NoOfDiskPagesToDiskAfterRestartTUP",
989
"DiskCheckpointSpeed",
990
ConfigInfo::CI_DEPRICATED,
995
STR_VALUE(MAX_INT_RNIL) },
998
CFG_DB_LCP_DISC_PAGES_ACC_SR,
999
"NoOfDiskPagesToDiskDuringRestartACC",
1001
"DiskCheckpointSpeedSr",
1002
ConfigInfo::CI_DEPRICATED,
1007
STR_VALUE(MAX_INT_RNIL) },
1010
CFG_DB_LCP_DISC_PAGES_ACC,
1011
"NoOfDiskPagesToDiskAfterRestartACC",
1013
"DiskCheckpointSpeed",
1014
ConfigInfo::CI_DEPRICATED,
1019
STR_VALUE(MAX_INT_RNIL) },
1027
ConfigInfo::CI_USED,
1029
ConfigInfo::CI_BOOL,
1039
ConfigInfo::CI_DEPRICATED,
1041
ConfigInfo::CI_BOOL,
1049
CFG_DB_ARBIT_TIMEOUT,
1050
"ArbitrationTimeout",
1052
"Max time (milliseconds) database partion waits for arbitration signal",
1053
ConfigInfo::CI_USED,
1058
STR_VALUE(MAX_INT_RNIL) },
1064
"Data directory for this node",
1065
ConfigInfo::CI_USED,
1067
ConfigInfo::CI_STRING,
1072
CFG_DB_FILESYSTEM_PATH,
1075
"Path to directory where the "DB_TOKEN_PRINT" node stores its data (directory must exist)",
1076
ConfigInfo::CI_USED,
1078
ConfigInfo::CI_STRING,
1083
CFG_LOGLEVEL_STARTUP,
1086
"Node startup info printed on stdout",
1087
ConfigInfo::CI_USED,
1095
CFG_LOGLEVEL_SHUTDOWN,
1098
"Node shutdown info printed on stdout",
1099
ConfigInfo::CI_USED,
1107
CFG_LOGLEVEL_STATISTICS,
1108
"LogLevelStatistic",
1110
"Transaction, operation, transporter info printed on stdout",
1111
ConfigInfo::CI_USED,
1119
CFG_LOGLEVEL_CHECKPOINT,
1120
"LogLevelCheckpoint",
1122
"Local and Global checkpoint info printed on stdout",
1123
ConfigInfo::CI_USED,
1131
CFG_LOGLEVEL_NODERESTART,
1132
"LogLevelNodeRestart",
1134
"Node restart, node failure info printed on stdout",
1135
ConfigInfo::CI_USED,
1143
CFG_LOGLEVEL_CONNECTION,
1144
"LogLevelConnection",
1146
"Node connect/disconnect info printed on stdout",
1147
ConfigInfo::CI_USED,
1155
CFG_LOGLEVEL_CONGESTION,
1156
"LogLevelCongestion",
1158
"Congestion info printed on stdout",
1159
ConfigInfo::CI_USED,
1170
"Transporter, heartbeat errors printed on stdout",
1171
ConfigInfo::CI_USED,
1182
"Heartbeat and log info printed on stdout",
1183
ConfigInfo::CI_USED,
1194
CFG_DB_PARALLEL_BACKUPS,
1197
"Maximum number of parallel backups",
1198
ConfigInfo::CI_NOTIMPLEMENTED,
1206
CFG_DB_BACKUP_DATADIR,
1209
"Path to where to store backups",
1210
ConfigInfo::CI_USED,
1212
ConfigInfo::CI_STRING,
1217
CFG_DB_DISK_SYNCH_SIZE,
1220
"Data written to a file before a synch is forced",
1221
ConfigInfo::CI_USED,
1226
STR_VALUE(MAX_INT_RNIL) },
1229
CFG_DB_CHECKPOINT_SPEED,
1230
"DiskCheckpointSpeed",
1232
"Bytes per second allowed to be written by checkpoint",
1233
ConfigInfo::CI_USED,
1238
STR_VALUE(MAX_INT_RNIL) },
1241
CFG_DB_CHECKPOINT_SPEED_SR,
1242
"DiskCheckpointSpeedInRestart",
1244
"Bytes per second allowed to be written by checkpoint during restart",
1245
ConfigInfo::CI_USED,
1250
STR_VALUE(MAX_INT_RNIL) },
1256
"Total memory allocated for backups per node (in bytes)",
1257
ConfigInfo::CI_USED,
1260
"4M", // sum of BackupDataBufferSize and BackupLogBufferSize
1262
STR_VALUE(MAX_INT_RNIL) },
1265
CFG_DB_BACKUP_DATA_BUFFER_MEM,
1266
"BackupDataBufferSize",
1268
"Default size of databuffer for a backup (in bytes)",
1269
ConfigInfo::CI_USED,
1272
"2M", // remember to change BackupMemory
1274
STR_VALUE(MAX_INT_RNIL) },
1277
CFG_DB_BACKUP_LOG_BUFFER_MEM,
1278
"BackupLogBufferSize",
1280
"Default size of logbuffer for a backup (in bytes)",
1281
ConfigInfo::CI_USED,
1284
"2M", // remember to change BackupMemory
1286
STR_VALUE(MAX_INT_RNIL) },
1289
CFG_DB_BACKUP_WRITE_SIZE,
1292
"Default size of filesystem writes made by backup (in bytes)",
1293
ConfigInfo::CI_USED,
1298
STR_VALUE(MAX_INT_RNIL) },
1301
CFG_DB_BACKUP_MAX_WRITE_SIZE,
1302
"BackupMaxWriteSize",
1304
"Max size of filesystem writes made by backup (in bytes)",
1305
ConfigInfo::CI_USED,
1310
STR_VALUE(MAX_INT_RNIL) },
1313
CFG_DB_STRING_MEMORY,
1316
"Default size of string memory (0 -> 5% of max 1-100 -> %of max, >100 -> actual bytes)",
1317
ConfigInfo::CI_USED,
1322
STR_VALUE(MAX_INT_RNIL) },
1325
CFG_DB_MAX_ALLOCATE,
1328
"Maximum size of allocation to use when allocating memory for tables",
1329
ConfigInfo::CI_USED,
1337
CFG_DB_MEMREPORT_FREQUENCY,
1338
"MemReportFrequency",
1340
"Frequency of mem reports in seconds, 0 = only when passing %-limits",
1341
ConfigInfo::CI_USED,
1346
STR_VALUE(MAX_INT_RNIL) },
1352
"Use O_DIRECT file write/read when possible",
1353
ConfigInfo::CI_USED,
1355
ConfigInfo::CI_BOOL,
1360
/***************************************************************************
1362
***************************************************************************/
1368
ConfigInfo::CI_USED,
1370
ConfigInfo::CI_SECTION,
1371
(const char *)NODE_TYPE_API,
1379
"Name of computer for this node",
1380
ConfigInfo::CI_INTERNAL,
1382
ConfigInfo::CI_STRING,
1390
"Name of system for this node",
1391
ConfigInfo::CI_INTERNAL,
1393
ConfigInfo::CI_STRING,
1402
ConfigInfo::CI_DEPRICATED,
1407
STR_VALUE(MAX_NODES_ID) },
1413
"Number identifying application node ("API_TOKEN_PRINT")",
1414
ConfigInfo::CI_USED,
1419
STR_VALUE(MAX_NODES_ID) },
1423
"ExecuteOnComputer",
1425
"String referencing an earlier defined COMPUTER",
1426
ConfigInfo::CI_USED,
1428
ConfigInfo::CI_STRING,
1433
CFG_NODE_ARBIT_RANK,
1436
"If 0, then "API_TOKEN_PRINT" is not arbitrator. Kernel selects arbitrators in order 1, 2",
1437
ConfigInfo::CI_USED,
1445
CFG_NODE_ARBIT_DELAY,
1448
"When asked to arbitrate, arbitrator waits this long before voting (msec)",
1449
ConfigInfo::CI_USED,
1454
STR_VALUE(MAX_INT_RNIL) },
1457
CFG_MAX_SCAN_BATCH_SIZE,
1460
"The maximum collective batch size for one scan",
1461
ConfigInfo::CI_USED,
1464
STR_VALUE(MAX_SCAN_BATCH_SIZE),
1469
CFG_BATCH_BYTE_SIZE,
1472
"The default batch size in bytes",
1473
ConfigInfo::CI_USED,
1476
STR_VALUE(SCAN_BATCH_SIZE),
1484
"The default batch size in number of records",
1485
ConfigInfo::CI_USED,
1488
STR_VALUE(DEF_BATCH_SIZE),
1490
STR_VALUE(MAX_PARALLEL_OP_PER_SCAN) },
1492
/****************************************************************************
1494
***************************************************************************/
1500
ConfigInfo::CI_USED,
1502
ConfigInfo::CI_SECTION,
1503
(const char *)NODE_TYPE_MGM,
1511
"Name of computer for this node",
1512
ConfigInfo::CI_INTERNAL,
1514
ConfigInfo::CI_STRING,
1522
"Data directory for this node",
1523
ConfigInfo::CI_USED,
1525
ConfigInfo::CI_STRING,
1533
"Name of system for this node",
1534
ConfigInfo::CI_INTERNAL,
1536
ConfigInfo::CI_STRING,
1545
ConfigInfo::CI_DEPRICATED,
1550
STR_VALUE(MAX_NODES_ID) },
1556
"Number identifying the management server node ("MGM_TOKEN_PRINT")",
1557
ConfigInfo::CI_USED,
1562
STR_VALUE(MAX_NODES_ID) },
1565
CFG_LOG_DESTINATION,
1568
"String describing where logmessages are sent",
1569
ConfigInfo::CI_USED,
1571
ConfigInfo::CI_STRING,
1577
"ExecuteOnComputer",
1579
"String referencing an earlier defined COMPUTER",
1580
ConfigInfo::CI_USED,
1582
ConfigInfo::CI_STRING,
1588
"MaxNoOfSavedEvents",
1591
ConfigInfo::CI_USED,
1596
STR_VALUE(MAX_INT_RNIL) },
1602
"Port number to give commands to/fetch configurations from management server",
1603
ConfigInfo::CI_USED,
1608
STR_VALUE(MAX_PORT_NO) },
1614
"Port number used to get statistical information from a management server",
1615
ConfigInfo::CI_USED,
1620
STR_VALUE(MAX_PORT_NO) },
1623
CFG_NODE_ARBIT_RANK,
1626
"If 0, then "MGM_TOKEN_PRINT" is not arbitrator. Kernel selects arbitrators in order 1, 2",
1627
ConfigInfo::CI_USED,
1635
CFG_NODE_ARBIT_DELAY,
1639
ConfigInfo::CI_USED,
1644
STR_VALUE(MAX_INT_RNIL) },
1646
/****************************************************************************
1648
***************************************************************************/
1650
CFG_SECTION_CONNECTION,
1653
"Connection section",
1654
ConfigInfo::CI_USED,
1656
ConfigInfo::CI_SECTION,
1657
(const char *)CONNECTION_TYPE_TCP,
1662
CFG_CONNECTION_HOSTNAME_1,
1665
"Name/IP of computer on one side of the connection",
1666
ConfigInfo::CI_INTERNAL,
1668
ConfigInfo::CI_STRING,
1673
CFG_CONNECTION_HOSTNAME_2,
1676
"Name/IP of computer on one side of the connection",
1677
ConfigInfo::CI_INTERNAL,
1679
ConfigInfo::CI_STRING,
1684
CFG_CONNECTION_NODE_1,
1687
"Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection",
1688
ConfigInfo::CI_USED,
1690
ConfigInfo::CI_STRING,
1695
CFG_CONNECTION_NODE_2,
1698
"Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection",
1699
ConfigInfo::CI_USED,
1701
ConfigInfo::CI_STRING,
1706
CFG_CONNECTION_GROUP,
1710
ConfigInfo::CI_USED,
1717
CFG_CONNECTION_NODE_ID_SERVER,
1721
ConfigInfo::CI_USED,
1728
CFG_CONNECTION_SEND_SIGNAL_ID,
1731
"Sends id in each signal. Used in trace files.",
1732
ConfigInfo::CI_USED,
1734
ConfigInfo::CI_BOOL,
1741
CFG_CONNECTION_CHECKSUM,
1744
"If checksum is enabled, all signals between nodes are checked for errors",
1745
ConfigInfo::CI_USED,
1747
ConfigInfo::CI_BOOL,
1753
CFG_CONNECTION_SERVER_PORT,
1756
"Port used for this transporter",
1757
ConfigInfo::CI_USED,
1762
STR_VALUE(MAX_PORT_NO) },
1765
CFG_TCP_SEND_BUFFER_SIZE,
1768
"Bytes of buffer for signals sent from this node",
1769
ConfigInfo::CI_USED,
1774
STR_VALUE(MAX_INT_RNIL) },
1777
CFG_TCP_RECEIVE_BUFFER_SIZE,
1778
"ReceiveBufferMemory",
1780
"Bytes of buffer for signals received by this node",
1781
ConfigInfo::CI_USED,
1786
STR_VALUE(MAX_INT_RNIL) },
1793
ConfigInfo::CI_USED,
1795
ConfigInfo::CI_STRING,
1800
CFG_CONNECTION_NODE_1_SYSTEM,
1803
"System for node 1 in connection",
1804
ConfigInfo::CI_INTERNAL,
1806
ConfigInfo::CI_STRING,
1811
CFG_CONNECTION_NODE_2_SYSTEM,
1814
"System for node 2 in connection",
1815
ConfigInfo::CI_INTERNAL,
1817
ConfigInfo::CI_STRING,
1822
/****************************************************************************
1824
***************************************************************************/
1826
CFG_SECTION_CONNECTION,
1829
"Connection section",
1830
ConfigInfo::CI_USED,
1832
ConfigInfo::CI_SECTION,
1833
(const char *)CONNECTION_TYPE_SHM,
1837
CFG_CONNECTION_HOSTNAME_1,
1840
"Name/IP of computer on one side of the connection",
1841
ConfigInfo::CI_INTERNAL,
1843
ConfigInfo::CI_STRING,
1848
CFG_CONNECTION_HOSTNAME_2,
1851
"Name/IP of computer on one side of the connection",
1852
ConfigInfo::CI_INTERNAL,
1854
ConfigInfo::CI_STRING,
1859
CFG_CONNECTION_SERVER_PORT,
1862
"Port used for this transporter",
1863
ConfigInfo::CI_USED,
1868
STR_VALUE(MAX_PORT_NO) },
1874
"Signum to be used for signalling",
1875
ConfigInfo::CI_USED,
1880
STR_VALUE(MAX_INT_RNIL) },
1883
CFG_CONNECTION_NODE_1,
1886
"Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection",
1887
ConfigInfo::CI_USED,
1889
ConfigInfo::CI_STRING,
1894
CFG_CONNECTION_NODE_2,
1897
"Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection",
1898
ConfigInfo::CI_USED,
1900
ConfigInfo::CI_STRING,
1905
CFG_CONNECTION_GROUP,
1909
ConfigInfo::CI_USED,
1916
CFG_CONNECTION_NODE_ID_SERVER,
1920
ConfigInfo::CI_USED,
1927
CFG_CONNECTION_SEND_SIGNAL_ID,
1930
"Sends id in each signal. Used in trace files.",
1931
ConfigInfo::CI_USED,
1933
ConfigInfo::CI_BOOL,
1940
CFG_CONNECTION_CHECKSUM,
1943
"If checksum is enabled, all signals between nodes are checked for errors",
1944
ConfigInfo::CI_USED,
1946
ConfigInfo::CI_BOOL,
1955
"A shared memory key",
1956
ConfigInfo::CI_USED,
1961
STR_VALUE(MAX_INT_RNIL) },
1967
"Size of shared memory segment",
1968
ConfigInfo::CI_USED,
1973
STR_VALUE(MAX_INT_RNIL) },
1976
CFG_CONNECTION_NODE_1_SYSTEM,
1979
"System for node 1 in connection",
1980
ConfigInfo::CI_INTERNAL,
1982
ConfigInfo::CI_STRING,
1987
CFG_CONNECTION_NODE_2_SYSTEM,
1990
"System for node 2 in connection",
1991
ConfigInfo::CI_INTERNAL,
1993
ConfigInfo::CI_STRING,
1997
/****************************************************************************
1999
***************************************************************************/
2001
CFG_SECTION_CONNECTION,
2004
"Connection section",
2005
ConfigInfo::CI_USED,
2007
ConfigInfo::CI_SECTION,
2008
(const char *)CONNECTION_TYPE_SCI,
2013
CFG_CONNECTION_NODE_1,
2016
"Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection",
2017
ConfigInfo::CI_USED,
2019
ConfigInfo::CI_STRING,
2022
STR_VALUE(MAX_INT_RNIL) },
2025
CFG_CONNECTION_NODE_2,
2028
"Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection",
2029
ConfigInfo::CI_USED,
2031
ConfigInfo::CI_STRING,
2034
STR_VALUE(MAX_INT_RNIL) },
2037
CFG_CONNECTION_GROUP,
2041
ConfigInfo::CI_USED,
2048
CFG_CONNECTION_NODE_ID_SERVER,
2052
ConfigInfo::CI_USED,
2059
CFG_CONNECTION_HOSTNAME_1,
2062
"Name/IP of computer on one side of the connection",
2063
ConfigInfo::CI_INTERNAL,
2065
ConfigInfo::CI_STRING,
2070
CFG_CONNECTION_HOSTNAME_2,
2073
"Name/IP of computer on one side of the connection",
2074
ConfigInfo::CI_INTERNAL,
2076
ConfigInfo::CI_STRING,
2081
CFG_CONNECTION_SERVER_PORT,
2084
"Port used for this transporter",
2085
ConfigInfo::CI_USED,
2090
STR_VALUE(MAX_PORT_NO) },
2096
"SCI-node id for adapter 0 on Host1 (a computer can have two adapters)",
2097
ConfigInfo::CI_USED,
2102
STR_VALUE(MAX_INT_RNIL) },
2108
"SCI-node id for adapter 1 on Host1 (a computer can have two adapters)",
2109
ConfigInfo::CI_USED,
2114
STR_VALUE(MAX_INT_RNIL) },
2120
"SCI-node id for adapter 0 on Host2 (a computer can have two adapters)",
2121
ConfigInfo::CI_USED,
2126
STR_VALUE(MAX_INT_RNIL) },
2132
"SCI-node id for adapter 1 on Host2 (a computer can have two adapters)",
2133
ConfigInfo::CI_USED,
2138
STR_VALUE(MAX_INT_RNIL) },
2141
CFG_CONNECTION_SEND_SIGNAL_ID,
2144
"Sends id in each signal. Used in trace files.",
2145
ConfigInfo::CI_USED,
2147
ConfigInfo::CI_BOOL,
2153
CFG_CONNECTION_CHECKSUM,
2156
"If checksum is enabled, all signals between nodes are checked for errors",
2157
ConfigInfo::CI_USED,
2159
ConfigInfo::CI_BOOL,
2168
"Transporter send buffer contents are sent when this no of bytes is buffered",
2169
ConfigInfo::CI_USED,
2180
"Size of shared memory segment",
2181
ConfigInfo::CI_USED,
2186
STR_VALUE(MAX_INT_RNIL) },
2189
CFG_CONNECTION_NODE_1_SYSTEM,
2192
"System for node 1 in connection",
2193
ConfigInfo::CI_INTERNAL,
2195
ConfigInfo::CI_STRING,
2200
CFG_CONNECTION_NODE_2_SYSTEM,
2203
"System for node 2 in connection",
2204
ConfigInfo::CI_INTERNAL,
2206
ConfigInfo::CI_STRING,
2211
const int ConfigInfo::m_NoOfParams = sizeof(m_ParamInfo) / sizeof(ParamInfo);
2214
/****************************************************************************
2216
****************************************************************************/
2217
static void require(bool v)
2228
ConfigInfo::ConfigInfo()
2229
: m_info(true), m_systemDefaults(true)
2232
Properties *section;
2233
const Properties *oldpinfo;
2235
for (i=0; i<m_NoOfParams; i++) {
2236
const ParamInfo & param = m_ParamInfo[i];
2237
Uint64 default_uint64;
2240
// Create new section if it did not exist
2241
if (!m_info.getCopy(param._section, §ion)) {
2242
Properties newsection(true);
2243
m_info.put(param._section, &newsection);
2245
// Get copy of section
2246
m_info.getCopy(param._section, §ion);
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);
2258
if(param._default == MANDATORY){
2259
pinfo.put("Mandatory", (Uint32)1);
2262
switch (param._type) {
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);
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);
2283
pinfo.put("SectionType", (Uint32)UintPtr(param._default));
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
2297
// Add new pinfo to section
2298
section->put(param._fname, &pinfo);
2300
// Replace section with modified section
2301
m_info.put(param._section, section, true);
2304
if(param._type != ConfigInfo::CI_SECTION){
2306
if(!m_systemDefaults.getCopy(param._section, &p)){
2307
p = new Properties(true);
2309
if(param._default != UNDEFINED &&
2310
param._default != MANDATORY){
2311
switch (param._type)
2316
require(p->put(param._fname, param._default));
2320
require(InitConfigFileParser::convertStringToBool(param._default, default_bool));
2321
require(p->put(param._fname, default_bool));
2327
require(InitConfigFileParser::convertStringToUint64(param._default, default_uint64));
2328
require(p->put(param._fname, default_uint64));
2333
require(m_systemDefaults.put(param._section, p, true));
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;
2346
if(m_ParamInfo[i]._type == ConfigInfo::CI_SECTION)
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;
2361
/****************************************************************************
2363
****************************************************************************/
2364
inline void warning(const char * src, const char * arg){
2365
ndbout << "Illegal call to ConfigInfo::" << src << "() - " << arg << endl;
2370
ConfigInfo::getInfo(const char * section) const {
2371
const Properties * p;
2372
if(!m_info.get(section, &p)){
2374
// warning("getInfo", section);
2380
ConfigInfo::getDefaults(const char * section) const {
2381
const Properties * p;
2382
if(!m_systemDefaults.get(section, &p)){
2384
//warning("getDefaults", section);
2391
getInfoInt(const Properties * section,
2392
const char* fname, const char * type){
2394
const Properties * p;
2395
if (section->get(fname, &p) && p->get(type, &val32)) {
2400
if(p && p->get(type, &val64)){
2405
if(section->get(fname, &p)){
2409
warning(type, fname);
2415
getInfoString(const Properties * section,
2416
const char* fname, const char * type){
2418
const Properties * p;
2419
if (section->get(fname, &p) && p->get(type, &val)) {
2422
warning(type, fname);
2427
ConfigInfo::getMax(const Properties * section, const char* fname) const {
2428
return getInfoInt(section, fname, "Max");
2432
ConfigInfo::getMin(const Properties * section, const char* fname) const {
2433
return getInfoInt(section, fname, "Min");
2437
ConfigInfo::getDefault(const Properties * section, const char* fname) const {
2438
return getInfoInt(section, fname, "Default");
2442
ConfigInfo::getDescription(const Properties * section,
2443
const char* fname) const {
2444
return getInfoString(section, fname, "Description");
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;
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;
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;
2472
ConfigInfo::verify(const Properties * section, const char* fname,
2473
Uint64 value) const {
2476
min = getInfoInt(section, fname, "Min");
2477
max = getInfoInt(section, fname, "Max");
2479
warning("verify", fname);
2481
if (value >= min && value <= max)
2488
ConfigInfo::getType(const Properties * section, const char* fname) const {
2489
return (ConfigInfo::Type) getInfoInt(section, fname, "Type");
2493
ConfigInfo::getStatus(const Properties * section, const char* fname) const {
2494
return (ConfigInfo::Status) getInfoInt(section, fname, "Status");
2497
/****************************************************************************
2499
****************************************************************************/
2501
void ConfigInfo::print() const {
2502
Properties::Iterator it(&m_info);
2503
for (const char* n = it.first(); n != NULL; n = it.next()) {
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;
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;
2536
ndbout << "UNKNOWN" << endl;
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 (";
2550
ndbout << "Default: " << getDefault(section, parameter) << " (";
2552
ndbout << "Min: " << getMin(section, parameter) << ", ";
2553
ndbout << "Max: " << getMax(section, parameter) << ")" << endl;
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;
2563
ndbout << "No default value" << endl;
2567
case ConfigInfo::CI_SECTION:
2572
/****************************************************************************
2574
****************************************************************************/
2577
* Node rule: Add "Type" and update "NoOfNodes"
2580
transformNode(InitConfigFileParser::Context & ctx, const char * data){
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);
2587
while (ctx.m_userProperties.get("AllocatedNodeId_", id, &line))
2589
if (id != nextNodeId)
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);
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);
2606
ctx.reportError("too many nodes configured, only up to %d nodes supported.",
2611
// next node id _always_ next numbers after last used id
2612
ctx.m_userProperties.put("NextNodeId", id+1, true);
2614
ctx.m_userProperties.put("AllocatedNodeId_", id, ctx.m_sectionLineno);
2615
BaseString::snprintf(ctx.pname, sizeof(ctx.pname), "Node_%d", id);
2617
ctx.m_currentSection->put("Type", ctx.fname);
2620
ctx.m_userProperties.get("NoOfNodes", &nodes);
2621
ctx.m_userProperties.put("NoOfNodes", ++nodes, true);
2624
* Update count (per type)
2627
ctx.m_userProperties.get(ctx.fname, &nodes);
2628
ctx.m_userProperties.put(ctx.fname, ++nodes, true);
2633
static bool checkLocalhostHostnameMix(InitConfigFileParser::Context & ctx, const char * data)
2635
DBUG_ENTER("checkLocalhostHostnameMix");
2636
const char * hostname= 0;
2637
ctx.m_currentSection->get("HostName", &hostname);
2638
if (hostname == 0 || hostname[0] == 0)
2641
Uint32 localhost_used= 0;
2642
if(!strcmp(hostname, "localhost") || !strcmp(hostname, "127.0.0.1")){
2644
ctx.m_userProperties.put("$computer-localhost-used", localhost_used);
2645
if(!ctx.m_userProperties.get("$computer-localhost", &hostname))
2648
ctx.m_userProperties.get("$computer-localhost-used", &localhost_used);
2649
ctx.m_userProperties.put("$computer-localhost", hostname);
2652
if (localhost_used) {
2653
ctx.reportError("Mixing of localhost (default for [NDBD]HostName) with other hostname(%s) is illegal",
2662
fixNodeHostname(InitConfigFileParser::Context & ctx, const char * data)
2664
const char * hostname;
2665
DBUG_ENTER("fixNodeHostname");
2667
if (ctx.m_currentSection->get("HostName", &hostname))
2668
DBUG_RETURN(checkLocalhostHostnameMix(ctx,0));
2670
const char * compId;
2671
if(!ctx.m_currentSection->get("ExecuteOnComputer", &compId))
2674
const Properties * computer;
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);
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);
2691
require(ctx.m_currentSection->put("HostName", hostname));
2692
DBUG_RETURN(checkLocalhostHostnameMix(ctx,0));
2696
fixFileSystemPath(InitConfigFileParser::Context & ctx, const char * data){
2697
DBUG_ENTER("fixFileSystemPath");
2700
if (ctx.m_currentSection->get("FileSystemPath", &path))
2703
if (ctx.m_currentSection->get("DataDir", &path)) {
2704
require(ctx.m_currentSection->put("FileSystemPath", path));
2713
fixBackupDataDir(InitConfigFileParser::Context & ctx, const char * data){
2716
if (ctx.m_currentSection->get("BackupDataDir", &path))
2719
if (ctx.m_currentSection->get("FileSystemPath", &path)) {
2720
require(ctx.m_currentSection->put("BackupDataDir", path));
2729
* Connection rule: Check support of connection
2732
checkConnectionSupport(InitConfigFileParser::Context & ctx, const char * data)
2735
if (strcasecmp("TCP",ctx.fname) == 0)
2739
else if (strcasecmp("SHM",ctx.fname) == 0)
2741
#ifndef NDB_SHM_TRANSPORTER
2745
else if (strcasecmp("SCI",ctx.fname) == 0)
2747
#ifndef NDB_SCI_TRANSPORTER
2754
ctx.reportError("Binary not compiled with this connection support, "
2755
"[%s] starting at line: %d",
2756
ctx.fname, ctx.m_sectionLineno);
2763
* Connection rule: Update "NoOfConnections"
2766
transformConnection(InitConfigFileParser::Context & ctx, const char * data)
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);
2773
ctx.m_currentSection->put("Type", ctx.fname);
2778
* System rule: Just add it
2781
transformSystem(InitConfigFileParser::Context & ctx, const char * data){
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);
2791
ndbout << "transformSystem " << name << endl;
2793
BaseString::snprintf(ctx.pname, sizeof(ctx.pname), "SYSTEM_%s", name);
2799
* Computer rule: Update "NoOfComputers", add "Type"
2802
transformComputer(InitConfigFileParser::Context & ctx, const char * data){
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);
2810
BaseString::snprintf(ctx.pname, sizeof(ctx.pname), "Computer_%s", id);
2812
Uint32 computers = 0;
2813
ctx.m_userProperties.get("NoOfComputers", &computers);
2814
ctx.m_userProperties.put("NoOfComputers", ++computers, true);
2816
const char * hostname = 0;
2817
ctx.m_currentSection->get("HostName", &hostname);
2822
return checkLocalhostHostnameMix(ctx,0);
2826
* Apply default values
2829
applyDefaultValues(InitConfigFileParser::Context & ctx,
2830
const Properties * defaults)
2832
DBUG_ENTER("applyDefaultValues");
2833
if(defaults != NULL){
2834
Properties::Iterator it(defaults);
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:{
2843
::require(defaults->get(name, &val));
2844
ctx.m_currentSection->put(name, val);
2845
DBUG_PRINT("info",("%s=%d #default",name,val));
2848
case ConfigInfo::CI_INT64:{
2850
::require(defaults->get(name, &val));
2851
ctx.m_currentSection->put64(name, val);
2852
DBUG_PRINT("info",("%s=%lld #default",name,val));
2855
case ConfigInfo::CI_STRING:{
2857
::require(defaults->get(name, &val));
2858
ctx.m_currentSection->put(name, val);
2859
DBUG_PRINT("info",("%s=%s #default",name,val));
2862
case ConfigInfo::CI_SECTION:
2869
switch (ctx.m_info->getType(ctx.m_currentInfo, name)){
2870
case ConfigInfo::CI_INT:
2871
case ConfigInfo::CI_BOOL:{
2873
::require(ctx.m_currentSection->get(name, &val));
2874
DBUG_PRINT("info",("%s=%d",name,val));
2877
case ConfigInfo::CI_INT64:{
2879
::require(ctx.m_currentSection->get(name, &val));
2880
DBUG_PRINT("info",("%s=%lld",name,val));
2883
case ConfigInfo::CI_STRING:{
2885
::require(ctx.m_currentSection->get(name, &val));
2886
DBUG_PRINT("info",("%s=%s",name,val));
2889
case ConfigInfo::CI_SECTION:
2900
applyDefaultValues(InitConfigFileParser::Context & ctx, const char * data){
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);
2913
* Check that a section contains all MANDATORY parameters
2916
checkMandatory(InitConfigFileParser::Context & ctx, const char * data){
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));
2923
if(info->get("Mandatory", &val)){
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);
2938
* Connection rule: Fix node id
2940
* Transform a string "NodeidX" (e.g. "uppsala.32")
2941
* into a Uint32 "NodeIdX" (e.g. 32) and a string "SystemX" (e.g. "uppsala").
2943
static bool fixNodeId(InitConfigFileParser::Context & ctx, const char * data)
2945
char buf[] = "NodeIdX"; buf[6] = data[sizeof("NodeI")];
2946
char sysbuf[] = "SystemX"; sysbuf[6] = data[sizeof("NodeI")];
2948
if(!ctx.m_currentSection->get(buf, &nodeId))
2950
ctx.reportError("Mandatory parameter %s missing from section"
2951
"[%s] starting at line: %d",
2952
buf, ctx.fname, ctx.m_sectionLineno);
2956
char tmpLine[MAX_LINE_LENGTH];
2957
strncpy(tmpLine, nodeId, MAX_LINE_LENGTH);
2958
char* token1 = strtok(tmpLine, ".");
2959
char* token2 = strtok(NULL, ".");
2964
ctx.reportError("Value for mandatory parameter %s missing from section "
2965
"[%s] starting at line: %d",
2966
buf, ctx.fname, ctx.m_sectionLineno);
2969
if (token2 == NULL) { // Only a number given
2972
id = strtol(token1, &p, 10);
2973
if (errno != 0 || id <= 0x0 || id > MAX_NODES)
2975
ctx.reportError("Illegal value for mandatory parameter %s from section "
2976
"[%s] starting at line: %d",
2977
buf, ctx.fname, ctx.m_sectionLineno);
2980
require(ctx.m_currentSection->put(buf, id, true));
2981
} else { // A pair given (e.g. "uppsala.32")
2984
id = strtol(token2, &p, 10);
2985
if (errno != 0 || id <= 0x0 || id > MAX_NODES)
2987
ctx.reportError("Illegal value for mandatory parameter %s from section "
2988
"[%s] starting at line: %d",
2989
buf, ctx.fname, ctx.m_sectionLineno);
2992
require(ctx.m_currentSection->put(buf, id, true));
2993
require(ctx.m_currentSection->put(sysbuf, token1));
2999
* Connection rule: Fix hostname
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
3007
fixHostname(InitConfigFileParser::Context & ctx, const char * data){
3009
char buf[] = "NodeIdX"; buf[6] = data[sizeof("HostNam")];
3010
char sysbuf[] = "SystemX"; sysbuf[6] = data[sizeof("HostNam")];
3012
if(!ctx.m_currentSection->contains(data)){
3014
require(ctx.m_currentSection->get(buf, &id));
3016
const Properties * node;
3017
if(!ctx.m_config->get("Node", id, &node))
3019
ctx.reportError("Unknown node: \"%d\" specified in connection "
3020
"[%s] starting at line: %d",
3021
id, ctx.fname, ctx.m_sectionLineno);
3025
const char * hostname;
3026
require(node->get("HostName", &hostname));
3027
require(ctx.m_currentSection->put(data, hostname));
3033
* Connection rule: Fix port number (using a port number adder)
3036
fixPortNumber(InitConfigFileParser::Context & ctx, const char * data){
3038
DBUG_ENTER("fixPortNumber");
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));
3050
const Properties *node1, *node2;
3051
require(ctx.m_config->get("Node", id1, &node1));
3052
require(ctx.m_config->get("Node", id2, &node2));
3054
const char *type1, *type2;
3055
require(node1->get("Type", &type1));
3056
require(node2->get("Type", &type2));
3058
/* add NodeIdServer info */
3060
Uint32 nodeIdServer = id1 < id2 ? id1 : id2;
3061
if(strcmp(type1, API_TOKEN) == 0 || strcmp(type2, MGM_TOKEN) == 0)
3063
else if(strcmp(type2, API_TOKEN) == 0 || strcmp(type1, MGM_TOKEN) == 0)
3065
ctx.m_currentSection->put("NodeIdServer", nodeIdServer);
3067
if (id2 == nodeIdServer) {
3069
const char *tmp= hostName1;
3070
hostName1= hostName2;
3079
const Properties *tmp= node1;
3084
const char *tmp= type1;
3091
BaseString hostname(hostName1);
3093
if (hostname.c_str()[0] == 0) {
3094
ctx.reportError("Hostname required on nodeid %d since it will "
3095
"act as server.", id1);
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);
3106
!node1->get("ServerPort", &port) &&
3107
!ctx.m_userProperties.get("ServerPort_", id1, &port))
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.
3115
if(ctx.m_userDefaults && ctx.m_userDefaults->get("PortNumber", &base))
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);
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);
3131
ctx.m_userProperties.put("ServerPortBase", base);
3135
ctx.m_userProperties.put("ServerPort_", id1, port);
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);
3147
ctx.m_currentSection->put("PortNumber", port);
3150
DBUG_PRINT("info", ("connection %d-%d port %d host %s",
3151
id1, id2, port, hostname.c_str()));
3157
fixShmUniqueId(InitConfigFileParser::Context & ctx, const char * data)
3159
DBUG_ENTER("fixShmUniqueId");
3161
ctx.m_userProperties.get(ctx.fname, &nodes);
3162
if (nodes == 1) // first management server
3164
Uint32 portno= atoi(NDB_PORT);
3165
ctx.m_currentSection->get("PortNumber", &portno);
3166
ctx.m_userProperties.put("ShmUniqueId", portno);
3173
fixShmKey(InitConfigFileParser::Context & ctx, const char *)
3175
DBUG_ENTER("fixShmKey");
3177
static int last_signum= -1;
3179
if(!ctx.m_currentSection->get("Signum", &signum))
3181
signum= OPT_NDB_SHM_SIGNUM_DEFAULT;
3184
ctx.reportError("Unable to set default parameter for [SHM]Signum"
3185
" please specify [SHM DEFAULT]Signum");
3188
ctx.m_currentSection->put("Signum", signum);
3189
DBUG_PRINT("info",("Added Signum=%u", signum));
3191
if ( last_signum != (int)signum && last_signum >= 0 )
3193
ctx.reportError("All shared memory transporters must have same [SHM]Signum defined."
3194
" Use [SHM DEFAULT]Signum");
3197
last_signum= (int)signum;
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))
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));
3215
* DB Node rule: Check various constraints
3218
checkDbConstraints(InitConfigFileParser::Context & ctx, const char *){
3220
Uint32 t1 = 0, t2 = 0;
3221
ctx.m_currentSection->get("MaxNoOfConcurrentOperations", &t1);
3222
ctx.m_currentSection->get("MaxNoOfConcurrentTransactions", &t2);
3225
ctx.reportError("MaxNoOfConcurrentOperations must be greater than "
3226
"MaxNoOfConcurrentTransactions - [%s] starting at line: %d",
3227
ctx.fname, ctx.m_sectionLineno);
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);
3241
ctx.m_userProperties.put("NoOfReplicas", replicas);
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.
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);
3258
Uint64 sum= (Uint64)noOfTables + noOfOrderedIndexes + noOfUniqueHashIndexes;
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);
3272
* Connection rule: Check varius constraints
3275
checkConnectionConstraints(InitConfigFileParser::Context & ctx, const char *){
3277
Uint32 id1 = 0, id2 = 0;
3278
ctx.m_currentSection->get("NodeId1", &id1);
3279
ctx.m_currentSection->get("NodeId2", &id2);
3282
ctx.reportError("Illegal connection from node to itself"
3283
" - [%s] starting at line: %d",
3284
ctx.fname, ctx.m_sectionLineno);
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);
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);
3306
require(node1->get("Type", &type1));
3307
require(node2->get("Type", &type2));
3310
* Report error if the following are true
3311
* -# None of the nodes is of type DB
3312
* -# Not both of them are MGMs
3314
if((strcmp(type1, DB_TOKEN) != 0 && strcmp(type2, DB_TOKEN) != 0) &&
3315
!(strcmp(type1, MGM_TOKEN) == 0 && strcmp(type2, MGM_TOKEN) == 0))
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);
3328
checkTCPConstraints(InitConfigFileParser::Context & ctx, const char * data){
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);
3344
transform(InitConfigFileParser::Context & ctx,
3346
const char * oldName,
3347
const char * newName,
3348
double add, double mul){
3350
if(ctx.m_currentSection->contains(newName)){
3351
ctx.reportError("Both %s and %s specified"
3352
" - [%s] starting at line: %d",
3354
ctx.fname, ctx.m_sectionLineno);
3358
PropertiesType oldType;
3359
require(ctx.m_currentSection->getTypeOf(oldName, &oldType));
3360
ConfigInfo::Type newType = ctx.m_info->getType(ctx.m_currentInfo, newName);
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",
3368
ctx.fname, ctx.m_sectionLineno);
3372
require(ctx.m_currentSection->get(oldName, &oldVal));
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",
3379
ctx.fname, ctx.m_sectionLineno);
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));
3392
fixDepricated(InitConfigFileParser::Context & ctx, const char * data){
3395
* Transform old values to new values
3396
* Transform new values to old values (backward compatible)
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)){
3410
} else if(strcasecmp(name, p->m_newName) == 0) {
3411
if(!transform(ctx, tmp, name, p->m_oldName, -add/mul,1.0/mul)){
3420
Properties::Iterator it2(&tmp);
3421
for (name = it2.first(); name != NULL; name = it2.next()) {
3422
PropertiesType type;
3423
require(tmp.getTypeOf(name, &type));
3425
case PropertiesType_Uint32:{
3427
require(tmp.get(name, &val));
3428
::require(ctx.m_currentSection->put(name, val));
3431
case PropertiesType_char:{
3433
require(tmp.get(name, &val));
3434
::require(ctx.m_currentSection->put(name, val));
3437
case PropertiesType_Uint64:{
3439
require(tmp.get(name, &val));
3440
::require(ctx.m_currentSection->put64(name, val));
3443
case PropertiesType_Properties:
3451
extern int g_print_full_config;
3454
saveInConfigValues(InitConfigFileParser::Context & ctx, const char * data){
3455
const Properties * sec;
3456
if(!ctx.m_currentInfo->get(ctx.fname, &sec)){
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));
3469
if(id == KEY_INTERNAL || status == ConfigInfo::CI_INTERNAL){
3470
ndbout_c("skipping section %s", ctx.fname);
3474
if (g_print_full_config)
3476
const char *alias= ConfigInfo::nameToAlias(ctx.fname);
3477
printf("[%s]\n", alias ? alias : ctx.fname);
3481
ctx.m_userProperties.get("$Section", id, &no);
3482
ctx.m_userProperties.put("$Section", id, no+1, true);
3484
ctx.m_configValues.openSection(id, no);
3485
ctx.m_configValues.put(CFG_TYPE_OF_SECTION, typeVal);
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))
3494
info->get("Id", &id);
3496
if(id == KEY_INTERNAL)
3500
PropertiesType type;
3501
require(ctx.m_currentSection->getTypeOf(n, &type));
3503
case PropertiesType_Uint32:{
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);
3511
case PropertiesType_Uint64:{
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);
3519
case PropertiesType_char:{
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);
3532
ctx.m_configValues.closeSection();
3538
sanity_checks(Vector<ConfigInfo::ConfigRuleSection>§ions,
3539
struct InitConfigFileParser::Context &ctx,
3540
const char * rule_data)
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");
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");
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");
3561
add_a_connection(Vector<ConfigInfo::ConfigRuleSection>§ions,
3562
struct InitConfigFileParser::Context &ctx,
3563
Uint32 nodeId1, Uint32 nodeId2, bool use_shm)
3565
ConfigInfo::ConfigRuleSection s;
3566
const char *hostname1= 0, *hostname2= 0;
3567
const Properties *tmp;
3569
require(ctx.m_config->get("Node", nodeId1, &tmp));
3570
tmp->get("HostName", &hostname1);
3572
require(ctx.m_config->get("Node", nodeId2, &tmp));
3573
tmp->get("HostName", &hostname2);
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);
3583
hostname1 && hostname1[0] &&
3584
hostname2 && hostname2[0] &&
3585
strcmp(hostname1,hostname2) == 0)
3587
s.m_sectionType= BaseString("SHM");
3588
DBUG_PRINT("info",("adding SHM connection %d %d",nodeId1,nodeId2));
3592
s.m_sectionType= BaseString("TCP");
3593
DBUG_PRINT("info",("adding TCP connection %d %d",nodeId1,nodeId2));
3596
sections.push_back(s);
3600
add_node_connections(Vector<ConfigInfo::ConfigRuleSection>§ions,
3601
struct InitConfigFileParser::Context &ctx,
3602
const char * rule_data)
3604
DBUG_ENTER("add_node_connections");
3606
Properties * props= ctx.m_config;
3607
Properties p_connections(true);
3608
Properties p_connections2(true);
3611
const Properties * tmp;
3612
Uint32 nodeId1, nodeId2;
3614
if(!props->get("Connection", i, &tmp)) break;
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);
3621
p_connections2.put("", nodeId1 + nodeId2<<16, nodeId1);
3622
p_connections2.put("", nodeId2 + nodeId1<<16, nodeId2);
3626
ctx.m_userProperties.get("NoOfNodes", &nNodes);
3628
Properties p_db_nodes(true);
3629
Properties p_api_nodes(true);
3630
Properties p_mgm_nodes(true);
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;
3639
if(!tmp->get("Type", &type)) continue;
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);
3649
Uint32 nodeId1, nodeId2, dummy;
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);
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);
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);
3681
static bool set_connection_priorities(Vector<ConfigInfo::ConfigRuleSection>§ions,
3682
struct InitConfigFileParser::Context &ctx,
3683
const char * rule_data)
3685
DBUG_ENTER("set_connection_priorities");
3690
check_node_vs_replicas(Vector<ConfigInfo::ConfigRuleSection>§ions,
3691
struct InitConfigFileParser::Context &ctx,
3692
const char * rule_data)
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");
3705
// check that node groups and arbitrators are ok
3706
// just issue warning if not
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;
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";
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;
3727
if(!tmp->get("Type", &type)) continue;
3729
const char* host= 0;
3730
tmp->get("HostName", &host);
3732
if (strcmp(type,DB_TOKEN) == 0)
3736
if (!p_db_hosts.get(host,&ii))
3738
p_db_hosts.put(host,i);
3739
if (p_arbitrators.get(host,&ii))
3741
arbitration_warning.appfmt(arbit_warn_fmt, ii, i, host);
3742
p_arbitrators.remove(host); // only one warning per db node
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++)
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);
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);
3769
DBUG_ASSERT(i_group <= replicas);
3770
if (i_group == replicas)
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.");
3778
node_group_warning.append(".\n Host failure may "
3779
"cause complete cluster shutdown.");
3785
else if (strcmp(type,API_TOKEN) == 0 ||
3786
strcmp(type,MGM_TOKEN) == 0)
3789
if(tmp->get("ArbitrationRank", &rank) && rank > 0)
3791
with_arbitration_rank = true; //check whether MGM or API node configured with rank >0
3792
if(host && host[0] != 0)
3795
p_arbitrators.put(host,i);
3796
if (p_db_hosts.get(host,&ii))
3798
arbitration_warning.appfmt(arbit_warn_fmt, i, ii, host);
3803
arbitration_warning.appfmt(arbit_warn_fmt2, i);
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)
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);
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.");
3825
template class Vector<ConfigInfo::ConfigRuleSection>;
3826
#endif /* NDB_MGMAPI */