Skip to content

test(pkg): expose revision-store lock inode race - #16171

Draft
Alizter wants to merge 1 commit into
ocaml:mainfrom
Alizter:repro/rev-store-lock-contention
Draft

test(pkg): expose revision-store lock inode race#16171
Alizter wants to merge 1 commit into
ocaml:mainfrom
Alizter:repro/rev-store-lock-contention

Conversation

@Alizter

@Alizter Alizter commented Aug 24, 2026

Copy link
Copy Markdown
Collaborator

Description

Add a Linux-only cram regression for the revision-store lock inode race.

Two dune pkg lock processes share a fresh cache. A fake git, FIFO barriers, and /proc/<pid>/fd deterministically queue the second process on the first process's lock inode, wait until the first owner has finished cleanup, and then hold the second process inside Rev_store.load_or_create. A third nonblocking flock on the canonical path must still contend with that owner.

All readiness and exit waits are bounded. Failure cleanup releases FIFO readers, kills, and reaps the spawned Dune processes. util-linux is added only to the Linux test environment to provide the external flock probe.

This is intentionally a test-only draft. The expected mutual-exclusion behavior remains in the cram, so the new test is red on main.

Current Failure

with_flock unlinks rev-store.lock before releasing its flock. The queued second process subsequently owns the unlinked original inode while the third process creates and locks a replacement inode at the canonical path, entering the revision-store critical section concurrently.

Related Issue and Motivation

#9140 added the revision-store lock to prevent concurrent processes from corrupting the shared bare repository. This test isolates an inode-lifetime hole in that locking contract before any production fix is proposed.

Verification

  • The new cram failed at the intended third-contender assertion in five consecutive local runs with byte-identical diagnostics.
  • nix develop path:. -c dune fmt passed.
  • nix develop path:. -c dune build @check passed.
  • Existing rev-store-lock-linux.t and rev-store-lock.t passed.

Checklist

  • Test added.
  • Changelog not applicable: test-only reproducer.
  • Documentation not applicable: test-only reproducer.

@Alizter
Alizter force-pushed the repro/rev-store-lock-contention branch from e658e15 to 7987f25 Compare August 24, 2026 14:21
@Alizter Alizter changed the title test(pkg): expose revision-store lock inode race fix(pkg): keep revision-store lock file linked Aug 24, 2026
Add a Linux-only cram regression that drives two Dune package-lock processes through Rev_store.load_or_create with a shared fresh cache. A fake git and FIFO barriers deterministically queue the second process on the first process's lock inode, then hold it in rev-store validation. A third nonblocking contender verifies that the canonical lock path still refers to the held inode.

The correct mutual-exclusion expectation intentionally fails on main: with_flock unlinks rev-store.lock before unlocking it, so the queued second process holds an unlinked inode while the third process locks a new inode at the canonical path.

Signed-off-by: Ali Caglayan <alizter@gmail.com>
@Alizter
Alizter force-pushed the repro/rev-store-lock-contention branch from 7987f25 to ceac1d5 Compare August 24, 2026 15:47
@Alizter Alizter changed the title fix(pkg): keep revision-store lock file linked test(pkg): expose revision-store lock inode race Aug 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant