#include <bea_migration.h>


Definition at line 33 of file bea_migration.h.
Public Member Functions | |
| bea_MigrationThread (i_BackEndAgent_i &a_bea, bea_Drive *const a_drive_p) | |
Protected Member Functions | |
| virtual | ~bea_MigrationThread () |
Private Member Functions | |
| virtual void | Run (void *arg) |
| void | Migrate () |
| bool | WriteBlock (df_FRI &a_fri, UInt8_t *a_blkBuf) |
| void | SendToFSC (const vector< df_SplitInfo > &a_splits) |
| UInt8_t * | FRIVolumeStart (df_FRI &a_fri) |
| void | FRIVolumeEnd (df_FRI &a_fri, UInt32_t a_status) |
| void | ExchangeResources () |
| void | PrepareVolume () |
| void | CheckFRI () |
Private Attributes | |
| log_CLASSID_m | |
| i_BackEndAgent_i & | m_bea |
| bea_Drive * | m_drive_p |
| i_FSC_var | m_fsc |
| bea_Volume * | m_vol_p |
| UInt32_t | m_mediumPos |
| UInt64_t | m_dataAmount |
| i_CompletionStatus_e | m_status |
| vector< UInt64_t > | m_minColIds |
| bea_MigrationThread::bea_MigrationThread | ( | i_BackEndAgent_i & | a_bea, | |
| bea_Drive *const | a_drive_p | |||
| ) |
Definition at line 36 of file bea_migration.cpp.
References i_BackEndAgent_i::GetJob(), cmn_ThreadCounter::Inc(), ipc_EXEC_m, log_FUNC_m, m_bea, m_fsc, and i_BackEndAgent_i::m_threadCounter.
00040 : m_bea(a_bea), 00041 m_drive_p(a_drive_p), 00042 m_vol_p(NULL), 00043 m_mediumPos(0), 00044 m_dataAmount(0), 00045 m_status(i_UNKNOWN) { 00046 00047 log_FUNC_m(bea_MigrationThread); 00048 00049 ipc_EXEC_m( 00050 m_fsc = i_FSC::_duplicate(m_bea.GetJob()->GetFSC()); 00051 ); 00052 00053 m_bea.m_threadCounter.Inc(); 00054 }

