From 3c6f29a0d0c89186e5f8fe1dfb12f76a6e448b28 Mon Sep 17 00:00:00 2001 From: Dhruvaraj Subhashchandran Date: Thu, 20 Apr 2017 09:47:28 -0500 Subject: Implement led assert and deassert based on faults Change-Id: I28378b155da15282b1b5bf0403075b55bda5b70d Signed-off-by: Dhruvaraj Subhashchandran --- fault-monitor/Makefile.am | 27 ++++- fault-monitor/fru-fault-monitor.cpp | 196 +++++++++++++++++++++++++++++++++++- 2 files changed, 221 insertions(+), 2 deletions(-) (limited to 'fault-monitor') diff --git a/fault-monitor/Makefile.am b/fault-monitor/Makefile.am index ba7603f..044b638 100644 --- a/fault-monitor/Makefile.am +++ b/fault-monitor/Makefile.am @@ -7,7 +7,16 @@ sbin_PROGRAMS = phosphor-fru-fault-monitor phosphor_fru_fault_monitor_SOURCES = \ fru-fault-monitor.cpp \ - monitor-main.cpp + monitor-main.cpp \ + xyz/openbmc_project/Led/Mapper/error.cpp \ + xyz/openbmc_project/Led/Fru/Monitor/error.cpp + +BUILT_SOURCES = xyz/openbmc_project/Led/Mapper/error.hpp \ + xyz/openbmc_project/Led/Mapper/error.cpp \ + xyz/openbmc_project/Led/Fru/Monitor/error.hpp \ + xyz/openbmc_project/Led/Fru/Monitor/error.cpp + +CLEANFILES = ${BUILT_SOURCES} phosphor_fru_fault_monitor_LDFLAGS = $(SDBUSPLUS_LIBS) \ $(PHOSPHOR_LOGGING_LIBS) \ @@ -15,3 +24,19 @@ phosphor_fru_fault_monitor_LDFLAGS = $(SDBUSPLUS_LIBS) \ phosphor_fru_fault_monitor_CFLAGS = $(SDBUSPLUS_CFLAGS) \ $(PHOSPHOR_LOGGING_CFLAGS) \ $(PHOSPHOR_DBUS_INTERFACES_CFLAGS) + +xyz/openbmc_project/Led/Mapper/error.hpp: ${top_srcdir}/xyz/openbmc_project/Led/Mapper.errors.yaml + @mkdir -p `dirname $@` + $(SDBUSPLUSPLUS) -r $(top_srcdir) error exception-header xyz.openbmc_project.Led.Mapper > $@ + +xyz/openbmc_project/Led/Mapper/error.cpp: ${top_srcdir}/xyz/openbmc_project/Led/Mapper.errors.yaml + @mkdir -p `dirname $@` + $(SDBUSPLUSPLUS) -r $(top_srcdir) error exception-cpp xyz.openbmc_project.Led.Mapper > $@ + +xyz/openbmc_project/Led/Fru/Monitor/error.hpp: ${top_srcdir}/xyz/openbmc_project/Led/Fru/Monitor.errors.yaml + @mkdir -p `dirname $@` + $(SDBUSPLUSPLUS) -r $(top_srcdir) error exception-header xyz.openbmc_project.Led.Fru.Monitor > $@ + +xyz/openbmc_project/Led/Fru/Monitor/error.cpp: ${top_srcdir}/xyz/openbmc_project/Led/Fru/Monitor.errors.yaml + @mkdir -p `dirname $@` + $(SDBUSPLUSPLUS) -r $(top_srcdir) error exception-cpp xyz.openbmc_project.Led.Fru.Monitor > $@ diff --git a/fault-monitor/fru-fault-monitor.cpp b/fault-monitor/fru-fault-monitor.cpp index 1213128..e21727b 100644 --- a/fault-monitor/fru-fault-monitor.cpp +++ b/fault-monitor/fru-fault-monitor.cpp @@ -1,4 +1,9 @@ +#include +#include "xyz/openbmc_project/Led/Fru/Monitor/error.hpp" +#include "xyz/openbmc_project/Led/Mapper/error.hpp" +#include "elog-errors.hpp" #include "fru-fault-monitor.hpp" + namespace phosphor { namespace led @@ -10,10 +15,105 @@ namespace fault namespace monitor { +using namespace phosphor::logging; + +constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper"; +constexpr auto MAPPER_OBJ_PATH = "/xyz/openbmc_project/object_mapper"; +constexpr auto MAPPER_IFACE = "xyz.openbmc_project.ObjectMapper"; +constexpr auto OBJMGR_IFACE = "org.freedesktop.DBus.ObjectManager"; +constexpr auto LED_GROUPS = "/xyz/openbmc_project/led/groups/"; +constexpr auto LOG_PATH = "/xyz/openbmc_project/logging"; + +using AssociationList = std::vector>; +using MethodErr = + sdbusplus::xyz::openbmc_project::Led::Mapper::Error::MethodError; +using ObjectNotFoundErr = + sdbusplus::xyz::openbmc_project::Led::Mapper::Error::ObjectNotFoundError; +using AssociationRetrieveErr = + sdbusplus::xyz::openbmc_project:: + Led::Fru::Monitor::Error::AssociationRetrieveError; +using InventoryPathErr = + sdbusplus::xyz::openbmc_project:: + Led::Fru::Monitor::Error::InventoryPathError; + +std::string getService(sdbusplus::bus::bus& bus, + const std::string& path) +{ + auto mapper = bus.new_method_call(MAPPER_BUSNAME, + MAPPER_OBJ_PATH, + MAPPER_IFACE, "GetObject"); + mapper.append(path.c_str(), std::vector({OBJMGR_IFACE})); + auto mapperResponseMsg = bus.call(mapper); + if (mapperResponseMsg.is_method_error()) + { + using namespace xyz::openbmc_project::Led::Mapper; + elog( + MethodError::METHOD_NAME("GetObject"), + MethodError::PATH(path.c_str()), + MethodError::INTERFACE( + OBJMGR_IFACE)); + } + + std::map> mapperResponse; + mapperResponseMsg.read(mapperResponse); + if (mapperResponse.empty()) + { + using namespace xyz::openbmc_project::Led::Mapper; + elog( + ObjectNotFoundError::METHOD_NAME("GetObject"), + ObjectNotFoundError::PATH(path.c_str()), + ObjectNotFoundError::INTERFACE( + OBJMGR_IFACE)); + } + + return mapperResponse.cbegin()->first; +} + void action(sdbusplus::bus::bus& bus, - const std::string& unit, + const std::string& path, bool assert) { + std::string service; + try + { + service = getService(bus, LED_GROUPS); + } + catch (MethodErr& e) + { + commit(); + return; + } + catch (ObjectNotFoundErr& e) + { + commit(); + return; + } + + auto pos = path.rfind("/"); + if (pos == std::string::npos) + { + using namespace xyz::openbmc_project::Led::Fru::Monitor; + report( + InventoryPathError::PATH( + path.c_str())); + return; + } + auto unit = path.substr(pos + 1); + + std::string ledPath = LED_GROUPS + + unit + '_' + LED_FAULT; + + auto method = bus.new_method_call(service.c_str(), + ledPath.c_str(), + "org.freedesktop.DBus.Properties", + "Set"); + method.append("xyz.openbmc_project.Led.Group"); + method.append("Asserted"); + + method.append(sdbusplus::message::variant(assert)); + bus.call_noreply(method); + return; } @@ -21,6 +121,72 @@ int Add::created(sd_bus_message* msg, void* data, sd_bus_error* retError) { + auto m = sdbusplus::message::message(msg); + auto bus = m.get_bus(); + + sdbusplus::message::object_path obPath; + m.read(obPath); + std::string objectPath(std::move(obPath)); + + std::size_t found = objectPath.find(ELOG_ENTRY); + if (found == std::string::npos) + { + //Not a new error entry skip + return 0; + } + + std::string service; + try + { + service = getService(bus, LOG_PATH); + } + catch (MethodErr& e) + { + commit(); + return 0; + } + catch (ObjectNotFoundErr& e) + { + commit(); + return 0; + } + + auto method = bus.new_method_call(service.c_str(), objectPath.c_str(), + "org.freedesktop.DBus.Properties", + "Get"); + + method.append("org.openbmc.Associations"); + method.append("associations"); + auto reply = bus.call(method); + if (reply.is_method_error()) + { + using namespace xyz::openbmc_project::Led::Fru::Monitor; + report( + AssociationRetrieveError::ELOG_ENTRY_PATH( + objectPath.c_str())); + return 0; + } + + sdbusplus::message::variant assoc; + reply.read(assoc); + + auto assocs = + sdbusplus::message::variant_ns::get(assoc); + if (assocs.empty()) + { + //No associations skip + return 0; + } + + for (const auto& item : assocs) + { + if (std::get<1>(item).compare(CALLOUT_REV_ASSOCIATION) == 0) + { + action(bus, std::get<2>(item), true); + static_cast(data)->removeWatches.emplace_back( + std::make_unique(bus, std::get<2>(item))); + } + } return 0; } @@ -28,6 +194,34 @@ int Remove::removed(sd_bus_message* msg, void* data, sd_bus_error* retError) { + auto m = sdbusplus::message::message(msg); + auto bus = m.get_bus(); + std::string assoc; + m.read(assoc); + + if (assoc.compare("org.openbmc.Association")) + { + //Skip if not about association + return 0; + } + + std::map> endPoints; + m.read(endPoints); + auto it = endPoints.find("endpoints"); + + if (it == endPoints.end()) + { + //No end points,skip + return 0; + } + + if (!((*it).second.empty())) + { + //Skip, end points are not empty + return 0; + } + + action(bus, static_cast(data)->inventoryPath, false); return 0; } -- cgit v1.2.1