Commit f75c5f5b authored by Eric Cano's avatar Eric Cano
Browse files

Added retrieve jobs queueing to the getMountInfo unit test for the scheduler db.

Reworked the queueing of retrieve jobs in the OStoreDB.
Improved some variable names.
parent 4e5012a5
......@@ -46,7 +46,7 @@ struct TapeCopyInfo {
/**
* The path of the archive file.
*/
std::string filePath;
std::string archiveFilePath;
/**
* The ID of the file
......@@ -72,6 +72,11 @@ struct TapeCopyInfo {
* The hostname of the nameserver holding the file
*/
std::string nsHostName;
/**
* The copy number for this tape copy
*/
uint16_t copyNumber;
}; // struct TapeCopyLocation
......
......@@ -64,7 +64,7 @@ std::string cta::objectstore::RetrieveToFileRequest::getArchiveFile() {
void cta::objectstore::RetrieveToFileRequest::setRemoteFile(
const std::string& remoteFile) {
checkHeaderReadable();
checkPayloadWritable();
m_payload.set_remotefile(remoteFile);
}
......@@ -80,7 +80,7 @@ void cta::objectstore::RetrieveToFileRequest::setPriority(uint64_t priority) {
void cta::objectstore::RetrieveToFileRequest::setCreationLog(
const objectstore::CreationLog& creationLog) {
checkPayloadReadable();
checkPayloadWritable();
creationLog.serialize(*m_payload.mutable_log());
}
......
......@@ -43,6 +43,7 @@
#include <algorithm>
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
#include <stdexcept>
namespace cta {
......@@ -925,6 +926,7 @@ std::list<ArchiveToTapeCopyRequest>
void OStoreDB::queue(const cta::RetrieveToFileRequest& rqst) {
assertAgentSet();
// Check at least one potential tape copy is provided.
// In order to post the job, construct it first.
objectstore::RetrieveToFileRequest rtfr(m_agent->nextId("RetrieveToFileRequest"), m_objectStore);
rtfr.initialize();
......@@ -932,48 +934,80 @@ void OStoreDB::queue(const cta::RetrieveToFileRequest& rqst) {
rtfr.setRemoteFile(rqst.getRemoteFile());
rtfr.setPriority(rqst.priority);
rtfr.setCreationLog(rqst.creationLog);
// We will need to identity tapes is order to construct the request
// We will need to identity tapes is order to construct the request.
// First load all the tapes information in a memory map
std::map<std::string, std::string> vidToAddress;
RootEntry re(m_objectStore);
ScopedSharedLock rel(re);
re.fetch();
auto & tc = rqst.getTapeCopies();
auto numberOfCopies = tc.size();
srand (time(NULL));
auto chosenCopyNumber = rand() % numberOfCopies;
auto it = tc.begin();
std::advance(it, chosenCopyNumber);
auto tapePools = re.dumpTapePools();
std::string tapeAddress = "";
for(auto pool=tapePools.begin(); pool!=tapePools.end(); pool++) {
objectstore::TapePool tp(pool->address, m_objectStore);
objectstore::ScopedSharedLock tpl(tp);
tp.fetch();
auto tapes = tp.dumpTapes();
for(auto tape=tapes.begin(); tape!=tapes.end(); tape++) {
if(tape->vid==it->vid) {
tapeAddress = tape->address;
break;
for(auto tape=tapes.begin(); tape!=tapes.end(); tape++)
vidToAddress[tape->vid] = tape->address;
}
// Now add all the candidate tape copies to the request. With validation
for (auto tc=rqst.getTapeCopies().begin(); tc!=rqst.getTapeCopies().end(); tc++) {
// Check the tape copy copynumber (range = [1 - copyCount] )
if (tc->copyNumber > rqst.getTapeCopies().size() || tc->copyNumber < 1) {
throw TapeCopyNumberOutOfRange("In OStoreDB::queue(RetrieveToFile): copy number out of range");
}
}
// Add all the tape copies to the request
try {
for (auto tc=rqst.getTapeCopies().begin(); tc!=rqst.getTapeCopies().end(); tc++) {
rtfr.addJob(tc->copyNumber, tc->vid, vidToAddress.at(tc->vid));
}
} catch (std::out_of_range &) {
throw NoSuchTape("In OStoreDB::queue(RetrieveToFile): tape not found");
}
// We now need to select the tape from which we will migrate next. This should
// be the tape with the most jobs already queued.
// TODO: this will have to look at tape statuses on the long run as well
uint16_t selectedCopyNumber;
uint64_t bestTapeQueuedBytes;
std::string selectedVid;
{
// First tape copy is always better than nothing.
auto tc=rqst.getTapeCopies().begin();
selectedCopyNumber = tc->copyNumber;
selectedVid = tc->vid;
// Get info for the tape.
{
objectstore::Tape t(vidToAddress.at(tc->vid), m_objectStore);
objectstore::ScopedSharedLock tl(t);
t.fetch();
bestTapeQueuedBytes = t.getJobsSummary().bytes;
}
tc++;
// Compare with the next ones
for (;tc!=rqst.getTapeCopies().end(); tc++) {
objectstore::Tape t(vidToAddress.at(tc->vid), m_objectStore);
objectstore::ScopedSharedLock tl(t);
t.fetch();
if (t.getJobsSummary().bytes > bestTapeQueuedBytes) {
bestTapeQueuedBytes = t.getJobsSummary().bytes;
selectedCopyNumber = tc->copyNumber;
}
}
}
rtfr.addJob(chosenCopyNumber, it->vid, tapeAddress);
auto jl = rtfr.dumpJobs();
if (!jl.size()) {
throw RetrieveRequestHasNoCopies("In OStoreDB::queue: the retrieve to file request has no copies");
}
// We successfully prepared the object. Time to create it and plug it to
// the tree.
rtfr.setOwner(m_agent->getAddressIfSet());
rtfr.insert();
ScopedExclusiveLock rtfrl(rtfr);
// We can now plug the request onto its tape
for (auto j=jl.begin(); j!=jl.end(); j++) {
objectstore::Tape tp(j->tapeAddress, m_objectStore);
// We now can enqueue the request on this most promising tape.
{
objectstore::Tape tp(vidToAddress.at(selectedVid), m_objectStore);
ScopedExclusiveLock tpl(tp);
tp.fetch();
tp.addJob(*j, rtfr.getAddressIfSet(), rtfr.getSize(), rqst.priority, time(NULL));
objectstore::RetrieveToFileRequest::JobDump jd;
jd.copyNb = selectedCopyNumber;
jd.tape = selectedVid;
jd.tapeAddress = vidToAddress.at(selectedVid);
tp.addJob(jd, rtfr.getAddressIfSet(), rqst.getSize(), rqst.priority, rqst.creationLog.time);
tp.commit();
}
// The request is now fully set. As it's multi-owned, we do not set the owner
rtfr.setOwner("");
// The request is now fully set. It belongs to the tape.
rtfr.setOwner(vidToAddress.at(selectedVid));
rtfr.commit();
// And remove reference from the agent
{
......
......@@ -190,6 +190,7 @@ public:
/* === Retrieve requests handling ======================================== */
CTA_GENERATE_EXCEPTION_CLASS(RetrieveRequestHasNoCopies);
CTA_GENERATE_EXCEPTION_CLASS(TapeCopyNumberOutOfRange);
virtual void queue(const RetrieveToFileRequest& rqst_);
virtual void queue(const RetrieveToDirRequest& rqst);
......
......@@ -36,7 +36,7 @@ cta::RetrieveJob::RetrieveJob(
const uint32_t copyNb,
const std::string &remoteFile,
const uint64_t castorNsFileId):
tapeCopyLocation(tapeCopyLocation), m_id(id) {
tapeCopyInfo(tapeCopyLocation), m_id(id) {
}
//------------------------------------------------------------------------------
......
......@@ -112,7 +112,7 @@ public:
/** Translation of positioningMethod */
std::string toString (PositioningMethod);
TapeCopyInfo tapeCopyLocation; /**<The location of the source tape file. */
TapeCopyInfo tapeCopyInfo; /**<The location of the source tape file. */
PositioningMethod positioningMethod; /**< The desired positioning method. */
RemotePath remoteFilePath; /** <The location of the destination file. */
std::string m_id;
......
......@@ -36,14 +36,16 @@ cta::RetrieveToFileRequest::~RetrieveToFileRequest() throw() {
//------------------------------------------------------------------------------
cta::RetrieveToFileRequest::RetrieveToFileRequest(
const std::string &archiveFile,
const uint64_t size,
const std::list<cta::TapeCopyInfo> &tapeCopies,
const std::string &remoteFile,
const uint64_t priority,
const CreationLog & creationLog):
RetrieveRequest(priority, creationLog),
m_archiveFile(archiveFile),
m_size(size),
m_tapeCopies(tapeCopies),
m_remoteFile(remoteFile) {
m_remoteFile(remoteFile){
}
//------------------------------------------------------------------------------
......@@ -53,6 +55,13 @@ const std::string &cta::RetrieveToFileRequest::getArchiveFile() const throw() {
return m_archiveFile;
}
//------------------------------------------------------------------------------
// getSize
//------------------------------------------------------------------------------
uint64_t cta::RetrieveToFileRequest::getSize() const throw() {
return m_size;
}
//------------------------------------------------------------------------------
// getTapeCopies
//------------------------------------------------------------------------------
......
......@@ -58,6 +58,7 @@ public:
*/
RetrieveToFileRequest(
const std::string &archiveFile,
const uint64_t size,
const std::list<TapeCopyInfo> &tapeCopies,
const std::string &remoteFile,
const uint64_t priority,
......@@ -70,6 +71,13 @@ public:
*/
const std::string &getArchiveFile() const throw();
/**
* Returns the size of the source archive file.
*
* @return The size of the source archive file.
*/
uint64_t getSize() const throw();
/**
* Returns the physical location(s) of the archive file on tape.
*
......@@ -91,6 +99,10 @@ private:
*/
std::string m_archiveFile;
/**
* The file size
*/
uint64_t m_size;
/**
* The physical location(s) of the archive file on tape.
*/
......
......@@ -21,6 +21,7 @@
#include "common/admin/AdminUser.hpp"
#include "common/archiveRoutes/ArchiveRoute.hpp"
#include "scheduler/ArchiveToFileRequest.hpp"
#include "scheduler/RetrieveToFileRequest.hpp"
#include "scheduler/mockDB/MockSchedulerDatabase.hpp"
#include "scheduler/mockDB/MockSchedulerDatabaseFactory.hpp"
#include "scheduler/SchedulerDatabase.hpp"
......@@ -445,7 +446,7 @@ TEST_P(SchedulerDatabaseTest, getMountInfo) {
ASSERT_EQ(1, tmdi.potentialMounts.front().filesQueued);
ASSERT_EQ(cl.time, tmdi.potentialMounts.front().oldestJobStartTime);
}
// Add one more job to the queue: the summary should not change
// Add one more job to the queue: the summary should change accordingly
std::unique_ptr<cta::SchedulerDatabase::ArchiveToFileRequestCreation> creation2(db.queue(atfr));
creation2->complete();
ASSERT_NO_THROW(mountCandidates = db.getMountInfo());
......@@ -458,7 +459,51 @@ TEST_P(SchedulerDatabaseTest, getMountInfo) {
ASSERT_EQ(2, tmdi.potentialMounts.front().filesQueued);
ASSERT_EQ(cl.time, tmdi.potentialMounts.front().oldestJobStartTime);
}
// Add 2 tapes
ASSERT_THROW(db.createTape("Tape2", "Lib2", "pool2", 10L*1000*1000*1000*1000*1000, cl),
cta::exception::Exception);
db.createLogicalLibrary("Lib2", cl);
ASSERT_THROW(db.createTape("Tape2", "Lib2", "pool2", 10L*1000*1000*1000*1000*1000, cl),
cta::exception::Exception);
db.createTapePool("pool2", 5, cl);
ASSERT_NO_THROW(db.createTape("Tape2", "Lib2", "pool2", 10L*1000*1000*1000*1000*1000, cl));
db.createLogicalLibrary("Lib3", cl);
db.createTapePool("pool3", 5, cl);
ASSERT_NO_THROW(db.createTape("Tape3", "Lib3", "pool3", 10L*1000*1000*1000*1000*1000, cl));
// Add retrieve jobs
std::list<TapeCopyInfo> tcl;
tcl.push_back(TapeCopyInfo());
tcl.back().blockId = 666;
tcl.back().fileId = 777;
tcl.back().archiveFilePath = "cta:://cta/myfile";
tcl.back().fseq = 10;
tcl.back().nsHostName = "NSHost";
tcl.back().vid = "Tape2";
tcl.push_back(TapeCopyInfo());
tcl.back().blockId = 111;
tcl.back().fileId = 777;
tcl.back().archiveFilePath = "cta:://cta/myfile";
tcl.back().fseq = 5;
tcl.back().nsHostName = "NSHost";
tcl.back().vid = "Tape3";
ASSERT_NO_THROW(db.queue(cta::RetrieveToFileRequest("cta:://cta/myfile", 1234, tcl, "eos://myeos/myeosfile", 10, cl)));
// Add retrieve jobs
std::list<TapeCopyInfo> tcl2;
tcl.push_back(TapeCopyInfo());
tcl.back().blockId = 999;
tcl.back().fileId = 888;
tcl.back().archiveFilePath = "cta:://cta/myfile2";
tcl.back().fseq = 11;
tcl.back().nsHostName = "NSHost";
tcl.back().vid = "Tape2";
tcl.push_back(TapeCopyInfo());
tcl.back().blockId = 333;
tcl.back().fileId = 888;
tcl.back().archiveFilePath = "cta:://cta/myfile2";
tcl.back().fseq = 3;
tcl.back().nsHostName = "NSHost";
tcl.back().vid = "Tape3";
db.queue(cta::RetrieveToFileRequest("cta:://cta/myfile2", 1234, tcl2, "eos://myeos/myeosfile2", 10, cl));
}
#undef TEST_MOCK_DB
......
......@@ -52,10 +52,10 @@ bool DiskWriteTask::execute(RecallReportPacker& reporter,log::LogContext& lc,
castor::utils::Timer totalTime(localTime);
castor::utils::Timer transferTime(localTime);
log::ScopedParamContainer URLcontext(lc);
URLcontext.add("NSFILEID",m_retrieveJob->tapeCopyLocation.fileId)
.add("path", m_retrieveJob->tapeCopyLocation.filePath)
URLcontext.add("NSFILEID",m_retrieveJob->tapeCopyInfo.fileId)
.add("path", m_retrieveJob->tapeCopyInfo.archiveFilePath)
.add("fileTransactionId",m_retrieveJob->m_id)
.add("fSeq",m_retrieveJob->tapeCopyLocation.fseq);
.add("fSeq",m_retrieveJob->tapeCopyInfo.fseq);
// This out-of-try-catch variables allows us to record the stage of the
// process we're in, and to count the error if it occurs.
// We will not record errors for an empty string. This will allow us to
......@@ -90,7 +90,7 @@ bool DiskWriteTask::execute(RecallReportPacker& reporter,log::LogContext& lc,
// Synchronise the counter with the open time counter.
currentErrorToCount = "Error_diskOpenForWrite";
transferTime = localTime;
writeFile.reset(fileFactory.createWriteFile(m_retrieveJob->tapeCopyLocation.filePath));
writeFile.reset(fileFactory.createWriteFile(m_retrieveJob->tapeCopyInfo.archiveFilePath));
URLcontext.add("actualURL", writeFile->URL());
lc.log(LOG_INFO, "Opened disk file for writing");
m_stats.openingTime+=localTime.secs(castor::utils::Timer::resetCounter);
......@@ -200,7 +200,7 @@ void DiskWriteTask::releaseAllBlock(){
//------------------------------------------------------------------------------
void DiskWriteTask::checkErrors(MemBlock* mb,int blockId,castor::log::LogContext& lc){
using namespace castor::log;
if(m_retrieveJob->tapeCopyLocation.fileId != static_cast<unsigned int>(mb->m_fileid)
if(m_retrieveJob->tapeCopyInfo.fileId != static_cast<unsigned int>(mb->m_fileid)
|| blockId != mb->m_fileBlock || mb->isFailed() ){
LogContext::ScopedParam sp[]={
LogContext::ScopedParam(lc, Param("received_NSFILEID", mb->m_fileid)),
......@@ -253,8 +253,8 @@ void DiskWriteTask::logWithStat(int level,const std::string& msg,log::LogContext
m_stats.transferTime?1.0*m_stats.dataVolume/1000/1000/m_stats.transferTime:0)
.add("openRWCloseToTransferTimeRatio",
m_stats.transferTime?(m_stats.openingTime+m_stats.readWriteTime+m_stats.closingTime)/m_stats.transferTime:0.0)
.add("FILEID",m_retrieveJob->tapeCopyLocation.fileId)
.add("path",m_retrieveJob->tapeCopyLocation.filePath);
.add("FILEID",m_retrieveJob->tapeCopyInfo.fileId)
.add("path",m_retrieveJob->tapeCopyInfo.archiveFilePath);
lc.log(level,msg);
}
}}}}
......
......@@ -91,11 +91,11 @@ void RecallTaskInjector::injectBulkRecalls(const std::vector<cta::RetrieveJob *>
(*it)->positioningMethod=cta::RetrieveJob::PositioningMethod::ByBlock;
LogContext::ScopedParam sp[]={
LogContext::ScopedParam(m_lc, Param("NSHOSTNAME", (*it)->tapeCopyLocation.nsHostName)),
LogContext::ScopedParam(m_lc, Param("NSFILEID", (*it)->tapeCopyLocation.fileId)),
LogContext::ScopedParam(m_lc, Param("fSeq", (*it)->tapeCopyLocation.fseq)),
LogContext::ScopedParam(m_lc, Param("blockID", (*it)->tapeCopyLocation.blockId)),
LogContext::ScopedParam(m_lc, Param("path", (*it)->tapeCopyLocation.filePath))
LogContext::ScopedParam(m_lc, Param("NSHOSTNAME", (*it)->tapeCopyInfo.nsHostName)),
LogContext::ScopedParam(m_lc, Param("NSFILEID", (*it)->tapeCopyInfo.fileId)),
LogContext::ScopedParam(m_lc, Param("fSeq", (*it)->tapeCopyInfo.fseq)),
LogContext::ScopedParam(m_lc, Param("blockID", (*it)->tapeCopyInfo.blockId)),
LogContext::ScopedParam(m_lc, Param("path", (*it)->tapeCopyInfo.archiveFilePath))
};
tape::utils::suppresUnusedVariable(sp);
......
......@@ -69,12 +69,12 @@ public:
// Set the common context for all the coming logs (file info)
log::ScopedParamContainer params(lc);
params.add("NSHOSTNAME", m_retrieveJob->tapeCopyLocation.nsHostName)
.add("NSFILEID", m_retrieveJob->tapeCopyLocation.fileId)
.add("BlockId", m_retrieveJob->tapeCopyLocation.blockId)
.add("fSeq", m_retrieveJob->tapeCopyLocation.fseq)
params.add("NSHOSTNAME", m_retrieveJob->tapeCopyInfo.nsHostName)
.add("NSFILEID", m_retrieveJob->tapeCopyInfo.fileId)
.add("BlockId", m_retrieveJob->tapeCopyInfo.blockId)
.add("fSeq", m_retrieveJob->tapeCopyInfo.fseq)
.add("fileTransactionId", m_retrieveJob->m_id)
.add("path", m_retrieveJob->tapeCopyLocation.filePath);
.add("path", m_retrieveJob->tapeCopyInfo.archiveFilePath);
// We will clock the stats for the file itself, and eventually add those
// stats to the session's.
......@@ -110,9 +110,9 @@ public:
mb=m_mm.getFreeBlock();
localStats.waitFreeMemoryTime += timer.secs(castor::utils::Timer::resetCounter);
mb->m_fSeq = m_retrieveJob->tapeCopyLocation.fseq;
mb->m_fSeq = m_retrieveJob->tapeCopyInfo.fseq;
mb->m_fileBlock = fileBlock++;
mb->m_fileid = m_retrieveJob->tapeCopyLocation.fileId;
mb->m_fileid = m_retrieveJob->tapeCopyInfo.fileId;
mb->m_tapeFileBlock = tapeBlock;
mb->m_tapeBlockSize = rf->getBlockSize();
try {
......@@ -191,8 +191,8 @@ public:
*/
void reportCancellationToDiskTask(){
MemBlock* mb =m_mm.getFreeBlock();
mb->m_fSeq = m_retrieveJob->tapeCopyLocation.fseq;
mb->m_fileid = m_retrieveJob->tapeCopyLocation.fileId;
mb->m_fSeq = m_retrieveJob->tapeCopyInfo.fseq;
mb->m_fileid = m_retrieveJob->tapeCopyInfo.fileId;
//mark the block cancelled and push it (plus signal the end)
mb->markAsCancelled();
m_fifo.pushDataBlock(mb);
......@@ -208,8 +208,8 @@ private:
// fill it up
if (!mb) {
mb=m_mm.getFreeBlock();
mb->m_fSeq = m_retrieveJob->tapeCopyLocation.fseq;
mb->m_fileid = m_retrieveJob->tapeCopyLocation.fileId;
mb->m_fSeq = m_retrieveJob->tapeCopyInfo.fseq;
mb->m_fileid = m_retrieveJob->tapeCopyInfo.fileId;
}
//mark the block failed and push it (plus signal the end)
mb->markAsFailed(msg,code);
......
......@@ -108,13 +108,13 @@ namespace castor {
const cta::RetrieveJob &filetoRecall,
const tape::tapeserver::daemon::VolumeInfo &volInfo) {
const std::string &volId = volInfo.vid;
if(!checkHeaderNumericalField(hdr1.getFileId(), filetoRecall.tapeCopyLocation.fileId, hexadecimal)) {
if(!checkHeaderNumericalField(hdr1.getFileId(), filetoRecall.tapeCopyInfo.fileId, hexadecimal)) {
// the nsfileid stored in HDR1 as an hexadecimal string . The one in
// filetoRecall is numeric
std::stringstream ex_str;
ex_str << "[HeaderChecker::checkHDR1] - Invalid fileid detected: (0x)\""
<< hdr1.getFileId() << "\". Wanted: 0x" << std::hex
<< filetoRecall.tapeCopyLocation.fileId << std::endl;
<< filetoRecall.tapeCopyInfo.fileId << std::endl;
throw TapeFormatError(ex_str.str());
}
......@@ -129,10 +129,10 @@ namespace castor {
void HeaderChecker::checkUHL1(const UHL1 &uhl1,
const cta::RetrieveJob &fileToRecall) {
if(!checkHeaderNumericalField(uhl1.getfSeq(), fileToRecall.tapeCopyLocation.fseq, decimal)) {
if(!checkHeaderNumericalField(uhl1.getfSeq(), fileToRecall.tapeCopyInfo.fseq, decimal)) {
std::stringstream ex_str;
ex_str << "[HeaderChecker::checkUHL1] - Invalid fseq detected in uhl1: \""
<< uhl1.getfSeq() << "\". Wanted: " << fileToRecall.tapeCopyLocation.fseq;
<< uhl1.getfSeq() << "\". Wanted: " << fileToRecall.tapeCopyInfo.fseq;
throw TapeFormatError(ex_str.str());
}
}
......@@ -174,15 +174,15 @@ namespace castor {
m_session->release();
}
void ReadFile::positionByFseq(const cta::RetrieveJob &fileToRecall) {
if(fileToRecall.tapeCopyLocation.fseq<1) {
if(fileToRecall.tapeCopyInfo.fseq<1) {
std::stringstream err;
err << "Unexpected fileId in ReadFile::position with fSeq expected >=1, got: "
<< fileToRecall.tapeCopyLocation.fseq << ")";
<< fileToRecall.tapeCopyInfo.fseq << ")";
throw castor::exception::InvalidArgument(err.str());
}
int64_t fseq_delta = fileToRecall.tapeCopyLocation.fseq - m_session->getCurrentFseq();
if(fileToRecall.tapeCopyLocation.fseq == 1) {
int64_t fseq_delta = fileToRecall.tapeCopyInfo.fseq - m_session->getCurrentFseq();
if(fileToRecall.tapeCopyInfo.fseq == 1) {
// special case: we can rewind the tape to be faster
//(TODO: in the future we could also think of a threshold above
//which we rewind the tape anyway and then space forward)
......@@ -212,14 +212,14 @@ namespace castor {
}
void ReadFile::positionByBlockID(const cta::RetrieveJob &fileToRecall) {
if(fileToRecall.tapeCopyLocation.blockId > std::numeric_limits<uint32_t>::max()){
if(fileToRecall.tapeCopyInfo.blockId > std::numeric_limits<uint32_t>::max()){
std::stringstream ex_str;
ex_str << "[ReadFile::positionByBlockID] - Block id larger than the supported uint32_t limit: " << fileToRecall.tapeCopyLocation.blockId;
ex_str << "[ReadFile::positionByBlockID] - Block id larger than the supported uint32_t limit: " << fileToRecall.tapeCopyInfo.blockId;
throw castor::exception::Exception(ex_str.str());
}
// if we want the first file on tape (fileInfo.blockId==0) we need to skip the VOL1 header
const uint32_t destination_block = fileToRecall.tapeCopyLocation.blockId ?
fileToRecall.tapeCopyLocation.blockId : 1;
const uint32_t destination_block = fileToRecall.tapeCopyInfo.blockId ?
fileToRecall.tapeCopyInfo.blockId : 1;
/*
we position using the sg locate because it is supposed to do the
right thing possibly in a more optimized way (better than st's
......@@ -263,7 +263,7 @@ namespace castor {
}
//save the current fseq into the read session
m_session->setCurrentFseq(fileToRecall.tapeCopyLocation.fseq);
m_session->setCurrentFseq(fileToRecall.tapeCopyInfo.fseq);
HDR1 hdr1;
HDR2 hdr2;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment