Skip to content

fix(selfupdate): count the current binary towards the space budget - #548

Merged
gnacho merged 1 commit into
mainfrom
fix/547-selfupdate-space-precheck
Oct 20, 2026
Merged

gnacho merged 1 commit into
mainfrom
fix/547-selfupdate-space-precheck

Conversation

@gnacho

@gnacho gnacho commented Oct 20, 2026

Copy link
Copy Markdown
Owner

Problem

installSelfUpdate runs the free-space pre-check before unlinking the current binary, so on tiny overlays the check demands the full size of the new binary plus 1 MiB headroom from free space alone, ignoring the space that os.Remove(currentBin) frees a moment later.

Real failure on a Linksys LGS352C (OpenWrt, 20.3 MB overlay, ~15.8 MB binaries):

self-update failed: install: not enough space on /usr/sbin for the new binary (need ~15794331 bytes)

The overlay had ~11 MB free and the running binary was ~15.1 MB, so the swap itself fit comfortably; the check just could not see it.

Fix

spaceFor now takes the bytes the install is about to free (the current binary's apparent size) and adds them to the available-space budget. Apparent size is used on purpose: on compressing filesystems (ubifs) it overestimates what the unlink actually frees, which is the safe direction for a pre-check. A false "not enough" only fails the update; a false "enough" defers ENOSPC to the copy, which is already handled gracefully (rescue copy in tmpfs, clear error, service keeps running the old binary).

Test

TestSpaceForCountsFreedBytes: a need above raw free space passes once the freed bytes are counted, fails without them, and the 1 MiB headroom is still enforced on top of avail + freed.

)

The install pre-check demanded the whole new binary plus headroom from
free space alone, ignoring the space the unlink of the current binary
frees before the copy. On tiny overlays (20 MB flash, ~16 MB binary)
free space never reaches the new binary size, so every self-update
failed with "not enough space" even though the swap itself fit.

Add the current binary's apparent size to the budget: on compressing
filesystems (ubifs) it overestimates the freed space, the safe
direction for a pre-check. The rescue copy and the graceful ENOSPC
handling on the copy itself stay unchanged.

Closes #547
@gnacho
gnacho merged commit 6233aa7 into main Oct 20, 2026
2 checks passed
@gnacho
gnacho deleted the fix/547-selfupdate-space-precheck branch October 20, 2026 07:31
borky pushed a commit to borky/netgrip that referenced this pull request Oct 25, 2026
Upstream gnacho#548 counted the current binary towards the space budget because
it is unlinked before the copy. But self-update replaces the running
binary, whose blocks are not freed until the process exits. On a
near-full overlay the pre-check now passed, the old binary was removed,
and the copy ran out of space halfway, leaving a truncated binary for
procd to start next time. The running binary no longer counts; one that
is not running still does.
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.

1 participant