mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-06-27 15:57:09 +00:00
Merge pull request #7932 from Apokleos/wrap-virtiofs-in-dm
runtime-rs: bringing virtio-fs device in device-manager
This commit is contained in:
commit
4fd2914a33
@ -10,8 +10,8 @@ use crate::BlockDevice;
|
||||
use crate::HybridVsockDevice;
|
||||
use crate::NetworkConfig;
|
||||
use crate::PciPath;
|
||||
use crate::ShareFsConfig;
|
||||
use crate::ShareFsDevice;
|
||||
use crate::ShareFsDeviceConfig;
|
||||
use crate::VfioDevice;
|
||||
use crate::VmmState;
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
@ -108,6 +108,10 @@ impl CloudHypervisorInner {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn update_device(&mut self, _device: DeviceType) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_share_fs_device(&mut self, sharefs: ShareFsDevice) -> Result<DeviceType> {
|
||||
let device: ShareFsDevice = sharefs.clone();
|
||||
if device.config.fs_type != VIRTIO_FS {
|
||||
@ -363,12 +367,12 @@ impl TryFrom<NetworkConfig> for NetConfig {
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub struct ShareFsSettings {
|
||||
cfg: ShareFsDeviceConfig,
|
||||
cfg: ShareFsConfig,
|
||||
vm_path: String,
|
||||
}
|
||||
|
||||
impl ShareFsSettings {
|
||||
pub fn new(cfg: ShareFsDeviceConfig, vm_path: String) -> Self {
|
||||
pub fn new(cfg: ShareFsConfig, vm_path: String) -> Self {
|
||||
ShareFsSettings { cfg, vm_path }
|
||||
}
|
||||
}
|
||||
|
@ -89,6 +89,11 @@ impl Hypervisor for CloudHypervisor {
|
||||
inner.remove_device(device).await
|
||||
}
|
||||
|
||||
async fn update_device(&self, device: DeviceType) -> Result<()> {
|
||||
let mut inner = self.inner.write().await;
|
||||
inner.update_device(device).await
|
||||
}
|
||||
|
||||
async fn get_agent_socket(&self) -> Result<String> {
|
||||
let inner = self.inner.write().await;
|
||||
inner.get_agent_socket().await
|
||||
|
@ -12,8 +12,8 @@ use tokio::sync::{Mutex, RwLock};
|
||||
|
||||
use crate::{
|
||||
vhost_user_blk::VhostUserBlkDevice, BlockConfig, BlockDevice, HybridVsockDevice, Hypervisor,
|
||||
NetworkDevice, VfioDevice, VhostUserConfig, KATA_BLK_DEV_TYPE, KATA_MMIO_BLK_DEV_TYPE,
|
||||
KATA_NVDIMM_DEV_TYPE, VIRTIO_BLOCK_MMIO, VIRTIO_BLOCK_PCI, VIRTIO_PMEM,
|
||||
NetworkDevice, ShareFsDevice, VfioDevice, VhostUserConfig, KATA_BLK_DEV_TYPE,
|
||||
KATA_MMIO_BLK_DEV_TYPE, KATA_NVDIMM_DEV_TYPE, VIRTIO_BLOCK_MMIO, VIRTIO_BLOCK_PCI, VIRTIO_PMEM,
|
||||
};
|
||||
|
||||
use super::{
|
||||
@ -226,6 +226,11 @@ impl DeviceManager {
|
||||
return Some(device_id.to_string());
|
||||
}
|
||||
}
|
||||
DeviceType::ShareFs(device) => {
|
||||
if device.config.host_shared_path == host_path {
|
||||
return Some(device_id.to_string());
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
// TODO: support find other device type
|
||||
continue;
|
||||
@ -325,6 +330,22 @@ impl DeviceManager {
|
||||
// No need to do find device for hybrid vsock device.
|
||||
Arc::new(Mutex::new(HybridVsockDevice::new(&device_id, hvconfig)))
|
||||
}
|
||||
DeviceConfig::ShareFsCfg(config) => {
|
||||
// Try to find the sharefs device. If found, just return matched device id.
|
||||
if let Some(device_id_matched) =
|
||||
self.find_device(config.host_shared_path.clone()).await
|
||||
{
|
||||
info!(
|
||||
sl!(),
|
||||
"share-fs device with path:{:?} found, device id: {:?}",
|
||||
config.host_shared_path,
|
||||
device_id_matched
|
||||
);
|
||||
return Ok(device_id_matched);
|
||||
}
|
||||
|
||||
Arc::new(Mutex::new(ShareFsDevice::new(&device_id, config)))
|
||||
}
|
||||
_ => {
|
||||
return Err(anyhow!("invliad device type"));
|
||||
}
|
||||
@ -437,6 +458,62 @@ impl DeviceManager {
|
||||
|
||||
Err(anyhow!("ID are exhausted"))
|
||||
}
|
||||
|
||||
async fn try_update_device(&mut self, updated_config: &DeviceConfig) -> Result<()> {
|
||||
let device_id = match updated_config {
|
||||
DeviceConfig::ShareFsCfg(config) => {
|
||||
// Try to find the sharefs device.
|
||||
// If found, just return the matched device id, otherwise return an error.
|
||||
if let Some(device_id_matched) =
|
||||
self.find_device(config.host_shared_path.clone()).await
|
||||
{
|
||||
device_id_matched
|
||||
} else {
|
||||
return Err(anyhow!(
|
||||
"no matching device was found to do the update operation"
|
||||
));
|
||||
}
|
||||
}
|
||||
// TODO for other Device Type
|
||||
_ => {
|
||||
return Err(anyhow!("update device with unsupported device type"));
|
||||
}
|
||||
};
|
||||
|
||||
// get the original device
|
||||
let target_device = self
|
||||
.get_device_info(&device_id)
|
||||
.await
|
||||
.context("get device failed")?;
|
||||
|
||||
// update device with the updated configuration.
|
||||
let updated_device: ArcMutexDevice = match target_device {
|
||||
DeviceType::ShareFs(mut device) => {
|
||||
if let DeviceConfig::ShareFsCfg(config) = updated_config {
|
||||
// update the mount_config.
|
||||
device.config.mount_config = config.mount_config.clone();
|
||||
}
|
||||
Arc::new(Mutex::new(device))
|
||||
}
|
||||
_ => return Err(anyhow!("update unsupported device type")),
|
||||
};
|
||||
|
||||
// do handle update
|
||||
if let Err(e) = updated_device
|
||||
.lock()
|
||||
.await
|
||||
.update(self.hypervisor.as_ref())
|
||||
.await
|
||||
{
|
||||
debug!(sl!(), "update device with device id: {:?}", &device_id);
|
||||
return Err(e);
|
||||
}
|
||||
|
||||
// Finally, we update the Map in Device Manager
|
||||
self.devices.insert(device_id, updated_device);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// Many scenarios have similar steps when adding devices. so to reduce duplicated code,
|
||||
@ -472,6 +549,19 @@ pub async fn do_handle_device(
|
||||
Ok(device_info)
|
||||
}
|
||||
|
||||
pub async fn do_update_device(
|
||||
d: &RwLock<DeviceManager>,
|
||||
updated_config: &DeviceConfig,
|
||||
) -> Result<()> {
|
||||
d.write()
|
||||
.await
|
||||
.try_update_device(updated_config)
|
||||
.await
|
||||
.context("failed to update device")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn get_block_driver(d: &RwLock<DeviceManager>) -> String {
|
||||
d.read().await.get_block_driver().await
|
||||
}
|
||||
|
@ -20,8 +20,7 @@ pub use virtio_blk::{
|
||||
VIRTIO_BLOCK_MMIO, VIRTIO_BLOCK_PCI, VIRTIO_PMEM,
|
||||
};
|
||||
pub use virtio_fs::{
|
||||
ShareFsDevice, ShareFsDeviceConfig, ShareFsMountConfig, ShareFsMountDevice, ShareFsMountType,
|
||||
ShareFsOperation,
|
||||
ShareFsConfig, ShareFsDevice, ShareFsMountConfig, ShareFsMountOperation, ShareFsMountType,
|
||||
};
|
||||
pub use virtio_net::{Address, Backend, NetworkConfig, NetworkDevice};
|
||||
pub use virtio_vsock::{
|
||||
|
@ -543,6 +543,11 @@ impl Device for VfioDevice {
|
||||
Ok(device_index)
|
||||
}
|
||||
|
||||
async fn update(&mut self, _h: &dyn hypervisor) -> Result<()> {
|
||||
// There's no need to do update for vfio device
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn increase_attach_count(&mut self) -> Result<bool> {
|
||||
match self.attach_count {
|
||||
0 => {
|
||||
|
@ -86,6 +86,11 @@ impl Device for VhostUserBlkDevice {
|
||||
Ok(Some(self.config.index))
|
||||
}
|
||||
|
||||
async fn update(&mut self, _h: &dyn hypervisor) -> Result<()> {
|
||||
// There's no need to do update for vhost-user-blk
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_device_info(&self) -> DeviceType {
|
||||
DeviceType::VhostUserBlk(self.clone())
|
||||
}
|
||||
|
@ -114,6 +114,11 @@ impl Device for BlockDevice {
|
||||
Ok(Some(self.config.index))
|
||||
}
|
||||
|
||||
async fn update(&mut self, _h: &dyn hypervisor) -> Result<()> {
|
||||
// There's no need to do update for virtio-blk
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_device_info(&self) -> DeviceType {
|
||||
DeviceType::Block(self.clone())
|
||||
}
|
||||
|
@ -4,21 +4,28 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum ShareFsOperation {
|
||||
use anyhow::{Context, Result};
|
||||
use async_trait::async_trait;
|
||||
|
||||
use crate::device::{hypervisor, Device, DeviceType};
|
||||
|
||||
#[derive(Copy, Clone, Debug, Default)]
|
||||
pub enum ShareFsMountOperation {
|
||||
#[default]
|
||||
Mount,
|
||||
Umount,
|
||||
Update,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub enum ShareFsMountType {
|
||||
#[default]
|
||||
PASSTHROUGH,
|
||||
RAFS,
|
||||
}
|
||||
|
||||
/// ShareFsMountConfig: share fs mount config
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct ShareFsMountConfig {
|
||||
/// source: the passthrough fs exported dir or rafs meta file of rafs
|
||||
pub source: String,
|
||||
@ -36,20 +43,19 @@ pub struct ShareFsMountConfig {
|
||||
pub tag: String,
|
||||
|
||||
/// op: the operation to take, e.g. mount, umount or update
|
||||
pub op: ShareFsOperation,
|
||||
pub op: ShareFsMountOperation,
|
||||
|
||||
/// prefetch_list_path: path to file that contains file lists that should be prefetched by rafs
|
||||
pub prefetch_list_path: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ShareFsMountDevice {
|
||||
pub config: ShareFsMountConfig,
|
||||
}
|
||||
/// ShareFsConfig: Sharefs config for virtio-fs devices and their corresponding mount configurations,
|
||||
/// facilitating mount/umount/update operations.
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct ShareFsConfig {
|
||||
/// host_shared_path: the upperdir of the passthrough fs exported dir or rafs meta file of rafs
|
||||
pub host_shared_path: String,
|
||||
|
||||
/// ShareFsDeviceConfig: share fs device config
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ShareFsDeviceConfig {
|
||||
/// fs_type: virtiofs or inline-virtiofs
|
||||
pub fs_type: String,
|
||||
|
||||
@ -59,9 +65,6 @@ pub struct ShareFsDeviceConfig {
|
||||
/// mount_tag: a label used as a hint to the guest.
|
||||
pub mount_tag: String,
|
||||
|
||||
/// host_path: the host filesystem path for this volume.
|
||||
pub host_path: String,
|
||||
|
||||
/// queue_size: queue size
|
||||
pub queue_size: u64,
|
||||
|
||||
@ -70,9 +73,65 @@ pub struct ShareFsDeviceConfig {
|
||||
|
||||
/// options: virtiofs device's config options.
|
||||
pub options: Vec<String>,
|
||||
|
||||
/// mount config for sharefs mount/umount/update
|
||||
pub mount_config: Option<ShareFsMountConfig>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct ShareFsDevice {
|
||||
pub config: ShareFsDeviceConfig,
|
||||
/// device id for sharefs device in device manager
|
||||
pub device_id: String,
|
||||
|
||||
/// config for sharefs device
|
||||
pub config: ShareFsConfig,
|
||||
}
|
||||
|
||||
impl ShareFsDevice {
|
||||
// new creates a share-fs device
|
||||
pub fn new(device_id: &str, config: &ShareFsConfig) -> Self {
|
||||
Self {
|
||||
device_id: device_id.to_string(),
|
||||
config: config.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl Device for ShareFsDevice {
|
||||
async fn attach(&mut self, h: &dyn hypervisor) -> Result<()> {
|
||||
h.add_device(DeviceType::ShareFs(self.clone()))
|
||||
.await
|
||||
.context("add share-fs device.")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn detach(&mut self, _h: &dyn hypervisor) -> Result<Option<u64>> {
|
||||
// no need to detach share-fs device
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
async fn update(&mut self, h: &dyn hypervisor) -> Result<()> {
|
||||
h.update_device(DeviceType::ShareFs(self.clone()))
|
||||
.await
|
||||
.context("update share-fs device.")
|
||||
}
|
||||
|
||||
async fn get_device_info(&self) -> DeviceType {
|
||||
DeviceType::ShareFs(self.clone())
|
||||
}
|
||||
|
||||
async fn increase_attach_count(&mut self) -> Result<bool> {
|
||||
// share-fs devices will not be attached multiple times, Just return Ok(false)
|
||||
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
async fn decrease_attach_count(&mut self) -> Result<bool> {
|
||||
// share-fs devices will not be detached multiple times, Just return Ok(false)
|
||||
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
|
@ -95,6 +95,11 @@ impl Device for NetworkDevice {
|
||||
Ok(Some(self.config.index))
|
||||
}
|
||||
|
||||
async fn update(&mut self, _h: &dyn hypervisor) -> Result<()> {
|
||||
// There's no need to do update for network device
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_device_info(&self) -> DeviceType {
|
||||
DeviceType::Network(self.clone())
|
||||
}
|
||||
|
@ -62,6 +62,11 @@ impl Device for HybridVsockDevice {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
async fn update(&mut self, _h: &dyn hypervisor) -> Result<()> {
|
||||
// There's no need to do update for hvsock device
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_device_info(&self) -> DeviceType {
|
||||
DeviceType::HybridVsock(self.clone())
|
||||
}
|
||||
|
@ -9,8 +9,8 @@ use std::fmt;
|
||||
use crate::device::driver::vhost_user_blk::VhostUserBlkDevice;
|
||||
use crate::{
|
||||
BlockConfig, BlockDevice, HybridVsockConfig, HybridVsockDevice, Hypervisor as hypervisor,
|
||||
NetworkConfig, NetworkDevice, ShareFsDevice, ShareFsDeviceConfig, ShareFsMountConfig,
|
||||
ShareFsMountDevice, VfioConfig, VfioDevice, VhostUserConfig, VsockConfig,
|
||||
NetworkConfig, NetworkDevice, ShareFsConfig, ShareFsDevice, VfioConfig, VfioDevice,
|
||||
VhostUserConfig, VsockConfig,
|
||||
};
|
||||
use anyhow::Result;
|
||||
use async_trait::async_trait;
|
||||
@ -24,9 +24,8 @@ pub enum DeviceConfig {
|
||||
BlockCfg(BlockConfig),
|
||||
VhostUserBlkCfg(VhostUserConfig),
|
||||
NetworkCfg(NetworkConfig),
|
||||
ShareFsCfg(ShareFsDeviceConfig),
|
||||
ShareFsCfg(ShareFsConfig),
|
||||
VfioCfg(VfioConfig),
|
||||
ShareFsMountCfg(ShareFsMountConfig),
|
||||
VsockCfg(VsockConfig),
|
||||
HybridVsockCfg(HybridVsockConfig),
|
||||
}
|
||||
@ -38,7 +37,6 @@ pub enum DeviceType {
|
||||
Vfio(VfioDevice),
|
||||
Network(NetworkDevice),
|
||||
ShareFs(ShareFsDevice),
|
||||
ShareFsMount(ShareFsMountDevice),
|
||||
HybridVsock(HybridVsockDevice),
|
||||
}
|
||||
|
||||
@ -54,6 +52,8 @@ pub trait Device: std::fmt::Debug + Send + Sync {
|
||||
async fn attach(&mut self, h: &dyn hypervisor) -> Result<()>;
|
||||
// detach is to unplug device from VM
|
||||
async fn detach(&mut self, h: &dyn hypervisor) -> Result<Option<u64>>;
|
||||
// update is to do update for some device
|
||||
async fn update(&mut self, h: &dyn hypervisor) -> Result<()>;
|
||||
// get_device_info returns device config
|
||||
async fn get_device_info(&self) -> DeviceType;
|
||||
// increase_attach_count is used to increase the attach count for a device
|
||||
|
@ -14,8 +14,8 @@ use dragonball::device_manager::blk_dev_mgr::BlockDeviceType;
|
||||
|
||||
use super::DragonballInner;
|
||||
use crate::{
|
||||
device::DeviceType, HybridVsockConfig, NetworkConfig, ShareFsDeviceConfig, ShareFsMountConfig,
|
||||
ShareFsMountType, ShareFsOperation, VfioBusMode, VfioDevice, VmmState, JAILER_ROOT,
|
||||
device::DeviceType, HybridVsockConfig, NetworkConfig, ShareFsConfig, ShareFsMountConfig,
|
||||
ShareFsMountOperation, ShareFsMountType, VfioBusMode, VfioDevice, VmmState, JAILER_ROOT,
|
||||
};
|
||||
|
||||
const MB_TO_B: u32 = 1024 * 1024;
|
||||
@ -67,9 +67,6 @@ impl DragonballInner {
|
||||
DeviceType::ShareFs(sharefs) => self
|
||||
.add_share_fs_device(&sharefs.config)
|
||||
.context("add share fs device"),
|
||||
DeviceType::ShareFsMount(sharefs_mount) => self
|
||||
.add_share_fs_mount(&sharefs_mount.config)
|
||||
.context("add share fs mount"),
|
||||
}
|
||||
}
|
||||
|
||||
@ -101,6 +98,18 @@ impl DragonballInner {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn update_device(&mut self, device: DeviceType) -> Result<()> {
|
||||
info!(sl!(), "dragonball update device {:?}", &device);
|
||||
match device {
|
||||
DeviceType::ShareFs(sharefs_mount) => {
|
||||
// It's safe to unwrap mount config as mount_config is always there.
|
||||
self.add_share_fs_mount(&sharefs_mount.config.mount_config.unwrap())
|
||||
.context("update share-fs device with mount operation.")
|
||||
}
|
||||
_ => Err(anyhow!("unsupported device {:?} to update.", device)),
|
||||
}
|
||||
}
|
||||
|
||||
fn add_vfio_device(&mut self, device: &VfioDevice) -> Result<()> {
|
||||
let vfio_device = device.clone();
|
||||
|
||||
@ -285,7 +294,7 @@ impl DragonballInner {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn add_share_fs_device(&self, config: &ShareFsDeviceConfig) -> Result<()> {
|
||||
fn add_share_fs_device(&self, config: &ShareFsConfig) -> Result<()> {
|
||||
let mut fs_cfg = FsDeviceConfigInfo {
|
||||
sock_path: config.sock_path.clone(),
|
||||
tag: config.mount_tag.clone(),
|
||||
@ -337,9 +346,9 @@ impl DragonballInner {
|
||||
|
||||
fn add_share_fs_mount(&mut self, config: &ShareFsMountConfig) -> Result<()> {
|
||||
let ops = match config.op {
|
||||
ShareFsOperation::Mount => "mount",
|
||||
ShareFsOperation::Umount => "umount",
|
||||
ShareFsOperation::Update => "update",
|
||||
ShareFsMountOperation::Mount => "mount",
|
||||
ShareFsMountOperation::Umount => "umount",
|
||||
ShareFsMountOperation::Update => "update",
|
||||
};
|
||||
|
||||
let fstype = match config.fstype {
|
||||
|
@ -110,6 +110,11 @@ impl Hypervisor for Dragonball {
|
||||
inner.remove_device(device).await
|
||||
}
|
||||
|
||||
async fn update_device(&self, device: DeviceType) -> Result<()> {
|
||||
let mut inner = self.inner.write().await;
|
||||
inner.update_device(device).await
|
||||
}
|
||||
|
||||
async fn get_agent_socket(&self) -> Result<String> {
|
||||
let inner = self.inner.read().await;
|
||||
inner.get_agent_socket().await
|
||||
|
@ -26,7 +26,7 @@ use nix::sched::{setns, CloneFlags};
|
||||
use seccompiler::BpfProgram;
|
||||
use vmm_sys_util::eventfd::EventFd;
|
||||
|
||||
use crate::ShareFsOperation;
|
||||
use crate::ShareFsMountOperation;
|
||||
|
||||
pub enum Request {
|
||||
Sync(VmmAction),
|
||||
@ -238,7 +238,7 @@ impl VmmInstance {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn patch_fs(&self, cfg: &FsMountConfigInfo, op: ShareFsOperation) -> Result<()> {
|
||||
pub fn patch_fs(&self, cfg: &FsMountConfigInfo, op: ShareFsMountOperation) -> Result<()> {
|
||||
self.handle_request(Request::Sync(VmmAction::ManipulateFsBackendFs(cfg.clone())))
|
||||
.with_context(|| {
|
||||
format!(
|
||||
|
@ -87,6 +87,7 @@ pub trait Hypervisor: std::fmt::Debug + Send + Sync {
|
||||
// device manager
|
||||
async fn add_device(&self, device: DeviceType) -> Result<DeviceType>;
|
||||
async fn remove_device(&self, device: DeviceType) -> Result<()>;
|
||||
async fn update_device(&self, device: DeviceType) -> Result<()>;
|
||||
|
||||
// utils
|
||||
async fn get_agent_socket(&self) -> Result<String>;
|
||||
|
@ -155,4 +155,10 @@ impl QemuInner {
|
||||
info!(sl!(), "QemuInner::remove_device() {} ", device);
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub(crate) async fn update_device(&mut self, device: DeviceType) -> Result<()> {
|
||||
info!(sl!(), "QemuInner::update_device() {:?}", &device);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -84,6 +84,11 @@ impl Hypervisor for Qemu {
|
||||
inner.remove_device(device).await
|
||||
}
|
||||
|
||||
async fn update_device(&self, device: DeviceType) -> Result<()> {
|
||||
let mut inner = self.inner.write().await;
|
||||
inner.update_device(device).await
|
||||
}
|
||||
|
||||
async fn get_agent_socket(&self) -> Result<String> {
|
||||
let inner = self.inner.read().await;
|
||||
inner.get_agent_socket().await
|
||||
|
@ -102,7 +102,10 @@ impl ResourceManagerInner {
|
||||
{
|
||||
let share_fs = share_fs::new(&self.sid, &c).context("new share fs")?;
|
||||
share_fs
|
||||
.setup_device_before_start_vm(self.hypervisor.as_ref())
|
||||
.setup_device_before_start_vm(
|
||||
self.hypervisor.as_ref(),
|
||||
&self.device_manager,
|
||||
)
|
||||
.await
|
||||
.context("setup share fs device before start vm")?;
|
||||
|
||||
@ -212,7 +215,7 @@ impl ResourceManagerInner {
|
||||
pub async fn setup_after_start_vm(&mut self) -> Result<()> {
|
||||
if let Some(share_fs) = self.share_fs.as_ref() {
|
||||
share_fs
|
||||
.setup_device_after_start_vm(self.hypervisor.as_ref())
|
||||
.setup_device_after_start_vm(self.hypervisor.as_ref(), &self.device_manager)
|
||||
.await
|
||||
.context("setup share fs device after start vm")?;
|
||||
}
|
||||
@ -227,6 +230,7 @@ impl ResourceManagerInner {
|
||||
.context("handle neighbors")?;
|
||||
self.handle_routes(network).await.context("handle routes")?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@ use self::{block_rootfs::is_block_rootfs, nydus_rootfs::NYDUS_ROOTFS_TYPE};
|
||||
const ROOTFS: &str = "rootfs";
|
||||
const HYBRID_ROOTFS_LOWER_DIR: &str = "rootfs_lower";
|
||||
const TYPE_OVERLAY_FS: &str = "overlay";
|
||||
|
||||
#[async_trait]
|
||||
pub trait Rootfs: Send + Sync {
|
||||
async fn get_guest_rootfs_path(&self) -> Result<String>;
|
||||
@ -102,9 +103,16 @@ impl RootFsResource {
|
||||
// handle nydus rootfs
|
||||
let share_rootfs: Arc<dyn Rootfs> = if layer.fs_type == NYDUS_ROOTFS_TYPE {
|
||||
Arc::new(
|
||||
nydus_rootfs::NydusRootfs::new(share_fs, h, sid, cid, layer)
|
||||
.await
|
||||
.context("new nydus rootfs")?,
|
||||
nydus_rootfs::NydusRootfs::new(
|
||||
device_manager,
|
||||
share_fs,
|
||||
h,
|
||||
sid,
|
||||
cid,
|
||||
layer,
|
||||
)
|
||||
.await
|
||||
.context("new nydus rootfs")?,
|
||||
)
|
||||
}
|
||||
// handle sharefs rootfs
|
||||
|
@ -39,6 +39,7 @@ pub(crate) struct NydusRootfs {
|
||||
|
||||
impl NydusRootfs {
|
||||
pub async fn new(
|
||||
d: &RwLock<DeviceManager>,
|
||||
share_fs: &Arc<dyn ShareFs>,
|
||||
h: &dyn Hypervisor,
|
||||
sid: &str,
|
||||
@ -61,7 +62,8 @@ impl NydusRootfs {
|
||||
// rafs mount the metadata of nydus rootfs
|
||||
let rafs_mnt = do_get_guest_share_path(HYBRID_ROOTFS_LOWER_DIR, cid, true);
|
||||
rafs_mount(
|
||||
h,
|
||||
d,
|
||||
sid,
|
||||
rafs_meta.to_string(),
|
||||
rafs_mnt,
|
||||
extra_options.config.clone(),
|
||||
|
@ -22,12 +22,15 @@ pub mod sandbox_bind_mounts;
|
||||
|
||||
use std::{collections::HashMap, fmt::Debug, path::PathBuf, sync::Arc};
|
||||
|
||||
use agent::Storage;
|
||||
use anyhow::{anyhow, Context, Ok, Result};
|
||||
use async_trait::async_trait;
|
||||
use hypervisor::Hypervisor;
|
||||
use tokio::sync::RwLock;
|
||||
|
||||
use agent::Storage;
|
||||
use kata_types::config::hypervisor::SharedFsInfo;
|
||||
|
||||
use hypervisor::{device::device_manager::DeviceManager, Hypervisor};
|
||||
|
||||
const VIRTIO_FS: &str = "virtio-fs";
|
||||
const _VIRTIO_FS_NYDUS: &str = "virtio-fs-nydus";
|
||||
const INLINE_VIRTIO_FS: &str = "inline-virtio-fs";
|
||||
@ -45,8 +48,16 @@ const RAFS_DIR: &str = "rafs";
|
||||
#[async_trait]
|
||||
pub trait ShareFs: Send + Sync {
|
||||
fn get_share_fs_mount(&self) -> Arc<dyn ShareFsMount>;
|
||||
async fn setup_device_before_start_vm(&self, h: &dyn Hypervisor) -> Result<()>;
|
||||
async fn setup_device_after_start_vm(&self, h: &dyn Hypervisor) -> Result<()>;
|
||||
async fn setup_device_before_start_vm(
|
||||
&self,
|
||||
h: &dyn Hypervisor,
|
||||
d: &RwLock<DeviceManager>,
|
||||
) -> Result<()>;
|
||||
async fn setup_device_after_start_vm(
|
||||
&self,
|
||||
h: &dyn Hypervisor,
|
||||
d: &RwLock<DeviceManager>,
|
||||
) -> Result<()>;
|
||||
async fn get_storages(&self) -> Result<Vec<Storage>>;
|
||||
fn mounted_info_set(&self) -> Arc<Mutex<HashMap<String, MountedInfo>>>;
|
||||
}
|
||||
|
@ -7,18 +7,18 @@
|
||||
use std::path::Path;
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use nix::mount::MsFlags;
|
||||
use tokio::sync::RwLock;
|
||||
|
||||
use hypervisor::{
|
||||
device::{
|
||||
driver::{
|
||||
ShareFsDevice, ShareFsMountConfig, ShareFsMountDevice, ShareFsMountType,
|
||||
ShareFsOperation,
|
||||
},
|
||||
DeviceType,
|
||||
device_manager::{do_handle_device, do_update_device, DeviceManager},
|
||||
driver::{ShareFsMountConfig, ShareFsMountOperation, ShareFsMountType},
|
||||
DeviceConfig,
|
||||
},
|
||||
Hypervisor, ShareFsDeviceConfig,
|
||||
ShareFsConfig,
|
||||
};
|
||||
use kata_sys_util::mount;
|
||||
use nix::mount::MsFlags;
|
||||
|
||||
use super::{utils, PASSTHROUGH_FS_DIR};
|
||||
|
||||
@ -35,7 +35,7 @@ pub(crate) fn generate_sock_path(root: &str) -> String {
|
||||
}
|
||||
|
||||
pub(crate) async fn prepare_virtiofs(
|
||||
h: &dyn Hypervisor,
|
||||
d: &RwLock<DeviceManager>,
|
||||
fs_type: &str,
|
||||
id: &str,
|
||||
root: &str,
|
||||
@ -49,24 +49,26 @@ pub(crate) async fn prepare_virtiofs(
|
||||
mount::bind_mount_unchecked(&host_rw_dest, &host_ro_dest, true, MsFlags::MS_SLAVE)
|
||||
.context("bind mount shared_fs directory")?;
|
||||
|
||||
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,
|
||||
options: vec![],
|
||||
},
|
||||
let sharefs_config = ShareFsConfig {
|
||||
host_shared_path: host_ro_dest.display().to_string(),
|
||||
sock_path: generate_sock_path(root),
|
||||
mount_tag: String::from(MOUNT_GUEST_TAG),
|
||||
fs_type: fs_type.to_string(),
|
||||
queue_size: 0,
|
||||
queue_num: 0,
|
||||
options: vec![],
|
||||
mount_config: None,
|
||||
};
|
||||
h.add_device(DeviceType::ShareFs(share_fs_device))
|
||||
|
||||
// create and insert virtio-fs device into Guest
|
||||
do_handle_device(d, &DeviceConfig::ShareFsCfg(sharefs_config))
|
||||
.await
|
||||
.context("add device")?;
|
||||
.context("do add virtio-fs device failed.")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn setup_inline_virtiofs(id: &str, h: &dyn Hypervisor) -> Result<()> {
|
||||
pub(crate) async fn setup_inline_virtiofs(d: &RwLock<DeviceManager>, id: &str) -> Result<()> {
|
||||
// - source is the absolute path of PASSTHROUGH_FS_DIR on host, e.g.
|
||||
// /run/kata-containers/shared/sandboxes/<sid>/passthrough
|
||||
// - mount point is the path relative to KATA_GUEST_SHARE_DIR in guest
|
||||
@ -75,34 +77,39 @@ pub(crate) async fn setup_inline_virtiofs(id: &str, h: &dyn Hypervisor) -> Resul
|
||||
let rw_source = utils::get_host_rw_shared_path(id).join(PASSTHROUGH_FS_DIR);
|
||||
utils::ensure_dir_exist(&rw_source).context("ensure directory exist")?;
|
||||
|
||||
let ro_source = utils::get_host_ro_shared_path(id).join(PASSTHROUGH_FS_DIR);
|
||||
let source = String::from(ro_source.to_str().unwrap());
|
||||
let host_ro_shared_path = utils::get_host_ro_shared_path(id);
|
||||
let source = host_ro_shared_path
|
||||
.join(PASSTHROUGH_FS_DIR)
|
||||
.display()
|
||||
.to_string();
|
||||
|
||||
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,
|
||||
},
|
||||
let virtiofs_mount = ShareFsMountConfig {
|
||||
source: source.clone(),
|
||||
fstype: ShareFsMountType::PASSTHROUGH,
|
||||
mount_point: mnt,
|
||||
config: None,
|
||||
tag: String::from(MOUNT_GUEST_TAG),
|
||||
op: ShareFsMountOperation::Mount,
|
||||
prefetch_list_path: None,
|
||||
};
|
||||
|
||||
let result = h
|
||||
.add_device(DeviceType::ShareFsMount(virtio_fs))
|
||||
.await
|
||||
.with_context(|| format!("fail to attach passthrough fs {:?}", source));
|
||||
let sharefs_config = ShareFsConfig {
|
||||
host_shared_path: host_ro_shared_path.display().to_string(),
|
||||
mount_config: Some(virtiofs_mount),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
match result {
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
// update virtio-fs device with ShareFsMountConfig
|
||||
do_update_device(d, &DeviceConfig::ShareFsCfg(sharefs_config))
|
||||
.await
|
||||
.context("fail to attach passthrough fs.")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn rafs_mount(
|
||||
h: &dyn Hypervisor,
|
||||
d: &RwLock<DeviceManager>,
|
||||
sid: &str,
|
||||
rafs_meta: String,
|
||||
rafs_mnt: String,
|
||||
config_content: String,
|
||||
@ -112,19 +119,28 @@ pub async fn rafs_mount(
|
||||
sl!(),
|
||||
"Attaching rafs meta file {} to virtio-fs device, rafs mount point {}", rafs_meta, rafs_mnt
|
||||
);
|
||||
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,
|
||||
},
|
||||
|
||||
let rafs_config = ShareFsMountConfig {
|
||||
source: rafs_meta.clone(),
|
||||
fstype: ShareFsMountType::RAFS,
|
||||
mount_point: rafs_mnt,
|
||||
config: Some(config_content),
|
||||
tag: String::from(MOUNT_GUEST_TAG),
|
||||
op: ShareFsMountOperation::Mount,
|
||||
prefetch_list_path,
|
||||
};
|
||||
h.add_device(DeviceType::ShareFsMount(virtio_fs))
|
||||
|
||||
let host_shared_path = utils::get_host_ro_shared_path(sid).display().to_string();
|
||||
let sharefs_config = ShareFsConfig {
|
||||
host_shared_path,
|
||||
mount_config: Some(rafs_config),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
// update virtio-fs device with ShareFsMountConfig
|
||||
do_update_device(d, &DeviceConfig::ShareFsCfg(sharefs_config))
|
||||
.await
|
||||
.with_context(|| format!("fail to attach rafs {:?}", rafs_meta))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -6,12 +6,13 @@
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use agent::Storage;
|
||||
use anyhow::{Context, Result};
|
||||
use async_trait::async_trait;
|
||||
use hypervisor::Hypervisor;
|
||||
use tokio::sync::{Mutex, RwLock};
|
||||
|
||||
use agent::Storage;
|
||||
use hypervisor::{device::device_manager::DeviceManager, Hypervisor};
|
||||
use kata_types::config::hypervisor::SharedFsInfo;
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
use super::{
|
||||
share_virtio_fs::{
|
||||
@ -52,19 +53,30 @@ impl ShareFs for ShareVirtioFsInline {
|
||||
self.share_fs_mount.clone()
|
||||
}
|
||||
|
||||
async fn setup_device_before_start_vm(&self, h: &dyn Hypervisor) -> Result<()> {
|
||||
prepare_virtiofs(h, INLINE_VIRTIO_FS, &self.config.id, "")
|
||||
async fn setup_device_before_start_vm(
|
||||
&self,
|
||||
_h: &dyn Hypervisor,
|
||||
d: &RwLock<DeviceManager>,
|
||||
) -> Result<()> {
|
||||
prepare_virtiofs(d, INLINE_VIRTIO_FS, &self.config.id, "")
|
||||
.await
|
||||
.context("prepare virtiofs")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn setup_device_after_start_vm(&self, h: &dyn Hypervisor) -> Result<()> {
|
||||
setup_inline_virtiofs(&self.config.id, h)
|
||||
async fn setup_device_after_start_vm(
|
||||
&self,
|
||||
_h: &dyn Hypervisor,
|
||||
d: &RwLock<DeviceManager>,
|
||||
) -> Result<()> {
|
||||
setup_inline_virtiofs(d, &self.config.id)
|
||||
.await
|
||||
.context("setup inline virtiofs")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_storages(&self) -> Result<Vec<Storage>> {
|
||||
// setup storage
|
||||
let mut storages: Vec<Storage> = Vec::new();
|
||||
|
@ -6,15 +6,8 @@
|
||||
|
||||
use std::{collections::HashMap, process::Stdio, sync::Arc};
|
||||
|
||||
use crate::share_fs::share_virtio_fs::{
|
||||
prepare_virtiofs, FS_TYPE_VIRTIO_FS, KATA_VIRTIO_FS_DEV_TYPE, MOUNT_GUEST_TAG,
|
||||
};
|
||||
use crate::share_fs::{KATA_GUEST_SHARE_DIR, VIRTIO_FS};
|
||||
use agent::Storage;
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use async_trait::async_trait;
|
||||
use hypervisor::Hypervisor;
|
||||
use kata_types::config::hypervisor::SharedFsInfo;
|
||||
use tokio::{
|
||||
io::{AsyncBufReadExt, BufReader},
|
||||
process::{Child, Command},
|
||||
@ -24,10 +17,20 @@ use tokio::{
|
||||
},
|
||||
};
|
||||
|
||||
use agent::Storage;
|
||||
use hypervisor::{device::device_manager::DeviceManager, Hypervisor};
|
||||
use kata_types::config::hypervisor::SharedFsInfo;
|
||||
|
||||
use super::{
|
||||
share_virtio_fs::generate_sock_path, utils::ensure_dir_exist, utils::get_host_ro_shared_path,
|
||||
virtio_fs_share_mount::VirtiofsShareMount, MountedInfo, ShareFs, ShareFsMount,
|
||||
};
|
||||
use crate::share_fs::{
|
||||
share_virtio_fs::{
|
||||
prepare_virtiofs, FS_TYPE_VIRTIO_FS, KATA_VIRTIO_FS_DEV_TYPE, MOUNT_GUEST_TAG,
|
||||
},
|
||||
KATA_GUEST_SHARE_DIR, VIRTIO_FS,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ShareVirtioFsStandaloneConfig {
|
||||
@ -172,15 +175,24 @@ impl ShareFs for ShareVirtioFsStandalone {
|
||||
self.share_fs_mount.clone()
|
||||
}
|
||||
|
||||
async fn setup_device_before_start_vm(&self, h: &dyn Hypervisor) -> Result<()> {
|
||||
prepare_virtiofs(h, VIRTIO_FS, &self.config.id, &h.get_jailer_root().await?)
|
||||
async fn setup_device_before_start_vm(
|
||||
&self,
|
||||
h: &dyn Hypervisor,
|
||||
d: &RwLock<DeviceManager>,
|
||||
) -> Result<()> {
|
||||
prepare_virtiofs(d, VIRTIO_FS, &self.config.id, &h.get_jailer_root().await?)
|
||||
.await
|
||||
.context("prepare virtiofs")?;
|
||||
self.setup_virtiofsd(h).await.context("setup virtiofsd")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn setup_device_after_start_vm(&self, _h: &dyn Hypervisor) -> Result<()> {
|
||||
async fn setup_device_after_start_vm(
|
||||
&self,
|
||||
_h: &dyn Hypervisor,
|
||||
_d: &RwLock<DeviceManager>,
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user