blob: 2d443c694776393bbad57fc08164ac0234d3c681 [file] [log] [blame]
Matt Spinler4e8078c2019-07-09 13:22:32 -05001#pragma once
2
Matt Spinlera34ab722019-12-16 10:39:32 -06003#include "config.h"
4
Matt Spinlerc8705e22019-09-11 12:36:07 -05005#include "data_interface.hpp"
Matt Spinlerf682b402019-12-18 13:48:08 -06006#include "event_logger.hpp"
Matt Spinlerf60ac272019-12-11 13:47:50 -06007#include "host_notifier.hpp"
Matt Spinler4e8078c2019-07-09 13:22:32 -05008#include "log_manager.hpp"
Matt Spinler89fa0822019-07-17 13:54:30 -05009#include "paths.hpp"
Matt Spinler56ad2a02020-03-26 14:00:52 -050010#include "pel.hpp"
Matt Spinler367144c2019-09-19 15:33:52 -050011#include "registry.hpp"
Matt Spinler89fa0822019-07-17 13:54:30 -050012#include "repository.hpp"
Matt Spinler4e8078c2019-07-09 13:22:32 -050013
Matt Spinlera34ab722019-12-16 10:39:32 -060014#include <org/open_power/Logging/PEL/server.hpp>
15#include <sdbusplus/server.hpp>
Matt Spinler6b1a5c82020-01-07 08:48:53 -060016#include <sdeventplus/event.hpp>
17#include <sdeventplus/source/event.hpp>
Matt Spinlera34ab722019-12-16 10:39:32 -060018
Matt Spinler4e8078c2019-07-09 13:22:32 -050019namespace openpower
20{
21namespace pels
22{
23
Matt Spinlera34ab722019-12-16 10:39:32 -060024using PELInterface = sdbusplus::server::object::object<
25 sdbusplus::org::open_power::Logging::server::PEL>;
26
Matt Spinler4e8078c2019-07-09 13:22:32 -050027/**
28 * @brief PEL manager object
29 */
Matt Spinlera34ab722019-12-16 10:39:32 -060030class Manager : public PELInterface
Matt Spinler4e8078c2019-07-09 13:22:32 -050031{
32 public:
33 Manager() = delete;
34 ~Manager() = default;
35 Manager(const Manager&) = default;
36 Manager& operator=(const Manager&) = default;
37 Manager(Manager&&) = default;
38 Manager& operator=(Manager&&) = default;
39
40 /**
41 * @brief constructor
42 *
43 * @param[in] logManager - internal::Manager object
Matt Spinlerf60ac272019-12-11 13:47:50 -060044 * @param[in] dataIface - The data interface object
Matt Spinlerf682b402019-12-18 13:48:08 -060045 * @param[in] creatorFunc - The function that EventLogger will
46 * use for creating event logs
Matt Spinler4e8078c2019-07-09 13:22:32 -050047 */
Matt Spinlerf60ac272019-12-11 13:47:50 -060048 Manager(phosphor::logging::internal::Manager& logManager,
Matt Spinlerf682b402019-12-18 13:48:08 -060049 std::unique_ptr<DataInterfaceBase> dataIface,
50 EventLogger::LogFunction creatorFunc) :
Matt Spinlera34ab722019-12-16 10:39:32 -060051 PELInterface(logManager.getBus(), OBJ_LOGGING),
Matt Spinler104e9362020-04-02 09:34:41 -050052 _logManager(logManager), _eventLogger(std::move(creatorFunc)),
Matt Spinlerf682b402019-12-18 13:48:08 -060053 _repo(getPELRepoPath()),
Matt Spinler0d804ef2020-05-12 16:16:26 -050054 _registry(getPELReadOnlyDataPath() / message::registryFileName),
Matt Spinler367144c2019-09-19 15:33:52 -050055 _dataIface(std::move(dataIface))
Matt Spinler4e8078c2019-07-09 13:22:32 -050056 {
57 }
58
59 /**
Matt Spinlerf60ac272019-12-11 13:47:50 -060060 * @brief constructor that enables host notification
61 *
62 * @param[in] logManager - internal::Manager object
63 * @param[in] dataIface - The data interface object
Matt Spinlerf682b402019-12-18 13:48:08 -060064 * @param[in] creatorFunc - The function that EventLogger will
65 * use for creating event logs
Matt Spinlerf60ac272019-12-11 13:47:50 -060066 * @param[in] hostIface - The hostInterface object
67 */
68 Manager(phosphor::logging::internal::Manager& logManager,
69 std::unique_ptr<DataInterfaceBase> dataIface,
Matt Spinlerf682b402019-12-18 13:48:08 -060070 EventLogger::LogFunction creatorFunc,
Matt Spinlerf60ac272019-12-11 13:47:50 -060071 std::unique_ptr<HostInterface> hostIface) :
Matt Spinlerf682b402019-12-18 13:48:08 -060072 Manager(logManager, std::move(dataIface), std::move(creatorFunc))
Matt Spinlerf60ac272019-12-11 13:47:50 -060073 {
74 _hostNotifier = std::make_unique<HostNotifier>(
75 _repo, *(_dataIface.get()), std::move(hostIface));
76 }
77
78 /**
Matt Spinler4e8078c2019-07-09 13:22:32 -050079 * @brief Creates a PEL based on the OpenBMC event log contents. If
80 * a PEL was passed in via the RAWPEL specifier in the
81 * additionalData parameter, use that instead.
82 *
83 * @param[in] message - the event log message property
84 * @param[in] obmcLogID - the corresponding OpenBMC event log id
85 * @param[in] timestamp - the Timestamp property
86 * @param[in] severity - the event log severity
87 * @param[in] additionalData - the AdditionalData property
88 * @param[in] associations - the Associations property
Matt Spinler56ad2a02020-03-26 14:00:52 -050089 * @param[in] ffdc - A vector of FFDC file information
Matt Spinler4e8078c2019-07-09 13:22:32 -050090 */
91 void create(const std::string& message, uint32_t obmcLogID,
Matt Spinler367144c2019-09-19 15:33:52 -050092 uint64_t timestamp, phosphor::logging::Entry::Level severity,
Matt Spinler4e8078c2019-07-09 13:22:32 -050093 const std::vector<std::string>& additionalData,
Matt Spinler56ad2a02020-03-26 14:00:52 -050094 const std::vector<std::string>& associations,
95 const phosphor::logging::FFDCEntries& ffdc =
96 phosphor::logging::FFDCEntries{});
Matt Spinler4e8078c2019-07-09 13:22:32 -050097
98 /**
99 * @brief Erase a PEL based on its OpenBMC event log ID
100 *
101 * @param[in] obmcLogID - the corresponding OpenBMC event log id
102 */
103 void erase(uint32_t obmcLogID);
104
105 /** @brief Says if an OpenBMC event log may not be manually deleted at this
106 * time because its corresponding PEL cannot be.
107 *
108 * There are PEL retention policies that can prohibit the manual deletion
109 * of PELs (and therefore OpenBMC event logs).
110 *
111 * @param[in] obmcLogID - the OpenBMC event log ID
112 * @return bool - true if prohibited
113 */
114 bool isDeleteProhibited(uint32_t obmcLogID);
115
Matt Spinlera34ab722019-12-16 10:39:32 -0600116 /**
117 * @brief Return a file descriptor to the raw PEL data
118 *
119 * Throws InvalidArgument if the PEL ID isn't found,
120 * and InternalFailure if anything else fails.
121 *
122 * @param[in] pelID - The PEL ID to get the data for
123 *
124 * @return unix_fd - File descriptor to the file that contains the PEL
125 */
126 sdbusplus::message::unix_fd getPEL(uint32_t pelID) override;
127
128 /**
129 * @brief Returns data for the PEL corresponding to an OpenBMC
130 * event log.
131 *
132 * @param[in] obmcLogID - The OpenBMC event log ID
133 *
134 * @return vector<uint8_t> - The raw PEL data
135 */
136 std::vector<uint8_t> getPELFromOBMCID(uint32_t obmcLogID) override;
137
138 /**
139 * @brief The D-Bus method called when a host successfully processes
140 * a PEL.
141 *
142 * This D-Bus method is called from the PLDM daemon when they get an
143 * 'Ack PEL' PLDM message from the host, which indicates the host
144 * firmware successfully sent it to the OS and this code doesn't need
145 * to send it to the host again.
146 *
147 * @param[in] pelID - The PEL ID
148 */
149 void hostAck(uint32_t pelID) override;
150
151 /**
152 * @brief D-Bus method called when the host rejects a PEL.
153 *
154 * This D-Bus method is called from the PLDM daemon when they get an
155 * 'Ack PEL' PLDM message from the host with a payload that says
156 * something when wrong.
157 *
158 * The choices are either:
159 * * Host Full - The host's staging area is full - try again later
160 * * Malrformed PEL - The host received an invalid PEL
161 *
162 * @param[in] pelID - The PEL ID
163 * @param[in] reason - One of the above two reasons
164 */
165 void hostReject(uint32_t pelID, RejectionReason reason) override;
166
Matt Spinler19e72902020-01-24 11:05:20 -0600167 /**
168 * @brief Converts the ESEL field in an OpenBMC event log to a
169 * vector of uint8_ts that just contains the PEL data.
170 *
171 * That data string looks like: "50 48 00 ab ..."
172 *
173 * Throws an exception on any failures.
174 *
175 * @param[in] esel - The ESEL string
176 *
177 * @return std::vector<uint8_t> - The contained PEL data
178 */
179 static std::vector<uint8_t> eselToRawData(const std::string& esel);
180
Matt Spinler4e8078c2019-07-09 13:22:32 -0500181 private:
182 /**
183 * @brief Adds a received raw PEL to the PEL repository
184 *
185 * @param[in] rawPelPath - The path to the file that contains the
186 * raw PEL.
187 * @param[in] obmcLogID - the corresponding OpenBMC event log id
188 */
189 void addRawPEL(const std::string& rawPelPath, uint32_t obmcLogID);
190
191 /**
192 * @brief Creates a PEL based on the OpenBMC event log contents.
193 *
194 * @param[in] message - The event log message property
195 * @param[in] obmcLogID - the corresponding OpenBMC event log id
196 * @param[in] timestamp - The timestamp property
197 * @param[in] severity - The event log severity
198 * @param[in] additionalData - The AdditionalData property
199 * @param[in] associations - The associations property
Matt Spinler56ad2a02020-03-26 14:00:52 -0500200 * @param[in] ffdc - A vector of FFDC file information
Matt Spinler4e8078c2019-07-09 13:22:32 -0500201 */
202 void createPEL(const std::string& message, uint32_t obmcLogID,
Matt Spinler367144c2019-09-19 15:33:52 -0500203 uint64_t timestamp, phosphor::logging::Entry::Level severity,
Matt Spinler4e8078c2019-07-09 13:22:32 -0500204 const std::vector<std::string>& additionalData,
Matt Spinler56ad2a02020-03-26 14:00:52 -0500205 const std::vector<std::string>& associations,
206 const phosphor::logging::FFDCEntries& ffdc);
Matt Spinler4e8078c2019-07-09 13:22:32 -0500207
208 /**
Matt Spinler6b1a5c82020-01-07 08:48:53 -0600209 * @brief Schedules a close of the file descriptor to occur from
210 * the event loop.
211 *
212 * Uses sd_event_add_defer
213 *
214 * @param[in] fd - The file descriptor to close
215 */
216 void scheduleFDClose(int fd);
217
218 /**
219 * @brief Closes the file descriptor passed in.
220 *
221 * This is called from the event loop to close FDs returned
222 * from getPEL().
223 *
224 * @param[in] fd - The file descriptor to close
225 * @param[in] source - The event source object used
226 */
227 void closeFD(int fd, sdeventplus::source::EventBase& source);
228
229 /**
Matt Spinler19e72902020-01-24 11:05:20 -0600230 * @brief Adds a PEL to the repository given its data
231 *
232 * @param[in] pelData - The PEL to add as a vector of uint8_ts
233 * @param[in] obmcLogID - the OpenBMC event log ID
234 */
235 void addPEL(std::vector<uint8_t>& pelData, uint32_t obmcLogID);
236
237 /**
238 * @brief Adds the PEL stored in the ESEL field of the AdditionalData
239 * property of an OpenBMC event log to the repository.
240 *
241 * @param[in] esel - The ESEL AdditionalData contents
242 * @param[in] obmcLogID - The OpenBMC event log ID
243 */
244 void addESELPEL(const std::string& esel, uint32_t obmcLogID);
245
246 /**
Matt Spinler56ad2a02020-03-26 14:00:52 -0500247 * @brief Converts the D-Bus FFDC method argument into a data
248 * structure understood by the PEL code.
249 *
250 * @param[in] ffdc - A vector of FFDC file information
251 *
252 * @return PelFFDC - The PEL FFDC data structure
253 */
254 PelFFDC convertToPelFFDC(const phosphor::logging::FFDCEntries& ffdc);
255
256 /**
Matt Spinler7e727a32020-07-07 15:00:17 -0500257 * @brief Schedules a PEL repository prune to occur from
258 * the event loop.
259 *
260 * Uses sd_event_add_defer
261 */
262 void scheduleRepoPrune();
263
264 /**
265 * @brief Prunes old PELs out of the repository to save space.
266 *
267 * This is called from the event loop.
268 *
269 * @param[in] source - The event source object used
270 */
271 void pruneRepo(sdeventplus::source::EventBase& source);
272
273 /**
Matt Spinler4e8078c2019-07-09 13:22:32 -0500274 * @brief Reference to phosphor-logging's Manager class
275 */
Matt Spinler367144c2019-09-19 15:33:52 -0500276 phosphor::logging::internal::Manager& _logManager;
Matt Spinler89fa0822019-07-17 13:54:30 -0500277
278 /**
Matt Spinlerf682b402019-12-18 13:48:08 -0600279 * @brief Handles creating event logs/PELs from within
280 * the PEL extension code
281 */
282 EventLogger _eventLogger;
283
284 /**
Matt Spinler89fa0822019-07-17 13:54:30 -0500285 * @brief The PEL repository object
286 */
287 Repository _repo;
Matt Spinlerc8705e22019-09-11 12:36:07 -0500288
289 /**
Matt Spinler367144c2019-09-19 15:33:52 -0500290 * @brief The PEL message registry object
291 */
292 message::Registry _registry;
293
294 /**
Matt Spinlerc8705e22019-09-11 12:36:07 -0500295 * @brief The API the PEL sections use to gather data
296 */
297 std::unique_ptr<DataInterfaceBase> _dataIface;
Matt Spinlerf60ac272019-12-11 13:47:50 -0600298
299 /**
300 * @brief The HostNotifier object used for telling the
301 * host about new PELs
302 */
303 std::unique_ptr<HostNotifier> _hostNotifier;
Matt Spinler6b1a5c82020-01-07 08:48:53 -0600304
305 /**
306 * @brief The event source for closing a PEL file descriptor after
307 * it has been returned from the getPEL D-Bus method.
308 */
309 std::unique_ptr<sdeventplus::source::Defer> _fdCloserEventSource;
Matt Spinler7e727a32020-07-07 15:00:17 -0500310
311 /**
312 * @brief The even source for removing old PELs when the repo is
313 * running out of space to make room for new ones.
314 */
315 std::unique_ptr<sdeventplus::source::Defer> _repoPrunerEventSource;
Matt Spinler4e8078c2019-07-09 13:22:32 -0500316};
317
318} // namespace pels
319} // namespace openpower