diff options
author | Josh D. King <jdking@us.ibm.com> | 2017-03-02 11:15:55 -0600 |
---|---|---|
committer | Patrick Williams <patrick@stwcx.xyz> | 2017-04-17 17:21:32 +0000 |
commit | 697474c5491f6840ae7c6fc64b7364d23b7e87b8 (patch) | |
tree | ef954326140023fb03f6b3a4fa69112383b35fbc | |
parent | 929ef70706fa339e6cc7adbed32e54624de1b813 (diff) | |
download | phosphor-state-manager-697474c5491f6840ae7c6fc64b7364d23b7e87b8.tar.gz phosphor-state-manager-697474c5491f6840ae7c6fc64b7364d23b7e87b8.zip |
Remove Chassis power on messages when powering off
Currently Chassis 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: I55bc87fa9ff647212fe545b7edd7df8a85e9e223
Signed-off-by: Josh D. King <jdking@us.ibm.com>
-rw-r--r-- | chassis_state_manager.cpp | 64 | ||||
-rw-r--r-- | chassis_state_manager.hpp | 12 |
2 files changed, 74 insertions, 2 deletions
diff --git a/chassis_state_manager.cpp b/chassis_state_manager.cpp index b7b5a9d..3b00fde 100644 --- a/chassis_state_manager.cpp +++ b/chassis_state_manager.cpp @@ -17,6 +17,9 @@ using namespace phosphor::logging; constexpr auto CHASSIS_STATE_POWEROFF_TGT = "obmc-chassis-poweroff@0.target"; constexpr auto CHASSIS_STATE_POWERON_TGT = "obmc-chassis-poweron@0.target"; +constexpr auto ACTIVE_STATE = "active"; +constexpr auto ACTIVATING_STATE = "activating"; + /* Map a transition to it's systemd target */ const std::map<server::Chassis::Transition,std::string> SYSTEMD_TARGET_TABLE = { @@ -28,6 +31,9 @@ constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1"; constexpr auto SYSTEMD_OBJ_PATH = "/org/freedesktop/systemd1"; constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager"; +constexpr auto SYSTEMD_PROPERTY_IFACE = "org.freedesktop.DBus.Properties"; +constexpr auto SYSTEMD_INTERFACE_UNIT = "org.freedesktop.systemd1.Unit"; + void Chassis::subscribeToSystemdSignals() { auto method = this->bus.new_method_call(SYSTEMD_SERVICE, @@ -91,6 +97,58 @@ void Chassis::executeTransition(Transition tranReq) return; } +bool Chassis::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; + +} + int Chassis::sysStateChangeSignal(sd_bus_message *msg, void *userData, sd_bus_error *retError) { @@ -110,13 +168,15 @@ int Chassis::sysStateChange(sd_bus_message* msg, sdPlusMsg.read(newStateID, newStateObjPath, newStateUnit, newStateResult); if((newStateUnit == CHASSIS_STATE_POWEROFF_TGT) && - (newStateResult == "done")) + (newStateResult == "done") && + (!stateActive(CHASSIS_STATE_POWERON_TGT))) { log<level::INFO>("Recieved signal that power OFF is complete"); this->currentPowerState(server::Chassis::PowerState::Off); } else if((newStateUnit == CHASSIS_STATE_POWERON_TGT) && - (newStateResult == "done")) + (newStateResult == "done") && + (stateActive(CHASSIS_STATE_POWERON_TGT))) { log<level::INFO>("Recieved signal that power ON is complete"); this->currentPowerState(server::Chassis::PowerState::On); diff --git a/chassis_state_manager.hpp b/chassis_state_manager.hpp index a56924e..0c6d5a1 100644 --- a/chassis_state_manager.hpp +++ b/chassis_state_manager.hpp @@ -80,6 +80,18 @@ class Chassis : 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 Callback function on systemd state changes * * Will just do a call into the appropriate object for processing |