Attn: Quiesce host on SBE vital

When an SBE vital is detected the attention handler will transition the
host to the quiesce state. Code has also been added to make a call to
thread_stop_all (libpdbg) before transitioning host (mpipl and
quiesce cases).

Signed-off-by: Ben Tyner <ben.tyner@ibm.com>
Change-Id: Idac4680e2cb9eacedb6be7b70ae8b0d60dde66b5
diff --git a/attn/attn_common.cpp b/attn/attn_common.cpp
new file mode 100644
index 0000000..3e1f473
--- /dev/null
+++ b/attn/attn_common.cpp
@@ -0,0 +1,36 @@
+#include <libpdbg.h>
+
+#include <attn/attn_common.hpp>
+#include <sdbusplus/bus.hpp>
+
+#include <map>
+
+namespace attn
+{
+
+/** @brief Transition the host state */
+void transitionHost(const HostState i_hostState)
+{
+    thread_stop_all(); // in libpdbg
+
+    // We will be transitioning host by starting appropriate dbus target
+    std::string target = "obmc-host-quiesce@0.target"; // quiesce is default
+
+    // diagnostic mode state requested
+    if (HostState::Diagnostic == i_hostState)
+    {
+        target = "obmc-host-diagnostic-mode@0.target";
+    }
+
+    auto bus    = sdbusplus::bus::new_system();
+    auto method = bus.new_method_call(
+        "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
+        "org.freedesktop.systemd1.Manager", "StartUnit");
+
+    method.append(target);    // target unit to start
+    method.append("replace"); // mode = replace conflicting queued jobs
+
+    bus.call_noreply(method); // start the service
+}
+
+} // namespace attn
diff --git a/attn/attn_common.hpp b/attn/attn_common.hpp
new file mode 100644
index 0000000..559a9f3
--- /dev/null
+++ b/attn/attn_common.hpp
@@ -0,0 +1,21 @@
+#pragma once
+
+namespace attn
+{
+
+enum class HostState
+{
+    Quiesce,
+    Diagnostic
+};
+
+/**
+ * @brief Transition the host state
+ *
+ * We will transition the host state by starting the appropriate dbus target.
+ *
+ * @param i_hostState the state to transition the host to
+ */
+void transitionHost(const HostState i_hostState);
+
+} // namespace attn
diff --git a/attn/attn_handler.cpp b/attn/attn_handler.cpp
index d1f028d..8a5042d 100644
--- a/attn/attn_handler.cpp
+++ b/attn/attn_handler.cpp
@@ -2,11 +2,13 @@
 
 #include <analyzer/analyzer_main.hpp>
 #include <attn/attention.hpp>
+#include <attn/attn_common.hpp>
 #include <attn/attn_config.hpp>
 #include <attn/attn_handler.hpp>
 #include <attn/attn_logging.hpp>
 #include <attn/bp_handler.hpp>
 #include <attn/ti_handler.hpp>
+#include <attn/vital_handler.hpp>
 
 #include <algorithm>
 #include <iomanip>
