Refactor to pass errors to watch through config YAML

Add errors to watch for through error YAML file
Add support for checkstop error type

Tested:
Generating dumps for elog, core, checkstop type errors.

Change-Id: Idd00ace2e3d0c472a74ec142e6d150e55e843a6f
Signed-off-by: Marri Devender Rao <devenrao@in.ibm.com>
diff --git a/Makefile.am b/Makefile.am
index 30f0331..9279a1d 100755
--- a/Makefile.am
+++ b/Makefile.am
@@ -55,7 +55,8 @@
 # Be sure to build needed files before compiling
 BUILT_SOURCES = \
 	xyz/openbmc_project/Dump/Internal/Create/server.cpp \
-	xyz/openbmc_project/Dump/Internal/Create/server.hpp
+	xyz/openbmc_project/Dump/Internal/Create/server.hpp \
+	errors_map.hpp
 
 CLEANFILES=${BUILT_SOURCES}
 
@@ -71,3 +72,11 @@
 	@mkdir -p `dirname $@`
 	$(SDBUSPLUSPLUS) -r $(srcdir) interface server-header \
 xyz.openbmc_project.Dump.Internal.Create > $@
+
+ERROR_TEMPLATE ?= ${abs_srcdir}/errors_map.mako.hpp
+ERROR_REQ_FILES_TO_GEN ?= ${abs_srcdir}/errors_map_gen.py \
+	${ERROR_TEMPLATE}
+
+EXTRA_DIST = $(ERROR_REQ_FILES_TO_GEN)
+errors_map.hpp: $(ERROR_REQ_FILES_TO_GEN)
+	$(AM_V_at)$(PYTHON) ${abs_srcdir}/errors_map_gen.py -i ${ERROR_MAP_YAML}
diff --git a/configure.ac b/configure.ac
index e108087..114e722 100644
--- a/configure.ac
+++ b/configure.ac
@@ -96,5 +96,9 @@
       [Turn on ubi workaround for core file])]
 )
 
+AC_ARG_VAR(ERROR_MAP_YAML, [YAML filepath containing error object paths])
+AS_IF([test "x$ERROR_MAP_YAML" == "x"], \
+    [ERROR_MAP_YAML="example_errors_watch.yaml"])
+
 AC_CONFIG_FILES([Makefile])
 AC_OUTPUT
