summaryrefslogtreecommitdiffstats
path: root/host-cmd-manager.cpp
diff options
context:
space:
mode:
authorMatt Spinler <spinler@us.ibm.com>2018-06-27 13:01:25 -0500
committerVernon Mauery <vernon.mauery@linux.intel.com>2018-07-24 20:56:11 +0000
commit15309efc2c1cebadbabdb0ef5f74a38fb8b78cfd (patch)
tree739a585033f28e2da1237b80e1545df4deacf305 /host-cmd-manager.cpp
parent1500a64704cf558a1d08d1cf0db7a4a3d550989a (diff)
downloadphosphor-host-ipmid-15309efc2c1cebadbabdb0ef5f74a38fb8b78cfd.tar.gz
phosphor-host-ipmid-15309efc2c1cebadbabdb0ef5f74a38fb8b78cfd.zip
Clear host command queue on a power on
When the RequestedHostTransition property changes to On, clear any pending commands in the command queue. This is done to avoid race conditions around state transitions as well as other scenarios like the following: 1) Host is already off 2) RequestedHostTransition is set to Off 3) RequestedHostTransition is set to On 4) Host powers on 5) Host immediately powers off because of the pending command sent in 2). Resolves openbmc/openbmc#3207 Tested: Verified the scenario above no longer occurs. Change-Id: I26c8195c305c75b01333d1b10ff4bf16d76b91a6 Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Diffstat (limited to 'host-cmd-manager.cpp')
-rw-r--r--host-cmd-manager.cpp42
1 files changed, 41 insertions, 1 deletions
diff --git a/host-cmd-manager.cpp b/host-cmd-manager.cpp
index 799f9bf..4316451 100644
--- a/host-cmd-manager.cpp
+++ b/host-cmd-manager.cpp
@@ -2,6 +2,7 @@
#include <phosphor-logging/log.hpp>
#include <phosphor-logging/elog-errors.hpp>
#include <xyz/openbmc_project/Common/error.hpp>
+#include <xyz/openbmc_project/State/Host/server.hpp>
#include <systemintfcmds.h>
#include <utils.hpp>
#include <config.h>
@@ -18,15 +19,26 @@ namespace command
constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
constexpr auto MAPPER_PATH = "/xyz/openbmc_project/object_mapper";
constexpr auto MAPPER_INTERFACE = "xyz.openbmc_project.ObjectMapper";
+constexpr auto HOST_STATE_PATH = "/xyz/openbmc_project/state/host0";
+constexpr auto HOST_STATE_INTERFACE = "xyz.openbmc_project.State.Host";
+constexpr auto HOST_TRANS_PROP = "RequestedHostTransition";
// For throwing exceptions
using namespace phosphor::logging;
using InternalFailure = sdbusplus::xyz::openbmc_project::Common::
Error::InternalFailure;
+namespace sdbusRule = sdbusplus::bus::match::rules;
+
Manager::Manager(sdbusplus::bus::bus& bus, sd_event* event) :
bus(bus),
- timer(event, std::bind(&Manager::hostTimeout, this))
+ timer(event, std::bind(&Manager::hostTimeout, this)),
+ hostTransitionMatch(bus,
+ sdbusRule::propertiesChanged(
+ HOST_STATE_PATH,
+ HOST_STATE_INTERFACE),
+ std::bind(&Manager::clearQueueOnPowerOn, this,
+ std::placeholders::_1))
{
// Nothing to do here.
}
@@ -75,6 +87,11 @@ void Manager::hostTimeout()
{
log<level::ERR>("Host control timeout hit!");
+ clearQueue();
+}
+
+void Manager::clearQueue()
+{
// Dequeue all entries and send fail signal
while(!this->workQueue.empty())
{
@@ -150,6 +167,29 @@ void Manager::execute(CommandHandler command)
return;
}
+void Manager::clearQueueOnPowerOn(sdbusplus::message::message& msg)
+{
+ namespace server = sdbusplus::xyz::openbmc_project::State::server;
+
+ ::ipmi::DbusInterface interface;
+ ::ipmi::PropertyMap properties;
+
+ msg.read(interface, properties);
+
+ if (properties.find(HOST_TRANS_PROP) == properties.end())
+ {
+ return;
+ }
+
+ auto& requestedState = properties.at(HOST_TRANS_PROP).get<std::string>();
+
+ if (server::Host::convertTransitionFromString(requestedState) ==
+ server::Host::Transition::On)
+ {
+ clearQueue();
+ }
+}
+
} // namespace command
} // namespace host
} // namepsace phosphor
OpenPOWER on IntegriCloud