blob: 71bd986e7b671a2ddaa6bbaffd3246a9e4e2e730 [file] [log] [blame]
Patrick Venturef18bf832018-10-26 18:14:00 -07001#include "config.h"
Jayanth Othayoth9c7f03a2017-09-20 00:04:22 -05002
Deepak Kodihalli72654f12017-06-12 04:33:29 -05003#include "elog_serialize.hpp"
Patrick Venturef18bf832018-10-26 18:14:00 -07004
Matt Spinlerdfe021c2025-05-09 14:06:50 -05005#include "util.hpp"
6
Patrick Venturef18bf832018-10-26 18:14:00 -07007#include <cereal/archives/binary.hpp>
Patrick Williams5402fa62024-11-22 14:42:52 -05008#include <cereal/types/map.hpp>
Patrick Venturef18bf832018-10-26 18:14:00 -07009#include <cereal/types/string.hpp>
10#include <cereal/types/tuple.hpp>
11#include <cereal/types/vector.hpp>
Arya K Padman5bc26532024-04-10 06:19:25 -050012#include <phosphor-logging/lg2.hpp>
Vishwanatha Subbanna37af9ba2017-09-28 16:33:53 +053013
Patrick Williams2544b412022-10-04 08:41:06 -050014#include <fstream>
15
Vishwanatha Subbanna37af9ba2017-09-28 16:33:53 +053016// Register class version
17// From cereal documentation;
18// "This macro should be placed at global scope"
Patrick Williamsf40323d2021-04-16 15:35:17 -050019CEREAL_CLASS_VERSION(phosphor::logging::Entry, CLASS_VERSION)
Deepak Kodihalli72654f12017-06-12 04:33:29 -050020
21namespace phosphor
22{
23namespace logging
24{
25
Deepak Kodihallif1630ea2017-06-25 22:05:47 -050026/** @brief Function required by Cereal to perform serialization.
27 * @tparam Archive - Cereal archive type (binary in our case).
Vishwanatha Subbanna37af9ba2017-09-28 16:33:53 +053028 * @param[in] a - reference to Cereal archive.
29 * @param[in] e - const reference to error entry.
30 * @param[in] version - Class version that enables handling
31 * a serialized data across code levels
Deepak Kodihallif1630ea2017-06-25 22:05:47 -050032 */
Patrick Venturef18bf832018-10-26 18:14:00 -070033template <class Archive>
Patrick Williamsf40323d2021-04-16 15:35:17 -050034void save(Archive& a, const Entry& e, const std::uint32_t /*version*/)
Deepak Kodihallif1630ea2017-06-25 22:05:47 -050035{
Matt Spinler3d079c62025-03-26 12:57:18 -050036 a(e.id(), e.severity(), e.timestamp(), e.message(),
37 util::additional_data::combine(e.additionalData()), e.associations(),
38 e.resolved(), e.version(), e.updateTimestamp(), e.eventId(),
39 e.resolution());
Deepak Kodihallif1630ea2017-06-25 22:05:47 -050040}
41
42/** @brief Function required by Cereal to perform deserialization.
43 * @tparam Archive - Cereal archive type (binary in our case).
Vishwanatha Subbanna37af9ba2017-09-28 16:33:53 +053044 * @param[in] a - reference to Cereal archive.
45 * @param[in] e - reference to error entry.
46 * @param[in] version - Class version that enables handling
47 * a serialized data across code levels
Deepak Kodihallif1630ea2017-06-25 22:05:47 -050048 */
Patrick Venturef18bf832018-10-26 18:14:00 -070049template <class Archive>
Vishwanatha Subbanna37af9ba2017-09-28 16:33:53 +053050void load(Archive& a, Entry& e, const std::uint32_t version)
Deepak Kodihallif1630ea2017-06-25 22:05:47 -050051{
Willy Tu6ddbf692023-09-05 10:54:16 -070052 using namespace sdbusplus::server::xyz::openbmc_project::logging;
Deepak Kodihallif1630ea2017-06-25 22:05:47 -050053
54 uint32_t id{};
55 Entry::Level severity{};
56 uint64_t timestamp{};
57 std::string message{};
Patrick Williams5402fa62024-11-22 14:42:52 -050058 std::map<std::string, std::string> additionalData{};
Deepak Kodihallif1630ea2017-06-25 22:05:47 -050059 bool resolved{};
60 AssociationList associations{};
Matt Spinler375ac9b2018-05-01 15:20:55 -050061 std::string fwVersion{};
Matt Spinler1e71a4d2020-03-04 13:40:22 -060062 uint64_t updateTimestamp{};
Vijay Lobod354a392021-06-01 16:21:02 -050063 std::string eventId{};
Vijay Lobo593a4c62021-06-16 14:25:26 -050064 std::string resolution{};
Deepak Kodihallif1630ea2017-06-25 22:05:47 -050065
Matt Spinler375ac9b2018-05-01 15:20:55 -050066 if (version < std::stoul(FIRST_CEREAL_CLASS_VERSION_WITH_FWLEVEL))
67 {
Patrick Williams5402fa62024-11-22 14:42:52 -050068 std::vector<std::string> additionalData_old{};
69 a(id, severity, timestamp, message, additionalData_old, associations,
Patrick Venturef18bf832018-10-26 18:14:00 -070070 resolved);
Matt Spinler1e71a4d2020-03-04 13:40:22 -060071 updateTimestamp = timestamp;
Patrick Williams5402fa62024-11-22 14:42:52 -050072 additionalData = util::additional_data::parse(additionalData_old);
Matt Spinler1e71a4d2020-03-04 13:40:22 -060073 }
74 else if (version < std::stoul(FIRST_CEREAL_CLASS_VERSION_WITH_UPDATE_TS))
75 {
Patrick Williams5402fa62024-11-22 14:42:52 -050076 std::vector<std::string> additionalData_old{};
77 a(id, severity, timestamp, message, additionalData_old, associations,
Matt Spinler1e71a4d2020-03-04 13:40:22 -060078 resolved, fwVersion);
79 updateTimestamp = timestamp;
Patrick Williams5402fa62024-11-22 14:42:52 -050080 additionalData = util::additional_data::parse(additionalData_old);
Matt Spinler375ac9b2018-05-01 15:20:55 -050081 }
Vijay Lobod354a392021-06-01 16:21:02 -050082 else if (version < std::stoul(FIRST_CEREAL_CLASS_VERSION_WITH_EVENTID))
Matt Spinler375ac9b2018-05-01 15:20:55 -050083 {
Patrick Williams5402fa62024-11-22 14:42:52 -050084 std::vector<std::string> additionalData_old{};
85 a(id, severity, timestamp, message, additionalData_old, associations,
Matt Spinler1e71a4d2020-03-04 13:40:22 -060086 resolved, fwVersion, updateTimestamp);
Patrick Williams5402fa62024-11-22 14:42:52 -050087 additionalData = util::additional_data::parse(additionalData_old);
Matt Spinler375ac9b2018-05-01 15:20:55 -050088 }
Vijay Lobo593a4c62021-06-16 14:25:26 -050089 else if (version < std::stoul(FIRST_CEREAL_CLASS_VERSION_WITH_RESOLUTION))
Vijay Lobod354a392021-06-01 16:21:02 -050090 {
Patrick Williams5402fa62024-11-22 14:42:52 -050091 std::vector<std::string> additionalData_old{};
92 a(id, severity, timestamp, message, additionalData_old, associations,
Vijay Lobod354a392021-06-01 16:21:02 -050093 resolved, fwVersion, updateTimestamp, eventId);
Patrick Williams5402fa62024-11-22 14:42:52 -050094 additionalData = util::additional_data::parse(additionalData_old);
95 }
96 else if (version <
97 std::stoul(FIRST_CEREAL_CLASS_VERSION_WITH_METADATA_DICT))
98 {
99 std::vector<std::string> additionalData_old{};
100 a(id, severity, timestamp, message, additionalData_old, associations,
101 resolved, fwVersion, updateTimestamp, eventId, resolution);
102 additionalData = util::additional_data::parse(additionalData_old);
Vijay Lobod354a392021-06-01 16:21:02 -0500103 }
Matt Spinler3d079c62025-03-26 12:57:18 -0500104 else if (version ==
105 std::stoul(FIRST_CEREAL_CLASS_VERSION_WITH_METADATA_DICT))
Vijay Lobo593a4c62021-06-16 14:25:26 -0500106 {
107 a(id, severity, timestamp, message, additionalData, associations,
108 resolved, fwVersion, updateTimestamp, eventId, resolution);
109 }
Matt Spinler3d079c62025-03-26 12:57:18 -0500110 else
111 {
112 // Go back to reading a vector for additionalData
113 std::vector<std::string> additionalData_old{};
114 a(id, severity, timestamp, message, additionalData_old, associations,
115 resolved, fwVersion, updateTimestamp, eventId, resolution);
116 additionalData = util::additional_data::parse(additionalData_old);
117 }
Deepak Kodihallif1630ea2017-06-25 22:05:47 -0500118
Matt Spinleref952af2021-08-19 10:23:05 -0500119 e.id(id, true);
120 e.severity(severity, true);
121 e.timestamp(timestamp, true);
122 e.message(message, true);
Patrick Williamsea6d9c42024-12-11 14:58:21 -0500123 e.additionalData(additionalData, true);
Willy Tu6ddbf692023-09-05 10:54:16 -0700124 e.sdbusplus::server::xyz::openbmc_project::logging::Entry::resolved(
Matt Spinleref952af2021-08-19 10:23:05 -0500125 resolved, true);
126 e.associations(associations, true);
127 e.version(fwVersion, true);
Willy Tu6ddbf692023-09-05 10:54:16 -0700128 e.purpose(sdbusplus::server::xyz::openbmc_project::software::Version::
Matt Spinleref952af2021-08-19 10:23:05 -0500129 VersionPurpose::BMC,
130 true);
131 e.updateTimestamp(updateTimestamp, true);
132 e.eventId(eventId, true);
133 e.resolution(resolution, true);
Deepak Kodihallif1630ea2017-06-25 22:05:47 -0500134}
135
Matt Spinlerfb978da2022-01-21 08:42:24 -0600136fs::path getEntrySerializePath(uint32_t id, const fs::path& dir)
137{
138 return dir / std::to_string(id);
139}
140
Deepak Kodihalli72654f12017-06-12 04:33:29 -0500141fs::path serialize(const Entry& e, const fs::path& dir)
142{
Matt Spinlerfb978da2022-01-21 08:42:24 -0600143 auto path = getEntrySerializePath(e.id(), dir);
Deepak Kodihalli72654f12017-06-12 04:33:29 -0500144 std::ofstream os(path.c_str(), std::ios::binary);
145 cereal::BinaryOutputArchive oarchive(os);
146 oarchive(e);
147 return path;
148}
149
150bool deserialize(const fs::path& path, Entry& e)
151{
Jayanth Othayoth9c7f03a2017-09-20 00:04:22 -0500152 try
Deepak Kodihalli72654f12017-06-12 04:33:29 -0500153 {
Jayanth Othayoth9c7f03a2017-09-20 00:04:22 -0500154 if (fs::exists(path))
155 {
156 std::ifstream is(path.c_str(), std::ios::in | std::ios::binary);
157 cereal::BinaryInputArchive iarchive(is);
158 iarchive(e);
159 return true;
160 }
161 return false;
Deepak Kodihalli72654f12017-06-12 04:33:29 -0500162 }
Matt Spinler991e2b02025-03-19 10:54:46 -0500163 catch (const std::exception& ex)
Jayanth Othayoth9c7f03a2017-09-20 00:04:22 -0500164 {
Matt Spinler991e2b02025-03-19 10:54:46 -0500165 lg2::error("Failed restoring {PATH}: {EXCEPTION}", "PATH", path,
166 "EXCEPTION", ex);
167 // Save it for later debug. Just write over any previous ones.
168 auto saveDir = paths::error().parent_path();
169 fs::rename(path, saveDir / "corrupt_error");
Vishwanatha Subbanna37af9ba2017-09-28 16:33:53 +0530170 return false;
171 }
Deepak Kodihalli72654f12017-06-12 04:33:29 -0500172}
173
174} // namespace logging
175} // namespace phosphor