blob: 5ab65df563384a358ba810e82f80621bc8c860a9 [file] [log] [blame]
Jayanth Othayothd0f00642017-09-04 06:26:30 -05001#include <phosphor-logging/elog.hpp>
2
3#include "elog_watch.hpp"
4#include "dump_internal.hpp"
5#include "xyz/openbmc_project/Dump/Create/error.hpp"
Jayanth Othayoth24964822017-09-04 22:07:06 -05006#include "dump_serialize.hpp"
Jayanth Othayothd0f00642017-09-04 06:26:30 -05007
8namespace phosphor
9{
10namespace dump
11{
12namespace elog
13{
14
15using namespace phosphor::logging;
16constexpr auto LOG_PATH = "/xyz/openbmc_project/logging";
17constexpr auto INTERNAL_FAILURE =
18 "xyz.openbmc_project.Common.Error.InternalFailure";
19using Message = std::string;
20using Attributes = sdbusplus::message::variant<Message>;
21using AttributeName = std::string;
22using AttributeMap = std::map<AttributeName, Attributes>;
23using PropertyName = std::string;
24using PropertyMap = std::map<PropertyName, AttributeMap>;
25using LogEntryMsg = std::pair<sdbusplus::message::object_path, PropertyMap>;
26
Jayanth Othayoth24964822017-09-04 22:07:06 -050027Watch::Watch(sdbusplus::bus::bus& bus, IMgr& iMgr):
28 iMgr(iMgr),
29 addMatch(
30 bus,
31 sdbusplus::bus::match::rules::interfacesAdded() +
32 sdbusplus::bus::match::rules::path_namespace(
33 OBJ_LOGGING),
34 std::bind(std::mem_fn(&Watch::addCallback),
35 this, std::placeholders::_1)),
36 delMatch(
37 bus,
38 sdbusplus::bus::match::rules::interfacesRemoved() +
39 sdbusplus::bus::match::rules::path_namespace(
40 OBJ_LOGGING),
41 std::bind(std::mem_fn(&Watch::delCallback),
42 this, std::placeholders::_1))
43{
44
45 fs::path file(ELOG_ID_PERSIST_PATH);
46 if (fs::exists(file))
47 {
48 if (!deserialize(ELOG_ID_PERSIST_PATH, elogList))
49 {
50 log<level::ERR>("Error occurred during error id deserialize");
51 }
52 }
53}
54
55void Watch::addCallback(sdbusplus::message::message& msg)
Jayanth Othayothd0f00642017-09-04 06:26:30 -050056{
57 using Type =
58 sdbusplus::xyz::openbmc_project::Dump::Internal::server::Create::Type;
59 using QuotaExceeded =
60 sdbusplus::xyz::openbmc_project::Dump::Create::Error::QuotaExceeded;
61
62 LogEntryMsg logEntry;
63 msg.read(logEntry);
64
65 std::string objectPath(std::move(logEntry.first));
66
67 std::size_t found = objectPath.find("entry");
68 if (found == std::string::npos)
69 {
70 //Not a new error entry skip
71 return;
72 }
73
Jayanth Othayoth24964822017-09-04 22:07:06 -050074 auto eId = getEid(objectPath);
75
76 auto search = elogList.find(eId);
77 if (search != elogList.end())
78 {
79 //elog exists in the list, Skip the dump
80 return;
81 }
82
Jayanth Othayothd0f00642017-09-04 06:26:30 -050083 auto iter = logEntry.second.find("xyz.openbmc_project.Logging.Entry");
84 if (iter == logEntry.second.end())
85 {
86 return;
87 }
88
89 auto attr = iter->second.find("Message");
90 if (attr == iter->second.end())
91 {
92 return;
93 }
94
95 auto& data =
96 sdbusplus::message::variant_ns::get<PropertyName>(attr->second);
97 if (data.empty())
98 {
99 //No Message skip
100 return;
101 }
102
Jayanth Othayoth24964822017-09-04 22:07:06 -0500103 if (data != INTERNAL_FAILURE)
Jayanth Othayothd0f00642017-09-04 06:26:30 -0500104 {
105 //Not a InternalFailure, skip
106 return;
107 }
108
109 std::vector<std::string> fullPaths;
110 fullPaths.push_back(objectPath);
111
112 try
113 {
Jayanth Othayoth24964822017-09-04 22:07:06 -0500114 //Save the elog information. This is to avoid dump requests
115 //in elog restore path.
116 elogList.insert(eId);
117
118 phosphor::dump::elog::serialize(elogList);
119
Jayanth Othayothd0f00642017-09-04 06:26:30 -0500120 //Call internal create function to initiate dump
121 iMgr.IMgr::create(Type::InternalFailure, fullPaths);
122 }
123 catch (QuotaExceeded& e)
124 {
125 //No action now
126 }
127 return;
128}
129
Jayanth Othayoth24964822017-09-04 22:07:06 -0500130void Watch::delCallback(sdbusplus::message::message& msg)
131{
132 sdbusplus::message::object_path logEntry;
133 msg.read(logEntry);
134
135 //Get elog entry message string.
136 std::string objectPath(logEntry);
137
138 //Get elog id
139 auto eId = getEid(objectPath);
140
141 //Delete the elog entry from the list and serialize
142 auto search = elogList.find(eId);
143 if (search != elogList.end())
144 {
145 elogList.erase(search);
146 phosphor::dump::elog::serialize(elogList);
147 }
148}
149
Jayanth Othayothd0f00642017-09-04 06:26:30 -0500150}//namespace elog
151}//namespace dump
152}//namespace phosphor