summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Williams <patrick@stwcx.xyz>2017-02-16 16:06:51 -0600
committerPatrick Williams <patrick@stwcx.xyz>2017-02-16 16:06:53 -0600
commitbee1a6a3b233495fc48265626ca3a7952a43363f (patch)
tree6654ee4a8da018512c524fc1d57b1c7ff088f4f9
parent16e175311d55045fa6709c0b91cc0f0ec5e2b3a5 (diff)
downloadsdbusplus-bee1a6a3b233495fc48265626ca3a7952a43363f.tar.gz
sdbusplus-bee1a6a3b233495fc48265626ca3a7952a43363f.zip
transaction: avoid recursive sdbus calls
The server bindings for transactions use the bus unique_name to create a transaction ID. If the bus object is not in RUNNING state, the unique_name call causes, deep in sd-bus, a call into sd_bus_process to get the bus up and running since the unique_name is assigned by the dbus-daemon. When DBus objects are created there is a call to generate a signal for object/interface creation. In sd-bus this creates a message and calls back into the server bindings to read all of the properties of the interface. When the transaction ID is assigned, calling unique_name, this causes a recursive entry into sd_bus_process which asserts. The ideal solution would be to catch all C++ objects that might result in a recursive call like this and call unique_name before. This would currently be on slot, server/match, and server/interface and may be others in the future. Instead, I took a simple approach, which is to get the unique_name immediately after instantiating any bus-object. Fixes openbmc/openbmc#1072. Change-Id: I024fd2f46fd08c85317e102dfced88a11e18f9de Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
-rw-r--r--sdbusplus/bus.hpp18
1 files changed, 17 insertions, 1 deletions
diff --git a/sdbusplus/bus.hpp b/sdbusplus/bus.hpp
index 6365644..48c8791 100644
--- a/sdbusplus/bus.hpp
+++ b/sdbusplus/bus.hpp
@@ -69,7 +69,7 @@ struct bus
*
* Takes ownership of the bus-pointer and releases it when done.
*/
- explicit bus(busp_t b) : _bus(b) {}
+ explicit bus(busp_t b);
/** @brief Release ownership of the stored bus-pointer. */
busp_t release() { return _bus.release(); }
@@ -237,6 +237,22 @@ struct bus
details::bus _bus;
};
+inline bus::bus(busp_t b) : _bus(b)
+{
+#ifndef DISABLE_TRANSACTION
+ // Emitting object added causes a message to get the properties
+ // which can trigger a 'transaction' in the server bindings. If
+ // the bus isn't up far enough, this causes an assert deep in
+ // sd-bus code. Get the 'unique_name' to ensure the bus is up far
+ // enough to avoid the assert.
+ if (b != nullptr)
+ {
+ get_unique_name();
+ }
+#endif
+}
+
+
inline bus new_default()
{
sd_bus* b = nullptr;
OpenPOWER on IntegriCloud