Disable pulseaudio idle-exit and support multiple users
Previous blog post in the pulseaudio and pipewire saga:
https://bkhome.org/news/202111/can-now-switch-between-pulseaudio-and-pipewire.html
Before getting onto the subject of multiple users, one thing that has
been a headache for me, and after some online reading a headache for
many others, is the idle-exit of the pulseaudio daemon.
Normally, a daemon is something that you start, and it keeps running
for duration of the session. Not so with /usr/bin/pulseaudio. It
defaults to exit after 20 seconds being idle, and it "respawns" on
request, like when an app such as pavucontrol, the pulseaudio GUI mixer
app, starts. When pavucontrol quits, so does the daemon 20 seconds
later.
So many users, myself included, use some commandline utilities, such
as 'pacmd', to query the daemon -- but pacmd doesn't respawn the daemon,
it just reports the daemon not running.
In Multiple Sound Card Wizard (/usr/sbin/mscw), the 'pacmd' utility is used, for example:
# pacmd list-sinks
I was immensely puzzled that it would work, then suddenly not work. Now I know why.
I edited file /etc/pulse/daemon.conf, with this:
allow-exit = no
exit-idle-time = -1
However, those settings are not actually required, as I am explicitly disabling idle-exit when start the daemon. It is started in /root/Startup/pulseaudio like this:
/usr/bin/pulseaudio --start --log-target=syslog --disallow-exit --exit-idle-time=-1
Good, now onto multiple users...
The above invocation starts the daemon as the current user, which in
EasyOS is 'root'. If the daemon had been started with the "--system"
commandline parameter, the daemon will change to user and group 'pulse',
and users, including root, have to be a member of group 'pulse' for
audio to work.
However, the pulseaudio developers strongly advise not to use "--system". See:
https://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/WhatIsWrongWithSystemWide/
Here is the problem: I am moving to running Internet-connected apps
as their own user and group. For example, SeaMonkey now runs as user
'seamonkey' and group 'seamonkey'. See this blog post:
https://bkhome.org/news/202109/infrastructure-in-place-to-run-each-app-as-a-separate-user.html
...though the top-level folder for the "non-root clients" is now /home, not /clients.
Pulseaudio will not work in these non-root clients. These guys
showed me the solution:
http://billauer.co.il/blog/2014/01/pa-multiple-users/
https://dhole.github.io/post/pulseaudio_multiple_users/
Here are the files that I have edited over the last couple of days:
/usr/sbin/mscw
/usr/local/clients/create-client-environment
/usr/local/clients/setup-client
/etc/pulse/client.conf.d/client.conf
/etc/pulse/daemon.conf
/etc/pulse/default.pa
/root/Startup/pulseaudio
/etc/profile.d/pulseaudio
As all these interactions can be confusing, I have put plenty of comments into those files.
/etc/profile.d/pulseaudio has this:
export PULSE_RUNTIME_PATH=/run/pulse
...so that clients will know where the daemon socket is, and will be able to communicate with the daemon.
Ran into a problem here. When the daemon starts it creates a socket
/run/pulse/native. It also changes the 'pulse' folder to 0700
permissions, so the non-root clients cannot see the socket!!!
So the socket has to be elsewhere; however, apps such as pavucontrol
expect it to be at /run/pulse/native. I don't know how to fix this, so
created another hack. Created a symlink /run/pulse/native to where the
socket actually exists.
The symlink is created in /usr/local/clients/setup-client. A snapshot showing symlink and actual socket:
I have edited this line in /etc/pulse/default.pa:
load-module module-native-protocol-unix auth-group=audio socket=/tmp/pulse-socket
...the actual socket is named "pulse-socket". Users now must be a member of the 'audio' group for sound to work.
That's it, we just need to arrange for any client app to be a member of the 'audio' group!
So that non-root clients know where the socket is, I inserted
this line into /home/<user>/.config/pulse/client.conf:
default-server = unix:/tmp/pulse-socket
...where <user> is "seamonkey" or whatever the non-root client
is. That file is also created by /usr/local/clients/setup-client.
One of those above links also advised this, in /etc/pulse/client.conf:
enable-memfd = yes
The end result should be something that "just works", without users
having to puzzle over arcane configuration files as I have
done.
Yes, it does work. I downloaded the firefox SFS and YouTube videos play with sound.
I do not yet know what needs to be done to get audio working in
containers. I think will also investigate TCP connection to the
pulseaudio daemon (the above method is using Unix Domain Sockets), as it
might be simpler.
Tags: easy