From 18aa044eace292d2d58406e06e3ca4a98fbfaaea Mon Sep 17 00:00:00 2001 From: Deepak Kodihalli Date: Fri, 21 Jul 2017 07:07:09 -0500 Subject: Add API to retrieve settings Add API to retrieve and cache settings objects of interest. Change-Id: I8afd58b5b3e9a691e4d3fa6bfba2ba5c92cd2568 Signed-off-by: Deepak Kodihalli --- Makefile.am | 19 +++++++++++--- configure.ac | 2 ++ settings.cpp | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ settings.hpp | 56 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 156 insertions(+), 3 deletions(-) create mode 100644 settings.cpp create mode 100644 settings.hpp diff --git a/Makefile.am b/Makefile.am index 0379037..8dd3fc2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,8 +4,11 @@ sbin_PROGRAMS = \ ipmid ipmid_SOURCES = \ - ipmid.cpp + ipmid.cpp \ + settings.cpp + nodist_ipmid_SOURCES = ipmiwhitelist.cpp + BUILT_SOURCES = \ ipmiwhitelist.cpp \ sensor-gen.cpp \ @@ -15,8 +18,18 @@ BUILT_SOURCES = \ CLEANFILES = $(BUILT_SOURCES) #TODO - Make this path a configure option (bitbake parameter) -ipmid_CPPFLAGS = -DHOST_IPMI_LIB_PATH=\"/usr/lib/host-ipmid/\" $(PHOSPHOR_LOGGING_CFLAGS) -ipmid_LDFLAGS = $(SYSTEMD_LIBS) $(libmapper_LIBS) $(LIBADD_DLOPEN) $(PHOSPHOR_LOGGING_LIBS) -export-dynamic +ipmid_CPPFLAGS = \ + -DHOST_IPMI_LIB_PATH=\"/usr/lib/host-ipmid/\" \ + $(PHOSPHOR_LOGGING_CFLAGS) \ + $(PHOSPHOR_DBUS_INTERFACES_CFLAGS) + +ipmid_LDFLAGS = \ + $(SYSTEMD_LIBS) \ + $(libmapper_LIBS) \ + $(LIBADD_DLOPEN) \ + $(PHOSPHOR_LOGGING_LIBS) \ + $(PHOSPHOR_DBUS_INTERFACES_LIBS) \ + -export-dynamic # TODO: Rather than use -export-dynamic, we should use -export-symbol to have a # selective list of symbols. diff --git a/configure.ac b/configure.ac index 7efb842..9c909ea 100644 --- a/configure.ac +++ b/configure.ac @@ -26,6 +26,8 @@ AC_CHECK_LIB([mapper], [mapper_get_service], ,[AC_MSG_ERROR([Could not find libm PKG_CHECK_MODULES([SYSTEMD], [libsystemd >= 221], [], [AC_MSG_ERROR(["systemd required and not found"])]) PKG_CHECK_MODULES([PHOSPHOR_LOGGING], [phosphor-logging],, [AC_MSG_ERROR([Could not find phosphor-logging...openbmc/phosphor-logging package required])]) PKG_CHECK_MODULES([PHOSPHOR_DBUS_INTERFACES], [phosphor-dbus-interfaces],, [AC_MSG_ERROR([Could not find phosphor-dbus-interfaces...openbmc/phosphor-dbus-interfaces package required])]) +PKG_CHECK_MODULES([SDBUSPLUS], [sdbusplus],,\ + AC_MSG_ERROR(["Requires sdbusplus package."])) AS_IF([test "x$enable_softoff" != "xno"], # Check for sdbusplus diff --git a/settings.cpp b/settings.cpp new file mode 100644 index 0000000..cb86d99 --- /dev/null +++ b/settings.cpp @@ -0,0 +1,82 @@ +#include +#include +#include "xyz/openbmc_project/Common/error.hpp" +#include "settings.hpp" + +namespace settings +{ + +using namespace phosphor::logging; +using namespace sdbusplus::xyz::openbmc_project::Common::Error; + +constexpr auto mapperService = "xyz.openbmc_project.ObjectMapper"; +constexpr auto mapperPath = "/xyz/openbmc_project/object_mapper"; +constexpr auto mapperIntf = "xyz.openbmc_project.ObjectMapper"; + +Objects::Objects(sdbusplus::bus::bus& bus, + const std::vector& filter): + bus(bus) +{ + auto depth = 0; + + auto mapperCall = bus.new_method_call(mapperService, + mapperPath, + mapperIntf, + "GetSubTree"); + mapperCall.append(root); + mapperCall.append(depth); + mapperCall.append(filter); + auto response = bus.call(mapperCall); + if (response.is_method_error()) + { + log("Error in mapper GetSubTree"); + elog(); + } + + using Interfaces = std::vector; + using MapperResponse = std::map>; + MapperResponse result; + response.read(result); + if (result.empty()) + { + log("Invalid response from mapper"); + elog(); + } + + for (auto& iter : result) + { + const auto& path = iter.first; + auto& interface = iter.second.begin()->second[0]; + map.emplace(std::move(interface), path); + } +} + +Service Objects::service(const Path& path, const Interface& interface) const +{ + using Interfaces = std::vector; + auto mapperCall = bus.new_method_call(mapperService, + mapperPath, + mapperIntf, + "GetObject"); + mapperCall.append(path); + mapperCall.append(Interfaces({interface})); + + auto response = bus.call(mapperCall); + if (response.is_method_error()) + { + log("Error in mapper GetObject"); + elog(); + } + + std::map result; + response.read(result); + if (result.empty()) + { + log("Invalid response from mapper"); + elog(); + } + + return result.begin()->first; +} + +} // namespace settings diff --git a/settings.hpp b/settings.hpp new file mode 100644 index 0000000..60ee4d4 --- /dev/null +++ b/settings.hpp @@ -0,0 +1,56 @@ +#pragma once + +#include +#include + +namespace settings +{ + +using Path = std::string; +using Service = std::string; +using Interface = std::string; + +constexpr auto root = "/"; + +/** @class Objects + * @brief Fetch paths of settings d-bus objects of interest, upon construction + */ +struct Objects +{ + public: + /** @brief Constructor - fetch settings objects + * + * @param[in] bus - The Dbus bus object + * @param[in] filter - A vector of settings interfaces the caller is + * interested in. + */ + Objects(sdbusplus::bus::bus& bus, const std::vector& filter); + Objects(const Objects&) = default; + Objects& operator=(const Objects&) = default; + Objects(Objects&&) = delete; + Objects& operator=(Objects&&) = delete; + ~Objects() = default; + + /** @brief Fetch d-bus service, given a path and an interface. The + * service can't be cached because mapper returns unique + * service names. + * + * @param[in] path - The Dbus object + * @param[in] interface - The Dbus interface + * + * @return std::string - the dbus service + */ + Service service(const Path& path, const Interface& interface) const; + + // TODO openbmc/openbmc#2058 - This will break when multiple settings, + // or in general multiple objects implement a single setting interface. + // For instance this will break for a 2-blade server, because we'd have + // 2 sets of settings objects. Need to revisit and fix this. + /** @brief map of settings objects */ + std::map map; + + /** @brief The Dbus bus object */ + sdbusplus::bus::bus& bus; +}; + +} // namespace settings -- cgit v1.2.1