callback-manager: Add association manager
This adds an association manager based on Redfish health
whitepaper to do a rollup of subcomponent health.
https://gerrit.openbmc-project.xyz/c/openbmc/docs/+/21380
Tested:
Chassis health rollup works with upstream patch 21798
{
"@odata.context": "/redfish/v1/$metadata#Chassis.Chassis",
"@odata.id": "/redfish/v1/Chassis/WFP_Baseboard",
"@odata.type": "#Chassis.v1_4_0.Chassis",
"ChassisType": "RackMount",
"Id": "WFP_Baseboard",
"Links": {
"ComputerSystems": [
{
"@odata.id": "/redfish/v1/Systems/system"
}
],
"ManagedBy": [
{
"@odata.id": "/redfish/v1/Managers/bmc"
}
]
},
"Manufacturer": "Intel Corporation",
"Model": "S2600WFT",
"Name": "WFP_Baseboard",
"PartNumber": "123456789",
"Power": {
"@odata.id": "/redfish/v1/Chassis/WFP_Baseboard/Power"
},
"PowerState": "Off",
"SerialNumber": "123454321",
"Status": {
"Health": "Warning",
"HealthRollup": "Critical",
"State": "StandbyOffline"
},
"Thermal": {
"@odata.id": "/redfish/v1/Chassis/WFP_Baseboard/Thermal"
}
}
Change-Id: I1d944f31749f6eae952573078ad410547ae9faea
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
new file mode 100644
index 0000000..f66cb4d
--- /dev/null
+++ b/callback-manager/include/callback_manager.hpp
@@ -0,0 +1,94 @@
+#pragma once
+
+#include <boost/algorithm/string/predicate.hpp>
+#include <iostream>
+#include <sdbusplus/asio/connection.hpp>
+#include <sdbusplus/asio/object_server.hpp>
+
+using Association = std::tuple<std::string, std::string, std::string>;
+
+constexpr const char* rootPath = "/xyz/openbmc_project/CallbackManager";
+constexpr const char* sensorPath = "/xyz/openbmc_project/sensors";
+
+constexpr const char* globalInventoryIface =
+ "xyz.openbmc_project.Inventory.Item.Global";
+constexpr const char* associationIface = "org.openbmc.Associations";
+
+namespace threshold
+{
+constexpr const char* critical = "critical";
+constexpr const char* warning = "warning";
+} // namespace threshold
+
+struct AssociationManager
+{
+ AssociationManager(sdbusplus::asio::object_server& objectServer,
+ std::shared_ptr<sdbusplus::asio::connection>& conn) :
+ objectServer(objectServer),
+ association(objectServer.add_interface(rootPath, associationIface)),
+ sensorAssociation(
+ objectServer.add_interface(sensorPath, associationIface))
+ {
+ association->register_property("associations", std::set<Association>());
+ sensorAssociation->register_property("associations",
+ std::set<Association>());
+ association->initialize();
+ sensorAssociation->initialize();
+ }
+ ~AssociationManager()
+ {
+ objectServer.remove_interface(association);
+ objectServer.remove_interface(sensorAssociation);
+ }
+
+ void setLocalAssociations(const std::vector<std::string>& fatal,
+ const std::vector<std::string>& critical,
+ const std::vector<std::string>& warning)
+ {
+ std::set<Association> result;
+
+ // fatal maps to redfish critical as refish only has 3 states and LED
+ // has 4
+ for (const std::string& path : fatal)
+ {
+ result.emplace(threshold::critical, "", path);
+ }
+ for (const std::string& path : critical)
+ {
+ result.emplace(threshold::warning, "", path);
+ }
+ for (const std::string& path : warning)
+ {
+ result.emplace(threshold::warning, "", path);
+ }
+ setSensorAssociations(critical, warning);
+ association->set_property("associations", result);
+ }
+
+ void setSensorAssociations(const std::vector<std::string>& critical,
+ const std::vector<std::string>& warning)
+ {
+ std::set<Association> result;
+ for (const std::string& path : critical)
+ {
+ if (!boost::starts_with(path, sensorPath))
+ {
+ continue;
+ }
+ result.emplace(threshold::critical, "", path);
+ }
+ for (const std::string& path : warning)
+ {
+ if (!boost::starts_with(path, sensorPath))
+ {
+ continue;
+ }
+ result.emplace(threshold::warning, "", path);
+ }
+ sensorAssociation->set_property("associations", result);
+ }
+
+ sdbusplus::asio::object_server& objectServer;
+ std::shared_ptr<sdbusplus::asio::dbus_interface> association;
+ std::shared_ptr<sdbusplus::asio::dbus_interface> sensorAssociation;
+};
\ No newline at end of file
diff --git a/callback-manager/src/callback_manager.cpp b/callback-manager/src/callback_manager.cpp
index 34506d9..ba59306 100644
--- a/callback-manager/src/callback_manager.cpp
+++ b/callback-manager/src/callback_manager.cpp
@@ -14,8 +14,9 @@
// limitations under the License.
*/
+#include "callback_manager.hpp"
+
#include <boost/container/flat_map.hpp>
-#include <iostream>
#include <sdbusplus/asio/connection.hpp>
#include <sdbusplus/asio/object_server.hpp>
#include <variant>
@@ -33,6 +34,8 @@
constexpr const char* ledManagerBusname =
"xyz.openbmc_project.LED.GroupManager";
+std::unique_ptr<AssociationManager> associationManager;
+
enum class StatusSetting
{
none,
@@ -42,8 +45,6 @@
fatal
};
-std::shared_ptr<sdbusplus::asio::dbus_interface> assertedIface = nullptr;
-
constexpr const bool debug = false;
// final led state tracking
@@ -82,18 +83,17 @@
void updateLedStatus(std::shared_ptr<sdbusplus::asio::connection>& conn,
bool forceRefresh = false)
{
- std::vector<std::string> assertedVector = assertedInMap(fatalAssertMap);
- assertedIface->set_property("Fatal", assertedVector);
- bool fatal = assertedVector.size();
+ std::vector<std::string> fatalVector = assertedInMap(fatalAssertMap);
+ bool fatal = fatalVector.size();
- assertedVector = assertedInMap(criticalAssertMap);
- assertedIface->set_property("Critical", assertedVector);
- bool critical = assertedVector.size();
+ std::vector<std::string> criticalVector = assertedInMap(criticalAssertMap);
+ bool critical = criticalVector.size();
- assertedVector = assertedInMap(warningAssertMap);
- assertedIface->set_property("Warning", assertedVector);
+ std::vector<std::string> warningVector = assertedInMap(warningAssertMap);
+ bool warn = warningVector.size();
- bool warn = assertedVector.size();
+ associationManager->setLocalAssociations(fatalVector, criticalVector,
+ warningVector);
StatusSetting last = currentPriority;
@@ -237,15 +237,18 @@
auto conn = std::make_shared<sdbusplus::asio::connection>(io);
conn->request_name("xyz.openbmc_project.CallbackManager");
sdbusplus::asio::object_server objServer(conn);
- assertedIface =
- objServer.add_interface("/xyz/openbmc_project/CallbackManager",
+ std::shared_ptr<sdbusplus::asio::dbus_interface> rootIface =
+ objServer.add_interface(rootPath,
"xyz.openbmc_project.CallbackManager");
- assertedIface->register_property("Warning", std::vector<std::string>());
- assertedIface->register_property("Critical", std::vector<std::string>());
- assertedIface->register_property("Fatal", std::vector<std::string>());
- assertedIface->register_method("RetriggerLEDUpdate",
- [&conn]() { updateLedStatus(conn, true); });
- assertedIface->initialize();
+ rootIface->register_method("RetriggerLEDUpdate",
+ [&conn]() { updateLedStatus(conn, true); });
+ rootIface->initialize();
+
+ std::shared_ptr<sdbusplus::asio::dbus_interface> inventoryIface =
+ objServer.add_interface(rootPath, globalInventoryIface);
+ inventoryIface->initialize();
+
+ associationManager = std::make_unique<AssociationManager>(objServer, conn);
createThresholdMatch(conn);
updateLedStatus(conn);