blob: 0a7789cfd1c5cde0c86254c53e83534a48de11d9 [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>
Marri Devender Rao0deb2872018-11-12 07:45:54 -060011#include <fstream>
Jayanth Othayothd0f00642017-09-04 06:26:30 -050012#include <phosphor-logging/elog.hpp>
William A. Kennington III15cd3ce2018-05-15 11:34:44 -070013#include <sdbusplus/exception.hpp>
Jayanth Othayothd0f00642017-09-04 06:26:30 -050014
Vishwanatha Subbanna31085972017-10-05 17:06:37 +053015// Register class version with Cereal
16CEREAL_CLASS_VERSION(phosphor::dump::elog::Watch, CLASS_VERSION);
Jayanth Othayothd0f00642017-09-04 06:26:30 -050017
18namespace phosphor
19{
20namespace dump
21{
22namespace elog
23{
24
25using namespace phosphor::logging;
26constexpr auto LOG_PATH = "/xyz/openbmc_project/logging";
Jayanth Othayothd0f00642017-09-04 06:26:30 -050027using Message = std::string;
28using Attributes = sdbusplus::message::variant<Message>;
29using AttributeName = std::string;
30using AttributeMap = std::map<AttributeName, Attributes>;
31using PropertyName = std::string;
32using PropertyMap = std::map<PropertyName, AttributeMap>;
Jayanth Othayothd0f00642017-09-04 06:26:30 -050033
Jayanth Othayothcb65ffc2018-10-16 08:29:32 -050034Watch::Watch(sdbusplus::bus::bus& bus, IMgr& iMgr) :
Jayanth Othayoth24964822017-09-04 22:07:06 -050035 iMgr(iMgr),
Jayanth Othayothcb65ffc2018-10-16 08:29:32 -050036 addMatch(bus,
37 sdbusplus::bus::match::rules::interfacesAdded() +
38 sdbusplus::bus::match::rules::path_namespace(OBJ_LOGGING),
39 std::bind(std::mem_fn(&Watch::addCallback), this,
40 std::placeholders::_1)),
41 delMatch(bus,
42 sdbusplus::bus::match::rules::interfacesRemoved() +
43 sdbusplus::bus::match::rules::path_namespace(OBJ_LOGGING),
44 std::bind(std::mem_fn(&Watch::delCallback), this,
45 std::placeholders::_1))
Jayanth Othayoth24964822017-09-04 22:07:06 -050046{
47
48 fs::path file(ELOG_ID_PERSIST_PATH);
49 if (fs::exists(file))
50 {
51 if (!deserialize(ELOG_ID_PERSIST_PATH, elogList))
52 {
53 log<level::ERR>("Error occurred during error id deserialize");
54 }
55 }
56}
57
58void Watch::addCallback(sdbusplus::message::message& msg)
Jayanth Othayothd0f00642017-09-04 06:26:30 -050059{
Jayanth Othayothd0f00642017-09-04 06:26:30 -050060 using QuotaExceeded =
61 sdbusplus::xyz::openbmc_project::Dump::Create::Error::QuotaExceeded;
62
William A. Kennington III90d147a2018-06-12 16:42:33 -070063 sdbusplus::message::object_path objectPath;
64 PropertyMap propertyMap;
William A. Kennington III15cd3ce2018-05-15 11:34:44 -070065 try
66 {
William A. Kennington III90d147a2018-06-12 16:42:33 -070067 msg.read(objectPath, propertyMap);
William A. Kennington III15cd3ce2018-05-15 11:34:44 -070068 }
69 catch (const sdbusplus::exception::SdBusError& e)
70 {
71 log<level::ERR>("Failed to parse elog add signal",
72 entry("ERROR=%s", e.what()),
73 entry("REPLY_SIG=%s", msg.get_signature()));
74 return;
75 }
Jayanth Othayothd0f00642017-09-04 06:26:30 -050076
William A. Kennington III90d147a2018-06-12 16:42:33 -070077 std::size_t found = objectPath.str.find("entry");
Jayanth Othayothd0f00642017-09-04 06:26:30 -050078 if (found == std::string::npos)
79 {
Jayanth Othayothcb65ffc2018-10-16 08:29:32 -050080 // Not a new error entry skip
Jayanth Othayothd0f00642017-09-04 06:26:30 -050081 return;
82 }
83
Jayanth Othayoth24964822017-09-04 22:07:06 -050084 auto eId = getEid(objectPath);
85
86 auto search = elogList.find(eId);
87 if (search != elogList.end())
88 {
Jayanth Othayothcb65ffc2018-10-16 08:29:32 -050089 // elog exists in the list, Skip the dump
Jayanth Othayoth24964822017-09-04 22:07:06 -050090 return;
91 }
92
William A. Kennington III90d147a2018-06-12 16:42:33 -070093 auto iter = propertyMap.find("xyz.openbmc_project.Logging.Entry");
94 if (iter == propertyMap.end())
Jayanth Othayothd0f00642017-09-04 06:26:30 -050095 {
96 return;
97 }
98
99 auto attr = iter->second.find("Message");
100 if (attr == iter->second.end())
101 {
102 return;
103 }
104
105 auto& data =
106 sdbusplus::message::variant_ns::get<PropertyName>(attr->second);
107 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(
142 TypeMap.begin(), TypeMap.end(),
143 [errorType](const auto& err) { return (err.second == errorType); });
144 if (item != TypeMap.end())
145 {
146 iMgr.IMgr::create((*item).first, fullPaths);
147 }
Jayanth Othayothd0f00642017-09-04 06:26:30 -0500148 }
149 catch (QuotaExceeded& e)
150 {
Jayanth Othayothcb65ffc2018-10-16 08:29:32 -0500151 // No action now
Jayanth Othayothd0f00642017-09-04 06:26:30 -0500152 }
153 return;
154}
155
Jayanth Othayoth24964822017-09-04 22:07:06 -0500156void Watch::delCallback(sdbusplus::message::message& msg)
157{
William A. Kennington III90d147a2018-06-12 16:42:33 -0700158 sdbusplus::message::object_path objectPath;
William A. Kennington III15cd3ce2018-05-15 11:34:44 -0700159 try
160 {
William A. Kennington III90d147a2018-06-12 16:42:33 -0700161 msg.read(objectPath);
William A. Kennington III15cd3ce2018-05-15 11:34:44 -0700162 }
163 catch (const sdbusplus::exception::SdBusError& e)
164 {
165 log<level::ERR>("Failed to parse elog del signal",
166 entry("ERROR=%s", e.what()),
167 entry("REPLY_SIG=%s", msg.get_signature()));
168 return;
169 }
Jayanth Othayoth24964822017-09-04 22:07:06 -0500170
Jayanth Othayothcb65ffc2018-10-16 08:29:32 -0500171 // Get elog id
Jayanth Othayoth24964822017-09-04 22:07:06 -0500172 auto eId = getEid(objectPath);
173
Jayanth Othayothcb65ffc2018-10-16 08:29:32 -0500174 // Delete the elog entry from the list and serialize
Jayanth Othayoth24964822017-09-04 22:07:06 -0500175 auto search = elogList.find(eId);
176 if (search != elogList.end())
177 {
178 elogList.erase(search);
179 phosphor::dump::elog::serialize(elogList);
180 }
181}
182
Jayanth Othayothcb65ffc2018-10-16 08:29:32 -0500183} // namespace elog
184} // namespace dump
185} // namespace phosphor