From 28b0f7a48c042d70690dd9d8924dfa2396a9da0f Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Wed, 24 Apr 2024 12:33:56 +0200 Subject: [PATCH 1/4] [Refactor] l_LegacyDowntimesCache: store Downtime objects, not just their names to avoid names of vanished objects. --- lib/icinga/downtime.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/icinga/downtime.cpp b/lib/icinga/downtime.cpp index 2178953f3..3ec7e01d4 100644 --- a/lib/icinga/downtime.cpp +++ b/lib/icinga/downtime.cpp @@ -16,7 +16,7 @@ using namespace icinga; static int l_NextDowntimeID = 1; static std::mutex l_DowntimeMutex; -static std::map l_LegacyDowntimesCache; +static std::map l_LegacyDowntimesCache; static Timer::Ptr l_DowntimesOrphanedTimer; static Timer::Ptr l_DowntimesStartTimer; @@ -109,7 +109,7 @@ void Downtime::Start(bool runtimeCreated) std::unique_lock lock(l_DowntimeMutex); SetLegacyId(l_NextDowntimeID); - l_LegacyDowntimesCache[l_NextDowntimeID] = GetName(); + l_LegacyDowntimesCache[l_NextDowntimeID] = this; l_NextDowntimeID++; } @@ -522,7 +522,7 @@ String Downtime::GetDowntimeIDFromLegacyID(int id) if (it == l_LegacyDowntimesCache.end()) return Empty; - return it->second; + return it->second->GetName(); } void Downtime::DowntimesStartTimerHandler() From f0b5239a159c1c631a50cba3308db76855c54cb2 Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Wed, 24 Apr 2024 13:07:18 +0200 Subject: [PATCH 2/4] [Refactor] Downtime::GetDowntimeIDFromLegacyID(): return the Downtime itself not just its name. --- lib/icinga/downtime.cpp | 9 +- lib/icinga/downtime.hpp | 2 +- lib/icinga/externalcommandprocessor.cpp | 104 +++++++++++++++++++----- 3 files changed, 90 insertions(+), 25 deletions(-) diff --git a/lib/icinga/downtime.cpp b/lib/icinga/downtime.cpp index 3ec7e01d4..264382915 100644 --- a/lib/icinga/downtime.cpp +++ b/lib/icinga/downtime.cpp @@ -513,16 +513,17 @@ void Downtime::SetRemovalInfo(const String& removedBy, double removeTime, const OnRemovalInfoChanged(this, removedBy, removeTime, origin); } -String Downtime::GetDowntimeIDFromLegacyID(int id) +Downtime::Ptr Downtime::GetDowntimeFromLegacyID(int id) { std::unique_lock lock(l_DowntimeMutex); auto it = l_LegacyDowntimesCache.find(id); - if (it == l_LegacyDowntimesCache.end()) - return Empty; + if (it == l_LegacyDowntimesCache.end()) { + return nullptr; + } - return it->second->GetName(); + return it->second; } void Downtime::DowntimesStartTimerHandler() diff --git a/lib/icinga/downtime.hpp b/lib/icinga/downtime.hpp index 15aa0af5d..f8b64d142 100644 --- a/lib/icinga/downtime.hpp +++ b/lib/icinga/downtime.hpp @@ -64,7 +64,7 @@ public: void OnAllConfigLoaded() override; - static String GetDowntimeIDFromLegacyID(int id); + static Downtime::Ptr GetDowntimeFromLegacyID(int id); static DowntimeChildOptions ChildOptionsFromValue(const Value& options); diff --git a/lib/icinga/externalcommandprocessor.cpp b/lib/icinga/externalcommandprocessor.cpp index 2ced054f0..e3c449835 100644 --- a/lib/icinga/externalcommandprocessor.cpp +++ b/lib/icinga/externalcommandprocessor.cpp @@ -970,8 +970,14 @@ void ExternalCommandProcessor::ScheduleSvcDowntime(double, const std::vectorGetName(); + } + } Log(LogNotice, "ExternalCommandProcessor") << "Creating downtime for service " << service->GetName(); @@ -983,7 +989,12 @@ void ExternalCommandProcessor::ScheduleSvcDowntime(double, const std::vector& arguments) { int id = Convert::ToLong(arguments[0]); - String rid = Downtime::GetDowntimeIDFromLegacyID(id); + String rid; + auto dt (Downtime::GetDowntimeFromLegacyID(id)); + + if (dt) { + rid = dt->GetName(); + } try { Downtime::RemoveDowntime(rid, false, true); @@ -1005,8 +1016,14 @@ void ExternalCommandProcessor::ScheduleHostDowntime(double, const std::vectorGetName(); + } + } Log(LogNotice, "ExternalCommandProcessor") << "Creating downtime for host " << host->GetName(); @@ -1026,8 +1043,14 @@ void ExternalCommandProcessor::ScheduleAndPropagateHostDowntime(double, const st String triggeredBy; int triggeredByLegacy = Convert::ToLong(arguments[4]); int is_fixed = Convert::ToLong(arguments[3]); - if (triggeredByLegacy != 0) - triggeredBy = Downtime::GetDowntimeIDFromLegacyID(triggeredByLegacy); + + if (triggeredByLegacy != 0) { + auto trigger (Downtime::GetDowntimeFromLegacyID(triggeredByLegacy)); + + if (trigger) { + triggeredBy = trigger->GetName(); + } + } Log(LogNotice, "ExternalCommandProcessor") << "Creating downtime for host " << host->GetName(); @@ -1062,8 +1085,14 @@ void ExternalCommandProcessor::ScheduleAndPropagateTriggeredHostDowntime(double, String triggeredBy; int triggeredByLegacy = Convert::ToLong(arguments[4]); int is_fixed = Convert::ToLong(arguments[3]); - if (triggeredByLegacy != 0) - triggeredBy = Downtime::GetDowntimeIDFromLegacyID(triggeredByLegacy); + + if (triggeredByLegacy != 0) { + auto trigger (Downtime::GetDowntimeFromLegacyID(triggeredByLegacy)); + + if (trigger) { + triggeredBy = trigger->GetName(); + } + } Log(LogNotice, "ExternalCommandProcessor") << "Creating downtime for host " << host->GetName(); @@ -1091,7 +1120,12 @@ void ExternalCommandProcessor::ScheduleAndPropagateTriggeredHostDowntime(double, void ExternalCommandProcessor::DelHostDowntime(double, const std::vector& arguments) { int id = Convert::ToLong(arguments[0]); - String rid = Downtime::GetDowntimeIDFromLegacyID(id); + String rid; + auto dt (Downtime::GetDowntimeFromLegacyID(id)); + + if (dt) { + rid = dt->GetName(); + } try { Downtime::RemoveDowntime(rid, false, true); @@ -1172,8 +1206,14 @@ void ExternalCommandProcessor::ScheduleHostSvcDowntime(double, const std::vector String triggeredBy; int triggeredByLegacy = Convert::ToLong(arguments[4]); int is_fixed = Convert::ToLong(arguments[3]); - if (triggeredByLegacy != 0) - triggeredBy = Downtime::GetDowntimeIDFromLegacyID(triggeredByLegacy); + + if (triggeredByLegacy != 0) { + auto trigger (Downtime::GetDowntimeFromLegacyID(triggeredByLegacy)); + + if (trigger) { + triggeredBy = trigger->GetName(); + } + } Log(LogNotice, "ExternalCommandProcessor") << "Creating downtime for host " << host->GetName(); @@ -1201,8 +1241,14 @@ void ExternalCommandProcessor::ScheduleHostgroupHostDowntime(double, const std:: String triggeredBy; int triggeredByLegacy = Convert::ToLong(arguments[4]); int is_fixed = Convert::ToLong(arguments[3]); - if (triggeredByLegacy != 0) - triggeredBy = Downtime::GetDowntimeIDFromLegacyID(triggeredByLegacy); + + if (triggeredByLegacy != 0) { + auto trigger (Downtime::GetDowntimeFromLegacyID(triggeredByLegacy)); + + if (trigger) { + triggeredBy = trigger->GetName(); + } + } for (const Host::Ptr& host : hg->GetMembers()) { Log(LogNotice, "ExternalCommandProcessor") @@ -1224,8 +1270,14 @@ void ExternalCommandProcessor::ScheduleHostgroupSvcDowntime(double, const std::v String triggeredBy; int triggeredByLegacy = Convert::ToLong(arguments[4]); int is_fixed = Convert::ToLong(arguments[3]); - if (triggeredByLegacy != 0) - triggeredBy = Downtime::GetDowntimeIDFromLegacyID(triggeredByLegacy); + + if (triggeredByLegacy != 0) { + auto trigger (Downtime::GetDowntimeFromLegacyID(triggeredByLegacy)); + + if (trigger) { + triggeredBy = trigger->GetName(); + } + } /* Note: we can't just directly create downtimes for all the services by iterating * over all hosts in the host group - otherwise we might end up creating multiple @@ -1258,8 +1310,14 @@ void ExternalCommandProcessor::ScheduleServicegroupHostDowntime(double, const st String triggeredBy; int triggeredByLegacy = Convert::ToLong(arguments[4]); int is_fixed = Convert::ToLong(arguments[3]); - if (triggeredByLegacy != 0) - triggeredBy = Downtime::GetDowntimeIDFromLegacyID(triggeredByLegacy); + + if (triggeredByLegacy != 0) { + auto trigger (Downtime::GetDowntimeFromLegacyID(triggeredByLegacy)); + + if (trigger) { + triggeredBy = trigger->GetName(); + } + } /* Note: we can't just directly create downtimes for all the hosts by iterating * over all services in the service group - otherwise we might end up creating multiple @@ -1291,8 +1349,14 @@ void ExternalCommandProcessor::ScheduleServicegroupSvcDowntime(double, const std String triggeredBy; int triggeredByLegacy = Convert::ToLong(arguments[4]); int is_fixed = Convert::ToLong(arguments[3]); - if (triggeredByLegacy != 0) - triggeredBy = Downtime::GetDowntimeIDFromLegacyID(triggeredByLegacy); + + if (triggeredByLegacy != 0) { + auto trigger (Downtime::GetDowntimeFromLegacyID(triggeredByLegacy)); + + if (trigger) { + triggeredBy = trigger->GetName(); + } + } for (const Service::Ptr& service : sg->GetMembers()) { Log(LogNotice, "ExternalCommandProcessor") From c0f87dd4c9f8244765827150027f911f7de6582e Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Wed, 24 Apr 2024 16:58:08 +0200 Subject: [PATCH 3/4] /v1/actions/schedule-downtime: reject request on invalid trigger_name For this purpose lookup the specified Downtime. Also pass Downtime objects, not just names, to Downtime::AddDowntime() not to lookup it twice. --- lib/icinga/apiactions.cpp | 26 ++++++--- lib/icinga/downtime.cpp | 10 +++- lib/icinga/downtime.hpp | 2 +- lib/icinga/externalcommandprocessor.cpp | 74 +++++++------------------ lib/icinga/scheduleddowntime.cpp | 8 +-- 5 files changed, 48 insertions(+), 72 deletions(-) diff --git a/lib/icinga/apiactions.cpp b/lib/icinga/apiactions.cpp index 885834edc..4326a8207 100644 --- a/lib/icinga/apiactions.cpp +++ b/lib/icinga/apiactions.cpp @@ -391,9 +391,16 @@ Dictionary::Ptr ApiActions::ScheduleDowntime(const ConfigObject::Ptr& object, if (params->Contains("duration")) duration = HttpUtility::GetLastParameter(params, "duration"); - String triggerName; - if (params->Contains("trigger_name")) - triggerName = HttpUtility::GetLastParameter(params, "trigger_name"); + Downtime::Ptr trigger; + String triggerName = HttpUtility::GetLastParameter(params, "trigger_name"); + + if (!triggerName.IsEmpty()) { + trigger = Downtime::GetByName(triggerName); + + if (!trigger) { + return ApiActions::CreateResult(404, "Won't schedule downtime with non-existent trigger downtime."); + } + } String author = HttpUtility::GetLastParameter(params, "author"); String comment = HttpUtility::GetLastParameter(params, "comment"); @@ -420,7 +427,7 @@ Dictionary::Ptr ApiActions::ScheduleDowntime(const ConfigObject::Ptr& object, } Downtime::Ptr downtime = Downtime::AddDowntime(checkable, author, comment, startTime, endTime, - fixed, triggerName, duration); + fixed, trigger, duration); String downtimeName = downtime->GetName(); Dictionary::Ptr additional = new Dictionary({ @@ -442,7 +449,7 @@ Dictionary::Ptr ApiActions::ScheduleDowntime(const ConfigObject::Ptr& object, << "Creating downtime for service " << hostService->GetName() << " on host " << host->GetName(); Downtime::Ptr serviceDowntime = Downtime::AddDowntime(hostService, author, comment, startTime, endTime, - fixed, triggerName, duration, String(), String(), downtimeName); + fixed, trigger, duration, String(), String(), downtimeName); String serviceDowntimeName = serviceDowntime->GetName(); serviceDowntimes.push_back(new Dictionary({ @@ -459,8 +466,9 @@ Dictionary::Ptr ApiActions::ScheduleDowntime(const ConfigObject::Ptr& object, /* 'DowntimeTriggeredChildren' schedules child downtimes triggered by the parent downtime. * 'DowntimeNonTriggeredChildren' schedules non-triggered downtimes for all children. */ - if (childOptions == DowntimeTriggeredChildren) - triggerName = downtimeName; + if (childOptions == DowntimeTriggeredChildren) { + trigger = downtime; + } Log(LogNotice, "ApiActions") << "Processing child options " << childOptions << " for downtime " << downtimeName; @@ -486,7 +494,7 @@ Dictionary::Ptr ApiActions::ScheduleDowntime(const ConfigObject::Ptr& object, << "Scheduling downtime for child object " << child->GetName(); Downtime::Ptr childDowntime = Downtime::AddDowntime(child, author, comment, startTime, endTime, - fixed, triggerName, duration); + fixed, trigger, duration); String childDowntimeName = childDowntime->GetName(); Log(LogNotice, "ApiActions") @@ -506,7 +514,7 @@ Dictionary::Ptr ApiActions::ScheduleDowntime(const ConfigObject::Ptr& object, << "Creating downtime for service " << childService->GetName() << " on child host " << childHost->GetName(); Downtime::Ptr serviceDowntime = Downtime::AddDowntime(childService, author, comment, startTime, endTime, - fixed, triggerName, duration, String(), String(), childDowntimeName); + fixed, trigger, duration, String(), String(), childDowntimeName); String serviceDowntimeName = serviceDowntime->GetName(); childServiceDowntimes.push_back(new Dictionary({ diff --git a/lib/icinga/downtime.cpp b/lib/icinga/downtime.cpp index 264382915..08c782720 100644 --- a/lib/icinga/downtime.cpp +++ b/lib/icinga/downtime.cpp @@ -245,17 +245,22 @@ int Downtime::GetNextDowntimeID() Downtime::Ptr Downtime::AddDowntime(const Checkable::Ptr& checkable, const String& author, const String& comment, double startTime, double endTime, bool fixed, - const String& triggeredBy, double duration, + const Downtime::Ptr& parentDowntime, double duration, const String& scheduledDowntime, const String& scheduledBy, const String& parent, const String& id, const MessageOrigin::Ptr& origin) { String fullName; + String triggeredBy; if (id.IsEmpty()) fullName = checkable->GetName() + "!" + Utility::NewUniqueID(); else fullName = id; + if (parentDowntime) { + triggeredBy = parentDowntime->GetName(); + } + Dictionary::Ptr attrs = new Dictionary(); attrs->Set("author", author); @@ -326,8 +331,7 @@ Downtime::Ptr Downtime::AddDowntime(const Checkable::Ptr& checkable, const Strin BOOST_THROW_EXCEPTION(std::runtime_error("Could not create downtime.")); } - if (!triggeredBy.IsEmpty()) { - Downtime::Ptr parentDowntime = Downtime::GetByName(triggeredBy); + if (parentDowntime) { Array::Ptr triggers = parentDowntime->GetTriggers(); ObjectLock olock(triggers); diff --git a/lib/icinga/downtime.hpp b/lib/icinga/downtime.hpp index f8b64d142..fa5ceee47 100644 --- a/lib/icinga/downtime.hpp +++ b/lib/icinga/downtime.hpp @@ -48,7 +48,7 @@ public: static Ptr AddDowntime(const intrusive_ptr& checkable, const String& author, const String& comment, double startTime, double endTime, bool fixed, - const String& triggeredBy, double duration, const String& scheduledDowntime = String(), + const Ptr& parentDowntime, double duration, const String& scheduledDowntime = String(), const String& scheduledBy = String(), const String& parent = String(), const String& id = String(), const MessageOrigin::Ptr& origin = nullptr); diff --git a/lib/icinga/externalcommandprocessor.cpp b/lib/icinga/externalcommandprocessor.cpp index e3c449835..d3af82eed 100644 --- a/lib/icinga/externalcommandprocessor.cpp +++ b/lib/icinga/externalcommandprocessor.cpp @@ -967,16 +967,12 @@ void ExternalCommandProcessor::ScheduleSvcDowntime(double, const std::vectorGetName(); - } + triggeredBy = Downtime::GetDowntimeFromLegacyID(triggeredByLegacy); } Log(LogNotice, "ExternalCommandProcessor") @@ -1013,16 +1009,12 @@ void ExternalCommandProcessor::ScheduleHostDowntime(double, const std::vectorGetName(); - } + triggeredBy = Downtime::GetDowntimeFromLegacyID(triggeredByLegacy); } Log(LogNotice, "ExternalCommandProcessor") @@ -1040,16 +1032,12 @@ void ExternalCommandProcessor::ScheduleAndPropagateHostDowntime(double, const st if (!host) BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot schedule and propagate host downtime for non-existent host '" + arguments[0] + "'")); - String triggeredBy; + Downtime::Ptr triggeredBy; int triggeredByLegacy = Convert::ToLong(arguments[4]); int is_fixed = Convert::ToLong(arguments[3]); if (triggeredByLegacy != 0) { - auto trigger (Downtime::GetDowntimeFromLegacyID(triggeredByLegacy)); - - if (trigger) { - triggeredBy = trigger->GetName(); - } + triggeredBy = Downtime::GetDowntimeFromLegacyID(triggeredByLegacy); } Log(LogNotice, "ExternalCommandProcessor") @@ -1082,16 +1070,12 @@ void ExternalCommandProcessor::ScheduleAndPropagateTriggeredHostDowntime(double, if (!host) BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot schedule and propagate triggered host downtime for non-existent host '" + arguments[0] + "'")); - String triggeredBy; + Downtime::Ptr triggeredBy; int triggeredByLegacy = Convert::ToLong(arguments[4]); int is_fixed = Convert::ToLong(arguments[3]); if (triggeredByLegacy != 0) { - auto trigger (Downtime::GetDowntimeFromLegacyID(triggeredByLegacy)); - - if (trigger) { - triggeredBy = trigger->GetName(); - } + triggeredBy = Downtime::GetDowntimeFromLegacyID(triggeredByLegacy); } Log(LogNotice, "ExternalCommandProcessor") @@ -1113,7 +1097,7 @@ void ExternalCommandProcessor::ScheduleAndPropagateTriggeredHostDowntime(double, (void) Downtime::AddDowntime(child, arguments[6], arguments[7], Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]), - Convert::ToBool(is_fixed), parentDowntime->GetName(), Convert::ToDouble(arguments[5])); + Convert::ToBool(is_fixed), parentDowntime, Convert::ToDouble(arguments[5])); } } @@ -1203,16 +1187,12 @@ void ExternalCommandProcessor::ScheduleHostSvcDowntime(double, const std::vector if (!host) BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot schedule host services downtime for non-existent host '" + arguments[0] + "'")); - String triggeredBy; + Downtime::Ptr triggeredBy; int triggeredByLegacy = Convert::ToLong(arguments[4]); int is_fixed = Convert::ToLong(arguments[3]); if (triggeredByLegacy != 0) { - auto trigger (Downtime::GetDowntimeFromLegacyID(triggeredByLegacy)); - - if (trigger) { - triggeredBy = trigger->GetName(); - } + triggeredBy = Downtime::GetDowntimeFromLegacyID(triggeredByLegacy); } Log(LogNotice, "ExternalCommandProcessor") @@ -1238,16 +1218,12 @@ void ExternalCommandProcessor::ScheduleHostgroupHostDowntime(double, const std:: if (!hg) BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot schedule hostgroup host downtime for non-existent hostgroup '" + arguments[0] + "'")); - String triggeredBy; + Downtime::Ptr triggeredBy; int triggeredByLegacy = Convert::ToLong(arguments[4]); int is_fixed = Convert::ToLong(arguments[3]); if (triggeredByLegacy != 0) { - auto trigger (Downtime::GetDowntimeFromLegacyID(triggeredByLegacy)); - - if (trigger) { - triggeredBy = trigger->GetName(); - } + triggeredBy = Downtime::GetDowntimeFromLegacyID(triggeredByLegacy); } for (const Host::Ptr& host : hg->GetMembers()) { @@ -1267,16 +1243,12 @@ void ExternalCommandProcessor::ScheduleHostgroupSvcDowntime(double, const std::v if (!hg) BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot schedule hostgroup service downtime for non-existent hostgroup '" + arguments[0] + "'")); - String triggeredBy; + Downtime::Ptr triggeredBy; int triggeredByLegacy = Convert::ToLong(arguments[4]); int is_fixed = Convert::ToLong(arguments[3]); if (triggeredByLegacy != 0) { - auto trigger (Downtime::GetDowntimeFromLegacyID(triggeredByLegacy)); - - if (trigger) { - triggeredBy = trigger->GetName(); - } + triggeredBy = Downtime::GetDowntimeFromLegacyID(triggeredByLegacy); } /* Note: we can't just directly create downtimes for all the services by iterating @@ -1307,16 +1279,12 @@ void ExternalCommandProcessor::ScheduleServicegroupHostDowntime(double, const st if (!sg) BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot schedule servicegroup host downtime for non-existent servicegroup '" + arguments[0] + "'")); - String triggeredBy; + Downtime::Ptr triggeredBy; int triggeredByLegacy = Convert::ToLong(arguments[4]); int is_fixed = Convert::ToLong(arguments[3]); if (triggeredByLegacy != 0) { - auto trigger (Downtime::GetDowntimeFromLegacyID(triggeredByLegacy)); - - if (trigger) { - triggeredBy = trigger->GetName(); - } + triggeredBy = Downtime::GetDowntimeFromLegacyID(triggeredByLegacy); } /* Note: we can't just directly create downtimes for all the hosts by iterating @@ -1346,16 +1314,12 @@ void ExternalCommandProcessor::ScheduleServicegroupSvcDowntime(double, const std if (!sg) BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot schedule servicegroup service downtime for non-existent servicegroup '" + arguments[0] + "'")); - String triggeredBy; + Downtime::Ptr triggeredBy; int triggeredByLegacy = Convert::ToLong(arguments[4]); int is_fixed = Convert::ToLong(arguments[3]); if (triggeredByLegacy != 0) { - auto trigger (Downtime::GetDowntimeFromLegacyID(triggeredByLegacy)); - - if (trigger) { - triggeredBy = trigger->GetName(); - } + triggeredBy = Downtime::GetDowntimeFromLegacyID(triggeredByLegacy); } for (const Service::Ptr& service : sg->GetMembers()) { diff --git a/lib/icinga/scheduleddowntime.cpp b/lib/icinga/scheduleddowntime.cpp index f23d3e436..2ad9fa80d 100644 --- a/lib/icinga/scheduleddowntime.cpp +++ b/lib/icinga/scheduleddowntime.cpp @@ -282,7 +282,7 @@ void ScheduledDowntime::CreateNextDowntime() Downtime::Ptr downtime = Downtime::AddDowntime(GetCheckable(), GetAuthor(), GetComment(), segment.first, segment.second, - GetFixed(), String(), GetDuration(), GetName(), GetName()); + GetFixed(), nullptr, GetDuration(), GetName(), GetName()); String downtimeName = downtime->GetName(); int childOptions = Downtime::ChildOptionsFromValue(GetChildOptions()); @@ -290,9 +290,9 @@ void ScheduledDowntime::CreateNextDowntime() /* 'DowntimeTriggeredChildren' schedules child downtimes triggered by the parent downtime. * 'DowntimeNonTriggeredChildren' schedules non-triggered downtimes for all children. */ - String triggerName; + Downtime::Ptr trigger; if (childOptions == 1) - triggerName = downtimeName; + trigger = downtime; Log(LogNotice, "ScheduledDowntime") << "Processing child options " << childOptions << " for downtime " << downtimeName; @@ -302,7 +302,7 @@ void ScheduledDowntime::CreateNextDowntime() << "Scheduling downtime for child object " << child->GetName(); Downtime::Ptr childDowntime = Downtime::AddDowntime(child, GetAuthor(), GetComment(), - segment.first, segment.second, GetFixed(), triggerName, GetDuration(), GetName(), GetName()); + segment.first, segment.second, GetFixed(), trigger, GetDuration(), GetName(), GetName()); Log(LogNotice, "ScheduledDowntime") << "Add child downtime '" << childDowntime->GetName() << "'."; From 5f80ac17aa1f098b1a115cd9317fa60ee8fb6dcf Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Thu, 25 Apr 2024 12:04:37 +0200 Subject: [PATCH 4/4] l_LegacyDowntimesCache: delete removed objects not to leak memory --- lib/icinga/downtime.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/icinga/downtime.cpp b/lib/icinga/downtime.cpp index 08c782720..53de3a534 100644 --- a/lib/icinga/downtime.cpp +++ b/lib/icinga/downtime.cpp @@ -148,6 +148,12 @@ void Downtime::Start(bool runtimeCreated) void Downtime::Stop(bool runtimeRemoved) { + { + std::unique_lock lock (l_DowntimeMutex); + + l_LegacyDowntimesCache.erase(GetLegacyId()); + } + GetCheckable()->UnregisterDowntime(this); Downtime::Ptr parent = GetByName(GetParent());