mirror of
https://github.com/kvcache-ai/AgentENV.git
synced 2026-11-05 01:17:36 +00:00
[PR #110] [CLOSED] perf(network): skip empty egress programming on clean slots #186
Labels
No labels
bug
documentation
enhancement
enhancement
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
kvcache-ai/AgentENV#186
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/kvcache-ai/AgentENV/pull/110
Author: @cleverhu
Created: 8/3/2026
Status: ❌ Closed
Base:
main← Head:perf/skip-empty-egress📝 Commits (1)
a3f898bperf(network): skip empty egress programming on clean slots📊 Changes
1 file changed (+43 additions, -2 deletions)
View changed files
📝
src/sandbox/network/slot.rs(+43 -2)📄 Description
What
Skip the egress-policy apply when the requested policy is empty and the namespace's user egress chain is already empty. Slots track whether their chain currently holds rules so recycled slots are still cleared.
Why
set_egress_policyunconditionally spawns a thread, enters the sandbox network namespace, and runsiptables-restore. When a sandbox is started with no egress policy — the common case — that entire sequence programs an empty policy into an already empty chain: a no-op that still pays for a process spawn and a netns switch.On a sandbox start that otherwise hits every warm pool (network slot, block device, Firecracker), this is the single most expensive remaining step. Removing it takes the whole call to a couple of atomic loads.
Related issue
None. The change is local to one function and comes with unit tests.
Scope and non-goals
Included: the fast path plus the state tracking that makes it safe.
Excluded:
Design and behavior changes
Slotgainsuser_egress_rules_present: AtomicBool. A freshly created namespace starts with an empty chain, so it initializes tofalse.set_egress_policyreturns early only when both the requested policy has no runtime egress rules and the flag isfalse. Otherwise it takes the existing path and then storesresult.is_err() || wants_rules.The
is_err()term is deliberate: a failed apply may have flushed the chain and stopped partway, so the slot is assumed to hold rules. That is the conservative direction — the next tenant does a redundant clear rather than inheriting the previous tenant's rules.This matters because slots are recycled through the warm pool without their rules being cleared at release time. A recycled slot that held rules still gets cleared by the next tenant's empty policy.
Compatibility and operations
falseon restart, which matches a fresh namespace.Validation
make fmtmake clippymake test-unit(targeted; see below)make -C services test(required whenservices/changes)maketargetCommands and results:
Two tests are added:
empty_egress_policy_on_a_clean_slot_is_a_no_op— no namespace is ever created for the slot, so any path other than the fast one would fail entering it. Passing proves the fast path was taken.empty_egress_policy_still_clears_rules_a_previous_tenant_left— with the flag forced totrue, the call must be attempted (and therefore fail, since there is no namespace) rather than skipped.Skipped checks and reasons:
make test-unitnot run; only the two relevant tests plus a full--all-targetsbuild. The remaining phases need capabilities and a provisioned host.scripts/bench.py createon a warmed pool is the way to quantify it.Risks and reviewer notes
The correctness question is the state machine on
user_egress_rules_present, so please review that closely:falseis correct only if a new namespace really starts with an empty user egress chain.result.is_err() || wants_ruleserrs toward assuming rules exist. The cost of being wrong in that direction is a redundant clear; the cost in the other direction would be a leaked policy across tenants, which is a security issue.Slot, not being reset on release.The security-relevant scenario is a slot that held a restrictive policy being reused by a tenant with no policy. That is exactly the second test.
Most important file:
src/sandbox/network/slot.rs.Checklist
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.