bea_DupWriteThread Class Reference
[IVD Back-End Agent]

#include <bea_mediumdup.h>

Inheritance diagram for bea_DupWriteThread:

Inheritance graph
[legend]
Collaboration diagram for bea_DupWriteThread:

Collaboration graph
[legend]

List of all members.


Detailed Description

Definition at line 59 of file bea_mediumdup.h.


Public Member Functions

 bea_DupWriteThread (i_BackEndAgent_i &a_bea, bea_Drive *const a_drive_p, UInt32_t a_volSize, bool a_appendVol, bool a_srcMediumFull)
virtual ~bea_DupWriteThread ()
virtual void Run (void *arg)

Private Member Functions

void WriteMedVolume ()
void AppendVolume ()

Private Attributes

 log_CLASSID_m
i_BackEndAgent_im_bea
bea_Drive *const m_drive_p
UInt32_t m_volSize
bool m_appendVol
bool m_srcMediumFull
UInt32_t m_volChunks
i_CompletionStatus_e m_status

Constructor & Destructor Documentation

bea_DupWriteThread::bea_DupWriteThread ( i_BackEndAgent_i a_bea,
bea_Drive *const   a_drive_p,
UInt32_t  a_volSize,
bool  a_appendVol,
bool  a_srcMediumFull 
)

Definition at line 286 of file bea_mediumdup.cpp.

References cmn_ThreadCounter::Inc(), log_FUNC_A_m, m_bea, and i_BackEndAgent_i::m_threadCounter.

00292   : m_bea(a_bea),
00293     m_drive_p(a_drive_p),
00294     m_volSize(a_volSize),
00295     m_appendVol(a_appendVol),
00296     m_srcMediumFull(a_srcMediumFull),
00297     m_volChunks(0),
00298     m_status(i_UNKNOWN) {
00299 
00300     log_FUNC_A_m(
00301         bea_DupWriteThread,
00302         " size: " << a_volSize <<
00303         " append: " << (a_appendVol? "YES" : "NO") );
00304 
00305     m_bea.m_threadCounter.Inc();
00306 }

Here is the call graph for this function:

bea_DupWriteThread::~bea_DupWriteThread (  )  [virtual]

Definition at line 310 of file bea_mediumdup.cpp.

References dbg_LOW, cmn_ThreadCounter::Dec(), i_BackEndAgent_i::GetBEANumber(), i_BackEndAgent_i::GetJob(), ipc_EXEC_m, i_BackEndAgent_i::IsAborted(), log_DBG_m, log_FUNC_m, m_bea, m_status, i_BackEndAgent_i::m_threadCounter, and i_BackEndAgent_i::ReleaseResources().

00310                                         {
00311 
00312     log_FUNC_m(~bea_MediumDupThread);
00313 
00314     try {
00315         m_bea.ReleaseResources();
00316     }
00317     catch (...) {
00318         // Ignore all exceptions at this point
00319     }
00320 
00321     try {
00322         if (m_bea.IsAborted()) {
00323             log_DBG_m(dbg_LOW, "Duplication aborted. Won't contact job.");
00324         }
00325         else {
00326             ipc_EXEC_m(
00327                 if( !CORBA::is_nil(m_bea.GetJob()) ) {
00328                     log_DBG_m(dbg_LOW, "Completion status: " << m_status);
00329                     i_Job_var job = m_bea.GetJob();
00330                     job->MediumOperationComplete(m_bea.GetBEANumber(), m_status);
00331                 };
00332             );
00333         }
00334     }
00335     catch(...) {
00336         // Ignore all exceptions at this point.
00337     }
00338 
00339     m_bea.m_threadCounter.Dec();
00340 }

Here is the call graph for this function:


Member Function Documentation

void bea_DupWriteThread::Run ( void *  arg  )  [virtual]

Reimplemented from cmn_Thread.

Definition at line 344 of file bea_mediumdup.cpp.

References AppendVolume(), bea_OPWRITE, dbg_LOW, i_BackEndAgent_i::HandleError(), i_SUCCEDED, i_UNKNOWN, log_DBG_m, log_FUNC_m, m_appendVol, m_bea, m_status, and WriteMedVolume().

