summaryrefslogtreecommitdiffstats
path: root/extensions/openpower-pels/log_id.cpp
diff options
context:
space:
mode:
authorMatt Spinler <spinler@us.ibm.com>2019-07-10 16:54:13 -0500
committerMatt Spinler <spinler@us.ibm.com>2019-07-26 13:43:04 -0500
commitdf13bdb6e1423b25e7b737f4bf431af3d5c08d8b (patch)
treef8b9d42b3c78d018e83a5b3fcb4014e57d690281 /extensions/openpower-pels/log_id.cpp
parent03c1d91559b3e9625d21ad96f93e2d8376cfa1d4 (diff)
downloadphosphor-logging-df13bdb6e1423b25e7b737f4bf431af3d5c08d8b.tar.gz
phosphor-logging-df13bdb6e1423b25e7b737f4bf431af3d5c08d8b.zip
PEL: Add function to generate unique PEL IDs
Create generatePELID() to return a unique 4B PEL ID every time it is called. It will start at a base value, and then increment by 1 each time. It uses a file to save the next value to use. This will be used by the PEL handling code to create unique values for the error log ID field in the Private Header section. Signed-off-by: Matt Spinler <spinler@us.ibm.com> Change-Id: I841a8dcc5dc48e2b663004be3dccfb114ba366f2
Diffstat (limited to 'extensions/openpower-pels/log_id.cpp')
-rw-r--r--extensions/openpower-pels/log_id.cpp97
1 files changed, 97 insertions, 0 deletions
diff --git a/extensions/openpower-pels/log_id.cpp b/extensions/openpower-pels/log_id.cpp
new file mode 100644
index 0000000..cbe1247
--- /dev/null
+++ b/extensions/openpower-pels/log_id.cpp
@@ -0,0 +1,97 @@
+#include "log_id.hpp"
+
+#include "paths.hpp"
+
+#include <chrono>
+#include <filesystem>
+#include <fstream>
+#include <phosphor-logging/log.hpp>
+
+namespace openpower
+{
+namespace pels
+{
+
+namespace fs = std::filesystem;
+using namespace phosphor::logging;
+
+constexpr uint32_t startingLogID = 1;
+constexpr uint32_t bmcLogIDPrefix = 0x50000000;
+
+namespace detail
+{
+
+uint32_t addLogIDPrefix(uint32_t id)
+{
+ // If redundant BMCs are ever a thing, may need a different prefix.
+ return (id & 0x00FFFFFF) | bmcLogIDPrefix;
+}
+
+uint32_t getTimeBasedLogID()
+{
+ using namespace std::chrono;
+
+ // Use 3 bytes of the nanosecond count since the epoch.
+ uint32_t id =
+ duration_cast<nanoseconds>(system_clock::now().time_since_epoch())
+ .count();
+
+ return addLogIDPrefix(id);
+}
+
+} // namespace detail
+
+uint32_t generatePELID()
+{
+ // Note: there isn't a need to be thread safe.
+
+ static std::string idFilename;
+ if (idFilename.empty())
+ {
+ idFilename = getPELIDFile();
+ }
+
+ uint32_t id = 0;
+
+ if (!fs::exists(idFilename))
+ {
+ auto path = fs::path(idFilename).parent_path();
+ if (!fs::exists(path))
+ {
+ fs::create_directories(path);
+ }
+
+ id = startingLogID;
+ }
+ else
+ {
+ std::ifstream idFile{idFilename};
+ idFile >> id;
+ if (idFile.fail())
+ {
+ // Just make up an ID
+ log<level::ERR>("Unable to read PEL ID File!");
+ return detail::getTimeBasedLogID();
+ }
+ }
+
+ // Wrapping shouldn't be a problem, but check anyway
+ if (id == 0x00FFFFFF)
+ {
+ id = startingLogID;
+ }
+
+ std::ofstream idFile{idFilename};
+ idFile << (id + 1);
+ if (idFile.fail())
+ {
+ // Just make up an ID so we don't reuse one next time
+ log<level::ERR>("Unable to write PEL ID File!");
+ return detail::getTimeBasedLogID();
+ }
+
+ return detail::addLogIDPrefix(id);
+}
+
+} // namespace pels
+} // namespace openpower
OpenPOWER on IntegriCloud