fix(driver-mxc): resolve StopSandbox by sandbox_id - #3278
Conversation
…rd checkup Signed-off-by: Artem Lytvyn <alytvyn@redhat.com>
sylvesterkaczmarek
left a comment
There was a problem hiding this comment.
The id/name validation happens before waiting on lifecycle_gate, but after the await the code only does registry.get_mut(sandbox_id) and does not verify it is still the entry whose gate/name was checked. A concurrent delete followed by recreation of the same id can therefore make this stop act on the replacement while holding the old entry’s gate. Could we revalidate the entry after acquiring the gate (including gate identity/name), and cover delete/recreate racing with stop?
…cle gate Signed-off-by: Artem Lytvyn <alytvyn@redhat.com>
sylvesterkaczmarek
left a comment
There was a problem hiding this comment.
Rechecked 1d4a5734. After waiting on the lifecycle gate, stop now revalidates that the registry entry still owns the same gate allocation before acting, and the delete/recreate regression covers reuse of the same sandbox id. This resolves the race I raised.
Summary
StopSandboxon the MXC driver discarded thesandbox_idthe gateway sends andresolved the target by name alone, over a registry that is shared across
workspaces. Because sandbox names are unique per workspace rather than globally,
a stop request could terminate a same-named sandbox in a different workspace,
chosen by hash iteration order. This makes
sandbox_idauthoritative for stop,matching the contract
DeleteSandboxalready enforces on the same driver.Related Issue
Fixes #3253
Changes
grpc.rs:StopSandboxnow rejects an emptysandbox_idwithInvalidArgumentand forwards both identifiers to the backend. This mirrors the existingDeleteSandboxvalidation and removes name-only resolution rather than making it deterministic, matching the Podman and Kubernetes drivers. The gateway already populatessandbox_idon every stop call site, so no supported caller is affected.driver.rs:MxcComputeBackend::stop_sandboxtakessandbox_idand resolves throughregistry.get(sandbox_id)instead of scanningvalues()for a name match, then returnsFailedPreconditionwhen the resolved entry's name disagrees. This is the same id-first lookup plus name guard thatdelete_sandboxalready uses. It also turns a linear scan into a hash lookup on the key the registry is already keyed by.driver_sandbox_namedhelper so a sandbox's id, name, and workspace can be set independently. The existing helper forcedname == id.to_string(), which made the whole class of id/name confusion bugs inexpressible in the suite. Addedsandbox_by_idandwait_for_idbecauseget_sandboxandwait_forresolve by name and cannot address an individual entry once two sandboxes share one.Audited
DeleteSandboxon this driver for the same weakness, per the issue's final acceptance criterion. It is already sound: id-first lookup with aFailedPreconditionname guard, and every subsequent operation keys onsandbox_id. No change needed.GetSandboxresolves by name but fails closed on an id mismatch, so it can return a wrong-workspace error but never mutates the wrong sandbox.StopSandboxwas the only handler with no id gate at all.Testing
mise run pre-commitpassesChecklist