Skip to content

git-mirror: fstrim the mirror sticky disk before unmount at commit - #63

Open
magma-beef wants to merge 3 commits into
mainfrom
devin/1792451273-git-mirror-fstrim
Open

magma-beef wants to merge 3 commits into
mainfrom
devin/1792451273-git-mirror-fstrim

Conversation

@magma-beef

@magma-beef magma-beef commented Oct 20, 2026 •

Copy link
Copy Markdown

Summary

Feature — git-mirror cleanup runs a best-effort fstrim on the mirror sticky disk right before unmounting a disk it is about to commit, for at most the number of seconds the VM agent sends. Nothing changes until a host is configured: the agent sends 0 today, and the hypervisor does not negotiate discard yet.

Start here: src/blacksmith-cache.ts (fstrimTimeoutSecsFrom, the trim in cleanup); src/state-helper.ts, src/git-source-provider.ts, src/main.ts only carry the budget from mount to cleanup. dist/ is generated.

Why

The git-mirror sticky disk is an RBD image; packs that git gc/maintenance deletes stay allocated in Ceph until the guest discards them. Same change as useblacksmith/stickydisk#82 for the bare action and useblacksmith/setup-docker-builder#143 for buildkit.

What

  • On cleanup, when the run will commit the mirror (shouldCommit) and the host enabled the trim, run timeout <secs> sudo fstrim -v -- <mount> after sync/maintenance and before umount. Any exit code or exception only logs ([git-mirror] fstrim ...: <output> | timed out after Ns | failed: ...).
  • The budget comes from the VM agent: GetStickyDiskResponse.fstrim_timeout_secs (FastActions/fa#6600, live config guest_fstrim_timeout_secs), saved in action state at mount time. 0/absent = no trim, so this release does nothing until the agent sends a budget — the rollout and its tuning are agent-side.
  • fstrimTimeoutSecsFrom() reads the typed field when the bundled proto package has it, else unknown field 8 via listUnknownFields() (protobuf-es keeps unknown binary fields; the transport is gRPC), so this version keeps working once the agent starts sending the field without a package bump.

Evidence

Check Result
npm run lint, npm run format-check, npm run build clean; dist/ committed
npm test 199 pass; new tests for parseFstrimTimeoutSecs, fstrimTimeoutSecsFrom, decodeVarint
CI build, check-dist, test (ubuntu/macos/windows), git-mirror e2e legs, CodeQL green

Risks

Verdict: Ship. With the agent sending 0 (current default) cleanup only reads one state value; the trim path is reachable only after a host is configured.
Worry about: once a host is configured and discard is negotiated, the first trim of a large never-trimmed mirror runs until the budget expires and cleanup is longer by up to that budget; later trims are incremental.
Checked, not worried: every trim failure mode (unsupported discard, missing binary, timeout) logs and continues; the trim happens after maintenance/sync so it describes the committed state; non-commit runs skip it.
If it goes wrong: cleanup logs [git-mirror] fstrim ...: failed|timed out; set guest_fstrim_timeout_secs back to 0 on the host — no action release needed.

Related: useblacksmith/stickydisk#82, useblacksmith/setup-docker-builder#143, FastActions/fa#6600, useblacksmith/web#18629.

Link to Devin session: https://app.devin.ai/sessions/2e17815c306b4c3cb7af4f6bce008a66
Open in Devin Desktop: https://app.devin.ai/desktop/session/2e17815c306b4c3cb7af4f6bce008a66?variant=devin
Requested by: @magma-beef


Devin Review


View with [code]smith Generate Proof with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.


View with [code]smith View full Proof
Need help on this PR? Tag @codesmith-bot with what you need. (Staging)

magma-beef and others added 3 commits October 19, 2026 23:07
Deleted packs keep their RBD extents allocated on the backing store until
the guest discards them. Run a best-effort fstrim on the mirror mount
after sync and before unmount, only when the run will commit and only
when the host enabled it: the VM agent returns
GetStickyDiskResponse.fstrim_timeout_secs (fa live config
guest_fstrim_timeout_secs), saved in action state at mount time; 0 means
no trim. Any failure or timeout only logs.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…oto package predates it

The bundled GetStickyDiskResponse has no fstrim_timeout_secs yet, and protobuf-es keeps fields it does not know in the message's unknown-field list (the gRPC transport is binary), so decode field 8 from there when the typed field is absent. Releases built before the field existed therefore honour the host budget once the agent sends it.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

@blacksmith-staging

blacksmith-staging Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Checked Post step trims the mirror before unmount

After, the post step trims the mounted mirror between maintenance and unmount, and a deleted 512 MiB pack's blocks are released from the backing image; before, they stay allocated through commit.

Merge-base

Before: no trim

This PR f36ea7dd

After: trim before unmount

Also checked · 3 more claims, all matched observations

Checked Budget read from agent field 8
Checked No budget or no commit: no trim
Checked fstrim failure only logs

Proof on f36ea7dd

View full Proof report

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