blob: de32c0155c05a78e8689671614c200f25c0b2cc8 [file] [log] [blame]
From 7a74bdc8d1b0b32c35dc83e130f687a52dfda1e8 Mon Sep 17 00:00:00 2001
From: Jeremy Kerr <jk@ozlabs.org>
Date: Tue, 13 Oct 2015 09:17:21 +0800
Subject: [PATCH] plugins: Add a backend for the OpenBMC dbus interface
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Includes the following commits from the following authors
plugins/dbus: Split netfn from lun, and ccode from data
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
plugins/dbus: fix missing semicolon
Reported-by: Chris Austen <austenc@us.ibm.com>
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
plugins/dbus: Fix ccode response
We need to copy it in from the dbus reply.
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
plugins/dbus: Use default dbus connection
... so we'll use the system bus if run as UID 0.
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
if no interface is specified, use the dbus interface by default
This is a patch that should only be on openbmc, not sent upstream
because the dbus interface is really only an openbmc thing.
Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
---
configure.ac | 19 ++++
src/plugins/Makefile.am | 4 +-
src/plugins/dbus/Makefile.am | 41 ++++++++
src/plugins/dbus/dbus.c | 199 +++++++++++++++++++++++++++++++++++
src/plugins/ipmi_intf.c | 6 ++
5 files changed, 267 insertions(+), 2 deletions(-)
create mode 100644 src/plugins/dbus/Makefile.am
create mode 100644 src/plugins/dbus/dbus.c
diff --git a/configure.ac b/configure.ac
index f2fe1f3..81cc925 100644
--- a/configure.ac
+++ b/configure.ac
@@ -60,6 +60,7 @@ xenable_all_options=yes
xenable_intf_bmc=no
xenable_intf_dummy=no
xenable_intf_imb=yes
+xenable_intf_dbus=yes
xenable_intf_lipmi=yes
xenable_intf_open=yes
#xenable_intf_serial=yes
@@ -222,6 +223,22 @@ if test "x$xenable_intf_usb" = "xyes"; then
IPMITOOL_INTF_LIB="$IPMITOOL_INTF_LIB usb/libintf_usb.la"
fi
+dnl enable IPMI dbus interface
+AC_ARG_ENABLE([intf-dbus],
+ [AC_HELP_STRING([--enable-intf-dbus],
+ [enable IPMI dbus interface [default=yes]])],
+ [xenable_intf_dbus=$enableval],
+ [xenable_intf_dbus=yes])
+if test "x$xenable_intf_dbus" = "xstatic" || test "x$xenable_intf_dbus" = "xplugin"; then
+ xenable_intf_dbus=yes
+fi
+if test "x$xenable_intf_dbus" = "xyes"; then
+ AC_DEFINE(IPMI_INTF_DBUS, [1], [Define to 1 to enable dbus interface.])
+ AC_SUBST(INTF_DBUS, [dbus])
+ AC_SUBST(INTF_DBUS_LIB, [libintf_dbus.la])
+ IPMITOOL_INTF_LIB="$IPMITOOL_INTF_LIB dbus/libintf_dbus.la"
+fi
+
dnl enable IPMIv2.0 RMCP+ LAN interface
AC_ARG_ENABLE([intf-lanplus],
[AC_HELP_STRING([--enable-intf-lanplus],
@@ -664,6 +681,7 @@ AC_CONFIG_FILES([Makefile
src/plugins/imb/Makefile
src/plugins/bmc/Makefile
src/plugins/usb/Makefile
+ src/plugins/dbus/Makefile
src/plugins/lipmi/Makefile
src/plugins/serial/Makefile
src/plugins/dummy/Makefile])
@@ -681,6 +699,7 @@ AC_MSG_RESULT([ free : $xenable_intf_free])
AC_MSG_RESULT([ imb : $xenable_intf_imb])
AC_MSG_RESULT([ bmc : $xenable_intf_bmc])
AC_MSG_RESULT([ usb : $xenable_intf_usb])
+AC_MSG_RESULT([ dbus : $xenable_intf_dbus])
AC_MSG_RESULT([ lipmi : $xenable_intf_lipmi])
AC_MSG_RESULT([ serial : $xenable_intf_serial])
AC_MSG_RESULT([ dummy : $xenable_intf_dummy])
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index 7ad8173..c0b0b29 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -32,8 +32,8 @@ MAINTAINERCLEANFILES = Makefile.in
AM_CPPFLAGS = -I$(top_srcdir)/include
-SUBDIRS = @INTF_LAN@ @INTF_LANPLUS@ @INTF_OPEN@ @INTF_LIPMI@ @INTF_IMB@ @INTF_BMC@ @INTF_FREE@ @INTF_SERIAL@ @INTF_DUMMY@ @INTF_USB@
-DIST_SUBDIRS = lan lanplus open lipmi imb bmc free serial dummy usb
+SUBDIRS = @INTF_LAN@ @INTF_LANPLUS@ @INTF_OPEN@ @INTF_LIPMI@ @INTF_IMB@ @INTF_BMC@ @INTF_FREE@ @INTF_SERIAL@ @INTF_DUMMY@ @INTF_USB@ @INTF_DBUS@
+DIST_SUBDIRS = lan lanplus open lipmi imb bmc free serial dummy usb dbus
noinst_LTLIBRARIES = libintf.la
libintf_la_SOURCES = ipmi_intf.c
diff --git a/src/plugins/dbus/Makefile.am b/src/plugins/dbus/Makefile.am
new file mode 100644
index 0000000..3e92113
--- /dev/null
+++ b/src/plugins/dbus/Makefile.am
@@ -0,0 +1,41 @@
+ #
+ # Copyright (c) 2015 IBM Corporation
+ # All rights reserved.
+ #
+ # Redistribution and use in source and binary forms, with or without
+ # modification,are permitted provided that the following conditions are met:
+ #
+ # 1. Redistributions of source code must retain the above copyright notice,
+ # this list of conditions and the following disclaimer.
+ #
+ # 2. Redistributions in binary form must reproduce the above copyright notice,
+ # this list of conditions and the following disclaimer in the documentation
+ # and/or other materials provided with the distribution.
+ #
+ # 3. Neither the name of the copyright holder nor the names of its contributors
+ # may be used to endorse or promote products derived from this software
+ # without specific prior written permission.
+ #
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ # POSSIBILITY OF SUCH DAMAGE.
+ #
+
+MAINTAINERCLEANFILES = Makefile.in
+
+INCLUDES = -I$(top_srcdir)/include
+
+EXTRA_LTLIBRARIES = libintf_dbus.la
+noinst_LTLIBRARIES = @INTF_DBUS_LIB@
+libintf_dbus_la_LDFLAGS = -lsystemd
+libintf_dbus_la_LIBADD = $(top_builddir)/lib/libipmitool.la
+libintf_dbus_la_SOURCES = dbus.c
+
diff --git a/src/plugins/dbus/dbus.c b/src/plugins/dbus/dbus.c
new file mode 100644
index 0000000..c20545f
--- /dev/null
+++ b/src/plugins/dbus/dbus.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2015 IBM Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define _BSD_SOURCE
+
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdbool.h>
+
+#include <systemd/sd-bus.h>
+#include <systemd/sd-bus-vtable.h>
+
+#include <ipmitool/log.h>
+#include <ipmitool/ipmi.h>
+#include <ipmitool/ipmi_intf.h>
+
+static sd_bus *bus;
+static uint8_t seq;
+static struct ipmi_rs rsp;
+static bool reply_received;
+
+static const char *bus_name = "org.openbmc.HostIpmi.ipmitool";
+static const char *object_path = "/org/openbmc/HostIpmi/ipmitool";
+static const char *interface = "org.openbmc.HostIpmi";
+
+static struct ipmi_rs *ipmi_dbus_sendrecv(struct ipmi_intf *intf,
+ struct ipmi_rq *req)
+{
+ sd_bus_message *msg;
+ int rc;
+
+ (void)intf;
+
+ rsp.ccode = 0xff;
+
+ rc = sd_bus_message_new_signal(bus, &msg, object_path,
+ interface, "ReceivedMessage");
+ if (rc < 0) {
+ lprintf(LOG_ERR, "%s: failed to create message: %s\n",
+ __func__, strerror(-rc));
+ goto out;
+ }
+
+ rc = sd_bus_message_append(msg, "yyyy",
+ ++seq,
+ req->msg.netfn,
+ req->msg.lun,
+ req->msg.cmd);
+ if (rc < 0) {
+ lprintf(LOG_ERR, "%s: failed to init bytes\n", __func__);
+ goto out_free;
+ }
+
+ rc = sd_bus_message_append_array(msg, 'y', req->msg.data,
+ req->msg.data_len);
+ if (rc < 0) {
+ lprintf(LOG_ERR, "%s: failed to init body\n", __func__);
+ goto out_free;
+ }
+
+ rc = sd_bus_send(bus, msg, NULL);
+ if (rc < 0) {
+ lprintf(LOG_ERR, "%s: failed to send dbus message\n",
+ __func__);
+ goto out_free;
+ }
+
+ for (reply_received = false; !reply_received;) {
+ rc = sd_bus_wait(bus, -1);
+ sd_bus_process(bus, NULL);
+ }
+
+out_free:
+ sd_bus_message_unref(msg);
+out:
+ return &rsp;
+}
+
+static int ipmi_dbus_method_send_message(sd_bus_message *msg, void *userdata,
+ sd_bus_error *error)
+{
+ uint8_t recv_seq, recv_netfn, recv_lun, recv_cmd, recv_cc;
+ const void *data;
+ size_t n;
+ int rc;
+
+ (void)userdata;
+ (void)error;
+
+ rc = sd_bus_message_read(msg, "yyyyy", &recv_seq, &recv_netfn,
+ &recv_lun, &recv_cmd, &recv_cc);
+ if (rc < 0) {
+ lprintf(LOG_ERR, "%s: failed to read reply\n", __func__);
+ goto out;
+ }
+
+ rc = sd_bus_message_read_array(msg, 'y', &data, &n);
+ if (rc < 0) {
+ lprintf(LOG_ERR, "%s: failed to read reply data\n", __func__);
+ goto out;
+ }
+
+ if (n > sizeof(rsp.data)) {
+ lprintf(LOG_ERR, "%s: data too long!\n", __func__);
+ goto out;
+ }
+
+ if (recv_seq == seq) {
+ rsp.ccode = recv_cc;
+ rsp.data_len = n;
+ memcpy(rsp.data, data, rsp.data_len);
+ reply_received = true;
+ }
+
+out:
+ sd_bus_reply_method_return(msg, "x", 0);
+ return 0;
+}
+
+static const sd_bus_vtable dbus_vtable[] = {
+ SD_BUS_VTABLE_START(0),
+ SD_BUS_SIGNAL("ReceivedMessage", "yyyyay", 0),
+ SD_BUS_METHOD("sendMessage", "yyyyyay", "x",
+ ipmi_dbus_method_send_message,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_VTABLE_END
+};
+
+static int ipmi_dbus_setup(struct ipmi_intf *intf)
+{
+ const char *name;
+ int rc;
+
+ rc = sd_bus_default(&bus);
+ if (rc < 0) {
+ lprintf(LOG_ERR, "Can't connect to session bus: %s\n",
+ strerror(-rc));
+ return -1;
+ }
+
+ sd_bus_add_object_vtable(bus, NULL, object_path, interface,
+ dbus_vtable, NULL);
+
+ sd_bus_request_name(bus, bus_name, SD_BUS_NAME_REPLACE_EXISTING);
+
+ sd_bus_flush(bus);
+ sd_bus_get_unique_name(bus, &name);
+ intf->opened = 1;
+
+ return 0;
+}
+
+static void ipmi_dbus_close(struct ipmi_intf *intf)
+{
+ if (intf->opened)
+ sd_bus_close(bus);
+ intf->opened = 0;
+}
+
+struct ipmi_intf ipmi_dbus_intf = {
+ .name = "dbus",
+ .desc = "OpenBMC dbus interface",
+ .setup = ipmi_dbus_setup,
+ .close = ipmi_dbus_close,
+ .sendrecv = ipmi_dbus_sendrecv,
+};
diff --git a/src/plugins/ipmi_intf.c b/src/plugins/ipmi_intf.c
index 9225a34..56c2543 100644
--- a/src/plugins/ipmi_intf.c
+++ b/src/plugins/ipmi_intf.c
@@ -89,8 +89,14 @@ extern struct ipmi_intf ipmi_dummy_intf;
#ifdef IPMI_INTF_USB
extern struct ipmi_intf ipmi_usb_intf;
#endif
+#ifdef IPMI_INTF_DBUS
+extern struct ipmi_intf ipmi_dbus_intf;
+#endif
struct ipmi_intf * ipmi_intf_table[] = {
+#ifdef IPMI_INTF_DBUS
+ &ipmi_dbus_intf,
+#endif
#ifdef IPMI_INTF_OPEN
&ipmi_open_intf,
#endif
--
2.17.1