RTKit, portals, and Pipewire
Peeling an onion1, or how a bug report in a flatpaked2 application lead to fixes in three different part of the stack, but no change in the application itself.
How it started
It started with a bug report for the Flatpak of Ardour.
Pipewire needs to request realtime
priorities for threads. Inside Flatpak
pipewire is provided by the
freedesktop-sdk, and what that bug
report show is that pipewire can't find the module it uses to handle
realtime priorities. This was a bug in the
SDK,
where it was too eager in removing unused files pipewire-module-rt
is the new name of the module. I submitted a fix for the 22.08
release,
learning how to build the SDK in the process. freedesktop-sdk 22.08,
to be released later this month, should become the base of GNOME 44
(and I think the current nightly), as well as a future KDE SDK
release.
Realtime is not real
Now, to request the RT priority, pipewire does so by calling into RTKit, or, if it is not available, by calling the POSIX thread API.
RTKit allow requesting real time priorities for threads using D-Bus. It works by having the requester calling a D-Bus methods passing the process ID and thread ID.
Problem: Inside the Flatpak sandbox, the processes are in a
namespace, therefore
the process ID and thread ID are different. Passing them to RTKit
doesn't work, so we need to use the portal API. One of the components
is
xdg-portal-desktop
,
that sits on the host side (outside the sandbox), but that get called
via D-Bus from inside. It does provide an
interface
to proxy the RTKit calls. It does so by remapping the PID before
forwarding it to RTKit. But this is not enough, the D-Bus call return
a "not found" error. Notice how I said it remapped the process ID?
What about the thread ID? Indeed, that's the source of the
not-found-error.
Side note: Bustle was a great helper in helping diagnosing and testing this.
I then submitted a patch for the newly released "unstable" 1.15.0. And backported to 1.12.6 and 1.14.6.
Through the portal
As I said previously, Pipewire calls into RTKit. This still doesn't
work for the reason given above. So I also submitted a
patch
for Pipewire to call the portal, and, if not found, RTKit directly. Note
that the portal is also available to non flatpak applications3, and in that
case it will directly forward the calls to RTKit. I hope this to be in
0.3.57 (it is on master
as I write this).
On more thing...
Meanwhile, while testing how the build was going using the
freedesktop-sdk 22.08beta I was still disappointed that
pipewire-jack
4 still didn't ship the
JACK headers, forcing Flatpak packages to
build JACK first. So I submitted a
fix
to the freedesktop-sdk.
And then I found out that the .pc
file generated by Pipewire was
incorrect, so I submitted a
fix
for that too, fix that is in 0.3.56.
Bottom line
With all of this we have better support for requesting realtime priorities and for Pipewire being a true drop in replacement in 22.08. Still pending is a release of pipewire 0.3.57 for the realtime portal support.
And there are probably a other applications to fix.
The onion peeling metaphor is adequate as there were a lot of tears.
Flatpak is a verb.
Unless you stripped down your system and there is no portal, which is handled anyway.
An important note here: JACK, cannot work from inside a Flatpak
sandbox. Its API/ABI is guaranteed by using the system provided shared
library libjack.so
that will communicate with the sound daemon. That
also means using a version libjack.so
inside the sandbox wouldn't
work as there is no guarantee it matches JACK installed on the
host. On the other hand, pipewire-jack is designed to offer a JACK API
drop in replacement, and that's what we are using.