Repository navigation
Conversation
The jailed-socket fallback in ResolveProcessPID ran whenever no listener was bound to the socket path, including a plain socket file left behind by a dead VMM. Each such lookup then scanned every process's fds, and listing instances resolves one per stale socket, so a host with many dead VMMs spent seconds per list. Only take the fallback when the socket path is a link and a listener is bound to the link target's name at the root. Anything else reports ErrNoOwningProcess straight from /proc/net/unix, as before the jailer.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Since #560,
instances.liston a staging host with many dead VMMs takes ~2.5–3s at p50 (was ~130ms). Almost all of it ishydrate_ms. The jailer is off on every host, so this is the new jailed-socket fallback inResolveProcessPIDrunning for unjailed VMs.A VMM that dies can leave its control socket file behind. List hydration calls
refreshHypervisorPIDfor those instances, which callsResolveProcessPID. Before #560 that returnedErrNoOwningProcessafter one read of/proc/net/unix. #560 added a fallback for jailed VMMs that runs whenever no listener is bound to the socket path, so every stale socket now scans the fds of every process on the host.On the affected host: 38 of 72 VMM control sockets have no listener, the host runs ~1,450 processes, and each stale lookup costs ~100ms. The slowest instance in every slow list was one of those stale sockets.
This takes the fallback only when it can apply:
/proc/net/unixis bound to the link target's name at the root (/api.sockfor a jailed firecracker).Otherwise it returns
ErrNoOwningProcessfrom/proc/net/unixalone, as before #560. When the fallback does run, it only checks listeners bound to that name instead of every listener with a path.Existing and new flows
Exact path matches (every live unjailed VMM) are unchanged.
Testing
TestResolveProcessPIDSkipsFDScanForStaleSocket: a stale plain socket file and a stale jailed link both returnErrNoOwningProcess, with a fake/procthat turns any fd scan into an error. It fails on main (inspect process fds: ... not a directory) and passes here.ResolveProcessPIDon a stale socket on a shared dev host with ~3,000 processes, 20 iterations each: 306ms/op on main, 5ms/op with this change.TestStandbySnapshotRestore(jailed and unjailed),TestJailedSocketOwners(two concurrent jailed VMs, each resolves to its own pid), and the jailed snapshot, restore and fork tests all pass.go test ./lib/hypervisor/: the resolver tests pass.TestSocketCacheKeyChangesWhenSocketIsRecreatedfails on my machine because the filesystem reuses inodes, andTestResolveProcessPIDDuringProcessChurnis flaky under parallel package runs (passes alone). Both fail the same way on main.Note
Medium Risk
Changes Linux socket PID resolution used during instance list hydration; live unjailed exact-path matches are unchanged, but jailed fallback preconditions are stricter.
Overview
Limits the jailed-VM socket owner fallback so stale control sockets no longer trigger a full
/procfd scan.socketMatcherForPathnow returnsErrNoOwningProcessimmediately when the path is not a symlink, or when no listener in/proc/net/unixis bound to/<link-target basename>. Only that symlink + live jailed-listener case keeps the fd scan, and matching useslistenersBoundTo(replacing a scan of all path-backed listeners) to narrow candidates.Adds
TestResolveProcessPIDSkipsFDScanForStaleSocketso dead unjailed sockets and stale jailed symlinks still reportErrNoOwningProcesswithout touching process fds.Reviewed by Cursor Bugbot for commit 365c27c. Configure here.