runtime-rs: add resize_memory trait for hypervisor

Fixes: #6875
Signed-off-by: Zhongtao Hu <zhongtaohu.tim@linux.alibaba.com>
This commit is contained in:
Zhongtao Hu 2023-05-17 14:38:55 +08:00
parent d428a3f9b9
commit 81e55c424a
9 changed files with 138 additions and 10 deletions

View File

@ -35,7 +35,7 @@ kata-types = { path = "../../../libs/kata-types" }
logging = { path = "../../../libs/logging" } logging = { path = "../../../libs/logging" }
shim-interface = { path = "../../../libs/shim-interface" } shim-interface = { path = "../../../libs/shim-interface" }
dragonball = { path = "../../../dragonball", features = ["atomic-guest-memory", "virtio-vsock", "hotplug", "virtio-blk", "virtio-net", "virtio-fs", "vhost-net", "dbs-upcall"] } dragonball = { path = "../../../dragonball", features = ["atomic-guest-memory", "virtio-vsock", "hotplug", "virtio-blk", "virtio-net", "virtio-fs", "vhost-net", "dbs-upcall","virtio-mem", "virtio-balloon"] }
ch-config = { path = "ch-config", optional = true } ch-config = { path = "ch-config", optional = true }
tests_utils = { path = "../../tests/utils" } tests_utils = { path = "../../tests/utils" }

View File

@ -8,8 +8,10 @@ use crate::ch::utils::get_api_socket_path;
use crate::ch::utils::get_vsock_path; use crate::ch::utils::get_vsock_path;
use crate::kernel_param::KernelParams; use crate::kernel_param::KernelParams;
use crate::utils::{get_jailer_root, get_sandbox_path}; use crate::utils::{get_jailer_root, get_sandbox_path};
use crate::MemoryConfig;
use crate::VM_ROOTFS_DRIVER_BLK;
use crate::VM_ROOTFS_DRIVER_PMEM;
use crate::{VcpuThreadIds, VmmState}; use crate::{VcpuThreadIds, VmmState};
use crate::{VM_ROOTFS_DRIVER_BLK, VM_ROOTFS_DRIVER_PMEM};
use anyhow::{anyhow, Context, Result}; use anyhow::{anyhow, Context, Result};
use ch_config::ch_api::{ use ch_config::ch_api::{
cloud_hypervisor_vm_create, cloud_hypervisor_vm_start, cloud_hypervisor_vmm_ping, cloud_hypervisor_vm_create, cloud_hypervisor_vm_start, cloud_hypervisor_vmm_ping,
@ -753,6 +755,14 @@ impl CloudHypervisorInner {
pub(crate) fn guest_memory_block_size_mb(&self) -> u32 { pub(crate) fn guest_memory_block_size_mb(&self) -> u32 {
todo!() todo!()
} }
pub(crate) fn resize_memory(
&self,
_req_mem_mb: u32,
_curr_mem_mb: u32,
) -> Result<(u32, MemoryConfig)> {
todo!()
}
} }
// Log all output from the CH process until a shutdown signal is received. // Log all output from the CH process until a shutdown signal is received.

View File

@ -5,7 +5,7 @@
use super::HypervisorState; use super::HypervisorState;
use crate::device::DeviceType; use crate::device::DeviceType;
use crate::{Hypervisor, VcpuThreadIds}; use crate::{Hypervisor, MemoryConfig, VcpuThreadIds};
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use async_trait::async_trait; use async_trait::async_trait;
use kata_types::capabilities::{Capabilities, CapabilityBits}; use kata_types::capabilities::{Capabilities, CapabilityBits};
@ -177,6 +177,15 @@ impl Hypervisor for CloudHypervisor {
let inner = self.inner.read().await; let inner = self.inner.read().await;
inner.guest_memory_block_size_mb() inner.guest_memory_block_size_mb()
} }
async fn resize_memory(
&self,
req_mem_mb: u32,
curr_mem_mb: u32,
) -> Result<(u32, MemoryConfig)> {
let inner = self.inner.read().await;
inner.resize_memory(req_mem_mb, curr_mem_mb)
}
} }
#[async_trait] #[async_trait]

View File