00344                                       {
00345     log_FUNC_m(Run);
00346 
00347     try {
00348         WriteMedVolume();
00349         if (m_appendVol) {
00350             AppendVolume();
00351         }
00352         m_status = i_SUCCEDED;
00353         log_DBG_m(dbg_LOW, "Completed duplication writing task.");
00354     }
00355     catch(ivd_Error &ie) {
00356         m_status = m_bea.HandleError(ie, bea_OPWRITE);
00357     }
00358     catch(...) {
00359         log_DBG_m(dbg_LOW, "Error while duplicating medium volume.");
00360         if (m_status == i_SUCCEDED) {
00361             m_status = i_UNKNOWN;
00362         }
00363     }
00364 }

Here is the call graph for this function:

void bea_DupWriteThread::WriteMedVolume (  )  [private]

Definition at line 368 of file bea_mediumdup.cpp.

References bea_Medium::ChangeVolume(), cmn_File::CloseF(), dbg_LOW, dbg_NORM, cmn_File::DeleteF(), df_VOLHDR_REC_SIZE, cmn_Global::dirs, ivd_Directories::diskbuf, bea_Volume::Flush(), fom_READ, g_cmn, bea_Medium::GetCurrentVolume(), bea_Medium::GetCurVolNumber(), i_BackEndAgent_i::GetDiskBufferFS(), ivd_BaseException::GetError(), i_BackEndAgent_i::GetJobID(), bea_Drive::GetMedium(), i_BackEndAgent_i::GetMedVolBlockSize(), i_BackEndAgent_i::GetMedVolID(), i_BackEndAgent_i::GetMedVolNumber(), i_BackEndAgent_i::GetMedVolType(), ie_DATA_CORRUPTION, ie_MEDIUM_EOM, i_BackEndAgent_i::IsAborted(), ivd_Error, log_DBG_m, log_FUNC_m, log_MARKLINE_m, m_bea, m_drive_p, m_volChunks, cmn_File::OpenF(), cmn_File::ReadF(), bea_Volume::Rewind(), rmdb_SYSTEM_VOLUME, bea_Volume::SetBlockSize(), i_BackEndAgent_i::WaitForResources(), bea_Volume::Write(), bea_Volume::WriteFileMarks(), and bea_Volume::WriteVolHdr().

Referenced by Run().

