crit-service: check for bmc quiesce on startup
If the new bmc-bmc-service-quiesce target is entered, then change the
BMC state to Quiesced and do not allow it to change until the BMC is
rebooted out of the failure.
Tested:
- Installed new code on system and started target-monitor with new
critical services json file as input. Verified that when a critical
service was killed three times within quick succession, the service
went into a failed state, the target-monitor detected it, and BMC went
to Quiesced state.
- Restarted bmc-state manager application while BMC was in Quiesced
state and verified it rediscovered that upon restart.
Signed-off-by: Andrew Geissler <geissonator@yahoo.com>
Change-Id: I1096a29e4c244c0d0dfc9829f58fda6e1b2cba35
diff --git a/bmc_state_manager.cpp b/bmc_state_manager.cpp
index 4575a76..9c047c7 100644
--- a/bmc_state_manager.cpp
+++ b/bmc_state_manager.cpp
@@ -30,6 +30,7 @@
using namespace phosphor::logging;
using sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
+constexpr auto obmcQuiesceTarget = "obmc-bmc-service-quiesce@0.target";
constexpr auto obmcStandbyTarget = "multi-user.target";
constexpr auto signalDone = "done";
constexpr auto activeState = "active";
@@ -88,25 +89,22 @@
void BMC::discoverInitialState()
{
- auto currentStateStr = getUnitState(obmcStandbyTarget);
+
+ // First look to see if the BMC quiesce target is active
+ auto currentStateStr = getUnitState(obmcQuiesceTarget);
+ if (currentStateStr == activeState)
+ {
+ info("Setting the BMCState field to BMC_QUIESCED");
+ this->currentBMCState(BMCState::Quiesced);
+ return;
+ }
+
+ // If not quiesced, then check standby target
+ currentStateStr = getUnitState(obmcStandbyTarget);
if (currentStateStr == activeState)
{
info("Setting the BMCState field to BMC_READY");
this->currentBMCState(BMCState::Ready);
-
- // Unsubscribe so we stop processing all other signals
- auto method =
- this->bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_OBJ_PATH,
- SYSTEMD_INTERFACE, "Unsubscribe");
- try
- {
- this->bus.call(method);
- this->stateSignal.release();
- }
- catch (const sdbusplus::exception::exception& e)
- {
- info("Error in Unsubscribe: {ERROR}", "ERROR", e);
- }
}
else
{
@@ -191,13 +189,13 @@
// Read the msg and populate each variable
msg.read(newStateID, newStateObjPath, newStateUnit, newStateResult);
- // Caught the signal that indicates the BMC is now BMC_READY
- if ((newStateUnit == obmcStandbyTarget) && (newStateResult == signalDone))
+ if ((newStateUnit == obmcQuiesceTarget) && (newStateResult == signalDone))
{
- info("BMC_READY");
- this->currentBMCState(BMCState::Ready);
+ error("BMC has entered BMC_QUIESCED state");
+ this->currentBMCState(BMCState::Quiesced);
- // Unsubscribe so we stop processing all other signals
+ // There is no getting out of Quiesced once entered (other then BMC
+ // reboot) so stop watching for signals
auto method =
this->bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_OBJ_PATH,
SYSTEMD_INTERFACE, "Unsubscribe");
@@ -211,6 +209,15 @@
{
info("Error in Unsubscribe: {ERROR}", "ERROR", e);
}
+
+ return 0;
+ }
+
+ // Caught the signal that indicates the BMC is now BMC_READY
+ if ((newStateUnit == obmcStandbyTarget) && (newStateResult == signalDone))
+ {
+ info("BMC_READY");
+ this->currentBMCState(BMCState::Ready);
}
return 0;