1 #include "manager_serialize.hpp"
2
3 #include <cereal/archives/binary.hpp>
4 #include <cereal/cereal.hpp>
5 #include <cereal/types/map.hpp>
6 #include <cereal/types/string.hpp>
7 #include <cereal/types/tuple.hpp>
8 #include <cereal/types/variant.hpp>
9 #include <cereal/types/vector.hpp>
10 #include <phosphor-logging/lg2.hpp>
11
12 #include <fstream>
13 #include <map>
14 #include <variant>
15 #include <vector>
16
17 CEREAL_CLASS_VERSION(bios_config::Manager, 1);
18 namespace bios_config
19 {
20
convertBiosData(Manager & entry,Manager::BaseTable & baseTable,Manager::oldBaseTable & baseTbl)21 inline void convertBiosData(Manager& entry, Manager::BaseTable& baseTable,
22 Manager::oldBaseTable& baseTbl)
23 {
24 switch (cereal::detail::Version<Manager>::version)
25 {
26 case 0:
27 entry.convertBiosDataToVersion0(baseTbl, baseTable);
28 break;
29 case 1:
30 entry.convertBiosDataToVersion1(baseTbl, baseTable);
31 break;
32 }
33 }
34
35 /** @brief Function required by Cereal to perform serialization.
36 *
37 * @tparam Archive - Cereal archive type (binary in this case).
38 * @param[in] archive - reference to cereal archive.
39 * @param[in] entry- const reference to bios manager object
40 * @param[in] version - Class version that enables handling a serialized data
41 * across code levels
42 */
43 template <class Archive>
save(Archive & archive,const Manager & entry,const std::uint32_t version)44 void save(Archive& archive, const Manager& entry, const std::uint32_t version)
45 {
46 lg2::error("Save is called with version {VER}", "VER", version);
47 archive(entry.sdbusplus::xyz::openbmc_project::BIOSConfig::server::Manager::
48 baseBIOSTable(),
49 entry.sdbusplus::xyz::openbmc_project::BIOSConfig::server::Manager::
50 pendingAttributes());
51 }
52
53 /** @brief Function required by Cereal to perform deserialization.
54 *
55 * @tparam Archive - Cereal archive type (binary in our case).
56 * @param[in] archive - reference to cereal archive.
57 * @param[out] entry - reference to bios manager object
58 * @param[in] version - Class version that enables handling a serialized data
59 * across code levels
60 */
61 template <class Archive>
load(Archive & archive,Manager & entry,const std::uint32_t version)62 void load(Archive& archive, Manager& entry, const std::uint32_t version)
63 {
64 lg2::error("Load is called with version {VER}", "VER", version);
65
66 Manager::BaseTable baseTable;
67 Manager::oldBaseTable baseTbl;
68 Manager::PendingAttributes pendingAttrs;
69
70 auto currentVersion = cereal::detail::Version<Manager>::version;
71
72 switch (version)
73 {
74 case 0:
75 archive(baseTbl, pendingAttrs);
76 break;
77 case 1:
78 archive(baseTable, pendingAttrs);
79 break;
80 }
81
82 if (currentVersion != version)
83 {
84 lg2::error("Version Mismatch with saved data 1");
85 convertBiosData(entry, baseTable, baseTbl);
86 }
87
88 // Update Dbus
89 entry.sdbusplus::xyz::openbmc_project::BIOSConfig::server::Manager::
90 baseBIOSTable(baseTable, true);
91
92 entry.sdbusplus::xyz::openbmc_project::BIOSConfig::server::Manager::
93 pendingAttributes(pendingAttrs, true);
94 }
95
serialize(const Manager & obj,const fs::path & path)96 void serialize(const Manager& obj, const fs::path& path)
97 {
98 try
99 {
100 std::ofstream os(path, std::ios::out | std::ios::binary);
101
102 if (!os.is_open())
103 {
104 lg2::error("Failed to open file for serialization: {FILE}", "FILE",
105 path);
106 return;
107 }
108
109 cereal::BinaryOutputArchive oarchive(os);
110 oarchive(obj);
111 }
112 catch (const std::exception& e)
113 {
114 lg2::error("Failed to Serialize : {ERROR} ", "ERROR", e);
115 }
116 }
117
deserialize(const fs::path & path,Manager & entry)118 bool deserialize(const fs::path& path, Manager& entry)
119 {
120 try
121 {
122 if (fs::exists(path))
123 {
124 std::ifstream is(path.c_str(), std::ios::in | std::ios::binary);
125 if (!is.is_open())
126 {
127 lg2::error("Failed to open file for deserialization: {FILE}",
128 "FILE", path);
129 return false;
130 }
131 cereal::BinaryInputArchive iarchive(is);
132 iarchive(entry);
133 return true;
134 }
135 return false;
136 }
137 catch (const std::exception& e)
138 {
139 lg2::error("Failed to serialize: {ERROR}", "ERROR", e);
140 fs::remove(path);
141 return false;
142 }
143 }
144
145 } // namespace bios_config
146