Public Member Functions | Private Member Functions | Private Attributes

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.

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

Detailed Description

Definition at line 46 of file bea_mediumdup.h.


Constructor & Destructor Documentation

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

Definition at line 54 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.

  : m_bea(a_bea),
    m_drive_p(a_drive_p),
    m_status(i_UNKNOWN) {

    log_FUNC_m(bea_DupReadThread);

    if (m_bea.GetMedVolNumber() == 0) {
        throw ivd_Error(ie_INVALID_ARG, "VolID is 0.", true);
    }

    m_bea.m_threadCounter.Inc();
}

Here is the call graph for this function:

bea_DupReadThread::~bea_DupReadThread (  )  [virtual]

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

                                      {

    log_FUNC_m(~bea_DupReadThread);

    try {
        m_bea.ReleaseResources();
    }
    catch (...) {
        // Ignore all exceptions at this point
    }

    try {
        if (m_bea.IsAborted()) {
            log_DBG_m(dbg_LOW, "Duplication aborted. Won't contact job.");
        }
        else {
            ipc_EXEC_m(
                if( !CORBA::is_nil(m_bea.GetJob()) ) {
                    log_DBG_m(dbg_LOW, "Completion status: " << m_status);
                    i_Job_var job = m_bea.GetJob();
                    job->MediumOperationComplete(m_bea.GetBEANumber(), m_status);
                };
            );
        }
    }
    catch(...) {
        // Ignore all exceptions at this point.
    }

    m_bea.m_threadCounter.Dec();
}

Here is the call graph for this function:


Member Function Documentation

void bea_DupReadThread::ReadMedVolume (  )  [private]

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

                                      {
    log_FUNC_m(ReadMedVolume);

    log_DBG_m(dbg_LOW,
        "Started reading medium. Job ID: " << m_bea.GetJobID());

    m_bea.WaitForResources();

    if (m_bea.IsAborted()) {
        log_DBG_m(dbg_LOW, "Job aborted. Exit.");
        return;
    };

    bea_Medium* med = m_drive_p->GetMedium();
    if (m_bea.GetMedVolNumber() != med->GetCurVolNumber()) {
        med->ChangeVolume(m_bea.GetMedVolNumber());
    }

    bea_Volume *const vol = m_drive_p->GetMedium()->GetCurrentVolume();

/* TODO: Enable Volume ID Check for medium duplication?
         Does job set it?

    vol->ReadVolInfoFromHeader();

    // Check volume ID.
    cmn_UUID_t volid(m_bea.GetMedVolID());
    if (vol->GetVolumeID() != volid) {
        ostringstream sstr;
        sstr <<
            m_bea.GetBarcode() << ":" << m_bea.GetMedVolNumber() <<
            " Medium duplication. Volume UUID doesn't match. Expected: " << volid <<
            " read: " << vol->GetVolumeID() );

        log_WriteEvent(evt_ERROR, sstr.str(), "MEDIUMDUP",
            m_bea.GetJobID(), m_bea.GetBarcode() );

        throw ivd_Error(ie_BEA_INVVOLID, sstr.str());
    };
*/
    vol->Rewind();

    //
    // Medium volume is divided into one or more chunks (parts of volume
    // between file marks. Each of the chunks is written into a separate
    // file.
    //
    UInt32_t    chunkNum(0);
    bool        endOfVolume(false);

    log_DBG_m(dbg_LOW, "Dumping medium volume header.");

    {
        cmn_Path chunkName;
        {
            ostringstream sstr;
            sstr << vol->GetVolumeID() << "." << chunkNum;
            chunkName = g_cmn.dirs.diskbuf + m_bea.GetDiskBufferFS() + sstr.str();
        }

        cmn_File copyFile(chunkName);
        copyFile.OpenF(fom_WRITE | fom_CREATE_ALWAYS);

        UInt32_t blockSize(vol->GetBlockSize());
        vector<UInt8_t> hdrBlock(df_VOLHDR_REC_SIZE, 0);
        vector<UInt8_t> block(blockSize, 0);

        try {
            vol->ReadVolHdr(&(hdrBlock[0]));
            copyFile.WriteF(&(hdrBlock[0]), df_VOLHDR_REC_SIZE);

            vol->Read(&(block[0]));
            copyFile.WriteF(&(block[0]), blockSize);

            // This should trigger exception (file mark).
            vol->Read(&(block[0]));
            copyFile.WriteF(&(block[0]), blockSize);
        }
        catch (const ivd_Error& ie) {
            switch (ie.GetError()) {
                case ie_MEDIUM_FILEMARK:
                    log_DBG_m(dbg_LOW,
                        "File mark detected ==> End of header.");
                    break;
                case ie_MEDIUM_EOM:
                    log_DBG_m(dbg_LOW,
                        "End of volume detected ==> Stop reading");
                    endOfVolume = true;
                    break;
                case ie_MEDIUM_EOD:
                    log_DBG_m(dbg_LOW,
                        "End of data detected ==> Stop reading.");
                    endOfVolume = true;
                    break;
                default:
                    log_DBG_m(dbg_LOW,
                    "Unexpected exception while reading volume ==> re-throw.");
                    throw;
            } // switch
        }
        log_DBG_m(dbg_NORM, "Dumped " << chunkName);
        copyFile.SyncF();
        chunkNum++;
    }

    log_DBG_m(dbg_LOW, "Dumping rest of medium volume chunks.");

    while (!endOfVolume && !m_bea.IsAborted()) {
        cmn_Path chunkName;
        {
            ostringstream sstr;
            sstr << vol->GetVolumeID() << "." << chunkNum;
            chunkName = g_cmn.dirs.diskbuf + m_bea.GetDiskBufferFS()+ sstr.str();
        }

        cmn_File copyFile(chunkName);
        copyFile.OpenF(fom_WRITE | fom_CREATE_ALWAYS);

        UInt32_t blockSize(vol->GetBlockSize());
        vector<UInt8_t> block(blockSize, 0);

        try {
            while(!m_bea.IsAborted()) {
                vol->Read(&(block[0]));
                copyFile.WriteF(&(block[0]), blockSize);
            }
        }
        catch (const ivd_Error& ie) {
            switch (ie.GetError()) {
                case ie_MEDIUM_FILEMARK:
                    log_DBG_m(dbg_LOW,
                        "File mark detected ==> End of volume part.");
                    break;
                case ie_MEDIUM_EOD:
                    log_DBG_m(dbg_LOW,
                        "End of data detected ==> Stop reading.");
                    endOfVolume = true;
                    break;
                default:
                    log_DBG_m(dbg_LOW,
                    "Unexpected exception while reading volume ==> re-throw.");
                    throw;
            } // switch
        }
        log_DBG_m(dbg_NORM, "Dumped " << chunkName);
        copyFile.SyncF();
        copyFile.CloseF();

        if (!endOfVolume) {
            chunkNum++;
        }
    }

    log_DBG_m(dbg_LOW, "Sucessfully completed reading medium volume.");
}

