From a6e3a3080d532536e02e304c819c1e17214e038a Mon Sep 17 00:00:00 2001 From: Andrew Geissler Date: Wed, 31 May 2017 19:34:00 -0500 Subject: Create file to indicate host requested off/reboot Create a file to ensure the soft power off service is not run when the host is requesting a power off or reboot. There's no need to notify the host (i.e. soft power off) when they are initiating it. Change-Id: Ic9f8e7110d30f477ceae38bba9d684559d9503d3 Signed-off-by: Andrew Geissler --- Makefile.am | 2 +- chassishandler.cpp | 63 +++++++++++++++++++++++++++++++++++++++++++++++------- configure.ac | 13 +++++++++++ elog-errors.hpp | 1 - 4 files changed, 69 insertions(+), 10 deletions(-) diff --git a/Makefile.am b/Makefile.am index e0412b6..d987cc3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -41,7 +41,7 @@ libapphandler_la_SOURCES = \ utils.cpp \ inventory-sensor-gen.cpp -libapphandler_la_LDFLAGS = $(SYSTEMD_LIBS) $(libmapper_LIBS) $(PHOSPHOR_LOGGING_LIBS) $(PHOSPHOR_DBUS_INTERFACES_LIBS) -version-info 0:0:0 -shared +libapphandler_la_LDFLAGS = $(SYSTEMD_LIBS) $(libmapper_LIBS) $(PHOSPHOR_LOGGING_LIBS) $(PHOSPHOR_DBUS_INTERFACES_LIBS) -lstdc++fs -version-info 0:0:0 -shared libapphandler_la_CXXFLAGS = $(SYSTEMD_CFLAGS) $(libmapper_CFLAGS) $(PHOSPHOR_LOGGING_CFLAGS) $(PHOSPHOR_DBUS_INTERFACES_CFLAGS) libsysintfcmdsdir = ${libdir}/ipmid-providers diff --git a/chassishandler.cpp b/chassishandler.cpp index ef5647c..5dc23b2 100644 --- a/chassishandler.cpp +++ b/chassishandler.cpp @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include #include #include "config.h" @@ -44,7 +46,7 @@ static constexpr size_t IPADDR_OFFSET = 17; static constexpr size_t PREFIX_OFFSET = 21; static constexpr size_t GATEWAY_OFFSET = 22; - +using namespace phosphor::logging; void register_netfn_chassis_functions() __attribute__((constructor)); @@ -76,6 +78,8 @@ typedef struct // Phosphor Host State manager namespace State = sdbusplus::xyz::openbmc_project::State::server; +namespace fs = std::experimental::filesystem; + int dbus_get_property(const char *name, char **buf) { sd_bus_error error = SD_BUS_ERROR_NULL; @@ -577,8 +581,6 @@ ipmi_ret_t ipmi_get_chassis_cap(ipmi_netfn_t netfn, ipmi_cmd_t cmd, //------------------------------------------ int initiate_state_transition(State::Host::Transition transition) { - using namespace phosphor::logging; - // OpenBMC Host State Manager dbus framework constexpr auto HOST_STATE_MANAGER_ROOT = "/xyz/openbmc_project/state/host0"; constexpr auto HOST_STATE_MANAGER_IFACE = "xyz.openbmc_project.State.Host"; @@ -851,6 +853,29 @@ int stop_soft_off_timer() return rc; } +//---------------------------------------------------------------------- +// Create file to indicate there is no need for softoff notification to host +//---------------------------------------------------------------------- +void indicate_no_softoff_needed() +{ + fs::path path{HOST_INBAND_REQUEST_DIR}; + if (!fs::is_directory(path)) + { + fs::create_directory(path); + } + + // Add the host instance (default 0 for now) to the file name + std::string file{HOST_INBAND_REQUEST_FILE}; + auto size = std::snprintf(nullptr,0,file.c_str(),0); + size++; // null + std::unique_ptr buf(new char[size]); + std::snprintf(buf.get(),size,file.c_str(),0); + + // Append file name to directory and create it + path /= buf.get(); + std::ofstream(path.c_str()); +} + //---------------------------------------------------------------------- // Chassis Control commands //---------------------------------------------------------------------- @@ -879,13 +904,28 @@ ipmi_ret_t ipmi_chassis_control(ipmi_netfn_t netfn, ipmi_cmd_t cmd, // Need to Nudge SoftPowerOff application that it needs to stop the // watchdog timer if running. rc = stop_soft_off_timer(); - if (!rc) + // Only request the Off transition if the soft power off + // application is not running + if (rc < 0) { - fprintf(stderr, "Error stopping watchdog timer"); + log("Did not find soft off service so request " + "Host:Transition:Off"); + + // First create a file to indicate to the soft off application + // that it should not run since this is a direct user initiated + // power off request (i.e. a power off request that is not + // originating via a soft power off SMS request) + indicate_no_softoff_needed(); + + // Now request the shutdown + rc = initiate_state_transition(State::Host::Transition::Off); } - // Does not matter if we are able to stop the timer, - // just get going and do the hard power off - rc = initiate_state_transition(State::Host::Transition::Off); + else + { + log("Soft off is running, so let that stop " + "the host"); + } + break; case CMD_HARD_RESET: @@ -893,6 +933,13 @@ ipmi_ret_t ipmi_chassis_control(ipmi_netfn_t netfn, ipmi_cmd_t cmd, // SPEC has a section that says certain implementations can trigger // PowerOn if power is Off when a command to power cycle is // requested + + // First create a file to indicate to the soft off application + // that it should not run since this is a direct user initiated + // power reboot request (i.e. a reboot request that is not + // originating via a soft power off SMS request) + indicate_no_softoff_needed(); + rc = initiate_state_transition(State::Host::Transition::Reboot); break; default: diff --git a/configure.ac b/configure.ac index 4f534df..076cc6f 100644 --- a/configure.ac +++ b/configure.ac @@ -101,6 +101,19 @@ AS_IF([test "x$enable_softoff" != "xno"], [AC_ARG_VAR(IPMI_HOST_SHUTDOWN_COMPLETE_TIMEOUT_SECS, [Wait time until Host can quiesce])] [AC_DEFINE_UNQUOTED([IPMI_HOST_SHUTDOWN_COMPLETE_TIMEOUT_SECS], [45*60], [Wait time until Host can quiesce])] + + # Indicates an in-band power off or reboot request from the host + # This file is used to ensure the soft off service does not run for host + # initiated shutdown or reboot requests + [AC_ARG_VAR(HOST_INBAND_REQUEST_DIR, [Directory used to indicate the host has initiated a shutdown or reboot])] + AS_IF([test "x$HOST_INBAND_REQUEST_DIR" == "x"], + [HOST_INBAND_REQUEST_DIR="/run/openbmc/"]) + [AC_DEFINE_UNQUOTED([HOST_INBAND_REQUEST_DIR], ["$HOST_INBAND_REQUEST_DIR"], [Directory to store host initiated shutdown file])] + + [AC_ARG_VAR(HOST_INBAND_REQUEST_FILE, [File which indicates the host has initiated a shutdown or reboot])] + AS_IF([test "x$HOST_INBAND_REQUEST_FILE" == "x"], + [HOST_INBAND_REQUEST_FILE="host@%u-request"]) + [AC_DEFINE_UNQUOTED([HOST_INBAND_REQUEST_FILE], ["$HOST_INBAND_REQUEST_FILE"], [File to create if host has initiated shutdown or reboot])] ) # Control Host Interfaces diff --git a/elog-errors.hpp b/elog-errors.hpp index de74160..1db2709 100644 --- a/elog-errors.hpp +++ b/elog-errors.hpp @@ -61,7 +61,6 @@ struct QueueEmpty : public sdbusplus::exception_t } // namespace openbmc_project } // namespace xyz - } // namespace logging } // namespace phosphor -- cgit v1.2.1