1cb65ffceSJayanth Othayoth #include "config.h"
2cb65ffceSJayanth Othayoth
3cb65ffceSJayanth Othayoth #include "elog_watch.hpp"
4cb65ffceSJayanth Othayoth
5cb65ffceSJayanth Othayoth #include "dump_serialize.hpp"
6aa0937f9SDhruvaraj Subhashchandran #include "dump_types.hpp"
7cb65ffceSJayanth Othayoth #include "xyz/openbmc_project/Dump/Create/error.hpp"
8cb65ffceSJayanth Othayoth
931085974SVishwanatha Subbanna #include <cereal/cereal.hpp>
10d0f0064eSJayanth Othayoth #include <phosphor-logging/elog.hpp>
11d1f670feSDhruvaraj Subhashchandran #include <phosphor-logging/lg2.hpp>
1215cd3ce7SWilliam A. Kennington III #include <sdbusplus/exception.hpp>
131615b824SDhruvaraj Subhashchandran #include <xyz/openbmc_project/Dump/Create/common.hpp>
14d0f0064eSJayanth Othayoth
150af74a5eSJayanth Othayoth #include <fstream>
160af74a5eSJayanth Othayoth
1731085974SVishwanatha Subbanna // Register class version with Cereal
18bb410df7SRamesh Iyyar CEREAL_CLASS_VERSION(phosphor::dump::elog::Watch, CLASS_VERSION)
19d0f0064eSJayanth Othayoth
20d0f0064eSJayanth Othayoth namespace phosphor
21d0f0064eSJayanth Othayoth {
22d0f0064eSJayanth Othayoth namespace dump
23d0f0064eSJayanth Othayoth {
24d0f0064eSJayanth Othayoth namespace elog
25d0f0064eSJayanth Othayoth {
26d0f0064eSJayanth Othayoth
27d0f0064eSJayanth Othayoth using Message = std::string;
28984a98f7SPatrick Williams using Attributes = std::variant<Message>;
29d0f0064eSJayanth Othayoth using AttributeName = std::string;
30d0f0064eSJayanth Othayoth using AttributeMap = std::map<AttributeName, Attributes>;
31d0f0064eSJayanth Othayoth using PropertyName = std::string;
32d0f0064eSJayanth Othayoth using PropertyMap = std::map<PropertyName, AttributeMap>;
33d0f0064eSJayanth Othayoth
Watch(sdbusplus::bus_t & bus,Mgr & mgr)34e4350f93SDhruvaraj Subhashchandran Watch::Watch(sdbusplus::bus_t& bus, Mgr& mgr) :
35e4350f93SDhruvaraj Subhashchandran mgr(mgr),
36cb65ffceSJayanth Othayoth addMatch(bus,
372496482aSJayanth Othayoth sdbusplus::bus::match::rules::interfacesAdded() +
38cb65ffceSJayanth Othayoth sdbusplus::bus::match::rules::path_namespace(OBJ_LOGGING),
39cb65ffceSJayanth Othayoth std::bind(std::mem_fn(&Watch::addCallback), this,
40cb65ffceSJayanth Othayoth std::placeholders::_1)),
41cb65ffceSJayanth Othayoth delMatch(bus,
422496482aSJayanth Othayoth sdbusplus::bus::match::rules::interfacesRemoved() +
43cb65ffceSJayanth Othayoth sdbusplus::bus::match::rules::path_namespace(OBJ_LOGGING),
44cb65ffceSJayanth Othayoth std::bind(std::mem_fn(&Watch::delCallback), this,
45cb65ffceSJayanth Othayoth std::placeholders::_1))
462496482aSJayanth Othayoth {
473fc6df48SJayanth Othayoth std::filesystem::path file(ELOG_ID_PERSIST_PATH);
483fc6df48SJayanth Othayoth if (std::filesystem::exists(file))
492496482aSJayanth Othayoth {
502496482aSJayanth Othayoth if (!deserialize(ELOG_ID_PERSIST_PATH, elogList))
512496482aSJayanth Othayoth {
52d1f670feSDhruvaraj Subhashchandran lg2::error("Error occurred during error id deserialize");
532496482aSJayanth Othayoth }
542496482aSJayanth Othayoth }
552496482aSJayanth Othayoth }
562496482aSJayanth Othayoth
addCallback(sdbusplus::message_t & msg)579b18bf2dSPatrick Williams void Watch::addCallback(sdbusplus::message_t& msg)
58d0f0064eSJayanth Othayoth {
59d0f0064eSJayanth Othayoth using QuotaExceeded =
60d0f0064eSJayanth Othayoth sdbusplus::xyz::openbmc_project::Dump::Create::Error::QuotaExceeded;
61d0f0064eSJayanth Othayoth
6290d147a1SWilliam A. Kennington III sdbusplus::message::object_path objectPath;
6390d147a1SWilliam A. Kennington III PropertyMap propertyMap;
6415cd3ce7SWilliam A. Kennington III try
6515cd3ce7SWilliam A. Kennington III {
6690d147a1SWilliam A. Kennington III msg.read(objectPath, propertyMap);
6715cd3ce7SWilliam A. Kennington III }
689b18bf2dSPatrick Williams catch (const sdbusplus::exception_t& e)
6915cd3ce7SWilliam A. Kennington III {
70d1f670feSDhruvaraj Subhashchandran lg2::error("Failed to parse elog add signal, errormsg: {ERROR}, "
71d1f670feSDhruvaraj Subhashchandran "REPLY_SIG: {REPLY_SIG}",
72d1f670feSDhruvaraj Subhashchandran "ERROR", e, "REPLY_SIG", msg.get_signature());
7315cd3ce7SWilliam A. Kennington III return;
7415cd3ce7SWilliam A. Kennington III }
75d0f0064eSJayanth Othayoth
7690d147a1SWilliam A. Kennington III std::size_t found = objectPath.str.find("entry");
77d0f0064eSJayanth Othayoth if (found == std::string::npos)
78d0f0064eSJayanth Othayoth {
79d0f0064eSJayanth Othayoth // Not a new error entry skip
80d0f0064eSJayanth Othayoth return;
81d0f0064eSJayanth Othayoth }
82d0f0064eSJayanth Othayoth
832496482aSJayanth Othayoth auto eId = getEid(objectPath);
842496482aSJayanth Othayoth
852496482aSJayanth Othayoth auto search = elogList.find(eId);
862496482aSJayanth Othayoth if (search != elogList.end())
872496482aSJayanth Othayoth {
882496482aSJayanth Othayoth // elog exists in the list, Skip the dump
892496482aSJayanth Othayoth return;
902496482aSJayanth Othayoth }
912496482aSJayanth Othayoth
9290d147a1SWilliam A. Kennington III auto iter = propertyMap.find("xyz.openbmc_project.Logging.Entry");
9390d147a1SWilliam A. Kennington III if (iter == propertyMap.end())
94d0f0064eSJayanth Othayoth {
95d0f0064eSJayanth Othayoth return;
96d0f0064eSJayanth Othayoth }
97d0f0064eSJayanth Othayoth
98d0f0064eSJayanth Othayoth auto attr = iter->second.find("Message");
99d0f0064eSJayanth Othayoth if (attr == iter->second.end())
100d0f0064eSJayanth Othayoth {
101d0f0064eSJayanth Othayoth return;
102d0f0064eSJayanth Othayoth }
103d0f0064eSJayanth Othayoth
10407f0f465SPatrick Williams auto& data = std::get<PropertyName>(attr->second);
105d0f0064eSJayanth Othayoth if (data.empty())
106d0f0064eSJayanth Othayoth {
107d0f0064eSJayanth Othayoth // No Message skip
108d0f0064eSJayanth Othayoth return;
109d0f0064eSJayanth Othayoth }
110d0f0064eSJayanth Othayoth
111aa0937f9SDhruvaraj Subhashchandran auto etype = findErrorType(data);
112aa0937f9SDhruvaraj Subhashchandran if (!etype.has_value())
113d0f0064eSJayanth Othayoth {
1140deb287cSMarri Devender Rao // error not supported in the configuration
115d0f0064eSJayanth Othayoth return;
116d0f0064eSJayanth Othayoth }
117d0f0064eSJayanth Othayoth
118aa0937f9SDhruvaraj Subhashchandran auto errorType = etype.value();
119aa0937f9SDhruvaraj Subhashchandran
120e4350f93SDhruvaraj Subhashchandran DumpCreateParams params;
121e4350f93SDhruvaraj Subhashchandran using DumpIntr = sdbusplus::common::xyz::openbmc_project::dump::Create;
122e4350f93SDhruvaraj Subhashchandran using CreateParameters =
123e4350f93SDhruvaraj Subhashchandran sdbusplus::common::xyz::openbmc_project::dump::Create::CreateParameters;
124e4350f93SDhruvaraj Subhashchandran using DumpType =
125e4350f93SDhruvaraj Subhashchandran sdbusplus::common::xyz::openbmc_project::dump::Create::DumpType;
126e4350f93SDhruvaraj Subhashchandran params[DumpIntr::convertCreateParametersToString(
127e4350f93SDhruvaraj Subhashchandran CreateParameters::FilePath)] = objectPath;
128e4350f93SDhruvaraj Subhashchandran params[DumpIntr::convertCreateParametersToString(
129e4350f93SDhruvaraj Subhashchandran CreateParameters::DumpType)] =
130e4350f93SDhruvaraj Subhashchandran DumpIntr::convertDumpTypeToString(DumpType::ErrorLog);
131e4350f93SDhruvaraj Subhashchandran params[DumpIntr::convertCreateParametersToString(
132e4350f93SDhruvaraj Subhashchandran CreateParameters::ErrorType)] = errorType;
133d0f0064eSJayanth Othayoth try
134d0f0064eSJayanth Othayoth {
1352496482aSJayanth Othayoth // Save the elog information. This is to avoid dump requests
1362496482aSJayanth Othayoth // in elog restore path.
1372496482aSJayanth Othayoth elogList.insert(eId);
1382496482aSJayanth Othayoth
1392496482aSJayanth Othayoth phosphor::dump::elog::serialize(elogList);
140e4350f93SDhruvaraj Subhashchandran mgr.Mgr::createDump(params);
141d0f0064eSJayanth Othayoth }
1429d2d7226SPatrick Williams catch (const QuotaExceeded& e)
143d0f0064eSJayanth Othayoth {
144*316a2277SJayanth Othayoth // No action needed
145*316a2277SJayanth Othayoth lg2::warning("Skipping exception: QuotaExceeded during createDump");
146d0f0064eSJayanth Othayoth }
147d0f0064eSJayanth Othayoth return;
148d0f0064eSJayanth Othayoth }
149d0f0064eSJayanth Othayoth
delCallback(sdbusplus::message_t & msg)1509b18bf2dSPatrick Williams void Watch::delCallback(sdbusplus::message_t& msg)
1512496482aSJayanth Othayoth {
15290d147a1SWilliam A. Kennington III sdbusplus::message::object_path objectPath;
15315cd3ce7SWilliam A. Kennington III try
15415cd3ce7SWilliam A. Kennington III {
15590d147a1SWilliam A. Kennington III msg.read(objectPath);
15615cd3ce7SWilliam A. Kennington III }
1579b18bf2dSPatrick Williams catch (const sdbusplus::exception_t& e)
15815cd3ce7SWilliam A. Kennington III {
159d1f670feSDhruvaraj Subhashchandran lg2::error("Failed to parse elog del signal, errormsg: {ERROR}, "
160d1f670feSDhruvaraj Subhashchandran "REPLY_SIG: {REPLY_SIG}",
161d1f670feSDhruvaraj Subhashchandran "ERROR", e, "REPLY_SIG", msg.get_signature());
16215cd3ce7SWilliam A. Kennington III return;
16315cd3ce7SWilliam A. Kennington III }
1642496482aSJayanth Othayoth
165638b43f5SAndrew Geissler std::size_t found = objectPath.str.find("entry");
166638b43f5SAndrew Geissler if (found == std::string::npos)
167638b43f5SAndrew Geissler {
168638b43f5SAndrew Geissler // Not a error entry so skip
169638b43f5SAndrew Geissler return;
170638b43f5SAndrew Geissler }
171638b43f5SAndrew Geissler
1722496482aSJayanth Othayoth // Get elog id
1732496482aSJayanth Othayoth auto eId = getEid(objectPath);
1742496482aSJayanth Othayoth
1752496482aSJayanth Othayoth // Delete the elog entry from the list and serialize
1762496482aSJayanth Othayoth auto search = elogList.find(eId);
1772496482aSJayanth Othayoth if (search != elogList.end())
1782496482aSJayanth Othayoth {
1792496482aSJayanth Othayoth elogList.erase(search);
1802496482aSJayanth Othayoth phosphor::dump::elog::serialize(elogList);
1812496482aSJayanth Othayoth }
1822496482aSJayanth Othayoth }
1832496482aSJayanth Othayoth
184d0f0064eSJayanth Othayoth } // namespace elog
185d0f0064eSJayanth Othayoth } // namespace dump
186d0f0064eSJayanth Othayoth } // namespace phosphor
187