Skip to content

Commit 26a3d10

Browse files
acatangiualxiord
authored andcommitted
vmm: std::convert::From<StartMicrovmError> for VmmActionError
Decorate each type of StartMicrovmError with the correct ErrorKind. Signed-off-by: Adrian Catangiu <[email protected]>
1 parent d6a63ca commit 26a3d10

File tree

2 files changed

+85
-54
lines changed

2 files changed

+85
-54
lines changed

vmm/src/lib.rs

Lines changed: 54 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,49 @@ pub enum VmmActionError {
212212
VsockConfig(ErrorKind, VsockError),
213213
}
214214

215+
// It's convenient to turn StartMicrovmErrors into VmmActionErrors directly.
216+
impl std::convert::From<StartMicrovmError> for VmmActionError {
217+
fn from(e: StartMicrovmError) -> Self {
218+
let kind = match e {
219+
// User errors.
220+
#[cfg(feature = "vsock")]
221+
StartMicrovmError::CreateVsockDevice(_) => ErrorKind::User,
222+
StartMicrovmError::CreateBlockDevice(_)
223+
| StartMicrovmError::CreateNetDevice(_)
224+
| StartMicrovmError::KernelCmdline(_)
225+
| StartMicrovmError::KernelLoader(_)
226+
| StartMicrovmError::MicroVMAlreadyRunning
227+
| StartMicrovmError::MissingKernelConfig
228+
| StartMicrovmError::NetDeviceNotConfigured
229+
| StartMicrovmError::OpenBlockDevice(_)
230+
| StartMicrovmError::VcpusNotConfigured => ErrorKind::User,
231+
// Internal errors.
232+
#[cfg(feature = "vsock")]
233+
StartMicrovmError::RegisterVsockDevice(_) => ErrorKind::Internal,
234+
StartMicrovmError::ConfigureSystem(_)
235+
| StartMicrovmError::ConfigureVm(_)
236+
| StartMicrovmError::CreateRateLimiter(_)
237+
| StartMicrovmError::DeviceManager
238+
| StartMicrovmError::EventFd
239+
| StartMicrovmError::GuestMemory(_)
240+
| StartMicrovmError::LegacyIOBus(_)
241+
| StartMicrovmError::RegisterBlockDevice(_)
242+
| StartMicrovmError::RegisterEvent
243+
| StartMicrovmError::RegisterNetDevice(_)
244+
| StartMicrovmError::SeccompFilters(_)
245+
| StartMicrovmError::Vcpu(_)
246+
| StartMicrovmError::VcpuConfigure(_)
247+
| StartMicrovmError::VcpuSpawn(_) => ErrorKind::Internal,
248+
// The only user `LoadCommandline` error is `CommandLineOverflow`.
249+
StartMicrovmError::LoadCommandline(ref cle) => match cle {
250+
kernel_loader::Error::CommandLineOverflow => ErrorKind::User,
251+
_ => ErrorKind::Internal,
252+
},
253+
};
254+
VmmActionError::StartMicrovm(kind, e)
255+
}
256+
}
257+
215258
impl VmmActionError {
216259
/// Returns the error type.
217260
pub fn get_kind(&self) -> &ErrorKind {
@@ -1175,51 +1218,36 @@ impl Vmm {
11751218
fn start_microvm(&mut self) -> std::result::Result<VmmData, VmmActionError> {
11761219
info!("VMM received instance start command");
11771220
if self.is_instance_initialized() {
1178-
return Err(VmmActionError::StartMicrovm(
1179-
ErrorKind::User,
1180-
StartMicrovmError::MicroVMAlreadyRunning,
1181-
));
1221+
Err(StartMicrovmError::MicroVMAlreadyRunning)?;
11821222
}
11831223
let request_ts = TimestampUs {
11841224
time_us: get_time_us(),
11851225
cputime_us: now_cputime_us(),
11861226
};
11871227

1188-
self.check_health()
1189-
.map_err(|e| VmmActionError::StartMicrovm(ErrorKind::User, e))?;
1228+
self.check_health()?;
11901229
// Use expect() to crash if the other thread poisoned this lock.
11911230
self.shared_info
11921231
.write()
11931232
.expect("Failed to start microVM because shared info couldn't be written due to poisoned lock")
11941233
.state = InstanceState::Starting;
11951234

1196-
self.init_guest_memory()
1197-
.map_err(|e| VmmActionError::StartMicrovm(ErrorKind::Internal, e))?;
1235+
self.init_guest_memory()?;
11981236

1199-
self.setup_interrupt_controller()
1200-
.map_err(|e| VmmActionError::StartMicrovm(ErrorKind::Internal, e))?;
1237+
self.setup_interrupt_controller()?;
12011238

1202-
self.attach_virtio_devices()
1203-
.map_err(|e| VmmActionError::StartMicrovm(ErrorKind::Internal, e))?;
1204-
self.attach_legacy_devices()
1205-
.map_err(|e| VmmActionError::StartMicrovm(ErrorKind::Internal, e))?;
1239+
self.attach_virtio_devices()?;
1240+
self.attach_legacy_devices()?;
12061241

1207-
let entry_addr = self
1208-
.load_kernel()
1209-
.map_err(|e| VmmActionError::StartMicrovm(ErrorKind::Internal, e))?;
1242+
let entry_addr = self.load_kernel()?;
12101243

1211-
self.configure_system()
1212-
.map_err(|e| VmmActionError::StartMicrovm(ErrorKind::Internal, e))?;
1244+
self.configure_system()?;
12131245

1214-
self.register_events()
1215-
.map_err(|e| VmmActionError::StartMicrovm(ErrorKind::Internal, e))?;
1246+
self.register_events()?;
12161247

1217-
let vcpus = self
1218-
.create_vcpus(entry_addr, request_ts)
1219-
.map_err(|e| VmmActionError::StartMicrovm(ErrorKind::Internal, e))?;
1248+
let vcpus = self.create_vcpus(entry_addr, request_ts)?;
12201249

1221-
self.start_vcpus(vcpus)
1222-
.map_err(|e| VmmActionError::StartMicrovm(ErrorKind::Internal, e))?;
1250+
self.start_vcpus(vcpus)?;
12231251
// Use expect() to crash if the other thread poisoned this lock.
12241252
self.shared_info
12251253
.write()
@@ -1989,7 +2017,6 @@ mod tests {
19892017
use super::*;
19902018

19912019
use serde_json::Value;
1992-
use std::env;
19932020
use std::fs::File;
19942021
use std::io::BufRead;
19952022
use std::io::BufReader;

vmm/src/vstate.rs

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -76,21 +76,21 @@ pub enum Error {
7676
/// Cannot configure the IRQ.
7777
Irq(io::Error),
7878
/// Cannot spawn a new vCPU thread.
79-
VcpuSpawn(std::io::Error),
79+
VcpuSpawn(io::Error),
8080
/// Unexpected KVM_RUN exit reason
8181
VcpuUnhandledKvmExit,
8282
#[cfg(target_arch = "aarch64")]
8383
/// Error setting up the global interrupt controller.
8484
SetupGIC(arch::aarch64::gic::Error),
85+
#[cfg(target_arch = "aarch64")]
86+
/// Error getting the Vcpu preferred target on Arm.
87+
VcpuArmPreferredTarget(io::Error),
88+
#[cfg(target_arch = "aarch64")]
89+
/// Error doing Vcpu Init on Arm.
90+
VcpuArmInit(io::Error),
8591
}
8692
pub type Result<T> = result::Result<T, Error>;
8793

88-
impl ::std::convert::From<io::Error> for Error {
89-
fn from(e: io::Error) -> Error {
90-
Error::SetUserMemoryRegion(e)
91-
}
92-
}
93-
9494
/// A wrapper around creating and using a VM.
9595
pub struct Vm {
9696
fd: VmFd,
@@ -136,24 +136,26 @@ impl Vm {
136136
if guest_mem.num_regions() > kvm_context.max_memslots() {
137137
return Err(Error::NotEnoughMemorySlots);
138138
}
139-
guest_mem.with_regions(|index, guest_addr, size, host_addr| {
140-
info!("Guest memory starts at {:x?}", host_addr);
141-
142-
let flags = if LOGGER.flags() & LogOption::LogDirtyPages as usize > 0 {
143-
KVM_MEM_LOG_DIRTY_PAGES
144-
} else {
145-
0
146-
};
147-
148-
let memory_region = kvm_userspace_memory_region {
149-
slot: index as u32,
150-
guest_phys_addr: guest_addr.offset() as u64,
151-
memory_size: size as u64,
152-
userspace_addr: host_addr as u64,
153-
flags,
154-
};
155-
self.fd.set_user_memory_region(memory_region)
156-
})?;
139+
guest_mem
140+
.with_regions(|index, guest_addr, size, host_addr| {
141+
info!("Guest memory starts at {:x?}", host_addr);
142+
143+
let flags = if LOGGER.flags() & LogOption::LogDirtyPages as usize > 0 {
144+
KVM_MEM_LOG_DIRTY_PAGES
145+
} else {
146+
0
147+
};
148+
149+
let memory_region = kvm_userspace_memory_region {
150+
slot: index as u32,
151+
guest_phys_addr: guest_addr.offset() as u64,
152+
memory_size: size as u64,
153+
userspace_addr: host_addr as u64,
154+
flags,
155+
};
156+
self.fd.set_user_memory_region(memory_region)
157+
})
158+
.map_err(Error::SetUserMemoryRegion)?;
157159
self.guest_mem = Some(guest_mem);
158160

159161
#[cfg(target_arch = "x86_64")]
@@ -330,15 +332,17 @@ impl Vcpu {
330332
let mut kvi: kvm_bindings::kvm_vcpu_init = kvm_bindings::kvm_vcpu_init::default();
331333

332334
// This reads back the kernel's preferred target type.
333-
vm.fd.get_preferred_target(&mut kvi)?;
335+
vm.fd
336+
.get_preferred_target(&mut kvi)
337+
.map_err(Error::VcpuArmPreferredTarget)?;
334338
// We already checked that the capability is supported.
335339
kvi.features[0] |= 1 << kvm_bindings::KVM_ARM_VCPU_PSCI_0_2;
336340
// Non-boot cpus are powered off initially.
337341
if self.id > 0 {
338342
kvi.features[0] |= 1 << kvm_bindings::KVM_ARM_VCPU_POWER_OFF;
339343
}
340344

341-
self.fd.vcpu_init(&kvi)?;
345+
self.fd.vcpu_init(&kvi).map_err(Error::VcpuArmInit)?;
342346
arch::aarch64::regs::setup_regs(&self.fd, self.id, kernel_load_addr.offset(), vm_memory)
343347
.map_err(Error::REGSConfiguration)?;
344348
Ok(())

0 commit comments

Comments
 (0)