bea_DiskVolume Class Reference
[IVD Back-End Agent]

#include <bea_diskvolume.h>

Inheritance diagram for bea_DiskVolume:

Inheritance graph
[legend]
Collaboration diagram for bea_DiskVolume:

Collaboration graph
[legend]

List of all members.


Detailed Description

Definition at line 46 of file bea_diskvolume.h.


Public Types

enum  dv_FileType_e {
  dv_HeaderFile, dv_DataFile,
  dv_FRIFile
}

Public Member Functions

 bea_DiskVolume (bea_Medium *const a_medium_p, UInt32_t a_volNumber, UInt32_t a_volSize)
virtual UInt32_t GetPosition ()
virtual void Erase ()
virtual void WriteFileMarks (UInt32_t a_count=1)
virtual void Flush ()
virtual void SeekEOD ()
virtual void Rewind ()
virtual void SeekBlock (UInt32_t a_block)
virtual void SeekFileMark (Int32_t a_relativeFM)

Protected Member Functions

virtual ~bea_DiskVolume ()
virtual void WriteRaw (const UInt8_t *a_buf, UInt32_t a_size)
virtual void ReadRaw (UInt8_t *a_buf, UInt32_t a_size)
virtual void ReadEstimSizes ()
 Reads estimated overall and remaining capacity of this medium volume.

Private Member Functions

void ReparseFiles ()
dv_FileType_e GetTypeFromExt (const string &a_extStr)
void CreateNewFile ()
void ExtendToFullBlock (cmn_File &a_file, ivd_FilePosition_t a_filePos, UInt32_t a_blkSize)
void ReadVolInfo ()
void WriteVolInfo ()

Static Private Member Functions

static string CreateOffsetFileName (UInt32_t a_offset, dv_FileType_e a_type)

Private Attributes

 log_CLASSID_m
cmn_Path m_dvPath
cmn_File m_dvinfo
vector< VolFilem_files
UInt32_t m_curFile

Classes

class  VolFile

Member Enumeration Documentation

Enumerator:
dv_HeaderFile 
dv_DataFile 
dv_FRIFile 

Definition at line 66 of file bea_diskvolume.h.


Constructor & Destructor Documentation

bea_DiskVolume::bea_DiskVolume ( bea_Medium *const   a_medium_p,
UInt32_t  a_volNumber,
UInt32_t  a_volSize 
)

Definition at line 50 of file bea_diskvolume.cpp.

References dbg_NORM, log_DBG_m, log_FUNC_A_m, m_dvPath, ReadVolInfo(), ReparseFiles(), and bea_Volume::SetDeclaredSize().

00054   : bea_Volume(a_medium_p, a_volNumber, a_size),
00055     m_dvPath(bea_DiskMedium::GetDiskMediumPath(a_medium_p->GetBarcode()) +
00056              bea_DiskMedium::VolDirName(a_volNumber)),
00057     m_dvinfo( m_dvPath + dv_VOLINFO ),
00058     m_curFile(0) {
00059 
00060     log_FUNC_A_m(bea_DiskVolume,
00061         "location: " << m_dvPath << " num: " << a_volNumber << " size: " << a_size);
00062 
00063     if (a_size > 0) {
00064         log_DBG_m(dbg_NORM, "Setting default declared volume size to: " << a_size);
00065         SetDeclaredSize(a_size);
00066     };
00067 
00068     ReadVolInfo();
00069     ReparseFiles();
00070 }

Here is the call graph for this function:

bea_DiskVolume::~bea_DiskVolume (  )  [protected, virtual]

Definition at line 74 of file bea_diskvolume.cpp.

References log_FUNC_m.

00074                                 {
00075     log_FUNC_m(~bea_DiskVolume);
00076 
00077 //    WriteVolInfo();
00078 }


Member Function Documentation

UInt32_t bea_DiskVolume::GetPosition (  )  [virtual]

Implements bea_Volume.

Definition at line 154 of file bea_diskvolume.cpp.

References bea_DiskVolume::VolFile::blkOffset, df_VOLHDR_REC_SIZE, bea_DiskVolume::VolFile::file, file, bea_Volume::GetBlockSize(), cmn_File::GetCurrentPosF(), cmn_File::IsOpen(), log_FUNC_m, m_curFile, and m_files.

Referenced by ReadRaw(), SeekBlock(), and SeekEOD().

00154                                      {
00155     log_FUNC_m(GetPosition);
00156 
00157     const VolFile& file = m_files[m_curFile];
00158     UInt32_t position(file.blkOffset);
00159 
00160     if (file.file.IsOpen()) {
00161         if (file.file.GetCurrentPosF() == 0) {
00162             position += 0;
00163         }
00164         else {
00165             ivd_FilePosition_t pos(file.file.GetCurrentPosF());
00166 
00167             // Special handling for volume header block, which occupies one
00168             // fixed-size block.
00169             if (m_curFile == 0) {
00170                 if (pos < df_VOLHDR_REC_SIZE) {
00171                     position = 0;
00172                 }
00173                 else {
00174                     position = 1 + ( (pos - df_VOLHDR_REC_SIZE) / GetBlockSize() );
00175                 }
00176             }
00177             else {
00178                 position += pos / GetBlockSize();
00179             }
00180         }
00181     }
00182     return position;
00183 }

Here is the call graph for this function:

Here is the caller graph for this function:

void bea_DiskVolume::Erase (  )  [virtual]

Implements bea_Volume.

Definition at line 315 of file bea_diskvolume.cpp.

References dbg_DETAIL, dbg_NORM, cmn_File::DeleteF(), file, fom_READWRITE, cmn_File::GetCurrentPosF(), bea_Volume::InvalidateSizes(), cmn_File::IsOpen(), log_DBG_m, log_FUNC_m, bea_Volume::m_atEOD, m_curFile, m_files, cmn_File::OpenF(), cmn_File::SeekEndF(), size, and cmn_File::TruncF().

