diff --git a/catalogue/Catalogue.hpp b/catalogue/Catalogue.hpp index 5c705b15f8387f2c1ba5d26573bc12ec771e0d69..1dd5caaec010793c7031c8394b1512a645447b13 100644 --- a/catalogue/Catalogue.hpp +++ b/catalogue/Catalogue.hpp @@ -182,6 +182,8 @@ public: virtual void fileWrittenToTape( const cta::common::dataStructures::ArchiveRequest &archiveRequest, const cta::common::dataStructures::TapeFileLocation tapeFileLocation) = 0; + + virtual std::map<uint64_t,std::string> getCopyNbToTapePoolMap(const std::string &storageClass) = 0; }; // class Catalogue diff --git a/catalogue/DummyCatalogue.cpp b/catalogue/DummyCatalogue.cpp index a038f87712aa808811626f8f69afa0d21f55a21b..8db678318f357f75fe6ecfa746371e063d4d6643 100644 --- a/catalogue/DummyCatalogue.cpp +++ b/catalogue/DummyCatalogue.cpp @@ -408,3 +408,10 @@ void cta::catalogue::DummyCatalogue::fileWrittenToTape( const cta::common::dataStructures::ArchiveRequest &archiveRequest, const cta::common::dataStructures::TapeFileLocation tapeFileLocation) { } + +//------------------------------------------------------------------------------ +// getCopyNbToTapePoolMap +//------------------------------------------------------------------------------ +std::map<uint64_t,std::string> cta::catalogue::DummyCatalogue::getCopyNbToTapePoolMap(const std::string &storageClass) { + return std::map<uint64_t,std::string>(); +} \ No newline at end of file diff --git a/catalogue/DummyCatalogue.hpp b/catalogue/DummyCatalogue.hpp index 884a84ee35d3874f94c6ea5f815d9b2b55bb9ecb..24f776abfba20e9624a5cf4d642d3d56491d31f4 100644 --- a/catalogue/DummyCatalogue.hpp +++ b/catalogue/DummyCatalogue.hpp @@ -141,6 +141,8 @@ public: virtual void fileWrittenToTape( const cta::common::dataStructures::ArchiveRequest &archiveRequest, const cta::common::dataStructures::TapeFileLocation tapeFileLocation); + + std::map<uint64_t,std::string> getCopyNbToTapePoolMap(const std::string &storageClass); }; // class DummyCatalogue diff --git a/scheduler/OStoreDB/OStoreDB.cpp b/scheduler/OStoreDB/OStoreDB.cpp index 657d7bb9c44396e6640a23c43a21f850fe170656..375500327df8711b03c2526849b0a6b3771c72c3 100644 --- a/scheduler/OStoreDB/OStoreDB.cpp +++ b/scheduler/OStoreDB/OStoreDB.cpp @@ -40,6 +40,7 @@ #include "ArchiveToTapeCopyRequest.hpp" #include "common/archiveNS/ArchiveFile.hpp" #include "objectstore/ArchiveRequest.hpp" +#include "common/dataStructures/UserGroup.hpp" #include <algorithm> #include <stdlib.h> /* srand, rand */ #include <time.h> /* time */ @@ -743,9 +744,63 @@ std::unique_ptr<cta::SchedulerDatabase::ArchiveToFileRequestCreation> return ret; } -std::unique_ptr<cta::SchedulerDatabase::ArchiveRequestCreation> - OStoreDB::queue(const cta::common::dataStructures::ArchiveRequest &request, const uint64_t archiveFileId) { - return std::unique_ptr<cta::SchedulerDatabase::ArchiveRequestCreation>(); +std::unique_ptr<cta::SchedulerDatabase::ArchiveRequestCreation> OStoreDB::queue(const cta::common::dataStructures::ArchiveRequest &request, + const uint64_t archiveFileId, const std::map<uint64_t, std::string> ©NbToPoolMap) { + assertAgentSet(); + // Construct the return value immediately + std::unique_ptr<cta::OStoreDB::ArchiveRequestCreation> internalRet(new cta::OStoreDB::ArchiveRequestCreation(m_agent, m_objectStore)); + cta::objectstore::ArchiveRequest & ar = internalRet->m_request; + ar.setAddress(m_agent->nextId("ArchiveRequest")); + ar.initialize(); + ar.setChecksumType(request.getChecksumType()); + ar.setChecksumValue(request.getChecksumValue()); + ar.setCreationLog(request.getCreationLog()); + ar.setDiskpoolName(request.getDiskpoolName()); + ar.setDiskpoolThroughput(request.getDiskpoolThroughput()); + ar.setDrData(request.getDrData()); + ar.setEosFileID(request.getEosFileID()); + ar.setFileSize(request.getFileSize()); + ar.setRequester(request.getRequester()); + ar.setSrcURL(request.getSrcURL()); + ar.setStorageClass(request.getStorageClass()); + // We will need to identity tapepools is order to construct the request + RootEntry re(m_objectStore); + ScopedSharedLock rel(re); + re.fetch(); + auto & cl = copyNbToPoolMap; + std::list<cta::objectstore::ArchiveRequest::JobDump> jl; + for (auto copy=cl.begin(); copy != cl.end(); copy++) { + std::string tpaddr = re.getTapePoolAddress(copy->second); + ar.addJob(copy->first, copy->second, tpaddr); + jl.push_back(cta::objectstore::ArchiveRequest::JobDump()); + jl.back().copyNb = copy->first; + jl.back().tapePool = copy->second; + jl.back().tapePoolAddress = tpaddr; + } + if (!jl.size()) { + throw ArchiveRequestHasNoCopies("In OStoreDB::queue: the archive to file request has no copy"); + } + // We create the object here + { + objectstore::ScopedExclusiveLock al(*m_agent); + m_agent->fetch(); + m_agent->addToOwnership(ar.getAddressIfSet()); + m_agent->commit(); + } + ar.setOwner(m_agent->getAddressIfSet()); + ar.insert(); + internalRet->m_lock.lock(ar); + // We successfully prepared the object. It will remain attached to the agent + // entry for the time being and get plugged to the tape pools on a second + // pass. + // TODO: this can be improved by passing an opaque set of data to the called + // (including the lock) in order to optimise the acesses to the object store. + // In the mean time, the step 2 of this insertion will be done by finding the + // archiveRequest from the agent's owned object. Crude, but should not be too + // bad as the agent is not supposed to own many objects in this place. + std::unique_ptr<cta::SchedulerDatabase::ArchiveRequestCreation> ret; + ret.reset(internalRet.release()); + return ret; } void OStoreDB::deleteArchiveRequest(const SecurityIdentity& requester, diff --git a/scheduler/OStoreDB/OStoreDB.hpp b/scheduler/OStoreDB/OStoreDB.hpp index df03194c7166009335ddb23f6830bd7fb7e494bb..9a79f37af7b31c1733b82e20d6ffa403f9544f75 100644 --- a/scheduler/OStoreDB/OStoreDB.hpp +++ b/scheduler/OStoreDB/OStoreDB.hpp @@ -252,7 +252,7 @@ public: virtual std::unique_ptr<cta::SchedulerDatabase::ArchiveToFileRequestCreation> queue(const ArchiveToFileRequest& rqst); - virtual std::unique_ptr<cta::SchedulerDatabase::ArchiveRequestCreation> queue(const cta::common::dataStructures::ArchiveRequest &request, const uint64_t archiveFileId); + virtual std::unique_ptr<cta::SchedulerDatabase::ArchiveRequestCreation> queue(const cta::common::dataStructures::ArchiveRequest &request, const uint64_t archiveFileId, const std::map<uint64_t, std::string> ©NbToPoolMap); CTA_GENERATE_EXCEPTION_CLASS(NoSuchArchiveRequest); CTA_GENERATE_EXCEPTION_CLASS(ArchiveRequestAlreadyDeleted); diff --git a/scheduler/OStoreDB/OStoreDBFactory.hpp b/scheduler/OStoreDB/OStoreDBFactory.hpp index e0e6f6be3492bb703f6ce122cad16d68767899a1..950950512c68169146ad6e58792c10dbf4974858 100644 --- a/scheduler/OStoreDB/OStoreDBFactory.hpp +++ b/scheduler/OStoreDB/OStoreDBFactory.hpp @@ -165,8 +165,8 @@ public: return m_OStoreDB.queue(rqst); } - virtual std::unique_ptr<ArchiveRequestCreation> queue(const cta::common::dataStructures::ArchiveRequest &request, const uint64_t archiveFileId) { - return m_OStoreDB.queue(request, archiveFileId); + virtual std::unique_ptr<ArchiveRequestCreation> queue(const cta::common::dataStructures::ArchiveRequest &request, const uint64_t archiveFileId, const std::map<uint64_t, std::string> ©NbToPoolMap) { + return m_OStoreDB.queue(request, archiveFileId, copyNbToPoolMap); } virtual void queue(const RetrieveToFileRequest& rqst) { diff --git a/scheduler/Scheduler.cpp b/scheduler/Scheduler.cpp index 9c640358678839a3b7b41f5a731e3b4e7a3b5199..04315c9af16cfc65be263f71242958ae3a0cf7a3 100644 --- a/scheduler/Scheduler.cpp +++ b/scheduler/Scheduler.cpp @@ -49,7 +49,8 @@ cta::Scheduler::~Scheduler() throw() { //------------------------------------------------------------------------------ uint64_t cta::Scheduler::queueArchiveRequest(const cta::common::dataStructures::SecurityIdentity &requestPusher, const cta::common::dataStructures::ArchiveRequest &request) { const uint64_t archiveFileId = m_catalogue.getNextArchiveFileId(); - std::unique_ptr<SchedulerDatabase::ArchiveRequestCreation> requestCreation(m_db.queue(request, archiveFileId)); + const std::map<uint64_t, std::string> copyNbToPoolMap = m_catalogue.getCopyNbToTapePoolMap(request.getStorageClass()); + std::unique_ptr<SchedulerDatabase::ArchiveRequestCreation> requestCreation(m_db.queue(request, archiveFileId, copyNbToPoolMap)); requestCreation->complete(); return 0; diff --git a/scheduler/SchedulerDatabase.hpp b/scheduler/SchedulerDatabase.hpp index d8f8486055af7368ae08255d78b26f35fd975bca..bb194cb90edef1a1b91f72c0dc2618e1f78e2df4 100644 --- a/scheduler/SchedulerDatabase.hpp +++ b/scheduler/SchedulerDatabase.hpp @@ -92,7 +92,7 @@ public: * * @param rqst The request. */ - virtual std::unique_ptr<ArchiveRequestCreation> queue(const cta::common::dataStructures::ArchiveRequest &request, const uint64_t archiveFileId) = 0; + virtual std::unique_ptr<ArchiveRequestCreation> queue(const cta::common::dataStructures::ArchiveRequest &request, const uint64_t archiveFileId, const std::map<uint64_t, std::string> ©NbToPoolMap) = 0; /** * Returns all of the queued archive requests. The returned requests are