0

So I ran into the following interesting problem:

I tried to define XDG_RUNTIME_DIR in my .bashrc as follows:

export XDG_RUNTIME_DIR=$MY_HOME/.local/share

After doing this I noticed my pactl cli stopped working:

 $ pactl info
Connection failure: Connection refused
pa_context_connect() failed: Connection refused

The issue I found is that the pactl socket file was placed in /var/run/user/<user-id> presumably by the server started from systemd (checked with systemctl --user status pulseaudio), so calling pactl with the following did fix it:

XDG_RUNTIME_DIR=/var/run/user/$(id -u) pactl list

But how do I now repoint both server and client to a user defined XDG_RUNTIME_DIR so that both find the socket file and pactl cli naturally works?

4
  • 1
    This doesn’t answer your question, but setting XDG_RUNTIME_DIR to the same value as XDG_DATA_HOME (unless you’ve changed that) seems dangerous — the spec requires the runtime directory to be removed on logout. Commented yesterday
  • setting environment variables for graphical settings in the startup script of your shell seems almost universally like it won't work (or if it works, something went wrong. Commented 19 hours ago
  • Just to answer your question, and assuming pulseaudio server cares about XDG_RUNTIME_DIR for that, the proper way would be to systemctl --user edit pulseaudio and add a [Unit] drop-in with Environment=XDG_RUNTIME_DIR=%h/.local/share. (There may not exactly be a way to "universally" set it for all clients.)
    – Tom Yan
    Commented 14 hours ago
  • @TomYan This could be a specific way, but I'm really looking for a general way. I heard about pam_systemd but I'm not sure what it does exactly. Could it be a solution?
    – glades
    Commented 4 hours ago

1 Answer 1

0

According to his comment, apparently the OP wants to literally change XDG_RUNTIME_DIR for everything instead of just what is known to the pulseaudio server and clients. This answer is written for such presumed desire.

According to my own test in Arch Linux with systemd 257.5, the proper way to change XDG_RUNTIME_DIR for all user services (such as pulseaudio.service) is to set it with:

[Manager]
ManagerEnvironment=XDG_RUNTIME_DIR=%h/.local/share

in ~/.config/systemd/user.conf (or /etc/systemd/user.conf.d/name_you_like.conf if you want to set it for all users).

There is also DefaultEnvironment= and "environment.d". However, apparently they do not make the user manager start under the set environment, so using either of them alternatively would break e.g. systemctl (because of where the user "bus" would be placed and so on, I think) if your current shell also has the "new" environment. You would see that DBUS_SESSION_BUS_ADDRESS somehow does not get set in this case as well (if you check systemctl --user show-environment).

Note that processes of user sessions (such as the login shell you get after logging in via a tty) will not have environment set with any of the above approaches, except /etc/environment, but just exactly that, not other "environment.d".

The reason that /etc/environment works precisely leads to a non-shell-specific way / "lower-level" way to set the environment for user sessions: pam_env.

First of all you'd need make sure corresponding "PAM services" load pam_env.so with user_readenv=1:

session    required   pam_env.so       user_readenv=1

AFAIK where / which session required pam_env.so line exactly you should put user_readenv=1 really depends on your distro. In Arch it would be the system-login file in /etc/pam.d, because the file is included via system-local-login or system-remote-login by e.g. login, remote and sshd in the same directory. (These three are the ones that are "directly" used by their corresponding "PAM services".)

Then you should set the environment in ~/.pam_environment:

XDG_RUNTIME_DIR=/home/glades/.local/share

AFAIK you can't expand anything to get your HOME in this file. Not ~, not $HOME, not %h. At least not when HOME is not explicitly set in the same file. (Just like in any of the "environment.d".) That is more or less why you can't just use /etc/environment. (Well, it might be fine if you are only going to have one non-system user.)

However, according to the man page, user_readenv has been

deprecated since the 1.5.0 version and will be removed completely at some point in the future.

Also,

By default this option is off as user supplied environment variables in the PAM environment could affect behavior of subsequent modules in the stack without the consent of the system administrator.

which I don't really grok so I just quote it verbatim here as note for you.

So you may or may not want to use it. As an extreme measure, you may want to make your own PAM module that does the same thing, so that the effect will not just suddenly vanish some day. (I don't know much about PAM modules, so don't ask me how.)

Besides, depending on what you use exactly, leveraging shell profile file might effectively be sufficient for setting the environment for session processes.

P.S. In Arch, apparently because /etc/pam.d/systemd-user include system-login as well, one doesn't even need to set ManagerEnvironment= in user.conf anymore with the pam_env approach.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.