OpenPOWER: Limit User-Requested System Dumps

System dumps can be several gigabytes in size. To conserve space,
only one dump is stored at a time. When a new dump is requested,
the existing dump will be discarded while creating a new one.
In the case of system-generated dumps, which are triggered by
critical errors, it is permissible to initiate a new dump even
if an existing dump is already present in the host memory
This commit adds a restriction on initiating new user-requested system
dumps while a system dump is in progress or if one is already stored
in host memory.

New user-requested system dumps will be allowed once the existing
dump is deleted or offloaded.

This change applies only to user-requested dumps and does not impact
system generated dumps.

Test:
- Initiate system dump when another dump in progress and verified
  a Unavailable was returned
- Force a system generated system dump when one dump is present
  a Unavailable was returned

Signed-off-by: Dhruvaraj Subhashchandran <dhruvaraj@in.ibm.com>
Change-Id: I4598912b0761669859f84a43ab4c60f47664b1e6
diff --git a/dump-extensions/openpower-dumps/op_dump_util.cpp b/dump-extensions/openpower-dumps/op_dump_util.cpp
index e8b2497..c56b902 100644
--- a/dump-extensions/openpower-dumps/op_dump_util.cpp
+++ b/dump-extensions/openpower-dumps/op_dump_util.cpp
@@ -1,5 +1,6 @@
 #include "op_dump_util.hpp"
 
+#include "dump_utils.hpp"
 #include "xyz/openbmc_project/Common/error.hpp"
 #include "xyz/openbmc_project/Dump/Create/error.hpp"
 
@@ -52,6 +53,60 @@
     return isEnabled;
 }
 
+BIOSAttrValueType readBIOSAttribute(const std::string& attrName,
+                                    sdbusplus::bus::bus& bus)
+{
+    std::tuple<std::string, BIOSAttrValueType, BIOSAttrValueType> attrVal;
+    auto method = bus.new_method_call(
+        "xyz.openbmc_project.BIOSConfigManager",
+        "/xyz/openbmc_project/bios_config/manager",
+        "xyz.openbmc_project.BIOSConfig.Manager", "GetAttribute");
+    method.append(attrName);
+    try
+    {
+        auto result = bus.call(method);
+        result.read(std::get<0>(attrVal), std::get<1>(attrVal),
+                    std::get<2>(attrVal));
+    }
+    catch (const sdbusplus::exception::SdBusError& e)
+    {
+        lg2::error("Failed to read BIOS Attribute: {ATTRIBUTE_NAME}",
+                   "ATTRIBUTE_NAME", attrName);
+        throw;
+    }
+    return std::get<1>(attrVal);
+}
+
+bool isSystemDumpInProgress(sdbusplus::bus::bus& bus)
+{
+    try
+    {
+        auto dumpInProgress = std::get<std::string>(
+            readBIOSAttribute("pvm_sys_dump_active"), bus);
+        if (dumpInProgress == "Enabled")
+        {
+            lg2::info("A system dump is already in progress");
+            return true;
+        }
+    }
+    catch (const std::bad_variant_access& ex)
+    {
+        lg2::error("Failed to read pvm_sys_dump_active property value due "
+                   "to bad variant access error:{ERROR}",
+                   "ERROR", ex);
+        return false;
+    }
+    catch (const std::exception& ex)
+    {
+        lg2::error("Failed to read pvm_sys_dump_active error:{ERROR}", "ERROR",
+                   ex);
+        return false;
+    }
+
+    lg2::info("Another system dump is not in progress");
+    return false;
+}
+
 } // namespace util
 } // namespace dump
 } // namespace openpower