Skip to content

export.json records the effective size; recovery reconciles a size mismatch - #105

Merged
jaredLunde merged 1 commit into
mainfrom
jared/export-effective-size
Nov 2, 2026
Merged

jaredLunde merged 1 commit into
mainfrom
jared/export-effective-size

Conversation

@jaredLunde

Copy link
Copy Markdown
Contributor

Homelab GlideFS handoff (v0.9.6 upgrade and a same-binary dry run) aborts with ExportMismatch: the successor cannot restore two rootfs-cache.bases-ubuntu-noble-16g.* exports. Journal: Cannot shrink device stored_size=17179869184 config_size=4294967296 then Failed to restore export ...: Invalid cache metadata (cli/server.rs recovery, write_cache/inner.rs shrink check). S3 export.json said size_gb: 4.0; the live device is 16 GiB because a fork is at least as large as its base (router.rs create_export fork path). Any restart or handoff of such an export fails.

Fix

  • PUT /api/exports saves the handler's real size in export.json (api.rs).
  • The recovery path loads the persisted manifest before opening the cache and uses max(export.json, manifest size) (router.rs create_export, normal path; the manifest is fetched once, as before). So existing export.json files that still record the request recover too: no deletion, no migration.
  • ARCHITECTURE.md recovery paragraph updated.

Proof

test_fork_smaller_than_base_records_effective_size_and_recovers (hermetic): fork a 0.1 GB image at size_gb 0.01; assert export.json records 0.1; rewrite it to the legacy 0.01, shut the router down, build a second router on the same store and cache dir, and recover (what the successor does in a handoff).

  • On main: FAILED at the size assertion (0.01); with that assertion disabled, FAILED at recovery with Cache(InvalidMetadata), the production error.
  • On this branch: passes. cargo test -p glidefs --features ublk --lib -- block::api block::router: 125 passed.

🤖 Generated with Claude Code

https://claude.ai/code/session_01XoaQgogNq1z3dNoM9feGoH

…he manifest's size

A fork is at least as large as its base whatever size_gb asked for, but
export.json recorded the request. On recovery the cache was opened at the
smaller size and refused ("Cannot shrink device", Cache(InvalidMetadata)),
so the export was left out of the successor router: every restart and
graceful handoff of such an export aborted with ExportMismatch (homelab:
two rootfs-cache staging exports, 4 GiB recorded, 16 GiB real).

PUT /api/exports now saves the handler's real size, and the recovery path
takes max(export.json, persisted manifest size) before opening the cache.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XoaQgogNq1z3dNoM9feGoH
@jaredLunde
jaredLunde merged commit fef334d into main Nov 2, 2026
25 checks passed
@jaredLunde
jaredLunde deleted the jared/export-effective-size branch November 2, 2026 06:39
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