xref: /openbmc/bios-settings-mgr/src/manager_serialize.cpp (revision 4e29f80bf85c3a8197bb6c3183f25face059f29c)
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