#include <bea_recall.h>


Definition at line 33 of file bea_recall.h.
Public Member Functions | |
| bea_RecallThread (i_BackEndAgent_i &a_bea, bea_Drive *const a_drive_p, bool a_firstCall) | |
Protected Member Functions | |
| virtual | ~bea_RecallThread () |
Private Member Functions | |
| virtual void | Run (void *arg) |
| void | Recall () |
| void | MultiRecall () |
Private Attributes | |
| log_CLASSID_m | |
| i_BackEndAgent_i & | m_bea |
| bea_Drive * | m_drive_p |
| bea_Volume * | m_vol_p |
| UInt64_t | m_dataAmount |
| i_CompletionStatus_e | m_status |
| bool | m_multi |
| bool | m_firstCall |
| bea_RecallThread::bea_RecallThread | ( | i_BackEndAgent_i & | a_bea, | |
| bea_Drive *const | a_drive_p, | |||
| bool | a_firstCall | |||
| ) |
Definition at line 45 of file bea_recall.cpp.
References cmn_ThreadCounter::Inc(), log_FUNC_m, m_bea, and i_BackEndAgent_i::m_threadCounter.
00050 : m_bea(a_bea), 00051 m_drive_p(a_drive_p), 00052 m_vol_p(NULL), 00053 m_dataAmount(0), 00054 m_status(i_UNKNOWN), 00055 m_firstCall(a_firstCall){ 00056 00057 log_FUNC_m(bea_RecallThread); 00058 00059 m_bea.m_threadCounter.Inc(); 00060 }

