PEL: Run a user defined function on every PEL
Add a for_each() function to the PEL repository that takes a user
defined function that will be run on every PEL, unless that function
says to stop early.
The user defined function is a std::function<bool>(const PEL&);
For example, to save up to 100 IDs in the repo into a vector:
std::vector<uint32_t> ids;
ForEachFunc f = [&ids](const PEL& pel) {
ids.push_back(pel.id());
return ids.size() == 100 ? true : false;
};
repo.for_each(f);
This will be used to find which PELs still need to be sent up to the
host after a reboot, among other things.
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: Ic60525a8ab3dd593ba37e43a6cb0b3db8dda7cee
diff --git a/extensions/openpower-pels/repository.cpp b/extensions/openpower-pels/repository.cpp
index 81832dd..21b0243 100644
--- a/extensions/openpower-pels/repository.cpp
+++ b/extensions/openpower-pels/repository.cpp
@@ -162,5 +162,41 @@
return std::nullopt;
}
+void Repository::for_each(ForEachFunc func) const
+{
+ for (const auto& [id, path] : _idsToPELs)
+ {
+ std::ifstream file{path};
+
+ if (!file.good())
+ {
+ auto e = errno;
+ log<level::ERR>("Repository::for_each: Unable to open PEL file",
+ entry("ERRNO=%d", e),
+ entry("PATH=%s", path.c_str()));
+ continue;
+ }
+
+ std::vector<uint8_t> data{std::istreambuf_iterator<char>(file),
+ std::istreambuf_iterator<char>()};
+ file.close();
+
+ PEL pel{data};
+
+ try
+ {
+ if (func(pel))
+ {
+ break;
+ }
+ }
+ catch (std::exception& e)
+ {
+ log<level::ERR>("Repository::for_each function exception",
+ entry("ERROR=%s", e.what()));
+ }
+ }
+}
+
} // namespace pels
} // namespace openpower