OpenPOWER: Do not allow system dump when already in progress
if a system dump is in progress or already available in host
memory reject any further dump requests.
Test:
Initiate system dump when another dump in progress
Signed-off-by: Dhruvaraj Subhashchandran <dhruvaraj@in.ibm.com>
Change-Id: I4598912b0761669859f84a43ab4c60f47664b1e6
diff --git a/dump-extensions/openpower-dumps/dump_manager_system.cpp b/dump-extensions/openpower-dumps/dump_manager_system.cpp
index 23d1994..93200c2 100644
--- a/dump-extensions/openpower-dumps/dump_manager_system.cpp
+++ b/dump-extensions/openpower-dumps/dump_manager_system.cpp
@@ -4,6 +4,7 @@
#include "dump_utils.hpp"
#include "op_dump_consts.hpp"
+#include "op_dump_util.hpp"
#include "system_dump_entry.hpp"
#include "xyz/openbmc_project/Common/error.hpp"
@@ -126,6 +127,14 @@
"System dump accepts not more than 2 additional parameters");
}
+ if (openpower::dump::util::isSystemDumpInProgress())
+ {
+ log<level::ERR>(
+ fmt::format("Another dump in progress or available to offload")
+ .c_str());
+ elog<sdbusplus::xyz::openbmc_project::Common::Error::Unavailable>();
+ }
+
using NotAllowed =
sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
using Reason = xyz::openbmc_project::Common::NotAllowed::REASON;
diff --git a/dump-extensions/openpower-dumps/op_dump_util.cpp b/dump-extensions/openpower-dumps/op_dump_util.cpp
index 88d41ab..2c6fb5e 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"
@@ -70,6 +71,69 @@
return std::filesystem::exists(MP_REBOOT_FILE);
}
+bool isSystemDumpInProgress()
+{
+ using BiosBaseTableItem = std::pair<
+ std::string,
+ std::tuple<std::string, bool, std::string, std::string, std::string,
+ std::variant<int64_t, std::string>,
+ std::variant<int64_t, std::string>,
+ std::vector<std::tuple<
+ std::string, std::variant<int64_t, std::string>>>>>;
+ using BiosBaseTable = std::vector<BiosBaseTableItem>;
+
+ try
+ {
+ std::string dumpInProgress{};
+ auto bus = sdbusplus::bus::new_default();
+
+ auto retVal =
+ phosphor::dump::readDBusProperty<std::variant<BiosBaseTable>>(
+ bus, "xyz.openbmc_project.BIOSConfigManager",
+ "/xyz/openbmc_project/bios_config/manager",
+ "xyz.openbmc_project.BIOSConfig.Manager", "BaseBIOSTable");
+ const auto baseBiosTable = std::get_if<BiosBaseTable>(&retVal);
+ if (baseBiosTable == nullptr)
+ {
+ log<level::ERR>(
+ "Util failed to read BIOSconfig property BaseBIOSTable");
+ return false;
+ }
+ for (const auto& item : *baseBiosTable)
+ {
+ const auto attributeName = std::get<0>(item);
+ auto attrValue = std::get<5>(std::get<1>(item));
+ auto val = std::get_if<std::string>(&attrValue);
+ if (val != nullptr && attributeName == "pvm_sys_dump_active")
+ {
+ dumpInProgress = *val;
+ break;
+ }
+ }
+ if (dumpInProgress.empty())
+ {
+ log<level::ERR>(
+ "Util failed to read pvm_hmc_managed property value");
+ return false;
+ }
+ if (dumpInProgress == "Enabled")
+ {
+ log<level::INFO>("A system dump is already in progress");
+ return true;
+ }
+ }
+ catch (const std::exception& ex)
+ {
+ log<level::ERR>(
+ fmt::format("Failed to read pvm_sys_dump_active ({})", ex.what())
+ .c_str());
+ return false;
+ }
+
+ log<level::INFO>("Another system dump is not in progress");
+ return false;
+}
+
} // namespace util
} // namespace dump
} // namespace openpower
diff --git a/dump-extensions/openpower-dumps/op_dump_util.hpp b/dump-extensions/openpower-dumps/op_dump_util.hpp
index 3de441a..ad7e135 100644
--- a/dump-extensions/openpower-dumps/op_dump_util.hpp
+++ b/dump-extensions/openpower-dumps/op_dump_util.hpp
@@ -24,6 +24,12 @@
*/
bool isInMpReboot();
+/** @brief Check whether a system is in progress or
+ * available to offload.
+ * @return true - A dump is in progress or available to offload
+ * false - No dump in progress
+ */
+bool isSystemDumpInProgress();
} // namespace util
} // namespace dump
} // namespace openpower
diff --git a/dump_utils.hpp b/dump_utils.hpp
index 82fff10..93e8878 100644
--- a/dump_utils.hpp
+++ b/dump_utils.hpp
@@ -3,11 +3,13 @@
#include "dump_manager.hpp"
#include <fmt/core.h>
+#include <fmt/format.h>
#include <systemd/sd-event.h>
#include <unistd.h>
#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/elog.hpp>
+#include <phosphor-logging/log.hpp>
#include <sdbusplus/bus.hpp>
#include <xyz/openbmc_project/Common/error.hpp>
#include <xyz/openbmc_project/Dump/Create/server.hpp>
@@ -202,5 +204,44 @@
*/
bool isHostQuiesced();
+/**
+ * @brief Read property value from the specified object and interface
+ * @param[in] bus D-Bus handle
+ * @param[in] service service which has implemented the interface
+ * @param[in] object object having has implemented the interface
+ * @param[in] intf interface having the property
+ * @param[in] prop name of the property to read
+ * @return property value
+ */
+template <typename T>
+T readDBusProperty(sdbusplus::bus::bus& bus, const std::string& service,
+ const std::string& object, const std::string& intf,
+ const std::string& prop)
+{
+ using ::phosphor::logging::level;
+ using ::phosphor::logging::log;
+ T retVal{};
+ try
+ {
+ auto properties =
+ bus.new_method_call(service.c_str(), object.c_str(),
+ "org.freedesktop.DBus.Properties", "Get");
+ properties.append(intf);
+ properties.append(prop);
+ auto result = bus.call(properties);
+ result.read(retVal);
+ }
+ catch (const std::exception& ex)
+ {
+ log<level::ERR>(
+ fmt::format("Failed to get the property ({}) interface ({}) "
+ "object path ({}) error ({}) ",
+ prop.c_str(), intf.c_str(), object.c_str(), ex.what())
+ .c_str());
+ throw;
+ }
+ return retVal;
+}
+
} // namespace dump
} // namespace phosphor