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 ;
   }
Exemple #2
0
   // 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 ;
   }