blob: 764cd33e7ad2abaf538bdbf423f5f333ddb6275a [file] [log] [blame]
Jayanth Othayothcb65ffc2018-10-16 08:29:32 -05001#include "config.h"
2
3#include "elog_watch.hpp"
4
5#include "dump_internal.hpp"
6#include "dump_serialize.hpp"
Marri Devender Rao0deb2872018-11-12 07:45:54 -06007#include "errors_map.hpp"
Jayanth Othayothcb65ffc2018-10-16 08:29:32 -05008#include "xyz/openbmc_project/Dump/Create/error.hpp"
9
Vishwanatha Subbanna31085972017-10-05 17:06:37 +053010#include <cereal/cereal.hpp>
Jayanth Othayothd0f00642017-09-04 06:26:30 -050011#include <phosphor-logging/elog.hpp>
William A. Kennington III15cd3ce2018-05-15 11:34:44 -070012#include <sdbusplus/exception.hpp>
Jayanth Othayothd0f00642017-09-04 06:26:30 -050013
Jayanth Othayoth0af74a52021-04-08 03:55:21 -050014#include <fstream>
15
Vishwanatha Subbanna31085972017-10-05 17:06:37 +053016// Register class version with Cereal
Ramesh Iyyarbb410df2020-08-03 03:13:04 -050017CEREAL_CLASS_VERSION(phosphor::dump::elog::Watch, CLASS_VERSION)
Jayanth Othayothd0f00642017-09-04 06:26:30 -050018
19namespace phosphor
20{
21namespace dump
22{
23namespace elog
24{
25
26using namespace phosphor::logging;
27constexpr auto LOG_PATH = "/xyz/openbmc_project/logging";
Jayanth Othayothd0f00642017-09-04 06:26:30 -050028using Message = std::string;
Patrick Williams984a98f2020-05-13 17:53:32 -050029using Attributes = std::variant<Message>;
Jayanth Othayothd0f00642017-09-04 06:26:30 -050030using AttributeName = std::string;
31using AttributeMap = std::map<AttributeName, Attributes>;
32using PropertyName = std::string;
33using PropertyMap = std::map<PropertyName, AttributeMap>;
Jayanth Othayothd0f00642017-09-04 06:26:30 -050034
Jayanth Othayothcb65ffc2018-10-16 08:29:32 -050035Watch::Watch(sdbusplus::bus::bus& bus, IMgr& iMgr) :
Jayanth Othayoth24964822017-09-04 22:07:06 -050036 iMgr(iMgr),
Jayanth Othayothcb65ffc2018-10-16 08:29:32 -050037 addMatch(bus,
38 sdbusplus::bus::match::rules::interfacesAdded() +
39 sdbusplus::bus::match::rules::path_namespace(OBJ_LOGGING),
40 std::bind(std::mem_fn(&Watch::addCallback), this,
41 std::placeholders::_1)),
42 delMatch(bus,
43 sdbusplus::bus::match::rules::interfacesRemoved() +
44 sdbusplus::bus::match::rules::path_namespace(OBJ_LOGGING),
45 std::bind(std::mem_fn(&Watch::delCallback), this,
46 std::placeholders::_1))
Jayanth Othayoth24964822017-09-04 22:07:06 -050047{
48
Jayanth Othayoth3fc6df42021-04-08 03:45:24 -050049 std::filesystem::path file(ELOG_ID_PERSIST_PATH);
50 if (std::filesystem::exists(file))
Jayanth Othayoth24964822017-09-04 22:07:06 -050051 {
52 if (!deserialize(ELOG_ID_PERSIST_PATH, elogList))
53 {
54 log<level::ERR>("Error occurred during error id deserialize");
55 }
56 }
57}
58
59void Watch::addCallback(sdbusplus::message::message& msg)
Jayanth Othayothd0f00642017-09-04 06:26:30 -050060{
Jayanth Othayothd0f00642017-09-04 06:26:30 -050061 using QuotaExceeded =
62 sdbusplus::xyz::openbmc_project::Dump::Create::Error::QuotaExceeded;
63
William A. Kennington III90d147a2018-06-12 16:42:33 -070064 sdbusplus::message::object_path objectPath;
65 PropertyMap propertyMap;
William A. Kennington III15cd3ce2018-05-15 11:34:44 -070066 try
67 {
William A. Kennington III90d147a2018-06-12 16:42:33 -070068 msg.read(objectPath, propertyMap);
William A. Kennington III15cd3ce2018-05-15 11:34:44 -070069 }
70 catch (const sdbusplus::exception::SdBusError& e)
71 {
72 log<level::ERR>("Failed to parse elog add signal",
73 entry("ERROR=%s", e.what()),
74 entry("REPLY_SIG=%s", msg.get_signature()));
75 return;
76 }
Jayanth Othayothd0f00642017-09-04 06:26:30 -050077
William A. Kennington III90d147a2018-06-12 16:42:33 -070078 std::size_t found = objectPath.str.find("entry");
Jayanth Othayothd0f00642017-09-04 06:26:30 -050079 if (found == std::string::npos)
80 {
Jayanth Othayothcb65ffc2018-10-16 08:29:32 -050081 // Not a new error entry skip
Jayanth Othayothd0f00642017-09-04 06:26:30 -050082 return;
83 }
84
Jayanth Othayoth24964822017-09-04 22:07:06 -050085 auto eId = getEid(objectPath);
86
87 auto search = elogList.find(eId);
88 if (search != elogList.end())
89 {
Jayanth Othayothcb65ffc2018-10-16 08:29:32 -050090 // elog exists in the list, Skip the dump
Jayanth Othayoth24964822017-09-04 22:07:06 -050091 return;
92 }
93
William A. Kennington III90d147a2018-06-12 16:42:33 -070094 auto iter = propertyMap.find("xyz.openbmc_project.Logging.Entry");
95 if (iter == propertyMap.end())
Jayanth Othayothd0f00642017-09-04 06:26:30 -050096 {
97 return;
98 }
99
100 auto attr = iter->second.find("Message");
101 if (attr == iter->second.end())
102 {
103 return;
104 }
105
Patrick Williams07f0f462020-05-13 11:58:11 -0500106 auto& data = std::get<PropertyName>(attr->second);
Jayanth Othayothd0f00642017-09-04 06:26:30 -0500107 if (data.empty())
108 {
Jayanth Othayothcb65ffc2018-10-16 08:29:32 -0500109 // No Message skip
Jayanth Othayothd0f00642017-09-04 06:26:30 -0500110 return;
111 }
112
Marri Devender Rao0deb2872018-11-12 07:45:54 -0600113 EType errorType;
114 for (const auto& [type, errorList] : errorMap)
Jayanth Othayothd0f00642017-09-04 06:26:30 -0500115 {
Marri Devender Rao0deb2872018-11-12 07:45:54 -0600116 auto error = std::find(errorList.begin(), errorList.end(), data);
117 if (error != errorList.end())
118 {
119 errorType = type;
120 break;
121 }
122 }
123
124 // error not supported in the configuration
125 if (errorType.empty())
126 {
Jayanth Othayothd0f00642017-09-04 06:26:30 -0500127 return;
128 }
129
130 std::vector<std::string> fullPaths;
131 fullPaths.push_back(objectPath);
132
133 try
134 {
Jayanth Othayothcb65ffc2018-10-16 08:29:32 -0500135 // Save the elog information. This is to avoid dump requests
136 // in elog restore path.
Jayanth Othayoth24964822017-09-04 22:07:06 -0500137 elogList.insert(eId);
138
139 phosphor::dump::elog::serialize(elogList);
140
Marri Devender Rao0deb2872018-11-12 07:45:54 -0600141 auto item = std::find_if(
Dhruvaraj Subhashchandranfef66a92020-09-06 13:10:59 -0500142 phosphor::dump::bmc::TypeMap.begin(),
143 phosphor::dump::bmc::TypeMap.end(),
Marri Devender Rao0deb2872018-11-12 07:45:54 -0600144 [errorType](const auto& err) { return (err.second == errorType); });
Dhruvaraj Subhashchandranfef66a92020-09-06 13:10:59 -0500145 if (item != phosphor::dump::bmc::TypeMap.end())
Marri Devender Rao0deb2872018-11-12 07:45:54 -0600146 {
147 iMgr.IMgr::create((*item).first, fullPaths);
148 }
Jayanth Othayothd0f00642017-09-04 06:26:30 -0500149 }
150 catch (QuotaExceeded& e)
151 {
Jayanth Othayothcb65ffc2018-10-16 08:29:32 -0500152 // No action now
Jayanth Othayothd0f00642017-09-04 06:26:30 -0500153 }
154 return;
155}
156
Jayanth Othayoth24964822017-09-04 22:07:06 -0500157void Watch::delCallback(sdbusplus::message::message& msg)
158{
William A. Kennington III90d147a2018-06-12 16:42:33 -0700159 sdbusplus::message::object_path objectPath;
William A. Kennington III15cd3ce2018-05-15 11:34:44 -0700160 try
161 {
William A. Kennington III90d147a2018-06-12 16:42:33 -0700162 msg.read(objectPath);
William A. Kennington III15cd3ce2018-05-15 11:34:44 -0700163 }
164 catch (const sdbusplus::exception::SdBusError& e)
165 {
166 log<level::ERR>("Failed to parse elog del signal",
167 entry("ERROR=%s", e.what()),
168 entry("REPLY_SIG=%s", msg.get_signature()));
169 return;
170 }
Jayanth Othayoth24964822017-09-04 22:07:06 -0500171
Andrew Geissler638b43f2020-04-16 13:33:33 -0500172 std::size_t found = objectPath.str.find("entry");
173 if (found == std::string::npos)
174 {
175 // Not a error entry so skip
176 return;
177 }
178
Jayanth Othayothcb65ffc2018-10-16 08:29:32 -0500179 // Get elog id
Jayanth Othayoth24964822017-09-04 22:07:06 -0500180 auto eId = getEid(objectPath);
181
Jayanth Othayothcb65ffc2018-10-16 08:29:32 -0500182 // Delete the elog entry from the list and serialize
Jayanth Othayoth24964822017-09-04 22:07:06 -0500183 auto search = elogList.find(eId);
184 if (search != elogList.end())
185 {
186 elogList.erase(search);
187 phosphor::dump::elog::serialize(elogList);
188 }
189}
190
Jayanth Othayothcb65ffc2018-10-16 08:29:32 -0500191} // namespace elog
192} // namespace dump
193} // namespace phosphor