hypervisor: state management support
Some systems have a hypervisor firmware stack which they wish to track
and change the state of. This new state management object will provide
this function if a user selects to bring it into their system.
Signed-off-by: Andrew Geissler <geissonator@yahoo.com>
Change-Id: I6082c6e06c6731d71f2e580e1ab87af38917bb3a
diff --git a/hypervisor_state_manager.cpp b/hypervisor_state_manager.cpp
new file mode 100644
index 0000000..acfbb83
--- /dev/null
+++ b/hypervisor_state_manager.cpp
@@ -0,0 +1,62 @@
+#include "config.h"
+
+#include "hypervisor_state_manager.hpp"
+
+#include <fmt/format.h>
+
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/log.hpp>
+#include <sdbusplus/exception.hpp>
+#include <sdbusplus/server.hpp>
+
+#include <fstream>
+#include <iostream>
+#include <map>
+#include <string>
+
+namespace phosphor
+{
+namespace state
+{
+namespace manager
+{
+
+// When you see server:: you know we're referencing our base class
+namespace server = sdbusplus::xyz::openbmc_project::State::server;
+using namespace phosphor::logging;
+using sdbusplus::exception::SdBusError;
+
+server::Host::Transition Hypervisor::requestedHostTransition(Transition value)
+{
+ log<level::INFO>(fmt::format("Hypervisor state transition request of {}",
+ convertForMessage(value))
+ .c_str());
+
+ // Only support the transition to On
+ if (value != server::Host::Transition::On)
+ {
+ log<level::ERR>("Hypervisor state only supports a transition to On");
+ // TODO raise appropriate error exception
+ return server::Host::Transition::Off;
+ }
+
+ // This property is monitored by a separate application (for example PLDM)
+ // which is responsible for propagating the On request to the hypervisor
+
+ return server::Host::requestedHostTransition(value);
+}
+
+// TODO - Monitor BootProgress and update hypervisor state to Running if
+// OS is started
+
+server::Host::HostState Hypervisor::currentHostState(HostState value)
+{
+ log<level::INFO>(
+ fmt::format("Change to Hypervisor State: {}", convertForMessage(value))
+ .c_str());
+ return server::Host::currentHostState(value);
+}
+
+} // namespace manager
+} // namespace state
+} // namespace phosphor
diff --git a/hypervisor_state_manager.hpp b/hypervisor_state_manager.hpp
new file mode 100644
index 0000000..b0ce297
--- /dev/null
+++ b/hypervisor_state_manager.hpp
@@ -0,0 +1,61 @@
+#pragma once
+
+#include "config.h"
+
+#include "settings.hpp"
+#include "xyz/openbmc_project/State/Host/server.hpp"
+
+#include <sdbusplus/bus.hpp>
+
+namespace phosphor
+{
+namespace state
+{
+namespace manager
+{
+
+using HypervisorInherit = sdbusplus::server::object::object<
+ sdbusplus::xyz::openbmc_project::State::server::Host>;
+
+namespace server = sdbusplus::xyz::openbmc_project::State::server;
+
+/** @class Host
+ * @brief OpenBMC host state management implementation.
+ * @details A concrete implementation for xyz.openbmc_project.State.Host
+ * DBus API.
+ */
+class Hypervisor : public HypervisorInherit
+{
+ public:
+ Hypervisor() = delete;
+ Hypervisor(const Hypervisor&) = delete;
+ Hypervisor& operator=(const Hypervisor&) = delete;
+ Hypervisor(Hypervisor&&) = delete;
+ Hypervisor& operator=(Hypervisor&&) = delete;
+ virtual ~Hypervisor() = default;
+
+ /** @brief Constructs Hypervisor State Manager
+ *
+ * @param[in] bus - The Dbus bus object
+ * @param[in] objPath - The Dbus object path
+ */
+ Hypervisor(sdbusplus::bus::bus& bus, const char* objPath) :
+ HypervisorInherit(bus, objPath, false), bus(bus)
+ {}
+
+ /** @brief Set value of HostTransition */
+ server::Host::Transition
+ requestedHostTransition(server::Host::Transition value) override;
+
+ /** @brief Set value of CurrentHostState */
+ server::Host::HostState
+ currentHostState(server::Host::HostState value) override;
+
+ private:
+ /** @brief Persistent sdbusplus DBus bus connection. */
+ sdbusplus::bus::bus& bus;
+};
+
+} // namespace manager
+} // namespace state
+} // namespace phosphor
diff --git a/hypervisor_state_manager_main.cpp b/hypervisor_state_manager_main.cpp
new file mode 100644
index 0000000..61154d6
--- /dev/null
+++ b/hypervisor_state_manager_main.cpp
@@ -0,0 +1,29 @@
+#include "config.h"
+
+#include "hypervisor_state_manager.hpp"
+
+#include <sdbusplus/bus.hpp>
+
+#include <cstdlib>
+
+int main()
+{
+ auto bus = sdbusplus::bus::new_default();
+
+ // For now, we only have one instance of the hypervisor
+ auto objPathInst = std::string{HYPERVISOR_OBJPATH} + '0';
+
+ // Add sdbusplus ObjectManager.
+ sdbusplus::server::manager::manager objManager(bus, objPathInst.c_str());
+
+ phosphor::state::manager::Hypervisor manager(bus, objPathInst.c_str());
+
+ bus.request_name(HYPERVISOR_BUSNAME);
+
+ while (true)
+ {
+ bus.process_discard();
+ bus.wait();
+ }
+ return 0;
+}
diff --git a/meson.build b/meson.build
index 610b4ba..170971a 100644
--- a/meson.build
+++ b/meson.build
@@ -16,6 +16,10 @@
conf.set_quoted(
'HOST_OBJPATH', get_option('host-objpath'))
conf.set_quoted(
+ 'HYPERVISOR_BUSNAME', get_option('hypervisor-busname'))
+conf.set_quoted(
+ 'HYPERVISOR_OBJPATH', get_option('hypervisor-objpath'))
+conf.set_quoted(
'CHASSIS_BUSNAME', get_option('chassis-busname'))
conf.set_quoted(
'CHASSIS_OBJPATH', get_option('chassis-objpath'))
@@ -65,6 +69,18 @@
install: true
)
+executable('phosphor-hypervisor-state-manager',
+ 'hypervisor_state_manager.cpp',
+ 'hypervisor_state_manager_main.cpp',
+ 'settings.cpp',
+ dependencies: [
+ sdbusplus, sdeventplus, phosphorlogging,
+ phosphordbusinterfaces, cppfs
+ ],
+ implicit_include_directories: true,
+ install: true
+)
+
executable('phosphor-chassis-state-manager',
'chassis_state_manager.cpp',
'chassis_state_manager_main.cpp',
diff --git a/meson_options.txt b/meson_options.txt
index 9412421..d340668 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -13,6 +13,18 @@
)
option(
+ 'hypervisor-busname', type: 'string',
+ value: 'xyz.openbmc_project.State.Hypervisor',
+ description: 'The Hypervisor DBus busname to own.',
+)
+
+option(
+ 'hypervisor-objpath', type: 'string',
+ value: '/xyz/openbmc_project/state/hypervisor',
+ description: 'The hypervisor state manager Dbus root.',
+)
+
+option(
'chassis-busname', type: 'string',
value: 'xyz.openbmc_project.State.Chassis',
description: 'The Chassis DBus busname to own.',
diff --git a/service_files/meson.build b/service_files/meson.build
index a1f38f9..31b1974 100644
--- a/service_files/meson.build
+++ b/service_files/meson.build
@@ -9,6 +9,7 @@
'xyz.openbmc_project.State.BMC.service',
'xyz.openbmc_project.State.Chassis.service',
'xyz.openbmc_project.State.Host.service',
+ 'xyz.openbmc_project.State.Hypervisor.service',
'xyz.openbmc_project.State.ScheduledHostTransition.service',
'phosphor-clear-one-time@.service',
'phosphor-set-host-transition-to-off@.service',
diff --git a/service_files/xyz.openbmc_project.State.Hypervisor.service b/service_files/xyz.openbmc_project.State.Hypervisor.service
new file mode 100644
index 0000000..e0879bf
--- /dev/null
+++ b/service_files/xyz.openbmc_project.State.Hypervisor.service
@@ -0,0 +1,14 @@
+[Unit]
+Description=Phosphor Hypervisor State Manager
+Before=mapper-wait@-xyz-openbmc_project-state-hypervisor.service
+Wants=obmc-mapper.target
+After=obmc-mapper.target
+
+[Service]
+ExecStart=/usr/bin/phosphor-hypervisor-state-manager
+Restart=always
+Type=dbus
+BusName=xyz.openbmc_project.State.Hypervisor
+
+[Install]
+WantedBy=multi-user.target