Add Group Event Support for PSU
Some group events such as PSU Fan Fault will only have one event but
have more than one target to trigger redfish log. For example, PSU Fan
only has one event PSU Fan Fault, any Fan failure will trigger PSU Fan
Fault and change the functional property to false. But if another PSU
Fan failure happens, we still need to trigger a redfish log to indicate
the specific fan number. So change the PSU Event logic to support this
feature.
Tested:
Remove one of the PSU, Redfish Log show PSU Fan Fault on Fan1 and Fan2.
Insert the PSU and Redfish Log show PSU Fan1 and Fan2 recovered.
Signed-off-by: Cheng C Yang <cheng.c.yang@linux.intel.com>
Change-Id: I1a21d5a2a8172183b05b37a5ef747bd4f3510368
diff --git a/include/PSUEvent.hpp b/include/PSUEvent.hpp
index 89840a3..71fd5d0 100644
--- a/include/PSUEvent.hpp
+++ b/include/PSUEvent.hpp
@@ -28,7 +28,7 @@
public:
PSUSubEvent(std::shared_ptr<sdbusplus::asio::dbus_interface> eventInterface,
const std::string& path, boost::asio::io_service& io,
- const std::string& eventName,
+ const std::string& groupEventName, const std::string& eventName,
std::shared_ptr<std::set<std::string>> asserts,
std::shared_ptr<std::set<std::string>> combineEvent,
std::shared_ptr<bool> state, const std::string& psuName);
@@ -44,6 +44,7 @@
size_t errCount;
std::string path;
std::string eventName;
+ std::string groupEventName;
boost::asio::deadline_timer waitTimer;
boost::asio::streambuf readBuf;
void setupRead(void);
@@ -66,6 +67,10 @@
boost::asio::io_service& io, const std::string& psuName,
boost::container::flat_map<std::string, std::vector<std::string>>&
eventPathList,
+ boost::container::flat_map<
+ std::string,
+ boost::container::flat_map<std::string, std::vector<std::string>>>&
+ groupEventPathList,
const std::string& combineEventName);
~PSUCombineEvent();
diff --git a/src/PSUEvent.cpp b/src/PSUEvent.cpp
index 8980d53..bfe0776 100644
--- a/src/PSUEvent.cpp
+++ b/src/PSUEvent.cpp
@@ -34,6 +34,10 @@
const std::string& psuName,
boost::container::flat_map<std::string, std::vector<std::string>>&
eventPathList,
+ boost::container::flat_map<
+ std::string,
+ boost::container::flat_map<std::string, std::vector<std::string>>>&
+ groupEventPathList,
const std::string& combineEventName) :
objServer(objectServer)
{
@@ -54,23 +58,52 @@
{
std::shared_ptr<std::set<std::string>> assert =
std::make_shared<std::set<std::string>>();
+ std::shared_ptr<bool> state = std::make_shared<bool>(false);
const std::string& eventName = pathList.first;
std::string eventPSUName = eventName + psuName;
for (const auto& path : pathList.second)
{
- std::shared_ptr<bool> state = std::make_shared<bool>(false);
events[eventPSUName].emplace_back(std::make_unique<PSUSubEvent>(
- eventInterface, path, io, eventName, assert, combineEvent,
- state, psuName));
+ eventInterface, path, io, eventName, eventName, assert,
+ combineEvent, state, psuName));
asserts.emplace_back(assert);
states.emplace_back(state);
}
}
+
+ for (const auto& groupPathList : groupEventPathList)
+ {
+ for (const auto& pathList : groupPathList.second)
+ {
+ std::shared_ptr<std::set<std::string>> assert =
+ std::make_shared<std::set<std::string>>();
+ std::shared_ptr<bool> state = std::make_shared<bool>(false);
+
+ const std::string& groupEventName = pathList.first;
+ std::string eventPSUName = groupEventName + psuName;
+ for (const auto& path : pathList.second)
+ {
+ events[eventPSUName].emplace_back(std::make_unique<PSUSubEvent>(
+ eventInterface, path, io, groupEventName,
+ groupPathList.first, assert, combineEvent, state, psuName));
+ asserts.emplace_back(assert);
+ states.emplace_back(state);
+ }
+ }
+ }
}
PSUCombineEvent::~PSUCombineEvent()
{
+ // Clear unique_ptr first
+ for (auto& event : events)
+ {
+ for (auto& subEventPtr : event.second)
+ {
+ subEventPtr.reset();
+ }
+ }
events.clear();
objServer.remove_interface(eventInterface);
}
@@ -96,14 +129,15 @@
PSUSubEvent::PSUSubEvent(
std::shared_ptr<sdbusplus::asio::dbus_interface> eventInterface,
const std::string& path, boost::asio::io_service& io,
- const std::string& eventName,
+ const std::string& groupEventName, const std::string& eventName,
std::shared_ptr<std::set<std::string>> asserts,
std::shared_ptr<std::set<std::string>> combineEvent,
std::shared_ptr<bool> state, const std::string& psuName) :
eventInterface(eventInterface),
asserts(asserts), combineEvent(combineEvent), assertState(state),
errCount(0), path(path), eventName(eventName), waitTimer(io),
- inputDev(io, open(path.c_str(), O_RDONLY)), psuName(psuName)
+ inputDev(io, open(path.c_str(), O_RDONLY)), psuName(psuName),
+ groupEventName(groupEventName)
{
auto found = logID.find(eventName);
if (found == logID.end())
@@ -223,12 +257,12 @@
if (*assertState == true)
{
*assertState = false;
- auto foundCombine = (*combineEvent).find(eventName);
+ auto foundCombine = (*combineEvent).find(groupEventName);
if (foundCombine == (*combineEvent).end())
{
return;
}
- (*combineEvent).erase(eventName);
+ (*combineEvent).erase(groupEventName);
if (!deassertMessage.empty())
{
// Fan Failed has two args
@@ -287,7 +321,7 @@
{
eventInterface->set_property("functional", false);
}
- (*combineEvent).emplace(eventName);
+ (*combineEvent).emplace(groupEventName);
}
(*asserts).emplace(path);
}
diff --git a/src/PSUSensorMain.cpp b/src/PSUSensorMain.cpp
index a2c3de4..141b2ea 100644
--- a/src/PSUSensorMain.cpp
+++ b/src/PSUSensorMain.cpp
@@ -61,6 +61,10 @@
static boost::container::flat_map<std::string, std::string> pwmTable;
static boost::container::flat_map<std::string, std::vector<std::string>>
eventMatch;
+static boost::container::flat_map<
+ std::string,
+ boost::container::flat_map<std::string, std::vector<std::string>>>
+ groupEventMatch;
static boost::container::flat_map<std::string, std::vector<std::string>>
limitEventMatch;
@@ -95,6 +99,46 @@
}
}
+// Check Group Events which contains more than one targets in each combine
+// events.
+void checkGroupEvent(
+ const std::string& directory,
+ const boost::container::flat_map<
+ std::string,
+ boost::container::flat_map<std::string, std::vector<std::string>>>&
+ groupEventMatch,
+ boost::container::flat_map<
+ std::string,
+ boost::container::flat_map<std::string, std::vector<std::string>>>&
+ groupEventPathList)
+{
+ for (const auto& match : groupEventMatch)
+ {
+ const std::string& groupEventName = match.first;
+ const boost::container::flat_map<std::string, std::vector<std::string>>
+ events = match.second;
+ boost::container::flat_map<std::string, std::vector<std::string>>
+ pathList;
+ for (const auto& match : events)
+ {
+ const std::string& eventName = match.first;
+ const std::vector<std::string>& eventAttrs = match.second;
+ for (const auto& eventAttr : eventAttrs)
+ {
+ auto eventPath = directory + "/" + eventAttr;
+ std::ifstream eventFile(eventPath);
+ if (!eventFile.good())
+ {
+ continue;
+ }
+
+ pathList[eventName].push_back(eventPath);
+ }
+ }
+ groupEventPathList[groupEventName] = pathList;
+ }
+}
+
// Function checkEventLimits will check all the psu related xxx_input attributes
// in sysfs to see if xxx_crit_alarm xxx_lcrit_alarm xxx_max_alarm
// xxx_min_alarm exist, then store the existing paths of the alarm attributes
@@ -192,6 +236,10 @@
{
boost::container::flat_map<std::string, std::vector<std::string>>
eventPathList;
+ boost::container::flat_map<
+ std::string,
+ boost::container::flat_map<std::string, std::vector<std::string>>>
+ groupEventPathList;
std::ifstream nameFile(pmbusPath);
if (!nameFile.good())
@@ -331,6 +379,8 @@
continue;
}
checkEvent(directory.string(), eventMatch, eventPathList);
+ checkGroupEvent(directory.string(), groupEventMatch,
+ groupEventPathList);
/* Check if there are more sensors in the same interface */
int i = 1;
@@ -680,8 +730,9 @@
// OperationalStatus event
combineEvents[*psuName + "OperationalStatus"] = nullptr;
combineEvents[*psuName + "OperationalStatus"] =
- std::make_unique<PSUCombineEvent>(
- objectServer, io, *psuName, eventPathList, "OperationalStatus");
+ std::make_unique<PSUCombineEvent>(objectServer, io, *psuName,
+ eventPathList, groupEventPathList,
+ "OperationalStatus");
}
if constexpr (DEBUG)
@@ -740,12 +791,14 @@
limitEventMatch = {{"PredictiveFailure", {"max_alarm", "min_alarm"}},
{"Failure", {"crit_alarm", "lcrit_alarm"}}};
- eventMatch = {
- {"PredictiveFailure", {"power1_alarm"}},
- {"Failure", {"in2_alarm"}},
- {"ACLost", {"in1_beep"}},
- {"FanFault", {"fan1_alarm", "fan2_alarm", "fan1_fault", "fan2_fault"}},
- {"ConfigureError", {"in1_fault"}}};
+ eventMatch = {{"PredictiveFailure", {"power1_alarm"}},
+ {"Failure", {"in2_alarm"}},
+ {"ACLost", {"in1_beep"}},
+ {"ConfigureError", {"in1_fault"}}};
+
+ groupEventMatch = {{"FanFault",
+ {{"fan1", {"fan1_alarm", "fan1_fault"}},
+ {"fan2", {"fan2_alarm", "fan2_fault"}}}}};
}
int main()