Skip to content

Add mpDris2-remote.service, --abort-on-disconnect flag#165

Draft
ferdnyc wants to merge 7 commits intoeonpatapon:masterfrom
ferdnyc:remote-service-def
Draft

Add mpDris2-remote.service, --abort-on-disconnect flag#165
ferdnyc wants to merge 7 commits intoeonpatapon:masterfrom
ferdnyc:remote-service-def

Conversation

@ferdnyc
Copy link
Copy Markdown
Contributor

@ferdnyc ferdnyc commented Jan 17, 2025

This PR implements the second service definition I described in #161 (comment), for systems which use an mpd daemon that isn't running on the same system as the mpDris2 client.

For those systems, a systemd service file mpDris2-remote.service is added to the installation, as an alternative to mpDris2.service. (The two services are set to conflict, so that one or the other must be used, but not both.)

A new flag, --abort-on-disconnect, is added to the mpDris2 daemon, and used in the mpDris2-remote.service to have mpDris2 exit uncleanly when a connection failure occurs. Without it, the exits will be clean exits (intended for mpDris2.service).

The --no-reconnect logic is also extended to the initial connection attempt, so that initial startups will not retry when --no-reconnect is set (with or without --abort-on-disconnect).

Other changes

A separate commit updates the Makefile to generate .service files from .service.in files via a pattern rule, to avoid duplicating the same command for each .service file.

@ferdnyc
Copy link
Copy Markdown
Contributor Author

ferdnyc commented Jun 18, 2025

Augh! I discovered that this won't work, unfortunately. At least, not exactly as-is.

The problem is that the D-Bus service file is still installed with SystemdService=mpDris2.service, so having mpDris2-remote.service activated causes a bus name conflict.

The D-Bus service definition would have to be adjusted as well. Bother.

@ferdnyc ferdnyc marked this pull request as draft June 18, 2025 08:27
@ferdnyc
Copy link
Copy Markdown
Contributor Author

ferdnyc commented Jun 18, 2025

I suppose it might work to install a second D-Bus service as well, with the bus name org.mpris.MediaPlayer2.mpd_remote, and pass --bus_name=org.mpris.MediaPlayer2.mpd_remote to mpDris2 in mpDris2-remote.service. That'd completely separate the definitions.

@grawity
Copy link
Copy Markdown
Collaborator

grawity commented Jun 18, 2025

The D-Bus service definition only matters for "on-demand activatable" services. If the process is already running (like if someone has done systemctl start mpdris.service) and has claimed the name on the bus, then D-Bus doesn't even look at its own .service config.

If you want to avoid confusion (where the user enables the "-remote" service via systemd, but then accidentally causes the "main" service to be activated via D-Bus), then one pattern systemd suggests is to install the systemd service as an Alias=, e.g.:

[Install]
WantedBy=default.target
Alias=dbus-org.mpris.MediaPlayer2.mpd.service

...and then reference that, instead of the original name, from the D-Bus config file:

SystemdService=dbus-org.mpris.MediaPlayer2.mpd.service

But this also has the side effect that the service doesn't become activatable until it's been enabled. Systemd only has one systemctl enable, unfortunately. So either you have to couple "avoid dbus-activation confusion" with "enable for start-on-boot" together, or you have to ditch "enable for start-on-boot" and rely entirely on dbus-activation. (Or ditch dbus-activation and rely on "start-on-boot".)

@ferdnyc
Copy link
Copy Markdown
Contributor Author

ferdnyc commented Jun 18, 2025

@grawity

The D-Bus service definition only matters for "on-demand activatable" services. If the process is already running (like if someone has done systemctl start mpdris.service) and has claimed the name on the bus, then D-Bus doesn't even look at its own .service config.

If you want to avoid confusion (where the user enables the "-remote" service via systemd, but then accidentally causes the "main" service to be activated via D-Bus),

I'm actually more worried about the other way around — if someone has caused the D-Bus service to activate on demand, then starting mpDris2-remote.service will fail because it can't get the bus name.

It's the Exec= line in the D-Bus service file that's the real problem — I can tell systemd that the two service units conflict with each other, so it'll never allow them to be started together, but if D-Bus Execs mpDris2 --use-journal (which is also lacking the command line flags needed for mpDris2 to run in mpDris2-remote.service configuration, another issue) then it can lock the -remote unit out of the bus.

Is it valid to have D-Bus service files without Exec= lines? Do we actually need that there?

If D-Bus can't start the daemon (or can only start it using its registered systemd service unit) then on-demand starts don't run the risk of trampling all over the systemd-managed services.

@ferdnyc
Copy link
Copy Markdown
Contributor Author

ferdnyc commented Jun 18, 2025

Is it valid to have D-Bus service files without Exec= lines?

The fact that every file in /usr/share/dbus-1/services/ on my system contains exactly one match for Exec makes me think the answer to that is probably "no".

Edit: Confirmed, poop. From the spec:

Service description files must contain a D-BUS Service group with at least the keys Name (the well-known name of the service) and Exec (the command to be executed).

@ferdnyc
Copy link
Copy Markdown
Contributor Author

ferdnyc commented Jun 18, 2025

OK, next question: Do we actually need the d-bus service definition there at all?

I notice VLC doesn't install a /usr/share/dbus-1/services/org.mpris.MediaPlayer2.vlc.service, but it's still able to publish itself on the session bus and be controlled.

@grawity
Copy link
Copy Markdown
Collaborator

grawity commented Jun 19, 2025

Is it valid to have D-Bus service files without Exec= lines?

dbus-daemon won't try to Exec anything if it can start the corresponding systemd service. Systemd distributes several definitions that use Exec=/bin/false to enforce that only one instance (i.e. the systemd-managed instance) will ever be started.

OK, next question: Do we actually need the d-bus service definition there at all?

Like I said, the d-bus service definition is for on-demand activation. If the process is already running, then dbus-daemon doesn't look at the service definition for any other purpose.

On-demand activation is mostly not applicable to MPRIS due to how the discovery works (most MPRIS clients start by grepping all claimed services for "org.mpris.*", which means the MPRIS client won't know about services unless they're already running), so really the mpdris2 dbus service file will never be used.

I don't remember why mpdris2 has a service definition at all, but it might've been for some specific purpose like a playerctl-style client being explicitly told which bus name to send commands to.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants