blob: 50317a5e7ff47710df4c220e041d44f15ef35fbc [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;
Matt Spinler4e8078c2019-07-09 13:22:32 -050034 Manager(const Manager&) = default;
35 Manager& operator=(const Manager&) = default;
36 Manager(Manager&&) = default;
37 Manager& operator=(Manager&&) = default;
38
39 /**
40 * @brief constructor
41 *
42 * @param[in] logManager - internal::Manager object
Matt Spinlerf60ac272019-12-11 13:47:50 -060043 * @param[in] dataIface - The data interface object
Matt Spinlerf682b402019-12-18 13:48:08 -060044 * @param[in] creatorFunc - The function that EventLogger will
45 * use for creating event logs
Matt Spinler4e8078c2019-07-09 13:22:32 -050046 */
Matt Spinlerf60ac272019-12-11 13:47:50 -060047 Manager(phosphor::logging::internal::Manager& logManager,
Matt Spinlerf682b402019-12-18 13:48:08 -060048 std::unique_ptr<DataInterfaceBase> dataIface,
49 EventLogger::LogFunction creatorFunc) :
Matt Spinlera34ab722019-12-16 10:39:32 -060050 PELInterface(logManager.getBus(), OBJ_LOGGING),
Matt Spinler104e9362020-04-02 09:34:41 -050051 _logManager(logManager), _eventLogger(std::move(creatorFunc)),
Matt Spinlerf682b402019-12-18 13:48:08 -060052 _repo(getPELRepoPath()),
Matt Spinler0d804ef2020-05-12 16:16:26 -050053 _registry(getPELReadOnlyDataPath() / message::registryFileName),
Matt Spinlerff9cec22020-07-15 13:06:35 -050054 _event(sdeventplus::Event::get_default()),
Matt Spinler367144c2019-09-19 15:33:52 -050055 _dataIface(std::move(dataIface))
Matt Spinler4e8078c2019-07-09 13:22:32 -050056 {
Matt Spinlerff9cec22020-07-15 13:06:35 -050057 setupPELDeleteWatch();
Matt Spinler4e8078c2019-07-09 13:22:32 -050058 }
59
60 /**
Matt Spinlerf60ac272019-12-11 13:47:50 -060061 * @brief constructor that enables host notification
62 *
63 * @param[in] logManager - internal::Manager object
64 * @param[in] dataIface - The data interface object
Matt Spinlerf682b402019-12-18 13:48:08 -060065 * @param[in] creatorFunc - The function that EventLogger will
66 * use for creating event logs
Matt Spinlerf60ac272019-12-11 13:47:50 -060067 * @param[in] hostIface - The hostInterface object
68 */
69 Manager(phosphor::logging::internal::Manager& logManager,
70 std::unique_ptr<DataInterfaceBase> dataIface,
Matt Spinlerf682b402019-12-18 13:48:08 -060071 EventLogger::LogFunction creatorFunc,
Matt Spinlerf60ac272019-12-11 13:47:50 -060072 std::unique_ptr<HostInterface> hostIface) :
Matt Spinlerf682b402019-12-18 13:48:08 -060073 Manager(logManager, std::move(dataIface), std::move(creatorFunc))
Matt Spinlerf60ac272019-12-11 13:47:50 -060074 {
75 _hostNotifier = std::make_unique<HostNotifier>(
76 _repo, *(_dataIface.get()), std::move(hostIface));
77 }
78
79 /**
Matt Spinlerff9cec22020-07-15 13:06:35 -050080 * @brief Destructor
81 */
82 ~Manager();
83
84 /**
Matt Spinler4e8078c2019-07-09 13:22:32 -050085 * @brief Creates a PEL based on the OpenBMC event log contents. If
86 * a PEL was passed in via the RAWPEL specifier in the
87 * additionalData parameter, use that instead.
88 *
89 * @param[in] message - the event log message property
90 * @param[in] obmcLogID - the corresponding OpenBMC event log id
91 * @param[in] timestamp - the Timestamp property
92 * @param[in] severity - the event log severity
93 * @param[in] additionalData - the AdditionalData property
94 * @param[in] associations - the Associations property
Matt Spinler56ad2a02020-03-26 14:00:52 -050095 * @param[in] ffdc - A vector of FFDC file information
Matt Spinler4e8078c2019-07-09 13:22:32 -050096 */
97 void create(const std::string& message, uint32_t obmcLogID,
Matt Spinler367144c2019-09-19 15:33:52 -050098 uint64_t timestamp, phosphor::logging::Entry::Level severity,
Matt Spinler4e8078c2019-07-09 13:22:32 -050099 const std::vector<std::string>& additionalData,
Matt Spinler56ad2a02020-03-26 14:00:52 -0500100 const std::vector<std::string>& associations,
101 const phosphor::logging::FFDCEntries& ffdc =
102 phosphor::logging::FFDCEntries{});
Matt Spinler4e8078c2019-07-09 13:22:32 -0500103
104 /**
105 * @brief Erase a PEL based on its OpenBMC event log ID
106 *
107 * @param[in] obmcLogID - the corresponding OpenBMC event log id
108 */
109 void erase(uint32_t obmcLogID);
110
111 /** @brief Says if an OpenBMC event log may not be manually deleted at this
112 * time because its corresponding PEL cannot be.
113 *
114 * There are PEL retention policies that can prohibit the manual deletion
115 * of PELs (and therefore OpenBMC event logs).
116 *
117 * @param[in] obmcLogID - the OpenBMC event log ID
118 * @return bool - true if prohibited
119 */
120 bool isDeleteProhibited(uint32_t obmcLogID);
121
Matt Spinlera34ab722019-12-16 10:39:32 -0600122 /**
123 * @brief Return a file descriptor to the raw PEL data
124 *
125 * Throws InvalidArgument if the PEL ID isn't found,
126 * and InternalFailure if anything else fails.
127 *
128 * @param[in] pelID - The PEL ID to get the data for
129 *
130 * @return unix_fd - File descriptor to the file that contains the PEL
131 */
132 sdbusplus::message::unix_fd getPEL(uint32_t pelID) override;
133
134 /**
135 * @brief Returns data for the PEL corresponding to an OpenBMC
136 * event log.
137 *
138 * @param[in] obmcLogID - The OpenBMC event log ID
139 *
140 * @return vector<uint8_t> - The raw PEL data
141 */
142 std::vector<uint8_t> getPELFromOBMCID(uint32_t obmcLogID) override;
143
144 /**
145 * @brief The D-Bus method called when a host successfully processes
146 * a PEL.
147 *
148 * This D-Bus method is called from the PLDM daemon when they get an
149 * 'Ack PEL' PLDM message from the host, which indicates the host
150 * firmware successfully sent it to the OS and this code doesn't need
151 * to send it to the host again.
152 *
153 * @param[in] pelID - The PEL ID
154 */
155 void hostAck(uint32_t pelID) override;
156
157 /**
158 * @brief D-Bus method called when the host rejects a PEL.
159 *
160 * This D-Bus method is called from the PLDM daemon when they get an
161 * 'Ack PEL' PLDM message from the host with a payload that says
162 * something when wrong.
163 *
164 * The choices are either:
165 * * Host Full - The host's staging area is full - try again later
166 * * Malrformed PEL - The host received an invalid PEL
167 *
168 * @param[in] pelID - The PEL ID
169 * @param[in] reason - One of the above two reasons
170 */
171 void hostReject(uint32_t pelID, RejectionReason reason) override;
172
Matt Spinler19e72902020-01-24 11:05:20 -0600173 /**
174 * @brief Converts the ESEL field in an OpenBMC event log to a
175 * vector of uint8_ts that just contains the PEL data.
176 *
177 * That data string looks like: "50 48 00 ab ..."
178 *
179 * Throws an exception on any failures.
180 *
181 * @param[in] esel - The ESEL string
182 *
183 * @return std::vector<uint8_t> - The contained PEL data
184 */
185 static std::vector<uint8_t> eselToRawData(const std::string& esel);
186
Matt Spinler4e8078c2019-07-09 13:22:32 -0500187 private:
188 /**
189 * @brief Adds a received raw PEL to the PEL repository
190 *
191 * @param[in] rawPelPath - The path to the file that contains the
192 * raw PEL.
193 * @param[in] obmcLogID - the corresponding OpenBMC event log id
194 */
195 void addRawPEL(const std::string& rawPelPath, uint32_t obmcLogID);
196
197 /**
198 * @brief Creates a PEL based on the OpenBMC event log contents.
199 *
200 * @param[in] message - The event log message property
201 * @param[in] obmcLogID - the corresponding OpenBMC event log id
202 * @param[in] timestamp - The timestamp property
203 * @param[in] severity - The event log severity
204 * @param[in] additionalData - The AdditionalData property
205 * @param[in] associations - The associations property
Matt Spinler56ad2a02020-03-26 14:00:52 -0500206 * @param[in] ffdc - A vector of FFDC file information
Matt Spinler4e8078c2019-07-09 13:22:32 -0500207 */
208 void createPEL(const std::string& message, uint32_t obmcLogID,
Matt Spinler367144c2019-09-19 15:33:52 -0500209 uint64_t timestamp, phosphor::logging::Entry::Level severity,
Matt Spinler4e8078c2019-07-09 13:22:32 -0500210 const std::vector<std::string>& additionalData,
Matt Spinler56ad2a02020-03-26 14:00:52 -0500211 const std::vector<std::string>& associations,
212 const phosphor::logging::FFDCEntries& ffdc);
Matt Spinler4e8078c2019-07-09 13:22:32 -0500213
214 /**
Matt Spinler6b1a5c82020-01-07 08:48:53 -0600215 * @brief Schedules a close of the file descriptor to occur from
216 * the event loop.
217 *
218 * Uses sd_event_add_defer
219 *
220 * @param[in] fd - The file descriptor to close
221 */
222 void scheduleFDClose(int fd);
223
224 /**
225 * @brief Closes the file descriptor passed in.
226 *
227 * This is called from the event loop to close FDs returned
228 * from getPEL().
229 *
230 * @param[in] fd - The file descriptor to close
231 * @param[in] source - The event source object used
232 */
233 void closeFD(int fd, sdeventplus::source::EventBase& source);
234
235 /**
Matt Spinler19e72902020-01-24 11:05:20 -0600236 * @brief Adds a PEL to the repository given its data
237 *
238 * @param[in] pelData - The PEL to add as a vector of uint8_ts
239 * @param[in] obmcLogID - the OpenBMC event log ID
240 */
241 void addPEL(std::vector<uint8_t>& pelData, uint32_t obmcLogID);
242
243 /**
244 * @brief Adds the PEL stored in the ESEL field of the AdditionalData
245 * property of an OpenBMC event log to the repository.
246 *
247 * @param[in] esel - The ESEL AdditionalData contents
248 * @param[in] obmcLogID - The OpenBMC event log ID
249 */
250 void addESELPEL(const std::string& esel, uint32_t obmcLogID);
251
252 /**
Matt Spinler56ad2a02020-03-26 14:00:52 -0500253 * @brief Converts the D-Bus FFDC method argument into a data
254 * structure understood by the PEL code.
255 *
256 * @param[in] ffdc - A vector of FFDC file information
257 *
258 * @return PelFFDC - The PEL FFDC data structure
259 */
260 PelFFDC convertToPelFFDC(const phosphor::logging::FFDCEntries& ffdc);
261
262 /**
Matt Spinler7e727a32020-07-07 15:00:17 -0500263 * @brief Schedules a PEL repository prune to occur from
264 * the event loop.
265 *
266 * Uses sd_event_add_defer
267 */
268 void scheduleRepoPrune();
269
270 /**
271 * @brief Prunes old PELs out of the repository to save space.
272 *
273 * This is called from the event loop.
274 *
275 * @param[in] source - The event source object used
276 */
277 void pruneRepo(sdeventplus::source::EventBase& source);
278
279 /**
Matt Spinlerff9cec22020-07-15 13:06:35 -0500280 * @brief Sets up an inotify watch to watch for deleted PEL
281 * files. Calls pelFileDeleted() when that occurs.
282 */
283 void setupPELDeleteWatch();
284
285 /**
286 * @brief Called when the inotify watch put on the repository directory
287 * detects a PEL file was deleted.
288 *
289 * Will tell the Repository class about the deleted PEL, and then tell
290 * the log manager class to delete the corresponding OpenBMC event log.
291 */
292 void pelFileDeleted(sdeventplus::source::IO& io, int fd, uint32_t revents);
293
294 /**
Matt Spinler4e8078c2019-07-09 13:22:32 -0500295 * @brief Reference to phosphor-logging's Manager class
296 */
Matt Spinler367144c2019-09-19 15:33:52 -0500297 phosphor::logging::internal::Manager& _logManager;
Matt Spinler89fa0822019-07-17 13:54:30 -0500298
299 /**
Matt Spinlerf682b402019-12-18 13:48:08 -0600300 * @brief Handles creating event logs/PELs from within
301 * the PEL extension code
302 */
303 EventLogger _eventLogger;
304
305 /**
Matt Spinler89fa0822019-07-17 13:54:30 -0500306 * @brief The PEL repository object
307 */
308 Repository _repo;
Matt Spinlerc8705e22019-09-11 12:36:07 -0500309
310 /**
Matt Spinler367144c2019-09-19 15:33:52 -0500311 * @brief The PEL message registry object
312 */
313 message::Registry _registry;
314
315 /**
Matt Spinlerff9cec22020-07-15 13:06:35 -0500316 * @brief The Event object this class uses
317 */
318 sdeventplus::Event _event;
319
320 /**
Matt Spinlerc8705e22019-09-11 12:36:07 -0500321 * @brief The API the PEL sections use to gather data
322 */
323 std::unique_ptr<DataInterfaceBase> _dataIface;
Matt Spinlerf60ac272019-12-11 13:47:50 -0600324
325 /**
326 * @brief The HostNotifier object used for telling the
327 * host about new PELs
328 */
329 std::unique_ptr<HostNotifier> _hostNotifier;
Matt Spinler6b1a5c82020-01-07 08:48:53 -0600330
331 /**
332 * @brief The event source for closing a PEL file descriptor after
333 * it has been returned from the getPEL D-Bus method.
334 */
335 std::unique_ptr<sdeventplus::source::Defer> _fdCloserEventSource;
Matt Spinler7e727a32020-07-07 15:00:17 -0500336
337 /**
338 * @brief The even source for removing old PELs when the repo is
339 * running out of space to make room for new ones.
340 */
341 std::unique_ptr<sdeventplus::source::Defer> _repoPrunerEventSource;
Matt Spinlerff9cec22020-07-15 13:06:35 -0500342
343 /**
344 * @brief The even source for watching for deleted PEL files.
345 */
346 std::unique_ptr<sdeventplus::source::IO> _pelFileDeleteEventSource;
347
348 /**
349 * @brief The file descriptor returned by inotify_init1() used
350 * for watching for deleted PEL files.
351 */
352 int _pelFileDeleteFD = -1;
353
354 /**
355 * @brief The file descriptor returned by inotify_add_watch().
356 */
357 int _pelFileDeleteWatchFD = -1;
Matt Spinler4e8078c2019-07-09 13:22:32 -0500358};
359
360} // namespace pels
361} // namespace openpower