Persist error d-bus objects

Use Cereal to implement serialization and de-serialization of
properties of error d-bus objects.

Serialize and persist error d-bus objects as they are put on the bus.
De-serialize and restore them (if persistent ones exist) when
phosphor-log-manager starts up.

Change-Id: I1f5df1abbe74bfdb86e3e82a78ff7115e90e2112
Signed-off-by: Deepak Kodihalli <dkodihal@in.ibm.com>
diff --git a/log_manager.cpp b/log_manager.cpp
index 8ab495b..3f61e91 100644
--- a/log_manager.cpp
+++ b/log_manager.cpp
@@ -14,6 +14,7 @@
 #include <phosphor-logging/log.hpp>
 #include "log_manager.hpp"
 #include "elog_meta.hpp"
+#include "elog_serialize.hpp"
 
 using namespace phosphor::logging;
 extern const std::map<metadata::Metadata,
@@ -145,17 +146,18 @@
     {
         reqLevel = levelmap->second;
     }
-    entries.insert(std::make_pair(entryId, std::make_unique<Entry>(
-            busLog,
-            objPath,
-            entryId,
-            ms, // Milliseconds since 1970
-            static_cast<Entry::Level>(reqLevel),
-            std::move(errMsg),
-            std::move(additionalData),
-            std::move(objects),
-            *this)));
-    return;
+    auto e = std::make_unique<Entry>(
+                 busLog,
+                 objPath,
+                 entryId,
+                 ms, // Milliseconds since 1970
+                 static_cast<Entry::Level>(reqLevel),
+                 std::move(errMsg),
+                 std::move(additionalData),
+                 std::move(objects),
+                 *this);
+    serialize(*e);
+    entries.insert(std::make_pair(entryId, std::move(e)));
 }
 
 void Manager::processMetadata(const std::string& errorName,
@@ -188,5 +190,35 @@
     }
 }
 
+void Manager::restore()
+{
+    std::vector<uint32_t> errorIds;
+
+    fs::path dir(ERRLOG_PERSIST_PATH);
+    if (!fs::exists(dir) || fs::is_empty(dir))
+    {
+        return;
+    }
+
+    for(auto& file: fs::directory_iterator(dir))
+    {
+        auto id = file.path().filename().c_str();
+        auto idNum = std::stol(id);
+        auto e = std::make_unique<Entry>(
+                     busLog,
+                     std::string(OBJ_ENTRY) + '/' + id,
+                     idNum,
+                     *this);
+        if (deserialize(file.path(), *e))
+        {
+            e->emit_object_added();
+            entries.insert(std::make_pair(idNum, std::move(e)));
+            errorIds.push_back(idNum);
+        }
+    }
+
+    entryId = *(std::max_element(errorIds.begin(), errorIds.end()));
+}
+
 } // namespace logging
 } // namepsace phosphor