crit-service: start bmc quiesce target on fail

This target will be monitored by the BMC state target and used to tell
external clients when the BMC is in a bad state due to a critical
service failing

Signed-off-by: Andrew Geissler <geissonator@yahoo.com>
Change-Id: Ibf0460bef9b3ac2a96e8a294e6de122463530713
diff --git a/systemd_target_signal.cpp b/systemd_target_signal.cpp
index cc3cf4c..88b1aad 100644
--- a/systemd_target_signal.cpp
+++ b/systemd_target_signal.cpp
@@ -39,6 +39,30 @@
     }
 }
 
+void SystemdTargetLogging::startBmcQuiesceTarget()
+{
+    auto method = this->bus.new_method_call(
+        "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
+        "org.freedesktop.systemd1.Manager", "StartUnit");
+
+    // TODO: Enhance when needed to support multiple-bmc instance systems
+    method.append("obmc-bmc-service-quiesce@0.target");
+    method.append("replace");
+    try
+    {
+        this->bus.call_noreply(method);
+    }
+    catch (const sdbusplus::exception::exception& e)
+    {
+        error("Failed to start BMC quiesce target, exception:{ERROR}", "ERROR",
+              e);
+        // just continue, this is error path anyway so we're just doing what
+        // we can
+    }
+
+    return;
+}
+
 void SystemdTargetLogging::logError(const std::string& errorLog,
                                     const std::string& result,
                                     const std::string& unit)
@@ -94,6 +118,8 @@
 
             // Generate a BMC dump when a critical service fails
             createBmcDump();
+            // Enter BMC Quiesce when a critical service fails
+            startBmcQuiesceTarget();
             return (std::string{
                 "xyz.openbmc_project.State.Error.CriticalServiceFailure"});
         }
diff --git a/systemd_target_signal.hpp b/systemd_target_signal.hpp
index 27e0334..755c817 100644
--- a/systemd_target_signal.hpp
+++ b/systemd_target_signal.hpp
@@ -75,6 +75,9 @@
     /** @brief Call phosphor-dump-manager to create BMC dump */
     void createBmcDump();
 
+    /** @brief Start BMC Quiesce Target to indicate critical service failure */
+    void startBmcQuiesceTarget();
+
     /** @brief Call phosphor-logging to create error
      *
      * @param[in]  error      - The error to log
diff --git a/target_files/meson.build b/target_files/meson.build
index 67a23d8..3523127 100644
--- a/target_files/meson.build
+++ b/target_files/meson.build
@@ -1,4 +1,5 @@
 unit_files = [
+    'obmc-bmc-service-quiesce@.target',
     'obmc-chassis-hard-poweroff@.target',
     'obmc-chassis-powered-off@.target',
     'obmc-chassis-poweroff@.target',
diff --git a/target_files/obmc-bmc-service-quiesce@.target b/target_files/obmc-bmc-service-quiesce@.target
new file mode 100644
index 0000000..23d588b
--- /dev/null
+++ b/target_files/obmc-bmc-service-quiesce@.target
@@ -0,0 +1,3 @@
+[Unit]
+Description=BMC Quiesce Target
+RefuseManualStop=yes