@ -6,13 +6,14 @@
use super::vmm_instance::VmmInstance; use super::vmm_instance::VmmInstance;
use crate::{ use crate::{
device::DeviceType, hypervisor_persist::HypervisorState, kernel_param::KernelParams, VmmState, device::DeviceType, hypervisor_persist::HypervisorState, kernel_param::KernelParams,
DEV_HUGEPAGES, HUGETLBFS, HUGE_SHMEM, HYPERVISOR_DRAGONBALL, SHMEM, MemoryConfig, VmmState, DEV_HUGEPAGES, HUGETLBFS, HUGE_SHMEM, HYPERVISOR_DRAGONBALL, SHMEM,
}; };
use anyhow::{anyhow, Context, Result}; use anyhow::{anyhow, Context, Result};
use async_trait::async_trait; use async_trait::async_trait;
use dragonball::{ use dragonball::{
api::v1::{BootSourceConfig, VcpuResizeInfo}, api::v1::{BootSourceConfig, VcpuResizeInfo},
device_manager::{balloon_dev_mgr::BalloonDeviceConfigInfo, mem_dev_mgr::MemDeviceConfigInfo},
vm::VmConfigInfo, vm::VmConfigInfo,
}; };
@ -26,6 +27,7 @@ use kata_types::{
}; };
use nix::mount::MsFlags; use nix::mount::MsFlags;
use persist::sandbox_persist::Persist; use persist::sandbox_persist::Persist;
use std::cmp::Ordering;
use std::{collections::HashSet, fs::create_dir_all}; use std::{collections::HashSet, fs::create_dir_all};
const DRAGONBALL_KERNEL: &str = "vmlinux"; const DRAGONBALL_KERNEL: &str = "vmlinux";
@ -343,6 +345,64 @@ impl DragonballInner {
Ok((old_vcpus, new_vcpus)) Ok((old_vcpus, new_vcpus))
} }
// curr_mem_m size = default + hotplug
pub(crate) fn resize_memory(
&self,
req_mem_mb: u32,
curr_mem_mb: u32,
) -> Result<(u32, MemoryConfig)> {
let mem_device_to_insert = match req_mem_mb.cmp(&curr_mem_mb) {
Ordering::Greater => {
// We need to insert a new memory device
let add_mem_mb = req_mem_mb - curr_mem_mb;
if self.config.memory_info.enable_virtio_mem {
Some(MemDeviceConfigInfo {
mem_id: format!("mem{}", curr_mem_mb),
size_mib: add_mem_mb as u64,
capacity_mib: add_mem_mb as u64,
multi_region: false,
host_numa_node_id: None,
guest_numa_node_id: None,
use_shared_irq: None,
use_generic_irq: None,
})
} else {
None
}
}
Ordering::Less => {
// We need to insert a new balloon device to release memory
let balloon_config = BalloonDeviceConfigInfo {
balloon_id: format!("mem{}", curr_mem_mb),
size_mib: (curr_mem_mb - req_mem_mb) as u64,
use_shared_irq: None,
use_generic_irq: None,
f_deflate_on_oom: false,
f_reporting: false,
};
self.vmm_instance
.insert_balloon_device(balloon_config)
.context("failed to insert balloon device")?;
None
}
Ordering::Equal => None, // Everything is already set up
};
// If we have a memory device to insert, do it now
if let Some(mem_config) = mem_device_to_insert {
self.vmm_instance
.insert_mem_device(mem_config)
.context("failed to insert memory device")?;
}
Ok((
req_mem_mb,
MemoryConfig {
..Default::default()
},
))
}
pub fn set_hypervisor_config(&mut self, config: HypervisorConfig) { pub fn set_hypervisor_config(&mut self, config: HypervisorConfig) {
self.config = config; self.config = config;
} }
@ -359,7 +419,7 @@ impl DragonballInner {
self.guest_memory_block_size_mb = size; self.guest_memory_block_size_mb = size;
} }
pub(crate) fn get_guest_memory_block_size(&self) -> u32 { pub(crate) fn guest_memory_block_size_mb(&self) -> u32 {
self.guest_memory_block_size_mb self.guest_memory_block_size_mb
} }
} }

View File

