Synchronize stopped supervisor composition checks

This commit is contained in:
ms2k 2026-07-17 15:04:59 +09:00
commit 19c8ca6523

View file

@ -16,7 +16,7 @@ use lazaret_core::configuration::{
}; };
use lazaret_core::identity::{ use lazaret_core::identity::{
BundleDigest, ClientId, ContainerId, CoordinatorId, GenerationId, HostPath, NetworkSidecarId, BundleDigest, ClientId, ContainerId, CoordinatorId, GenerationId, HostPath, NetworkSidecarId,
SandboxId, SessionAnchorId, SessionId, PidfsProcessIdentityV1, SandboxId, SessionAnchorId, SessionId,
}; };
use lazaret_core::network::{DnsQueryExpectation, ReachabilityExpectation, derive_ipv4_policy}; use lazaret_core::network::{DnsQueryExpectation, ReachabilityExpectation, derive_ipv4_policy};
use lazaret_core::records::{ use lazaret_core::records::{
@ -36,7 +36,8 @@ use lazaret_host_coordinator::terminal::{
use lazaret_linux::filesystem::{current_mount_identity, try_exclusive_flock}; use lazaret_linux::filesystem::{current_mount_identity, try_exclusive_flock};
use lazaret_linux::platform::{PlatformObservation, check_platform}; use lazaret_linux::platform::{PlatformObservation, check_platform};
use lazaret_linux::process::{ use lazaret_linux::process::{
ProcessOwnershipContext, RetainedProcess, TargetCommand, child_broker, current_process_identity, ProcessOwnershipContext, RetainedProcess, TargetCommand, child_broker,
current_process_identity, read_start_time,
}; };
use lazaret_runtime_supervisor::network::{DnsProbeTarget, NetworkProbeRequest, TcpProbeTarget}; use lazaret_runtime_supervisor::network::{DnsProbeTarget, NetworkProbeRequest, TcpProbeTarget};
use lazaret_runtime_supervisor::sandbox::{ use lazaret_runtime_supervisor::sandbox::{
@ -605,19 +606,21 @@ fn normal_stop_and_stop_resume() -> Result<(), MatrixError> {
.signal_attached_runsc(AttachedRunscSignal::Stop) .signal_attached_runsc(AttachedRunscSignal::Stop)
.map_err(failure)?; .map_err(failure)?;
thread::sleep(Duration::from_millis(50)); thread::sleep(Duration::from_millis(50));
let stopped_runsc_size = fs::metadata(&fixture.activity)?.len();
runtime runtime
.signal_attached_runsc(AttachedRunscSignal::Continue) .signal_attached_runsc(AttachedRunscSignal::Continue)
.map_err(failure)?; .map_err(failure)?;
wait_for_activity_growth(&fixture.activity, stopped_runsc_size)?;
let supervisor = runtime
.runtime_supervisor_identity()
.ok_or_else(|| failure("Runtime Supervisor identity is absent"))?;
runtime runtime
.signal_runtime_supervisor(Signal::STOP) .signal_runtime_supervisor(Signal::STOP)
.map_err(failure)?; .map_err(failure)?;
wait_for_process_stop(supervisor)?;
let stopped_size = fs::metadata(&fixture.activity)?.len(); let stopped_size = fs::metadata(&fixture.activity)?.len();
thread::sleep(Duration::from_millis(50)); wait_for_activity_growth(&fixture.activity, stopped_size)
if fs::metadata(&fixture.activity)?.len() <= stopped_size { .map_err(|_| failure("stopped Runtime Supervisor incorrectly stopped a present sandbox"))?;
return Err(failure(
"stopped Runtime Supervisor incorrectly stopped a present sandbox",
));
}
runtime runtime
.signal_runtime_supervisor(Signal::CONT) .signal_runtime_supervisor(Signal::CONT)
.map_err(failure)?; .map_err(failure)?;
@ -783,6 +786,40 @@ fn wait_for_activity(path: &Path) -> Result<(), MatrixError> {
Err(failure("guest activity did not start")) Err(failure("guest activity did not start"))
} }
fn wait_for_activity_growth(path: &Path, previous_size: u64) -> Result<(), MatrixError> {
for _ in 0..400 {
if path
.metadata()
.is_ok_and(|metadata| metadata.len() > previous_size)
{
return Ok(());
}
thread::sleep(Duration::from_millis(5));
}
Err(failure("guest activity did not advance"))
}
fn wait_for_process_stop(identity: PidfsProcessIdentityV1) -> Result<(), MatrixError> {
let host_pid = identity.host_pid().get();
for _ in 0..400 {
if read_start_time(host_pid)? != identity.start_time_ticks().get() {
return Err(failure(
"Runtime Supervisor identity changed while observing stop",
));
}
let stat = fs::read_to_string(format!("/proc/{host_pid}/stat"))?;
let state = stat
.rsplit_once(") ")
.and_then(|(_, suffix)| suffix.as_bytes().first())
.copied();
if state == Some(b'T') {
return Ok(());
}
thread::sleep(Duration::from_millis(5));
}
Err(failure("Runtime Supervisor did not reach stopped state"))
}
fn assert_activity_stable(path: &Path) -> Result<(), MatrixError> { fn assert_activity_stable(path: &Path) -> Result<(), MatrixError> {
let before = fs::metadata(path)?.len(); let before = fs::metadata(path)?.len();
thread::sleep(Duration::from_millis(100)); thread::sleep(Duration::from_millis(100));