fix(state): doctor's holder count enumerates macOS holders via libproc (#109641)
`count_db_holders` returned None on every non-Linux host, so `hermes doctor` on macOS (every reporter in the deleted-WAL cluster) printed no "N process(es) holding the DB open" row. The libproc enumeration that #110544 landed for the sidecar scan already yields `(pid, fd, path, (st_dev, st_ino))`; count distinct PIDs whose fd identity matches state.db's inode. Identity, not pathname: libproc reports the path as the opener spelled it (case, symlinked prefix), which is what the sidecar leg had to case-fold around. Carries the surviving delta from #110023 (@kshitijk4poor), whose libproc leg otherwise landed via #110544.
This commit is contained in:
+10
-4
@@ -765,13 +765,19 @@ def collect_state_db_stats(db_path: Path) -> Dict[str, Any]:
|
||||
|
||||
|
||||
def count_db_holders(db_path: Path) -> Optional[int]:
|
||||
"""Best-effort count of distinct PIDs holding ``db_path`` open (``/proc/*/fd`` scan); ``None``
|
||||
on any error or non-Linux host, never raises. Unreadable fd dirs (other users' processes
|
||||
without root) are skipped, so this is a lower bound."""
|
||||
"""Best-effort count of distinct PIDs holding ``db_path`` open (``/proc/*/fd`` on Linux, libproc
|
||||
on macOS); ``None`` on any error or other host, never raises. Uninspectable processes (other
|
||||
users' without root) are skipped, so this is a lower bound."""
|
||||
try:
|
||||
target = os.path.realpath(str(db_path))
|
||||
if sys.platform == "darwin":
|
||||
# Identity, not pathname: libproc reports the vnode's last name as the opener spelled it
|
||||
# (case, symlinked prefix), which is exactly what the sidecar leg had to case-fold around.
|
||||
st = os.stat(target)
|
||||
identity = (st.st_dev, st.st_ino)
|
||||
return len({pid for pid, _fd, _path, ident in _iter_darwin_fd_targets() if ident == identity})
|
||||
if not sys.platform.startswith("linux"):
|
||||
return None
|
||||
target = os.path.realpath(str(db_path))
|
||||
return len({pid for pid, link, _fd_path in _iter_proc_fd_targets() if link == target})
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
Reference in New Issue
Block a user