#include <bea_mediumdup.h>


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_i & | m_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 |
| 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 }

| 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 }

| 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 }

| 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 }


| 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 }


bea_DupWriteThread::log_CLASSID_m [private] |
i_BackEndAgent_i& bea_DupWriteThread::m_bea [private] |
Definition at line 79 of file bea_mediumdup.h.
Referenced by AppendVolume(), bea_DupWriteThread(), Run(), WriteMedVolume(), and ~bea_DupWriteThread().
bea_Drive* const bea_DupWriteThread::m_drive_p [private] |
UInt32_t bea_DupWriteThread::m_volSize [private] |
bool bea_DupWriteThread::m_appendVol [private] |
bool bea_DupWriteThread::m_srcMediumFull [private] |
UInt32_t bea_DupWriteThread::m_volChunks [private] |
1.5.6