# Demand starting per-user Desktop Bus user services

Desktop Bus servers communicate with clients via an intermediary "broker" process, which passes messages around and keeps track of registered server "names". Clients generally rely upon servers either being explicitly run or started on demand. The old way of demand-starting servers, on systems without per-user service managers, was for the broker process to directly spawn the server processes. This so-called "bus activation" should be avoided on systems with service management, for several reasons. On systems with per-user service managers, the per-user service manager has a definition of the Desktop Bus server and either the broker process tells the service manager when to start it or the user explicitly enables the service to start automatically at startup using the normal service manager mechanisms. Or both.

## How it works

Demand start of per-user Desktop Bus servers works like this:

1. A Desktop Bus client contacts the broker and asks it to connect it to the server `org.example.Sheila`.

2. Recognizing that no server by that name has yet been registered with it, the Desktop Bus broker scans its server definition files for a server that has `Name=org.example.Sheila`. These files include the overrides at `~`username`/.local/share/dbus-1/services`.

3. It finds an override named `~`username`/.local/share/dbus-1/services/org.example.Sheila.service` that has `Name=org.example.Sheila`.

4. Using `dbus-daemon-launch-helper`, the broker sends a `system-control --user start org.example.Sheila` to the per-user service manager.

5. The per-user service manager starts the `~`username`/.config/service-bundles/services/org.example.Sheila` service.

6. The service contacts the Desktop Bus broker (whose address it knows from the `DBUS_SESSION_BUS_ADDRESS` environment variable that the service is configured with) and registers the `org.example.Sheila` service.

7. The broker finally answers the connection request from the original client.

## Unified server names

In theory `dbus-daemon-launch-helper` is supposed to look in the Desktop Bus broker server definition file for a `SystemdService` setting. In theory, the name of the service to be started could thus be different from the name that the server registers with the broker when it starts up.

Moreover: Originally, the `Name` field in a server definition file could differ from the name of the server definition file itself, too. So there would be three names, all different: the name of the server definition file, the `Name` field within it, and the service management service name named by the `SystemdService` named within it.

But the Desktop Bus people discovered that this made it far too easy to mess things up in various surprising ways, and nowadays they try to enforce the convention that the `Name` is always the same as the server definition filename. Adhering to this convention prevents, for one thing, the ambiguous case of two (or more) server definition files with different names that define the same server `Name` internally. The broker actually does not guarantee which server definition file it picks in such a scenario. If the server definition file name is always the server registration name, installation and package managers will notice the filename conflict.

The same reasoning applies to the `SystemdService` setting, the name seen by the service manager. It is far too easy to mess things up in various surprising ways if the names used in service management do not match the server names seen by the broker. In practice, this is pointless extra indirection. And the systemd people quickly adopted the convention that if the registration name is not the service management name itself, the service management name must have the registration name as an alias, so that the service can be managed using its registration name.

`dbus-daemon-launch-helper` thus adopts the convention that the service name given by `SystemdService`, the registration name given by `Name`, and the name of the Desktop Bus server definition file, are all the same single name. The broker gives the helper the name of the server definition file, so it just uses that as-is, and entirely ignores the server definition file contents and its superfluous, pointless, and problem-enabling `Name` and `SystemdService` fields.

## Creating more demand-started services of your own

To create your own demand-start Desktop Bus server process, you need to create a user-level service bundle (in ~/.config/service-bundles/services) for your per-user service manager and a override server definition file for the Desktop Bus broker. Proceed as follows:

1. Find the old server definition file for it. This will be somewhere in `/usr/local/share/dbus-1/services`, or its equivalent.

2. Make a note of the `Exec` setting in that file. This will be how your service bundle starts the service.

3. Make a note of the `Name` setting in that file. This will be the single unified name of everything.

4. Create a file with that name (plus `.service`) in your personal server definitions directory as `~/.local/share/dbus-1/services/`name`.service`. Do not worry if it is a different name to the server definition that it is overriding. Ironically, one of the complex mechanisms that it makes it so easy to mess things up is the system where the broker "knows" that two differently named files actually define the same server. Usually it will be the same name, though, per the modern Desktop Bus naming convention that tries to avoid the mess; and as long as there are just the two files, one in your personal server definitions directory and one in the system-wide (user) server definitions directory, the broker's "directory priority" scheme comes into play and there is no ambiguity.

5. The file is a Windows INI file. Its contents should comprise a `[D-BUS Service]` section with fields as follows:

   - `Name=`name
   - `User=`username
   - `Exec=/bin/exec true`

   It has to contain `User=`something, even though the broker is not running as the superuser, nor will the servers that are being launched. This is another D-BUS bug. Because of a mis-applied check in the `dbus-daemon` code, in order to use any helper with a per-user D-BUS broker every D-BUS server definition must have a totally redundant `User=` setting. The replacement D-BUS files generated by the configuration import subsystem, such as `~`username`/.local/share/dbus-1/services/org.example.Sheila.service`, all have a dummy `User=` and a dummy `Exec=` setting, neither of which is actually used. You must do the same in the files that you create yourself.

6. Create a service bundle in your per-user service bundles area as `~/.config/service-bundles/services/`name.

   - Its `run` program should contain the command that you noted from the `Exec` setting earlier.

   - It should have a `wants/` and an `after/` relationship to your `~/.config/service-bundles/services/dbus` service, and to your `~/.config/service-bundles/targets/basic` target.

   - It should have a `log/` symbolic link to to your `~/.config/service-bundles/services/dbus-servers-log` service (unless you decide to give it its own private logging service).

   - It should have a `wants/` and an `after/` relationship to its `log/` service.

   - It should have a `stopped-by/` and an `before/` relationship to your `~/.config/service-bundles/targets/shutdown` target.