| bea_RecallThread::~bea_RecallThread | ( | ) | [protected, virtual] |
Definition at line 64 of file bea_recall.cpp.
References bea_Drive::Close(), 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_drive_p, m_status, i_BackEndAgent_i::m_threadCounter, and NULL.
00064 { 00065 00066 log_FUNC_m(~bea_RecallThread); 00067 00068 // Decrease the counter imediatelly, because the job might imediatelly call 00069 // UseResources(). 00070 m_bea.m_threadCounter.Dec(); 00071 00072 // Close the device before contactacting job 00073 if (m_drive_p != NULL) { 00074 m_drive_p->Close(); 00075 } 00076 00077 // Complete job 00078 try { 00079 if (m_bea.IsAborted()) { 00080 log_DBG_m(dbg_LOW, "Recall aborted. Won't contact job."); 00081 } 00082 else { 00083 ipc_EXEC_m( 00084 if( !CORBA::is_nil(m_bea.GetJob()) ) { 00085 log_DBG_m(dbg_LOW, "Completion status: " << m_status); 00086 i_Job_var job = m_bea.GetJob(); 00087 job->MediumOperationComplete(m_bea.GetBEANumber(), m_status); 00088 }; 00089 ); 00090 } 00091 } 00092 catch(...) { 00093 // Ignore all exceptions at this point. 00094 } 00095 }

| void bea_RecallThread::Run | ( | void * | arg | ) | [private, virtual] |
Reimplemented from cmn_Thread.
Definition at line 99 of file bea_recall.cpp.
References bea_OPREAD, dbg_LOW, evt_ERROR, i_BackEndAgent_i::GetBarcode(), i_BackEndAgent_i::GetJobID(), i_BackEndAgent_i::GetMedVolBlockSize(), i_BackEndAgent_i::GetMedVolID(), i_BackEndAgent_i::GetMedVolNumber(), i_BackEndAgent_i::GetPoolID(), i_BackEndAgent_i::HandleError(), i_DATA_ERROR, i_SUCCEDED, i_UNKNOWN, i_BackEndAgent_i::IsAborted(), log_DBG_m, log_ERR_m, log_FUNC_m, log_WriteEvent(), m_bea, m_status, i_BackEndAgent_i::ReadIDs(), Recall(), i_BackEndAgent_i::ReleaseResources(), and i_BackEndAgent_i::VerifyIDs().
00099 { 00100 log_FUNC_m(Run); 00101 00102 try { 00103 try { 00104 Recall(); 00105 m_status = i_SUCCEDED; 00106 } 00107 catch(const ivd_DFError &dfe) { 00108 // Recall doesn't read volume header. 00109 // Incorrect medium is detected when trying to read the file. 00110 // 00111 // Check vol ID then for better error reporting. 00112 log_DBG_m(dbg_LOW, "Data format error detected. Checking volume ID."); 00113 00114 m_bea.ReadIDs(m_bea.GetMedVolNumber(), true); 00115 00116 m_bea.VerifyIDs( 00117 m_bea.GetBarcode(), 00118 m_bea.GetMedVolNumber(), 00119 m_bea.GetMedVolBlockSize(), 00120 cmn_UUID_t(m_bea.GetMedVolID()), 00121 cmn_UUID_t(m_bea.GetPoolID()) ); 00122 00123 // ID check passed: Volume and pool IDs match. 00124 // This is data format error or FSC/media mismatch 00125 ostringstream sstr; 00126 sstr 00127 << "Data format error on volume " 00128 << m_bea.GetMedVolNumber()<< ". " 00129 << "Please verify the situation using FSC vs media check."; 00130 00131 log_WriteEvent(evt_ERROR, sstr.str(), "RECALL", 00132 m_bea.GetJobID(), m_bea.GetBarcode() ); 00133 00134 log_ERR_m("Data format error on recall: " << dfe); 00135 00136 m_status = i_DATA_ERROR; 00137 } 00138 } 00139 catch(const ivd_Error &ie) { 00140 i_CompletionStatus_e status = m_bea.HandleError(ie, bea_OPREAD); 00141 00142 if (m_status == i_UNKNOWN || m_status == i_SUCCEDED) { 00143 m_status = status; 00144 } 00145 } 00146 catch(const std::exception& ie) { 00147 if (m_bea.IsAborted()) { 00148 log_DBG_m(dbg_LOW, 00149 "Recall aborted. Received exception: " << ie.what() ); 00150 } 00151 else { 00152 ostringstream sstr; 00153 sstr << "Recall failed: " << ie.what(); 00154 log_WriteEvent(evt_ERROR, sstr.str(), "", 00155 m_bea.GetJobID(), m_bea.GetBarcode() ); 00156 } 00157 00158 if (m_status == i_SUCCEDED) { 00159 m_status = i_UNKNOWN; 00160 } 00161 } 00162 catch(...) { 00163 log_WriteEvent(evt_ERROR, "Recall failed. Unknown error.", "", 00164 m_bea.GetJobID(), m_bea.GetBarcode() ); 00165 00166 if (m_status == i_SUCCEDED) { 00167 m_status = i_UNKNOWN; 00168 } 00169 } 00170 00171 try { 00172 m_bea.ReleaseResources(); 00173 } 00174 catch (...) { 00175 // Ignore everything 00176 } 00177 }

| void bea_RecallThread::Recall | ( | ) | [private] |
Definition at line 181 of file bea_recall.cpp.
References bea_OPREAD, cfg_MEGABYTE, bea_Medium::ChangeVolume(), df_Filter::CheckLeftovers(), cmn_GetEnvVariable(), cmn_Num2Str(), cmn_Str2Num(), dbg_DETAIL, dbg_LOW, dbg_NORM, file_creation_threshold_c(), bea_Volume::GetBlockSize(), i_BackEndAgent_i::GetBufferID(), bea_Medium::GetCurrentVolume(), bea_Medium::GetCurVolNumber(), i_BackEndAgent_i::GetDiskBufferFS(), i_BackEndAgent_i::GetDrive(), ivd_BaseException::GetError(), i_BackEndAgent_i::GetJob(), i_BackEndAgent_i::GetJobID(), bea_Drive::GetMedium(), bea_Medium::GetMediumMem(), i_BackEndAgent_i::GetMedVolBlockSize(), i_BackEndAgent_i::GetMedVolNumber(), bea_Volume::GetPosition(), bea_Medium::GetRMType(), i_BackEndAgent_i::GetSeekThreshold(), bea_Volume::GetVolumeNumber(), i_SUCCEDED, ie_DATA_CORRUPTION, ie_MEDIUM_EOD, ie_MEDIUM_EOM, ie_MEDIUM_FILEMARK, ipc_EXEC_m, i_BackEndAgent_i::IsAborted(), bea_Medium::IsMediumMemValid(), ivd_Error, log_DBG_m, log_FUNC_m, log_MARKLINE_m, i_BackEndAgent_i::LogStats(), m_bea, m_dataAmount, m_drive_p, m_firstCall, m_status, m_vol_p, df_Filter::NextBlockToCopy(), df_Filter::NextInputBlock(), df_Filter::NONE, NULL, df_Filter::ProcEndOfInput(), df_Filter::ProcessingFile(), bea_Volume::Read(), df_Filter::Reset(), bea_Volume::SeekBlock(), bea_Volume::SetBlockSize(), df_Filter::SetConsistencyMode(), df_RecReader::Unpack(), bea_MediumMemory::UpdateAccess(), and i_BackEndAgent_i::WaitForResources().
Referenced by Run().
00181 { 00182 log_FUNC_m(Recall); 00183 00184 m_bea.WaitForResources(); 00185 00186 if (m_bea.IsAborted()) { 00187 log_DBG_m(dbg_LOW, "Job aborted (1). Exit."); 00188 return; 00189 } 00190 00191 log_DBG_m(dbg_LOW, "Starting recall. Job ID: " << m_bea.GetJobID()); 00192 00193 cmn_Time startTime; 00194 00195 bea_Medium* med_p = m_drive_p->GetMedium(); 00196 00197 if (med_p->GetCurVolNumber() != m_bea.GetMedVolNumber()) { 00198 med_p->ChangeVolume( m_bea.GetMedVolNumber() ); 00199 } 00200 m_vol_p = med_p->GetCurrentVolume(); 00201 // Set the block size as sent by the recall job, 00202 // because volume identification is not read from volume header for recalls. 00203 m_vol_p->SetBlockSize(m_bea.GetMedVolBlockSize()); 00204 00205 if (med_p->GetCurVolNumber() != m_bea.GetMedVolNumber()) { 00206 med_p->ChangeVolume( m_bea.GetMedVolNumber() ); 00207 } 00208 00209 ivd_MediaType_e type = static_cast<ivd_MediaType_e>(med_p->GetRMType()); 00210 bea_Drive* drv_p(m_bea.GetDrive()); 00211 UInt64_t seekThreshold( 00212 m_bea.GetSeekThreshold( 00213 drv_p->GetVendorID(), drv_p->GetProductID(), type ) ); 00214 00215 if (seekThreshold == 0) { 00216 seekThreshold = drv_p->GetDefaultSeekThreshold(); 00217 } 00218 00219 log_DBG_m(dbg_LOW, "Seek threshold: " << seekThreshold); 00220 string fileCreationThreshold = cmn_GetEnvVariable(file_creation_threshold_c); 00221 00222 bool firstSet(true); 00223 00224 while (true){ 00225 00226 // Get files from Job 00227 i_FileLocationDataList_t_var iFileList; 00228 ipc_EXEC_m( 00229 iFileList = m_bea.GetJob()->GetNextRecallSet(); 00230 ); 00231 for (UInt32_t i(0); i < iFileList->length(); i++){ 00232 log_DBG_m(dbg_DETAIL, "blk:" << iFileList[i].blockOffset << 00233 " fileID:" << iFileList[i].fileID << 00234 " migID:" << ivd_MigrationID(iFileList[i].migrationID) << 00235 " spltsz:" << iFileList[i].splitSize ); 00236 } 00237 00238 if (iFileList->length() == 0) { 00239 log_DBG_m(dbg_LOW, "Recall finished"); 00240 break; 00241 } 00242 //else 00243 00244 ivd_FileLocVect_t files; 00245 ivd_FileSize_t estDbSize(0); 00246 00247 // check if file is big enough to enable seek to filesize 00248 log_DBG_m(dbg_DETAIL, "fileCreationThreshold = " << fileCreationThreshold); 00249 00250 for (UInt32_t i(0); i < iFileList->length(); i++){ 00251 files.push_back(ivd_FileLocationData_t(iFileList[i])); 00252 // estimation is too small on purpose (only data stream calculated), 00253 // the actual file will grow a few KB/MB more. 00254 estDbSize += iFileList[i].splitSize; 00255 } 00256 00257 if (m_firstCall && !fileCreationThreshold.empty()) { 00258 UInt32_t fileCreationThresholdVal = cmn_Str2Num(fileCreationThreshold) * cfg_MEGABYTE; 00259 00260 if ((fileCreationThresholdVal != 0) && (estDbSize > fileCreationThresholdVal)) { 00261 log_DBG_m(dbg_DETAIL, "Enable trunc to filesize, fileCreationThresholdVal= " << fileCreationThresholdVal << 00262 ", estDbSize=" << estDbSize); 00263 } 00264 else { 00265 estDbSize = 0; 00266 log_DBG_m(dbg_DETAIL, "Normal writing to diskbuff, fileCreationThresholdVal = " << 00267 fileCreationThresholdVal << 00268 ", estDbSize=" << 00269 estDbSize); 00270 } 00271 } 00272 else { 00273 estDbSize = 0; 00274 log_DBG_m(dbg_DETAIL, "Normal writing to diskbuff, estDbSize=" << estDbSize); 00275 } 00276 00277 00278 log_DBG_m(dbg_LOW, "Recall will recall " << files.size() << " files"); 00279 00280 { 00281 UInt32_t nextBlockToCopy(0); 00282 bool skipping(false); 00283 00284 //Do append only if this is first Recall and first set of files 00285 bool append = !m_firstCall || !firstSet; 00286 log_DBG_m(dbg_LOW, "append: " << boolalpha << append); 00287 00288 df_Filter dffilter( m_vol_p->GetBlockSize(), 00289 m_bea.GetDiskBufferFS(), 00290 cmn_Num2Str(m_bea.GetBufferID()), 00291 files, 00292 append, 00293 estDbSize); 00294 firstSet = false; 00295 00296 UInt32_t blkPos(files[0].blockOffset); 00297 00298 // Sanity check: Positions have to be below 00299 if (blkPos < m_vol_p->GetStartOfDataPosition()) { 00300 log_MARKLINE_m; 00301 throw ivd_Error(ie_DATA_CORRUPTION, 00302 "Invalid input parameters: Trying to seek to a medium position in the header.", 00303 true); 00304 } 00305 00306 // Don't perform unnecessary seeks, which may throw the contents of 00307 // the drive buffer away. 00308 if (m_vol_p->GetPosition() != blkPos) { 00309 m_vol_p->SeekBlock(blkPos); 00310 } 00311 00312 // Job was aborted while seeking to the first position to read 00313 // files from. 00314 if (m_bea.IsAborted()) { 00315 log_DBG_m(dbg_NORM, "Recall aborted while seeking to first position."); 00316 dffilter.SetConsistencyMode(df_Filter::NONE); 00317 break; 00318 } 00319 00320 UInt8_t* buffer = dffilter.NextInputBlock(); 00321 while ( buffer != NULL ) { 00322 00323 try { 00324 m_vol_p->Read(buffer); 00325 m_dataAmount += m_vol_p->GetBlockSize(); 00326 } 00327 catch (ivd_Error &ie) { 00328 if (ie.GetError() == ie_MEDIUM_FILEMARK) { 00329 //reading finished 00330 log_DBG_m(dbg_LOW, "reading finished (Filemark)."); 00331 break; 00332 } 00333 else if (ie.GetError() == ie_MEDIUM_EOD) { 00334 log_DBG_m(dbg_LOW, "reading finished (eod)."); 00335 break; 00336 } 00337 else if (ie.GetError() == ie_MEDIUM_EOM) { 00338 log_DBG_m(dbg_LOW, "Early end of volume. Ignore."); 00339 } 00340 else { 00341 // An error has happened when reading data from 00342 // medium: df_Filter shouldn't check for 00343 // for consistency of recalled data in this case. 00344 dffilter.SetConsistencyMode(df_Filter::NONE); 00345 throw; 00346 } 00347 } 00348 00349 // Don't parse the data format in the 00350 // "holes between" the valid files. 00351 if (nextBlockToCopy <= blkPos) { 00352 skipping = false; 00353 dffilter.Unpack(buffer, blkPos); 00354 } 00355 00356 if (!skipping && !dffilter.ProcessingFile()) { 00357 nextBlockToCopy = dffilter.NextBlockToCopy(); 00358 if (nextBlockToCopy == 0){ //no more files 00359 log_DBG_m(dbg_NORM, "No more files for processing."); 00360 break; 00361 } 00362 log_DBG_m(dbg_NORM, 00363 "Filter is not processing file. " << 00364 "Skip to block " << nextBlockToCopy << 00365 " (current: " << blkPos << ")"); 00366 dffilter.Reset(); 00367 skipping = true; 00368 } 00369 00370 buffer = dffilter.NextInputBlock(); 00371 00372 if (skipping) { 00373 UInt64_t sizeGap(nextBlockToCopy - blkPos); 00374 sizeGap *= m_vol_p->GetBlockSize(); 00375 log_DBG_m(dbg_DETAIL, "gap: " << sizeGap); 00376 00377 if (sizeGap > seekThreshold) { 00378 m_vol_p->SeekBlock(nextBlockToCopy); 00379 blkPos = m_vol_p->GetPosition(); 00380 skipping = false; 00381 } 00382 else { 00383 // Skipping by reading. 00384 blkPos++; 00385 } 00386 } 00387 else { 00388 // Reading. 00389 blkPos++; 00390 } 00391 00392 if (m_bea.IsAborted()) { 00393 log_DBG_m(dbg_NORM, "Recall aborted."); 00394 dffilter.SetConsistencyMode(df_Filter::NONE); 00395 break; 00396 } 00397 } // while 00398 00399 dffilter.ProcEndOfInput(); 00400 dffilter.CheckLeftovers(); 00401 if (m_bea.IsAborted()) { 00402 log_DBG_m(dbg_NORM, "Recall aborted."); 00403 dffilter.SetConsistencyMode(df_Filter::NONE); 00404 break; 00405 } 00406 } 00407 }//end while //recall finished 00408 00409 cmn_Time endTime; 00410 cmn_Time diffTime = endTime - startTime; 00411 00412 m_bea.LogStats(diffTime, m_dataAmount, bea_OPREAD); 00413 00414 try { 00415 if (m_drive_p->GetMedium()->IsMediumMemValid()) { 00416 bea_MediumMemory* mm = m_drive_p->GetMedium()->GetMediumMem(); 00417 mm->UpdateAccess(m_vol_p->GetVolumeNumber()); 00418 } 00419 } 00420 catch(ivd_Exception &ie) { 00421 log_DBG_m(dbg_LOW, "Error updating MIC. Ignored: " << ie ); 00422 } 00423 00424 m_status = i_SUCCEDED; 00425 }


| void bea_RecallThread::MultiRecall | ( | ) | [private] |
bea_RecallThread::log_CLASSID_m [private] |
i_BackEndAgent_i& bea_RecallThread::m_bea [private] |
Definition at line 52 of file bea_recall.h.
Referenced by bea_RecallThread(), Recall(), Run(), and ~bea_RecallThread().
bea_Drive* bea_RecallThread::m_drive_p [private] |
bea_Volume* bea_RecallThread::m_vol_p [private] |
UInt64_t bea_RecallThread::m_dataAmount [private] |
bool bea_RecallThread::m_multi [private] |
Definition at line 57 of file bea_recall.h.
bool bea_RecallThread::m_firstCall [private] |
1.5.6