From a076deb55a4db8ee326e6c0b72275632b7392587 Mon Sep 17 00:00:00 2001 From: Elias Bakken Date: Mon, 10 Aug 2026 21:11:45 +0200 Subject: [PATCH] Fix create-recore-config to actually provision the eMMC config Three bugs, all reported in #85: 1. Formatted a nonexistent partition node - mkfs.ext4 targeted /dev/mmcblk2boot0p1, but the kernel doesn't create child partition nodes for eMMC boot partitions. mount-config and every other reader loop-mount the raw device directly at offset 17408 instead - the filesystem now gets created the same way, via a loop device at that offset, not via fdisk/a partition node that never existed. 2. metadata_csum (default-on in e2fsprogs 1.47) left no room for the dir-leaf checksum once the filesystem picked a 1K block size at this tiny size, so reads failed with "Bad message". Disabled via -O ^metadata_csum,^64bit. 3. The create path wrote through mount-config, which always mounts read-only (it's meant for readers) - the echo > serial_number would fail even with a valid filesystem. The create path now mounts the loop device directly, read-write, instead. Also fixed a related bug in get-recore-serial-number: it called plain umount instead of unmount-config to tear down the transient mount mount-config sets up via systemd-mount. Plain umount unmounts the filesystem but doesn't deregister the transient systemd unit, so a later mount-config call can fail with "Unit mnt-config.mount was already loaded". Live-tested on real hardware: extracted and backed up the board's existing (already-provisioned) config partition first, ran the fixed create-recore-config against the same serial, and confirmed get-recore-revision/get-recore-serial-number both work and the downloaded calibration.json is byte-identical to the original. Closes #85 --- bin/prod/create-recore-config | 38 +++++++++++++++++++++++-------- bin/prod/get-recore-serial-number | 2 +- test/bats/getters.bats | 2 +- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/bin/prod/create-recore-config b/bin/prod/create-recore-config index 2dfcfce..953968f 100755 --- a/bin/prod/create-recore-config +++ b/bin/prod/create-recore-config @@ -1,6 +1,9 @@ #!/bin/bash +set -euo pipefail + SERIAL_NR=$1 +OFFSET=17408 info() { echo "[info] $1" >> /var/log/reflash.log @@ -52,23 +55,38 @@ fi info "Calibration file valid" DEV=`lsblk -n -o NAME | grep 'mmcblk[0-2]$'` +DEV_BOOT="/dev/${DEV}boot0" echo 0 > "/sys/block/${DEV}boot0/force_ro" -info "Creating boot partition" -dd if=/dev/zero of=/dev/${DEV}boot0 -partprobe -printf "g\nn\n\n\n\nw\n" | fdisk /dev/${DEV}boot0 -partprobe -mkfs.ext4 -E nodiscard /dev/${DEV}boot0p1 +# The kernel doesn't create a child partition node for eMMC boot +# partitions (there's no ${DEV_BOOT}p1), and mount-config/other readers +# loop-mount the raw device directly at a byte offset - so the +# filesystem has to be created the same way, not via fdisk/mkfs on a +# nonexistent partition node. +info "Creating config filesystem" +# Zeroing the whole device this way always ends in "No space left on +# device" once dd hits the end of the block device - that's the +# expected way it finishes, not a real failure. +dd if=/dev/zero of="$DEV_BOOT" bs=1M || true +LOOP=$(losetup -f --show -o "$OFFSET" "$DEV_BOOT") +# metadata_csum (default-on in e2fsprogs 1.47) leaves no room for the +# dir-leaf checksum once the filesystem picks a 1K block size, which it +# does at this size - reads then fail with "Bad message". Disable it. +mkfs.ext4 -F -q -O ^metadata_csum,^64bit -E nodiscard "$LOOP" -mount-config +# mount-config always mounts read-only (it's meant for readers); the +# create path needs to write, so mount the loop device directly rather +# than going through mount-config/unmount-config here. +mkdir -p /mnt/config +mount "$LOOP" /mnt/config echo "$SNR" > /mnt/config/serial_number info "Downloading calibration file ${FILE}" -wget $URL -mv ${FILE} /mnt/config +wget -O "/mnt/config/${FILE}" "$URL" -unmount-config +sync +umount /mnt/config +losetup -d "$LOOP" echo 1 > "/sys/block/${DEV}boot0/force_ro" info "Done" diff --git a/bin/prod/get-recore-serial-number b/bin/prod/get-recore-serial-number index dfb4913..407dc90 100755 --- a/bin/prod/get-recore-serial-number +++ b/bin/prod/get-recore-serial-number @@ -6,4 +6,4 @@ CONFIG_DIR="${REFLASH_CONFIG_DIR:-/mnt/config}" mount-config cat "$CONFIG_DIR/serial_number" -umount "$CONFIG_DIR/" +unmount-config diff --git a/test/bats/getters.bats b/test/bats/getters.bats index ea11b4e..77c3766 100644 --- a/test/bats/getters.bats +++ b/test/bats/getters.bats @@ -22,7 +22,7 @@ teardown() { teardown_sandbox; } mkdir -p "$REFLASH_CONFIG_DIR" echo "RC-0001-XYZ" > "$REFLASH_CONFIG_DIR/serial_number" stub_silent mount-config - stub_silent umount + stub_silent unmount-config run "$PROD_BIN/get-recore-serial-number" [ "$status" -eq 0 ] [ "$output" = "RC-0001-XYZ" ]