PEL: Fix for error - unable to read PEL ID file

This is a case when PEL daemon can't read pelID file to get the next
pel Id to use. It could be that the file got corrupted during code
update or factory reset leading to zeros data in file. The fix is to
delete the file as there is already code later to recreate file if
not available.

Signed-off-by: Sumit Kumar <sumit_kumar@in.ibm.com>
Change-Id: I42372cc1d79ece5914e7fdb51f3fa2a2d9cb07e7
diff --git a/extensions/openpower-pels/log_id.cpp b/extensions/openpower-pels/log_id.cpp
index debcc99..ee215c2 100644
--- a/extensions/openpower-pels/log_id.cpp
+++ b/extensions/openpower-pels/log_id.cpp
@@ -64,6 +64,7 @@
     if (idFilename.empty())
     {
         idFilename = getPELIDFile();
+        checkFileForZeroData(idFilename);
     }
 
     uint32_t id = 0;
@@ -108,5 +109,26 @@
     return detail::addLogIDPrefix(id);
 }
 
+void checkFileForZeroData(const std::string& filename)
+{
+    if (fs::exists(filename))
+    {
+        char ch;
+
+        std::ifstream rf{filename, std::ios::binary};
+        rf.read(&ch, sizeof(ch));
+        while (ch == '\0')
+        {
+            if (rf.eof())
+            {
+                fs::remove(filename);
+                log<level::WARNING>(
+                    "PEL ID file seems corrupted. Deleting it.");
+                break;
+            }
+            rf.read(&ch, sizeof(ch));
+        }
+    }
+}
 } // namespace pels
 } // namespace openpower
diff --git a/extensions/openpower-pels/log_id.hpp b/extensions/openpower-pels/log_id.hpp
index 21f04eb..7318711 100644
--- a/extensions/openpower-pels/log_id.hpp
+++ b/extensions/openpower-pels/log_id.hpp
@@ -1,6 +1,7 @@
 #pragma once
 
 #include <cstdint>
+#include <string>
 
 namespace openpower
 {
@@ -43,5 +44,11 @@
  */
 uint32_t generatePELID();
 
+/**
+ * @brief Check for file containing zero data.
+ *
+ */
+void checkFileForZeroData(const std::string& filename);
+
 } // namespace pels
 } // namespace openpower
diff --git a/test/openpower-pels/log_id_test.cpp b/test/openpower-pels/log_id_test.cpp
index 7167dd7..9588b07 100644
--- a/test/openpower-pels/log_id_test.cpp
+++ b/test/openpower-pels/log_id_test.cpp
@@ -20,6 +20,7 @@
 
 #include <chrono>
 #include <filesystem>
+#include <fstream>
 #include <thread>
 
 #include <gtest/gtest.h>
@@ -58,3 +59,39 @@
 
     fs::remove_all(fs::path{backingFile}.parent_path());
 }
+
+TEST(LogIdTest, PELIDTest)
+{
+    // Get PEL ID file updated with binary zeros
+    auto backingFile = getPELIDFile();
+    std::ofstream wf{backingFile, std::ios::binary};
+    char id = '\0';
+    for (int i = 0; i < 4; i++)
+    {
+        wf.write(&id, sizeof(id));
+    }
+    wf.close();
+
+    // Expect existing PEL ID file to be deleted and
+    // new PEL ID regenerated
+    EXPECT_EQ(generatePELID(), 0x50000001);
+    EXPECT_EQ(generatePELID(), 0x50000002);
+    EXPECT_EQ(generatePELID(), 0x50000003);
+    EXPECT_EQ(generatePELID(), 0x50000004);
+    EXPECT_EQ(generatePELID(), 0x50000005);
+
+    // Get PEL ID file updated with binary zeros again
+    std::ofstream fw{backingFile, std::ios::binary};
+    for (int i = 0; i < 4; i++)
+    {
+        fw.write(&id, sizeof(id));
+    }
+    fw.close();
+
+    // This time PEL IDs are random generated
+    EXPECT_NE(generatePELID(), 0x50000001);
+    EXPECT_NE(generatePELID(), 0x50000002);
+    EXPECT_NE(generatePELID(), 0x50000003);
+    EXPECT_NE(generatePELID(), 0x50000004);
+    EXPECT_NE(generatePELID(), 0x50000005);
+}