blob: aa4a393a4b079ce2b6cd2c7d912b738796579724 [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 Spinler44893cc2020-08-26 11:34:17 -050018#include <xyz/openbmc_project/Logging/Create/server.hpp>
Matt Spinlera34ab722019-12-16 10:39:32 -060019
Matt Spinler4e8078c2019-07-09 13:22:32 -050020namespace openpower
21{
22namespace pels
23{
24
Matt Spinlera34ab722019-12-16 10:39:32 -060025using PELInterface = sdbusplus::server::object::object<
26 sdbusplus::org::open_power::Logging::server::PEL>;
27
Matt Spinler4e8078c2019-07-09 13:22:32 -050028/**
29 * @brief PEL manager object
30 */
Matt Spinlera34ab722019-12-16 10:39:32 -060031class Manager : public PELInterface
Matt Spinler4e8078c2019-07-09 13:22:32 -050032{
33 public:
34 Manager() = delete;
Matt Spinler4e8078c2019-07-09 13:22:32 -050035 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 Spinlerff9cec22020-07-15 13:06:35 -050055 _event(sdeventplus::Event::get_default()),
Matt Spinler367144c2019-09-19 15:33:52 -050056 _dataIface(std::move(dataIface))
Matt Spinler4e8078c2019-07-09 13:22:32 -050057 {
Adriana Kobylake7d271a2020-12-07 14:32:44 -060058 for (const auto& entry : _logManager.entries)
59 {
60 setEntryPath(entry.first);
Vijay Lobocbc93a42021-05-20 19:04:07 -050061 setServiceProviderNotifyFlag(entry.first);
Adriana Kobylake7d271a2020-12-07 14:32:44 -060062 }
Matt Spinlerff9cec22020-07-15 13:06:35 -050063 setupPELDeleteWatch();
Matt Spinler4e8078c2019-07-09 13:22:32 -050064 }
65
66 /**
Matt Spinlerf60ac272019-12-11 13:47:50 -060067 * @brief constructor that enables host notification
68 *
69 * @param[in] logManager - internal::Manager object
70 * @param[in] dataIface - The data interface object
Matt Spinlerf682b402019-12-18 13:48:08 -060071 * @param[in] creatorFunc - The function that EventLogger will
72 * use for creating event logs
Matt Spinlerf60ac272019-12-11 13:47:50 -060073 * @param[in] hostIface - The hostInterface object
74 */
75 Manager(phosphor::logging::internal::Manager& logManager,
76 std::unique_ptr<DataInterfaceBase> dataIface,
Matt Spinlerf682b402019-12-18 13:48:08 -060077 EventLogger::LogFunction creatorFunc,
Matt Spinlerf60ac272019-12-11 13:47:50 -060078 std::unique_ptr<HostInterface> hostIface) :
Matt Spinlerf682b402019-12-18 13:48:08 -060079 Manager(logManager, std::move(dataIface), std::move(creatorFunc))
Matt Spinlerf60ac272019-12-11 13:47:50 -060080 {
81 _hostNotifier = std::make_unique<HostNotifier>(
82 _repo, *(_dataIface.get()), std::move(hostIface));
83 }
84
85 /**
Matt Spinlerff9cec22020-07-15 13:06:35 -050086 * @brief Destructor
87 */
88 ~Manager();
89
90 /**
Matt Spinler4e8078c2019-07-09 13:22:32 -050091 * @brief Creates a PEL based on the OpenBMC event log contents. If
92 * a PEL was passed in via the RAWPEL specifier in the
93 * additionalData parameter, use that instead.
94 *
95 * @param[in] message - the event log message property
96 * @param[in] obmcLogID - the corresponding OpenBMC event log id
97 * @param[in] timestamp - the Timestamp property
98 * @param[in] severity - the event log severity
99 * @param[in] additionalData - the AdditionalData property
100 * @param[in] associations - the Associations property
Matt Spinler56ad2a02020-03-26 14:00:52 -0500101 * @param[in] ffdc - A vector of FFDC file information
Matt Spinler4e8078c2019-07-09 13:22:32 -0500102 */
103 void create(const std::string& message, uint32_t obmcLogID,
Matt Spinler367144c2019-09-19 15:33:52 -0500104 uint64_t timestamp, phosphor::logging::Entry::Level severity,
Matt Spinler4e8078c2019-07-09 13:22:32 -0500105 const std::vector<std::string>& additionalData,
Matt Spinler56ad2a02020-03-26 14:00:52 -0500106 const std::vector<std::string>& associations,
107 const phosphor::logging::FFDCEntries& ffdc =
108 phosphor::logging::FFDCEntries{});
Matt Spinler4e8078c2019-07-09 13:22:32 -0500109
110 /**
111 * @brief Erase a PEL based on its OpenBMC event log ID
112 *
113 * @param[in] obmcLogID - the corresponding OpenBMC event log id
114 */
115 void erase(uint32_t obmcLogID);
116
117 /** @brief Says if an OpenBMC event log may not be manually deleted at this
118 * time because its corresponding PEL cannot be.
119 *
120 * There are PEL retention policies that can prohibit the manual deletion
121 * of PELs (and therefore OpenBMC event logs).
122 *
123 * @param[in] obmcLogID - the OpenBMC event log ID
124 * @return bool - true if prohibited
125 */
126 bool isDeleteProhibited(uint32_t obmcLogID);
127
Matt Spinlera34ab722019-12-16 10:39:32 -0600128 /**
129 * @brief Return a file descriptor to the raw PEL data
130 *
131 * Throws InvalidArgument if the PEL ID isn't found,
132 * and InternalFailure if anything else fails.
133 *
134 * @param[in] pelID - The PEL ID to get the data for
135 *
136 * @return unix_fd - File descriptor to the file that contains the PEL
137 */
138 sdbusplus::message::unix_fd getPEL(uint32_t pelID) override;
139
140 /**
141 * @brief Returns data for the PEL corresponding to an OpenBMC
142 * event log.
143 *
144 * @param[in] obmcLogID - The OpenBMC event log ID
145 *
146 * @return vector<uint8_t> - The raw PEL data
147 */
148 std::vector<uint8_t> getPELFromOBMCID(uint32_t obmcLogID) override;
149
150 /**
151 * @brief The D-Bus method called when a host successfully processes
152 * 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, which indicates the host
156 * firmware successfully sent it to the OS and this code doesn't need
157 * to send it to the host again.
158 *
159 * @param[in] pelID - The PEL ID
160 */
161 void hostAck(uint32_t pelID) override;
162
163 /**
164 * @brief D-Bus method called when the host rejects a PEL.
165 *
166 * This D-Bus method is called from the PLDM daemon when they get an
167 * 'Ack PEL' PLDM message from the host with a payload that says
168 * something when wrong.
169 *
170 * The choices are either:
171 * * Host Full - The host's staging area is full - try again later
172 * * Malrformed PEL - The host received an invalid PEL
173 *
174 * @param[in] pelID - The PEL ID
175 * @param[in] reason - One of the above two reasons
176 */
177 void hostReject(uint32_t pelID, RejectionReason reason) override;
178
Matt Spinler44893cc2020-08-26 11:34:17 -0500179 /**
180 * @brief D-Bus method to create a PEL/OpenBMC event log and
181 * return the created OpenBMC and PEL log IDs.
182 *
183 * The same as the CreateWithFFDCFiles method on the
184 * xyz.openbmc_project.Logging.Create interface, except for
185 * the return values.
186 *
187 * @param[in] message - The event log message property
188 * @param[in] severity - The event log severity
189 * @param[in] additionalData - The AdditionalData property
190 * @param[in] ffdc - A vector of FFDC file information
191 */
Matt Spinler9cc30072020-09-16 15:39:34 -0500192 std::tuple<uint32_t, uint32_t> createPELWithFFDCFiles(
193 std::string message, phosphor::logging::Entry::Level severity,
194 std::map<std::string, std::string> additionalData,
195 std::vector<std::tuple<sdbusplus::xyz::openbmc_project::Logging::
196 server::Create::FFDCFormat,
197 uint8_t, uint8_t, sdbusplus::message::unix_fd>>
Matt Spinler44893cc2020-08-26 11:34:17 -0500198 fFDC) override;
Matt Spinler9cc30072020-09-16 15:39:34 -0500199
Matt Spinler19e72902020-01-24 11:05:20 -0600200 /**
201 * @brief Converts the ESEL field in an OpenBMC event log to a
202 * vector of uint8_ts that just contains the PEL data.
203 *
204 * That data string looks like: "50 48 00 ab ..."
205 *
206 * Throws an exception on any failures.
207 *
208 * @param[in] esel - The ESEL string
209 *
210 * @return std::vector<uint8_t> - The contained PEL data
211 */
212 static std::vector<uint8_t> eselToRawData(const std::string& esel);
213
Vijay Lobod354a392021-06-01 16:21:02 -0500214 /**
Vijay Lobo593a4c62021-06-16 14:25:26 -0500215 * @brief Generate resolution string from the PEL
216 *
217 * @param[in] pel - The PEL to use
218 */
219 std::string getResolution(const openpower::pels::PEL& pel) const;
220
221 /**
Vijay Lobod354a392021-06-01 16:21:02 -0500222 * @brief Generate event ID from the PEL
223 *
224 * @param[in] pel - The PEL to use
225 */
226 std::string getEventId(const openpower::pels::PEL& pel) const;
227
Ramesh Iyyarf4203c42021-06-24 06:09:23 -0500228 /** @brief Implementation for GetPELIdFromBMCLogId
229 *
230 * Returns the PEL Id (aka Entry ID (EID)) based on the given
231 * BMC event log id.
232 *
233 * @param[in] bmcLogId - The BMC event log id of the PEL to retrieve
234 * the PEL id.
235 *
236 * @return uint32_t - The Id of the PEL.
237 * Throw "InvalidArgument" if not found.
238 */
239 uint32_t getPELIdFromBMCLogId(uint32_t bmcLogId) override;
240
Ramesh Iyyar530efbf2021-06-24 06:22:22 -0500241 /** @brief Implementation for GetBMCLogIdFromPELId
242 *
243 * Returns the BMC event log id based on the given PEL id
244 * (aka Entry ID (EID)).
245 *
246 * @param[in] pelId - The PEL id to retrieve the BMC event log id.
247 *
248 * @return uint32_t - The BMC event log id of the PEL.
249 * Throw "InvalidArgument" if not found.
250 */
251 uint32_t getBMCLogIdFromPELId(uint32_t pelId) override;
252
Matt Spinler4e8078c2019-07-09 13:22:32 -0500253 private:
254 /**
255 * @brief Adds a received raw PEL to the PEL repository
256 *
257 * @param[in] rawPelPath - The path to the file that contains the
258 * raw PEL.
259 * @param[in] obmcLogID - the corresponding OpenBMC event log id
260 */
261 void addRawPEL(const std::string& rawPelPath, uint32_t obmcLogID);
262
263 /**
264 * @brief Creates a PEL based on the OpenBMC event log contents.
265 *
266 * @param[in] message - The event log message property
267 * @param[in] obmcLogID - the corresponding OpenBMC event log id
268 * @param[in] timestamp - The timestamp property
269 * @param[in] severity - The event log severity
270 * @param[in] additionalData - The AdditionalData property
271 * @param[in] associations - The associations property
Matt Spinler56ad2a02020-03-26 14:00:52 -0500272 * @param[in] ffdc - A vector of FFDC file information
Matt Spinler4e8078c2019-07-09 13:22:32 -0500273 */
274 void createPEL(const std::string& message, uint32_t obmcLogID,
Matt Spinler367144c2019-09-19 15:33:52 -0500275 uint64_t timestamp, phosphor::logging::Entry::Level severity,
Matt Spinler4e8078c2019-07-09 13:22:32 -0500276 const std::vector<std::string>& additionalData,
Matt Spinler56ad2a02020-03-26 14:00:52 -0500277 const std::vector<std::string>& associations,
278 const phosphor::logging::FFDCEntries& ffdc);
Matt Spinler4e8078c2019-07-09 13:22:32 -0500279
280 /**
Matt Spinler6b1a5c82020-01-07 08:48:53 -0600281 * @brief Schedules a close of the file descriptor to occur from
282 * the event loop.
283 *
284 * Uses sd_event_add_defer
285 *
286 * @param[in] fd - The file descriptor to close
287 */
288 void scheduleFDClose(int fd);
289
290 /**
291 * @brief Closes the file descriptor passed in.
292 *
293 * This is called from the event loop to close FDs returned
294 * from getPEL().
295 *
296 * @param[in] fd - The file descriptor to close
297 * @param[in] source - The event source object used
298 */
299 void closeFD(int fd, sdeventplus::source::EventBase& source);
300
301 /**
Matt Spinler19e72902020-01-24 11:05:20 -0600302 * @brief Adds a PEL to the repository given its data
303 *
304 * @param[in] pelData - The PEL to add as a vector of uint8_ts
305 * @param[in] obmcLogID - the OpenBMC event log ID
306 */
307 void addPEL(std::vector<uint8_t>& pelData, uint32_t obmcLogID);
308
309 /**
310 * @brief Adds the PEL stored in the ESEL field of the AdditionalData
311 * property of an OpenBMC event log to the repository.
312 *
313 * @param[in] esel - The ESEL AdditionalData contents
314 * @param[in] obmcLogID - The OpenBMC event log ID
315 */
316 void addESELPEL(const std::string& esel, uint32_t obmcLogID);
317
318 /**
Matt Spinler56ad2a02020-03-26 14:00:52 -0500319 * @brief Converts the D-Bus FFDC method argument into a data
320 * structure understood by the PEL code.
321 *
322 * @param[in] ffdc - A vector of FFDC file information
323 *
324 * @return PelFFDC - The PEL FFDC data structure
325 */
326 PelFFDC convertToPelFFDC(const phosphor::logging::FFDCEntries& ffdc);
327
328 /**
Matt Spinler7e727a32020-07-07 15:00:17 -0500329 * @brief Schedules a PEL repository prune to occur from
330 * the event loop.
331 *
332 * Uses sd_event_add_defer
333 */
334 void scheduleRepoPrune();
335
336 /**
337 * @brief Prunes old PELs out of the repository to save space.
338 *
339 * This is called from the event loop.
340 *
341 * @param[in] source - The event source object used
342 */
343 void pruneRepo(sdeventplus::source::EventBase& source);
344
345 /**
Matt Spinlerff9cec22020-07-15 13:06:35 -0500346 * @brief Sets up an inotify watch to watch for deleted PEL
347 * files. Calls pelFileDeleted() when that occurs.
348 */
349 void setupPELDeleteWatch();
350
351 /**
352 * @brief Called when the inotify watch put on the repository directory
353 * detects a PEL file was deleted.
354 *
355 * Will tell the Repository class about the deleted PEL, and then tell
356 * the log manager class to delete the corresponding OpenBMC event log.
357 */
358 void pelFileDeleted(sdeventplus::source::IO& io, int fd, uint32_t revents);
359
360 /**
Andrew Geissler44fc3162020-07-09 09:21:31 -0500361 * @brief Check if the input PEL should cause a quiesce of the system
362 *
363 * If QuiesceOnHwError is enabled within phosphor-settings and the PEL
Matt Spinlerb2abc042021-05-17 15:32:50 -0600364 * from the host has a severity which is not SeverityType::nonError or
365 * recovered then execute the quiesce and boot block logic.
Andrew Geissler44fc3162020-07-09 09:21:31 -0500366 *
367 * @param[in] pel - The PEL to check
368 */
369 void checkPelAndQuiesce(std::unique_ptr<openpower::pels::PEL>& pel);
370
371 /**
Vijay Lobod354a392021-06-01 16:21:02 -0500372 * @brief Update eventId D-bus property for this error log
373 *
374 * Update the eventId property of D-bus with SRC and hexwords from the
375 * PEL created
376 *
377 * @param[in] pel - The PEL to use
378 */
379 void updateEventId(std::unique_ptr<openpower::pels::PEL>& pel);
380
381 /**
Adriana Kobylake7d271a2020-12-07 14:32:44 -0600382 * @brief Sets the FilePath of the specified error log entry to the PEL file
383 * path.
384 *
385 * @param[in] obmcLogID - The OpenBMC entry log ID
386 */
387 void setEntryPath(uint32_t obmcLogID);
388
389 /**
Vijay Lobocbc93a42021-05-20 19:04:07 -0500390 * @brief Sets the serviceProviderNotify D-bus property of PEL.
391 *
392 * @param[in] obmcLogID - The OpenBMC entry log ID
393 */
394 void setServiceProviderNotifyFlag(uint32_t obmcLogID);
395
396 /**
Vijay Lobo593a4c62021-06-16 14:25:26 -0500397 * @brief Update resolution D-bus property for this error log
398 *
399 * Update the resolution property of D-bus with callouts extracted from PEL
400 *
401 * @param[in] pel - The PEL to use
402 */
403 void updateResolution(std::unique_ptr<openpower::pels::PEL>& pel);
404
405 /**
Matt Spinler4e8078c2019-07-09 13:22:32 -0500406 * @brief Reference to phosphor-logging's Manager class
407 */
Matt Spinler367144c2019-09-19 15:33:52 -0500408 phosphor::logging::internal::Manager& _logManager;
Matt Spinler89fa0822019-07-17 13:54:30 -0500409
410 /**
Matt Spinlerf682b402019-12-18 13:48:08 -0600411 * @brief Handles creating event logs/PELs from within
412 * the PEL extension code
413 */
414 EventLogger _eventLogger;
415
416 /**
Matt Spinler89fa0822019-07-17 13:54:30 -0500417 * @brief The PEL repository object
418 */
419 Repository _repo;
Matt Spinlerc8705e22019-09-11 12:36:07 -0500420
421 /**
Matt Spinler367144c2019-09-19 15:33:52 -0500422 * @brief The PEL message registry object
423 */
424 message::Registry _registry;
425
426 /**
Matt Spinlerff9cec22020-07-15 13:06:35 -0500427 * @brief The Event object this class uses
428 */
429 sdeventplus::Event _event;
430
431 /**
Matt Spinlerc8705e22019-09-11 12:36:07 -0500432 * @brief The API the PEL sections use to gather data
433 */
434 std::unique_ptr<DataInterfaceBase> _dataIface;
Matt Spinlerf60ac272019-12-11 13:47:50 -0600435
436 /**
437 * @brief The HostNotifier object used for telling the
438 * host about new PELs
439 */
440 std::unique_ptr<HostNotifier> _hostNotifier;
Matt Spinler6b1a5c82020-01-07 08:48:53 -0600441
442 /**
443 * @brief The event source for closing a PEL file descriptor after
444 * it has been returned from the getPEL D-Bus method.
445 */
446 std::unique_ptr<sdeventplus::source::Defer> _fdCloserEventSource;
Matt Spinler7e727a32020-07-07 15:00:17 -0500447
448 /**
449 * @brief The even source for removing old PELs when the repo is
450 * running out of space to make room for new ones.
451 */
452 std::unique_ptr<sdeventplus::source::Defer> _repoPrunerEventSource;
Matt Spinlerff9cec22020-07-15 13:06:35 -0500453
454 /**
455 * @brief The even source for watching for deleted PEL files.
456 */
457 std::unique_ptr<sdeventplus::source::IO> _pelFileDeleteEventSource;
458
459 /**
460 * @brief The file descriptor returned by inotify_init1() used
461 * for watching for deleted PEL files.
462 */
463 int _pelFileDeleteFD = -1;
464
465 /**
466 * @brief The file descriptor returned by inotify_add_watch().
467 */
468 int _pelFileDeleteWatchFD = -1;
Matt Spinler4e8078c2019-07-09 13:22:32 -0500469};
470
471} // namespace pels
472} // namespace openpower