| bea_MigrationThread::~bea_MigrationThread | ( | ) | [protected, virtual] |
Definition at line 58 of file bea_migration.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.
00058 { 00059 00060 log_FUNC_m(~bea_MigrationThread); 00061 00062 // Close the device before contacting job 00063 if (m_drive_p != NULL) { 00064 m_drive_p->Close(); 00065 } 00066 00067 // Complete job 00068 try { 00069 if (m_bea.IsAborted()) { 00070 log_DBG_m(dbg_LOW, "Migration aborted. Won't contact job."); 00071 } 00072 else { 00073 ipc_EXEC_m( 00074 if( !CORBA::is_nil(m_bea.GetJob()) ) { 00075 log_DBG_m(dbg_LOW, "Completion status: " << m_status); 00076 i_Job_var job = m_bea.GetJob(); 00077 job->MediumOperationComplete(m_bea.GetBEANumber(), m_status); 00078 }; 00079 ); 00080 } 00081 } 00082 catch(...) { 00083 // Ignore all exceptions at this point. 00084 } 00085 00086 m_bea.m_threadCounter.Dec(); 00087 }

| void bea_MigrationThread::Run | ( | void * | arg | ) | [private, virtual] |
Reimplemented from cmn_Thread.
Definition at line 91 of file bea_migration.cpp.
References bea_OPWRITE, dbg_LOW, dbg_NORM, evt_ERROR, i_BackEndAgent_i::GetBarcode(), i_BackEndAgent_i::GetJobID(), i_BackEndAgent_i::HandleError(), i_DATA_ERROR, i_HW_ERROR, i_MEDIUM_ERROR, i_SUCCEDED, i_UNKNOWN, i_BackEndAgent_i::IsAborted(), log_DBG_m, log_ERR_m, log_FUNC_m, log_WriteEvent(), m_bea, m_status, Migrate(), i_BackEndAgent_i::ReleaseResources(), and i_BackEndAgent_i::UpdateVolumeUsed().
00091 { 00092 log_FUNC_m(Run); 00093 00094 try { 00095 Migrate(); 00096 m_status = i_SUCCEDED; 00097 } 00098 catch(const ivd_DFError &dfe) { 00099 log_WriteEvent(evt_ERROR, "Migration failed. Data format error.", "", 00100 m_bea.GetJobID(), m_bea.GetBarcode() ); 00101 00102 log_ERR_m("Data format error on migration: " << dfe); 00103 00104 m_status = i_DATA_ERROR; 00105 } 00106 catch(const ivd_Error& ie) { 00107 i_CompletionStatus_e status = m_bea.HandleError(ie, bea_OPWRITE); 00108 00109 if (m_status == i_UNKNOWN || m_status == i_SUCCEDED) { 00110 m_status = status; 00111 } 00112 } 00113 catch(const std::exception& ie) { 00114 if (m_bea.IsAborted()) { 00115 log_DBG_m(dbg_LOW, 00116 "Migration aborted. Received exception: " << ie.what() ); 00117 } 00118 else { 00119 ostringstream sstr; 00120 sstr << "Migration failed: " << ie.what(); 00121 00122 log_WriteEvent(evt_ERROR, sstr.str(), "", 00123 m_bea.GetJobID(), m_bea.GetBarcode() ); 00124 } 00125 00126 if (m_status == i_SUCCEDED) { 00127 m_status = i_UNKNOWN; 00128 } 00129 } 00130 catch(...) { 00131 log_WriteEvent(evt_ERROR, "Migration failed. Unknown error.", "", 00132 m_bea.GetJobID(), m_bea.GetBarcode() ); 00133 00134 if (m_status == i_SUCCEDED) { 00135 m_status = i_UNKNOWN; 00136 } 00137 } 00138 00139 if (m_status != i_MEDIUM_ERROR && m_status != i_HW_ERROR) { 00140 // Update volume usage in RMDB 00141 m_bea.UpdateVolumeUsed(); 00142 } 00143 else { 00144 log_DBG_m(dbg_NORM, 00145 "Won't update VolumeUsed in RM because of medium or hardware error."); 00146 } 00147 00148 try { 00149 m_bea.ReleaseResources(); 00150 } 00151 catch (...) { 00152 // Ignore everything 00153 } 00154 }

| void bea_MigrationThread::Migrate | ( | ) | [private] |
Definition at line 158 of file bea_migration.cpp.
References bea_OPWRITE, CheckFRI(), bea_FRI::CloseVolume(), bea_FRI::CloseVolumeInRMDB(), cmn_Num2Str(), dbg_DETAIL, dbg_LOW, dbg_NORM, df_DISKBUF_BLOCKS_c, df_FRIS_ABORTED, df_FRIS_COMPLETE, cmn_Global::dirs, evt_WARNING, ExchangeResources(), bea_Volume::Flush(), ivd_Directories::fri, FRIVolumeEnd(), FRIVolumeStart(), g_cmn, bea_Medium::GetBarcode(), i_BackEndAgent_i::GetBarcode(), bea_Volume::GetBlockSize(), i_BackEndAgent_i::GetBufferID(), df_DataBlock::GetData(), i_BackEndAgent_i::GetDiskBufferFS(), ivd_BaseException::GetError(), df_MgrReader::GetFull(), i_BackEndAgent_i::GetJobID(), bea_Drive::GetMedium(), bea_Volume::GetPartitionID(), bea_Volume::GetPoolID(), bea_Volume::GetPosition(), bea_Volume::GetVolumeNumber(), i_SUCCEDED, ie_DATA_CORRUPTION, ie_MEDIUM_EOM, ie_MEDIUM_OVERFLOW, i_BackEndAgent_i::IsAborted(), df_DataBlock::IsEmpty(), ivd_Error, log_DBG_m, log_FUNC_m, log_MARKLINE_m, log_WriteEvent(), i_BackEndAgent_i::LogStats(), m_bea, m_dataAmount, m_drive_p, m_mediumPos, m_status, m_vol_p, bea_Volume::MustDumpFRI(), NULL, PrepareVolume(), df_MgrReader::Release(), cmn_Thread::Start(), i_BackEndAgent_i::WaitForResources(), and WriteBlock().
Referenced by Run().
00158 { 00159 log_FUNC_m(Migrate); 00160 00161 log_DBG_m(dbg_LOW, "Starting migration. Job ID: " << m_bea.GetJobID()); 00162 00163 m_bea.WaitForResources(); 00164 00165 if (m_bea.IsAborted()) { 00166 log_DBG_m(dbg_LOW, "Job aborted (1). Exit."); 00167 return; 00168 }; 00169 00170 PrepareVolume(); 00171 CheckFRI(); 00172 cmn_Time startTime; 00173 00174 bool newVolume(true); // has to do FRIVolumeStart 00175 UInt32_t numBlkToCapChk(0); // imediately perform capacity check 00176 00177 df_BlockManager mgr(m_vol_p->GetBlockSize(), df_DISKBUF_BLOCKS_c); 00178 00179 // 00180 // TODO: Replace df_FRI with df_FRIDistiller. 00181 // 00182 df_FRI fri( 00183 m_vol_p->GetPartitionID(), 00184 m_vol_p->GetPoolID(), 00185 m_vol_p->GetBlockSize() ); 00186 00187 { 00188 df_MgrReader reader(mgr); 00189 00190 // Only disk buffer is used currently 00191 // Improve if new will be introduced. 00192 blk_DiskBufferReader *db_p = 00193 new blk_DiskBufferReader(mgr, m_bea.GetDiskBufferFS(), cmn_Num2Str(m_bea.GetBufferID()) ); 00194 00195 db_p->Start(); 00196 00197 df_DataBlock *blk = NULL; 00198 while ( (blk = reader.GetFull()) != NULL && !m_bea.IsAborted()) { 00199 if (!blk->IsEmpty()) { 00200 00201 while (numBlkToCapChk == 0) { 00202 00203 if (m_vol_p->MustDumpFRI(&numBlkToCapChk)) { 00204 cmn_Time endTime; 00205 cmn_Time diffTime = endTime - startTime; 00206 m_bea.LogStats(diffTime, m_dataAmount, bea_OPWRITE); 00207 00208 if (!newVolume) { 00209 // we have written some block to volume - end FRI 00210 FRIVolumeEnd(fri, df_FRIS_COMPLETE); 00211 } 00212 00213 bea_FRI bfri(m_bea, m_vol_p, g_cmn.dirs.fri); 00214 bfri.CloseVolume(); 00215 00216 ExchangeResources(); 00217 PrepareVolume(); 00218 00219 m_dataAmount = 0; 00220 newVolume = true; 00221 numBlkToCapChk = 0; 00222 startTime.Refresh(); 00223 if (m_bea.IsAborted()) { 00224 log_DBG_m(dbg_LOW, 00225 "Job aborted (3). Stop writing to tape."); 00226 break; 00227 } 00228 } 00229 } 00230 00231 if (newVolume) { 00232 auto_ptr<UInt8_t> contBlk_ap; 00233 contBlk_ap.reset(FRIVolumeStart(fri)); 00234 00235 if (contBlk_ap.get() != NULL) { 00236 log_DBG_m(dbg_DETAIL, "Parse & write cont block..."); 00237 if (WriteBlock(fri, contBlk_ap.get())) { 00238 // TODO: EOM - what to do?? 00239 } 00240 numBlkToCapChk--; 00241 } 00242 newVolume = false; 00243 } 00244 00245 bool reachedEOM(false); 00246 try { 00247 // write actual block to tape 00248 reachedEOM = WriteBlock(fri, blk->GetData()); 00249 } 00250 catch (const ivd_Error &ie) { 00251 switch (ie.GetError()) { 00252 case ie_MEDIUM_EOM: 00253 reachedEOM = true; 00254 break; 00255 case ie_MEDIUM_OVERFLOW: 00256 { 00257 bea_FRI fri(m_bea, m_vol_p, g_cmn.dirs.fri); 00258 fri.CloseVolumeInRMDB(); 00259 ostringstream sstr; 00260 sstr 00261 << "Vol " << m_vol_p->GetVolumeNumber() << ": " 00262 << "Overflow detected. Volume closed in RMDB."; 00263 00264 log_WriteEvent(evt_WARNING, sstr.str(), "FRI", 00265 m_bea.GetJobID(), m_bea.GetBarcode() ); 00266 } 00267 // fall through 00268 default: 00269 throw; 00270 } 00271 } 00272 00273 if (reachedEOM) { 00274 cmn_Time endTime; 00275 cmn_Time diffTime = endTime - startTime; 00276 m_bea.LogStats(diffTime, m_dataAmount, bea_OPWRITE); 00277 00278 if (!newVolume) { 00279 // we have written some block to volume - end FRI 00280 FRIVolumeEnd(fri, df_FRIS_COMPLETE); 00281 } 00282 00283 bea_FRI fri(m_bea, m_vol_p, g_cmn.dirs.fri); 00284 fri.CloseVolume(); 00285 00286 ExchangeResources(); 00287 PrepareVolume(); 00288 m_dataAmount = 0; 00289 newVolume = true; 00290 numBlkToCapChk = 0; 00291 startTime.Refresh(); 00292 } 00293 else { 00294 numBlkToCapChk--; 00295 }; 00296 00297 if (m_bea.IsAborted()) { 00298 log_DBG_m(dbg_LOW, "Job aborted. Stop writing to tape."); 00299 } 00300 } 00301 reader.Release(); 00302 } 00303 } 00304 00305 log_DBG_m(dbg_NORM, "End of data."); 00306 00307 if (!newVolume) { 00308 if (m_bea.IsAborted()) { 00309 FRIVolumeEnd(fri, df_FRIS_ABORTED); 00310 } 00311 else { 00312 FRIVolumeEnd(fri, df_FRIS_COMPLETE); 00313 } 00314 } 00315 00316 m_vol_p->Flush(); 00317 00318 // verify medium position 00319 UInt32_t actualMediumPos(m_vol_p->GetPosition()); 00320 if (m_mediumPos != actualMediumPos) { 00321 log_MARKLINE_m; 00322 ostringstream sstr; 00323 sstr 00324 << "Counted medium position (" << m_mediumPos << ")" 00325 << " is different from actual (" << actualMediumPos << "). " 00326 << "Job: " << m_bea.GetJobID() << " " 00327 << "Medium/volume: " 00328 << m_drive_p->GetMedium()->GetBarcode() << "/" 00329 << m_vol_p->GetVolumeNumber(); 00330 00331 throw ivd_Error(ie_DATA_CORRUPTION, sstr.str(), true); 00332 } 00333 00334 m_status = i_SUCCEDED; 00335 00336 cmn_Time endTime; 00337 cmn_Time diffTime = endTime - startTime; 00338 m_bea.LogStats(diffTime, m_dataAmount, bea_OPWRITE); 00339 00340 log_DBG_m(dbg_LOW, "Migration complete. Job ID: " << m_bea.GetJobID()); 00341 }


Definition at line 345 of file bea_migration.cpp.
References df_FRI::BlockScan(), df_FRI::BlockWritten(), dbg_DETAIL, dbg_LOW, bea_Medium::GetBarcode(), bea_Volume::GetBlockSize(), ivd_BaseException::GetError(), i_BackEndAgent_i::GetJobID(), bea_Drive::GetMedium(), bea_Volume::GetMedium(), bea_Volume::GetPosition(), bea_Volume::GetVolumeNumber(), i_DATA_ERROR, ie_DATA_CORRUPTION, ie_MEDIUM_EOM, ivd_Error, log_DBG_m, log_ERR_m, log_FUNC_m, m_bea, m_dataAmount, m_drive_p, m_mediumPos, m_status, m_vol_p, i_BackEndAgent_i::MustReadPosition(), and bea_Volume::Write().
Referenced by Migrate().
00345 { 00346 log_FUNC_m(WriteBlock); 00347 00348 bool medVolFull = false; 00349 00350 log_DBG_m(dbg_DETAIL, "Parse block & update fields..."); 00351 try { 00352 a_fri.BlockScan(a_blkBuf); 00353 } 00354 catch (...) { 00355 // Any error in Block Scan means disk buffer error; 00356 log_DBG_m(dbg_LOW, "*** Input disk buffer is not OK. ****"); 00357 m_status = i_DATA_ERROR; 00358 throw; 00359 }; 00360 00361 if (m_bea.MustReadPosition(m_vol_p->GetMedium())) { 00362 UInt32_t mediumPos = m_vol_p->GetPosition(); 00363 00364 if (mediumPos == m_mediumPos) { 00365 // Position is OK. 00366 } 00367 else { 00368 ostringstream sstr; 00369 00370 // Verify medium position to detect any unexpected change 00371 // of position which may result in data loss. 00372 if (mediumPos > m_mediumPos) { 00373 log_ERR_m( 00374 "Medium position (" << mediumPos << ")" 00375 << " is larger than expected (" << m_mediumPos << "). " 00376 << "Job: " << m_bea.GetJobID() << " " 00377 << "Medium/volume: " 00378 << m_drive_p->GetMedium()->GetBarcode() << "/" 00379 << m_vol_p->GetVolumeNumber() ); 00380 00381 sstr << "Medium position larger than expected. See error.log."; 00382 } 00383 else if (mediumPos < m_mediumPos) { 00384 log_ERR_m( 00385 "Medium position (" << mediumPos << ")" 00386 << " is smaller than expected (" << m_mediumPos << "). " 00387 << "Job: " << m_bea.GetJobID() << " " 00388 << "Medium/volume: " 00389 << m_drive_p->GetMedium()->GetBarcode() << "/" 00390 << m_vol_p->GetVolumeNumber() ); 00391 00392 if (mediumPos > 0) { 00393 sstr 00394 << "Data loss detected. Medium was overwritten. See error.log." 00395 << "Medium/volume: " 00396 << m_drive_p->GetMedium()->GetBarcode() << "/" 00397 << m_vol_p->GetVolumeNumber(); 00398 } 00399 else { 00400 sstr 00401 << "Medium position changed to 0. Aborting. See error.log." 00402 << "Medium/volume: " 00403 << m_drive_p->GetMedium()->GetBarcode() << "/" 00404 << m_vol_p->GetVolumeNumber(); 00405 } 00406 } 00407 // Position doesn't match. Throw exception. 00408 throw ivd_Error(ie_DATA_CORRUPTION, sstr.str(), true); 00409 } 00410 } 00411 00412 // Prevent invalid entries from being written to FRI/FSC 00413 if (m_mediumPos < m_vol_p->GetStartOfDataPosition()) { 00414 ostringstream sstr; 00415 sstr << "m_mediumPos = " << m_mediumPos << ", but should be >= 3"; 00416 throw ivd_InternalError(ie_DATA_CORRUPTION, sstr.str()); 00417 } 00418 00419 log_DBG_m(dbg_DETAIL, "Writing block to medium on position: " << m_mediumPos); 00420 try { 00421 m_vol_p->Write(a_blkBuf); 00422 } 00423 catch (ivd_Error &ie) { 00424 if (ie.GetError() == ie_MEDIUM_EOM) { 00425 log_DBG_m(dbg_LOW, "End of media detected. Will append FRI."); 00426 medVolFull = true; 00427 } 00428 else { 00429 throw; 00430 } 00431 } 00432 m_dataAmount += m_vol_p->GetBlockSize(); 00433 00434 log_DBG_m(dbg_DETAIL, "Block written. Append to FRI..."); 00435 00436 a_fri.BlockWritten(m_mediumPos); 00437 00438 // Update member to next expected medium position. 00439 ++m_mediumPos; 00440 00441 return medVolFull; 00442 }


| void bea_MigrationThread::SendToFSC | ( | const vector< df_SplitInfo > & | a_splits | ) | [private] |
Definition at line 445 of file bea_migration.cpp.
References dbg_LOW, dbg_NORM, i_BackEndAgent_i::GetBEANumber(), bea_Volume::GetEstimRemainingSize(), i_BackEndAgent_i::GetMediumKey(), i_BackEndAgent_i::GetMigrationID(), bea_Volume::GetPosition(), bea_Volume::GetVolumeID(), bea_Volume::GetVolumeNumber(), ie_FATAL_ERROR, cmn_UUID_t::IsNull(), log_DBG_m, log_FUNC_m, log_MARKLINE_m, m_bea, m_fsc, m_vol_p, and df_FRI::MediumVolumeStart().
Referenced by Migrate().
00445 { 00446 log_FUNC_m(FRIVolumeStart); 00447 00448 if (m_vol_p->GetVolumeID().IsNull()) { 00449 log_MARKLINE_m; 00450 throw ivd_InternalError(ie_FATAL_ERROR, "IDs not set for the migration."); 00451 } 00452 00453 UInt32_t startPos = m_vol_p->GetPosition(); 00454 00455 log_DBG_m(dbg_LOW, 00456 "Start Pos: " << startPos << 00457 " Remaining Capacity: " << 00458 m_vol_p->GetEstimRemainingSize() << " MB"); 00459 00460 log_DBG_m(dbg_NORM, 00461 "Start FRI for volume: " << m_vol_p->GetVolumeID() << 00462 ", startPos=" << startPos); 00463 00464 return a_fri.MediumVolumeStart( 00465 m_vol_p->GetVolumeID(), 00466 startPos, 00467 m_bea.GetMigrationID(), 00468 m_bea.GetBEANumber(), 00469 m_bea.GetMediumKey(), 00470 m_vol_p->GetVolumeNumber(), 00471 m_fsc ); 00472 00473 }


Definition at line 477 of file bea_migration.cpp.
References dbg_LOW, dbg_NORM, bea_Volume::GetEstimRemainingSize(), bea_Volume::GetPosition(), bea_Volume::GetVolumeID(), log_DBG_m, log_FUNC_m, m_vol_p, and df_FRI::MediumVolumeEnd().
Referenced by Migrate().
00477 { 00478 log_FUNC_m(FRIVolumeEnd); 00479 00480 UInt32_t endPos = m_vol_p->GetPosition(); 00481 00482 log_DBG_m(dbg_LOW, 00483 "Finishing FRI for this medium volume." << 00484 "End Pos: " << endPos << " Remaining Capacity: " << 00485 m_vol_p->GetEstimRemainingSize() << " MB"); 00486 00487 log_DBG_m(dbg_NORM, 00488 "End FRI for volume: " << m_vol_p->GetVolumeID() << 00489 ", endPos=" << endPos); 00490 00491 a_fri.MediumVolumeEnd(a_status); 00492 }


| void bea_MigrationThread::ExchangeResources | ( | ) | [private] |
Definition at line 498 of file bea_migration.cpp.
References dbg_NORM, i_BackEndAgent_i::GetDrive(), i_BackEndAgent_i::IsAborted(), log_DBG_m, log_FUNC_m, m_bea, m_drive_p, i_BackEndAgent_i::RequestNewResources(), and i_BackEndAgent_i::WaitForResources().
Referenced by CheckFRI(), and Migrate().
00498 { 00499 log_FUNC_m(ExchangeResources); 00500 00501 m_bea.RequestNewResources(); 00502 m_bea.WaitForResources(); 00503 00504 if (m_bea.IsAborted()) { 00505 log_DBG_m(dbg_NORM, "Aborted while requesting for resources."); 00506 return; 00507 } 00508 00509 // m_drive was reopened. Re-read the drive & medium. 00510 m_drive_p = m_bea.GetDrive(); 00511 }


| void bea_MigrationThread::PrepareVolume | ( | ) | [private] |
Definition at line 515 of file bea_migration.cpp.
References cfg_MEGABYTE, bea_Medium::ChangeVolume(), dbg_DETAIL, dbg_LOW, evt_WARNING, bea_Medium::GetBarcode(), i_BackEndAgent_i::GetBarcode(), bea_Volume::GetBlockSize(), bea_Medium::GetCurrentVolume(), bea_Medium::GetCurVolNumber(), ivd_BaseException::GetError(), i_BackEndAgent_i::GetJobType(), bea_Drive::GetMedium(), i_BackEndAgent_i::GetMedVolBlockSize(), i_BackEndAgent_i::GetMedVolID(), i_BackEndAgent_i::GetMedVolNumber(), i_BackEndAgent_i::GetPartitionID(), i_BackEndAgent_i::GetPoolID(), bea_Volume::GetPosition(), i_BackEndAgent_i::GetRM(), bea_Medium::GetVolume(), bea_Volume::GetVolumeID(), bea_Volume::GetVolumeNumber(), ie_BEA_INVVOLID, ie_FATAL_ERROR, ie_MEDIUM_MEDERR, bea_Medium::IsMediumMemValid(), ivd_Error, jt_MIGRATION, log_DBG_m, log_FUNC_m, log_MARKLINE_m, log_WriteEvent(), m_bea, m_drive_p, m_mediumPos, m_vol_p, i_BackEndAgent_i::MustVerifyHeader(), NULL, bea_Volume::OverrideIDs(), i_BackEndAgent_i::ReadIDs(), bea_Volume::SeekEOD(), bea_Volume::SetBlockSize(), cmn_UUID_t::ToString(), i_BackEndAgent_i::VerifyIDs(), and bea_Drive::WasMediumChanged().
Referenced by CheckFRI(), and Migrate().
00515 { 00516 log_FUNC_m(PrepareVolume); 00517 00518 bea_Medium* med = m_drive_p->GetMedium(); 00519 00520 if (med == NULL) { 00521 log_MARKLINE_m; 00522 throw ivd_InternalError( 00523 ie_FATAL_ERROR, "Medium not available after exchanging resources"); 00524 } 00525 00526 if (m_bea.GetJobType() != jt_MIGRATION) { 00527 // IDs for migration jobs already checked. 00528 // Check for other jobs (reorg) as well. 00529 00530 if (med->IsMediumMemValid()) { 00531 //First try to verify IDs from MAM/MIC 00532 //If it fails, check what is specified in trace.cfg 00533 //for checking IDs in medium header 00534 log_DBG_m(dbg_DETAIL, "Medium memory is detected and it and it contains valid cookies."); 00535 m_bea.ReadIDs(m_bea.GetMedVolNumber(), false); 00536 00537 try { 00538 m_bea.VerifyIDs( 00539 m_bea.GetBarcode(), 00540 m_bea.GetMedVolNumber(), 00541 m_bea.GetMedVolBlockSize(), 00542 cmn_UUID_t(m_bea.GetMedVolID()), 00543 cmn_UUID_t(m_bea.GetPoolID()) ); 00544 } 00545 catch (const ivd_Error) { 00546 log_DBG_m(dbg_LOW, 00547 "Error verifying IDs in medium memory. Check if it is needed to read from header."); 00548 if (m_drive_p->WasMediumChanged() || m_bea.MustVerifyHeader()){ 00549 try{ 00550 m_bea.ReadIDs(m_bea.GetMedVolNumber(), true); 00551 m_bea.VerifyIDs( 00552 m_bea.GetBarcode(), 00553 m_bea.GetMedVolNumber(), 00554 m_bea.GetMedVolBlockSize(), 00555 cmn_UUID_t(m_bea.GetMedVolID()), 00556 cmn_UUID_t(m_bea.GetPoolID()) ); 00557 } 00558 catch (const ivd_Error& e) { 00559 if (e.GetError() == ie_BEA_INVVOLID){ 00560 //If header is not correct, medium error is returned, 00561 //Handle error will set medium to unreliable 00562 throw ivd_Error(ie_MEDIUM_MEDERR, "Marking medium as unreliable. Header is not correct!", true); 00563 } 00564 else throw; 00565 } 00566 } 00567 else{ 00568 log_DBG_m(dbg_LOW, "Header won't be read and verified."); 00569 string mediumBarcode = m_bea.GetBarcode(); 00570 ostringstream eventText; 00571 eventText << "Reading from MAM/MIC has failed and header for media " << mediumBarcode; 00572 eventText << " is not verified" << endl; 00573 eventText << "Check in trace.cfg if HSM_BEA_VERIFY_HEADER is set to yes"; 00574 log_WriteEvent(evt_WARNING, eventText.str()); 00575 } 00576 } 00577 } 00578 else { 00579 log_DBG_m(dbg_DETAIL, "Medium memory is not detected or does not contain valid cookies."); 00580 if (m_bea.MustVerifyHeader() || m_drive_p->WasMediumChanged()) { 00581 // Check medium IDs for migration. 00582 // Writing part of reorg checks before writing 00583 log_DBG_m(dbg_DETAIL, "Header will be read and verified."); 00584 try{ 00585 m_bea.ReadIDs(m_bea.GetMedVolNumber(), true); 00586 m_bea.VerifyIDs( 00587 m_bea.GetBarcode(), 00588 m_bea.GetMedVolNumber(), 00589 m_bea.GetMedVolBlockSize(), 00590 cmn_UUID_t(m_bea.GetMedVolID()), 00591 cmn_UUID_t(m_bea.GetPoolID()) ); 00592 } 00593 catch (const ivd_Error& e) { 00594 if (e.GetError() == ie_BEA_INVVOLID){ 00595 //If header is not correct, medium error is returned, 00596 //Handle error will set medium to unreliable 00597 throw ivd_Error(ie_MEDIUM_MEDERR, "Marking medium as unreliable. Header is not correct!", true); 00598 } 00599 else throw; 00600 } 00601 } 00602 else { 00603 log_DBG_m(dbg_LOW, "Header won't be read and verified."); 00604 string mediumBarcode = m_bea.GetBarcode(); 00605 ostringstream eventText; 00606 eventText << "Reading from MAM/MIC has failed and header for media " << mediumBarcode; 00607 eventText << " is not verified" << endl; 00608 eventText << "Check in trace.cfg if HSM_BEA_VERIFY_HEADER is set to yes"; 00609 log_WriteEvent(evt_WARNING, eventText.str()); 00610 } 00611 } 00612 } 00613 00614 if (!med->IsMediumMemValid() && !m_bea.MustVerifyHeader()) { 00615 // IDs were not read from medium header. 00616 // IDs received from the job are set. 00617 bea_Volume* vol_p = med->GetVolume(m_bea.GetMedVolNumber()); 00618 vol_p->SetBlockSize(m_bea.GetMedVolBlockSize()); 00619 00620 cmn_UUID_t poolID(m_bea.GetPoolID()); 00621 vol_p->OverrideIDs(m_bea.GetMedVolID(), poolID, m_bea.GetPartitionID()); 00622 } 00623 00624 if (m_bea.GetMedVolNumber() != med->GetCurVolNumber()) { 00625 med->ChangeVolume(m_bea.GetMedVolNumber()); 00626 } 00627 00628 m_vol_p = med->GetCurrentVolume(); 00629 m_vol_p->SeekEOD(); 00630 00631 m_mediumPos = m_vol_p->GetPosition(); 00632 00633 i_ResourceManager_var rm = m_bea.GetRM(); 00634 i_MediumVol_t_var rmvol = rm->SelectMediumVol( 00635 CORBA::string_dup(med->GetBarcode().c_str()), 00636 m_vol_p->GetVolumeNumber()); 00637 00638 if (rmvol->volUsed == 0) { 00639 UInt32_t percent(1); 00640 UInt64_t totalData = (UInt64_t(m_mediumPos) * m_vol_p->GetBlockSize()) / cfg_MEGABYTE; 00641 00642 rm->VolumeUsage( 00643 CORBA::string_dup(m_vol_p->GetVolumeID().ToString().c_str()), 00644 percent, 00645 static_cast<i_VolSize_t>(totalData) ); 00646 00647 log_DBG_m(dbg_LOW, "Volume used is set to " << percent << "%"); 00648 } // if (rmvol->volUsed == 0) 00649 } //preparevolume


| void bea_MigrationThread::CheckFRI | ( | ) | [private] |
Definition at line 651 of file bea_migration.cpp.
References bea_FRI::CloseVolumeInRMDB(), dbg_DETAIL, dbg_LOW, dbg_NORM, cmn_Global::dirs, evt_WARNING, ExchangeResources(), ivd_Directories::fri, g_cmn, bea_Medium::GetBarcode(), ivd_BaseException::GetFriendly(), i_BackEndAgent_i::GetJobID(), bea_Drive::GetMedium(), bea_Volume::GetStartOfDataPosition(), bea_Volume::GetVolumeID(), bea_Volume::GetVolumeNumber(), log_DBG_m, log_FUNC_m, log_WriteEvent(), m_bea, m_drive_p, m_mediumPos, m_vol_p, bea_FRI::PositionToStartOfFRI(), PrepareVolume(), and cmn_UUID_t::ToString().
Referenced by Migrate().
00651 { 00652 log_FUNC_m(CheckFRI); 00653 00654 bool volumeFound(false); 00655 while (!volumeFound){ 00656 00657 // Check the position on the volume and the size of the FRI file. 00658 00659 UInt32_t eodPos(m_mediumPos); 00660 UInt64_t friSize(0); 00661 try { 00662 cmn_File friFile(g_cmn.dirs.fri + m_vol_p->GetVolumeID().ToString()); 00663 ivd_FileInfo_t info; 00664 friFile.StatF(info); 00665 friSize = info.size; 00666 log_DBG_m(dbg_LOW, "FRI found on disk: " << friFile.GetFullPathRef()); 00667 } 00668 catch (const ivd_Exception& ie) { 00669 log_DBG_m(dbg_DETAIL, "Can't get FRI size. " << ie.GetFriendly()); 00670 } 00671 00672 ostringstream sstr; 00673 if (eodPos > m_vol_p->GetStartOfDataPosition()) { 00674 // Some data was already migrated. 00675 log_DBG_m(dbg_DETAIL, "Some data was already migrated."); 00676 00677 if (friSize == 0) { 00678 // bug 8338 00679 log_DBG_m(dbg_NORM, "friSize == 0"); 00680 00681 //check if FRI is on medium 00682 //this can happen after restore from backup 00683 00684 bea_FRI fri(m_bea, m_vol_p, g_cmn.dirs.fri); 00685 bool friOnMedium(false); 00686 friOnMedium = fri.PositionToStartOfFRI(); 00687 00688 if (friOnMedium){ 00689 sstr 00690 << "Vol " << m_vol_p->GetVolumeNumber() 00691 << ": Volume contains data and FRI. " 00692 << "Will close volume and request new for migration."; 00693 00694 log_WriteEvent( 00695 evt_WARNING, sstr.str(), "", 00696 m_bea.GetJobID(), m_drive_p->GetMedium()->GetBarcode()); 00697 00698 //close volume 00699 fri.CloseVolumeInRMDB(); 00700 00701 // 00702 ExchangeResources(); 00703 PrepareVolume(); 00704 } else { 00705 //looks like there is only data, but no FRI 00706 sstr 00707 << "Vol " << m_vol_p->GetVolumeNumber() 00708 << ": Volume contains data, but there is no FRI on the disk. " 00709 << "Recreate FRI for this medium volume."; 00710 00711 log_WriteEvent( 00712 evt_WARNING, sstr.str(), "", 00713 m_bea.GetJobID(), m_drive_p->GetMedium()->GetBarcode()); 00714 volumeFound = true; 00715 } 00716 } else { 00717 volumeFound = true; 00718 log_DBG_m(dbg_NORM, "friSize:" << friSize); 00719 } 00720 } else if (friSize > 0) { 00721 // Volume is empty. 00722 sstr 00723 << "Vol " << m_vol_p->GetVolumeNumber() 00724 << ": Volume is empty, but there is FRI on the disk. " 00725 << "Recreate FRI for this medium volume."; 00726 00727 log_WriteEvent( 00728 evt_WARNING, sstr.str(), "", 00729 m_bea.GetJobID(), m_drive_p->GetMedium()->GetBarcode()); 00730 volumeFound = true; 00731 } else { 00732 //no data migrated and no FRI 00733 log_DBG_m(dbg_LOW, "No data migrated and no FRI."); 00734 volumeFound = true; 00735 } 00736 } 00737 }


bea_MigrationThread::log_CLASSID_m [private] |
i_BackEndAgent_i& bea_MigrationThread::m_bea [private] |
Definition at line 57 of file bea_migration.h.
Referenced by bea_MigrationThread(), CheckFRI(), ExchangeResources(), FRIVolumeStart(), Migrate(), PrepareVolume(), Run(), WriteBlock(), and ~bea_MigrationThread().
bea_Drive* bea_MigrationThread::m_drive_p [private] |
Definition at line 58 of file bea_migration.h.
Referenced by CheckFRI(), ExchangeResources(), Migrate(), PrepareVolume(), WriteBlock(), and ~bea_MigrationThread().
i_FSC_var bea_MigrationThread::m_fsc [private] |
Definition at line 59 of file bea_migration.h.
Referenced by bea_MigrationThread(), and FRIVolumeStart().
bea_Volume* bea_MigrationThread::m_vol_p [private] |
Definition at line 60 of file bea_migration.h.
Referenced by CheckFRI(), FRIVolumeEnd(), FRIVolumeStart(), Migrate(), PrepareVolume(), and WriteBlock().
UInt32_t bea_MigrationThread::m_mediumPos [private] |
Definition at line 62 of file bea_migration.h.
Referenced by CheckFRI(), Migrate(), PrepareVolume(), and WriteBlock().
UInt64_t bea_MigrationThread::m_dataAmount [private] |
Definition at line 65 of file bea_migration.h.
Referenced by Migrate(), Run(), WriteBlock(), and ~bea_MigrationThread().
vector<UInt64_t> bea_MigrationThread::m_minColIds [private] |
Definition at line 67 of file bea_migration.h.
1.5.6