Skip to content

Commit d0225fe

Browse files
fidenciolikebreath
authored andcommitted
vmm: api: Be more specific on "Still pending remove vcpu" errors
Although the CPU manager gives us a quite descriptive error, on the application side (the part calling Cloud Hypervisor) we have absolutely no way to distinguish such error from any other error that may happen when resizing a VM. With this in mind, let's be more specific and return a TooManyRequests (429) error, allowing the caller to have a chance to decide whether they want to retry the operation or not. https://datatracker.ietf.org/doc/html/rfc6585#section-4 Signed-off-by: Fabiano Fidêncio <fidencio@northflank.com>
1 parent 87007a2 commit d0225fe

3 files changed

Lines changed: 38 additions & 2 deletions

File tree

vmm/src/api/http/http_endpoint.rs

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@ use crate::api::http::{error_response, EndpointHandler, HttpError};
1515
#[cfg(all(target_arch = "x86_64", feature = "guest_debug"))]
1616
use crate::api::VmCoredump;
1717
use crate::api::{
18-
AddDisk, ApiAction, ApiRequest, NetConfig, VmAddDevice, VmAddFs, VmAddNet, VmAddPmem,
18+
AddDisk, ApiAction, ApiError, ApiRequest, NetConfig, VmAddDevice, VmAddFs, VmAddNet, VmAddPmem,
1919
VmAddUserDevice, VmAddVdpa, VmAddVsock, VmBoot, VmConfig, VmCounters, VmDelete, VmNmi, VmPause,
2020
VmPowerButton, VmReboot, VmReceiveMigration, VmRemoveDevice, VmResize, VmResizeZone, VmRestore,
2121
VmResume, VmSendMigration, VmShutdown, VmSnapshot,
2222
};
2323
use crate::config::RestoreConfig;
24+
use crate::cpu::Error as CpuError;
25+
use crate::vm::Error as VmError;
2426

2527
// /api/v1/vm.create handler
2628
pub struct VmCreate {}
@@ -183,7 +185,6 @@ vm_action_put_handler_body!(VmAddVdpa);
183185
vm_action_put_handler_body!(VmAddVsock);
184186
vm_action_put_handler_body!(VmAddUserDevice);
185187
vm_action_put_handler_body!(VmRemoveDevice);
186-
vm_action_put_handler_body!(VmResize);
187188
vm_action_put_handler_body!(VmResizeZone);
188189
vm_action_put_handler_body!(VmSnapshot);
189190
vm_action_put_handler_body!(VmReceiveMigration);
@@ -220,6 +221,34 @@ impl PutHandler for VmAddNet {
220221

221222
impl GetHandler for VmAddNet {}
222223

224+
impl PutHandler for VmResize {
225+
fn handle_request(
226+
&'static self,
227+
api_notifier: EventFd,
228+
api_sender: Sender<ApiRequest>,
229+
body: &Option<Body>,
230+
_files: Vec<File>,
231+
) -> std::result::Result<Option<Body>, HttpError> {
232+
if let Some(body) = body {
233+
self.send(
234+
api_notifier,
235+
api_sender,
236+
serde_json::from_slice(body.raw())?,
237+
)
238+
.map_err(|e| match e {
239+
ApiError::VmResize(VmError::CpuManager(CpuError::VcpuPendingRemovedVcpu)) => {
240+
HttpError::TooManyRequests
241+
}
242+
_ => HttpError::ApiError(e),
243+
})
244+
} else {
245+
Err(HttpError::BadRequest)
246+
}
247+
}
248+
}
249+
250+
impl GetHandler for VmResize {}
251+
223252
impl PutHandler for VmRestore {
224253
fn handle_request(
225254
&'static self,

vmm/src/api/http/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ pub enum HttpError {
5252
/// Undefined endpoints
5353
NotFound,
5454

55+
/// Too many requests
56+
TooManyRequests,
57+
5558
/// Internal Server Error
5659
InternalServerError,
5760

@@ -65,6 +68,7 @@ impl Display for HttpError {
6568
match self {
6669
BadRequest => write!(f, "Bad Request"),
6770
NotFound => write!(f, "Not Found"),
71+
TooManyRequests => write!(f, "Too Many Requests"),
6872
InternalServerError => write!(f, "Internal Server Error"),
6973
SerdeJsonDeserialize(serde_error) => write!(f, "{}", serde_error),
7074
ApiError(api_error) => write!(f, "{}", api_error),
@@ -125,6 +129,7 @@ pub trait EndpointHandler {
125129
Err(e @ HttpError::SerdeJsonDeserialize(_)) => {
126130
error_response(e, StatusCode::BadRequest)
127131
}
132+
Err(e @ HttpError::TooManyRequests) => error_response(e, StatusCode::TooManyRequests),
128133
Err(e) => error_response(e, StatusCode::InternalServerError),
129134
}
130135
}

vmm/src/api/openapi/cloud-hypervisor.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@ paths:
160160
description: The VM instance was successfully resized.
161161
404:
162162
description: The VM instance could not be resized because it is not created.
163+
429:
164+
description: The VM instance could not be resized because a cpu removal is still pending.
163165

164166
/vm.resize-zone:
165167
put:

0 commit comments

Comments
 (0)