diff options
| author | Patrick Williams <patrick@stwcx.xyz> | 2017-02-16 16:06:51 -0600 |
|---|---|---|
| committer | Patrick Williams <patrick@stwcx.xyz> | 2017-02-16 16:06:53 -0600 |
| commit | bee1a6a3b233495fc48265626ca3a7952a43363f (patch) | |
| tree | 6654ee4a8da018512c524fc1d57b1c7ff088f4f9 | |
| parent | 16e175311d55045fa6709c0b91cc0f0ec5e2b3a5 (diff) | |
| download | sdbusplus-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.hpp | 18 |
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; |

