blob: fb4f891a975af30c9a656dbdb1a107a9aacef0db [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>
George Liue9fb5c62021-07-01 14:05:32 +08006#include <phosphor-logging/lg2.hpp>
Patrick Venture91ac8d32018-11-01 17:03:22 -07007#include <sdbusplus/exception.hpp>
George Liu4b062012020-10-13 15:26:58 +08008#include <xyz/openbmc_project/Led/Fru/Monitor/error.hpp>
9#include <xyz/openbmc_project/Led/Mapper/error.hpp>
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050010
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -050011namespace phosphor
12{
13namespace led
14{
15namespace fru
16{
17namespace fault
18{
19namespace monitor
20{
21
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050022using namespace phosphor::logging;
23
Patrick Venture91ac8d32018-11-01 17:03:22 -070024constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
25constexpr auto MAPPER_OBJ_PATH = "/xyz/openbmc_project/object_mapper";
26constexpr auto MAPPER_IFACE = "xyz.openbmc_project.ObjectMapper";
27constexpr auto OBJMGR_IFACE = "org.freedesktop.DBus.ObjectManager";
28constexpr auto LED_GROUPS = "/xyz/openbmc_project/led/groups/";
29constexpr auto LOG_PATH = "/xyz/openbmc_project/logging";
30constexpr auto LOG_IFACE = "xyz.openbmc_project.Logging.Entry";
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050031
Patrick Venture91ac8d32018-11-01 17:03:22 -070032using AssociationList =
33 std::vector<std::tuple<std::string, std::string, std::string>>;
Patrick Williamsa41d2822020-05-13 17:57:23 -050034using Attributes = std::variant<bool, AssociationList>;
Dhruvaraj Subhashchandranaebfde82017-07-11 01:36:33 -050035using PropertyName = std::string;
Matt Spinlerb2f253b2018-06-13 09:54:13 -050036using PropertyMap = std::map<PropertyName, Attributes>;
37using InterfaceName = std::string;
38using InterfaceMap = std::map<InterfaceName, PropertyMap>;
Dhruvaraj Subhashchandranaebfde82017-07-11 01:36:33 -050039
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -050040using Service = std::string;
41using Path = std::string;
42using Interface = std::string;
43using Interfaces = std::vector<Interface>;
44using MapperResponseType = std::map<Path, std::map<Service, Interfaces>>;
45
Patrick Venture91ac8d32018-11-01 17:03:22 -070046using MethodErr =
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050047 sdbusplus::xyz::openbmc_project::Led::Mapper::Error::MethodError;
48using ObjectNotFoundErr =
49 sdbusplus::xyz::openbmc_project::Led::Mapper::Error::ObjectNotFoundError;
Patrick Venture91ac8d32018-11-01 17:03:22 -070050using InventoryPathErr = sdbusplus::xyz::openbmc_project::Led::Fru::Monitor::
51 Error::InventoryPathError;
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050052
Patrick Venture91ac8d32018-11-01 17:03:22 -070053std::string getService(sdbusplus::bus::bus& bus, const std::string& path)
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050054{
Patrick Venture91ac8d32018-11-01 17:03:22 -070055 auto mapper = bus.new_method_call(MAPPER_BUSNAME, MAPPER_OBJ_PATH,
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050056 MAPPER_IFACE, "GetObject");
57 mapper.append(path.c_str(), std::vector<std::string>({OBJMGR_IFACE}));
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050058
59 std::map<std::string, std::vector<std::string>> mapperResponse;
William A. Kennington III151122a2018-05-15 12:00:32 -070060 try
61 {
George Liud78de142021-08-23 16:16:32 +080062 auto mapperResponseMsg = bus.call(mapper);
William A. Kennington III151122a2018-05-15 12:00:32 -070063 mapperResponseMsg.read(mapperResponse);
64 }
Patrick Williams7152edc2021-09-02 09:41:54 -050065 catch (const sdbusplus::exception::exception& e)
William A. Kennington III151122a2018-05-15 12:00:32 -070066 {
George Liue9fb5c62021-07-01 14:05:32 +080067 lg2::error(
68 "Failed to parse getService mapper response, ERROR = {ERROR}",
69 "ERROR", e);
William A. Kennington III151122a2018-05-15 12:00:32 -070070 using namespace xyz::openbmc_project::Led::Mapper;
Patrick Venture91ac8d32018-11-01 17:03:22 -070071 elog<ObjectNotFoundErr>(ObjectNotFoundError::METHOD_NAME("GetObject"),
72 ObjectNotFoundError::PATH(path.c_str()),
73 ObjectNotFoundError::INTERFACE(OBJMGR_IFACE));
William A. Kennington III151122a2018-05-15 12:00:32 -070074 }
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050075 if (mapperResponse.empty())
76 {
77 using namespace xyz::openbmc_project::Led::Mapper;
Patrick Venture91ac8d32018-11-01 17:03:22 -070078 elog<ObjectNotFoundErr>(ObjectNotFoundError::METHOD_NAME("GetObject"),
79 ObjectNotFoundError::PATH(path.c_str()),
80 ObjectNotFoundError::INTERFACE(OBJMGR_IFACE));
George Liuc5e0f312021-12-27 15:54:31 +080081 return {};
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050082 }
83
84 return mapperResponse.cbegin()->first;
85}
86
Patrick Venture91ac8d32018-11-01 17:03:22 -070087void action(sdbusplus::bus::bus& bus, const std::string& path, bool assert)
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -050088{
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050089 std::string service;
90 try
91 {
Matt Spinlere77b8342018-09-12 10:41:53 -050092 std::string groups{LED_GROUPS};
93 groups.pop_back();
94 service = getService(bus, groups);
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050095 }
Patrick Williamsfb56fde2021-10-06 12:27:15 -050096 catch (const MethodErr& e)
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050097 {
98 commit<MethodErr>();
99 return;
100 }
Patrick Williamsfb56fde2021-10-06 12:27:15 -0500101 catch (const ObjectNotFoundErr& e)
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500102 {
103 commit<ObjectNotFoundErr>();
104 return;
105 }
106
107 auto pos = path.rfind("/");
108 if (pos == std::string::npos)
109 {
110 using namespace xyz::openbmc_project::Led::Fru::Monitor;
Patrick Venture91ac8d32018-11-01 17:03:22 -0700111 report<InventoryPathErr>(InventoryPathError::PATH(path.c_str()));
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500112 return;
113 }
114 auto unit = path.substr(pos + 1);
115
Patrick Venture91ac8d32018-11-01 17:03:22 -0700116 std::string ledPath = LED_GROUPS + unit + '_' + LED_FAULT;
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500117
Patrick Venture91ac8d32018-11-01 17:03:22 -0700118 auto method = bus.new_method_call(service.c_str(), ledPath.c_str(),
119 "org.freedesktop.DBus.Properties", "Set");
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500120 method.append("xyz.openbmc_project.Led.Group");
121 method.append("Asserted");
122
Patrick Williamsa41d2822020-05-13 17:57:23 -0500123 method.append(std::variant<bool>(assert));
Adriana Kobylak08d613e2018-07-18 15:30:39 -0500124
125 try
126 {
127 bus.call_noreply(method);
128 }
Patrick Williams7152edc2021-09-02 09:41:54 -0500129 catch (const sdbusplus::exception::exception& e)
Adriana Kobylak08d613e2018-07-18 15:30:39 -0500130 {
131 // Log an info message, system may not have all the LED Groups defined
George Liue9fb5c62021-07-01 14:05:32 +0800132 lg2::info("Failed to Assert LED Group, ERROR = {ERROR}", "ERROR", e);
Adriana Kobylak08d613e2018-07-18 15:30:39 -0500133 }
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500134
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500135 return;
136}
137
Patrick Williams3eedbe42017-05-31 17:27:05 -0500138void Add::created(sdbusplus::message::message& msg)
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500139{
Patrick Williams3eedbe42017-05-31 17:27:05 -0500140 auto bus = msg.get_bus();
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500141
Matt Spinlerb2f253b2018-06-13 09:54:13 -0500142 sdbusplus::message::object_path objectPath;
143 InterfaceMap interfaces;
William A. Kennington III151122a2018-05-15 12:00:32 -0700144 try
145 {
Matt Spinlerb2f253b2018-06-13 09:54:13 -0500146 msg.read(objectPath, interfaces);
William A. Kennington III151122a2018-05-15 12:00:32 -0700147 }
Patrick Williams7152edc2021-09-02 09:41:54 -0500148 catch (const sdbusplus::exception::exception& e)
William A. Kennington III151122a2018-05-15 12:00:32 -0700149 {
George Liue9fb5c62021-07-01 14:05:32 +0800150 lg2::error("Failed to parse created message, ERROR = {ERROR}", "ERROR",
151 e);
William A. Kennington III151122a2018-05-15 12:00:32 -0700152 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.
George Liue9fb5c62021-07-01 14:05:32 +0800169 // TODO:(phosphor-logging#25): support sdbusplus::message::object_path
170 // directly.
171 lg2::info("{PATH} created", "PATH", objectPath.str);
Matt Spinler3d2b0d62018-03-29 08:48:37 -0500172
Andrew Geisslera6e48922019-11-06 08:43:54 -0600173 auto attr = iter->second.find("Associations");
Dhruvaraj Subhashchandranaebfde82017-07-11 01:36:33 -0500174 if (attr == iter->second.end())
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500175 {
Patrick Williams3eedbe42017-05-31 17:27:05 -0500176 return;
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500177 }
178
Patrick Williams5ebebef2020-05-13 11:47:27 -0500179 auto& assocs = std::get<AssociationList>(attr->second);
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500180 if (assocs.empty())
181 {
Patrick Venture91ac8d32018-11-01 17:03:22 -0700182 // No associations skip
Patrick Williams3eedbe42017-05-31 17:27:05 -0500183 return;
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500184 }
185
186 for (const auto& item : assocs)
187 {
188 if (std::get<1>(item).compare(CALLOUT_REV_ASSOCIATION) == 0)
189 {
Patrick Williams3eedbe42017-05-31 17:27:05 -0500190 removeWatches.emplace_back(
Dhruvaraj Subhashchandranaebfde82017-07-11 01:36:33 -0500191 std::make_unique<Remove>(bus, std::get<2>(item)));
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500192 action(bus, std::get<2>(item), true);
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500193 }
194 }
Dhruvaraj Subhashchandranaebfde82017-07-11 01:36:33 -0500195
Patrick Williams3eedbe42017-05-31 17:27:05 -0500196 return;
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500197}
198
Matt Spinler91122922018-09-24 11:31:44 -0500199void getLoggingSubTree(sdbusplus::bus::bus& bus, MapperResponseType& subtree)
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500200{
201 auto depth = 0;
Patrick Venture91ac8d32018-11-01 17:03:22 -0700202 auto mapperCall = bus.new_method_call(MAPPER_BUSNAME, MAPPER_OBJ_PATH,
203 MAPPER_IFACE, "GetSubTree");
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500204 mapperCall.append("/");
205 mapperCall.append(depth);
206 mapperCall.append(std::vector<Interface>({LOG_IFACE}));
207
William A. Kennington III151122a2018-05-15 12:00:32 -0700208 try
209 {
Matt Spinler91122922018-09-24 11:31:44 -0500210 auto mapperResponseMsg = bus.call(mapperCall);
George Liud78de142021-08-23 16:16:32 +0800211 mapperResponseMsg.read(subtree);
William A. Kennington III151122a2018-05-15 12:00:32 -0700212 }
Patrick Williams7152edc2021-09-02 09:41:54 -0500213 catch (const sdbusplus::exception::exception& e)
William A. Kennington III151122a2018-05-15 12:00:32 -0700214 {
George Liue9fb5c62021-07-01 14:05:32 +0800215 lg2::error(
216 "Failed to parse existing callouts subtree message, ERROR = {ERROR}",
217 "ERROR", e);
William A. Kennington III151122a2018-05-15 12:00:32 -0700218 }
Matt Spinler91122922018-09-24 11:31:44 -0500219}
220
221void Add::processExistingCallouts(sdbusplus::bus::bus& bus)
222{
Patrick Venture91ac8d32018-11-01 17:03:22 -0700223 MapperResponseType mapperResponse;
Matt Spinler91122922018-09-24 11:31:44 -0500224
225 getLoggingSubTree(bus, mapperResponse);
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500226 if (mapperResponse.empty())
227 {
Patrick Venture91ac8d32018-11-01 17:03:22 -0700228 // No errors to process.
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500229 return;
230 }
231
232 for (const auto& elem : mapperResponse)
233 {
Patrick Venture91ac8d32018-11-01 17:03:22 -0700234 auto method = bus.new_method_call(
235 elem.second.begin()->first.c_str(), elem.first.c_str(),
236 "org.freedesktop.DBus.Properties", "Get");
Andrew Geisslera6e48922019-11-06 08:43:54 -0600237 method.append("xyz.openbmc_project.Association.Definitions");
238 method.append("Associations");
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500239 auto reply = bus.call(method);
240 if (reply.is_method_error())
241 {
Patrick Venture91ac8d32018-11-01 17:03:22 -0700242 // do not stop, continue with next elog
George Liue9fb5c62021-07-01 14:05:32 +0800243 lg2::error("Error in getting associations");
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500244 continue;
245 }
246
Patrick Williamsa41d2822020-05-13 17:57:23 -0500247 std::variant<AssociationList> assoc;
William A. Kennington III151122a2018-05-15 12:00:32 -0700248 try
249 {
250 reply.read(assoc);
251 }
Patrick Williams7152edc2021-09-02 09:41:54 -0500252 catch (const sdbusplus::exception::exception& e)
William A. Kennington III151122a2018-05-15 12:00:32 -0700253 {
George Liue9fb5c62021-07-01 14:05:32 +0800254 lg2::error(
255 "Failed to parse existing callouts associations message, ERROR = {ERROR}",
256 "ERROR", e);
William A. Kennington III151122a2018-05-15 12:00:32 -0700257 continue;
258 }
Patrick Williams5ebebef2020-05-13 11:47:27 -0500259 auto& assocs = std::get<AssociationList>(assoc);
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500260 if (assocs.empty())
261 {
Patrick Venture91ac8d32018-11-01 17:03:22 -0700262 // no associations, skip
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500263 continue;
264 }
265
266 for (const auto& item : assocs)
267 {
268 if (std::get<1>(item).compare(CALLOUT_REV_ASSOCIATION) == 0)
269 {
270 removeWatches.emplace_back(
271 std::make_unique<Remove>(bus, std::get<2>(item)));
272 action(bus, std::get<2>(item), true);
273 }
274 }
275 }
276}
277
Patrick Williams3eedbe42017-05-31 17:27:05 -0500278void Remove::removed(sdbusplus::message::message& msg)
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500279{
Patrick Williams3eedbe42017-05-31 17:27:05 -0500280 auto bus = msg.get_bus();
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500281
Patrick Williams3eedbe42017-05-31 17:27:05 -0500282 action(bus, inventoryPath, false);
283 return;
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500284}
285
Patrick Venture91ac8d32018-11-01 17:03:22 -0700286} // namespace monitor
287} // namespace fault
288} // namespace fru
289} // namespace led
290} // namespace phosphor