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 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> 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> 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 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 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