blob: 7c0310e442366e6c7831bffbab99bdfdb78f1f84 [file] [log] [blame]
Matt Spinler23818bb2018-05-23 11:00:15 -05001/** Copyright © 2018 IBM Corporation
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
Matt Spinleref3b86f2018-05-23 11:19:10 -050015#include <cereal/archives/binary.hpp>
16#include <cereal/types/string.hpp>
17#include <cereal/types/vector.hpp>
18#include <cereal/types/tuple.hpp>
19#include <experimental/filesystem>
20#include <fstream>
21#include <phosphor-logging/log.hpp>
Matt Spinler23818bb2018-05-23 11:00:15 -050022#include "callout.hpp"
Matt Spinleref3b86f2018-05-23 11:19:10 -050023#include "config.h"
24#include "dbus.hpp"
25
26CEREAL_CLASS_VERSION(ibm::logging::Callout, CALLOUT_CLASS_VERSION);
Matt Spinler23818bb2018-05-23 11:00:15 -050027
28namespace ibm
29{
30namespace logging
31{
32
Matt Spinleref3b86f2018-05-23 11:19:10 -050033using namespace phosphor::logging;
34
35/**
36 * Function required by Cereal for saving data
37 *
38 * @param[in] archive - the Cereal archive object
39 * @param[in] callout - the object to save
40 * @param[in] version - the version of the persisted data
41 */
42template <class Archive>
43void save(Archive& archive, const Callout& callout, const std::uint32_t version)
44{
45 archive(callout.id(), callout.ts(), callout.path(), callout.buildDate(),
46 callout.manufacturer(), callout.model(), callout.partNumber(),
47 callout.serialNumber());
48}
49
50/**
51 * Function required by Cereal for restoring data into an object
52 *
53 * @param[in] archive - the Cereal archive object
54 * @param[in] callout - the callout object to restore
55 * @param[in] version - the version of the persisted data
56 */
57template <class Archive>
58void load(Archive& archive, Callout& callout, const std::uint32_t version)
59{
60 size_t id;
61 uint64_t timestamp;
62 std::string inventoryPath;
63 std::string build;
64 std::string mfgr;
65 std::string model;
66 std::string pn;
67 std::string sn;
68
69 archive(id, timestamp, inventoryPath, build, mfgr, model, pn, sn);
70
71 callout.id(id);
72 callout.ts(timestamp);
73 callout.path(inventoryPath);
74 callout.buildDate(build);
75 callout.manufacturer(mfgr);
76 callout.model(model);
77 callout.partNumber(pn);
78 callout.serialNumber(sn);
79}
80
Matt Spinler23818bb2018-05-23 11:00:15 -050081Callout::Callout(sdbusplus::bus::bus& bus, const std::string& objectPath,
82 size_t id, uint64_t timestamp) :
83 CalloutObject(bus, objectPath.c_str(), true),
84 entryID(id), timestamp(timestamp)
85{
86}
87
88Callout::Callout(sdbusplus::bus::bus& bus, const std::string& objectPath,
89 const std::string& inventoryPath, size_t id,
90 uint64_t timestamp, const DbusPropertyMap& properties) :
91 CalloutObject(bus, objectPath.c_str(), true),
92 entryID(id), timestamp(timestamp)
93{
94 path(inventoryPath);
95
96 auto it = properties.find("BuildDate");
97 if (it != properties.end())
98 {
99 buildDate(it->second.get<std::string>());
100 }
101
102 it = properties.find("Manufacturer");
103 if (it != properties.end())
104 {
105 manufacturer(it->second.get<std::string>());
106 }
107
108 it = properties.find("Model");
109 if (it != properties.end())
110 {
111 model(it->second.get<std::string>());
112 }
113
114 it = properties.find("PartNumber");
115 if (it != properties.end())
116 {
117 partNumber(it->second.get<std::string>());
118 }
119
120 it = properties.find("SerialNumber");
121 if (it != properties.end())
122 {
123 serialNumber(it->second.get<std::string>());
124 }
125
126 emit_object_added();
127}
Matt Spinleref3b86f2018-05-23 11:19:10 -0500128
129void Callout::serialize(const fs::path& dir)
130{
131 auto path = getFilePath(dir);
132 std::ofstream stream(path.c_str(), std::ios::binary);
133 cereal::BinaryOutputArchive oarchive(stream);
134
135 oarchive(*this);
136}
137
138bool Callout::deserialize(const fs::path& dir)
139{
140 auto path = getFilePath(dir);
141
142 if (!fs::exists(path))
143 {
144 return false;
145 }
146
147 // Save the current ID and timestamp and then use them after
148 // deserialization to check that the data we are restoring
149 // is for the correct error log.
150
151 auto originalID = entryID;
152 auto originalTS = timestamp;
153
154 try
155 {
156 std::ifstream stream(path.c_str(), std::ios::binary);
157 cereal::BinaryInputArchive iarchive(stream);
158
159 iarchive(*this);
160 }
161 catch (std::exception& e)
162 {
163 log<level::ERR>(e.what());
164 log<level::ERR>("Failed trying to restore a Callout object",
165 entry("PATH=%s", path.c_str()));
166 fs::remove(path);
167 return false;
168 }
169
170 if ((entryID != originalID) || (timestamp != originalTS))
171 {
172 log<level::INFO>(
173 "Timestamp or ID mismatch in persisted Callout. Discarding",
174 entry("PATH=%s", path.c_str()), entry("PERSISTED_ID=%lu", entryID),
175 entry("EXPECTED_ID=%lu", originalID),
176 entry("PERSISTED_TS=%llu", timestamp),
177 entry("EXPECTED_TS=%llu", originalTS));
178 fs::remove(path);
179 return false;
180 }
181
182 return true;
183}
Matt Spinler23818bb2018-05-23 11:00:15 -0500184}
185}