00001 /* Copyright (C) 2003 MySQL AB 00002 00003 This program is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU General Public License as published by 00005 the Free Software Foundation; either version 2 of the License, or 00006 (at your option) any later version. 00007 00008 This program is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 GNU General Public License for more details. 00012 00013 You should have received a copy of the GNU General Public License 00014 along with this program; if not, write to the Free Software 00015 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 00016 00017 #include <ndb_global.h> 00018 #include <ndb_opt_defaults.h> 00019 00020 #include <NdbTCP.h> 00021 #include "ConfigInfo.hpp" 00022 #include <mgmapi_config_parameters.h> 00023 #include <ndb_limits.h> 00024 #include "InitConfigFileParser.hpp" 00025 #include <m_string.h> 00026 00027 extern my_bool opt_ndb_shm; 00028 extern my_bool opt_core; 00029 00030 #define MAX_LINE_LENGTH 255 00031 #define KEY_INTERNAL 0 00032 #define MAX_INT_RNIL 0xfffffeff 00033 #define MAX_PORT_NO 65535 00034 00035 #define _STR_VALUE(x) #x 00036 #define STR_VALUE(x) _STR_VALUE(x) 00037 00038 /**************************************************************************** 00039 * Section names 00040 ****************************************************************************/ 00041 00042 #define DB_TOKEN_PRINT "ndbd(DB)" 00043 #define MGM_TOKEN_PRINT "ndb_mgmd(MGM)" 00044 #define API_TOKEN_PRINT "mysqld(API)" 00045 00046 #define DB_TOKEN "DB" 00047 #define MGM_TOKEN "MGM" 00048 #define API_TOKEN "API" 00049 00050 const ConfigInfo::AliasPair 00051 ConfigInfo::m_sectionNameAliases[]={ 00052 {API_TOKEN, "MYSQLD"}, 00053 {DB_TOKEN, "NDBD"}, 00054 {MGM_TOKEN, "NDB_MGMD"}, 00055 {0, 0} 00056 }; 00057 00058 const char* 00059 ConfigInfo::m_sectionNames[]={ 00060 "SYSTEM", 00061 "COMPUTER", 00062 00063 DB_TOKEN, 00064 MGM_TOKEN, 00065 API_TOKEN, 00066 00067 "TCP", 00068 "SCI", 00069 "SHM", 00070 "OSE" 00071 }; 00072 const int ConfigInfo::m_noOfSectionNames = 00073 sizeof(m_sectionNames)/sizeof(char*); 00074 00075 00076 /**************************************************************************** 00077 * Section Rules declarations 00078 ****************************************************************************/ 00079 static bool transformComputer(InitConfigFileParser::Context & ctx, const char *); 00080 static bool transformSystem(InitConfigFileParser::Context & ctx, const char *); 00081 static bool transformNode(InitConfigFileParser::Context & ctx, const char *); 00082 static bool checkConnectionSupport(InitConfigFileParser::Context & ctx, const char *); 00083 static bool transformConnection(InitConfigFileParser::Context & ctx, const char *); 00084 static bool applyDefaultValues(InitConfigFileParser::Context & ctx, const char *); 00085 static bool checkMandatory(InitConfigFileParser::Context & ctx, const char *); 00086 static bool fixPortNumber(InitConfigFileParser::Context & ctx, const char *); 00087 static bool fixShmKey(InitConfigFileParser::Context & ctx, const char *); 00088 static bool checkDbConstraints(InitConfigFileParser::Context & ctx, const char *); 00089 static bool checkConnectionConstraints(InitConfigFileParser::Context &, const char *); 00090 static bool checkTCPConstraints(InitConfigFileParser::Context &, const char *); 00091 static bool fixNodeHostname(InitConfigFileParser::Context & ctx, const char * data); 00092 static bool fixHostname(InitConfigFileParser::Context & ctx, const char * data); 00093 static bool fixNodeId(InitConfigFileParser::Context & ctx, const char * data); 00094 static bool fixDepricated(InitConfigFileParser::Context & ctx, const char *); 00095 static bool saveInConfigValues(InitConfigFileParser::Context & ctx, const char *); 00096 static bool fixFileSystemPath(InitConfigFileParser::Context & ctx, const char * data); 00097 static bool fixBackupDataDir(InitConfigFileParser::Context & ctx, const char * data); 00098 static bool fixShmUniqueId(InitConfigFileParser::Context & ctx, const char * data); 00099 static bool checkLocalhostHostnameMix(InitConfigFileParser::Context & ctx, const char * data); 00100 00101 const ConfigInfo::SectionRule 00102 ConfigInfo::m_SectionRules[] = { 00103 { "SYSTEM", transformSystem, 0 }, 00104 { "COMPUTER", transformComputer, 0 }, 00105 00106 { DB_TOKEN, transformNode, 0 }, 00107 { API_TOKEN, transformNode, 0 }, 00108 { MGM_TOKEN, transformNode, 0 }, 00109 00110 { MGM_TOKEN, fixShmUniqueId, 0 }, 00111 00112 { "TCP", checkConnectionSupport, 0 }, 00113 { "SHM", checkConnectionSupport, 0 }, 00114 { "SCI", checkConnectionSupport, 0 }, 00115 { "OSE", checkConnectionSupport, 0 }, 00116 00117 { "TCP", transformConnection, 0 }, 00118 { "SHM", transformConnection, 0 }, 00119 { "SCI", transformConnection, 0 }, 00120 { "OSE", transformConnection, 0 }, 00121 00122 { DB_TOKEN, fixNodeHostname, 0 }, 00123 { API_TOKEN, fixNodeHostname, 0 }, 00124 { MGM_TOKEN, fixNodeHostname, 0 }, 00125 00126 { "TCP", fixNodeId, "NodeId1" }, 00127 { "TCP", fixNodeId, "NodeId2" }, 00128 { "SHM", fixNodeId, "NodeId1" }, 00129 { "SHM", fixNodeId, "NodeId2" }, 00130 { "SCI", fixNodeId, "NodeId1" }, 00131 { "SCI", fixNodeId, "NodeId2" }, 00132 { "OSE", fixNodeId, "NodeId1" }, 00133 { "OSE", fixNodeId, "NodeId2" }, 00134 00135 { "TCP", fixHostname, "HostName1" }, 00136 { "TCP", fixHostname, "HostName2" }, 00137 { "SHM", fixHostname, "HostName1" }, 00138 { "SHM", fixHostname, "HostName2" }, 00139 { "SCI", fixHostname, "HostName1" }, 00140 { "SCI", fixHostname, "HostName2" }, 00141 { "SHM", fixHostname, "HostName1" }, 00142 { "SHM", fixHostname, "HostName2" }, 00143 { "OSE", fixHostname, "HostName1" }, 00144 { "OSE", fixHostname, "HostName2" }, 00145 00146 { "TCP", fixPortNumber, 0 }, // has to come after fixHostName 00147 { "SHM", fixPortNumber, 0 }, // has to come after fixHostName 00148 { "SCI", fixPortNumber, 0 }, // has to come after fixHostName 00149 00150 { "*", applyDefaultValues, "user" }, 00151 { "*", fixDepricated, 0 }, 00152 { "*", applyDefaultValues, "system" }, 00153 00154 { "SHM", fixShmKey, 0 }, // has to come after apply default values 00155 00156 { DB_TOKEN, checkLocalhostHostnameMix, 0 }, 00157 { API_TOKEN, checkLocalhostHostnameMix, 0 }, 00158 { MGM_TOKEN, checkLocalhostHostnameMix, 0 }, 00159 00160 { DB_TOKEN, fixFileSystemPath, 0 }, 00161 { DB_TOKEN, fixBackupDataDir, 0 }, 00162 00163 { DB_TOKEN, checkDbConstraints, 0 }, 00164 00165 { "TCP", checkConnectionConstraints, 0 }, 00166 { "SHM", checkConnectionConstraints, 0 }, 00167 { "SCI", checkConnectionConstraints, 0 }, 00168 { "OSE", checkConnectionConstraints, 0 }, 00169 00170 { "TCP", checkTCPConstraints, "HostName1" }, 00171 { "TCP", checkTCPConstraints, "HostName2" }, 00172 { "SCI", checkTCPConstraints, "HostName1" }, 00173 { "SCI", checkTCPConstraints, "HostName2" }, 00174 { "SHM", checkTCPConstraints, "HostName1" }, 00175 { "SHM", checkTCPConstraints, "HostName2" }, 00176 00177 { "*", checkMandatory, 0 }, 00178 00179 { DB_TOKEN, saveInConfigValues, 0 }, 00180 { API_TOKEN, saveInConfigValues, 0 }, 00181 { MGM_TOKEN, saveInConfigValues, 0 }, 00182 00183 { "TCP", saveInConfigValues, 0 }, 00184 { "SHM", saveInConfigValues, 0 }, 00185 { "SCI", saveInConfigValues, 0 }, 00186 { "OSE", saveInConfigValues, 0 } 00187 }; 00188 const int ConfigInfo::m_NoOfRules = sizeof(m_SectionRules)/sizeof(SectionRule); 00189 00190 /**************************************************************************** 00191 * Config Rules declarations 00192 ****************************************************************************/ 00193 static bool sanity_checks(Vector<ConfigInfo::ConfigRuleSection>§ions, 00194 struct InitConfigFileParser::Context &ctx, 00195 const char * rule_data); 00196 static bool add_node_connections(Vector<ConfigInfo::ConfigRuleSection>§ions, 00197 struct InitConfigFileParser::Context &ctx, 00198 const char * rule_data); 00199 static bool set_connection_priorities(Vector<ConfigInfo::ConfigRuleSection>§ions, 00200 struct InitConfigFileParser::Context &ctx, 00201 const char * rule_data); 00202 static bool check_node_vs_replicas(Vector<ConfigInfo::ConfigRuleSection>§ions, 00203 struct InitConfigFileParser::Context &ctx, 00204 const char * rule_data); 00205 00206 const ConfigInfo::ConfigRule 00207 ConfigInfo::m_ConfigRules[] = { 00208 { sanity_checks, 0 }, 00209 { add_node_connections, 0 }, 00210 { set_connection_priorities, 0 }, 00211 { check_node_vs_replicas, 0 }, 00212 { 0, 0 } 00213 }; 00214 00215 struct DepricationTransform { 00216 const char * m_section; 00217 const char * m_oldName; 00218 const char * m_newName; 00219 double m_add; 00220 double m_mul; 00221 }; 00222 00223 static 00224 const DepricationTransform f_deprication[] = { 00225 { DB_TOKEN, "Discless", "Diskless", 0, 1 }, 00226 { DB_TOKEN, "Id", "NodeId", 0, 1 }, 00227 { API_TOKEN, "Id", "NodeId", 0, 1 }, 00228 { MGM_TOKEN, "Id", "NodeId", 0, 1 }, 00229 { 0, 0, 0, 0, 0} 00230 }; 00231 00256 const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { 00257 00258 /**************************************************************************** 00259 * COMPUTER 00260 ***************************************************************************/ 00261 { 00262 KEY_INTERNAL, 00263 "COMPUTER", 00264 "COMPUTER", 00265 "Computer section", 00266 ConfigInfo::CI_INTERNAL, 00267 false, 00268 ConfigInfo::CI_SECTION, 00269 0, 00270 0, 0 }, 00271 00272 { 00273 KEY_INTERNAL, 00274 "Id", 00275 "COMPUTER", 00276 "Name of computer", 00277 ConfigInfo::CI_USED, 00278 false, 00279 ConfigInfo::CI_STRING, 00280 MANDATORY, 00281 0, 0 }, 00282 00283 { 00284 KEY_INTERNAL, 00285 "HostName", 00286 "COMPUTER", 00287 "Hostname of computer (e.g. mysql.com)", 00288 ConfigInfo::CI_USED, 00289 false, 00290 ConfigInfo::CI_STRING, 00291 MANDATORY, 00292 0, 0 }, 00293 00294 { 00295 KEY_INTERNAL, 00296 "ByteOrder", 00297 "COMPUTER", 00298 0, 00299 ConfigInfo::CI_DEPRICATED, 00300 false, 00301 ConfigInfo::CI_STRING, 00302 UNDEFINED, 00303 0, 00304 0 }, 00305 00306 /**************************************************************************** 00307 * SYSTEM 00308 ***************************************************************************/ 00309 { 00310 CFG_SECTION_SYSTEM, 00311 "SYSTEM", 00312 "SYSTEM", 00313 "System section", 00314 ConfigInfo::CI_USED, 00315 false, 00316 ConfigInfo::CI_SECTION, 00317 (const char *)CFG_SECTION_SYSTEM, 00318 0, 0 }, 00319 00320 { 00321 CFG_SYS_NAME, 00322 "Name", 00323 "SYSTEM", 00324 "Name of system (NDB Cluster)", 00325 ConfigInfo::CI_USED, 00326 false, 00327 ConfigInfo::CI_STRING, 00328 MANDATORY, 00329 0, 0 }, 00330 00331 { 00332 CFG_SYS_PRIMARY_MGM_NODE, 00333 "PrimaryMGMNode", 00334 "SYSTEM", 00335 "Node id of Primary "MGM_TOKEN_PRINT" node", 00336 ConfigInfo::CI_USED, 00337 false, 00338 ConfigInfo::CI_INT, 00339 "0", 00340 "0", 00341 STR_VALUE(MAX_INT_RNIL) }, 00342 00343 { 00344 CFG_SYS_CONFIG_GENERATION, 00345 "ConfigGenerationNumber", 00346 "SYSTEM", 00347 "Configuration generation number", 00348 ConfigInfo::CI_USED, 00349 false, 00350 ConfigInfo::CI_INT, 00351 "0", 00352 "0", 00353 STR_VALUE(MAX_INT_RNIL) }, 00354 00355 /*************************************************************************** 00356 * DB 00357 ***************************************************************************/ 00358 { 00359 CFG_SECTION_NODE, 00360 DB_TOKEN, 00361 DB_TOKEN, 00362 "Node section", 00363 ConfigInfo::CI_USED, 00364 false, 00365 ConfigInfo::CI_SECTION, 00366 (const char *)NODE_TYPE_DB, 00367 0, 0 00368 }, 00369 00370 { 00371 CFG_NODE_HOST, 00372 "HostName", 00373 DB_TOKEN, 00374 "Name of computer for this node", 00375 ConfigInfo::CI_INTERNAL, 00376 false, 00377 ConfigInfo::CI_STRING, 00378 "localhost", 00379 0, 0 }, 00380 00381 { 00382 CFG_NODE_SYSTEM, 00383 "System", 00384 DB_TOKEN, 00385 "Name of system for this node", 00386 ConfigInfo::CI_INTERNAL, 00387 false, 00388 ConfigInfo::CI_STRING, 00389 UNDEFINED, 00390 0, 0 }, 00391 00392 { 00393 KEY_INTERNAL, 00394 "Id", 00395 DB_TOKEN, 00396 "", 00397 ConfigInfo::CI_DEPRICATED, 00398 false, 00399 ConfigInfo::CI_INT, 00400 MANDATORY, 00401 "1", 00402 STR_VALUE(MAX_NODES) }, 00403 00404 { 00405 CFG_NODE_ID, 00406 "NodeId", 00407 DB_TOKEN, 00408 "Number identifying the database node ("DB_TOKEN_PRINT")", 00409 ConfigInfo::CI_USED, 00410 false, 00411 ConfigInfo::CI_INT, 00412 MANDATORY, 00413 "1", 00414 STR_VALUE(MAX_NODES) }, 00415 00416 { 00417 KEY_INTERNAL, 00418 "ServerPort", 00419 DB_TOKEN, 00420 "Port used to setup transporter", 00421 ConfigInfo::CI_USED, 00422 false, 00423 ConfigInfo::CI_INT, 00424 UNDEFINED, 00425 "1", 00426 STR_VALUE(MAX_PORT_NO) }, 00427 00428 { 00429 CFG_DB_NO_REPLICAS, 00430 "NoOfReplicas", 00431 DB_TOKEN, 00432 "Number of copies of all data in the database (1-4)", 00433 ConfigInfo::CI_USED, 00434 false, 00435 ConfigInfo::CI_INT, 00436 MANDATORY, 00437 "1", 00438 "4" }, 00439 00440 { 00441 CFG_DB_NO_ATTRIBUTES, 00442 "MaxNoOfAttributes", 00443 DB_TOKEN, 00444 "Total number of attributes stored in database. I.e. sum over all tables", 00445 ConfigInfo::CI_USED, 00446 false, 00447 ConfigInfo::CI_INT, 00448 "1000", 00449 "32", 00450 STR_VALUE(MAX_INT_RNIL) }, 00451 00452 { 00453 CFG_DB_NO_TABLES, 00454 "MaxNoOfTables", 00455 DB_TOKEN, 00456 "Total number of tables stored in the database", 00457 ConfigInfo::CI_USED, 00458 false, 00459 ConfigInfo::CI_INT, 00460 "128", 00461 "8", 00462 STR_VALUE(MAX_INT_RNIL) }, 00463 00464 { 00465 CFG_DB_NO_ORDERED_INDEXES, 00466 "MaxNoOfOrderedIndexes", 00467 DB_TOKEN, 00468 "Total number of ordered indexes that can be defined in the system", 00469 ConfigInfo::CI_USED, 00470 false, 00471 ConfigInfo::CI_INT, 00472 "128", 00473 "0", 00474 STR_VALUE(MAX_INT_RNIL) }, 00475 00476 { 00477 CFG_DB_NO_UNIQUE_HASH_INDEXES, 00478 "MaxNoOfUniqueHashIndexes", 00479 DB_TOKEN, 00480 "Total number of unique hash indexes that can be defined in the system", 00481 ConfigInfo::CI_USED, 00482 false, 00483 ConfigInfo::CI_INT, 00484 "64", 00485 "0", 00486 STR_VALUE(MAX_INT_RNIL) }, 00487 00488 { 00489 CFG_DB_NO_INDEXES, 00490 "MaxNoOfIndexes", 00491 DB_TOKEN, 00492 "Total number of indexes that can be defined in the system", 00493 ConfigInfo::CI_DEPRICATED, 00494 false, 00495 ConfigInfo::CI_INT, 00496 "128", 00497 "0", 00498 STR_VALUE(MAX_INT_RNIL) }, 00499 00500 { 00501 CFG_DB_NO_INDEX_OPS, 00502 "MaxNoOfConcurrentIndexOperations", 00503 DB_TOKEN, 00504 "Total number of index operations that can execute simultaneously on one "DB_TOKEN_PRINT" node", 00505 ConfigInfo::CI_USED, 00506 false, 00507 ConfigInfo::CI_INT, 00508 "8K", 00509 "0", 00510 STR_VALUE(MAX_INT_RNIL) 00511 }, 00512 00513 { 00514 CFG_DB_NO_TRIGGERS, 00515 "MaxNoOfTriggers", 00516 DB_TOKEN, 00517 "Total number of triggers that can be defined in the system", 00518 ConfigInfo::CI_USED, 00519 false, 00520 ConfigInfo::CI_INT, 00521 "768", 00522 "0", 00523 STR_VALUE(MAX_INT_RNIL) }, 00524 00525 { 00526 CFG_DB_NO_TRIGGER_OPS, 00527 "MaxNoOfFiredTriggers", 00528 DB_TOKEN, 00529 "Total number of triggers that can fire simultaneously in one "DB_TOKEN_PRINT" node", 00530 ConfigInfo::CI_USED, 00531 false, 00532 ConfigInfo::CI_INT, 00533 "4000", 00534 "0", 00535 STR_VALUE(MAX_INT_RNIL) }, 00536 00537 { 00538 KEY_INTERNAL, 00539 "ExecuteOnComputer", 00540 DB_TOKEN, 00541 "String referencing an earlier defined COMPUTER", 00542 ConfigInfo::CI_USED, 00543 false, 00544 ConfigInfo::CI_STRING, 00545 UNDEFINED, 00546 0, 0 }, 00547 00548 { 00549 CFG_DB_NO_SAVE_MSGS, 00550 "MaxNoOfSavedMessages", 00551 DB_TOKEN, 00552 "Max number of error messages in error log and max number of trace files", 00553 ConfigInfo::CI_USED, 00554 true, 00555 ConfigInfo::CI_INT, 00556 "25", 00557 "0", 00558 STR_VALUE(MAX_INT_RNIL) }, 00559 00560 { 00561 CFG_DB_MEMLOCK, 00562 "LockPagesInMainMemory", 00563 DB_TOKEN, 00564 "If set to yes, then NDB Cluster data will not be swapped out to disk", 00565 ConfigInfo::CI_USED, 00566 true, 00567 ConfigInfo::CI_BOOL, 00568 "false", 00569 "false", 00570 "true" }, 00571 00572 { 00573 CFG_DB_WATCHDOG_INTERVAL, 00574 "TimeBetweenWatchDogCheck", 00575 DB_TOKEN, 00576 "Time between execution checks inside a database node", 00577 ConfigInfo::CI_USED, 00578 true, 00579 ConfigInfo::CI_INT, 00580 "6000", 00581 "70", 00582 STR_VALUE(MAX_INT_RNIL) }, 00583 00584 { 00585 CFG_DB_STOP_ON_ERROR, 00586 "StopOnError", 00587 DB_TOKEN, 00588 "If set to N, "DB_TOKEN_PRINT" automatically restarts/recovers in case of node failure", 00589 ConfigInfo::CI_USED, 00590 true, 00591 ConfigInfo::CI_BOOL, 00592 "true", 00593 "false", 00594 "true" }, 00595 00596 { 00597 CFG_DB_STOP_ON_ERROR_INSERT, 00598 "RestartOnErrorInsert", 00599 DB_TOKEN, 00600 "See src/kernel/vm/Emulator.hpp NdbRestartType for details", 00601 ConfigInfo::CI_INTERNAL, 00602 true, 00603 ConfigInfo::CI_INT, 00604 "2", 00605 "0", 00606 "4" }, 00607 00608 { 00609 CFG_DB_NO_OPS, 00610 "MaxNoOfConcurrentOperations", 00611 DB_TOKEN, 00612 "Max number of operation records in transaction coordinator", 00613 ConfigInfo::CI_USED, 00614 false, 00615 ConfigInfo::CI_INT, 00616 "32k", 00617 "32", 00618 STR_VALUE(MAX_INT_RNIL) }, 00619 00620 { 00621 CFG_DB_NO_LOCAL_OPS, 00622 "MaxNoOfLocalOperations", 00623 DB_TOKEN, 00624 "Max number of operation records defined in the local storage node", 00625 ConfigInfo::CI_USED, 00626 false, 00627 ConfigInfo::CI_INT, 00628 UNDEFINED, 00629 "32", 00630 STR_VALUE(MAX_INT_RNIL) }, 00631 00632 { 00633 CFG_DB_NO_LOCAL_SCANS, 00634 "MaxNoOfLocalScans", 00635 DB_TOKEN, 00636 "Max number of fragment scans in parallel in the local storage node", 00637 ConfigInfo::CI_USED, 00638 false, 00639 ConfigInfo::CI_INT, 00640 UNDEFINED, 00641 "32", 00642 STR_VALUE(MAX_INT_RNIL) }, 00643 00644 { 00645 CFG_DB_BATCH_SIZE, 00646 "BatchSizePerLocalScan", 00647 DB_TOKEN, 00648 "Used to calculate the number of lock records for scan with hold lock", 00649 ConfigInfo::CI_USED, 00650 false, 00651 ConfigInfo::CI_INT, 00652 STR_VALUE(DEF_BATCH_SIZE), 00653 "1", 00654 STR_VALUE(MAX_PARALLEL_OP_PER_SCAN) }, 00655 00656 { 00657 CFG_DB_NO_TRANSACTIONS, 00658 "MaxNoOfConcurrentTransactions", 00659 DB_TOKEN, 00660 "Max number of transaction executing concurrently on the "DB_TOKEN_PRINT" node", 00661 ConfigInfo::CI_USED, 00662 false, 00663 ConfigInfo::CI_INT, 00664 "4096", 00665 "32", 00666 STR_VALUE(MAX_INT_RNIL) }, 00667 00668 { 00669 CFG_DB_NO_SCANS, 00670 "MaxNoOfConcurrentScans", 00671 DB_TOKEN, 00672 "Max number of scans executing concurrently on the "DB_TOKEN_PRINT" node", 00673 ConfigInfo::CI_USED, 00674 false, 00675 ConfigInfo::CI_INT, 00676 "256", 00677 "2", 00678 "500" }, 00679 00680 { 00681 CFG_DB_TRANS_BUFFER_MEM, 00682 "TransactionBufferMemory", 00683 DB_TOKEN, 00684 "Dynamic buffer space (in bytes) for key and attribute data allocated for each "DB_TOKEN_PRINT" node", 00685 ConfigInfo::CI_USED, 00686 false, 00687 ConfigInfo::CI_INT, 00688 "1M", 00689 "1K", 00690 STR_VALUE(MAX_INT_RNIL) }, 00691 00692 { 00693 CFG_DB_INDEX_MEM, 00694 "IndexMemory", 00695 DB_TOKEN, 00696 "Number bytes on each "DB_TOKEN_PRINT" node allocated for storing indexes", 00697 ConfigInfo::CI_USED, 00698 false, 00699 ConfigInfo::CI_INT64, 00700 "18M", 00701 "1M", 00702 "1024G" }, 00703 00704 { 00705 CFG_DB_DATA_MEM, 00706 "DataMemory", 00707 DB_TOKEN, 00708 "Number bytes on each "DB_TOKEN_PRINT" node allocated for storing data", 00709 ConfigInfo::CI_USED, 00710 false, 00711 ConfigInfo::CI_INT64, 00712 "80M", 00713 "1M", 00714 "1024G" }, 00715 00716 { 00717 CFG_DB_UNDO_INDEX_BUFFER, 00718 "UndoIndexBuffer", 00719 DB_TOKEN, 00720 "Number bytes on each "DB_TOKEN_PRINT" node allocated for writing UNDO logs for index part", 00721 ConfigInfo::CI_USED, 00722 false, 00723 ConfigInfo::CI_INT, 00724 "2M", 00725 "1M", 00726 STR_VALUE(MAX_INT_RNIL)}, 00727 00728 { 00729 CFG_DB_UNDO_DATA_BUFFER, 00730 "UndoDataBuffer", 00731 DB_TOKEN, 00732 "Number bytes on each "DB_TOKEN_PRINT" node allocated for writing UNDO logs for data part", 00733 ConfigInfo::CI_USED, 00734 false, 00735 ConfigInfo::CI_INT, 00736 "16M", 00737 "1M", 00738 STR_VALUE(MAX_INT_RNIL)}, 00739 00740 { 00741 CFG_DB_REDO_BUFFER, 00742 "RedoBuffer", 00743 DB_TOKEN, 00744 "Number bytes on each "DB_TOKEN_PRINT" node allocated for writing REDO logs", 00745 ConfigInfo::CI_USED, 00746 false, 00747 ConfigInfo::CI_INT, 00748 "8M", 00749 "1M", 00750 STR_VALUE(MAX_INT_RNIL)}, 00751 00752 { 00753 CFG_DB_LONG_SIGNAL_BUFFER, 00754 "LongMessageBuffer", 00755 DB_TOKEN, 00756 "Number bytes on each "DB_TOKEN_PRINT" node allocated for internal long messages", 00757 ConfigInfo::CI_USED, 00758 false, 00759 ConfigInfo::CI_INT, 00760 "1M", 00761 "512k", 00762 STR_VALUE(MAX_INT_RNIL)}, 00763 00764 { 00765 CFG_DB_DISK_PAGE_BUFFER_MEMORY, 00766 "DiskPageBufferMemory", 00767 DB_TOKEN, 00768 "Number bytes on each "DB_TOKEN_PRINT" node allocated for disk page buffer cache", 00769 ConfigInfo::CI_USED, 00770 false, 00771 ConfigInfo::CI_INT64, 00772 "64M", 00773 "4M", 00774 "1024G" }, 00775 00776 { 00777 CFG_DB_SGA, 00778 "SharedGlobalMemory", 00779 DB_TOKEN, 00780 "Total number bytes on each "DB_TOKEN_PRINT" node allocated for any use", 00781 ConfigInfo::CI_USED, 00782 false, 00783 ConfigInfo::CI_INT64, 00784 "20M", 00785 "0", 00786 "65536G" }, // 32k pages * 32-bit i value 00787 00788 { 00789 CFG_DB_START_PARTIAL_TIMEOUT, 00790 "StartPartialTimeout", 00791 DB_TOKEN, 00792 "Time to wait before trying to start wo/ all nodes. 0=Wait forever", 00793 ConfigInfo::CI_USED, 00794 true, 00795 ConfigInfo::CI_INT, 00796 "30000", 00797 "0", 00798 STR_VALUE(MAX_INT_RNIL) }, 00799 00800 { 00801 CFG_DB_START_PARTITION_TIMEOUT, 00802 "StartPartitionedTimeout", 00803 DB_TOKEN, 00804 "Time to wait before trying to start partitioned. 0=Wait forever", 00805 ConfigInfo::CI_USED, 00806 true, 00807 ConfigInfo::CI_INT, 00808 "60000", 00809 "0", 00810 STR_VALUE(MAX_INT_RNIL) }, 00811 00812 { 00813 CFG_DB_START_FAILURE_TIMEOUT, 00814 "StartFailureTimeout", 00815 DB_TOKEN, 00816 "Time to wait before terminating. 0=Wait forever", 00817 ConfigInfo::CI_USED, 00818 true, 00819 ConfigInfo::CI_INT, 00820 "0", 00821 "0", 00822 STR_VALUE(MAX_INT_RNIL) }, 00823 00824 { 00825 CFG_DB_HEARTBEAT_INTERVAL, 00826 "HeartbeatIntervalDbDb", 00827 DB_TOKEN, 00828 "Time between "DB_TOKEN_PRINT"-"DB_TOKEN_PRINT" heartbeats. "DB_TOKEN_PRINT" considered dead after 3 missed HBs", 00829 ConfigInfo::CI_USED, 00830 true, 00831 ConfigInfo::CI_INT, 00832 "1500", 00833 "10", 00834 STR_VALUE(MAX_INT_RNIL) }, 00835 00836 { 00837 CFG_DB_API_HEARTBEAT_INTERVAL, 00838 "HeartbeatIntervalDbApi", 00839 DB_TOKEN, 00840 "Time between "API_TOKEN_PRINT"-"DB_TOKEN_PRINT" heartbeats. "API_TOKEN_PRINT" connection closed after 3 missed HBs", 00841 ConfigInfo::CI_USED, 00842 true, 00843 ConfigInfo::CI_INT, 00844 "1500", 00845 "100", 00846 STR_VALUE(MAX_INT_RNIL) }, 00847 00848 { 00849 CFG_DB_LCP_INTERVAL, 00850 "TimeBetweenLocalCheckpoints", 00851 DB_TOKEN, 00852 "Time between taking snapshots of the database (expressed in 2log of bytes)", 00853 ConfigInfo::CI_USED, 00854 true, 00855 ConfigInfo::CI_INT, 00856 "20", 00857 "0", 00858 "31" }, 00859 00860 { 00861 CFG_DB_GCP_INTERVAL, 00862 "TimeBetweenGlobalCheckpoints", 00863 DB_TOKEN, 00864 "Time between doing group commit of transactions to disk", 00865 ConfigInfo::CI_USED, 00866 true, 00867 ConfigInfo::CI_INT, 00868 "2000", 00869 "10", 00870 "32000" }, 00871 00872 { 00873 CFG_DB_NO_REDOLOG_FILES, 00874 "NoOfFragmentLogFiles", 00875 DB_TOKEN, 00876 "No of 16 Mbyte Redo log files in each of 4 file sets belonging to "DB_TOKEN_PRINT" node", 00877 ConfigInfo::CI_USED, 00878 false, 00879 ConfigInfo::CI_INT, 00880 "8", 00881 "3", 00882 STR_VALUE(MAX_INT_RNIL) }, 00883 00884 { 00885 CFG_DB_MAX_OPEN_FILES, 00886 "MaxNoOfOpenFiles", 00887 DB_TOKEN, 00888 "Max number of files open per "DB_TOKEN_PRINT" node.(One thread is created per file)", 00889 ConfigInfo::CI_USED, 00890 false, 00891 ConfigInfo::CI_INT, 00892 "40", 00893 "20", 00894 STR_VALUE(MAX_INT_RNIL) }, 00895 00896 { 00897 CFG_DB_INITIAL_OPEN_FILES, 00898 "InitialNoOfOpenFiles", 00899 DB_TOKEN, 00900 "Initial number of files open per "DB_TOKEN_PRINT" node.(One thread is created per file)", 00901 ConfigInfo::CI_USED, 00902 false, 00903 ConfigInfo::CI_INT, 00904 "27", 00905 "20", 00906 STR_VALUE(MAX_INT_RNIL) }, 00907 00908 { 00909 CFG_DB_TRANSACTION_CHECK_INTERVAL, 00910 "TimeBetweenInactiveTransactionAbortCheck", 00911 DB_TOKEN, 00912 "Time between inactive transaction checks", 00913 ConfigInfo::CI_USED, 00914 true, 00915 ConfigInfo::CI_INT, 00916 "1000", 00917 "1000", 00918 STR_VALUE(MAX_INT_RNIL) }, 00919 00920 { 00921 CFG_DB_TRANSACTION_INACTIVE_TIMEOUT, 00922 "TransactionInactiveTimeout", 00923 DB_TOKEN, 00924 "Time application can wait before executing another transaction part (ms).\n" 00925 "This is the time the transaction coordinator waits for the application\n" 00926 "to execute or send another part (query, statement) of the transaction.\n" 00927 "If the application takes too long time, the transaction gets aborted.\n" 00928 "Timeout set to 0 means that we don't timeout at all on application wait.", 00929 ConfigInfo::CI_USED, 00930 true, 00931 ConfigInfo::CI_INT, 00932 STR_VALUE(MAX_INT_RNIL), 00933 "0", 00934 STR_VALUE(MAX_INT_RNIL) }, 00935 00936 { 00937 CFG_DB_TRANSACTION_DEADLOCK_TIMEOUT, 00938 "TransactionDeadlockDetectionTimeout", 00939 DB_TOKEN, 00940 "Time transaction can be executing in a DB node (ms).\n" 00941 "This is the time the transaction coordinator waits for each database node\n" 00942 "of the transaction to execute a request. If the database node takes too\n" 00943 "long time, the transaction gets aborted.", 00944 ConfigInfo::CI_USED, 00945 true, 00946 ConfigInfo::CI_INT, 00947 "1200", 00948 "50", 00949 STR_VALUE(MAX_INT_RNIL) }, 00950 00951 { 00952 CFG_DB_LCP_DISC_PAGES_TUP_SR, 00953 "NoOfDiskPagesToDiskDuringRestartTUP", 00954 DB_TOKEN, 00955 "?", 00956 ConfigInfo::CI_USED, 00957 true, 00958 ConfigInfo::CI_INT, 00959 "40", 00960 "1", 00961 STR_VALUE(MAX_INT_RNIL) }, 00962 00963 { 00964 CFG_DB_LCP_DISC_PAGES_TUP, 00965 "NoOfDiskPagesToDiskAfterRestartTUP", 00966 DB_TOKEN, 00967 "?", 00968 ConfigInfo::CI_USED, 00969 true, 00970 ConfigInfo::CI_INT, 00971 "40", 00972 "1", 00973 STR_VALUE(MAX_INT_RNIL) }, 00974 00975 { 00976 CFG_DB_LCP_DISC_PAGES_ACC_SR, 00977 "NoOfDiskPagesToDiskDuringRestartACC", 00978 DB_TOKEN, 00979 "?", 00980 ConfigInfo::CI_USED, 00981 true, 00982 ConfigInfo::CI_INT, 00983 "20", 00984 "1", 00985 STR_VALUE(MAX_INT_RNIL) }, 00986 00987 { 00988 CFG_DB_LCP_DISC_PAGES_ACC, 00989 "NoOfDiskPagesToDiskAfterRestartACC", 00990 DB_TOKEN, 00991 "?", 00992 ConfigInfo::CI_USED, 00993 true, 00994 ConfigInfo::CI_INT, 00995 "20", 00996 "1", 00997 STR_VALUE(MAX_INT_RNIL) }, 00998 00999 01000 { 01001 CFG_DB_DISCLESS, 01002 "Diskless", 01003 DB_TOKEN, 01004 "Run wo/ disk", 01005 ConfigInfo::CI_USED, 01006 true, 01007 ConfigInfo::CI_BOOL, 01008 "false", 01009 "false", 01010 "true"}, 01011 01012 { 01013 KEY_INTERNAL, 01014 "Discless", 01015 DB_TOKEN, 01016 "Diskless", 01017 ConfigInfo::CI_DEPRICATED, 01018 true, 01019 ConfigInfo::CI_BOOL, 01020 "false", 01021 "false", 01022 "true"}, 01023 01024 01025 01026 { 01027 CFG_DB_ARBIT_TIMEOUT, 01028 "ArbitrationTimeout", 01029 DB_TOKEN, 01030 "Max time (milliseconds) database partion waits for arbitration signal", 01031 ConfigInfo::CI_USED, 01032 false, 01033 ConfigInfo::CI_INT, 01034 "3000", 01035 "10", 01036 STR_VALUE(MAX_INT_RNIL) }, 01037 01038 { 01039 CFG_NODE_DATADIR, 01040 "DataDir", 01041 DB_TOKEN, 01042 "Data directory for this node", 01043 ConfigInfo::CI_USED, 01044 false, 01045 ConfigInfo::CI_STRING, 01046 MYSQLCLUSTERDIR, 01047 0, 0 }, 01048 01049 { 01050 CFG_DB_FILESYSTEM_PATH, 01051 "FileSystemPath", 01052 DB_TOKEN, 01053 "Path to directory where the "DB_TOKEN_PRINT" node stores its data (directory must exist)", 01054 ConfigInfo::CI_USED, 01055 false, 01056 ConfigInfo::CI_STRING, 01057 UNDEFINED, 01058 0, 0 }, 01059 01060 { 01061 CFG_LOGLEVEL_STARTUP, 01062 "LogLevelStartup", 01063 DB_TOKEN, 01064 "Node startup info printed on stdout", 01065 ConfigInfo::CI_USED, 01066 false, 01067 ConfigInfo::CI_INT, 01068 "1", 01069 "0", 01070 "15" }, 01071 01072 { 01073 CFG_LOGLEVEL_SHUTDOWN, 01074 "LogLevelShutdown", 01075 DB_TOKEN, 01076 "Node shutdown info printed on stdout", 01077 ConfigInfo::CI_USED, 01078 false, 01079 ConfigInfo::CI_INT, 01080 "0", 01081 "0", 01082 "15" }, 01083 01084 { 01085 CFG_LOGLEVEL_STATISTICS, 01086 "LogLevelStatistic", 01087 DB_TOKEN, 01088 "Transaction, operation, transporter info printed on stdout", 01089 ConfigInfo::CI_USED, 01090 false, 01091 ConfigInfo::CI_INT, 01092 "0", 01093 "0", 01094 "15" }, 01095 01096 { 01097 CFG_LOGLEVEL_CHECKPOINT, 01098 "LogLevelCheckpoint", 01099 DB_TOKEN, 01100 "Local and Global checkpoint info printed on stdout", 01101 ConfigInfo::CI_USED, 01102 false, 01103 ConfigInfo::CI_INT, 01104 "0", 01105 "0", 01106 "15" }, 01107 01108 { 01109 CFG_LOGLEVEL_NODERESTART, 01110 "LogLevelNodeRestart", 01111 DB_TOKEN, 01112 "Node restart, node failure info printed on stdout", 01113 ConfigInfo::CI_USED, 01114 false, 01115 ConfigInfo::CI_INT, 01116 "0", 01117 "0", 01118 "15" }, 01119 01120 { 01121 CFG_LOGLEVEL_CONNECTION, 01122 "LogLevelConnection", 01123 DB_TOKEN, 01124 "Node connect/disconnect info printed on stdout", 01125 ConfigInfo::CI_USED, 01126 false, 01127 ConfigInfo::CI_INT, 01128 "0", 01129 "0", 01130 "15" }, 01131 01132 { 01133 CFG_LOGLEVEL_CONGESTION, 01134 "LogLevelCongestion", 01135 DB_TOKEN, 01136 "Congestion info printed on stdout", 01137 ConfigInfo::CI_USED, 01138 false, 01139 ConfigInfo::CI_INT, 01140 "0", 01141 "0", 01142 "15" }, 01143 01144 { 01145 CFG_LOGLEVEL_ERROR, 01146 "LogLevelError", 01147 DB_TOKEN, 01148 "Transporter, heartbeat errors printed on stdout", 01149 ConfigInfo::CI_USED, 01150 false, 01151 ConfigInfo::CI_INT, 01152 "0", 01153 "0", 01154 "15" }, 01155 01156 { 01157 CFG_LOGLEVEL_INFO, 01158 "LogLevelInfo", 01159 DB_TOKEN, 01160 "Heartbeat and log info printed on stdout", 01161 ConfigInfo::CI_USED, 01162 false, 01163 ConfigInfo::CI_INT, 01164 "0", 01165 "0", 01166 "15" }, 01167 01171 { 01172 CFG_DB_PARALLEL_BACKUPS, 01173 "ParallelBackups", 01174 DB_TOKEN, 01175 "Maximum number of parallel backups", 01176 ConfigInfo::CI_NOTIMPLEMENTED, 01177 false, 01178 ConfigInfo::CI_INT, 01179 "1", 01180 "1", 01181 "1" }, 01182 01183 { 01184 CFG_DB_BACKUP_DATADIR, 01185 "BackupDataDir", 01186 DB_TOKEN, 01187 "Path to where to store backups", 01188 ConfigInfo::CI_USED, 01189 false, 01190 ConfigInfo::CI_STRING, 01191 UNDEFINED, 01192 0, 0 }, 01193 01194 { 01195 CFG_DB_BACKUP_MEM, 01196 "BackupMemory", 01197 DB_TOKEN, 01198 "Total memory allocated for backups per node (in bytes)", 01199 ConfigInfo::CI_USED, 01200 false, 01201 ConfigInfo::CI_INT, 01202 "4M", // sum of BackupDataBufferSize and BackupLogBufferSize 01203 "0", 01204 STR_VALUE(MAX_INT_RNIL) }, 01205 01206 { 01207 CFG_DB_BACKUP_DATA_BUFFER_MEM, 01208 "BackupDataBufferSize", 01209 DB_TOKEN, 01210 "Default size of databuffer for a backup (in bytes)", 01211 ConfigInfo::CI_USED, 01212 false, 01213 ConfigInfo::CI_INT, 01214 "2M", // remember to change BackupMemory 01215 "0", 01216 STR_VALUE(MAX_INT_RNIL) }, 01217 01218 { 01219 CFG_DB_BACKUP_LOG_BUFFER_MEM, 01220 "BackupLogBufferSize", 01221 DB_TOKEN, 01222 "Default size of logbuffer for a backup (in bytes)", 01223 ConfigInfo::CI_USED, 01224 false, 01225 ConfigInfo::CI_INT, 01226 "2M", // remember to change BackupMemory 01227 "0", 01228 STR_VALUE(MAX_INT_RNIL) }, 01229 01230 { 01231 CFG_DB_BACKUP_WRITE_SIZE, 01232 "BackupWriteSize", 01233 DB_TOKEN, 01234 "Default size of filesystem writes made by backup (in bytes)", 01235 ConfigInfo::CI_USED, 01236 false, 01237 ConfigInfo::CI_INT, 01238 "32K", 01239 "2K", 01240 STR_VALUE(MAX_INT_RNIL) }, 01241 01242 { 01243 CFG_DB_BACKUP_MAX_WRITE_SIZE, 01244 "BackupMaxWriteSize", 01245 DB_TOKEN, 01246 "Max size of filesystem writes made by backup (in bytes)", 01247 ConfigInfo::CI_USED, 01248 false, 01249 ConfigInfo::CI_INT, 01250 "256K", 01251 "2K", 01252 STR_VALUE(MAX_INT_RNIL) }, 01253 01254 { 01255 CFG_DB_STRING_MEMORY, 01256 "StringMemory", 01257 DB_TOKEN, 01258 "Default size of string memory (0 -> 5% of max 1-100 -> %of max, >100 -> actual bytes)", 01259 ConfigInfo::CI_USED, 01260 false, 01261 ConfigInfo::CI_INT, 01262 "0", 01263 "0", 01264 STR_VALUE(MAX_INT_RNIL) }, 01265 01266 /*************************************************************************** 01267 * API 01268 ***************************************************************************/ 01269 { 01270 CFG_SECTION_NODE, 01271 API_TOKEN, 01272 API_TOKEN, 01273 "Node section", 01274 ConfigInfo::CI_USED, 01275 false, 01276 ConfigInfo::CI_SECTION, 01277 (const char *)NODE_TYPE_API, 01278 0, 0 01279 }, 01280 01281 { 01282 CFG_NODE_HOST, 01283 "HostName", 01284 API_TOKEN, 01285 "Name of computer for this node", 01286 ConfigInfo::CI_INTERNAL, 01287 false, 01288 ConfigInfo::CI_STRING, 01289 "", 01290 0, 0 }, 01291 01292 { 01293 CFG_NODE_SYSTEM, 01294 "System", 01295 API_TOKEN, 01296 "Name of system for this node", 01297 ConfigInfo::CI_INTERNAL, 01298 false, 01299 ConfigInfo::CI_STRING, 01300 UNDEFINED, 01301 0, 0 }, 01302 01303 { 01304 KEY_INTERNAL, 01305 "Id", 01306 API_TOKEN, 01307 "", 01308 ConfigInfo::CI_DEPRICATED, 01309 false, 01310 ConfigInfo::CI_INT, 01311 MANDATORY, 01312 "1", 01313 STR_VALUE(MAX_NODES) }, 01314 01315 { 01316 CFG_NODE_ID, 01317 "NodeId", 01318 API_TOKEN, 01319 "Number identifying application node ("API_TOKEN_PRINT")", 01320 ConfigInfo::CI_USED, 01321 false, 01322 ConfigInfo::CI_INT, 01323 MANDATORY, 01324 "1", 01325 STR_VALUE(MAX_NODES) }, 01326 01327 { 01328 KEY_INTERNAL, 01329 "ExecuteOnComputer", 01330 API_TOKEN, 01331 "String referencing an earlier defined COMPUTER", 01332 ConfigInfo::CI_USED, 01333 false, 01334 ConfigInfo::CI_STRING, 01335 UNDEFINED, 01336 0, 0 }, 01337 01338 { 01339 CFG_NODE_ARBIT_RANK, 01340 "ArbitrationRank", 01341 API_TOKEN, 01342 "If 0, then "API_TOKEN_PRINT" is not arbitrator. Kernel selects arbitrators in order 1, 2", 01343 ConfigInfo::CI_USED, 01344 false, 01345 ConfigInfo::CI_INT, 01346 "0", 01347 "0", 01348 "2" }, 01349 01350 { 01351 CFG_NODE_ARBIT_DELAY, 01352 "ArbitrationDelay", 01353 API_TOKEN, 01354 "When asked to arbitrate, arbitrator waits this long before voting (msec)", 01355 ConfigInfo::CI_USED, 01356 false, 01357 ConfigInfo::CI_INT, 01358 "0", 01359 "0", 01360 STR_VALUE(MAX_INT_RNIL) }, 01361 01362 { 01363 CFG_MAX_SCAN_BATCH_SIZE, 01364 "MaxScanBatchSize", 01365 "API", 01366 "The maximum collective batch size for one scan", 01367 ConfigInfo::CI_USED, 01368 false, 01369 ConfigInfo::CI_INT, 01370 STR_VALUE(MAX_SCAN_BATCH_SIZE), 01371 "32k", 01372 "16M" }, 01373 01374 { 01375 CFG_BATCH_BYTE_SIZE, 01376 "BatchByteSize", 01377 "API", 01378 "The default batch size in bytes", 01379 ConfigInfo::CI_USED, 01380 false, 01381 ConfigInfo::CI_INT, 01382 STR_VALUE(SCAN_BATCH_SIZE), 01383 "1k", 01384 "1M" }, 01385 01386 { 01387 CFG_BATCH_SIZE, 01388 "BatchSize", 01389 "API", 01390 "The default batch size in number of records", 01391 ConfigInfo::CI_USED, 01392 false, 01393 ConfigInfo::CI_INT, 01394 STR_VALUE(DEF_BATCH_SIZE), 01395 "1", 01396 STR_VALUE(MAX_PARALLEL_OP_PER_SCAN) }, 01397 01398 /**************************************************************************** 01399 * MGM 01400 ***************************************************************************/ 01401 { 01402 CFG_SECTION_NODE, 01403 MGM_TOKEN, 01404 MGM_TOKEN, 01405 "Node section", 01406 ConfigInfo::CI_USED, 01407 false, 01408 ConfigInfo::CI_SECTION, 01409 (const char *)NODE_TYPE_MGM, 01410 0, 0 01411 }, 01412 01413 { 01414 CFG_NODE_HOST, 01415 "HostName", 01416 MGM_TOKEN, 01417 "Name of computer for this node", 01418 ConfigInfo::CI_INTERNAL, 01419 false, 01420 ConfigInfo::CI_STRING, 01421 "", 01422 0, 0 }, 01423 01424 { 01425 CFG_NODE_DATADIR, 01426 "DataDir", 01427 MGM_TOKEN, 01428 "Data directory for this node", 01429 ConfigInfo::CI_USED, 01430 false, 01431 ConfigInfo::CI_STRING, 01432 MYSQLCLUSTERDIR, 01433 0, 0 }, 01434 01435 { 01436 CFG_NODE_SYSTEM, 01437 "System", 01438 MGM_TOKEN, 01439 "Name of system for this node", 01440 ConfigInfo::CI_INTERNAL, 01441 false, 01442 ConfigInfo::CI_STRING, 01443 UNDEFINED, 01444 0, 0 }, 01445 01446 { 01447 KEY_INTERNAL, 01448 "Id", 01449 MGM_TOKEN, 01450 "", 01451 ConfigInfo::CI_DEPRICATED, 01452 false, 01453 ConfigInfo::CI_INT, 01454 MANDATORY, 01455 "1", 01456 STR_VALUE(MAX_NODES) }, 01457 01458 { 01459 CFG_NODE_ID, 01460 "NodeId", 01461 MGM_TOKEN, 01462 "Number identifying the management server node ("MGM_TOKEN_PRINT")", 01463 ConfigInfo::CI_USED, 01464 false, 01465 ConfigInfo::CI_INT, 01466 MANDATORY, 01467 "1", 01468 STR_VALUE(MAX_NODES) }, 01469 01470 { 01471 CFG_LOG_DESTINATION, 01472 "LogDestination", 01473 MGM_TOKEN, 01474 "String describing where logmessages are sent", 01475 ConfigInfo::CI_USED, 01476 false, 01477 ConfigInfo::CI_STRING, 01478 0, 01479 0, 0 }, 01480 01481 { 01482 KEY_INTERNAL, 01483 "ExecuteOnComputer", 01484 MGM_TOKEN, 01485 "String referencing an earlier defined COMPUTER", 01486 ConfigInfo::CI_USED, 01487 false, 01488 ConfigInfo::CI_STRING, 01489 0, 01490 0, 0 }, 01491 01492 { 01493 KEY_INTERNAL, 01494 "MaxNoOfSavedEvents", 01495 MGM_TOKEN, 01496 "", 01497 ConfigInfo::CI_USED, 01498 false, 01499 ConfigInfo::CI_INT, 01500 "100", 01501 "0", 01502 STR_VALUE(MAX_INT_RNIL) }, 01503 01504 { 01505 CFG_MGM_PORT, 01506 "PortNumber", 01507 MGM_TOKEN, 01508 "Port number to give commands to/fetch configurations from management server", 01509 ConfigInfo::CI_USED, 01510 false, 01511 ConfigInfo::CI_INT, 01512 NDB_PORT, 01513 "0", 01514 STR_VALUE(MAX_PORT_NO) }, 01515 01516 { 01517 KEY_INTERNAL, 01518 "PortNumberStats", 01519 MGM_TOKEN, 01520 "Port number used to get statistical information from a management server", 01521 ConfigInfo::CI_USED, 01522 false, 01523 ConfigInfo::CI_INT, 01524 UNDEFINED, 01525 "0", 01526 STR_VALUE(MAX_PORT_NO) }, 01527 01528 { 01529 CFG_NODE_ARBIT_RANK, 01530 "ArbitrationRank", 01531 MGM_TOKEN, 01532 "If 0, then "MGM_TOKEN_PRINT" is not arbitrator. Kernel selects arbitrators in order 1, 2", 01533 ConfigInfo::CI_USED, 01534 false, 01535 ConfigInfo::CI_INT, 01536 "1", 01537 "0", 01538 "2" }, 01539 01540 { 01541 CFG_NODE_ARBIT_DELAY, 01542 "ArbitrationDelay", 01543 MGM_TOKEN, 01544 "", 01545 ConfigInfo::CI_USED, 01546 false, 01547 ConfigInfo::CI_INT, 01548 "0", 01549 "0", 01550 STR_VALUE(MAX_INT_RNIL) }, 01551 01552 /**************************************************************************** 01553 * TCP 01554 ***************************************************************************/ 01555 { 01556 CFG_SECTION_CONNECTION, 01557 "TCP", 01558 "TCP", 01559 "Connection section", 01560 ConfigInfo::CI_USED, 01561 false, 01562 ConfigInfo::CI_SECTION, 01563 (const char *)CONNECTION_TYPE_TCP, 01564 0, 0 01565 }, 01566 01567 { 01568 CFG_CONNECTION_HOSTNAME_1, 01569 "HostName1", 01570 "TCP", 01571 "Name/IP of computer on one side of the connection", 01572 ConfigInfo::CI_INTERNAL, 01573 false, 01574 ConfigInfo::CI_STRING, 01575 UNDEFINED, 01576 0, 0 }, 01577 01578 { 01579 CFG_CONNECTION_HOSTNAME_2, 01580 "HostName2", 01581 "TCP", 01582 "Name/IP of computer on one side of the connection", 01583 ConfigInfo::CI_INTERNAL, 01584 false, 01585 ConfigInfo::CI_STRING, 01586 UNDEFINED, 01587 0, 0 }, 01588 01589 { 01590 CFG_CONNECTION_NODE_1, 01591 "NodeId1", 01592 "TCP", 01593 "Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection", 01594 ConfigInfo::CI_USED, 01595 false, 01596 ConfigInfo::CI_STRING, 01597 MANDATORY, 01598 0, 0 }, 01599 01600 { 01601 CFG_CONNECTION_NODE_2, 01602 "NodeId2", 01603 "TCP", 01604 "Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection", 01605 ConfigInfo::CI_USED, 01606 false, 01607 ConfigInfo::CI_STRING, 01608 MANDATORY, 01609 0, 0 }, 01610 01611 { 01612 CFG_CONNECTION_GROUP, 01613 "Group", 01614 "TCP", 01615 "", 01616 ConfigInfo::CI_USED, 01617 false, 01618 ConfigInfo::CI_INT, 01619 "55", 01620 "0", "200" }, 01621 01622 { 01623 CFG_CONNECTION_NODE_ID_SERVER, 01624 "NodeIdServer", 01625 "TCP", 01626 "", 01627 ConfigInfo::CI_USED, 01628 false, 01629 ConfigInfo::CI_INT, 01630 MANDATORY, 01631 "1", "63" }, 01632 01633 { 01634 CFG_CONNECTION_SEND_SIGNAL_ID, 01635 "SendSignalId", 01636 "TCP", 01637 "Sends id in each signal. Used in trace files.", 01638 ConfigInfo::CI_USED, 01639 false, 01640 ConfigInfo::CI_BOOL, 01641 "true", 01642 "false", 01643 "true" }, 01644 01645 01646 { 01647 CFG_CONNECTION_CHECKSUM, 01648 "Checksum", 01649 "TCP", 01650 "If checksum is enabled, all signals between nodes are checked for errors", 01651 ConfigInfo::CI_USED, 01652 false, 01653 ConfigInfo::CI_BOOL, 01654 "false", 01655 "false", 01656 "true" }, 01657 01658 { 01659 CFG_CONNECTION_SERVER_PORT, 01660 "PortNumber", 01661 "TCP", 01662 "Port used for this transporter", 01663 ConfigInfo::CI_USED, 01664 false, 01665 ConfigInfo::CI_INT, 01666 MANDATORY, 01667 "0", 01668 STR_VALUE(MAX_PORT_NO) }, 01669 01670 { 01671 CFG_TCP_SEND_BUFFER_SIZE, 01672 "SendBufferMemory", 01673 "TCP", 01674 "Bytes of buffer for signals sent from this node", 01675 ConfigInfo::CI_USED, 01676 false, 01677 ConfigInfo::CI_INT, 01678 "256K", 01679 "64K", 01680 STR_VALUE(MAX_INT_RNIL) }, 01681 01682 { 01683 CFG_TCP_RECEIVE_BUFFER_SIZE, 01684 "ReceiveBufferMemory", 01685 "TCP", 01686 "Bytes of buffer for signals received by this node", 01687 ConfigInfo::CI_USED, 01688 false, 01689 ConfigInfo::CI_INT, 01690 "64K", 01691 "16K", 01692 STR_VALUE(MAX_INT_RNIL) }, 01693 01694 { 01695 CFG_TCP_PROXY, 01696 "Proxy", 01697 "TCP", 01698 "", 01699 ConfigInfo::CI_USED, 01700 false, 01701 ConfigInfo::CI_STRING, 01702 UNDEFINED, 01703 0, 0 }, 01704 01705 { 01706 CFG_CONNECTION_NODE_1_SYSTEM, 01707 "NodeId1_System", 01708 "TCP", 01709 "System for node 1 in connection", 01710 ConfigInfo::CI_INTERNAL, 01711 false, 01712 ConfigInfo::CI_STRING, 01713 UNDEFINED, 01714 0, 0 }, 01715 01716 { 01717 CFG_CONNECTION_NODE_2_SYSTEM, 01718 "NodeId2_System", 01719 "TCP", 01720 "System for node 2 in connection", 01721 ConfigInfo::CI_INTERNAL, 01722 false, 01723 ConfigInfo::CI_STRING, 01724 UNDEFINED, 01725 0, 0 }, 01726 01727 01728 /**************************************************************************** 01729 * SHM 01730 ***************************************************************************/ 01731 { 01732 CFG_SECTION_CONNECTION, 01733 "SHM", 01734 "SHM", 01735 "Connection section", 01736 ConfigInfo::CI_USED, 01737 false, 01738 ConfigInfo::CI_SECTION, 01739 (const char *)CONNECTION_TYPE_SHM, 01740 0, 0 }, 01741 01742 { 01743 CFG_CONNECTION_HOSTNAME_1, 01744 "HostName1", 01745 "SHM", 01746 "Name/IP of computer on one side of the connection", 01747 ConfigInfo::CI_INTERNAL, 01748 false, 01749 ConfigInfo::CI_STRING, 01750 UNDEFINED, 01751 0, 0 }, 01752 01753 { 01754 CFG_CONNECTION_HOSTNAME_2, 01755 "HostName2", 01756 "SHM", 01757 "Name/IP of computer on one side of the connection", 01758 ConfigInfo::CI_INTERNAL, 01759 false, 01760 ConfigInfo::CI_STRING, 01761 UNDEFINED, 01762 0, 0 }, 01763 01764 { 01765 CFG_CONNECTION_SERVER_PORT, 01766 "PortNumber", 01767 "SHM", 01768 "Port used for this transporter", 01769 ConfigInfo::CI_USED, 01770 false, 01771 ConfigInfo::CI_INT, 01772 MANDATORY, 01773 "0", 01774 STR_VALUE(MAX_PORT_NO) }, 01775 01776 { 01777 CFG_SHM_SIGNUM, 01778 "Signum", 01779 "SHM", 01780 "Signum to be used for signalling", 01781 ConfigInfo::CI_USED, 01782 false, 01783 ConfigInfo::CI_INT, 01784 UNDEFINED, 01785 "0", 01786 STR_VALUE(MAX_INT_RNIL) }, 01787 01788 { 01789 CFG_CONNECTION_NODE_1, 01790 "NodeId1", 01791 "SHM", 01792 "Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection", 01793 ConfigInfo::CI_USED, 01794 false, 01795 ConfigInfo::CI_STRING, 01796 MANDATORY, 01797 0, 0 }, 01798 01799 { 01800 CFG_CONNECTION_NODE_2, 01801 "NodeId2", 01802 "SHM", 01803 "Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection", 01804 ConfigInfo::CI_USED, 01805 false, 01806 ConfigInfo::CI_STRING, 01807 MANDATORY, 01808 0, 0 }, 01809 01810 { 01811 CFG_CONNECTION_GROUP, 01812 "Group", 01813 "SHM", 01814 "", 01815 ConfigInfo::CI_USED, 01816 false, 01817 ConfigInfo::CI_INT, 01818 "35", 01819 "0", "200" }, 01820 01821 { 01822 CFG_CONNECTION_NODE_ID_SERVER, 01823 "NodeIdServer", 01824 "SHM", 01825 "", 01826 ConfigInfo::CI_USED, 01827 false, 01828 ConfigInfo::CI_INT, 01829 MANDATORY, 01830 "1", "63" }, 01831 01832 { 01833 CFG_CONNECTION_SEND_SIGNAL_ID, 01834 "SendSignalId", 01835 "SHM", 01836 "Sends id in each signal. Used in trace files.", 01837 ConfigInfo::CI_USED, 01838 false, 01839 ConfigInfo::CI_BOOL, 01840 "false", 01841 "false", 01842 "true" }, 01843 01844 01845 { 01846 CFG_CONNECTION_CHECKSUM, 01847 "Checksum", 01848 "SHM", 01849 "If checksum is enabled, all signals between nodes are checked for errors", 01850 ConfigInfo::CI_USED, 01851 false, 01852 ConfigInfo::CI_BOOL, 01853 "true", 01854 "false", 01855 "true" }, 01856 01857 { 01858 CFG_SHM_KEY, 01859 "ShmKey", 01860 "SHM", 01861 "A shared memory key", 01862 ConfigInfo::CI_USED, 01863 false, 01864 ConfigInfo::CI_INT, 01865 UNDEFINED, 01866 "0", 01867 STR_VALUE(MAX_INT_RNIL) }, 01868 01869 { 01870 CFG_SHM_BUFFER_MEM, 01871 "ShmSize", 01872 "SHM", 01873 "Size of shared memory segment", 01874 ConfigInfo::CI_USED, 01875 false, 01876 ConfigInfo::CI_INT, 01877 "1M", 01878 "64K", 01879 STR_VALUE(MAX_INT_RNIL) }, 01880 01881 { 01882 CFG_CONNECTION_NODE_1_SYSTEM, 01883 "NodeId1_System", 01884 "SHM", 01885 "System for node 1 in connection", 01886 ConfigInfo::CI_INTERNAL, 01887 false, 01888 ConfigInfo::CI_STRING, 01889 UNDEFINED, 01890 0, 0 }, 01891 01892 { 01893 CFG_CONNECTION_NODE_2_SYSTEM, 01894 "NodeId2_System", 01895 "SHM", 01896 "System for node 2 in connection", 01897 ConfigInfo::CI_INTERNAL, 01898 false, 01899 ConfigInfo::CI_STRING, 01900 UNDEFINED, 01901 0, 0 }, 01902 01903 /**************************************************************************** 01904 * SCI 01905 ***************************************************************************/ 01906 { 01907 CFG_SECTION_CONNECTION, 01908 "SCI", 01909 "SCI", 01910 "Connection section", 01911 ConfigInfo::CI_USED, 01912 false, 01913 ConfigInfo::CI_SECTION, 01914 (const char *)CONNECTION_TYPE_SCI, 01915 0, 0 01916 }, 01917 01918 { 01919 CFG_CONNECTION_NODE_1, 01920 "NodeId1", 01921 "SCI", 01922 "Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection", 01923 ConfigInfo::CI_USED, 01924 false, 01925 ConfigInfo::CI_STRING, 01926 MANDATORY, 01927 "0", 01928 STR_VALUE(MAX_INT_RNIL) }, 01929 01930 { 01931 CFG_CONNECTION_NODE_2, 01932 "NodeId2", 01933 "SCI", 01934 "Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection", 01935 ConfigInfo::CI_USED, 01936 false, 01937 ConfigInfo::CI_STRING, 01938 MANDATORY, 01939 "0", 01940 STR_VALUE(MAX_INT_RNIL) }, 01941 01942 { 01943 CFG_CONNECTION_GROUP, 01944 "Group", 01945 "SCI", 01946 "", 01947 ConfigInfo::CI_USED, 01948 false, 01949 ConfigInfo::CI_INT, 01950 "15", 01951 "0", "200" }, 01952 01953 { 01954 CFG_CONNECTION_NODE_ID_SERVER, 01955 "NodeIdServer", 01956 "SCI", 01957 "", 01958 ConfigInfo::CI_USED, 01959 false, 01960 ConfigInfo::CI_INT, 01961 MANDATORY, 01962 "1", "63" }, 01963 01964 { 01965 CFG_CONNECTION_HOSTNAME_1, 01966 "HostName1", 01967 "SCI", 01968 "Name/IP of computer on one side of the connection", 01969 ConfigInfo::CI_INTERNAL, 01970 false, 01971 ConfigInfo::CI_STRING, 01972 UNDEFINED, 01973 0, 0 }, 01974 01975 { 01976 CFG_CONNECTION_HOSTNAME_2, 01977 "HostName2", 01978 "SCI", 01979 "Name/IP of computer on one side of the connection", 01980 ConfigInfo::CI_INTERNAL, 01981 false, 01982 ConfigInfo::CI_STRING, 01983 UNDEFINED, 01984 0, 0 }, 01985 01986 { 01987 CFG_CONNECTION_SERVER_PORT, 01988 "PortNumber", 01989 "SCI", 01990 "Port used for this transporter", 01991 ConfigInfo::CI_USED, 01992 false, 01993 ConfigInfo::CI_INT, 01994 MANDATORY, 01995 "0", 01996 STR_VALUE(MAX_PORT_NO) }, 01997 01998 { 01999 CFG_SCI_HOST1_ID_0, 02000 "Host1SciId0", 02001 "SCI", 02002 "SCI-node id for adapter 0 on Host1 (a computer can have two adapters)", 02003 ConfigInfo::CI_USED, 02004 false, 02005 ConfigInfo::CI_INT, 02006 MANDATORY, 02007 "0", 02008 STR_VALUE(MAX_INT_RNIL) }, 02009 02010 { 02011 CFG_SCI_HOST1_ID_1, 02012 "Host1SciId1", 02013 "SCI", 02014 "SCI-node id for adapter 1 on Host1 (a computer can have two adapters)", 02015 ConfigInfo::CI_USED, 02016 false, 02017 ConfigInfo::CI_INT, 02018 "0", 02019 "0", 02020 STR_VALUE(MAX_INT_RNIL) }, 02021 02022 { 02023 CFG_SCI_HOST2_ID_0, 02024 "Host2SciId0", 02025 "SCI", 02026 "SCI-node id for adapter 0 on Host2 (a computer can have two adapters)", 02027 ConfigInfo::CI_USED, 02028 false, 02029 ConfigInfo::CI_INT, 02030 MANDATORY, 02031 "0", 02032 STR_VALUE(MAX_INT_RNIL) }, 02033 02034 { 02035 CFG_SCI_HOST2_ID_1, 02036 "Host2SciId1", 02037 "SCI", 02038 "SCI-node id for adapter 1 on Host2 (a computer can have two adapters)", 02039 ConfigInfo::CI_USED, 02040 false, 02041 ConfigInfo::CI_INT, 02042 "0", 02043 "0", 02044 STR_VALUE(MAX_INT_RNIL) }, 02045 02046 { 02047 CFG_CONNECTION_SEND_SIGNAL_ID, 02048 "SendSignalId", 02049 "SCI", 02050 "Sends id in each signal. Used in trace files.", 02051 ConfigInfo::CI_USED, 02052 false, 02053 ConfigInfo::CI_BOOL, 02054 "true", 02055 "false", 02056 "true" }, 02057 02058 { 02059 CFG_CONNECTION_CHECKSUM, 02060 "Checksum", 02061 "SCI", 02062 "If checksum is enabled, all signals between nodes are checked for errors", 02063 ConfigInfo::CI_USED, 02064 false, 02065 ConfigInfo::CI_BOOL, 02066 "false", 02067 "false", 02068 "true" }, 02069 02070 { 02071 CFG_SCI_SEND_LIMIT, 02072 "SendLimit", 02073 "SCI", 02074 "Transporter send buffer contents are sent when this no of bytes is buffered", 02075 ConfigInfo::CI_USED, 02076 false, 02077 ConfigInfo::CI_INT, 02078 "8K", 02079 "128", 02080 "32K" }, 02081 02082 { 02083 CFG_SCI_BUFFER_MEM, 02084 "SharedBufferSize", 02085 "SCI", 02086 "Size of shared memory segment", 02087 ConfigInfo::CI_USED, 02088 false, 02089 ConfigInfo::CI_INT, 02090 "1M", 02091 "64K", 02092 STR_VALUE(MAX_INT_RNIL) }, 02093 02094 { 02095 CFG_CONNECTION_NODE_1_SYSTEM, 02096 "NodeId1_System", 02097 "SCI", 02098 "System for node 1 in connection", 02099 ConfigInfo::CI_INTERNAL, 02100 false, 02101 ConfigInfo::CI_STRING, 02102 UNDEFINED, 02103 0, 0 }, 02104 02105 { 02106 CFG_CONNECTION_NODE_2_SYSTEM, 02107 "NodeId2_System", 02108 "SCI", 02109 "System for node 2 in connection", 02110 ConfigInfo::CI_INTERNAL, 02111 false, 02112 ConfigInfo::CI_STRING, 02113 UNDEFINED, 02114 0, 0 }, 02115 02116 /**************************************************************************** 02117 * OSE 02118 ***************************************************************************/ 02119 { 02120 CFG_SECTION_CONNECTION, 02121 "OSE", 02122 "OSE", 02123 "Connection section", 02124 ConfigInfo::CI_USED, 02125 false, 02126 ConfigInfo::CI_SECTION, 02127 (const char *)CONNECTION_TYPE_OSE, 02128 0, 0 02129 }, 02130 02131 { 02132 CFG_CONNECTION_HOSTNAME_1, 02133 "HostName1", 02134 "OSE", 02135 "Name of computer on one side of the connection", 02136 ConfigInfo::CI_USED, 02137 false, 02138 ConfigInfo::CI_STRING, 02139 UNDEFINED, 02140 0, 0 }, 02141 02142 { 02143 CFG_CONNECTION_HOSTNAME_2, 02144 "HostName2", 02145 "OSE", 02146 "Name of computer on one side of the connection", 02147 ConfigInfo::CI_USED, 02148 false, 02149 ConfigInfo::CI_STRING, 02150 UNDEFINED, 02151 0, 0 }, 02152 02153 { 02154 CFG_CONNECTION_NODE_1, 02155 "NodeId1", 02156 "OSE", 02157 "Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection", 02158 ConfigInfo::CI_USED, 02159 false, 02160 ConfigInfo::CI_INT, 02161 MANDATORY, 02162 "0", 02163 STR_VALUE(MAX_INT_RNIL) }, 02164 02165 { 02166 CFG_CONNECTION_NODE_2, 02167 "NodeId2", 02168 "OSE", 02169 "Id of node ("DB_TOKEN_PRINT", "API_TOKEN_PRINT" or "MGM_TOKEN_PRINT") on one side of the connection", 02170 ConfigInfo::CI_USED, 02171 false, 02172 ConfigInfo::CI_INT, 02173 UNDEFINED, 02174 "0", 02175 STR_VALUE(MAX_INT_RNIL) }, 02176 02177 { 02178 CFG_CONNECTION_SEND_SIGNAL_ID, 02179 "SendSignalId", 02180 "OSE", 02181 "Sends id in each signal. Used in trace files.", 02182 ConfigInfo::CI_USED, 02183 false, 02184 ConfigInfo::CI_BOOL, 02185 "true", 02186 "false", 02187 "true" }, 02188 02189 { 02190 CFG_CONNECTION_CHECKSUM, 02191 "Checksum", 02192 "OSE", 02193 "If checksum is enabled, all signals between nodes are checked for errors", 02194 ConfigInfo::CI_USED, 02195 false, 02196 ConfigInfo::CI_BOOL, 02197 "false", 02198 "false", 02199 "true" }, 02200 02201 { 02202 CFG_OSE_PRIO_A_SIZE, 02203 "PrioASignalSize", 02204 "OSE", 02205 "Size of priority A signals (in bytes)", 02206 ConfigInfo::CI_USED, 02207 false, 02208 ConfigInfo::CI_INT, 02209 "1000", 02210 "0", 02211 STR_VALUE(MAX_INT_RNIL) }, 02212 02213 { 02214 CFG_OSE_PRIO_B_SIZE, 02215 "PrioBSignalSize", 02216 "OSE", 02217 "Size of priority B signals (in bytes)", 02218 ConfigInfo::CI_USED, 02219 false, 02220 ConfigInfo::CI_INT, 02221 "1000", 02222 "0", 02223 STR_VALUE(MAX_INT_RNIL) }, 02224 02225 { 02226 CFG_OSE_RECEIVE_ARRAY_SIZE, 02227 "ReceiveArraySize", 02228 "OSE", 02229 "Number of OSE signals checked for correct ordering (in no of OSE signals)", 02230 ConfigInfo::CI_USED, 02231 false, 02232 ConfigInfo::CI_INT, 02233 "10", 02234 "0", 02235 STR_VALUE(MAX_INT_RNIL) }, 02236 02237 { 02238 CFG_CONNECTION_NODE_1_SYSTEM, 02239 "NodeId1_System", 02240 "OSE", 02241 "System for node 1 in connection", 02242 ConfigInfo::CI_INTERNAL, 02243 false, 02244 ConfigInfo::CI_STRING, 02245 UNDEFINED, 02246 0, 0 }, 02247 02248 { 02249 CFG_CONNECTION_NODE_2_SYSTEM, 02250 "NodeId2_System", 02251 "OSE", 02252 "System for node 2 in connection", 02253 ConfigInfo::CI_INTERNAL, 02254 false, 02255 ConfigInfo::CI_STRING, 02256 UNDEFINED, 02257 0, 0 }, 02258 }; 02259 02260 const int ConfigInfo::m_NoOfParams = sizeof(m_ParamInfo) / sizeof(ParamInfo); 02261 02262 02263 /**************************************************************************** 02264 * Ctor 02265 ****************************************************************************/ 02266 static void require(bool v) 02267 { 02268 if(!v) 02269 { 02270 if (opt_core) 02271 abort(); 02272 else 02273 exit(-1); 02274 } 02275 } 02276 02277 ConfigInfo::ConfigInfo() 02278 : m_info(true), m_systemDefaults(true) 02279 { 02280 int i; 02281 Properties *section; 02282 const Properties *oldpinfo; 02283 02284 for (i=0; i<m_NoOfParams; i++) { 02285 const ParamInfo & param = m_ParamInfo[i]; 02286 Uint64 default_uint64; 02287 bool default_bool; 02288 02289 // Create new section if it did not exist 02290 if (!m_info.getCopy(param._section, §ion)) { 02291 Properties newsection(true); 02292 m_info.put(param._section, &newsection); 02293 02294 // Get copy of section 02295 m_info.getCopy(param._section, §ion); 02296 } 02297 02298 // Create pinfo (parameter info) entry 02299 Properties pinfo(true); 02300 pinfo.put("Id", param._paramId); 02301 pinfo.put("Fname", param._fname); 02302 pinfo.put("Description", param._description); 02303 pinfo.put("Updateable", param._updateable); 02304 pinfo.put("Type", param._type); 02305 pinfo.put("Status", param._status); 02306 02307 if(param._default == MANDATORY){ 02308 pinfo.put("Mandatory", (Uint32)1); 02309 } 02310 02311 switch (param._type) { 02312 case CI_BOOL: 02313 { 02314 bool tmp_bool; 02315 require(InitConfigFileParser::convertStringToBool(param._min, tmp_bool)); 02316 pinfo.put64("Min", tmp_bool); 02317 require(InitConfigFileParser::convertStringToBool(param._max, tmp_bool)); 02318 pinfo.put64("Max", tmp_bool); 02319 break; 02320 } 02321 case CI_INT: 02322 case CI_INT64: 02323 { 02324 Uint64 tmp_uint64; 02325 require(InitConfigFileParser::convertStringToUint64(param._min, tmp_uint64)); 02326 pinfo.put64("Min", tmp_uint64); 02327 require(InitConfigFileParser::convertStringToUint64(param._max, tmp_uint64)); 02328 pinfo.put64("Max", tmp_uint64); 02329 break; 02330 } 02331 case CI_SECTION: 02332 pinfo.put("SectionType", (Uint32)UintPtr(param._default)); 02333 break; 02334 case CI_STRING: 02335 break; 02336 } 02337 02338 // Check that pinfo is really new 02339 if (section->get(param._fname, &oldpinfo)) { 02340 ndbout << "Error: Parameter " << param._fname 02341 << " defined twice in section " << param._section 02342 << "." << endl; 02343 require(false); 02344 } 02345 02346 // Add new pinfo to section 02347 section->put(param._fname, &pinfo); 02348 02349 // Replace section with modified section 02350 m_info.put(param._section, section, true); 02351 delete section; 02352 02353 if(param._type != ConfigInfo::CI_SECTION){ 02354 Properties * p; 02355 if(!m_systemDefaults.getCopy(param._section, &p)){ 02356 p = new Properties(true); 02357 } 02358 if(param._default != UNDEFINED && 02359 param._default != MANDATORY){ 02360 switch (param._type) 02361 { 02362 case CI_SECTION: 02363 break; 02364 case CI_STRING: 02365 require(p->put(param._fname, param._default)); 02366 break; 02367 case CI_BOOL: 02368 { 02369 bool tmp_bool; 02370 require(InitConfigFileParser::convertStringToBool(param._default, default_bool)); 02371 require(p->put(param._fname, default_bool)); 02372 break; 02373 } 02374 case CI_INT: 02375 case CI_INT64: 02376 { 02377 Uint64 tmp_uint64; 02378 require(InitConfigFileParser::convertStringToUint64(param._default, default_uint64)); 02379 require(p->put(param._fname, default_uint64)); 02380 break; 02381 } 02382 } 02383 } 02384 require(m_systemDefaults.put(param._section, p, true)); 02385 delete p; 02386 } 02387 } 02388 02389 for (i=0; i<m_NoOfParams; i++) { 02390 if(m_ParamInfo[i]._section == NULL){ 02391 ndbout << "Check that each entry has a section failed." << endl; 02392 ndbout << "Parameter \"" << m_ParamInfo[i]._fname << endl; 02393 ndbout << "Edit file " << __FILE__ << "." << endl; 02394 require(false); 02395 } 02396 02397 if(m_ParamInfo[i]._type == ConfigInfo::CI_SECTION) 02398 continue; 02399 02400 const Properties * p = getInfo(m_ParamInfo[i]._section); 02401 if (!p || !p->contains(m_ParamInfo[i]._fname)) { 02402 ndbout << "Check that each pname has an fname failed." << endl; 02403 ndbout << "Parameter \"" << m_ParamInfo[i]._fname 02404 << "\" does not exist in section \"" 02405 << m_ParamInfo[i]._section << "\"." << endl; 02406 ndbout << "Edit file " << __FILE__ << "." << endl; 02407 require(false); 02408 } 02409 } 02410 } 02411 02412 /**************************************************************************** 02413 * Getters 02414 ****************************************************************************/ 02415 inline void warning(const char * src, const char * arg){ 02416 ndbout << "Illegal call to ConfigInfo::" << src << "() - " << arg << endl; 02417 require(false); 02418 } 02419 02420 const Properties * 02421 ConfigInfo::getInfo(const char * section) const { 02422 const Properties * p; 02423 if(!m_info.get(section, &p)){ 02424 return 0; 02425 // warning("getInfo", section); 02426 } 02427 return p; 02428 } 02429 02430 const Properties * 02431 ConfigInfo::getDefaults(const char * section) const { 02432 const Properties * p; 02433 if(!m_systemDefaults.get(section, &p)){ 02434 return 0; 02435 //warning("getDefaults", section); 02436 } 02437 return p; 02438 } 02439 02440 static 02441 Uint64 02442 getInfoInt(const Properties * section, 02443 const char* fname, const char * type){ 02444 Uint32 val32; 02445 const Properties * p; 02446 if (section->get(fname, &p) && p->get(type, &val32)) { 02447 return val32; 02448 } 02449 02450 Uint64 val64; 02451 if(p && p->get(type, &val64)){ 02452 return val64; 02453 } 02454 02455 section->print(); 02456 if(section->get(fname, &p)){ 02457 p->print(); 02458 } 02459 02460 warning(type, fname); 02461 return 0; 02462 } 02463 02464 static 02465 const char * 02466 getInfoString(const Properties * section, 02467 const char* fname, const char * type){ 02468 const char* val; 02469 const Properties * p; 02470 if (section->get(fname, &p) && p->get(type, &val)) { 02471 return val; 02472 } 02473 warning(type, fname); 02474 return val; 02475 } 02476 02477 Uint64 02478 ConfigInfo::getMax(const Properties * section, const char* fname) const { 02479 return getInfoInt(section, fname, "Max"); 02480 } 02481 02482 Uint64 02483 ConfigInfo::getMin(const Properties * section, const char* fname) const { 02484 return getInfoInt(section, fname, "Min"); 02485 } 02486 02487 Uint64 02488 ConfigInfo::getDefault(const Properties * section, const char* fname) const { 02489 return getInfoInt(section, fname, "Default"); 02490 } 02491 02492 const char* 02493 ConfigInfo::getDescription(const Properties * section, 02494 const char* fname) const { 02495 return getInfoString(section, fname, "Description"); 02496 } 02497 02498 bool 02499 ConfigInfo::isSection(const char * section) const { 02500 for (int i = 0; i<m_noOfSectionNames; i++) { 02501 if(!strcasecmp(section, m_sectionNames[i])) return true; 02502 } 02503 return false; 02504 } 02505 02506 const char* 02507 ConfigInfo::nameToAlias(const char * name) { 02508 for (int i = 0; m_sectionNameAliases[i].name != 0; i++) 02509 if(!strcasecmp(name, m_sectionNameAliases[i].name)) 02510 return m_sectionNameAliases[i].alias; 02511 return 0; 02512 } 02513 02514 const char* 02515 ConfigInfo::getAlias(const char * section) { 02516 for (int i = 0; m_sectionNameAliases[i].name != 0; i++) 02517 if(!strcasecmp(section, m_sectionNameAliases[i].alias)) 02518 return m_sectionNameAliases[i].name; 02519 return 0; 02520 } 02521 02522 bool 02523 ConfigInfo::verify(const Properties * section, const char* fname, 02524 Uint64 value) const { 02525 Uint64 min, max; 02526 02527 min = getInfoInt(section, fname, "Min"); 02528 max = getInfoInt(section, fname, "Max"); 02529 if(min > max){ 02530 warning("verify", fname); 02531 } 02532 if (value >= min && value <= max) 02533 return true; 02534 else 02535 return false; 02536 } 02537 02538 ConfigInfo::Type 02539 ConfigInfo::getType(const Properties * section, const char* fname) const { 02540 return (ConfigInfo::Type) getInfoInt(section, fname, "Type"); 02541 } 02542 02543 ConfigInfo::Status 02544 ConfigInfo::getStatus(const Properties * section, const char* fname) const { 02545 return (ConfigInfo::Status) getInfoInt(section, fname, "Status"); 02546 } 02547 02548 /**************************************************************************** 02549 * Printers 02550 ****************************************************************************/ 02551 02552 void ConfigInfo::print() const { 02553 Properties::Iterator it(&m_info); 02554 for (const char* n = it.first(); n != NULL; n = it.next()) { 02555 print(n); 02556 } 02557 } 02558 02559 void ConfigInfo::print(const char* section) const { 02560 ndbout << "****** " << section << " ******" << endl << endl; 02561 const Properties * sec = getInfo(section); 02562 Properties::Iterator it(sec); 02563 for (const char* n = it.first(); n != NULL; n = it.next()) { 02564 // Skip entries with different F- and P-names 02565 if (getStatus(sec, n) == ConfigInfo::CI_INTERNAL) continue; 02566 if (getStatus(sec, n) == ConfigInfo::CI_DEPRICATED) continue; 02567 if (getStatus(sec, n) == ConfigInfo::CI_NOTIMPLEMENTED) continue; 02568 print(sec, n); 02569 } 02570 } 02571 02572 void ConfigInfo::print(const Properties * section, 02573 const char* parameter) const { 02574 ndbout << parameter; 02575 // ndbout << getDescription(section, parameter) << endl; 02576 switch (getType(section, parameter)) { 02577 case ConfigInfo::CI_BOOL: 02578 ndbout << " (Boolean value)" << endl; 02579 ndbout << getDescription(section, parameter) << endl; 02580 if (getDefault(section, parameter) == false) { 02581 ndbout << "Default: N (Legal values: Y, N)" << endl; 02582 } else if (getDefault(section, parameter) == true) { 02583 ndbout << "Default: Y (Legal values: Y, N)" << endl; 02584 } else if (getDefault(section, parameter) == (UintPtr)MANDATORY) { 02585 ndbout << "MANDATORY (Legal values: Y, N)" << endl; 02586 } else { 02587 ndbout << "UNKNOWN" << endl; 02588 } 02589 ndbout << endl; 02590 break; 02591 02592 case ConfigInfo::CI_INT: 02593 case ConfigInfo::CI_INT64: 02594 ndbout << " (Non-negative Integer)" << endl; 02595 ndbout << getDescription(section, parameter) << endl; 02596 if (getDefault(section, parameter) == (UintPtr)MANDATORY) { 02597 ndbout << "MANDATORY ("; 02598 } else if (getDefault(section, parameter) == (UintPtr)UNDEFINED) { 02599 ndbout << "UNDEFINED ("; 02600 } else { 02601 ndbout << "Default: " << getDefault(section, parameter) << " ("; 02602 } 02603 ndbout << "Min: " << getMin(section, parameter) << ", "; 02604 ndbout << "Max: " << getMax(section, parameter) << ")" << endl; 02605 ndbout << endl; 02606 break; 02607 02608 case ConfigInfo::CI_STRING: 02609 ndbout << " (String)" << endl; 02610 ndbout << getDescription(section, parameter) << endl; 02611 if (getDefault(section, parameter) == (UintPtr)MANDATORY) { 02612 ndbout << "MANDATORY" << endl; 02613 } else { 02614 ndbout << "No default value" << endl; 02615 } 02616 ndbout << endl; 02617 break; 02618 case ConfigInfo::CI_SECTION: 02619 break; 02620 } 02621 } 02622 02623 /**************************************************************************** 02624 * Section Rules 02625 ****************************************************************************/ 02626 02630 bool 02631 transformNode(InitConfigFileParser::Context & ctx, const char * data){ 02632 02633 Uint32 id, line; 02634 if(!ctx.m_currentSection->get("NodeId", &id) && !ctx.m_currentSection->get("Id", &id)){ 02635 Uint32 nextNodeId= 1; 02636 ctx.m_userProperties.get("NextNodeId", &nextNodeId); 02637 id= nextNodeId; 02638 while (ctx.m_userProperties.get("AllocatedNodeId_", id, &line)) 02639 id++; 02640 if (id != nextNodeId) 02641 { 02642 fprintf(stderr,"Cluster configuration warning line %d: " 02643 "Could not use next node id %d for section [%s], " 02644 "using next unused node id %d.\n", 02645 ctx.m_sectionLineno, nextNodeId, ctx.fname, id); 02646 } 02647 ctx.m_currentSection->put("NodeId", id); 02648 } else if(ctx.m_userProperties.get("AllocatedNodeId_", id, &line)) { 02649 ctx.reportError("Duplicate nodeid in section " 02650 "[%s] starting at line: %d. Previously used on line %d.", 02651 ctx.fname, ctx.m_sectionLineno, line); 02652 return false; 02653 } 02654 02655 // next node id _always_ next numbers after last used id 02656 ctx.m_userProperties.put("NextNodeId", id+1, true); 02657 02658 ctx.m_userProperties.put("AllocatedNodeId_", id, ctx.m_sectionLineno); 02659 BaseString::snprintf(ctx.pname, sizeof(ctx.pname), "Node_%d", id); 02660 02661 ctx.m_currentSection->put("Type", ctx.fname); 02662 02663 Uint32 nodes = 0; 02664 ctx.m_userProperties.get("NoOfNodes", &nodes); 02665 ctx.m_userProperties.put("NoOfNodes", ++nodes, true); 02666 02670 nodes = 0; 02671 ctx.m_userProperties.get(ctx.fname, &nodes); 02672 ctx.m_userProperties.put(ctx.fname, ++nodes, true); 02673 02674 return true; 02675 } 02676 02677 static bool checkLocalhostHostnameMix(InitConfigFileParser::Context & ctx, const char * data) 02678 { 02679 DBUG_ENTER("checkLocalhostHostnameMix"); 02680 const char * hostname= 0; 02681 ctx.m_currentSection->get("HostName", &hostname); 02682 if (hostname == 0 || hostname[0] == 0) 02683 DBUG_RETURN(true); 02684 02685 Uint32 localhost_used= 0; 02686 if(!strcmp(hostname, "localhost") || !strcmp(hostname, "127.0.0.1")){ 02687 localhost_used= 1; 02688 ctx.m_userProperties.put("$computer-localhost-used", localhost_used); 02689 if(!ctx.m_userProperties.get("$computer-localhost", &hostname)) 02690 DBUG_RETURN(true); 02691 } else { 02692 ctx.m_userProperties.get("$computer-localhost-used", &localhost_used); 02693 ctx.m_userProperties.put("$computer-localhost", hostname); 02694 } 02695 02696 if (localhost_used) { 02697 ctx.reportError("Mixing of localhost (default for [NDBD]HostName) with other hostname(%s) is illegal", 02698 hostname); 02699 DBUG_RETURN(false); 02700 } 02701 02702 DBUG_RETURN(true); 02703 } 02704 02705 bool 02706 fixNodeHostname(InitConfigFileParser::Context & ctx, const char * data) 02707 { 02708 const char * hostname; 02709 DBUG_ENTER("fixNodeHostname"); 02710 02711 if (ctx.m_currentSection->get("HostName", &hostname)) 02712 DBUG_RETURN(checkLocalhostHostnameMix(ctx,0)); 02713 02714 const char * compId; 02715 if(!ctx.m_currentSection->get("ExecuteOnComputer", &compId)) 02716 DBUG_RETURN(true); 02717 02718 const Properties * computer; 02719 char tmp[255]; 02720 BaseString::snprintf(tmp, sizeof(tmp), "Computer_%s", compId); 02721 if(!ctx.m_config->get(tmp, &computer)){ 02722 ctx.reportError("Computer \"%s\" not declared" 02723 "- [%s] starting at line: %d", 02724 compId, ctx.fname, ctx.m_sectionLineno); 02725 DBUG_RETURN(false); 02726 } 02727 02728 if(!computer->get("HostName", &hostname)){ 02729 ctx.reportError("HostName missing in [COMPUTER] (Id: %d) " 02730 " - [%s] starting at line: %d", 02731 compId, ctx.fname, ctx.m_sectionLineno); 02732 DBUG_RETURN(false); 02733 } 02734 02735 require(ctx.m_currentSection->put("HostName", hostname)); 02736 DBUG_RETURN(checkLocalhostHostnameMix(ctx,0)); 02737 } 02738 02739 bool 02740 fixFileSystemPath(InitConfigFileParser::Context & ctx, const char * data){ 02741 DBUG_ENTER("fixFileSystemPath"); 02742 02743 const char * path; 02744 if (ctx.m_currentSection->get("FileSystemPath", &path)) 02745 DBUG_RETURN(true); 02746 02747 if (ctx.m_currentSection->get("DataDir", &path)) { 02748 require(ctx.m_currentSection->put("FileSystemPath", path)); 02749 DBUG_RETURN(true); 02750 } 02751 02752 require(false); 02753 DBUG_RETURN(false); 02754 } 02755 02756 bool 02757 fixBackupDataDir(InitConfigFileParser::Context & ctx, const char * data){ 02758 02759 const char * path; 02760 if (ctx.m_currentSection->get("BackupDataDir", &path)) 02761 return true; 02762 02763 if (ctx.m_currentSection->get("FileSystemPath", &path)) { 02764 require(ctx.m_currentSection->put("BackupDataDir", path)); 02765 return true; 02766 } 02767 02768 require(false); 02769 return false; 02770 } 02771 02775 bool 02776 checkConnectionSupport(InitConfigFileParser::Context & ctx, const char * data) 02777 { 02778 int error= 0; 02779 if (strcasecmp("TCP",ctx.fname) == 0) 02780 { 02781 // always enabled 02782 } 02783 else if (strcasecmp("SHM",ctx.fname) == 0) 02784 { 02785 #ifndef NDB_SHM_TRANSPORTER 02786 error= 1; 02787 #endif 02788 } 02789 else if (strcasecmp("SCI",ctx.fname) == 0) 02790 { 02791 #ifndef NDB_SCI_TRANSPORTER 02792 error= 1; 02793 #endif 02794 } 02795 else if (strcasecmp("OSE",ctx.fname) == 0) 02796 { 02797 #ifndef NDB_OSE_TRANSPORTER 02798 error= 1; 02799 #endif 02800 } 02801 if (error) 02802 { 02803 ctx.reportError("Binary not compiled with this connection support, " 02804 "[%s] starting at line: %d", 02805 ctx.fname, ctx.m_sectionLineno); 02806 return false; 02807 } 02808 return true; 02809 } 02810 02814 bool 02815 transformConnection(InitConfigFileParser::Context & ctx, const char * data) 02816 { 02817 Uint32 connections = 0; 02818 ctx.m_userProperties.get("NoOfConnections", &connections); 02819 BaseString::snprintf(ctx.pname, sizeof(ctx.pname), "Connection_%d", connections); 02820 ctx.m_userProperties.put("NoOfConnections", ++connections, true); 02821 02822 ctx.m_currentSection->put("Type", ctx.fname); 02823 return true; 02824 } 02825 02829 bool 02830 transformSystem(InitConfigFileParser::Context & ctx, const char * data){ 02831 02832 const char * name; 02833 if(!ctx.m_currentSection->get("Name", &name)){ 02834 ctx.reportError("Mandatory parameter Name missing from section " 02835 "[%s] starting at line: %d", 02836 ctx.fname, ctx.m_sectionLineno); 02837 return false; 02838 } 02839 02840 ndbout << "transformSystem " << name << endl; 02841 02842 BaseString::snprintf(ctx.pname, sizeof(ctx.pname), "SYSTEM_%s", name); 02843 02844 return true; 02845 } 02846 02850 bool 02851 transformComputer(InitConfigFileParser::Context & ctx, const char * data){ 02852 const char * id; 02853 if(!ctx.m_currentSection->get("Id", &id)){ 02854 ctx.reportError("Mandatory parameter Id missing from section " 02855 "[%s] starting at line: %d", 02856 ctx.fname, ctx.m_sectionLineno); 02857 return false; 02858 } 02859 BaseString::snprintf(ctx.pname, sizeof(ctx.pname), "Computer_%s", id); 02860 02861 Uint32 computers = 0; 02862 ctx.m_userProperties.get("NoOfComputers", &computers); 02863 ctx.m_userProperties.put("NoOfComputers", ++computers, true); 02864 02865 const char * hostname = 0; 02866 ctx.m_currentSection->get("HostName", &hostname); 02867 if(!hostname){ 02868 return true; 02869 } 02870 02871 return checkLocalhostHostnameMix(ctx,0); 02872 } 02873 02877 void 02878 applyDefaultValues(InitConfigFileParser::Context & ctx, 02879 const Properties * defaults) 02880 { 02881 DBUG_ENTER("applyDefaultValues"); 02882 if(defaults != NULL){ 02883 Properties::Iterator it(defaults); 02884 02885 for(const char * name = it.first(); name != NULL; name = it.next()){ 02886 ConfigInfo::Status st = ctx.m_info->getStatus(ctx.m_currentInfo, name); 02887 if(!ctx.m_currentSection->contains(name)){ 02888 switch (ctx.m_info->getType(ctx.m_currentInfo, name)){ 02889 case ConfigInfo::CI_INT: 02890 case ConfigInfo::CI_BOOL:{ 02891 Uint32 val = 0; 02892 ::require(defaults->get(name, &val)); 02893 ctx.m_currentSection->put(name, val); 02894 DBUG_PRINT("info",("%s=%d #default",name,val)); 02895 break; 02896 } 02897 case ConfigInfo::CI_INT64:{ 02898 Uint64 val = 0; 02899 ::require(defaults->get(name, &val)); 02900 ctx.m_currentSection->put64(name, val); 02901 DBUG_PRINT("info",("%s=%lld #default",name,val)); 02902 break; 02903 } 02904 case ConfigInfo::CI_STRING:{ 02905 const char * val; 02906 ::require(defaults->get(name, &val)); 02907 ctx.m_currentSection->put(name, val); 02908 DBUG_PRINT("info",("%s=%s #default",name,val)); 02909 break; 02910 } 02911 case ConfigInfo::CI_SECTION: 02912 break; 02913 } 02914 } 02915 #ifndef DBUG_OFF 02916 else 02917 { 02918 switch (ctx.m_info->getType(ctx.m_currentInfo, name)){ 02919 case ConfigInfo::CI_INT: 02920 case ConfigInfo::CI_BOOL:{ 02921 Uint32 val = 0; 02922 ::require(ctx.m_currentSection->get(name, &val)); 02923 DBUG_PRINT("info",("%s=%d",name,val)); 02924 break; 02925 } 02926 case ConfigInfo::CI_INT64:{ 02927 Uint64 val = 0; 02928 ::require(ctx.m_currentSection->get(name, &val)); 02929 DBUG_PRINT("info",("%s=%lld",name,val)); 02930 break; 02931 } 02932 case ConfigInfo::CI_STRING:{ 02933 const char * val; 02934 ::require(ctx.m_currentSection->get(name, &val)); 02935 DBUG_PRINT("info",("%s=%s",name,val)); 02936 break; 02937 } 02938 case ConfigInfo::CI_SECTION: 02939 break; 02940 } 02941 } 02942 #endif 02943 } 02944 } 02945 DBUG_VOID_RETURN; 02946 } 02947 02948 bool 02949 applyDefaultValues(InitConfigFileParser::Context & ctx, const char * data){ 02950 02951 if(strcmp(data, "user") == 0) 02952 applyDefaultValues(ctx, ctx.m_userDefaults); 02953 else if (strcmp(data, "system") == 0) 02954 applyDefaultValues(ctx, ctx.m_systemDefaults); 02955 else 02956 return false; 02957 02958 return true; 02959 } 02960 02964 bool 02965 checkMandatory(InitConfigFileParser::Context & ctx, const char * data){ 02966 02967 Properties::Iterator it(ctx.m_currentInfo); 02968 for(const char * name = it.first(); name != NULL; name = it.next()){ 02969 const Properties * info = NULL; 02970 ::require(ctx.m_currentInfo->get(name, &info)); 02971 Uint32 val; 02972 if(info->get("Mandatory", &val)){ 02973 const char * fname; 02974 ::require(info->get("Fname", &fname)); 02975 if(!ctx.m_currentSection->contains(fname)){ 02976 ctx.reportError("Mandatory parameter %s missing from section " 02977 "[%s] starting at line: %d", 02978 fname, ctx.fname, ctx.m_sectionLineno); 02979 return false; 02980 } 02981 } 02982 } 02983 return true; 02984 } 02985 02992 static bool fixNodeId(InitConfigFileParser::Context & ctx, const char * data) 02993 { 02994 char buf[] = "NodeIdX"; buf[6] = data[sizeof("NodeI")]; 02995 char sysbuf[] = "SystemX"; sysbuf[6] = data[sizeof("NodeI")]; 02996 const char* nodeId; 02997 require(ctx.m_currentSection->get(buf, &nodeId)); 02998 02999 char tmpLine[MAX_LINE_LENGTH]; 03000 strncpy(tmpLine, nodeId, MAX_LINE_LENGTH); 03001 char* token1 = strtok(tmpLine, "."); 03002 char* token2 = strtok(NULL, "."); 03003 Uint32 id; 03004 03005 if (token2 == NULL) { // Only a number given 03006 errno = 0; 03007 char* p; 03008 id = strtol(token1, &p, 10); 03009 if (errno != 0) warning("STRTOK1", nodeId); 03010 require(ctx.m_currentSection->put(buf, id, true)); 03011 } else { // A pair given (e.g. "uppsala.32") 03012 errno = 0; 03013 char* p; 03014 id = strtol(token2, &p, 10); 03015 if (errno != 0) warning("STRTOK2", nodeId); 03016 require(ctx.m_currentSection->put(buf, id, true)); 03017 require(ctx.m_currentSection->put(sysbuf, token1)); 03018 } 03019 return true; 03020 } 03021 03030 static bool 03031 fixHostname(InitConfigFileParser::Context & ctx, const char * data){ 03032 03033 char buf[] = "NodeIdX"; buf[6] = data[sizeof("HostNam")]; 03034 char sysbuf[] = "SystemX"; sysbuf[6] = data[sizeof("HostNam")]; 03035 03036 if(!ctx.m_currentSection->contains(data)){ 03037 Uint32 id = 0; 03038 require(ctx.m_currentSection->get(buf, &id)); 03039 03040 const Properties * node; 03041 if(!ctx.m_config->get("Node", id, &node)) 03042 { 03043 ctx.reportError("Unknown node: \"%d\" specified in connection " 03044 "[%s] starting at line: %d", 03045 id, ctx.fname, ctx.m_sectionLineno); 03046 return false; 03047 } 03048 03049 const char * hostname; 03050 require(node->get("HostName", &hostname)); 03051 require(ctx.m_currentSection->put(data, hostname)); 03052 } 03053 return true; 03054 } 03055 03059 static bool 03060 fixPortNumber(InitConfigFileParser::Context & ctx, const char * data){ 03061 03062 DBUG_ENTER("fixPortNumber"); 03063 03064 Uint32 id1, id2; 03065 const char *hostName1; 03066 const char *hostName2; 03067 require(ctx.m_currentSection->get("NodeId1", &id1)); 03068 require(ctx.m_currentSection->get("NodeId2", &id2)); 03069 require(ctx.m_currentSection->get("HostName1", &hostName1)); 03070 require(ctx.m_currentSection->get("HostName2", &hostName2)); 03071 DBUG_PRINT("info",("NodeId1=%d HostName1=\"%s\"",id1,hostName1)); 03072 DBUG_PRINT("info",("NodeId2=%d HostName2=\"%s\"",id2,hostName2)); 03073 03074 const Properties *node1, *node2; 03075 require(ctx.m_config->get("Node", id1, &node1)); 03076 require(ctx.m_config->get("Node", id2, &node2)); 03077 03078 const char *type1, *type2; 03079 require(node1->get("Type", &type1)); 03080 require(node2->get("Type", &type2)); 03081 03082 /* add NodeIdServer info */ 03083 { 03084 Uint32 nodeIdServer = id1 < id2 ? id1 : id2; 03085 if(strcmp(type1, API_TOKEN) == 0 || strcmp(type2, MGM_TOKEN) == 0) 03086 nodeIdServer = id2; 03087 else if(strcmp(type2, API_TOKEN) == 0 || strcmp(type1, MGM_TOKEN) == 0) 03088 nodeIdServer = id1; 03089 ctx.m_currentSection->put("NodeIdServer", nodeIdServer); 03090 03091 if (id2 == nodeIdServer) { 03092 { 03093 const char *tmp= hostName1; 03094 hostName1= hostName2; 03095 hostName2= tmp; 03096 } 03097 { 03098 Uint32 tmp= id1; 03099 id1= id2; 03100 id2= tmp; 03101 } 03102 { 03103 const Properties *tmp= node1; 03104 node1= node2; 03105 node2= tmp; 03106 } 03107 { 03108 const char *tmp= type1; 03109 type1= type2; 03110 type2= tmp; 03111 } 03112 } 03113 } 03114 03115 BaseString hostname(hostName1); 03116 03117 if (hostname.c_str()[0] == 0) { 03118 ctx.reportError("Hostname required on nodeid %d since it will " 03119 "act as server.", id1); 03120 DBUG_RETURN(false); 03121 } 03122 03123 Uint32 port= 0; 03124 if(strcmp(type1, MGM_TOKEN)==0) 03125 node1->get("PortNumber",&port); 03126 else if(strcmp(type2, MGM_TOKEN)==0) 03127 node2->get("PortNumber",&port); 03128 03129 if (!port && 03130 !node1->get("ServerPort", &port) && 03131 !ctx.m_userProperties.get("ServerPort_", id1, &port)) 03132 { 03133 Uint32 base= 0; 03134 /* 03135 * If the connection doesn't involve an mgm server, 03136 * and a default port number has been set, behave the old 03137 * way of allocating port numbers for transporters. 03138 */ 03139 if(ctx.m_userDefaults && ctx.m_userDefaults->get("PortNumber", &base)) 03140 { 03141 Uint32 adder= 0; 03142 { 03143 BaseString server_port_adder(hostname); 03144 server_port_adder.append("_ServerPortAdder"); 03145 ctx.m_userProperties.get(server_port_adder.c_str(), &adder); 03146 ctx.m_userProperties.put(server_port_adder.c_str(), adder+1, true); 03147 } 03148 03149 if (!ctx.m_userProperties.get("ServerPortBase", &base)){ 03150 if(!(ctx.m_userDefaults && 03151 ctx.m_userDefaults->get("PortNumber", &base)) && 03152 !ctx.m_systemDefaults->get("PortNumber", &base)) { 03153 base= strtoll(NDB_TCP_BASE_PORT,0,0); 03154 } 03155 ctx.m_userProperties.put("ServerPortBase", base); 03156 } 03157 03158 port= base + adder; 03159 ctx.m_userProperties.put("ServerPort_", id1, port); 03160 } 03161 } 03162 03163 if(ctx.m_currentSection->contains("PortNumber")) { 03164 ndbout << "PortNumber should no longer be specificied " 03165 << "per connection, please remove from config. " 03166 << "Will be changed to " << port << endl; 03167 ctx.m_currentSection->put("PortNumber", port, true); 03168 } 03169 else 03170 { 03171 ctx.m_currentSection->put("PortNumber", port); 03172 } 03173 03174 DBUG_PRINT("info", ("connection %d-%d port %d host %s", 03175 id1, id2, port, hostname.c_str())); 03176 03177 DBUG_RETURN(true); 03178 } 03179 03180 static bool 03181 fixShmUniqueId(InitConfigFileParser::Context & ctx, const char * data) 03182 { 03183 DBUG_ENTER("fixShmUniqueId"); 03184 Uint32 nodes= 0; 03185 ctx.m_userProperties.get(ctx.fname, &nodes); 03186 if (nodes == 1) // first management server 03187 { 03188 Uint32 portno= atoi(NDB_PORT); 03189 ctx.m_currentSection->get("PortNumber", &portno); 03190 ctx.m_userProperties.put("ShmUniqueId", portno); 03191 } 03192 DBUG_RETURN(true); 03193 } 03194 03195 static 03196 bool 03197 fixShmKey(InitConfigFileParser::Context & ctx, const char *) 03198 { 03199 DBUG_ENTER("fixShmKey"); 03200 { 03201 static int last_signum= -1; 03202 Uint32 signum; 03203 if(!ctx.m_currentSection->get("Signum", &signum)) 03204 { 03205 signum= OPT_NDB_SHM_SIGNUM_DEFAULT; 03206 if (signum <= 0) 03207 { 03208 ctx.reportError("Unable to set default parameter for [SHM]Signum" 03209 " please specify [SHM DEFAULT]Signum"); 03210 return false; 03211 } 03212 ctx.m_currentSection->put("Signum", signum); 03213 DBUG_PRINT("info",("Added Signum=%u", signum)); 03214 } 03215 if ( last_signum != (int)signum && last_signum >= 0 ) 03216 { 03217 ctx.reportError("All shared memory transporters must have same [SHM]Signum defined." 03218 " Use [SHM DEFAULT]Signum"); 03219 return false; 03220 } 03221 last_signum= (int)signum; 03222 } 03223 { 03224 Uint32 id1= 0, id2= 0, key= 0; 03225 require(ctx.m_currentSection->get("NodeId1", &id1)); 03226 require(ctx.m_currentSection->get("NodeId2", &id2)); 03227 if(!ctx.m_currentSection->get("ShmKey", &key)) 03228 { 03229 require(ctx.m_userProperties.get("ShmUniqueId", &key)); 03230 key= key << 16 | (id1 > id2 ? id1 << 8 | id2 : id2 << 8 | id1); 03231 ctx.m_currentSection->put("ShmKey", key); 03232 DBUG_PRINT("info",("Added ShmKey=0x%x", key)); 03233 } 03234 } 03235 DBUG_RETURN(true); 03236 } 03237 03241 static bool 03242 checkDbConstraints(InitConfigFileParser::Context & ctx, const char *){ 03243 03244 Uint32 t1 = 0, t2 = 0; 03245 ctx.m_currentSection->get("MaxNoOfConcurrentOperations", &t1); 03246 ctx.m_currentSection->get("MaxNoOfConcurrentTransactions", &t2); 03247 03248 if (t1 < t2) { 03249 ctx.reportError("MaxNoOfConcurrentOperations must be greater than " 03250 "MaxNoOfConcurrentTransactions - [%s] starting at line: %d", 03251 ctx.fname, ctx.m_sectionLineno); 03252 return false; 03253 } 03254 03255 Uint32 replicas = 0, otherReplicas; 03256 ctx.m_currentSection->get("NoOfReplicas", &replicas); 03257 if(ctx.m_userProperties.get("NoOfReplicas", &otherReplicas)){ 03258 if(replicas != otherReplicas){ 03259 ctx.reportError("NoOfReplicas defined differently on different nodes" 03260 " - [%s] starting at line: %d", 03261 ctx.fname, ctx.m_sectionLineno); 03262 return false; 03263 } 03264 } else { 03265 ctx.m_userProperties.put("NoOfReplicas", replicas); 03266 } 03267 03268 return true; 03269 } 03270 03274 static bool 03275 checkConnectionConstraints(InitConfigFileParser::Context & ctx, const char *){ 03276 03277 Uint32 id1 = 0, id2 = 0; 03278 ctx.m_currentSection->get("NodeId1", &id1); 03279 ctx.m_currentSection->get("NodeId2", &id2); 03280 03281 if(id1 == id2){ 03282 ctx.reportError("Illegal connection from node to itself" 03283 " - [%s] starting at line: %d", 03284 ctx.fname, ctx.m_sectionLineno); 03285 return false; 03286 } 03287 03288 const Properties * node1; 03289 if(!ctx.m_config->get("Node", id1, &node1)){ 03290 ctx.reportError("Connection refering to undefined node: %d" 03291 " - [%s] starting at line: %d", 03292 id1, ctx.fname, ctx.m_sectionLineno); 03293 return false; 03294 } 03295 03296 const Properties * node2; 03297 if(!ctx.m_config->get("Node", id2, &node2)){ 03298 ctx.reportError("Connection refering to undefined node: %d" 03299 " - [%s] starting at line: %d", 03300 id2, ctx.fname, ctx.m_sectionLineno); 03301 return false; 03302 } 03303 03304 const char * type1; 03305 const char * type2; 03306 require(node1->get("Type", &type1)); 03307 require(node2->get("Type", &type2)); 03308 03314 if((strcmp(type1, DB_TOKEN) != 0 && strcmp(type2, DB_TOKEN) != 0) && 03315 !(strcmp(type1, MGM_TOKEN) == 0 && strcmp(type2, MGM_TOKEN) == 0)) 03316 { 03317 ctx.reportError("Invalid connection between node %d (%s) and node %d (%s)" 03318 " - [%s] starting at line: %d", 03319 id1, type1, id2, type2, 03320 ctx.fname, ctx.m_sectionLineno); 03321 return false; 03322 } 03323 03324 return true; 03325 } 03326 03327 static bool 03328 checkTCPConstraints(InitConfigFileParser::Context & ctx, const char * data){ 03329 03330 const char * host; 03331 struct in_addr addr; 03332 if(ctx.m_currentSection->get(data, &host) && strlen(host) && 03333 Ndb_getInAddr(&addr, host)){ 03334 ctx.reportError("Unable to lookup/illegal hostname %s" 03335 " - [%s] starting at line: %d", 03336 host, ctx.fname, ctx.m_sectionLineno); 03337 return false; 03338 } 03339 return true; 03340 } 03341 03342 static 03343 bool 03344 transform(InitConfigFileParser::Context & ctx, 03345 Properties & dst, 03346 const char * oldName, 03347 const char * newName, 03348 double add, double mul){ 03349 03350 if(ctx.m_currentSection->contains(newName)){ 03351 ctx.reportError("Both %s and %s specified" 03352 " - [%s] starting at line: %d", 03353 oldName, newName, 03354 ctx.fname, ctx.m_sectionLineno); 03355 return false; 03356 } 03357 03358 PropertiesType oldType; 03359 require(ctx.m_currentSection->getTypeOf(oldName, &oldType)); 03360 ConfigInfo::Type newType = ctx.m_info->getType(ctx.m_currentInfo, newName); 03361 03362 if(!((oldType == PropertiesType_Uint32 || oldType == PropertiesType_Uint64) 03363 && (newType == ConfigInfo::CI_INT || newType == ConfigInfo::CI_INT64 || newType == ConfigInfo::CI_BOOL))){ 03364 ndbout << "oldType: " << (int)oldType << ", newType: " << (int)newType << endl; 03365 ctx.reportError("Unable to handle type conversion w.r.t deprication %s %s" 03366 "- [%s] starting at line: %d", 03367 oldName, newName, 03368 ctx.fname, ctx.m_sectionLineno); 03369 return false; 03370 } 03371 Uint64 oldVal; 03372 require(ctx.m_currentSection->get(oldName, &oldVal)); 03373 03374 Uint64 newVal = (Uint64)((Int64)oldVal * mul + add); 03375 if(!ctx.m_info->verify(ctx.m_currentInfo, newName, newVal)){ 03376 ctx.reportError("Unable to handle deprication, new value not within bounds" 03377 "%s %s - [%s] starting at line: %d", 03378 oldName, newName, 03379 ctx.fname, ctx.m_sectionLineno); 03380 return false; 03381 } 03382 03383 if(newType == ConfigInfo::CI_INT || newType == ConfigInfo::CI_BOOL){ 03384 require(dst.put(newName, (Uint32)newVal)); 03385 } else if(newType == ConfigInfo::CI_INT64) { 03386 require(dst.put64(newName, newVal)); 03387 } 03388 return true; 03389 } 03390 03391 static bool 03392 fixDepricated(InitConfigFileParser::Context & ctx, const char * data){ 03393 const char * name; 03398 Properties tmp(true); 03399 Properties::Iterator it(ctx.m_currentSection); 03400 for (name = it.first(); name != NULL; name = it.next()) { 03401 const DepricationTransform * p = &f_deprication[0]; 03402 while(p->m_section != 0){ 03403 if(strcmp(p->m_section, ctx.fname) == 0){ 03404 double mul = p->m_mul; 03405 double add = p->m_add; 03406 if(strcasecmp(name, p->m_oldName) == 0){ 03407 if(!transform(ctx, tmp, name, p->m_newName, add, mul)){ 03408 return false; 03409 } 03410 } else if(strcasecmp(name, p->m_newName) == 0) { 03411 if(!transform(ctx, tmp, name, p->m_oldName, -add/mul,1.0/mul)){ 03412 return false; 03413 } 03414 } 03415 } 03416 p++; 03417 } 03418 } 03419 03420 Properties::Iterator it2(&tmp); 03421 for (name = it2.first(); name != NULL; name = it2.next()) { 03422 PropertiesType type; 03423 require(tmp.getTypeOf(name, &type)); 03424 switch(type){ 03425 case PropertiesType_Uint32:{ 03426 Uint32 val; 03427 require(tmp.get(name, &val)); 03428 ::require(ctx.m_currentSection->put(name, val)); 03429 break; 03430 } 03431 case PropertiesType_char:{ 03432 const char * val; 03433 require(tmp.get(name, &val)); 03434 ::require(ctx.m_currentSection->put(name, val)); 03435 break; 03436 } 03437 case PropertiesType_Uint64:{ 03438 Uint64 val; 03439 require(tmp.get(name, &val)); 03440 ::require(ctx.m_currentSection->put64(name, val)); 03441 break; 03442 } 03443 case PropertiesType_Properties: 03444 default: 03445 ::require(false); 03446 } 03447 } 03448 return true; 03449 } 03450 03451 extern int g_print_full_config; 03452 03453 static bool 03454 saveInConfigValues(InitConfigFileParser::Context & ctx, const char * data){ 03455 const Properties * sec; 03456 if(!ctx.m_currentInfo->get(ctx.fname, &sec)){ 03457 require(false); 03458 return false; 03459 } 03460 03461 do { 03462 const char *secName; 03463 Uint32 id, status, typeVal; 03464 require(sec->get("Fname", &secName)); 03465 require(sec->get("Id", &id)); 03466 require(sec->get("Status", &status)); 03467 require(sec->get("SectionType", &typeVal)); 03468 03469 if(id == KEY_INTERNAL || status == ConfigInfo::CI_INTERNAL){ 03470 ndbout_c("skipping section %s", ctx.fname); 03471 break; 03472 } 03473 03474 if (g_print_full_config) 03475 { 03476 const char *alias= ConfigInfo::nameToAlias(ctx.fname); 03477 printf("[%s]\n", alias ? alias : ctx.fname); 03478 } 03479 03480 Uint32 no = 0; 03481 ctx.m_userProperties.get("$Section", id, &no); 03482 ctx.m_userProperties.put("$Section", id, no+1, true); 03483 03484 ctx.m_configValues.openSection(id, no); 03485 ctx.m_configValues.put(CFG_TYPE_OF_SECTION, typeVal); 03486 03487 Properties::Iterator it(ctx.m_currentSection); 03488 for (const char* n = it.first(); n != NULL; n = it.next()) { 03489 const Properties * info; 03490 if(!ctx.m_currentInfo->get(n, &info)) 03491 continue; 03492 03493 Uint32 id = 0; 03494 info->get("Id", &id); 03495 03496 if(id == KEY_INTERNAL) 03497 continue; 03498 03499 bool ok = true; 03500 PropertiesType type; 03501 require(ctx.m_currentSection->getTypeOf(n, &type)); 03502 switch(type){ 03503 case PropertiesType_Uint32:{ 03504 Uint32 val; 03505 require(ctx.m_currentSection->get(n, &val)); 03506 ok = ctx.m_configValues.put(id, val); 03507 if (g_print_full_config) 03508 printf("%s=%u\n", n, val); 03509 break; 03510 } 03511 case PropertiesType_Uint64:{ 03512 Uint64 val; 03513 require(ctx.m_currentSection->get(n, &val)); 03514 ok = ctx.m_configValues.put64(id, val); 03515 if (g_print_full_config) 03516 printf("%s=%llu\n", n, val); 03517 break; 03518 } 03519 case PropertiesType_char:{ 03520 const char * val; 03521 require(ctx.m_currentSection->get(n, &val)); 03522 ok = ctx.m_configValues.put(id, val); 03523 if (g_print_full_config) 03524 printf("%s=%s\n", n, val); 03525 break; 03526 } 03527 default: 03528 require(false); 03529 } 03530 require(ok); 03531 } 03532 ctx.m_configValues.closeSection(); 03533 } while(0); 03534 return true; 03535 } 03536 03537 static bool 03538 sanity_checks(Vector<ConfigInfo::ConfigRuleSection>§ions, 03539 struct InitConfigFileParser::Context &ctx, 03540 const char * rule_data) 03541 { 03542 Uint32 db_nodes = 0; 03543 Uint32 mgm_nodes = 0; 03544 Uint32 api_nodes = 0; 03545 if (!ctx.m_userProperties.get("DB", &db_nodes)) { 03546 ctx.reportError("At least one database node should be defined in config file"); 03547 return false; 03548 } 03549 if (!ctx.m_userProperties.get("MGM", &mgm_nodes)) { 03550 ctx.reportError("At least one management server node should be defined in config file"); 03551 return false; 03552 } 03553 if (!ctx.m_userProperties.get("API", &api_nodes)) { 03554 ctx.reportError("At least one application node (for the mysqld) should be defined in config file"); 03555 return false; 03556 } 03557 return true; 03558 } 03559 03560 static void 03561 add_a_connection(Vector<ConfigInfo::ConfigRuleSection>§ions, 03562 struct InitConfigFileParser::Context &ctx, 03563 Uint32 nodeId1, Uint32 nodeId2, bool use_shm) 03564 { 03565 ConfigInfo::ConfigRuleSection s; 03566 const char *hostname1= 0, *hostname2= 0; 03567 const Properties *tmp; 03568 03569 require(ctx.m_config->get("Node", nodeId1, &tmp)); 03570 tmp->get("HostName", &hostname1); 03571 03572 require(ctx.m_config->get("Node", nodeId2, &tmp)); 03573 tmp->get("HostName", &hostname2); 03574 03575 char buf[16]; 03576 s.m_sectionData= new Properties(true); 03577 BaseString::snprintf(buf, sizeof(buf), "%u", nodeId1); 03578 s.m_sectionData->put("NodeId1", buf); 03579 BaseString::snprintf(buf, sizeof(buf), "%u", nodeId2); 03580 s.m_sectionData->put("NodeId2", buf); 03581 03582 if (use_shm && 03583 hostname1 && hostname1[0] && 03584 hostname2 && hostname2[0] && 03585 strcmp(hostname1,hostname2) == 0) 03586 { 03587 s.m_sectionType= BaseString("SHM"); 03588 DBUG_PRINT("info",("adding SHM connection %d %d",nodeId1,nodeId2)); 03589 } 03590 else 03591 { 03592 s.m_sectionType= BaseString("TCP"); 03593 DBUG_PRINT("info",("adding TCP connection %d %d",nodeId1,nodeId2)); 03594 } 03595 03596 sections.push_back(s); 03597 } 03598 03599 static bool 03600 add_node_connections(Vector<ConfigInfo::ConfigRuleSection>§ions, 03601 struct InitConfigFileParser::Context &ctx, 03602 const char * rule_data) 03603 { 03604 DBUG_ENTER("add_node_connections"); 03605 Uint32 i; 03606 Properties * props= ctx.m_config; 03607 Properties p_connections(true); 03608 Properties p_connections2(true); 03609 03610 for (i = 0;; i++){ 03611 const Properties * tmp; 03612 Uint32 nodeId1, nodeId2; 03613 03614 if(!props->get("Connection", i, &tmp)) break; 03615 03616 if(!tmp->get("NodeId1", &nodeId1)) continue; 03617 p_connections.put("", nodeId1, nodeId1); 03618 if(!tmp->get("NodeId2", &nodeId2)) continue; 03619 p_connections.put("", nodeId2, nodeId2); 03620 03621 p_connections2.put("", nodeId1 + nodeId2<<16, nodeId1); 03622 p_connections2.put("", nodeId2 + nodeId1<<16, nodeId2); 03623 } 03624 03625 Uint32 nNodes; 03626 ctx.m_userProperties.get("NoOfNodes", &nNodes); 03627 03628 Properties p_db_nodes(true); 03629 Properties p_api_nodes(true); 03630 Properties p_mgm_nodes(true); 03631 03632 Uint32 i_db= 0, i_api= 0, i_mgm= 0, n; 03633 for (i= 0, n= 0; n < nNodes; i++){ 03634 const Properties * tmp; 03635 if(!props->get("Node", i, &tmp)) continue; 03636 n++; 03637 03638 const char * type; 03639 if(!tmp->get("Type", &type)) continue; 03640 03641 if (strcmp(type,DB_TOKEN) == 0) 03642 p_db_nodes.put("", i_db++, i); 03643 else if (strcmp(type,API_TOKEN) == 0) 03644 p_api_nodes.put("", i_api++, i); 03645 else if (strcmp(type,MGM_TOKEN) == 0) 03646 p_mgm_nodes.put("", i_mgm++, i); 03647 } 03648 03649 Uint32 nodeId1, nodeId2, dummy; 03650 03651 for (i= 0; p_db_nodes.get("", i, &nodeId1); i++){ 03652 for (Uint32 j= i+1;; j++){ 03653 if(!p_db_nodes.get("", j, &nodeId2)) break; 03654 if(!p_connections2.get("", nodeId1+nodeId2<<16, &dummy)) { 03655 add_a_connection(sections,ctx,nodeId1,nodeId2,opt_ndb_shm); 03656 } 03657 } 03658 } 03659 03660 for (i= 0; p_api_nodes.get("", i, &nodeId1); i++){ 03661 if(!p_connections.get("", nodeId1, &dummy)) { 03662 for (Uint32 j= 0;; j++){ 03663 if(!p_db_nodes.get("", j, &nodeId2)) break; 03664 add_a_connection(sections,ctx,nodeId1,nodeId2,opt_ndb_shm); 03665 } 03666 } 03667 } 03668 03669 for (i= 0; p_mgm_nodes.get("", i, &nodeId1); i++){ 03670 if(!p_connections.get("", nodeId1, &dummy)) { 03671 for (Uint32 j= 0;; j++){ 03672 if(!p_db_nodes.get("", j, &nodeId2)) break; 03673 add_a_connection(sections,ctx,nodeId1,nodeId2,0); 03674 } 03675 } 03676 } 03677 03678 DBUG_RETURN(true); 03679 } 03680 03681 static bool set_connection_priorities(Vector<ConfigInfo::ConfigRuleSection>§ions, 03682 struct InitConfigFileParser::Context &ctx, 03683 const char * rule_data) 03684 { 03685 DBUG_ENTER("set_connection_priorities"); 03686 DBUG_RETURN(true); 03687 } 03688 03689 static bool 03690 check_node_vs_replicas(Vector<ConfigInfo::ConfigRuleSection>§ions, 03691 struct InitConfigFileParser::Context &ctx, 03692 const char * rule_data) 03693 { 03694 Uint32 db_nodes= 0; 03695 Uint32 replicas= 0; 03696 Uint32 db_host_count= 0; 03697 ctx.m_userProperties.get(DB_TOKEN, &db_nodes); 03698 ctx.m_userProperties.get("NoOfReplicas", &replicas); 03699 if((db_nodes % replicas) != 0){ 03700 ctx.reportError("Invalid no of db nodes wrt no of replicas.\n" 03701 "No of nodes must be dividable with no or replicas"); 03702 return false; 03703 } 03704 // check that node groups and arbitrators are ok 03705 // just issue warning if not 03706 if(replicas > 1){ 03707 Properties * props= ctx.m_config; 03708 Properties p_db_hosts(true); // store hosts which db nodes run on 03709 Properties p_arbitrators(true); // store hosts which arbitrators run on 03710 // arbitrator should not run together with db node on same host 03711 Uint32 i, n, group= 0, i_group= 0; 03712 Uint32 n_nodes; 03713 BaseString node_group_warning, arbitration_warning; 03714 const char *arbit_warn_fmt= 03715 "\n arbitrator with id %d and db node with id %d on same host %s"; 03716 const char *arbit_warn_fmt2= 03717 "\n arbitrator with id %d has no hostname specified"; 03718 03719 ctx.m_userProperties.get("NoOfNodes", &n_nodes); 03720 for (i= 0, n= 0; n < n_nodes; i++){ 03721 const Properties * tmp; 03722 if(!props->get("Node", i, &tmp)) continue; 03723 n++; 03724 03725 const char * type; 03726 if(!tmp->get("Type", &type)) continue; 03727 03728 const char* host= 0; 03729 tmp->get("HostName", &host); 03730 03731 if (strcmp(type,DB_TOKEN) == 0) 03732 { 03733 { 03734 Uint32 ii; 03735 if (!p_db_hosts.get(host,&ii)) 03736 db_host_count++; 03737 p_db_hosts.put(host,i); 03738 if (p_arbitrators.get(host,&ii)) 03739 { 03740 arbitration_warning.appfmt(arbit_warn_fmt, ii, i, host); 03741 p_arbitrators.remove(host); // only one warning per db node 03742 } 03743 } 03744 { 03745 unsigned j; 03746 BaseString str, str2; 03747 str.assfmt("#group%d_",group); 03748 p_db_hosts.put(str.c_str(),i_group,host); 03749 str2.assfmt("##group%d_",group); 03750 p_db_hosts.put(str2.c_str(),i_group,i); 03751 for (j= 0; j < i_group; j++) 03752 { 03753 const char *other_host; 03754 p_db_hosts.get(str.c_str(),j,&other_host); 03755 if (strcmp(host,other_host) == 0) { 03756 unsigned int other_i, c= 0; 03757 p_db_hosts.get(str2.c_str(),j,&other_i); 03758 p_db_hosts.get(str.c_str(),&c); 03759 if (c == 0) // first warning in this node group 03760 node_group_warning.appfmt(" Node group %d", group); 03761 c|= 1 << j; 03762 p_db_hosts.put(str.c_str(),c); 03763 03764 node_group_warning.appfmt(",\n db node with id %d and id %d " 03765 "on same host %s", other_i, i, host); 03766 } 03767 } 03768 i_group++; 03769 DBUG_ASSERT(i_group <= replicas); 03770 if (i_group == replicas) 03771 { 03772 unsigned c= 0; 03773 p_db_hosts.get(str.c_str(),&c); 03774 if (c+1 == (1u << (replicas-1))) // all nodes on same machine 03775 node_group_warning.append(".\n Host failure will " 03776 "cause complete cluster shutdown."); 03777 else if (c > 0) 03778 node_group_warning.append(".\n Host failure may " 03779 "cause complete cluster shutdown."); 03780 group++; 03781 i_group= 0; 03782 } 03783 } 03784 } 03785 else if (strcmp(type,API_TOKEN) == 0 || 03786 strcmp(type,MGM_TOKEN) == 0) 03787 { 03788 Uint32 rank; 03789 if(tmp->get("ArbitrationRank", &rank) && rank > 0) 03790 { 03791 if(host && host[0] != 0) 03792 { 03793 Uint32 ii; 03794 p_arbitrators.put(host,i); 03795 if (p_db_hosts.get(host,&ii)) 03796 { 03797 arbitration_warning.appfmt(arbit_warn_fmt, i, ii, host); 03798 } 03799 } 03800 else 03801 { 03802 arbitration_warning.appfmt(arbit_warn_fmt2, i); 03803 } 03804 } 03805 } 03806 } 03807 if (db_host_count > 1 && node_group_warning.length() > 0) 03808 ndbout_c("Cluster configuration warning:\n%s",node_group_warning.c_str()); 03809 if (db_host_count > 1 && arbitration_warning.length() > 0) 03810 ndbout_c("Cluster configuration warning:%s%s",arbitration_warning.c_str(), 03811 "\n Running arbitrator on the same host as a database node may" 03812 "\n cause complete cluster shutdown in case of host failure."); 03813 } 03814 return true; 03815 } 03816 03817 template class Vector<ConfigInfo::ConfigRuleSection>;
1.4.7