Referenced by WriteFileMarks(), and WriteRaw().

00315                            {
00316     log_FUNC_m(Erase);
00317 
00318 //    WriteVolInfo();
00319     InvalidateSizes();
00320 
00321     if (m_files.size() == 0) {
00322         return;
00323     }
00324 
00325     UInt32_t deletedFiles(0);
00326     for (UInt32_t i(m_curFile+1); i < m_files.size(); ++i) {
00327         log_DBG_m(dbg_DETAIL, "Deleting file: " << i);
00328         cmn_File& file = m_files[i].file;
00329         file.DeleteF();
00330         ++deletedFiles;
00331     }
00332 
00333     cmn_File& file = m_files[m_curFile].file;
00334     if (!file.IsOpen()) {
00335         file.OpenF(fom_READWRITE);
00336     }
00337 
00338     ivd_FilePosition_t pos = file.GetCurrentPosF();
00339     if (pos == 0) {
00340         if (m_files[m_curFile].size > 0 || deletedFiles == 0) {
00341             log_DBG_m(dbg_DETAIL,
00342                 "Positioned at the beginning of file. Deleting file: " << m_curFile);
00343             file.DeleteF();
00344             --m_curFile;
00345         }
00346         else {
00347             log_DBG_m(dbg_DETAIL,
00348                 "Erase already deleted files after empty file: " << m_curFile);
00349         }
00350     }
00351     else {
00352         log_DBG_m(dbg_DETAIL,
00353             "Truncating file " << m_curFile << " on position: " << pos);
00354         file.TruncF(pos);
00355         file.SeekEndF();
00356     }
00357 
00358     if (m_curFile+1 < m_files.size()) {
00359         m_files.resize(m_curFile+1);
00360     };
00361 
00362     log_DBG_m(dbg_NORM,
00363         "Files left after erasing: " << m_files.size() << ".");
00364 
00365     m_atEOD = true;
00366 }

Here is the call graph for this function:

Here is the caller graph for this function:

void bea_DiskVolume::WriteFileMarks ( UInt32_t  a_count = 1  )  [virtual]

Implements bea_Volume.

Definition at line 370 of file bea_diskvolume.cpp.

References CreateNewFile(), dbg_LOW, bea_Volume::DoMediumLogging(), Erase(), bea_Medium::GetBarcode(), bea_Volume::GetJobID(), bea_Volume::GetVolumeNumber(), log_DBG_m, log_FUNC_A_m, log_WriteEvent(), bea_Volume::m_atEOD, m_files, and bea_Volume::m_medium_p.

00370                                                     {
00371     log_FUNC_A_m(WriteFileMarks, "count: " << a_count);
00372 
00373 //    WriteVolInfo();
00374 
00375     if (DoMediumLogging()) {
00376         ostringstream sstr;
00377         sstr << "Vol " << GetVolumeNumber()
00378             << ": Writing filemark(s) "<< a_count << "...";
00379 
00380         log_WriteEvent(
00381             sstr.str(), "",
00382             GetJobID(),
00383             m_medium_p->GetBarcode());
00384     }
00385 
00386     if (!m_atEOD) {
00387         Erase();
00388     }
00389 
00390     for (UInt32_t i(0); i < a_count; ++i) {
00391         CreateNewFile();
00392     }
00393 
00394     log_DBG_m(dbg_LOW, "Currently " << m_files.size() << " files on volume.");
00395 
00396     m_atEOD = true;
00397 }

Here is the call graph for this function:

void bea_DiskVolume::Flush (  )  [virtual]

Implements bea_Volume.

Definition at line 401 of file bea_diskvolume.cpp.

References file, cmn_File::IsOpen(), log_FUNC_m, m_curFile, m_files, and cmn_File::SyncF().

00401                            {
00402     log_FUNC_m(Flush);
00403 
00404     cmn_File& file = m_files[m_curFile].file;
00405     if (file.IsOpen()) {
00406         file.SyncF();
00407     }
00408 
00409 //    WriteVolInfo();
00410 }

Here is the call graph for this function:

void bea_DiskVolume::SeekEOD (  )  [virtual]

Implements bea_Volume.

Definition at line 414 of file bea_diskvolume.cpp.

References cmn_File::CloseF(), dbg_DETAIL, df_VOLHDR_REC_SIZE, bea_Volume::DoMediumLogging(), ExtendToFullBlock(), fom_READWRITE, bea_Medium::GetBarcode(), bea_Volume::GetBlockSize(), bea_Volume::GetJobID(), GetPosition(), bea_Volume::GetVolumeNumber(), ie_MEDIUM_MEDERR, ivd_Error, log_DBG_m, log_FUNC_m, log_WriteEvent(), bea_Volume::m_atEOD, m_curFile, m_dvPath, m_files, bea_Volume::m_medium_p, cmn_File::OpenF(), and cmn_File::SeekEndF().

