bea_DupReadThread Class Reference
[IVD Back-End Agent]

#include <bea_mediumdup.h>

Inheritance diagram for bea_DupReadThread:

Inheritance graph
[legend]
Collaboration diagram for bea_DupReadThread:

Collaboration graph
[legend]

List of all members.


Detailed Description

Definition at line 32 of file bea_mediumdup.h.


Public Member Functions

 bea_DupReadThread (i_BackEndAgent_i &a_bea, bea_Drive *const a_drive_p)
virtual ~bea_DupReadThread ()
virtual void Run (void *arg)

Private Member Functions

void ReadMedVolume ()

Private Attributes

 log_CLASSID_m
i_BackEndAgent_im_bea
bea_Drive *const m_drive_p
i_CompletionStatus_e m_status

Constructor & Destructor Documentation

bea_DupReadThread::bea_DupReadThread ( i_BackEndAgent_i a_bea,
bea_Drive *const   a_drive_p 
)

Definition at line 40 of file bea_mediumdup.cpp.

References i_BackEndAgent_i::GetMedVolNumber(), ie_INVALID_ARG, cmn_ThreadCounter::Inc(), ivd_Error, log_FUNC_m, m_bea, and i_BackEndAgent_i::m_threadCounter.

00043   : m_bea(a_bea),
00044     m_drive_p(a_drive_p),
00045     m_status(i_UNKNOWN) {
00046 
00047     log_FUNC_m(bea_DupReadThread);
00048 
00049     if (m_bea.GetMedVolNumber() == 0) {
00050         throw ivd_Error(ie_INVALID_ARG, "VolID is 0.", true);
00051     }
00052 
00053     m_bea.m_threadCounter.Inc();
00054 }

Here is the call graph for this function:

bea_DupReadThread::~bea_DupReadThread (  )  [virtual]

Definition at line 58 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().

00058                                       {
00059 
00060     log_FUNC_m(~bea_DupReadThread);
00061 
00062     try {
00063         m_bea.ReleaseResources();
00064     }
00065     catch (...) {
00066         // Ignore all exceptions at this point
00067     }
00068 
00069     try {
00070         if (m_bea.IsAborted()) {
00071             log_DBG_m(dbg_LOW, "Duplication aborted. Won't contact job.");
00072         }
00073         else {
00074             ipc_EXEC_m(
00075                 if( !CORBA::is_nil(m_bea.GetJob()) ) {
00076                     log_DBG_m(dbg_LOW, "Completion status: " << m_status);
00077                     i_Job_var job = m_bea.GetJob();
00078                     job->MediumOperationComplete(m_bea.GetBEANumber(), m_status);
00079                 };
00080             );
00081         }
00082     }
00083     catch(...) {
00084         // Ignore all exceptions at this point.
00085     }
00086 
00087     m_bea.m_threadCounter.Dec();
00088 }

Here is the call graph for this function:


Member Function Documentation

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

Reimplemented from cmn_Thread.

Definition at line 92 of file bea_mediumdup.cpp.

References bea_OPREAD, dbg_LOW, evt_ERROR, i_BackEndAgent_i::GetBarcode(), i_BackEndAgent_i::GetJobID(), i_BackEndAgent_i::HandleError(), i_SUCCEDED, i_UNKNOWN, log_DBG_m, log_FUNC_m, log_WriteEvent(), m_bea, m_status, and ReadMedVolume().

00092                                      {
00093     log_FUNC_m(Run);
00094 
00095     try {
00096         ReadMedVolume();
00097         m_status = i_SUCCEDED;
00098         log_DBG_m(dbg_LOW, "Completed duplication reading task.");
00099     }
00100     catch(ivd_Error &ie) {
00101         m_status = m_bea.HandleError(ie, bea_OPREAD);
00102     }
00103     catch(const std::exception& ie) {
00104         ostringstream sstr;
00105         sstr << "Duplication failed: " << ie.what();
00106 
00107         log_WriteEvent(evt_ERROR, sstr.str(), "",
00108             m_bea.GetJobID(), m_bea.GetBarcode() );
00109 
00110         if (m_status == i_SUCCEDED) {
00111             m_status = i_UNKNOWN;
00112         }
00113     }
00114     catch(...) {
00115         log_WriteEvent(evt_ERROR, "Duplication failed. Unknown error.", "",
00116             m_bea.GetJobID(), m_bea.GetBarcode() );
00117 
00118         if (m_status == i_SUCCEDED) {
00119             m_status = i_UNKNOWN;
00120         }
00121     }
00122 }

