arkq / bluez-alsa

Bluetooth Audio ALSA Backend
MIT License
864 stars 189 forks source link

Couldn't acquire D-Bus name. #633

Closed gearhead closed 1 year ago

gearhead commented 1 year ago

Problem

using the latest bluealsa.service file from the repo I cannot get it to run as bluealsa I get this in the log and it fails to run:

bluealsa: W: Couldn't create storage directory: No such file or directory
bluealsa[10982]: bluealsa: E: Couldn't acquire D-Bus name. Please check D-Bus configuration. Requested name: org.bluealsa

If I change the user to root, it runs

bluealsa[11757]: bluealsa: W: Couldn't create storage directory: No such file or directory
systemd[1]: Started BlueALSA service.

Are there any changes that need to be made to the journalctl config file?

Setup

Running on an Rpi running armhf binaries on armv6 hardware the OS distribution and version

# uname -a
Linux kitchenrune 6.1.21+ #1642 Mon Apr  3 17:19:14 BST 2023 armv6l GNU/Linux
# bluealsa -V
6837b54
# bluetoothd --version
5.55
# aplay --version
aplay: version 1.2.4 by Jaroslav Kysela <perex@perex.cz>
borine commented 1 year ago

bluealsa: W: Couldn't create storage directory: No such file or directory

looks like some issue with build configuration, perhaps the service unit file needs the storage directory configured to account for $prefix.

From the issue template Setup section (my emphasis in bold italics):

  • if self-built from source, please state the branch, commit and used configure options

Then we can try to reproduce this error to understand it properly

bluealsa[10982]: bluealsa: E: Couldn't acquire D-Bus name. Please check D-Bus configuration. Requested name: org.bluealsa

your installation is either incomplete or broken. Maybe related to the above, maybe not.

arkq commented 1 year ago

The error message lacks path information (I will add such info, so it will be easier to resolve such issues in the future). But you can use strace to check which syscall has failed - you will see the path in the strace output. Most likely there is no "base" directory for bluealsa's mkdir().

borine commented 1 year ago

When using the latest systemd service unit file, the storage directory should have been created, with appropriate permissions, by systemd. That's why I suspect the unit file may not be configured correctly to match the path required by the bluealsa daemon.

Relying on bluealsa to create its own storage directory would require it to have root privileges, which is something I think we should try to avoid.

[EDIT] I'll add a note to INSTALL.md mentioning the need to create this directory manually if not using systemd

borine commented 1 year ago

Looking at the systemd docs, I see that the environment variable $STATE_DIRECTORY is set for the main process to find the runtime parent directory that systemd has used for its state files. Perhaps the bluealsa daemon should use that environment variable if set, overriding the value given at configuration time?

borine commented 1 year ago

@gearhead I've just re-read your question, and I noticed the wording used here:

using the latest bluealsa.service file from the repo

Does that mean you are using a systemd unit file and D-Bus policy file from an OS distribution repository, or are you using the ones from this project source code repository? If the former then you really need to seek help from the OS - this project has no control over what files or config options are used by distributions.

arkq commented 1 year ago

Looking at the systemd docs, I see that the environment variable $STATE_DIRECTORY is set for the main process...

I've just pushed a change which will check STATE_DIRECTORY in case when bluez-alsa was configured with --enable-systemd. I hope this will solve this issue.

gearhead commented 1 year ago

@arkq Sorry for being incomplete. I am building from source. I am using the examples here in this source code repo for the service files and D-Bus policy. The configure options I use are:

  flags=(--with-libopenaptx
         --enable-ldac
         --enable-mp3lame
         --enable-cli
         --enable-aac
         --enable-manpages
         --enable-systemd
         --enable-aptx-hd
         --enable-faststream)
  ./configure --prefix=/usr \
      --sysconfdir=/etc \
      "${flags[@]}"

I am using the service file from here as a guide but made a couple additions: https://github.com/arkq/bluez-alsa/blob/master/misc/systemd/bluealsa-aplay.service.in

[Unit]
Description=BlueALSA service
Documentation=man:bluealsa(8)
Requisite=dbus.service
After=bluetooth.service

# In order to customize BlueALSA D-Bus service one should create an override
# for this systemd unit file. Please note, that in the override file one will
# have to explicitly clear the ExecStart before setting it again. See the
# bluez-alsa wiki for more options.
#
# $ sudo systemctl edit bluealsa
# [Service]
# ExecStart=
# ExecStart=@bindir@/bluealsa -S --keep-alive=5 -p a2dp-sink

