summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am3
-rw-r--r--host-interface.cpp58
-rw-r--r--host-interface.hpp30
-rw-r--r--softoff/Makefile.am4
-rw-r--r--softoff/test/Makefile.am2
-rw-r--r--systemintfcmds.cpp6
-rw-r--r--timer.cpp (renamed from softoff/timer.cpp)0
-rw-r--r--timer.hpp (renamed from softoff/timer.hpp)0
8 files changed, 78 insertions, 25 deletions
diff --git a/Makefile.am b/Makefile.am
index 4daadcd..2a51d2f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -45,7 +45,8 @@ libsysintfcmds_LTLIBRARIES = libsysintfcmds.la
libsysintfcmds_la_SOURCES = \
systemintfcmds.cpp \
host-interface.cpp \
- utils.cpp
+ utils.cpp \
+ timer.cpp
libsysintfcmds_la_LDFLAGS = $(SYSTEMD_LIBS) \
$(libmapper_LIBS) \
$(PHOSPHOR_DBUS_INTERFACES_LIBS) \
diff --git a/host-interface.cpp b/host-interface.cpp
index 160c127..be2bd99 100644
--- a/host-interface.cpp
+++ b/host-interface.cpp
@@ -1,6 +1,9 @@
+#include <chrono>
#include <phosphor-logging/log.hpp>
#include <utils.hpp>
+#include <config.h>
#include "host-interface.hpp"
+#include "elog-errors.hpp"
namespace phosphor
{
@@ -16,10 +19,45 @@ using namespace phosphor::logging;
// When you see base:: you know we're referencing our base class
namespace base = sdbusplus::xyz::openbmc_project::Control::server;
-// TODO - Add timeout function?
-// - If host does not respond to SMS, need to signal a failure
-// - Flush queue on power off? - Timeout would do this for us for free
-// - Ignore requests when host state not running? - Timeout handles too
+base::Host::Command Host::getNextCommand()
+{
+ // Stop the timer
+ auto r = timer.setTimer(SD_EVENT_OFF);
+ if (r < 0)
+ {
+ log<level::ERR>("Failure to STOP the timer",
+ entry("ERROR=%s", strerror(-r)));
+ }
+
+ if(this->workQueue.empty())
+ {
+ log<level::ERR>("Control Host work queue is empty!");
+ elog<xyz::openbmc_project::Control::Internal::Host::QueueEmpty>();
+ }
+
+ // Pop the processed entry off the queue
+ Command command = this->workQueue.front();
+ this->workQueue.pop();
+
+ // Issue command complete signal
+ this->commandComplete(command, Result::Success);
+
+ // Check for another entry in the queue and kick it off
+ this->checkQueue();
+ return command;
+}
+
+void Host::hostTimeout()
+{
+ log<level::ERR>("Host control timeout hit!");
+ // Dequeue all entries and send fail signal
+ while(!this->workQueue.empty())
+ {
+ auto command = this->workQueue.front();
+ this->workQueue.pop();
+ this->commandComplete(command,Result::Failure);
+ }
+}
void Host::checkQueue()
{
@@ -30,7 +68,17 @@ void Host::checkQueue()
std::string IPMI_PATH("/org/openbmc/HostIpmi/1");
std::string IPMI_INTERFACE("org.openbmc.HostIpmi");
- auto host = ipmi::getService(this->bus,IPMI_INTERFACE,IPMI_PATH);
+ auto host = ::ipmi::getService(this->bus,IPMI_INTERFACE,IPMI_PATH);
+
+ // Start the timer for this transaction
+ auto time = std::chrono::duration_cast<std::chrono::microseconds>(
+ std::chrono::seconds(IPMI_SMS_ATN_ACK_TIMEOUT_SECS));
+ auto r = timer.startTimer(time);
+ if (r < 0)
+ {
+ log<level::ERR>("Error starting timer for control host");
+ return;
+ }
auto method = this->bus.new_method_call(host.c_str(),
IPMI_PATH.c_str(),
diff --git a/host-interface.hpp b/host-interface.hpp
index 0ad3bfb..8901a2b 100644
--- a/host-interface.hpp
+++ b/host-interface.hpp
@@ -4,7 +4,7 @@
#include <sdbusplus/bus.hpp>
#include <phosphor-logging/elog.hpp>
#include <xyz/openbmc_project/Control/Host/server.hpp>
-#include "elog-errors.hpp"
+#include <timer.hpp>
namespace phosphor
{
@@ -26,13 +26,17 @@ class Host : public sdbusplus::server::object::object<
*
* @param[in] bus - The Dbus bus object
* @param[in] objPath - The Dbus object path
+ * @param[in] events - The sd_event pointer
*/
Host(sdbusplus::bus::bus& bus,
- const char* objPath) :
+ const char* objPath,
+ sd_event* events) :
sdbusplus::server::object::object<
sdbusplus::xyz::openbmc_project::Control::server::Host>(
bus, objPath),
- bus(bus)
+ bus(bus),
+ timer(events,
+ std::bind(&Host::hostTimeout, this))
{}
/** @brief Send input command to host
@@ -51,30 +55,24 @@ class Host : public sdbusplus::server::object::object<
* passed to the host (which is required when calling this interface)
*
*/
- Command getNextCommand()
- {
- if(this->workQueue.empty())
- {
- log<level::ERR>("Control Host work queue is empty!");
- elog<xyz::openbmc_project::Control::Internal::Host::QueueEmpty>();
- }
- Command command = this->workQueue.front();
- this->workQueue.pop();
- this->commandComplete(command, Result::Success);
- this->checkQueue();
- return command;
- }
+ Command getNextCommand();
private:
/** @brief Check if anything in queue and alert host if so */
void checkQueue();
+ /** @brief Call back interface on message timeouts to host */
+ void hostTimeout();
+
/** @brief Persistent sdbusplus DBus bus connection. */
sdbusplus::bus::bus& bus;
/** @brief Queue to store the requested commands */
std::queue<Command> workQueue{};
+
+ /** @brief Timer for commands to host */
+ phosphor::ipmi::Timer timer;
};
} // namespace host
diff --git a/softoff/Makefile.am b/softoff/Makefile.am
index 35734d2..b7f4c92 100644
--- a/softoff/Makefile.am
+++ b/softoff/Makefile.am
@@ -2,9 +2,11 @@ AM_DEFAULT_SOURCE_EXT = .cpp
AM_CPPFLAGS = -I$(top_srcdir)
sbin_PROGRAMS = phosphor-softpoweroff
+# Using ../ instead of $(top_srcdir) due to automake bug in version 1.15.
+# https://debbugs.gnu.org/cgi/bugreport.cgi?bug=13928
phosphor_softpoweroff_SOURCES = \
softoff.cpp \
- timer.cpp \
+ ../timer.cpp \
mainapp.cpp \
xyz/openbmc_project/Ipmi/Internal/SoftPowerOff/server.cpp
diff --git a/softoff/test/Makefile.am b/softoff/test/Makefile.am
index 2c65568..afdb620 100644
--- a/softoff/test/Makefile.am
+++ b/softoff/test/Makefile.am
@@ -9,4 +9,4 @@ utest_CPPFLAGS = -Igtest $(GTEST_CPPFLAGS) $(AM_CPPFLAGS)
utest_CXXFLAGS = $(PTHREAD_CFLAGS)
utest_LDFLAGS = -lgtest_main -lgtest $(PTHREAD_LIBS) $(OESDK_TESTCASE_FLAGS) $(SYSTEMD_LIBS) ${SDBUSPLUS_LIBS}
utest_SOURCES = utest.cpp
-utest_LDADD = $(top_builddir)/softoff/timer.o
+utest_LDADD = $(top_builddir)/timer.o
diff --git a/systemintfcmds.cpp b/systemintfcmds.cpp
index 999e710..23e81ba 100644
--- a/systemintfcmds.cpp
+++ b/systemintfcmds.cpp
@@ -182,8 +182,12 @@ void register_netfn_app_functions()
sdbusplus::server::manager::manager objManager(*sdbus,
objPathInst.c_str());
+ // Get the sd_events pointer
+ auto events = ipmid_get_sd_event_connection();
+
host = new phosphor::host::Host(*sdbus,
- objPathInst.c_str());
+ objPathInst.c_str(),
+ events);
sdbus->request_name(CONTROL_HOST_BUSNAME);
diff --git a/softoff/timer.cpp b/timer.cpp
index 4e8fd9a..4e8fd9a 100644
--- a/softoff/timer.cpp
+++ b/timer.cpp
diff --git a/softoff/timer.hpp b/timer.hpp
index cbd3444..cbd3444 100644
--- a/softoff/timer.hpp
+++ b/timer.hpp
OpenPOWER on IntegriCloud