mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-06-28 00:07:16 +00:00
Merge pull request #8284 from amshinde/runtime-rs-update-device-pci-info
runtime-rs: update device pci info for vfio and virtio-blk devices
This commit is contained in:
commit
3b2fb6a604
@ -70,7 +70,7 @@ pub async fn cloud_hypervisor_vm_stop(mut socket: UnixStream) -> Result<Option<S
|
|||||||
.await?
|
.await?
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Deserialize, Debug)]
|
||||||
pub struct PciDeviceInfo {
|
pub struct PciDeviceInfo {
|
||||||
pub id: String,
|
pub id: String,
|
||||||
pub bdf: String,
|
pub bdf: String,
|
||||||
|
@ -7,16 +7,18 @@
|
|||||||
use super::inner::CloudHypervisorInner;
|
use super::inner::CloudHypervisorInner;
|
||||||
use crate::device::DeviceType;
|
use crate::device::DeviceType;
|
||||||
use crate::BlockDevice;
|
use crate::BlockDevice;
|
||||||
use crate::HybridVsockConfig;
|
use crate::HybridVsockDevice;
|
||||||
use crate::NetworkConfig;
|
use crate::NetworkConfig;
|
||||||
|
use crate::PciPath;
|
||||||
|
use crate::ShareFsDevice;
|
||||||
use crate::ShareFsDeviceConfig;
|
use crate::ShareFsDeviceConfig;
|
||||||
use crate::VfioDevice;
|
use crate::VfioDevice;
|
||||||
use crate::VmmState;
|
use crate::VmmState;
|
||||||
use anyhow::{anyhow, Context, Result};
|
use anyhow::{anyhow, Context, Result};
|
||||||
|
use ch_config::ch_api::cloud_hypervisor_vm_device_add;
|
||||||
use ch_config::ch_api::{
|
use ch_config::ch_api::{
|
||||||
cloud_hypervisor_vm_blockdev_add, cloud_hypervisor_vm_device_add,
|
cloud_hypervisor_vm_blockdev_add, cloud_hypervisor_vm_device_remove,
|
||||||
cloud_hypervisor_vm_device_remove, cloud_hypervisor_vm_fs_add, PciDeviceInfo,
|
cloud_hypervisor_vm_fs_add, PciDeviceInfo, VmRemoveDeviceData,
|
||||||
VmRemoveDeviceData,
|
|
||||||
};
|
};
|
||||||
use ch_config::convert::{DEFAULT_DISK_QUEUES, DEFAULT_DISK_QUEUE_SIZE, DEFAULT_NUM_PCI_SEGMENTS};
|
use ch_config::convert::{DEFAULT_DISK_QUEUES, DEFAULT_DISK_QUEUE_SIZE, DEFAULT_NUM_PCI_SEGMENTS};
|
||||||
use ch_config::DiskConfig;
|
use ch_config::DiskConfig;
|
||||||
@ -31,7 +33,7 @@ pub const DEFAULT_FS_QUEUES: usize = 1;
|
|||||||
const DEFAULT_FS_QUEUE_SIZE: u16 = 1024;
|
const DEFAULT_FS_QUEUE_SIZE: u16 = 1024;
|
||||||
|
|
||||||
impl CloudHypervisorInner {
|
impl CloudHypervisorInner {
|
||||||
pub(crate) async fn add_device(&mut self, device: DeviceType) -> Result<()> {
|
pub(crate) async fn add_device(&mut self, device: DeviceType) -> Result<DeviceType> {
|
||||||
if self.state != VmmState::VmRunning {
|
if self.state != VmmState::VmRunning {
|
||||||
// If the VM is not running, add the device to the pending list to
|
// If the VM is not running, add the device to the pending list to
|
||||||
// be handled later.
|
// be handled later.
|
||||||
@ -55,8 +57,8 @@ impl CloudHypervisorInner {
|
|||||||
// - Network details need to be saved for later application.
|
// - Network details need to be saved for later application.
|
||||||
//
|
//
|
||||||
match device {
|
match device {
|
||||||
DeviceType::ShareFs(_) => self.pending_devices.insert(0, device),
|
DeviceType::ShareFs(_) => self.pending_devices.insert(0, device.clone()),
|
||||||
DeviceType::Network(_) => self.pending_devices.insert(0, device),
|
DeviceType::Network(_) => self.pending_devices.insert(0, device.clone()),
|
||||||
_ => {
|
_ => {
|
||||||
debug!(
|
debug!(
|
||||||
sl!(),
|
sl!(),
|
||||||
@ -65,20 +67,18 @@ impl CloudHypervisorInner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(());
|
return Ok(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.handle_add_device(device).await?;
|
self.handle_add_device(device).await
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_add_device(&mut self, device: DeviceType) -> Result<()> {
|
async fn handle_add_device(&mut self, device: DeviceType) -> Result<DeviceType> {
|
||||||
match device {
|
match device {
|
||||||
DeviceType::ShareFs(sharefs) => self.handle_share_fs_device(sharefs.config).await,
|
DeviceType::ShareFs(sharefs) => self.handle_share_fs_device(sharefs).await,
|
||||||
DeviceType::HybridVsock(hvsock) => self.handle_hvsock_device(&hvsock.config).await,
|
DeviceType::HybridVsock(hvsock) => self.handle_hvsock_device(hvsock).await,
|
||||||
DeviceType::Block(block) => self.handle_block_device(block).await,
|
DeviceType::Block(block) => self.handle_block_device(block).await,
|
||||||
DeviceType::Vfio(vfiodev) => self.handle_vfio_device(&vfiodev).await,
|
DeviceType::Vfio(vfiodev) => self.handle_vfio_device(vfiodev).await,
|
||||||
_ => Err(anyhow!("unhandled device: {:?}", device)),
|
_ => Err(anyhow!("unhandled device: {:?}", device)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -108,9 +108,13 @@ impl CloudHypervisorInner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_share_fs_device(&mut self, cfg: ShareFsDeviceConfig) -> Result<()> {
|
async fn handle_share_fs_device(&mut self, sharefs: ShareFsDevice) -> Result<DeviceType> {
|
||||||
if cfg.fs_type != VIRTIO_FS {
|
let device: ShareFsDevice = sharefs.clone();
|
||||||
return Err(anyhow!("cannot handle share fs type: {:?}", cfg.fs_type));
|
if device.config.fs_type != VIRTIO_FS {
|
||||||
|
return Err(anyhow!(
|
||||||
|
"cannot handle share fs type: {:?}",
|
||||||
|
device.config.fs_type
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let socket = self
|
let socket = self
|
||||||
@ -119,26 +123,26 @@ impl CloudHypervisorInner {
|
|||||||
.ok_or("missing socket")
|
.ok_or("missing socket")
|
||||||
.map_err(|e| anyhow!(e))?;
|
.map_err(|e| anyhow!(e))?;
|
||||||
|
|
||||||
let num_queues: usize = if cfg.queue_num > 0 {
|
let num_queues: usize = if device.config.queue_num > 0 {
|
||||||
cfg.queue_num as usize
|
device.config.queue_num as usize
|
||||||
} else {
|
} else {
|
||||||
DEFAULT_FS_QUEUES
|
DEFAULT_FS_QUEUES
|
||||||
};
|
};
|
||||||
|
|
||||||
let queue_size: u16 = if cfg.queue_num > 0 {
|
let queue_size: u16 = if device.config.queue_num > 0 {
|
||||||
u16::try_from(cfg.queue_size)?
|
u16::try_from(device.config.queue_size)?
|
||||||
} else {
|
} else {
|
||||||
DEFAULT_FS_QUEUE_SIZE
|
DEFAULT_FS_QUEUE_SIZE
|
||||||
};
|
};
|
||||||
|
|
||||||
let socket_path = if cfg.sock_path.starts_with('/') {
|
let socket_path = if device.config.sock_path.starts_with('/') {
|
||||||
PathBuf::from(cfg.sock_path)
|
PathBuf::from(device.config.sock_path)
|
||||||
} else {
|
} else {
|
||||||
scoped_join(&self.vm_path, cfg.sock_path)?
|
scoped_join(&self.vm_path, device.config.sock_path)?
|
||||||
};
|
};
|
||||||
|
|
||||||
let fs_config = FsConfig {
|
let fs_config = FsConfig {
|
||||||
tag: cfg.mount_tag,
|
tag: device.config.mount_tag,
|
||||||
socket: socket_path,
|
socket: socket_path,
|
||||||
num_queues,
|
num_queues,
|
||||||
queue_size,
|
queue_size,
|
||||||
@ -157,14 +161,16 @@ impl CloudHypervisorInner {
|
|||||||
debug!(sl!(), "fs add response: {:?}", detail);
|
debug!(sl!(), "fs add response: {:?}", detail);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(DeviceType::ShareFs(sharefs))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_hvsock_device(&mut self, _cfg: &HybridVsockConfig) -> Result<()> {
|
async fn handle_hvsock_device(&mut self, device: HybridVsockDevice) -> Result<DeviceType> {
|
||||||
Ok(())
|
Ok(DeviceType::HybridVsock(device))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_vfio_device(&mut self, device: &VfioDevice) -> Result<()> {
|
async fn handle_vfio_device(&mut self, device: VfioDevice) -> Result<DeviceType> {
|
||||||
|
let mut vfio_device: VfioDevice = device.clone();
|
||||||
|
|
||||||
// A device with multi-funtions, or a IOMMU group with one more
|
// A device with multi-funtions, or a IOMMU group with one more
|
||||||
// devices, the Primary device is selected to be passed to VM.
|
// devices, the Primary device is selected to be passed to VM.
|
||||||
// And the the first one is Primary device.
|
// And the the first one is Primary device.
|
||||||
@ -204,9 +210,15 @@ impl CloudHypervisorInner {
|
|||||||
serde_json::from_str(detail.as_str()).map_err(|e| anyhow!(e))?;
|
serde_json::from_str(detail.as_str()).map_err(|e| anyhow!(e))?;
|
||||||
self.device_ids
|
self.device_ids
|
||||||
.insert(device.device_id.clone(), dev_info.id);
|
.insert(device.device_id.clone(), dev_info.id);
|
||||||
|
|
||||||
|
// Update PCI path for the vfio host device. It is safe to directly access the slice element
|
||||||
|
// here as we have already checked if it exists.
|
||||||
|
// Todo: Handle vfio-ap mediated devices - return error for them.
|
||||||
|
vfio_device.devices[0].guest_pci_path =
|
||||||
|
Some(Self::clh_pci_info_to_path(&dev_info.bdf)?);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(DeviceType::Vfio(vfio_device))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn remove_vfio_device(&mut self, device: &VfioDevice) -> Result<()> {
|
async fn remove_vfio_device(&mut self, device: &VfioDevice) -> Result<()> {
|
||||||
@ -242,7 +254,31 @@ impl CloudHypervisorInner {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_block_device(&mut self, device: BlockDevice) -> Result<()> {
|
// Various cloud-hypervisor APIs report a PCI address in "BB:DD.F"
|
||||||
|
// form within the PciDeviceInfo struct.
|
||||||
|
// eg "0000:00:DD.F"
|
||||||
|
fn clh_pci_info_to_path(bdf: &str) -> Result<PciPath> {
|
||||||
|
let tokens: Vec<&str> = bdf.split(':').collect();
|
||||||
|
if tokens.len() != 3 || tokens[0] != "0000" || tokens[1] != "00" {
|
||||||
|
return Err(anyhow!(
|
||||||
|
"Unexpected PCI address {:?} for clh device add",
|
||||||
|
bdf
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
let toks: Vec<&str> = tokens[2].split('.').collect();
|
||||||
|
if toks.len() != 2 || toks[1] != "0" || toks[0].len() != 2 {
|
||||||
|
return Err(anyhow!(
|
||||||
|
"Unexpected PCI address {:?} for clh device add",
|
||||||
|
bdf
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
PciPath::convert_from_string(toks[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn handle_block_device(&mut self, device: BlockDevice) -> Result<DeviceType> {
|
||||||
|
let mut block_dev = device.clone();
|
||||||
let socket = self
|
let socket = self
|
||||||
.api_socket
|
.api_socket
|
||||||
.as_ref()
|
.as_ref()
|
||||||
@ -272,9 +308,10 @@ impl CloudHypervisorInner {
|
|||||||
let dev_info: PciDeviceInfo =
|
let dev_info: PciDeviceInfo =
|
||||||
serde_json::from_str(detail.as_str()).map_err(|e| anyhow!(e))?;
|
serde_json::from_str(detail.as_str()).map_err(|e| anyhow!(e))?;
|
||||||
self.device_ids.insert(device.device_id, dev_info.id);
|
self.device_ids.insert(device.device_id, dev_info.id);
|
||||||
|
block_dev.config.pci_path = Some(Self::clh_pci_info_to_path(dev_info.bdf.as_str())?);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(DeviceType::Block(block_dev))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn get_shared_devices(
|
pub(crate) async fn get_shared_devices(
|
||||||
|
@ -79,7 +79,7 @@ impl Hypervisor for CloudHypervisor {
|
|||||||
inner.save_vm().await
|
inner.save_vm().await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn add_device(&self, device: DeviceType) -> Result<()> {
|
async fn add_device(&self, device: DeviceType) -> Result<DeviceType> {
|
||||||
let mut inner = self.inner.write().await;
|
let mut inner = self.inner.write().await;
|
||||||
inner.add_device(device).await
|
inner.add_device(device).await
|
||||||
}
|
}
|
||||||
|
@ -389,7 +389,7 @@ impl VfioDevice {
|
|||||||
.get_vfio_device_vendor(&dev_bdf)
|
.get_vfio_device_vendor(&dev_bdf)
|
||||||
.context("get property device and vendor failed")?;
|
.context("get property device and vendor failed")?;
|
||||||
|
|
||||||
let mut vfio_dev = HostDevice {
|
let vfio_dev = HostDevice {
|
||||||
bus_slot_func: dev_bdf.clone(),
|
bus_slot_func: dev_bdf.clone(),
|
||||||
device_vendor: Some(dev_vendor),
|
device_vendor: Some(dev_vendor),
|
||||||
sysfs_path: vfio_dev_details.1,
|
sysfs_path: vfio_dev_details.1,
|
||||||
@ -397,18 +397,6 @@ impl VfioDevice {
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
// when vfio pci, kata-agent handles with device_options, and its
|
|
||||||
// format: "DDDD:BB:DD.F=<pcipath>"
|
|
||||||
// DDDD:BB:DD.F is the device's PCI address on host
|
|
||||||
// <pcipath> is the device's PCI path in the guest
|
|
||||||
if self.bus_mode == VfioBusMode::PCI {
|
|
||||||
let pci_path =
|
|
||||||
generate_guest_pci_path(dev_bdf.clone()).context("generate pci path failed")?;
|
|
||||||
vfio_dev.guest_pci_path = Some(pci_path.clone());
|
|
||||||
self.device_options
|
|
||||||
.push(format!("0000:{}={}", dev_bdf, pci_path.convert_to_string()));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(vfio_dev)
|
Ok(vfio_dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -493,13 +481,42 @@ impl Device for VfioDevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// do add device for vfio deivce
|
// do add device for vfio deivce
|
||||||
if let Err(e) = h.add_device(DeviceType::Vfio(self.clone())).await {
|
match h.add_device(DeviceType::Vfio(self.clone())).await {
|
||||||
self.decrease_attach_count().await?;
|
Ok(dev) => {
|
||||||
|
// Update device info with the one received from device attach
|
||||||
|
if let DeviceType::Vfio(vfio) = dev {
|
||||||
|
self.config = vfio.config;
|
||||||
|
self.devices = vfio.devices;
|
||||||
|
}
|
||||||
|
|
||||||
return Err(e);
|
if self.bus_mode == VfioBusMode::PCI {
|
||||||
|
for hostdev in self.devices.iter_mut() {
|
||||||
|
if hostdev.guest_pci_path.is_none() {
|
||||||
|
// guest_pci_path may be empty for certain hypervisors such as
|
||||||
|
// dragonball
|
||||||
|
hostdev.guest_pci_path = Some(
|
||||||
|
generate_guest_pci_path(hostdev.bus_slot_func.clone())
|
||||||
|
.map_err(|e| anyhow!("generate pci path failed: {:?}", e))?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Safe to call unwrap here because of previous assignment.
|
||||||
|
let pci_path = hostdev.guest_pci_path.clone().unwrap();
|
||||||
|
self.device_options.push(format!(
|
||||||
|
"0000:{}={}",
|
||||||
|
hostdev.bus_slot_func.clone(),
|
||||||
|
pci_path.convert_to_string()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
self.decrease_attach_count().await?;
|
||||||
|
return Err(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn detach(&mut self, h: &dyn hypervisor) -> Result<Option<u64>> {
|
async fn detach(&mut self, h: &dyn hypervisor) -> Result<Option<u64>> {
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
use crate::device::Device;
|
use crate::device::Device;
|
||||||
use crate::device::DeviceType;
|
use crate::device::DeviceType;
|
||||||
use crate::Hypervisor as hypervisor;
|
use crate::Hypervisor as hypervisor;
|
||||||
|
use crate::PciPath;
|
||||||
use anyhow::{anyhow, Context, Result};
|
use anyhow::{anyhow, Context, Result};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
|
||||||
@ -39,6 +40,9 @@ pub struct BlockConfig {
|
|||||||
/// device path in guest
|
/// device path in guest
|
||||||
pub virt_path: String,
|
pub virt_path: String,
|
||||||
|
|
||||||
|
/// pci path is the slot at which the drive is attached
|
||||||
|
pub pci_path: Option<PciPath>,
|
||||||
|
|
||||||
/// device attach count
|
/// device attach count
|
||||||
pub attach_count: u64,
|
pub attach_count: u64,
|
||||||
|
|
||||||
@ -78,11 +82,20 @@ impl Device for BlockDevice {
|
|||||||
{
|
{
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
if let Err(e) = h.add_device(DeviceType::Block(self.clone())).await {
|
|
||||||
self.decrease_attach_count().await?;
|
match h.add_device(DeviceType::Block(self.clone())).await {
|
||||||
return Err(e);
|
Ok(dev) => {
|
||||||
|
// Update device info with the one received from device attach
|
||||||
|
if let DeviceType::Block(blk) = dev {
|
||||||
|
self.config = blk.config;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
self.decrease_attach_count().await?;
|
||||||
|
return Err(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return Ok(());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn detach(&mut self, h: &dyn hypervisor) -> Result<Option<u64>> {
|
async fn detach(&mut self, h: &dyn hypervisor) -> Result<Option<u64>> {
|
||||||
|
@ -10,7 +10,7 @@ use crate::device::driver::vhost_user_blk::VhostUserBlkDevice;
|
|||||||
use crate::{
|
use crate::{
|
||||||
BlockConfig, BlockDevice, HybridVsockConfig, HybridVsockDevice, Hypervisor as hypervisor,
|
BlockConfig, BlockDevice, HybridVsockConfig, HybridVsockDevice, Hypervisor as hypervisor,
|
||||||
NetworkConfig, NetworkDevice, ShareFsDevice, ShareFsDeviceConfig, ShareFsMountConfig,
|
NetworkConfig, NetworkDevice, ShareFsDevice, ShareFsDeviceConfig, ShareFsMountConfig,
|
||||||
ShareFsMountDevice, VfioConfig, VfioDevice, VhostUserConfig, VsockConfig, VsockDevice,
|
ShareFsMountDevice, VfioConfig, VfioDevice, VhostUserConfig, VsockConfig,
|
||||||
};
|
};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
@ -31,7 +31,7 @@ pub enum DeviceConfig {
|
|||||||
HybridVsockCfg(HybridVsockConfig),
|
HybridVsockCfg(HybridVsockConfig),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum DeviceType {
|
pub enum DeviceType {
|
||||||
Block(BlockDevice),
|
Block(BlockDevice),
|
||||||
VhostUserBlk(VhostUserBlkDevice),
|
VhostUserBlk(VhostUserBlkDevice),
|
||||||
@ -40,7 +40,6 @@ pub enum DeviceType {
|
|||||||
ShareFs(ShareFsDevice),
|
ShareFs(ShareFsDevice),
|
||||||
ShareFsMount(ShareFsMountDevice),
|
ShareFsMount(ShareFsMountDevice),
|
||||||
HybridVsock(HybridVsockDevice),
|
HybridVsock(HybridVsockDevice),
|
||||||
Vsock(VsockDevice),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for DeviceType {
|
impl fmt::Display for DeviceType {
|
||||||
|
@ -74,9 +74,6 @@ impl DragonballInner {
|
|||||||
DeviceType::ShareFsMount(sharefs_mount) => self
|
DeviceType::ShareFsMount(sharefs_mount) => self
|
||||||
.add_share_fs_mount(&sharefs_mount.config)
|
.add_share_fs_mount(&sharefs_mount.config)
|
||||||
.context("add share fs mount"),
|
.context("add share fs mount"),
|
||||||
DeviceType::Vsock(_) => {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,9 +92,12 @@ impl Hypervisor for Dragonball {
|
|||||||
inner.resize_vcpu(old_vcpus, new_vcpus).await
|
inner.resize_vcpu(old_vcpus, new_vcpus).await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn add_device(&self, device: DeviceType) -> Result<()> {
|
async fn add_device(&self, device: DeviceType) -> Result<DeviceType> {
|
||||||
let mut inner = self.inner.write().await;
|
let mut inner = self.inner.write().await;
|
||||||
inner.add_device(device).await
|
match inner.add_device(device.clone()).await {
|
||||||
|
Ok(_) => Ok(device),
|
||||||
|
Err(err) => Err(err),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn remove_device(&self, device: DeviceType) -> Result<()> {
|
async fn remove_device(&self, device: DeviceType) -> Result<()> {
|
||||||
|
@ -85,7 +85,7 @@ pub trait Hypervisor: std::fmt::Debug + Send + Sync {
|
|||||||
async fn resize_vcpu(&self, old_vcpus: u32, new_vcpus: u32) -> Result<(u32, u32)>; // returns (old_vcpus, new_vcpus)
|
async fn resize_vcpu(&self, old_vcpus: u32, new_vcpus: u32) -> Result<(u32, u32)>; // returns (old_vcpus, new_vcpus)
|
||||||
|
|
||||||
// device manager
|
// device manager
|
||||||
async fn add_device(&self, device: DeviceType) -> Result<()>;
|
async fn add_device(&self, device: DeviceType) -> Result<DeviceType>;
|
||||||
async fn remove_device(&self, device: DeviceType) -> Result<()>;
|
async fn remove_device(&self, device: DeviceType) -> Result<()>;
|
||||||
|
|
||||||
// utils
|
// utils
|
||||||
|
@ -146,9 +146,9 @@ use crate::device::DeviceType;
|
|||||||
|
|
||||||
// device manager part of Hypervisor
|
// device manager part of Hypervisor
|
||||||
impl QemuInner {
|
impl QemuInner {
|
||||||
pub(crate) async fn add_device(&mut self, device: DeviceType) -> Result<()> {
|
pub(crate) async fn add_device(&mut self, device: DeviceType) -> Result<DeviceType> {
|
||||||
info!(sl!(), "QemuInner::add_device() {}", device);
|
info!(sl!(), "QemuInner::add_device() {}", device);
|
||||||
todo!()
|
Ok(device)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn remove_device(&mut self, device: DeviceType) -> Result<()> {
|
pub(crate) async fn remove_device(&mut self, device: DeviceType) -> Result<()> {
|
||||||
|
@ -74,7 +74,7 @@ impl Hypervisor for Qemu {
|
|||||||
inner.save_vm().await
|
inner.save_vm().await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn add_device(&self, device: DeviceType) -> Result<()> {
|
async fn add_device(&self, device: DeviceType) -> Result<DeviceType> {
|
||||||
let mut inner = self.inner.write().await;
|
let mut inner = self.inner.write().await;
|
||||||
inner.add_device(device).await
|
inner.add_device(device).await
|
||||||
}
|
}
|
||||||
|
@ -297,8 +297,16 @@ impl ResourceManagerInner {
|
|||||||
// create block device for kata agent,
|
// create block device for kata agent,
|
||||||
// if driver is virtio-blk-pci, the id will be pci address.
|
// if driver is virtio-blk-pci, the id will be pci address.
|
||||||
if let DeviceType::Block(device) = device_info {
|
if let DeviceType::Block(device) = device_info {
|
||||||
|
// The following would work for drivers virtio-blk-pci and mmio.
|
||||||
|
// Once scsi support is added, need to handle scsi identifiers.
|
||||||
|
let id = if let Some(pci_path) = device.config.pci_path {
|
||||||
|
pci_path.convert_to_string()
|
||||||
|
} else {
|
||||||
|
device.config.virt_path.clone()
|
||||||
|
};
|
||||||
|
|
||||||
let agent_device = Device {
|
let agent_device = Device {
|
||||||
id: device.config.virt_path.clone(),
|
id,
|
||||||
container_path: d.path.clone(),
|
container_path: d.path.clone(),
|
||||||
field_type: device.config.driver_option,
|
field_type: device.config.driver_option,
|
||||||
vm_path: device.config.virt_path,
|
vm_path: device.config.virt_path,
|
||||||
|
@ -89,9 +89,16 @@ pub(crate) async fn setup_inline_virtiofs(id: &str, h: &dyn Hypervisor) -> Resul
|
|||||||
prefetch_list_path: None,
|
prefetch_list_path: None,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
h.add_device(DeviceType::ShareFsMount(virtio_fs))
|
|
||||||
|
let result = h
|
||||||
|
.add_device(DeviceType::ShareFsMount(virtio_fs))
|
||||||
.await
|
.await
|
||||||
.with_context(|| format!("fail to attach passthrough fs {:?}", source))
|
.with_context(|| format!("fail to attach passthrough fs {:?}", source));
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Ok(_) => Ok(()),
|
||||||
|
Err(e) => Err(e),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn rafs_mount(
|
pub async fn rafs_mount(
|
||||||
|
Loading…
Reference in New Issue
Block a user