Add support for system dump

When a system dump entry is encountered, a crash target is
set to start the memory preserving reboot.

Change-Id: I8f69a780e8a76b25b0936efb3c1a5ea10b285518
Signed-off-by: Dhruvaraj Subhashchandran <dhruvaraj@in.ibm.com>
diff --git a/dump/dump_monitor.cpp b/dump/dump_monitor.cpp
index 6595cf5..0afe7ca 100644
--- a/dump/dump_monitor.cpp
+++ b/dump/dump_monitor.cpp
@@ -118,7 +118,7 @@
             {
                 lg2::info("An entry created, collecting a new dump {DUMP}",
                           "DUMP", interfaceName);
-                executeCollectionScript(objectPath, it->second);
+                initiateDumpCollection(objectPath, interfaceName, it->second);
             }
         }
     }
@@ -147,4 +147,55 @@
     }
 }
 
+void DumpMonitor::startMpReboot(
+    const sdbusplus::message::object_path& objectPath)
+{
+    constexpr auto systemdService = "org.freedesktop.systemd1";
+    constexpr auto systemdObjPath = "/org/freedesktop/systemd1";
+    constexpr auto systemdInterface = "org.freedesktop.systemd1.Manager";
+    constexpr auto diagModeTarget = "obmc-host-crash@0.target";
+
+    try
+    {
+        auto b = sdbusplus::bus::new_default();
+        auto method = b.new_method_call(systemdService, systemdObjPath,
+                                        systemdInterface, "StartUnit");
+        method.append(diagModeTarget); // unit to activate
+        method.append("replace");
+        b.call_noreply(method);
+    }
+    catch (const sdbusplus::exception_t& e)
+    {
+        lg2::error("Failed to start memory preserving reboot");
+        updateProgressStatus(objectPath, dumpStatusFailed);
+    }
+}
+
+void DumpMonitor::initiateDumpCollection(const std::string& path,
+                                         const std::string& intf,
+                                         const PropertyMap& properties)
+{
+    using namespace sdbusplus::common::xyz::openbmc_project::dump::entry;
+    if (intf == System::interface)
+    {
+        // Find the SystemImpact property, if this property is not
+        // available assume disruptive.
+        auto systemImpactIt = properties.find("SystemImpact");
+        if (systemImpactIt != properties.end() &&
+            std::get<std::string>(systemImpactIt->second) !=
+                System::convertSystemImpactToString(
+                    System::SystemImpact::Disruptive))
+        {
+            lg2::info("Ignoring non-disruptive system dump {PATH}", "PATH",
+                      path);
+            return;
+        }
+        startMpReboot(path);
+    }
+    else
+    {
+        executeCollectionScript(path, properties);
+    }
+}
+
 } // namespace openpower::dump
diff --git a/dump/dump_monitor.hpp b/dump/dump_monitor.hpp
index c9c4021..b499dba 100644
--- a/dump/dump_monitor.hpp
+++ b/dump/dump_monitor.hpp
@@ -10,6 +10,7 @@
 #include <sdbusplus/bus.hpp>
 #include <sdbusplus/bus/match.hpp>
 #include <xyz/openbmc_project/Common/Progress/common.hpp>
+#include <xyz/openbmc_project/Dump/Entry/System/common.hpp>
 
 #include <iostream>
 #include <string>
@@ -20,6 +21,7 @@
 
 using PropertyMap = std::map<std::string, std::variant<uint32_t, std::string>>;
 using InterfaceMap = std::map<std::string, PropertyMap>;
+
 /**
  * @class DumpMonitor
  * @brief Monitors DBus signals for dump creation and handles them.
@@ -57,7 +59,7 @@
     /* @brief Monitores dump interfaces */
     const std::vector<std::string> monitoredInterfaces = {
         "com.ibm.Dump.Entry.Hardware", "com.ibm.Dump.Entry.Hostboot",
-        "com.ibm.Dump.Entry.SBE"};
+        "com.ibm.Dump.Entry.SBE", "xyz.openbmc_project.Dump.Entry.System"};
 
     /* @brief InterfaceAdded match */
     sdbusplus::bus::match_t match;
@@ -129,6 +131,24 @@
         }
         return 0;
     }
+
+    /**
+     * @brief Initiates the dump collection process based on the given interface
+     *        and properties.
+     *
+     * @param[in] path The object path of the dump entry.
+     * @param[in] intf The interface type of the dump entry.
+     * @param[in] properties The properties of the dump entry.
+     */
+    void initiateDumpCollection(const std::string& path,
+                                const std::string& intf,
+                                const PropertyMap& properties);
+
+    /**
+     * @brief Initiates a memory-preserving reboot by starting the
+     *        appropriate systemd unit.
+     */
+    void startMpReboot(const sdbusplus::message::object_path& objectPath);
 };
 
 } // namespace openpower::dump