summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Geissler <andrewg@us.ibm.com>2017-03-16 15:53:20 -0500
committerAndrew Geissler <andrewg@us.ibm.com>2017-05-09 09:34:44 -0500
commitdd2c6fdc50572c90d5919d0839f1dac82388c2ed (patch)
tree63affe519f944b12b68586591ba08a6931adc076
parent00f0815b9f34dce75e77001fa56dbc1f44bba2ff (diff)
downloadphosphor-host-ipmid-dd2c6fdc50572c90d5919d0839f1dac82388c2ed.tar.gz
phosphor-host-ipmid-dd2c6fdc50572c90d5919d0839f1dac82388c2ed.zip
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 <andrewg@us.ibm.com>
-rw-r--r--Makefile.am13
-rw-r--r--host-interface.cpp9
-rw-r--r--host-interface.hpp34
-rw-r--r--host-services.c144
-rw-r--r--host-services.h3
5 files changed, 203 insertions, 0 deletions
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 <sdbusplus/bus.hpp>
+#include <xyz/openbmc_project/Control/Host/server.hpp>
+
+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 <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <systemd/sd-bus.h>
+#include <mapper.h>
+#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 <systemd/sd-bus.h>
+
+extern "C" int start_host_service(sd_bus *, sd_bus_slot *);
OpenPOWER on IntegriCloud