00414                              {
00415     log_FUNC_m(SeekEOD);
00416 
00417     if (DoMediumLogging()) {
00418         ostringstream sstr;
00419         sstr << "Vol " << GetVolumeNumber()
00420             << ": Seeking to EOD...";
00421 
00422         log_WriteEvent(
00423             sstr.str(), "",
00424             GetJobID(),
00425             m_medium_p->GetBarcode());
00426     }
00427 
00428     if (m_files.size() == 0) {
00429         m_curFile = 0;
00430     }
00431     else {
00432         cmn_File& cf = m_files[m_curFile].file;
00433         cf.CloseF();
00434 
00435         m_curFile = m_files.size()-1;
00436         cmn_File& lf = m_files[m_curFile].file;
00437         lf.OpenF(fom_READWRITE);
00438         ivd_FilePosition_t filePos = lf.SeekEndF();
00439 
00440         //
00441         // Check consistency of the file: EOD must be either:
00442         // - at the end of the header: size is known
00443         // - EOF position must be divisible by block size
00444         //
00445         if (m_curFile == 0) {
00446             if ( filePos != df_VOLHDR_REC_SIZE + GetBlockSize() ) {
00447                 ostringstream sstr;
00448                 sstr << "Disk medium error (header size mismatch): " << m_dvPath;
00449                 throw ivd_Error(ie_MEDIUM_MEDERR, sstr.str());
00450             }
00451         }
00452         else {
00453             ExtendToFullBlock(lf, filePos, GetBlockSize());
00454         }
00455     }
00456     m_atEOD = true;
00457 
00458     if (DoMediumLogging()) {
00459         ostringstream sstr;
00460         sstr << "Vol " << GetVolumeNumber()
00461             << ": At EOD (" << GetPosition() << ")";
00462 
00463         log_WriteEvent(
00464             sstr.str(), "",
00465             GetJobID(),
00466             m_medium_p->GetBarcode());
00467     }
00468 
00469     log_DBG_m(dbg_DETAIL,
00470         "Volume:" << m_dvPath << " CurrentFile:" << m_curFile);
00471 }

Here is the call graph for this function:

void bea_DiskVolume::Rewind (  )  [virtual]

Implements bea_Volume.

Definition at line 568 of file bea_diskvolume.cpp.

References bea_Volume::DoMediumLogging(), bea_Medium::GetBarcode(), bea_Volume::GetJobID(), bea_Volume::GetVolumeNumber(), log_FUNC_m, log_WriteEvent(), bea_Volume::m_medium_p, and SeekBlock().

00568                             {
00569     log_FUNC_m(Rewind);
00570 
00571     if (DoMediumLogging()) {
00572         ostringstream sstr;
00573         sstr << "Vol " << GetVolumeNumber()
00574             << ": Rewind...";
00575 
00576         log_WriteEvent(
00577             sstr.str(), "",
00578             GetJobID(),
00579             m_medium_p->GetBarcode());
00580     }
00581 
00582     SeekBlock(0);
00583 }

Here is the call graph for this function:

void bea_DiskVolume::SeekBlock ( UInt32_t  a_block  )  [virtual]

Implements bea_Volume.

Definition at line 475 of file bea_diskvolume.cpp.

References bea_DiskVolume::VolFile::blkOffset, cmn_File::CloseF(), dbg_DETAIL, dbg_LOW, bea_Volume::DoMediumLogging(), bea_DiskVolume::VolFile::file, fom_READ, bea_Medium::GetBarcode(), bea_Volume::GetBlockSize(), bea_Volume::GetJobID(), GetPosition(), bea_Volume::GetVolumeNumber(), ie_FATAL_ERROR, ie_MEDIUM_EOM, bea_Volume::InvalidateEOD(), bea_Volume::InvalidateSizes(), ivd_Error, log_DBG_m, log_FUNC_A_m, log_MARKLINE_m, log_WriteEvent(), m_curFile, m_dvPath, m_files, bea_Volume::m_medium_p, cmn_File::OpenF(), cmn_File::SeekF(), and bea_DiskVolume::VolFile::size.

Referenced by Rewind().

00475                                                {
00476     log_FUNC_A_m(SeekBlock, " blk: " << a_block);
00477 
00478     if (DoMediumLogging()) {
00479         ostringstream sstr;
00480         sstr << "Vol " << GetVolumeNumber()
00481             << ": Seeking to " << a_block << "...";
00482 
00483         log_WriteEvent(
00484             sstr.str(), "",
00485             GetJobID(),
00486             m_medium_p->GetBarcode());
00487     }
00488 
00489     InvalidateSizes();
00490     InvalidateEOD();
00491 
00492     if (m_files.size() == 0) {
00493         if (a_block > 0) {
00494             throw ivd_Error(ie_MEDIUM_EOM, "Disk volume is empty. Already on EOM.");
00495         }
00496         else {
00497             return;
00498         }
00499     }
00500 
00501     UInt32_t tgtFile(UINT_MAX);
00502     UInt32_t relOffset(0);
00503 
00504     cmn_File& cf = m_files[m_curFile].file;
00505     cf.CloseF();
00506 
00507     if (a_block == 0) {
00508         tgtFile = 0;
00509         relOffset = 0;
00510         VolFile& tf = m_files[tgtFile];
00511         tf.file.OpenF(fom_READ);
00512         tf.file.SeekF(0);
00513     }
00514     else {
00515         for (UInt32_t i(0); i < m_files.size(); ++i) {
00516             if (m_files[i].blkOffset > a_block) {
00517                 tgtFile = i-1;
00518                 break;
00519             }
00520         }
00521 
00522         // Try the last file
00523         if (tgtFile == UINT_MAX) {
00524             tgtFile = m_files.size()-1;
00525         }
00526 
00527         VolFile& tf = m_files[tgtFile];
00528         tf.file.OpenF(fom_READ);
00529 
00530         relOffset = a_block - tf.blkOffset;
00531         ivd_FilePosition_t seekPos(static_cast<ivd_FilePosition_t>(relOffset) * GetBlockSize());
00532 
00533         if (seekPos > tf.size) {
00534             log_MARKLINE_m;
00535 #if TGT_OS_linux
00536 #warning Check consistency of the file size (see SeekEOD).
00537 #endif
00538             if (tgtFile == m_files.size()-1) {
00539                 throw ivd_Error(ie_MEDIUM_EOM, "Seek over the EOD.");
00540             }
00541             else {
00542                 throw ivd_InternalError(ie_FATAL_ERROR,
00543                     "Invalid internal calculation.",
00544                     string("Seek over the size of the file."));
00545             }
00546         };
00547         tf.file.SeekF(seekPos);
00548     }
00549 
00550     m_curFile = tgtFile;
00551 
00552     log_DBG_m(dbg_DETAIL, "Volume:" << m_dvPath <<
00553         " CurrentFile:" << m_curFile );
00554 
00555     // Verify that new position is OK.
00556     UInt32_t newPosition(GetPosition());
00557     if ( newPosition != a_block ) {
00558         log_DBG_m(dbg_LOW, "CurrentPosition: " << newPosition << " a_blk: " << a_block);
00559 
00560         throw ivd_InternalError(ie_FATAL_ERROR,
00561             "Invalid internal calculation.",
00562             string("GetPosition() returns value different from a_block."));
00563     }
00564 }

