diff options
author | Deepak Kodihalli <dkodihal@in.ibm.com> | 2017-05-08 07:11:22 -0500 |
---|---|---|
committer | Deepak Kodihalli <dkodihal@in.ibm.com> | 2017-06-13 08:18:25 -0500 |
commit | fd358d18b8b7f73204cc482f3b29f49a50fda214 (patch) | |
tree | b231ebe86d27090357161ab7ce68c8ba2fb6bacd | |
parent | d13694a0658a9fc5914b06eadcaabe9d671f70b2 (diff) | |
download | openpower-occ-control-fd358d18b8b7f73204cc482f3b29f49a50fda214.tar.gz openpower-occ-control-fd358d18b8b7f73204cc482f3b29f49a50fda214.zip |
Create OCC pass-through objects
Create OCC pass-through d-bus objects when corresponding CPU objects are
created in the inventory.
Resolves openbmc/openbmc#1450.
Change-Id: I8da879f51ebef8dcc3d25358def81c5e0dce0617
Signed-off-by: Deepak Kodihalli <dkodihal@in.ibm.com>
-rw-r--r-- | Makefile.am | 5 | ||||
-rw-r--r-- | app.cpp | 14 | ||||
-rw-r--r-- | configure.ac | 18 | ||||
-rw-r--r-- | occ_finder.cpp | 71 | ||||
-rw-r--r-- | occ_finder.hpp | 20 | ||||
-rw-r--r-- | occ_pass_through.cpp | 25 | ||||
-rw-r--r-- | occ_pass_through.hpp | 94 |
7 files changed, 109 insertions, 138 deletions
diff --git a/Makefile.am b/Makefile.am index 50d23da..b68f9a0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,11 +1,9 @@ # Build these headers, don't install them noinst_HEADERS = \ - occ_finder.hpp \ occ_pass_through.hpp sbin_PROGRAMS = openpower-occ-control openpower_occ_control_SOURCES = \ - occ_finder.cpp \ occ_pass_through.cpp \ app.cpp \ org/open_power/OCC/PassThrough/error.cpp @@ -18,7 +16,8 @@ CLEANFILES = ${BUILT_SOURCES} openpower_occ_control_LDFLAGS = \ $(SDBUSPLUS_LIBS) \ $(PHOSPHOR_LOGGING_LIBS) \ - $(OPENPOWER_DBUS_INTERFACES_LIBS) + $(OPENPOWER_DBUS_INTERFACES_LIBS) \ + -lstdc++fs openpower_occ_control_CXXFLAGS = $(SDBUSPLUS_CFLAGS) \ @@ -6,7 +6,19 @@ int main(int argc, char* argv[]) { try { - open_power::occ::pass_through::run(); + auto bus = sdbusplus::bus::new_default(); + bus.request_name(OCC_PASS_THROUGH_BUSNAME); + + sdbusplus::server::manager::manager objManager(bus, + OCC_PASS_THROUGH_ROOT); + + open_power::occ::pass_through::manager::Manager mgr(bus); + + while (true) + { + bus.process_discard(); + bus.wait(); + } } catch (const std::exception& e) { diff --git a/configure.ac b/configure.ac index 211e723..676dc0d 100644 --- a/configure.ac +++ b/configure.ac @@ -43,17 +43,21 @@ AC_ARG_VAR(INVENTORY_ITEM_INTERFACE, [The Inventory.Item interface]) AS_IF([test "x$INVENTORY_ITEM_INTERFACE" == "x"], [INVENTORY_ITEM_INTERFACE="xyz.openbmc_project.Inventory.Item"]) AC_DEFINE_UNQUOTED([INVENTORY_ITEM_INTERFACE], ["$INVENTORY_ITEM_INTERFACE"], [The Inventory.Item root]) -AC_ARG_VAR(INVENTORY_ROOT, [The Inventory root]) -AS_IF([test "x$INVENTORY_ROOT" == "x"], [INVENTORY_ROOT="/xyz/openbmc_project/inventory/system"]) -AC_DEFINE_UNQUOTED([INVENTORY_ROOT], ["$INVENTORY_ROOT"], [The Inventory root]) +AC_ARG_VAR(CPU_PATH, [CPU inventory path]) +AS_IF([test "x$CPU_PATH" == "x"], [CPU_PATH="/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu"]) +AC_DEFINE_UNQUOTED([CPU_PATH], ["$CPU_PATH"], [CPU inventory path]) -AC_ARG_VAR(CPU_NAME, [The name of the cpu object]) +AC_ARG_VAR(MAX_CPUS, [The max number of CPUs]) +AS_IF([test "x$MAX_CPUS" == "x"], [MAX_CPUS=2]) +AC_DEFINE_UNQUOTED([MAX_CPUS], [$MAX_CPUS], [The max number of CPUs]) + +AC_ARG_VAR(CPU_NAME, [The CPU object name]) AS_IF([test "x$CPU_NAME" == "x"], [CPU_NAME="cpu"]) -AC_DEFINE_UNQUOTED([CPU_NAME], ["$CPU_NAME"], [The name of the cpu object]) +AC_DEFINE_UNQUOTED([CPU_NAME], ["$CPU_NAME"], [The CPU object name]) -AC_ARG_VAR(OCC_NAME, [The name of the occ object]) +AC_ARG_VAR(OCC_NAME, [The OCC object name]) AS_IF([test "x$OCC_NAME" == "x"], [OCC_NAME="occ"]) -AC_DEFINE_UNQUOTED([OCC_NAME], ["$OCC_NAME"], [The name of the occ object]) +AC_DEFINE_UNQUOTED([OCC_NAME], ["$OCC_NAME"], [The OCC object name]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_FILES([Makefile]) diff --git a/occ_finder.cpp b/occ_finder.cpp deleted file mode 100644 index 8d6391d..0000000 --- a/occ_finder.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include <algorithm> -#include <sdbusplus/server.hpp> -#include "occ_finder.hpp" -#include "config.h" - -namespace open_power -{ -namespace occ -{ -namespace finder -{ - -constexpr auto toChar(size_t c) -{ - constexpr auto map = "0123"; - return map[c]; -} - -std::vector<std::string> get() -{ - auto bus = sdbusplus::bus::new_default(); - auto mapper = - bus.new_method_call( - "xyz.openbmc_project.ObjectMapper", - "/xyz/openbmc_project/object_mapper", - "xyz.openbmc_project.ObjectMapper", - "GetSubTreePaths"); - - auto depth = 0; - mapper.append(std::string(INVENTORY_ROOT)); - mapper.append(depth); - mapper.append(std::vector<std::string>( - {std::string(INVENTORY_ITEM_INTERFACE)})); - - auto result = bus.call(mapper); - if (result.is_method_error()) - { - throw std::runtime_error("ObjectMapper GetSubTreePaths failed"); - } - - std::vector<std::string> response; - result.read(response); - if (response.empty()) - { - throw std::runtime_error("ObjectMapper GetSubTreePaths : bad response"); - } - - std::vector<std::string> occs; - size_t count = 0; - std::string cpu = std::string(CPU_NAME) + toChar(count); - auto constexpr MAX_PROCS = 4; // Revisit for multi-node systems - for (const auto& path: response) - { - if (std::equal(cpu.crbegin(), cpu.crend(), path.crbegin())) - { - if(count == MAX_PROCS) - { - break; - } - occs.emplace_back(std::string(OCC_NAME) + - toChar(count++)); - } - cpu.back() = toChar(count); - } - - return occs; -} - -} // namespace finder -} // namespace occ -} // namespace open_power diff --git a/occ_finder.hpp b/occ_finder.hpp deleted file mode 100644 index 2a31b71..0000000 --- a/occ_finder.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include <vector> -#include <string> - -namespace open_power -{ -namespace occ -{ -namespace finder -{ - -/** @brief Get OCC objects on the system by mapping them to processor inventory - * @returns list of occ objects, such as occ0, occ1, and so on. - */ -std::vector<std::string> get(); - -} // namespace finder -} // namespace occ -} // namespace open_power diff --git a/occ_pass_through.cpp b/occ_pass_through.cpp index 7027d65..911dd85 100644 --- a/occ_pass_through.cpp +++ b/occ_pass_through.cpp @@ -6,7 +6,6 @@ #include <phosphor-logging/elog.hpp> #include <org/open_power/OCC/PassThrough/error.hpp> #include "occ_pass_through.hpp" -#include "occ_finder.hpp" #include "elog-errors.hpp" namespace open_power { @@ -15,30 +14,6 @@ namespace occ namespace pass_through { -void run() -{ - auto bus = sdbusplus::bus::new_default(); - sdbusplus::server::manager::manager objManager(bus, - OCC_PASS_THROUGH_ROOT); - - std::vector<std::unique_ptr<PassThrough>> objects; - auto occs = open_power::occ::finder::get(); - - for (const auto& occ : occs) - { - auto occPassThrough = object(occ); - objects.emplace_back( - std::make_unique<PassThrough>(bus, occPassThrough.c_str())); - } - bus.request_name(OCC_PASS_THROUGH_BUSNAME); - - while (true) - { - bus.process_discard(); - bus.wait(); - } -} - PassThrough::PassThrough( sdbusplus::bus::bus& bus, const char* path) : diff --git a/occ_pass_through.hpp b/occ_pass_through.hpp index 070e371..c9f6566 100644 --- a/occ_pass_through.hpp +++ b/occ_pass_through.hpp @@ -1,14 +1,20 @@ #pragma once #include <string> +#include <cstring> +#include <map> #include <vector> +#include <experimental/filesystem> #include <unistd.h> #include <sdbusplus/bus.hpp> +#include <functional> #include <sdbusplus/server/object.hpp> #include <org/open_power/OCC/PassThrough/server.hpp> #include "config.h" #include "file.hpp" +namespace sdbusRule = sdbusplus::bus::match::rules; + namespace open_power { namespace occ @@ -16,20 +22,86 @@ namespace occ namespace pass_through { -/** @brief Make occ pass-through d-bus object pathname - * @param[in] occ - occ name - * @returns occ pass-through path - */ -inline auto object(const std::string& occ) +class PassThrough; + +namespace manager { - return std::string(OCC_PASS_THROUGH_ROOT) + - '/' + - occ; -} -/** @brief Put occ pass through objects on the bus +/** @class Manager + * @brief Builds and manages OCC pass-through objects */ -void run(); +struct Manager +{ + public: + Manager() = delete; + Manager(const Manager&) = delete; + Manager& operator=(const Manager&) = delete; + Manager(Manager&&) = default; + Manager& operator=(Manager&&) = default; + ~Manager() = default; + + /** @brief Ctor - Add OCC pass-through objects on the bus. Create + * OCC objects when corresponding CPU inventory is created. + * @param[in] bus - handle to the bus + */ + Manager(sdbusplus::bus::bus& bus): + bus(bus) + { + for (auto id = 0; id < MAX_CPUS; ++id) + { + auto path = std::string(CPU_PATH) + std::to_string(id); + cpuMatches.emplace_back( + bus, + sdbusRule::interfacesAdded() + + sdbusRule::argNpath(0, path), + std::bind(std::mem_fn(&Manager::cpuCreated), + this, std::placeholders::_1)); + } + } + + /** @brief Callback that responds to cpu creation in the inventory - + * by creating the occ passthrough object. + * + * @param[in] msg - bus message + * + * @returns 0 to indicate success + */ + int cpuCreated(sdbusplus::message::message& msg) + { + namespace fs = std::experimental::filesystem; + + sdbusplus::message::object_path o; + msg.read(o); + fs::path cpuPath(std::string(std::move(o))); + auto cpu = cpuPath.filename(); + + auto occPath = fs::path(OCC_PASS_THROUGH_ROOT); + std::string name{cpu.c_str()}; + auto index = name.find(CPU_NAME); + name.replace(index, std::strlen(CPU_NAME), OCC_NAME); + occPath /= name; + + objects.emplace_back( + std::make_unique<PassThrough>( + bus, + occPath.c_str())); + + return 0; + } + + private: + /** @brief reference to the bus */ + sdbusplus::bus::bus& bus; + + /** @brief OCC pass-through objects */ + std::vector<std::unique_ptr<PassThrough>> objects; + + /** @brief sbdbusplus match objects */ + std::vector<sdbusplus::bus::match_t> cpuMatches; +}; + +} // namespace manager + using Iface = sdbusplus::server::object::object< sdbusplus::org::open_power::OCC::server::PassThrough>; |