Adding a new function to sdbusplus::server::object

Lei YU mine260309 at gmail.com
Wed Sep 25 13:26:51 AEST 2019


This email is to introduce a "problem" and an RFC "fix" for sdbusplus at
https://gerrit.openbmc-project.xyz/c/openbmc/sdbusplus/+/25486

# The problem

With sdbusplus, when you have an existing dbus object, and you want to add a
new interface, usually you would like to create a
sdbusplus::server::object::object<interface>, and that's it.

However, that it not working correctly!

A demo is put at
https://gist.github.com/mine260309/aff3c3c2d2cc94edc9d09d59256b61b7

In short, with the code snippet like this:

using MyInterface = sdbusplus::server::object::object<
    sdbusplus::xyz::openbmc_project::Software::server::
        ActivationBlocksTransition>;

std::unique_ptr<MyInterface> block;

void signal_handler(int signal_num) {
   if(signal_num == SIGUSR2)
   {
       block.reset();
   }
}
int main(int, char**) {
    signal(SIGUSR2, signal_handler);
    auto bus = sdbusplus::bus::new_default();
    sdbusplus::server::manager::manager objManager(bus, objPath);
    bus.request_name(myService);
    block = std::make_unique<MyInterface>(bus, objPath);
    while(true)
    {
        bus.process_discard();
        bus.wait();
    }
    return 0;
}

When a DBus object is created, it shall implement at least 4 interfaces:
* org.freedesktop.DBus.Introspectable
* org.freedesktop.DBus.ObjectManager
* org.freedesktop.DBus.Peer
* org.freedesktop.DBus.Properties
And in the above example, an additioanl `ActivationBlocksTransition` is added:
* xyz.openbmc_project.Software.ActivationBlocksTransition

When block is destructed by sending a USR2 signal to the process, the expected
behavior is that the `ActivationBlocksTransition` interface is removed, and
other interfaces remain.
However, the result is, only `org.freedesktop.DBus.ObjectManager` remains, all
other interfaces are removed as well!

The workaround is to defer object added signal, and manually call
`emit_interfaces_added/removed()`, see example in
https://github.com/openbmc/phosphor-bmc-code-mgmt/blob/85c356f76fe07db3c1253c48f5b35c5811a15c07/activation.hpp#L137-L174

That looks *ugly*.

# The RFC fix

It is possible to let sdbusplus::server::object::object<> do the
`emit_interfaces_added/removed()` work, then the user will only pass an extra
parameter to object's constructor, that's it.

The changes to sdbusplus is pushed to
https://gerrit.openbmc-project.xyz/c/openbmc/sdbusplus/+/25486

With that change, in the above example, simply change the line

    block = std::make_unique<MyInterface>(bus, objPath);

to

    block = std::make_unique<MyInterface>(bus, objPath,
MyInterface::action::EMIT_INTERFACE_ADDED);

Then everything works expected.

So could you kindly review the sdbusplus patch, and provide comments?
Thanks!


More information about the openbmc mailing list