runtime-rs: return hypervisor PID from container manager methods

Docker and containerd use the PID returned by the shim to construct
`/proc/<pid>/ns/net` for network namespace operations.  The Rust shim
was returning the shim's own PID instead of the hypervisor's PID,
which meant Docker would look at the wrong network namespace.

Update `create_container`, `start_process`, `state_process`, `pid`,
and `connect_container` to return the VMM master thread/process ID
(`vmm_master_tid`) instead of `self.pid`.  For QEMU this is the QEMU
process PID; for Dragonball this is the VMM thread ID — both are
valid for `/proc/<id>/ns/net` on Linux.

Fixes: #9340

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
Made-with: Cursor
This commit is contained in:
Fabiano Fidêncio
2026-04-22 18:04:12 +02:00
parent b1393f03c4
commit 3ad2de584f

View File

@@ -24,7 +24,7 @@ use oci::Process as OCIProcess;
use oci_spec::runtime as oci;
use resource::ResourceManager;
use runtime_spec as spec;
use tokio::sync::RwLock;
use tokio::sync::{OnceCell, RwLock};
use tracing::instrument;
use kata_sys_util::{hooks::HookStates, netns::NetnsGuard};
@@ -40,6 +40,7 @@ pub struct VirtContainerManager {
resource_manager: Arc<ResourceManager>,
agent: Arc<dyn Agent>,
hypervisor: Arc<dyn Hypervisor>,
vmm_master_tid: OnceCell<u32>,
}
impl std::fmt::Debug for VirtContainerManager {
@@ -73,16 +74,26 @@ impl VirtContainerManager {
resource_manager,
agent,
hypervisor,
vmm_master_tid: OnceCell::new(),
}
}
async fn get_vmm_master_tid(&self) -> Result<u32> {
self.vmm_master_tid
.get_or_try_init(|| self.hypervisor.get_vmm_master_tid())
.await
.copied()
}
}
#[async_trait]
impl ContainerManager for VirtContainerManager {
#[instrument]
async fn create_container(&self, config: ContainerConfig, spec: oci::Spec) -> Result<PID> {
let vmm_master_tid = self.get_vmm_master_tid().await?;
let mut container = Container::new(
self.pid,
vmm_master_tid,
config.clone(),
spec.clone(),
self.agent.clone(),
@@ -96,7 +107,6 @@ impl ContainerManager for VirtContainerManager {
// * should be run in vmm namespace (hook path in runtime namespace)
// * should be run after the vm is started, before container is created, and after CreateRuntime Hooks
// * spec details: https://github.com/opencontainers/runtime-spec/blob/c1662686cff159595277b79322d0272f5182941b/config.md#createcontainer-hooks
let vmm_master_tid = self.hypervisor.get_vmm_master_tid().await?;
let vmm_ns_path = self.hypervisor.get_ns_path().await?;
let vmm_netns_path = format!("{}/{}", vmm_ns_path, "net");
let state = spec::State {
@@ -128,7 +138,9 @@ impl ContainerManager for VirtContainerManager {
}
containers.insert(container.container_id.to_string(), container);
Ok(PID { pid: self.pid })
Ok(PID {
pid: vmm_master_tid,
})
}
#[instrument]
@@ -159,11 +171,12 @@ impl ContainerManager for VirtContainerManager {
// * spec details: https://github.com/opencontainers/runtime-spec/blob/c1662686cff159595277b79322d0272f5182941b/config.md#poststop
let c_spec = c.spec().await;
let vmm_pid = self.get_vmm_master_tid().await?;
let state = spec::State {
version: c_spec.version().clone(),
id: c.container_id.to_string(),
status: spec::ContainerState::Stopped,
pid: self.pid as i32,
pid: vmm_pid as i32,
bundle: c.config().await.bundle,
annotations: c_spec.annotations().clone().unwrap_or_default(),
};
@@ -329,7 +342,7 @@ impl ContainerManager for VirtContainerManager {
// * should be run after user-specific command is executed but before start operation returns
// * spec details: https://github.com/opencontainers/runtime-spec/blob/c1662686cff159595277b79322d0272f5182941b/config.md#poststart
let c_spec = c.spec().await;
let vmm_master_tid = self.hypervisor.get_vmm_master_tid().await?;
let vmm_master_tid = self.get_vmm_master_tid().await?;
let state = spec::State {
version: c_spec.version().clone(),
id: c.container_id.to_string(),
@@ -343,7 +356,9 @@ impl ContainerManager for VirtContainerManager {
poststart_hook_states.execute_hooks(from_hooks(hooks.poststart()), Some(state))?;
}
Ok(PID { pid: self.pid })
Ok(PID {
pid: vmm_master_tid,
})
}
#[instrument]
@@ -356,11 +371,11 @@ impl ContainerManager for VirtContainerManager {
if let Some(c) = containers.get(container_id) {
c.state_process(process).await.context("state process")
} else if container_id == &self.sid {
// Sandbox container state - return synthetic state
let vmm_pid = self.get_vmm_master_tid().await?;
Ok(ProcessStateInfo {
container_id: self.sid.clone(),
exec_id: String::new(),
pid: PID { pid: self.pid },
pid: PID { pid: vmm_pid },
bundle: String::new(),
stdin: None,
stdout: None,
@@ -433,12 +448,14 @@ impl ContainerManager for VirtContainerManager {
#[instrument]
async fn pid(&self) -> Result<PID> {
Ok(PID { pid: self.pid })
let vmm_pid = self.get_vmm_master_tid().await?;
Ok(PID { pid: vmm_pid })
}
#[instrument]
async fn connect_container(&self, _id: &ContainerID) -> Result<PID> {
Ok(PID { pid: self.pid })
let vmm_pid = self.get_vmm_master_tid().await?;
Ok(PID { pid: vmm_pid })
}
#[instrument]