summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager/0002-Capture-host-restart-cause.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager/0002-Capture-host-restart-cause.patch')
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager/0002-Capture-host-restart-cause.patch338
1 files changed, 338 insertions, 0 deletions
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager/0002-Capture-host-restart-cause.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager/0002-Capture-host-restart-cause.patch
new file mode 100644
index 000000000..2adff372e
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/state/phosphor-state-manager/0002-Capture-host-restart-cause.patch
@@ -0,0 +1,338 @@
+From ed64fe7379a259a822aca69e70426a2b07aad25d Mon Sep 17 00:00:00 2001
+From: Kuiying Wang <kuiying.wang@intel.com>
+Date: Tue, 7 Aug 2018 16:43:00 +0800
+Subject: [PATCH] Capture host restart cause
+
+Capture host restart cause on power/reset button pressed,
+ipmi command/webui, host OS reboot(Ctrl-Alt-Del),
+and power restore policy settings.
+Save the restart cause into file system,
+and restore it when BMC boot up.
+
+Signed-off-by: Kuiying Wang <kuiying.wang@intel.com>
+Signed-off-by: Yong Li <yong.b.li@linux.intel.com>
+---
+ configure.ac | 4 +-
+ discover_system_state.cpp | 14 +++++
+ host_state_manager.cpp | 17 ++++++
+ host_state_manager.hpp | 148 +++++++++++++++++++++++++++++++++++++++++++++-
+ 4 files changed, 178 insertions(+), 5 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index 7919ec5..051a0c0 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -52,9 +52,9 @@ AC_ARG_VAR(HOST_RUNNING_FILE, [File to create if host is running])
+ AS_IF([test "x$HOST_RUNNING_FILE" == "x"], [HOST_RUNNING_FILE="/run/openbmc/host@%u-on"])
+ AC_DEFINE_UNQUOTED([HOST_RUNNING_FILE], ["$HOST_RUNNING_FILE"], [File to create if host is running])
+
+-AC_ARG_VAR(HOST_STATE_PERSIST_PATH, [Path of file for storing requested host state.])
++AC_ARG_VAR(HOST_STATE_PERSIST_PATH, [Path of file for storing host state.])
+ AS_IF([test "x$HOST_STATE_PERSIST_PATH" == "x"], \
+- [HOST_STATE_PERSIST_PATH="/var/lib/phosphor-state-manager/requestedHostTransition"])
++ [HOST_STATE_PERSIST_PATH="/var/lib/phosphor-state-manager/hostState"])
+ AC_DEFINE_UNQUOTED([HOST_STATE_PERSIST_PATH], ["$HOST_STATE_PERSIST_PATH"], \
+ [Path of file for storing requested host state.])
+
+diff --git a/discover_system_state.cpp b/discover_system_state.cpp
+index 3a38152..0b5798a 100644
+--- a/discover_system_state.cpp
++++ b/discover_system_state.cpp
+@@ -12,6 +12,7 @@
+ #include "settings.hpp"
+ #include "xyz/openbmc_project/Common/error.hpp"
+ #include "xyz/openbmc_project/Control/Power/RestorePolicy/server.hpp"
++#include <xyz/openbmc_project/State/Host/server.hpp>
+
+ namespace phosphor
+ {
+@@ -181,6 +182,10 @@ int main(int argc, char** argv)
+ log<level::INFO>("power_policy=ALWAYS_POWER_ON, powering host on");
+ setProperty(bus, hostPath, HOST_BUSNAME, "RequestedHostTransition",
+ convertForMessage(server::Host::Transition::On));
++
++ setProperty(
++ bus, hostPath, HOST_BUSNAME, "HostRestartCause",
++ convertForMessage(server::Host::RestartCause::PowerPolicyAlwaysOn));
+ }
+ else if (RestorePolicy::Policy::Restore ==
+ RestorePolicy::convertPolicyFromString(powerPolicy))
+@@ -192,6 +197,15 @@ int main(int argc, char** argv)
+ getProperty(bus, hostPath, HOST_BUSNAME, "RequestedHostTransition");
+ setProperty(bus, hostPath, HOST_BUSNAME, "RequestedHostTransition",
+ hostReqState);
++
++ if (server::Host::convertTransitionFromString(hostReqState) ==
++ server::Host::Transition::On)
++ {
++ setProperty(
++ bus, hostPath, HOST_BUSNAME, "HostRestartCause",
++ convertForMessage(
++ server::Host::RestartCause::PowerPolicyPreviousState));
++ }
+ }
+
+ return 0;
+diff --git a/host_state_manager.cpp b/host_state_manager.cpp
+index 7d661dd..0e00e78 100644
+--- a/host_state_manager.cpp
++++ b/host_state_manager.cpp
+@@ -308,6 +308,15 @@ bool Host::deserialize(const fs::path& path)
+ }
+ }
+
++void Host::restoreHostRestartCause()
++{
++ if (!deserialize(HOST_STATE_PERSIST_PATH))
++ {
++ // set to default value
++ server::Host::hostRestartCause(server::Host::RestartCause::Unknown);
++ }
++}
++
+ Host::Transition Host::requestedHostTransition(Transition value)
+ {
+ log<level::INFO>("Host State transaction request",
+@@ -321,6 +330,7 @@ Host::Transition Host::requestedHostTransition(Transition value)
+ // check of this count will occur
+ if (value != server::Host::Transition::Off)
+ {
++ hostRestartCause(RestartCause::IpmiCommand);
+ decrementRebootCount();
+ }
+
+@@ -353,6 +363,13 @@ Host::HostState Host::currentHostState(HostState value)
+ return server::Host::currentHostState(value);
+ }
+
++Host::RestartCause Host::hostRestartCause(RestartCause value)
++{
++ auto retVal = server::Host::hostRestartCause(value);
++ serialize();
++ return retVal;
++}
++
+ } // namespace manager
+ } // namespace state
+ } // namespace phosphor
+diff --git a/host_state_manager.hpp b/host_state_manager.hpp
+index 2b00777..afd8aa3 100644
+--- a/host_state_manager.hpp
++++ b/host_state_manager.hpp
+@@ -32,6 +32,22 @@ using namespace phosphor::logging;
+ namespace sdbusRule = sdbusplus::bus::match::rules;
+ namespace fs = std::experimental::filesystem;
+
++const static constexpr char* powerButtonPath =
++ "/xyz/openbmc_project/Chassis/Buttons/Power0";
++const static constexpr char* powerButtonIntf =
++ "xyz.openbmc_project.Chassis.Buttons.Power";
++const static constexpr char* resetButtonPath =
++ "/xyz/openbmc_project/Chassis/Buttons/Reset0";
++const static constexpr char* resetButtonIntf =
++ "xyz.openbmc_project.Chassis.Buttons.Reset";
++
++const static constexpr char* powerControlService =
++ "xyz.openbmc_project.Chassis.Control.Power";
++const static constexpr char* powerControlPath =
++ "/xyz/openbmc_project/Chassis/Control/Power0";
++const static constexpr char* powerControlInterface =
++ "xyz.openbmc_project.Chassis.Control.Power";
++
+ /** @class Host
+ * @brief OpenBMC host state management implementation.
+ * @details A concrete implementation for xyz.openbmc_project.State.Host
+@@ -59,8 +75,93 @@ class Host : public HostInherit
+ sdbusRule::interface("org.freedesktop.systemd1.Manager"),
+ std::bind(std::mem_fn(&Host::sysStateChange), this,
+ std::placeholders::_1)),
+- settings(bus)
++ settings(bus),
++ powerButtonPressedSignal(
++ bus,
++ sdbusRule::type::signal() + sdbusRule::member("Pressed") +
++ sdbusRule::path(powerButtonPath) +
++ sdbusRule::interface(powerButtonIntf),
++ [this](sdbusplus::message::message& msg) {
++ phosphor::logging::log<phosphor::logging::level::INFO>(
++ "powerButtonPressedSignal callback function is called...");
++ this->hostRestartCause(this->RestartCause::PowerButton);
++ this->powerButtonPressed = true;
++ return;
++ }),
++ resetButtonPressedSignal(
++ bus,
++ sdbusRule::type::signal() + sdbusRule::member("Pressed") +
++ sdbusRule::path(resetButtonPath) +
++ sdbusRule::interface(resetButtonIntf),
++ [this](sdbusplus::message::message& msg) {
++ phosphor::logging::log<phosphor::logging::level::INFO>(
++ "resetButtonPressedSignal callback function is called...");
++ this->hostRestartCause(this->RestartCause::ResetButton);
++ this->resetButtonPressed = true;
++ return;
++ }),
++ postCompletePropSignal(
++ bus,
++ sdbusplus::bus::match::rules::propertiesChanged(
++ powerControlPath, powerControlInterface),
++ [this](sdbusplus::message::message& msg) {
++ phosphor::logging::log<phosphor::logging::level::INFO>(
++ "postCompletePropSignal callback function is called...");
++
++ using DbusVariant = sdbusplus::message::variant<
++ std::string, bool, uint8_t, uint16_t, int16_t, uint32_t,
++ int32_t, uint64_t, int64_t, double>;
++
++ std::map<std::string, DbusVariant> props;
++ std::vector<std::string> inval;
++ std::string iface;
++ msg.read(iface, props, inval);
++
++ for (const auto& t : props)
++ {
++ auto key = t.first;
++ auto value = t.second;
++
++ if (key == "state")
++ {
++ this->powerStateChanged = true;
++ }
++
++ else if (key == "pgood")
++ {
++ this->pgood =
++ sdbusplus::message::variant_ns::get<int32_t>(value);
++ }
++
++ else if (key == "post_complete")
++ {
++ bool postState =
++ sdbusplus::message::variant_ns::get<bool>(value);
++
++ if (!postState && this->pgood)
++ {
++ if (!this->resetButtonPressed &&
++ !this->powerButtonPressed &&
++ !this->powerStateChanged)
++ {
++ phosphor::logging::log<
++ phosphor::logging::level::INFO>(
++ "OEM Reset");
++ this->hostRestartCause(this->RestartCause::OEM);
++ }
++ this->powerButtonPressed = false;
++ this->powerStateChanged = false;
++ this->resetButtonPressed = false;
++ }
++ }
++ }
++ })
+ {
++ powerButtonPressed = false;
++ powerStateChanged = false;
++ resetButtonPressed = false;
++ pgood = 0;
++
+ // Enable systemd signals
+ subscribeToSystemdSignals();
+
+@@ -69,8 +170,29 @@ class Host : public HostInherit
+
+ attemptsLeft(BOOT_COUNT_MAX_ALLOWED);
+
++ restoreHostRestartCause(); // restore host restart cause from persisted
++ // file
++
+ // We deferred this until we could get our property correct
+ this->emit_object_added();
++ sdbusplus::message::variant<int32_t> pgoodProp = -1;
++ auto method =
++ this->bus.new_method_call(powerControlService, powerControlPath,
++ "org.freedesktop.DBus.Properties", "Get");
++
++ method.append(powerControlInterface, "pgood");
++ try
++ {
++ auto reply = this->bus.call(method);
++ reply.read(pgoodProp);
++ pgood = sdbusplus::message::variant_ns::get<int>(pgoodProp);
++ }
++ catch (const sdbusplus::exception::SdBusError& e)
++ {
++ log<level::ERR>("Error performing call to get pgood",
++ entry("NAME=%s", e.name()),
++ entry("ERROR=%s", e.what()));
++ }
+ }
+
+ /** @brief Set value of HostTransition */
+@@ -85,6 +207,9 @@ class Host : public HostInherit
+ /** @brief Set value of CurrentHostState */
+ HostState currentHostState(HostState value) override;
+
++ /** @brief Set value of HostRestartCause */
++ RestartCause hostRestartCause(RestartCause value) override;
++
+ /**
+ * @brief Set host reboot count to default
+ *
+@@ -192,7 +317,9 @@ class Host : public HostInherit
+ server::Progress::bootProgress()),
+ convertForMessage(
+ sdbusplus::xyz::openbmc_project::State::OperatingSystem::
+- server::Status::operatingSystemState()));
++ server::Status::operatingSystemState()),
++ convertForMessage(sdbusplus::xyz::openbmc_project::State::
++ server::Host::hostRestartCause()));
+ }
+
+ /** @brief Function required by Cereal to perform deserialization.
+@@ -208,7 +335,8 @@ class Host : public HostInherit
+ std::string reqTranState;
+ std::string bootProgress;
+ std::string osState;
+- archive(reqTranState, bootProgress, osState);
++ std::string restartCause;
++ archive(reqTranState, bootProgress, osState, restartCause);
+ auto reqTran = Host::convertTransitionFromString(reqTranState);
+ // When restoring, set the requested state with persistent value
+ // but don't call the override which would execute it
+@@ -219,6 +347,8 @@ class Host : public HostInherit
+ sdbusplus::xyz::openbmc_project::State::OperatingSystem::server::
+ Status::operatingSystemState(
+ Host::convertOSStatusFromString(osState));
++ sdbusplus::xyz::openbmc_project::State::server::Host::hostRestartCause(
++ Host::convertRestartCauseFromString(restartCause));
+ }
+
+ /** @brief Serialize and persist requested host state
+@@ -239,6 +369,9 @@ class Host : public HostInherit
+ */
+ bool deserialize(const fs::path& path);
+
++ /** @brief Used to restore HostRestartCause value from persisted file */
++ void restoreHostRestartCause();
++
+ /** @brief Persistent sdbusplus DBus bus connection. */
+ sdbusplus::bus::bus& bus;
+
+@@ -247,6 +380,15 @@ class Host : public HostInherit
+
+ // Settings objects of interest
+ settings::Objects settings;
++
++ bool resetButtonPressed;
++ bool powerButtonPressed;
++ bool powerStateChanged;
++ int32_t pgood;
++
++ sdbusplus::bus::match_t powerButtonPressedSignal;
++ sdbusplus::bus::match_t resetButtonPressedSignal;
++ sdbusplus::bus::match_t postCompletePropSignal;
+ };
+
+ } // namespace manager
+--
+2.7.4
+