blob: e2a38669e4bbad6c6f245c6ff35be717bdffd7b4 [file] [log] [blame]
Vishwanatha Subbanna31085972017-10-05 17:06:37 +05301#include <cereal/cereal.hpp>
Jayanth Othayothd0f00642017-09-04 06:26:30 -05002#include <phosphor-logging/elog.hpp>
William A. Kennington III15cd3ce2018-05-15 11:34:44 -07003#include <sdbusplus/exception.hpp>
Jayanth Othayothd0f00642017-09-04 06:26:30 -05004
5#include "elog_watch.hpp"
6#include "dump_internal.hpp"
7#include "xyz/openbmc_project/Dump/Create/error.hpp"
Jayanth Othayoth24964822017-09-04 22:07:06 -05008#include "dump_serialize.hpp"
Vishwanatha Subbanna31085972017-10-05 17:06:37 +05309#include "config.h"
10
11// Register class version with Cereal
12CEREAL_CLASS_VERSION(phosphor::dump::elog::Watch, CLASS_VERSION);
Jayanth Othayothd0f00642017-09-04 06:26:30 -050013
14namespace phosphor
15{
16namespace dump
17{
18namespace elog
19{
20
21using namespace phosphor::logging;
22constexpr auto LOG_PATH = "/xyz/openbmc_project/logging";
23constexpr auto INTERNAL_FAILURE =
24 "xyz.openbmc_project.Common.Error.InternalFailure";
25using Message = std::string;
26using Attributes = sdbusplus::message::variant<Message>;
27using AttributeName = std::string;
28using AttributeMap = std::map<AttributeName, Attributes>;
29using PropertyName = std::string;
30using PropertyMap = std::map<PropertyName, AttributeMap>;
31using LogEntryMsg = std::pair<sdbusplus::message::object_path, PropertyMap>;
32
Jayanth Othayoth24964822017-09-04 22:07:06 -050033Watch::Watch(sdbusplus::bus::bus& bus, IMgr& iMgr):
34 iMgr(iMgr),
35 addMatch(
36 bus,
37 sdbusplus::bus::match::rules::interfacesAdded() +
38 sdbusplus::bus::match::rules::path_namespace(
39 OBJ_LOGGING),
40 std::bind(std::mem_fn(&Watch::addCallback),
41 this, std::placeholders::_1)),
42 delMatch(
43 bus,
44 sdbusplus::bus::match::rules::interfacesRemoved() +
45 sdbusplus::bus::match::rules::path_namespace(
46 OBJ_LOGGING),
47 std::bind(std::mem_fn(&Watch::delCallback),
48 this, std::placeholders::_1))
49{
50
51 fs::path file(ELOG_ID_PERSIST_PATH);
52 if (fs::exists(file))
53 {
54 if (!deserialize(ELOG_ID_PERSIST_PATH, elogList))
55 {
56 log<level::ERR>("Error occurred during error id deserialize");
57 }
58 }
59}
60
61void Watch::addCallback(sdbusplus::message::message& msg)
Jayanth Othayothd0f00642017-09-04 06:26:30 -050062{
63 using Type =
64 sdbusplus::xyz::openbmc_project::Dump::Internal::server::Create::Type;
65 using QuotaExceeded =
66 sdbusplus::xyz::openbmc_project::Dump::Create::Error::QuotaExceeded;
67
68 LogEntryMsg logEntry;
William A. Kennington III15cd3ce2018-05-15 11:34:44 -070069 try
70 {
71 msg.read(logEntry);
72 }
73 catch (const sdbusplus::exception::SdBusError& e)
74 {
75 log<level::ERR>("Failed to parse elog add signal",
76 entry("ERROR=%s", e.what()),
77 entry("REPLY_SIG=%s", msg.get_signature()));
78 return;
79 }
Jayanth Othayothd0f00642017-09-04 06:26:30 -050080
81 std::string objectPath(std::move(logEntry.first));
82
83 std::size_t found = objectPath.find("entry");
84 if (found == std::string::npos)
85 {
86 //Not a new error entry skip
87 return;
88 }
89
Jayanth Othayoth24964822017-09-04 22:07:06 -050090 auto eId = getEid(objectPath);
91
92 auto search = elogList.find(eId);
93 if (search != elogList.end())
94 {
95 //elog exists in the list, Skip the dump
96 return;
97 }
98
Jayanth Othayothd0f00642017-09-04 06:26:30 -050099 auto iter = logEntry.second.find("xyz.openbmc_project.Logging.Entry");
100 if (iter == logEntry.second.end())
101 {
102 return;
103 }
104
105 auto attr = iter->second.find("Message");
106 if (attr == iter->second.end())
107 {
108 return;
109 }
110
111 auto& data =
112 sdbusplus::message::variant_ns::get<PropertyName>(attr->second);
113 if (data.empty())
114 {
115 //No Message skip
116 return;
117 }
118
Jayanth Othayoth24964822017-09-04 22:07:06 -0500119 if (data != INTERNAL_FAILURE)
Jayanth Othayothd0f00642017-09-04 06:26:30 -0500120 {
121 //Not a InternalFailure, skip
122 return;
123 }
124
125 std::vector<std::string> fullPaths;
126 fullPaths.push_back(objectPath);
127
128 try
129 {
Jayanth Othayoth24964822017-09-04 22:07:06 -0500130 //Save the elog information. This is to avoid dump requests
131 //in elog restore path.
132 elogList.insert(eId);
133
134 phosphor::dump::elog::serialize(elogList);
135
Jayanth Othayothd0f00642017-09-04 06:26:30 -0500136 //Call internal create function to initiate dump
137 iMgr.IMgr::create(Type::InternalFailure, fullPaths);
138 }
139 catch (QuotaExceeded& e)
140 {
141 //No action now
142 }
143 return;
144}
145
Jayanth Othayoth24964822017-09-04 22:07:06 -0500146void Watch::delCallback(sdbusplus::message::message& msg)
147{
148 sdbusplus::message::object_path logEntry;
William A. Kennington III15cd3ce2018-05-15 11:34:44 -0700149 try
150 {
151 msg.read(logEntry);
152 }
153 catch (const sdbusplus::exception::SdBusError& e)
154 {
155 log<level::ERR>("Failed to parse elog del signal",
156 entry("ERROR=%s", e.what()),
157 entry("REPLY_SIG=%s", msg.get_signature()));
158 return;
159 }
Jayanth Othayoth24964822017-09-04 22:07:06 -0500160
161 //Get elog entry message string.
162 std::string objectPath(logEntry);
163
164 //Get elog id
165 auto eId = getEid(objectPath);
166
167 //Delete the elog entry from the list and serialize
168 auto search = elogList.find(eId);
169 if (search != elogList.end())
170 {
171 elogList.erase(search);
172 phosphor::dump::elog::serialize(elogList);
173 }
174}
175
Jayanth Othayothd0f00642017-09-04 06:26:30 -0500176}//namespace elog
177}//namespace dump
178}//namespace phosphor