@ -26,7 +26,7 @@ use kata_types::config::hypervisor::Hypervisor as HypervisorConfig;
use tokio::sync::RwLock; use tokio::sync::RwLock;
use tracing::instrument; use tracing::instrument;
use crate::{DeviceType, Hypervisor, NetworkConfig, VcpuThreadIds}; use crate::{DeviceType, Hypervisor, MemoryConfig, NetworkConfig, VcpuThreadIds};
pub struct Dragonball { pub struct Dragonball {
inner: Arc<RwLock<DragonballInner>>, inner: Arc<RwLock<DragonballInner>>,
@ -191,7 +191,16 @@ impl Hypervisor for Dragonball {
async fn guest_memory_block_size(&self) -> u32 { async fn guest_memory_block_size(&self) -> u32 {
let inner = self.inner.read().await; let inner = self.inner.read().await;
inner.get_guest_memory_block_size() inner.guest_memory_block_size_mb()
}
async fn resize_memory(
&self,
req_mem_mb: u32,
curr_mem_mb: u32,
) -> Result<(u32, MemoryConfig)> {
let inner = self.inner.read().await;
inner.resize_memory(req_mem_mb, curr_mem_mb)
} }
} }

View File

@ -19,6 +19,7 @@ use dragonball::{
InstanceInfo, InstanceState, NetworkInterfaceConfig, VcpuResizeInfo, VmmAction, InstanceInfo, InstanceState, NetworkInterfaceConfig, VcpuResizeInfo, VmmAction,
VmmActionError, VmmData, VmmRequest, VmmResponse, VmmService, VsockDeviceConfigInfo, VmmActionError, VmmData, VmmRequest, VmmResponse, VmmService, VsockDeviceConfigInfo,
}, },
device_manager::{balloon_dev_mgr::BalloonDeviceConfigInfo, mem_dev_mgr::MemDeviceConfigInfo},
vm::VmConfigInfo, vm::VmConfigInfo,
Vmm, Vmm,
}; };
@ -255,6 +256,18 @@ impl VmmInstance {
Ok(()) Ok(())
} }
pub fn insert_mem_device(&self, cfg: MemDeviceConfigInfo) -> Result<()> {
self.handle_request(Request::Sync(VmmAction::InsertMemDevice(cfg.clone())))
.with_context(|| format!("Failed to insert memory device : {:?}", cfg))?;
Ok(())
}
pub fn insert_balloon_device(&self, cfg: BalloonDeviceConfigInfo) -> Result<()> {
self.handle_request(Request::Sync(VmmAction::InsertBalloonDevice(cfg.clone())))
.with_context(|| format!("Failed to insert balloon device: {:?}", cfg))?;
Ok(())
}
pub fn pause(&self) -> Result<()> { pub fn pause(&self) -> Result<()> {
todo!() todo!()
} }

View File

@ -73,6 +73,14 @@ pub struct VcpuThreadIds {
pub vcpus: HashMap<u32, u32>, pub vcpus: HashMap<u32, u32>,
} }
#[derive(Debug, Default)]
pub struct MemoryConfig {
pub slot: u32,
pub size_mb: u32,
pub addr: u64,
pub probe: bool,
}
#[async_trait] #[async_trait]
pub trait Hypervisor: std::fmt::Debug + Send + Sync { pub trait Hypervisor: std::fmt::Debug + Send + Sync {
// vm manager // vm manager
@ -106,4 +114,6 @@ pub trait Hypervisor: std::fmt::Debug + Send + Sync {
async fn set_capabilities(&self, flag: CapabilityBits); async fn set_capabilities(&self, flag: CapabilityBits);
async fn set_guest_memory_block_size(&self, size: u32); async fn set_guest_memory_block_size(&self, size: u32);
async fn guest_memory_block_size(&self) -> u32; async fn guest_memory_block_size(&self) -> u32;
async fn resize_memory(&self, req_mem_mb: u32, curr_mem_mb: u32)
-> Result<(u32, MemoryConfig)>;
} }

View File

@ -5,7 +5,7 @@
use anyhow::Result; use anyhow::Result;
use crate::{HypervisorConfig, VcpuThreadIds}; use crate::{HypervisorConfig, MemoryConfig, VcpuThreadIds};
use kata_types::capabilities::{Capabilities, CapabilityBits}; use kata_types::capabilities::{Capabilities, CapabilityBits};
const VSOCK_SCHEME: &str = "vsock"; const VSOCK_SCHEME: &str = "vsock";
@ -152,6 +152,14 @@ impl QemuInner {
pub(crate) fn guest_memory_block_size_mb(&self) -> u32 { pub(crate) fn guest_memory_block_size_mb(&self) -> u32 {
todo!() todo!()
} }
pub(crate) fn resize_memory(
&self,
_req_mem_mb: u32,
_curr_mem_mb: u32,
) -> Result<(u32, MemoryConfig)> {
todo!()
}
} }
use crate::device::DeviceType; use crate::device::DeviceType;

View File

@ -7,7 +7,7 @@ mod inner;
use crate::device::DeviceType; use crate::device::DeviceType;
use crate::hypervisor_persist::HypervisorState; use crate::hypervisor_persist::HypervisorState;
use crate::Hypervisor; use crate::{Hypervisor, MemoryConfig};
use crate::{HypervisorConfig, VcpuThreadIds}; use crate::{HypervisorConfig, VcpuThreadIds};
use inner::QemuInner; use inner::QemuInner;
use kata_types::capabilities::{Capabilities, CapabilityBits}; use kata_types::capabilities::{Capabilities, CapabilityBits};
@ -172,4 +172,13 @@ impl Hypervisor for Qemu {
let inner = self.inner.read().await; let inner = self.inner.read().await;
inner.guest_memory_block_size_mb() inner.guest_memory_block_size_mb()
} }
async fn resize_memory(
&self,
req_mem_mb: u32,
curr_mem_mb: u32,
) -> Result<(u32, MemoryConfig)> {
let inner = self.inner.read().await;
inner.resize_memory(req_mem_mb, curr_mem_mb)
}
} }