fix(archiso): use oflag=direct so USB write progress isn't misleading

Without oflag=direct, dd copies the ISO into the page cache at high speed, the
status=progress counter races to ~100%, then appears to hang at the end while
the slow USB drains and conv=fsync flushes — looking frozen when it is still
writing. write-usb.sh now writes with oflag=direct (honest device-level
progress) and falls back to a cached write if the bridge rejects O_DIRECT;
build.sh's dd hint and explanation are updated to match.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
main
Amir Alexander Abdelbaki 2026-06-26 19:22:23 +02:00
parent 3b0bf17210
commit 0e04a7cada
2 changed files with 17 additions and 5 deletions

View File

@ -240,7 +240,9 @@ if [[ -e "$_built_iso" ]]; then
echo
echo "To write it to a USB stick (block-level — required for BIOS boot):"
echo " bash $SCRIPT_DIR/write-usb.sh \"$_built_iso\" /dev/sdX"
echo " or directly: sudo dd if=\"$_built_iso\" of=/dev/sdX bs=4M conv=fsync status=progress"
echo " or directly: sudo dd if=\"$_built_iso\" of=/dev/sdX bs=4M conv=fsync oflag=direct status=progress"
echo " (oflag=direct makes the progress counter honest; without it dd races to"
echo " ~100% then pauses at the end while the slow USB flushes — not a hang.)"
echo " Do NOT drag-and-drop the .iso onto the USB, and avoid Rufus 'ISO' mode"
echo " (use 'DD' mode) — those cause 'failed to load ldlinux.c32' at boot."
fi

View File

@ -73,10 +73,20 @@ while read -r _part; do
sudo umount "/dev/$_part" 2>/dev/null || true
done < <(lsblk -ln -o NAME,TYPE "$DEV" | awk '$2=="part"{print $1}')
echo "Writing (block-level)…"
# bs=4M: large blocks for throughput; conv=fsync: flush to the device before dd
# exits so "Done" really means written; status=progress: live byte counter.
echo "Writing (block-level)… USB sticks are slow; this can take several minutes."
# oflag=direct bypasses the kernel page cache so the byte counter reflects data
# actually written to the device. WITHOUT it, dd copies into RAM cache at high
# speed, status=progress races to ~100%, and then appears to "hang" at the end
# while the slow USB drains and conv=fsync flushes — looking frozen when it is
# really still writing. ISO images are 2048-byte aligned, satisfying O_DIRECT.
# bs=4M: large blocks for throughput; conv=fsync: ensure everything is on the
# device before dd returns. Some USB bridges reject O_DIRECT (EINVAL); fall back
# to a cached write (which still finishes, just with the misleading end-stall).
if ! sudo dd if="$ISO" of="$DEV" bs=4M conv=fsync oflag=direct status=progress; then
echo "Direct write unsupported on this device — retrying via the page cache…"
echo "(progress will jump to ~100%, then pause at the end while the USB flushes)"
sudo dd if="$ISO" of="$DEV" bs=4M conv=fsync status=progress
fi
# Final flush of any remaining kernel buffers for the device.
sync