diff options
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.patch | 338 |
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 + |