[RFC] ERL-1323 - Make Erlang/OTP work from any installation directory by removing the need for an absolute path

Jérôme de Bretagne jerome.debretagne@REDACTED
Tue Sep 8 23:06:08 CEST 2020


Hi all,

I'm looking for comments about the following proposition that I had
created about a month ago here:
https://bugs.erlang.org/browse/ERL-1323 I don't know if this was the
best tool and place within the community to gather feedback, but with
none so far on the bug tracker, I'm taking my chance through the
mailing list! So here you go:

The current Erlang/OTP installation process (using make release for
instance) creates a few executable scripts (bin/erl, bin/start,
bin/start_erl, erts-X.Y.Z/bin/erl, etc.) which define one or more
absolute paths (BINDIR, ROOTDIR) that are freezing the installation
into a specific directory.

This approach has the following consequences:
1. it is not possible to freely move the installation directory later
on, as the above scripts then point to incorrect paths
2. it is needed to know upfront in which absolute path the Erlang
runtime will be installed, or an extra step is required to update the
scripts (using the ./Install script) to fix the paths and freeze the
installation once the exact location is finally known

Looking at all the scripts, including the ./Install one, what seems to
really matter is the directory structure relative to $ERL_ROOT in
fact. I don't know the history/background for this choice to require
an absolute path, it certainly brings some benefits (simplicity?
robustness and wide-compatibility?) but it also adds an extra layer of
complexity which creates some friction in a world of VMs / containers.

There are some ways to find the absolute path of a script from within
itself, including following symlinks, such as this one (with a proper
formatting in the bug tracker):

prog="$0"
while [ -h "${prog}" ]; do
    newProg=`ls -ld "${prog}"`
    newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
    if expr "x${newProg}" : 'x/' >/dev/null; then
        prog="${newProg}"
    else
        progdir=`dirname "${prog}"`
        prog="${progdir}/${newProg}"
    fi
done
oldwd=`pwd`
progdir=`dirname "${prog}"`
cd "${progdir}"
progdir=`pwd`
prog="${progdir}"/`basename "${prog}"`
echo "${prog}"
cd "${oldwd}"

from dalvik/dx/etc/dx
(https://android.googlesource.com/platform/dalvik/+/master/dx/etc/dx)
as discussed and referenced here on Stack Overflow
(https://stackoverflow.com/questions/4774054/reliable-way-for-a-bash-script-to-get-the-full-path-to-itself).

- Would a PR going in this direction be acceptable if removing the
hardcoded absolute paths?

- What would be other requirements to take into consideration (OS
compatibility)? Other documented expectations that should be looked at
carefully?

A smooth transition could be to keep full backwards compatibility with
the current ./Install script approach by simply providing a default
behavior when %FINAL_ROOTDIR% has not been set.

For completeness, there is already one system at least for which point
2. above is already a deal breaker, which is Android 10, cf. this
issue #2 in erlanglauncher
(https://github.com/JeromeDeBretagne/erlanglauncher/issues/2).

Indeed, when targeting Android 10 and above, native executables
(binaries or scripts) can have the needed execute permission only when
preset in the APK and extracted within a specific directory (the app's
native 'lib' directory), due to this change "Removed execute
permission for app home directory"
(https://developer.android.com/about/versions/10/behavior-changes-10#execute-permission).

However, the absolute path of this 'lib' directory is unknown until
app installation time as it contains random characters (for instance
'/data/app/~~XQXxwg2AgjdCIm7mBvYUIg==/com.my.package-oThErRAnDOmChar==/lib')
and its content can't be updated once extracted as the app data is set
as read-only for W^X security reasons
(https://en.wikipedia.org/wiki/W%5EX). To work around this recent
restriction, the Erlang runtime would have to be modified to become
fully independent of its installation path to keep working on Android
going forward.

I know that Android is not a supported system, that's why I'm willing
to investigate an approach that would fix this Android-specific issue
while also providing similar benefits to the wider Erlang ecosystem.

Let me know your thoughts!

Thanks,
Jérôme


More information about the erlang-questions mailing list