blob: 047994fc1c8b8711cfa3b0e6ec223feb91d46618 [file] [log] [blame]
Patrick Venture91ac8d32018-11-01 17:03:22 -07001#include "fru-fault-monitor.hpp"
2
3#include "elog-errors.hpp"
Patrick Venture91ac8d32018-11-01 17:03:22 -07004
5#include <phosphor-logging/elog.hpp>
6#include <sdbusplus/exception.hpp>
George Liu4b062012020-10-13 15:26:58 +08007#include <xyz/openbmc_project/Led/Fru/Monitor/error.hpp>
8#include <xyz/openbmc_project/Led/Mapper/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
Patrick Venture91ac8d32018-11-01 17:03:22 -070023constexpr 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";
29constexpr auto LOG_IFACE = "xyz.openbmc_project.Logging.Entry";
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050030
Patrick Venture91ac8d32018-11-01 17:03:22 -070031using AssociationList =
32 std::vector<std::tuple<std::string, std::string, std::string>>;
Patrick Williamsa41d2822020-05-13 17:57:23 -050033using Attributes = std::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
Patrick Venture91ac8d32018-11-01 17:03:22 -070045using MethodErr =
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050046 sdbusplus::xyz::openbmc_project::Led::Mapper::Error::MethodError;
47using ObjectNotFoundErr =
48 sdbusplus::xyz::openbmc_project::Led::Mapper::Error::ObjectNotFoundError;
Patrick Venture91ac8d32018-11-01 17:03:22 -070049using InventoryPathErr = sdbusplus::xyz::openbmc_project::Led::Fru::Monitor::
50 Error::InventoryPathError;
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050051
Patrick Venture91ac8d32018-11-01 17:03:22 -070052std::string getService(sdbusplus::bus::bus& bus, const std::string& path)
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050053{
Patrick Venture91ac8d32018-11-01 17:03:22 -070054 auto mapper = bus.new_method_call(MAPPER_BUSNAME, MAPPER_OBJ_PATH,
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050055 MAPPER_IFACE, "GetObject");
56 mapper.append(path.c_str(), std::vector<std::string>({OBJMGR_IFACE}));
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050057
58 std::map<std::string, std::vector<std::string>> mapperResponse;
William A. Kennington III151122a2018-05-15 12:00:32 -070059 try
60 {
George Liud78de142021-08-23 16:16:32 +080061 auto mapperResponseMsg = bus.call(mapper);
William A. Kennington III151122a2018-05-15 12:00:32 -070062 mapperResponseMsg.read(mapperResponse);
63 }
Patrick Williams7152edc2021-09-02 09:41:54 -050064 catch (const sdbusplus::exception::exception& e)
William A. Kennington III151122a2018-05-15 12:00:32 -070065 {
Patrick Venture91ac8d32018-11-01 17:03:22 -070066 log<level::ERR>(
George Liud78de142021-08-23 16:16:32 +080067 "Failed to GetObject or parse getService mapper response",
68 entry("ERROR=%s", e.what()));
William A. Kennington III151122a2018-05-15 12:00:32 -070069 using namespace xyz::openbmc_project::Led::Mapper;
Patrick Venture91ac8d32018-11-01 17:03:22 -070070 elog<ObjectNotFoundErr>(ObjectNotFoundError::METHOD_NAME("GetObject"),
71 ObjectNotFoundError::PATH(path.c_str()),
72 ObjectNotFoundError::INTERFACE(OBJMGR_IFACE));
William A. Kennington III151122a2018-05-15 12:00:32 -070073 }
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050074 if (mapperResponse.empty())
75 {
76 using namespace xyz::openbmc_project::Led::Mapper;
Patrick Venture91ac8d32018-11-01 17:03:22 -070077 elog<ObjectNotFoundErr>(ObjectNotFoundError::METHOD_NAME("GetObject"),
78 ObjectNotFoundError::PATH(path.c_str()),
79 ObjectNotFoundError::INTERFACE(OBJMGR_IFACE));
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050080 }
81
82 return mapperResponse.cbegin()->first;
83}
84
Patrick Venture91ac8d32018-11-01 17:03:22 -070085void action(sdbusplus::bus::bus& bus, const std::string& path, bool assert)
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -050086{
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050087 std::string service;
88 try
89 {
Matt Spinlere77b8342018-09-12 10:41:53 -050090 std::string groups{LED_GROUPS};
91 groups.pop_back();
92 service = getService(bus, groups);
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050093 }
94 catch (MethodErr& e)
95 {
96 commit<MethodErr>();
97 return;
98 }
99 catch (ObjectNotFoundErr& e)
100 {
101 commit<ObjectNotFoundErr>();
102 return;
103 }
104
105 auto pos = path.rfind("/");
106 if (pos == std::string::npos)
107 {
108 using namespace xyz::openbmc_project::Led::Fru::Monitor;
Patrick Venture91ac8d32018-11-01 17:03:22 -0700109 report<InventoryPathErr>(InventoryPathError::PATH(path.c_str()));
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500110 return;
111 }
112 auto unit = path.substr(pos + 1);
113
Patrick Venture91ac8d32018-11-01 17:03:22 -0700114 std::string ledPath = LED_GROUPS + unit + '_' + LED_FAULT;
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500115
Patrick Venture91ac8d32018-11-01 17:03:22 -0700116 auto method = bus.new_method_call(service.c_str(), ledPath.c_str(),
117 "org.freedesktop.DBus.Properties", "Set");
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500118 method.append("xyz.openbmc_project.Led.Group");
119 method.append("Asserted");
120
Patrick Williamsa41d2822020-05-13 17:57:23 -0500121 method.append(std::variant<bool>(assert));
Adriana Kobylak08d613e2018-07-18 15:30:39 -0500122
123 try
124 {
125 bus.call_noreply(method);
126 }
Patrick Williams7152edc2021-09-02 09:41:54 -0500127 catch (const sdbusplus::exception::exception& e)
Adriana Kobylak08d613e2018-07-18 15:30:39 -0500128 {
129 // Log an info message, system may not have all the LED Groups defined
130 log<level::INFO>("Failed to Assert LED Group",
131 entry("ERROR=%s", e.what()));
132 }
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500133
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500134 return;
135}
136
Patrick Williams3eedbe42017-05-31 17:27:05 -0500137void Add::created(sdbusplus::message::message& msg)
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500138{
Patrick Williams3eedbe42017-05-31 17:27:05 -0500139 auto bus = msg.get_bus();
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500140
Matt Spinlerb2f253b2018-06-13 09:54:13 -0500141 sdbusplus::message::object_path objectPath;
142 InterfaceMap interfaces;
William A. Kennington III151122a2018-05-15 12:00:32 -0700143 try
144 {
Matt Spinlerb2f253b2018-06-13 09:54:13 -0500145 msg.read(objectPath, interfaces);
William A. Kennington III151122a2018-05-15 12:00:32 -0700146 }
Patrick Williams7152edc2021-09-02 09:41:54 -0500147 catch (const sdbusplus::exception::exception& e)
William A. Kennington III151122a2018-05-15 12:00:32 -0700148 {
149 log<level::ERR>("Failed to parse created message",
150 entry("ERROR=%s", e.what()),
151 entry("REPLY_SIG=%s", msg.get_signature()));
152 return;
153 }
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500154
Matt Spinlerb2f253b2018-06-13 09:54:13 -0500155 std::size_t found = objectPath.str.find(ELOG_ENTRY);
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500156 if (found == std::string::npos)
157 {
Patrick Venture91ac8d32018-11-01 17:03:22 -0700158 // Not a new error entry skip
Patrick Williams3eedbe42017-05-31 17:27:05 -0500159 return;
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500160 }
Andrew Geisslera6e48922019-11-06 08:43:54 -0600161 auto iter = interfaces.find("xyz.openbmc_project.Association.Definitions");
Matt Spinlerb2f253b2018-06-13 09:54:13 -0500162 if (iter == interfaces.end())
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500163 {
Patrick Williams3eedbe42017-05-31 17:27:05 -0500164 return;
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500165 }
166
Patrick Venture91ac8d32018-11-01 17:03:22 -0700167 // Nothing else shows when a specific error log
168 // has been created. Do it here.
Matt Spinlerb2f253b2018-06-13 09:54:13 -0500169 std::string message{objectPath.str + " created"};
Matt Spinler3d2b0d62018-03-29 08:48:37 -0500170 log<level::INFO>(message.c_str());
171
Andrew Geisslera6e48922019-11-06 08:43:54 -0600172 auto attr = iter->second.find("Associations");
Dhruvaraj Subhashchandranaebfde82017-07-11 01:36:33 -0500173 if (attr == iter->second.end())
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500174 {
Patrick Williams3eedbe42017-05-31 17:27:05 -0500175 return;
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500176 }
177
Patrick Williams5ebebef2020-05-13 11:47:27 -0500178 auto& assocs = std::get<AssociationList>(attr->second);
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500179 if (assocs.empty())
180 {
Patrick Venture91ac8d32018-11-01 17:03:22 -0700181 // No associations skip
Patrick Williams3eedbe42017-05-31 17:27:05 -0500182 return;
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500183 }
184
185 for (const auto& item : assocs)
186 {
187 if (std::get<1>(item).compare(CALLOUT_REV_ASSOCIATION) == 0)
188 {
Patrick Williams3eedbe42017-05-31 17:27:05 -0500189 removeWatches.emplace_back(
Dhruvaraj Subhashchandranaebfde82017-07-11 01:36:33 -0500190 std::make_unique<Remove>(bus, std::get<2>(item)));
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500191 action(bus, std::get<2>(item), true);
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500192 }
193 }
Dhruvaraj Subhashchandranaebfde82017-07-11 01:36:33 -0500194
Patrick Williams3eedbe42017-05-31 17:27:05 -0500195 return;
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500196}
197
Matt Spinler91122922018-09-24 11:31:44 -0500198void getLoggingSubTree(sdbusplus::bus::bus& bus, MapperResponseType& subtree)
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500199{
200 auto depth = 0;
Patrick Venture91ac8d32018-11-01 17:03:22 -0700201 auto mapperCall = bus.new_method_call(MAPPER_BUSNAME, MAPPER_OBJ_PATH,
202 MAPPER_IFACE, "GetSubTree");
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500203 mapperCall.append("/");
204 mapperCall.append(depth);
205 mapperCall.append(std::vector<Interface>({LOG_IFACE}));
206
William A. Kennington III151122a2018-05-15 12:00:32 -0700207 try
208 {
Matt Spinler91122922018-09-24 11:31:44 -0500209 auto mapperResponseMsg = bus.call(mapperCall);
George Liud78de142021-08-23 16:16:32 +0800210 mapperResponseMsg.read(subtree);
William A. Kennington III151122a2018-05-15 12:00:32 -0700211 }
Patrick Williams7152edc2021-09-02 09:41:54 -0500212 catch (const sdbusplus::exception::exception& e)
William A. Kennington III151122a2018-05-15 12:00:32 -0700213 {
George Liud78de142021-08-23 16:16:32 +0800214 log<level::ERR>("Failed to parse existing callouts subtree message",
215 entry("ERROR=%s", e.what()));
William A. Kennington III151122a2018-05-15 12:00:32 -0700216 }
Matt Spinler91122922018-09-24 11:31:44 -0500217}
218
219void Add::processExistingCallouts(sdbusplus::bus::bus& bus)
220{
Patrick Venture91ac8d32018-11-01 17:03:22 -0700221 MapperResponseType mapperResponse;
Matt Spinler91122922018-09-24 11:31:44 -0500222
223 getLoggingSubTree(bus, mapperResponse);
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500224 if (mapperResponse.empty())
225 {
Patrick Venture91ac8d32018-11-01 17:03:22 -0700226 // No errors to process.
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500227 return;
228 }
229
230 for (const auto& elem : mapperResponse)
231 {
Patrick Venture91ac8d32018-11-01 17:03:22 -0700232 auto method = bus.new_method_call(
233 elem.second.begin()->first.c_str(), elem.first.c_str(),
234 "org.freedesktop.DBus.Properties", "Get");
Andrew Geisslera6e48922019-11-06 08:43:54 -0600235 method.append("xyz.openbmc_project.Association.Definitions");
236 method.append("Associations");
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500237 auto reply = bus.call(method);
238 if (reply.is_method_error())
239 {
Patrick Venture91ac8d32018-11-01 17:03:22 -0700240 // do not stop, continue with next elog
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500241 log<level::ERR>("Error in getting associations");
242 continue;
243 }
244
Patrick Williamsa41d2822020-05-13 17:57:23 -0500245 std::variant<AssociationList> assoc;
William A. Kennington III151122a2018-05-15 12:00:32 -0700246 try
247 {
248 reply.read(assoc);
249 }
Patrick Williams7152edc2021-09-02 09:41:54 -0500250 catch (const sdbusplus::exception::exception& e)
William A. Kennington III151122a2018-05-15 12:00:32 -0700251 {
George Liud78de142021-08-23 16:16:32 +0800252 log<level::ERR>("Failed to get Associations or parse existing "
253 "callouts associations message",
254 entry("ERROR=%s", e.what()));
William A. Kennington III151122a2018-05-15 12:00:32 -0700255 continue;
256 }
Patrick Williams5ebebef2020-05-13 11:47:27 -0500257 auto& assocs = std::get<AssociationList>(assoc);
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500258 if (assocs.empty())
259 {
Patrick Venture91ac8d32018-11-01 17:03:22 -0700260 // no associations, skip
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500261 continue;
262 }
263
264 for (const auto& item : assocs)
265 {
266 if (std::get<1>(item).compare(CALLOUT_REV_ASSOCIATION) == 0)
267 {
268 removeWatches.emplace_back(
269 std::make_unique<Remove>(bus, std::get<2>(item)));
270 action(bus, std::get<2>(item), true);
271 }
272 }
273 }
274}
275
Patrick Williams3eedbe42017-05-31 17:27:05 -0500276void Remove::removed(sdbusplus::message::message& msg)
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500277{
Patrick Williams3eedbe42017-05-31 17:27:05 -0500278 auto bus = msg.get_bus();
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500279
Patrick Williams3eedbe42017-05-31 17:27:05 -0500280 action(bus, inventoryPath, false);
281 return;
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500282}
283
Patrick Venture91ac8d32018-11-01 17:03:22 -0700284} // namespace monitor
285} // namespace fault
286} // namespace fru
287} // namespace led
288} // namespace phosphor