runtim-rs: get guest memory details

get memory block size and guest mem hotplug probe

Fixes:#6356
Signed-off-by: Zhongtao Hu <zhongtaohu.tim@linux.alibaba.com>
This commit is contained in:
Zhongtao Hu
2023-02-23 16:54:08 +08:00
parent 4a49dd73db
commit d428a3f9b9
12 changed files with 170 additions and 10 deletions

View File

@@ -19,6 +19,8 @@ pub enum CapabilityBits {
FsSharingSupport,
/// hypervisor supports hybrid-vsock
HybridVsockSupport,
/// hypervisor supports memory hotplug probe interface
GuestMemoryHotplugProbe,
}
/// Capabilities describe a virtcontainers hypervisor capabilities through a bit mask.
@@ -47,17 +49,22 @@ impl Capabilities {
self.flags = flags;
}
/// is_block_device_supported tells if an hypervisor supports block devices.
/// add CapabilityBits
pub fn add(&mut self, flags: CapabilityBits) {
self.flags |= flags;
}
/// is_block_device_supported tells if the hypervisor supports block devices.
pub fn is_block_device_supported(&self) -> bool {
self.flags.and(CapabilityBits::BlockDeviceSupport) != 0
}
/// is_block_device_hotplug_supported tells if an hypervisor supports block devices.
/// is_block_device_hotplug_supported tells if the hypervisor supports block devices.
pub fn is_block_device_hotplug_supported(&self) -> bool {
self.flags.and(CapabilityBits::BlockDeviceHotplugSupport) != 0
}
/// is_multi_queue_supported tells if an hypervisor supports device multi queue support.
/// is_multi_queue_supported tells if the hypervisor supports device multi queue support.
pub fn is_multi_queue_supported(&self) -> bool {
self.flags.and(CapabilityBits::MultiQueueSupport) != 0
}
@@ -71,6 +78,11 @@ impl Capabilities {
pub fn is_fs_sharing_supported(&self) -> bool {
self.flags.and(CapabilityBits::FsSharingSupport) != 0
}
/// is_mem_hotplug_probe_supported tells if the hypervisor supports hotplug probe interface
pub fn is_mem_hotplug_probe_supported(&self) -> bool {
self.flags.and(CapabilityBits::GuestMemoryHotplugProbe) != 0
}
}
#[cfg(test)]
@@ -117,5 +129,9 @@ mod tests {
// test set hybrid-vsock support
cap.set(CapabilityBits::HybridVsockSupport);
assert!(cap.is_hybrid_vsock_supported());
// test append capabilities
cap.add(CapabilityBits::GuestMemoryHotplugProbe);
assert!(cap.is_mem_hotplug_probe_supported());
assert!(cap.is_fs_sharing_supported());
}
}

View File

@@ -122,5 +122,6 @@ impl_agent!(
get_volume_stats | crate::VolumeStatsRequest | crate::VolumeStatsResponse | None,
resize_volume | crate::ResizeVolumeRequest | crate::Empty | None,
online_cpu_mem | crate::OnlineCPUMemRequest | crate::Empty | None,
get_metrics | crate::Empty | crate::MetricsResponse | None
get_metrics | crate::Empty | crate::MetricsResponse | None,
get_guest_details | crate::GetGuestDetailsRequest | crate::GuestDetailsResponse | None
);

View File

@@ -27,7 +27,7 @@ use crate::{
UpdateInterfaceRequest, UpdateRoutesRequest, VersionCheckResponse, VolumeStatsRequest,
VolumeStatsResponse, WaitProcessRequest, WriteStreamRequest,
},
OomEventResponse, WaitProcessResponse, WriteStreamResponse,
GetGuestDetailsRequest, OomEventResponse, WaitProcessResponse, WriteStreamResponse,
};
fn trans_vec<F: Sized + Clone, T: From<F>>(from: Vec<F>) -> Vec<T> {
@@ -723,6 +723,16 @@ impl From<SetGuestDateTimeRequest> for agent::SetGuestDateTimeRequest {
}
}
impl From<GetGuestDetailsRequest> for agent::GuestDetailsRequest {
fn from(from: GetGuestDetailsRequest) -> Self {
Self {
mem_block_size: from.mem_block_size,
mem_hotplug_probe: from.mem_hotplug_probe,
..Default::default()
}
}
}
impl From<agent::AgentDetails> for AgentDetails {
fn from(src: agent::AgentDetails) -> Self {
Self {

View File

@@ -93,4 +93,5 @@ pub trait Agent: AgentManager + HealthService + Send + Sync {
async fn set_ip_tables(&self, req: SetIPTablesRequest) -> Result<SetIPTablesResponse>;
async fn get_volume_stats(&self, req: VolumeStatsRequest) -> Result<VolumeStatsResponse>;
async fn resize_volume(&self, req: ResizeVolumeRequest) -> Result<Empty>;
async fn get_guest_details(&self, req: GetGuestDetailsRequest) -> Result<GuestDetailsResponse>;
}

View File

@@ -741,6 +741,18 @@ impl CloudHypervisorInner {
pub(crate) async fn get_hypervisor_metrics(&self) -> Result<String> {
todo!()
}
pub(crate) fn set_capabilities(&mut self, _flag: CapabilityBits) {
todo!()
}
pub(crate) fn set_guest_memory_block_size(&mut self, _size: u32) {
todo!()
}
pub(crate) fn guest_memory_block_size_mb(&self) -> u32 {
todo!()
}
}
// Log all output from the CH process until a shutdown signal is received.

View File

@@ -8,7 +8,7 @@ use crate::device::DeviceType;
use crate::{Hypervisor, VcpuThreadIds};
use anyhow::{Context, Result};
use async_trait::async_trait;
use kata_types::capabilities::Capabilities;
use kata_types::capabilities::{Capabilities, CapabilityBits};
use kata_types::config::hypervisor::Hypervisor as HypervisorConfig;
use persist::sandbox_persist::Persist;
use std::sync::Arc;
@@ -162,6 +162,21 @@ impl Hypervisor for CloudHypervisor {
let inner = self.inner.read().await;
inner.get_hypervisor_metrics().await
}
async fn set_capabilities(&self, flag: CapabilityBits) {
let mut inner = self.inner.write().await;
inner.set_capabilities(flag)
}
async fn set_guest_memory_block_size(&self, size: u32) {
let mut inner = self.inner.write().await;
inner.set_guest_memory_block_size(size);
}
async fn guest_memory_block_size(&self) -> u32 {
let inner = self.inner.read().await;
inner.guest_memory_block_size_mb()
}
}
#[async_trait]

View File

@@ -68,6 +68,9 @@ pub struct DragonballInner {
/// dragonball capabilities
pub(crate) capabilities: Capabilities,
/// the size of memory block of guest OS
pub(crate) guest_memory_block_size_mb: u32,
}
impl DragonballInner {
@@ -92,6 +95,7 @@ impl DragonballInner {
run_dir: "".to_string(),
cached_block_devices: Default::default(),
capabilities,
guest_memory_block_size_mb: 0,
}
}
@@ -346,6 +350,18 @@ impl DragonballInner {
pub fn hypervisor_config(&self) -> HypervisorConfig {
self.config.clone()
}
pub(crate) fn set_capabilities(&mut self, flag: CapabilityBits) {
self.capabilities.add(flag);
}
pub(crate) fn set_guest_memory_block_size(&mut self, size: u32) {
self.guest_memory_block_size_mb = size;
}
pub(crate) fn get_guest_memory_block_size(&self) -> u32 {
self.guest_memory_block_size_mb
}
}
#[async_trait]
@@ -387,6 +403,7 @@ impl Persist for DragonballInner {
pending_devices: vec![],
cached_block_devices: hypervisor_state.cached_block_devices,
capabilities: Capabilities::new(),
guest_memory_block_size_mb: 0,
})
}
}

View File

@@ -21,7 +21,7 @@ use dragonball::api::v1::{
Backend as DragonballBackend, NetworkInterfaceConfig as DragonballNetworkConfig,
VirtioConfig as DragonballVirtioConfig,
};
use kata_types::capabilities::Capabilities;
use kata_types::capabilities::{Capabilities, CapabilityBits};
use kata_types::config::hypervisor::Hypervisor as HypervisorConfig;
use tokio::sync::RwLock;
use tracing::instrument;
@@ -178,6 +178,21 @@ impl Hypervisor for Dragonball {
let inner = self.inner.read().await;
inner.get_hypervisor_metrics().await
}
async fn set_capabilities(&self, flag: CapabilityBits) {
let mut inner = self.inner.write().await;
inner.set_capabilities(flag)
}
async fn set_guest_memory_block_size(&self, size: u32) {
let mut inner = self.inner.write().await;
inner.set_guest_memory_block_size(size);
}
async fn guest_memory_block_size(&self) -> u32 {
let inner = self.inner.read().await;
inner.get_guest_memory_block_size()
}
}
#[async_trait]

View File

