]> git.ipfire.org Git - ipfire-2.x.git/commitdiff
make.sh: Fix build with kernels < 6.0.0
authorMichael Tremer <michael.tremer@ipfire.org>
Mon, 19 Aug 2024 18:06:23 +0000 (18:06 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Mon, 19 Aug 2024 18:06:23 +0000 (18:06 +0000)
unshare(8) seems to fail with kernels older than 6.0.0 when mounting
the /proc filesystem in the inner namespace. This seems to be an bug
where unshare does not even try to mount the /proc filesystem but tries
to make its mount propagation private.

This is now solved in that way that we will use unshare on newer kernels
but will fall back on manually mounting the /proc filesystem once we have
entered the chroot environment.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
make.sh
tools/execute.sh

diff --git a/make.sh b/make.sh
index 8e0154107f6c2a489c49d7f1125e46d15314d817..f2738eec4b829a998b9ae51863f8dd840e4d7e36 100755 (executable)
--- a/make.sh
+++ b/make.sh
@@ -42,6 +42,7 @@ TOOLCHAINVER=20240521
 ###############################################################################
 
 HOST_ARCH="${HOSTTYPE}"
+HOST_KERNEL="$(uname -r)"
 LC_ALL=POSIX
 PS1='\u:\w$ '
 
@@ -290,6 +291,76 @@ __timer_event() {
        return 0
 }
 
+version_compare() {
+       local v1="${1}"
+       local op="${2}"
+       local v2="${3}"
+
+       # Split both versions by .
+       v1=( ${v1//./ } )
+       v2=( ${v2//./ } )
+
+       # Run for as long as both versions have not been fully processed
+       while [ "${#v1[@]}" -gt 0 ] && [ "${#v2[@]}" -gt 0 ]; do
+               # Fetch the first element from each version
+               local f1="${v1[@]:0:1}"
+               local f2="${v2[@]:0:1}"
+
+               # Shift the array
+               v1=( ${v1[@]:1} )
+               v2=( ${v2[@]:1} )
+
+               local n1
+               local n2
+
+               # Split off any numeric parts
+               if [[ ${f1} =~ ^([0-9]+) ]]; then
+                       n1="${BASH_REMATCH[1]}"
+               fi
+
+               if [[ ${f2} =~ ^([0-9]+) ]]; then
+                       n2="${BASH_REMATCH[1]}"
+               fi
+
+               # Remove the numeric parts from each field
+               f1="${f1#${n1}}"
+               f2="${f2#${n2}}"
+
+               # Check the numeric parts first
+               if [ -n "${n1}" ] && [ -n "${n2}" ]; then
+                       case "${op}" in
+                               ge)
+                                       if [ "${n1}" -ge "${n2}" ]; then
+                                               return 1
+                                       fi
+                                       ;;
+                       esac
+
+               # If we only have a numeric part in the first version...
+               elif [ -n "${n1}" ]; then
+                       case "${op}" in
+                               ge)
+                                       return 1
+                                       ;;
+                       esac
+
+               # If we only have a numeric part in the second version...
+               elif [ -n "${n2}" ]; then
+                       case "${op}" in
+                               ge)
+                                       return 0
+                                       ;;
+                       esac
+               fi
+
+               # I don't know how to handle the non-numeric part here, and we should not need it
+               # as we are only using this for kernel versions which should all lead with numbers.
+       done
+
+       # Don't know
+       return 0
+}
+
 exiterror() {
        # Dump logfile
        if [ -n "${LOGFILE}" ] && [ -e "${LOGFILE}" ]; then
@@ -662,13 +733,19 @@ execute() {
                        # Create a new UTS namespace
                        "--uts"
 
-                       # Mount /proc so that the build environment does not see
-                       # any foreign processes.
-                       "--mount-proc=${BUILD_DIR}/proc"
-
                        # If unshare is asked to terminate, terminate all child processes
                        "--kill-child"
                )
+
+               # Mount /proc so that the build environment does not see
+               # any foreign processes.
+               # This does not work on kernels < 6.0.0, and we will mount /proc
+               # in the execute.sh script instead.
+               if version_compare "${HOST_KERNEL}" ge "6.0.0"; then
+                       unshare+=(
+                               "--mount-proc=${BUILD_DIR}/proc"
+                       )
+               fi
        fi
 
        while [ $# -gt 0 ]; do
index b3bf42f223d392234e01527309491566497b45d4..7a5b218b439706c96373acb9fe84f42c2dd78ed1 100755 (executable)
 # This is a helper script that is called after we have created the new
 # namespaces to perform further setup. This will be executed on the host.
 
+# Mount /proc if it has not been mounted, yet
+if ! mountpoint /proc; then
+       mount -t procfs none /proc -o nosuid,noexec,nodev
+fi
+
 # Bring up the loopback interface
 ip link set lo up &>/dev/null