summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am5
-rw-r--r--app.cpp14
-rw-r--r--configure.ac18
-rw-r--r--occ_finder.cpp71
-rw-r--r--occ_finder.hpp20
-rw-r--r--occ_pass_through.cpp25
-rw-r--r--occ_pass_through.hpp94
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) \
diff --git a/app.cpp b/app.cpp
index 0ffe711..4b73e51 100644
--- a/app.cpp
+++ b/app.cpp
@@ -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>;
OpenPOWER on IntegriCloud