diff --git a/common/dataStructures/DriveState.cpp b/common/dataStructures/DriveState.cpp index e9d013bc5e6a25f4a7085d8bfc4ce987463b47b9..73d83e009935df39b9628ee114a0c026f00ee92f 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 c320473f7bbeb9883bca9a5a11cfcfd236b82d5a..b4568c450f119abf333ecb31988ab328e99c4ed7 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 c28f5465b9337cc85711e2500210330c88ee538c..6d0eac20e65b051b8b0a022a230de2bc827fbf6d 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 db213046a39c741111fea049ed7ddeaaa1573acc..d77af306d07fce9ea5667bfd6a07cab979befd9e 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 9816f51ece2ffb563d962f242419e10f340d93b0..9d086f6e778fb358fa97d7412e63916485a5179d 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 ea8d21ee50ce8e697b4d4e49802b16735ae3ce4b..5f320f729f1b157c3eb42658d48e72a290f07387 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 a49cec8c12cf9b257effa3881b5748dc9adf4509..b40b45a5e4d7bb345120daeefb90613c91b63941 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 2d5cf775d43b573bd9ef5338967277e187a23d6c..46bce86c527ad588c0f5f78be65f4d965da14c1e 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 1dc8c60f224fffd2f6ba3f9b5ada6dc86b5fa66f..0392653e670978365dfde5d5b285eb91c535f88e 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 b545229f9954487dd8a2779ca57f72f85c6a8031..6d225af666835bcacc894ef760895ad315b72de0 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;