boot-block: quiesce host on error
If the user has requested the boot be blocked on an error with a
callout then also quiesce the host if it is running when this error
occurs.
Signed-off-by: Andrew Geissler <geissonator@yahoo.com>
Change-Id: I9f1f4fc1c704850649217770f4cfcff1cad70404
diff --git a/log_manager.cpp b/log_manager.cpp
index d636a67..1acd746 100644
--- a/log_manager.cpp
+++ b/log_manager.cpp
@@ -27,6 +27,7 @@
#include <set>
#include <string>
#include <vector>
+#include <xyz/openbmc_project/State/Host/server.hpp>
using namespace phosphor::logging;
using namespace std::chrono;
@@ -314,6 +315,59 @@
}
}
+void Manager::checkAndQuiesceHost()
+{
+ // First check host state
+ std::variant<std::string> property;
+
+ auto method = this->busLog.new_method_call(
+ "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
+ "org.freedesktop.DBus.Properties", "Get");
+
+ method.append("xyz.openbmc_project.State.Host", "CurrentHostState");
+
+ try
+ {
+ auto reply = this->busLog.call(method);
+ reply.read(property);
+ }
+ catch (const SdBusError& e)
+ {
+ // Quiescing the host is a "best effort" type function. If unable to
+ // read the host state or it comes back empty, just return.
+ // The boot block object will still be created and the associations to
+ // find the log will be present. Don't want a dependency with
+ // phosphor-state-manager service
+ log<level::INFO>("Error reading QuiesceOnHwError property",
+ entry("ERROR=%s", e.what()));
+ return;
+ }
+
+ std::string hostState = std::get<std::string>(property);
+
+ // If host state is empty, do nothing
+ if (hostState.empty())
+ {
+ return;
+ }
+
+ using Host = sdbusplus::xyz::openbmc_project::State::server::Host;
+ auto state = Host::convertHostStateFromString(hostState);
+ if (state != Host::HostState::Running)
+ {
+ return;
+ }
+
+ auto quiesce = this->busLog.new_method_call(
+ "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager", "StartUnit");
+
+ quiesce.append("obmc-host-quiesce@0.target");
+ quiesce.append("replace");
+
+ this->busLog.call_noreply(quiesce);
+}
+
void Manager::checkQuiesceOnError(const Entry& entry)
{
@@ -343,8 +397,7 @@
propChangedEntryCallback.insert(
std::make_pair(entry.id(), std::move(callback)));
- // TODO in later commit in this series
- // Call systemd to quiesce host
+ checkAndQuiesceHost();
}
void Manager::doExtensionLogCreate(const Entry& entry, const FFDCEntries& ffdc)
diff --git a/log_manager.hpp b/log_manager.hpp
index 87dd038..34117dc 100644
--- a/log_manager.hpp
+++ b/log_manager.hpp
@@ -286,6 +286,13 @@
/** @brief Remove block objects for any resolved entries */
void findAndRemoveResolvedBlocks();
+ /** @brief Quiesce host if it is running
+ *
+ * This is called when the user has requested the system be quiesced
+ * if a log with a callout is created
+ */
+ void checkAndQuiesceHost();
+
/** @brief Persistent sdbusplus DBus bus connection. */
sdbusplus::bus::bus& busLog;