Here is the last part of my mini-series about D-Bus, this time on D-Bus activation
In my last blog entry I talked about implementing a D-Bus service in Ruby. Running the service was done as a background daemon, started by root (or with other credentials).
D-Bus also provides an on-demand service creation, named activation. Here the D-Bus daemon creates the service as soon as a client is requesting it. Shutdown of the service is at the discretion of the implementation, the D-Bus deamon does not automatically deactivate a running service.
About D-Bus activation
For D-Bus actication, you have to create a .service file. This is an INI-style format file containing
- the name of the service
- the file to run, implementing the service
- the user name to run the service as
Since the D-Bus daemon runs as user 'messagebus' and thus is unprivileged. It cannot directly run the service or assume the correct user credentials.
Instead, it uses a service helper which is setuid root to start the service. This helper is configured within /etc/dbus-1/system.conf as <servicehelper> and typically resides below /lib/dbus-1/dbus-daemon-launch-helper (/lib64/dbus-1/dbus-daemon-launch-helper on 64bit systems).
dbus-daemon-launch-helper is extra-picky when it comes to security and checks its own configuration at startup. If your D-Bus service fails to get activated, maybe dbus-daemon-launch-helper is not correctly installed.
Writing the .service file
The name of the service file must be equal to the service name with a .service extension.
A typical service file for my.awesome.Service would be named my.awesome.Service.service and contain
# DBus service activation config [D-BUS Service] Name=my.awesome.Service Exec=/usr/bin/awesome User=the_dude
Name is the name of the service, Exec the path to the executable implementing the service and User the user name to run the service. Be careful when using User=root, only very few services actually need root rights.
The Exec line can also contain arguments to be passed to the executable. This can be used to e.g. implement multiple services in a single binary and pass the actual service name as a parameter.
Installing the .service file
Just copy the service file to either /usr/share/dbus-1/system-services (for a system bus service) or to /usr/share/dbus-1/services (for a session bus service).
Your service is now ready to run. The D-Bus daemon will automatically pick up changes in the service directories and find the new file.