@@ -4,6 +4,7 @@ import (
4 "encoding/json"
4 "encoding/json"
8 "path/filepath"
9 "path/filepath"
@@ -63,13 +64,17 @@ func acquireDataDirLock(dataDir string) (*dataDirLock, error) {
63 // Record ownership metadata so a contending process can identify
64 // Record ownership metadata so a contending process can identify
64 // us. Failures here are non-fatal: the OS-level lock is what
65 // us. Failures here are non-fatal: the OS-level lock is what
65 // actually guarantees mutual exclusion, and a missing/partial JSON
66 // actually guarantees mutual exclusion, and a missing/partial JSON
66− // payload only degrades diagnostics.
67+ // payload only degrades the diagnostic a contender prints.
67 if err := writeOwnerInfo(path); err != nil {
68 if err := writeOwnerInfo(path); err != nil {
68− // Best-effort; log via stderr only when running in a debug
69+ slog.Debug("Failed to write data-dir owner info", "path", path, "error", err)
69− // context would be invasive here, so we silently swallow.
72+ // The lock file itself is intentionally never unlinked. flock is
73+ // keyed by inode, not by path, and any close-then-unlink (or
74+ // unlink-then-close) ordering opens a window where two processes
75+ // can each hold a flock on a different inode that lives at the
76+ // same path. Leaving the file in place lets every acquirer see
77+ // the same inode and lets the kernel arbitrate correctly.
73 return &dataDirLock{release: release}, nil
78 return &dataDirLock{release: release}, nil