Uninstallable Firmware Artifacts: Check Available Space Before Reserving a Campaign Slot
Admit an update against the peak additional allocation on each real storage pool, then reserve that budget through the stages that consume it. A bundle that fits its destination slot can still fail because staging, temporary output, recovery data or concurrent jobs exhaust another filesystem.
This guide defines an original runtime admission ledger for a Linux-based updater, with RAUC 1.13 as an example of why installation methods need different resource plans. It is distinct from static image-size budgeting. No filesystems were filled, artifacts deleted or installations performed.
1. Map allocations to real capacity pools
List the download destination, temporary directory, raw target slot, updater state, diagnostic output and any required recovery snapshot. Resolve directories to their actual backing filesystems. Two paths on the same filesystem draw from one pool; two partitions cannot generally borrow each other’s spare capacity.
For each allocation, record its owner, maximum additional bytes, object-count requirement, creation stage and earliest permitted release stage. Include the failure path: a partially produced candidate and the prior valid artifact may need to coexist until reconciliation.
| Allocation | Lifetime question | Admission consequence |
|---|---|---|
| Downloaded bundle | Must it remain through installation or retry? | Do not release its budget at download completion |
| Temporary reconstructed output | Does it overlap the input and old output? | Count the overlap, not only final image size |
| Required recovery snapshot | When may it be retired under policy? | Preserve it even if the new download needs space |
| Updater metadata and bounded logs | Must they survive an incomplete install? | Reserve failure-reporting and reconciliation capacity |
| Raw target slot | Does the logical image fit its own target? | Evaluate separately from filesystem free bytes |

2. Derive the plan from the installation method
The RAUC 1.13 basics describes mounting its SquashFS bundle without unpacking the complete bundle into another staging tree. Streaming can avoid storing the full downloaded bundle first. Therefore, blindly budgeting “download plus full unpack” can overstate one method while missing a custom hook’s real temporary work.
Conversely, a delta reconstruction or application-specific conversion may create substantial output alongside retained input. Inventory what this deployed implementation actually allocates. Do not apply a streaming plan to a fallback that downloads a conventional bundle, or assume a casync index accounts for all temporary helper needs.
The tagged raw-image size check compares image length with block-device capacity where supported. That is a separate constraint from free space in an updater’s writable filesystem. Passing either check does not imply the other passed.
3. Compute peak overlap without double counting
For a pool, define A as the current usable allocation budget established by the product’s filesystem and quota policy. Let U be admitted but not yet allocated commitments belonging to other jobs, M the required remaining margin, and R the new job’s maximum additional live allocation from the current stage onward.
The proposed gate is R + U + M ≤ A, evaluated with checked units and overflow-safe arithmetic. R comes from the maximum simultaneous overlap across the remaining stages, not the sum of allocations whose lifetimes never overlap.
Already allocated files are reflected in the current available-space observation. Do not subtract them again as unallocated commitments. If a reservation becomes an actual allocation, reconcile both the observation and ledger consistently so the same bytes do not remain charged twice or become briefly available to two jobs.
Apply the gate independently to every pool. A pass on staging storage cannot compensate for a failed temporary-filesystem or target-slot gate. Keep retained recovery objects in place; their future replacement may require additional budget even though their current allocation is already reflected in A.
4. Treat free-space samples as observations
The Linux man-pages 6.19 statvfs reference defines filesystem statistics including f_bavail, fragment size and available inode counts, and warns that not all fields are meaningful on every filesystem. Check the return value and field semantics before conversion. A failed or unsuitable observation is not zero-cost permission to proceed.
Use the actual service’s mount view and applicable quota limits. Validate block-to-byte conversion against the chosen interface; retain raw values and observation time for diagnosis. A positive byte budget does not prove that inode limits, permissions, read-only state or quota allow the planned objects.
The snapshot does not reserve capacity. Serialize reservations among participating product writers, and define how unrelated writers are constrained or accommodated. Even a correct application ledger must handle allocation, write, synchronization and close failures from the real storage stack.
5. Release reservations only at verified boundaries
Give every reservation an operation identity, pool, stage and remaining unallocated commitment. A download timeout does not establish that its partial file disappeared. Likewise, a client disconnect does not release space owned by a still-running installer.
On restart, reconcile records against actual owned artifacts and installer state before granting new reservations. Use explicit ownership and validated metadata; do not identify cleanup candidates by filename suffix alone. Unknown files or required recovery data remain outside automatic cleanup until policy establishes their disposition.
If optional cleanup is permitted, remove only objects within the already authorized retention policy and confirm the resulting capacity before readmission. Never delete calibration, identity, customer data or the only recovery artifact to force a passing preflight.
6. A hypothetical peak-space rejection
Suppose a staging pool has an observed usable budget of 420 MiB. Existing unallocated commitments total 40 MiB and the policy requires 50 MiB to remain. A proposed update needs 350 MiB of additional peak storage while its input and prepared output coexist. Its admission total is 440 MiB, so it must wait or use a separately qualified plan.
A recovery artifact already occupying that pool is not subtracted a second time from the observed 420 MiB. It also is not automatically disposable. A streaming alternative may reduce R, but only after its own temporary, target and interruption requirements are validated.
7. Test the ledger at failure boundaries
- Two requests concurrently pass an initial free-space sample.
- A partial download remains after cancellation or restart.
- Temporary output reaches its peak while the original input is retained.
- Bytes remain available but object-count or quota limits reject creation.
- A fallback method requires more staging than the initial plan.
- Allocation succeeds but a later write or synchronization fails.
Use disposable volumes and preserved data for real low-space tests. Require accurate rejection, bounded diagnostics and recovery-artifact preservation. The useful release evidence is a stage-by-stage capacity plan and reconciled reservation ledger, not a single “free disk space” number captured before the campaign.