Here is the call graph for this function:

void bea_DupReadThread::ReadMedVolume (  )  [private]

Definition at line 126 of file bea_mediumdup.cpp.

References bea_Medium::ChangeVolume(), cmn_File::CloseF(), dbg_LOW, dbg_NORM, df_VOLHDR_REC_SIZE, cmn_Global::dirs, ivd_Directories::diskbuf, fom_CREATE_ALWAYS, fom_WRITE, g_cmn, bea_Volume::GetBlockSize(), bea_Medium::GetCurrentVolume(), bea_Medium::GetCurVolNumber(), i_BackEndAgent_i::GetDiskBufferFS(), ivd_BaseException::GetError(), i_BackEndAgent_i::GetJobID(), bea_Drive::GetMedium(), i_BackEndAgent_i::GetMedVolNumber(), bea_Volume::GetVolumeID(), ie_MEDIUM_EOD, ie_MEDIUM_EOM, ie_MEDIUM_FILEMARK, i_BackEndAgent_i::IsAborted(), log_DBG_m, log_FUNC_m, m_bea, m_drive_p, cmn_File::OpenF(), bea_Volume::Read(), bea_Volume::ReadVolHdr(), bea_Volume::Rewind(), cmn_File::SyncF(), i_BackEndAgent_i::WaitForResources(), and cmn_File::WriteF().

Referenced by Run().