Here is the call graph for this function:

Here is the caller graph for this function:

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

Reimplemented from cmn_Thread.

Definition at line 106 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, log_DBG_m, log_FUNC_m, log_WriteEvent(), m_bea, m_status, and ReadMedVolume().

                                     {
    log_FUNC_m(Run);

    try {
        ReadMedVolume();
        m_status = i_SUCCEDED;
        log_DBG_m(dbg_LOW, "Completed duplication reading task.");
    }
    catch(ivd_Error &ie) {
        m_status = m_bea.HandleError(ie, bea_OPREAD);
    }
    catch(const std::exception& ie) {
        ostringstream sstr;
        sstr << "Duplication failed: " << ie.what();

        log_WriteEvent(evt_ERROR, sstr.str(), "",
            m_bea.GetJobID(), m_bea.GetBarcode() );

        if (m_status == i_SUCCEDED) {
            m_status = i_UNKNOWN;
        }
    }
    catch(...) {
        log_WriteEvent(evt_ERROR, "Duplication failed. Unknown error.", "",
            m_bea.GetJobID(), m_bea.GetBarcode() );

        if (m_status == i_SUCCEDED) {
            m_status = i_UNKNOWN;
        }
    }
}

Here is the call graph for this function:


Member Data Documentation

Reimplemented from cmn_Thread.

Definition at line 58 of file bea_mediumdup.h.

Definition at line 62 of file bea_mediumdup.h.

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

Definition at line 63 of file bea_mediumdup.h.

Referenced by ReadMedVolume().

Definition at line 65 of file bea_mediumdup.h.

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


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