diff --git a/src/bin/ch-remote.rs b/src/bin/ch-remote.rs index 3da594a8a..66cc69183 100644 --- a/src/bin/ch-remote.rs +++ b/src/bin/ch-remote.rs @@ -226,7 +226,7 @@ fn resize_api_command( None }; - let desired_ram_w_balloon: Option = if let Some(balloon) = balloon { + let desired_balloon: Option = if let Some(balloon) = balloon { Some( balloon .parse::() @@ -240,7 +240,7 @@ fn resize_api_command( let resize = vmm::api::VmResizeData { desired_vcpus, desired_ram, - desired_ram_w_balloon, + desired_balloon, }; simple_api_command( @@ -577,7 +577,7 @@ fn main() { .arg( Arg::with_name("balloon") .long("balloon") - .help("New memory with balloon size in bytes (supports K/M/G suffix)") + .help("New balloon size in bytes (supports K/M/G suffix)") .takes_value(true) .number_of_values(1), ), diff --git a/vmm/src/api/mod.rs b/vmm/src/api/mod.rs index 8521954c8..36583f334 100644 --- a/vmm/src/api/mod.rs +++ b/vmm/src/api/mod.rs @@ -157,7 +157,7 @@ pub struct VmmPingResponse { pub struct VmResizeData { pub desired_vcpus: Option, pub desired_ram: Option, - pub desired_ram_w_balloon: Option, + pub desired_balloon: Option, } #[derive(Clone, Deserialize, Serialize, Default)] diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index 85c6be252..51f5e2652 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -358,6 +358,12 @@ pub enum DeviceManagerError { /// No support for device passthrough NoDevicePassthroughSupport, + + /// Failed to resize virtio-balloon + VirtioBalloonResize(virtio_devices::balloon::Error), + + /// Missing virtio-balloon, can't proceed as expected. + MissingVirtioBalloon, } pub type DeviceManagerResult = result::Result; @@ -780,6 +786,9 @@ pub struct DeviceManager { // List of guest NUMA nodes. #[cfg(feature = "acpi")] numa_nodes: NumaNodes, + + // Possible handle to the virtio-balloon device + balloon: Option>>, } impl DeviceManager { @@ -850,6 +859,7 @@ impl DeviceManager { seccomp_action, #[cfg(feature = "acpi")] numa_nodes, + balloon: None, }; #[cfg(feature = "acpi")] @@ -2440,22 +2450,19 @@ impl DeviceManager { ) -> DeviceManagerResult> { let mut devices = Vec::new(); - if self.config.lock().unwrap().memory.balloon { + if let Some(balloon_config) = &self.config.lock().unwrap().balloon { let id = String::from(BALLOON_DEVICE_NAME); let virtio_balloon_device = Arc::new(Mutex::new( virtio_devices::Balloon::new( id.clone(), - self.config.lock().unwrap().memory.balloon_size, + balloon_config.size, self.seccomp_action.clone(), ) .map_err(DeviceManagerError::CreateVirtioBalloon)?, )); - self.memory_manager - .lock() - .unwrap() - .set_balloon(virtio_balloon_device.clone()); + self.balloon = Some(virtio_balloon_device.clone()); devices.push(( Arc::clone(&virtio_balloon_device) as VirtioDeviceArc, @@ -3197,6 +3204,27 @@ impl DeviceManager { counters } + + pub fn resize_balloon(&mut self, size: u64) -> DeviceManagerResult<()> { + if let Some(balloon) = &self.balloon { + return balloon + .lock() + .unwrap() + .resize(size) + .map_err(DeviceManagerError::VirtioBalloonResize); + } + + warn!("No balloon setup: Can't resize the balloon"); + Err(DeviceManagerError::MissingVirtioBalloon) + } + + pub fn balloon_size(&self) -> u64 { + if let Some(balloon) = &self.balloon { + return balloon.lock().unwrap().get_actual(); + } + + 0 + } } #[cfg(feature = "acpi")] diff --git a/vmm/src/lib.rs b/vmm/src/lib.rs index 4ad9b8f45..5916b6a11 100644 --- a/vmm/src/lib.rs +++ b/vmm/src/lib.rs @@ -469,7 +469,7 @@ impl Vmm { let mut memory_actual_size = config.lock().unwrap().memory.total_size(); if let Some(vm) = &self.vm { - memory_actual_size -= vm.get_balloon_actual(); + memory_actual_size -= vm.balloon_size(); } Ok(VmInfo { @@ -511,10 +511,10 @@ impl Vmm { &mut self, desired_vcpus: Option, desired_ram: Option, - desired_ram_w_balloon: Option, + desired_balloon: Option, ) -> result::Result<(), VmError> { if let Some(ref mut vm) = self.vm { - if let Err(e) = vm.resize(desired_vcpus, desired_ram, desired_ram_w_balloon) { + if let Err(e) = vm.resize(desired_vcpus, desired_ram, desired_balloon) { error!("Error when resizing VM: {:?}", e); Err(e) } else { @@ -801,7 +801,7 @@ impl Vmm { .vm_resize( resize_data.desired_vcpus, resize_data.desired_ram, - resize_data.desired_ram_w_balloon, + resize_data.desired_balloon, ) .map_err(ApiError::VmResize) .map(|_| ApiResponsePayload::Empty); diff --git a/vmm/src/memory_manager.rs b/vmm/src/memory_manager.rs index 61e686bb9..819c74c37 100644 --- a/vmm/src/memory_manager.rs +++ b/vmm/src/memory_manager.rs @@ -117,7 +117,6 @@ pub struct MemoryManager { snapshot: Mutex>>, shared: bool, hugepages: bool, - balloon: Option>>, #[cfg(target_arch = "x86_64")] sgx_epc_region: Option, user_provided_zones: bool, @@ -176,9 +175,6 @@ pub enum Error { /// memory regions. InvalidAmountExternalBackingFiles, - /// Failed to virtio-balloon resize - VirtioBalloonResizeFail(virtio_devices::balloon::Error), - /// Invalid SGX EPC section size #[cfg(target_arch = "x86_64")] EpcSectionSizeInvalid, @@ -688,7 +684,6 @@ impl MemoryManager { snapshot: Mutex::new(None), shared: config.shared, hugepages: config.hugepages, - balloon: None, #[cfg(target_arch = "x86_64")] sgx_epc_region: None, user_provided_zones, @@ -1085,10 +1080,6 @@ impl MemoryManager { Ok(region) } - pub fn set_balloon(&mut self, balloon: Arc>) { - self.balloon = Some(balloon); - } - pub fn guest_memory(&self) -> GuestMemoryAtomic { self.guest_memory.clone() } @@ -1242,30 +1233,6 @@ impl MemoryManager { Err(Error::UnknownMemoryZone) } - pub fn balloon_resize(&mut self, expected_ram: u64) -> Result { - let mut balloon_size = 0; - if let Some(balloon) = &self.balloon { - if expected_ram < self.current_ram { - balloon_size = self.current_ram - expected_ram; - } - balloon - .lock() - .unwrap() - .resize(balloon_size) - .map_err(Error::VirtioBalloonResizeFail)?; - } - - Ok(balloon_size) - } - - pub fn get_balloon_actual(&self) -> u64 { - if let Some(balloon) = &self.balloon { - return balloon.lock().unwrap().get_actual(); - } - - 0 - } - /// In case this function resulted in adding a new memory region to the /// guest memory, the new region is returned to the caller. The virtio-mem /// use case never adds a new region as the whole hotpluggable memory has diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index 60155ac0a..12c61b590 100644 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -1040,7 +1040,7 @@ impl Vm { &mut self, desired_vcpus: Option, desired_memory: Option, - desired_ram_w_balloon: Option, + desired_balloon: Option, ) -> Result<()> { if let Some(desired_vcpus) = desired_vcpus { if self @@ -1103,15 +1103,18 @@ impl Vm { } } - if let Some(desired_ram_w_balloon) = desired_ram_w_balloon { - // update the configuration value for the balloon size to ensure - // a reboot would use the right value. - self.config.lock().unwrap().memory.balloon_size = self - .memory_manager + if let Some(desired_balloon) = desired_balloon { + self.device_manager .lock() .unwrap() - .balloon_resize(desired_ram_w_balloon) - .map_err(Error::MemoryManager)?; + .resize_balloon(desired_balloon) + .map_err(Error::DeviceManager)?; + + // Update the configuration value for the balloon size to ensure + // a reboot would use the right value. + if let Some(balloon_config) = &mut self.config.lock().unwrap().balloon { + balloon_config.size = desired_balloon; + } } Ok(()) @@ -1607,8 +1610,8 @@ impl Vm { } /// Gets the actual size of the balloon. - pub fn get_balloon_actual(&self) -> u64 { - self.memory_manager.lock().unwrap().get_balloon_actual() + pub fn balloon_size(&self) -> u64 { + self.device_manager.lock().unwrap().balloon_size() } }