Exemplo n.º 1
0
AsyncFile*
Ndbfs::createAsyncFile(){

  // Check limit of open files
  if (m_maxFiles !=0 && theFiles.size() ==  m_maxFiles) {
    // Print info about all open files
    for (unsigned i = 0; i < theFiles.size(); i++){
      AsyncFile* file = theFiles[i];
      ndbout_c("%2d (0x%lx): %s", i, (long) file, file->isOpen()?"OPEN":"CLOSED");
    }
    ERROR_SET(fatal, NDBD_EXIT_AFS_MAXOPEN,""," Ndbfs::createAsyncFile");
  }

  AsyncFile* file = new AsyncFile(* this);
  file->doStart();

  // Put the file in list of all files
  theFiles.push_back(file);

#ifdef VM_TRACE
  infoEvent("NDBFS: Created new file thread %d", theFiles.size());
#endif
  
  return file;
}
Exemplo n.º 2
0
    void
AsyncDataWriterSupplier::close()
{
    closing = true;
    if (filterSupplier != NULL) {
        filterSupplier->onClosing(this);
    }
    file->close();
    if (filterSupplier != NULL) {
        filterSupplier->onClosed(this);
    }
    DestroyExclusiveLock(&lock);
}
Exemplo n.º 3
0
void 
Ndbfs::execFSREMOVEREQ(Signal* signal)
{
  jamEntry();
  const FsRemoveReq * const req = (FsRemoveReq *)signal->getDataPtr();
  const BlockReference userRef = req->userReference;
  AsyncFile* file = getIdleFile();
  ndbrequire(file != NULL);

  Filename::NameSpec spec(theFileSystemPath, theBackupFilePath);
  file->theFileName.set(spec, userRef, req->fileNumber, req->directory);
  file->reportTo(&theFromThreads);
  
  Request* request = theRequestPool->get();
  request->action = Request::rmrf;
  request->par.rmrf.directory = req->directory;
  request->par.rmrf.own_directory = req->ownDirectory;
  request->error = 0;
  request->set(userRef, req->userPointer, newId() );
  request->file = file;
  request->theTrace = signal->getTrace();
  
  ndbrequire(forward(file, request));
}
Exemplo n.º 4
0
//---------------------------------------------------------------------------
void LogFile::rotate(AsyncFile & file)
{
  if( rotatedFileCount_ == 0 || file.std() || file.size() <= rotationThreshold_ ) return;
  file.close();
  file.exclusive(true).open();
  utf8::String fileExt(getFileExt(file.fileName()));
  uintptr_t i = rotatedFileCount_;
  while( i >= 1 ){
    if( i == rotatedFileCount_ ){
      remove(changeFileExt(file.fileName(),"." + utf8::int2Str(i - 1)) + fileExt,true);
    }
    else {
      rename(
        changeFileExt(file.fileName(),"." + utf8::int2Str(i - 1)) + fileExt,
        changeFileExt(file.fileName(),"." + utf8::int2Str(i)) + fileExt,
	      true,
	      true
      );
    }
    i--;
  }
  file.close();
  rename(file.fileName(),changeFileExt(file.fileName(),".0") + fileExt,true,true);
}
Exemplo n.º 5
0
void 
Ndbfs::execFSOPENREQ(Signal* signal)
{
  jamEntry();
  const FsOpenReq * const fsOpenReq = (FsOpenReq *)&signal->theData[0];
  const BlockReference userRef = fsOpenReq->userReference;
  AsyncFile* file = getIdleFile();
  ndbrequire(file != NULL);
  Filename::NameSpec spec(theFileSystemPath, theBackupFilePath);

  Uint32 userPointer = fsOpenReq->userPointer;
  
  if(fsOpenReq->fileFlags & FsOpenReq::OM_INIT)
  {
    Ptr<GlobalPage> page_ptr;
    if(m_global_page_pool.seize(page_ptr) == false)
    {
      FsRef * const fsRef = (FsRef *)&signal->theData[0];
      fsRef->userPointer  = userPointer; 
      fsRef->setErrorCode(fsRef->errorCode, FsRef::fsErrOutOfMemory);
      fsRef->osErrorCode  = ~0; // Indicate local error
      sendSignal(userRef, GSN_FSOPENREF, signal, 3, JBB);
      return;
    }
    file->m_page_ptr = page_ptr;
  } 
  else
  {
    ndbassert(file->m_page_ptr.isNull());
    file->m_page_ptr.setNull();
  }
  
  if(signal->getNoOfSections() == 0){
    jam();
    file->theFileName.set(spec, userRef, fsOpenReq->fileNumber);
  } else {
    jam();
    SegmentedSectionPtr ptr;
    signal->getSection(ptr, FsOpenReq::FILENAME);
    file->theFileName.set(spec, ptr, g_sectionSegmentPool);
    releaseSections(signal);
  }
  file->reportTo(&theFromThreads);
  if (getenv("NDB_TRACE_OPEN"))
    ndbout_c("open(%s)", file->theFileName.c_str());
  
  Request* request = theRequestPool->get();
  request->action = Request::open;
  request->error = 0;
  request->set(userRef, userPointer, newId() );
  request->file = file;
  request->theTrace = signal->getTrace();
  request->par.open.flags = fsOpenReq->fileFlags;
  request->par.open.page_size = fsOpenReq->page_size;
  request->par.open.file_size = fsOpenReq->file_size_hi;
  request->par.open.file_size <<= 32;
  request->par.open.file_size |= fsOpenReq->file_size_lo;
  request->par.open.auto_sync_size = fsOpenReq->auto_sync_size;
  
  ndbrequire(forward(file, request));
}
Exemplo n.º 6
0
void
Ndbfs::execDUMP_STATE_ORD(Signal* signal)
{
  if(signal->theData[0] == 19){
    return;
  }
  if(signal->theData[0] == DumpStateOrd::NdbfsDumpFileStat){
    infoEvent("NDBFS: Files: %d Open files: %d",
	      theFiles.size(),
	      theOpenFiles.size());
    infoEvent(" Idle files: %d Max opened files: %d",
	       theIdleFiles.size(),
	       m_maxOpenedFiles);
    infoEvent(" Max files: %d",
	      m_maxFiles);
    infoEvent(" Requests: %d",
	      theRequestPool->size());

    return;
  }
  if(signal->theData[0] == DumpStateOrd::NdbfsDumpOpenFiles){
    infoEvent("NDBFS: Dump open files: %d", theOpenFiles.size());
    
    for (unsigned i = 0; i < theOpenFiles.size(); i++){
      AsyncFile* file = theOpenFiles.getFile(i);
      infoEvent("%2d (0x%x): %s", i,file, file->theFileName.c_str());
    }
    return;
  }
  if(signal->theData[0] == DumpStateOrd::NdbfsDumpAllFiles){
    infoEvent("NDBFS: Dump all files: %d", theFiles.size());
    
    for (unsigned i = 0; i < theFiles.size(); i++){
      AsyncFile* file = theFiles[i];
      infoEvent("%2d (0x%x): %s", i,file, file->isOpen()?"OPEN":"CLOSED");
    }
    return;
  }
  if(signal->theData[0] == DumpStateOrd::NdbfsDumpIdleFiles){
    infoEvent("NDBFS: Dump idle files: %d", theIdleFiles.size());
    
    for (unsigned i = 0; i < theIdleFiles.size(); i++){
      AsyncFile* file = theIdleFiles[i];
      infoEvent("%2d (0x%x): %s", i,file, file->isOpen()?"OPEN":"CLOSED");
    }
    return;
  }

  if(signal->theData[0] == 404)
  {
    ndbrequire(signal->getLength() == 2);
    Uint32 file= signal->theData[1];
    AsyncFile* openFile = theOpenFiles.find(file);
    ndbrequire(openFile != 0);
    ndbout_c("File: %s %p", openFile->theFileName.c_str(), openFile);
    Request* curr = openFile->m_current_request;
    Request* last = openFile->m_last_request;
    if(curr)
      ndbout << "Current request: " << *curr << endl;
    if(last)
       ndbout << "Last request: " << *last << endl;

    ndbout << "theReportTo " << *openFile->theReportTo << endl;
    ndbout << "theMemoryChannelPtr" << *openFile->theMemoryChannelPtr << endl;

    ndbout << "All files: " << endl;
    for (unsigned i = 0; i < theFiles.size(); i++){
      AsyncFile* file = theFiles[i];
      ndbout_c("%2d (0x%lx): %s", i, (long) file, file->isOpen()?"OPEN":"CLOSED");
    }
  }
}//Ndbfs::execDUMP_STATE_ORD()
Exemplo n.º 7
0
void
AsyncIoThread::run()
{
  Request *request;

  // Create theMemoryChannel in the thread that will wait for it
  NdbMutex_Lock(theStartMutexPtr);
  theStartFlag = true;
  NdbMutex_Unlock(theStartMutexPtr);
  NdbCondition_Signal(theStartConditionPtr);

  EmulatedJamBuffer jamBuffer;
  jamBuffer.theEmulatedJamIndex = 0;
  // This key is needed by jamNoBlock().
  NdbThread_SetTlsKey(NDB_THREAD_TLS_JAM, &jamBuffer);

  while (1)
  {
    request = theMemoryChannelPtr->readChannel();
    if (!request || request->action == Request::end)
    {
      DEBUG(ndbout_c("Nothing read from Memory Channel in AsyncFile"));
      theStartFlag = false;
      return;
    }//if

    AsyncFile * file = request->file;
    m_current_request= request;
    switch (request->action) {
    case Request::open:
      file->openReq(request);
      if (request->error == 0 && request->m_do_bind)
        attach(file);
      break;
    case Request::close:
      file->closeReq(request);
      detach(file);
      break;
    case Request::closeRemove:
      file->closeReq(request);
      file->removeReq(request);
      detach(file);
      break;
    case Request::readPartial:
    case Request::read:
      file->readReq(request);
      break;
    case Request::readv:
      file->readvReq(request);
      break;
    case Request::write:
      file->writeReq(request);
      break;
    case Request::writev:
      file->writevReq(request);
      break;
    case Request::writeSync:
      file->writeReq(request);
      file->syncReq(request);
      break;
    case Request::writevSync:
      file->writevReq(request);
      file->syncReq(request);
      break;
    case Request::sync:
      file->syncReq(request);
      break;
    case Request::append:
      file->appendReq(request);
      break;
    case Request::append_synch:
      file->appendReq(request);
      file->syncReq(request);
      break;
    case Request::rmrf:
      file->rmrfReq(request, file->theFileName.c_str(),
                    request->par.rmrf.own_directory);
      break;
    case Request::end:
      theStartFlag = false;
      return;
    case Request::allocmem:
    {
      allocMemReq(request);
      break;
    }
    case Request::buildindx:
      buildIndxReq(request);
      break;
    case Request::suspend:
      if (request->par.suspend.milliseconds)
      {
        g_eventLogger->debug("Suspend %s %u ms",
                             file->theFileName.c_str(),
                             request->par.suspend.milliseconds);
        NdbSleep_MilliSleep(request->par.suspend.milliseconds);
        continue;
      }
      else
      {
        g_eventLogger->debug("Suspend %s",
                             file->theFileName.c_str());
        theStartFlag = false;
        return;
      }
    default:
      DEBUG(ndbout_c("Invalid Request"));
      abort();
      break;
    }//switch
    m_last_request = request;
    m_current_request = 0;

    // No need to signal as ndbfs only uses tryRead
    theReportTo->writeChannelNoSignal(request);
    m_fs.wakeup();
  }
}
Exemplo n.º 8
0
//---------------------------------------------------------------------------
void LogFile::threadExecute()
{
#ifndef __FreeBSD__
  priority(THREAD_PRIORITY_LOWEST);
#endif
  threadFile_.fileName(file_).createIfNotExist(true);
  AsyncFile lck;
  lck.fileName(threadFile_.fileName() + ".lck").createIfNotExist(true).removeAfterClose(true);
  bool exception;
  for(;;){
    exception = false;
    AutoPtr<char,AutoPtrMemoryDestructor> buffer;
    uintptr_t bufferPos = 0;
    int64_t ft;
    try {
      {
        AutoLock<LiteWriteLock> lock(threadReadWriteLock_);
        bufferPos = bufferPos_;
        ft = bufferDataTTA_ - (gettimeofday() - lastFlushTime_);
      }
      if( bufferPos == 0 && !terminated_ ){
        bufferSemaphore_.wait();
        continue;
      }
      if( bufferPos > 0 && !terminated_ && ft >= 0 ){
        bufferSemaphore_.timedWait(ft);
      }
      {
        AutoLock<LiteWriteLock> lock(threadReadWriteLock_);
        buffer.xchg(buffer_);
        bufferPos = bufferPos_;
        bufferPos_ = 0;
        bufferSize_ = 0;
      }
    }
    catch( ExceptionSP & e ){
      exceptionStdErrorToSyslog(e);
    }
    if( terminated_ && (bufferPos == 0 || exception) ) break;
    if( bufferPos > 0 ){
      exception = false;
      AutoFileWRLock<AsyncFile> lock;
      try {
        lck.open();
        lck.wrLock(0,0);
        lock.setLocked(lck);
        threadFile_.exclusive(false).open();
        threadFile_.seek(threadFile_.size()).writeBuffer(buffer,bufferPos);
        {
          AutoLock<LiteWriteLock> lock(threadReadWriteLock_);
          lastFlushTime_ = gettimeofday();
	}
        rotate(threadFile_);
      }
      catch( ExceptionSP & e ){
        exception = true;
        exceptionStdErrorToSyslog(e);
      }
    }
    if( exception ){
      threadFile_.close();
      lck.close();
    }
  }
//  fprintf(stderr,"%s %d\n",__FILE__,__LINE__);
}
void
AsyncIoThread::run()
{
  bool first_flag = true;
  Request *request;
  NDB_TICKS last_yield_ticks;

  // Create theMemoryChannel in the thread that will wait for it
  NdbMutex_Lock(theStartMutexPtr);
  theStartFlag = true;
  NdbMutex_Unlock(theStartMutexPtr);
  NdbCondition_Signal(theStartConditionPtr);

  EmulatedJamBuffer jamBuffer;
  jamBuffer.theEmulatedJamIndex = 0;
  // This key is needed by jamNoBlock().
  NdbThread_SetTlsKey(NDB_THREAD_TLS_JAM, &jamBuffer);

  while (1)
  {
    if (m_real_time)
    {
      /**
       * If we are running in real-time we'll simply insert a break every
       * so often to ensure that low-prio threads aren't blocked from the
       * CPU, this is especially important if we're using a compressed
       * file system where lots of CPU is used by this thread.
       */
      bool yield_flag = false;
      const NDB_TICKS current_ticks = NdbTick_getCurrentTicks();

      if (first_flag)
      {
        first_flag = false;
        yield_flag = true;
      }
      else
      {
        Uint64 micros_passed =
          NdbTick_Elapsed(last_yield_ticks, current_ticks).microSec();
        if (micros_passed > 10000)
        {
          yield_flag = true;
        }
      }
      if (yield_flag)
      {
        if (NdbThread_yield_rt(theThreadPtr, TRUE))
        {
          m_real_time = false;
        }
        last_yield_ticks = current_ticks;
      }
    }
    request = theMemoryChannelPtr->readChannel();
    if (!request || request->action == Request::end)
    {
      DEBUG(ndbout_c("Nothing read from Memory Channel in AsyncFile"));
      theStartFlag = false;
      return;
    }//if

    AsyncFile * file = request->file;
    m_current_request= request;
    switch (request->action) {
    case Request::open:
      file->openReq(request);
      if (request->error == 0 && request->m_do_bind)
        attach(file);
      break;
    case Request::close:
      file->closeReq(request);
      detach(file);
      break;
    case Request::closeRemove:
      file->closeReq(request);
      file->removeReq(request);
      detach(file);
      break;
    case Request::readPartial:
    case Request::read:
      file->readReq(request);
      break;
    case Request::readv:
      file->readvReq(request);
      break;
    case Request::write:
      file->writeReq(request);
      break;
    case Request::writev:
      file->writevReq(request);
      break;
    case Request::writeSync:
      file->writeReq(request);
      file->syncReq(request);
      break;
    case Request::writevSync:
      file->writevReq(request);
      file->syncReq(request);
      break;
    case Request::sync:
      file->syncReq(request);
      break;
    case Request::append:
      file->appendReq(request);
      break;
    case Request::append_synch:
      file->appendReq(request);
      file->syncReq(request);
      break;
    case Request::rmrf:
      file->rmrfReq(request, file->theFileName.c_str(),
                    request->par.rmrf.own_directory);
      break;
    case Request::end:
      theStartFlag = false;
      return;
    case Request::allocmem:
    {
      allocMemReq(request);
      break;
    }
    case Request::buildindx:
      buildIndxReq(request);
      break;
    case Request::suspend:
      if (request->par.suspend.milliseconds)
      {
        g_eventLogger->debug("Suspend %s %u ms",
                             file->theFileName.c_str(),
                             request->par.suspend.milliseconds);
        NdbSleep_MilliSleep(request->par.suspend.milliseconds);
        continue;
      }
      else
      {
        g_eventLogger->debug("Suspend %s",
                             file->theFileName.c_str());
        theStartFlag = false;
        return;
      }
    default:
      DEBUG(ndbout_c("Invalid Request"));
      abort();
      break;
    }//switch
    m_last_request = request;
    m_current_request = 0;

    // No need to signal as ndbfs only uses tryRead
    theReportTo->writeChannelNoSignal(request);
    m_fs.wakeup();
  }
}