diff --git a/vmm/src/api/http/http_endpoint.rs b/vmm/src/api/http/http_endpoint.rs index 65da20674..ff1de5629 100644 --- a/vmm/src/api/http/http_endpoint.rs +++ b/vmm/src/api/http/http_endpoint.rs @@ -15,12 +15,14 @@ use crate::api::http::{error_response, EndpointHandler, HttpError}; #[cfg(all(target_arch = "x86_64", feature = "guest_debug"))] use crate::api::VmCoredump; use crate::api::{ - AddDisk, ApiAction, ApiRequest, NetConfig, VmAddDevice, VmAddFs, VmAddNet, VmAddPmem, + AddDisk, ApiAction, ApiError, ApiRequest, NetConfig, VmAddDevice, VmAddFs, VmAddNet, VmAddPmem, VmAddUserDevice, VmAddVdpa, VmAddVsock, VmBoot, VmConfig, VmCounters, VmDelete, VmNmi, VmPause, VmPowerButton, VmReboot, VmReceiveMigration, VmRemoveDevice, VmResize, VmResizeZone, VmRestore, VmResume, VmSendMigration, VmShutdown, VmSnapshot, }; use crate::config::RestoreConfig; +use crate::cpu::Error as CpuError; +use crate::vm::Error as VmError; // /api/v1/vm.create handler pub struct VmCreate {} @@ -183,7 +185,6 @@ vm_action_put_handler_body!(VmAddVdpa); vm_action_put_handler_body!(VmAddVsock); vm_action_put_handler_body!(VmAddUserDevice); vm_action_put_handler_body!(VmRemoveDevice); -vm_action_put_handler_body!(VmResize); vm_action_put_handler_body!(VmResizeZone); vm_action_put_handler_body!(VmSnapshot); vm_action_put_handler_body!(VmReceiveMigration); @@ -220,6 +221,34 @@ impl PutHandler for VmAddNet { impl GetHandler for VmAddNet {} +impl PutHandler for VmResize { + fn handle_request( + &'static self, + api_notifier: EventFd, + api_sender: Sender, + body: &Option, + _files: Vec, + ) -> std::result::Result, HttpError> { + if let Some(body) = body { + self.send( + api_notifier, + api_sender, + serde_json::from_slice(body.raw())?, + ) + .map_err(|e| match e { + ApiError::VmResize(VmError::CpuManager(CpuError::VcpuPendingRemovedVcpu)) => { + HttpError::TooManyRequests + } + _ => HttpError::ApiError(e), + }) + } else { + Err(HttpError::BadRequest) + } + } +} + +impl GetHandler for VmResize {} + impl PutHandler for VmRestore { fn handle_request( &'static self, diff --git a/vmm/src/api/http/mod.rs b/vmm/src/api/http/mod.rs index a105fc0cf..2c4eb4c93 100644 --- a/vmm/src/api/http/mod.rs +++ b/vmm/src/api/http/mod.rs @@ -52,6 +52,9 @@ pub enum HttpError { /// Undefined endpoints NotFound, + /// Too many requests + TooManyRequests, + /// Internal Server Error InternalServerError, @@ -65,6 +68,7 @@ impl Display for HttpError { match self { BadRequest => write!(f, "Bad Request"), NotFound => write!(f, "Not Found"), + TooManyRequests => write!(f, "Too Many Requests"), InternalServerError => write!(f, "Internal Server Error"), SerdeJsonDeserialize(serde_error) => write!(f, "{}", serde_error), ApiError(api_error) => write!(f, "{}", api_error), @@ -125,6 +129,7 @@ pub trait EndpointHandler { Err(e @ HttpError::SerdeJsonDeserialize(_)) => { error_response(e, StatusCode::BadRequest) } + Err(e @ HttpError::TooManyRequests) => error_response(e, StatusCode::TooManyRequests), Err(e) => error_response(e, StatusCode::InternalServerError), } } diff --git a/vmm/src/api/openapi/cloud-hypervisor.yaml b/vmm/src/api/openapi/cloud-hypervisor.yaml index e723bee8f..15f99d303 100644 --- a/vmm/src/api/openapi/cloud-hypervisor.yaml +++ b/vmm/src/api/openapi/cloud-hypervisor.yaml @@ -160,6 +160,8 @@ paths: description: The VM instance was successfully resized. 404: description: The VM instance could not be resized because it is not created. + 429: + description: The VM instance could not be resized because a cpu removal is still pending. /vm.resize-zone: put: