Skip to content

Commit d5a0ed5

Browse files
committed
fix: Give build_microvm_from_requests a proper error type
Using FcExitCode as an error type is undesirable, as it allows us to construct Err(FcExitCode::Ok), e.g. an object that says "error: everything's okay!". This is confusing and has caused problems in different contexts before, so replace FcExitCode with a proper error type here. Signed-off-by: Patrick Roy <[email protected]>
1 parent 259c8b8 commit d5a0ed5

File tree

2 files changed

+28
-21
lines changed

2 files changed

+28
-21
lines changed

src/firecracker/src/api_server_adapter.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,17 @@ use utils::eventfd::EventFd;
1515
use vmm::logger::{error, warn, ProcessTimeReporter};
1616
use vmm::resources::VmResources;
1717
use vmm::rpc_interface::{
18-
ApiRequest, ApiResponse, PrebootApiController, RuntimeApiController, VmmAction,
18+
ApiRequest, ApiResponse, BuildMicrovmFromRequestsError, PrebootApiController,
19+
RuntimeApiController, VmmAction,
1920
};
2021
use vmm::vmm_config::instance_info::InstanceInfo;
2122
use vmm::{EventManager, FcExitCode, Vmm};
2223

2324
#[derive(Debug, thiserror::Error, displaydoc::Display)]
2425
pub enum ApiServerError {
25-
/// MicroVMStopped with an error: {0:?}
26+
/// Failed to build MicroVM: {0:?}.
27+
BuildMicroVmError(BuildMicrovmFromRequestsError),
28+
/// MicroVM stopped with an error: {0:?}
2629
MicroVMStoppedWithError(FcExitCode),
2730
/// Failed to open the API socket at: {0}. Check that it is not already used.
2831
FailedToBindSocket(String),
@@ -222,7 +225,7 @@ pub(crate) fn run_with_api(
222225
mmds_size_limit,
223226
metadata_json,
224227
)
225-
.map_err(ApiServerError::MicroVMStoppedWithError),
228+
.map_err(ApiServerError::BuildMicroVmError),
226229
};
227230

228231
let result = build_result.and_then(|(vm_resources, vmm)| {

src/vmm/src/rpc_interface.rs

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use super::{
2020
};
2121
use crate::builder::StartMicrovmError;
2222
use crate::cpu_config::templates::{CustomCpuTemplate, GuestConfigError};
23-
use crate::logger::{error, info, warn, LoggerConfig, *};
23+
use crate::logger::{info, warn, LoggerConfig, *};
2424
use crate::mmds::data_store::{self, Mmds};
2525
use crate::persist::{CreateSnapshotError, RestoreFromSnapshotError, VmInfo};
2626
use crate::resources::VmmConfig;
@@ -42,7 +42,7 @@ use crate::vmm_config::net::{
4242
use crate::vmm_config::snapshot::{CreateSnapshotParams, LoadSnapshotParams, SnapshotType};
4343
use crate::vmm_config::vsock::{VsockConfigError, VsockDeviceConfig};
4444
use crate::vmm_config::{self, RateLimiterUpdate};
45-
use crate::{EventManager, FcExitCode};
45+
use crate::EventManager;
4646

4747
/// This enum represents the public interface of the VMM. Each action contains various
4848
/// bits of information (ids, paths, etc.).
@@ -247,7 +247,7 @@ pub struct PrebootApiController<'a> {
247247
boot_path: bool,
248248
// Some PrebootApiRequest errors are irrecoverable and Firecracker
249249
// should cleanly teardown if they occur.
250-
fatal_error: Option<FcExitCode>,
250+
fatal_error: Option<BuildMicrovmFromRequestsError>,
251251
}
252252

253253
// TODO Remove when `EventManager` implements `std::fmt::Debug`.
@@ -287,6 +287,17 @@ pub type ApiRequest = Box<VmmAction>;
287287
/// Shorthand type for a response containing a boxed Result.
288288
pub type ApiResponse = Box<std::result::Result<VmmData, VmmActionError>>;
289289

290+
/// Error type for `PrebootApiController::build_microvm_from_requests`.
291+
#[derive(Debug, thiserror::Error, displaydoc::Display, derive_more::From)]
292+
pub enum BuildMicrovmFromRequestsError {
293+
/// Populating MMDS from file failed: {0}.
294+
Mmds(data_store::Error),
295+
/// Loading snapshot failed.
296+
Restore,
297+
/// Resuming MicroVM after loading snapshot failed.
298+
Resume,
299+
}
300+
290301
impl<'a> PrebootApiController<'a> {
291302
/// Constructor for the PrebootApiController.
292303
pub fn new(
@@ -320,7 +331,7 @@ impl<'a> PrebootApiController<'a> {
320331
boot_timer_enabled: bool,
321332
mmds_size_limit: usize,
322333
metadata_json: Option<&str>,
323-
) -> Result<(VmResources, Arc<Mutex<Vmm>>), FcExitCode> {
334+
) -> Result<(VmResources, Arc<Mutex<Vmm>>), BuildMicrovmFromRequestsError> {
324335
let mut vm_resources = VmResources::default();
325336
// Silence false clippy warning. Clippy suggests using
326337
// VmResources { boot_timer: boot_timer_enabled, ..Default::default() }; but this will
@@ -333,16 +344,9 @@ impl<'a> PrebootApiController<'a> {
333344

334345
// Init the data store from file, if present.
335346
if let Some(data) = metadata_json {
336-
vm_resources
337-
.locked_mmds_or_default()
338-
.put_data(
339-
serde_json::from_str(data)
340-
.expect("MMDS error: metadata provided not valid json"),
341-
)
342-
.map_err(|err| {
343-
error!("Populating MMDS from file failed: {:?}", err);
344-
crate::FcExitCode::GenericError
345-
})?;
347+
vm_resources.locked_mmds_or_default().put_data(
348+
serde_json::from_str(data).expect("MMDS error: metadata provided not valid json"),
349+
)?;
346350

347351
info!("Successfully added metadata to mmds from file");
348352
}
@@ -376,8 +380,8 @@ impl<'a> PrebootApiController<'a> {
376380
to_api.send(Box::new(res)).expect("one-shot channel closed");
377381

378382
// If any fatal errors were encountered, break the loop.
379-
if let Some(exit_code) = preboot_controller.fatal_error {
380-
return Err(exit_code);
383+
if let Some(preboot_error) = preboot_controller.fatal_error {
384+
return Err(preboot_error);
381385
}
382386
}
383387

@@ -577,7 +581,7 @@ impl<'a> PrebootApiController<'a> {
577581
)
578582
.map_err(|err| {
579583
// If restore fails, we consider the process is too dirty to recover.
580-
self.fatal_error = Some(FcExitCode::BadConfiguration);
584+
self.fatal_error = Some(BuildMicrovmFromRequestsError::Restore);
581585
err
582586
})?;
583587
// Resume VM
@@ -587,7 +591,7 @@ impl<'a> PrebootApiController<'a> {
587591
.resume_vm()
588592
.map_err(|err| {
589593
// If resume fails, we consider the process is too dirty to recover.
590-
self.fatal_error = Some(FcExitCode::BadConfiguration);
594+
self.fatal_error = Some(BuildMicrovmFromRequestsError::Resume);
591595
err
592596
})?;
593597
}

0 commit comments

Comments
 (0)