From e49e26b759653ab80539ee17ffc4e9b532894b13 Mon Sep 17 00:00:00 2001 From: Eric Cano <Eric.Cano@cern.ch> Date: Thu, 14 Sep 2017 09:41:41 +0200 Subject: [PATCH] Added new states for the drive: Probing and Shutdown. The probe state is also used. It represents the time when the drive is being checked for tapes during the down to up transition. Shutdown is not in use yet as it requires changing the behaviour of the system (clean shutdowns). --- common/dataStructures/DriveState.cpp | 6 ++ common/dataStructures/DriveState.hpp | 2 + common/dataStructures/DriveStatus.cpp | 4 + common/dataStructures/DriveStatus.hpp | 2 + objectstore/DriveRegister.cpp | 6 ++ objectstore/cta.proto | 2 + scheduler/OStoreDB/OStoreDB.cpp | 90 +++++++++++++++++++ scheduler/OStoreDB/OStoreDB.hpp | 5 ++ .../tapeserver/daemon/DataTransferSession.cpp | 1 + xroot_plugins/XrdCtaFile.cpp | 4 + 10 files changed, 122 insertions(+) diff --git a/common/dataStructures/DriveState.cpp b/common/dataStructures/DriveState.cpp index e9d013bc5e..73d83e0099 100644 --- a/common/dataStructures/DriveState.cpp +++ b/common/dataStructures/DriveState.cpp @@ -39,9 +39,11 @@ DriveState::DriveState(): unmountStartTime(0), drainingStartTime(0), downOrUpStartTime(0), + probeStartTime(0), cleanupStartTime(0), lastUpdateTime(0), startStartTime(0), + shutdownTime(0), mountType(dataStructures::MountType::NoMount), driveStatus(dataStructures::DriveStatus::Down), desiredDriveState({false, false}), @@ -65,9 +67,11 @@ bool DriveState::operator==(const DriveState &rhs) const { && unmountStartTime==rhs.unmountStartTime && drainingStartTime==rhs.drainingStartTime && downOrUpStartTime==rhs.downOrUpStartTime + && probeStartTime==rhs.probeStartTime && cleanupStartTime==rhs.cleanupStartTime && lastUpdateTime==rhs.lastUpdateTime && startStartTime==rhs.startStartTime + && shutdownTime==rhs.shutdownTime && mountType==rhs.mountType && driveStatus==rhs.driveStatus && desiredDriveState==rhs.desiredDriveState @@ -104,9 +108,11 @@ std::ostream &operator<<(std::ostream &os, const DriveState &obj) { << " unmountStartTime=" << obj.unmountStartTime << " drainingStartTime=" << obj.drainingStartTime << " downOrUpStartTime=" << obj.downOrUpStartTime + << " probeStartTime=" << obj.probeStartTime << " cleanupStartTime=" << obj.cleanupStartTime << " lastUpdateTime=" << obj.lastUpdateTime << " startStartTime=" << obj.startStartTime + << " shutdownTime=" << obj.shutdownTime << " mountType=" << obj.mountType << " status=" << obj.driveStatus << " desiredState=" << obj.desiredDriveState diff --git a/common/dataStructures/DriveState.hpp b/common/dataStructures/DriveState.hpp index c320473f7b..b4568c450f 100644 --- a/common/dataStructures/DriveState.hpp +++ b/common/dataStructures/DriveState.hpp @@ -55,9 +55,11 @@ struct DriveState { time_t unmountStartTime; time_t drainingStartTime; time_t downOrUpStartTime; + time_t probeStartTime; time_t cleanupStartTime; time_t lastUpdateTime; time_t startStartTime; + time_t shutdownTime; MountType mountType; DriveStatus driveStatus; DesiredDriveState desiredDriveState; diff --git a/common/dataStructures/DriveStatus.cpp b/common/dataStructures/DriveStatus.cpp index c28f5465b9..6d0eac20e6 100644 --- a/common/dataStructures/DriveStatus.cpp +++ b/common/dataStructures/DriveStatus.cpp @@ -26,6 +26,8 @@ std::string cta::common::dataStructures::toString(cta::common::dataStructures::D return "Down"; case cta::common::dataStructures::DriveStatus::Up: return "Free"; + case cta::common::dataStructures::DriveStatus::Probing: + return "Probe"; case cta::common::dataStructures::DriveStatus::Starting: return "Start"; case cta::common::dataStructures::DriveStatus::Mounting: @@ -40,6 +42,8 @@ std::string cta::common::dataStructures::toString(cta::common::dataStructures::D return "DrainToDisk"; case cta::common::dataStructures::DriveStatus::CleaningUp: return "CleanUp"; + case cta::common::dataStructures::DriveStatus::Shutdown: + return "Shutdown"; case cta::common::dataStructures::DriveStatus::Unknown: return "Unknown"; default: diff --git a/common/dataStructures/DriveStatus.hpp b/common/dataStructures/DriveStatus.hpp index db213046a3..d77af306d0 100644 --- a/common/dataStructures/DriveStatus.hpp +++ b/common/dataStructures/DriveStatus.hpp @@ -26,6 +26,7 @@ namespace dataStructures { enum DriveStatus { Down, Up, + Probing, Starting, Mounting, Transferring, @@ -33,6 +34,7 @@ enum DriveStatus { Unmounting, DrainingToDisk, CleaningUp, + Shutdown, Unknown }; diff --git a/objectstore/DriveRegister.cpp b/objectstore/DriveRegister.cpp index 9816f51ece..9d086f6e77 100644 --- a/objectstore/DriveRegister.cpp +++ b/objectstore/DriveRegister.cpp @@ -124,9 +124,11 @@ std::list<cta::common::dataStructures::DriveState> DriveRegister::getAllDrivesSt ret.back().unmountStartTime = d.unmountstarttime(); ret.back().drainingStartTime = d.drainingstarttime(); ret.back().downOrUpStartTime = d.downorupstarttime(); + ret.back().probeStartTime = d.probestarttime(); ret.back().cleanupStartTime = d.cleanupstarttime(); ret.back().lastUpdateTime = d.lastupdatetime(); ret.back().startStartTime = d.startstarttime(); + ret.back().shutdownTime = d.shutdowntime(); ret.back().mountType = (common::dataStructures::MountType) d.mounttype(); ret.back().driveStatus = (common::dataStructures::DriveStatus) d.drivestatus(); ret.back().desiredDriveState.up = d.desiredup(); @@ -164,9 +166,11 @@ cta::common::dataStructures::DriveState DriveRegister::getDriveState(const std:: ret.unmountStartTime = d.unmountstarttime(); ret.drainingStartTime = d.drainingstarttime(); ret.downOrUpStartTime = d.downorupstarttime(); + ret.probeStartTime = d.probestarttime(); ret.cleanupStartTime = d.cleanupstarttime(); ret.lastUpdateTime = d.lastupdatetime(); ret.startStartTime = d.startstarttime(); + ret.shutdownTime = d.shutdowntime(); ret.mountType = (common::dataStructures::MountType) d.mounttype(); ret.driveStatus = (common::dataStructures::DriveStatus) d.drivestatus(); ret.desiredDriveState.up = d.desiredup(); @@ -210,9 +214,11 @@ update: ds->set_unmountstarttime(driveState.unmountStartTime); ds->set_drainingstarttime(driveState.drainingStartTime); ds->set_downorupstarttime(driveState.downOrUpStartTime); + ds->set_probestarttime(driveState.probeStartTime); ds->set_cleanupstarttime(driveState.cleanupStartTime); ds->set_lastupdatetime(driveState.lastUpdateTime); ds->set_startstarttime(driveState.startStartTime); + ds->set_shutdowntime(driveState.shutdownTime); ds->set_mounttype((uint32_t)driveState.mountType); ds->set_drivestatus((uint32_t)driveState.driveStatus); ds->set_desiredup(driveState.desiredDriveState.up); diff --git a/objectstore/cta.proto b/objectstore/cta.proto index ea8d21ee50..5f320f729f 100644 --- a/objectstore/cta.proto +++ b/objectstore/cta.proto @@ -266,9 +266,11 @@ message DriveState { optional uint64 unmountstarttime = 5011; optional uint64 drainingstarttime = 5012; optional uint64 downorupstarttime = 5013; + optional uint64 probestarttime = 5026; optional uint64 cleanupstarttime = 5014; optional uint64 lastupdatetime = 5015; optional uint64 startstarttime = 5016; + optional uint64 shutdowntime = 5027; required uint32 mounttype = 5017; required uint32 drivestatus = 5018; required bool desiredUp = 5019; diff --git a/scheduler/OStoreDB/OStoreDB.cpp b/scheduler/OStoreDB/OStoreDB.cpp index a49cec8c12..b40b45a5e4 100644 --- a/scheduler/OStoreDB/OStoreDB.cpp +++ b/scheduler/OStoreDB/OStoreDB.cpp @@ -1116,9 +1116,11 @@ void OStoreDB::updateDriveStatusInRegitry(objectstore::DriveRegister& dr, driveState.unmountStartTime = 0; driveState.drainingStartTime = 0; driveState.downOrUpStartTime = 0; + driveState.probeStartTime = 0; driveState.cleanupStartTime = 0; driveState.lastUpdateTime = 0; driveState.startStartTime = 0; + driveState.shutdownTime=0; driveState.desiredDriveState.up = (inputs.status==DriveStatus::Down?false:true); driveState.desiredDriveState.forceDown = false; driveState.currentTapePool = ""; @@ -1135,6 +1137,9 @@ void OStoreDB::updateDriveStatusInRegitry(objectstore::DriveRegister& dr, case DriveStatus::Up: setDriveUpOrMaybeDown(driveState, inputs); break; + case DriveStatus::Probing: + setDriveProbing(driveState, inputs); + break; case DriveStatus::Starting: setDriveStarting(driveState, inputs); break; @@ -1156,6 +1161,9 @@ void OStoreDB::updateDriveStatusInRegitry(objectstore::DriveRegister& dr, case DriveStatus::CleaningUp: setDriveCleaningUp(driveState, inputs); break; + case DriveStatus::Shutdown: + setDriveShutdown(driveState, inputs); + break; default: throw exception::Exception("Unexpected status in DriveRegister::reportDriveStatus"); } @@ -1219,7 +1227,9 @@ void OStoreDB::setDriveDown(common::dataStructures::DriveState & driveState, driveState.unmountStartTime=0; driveState.drainingStartTime=0; driveState.downOrUpStartTime=inputs.reportTime; + driveState.probeStartTime=0; driveState.cleanupStartTime=0; + driveState.shutdownTime=0; driveState.lastUpdateTime=inputs.reportTime; driveState.mountType=common::dataStructures::MountType::NoMount; driveState.driveStatus=common::dataStructures::DriveStatus::Down; @@ -1257,7 +1267,9 @@ void OStoreDB::setDriveUpOrMaybeDown(common::dataStructures::DriveState & driveS driveState.unmountStartTime=0; driveState.drainingStartTime=0; driveState.downOrUpStartTime=inputs.reportTime; + driveState.probeStartTime=0; driveState.cleanupStartTime=0; + driveState.shutdownTime=0; driveState.lastUpdateTime=inputs.reportTime; driveState.mountType=common::dataStructures::MountType::NoMount; driveState.driveStatus=targetStatus; @@ -1265,6 +1277,39 @@ void OStoreDB::setDriveUpOrMaybeDown(common::dataStructures::DriveState & driveS driveState.currentTapePool=""; } +//------------------------------------------------------------------------------ +// OStoreDB::setDriveUp() +//------------------------------------------------------------------------------ +void OStoreDB::setDriveProbing(common::dataStructures::DriveState & driveState, + const ReportDriveStatusInputs & inputs) { + using common::dataStructures::DriveStatus; + // If we were already up (or down), then we only update the last update time. + if (driveState.driveStatus == inputs.status) { + driveState.lastUpdateTime=inputs.reportTime; + return; + } + // If we are changing state, then all should be reset. + driveState.sessionId=0; + driveState.bytesTransferredInSession=0; + driveState.filesTransferredInSession=0; + driveState.latestBandwidth=0; + driveState.sessionStartTime=0; + driveState.mountStartTime=0; + driveState.transferStartTime=0; + driveState.unloadStartTime=0; + driveState.unmountStartTime=0; + driveState.drainingStartTime=0; + driveState.downOrUpStartTime=0; + driveState.probeStartTime=inputs.reportTime; + driveState.cleanupStartTime=0; + driveState.shutdownTime=0; + driveState.lastUpdateTime=inputs.reportTime; + driveState.mountType=common::dataStructures::MountType::NoMount; + driveState.driveStatus=inputs.status; + driveState.currentVid=""; + driveState.currentTapePool=""; +} + //------------------------------------------------------------------------------ // OStoreDB::setDriveStarting() //------------------------------------------------------------------------------ @@ -1288,7 +1333,9 @@ void OStoreDB::setDriveStarting(common::dataStructures::DriveState & driveState, driveState.unmountStartTime=0; driveState.drainingStartTime=0; driveState.downOrUpStartTime=0; + driveState.probeStartTime=0; driveState.cleanupStartTime=0; + driveState.shutdownTime=0; driveState.startStartTime=inputs.reportTime; driveState.lastUpdateTime=inputs.reportTime; driveState.mountType=inputs.mountType; @@ -1320,7 +1367,9 @@ void OStoreDB::setDriveMounting(common::dataStructures::DriveState & driveState, driveState.unmountStartTime=0; driveState.drainingStartTime=0; driveState.downOrUpStartTime=0; + driveState.probeStartTime=0; driveState.cleanupStartTime=0; + driveState.shutdownTime=0; driveState.lastUpdateTime=inputs.reportTime; driveState.mountType=inputs.mountType; driveState.driveStatus=common::dataStructures::DriveStatus::Mounting; @@ -1352,7 +1401,9 @@ void OStoreDB::setDriveTransferring(common::dataStructures::DriveState & driveSt driveState.unmountStartTime=0; driveState.drainingStartTime=0; driveState.downOrUpStartTime=0; + driveState.probeStartTime=0; driveState.cleanupStartTime=0; + driveState.shutdownTime=0; driveState.lastUpdateTime=inputs.reportTime; driveState.mountType=inputs.mountType; driveState.driveStatus=common::dataStructures::DriveStatus::Transferring; @@ -1382,7 +1433,9 @@ void OStoreDB::setDriveUnloading(common::dataStructures::DriveState & driveState driveState.unmountStartTime=0; driveState.drainingStartTime=0; driveState.downOrUpStartTime=0; + driveState.probeStartTime=0; driveState.cleanupStartTime=0; + driveState.shutdownTime=0; driveState.lastUpdateTime=inputs.reportTime; driveState.mountType=inputs.mountType; driveState.driveStatus=common::dataStructures::DriveStatus::Unloading; @@ -1412,7 +1465,9 @@ void OStoreDB::setDriveUnmounting(common::dataStructures::DriveState & driveStat driveState.unmountStartTime=inputs.reportTime; driveState.drainingStartTime=0; driveState.downOrUpStartTime=0; + driveState.probeStartTime=0; driveState.cleanupStartTime=0; + driveState.shutdownTime=0; driveState.lastUpdateTime=inputs.reportTime; driveState.mountType=inputs.mountType; driveState.driveStatus=common::dataStructures::DriveStatus::Unmounting; @@ -1442,7 +1497,9 @@ void OStoreDB::setDriveDrainingToDisk(common::dataStructures::DriveState & drive driveState.unmountStartTime=0; driveState.drainingStartTime=inputs.reportTime; driveState.downOrUpStartTime=0; + driveState.probeStartTime=0; driveState.cleanupStartTime=0; + driveState.shutdownTime=0; driveState.lastUpdateTime=inputs.reportTime; driveState.mountType=inputs.mountType; driveState.driveStatus=common::dataStructures::DriveStatus::DrainingToDisk; @@ -1472,7 +1529,9 @@ void OStoreDB::setDriveCleaningUp(common::dataStructures::DriveState & driveStat driveState.unmountStartTime=0; driveState.drainingStartTime=0; driveState.downOrUpStartTime=0; + driveState.probeStartTime=0; driveState.cleanupStartTime=inputs.reportTime; + driveState.shutdownTime=0; driveState.lastUpdateTime=inputs.reportTime; driveState.mountType=inputs.mountType; driveState.driveStatus=common::dataStructures::DriveStatus::CleaningUp; @@ -1480,6 +1539,37 @@ void OStoreDB::setDriveCleaningUp(common::dataStructures::DriveState & driveStat driveState.currentTapePool=inputs.tapepool; } +//------------------------------------------------------------------------------ +// OStoreDB::setDriveShutdown() +//------------------------------------------------------------------------------ +void OStoreDB::setDriveShutdown(common::dataStructures::DriveState & driveState, + const ReportDriveStatusInputs & inputs) { + if (driveState.driveStatus == common::dataStructures::DriveStatus::Shutdown) { + driveState.lastUpdateTime=inputs.reportTime; + return; + } + // If we are changing state, then all should be reset. We are not supposed to + // know the direction yet. + driveState.sessionId=0; + driveState.bytesTransferredInSession=0; + driveState.filesTransferredInSession=0; + driveState.latestBandwidth=0; + driveState.sessionStartTime=0; + driveState.mountStartTime=0; + driveState.transferStartTime=0; + driveState.unloadStartTime=0; + driveState.unmountStartTime=0; + driveState.drainingStartTime=0; + driveState.downOrUpStartTime=0; + driveState.probeStartTime=0; + driveState.cleanupStartTime=0; + driveState.shutdownTime=inputs.reportTime; + driveState.lastUpdateTime=inputs.reportTime; + driveState.mountType=inputs.mountType; + driveState.driveStatus=common::dataStructures::DriveStatus::CleaningUp; + driveState.currentVid=inputs.vid; + driveState.currentTapePool=inputs.tapepool; +} //------------------------------------------------------------------------------ // OStoreDB::TapeMountDecisionInfo::createArchiveMount() //------------------------------------------------------------------------------ diff --git a/scheduler/OStoreDB/OStoreDB.hpp b/scheduler/OStoreDB/OStoreDB.hpp index 2d5cf775d4..46bce86c52 100644 --- a/scheduler/OStoreDB/OStoreDB.hpp +++ b/scheduler/OStoreDB/OStoreDB.hpp @@ -329,6 +329,9 @@ private: /** Helper for setting a drive state in a specific case. Going UP means drive is ready. It will be instead marked as * down if this is the requested state */ static void setDriveUpOrMaybeDown(common::dataStructures::DriveState & driveState, const ReportDriveStatusInputs & inputs); + + /** Helper for setting a drive state in a specific case */ + static void setDriveProbing(common::dataStructures::DriveState & driveState, const ReportDriveStatusInputs & inputs); /** Helper for setting a drive state in a specific case */ static void setDriveStarting(common::dataStructures::DriveState & driveState, const ReportDriveStatusInputs & inputs); @@ -351,6 +354,8 @@ private: /** Helper for setting a drive state in a specific case */ static void setDriveCleaningUp(common::dataStructures::DriveState & driveState, const ReportDriveStatusInputs & inputs); + /** Helper for setting a drive state in a specific case */ + static void setDriveShutdown(common::dataStructures::DriveState & driveState, const ReportDriveStatusInputs & inputs); private: objectstore::Backend & m_objectStore; catalogue::Catalogue & m_catalogue; diff --git a/tapeserver/castor/tape/tapeserver/daemon/DataTransferSession.cpp b/tapeserver/castor/tape/tapeserver/daemon/DataTransferSession.cpp index 1dc8c60f22..0392653e67 100644 --- a/tapeserver/castor/tape/tapeserver/daemon/DataTransferSession.cpp +++ b/tapeserver/castor/tape/tapeserver/daemon/DataTransferSession.cpp @@ -115,6 +115,7 @@ schedule: // down to up. In such a case, we will run an empty if (downUpTransition) { downUpTransition = false; + m_scheduler.reportDriveStatus(m_driveInfo, cta::common::dataStructures::MountType::NoMount, cta::common::dataStructures::DriveStatus::Probing, lc); castor::tape::tapeserver::daemon::EmptyDriveProbe emptyDriveProbe(m_log, m_driveConfig, m_sysWrapper); lc.log(cta::log::INFO, "Transition from down to up detected. Will check if a tape is in the drive."); if (!emptyDriveProbe.driveIsEmpty()) { diff --git a/xroot_plugins/XrdCtaFile.cpp b/xroot_plugins/XrdCtaFile.cpp index b545229f99..6d225af666 100644 --- a/xroot_plugins/XrdCtaFile.cpp +++ b/xroot_plugins/XrdCtaFile.cpp @@ -1897,6 +1897,8 @@ std::string XrdCtaFile::xCom_drive() { currentRow.push_back(cta::common::dataStructures::toString(ds.driveStatus)); // print the time spent in the current state switch(ds.driveStatus) { + case cta::common::dataStructures::DriveStatus::Probing: + currentRow.push_back(std::to_string((unsigned long long)(time(nullptr)-ds.probeStartTime))); case cta::common::dataStructures::DriveStatus::Up: case cta::common::dataStructures::DriveStatus::Down: currentRow.push_back(std::to_string((unsigned long long)(time(nullptr)-ds.downOrUpStartTime))); @@ -1922,6 +1924,8 @@ std::string XrdCtaFile::xCom_drive() { case cta::common::dataStructures::DriveStatus::DrainingToDisk: currentRow.push_back(std::to_string((unsigned long long)(time(nullptr)-ds.drainingStartTime))); break; + case cta::common::dataStructures::DriveStatus::Shutdown: + currentRow.push_back(std::to_string((unsigned long long)(time(nullptr)-ds.shutdownTime))); case cta::common::dataStructures::DriveStatus::Unknown: currentRow.push_back("-"); break; -- GitLab