Require fresh State Anchor absence before lease release

This commit is contained in:
ms2k 2026-07-17 04:40:02 +09:00
commit 3b76b59bdf

View file

@ -26,7 +26,10 @@ use crate::lifecycle::{
SessionLifecycleAdapter,
};
use crate::network::NetworkCoordinator;
use crate::runtime::{AwaitingAttachedRunsc, CommittedSandboxRuntime, SandboxCoordinator};
use crate::runtime::{
AwaitingAttachedRunsc, CommittedSandboxRuntime, SandboxCoordinator,
StateAnchorAbsenceObservation,
};
use crate::state_anchor::{StateAnchorCoordinator, StateAnchorReleaseAuthority};
#[derive(Debug)]
@ -80,6 +83,7 @@ pub struct ProductionLifecycleAdapter<'a> {
runtime: Option<CommittedSandboxRuntime>,
state_anchor_mount: Option<MountIdentity>,
state_anchor_release: Option<StateAnchorReleaseAuthority>,
state_anchor_absence: Option<StateAnchorAbsenceObservation>,
}
pub type ProductionHostCoordinatorLifecycle<'store, 'resources> = HostCoordinatorLifecycle<
@ -175,6 +179,7 @@ impl<'a> ProductionLifecycleAdapter<'a> {
runtime: None,
state_anchor_mount: None,
state_anchor_release: None,
state_anchor_absence: None,
},
ProductionSessionRegistry { registry },
)
@ -409,18 +414,26 @@ impl<'a> ProductionLifecycleAdapter<'a> {
)
.map_err(failure)?,
);
self.runtime
let runtime = self
.runtime
.as_mut()
.ok_or_else(|| ProductionLifecycleError("committed runtime is absent".into()))?
.unmount_state_anchor(
self.state_anchor_release
.as_ref()
.ok_or_else(|| {
ProductionLifecycleError("State Anchor release is absent".into())
})?
.mount(),
)
.ok_or_else(|| ProductionLifecycleError("committed runtime is absent".into()))?;
let release = self
.state_anchor_release
.as_ref()
.ok_or_else(|| ProductionLifecycleError("State Anchor release is absent".into()))?;
runtime
.unmount_state_anchor(release.mount())
.map_err(failure)?;
self.state_anchor_absence = Some(
runtime
.observe_state_anchor_absence(
release.user_namespace(),
release.mount_namespace(),
release.mount(),
)
.map_err(failure)?,
);
self.state_anchor_mount = None;
Ok(())
}
@ -428,11 +441,44 @@ impl<'a> ProductionLifecycleAdapter<'a> {
fn release_prepared_lower(&mut self) -> Result<(), ProductionLifecycleError> {
let release = self
.state_anchor_release
.take()
.as_ref()
.ok_or_else(|| ProductionLifecycleError("State Anchor release is absent".into()))?;
self.state_anchor()
.complete_release_after_unmount(&release, self.plan.state_anchor_layout)
.map_err(failure)
let first_observation = self.state_anchor_absence.ok_or_else(|| {
ProductionLifecycleError("State Anchor absence evidence is absent".into())
})?;
let runtime = self
.runtime
.as_mut()
.ok_or_else(|| ProductionLifecycleError("committed runtime is absent".into()))?;
let coordinator = StateAnchorCoordinator::new(&self.plan.store, self.plan.catalog);
coordinator
.complete_release_after_unmount(
release,
self.plan.state_anchor_layout,
first_observation,
|| {
runtime
.observe_state_anchor_absence(
release.user_namespace(),
release.mount_namespace(),
release.mount(),
)
.map_err(|error| {
crate::state_anchor::StateAnchorCoordinatorError::InvalidState(
match error {
crate::runtime::SandboxCoordinatorError::InvalidState(
detail,
) => detail,
_ => "Runtime Supervisor absence observation failed",
},
)
})
},
)
.map_err(failure)?;
self.state_anchor_release = None;
self.state_anchor_absence = None;
Ok(())
}
fn graceful_exit(&mut self) -> Result<(), ProductionLifecycleError> {