Here is the call graph for this function:

Here is the caller graph for this function:

void bea_DiskVolume::SeekFileMark ( Int32_t  a_relativeFM  )  [virtual]

Implements bea_Volume.

Definition at line 587 of file bea_diskvolume.cpp.

References cmn_File::CloseF(), dbg_NORM, bea_Volume::DoMediumLogging(), bea_DiskVolume::VolFile::file, fom_READWRITE, bea_Medium::GetBarcode(), bea_Volume::GetJobID(), bea_Volume::GetVolumeNumber(), ie_MEDIUM_BLANK, ie_MEDIUM_EOD, bea_Volume::InvalidateEOD(), ivd_Error, log_DBG_m, log_FUNC_A_m, log_MARKLINE_m, log_WriteEvent(), bea_Volume::m_atEOD, m_curFile, m_files, bea_Volume::m_medium_p, cmn_File::OpenF(), and cmn_File::SeekEndF().

00587                                                       {
00588     log_FUNC_A_m(SeekFileMark, "relativeFM: " << a_relativeFM);
00589 
00590     if (DoMediumLogging()) {
00591         ostringstream sstr;
00592         sstr << "Vol " << GetVolumeNumber()
00593             << ": Seeking " << a_relativeFM << " filemark(s) forward...";
00594 
00595         log_WriteEvent(
00596             sstr.str(), "",
00597             GetJobID(),
00598             m_medium_p->GetBarcode());
00599     }
00600 
00601     InvalidateEOD();
00602 
00603     if (m_files.size() == 0) {
00604         if (a_relativeFM > 0) {
00605             log_MARKLINE_m;
00606             throw ivd_Error(ie_MEDIUM_BLANK);
00607         }
00608         else {
00609             m_curFile = 0;
00610             return;
00611         }
00612     }
00613 
00614     VolFile& cf = m_files[m_curFile];
00615     cf.file.CloseF();
00616 
00617     Int32_t absFile = m_curFile + a_relativeFM;
00618 
00619     if (absFile < 0) {
00620         m_curFile = 0;
00621         return;
00622     }
00623 
00624     // Seeking over the end of medium
00625     if (UInt32_t(absFile) >= m_files.size()) {
00626         m_curFile = m_files.size()-1;
00627         VolFile& tf = m_files[m_curFile];
00628         tf.file.OpenF(fom_READWRITE);
00629         (void)tf.file.SeekEndF();
00630         m_atEOD = true;
00631         throw ivd_Error(ie_MEDIUM_EOD, "Seek over the disk volume boundaries.");
00632     }
00633 
00634     // Positioning to proper file
00635     m_curFile = absFile;
00636     VolFile& tf = m_files[m_curFile];
00637     tf.file.OpenF(fom_READWRITE);
00638 
00639     log_DBG_m(dbg_NORM, "Positioned to file: " << m_curFile);
00640 
00641     // This is the same as the tape: negative seek positions just before
00642     // the file mark.
00643     if (a_relativeFM < 0) {
00644         log_DBG_m(dbg_NORM, "Reverse file mark seek -> positioning to end of file.");
00645         (void)tf.file.SeekEndF();
00646     }
00647 }

Here is the call graph for this function:

void bea_DiskVolume::WriteRaw ( const UInt8_t a_buf,
UInt32_t  a_size 
) [protected, virtual]

Implements bea_Volume.

Definition at line 187 of file bea_diskvolume.cpp.

References CreateNewFile(), Erase(), file, fom_READWRITE, cmn_File::GetCurrentPosF(), ivd_BaseException::GetError(), ivd_BaseException::GetFriendly(), cmn_File::GetFullPathRef(), ie_MEDIUM_MEDERR, ie_MEDIUM_OVERFLOW, cmn_File::IsOpen(), ivd_Error, log_FUNC_m, log_WRN_m, bea_Volume::m_atEOD, m_curFile, m_dvPath, m_files, cmn_File::OpenF(), cmn_File::TruncF(), and cmn_File::WriteF().

00187                                                                    {
00188     log_FUNC_m(WriteRaw);
00189 
00190     if (!m_atEOD) {
00191         Erase();
00192     }
00193 
00194     if (m_files.empty()) {
00195         CreateNewFile();
00196     }
00197 
00198     cmn_File& file = m_files[m_curFile].file;
00199 
00200     if (!file.IsOpen()) {
00201         file.OpenF(fom_READWRITE);
00202     }
00203 
00204     try {
00205         //
00206         // Atomic append to the file.
00207         // TODO: Shall this functionality be moved to cmn_File?
00208         //
00209         ivd_FileRetSize_t wrote = file.WriteF(a_buf, a_size);
00210 
00211         if (static_cast<UInt32_t>(wrote) < a_size) {
00212             log_WRN_m(
00213                 "Writing failed. Truncating file to last full block: " <<
00214                 file.GetFullPathRef() );
00215 
00216             ivd_FilePosition_t filePos = file.GetCurrentPosF();
00217             file.TruncF(filePos - wrote);
00218 
00219             ostringstream sstr;
00220             sstr << "Disk medium out of space: " << m_dvPath;
00221             throw ivd_Error(ie_MEDIUM_OVERFLOW, sstr.str(), true);
00222         }
00223     }
00224     catch (const ivd_SysError& se) {
00225         if (se.GetError() == ENOSPC) {
00226             ostringstream sstr;
00227             sstr << "Disk medium out of space: " << m_dvPath;
00228             throw ivd_Error(ie_MEDIUM_OVERFLOW, sstr.str(), true);
00229         }
00230         else {
00231             ostringstream sstr;
00232             sstr << "Disk medium error: " << m_dvPath;
00233             throw ivd_Error(ie_MEDIUM_MEDERR, sstr.str(), se.GetFriendly());
00234         }
00235     };
00236 
00237     m_files[m_curFile].size += a_size;
00238 }

