[Patch] Auto-Close dbus-daemon when unused
Simon McVittie
simon.mcvittie at collabora.co.uk
Fri Sep 25 09:57:34 PDT 2015
On 25/09/15 09:20, Leon Winter wrote:
> Sadly we do use terminal-multiplexers like screen(1) and such. The working
> assumption normally is that all processes are running for a reason. They might
> be in use or holding a detached shell. Users may very well have processes
> running accross "sessions" (like X11 sessions).
If that's your reasoning, then doesn't it apply equally to D-Bus
services, and to processes that merely *use* D-Bus?
Processes that use D-Bus are normally expected to exit when the
dbus-daemon does, because of exactly your situation: system
administrators on massively-shared systems hated it when pre-D-Bus
daemons like gconf persisted after a session was over. However, you
can't have it both ways - there has to be some rule for deciding whether
a process is allowed to persist.
If there is some more complex rule for deciding case-by-case whether
terminating a background process is desired or not, then I suggest using
it as input for systemd-logind. I believe the systemd maintainers' plan
is that eventually, tools like screen will register themselves as a
session, so that a user's dbus-daemon etc. stay running as long as they
have at least one X11, screen or tty session.
> Also we are not running systemd at this time.
I would recommend doing so. systemd-logind is the most consistent model
of "what it means to be in a session" that I've encountered, and
dbus-user-session makes a lot of sense (at least, it does to me).
>> Having a process automatically terminate when it thinks it is no longer
>> in use is usually a bad idea, because there is a race condition
>
> The mentioned race condition can indeed be fixed in the implementation and does
> not pose a problem in principal.
That's easy for you to say, you won't be the one responsible for
maintaining it in 5 years' time :-)
>> [...] that approach naturally provides "single instance"
>> semantics, and ensures that processes are started from a predictable
>> state rather than inheriting random process attributes from their
>> caller.
>
> I am not sure why you would call inherited process attributes random. We tend to
> launch applications (like evince) with specific environment variables (like
> PRINTER). We would then like evince to use the given printer.
Environment variables are actually not the main thing I'm worried about.
I'm more concerned about the more obscure corners of process attributes,
such as rlimits, setuid/setgid, process groups, whether or not SIGPIPE
is blocked, etc. - many of which make sense in a CLI environment, but
are just a source of failures for GUI components and services.
The central problem with environment variables for this sort of thing
is: suppose you already had an evince process running with PRINTER=hp,
and now you start another /usr/bin/evince (which communicates with the
existing process to make that process do the actual work) with
PRINTER=canon. Which printer will each window end up using? The answer
is that it depends whether the single-instance mechanism gathers up
(some subset of) the environment of the process-starter and passes it
across D-Bus to the existing instance to be associated with the new window.
The existing instance cannot just putenv("PRINTER"), because that's
process-global: it would affect the other window. It is also unsafe to
alter the environment from one thread while another thread might be
reading an environment variable; in practice, that means the only time
an application can safely alter its own environment is during very early
startup.
The way to have a single-instance application respect environment
variables is for the "starter" to pass environment variables across
D-Bus to the existing instance, for instance with
G_APPLICATION_SEND_ENVIRONMENT in GApplication.
I'm aware that setting environment variables is a configuration
mechanism that has been around for decades and is somewhat
well-understood, but that doesn't necessarily mean it provides a good
user-experience.
Any form of autolaunching for background processes is particularly
problematic if you're making active use of changing environment
variables during a session, because the new dbus-daemon (or whatever)
will have whatever arbitrary environment happens to have been active
when it was autolaunched, which it then passes on to its children.
> or hopes that evince offers a DBus API to change printers and use that
... or talk to the developers of toolkits like Gtk and Qt about your
use-cases, and get sufficiently clever desktop-wide printer selection
that it does the right thing without setting environment variables?
(For example, if I'm logged in from a thin client in a particular
location, it would make sense for there to be a way for me or a sysadmin
to arrange for my default printer to be set to one that is in that
location - but don't confuse the policy, "give me a nearby printer",
with the mechanism, "select a printer using environment variables".)
> Of the two issues of
>
> (a) lingering dbus-daemons after user sessions and
> (b) limiting the runtime of dbus-daemon to the time of actual usage
>
> we can consider (a) fixed when having DBus tied to X11 by using
> "--exit-with-session" for such "user session = X11 session" scenarios.
> Luckily most dbus-dependent applications require X11 anyway so it not much of an
> ask for DBus to require X11 as well. However running non-X11 DBus-dependent
> applications via SSH connections would then not be possible. I am currently not
> aware that we would have such non-X11 DBus-dependent applications running.
If you want non-X11 D-Bus-dependent things, the solution is the
systemd-logind user-session model, for which see dbus-user-session.
In dbus-user-session, a well-known bus socket per user is provided by
systemd --user, which listen()s on dbus-daemon's behalf; on the first
connection to the socket, systemd starts a dbus-daemon and hands over
the socket, ready for dbus-daemon to accept() a connection. This makes
the automatic starting a *lot* simpler than X11 autolaunching.
This might also make auto-termination more feasible to implement: for
instance, it might be possible for dbus-daemon to "give back" the socket
to systemd in an atomic way, and be sure that it has handed over its
responsibility and can safely exit.
> The issue (b) is partly addressed when using "autolaunching". Should no
> application require dbus, no dbus-daemon process is running. Yet when a single
> application autolaunch dbus it will stick around until the session ends despite
> nobody ever requires DBus any more (other then the application that spawned it
> in the first place). Sure, the dbus-daemon will be terminated once the user logs
> out, but *until* then it stays alive without purpose wasting resources.
How does this resource use compare with the rest of the user's session?
My guess is that the answer is "it isn't significant", although of
course I could be wrong.
If auto-terminating the dbus-daemon has sufficiently compelling
resource-use advantages that it is worth the code complexity of
implementing it, I'd want to see a design that explains how the race
condition can be avoided, before reviewing any code.
--
Simon McVittie
Collabora Ltd. <http://www.collabora.com/>
More information about the dbus
mailing list