runtime-rs: use device manager to handle vm rootfs

use device manager to handle vm rootfs, after attach the block device of
vm rootfs, we need to increase index number

Fixes: #7119
Signed-off-by: Zhongtao Hu <zhongtaohu.tim@linux.alibaba.com>
Signed-off-by: Chelsea Mafrica <chelsea.e.mafrica@intel.com>
Signed-off-by: James O. D. Hunt <james.o.hunt@intel.com>
This commit is contained in:
Zhongtao Hu 2023-06-20 14:27:51 +08:00
parent 20f1f62a2a
commit 5d6199f9bc
5 changed files with 54 additions and 60 deletions

View File

@ -7,13 +7,12 @@
use super::vmm_instance::VmmInstance; use super::vmm_instance::VmmInstance;
use crate::{ use crate::{
device::DeviceType, hypervisor_persist::HypervisorState, kernel_param::KernelParams, VmmState, device::DeviceType, hypervisor_persist::HypervisorState, kernel_param::KernelParams, VmmState,
DEV_HUGEPAGES, HUGETLBFS, HYPERVISOR_DRAGONBALL, SHMEM, VM_ROOTFS_DRIVER_BLK, DEV_HUGEPAGES, HUGETLBFS, HYPERVISOR_DRAGONBALL, SHMEM,
VM_ROOTFS_DRIVER_MMIO,
}; };
use anyhow::{anyhow, Context, Result}; use anyhow::{anyhow, Context, Result};
use async_trait::async_trait; use async_trait::async_trait;
use dragonball::{ use dragonball::{
api::v1::{BlockDeviceConfigInfo, BootSourceConfig, VcpuResizeInfo}, api::v1::{BootSourceConfig, VcpuResizeInfo},
vm::VmConfigInfo, vm::VmConfigInfo,
}; };
@ -25,7 +24,7 @@ use kata_types::{
use nix::mount::MsFlags; use nix::mount::MsFlags;
use persist::sandbox_persist::Persist; use persist::sandbox_persist::Persist;
use shim_interface::KATA_PATH; use shim_interface::KATA_PATH;
use std::{collections::HashSet, fs::create_dir_all, path::PathBuf}; use std::{collections::HashSet, fs::create_dir_all};
const DRAGONBALL_KERNEL: &str = "vmlinux"; const DRAGONBALL_KERNEL: &str = "vmlinux";
const DRAGONBALL_ROOT_FS: &str = "rootfs"; const DRAGONBALL_ROOT_FS: &str = "rootfs";
@ -122,22 +121,6 @@ impl DragonballInner {
) )
.context("set_boot_source")?; .context("set_boot_source")?;
// get vm rootfs
let image = {
let initrd_path = self.config.boot_info.initrd.clone();
let image_path = self.config.boot_info.image.clone();
if !initrd_path.is_empty() {
Ok(initrd_path)
} else if !image_path.is_empty() {
Ok(image_path)
} else {
Err(anyhow!("failed to get image"))
}
}
.context("get image")?;
self.set_vm_rootfs(&image, &rootfs_driver)
.context("set vm rootfs")?;
// add pending devices // add pending devices
while let Some(dev) = self.pending_devices.pop() { while let Some(dev) = self.pending_devices.pop() {
self.add_device(dev).await.context("add_device")?; self.add_device(dev).await.context("add_device")?;
@ -264,37 +247,6 @@ impl DragonballInner {
.context("put boot source") .context("put boot source")
} }
fn set_vm_rootfs(&mut self, path: &str, driver: &str) -> Result<()> {
info!(sl!(), "set vm rootfs {} {}", path, driver);
let jail_drive = self
.get_resource(path, DRAGONBALL_ROOT_FS)
.context("get resource")?;
if driver == VM_ROOTFS_DRIVER_BLK || driver == VM_ROOTFS_DRIVER_MMIO {
let blk_cfg = BlockDeviceConfigInfo {
path_on_host: PathBuf::from(jail_drive),
drive_id: DRAGONBALL_ROOT_FS.to_string(),
is_root_device: false,
// Add it as a regular block device
// This allows us to use a partitioned root block device
// is_read_only
is_read_only: true,
is_direct: false,
..Default::default()
};
self.vmm_instance
.insert_block_device(blk_cfg)
.context("inert block device")
} else {
Err(anyhow!(
"Unknown vm_rootfs driver {} path {:?}",
driver,
path
))
}
}
fn start_vmm_instance(&mut self) -> Result<()> { fn start_vmm_instance(&mut self) -> Result<()> {
info!(sl!(), "Starting VM"); info!(sl!(), "Starting VM");
self.vmm_instance self.vmm_instance

View File

@ -87,7 +87,7 @@ impl KernelParams {
params.push(Param::new("rootflags", "dax ro")); params.push(Param::new("rootflags", "dax ro"));
} }
_ => { _ => {
return Err(anyhow!("Unsupported rootfs type")); return Err(anyhow!("Unsupported rootfs type {}", rootfs_type));
} }
} }
} }
@ -101,12 +101,12 @@ impl KernelParams {
params.push(Param::new("rootflags", "ro")); params.push(Param::new("rootflags", "ro"));
} }
_ => { _ => {
return Err(anyhow!("Unsupported rootfs type")); return Err(anyhow!("Unsupported rootfs type {}", rootfs_type));
} }
} }
} }
_ => { _ => {
return Err(anyhow!("Unsupported rootfs driver")); return Err(anyhow!("Unsupported rootfs driver {}", rootfs_driver));
} }
} }
@ -310,7 +310,7 @@ mod tests {
] ]
.to_vec(), .to_vec(),
}, },
result: Err(anyhow!("Unsupported rootfs driver")), result: Err(anyhow!("Unsupported rootfs driver foo")),
}, },
// Unsupported rootfs type // Unsupported rootfs type
TestData { TestData {
@ -324,7 +324,7 @@ mod tests {
] ]
.to_vec(), .to_vec(),
}, },
result: Err(anyhow!("Unsupported rootfs type")), result: Err(anyhow!("Unsupported rootfs type foo")),
}, },
]; ];
@ -332,7 +332,6 @@ mod tests {
let msg = format!("test[{}]: {:?}", i, t); let msg = format!("test[{}]: {:?}", i, t);
let result = KernelParams::new_rootfs_kernel_params(t.rootfs_driver, t.rootfs_type); let result = KernelParams::new_rootfs_kernel_params(t.rootfs_driver, t.rootfs_type);
let msg = format!("{}, result: {:?}", msg, result); let msg = format!("{}, result: {:?}", msg, result);
if t.result.is_ok() { if t.result.is_ok() {
assert!(result.is_ok(), "{}", msg); assert!(result.is_ok(), "{}", msg);
assert_eq!(t.expect_params, result.unwrap()); assert_eq!(t.expect_params, result.unwrap());

View File

@ -17,6 +17,7 @@ pub mod manager;
mod manager_inner; mod manager_inner;
pub mod network; pub mod network;
pub mod resource_persist; pub mod resource_persist;
use hypervisor::BlockConfig;
use network::NetworkConfig; use network::NetworkConfig;
pub mod rootfs; pub mod rootfs;
pub mod share_fs; pub mod share_fs;
@ -30,6 +31,7 @@ use kata_types::config::hypervisor::SharedFsInfo;
pub enum ResourceConfig { pub enum ResourceConfig {
Network(NetworkConfig), Network(NetworkConfig),
ShareFs(SharedFsInfo), ShareFs(SharedFsInfo),
VmRootfs(BlockConfig),
} }
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]

View File

@ -121,6 +121,11 @@ impl ResourceManagerInner {
.await .await
.context("failed to handle network")?; .context("failed to handle network")?;
} }
ResourceConfig::VmRootfs(r) => {
do_handle_device(&self.device_manager, &DeviceConfig::BlockCfg(r))
.await
.context("do handle device failed.")?;
}
}; };
} }

