Add PostCodeDataVersion to the persisted data

Commit `06b1dbe9c768adf8921e4c1cb915538486b5a7ca` changed the
serialized format of `PostCodeData` without providing backward or
forward compatibility.

Previously, persisted data was stored as a `uint64_t`, whereas the
updated code now expects a `vector<uint8_t>`. When the new code
attempts to deserialize old data, Cereal interprets the `uint64_t`
value as the vector size, resulting in excessively large allocations
and out-of-memory errors during BMC initialization.

This commit introduces a `PostCodeDataVersion` field in the serialized
file. On startup, `post-code-manager` checks this version before
deserialization and discards outdated data if the version does not
match, ensuring a clean start without triggering memory issues.

Tested:
Verified that legacy persisted data is detected and discarded, allowing
`post-code-manager` to initialize with fresh data. No out-of-memory
conditions observed.

Change-Id: I698556a1b9781d7d869daf18348bdcf6ec82d6a7
Signed-off-by: Manojkiran Eda <manojkiran.eda@gmail.com>
diff --git a/inc/post_code.hpp b/inc/post_code.hpp
index 5a3895e..7003af4 100644
--- a/inc/post_code.hpp
+++ b/inc/post_code.hpp
@@ -42,6 +42,8 @@
     "/var/lib/phosphor-post-code-manager/host";
 const static constexpr char* HostStatePathPrefix =
     "/xyz/openbmc_project/state/host";
+const static constexpr char* PostCodeDataVersionName = "PostCodeDataVersion";
+const static constexpr uint16_t PostCodeDataVersion = 1;
 
 struct EventDeleter
 {
@@ -148,11 +150,26 @@
         phosphor::logging::log<phosphor::logging::level::INFO>(
             "PostCode is created");
         fs::create_directories(postCodeListPath);
-        deserialize(postCodeListPath / CurrentBootCycleIndexName,
-                    currentBootCycleIndex);
-        uint16_t count = 0;
-        deserialize(postCodeListPath / CurrentBootCycleCountName, count);
-        currentBootCycleCount(count);
+        uint16_t version = 0;
+        if (!deserialize(postCodeListPath / PostCodeDataVersionName, version) ||
+            version != PostCodeDataVersion)
+        {
+            phosphor::logging::log<phosphor::logging::level::INFO>(
+                "This version of post code data is not supported");
+            fs::remove_all(postCodeListPath);
+            fs::create_directories(postCodeListPath);
+            postCodes.clear();
+            currentBootCycleIndex = 0;
+            currentBootCycleCount(0);
+        }
+        else
+        {
+            deserialize(postCodeListPath / CurrentBootCycleIndexName,
+                        currentBootCycleIndex);
+            uint16_t count = 0;
+            deserialize(postCodeListPath / CurrentBootCycleCountName, count);
+            currentBootCycleCount(count);
+        }
         maxBootCycleNum(MAX_BOOT_CYCLE_COUNT);
     }
     ~PostCode() {}
diff --git a/src/post_code.cpp b/src/post_code.cpp
index 23f0a4f..31bd8d1 100644
--- a/src/post_code.cpp
+++ b/src/post_code.cpp
@@ -297,6 +297,11 @@
         std::ofstream osPostCodes(path / std::to_string(currentBootCycleIndex));
         cereal::BinaryOutputArchive oarchivePostCodes(osPostCodes);
         oarchivePostCodes(postCodes);
+
+        std::ofstream osVersion(path / PostCodeDataVersionName,
+                                std::ios::binary);
+        cereal::BinaryOutputArchive versionArchive(osVersion);
+        versionArchive(PostCodeDataVersion);
     }
     catch (const cereal::Exception& e)
     {