Handle response from host for soft power off request
Change-Id: Ia923eff57f855dc88cb04db13590ae1a58a502fd
Signed-off-by: Vishwanatha Subbanna <vishwa@linux.vnet.ibm.com>
diff --git a/softoff/mainapp.cpp b/softoff/mainapp.cpp
index f5fbf18..9ed34dd 100644
--- a/softoff/mainapp.cpp
+++ b/softoff/mainapp.cpp
@@ -19,10 +19,10 @@
#include "config.h"
#include "timer.hpp"
-using namespace phosphor::logging;
-
int main(int argc, char** argv)
{
+ using namespace phosphor::logging;
+
// systemd event handler
sd_event* events = nullptr;
@@ -32,13 +32,14 @@
// Add systemd object manager.
sdbusplus::server::manager::manager(bus, SOFTOFF_OBJPATH);
- // sd_event object
+ // sd_event object. StateManager wants that this applicatin return '0'
+ // always.
auto r = sd_event_default(&events);
if (r < 0)
{
log<level::ERR>("Failure to create sd_event handler",
entry("ERROR=%s", strerror(-r)));
- return -1;
+ return 0;
}
// Attach the bus to sd_event to service user requests
@@ -47,12 +48,13 @@
// Create the SoftPowerOff object.
phosphor::ipmi::SoftPowerOff powerObj(bus, events, SOFTOFF_OBJPATH);
- /** @brief Claim the bus */
+ // Claim the bus. Delaying it until sending SMS_ATN may result
+ // in a race condition between this available and IPMI trying to send
+ // message as a reponse to ack from host.
bus.request_name(SOFTOFF_BUSNAME);
- /** @brief Wait for client requests until this application has processed
- * at least one successful SoftPowerOff
- */
+ // Wait for client requests until this application has processed
+ // at least one successful SoftPowerOff or we timed out
while(!powerObj.isCompleted() && !powerObj.isTimerExpired())
{
// -1 denotes wait for ever
diff --git a/softoff/softoff.cpp b/softoff/softoff.cpp
index 49b6f26..e88096f 100644
--- a/softoff/softoff.cpp
+++ b/softoff/softoff.cpp
@@ -46,5 +46,42 @@
return;
}
+/** @brief Host Response handler */
+auto SoftPowerOff::responseReceived(HostResponse response) -> HostResponse
+{
+ using namespace std::chrono;
+ using namespace phosphor::logging;
+
+ if (response == HostResponse::SoftOffReceived)
+ {
+ // Need to stop the running timer and then start a new timer
+ auto time = duration_cast<microseconds>(
+ seconds(IPMI_HOST_SHUTDOWN_COMPLETE_TIMEOUT_SECS));
+ auto r = timer.startTimer(time);
+ if (r < 0)
+ {
+ log<level::ERR>("Failure to start HostQuiesce wait timer",
+ entry("ERROR=%s", strerror(-r)));
+ }
+ }
+ else if (response == HostResponse::HostShutdown)
+ {
+ // Disable the timer since Host has quiesced and we are
+ // done with soft power off part
+ auto r = timer.setTimer(SD_EVENT_OFF);
+ if (r < 0)
+ {
+ log<level::ERR>("Failure to STOP the timer",
+ entry("ERROR=%s", strerror(-r)));
+ }
+
+ // This marks the completion of soft power off sequence.
+ completed = true;
+ }
+
+ return sdbusplus::xyz::openbmc_project::Ipmi::Internal
+ ::server::SoftPowerOff::responseReceived(response);
+}
+
} // namespace ipmi
} // namespace phosphor
diff --git a/softoff/softoff.hpp b/softoff/softoff.hpp
index 06f3861..da88fc5 100644
--- a/softoff/softoff.hpp
+++ b/softoff/softoff.hpp
@@ -55,6 +55,14 @@
return timer.isExpired();
}
+ /** @brief overloaded property setter function
+ *
+ * @param[in] value - One of SoftOffReceived / HostShutdown
+ *
+ * @return Success or exception thrown
+ */
+ HostResponse responseReceived(HostResponse value) override;
+
private:
// Need this to send SMS_ATTN
// TODO : Switch over to using mapper service in a different patch