runtime-rs: add devicetype enum

use device type to store the config information for different kind of
devices

Fixes:#5375
Signed-off-by: Zhongtao Hu <zhongtaohu.tim@linux.alibaba.com>
Signed-off-by: alex.lyn <alex.lyn@antgroup.com>
This commit is contained in:
Zhongtao Hu 2023-05-20 18:07:32 +08:00
parent 6800d30fdb
commit f9bded4484
29 changed files with 337 additions and 198 deletions

View File

@ -4,7 +4,7 @@
// SPDX-License-Identifier: Apache-2.0
use super::HypervisorState;
use crate::driver::DeviceConfig;
use crate::device::DeviceType;
use crate::VmmState;
use anyhow::Result;
use async_trait::async_trait;
@ -44,7 +44,7 @@ pub struct CloudHypervisorInner {
pub(crate) jailer_root: String,
/// List of devices that will be added to the VM once it boots
pub(crate) pending_devices: Option<Vec<DeviceConfig>>,
pub(crate) pending_devices: Option<Vec<DeviceType>>,
pub(crate) _capabilities: Capabilities,

View File

@ -5,8 +5,9 @@
// SPDX-License-Identifier: Apache-2.0
use super::inner::CloudHypervisorInner;
use crate::driver::{DeviceConfig, ShareFsDeviceConfig};
use crate::device::DeviceType;
use crate::HybridVsockConfig;
use crate::ShareFsDeviceConfig;
use crate::VmmState;
use anyhow::{anyhow, Context, Result};
use ch_config::ch_api::cloud_hypervisor_vm_fs_add;
@ -18,10 +19,9 @@ use std::path::PathBuf;
const VIRTIO_FS: &str = "virtio-fs";
impl CloudHypervisorInner {
pub(crate) async fn add_device(&mut self, device: DeviceConfig) -> Result<()> {
pub(crate) async fn add_device(&mut self, device: DeviceType) -> Result<()> {
if self.state != VmmState::VmRunning {
let mut devices: Vec<DeviceConfig> = if let Some(devices) = self.pending_devices.take()
{
let mut devices: Vec<DeviceType> = if let Some(devices) = self.pending_devices.take() {
devices
} else {
vec![]
@ -39,10 +39,10 @@ impl CloudHypervisorInner {
Ok(())
}
async fn handle_add_device(&mut self, device: DeviceConfig) -> Result<()> {
async fn handle_add_device(&mut self, device: DeviceType) -> Result<()> {
match device {
DeviceConfig::ShareFsDevice(cfg) => self.handle_share_fs_device(cfg).await,
DeviceConfig::HybridVsock(cfg) => self.handle_hvsock_device(&cfg).await,
DeviceType::ShareFs(sharefs) => self.handle_share_fs_device(sharefs.config).await,
DeviceType::HybridVsock(hvsock) => self.handle_hvsock_device(&hvsock.config).await,
_ => Err(anyhow!("unhandled device: {:?}", device)),
}
}
@ -67,7 +67,7 @@ impl CloudHypervisorInner {
Ok(())
}
pub(crate) async fn remove_device(&mut self, _device: DeviceConfig) -> Result<()> {
pub(crate) async fn remove_device(&mut self, _device: DeviceType) -> Result<()> {
Ok(())
}
@ -133,8 +133,8 @@ impl CloudHypervisorInner {
if let Some(devices) = pending_root_devices {
for dev in devices {
match dev {
DeviceConfig::ShareFsDevice(dev) => {
let settings = ShareFsSettings::new(dev, self.vm_path.clone());
DeviceType::ShareFs(dev) => {
let settings = ShareFsSettings::new(dev.config, self.vm_path.clone());
let fs_cfg = FsConfig::try_from(settings)?;

View File

@ -6,9 +6,9 @@
use super::inner::CloudHypervisorInner;
use crate::ch::utils::get_api_socket_path;
use crate::ch::utils::{get_jailer_root, get_sandbox_path, get_vsock_path};
use crate::device::DeviceType;
use crate::kernel_param::KernelParams;
use crate::DeviceConfig;
use crate::VsockConfig;
use crate::VsockDevice;
use crate::VM_ROOTFS_DRIVER_PMEM;
use crate::{VcpuThreadIds, VmmState};
use anyhow::{anyhow, Context, Result};
@ -417,10 +417,11 @@ impl CloudHypervisorInner {
self.netns = netns;
let vsock_cfg = VsockConfig::new(self.id.clone()).await?;
let vsock_dev = VsockDevice::new(self.id.clone()).await?;
let dev = DeviceConfig::Vsock(vsock_cfg);
self.add_device(dev).await.context("add vsock device")?;
self.add_device(DeviceType::Vsock(vsock_dev))
.await
.context("add vsock device")?;
self.start_hypervisor(self.timeout_secs).await?;

View File

@ -4,7 +4,8 @@
// SPDX-License-Identifier: Apache-2.0
use super::HypervisorState;
use crate::{driver::DeviceConfig, Hypervisor, VcpuThreadIds};
use crate::device::DeviceType;
use crate::{Hypervisor, VcpuThreadIds};
use anyhow::{Context, Result};
use async_trait::async_trait;
use kata_types::capabilities::Capabilities;
@ -78,12 +79,12 @@ impl Hypervisor for CloudHypervisor {
inner.save_vm().await
}
async fn add_device(&self, device: DeviceConfig) -> Result<()> {
async fn add_device(&self, device: DeviceType) -> Result<()> {
let mut inner = self.inner.write().await;
inner.add_device(device).await
}
async fn remove_device(&self, device: DeviceConfig) -> Result<()> {
async fn remove_device(&self, device: DeviceType) -> Result<()> {
let mut inner = self.inner.write().await;
inner.remove_device(device).await
}

View File

@ -11,13 +11,13 @@ use kata_sys_util::rand::RandomBytes;
use tokio::sync::Mutex;
use crate::{
BlockConfig, DeviceConfig, Hypervisor, KATA_BLK_DEV_TYPE, KATA_MMIO_BLK_DEV_TYPE,
BlockConfig, BlockDevice, Hypervisor, KATA_BLK_DEV_TYPE, KATA_MMIO_BLK_DEV_TYPE,
VIRTIO_BLOCK_MMIO, VIRTIO_BLOCK_PCI,
};
use super::{
util::{get_host_path, get_virt_drive_name},
Device,
Device, DeviceConfig,
};
pub type ArcMutexDevice = Arc<Mutex<dyn Device>>;
@ -97,7 +97,7 @@ impl DeviceManager {
let result = device_guard.attach(self.hypervisor.as_ref()).await;
// handle attach error
if let Err(e) = result {
if let DeviceConfig::Block(config) = device_guard.get_device_info().await {
if let DeviceConfig::BlockCfg(config) = device_guard.get_device_info().await {
self.shared_info.release_device_index(config.index);
};
drop(device_guard);
@ -146,8 +146,8 @@ impl DeviceManager {
async fn find_device(&self, device_config: &DeviceConfig) -> Option<String> {
for (device_id, dev) in &self.devices {
match dev.lock().await.get_device_info().await {
DeviceConfig::Block(config) => match device_config {
DeviceConfig::Block(ref config_new) => {
DeviceConfig::BlockCfg(config) => match device_config {
DeviceConfig::BlockCfg(ref config_new) => {
if config_new.path_on_host == config.path_on_host {
return Some(device_id.to_string());
}
@ -170,7 +170,7 @@ impl DeviceManager {
// in case of ID collision
let device_id = self.new_device_id()?;
let dev: ArcMutexDevice = match device_config {
DeviceConfig::Block(config) => self
DeviceConfig::BlockCfg(config) => self
.create_block_device(config, device_id.clone())
.await
.context("failed to create device")?,
@ -189,7 +189,6 @@ impl DeviceManager {
device_id: String,
) -> Result<ArcMutexDevice> {
let mut block_config = config.clone();
block_config.id = device_id.clone();
// get hypervisor block driver
let block_driver = match self
.hypervisor
@ -216,7 +215,10 @@ impl DeviceManager {
block_config.path_on_host = get_host_path("b".to_owned(), config.major, config.minor)
.context("failed to get host path")?;
}
Ok(Arc::new(Mutex::new(BlockConfig::new(block_config))))
Ok(Arc::new(Mutex::new(BlockDevice::new(
device_id,
block_config,
))))
}
// device ID must be generated by device manager instead of device itself

View File

@ -7,31 +7,17 @@
mod vhost_user;
mod virtio_blk;
pub use virtio_blk::{
BlockConfig, KATA_BLK_DEV_TYPE, KATA_MMIO_BLK_DEV_TYPE, VIRTIO_BLOCK_MMIO, VIRTIO_BLOCK_PCI,
BlockConfig, BlockDevice, KATA_BLK_DEV_TYPE, KATA_MMIO_BLK_DEV_TYPE, VIRTIO_BLOCK_MMIO,
VIRTIO_BLOCK_PCI,
};
mod virtio_net;
pub use virtio_net::{Address, NetworkConfig};
pub use virtio_net::{Address, NetworkConfig, NetworkDevice};
mod vfio;
pub use vfio::{bind_device_to_host, bind_device_to_vfio, VfioBusMode, VfioConfig};
pub use vfio::{bind_device_to_host, bind_device_to_vfio, VfioBusMode, VfioConfig, VfioDevice};
mod virtio_fs;
pub use virtio_fs::{ShareFsDeviceConfig, ShareFsMountConfig, ShareFsMountType, ShareFsOperation};
pub use virtio_fs::{
ShareFsDevice, ShareFsDeviceConfig, ShareFsMountConfig, ShareFsMountDevice, ShareFsMountType,
ShareFsOperation,
};
mod virtio_vsock;
use std::fmt;
pub use virtio_vsock::{HybridVsockConfig, VsockConfig};
#[derive(Debug)]
pub enum DeviceConfig {
Block(BlockConfig),
Network(NetworkConfig),
ShareFsDevice(ShareFsDeviceConfig),
Vfio(VfioConfig),
ShareFsMount(ShareFsMountConfig),
Vsock(VsockConfig),
HybridVsock(HybridVsockConfig),
}
impl fmt::Display for DeviceConfig {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", self)
}
}
pub use virtio_vsock::{HybridVsockConfig, HybridVsockDevice, VsockConfig, VsockDevice};

View File

@ -6,8 +6,9 @@
use std::{fs, path::Path, process::Command};
use crate::device::Device;
use crate::device::DeviceConfig;
use crate::Hypervisor as hypervisor;
use crate::{device::Device, DeviceConfig};
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
use anyhow::anyhow;
use anyhow::{Context, Result};
@ -45,9 +46,6 @@ impl VfioBusMode {
#[derive(Debug, Clone)]
pub struct VfioConfig {
/// Unique identifier of the device
pub id: String,
/// Sysfs path for mdev bus type device
pub sysfs_path: String,
@ -58,6 +56,15 @@ pub struct VfioConfig {
pub mode: VfioBusMode,
}
#[derive(Debug, Clone)]
pub struct VfioDevice {
/// Unique identifier of the device
pub id: String,
/// Config info for Vfio Device
pub config: VfioConfig,
}
/// binds the device to vfio driver after unbinding from host.
/// Will be called by a network interface or a generic pcie device.
pub fn bind_device_to_vfio(bdf: &str, host_driver: &str, _vendor_device_id: &str) -> Result<()> {

View File

@ -4,11 +4,13 @@
// SPDX-License-Identifier: Apache-2.0
//
use crate::device::Device;
use crate::device::DeviceConfig;
use crate::Hypervisor as hypervisor;
use crate::{device::Device, DeviceConfig};
use anyhow::Result;
use async_trait::async_trait;
#[derive(Debug, Clone, Default)]
/// VhostUserConfig represents data shared by most vhost-user devices
pub struct VhostUserConfig {
/// Device id
@ -29,6 +31,12 @@ pub struct VhostUserConfig {
pub queue_siez: u32,
}
#[derive(Debug, Clone, Default)]
pub struct VhostUserDevice {
pub device_id: String,
pub config: VhostUserConfig,
}
#[async_trait]
impl Device for VhostUserConfig {
async fn attach(&mut self, _h: &dyn hypervisor) -> Result<()> {

View File

@ -5,8 +5,9 @@
//
pub const VIRTIO_BLOCK_MMIO: &str = "virtio-blk-mmio";
use crate::device::Device;
use crate::device::{DeviceConfig, DeviceType};
use crate::Hypervisor as hypervisor;
use crate::{device::Device, DeviceConfig};
use anyhow::{anyhow, Context, Result};
use async_trait::async_trait;
/// VIRTIO_BLOCK_PCI indicates block driver is virtio-pci based
@ -16,9 +17,6 @@ pub const KATA_BLK_DEV_TYPE: &str = "blk";
#[derive(Debug, Clone, Default)]
pub struct BlockConfig {
/// Unique identifier of the drive.
pub id: String,
/// Path of the drive.
pub path_on_host: String,
@ -48,15 +46,26 @@ pub struct BlockConfig {
pub minor: i64,
}
impl BlockConfig {
#[derive(Debug, Clone, Default)]
pub struct BlockDevice {
pub device_id: String,
pub attach_count: u64,
pub config: BlockConfig,
}
impl BlockDevice {
// new creates a new VirtioBlkDevice
pub fn new(dev_info: BlockConfig) -> Self {
dev_info
pub fn new(device_id: String, config: BlockConfig) -> Self {
BlockDevice {
device_id,
attach_count: 0,
config,
}
}
}
#[async_trait]
impl Device for BlockConfig {
impl Device for BlockDevice {
async fn attach(&mut self, h: &dyn hypervisor) -> Result<()> {
// increase attach count, skip attach the device if the device is already attached
if self
@ -66,7 +75,7 @@ impl Device for BlockConfig {
{
return Ok(());
}
if let Err(e) = h.add_device(DeviceConfig::Block(self.clone())).await {
if let Err(e) = h.add_device(DeviceType::Block(self.clone())).await {
self.decrease_attach_count().await?;
return Err(e);
}
@ -82,15 +91,15 @@ impl Device for BlockConfig {
{
return Ok(None);
}
if let Err(e) = h.remove_device(DeviceConfig::Block(self.clone())).await {
if let Err(e) = h.remove_device(DeviceType::Block(self.clone())).await {
self.increase_attach_count().await?;
return Err(e);
}
Ok(Some(self.index))
Ok(Some(self.config.index))
}
async fn get_device_info(&self) -> DeviceConfig {
DeviceConfig::Block(self.clone())
DeviceConfig::BlockCfg(self.config.clone())
}
async fn increase_attach_count(&mut self) -> Result<bool> {

View File

@ -42,6 +42,11 @@ pub struct ShareFsMountConfig {
pub prefetch_list_path: Option<String>,
}
#[derive(Debug, Clone)]
pub struct ShareFsMountDevice {
pub config: ShareFsMountConfig,
}
/// ShareFsDeviceConfig: share fs device config
#[derive(Debug, Clone)]
pub struct ShareFsDeviceConfig {
@ -63,3 +68,8 @@ pub struct ShareFsDeviceConfig {
/// queue_num: queue number
pub queue_num: u64,
}
#[derive(Debug, Clone)]
pub struct ShareFsDevice {
pub config: ShareFsDeviceConfig,
}

View File

@ -22,12 +22,18 @@ impl fmt::Debug for Address {
#[derive(Debug, Clone)]
pub struct NetworkConfig {
/// Unique identifier of the device
pub id: String,
/// Host level path for the guest network interface.
pub host_dev_name: String,
/// Guest MAC address.
pub guest_mac: Option<Address>,
}
#[derive(Debug, Clone)]
pub struct NetworkDevice {
/// Unique identifier of the device
pub id: String,
/// Network Device config info
pub config: NetworkConfig,
}

View File

@ -11,9 +11,6 @@ use tokio::fs::{File, OpenOptions};
#[derive(Debug)]
pub struct HybridVsockConfig {
/// Unique identifier of the device
pub id: String,
/// A 32-bit Context Identifier (CID) used to identify the guest.
pub guest_cid: u32,
@ -22,10 +19,16 @@ pub struct HybridVsockConfig {
}
#[derive(Debug)]
pub struct VsockConfig {
pub struct HybridVsockDevice {
/// Unique identifier of the device
pub id: String,
/// config information for HybridVsockDevice
pub config: HybridVsockConfig,
}
#[derive(Debug)]
pub struct VsockConfig {
/// A 32-bit Context Identifier (CID) used to identify the guest.
pub guest_cid: u32,
@ -33,6 +36,15 @@ pub struct VsockConfig {
pub vhost_fd: File,
}
#[derive(Debug)]
pub struct VsockDevice {
/// Unique identifier of the device
pub id: String,
/// config information for VsockDevice
pub config: VsockConfig,
}
const VHOST_VSOCK_DEVICE: &str = "/dev/vhost-vsock";
// From <linux/vhost.h>
@ -50,7 +62,7 @@ nix::ioctl_write_ptr!(
const CID_RETRY_COUNT: u32 = 50;
impl VsockConfig {
impl VsockDevice {
pub async fn new(id: String) -> Result<Self> {
let vhost_fd = OpenOptions::new()
.read(true)
@ -72,10 +84,12 @@ impl VsockConfig {
unsafe { vhost_vsock_set_guest_cid(vhost_fd.as_raw_fd(), &(rand_cid as u64)) };
match guest_cid {
Ok(_) => {
return Ok(VsockConfig {
return Ok(VsockDevice {
id,
guest_cid: rand_cid,
vhost_fd,
config: VsockConfig {
guest_cid: rand_cid,
vhost_fd,
},
});
}
Err(nix::Error::EADDRINUSE) => {

View File

@ -4,7 +4,13 @@
// SPDX-License-Identifier: Apache-2.0
//
use crate::{DeviceConfig, Hypervisor as hypervisor};
use std::fmt;
use crate::{
BlockConfig, BlockDevice, HybridVsockConfig, HybridVsockDevice, Hypervisor as hypervisor,
NetworkConfig, NetworkDevice, ShareFsDevice, ShareFsDeviceConfig, ShareFsMountConfig,
ShareFsMountDevice, VfioConfig, VfioDevice, VsockConfig, VsockDevice,
};
use anyhow::Result;
use async_trait::async_trait;
@ -12,6 +18,34 @@ pub mod device_manager;
pub mod driver;
pub mod util;
#[derive(Debug)]
pub enum DeviceConfig {
BlockCfg(BlockConfig),
NetworkCfg(NetworkConfig),
ShareFsCfg(ShareFsDeviceConfig),
VfioCfg(VfioConfig),
ShareFsMountCfg(ShareFsMountConfig),
VsockCfg(VsockConfig),
HybridVsockCfg(HybridVsockConfig),
}
#[derive(Debug)]
pub enum DeviceType {
Block(BlockDevice),
Vfio(VfioDevice),
Network(NetworkDevice),
ShareFs(ShareFsDevice),
ShareFsMount(ShareFsMountDevice),
HybridVsock(HybridVsockDevice),
Vsock(VsockDevice),
}
impl fmt::Display for DeviceType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", self)
}
}
#[async_trait]
pub trait Device: Send + Sync {
// attach is to plug device into VM

View File

@ -6,8 +6,8 @@
use super::vmm_instance::VmmInstance;
use crate::{
driver::DeviceConfig, hypervisor_persist::HypervisorState, kernel_param::KernelParams,
VmmState, DEV_HUGEPAGES, HUGETLBFS, HYPERVISOR_DRAGONBALL, SHMEM, VM_ROOTFS_DRIVER_BLK,
device::DeviceType, hypervisor_persist::HypervisorState, kernel_param::KernelParams, VmmState,
DEV_HUGEPAGES, HUGETLBFS, HYPERVISOR_DRAGONBALL, SHMEM, VM_ROOTFS_DRIVER_BLK,
};
use anyhow::{anyhow, Context, Result};
use async_trait::async_trait;
@ -56,7 +56,7 @@ pub struct DragonballInner {
pub(crate) run_dir: String,
/// pending device
pub(crate) pending_devices: Vec<DeviceConfig>,
pub(crate) pending_devices: Vec<DeviceType>,
/// cached block device
pub(crate) cached_block_devices: HashSet<String>,

View File

@ -15,8 +15,8 @@ use dragonball::api::v1::{
use super::DragonballInner;
use crate::{
driver::DeviceConfig, HybridVsockConfig, NetworkConfig, ShareFsDeviceConfig,
ShareFsMountConfig, ShareFsMountType, ShareFsOperation, VmmState,
device::DeviceType, HybridVsockConfig, NetworkConfig, ShareFsDeviceConfig, ShareFsMountConfig,
ShareFsMountType, ShareFsOperation, VmmState,
};
const MB_TO_B: u32 = 1024 * 1024;
@ -31,7 +31,7 @@ pub(crate) fn drive_index_to_id(index: u64) -> String {
}
impl DragonballInner {
pub(crate) async fn add_device(&mut self, device: DeviceConfig) -> Result<()> {
pub(crate) async fn add_device(&mut self, device: DeviceType) -> Result<()> {
if self.state == VmmState::NotReady {
info!(sl!(), "VMM not ready, queueing device {}", device);
@ -44,41 +44,43 @@ impl DragonballInner {
info!(sl!(), "dragonball add device {:?}", &device);
match device {
DeviceConfig::Network(config) => self.add_net_device(&config).context("add net device"),
DeviceConfig::Vfio(_config) => {
DeviceType::Network(network) => self
.add_net_device(&network.config, network.id)
.context("add net device"),
DeviceType::Vfio(_) => {
todo!()
}
DeviceConfig::Block(config) => self
DeviceType::Block(block) => self
.add_block_device(
config.path_on_host.as_str(),
config.id.as_str(),
config.is_readonly,
config.no_drop,
block.config.path_on_host.as_str(),
block.device_id.as_str(),
block.config.is_readonly,
block.config.no_drop,
)
.context("add block device"),
DeviceConfig::HybridVsock(config) => self.add_hvsock(&config).context("add vsock"),
DeviceConfig::ShareFsDevice(config) => self
.add_share_fs_device(&config)
DeviceType::HybridVsock(hvsock) => self.add_hvsock(&hvsock.config).context("add vsock"),
DeviceType::ShareFs(sharefs) => self
.add_share_fs_device(&sharefs.config)
.context("add share fs device"),
DeviceConfig::ShareFsMount(config) => self
.add_share_fs_mount(&config)
DeviceType::ShareFsMount(sharefs_mount) => self
.add_share_fs_mount(&sharefs_mount.config)
.context("add share fs mount"),
DeviceConfig::Vsock(_) => {
DeviceType::Vsock(_) => {
todo!()
}
}
}
pub(crate) async fn remove_device(&mut self, device: DeviceConfig) -> Result<()> {
pub(crate) async fn remove_device(&mut self, device: DeviceType) -> Result<()> {
info!(sl!(), "remove device {} ", device);
match device {
DeviceConfig::Block(config) => {
let drive_id = drive_index_to_id(config.index);
DeviceType::Block(block) => {
let drive_id = drive_index_to_id(block.config.index);
self.remove_block_drive(drive_id.as_str())
.context("remove block drive")
}
DeviceConfig::Vfio(_config) => {
DeviceType::Vfio(_config) => {
todo!()
}
_ => Err(anyhow!("unsupported device {:?}", device)),
@ -121,9 +123,9 @@ impl DragonballInner {
Ok(())
}
fn add_net_device(&mut self, config: &NetworkConfig) -> Result<()> {
fn add_net_device(&mut self, config: &NetworkConfig, device_id: String) -> Result<()> {
let iface_cfg = VirtioNetDeviceConfigInfo {
iface_id: config.id.clone(),
iface_id: device_id,
host_dev_name: config.host_dev_name.clone(),
guest_mac: match &config.guest_mac {
Some(mac) => MacAddr::from_bytes(&mac.0).ok(),

View File

@ -13,7 +13,9 @@ use anyhow::{Context, Ok, Result};
use kata_types::capabilities::Capabilities;
use super::inner::DragonballInner;
use crate::{utils, VcpuThreadIds, VmmState};
use crate::{
device::DeviceType, utils, HybridVsockConfig, HybridVsockDevice, VcpuThreadIds, VmmState,
};
use shim_interface::KATA_PATH;
const DEFAULT_HYBRID_VSOCK_NAME: &str = "kata.hvsock";
@ -32,10 +34,12 @@ impl DragonballInner {
// prepare vsock
let uds_path = [&self.jailer_root, DEFAULT_HYBRID_VSOCK_NAME].join("/");
let d = crate::driver::DeviceConfig::HybridVsock(crate::driver::HybridVsockConfig {
let d = DeviceType::HybridVsock(HybridVsockDevice {
id: format!("vsock-{}", &self.id),
guest_cid: 3,
uds_path,
config: HybridVsockConfig {
guest_cid: 3,
uds_path,
},
});
self.add_device(d).await.context("add device")?;

View File

@ -20,7 +20,7 @@ use kata_types::capabilities::Capabilities;
use kata_types::config::hypervisor::Hypervisor as HypervisorConfig;
use tokio::sync::RwLock;
use crate::{driver::DeviceConfig, Hypervisor, VcpuThreadIds};
use crate::{DeviceType, Hypervisor, VcpuThreadIds};
pub struct Dragonball {
inner: Arc<RwLock<DragonballInner>>,
@ -77,12 +77,12 @@ impl Hypervisor for Dragonball {
inner.save_vm().await
}
async fn add_device(&self, device: DeviceConfig) -> Result<()> {
async fn add_device(&self, device: DeviceType) -> Result<()> {
let mut inner = self.inner.write().await;
inner.add_device(device).await
}
async fn remove_device(&self, device: DeviceConfig) -> Result<()> {
async fn remove_device(&self, device: DeviceType) -> Result<()> {
let mut inner = self.inner.write().await;
inner.remove_device(device).await
}

View File

@ -11,8 +11,8 @@ logging::logger_with_subsystem!(sl, "hypervisor");
pub mod device;
pub mod hypervisor_persist;
use device::driver;
pub use device::driver::*;
use device::DeviceType;
pub mod dragonball;
mod kernel_param;
pub mod qemu;
@ -79,8 +79,8 @@ pub trait Hypervisor: Send + Sync {
async fn resume_vm(&self) -> Result<()>;
// device manager
async fn add_device(&self, device: driver::DeviceConfig) -> Result<()>;
async fn remove_device(&self, device: driver::DeviceConfig) -> Result<()>;
async fn add_device(&self, device: DeviceType) -> Result<()>;
async fn remove_device(&self, device: DeviceType) -> Result<()>;
// utils
async fn get_agent_socket(&self) -> Result<String>;

View File

@ -133,16 +133,16 @@ impl QemuInner {
}
}
use crate::driver::DeviceConfig;
use crate::device::DeviceType;
// device manager part of Hypervisor
impl QemuInner {
pub(crate) async fn add_device(&mut self, device: DeviceConfig) -> Result<()> {
pub(crate) async fn add_device(&mut self, device: DeviceType) -> Result<()> {
info!(sl!(), "QemuInner::add_device() {}", device);
todo!()
}
pub(crate) async fn remove_device(&mut self, device: DeviceConfig) -> Result<()> {
pub(crate) async fn remove_device(&mut self, device: DeviceType) -> Result<()> {
info!(sl!(), "QemuInner::remove_device() {} ", device);
todo!()
}

View File

@ -5,7 +5,7 @@
mod inner;
use crate::driver::DeviceConfig;
use crate::device::DeviceType;
use crate::hypervisor_persist::HypervisorState;
use crate::Hypervisor;
use crate::{HypervisorConfig, VcpuThreadIds};
@ -73,12 +73,12 @@ impl Hypervisor for Qemu {
inner.save_vm().await
}
async fn add_device(&self, device: DeviceConfig) -> Result<()> {
async fn add_device(&self, device: DeviceType) -> Result<()> {
let mut inner = self.inner.write().await;
inner.add_device(device).await
}
async fn remove_device(&self, device: DeviceConfig) -> Result<()> {
async fn remove_device(&self, device: DeviceType) -> Result<()> {
let mut inner = self.inner.write().await;
inner.remove_device(device).await
}

View File

@ -10,7 +10,10 @@ use crate::{network::NetworkConfig, resource_persist::ResourceState};
use agent::{types::Device, Agent, Storage};
use anyhow::{anyhow, Context, Ok, Result};
use async_trait::async_trait;
use hypervisor::{device::device_manager::DeviceManager, BlockConfig, DeviceConfig, Hypervisor};
use hypervisor::{
device::{device_manager::DeviceManager, DeviceConfig},
BlockConfig, Hypervisor,
};
use kata_types::config::TomlConfig;
use kata_types::mount::Mount;
use oci::{Linux, LinuxResources};
@ -255,7 +258,7 @@ impl ResourceManagerInner {
for d in linux.devices.iter() {
match d.r#type.as_str() {
"b" => {
let device_info = DeviceConfig::Block(BlockConfig {
let device_info = DeviceConfig::BlockCfg(BlockConfig {
major: d.major,
minor: d.minor,
..Default::default()
@ -285,7 +288,7 @@ impl ResourceManagerInner {
.context("failed to get device info")?;
// create agent device
if let DeviceConfig::Block(config) = dev_info {
if let DeviceConfig::BlockCfg(config) = dev_info {
let agent_device = Device {
id: device_id.clone(),
container_path: d.path.clone(),

View File

@ -9,11 +9,13 @@ use std::io::{self, Error};
use super::endpoint_persist::{EndpointState, IpVlanEndpointState};
use anyhow::{Context, Result};
use async_trait::async_trait;
use hypervisor::device::DeviceType;
use hypervisor::NetworkDevice;
use super::Endpoint;
use crate::network::network_model::TC_FILTER_NET_MODEL_STR;
use crate::network::{utils, NetworkPair};
use hypervisor::{device::driver::NetworkConfig, DeviceConfig, Hypervisor};
use hypervisor::{device::driver::NetworkConfig, Hypervisor};
// IPVlanEndpoint is the endpoint bridged to VM
#[derive(Debug)]
@ -44,7 +46,6 @@ impl IPVlanEndpoint {
)
})?;
Ok(NetworkConfig {
id: self.net_pair.virt_iface.name.clone(),
host_dev_name: iface.name.clone(),
guest_mac: Some(guest_mac),
})
@ -67,9 +68,12 @@ impl Endpoint for IPVlanEndpoint {
.await
.context("error adding network model")?;
let config = self.get_network_config().context("get network config")?;
h.add_device(DeviceConfig::Network(config))
.await
.context("error adding device by hypervisor")?;
h.add_device(DeviceType::Network(NetworkDevice {
id: self.net_pair.virt_iface.name.clone(),
config,
}))
.await
.context("error adding device by hypervisor")?;
Ok(())
}
@ -82,9 +86,12 @@ impl Endpoint for IPVlanEndpoint {
let config = self
.get_network_config()
.context("error getting network config")?;
h.remove_device(DeviceConfig::Network(config))
.await
.context("error removing device by hypervisor")?;
h.remove_device(DeviceType::Network(NetworkDevice {
id: self.net_pair.virt_iface.name.clone(),
config,
}))
.await
.context("error removing device by hypervisor")?;
Ok(())
}

View File

@ -11,7 +11,9 @@ use super::Endpoint;
use crate::network::{utils, NetworkPair};
use anyhow::{Context, Result};
use async_trait::async_trait;
use hypervisor::{device::driver::NetworkConfig, DeviceConfig, Hypervisor};
use hypervisor::device::DeviceType;
use hypervisor::NetworkDevice;
use hypervisor::{device::driver::NetworkConfig, Hypervisor};
#[derive(Debug)]
pub struct MacVlanEndpoint {
@ -41,7 +43,6 @@ impl MacVlanEndpoint {
)
})?;
Ok(NetworkConfig {
id: self.net_pair.virt_iface.name.clone(),
host_dev_name: iface.name.clone(),
guest_mac: Some(guest_mac),
})
@ -64,9 +65,13 @@ impl Endpoint for MacVlanEndpoint {
.await
.context("add network model")?;
let config = self.get_network_config().context("get network config")?;
h.add_device(DeviceConfig::Network(config))
.await
.context("Error add device")?;
h.add_device(DeviceType::Network(NetworkDevice {
id: self.net_pair.virt_iface.name.clone(),
config,
}))
.await
.context("error adding device by hypervisor")?;
Ok(())
}
@ -76,9 +81,13 @@ impl Endpoint for MacVlanEndpoint {
.await
.context("del network model")?;
let config = self.get_network_config().context("get network config")?;
h.remove_device(DeviceConfig::Network(config))
.await
.context("remove device")?;
h.remove_device(DeviceType::Network(NetworkDevice {
id: self.net_pair.virt_iface.name.clone(),
config,
}))
.await
.context("error removing device by hypervisor")?;
Ok(())
}

View File

@ -8,7 +8,9 @@ use std::path::Path;
use anyhow::{anyhow, Context, Result};
use async_trait::async_trait;
use hypervisor::device::DeviceType;
use hypervisor::{device::driver, Hypervisor};
use hypervisor::{VfioConfig, VfioDevice};
use super::endpoint_persist::{EndpointState, PhysicalEndpointState};
use super::Endpoint;
@ -108,12 +110,14 @@ impl Endpoint for PhysicalEndpoint {
};
// add vfio device
let d = driver::DeviceConfig::Vfio(driver::VfioConfig {
let d = DeviceType::Vfio(VfioDevice {
id: format!("physical_nic_{}", self.name().await),
sysfs_path: "".to_string(),
bus_slot_func: self.bdf.clone(),
mode: driver::VfioBusMode::new(mode)
.with_context(|| format!("new vfio bus mode {:?}", mode))?,
config: VfioConfig {
sysfs_path: "".to_string(),
bus_slot_func: self.bdf.clone(),
mode: driver::VfioBusMode::new(mode)
.with_context(|| format!("new vfio bus mode {:?}", mode))?,
},
});
hypervisor.add_device(d).await.context("add device")?;
Ok(())

View File

@ -11,7 +11,9 @@ use super::Endpoint;
use crate::network::{utils, NetworkPair};
use anyhow::{Context, Result};
use async_trait::async_trait;
use hypervisor::{device::driver::NetworkConfig, DeviceConfig, Hypervisor};
use hypervisor::device::DeviceType;
use hypervisor::NetworkDevice;
use hypervisor::{device::driver::NetworkConfig, Hypervisor};
#[derive(Debug)]
pub struct VethEndpoint {
@ -41,7 +43,6 @@ impl VethEndpoint {
)
})?;
Ok(NetworkConfig {
id: self.net_pair.virt_iface.name.clone(),
host_dev_name: iface.name.clone(),
guest_mac: Some(guest_mac),
})
@ -64,9 +65,12 @@ impl Endpoint for VethEndpoint {
.await
.context("add network model")?;
let config = self.get_network_config().context("get network config")?;
h.add_device(DeviceConfig::Network(config))
.await
.context("Error add device")?;
h.add_device(DeviceType::Network(NetworkDevice {
id: self.net_pair.virt_iface.name.clone(),
config,
}))
.await
.context("error adding device by hypervisor")?;
Ok(())
}
@ -76,9 +80,12 @@ impl Endpoint for VethEndpoint {
.await
.context("del network model")?;
let config = self.get_network_config().context("get network config")?;
h.remove_device(DeviceConfig::Network(config))
.await
.context("remove device")?;
h.remove_device(DeviceType::Network(NetworkDevice {
id: self.net_pair.virt_iface.name.clone(),
config,
}))
.await
.context("error removing device by hypervisor")?;
Ok(())
}
async fn save(&self) -> Option<EndpointState> {

View File

@ -8,12 +8,14 @@ use std::io::{self, Error};
use anyhow::{Context, Result};
use async_trait::async_trait;
use hypervisor::device::DeviceType;
use hypervisor::NetworkDevice;
use super::endpoint_persist::{EndpointState, VlanEndpointState};
use super::Endpoint;
use crate::network::network_model::TC_FILTER_NET_MODEL_STR;
use crate::network::{utils, NetworkPair};
use hypervisor::{device::driver::NetworkConfig, DeviceConfig, Hypervisor};
use hypervisor::{device::driver::NetworkConfig, Hypervisor};
#[derive(Debug)]
pub struct VlanEndpoint {
pub(crate) net_pair: NetworkPair,
@ -41,7 +43,6 @@ impl VlanEndpoint {
)
})?;
Ok(NetworkConfig {
id: self.net_pair.virt_iface.name.clone(),
host_dev_name: iface.name.clone(),
guest_mac: Some(guest_mac),
})
@ -64,9 +65,12 @@ impl Endpoint for VlanEndpoint {
.await
.context("error adding network model")?;
let config = self.get_network_config().context("get network config")?;
h.add_device(DeviceConfig::Network(config))
.await
.context("error adding device by hypervisor")?;
h.add_device(DeviceType::Network(NetworkDevice {
id: self.net_pair.virt_iface.name.clone(),
config,
}))
.await
.context("error adding device by hypervisor")?;
Ok(())
}
@ -79,9 +83,12 @@ impl Endpoint for VlanEndpoint {
let config = self
.get_network_config()
.context("error getting network config")?;
h.remove_device(DeviceConfig::Network(config))
.await
.context("error removing device by hypervisor")?;
h.remove_device(DeviceType::Network(NetworkDevice {
id: self.net_pair.virt_iface.name.clone(),
config,
}))
.await
.context("error removing device by hypervisor")?;
Ok(())
}

View File

@ -9,7 +9,10 @@ use crate::share_fs::{do_get_guest_path, do_get_host_path};
use agent::Storage;
use anyhow::{anyhow, Context, Result};
use async_trait::async_trait;
use hypervisor::{device::device_manager::DeviceManager, BlockConfig, DeviceConfig};
use hypervisor::{
device::{device_manager::DeviceManager, DeviceConfig},
BlockConfig,
};
use kata_types::mount::Mount;
use nix::sys::stat::{self, SFlag};
use std::fs;
@ -46,7 +49,7 @@ impl BlockRootfs {
let device_id = d
.write()
.await
.new_device(&DeviceConfig::Block(block_device_config.clone()))
.new_device(&DeviceConfig::BlockCfg(block_device_config.clone()))
.await
.context("failed to create deviec")?;
@ -71,7 +74,7 @@ impl BlockRootfs {
.await
.context("failed to get device info")?;
if let DeviceConfig::Block(config) = dev_info {
if let DeviceConfig::BlockCfg(config) = dev_info {
storage.driver = config.driver_option;
storage.source = config.virt_path;
}

View File

@ -8,8 +8,12 @@ use std::path::Path;
use anyhow::{Context, Result};
use hypervisor::{
device::driver::{
DeviceConfig as HypervisorDevice, ShareFsMountConfig, ShareFsMountType, ShareFsOperation,
device::{
driver::{
ShareFsDevice, ShareFsMountConfig, ShareFsMountDevice, ShareFsMountType,
ShareFsOperation,
},
DeviceType,
},
Hypervisor, ShareFsDeviceConfig,
};
@ -44,15 +48,19 @@ pub(crate) async fn prepare_virtiofs(
mount::bind_mount_unchecked(&host_rw_dest, &host_ro_dest, true)
.context("bind mount shared_fs directory")?;
let share_fs_device = HypervisorDevice::ShareFsDevice(ShareFsDeviceConfig {
sock_path: generate_sock_path(root),
mount_tag: String::from(MOUNT_GUEST_TAG),
host_path: String::from(host_ro_dest.to_str().unwrap()),
fs_type: fs_type.to_string(),
queue_size: 0,
queue_num: 0,
});
h.add_device(share_fs_device).await.context("add device")?;
let share_fs_device = ShareFsDevice {
config: ShareFsDeviceConfig {
sock_path: generate_sock_path(root),
mount_tag: String::from(MOUNT_GUEST_TAG),
host_path: String::from(host_ro_dest.to_str().unwrap()),
fs_type: fs_type.to_string(),
queue_size: 0,
queue_num: 0,
},
};
h.add_device(DeviceType::ShareFs(share_fs_device))
.await
.context("add device")?;
Ok(())
}
@ -68,16 +76,18 @@ pub(crate) async fn setup_inline_virtiofs(id: &str, h: &dyn Hypervisor) -> Resul
let ro_source = utils::get_host_ro_shared_path(id).join(PASSTHROUGH_FS_DIR);
let source = String::from(ro_source.to_str().unwrap());
let virtio_fs = HypervisorDevice::ShareFsMount(ShareFsMountConfig {
source: source.clone(),
fstype: ShareFsMountType::PASSTHROUGH,
mount_point: mnt,
config: None,
tag: String::from(MOUNT_GUEST_TAG),
op: ShareFsOperation::Mount,
prefetch_list_path: None,
});
h.add_device(virtio_fs)
let virtio_fs = ShareFsMountDevice {
config: ShareFsMountConfig {
source: source.clone(),
fstype: ShareFsMountType::PASSTHROUGH,
mount_point: mnt,
config: None,
tag: String::from(MOUNT_GUEST_TAG),
op: ShareFsOperation::Mount,
prefetch_list_path: None,
},
};
h.add_device(DeviceType::ShareFsMount(virtio_fs))
.await
.with_context(|| format!("fail to attach passthrough fs {:?}", source))
}
@ -93,16 +103,18 @@ pub async fn rafs_mount(
sl!(),
"Attaching rafs meta file {} to virtio-fs device, rafs mount point {}", rafs_meta, rafs_mnt
);
let virtio_fs = HypervisorDevice::ShareFsMount(ShareFsMountConfig {
source: rafs_meta.clone(),
fstype: ShareFsMountType::RAFS,
mount_point: rafs_mnt,
config: Some(config_content),
tag: String::from(MOUNT_GUEST_TAG),
op: ShareFsOperation::Mount,
prefetch_list_path,
});
h.add_device(virtio_fs)
let virtio_fs = ShareFsMountDevice {
config: ShareFsMountConfig {
source: rafs_meta.clone(),
fstype: ShareFsMountType::RAFS,
mount_point: rafs_mnt,
config: Some(config_content),
tag: String::from(MOUNT_GUEST_TAG),
op: ShareFsOperation::Mount,
prefetch_list_path,
},
};
h.add_device(DeviceType::ShareFsMount(virtio_fs))
.await
.with_context(|| format!("fail to attach rafs {:?}", rafs_meta))?;
Ok(())

View File

@ -13,7 +13,10 @@ use crate::share_fs::{do_get_guest_path, do_get_host_path};
use super::{share_fs_volume::generate_mount_path, Volume};
use agent::Storage;
use anyhow::{anyhow, Context};
use hypervisor::{device::device_manager::DeviceManager, BlockConfig, DeviceConfig};
use hypervisor::{
device::{device_manager::DeviceManager, DeviceConfig},
BlockConfig,
};
use nix::sys::stat::{self, SFlag};
use tokio::sync::RwLock;
#[derive(Debug)]
@ -48,7 +51,7 @@ impl BlockVolume {
let device_id = d
.write()
.await
.new_device(&DeviceConfig::Block(block_device_config.clone()))
.new_device(&DeviceConfig::BlockCfg(block_device_config.clone()))
.await
.context("failed to create deviec")?;
@ -76,7 +79,7 @@ impl BlockVolume {
// storage
let mut storage = Storage::default();
if let DeviceConfig::Block(config) = dev_info {
if let DeviceConfig::BlockCfg(config) = dev_info {
storage.driver = config.driver_option;
storage.source = config.virt_path;
}