diff --git a/scheduler/Scheduler.cpp b/scheduler/Scheduler.cpp index bac8dbaf329841c9a11d0c26f3370cd3fe5d4f72..efd2a8248143ba0c92e7a981d05b9ec70f4767de 100644 --- a/scheduler/Scheduler.cpp +++ b/scheduler/Scheduler.cpp @@ -903,7 +903,7 @@ std::list<common::dataStructures::DriveState> Scheduler::getDriveStates(const co //------------------------------------------------------------------------------ void Scheduler::sortAndGetTapesForMountInfo(std::unique_ptr<SchedulerDatabase::TapeMountDecisionInfo>& mountInfo, const std::string & logicalLibraryName, const std::string & driveName, utils::Timer & timer, - ExistingMountSummary & existingMountsSummary, std::set<std::string> & tapesInUse, std::list<catalogue::TapeForWriting> & tapeList, + ExistingMountSummaryPerTapepool & existingMountsSummaryPerTapepool, ExistingMountSummaryPerVo & existingMountSummaryPerVo, std::set<std::string> & tapesInUse, std::list<catalogue::TapeForWriting> & tapeList, double & getTapeInfoTime, double & candidateSortingTime, double & getTapeForWriteTime, log::LogContext & lc) { // The library information is not know for the tapes involved in retrieves. We // need to query the catalogue now about all those tapes. @@ -945,9 +945,9 @@ void Scheduler::sortAndGetTapesForMountInfo(std::unique_ptr<SchedulerDatabase::T for (auto & em: mountInfo->existingOrNextMounts) { // If a mount is still listed for our own drive, it is a leftover that we disregard. if (em.driveName!=driveName) { - existingMountsSummary[TapePoolMountPair(em.tapePool, em.type)].totalMounts++; + existingMountsSummaryPerTapepool[TapePoolMountPair(em.tapePool, em.type)].totalMounts++; if (em.activity) - existingMountsSummary[TapePoolMountPair(em.tapePool, em.type)] + existingMountsSummaryPerTapepool[TapePoolMountPair(em.tapePool, em.type)] .activityMounts[em.activity.value()].value++; if (em.vid.size()) { tapesInUse.insert(em.vid); @@ -966,23 +966,23 @@ void Scheduler::sortAndGetTapesForMountInfo(std::unique_ptr<SchedulerDatabase::T // and weight the remaining by how much of their quota is reached. for (auto m = mountInfo->potentialMounts.begin(); m!= mountInfo->potentialMounts.end();) { // Get summary data - uint32_t existingMounts = 0; + uint32_t existingMountsPerTapepool = 0; uint32_t activityMounts = 0; bool sleepingMount = false; try { - existingMounts = existingMountsSummary + existingMountsPerTapepool = existingMountsSummaryPerTapepool .at(TapePoolMountPair(m->tapePool, m->type)) .totalMounts; } catch (std::out_of_range &) {} if (m->activityNameAndWeightedMountCount) { try { - activityMounts = existingMountsSummary + activityMounts = existingMountsSummaryPerTapepool .at(TapePoolMountPair(m->tapePool, m->type)) .activityMounts.at(m->activityNameAndWeightedMountCount.value().activity).value; } catch (std::out_of_range &) {} } - uint32_t effectiveExistingMounts = 0; - if (common::dataStructures::getMountBasicType(m->type) == common::dataStructures::MountType::ArchiveAllTypes) effectiveExistingMounts = existingMounts; + uint32_t effectiveExistingMountsPerTapepool = 0; + if (common::dataStructures::getMountBasicType(m->type) == common::dataStructures::MountType::ArchiveAllTypes) effectiveExistingMountsPerTapepool = existingMountsPerTapepool; bool mountPassesACriteria = false; uint64_t minBytesToWarrantAMount = m_minBytesToWarrantAMount; uint64_t minFilesToWarrantAMount = m_minFilesToWarrantAMount; @@ -990,37 +990,36 @@ void Scheduler::sortAndGetTapesForMountInfo(std::unique_ptr<SchedulerDatabase::T minBytesToWarrantAMount *= 2; minFilesToWarrantAMount *= 2; } - if (m->bytesQueued / (1 + effectiveExistingMounts) >= minBytesToWarrantAMount) + if (m->bytesQueued / (1 + effectiveExistingMountsPerTapepool) >= minBytesToWarrantAMount) mountPassesACriteria = true; - if (m->filesQueued / (1 + effectiveExistingMounts) >= minFilesToWarrantAMount) + if (m->filesQueued / (1 + effectiveExistingMountsPerTapepool) >= minFilesToWarrantAMount) mountPassesACriteria = true; - if (!effectiveExistingMounts && ((time(NULL) - m->oldestJobStartTime) > m->minRequestAge)) + if (!effectiveExistingMountsPerTapepool && ((time(NULL) - m->oldestJobStartTime) > m->minRequestAge)) mountPassesACriteria = true; if (m->sleepingMount) { sleepingMount = true; } - if (!mountPassesACriteria || existingMounts >= m->maxDrivesAllowed || sleepingMount) { + if (!mountPassesACriteria || existingMountsPerTapepool >= m->maxDrivesAllowed || sleepingMount) { log::ScopedParamContainer params(lc); params.add("tapePool", m->tapePool); if ( m->type == common::dataStructures::MountType::Retrieve) { params.add("tapeVid", m->vid); } params.add("mountType", common::dataStructures::toString(m->type)) - .add("existingMounts", existingMounts) + .add("existingMountsPerTapepool", existingMountsPerTapepool) .add("bytesQueued", m->bytesQueued) .add("minBytesToWarrantMount", minBytesToWarrantAMount) .add("filesQueued", m->filesQueued) .add("minFilesToWarrantMount", minFilesToWarrantAMount) .add("oldestJobAge", time(NULL) - m->oldestJobStartTime) .add("minArchiveRequestAge", m->minRequestAge) - .add("existingMounts", existingMounts) .add("maxDrivesAllowed", m->maxDrivesAllowed); if (sleepingMount) params.add("fullDiskSystem", m->diskSystemSleptFor); lc.log(log::DEBUG, "In Scheduler::sortAndGetTapesForMountInfo(): Removing potential mount not passing criteria"); m = mountInfo->potentialMounts.erase(m); } else { // populate the mount with a weight - m->ratioOfMountQuotaUsed = 1.0L * existingMounts / m->maxDrivesAllowed; + m->ratioOfMountQuotaUsed = 1.0L * existingMountsPerTapepool / m->maxDrivesAllowed; if (m->activityNameAndWeightedMountCount) { m->activityNameAndWeightedMountCount.value().mountCount = activityMounts; // Protect against division by zero @@ -1037,14 +1036,14 @@ void Scheduler::sortAndGetTapesForMountInfo(std::unique_ptr<SchedulerDatabase::T params.add("tapeVid", m->vid); } params.add("mountType", common::dataStructures::toString(m->type)) - .add("existingMounts", existingMounts) + .add("existingMountsPerTapepool", existingMountsPerTapepool) .add("bytesQueued", m->bytesQueued) .add("minBytesToWarrantMount", m_minBytesToWarrantAMount) .add("filesQueued", m->filesQueued) .add("minFilesToWarrantMount", m_minFilesToWarrantAMount) .add("oldestJobAge", time(NULL) - m->oldestJobStartTime) .add("minArchiveRequestAge", m->minRequestAge) - .add("existingMounts", existingMounts) + .add("existingMountsPerTapepool", existingMountsPerTapepool) .add("maxDrivesAllowed", m->maxDrivesAllowed) .add("ratioOfMountQuotaUsed", m->ratioOfMountQuotaUsed); lc.log(log::DEBUG, "In Scheduler::sortAndGetTapesForMountInfo(): Will consider potential mount"); @@ -1178,12 +1177,13 @@ bool Scheduler::getNextMountDryRun(const std::string& logicalLibraryName, const std::unique_ptr<SchedulerDatabase::TapeMountDecisionInfo> mountInfo; mountInfo = m_db.getMountInfoNoLock(SchedulerDatabase::PurposeGetMountInfo::GET_NEXT_MOUNT,lc); getMountInfoTime = timer.secs(utils::Timer::resetCounter); - ExistingMountSummary existingMountsSummary; + ExistingMountSummaryPerTapepool existingMountsSummaryPerTapepool; + ExistingMountSummaryPerVo existingMountSummaryPerVo; std::set<std::string> tapesInUse; std::list<catalogue::TapeForWriting> tapeList; sortAndGetTapesForMountInfo(mountInfo, logicalLibraryName, driveName, timer, - existingMountsSummary, tapesInUse, tapeList, + existingMountsSummaryPerTapepool, existingMountSummaryPerVo, tapesInUse, tapeList, getTapeInfoTime, candidateSortingTime, getTapeForWriteTime, lc); // We can now simply iterate on the candidates until we manage to find a valid mount @@ -1200,15 +1200,15 @@ bool Scheduler::getNextMountDryRun(const std::string& logicalLibraryName, const decisionTime += timer.secs(utils::Timer::resetCounter); schedulerDbTime = getMountInfoTime; catalogueTime = getTapeInfoTime + getTapeForWriteTime; - uint32_t existingMounts = 0; + uint32_t existingMountsPerTapepool = 0; try { - existingMounts=existingMountsSummary.at(TapePoolMountPair(m->tapePool, m->type)).totalMounts; + existingMountsPerTapepool=existingMountsSummaryPerTapepool.at(TapePoolMountPair(m->tapePool, m->type)).totalMounts; } catch (...) {} log::ScopedParamContainer params(lc); params.add("tapePool", m->tapePool) .add("tapeVid", t.vid) .add("mountType", common::dataStructures::toString(m->type)) - .add("existingMounts", existingMounts) + .add("existingMountsPerTapepool", existingMountsPerTapepool) .add("bytesQueued", m->bytesQueued) .add("minBytesToWarrantMount", m_minBytesToWarrantAMount) .add("filesQueued", m->filesQueued) @@ -1233,16 +1233,16 @@ bool Scheduler::getNextMountDryRun(const std::string& logicalLibraryName, const if (tapesInUse.count(m->vid)) continue; decisionTime += timer.secs(utils::Timer::resetCounter); log::ScopedParamContainer params(lc); - uint32_t existingMounts = 0; + uint32_t existingMountsPerTapepool = 0; try { - existingMounts=existingMountsSummary.at(TapePoolMountPair(m->tapePool, m->type)).totalMounts; + existingMountsPerTapepool=existingMountsSummaryPerTapepool.at(TapePoolMountPair(m->tapePool, m->type)).totalMounts; } catch (...) {} schedulerDbTime = getMountInfoTime; catalogueTime = getTapeInfoTime + getTapeForWriteTime; params.add("tapePool", m->tapePool) .add("tapeVid", m->vid) .add("mountType", common::dataStructures::toString(m->type)) - .add("existingMounts", existingMounts); + .add("existingMountsPerTapepool", existingMountsPerTapepool); if (m->activityNameAndWeightedMountCount) { params.add("activity", m->activityNameAndWeightedMountCount.value().activity) .add("activityMounts", m->activityNameAndWeightedMountCount.value().weightedMountCount) @@ -1338,12 +1338,13 @@ auto logicalLibrary = getLogicalLibrary(logicalLibraryName,getLogicalLibrariesTi } __attribute__((unused)) SchedulerDatabase::TapeMountDecisionInfo & debugMountInfo = *mountInfo; - ExistingMountSummary existingMountsSummary; + ExistingMountSummaryPerTapepool existingMountsSummaryPerTapepool; + ExistingMountSummaryPerVo existingMountSummaryPerVo; std::set<std::string> tapesInUse; std::list<catalogue::TapeForWriting> tapeList; sortAndGetTapesForMountInfo(mountInfo, logicalLibraryName, driveName, timer, - existingMountsSummary, tapesInUse, tapeList, + existingMountsSummaryPerTapepool, existingMountSummaryPerVo, tapesInUse, tapeList, getTapeInfoTime, candidateSortingTime, getTapeForWriteTime, lc); // We can now simply iterate on the candidates until we manage to create a @@ -1376,9 +1377,9 @@ auto logicalLibrary = getLogicalLibrary(logicalLibraryName,getLogicalLibrariesTi internalRet->m_sessionRunning = true; driveStatusSetTime += timer.secs(utils::Timer::resetCounter); log::ScopedParamContainer params(lc); - uint32_t existingMounts = 0; + uint32_t existingMountsPerTapepool = 0; try { - existingMounts=existingMountsSummary.at(TapePoolMountPair(m->tapePool, m->type)).totalMounts; + existingMountsPerTapepool=existingMountsSummaryPerTapepool.at(TapePoolMountPair(m->tapePool, m->type)).totalMounts; } catch (...) {} schedulerDbTime = getMountInfoTime + queueTrimingTime + mountCreationTime + driveStatusSetTime; catalogueTime = getTapeInfoTime + getTapeForWriteTime; @@ -1389,7 +1390,7 @@ auto logicalLibrary = getLogicalLibrary(logicalLibraryName,getLogicalLibrariesTi .add("mediaType",t.mediaType) .add("vendor",t.vendor) .add("mountType", common::dataStructures::toString(m->type)) - .add("existingMounts", existingMounts) + .add("existingMountsPerTapepool", existingMountsPerTapepool) .add("bytesQueued", m->bytesQueued) .add("minBytesToWarrantMount", m_minBytesToWarrantAMount) .add("filesQueued", m->filesQueued) @@ -1447,9 +1448,9 @@ auto logicalLibrary = getLogicalLibrary(logicalLibraryName,getLogicalLibrariesTi internalRet->m_tapeRunning = true; driveStatusSetTime += timer.secs(utils::Timer::resetCounter); log::ScopedParamContainer params(lc); - uint32_t existingMounts = 0; + uint32_t existingMountsPerTapepool = 0; try { - existingMounts=existingMountsSummary.at(TapePoolMountPair(m->tapePool, m->type)).totalMounts; + existingMountsPerTapepool=existingMountsSummaryPerTapepool.at(TapePoolMountPair(m->tapePool, m->type)).totalMounts; } catch (...) {} schedulerDbTime = getMountInfoTime + queueTrimingTime + mountCreationTime + driveStatusSetTime; catalogueTime = getTapeInfoTime + getTapeForWriteTime; @@ -1459,7 +1460,7 @@ auto logicalLibrary = getLogicalLibrary(logicalLibraryName,getLogicalLibrariesTi .add("mediaType",m->mediaType) .add("vendor",m->vendor) .add("mountType", common::dataStructures::toString(m->type)) - .add("existingMounts", existingMounts); + .add("existingMountsPerTapepool", existingMountsPerTapepool); if (m->activityNameAndWeightedMountCount) { params.add("activity", m->activityNameAndWeightedMountCount.value().activity) .add("activityMounts", m->activityNameAndWeightedMountCount.value().weightedMountCount) @@ -1525,7 +1526,8 @@ std::list<SchedulingInfos> Scheduler::getSchedulingInformations(log::LogContext& double candidateSortingTime = 0; double getTapeForWriteTime = 0; - ExistingMountSummary existingMountsSummary; + ExistingMountSummaryPerTapepool existingMountsSummaryPerTapepool; + ExistingMountSummaryPerVo existingMountSummaryPerVo; std::set<std::string> tapesInUse; std::list<catalogue::TapeForWriting> tapeList; @@ -1546,7 +1548,7 @@ std::list<SchedulingInfos> Scheduler::getSchedulingInformations(log::LogContext& cta::SchedulingInfos schedulingInfos(logicalLibrary); for(auto & driveName: kv.second){ sortAndGetTapesForMountInfo(mountInfo, logicalLibrary, driveName, timer, - existingMountsSummary, tapesInUse, tapeList, + existingMountsSummaryPerTapepool, existingMountSummaryPerVo, tapesInUse, tapeList, getTapeInfoTime, candidateSortingTime, getTapeForWriteTime, lc); //schedulingInfos.addDrivePotentialMount std::vector<cta::SchedulerDatabase::PotentialMount> potentialMounts = mountInfo->potentialMounts; diff --git a/scheduler/Scheduler.hpp b/scheduler/Scheduler.hpp index 29a76a8b7262b034c23dfbd0a2a6369ce17371db..4bf23c56fcd51b59899d8c4e75d9ba4db88c55dd 100644 --- a/scheduler/Scheduler.hpp +++ b/scheduler/Scheduler.hpp @@ -276,6 +276,8 @@ public: private: typedef std::pair<std::string, common::dataStructures::MountType> TapePoolMountPair; + typedef std::pair<std::string, common::dataStructures::MountType> VirtualOrganizationMountPair; + struct MountCounts { uint32_t totalMounts = 0; struct AutoZeroUint32_t { @@ -283,7 +285,8 @@ private: }; std::map<std::string, AutoZeroUint32_t> activityMounts; }; - typedef std::map<TapePoolMountPair, MountCounts> ExistingMountSummary; + typedef std::map<TapePoolMountPair, MountCounts> ExistingMountSummaryPerTapepool; + typedef std::map<VirtualOrganizationMountPair, MountCounts> ExistingMountSummaryPerVo; const std::set<std::string> c_mandatoryEnvironmentVariables = {"XrdSecPROTOCOL", "XrdSecSSSKT"}; @@ -293,7 +296,7 @@ private: */ void sortAndGetTapesForMountInfo(std::unique_ptr<SchedulerDatabase::TapeMountDecisionInfo> &mountInfo, const std::string & logicalLibraryName, const std::string & driveName, utils::Timer & timer, - ExistingMountSummary & existingMountsSummary, std::set<std::string> & tapesInUse, std::list<catalogue::TapeForWriting> & tapeList, + ExistingMountSummaryPerTapepool & existingMountsSummaryPerTapepool, ExistingMountSummaryPerVo & existingMountSummaryPerVo, std::set<std::string> & tapesInUse, std::list<catalogue::TapeForWriting> & tapeList, double & getTapeInfoTime, double & candidateSortingTime, double & getTapeForWriteTime, log::LogContext & lc); /**