From db4b177e20a0836cca2d95882a835681fac6b50e Mon Sep 17 00:00:00 2001 From: WANG Xuerui Date: Wed, 12 Jul 2023 21:35:58 +0800 Subject: [PATCH] rustup-init.sh: Check for kernel UAPI compatibility on LoongArch And provide friendly diagnostics if a certain widely-deployed but incompatible UAPI flavor (a.k.a. the "old-world" UAPI that's used by several early and/or commercial LoongArch Linux distributions) is detected. The minimalistic probe was crafted by myself, checking for one of the most prominent incompatibilities between the two UAPI flavors: `sizeof(sigset_t)`. The probe binary is small enough to fit in 3 lines of Base64, which is decoded into a temp file and executed for result. The `base64(1)` command is ubiquitous (being provided by coreutils, busybox and probably many others), and only necessary on LoongArch, so we effectively don't lose portability. Other irrelevant errors (e.g. /tmp being noexec) are made non-fatal, because without the check the installer binary will instantly die anyway on an incompatible system. A warning message is printed in case such an error occurs. (The installer binary, being dynamically linked, will die on a system using the other incompatible UAPI, with a confusing error saying the program being executed itself is not found: the actual non-existent path is the ELF interpreter i.e. `ld.so`. Having some error messages in case of this would hopefully reduce the technical support burden for many.) --- rustup-init.sh | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/rustup-init.sh b/rustup-init.sh index ddc99f2472..58e66df8b2 100755 --- a/rustup-init.sh +++ b/rustup-init.sh @@ -240,6 +240,67 @@ get_endianness() { fi } +# Detect the Linux/LoongArch UAPI flavor, with all errors being non-fatal. +# Returns 0 or 234 in case of successful detection, 1 otherwise (/tmp being +# noexec, or other causes). +check_loongarch_uapi() { + need_cmd base64 + + local _tmp + if ! _tmp="$(ensure mktemp)"; then + return 1 + fi + + # Minimal Linux/LoongArch UAPI detection, exiting with 0 in case of + # upstream ("new world") UAPI, and 234 (-EINVAL truncated) in case of + # old-world (as deployed on several early commercial Linux distributions + # for LoongArch). + # + # See https://gist.github.com/xen0n/5ee04aaa6cecc5c7794b9a0c3b65fc7f for + # source to this helper binary. + ignore base64 -d > "$_tmp" <&2 + echo 'Your Linux kernel does not provide the ABI required by this Rust' >&2 + echo 'distribution. Please check with your OS provider for how to obtain a' >&2 + echo 'compatible Rust package for your system.' >&2 + echo >&2 + exit 1 + ;; + *) + echo "Warning: Cannot determine current system's ABI flavor, continuing anyway." >&2 + echo >&2 + echo 'Note that the official Rust distribution only works with the upstream' >&2 + echo 'kernel ABI. Installation will fail if your running kernel happens to be' >&2 + echo 'incompatible.' >&2 + ;; + esac +} + get_architecture() { local _ostype _cputype _bitness _arch _clibtype _ostype="$(uname -s)" @@ -393,6 +454,7 @@ get_architecture() { ;; loongarch64) _cputype=loongarch64 + ensure_loongarch_uapi ;; *) err "unknown CPU type: $_cputype"