airvzxf / airvzxf/voxora

fix(hf): fs2 flock(2) silently no-ops on NFS / 9P / overlay-fs — headline invariant of #185 broken

Open
#209 0 comments 0 reactions 0 assignees View on GitHub
bug epic pending-human security
Dominant language
Rust
Stars
0
Forks
1
Avg merge
11m
Merged PRs (30d)
77

Description

## Problem

`voxora-hf` was switched to `fs2 = "0.4"` in PR #207 / fix to #185. `fs2` invokes `libc::flock(fd, LOCK_EX | LOCK_NB)` directly (verified in the upstream `fs2-0.4.3/src/unix.rs:51-54`). The Linux `flock(2)` man page states: *"flock() does not work with NFS. Use fcntl(2) for NFS file locking."* Same deadness on 9P and partial deadness on overlay-fs.

The F1 headline — *"two concurrent resolves make exactly one set of HTTP requests"* — therefore fails in any non-local-FS deployment:

- Two voxora CLI processes on an NFS-mounted cache root each take a local-only flock.
- Both proceed past `acquire_lock` (`try_lock_exclusive` returns `Ok`) and both walk the slow path.
- Bandwidth doubles (or worse). Quietly — Linux logs nothing on this degradation.

Other targets affected:
- 9P / virtio-fs: `ENOSYS` or silently no-op depending on the daemon.
- overlay-fs: depends on backing filesystem; CI's `runs-on: ubuntu-latest` is local so this never surfaces in PR CI.

## Recipe

Replace `fs2` with a Linux-OFD lock via `fcntl(F_OFD_SETLK)`. Wrap the libc calls in a thin safe module (the crate already has the precedent at `voxora-local/src/source.rs:268-275` for `O_NOFOLLOW`). The `unsafe` stays inside `voxora-hf` but the `#![forbid(unsafe_code)]` at `voxora-hf/src/lib.rs:1` still bites — promote the lock primitive to a new private module with `#![allow(unsafe_code)]` scoped to the lock file, OR use a maintained crate that exposes `fcntl(F_OFD_SETLK)` safely.

`fs2` removal also deletes the `LIBNAME` shim it pulled in (verified: `fs2` adds `libc` + `windows-sys` to `Cargo.lock`; the former was already present transitively).

Document the supported filesystems in `voxora-hf/src/cache.rs::acquire_lock` rustdoc ("local ext4 / xfs / tmpfs; not NFS / 9P / overlay-fs"). On unsupported mounts the implementation should fall back to a path-based `tokio::sync::Mutex` keyed by `cache::model_dir`, so the worst-case on NFS is "advisory serialisation through user-space" rather than silent corruption.

## Acceptance

- A new integration test mounts a 9P filesystem (the kernel source tree's tests/ subdir is a convenient 9P source for Linux runners; CI can be skipped on this leg) and asserts that two concurrent `HuggingFaceSource::resolve` calls make exactly one set of HTTP requests.
- The current `voxora-hf/tests/wiremock_concurrency.rs::parallel_resolves_complete_without_corruption` test still passes on ext4 with `expect(1)` budgets.
- The `fs2` dependency is removed from `voxora-hf/Cargo.toml`; `Cargo.lock` no longer carries the `fs2` package entry.

## Cross-references

Found during the F2 sweep after PR #207 landed. Member of EPIC #206.

Contributor guide

Open the contributing guide

Research direction

Start with voxora-hf/src/cache.rs::acquire_lock, voxora-hf/src/lib.rs, and the O_NOFOLLOW precedent in voxora-local/src/source.rs:268-275. Read and run voxora-hf/tests/wiremock_concurrency.rs::parallel_resolves_complete_without_corruption before investigating the 9P integration-test setup. Done means concurrent resolves serialize on supported and unsupported filesystems, fs2 is removed, and the existing ext4 test and acceptance checks pass.

Written by the indexing model from the issue text.

Assessment

Tech stack
linux, rust
Domain
cli, operating-systems, testing
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.