diff --git a/dump_manager.cpp b/dump_manager.cpp
index d9326e0..21fca8a 100644
--- a/dump_manager.cpp
+++ b/dump_manager.cpp
@@ -40,12 +40,6 @@
 uint32_t Manager::captureDump(Type type,
                               const std::vector<std::string>& fullPaths)
 {
-    // Type to dreport type  string map
-    static const std::map<Type, std::string> typeMap = {
-        {Type::ApplicationCored, "core"},
-        {Type::UserRequested, "user"},
-        {Type::InternalFailure, "elog"}};
-
     // Get Dump size.
     auto size = getAllowedSize();
 
@@ -58,7 +52,7 @@
         dumpPath /= id;
 
         // get dreport type map entry
-        auto tempType = typeMap.find(type);
+        auto tempType = TypeMap.find(type);
 
         execl("/usr/bin/dreport", "dreport", "-d", dumpPath.c_str(), "-i",
               id.c_str(), "-s", std::to_string(size).c_str(), "-q", "-v", "-p",
diff --git a/dump_manager.hpp b/dump_manager.hpp
index f414752..694cf7b 100644
--- a/dump_manager.hpp
+++ b/dump_manager.hpp
@@ -37,6 +37,13 @@
 
 using Watch = phosphor::dump::inotify::Watch;
 
+// Type to dreport type  string map
+static const std::map<Type, std::string> TypeMap = {
+    {Type::ApplicationCored, "core"},
+    {Type::UserRequested, "user"},
+    {Type::InternalFailure, "elog"},
+    {Type::Checkstop, "checkstop"}};
+
 /** @class Manager
  *  @brief OpenBMC Dump  manager implementation.
  *  @details A concrete implementation for the
diff --git a/elog_watch.cpp b/elog_watch.cpp
index 7369783..0a7789c 100644
--- a/elog_watch.cpp
+++ b/elog_watch.cpp
@@ -4,9 +4,11 @@
 
 #include "dump_internal.hpp"
 #include "dump_serialize.hpp"
+#include "errors_map.hpp"
 #include "xyz/openbmc_project/Dump/Create/error.hpp"
 
 #include <cereal/cereal.hpp>
+#include <fstream>
 #include <phosphor-logging/elog.hpp>
 #include <sdbusplus/exception.hpp>
 
@@ -22,8 +24,6 @@
 
 using namespace phosphor::logging;
 constexpr auto LOG_PATH = "/xyz/openbmc_project/logging";
-constexpr auto INTERNAL_FAILURE =
-    "xyz.openbmc_project.Common.Error.InternalFailure";
 using Message = std::string;
 using Attributes = sdbusplus::message::variant<Message>;
 using AttributeName = std::string;
@@ -57,8 +57,6 @@
 
 void Watch::addCallback(sdbusplus::message::message& msg)
 {
-    using Type =
-        sdbusplus::xyz::openbmc_project::Dump::Internal::server::Create::Type;
     using QuotaExceeded =
         sdbusplus::xyz::openbmc_project::Dump::Create::Error::QuotaExceeded;
 
@@ -112,9 +110,20 @@
         return;
     }
 
-    if (data != INTERNAL_FAILURE)
+    EType errorType;
+    for (const auto& [type, errorList] : errorMap)
     {
-        // Not a InternalFailure, skip
+        auto error = std::find(errorList.begin(), errorList.end(), data);
+        if (error != errorList.end())
+        {
+            errorType = type;
+            break;
+        }
+    }
+
+    // error not supported in the configuration
+    if (errorType.empty())
+    {
         return;
     }
 
@@ -129,8 +138,13 @@
 
         phosphor::dump::elog::serialize(elogList);
 
-        // Call internal create function to initiate dump
-        iMgr.IMgr::create(Type::InternalFailure, fullPaths);
+        auto item = std::find_if(
+            TypeMap.begin(), TypeMap.end(),
+            [errorType](const auto& err) { return (err.second == errorType); });
+        if (item != TypeMap.end())
+        {
+            iMgr.IMgr::create((*item).first, fullPaths);
+        }
     }
     catch (QuotaExceeded& e)
     {
diff --git a/errors_map.mako.hpp b/errors_map.mako.hpp
new file mode 100644
index 0000000..b04f00e
--- /dev/null
+++ b/errors_map.mako.hpp
@@ -0,0 +1,18 @@
+## This file is a template.  The comment below is emitted
+## into the rendered file; feel free to edit this file.
+// !!! WARNING: This is a GENERATED Code..Please do NOT Edit !!!
+#include <map>
+using EType = std::string;
+using Error = std::string;
+using ErrorList = std::vector<Error>;
+using ErrorMap = std::map<EType, std::vector<Error>>;
+
+const ErrorMap errorMap = {
+% for key, errors in errDict.items():
+    {"${key}", {
+    % for error in errors:
+        "${error}",
+    % endfor
+    }},
+% endfor
+};
diff --git a/errors_map_gen.py b/errors_map_gen.py
new file mode 100755
index 0000000..6e60610
--- /dev/null
+++ b/errors_map_gen.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+
+import os
+import yaml
+from mako.template import Template
+import argparse
+
+def main():
+    parser = argparse.ArgumentParser(
+        description="OpenPOWER error map code generator")
+
+    parser.add_argument(
+        '-i', '--errors_map_yaml', dest='errors_map_yaml',
+        default='errors_watch.yaml', help='input errors watch yaml file to parse')
+    args = parser.parse_args()
+
+    with open(os.path.join(script_dir, args.errors_map_yaml), 'r') as fd:
+        yamlDict = yaml.safe_load(fd)
+
+        # Render the mako template
+        template = os.path.join(script_dir, 'errors_map.mako.hpp')
+        t = Template(filename=template)
+        with open('errors_map.hpp', 'w') as fd:
+            fd.write(
+                t.render(
+                    errDict=yamlDict))
+
+
+if __name__ == '__main__':
+    script_dir = os.path.dirname(os.path.realpath(__file__))
+    main()
\ No newline at end of file
diff --git a/example_errors_watch.yaml b/example_errors_watch.yaml
new file mode 100644
index 0000000..eb47ec6
--- /dev/null
+++ b/example_errors_watch.yaml
@@ -0,0 +1,2 @@
+elog:

+    - xyz.openbmc_project.Common.Error.InternalFailure

diff --git a/tools/dreport.d/dreport b/tools/dreport.d/dreport
index 7fc1c32..3b6dce3 100755
--- a/tools/dreport.d/dreport
+++ b/tools/dreport.d/dreport
@@ -43,6 +43,7 @@
 declare -rx TYPE_USER="user"
 declare -rx TYPE_CORE="core"
 declare -rx TYPE_ELOG="elog"
+declare -rx TYPE_CHECKSTOP="checkstop"
 declare -rx SUMMARY_LOG="summary.log"
 declare -rx DREPORT_LOG="dreport.log"
 declare -rx TMP_DIR="/tmp"
@@ -94,6 +95,11 @@
             elog_id=$(basename "$optional_path")
             set_elog_pid
             ;;
+        $TYPE_CHECKSTOP)
+            log_summary "CHECKSTOP: $optional_path"
+            elog_id=$(basename "$optional_path")
+            set_elog_pid
+            ;;
 
         $SUMMARY_DUMP)
             #No data collection is required.
@@ -190,7 +196,8 @@
     #Type
     if [[ !($dump_type = $TYPE_USER || \
             $dump_type = $TYPE_CORE || \
-            $dump_type = $TYPE_ELOG) ]]; then
+            $dump_type = $TYPE_ELOG || \
+            $dump_type = $TYPE_CHECKSTOP) ]]; then
        log_error "Invalid -type, Only summary log is available"
        dump_type=$SUMMARY_DUMP
     fi
diff --git a/tools/dreport.d/sample.conf b/tools/dreport.d/sample.conf
index 8a0e24a..45f5e59 100644
--- a/tools/dreport.d/sample.conf
+++ b/tools/dreport.d/sample.conf
@@ -8,3 +8,4 @@
 1: core
 2: user
 3: elog
+4: checkstop
diff --git a/xyz/openbmc_project/Dump/Internal/Create.interface.yaml b/xyz/openbmc_project/Dump/Internal/Create.interface.yaml
index bb4a74f..ddb405f 100644
--- a/xyz/openbmc_project/Dump/Internal/Create.interface.yaml
+++ b/xyz/openbmc_project/Dump/Internal/Create.interface.yaml
@@ -34,5 +34,8 @@
         - name: InternalFailure
           description: >
               Dump triggered due to InternalFailure type error commit.
+        - name: Checkstop
+          description: >
+              Dump triggered due to Checkstop type error commit.
 
 # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4