Skip to content

Retry a format that failed, instead of skipping it for ever (#168) - #169

Merged
eliasbakken merged 1 commit into
mainfrom
fix-168-unformatted-usb
Sep 18, 2026
Merged

eliasbakken merged 1 commit into
mainfrom
fix-168-unformatted-usb

Conversation

@eliasbakken

Copy link
Copy Markdown
Contributor

Fixes #168.

A board sat unusable across five reboots and a fresh flash - storage: FAILED, mount refusing /dev/sda2 for a bad superblock, ssh-keygen-boot unable to restore host keys so sshd never started, and with no readable options.cfg the board on its own hotspot instead of the configured WiFi. It read as a bad flash. It was a partition with no filesystem: correctly sized, blank from its first byte.

Three changes

The guard. expand-usb asked whether the partition existed to decide whether there was work to do, so once sda2 had been created a failed format was never retried - the one step that could fix the drive was the one being skipped. It now asks whether there is a filesystem (lsblk -no FSTYPE, and lsblk is in the image), and formats a partition that has none without re-partitioning it.

A settle before mkfs. On the first boot of a freshly written stick, ssh-keygen-boot started at 11:29:21 and failed at 11:29:22. mkfs on this stick takes ~31s by this script's own measured comment, and that boot's log reached "Creating ext4 filesystem" - so mkfs was invoked and returned an error immediately, rather than being cut short. The device is fine: the same mkfs by hand afterwards succeeded in two seconds and brought the board straight back. That points at mke2fs opening the device O_EXCL while udev is still probing a partition that appeared a moment earlier - the same race as #145 and #147.

mkfs's output into the log. It points rather than proves, and that is the third fix: mkfs wrote its reason to stderr, stderr went to the journal, and this rootfs is a ramdisk, so the explanation died with the reboot. set -e already stopped the script; nothing recorded why.

Tests

Static checks on the script text, like flash-cleanup.bats and for the same reason: this script hardcodes /dev/sda with no seams, and a real run needs root and losetup. All five defect tests fail against the old script and pass against this one.

make test: Go, bats (99 including the six new), and 144 vitest all pass.

Note

The failure is intermittent - plenty of boots format cleanly - but its result was not: one unlucky second left a board with no storage, no ssh and no WiFi config until someone formatted the partition by hand over the serial console.

🤖 Generated with Claude Code

A board sat unusable across five reboots and a fresh flash: storage FAILED, no
images, mount refusing /dev/sda2 for a bad superblock, ssh-keygen-boot unable to
restore host keys so sshd never started, and - with no readable options.cfg -
the board on its own hotspot instead of the WiFi it was configured for. It read
as a bad flash. It was a partition with no filesystem: correctly sized, and
blank from its first byte.

expand-usb asked whether the *partition* existed to decide whether there was
anything to do, so the one thing that could fix the drive was the step being
skipped. It now asks whether there is a filesystem - lsblk reports an empty
FSTYPE, and lsblk is in the image - and formats a partition that has none
without re-partitioning it.

Why the format failed at all: on the first boot of a freshly written stick,
ssh-keygen-boot started at 11:29:21 and failed at 11:29:22. mkfs on this stick
takes ~31s by the measurement in the comment below, and that boot's log reached
"Creating ext4 filesystem" - so mkfs was invoked and returned an error at once
rather than being cut short. The device is fine: the same mkfs by hand
afterwards succeeded in two seconds and brought the board straight back.

That points at mke2fs opening the device O_EXCL while udev is still probing a
partition that appeared a moment earlier - the same race as #145 and #147 - so
there is a settle before the format now.

It points, rather than proves, and that is the third fix here: mkfs wrote its
reason to stderr, stderr went to the journal, and this rootfs is a ramdisk, so
the explanation died with the reboot that followed. It goes to the reflash log
now. set -e already stopped the script; nothing recorded why.

The tests are static checks on the script text, like flash-cleanup.bats and for
the same reason - this script hardcodes /dev/sda with no seams, and a real run
needs root and losetup. All five defect tests fail against the old script.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@eliasbakken
eliasbakken merged commit 4e67472 into main Sep 18, 2026
2 checks passed
@eliasbakken
eliasbakken deleted the fix-168-unformatted-usb branch September 18, 2026 14:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

One failed format leaves the USB drive unformatted for ever: the guard checks for a partition, not a filesystem

1 participant