diff --git a/lib/icinga/checkable-dependency.cpp b/lib/icinga/checkable-dependency.cpp index 58d6b578bb..e059599780 100644 --- a/lib/icinga/checkable-dependency.cpp +++ b/lib/icinga/checkable-dependency.cpp @@ -55,11 +55,6 @@ bool Checkable::IsReachable(DependencyType dt, Dependency::Ptr *failedDependency return false; } - for (const Checkable::Ptr& checkable : GetParents()) { - if (!checkable->IsReachable(dt, failedDependency, rstack + 1)) - return false; - } - /* implicit dependency on host if this is a service */ const auto *service = dynamic_cast(this); if (service && (dt == DependencyState || dt == DependencyNotification)) { @@ -78,9 +73,13 @@ bool Checkable::IsReachable(DependencyType dt, Dependency::Ptr *failedDependency std::unordered_map violated; // key: redundancy group, value: nullptr if satisfied, violating dependency otherwise for (const Dependency::Ptr& dep : deps) { - std::string redundancy_group = dep->GetRedundancyGroup(); + bool parentReachable{true}; + if (auto parent = dep->GetParent()) { + parentReachable = parent->IsReachable(dt, failedDependency, rstack + 1); + } - if (!dep->IsAvailable(dt)) { + std::string redundancy_group = dep->GetRedundancyGroup(); + if (!parentReachable || !dep->IsAvailable(dt)) { if (redundancy_group.empty()) { Log(LogDebug, "Checkable") << "Non-redundant dependency '" << dep->GetName() << "' failed for checkable '" << GetName() << "': Marking as unreachable."; @@ -92,7 +91,7 @@ bool Checkable::IsReachable(DependencyType dt, Dependency::Ptr *failedDependency } // tentatively mark this dependency group as failed unless it is already marked; - // so it either passed before (don't overwrite) or already failed (so don't care) + // so it either passed before (don't overwrite) or already failed (so don't care) // note that std::unordered_map::insert() will not overwrite an existing entry violated.insert(std::make_pair(redundancy_group, dep)); } else if (!redundancy_group.empty()) {