void ClusterMgr::execAPI_REGCONF(const Uint32 * theData){ const ApiRegConf * const apiRegConf = (ApiRegConf *)&theData[0]; const NodeId nodeId = refToNode(apiRegConf->qmgrRef); #ifdef DEBUG_REG ndbout_c("ClusterMgr: Recd API_REGCONF from node %d", nodeId); #endif assert(nodeId > 0 && nodeId < MAX_NODES); Node & node = theNodes[nodeId]; assert(node.defined == true); assert(node.connected == true); if(node.m_info.m_version != apiRegConf->version){ node.m_info.m_version = apiRegConf->version; if(theNodes[theFacade.ownId()].m_info.m_type == NodeInfo::MGM) node.compatible = ndbCompatible_mgmt_ndb(NDB_VERSION, node.m_info.m_version); else node.compatible = ndbCompatible_api_ndb(NDB_VERSION, node.m_info.m_version); } node.m_api_reg_conf = true; node.m_state = apiRegConf->nodeState; if (node.compatible && (node.m_state.startLevel == NodeState::SL_STARTED || node.m_state.getSingleUserMode())){ set_node_alive(node, true); } else { set_node_alive(node, false); }//if node.m_info.m_heartbeat_cnt = 0; node.hbCounter = 0; if(waitingForHB) { waitForHBFromNodes.clear(nodeId); if(waitForHBFromNodes.isclear()) { waitingForHB= false; NdbCondition_Broadcast(waitForHBCond); } } node.hbFrequency = (apiRegConf->apiHeartbeatFrequency * 10) - 50; }
void MgmApiSession::getConfig(Parser_t::Context &, const class Properties &args) { Uint32 version, node = 0; args.get("version", &version); args.get("node", &node); const Config *conf = m_mgmsrv.getConfig(); if(conf == NULL) { m_output->println("get config reply"); m_output->println("result: Could not fetch configuration"); m_output->println(""); return; } if(node != 0){ bool compatible; switch (m_mgmsrv.getNodeType(node)) { case NDB_MGM_NODE_TYPE_NDB: compatible = ndbCompatible_mgmt_ndb(NDB_VERSION, version); break; case NDB_MGM_NODE_TYPE_API: case NDB_MGM_NODE_TYPE_MGM: compatible = ndbCompatible_mgmt_api(NDB_VERSION, version); break; default: m_output->println("get config"); m_output->println("result: unrecognignized node type"); m_output->println(""); return; } if (!compatible){ m_output->println("get config"); m_output->println("result: incompatible version mgmt 0x%x and node 0x%x", NDB_VERSION, version); m_output->println(""); return; } } NdbMutex_Lock(m_mgmsrv.m_configMutex); const ConfigValues * cfg = &conf->m_configValues->m_config; UtilBuffer src; cfg->pack(src); NdbMutex_Unlock(m_mgmsrv.m_configMutex); char *tmp_str = (char *) malloc(base64_needed_encoded_length(src.length())); (void) base64_encode(src.get_data(), src.length(), tmp_str); SLEEP_ERROR_INSERTED(1); m_output->println("get config reply"); m_output->println("result: Ok"); m_output->println("Content-Length: %d", strlen(tmp_str)); m_output->println("Content-Type: ndbconfig/octet-stream"); SLEEP_ERROR_INSERTED(2); m_output->println("Content-Transfer-Encoding: base64"); m_output->println(""); if(ERROR_INSERTED(3)) { int l= strlen(tmp_str); tmp_str[l/2]='\0'; m_output->println(tmp_str); NdbSleep_SecSleep(10); } m_output->println(tmp_str); free(tmp_str); return; }
void MgmApiSession::get_nodeid(Parser_t::Context &, const class Properties &args) { const char *cmd= "get nodeid reply"; Uint32 version, nodeid= 0, nodetype= 0xff; Uint32 timeout= 20; // default seconds timeout const char * transporter; const char * user; const char * password; const char * public_key; const char * endian= NULL; const char * name= NULL; Uint32 log_event= 1; bool log_event_version; union { long l; char c[sizeof(long)]; } endian_check; args.get("version", &version); args.get("nodetype", &nodetype); args.get("transporter", &transporter); args.get("nodeid", &nodeid); args.get("user", &user); args.get("password", &password); args.get("public key", &public_key); args.get("endian", &endian); args.get("name", &name); args.get("timeout", &timeout); /* for backwards compatability keep track if client uses new protocol */ log_event_version= args.get("log_event", &log_event); endian_check.l = 1; if(endian && strcmp(endian,(endian_check.c[sizeof(long)-1])?"big":"little")!=0) { m_output->println(cmd); m_output->println("result: Node does not have the same endianness as the management server."); m_output->println(""); return; } bool compatible; switch (nodetype) { case NODE_TYPE_MGM: case NODE_TYPE_API: compatible = ndbCompatible_mgmt_api(NDB_VERSION, version); break; case NODE_TYPE_DB: compatible = ndbCompatible_mgmt_ndb(NDB_VERSION, version); break; default: m_output->println(cmd); m_output->println("result: unknown nodetype %d", nodetype); m_output->println(""); return; } struct sockaddr_in addr; SOCKET_SIZE_TYPE addrlen= sizeof(addr); int r = getpeername(m_socket, (struct sockaddr*)&addr, &addrlen); if (r != 0 ) { m_output->println(cmd); m_output->println("result: getpeername(%d) failed, err= %d", m_socket, r); m_output->println(""); return; } NodeId tmp= nodeid; if(tmp == 0 || !m_allocated_resources->is_reserved(tmp)){ BaseString error_string; int error_code; NDB_TICKS tick= 0; /* only report error on second attempt as not to clog the cluster log */ while (!m_mgmsrv.alloc_node_id(&tmp, (enum ndb_mgm_node_type)nodetype, (struct sockaddr*)&addr, &addrlen, error_code, error_string, tick == 0 ? 0 : log_event)) { /* NDB_MGM_ALLOCID_CONFIG_MISMATCH is a non retriable error */ if (tick == 0 && error_code != NDB_MGM_ALLOCID_CONFIG_MISMATCH) { // attempt to free any timed out reservations tick= NdbTick_CurrentMillisecond(); struct PurgeStruct ps; m_mgmsrv.get_connected_nodes(ps.free_nodes); // invert connected_nodes to get free nodes ps.free_nodes.bitXORC(NodeBitmask()); ps.str= 0; ps.tick= tick; m_mgmsrv.get_socket_server()-> foreachSession(stop_session_if_timed_out,&ps); m_mgmsrv.get_socket_server()->checkSessions(); error_string = ""; continue; } 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: %s", error_string.c_str()); /* only use error_code protocol if client knows about it */ if (log_event_version) m_output->println("error_code: %d", error_code); m_output->println(""); return; } } #if 0 if (!compatible){ m_output->println(cmd); m_output->println("result: incompatible version mgmt 0x%x and node 0x%x", NDB_VERSION, version); m_output->println(""); return; } #endif m_output->println(cmd); m_output->println("nodeid: %u", tmp); m_output->println("result: Ok"); m_output->println(""); m_allocated_resources->reserve_node(tmp, timeout*1000); if (name) g_eventLogger.info("Node %d: %s", tmp, name); return; }
void ClusterMgr::execAPI_REGCONF(const NdbApiSignal * signal, const LinearSectionPtr ptr[]) { const ApiRegConf * apiRegConf = CAST_CONSTPTR(ApiRegConf, signal->getDataPtr()); const NodeId nodeId = refToNode(apiRegConf->qmgrRef); #ifdef DEBUG_REG ndbout_c("ClusterMgr: Recd API_REGCONF from node %d", nodeId); #endif assert(nodeId > 0 && nodeId < MAX_NODES); Node & cm_node = theNodes[nodeId]; trp_node & node = cm_node; assert(node.defined == true); assert(node.is_connected() == true); if(node.m_info.m_version != apiRegConf->version) { node.m_info.m_version = apiRegConf->version; node.m_info.m_mysql_version = apiRegConf->mysql_version; if (node.m_info.m_version < NDBD_SPLIT_VERSION) node.m_info.m_mysql_version = 0; if(theNodes[theFacade.ownId()].m_info.m_type == NodeInfo::MGM) node.compatible = ndbCompatible_mgmt_ndb(NDB_VERSION, node.m_info.m_version); else node.compatible = ndbCompatible_api_ndb(NDB_VERSION, node.m_info.m_version); } node.set_confirmed(true); if (node.minDbVersion != apiRegConf->minDbVersion) { node.minDbVersion = apiRegConf->minDbVersion; recalcMinDbVersion(); } if (node.m_info.m_version >= NDBD_255_NODES_VERSION) { node.m_state = apiRegConf->nodeState; } else { /** * from 2 to 8 words = 6 words diff, 6*4 = 24 */ memcpy(&node.m_state, &apiRegConf->nodeState, sizeof(node.m_state) - 24); } if (node.m_info.m_type == NodeInfo::DB) { /** * Only set DB nodes to "alive" */ if (node.compatible && (node.m_state.startLevel == NodeState::SL_STARTED || node.m_state.getSingleUserMode())) { set_node_alive(node, true); } else { set_node_alive(node, false); } } cm_node.hbMissed = 0; cm_node.hbCounter = 0; /* By convention, conf->apiHeartbeatFrequency is in centiseconds rather than milliseconds. See also Qmgr::sendApiRegConf(). */ const Int64 freq = (static_cast<Int64>(apiRegConf->apiHeartbeatFrequency) * 10) - 50; if (freq > UINT_MAX32) { // In case of overflow. assert(false); /* Note this assert fails on some upgrades... */ cm_node.hbFrequency = UINT_MAX32; } else if (freq < minHeartBeatInterval) { /** * We use minHeartBeatInterval as a lower limit. This also prevents * against underflow. */ cm_node.hbFrequency = minHeartBeatInterval; } else { cm_node.hbFrequency = static_cast<Uint32>(freq); } // If responding nodes indicates that it is connected to other // nodes, that makes it probable that those nodes are alive and // available also for this node. for (int db_node_id = 1; db_node_id <= MAX_DATA_NODE_ID; db_node_id ++) { if (node.m_state.m_connected_nodes.get(db_node_id)) { // Tell this nodes start clients thread that db_node_id // is up and probable connectable. theFacade.theTransporterRegistry->indicate_node_up(db_node_id); } } // Distribute signal to all threads/blocks // TODO only if state changed... theFacade.for_each(this, signal, ptr); }
void ClusterMgr::execAPI_REGCONF(const NdbApiSignal * signal, const LinearSectionPtr ptr[]) { const ApiRegConf * apiRegConf = CAST_CONSTPTR(ApiRegConf, signal->getDataPtr()); const NodeId nodeId = refToNode(apiRegConf->qmgrRef); #ifdef DEBUG_REG ndbout_c("ClusterMgr: Recd API_REGCONF from node %d", nodeId); #endif assert(nodeId > 0 && nodeId < MAX_NODES); Node & cm_node = theNodes[nodeId]; trp_node & node = cm_node; assert(node.defined == true); assert(node.is_connected() == true); if(node.m_info.m_version != apiRegConf->version){ node.m_info.m_version = apiRegConf->version; node.m_info.m_mysql_version = apiRegConf->mysql_version; if (node.m_info.m_version < NDBD_SPLIT_VERSION) node.m_info.m_mysql_version = 0; if(theNodes[theFacade.ownId()].m_info.m_type == NodeInfo::MGM) node.compatible = ndbCompatible_mgmt_ndb(NDB_VERSION, node.m_info.m_version); else node.compatible = ndbCompatible_api_ndb(NDB_VERSION, node.m_info.m_version); } node.set_confirmed(true); if (node.minDbVersion != apiRegConf->minDbVersion) { node.minDbVersion = apiRegConf->minDbVersion; recalcMinDbVersion(); } if (node.m_info.m_version >= NDBD_255_NODES_VERSION) { node.m_state = apiRegConf->nodeState; } else { /** * from 2 to 8 words = 6 words diff, 6*4 = 24 */ memcpy(&node.m_state, &apiRegConf->nodeState, sizeof(node.m_state) - 24); } if (node.m_info.m_type == NodeInfo::DB) { /** * Only set DB nodes to "alive" */ if (node.compatible && (node.m_state.startLevel == NodeState::SL_STARTED || node.m_state.getSingleUserMode())) { set_node_alive(node, true); } else { set_node_alive(node, false); } } cm_node.hbMissed = 0; cm_node.hbCounter = 0; cm_node.hbFrequency = (apiRegConf->apiHeartbeatFrequency * 10) - 50; // Distribute signal to all threads/blocks // TODO only if state changed... theFacade.for_each(this, signal, ptr); check_wait_for_hb(nodeId); }