diff --git a/lib/icinga/scheduleddowntime.cpp b/lib/icinga/scheduleddowntime.cpp index 8b7c87f1e..972a428ad 100644 --- a/lib/icinga/scheduleddowntime.cpp +++ b/lib/icinga/scheduleddowntime.cpp @@ -98,6 +98,15 @@ void ScheduledDowntime::TimerProc() Log(LogCritical, "ScheduledDowntime") << "Exception occurred during creation of next downtime for scheduled downtime '" << sd->GetName() << "': " << DiagnosticInformation(ex, false); + continue; + } + + try { + sd->RemoveObsoleteDowntimes(); + } catch (const std::exception& ex) { + Log(LogCritical, "ScheduledDowntime") + << "Exception occurred during removal of obsolete downtime for scheduled downtime '" + << sd->GetName() << "': " << DiagnosticInformation(ex, false); } } } @@ -301,6 +310,24 @@ void ScheduledDowntime::CreateNextDowntime() } } +void ScheduledDowntime::RemoveObsoleteDowntimes() +{ + auto name (GetName()); + auto downtimeOptionsHash (HashDowntimeOptions()); + + // Just to be sure start and removal don't happen at the same time + auto threshold (Utility::GetTime() + 5 * 60); + + for (const Downtime::Ptr& downtime : GetCheckable()->GetDowntimes()) { + if (downtime->GetScheduledBy() == name && downtime->GetStartTime() > threshold) { + auto configOwnerHash (downtime->GetConfigOwnerHash()); + + if (!configOwnerHash.IsEmpty() && configOwnerHash != downtimeOptionsHash) + Downtime::RemoveDowntime(downtime->GetName(), false, true); + } + } +} + void ScheduledDowntime::ValidateRanges(const Lazy& lvalue, const ValidationUtils& utils) { ObjectImpl::ValidateRanges(lvalue, utils); diff --git a/lib/icinga/scheduleddowntime.hpp b/lib/icinga/scheduleddowntime.hpp index 3c1a23d47..f8d8e0840 100644 --- a/lib/icinga/scheduleddowntime.hpp +++ b/lib/icinga/scheduleddowntime.hpp @@ -47,6 +47,7 @@ private: std::pair FindRunningSegment(double minEnd = 0); std::pair FindNextSegment(); void CreateNextDowntime(); + void RemoveObsoleteDowntimes(); static std::atomic m_AllConfigLoaded;