blob: 431a7f476d76f84005b38a61df1a9f44bb07e734 [file] [log] [blame]
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -05001#include <phosphor-logging/elog.hpp>
William A. Kennington III151122a2018-05-15 12:00:32 -07002#include <sdbusplus/exception.hpp>
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -05003#include "xyz/openbmc_project/Led/Fru/Monitor/error.hpp"
4#include "xyz/openbmc_project/Led/Mapper/error.hpp"
5#include "elog-errors.hpp"
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -05006#include "fru-fault-monitor.hpp"
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -05007#include <phosphor-logging/elog-errors.hpp>
8#include "xyz/openbmc_project/Common/error.hpp"
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -05009
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -050010namespace phosphor
11{
12namespace led
13{
14namespace fru
15{
16namespace fault
17{
18namespace monitor
19{
20
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050021using namespace phosphor::logging;
22
23constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
24constexpr auto MAPPER_OBJ_PATH = "/xyz/openbmc_project/object_mapper";
25constexpr auto MAPPER_IFACE = "xyz.openbmc_project.ObjectMapper";
26constexpr auto OBJMGR_IFACE = "org.freedesktop.DBus.ObjectManager";
27constexpr auto LED_GROUPS = "/xyz/openbmc_project/led/groups/";
28constexpr auto LOG_PATH = "/xyz/openbmc_project/logging";
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -050029constexpr auto LOG_IFACE = "xyz.openbmc_project.Logging.Entry";
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050030
31using AssociationList = std::vector<std::tuple<
32 std::string, std::string, std::string>>;
Dhruvaraj Subhashchandranaebfde82017-07-11 01:36:33 -050033using Attributes = sdbusplus::message::variant<bool,AssociationList>;
Dhruvaraj Subhashchandranaebfde82017-07-11 01:36:33 -050034using PropertyName = std::string;
Matt Spinlerb2f253b2018-06-13 09:54:13 -050035using PropertyMap = std::map<PropertyName, Attributes>;
36using InterfaceName = std::string;
37using InterfaceMap = std::map<InterfaceName, PropertyMap>;
Dhruvaraj Subhashchandranaebfde82017-07-11 01:36:33 -050038
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -050039using Service = std::string;
40using Path = std::string;
41using Interface = std::string;
42using Interfaces = std::vector<Interface>;
43using MapperResponseType = std::map<Path, std::map<Service, Interfaces>>;
44
45using InternalFailure =
46 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
47
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050048using MethodErr =
49 sdbusplus::xyz::openbmc_project::Led::Mapper::Error::MethodError;
50using ObjectNotFoundErr =
51 sdbusplus::xyz::openbmc_project::Led::Mapper::Error::ObjectNotFoundError;
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050052using InventoryPathErr =
53 sdbusplus::xyz::openbmc_project::
54 Led::Fru::Monitor::Error::InventoryPathError;
55
56std::string getService(sdbusplus::bus::bus& bus,
57 const std::string& path)
58{
59 auto mapper = bus.new_method_call(MAPPER_BUSNAME,
60 MAPPER_OBJ_PATH,
61 MAPPER_IFACE, "GetObject");
62 mapper.append(path.c_str(), std::vector<std::string>({OBJMGR_IFACE}));
63 auto mapperResponseMsg = bus.call(mapper);
64 if (mapperResponseMsg.is_method_error())
65 {
66 using namespace xyz::openbmc_project::Led::Mapper;
67 elog<MethodErr>(
68 MethodError::METHOD_NAME("GetObject"),
69 MethodError::PATH(path.c_str()),
70 MethodError::INTERFACE(
71 OBJMGR_IFACE));
72 }
73
74 std::map<std::string, std::vector<std::string>> mapperResponse;
William A. Kennington III151122a2018-05-15 12:00:32 -070075 try
76 {
77 mapperResponseMsg.read(mapperResponse);
78 }
79 catch (const sdbusplus::exception::SdBusError& e)
80 {
81 log<level::ERR>("Failed to parse getService mapper response",
82 entry("ERROR=%s", e.what()),
83 entry("REPLY_SIG=%s", mapperResponseMsg.get_signature()));
84 using namespace xyz::openbmc_project::Led::Mapper;
85 elog<ObjectNotFoundErr>(
86 ObjectNotFoundError::METHOD_NAME("GetObject"),
87 ObjectNotFoundError::PATH(path.c_str()),
88 ObjectNotFoundError::INTERFACE(
89 OBJMGR_IFACE));
90 }
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050091 if (mapperResponse.empty())
92 {
93 using namespace xyz::openbmc_project::Led::Mapper;
94 elog<ObjectNotFoundErr>(
95 ObjectNotFoundError::METHOD_NAME("GetObject"),
96 ObjectNotFoundError::PATH(path.c_str()),
97 ObjectNotFoundError::INTERFACE(
98 OBJMGR_IFACE));
99 }
100
101 return mapperResponse.cbegin()->first;
102}
103
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500104void action(sdbusplus::bus::bus& bus,
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500105 const std::string& path,
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500106 bool assert)
107{
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500108 std::string service;
109 try
110 {
111 service = getService(bus, LED_GROUPS);
112 }
113 catch (MethodErr& e)
114 {
115 commit<MethodErr>();
116 return;
117 }
118 catch (ObjectNotFoundErr& e)
119 {
120 commit<ObjectNotFoundErr>();
121 return;
122 }
123
124 auto pos = path.rfind("/");
125 if (pos == std::string::npos)
126 {
127 using namespace xyz::openbmc_project::Led::Fru::Monitor;
128 report<InventoryPathErr>(
129 InventoryPathError::PATH(
130 path.c_str()));
131 return;
132 }
133 auto unit = path.substr(pos + 1);
134
135 std::string ledPath = LED_GROUPS +
136 unit + '_' + LED_FAULT;
137
138 auto method = bus.new_method_call(service.c_str(),
139 ledPath.c_str(),
140 "org.freedesktop.DBus.Properties",
141 "Set");
142 method.append("xyz.openbmc_project.Led.Group");
143 method.append("Asserted");
144
145 method.append(sdbusplus::message::variant<bool>(assert));
146 bus.call_noreply(method);
147
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500148 return;
149}
150
Patrick Williams3eedbe42017-05-31 17:27:05 -0500151void Add::created(sdbusplus::message::message& msg)
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500152{
Patrick Williams3eedbe42017-05-31 17:27:05 -0500153 auto bus = msg.get_bus();
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500154
Matt Spinlerb2f253b2018-06-13 09:54:13 -0500155 sdbusplus::message::object_path objectPath;
156 InterfaceMap interfaces;
William A. Kennington III151122a2018-05-15 12:00:32 -0700157 try
158 {
Matt Spinlerb2f253b2018-06-13 09:54:13 -0500159 msg.read(objectPath, interfaces);
William A. Kennington III151122a2018-05-15 12:00:32 -0700160 }
161 catch (const sdbusplus::exception::SdBusError& e)
162 {
163 log<level::ERR>("Failed to parse created message",
164 entry("ERROR=%s", e.what()),
165 entry("REPLY_SIG=%s", msg.get_signature()));
166 return;
167 }
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500168
Matt Spinlerb2f253b2018-06-13 09:54:13 -0500169 std::size_t found = objectPath.str.find(ELOG_ENTRY);
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500170 if (found == std::string::npos)
171 {
172 //Not a new error entry skip
Patrick Williams3eedbe42017-05-31 17:27:05 -0500173 return;
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500174 }
Matt Spinlerb2f253b2018-06-13 09:54:13 -0500175 auto iter = interfaces.find("org.openbmc.Associations");
176 if (iter == interfaces.end())
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500177 {
Patrick Williams3eedbe42017-05-31 17:27:05 -0500178 return;
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500179 }
180
Matt Spinler3d2b0d62018-03-29 08:48:37 -0500181 //Nothing else shows when a specific error log
182 //has been created. Do it here.
Matt Spinlerb2f253b2018-06-13 09:54:13 -0500183 std::string message{objectPath.str + " created"};
Matt Spinler3d2b0d62018-03-29 08:48:37 -0500184 log<level::INFO>(message.c_str());
185
Dhruvaraj Subhashchandranaebfde82017-07-11 01:36:33 -0500186 auto attr = iter->second.find("associations");
187 if (attr == iter->second.end())
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500188 {
Patrick Williams3eedbe42017-05-31 17:27:05 -0500189 return;
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500190 }
191
Dhruvaraj Subhashchandranaebfde82017-07-11 01:36:33 -0500192 auto& assocs =
193 sdbusplus::message::variant_ns::get<AssociationList>(attr->second);
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500194 if (assocs.empty())
195 {
196 //No associations skip
Patrick Williams3eedbe42017-05-31 17:27:05 -0500197 return;
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500198 }
199
200 for (const auto& item : assocs)
201 {
202 if (std::get<1>(item).compare(CALLOUT_REV_ASSOCIATION) == 0)
203 {
Patrick Williams3eedbe42017-05-31 17:27:05 -0500204 removeWatches.emplace_back(
Dhruvaraj Subhashchandranaebfde82017-07-11 01:36:33 -0500205 std::make_unique<Remove>(bus, std::get<2>(item)));
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500206 action(bus, std::get<2>(item), true);
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500207 }
208 }
Dhruvaraj Subhashchandranaebfde82017-07-11 01:36:33 -0500209
Patrick Williams3eedbe42017-05-31 17:27:05 -0500210 return;
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500211}
212
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500213void Add::processExistingCallouts(sdbusplus::bus::bus& bus)
214{
215 auto depth = 0;
216 auto mapperCall = bus.new_method_call(MAPPER_BUSNAME,
217 MAPPER_OBJ_PATH,
218 MAPPER_IFACE,
219 "GetSubTree");
220 mapperCall.append("/");
221 mapperCall.append(depth);
222 mapperCall.append(std::vector<Interface>({LOG_IFACE}));
223
224 auto mapperResponseMsg = bus.call(mapperCall);
225 if (mapperResponseMsg.is_method_error())
226 {
227 using namespace xyz::openbmc_project::Led::Mapper;
228 report<MethodErr>(
229 MethodError::METHOD_NAME("GetSubTree"),
230 MethodError::PATH(MAPPER_OBJ_PATH),
231 MethodError::INTERFACE(
232 OBJMGR_IFACE));
233 return;
234 }
235
236 MapperResponseType mapperResponse;
William A. Kennington III151122a2018-05-15 12:00:32 -0700237 try
238 {
239 mapperResponseMsg.read(mapperResponse);
240 }
241 catch (const sdbusplus::exception::SdBusError& e)
242 {
243 log<level::ERR>("Failed to parse existing callouts subtree message",
244 entry("ERROR=%s", e.what()),
245 entry("REPLY_SIG=%s", mapperResponseMsg.get_signature()));
246 return;
247 }
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500248 if (mapperResponse.empty())
249 {
Dhruvaraj Subhashchandranfc30e0c2017-09-19 03:59:08 -0500250 //No errors to process.
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500251 return;
252 }
253
254 for (const auto& elem : mapperResponse)
255 {
256 auto method = bus.new_method_call(elem.second.begin()->first.c_str(),
257 elem.first.c_str(),
258 "org.freedesktop.DBus.Properties",
259 "Get");
260 method.append("org.openbmc.Associations");
261 method.append("associations");
262 auto reply = bus.call(method);
263 if (reply.is_method_error())
264 {
265 //do not stop, continue with next elog
266 log<level::ERR>("Error in getting associations");
267 continue;
268 }
269
270 sdbusplus::message::variant<AssociationList> assoc;
William A. Kennington III151122a2018-05-15 12:00:32 -0700271 try
272 {
273 reply.read(assoc);
274 }
275 catch (const sdbusplus::exception::SdBusError& e)
276 {
277 log<level::ERR>("Failed to parse existing callouts associations message",
278 entry("ERROR=%s", e.what()),
279 entry("REPLY_SIG=%s", reply.get_signature()));
280 continue;
281 }
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500282 auto& assocs = assoc.get<AssociationList>();
283 if (assocs.empty())
284 {
285 //no associations, skip
286 continue;
287 }
288
289 for (const auto& item : assocs)
290 {
291 if (std::get<1>(item).compare(CALLOUT_REV_ASSOCIATION) == 0)
292 {
293 removeWatches.emplace_back(
294 std::make_unique<Remove>(bus, std::get<2>(item)));
295 action(bus, std::get<2>(item), true);
296 }
297 }
298 }
299}
300
Patrick Williams3eedbe42017-05-31 17:27:05 -0500301void Remove::removed(sdbusplus::message::message& msg)
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500302{
Patrick Williams3eedbe42017-05-31 17:27:05 -0500303 auto bus = msg.get_bus();
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500304
Patrick Williams3eedbe42017-05-31 17:27:05 -0500305 action(bus, inventoryPath, false);
306 return;
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500307}
308
309}//namespace monitor
310}//namespace fault
311}//namespace fru
312}//namespace led
313}//namespace phosphor