Esempio n. 1
0
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
}
Esempio n. 2
0
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;
  }
}
Esempio n. 3
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);
  }
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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);
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
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;
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
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;
}
Esempio n. 10
0
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)));
}
Esempio n. 11
0
/**
 * 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;
}
Esempio n. 12
0
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;
}
Esempio n. 13
0
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);
  }
}
Esempio n. 14
0
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()
Esempio n. 15
0
/*****************************************************************************
 * ~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;
}
Esempio n. 16
0
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_);
}
Esempio n. 17
0
/*
 *  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;
}
Esempio n. 18
0
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;
}
Esempio n. 20
0
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);
}
Esempio n. 21
0
// 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;
}
Esempio n. 22
0
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;
}
Esempio n. 23
0
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;
}