bea_MigrationThread Class Reference
[IVD Back-End Agent]

#include <bea_migration.h>

Inheritance diagram for bea_MigrationThread:

Inheritance graph
[legend]
Collaboration diagram for bea_MigrationThread:

Collaboration graph
[legend]

List of all members.


Detailed Description

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_tFRIVolumeStart (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_im_bea
bea_Drivem_drive_p
i_FSC_var m_fsc
bea_Volumem_vol_p
UInt32_t m_mediumPos
UInt64_t m_dataAmount
i_CompletionStatus_e m_status
vector< UInt64_tm_minColIds

Constructor & Destructor Documentation

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 }

Here is the call graph for this function:

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 }

Here is the call graph for this function:


Member Function Documentation

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 }

Here is the call graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

bool bea_MigrationThread::WriteBlock ( df_FRI a_fri,
UInt8_t a_blkBuf 
) [private]

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

void bea_MigrationThread::SendToFSC ( const vector< df_SplitInfo > &  a_splits  )  [private]

UInt8_t * bea_MigrationThread::FRIVolumeStart ( df_FRI a_fri  )  [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 }

Here is the call graph for this function:

Here is the caller graph for this function:

void bea_MigrationThread::FRIVolumeEnd ( df_FRI a_fri,
UInt32_t  a_status 
) [private]

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

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_migration.h.

i_FSC_var bea_MigrationThread::m_fsc [private]

Definition at line 59 of file bea_migration.h.

Referenced by bea_MigrationThread(), and FRIVolumeStart().

Definition at line 62 of file bea_migration.h.

Referenced by CheckFRI(), Migrate(), PrepareVolume(), and WriteBlock().

Definition at line 63 of file bea_migration.h.

Referenced by Migrate(), and WriteBlock().

Definition at line 65 of file bea_migration.h.

Referenced by Migrate(), Run(), WriteBlock(), and ~bea_MigrationThread().

Definition at line 67 of file bea_migration.h.


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

Generated on Mon Feb 27 19:00:28 2012 for OPENARCHIVE by  doxygen 1.5.6