Commit e4290e48 authored by tomas@poseidon.(none)'s avatar tomas@poseidon.(none)

dded method to retrieve mysqld, ndbd, and ndb_mgmd aliases for API,MGM and DB

added sanity checks for config file
changed so that ndb_0 is replaced by ndb_pid#### in ndb files
added error_string for to some functions, alloc_node_id(), start()
added better error printout for failed alloc node id
better error printouts for failures when starting ndb_mgmd
parent dab89186
......@@ -394,6 +394,14 @@ extern "C" {
*/
const char * ndb_mgm_get_node_type_string(enum ndb_mgm_node_type type);
/**
* Convert an ndb_mgm_node_type to a alias string
*
* @param type Node type.
* @return NULL if invalid id.
*/
const char * ndb_mgm_get_node_type_alias_string(enum ndb_mgm_node_type type, const char **str);
/**
* Convert a string to a ndb_mgm_node_status
*
......
......@@ -161,6 +161,9 @@ const int ConfigInfo::m_NoOfRules = sizeof(m_SectionRules)/sizeof(SectionRule);
/****************************************************************************
* Config Rules declarations
****************************************************************************/
static bool sanity_checks(Vector<ConfigInfo::ConfigRuleSection>&sections,
struct InitConfigFileParser::Context &ctx,
const char * rule_data);
static bool add_node_connections(Vector<ConfigInfo::ConfigRuleSection>&sections,
struct InitConfigFileParser::Context &ctx,
const char * rule_data);
......@@ -173,6 +176,7 @@ static bool check_node_vs_replicas(Vector<ConfigInfo::ConfigRuleSection>&section
const ConfigInfo::ConfigRule
ConfigInfo::m_ConfigRules[] = {
{ sanity_checks, 0 },
{ add_node_connections, 0 },
{ add_server_ports, 0 },
{ check_node_vs_replicas, 0 },
......@@ -2958,6 +2962,29 @@ saveInConfigValues(InitConfigFileParser::Context & ctx, const char * data){
return true;
}
static bool
sanity_checks(Vector<ConfigInfo::ConfigRuleSection>&sections,
struct InitConfigFileParser::Context &ctx,
const char * rule_data)
{
Uint32 db_nodes = 0;
Uint32 mgm_nodes = 0;
Uint32 api_nodes = 0;
if (!ctx.m_userProperties.get("DB", &db_nodes)) {
ctx.reportError("At least one database node should be defined in config file");
return false;
}
if (!ctx.m_userProperties.get("MGM", &mgm_nodes)) {
ctx.reportError("At least one management server node should be defined in config file");
return false;
}
if (!ctx.m_userProperties.get("API", &api_nodes)) {
ctx.reportError("At least one application node (for the mysqld) should be defined in config file");
return false;
}
return true;
}
static bool
add_node_connections(Vector<ConfigInfo::ConfigRuleSection>&sections,
struct InitConfigFileParser::Context &ctx,
......@@ -3091,7 +3118,9 @@ check_node_vs_replicas(Vector<ConfigInfo::ConfigRuleSection>&sections,
{
Uint32 db_nodes = 0;
Uint32 replicas = 0;
ctx.m_userProperties.get("DB", &db_nodes);
if (!ctx.m_userProperties.get("DB", &db_nodes)) {
return true;
}
ctx.m_userProperties.get("NoOfReplicas", &replicas);
if((db_nodes % replicas) != 0){
ctx.reportError("Invalid no of db nodes wrt no of replicas.\n"
......
......@@ -53,58 +53,73 @@ NdbConfig_NdbCfgName(int with_ndb_home){
return buf;
}
static
char *get_prefix_buf(int len, int node_id)
{
char tmp_buf[sizeof("ndb_pid#########")+1];
if (node_id > 0)
snprintf(tmp_buf, sizeof(tmp_buf), "ndb_%u", node_id);
else
snprintf(tmp_buf, sizeof(tmp_buf), "ndb_pid%u", getpid());
tmp_buf[sizeof(tmp_buf)-1]= 0;
char *buf= NdbConfig_AllocHomePath(len+strlen(tmp_buf));
strcat(buf, tmp_buf);
return buf;
}
char*
NdbConfig_ErrorFileName(int node_id){
char *buf= NdbConfig_AllocHomePath(128);
char *buf= get_prefix_buf(128, node_id);
int len= strlen(buf);
snprintf(buf+len, 128, "ndb_%u_error.log", node_id);
snprintf(buf+len, 128, "_error.log");
return buf;
}
char*
NdbConfig_ClusterLogFileName(int node_id){
char *buf= NdbConfig_AllocHomePath(128);
char *buf= get_prefix_buf(128, node_id);
int len= strlen(buf);
snprintf(buf+len, 128, "ndb_%u_cluster.log", node_id);
snprintf(buf+len, 128, "_cluster.log");
return buf;
}
char*
NdbConfig_SignalLogFileName(int node_id){
char *buf= NdbConfig_AllocHomePath(128);
char *buf= get_prefix_buf(128, node_id);
int len= strlen(buf);
snprintf(buf+len, 128, "ndb_%u_signal.log", node_id);
snprintf(buf+len, 128, "_signal.log");
return buf;
}
char*
NdbConfig_TraceFileName(int node_id, int file_no){
char *buf= NdbConfig_AllocHomePath(128);
char *buf= get_prefix_buf(128, node_id);
int len= strlen(buf);
snprintf(buf+len, 128, "ndb_%u_trace.log.%u", node_id, file_no);
snprintf(buf+len, 128, "_trace.log.%u", file_no);
return buf;
}
char*
NdbConfig_NextTraceFileName(int node_id){
char *buf= NdbConfig_AllocHomePath(128);
char *buf= get_prefix_buf(128, node_id);
int len= strlen(buf);
snprintf(buf+len, 128, "ndb_%u_trace.log.next", node_id);
snprintf(buf+len, 128, "_trace.log.next");
return buf;
}
char*
NdbConfig_PidFileName(int node_id){
char *buf= NdbConfig_AllocHomePath(128);
char *buf= get_prefix_buf(128, node_id);
int len= strlen(buf);
snprintf(buf+len, 128, "ndb_%u.pid", node_id);
snprintf(buf+len, 128, ".pid");
return buf;
}
char*
NdbConfig_StdoutFileName(int node_id){
char *buf= NdbConfig_AllocHomePath(128);
char *buf= get_prefix_buf(128, node_id);
int len= strlen(buf);
snprintf(buf+len, 128, "ndb_%u_out.log", node_id);
snprintf(buf+len, 128, "_out.log");
return buf;
}
......@@ -139,7 +139,7 @@ ErrorReporter::formatMessage(ErrorCategory type,
objRef,
programName,
processId,
theNameOfTheTraceFile);
theNameOfTheTraceFile ? theNameOfTheTraceFile : "<no tracefile>");
// Add trailing blanks to get a fixed lenght of the message
while (strlen(messptr) <= MESSAGE_LENGTH-3){
......@@ -217,8 +217,10 @@ WriteMessage(ErrorCategory thrdType, int thrdMessageID,
/**
* Format trace file name
*/
int file_no= ErrorReporter::get_trace_no();
char *theTraceFileName= NdbConfig_TraceFileName(globalData.ownId, file_no);
char *theTraceFileName= 0;
if (globalData.ownId > 0)
theTraceFileName= NdbConfig_TraceFileName(globalData.ownId,
ErrorReporter::get_trace_no());
NdbAutoPtr<char> tmp_aptr1(theTraceFileName);
// The first 69 bytes is info about the current offset
......@@ -291,26 +293,28 @@ WriteMessage(ErrorCategory thrdType, int thrdMessageID,
fflush(stream);
fclose(stream);
// Open the tracefile...
FILE *jamStream = fopen(theTraceFileName, "w");
if (theTraceFileName) {
// Open the tracefile...
FILE *jamStream = fopen(theTraceFileName, "w");
// ...and "dump the jam" there.
// ErrorReporter::dumpJam(jamStream);
if(thrdTheEmulatedJam != 0){
dumpJam(jamStream, thrdTheEmulatedJamIndex, thrdTheEmulatedJam);
}
/* Dont print the jobBuffers until a way to copy them,
like the other variables,
is implemented. Otherwise when NDB keeps running,
with this function running
in the background, the jobBuffers will change during runtime. And when
they're printed here, they will not be correct anymore.
*/
globalScheduler.dumpSignalMemory(jamStream);
// ...and "dump the jam" there.
// ErrorReporter::dumpJam(jamStream);
if(thrdTheEmulatedJam != 0){
dumpJam(jamStream, thrdTheEmulatedJamIndex, thrdTheEmulatedJam);
}
fclose(jamStream);
/* Dont print the jobBuffers until a way to copy them,
like the other variables,
is implemented. Otherwise when NDB keeps running,
with this function running
in the background, the jobBuffers will change during runtime. And when
they're printed here, they will not be correct anymore.
*/
globalScheduler.dumpSignalMemory(jamStream);
fclose(jamStream);
}
return 0;
}
......
......@@ -403,14 +403,15 @@ ndb_mgm_disconnect(NdbMgmHandle handle)
struct ndb_mgm_type_atoi
{
const char * str;
const char * alias;
enum ndb_mgm_node_type value;
};
static struct ndb_mgm_type_atoi type_values[] =
{
{ "NDB", NDB_MGM_NODE_TYPE_NDB},
{ "API", NDB_MGM_NODE_TYPE_API },
{ "MGM", NDB_MGM_NODE_TYPE_MGM }
{ "NDB", "ndbd", NDB_MGM_NODE_TYPE_NDB},
{ "API", "mysqld", NDB_MGM_NODE_TYPE_API },
{ "MGM", "ndb_mgmd", NDB_MGM_NODE_TYPE_MGM }
};
const int no_of_type_values = (sizeof(type_values) /
......@@ -440,6 +441,20 @@ ndb_mgm_get_node_type_string(enum ndb_mgm_node_type type)
return 0;
}
extern "C"
const char *
ndb_mgm_get_node_type_alias_string(enum ndb_mgm_node_type type, const char** str)
{
for(int i = 0; i<no_of_type_values; i++)
if(type_values[i].value == type)
{
if (str)
*str= type_values[i].str;
return type_values[i].alias;
}
return 0;
}
struct ndb_mgm_status_atoi {
const char * str;
enum ndb_mgm_node_status value;
......
......@@ -584,8 +584,10 @@ MgmtSrvr::MgmtSrvr(NodeId nodeId,
_ownNodeId= 0;
NodeId tmp= nodeId;
if (!alloc_node_id(&tmp, NDB_MGM_NODE_TYPE_MGM, 0, 0)){
ndbout << "Unable to obtain requested nodeid " << nodeId;
BaseString error_string;
if (!alloc_node_id(&tmp, NDB_MGM_NODE_TYPE_MGM, 0, 0, error_string)){
ndbout << "Unable to obtain requested nodeid: "
<< error_string.c_str() << endl;
exit(-1);
}
_ownNodeId = tmp;
......@@ -606,17 +608,20 @@ MgmtSrvr::check_start()
}
bool
MgmtSrvr::start()
MgmtSrvr::start(BaseString &error_string)
{
if (_props == NULL) {
if (!check_start())
if (!check_start()) {
error_string.append("MgmtSrvr.cpp: check_start() failed.");
return false;
}
}
theFacade = TransporterFacade::start_instance
(_ownNodeId,(ndb_mgm_configuration*)_config->m_configValues);
if(theFacade == 0) {
DEBUG("MgmtSrvr.cpp: theFacade is NULL.");
error_string.append("MgmtSrvr.cpp: theFacade is NULL.");
return false;
}
......@@ -630,6 +635,7 @@ MgmtSrvr::start()
if(_blockNumber == -1){
DEBUG("MgmtSrvr.cpp: _blockNumber is -1.");
error_string.append("MgmtSrvr.cpp: _blockNumber is -1.");
theFacade->stop_instance();
theFacade = 0;
return false;
......@@ -2304,7 +2310,8 @@ bool
MgmtSrvr::alloc_node_id(NodeId * nodeId,
enum ndb_mgm_node_type type,
struct sockaddr *client_addr,
SOCKET_SIZE_TYPE *client_addr_len)
SOCKET_SIZE_TYPE *client_addr_len,
BaseString &error_string)
{
Guard g(&f_node_id_mutex);
#if 0
......@@ -2322,19 +2329,26 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId,
}
}
bool found_matching_id= false;
bool found_matching_type= false;
bool found_free_node= false;
unsigned type_c= 0;
ndb_mgm_configuration_iterator iter(*(ndb_mgm_configuration *)_config->m_configValues,
CFG_SECTION_NODE);
for(iter.first(); iter.valid(); iter.next()) {
unsigned tmp= 0;
if(iter.get(CFG_NODE_ID, &tmp)) abort();
if (connected_nodes.get(tmp))
continue;
if (*nodeId && *nodeId != tmp)
continue;
unsigned type_c;
found_matching_id= true;
if(iter.get(CFG_TYPE_OF_SECTION, &type_c)) abort();
if(type_c != type)
continue;
found_matching_type= true;
if (connected_nodes.get(tmp))
continue;
found_free_node= true;
const char *config_hostname = 0;
if(iter.get(CFG_NODE_HOST, &config_hostname)) abort();
......@@ -2374,6 +2388,43 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId,
#endif
return true;
}
BaseString type_string, type_c_string;
{
const char *alias, *str;
alias= ndb_mgm_get_node_type_alias_string(type, &str);
type_string.assfmt("%s(%s)", alias, str);
alias= ndb_mgm_get_node_type_alias_string((enum ndb_mgm_node_type)type_c, &str);
type_c_string.assfmt("%s(%s)", alias, str);
}
if (*nodeId == 0) {
if (found_matching_id)
if (found_matching_type)
if (found_free_node)
error_string.appfmt("Connection done from wrong host %s.",
inet_ntoa(((struct sockaddr_in *)(client_addr))->sin_addr));
else
error_string.appfmt("No free node id found for %s.", type_string.c_str());
else
error_string.appfmt("No %s node defined in config file.", type_string.c_str());
else
error_string.append("No nodes defined in config file.");
} else {
if (found_matching_id)
if (found_matching_type)
if (found_free_node)
error_string.appfmt("Connection with id %d done from wrong host %s, expected host XX.",
*nodeId, inet_ntoa(((struct sockaddr_in *)(client_addr))->sin_addr));
else
error_string.appfmt("Id %d already allocated by another node.", *nodeId);
else
error_string.appfmt("Id %d configured as %s, connect attempted as %s.",
*nodeId, type_c_string.c_str(), type_string.c_str());
else
error_string.appfmt("No node defined with id=%d in config file.", *nodeId);
}
return false;
}
......
......@@ -179,7 +179,7 @@ public:
* @return true if succeeded, otherwise false
*/
bool check_start(); // may be run before start to check that some things are ok
bool start();
bool start(BaseString &error_string);
~MgmtSrvr();
......@@ -467,7 +467,8 @@ public:
*/
bool getNextNodeId(NodeId * _nodeId, enum ndb_mgm_node_type type) const ;
bool alloc_node_id(NodeId * _nodeId, enum ndb_mgm_node_type type,
struct sockaddr *client_addr, SOCKET_SIZE_TYPE *client_addr_len);
struct sockaddr *client_addr, SOCKET_SIZE_TYPE *client_addr_len,
BaseString &error_string);
/**
*
......
......@@ -413,11 +413,14 @@ MgmApiSession::get_nodeid(Parser_t::Context &,
NodeId tmp= nodeid;
if(tmp == 0 || !m_allocated_resources->is_reserved(tmp)){
BaseString error_string;
if (!m_mgmsrv.alloc_node_id(&tmp, (enum ndb_mgm_node_type)nodetype,
&addr, &addrlen)){
&addr, &addrlen, error_string)){
const char *alias;
const char *str;
alias= ndb_mgm_get_node_type_alias_string((enum ndb_mgm_node_type)nodetype, &str);
m_output->println(cmd);
m_output->println("result: no free nodeid %d for nodetype %d",
nodeid, nodetype);
m_output->println("result: %s", error_string.c_str());
m_output->println("");
return;
}
......
......@@ -183,7 +183,7 @@ NDB_MAIN(mgmsrv){
if(!glob.socketServer->tryBind(glob.port, glob.interface_name)){
ndbout_c("Unable to setup port: %s:%d!\n"
"Please check if the port is already used,\n"
"(perhaps a mgmtsrvr is already running),\n"
"(perhaps a ndb_mgmd is already running),\n"
"and if you are executing on the correct computer",
(glob.interface_name ? glob.interface_name : "*"), glob.port);
goto error_end;
......@@ -195,7 +195,7 @@ NDB_MAIN(mgmsrv){
if(!glob.socketServer->setup(mapi, glob.port, glob.interface_name)){
ndbout_c("Unable to setup management port: %d!\n"
"Please check if the port is already used,\n"
"(perhaps a mgmtsrvr is already running),\n"
"(perhaps a ndb_mgmd is already running),\n"
"and if you are executing on the correct computer",
glob.port);
delete mapi;
......@@ -228,10 +228,14 @@ NDB_MAIN(mgmsrv){
}
signal(SIGPIPE, SIG_IGN);
if(!glob.mgmObject->start()){
ndbout_c("Unable to start management server.");
ndbout_c("Probably caused by illegal initial configuration file.");
goto error_end;
{
BaseString error_string;
if(!glob.mgmObject->start(error_string)){
ndbout_c("Unable to start management server.");
ndbout_c("Probably caused by illegal initial configuration file.");
ndbout_c(error_string.c_str());
goto error_end;
}
}
//glob.mgmObject->saveConfig();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment