blob: 86030d4bb053a67fe2f1444e01158374a643101e [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 Spinler367144c2019-09-19 15:33:52 -050010#include "registry.hpp"
Matt Spinler89fa0822019-07-17 13:54:30 -050011#include "repository.hpp"
Matt Spinler4e8078c2019-07-09 13:22:32 -050012
Matt Spinlera34ab722019-12-16 10:39:32 -060013#include <org/open_power/Logging/PEL/server.hpp>
14#include <sdbusplus/server.hpp>
Matt Spinler6b1a5c82020-01-07 08:48:53 -060015#include <sdeventplus/event.hpp>
16#include <sdeventplus/source/event.hpp>
Matt Spinlera34ab722019-12-16 10:39:32 -060017
Matt Spinler4e8078c2019-07-09 13:22:32 -050018namespace openpower
19{
20namespace pels
21{
22
Matt Spinlera34ab722019-12-16 10:39:32 -060023using PELInterface = sdbusplus::server::object::object<
24 sdbusplus::org::open_power::Logging::server::PEL>;
25
Matt Spinler4e8078c2019-07-09 13:22:32 -050026/**
27 * @brief PEL manager object
28 */
Matt Spinlera34ab722019-12-16 10:39:32 -060029class Manager : public PELInterface
Matt Spinler4e8078c2019-07-09 13:22:32 -050030{
31 public:
32 Manager() = delete;
33 ~Manager() = default;
34 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 Spinlerf682b402019-12-18 13:48:08 -060051 _logManager(logManager),
52 _eventLogger(logManager.getBus().get_event(), std::move(creatorFunc)),
53 _repo(getPELRepoPath()),
Matt Spinler367144c2019-09-19 15:33:52 -050054 _registry(getMessageRegistryPath() / message::registryFileName),
55 _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
89 */
90 void create(const std::string& message, uint32_t obmcLogID,
Matt Spinler367144c2019-09-19 15:33:52 -050091 uint64_t timestamp, phosphor::logging::Entry::Level severity,
Matt Spinler4e8078c2019-07-09 13:22:32 -050092 const std::vector<std::string>& additionalData,
93 const std::vector<std::string>& associations);
94
95 /**
96 * @brief Erase a PEL based on its OpenBMC event log ID
97 *
98 * @param[in] obmcLogID - the corresponding OpenBMC event log id
99 */
100 void erase(uint32_t obmcLogID);
101
102 /** @brief Says if an OpenBMC event log may not be manually deleted at this
103 * time because its corresponding PEL cannot be.
104 *
105 * There are PEL retention policies that can prohibit the manual deletion
106 * of PELs (and therefore OpenBMC event logs).
107 *
108 * @param[in] obmcLogID - the OpenBMC event log ID
109 * @return bool - true if prohibited
110 */
111 bool isDeleteProhibited(uint32_t obmcLogID);
112
Matt Spinlera34ab722019-12-16 10:39:32 -0600113 /**
114 * @brief Return a file descriptor to the raw PEL data
115 *
116 * Throws InvalidArgument if the PEL ID isn't found,
117 * and InternalFailure if anything else fails.
118 *
119 * @param[in] pelID - The PEL ID to get the data for
120 *
121 * @return unix_fd - File descriptor to the file that contains the PEL
122 */
123 sdbusplus::message::unix_fd getPEL(uint32_t pelID) override;
124
125 /**
126 * @brief Returns data for the PEL corresponding to an OpenBMC
127 * event log.
128 *
129 * @param[in] obmcLogID - The OpenBMC event log ID
130 *
131 * @return vector<uint8_t> - The raw PEL data
132 */
133 std::vector<uint8_t> getPELFromOBMCID(uint32_t obmcLogID) override;
134
135 /**
136 * @brief The D-Bus method called when a host successfully processes
137 * a PEL.
138 *
139 * This D-Bus method is called from the PLDM daemon when they get an
140 * 'Ack PEL' PLDM message from the host, which indicates the host
141 * firmware successfully sent it to the OS and this code doesn't need
142 * to send it to the host again.
143 *
144 * @param[in] pelID - The PEL ID
145 */
146 void hostAck(uint32_t pelID) override;
147
148 /**
149 * @brief D-Bus method called when the host rejects a PEL.
150 *
151 * This D-Bus method is called from the PLDM daemon when they get an
152 * 'Ack PEL' PLDM message from the host with a payload that says
153 * something when wrong.
154 *
155 * The choices are either:
156 * * Host Full - The host's staging area is full - try again later
157 * * Malrformed PEL - The host received an invalid PEL
158 *
159 * @param[in] pelID - The PEL ID
160 * @param[in] reason - One of the above two reasons
161 */
162 void hostReject(uint32_t pelID, RejectionReason reason) override;
163
Matt Spinler19e72902020-01-24 11:05:20 -0600164 /**
165 * @brief Converts the ESEL field in an OpenBMC event log to a
166 * vector of uint8_ts that just contains the PEL data.
167 *
168 * That data string looks like: "50 48 00 ab ..."
169 *
170 * Throws an exception on any failures.
171 *
172 * @param[in] esel - The ESEL string
173 *
174 * @return std::vector<uint8_t> - The contained PEL data
175 */
176 static std::vector<uint8_t> eselToRawData(const std::string& esel);
177
Matt Spinler4e8078c2019-07-09 13:22:32 -0500178 private:
179 /**
180 * @brief Adds a received raw PEL to the PEL repository
181 *
182 * @param[in] rawPelPath - The path to the file that contains the
183 * raw PEL.
184 * @param[in] obmcLogID - the corresponding OpenBMC event log id
185 */
186 void addRawPEL(const std::string& rawPelPath, uint32_t obmcLogID);
187
188 /**
189 * @brief Creates a PEL based on the OpenBMC event log contents.
190 *
191 * @param[in] message - The event log message property
192 * @param[in] obmcLogID - the corresponding OpenBMC event log id
193 * @param[in] timestamp - The timestamp property
194 * @param[in] severity - The event log severity
195 * @param[in] additionalData - The AdditionalData property
196 * @param[in] associations - The associations property
197 */
198 void createPEL(const std::string& message, uint32_t obmcLogID,
Matt Spinler367144c2019-09-19 15:33:52 -0500199 uint64_t timestamp, phosphor::logging::Entry::Level severity,
Matt Spinler4e8078c2019-07-09 13:22:32 -0500200 const std::vector<std::string>& additionalData,
201 const std::vector<std::string>& associations);
202
203 /**
Matt Spinler6b1a5c82020-01-07 08:48:53 -0600204 * @brief Schedules a close of the file descriptor to occur from
205 * the event loop.
206 *
207 * Uses sd_event_add_defer
208 *
209 * @param[in] fd - The file descriptor to close
210 */
211 void scheduleFDClose(int fd);
212
213 /**
214 * @brief Closes the file descriptor passed in.
215 *
216 * This is called from the event loop to close FDs returned
217 * from getPEL().
218 *
219 * @param[in] fd - The file descriptor to close
220 * @param[in] source - The event source object used
221 */
222 void closeFD(int fd, sdeventplus::source::EventBase& source);
223
224 /**
Matt Spinler19e72902020-01-24 11:05:20 -0600225 * @brief Adds a PEL to the repository given its data
226 *
227 * @param[in] pelData - The PEL to add as a vector of uint8_ts
228 * @param[in] obmcLogID - the OpenBMC event log ID
229 */
230 void addPEL(std::vector<uint8_t>& pelData, uint32_t obmcLogID);
231
232 /**
233 * @brief Adds the PEL stored in the ESEL field of the AdditionalData
234 * property of an OpenBMC event log to the repository.
235 *
236 * @param[in] esel - The ESEL AdditionalData contents
237 * @param[in] obmcLogID - The OpenBMC event log ID
238 */
239 void addESELPEL(const std::string& esel, uint32_t obmcLogID);
240
241 /**
Matt Spinler4e8078c2019-07-09 13:22:32 -0500242 * @brief Reference to phosphor-logging's Manager class
243 */
Matt Spinler367144c2019-09-19 15:33:52 -0500244 phosphor::logging::internal::Manager& _logManager;
Matt Spinler89fa0822019-07-17 13:54:30 -0500245
246 /**
Matt Spinlerf682b402019-12-18 13:48:08 -0600247 * @brief Handles creating event logs/PELs from within
248 * the PEL extension code
249 */
250 EventLogger _eventLogger;
251
252 /**
Matt Spinler89fa0822019-07-17 13:54:30 -0500253 * @brief The PEL repository object
254 */
255 Repository _repo;
Matt Spinlerc8705e22019-09-11 12:36:07 -0500256
257 /**
Matt Spinler367144c2019-09-19 15:33:52 -0500258 * @brief The PEL message registry object
259 */
260 message::Registry _registry;
261
262 /**
Matt Spinlerc8705e22019-09-11 12:36:07 -0500263 * @brief The API the PEL sections use to gather data
264 */
265 std::unique_ptr<DataInterfaceBase> _dataIface;
Matt Spinlerf60ac272019-12-11 13:47:50 -0600266
267 /**
268 * @brief The HostNotifier object used for telling the
269 * host about new PELs
270 */
271 std::unique_ptr<HostNotifier> _hostNotifier;
Matt Spinler6b1a5c82020-01-07 08:48:53 -0600272
273 /**
274 * @brief The event source for closing a PEL file descriptor after
275 * it has been returned from the getPEL D-Bus method.
276 */
277 std::unique_ptr<sdeventplus::source::Defer> _fdCloserEventSource;
Matt Spinler4e8078c2019-07-09 13:22:32 -0500278};
279
280} // namespace pels
281} // namespace openpower