blob: cf6486275d5c9db11d87106e49def7704de09daf [file] [log] [blame]
Patrick Venture91ac8d32018-11-01 17:03:22 -07001#include "fru-fault-monitor.hpp"
2
Patrick Williams9bd334f2022-03-16 11:28:26 -05003#include <phosphor-logging/elog-errors.hpp>
Patrick Venture91ac8d32018-11-01 17:03:22 -07004#include <phosphor-logging/elog.hpp>
George Liue9fb5c62021-07-01 14:05:32 +08005#include <phosphor-logging/lg2.hpp>
Patrick Venture91ac8d32018-11-01 17:03:22 -07006#include <sdbusplus/exception.hpp>
Patrick Williams9bd334f2022-03-16 11:28:26 -05007#include <xyz/openbmc_project/Common/error.hpp>
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -05008
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -05009namespace phosphor
10{
11namespace led
12{
13namespace fru
14{
15namespace fault
16{
17namespace monitor
18{
19
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050020using namespace phosphor::logging;
21
George Liu1f0b7152023-07-18 09:24:34 +080022static constexpr auto mapperBusName = "xyz.openbmc_project.ObjectMapper";
23static constexpr auto mapperObjPath = "/xyz/openbmc_project/object_mapper";
24static constexpr auto mapperIntf = "xyz.openbmc_project.ObjectMapper";
25static constexpr auto objMgrIntf = "org.freedesktop.DBus.ObjectManager";
26static constexpr auto ledGroups = "/xyz/openbmc_project/led/groups/";
27static constexpr auto logIntf = "xyz.openbmc_project.Logging.Entry";
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050028
Patrick Venture91ac8d32018-11-01 17:03:22 -070029using AssociationList =
30 std::vector<std::tuple<std::string, std::string, std::string>>;
Patrick Williamsa41d2822020-05-13 17:57:23 -050031using Attributes = std::variant<bool, AssociationList>;
Dhruvaraj Subhashchandranaebfde82017-07-11 01:36:33 -050032using PropertyName = std::string;
Patrick Williamsf2044032022-03-17 05:12:30 -050033using PropertyMap = std::unordered_map<PropertyName, Attributes>;
Matt Spinlerb2f253b2018-06-13 09:54:13 -050034using InterfaceName = std::string;
Patrick Williamsf2044032022-03-17 05:12:30 -050035using InterfaceMap = std::unordered_map<InterfaceName, PropertyMap>;
Dhruvaraj Subhashchandranaebfde82017-07-11 01:36:33 -050036
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -050037using Service = std::string;
38using Path = std::string;
39using Interface = std::string;
40using Interfaces = std::vector<Interface>;
Patrick Williamsf2044032022-03-17 05:12:30 -050041using MapperResponseType =
42 std::unordered_map<Path, std::unordered_map<Service, Interfaces>>;
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -050043
Patrick Williams9bd334f2022-03-16 11:28:26 -050044using ResourceNotFoundErr =
45 sdbusplus::xyz::openbmc_project::Common::Error::ResourceNotFound;
46using InvalidArgumentErr =
47 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument;
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050048
Patrick Williams3e073ba2022-07-22 19:26:52 -050049std::string getService(sdbusplus::bus_t& bus, const std::string& path)
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050050{
George Liu1f0b7152023-07-18 09:24:34 +080051 auto mapper = bus.new_method_call(mapperBusName, mapperObjPath, mapperIntf,
52 "GetObject");
53 mapper.append(path.c_str(), std::vector<std::string>({objMgrIntf}));
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050054
Patrick Williamsf2044032022-03-17 05:12:30 -050055 std::unordered_map<std::string, std::vector<std::string>> mapperResponse;
William A. Kennington III151122a2018-05-15 12:00:32 -070056 try
57 {
George Liud78de142021-08-23 16:16:32 +080058 auto mapperResponseMsg = bus.call(mapper);
William A. Kennington III151122a2018-05-15 12:00:32 -070059 mapperResponseMsg.read(mapperResponse);
60 }
Patrick Williams3e073ba2022-07-22 19:26:52 -050061 catch (const sdbusplus::exception_t& e)
William A. Kennington III151122a2018-05-15 12:00:32 -070062 {
George Liue9fb5c62021-07-01 14:05:32 +080063 lg2::error(
64 "Failed to parse getService mapper response, ERROR = {ERROR}",
65 "ERROR", e);
Patrick Williams9bd334f2022-03-16 11:28:26 -050066 using namespace xyz::openbmc_project::Common;
67 elog<ResourceNotFoundErr>(ResourceNotFound::RESOURCE(path.c_str()));
William A. Kennington III151122a2018-05-15 12:00:32 -070068 }
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050069 if (mapperResponse.empty())
70 {
Patrick Williams9bd334f2022-03-16 11:28:26 -050071 using namespace xyz::openbmc_project::Common;
72 elog<ResourceNotFoundErr>(ResourceNotFound::RESOURCE(path.c_str()));
George Liuc5e0f312021-12-27 15:54:31 +080073 return {};
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050074 }
75
76 return mapperResponse.cbegin()->first;
77}
78
Patrick Williams3e073ba2022-07-22 19:26:52 -050079void action(sdbusplus::bus_t& bus, const std::string& path, bool assert)
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -050080{
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050081 std::string service;
82 try
83 {
George Liu1f0b7152023-07-18 09:24:34 +080084 std::string groups{ledGroups};
Matt Spinlere77b8342018-09-12 10:41:53 -050085 groups.pop_back();
86 service = getService(bus, groups);
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050087 }
Patrick Williams9bd334f2022-03-16 11:28:26 -050088 catch (const ResourceNotFoundErr& e)
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050089 {
Patrick Williams9bd334f2022-03-16 11:28:26 -050090 commit<ResourceNotFoundErr>();
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050091 return;
92 }
93
George Liu4bb15d82024-08-22 19:10:44 +080094 auto pos = path.rfind('/');
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050095 if (pos == std::string::npos)
96 {
Patrick Williams9bd334f2022-03-16 11:28:26 -050097 using namespace xyz::openbmc_project::Common;
98 report<InvalidArgumentErr>(
99 InvalidArgument::ARGUMENT_NAME("path"),
100 InvalidArgument::ARGUMENT_VALUE(path.c_str()));
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500101 return;
102 }
103 auto unit = path.substr(pos + 1);
104
George Liu1f0b7152023-07-18 09:24:34 +0800105 std::string ledPath = ledGroups + unit + '_' + LED_FAULT;
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500106
Patrick Venture91ac8d32018-11-01 17:03:22 -0700107 auto method = bus.new_method_call(service.c_str(), ledPath.c_str(),
108 "org.freedesktop.DBus.Properties", "Set");
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500109 method.append("xyz.openbmc_project.Led.Group");
110 method.append("Asserted");
111
Patrick Williamsa41d2822020-05-13 17:57:23 -0500112 method.append(std::variant<bool>(assert));
Adriana Kobylak08d613e2018-07-18 15:30:39 -0500113
114 try
115 {
116 bus.call_noreply(method);
117 }
Patrick Williams3e073ba2022-07-22 19:26:52 -0500118 catch (const sdbusplus::exception_t& e)
Adriana Kobylak08d613e2018-07-18 15:30:39 -0500119 {
120 // Log an info message, system may not have all the LED Groups defined
George Liue9fb5c62021-07-01 14:05:32 +0800121 lg2::info("Failed to Assert LED Group, ERROR = {ERROR}", "ERROR", e);
Adriana Kobylak08d613e2018-07-18 15:30:39 -0500122 }
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500123
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500124 return;
125}
126
Patrick Williams3e073ba2022-07-22 19:26:52 -0500127void Add::created(sdbusplus::message_t& msg)
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500128{
Patrick Williams3eedbe42017-05-31 17:27:05 -0500129 auto bus = msg.get_bus();
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500130
Matt Spinlerb2f253b2018-06-13 09:54:13 -0500131 sdbusplus::message::object_path objectPath;
132 InterfaceMap interfaces;
William A. Kennington III151122a2018-05-15 12:00:32 -0700133 try
134 {
Matt Spinlerb2f253b2018-06-13 09:54:13 -0500135 msg.read(objectPath, interfaces);
William A. Kennington III151122a2018-05-15 12:00:32 -0700136 }
Patrick Williams3e073ba2022-07-22 19:26:52 -0500137 catch (const sdbusplus::exception_t& e)
William A. Kennington III151122a2018-05-15 12:00:32 -0700138 {
George Liue9fb5c62021-07-01 14:05:32 +0800139 lg2::error("Failed to parse created message, ERROR = {ERROR}", "ERROR",
140 e);
William A. Kennington III151122a2018-05-15 12:00:32 -0700141 return;
142 }
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500143
Matt Spinlerb2f253b2018-06-13 09:54:13 -0500144 std::size_t found = objectPath.str.find(ELOG_ENTRY);
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500145 if (found == std::string::npos)
146 {
Patrick Venture91ac8d32018-11-01 17:03:22 -0700147 // Not a new error entry skip
Patrick Williams3eedbe42017-05-31 17:27:05 -0500148 return;
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500149 }
Andrew Geisslera6e48922019-11-06 08:43:54 -0600150 auto iter = interfaces.find("xyz.openbmc_project.Association.Definitions");
Matt Spinlerb2f253b2018-06-13 09:54:13 -0500151 if (iter == interfaces.end())
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500152 {
Patrick Williams3eedbe42017-05-31 17:27:05 -0500153 return;
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500154 }
155
Patrick Venture91ac8d32018-11-01 17:03:22 -0700156 // Nothing else shows when a specific error log
157 // has been created. Do it here.
George Liub4c82cf2023-01-04 10:23:36 +0800158 lg2::info("{PATH} created", "PATH", objectPath);
Matt Spinler3d2b0d62018-03-29 08:48:37 -0500159
Andrew Geisslera6e48922019-11-06 08:43:54 -0600160 auto attr = iter->second.find("Associations");
Dhruvaraj Subhashchandranaebfde82017-07-11 01:36:33 -0500161 if (attr == iter->second.end())
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500162 {
Patrick Williams3eedbe42017-05-31 17:27:05 -0500163 return;
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500164 }
165
Patrick Williams5ebebef2020-05-13 11:47:27 -0500166 auto& assocs = std::get<AssociationList>(attr->second);
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500167
168 for (const auto& item : assocs)
169 {
170 if (std::get<1>(item).compare(CALLOUT_REV_ASSOCIATION) == 0)
171 {
Patrick Williams3eedbe42017-05-31 17:27:05 -0500172 removeWatches.emplace_back(
Dhruvaraj Subhashchandranaebfde82017-07-11 01:36:33 -0500173 std::make_unique<Remove>(bus, std::get<2>(item)));
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500174 action(bus, std::get<2>(item), true);
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500175 }
176 }
Dhruvaraj Subhashchandranaebfde82017-07-11 01:36:33 -0500177
Patrick Williams3eedbe42017-05-31 17:27:05 -0500178 return;
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500179}
180
Patrick Williams3e073ba2022-07-22 19:26:52 -0500181void getLoggingSubTree(sdbusplus::bus_t& bus, MapperResponseType& subtree)
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500182{
183 auto depth = 0;
George Liu1f0b7152023-07-18 09:24:34 +0800184 auto mapperCall = bus.new_method_call(mapperBusName, mapperObjPath,
185 mapperIntf, "GetSubTree");
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500186 mapperCall.append("/");
187 mapperCall.append(depth);
George Liu1f0b7152023-07-18 09:24:34 +0800188 mapperCall.append(std::vector<Interface>({logIntf}));
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500189
William A. Kennington III151122a2018-05-15 12:00:32 -0700190 try
191 {
Matt Spinler91122922018-09-24 11:31:44 -0500192 auto mapperResponseMsg = bus.call(mapperCall);
George Liud78de142021-08-23 16:16:32 +0800193 mapperResponseMsg.read(subtree);
William A. Kennington III151122a2018-05-15 12:00:32 -0700194 }
Patrick Williams3e073ba2022-07-22 19:26:52 -0500195 catch (const sdbusplus::exception_t& e)
William A. Kennington III151122a2018-05-15 12:00:32 -0700196 {
George Liue9fb5c62021-07-01 14:05:32 +0800197 lg2::error(
198 "Failed to parse existing callouts subtree message, ERROR = {ERROR}",
199 "ERROR", e);
William A. Kennington III151122a2018-05-15 12:00:32 -0700200 }
Matt Spinler91122922018-09-24 11:31:44 -0500201}
202
Patrick Williams3e073ba2022-07-22 19:26:52 -0500203void Add::processExistingCallouts(sdbusplus::bus_t& bus)
Matt Spinler91122922018-09-24 11:31:44 -0500204{
Patrick Venture91ac8d32018-11-01 17:03:22 -0700205 MapperResponseType mapperResponse;
Matt Spinler91122922018-09-24 11:31:44 -0500206
207 getLoggingSubTree(bus, mapperResponse);
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500208 if (mapperResponse.empty())
209 {
Patrick Venture91ac8d32018-11-01 17:03:22 -0700210 // No errors to process.
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500211 return;
212 }
213
214 for (const auto& elem : mapperResponse)
215 {
Patrick Venture91ac8d32018-11-01 17:03:22 -0700216 auto method = bus.new_method_call(
217 elem.second.begin()->first.c_str(), elem.first.c_str(),
218 "org.freedesktop.DBus.Properties", "Get");
Andrew Geisslera6e48922019-11-06 08:43:54 -0600219 method.append("xyz.openbmc_project.Association.Definitions");
220 method.append("Associations");
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500221 auto reply = bus.call(method);
222 if (reply.is_method_error())
223 {
Patrick Venture91ac8d32018-11-01 17:03:22 -0700224 // do not stop, continue with next elog
George Liue9fb5c62021-07-01 14:05:32 +0800225 lg2::error("Error in getting associations");
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500226 continue;
227 }
228
Patrick Williamsa41d2822020-05-13 17:57:23 -0500229 std::variant<AssociationList> assoc;
William A. Kennington III151122a2018-05-15 12:00:32 -0700230 try
231 {
232 reply.read(assoc);
233 }
Patrick Williams3e073ba2022-07-22 19:26:52 -0500234 catch (const sdbusplus::exception_t& e)
William A. Kennington III151122a2018-05-15 12:00:32 -0700235 {
George Liue9fb5c62021-07-01 14:05:32 +0800236 lg2::error(
237 "Failed to parse existing callouts associations message, ERROR = {ERROR}",
238 "ERROR", e);
William A. Kennington III151122a2018-05-15 12:00:32 -0700239 continue;
240 }
Patrick Williams5ebebef2020-05-13 11:47:27 -0500241 auto& assocs = std::get<AssociationList>(assoc);
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500242
243 for (const auto& item : assocs)
244 {
245 if (std::get<1>(item).compare(CALLOUT_REV_ASSOCIATION) == 0)
246 {
247 removeWatches.emplace_back(
248 std::make_unique<Remove>(bus, std::get<2>(item)));
249 action(bus, std::get<2>(item), true);
250 }
251 }
252 }
253}
254
Patrick Williams3e073ba2022-07-22 19:26:52 -0500255void Remove::removed(sdbusplus::message_t& msg)
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500256{
Patrick Williams3eedbe42017-05-31 17:27:05 -0500257 auto bus = msg.get_bus();
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500258
Patrick Williams3eedbe42017-05-31 17:27:05 -0500259 action(bus, inventoryPath, false);
260 return;
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500261}
262
Patrick Venture91ac8d32018-11-01 17:03:22 -0700263} // namespace monitor
264} // namespace fault
265} // namespace fru
266} // namespace led
267} // namespace phosphor