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>
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 @@
{
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 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 @@
warningAssertMap[message.get_path()]["High"] =
std::get<bool>(findWarnHigh->second);
}
- updateLedStatus(conn);
- };
- match = std::make_unique<sdbusplus::bus::match::match>(
+ associationManager->setSensorAssociations(
+ assertedInMap(criticalAssertMap),
+ assertedInMap(warningAssertMap));
+
+ updateLedStatus(conn);
+ });
+}
+
+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 @@
associationManager = std::make_unique<AssociationManager>(objServer, conn);
createThresholdMatch(conn);
+ createAssociationMatch(conn);
updateLedStatus(conn);
io.run();