Bug 1879216

Summary: systemd --user strips bash functions; environment modules no longer work
Product: [Fedora] Fedora Reporter: Ian Collier <imc>
Component: systemdAssignee: systemd-maint
Status: CLOSED WONTFIX QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: low Docs Contact:
Priority: unspecified    
Version: 32CC: fedoraproject, filbranden, flepied, lnykryn, msekleta, ssahani, s, systemd-maint, yuwatana, zbyszek, z
Target Milestone: ---   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: systemd-247~rc2-1.fc34 systemd-246.7-2.fc33 Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2020-12-10 01:15:17 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Ian Collier 2020-09-15 16:43:42 UTC
Summary:

Now that GNOME has switched to using systemd to launch its apps, there is no
longer a reliable way to define system-wide bash functions for people who use GNOME.
One subsystem which needs these is the environment modules system as implemented
by the Lmod package, which is required by several other Fedora packages including
mp and openmpi.  The third-party package Anaconda also works by defining bash
functions.  These now no longer work under some conditions when a user logs in
to a GNOME session on Fedora 32, but they work in other desktop environments
and they used to work in GNOME sessions on Fedora 30.

Background:

Environment modules provide the user with a way to dynamically change the
environment by means of module files typically supplied by other packages.
For example, the module file provided with openmpi extends PATH, LD_LIBRARY_PATH
and PKG_CONFIG_PATH to include the paths used by openmpi and sets several MPI_
environment variables.  It is done this way because you might also have
installed mpich which implements the same featureset and this makes it possible
to choose between the implementations at run time.  (Similarly, Anaconda is
an implementation of Python, and it is useful to give the user a method to
switch between Anaconda and the system Python installation at run time.)

In order to select openmpi, you type into your shell:
module load mpi/openmpi-x86_64

Because this has to affect the environment of the running shell, the "module"
command must be implemented as a shell function.  In bash, the most common
shell, this is done by putting the function definition in /etc/profile.d and
letting it be defined at login.  It is then exported with the bash command
"export -f" so that other shells that you start during this session will also
inherit this function definition.

Issue:

If you log in to a user account with no ~/.bashrc and select GNOME desktop on
Fedora 32 then type "module load mpi/openmpi-x86_64" you will get "module:
command not found".  This is a regression from Fedora 30, where it worked
properly, and it is also not an issue in most other desktop environments
where systemd is not used to launch the apps.

The way bash exports functions is by setting an environment variable called
"BASH_FUNC_functionname%%" and these variables are being stripped out of the
environment by systemd, whereas with the traditional way of starting a desktop
the environment variables - and thus the bash functions - are simply inherited
by the child processes of the desktop session manager.

My guess is that the variables are being stripped because they are not
POSIX compliant (and necessarily have to be that way because of
Shellshock/Bashdoor).

Unfortunately, bash does not offer any other foolproof way of defining
system-wide functions, because interactive non-login shells (such as would
appear in any terminals opened inside a GNOME session) do not read any
system-wide initialisation files - unlike login bash shells which read in
/etc/profile (and unlike zsh which reads in /etc/zshrc).

As it happens, there *is* an /etc/bashrc which sources /etc/profile.d/*.sh -
but bash doesn't read in this file unless your ~/.bashrc tells it to.  Maybe
most bash users have this in their ~./bashrc?  Certainly users who have
inherited their .bashrc from /etc/skel do.

So the question is: should systemd allow environment variables ending with '%%'
to be exported, or is it enough to require users to source /etc/bashrc in
their ~/.bashrc and tell them it's their own fault if they don't?  (Why doesn't
bash do this itself if it's required?)

See also:

https://github.com/systemd/systemd/issues/14878
Bug 1754395

Comment 1 Zbigniew Jędrzejewski-Szmek 2020-11-17 15:53:23 UTC
Fixed in rawhide so far.

Comment 2 Fedora Update System 2020-12-08 19:43:47 UTC
FEDORA-2020-3616681a70 has been submitted as an update to Fedora 33. https://bodhi.fedoraproject.org/updates/FEDORA-2020-3616681a70

Comment 3 Fedora Update System 2020-12-09 02:20:59 UTC
FEDORA-2020-3616681a70 has been pushed to the Fedora 33 testing repository.
Soon you'll be able to install the update with the following command:
`sudo dnf upgrade --enablerepo=updates-testing --advisory=FEDORA-2020-3616681a70`
You can provide feedback for this update here: https://bodhi.fedoraproject.org/updates/FEDORA-2020-3616681a70

See also https://fedoraproject.org/wiki/QA:Updates_Testing for more information on how to test updates.

Comment 4 Fedora Update System 2020-12-10 01:15:17 UTC
FEDORA-2020-3616681a70 has been pushed to the Fedora 33 stable repository.
If problem still persists, please make note of it in this bug report.

Comment 5 Zbigniew Jędrzejewski-Szmek 2020-12-10 07:52:58 UTC
So... actually this was not resolved as requested: we again do not allow bash functions to
propagated using the manager environment block. The biggest problem is that people
want 'systemctl show-environment' to be useful for various shells, and various shells
are confused when there are non-standard things there. So after initially allowing that,
support was removed again.

It also seems that the manager environment block is not the right place for this: functions
specific to some shell should be imported into that shell (using .bash_profile or whatever)
and not propagated to unrelated programs and shells.

> So the question is: should systemd allow environment variables ending with '%%'
> to be exported, or is it enough to require users to source /etc/bashrc in
> their ~/.bashrc and tell them it's their own fault if they don't?  (Why doesn't
> bash do this itself if it's required?)

I think the latter.