blob: de32c0155c05a78e8689671614c200f25c0b2cc8 [file] [log] [blame]
Ed Tanousfe41c382019-01-11 16:26:13 -08001From 7a74bdc8d1b0b32c35dc83e130f687a52dfda1e8 Mon Sep 17 00:00:00 2001
2From: Jeremy Kerr <jk@ozlabs.org>
3Date: Tue, 13 Oct 2015 09:17:21 +0800
4Subject: [PATCH] plugins: Add a backend for the OpenBMC dbus interface
5
6Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
7
8Includes the following commits from the following authors
9
10plugins/dbus: Split netfn from lun, and ccode from data
11
12Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
13
14plugins/dbus: fix missing semicolon
15
16Reported-by: Chris Austen <austenc@us.ibm.com>
17
18Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
19
20plugins/dbus: Fix ccode response
21
22We need to copy it in from the dbus reply.
23
24Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
25
26plugins/dbus: Use default dbus connection
27
28... so we'll use the system bus if run as UID 0.
29
30Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
31
32if no interface is specified, use the dbus interface by default
33
34This is a patch that should only be on openbmc, not sent upstream
35because the dbus interface is really only an openbmc thing.
36
37Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
38---
39 configure.ac | 19 ++++
40 src/plugins/Makefile.am | 4 +-
41 src/plugins/dbus/Makefile.am | 41 ++++++++
42 src/plugins/dbus/dbus.c | 199 +++++++++++++++++++++++++++++++++++
43 src/plugins/ipmi_intf.c | 6 ++
44 5 files changed, 267 insertions(+), 2 deletions(-)
45 create mode 100644 src/plugins/dbus/Makefile.am
46 create mode 100644 src/plugins/dbus/dbus.c
47
48diff --git a/configure.ac b/configure.ac
49index f2fe1f3..81cc925 100644
50--- a/configure.ac
51+++ b/configure.ac
52@@ -60,6 +60,7 @@ xenable_all_options=yes
53 xenable_intf_bmc=no
54 xenable_intf_dummy=no
55 xenable_intf_imb=yes
56+xenable_intf_dbus=yes
57 xenable_intf_lipmi=yes
58 xenable_intf_open=yes
59 #xenable_intf_serial=yes
60@@ -222,6 +223,22 @@ if test "x$xenable_intf_usb" = "xyes"; then
61 IPMITOOL_INTF_LIB="$IPMITOOL_INTF_LIB usb/libintf_usb.la"
62 fi
63
64+dnl enable IPMI dbus interface
65+AC_ARG_ENABLE([intf-dbus],
66+ [AC_HELP_STRING([--enable-intf-dbus],
67+ [enable IPMI dbus interface [default=yes]])],
68+ [xenable_intf_dbus=$enableval],
69+ [xenable_intf_dbus=yes])
70+if test "x$xenable_intf_dbus" = "xstatic" || test "x$xenable_intf_dbus" = "xplugin"; then
71+ xenable_intf_dbus=yes
72+fi
73+if test "x$xenable_intf_dbus" = "xyes"; then
74+ AC_DEFINE(IPMI_INTF_DBUS, [1], [Define to 1 to enable dbus interface.])
75+ AC_SUBST(INTF_DBUS, [dbus])
76+ AC_SUBST(INTF_DBUS_LIB, [libintf_dbus.la])
77+ IPMITOOL_INTF_LIB="$IPMITOOL_INTF_LIB dbus/libintf_dbus.la"
78+fi
79+
80 dnl enable IPMIv2.0 RMCP+ LAN interface
81 AC_ARG_ENABLE([intf-lanplus],
82 [AC_HELP_STRING([--enable-intf-lanplus],
83@@ -664,6 +681,7 @@ AC_CONFIG_FILES([Makefile
84 src/plugins/imb/Makefile
85 src/plugins/bmc/Makefile
86 src/plugins/usb/Makefile
87+ src/plugins/dbus/Makefile
88 src/plugins/lipmi/Makefile
89 src/plugins/serial/Makefile
90 src/plugins/dummy/Makefile])
91@@ -681,6 +699,7 @@ AC_MSG_RESULT([ free : $xenable_intf_free])
92 AC_MSG_RESULT([ imb : $xenable_intf_imb])
93 AC_MSG_RESULT([ bmc : $xenable_intf_bmc])
94 AC_MSG_RESULT([ usb : $xenable_intf_usb])
95+AC_MSG_RESULT([ dbus : $xenable_intf_dbus])
96 AC_MSG_RESULT([ lipmi : $xenable_intf_lipmi])
97 AC_MSG_RESULT([ serial : $xenable_intf_serial])
98 AC_MSG_RESULT([ dummy : $xenable_intf_dummy])
99diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
100index 7ad8173..c0b0b29 100644
101--- a/src/plugins/Makefile.am
102+++ b/src/plugins/Makefile.am
103@@ -32,8 +32,8 @@ MAINTAINERCLEANFILES = Makefile.in
104
105 AM_CPPFLAGS = -I$(top_srcdir)/include
106
107-SUBDIRS = @INTF_LAN@ @INTF_LANPLUS@ @INTF_OPEN@ @INTF_LIPMI@ @INTF_IMB@ @INTF_BMC@ @INTF_FREE@ @INTF_SERIAL@ @INTF_DUMMY@ @INTF_USB@
108-DIST_SUBDIRS = lan lanplus open lipmi imb bmc free serial dummy usb
109+SUBDIRS = @INTF_LAN@ @INTF_LANPLUS@ @INTF_OPEN@ @INTF_LIPMI@ @INTF_IMB@ @INTF_BMC@ @INTF_FREE@ @INTF_SERIAL@ @INTF_DUMMY@ @INTF_USB@ @INTF_DBUS@
110+DIST_SUBDIRS = lan lanplus open lipmi imb bmc free serial dummy usb dbus
111
112 noinst_LTLIBRARIES = libintf.la
113 libintf_la_SOURCES = ipmi_intf.c
114diff --git a/src/plugins/dbus/Makefile.am b/src/plugins/dbus/Makefile.am
115new file mode 100644
116index 0000000..3e92113
117--- /dev/null
118+++ b/src/plugins/dbus/Makefile.am
119@@ -0,0 +1,41 @@
120+ #
121+ # Copyright (c) 2015 IBM Corporation
122+ # All rights reserved.
123+ #
124+ # Redistribution and use in source and binary forms, with or without
125+ # modification,are permitted provided that the following conditions are met:
126+ #
127+ # 1. Redistributions of source code must retain the above copyright notice,
128+ # this list of conditions and the following disclaimer.
129+ #
130+ # 2. Redistributions in binary form must reproduce the above copyright notice,
131+ # this list of conditions and the following disclaimer in the documentation
132+ # and/or other materials provided with the distribution.
133+ #
134+ # 3. Neither the name of the copyright holder nor the names of its contributors
135+ # may be used to endorse or promote products derived from this software
136+ # without specific prior written permission.
137+ #
138+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
139+ # AND ANY EXPRESS OR IMPLIED WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE
140+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
141+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
142+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
143+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
144+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
145+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
146+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
147+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
148+ # POSSIBILITY OF SUCH DAMAGE.
149+ #
150+
151+MAINTAINERCLEANFILES = Makefile.in
152+
153+INCLUDES = -I$(top_srcdir)/include
154+
155+EXTRA_LTLIBRARIES = libintf_dbus.la
156+noinst_LTLIBRARIES = @INTF_DBUS_LIB@
157+libintf_dbus_la_LDFLAGS = -lsystemd
158+libintf_dbus_la_LIBADD = $(top_builddir)/lib/libipmitool.la
159+libintf_dbus_la_SOURCES = dbus.c
160+
161diff --git a/src/plugins/dbus/dbus.c b/src/plugins/dbus/dbus.c
162new file mode 100644
163index 0000000..c20545f
164--- /dev/null
165+++ b/src/plugins/dbus/dbus.c
166@@ -0,0 +1,199 @@
167+/*
168+ * Copyright (c) 2015 IBM Corporation
169+ * All rights reserved.
170+ *
171+ * Redistribution and use in source and binary forms, with or without
172+ * modification, are permitted provided that the following conditions
173+ * are met:
174+ *
175+ * 1. Redistributions of source code must retain the above copyright notice,
176+ * this list of conditions and the following disclaimer.
177+ *
178+ * 2. Redistributions in binary form must reproduce the above copyright notice,
179+ * this list of conditions and the following disclaimer in the documentation
180+ * and/or other materials provided with the distribution.
181+ *
182+ * 3. Neither the name of the copyright holder nor the names of its
183+ * contributors may be used to endorse or promote products derived from this
184+ * software without specific prior written permission.
185+ *
186+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
187+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
188+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
189+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
190+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
191+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
192+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
193+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
194+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
195+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
196+ * POSSIBILITY OF SUCH DAMAGE.
197+ */
198+
199+#define _BSD_SOURCE
200+
201+#include <sys/file.h>
202+#include <sys/stat.h>
203+#include <sys/types.h>
204+#include <fcntl.h>
205+#include <errno.h>
206+#include <unistd.h>
207+#include <stdbool.h>
208+
209+#include <systemd/sd-bus.h>
210+#include <systemd/sd-bus-vtable.h>
211+
212+#include <ipmitool/log.h>
213+#include <ipmitool/ipmi.h>
214+#include <ipmitool/ipmi_intf.h>
215+
216+static sd_bus *bus;
217+static uint8_t seq;
218+static struct ipmi_rs rsp;
219+static bool reply_received;
220+
221+static const char *bus_name = "org.openbmc.HostIpmi.ipmitool";
222+static const char *object_path = "/org/openbmc/HostIpmi/ipmitool";
223+static const char *interface = "org.openbmc.HostIpmi";
224+
225+static struct ipmi_rs *ipmi_dbus_sendrecv(struct ipmi_intf *intf,
226+ struct ipmi_rq *req)
227+{
228+ sd_bus_message *msg;
229+ int rc;
230+
231+ (void)intf;
232+
233+ rsp.ccode = 0xff;
234+
235+ rc = sd_bus_message_new_signal(bus, &msg, object_path,
236+ interface, "ReceivedMessage");
237+ if (rc < 0) {
238+ lprintf(LOG_ERR, "%s: failed to create message: %s\n",
239+ __func__, strerror(-rc));
240+ goto out;
241+ }
242+
243+ rc = sd_bus_message_append(msg, "yyyy",
244+ ++seq,
245+ req->msg.netfn,
246+ req->msg.lun,
247+ req->msg.cmd);
248+ if (rc < 0) {
249+ lprintf(LOG_ERR, "%s: failed to init bytes\n", __func__);
250+ goto out_free;
251+ }
252+
253+ rc = sd_bus_message_append_array(msg, 'y', req->msg.data,
254+ req->msg.data_len);
255+ if (rc < 0) {
256+ lprintf(LOG_ERR, "%s: failed to init body\n", __func__);
257+ goto out_free;
258+ }
259+
260+ rc = sd_bus_send(bus, msg, NULL);
261+ if (rc < 0) {
262+ lprintf(LOG_ERR, "%s: failed to send dbus message\n",
263+ __func__);
264+ goto out_free;
265+ }
266+
267+ for (reply_received = false; !reply_received;) {
268+ rc = sd_bus_wait(bus, -1);
269+ sd_bus_process(bus, NULL);
270+ }
271+
272+out_free:
273+ sd_bus_message_unref(msg);
274+out:
275+ return &rsp;
276+}
277+
278+static int ipmi_dbus_method_send_message(sd_bus_message *msg, void *userdata,
279+ sd_bus_error *error)
280+{
281+ uint8_t recv_seq, recv_netfn, recv_lun, recv_cmd, recv_cc;
282+ const void *data;
283+ size_t n;
284+ int rc;
285+
286+ (void)userdata;
287+ (void)error;
288+
289+ rc = sd_bus_message_read(msg, "yyyyy", &recv_seq, &recv_netfn,
290+ &recv_lun, &recv_cmd, &recv_cc);
291+ if (rc < 0) {
292+ lprintf(LOG_ERR, "%s: failed to read reply\n", __func__);
293+ goto out;
294+ }
295+
296+ rc = sd_bus_message_read_array(msg, 'y', &data, &n);
297+ if (rc < 0) {
298+ lprintf(LOG_ERR, "%s: failed to read reply data\n", __func__);
299+ goto out;
300+ }
301+
302+ if (n > sizeof(rsp.data)) {
303+ lprintf(LOG_ERR, "%s: data too long!\n", __func__);
304+ goto out;
305+ }
306+
307+ if (recv_seq == seq) {
308+ rsp.ccode = recv_cc;
309+ rsp.data_len = n;
310+ memcpy(rsp.data, data, rsp.data_len);
311+ reply_received = true;
312+ }
313+
314+out:
315+ sd_bus_reply_method_return(msg, "x", 0);
316+ return 0;
317+}
318+
319+static const sd_bus_vtable dbus_vtable[] = {
320+ SD_BUS_VTABLE_START(0),
321+ SD_BUS_SIGNAL("ReceivedMessage", "yyyyay", 0),
322+ SD_BUS_METHOD("sendMessage", "yyyyyay", "x",
323+ ipmi_dbus_method_send_message,
324+ SD_BUS_VTABLE_UNPRIVILEGED),
325+ SD_BUS_VTABLE_END
326+};
327+
328+static int ipmi_dbus_setup(struct ipmi_intf *intf)
329+{
330+ const char *name;
331+ int rc;
332+
333+ rc = sd_bus_default(&bus);
334+ if (rc < 0) {
335+ lprintf(LOG_ERR, "Can't connect to session bus: %s\n",
336+ strerror(-rc));
337+ return -1;
338+ }
339+
340+ sd_bus_add_object_vtable(bus, NULL, object_path, interface,
341+ dbus_vtable, NULL);
342+
343+ sd_bus_request_name(bus, bus_name, SD_BUS_NAME_REPLACE_EXISTING);
344+
345+ sd_bus_flush(bus);
346+ sd_bus_get_unique_name(bus, &name);
347+ intf->opened = 1;
348+
349+ return 0;
350+}
351+
352+static void ipmi_dbus_close(struct ipmi_intf *intf)
353+{
354+ if (intf->opened)
355+ sd_bus_close(bus);
356+ intf->opened = 0;
357+}
358+
359+struct ipmi_intf ipmi_dbus_intf = {
360+ .name = "dbus",
361+ .desc = "OpenBMC dbus interface",
362+ .setup = ipmi_dbus_setup,
363+ .close = ipmi_dbus_close,
364+ .sendrecv = ipmi_dbus_sendrecv,
365+};
366diff --git a/src/plugins/ipmi_intf.c b/src/plugins/ipmi_intf.c
367index 9225a34..56c2543 100644
368--- a/src/plugins/ipmi_intf.c
369+++ b/src/plugins/ipmi_intf.c
370@@ -89,8 +89,14 @@ extern struct ipmi_intf ipmi_dummy_intf;
371 #ifdef IPMI_INTF_USB
372 extern struct ipmi_intf ipmi_usb_intf;
373 #endif
374+#ifdef IPMI_INTF_DBUS
375+extern struct ipmi_intf ipmi_dbus_intf;
376+#endif
377
378 struct ipmi_intf * ipmi_intf_table[] = {
379+#ifdef IPMI_INTF_DBUS
380+ &ipmi_dbus_intf,
381+#endif
382 #ifdef IPMI_INTF_OPEN
383 &ipmi_open_intf,
384 #endif
385--
3862.17.1
387