[Service]
Type=dbus
BusName=org.bluealsa
User=root
EnvironmentFile=-/etc/default/bluealsa
ExecStart=/usr/bin/bluealsa $OPTIONS
Restart=on-failure

# Sandboxing
AmbientCapabilities=CAP_NET_RAW
CapabilityBoundingSet=CAP_NET_RAW
IPAddressDeny=any
LockPersonality=true
MemoryDenyWriteExecute=true
NoNewPrivileges=true
PrivateDevices=true
PrivateTmp=true
PrivateUsers=false
ProtectClock=true
ProtectControlGroups=true
ProtectHome=true
ProtectHostname=true
ProtectKernelLogs=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectProc=invisible
ProtectSystem=strict
RemoveIPC=true
RestrictAddressFamilies=AF_UNIX AF_BLUETOOTH
RestrictNamespaces=true
RestrictRealtime=true
RestrictSUIDSGID=true
SystemCallArchitectures=native
SystemCallErrorNumber=EPERM
SystemCallFilter=@system-service
SystemCallFilter=~@resources @privileged
UMask=0077

# Setup state directory for persistent storage
ReadWritePaths=/var/lib/bluealsa
StateDirectory=bluealsa

[Install]
WantedBy=bluetooth.target

I do note that it does create a directory /var/lib/bluealsa when I start it.

# ls -al /var/lib/bluealsa/
total 8
drwxr-xr-x  2 root root 4096 Apr 24 18:12 .
drwxr-xr-x 45 root root 4096 Apr 24 18:12 ..
borine commented 1 year ago

I've just tried configuring with your options, and I find:

$ grep localstoragedir config.log
localstoragedir='/usr/var/lib'

So that explains why bluealsa is not finding its storage directory. I'm thinking that is probably an error in the configure.ac file, but will need to read up on it a bit more to be sure of how these standard directories are supposed to relate to a given $prefix.

However, as you are configuring with --enable-systemd, @arkq has now made a change (see comment https://github.com/arkq/bluez-alsa/issues/633#issuecomment-1519142510) so that systemd will override the compiled-in storage path and you will find that the latest code in Master will always use /var/lib/bluealsa/ when used with systemd.

As for the error

bluealsa[10982]: bluealsa: E: Couldn't acquire D-Bus name. Please check D-Bus configuration. Requested name: org.bluealsa

That is one of the common errors mentioned in the README, please read the troubleshhooting section in that for the possible causes. I suspect in your case it is the D-Bus policy file that is the problem. Had you used the configure option --with-bluealsauser=USER when configuring instead of editing the systemd service unit file by hand, then configure would have taken care of this. I am currently preparing updated installation and troubleshooting guides (PR #630) which contain instructions on how to configure D-Bus policy by hand, in the meantime there are several past issues which contain example D-Bus policy files, for example https://github.com/arkq/bluez-alsa/issues/629#issuecomment-1510150973

borine commented 1 year ago

@arkq

storage directory ... is probably an error in the configure.ac file

So, reading the GNU coding standards it seems that localstatedir should indeed be relative to the ${prefix} so BlueALSA configure behaviour when user sets --prefix=/usr is correct. The BlueALSA default behaviour (use /var/lib) contravenes GNU standards. When users wants to install outside the ${prefix} then they must explicitly set --localstatedir=/var/lib, for example.

I personally prefer BlueALSA to default to /var/lib, ignoring the GNU standards, but then it is somewhat surprising that explicitly setting --prefix=/usr gives a different result from just using the default prefix, which is also /usr. I'll try to document this anomaly in the wiki installation guide, unless you want to modify configure.ac to remove the anomaly?

arkq commented 1 year ago

unless you want to modify configure.ac to remove the anomaly

I think that we should follow BlueZ project on that matter. The bluetoothd service also uses persistent storage, and also uses autotools. Since bluez-alsa is an "adjacent" project to bluez.org, I think that we should be consistent. I think that I've "copied" (I hope, correctly) the logic from bluez, so in that case I'll go with doc update.

gearhead commented 1 year ago

I think I followed your instructions. I changed my build config:

flags=(--with-libopenaptx
         --with-bluealsauser=bluealsa
         --with-bluealsaaplayuser=bluealsa
         --enable-ldac
         --enable-mp3lame
         --enable-cli
         --enable-aac
         --enable-manpages
         --enable-systemd
         --enable-aptx-hd
         --enable-faststream)
  ./configure \
      "${flags[@]}"

and now it will run as bluealsa user. I had already looked and traced and retraced my steps with the README instructions on the dbus-1 config, but did not get that it needed to be user=bluealsa, but now it all works. Thanks for the help!

arkq commented 1 year ago

I'm closing this issue as resolved, then.