From dd2c6fdc50572c90d5919d0839f1dac82388c2ed Mon Sep 17 00:00:00 2001 From: Andrew Geissler Date: Thu, 16 Mar 2017 15:53:20 -0500 Subject: Compile new control host code The purpose of this series of commits is to provide the ability for other services to communicate with the host. Specifically with this series, to be able to request the host power itself down or to simply check if the host is running. Change-Id: I0136467cd3f258fbed3e40e4b7269ed4d8a23e46 Signed-off-by: Andrew Geissler --- Makefile.am | 13 +++++ host-interface.cpp | 9 ++++ host-interface.hpp | 34 +++++++++++++ host-services.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++++++++ host-services.h | 3 ++ 5 files changed, 203 insertions(+) create mode 100644 host-interface.cpp create mode 100644 host-interface.hpp create mode 100644 host-services.c create mode 100644 host-services.h diff --git a/Makefile.am b/Makefile.am index 5cc9059..409cd3f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -47,6 +47,19 @@ libsysintfcmds_la_SOURCES = \ libsysintfcmds_la_LDFLAGS = $(SYSTEMD_LIBS) $(libmapper_LIBS) -version-info 0:0:0 -shared libsysintfcmds_la_CXXFLAGS = $(SYSTEMD_CFLAGS) $(libmapper_CFLAGS) +libhostservicedir = ${libdir}/ipmid-providers +libhostservice_LTLIBRARIES = libhostservice.la +libhostservice_la_SOURCES = \ + host-services.c \ + host-interface.cpp +libhostservice_la_LDFLAGS = $(SYSTEMD_LIBS) \ + $(libmapper_LIBS) \ + $(PHOSPHOR_DBUS_INTERFACES_LIBS) \ + -version-info 0:0:0 -shared +libhostservice_la_CXXFLAGS = $(SYSTEMD_CFLAGS) \ + $(PHOSPHOR_DBUS_INTERFACES_CFLAGS) \ + $(libmapper_CFLAGS) + nobase_include_HEADERS = \ host-ipmid/ipmid-api.h diff --git a/host-interface.cpp b/host-interface.cpp new file mode 100644 index 0000000..010eef1 --- /dev/null +++ b/host-interface.cpp @@ -0,0 +1,9 @@ +#include "host-interface.hpp" + +namespace phosphor +{ +namespace host +{ + +} // namespace host +} // namepsace phosphor diff --git a/host-interface.hpp b/host-interface.hpp new file mode 100644 index 0000000..793a5cb --- /dev/null +++ b/host-interface.hpp @@ -0,0 +1,34 @@ +#pragma once + +#include +#include + +namespace phosphor +{ +namespace host +{ + +/** @class Host + * @brief OpenBMC control host interface implementation. + * @details A concrete implementation for xyz.openbmc_project.Control.Host + * DBus API. + */ +class Host : public sdbusplus::server::object::object< + sdbusplus::xyz::openbmc_project::Control::server::Host> +{ + public: + /** @brief Constructs Host Control Interface + * + * @param[in] bus - The Dbus bus object + * @param[in] objPath - The Dbus object path + */ + Host(sdbusplus::bus::bus& bus, + const char* objPath) : + sdbusplus::server::object::object< + sdbusplus::xyz::openbmc_project::Control::server::Host>( + bus, objPath) + {} +}; + +} // namespace host +} // namespace phosphor diff --git a/host-services.c b/host-services.c new file mode 100644 index 0000000..b0b12ae --- /dev/null +++ b/host-services.c @@ -0,0 +1,144 @@ +#include +#include +#include +#include +#include +#include "host-ipmid/ipmid-api.h" + +void register_host_services() __attribute__((constructor)); + +// OpenBMC Host IPMI dbus framework +const char *object_name = "/org/openbmc/HostIpmi/1"; +const char *intf_name = "org.openbmc.HostIpmi"; + +//------------------------------------------------------------------- +// Gets called by PowerOff handler when a Soft Power off is requested +//------------------------------------------------------------------- +static int soft_power_off(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) +{ + int64_t bt_resp = -1; + int rc = 0; + char *bus_name = NULL; + + // Steps to be taken when we get this. + // 1: Send a SMS_ATN to the Host + // 2: Host receives it and sends a GetMsgFlags IPMI command + // 3: IPMID app handler will respond to that with a MSgFlag with bit:0x2 + // set indicating we have a message for Host + // 4: Host sends a GetMsgBuffer command and app handler will respond to + // that with a OEM-SEL with certain fields packed indicating to the + // host that it do a shutdown of the partitions. + // 5: Host does the partition shutdown and calls Chassis Power off command + // 6: App handler handles the command by making a call to ChassisManager + // Dbus + + // Now the job is to send the SMS_ATTN. + + // Req message contains the specifics about which method etc that we want to + // access on which bus, object + sd_bus_message *response = NULL; + + // Error return mechanism + sd_bus_error bus_error = SD_BUS_ERROR_NULL; + + // Gets a hook onto either a SYSTEM or SESSION bus + sd_bus *bus = ipmid_get_sd_bus_connection(); + rc = mapper_get_service(bus, object_name, &bus_name); + if (rc < 0) { + fprintf(stderr, "Failed to get %s bus name: %s\n", + object_name, strerror(-rc)); + goto finish; + } + rc = sd_bus_call_method(bus, // In the System Bus + bus_name, // Service to contact + object_name, // Object path + intf_name, // Interface name + "setAttention", // Method to be called + &bus_error, // object to return error + &response, // Response buffer if any + NULL); // No input arguments + if(rc < 0) + { + fprintf(stderr,"ERROR initiating Power Off:[%s]\n",bus_error.message); + goto finish; + } + + // See if we were able to successfully raise SMS_ATN + rc = sd_bus_message_read(response, "x", &bt_resp); + if (rc < 0) + { + fprintf(stderr, "Failed to get a rc from BT for SMS_ATN: %s\n", strerror(-rc)); + goto finish; + } + +finish: + sd_bus_error_free(&bus_error); + response = sd_bus_message_unref(response); + free(bus_name); + + if(rc < 0) + { + return sd_bus_reply_method_return(m, "x", rc); + } + else + { + return sd_bus_reply_method_return(m, "x", bt_resp); + } +} + +//------------------------------------------- +// Function pointer of APIs exposed via Dbus +//------------------------------------------- +static const sd_bus_vtable host_services_vtable[] = +{ + SD_BUS_VTABLE_START(0), + // Takes No("") arguments -but- returns a value of type 64 bit integer("x") + SD_BUS_METHOD("SoftPowerOff", "", "x", &soft_power_off, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_VTABLE_END, +}; + +//------------------------------------------------------ +// Called by IPMID as part of the start up +// ----------------------------------------------------- +int start_host_service(sd_bus *bus, sd_bus_slot *slot) +{ + int rc = 0; + + /* Install the object */ + rc = sd_bus_add_object_vtable(bus, + &slot, + "/org/openbmc/HostServices", /* object path */ + "org.openbmc.HostServices", /* interface name */ + host_services_vtable, + NULL); + if (rc < 0) + { + fprintf(stderr, "Failed to issue method call: %s\n", strerror(-rc)); + } + else + { + /* Take one in OpenBmc */ + rc = sd_bus_request_name(bus, "org.openbmc.HostServices", 0); + if (rc < 0) + { + fprintf(stderr, "Failed to acquire service name: %s\n", strerror(-rc)); + } + } + + return rc < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} + +//------------------------------------------------------ +// Callback register function +// ----------------------------------------------------- +void register_host_services() +{ + // Gets a hook onto SYSTEM bus used by host-ipmid + sd_bus *bus = ipmid_get_sd_bus_connection(); + + // Gets a hook onto SYSTEM bus slot used by host-ipmid + sd_bus_slot *ipmid_slot = ipmid_get_sd_bus_slot(); + + //start_host_service(bus, ipmid_slot); + start_host_service(bus, ipmid_slot); +} diff --git a/host-services.h b/host-services.h new file mode 100644 index 0000000..0d93480 --- /dev/null +++ b/host-services.h @@ -0,0 +1,3 @@ +#include + +extern "C" int start_host_service(sd_bus *, sd_bus_slot *); -- cgit v1.2.1