Commit 892d75ba authored by Cedric Caffy's avatar Cedric Caffy
Browse files

[repack] A check on the tape is done before it gets queued for repack

- BROKEN tape cannot be queued for repack
- DISABLED tape cannot be queued for repack if the --disabledtape flag has not been provided by the user
- NOT FULL tape cannot be queued for repack
parent 5499849a
......@@ -316,15 +316,20 @@ void Scheduler::queueLabel(const common::dataStructures::SecurityIdentity &cliId
throw exception::Exception(std::string("Not implemented: ") + __PRETTY_FUNCTION__);
}
void Scheduler::checkTapeFullBeforeRepack(std::string vid){
std::set<std::string> vidToRepack;
vidToRepack.insert(vid);
void Scheduler::checkTapeCanBeRepacked(const std::string & vid, const SchedulerDatabase::QueueRepackRequest & repackRequest){
std::set<std::string> vidToRepack({vid});
try{
auto vidToTapesMap = m_catalogue.getTapesByVid(vidToRepack); //throws an exception if the vid is not found on the database
cta::common::dataStructures::Tape tapeToCheck = vidToTapesMap.at(vid);
if(!tapeToCheck.full){
throw exception::UserError("You must set the tape as full before repacking it.");
}
if(tapeToCheck.state == common::dataStructures::Tape::BROKEN){
throw exception::UserError(std::string("You cannot repack a tape that is ") + common::dataStructures::Tape::stateToString(common::dataStructures::Tape::BROKEN) + ".");
}
if(tapeToCheck.isDisabled() && !repackRequest.m_forceDisabledTape){
throw exception::UserError(std::string("You cannot repack a ") + common::dataStructures::Tape::stateToString(common::dataStructures::Tape::DISABLED)+ " tape. You can force it by using the flag --disabledtape.");
}
} catch(const exception::UserError& userEx){
throw userEx;
} catch(const cta::exception::Exception & ex){
......@@ -344,7 +349,7 @@ void Scheduler::queueRepack(const common::dataStructures::SecurityIdentity &cliI
if (vid.empty()) throw exception::UserError("Empty VID name.");
if (repackBufferURL.empty()) throw exception::UserError("Empty buffer URL.");
utils::Timer t;
checkTapeFullBeforeRepack(vid);
checkTapeCanBeRepacked(vid,repackRequestToQueue);
std::string repackRequestAddress = m_db.queueRepack(repackRequestToQueue, lc);
log::TimingList tl;
tl.insertAndReset("schedulerDbTime", t);
......
......@@ -300,12 +300,13 @@ private:
double & getTapeInfoTime, double & candidateSortingTime, double & getTapeForWriteTime, log::LogContext & lc);
/**
* Checks wether the tape is full before repacking
* Checks wether the tape can be repacked of not.
* A tape can be repacked if it exists, it is full, not BROKEN and not DISABLED unless there the --disabledtape flag has been provided by the user.
* @param vid the vid of the tape to check
* @throws a UserError exception if the vid does not exist or if
* the tape is not full
* @param repackRequest the associated repackRequest to check the tape can be repacked
* @throws a UserError exception if the tape cannot be repacked
*/
void checkTapeFullBeforeRepack(std::string vid);
void checkTapeCanBeRepacked(const std::string & vid, const SchedulerDatabase::QueueRepackRequest & repackRequest);
cta::optional<common::dataStructures::LogicalLibrary> getLogicalLibrary(const std::string &libraryName, double &getLogicalLibraryTime);
......
......@@ -2642,9 +2642,10 @@ TEST_P(SchedulerTest, expandRepackRequestDisabledTape) {
//one retrieve request
scheduler.waitSchedulerDbSubthreadsComplete();
{
bool forceDisableTape = false;
cta::SchedulerDatabase::QueueRepackRequest qrr(vid,"file://"+tempDirectory.path(),common::dataStructures::RepackInfo::Type::MoveOnly,
common::dataStructures::MountPolicy::s_defaultMountPolicyForRepack,s_defaultRepackDisabledTapeFlag,s_defaultRepackNoRecall);
scheduler.queueRepack(admin,qrr,lc);
common::dataStructures::MountPolicy::s_defaultMountPolicyForRepack,forceDisableTape,s_defaultRepackNoRecall);
ASSERT_THROW(scheduler.queueRepack(admin,qrr,lc),cta::exception::UserError);
scheduler.waitSchedulerDbSubthreadsComplete();
log::TimingList tl;
......@@ -2654,31 +2655,87 @@ TEST_P(SchedulerTest, expandRepackRequestDisabledTape) {
scheduler.waitSchedulerDbSubthreadsComplete();
auto repackRequestToExpand = scheduler.getNextRepackRequestToExpand();
scheduler.expandRepackRequest(repackRequestToExpand,tl,t,lc);
scheduler.waitSchedulerDbSubthreadsComplete();
ASSERT_EQ(vid,repackRequestToExpand->getRepackInfo().vid);
repackRequestToExpand = scheduler.getNextRepackRequestToExpand();
ASSERT_EQ(nullptr,repackRequestToExpand);
}
//Queue the repack request with the force disabled tape flag
{
//Check that no mount exist because the tape is disabled
std::unique_ptr<cta::TapeMount> mount;
mount.reset(scheduler.getNextMount(s_libraryName, "drive0", lc).release());
ASSERT_EQ(nullptr, mount.get());
//Check that the repack request is failed with 10 failed to retrieve and 0 failed archive files (as they have not been created, these archive jobs are not failed)
objectstore::RootEntry re(schedulerDB.getBackend());
re.fetchNoLock();
objectstore::RepackIndex ri(re.getRepackIndexAddress(), schedulerDB.getBackend());
ri.fetchNoLock();
objectstore::RepackRequest rr(ri.getRepackRequestAddress(vid),schedulerDB.getBackend());
rr.fetchNoLock();
ASSERT_EQ(10,rr.getStats().at(objectstore::RepackRequest::StatsType::RetrieveFailure).files);
ASSERT_EQ(0,rr.getStats().at(objectstore::RepackRequest::StatsType::ArchiveFailure).files);
ASSERT_EQ(common::dataStructures::RepackInfo::Status::Failed,rr.getInfo().status);
bool forceDisableTape = true;
cta::SchedulerDatabase::QueueRepackRequest qrr(vid,"file://"+tempDirectory.path(),common::dataStructures::RepackInfo::Type::MoveOnly,
common::dataStructures::MountPolicy::s_defaultMountPolicyForRepack,forceDisableTape,s_defaultRepackNoRecall);
ASSERT_NO_THROW(scheduler.queueRepack(admin,qrr,lc));
scheduler.waitSchedulerDbSubthreadsComplete();
log::TimingList tl;
utils::Timer t;
scheduler.promoteRepackRequestsToToExpand(lc);
scheduler.waitSchedulerDbSubthreadsComplete();
auto repackRequestToExpand = scheduler.getNextRepackRequestToExpand();
ASSERT_NE(nullptr,repackRequestToExpand);
}
}
TEST_P(SchedulerTest, expandRepackRequestBrokenTape) {
using namespace cta;
using namespace cta::objectstore;
unitTests::TempDirectory tempDirectory;
auto &catalogue = getCatalogue();
auto &scheduler = getScheduler();
auto &schedulerDB = getSchedulerDB();
cta::objectstore::Backend& backend = schedulerDB.getBackend();
setupDefaultCatalogue();
#ifdef STDOUT_LOGGING
log::StdoutLogger dl("dummy", "unitTest");
#else
log::DummyLogger dl("", "");
#endif
log::LogContext lc(dl);
//Create an agent to represent this test process
cta::objectstore::AgentReference agentReference("expandRepackRequestTest", dl);
cta::objectstore::Agent agent(agentReference.getAgentAddress(), backend);
agent.initialize();
agent.setTimeout_us(0);
agent.insertAndRegisterSelf(lc);
cta::common::dataStructures::SecurityIdentity admin;
admin.username = "admin_user_name";
admin.host = "admin_host";
//Create a logical library in the catalogue
const bool logicalLibraryIsDisabled = false;
catalogue.createLogicalLibrary(admin, s_libraryName, logicalLibraryIsDisabled, "Create logical library");
std::ostringstream ossVid;
ossVid << s_vid << "_" << 1;
std::string vid = ossVid.str();
{
auto tape = getDefaultTape();
tape.vid = vid;
tape.full = true;
tape.state = common::dataStructures::Tape::BROKEN;
tape.stateReason = "Test";
catalogue.createTape(s_adminOnAdminHost, tape);
}
{
bool forceDisableTape = false;
cta::SchedulerDatabase::QueueRepackRequest qrr(vid,"file://"+tempDirectory.path(),common::dataStructures::RepackInfo::Type::MoveOnly,
common::dataStructures::MountPolicy::s_defaultMountPolicyForRepack,forceDisableTape,s_defaultRepackNoRecall);
ASSERT_THROW(scheduler.queueRepack(admin,qrr,lc),cta::exception::UserError);
scheduler.waitSchedulerDbSubthreadsComplete();
log::TimingList tl;
utils::Timer t;
scheduler.promoteRepackRequestsToToExpand(lc);
scheduler.waitSchedulerDbSubthreadsComplete();
auto repackRequestToExpand = scheduler.getNextRepackRequestToExpand();
ASSERT_EQ(nullptr,repackRequestToExpand);
}
}
......
Markdown is supported
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