def configured_observe_roots(): roots = config_list(MEMORY_CONFIG, "observeStateRoots", config_list(MEMORY_CONFIG, "webObserveRoots", [])) return [os.path.abspath(item) for item in roots if isinstance(item, str) and item.startswith("/")] def is_direct_observe_run_path(path): resolved = os.path.abspath(path) for root in configured_observe_roots(): if os.path.dirname(resolved) == root and resolved.startswith(root.rstrip("/") + "/"): return True return False def path_has_open_fd(path): resolved = os.path.realpath(path) prefix = resolved.rstrip("/") + "/" proc_root = "/proc" try: pids = [name for name in os.listdir(proc_root) if name.isdigit()] except OSError: return True for pid in pids: base = os.path.join(proc_root, pid) for name in ["cwd", "root"]: try: target = os.path.realpath(os.readlink(os.path.join(base, name))) except OSError: continue if target == resolved or target.startswith(prefix): return True fd_dir = os.path.join(base, "fd") try: fds = os.listdir(fd_dir) except OSError: continue for fd in fds: try: target = os.path.realpath(os.readlink(os.path.join(fd_dir, fd))) except OSError: continue if target == resolved or target.startswith(prefix): return True return False def assert_web_observe_candidate(path): resolved = os.path.abspath(path) if not is_direct_observe_run_path(resolved): raise RuntimeError("refusing to remove web-observe path outside configured direct run roots: %s" % path) if os.path.islink(resolved) or not os.path.isdir(resolved): raise RuntimeError("refusing to remove non-directory or symlink web-observe path: %s" % path) stale_hours = config_float(MEMORY_CONFIG, "staleRunMaxAgeHours", 6.0, minimum=0.0) record = observe_run_record(resolved, stale_hours) if record.get("pidAlive"): raise RuntimeError("refusing to remove active web-observe run with live pid: %s" % path) if not record.get("staleSignal"): raise RuntimeError("refusing to remove web-observe run without stale signal: %s" % path) if path_has_open_fd(resolved): raise RuntimeError("refusing to remove web-observe run with open fd/cwd reference: %s" % path) return record