Hold a lock so a second scan fails at once (closes #53) #75

Merged
clawbot merged 1 commits from issue-53-scan-lock into next 2026-10-04 02:30:23 +02:00
Collaborator

scan now takes an exclusive flock(2) on a lock file beside the database (its path with .lock appended) after checking its operands, before walking anything or opening the database, and holds it until it returns. A second scan against the same database exits 1 with sfdupes: another scan is running (lock held on /var/lib/sfdupes/db.sqlite.lock). report and trees never touch the lock. golang.org/x/sys becomes a direct dependency; README.md §Constraints, §Database and §Error handling are updated.

Not obvious from the diff:

  • The lock file is never deleted, on purpose: deleting it would let a third scan lock a new file while the second still holds the old one.
  • The lock is released after the database is closed, so the switch out of WAL mode happens while it is still held.
  • lockScanDatabase creates the database directory because it runs before openScanDatabase, which still creates it for its other callers.

Disclosures:

  • Deviation: the README.md smoke test keeps the database in its own temp directory; inside the scanned tree its empty lock file would join the empty1/empty2 group.
  • Rule suppressed: gosec G304 on opening the lock file, whose path the operator sets.
  • Judgement call: lock file mode 0600, since anyone who can open it can block every scan.
  • Partially verified: with no signal handling, release on an interrupt relies on the operating system closing the file at exit; checked by hand, not by a test.

Model: opus-5-5

`scan` now takes an exclusive `flock(2)` on a lock file beside the database (its path with `.lock` appended) after checking its operands, before walking anything or opening the database, and holds it until it returns. A second `scan` against the same database exits 1 with `sfdupes: another scan is running (lock held on /var/lib/sfdupes/db.sqlite.lock)`. `report` and `trees` never touch the lock. `golang.org/x/sys` becomes a direct dependency; `README.md` §Constraints, §Database and §Error handling are updated. Not obvious from the diff: - The lock file is never deleted, on purpose: deleting it would let a third scan lock a new file while the second still holds the old one. - The lock is released after the database is closed, so the switch out of WAL mode happens while it is still held. - `lockScanDatabase` creates the database directory because it runs before `openScanDatabase`, which still creates it for its other callers. Disclosures: - Deviation: the `README.md` smoke test keeps the database in its own temp directory; inside the scanned tree its empty lock file would join the `empty1`/`empty2` group. - Rule suppressed: gosec G304 on opening the lock file, whose path the operator sets. - Judgement call: lock file mode 0600, since anyone who can open it can block every scan. - Partially verified: with no signal handling, release on an interrupt relies on the operating system closing the file at exit; checked by hand, not by a test. Model: opus-5-5
clawbot added the needs-review label 2026-10-04 01:57:07 +02:00
clawbot self-assigned this 2026-10-04 01:57:07 +02:00
clawbot added 1 commit 2026-10-04 01:57:08 +02:00
scan takes an exclusive flock(2) on a lock file beside the database
(its path with .lock appended) before it walks anything or opens the
database, and holds it until it returns. A second scan against the
same database fails at once with a one-line error naming the lock
file and exits 1. report and trees never take the lock. The lock ends
with the process, so a fatal error or an interrupt releases it; the
file is never deleted. golang.org/x/sys becomes a direct dependency.

The README smoke test now keeps the database outside the scanned
tree, where its empty lock file would have joined the empty-file
group.

Model: opus-5-5
Author
Collaborator

Review passed.

Model: opus-5-5

Review passed. Model: opus-5-5
clawbot merged commit 705c8729ca into next 2026-10-04 02:30:23 +02:00
clawbot deleted branch issue-53-scan-lock 2026-10-04 02:30:24 +02:00
Sign in to join this conversation.