View File

@ -17,7 +17,7 @@ use common::{
Sandbox, SandboxNetworkEnv, Sandbox, SandboxNetworkEnv,
}; };
use containerd_shim_protos::events::task::TaskOOM; use containerd_shim_protos::events::task::TaskOOM;
use hypervisor::{dragonball::Dragonball, Hypervisor, HYPERVISOR_DRAGONBALL}; use hypervisor::{dragonball::Dragonball, BlockConfig, Hypervisor, HYPERVISOR_DRAGONBALL};
use kata_sys_util::hooks::HookStates; use kata_sys_util::hooks::HookStates;
use kata_types::config::TomlConfig; use kata_types::config::TomlConfig;
use resource::{ use resource::{
@ -105,6 +105,8 @@ impl VirtSandbox {
network_env: SandboxNetworkEnv, network_env: SandboxNetworkEnv,
) -> Result<Vec<ResourceConfig>> { ) -> Result<Vec<ResourceConfig>> {
let mut resource_configs = vec![]; let mut resource_configs = vec![];
// prepare network config
if !network_env.network_created { if !network_env.network_created {
if let Some(netns_path) = network_env.netns { if let Some(netns_path) = network_env.netns {
let network_config = ResourceConfig::Network( let network_config = ResourceConfig::Network(
@ -114,10 +116,20 @@ impl VirtSandbox {
resource_configs.push(network_config); resource_configs.push(network_config);
} }
} }
let hypervisor_config = self.hypervisor.hypervisor_config().await;
let virtio_fs_config = ResourceConfig::ShareFs(hypervisor_config.shared_fs); // prepare sharefs device config
let virtio_fs_config =
ResourceConfig::ShareFs(self.hypervisor.hypervisor_config().await.shared_fs);
resource_configs.push(virtio_fs_config); resource_configs.push(virtio_fs_config);
// prepare VM rootfs device config
let vm_rootfs = ResourceConfig::VmRootfs(
self.prepare_rootfs_config()
.await
.context("failed to prepare rootfs device config")?,
);
resource_configs.push(vm_rootfs);
Ok(resource_configs) Ok(resource_configs)
} }
@ -173,6 +185,29 @@ impl VirtSandbox {
}) })
} }
async fn prepare_rootfs_config(&self) -> Result<BlockConfig> {
let hypervisor_config = self.hypervisor.hypervisor_config().await;
let image = {
let initrd_path = hypervisor_config.boot_info.initrd.clone();
let image_path = hypervisor_config.boot_info.image;
if !initrd_path.is_empty() {
Ok(initrd_path)
} else if !image_path.is_empty() {
Ok(image_path)
} else {
Err(anyhow!("failed to get image"))
}
}
.context("get image")?;
Ok(BlockConfig {
path_on_host: image,
is_readonly: true,
..Default::default()
})
}
fn has_prestart_hooks( fn has_prestart_hooks(
&self, &self,
prestart_hooks: Vec<oci::Hook>, prestart_hooks: Vec<oci::Hook>,
@ -212,6 +247,7 @@ impl Sandbox for VirtSandbox {
let resources = self let resources = self
.prepare_for_start_sandbox(id, network_env.clone()) .prepare_for_start_sandbox(id, network_env.clone())
.await?; .await?;
self.resource_manager self.resource_manager
.prepare_before_start_vm(resources) .prepare_before_start_vm(resources)
.await .await