Here is the call graph for this function:

void bea_DiskVolume::ReadRaw ( UInt8_t a_buf,
UInt32_t  a_size 
) [protected, virtual]

Implements bea_Volume.

Definition at line 242 of file bea_diskvolume.cpp.

References cmn_File::CloseF(), dbg_NORM, df_VOLHDR_REC_SIZE, ExtendToFullBlock(), file, fom_READWRITE, bea_Volume::GetBlockSize(), cmn_File::GetCurrentPosF(), ivd_BaseException::GetFriendly(), GetPosition(), ie_DATA_CORRUPTION, ie_MEDIUM_BLANK, ie_MEDIUM_EOD, ie_MEDIUM_FILEMARK, ie_MEDIUM_ILENGTH, ie_MEDIUM_MEDERR, cmn_File::IsOpen(), ivd_Error, log_DBG_m, log_FUNC_m, log_WRN_m, m_curFile, m_dvPath, m_files, cmn_File::OpenF(), and cmn_File::ReadF().

00242                                                             {
00243     log_FUNC_m(ReadRaw);
00244 
00245     if ( m_files.size() == 0 ||
00246         (m_files.size() == 1 && m_files[0].size == 0) ) {
00247         throw ivd_Error(ie_MEDIUM_BLANK);
00248     }
00249 
00250     if (m_files.size() <= m_curFile) {
00251         throw ivd_InternalError(ie_DATA_CORRUPTION, "m_curFile >= #files");
00252     }
00253 
00254     cmn_File& file = m_files[m_curFile].file;
00255 
00256     if (!file.IsOpen()) {
00257         file.OpenF(fom_READWRITE);
00258     }
00259 
00260     UInt32_t toRead(a_size);
00261     if (GetPosition() == 0) {
00262         toRead = df_VOLHDR_REC_SIZE;
00263     }
00264 
00265     UInt32_t readAmount(0);
00266     try {
00267         readAmount = file.ReadF(a_buf, toRead);
00268     }
00269     catch (const ivd_SysError& se) {
00270         ostringstream sstr;
00271         sstr << "Disk medium error: " << m_dvPath;
00272         throw ivd_Error(ie_MEDIUM_MEDERR, sstr.str(), se.GetFriendly());
00273     };
00274 
00275     if (readAmount == 0) {
00276         if (m_curFile == (m_files.size()-1) ) {
00277             throw ivd_Error(ie_MEDIUM_EOD, "End of disk volume reached.");
00278         }
00279         else {
00280             log_DBG_m(dbg_NORM, "File mark reached. Skip over to next file.");
00281             file.CloseF();
00282             ++m_curFile;
00283             throw ivd_Error(ie_MEDIUM_FILEMARK, "Disk medium filemark reached.");
00284         }
00285     }
00286 
00287     if (readAmount < toRead) {
00288         if ( (m_curFile + 1) == m_files.size() && m_curFile > 0) {
00289             ivd_FilePosition_t pos = file.GetCurrentPosF();
00290             bea_DiskVolume::ExtendToFullBlock(file, pos, GetBlockSize());
00291         }
00292         else {
00293             log_WRN_m(
00294                 "Read less that requested on non-last file.");
00295         }
00296 
00297         ostringstream sstr;
00298         sstr
00299             << "Read less (" << readAmount
00300             << ") than block size (" << toRead << ").";
00301 
00302         throw ivd_Error(ie_MEDIUM_ILENGTH, "File too short.", sstr.str());
00303     }
00304 
00305     if (toRead < a_size) {
00306         ostringstream sstr;
00307         sstr << "Attempt to read more (" << a_size
00308             << ") than block size (" << toRead << ").";
00309         throw ivd_Error(ie_MEDIUM_ILENGTH, sstr.str());
00310     }
00311 }

Here is the call graph for this function:

void bea_DiskVolume::ReadEstimSizes (  )  [protected, virtual]

Reads estimated overall and remaining capacity of this medium volume.

It stores the values so that they can be retrieved by Get* methods. This method converts sizes to MB.

Implements bea_Volume.

Definition at line 657 of file bea_diskvolume.cpp.

References ivd_FileSystemSize_t::bytesFree, ivd_FileSystemSize_t::bytesTotal, cfg_MEGABYTE, dbg_DETAIL, dbg_LOW, dbg_NORM, bea_Medium::GetCurVolNumber(), cmn_File::GetFileSystemSize(), bea_Volume::GetSize(), bea_Volume::GetVolumeNumber(), ie_INVALID_ARG, ivd_Error, log_DBG_m, log_FUNC_m, log_WRN_m, m_dvPath, m_files, bea_Volume::m_medium_p, and bea_Volume::SetEstimatedSizes().

