1

I have a user-space daemon, call it maxwell, that executes various actions based on D-bus signals from another application, call it room. I would like to run maxwell as soon as the user starts room, and stop it when room exits.

I think a launcher script like this would result in the desired behaviour:

#!/bin/sh

systemctl --user start maxwell
room
systemctl --user stop maxwell

but is there a better / standard way to do it, e.g. via systemd itself?

Update: It seems like the functionality I'm looking for is similar to what upstart used to provide with its dbus event. The closest thing that can be achieved with systemd appears to be auto-starting a service which "owns" a certain D-bus name when that name is first used, as per Stephen Kitt's answer; unfortunately, in this case it is room that "owns" the name.


Note: I don't think that this is the same as systemd requires="some non-systemd process"? or, at least, that the answer provided therein works in this case. As far as I understand, using ExecStartPre would simply mark the maxwell unit as failed if room wasn't already running.

  • yes. Please read about systemd unit files and ask more concrete questions. – arved Jul 5 at 9:22
  • @arved Could you be more explicit? I read the whole systemd.unit man page multiple times before asking this, and couldn't find what I was looking for. The question also seems pretty concrete to me. I could give you the names of the precise programs I'm running, but that wouldn't change anything for the problem itself. Also, I am under the impression that more general, yet answerable in a precise manner, questions are preferred on SE. – A.P. Jul 5 at 9:25
  • Possible duplicate of systemd requires="some non-systemd process"? – 炸鱼薯条德里克 Jul 5 at 9:33
  • 1
    The title doesn't match the body. If Maxwell doesn't needs to to running when room is not, then it doesn't need to be a daemon at all – 炸鱼薯条德里克 Jul 5 at 9:36
2

systemd supports D-Bus activation, where a service is started to service a D-Bus method call. I’m not sure whether this can be transposed to user services; for system services you create a D-Bus service file:

[D-BUS Service]
Name=your.bus.name
Exec=/path/to/the/daemon
User=root
SystemdService=systemd-service-name.service

and a corresponding systemd service, which has to specify a matching bus name:

[Service]
BusName=your.bus.name

Specifying BusName in this way automatically marks the service as a D-Bus service.

It should be possible to install everything as user services (changing User in the D-Bus service file to match), but I haven’t tried that.

  • This sounds promising. I'll give it a try, thank you. – A.P. Jul 5 at 9:39
  • In my experiments, I could only make it work if the daemon "owns" your.bus.name and the application tries to connect to it: if D-Bus receives a message for the daemon and it isn't running, then D-Bus automatically starts it up before delivering the message. Is there a way to make this work if the application "owns" your.bus.name and the daemon simply listens in on the chatter? E.g. start the daemon the first time a well-known name is used / registered? – A.P. Jul 5 at 12:33
  • By the way, according to the documentation, service description files for the session bus should be placed in dbus-1/services/ under one of the XDG data directories (e.g. ~/.local/share/) and, unlike system bus service files, they don't require a User field. – A.P. Jul 5 at 12:42
  • 1
    Yes, D-Bus activation only really works if the service being started “owns” the activated bus. – Stephen Kitt Jul 8 at 7:58
  • Although it doesn't exactly solve my issue, I'm accepting this answer since it seems to be the closest result achievable through systemd. – A.P. Jul 8 at 23:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.