RBMC: Create initial RBMC application
Create a new phosphor-rbmc-manager application and service file to go
along with it, hidden behind the rbmc-state-management meson option.
As described in https://gerrit.openbmc.org/c/openbmc/docs/+/70233, this
application will manage redundancy related information for redundant BMC
systems.
This initial commit will just immediately set the role to Passive. It
does introduce the framework to determine the role and also includes a
basic test case. Future commits can then build on this.
It is setup to use the coroutine versions of sdbusplus's D-Bus
bindings.
The idea for the role_determination::run() function is to eventually
pass in all of the pieces of information it would need to determine the
role, like BMC position, sibling presence, previous role, etc. That
way, test cases can be created to easily vary the inputs to test all of
the code paths.
Tested:
```
$ busctl introspect xyz.openbmc_project.State.BMC.Redundancy /xyz/openbmc_project/state/bmc/redundancy -l
NAME TYPE SIGNATURE RESULT/VALUE FLAGS
org.freedesktop.DBus.Introspectable interface - - -
.Introspect method - s -
org.freedesktop.DBus.ObjectManager interface - - -
.GetManagedObjects method - a{oa{sa{sv}}} -
.InterfacesAdded signal oa{sa{sv}} - -
.InterfacesRemoved signal oas - -
org.freedesktop.DBus.Peer interface - - -
.GetMachineId method - s -
.Ping method - - -
org.freedesktop.DBus.Properties interface - - -
.Get method ss v -
.GetAll method s a{sv} -
.Set method ssv - -
.PropertiesChanged signal sa{sv}as - -
xyz.openbmc_project.State.BMC.Redundancy interface - - -
.RedundancyEnabled property b false emits-change
.Role property s "xyz.openbmc_project.State.BMC.Redundancy.Role.Passive" emits-change
```
Change-Id: Ie159d46ac5bd9cf47792d55ebd5a2e4a811017e8
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
diff --git a/meson.build b/meson.build
index 12daf35..83beef5 100644
--- a/meson.build
+++ b/meson.build
@@ -371,3 +371,7 @@
)
)
endif
+
+if get_option('rbmc-state-management').allowed()
+ subdir('redundant-bmc')
+endif
diff --git a/redundant-bmc/manager.cpp b/redundant-bmc/manager.cpp
new file mode 100644
index 0000000..7ad79b3
--- /dev/null
+++ b/redundant-bmc/manager.cpp
@@ -0,0 +1,32 @@
+#include "manager.hpp"
+
+#include "role_determination.hpp"
+
+#include <phosphor-logging/lg2.hpp>
+
+namespace bmc::redundancy
+{
+
+Manager::Manager(sdbusplus::async::context& ctx) :
+ ctx(ctx),
+ redundancyInterface(ctx.get_bus(), RedundancyInterface::instance_path)
+{
+ ctx.spawn(startup());
+}
+
+sdbusplus::async::task<> Manager::startup()
+{
+ determineRole();
+ co_return;
+}
+
+void Manager::determineRole()
+{
+ auto role = role_determination::run();
+
+ lg2::info("Role Determined: {ROLE}", "ROLE", role);
+
+ redundancyInterface.role(role);
+}
+
+} // namespace bmc::redundancy
diff --git a/redundant-bmc/manager.hpp b/redundant-bmc/manager.hpp
new file mode 100644
index 0000000..c40dc91
--- /dev/null
+++ b/redundant-bmc/manager.hpp
@@ -0,0 +1,50 @@
+#pragma once
+#include <sdbusplus/async/context.hpp>
+#include <xyz/openbmc_project/State/BMC/Redundancy/server.hpp>
+
+namespace bmc::redundancy
+{
+
+using RedundancyIntf =
+ sdbusplus::xyz::openbmc_project::State::BMC::server::Redundancy;
+using RedundancyInterface = sdbusplus::server::object_t<RedundancyIntf>;
+
+class Manager
+{
+ public:
+ ~Manager() = default;
+ Manager(const Manager&) = delete;
+ Manager& operator=(const Manager&) = delete;
+ Manager(Manager&&) = delete;
+ Manager& operator=(Manager&&) = delete;
+
+ /**
+ * @brief Constructor
+ *
+ * @param cts - The async context object
+ */
+ explicit Manager(sdbusplus::async::context& ctx);
+
+ private:
+ /**
+ * @brief Kicks off the Manager startup as a coroutine
+ */
+ sdbusplus::async::task<> startup();
+
+ /**
+ * @brief Determines the BMC role, active or passive
+ */
+ void determineRole();
+
+ /**
+ * @brief The async context object
+ */
+ sdbusplus::async::context& ctx;
+
+ /**
+ * @brief The Redundancy D-Bus interface
+ */
+ RedundancyInterface redundancyInterface;
+};
+
+} // namespace bmc::redundancy
diff --git a/redundant-bmc/meson.build b/redundant-bmc/meson.build
new file mode 100644
index 0000000..27fe26a
--- /dev/null
+++ b/redundant-bmc/meson.build
@@ -0,0 +1,40 @@
+librbmc_sources = files(
+ 'manager.cpp',
+ 'role_determination.cpp',
+)
+
+librbmc_deps = [
+ sdbusplus,
+ phosphordbusinterfaces,
+ phosphorlogging,
+]
+
+librbmc_lib = static_library(
+ 'rbmc',
+ librbmc_sources,
+ dependencies: [
+ librbmc_deps
+ ]
+)
+
+librbmc_dep = declare_dependency(
+ include_directories: include_directories('.'),
+ link_with: librbmc_lib,
+ dependencies: [
+ sdbusplus,
+ phosphordbusinterfaces,
+ phosphorlogging,
+ ]
+)
+
+executable('phosphor-rbmc-state-manager',
+ 'rbmc_state_manager_main.cpp',
+ dependencies: [
+ librbmc_dep
+ ],
+ install: true
+)
+
+if get_option('tests').allowed()
+ subdir('test')
+endif
\ No newline at end of file
diff --git a/redundant-bmc/rbmc_state_manager_main.cpp b/redundant-bmc/rbmc_state_manager_main.cpp
new file mode 100644
index 0000000..b2196de
--- /dev/null
+++ b/redundant-bmc/rbmc_state_manager_main.cpp
@@ -0,0 +1,21 @@
+#include "manager.hpp"
+
+#include <sdbusplus/async.hpp>
+
+int main()
+{
+ sdbusplus::async::context ctx;
+ sdbusplus::server::manager_t objMgr{
+ ctx, bmc::redundancy::RedundancyInterface::instance_path};
+
+ bmc::redundancy::Manager manager{ctx};
+
+ ctx.spawn([](sdbusplus::async::context& ctx) -> sdbusplus::async::task<> {
+ ctx.request_name(bmc::redundancy::RedundancyInterface::default_service);
+ co_return;
+ }(ctx));
+
+ ctx.run();
+
+ return 0;
+}
diff --git a/redundant-bmc/role_determination.cpp b/redundant-bmc/role_determination.cpp
new file mode 100644
index 0000000..ef28c06
--- /dev/null
+++ b/redundant-bmc/role_determination.cpp
@@ -0,0 +1,14 @@
+#include "role_determination.hpp"
+
+namespace role_determination
+{
+using Redundancy =
+ sdbusplus::common::xyz::openbmc_project::state::bmc::Redundancy;
+
+Redundancy::Role run()
+{
+ using enum Redundancy::Role;
+ return Passive;
+}
+
+} // namespace role_determination
diff --git a/redundant-bmc/role_determination.hpp b/redundant-bmc/role_determination.hpp
new file mode 100644
index 0000000..69ae2c9
--- /dev/null
+++ b/redundant-bmc/role_determination.hpp
@@ -0,0 +1,15 @@
+#pragma once
+
+#include <xyz/openbmc_project/State/BMC/Redundancy/common.hpp>
+
+namespace role_determination
+{
+
+/**
+ * @brief Determines if this BMC should claim the Active or Passive role.
+ *
+ * @return The role
+ */
+sdbusplus::common::xyz::openbmc_project::state::bmc::Redundancy::Role run();
+
+} // namespace role_determination
diff --git a/redundant-bmc/test/meson.build b/redundant-bmc/test/meson.build
new file mode 100644
index 0000000..60edfc6
--- /dev/null
+++ b/redundant-bmc/test/meson.build
@@ -0,0 +1,15 @@
+test('rbmc-state-manager-tests',
+ executable('rbmc-state-manager-tests',
+ 'role_determination_test.cpp',
+ dependencies: [
+ gtest,
+ phosphordbusinterfaces,
+ sdbusplus,
+ phosphorlogging,
+ ],
+ link_with: [
+ librbmc_lib
+ ],
+ include_directories: '../'
+ )
+)
diff --git a/redundant-bmc/test/role_determination_test.cpp b/redundant-bmc/test/role_determination_test.cpp
new file mode 100644
index 0000000..1fab501
--- /dev/null
+++ b/redundant-bmc/test/role_determination_test.cpp
@@ -0,0 +1,13 @@
+#include "role_determination.hpp"
+
+#include <gtest/gtest.h>
+
+using Role =
+ sdbusplus::common::xyz::openbmc_project::state::bmc::Redundancy::Role;
+
+namespace rd = role_determination;
+
+TEST(RoleDeterminationTest, RoleDeterminationTest)
+{
+ EXPECT_EQ(rd::run(), Role::Passive);
+}
diff --git a/service_files/meson.build b/service_files/meson.build
index 0ba81ba..d372ddc 100644
--- a/service_files/meson.build
+++ b/service_files/meson.build
@@ -28,7 +28,8 @@
if get_option('rbmc-state-management').allowed()
unit_files += [
- 'phosphor-set-bmc-active-passive.service'
+ 'phosphor-set-bmc-active-passive.service',
+ 'xyz.openbmc_project.State.BMC.Redundancy.service'
]
endif
diff --git a/service_files/xyz.openbmc_project.State.BMC.Redundancy.service b/service_files/xyz.openbmc_project.State.BMC.Redundancy.service
new file mode 100644
index 0000000..65910a3
--- /dev/null
+++ b/service_files/xyz.openbmc_project.State.BMC.Redundancy.service
@@ -0,0 +1,12 @@
+[Unit]
+Description=Phosphor Redundant BMC State Manager
+After=xyz.openbmc_project.State.BMC.service
+
+[Service]
+ExecStart=/usr/bin/phosphor-rbmc-state-manager
+Restart=always
+Type=dbus
+BusName=xyz.openbmc_project.State.BMC.Redundancy
+
+[Install]
+WantedBy=multi-user.target