diff options
author | James Feist <james.feist@linux.intel.com> | 2019-06-25 21:56:49 +0300 |
---|---|---|
committer | James Feist <james.feist@linux.intel.com> | 2019-06-25 21:56:49 +0300 |
commit | ced0ff05c6cccce660331e95381c5e2c349f40c2 (patch) | |
tree | c4a1f90c2c627803be2a8474ec8a98006c018105 /callback-manager | |
parent | 2c94bc2e81402ee9682e30a9326f947f2c4b2c72 (diff) | |
download | provingground-ced0ff05c6cccce660331e95381c5e2c349f40c2.tar.xz |
Add Association Monitoring support
Based on redfish design, there is global and non global
critical / warning to monitor health. Take these and
use them to trigger the led.
Tested: Created IPMI ME health event and saw led turn
to blinking yellow
Change-Id: I0ddcd142355b148b6ae07b6d0e9274c3e99a049e
Signed-off-by: James Feist <james.feist@linux.intel.com>
Diffstat (limited to 'callback-manager')
-rw-r--r-- | callback-manager/include/callback_manager.hpp | 1 | ||||
-rw-r--r-- | callback-manager/src/callback_manager.cpp | 116 |
2 files changed, 107 insertions, 10 deletions
diff --git a/callback-manager/include/callback_manager.hpp b/callback-manager/include/callback_manager.hpp index f66cb4d..4ecdd60 100644 --- a/callback-manager/include/callback_manager.hpp +++ b/callback-manager/include/callback_manager.hpp @@ -61,7 +61,6 @@ struct AssociationManager { result.emplace(threshold::warning, "", path); } - setSensorAssociations(critical, warning); association->set_property("associations", result); } diff --git a/callback-manager/src/callback_manager.cpp b/callback-manager/src/callback_manager.cpp index ba59306..ac2fb02 100644 --- a/callback-manager/src/callback_manager.cpp +++ b/callback-manager/src/callback_manager.cpp @@ -179,14 +179,25 @@ void updateLedStatus(std::shared_ptr<sdbusplus::asio::connection>& conn, void createThresholdMatch(std::shared_ptr<sdbusplus::asio::connection>& conn) { - static std::unique_ptr<sdbusplus::bus::match::match> match = nullptr; - std::function<void(sdbusplus::message::message&)> thresholdCallback = + static sdbusplus::bus::match::match match( + static_cast<sdbusplus::bus::bus&>(*conn), + "type='signal',interface='org.freedesktop.DBus.Properties'," + "path_" + "namespace='/xyz/openbmc_project/" + "sensors',arg0namespace='xyz.openbmc_project.Sensor.Threshold'", [&conn](sdbusplus::message::message& message) { std::string objectName; boost::container::flat_map<std::string, std::variant<bool>> values; - message.read(objectName, values); + try + { + message.read(objectName, values); + } + catch (sdbusplus::exception_t&) + { + return; + } if constexpr (debug) { std::cerr << "Threshold callback " << message.get_path() @@ -219,16 +230,102 @@ void createThresholdMatch(std::shared_ptr<sdbusplus::asio::connection>& conn) warningAssertMap[message.get_path()]["High"] = std::get<bool>(findWarnHigh->second); } + + associationManager->setSensorAssociations( + assertedInMap(criticalAssertMap), + assertedInMap(warningAssertMap)); + updateLedStatus(conn); - }; + }); +} - match = std::make_unique<sdbusplus::bus::match::match>( +void createAssociationMatch(std::shared_ptr<sdbusplus::asio::connection>& conn) +{ + static sdbusplus::bus::match::match match( static_cast<sdbusplus::bus::bus&>(*conn), "type='signal',interface='org.freedesktop.DBus.Properties'," - "path_" - "namespace='/xyz/openbmc_project/" - "sensors',arg0namespace='xyz.openbmc_project.Sensor.Threshold'", - thresholdCallback); + "arg0namespace='" + + std::string(associationIface) + "'", + [&conn](sdbusplus::message::message& message) { + if (message.get_path() == rootPath) + { + return; // it's us + } + std::string objectName; + boost::container::flat_map<std::string, + std::variant<std::vector<Association>>> + values; + try + { + message.read(objectName, values); + } + catch (sdbusplus::exception_t&) + { + return; + } + + if constexpr (debug) + { + std::cerr << "Association callback " << message.get_path() + << "\n"; + } + + auto findAssociations = values.find("associations"); + if (findAssociations == values.end()) + { + return; + } + const std::vector<Association>* associations = + std::get_if<std::vector<Association>>( + &findAssociations->second); + + if (associations == nullptr) + { + std::cerr << "Illegal Association on " << message.get_path() + << "\n"; + return; + } + + bool localWarning = false; + bool localCritical = false; + bool globalWarning = false; + bool globalCritical = false; + + for (const auto& [forward, reverse, path] : *associations) + { + if (path == rootPath) + { + globalWarning = globalWarning ? true : reverse == "warning"; + globalCritical = + globalCritical ? true : reverse == "critical"; + + if constexpr (1) + { + std::cerr << "got global "; + } + } + else + { + localWarning = localWarning ? true : reverse == "warning"; + localCritical = + localCritical ? true : reverse == "critical"; + } + if (globalCritical && localCritical) + { + break; + } + } + + bool fatal = globalCritical && localCritical; + bool critical = globalWarning && localCritical; + bool warning = globalWarning && localWarning; + + fatalAssertMap[message.get_path()]["association"] = fatal; + criticalAssertMap[message.get_path()]["association"] = critical; + warningAssertMap[message.get_path()]["association"] = warning; + + updateLedStatus(conn); + }); } int main(int argc, char** argv) @@ -251,6 +348,7 @@ int main(int argc, char** argv) associationManager = std::make_unique<AssociationManager>(objServer, conn); createThresholdMatch(conn); + createAssociationMatch(conn); updateLedStatus(conn); io.run(); |