diff options
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | host-interface.cpp | 58 | ||||
-rw-r--r-- | host-interface.hpp | 30 | ||||
-rw-r--r-- | softoff/Makefile.am | 4 | ||||
-rw-r--r-- | softoff/test/Makefile.am | 2 | ||||
-rw-r--r-- | systemintfcmds.cpp | 6 | ||||
-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 |