xref: /openbmc/phosphor-led-manager/fault-monitor/fru-fault-monitor.cpp (revision 3d2b0d62ed1567ffba53ffb44d0a8617869ea08c)
13c6f29a0SDhruvaraj Subhashchandran #include <phosphor-logging/elog.hpp>
23c6f29a0SDhruvaraj Subhashchandran #include "xyz/openbmc_project/Led/Fru/Monitor/error.hpp"
33c6f29a0SDhruvaraj Subhashchandran #include "xyz/openbmc_project/Led/Mapper/error.hpp"
43c6f29a0SDhruvaraj Subhashchandran #include "elog-errors.hpp"
559b86cd7SDhruvaraj Subhashchandran #include "fru-fault-monitor.hpp"
6891c4769SDhruvaraj Subhashchandran #include <phosphor-logging/elog-errors.hpp>
7891c4769SDhruvaraj Subhashchandran #include "xyz/openbmc_project/Common/error.hpp"
83c6f29a0SDhruvaraj Subhashchandran 
959b86cd7SDhruvaraj Subhashchandran namespace phosphor
1059b86cd7SDhruvaraj Subhashchandran {
1159b86cd7SDhruvaraj Subhashchandran namespace led
1259b86cd7SDhruvaraj Subhashchandran {
1359b86cd7SDhruvaraj Subhashchandran namespace fru
1459b86cd7SDhruvaraj Subhashchandran {
1559b86cd7SDhruvaraj Subhashchandran namespace fault
1659b86cd7SDhruvaraj Subhashchandran {
1759b86cd7SDhruvaraj Subhashchandran namespace monitor
1859b86cd7SDhruvaraj Subhashchandran {
1959b86cd7SDhruvaraj Subhashchandran 
203c6f29a0SDhruvaraj Subhashchandran using namespace phosphor::logging;
213c6f29a0SDhruvaraj Subhashchandran 
223c6f29a0SDhruvaraj Subhashchandran constexpr auto MAPPER_BUSNAME   = "xyz.openbmc_project.ObjectMapper";
233c6f29a0SDhruvaraj Subhashchandran constexpr auto MAPPER_OBJ_PATH  = "/xyz/openbmc_project/object_mapper";
243c6f29a0SDhruvaraj Subhashchandran constexpr auto MAPPER_IFACE     = "xyz.openbmc_project.ObjectMapper";
253c6f29a0SDhruvaraj Subhashchandran constexpr auto OBJMGR_IFACE     = "org.freedesktop.DBus.ObjectManager";
263c6f29a0SDhruvaraj Subhashchandran constexpr auto LED_GROUPS       = "/xyz/openbmc_project/led/groups/";
273c6f29a0SDhruvaraj Subhashchandran constexpr auto LOG_PATH         = "/xyz/openbmc_project/logging";
28891c4769SDhruvaraj Subhashchandran constexpr auto LOG_IFACE        = "xyz.openbmc_project.Logging.Entry";
293c6f29a0SDhruvaraj Subhashchandran 
303c6f29a0SDhruvaraj Subhashchandran using AssociationList = std::vector<std::tuple<
313c6f29a0SDhruvaraj Subhashchandran                         std::string, std::string, std::string>>;
32aebfde81SDhruvaraj Subhashchandran using Attributes = sdbusplus::message::variant<bool,AssociationList>;
33aebfde81SDhruvaraj Subhashchandran using AttributeName = std::string;
34aebfde81SDhruvaraj Subhashchandran using AttributeMap = std::map<AttributeName, Attributes>;
35aebfde81SDhruvaraj Subhashchandran using PropertyName = std::string;
36aebfde81SDhruvaraj Subhashchandran using PropertyMap = std::map<PropertyName, AttributeMap>;
37aebfde81SDhruvaraj Subhashchandran using LogEntryMsg = std::pair<sdbusplus::message::object_path, PropertyMap>;
38aebfde81SDhruvaraj Subhashchandran 
39891c4769SDhruvaraj Subhashchandran using Service = std::string;
40891c4769SDhruvaraj Subhashchandran using Path = std::string;
41891c4769SDhruvaraj Subhashchandran using Interface = std::string;
42891c4769SDhruvaraj Subhashchandran using Interfaces = std::vector<Interface>;
43891c4769SDhruvaraj Subhashchandran using MapperResponseType = std::map<Path, std::map<Service, Interfaces>>;
44891c4769SDhruvaraj Subhashchandran 
45891c4769SDhruvaraj Subhashchandran using InternalFailure =
46891c4769SDhruvaraj Subhashchandran     sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
47891c4769SDhruvaraj Subhashchandran 
483c6f29a0SDhruvaraj Subhashchandran using MethodErr  =
493c6f29a0SDhruvaraj Subhashchandran     sdbusplus::xyz::openbmc_project::Led::Mapper::Error::MethodError;
503c6f29a0SDhruvaraj Subhashchandran using ObjectNotFoundErr =
513c6f29a0SDhruvaraj Subhashchandran     sdbusplus::xyz::openbmc_project::Led::Mapper::Error::ObjectNotFoundError;
523c6f29a0SDhruvaraj Subhashchandran using InventoryPathErr =
533c6f29a0SDhruvaraj Subhashchandran     sdbusplus::xyz::openbmc_project::
543c6f29a0SDhruvaraj Subhashchandran     Led::Fru::Monitor::Error::InventoryPathError;
553c6f29a0SDhruvaraj Subhashchandran 
563c6f29a0SDhruvaraj Subhashchandran std::string getService(sdbusplus::bus::bus& bus,
573c6f29a0SDhruvaraj Subhashchandran                        const std::string& path)
583c6f29a0SDhruvaraj Subhashchandran {
593c6f29a0SDhruvaraj Subhashchandran     auto mapper = bus.new_method_call(MAPPER_BUSNAME,
603c6f29a0SDhruvaraj Subhashchandran                                       MAPPER_OBJ_PATH,
613c6f29a0SDhruvaraj Subhashchandran                                       MAPPER_IFACE, "GetObject");
623c6f29a0SDhruvaraj Subhashchandran     mapper.append(path.c_str(), std::vector<std::string>({OBJMGR_IFACE}));
633c6f29a0SDhruvaraj Subhashchandran     auto mapperResponseMsg = bus.call(mapper);
643c6f29a0SDhruvaraj Subhashchandran     if (mapperResponseMsg.is_method_error())
653c6f29a0SDhruvaraj Subhashchandran     {
663c6f29a0SDhruvaraj Subhashchandran         using namespace xyz::openbmc_project::Led::Mapper;
673c6f29a0SDhruvaraj Subhashchandran         elog<MethodErr>(
683c6f29a0SDhruvaraj Subhashchandran             MethodError::METHOD_NAME("GetObject"),
693c6f29a0SDhruvaraj Subhashchandran             MethodError::PATH(path.c_str()),
703c6f29a0SDhruvaraj Subhashchandran             MethodError::INTERFACE(
713c6f29a0SDhruvaraj Subhashchandran                 OBJMGR_IFACE));
723c6f29a0SDhruvaraj Subhashchandran     }
733c6f29a0SDhruvaraj Subhashchandran 
743c6f29a0SDhruvaraj Subhashchandran     std::map<std::string, std::vector<std::string>> mapperResponse;
753c6f29a0SDhruvaraj Subhashchandran     mapperResponseMsg.read(mapperResponse);
763c6f29a0SDhruvaraj Subhashchandran     if (mapperResponse.empty())
773c6f29a0SDhruvaraj Subhashchandran     {
783c6f29a0SDhruvaraj Subhashchandran         using namespace xyz::openbmc_project::Led::Mapper;
793c6f29a0SDhruvaraj Subhashchandran         elog<ObjectNotFoundErr>(
803c6f29a0SDhruvaraj Subhashchandran             ObjectNotFoundError::METHOD_NAME("GetObject"),
813c6f29a0SDhruvaraj Subhashchandran             ObjectNotFoundError::PATH(path.c_str()),
823c6f29a0SDhruvaraj Subhashchandran             ObjectNotFoundError::INTERFACE(
833c6f29a0SDhruvaraj Subhashchandran                 OBJMGR_IFACE));
843c6f29a0SDhruvaraj Subhashchandran     }
853c6f29a0SDhruvaraj Subhashchandran 
863c6f29a0SDhruvaraj Subhashchandran     return mapperResponse.cbegin()->first;
873c6f29a0SDhruvaraj Subhashchandran }
883c6f29a0SDhruvaraj Subhashchandran 
8959b86cd7SDhruvaraj Subhashchandran void action(sdbusplus::bus::bus& bus,
903c6f29a0SDhruvaraj Subhashchandran             const std::string& path,
9159b86cd7SDhruvaraj Subhashchandran             bool assert)
9259b86cd7SDhruvaraj Subhashchandran {
933c6f29a0SDhruvaraj Subhashchandran     std::string service;
943c6f29a0SDhruvaraj Subhashchandran     try
953c6f29a0SDhruvaraj Subhashchandran     {
963c6f29a0SDhruvaraj Subhashchandran         service = getService(bus, LED_GROUPS);
973c6f29a0SDhruvaraj Subhashchandran     }
983c6f29a0SDhruvaraj Subhashchandran     catch (MethodErr& e)
993c6f29a0SDhruvaraj Subhashchandran     {
1003c6f29a0SDhruvaraj Subhashchandran         commit<MethodErr>();
1013c6f29a0SDhruvaraj Subhashchandran         return;
1023c6f29a0SDhruvaraj Subhashchandran     }
1033c6f29a0SDhruvaraj Subhashchandran     catch (ObjectNotFoundErr& e)
1043c6f29a0SDhruvaraj Subhashchandran     {
1053c6f29a0SDhruvaraj Subhashchandran         commit<ObjectNotFoundErr>();
1063c6f29a0SDhruvaraj Subhashchandran         return;
1073c6f29a0SDhruvaraj Subhashchandran     }
1083c6f29a0SDhruvaraj Subhashchandran 
1093c6f29a0SDhruvaraj Subhashchandran     auto pos = path.rfind("/");
1103c6f29a0SDhruvaraj Subhashchandran     if (pos == std::string::npos)
1113c6f29a0SDhruvaraj Subhashchandran     {
1123c6f29a0SDhruvaraj Subhashchandran         using namespace xyz::openbmc_project::Led::Fru::Monitor;
1133c6f29a0SDhruvaraj Subhashchandran         report<InventoryPathErr>(
1143c6f29a0SDhruvaraj Subhashchandran             InventoryPathError::PATH(
1153c6f29a0SDhruvaraj Subhashchandran                 path.c_str()));
1163c6f29a0SDhruvaraj Subhashchandran         return;
1173c6f29a0SDhruvaraj Subhashchandran     }
1183c6f29a0SDhruvaraj Subhashchandran     auto unit = path.substr(pos + 1);
1193c6f29a0SDhruvaraj Subhashchandran 
1203c6f29a0SDhruvaraj Subhashchandran     std::string ledPath = LED_GROUPS +
1213c6f29a0SDhruvaraj Subhashchandran                           unit + '_' + LED_FAULT;
1223c6f29a0SDhruvaraj Subhashchandran 
1233c6f29a0SDhruvaraj Subhashchandran     auto method =  bus.new_method_call(service.c_str(),
1243c6f29a0SDhruvaraj Subhashchandran                                        ledPath.c_str(),
1253c6f29a0SDhruvaraj Subhashchandran                                        "org.freedesktop.DBus.Properties",
1263c6f29a0SDhruvaraj Subhashchandran                                        "Set");
1273c6f29a0SDhruvaraj Subhashchandran     method.append("xyz.openbmc_project.Led.Group");
1283c6f29a0SDhruvaraj Subhashchandran     method.append("Asserted");
1293c6f29a0SDhruvaraj Subhashchandran 
1303c6f29a0SDhruvaraj Subhashchandran     method.append(sdbusplus::message::variant<bool>(assert));
1313c6f29a0SDhruvaraj Subhashchandran     bus.call_noreply(method);
1323c6f29a0SDhruvaraj Subhashchandran 
13359b86cd7SDhruvaraj Subhashchandran     return;
13459b86cd7SDhruvaraj Subhashchandran }
13559b86cd7SDhruvaraj Subhashchandran 
1363eedbe44SPatrick Williams void Add::created(sdbusplus::message::message& msg)
13759b86cd7SDhruvaraj Subhashchandran {
1383eedbe44SPatrick Williams     auto bus = msg.get_bus();
1393c6f29a0SDhruvaraj Subhashchandran 
140aebfde81SDhruvaraj Subhashchandran     LogEntryMsg logEntry;
141aebfde81SDhruvaraj Subhashchandran     msg.read(logEntry);
142aebfde81SDhruvaraj Subhashchandran     std::string objectPath(std::move(logEntry.first));
1433c6f29a0SDhruvaraj Subhashchandran 
1443c6f29a0SDhruvaraj Subhashchandran     std::size_t found = objectPath.find(ELOG_ENTRY);
1453c6f29a0SDhruvaraj Subhashchandran     if (found == std::string::npos)
1463c6f29a0SDhruvaraj Subhashchandran     {
1473c6f29a0SDhruvaraj Subhashchandran         //Not a new error entry skip
1483eedbe44SPatrick Williams         return;
1493c6f29a0SDhruvaraj Subhashchandran     }
150aebfde81SDhruvaraj Subhashchandran     auto iter = logEntry.second.find("org.openbmc.Associations");
151aebfde81SDhruvaraj Subhashchandran     if (iter == logEntry.second.end())
1523c6f29a0SDhruvaraj Subhashchandran     {
1533eedbe44SPatrick Williams         return;
1543c6f29a0SDhruvaraj Subhashchandran     }
1553c6f29a0SDhruvaraj Subhashchandran 
156*3d2b0d62SMatt Spinler     //Nothing else shows when a specific error log
157*3d2b0d62SMatt Spinler     //has been created. Do it here.
158*3d2b0d62SMatt Spinler     std::string message{objectPath + " created"};
159*3d2b0d62SMatt Spinler     log<level::INFO>(message.c_str());
160*3d2b0d62SMatt Spinler 
161aebfde81SDhruvaraj Subhashchandran     auto attr = iter->second.find("associations");
162aebfde81SDhruvaraj Subhashchandran     if (attr == iter->second.end())
1633c6f29a0SDhruvaraj Subhashchandran     {
1643eedbe44SPatrick Williams         return;
1653c6f29a0SDhruvaraj Subhashchandran     }
1663c6f29a0SDhruvaraj Subhashchandran 
167aebfde81SDhruvaraj Subhashchandran     auto& assocs =
168aebfde81SDhruvaraj Subhashchandran         sdbusplus::message::variant_ns::get<AssociationList>(attr->second);
1693c6f29a0SDhruvaraj Subhashchandran     if (assocs.empty())
1703c6f29a0SDhruvaraj Subhashchandran     {
1713c6f29a0SDhruvaraj Subhashchandran         //No associations skip
1723eedbe44SPatrick Williams         return;
1733c6f29a0SDhruvaraj Subhashchandran     }
1743c6f29a0SDhruvaraj Subhashchandran 
1753c6f29a0SDhruvaraj Subhashchandran     for (const auto& item : assocs)
1763c6f29a0SDhruvaraj Subhashchandran     {
1773c6f29a0SDhruvaraj Subhashchandran         if (std::get<1>(item).compare(CALLOUT_REV_ASSOCIATION) == 0)
1783c6f29a0SDhruvaraj Subhashchandran         {
1793eedbe44SPatrick Williams             removeWatches.emplace_back(
1803c6f29a0SDhruvaraj Subhashchandran                 std::make_unique<Remove>(bus, std::get<2>(item)));
181891c4769SDhruvaraj Subhashchandran             action(bus, std::get<2>(item), true);
1823c6f29a0SDhruvaraj Subhashchandran         }
1833c6f29a0SDhruvaraj Subhashchandran     }
184aebfde81SDhruvaraj Subhashchandran 
1853eedbe44SPatrick Williams     return;
18659b86cd7SDhruvaraj Subhashchandran }
18759b86cd7SDhruvaraj Subhashchandran 
188891c4769SDhruvaraj Subhashchandran void Add::processExistingCallouts(sdbusplus::bus::bus& bus)
189891c4769SDhruvaraj Subhashchandran {
190891c4769SDhruvaraj Subhashchandran     auto depth = 0;
191891c4769SDhruvaraj Subhashchandran     auto mapperCall = bus.new_method_call(MAPPER_BUSNAME,
192891c4769SDhruvaraj Subhashchandran                                           MAPPER_OBJ_PATH,
193891c4769SDhruvaraj Subhashchandran                                           MAPPER_IFACE,
194891c4769SDhruvaraj Subhashchandran                                           "GetSubTree");
195891c4769SDhruvaraj Subhashchandran     mapperCall.append("/");
196891c4769SDhruvaraj Subhashchandran     mapperCall.append(depth);
197891c4769SDhruvaraj Subhashchandran     mapperCall.append(std::vector<Interface>({LOG_IFACE}));
198891c4769SDhruvaraj Subhashchandran 
199891c4769SDhruvaraj Subhashchandran     auto mapperResponseMsg = bus.call(mapperCall);
200891c4769SDhruvaraj Subhashchandran     if (mapperResponseMsg.is_method_error())
201891c4769SDhruvaraj Subhashchandran     {
202891c4769SDhruvaraj Subhashchandran         using namespace xyz::openbmc_project::Led::Mapper;
203891c4769SDhruvaraj Subhashchandran         report<MethodErr>(
204891c4769SDhruvaraj Subhashchandran             MethodError::METHOD_NAME("GetSubTree"),
205891c4769SDhruvaraj Subhashchandran             MethodError::PATH(MAPPER_OBJ_PATH),
206891c4769SDhruvaraj Subhashchandran             MethodError::INTERFACE(
207891c4769SDhruvaraj Subhashchandran                 OBJMGR_IFACE));
208891c4769SDhruvaraj Subhashchandran         return;
209891c4769SDhruvaraj Subhashchandran     }
210891c4769SDhruvaraj Subhashchandran 
211891c4769SDhruvaraj Subhashchandran     MapperResponseType mapperResponse;
212891c4769SDhruvaraj Subhashchandran     mapperResponseMsg.read(mapperResponse);
213891c4769SDhruvaraj Subhashchandran     if (mapperResponse.empty())
214891c4769SDhruvaraj Subhashchandran     {
215fc30e0c1SDhruvaraj Subhashchandran         //No errors to process.
216891c4769SDhruvaraj Subhashchandran         return;
217891c4769SDhruvaraj Subhashchandran     }
218891c4769SDhruvaraj Subhashchandran 
219891c4769SDhruvaraj Subhashchandran     for (const auto& elem : mapperResponse)
220891c4769SDhruvaraj Subhashchandran     {
221891c4769SDhruvaraj Subhashchandran         auto method =  bus.new_method_call(elem.second.begin()->first.c_str(),
222891c4769SDhruvaraj Subhashchandran                                            elem.first.c_str(),
223891c4769SDhruvaraj Subhashchandran                                            "org.freedesktop.DBus.Properties",
224891c4769SDhruvaraj Subhashchandran                                            "Get");
225891c4769SDhruvaraj Subhashchandran         method.append("org.openbmc.Associations");
226891c4769SDhruvaraj Subhashchandran         method.append("associations");
227891c4769SDhruvaraj Subhashchandran         auto reply = bus.call(method);
228891c4769SDhruvaraj Subhashchandran         if (reply.is_method_error())
229891c4769SDhruvaraj Subhashchandran         {
230891c4769SDhruvaraj Subhashchandran             //do not stop, continue with next elog
231891c4769SDhruvaraj Subhashchandran             log<level::ERR>("Error in getting associations");
232891c4769SDhruvaraj Subhashchandran             continue;
233891c4769SDhruvaraj Subhashchandran         }
234891c4769SDhruvaraj Subhashchandran 
235891c4769SDhruvaraj Subhashchandran         sdbusplus::message::variant<AssociationList> assoc;
236891c4769SDhruvaraj Subhashchandran         reply.read(assoc);
237891c4769SDhruvaraj Subhashchandran         auto& assocs = assoc.get<AssociationList>();
238891c4769SDhruvaraj Subhashchandran         if (assocs.empty())
239891c4769SDhruvaraj Subhashchandran         {
240891c4769SDhruvaraj Subhashchandran             //no associations, skip
241891c4769SDhruvaraj Subhashchandran             continue;
242891c4769SDhruvaraj Subhashchandran         }
243891c4769SDhruvaraj Subhashchandran 
244891c4769SDhruvaraj Subhashchandran         for (const auto& item : assocs)
245891c4769SDhruvaraj Subhashchandran         {
246891c4769SDhruvaraj Subhashchandran             if (std::get<1>(item).compare(CALLOUT_REV_ASSOCIATION) == 0)
247891c4769SDhruvaraj Subhashchandran             {
248891c4769SDhruvaraj Subhashchandran                 removeWatches.emplace_back(
249891c4769SDhruvaraj Subhashchandran                     std::make_unique<Remove>(bus, std::get<2>(item)));
250891c4769SDhruvaraj Subhashchandran                 action(bus, std::get<2>(item), true);
251891c4769SDhruvaraj Subhashchandran             }
252891c4769SDhruvaraj Subhashchandran         }
253891c4769SDhruvaraj Subhashchandran     }
254891c4769SDhruvaraj Subhashchandran }
255891c4769SDhruvaraj Subhashchandran 
2563eedbe44SPatrick Williams void Remove::removed(sdbusplus::message::message& msg)
25759b86cd7SDhruvaraj Subhashchandran {
2583eedbe44SPatrick Williams     auto bus = msg.get_bus();
2593c6f29a0SDhruvaraj Subhashchandran 
2603eedbe44SPatrick Williams     action(bus, inventoryPath, false);
2613eedbe44SPatrick Williams     return;
26259b86cd7SDhruvaraj Subhashchandran }
26359b86cd7SDhruvaraj Subhashchandran 
26459b86cd7SDhruvaraj Subhashchandran }//namespace monitor
26559b86cd7SDhruvaraj Subhashchandran }//namespace fault
26659b86cd7SDhruvaraj Subhashchandran }//namespace fru
26759b86cd7SDhruvaraj Subhashchandran }//namespace led
26859b86cd7SDhruvaraj Subhashchandran }//namespace phosphor
269