Generate errorlog when timer expires waiting for host to shutdown

Fixes openbmc/openbmc#930

Change-Id: I1780071d5cbef23df88c17fe131098f54f54f25f
Signed-off-by: Vishwanatha Subbanna <vishwa@linux.vnet.ibm.com>
diff --git a/softoff/Makefile.am b/softoff/Makefile.am
index b8266b3..35734d2 100644
--- a/softoff/Makefile.am
+++ b/softoff/Makefile.am
@@ -15,8 +15,14 @@
 CLEANFILES = xyz/openbmc_project/Ipmi/Internal/SoftPowerOff/server.cpp \
              xyz/openbmc_project/Ipmi/Internal/SoftPowerOff/server.hpp
 
-phosphor_softpoweroff_LDFLAGS = $(SYSTEMD_LIBS) $(SDBUSPLUS_LIBS)
-phosphor_softpoweroff_CXXFLAGS = $(SYSTEMD_CFLAGS) $(SDBUSPLUS_CFLAGS)
+phosphor_softpoweroff_LDFLAGS = $(SYSTEMD_LIBS) \
+								$(SDBUSPLUS_LIBS) \
+								$(PHOSPHOR_LOGGING_LIBS) \
+								$(PHOSPHOR_DBUS_INTERFACES_LIBS)
+phosphor_softpoweroff_CXXFLAGS = $(SYSTEMD_CFLAGS) \
+								 $(SDBUSPLUS_CFLAGS) \
+								 $(PHOSPHOR_LOGGING_CFLAGS) \
+								 $(PHOSPHOR_DBUS_INTERFACES_CFLAGS)
 
 xyz/openbmc_project/Ipmi/Internal/SoftPowerOff/server.cpp: ${top_srcdir}/xyz/openbmc_project/Ipmi/Internal/SoftPowerOff.interface.yaml
 	@mkdir -p `dirname $@`
diff --git a/softoff/mainapp.cpp b/softoff/mainapp.cpp
index 9ed34dd..1f037fc 100644
--- a/softoff/mainapp.cpp
+++ b/softoff/mainapp.cpp
@@ -14,7 +14,9 @@
  * limitations under the License.
  */
 #include <systemd/sd-event.h>
-#include <phosphor-logging/log.hpp>
+#include <phosphor-logging/elog.hpp>
+#include <phosphor-logging/elog-errors.hpp>
+#include <xyz/openbmc_project/State/Host/error.hpp>
 #include "softoff.hpp"
 #include "config.h"
 #include "timer.hpp"
@@ -45,14 +47,14 @@
     // Attach the bus to sd_event to service user requests
     bus.attach_event(events, SD_EVENT_PRIORITY_NORMAL);
 
-    // Create the SoftPowerOff object.
-    phosphor::ipmi::SoftPowerOff powerObj(bus, events, SOFTOFF_OBJPATH);
-
     // 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);
 
+    // Create the SoftPowerOff object.
+    phosphor::ipmi::SoftPowerOff powerObj(bus, events, SOFTOFF_OBJPATH);
+
     // Wait for client requests until this application has processed
     // at least one successful SoftPowerOff or we timed out
     while(!powerObj.isCompleted() && !powerObj.isTimerExpired())
@@ -67,6 +69,25 @@
         }
     }
 
+    // Log an error if we timed out after getting Ack for SMS_ATN and before
+    // getting the Host Shutdown response
+    if(powerObj.isTimerExpired() && (powerObj.responseReceived() ==
+            phosphor::ipmi::Base::SoftPowerOff::HostResponse::SoftOffReceived))
+    {
+        try
+        {
+            elog<sdbusplus::xyz::openbmc_project::State
+                    ::Host::Error::SoftOffTimeout>(
+                 prev_entry<phosphor::logging::xyz::openbmc_project::State
+                    ::Host::SoftOffTimeout::TIMEOUT_IN_MSEC>());
+        }
+        catch (sdbusplus::xyz::openbmc_project::State::Host::Error
+                    ::SoftOffTimeout& elog)
+        {
+            commit(elog.name());
+        }
+    }
+
     // Cleanup the event handler
     events = sd_event_unref(events);
 
diff --git a/softoff/softoff.cpp b/softoff/softoff.cpp
index e88096f..88aa6cf 100644
--- a/softoff/softoff.cpp
+++ b/softoff/softoff.cpp
@@ -22,7 +22,7 @@
 namespace ipmi
 {
 
-/** @brief Send the SMS_ATN to host if value is set */
+// Sends the SMS_ATN to host if value is set
 void SoftPowerOff::sendSMSAttn()
 {
     using namespace std::chrono;
@@ -46,7 +46,13 @@
     return;
 }
 
-/** @brief Host Response handler */
+// Starts a timer
+int SoftPowerOff::startTimer(const std::chrono::microseconds& usec)
+{
+    return timer.startTimer(usec);
+}
+
+// Host Response handler
 auto SoftPowerOff::responseReceived(HostResponse response) -> HostResponse
 {
     using namespace std::chrono;
@@ -57,12 +63,19 @@
         // 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);
+        auto r = startTimer(time);
         if (r < 0)
         {
-            log<level::ERR>("Failure to start HostQuiesce wait timer",
+            log<level::ERR>("Failure to start Host shutdown wait timer",
                     entry("ERROR=%s", strerror(-r)));
         }
+        else
+        {
+            log<level::INFO>("Timer started waiting for host to shutdown",
+                    entry("TIMEOUT_IN_MSEC=%llu",
+                        duration_cast<milliseconds>(seconds
+                            (IPMI_HOST_SHUTDOWN_COMPLETE_TIMEOUT_SECS))));
+        }
     }
     else if (response == HostResponse::HostShutdown)
     {
diff --git a/softoff/softoff.hpp b/softoff/softoff.hpp
index da88fc5..f0e992c 100644
--- a/softoff/softoff.hpp
+++ b/softoff/softoff.hpp
@@ -63,6 +63,17 @@
          */
         HostResponse responseReceived(HostResponse value) override;
 
+        /** @brief Using the base class's getter method */
+        using Base::SoftPowerOff::responseReceived;
+
+        /** @brief Calls to start a timer
+         *
+         *  @param[in] usec - Time in microseconds
+         *
+         *  @return Success or exception thrown
+         */
+        int startTimer(const std::chrono::microseconds& usec);
+
     private:
         // Need this to send SMS_ATTN
         // TODO : Switch over to using mapper service in a different patch