From f16012a1eb8665e85b08f129b8fffc14d1ee733b Mon Sep 17 00:00:00 2001 From: Zhongtao Hu Date: Thu, 11 May 2023 10:53:07 +0800 Subject: [PATCH] runtime-rs: support linux device support linux device in runtime-rs Fixes:#5375 Signed-off-by: Zhongtao Hu Signed-off-by: alex.lyn --- .../hypervisor/src/device/device_manager.rs | 4 +- src/runtime-rs/crates/resource/src/manager.rs | 8 ++- .../crates/resource/src/manager_inner.rs | 63 +++++++++++++++++-- .../src/container_manager/container.rs | 11 +++- 4 files changed, 78 insertions(+), 8 deletions(-) diff --git a/src/runtime-rs/crates/hypervisor/src/device/device_manager.rs b/src/runtime-rs/crates/hypervisor/src/device/device_manager.rs index cdce8956b1..6d9325d398 100644 --- a/src/runtime-rs/crates/hypervisor/src/device/device_manager.rs +++ b/src/runtime-rs/crates/hypervisor/src/device/device_manager.rs @@ -76,10 +76,10 @@ impl DeviceManager { } pub async fn new_device(&mut self, device_config: &DeviceConfig) -> Result { - let device_id = if let Some(dev) = self.find_device(&device_config).await { + let device_id = if let Some(dev) = self.find_device(device_config).await { dev } else { - self.create_device(&device_config) + self.create_device(device_config) .await .context("failed to create device")? }; diff --git a/src/runtime-rs/crates/resource/src/manager.rs b/src/runtime-rs/crates/resource/src/manager.rs index 9514b60138..34753b7d58 100644 --- a/src/runtime-rs/crates/resource/src/manager.rs +++ b/src/runtime-rs/crates/resource/src/manager.rs @@ -7,13 +7,14 @@ use crate::network::NetworkConfig; use crate::resource_persist::ResourceState; use crate::{manager_inner::ResourceManagerInner, rootfs::Rootfs, volume::Volume, ResourceConfig}; +use agent::types::Device; use agent::{Agent, Storage}; use anyhow::Result; use async_trait::async_trait; use hypervisor::Hypervisor; use kata_types::config::TomlConfig; use kata_types::mount::Mount; -use oci::LinuxResources; +use oci::{Linux, LinuxResources}; use persist::sandbox_persist::Persist; use std::sync::Arc; use tokio::sync::RwLock; @@ -93,6 +94,11 @@ impl ResourceManager { inner.handler_volumes(cid, spec).await } + pub async fn handler_devices(&self, cid: &str, linux: &Linux) -> Result> { + let inner = self.inner.read().await; + inner.handler_devices(cid, linux).await + } + pub async fn dump(&self) { let inner = self.inner.read().await; inner.dump().await diff --git a/src/runtime-rs/crates/resource/src/manager_inner.rs b/src/runtime-rs/crates/resource/src/manager_inner.rs index e76fa4eb6e..1698568750 100644 --- a/src/runtime-rs/crates/resource/src/manager_inner.rs +++ b/src/runtime-rs/crates/resource/src/manager_inner.rs @@ -4,16 +4,16 @@ // SPDX-License-Identifier: Apache-2.0 // -use std::{sync::Arc, thread}; +use std::{sync::Arc, thread, vec}; use crate::{network::NetworkConfig, resource_persist::ResourceState}; -use agent::{Agent, Storage}; +use agent::{types::Device, Agent, Storage}; use anyhow::{anyhow, Context, Ok, Result}; use async_trait::async_trait; -use hypervisor::{device::device_manager::DeviceManager, Hypervisor}; +use hypervisor::{device::device_manager::DeviceManager, BlockConfig, DeviceConfig, Hypervisor}; use kata_types::config::TomlConfig; use kata_types::mount::Mount; -use oci::LinuxResources; +use oci::{Linux, LinuxResources}; use persist::sandbox_persist::Persist; use tokio::{runtime, sync::RwLock}; @@ -246,6 +246,61 @@ impl ResourceManagerInner { .await } + pub async fn handler_devices(&self, _cid: &str, linux: &Linux) -> Result> { + let mut devices = vec![]; + for d in linux.devices.iter() { + match d.r#type.as_str() { + "b" => { + let device_info = DeviceConfig::Block(BlockConfig { + major: d.major, + minor: d.minor, + ..Default::default() + }); + let device_id = self + .device_manager + .write() + .await + .new_device(&device_info) + .await + .context("failed to create deviec")?; + + self.device_manager + .write() + .await + .try_add_device(&device_id) + .await + .context("failed to add deivce")?; + + // get complete device information + let dev_info = self + .device_manager + .read() + .await + .get_device_info(&device_id) + .await + .context("failed to get device info")?; + + // create agent device + if let DeviceConfig::Block(config) = dev_info { + let agent_device = Device { + id: device_id.clone(), + container_path: d.path.clone(), + field_type: config.driver_option, + vm_path: config.virt_path, + ..Default::default() + }; + devices.push(agent_device); + } + } + _ => { + // TODO enable other devices type + continue; + } + } + } + Ok(devices) + } + pub async fn update_cgroups( &self, cid: &str, diff --git a/src/runtime-rs/crates/runtimes/virt_container/src/container_manager/container.rs b/src/runtime-rs/crates/runtimes/virt_container/src/container_manager/container.rs index 2f9f03b0e8..94d75b8351 100644 --- a/src/runtime-rs/crates/runtimes/virt_container/src/container_manager/container.rs +++ b/src/runtime-rs/crates/runtimes/virt_container/src/container_manager/container.rs @@ -140,7 +140,15 @@ impl Container { } spec.mounts = oci_mounts; - // TODO: handler device + let linux = spec + .linux + .as_ref() + .context("OCI spec missing linux field")?; + + let devices_agent = self + .resource_manager + .handler_devices(&config.container_id, linux) + .await?; // update cgroups self.resource_manager @@ -158,6 +166,7 @@ impl Container { storages, oci: Some(spec), sandbox_pidns, + devices: devices_agent, ..Default::default() };