diff options
author | Josh D. King <jdking@us.ibm.com> | 2017-03-02 10:58:11 -0600 |
---|---|---|
committer | Patrick Williams <patrick@stwcx.xyz> | 2017-04-17 17:21:32 +0000 |
commit | 929ef70706fa339e6cc7adbed32e54624de1b813 (patch) | |
tree | 929818f8854e9982913b447f25e5fb5ec801ca81 | |
parent | ca3579226904b666c2436ebe82d9d7723c97fb51 (diff) | |
download | phosphor-state-manager-929ef70706fa339e6cc7adbed32e54624de1b813.tar.gz phosphor-state-manager-929ef70706fa339e6cc7adbed32e54624de1b813.zip |
Remove Hosts power on messages when powering off
Currently Host state services show incorrect states
when a target exits. To fix this, a bus call is used on
the target to determine its ActiveState. Doing that
helps to determine if the target is already
powered on and is now powering down.
Change-Id: Id91dc8156308372fc1649526a7b6dedee94eeb01
Signed-off-by: Josh D. King <jdking@us.ibm.com>
-rw-r--r-- | host_state_manager.cpp | 67 | ||||
-rw-r--r-- | host_state_manager.hpp | 12 |
2 files changed, 76 insertions, 3 deletions
diff --git a/host_state_manager.cpp b/host_state_manager.cpp index 3eb76b9..b6ea501 100644 --- a/host_state_manager.cpp +++ b/host_state_manager.cpp @@ -22,6 +22,9 @@ constexpr auto HOST_STATE_POWEROFF_TGT = "obmc-host-stop@0.target"; constexpr auto HOST_STATE_POWERON_TGT = "obmc-host-start@0.target"; constexpr auto HOST_STATE_QUIESCE_TGT = "obmc-quiesce-host@0.target"; +constexpr auto ACTIVE_STATE = "active"; +constexpr auto ACTIVATING_STATE = "activating"; + /* Map a transition to it's systemd target */ const std::map<server::Host::Transition,std::string> SYSTEMD_TARGET_TABLE = { @@ -45,8 +48,12 @@ constexpr auto REBOOTCOUNTER_SERVICE("org.openbmc.Sensors"); constexpr auto REBOOTCOUNTER_PATH("/org/openbmc/sensors/host/BootCount"); constexpr auto REBOOTCOUNTER_INTERFACE("org.openbmc.SensorValue"); +constexpr auto SYSTEMD_PROPERTY_IFACE = "org.freedesktop.DBus.Properties"; +constexpr auto SYSTEMD_INTERFACE_UNIT = "org.freedesktop.systemd1.Unit"; + const sdbusplus::message::variant<int> DEFAULT_BOOTCOUNT = 2; + /* Map a system state to the HostState */ const std::map<std::string, server::Host::HostState> SYS_HOST_STATE_TABLE = { {"HOST_BOOTING", server::Host::HostState::Running}, @@ -121,6 +128,58 @@ void Host::executeTransition(Transition tranReq) return; } +bool Host::stateActive(const std::string& target) +{ + sdbusplus::message::variant<std::string> currentState; + sdbusplus::message::object_path unitTargetPath; + + auto method = this->bus.new_method_call(SYSTEMD_SERVICE, + SYSTEMD_OBJ_PATH, + SYSTEMD_INTERFACE, + "GetUnit"); + + method.append(target); + auto result = this->bus.call(method); + + //Check that the bus call didn't result in an error + if(result.is_method_error()) + { + log<level::ERR>("Error in bus call - could not resolve GetUnit for:", + entry(" %s", SYSTEMD_INTERFACE)); + return false; + } + + result.read(unitTargetPath); + + method = this->bus.new_method_call(SYSTEMD_SERVICE, + static_cast<const std::string&> + (unitTargetPath).c_str(), + SYSTEMD_PROPERTY_IFACE, + "Get"); + + method.append(SYSTEMD_INTERFACE_UNIT, "ActiveState"); + result = this->bus.call(method); + + //Check that the bus call didn't result in an error + if(result.is_method_error()) + { + log<level::ERR>("Error in bus call - could not resolve Get for:", + entry(" %s", SYSTEMD_PROPERTY_IFACE)); + return false; + } + + result.read(currentState); + + if(currentState != ACTIVE_STATE && currentState != ACTIVATING_STATE) + { + //False - not active + return false; + } + //True - active + return true; +} + + bool Host::isAutoReboot() { sdbusplus::message::variant<std::string> autoRebootParam; @@ -205,7 +264,7 @@ bool Host::isAutoReboot() return true; } if(rebootCounterParam == 0) - { + { // Reset reboot counter and go to quiesce state method.append(DEFAULT_BOOTCOUNT); this->bus.call_noreply(method); @@ -235,7 +294,8 @@ int Host::sysStateChange(sd_bus_message* msg, sdPlusMsg.read(newStateID, newStateObjPath, newStateUnit, newStateResult); if((newStateUnit == HOST_STATE_POWEROFF_TGT) && - (newStateResult == "done")) + (newStateResult == "done") && + (!stateActive(HOST_STATE_POWERON_TGT))) { log<level::INFO>("Recieved signal that host is off"); this->currentHostState(server::Host::HostState::Off); @@ -249,7 +309,8 @@ int Host::sysStateChange(sd_bus_message* msg, } } else if((newStateUnit == HOST_STATE_POWERON_TGT) && - (newStateResult == "done")) + (newStateResult == "done") && + (stateActive(HOST_STATE_POWERON_TGT))) { log<level::INFO>("Recieved signal that host is running"); this->currentHostState(server::Host::HostState::Running); diff --git a/host_state_manager.hpp b/host_state_manager.hpp index 4678746..e277289 100644 --- a/host_state_manager.hpp +++ b/host_state_manager.hpp @@ -88,6 +88,18 @@ class Host : public sdbusplus::server::object::object< void executeTransition(Transition tranReq); /** + * @brief Determine if target is active + * + * This function determines if the target is active and + * helps prevent misleading log recorded states. + * + * @param[in] target - Target string to check on + * + * @return boolean corresponding to state active + **/ + bool stateActive(const std::string& target); + + /** * @brief Determine if auto reboot flag is set * * @return boolean corresponding to current auto_reboot setting |