00368                                         {
00369     log_FUNC_m(WriteMedVolume);
00370 
00371     log_DBG_m(dbg_LOW,
00372         "Started writing medium volume. Job ID: " << m_bea.GetJobID());
00373 
00374     m_bea.WaitForResources();
00375 
00376     if (m_bea.IsAborted()) {
00377         log_DBG_m(dbg_LOW, "Job aborted. Exit.");
00378         return;
00379     };
00380 
00381     {
00382         bea_Medium* med = m_drive_p->GetMedium();
00383         if (m_bea.GetMedVolNumber() != med->GetCurVolNumber()) {
00384             med->ChangeVolume(m_bea.GetMedVolNumber());
00385         }
00386     }
00387 
00388     // Get names of files of volume chunks
00389     list<string> chunkNames;
00390     {
00391         cmn_DirLst chunkFiles(
00392             g_cmn.dirs.diskbuf + m_bea.GetDiskBufferFS(), "", m_bea.GetMedVolID() );
00393 
00394         string name;
00395         while ( (name = chunkFiles.GetNextName()) != "") {
00396             chunkNames.push_back(name);
00397         }
00398         chunkNames.sort();
00399     }
00400 
00401     m_volChunks = chunkNames.size();
00402 
00403     log_DBG_m(dbg_LOW, "Number of chunks to be written: " << m_volChunks);
00404 
00405     if (m_volChunks == 0) {
00406         log_DBG_m(dbg_LOW, "No volume chunks found.");
00407         return;
00408     }
00409 
00410     bea_Volume* const vol = m_drive_p->GetMedium()->GetCurrentVolume();
00411     vol->SetBlockSize(m_bea.GetMedVolBlockSize());
00412     vol->Rewind();
00413 
00414     // Iterate over the list of volume chunk names
00415     list<string>::const_iterator name_i;
00416     UInt32_t chunkNum(0);
00417 
00418     for (name_i = chunkNames.begin();
00419          name_i != chunkNames.end() && !m_bea.IsAborted();
00420          ++name_i) {
00421 
00422         cmn_Path chunkName = g_cmn.dirs.diskbuf + m_bea.GetDiskBufferFS()+ (*name_i);
00423 
00424         log_DBG_m(dbg_NORM, "Reading file " << chunkName);
00425 
00426         cmn_File copyFile(chunkName);
00427         copyFile.OpenF(fom_READ);
00428 
00429         UInt32_t bytes(0);
00430         if (chunkNum == 0) {
00431             log_DBG_m(dbg_NORM, "Writing volume header.");
00432             vector<UInt8_t> hdrBlock(df_VOLHDR_REC_SIZE, 0);
00433 
00434             bytes = copyFile.ReadF(&(hdrBlock[0]), df_VOLHDR_REC_SIZE);
00435 
00436             if (bytes == df_VOLHDR_REC_SIZE) {
00437                 vol->WriteVolHdr(&(hdrBlock[0]));
00438             }
00439             else {
00440                 log_MARKLINE_m;
00441                 ostringstream sstr;
00442                 sstr
00443                     << "Read " << bytes << "bytes but expecting "
00444                     << df_VOLHDR_REC_SIZE << " bytes. "
00445                     << "Possible disk buffer file system corruption.";
00446 
00447                 throw ivd_Error(ie_DATA_CORRUPTION, sstr.str(), true);
00448             }
00449         }
00450 
00451         do {
00452             UInt32_t blockSize(m_bea.GetMedVolBlockSize());
00453             vector<UInt8_t> block(blockSize, 0);
00454 
00455             bytes = copyFile.ReadF(&(block[0]), blockSize);
00456 
00457             if (bytes == blockSize) {
00458                 try {
00459                     vol->Write(&(block[0]));
00460                 }
00461                 catch (ivd_Error &ie) {
00462                     if (ie.GetError() == ie_MEDIUM_EOM) {
00463                         log_DBG_m(dbg_NORM,
00464                             "Early EOM on Write - ignore for Duplication");
00465                     } else {
00466                         throw;
00467                     }
00468                 }
00469             }
00470             else if (bytes != 0) {
00471                 log_MARKLINE_m;
00472                 ostringstream sstr;
00473                 sstr
00474                     << "Read " << bytes << "bytes but expecting "
00475                     << blockSize << " bytes. "
00476                     << "Possible disk buffer file system corruption.";
00477 
00478                 throw ivd_Error(ie_DATA_CORRUPTION, sstr.str(), true);
00479             }
00480 
00481         } while (bytes > 0 && !m_bea.IsAborted());
00482 
00483         if (   (chunkNum == 0)                                  // header
00484             || ((chunkNames.size() > 2) && (chunkNum == 1))     // between data and fri
00485             || (m_bea.GetMedVolType() == rmdb_SYSTEM_VOLUME)) {
00486 
00487             // Write file marks after header and after FRIs on system volume
00488 
00489             vol->WriteFileMarks(1);
00490         }
00491 
00492         copyFile.CloseF();
00493         copyFile.DeleteF();
00494         //cmn_File::DeleteFile(chunkName);
00495         chunkNum++;
00496     };
00497 
00498     vol->Flush();
00499 
00500     log_DBG_m(dbg_LOW, "Sucessfully completed writing medium volume.");
00501 }

Here is the call graph for this function:

Here is the caller graph for this function:

void bea_DupWriteThread::AppendVolume (  )  [private]

Definition at line 505 of file bea_mediumdup.cpp.

References bea_Medium::AppendVolume(), dbg_LOW, dbg_NORM, evt_ERROR, evt_WARNING, i_BackEndAgent_i::GetBarcode(), bea_Medium::GetBarcode(), bea_Medium::GetCurrentVolume(), bea_Volume::GetEstimRemainingSize(), bea_Volume::GetEstimTotalSize(), i_BackEndAgent_i::GetJobID(), bea_Drive::GetMedium(), i_BackEndAgent_i::GetMedVolType(), i_BackEndAgent_i::GetRM(), bea_Volume::GetSize(), log_DBG_m, log_ERR_m, log_FUNC_m, log_WriteEvent(), m_bea, m_drive_p, m_srcMediumFull, m_volChunks, m_volSize, rmdb_MEDIUM_FULL, and rmdb_SYSTEM_VOLUME.

