summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh D. King <jdking@us.ibm.com>2017-03-02 10:58:11 -0600
committerPatrick Williams <patrick@stwcx.xyz>2017-04-17 17:21:32 +0000
commit929ef70706fa339e6cc7adbed32e54624de1b813 (patch)
tree929818f8854e9982913b447f25e5fb5ec801ca81
parentca3579226904b666c2436ebe82d9d7723c97fb51 (diff)
downloadphosphor-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.cpp67
-rw-r--r--host_state_manager.hpp12
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
OpenPOWER on IntegriCloud