@@ -18,15 +20,6 @@
 {
 
 /**
- * @brief Handle SBE vital attention
- *
- * @param i_attention Attention object
- * @return 0 indicates that the vital attention was successfully handled
- *         1 indicates that the vital attention was NOT successfully handled
- */
-int handleVital(Attention* i_attention);
-
-/**
  * @brief Handle checkstop attention
  *
  * @param i_attention Attention object
@@ -204,33 +197,6 @@
 }
 
 /**
- * @brief Handle SBE vital attention
- *
- * @param i_attention Attention object
- * @return 0 indicates that the vital attention was successfully handled
- *         1 indicates that the vital attention was NOT successfully handled
- */
-int handleVital(Attention* i_attention)
-{
-    int rc = RC_SUCCESS; // assume vital handled
-
-    trace<level::INFO>("vital handler started");
-
-    // if vital handling enabled, handle vital attention
-    if (false == (i_attention->getConfig()->getFlag(enVital)))
-    {
-        trace<level::INFO>("vital handling disabled");
-        rc = RC_NOT_HANDLED;
-    }
-    else
-    {
-        eventVital();
-    }
-
-    return rc;
-}
-
-/**
  * @brief Handle checkstop attention
  *
  * @param i_attention Attention object
diff --git a/attn/meson.build b/attn/meson.build
index f8a1d9d..815e038 100644
--- a/attn/meson.build
+++ b/attn/meson.build
@@ -25,6 +25,7 @@
 
 # Source files.
 attn_src = files(
+    'attn_common.cpp',
     'attn_config.cpp',
     'attention.cpp',
     'attn_handler.cpp',
@@ -33,6 +34,7 @@
     'bp_handler.cpp',
     logging_src,
     'ti_handler.cpp',
+    'vital_handler.cpp',
 )
 
 # Library dependencies.
@@ -51,4 +53,3 @@
     cpp_args : [boost_args, test_arg],
     install : false,
 )
-
diff --git a/attn/ti_handler.cpp b/attn/ti_handler.cpp
index a8daedb..35fb346 100644
--- a/attn/ti_handler.cpp
+++ b/attn/ti_handler.cpp
@@ -1,3 +1,4 @@
+#include <attn/attn_common.hpp>
 #include <attn/attn_handler.hpp>
 #include <attn/attn_logging.hpp>
 #include <attn/ti_handler.hpp>
@@ -52,29 +53,6 @@
 }
 
 /**
- * @brief Transition the host state
- *
- * We will transition the host state by starting the appropriate dbus target.
- *
- * @param i_target the dbus target to start
- */
-void transitionHost(const char* i_target)
-{
-    // We will be transitioning host by starting appropriate dbus target
-    auto bus    = sdbusplus::bus::new_system();
-    auto method = bus.new_method_call(
-        "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
-        "org.freedesktop.systemd1.Manager", "StartUnit");
-
-    method.append(i_target);  // target unit to start
-    method.append("replace"); // mode = replace conflicting queued jobs
-
-    trace<level::INFO>(i_target);
-
-    bus.call_noreply(method); // start the service
-}
-
-/**
  * @brief Handle a PHYP terminate immediate special attention
  *
  * The TI info data area will contain information pertaining to the TI
@@ -92,12 +70,12 @@
     {
         // If autoreboot is enabled we will start diagnostic mode target
         // which will ultimately mpipl the host.
-        transitionHost("obmc-host-diagnostic-mode@0.target");
+        transitionHost(HostState::Diagnostic);
     }
     else
     {
         // If autoreboot is disabled we will quiesce the host
-        transitionHost("obmc-host-quiesce@0.target");
+        transitionHost(HostState::Quiesce);
     }
 
     // gather additional data for PEL
@@ -213,13 +191,13 @@
             // Until HB dump support available just quiesce the host - once
             // dump support is available the dump component will transition
             // (ipl/halt) the host.
-            transitionHost("obmc-host-quiesce@0.target");
+            transitionHost(HostState::Quiesce);
         }
         else
         {
             // Quiese the host - when the host is quiesced it will either
             // "halt" or IPL depending on autoreboot setting.
-            transitionHost("obmc-host-quiesce@0.target");
+            transitionHost(HostState::Quiesce);
         }
     }
 
diff --git a/attn/vital_handler.cpp b/attn/vital_handler.cpp
new file mode 100644
index 0000000..15a7a68
--- /dev/null
+++ b/attn/vital_handler.cpp
@@ -0,0 +1,41 @@
+#include <attn/attention.hpp>
+#include <attn/attn_common.hpp>
+#include <attn/attn_handler.hpp>
+#include <attn/attn_logging.hpp>
+#include <sdbusplus/bus.hpp>
+
+namespace attn
+{
+
+/**
+ * @brief Handle SBE vital attention
+ *
+ * @param i_attention Attention object
+ * @return 0 indicates that the vital attention was successfully handled
+ *         1 indicates that the vital attention was NOT successfully handled
+ */
+int handleVital(Attention* i_attention)
+{
+    int rc = RC_SUCCESS; // assume vital handled
+
+    trace<level::INFO>("vital handler started");
+
+    // if vital handling enabled, handle vital attention
+    if (false == (i_attention->getConfig()->getFlag(enVital)))
+    {
+        trace<level::INFO>("vital handling disabled");
+        rc = RC_NOT_HANDLED;
+    }
+    else
+    {
+        // transition host state after analyses
+        transitionHost(HostState::Quiesce);
+
+        // generate pel
+        eventVital();
+    }
+
+    return rc;
+}
+
+} // namespace attn
diff --git a/attn/vital_handler.hpp b/attn/vital_handler.hpp
new file mode 100644
index 0000000..e1ae4ac
--- /dev/null
+++ b/attn/vital_handler.hpp
@@ -0,0 +1,15 @@
+#pragma once
+
+namespace attn
+{
+
+/**
+ * @brief Handle SBE vital attention
+ *
+ * @param i_attention Attention object
+ * @return 0 indicates that the vital attention was successfully handled
+ *         1 indicates that the vital attention was NOT successfully handled
+ */
+int handleVital(Attention* i_attention);
+
+} // namespace attn