Referenced by Run().

00505                                       {
00506     log_FUNC_m(AppendVolume);
00507 
00508     bea_Medium* med = m_drive_p->GetMedium();
00509     bea_Volume *const vol = med->GetCurrentVolume();
00510 
00511     UInt32_t appendSize(0);
00512 
00513     if ( ( m_bea.GetMedVolType() == rmdb_SYSTEM_VOLUME  && !m_srcMediumFull )
00514         || m_volChunks < 3) {
00515         // Create target volume of approx the same size as the source
00516         // if the volume is not yet closed or it is a system volume 
00517         // on medium which is not full
00518         bool mediumFull(false);
00519 
00520         if (m_bea.GetMedVolType() == rmdb_SYSTEM_VOLUME) {
00521 
00522             try {
00523                 i_ResourceManager_var rm = m_bea.GetRM();
00524                 i_Medium_t_var rmMedium = rm->SelectMedium(CORBA::string_dup(med->GetBarcode().c_str()));
00525 
00526                 if ((rmMedium->status & rmdb_MEDIUM_FULL) == rmdb_MEDIUM_FULL) {
00527                  mediumFull = true;
00528                  log_DBG_m(dbg_NORM, "Medium is full: append system volume  at the end of data (not configured size).");
00529                 }
00530             }
00531             catch(...) {
00532                 // Ignore all exceptions at this point.
00533                 ostringstream sstr;
00534                 sstr << "Cannot get medium status from RM";
00535 
00536                 log_WriteEvent(evt_WARNING, sstr.str(), "",
00537                     m_bea.GetJobID(), m_bea.GetBarcode() );
00538             }
00539         }
00540 
00541         if (!mediumFull) {
00542             // Calculate compressed usage of the volume
00543             UInt32_t total = vol->GetEstimTotalSize();
00544             UInt32_t used = ( (total - vol->GetEstimRemainingSize()) * vol->GetSize())/total; // MB
00545     
00546             if (m_volSize > used) {
00547                 // append size + used size = volume size in RMDB
00548                 appendSize = m_volSize - used;
00549             }
00550             else {
00551                 appendSize = 0;
00552                 log_ERR_m(
00553                     "Duplication: " <<
00554                     "Volume size in RMDB is smaller than total data on volume. " << endl <<
00555                     "RMDB: " << m_volSize << ", compressed data: " << used);
00556     
00557                 log_WriteEvent(evt_ERROR,
00558                     "Duplication detected volume size mismatch. See error.log for details", "",
00559                     m_bea.GetJobID(), m_bea.GetBarcode() );
00560     
00561             };
00562     
00563             log_DBG_m(dbg_NORM, endl <<
00564                 "Source volume is not closed or is system volume." << endl <<
00565                 "Estimated total : " << vol->GetEstimTotalSize() << endl <<
00566                 "Estimated used  : " << (vol->GetEstimTotalSize() - vol->GetEstimRemainingSize()) << endl <<
00567                 "Compressed used : " << used << endl <<
00568                 "Append size     : " << appendSize << endl <<
00569                 "New volume size : " << (appendSize+used) << endl <<
00570                 "Src volume size : " << m_volSize);
00571         }
00572     }
00573     else {
00574         log_DBG_m(dbg_LOW,
00575             "Source volume is closed. Append volume at the end of data.");
00576     }
00577 
00578     log_DBG_m(dbg_LOW, "Appending volume: " << appendSize << " MB");
00579 
00580     med->AppendVolume(appendSize);
00581 }

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Reimplemented from cmn_Thread.

Definition at line 74 of file bea_mediumdup.h.

Definition at line 80 of file bea_mediumdup.h.

Referenced by AppendVolume(), and WriteMedVolume().

Definition at line 81 of file bea_mediumdup.h.

Referenced by AppendVolume().

Definition at line 82 of file bea_mediumdup.h.

Referenced by Run().

Definition at line 83 of file bea_mediumdup.h.

Referenced by AppendVolume().

Definition at line 84 of file bea_mediumdup.h.

Referenced by AppendVolume(), and WriteMedVolume().

Definition at line 86 of file bea_mediumdup.h.

Referenced by Run(), and ~bea_DupWriteThread().


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

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