void TCP_Transporter::setSocketOptions(){ int sockOptKeepAlive = 1; if (setsockopt(theSocket, SOL_SOCKET, SO_RCVBUF, (char*)&sockOptRcvBufSize, sizeof(sockOptRcvBufSize)) < 0) { #ifdef DEBUG_TRANSPORTER g_eventLogger.error("The setsockopt SO_RCVBUF error code = %d", InetErrno); #endif }//if if (setsockopt(theSocket, SOL_SOCKET, SO_SNDBUF, (char*)&sockOptSndBufSize, sizeof(sockOptSndBufSize)) < 0) { #ifdef DEBUG_TRANSPORTER g_eventLogger.error("The setsockopt SO_SNDBUF error code = %d", InetErrno); #endif }//if if (setsockopt(theSocket, SOL_SOCKET, SO_KEEPALIVE, (char*)&sockOptKeepAlive, sizeof(sockOptKeepAlive)) < 0) { ndbout_c("The setsockopt SO_KEEPALIVE error code = %d", InetErrno); }//if //----------------------------------------------- // Set the TCP_NODELAY option so also small packets are sent // as soon as possible //----------------------------------------------- if (setsockopt(theSocket, IPPROTO_TCP, TCP_NODELAY, (char*)&sockOptNodelay, sizeof(sockOptNodelay)) < 0) { #ifdef DEBUG_TRANSPORTER g_eventLogger.error("The setsockopt TCP_NODELAY error code = %d", InetErrno); #endif }//if }
int TCP_Transporter::doReceive() { // Select-function must return the socket for read // before this method is called // It reads the external TCP/IP interface once Uint32 size = receiveBuffer.sizeOfBuffer - receiveBuffer.sizeOfData; if(size > 0){ const int nBytesRead = recv(theSocket, receiveBuffer.insertPtr, size < maxReceiveSize ? size : maxReceiveSize, 0); if (nBytesRead > 0) { receiveBuffer.sizeOfData += nBytesRead; receiveBuffer.insertPtr += nBytesRead; if(receiveBuffer.sizeOfData > receiveBuffer.sizeOfBuffer){ #ifdef DEBUG_TRANSPORTER g_eventLogger.error("receiveBuffer.sizeOfData(%d) > receiveBuffer.sizeOfBuffer(%d)", receiveBuffer.sizeOfData, receiveBuffer.sizeOfBuffer); g_eventLogger.error("nBytesRead = %d", nBytesRead); #endif g_eventLogger.error("receiveBuffer.sizeOfData(%d) > receiveBuffer.sizeOfBuffer(%d)", receiveBuffer.sizeOfData, receiveBuffer.sizeOfBuffer); report_error(TE_INVALID_MESSAGE_LENGTH); return 0; } receiveCount ++; receiveSize += nBytesRead; if(receiveCount == reportFreq){ reportReceiveLen(get_callback_obj(), remoteNodeId, receiveCount, receiveSize); receiveCount = 0; receiveSize = 0; } return nBytesRead; } else { #if defined DEBUG_TRANSPORTER g_eventLogger.error("Receive Failure(disconnect==%d) to node = %d nBytesSent = %d " "errno = %d strerror = %s", DISCONNECT_ERRNO(InetErrno, nBytesRead), remoteNodeId, nBytesRead, InetErrno, (char*)ndbstrerror(InetErrno)); #endif if(DISCONNECT_ERRNO(InetErrno, nBytesRead)){ // The remote node has closed down doDisconnect(); report_disconnect(InetErrno); } } return nBytesRead; } else { return 0; } }
void Cmvmi::execSTTOR(Signal* signal) { Uint32 theStartPhase = signal->theData[1]; jamEntry(); if (theStartPhase == 1){ jam(); if(m_ctx.m_config.lockPagesInMainMemory() == 1) { int res = NdbMem_MemLockAll(0); if(res != 0){ g_eventLogger.warning("Failed to memlock pages"); warningEvent("Failed to memlock pages"); } } sendSTTORRY(signal); return; } else if (theStartPhase == 3) { jam(); globalData.activateSendPacked = 1; sendSTTORRY(signal); } else if (theStartPhase == 8){ /*---------------------------------------------------*/ /* Open com to API + REP nodes */ /*---------------------------------------------------*/ signal->theData[0] = 0; // no answer signal->theData[1] = 0; // no id signal->theData[2] = NodeInfo::API; execOPEN_COMREQ(signal); globalData.theStartLevel = NodeState::SL_STARTED; sendSTTORRY(signal); } }
void TransporterRegistry::startReceiving() { DBUG_ENTER("TransporterRegistry::startReceiving"); #ifdef NDB_SHM_TRANSPORTER m_shm_own_pid = getpid(); if (g_ndb_shm_signum) { DBUG_PRINT("info",("Install signal handler for signum %d", g_ndb_shm_signum)); struct sigaction sa; NdbThread_set_shm_sigmask(FALSE); sigemptyset(&sa.sa_mask); sa.sa_handler = shm_sig_handler; sa.sa_flags = 0; int ret; while((ret = sigaction(g_ndb_shm_signum, &sa, 0)) == -1 && errno == EINTR); if(ret != 0) { DBUG_PRINT("error",("Install failed")); g_eventLogger.error("Failed to install signal handler for" " SHM transporter, signum %d, errno: %d (%s)", g_ndb_shm_signum, errno, strerror(errno)); } } #endif // NDB_SHM_TRANSPORTER DBUG_VOID_RETURN; }
bool TransporterRegistry::start_service(SocketServer& socket_server) { DBUG_ENTER("TransporterRegistry::start_service"); if (m_transporter_interface.size() > 0 && !nodeIdSpecified) { g_eventLogger.error("TransporterRegistry::startReceiving: localNodeId not specified"); DBUG_RETURN(false); } for (unsigned i= 0; i < m_transporter_interface.size(); i++) { Transporter_interface &t= m_transporter_interface[i]; unsigned short port= (unsigned short)t.m_s_service_port; if(t.m_s_service_port<0) port= -t.m_s_service_port; // is a dynamic port TransporterService *transporter_service = new TransporterService(new SocketAuthSimple("ndbd", "ndbd passwd")); if(!socket_server.setup(transporter_service, &port, t.m_interface)) { DBUG_PRINT("info", ("Trying new port")); port= 0; if(t.m_s_service_port>0 || !socket_server.setup(transporter_service, &port, t.m_interface)) { /* * If it wasn't a dynamically allocated port, or * our attempts at getting a new dynamic port failed */ g_eventLogger.error("Unable to setup transporter service port: %s:%d!\n" "Please check if the port is already used,\n" "(perhaps the node is already running)", t.m_interface ? t.m_interface : "*", t.m_s_service_port); delete transporter_service; DBUG_RETURN(false); } } t.m_s_service_port= (t.m_s_service_port<=0)?-port:port; // -`ve if dynamic DBUG_PRINT("info", ("t.m_s_service_port = %d",t.m_s_service_port)); transporter_service->setTransporterRegistry(this); } DBUG_RETURN(true); }
bool TCP_Transporter::setSocketNonBlocking(NDB_SOCKET_TYPE socket){ int flags; flags = fcntl(socket, F_GETFL, 0); if (flags < 0) { #ifdef DEBUG_TRANSPORTER g_eventLogger.error("Set non-blocking server error1: %s", strerror(InetErrno)); #endif }//if flags |= NDB_NONBLOCK; if (fcntl(socket, F_SETFL, flags) == -1) { #ifdef DEBUG_TRANSPORTER g_eventLogger.error("Set non-blocking server error2: %s", strerror(InetErrno)); #endif }//if return true; }
Uint32 TransporterRegistry::poll_TCP(Uint32 timeOutMillis) { bool hasdata = false; if (false && nTCPTransporters == 0) { tcpReadSelectReply = 0; return 0; } NDB_SOCKET_TYPE maxSocketValue = -1; // Needed for TCP/IP connections // The read- and writeset are used by select FD_ZERO(&tcpReadset); // Prepare for sending and receiving for (int i = 0; i < nTCPTransporters; i++) { TCP_Transporter * t = theTCPTransporters[i]; // If the transporter is connected NodeId nodeId = t->getRemoteNodeId(); if (is_connected(nodeId) && t->isConnected()) { const NDB_SOCKET_TYPE socket = t->getSocket(); // Find the highest socket value. It will be used by select if (socket > maxSocketValue) maxSocketValue = socket; // Put the connected transporters in the socket read-set FD_SET(socket, &tcpReadset); } hasdata |= t->hasReceiveData(); } timeOutMillis = hasdata ? 0 : timeOutMillis; struct timeval timeout; timeout.tv_sec = timeOutMillis / 1000; timeout.tv_usec = (timeOutMillis % 1000) * 1000; // The highest socket value plus one maxSocketValue++; tcpReadSelectReply = select(maxSocketValue, &tcpReadset, 0, 0, &timeout); if(false && tcpReadSelectReply == -1 && errno == EINTR) g_eventLogger.info("woke-up by signal"); #ifdef NDB_WIN32 if(tcpReadSelectReply == SOCKET_ERROR) { NdbSleep_MilliSleep(timeOutMillis); } #endif return tcpReadSelectReply || hasdata; }
bool TCP_Transporter::doSend() { // If no sendbuffers are used nothing is done // Sends the contents of the SendBuffers until they are empty // or until select does not select the socket for write. // Before calling send, the socket must be selected for write // using "select" // It writes on the external TCP/IP interface until the send buffer is empty // and as long as write is possible (test it using select) // Empty the SendBuffers bool sent_any = true; while (m_sendBuffer.dataSize > 0) { const char * const sendPtr = m_sendBuffer.sendPtr; const Uint32 sizeToSend = m_sendBuffer.sendDataSize; const int nBytesSent = send(theSocket, sendPtr, sizeToSend, 0); if (nBytesSent > 0) { sent_any = true; m_sendBuffer.bytesSent(nBytesSent); sendCount ++; sendSize += nBytesSent; if(sendCount == reportFreq) { reportSendLen(get_callback_obj(), remoteNodeId, sendCount, sendSize); sendCount = 0; sendSize = 0; } } else { if (nBytesSent < 0 && InetErrno == EAGAIN && sent_any) break; // Send failed #if defined DEBUG_TRANSPORTER g_eventLogger.error("Send Failure(disconnect==%d) to node = %d nBytesSent = %d " "errno = %d strerror = %s", DISCONNECT_ERRNO(InetErrno, nBytesSent), remoteNodeId, nBytesSent, InetErrno, (char*)ndbstrerror(InetErrno)); #endif if(DISCONNECT_ERRNO(InetErrno, nBytesSent)){ doDisconnect(); report_disconnect(InetErrno); } return false; } } return true; }
Ndb_cluster_connection_impl::Ndb_cluster_connection_impl(const char * connect_string) : Ndb_cluster_connection(*this), m_optimized_node_selection(1), m_name(0) { DBUG_ENTER("Ndb_cluster_connection"); DBUG_PRINT("enter",("Ndb_cluster_connection this=0x%lx", (long) this)); g_eventLogger.createConsoleHandler(); g_eventLogger.setCategory("NdbApi"); g_eventLogger.enable(Logger::LL_ON, Logger::LL_ERROR); m_connect_thread= 0; m_connect_callback= 0; if (ndb_global_event_buffer_mutex == NULL) ndb_global_event_buffer_mutex= NdbMutex_Create(); #ifdef VM_TRACE if (ndb_print_state_mutex == NULL) ndb_print_state_mutex= NdbMutex_Create(); #endif m_config_retriever= new ConfigRetriever(connect_string, NDB_VERSION, NODE_TYPE_API); if (m_config_retriever->hasError()) { printf("Could not connect initialize handle to management server: %s", m_config_retriever->getErrorString()); delete m_config_retriever; m_config_retriever= 0; } if (m_name) { NdbMgmHandle h= m_config_retriever->get_mgmHandle(); ndb_mgm_set_name(h, m_name); } m_transporter_facade= TransporterFacade::theFacadeInstance= new TransporterFacade(); DBUG_VOID_RETURN; }
bool TransporterRegistry::connect_client(NdbMgmHandle *h) { DBUG_ENTER("TransporterRegistry::connect_client(NdbMgmHandle)"); Uint32 mgm_nodeid= ndb_mgm_get_mgmd_nodeid(*h); if(!mgm_nodeid) { g_eventLogger.error("%s: %d", __FILE__, __LINE__); return false; } Transporter * t = theTransporters[mgm_nodeid]; if (!t) { g_eventLogger.error("%s: %d", __FILE__, __LINE__); return false; } DBUG_RETURN(t->connect_client(connect_ndb_mgmd(h))); }
/** * Given a connected NdbMgmHandle, turns it into a transporter * and returns the socket. */ NDB_SOCKET_TYPE TransporterRegistry::connect_ndb_mgmd(NdbMgmHandle *h) { struct ndb_mgm_reply mgm_reply; if ( h==NULL || *h == NULL ) { g_eventLogger.error("%s: %d", __FILE__, __LINE__); return NDB_INVALID_SOCKET; } for(unsigned int i=0;i < m_transporter_interface.size();i++) if (m_transporter_interface[i].m_s_service_port < 0 && ndb_mgm_set_connection_int_parameter(*h, get_localNodeId(), m_transporter_interface[i].m_remote_nodeId, CFG_CONNECTION_SERVER_PORT, m_transporter_interface[i].m_s_service_port, &mgm_reply) < 0) { g_eventLogger.error("Error: %s: %d", ndb_mgm_get_latest_error_desc(*h), ndb_mgm_get_latest_error(*h)); g_eventLogger.error("%s: %d", __FILE__, __LINE__); ndb_mgm_destroy_handle(h); return NDB_INVALID_SOCKET; } /** * convert_to_transporter also disposes of the handle (i.e. we don't leak * memory here. */ NDB_SOCKET_TYPE sockfd= ndb_mgm_convert_to_transporter(h); if ( sockfd == NDB_INVALID_SOCKET) { g_eventLogger.error("Error: %s: %d", ndb_mgm_get_latest_error_desc(*h), ndb_mgm_get_latest_error(*h)); g_eventLogger.error("%s: %d", __FILE__, __LINE__); ndb_mgm_destroy_handle(h); } return sockfd; }
bool TCP_Transporter::setSocketNonBlocking(NDB_SOCKET_TYPE socket){ unsigned long ul = 1; if(ioctlsocket(socket, FIONBIO, &ul)) { #ifdef DEBUG_TRANSPORTER g_eventLogger.error("Set non-blocking server error3: %d", InetErrno); #endif }//if return true; }
void ErrorReporter::handleError(int messageID, const char* problemData, const char* objRef, NdbShutdownType nst) { WriteMessage(messageID, problemData, objRef, theEmulatedJamIndex, theEmulatedJam); g_eventLogger.info(problemData); g_eventLogger.info(objRef); childReportError(messageID); if(messageID == NDBD_EXIT_ERROR_INSERT){ NdbShutdown(NST_ErrorInsert); } else { if (nst == NST_ErrorHandler) nst = s_errorHandlerShutdownType; NdbShutdown(nst); } }
void Cmvmi::execEVENT_REP(Signal* signal) { //----------------------------------------------------------------------- // This message is sent to report any types of events in NDB. // Based on the log level they will be either ignored or // reported. Currently they are printed, but they will be // transferred to the management server for further distribution // to the graphical management interface. //----------------------------------------------------------------------- EventReport * const eventReport = (EventReport *)&signal->theData[0]; Ndb_logevent_type eventType = eventReport->getEventType(); Uint32 nodeId= eventReport->getNodeId(); if (nodeId == 0) { nodeId= refToNode(signal->getSendersBlockRef()); eventReport->setNodeId(nodeId); } jamEntry(); /** * If entry is not found */ Uint32 threshold; LogLevel::EventCategory eventCategory; Logger::LoggerLevel severity; EventLoggerBase::EventTextFunction textF; if (EventLoggerBase::event_lookup(eventType,eventCategory,threshold,severity,textF)) return; SubscriberPtr ptr; for(subscribers.first(ptr); ptr.i != RNIL; subscribers.next(ptr)){ if(ptr.p->logLevel.getLogLevel(eventCategory) < threshold){ continue; } sendSignal(ptr.p->blockRef, GSN_EVENT_REP, signal, signal->length(), JBB); } if(clogLevel.getLogLevel(eventCategory) < threshold){ return; } // Print the event info g_eventLogger.log(eventReport->getEventType(), signal->theData); return; }//execEVENT_REP()
/***************************************************************************** * ~Ndb(); * * Remark: Disconnect with the database. *****************************************************************************/ Ndb::~Ndb() { DBUG_ENTER("Ndb::~Ndb()"); DBUG_PRINT("enter",("this: 0x%lx", (long) this)); if (m_sys_tab_0) getDictionary()->removeTableGlobal(*m_sys_tab_0, 0); assert(theImpl->m_ev_op == 0); // user should return NdbEventOperation's for (NdbEventOperationImpl *op= theImpl->m_ev_op; op; op=op->m_next) { if (op->m_state == NdbEventOperation::EO_EXECUTING && op->stop()) g_eventLogger.error("stopping NdbEventOperation failed in Ndb destructor"); op->m_magic_number= 0; } doDisconnect(); /* Disconnect from transporter to stop signals from coming in */ if (theImpl->m_transporter_facade != NULL && theNdbBlockNumber > 0) { theImpl->m_transporter_facade->close(theNdbBlockNumber, theFirstTransId); } delete theEventBuffer; releaseTransactionArrays(); delete []theConnectionArray; if(theCommitAckSignal != NULL) { delete theCommitAckSignal; theCommitAckSignal = NULL; } delete theImpl; #ifdef POORMANSPURIFY #ifdef POORMANSGUI ndbout << "cnewSignals=" << cnewSignals << endl; ndbout << "cfreeSignals=" << cfreeSignals << endl; ndbout << "cgetSignals=" << cgetSignals << endl; ndbout << "creleaseSignals=" << creleaseSignals << endl; #endif // Poor mans purifier assert(cnewSignals == cfreeSignals); assert(cgetSignals == creleaseSignals); #endif DBUG_VOID_RETURN; }
void DataCollectorSolver::logQueryStats(const Query &query, QueryType type, TimeValue start, Solver::Validity validity) { int result; TimeValue duration = TimeValue::now() - start; std::string query_blob; std::pair<uint64_t, uint64_t> qids = serializer_.Serialize(query, query_blob); // Query structure sqlite3_clear_bindings(qinsert_stmt_); sqlite3_bind_int64(qinsert_stmt_, 1, qids.first); if (qids.second) { sqlite3_bind_int64(qinsert_stmt_, 2, qids.second); } sqlite3_bind_int64(qinsert_stmt_, 14, event_logger_->logEvent(g_s2e_state, EVENT_KLEE_QUERY, 1)); sqlite3_bind_int(qinsert_stmt_, 3, query.constraints.head()->depth()); sqlite3_bind_blob(qinsert_stmt_, 4, query_blob.c_str(), query_blob.size(), NULL); sqlite3_bind_int(qinsert_stmt_, 5, static_cast<int>(type)); result = sqlite3_step(qinsert_stmt_); assert(result == SQLITE_DONE); sqlite3_reset(qinsert_stmt_); // Query results sqlite3_bind_int64(rinsert_stmt_, 1, qids.first); sqlite3_bind_int64(rinsert_stmt_, 2, duration.usec()); if (type == TRUTH || type == VALIDITY) { sqlite3_bind_int(rinsert_stmt_, 3, static_cast<int>(validity)); } result = sqlite3_step(rinsert_stmt_); assert(result == SQLITE_DONE); sqlite3_reset(rinsert_stmt_); }
/* * MAIN */ int main(int argc, char** argv) { NDB_INIT(argv[0]); load_defaults("my",load_default_groups,&argc,&argv); int ho_error; #ifndef DBUG_OFF opt_debug= "d:t:O,/tmp/ndb_mgmd.trace"; #endif if ((ho_error=handle_options(&argc, &argv, my_long_options, ndb_std_get_one_option))) exit(ho_error); start: glob= new MgmGlobals; /** * OSE specific. Enable shared ownership of file system resources. * This is needed in order to use the cluster log since the events * from the cluster is written from the 'ndb_receive'(NDBAPI) thread/process. */ #if defined NDB_OSE || defined NDB_SOFTOSE efs_segment_share(); #endif global_mgmt_server_check = 1; if (opt_interactive || opt_non_interactive || g_print_full_config) { opt_daemon= 0; } if (opt_mycnf && opt_config_filename) { ndbout_c("Both --mycnf and -f is not supported"); return 0; } if (opt_mycnf == 0 && opt_config_filename == 0) { struct stat buf; if (stat("config.ini", &buf) != -1) opt_config_filename = "config.ini"; } glob->socketServer = new SocketServer(); MgmApiService * mapi = new MgmApiService(); glob->mgmObject = new MgmtSrvr(glob->socketServer, opt_config_filename, opt_connect_str); if (g_print_full_config) goto the_end; if (glob->mgmObject->init()) goto error_end; my_setwd(NdbConfig_get_path(0), MYF(0)); glob->localNodeId= glob->mgmObject->getOwnNodeId(); if (glob->localNodeId == 0) { goto error_end; } glob->port= glob->mgmObject->getPort(); if (glob->port == 0) goto error_end; glob->interface_name = 0; glob->use_specific_ip = false; if(!glob->use_specific_ip){ int count= 5; // no of retries for tryBind while(!glob->socketServer->tryBind(glob->port, glob->interface_name)){ if (--count > 0) { NdbSleep_MilliSleep(1000); continue; } ndbout_c("Unable to setup port: %s:%d!\n" "Please check if the port is already used,\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; } free(glob->interface_name); glob->interface_name = 0; } 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 ndb_mgmd is already running),\n" "and if you are executing on the correct computer", glob->port); delete mapi; goto error_end; } if(!glob->mgmObject->check_start()){ ndbout_c("Unable to check start management server."); ndbout_c("Probably caused by illegal initial configuration file."); goto error_end; } if (opt_daemon) { // Become a daemon char *lockfile= NdbConfig_PidFileName(glob->localNodeId); char *logfile= NdbConfig_StdoutFileName(glob->localNodeId); NdbAutoPtr<char> tmp_aptr1(lockfile), tmp_aptr2(logfile); if (NdbDaemon_Make(lockfile, logfile, 0) == -1) { ndbout << "Cannot become daemon: " << NdbDaemon_ErrorText << endl; return 1; } } #ifndef NDB_WIN32 signal(SIGPIPE, SIG_IGN); #endif { 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(); mapi->setMgm(glob->mgmObject); char msg[256]; BaseString::snprintf(msg, sizeof(msg), "NDB Cluster Management Server. %s", NDB_VERSION_STRING); ndbout_c(msg); g_eventLogger.info(msg); BaseString::snprintf(msg, 256, "Id: %d, Command port: %d", glob->localNodeId, glob->port); ndbout_c(msg); g_eventLogger.info(msg); g_StopServer = false; g_RestartServer= false; glob->socketServer->startServer(); #if ! defined NDB_OSE && ! defined NDB_SOFTOSE if(opt_interactive) { BaseString con_str; if(glob->interface_name) con_str.appfmt("host=%s:%d", glob->interface_name, glob->port); else con_str.appfmt("localhost:%d", glob->port); Ndb_mgmclient com(con_str.c_str(), 1); while(g_StopServer != true && read_and_execute(&com, "ndb_mgm> ", 1)); } else #endif { while(g_StopServer != true) NdbSleep_MilliSleep(500); } if(g_RestartServer) g_eventLogger.info("Restarting server..."); else g_eventLogger.info("Shutting down server..."); glob->socketServer->stopServer(); // We disconnect from the ConfigRetreiver mgmd when we delete glob below glob->socketServer->stopSessions(true); g_eventLogger.info("Shutdown complete"); the_end: delete glob; if(g_RestartServer) goto start; ndb_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0); return 0; error_end: delete glob; ndb_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0); return 1; }
bool Transporter::connect_client(NDB_SOCKET_TYPE sockfd) { if(m_connected) return true; if (sockfd == NDB_INVALID_SOCKET) return false; DBUG_ENTER("Transporter::connect_client"); DBUG_PRINT("info",("port %d isMgmConnection=%d",m_s_port,isMgmConnection)); SocketOutputStream s_output(sockfd); SocketInputStream s_input(sockfd); // send info about own id // send info about own transporter type s_output.println("%d %d", localNodeId, m_type); // get remote id int nodeId, remote_transporter_type= -1; char buf[256]; if (s_input.gets(buf, 256) == 0) { NDB_CLOSE_SOCKET(sockfd); DBUG_RETURN(false); } int r= sscanf(buf, "%d %d", &nodeId, &remote_transporter_type); switch (r) { case 2: break; case 1: // we're running version prior to 4.1.9 // ok, but with no checks on transporter configuration compatability break; default: NDB_CLOSE_SOCKET(sockfd); DBUG_RETURN(false); } DBUG_PRINT("info", ("nodeId=%d remote_transporter_type=%d", nodeId, remote_transporter_type)); if (remote_transporter_type != -1) { if (remote_transporter_type != m_type) { DBUG_PRINT("error", ("Transporter types mismatch this=%d remote=%d", m_type, remote_transporter_type)); NDB_CLOSE_SOCKET(sockfd); g_eventLogger.error("Incompatible configuration: transporter type " "mismatch with node %d", nodeId); DBUG_RETURN(false); } } else if (m_type == tt_SHM_TRANSPORTER) { g_eventLogger.warning("Unable to verify transporter compatability with node %d", nodeId); } { struct sockaddr_in addr; SOCKET_SIZE_TYPE addrlen= sizeof(addr); getpeername(sockfd, (struct sockaddr*)&addr, &addrlen); m_connect_address= (&addr)->sin_addr; } bool res = connect_client_impl(sockfd); if(res){ m_connected = true; m_errorCount = 0; } DBUG_RETURN(res); }
Ndb_cluster_connection_impl::Ndb_cluster_connection_impl(const char * connect_string) : Ndb_cluster_connection(*this), m_optimized_node_selection(1), m_name(0), m_run_connect_thread(0), m_event_add_drop_mutex(0), m_latest_trans_gci(0) { DBUG_ENTER("Ndb_cluster_connection"); DBUG_PRINT("enter",("Ndb_cluster_connection this=0x%lx", (long) this)); if (!m_event_add_drop_mutex) m_event_add_drop_mutex= NdbMutex_Create(); g_eventLogger.createConsoleHandler(); g_eventLogger.setCategory("NdbApi"); g_eventLogger.enable(Logger::LL_ON, Logger::LL_ERROR); m_connect_thread= 0; m_connect_callback= 0; #ifdef VM_TRACE if (ndb_print_state_mutex == NULL) ndb_print_state_mutex= NdbMutex_Create(); #endif m_config_retriever= new ConfigRetriever(connect_string, NDB_VERSION, NODE_TYPE_API); if (m_config_retriever->hasError()) { printf("Could not initialize handle to management server: %s\n", m_config_retriever->getErrorString()); delete m_config_retriever; m_config_retriever= 0; } if (m_name) { NdbMgmHandle h= m_config_retriever->get_mgmHandle(); ndb_mgm_set_name(h, m_name); } m_transporter_facade= new TransporterFacade(); NdbMutex_Lock(g_ndb_connection_mutex); if(g_ndb_connection_count++ == 0){ NdbDictionary::Column::FRAGMENT= NdbColumnImpl::create_pseudo("NDB$FRAGMENT"); NdbDictionary::Column::FRAGMENT_FIXED_MEMORY= NdbColumnImpl::create_pseudo("NDB$FRAGMENT_FIXED_MEMORY"); NdbDictionary::Column::FRAGMENT_VARSIZED_MEMORY= NdbColumnImpl::create_pseudo("NDB$FRAGMENT_VARSIZED_MEMORY"); NdbDictionary::Column::ROW_COUNT= NdbColumnImpl::create_pseudo("NDB$ROW_COUNT"); NdbDictionary::Column::COMMIT_COUNT= NdbColumnImpl::create_pseudo("NDB$COMMIT_COUNT"); NdbDictionary::Column::ROW_SIZE= NdbColumnImpl::create_pseudo("NDB$ROW_SIZE"); NdbDictionary::Column::RANGE_NO= NdbColumnImpl::create_pseudo("NDB$RANGE_NO"); NdbDictionary::Column::DISK_REF= NdbColumnImpl::create_pseudo("NDB$DISK_REF"); NdbDictionary::Column::RECORDS_IN_RANGE= NdbColumnImpl::create_pseudo("NDB$RECORDS_IN_RANGE"); NdbDictionary::Column::ROWID= NdbColumnImpl::create_pseudo("NDB$ROWID"); NdbDictionary::Column::ROW_GCI= NdbColumnImpl::create_pseudo("NDB$ROW_GCI"); NdbDictionary::Column::ANY_VALUE= NdbColumnImpl::create_pseudo("NDB$ANY_VALUE"); NdbDictionary::Column::COPY_ROWID= NdbColumnImpl::create_pseudo("NDB$COPY_ROWID"); } NdbMutex_Unlock(g_ndb_connection_mutex); DBUG_VOID_RETURN; }
bool TransporterRegistry::connect_server(NDB_SOCKET_TYPE sockfd) { DBUG_ENTER("TransporterRegistry::connect_server"); // read node id from client // read transporter type int nodeId, remote_transporter_type= -1; SocketInputStream s_input(sockfd); char buf[256]; if (s_input.gets(buf, 256) == 0) { DBUG_PRINT("error", ("Could not get node id from client")); DBUG_RETURN(false); } int r= sscanf(buf, "%d %d", &nodeId, &remote_transporter_type); switch (r) { case 2: break; case 1: // we're running version prior to 4.1.9 // ok, but with no checks on transporter configuration compatability break; default: DBUG_PRINT("error", ("Error in node id from client")); DBUG_RETURN(false); } DBUG_PRINT("info", ("nodeId=%d remote_transporter_type=%d", nodeId,remote_transporter_type)); //check that nodeid is valid and that there is an allocated transporter if ( nodeId < 0 || nodeId >= (int)maxTransporters) { DBUG_PRINT("error", ("Node id out of range from client")); DBUG_RETURN(false); } if (theTransporters[nodeId] == 0) { DBUG_PRINT("error", ("No transporter for this node id from client")); DBUG_RETURN(false); } //check that the transporter should be connected if (performStates[nodeId] != TransporterRegistry::CONNECTING) { DBUG_PRINT("error", ("Transporter in wrong state for this node id from client")); DBUG_RETURN(false); } Transporter *t= theTransporters[nodeId]; // send info about own id (just as response to acknowledge connection) // send info on own transporter type SocketOutputStream s_output(sockfd); s_output.println("%d %d", t->getLocalNodeId(), t->m_type); if (remote_transporter_type != -1) { if (remote_transporter_type != t->m_type) { DBUG_PRINT("error", ("Transporter types mismatch this=%d remote=%d", t->m_type, remote_transporter_type)); g_eventLogger.error("Incompatible configuration: Transporter type " "mismatch with node %d", nodeId); // wait for socket close for 1 second to let message arrive at client { fd_set a_set; FD_ZERO(&a_set); FD_SET(sockfd, &a_set); struct timeval timeout; timeout.tv_sec = 1; timeout.tv_usec = 0; select(sockfd+1, &a_set, 0, 0, &timeout); } DBUG_RETURN(false); } } else if (t->m_type == tt_SHM_TRANSPORTER) { g_eventLogger.warning("Unable to verify transporter compatability with node %d", nodeId); } // setup transporter (transporter responsible for closing sockfd) t->connect_server(sockfd); DBUG_RETURN(true); }
// run as own thread void TransporterRegistry::start_clients_thread() { int persist_mgm_count= 0; DBUG_ENTER("TransporterRegistry::start_clients_thread"); while (m_run_start_clients_thread) { NdbSleep_MilliSleep(100); persist_mgm_count++; if(persist_mgm_count==50) { ndb_mgm_check_connection(m_mgm_handle); persist_mgm_count= 0; } for (int i= 0, n= 0; n < nTransporters && m_run_start_clients_thread; i++){ Transporter * t = theTransporters[i]; if (!t) continue; n++; const NodeId nodeId = t->getRemoteNodeId(); switch(performStates[nodeId]){ case CONNECTING: if(!t->isConnected() && !t->isServer) { bool connected= false; /** * First, we try to connect (if we have a port number). */ if (t->get_s_port()) connected= t->connect_client(); /** * If dynamic, get the port for connecting from the management server */ if( !connected && t->get_s_port() <= 0) { // Port is dynamic int server_port= 0; struct ndb_mgm_reply mgm_reply; if(!ndb_mgm_is_connected(m_mgm_handle)) ndb_mgm_connect(m_mgm_handle, 0, 0, 0); if(ndb_mgm_is_connected(m_mgm_handle)) { int res= ndb_mgm_get_connection_int_parameter(m_mgm_handle, t->getRemoteNodeId(), t->getLocalNodeId(), CFG_CONNECTION_SERVER_PORT, &server_port, &mgm_reply); DBUG_PRINT("info",("Got dynamic port %d for %d -> %d (ret: %d)", server_port,t->getRemoteNodeId(), t->getLocalNodeId(),res)); if( res >= 0 ) { /** * Server_port == 0 just means that that a mgmt server * has not received a new port yet. Keep the old. */ if (server_port) t->set_s_port(server_port); } else if(ndb_mgm_is_connected(m_mgm_handle)) { g_eventLogger.info("Failed to get dynamic port to connect to: %d", res); ndb_mgm_disconnect(m_mgm_handle); } else { g_eventLogger.info("Management server closed connection early. " "It is probably being shut down (or has problems). " "We will retry the connection. %d %s %s line: %d", ndb_mgm_get_latest_error(m_mgm_handle), ndb_mgm_get_latest_error_desc(m_mgm_handle), ndb_mgm_get_latest_error_msg(m_mgm_handle), ndb_mgm_get_latest_error_line(m_mgm_handle) ); } } /** else * We will not be able to get a new port unless * the m_mgm_handle is connected. Note that not * being connected is an ok state, just continue * until it is able to connect. Continue using the * old port until we can connect again and get a * new port. */ } } break; case DISCONNECTING: if(t->isConnected()) t->doDisconnect(); break; default: break; } } } DBUG_VOID_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 WatchDog::run() { unsigned int anIPValue, sleep_time; unsigned int oldIPValue = 0; unsigned int theIntervalCheck = theInterval; struct MicroSecondTimer start_time, last_time, now; NdbTick_getMicroTimer(&start_time); last_time = start_time; // WatchDog for the single threaded NDB while (!theStop) { sleep_time= 100; NdbSleep_MilliSleep(sleep_time); if(theStop) break; NdbTick_getMicroTimer(&now); if (NdbTick_getMicrosPassed(last_time, now)/1000 > sleep_time*2) { struct tms my_tms; times(&my_tms); g_eventLogger.info("Watchdog: User time: %llu System time: %llu", (Uint64)my_tms.tms_utime, (Uint64)my_tms.tms_stime); g_eventLogger.warning("Watchdog: Warning overslept %u ms, expected %u ms.", NdbTick_getMicrosPassed(last_time, now)/1000, sleep_time); } last_time = now; // Verify that the IP thread is not stuck in a loop anIPValue = *theIPValue; if (anIPValue != 0) { oldIPValue = anIPValue; globalData.incrementWatchDogCounter(0); NdbTick_getMicroTimer(&start_time); theIntervalCheck = theInterval; } else { int warn = 1; Uint32 elapsed = NdbTick_getMicrosPassed(start_time, now)/1000; /* oldIPValue == 9 indicates malloc going on, this can take some time so only warn if we pass the watchdog interval */ if (oldIPValue == 9) if (elapsed < theIntervalCheck) warn = 0; else theIntervalCheck += theInterval; if (warn) { const char *last_stuck_action = get_action(oldIPValue); g_eventLogger.warning("Ndb kernel is stuck in: %s", last_stuck_action); { struct tms my_tms; times(&my_tms); g_eventLogger.info("Watchdog: User time: %llu System time: %llu", (Uint64)my_tms.tms_utime, (Uint64)my_tms.tms_stime); } if (elapsed > 3 * theInterval) { shutdownSystem(last_stuck_action); } } } } return; }