1 #include "config.h"
2 
3 #include "elog_serialize.hpp"
4 
5 #include <cereal/archives/binary.hpp>
6 #include <cereal/types/string.hpp>
7 #include <cereal/types/tuple.hpp>
8 #include <cereal/types/vector.hpp>
9 #include <fstream>
10 #include <phosphor-logging/log.hpp>
11 
12 // Register class version
13 // From cereal documentation;
14 // "This macro should be placed at global scope"
15 CEREAL_CLASS_VERSION(phosphor::logging::Entry, CLASS_VERSION);
16 
17 namespace phosphor
18 {
19 namespace logging
20 {
21 
22 /** @brief Function required by Cereal to perform serialization.
23  *  @tparam Archive - Cereal archive type (binary in our case).
24  *  @param[in] a       - reference to Cereal archive.
25  *  @param[in] e       - const reference to error entry.
26  *  @param[in] version - Class version that enables handling
27  *                       a serialized data across code levels
28  */
29 template <class Archive>
30 void save(Archive& a, const Entry& e, const std::uint32_t version)
31 {
32     a(e.id(), e.severity(), e.timestamp(), e.message(), e.additionalData(),
33       e.associations(), e.resolved(), e.version());
34 }
35 
36 /** @brief Function required by Cereal to perform deserialization.
37  *  @tparam Archive - Cereal archive type (binary in our case).
38  *  @param[in] a       - reference to Cereal archive.
39  *  @param[in] e       - reference to error entry.
40  *  @param[in] version - Class version that enables handling
41  *                       a serialized data across code levels
42  */
43 template <class Archive>
44 void load(Archive& a, Entry& e, const std::uint32_t version)
45 {
46     using namespace sdbusplus::xyz::openbmc_project::Logging::server;
47 
48     uint32_t id{};
49     Entry::Level severity{};
50     uint64_t timestamp{};
51     std::string message{};
52     std::vector<std::string> additionalData{};
53     bool resolved{};
54     AssociationList associations{};
55     std::string fwVersion{};
56 
57     if (version < std::stoul(FIRST_CEREAL_CLASS_VERSION_WITH_FWLEVEL))
58     {
59         a(id, severity, timestamp, message, additionalData, associations,
60           resolved);
61     }
62     else
63     {
64         a(id, severity, timestamp, message, additionalData, associations,
65           resolved, fwVersion);
66     }
67 
68     e.id(id);
69     e.severity(severity);
70     e.timestamp(timestamp);
71     e.message(message);
72     e.additionalData(additionalData);
73     e.sdbusplus::xyz::openbmc_project::Logging::server::Entry::resolved(
74         resolved);
75     e.associations(associations);
76     e.version(fwVersion);
77     e.purpose(sdbusplus::xyz::openbmc_project::Software::server::Version::
78                   VersionPurpose::BMC);
79 }
80 
81 fs::path serialize(const Entry& e, const fs::path& dir)
82 {
83     auto path = dir / std::to_string(e.id());
84     std::ofstream os(path.c_str(), std::ios::binary);
85     cereal::BinaryOutputArchive oarchive(os);
86     oarchive(e);
87     return path;
88 }
89 
90 bool deserialize(const fs::path& path, Entry& e)
91 {
92     try
93     {
94         if (fs::exists(path))
95         {
96             std::ifstream is(path.c_str(), std::ios::in | std::ios::binary);
97             cereal::BinaryInputArchive iarchive(is);
98             iarchive(e);
99             return true;
100         }
101         return false;
102     }
103     catch (cereal::Exception& e)
104     {
105         log<level::ERR>(e.what());
106         fs::remove(path);
107         return false;
108     }
109     catch (const std::length_error& e)
110     {
111         // Running into: USCiLab/cereal#192
112         // This may be indicating some other issue in the
113         // way vector may have been used inside the logging.
114         // possibly associations ??. But handling it here for
115         // now since we are anyway tossing the log
116         // TODO: openbmc/phosphor-logging#8
117         log<level::ERR>(e.what());
118         fs::remove(path);
119         return false;
120     }
121 }
122 
123 } // namespace logging
124 } // namespace phosphor
125