INT32 _readFile( const CHAR *pFilePath, CHAR **ppBuff, INT64 *pBuffLen ) { INT32 rc = SDB_OK ; BOOLEAN hasOpen = FALSE ; INT64 fileSize = 0 ; SINT64 readSize = 0 ; OSSFILE file ; stringstream ss ; if ( !ppBuff ) { rc = SDB_INVALIDARG ; goto error ; } rc = ossAccess( pFilePath ) ; if ( rc ) { ss << "Failed to access file[" << pFilePath << "], rc = " << rc << ERROR_END ; goto error ; } rc = ossOpen( pFilePath, OSS_READONLY, 0, file ) ; if ( rc ) { ss << "Failed to open file[" << pFilePath << "], rc = " << rc << ERROR_END ; goto error ; } hasOpen = TRUE ; rc = ossGetFileSize( &file, &fileSize ) ; if ( rc ) { ss << "Failed to get the size of file[" << pFilePath << "], rc = " << rc << ERROR_END ; goto error ; } rc = _checkBuffer( ppBuff, pBuffLen, fileSize ) ; if ( rc ) { ss << "Failed to check the size of buffer when read[" << pFilePath << "], rc = " << rc << ERROR_END ; goto error ; } rc = ossReadN( &file, fileSize, *ppBuff, readSize ) ; if ( rc ) { ss << "Failed to read content from file[" << pFilePath << "], rc = " << rc << ERROR_END ; } done: if ( hasOpen ) { ossClose( file ) ; } return rc ; error: cout << ss.str().c_str() << endl ; goto done ; }
// PD_TRACE_DECLARE_FUNCTION ( SDB__DPSLOGFILE__RESTRORE, "_dpsLogFile::_restore" ) INT32 _dpsLogFile::_restore () { INT32 rc = SDB_OK ; PD_TRACE_ENTRY ( SDB__DPSLOGFILE__RESTRORE ); INT64 fileSize = 0 ; UINT64 offSet = 0 ; UINT64 baseOffset = 0 ; dpsLogRecordHeader lsnHeader ; CHAR *lastRecord = NULL ; UINT64 lastOffset = 0 ; UINT32 lastLen = 0 ; _inRestore = TRUE ; //Judge the length is right rc = ossGetFileSize( _file, &fileSize ) ; if ( SDB_OK != rc ) { goto error ; } if ( fileSize < (INT64)( _fileSize + sizeof(dpsLogHeader) ) ) { PD_LOG ( PDERROR, "DPS file size[%d] is smaller than config[%d]", fileSize - sizeof(dpsLogHeader), _fileSize ) ; rc = SDB_DPS_FILE_SIZE_NOT_SAME ; goto error ; } //Init header rc = _readHeader() ; if ( SDB_OK != rc ) { PD_LOG ( PDERROR, "Fail to read dps file header[rc:%d]", rc ) ; goto error ; } // check header info if ( ossStrncmp( _logHeader._eyeCatcher, DPS_LOG_HEADER_EYECATCHER, sizeof( _logHeader._eyeCatcher ) ) != 0 ) { PD_LOG( PDERROR, "DPS file eye catcher error" ) ; rc = SDB_DPS_FILE_NOT_RECOGNISE ; goto error ; } else if ( _logHeader._fileSize != 0 && _logHeader._fileSize != _fileSize ) { PD_LOG( PDERROR, "DPS file's meta size[%d] is not the same with " "config[%d]", _logHeader._fileSize, _fileSize ) ; rc = SDB_DPS_FILE_SIZE_NOT_SAME ; goto error ; } else if ( _logHeader._fileNum != 0 && _logHeader._fileNum != _fileNum ) { PD_LOG( PDERROR, "DPS file's meta file num[%d] is not the same with " "config[%d]", _logHeader._fileNum, _fileNum ) ; rc = SDB_INVALIDARG ; goto error ; } // check the real size if ( fileSize > (INT64)( _fileSize + sizeof(dpsLogHeader) ) ) { PD_LOG( PDERROR, "DPS file real size[%d] is not the same with " "config[%d]", fileSize - sizeof(dpsLogHeader), _fileSize ) ; // start up from crash if ( !pmdGetStartup().isOK() ) { rc = ossTruncateFile( _file, _fileSize + sizeof(dpsLogHeader) ) ; if ( rc ) { PD_LOG( PDWARNING, "Tuncate dps file to config size failed, " "rc: %d", rc ) ; goto error ; } PD_LOG( PDEVENT, "Tuncate dps file to config size[%d]", _fileSize ) ; } else { goto error ; } } PD_LOG ( PDEVENT, "Header info[first lsn:%d.%lld, logID:%d]", _logHeader._firstLSN.version, _logHeader._firstLSN.offset, _logHeader._logID ) ; // upgrade the header if ( _logHeader._version != DPS_LOG_FILE_VERSION1 ) { _logHeader._version = DPS_LOG_FILE_VERSION1 ; _logHeader._fileSize = _fileSize ; _logHeader._fileNum = _fileNum ; rc = _flushHeader() ; PD_RC_CHECK( rc, PDERROR, "Failed to flush header, rc: %d", rc ) ; } if ( _logHeader._logID == DPS_INVALID_LOG_FILE_ID || _logHeader._firstLSN.invalid() ) { _logHeader._firstLSN.version = DPS_INVALID_LSN_VERSION ; _logHeader._firstLSN.offset = DPS_INVALID_LSN_OFFSET ; goto done ; } offSet = _logHeader._firstLSN.offset % _fileSize ; baseOffset = _logHeader._firstLSN.offset - offSet ; //analysis the file while ( offSet < _fileSize ) { rc = read ( offSet + baseOffset , sizeof (dpsLogRecordHeader), (CHAR*)&lsnHeader ) ; if ( SDB_OK != rc ) { PD_LOG ( PDERROR, "Failed to read lsn header[offset:%lld,rc:%d]", offSet, rc ) ; goto error ; } if ( lsnHeader._lsn != offSet + baseOffset ) { PD_LOG ( PDEVENT, "LSN is not the same[%lld!=%lld]", lsnHeader._lsn, offSet + baseOffset ) ; break ; } else if ( offSet + lsnHeader._length > _fileSize ) { PD_LOG ( PDEVENT, "LSN length[%d] is over the file " "size[offSet:%lld]", lsnHeader._length, offSet ) ; break ; } else if ( lsnHeader._length < sizeof (dpsLogRecordHeader) ) { PD_LOG ( PDEVENT, "LSN length[%d] less than min[%d], invalid LSN", lsnHeader._length, sizeof (dpsLogRecordHeader) ) ; break ; } offSet += lsnHeader._length ; lastOffset = offSet ; lastLen = lsnHeader._length ; } /// ensure that the last record is valid. if ( 0 < lastLen && 0 < lastOffset ) { _dpsLogRecord lr ; lastRecord = ( CHAR * )SDB_OSS_MALLOC( lastLen ) ; if ( NULL == lastRecord ) { PD_LOG( PDERROR, "failed to allocate mem.") ; rc = SDB_OOM ; goto error ; } rc = read( lastOffset + baseOffset - lastLen, lastLen, lastRecord ) ; if ( SDB_OK != rc ) { PD_LOG( PDERROR, "failed to read dps record[%lld, rc:%d]", offSet, rc ) ; goto error ; } rc = lr.load( lastRecord ) ; if ( SDB_DPS_CORRUPTED_LOG == rc ) { /// the last record is corrupted. move to pre one. offSet -= lastLen ; rc = SDB_OK ; const dpsLogRecordHeader *corruptedHeader = ( const dpsLogRecordHeader * )lastRecord ; PD_LOG( PDEVENT, "last log record(lsn:%lld) is corrupted.", corruptedHeader->_lsn ) ; /// only one corrupted log in this file. if ( 0 == offSet ) { _logHeader._firstLSN.offset = DPS_INVALID_LSN_OFFSET ; _logHeader._firstLSN.version = DPS_INVALID_LSN_VERSION ; } } else if ( SDB_OK != rc ) { PD_LOG( PDERROR, "failed to load record log:%d", rc ) ; goto error ; } } _idleSize = _fileSize - offSet ; done: _inRestore = FALSE ; SAFE_OSS_FREE( lastRecord ) ; PD_TRACE_EXITRC ( SDB__DPSLOGFILE__RESTRORE, rc ); return rc ; error: goto done ; }