Skip to content

Skip the process fd scan for a socket file with no listener - #565

Merged
yummybomb merged 1 commit into
mainfrom
hypeship/stale-socket-pid-scan
Nov 12, 2026
Merged

yummybomb merged 1 commit into
mainfrom
hypeship/stale-socket-pid-scan

Conversation

@yummybomb

@yummybomb yummybomb commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Resolving the PID behind a VMM control socket got slow for sockets whose VMM is gone but whose socket file is still on disk.

socketMatcherForPath first looks for a listener listed under the socket path in /proc/net/unix. When there is none and the file exists, it falls back to matching listeners by the file they are bound to inside each process's root, which is how a jailed firecracker is found. That fallback reads the fd table of every process. A socket file left behind by a dead VMM has no listener under its path either, so it takes the fallback and scans every process, only to report ErrNoOwningProcess. Instance hydration resolves the PID for such instances on every list and get, so a host with a few dozen stale sockets pays a full process scan per stale socket per list.

This probes the socket before the fallback: a refused connection proves no listener is bound to that file in any root, so the resolve returns ErrNoOwningProcess without scanning. A socket that accepts (a live jailed VMM), or a probe that fails for any other reason, still takes the fallback, so results are unchanged. The probe only runs when no listener is listed under the path, so resolving a live unjailed VMM does not connect to it.

Testing

  • TestResolveProcessPIDSkipsProcessScanForSocketWithoutListener: a socket file with no listener resolves to ErrNoOwningProcess against a fake /proc where a process scan would fail on an unreadable fd. It fails without the change.
  • The existing jailed-root test (TestResolveProcessPIDMatchesSocketInProcessRoot) still passes.
  • A local benchmark of ResolveProcessPID on a stale socket went from 2.2ms to 0.47ms per call on a machine with 185 processes, most of whose fd tables the test user cannot read; the gap grows with the number of processes.
  • lib/hypervisor: two tests fail locally with and without this change, TestSocketCacheKeyChangesWhenSocketIsRecreated and TestResolveProcessPIDDuringProcessChurn. Neither exercises the changed branch. The other lib/hypervisor/... packages pass.
  • lib/instances: 101 tests around process identity, stop, and delete give the same results with and without the change (two integration tests fail both ways for lack of root and mkfs.erofs).

Note

Low Risk
Linux-only optimization on a narrow code path; live listeners and jailed-root matching are unchanged unless the probe connects or errors for reasons other than ECONNREFUSED.

Overview
Speeds up PID resolution for stale VMM control sockets by probing the Unix socket before the expensive per-process fd scan.

When /proc/net/unix has no listener for the path but the socket file still exists, socketMatcherForPath now calls socketRefusesConnections (100ms DialTimeout). ECONNREFUSED is treated as proof nothing is listening, so resolution returns ErrNoOwningProcess without walking every process’s fds. Successful dials or non-refusal errors still use the existing jailed-root fallback, so live listeners behave as before.

Adds TestResolveProcessPIDSkipsProcessScanForSocketWithoutListener to ensure orphan socket files hit the fast path instead of failing during a full scan.

Reviewed by Cursor Bugbot for commit 94b042c. Bugbot is set up for automated code reviews on this repo. Configure here.

A socket file that no listener is listed under falls back to matching
listeners by the file they are bound to in each process's root, which
scans every process fd. A VMM that died without unlinking its socket
takes that path on every resolve. Probe the socket first: a refused
connection proves no listener is bound to the file in any root.
@yummybomb
yummybomb marked this pull request as ready for review November 12, 2026 22:15
@kernel-internal

Copy link
Copy Markdown
Contributor

Would auto-approve: no · medium risk · 94b042c

This changes core hypervisor PID resolution by actively connecting to control sockets and conditionally skipping ownership scans. Connection side effects and race behavior may affect live VMM lifecycle handling beyond what the focused test demonstrates.

Shadow mode: nothing is auto-approved and a human review is still required. React 👍 or 👎 if this call looks right or wrong.

@yummybomb
yummybomb requested a review from chruffins November 12, 2026 22:19

@chruffins chruffins 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.

lgtm

@yummybomb
yummybomb merged commit a4f70eb into main Nov 12, 2026
12 checks passed
@yummybomb
yummybomb deleted the hypeship/stale-socket-pid-scan branch November 12, 2026 22:26
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