Skip to content

fix Linux daemon PID lookup without lsof - #3523

Open
koriyoshi2041 wants to merge 1 commit into
vectorize-io:mainfrom
koriyoshi2041:fix/linux-port-pid-fallback
Open

fix Linux daemon PID lookup without lsof#3523
koriyoshi2041 wants to merge 1 commit into
vectorize-io:mainfrom
koriyoshi2041:fix/linux-port-pid-fallback

Conversation

@koriyoshi2041

@koriyoshi2041 koriyoshi2041 commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Complements #3585 for minimal Linux images where neither lsof nor ss is installed.

PID discovery now falls back to procfs: it finds listening TCP/TCP6 socket inodes for the target port in /proc/net, then resolves the owning process through /proc/<pid>/fd symlinks. Existing lsof and ss paths remain preferred.

Validation after rebasing onto current main:

  • uv run pytest tests/test_embed_manager.py -q — 28 passed
  • env -u HTTP_PROXY -u HTTPS_PROXY -u ALL_PROXY -u http_proxy -u https_proxy -u all_proxy NO_PROXY=127.0.0.1,localhost uv run pytest tests/ -q — 187 passed
  • uv run ruff check hindsight_embed tests — passed
  • uv run ruff format --check hindsight_embed tests — 22 files already formatted
  • git diff --check — passed

The proxy variables are removed for the full suite because the local environment points HTTPX at a SOCKS proxy without its optional socksio dependency; the first run otherwise produced 18 control-center transport setup failures unrelated to this patch.

@ebarkhordar ebarkhordar left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ran this against a real listener rather than the mocked subprocess.run, since CI's test-embed job is skipped on this PR (it is gated on has_secrets, which is false for a fork), so the new test has not executed upstream.

python:3.12-slim plus iproute2, lsof absent, a real socket bound to 127.0.0.1:9177, the package pip-installed from each side:

  • base 205e47b4: _find_pid_on_port(9177) returns None
  • head b69873f3: returns 342, which is the listener's own pid
  • tests/test_embed_manager.py at head: 22 passed

So the ss -H -ltnp "sport = :9177" argv is valid as written (iproute2 6.15.0), which the mocked test cannot show on its own.

One gap, not blocking. #3517 lists minimal containers next to CachyOS, and those often have neither binary. On stock python:3.12-slim (no lsof, no ss) head still returns None, and since #3171 a missing pid makes stop() return False rather than only log a warning. A stdlib fallback would cover that case with no new dependency: read /proc/net/tcp and /proc/net/tcp6 for the listening socket's inode (state 0A), then match it against the /proc/[0-9]*/fd/* symlinks. I tried that in a container with neither binary and it resolved the correct pid. Fine as a follow-up if you would rather keep this PR to the environment that was reported.

@koriyoshi2041

Copy link
Copy Markdown
Contributor Author

Added a stdlib /proc fallback in 80d75f5 for Linux systems with neither lsof nor ss. It matches LISTEN entries in /proc/net/tcp{,6} to /proc/<pid>/fd socket inodes; focused embed-manager coverage is now 24/24, with source lint, format, and diff checks clean.

@koriyoshi2041
koriyoshi2041 force-pushed the fix/linux-port-pid-fallback branch from 80d75f5 to 6424947 Compare August 19, 2026 11:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants