problem when closing Dbus
hp at redhat.com
Mon Jun 25 14:12:02 PDT 2007
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
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
(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*
- 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,
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 ;-)
More information about the dbus