bea_FRI Class Reference
[IVD Back-End Agent]

#include <bea_fri.h>

Collaboration diagram for bea_FRI:

Collaboration graph
[legend]

List of all members.


Detailed Description

Definition at line 32 of file bea_fri.h.


Public Member Functions

 bea_FRI (i_BackEndAgent_i &a_bea, bea_Volume *const a_volume_p, const cmn_Path &a_workDir, bool a_recreateInto=false, string a_extension="")
bool PositionToStartOfFRI ()
 Detects FRI on data volume and positions to the beginning of FRI or end od data (if there's no FRI).
void CloseVolume ()
 Performs all "medium close" steps:
  • mark the volume closed in the RMDB
  • write the FRI on the data volume
  • write the FRI on the system volume
  • verification of data format of the FRI when writing.

void CloseVolumeInRMDB ()
bool ReadFRIStart (cmn_UUID_t &a_volID)
 Reads first block of FRI and extracts volume ID.
bool ReadFRI (const cmn_UUID_t &a_volID)
 Reads one FRI from current medium position.
void CreateFRI (bool a_volumeClosed)
void DeleteFRIOnVolume ()
 Deletes last FRI on current volume (data or system).
UInt32_t GetFRIStartPosition () const

Private Member Functions

bool WriteFRI ()
void CopyFromDiskToMedium ()
void DeleteFRIOnDisk ()
void DeleteFRIOnDisk (const cmn_UUID_t &a_volID)
void MoveFromWorkToFRI ()
void SaveFRIOnError ()
bool VerifyExistenceOfFileMark (UInt32_t a_position)
 Verifies existance of the file mark on the specified position.

Private Attributes

 log_CLASSID_m
i_BackEndAgent_im_bea
bea_Drive *const m_drive_p
bea_Volume *const m_volume_p
bea_Volumem_sysVolume_p
bea_Volumem_currentVolume_p
const cmn_Pathm_workDir
bool m_recreateInto
string m_extension
UInt32_t m_friStartPos
 Position of the FRI on medium after the file mark.

Constructor & Destructor Documentation

bea_FRI::bea_FRI ( i_BackEndAgent_i a_bea,
bea_Volume *const   a_volume_p,
const cmn_Path a_workDir,
bool  a_recreateInto = false,
string  a_extension = "" 
)

Definition at line 36 of file bea_fri.cpp.

References dbg_LOW, bea_Drive::GetMedium(), bea_Medium::GetSysVolNumber(), bea_Medium::GetVolume(), log_DBG_m, log_FUNC_m, m_drive_p, and m_sysVolume_p.

00043   : m_bea(a_bea),
00044     m_drive_p(m_bea.GetDrive()),
00045     m_volume_p(a_volume_p),
00046     m_sysVolume_p(NULL),
00047     m_currentVolume_p(NULL),
00048     m_workDir(a_workDir),
00049     m_recreateInto(a_recreateInto),
00050     m_extension(a_extension),
00051     m_friStartPos(0) {
00052 
00053     log_FUNC_m(bea_FRI);
00054 
00055     bea_Medium* med_p = m_drive_p->GetMedium();
00056     if (med_p->GetSysVolNumber() > 0) {
00057         m_sysVolume_p = med_p->GetVolume(med_p->GetSysVolNumber());
00058         log_DBG_m(dbg_LOW, "Detected system volume is " << med_p->GetSysVolNumber());
00059     }
00060     else {
00061         log_DBG_m(dbg_LOW, "Medium doesn't have system volume.");
00062     }
00063 }

Here is the call graph for this function:


Member Function Documentation

bool bea_FRI::PositionToStartOfFRI (  ) 

Detects FRI on data volume and positions to the beginning of FRI or end od data (if there's no FRI).

The first FM is after the medium volume header, the second one is between data and FRI.

Return values:
true FRI detected
false No FRI on the volume

Definition at line 302 of file bea_fri.cpp.

References bea_OPREAD, bea_Medium::ChangeVolume(), dbg_LOW, dbg_NORM, bea_Medium::GetCurrentVolume(), bea_Medium::GetCurVolNumber(), ivd_BaseException::GetError(), bea_Drive::GetMedium(), bea_Volume::GetPosition(), bea_Volume::GetVolumeNumber(), i_BackEndAgent_i::HandleError(), ie_MEDIUM_EOD, ie_MEDIUM_EOM, log_DBG_m, log_FUNC_m, m_bea, m_currentVolume_p, m_drive_p, m_friStartPos, m_volume_p, bea_Volume::Rewind(), and bea_Volume::SeekFileMark().

Referenced by bea_MigrationThread::CheckFRI(), bea_FRIThread::CheckFRI(), and bea_FRIThread::ProcessFromDataVol().

00302                                    {
00303     log_FUNC_m(PositionToStartOfFRI);
00304 
00305     bea_Medium* med_p = m_drive_p->GetMedium();
00306     if (med_p->GetCurVolNumber() != m_volume_p->GetVolumeNumber() ) {
00307         med_p->ChangeVolume( m_volume_p->GetVolumeNumber() );
00308     }
00309     m_currentVolume_p = med_p->GetCurrentVolume();
00310     m_friStartPos = 0;
00311 
00312     try {
00313         log_DBG_m(dbg_NORM, "Detecting previously written FRI.")
00314         m_friStartPos = 0;
00315         m_volume_p->Rewind();
00316         m_volume_p->SeekFileMark(2);
00317         m_friStartPos = m_currentVolume_p->GetPosition();
00318 
00319         return true;
00320     }
00321     catch (const ivd_Error& ie) {
00322         if (ie.GetError() == ie_MEDIUM_EOM ||
00323             ie.GetError() == ie_MEDIUM_EOD) {
00324             log_DBG_m(dbg_LOW, "End of medium detected ==> No FRI on the tape.");
00325             return false;
00326         }
00327         else {
00328             log_DBG_m(dbg_LOW, "Error when positioning to the FRI.");
00329             m_bea.HandleError(ie, bea_OPREAD);
00330             throw;
00331         }
00332     }
00333 }

Here is the call graph for this function:

Here is the caller graph for this function:

void bea_FRI::CloseVolume (  ) 

Performs all "medium close" steps:

  • mark the volume closed in the RMDB
  • write the FRI on the data volume
  • write the FRI on the system volume
  • verification of data format of the FRI when writing.

This functionality is used during the migration and when closing the volume manually.

It is assumed that:

  • volume IDs were already read from the medium
  • volume is positioned to the end of data volume (PositionToStartOfFRI() can be used)

Error handling covers:

  • terminate close if the medium volume is empty
  • terminate close if RMDB can't be updated
  • undo (erasing incomplete FRI) if writing to medium fails
  • removing FRI with data format problems from disk and medium
  • deleting incomplete FRI detected on the system volume

FRI file is kept on the disk (the fri directory) if

  • writing of FRI to medium is not successful for data and system volume
  • the volume already contains the FRI and the medium is WORM (recreate FRI)
  • for FSC check or recovery purpose

Warning:
This function does not delete the FRI from the medium when recreating FRI.

Definition at line 97 of file bea_fri.cpp.

References bea_OPWRITE, bea_Medium::ChangeVolume(), CloseVolumeInRMDB(), dbg_LOW, DeleteFRIOnDisk(), DeleteFRIOnVolume(), cmn_Global::dirs, bea_Volume::Erase(), evt_ERROR, evt_WARNING, ivd_Directories::fri, g_cmn, i_BackEndAgent_i::GetBarcode(), bea_Medium::GetCurrentVolume(), ivd_BaseException::GetFriendly(), i_BackEndAgent_i::GetJobID(), bea_Drive::GetMedium(), bea_Volume::GetPosition(), bea_Volume::GetStartOfDataPosition(), bea_Medium::GetSysVolNumber(), bea_Volume::GetVolumeID(), bea_Volume::GetVolumeNumber(), i_BackEndAgent_i::HandleError(), ie_PRECONDITION, ivd_Error, log_DBG_m, log_FUNC_A_m, log_MARKLINE_m, log_WriteEvent(), m_bea, m_currentVolume_p, m_drive_p, m_friStartPos, m_sysVolume_p, m_volume_p, m_workDir, MoveFromWorkToFRI(), NULL, bea_Volume::SeekEOD(), bea_Volume::SeekFileMark(), cmn_UUID_t::ToString(), VerifyExistenceOfFileMark(), bea_Volume::WriteFileMarks(), and WriteFRI().

Referenced by CreateFRI(), and bea_MigrationThread::Migrate().

00097                           {
00098     log_FUNC_A_m(CloseVolume, "volID: " << m_volume_p->GetVolumeID() );
00099 
00100     // Prevent closing system volumes
00101     if (   m_sysVolume_p != NULL
00102         && m_volume_p->GetVolumeNumber() == m_sysVolume_p->GetVolumeNumber()) {
00103 
00104         log_MARKLINE_m;
00105         throw ivd_Error(ie_PRECONDITION, "System volume can't be closed.", true);
00106     }
00107 
00108     bea_Medium* med_p = m_drive_p->GetMedium();
00109     m_currentVolume_p = med_p->GetCurrentVolume();
00110 
00111     // Prevent closing empty medium volumes.
00112     UInt32_t pos = m_currentVolume_p->GetPosition();
00113     if (pos <= m_currentVolume_p->GetStartOfDataPosition()) {
00114         ostringstream sstr;
00115         sstr
00116             << "Vol " << m_currentVolume_p->GetVolumeNumber() << ": "
00117             << "Empty volume can't be closed.";
00118 
00119         log_WriteEvent(evt_WARNING, sstr.str(), "FRI",
00120             m_bea.GetJobID(), m_bea.GetBarcode() );
00121 
00122         throw ivd_Error(ie_PRECONDITION, sstr.str(), true);
00123     }
00124 
00125     // Throws exception if it fails --> close volume is terminated.
00126     CloseVolumeInRMDB();
00127 
00128     cmn_File fri(m_workDir + m_currentVolume_p->GetVolumeID().ToString());
00129 
00130     if (!fri.Exists()) {
00131         // No FRI on disk is not treated as an error situation.
00132         ostringstream sstr;
00133         sstr
00134                 << "Vol " << m_volume_p->GetVolumeNumber() << ": "
00135                 << "No FRI file on disk.";
00136 
00137         log_WriteEvent(evt_WARNING, sstr.str(), "FRI",
00138                        m_bea.GetJobID(), m_bea.GetBarcode() );
00139 
00140         return;
00141     };
00142 
00143     m_friStartPos = 0;
00144 
00145     // -- Data volume
00146     // Assumption is that the volume is already position to proper location
00147     // and writing can start.
00148     int successCount(0);
00149     try {
00150         m_currentVolume_p->WriteFileMarks();
00151         m_friStartPos = m_currentVolume_p->GetPosition();
00152     }
00153     catch (const ivd_Exception& ie) {
00154         // File mark was not written.
00155         ostringstream sstr;
00156         sstr
00157             << "Vol " << m_currentVolume_p->GetVolumeNumber() << ": "
00158             << "Error writing file mark: " << ie.GetFriendly();
00159 
00160         log_WriteEvent(evt_ERROR, sstr.str(), "FRI",
00161             m_bea.GetJobID(), m_bea.GetBarcode() );
00162 
00163         m_friStartPos = 0;
00164     }
00165     catch (...) {
00166         // File mark was not written.
00167         ostringstream sstr;
00168         sstr
00169             << "Vol " << m_currentVolume_p->GetVolumeNumber() << ": "
00170             << "Error writing file mark.";
00171 
00172         log_WriteEvent(evt_ERROR, sstr.str(), "FRI",
00173             m_bea.GetJobID(), m_bea.GetBarcode() );
00174 
00175         m_friStartPos = 0;
00176     }
00177 
00178     if (m_friStartPos > m_currentVolume_p->GetStartOfDataPosition()) {
00179         if (WriteFRI()) {
00180             ++successCount;
00181         }
00182     }
00183 
00184     if (m_sysVolume_p != NULL) {
00185         // -- System volume
00186 
00187         if (!fri.Exists()) {
00188         // No FRI on disk is not treated as an error situation.
00189             ostringstream sstr;
00190             sstr
00191                     << "Vol " << m_volume_p->GetVolumeNumber() << ": "
00192                     << "No FRI file on disk.";
00193 
00194             log_WriteEvent(evt_WARNING, sstr.str(), "FRI",
00195                            m_bea.GetJobID(), m_bea.GetBarcode() );
00196 
00197             return;
00198         };
00199 
00200         bool readyToWrite(true);
00201 
00202         // Change to end of system volume.
00203         med_p->ChangeVolume( med_p->GetSysVolNumber() );
00204         m_currentVolume_p = med_p->GetCurrentVolume();
00205         m_currentVolume_p->SeekEOD();
00206 
00207         m_friStartPos = 0;
00208         // Verify existance of FM at the end of the system volume
00209         if (VerifyExistenceOfFileMark(m_currentVolume_p->GetPosition()-1))  {
00210             log_DBG_m(dbg_LOW,
00211                 "System volume contains FM on pos: " <<
00212                 m_currentVolume_p->GetPosition() );
00213         }
00214         else {
00215             // No file mark at the end of sysvol
00216             //   --> delete last FRI on the volume: it is incomplete.
00217             try {
00218                 ostringstream sstr;
00219                 sstr
00220                     << "Vol " << m_currentVolume_p->GetVolumeNumber() << ": "
00221                     << "Erasing incomplete FRI on the system volume.";
00222 
00223                 log_WriteEvent(sstr.str(), "FRI",
00224                     m_bea.GetJobID(), m_bea.GetBarcode() );
00225 
00226                 m_currentVolume_p->SeekFileMark(-1);
00227                 m_currentVolume_p->SeekFileMark(1);
00228                 m_currentVolume_p->Erase();
00229             }
00230             catch (const ivd_Exception& ie) {
00231                 ostringstream sstr;
00232                 sstr
00233                     << "Vol " << m_currentVolume_p->GetVolumeNumber() << ": "
00234                     << "FRI won't be written to system volume beacause "
00235                     << "erase of incomplete FRI on system volume failed: "
00236                     << ie.GetFriendly();
00237 
00238                 log_WriteEvent(evt_WARNING, sstr.str(), "FRI",
00239                     m_bea.GetJobID(), m_bea.GetBarcode() );
00240 
00241                 readyToWrite = false;
00242             }
00243         }
00244 
00245         // Store position of the FRI
00246         m_friStartPos = m_currentVolume_p->GetPosition();
00247         if (WriteFRI()) {
00248             ++successCount;
00249         }
00250         try {
00251             // Write file mark after the FRI on system volume
00252             m_currentVolume_p->WriteFileMarks();
00253         }
00254         catch (const ivd_Error& ie) {
00255             // FRI on volume is not valid, no matter which error has occurred.
00256             DeleteFRIOnVolume();
00257             m_bea.HandleError(ie, bea_OPWRITE);
00258         }
00259         catch (...) {
00260             DeleteFRIOnVolume();
00261         }
00262     }
00263 
00264     if (successCount > 0) {
00265         if (m_workDir == g_cmn.dirs.fri) {
00266             DeleteFRIOnDisk();
00267         }
00268     }
00269     else {
00270         if (!fri.Exists()) {
00271             log_DBG_m(dbg_LOW, "No FRI on disk.");
00272         }
00273         else {
00274             ostringstream sstr;
00275             sstr
00276                 << "Vol " << m_currentVolume_p->GetVolumeNumber() << ": "
00277                 << "FRI can't be written to medium and is left on disk.";
00278 
00279             log_WriteEvent(evt_WARNING, sstr.str(), "FRI",
00280                 m_bea.GetJobID(), m_bea.GetBarcode() );
00281 
00282             if (m_workDir != g_cmn.dirs.fri) {
00283                 log_DBG_m(dbg_LOW, "Moving FRI file to " << g_cmn.dirs.fri);
00284                 MoveFromWorkToFRI();
00285             }
00286         } // else
00287     }
00288 }

Here is the call graph for this function:

Here is the caller graph for this function:

void bea_FRI::CloseVolumeInRMDB (  ) 

Definition at line 766 of file bea_fri.cpp.

References dbg_LOW, evt_ERROR, i_BackEndAgent_i::GetBarcode(), ivd_BaseException::GetFriendly(), i_BackEndAgent_i::GetJobID(), i_BackEndAgent_i::GetRM(), bea_Volume::GetVolumeID(), bea_Volume::GetVolumeNumber(), ipc_EXEC_m, log_DBG_m, log_FUNC_m, log_WriteEvent(), m_bea, m_volume_p, and cmn_UUID_t::ToString().

Referenced by bea_MigrationThread::CheckFRI(), CloseVolume(), and bea_MigrationThread::Migrate().

00766                                 {
00767     log_FUNC_m(CloseVolumeInRMDB);
00768 
00769     log_DBG_m(dbg_LOW,
00770         "Mark media volume full in RMDB." << m_volume_p->GetVolumeID());
00771 
00772     try {
00773         ipc_EXEC_m(
00774             i_ResourceManager_var rm = m_bea.GetRM();
00775             rm->VolumeFull(
00776                 CORBA::string_dup(m_volume_p->GetVolumeID().ToString().c_str()) );
00777         );
00778     }
00779     catch (const ivd_Exception& ie) {
00780         ostringstream sstr;
00781         sstr
00782             << "Vol " << m_volume_p->GetVolumeNumber() << ": "
00783             << "Setting volume full in RMDM failed. "
00784             << "Error: " << ie.GetFriendly() << " "
00785             << "Close volume manually.";
00786 
00787         log_WriteEvent(evt_ERROR, sstr.str(), "FRI",
00788             m_bea.GetJobID(), m_bea.GetBarcode() );
00789 
00790         throw;
00791     }
00792     catch (...) {
00793         ostringstream sstr;
00794         sstr
00795             << "Vol " << m_volume_p->GetVolumeNumber() << ": "
00796             << "Setting volume full in RMDM failed. "
00797             << "Close volume manually.";
00798 
00799         log_WriteEvent(evt_ERROR, sstr.str(), "FRI",
00800             m_bea.GetJobID(), m_bea.GetBarcode() );
00801 
00802         throw;
00803     }
00804 }

Here is the call graph for this function:

Here is the caller graph for this function:

bool bea_FRI::ReadFRIStart ( cmn_UUID_t a_volID  ) 

Reads first block of FRI and extracts volume ID.

Parameters:
a_volID OUT read volume ID
Return values:
true end of volume encountered

Definition at line 349 of file bea_fri.cpp.

References bea_OPREAD, blk_FRI_c, cmn_UUID_t::Clear(), dbg_LOW, evt_WARNING, i_BackEndAgent_i::GetBarcode(), bea_Medium::GetBarcode(), bea_Volume::GetBlockSize(), ivd_BaseException::GetError(), ivd_BaseException::GetFriendly(), i_BackEndAgent_i::GetJobID(), bea_Drive::GetMedium(), bea_Volume::GetStartOfDataPosition(), bea_Volume::GetVolumeNumber(), i_BackEndAgent_i::HandleError(), ie_MEDIUM_EOD, ie_MEDIUM_EOM, ie_MEDIUM_FILEMARK, log_DBG_m, log_FUNC_m, log_WriteEvent(), log_WRN_m, m_bea, m_drive_p, m_volume_p, ntoh(), NULL, df_RecFRIStart_t::partID, df_RecFRIStart_t::poolID, bea_Volume::Read(), rec_FRIStart_c, rec_NoRec_c, df_RecFRIStart_t::startPos, df_RecCmn_t::type, df_BlockProxy::VerifiedBlock(), df_RecReader::VerifiedRecCmn(), and df_RecFRIStart_t::volID.

Referenced by bea_FRIThread::CheckFRI(), and bea_FRIThread::ReadFromSysVol().

00349                                               {
00350     log_FUNC_m(ReadFRIStart);
00351 
00352     a_volID.Clear();
00353 
00354     // Read block and parse the contents to get the
00355     // media volume UUID.
00356     vector<UInt8_t> block(m_volume_p->GetBlockSize(), 0);
00357     try {
00358         m_volume_p->Read(&(block[0]));
00359     }
00360     catch (ivd_Error &ie) {
00361         if (ie.GetError() == ie_MEDIUM_EOD) {
00362             log_DBG_m(dbg_LOW, "End of data. Stop reading FRI.");
00363             return true;
00364         }
00365         else if (ie.GetError() == ie_MEDIUM_FILEMARK) {
00366             log_DBG_m(dbg_LOW, "File mark detected -> No FRI.");
00367             return false;
00368         }
00369         else if (ie.GetError() == ie_MEDIUM_EOM) {
00370             log_DBG_m(dbg_LOW, "Early End of medium. Ignore.");
00371         }
00372         else {
00373             m_bea.HandleError(ie, bea_OPREAD);
00374             throw;
00375         }
00376     };
00377 
00378     const df_BlockHeader_t* blkHdr_p(NULL);
00379     try {
00380         UInt32_t blockNum(0);
00381         blkHdr_p = df_BlockReader::VerifiedBlock(
00382             &(block[0]), m_volume_p->GetBlockSize(), blockNum, blk_FRI_c, 0);
00383     }
00384     catch (const ivd_DFError& de) {
00385         log_WRN_m(
00386             m_drive_p->GetMedium()->GetBarcode() <<
00387             ": Reading FRI from system volume." <<
00388             " Data format in FRI header record: " << de.GetFriendly() );
00389             return false;
00390     }
00391 
00392     UInt32_t recNum(0), prevRecType(rec_NoRec_c);
00393     const df_RecCmn_t* recCmn_p = df_RecReader::VerifiedRecCmn(
00394         &(block[sizeof(*blkHdr_p)]),
00395         recNum, blk_FRI_c, prevRecType, 0);
00396 
00397     if (recCmn_p->type != rec_FRIStart_c) {
00398         log_WRN_m(
00399             m_drive_p->GetMedium()->GetBarcode() <<
00400             ": Reading FRI from system volume." <<
00401             " Invalid record type found." <<
00402             " (Expected FRIs, found " <<
00403             reinterpret_cast<const char*>(&(recCmn_p->type)) << ")");
00404 
00405         return false;
00406 
00407         // TODO: Shall reaction be more rigorous in this case?
00408     };
00409 
00410     const df_RecFRIStart_t* fris_p =
00411         reinterpret_cast<const df_RecFRIStart_t*>(
00412             &(block[0]) + sizeof(*blkHdr_p) + sizeof(*recCmn_p) );
00413 
00414     UInt32_t friStartPos = ntoh(fris_p->startPos);
00415     log_DBG_m(dbg_LOW,
00416         "Got FRI for:" << endl <<
00417         "volID  : " << fris_p->volID << endl <<
00418         "poolID : " << fris_p->poolID << endl <<
00419         "partID : " << fris_p->partID << endl <<
00420         "startP : " << friStartPos);
00421 
00422     if (friStartPos > m_volume_p->GetStartOfDataPosition()) {
00423         ostringstream sstr;
00424         sstr
00425             << "Vol " << m_volume_p->GetVolumeNumber() << ": "
00426             << "FRI doesn't cover complete medium. "
00427             << "FRI start position: " << friStartPos;
00428 
00429         log_WriteEvent(evt_WARNING, sstr.str(), "FRI",
00430             m_bea.GetJobID(), m_bea.GetBarcode() );
00431     }
00432     else {
00433         // FRI start is valid.
00434         a_volID = fris_p->volID;
00435     }
00436 
00437     return false;
00438 }

Here is the call graph for this function:

Here is the caller graph for this function:

bool bea_FRI::ReadFRI ( const cmn_UUID_t a_volID  ) 

Reads one FRI from current medium position.

Return values:
true Reading stopped because of encountered file mark
false Reading stopped because of other reasons (end of volume...)

Definition at line 448 of file bea_fri.cpp.

References bea_OPREAD, dbg_DETAIL, dbg_LOW, dbg_NORM, DeleteFRIOnDisk(), DeleteFRIOnVolume(), df_DISKFRI_BLOCKS_c, evt_WARNING, df_MgrWriter::Flush(), i_BackEndAgent_i::GetBarcode(), df_DataBlock::GetBlockSize(), bea_Volume::GetBlockSize(), ivd_BaseException::GetError(), df_MgrWriter::GetFree(), i_BackEndAgent_i::GetJobID(), bea_Drive::GetMedium(), bea_Medium::GetMediumMem(), cmn_Time::GetMilliTime(), df_DataBlock::GetPosition(), cmn_Time::GetTime_t(), bea_Volume::GetVolumeNumber(), i_BackEndAgent_i::HandleError(), ie_MEDIUM_EOD, ie_MEDIUM_EOM, ie_MEDIUM_FILEMARK, ie_MEDIUM_HWERR, ie_MEDIUM_ILENGTH, ie_MEDIUM_MEDERR, i_BackEndAgent_i::IsAborted(), bea_Medium::IsMediumMemValid(), bea_Volume::IsSysVolume(), log_DBG_m, log_FUNC_A_m, log_WriteEvent(), m_bea, m_currentVolume_p, m_drive_p, m_extension, m_recreateInto, m_volume_p, m_workDir, df_DataBlock::Move(), NULL, bea_Volume::Read(), cmn_UUID_t::ToString(), and bea_MediumMemory::UpdateAccess().

Referenced by bea_FRIThread::ReadFRI(), and bea_FRIThread::ReadFromSysVol().

00448                                                {
00449     log_FUNC_A_m(ReadFRI, "volid: " << a_volID);
00450 
00451     ostringstream sstr;
00452     if (m_volume_p->IsSysVolume()) {
00453         sstr
00454             << "Vol " << m_volume_p->GetVolumeNumber()
00455             << ": Reading FRI from system volume for " << a_volID;
00456     }
00457     else {
00458         sstr
00459             << "Vol " << m_volume_p->GetVolumeNumber()
00460             << ": Reading FRI from data volume for " << a_volID;
00461     }
00462     log_WriteEvent( sstr.str(), "", m_bea.GetJobID(), m_bea.GetBarcode() );
00463 
00464     m_currentVolume_p = m_volume_p;
00465 
00466     UInt64_t friSize(0);
00467     cmn_Time startTime;
00468 
00469     df_BlockManager mgr(m_volume_p->GetBlockSize(), df_DISKFRI_BLOCKS_c);
00470 
00471     blk_DiskFRIWriter *fri_p =
00472         new blk_DiskFRIWriter(  mgr, 
00473                                 a_volID.ToString(), 
00474                                 !m_recreateInto, 
00475                                 true,
00476                                 m_recreateInto,
00477                                 m_workDir,
00478                                 m_extension);
00479 
00480     fri_p->Start();
00481 
00482     bool fileMark(false);
00483     bool fileValid(true);
00484     {
00485         df_MgrWriter writer(mgr);
00486 
00487         df_DataBlock *blk(NULL);
00488         bool         eod(false);
00489 
00490         while ( (blk = writer.GetFree()) != NULL && !eod ) {
00491             try {
00492                 m_volume_p->Read(blk->GetPosition());
00493                 // Simulate ie_MEDIUM_MEDERR error 
00494                 //SimulateMediumError();                
00495                 blk->Move(m_volume_p->GetBlockSize());
00496                 friSize += blk->GetBlockSize();
00497                 writer.Flush();
00498             }
00499             catch (const ivd_Error &ie) {
00500                 switch (ie.GetError()) {
00501                     case ie_MEDIUM_FILEMARK:
00502                         log_DBG_m(dbg_LOW,
00503                             "File mark detected ==> stop reading data.");
00504                         eod = fileMark = true;
00505                         break;
00506                     case ie_MEDIUM_EOM:
00507                         log_DBG_m(dbg_LOW,
00508                             "Early end of medium detected ==> continue.");
00509                         break;
00510                     case ie_MEDIUM_EOD:
00511                         log_DBG_m(dbg_LOW,
00512                             "End of data detected ==> stop reading data.");
00513                         eod = true;
00514                         break;
00515                     case ie_MEDIUM_ILENGTH:
00516                         log_DBG_m(dbg_LOW, "Illegal block length. Invalid FRI.");
00517                         eod = true;
00518                         fileValid = false;
00519                         break;
00520                     case ie_MEDIUM_MEDERR:
00521                         log_DBG_m(dbg_LOW,
00522                             "MED error while reading FRI ==> re-throw.");
00523                         if (!m_currentVolume_p->IsSysVolume()) {
00524                             m_bea.HandleError(ie, bea_OPREAD);
00525                         }
00526                         throw;
00527                     case ie_MEDIUM_HWERR:
00528                         log_DBG_m(dbg_LOW,
00529                             "HW error while reading FRI ==> re-throw.");
00530                         m_bea.HandleError(ie, bea_OPREAD);
00531                         throw;
00532                     default:
00533                         log_DBG_m(dbg_LOW, "Other error when reading.");
00534                         eod = true;
00535                         fileValid = false;
00536                         break;
00537                 }
00538             } // catch
00539 
00540             if (m_bea.IsAborted()) {
00541                 log_DBG_m(dbg_DETAIL, "Operation aborted.");
00542                 break;
00543             }
00544 
00545         }// while
00546     }
00547 
00548     try {
00549         if (m_drive_p->GetMedium()->IsMediumMemValid()) {
00550             bea_MediumMemory* mm = m_drive_p->GetMedium()->GetMediumMem();
00551             mm->UpdateAccess(m_volume_p->GetVolumeNumber());
00552         }
00553     }
00554     catch(const ivd_Exception &ie) {
00555         log_DBG_m(dbg_LOW, "Error updating MIC. Ignored: " << ie );
00556     }
00557 
00558     if (m_volume_p->IsSysVolume()) {
00559         if (friSize > 0) {
00560             if (m_bea.IsAborted()) {
00561                 log_DBG_m(dbg_LOW, "Aborted operation. Delete FRI on disk.");
00562                 DeleteFRIOnDisk(a_volID);
00563                 return false;
00564             }
00565             else if (!fileMark) {
00566                 ostringstream sstr;
00567                 sstr
00568                     << "Vol " << m_volume_p->GetVolumeNumber() << ": "
00569                     << "Missing file mark after the FRI on system volume."
00570                     << "Erasing the incomplete FRI.";
00571 
00572                 log_WriteEvent(evt_WARNING, sstr.str(), "FRI",
00573                     m_bea.GetJobID(), m_bea.GetBarcode() );
00574 
00575                 DeleteFRIOnVolume();
00576                 DeleteFRIOnDisk(a_volID);
00577             }
00578             return fileMark;
00579         }
00580     }
00581 
00582     if (!fileValid) {
00583         log_DBG_m(dbg_LOW, "FRI file is not valid. Will be deleted on disk.");
00584         if (friSize > 0) {
00585             DeleteFRIOnDisk(a_volID);
00586             return false;
00587         }
00588     }
00589 
00590     cmn_Time endTime;
00591     cmn_Time diffTime = endTime - startTime;
00592 
00593     UInt64_t msecDiff =
00594             UInt64_t(diffTime.GetTime_t()) * 1000 +
00595             diffTime.GetMilliTime();
00596 
00597     if (msecDiff == 0) {
00598         msecDiff = 1;
00599     }
00600 
00601     UInt64_t speed = (friSize * 1000) / (msecDiff * 1024) ;
00602 
00603     // log FRI read statistics
00604     sstr.str("");
00605     if (m_volume_p->IsSysVolume()) {
00606         sstr
00607             << "Vol " << m_volume_p->GetVolumeNumber()
00608             << ": FRI read from system volume for " << a_volID
00609             << " : " << friSize / 1024 << " KB (" << speed << " KB/s).";
00610     }
00611     else {
00612         sstr
00613             << "Vol " << m_volume_p->GetVolumeNumber()
00614             << ": FRI read from data volume for " << a_volID
00615             << " : " << friSize / 1024 << " KB (" << speed << " KB/s).";
00616     }
00617     log_WriteEvent( sstr.str(), "", m_bea.GetJobID(), m_bea.GetBarcode() );
00618 
00619     log_DBG_m(dbg_NORM, "FRI dumped to disk.");
00620 
00621     return fileMark;
00622 }

Here is the call graph for this function:

Here is the caller graph for this function:

void bea_FRI::CreateFRI ( bool  a_volumeClosed  ) 

Definition at line 626 of file bea_fri.cpp.

References bbt_DISK_FRI, bbt_TAPE_READ, blk_Data_c, blk_FRI_c, CloseVolume(), dbg_LOW, dbg_NORM, cmn_Global::dirs, bea_Volume::Erase(), evt_ERROR, evt_WARNING, ivd_Directories::fri, g_cmn, i_BackEndAgent_i::GetBarcode(), bea_Volume::GetBlockSize(), bea_Medium::GetCurrentVolume(), ivd_BaseException::GetFriendly(), i_BackEndAgent_i::GetJobID(), bea_Drive::GetMedium(), df_BlockReader::GetMgr(), bea_Volume::GetPartitionID(), bea_Volume::GetPoolID(), bea_Volume::GetStartOfDataPosition(), bea_Volume::GetVolumeID(), bea_Volume::GetVolumeNumber(), bea_Medium::IsWORM(), log_DBG_m, log_FUNC_m, log_WriteEvent(), log_WRN_m, m_bea, m_currentVolume_p, m_drive_p, m_extension, m_recreateInto, m_volume_p, m_workDir, MoveFromWorkToFRI(), bea_Volume::MustDumpFRI(), SaveFRIOnError(), bea_Volume::SeekBlock(), bea_Volume::SeekFileMark(), and cmn_UUID_t::ToString().

Referenced by bea_FRIThread::CreateFRI().

00626                                            {
00627     log_FUNC_m(CreateFRI);
00628 
00629     bea_Medium* med = m_drive_p->GetMedium();
00630     m_currentVolume_p = med->GetCurrentVolume();
00631 
00632     m_currentVolume_p->SeekBlock(m_currentVolume_p->GetStartOfDataPosition());
00633 
00634     ostringstream sstr;
00635     sstr
00636         << "Vol " << m_volume_p->GetVolumeNumber()
00637         << ": Creating new FRI. " << m_volume_p->GetVolumeID();
00638 
00639     log_WriteEvent( sstr.str(), "", m_bea.GetJobID(), m_bea.GetBarcode() );
00640 
00641     bool fmDetected(false);
00642 
00643     try {
00644         // Prepare output
00645         df_Writer writer(blk_FRI_c, bbt_DISK_FRI, m_volume_p->GetBlockSize());
00646 
00647         bool createFRIonTmp = (m_workDir != g_cmn.dirs.fri) && !m_recreateInto;
00648 
00649         writer.NewFRIBuffer(m_volume_p->GetVolumeID().ToString(),
00650                             true,
00651                             createFRIonTmp,
00652                             m_recreateInto,
00653                             m_workDir,
00654                             m_extension);
00655         writer.Go();
00656 
00657         // Prepare input
00658         {
00659             //
00660             // ** IMPORTANT **
00661             // These objects must be in a separate
00662             // block, because ~df_FRIDistiller() must be called
00663             // before writer.EndOfData().
00664             //
00665 
00666             df_BlockReader *blockReader_p =
00667                 new df_BlockReader(
00668                 blk_Data_c, bbt_TAPE_READ, m_volume_p->GetBlockSize());
00669 
00670             df_FRIDistiller dist(
00671                 blockReader_p,
00672                 m_volume_p->GetVolumeID(),
00673                 m_volume_p->GetPoolID(),
00674                 m_volume_p->GetPartitionID(),
00675                 writer);
00676 
00677             bea_VolumeReader *volReader =
00678                 new bea_VolumeReader(
00679                     blockReader_p->GetMgr(),
00680                     m_volume_p,
00681                     fmDetected);
00682 
00683             volReader->Start();
00684 
00685             dist.Unpack();
00686         }
00687 
00688         writer.EndOfData();
00689     }
00690     catch (const ivd_Error &ie) {
00691         sstr.str("");
00692         sstr
00693             << "FAILED creating new FRI: " << m_volume_p->GetVolumeID()
00694             << ". Error: " << ie.GetFriendly();
00695 
00696         log_WriteEvent(evt_ERROR, sstr.str(), "", m_bea.GetJobID(), m_bea.GetBarcode() );
00697         // partial and hopefully temporary solution for
00698         // problem reported in bug 7399
00699 
00700         // DeleteFRIOnDisk();
00701         SaveFRIOnError();
00702         throw;
00703     };
00704     
00705     if (m_recreateInto) {
00706         return;
00707     }
00708 
00709     // Write the FRI back to the medium if it was created on demand.
00710     if(fmDetected) {
00711         if (!a_volumeClosed) {
00712             log_WRN_m(
00713                 "Volume not closed in RMDB, but there is FRI on volume: " <<
00714                 "FRI will be closed and FRI overwritten. " <<
00715                 m_bea.GetBarcode() << "/" << m_volume_p->GetVolumeNumber());
00716         }
00717 
00718         if (!med->IsWORM()) {
00719             log_DBG_m(dbg_NORM, "Overwriting old FRI.");
00720             // Overwrite old FRI
00721             m_volume_p->SeekFileMark(-1);
00722             m_volume_p->Erase();
00723             CloseVolume();
00724         }
00725         else {
00726             ostringstream sstr;
00727             sstr
00728                 << "Vol " << m_volume_p->GetVolumeNumber() << ": "
00729                 << "WORM medium --> FRI left on disk. ";
00730 
00731             log_WriteEvent(evt_WARNING, sstr.str(), "FRI",
00732                 m_bea.GetJobID(), m_bea.GetBarcode() );
00733 
00734             if (m_workDir != g_cmn.dirs.fri) {
00735                 log_DBG_m(dbg_LOW, "Moving FRI file to " << g_cmn.dirs.fri);
00736                 MoveFromWorkToFRI();
00737             }
00738         }
00739     }
00740     else if (a_volumeClosed) {
00741         log_WRN_m(
00742             "Volume already closed in RMDB, but no FRI on volume. " <<
00743             "Writing FRI. " <<
00744             m_bea.GetBarcode() << "/" << m_volume_p->GetVolumeNumber() );
00745 
00746         CloseVolume();
00747     }
00748     else if (m_volume_p->MustDumpFRI()) {
00749         log_DBG_m(dbg_NORM, "Dumping FRI to the end of volume.");
00750         // Medium volume is full enough to dump the FRI.
00751         CloseVolume();
00752     }
00753     else {
00754         log_DBG_m(dbg_NORM,
00755             "Volume still has space for data. FRI created on the disk.");
00756         if (m_workDir != g_cmn.dirs.fri) {
00757             log_DBG_m(dbg_LOW, "Moving FRI file to " << g_cmn.dirs.fri);
00758             MoveFromWorkToFRI();
00759         }
00760     };
00761 
00762 }

Here is the call graph for this function:

Here is the caller graph for this function:

void bea_FRI::DeleteFRIOnVolume (  ) 

Deletes last FRI on current volume (data or system).

Definition at line 1091 of file bea_fri.cpp.

References bea_OPWRITE, dbg_LOW, bea_Volume::Erase(), evt_ERROR, evt_WARNING, i_BackEndAgent_i::GetBarcode(), ivd_BaseException::GetFriendly(), i_BackEndAgent_i::GetJobID(), bea_Drive::GetMedium(), bea_Volume::GetVolumeNumber(), i_BackEndAgent_i::HandleError(), bea_Medium::IsWORM(), log_DBG_m, log_FUNC_m, log_WriteEvent(), m_bea, m_currentVolume_p, m_drive_p, m_friStartPos, m_volume_p, and VerifyExistenceOfFileMark().

Referenced by bea_FRIThread::CheckFRI(), CloseVolume(), ReadFRI(), and WriteFRI().

01091                                 {
01092     log_FUNC_m(DeleteFRIOnVolume);
01093 
01094     if (m_drive_p->GetMedium()->IsWORM()) {
01095         log_DBG_m(dbg_LOW, "FRI on WORM medium can't be deleted.")
01096         return;
01097     }
01098 
01099     // Stored start FRI position should be at least header + FRI file mark
01100     if (m_friStartPos < m_currentVolume_p->GetStartOfDataPosition() + 1) {
01101         log_DBG_m(dbg_LOW,
01102             "FRI start position not stored: " << m_friStartPos << " "<<
01103             "Won't delete FRI on medium.");
01104         return;
01105     }
01106 
01107     ostringstream sstr;
01108     sstr
01109         << "Vol " << m_volume_p->GetVolumeNumber() << ": "
01110         << "Deleting FRI on medium volume.";
01111 
01112     log_WriteEvent(sstr.str(), "FRI",
01113         m_bea.GetJobID(), m_bea.GetBarcode() );
01114 
01115     log_DBG_m(dbg_LOW,
01116         "Seeking to stored position: " << m_friStartPos << " "<<
01117         "and verifying the existence of FRI file mark.");
01118 
01119     if (! VerifyExistenceOfFileMark(m_friStartPos - 1) ) {
01120         ostringstream sstr;
01121         sstr
01122             << "Vol " << m_currentVolume_p->GetVolumeNumber() << ": "
01123             << "FRI on the volume won't be deleted. No FRI file mark present.";
01124 
01125         log_WriteEvent(evt_WARNING, sstr.str(), "FRI",
01126             m_bea.GetJobID(), m_bea.GetBarcode() );
01127 
01128         m_friStartPos = 0;
01129         return;
01130     }
01131     m_friStartPos = 0;
01132 
01133     // File mark verification passed. Delete the FRI on the medium.
01134     log_DBG_m(dbg_LOW, "Deleting the FRI on the medium.");
01135 
01136     try {
01137         m_currentVolume_p->Erase();
01138     }
01139     catch (const ivd_Error& ie) {
01140         ostringstream sstr;
01141         sstr
01142             << "Vol " << m_currentVolume_p->GetVolumeNumber() << ": "
01143             << "Error when deleting invalid FRI on the medium: " << ie.GetFriendly();
01144 
01145         log_WriteEvent(evt_ERROR, sstr.str(), "FRI",
01146             m_bea.GetJobID(), m_bea.GetBarcode() );
01147 
01148         m_bea.HandleError(ie, bea_OPWRITE);
01149     }
01150     catch (...) {
01151         ostringstream sstr;
01152         sstr
01153             << "Vol " << m_currentVolume_p->GetVolumeNumber() << ": "
01154             << "Unknown error when deleting invalid FRI on the medium.";
01155 
01156         log_WriteEvent(evt_ERROR, sstr.str(), "FRI",
01157             m_bea.GetJobID(), m_bea.GetBarcode() );
01158 
01159         return;
01160     }
01161 }

Here is the call graph for this function:

Here is the caller graph for this function:

UInt32_t bea_FRI::GetFRIStartPosition (  )  const

Definition at line 337 of file bea_fri.cpp.

References m_friStartPos.

Referenced by bea_FRIThread::ProcessFromDataVol().

00337                                             {
00338     return m_friStartPos;
00339 }

Here is the caller graph for this function:

bool bea_FRI::WriteFRI (  )  [private]

Definition at line 807 of file bea_fri.cpp.

References CopyFromDiskToMedium(), DeleteFRIOnDisk(), DeleteFRIOnVolume(), evt_WARNING, i_BackEndAgent_i::GetBarcode(), ivd_BaseException::GetFriendly(), i_BackEndAgent_i::GetJobID(), bea_Volume::GetVolumeNumber(), log_FUNC_m, log_WriteEvent(), m_bea, m_volume_p, and i_BackEndAgent_i::UpdateVolumeUsed().

Referenced by CloseVolume().

00807                        {
00808     log_FUNC_m(WriteFRI);
00809 
00810     try {
00811         CopyFromDiskToMedium();
00812         m_bea.UpdateVolumeUsed();
00813         return true;
00814     }
00815     catch (const ivd_DFError& dfe) {
00816         // FRI on disk is not useful and must be recreated.
00817         ostringstream sstr;
00818         sstr
00819             << "Vol " << m_volume_p->GetVolumeNumber() << ": "
00820             << "Detected data format error in FRI on disk.  It will be deleted "
00821             << "from the disk and medium volume to prevent future recovery "
00822             << "errors. FRI will be rebuilt on next use. ("
00823             << dfe.GetFriendly() << ")";
00824 
00825         log_WriteEvent(evt_WARNING, sstr.str(), "FRI",
00826             m_bea.GetJobID(), m_bea.GetBarcode() );
00827 
00828         DeleteFRIOnDisk();
00829         DeleteFRIOnVolume();
00830     }
00831     catch (const ivd_Error) {
00832         // FRI on volume is not valid, no matter which error has occurred.
00833         DeleteFRIOnVolume();
00834     }
00835     catch (const ivd_SysError) {
00836         DeleteFRIOnVolume();
00837     }
00838     catch (...) {
00839         DeleteFRIOnVolume();
00840     }
00841     return false;
00842 }

Here is the call graph for this function:

Here is the caller graph for this function:

void bea_FRI::CopyFromDiskToMedium (  )  [private]

Definition at line 846 of file bea_fri.cpp.

References bbt_DISK_FRI, bea_OPWRITE, blk_FRI_c, dbg_DETAIL, dbg_LOW, dbg_NORM, evt_ERROR, bea_Volume::Flush(), fom_OPEN_EXISTING, fom_READ, i_BackEndAgent_i::GetBarcode(), bea_Volume::GetBlockSize(), ivd_BaseException::GetError(), ivd_BaseException::GetFriendly(), i_BackEndAgent_i::GetJobID(), cmn_Time::GetMilliTime(), cmn_Time::GetTime_t(), bea_Volume::GetVolumeID(), bea_Volume::GetVolumeNumber(), i_BackEndAgent_i::HandleError(), ie_DATA_CORRUPTION, ie_MEDIUM_EOM, log_DBG_m, log_FUNC_m, log_WriteEvent(), m_bea, m_currentVolume_p, m_volume_p, m_workDir, cmn_UUID_t::ToString(), and bea_Volume::Write().

Referenced by WriteFRI().

00846                                    {
00847     log_FUNC_m(CopyFromDiskToMedium);
00848 
00849     log_DBG_m(dbg_DETAIL,
00850         "workDir: " << m_workDir <<
00851         ", m_volume_p: 0x" << m_volume_p);
00852 
00853     cmn_File fri(m_workDir + m_volume_p->GetVolumeID().ToString());
00854 
00855     log_DBG_m(dbg_LOW,
00856         "Copy FRI file :" << fri.GetFullPathRef() <<
00857         " to :" << m_bea.GetBarcode() << "/" << m_currentVolume_p->GetVolumeNumber());
00858 
00859     UInt64_t friSize(0);
00860     try {
00861         fri.OpenF(fom_READ | fom_OPEN_EXISTING);
00862         ivd_FileInfo_t  friInfo;
00863         fri.StatF(friInfo);
00864         friSize = (friInfo.size / 1024);
00865     }
00866     catch (const ivd_SysError& se) {
00867         ostringstream sstr;
00868         sstr
00869             << "Vol " << m_volume_p->GetVolumeNumber() << ": "
00870             << "FRI file can't be accessed. Error: " << se.GetFriendly();
00871 
00872         log_WriteEvent(evt_ERROR, sstr.str(), "FRI",
00873             m_bea.GetJobID(), m_bea.GetBarcode() );
00874 
00875         throw;
00876     }
00877 
00878     UInt32_t blockSize(m_volume_p->GetBlockSize());
00879     UInt32_t blocksWritten(0);
00880     vector<UInt8_t> buffer(blockSize);
00881 
00882     df_RecReader parser(new df_BlockProxy(blk_FRI_c, bbt_DISK_FRI, blockSize), m_volume_p->GetVolumeID());
00883 
00884     cmn_Time startTime;
00885     // Copy loop
00886     while (true) {
00887 
00888         UInt32_t bytesRead = fri.ReadF(&(buffer[0]), blockSize);
00889 
00890         if (bytesRead == 0) {
00891             log_DBG_m(dbg_LOW, "End of FRI file.");
00892             break;
00893         }
00894 
00895         if (bytesRead < blockSize) {
00896             ostringstream sstr;
00897             sstr
00898                 << "Read request of " << blockSize
00899                 << " bytes returned only " << bytesRead;
00900 
00901             throw ivd_DFError(
00902                 ie_DATA_CORRUPTION, blocksWritten, sstr.str(), true);
00903         }
00904 
00905         // Verify data format to prevent having invalid FRI on the medium.
00906         // Throws ivd_DFError
00907         (void)parser.Unpack(&(buffer[0]), blocksWritten);
00908 
00909         try {
00910             m_currentVolume_p->Write(&(buffer[0]));
00911         }
00912         catch (const ivd_Error &ie) {
00913             if (ie.GetError() == ie_MEDIUM_EOM) {
00914                 log_DBG_m(dbg_NORM, "Early EOM on Write - ignore for FRI.");
00915             }
00916             else {
00917                 m_bea.HandleError(ie, bea_OPWRITE);
00918                 throw;
00919             }
00920         }
00921         ++blocksWritten;
00922     } // while
00923 
00924     try {
00925         m_currentVolume_p->Flush();
00926     }
00927     catch (const ivd_Exception& ie) {
00928         if (ie.GetError() == ie_MEDIUM_EOM) {
00929             log_DBG_m(dbg_NORM, "Early EOM on Write FM - ignore for FRI.");
00930         }
00931         else {
00932             ostringstream sstr;
00933             sstr
00934                 << "Vol " << m_volume_p->GetVolumeNumber() << ": "
00935                 << "Error flushing FRI to medium: " << ie.GetFriendly();
00936 
00937             log_WriteEvent(evt_ERROR, sstr.str(), "FRI",
00938                 m_bea.GetJobID(), m_bea.GetBarcode() );
00939 
00940             throw;
00941         }
00942     }
00943 
00944     // May throw ivd_DFError.
00945     parser.ProcEndOfInput();
00946 
00947     // Write statistics
00948     cmn_Time endTime;
00949     cmn_Time diffTime = endTime - startTime;
00950 
00951     UInt64_t msecDiff =
00952         UInt64_t(diffTime.GetTime_t()) * 1000 +
00953         diffTime.GetMilliTime();
00954 
00955     if (msecDiff == 0) {
00956         msecDiff = 1;
00957     }
00958     UInt64_t speed = (friSize * 1000) / (msecDiff) ;
00959 
00960     ostringstream sstr;
00961     sstr
00962         << "Vol " << m_volume_p->GetVolumeNumber()
00963         << ": FRI written to data volume " << m_volume_p->GetVolumeID()
00964         << " : " << friSize << " KB ( " << speed << " KB/s).";
00965 
00966     log_WriteEvent(sstr.str(), "", m_bea.GetJobID(), m_bea.GetBarcode() );
00967 }

Here is the call graph for this function:

Here is the caller graph for this function:

void bea_FRI::DeleteFRIOnDisk (  )  [private]

Definition at line 1011 of file bea_fri.cpp.

References bea_Volume::GetVolumeID(), log_FUNC_m, and m_volume_p.

Referenced by CloseVolume(), DeleteFRIOnDisk(), ReadFRI(), and WriteFRI().

01011                               {
01012     log_FUNC_m(DeleteFRIOnDisk);
01013 
01014     DeleteFRIOnDisk(m_volume_p->GetVolumeID());
01015 }

Here is the call graph for this function:

Here is the caller graph for this function:

void bea_FRI::DeleteFRIOnDisk ( const cmn_UUID_t a_volID  )  [private]

Definition at line 971 of file bea_fri.cpp.

References dbg_LOW, DeleteFRIOnDisk(), evt_ERROR, i_BackEndAgent_i::GetBarcode(), ivd_BaseException::GetError(), ivd_BaseException::GetFriendly(), i_BackEndAgent_i::GetJobID(), bea_Volume::GetVolumeNumber(), log_DBG_m, log_FUNC_m, log_WriteEvent(), m_bea, m_volume_p, m_workDir, and cmn_UUID_t::ToString().

00971                                                        {
00972     log_FUNC_m(DeleteFRIOnDisk(a_volID));
00973 
00974     ostringstream sstr;
00975     sstr
00976         << "Vol " << m_volume_p->GetVolumeNumber() << ": "
00977         << "Deleting FRI on disk.";
00978 
00979     log_WriteEvent(sstr.str(), "FRI",
00980         m_bea.GetJobID(), m_bea.GetBarcode() );
00981 
00982     cmn_File fri(m_workDir + a_volID.ToString());
00983     try {
00984         fri.DeleteF();
00985     }
00986     catch (const ivd_SysError& se) {
00987 
00988         // No FRI on disk is not treated as an error situation.
00989 #if IVD_POSIX_OS
00990         if (se.GetError() == ENOENT) {
00991 #elif TGT_OS_windows
00992         if (se.GetError() == ERROR_FILE_NOT_FOUND) {
00993 #endif
00994             log_DBG_m(dbg_LOW,
00995                 "No FRI file on disk to delete. UUID: " << a_volID);
00996         }
00997         else {
00998             ostringstream sstr;
00999             sstr
01000                 << "Vol " << m_volume_p->GetVolumeNumber() << ": "
01001                 << "FRI file can't be deleted. Error: " << se.GetFriendly();
01002 
01003             log_WriteEvent(evt_ERROR, sstr.str(), "FRI",
01004                 m_bea.GetJobID(), m_bea.GetBarcode() );
01005         }
01006     }
01007 }

Here is the call graph for this function:

void bea_FRI::MoveFromWorkToFRI (  )  [private]

Definition at line 1019 of file bea_fri.cpp.

References cmn_MoveFile(), dbg_LOW, cmn_File::DeleteFile(), cmn_Global::dirs, ivd_Directories::fri, g_cmn, bea_Volume::GetVolumeID(), log_DBG_m, log_FUNC_m, log_WRN_m, m_volume_p, m_workDir, and cmn_UUID_t::ToString().

Referenced by CloseVolume(), and CreateFRI().

01019                                 {
01020     log_FUNC_m(MoveFromWorkToFRI);
01021 
01022     log_DBG_m(dbg_LOW, "Moving FRI file to " << g_cmn.dirs.fri);
01023 
01024     cmn_Path src(m_workDir + m_volume_p->GetVolumeID().ToString());
01025     cmn_Path dest(g_cmn.dirs.fri + m_volume_p->GetVolumeID().ToString());
01026 
01027     try {
01028         cmn_MoveFile(src, dest);
01029     }
01030     catch (const ivd_SysError) {
01031         // TODO: Should failure in error recovery be handled?
01032         log_WRN_m(
01033             "Moving a file from " << src << " to " << dest <<
01034             " failed. Deleting source and target");
01035         cmn_File::DeleteFile(src);
01036         cmn_File::DeleteFile(dest);
01037     }
01038 }

Here is the call graph for this function:

Here is the caller graph for this function:

void bea_FRI::SaveFRIOnError (  )  [private]

Definition at line 1042 of file bea_fri.cpp.

References cmn_MoveFile(), dbg_LOW, cmn_File::DeleteFile(), cmn_Global::dirs, g_cmn, bea_Volume::GetVolumeID(), log_DBG_m, log_FUNC_m, log_WRN_m, m_volume_p, m_workDir, ivd_Directories::tmp, and cmn_UUID_t::ToString().

Referenced by CreateFRI().

01042                              {
01043     log_FUNC_m(SaveFRIOnError);
01044 
01045     cmn_Path src(m_workDir + m_volume_p->GetVolumeID().ToString());
01046 
01047     cmn_Path dest(g_cmn.dirs.tmp  + 
01048                   cmn_Path("fri") + 
01049                   m_volume_p->GetVolumeID().ToString()); 
01050 
01051     dest.append("-read-error");
01052 
01053     try {
01054         log_DBG_m(dbg_LOW, "Moving FRI file to " << dest);
01055         log_WRN_m(
01056             "Moving a file from " << src << " to " << dest <<
01057             " because creation of a new FRI failed.");
01058 
01059         cmn_MoveFile(src, dest);
01060     }
01061     catch (const ivd_SysError) {
01062         log_WRN_m(
01063             "Moving a file from " << src << " to " << dest <<
01064             " failed. Try again on the same directory.");
01065 
01066         dest = src;
01067         dest.append("-read-error");
01068 
01069         try {
01070             log_DBG_m(dbg_LOW, "Moving FRI file to " << dest);
01071             log_WRN_m("Moving a file from " << src << " to " << dest << ".");
01072 
01073             cmn_MoveFile(src, dest);
01074         }
01075         catch (const ivd_SysError) {
01076             log_WRN_m(
01077                 "Moving a file from " << src << " to " << dest <<
01078                 " failed. Deleting source and target");
01079 
01080             cmn_File::DeleteFile(src);
01081             cmn_File::DeleteFile(dest);
01082         }
01083     }
01084 }

Here is the call graph for this function:

Here is the caller graph for this function:

bool bea_FRI::VerifyExistenceOfFileMark ( UInt32_t  a_position  )  [private]

Verifies existance of the file mark on the specified position.

Definition at line 1168 of file bea_fri.cpp.

References bea_OPREAD, dbg_LOW, evt_ERROR, evt_WARNING, i_BackEndAgent_i::GetBarcode(), bea_Volume::GetBlockSize(), ivd_BaseException::GetError(), ivd_BaseException::GetFriendly(), i_BackEndAgent_i::GetJobID(), bea_Volume::GetVolumeNumber(), i_BackEndAgent_i::HandleError(), ie_MEDIUM_FILEMARK, log_DBG_m, log_FUNC_m, log_WriteEvent(), m_bea, m_currentVolume_p, bea_Volume::Read(), and bea_Volume::SeekBlock().

Referenced by CloseVolume(), and DeleteFRIOnVolume().

01168                                                            {
01169     log_FUNC_m(VerifyExistenceOfFileMark);
01170 
01171     try {
01172         m_currentVolume_p->SeekBlock(a_position);
01173         vector<UInt8_t> buffer(m_currentVolume_p->GetBlockSize());
01174         m_currentVolume_p->Read(&(buffer[0]));
01175 
01176         // If reading succeeds then there is no FRI on the medium
01177         // This is unexpected situation.
01178         ostringstream sstr;
01179         sstr
01180             << "Vol " << m_currentVolume_p->GetVolumeNumber() << ": "
01181             << "Missing FRI file mark. Please contact support.";
01182 
01183         log_WriteEvent(evt_WARNING, sstr.str(), "FRI",
01184             m_bea.GetJobID(), m_bea.GetBarcode() );
01185     }
01186     catch (const ivd_Error& ie) {
01187         if (ie.GetError() == ie_MEDIUM_FILEMARK) {
01188             log_DBG_m(dbg_LOW, "File mark existence verified.");
01189             return true;
01190         }
01191         else {
01192             ostringstream sstr;
01193             sstr
01194                 << "Vol " << m_currentVolume_p->GetVolumeNumber() << ": "
01195                 << "Error when detecting the FRI file mark: " << ie.GetFriendly();
01196 
01197             log_WriteEvent(evt_ERROR, sstr.str(), "FRI",
01198                 m_bea.GetJobID(), m_bea.GetBarcode() );
01199 
01200             m_bea.HandleError(ie, bea_OPREAD);
01201         }
01202     }
01203     catch (...) {
01204         ostringstream sstr;
01205         sstr
01206             << "Vol " << m_currentVolume_p->GetVolumeNumber() << ": "
01207             << "Unknown error when reading the FRI file mark.";
01208 
01209         log_WriteEvent(evt_ERROR, sstr.str(), "FRI",
01210             m_bea.GetJobID(), m_bea.GetBarcode() );
01211     }
01212     return false;
01213 }

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Definition at line 51 of file bea_fri.h.

bea_Drive* const bea_FRI::m_drive_p [private]

bea_Volume* const bea_FRI::m_volume_p [private]

Definition at line 56 of file bea_fri.h.

Referenced by bea_FRI(), and CloseVolume().

const cmn_Path& bea_FRI::m_workDir [private]

bool bea_FRI::m_recreateInto [private]

Definition at line 60 of file bea_fri.h.

Referenced by CreateFRI(), and ReadFRI().

string bea_FRI::m_extension [private]

Definition at line 61 of file bea_fri.h.

Referenced by CreateFRI(), and ReadFRI().

Position of the FRI on medium after the file mark.

Definition at line 64 of file bea_fri.h.

Referenced by CloseVolume(), DeleteFRIOnVolume(), GetFRIStartPosition(), and PositionToStartOfFRI().


The documentation for this class was generated from the following files:

Generated on Mon Feb 27 18:58:53 2012 for OPENARCHIVE by  doxygen 1.5.6