blob: 5923f0039ca2e89f6498ca7aaaf0cf35478dfee9 [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
Vijay Loboafb1b462021-07-21 23:29:13 -050014#include <org/open_power/Logging/PEL/Entry/server.hpp>
Matt Spinlera34ab722019-12-16 10:39:32 -060015#include <org/open_power/Logging/PEL/server.hpp>
16#include <sdbusplus/server.hpp>
Matt Spinler6b1a5c82020-01-07 08:48:53 -060017#include <sdeventplus/event.hpp>
18#include <sdeventplus/source/event.hpp>
Matt Spinler44893cc2020-08-26 11:34:17 -050019#include <xyz/openbmc_project/Logging/Create/server.hpp>
Matt Spinlera34ab722019-12-16 10:39:32 -060020
Matt Spinler4e8078c2019-07-09 13:22:32 -050021namespace openpower
22{
23namespace pels
24{
25
Matt Spinlera34ab722019-12-16 10:39:32 -060026using PELInterface = sdbusplus::server::object::object<
27 sdbusplus::org::open_power::Logging::server::PEL>;
28
Vijay Loboafb1b462021-07-21 23:29:13 -050029using PELEntry = sdbusplus::org::open_power::Logging::PEL::server::Entry;
30using PropertiesVariant = PELEntry::PropertiesVariant;
31
Matt Spinler4e8078c2019-07-09 13:22:32 -050032/**
33 * @brief PEL manager object
34 */
Matt Spinlera34ab722019-12-16 10:39:32 -060035class Manager : public PELInterface
Matt Spinler4e8078c2019-07-09 13:22:32 -050036{
37 public:
38 Manager() = delete;
Matt Spinler4e8078c2019-07-09 13:22:32 -050039 Manager(const Manager&) = default;
40 Manager& operator=(const Manager&) = default;
41 Manager(Manager&&) = default;
42 Manager& operator=(Manager&&) = default;
43
44 /**
45 * @brief constructor
46 *
47 * @param[in] logManager - internal::Manager object
Matt Spinlerf60ac272019-12-11 13:47:50 -060048 * @param[in] dataIface - The data interface object
Matt Spinlerf682b402019-12-18 13:48:08 -060049 * @param[in] creatorFunc - The function that EventLogger will
50 * use for creating event logs
Matt Spinler4e8078c2019-07-09 13:22:32 -050051 */
Matt Spinlerf60ac272019-12-11 13:47:50 -060052 Manager(phosphor::logging::internal::Manager& logManager,
Matt Spinlerf682b402019-12-18 13:48:08 -060053 std::unique_ptr<DataInterfaceBase> dataIface,
54 EventLogger::LogFunction creatorFunc) :
Matt Spinlera34ab722019-12-16 10:39:32 -060055 PELInterface(logManager.getBus(), OBJ_LOGGING),
Matt Spinler104e9362020-04-02 09:34:41 -050056 _logManager(logManager), _eventLogger(std::move(creatorFunc)),
Matt Spinlerf682b402019-12-18 13:48:08 -060057 _repo(getPELRepoPath()),
Matt Spinler0d804ef2020-05-12 16:16:26 -050058 _registry(getPELReadOnlyDataPath() / message::registryFileName),
Matt Spinlerff9cec22020-07-15 13:06:35 -050059 _event(sdeventplus::Event::get_default()),
Matt Spinler367144c2019-09-19 15:33:52 -050060 _dataIface(std::move(dataIface))
Matt Spinler4e8078c2019-07-09 13:22:32 -050061 {
Adriana Kobylake7d271a2020-12-07 14:32:44 -060062 for (const auto& entry : _logManager.entries)
63 {
64 setEntryPath(entry.first);
Vijay Lobocbc93a42021-05-20 19:04:07 -050065 setServiceProviderNotifyFlag(entry.first);
Vijay Loboafb1b462021-07-21 23:29:13 -050066 // Create PELEntry interface and setup properties with their values
67 createPELEntry(entry.first);
Adriana Kobylake7d271a2020-12-07 14:32:44 -060068 }
Matt Spinlerff9cec22020-07-15 13:06:35 -050069 setupPELDeleteWatch();
Matt Spinler4e8078c2019-07-09 13:22:32 -050070 }
71
72 /**
Matt Spinlerf60ac272019-12-11 13:47:50 -060073 * @brief constructor that enables host notification
74 *
75 * @param[in] logManager - internal::Manager object
76 * @param[in] dataIface - The data interface object
Matt Spinlerf682b402019-12-18 13:48:08 -060077 * @param[in] creatorFunc - The function that EventLogger will
78 * use for creating event logs
Matt Spinlerf60ac272019-12-11 13:47:50 -060079 * @param[in] hostIface - The hostInterface object
80 */
81 Manager(phosphor::logging::internal::Manager& logManager,
82 std::unique_ptr<DataInterfaceBase> dataIface,
Matt Spinlerf682b402019-12-18 13:48:08 -060083 EventLogger::LogFunction creatorFunc,
Matt Spinlerf60ac272019-12-11 13:47:50 -060084 std::unique_ptr<HostInterface> hostIface) :
Matt Spinlerf682b402019-12-18 13:48:08 -060085 Manager(logManager, std::move(dataIface), std::move(creatorFunc))
Matt Spinlerf60ac272019-12-11 13:47:50 -060086 {
87 _hostNotifier = std::make_unique<HostNotifier>(
88 _repo, *(_dataIface.get()), std::move(hostIface));
89 }
90
91 /**
Matt Spinlerff9cec22020-07-15 13:06:35 -050092 * @brief Destructor
93 */
94 ~Manager();
95
96 /**
Matt Spinler4e8078c2019-07-09 13:22:32 -050097 * @brief Creates a PEL based on the OpenBMC event log contents. If
98 * a PEL was passed in via the RAWPEL specifier in the
99 * additionalData parameter, use that instead.
100 *
101 * @param[in] message - the event log message property
102 * @param[in] obmcLogID - the corresponding OpenBMC event log id
103 * @param[in] timestamp - the Timestamp property
104 * @param[in] severity - the event log severity
105 * @param[in] additionalData - the AdditionalData property
106 * @param[in] associations - the Associations property
Matt Spinler56ad2a02020-03-26 14:00:52 -0500107 * @param[in] ffdc - A vector of FFDC file information
Matt Spinler4e8078c2019-07-09 13:22:32 -0500108 */
109 void create(const std::string& message, uint32_t obmcLogID,
Matt Spinler367144c2019-09-19 15:33:52 -0500110 uint64_t timestamp, phosphor::logging::Entry::Level severity,
Matt Spinler4e8078c2019-07-09 13:22:32 -0500111 const std::vector<std::string>& additionalData,
Matt Spinler56ad2a02020-03-26 14:00:52 -0500112 const std::vector<std::string>& associations,
113 const phosphor::logging::FFDCEntries& ffdc =
114 phosphor::logging::FFDCEntries{});
Matt Spinler4e8078c2019-07-09 13:22:32 -0500115
116 /**
117 * @brief Erase a PEL based on its OpenBMC event log ID
118 *
119 * @param[in] obmcLogID - the corresponding OpenBMC event log id
120 */
121 void erase(uint32_t obmcLogID);
122
123 /** @brief Says if an OpenBMC event log may not be manually deleted at this
124 * time because its corresponding PEL cannot be.
125 *
126 * There are PEL retention policies that can prohibit the manual deletion
127 * of PELs (and therefore OpenBMC event logs).
128 *
129 * @param[in] obmcLogID - the OpenBMC event log ID
130 * @return bool - true if prohibited
131 */
132 bool isDeleteProhibited(uint32_t obmcLogID);
133
Matt Spinlera34ab722019-12-16 10:39:32 -0600134 /**
135 * @brief Return a file descriptor to the raw PEL data
136 *
137 * Throws InvalidArgument if the PEL ID isn't found,
138 * and InternalFailure if anything else fails.
139 *
140 * @param[in] pelID - The PEL ID to get the data for
141 *
142 * @return unix_fd - File descriptor to the file that contains the PEL
143 */
144 sdbusplus::message::unix_fd getPEL(uint32_t pelID) override;
145
146 /**
147 * @brief Returns data for the PEL corresponding to an OpenBMC
148 * event log.
149 *
150 * @param[in] obmcLogID - The OpenBMC event log ID
151 *
152 * @return vector<uint8_t> - The raw PEL data
153 */
154 std::vector<uint8_t> getPELFromOBMCID(uint32_t obmcLogID) override;
155
156 /**
157 * @brief The D-Bus method called when a host successfully processes
158 * 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, which indicates the host
162 * firmware successfully sent it to the OS and this code doesn't need
163 * to send it to the host again.
164 *
165 * @param[in] pelID - The PEL ID
166 */
167 void hostAck(uint32_t pelID) override;
168
169 /**
170 * @brief D-Bus method called when the host rejects a PEL.
171 *
172 * This D-Bus method is called from the PLDM daemon when they get an
173 * 'Ack PEL' PLDM message from the host with a payload that says
174 * something when wrong.
175 *
176 * The choices are either:
177 * * Host Full - The host's staging area is full - try again later
178 * * Malrformed PEL - The host received an invalid PEL
179 *
180 * @param[in] pelID - The PEL ID
181 * @param[in] reason - One of the above two reasons
182 */
183 void hostReject(uint32_t pelID, RejectionReason reason) override;
184
Matt Spinler44893cc2020-08-26 11:34:17 -0500185 /**
186 * @brief D-Bus method to create a PEL/OpenBMC event log and
187 * return the created OpenBMC and PEL log IDs.
188 *
189 * The same as the CreateWithFFDCFiles method on the
190 * xyz.openbmc_project.Logging.Create interface, except for
191 * the return values.
192 *
193 * @param[in] message - The event log message property
194 * @param[in] severity - The event log severity
195 * @param[in] additionalData - The AdditionalData property
196 * @param[in] ffdc - A vector of FFDC file information
197 */
Matt Spinler9cc30072020-09-16 15:39:34 -0500198 std::tuple<uint32_t, uint32_t> createPELWithFFDCFiles(
199 std::string message, phosphor::logging::Entry::Level severity,
200 std::map<std::string, std::string> additionalData,
201 std::vector<std::tuple<sdbusplus::xyz::openbmc_project::Logging::
202 server::Create::FFDCFormat,
203 uint8_t, uint8_t, sdbusplus::message::unix_fd>>
Matt Spinler44893cc2020-08-26 11:34:17 -0500204 fFDC) override;
Matt Spinler9cc30072020-09-16 15:39:34 -0500205
Matt Spinler19e72902020-01-24 11:05:20 -0600206 /**
207 * @brief Converts the ESEL field in an OpenBMC event log to a
208 * vector of uint8_ts that just contains the PEL data.
209 *
210 * That data string looks like: "50 48 00 ab ..."
211 *
212 * Throws an exception on any failures.
213 *
214 * @param[in] esel - The ESEL string
215 *
216 * @return std::vector<uint8_t> - The contained PEL data
217 */
218 static std::vector<uint8_t> eselToRawData(const std::string& esel);
219
Vijay Lobod354a392021-06-01 16:21:02 -0500220 /**
Vijay Lobo593a4c62021-06-16 14:25:26 -0500221 * @brief Generate resolution string from the PEL
222 *
223 * @param[in] pel - The PEL to use
224 */
225 std::string getResolution(const openpower::pels::PEL& pel) const;
226
227 /**
Vijay Lobod354a392021-06-01 16:21:02 -0500228 * @brief Generate event ID from the PEL
229 *
230 * @param[in] pel - The PEL to use
231 */
232 std::string getEventId(const openpower::pels::PEL& pel) const;
233
Ramesh Iyyarf4203c42021-06-24 06:09:23 -0500234 /** @brief Implementation for GetPELIdFromBMCLogId
235 *
236 * Returns the PEL Id (aka Entry ID (EID)) based on the given
237 * BMC event log id.
238 *
239 * @param[in] bmcLogId - The BMC event log id of the PEL to retrieve
240 * the PEL id.
241 *
242 * @return uint32_t - The Id of the PEL.
243 * Throw "InvalidArgument" if not found.
244 */
245 uint32_t getPELIdFromBMCLogId(uint32_t bmcLogId) override;
246
Ramesh Iyyar530efbf2021-06-24 06:22:22 -0500247 /** @brief Implementation for GetBMCLogIdFromPELId
248 *
249 * Returns the BMC event log id based on the given PEL id
250 * (aka Entry ID (EID)).
251 *
252 * @param[in] pelId - The PEL id to retrieve the BMC event log id.
253 *
254 * @return uint32_t - The BMC event log id of the PEL.
255 * Throw "InvalidArgument" if not found.
256 */
257 uint32_t getBMCLogIdFromPELId(uint32_t pelId) override;
258
Matt Spinler4e8078c2019-07-09 13:22:32 -0500259 private:
260 /**
261 * @brief Adds a received raw PEL to the PEL repository
262 *
263 * @param[in] rawPelPath - The path to the file that contains the
264 * raw PEL.
265 * @param[in] obmcLogID - the corresponding OpenBMC event log id
266 */
267 void addRawPEL(const std::string& rawPelPath, uint32_t obmcLogID);
268
269 /**
270 * @brief Creates a PEL based on the OpenBMC event log contents.
271 *
272 * @param[in] message - The event log message property
273 * @param[in] obmcLogID - the corresponding OpenBMC event log id
274 * @param[in] timestamp - The timestamp property
275 * @param[in] severity - The event log severity
276 * @param[in] additionalData - The AdditionalData property
277 * @param[in] associations - The associations property
Matt Spinler56ad2a02020-03-26 14:00:52 -0500278 * @param[in] ffdc - A vector of FFDC file information
Matt Spinler4e8078c2019-07-09 13:22:32 -0500279 */
280 void createPEL(const std::string& message, uint32_t obmcLogID,
Matt Spinler367144c2019-09-19 15:33:52 -0500281 uint64_t timestamp, phosphor::logging::Entry::Level severity,
Matt Spinler4e8078c2019-07-09 13:22:32 -0500282 const std::vector<std::string>& additionalData,
Matt Spinler56ad2a02020-03-26 14:00:52 -0500283 const std::vector<std::string>& associations,
284 const phosphor::logging::FFDCEntries& ffdc);
Matt Spinler4e8078c2019-07-09 13:22:32 -0500285
286 /**
Matt Spinler6b1a5c82020-01-07 08:48:53 -0600287 * @brief Schedules a close of the file descriptor to occur from
288 * the event loop.
289 *
290 * Uses sd_event_add_defer
291 *
292 * @param[in] fd - The file descriptor to close
293 */
294 void scheduleFDClose(int fd);
295
296 /**
297 * @brief Closes the file descriptor passed in.
298 *
299 * This is called from the event loop to close FDs returned
300 * from getPEL().
301 *
302 * @param[in] fd - The file descriptor to close
303 * @param[in] source - The event source object used
304 */
305 void closeFD(int fd, sdeventplus::source::EventBase& source);
306
307 /**
Matt Spinler19e72902020-01-24 11:05:20 -0600308 * @brief Adds a PEL to the repository given its data
309 *
310 * @param[in] pelData - The PEL to add as a vector of uint8_ts
311 * @param[in] obmcLogID - the OpenBMC event log ID
312 */
313 void addPEL(std::vector<uint8_t>& pelData, uint32_t obmcLogID);
314
315 /**
316 * @brief Adds the PEL stored in the ESEL field of the AdditionalData
317 * property of an OpenBMC event log to the repository.
318 *
319 * @param[in] esel - The ESEL AdditionalData contents
320 * @param[in] obmcLogID - The OpenBMC event log ID
321 */
322 void addESELPEL(const std::string& esel, uint32_t obmcLogID);
323
324 /**
Matt Spinler56ad2a02020-03-26 14:00:52 -0500325 * @brief Converts the D-Bus FFDC method argument into a data
326 * structure understood by the PEL code.
327 *
328 * @param[in] ffdc - A vector of FFDC file information
329 *
330 * @return PelFFDC - The PEL FFDC data structure
331 */
332 PelFFDC convertToPelFFDC(const phosphor::logging::FFDCEntries& ffdc);
333
334 /**
Matt Spinler7e727a32020-07-07 15:00:17 -0500335 * @brief Schedules a PEL repository prune to occur from
336 * the event loop.
337 *
338 * Uses sd_event_add_defer
339 */
340 void scheduleRepoPrune();
341
342 /**
343 * @brief Prunes old PELs out of the repository to save space.
344 *
345 * This is called from the event loop.
346 *
347 * @param[in] source - The event source object used
348 */
349 void pruneRepo(sdeventplus::source::EventBase& source);
350
351 /**
Matt Spinlerff9cec22020-07-15 13:06:35 -0500352 * @brief Sets up an inotify watch to watch for deleted PEL
353 * files. Calls pelFileDeleted() when that occurs.
354 */
355 void setupPELDeleteWatch();
356
357 /**
358 * @brief Called when the inotify watch put on the repository directory
359 * detects a PEL file was deleted.
360 *
361 * Will tell the Repository class about the deleted PEL, and then tell
362 * the log manager class to delete the corresponding OpenBMC event log.
363 */
364 void pelFileDeleted(sdeventplus::source::IO& io, int fd, uint32_t revents);
365
366 /**
Andrew Geissler44fc3162020-07-09 09:21:31 -0500367 * @brief Check if the input PEL should cause a quiesce of the system
368 *
369 * If QuiesceOnHwError is enabled within phosphor-settings and the PEL
Matt Spinlerb2abc042021-05-17 15:32:50 -0600370 * from the host has a severity which is not SeverityType::nonError or
371 * recovered then execute the quiesce and boot block logic.
Andrew Geissler44fc3162020-07-09 09:21:31 -0500372 *
373 * @param[in] pel - The PEL to check
374 */
375 void checkPelAndQuiesce(std::unique_ptr<openpower::pels::PEL>& pel);
376
377 /**
Vijay Lobod354a392021-06-01 16:21:02 -0500378 * @brief Update eventId D-bus property for this error log
379 *
380 * Update the eventId property of D-bus with SRC and hexwords from the
381 * PEL created
382 *
383 * @param[in] pel - The PEL to use
384 */
385 void updateEventId(std::unique_ptr<openpower::pels::PEL>& pel);
386
387 /**
Adriana Kobylake7d271a2020-12-07 14:32:44 -0600388 * @brief Sets the FilePath of the specified error log entry to the PEL file
389 * path.
390 *
391 * @param[in] obmcLogID - The OpenBMC entry log ID
392 */
393 void setEntryPath(uint32_t obmcLogID);
394
395 /**
Vijay Lobocbc93a42021-05-20 19:04:07 -0500396 * @brief Sets the serviceProviderNotify D-bus property of PEL.
397 *
398 * @param[in] obmcLogID - The OpenBMC entry log ID
399 */
400 void setServiceProviderNotifyFlag(uint32_t obmcLogID);
401
402 /**
Vijay Lobo593a4c62021-06-16 14:25:26 -0500403 * @brief Update resolution D-bus property for this error log
404 *
405 * Update the resolution property of D-bus with callouts extracted from PEL
406 *
407 * @param[in] pel - The PEL to use
408 */
409 void updateResolution(std::unique_ptr<openpower::pels::PEL>& pel);
410
411 /**
Vijay Loboafb1b462021-07-21 23:29:13 -0500412 * @brief Create PELEntry Interface with supported properties
413 *
414 * Create PELEntry Interface and update all the properties which are
415 * supported
416 *
417 * @param[in] obmcLogID - The OpenBMC entry log ID
418 */
419 void createPELEntry(uint32_t obmcLogID);
420
421 /**
Matt Spinler4e8078c2019-07-09 13:22:32 -0500422 * @brief Reference to phosphor-logging's Manager class
423 */
Matt Spinler367144c2019-09-19 15:33:52 -0500424 phosphor::logging::internal::Manager& _logManager;
Matt Spinler89fa0822019-07-17 13:54:30 -0500425
426 /**
Matt Spinlerf682b402019-12-18 13:48:08 -0600427 * @brief Handles creating event logs/PELs from within
428 * the PEL extension code
429 */
430 EventLogger _eventLogger;
431
432 /**
Matt Spinler89fa0822019-07-17 13:54:30 -0500433 * @brief The PEL repository object
434 */
435 Repository _repo;
Matt Spinlerc8705e22019-09-11 12:36:07 -0500436
437 /**
Matt Spinler367144c2019-09-19 15:33:52 -0500438 * @brief The PEL message registry object
439 */
440 message::Registry _registry;
441
442 /**
Matt Spinlerff9cec22020-07-15 13:06:35 -0500443 * @brief The Event object this class uses
444 */
445 sdeventplus::Event _event;
446
447 /**
Matt Spinlerc8705e22019-09-11 12:36:07 -0500448 * @brief The API the PEL sections use to gather data
449 */
450 std::unique_ptr<DataInterfaceBase> _dataIface;
Matt Spinlerf60ac272019-12-11 13:47:50 -0600451
452 /**
Vijay Loboafb1b462021-07-21 23:29:13 -0500453 * @brief The map used to keep track of PEL entry pointer associated with
454 * event log.
455 */
456 std::map<std::string,
457 std::unique_ptr<
458 sdbusplus::org::open_power::Logging::PEL::server::Entry>>
459 _pelEntries;
460
461 /**
Matt Spinlerf60ac272019-12-11 13:47:50 -0600462 * @brief The HostNotifier object used for telling the
463 * host about new PELs
464 */
465 std::unique_ptr<HostNotifier> _hostNotifier;
Matt Spinler6b1a5c82020-01-07 08:48:53 -0600466
467 /**
468 * @brief The event source for closing a PEL file descriptor after
469 * it has been returned from the getPEL D-Bus method.
470 */
471 std::unique_ptr<sdeventplus::source::Defer> _fdCloserEventSource;
Matt Spinler7e727a32020-07-07 15:00:17 -0500472
473 /**
474 * @brief The even source for removing old PELs when the repo is
475 * running out of space to make room for new ones.
476 */
477 std::unique_ptr<sdeventplus::source::Defer> _repoPrunerEventSource;
Matt Spinlerff9cec22020-07-15 13:06:35 -0500478
479 /**
480 * @brief The even source for watching for deleted PEL files.
481 */
482 std::unique_ptr<sdeventplus::source::IO> _pelFileDeleteEventSource;
483
484 /**
485 * @brief The file descriptor returned by inotify_init1() used
486 * for watching for deleted PEL files.
487 */
488 int _pelFileDeleteFD = -1;
489
490 /**
491 * @brief The file descriptor returned by inotify_add_watch().
492 */
493 int _pelFileDeleteWatchFD = -1;
Matt Spinler4e8078c2019-07-09 13:22:32 -0500494};
495
496} // namespace pels
497} // namespace openpower