problem when closing Dbus

Havoc Pennington hp at redhat.com
Mon Jun 25 14:12:02 PDT 2007


Hi,

Simon McVittie wrote:
> Exiting or restarting the system bus is considered to be an unsupported action
> by the D-Bus core developers, who appear to believe that restarting
> the system bus is equivalent to replacing the kernel, and requires a
> reboot, while restarting the session bus requires a session restart (i.e. log
> out and back in). I must admit I'm not really happy about this,
> particularly for programs where D-Bus interaction is a minor part of the
> overall functionality (e.g. things that just want to watch NetworkManager
> so they can tell whether you're online), but there's no other simple
> solution (you either have to abort, or cope with the disconnection in a
> fairly extensive way).
> 

I don't think it's valid to blame this on the dbus developers. It is 
fairly intrinsic to the situation and I'd challenge anyone to produce a 
working entire distribution (dbus stuff + apps) that was reliable and 
had working bus restart in practice. Nothing in libdbus or dbus-daemon 
prevents anyone from doing so, either.

My position is not that restarting the bus is not OK. Go for it all you 
want. Rather, my position is that the hard thing about supporting 
restart is that all apps have to be coded to support it, and I would 
personally never trust "all apps" enough to restart the bus. In other 
words, it's not something I personally would do or rely on on my system.

I just think for any given installed OS version, of the many apps that 
connect to dbus on a system, at least one or a few of them will get f'd 
up by a restart. You can report bugs on those, but by the time you get 
new packages from your distribution, some other app will have gotten 
screwed up (or failed to do things right in the first place).

If you think this judgment is wrong, then just restart the bus and see. 
Nothing in dbus or libdbus itself is stopping you.

It's also possible that if someone put in an extensive and regular QA 
effort to be sure restarting worked in all apps, that they could keep it 
working reliably. However, I seriously doubt someone will appear who 
cares enough to do that.

Yes, the default in libdbus is that exit_on_disconnect=TRUE. That's 
because to handle restart an app has to write a bunch of code.
If they are going to write the restart handling code, they can also add 
the one line set_exit_on_disconnect(FALSE) as part of it.

If they don't write any restart handling code, then it's better to exit 
than to just get really confused and go into an infinite loop spamming 
warnings (which is a probable result of not handling restart while 
continuing to use a dead connection).

The exit by default in libdbus is NOT the problem. The problem is that 
the app does not handle restart, and there is no way to make libdbus 
magically fix that.

A secondary point, I think in many cases the restart code would involve 
more or less restarting the whole app, meaning it's quite hard to write 
an app that supports this without user disruption.

For the *session* bus there's an additional reason for exit on 
disconnect: the session bus defines the session lifetime. i.e. a 
disconnect from the session bus *means* "user is logging out." 
Therefore, in general the right behavior for apps is to exit, though if 
the app wants to shut down in an orderly way it may want to 
set_exit_on_disconnect(FALSE) in order to do the shutting down by hand.

This is because the session bus is the "lifecycle grounding point" for 
the session, that allows all *other* daemons and apps to keep track of 
each other stopping and starting reliably. However, if the session bus 
*itself* could restart, things simply would not work; you would have 
"turtles all the way down."

It may not be obvious today, but historically in the absence of the 
session bus there is no reliable way to locate "the _____ daemon for 
this session" - gconfd struggled with this for years with no success.

With the session bus, you can locate "the ____ daemon" by finding its 
associated well-known bus name. However, there is still no reliable way 
to locate the session bus *itself* - except the DBUS_SESSION_BUS_ADDRESS 
environment variable, which is set at login time and can't be 
dynamically replaced.

If someone invents a magic way out of this then great, but
for gconfd for example nobody ever came up with a solution over
many years. (The obvious stuff to try does not work.)
This is why the session daemon is located via env variable - it's
the only robust solution known. The session daemon can't solve "turtles 
all the way down" if it is itself a turtle.

Anyway, to sum up, for both system and session bus:
  - bus restart requires special code in apps; that special code
    can include exit_on_disconnect=FALSE if the code is written.
    My claim is that the code won't get written, but I'm not
    stopping anybody and libdbus does not impose policy, only
    a reasonable default for the case where the app developer
    didn't consider the issue.
  - the special code in apps can be pretty involved and difficult,
    basically your app has to be able to reset all its state without
    user disruption
    (yes it may be easy for *some* apps that use dbus lightly, but that
     is not helpful if your goal is to be able to restart the bus. To
     restart the bus you need 100% of apps to handle it cleanly.)

For session bus only:
  - the session bus defines the session, and exiting it *means*
    "logging out"
  - there is no way to dynamically restart the session bus and
    have all the apps in the session be able to dynamically
    find it again, because one reason the session bus was invented
    was to provide a way to dynamically find daemons - something
    it was difficult or impossible to do reliably in the past.
  - in both of these respects the session bus was modeled on the
    X server, and Xlib also has 'exit on disconnect' as the default
    and also is located via env variable
    (Note that in an X session, the session bus and X server should
    always be linked 1-1 and start up and exit at the same time,
    ideally)

Because the session bus poses more issues than the system bus, you can 
allow system bus restart by "only" fixing and keeping fixed/QA'd all 
apps that connect to it. For the session bus, you also have to solve 
some larger issues before restart works.

A final note, I think bindings can/should experiment with APIs that 
encourage apps to automatically handle bus restart. If someone 
establishes a good pattern for this then all the bindings can copy it. I 
don't think any bindings have really thought about this issue, though.

Hopefully this post covers the issue sufficiently that if it comes up 
again we can link to the archives ;-)

Havoc



More information about the dbus mailing list