Request hostboot dump when Host State is 'Running'

When CurrentHostStatus is not in 'Running' state, either host is 'Off'
or current state is changed by HW dump to a state other than 'Running'
and may have initiated/created the dump. In these cases, there is
no need to initiate hostboot dump. This commit allows initiating
hostboot dump collection when the current host state is 'Running'
and the watchdog times out.

Testing:
Run watchdog_timeout and check the following entries in the journal log:
'Running' state:
Mar 03 12:22:34 <xxxx> watchdog_timeout[3626]: Host did not respond
within watchdog timeout interval
Mar 03 12:22:34 <xxxx> watchdog_timeout[3626]: Handle Hostboot boot
failure
Mar 03 12:22:34 <xxxx> watchdog_timeout[3626]: hostboot dump
requested
Mar 03 12:23:26 <xxxx> watchdog_timeout[3626]:
/xyz/openbmc_project/dump/hostboot/entry/20000028
Mar 03 12:23:26 <xxxx> watchdog_timeout[3626]:
xyz.openbmc_project.Common.Progress.OperationStatus.Completed
Mar 03 12:23:26 <xxxx> watchdog_timeout[3626]: dump collection
completed

'Quiesced' state:
Mar 03 12:26:04 <xxxx> watchdog_timeout[3917]: Host did not respond
within watchdog timeout interval
Mar 03 12:26:04 <xxxx> watchdog_timeout[3917]: Host is not in
'Running' state. Dump maybe already occurring, skipping this dump
request...

Signed-off-by: Shantappa Teekappanavar <sbteeks@yahoo.com>
Change-Id: I7245fef1639299bf501667eef48e275a93307c00
diff --git a/watchdog/watchdog_dbus.cpp b/watchdog/watchdog_dbus.cpp
index 7a4c6d6..fb911eb 100644
--- a/watchdog/watchdog_dbus.cpp
+++ b/watchdog/watchdog_dbus.cpp
@@ -1,3 +1,4 @@
+#include <fmt/format.h>
 #include <unistd.h>
 
 #include <phosphor-logging/log.hpp>
@@ -129,5 +130,44 @@
     return plid; // platform log id or 0
 }
 
+bool isHostStateRunning()
+{
+    constexpr auto path = "/xyz/openbmc_project/state/host0";
+    constexpr auto interface = "xyz.openbmc_project.State.Host";
+    constexpr auto extended = "org.freedesktop.DBus.Properties";
+    constexpr auto function = "Get";
+
+    sdbusplus::message::message method;
+
+    if (0 == dbusMethod(path, interface, function, method, extended))
+    {
+        try
+        {
+            method.append(interface, "CurrentHostState");
+            auto bus = sdbusplus::bus::new_system();
+            auto response = bus.call(method);
+            std::variant<std::string> reply;
+
+            response.read(reply);
+            std::string currentHostState(std::get<std::string>(reply));
+
+            if (currentHostState ==
+                "xyz.openbmc_project.State.Host.HostState.Running")
+            {
+                return true;
+            }
+        }
+        catch (const sdbusplus::exception::exception& e)
+        {
+            log<level::ERR>(
+                fmt::format("Failed to read CurrentHostState property ({})",
+                            e.what())
+                    .c_str());
+        }
+    }
+
+    return false;
+}
+
 } // namespace dump
 } // namespace watchdog
diff --git a/watchdog/watchdog_dbus.hpp b/watchdog/watchdog_dbus.hpp
index 88d2ca6..e90c940 100644
--- a/watchdog/watchdog_dbus.hpp
+++ b/watchdog/watchdog_dbus.hpp
@@ -51,5 +51,12 @@
                    std::map<std::string, std::string>& additional,
                    const std::vector<FFDCTuple>& ffdc);
 
+/**
+ * @brief Query host state
+ *
+ * @return true if the CurrentHostState is 'Running'
+ */
+bool isHostStateRunning();
+
 } // namespace dump
 } // namespace watchdog
diff --git a/watchdog_timeout.cpp b/watchdog_timeout.cpp
index 5c374ef..527256a 100644
--- a/watchdog_timeout.cpp
+++ b/watchdog_timeout.cpp
@@ -55,6 +55,15 @@
         bool primaryIplDone = sbe::isPrimaryIplDone();
         if (primaryIplDone)
         {
+            // Collect hostboot dump only if the host is in 'Running' state
+            if (!isHostStateRunning())
+            {
+                log<level::INFO>(
+                    "CurrentHostState is not in 'Running' state. Dump maybe "
+                    "already occurring, skipping this dump request...");
+                return EXIT_SUCCESS;
+            }
+
             // SBE boot done, Need to collect hostboot dump
             log<level::INFO>("Handle Hostboot boot failure");
             triggerHostbootDump(timeout);