OpenPOWER: Allow initiating mp reboot dump in quiesced state
When system dumps are disabled, a system dump collection
request will end up in quiesced state. A memory preserving
reboot from that state can get the failed data from the host.
So enabling the mp reboot dump collection from quiesced state.
Test:
Disable dump
Inject error in host to move to quiesced state
Start mp reboot
Dump should be generated
Signed-off-by: Dhruvaraj Subhashchandran <dhruvaraj@in.ibm.com>
Change-Id: I9f444752b321f1ab47b99e5b8ac32c79182d6453
diff --git a/dump-extensions/openpower-dumps/dump_manager_system.cpp b/dump-extensions/openpower-dumps/dump_manager_system.cpp
index 2aaa35e..23d1994 100644
--- a/dump-extensions/openpower-dumps/dump_manager_system.cpp
+++ b/dump-extensions/openpower-dumps/dump_manager_system.cpp
@@ -69,9 +69,9 @@
if (upEntry != nullptr)
{
log<level::INFO>(
- fmt::format(
- "System Dump Notify: Updating dumpId({}) Id({}) Size({})",
- upEntry->getDumpId(), dumpId, size)
+ fmt::format("System Dump Notify: Updating dump entry with Id({}) "
+ "with source Id({}) and Size({})",
+ upEntry->getDumpId(), dumpId, size)
.c_str());
upEntry->update(timeStamp, size, dumpId);
return;
@@ -86,10 +86,11 @@
// For now replacing it with null
try
{
- log<level::INFO>(fmt::format("System Dump Notify: creating new dump "
- "entry dumpId({}) Id({}) Size({})",
- id, dumpId, size)
- .c_str());
+ log<level::INFO>(
+ fmt::format("System Dump Notify: creating new dump "
+ "entry with dumpId({}) with source Id({}) and Size({})",
+ id, dumpId, size)
+ .c_str());
entries.insert(std::make_pair(
id, std::make_unique<system::Entry>(
bus, objPath.c_str(), id, timeStamp, size, dumpId,
@@ -130,7 +131,8 @@
using Reason = xyz::openbmc_project::Common::NotAllowed::REASON;
// Allow creating system dump only when the host is up.
- if (!phosphor::dump::isHostRunning())
+ if (!(((phosphor::dump::isHostRunning()) ||
+ (phosphor::dump::isHostQuiesced()))))
{
elog<NotAllowed>(
Reason("System dump can be initiated only when the host is up"));
diff --git a/dump_utils.cpp b/dump_utils.cpp
index 830cce5..45f4153 100644
--- a/dump_utils.cpp
+++ b/dump_utils.cpp
@@ -55,19 +55,37 @@
"xyz.openbmc_project.State.Boot.Progress";
// TODO Need to change host instance if multiple instead "0"
constexpr auto hostStateObjPath = "/xyz/openbmc_project/state/host0";
+ auto value =
+ getStateValue(bootProgressInterface, hostStateObjPath, "BootProgress");
+ return sdbusplus::xyz::openbmc_project::State::Boot::server::Progress::
+ convertProgressStagesFromString(value);
+}
- BootProgress bootProgessStage;
+HostState getHostState()
+{
+ constexpr auto hostStateInterface = "xyz.openbmc_project.State.Host";
+ // TODO Need to change host instance if multiple instead "0"
+ constexpr auto hostStateObjPath = "/xyz/openbmc_project/state/host0";
+ auto value =
+ getStateValue(hostStateInterface, hostStateObjPath, "CurrentHostState");
+ return sdbusplus::xyz::openbmc_project::State::server::Host::
+ convertHostStateFromString(value);
+}
+std::string getStateValue(const std::string& intf, const std::string& objPath,
+ const std::string& state)
+{
+ std::string stateVal;
try
{
auto bus = sdbusplus::bus::new_default();
- auto service = getService(bus, hostStateObjPath, bootProgressInterface);
+ auto service = getService(bus, objPath, intf);
auto method =
- bus.new_method_call(service.c_str(), hostStateObjPath,
+ bus.new_method_call(service.c_str(), objPath.c_str(),
"org.freedesktop.DBus.Properties", "Get");
- method.append(bootProgressInterface, "BootProgress");
+ method.append(intf, state);
auto reply = bus.call(method);
@@ -78,32 +96,27 @@
reply.read(propertyVal);
- // BootProgress property type is string
- std::string bootPgs(std::get<std::string>(propertyVal));
-
- bootProgessStage = sdbusplus::xyz::openbmc_project::State::Boot::
- server::Progress::convertProgressStagesFromString(bootPgs);
+ stateVal = std::get<std::string>(propertyVal);
}
catch (const sdbusplus::exception_t& e)
{
log<level::ERR>(fmt::format("D-Bus call exception, OBJPATH({}), "
- "INTERFACE({}), EXCEPTION({})",
- hostStateObjPath, bootProgressInterface,
- e.what())
+ "INTERFACE({}), PROPERTY({}) EXCEPTION({})",
+ objPath, intf, state, e.what())
.c_str());
- throw std::runtime_error("Failed to get BootProgress stage");
+ throw std::runtime_error("Failed to get state property");
}
catch (const std::bad_variant_access& e)
{
log<level::ERR>(
- fmt::format("Exception raised while read BootProgress property "
+ fmt::format("Exception raised while read host state({}) property "
"value, OBJPATH({}), INTERFACE({}), EXCEPTION({})",
- hostStateObjPath, bootProgressInterface, e.what())
+ state, objPath, intf, e.what())
.c_str());
- throw std::runtime_error("Failed to get BootProgress stage");
+ throw std::runtime_error("Failed to get host state property");
}
- return bootProgessStage;
+ return stateVal;
}
bool isHostRunning()
@@ -121,5 +134,10 @@
}
return false;
}
+
+bool isHostQuiesced()
+{
+ return (phosphor::dump::getHostState() == HostState::Quiesced);
+}
} // namespace dump
} // namespace phosphor
diff --git a/dump_utils.hpp b/dump_utils.hpp
index 83952a3..82fff10 100644
--- a/dump_utils.hpp
+++ b/dump_utils.hpp
@@ -12,6 +12,7 @@
#include <xyz/openbmc_project/Common/error.hpp>
#include <xyz/openbmc_project/Dump/Create/server.hpp>
#include <xyz/openbmc_project/State/Boot/Progress/server.hpp>
+#include <xyz/openbmc_project/State/Host/server.hpp>
#include <memory>
@@ -22,6 +23,8 @@
using BootProgress = sdbusplus::xyz::openbmc_project::State::Boot::server::
Progress::ProgressStages;
+using HostState =
+ sdbusplus::xyz::openbmc_project::State::server::Host::HostState;
using namespace phosphor::logging;
using namespace sdbusplus::xyz::openbmc_project::Common::Error;
@@ -86,6 +89,15 @@
const std::string& interface);
/**
+ * @brief Get the host state
+ *
+ * @return HostState on success
+ * Throw exception on failure
+ *
+ */
+HostState getHostState();
+
+/**
* @brief Get the host boot progress stage
*
* @return BootProgress on success
@@ -95,6 +107,19 @@
BootProgress getBootProgress();
/**
+ * @brief Get the host state value
+ *
+ * @param[in] intf - Interface to get the value
+ * @param[in] objPath - Object path of the service
+ * @param[in] state - State name to get
+ *
+ * @return The state value on success
+ * Throw exception on failure
+ */
+std::string getStateValue(const std::string& intf, const std::string& objPath,
+ const std::string& state);
+
+/**
* @brief Check whether host is running
*
* @return true if the host running else false.
@@ -169,5 +194,13 @@
}
}
+/**
+ * @brief Check whether host is quiesced
+ *
+ * @return true if the host is quiesced else false.
+ * Throw exception on failure.
+ */
+bool isHostQuiesced();
+
} // namespace dump
} // namespace phosphor