00126                                       {
00127     log_FUNC_m(ReadMedVolume);
00128 
00129     log_DBG_m(dbg_LOW,
00130         "Started reading medium. Job ID: " << m_bea.GetJobID());
00131 
00132     m_bea.WaitForResources();
00133 
00134     if (m_bea.IsAborted()) {
00135         log_DBG_m(dbg_LOW, "Job aborted. Exit.");
00136         return;
00137     };
00138 
00139     bea_Medium* med = m_drive_p->GetMedium();
00140     if (m_bea.GetMedVolNumber() != med->GetCurVolNumber()) {
00141         med->ChangeVolume(m_bea.GetMedVolNumber());
00142     }
00143 
00144     bea_Volume *const vol = m_drive_p->GetMedium()->GetCurrentVolume();
00145 
00146 /* TODO: Enable Volume ID Check for medium duplication?
00147          Does job set it?
00148 
00149     vol->ReadVolInfoFromHeader();
00150 
00151     // Check volume ID.
00152     cmn_UUID_t volid(m_bea.GetMedVolID());
00153     if (vol->GetVolumeID() != volid) {
00154         ostringstream sstr;
00155         sstr <<
00156             m_bea.GetBarcode() << ":" << m_bea.GetMedVolNumber() <<
00157             " Medium duplication. Volume UUID doesn't match. Expected: " << volid <<
00158             " read: " << vol->GetVolumeID() );
00159 
00160         log_WriteEvent(evt_ERROR, sstr.str(), "MEDIUMDUP",
00161             m_bea.GetJobID(), m_bea.GetBarcode() );
00162 
00163         throw ivd_Error(ie_BEA_INVVOLID, sstr.str());
00164     };
00165 */
00166     vol->Rewind();
00167 
00168     //
00169     // Medium volume is divided into one or more chunks (parts of volume
00170     // between file marks. Each of the chunks is written into a separate
00171     // file.
00172     //
00173     UInt32_t    chunkNum(0);
00174     bool        endOfVolume(false);
00175 
00176     log_DBG_m(dbg_LOW, "Dumping medium volume header.");
00177 
00178     {
00179         cmn_Path chunkName;
00180         {
00181             ostringstream sstr;
00182             sstr << vol->GetVolumeID() << "." << chunkNum;
00183             chunkName = g_cmn.dirs.diskbuf + m_bea.GetDiskBufferFS() + sstr.str();
00184         }
00185 
00186         cmn_File copyFile(chunkName);
00187         copyFile.OpenF(fom_WRITE | fom_CREATE_ALWAYS);
00188 
00189         UInt32_t blockSize(vol->GetBlockSize());
00190         vector<UInt8_t> hdrBlock(df_VOLHDR_REC_SIZE, 0);
00191         vector<UInt8_t> block(blockSize, 0);
00192 
00193         try {
00194             vol->ReadVolHdr(&(hdrBlock[0]));
00195             copyFile.WriteF(&(hdrBlock[0]), df_VOLHDR_REC_SIZE);
00196 
00197             vol->Read(&(block[0]));
00198             copyFile.WriteF(&(block[0]), blockSize);
00199 
00200             // This should trigger exception (file mark).
00201             vol->Read(&(block[0]));
00202             copyFile.WriteF(&(block[0]), blockSize);
00203         }
00204         catch (const ivd_Error& ie) {
00205             switch (ie.GetError()) {
00206                 case ie_MEDIUM_FILEMARK:
00207                     log_DBG_m(dbg_LOW,
00208                         "File mark detected ==> End of header.");
00209                     break;
00210                 case ie_MEDIUM_EOM:
00211                     log_DBG_m(dbg_LOW,
00212                         "End of volume detected ==> Stop reading");
00213                     endOfVolume = true;
00214                     break;
00215                 case ie_MEDIUM_EOD:
00216                     log_DBG_m(dbg_LOW,
00217                         "End of data detected ==> Stop reading.");
00218                     endOfVolume = true;
00219                     break;
00220                 default:
00221                     log_DBG_m(dbg_LOW,
00222                     "Unexpected exception while reading volume ==> re-throw.");
00223                     throw;
00224             } // switch
00225         }
00226         log_DBG_m(dbg_NORM, "Dumped " << chunkName);
00227         copyFile.SyncF();
00228         chunkNum++;
00229     }
00230 
00231     log_DBG_m(dbg_LOW, "Dumping rest of medium volume chunks.");
00232 
00233     while (!endOfVolume && !m_bea.IsAborted()) {
00234         cmn_Path chunkName;
00235         {
00236             ostringstream sstr;
00237             sstr << vol->GetVolumeID() << "." << chunkNum;
00238             chunkName = g_cmn.dirs.diskbuf + m_bea.GetDiskBufferFS()+ sstr.str();
00239         }
00240 
00241         cmn_File copyFile(chunkName);
00242         copyFile.OpenF(fom_WRITE | fom_CREATE_ALWAYS);
00243 
00244         UInt32_t blockSize(vol->GetBlockSize());
00245         vector<UInt8_t> block(blockSize, 0);
00246 
00247         try {
00248             while(!m_bea.IsAborted()) {
00249                 vol->Read(&(block[0]));
00250                 copyFile.WriteF(&(block[0]), blockSize);
00251             }
00252         }
00253         catch (const ivd_Error& ie) {
00254             switch (ie.GetError()) {
00255                 case ie_MEDIUM_FILEMARK:
00256                     log_DBG_m(dbg_LOW,
00257                         "File mark detected ==> End of volume part.");
00258                     break;
00259                 case ie_MEDIUM_EOD:
00260                     log_DBG_m(dbg_LOW,
00261                         "End of data detected ==> Stop reading.");
00262                     endOfVolume = true;
00263                     break;
00264                 default:
00265                     log_DBG_m(dbg_LOW,
00266                     "Unexpected exception while reading volume ==> re-throw.");
00267                     throw;
00268             } // switch
00269         }
00270         log_DBG_m(dbg_NORM, "Dumped " << chunkName);
00271         copyFile.SyncF();
00272         copyFile.CloseF();
00273 
00274         if (!endOfVolume) {
00275             chunkNum++;
00276         }
00277     }
00278 
00279     log_DBG_m(dbg_LOW, "Sucessfully completed reading medium volume.");
00280 }

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 44 of file bea_mediumdup.h.

Definition at line 48 of file bea_mediumdup.h.

Referenced by bea_DupReadThread(), ReadMedVolume(), Run(), and ~bea_DupReadThread().

Definition at line 49 of file bea_mediumdup.h.

Referenced by ReadMedVolume().

Definition at line 51 of file bea_mediumdup.h.

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


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

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