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>
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 @@
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_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 @@
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 @@
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);