00657                                     {
00658     log_FUNC_m(ReadEstimSizes);
00659 
00660     if (m_medium_p->GetCurVolNumber() != GetVolumeNumber()) {
00661         throw ivd_Error(
00662             ie_INVALID_ARG,
00663             "Estimated sizes can only be read for current volume.");
00664     };
00665 
00666     UInt32_t estimSize(GetSize());
00667     UInt64_t sumOfFiles(0);
00668     UInt32_t estimFree(0);
00669     for (UInt32_t i(0); i < m_files.size(); i++) {
00670         // Re-read file allocated sizes.
00671         ivd_FileInfo_t info;
00672         m_files[i].file.StatF(info);
00673 
00674         sumOfFiles += info.allocated;
00675     }
00676     sumOfFiles /= cfg_MEGABYTE;
00677     log_DBG_m(dbg_DETAIL, "sumOfFiles:" << sumOfFiles);
00678 
00679     if (sumOfFiles <= estimSize) {
00680         estimFree = estimSize - sumOfFiles;
00681         log_DBG_m(dbg_DETAIL, "estimFree:" << estimFree);
00682     }
00683     else {
00684         log_WRN_m("Sum of file size bigger that actual space.");
00685         estimFree = 0;
00686     };
00687 
00688     {
00689         cmn_File info(m_dvPath);
00690         ivd_FileSystemSize_t fsSize;
00691         info.GetFileSystemSize(fsSize);
00692 
00693         log_DBG_m(dbg_NORM, "fsSize.bytesTotal:" << fsSize.bytesTotal <<
00694                             ", fsSize.bytesFree:" << fsSize.bytesFree);
00695 
00696         if ( (fsSize.bytesTotal/cfg_MEGABYTE) < estimSize) {
00697             estimSize = fsSize.bytesTotal/cfg_MEGABYTE;
00698             log_DBG_m(dbg_LOW,
00699                 "File system size is smaller than declared size. Using " <<
00700                 estimSize);
00701         }
00702 
00703         if ( (fsSize.bytesFree/cfg_MEGABYTE) < estimFree) {
00704             estimFree = fsSize.bytesFree/cfg_MEGABYTE;
00705             log_DBG_m(dbg_LOW,
00706                 "File system free space is smaller than declared size. Using " <<
00707                 estimFree);
00708         }
00709     };
00710 
00711     log_DBG_m(dbg_NORM,
00712         "Estimated capacity info [MB]:" <<
00713         " total: " << estimSize << " free : " << estimFree);
00714 
00715     SetEstimatedSizes(estimSize, estimFree);
00716 }

Here is the call graph for this function:

void bea_DiskVolume::ReparseFiles (  )  [private]

Definition at line 720 of file bea_diskvolume.cpp.

References val_Integer::Bind(), val_Value::Conv(), dbg_DETAIL, dbg_LOW, dbg_NORM, dv_FRIFile, dv_HeaderFile, dv_VOLINFO, cmn_DirLst::GetNextName(), GetTypeFromExt(), ie_MEDIUM_MEDERR, ift_FILE, ivd_Error, log_DBG_m, log_FUNC_m, log_MARKLINE_m, m_dvPath, m_files, stat(), and cmn_File::StatF().

Referenced by bea_DiskVolume().

00720                                   {
00721     log_FUNC_m(ReparseFiles);
00722     // Scan for <offset>.[hdr|dta|fri] files
00723 
00724     list<string> volFNames;
00725     {
00726         cmn_DirLst volFiles(m_dvPath, "");
00727         string name;
00728         name = volFiles.GetNextName();
00729         while ( name.size() > 0 ) {
00730             cmn_Path fullName(m_dvPath + name);
00731             ivd_FileType_e type;
00732             {
00733                 cmn_File entry(fullName);
00734                 ivd_FileInfo_t stat;
00735                 entry.StatF(stat);
00736                 type = stat.type;
00737             }
00738             
00739             string firstChar = name.substr(0, 1); //bug 8417 ignore all hidden files (e.g. sh_history)
00740                         
00741             if ( (name.compare(".") == 0) ||
00742                 (name.compare("..") == 0) ||
00743                 (firstChar.compare(".") == 0) ||
00744                 (name.compare(dv_VOLINFO) == 0) ) {
00745 
00746                 log_DBG_m(dbg_DETAIL, "Skipped file.");
00747             }
00748             else {
00749                 if (type != ift_FILE) {
00750                     log_MARKLINE_m;
00751                     ostringstream sstr;
00752                     sstr << m_dvPath << ": Found non-file entry \'" << name << "\'";
00753                     log_DBG_m(dbg_LOW, "Entry type: " << type);
00754 
00755                     throw ivd_Error(ie_MEDIUM_MEDERR, sstr.str());
00756                 };
00757                 volFNames.push_back(name);
00758             }
00759             name = volFiles.GetNextName();
00760         }
00761         volFNames.sort();
00762     }
00763 
00764     list<string>::const_iterator name_i;
00765     UInt32_t idx(0);
00766     for (name_i = volFNames.begin(); name_i != volFNames.end(); ++name_i) {
00767         const string& fn(*name_i);
00768         string::size_type dotPos = fn.find_first_of('.');
00769         if (dotPos == string::npos || dotPos == 0) {
00770             log_MARKLINE_m;
00771             throw ivd_Error(ie_MEDIUM_MEDERR,
00772                 string("Invalid disk volume name: ") + fn);
00773         }
00774 
00775         string offsetStr(fn.substr(0, dotPos));
00776         string extStr(fn.substr(dotPos));
00777 
00778         VolFile volFile;
00779         val_Integer iv("Offset", val_Limit(0, UINT_MAX));
00780         iv.Bind(volFile.blkOffset);
00781         iv.Conv(offsetStr);
00782 
00783         volFile.type = GetTypeFromExt(extStr);
00784         volFile.file.SetFullPath(m_dvPath + fn);
00785 
00786         if (idx == 0) {
00787             if (volFile.type != dv_HeaderFile) {
00788                 throw ivd_Error(ie_MEDIUM_MEDERR,
00789                     "Header file not on the first place.");
00790             }
00791             else if (volFile.blkOffset != 0) {
00792                 throw ivd_Error(ie_MEDIUM_MEDERR,
00793                     "Block offset for header larger that 0.");
00794             }
00795         }
00796         else if (idx < (volFNames.size()-1)) {
00797             if (volFile.type == dv_FRIFile) {
00798                 throw ivd_Error(ie_MEDIUM_MEDERR,
00799                     "FRI file not on the last place.");
00800             }
00801         }
00802 
00803         ivd_FileInfo_t info;
00804         volFile.file.StatF(info);
00805         volFile.size = info.size;
00806 
00807         m_files.push_back(volFile);
00808 
00809         log_DBG_m(dbg_NORM, "Found valid file: " << fn);
00810 
00811         ++idx;
00812     }
00813 
00814 }

