Skip to content

fix(sandbox): keep serving through transient accept errors - #5211

Merged
FrostGod merged 2 commits into
NVIDIA:mainfrom
EmilienM:fix/5183-accept-transient-errors/EmilienM
Nov 5, 2026
Merged

FrostGod merged 2 commits into
NVIDIA:mainfrom
EmilienM:fix/5183-accept-transient-errors/EmilienM

Conversation

@EmilienM

@EmilienM EmilienM commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Two accept loops in the sandbox treated any unexpected accept error as fatal. The boundary control listener ended the whole boundary on EMFILE-class errors, and the DNS TCP relay stopped serving TCP DNS on any error, including a peer that reset before its accept completed. Both loops now classify accept errors and keep serving through the transient ones.

Related Issue

Closes #5183

Changes

  • New accept_errors module in openshell-sandbox classifying accept errors: transient resource exhaustion (EMFILE, ENFILE, ENOBUFS, ENOMEM), peers that reset before they could be served, and the already-pending network errors Linux reports from accept(2) (ENETDOWN, EPROTO, EHOSTUNREACH, and friends) that the man page says to treat like EAGAIN
  • The boundary control listener retries resource errors with a 50 ms backoff and only ends the boundary on unrecoverable errors
  • The DNS TCP relay skips reset peers and pending network errors, backs off on resource errors, and emits an OCSF detection finding if it ever has to stop
  • Resource-exhaustion warnings are bounded: one line when an episode starts, then at most one per 30 s

Release Notes

A sandbox no longer exits when its control listener hits a transient accept error such as EMFILE, and DNS over TCP keeps working after a client resets its connection before it is accepted.

Testing

  • cargo clippy --locked -p openshell-sandbox --all-targets -- -D warnings
  • cargo fmt --all -- --check
  • cargo nextest run --locked -p openshell-sandbox (303 tests pass)
  • Unit tests added: accept-error classification tables, a real-EMFILE end-to-end test that drives serve through descriptor exhaustion with a queued control connection and asserts it serves again after recovery, and DNS relay tests that inject EMFILE and a reset-before-peer_addr and assert a query still round-trips
  • E2E tests: not applicable, accept-loop error handling is covered by the injected-error unit tests above; existing CI lanes cover the unchanged happy paths

Checklist

  • Follows Conventional Commits
  • Commits are signed off (DCO)
  • Architecture docs updated: not applicable

@copy-pr-bot

copy-pr-bot Bot commented Nov 3, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@EmilienM
EmilienM marked this pull request as ready for review November 3, 2026 16:12
@FrostGod

FrostGod commented Nov 3, 2026

Copy link
Copy Markdown
Collaborator

/ok to test c08b0ae

@FrostGod

FrostGod commented Nov 4, 2026

Copy link
Copy Markdown
Collaborator

/ok to test 7d00562

@mrunalp mrunalp added area:sandbox Sandbox runtime and isolation work test:e2e Requires end-to-end coverage labels Nov 4, 2026
@github-actions

github-actions Bot commented Nov 4, 2026

Copy link
Copy Markdown

Label test:e2e applied for 7d00562. Open the existing run and click Re-run all jobs to execute with the label set. The run will execute the standard E2E suite after building the required gateway, sandbox, and supervisor images once. The matching required CI gate status on this PR will flip green automatically once the run finishes.

@mrunalp

mrunalp commented Nov 4, 2026

Copy link
Copy Markdown
Collaborator

/ok to test 7d00562

@FrostGod FrostGod added the test:e2e-kubernetes Requires Kubernetes end-to-end coverage label Nov 4, 2026
@github-actions

github-actions Bot commented Nov 4, 2026

Copy link
Copy Markdown

Label test:e2e-kubernetes applied for 7d00562. Open the existing run and click Re-run all jobs to execute with the label set. The run will execute Kubernetes HA and credential-driver E2E after building the required gateway, sandbox, and supervisor images once. This is an optional proof-of-life suite; failures are visible in the workflow run but do not publish a required CI gate status.

@FrostGod
FrostGod enabled auto-merge November 4, 2026 21:37
EmilienM and others added 2 commits November 4, 2026 21:04
The boundary control listener treated any accept error beyond the benign
kinds as fatal, so a transient EMFILE or ENFILE ended the boundary and the
sandbox with it. The DNS TCP relay broke out of its accept loop on any
error at all, including a connection that reset before accept, which
silently disabled TCP DNS for the rest of the sandbox's life.

Classify accept errors in a shared accept_errors module: EMFILE, ENFILE,
ENOBUFS and ENOMEM are transient resource exhaustion, and ConnectionReset,
ConnectionAborted and NotConnected mark a peer that disappeared before its
connection could be served. The control listener now retries resource
errors with a short backoff and a warning, and only unrecoverable errors
end the boundary. The DNS TCP relay skips reset peers, retries resource
errors with the same backoff, and logs before stopping on an unrecoverable
error instead of stopping silently.

Unit tests inject these errors into both classification paths, and a
loop-level test drives the DNS TCP relay through an EMFILE and a
reset-before-accept before serving a real query, then stops it on an
unrecoverable error.

Closes NVIDIA#5183

Signed-off-by: Emilien Macchi <emacchi@redhat.com>
Signed-off-by: divesh <dgude@nvidia.com>
auto-merge was automatically disabled November 5, 2026 02:10

Head branch was pushed to by a user without write access

@EmilienM
EmilienM force-pushed the fix/5183-accept-transient-errors/EmilienM branch from 7d00562 to 16d64f7 Compare November 5, 2026 02:10
@FrostGod
FrostGod enabled auto-merge November 5, 2026 05:58
@FrostGod

FrostGod commented Nov 5, 2026

Copy link
Copy Markdown
Collaborator

/ok to test 16d64f7

@FrostGod
FrostGod added this pull request to the merge queue Nov 5, 2026
Merged via the queue into NVIDIA:main with commit 10ace4f Nov 5, 2026
142 of 150 checks passed
@FrostGod
FrostGod deleted the fix/5183-accept-transient-errors/EmilienM branch November 5, 2026 07:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:sandbox Sandbox runtime and isolation work test:e2e Requires end-to-end coverage test:e2e-kubernetes Requires Kubernetes end-to-end coverage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: a transient accept error ends the boundary control listener or the DNS TCP relay

3 participants