I bought a new drive for my home media box. In doing so a lot of things improved. First, I went with docker images rather than custom bare metal installs for the services that I maintain on it. I did some better organization on the system, better mounts, etc.

For the most part things went fairly smooth. Except for 2 things:

  1. Encrypted Swap didn’t work (protip: Use PARTUUID instead of UUID in your cyrptmount file)
  2. The volume on Kodi was very quiet

What happened?

Currently, Pipewire is pretty much the preferred route to using sound on Arch (Oh btw did I mention I use Arch.gif) and most of your applications (like Kodi) depend on it. When everything started, sound did work, but it did not have a lot of volume.

It had sound coming out of the speakers, but it was very faint.

What did I do to try to increase the volume?

Firstly I tried to install a ton of audio mixers. (alsa-utils, pacmixer, etc.) None of those worked from my non-service account. I had connection failures to the audio server.

Next step: Install the pipewire audio compatibility layers and enable them: pipewire-pulse, pipewire-alsa. I tried enabling them using:

systemctl --user enable --now pipewire.socket\n\nsystemctl --user enable --now pipewire-pulse.socket\n\nsystemctl --user enable --now wireplumber.service

That worked for my non-service account, but for my main SSH account it was fine. This is what the Arch guide suggested to do. But for my service account I got the error message of:

Failed to connect to bus: No medium found

DBUS Issues on the service account

A lot of forums recommend enabling linger on the account. This did not work. This error message that was stated above was due to the systemctl’s user service management. It just couldn’t connect to the DBUS layer underneath. Following this rabbit hole was even worse.

There were many forum post suggesting that this was due to misconfigured environment variables, needs for XDG startup scripts. None of that was helpful for a system that directly boots to Kodi.

The rabbit hole continues

Ok, so now we have a DBUS issue right? I started looking through Git history for DBUS related items. It mentioned that the script used to have a dbus launcher. After forcing the installed service to load that, it turned out even that didn’t help. Systemctl user scripts were still refusing to work. But we have a few weird things here:

  1. The Pipewire processes are running under the service account (so some sort of systemd stuff is running)
  2. The sound is playing and the only thing installed is the Pipewire dependencies

Ok, I give up, downgrading time

I did a search for all the Pipewire packages and attempted to uninstall them. That was a no-go from Pacman as that many of the packages I use need them.

This was incredibly disappointing news.

Further information

Again the weird thing here: The application sees the sound card. But my service account and my primary user don’t see relevant sound card details. The service account doesn’t see the sound server running, and my normal user only sees “Dummy Card” running (which doesn’t affect the machine’s sound card).

Pactree shows that the audio server is spawned from the Kodi standalone service. Which is weird.

A random stroke of luck

I found this post on reddit when following up on the DBus Issues.

It gave me the tip of logging into the service account of:

sudo machinectl shell --uid=<userid>

(The user account can be found by calling: id <userid> for the UID)

Once in the shell of the account, the command setups all the environment variables that the other posts were referring to. ($DBUS_SESSION_BUS_ADDRESS and XDG_RUNTIME_DIR)

From there I regained the ability to look at and edit the systemd user services. (systemctl --user) Additionally, the information about connecting to the local PulseAudio, and Alsa compatibility layers were working.

I was not able to get the PulseAudio mixers to work, however the old friend alsamixer did. Once the volume was changed, it also persisted.

What’s the difference between machinectl and su?

According to: This reddit post

Machinectl ends up basically creating a chroot of a particular user, in brings up the systemd bindings for the user. It turns out that using su doesn’t create those bindings. Mainly the binding in question is: XDG_RUNTIME_DIR.

Sigh. At least it works now.

Link to the discussion on the Systemd GitHub issue tracker