Here is the call graph for this function:

Here is the caller graph for this function:

bea_DiskVolume::dv_FileType_e bea_DiskVolume::GetTypeFromExt ( const string &  a_extStr  )  [private]

Definition at line 839 of file bea_diskvolume.cpp.

References dv_DATA_EXT, dv_DataFile, dv_FRI_EXT, dv_FRIFile, dv_HEADER_EXT, dv_HeaderFile, ie_MEDIUM_MEDERR, and ivd_Error.

Referenced by ReparseFiles().

00839                                                                                  {
00840 
00841     if (a_extStr.compare(dv_HEADER_EXT) == 0) {
00842         return dv_HeaderFile;
00843     }
00844     else if (a_extStr.compare(dv_DATA_EXT) == 0) {
00845         return dv_DataFile;
00846     }
00847     else if (a_extStr.compare(dv_FRI_EXT) == 0) {
00848         return dv_FRIFile;
00849     }
00850     else {
00851         throw ivd_Error(ie_MEDIUM_MEDERR, string("Wrong extension: ") + a_extStr);
00852     };
00853 }

Here is the caller graph for this function:

string bea_DiskVolume::CreateOffsetFileName ( UInt32_t  a_offset,
dv_FileType_e  a_type 
) [static, private]

Definition at line 819 of file bea_diskvolume.cpp.

References dv_DATA_EXT, dv_DataFile, dv_FRI_EXT, dv_FRIFile, dv_HEADER_EXT, and dv_HeaderFile.

Referenced by CreateNewFile().

00819                                                                                    {
00820 
00821     ostringstream ostr;
00822     ostr
00823         << std::setw(8)
00824         << std::setfill('0')
00825         << a_offset;
00826 
00827     switch (a_type) {
00828         case dv_HeaderFile: ostr << dv_HEADER_EXT; break;
00829         case dv_DataFile: ostr << dv_DATA_EXT; break;
00830         case dv_FRIFile: ostr << dv_FRI_EXT; break;
00831     };
00832 
00833     return ostr.str();
00834 
00835 }

Here is the caller graph for this function:

void bea_DiskVolume::CreateNewFile (  )  [private]

Definition at line 857 of file bea_diskvolume.cpp.

References bea_DiskVolume::VolFile::blkOffset, cmn_File::CloseF(), CreateOffsetFileName(), dbg_LOW, dbg_NORM, dv_DataFile, dv_FRIFile, dv_HeaderFile, file, bea_DiskVolume::VolFile::file, fom_CREATE_NEW, bea_Volume::GetBlockSize(), cmn_File::GetFullPathRef(), ie_DATA_CORRUPTION, log_DBG_m, log_FUNC_m, m_curFile, m_dvPath, m_files, cmn_File::OpenF(), S_IREAD, S_IWRITE, cmn_File::SetFullPath(), bea_DiskVolume::VolFile::size, and bea_DiskVolume::VolFile::type.

Referenced by WriteFileMarks(), and WriteRaw().

00857                                    {
00858     log_FUNC_m(CreateNewFile);
00859 
00860     cmn_Path filePath( m_dvPath );
00861 
00862     VolFile vol;
00863     UInt32_t blkOffset(0);
00864     if (m_files.size() == 0) {
00865         //make .hdr file.
00866         filePath += CreateOffsetFileName(0, dv_HeaderFile);
00867         vol.type = dv_HeaderFile;
00868     }
00869     else {
00870         UInt32_t absOffset(0);
00871         UInt32_t relOffset(0);
00872         if (m_files.size() == 1) {
00873             //make .vdf
00874             vol.type = dv_DataFile;
00875             relOffset = 2;
00876         }
00877         else if (m_files.size() == 2) {
00878             //make .fri
00879             vol.type = dv_FRIFile;
00880 
00881             VolFile& f = m_files[m_files.size() - 1];
00882             absOffset = f.blkOffset;
00883             relOffset = f.size/GetBlockSize();
00884         }
00885         else {
00886             ostringstream sstr;
00887             sstr
00888                 << "All files of the volume " << m_dvPath
00889                 << " already exist.";
00890             throw ivd_InternalError(ie_DATA_CORRUPTION, sstr.str());
00891         }
00892 
00893         log_DBG_m(dbg_NORM,
00894             "Offset of file: " << absOffset << " Offset in file: " << relOffset);
00895 
00896         // Simulate tape: each file mark uses one SCSI block
00897         blkOffset = absOffset + relOffset + 1;
00898         filePath += CreateOffsetFileName(blkOffset, vol.type);
00899     }
00900 
00901     log_DBG_m(dbg_LOW, "Creating new file:" << filePath);
00902 
00903     vol.file.SetFullPath(filePath);
00904     vol.file.OpenF(fom_CREATE_NEW);
00905     vol.file.CloseF();
00906 
00907     // Change permissions to allow access only for the owner
00908 #if TGT_OS_windows
00909     (void)chmod(filePath.c_str(), S_IREAD|S_IWRITE);
00910 #elif TGT_OS_linux
00911     (void)chmod(filePath.c_str(), S_IRUSR | S_IWUSR);
00912 #endif
00913 
00914     vol.size = 0;
00915     vol.blkOffset = blkOffset;
00916 
00917     log_DBG_m(dbg_NORM, "vol.file.PATH:" << vol.file.GetFullPathRef() <<
00918                         " vol.size:" << vol.size <<
00919                         " vol.blkOffset:" << vol.blkOffset);
00920 
00921     if (m_files.size() > 0) {
00922         cmn_File& file = m_files[m_curFile].file;
00923         file.CloseF();
00924     }
00925 
00926     m_files.push_back(vol);
00927     m_curFile = m_files.size() - 1;
00928 }

Here is the call graph for this function:

