fix(state): tolerate closed WAL scan descriptors
(cherry picked from commit 299f91bb0c235cd002510034f77c2e627b3985e6)
This commit is contained in:
@@ -165,6 +165,10 @@ def _fd_is_truly_unlinked(fd_path: str, watched_path: str) -> bool:
|
||||
names — the guard keeps failing closed."""
|
||||
try:
|
||||
fd_stat = os.stat(fd_path)
|
||||
except FileNotFoundError:
|
||||
# The descriptor was closed after /proc was read. It cannot keep a
|
||||
# retired generation alive, so do not turn this scan race into a halt.
|
||||
return False
|
||||
except OSError:
|
||||
return True
|
||||
return _identity_is_truly_unlinked((fd_stat.st_dev, fd_stat.st_ino), watched_path)
|
||||
|
||||
@@ -160,6 +160,22 @@ def test_iter_holders_ignores_live_unhashed_dentry(tmp_path, force_wal, monkeypa
|
||||
db.close()
|
||||
|
||||
|
||||
def test_iter_holders_ignores_descriptor_closed_during_scan(tmp_path, monkeypatch):
|
||||
"""A descriptor gone after ``readlink`` cannot hold a retired generation."""
|
||||
path = tmp_path / "state.db"
|
||||
wal = Path(str(path) + "-wal")
|
||||
wal.write_bytes(b"current generation")
|
||||
vanished_fd = tmp_path / "closed-writable-opener-fd"
|
||||
monkeypatch.setattr(hermes_state_dbfile.sys, "platform", "linux")
|
||||
monkeypatch.setattr(
|
||||
hermes_state_dbfile,
|
||||
"_iter_proc_fd_targets",
|
||||
lambda: iter([(os.getpid(), str(wal) + " (deleted)", str(vanished_fd))]),
|
||||
)
|
||||
|
||||
assert iter_deleted_sqlite_sidecar_holders(path) == []
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
not sys.platform.startswith("linux"),
|
||||
reason="deleted-WAL write halt uses Linux unlink semantics",
|
||||
|
||||
Reference in New Issue
Block a user