diff options
author | Andrew Geissler <andrewg@us.ibm.com> | 2017-07-06 12:56:32 -0500 |
---|---|---|
committer | Andrew Geissler <andrewg@us.ibm.com> | 2017-07-17 16:17:44 -0500 |
commit | 52cf26a821d914dc073b8d40a98b26cf2c6abe84 (patch) | |
tree | abedcf77cf6886268cf77495df81b04f705e1f6f | |
parent | 32016d18e1b4ddeb8390ee2032e51582a9bca58c (diff) | |
download | openpower-occ-control-52cf26a821d914dc073b8d40a98b26cf2c6abe84.tar.gz openpower-occ-control-52cf26a821d914dc073b8d40a98b26cf2c6abe84.zip |
Create pcap object and log monitored events
Change-Id: I2d7b3a449e2c9c1d5a0627161f8e85dcaca1e087
Signed-off-by: Andrew Geissler <andrewg@us.ibm.com>
-rw-r--r-- | occ_manager.hpp | 12 | ||||
-rw-r--r-- | powercap.cpp | 134 | ||||
-rw-r--r-- | powercap.hpp | 22 |
3 files changed, 166 insertions, 2 deletions
diff --git a/occ_manager.hpp b/occ_manager.hpp index a1b5234..48cd9c8 100644 --- a/occ_manager.hpp +++ b/occ_manager.hpp @@ -8,6 +8,7 @@ #include "occ_pass_through.hpp" #include "occ_status.hpp" #include "config.h" +#include <powercap.hpp> namespace sdbusRule = sdbusplus::bus::match::rules; @@ -78,6 +79,14 @@ struct Manager std::make_unique<Status>( bus, path.c_str())); + + // Create the power cap monitor object for master occ (0) + if(!pcap && (index == 0)) + { + pcap = std::make_unique<open_power::occ::powercap::PowerCap>( + bus, + *statusObjects[index]); + } return 0; } @@ -91,6 +100,9 @@ struct Manager /** @brief OCC Status objects */ std::vector<std::unique_ptr<Status>> statusObjects; + /** @brief Power cap monitor and occ notification object */ + std::unique_ptr<open_power::occ::powercap::PowerCap> pcap; + /** @brief sbdbusplus match objects */ std::vector<sdbusplus::bus::match_t> cpuMatches; }; diff --git a/powercap.cpp b/powercap.cpp index 2d5362d..2ecad0c 100644 --- a/powercap.cpp +++ b/powercap.cpp @@ -8,18 +8,148 @@ namespace occ namespace powercap { +constexpr auto PCAP_PATH = "/xyz/openbmc_project/control/host0/power_cap"; +constexpr auto PCAP_INTERFACE = "xyz.openbmc_project.Control.Power.Cap"; + +constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper"; +constexpr auto MAPPER_PATH = "/xyz/openbmc_project/object_mapper"; +constexpr auto MAPPER_INTERFACE = "xyz.openbmc_project.ObjectMapper"; + +constexpr auto POWER_CAP_PROP = "PowerCap"; +constexpr auto POWER_CAP_ENABLE_PROP = "PowerCapEnable"; + using namespace phosphor::logging; +std::string PowerCap::getService(std::string path, + std::string interface) +{ + auto mapper = bus.new_method_call(MAPPER_BUSNAME, + MAPPER_PATH, + MAPPER_INTERFACE, + "GetObject"); + + mapper.append(path, std::vector<std::string>({interface})); + auto mapperResponseMsg = bus.call(mapper); + + if (mapperResponseMsg.is_method_error()) + { + log<level::ERR>("Error in mapper call", + entry("PATH=%s", path.c_str()), + entry("INTERFACE=%s", interface.c_str())); + // TODO openbmc/openbmc#851 - Once available, throw returned error + throw std::runtime_error("Error in mapper call"); + } + + std::map<std::string, std::vector<std::string>> mapperResponse; + mapperResponseMsg.read(mapperResponse); + if (mapperResponse.empty()) + { + log<level::ERR>("Error reading mapper response", + entry("PATH=%s", path.c_str()), + entry("INTERFACE=%s", interface.c_str())); + // TODO openbmc/openbmc#1712 - Handle empty mapper resp. consistently + throw std::runtime_error("Error reading mapper response"); + } + + return mapperResponse.begin()->first; +} + +uint32_t PowerCap::getPcap() +{ + auto settingService = getService(PCAP_PATH,PCAP_INTERFACE); + + auto method = this->bus.new_method_call(settingService.c_str(), + PCAP_PATH, + "org.freedesktop.DBus.Properties", + "Get"); + + method.append(PCAP_INTERFACE, POWER_CAP_PROP); + auto reply = this->bus.call(method); + + if (reply.is_method_error()) + { + log<level::ERR>("Error in getPcap prop"); + return 0; + } + sdbusplus::message::variant<uint32_t> pcap; + reply.read(pcap); + + return pcap.get<uint32_t>(); +} + +bool PowerCap::getPcapEnabled() +{ + auto settingService = getService(PCAP_PATH,PCAP_INTERFACE); + + auto method = this->bus.new_method_call(settingService.c_str(), + PCAP_PATH, + "org.freedesktop.DBus.Properties", + "Get"); + + method.append(PCAP_INTERFACE, POWER_CAP_ENABLE_PROP); + auto reply = this->bus.call(method); + + if (reply.is_method_error()) + { + log<level::ERR>("Error in getPcapEnabled prop"); + return 0; + } + sdbusplus::message::variant<bool> pcapEnabled; + reply.read(pcapEnabled); + + return pcapEnabled.get<bool>(); +} void PowerCap::pcapChanged(sdbusplus::message::message& msg) { - log<level::DEBUG>("Power Cap Change Detected"); if (!occStatus.occActive()) { // Nothing to do return; } - // TODO - Process this change + + uint32_t pcap = 0; + bool pcapEnabled = false; + + std::string msgSensor; + std::map<std::string, sdbusplus::message::variant<uint32_t, bool>> msgData; + msg.read(msgSensor, msgData); + + // Retrieve which property changed via the msg and read the other one + auto valPropMap = msgData.find(POWER_CAP_PROP); + if (valPropMap != msgData.end()) + { + pcap = sdbusplus::message::variant_ns::get<uint32_t>( + valPropMap->second); + pcapEnabled = getPcapEnabled(); + } + else + { + valPropMap = msgData.find(POWER_CAP_ENABLE_PROP); + if (valPropMap != msgData.end()) + { + pcapEnabled = sdbusplus::message::variant_ns::get<bool>( + valPropMap->second); + pcap = getPcap(); + } + else + { + log<level::INFO>("Unknown power cap property changed"); + return; + } + } + + log<level::INFO>("Power Cap Property Change", + entry("PCAP=%u",pcap), + entry("PCAP_ENABLED=%u",pcapEnabled)); + + // Determine desired action to write to occ + // TODO + + // Write action to occ + // TODO + + return; } } // namespace open_power diff --git a/powercap.hpp b/powercap.hpp index 878822b..ff457f8 100644 --- a/powercap.hpp +++ b/powercap.hpp @@ -60,6 +60,28 @@ private: */ void pcapChanged(sdbusplus::message::message& msg); + /** @brief Look up DBUS service for input path/interface + * + * @param[in] path - DBUS path + * @param[in] path - DBUS interface + * + * @return Distinct service name for input path/interface + */ + std::string getService(std::string path, + std::string interface); + + /** @brief Get the power cap property + * + * @return Power cap, 0 on failure to indicate no pcap + */ + uint32_t getPcap(); + + /** @brief Get the power cap enable property + * + * @return Whether power cap enabled, will return false on error + */ + bool getPcapEnabled(); + /** @brief Reference to sdbus **/ sdbusplus::bus::bus& bus; |