diff options
Diffstat (limited to 'softoff')
-rw-r--r-- | softoff/mainapp.cpp | 22 | ||||
-rw-r--r-- | softoff/softoff.cpp | 51 | ||||
-rw-r--r-- | softoff/softoff.hpp | 241 | ||||
-rw-r--r-- | softoff/test/utest.cpp | 136 |
4 files changed, 224 insertions, 226 deletions
diff --git a/softoff/mainapp.cpp b/softoff/mainapp.cpp index 3a47cc4..3b153a8 100644 --- a/softoff/mainapp.cpp +++ b/softoff/mainapp.cpp @@ -13,13 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "config.h" + +#include "softoff.hpp" +#include "timer.hpp" + #include <systemd/sd-event.h> -#include <phosphor-logging/elog.hpp> + #include <phosphor-logging/elog-errors.hpp> +#include <phosphor-logging/elog.hpp> #include <xyz/openbmc_project/State/Host/error.hpp> -#include "softoff.hpp" -#include "config.h" -#include "timer.hpp" // Return -1 on any errors to ensure we follow the calling targets OnFailure= // path @@ -41,7 +44,7 @@ int main(int argc, char** argv) if (r < 0) { log<level::ERR>("Failure to create sd_event handler", - entry("ERRNO=0x%X", -r)); + entry("ERRNO=0x%X", -r)); return -1; } @@ -58,22 +61,23 @@ int main(int argc, char** argv) // Wait for client requests until this application has processed // at least one successful SoftPowerOff or we timed out - while(!powerObj.isCompleted() && !powerObj.isTimerExpired()) + while (!powerObj.isCompleted() && !powerObj.isTimerExpired()) { // -1 denotes wait for ever r = sd_event_run(events, (uint64_t)-1); if (r < 0) { log<level::ERR>("Failure in processing request", - entry("ERRNO=0x%X", -r)); + entry("ERRNO=0x%X", -r)); return -1; } } // Log an error if we timed out after getting Ack for SMS_ATN and before // getting the Host Shutdown response - if(powerObj.isTimerExpired() && (powerObj.responseReceived() == - phosphor::ipmi::Base::SoftPowerOff::HostResponse::SoftOffReceived)) + if (powerObj.isTimerExpired() && + (powerObj.responseReceived() == + phosphor::ipmi::Base::SoftPowerOff::HostResponse::SoftOffReceived)) { using error = sdbusplus::xyz::openbmc_project::State::Host::Error::SoftOffTimeout; diff --git a/softoff/softoff.cpp b/softoff/softoff.cpp index d76750a..921536f 100644 --- a/softoff/softoff.cpp +++ b/softoff/softoff.cpp @@ -13,12 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "config.h" + +#include "softoff.hpp" + #include <chrono> #include <phosphor-logging/log.hpp> -#include <xyz/openbmc_project/Control/Host/server.hpp> #include <utils.hpp> -#include "softoff.hpp" -#include "config.h" +#include <xyz/openbmc_project/Control/Host/server.hpp> namespace phosphor { namespace ipmi @@ -29,16 +31,13 @@ using namespace sdbusplus::xyz::openbmc_project::Control::server; void SoftPowerOff::sendHostShutDownCmd() { - auto ctrlHostPath = std::string{CONTROL_HOST_OBJ_MGR} + '/' + - HOST_NAME + '0'; - auto host = ::ipmi::getService(this->bus, - CONTROL_HOST_BUSNAME, + auto ctrlHostPath = + std::string{CONTROL_HOST_OBJ_MGR} + '/' + HOST_NAME + '0'; + auto host = ::ipmi::getService(this->bus, CONTROL_HOST_BUSNAME, ctrlHostPath.c_str()); - auto method = bus.new_method_call(host.c_str(), - ctrlHostPath.c_str(), - CONTROL_HOST_BUSNAME, - "Execute"); + auto method = bus.new_method_call(host.c_str(), ctrlHostPath.c_str(), + CONTROL_HOST_BUSNAME, "Execute"); method.append(convertForMessage(Host::Command::SoftOff).c_str()); @@ -53,7 +52,6 @@ void SoftPowerOff::sendHostShutDownCmd() return; } - // Function called on host control signals void SoftPowerOff::hostControlEvent(sdbusplus::message::message& msg) { @@ -63,32 +61,33 @@ void SoftPowerOff::hostControlEvent(sdbusplus::message::message& msg) msg.read(cmdCompleted, cmdStatus); log<level::DEBUG>("Host control signal values", - entry("COMMAND=%s",cmdCompleted.c_str()), - entry("STATUS=%s",cmdStatus.c_str())); + entry("COMMAND=%s", cmdCompleted.c_str()), + entry("STATUS=%s", cmdStatus.c_str())); - if(Host::convertResultFromString(cmdStatus) == Host::Result::Success) + if (Host::convertResultFromString(cmdStatus) == Host::Result::Success) { // Set our internal property indicating we got host attention - sdbusplus::xyz::openbmc_project::Ipmi::Internal - ::server::SoftPowerOff::responseReceived( - HostResponse::SoftOffReceived); + sdbusplus::xyz::openbmc_project::Ipmi::Internal ::server::SoftPowerOff:: + responseReceived(HostResponse::SoftOffReceived); // Start timer for host shutdown using namespace std::chrono; auto time = duration_cast<microseconds>( - seconds(IPMI_HOST_SHUTDOWN_COMPLETE_TIMEOUT_SECS)); + seconds(IPMI_HOST_SHUTDOWN_COMPLETE_TIMEOUT_SECS)); auto r = startTimer(time); if (r < 0) { log<level::ERR>("Failure to start Host shutdown wait timer", - entry("ERRNO=0x%X", -r)); + entry("ERRNO=0x%X", -r)); } else { - log<level::INFO>("Timer started waiting for host to shutdown", + log<level::INFO>( + "Timer started waiting for host to shutdown", entry("TIMEOUT_IN_MSEC=%llu", - (duration_cast<milliseconds>(seconds - (IPMI_HOST_SHUTDOWN_COMPLETE_TIMEOUT_SECS))).count())); + (duration_cast<milliseconds>( + seconds(IPMI_HOST_SHUTDOWN_COMPLETE_TIMEOUT_SECS))) + .count())); } } else @@ -120,15 +119,15 @@ auto SoftPowerOff::responseReceived(HostResponse response) -> HostResponse if (r < 0) { log<level::ERR>("Failure to STOP the timer", - entry("ERRNO=0x%X", -r)); + entry("ERRNO=0x%X", -r)); } // This marks the completion of soft power off sequence. completed = true; } - return sdbusplus::xyz::openbmc_project::Ipmi::Internal - ::server::SoftPowerOff::responseReceived(response); + return sdbusplus::xyz::openbmc_project::Ipmi::Internal ::server:: + SoftPowerOff::responseReceived(response); } } // namespace ipmi diff --git a/softoff/softoff.hpp b/softoff/softoff.hpp index 43bc303..b7555e3 100644 --- a/softoff/softoff.hpp +++ b/softoff/softoff.hpp @@ -1,12 +1,14 @@ #pragma once +#include "config.h" + +#include "timer.hpp" + +#include <functional> #include <sdbusplus/bus.hpp> #include <sdbusplus/server/object.hpp> -#include <functional> #include <xyz/openbmc_project/Control/Host/server.hpp> #include <xyz/openbmc_project/Ipmi/Internal/SoftPowerOff/server.hpp> -#include "timer.hpp" -#include "config.h" namespace phosphor { namespace ipmi @@ -20,126 +22,121 @@ namespace sdbusRule = sdbusplus::bus::match::rules; /** @class SoftPowerOff * @brief Responsible for coordinating Host SoftPowerOff operation */ -class SoftPowerOff : public sdbusplus::server::object::object< - Base::SoftPowerOff> +class SoftPowerOff + : public sdbusplus::server::object::object<Base::SoftPowerOff> { - public: - /** @brief Constructs SoftPowerOff object. - * - * @param[in] bus - system dbus handler - * @param[in] event - sd_event handler - * @param[in] objPath - The Dbus path hosting SoftPowerOff function - */ - SoftPowerOff(sdbusplus::bus::bus& bus, - sd_event* event, - const char* objPath) : - sdbusplus::server::object::object< - Base::SoftPowerOff>(bus, objPath, false), - bus(bus), - timer(event), - hostControlSignal( - bus, - sdbusRule::type::signal() + - sdbusRule::member("CommandComplete") + - sdbusRule::path("/xyz/openbmc_project/control/host0") + - sdbusRule::interface(CONTROL_HOST_BUSNAME) + - sdbusRule::argN(0,convertForMessage( - Host::Command::SoftOff)), - std::bind(std::mem_fn(&SoftPowerOff::hostControlEvent), - this, std::placeholders::_1)) - { - // Need to announce since we may get the response - // very quickly on host shutdown command - emit_object_added(); - - // The whole purpose of this application is to send a host shutdown - // command and watch for the soft power off to go through. We need - // the interface added signal emitted before we send the shutdown - // command just to attend to lightning fast response from host - sendHostShutDownCmd(); - } - - /** @brief Tells if the objective of this application is completed */ - inline auto isCompleted() - { - return completed; - } - - /** @brief Tells if the referenced timer is expired or not */ - inline auto isTimerExpired() - { - return timer.isExpired(); - } - - /** @brief overloaded property setter function - * - * @param[in] value - One of SoftOffReceived / HostShutdown - * - * @return Success or exception thrown - */ - HostResponse responseReceived(HostResponse value) override; - - /** @brief Using the base class's getter method */ - using Base::SoftPowerOff::responseReceived; - - /** @brief Calls to start a timer - * - * @param[in] usec - Time in microseconds - * - * @return Success or exception thrown - */ - int startTimer(const std::chrono::microseconds& usec); - - private: - // Need this to send SMS_ATTN - // TODO : Switch over to using mapper service in a different patch - static constexpr auto HOST_IPMI_BUS = "org.openbmc.HostIpmi"; - static constexpr auto HOST_IPMI_OBJ = "/org/openbmc/HostIpmi/1"; - static constexpr auto HOST_IPMI_INTF = "org.openbmc.HostIpmi"; - - /* @brief sdbusplus handle */ - sdbusplus::bus::bus& bus; - - /** @brief Reference to Timer object */ - Timer timer; - - /** @brief Marks the end of life of this application. - * - * This is set to true if host gives appropriate responses - * for the sequence of commands. - */ - bool completed = false; - - /** @brief Subscribe to host control signals - * - * Protocol is to send the host power off request to the host - * control interface and then wait for a signal indicating pass/fail - **/ - sdbusplus::bus::match_t hostControlSignal; - - /** @brief Sends host control command to tell host to shut down - * - * After sending the command, wait for a signal indicating the status - * of the command. - * - * After receiving the initial response, start a timer for 30 minutes - * to let host do a clean shutdown of partitions. When the response is - * received from the host, it indicates that BMC can do a power off. - * If BMC fails to get any response, then a hard power off would - * be forced. - * - * @return - Does not return anything. Error will result in exception - * being thrown - */ - void sendHostShutDownCmd(); - - /** @brief Callback function on host control signals - * - * @param[in] msg - Data associated with subscribed signal - * - */ - void hostControlEvent(sdbusplus::message::message& msg); - + public: + /** @brief Constructs SoftPowerOff object. + * + * @param[in] bus - system dbus handler + * @param[in] event - sd_event handler + * @param[in] objPath - The Dbus path hosting SoftPowerOff function + */ + SoftPowerOff(sdbusplus::bus::bus& bus, sd_event* event, + const char* objPath) : + sdbusplus::server::object::object<Base::SoftPowerOff>(bus, objPath, + false), + bus(bus), timer(event), + hostControlSignal( + bus, + sdbusRule::type::signal() + sdbusRule::member("CommandComplete") + + sdbusRule::path("/xyz/openbmc_project/control/host0") + + sdbusRule::interface(CONTROL_HOST_BUSNAME) + + sdbusRule::argN(0, convertForMessage(Host::Command::SoftOff)), + std::bind(std::mem_fn(&SoftPowerOff::hostControlEvent), this, + std::placeholders::_1)) + { + // Need to announce since we may get the response + // very quickly on host shutdown command + emit_object_added(); + + // The whole purpose of this application is to send a host shutdown + // command and watch for the soft power off to go through. We need + // the interface added signal emitted before we send the shutdown + // command just to attend to lightning fast response from host + sendHostShutDownCmd(); + } + + /** @brief Tells if the objective of this application is completed */ + inline auto isCompleted() + { + return completed; + } + + /** @brief Tells if the referenced timer is expired or not */ + inline auto isTimerExpired() + { + return timer.isExpired(); + } + + /** @brief overloaded property setter function + * + * @param[in] value - One of SoftOffReceived / HostShutdown + * + * @return Success or exception thrown + */ + HostResponse responseReceived(HostResponse value) override; + + /** @brief Using the base class's getter method */ + using Base::SoftPowerOff::responseReceived; + + /** @brief Calls to start a timer + * + * @param[in] usec - Time in microseconds + * + * @return Success or exception thrown + */ + int startTimer(const std::chrono::microseconds& usec); + + private: + // Need this to send SMS_ATTN + // TODO : Switch over to using mapper service in a different patch + static constexpr auto HOST_IPMI_BUS = "org.openbmc.HostIpmi"; + static constexpr auto HOST_IPMI_OBJ = "/org/openbmc/HostIpmi/1"; + static constexpr auto HOST_IPMI_INTF = "org.openbmc.HostIpmi"; + + /* @brief sdbusplus handle */ + sdbusplus::bus::bus& bus; + + /** @brief Reference to Timer object */ + Timer timer; + + /** @brief Marks the end of life of this application. + * + * This is set to true if host gives appropriate responses + * for the sequence of commands. + */ + bool completed = false; + + /** @brief Subscribe to host control signals + * + * Protocol is to send the host power off request to the host + * control interface and then wait for a signal indicating pass/fail + **/ + sdbusplus::bus::match_t hostControlSignal; + + /** @brief Sends host control command to tell host to shut down + * + * After sending the command, wait for a signal indicating the status + * of the command. + * + * After receiving the initial response, start a timer for 30 minutes + * to let host do a clean shutdown of partitions. When the response is + * received from the host, it indicates that BMC can do a power off. + * If BMC fails to get any response, then a hard power off would + * be forced. + * + * @return - Does not return anything. Error will result in exception + * being thrown + */ + void sendHostShutDownCmd(); + + /** @brief Callback function on host control signals + * + * @param[in] msg - Data associated with subscribed signal + * + */ + void hostControlEvent(sdbusplus::message::message& msg); }; } // namespace ipmi } // namespace phosphor diff --git a/softoff/test/utest.cpp b/softoff/test/utest.cpp index baaead4..0dd99ae 100644 --- a/softoff/test/utest.cpp +++ b/softoff/test/utest.cpp @@ -1,85 +1,83 @@ -#include <iostream> +#include "timer.hpp" + #include <chrono> +#include <iostream> + #include <gtest/gtest.h> -#include "timer.hpp" using namespace phosphor::ipmi; class TimerTest : public ::testing::Test { - public: - // systemd event handler - sd_event* events; + public: + // systemd event handler + sd_event* events; - // Need this so that events can be initialized. - int rc; + // Need this so that events can be initialized. + int rc; - // Source of event - sd_event_source* eventSource = nullptr; + // Source of event + sd_event_source* eventSource = nullptr; - // Add a Timer Object - Timer timer; + // Add a Timer Object + Timer timer; - // Gets called as part of each TEST_F construction - TimerTest() - : rc(sd_event_default(&events)), - timer(events) - { - // Check for successful creation of - // event handler and timer object. - EXPECT_GE(rc, 0); - } + // Gets called as part of each TEST_F construction + TimerTest() : rc(sd_event_default(&events)), timer(events) + { + // Check for successful creation of + // event handler and timer object. + EXPECT_GE(rc, 0); + } - // Gets called as part of each TEST_F destruction - ~TimerTest() - { - events = sd_event_unref(events); - } + // Gets called as part of each TEST_F destruction + ~TimerTest() + { + events = sd_event_unref(events); + } }; - class TimerTestCallBack : public ::testing::Test { - public: - // systemd event handler - sd_event* events; + public: + // systemd event handler + sd_event* events; - // Need this so that events can be initialized. - int rc; + // Need this so that events can be initialized. + int rc; - // Source of event - sd_event_source* eventSource = nullptr; + // Source of event + sd_event_source* eventSource = nullptr; - // Add a Timer Object - std::unique_ptr<Timer> timer = nullptr; + // Add a Timer Object + std::unique_ptr<Timer> timer = nullptr; - // Indicates optional call back fun was called - bool callBackDone = false; + // Indicates optional call back fun was called + bool callBackDone = false; - void callBack() - { - callBackDone = true; - } + void callBack() + { + callBackDone = true; + } - // Gets called as part of each TEST_F construction - TimerTestCallBack() - : rc(sd_event_default(&events)) + // Gets called as part of each TEST_F construction + TimerTestCallBack() : rc(sd_event_default(&events)) - { - // Check for successful creation of - // event handler and timer object. - EXPECT_GE(rc, 0); + { + // Check for successful creation of + // event handler and timer object. + EXPECT_GE(rc, 0); - std::function<void()> func(std::bind( - &TimerTestCallBack::callBack, this)); - timer = std::make_unique<Timer>(events, func); - } + std::function<void()> func( + std::bind(&TimerTestCallBack::callBack, this)); + timer = std::make_unique<Timer>(events, func); + } - // Gets called as part of each TEST_F destruction - ~TimerTestCallBack() - { - events = sd_event_unref(events); - } + // Gets called as part of each TEST_F destruction + ~TimerTestCallBack() + { + events = sd_event_unref(events); + } }; /** @brief Makes sure that timer is expired and the @@ -95,11 +93,11 @@ TEST_F(TimerTest, timerExpiresAfter2seconds) // Waiting 2 seconds is enough here since we have // already spent some usec now int count = 0; - while(count < 2 && !timer.isExpired()) + while (count < 2 && !timer.isExpired()) { // Returns -0- on timeout and positive number on dispatch auto sleepTime = duration_cast<microseconds>(seconds(1)); - if(!sd_event_run(events, sleepTime.count())) + if (!sd_event_run(events, sleepTime.count())) { count++; } @@ -123,11 +121,11 @@ TEST_F(TimerTest, timerNotExpiredAfter2Seconds) // Wait 2 seconds and see that timer is not expired int count = 0; - while(count < 2) + while (count < 2) { // Returns -0- on timeout auto sleepTime = duration_cast<microseconds>(seconds(1)); - if(!sd_event_run(events, sleepTime.count())) + if (!sd_event_run(events, sleepTime.count())) { count++; } @@ -157,11 +155,11 @@ TEST_F(TimerTest, updateTimerAndExpectExpire) // Wait 3 seconds and see that timer is expired int count = 0; - while(count < 3 && !timer.isExpired()) + while (count < 3 && !timer.isExpired()) { // Returns -0- on timeout auto sleepTime = duration_cast<microseconds>(seconds(1)); - if(!sd_event_run(events, sleepTime.count())) + if (!sd_event_run(events, sleepTime.count())) { count++; } @@ -193,11 +191,11 @@ TEST_F(TimerTest, updateTimerAndNeverExpire) // Wait 2 seconds and see that timer is expired int count = 0; - while(count < 2) + while (count < 2) { // Returns -0- on timeout auto sleepTime = duration_cast<microseconds>(seconds(1)); - if(!sd_event_run(events, sleepTime.count())) + if (!sd_event_run(events, sleepTime.count())) { count++; } @@ -219,11 +217,11 @@ TEST_F(TimerTestCallBack, optionalFuncCallBackDone) // Waiting 2 seconds is enough here since we have // already spent some usec now int count = 0; - while(count < 2 && !timer->isExpired()) + while (count < 2 && !timer->isExpired()) { // Returns -0- on timeout and positive number on dispatch auto sleepTime = duration_cast<microseconds>(seconds(1)); - if(!sd_event_run(events, sleepTime.count())) + if (!sd_event_run(events, sleepTime.count())) { count++; } @@ -248,11 +246,11 @@ TEST_F(TimerTestCallBack, timerNotExpiredAfter2SecondsNoOptionalCallBack) // Wait 2 seconds and see that timer is not expired int count = 0; - while(count < 2) + while (count < 2) { // Returns -0- on timeout auto sleepTime = duration_cast<microseconds>(seconds(1)); - if(!sd_event_run(events, sleepTime.count())) + if (!sd_event_run(events, sleepTime.count())) { count++; } |