Monday, March 09, 2009

D-Bus service on demand

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.

4 comments:

Unknown said...
This comment has been removed by a blog administrator.
Anonymous said...

Great article as for me. It would be great to read something more about this topic. Thanx for giving that information.
Sexy Lady
UK escort

DaveAtFraud said...

Thank you, thank you, thank you. I'm attempting to make a live CD (Ubuntu clone) installable and I kept getting a bizarre error from ubiquity. I finally ran across your blog after several other searches. Sure enough, the problem was I had blasted the file ownership (cown -R root:root *) to make sure I hadn't contaminated the image with my user account. One of the files that got changed to root:root ownership was dbus-daemon-launch-helper. That has now been fixed and the installer is running in a VM as I'm typing this.

Oh yeah, the weird error message was something about "Inhibit all polling failed..." Sure would have been nice if it had been something about a bad dbus-daemon-launch-helper bad installation.

Cheers,
Dave

Anonymous said...

Still helpful after 2 years. Thanks so much for the article. I spent a lot of time trying to figure out why my init script for GStreamer Daemon wasn't working at startup. Having dbus start gstd on demand is so much simpler!