Esempio n. 1
0
Int32 CmpISPFuncs::RegFuncs(
   const char* procName, //null terminated 
   SP_COMPILE_FUNCPTR compileFunc, 
   SP_INPUTFORMAT_FUNCPTR inFormatFunc,
   SP_PARSE_FUNCPTR parseFunc,
   SP_NUM_OUTPUTFIELDS_FUNCPTR outNumFormatFunc,
   SP_OUTPUTFORMAT_FUNCPTR outFormatFunc,
   SP_PROCESS_FUNCPTR procFunc,
   SP_HANDLE spHandle,
   const char* version)
{
  if ( strcmp(version, CMPISPVERSION) != 0 )
  {
    ABORT ( "arkcmp: The ISP interface version is not compatible" );
    NAExit(1);
  }
  procFuncsArray_.insert(ProcFuncsStruct(procName,
    compileFunc,
    inFormatFunc,
    parseFunc,
    outNumFormatFunc,
    outFormatFunc,
    procFunc,
    spHandle));
  return 1;
}
Esempio n. 2
0
void
UdrGuaControlConnection::actOnSystemMessage(
  short                  messageNum,
  IpcMessageBufferPtr    sysMsg,
  IpcMessageObjSize      sysMsgLen,
  short                  clientFileNumber,
  const GuaProcessHandle &clientPhandle,
  GuaConnectionToClient  *connection)
{
  const char * moduleName = "UdrGuaControlConnection::actOnSystemMessage";

  switch (messageNum)
  {
    case ZSYS_VAL_SMSG_OPEN:
      {
        if (udrGlob_->verbose_ &&
            udrGlob_->traceLevel_ >= TRACE_IPMS &&
            udrGlob_->showMain_)
        {
          ServerDebug(
           "[UdrServ (%s)] A new connection %p is opened to the Server.",
           moduleName,
           connection);
        }

        // Create a new message stream. Link the connection.
        // Then call receive on it to bring it into receiving mode.
        UdrServerControlStream *newControlStream =
          new (udrGlob_->getIpcHeap())
            UdrServerControlStream(udrGlob_->getIpcEnvironment(),
                                   udrGlob_,
                                   UDR_STREAM_SERVER_CONTROL,
                                   UdrServerControlStreamVersionNumber);
        newControlStream->addRecipient(connection);
        newControlStream->receive(FALSE);
      }
      break;

    default:
      // do nothing for all other kinds of system messages
      break;
  } // switch

  // The parent class already handles the job of closing all connections
  // who lost their client process by failed processes, failed CPUs and
  // failed systems or networks. Check here that we die if all our
  // requestors go away, but don't die if the first system message is
  // something other than an OPEN message.
  if (getNumRequestors() == 0 AND initialized_)
  {
    NAExit(0);
  }
  else if (NOT initialized_ AND getNumRequestors() > 0)
  {
    // the first requestor came in
    initialized_ = TRUE;
  }

} // UdrGuaControlConnection::actOnSystemMessage()
Esempio n. 3
0
void EspGuaControlConnection::actOnSystemMessage(
       short                  messageNum,
       IpcMessageBufferPtr    sysMsg,
       IpcMessageObjSize      sysMsgLen,
       short                  clientFileNumber,
       const GuaProcessHandle &clientPhandle,
       GuaConnectionToClient  *connection)
{
  switch (messageNum)
    {
    case ZSYS_VAL_SMSG_OPEN:
      if (initialized_)
	{
	  // This an OPEN message for a connection that isn't the
	  // initial control connection. Create a new message stream and
	  // attach it to the newly created connection.
	  EspNewIncomingConnectionStream *newStream = new(getEnv()->getHeap())
	    EspNewIncomingConnectionStream(getEnv(),espFragInstanceDir_);

	  ex_assert(connection != NULL,
                    "Must create connection for open sys msg");
	  newStream->addRecipient(connection);
          newStream->receive(FALSE);

	  // now abandon the new object, it will find its way to the right
	  // send bottom TCB on its own
	  // (a memory leak would result if the client would open our $RECEIVE
	  // w/o sending corresponding ESP level open requests)
	}
      break;

    case ZSYS_VAL_SMSG_CPUDOWN:
    case ZSYS_VAL_SMSG_REMOTECPUDOWN:
    case ZSYS_VAL_SMSG_CLOSE:
    case ZSYS_VAL_SMSG_NODEDOWN:
      // Somebody closed us or went down. Was it master executor?
      // Note that GuaReceiveControlConnection::getConnection returns
      // the master executor connection.
      if (getConnection() == connection)
      {
        // Master is gone, stop this process and let the OS cleanup.
        if (getEnv()->getLogEspGotCloseMsg())
        {
          /*
          Coverage notes: to test this code in a dev regression requires
          changing $TRAF_VAR/ms.env, so I made a manual test on
          May 11, 2012 to verify this code.
          */
          char myName[20];
          memset(myName, '\0', sizeof(myName));
          getEnv()->getMyOwnProcessId(IPC_DOM_GUA_PHANDLE).toAscii(
                                                    myName, sizeof(myName));
          char buf[500];
          char *sysMsgName = NULL;
          switch (messageNum)
          {
          case ZSYS_VAL_SMSG_CPUDOWN:
            sysMsgName = (char *) "CPUDOWN";
            break;
          case ZSYS_VAL_SMSG_REMOTECPUDOWN:
            sysMsgName = (char *) "REMOTECPUDOWN";
            break;
          case ZSYS_VAL_SMSG_CLOSE:
            sysMsgName = (char *) "CLOSE";
            break;
          case ZSYS_VAL_SMSG_NODEDOWN:
            sysMsgName = (char *) "NODEDOWN";
            break;
          }
          str_sprintf(buf, 
                      "System %s message causes %s to exit.",
                            sysMsgName, myName);
          SQLMXLoggingArea::logExecRtInfo(__FILE__, 
                                          __LINE__, buf, 0);
        }
        getEnv()->stopIpcEnvironment();
      }
      // Otherwise, do a search thru all
      // downloaded fragment entries and check whether their
      // client is still using them. The IPC layer will wake
      // up the scheduler so the actual release can take place.
      espFragInstanceDir_->releaseOrphanEntries();
      break;

    default:
      // do nothing for all other kinds of system messages
      break;
    } // switch


  // The parent class already handles the job of closing all connections
  // who lost their client process by failed processes, failed CPUs and
  // failed systems or networks. Check here that we die if all our
  // requestors go away, but don't die if the first system message is
  // something other than an OPEN message.
  if (getNumRequestors() == 0 AND initialized_)
    {
      // ABORT("Lost connection to client");
      // losing the client is not a reason to panic, the client may
      // have voluntarily decided to exit without freeing its resources
      NAExit(0);
    }
  else if (NOT initialized_ AND getNumRequestors() > 0)
    {
      // the first requestor came in
      initialized_ = TRUE;
    }
}
Esempio n. 4
0
void DoEspStartup(Int32 argc,
		  char **argv,
		  IpcEnvironment &env,
		  ExEspFragInstanceDir &fragInstanceDir,
		  GuaReceiveFastStart *guaReceiveFastStart)
{
  // make the compiler happy by using fragInstanceDir for something
  if (fragInstanceDir.getNumEntries() < 0)
    {}

  // interpret command line arguments
  IpcServerAllocationMethod allocMethod = IPC_ALLOC_DONT_CARE;

  Int32 currArg = 1;

  Int32 socketArg = 0;
  Int32 portArg = 0;

  while (currArg < argc)
    {
      if (strcmp("-fork", argv[currArg]) == 0)
        {
	  allocMethod = IPC_POSIX_FORK_EXEC;
        }
      else if (strcmp("-service", argv[currArg]) == 0)
	{
	  // /etc/inetd.conf should be configured such that the "-service"
	  // command line option is given
	  allocMethod = IPC_INETD;
	}
      else if (strcmp("-guardian", argv[currArg]) == 0)
	{
	  allocMethod = IPC_LAUNCH_GUARDIAN_PROCESS;
	}
      else if (strcmp("-noespfaststart", argv[currArg]) == 0)
	;
      else if (strcmp("-debug", argv[currArg]) == 0)
	{
	  NADebug();
	}
      else
	{
	  // bad arguments, die
	  NAExit(-1);
	}

      currArg++;
    }


  // create control connection (open $RECEIVE in Tandemese)
  switch (allocMethod)
    {
    case IPC_LAUNCH_GUARDIAN_PROCESS:
    case IPC_SPAWN_OSS_PROCESS:
      {
      // open $RECEIVE with a receive depth of 4000

	 GuaReceiveControlConnection *cc =
				  
	 new(&env) EspGuaControlConnection(&env,
					  &fragInstanceDir,
					  4000,
					  guaReceiveFastStart);
      env.setControlConnection(cc);

      // wait for the first open message to come in
      cc->waitForMaster();
      // set initial timeout in case the master never send first plan message
      env.setIdleTimestamp();
      }
     break;
      
    case IPC_INETD:
    case IPC_POSIX_FORK_EXEC:
      env.setControlConnection(
	   new(&env) EspSockControlConnection(&env,&fragInstanceDir));

      break;
      // NEEDS PORT (12/16/96) 
      //	handle the local NT process case without NSK-like

    case IPC_LAUNCH_NT_PROCESS:

      //debugging code - figure out later
      // the name of this machine on which this process is executing
      char myMachine[IpcNodeNameMaxLength];
      char errorLine[64];
      Int32  result;

      // who am I?
      result = gethostname(myMachine,IpcNodeNameMaxLength);
      if (!result)
	{
	  sprintf(errorLine," DoEspStartup : gethostname : error %d",result);
	  ABORT(errorLine);
	};
      // end debugging code
      env.setControlConnection(
	   new(&env) EspSockControlConnection(
		&env,&fragInstanceDir,socketArg, portArg));
      break;
      
    default:
      // bad command line arguments again
      NAExit(-1);
    }
}
Esempio n. 5
0
Int32 runESP(Int32 argc, char** argv, GuaReceiveFastStart *guaReceiveFastStart)
{
  // initialize ESP global data
  StatsGlobals * statsGlobals;

  XCONTROLMESSAGESYSTEM(XCTLMSGSYS_SETRECVLIMIT, XMAX_SETTABLE_RECVLIMIT_H);
  CliGlobals *cliGlobals = NULL;
  cliGlobals = CliGlobals::createCliGlobals(TRUE); // TRUE indicates a non-master process (WAIT on LREC)
  if (cliGlobals == NULL) // Sanity check
    NAExit(1); // Abend
  Int32 shmid;
  statsGlobals = shareStatsSegment(shmid);
  cliGlobals->setSharedMemId(shmid);
  //Lng32 numCliCalls = cliGlobals->incrNumOfCliCalls();
  cliGlobals->setIsESPProcess(TRUE);
  NAHeap *espExecutorHeap = cliGlobals->getExecutorMemory();
  // must create default context after set IpcEnvironment in CliGlobals first
  // because context's ExSqlComp object needs IpcEnvironment
  cliGlobals->initiateDefaultContext();
  NAHeap *espIpcHeap = cliGlobals->getIpcHeap();
  IpcEnvironment *ipcEnvPtr = cliGlobals->getEnvironment();
  if (statsGlobals != NULL)
     cliGlobals->setMemoryMonitor(statsGlobals->getMemoryMonitor());
  else 
  {
     // Start the  memory monitor for dynamic memory management
     Lng32 memMonitorWindowSize = 10;
     Lng32 memMonitorSampleInterval = 10;
     MemoryMonitor *memMonitor = new (espExecutorHeap) 
                           MemoryMonitor(memMonitorWindowSize,
                           memMonitorSampleInterval,
                           espExecutorHeap);
     cliGlobals->setMemoryMonitor(memMonitor);
  }
  // After CLI globals are initialized but before we begin ESP message
  // processing, have the CLI context set its user identity based on
  // the OS user identity.
  ContextCli *context = cliGlobals->currContext();
  ex_assert(context, "Invalid context pointer");
  context->initializeUserInfoFromOS();

  ExEspFragInstanceDir espFragInstanceDir(cliGlobals,
                                          espExecutorHeap,
                                          (StatsGlobals *)statsGlobals);

  ExEspControlMessage espIpcControlMessage(&espFragInstanceDir,
                                           ipcEnvPtr,
                                           espIpcHeap);

  // handle startup (command line args, control connection)
  DoEspStartup(argc,argv,*ipcEnvPtr,espFragInstanceDir,guaReceiveFastStart);
  // the control message stream talks through the control connection
  espIpcControlMessage.addRecipient(
       ipcEnvPtr->getControlConnection()->getConnection());

  // start the first receive operation
  espIpcControlMessage.receive(FALSE);
 
  NABoolean timeout;
  Int64 prevWaitTime = 0;

  // while there are requesters
  while (espFragInstanceDir.getNumMasters() > 0)
    {
      // -----------------------------------------------------------------
      // The ESPs most important line of code: DO THE WORK
      // -----------------------------------------------------------------

      espFragInstanceDir.work(prevWaitTime);

      // -----------------------------------------------------------------
      // After we have done work, it's necessary to wait for some I/O
      // (the frag instance dir work procedure works until it is blocked).
      // -----------------------------------------------------------------

      ipcEnvPtr->getAllConnections()->
	waitOnAll(IpcInfiniteTimeout, TRUE, &timeout, &prevWaitTime); // TRUE means: Called by ESP main
    }

  // nobody wants us anymore, right now that means that we stop
  return 0;
}
void runServer(Int32 argc, char **argv)
{
  Int32 shmid;
  jmp_buf sscpJmpBuf;
  StatsGlobals *statsGlobals = NULL;
  void *statsGlobalsAddr;
  NABoolean createStatsGlobals = FALSE;
  CliGlobals *cliGlobals = CliGlobals::createCliGlobals(FALSE);
  char tmbuf[64];
  time_t now;
  struct tm *nowtm;

  long maxSegSize = STATS_MAX_SEG_SIZE;
  char *envSegSize = getenv("MX_RTS_STATS_SEG_SIZE");
  if (envSegSize)
  {
    maxSegSize = (long) str_atoi(envSegSize, str_len(envSegSize));
    if (maxSegSize < 32)
      maxSegSize = 32;
    else if (maxSegSize > 256)
      maxSegSize = 256;
    maxSegSize *= 1024 * 1024;
  }
  long enableHugePages = 0;
  int shmFlag = RMS_SHMFLAGS;
  char *envShmHugePages = getenv("SQ_RMS_ENABLE_HUGEPAGES");
  if (envShmHugePages != NULL)
  {
     enableHugePages = (long) str_atoi(envShmHugePages,
                         str_len(envShmHugePages));
     if (enableHugePages > 0)
       shmFlag =  shmFlag | SHM_HUGETLB;
  }

  now = time(NULL);
  nowtm = localtime(&now);
  strftime(tmbuf, sizeof tmbuf, "%Y-%m-%d %H:%M:%S ", nowtm);

  if ((shmid = shmget((key_t)getStatsSegmentId(),
                         0,  // size doesn't matter unless we are creating.
                         shmFlag)) == -1)
  {
    if (errno == ENOENT)
    {
      // Normal case, segment does not exist yet. Try to create.
      bool didCreate = true;
      if ((shmid = shmget((key_t)getStatsSegmentId(),
                                maxSegSize,
                                shmFlag | IPC_CREAT)) == -1)
      {
        if (enableHugePages > 0)
        {
          enableHugePages = 0;
          // try again withouf hugepages
          shmFlag =  shmFlag & ~SHM_HUGETLB;
          if ((shmid = shmget((key_t)getStatsSegmentId(),
                                    maxSegSize,
                                    shmFlag | IPC_CREAT)) == -1)
            didCreate = false;
        }
        else 
          didCreate = false;
      }

      if (didCreate)
      {
        cout << tmbuf 
             << " RMS Shared segment id = " 
             << shmid << ", key = " 
             << (key_t)getStatsSegmentId() ;
        if (enableHugePages > 0)
          cout << ", created with huge pages support." << endl;
        else
          cout << ", created without huge pages support." << endl;

        createStatsGlobals = TRUE;
      }
      else
      {
        cout << tmbuf
             << " Shmget failed, key = "
             << getStatsSegmentId()
             <<", Error code: "
             << errno
             << " ("
             << strerror(errno)
             << ")" << endl;
        exit(errno);
      }
    } // if ENOENT (i.e., attempting creation.)
  }
  else
  {
     cout << tmbuf << " RMS Shared segment exists, attaching to it, shmid="<< shmid << ", key=" << (key_t)getStatsSegmentId() << "\n";
  }
  if ((statsGlobalsAddr = shmat(shmid, getRmsSharedMemoryAddr(), 0))
		== (void *)-1)
  {
    cout << tmbuf << "Shmat failed, shmid=" <<shmid << ", key=" << (key_t) getStatsSegmentId() << ", Error code : "  << errno << "(" << strerror(errno) << ")\n";
    exit(errno);
  }
  char *statsGlobalsStartAddr = (char *)statsGlobalsAddr;
  if (createStatsGlobals)
  {
     short envType = StatsGlobals::RTS_GLOBAL_ENV;
     statsGlobals = new (statsGlobalsStartAddr)
             StatsGlobals((void *)statsGlobalsAddr, envType, maxSegSize);
     cliGlobals->setSharedMemId(shmid);
     // We really should not squirrel the statsGlobals pointer away like
     // this until the StatsGloblas is initialized, but
     // statsGlobals->init() needs it ......
     cliGlobals->setStatsGlobals(statsGlobals);
     statsGlobals->init();
  }
  else
  {
    statsGlobals = (StatsGlobals *)statsGlobalsAddr;
    cliGlobals->setSharedMemId(shmid);
    cliGlobals->setStatsGlobals(statsGlobals);
  }
  XPROCESSHANDLE_GETMINE_(statsGlobals->getSscpProcHandle());
  NAHeap *sscpHeap = cliGlobals->getExecutorMemory();
  cliGlobals->setJmpBufPtr(&sscpJmpBuf);
  if (setjmp(sscpJmpBuf))
    NAExit(1); // Abend
  IpcEnvironment  *sscpIpcEnv = new (sscpHeap) IpcEnvironment(sscpHeap, cliGlobals->getEventConsumed(),
      FALSE, IPC_SQLSSCP_SERVER, FALSE, TRUE);

  SscpGlobals *sscpGlobals = NULL;

  sscpGlobals = new (sscpHeap) SscpGlobals(sscpHeap, statsGlobals);

  // Currently open $RECEIVE with 256
  SscpGuaReceiveControlConnection *cc =
	 new(sscpHeap) SscpGuaReceiveControlConnection(sscpIpcEnv,
					  sscpGlobals,
                                           256);
  sscpIpcEnv->setControlConnection(cc);
  while (TRUE)
  {
     while (cc->getConnection() == NULL)
      cc->wait(IpcInfiniteTimeout);

#ifdef _DEBUG_RTS
    cerr << "No. of Requesters-1 "  << cc->getNumRequestors() << " \n";
#endif
    while (cc->getNumRequestors() > 0)
    {
      sscpIpcEnv->getAllConnections()->waitOnAll(IpcInfiniteTimeout);
    } // Inner while
  }
}  // runServer
Esempio n. 7
0
// myNAExit(status) does mxcmp finalization before calling NAExit(status)
static void myNAExit(Int32 status)
{
  CURRENTQCACHE->finalize("Dynamic ");
  NAExit(status);
}