diff --git a/scheduler/ArchiveMount.cpp b/scheduler/ArchiveMount.cpp index d9c2ba614d942bba844a0a78f1120b3ede7bb4c7..4c68792b9e6f209f44f9c640593396ea7fec6f82 100644 --- a/scheduler/ArchiveMount.cpp +++ b/scheduler/ArchiveMount.cpp @@ -21,14 +21,15 @@ //------------------------------------------------------------------------------ // constructor //------------------------------------------------------------------------------ -cta::ArchiveMount::ArchiveMount(NameServer & ns): m_ns(ns) { +cta::ArchiveMount::ArchiveMount(NameServer & ns): m_ns(ns), m_sessionRunning(false){ } //------------------------------------------------------------------------------ // constructor //------------------------------------------------------------------------------ cta::ArchiveMount::ArchiveMount(NameServer & ns, - std::unique_ptr<SchedulerDatabase::ArchiveMount> dbMount): m_ns(ns) { + std::unique_ptr<SchedulerDatabase::ArchiveMount> dbMount): m_ns(ns), + m_sessionRunning(false) { m_dbMount.reset( dynamic_cast<SchedulerDatabase::ArchiveMount*>(dbMount.release())); if(!m_dbMount.get()) { @@ -83,6 +84,9 @@ std::string cta::ArchiveMount::getMountTransactionId() const throw(){ // getNextJob //------------------------------------------------------------------------------ std::unique_ptr<cta::ArchiveJob> cta::ArchiveMount::getNextJob() { + // Check we are still running the session + if (!m_sessionRunning) + throw SessionNotRunning("In ArchiveMount::getNextJob(): trying to get job from complete/not started session"); // try and get a new job from the DB side std::unique_ptr<cta::SchedulerDatabase::ArchiveJob> dbJob(m_dbMount->getNextJob().release()); if (!dbJob.get()) @@ -98,7 +102,10 @@ std::unique_ptr<cta::ArchiveJob> cta::ArchiveMount::getNextJob() { // complete //------------------------------------------------------------------------------ void cta::ArchiveMount::complete() { - throw NotImplemented(std::string(__FUNCTION__) + ": Not implemented"); + // Just set the session as complete in the DB. + m_dbMount->complete(time(NULL)); + // and record we are done with the mount + m_sessionRunning = false; } //------------------------------------------------------------------------------ diff --git a/scheduler/ArchiveMount.hpp b/scheduler/ArchiveMount.hpp index 42301a1019507e06ac41bea772ace02aa6882bf0..6b70df79013b544732de72cf2cad471d250fc7c0 100644 --- a/scheduler/ArchiveMount.hpp +++ b/scheduler/ArchiveMount.hpp @@ -92,6 +92,7 @@ namespace cta { */ virtual void complete(); + CTA_GENERATE_EXCEPTION_CLASS(SessionNotRunning); /** * Job factory * @@ -131,6 +132,11 @@ namespace cta { */ NameServer & m_ns; + /** + * Internal tracking of the session completion + */ + bool m_sessionRunning; + }; // class ArchiveMount } // namespace cta diff --git a/scheduler/OStoreDB/OStoreDB.cpp b/scheduler/OStoreDB/OStoreDB.cpp index 5e00119d2e180f71509f4a256617a4b29fae527f..8a1ac134842d41967763a10e1927272cca2ce742 100644 --- a/scheduler/OStoreDB/OStoreDB.cpp +++ b/scheduler/OStoreDB/OStoreDB.cpp @@ -1090,6 +1090,7 @@ std::unique_ptr<SchedulerDatabase::ArchiveMount> am.mountInfo.vid = vid; am.mountInfo.drive = driveName; am.mountInfo.tapePool = tapePool; + am.mountInfo.logicalLibrary = logicalLibrary; am.m_nextFseq = std::numeric_limits<decltype(am.m_nextFseq)>::max(); objectstore::RootEntry re(m_objectStore); objectstore::ScopedSharedLock rel(re); @@ -1275,6 +1276,36 @@ auto OStoreDB::ArchiveMount::getNextJob() -> std::unique_ptr<SchedulerDatabase:: return std::unique_ptr<SchedulerDatabase::ArchiveJob> (NULL); } +void OStoreDB::ArchiveMount::complete(time_t completionTime) { + // When the session is complete, we can reset the status of the tape and the + // drive + // Reset the drive + objectstore::RootEntry re(m_objectStore); + objectstore::ScopedSharedLock rel(re); + re.fetch(); + objectstore::DriveRegister dr(re.getDriveRegisterAddress(), m_objectStore); + objectstore::ScopedExclusiveLock drl(dr); + dr.fetch(); + // Reset the drive state. + dr.reportDriveStatus(mountInfo.drive, mountInfo.logicalLibrary, + objectstore::DriveRegister::DriveStatus::Up, completionTime, + objectstore::DriveRegister::MountType::NoMount, 0, + 0, 0, 0, "", ""); + dr.commit(); + // Find the tape and unbusy it. + objectstore::TapePool tp (re.getTapePoolAddress(mountInfo.tapePool), m_objectStore); + rel.release(); + objectstore::ScopedSharedLock tpl(tp); + tp.fetch(); + objectstore::Tape t(tp.getTapeAddress(mountInfo.vid), m_objectStore); + objectstore::ScopedExclusiveLock tl(t); + tpl.release(); + t.fetch(); + t.releaseBusy(); + t.commit(); +} + + OStoreDB::ArchiveJob::ArchiveJob(const std::string& jobAddress, objectstore::Backend& os, objectstore::Agent& ag): m_jobOwned(false), m_objectStore(os), m_agent(ag), m_atfr(jobAddress, os) {} diff --git a/scheduler/OStoreDB/OStoreDB.hpp b/scheduler/OStoreDB/OStoreDB.hpp index eb1945973592f83cae786ad3563cd1362cd26866..8c0e1bf716030f8461d59aac9360530f053f03e3 100644 --- a/scheduler/OStoreDB/OStoreDB.hpp +++ b/scheduler/OStoreDB/OStoreDB.hpp @@ -79,6 +79,7 @@ public: public: virtual const MountInfo & getMountInfo(); virtual std::unique_ptr<ArchiveJob> getNextJob(); + virtual void complete(time_t completionTime); }; /* === Archive Job Handling =============================================== */ diff --git a/scheduler/Scheduler.cpp b/scheduler/Scheduler.cpp index d12fef18406dd4239e8804dd3c72e6161e2e55b0..06c855db493d150fbfee4dfb4f68b66b63ac8d00 100644 --- a/scheduler/Scheduler.cpp +++ b/scheduler/Scheduler.cpp @@ -857,6 +857,7 @@ std::unique_ptr<cta::TapeMount> cta::Scheduler::getNextMount( logicalLibraryName, Utils::getShortHostname(), time(NULL)).release()); + internalRet->m_sessionRunning = true; return std::unique_ptr<TapeMount> (internalRet.release()); } catch (cta::exception::Exception & ex) { continue; diff --git a/scheduler/SchedulerDatabase.hpp b/scheduler/SchedulerDatabase.hpp index 30d0ac6dfc843cc9f2e19bf32d6f97bcc9d42f9c..5e5d586e8891c6550a823d70c872299d13e6ba4c 100644 --- a/scheduler/SchedulerDatabase.hpp +++ b/scheduler/SchedulerDatabase.hpp @@ -162,12 +162,14 @@ public: public: struct MountInfo { std::string vid; + std::string logicalLibrary; std::string tapePool; std::string drive; uint64_t mountId; } mountInfo; virtual const MountInfo & getMountInfo() = 0; virtual std::unique_ptr<ArchiveJob> getNextJob() = 0; + virtual void complete(time_t completionTime) = 0; virtual ~ArchiveMount() {} };