diff --git a/crates/runc-shim/src/container.rs b/crates/runc-shim/src/container.rs index 1c38d1bb..bf1d3f99 100644 --- a/crates/runc-shim/src/container.rs +++ b/crates/runc-shim/src/container.rs @@ -59,6 +59,7 @@ pub trait Container { async fn close_io(&mut self, exec_id: Option<&str>) -> Result<()>; async fn pause(&mut self) -> Result<()>; async fn resume(&mut self) -> Result<()>; + async fn init_state(&self) -> EnumOrUnknown; } #[async_trait] @@ -96,6 +97,11 @@ where E: Process + Send + Sync, P: ProcessFactory + Send + Sync, { + async fn init_state(&self) -> EnumOrUnknown { + // Default should be unknown + self.init.state().await.unwrap_or_default().status + } + async fn start(&mut self, exec_id: Option<&str>) -> Result { let process = self.get_mut_process(exec_id)?; process.start().await?; diff --git a/crates/runc-shim/src/task.rs b/crates/runc-shim/src/task.rs index 97e2e941..9679c3fc 100644 --- a/crates/runc-shim/src/task.rs +++ b/crates/runc-shim/src/task.rs @@ -30,10 +30,9 @@ use containerd_shim::{ PidsResponse, StatsRequest, StatsResponse, UpdateTaskRequest, }, events::task::{TaskCreate, TaskDelete, TaskExecAdded, TaskExecStarted, TaskIO, TaskStart}, - protobuf::MessageDyn, + protobuf::{EnumOrUnknown, MessageDyn}, shim_async::Task, - ttrpc, - ttrpc::r#async::TtrpcContext, + ttrpc::{self, r#async::TtrpcContext}, }, util::{convert_to_any, convert_to_timestamp, AsOption}, TtrpcResult, @@ -228,6 +227,15 @@ where async fn start(&self, _ctx: &TtrpcContext, req: StartRequest) -> TtrpcResult { info!("Start request for {:?}", &req); let mut container = self.container_mut(req.id()).await?; + // Prevent the init process from exiting and continuing with start + // Return early to reduce the time it takes to return only when runc encounters an error + if container.init_state().await == EnumOrUnknown::new(Status::STOPPED) { + debug!("container init process has exited, start process should not continue"); + return Err(ttrpc::Error::RpcStatus(ttrpc::get_status( + ttrpc::Code::FAILED_PRECONDITION, + format!("container init process has exited {}", container.id().await), + ))); + } let pid = container.start(req.exec_id.as_str().as_option()).await?; let mut resp = StartResponse::new();