blob: a390cbe2200f0efd4deec04427cee5877c038958 [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
Patrick Venture91ac8d32018-11-01 17:03:22 -070022constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
23constexpr auto MAPPER_OBJ_PATH = "/xyz/openbmc_project/object_mapper";
24constexpr auto MAPPER_IFACE = "xyz.openbmc_project.ObjectMapper";
25constexpr auto OBJMGR_IFACE = "org.freedesktop.DBus.ObjectManager";
26constexpr auto LED_GROUPS = "/xyz/openbmc_project/led/groups/";
27constexpr auto LOG_PATH = "/xyz/openbmc_project/logging";
28constexpr auto LOG_IFACE = "xyz.openbmc_project.Logging.Entry";
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050029
Patrick Venture91ac8d32018-11-01 17:03:22 -070030using AssociationList =
31 std::vector<std::tuple<std::string, std::string, std::string>>;
Patrick Williamsa41d2822020-05-13 17:57:23 -050032using Attributes = std::variant<bool, AssociationList>;
Dhruvaraj Subhashchandranaebfde82017-07-11 01:36:33 -050033using PropertyName = std::string;
Matt Spinlerb2f253b2018-06-13 09:54:13 -050034using PropertyMap = std::map<PropertyName, Attributes>;
35using InterfaceName = std::string;
36using InterfaceMap = std::map<InterfaceName, PropertyMap>;
Dhruvaraj Subhashchandranaebfde82017-07-11 01:36:33 -050037
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -050038using Service = std::string;
39using Path = std::string;
40using Interface = std::string;
41using Interfaces = std::vector<Interface>;
42using MapperResponseType = std::map<Path, std::map<Service, Interfaces>>;
43
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 Venture91ac8d32018-11-01 17:03:22 -070049std::string getService(sdbusplus::bus::bus& bus, const std::string& path)
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050050{
Patrick Venture91ac8d32018-11-01 17:03:22 -070051 auto mapper = bus.new_method_call(MAPPER_BUSNAME, MAPPER_OBJ_PATH,
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050052 MAPPER_IFACE, "GetObject");
53 mapper.append(path.c_str(), std::vector<std::string>({OBJMGR_IFACE}));
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050054
55 std::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 Williams7152edc2021-09-02 09:41:54 -050061 catch (const sdbusplus::exception::exception& 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 Venture91ac8d32018-11-01 17:03:22 -070079void action(sdbusplus::bus::bus& 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 {
Matt Spinlere77b8342018-09-12 10:41:53 -050084 std::string groups{LED_GROUPS};
85 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
94 auto pos = path.rfind("/");
95 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
Patrick Venture91ac8d32018-11-01 17:03:22 -0700105 std::string ledPath = LED_GROUPS + 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 Williams7152edc2021-09-02 09:41:54 -0500118 catch (const sdbusplus::exception::exception& 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 Williams3eedbe42017-05-31 17:27:05 -0500127void Add::created(sdbusplus::message::message& 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 Williams7152edc2021-09-02 09:41:54 -0500137 catch (const sdbusplus::exception::exception& 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 Liue9fb5c62021-07-01 14:05:32 +0800158 // TODO:(phosphor-logging#25): support sdbusplus::message::object_path
159 // directly.
160 lg2::info("{PATH} created", "PATH", objectPath.str);
Matt Spinler3d2b0d62018-03-29 08:48:37 -0500161
Andrew Geisslera6e48922019-11-06 08:43:54 -0600162 auto attr = iter->second.find("Associations");
Dhruvaraj Subhashchandranaebfde82017-07-11 01:36:33 -0500163 if (attr == iter->second.end())
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500164 {
Patrick Williams3eedbe42017-05-31 17:27:05 -0500165 return;
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500166 }
167
Patrick Williams5ebebef2020-05-13 11:47:27 -0500168 auto& assocs = std::get<AssociationList>(attr->second);
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500169 if (assocs.empty())
170 {
Patrick Venture91ac8d32018-11-01 17:03:22 -0700171 // No associations skip
Patrick Williams3eedbe42017-05-31 17:27:05 -0500172 return;
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500173 }
174
175 for (const auto& item : assocs)
176 {
177 if (std::get<1>(item).compare(CALLOUT_REV_ASSOCIATION) == 0)
178 {
Patrick Williams3eedbe42017-05-31 17:27:05 -0500179 removeWatches.emplace_back(
Dhruvaraj Subhashchandranaebfde82017-07-11 01:36:33 -0500180 std::make_unique<Remove>(bus, std::get<2>(item)));
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500181 action(bus, std::get<2>(item), true);
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500182 }
183 }
Dhruvaraj Subhashchandranaebfde82017-07-11 01:36:33 -0500184
Patrick Williams3eedbe42017-05-31 17:27:05 -0500185 return;
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500186}
187
Matt Spinler91122922018-09-24 11:31:44 -0500188void getLoggingSubTree(sdbusplus::bus::bus& bus, MapperResponseType& subtree)
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500189{
190 auto depth = 0;
Patrick Venture91ac8d32018-11-01 17:03:22 -0700191 auto mapperCall = bus.new_method_call(MAPPER_BUSNAME, MAPPER_OBJ_PATH,
192 MAPPER_IFACE, "GetSubTree");
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500193 mapperCall.append("/");
194 mapperCall.append(depth);
195 mapperCall.append(std::vector<Interface>({LOG_IFACE}));
196
William A. Kennington III151122a2018-05-15 12:00:32 -0700197 try
198 {
Matt Spinler91122922018-09-24 11:31:44 -0500199 auto mapperResponseMsg = bus.call(mapperCall);
George Liud78de142021-08-23 16:16:32 +0800200 mapperResponseMsg.read(subtree);
William A. Kennington III151122a2018-05-15 12:00:32 -0700201 }
Patrick Williams7152edc2021-09-02 09:41:54 -0500202 catch (const sdbusplus::exception::exception& e)
William A. Kennington III151122a2018-05-15 12:00:32 -0700203 {
George Liue9fb5c62021-07-01 14:05:32 +0800204 lg2::error(
205 "Failed to parse existing callouts subtree message, ERROR = {ERROR}",
206 "ERROR", e);
William A. Kennington III151122a2018-05-15 12:00:32 -0700207 }
Matt Spinler91122922018-09-24 11:31:44 -0500208}
209
210void Add::processExistingCallouts(sdbusplus::bus::bus& bus)
211{
Patrick Venture91ac8d32018-11-01 17:03:22 -0700212 MapperResponseType mapperResponse;
Matt Spinler91122922018-09-24 11:31:44 -0500213
214 getLoggingSubTree(bus, mapperResponse);
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500215 if (mapperResponse.empty())
216 {
Patrick Venture91ac8d32018-11-01 17:03:22 -0700217 // No errors to process.
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500218 return;
219 }
220
221 for (const auto& elem : mapperResponse)
222 {
Patrick Venture91ac8d32018-11-01 17:03:22 -0700223 auto method = bus.new_method_call(
224 elem.second.begin()->first.c_str(), elem.first.c_str(),
225 "org.freedesktop.DBus.Properties", "Get");
Andrew Geisslera6e48922019-11-06 08:43:54 -0600226 method.append("xyz.openbmc_project.Association.Definitions");
227 method.append("Associations");
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500228 auto reply = bus.call(method);
229 if (reply.is_method_error())
230 {
Patrick Venture91ac8d32018-11-01 17:03:22 -0700231 // do not stop, continue with next elog
George Liue9fb5c62021-07-01 14:05:32 +0800232 lg2::error("Error in getting associations");
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500233 continue;
234 }
235
Patrick Williamsa41d2822020-05-13 17:57:23 -0500236 std::variant<AssociationList> assoc;
William A. Kennington III151122a2018-05-15 12:00:32 -0700237 try
238 {
239 reply.read(assoc);
240 }
Patrick Williams7152edc2021-09-02 09:41:54 -0500241 catch (const sdbusplus::exception::exception& e)
William A. Kennington III151122a2018-05-15 12:00:32 -0700242 {
George Liue9fb5c62021-07-01 14:05:32 +0800243 lg2::error(
244 "Failed to parse existing callouts associations message, ERROR = {ERROR}",
245 "ERROR", e);
William A. Kennington III151122a2018-05-15 12:00:32 -0700246 continue;
247 }
Patrick Williams5ebebef2020-05-13 11:47:27 -0500248 auto& assocs = std::get<AssociationList>(assoc);
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500249 if (assocs.empty())
250 {
Patrick Venture91ac8d32018-11-01 17:03:22 -0700251 // no associations, skip
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500252 continue;
253 }
254
255 for (const auto& item : assocs)
256 {
257 if (std::get<1>(item).compare(CALLOUT_REV_ASSOCIATION) == 0)
258 {
259 removeWatches.emplace_back(
260 std::make_unique<Remove>(bus, std::get<2>(item)));
261 action(bus, std::get<2>(item), true);
262 }
263 }
264 }
265}
266
Patrick Williams3eedbe42017-05-31 17:27:05 -0500267void Remove::removed(sdbusplus::message::message& msg)
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500268{
Patrick Williams3eedbe42017-05-31 17:27:05 -0500269 auto bus = msg.get_bus();
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500270
Patrick Williams3eedbe42017-05-31 17:27:05 -0500271 action(bus, inventoryPath, false);
272 return;
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500273}
274
Patrick Venture91ac8d32018-11-01 17:03:22 -0700275} // namespace monitor
276} // namespace fault
277} // namespace fru
278} // namespace led
279} // namespace phosphor