diff --git a/crates/daemon/src/control.rs b/crates/daemon/src/control.rs index c132ffd..f767d38 100644 --- a/crates/daemon/src/control.rs +++ b/crates/daemon/src/control.rs @@ -664,22 +664,21 @@ impl ControlService for DaemonControlService { .into()); } - let resources = request.resources.unwrap_or_default(); + let mut resources = request.resources.unwrap_or_default(); + if resources.target_memory > resources.max_memory { + resources.max_memory = resources.target_memory; + } self.runtime - .set_max_memory(status.domid, resources.max_memory * 1024 * 1024) + .set_memory_resources( + status.domid, + resources.target_memory * 1024 * 1024, + resources.max_memory * 1024 * 1024, + ) .await .map_err(|error| ApiError { - message: format!("failed to set maximum memory: {}", error), + message: format!("failed to set memory resources: {}", error), })?; - - self.runtime - .set_target_memory(status.domid, resources.target_memory * 1024 * 1024) - .await - .map_err(|error| ApiError { - message: format!("failed to set target memory: {}", error), - })?; - status.resource_status = Some(ZoneResourceStatus { active_resources: Some(resources), }); diff --git a/crates/runtime/src/lib.rs b/crates/runtime/src/lib.rs index 6d1b7bf..8c1d7dd 100644 --- a/crates/runtime/src/lib.rs +++ b/crates/runtime/src/lib.rs @@ -6,6 +6,7 @@ use tokio::sync::Semaphore; use uuid::Uuid; use xenclient::XenClient; +use xenplatform::domain::XEN_EXTRA_MEMORY_KB; use xenstore::{XsdClient, XsdInterface}; use self::{ @@ -226,33 +227,34 @@ impl Runtime { Ok(uuid) } - pub async fn set_max_memory(&self, domid: u32, max_memory_bytes: u64) -> Result<()> { + pub async fn set_memory_resources( + &self, + domid: u32, + target_memory_bytes: u64, + max_memory_bytes: u64, + ) -> Result<()> { + let mut max_memory_bytes = max_memory_bytes + (XEN_EXTRA_MEMORY_KB * 1024); + if target_memory_bytes > max_memory_bytes { + max_memory_bytes = target_memory_bytes + (XEN_EXTRA_MEMORY_KB * 1024); + } + self.context .xen .call .set_max_mem(domid, max_memory_bytes / 1024) .await?; let domain_path = self.context.xen.store.get_domain_path(domid).await?; + let tx = self.context.xen.store.transaction().await?; let max_memory_path = format!("{}/memory/static-max", domain_path); - self.context - .xen - .store - .write_string(max_memory_path, &(max_memory_bytes / 1024).to_string()) + tx.write_string(max_memory_path, &(max_memory_bytes / 1024).to_string()) .await?; - Ok(()) - } - - pub async fn set_target_memory(&self, domid: u32, target_memory_bytes: u64) -> Result<()> { - let domain_path = self.context.xen.store.get_domain_path(domid).await?; let target_memory_path = format!("{}/memory/target", domain_path); - self.context - .xen - .store - .write_string( - target_memory_path, - &(target_memory_bytes / 1024).to_string(), - ) - .await?; + tx.write_string( + target_memory_path, + &(target_memory_bytes / 1024).to_string(), + ) + .await?; + tx.commit().await?; Ok(()) } diff --git a/crates/xen/xenplatform/src/domain.rs b/crates/xen/xenplatform/src/domain.rs index 2d56f34..9ba5c4d 100644 --- a/crates/xen/xenplatform/src/domain.rs +++ b/crates/xen/xenplatform/src/domain.rs @@ -9,6 +9,8 @@ use xencall::XenCall; use crate::error::Result; +pub const XEN_EXTRA_MEMORY_KB: u64 = 2048; + pub struct BaseDomainManager { call: XenCall, pub platform: Arc

, @@ -29,7 +31,7 @@ impl BaseDomainManager

{ let domid = self.call.create_domain(domain).await?; self.call.set_max_vcpus(domid, config.max_vcpus).await?; self.call - .set_max_mem(domid, (config.max_mem_mb * 1024) + 2048) + .set_max_mem(domid, (config.max_mem_mb * 1024) + XEN_EXTRA_MEMORY_KB) .await?; let loader = ElfImageLoader::load_file_kernel(&config.kernel)?; let platform = (*self.platform).clone();