@@ -26,7 +26,7 @@ pub mod ch;
use anyhow::Result;
use async_trait::async_trait;
use hypervisor_persist::HypervisorState;
use kata_types::capabilities::Capabilities;
use kata_types::capabilities::{Capabilities, CapabilityBits};
use kata_types::config::hypervisor::Hypervisor as HypervisorConfig;
pub use kata_types::config::hypervisor::HYPERVISOR_NAME_CH;
@@ -103,4 +103,7 @@ pub trait Hypervisor: std::fmt::Debug + Send + Sync {
async fn save_state(&self) -> Result<HypervisorState>;
async fn capabilities(&self) -> Result<Capabilities>;
async fn get_hypervisor_metrics(&self) -> Result<String>;
async fn set_capabilities(&self, flag: CapabilityBits);
async fn set_guest_memory_block_size(&self, size: u32);
async fn guest_memory_block_size(&self) -> u32;
}

View File

@@ -140,6 +140,18 @@ impl QemuInner {
pub(crate) async fn get_hypervisor_metrics(&self) -> Result<String> {
todo!()
}
pub(crate) fn set_capabilities(&mut self, _flag: CapabilityBits) {
todo!()
}
pub(crate) fn set_guest_memory_block_size(&mut self, _size: u32) {
todo!()
}
pub(crate) fn guest_memory_block_size_mb(&self) -> u32 {
todo!()
}
}
use crate::device::DeviceType;

View File

@@ -10,7 +10,7 @@ use crate::hypervisor_persist::HypervisorState;
use crate::Hypervisor;
use crate::{HypervisorConfig, VcpuThreadIds};
use inner::QemuInner;
use kata_types::capabilities::Capabilities;
use kata_types::capabilities::{Capabilities, CapabilityBits};
use anyhow::Result;
use async_trait::async_trait;
@@ -157,4 +157,19 @@ impl Hypervisor for Qemu {
let inner = self.inner.read().await;
inner.get_hypervisor_metrics().await
}
async fn set_capabilities(&self, flag: CapabilityBits) {
let mut inner = self.inner.write().await;
inner.set_capabilities(flag)
}
async fn set_guest_memory_block_size(&self, size: u32) {
let mut inner = self.inner.write().await;
inner.set_guest_memory_block_size(size);
}
async fn guest_memory_block_size(&self) -> u32 {
let inner = self.inner.read().await;
inner.guest_memory_block_size_mb()
}
}

View File

@@ -8,7 +8,9 @@ use std::sync::Arc;
use agent::kata::KataAgent;
use agent::types::KernelModule;
use agent::{self, Agent, GetIPTablesRequest, SetIPTablesRequest, VolumeStatsRequest};
use agent::{
self, Agent, GetGuestDetailsRequest, GetIPTablesRequest, SetIPTablesRequest, VolumeStatsRequest,
};
use anyhow::{anyhow, Context, Result};
use async_trait::async_trait;
use common::message::{Action, Message};
@@ -18,6 +20,7 @@ use hypervisor::VsockConfig;
use hypervisor::{dragonball::Dragonball, BlockConfig, Hypervisor, HYPERVISOR_DRAGONBALL};
use hypervisor::{utils::get_hvsock_path, HybridVsockConfig, DEFAULT_GUEST_VSOCK_CID};
use kata_sys_util::hooks::HookStates;
use kata_types::capabilities::CapabilityBits;
use kata_types::config::TomlConfig;
use persist::{self, sandbox_persist::Persist};
use resource::manager::ManagerArgs;
@@ -196,7 +199,41 @@ impl VirtSandbox {
// * spec details: https://github.com/opencontainers/runtime-spec/blob/c1662686cff159595277b79322d0272f5182941b/config.md#createruntime-hooks
let mut create_runtime_hook_states = HookStates::new();
create_runtime_hook_states.execute_hooks(create_runtime_hooks, Some(st.clone()))?;
Ok(())
}
// store_guest_details will get the information from the guest OS, like memory block size, agent details and is memory hotplug probe support
async fn store_guest_details(&self) -> Result<()> {
// get the information from agent
let guest_details = self
.agent
.get_guest_details(GetGuestDetailsRequest {
mem_block_size: true,
mem_hotplug_probe: true,
})
.await
.context("failed to store guest details")?;
// set memory block size
self.hypervisor
.set_guest_memory_block_size(guest_details.mem_block_size_bytes as u32)
.await;
// set memory hotplug probe
if guest_details.support_mem_hotplug_probe {
self.hypervisor
.set_capabilities(CapabilityBits::GuestMemoryHotplugProbe)
.await;
}
info!(
sl!(),
"memory block size is {}, memory probe support {}",
self.hypervisor.guest_memory_block_size().await,
self.hypervisor
.capabilities()
.await?
.is_mem_hotplug_probe_supported()
);
Ok(())
}
@@ -375,6 +412,12 @@ impl Sandbox for VirtSandbox {
.context("create sandbox")?;
inner.state = SandboxState::Running;
// get and store guest details
self.store_guest_details()
.await
.context("failed to store guest details")?;
let agent = self.agent.clone();
let sender = self.msg_sender.clone();
info!(sl!(), "oom watcher start");