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  | 

