diff --git a/src/bin/ch-remote.rs b/src/bin/ch-remote.rs index 1cd79a6f4..e8e482bf9 100644 --- a/src/bin/ch-remote.rs +++ b/src/bin/ch-remote.rs @@ -23,6 +23,7 @@ enum Error { ServerResponse(StatusCode, Option), InvalidCPUCount(std::num::ParseIntError), InvalidMemorySize(std::num::ParseIntError), + InvalidBalloonSize(std::num::ParseIntError), AddDeviceConfig(vmm::config::Error), AddDiskConfig(vmm::config::Error), AddFsConfig(vmm::config::Error), @@ -49,6 +50,7 @@ impl fmt::Display for Error { } InvalidCPUCount(e) => write!(f, "Error parsing CPU count: {}", e), InvalidMemorySize(e) => write!(f, "Error parsing memory size: {}", e), + InvalidBalloonSize(e) => write!(f, "Error parsing balloon size: {}", e), AddDeviceConfig(e) => write!(f, "Error parsing device syntax: {}", e), AddDiskConfig(e) => write!(f, "Error parsing disk syntax: {}", e), AddFsConfig(e) => write!(f, "Error parsing filesystem syntax: {}", e), @@ -204,6 +206,7 @@ fn resize_api_command( socket: &mut UnixStream, cpus: Option<&str>, memory: Option<&str>, + balloon: Option<&str>, ) -> Result<(), Error> { let desired_vcpus: Option = if let Some(cpus) = cpus { Some(cpus.parse().map_err(Error::InvalidCPUCount)?) @@ -217,9 +220,16 @@ fn resize_api_command( None }; + let desired_ram_w_balloon: Option = if let Some(balloon) = balloon { + Some(balloon.parse().map_err(Error::InvalidBalloonSize)?) + } else { + None + }; + let resize = vmm::api::VmResizeData { desired_vcpus, desired_ram, + desired_ram_w_balloon, }; simple_api_command( @@ -348,6 +358,10 @@ fn do_command(matches: &ArgMatches) -> Result<(), Error> { .subcommand_matches("resize") .unwrap() .value_of("memory"), + matches + .subcommand_matches("resize") + .unwrap() + .value_of("balloon"), ), Some("add-device") => add_device_api_command( &mut socket, @@ -518,6 +532,13 @@ fn main() { .help("New memory size (in MiB)") .takes_value(true) .number_of_values(1), + ) + .arg( + Arg::with_name("balloon") + .long("balloon") + .help("New memory with balloon size") + .takes_value(true) + .number_of_values(1), ), ) .subcommand(SubCommand::with_name("resume").about("Resume the VM")) diff --git a/vmm/src/api/mod.rs b/vmm/src/api/mod.rs index f49bdf52b..84560d891 100644 --- a/vmm/src/api/mod.rs +++ b/vmm/src/api/mod.rs @@ -153,6 +153,7 @@ pub struct VmmPingResponse { pub struct VmResizeData { pub desired_vcpus: Option, pub desired_ram: Option, + pub desired_ram_w_balloon: Option, } #[derive(Clone, Deserialize, Serialize, Default)] diff --git a/vmm/src/api/openapi/cloud-hypervisor.yaml b/vmm/src/api/openapi/cloud-hypervisor.yaml index f92037224..18fc98094 100644 --- a/vmm/src/api/openapi/cloud-hypervisor.yaml +++ b/vmm/src/api/openapi/cloud-hypervisor.yaml @@ -680,6 +680,10 @@ components: description: desired memory ram in bytes type: integer format: int64 + desired_ram_w_balloon: + description: desired ballon size in bytes + type: integer + format: int64 VmAddDevice: type: object diff --git a/vmm/src/lib.rs b/vmm/src/lib.rs index 53e6c1474..1dfdf300c 100644 --- a/vmm/src/lib.rs +++ b/vmm/src/lib.rs @@ -490,9 +490,10 @@ impl Vmm { &mut self, desired_vcpus: Option, desired_ram: Option, + desired_ram_w_balloon: Option, ) -> result::Result<(), VmError> { if let Some(ref mut vm) = self.vm { - if let Err(e) = vm.resize(desired_vcpus, desired_ram) { + if let Err(e) = vm.resize(desired_vcpus, desired_ram, desired_ram_w_balloon) { error!("Error when resizing VM: {:?}", e); Err(e) } else { @@ -766,6 +767,7 @@ impl Vmm { .vm_resize( resize_data.desired_vcpus, resize_data.desired_ram, + resize_data.desired_ram_w_balloon, ) .map_err(ApiError::VmResize) .map(|_| ApiResponsePayload::Empty); diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index 5a55288e9..397ba6e1a 100644 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -680,7 +680,12 @@ impl Vm { Ok(()) } - pub fn resize(&mut self, desired_vcpus: Option, desired_memory: Option) -> Result<()> { + pub fn resize( + &mut self, + desired_vcpus: Option, + desired_memory: Option, + desired_ram_w_balloon: Option, + ) -> Result<()> { if let Some(desired_vcpus) = desired_vcpus { if self .cpu_manager @@ -731,6 +736,15 @@ impl Vm { // it will be running with the last configure memory size. self.config.lock().unwrap().memory.size = desired_memory; } + + if let Some(desired_ram_w_balloon) = desired_ram_w_balloon { + self.memory_manager + .lock() + .unwrap() + .balloon_resize(desired_ram_w_balloon) + .map_err(Error::MemoryManager)?; + } + Ok(()) }