Here is the caller graph for this function:

void bea_DiskVolume::ExtendToFullBlock ( cmn_File a_file,
ivd_FilePosition_t  a_filePos,
UInt32_t  a_blkSize 
) [private]

Definition at line 930 of file bea_diskvolume.cpp.

References ivd_BaseException::GetFriendly(), ie_MEDIUM_MEDERR, ivd_Error, log_FUNC_m, log_WRN_m, m_dvPath, and cmn_File::TruncF().

Referenced by ReadRaw(), and SeekEOD().

00933                                    {
00934 
00935     log_FUNC_m(ExtendToFullBlock);
00936 
00937     Int32_t remainder = a_filePos % a_blkSize;
00938     if (remainder != 0) {
00939         ivd_FilePosition_t extSize = a_filePos + a_blkSize - remainder;
00940         log_WRN_m(
00941                 "Disk medium error (size mismatch): " << m_dvPath <<
00942                 " Autocorrecting: Extending file to next block: " << extSize);
00943         try {
00944             a_file.TruncF(extSize);
00945         }
00946         catch (const ivd_SysError& se) {
00947             ostringstream sstr;
00948             sstr << "Disk medium error (extending failed): " << m_dvPath;
00949             throw ivd_Error(ie_MEDIUM_MEDERR, sstr.str(), se.GetFriendly() );
00950         }
00951     }
00952 }

Here is the call graph for this function:

Here is the caller graph for this function:

void bea_DiskVolume::ReadVolInfo (  )  [private]

Definition at line 83 of file bea_diskvolume.cpp.

References cmn_File::CloseF(), dbg_LOW, dbg_NORM, fom_READ, ivd_BaseException::GetError(), ivd_BaseException::GetFriendly(), cmn_File::GetFullPathRef(), bea_Volume::GetSize(), ie_MEDIUM_MEDERR, ivd_Error, log_DBG_m, log_FUNC_m, m_dvinfo, cmn_File::OpenF(), cmn_File::ReadF(), bea_Volume::SetDeclaredSize(), dv_Info_t::size, and WriteVolInfo().

Referenced by bea_DiskVolume().

00083                                  {
00084     log_FUNC_m(ReadVolInfo);
00085 
00086     dv_Info_t info;
00087 
00088     try {
00089         m_dvinfo.OpenF(fom_READ);
00090         m_dvinfo.ReadF(&info, sizeof(info));
00091         m_dvinfo.CloseF();
00092 
00093         log_DBG_m(dbg_LOW, "Disk volume size: " << info.size);
00094         SetDeclaredSize(info.size);
00095     }
00096     catch (const ivd_Error& ie) {
00097         log_DBG_m(dbg_LOW, "Can't read volume info: " << ie.GetFriendly() );
00098         throw ivd_Error(ie_MEDIUM_MEDERR,
00099             string("Can't read volume info: ") + m_dvinfo.GetFullPathRef(),
00100             ie.GetFriendly(),
00101             true);
00102     }
00103     catch (const ivd_SysError& ie) {
00104         if (ie.GetError() == ENOENT) {
00105             if (GetSize() > 0) {
00106                 log_DBG_m(dbg_NORM, "vol.info doesn't exist. Creating new.");
00107                 WriteVolInfo();
00108             }
00109             else {
00110                 log_DBG_m(dbg_LOW,
00111                     "Volume info doesn't exist, but no new size specified: " <<
00112                     ie.GetFriendly() );
00113                 throw ivd_Error(ie_MEDIUM_MEDERR,
00114                     string("Can't read volume info: ") + m_dvinfo.GetFullPathRef(),
00115                     ie.GetFriendly(),
00116                     true);
00117             }
00118         }
00119         else {
00120             log_DBG_m(dbg_LOW, "Can't read volume info: " << ie.GetFriendly() );
00121             throw ivd_Error(ie_MEDIUM_MEDERR,
00122                 string("Can't read volume info: ") + m_dvinfo.GetFullPathRef(),
00123                 ie.GetFriendly(),
00124                 true);
00125         };
00126     }
00127 }

Here is the call graph for this function:

Here is the caller graph for this function:

void bea_DiskVolume::WriteVolInfo (  )  [private]

Definition at line 131 of file bea_diskvolume.cpp.

References cmn_File::CloseF(), dbg_LOW, fom_CREATE_ALWAYS, fom_WRITE, ivd_BaseException::GetFriendly(), cmn_File::GetFullPathRef(), bea_Volume::GetSize(), ie_MEDIUM_MEDERR, ivd_Error, log_DBG_m, log_FUNC_m, m_dvinfo, cmn_File::OpenF(), dv_Info_t::size, and cmn_File::WriteF().

Referenced by ReadVolInfo().

00131                                   {
00132     log_FUNC_m(WriteVolInfo);
00133 
00134     dv_Info_t info;
00135 
00136     info.size = GetSize();
00137 
00138     try {
00139         m_dvinfo.OpenF(fom_WRITE | fom_CREATE_ALWAYS);
00140         m_dvinfo.WriteF(&info, sizeof(info));
00141         m_dvinfo.CloseF();
00142     }
00143     catch (const ivd_Exception& ie) {
00144         log_DBG_m(dbg_LOW, "Can't write volume info: " << ie.GetFriendly() );
00145         throw ivd_Error(ie_MEDIUM_MEDERR,
00146             string("Can't write volume info: ") + m_dvinfo.GetFullPathRef(),
00147             ie.GetFriendly(),
00148             true);
00149     }
00150 
00151 }

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Reimplemented from bea_Volume.

Definition at line 91 of file bea_diskvolume.h.

Definition at line 93 of file bea_diskvolume.h.

Referenced by ReadVolInfo(), and WriteVolInfo().

vector<VolFile> bea_DiskVolume::m_files [private]


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

Generated on Mon Feb 27 18:58:16 2012 for OPENARCHIVE by  doxygen 1.5.6