mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / storage / ndb / src / mgmsrv / ConfigInfo.cpp
blobd615185e87063f602a78b0ce7e8522b0333e5d53
1 /* Copyright (c) 2003-2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
16 #include <ndb_global.h>
17 #ifndef NDB_MGMAPI
18 #include <ndb_opt_defaults.h>
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>
27 extern my_bool opt_ndb_shm;
28 extern my_bool opt_core;
30 #else
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 /****************************************************************************
44 * Section names
45 ****************************************************************************/
47 #define DB_TOKEN_PRINT "ndbd(DB)"
48 #define MGM_TOKEN_PRINT "ndb_mgmd(MGM)"
49 #define API_TOKEN_PRINT "mysqld(API)"
51 #define DB_TOKEN "DB"
52 #define MGM_TOKEN "MGM"
53 #define API_TOKEN "API"
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}
64 const char*
65 ConfigInfo::m_sectionNames[]={
66 "SYSTEM",
67 "COMPUTER",
69 DB_TOKEN,
70 MGM_TOKEN,
71 API_TOKEN,
73 "TCP",
74 "SCI",
75 "SHM"
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>&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);
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 }
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;
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}
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)
244 * - Attr7: Min value
245 * - Attr8: Max value
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 /****************************************************************************
257 * COMPUTER
258 ***************************************************************************/
260 KEY_INTERNAL,
261 "COMPUTER",
262 "COMPUTER",
263 "Computer section",
264 ConfigInfo::CI_INTERNAL,
265 false,
266 ConfigInfo::CI_SECTION,
268 0, 0 },
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 },
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 },
293 KEY_INTERNAL,
294 "ByteOrder",
295 "COMPUTER",
297 ConfigInfo::CI_DEPRICATED,
298 false,
299 ConfigInfo::CI_STRING,
300 UNDEFINED,
302 0 },
304 /****************************************************************************
305 * SYSTEM
306 ***************************************************************************/
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 },
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 },
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) },
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) },
353 /***************************************************************************
354 * DB
355 ***************************************************************************/
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
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 },
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 },
391 KEY_INTERNAL,
392 "Id",
393 DB_TOKEN,
395 ConfigInfo::CI_DEPRICATED,
396 false,
397 ConfigInfo::CI_INT,
398 MANDATORY,
399 "1",
400 STR_VALUE(MAX_DATA_NODE_ID) },
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) },
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) },
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" },
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) },
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) },
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) },
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) },
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) },
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)
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) },
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) },
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 },
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) },
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" },
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) },
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) },
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" },
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" },
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) },
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) },
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) },
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) },
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) },
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" },
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) },
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" },
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" },
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)},
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)},
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)},
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)},
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" },
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
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) },
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) },
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) },
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) },
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) },
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" },
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" },
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) },
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" },
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) },
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) },
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) },
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) },
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) },
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) },
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) },
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) },
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) },
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"},
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"},
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) },
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 },
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 },
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" },
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" },
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" },
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" },
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" },
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" },
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" },
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" },
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" },
1191 * Backup
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" },
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 },
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) },
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) },
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) },
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) },
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) },
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) },
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) },
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) },
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) },
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" },
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) },
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"},
1360 /***************************************************************************
1361 * API
1362 ***************************************************************************/
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
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,
1384 0, 0 },
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 },
1398 KEY_INTERNAL,
1399 "Id",
1400 API_TOKEN,
1402 ConfigInfo::CI_DEPRICATED,
1403 false,
1404 ConfigInfo::CI_INT,
1405 MANDATORY,
1406 "1",
1407 STR_VALUE(MAX_NODES_ID) },
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) },
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 },
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" },
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) },
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" },
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" },
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) },
1492 /****************************************************************************
1493 * MGM
1494 ***************************************************************************/
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
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,
1516 0, 0 },
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 },
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 },
1541 KEY_INTERNAL,
1542 "Id",
1543 MGM_TOKEN,
1545 ConfigInfo::CI_DEPRICATED,
1546 false,
1547 ConfigInfo::CI_INT,
1548 MANDATORY,
1549 "1",
1550 STR_VALUE(MAX_NODES_ID) },
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) },
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,
1573 0, 0 },
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,
1584 0, 0 },
1587 KEY_INTERNAL,
1588 "MaxNoOfSavedEvents",
1589 MGM_TOKEN,
1591 ConfigInfo::CI_USED,
1592 false,
1593 ConfigInfo::CI_INT,
1594 "100",
1595 "0",
1596 STR_VALUE(MAX_INT_RNIL) },
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) },
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) },
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" },
1635 CFG_NODE_ARBIT_DELAY,
1636 "ArbitrationDelay",
1637 MGM_TOKEN,
1639 ConfigInfo::CI_USED,
1640 false,
1641 ConfigInfo::CI_INT,
1642 "0",
1643 "0",
1644 STR_VALUE(MAX_INT_RNIL) },
1646 /****************************************************************************
1647 * TCP
1648 ***************************************************************************/
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
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 },
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 },
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 },
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 },
1706 CFG_CONNECTION_GROUP,
1707 "Group",
1708 "TCP",
1710 ConfigInfo::CI_USED,
1711 false,
1712 ConfigInfo::CI_INT,
1713 "55",
1714 "0", "200" },
1717 CFG_CONNECTION_NODE_ID_SERVER,
1718 "NodeIdServer",
1719 "TCP",
1721 ConfigInfo::CI_USED,
1722 false,
1723 ConfigInfo::CI_INT,
1724 MANDATORY,
1725 "1", "63" },
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" },
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" },
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) },
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) },
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) },
1789 CFG_TCP_PROXY,
1790 "Proxy",
1791 "TCP",
1793 ConfigInfo::CI_USED,
1794 false,
1795 ConfigInfo::CI_STRING,
1796 UNDEFINED,
1797 0, 0 },
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 },
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 },
1822 /****************************************************************************
1823 * SHM
1824 ***************************************************************************/
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 },
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 },
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 },
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) },
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) },
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 },
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 },
1905 CFG_CONNECTION_GROUP,
1906 "Group",
1907 "SHM",
1909 ConfigInfo::CI_USED,
1910 false,
1911 ConfigInfo::CI_INT,
1912 "35",
1913 "0", "200" },
1916 CFG_CONNECTION_NODE_ID_SERVER,
1917 "NodeIdServer",
1918 "SHM",
1920 ConfigInfo::CI_USED,
1921 false,
1922 ConfigInfo::CI_INT,
1923 MANDATORY,
1924 "1", "63" },
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" },
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" },
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) },
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) },
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 },
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 },
1997 /****************************************************************************
1998 * SCI
1999 ***************************************************************************/
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
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) },
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) },
2037 CFG_CONNECTION_GROUP,
2038 "Group",
2039 "SCI",
2041 ConfigInfo::CI_USED,
2042 false,
2043 ConfigInfo::CI_INT,
2044 "15",
2045 "0", "200" },
2048 CFG_CONNECTION_NODE_ID_SERVER,
2049 "NodeIdServer",
2050 "SCI",
2052 ConfigInfo::CI_USED,
2053 false,
2054 ConfigInfo::CI_INT,
2055 MANDATORY,
2056 "1", "63" },
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 },
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 },
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) },
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) },
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) },
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) },
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) },
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" },
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" },
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" },
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) },
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 },
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 }
2211 const int ConfigInfo::m_NoOfParams = sizeof(m_ParamInfo) / sizeof(ParamInfo);
2213 #ifndef NDB_MGMAPI
2214 /****************************************************************************
2215 * Ctor
2216 ****************************************************************************/
2217 static void require(bool v)
2219 if(!v)
2221 if (opt_core)
2222 abort();
2223 else
2224 exit(-1);
2228 ConfigInfo::ConfigInfo()
2229 : m_info(true), m_systemDefaults(true)
2231 int i;
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;
2238 bool default_bool;
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);
2245 // Get copy of section
2246 m_info.getCopy(param._section, &section);
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) {
2263 case CI_BOOL:
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;
2272 case CI_INT:
2273 case CI_INT64:
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;
2282 case CI_SECTION:
2283 pinfo.put("SectionType", (Uint32)UintPtr(param._default));
2284 break;
2285 case CI_STRING:
2286 break;
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);
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);
2302 delete section;
2304 if(param._type != ConfigInfo::CI_SECTION){
2305 Properties * p;
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)
2313 case CI_SECTION:
2314 break;
2315 case CI_STRING:
2316 require(p->put(param._fname, param._default));
2317 break;
2318 case CI_BOOL:
2320 require(InitConfigFileParser::convertStringToBool(param._default, default_bool));
2321 require(p->put(param._fname, default_bool));
2322 break;
2324 case CI_INT:
2325 case CI_INT64:
2327 require(InitConfigFileParser::convertStringToUint64(param._default, default_uint64));
2328 require(p->put(param._fname, default_uint64));
2329 break;
2333 require(m_systemDefaults.put(param._section, p, true));
2334 delete p;
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);
2346 if(m_ParamInfo[i]._type == ConfigInfo::CI_SECTION)
2347 continue;
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);
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);
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);
2376 return p;
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);
2386 return p;
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;
2399 Uint64 val64;
2400 if(p && p->get(type, &val64)){
2401 return val64;
2404 section->print();
2405 if(section->get(fname, &p)){
2406 p->print();
2409 warning(type, fname);
2410 return 0;
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;
2422 warning(type, fname);
2423 return val;
2426 Uint64
2427 ConfigInfo::getMax(const Properties * section, const char* fname) const {
2428 return getInfoInt(section, fname, "Max");
2431 Uint64
2432 ConfigInfo::getMin(const Properties * section, const char* fname) const {
2433 return getInfoInt(section, fname, "Min");
2436 Uint64
2437 ConfigInfo::getDefault(const Properties * section, const char* fname) const {
2438 return getInfoInt(section, fname, "Default");
2441 const char*
2442 ConfigInfo::getDescription(const Properties * section,
2443 const char* fname) const {
2444 return getInfoString(section, fname, "Description");
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;
2452 return false;
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;
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;
2471 bool
2472 ConfigInfo::verify(const Properties * section, const char* fname,
2473 Uint64 value) const {
2474 Uint64 min, max;
2476 min = getInfoInt(section, fname, "Min");
2477 max = getInfoInt(section, fname, "Max");
2478 if(min > max){
2479 warning("verify", fname);
2481 if (value >= min && value <= max)
2482 return true;
2483 else
2484 return false;
2487 ConfigInfo::Type
2488 ConfigInfo::getType(const Properties * section, const char* fname) const {
2489 return (ConfigInfo::Type) getInfoInt(section, fname, "Type");
2492 ConfigInfo::Status
2493 ConfigInfo::getStatus(const Properties * section, const char* fname) const {
2494 return (ConfigInfo::Status) getInfoInt(section, fname, "Status");
2497 /****************************************************************************
2498 * Printers
2499 ****************************************************************************/
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);
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);
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;
2538 ndbout << endl;
2539 break;
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) << " (";
2552 ndbout << "Min: " << getMin(section, parameter) << ", ";
2553 ndbout << "Max: " << getMax(section, parameter) << ")" << endl;
2554 ndbout << endl;
2555 break;
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;
2565 ndbout << endl;
2566 break;
2567 case ConfigInfo::CI_SECTION:
2568 break;
2572 /****************************************************************************
2573 * Section Rules
2574 ****************************************************************************/
2577 * Node rule: Add "Type" and update "NoOfNodes"
2579 bool
2580 transformNode(InitConfigFileParser::Context & ctx, const char * data){
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)
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);
2601 return false;
2604 if(id >= MAX_NODES)
2606 ctx.reportError("too many nodes configured, only up to %d nodes supported.",
2607 MAX_NODES);
2608 return false;
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);
2619 Uint32 nodes = 0;
2620 ctx.m_userProperties.get("NoOfNodes", &nodes);
2621 ctx.m_userProperties.put("NoOfNodes", ++nodes, true);
2624 * Update count (per type)
2626 nodes = 0;
2627 ctx.m_userProperties.get(ctx.fname, &nodes);
2628 ctx.m_userProperties.put(ctx.fname, ++nodes, true);
2630 return 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)
2639 DBUG_RETURN(true);
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);
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);
2658 DBUG_RETURN(true);
2661 bool
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))
2672 DBUG_RETURN(true);
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);
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);
2691 require(ctx.m_currentSection->put("HostName", hostname));
2692 DBUG_RETURN(checkLocalhostHostnameMix(ctx,0));
2695 bool
2696 fixFileSystemPath(InitConfigFileParser::Context & ctx, const char * data){
2697 DBUG_ENTER("fixFileSystemPath");
2699 const char * path;
2700 if (ctx.m_currentSection->get("FileSystemPath", &path))
2701 DBUG_RETURN(true);
2703 if (ctx.m_currentSection->get("DataDir", &path)) {
2704 require(ctx.m_currentSection->put("FileSystemPath", path));
2705 DBUG_RETURN(true);
2708 require(false);
2709 DBUG_RETURN(false);
2712 bool
2713 fixBackupDataDir(InitConfigFileParser::Context & ctx, const char * data){
2715 const char * path;
2716 if (ctx.m_currentSection->get("BackupDataDir", &path))
2717 return true;
2719 if (ctx.m_currentSection->get("FileSystemPath", &path)) {
2720 require(ctx.m_currentSection->put("BackupDataDir", path));
2721 return true;
2724 require(false);
2725 return false;
2729 * Connection rule: Check support of connection
2731 bool
2732 checkConnectionSupport(InitConfigFileParser::Context & ctx, const char * data)
2734 int error= 0;
2735 if (strcasecmp("TCP",ctx.fname) == 0)
2737 // always enabled
2739 else if (strcasecmp("SHM",ctx.fname) == 0)
2741 #ifndef NDB_SHM_TRANSPORTER
2742 error= 1;
2743 #endif
2745 else if (strcasecmp("SCI",ctx.fname) == 0)
2747 #ifndef NDB_SCI_TRANSPORTER
2748 error= 1;
2749 #endif
2752 if (error)
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;
2759 return true;
2763 * Connection rule: Update "NoOfConnections"
2765 bool
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);
2774 return true;
2778 * System rule: Just add it
2780 bool
2781 transformSystem(InitConfigFileParser::Context & ctx, const char * data){
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;
2791 ndbout << "transformSystem " << name << endl;
2793 BaseString::snprintf(ctx.pname, sizeof(ctx.pname), "SYSTEM_%s", name);
2795 return true;
2799 * Computer rule: Update "NoOfComputers", add "Type"
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;
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);
2818 if(!hostname){
2819 return true;
2822 return checkLocalhostHostnameMix(ctx,0);
2826 * Apply default values
2828 void
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:{
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;
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;
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;
2862 case ConfigInfo::CI_SECTION:
2863 break;
2866 #ifndef DBUG_OFF
2867 else
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;
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;
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;
2889 case ConfigInfo::CI_SECTION:
2890 break;
2893 #endif
2896 DBUG_VOID_RETURN;
2899 bool
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);
2906 else
2907 return false;
2909 return true;
2913 * Check that a section contains all MANDATORY parameters
2915 bool
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));
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;
2934 return true;
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")];
2947 const char* nodeId;
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);
2953 return false;
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;
2962 if(!token1)
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;
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)
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;
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)
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;
2992 require(ctx.m_currentSection->put(buf, id, true));
2993 require(ctx.m_currentSection->put(sysbuf, token1));
2995 return true;
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
3006 static bool
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)){
3013 Uint32 id = 0;
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);
3022 return false;
3025 const char * hostname;
3026 require(node->get("HostName", &hostname));
3027 require(ctx.m_currentSection->put(data, hostname));
3029 return true;
3033 * Connection rule: Fix port number (using a port number adder)
3035 static bool
3036 fixPortNumber(InitConfigFileParser::Context & ctx, const char * data){
3038 DBUG_ENTER("fixPortNumber");
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));
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)
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);
3067 if (id2 == nodeIdServer) {
3069 const char *tmp= hostName1;
3070 hostName1= hostName2;
3071 hostName2= tmp;
3074 Uint32 tmp= id1;
3075 id1= id2;
3076 id2= tmp;
3079 const Properties *tmp= node1;
3080 node1= node2;
3081 node2= tmp;
3084 const char *tmp= type1;
3085 type1= type2;
3086 type2= tmp;
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);
3096 DBUG_RETURN(false);
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);
3105 if (!port &&
3106 !node1->get("ServerPort", &port) &&
3107 !ctx.m_userProperties.get("ServerPort_", id1, &port))
3109 Uint32 base= 0;
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))
3117 Uint32 adder= 0;
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);
3134 port= base + adder;
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);
3145 else
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()));
3153 DBUG_RETURN(true);
3156 static bool
3157 fixShmUniqueId(InitConfigFileParser::Context & ctx, const char * data)
3159 DBUG_ENTER("fixShmUniqueId");
3160 Uint32 nodes= 0;
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);
3168 DBUG_RETURN(true);
3171 static
3172 bool
3173 fixShmKey(InitConfigFileParser::Context & ctx, const char *)
3175 DBUG_ENTER("fixShmKey");
3177 static int last_signum= -1;
3178 Uint32 signum;
3179 if(!ctx.m_currentSection->get("Signum", &signum))
3181 signum= OPT_NDB_SHM_SIGNUM_DEFAULT;
3182 if (signum <= 0)
3184 ctx.reportError("Unable to set default parameter for [SHM]Signum"
3185 " please specify [SHM DEFAULT]Signum");
3186 return false;
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");
3195 return false;
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));
3211 DBUG_RETURN(true);
3215 * DB Node rule: Check various constraints
3217 static bool
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);
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;
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;
3240 } else {
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);
3265 return false;
3268 return true;
3272 * Connection rule: Check varius constraints
3274 static bool
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);
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;
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;
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;
3304 const char * type1;
3305 const char * type2;
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);
3321 return false;
3324 return true;
3327 static bool
3328 checkTCPConstraints(InitConfigFileParser::Context & ctx, const char * data){
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;
3339 return true;
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){
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;
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",
3367 oldName, newName,
3368 ctx.fname, ctx.m_sectionLineno);
3369 return false;
3371 Uint64 oldVal;
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",
3378 oldName, newName,
3379 ctx.fname, ctx.m_sectionLineno);
3380 return false;
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));
3388 return true;
3391 static bool
3392 fixDepricated(InitConfigFileParser::Context & ctx, const char * data){
3393 const char * name;
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)){
3408 return false;
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;
3416 p++;
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;
3431 case PropertiesType_char:{
3432 const char * val;
3433 require(tmp.get(name, &val));
3434 ::require(ctx.m_currentSection->put(name, val));
3435 break;
3437 case PropertiesType_Uint64:{
3438 Uint64 val;
3439 require(tmp.get(name, &val));
3440 ::require(ctx.m_currentSection->put64(name, val));
3441 break;
3443 case PropertiesType_Properties:
3444 default:
3445 ::require(false);
3448 return true;
3451 extern int g_print_full_config;
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;
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));
3469 if(id == KEY_INTERNAL || status == ConfigInfo::CI_INTERNAL){
3470 ndbout_c("skipping section %s", ctx.fname);
3471 break;
3474 if (g_print_full_config)
3476 const char *alias= ConfigInfo::nameToAlias(ctx.fname);
3477 printf("[%s]\n", alias ? alias : ctx.fname);
3480 Uint32 no = 0;
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))
3491 continue;
3493 id = 0;
3494 info->get("Id", &id);
3496 if(id == KEY_INTERNAL)
3497 continue;
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;
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;
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;
3527 default:
3528 require(false);
3530 require(ok);
3532 ctx.m_configValues.closeSection();
3533 } while(0);
3534 return true;
3537 static bool
3538 sanity_checks(Vector<ConfigInfo::ConfigRuleSection>&sections,
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");
3547 return false;
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;
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;
3557 return true;
3560 static void
3561 add_a_connection(Vector<ConfigInfo::ConfigRuleSection>&sections,
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);
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);
3582 if (use_shm &&
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));
3590 else
3592 s.m_sectionType= BaseString("TCP");
3593 DBUG_PRINT("info",("adding TCP connection %d %d",nodeId1,nodeId2));
3596 sections.push_back(s);
3599 static bool
3600 add_node_connections(Vector<ConfigInfo::ConfigRuleSection>&sections,
3601 struct InitConfigFileParser::Context &ctx,
3602 const char * rule_data)
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);
3610 for (i = 0;; i++){
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);
3625 Uint32 nNodes;
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;
3636 n++;
3638 const char * type;
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);
3678 DBUG_RETURN(true);
3681 static bool set_connection_priorities(Vector<ConfigInfo::ConfigRuleSection>&sections,
3682 struct InitConfigFileParser::Context &ctx,
3683 const char * rule_data)
3685 DBUG_ENTER("set_connection_priorities");
3686 DBUG_RETURN(true);
3689 static bool
3690 check_node_vs_replicas(Vector<ConfigInfo::ConfigRuleSection>&sections,
3691 struct InitConfigFileParser::Context &ctx,
3692 const char * rule_data)
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;
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";
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++;
3726 const char * type;
3727 if(!tmp->get("Type", &type)) continue;
3729 const char* host= 0;
3730 tmp->get("HostName", &host);
3732 if (strcmp(type,DB_TOKEN) == 0)
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))
3741 arbitration_warning.appfmt(arbit_warn_fmt, ii, i, host);
3742 p_arbitrators.remove(host); // only one warning per db node
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++)
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);
3768 i_group++;
3769 DBUG_ASSERT(i_group <= replicas);
3770 if (i_group == replicas)
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;
3785 else if (strcmp(type,API_TOKEN) == 0 ||
3786 strcmp(type,MGM_TOKEN) == 0)
3788 Uint32 rank;
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)
3794 Uint32 ii;
3795 p_arbitrators.put(host,i);
3796 if (p_db_hosts.get(host,&ii))
3798 arbitration_warning.appfmt(arbit_warn_fmt, i, ii, host);
3801 else
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.");
3822 return true;
3825 template class Vector<ConfigInfo::ConfigRuleSection>;
3826 #endif /* NDB_MGMAPI */