From 2c784c51950418141a11add0d2682ca3c85fc6e6 Mon Sep 17 00:00:00 2001 From: Johannes Schauer Marin Rodrigues <josch@mister-muffin.de> Date: Fri, 29 Mar 2024 02:03:35 +0100 Subject: [PATCH] switch from genext2fs to mkfs.ext4 Problems with genext2fs: - slow O(n^2) runtime - need to upgrade ext2 filesystems to ext4 on first boot - inode size of 128 disallows timestamps beyond 2038 or sub-second precision timestamps Problems with mkfs.ext4: - not bit-by-bit reproducible across multiple invocations The problems with mkfs.ext4 are solved once this PR is merged: https://github.com/tytso/e2fsprogs/pull/118 --- .gitlab-ci.yml | 2 +- mkimage.sh | 68 ++++++++++++++++++++++++++++++++++---------------- 2 files changed, 47 insertions(+), 23 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 778c3ef..999ae0b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -30,7 +30,7 @@ build: fi fi apt update -o Acquire::AllowReleaseInfoChange=true -o quiet::ReleaseInfoChange=true - apt-get --no-install-recommends -y install mmdebstrap genext2fs ca-certificates e2fsprogs pigz git mount parted apt-utils libarchive-tools python3-apt + apt-get --no-install-recommends -y install mmdebstrap ca-certificates e2fsprogs pigz git mount parted apt-utils libarchive-tools python3-apt if [ ! -e /proc/sys/fs/binfmt_misc/status ]; then mount -t binfmt_misc binfmt_misc /proc/sys/fs/binfmt_misc fi diff --git a/mkimage.sh b/mkimage.sh index 1a3a652..95795a7 100755 --- a/mkimage.sh +++ b/mkimage.sh @@ -78,7 +78,7 @@ case "$MIRROR" in esac # make sure build tools are installed -set -- mmdebstrap genext2fs e2fsprogs git mount parted python3-apt +set -- mmdebstrap e2fsprogs git mount parted python3-apt if [ "$(dpkg --print-architecture)" != arm64 ]; then set -- "$@" arch-test qemu-user-static fi @@ -93,10 +93,6 @@ if dpkg --compare-versions "$(dpkg-query --showformat='${Version}\n' --show mmde echo "mmdebstrap version must be >= 0.8.4-1" exit 1 fi -if dpkg --compare-versions "$(dpkg-query --showformat='${Version}\n' --show genext2fs)" lt "1.5.0-2"; then - echo "genext2fs version must be >= 1.5.0-2" - exit 1 -fi # if we are in a git repository and if SOURCE_DATE_EPOCH is not set, use the # timestamp of the latest git commit @@ -226,6 +222,14 @@ set -- "$@" \ --customize-hook='rm "$1"/etc/resolv.conf' # copy out kernel and initrd for use with qemu set -- "$@" --customize-hook="download /vmlinuz kernel" --customize-hook="download /initrd.img initrd" +# copy out contents of /boot +set -- "$@" --customize-hook="tar-out /boot boot.tar" +# choose the correct mode +if [ "$(id -u)" = 0 ]; then + set -- "$@" --mode=root +else + set -- "$@" --mode=unshare +fi case "$DIST" in testing) @@ -239,12 +243,35 @@ case "$DIST" in ;; esac -mmdebstrap "$@" target-userland.tar +if [ "$(id -u)" = 0 ]; then + run_inside_userns() { + "$@" + } +else + run_inside_userns() { + unshare --user --map-auto --map-user=65536 --map-group=65536 --keep-caps -- "$@" + } +fi + +TEMPROOT= +cleanup() { + if test -n "$TEMPROOT"; then + run_inside_userns rm -Rf "$TEMPROOT" + fi + rm -f boot.ext4 boot.tar root.ext4 +} +trap cleanup EXIT +# The default action for these signals does not invoke the EXIT trap. +trap 'exit 1' HUP INT QUIT TERM +TEMPROOT="$(mktemp -d)" + +mmdebstrap "$@" --format=directory --mode=unshare --skip=output/dev "$TEMPROOT" # create a common root partition from the above # this will be identical independent of the sysimage -mmtarfilter --path-exclude='/boot/*' < target-userland.tar \ - | genext2fs --volume-label reformsdroot --block-size 1024 --size-in-blocks $((ROOTSIZE*1024)) --bytes-per-inode 16384 --tarball - root.ext2 +run_inside_userns find "$TEMPROOT/boot/" -mindepth 1 -delete +: >root.ext4 +run_inside_userns /sbin/mkfs.ext4 -L reformsdroot -d "$TEMPROOT" "root.ext4" "${ROOTSIZE}M" # system --------------------------------------------------------- @@ -319,9 +346,9 @@ for SYSIMAGE in $SYSIMAGES; do exit 1 fi MACHINE="$(basename "$CONF" .conf)" - # FIXME: use --skip=tar-in/mknod once support for it is in stable set -- --variant=custom --skip=update,setup,cleanup \ - --setup-hook='mmtarfilter --path-exclude="/dev/*" --path-include=/dev/pts --path-include=/dev/shm < target-userland.tar | tar --numeric-owner --xattrs --xattrs-include="*" --directory "$1" --extract --file -' \ + --skip=check/empty \ + --setup-hook="tar-in boot.tar /" \ --customize-hook="upload ./$(basename "$DTBPATH" .dtb)-flash.bin /boot/flash.bin" \ --chrooted-customize-hook=" set -exu; @@ -344,20 +371,18 @@ for SYSIMAGE in $SYSIMAGES; do --chrooted-customize-hook='update-initramfs -u' ;; esac - mmdebstrap "$@" '' - \ - | mmtarfilter --path-exclude='*' --path-include=/boot \ - --path-include='/boot/*' --strip-components=2 \ - | genext2fs --volume-label reformsdboot --block-size 1024 \ - --size-in-blocks $((BOOTSIZE*1024)) --bytes-per-inode 16384 \ - --tarball - boot.ext2 + mmdebstrap "$@" '' --format=directory --mode=unshare --skip=output/dev "$TEMPROOT" + + : >boot.ext4 + run_inside_userns /sbin/mkfs.ext4 -L reformsdboot -d "$TEMPROOT/boot" "boot.ext4" "${BOOTSIZE}M" # make sure that the filesystem includes boot.scr - /usr/sbin/debugfs boot.ext2 -R "stat boot.scr" \ - | sed 's/ \+/ /g' | grep --quiet "Type: regular Mode: 0644 Flags: 0x0" + /usr/sbin/debugfs boot.ext4 -R "stat boot.scr" \ + | sed 's/ \+/ /g' | grep --quiet "Type: regular Mode: 0644 Flags: 0x" - dd if=root.ext2 of="$SYSIMAGE.img" seek=$((((BOOTSIZE+4)*1024*1024)/4194304)) bs=4194304 - dd if=boot.ext2 of="$SYSIMAGE.img" seek=1 bs=4194304 conv=notrunc - rm boot.ext2 + dd if=root.ext4 of="$SYSIMAGE.img" seek=$((((BOOTSIZE+4)*1024*1024)/4194304)) bs=4194304 + dd if=boot.ext4 of="$SYSIMAGE.img" seek=1 bs=4194304 conv=notrunc + rm boot.ext4 truncate --size="+512" "$SYSIMAGE.img" /sbin/parted -s "$SYSIMAGE.img" "mklabel msdos" # reproducible disk signature @@ -382,4 +407,3 @@ echo "MD5 checksums:" >&2 for SYSIMAGE in $SYSIMAGES; do md5sum "$SYSIMAGE.img" >&2 done -rm target-userland.tar root.ext2 -- GitLab