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