summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHelmut Grohne <helmut@subdivi.de>2025-03-30 15:56:12 +0200
committerHelmut Grohne <helmut@subdivi.de>2025-03-30 16:19:51 +0200
commit5c0e89a0a97a3d802bc990173fde5c309bfac002 (patch)
treec315a21502936e14030ff26d8db5f6a84d03044f
parent695c2e7b2a5e82b7e50b8472a6649584fa9406f1 (diff)
downloaddebvm-5c0e89a0a97a3d802bc990173fde5c309bfac002.tar.gz
debvm-create: work around arm32 boot failure
The long story of this commit can be found in #1079443. Special thanks to all of the following for investing significant amounts of time into debugging the root cause: * Tj <tj.iam.tj@proton.me> * Jochen Sprickerhof <jspricke@debian.org> * Chris Hofstaedtler <zeha@debian.org> In the end, dracut-install fails to install kernel modules (including virtio_blk) that are being passed as =directory if said directory has an inode number exceeding 32bit on an arm32 userland. Lots of thought has been expended into fixing fts on the glibc side with little conclusions. Since armhf is still somewhat important, we settle on a workaround here. The problem is acknowledged and we explicitly install the virtio_blk kernel module that dracut-install should have installed. Doing so at least makes the debvm boot. For reproducing the problem, TMPDIR needs to point to a directory where created directories receive inodes exceeding 32bit. On a tmpfs, this situation can be achieved by creating and deleting lots of directories. The following code can be run in parallel to increase the inode counter in a couple of hours: #include <sys/stat.h> #include <unistd.h> int main(int argc, char **argv) { for(;;) { mkdir(argv[1], 0755); rmdir(argv[1]); } }
-rwxr-xr-xshare/customize-kernel.sh55
1 files changed, 52 insertions, 3 deletions
diff --git a/share/customize-kernel.sh b/share/customize-kernel.sh
index d216eaa..0a252a4 100755
--- a/share/customize-kernel.sh
+++ b/share/customize-kernel.sh
@@ -8,14 +8,52 @@
set -eu
+if [ "${MMDEBSTRAP_VERBOSITY:-1}" -ge 3 ]; then
+ set -x
+fi
+
TARGET="$1"
+ARCHITECTURES=$(xargs < "$TARGET/var/lib/dpkg/arch")
+
+affected_by_1079443() {
+ case "${ARCHITECTURES%% *}" in
+ armel|armhf)
+ ;;
+ *)
+ return 1
+ ;;
+ esac
+ test "${1:-}" = --maybe && return 0
+ test -d "$TARGET/etc/initramfs-tools/hooks" || return 1
+ dpkg-query --root="$TARGET" --showformat='${db:Status-Status}\n' --show dracut-install 2>/dev/null | grep -q '^installed$'
+}
+work_around_1079443() {
+ # FTS or its usage in dracut-install is broken on some 32bit architectures.
+ echo "Warning: working around #1079443"
+ cat >"$TARGET/etc/initramfs-tools/hooks/work_around_1079443" <<'EOF'
+#!/bin/sh
+
+test "${1-}" = prereqs && exit 0
+
+. /usr/share/initramfs-tools/hook-functions
+
+# work around #1079443
+manual_add_modules virtio_blk
+EOF
+ chmod +x "$TARGET/etc/initramfs-tools/hooks/work_around_1079443"
+ if test "${1:-}" = --update && test -x "$TARGET/usr/bin/update-initramfs"; then
+ chroot "$TARGET/update-initramfs -u"
+ fi
+}
+
if dpkg-query --root="$TARGET" --showformat='${db:Status-Status}\n' --show 'linux-image-*' 2>/dev/null | grep -q '^installed$'; then
+ if affected_by_1079443; then
+ work_around_1079443 --update
+ fi
exit 0
fi
-ARCHITECTURES=$(xargs < "$TARGET/var/lib/dpkg/arch")
-
KERNEL_ARCH="${ARCHITECTURES%% *}"
case "$KERNEL_ARCH" in
armel)
@@ -70,4 +108,15 @@ else
fi
# On some derivatives such as Ubuntu, linux image does not depend on an initramfs.
-apt-get --yes satisfy "$@" "linux-image-cloud-$KERNEL_ARCH | linux-image-$KERNEL_ARCH | linux-image-generic" "initramfs-tools | linux-initramfs-tool"
+KERNEL_SATISFY="linux-image-cloud-$KERNEL_ARCH | linux-image-$KERNEL_ARCH | linux-image-generic"
+INITRD_SATISFY="initramfs-tools | linux-initramfs-tool"
+
+if affected_by_1079443 --maybe; then
+ apt-get --yes satisfy "$@" "$INITRD_SATISFY"
+ if affected_by_1079443; then
+ work_around_1079443
+ fi
+ apt-get --yes satisfy "$@" "$KERNEL_SATISFY"
+else
+ apt-get --yes satisfy "$@" "$KERNEL_SATISFY" "$INITRD_SATISFY"
+fi