blob: 59c2e0dbe477e08a65752ed9001608bb445e5226 [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 Spinler9cc30072020-09-16 15:39:34 -050013#include "xyz/openbmc_project/Logging/Create/server.hpp"
Matt Spinler4e8078c2019-07-09 13:22:32 -050014
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 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 {
Matt Spinlerff9cec22020-07-15 13:06:35 -050058 setupPELDeleteWatch();
Matt Spinler4e8078c2019-07-09 13:22:32 -050059 }
60
61 /**
Matt Spinlerf60ac272019-12-11 13:47:50 -060062 * @brief constructor that enables host notification
63 *
64 * @param[in] logManager - internal::Manager object
65 * @param[in] dataIface - The data interface object
Matt Spinlerf682b402019-12-18 13:48:08 -060066 * @param[in] creatorFunc - The function that EventLogger will
67 * use for creating event logs
Matt Spinlerf60ac272019-12-11 13:47:50 -060068 * @param[in] hostIface - The hostInterface object
69 */
70 Manager(phosphor::logging::internal::Manager& logManager,
71 std::unique_ptr<DataInterfaceBase> dataIface,
Matt Spinlerf682b402019-12-18 13:48:08 -060072 EventLogger::LogFunction creatorFunc,
Matt Spinlerf60ac272019-12-11 13:47:50 -060073 std::unique_ptr<HostInterface> hostIface) :
Matt Spinlerf682b402019-12-18 13:48:08 -060074 Manager(logManager, std::move(dataIface), std::move(creatorFunc))
Matt Spinlerf60ac272019-12-11 13:47:50 -060075 {
76 _hostNotifier = std::make_unique<HostNotifier>(
77 _repo, *(_dataIface.get()), std::move(hostIface));
78 }
79
80 /**
Matt Spinlerff9cec22020-07-15 13:06:35 -050081 * @brief Destructor
82 */
83 ~Manager();
84
85 /**
Matt Spinler4e8078c2019-07-09 13:22:32 -050086 * @brief Creates a PEL based on the OpenBMC event log contents. If
87 * a PEL was passed in via the RAWPEL specifier in the
88 * additionalData parameter, use that instead.
89 *
90 * @param[in] message - the event log message property
91 * @param[in] obmcLogID - the corresponding OpenBMC event log id
92 * @param[in] timestamp - the Timestamp property
93 * @param[in] severity - the event log severity
94 * @param[in] additionalData - the AdditionalData property
95 * @param[in] associations - the Associations property
Matt Spinler56ad2a02020-03-26 14:00:52 -050096 * @param[in] ffdc - A vector of FFDC file information
Matt Spinler4e8078c2019-07-09 13:22:32 -050097 */
98 void create(const std::string& message, uint32_t obmcLogID,
Matt Spinler367144c2019-09-19 15:33:52 -050099 uint64_t timestamp, phosphor::logging::Entry::Level severity,
Matt Spinler4e8078c2019-07-09 13:22:32 -0500100 const std::vector<std::string>& additionalData,
Matt Spinler56ad2a02020-03-26 14:00:52 -0500101 const std::vector<std::string>& associations,
102 const phosphor::logging::FFDCEntries& ffdc =
103 phosphor::logging::FFDCEntries{});
Matt Spinler4e8078c2019-07-09 13:22:32 -0500104
105 /**
106 * @brief Erase a PEL based on its OpenBMC event log ID
107 *
108 * @param[in] obmcLogID - the corresponding OpenBMC event log id
109 */
110 void erase(uint32_t obmcLogID);
111
112 /** @brief Says if an OpenBMC event log may not be manually deleted at this
113 * time because its corresponding PEL cannot be.
114 *
115 * There are PEL retention policies that can prohibit the manual deletion
116 * of PELs (and therefore OpenBMC event logs).
117 *
118 * @param[in] obmcLogID - the OpenBMC event log ID
119 * @return bool - true if prohibited
120 */
121 bool isDeleteProhibited(uint32_t obmcLogID);
122
Matt Spinlera34ab722019-12-16 10:39:32 -0600123 /**
124 * @brief Return a file descriptor to the raw PEL data
125 *
126 * Throws InvalidArgument if the PEL ID isn't found,
127 * and InternalFailure if anything else fails.
128 *
129 * @param[in] pelID - The PEL ID to get the data for
130 *
131 * @return unix_fd - File descriptor to the file that contains the PEL
132 */
133 sdbusplus::message::unix_fd getPEL(uint32_t pelID) override;
134
135 /**
136 * @brief Returns data for the PEL corresponding to an OpenBMC
137 * event log.
138 *
139 * @param[in] obmcLogID - The OpenBMC event log ID
140 *
141 * @return vector<uint8_t> - The raw PEL data
142 */
143 std::vector<uint8_t> getPELFromOBMCID(uint32_t obmcLogID) override;
144
145 /**
146 * @brief The D-Bus method called when a host successfully processes
147 * a PEL.
148 *
149 * This D-Bus method is called from the PLDM daemon when they get an
150 * 'Ack PEL' PLDM message from the host, which indicates the host
151 * firmware successfully sent it to the OS and this code doesn't need
152 * to send it to the host again.
153 *
154 * @param[in] pelID - The PEL ID
155 */
156 void hostAck(uint32_t pelID) override;
157
158 /**
159 * @brief D-Bus method called when the host rejects a PEL.
160 *
161 * This D-Bus method is called from the PLDM daemon when they get an
162 * 'Ack PEL' PLDM message from the host with a payload that says
163 * something when wrong.
164 *
165 * The choices are either:
166 * * Host Full - The host's staging area is full - try again later
167 * * Malrformed PEL - The host received an invalid PEL
168 *
169 * @param[in] pelID - The PEL ID
170 * @param[in] reason - One of the above two reasons
171 */
172 void hostReject(uint32_t pelID, RejectionReason reason) override;
173
Matt Spinler9cc30072020-09-16 15:39:34 -0500174 std::tuple<uint32_t, uint32_t> createPELWithFFDCFiles(
175 std::string message, phosphor::logging::Entry::Level severity,
176 std::map<std::string, std::string> additionalData,
177 std::vector<std::tuple<sdbusplus::xyz::openbmc_project::Logging::
178 server::Create::FFDCFormat,
179 uint8_t, uint8_t, sdbusplus::message::unix_fd>>
180 fFDC);
181
Matt Spinler19e72902020-01-24 11:05:20 -0600182 /**
183 * @brief Converts the ESEL field in an OpenBMC event log to a
184 * vector of uint8_ts that just contains the PEL data.
185 *
186 * That data string looks like: "50 48 00 ab ..."
187 *
188 * Throws an exception on any failures.
189 *
190 * @param[in] esel - The ESEL string
191 *
192 * @return std::vector<uint8_t> - The contained PEL data
193 */
194 static std::vector<uint8_t> eselToRawData(const std::string& esel);
195
Matt Spinler4e8078c2019-07-09 13:22:32 -0500196 private:
197 /**
198 * @brief Adds a received raw PEL to the PEL repository
199 *
200 * @param[in] rawPelPath - The path to the file that contains the
201 * raw PEL.
202 * @param[in] obmcLogID - the corresponding OpenBMC event log id
203 */
204 void addRawPEL(const std::string& rawPelPath, uint32_t obmcLogID);
205
206 /**
207 * @brief Creates a PEL based on the OpenBMC event log contents.
208 *
209 * @param[in] message - The event log message property
210 * @param[in] obmcLogID - the corresponding OpenBMC event log id
211 * @param[in] timestamp - The timestamp property
212 * @param[in] severity - The event log severity
213 * @param[in] additionalData - The AdditionalData property
214 * @param[in] associations - The associations property
Matt Spinler56ad2a02020-03-26 14:00:52 -0500215 * @param[in] ffdc - A vector of FFDC file information
Matt Spinler4e8078c2019-07-09 13:22:32 -0500216 */
217 void createPEL(const std::string& message, uint32_t obmcLogID,
Matt Spinler367144c2019-09-19 15:33:52 -0500218 uint64_t timestamp, phosphor::logging::Entry::Level severity,
Matt Spinler4e8078c2019-07-09 13:22:32 -0500219 const std::vector<std::string>& additionalData,
Matt Spinler56ad2a02020-03-26 14:00:52 -0500220 const std::vector<std::string>& associations,
221 const phosphor::logging::FFDCEntries& ffdc);
Matt Spinler4e8078c2019-07-09 13:22:32 -0500222
223 /**
Matt Spinler6b1a5c82020-01-07 08:48:53 -0600224 * @brief Schedules a close of the file descriptor to occur from
225 * the event loop.
226 *
227 * Uses sd_event_add_defer
228 *
229 * @param[in] fd - The file descriptor to close
230 */
231 void scheduleFDClose(int fd);
232
233 /**
234 * @brief Closes the file descriptor passed in.
235 *
236 * This is called from the event loop to close FDs returned
237 * from getPEL().
238 *
239 * @param[in] fd - The file descriptor to close
240 * @param[in] source - The event source object used
241 */
242 void closeFD(int fd, sdeventplus::source::EventBase& source);
243
244 /**
Matt Spinler19e72902020-01-24 11:05:20 -0600245 * @brief Adds a PEL to the repository given its data
246 *
247 * @param[in] pelData - The PEL to add as a vector of uint8_ts
248 * @param[in] obmcLogID - the OpenBMC event log ID
249 */
250 void addPEL(std::vector<uint8_t>& pelData, uint32_t obmcLogID);
251
252 /**
253 * @brief Adds the PEL stored in the ESEL field of the AdditionalData
254 * property of an OpenBMC event log to the repository.
255 *
256 * @param[in] esel - The ESEL AdditionalData contents
257 * @param[in] obmcLogID - The OpenBMC event log ID
258 */
259 void addESELPEL(const std::string& esel, uint32_t obmcLogID);
260
261 /**
Matt Spinler56ad2a02020-03-26 14:00:52 -0500262 * @brief Converts the D-Bus FFDC method argument into a data
263 * structure understood by the PEL code.
264 *
265 * @param[in] ffdc - A vector of FFDC file information
266 *
267 * @return PelFFDC - The PEL FFDC data structure
268 */
269 PelFFDC convertToPelFFDC(const phosphor::logging::FFDCEntries& ffdc);
270
271 /**
Matt Spinler7e727a32020-07-07 15:00:17 -0500272 * @brief Schedules a PEL repository prune to occur from
273 * the event loop.
274 *
275 * Uses sd_event_add_defer
276 */
277 void scheduleRepoPrune();
278
279 /**
280 * @brief Prunes old PELs out of the repository to save space.
281 *
282 * This is called from the event loop.
283 *
284 * @param[in] source - The event source object used
285 */
286 void pruneRepo(sdeventplus::source::EventBase& source);
287
288 /**
Matt Spinlerff9cec22020-07-15 13:06:35 -0500289 * @brief Sets up an inotify watch to watch for deleted PEL
290 * files. Calls pelFileDeleted() when that occurs.
291 */
292 void setupPELDeleteWatch();
293
294 /**
295 * @brief Called when the inotify watch put on the repository directory
296 * detects a PEL file was deleted.
297 *
298 * Will tell the Repository class about the deleted PEL, and then tell
299 * the log manager class to delete the corresponding OpenBMC event log.
300 */
301 void pelFileDeleted(sdeventplus::source::IO& io, int fd, uint32_t revents);
302
303 /**
Matt Spinler4e8078c2019-07-09 13:22:32 -0500304 * @brief Reference to phosphor-logging's Manager class
305 */
Matt Spinler367144c2019-09-19 15:33:52 -0500306 phosphor::logging::internal::Manager& _logManager;
Matt Spinler89fa0822019-07-17 13:54:30 -0500307
308 /**
Matt Spinlerf682b402019-12-18 13:48:08 -0600309 * @brief Handles creating event logs/PELs from within
310 * the PEL extension code
311 */
312 EventLogger _eventLogger;
313
314 /**
Matt Spinler89fa0822019-07-17 13:54:30 -0500315 * @brief The PEL repository object
316 */
317 Repository _repo;
Matt Spinlerc8705e22019-09-11 12:36:07 -0500318
319 /**
Matt Spinler367144c2019-09-19 15:33:52 -0500320 * @brief The PEL message registry object
321 */
322 message::Registry _registry;
323
324 /**
Matt Spinlerff9cec22020-07-15 13:06:35 -0500325 * @brief The Event object this class uses
326 */
327 sdeventplus::Event _event;
328
329 /**
Matt Spinlerc8705e22019-09-11 12:36:07 -0500330 * @brief The API the PEL sections use to gather data
331 */
332 std::unique_ptr<DataInterfaceBase> _dataIface;
Matt Spinlerf60ac272019-12-11 13:47:50 -0600333
334 /**
335 * @brief The HostNotifier object used for telling the
336 * host about new PELs
337 */
338 std::unique_ptr<HostNotifier> _hostNotifier;
Matt Spinler6b1a5c82020-01-07 08:48:53 -0600339
340 /**
341 * @brief The event source for closing a PEL file descriptor after
342 * it has been returned from the getPEL D-Bus method.
343 */
344 std::unique_ptr<sdeventplus::source::Defer> _fdCloserEventSource;
Matt Spinler7e727a32020-07-07 15:00:17 -0500345
346 /**
347 * @brief The even source for removing old PELs when the repo is
348 * running out of space to make room for new ones.
349 */
350 std::unique_ptr<sdeventplus::source::Defer> _repoPrunerEventSource;
Matt Spinlerff9cec22020-07-15 13:06:35 -0500351
352 /**
353 * @brief The even source for watching for deleted PEL files.
354 */
355 std::unique_ptr<sdeventplus::source::IO> _pelFileDeleteEventSource;
356
357 /**
358 * @brief The file descriptor returned by inotify_init1() used
359 * for watching for deleted PEL files.
360 */
361 int _pelFileDeleteFD = -1;
362
363 /**
364 * @brief The file descriptor returned by inotify_add_watch().
365 */
366 int _pelFileDeleteWatchFD = -1;
Matt Spinler4e8078c2019-07-09 13:22:32 -0500367};
368
369} // namespace pels
370} // namespace openpower