blob: 4863ad5ff69de7b89617588d02f9e27f4a4b8d9f [file] [log] [blame]
Adriana Kobylak8f7941e2016-11-14 14:46:23 -06001#pragma once
2
Andrew Geissler6a0ef6f2020-04-06 15:06:31 -05003#include "elog_block.hpp"
Adriana Kobylakdf995fa2017-01-08 15:14:02 -06004#include "elog_entry.hpp"
Nagaraju Goruganti05aae8b2017-08-30 07:56:12 -05005#include "xyz/openbmc_project/Collection/DeleteAll/server.hpp"
Matt Spinler3fb83b32019-07-26 11:22:44 -05006#include "xyz/openbmc_project/Logging/Create/server.hpp"
7#include "xyz/openbmc_project/Logging/Entry/server.hpp"
Patrick Venturef18bf832018-10-26 18:14:00 -07008#include "xyz/openbmc_project/Logging/Internal/Manager/server.hpp"
9
10#include <list>
11#include <phosphor-logging/log.hpp>
12#include <sdbusplus/bus.hpp>
Adriana Kobylak8f7941e2016-11-14 14:46:23 -060013
14namespace phosphor
15{
16namespace logging
17{
Adriana Kobylakd722b3a2017-02-28 12:10:44 -060018
Patrick Venturef18bf832018-10-26 18:14:00 -070019extern const std::map<std::string, std::vector<std::string>> g_errMetaMap;
20extern const std::map<std::string, level> g_errLevelMap;
Adriana Kobylakd722b3a2017-02-28 12:10:44 -060021
Matt Spinler3fb83b32019-07-26 11:22:44 -050022using CreateIface = sdbusplus::xyz::openbmc_project::Logging::server::Create;
23using DeleteAllIface =
24 sdbusplus::xyz::openbmc_project::Collection::server::DeleteAll;
Nagaraju Goruganti05aae8b2017-08-30 07:56:12 -050025
Adriana Kobylak8f7941e2016-11-14 14:46:23 -060026namespace details
27{
Matt Spinler3fb83b32019-07-26 11:22:44 -050028template <typename... T>
29using ServerObject = typename sdbusplus::server::object::object<T...>;
Adriana Kobylak8f7941e2016-11-14 14:46:23 -060030
31using ManagerIface =
32 sdbusplus::xyz::openbmc_project::Logging::Internal::server::Manager;
33
34} // namespace details
35
Matt Spinlerc64b7122020-03-26 10:55:01 -050036constexpr size_t ffdcFormatPos = 0;
37constexpr size_t ffdcSubtypePos = 1;
38constexpr size_t ffdcVersionPos = 2;
39constexpr size_t ffdcFDPos = 3;
40
41using FFDCEntry = std::tuple<CreateIface::FFDCFormat, uint8_t, uint8_t,
42 sdbusplus::message::unix_fd>;
43
44using FFDCEntries = std::vector<FFDCEntry>;
45
Nagaraju Goruganti05aae8b2017-08-30 07:56:12 -050046namespace internal
47{
48
Adriana Kobylak8f7941e2016-11-14 14:46:23 -060049/** @class Manager
50 * @brief OpenBMC logging manager implementation.
51 * @details A concrete implementation for the
52 * xyz.openbmc_project.Logging.Internal.Manager DBus API.
53 */
Adriana Kobylakf477fe22017-01-06 11:56:41 -060054class Manager : public details::ServerObject<details::ManagerIface>
Adriana Kobylak8f7941e2016-11-14 14:46:23 -060055{
Patrick Venturef18bf832018-10-26 18:14:00 -070056 public:
57 Manager() = delete;
58 Manager(const Manager&) = delete;
59 Manager& operator=(const Manager&) = delete;
60 Manager(Manager&&) = delete;
61 Manager& operator=(Manager&&) = delete;
62 virtual ~Manager() = default;
Adriana Kobylak8f7941e2016-11-14 14:46:23 -060063
Patrick Venturef18bf832018-10-26 18:14:00 -070064 /** @brief Constructor to put object onto bus at a dbus path.
65 * @param[in] bus - Bus to attach to.
66 * @param[in] path - Path to attach at.
67 */
68 Manager(sdbusplus::bus::bus& bus, const char* objPath) :
69 details::ServerObject<details::ManagerIface>(bus, objPath), busLog(bus),
70 entryId(0), fwVersion(readFWVersion()){};
Adriana Kobylak8f7941e2016-11-14 14:46:23 -060071
Patrick Venturef18bf832018-10-26 18:14:00 -070072 /*
73 * @fn commit()
74 * @brief sd_bus Commit method implementation callback.
75 * @details Create an error/event log based on transaction id and
76 * error message.
77 * @param[in] transactionId - Unique identifier of the journal entries
78 * to be committed.
79 * @param[in] errMsg - The error exception message associated with the
80 * error log to be committed.
81 */
Lei YUb50c7052021-01-21 16:02:26 +080082 uint32_t commit(uint64_t transactionId, std::string errMsg) override;
Adriana Kobylakdf995fa2017-01-08 15:14:02 -060083
Patrick Venturef18bf832018-10-26 18:14:00 -070084 /*
85 * @fn commit()
86 * @brief sd_bus CommitWithLvl method implementation callback.
87 * @details Create an error/event log based on transaction id and
88 * error message.
89 * @param[in] transactionId - Unique identifier of the journal entries
90 * to be committed.
91 * @param[in] errMsg - The error exception message associated with the
92 * error log to be committed.
93 * @param[in] errLvl - level of the error
94 */
Lei YUb50c7052021-01-21 16:02:26 +080095 uint32_t commitWithLvl(uint64_t transactionId, std::string errMsg,
96 uint32_t errLvl) override;
Adriana Kobylakdf995fa2017-01-08 15:14:02 -060097
Patrick Venturef18bf832018-10-26 18:14:00 -070098 /** @brief Erase specified entry d-bus object
99 *
100 * @param[in] entryId - unique identifier of the entry
101 */
102 void erase(uint32_t entryId);
Deepak Kodihalli99a85492017-03-31 06:01:57 -0500103
Patrick Venturef18bf832018-10-26 18:14:00 -0700104 /** @brief Construct error d-bus objects from their persisted
105 * representations.
106 */
107 void restore();
Deepak Kodihalli72654f12017-06-12 04:33:29 -0500108
Patrick Venturef18bf832018-10-26 18:14:00 -0700109 /** @brief Erase all error log entries
110 *
111 */
112 void eraseAll()
113 {
114 auto iter = entries.begin();
115 while (iter != entries.end())
Nagaraju Goruganti05aae8b2017-08-30 07:56:12 -0500116 {
Patrick Venture34438962018-10-30 13:17:37 -0700117 auto e = iter->first;
Patrick Venturef18bf832018-10-26 18:14:00 -0700118 ++iter;
Patrick Venture34438962018-10-30 13:17:37 -0700119 erase(e);
Nagaraju Goruganti05aae8b2017-08-30 07:56:12 -0500120 }
Lotus Xud091a572021-05-24 13:59:21 +0800121 entryId = 0;
Patrick Venturef18bf832018-10-26 18:14:00 -0700122 }
Nagaraju Goruganti05aae8b2017-08-30 07:56:12 -0500123
Patrick Venturef18bf832018-10-26 18:14:00 -0700124 /** @brief Returns the count of high severity errors
125 *
126 * @return int - count of real errors
127 */
128 int getRealErrSize();
Nagaraju Goruganti477b7312018-06-25 23:28:58 -0500129
Patrick Venturef18bf832018-10-26 18:14:00 -0700130 /** @brief Returns the count of Info errors
131 *
132 * @return int - count of info errors
133 */
134 int getInfoErrSize();
Nagaraju Goruganti477b7312018-06-25 23:28:58 -0500135
Andrew Geissler6a0ef6f2020-04-06 15:06:31 -0500136 /** @brief Returns the number of blocking errors
137 *
138 * @return int - count of blocking errors
139 */
140 int getBlockingErrSize()
141 {
142 return blockingErrors.size();
143 }
144
Andrew Geissler7f6d4bc2020-04-16 14:47:34 -0500145 /** @brief Returns the number of property change callback objects
146 *
147 * @return int - count of property callback entries
148 */
149 int getEntryCallbackSize()
150 {
151 return propChangedEntryCallback.size();
152 }
153
Matt Spinler44893cc2020-08-26 11:34:17 -0500154 /**
155 * @brief Returns the sdbusplus bus object
156 *
157 * @return sdbusplus::bus::bus&
158 */
Matt Spinler8ebfd312019-06-03 12:43:59 -0500159 sdbusplus::bus::bus& getBus()
160 {
161 return busLog;
162 }
163
Matt Spinler44893cc2020-08-26 11:34:17 -0500164 /**
165 * @brief Returns the ID of the last created entry
166 *
167 * @return uint32_t - The ID
168 */
169 uint32_t lastEntryID() const
170 {
171 return entryId;
172 }
173
Matt Spinler3fb83b32019-07-26 11:22:44 -0500174 /** @brief Creates an event log
175 *
176 * This is an alternative to the _commit() API. It doesn't use
177 * the journal to look up event log metadata like _commit does.
178 *
179 * @param[in] errMsg - The error exception message associated with the
180 * error log to be committed.
181 * @param[in] severity - level of the error
182 * @param[in] additionalData - The AdditionalData property for the error
183 */
184 void create(
185 const std::string& message,
186 sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level severity,
187 const std::map<std::string, std::string>& additionalData);
188
Matt Spinlerc64b7122020-03-26 10:55:01 -0500189 /** @brief Creates an event log, and accepts FFDC files
190 *
191 * This is the same as create(), but also takes an FFDC argument.
192 *
193 * The FFDC argument is a vector of tuples that allows one to pass in file
194 * descriptors for files that contain FFDC (First Failure Data Capture).
195 * These will be passed to any event logging extensions.
196 *
197 * @param[in] errMsg - The error exception message associated with the
198 * error log to be committed.
199 * @param[in] severity - level of the error
200 * @param[in] additionalData - The AdditionalData property for the error
201 * @param[in] ffdc - A vector of FFDC file info
202 */
203 void createWithFFDC(
204 const std::string& message,
205 sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level severity,
206 const std::map<std::string, std::string>& additionalData,
207 const FFDCEntries& ffdc);
208
Andrew Geisslerc0c500e2020-03-26 11:08:56 -0500209 /** @brief Common wrapper for creating an Entry object
210 *
211 * @return true if quiesce on error setting is enabled, false otherwise
212 */
213 bool isQuiesceOnErrorEnabled();
214
Andrew Geissler32874542020-07-09 09:17:03 -0500215 /** @brief Create boot block association and quiesce host if running
Andrew Geisslerc0c500e2020-03-26 11:08:56 -0500216 *
Andrew Geissler32874542020-07-09 09:17:03 -0500217 * @param[in] entryId - The ID of the phosphor logging error
Andrew Geisslerc0c500e2020-03-26 11:08:56 -0500218 */
Andrew Geissler32874542020-07-09 09:17:03 -0500219 void quiesceOnError(const uint32_t entryId);
Andrew Geisslerc0c500e2020-03-26 11:08:56 -0500220
Andrew Geisslere4960ee2020-03-30 14:31:52 -0500221 /** @brief Check if inventory callout present in input entry
222 *
223 * @param[in] entry - The error to check for callouts
224 *
225 * @return true if inventory item in associations, false otherwise
226 */
227 bool isCalloutPresent(const Entry& entry);
228
Andrew Geisslerced6e2a2020-04-07 16:15:29 -0500229 /** @brief Check (and remove) entry being erased from blocking errors
230 *
231 * @param[in] entryId - The entry that is being erased
232 */
233 void checkAndRemoveBlockingError(uint32_t entryId);
234
Adriana Kobylake7d271a2020-12-07 14:32:44 -0600235 /** @brief Persistent map of Entry dbus objects and their ID */
236 std::map<uint32_t, std::unique_ptr<Entry>> entries;
237
Patrick Venturef18bf832018-10-26 18:14:00 -0700238 private:
239 /*
240 * @fn _commit()
241 * @brief commit() helper
242 * @param[in] transactionId - Unique identifier of the journal entries
243 * to be committed.
244 * @param[in] errMsg - The error exception message associated with the
245 * error log to be committed.
246 * @param[in] errLvl - level of the error
247 */
248 void _commit(uint64_t transactionId, std::string&& errMsg,
249 Entry::Level errLvl);
Deepak Kodihalli6fd9dc42018-04-03 02:08:42 -0500250
Patrick Venturef18bf832018-10-26 18:14:00 -0700251 /** @brief Call metadata handler(s), if any. Handlers may create
252 * associations.
253 * @param[in] errorName - name of the error
254 * @param[in] additionalData - list of metadata (in key=value format)
255 * @param[out] objects - list of error's association objects
256 */
257 void processMetadata(const std::string& errorName,
258 const std::vector<std::string>& additionalData,
259 AssociationList& objects) const;
Deepak Kodihallia87c1572017-02-28 07:40:34 -0600260
Patrick Venturef18bf832018-10-26 18:14:00 -0700261 /** @brief Synchronize unwritten journal messages to disk.
262 * @details This is the same implementation as the systemd command
263 * "journalctl --sync".
264 */
265 void journalSync();
Adriana Kobylak5f4247f2018-03-15 10:27:05 -0500266
Patrick Venturef18bf832018-10-26 18:14:00 -0700267 /** @brief Reads the BMC code level
268 *
269 * @return std::string - the version string
270 */
271 static std::string readFWVersion();
Matt Spinler1275bd12018-05-01 15:13:53 -0500272
Matt Spinler99c2b402019-05-23 14:29:16 -0500273 /** @brief Call any create() functions provided by any extensions.
274 * This is called right after an event log is created to allow
275 * extensions to create their own log based on this one.
276 *
277 * @param[in] entry - the new event log entry
Matt Spinlerc64b7122020-03-26 10:55:01 -0500278 * @param[in] ffdc - A vector of FFDC file info
Matt Spinler99c2b402019-05-23 14:29:16 -0500279 */
Matt Spinlerc64b7122020-03-26 10:55:01 -0500280 void doExtensionLogCreate(const Entry& entry, const FFDCEntries& ffdc);
Matt Spinler99c2b402019-05-23 14:29:16 -0500281
Matt Spinlerb60e7552019-07-24 15:28:08 -0500282 /** @brief Common wrapper for creating an Entry object
283 *
284 * @param[in] errMsg - The error exception message associated with the
285 * error log to be committed.
286 * @param[in] errLvl - level of the error
287 * @param[in] additionalData - The AdditionalData property for the error
Matt Spinlerc64b7122020-03-26 10:55:01 -0500288 * @param[in] ffdc - A vector of FFDC file info. Defaults to an empty
289 * vector.
Matt Spinlerb60e7552019-07-24 15:28:08 -0500290 */
291 void createEntry(std::string errMsg, Entry::Level errLvl,
Matt Spinlerc64b7122020-03-26 10:55:01 -0500292 std::vector<std::string> additionalData,
293 const FFDCEntries& ffdc = FFDCEntries{});
Matt Spinlerb60e7552019-07-24 15:28:08 -0500294
Andrew Geissler7f6d4bc2020-04-16 14:47:34 -0500295 /** @brief Notified on entry property changes
296 *
297 * If an entry is blocking, this callback will be registered to monitor for
298 * the entry having it's Resolved field set to true. If it is then remove
299 * the blocking object.
300 *
301 * @param[in] msg - sdbusplus dbusmessage
302 */
303 void onEntryResolve(sdbusplus::message::message& msg);
304
305 /** @brief Remove block objects for any resolved entries */
306 void findAndRemoveResolvedBlocks();
307
Andrew Geisslerf6126a72020-05-08 10:41:09 -0500308 /** @brief Quiesce host if it is running
309 *
310 * This is called when the user has requested the system be quiesced
311 * if a log with a callout is created
312 */
313 void checkAndQuiesceHost();
314
Patrick Venturef18bf832018-10-26 18:14:00 -0700315 /** @brief Persistent sdbusplus DBus bus connection. */
316 sdbusplus::bus::bus& busLog;
Adriana Kobylakdf995fa2017-01-08 15:14:02 -0600317
Patrick Venturef18bf832018-10-26 18:14:00 -0700318 /** @brief List of error ids for high severity errors */
319 std::list<uint32_t> realErrors;
Nagaraju Gorugantie4b0b772017-11-30 02:12:45 -0600320
Patrick Venturef18bf832018-10-26 18:14:00 -0700321 /** @brief List of error ids for Info(and below) severity */
322 std::list<uint32_t> infoErrors;
Nagaraju Gorugantif8a5a792017-10-13 08:09:52 -0500323
Patrick Venturef18bf832018-10-26 18:14:00 -0700324 /** @brief Id of last error log entry */
325 uint32_t entryId;
Matt Spinler1275bd12018-05-01 15:13:53 -0500326
Patrick Venturef18bf832018-10-26 18:14:00 -0700327 /** @brief The BMC firmware version */
328 const std::string fwVersion;
Andrew Geissler6a0ef6f2020-04-06 15:06:31 -0500329
330 /** @brief Array of blocking errors */
331 std::vector<std::unique_ptr<Block>> blockingErrors;
Andrew Geissler7f6d4bc2020-04-16 14:47:34 -0500332
333 /** @brief Map of entry id to call back object on properties changed */
334 std::map<uint32_t, std::unique_ptr<sdbusplus::bus::match::match>>
335 propChangedEntryCallback;
Adriana Kobylak8f7941e2016-11-14 14:46:23 -0600336};
337
Patrick Venturef18bf832018-10-26 18:14:00 -0700338} // namespace internal
Nagaraju Goruganti05aae8b2017-08-30 07:56:12 -0500339
340/** @class Manager
Matt Spinler3fb83b32019-07-26 11:22:44 -0500341 * @brief Implementation for deleting all error log entries and
342 * creating new logs.
Nagaraju Goruganti05aae8b2017-08-30 07:56:12 -0500343 * @details A concrete implementation for the
Matt Spinler3fb83b32019-07-26 11:22:44 -0500344 * xyz.openbmc_project.Collection.DeleteAll and
345 * xyz.openbmc_project.Logging.Create interfaces.
Nagaraju Goruganti05aae8b2017-08-30 07:56:12 -0500346 */
Matt Spinler3fb83b32019-07-26 11:22:44 -0500347class Manager : public details::ServerObject<DeleteAllIface, CreateIface>
Nagaraju Goruganti05aae8b2017-08-30 07:56:12 -0500348{
Patrick Venturef18bf832018-10-26 18:14:00 -0700349 public:
350 Manager() = delete;
351 Manager(const Manager&) = delete;
352 Manager& operator=(const Manager&) = delete;
353 Manager(Manager&&) = delete;
354 Manager& operator=(Manager&&) = delete;
355 virtual ~Manager() = default;
Nagaraju Goruganti05aae8b2017-08-30 07:56:12 -0500356
Patrick Venturef18bf832018-10-26 18:14:00 -0700357 /** @brief Constructor to put object onto bus at a dbus path.
358 * Defer signal registration (pass true for deferSignal to the
359 * base class) until after the properties are set.
360 * @param[in] bus - Bus to attach to.
361 * @param[in] path - Path to attach at.
362 * @param[in] manager - Reference to internal manager object.
363 */
364 Manager(sdbusplus::bus::bus& bus, const std::string& path,
365 internal::Manager& manager) :
Patrick Williams6ef6b252022-03-30 14:28:27 -0500366 details::ServerObject<DeleteAllIface, CreateIface>(
367 bus, path.c_str(),
368 details::ServerObject<DeleteAllIface,
369 CreateIface>::action::defer_emit),
Patrick Venturef18bf832018-10-26 18:14:00 -0700370 manager(manager){};
Nagaraju Goruganti05aae8b2017-08-30 07:56:12 -0500371
Patrick Venturef18bf832018-10-26 18:14:00 -0700372 /** @brief Delete all d-bus objects.
373 */
Patrick Williamsec4eaea2021-08-28 15:10:15 -0500374 void deleteAll() override
Patrick Venturef18bf832018-10-26 18:14:00 -0700375 {
Matt Spinlerf6f51232022-03-09 10:11:53 -0600376 log<level::INFO>("Deleting all log entries");
Patrick Venturef18bf832018-10-26 18:14:00 -0700377 manager.eraseAll();
378 }
379
Matt Spinler3fb83b32019-07-26 11:22:44 -0500380 /** @brief D-Bus method call implementation to create an event log.
381 *
382 * @param[in] errMsg - The error exception message associated with the
383 * error log to be committed.
384 * @param[in] severity - Level of the error
385 * @param[in] additionalData - The AdditionalData property for the error
386 */
387 void create(
388 std::string message,
389 sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level severity,
390 std::map<std::string, std::string> additionalData) override
391 {
392 manager.create(message, severity, additionalData);
393 }
394
Matt Spinlerc64b7122020-03-26 10:55:01 -0500395 /** @brief D-Bus method call implementation to create an event log with FFDC
396 *
397 * The same as create(), but takes an extra FFDC argument.
398 *
399 * @param[in] errMsg - The error exception message associated with the
400 * error log to be committed.
401 * @param[in] severity - Level of the error
402 * @param[in] additionalData - The AdditionalData property for the error
403 * @param[in] ffdc - A vector of FFDC file info
404 */
Matt Spinlerfcbaf3e2020-03-23 09:22:45 -0500405 void createWithFFDCFiles(
406 std::string message,
407 sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level severity,
408 std::map<std::string, std::string> additionalData,
409 std::vector<std::tuple<CreateIface::FFDCFormat, uint8_t, uint8_t,
410 sdbusplus::message::unix_fd>>
411 ffdc) override
412 {
Matt Spinlerc64b7122020-03-26 10:55:01 -0500413 manager.createWithFFDC(message, severity, additionalData, ffdc);
Matt Spinlerfcbaf3e2020-03-23 09:22:45 -0500414 }
415
Patrick Venturef18bf832018-10-26 18:14:00 -0700416 private:
417 /** @brief This is a reference to manager object */
418 internal::Manager& manager;
Nagaraju Goruganti05aae8b2017-08-30 07:56:12 -0500419};
420
Adriana Kobylak8f7941e2016-11-14 14:46:23 -0600421} // namespace logging
422} // namespace phosphor