xref: /openbmc/phosphor-led-manager/fault-monitor/fru-fault-monitor.cpp (revision e9fb5c6a1728a2f8a6ec69f4150d527502fb5510)
191ac8d3aSPatrick Venture #include "fru-fault-monitor.hpp"
291ac8d3aSPatrick Venture 
391ac8d3aSPatrick Venture #include "elog-errors.hpp"
491ac8d3aSPatrick Venture 
591ac8d3aSPatrick Venture #include <phosphor-logging/elog.hpp>
6*e9fb5c6aSGeorge Liu #include <phosphor-logging/lg2.hpp>
791ac8d3aSPatrick Venture #include <sdbusplus/exception.hpp>
84b062010SGeorge Liu #include <xyz/openbmc_project/Led/Fru/Monitor/error.hpp>
94b062010SGeorge Liu #include <xyz/openbmc_project/Led/Mapper/error.hpp>
103c6f29a0SDhruvaraj Subhashchandran 
1159b86cd7SDhruvaraj Subhashchandran namespace phosphor
1259b86cd7SDhruvaraj Subhashchandran {
1359b86cd7SDhruvaraj Subhashchandran namespace led
1459b86cd7SDhruvaraj Subhashchandran {
1559b86cd7SDhruvaraj Subhashchandran namespace fru
1659b86cd7SDhruvaraj Subhashchandran {
1759b86cd7SDhruvaraj Subhashchandran namespace fault
1859b86cd7SDhruvaraj Subhashchandran {
1959b86cd7SDhruvaraj Subhashchandran namespace monitor
2059b86cd7SDhruvaraj Subhashchandran {
2159b86cd7SDhruvaraj Subhashchandran 
223c6f29a0SDhruvaraj Subhashchandran using namespace phosphor::logging;
233c6f29a0SDhruvaraj Subhashchandran 
243c6f29a0SDhruvaraj Subhashchandran constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
253c6f29a0SDhruvaraj Subhashchandran constexpr auto MAPPER_OBJ_PATH = "/xyz/openbmc_project/object_mapper";
263c6f29a0SDhruvaraj Subhashchandran constexpr auto MAPPER_IFACE = "xyz.openbmc_project.ObjectMapper";
273c6f29a0SDhruvaraj Subhashchandran constexpr auto OBJMGR_IFACE = "org.freedesktop.DBus.ObjectManager";
283c6f29a0SDhruvaraj Subhashchandran constexpr auto LED_GROUPS = "/xyz/openbmc_project/led/groups/";
293c6f29a0SDhruvaraj Subhashchandran constexpr auto LOG_PATH = "/xyz/openbmc_project/logging";
30891c4769SDhruvaraj Subhashchandran constexpr auto LOG_IFACE = "xyz.openbmc_project.Logging.Entry";
313c6f29a0SDhruvaraj Subhashchandran 
3291ac8d3aSPatrick Venture using AssociationList =
3391ac8d3aSPatrick Venture     std::vector<std::tuple<std::string, std::string, std::string>>;
34a41d282aSPatrick Williams using Attributes = std::variant<bool, AssociationList>;
35aebfde81SDhruvaraj Subhashchandran using PropertyName = std::string;
36b2f253b7SMatt Spinler using PropertyMap = std::map<PropertyName, Attributes>;
37b2f253b7SMatt Spinler using InterfaceName = std::string;
38b2f253b7SMatt Spinler using InterfaceMap = std::map<InterfaceName, PropertyMap>;
39aebfde81SDhruvaraj Subhashchandran 
40891c4769SDhruvaraj Subhashchandran using Service = std::string;
41891c4769SDhruvaraj Subhashchandran using Path = std::string;
42891c4769SDhruvaraj Subhashchandran using Interface = std::string;
43891c4769SDhruvaraj Subhashchandran using Interfaces = std::vector<Interface>;
44891c4769SDhruvaraj Subhashchandran using MapperResponseType = std::map<Path, std::map<Service, Interfaces>>;
45891c4769SDhruvaraj Subhashchandran 
463c6f29a0SDhruvaraj Subhashchandran using MethodErr =
473c6f29a0SDhruvaraj Subhashchandran     sdbusplus::xyz::openbmc_project::Led::Mapper::Error::MethodError;
483c6f29a0SDhruvaraj Subhashchandran using ObjectNotFoundErr =
493c6f29a0SDhruvaraj Subhashchandran     sdbusplus::xyz::openbmc_project::Led::Mapper::Error::ObjectNotFoundError;
5091ac8d3aSPatrick Venture using InventoryPathErr = sdbusplus::xyz::openbmc_project::Led::Fru::Monitor::
5191ac8d3aSPatrick Venture     Error::InventoryPathError;
523c6f29a0SDhruvaraj Subhashchandran 
5391ac8d3aSPatrick Venture std::string getService(sdbusplus::bus::bus& bus, const std::string& path)
543c6f29a0SDhruvaraj Subhashchandran {
5591ac8d3aSPatrick Venture     auto mapper = bus.new_method_call(MAPPER_BUSNAME, MAPPER_OBJ_PATH,
563c6f29a0SDhruvaraj Subhashchandran                                       MAPPER_IFACE, "GetObject");
573c6f29a0SDhruvaraj Subhashchandran     mapper.append(path.c_str(), std::vector<std::string>({OBJMGR_IFACE}));
583c6f29a0SDhruvaraj Subhashchandran 
593c6f29a0SDhruvaraj Subhashchandran     std::map<std::string, std::vector<std::string>> mapperResponse;
60151122aaSWilliam A. Kennington III     try
61151122aaSWilliam A. Kennington III     {
62d78de14dSGeorge Liu         auto mapperResponseMsg = bus.call(mapper);
633c6f29a0SDhruvaraj Subhashchandran         mapperResponseMsg.read(mapperResponse);
64151122aaSWilliam A. Kennington III     }
657152edcfSPatrick Williams     catch (const sdbusplus::exception::exception& e)
66151122aaSWilliam A. Kennington III     {
67*e9fb5c6aSGeorge Liu         lg2::error(
68*e9fb5c6aSGeorge Liu             "Failed to parse getService mapper response, ERROR = {ERROR}",
69*e9fb5c6aSGeorge Liu             "ERROR", e);
70151122aaSWilliam A. Kennington III         using namespace xyz::openbmc_project::Led::Mapper;
7191ac8d3aSPatrick Venture         elog<ObjectNotFoundErr>(ObjectNotFoundError::METHOD_NAME("GetObject"),
72151122aaSWilliam A. Kennington III                                 ObjectNotFoundError::PATH(path.c_str()),
7391ac8d3aSPatrick Venture                                 ObjectNotFoundError::INTERFACE(OBJMGR_IFACE));
74151122aaSWilliam A. Kennington III     }
753c6f29a0SDhruvaraj Subhashchandran     if (mapperResponse.empty())
763c6f29a0SDhruvaraj Subhashchandran     {
773c6f29a0SDhruvaraj Subhashchandran         using namespace xyz::openbmc_project::Led::Mapper;
7891ac8d3aSPatrick Venture         elog<ObjectNotFoundErr>(ObjectNotFoundError::METHOD_NAME("GetObject"),
793c6f29a0SDhruvaraj Subhashchandran                                 ObjectNotFoundError::PATH(path.c_str()),
8091ac8d3aSPatrick Venture                                 ObjectNotFoundError::INTERFACE(OBJMGR_IFACE));
813c6f29a0SDhruvaraj Subhashchandran     }
823c6f29a0SDhruvaraj Subhashchandran 
833c6f29a0SDhruvaraj Subhashchandran     return mapperResponse.cbegin()->first;
843c6f29a0SDhruvaraj Subhashchandran }
853c6f29a0SDhruvaraj Subhashchandran 
8691ac8d3aSPatrick Venture void action(sdbusplus::bus::bus& bus, const std::string& path, bool assert)
8759b86cd7SDhruvaraj Subhashchandran {
883c6f29a0SDhruvaraj Subhashchandran     std::string service;
893c6f29a0SDhruvaraj Subhashchandran     try
903c6f29a0SDhruvaraj Subhashchandran     {
91e77b8345SMatt Spinler         std::string groups{LED_GROUPS};
92e77b8345SMatt Spinler         groups.pop_back();
93e77b8345SMatt Spinler         service = getService(bus, groups);
943c6f29a0SDhruvaraj Subhashchandran     }
953c6f29a0SDhruvaraj Subhashchandran     catch (MethodErr& e)
963c6f29a0SDhruvaraj Subhashchandran     {
973c6f29a0SDhruvaraj Subhashchandran         commit<MethodErr>();
983c6f29a0SDhruvaraj Subhashchandran         return;
993c6f29a0SDhruvaraj Subhashchandran     }
1003c6f29a0SDhruvaraj Subhashchandran     catch (ObjectNotFoundErr& e)
1013c6f29a0SDhruvaraj Subhashchandran     {
1023c6f29a0SDhruvaraj Subhashchandran         commit<ObjectNotFoundErr>();
1033c6f29a0SDhruvaraj Subhashchandran         return;
1043c6f29a0SDhruvaraj Subhashchandran     }
1053c6f29a0SDhruvaraj Subhashchandran 
1063c6f29a0SDhruvaraj Subhashchandran     auto pos = path.rfind("/");
1073c6f29a0SDhruvaraj Subhashchandran     if (pos == std::string::npos)
1083c6f29a0SDhruvaraj Subhashchandran     {
1093c6f29a0SDhruvaraj Subhashchandran         using namespace xyz::openbmc_project::Led::Fru::Monitor;
11091ac8d3aSPatrick Venture         report<InventoryPathErr>(InventoryPathError::PATH(path.c_str()));
1113c6f29a0SDhruvaraj Subhashchandran         return;
1123c6f29a0SDhruvaraj Subhashchandran     }
1133c6f29a0SDhruvaraj Subhashchandran     auto unit = path.substr(pos + 1);
1143c6f29a0SDhruvaraj Subhashchandran 
11591ac8d3aSPatrick Venture     std::string ledPath = LED_GROUPS + unit + '_' + LED_FAULT;
1163c6f29a0SDhruvaraj Subhashchandran 
11791ac8d3aSPatrick Venture     auto method = bus.new_method_call(service.c_str(), ledPath.c_str(),
11891ac8d3aSPatrick Venture                                       "org.freedesktop.DBus.Properties", "Set");
1193c6f29a0SDhruvaraj Subhashchandran     method.append("xyz.openbmc_project.Led.Group");
1203c6f29a0SDhruvaraj Subhashchandran     method.append("Asserted");
1213c6f29a0SDhruvaraj Subhashchandran 
122a41d282aSPatrick Williams     method.append(std::variant<bool>(assert));
12308d613e7SAdriana Kobylak 
12408d613e7SAdriana Kobylak     try
12508d613e7SAdriana Kobylak     {
1263c6f29a0SDhruvaraj Subhashchandran         bus.call_noreply(method);
12708d613e7SAdriana Kobylak     }
1287152edcfSPatrick Williams     catch (const sdbusplus::exception::exception& e)
12908d613e7SAdriana Kobylak     {
13008d613e7SAdriana Kobylak         // Log an info message, system may not have all the LED Groups defined
131*e9fb5c6aSGeorge Liu         lg2::info("Failed to Assert LED Group, ERROR = {ERROR}", "ERROR", e);
13208d613e7SAdriana Kobylak     }
1333c6f29a0SDhruvaraj Subhashchandran 
13459b86cd7SDhruvaraj Subhashchandran     return;
13559b86cd7SDhruvaraj Subhashchandran }
13659b86cd7SDhruvaraj Subhashchandran 
1373eedbe44SPatrick Williams void Add::created(sdbusplus::message::message& msg)
13859b86cd7SDhruvaraj Subhashchandran {
1393eedbe44SPatrick Williams     auto bus = msg.get_bus();
1403c6f29a0SDhruvaraj Subhashchandran 
141b2f253b7SMatt Spinler     sdbusplus::message::object_path objectPath;
142b2f253b7SMatt Spinler     InterfaceMap interfaces;
143151122aaSWilliam A. Kennington III     try
144151122aaSWilliam A. Kennington III     {
145b2f253b7SMatt Spinler         msg.read(objectPath, interfaces);
146151122aaSWilliam A. Kennington III     }
1477152edcfSPatrick Williams     catch (const sdbusplus::exception::exception& e)
148151122aaSWilliam A. Kennington III     {
149*e9fb5c6aSGeorge Liu         lg2::error("Failed to parse created message, ERROR = {ERROR}", "ERROR",
150*e9fb5c6aSGeorge Liu                    e);
151151122aaSWilliam A. Kennington III         return;
152151122aaSWilliam A. Kennington III     }
1533c6f29a0SDhruvaraj Subhashchandran 
154b2f253b7SMatt Spinler     std::size_t found = objectPath.str.find(ELOG_ENTRY);
1553c6f29a0SDhruvaraj Subhashchandran     if (found == std::string::npos)
1563c6f29a0SDhruvaraj Subhashchandran     {
1573c6f29a0SDhruvaraj Subhashchandran         // Not a new error entry skip
1583eedbe44SPatrick Williams         return;
1593c6f29a0SDhruvaraj Subhashchandran     }
160a6e48929SAndrew Geissler     auto iter = interfaces.find("xyz.openbmc_project.Association.Definitions");
161b2f253b7SMatt Spinler     if (iter == interfaces.end())
1623c6f29a0SDhruvaraj Subhashchandran     {
1633eedbe44SPatrick Williams         return;
1643c6f29a0SDhruvaraj Subhashchandran     }
1653c6f29a0SDhruvaraj Subhashchandran 
1663d2b0d62SMatt Spinler     // Nothing else shows when a specific error log
1673d2b0d62SMatt Spinler     // has been created. Do it here.
168*e9fb5c6aSGeorge Liu     // TODO:(phosphor-logging#25): support sdbusplus::message::object_path
169*e9fb5c6aSGeorge Liu     // directly.
170*e9fb5c6aSGeorge Liu     lg2::info("{PATH} created", "PATH", objectPath.str);
1713d2b0d62SMatt Spinler 
172a6e48929SAndrew Geissler     auto attr = iter->second.find("Associations");
173aebfde81SDhruvaraj Subhashchandran     if (attr == iter->second.end())
1743c6f29a0SDhruvaraj Subhashchandran     {
1753eedbe44SPatrick Williams         return;
1763c6f29a0SDhruvaraj Subhashchandran     }
1773c6f29a0SDhruvaraj Subhashchandran 
1785ebebeffSPatrick Williams     auto& assocs = std::get<AssociationList>(attr->second);
1793c6f29a0SDhruvaraj Subhashchandran     if (assocs.empty())
1803c6f29a0SDhruvaraj Subhashchandran     {
1813c6f29a0SDhruvaraj Subhashchandran         // No associations skip
1823eedbe44SPatrick Williams         return;
1833c6f29a0SDhruvaraj Subhashchandran     }
1843c6f29a0SDhruvaraj Subhashchandran 
1853c6f29a0SDhruvaraj Subhashchandran     for (const auto& item : assocs)
1863c6f29a0SDhruvaraj Subhashchandran     {
1873c6f29a0SDhruvaraj Subhashchandran         if (std::get<1>(item).compare(CALLOUT_REV_ASSOCIATION) == 0)
1883c6f29a0SDhruvaraj Subhashchandran         {
1893eedbe44SPatrick Williams             removeWatches.emplace_back(
1903c6f29a0SDhruvaraj Subhashchandran                 std::make_unique<Remove>(bus, std::get<2>(item)));
191891c4769SDhruvaraj Subhashchandran             action(bus, std::get<2>(item), true);
1923c6f29a0SDhruvaraj Subhashchandran         }
1933c6f29a0SDhruvaraj Subhashchandran     }
194aebfde81SDhruvaraj Subhashchandran 
1953eedbe44SPatrick Williams     return;
19659b86cd7SDhruvaraj Subhashchandran }
19759b86cd7SDhruvaraj Subhashchandran 
19891122927SMatt Spinler void getLoggingSubTree(sdbusplus::bus::bus& bus, MapperResponseType& subtree)
199891c4769SDhruvaraj Subhashchandran {
200891c4769SDhruvaraj Subhashchandran     auto depth = 0;
20191ac8d3aSPatrick Venture     auto mapperCall = bus.new_method_call(MAPPER_BUSNAME, MAPPER_OBJ_PATH,
20291ac8d3aSPatrick Venture                                           MAPPER_IFACE, "GetSubTree");
203891c4769SDhruvaraj Subhashchandran     mapperCall.append("/");
204891c4769SDhruvaraj Subhashchandran     mapperCall.append(depth);
205891c4769SDhruvaraj Subhashchandran     mapperCall.append(std::vector<Interface>({LOG_IFACE}));
206891c4769SDhruvaraj Subhashchandran 
20791122927SMatt Spinler     try
20891122927SMatt Spinler     {
209891c4769SDhruvaraj Subhashchandran         auto mapperResponseMsg = bus.call(mapperCall);
21091122927SMatt Spinler         mapperResponseMsg.read(subtree);
211151122aaSWilliam A. Kennington III     }
2127152edcfSPatrick Williams     catch (const sdbusplus::exception::exception& e)
213151122aaSWilliam A. Kennington III     {
214*e9fb5c6aSGeorge Liu         lg2::error(
215*e9fb5c6aSGeorge Liu             "Failed to parse existing callouts subtree message, ERROR = {ERROR}",
216*e9fb5c6aSGeorge Liu             "ERROR", e);
21791122927SMatt Spinler     }
21891122927SMatt Spinler }
21991122927SMatt Spinler 
22091122927SMatt Spinler void Add::processExistingCallouts(sdbusplus::bus::bus& bus)
22191122927SMatt Spinler {
22291122927SMatt Spinler     MapperResponseType mapperResponse;
22391122927SMatt Spinler 
22491122927SMatt Spinler     getLoggingSubTree(bus, mapperResponse);
225891c4769SDhruvaraj Subhashchandran     if (mapperResponse.empty())
226891c4769SDhruvaraj Subhashchandran     {
227fc30e0c1SDhruvaraj Subhashchandran         // No errors to process.
228891c4769SDhruvaraj Subhashchandran         return;
229891c4769SDhruvaraj Subhashchandran     }
230891c4769SDhruvaraj Subhashchandran 
231891c4769SDhruvaraj Subhashchandran     for (const auto& elem : mapperResponse)
232891c4769SDhruvaraj Subhashchandran     {
23391ac8d3aSPatrick Venture         auto method = bus.new_method_call(
23491ac8d3aSPatrick Venture             elem.second.begin()->first.c_str(), elem.first.c_str(),
23591ac8d3aSPatrick Venture             "org.freedesktop.DBus.Properties", "Get");
236a6e48929SAndrew Geissler         method.append("xyz.openbmc_project.Association.Definitions");
237a6e48929SAndrew Geissler         method.append("Associations");
238891c4769SDhruvaraj Subhashchandran         auto reply = bus.call(method);
239891c4769SDhruvaraj Subhashchandran         if (reply.is_method_error())
240891c4769SDhruvaraj Subhashchandran         {
241891c4769SDhruvaraj Subhashchandran             // do not stop, continue with next elog
242*e9fb5c6aSGeorge Liu             lg2::error("Error in getting associations");
243891c4769SDhruvaraj Subhashchandran             continue;
244891c4769SDhruvaraj Subhashchandran         }
245891c4769SDhruvaraj Subhashchandran 
246a41d282aSPatrick Williams         std::variant<AssociationList> assoc;
247151122aaSWilliam A. Kennington III         try
248151122aaSWilliam A. Kennington III         {
249891c4769SDhruvaraj Subhashchandran             reply.read(assoc);
250151122aaSWilliam A. Kennington III         }
2517152edcfSPatrick Williams         catch (const sdbusplus::exception::exception& e)
252151122aaSWilliam A. Kennington III         {
253*e9fb5c6aSGeorge Liu             lg2::error(
254*e9fb5c6aSGeorge Liu                 "Failed to parse existing callouts associations message, ERROR = {ERROR}",
255*e9fb5c6aSGeorge Liu                 "ERROR", e);
256151122aaSWilliam A. Kennington III             continue;
257151122aaSWilliam A. Kennington III         }
2585ebebeffSPatrick Williams         auto& assocs = std::get<AssociationList>(assoc);
259891c4769SDhruvaraj Subhashchandran         if (assocs.empty())
260891c4769SDhruvaraj Subhashchandran         {
261891c4769SDhruvaraj Subhashchandran             // no associations, skip
262891c4769SDhruvaraj Subhashchandran             continue;
263891c4769SDhruvaraj Subhashchandran         }
264891c4769SDhruvaraj Subhashchandran 
265891c4769SDhruvaraj Subhashchandran         for (const auto& item : assocs)
266891c4769SDhruvaraj Subhashchandran         {
267891c4769SDhruvaraj Subhashchandran             if (std::get<1>(item).compare(CALLOUT_REV_ASSOCIATION) == 0)
268891c4769SDhruvaraj Subhashchandran             {
269891c4769SDhruvaraj Subhashchandran                 removeWatches.emplace_back(
270891c4769SDhruvaraj Subhashchandran                     std::make_unique<Remove>(bus, std::get<2>(item)));
271891c4769SDhruvaraj Subhashchandran                 action(bus, std::get<2>(item), true);
272891c4769SDhruvaraj Subhashchandran             }
273891c4769SDhruvaraj Subhashchandran         }
274891c4769SDhruvaraj Subhashchandran     }
275891c4769SDhruvaraj Subhashchandran }
276891c4769SDhruvaraj Subhashchandran 
2773eedbe44SPatrick Williams void Remove::removed(sdbusplus::message::message& msg)
27859b86cd7SDhruvaraj Subhashchandran {
2793eedbe44SPatrick Williams     auto bus = msg.get_bus();
2803c6f29a0SDhruvaraj Subhashchandran 
2813eedbe44SPatrick Williams     action(bus, inventoryPath, false);
2823eedbe44SPatrick Williams     return;
28359b86cd7SDhruvaraj Subhashchandran }
28459b86cd7SDhruvaraj Subhashchandran 
28559b86cd7SDhruvaraj Subhashchandran } // namespace monitor
28659b86cd7SDhruvaraj Subhashchandran } // namespace fault
28759b86cd7SDhruvaraj Subhashchandran } // namespace fru
28859b86cd7SDhruvaraj Subhashchandran } // namespace led
28959b86cd7SDhruvaraj Subhashchandran } // namespace phosphor
290