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; }
void AsyncDataWriterSupplier::close() { closing = true; if (filterSupplier != NULL) { filterSupplier->onClosing(this); } file->close(); if (filterSupplier != NULL) { filterSupplier->onClosed(this); } DestroyExclusiveLock(&lock); }
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)); }
//--------------------------------------------------------------------------- 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); }
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)); }
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()
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(); } }
//--------------------------------------------------------------------------- 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(); } }