mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-10-01 11:05:46 +00:00
vmm: Improve error handling for vmm::vm::Error
In particular implement thiserror::Error, cleanup wording and remove unused errors. Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
parent
cb03540ffd
commit
62f17ccf8c
@ -508,7 +508,7 @@ impl Vmm {
|
|||||||
|
|
||||||
let source_url = restore_cfg.source_url.as_path().to_str();
|
let source_url = restore_cfg.source_url.as_path().to_str();
|
||||||
if source_url.is_none() {
|
if source_url.is_none() {
|
||||||
return Err(VmError::RestoreSourceUrlPathToStr);
|
return Err(VmError::InvalidRestoreSourceUrl);
|
||||||
}
|
}
|
||||||
// Safe to unwrap as we checked it was Some(&str).
|
// Safe to unwrap as we checked it was Some(&str).
|
||||||
let source_url = source_url.unwrap();
|
let source_url = source_url.unwrap();
|
||||||
|
203
vmm/src/vm.rs
203
vmm/src/vm.rs
@ -17,7 +17,7 @@ use crate::config::{
|
|||||||
UserDeviceConfig, ValidationError, VdpaConfig, VmConfig, VsockConfig,
|
UserDeviceConfig, ValidationError, VdpaConfig, VmConfig, VsockConfig,
|
||||||
};
|
};
|
||||||
use crate::cpu;
|
use crate::cpu;
|
||||||
use crate::device_manager::{self, Console, DeviceManager, DeviceManagerError, PtyPair};
|
use crate::device_manager::{Console, DeviceManager, DeviceManagerError, PtyPair};
|
||||||
use crate::device_tree::DeviceTree;
|
use crate::device_tree::DeviceTree;
|
||||||
#[cfg(feature = "gdb")]
|
#[cfg(feature = "gdb")]
|
||||||
use crate::gdb::{Debuggable, DebuggableError, GdbRequestPayload, GdbResponsePayload};
|
use crate::gdb::{Debuggable, DebuggableError, GdbRequestPayload, GdbResponsePayload};
|
||||||
@ -73,6 +73,7 @@ use std::os::unix::net::UnixStream;
|
|||||||
use std::panic::AssertUnwindSafe;
|
use std::panic::AssertUnwindSafe;
|
||||||
use std::sync::{Arc, Mutex, RwLock};
|
use std::sync::{Arc, Mutex, RwLock};
|
||||||
use std::{result, str, thread};
|
use std::{result, str, thread};
|
||||||
|
use thiserror::Error;
|
||||||
use vm_device::Bus;
|
use vm_device::Bus;
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use vm_device::BusDevice;
|
use vm_device::BusDevice;
|
||||||
@ -99,200 +100,192 @@ use arch::aarch64::gic::kvm::create_gic;
|
|||||||
use devices::interrupt_controller::{self, InterruptController};
|
use devices::interrupt_controller::{self, InterruptController};
|
||||||
|
|
||||||
/// Errors associated with VM management
|
/// Errors associated with VM management
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// Cannot open the kernel image
|
#[error("Cannot open kernel file: {0}")]
|
||||||
KernelFile(io::Error),
|
KernelFile(#[source] io::Error),
|
||||||
|
|
||||||
/// Cannot open the initramfs image
|
#[error("Cannot open initramfs file: {0}")]
|
||||||
InitramfsFile(io::Error),
|
InitramfsFile(#[source] io::Error),
|
||||||
|
|
||||||
/// Cannot load the kernel in memory
|
#[error("Cannot load the kernel into memory: {0}")]
|
||||||
KernelLoad(linux_loader::loader::Error),
|
KernelLoad(#[source] linux_loader::loader::Error),
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
/// Cannot load the UEFI binary in memory
|
#[error("Cannot load the UEFI binary in memory: {0:?}")]
|
||||||
UefiLoad(arch::aarch64::uefi::Error),
|
UefiLoad(arch::aarch64::uefi::Error),
|
||||||
|
|
||||||
/// Cannot load the initramfs in memory
|
#[error("Cannot load the initramfs into memory")]
|
||||||
InitramfsLoad,
|
InitramfsLoad,
|
||||||
|
|
||||||
/// Cannot load the command line in memory
|
#[error("Cannot load the kernel command line in memory: {0}")]
|
||||||
LoadCmdLine(linux_loader::loader::Error),
|
LoadCmdLine(#[source] linux_loader::loader::Error),
|
||||||
|
|
||||||
/// Cannot modify the command line
|
#[error("Cannot modify the kernel command line: {0}")]
|
||||||
CmdLineInsertStr(linux_loader::cmdline::Error),
|
CmdLineInsertStr(#[source] linux_loader::cmdline::Error),
|
||||||
|
|
||||||
/// Cannot configure system
|
#[error("Cannot configure system: {0}")]
|
||||||
ConfigureSystem(arch::Error),
|
ConfigureSystem(#[source] arch::Error),
|
||||||
|
|
||||||
/// Cannot enable interrupt controller
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
#[error("Cannot enable interrupt controller: {0:?}")]
|
||||||
EnableInterruptController(interrupt_controller::Error),
|
EnableInterruptController(interrupt_controller::Error),
|
||||||
|
|
||||||
|
#[error("VM state is poisoned")]
|
||||||
PoisonedState,
|
PoisonedState,
|
||||||
|
|
||||||
/// Cannot create a device manager.
|
#[error("Error from device manager: {0:?}")]
|
||||||
DeviceManager(DeviceManagerError),
|
DeviceManager(DeviceManagerError),
|
||||||
|
|
||||||
/// Write to the console failed.
|
#[error("Cannot setup terminal in raw mode: {0}")]
|
||||||
Console(vmm_sys_util::errno::Error),
|
SetTerminalRaw(#[source] vmm_sys_util::errno::Error),
|
||||||
|
|
||||||
/// Write to the pty console failed.
|
#[error("Cannot setup terminal in canonical mode.: {0}")]
|
||||||
PtyConsole(io::Error),
|
SetTerminalCanon(#[source] vmm_sys_util::errno::Error),
|
||||||
|
|
||||||
/// Cannot setup terminal in raw mode.
|
#[error("Cannot spawn a signal handler thread: {0}")]
|
||||||
SetTerminalRaw(vmm_sys_util::errno::Error),
|
SignalHandlerSpawn(#[source] io::Error),
|
||||||
|
|
||||||
/// Cannot setup terminal in canonical mode.
|
#[error("Failed to join on threads: {0:?}")]
|
||||||
SetTerminalCanon(vmm_sys_util::errno::Error),
|
|
||||||
|
|
||||||
/// Memory is overflow
|
|
||||||
MemOverflow,
|
|
||||||
|
|
||||||
/// Cannot spawn a signal handler thread
|
|
||||||
SignalHandlerSpawn(io::Error),
|
|
||||||
|
|
||||||
/// Failed to join on vCPU threads
|
|
||||||
ThreadCleanup(std::boxed::Box<dyn std::any::Any + std::marker::Send>),
|
ThreadCleanup(std::boxed::Box<dyn std::any::Any + std::marker::Send>),
|
||||||
|
|
||||||
/// VM config is missing.
|
#[error("VM config is missing")]
|
||||||
VmMissingConfig,
|
VmMissingConfig,
|
||||||
|
|
||||||
/// VM is not created
|
#[error("VM is not created")]
|
||||||
VmNotCreated,
|
VmNotCreated,
|
||||||
|
|
||||||
/// VM is already created
|
#[error("VM is already created")]
|
||||||
VmAlreadyCreated,
|
VmAlreadyCreated,
|
||||||
|
|
||||||
/// VM is not running
|
#[error("VM is not running")]
|
||||||
VmNotRunning,
|
VmNotRunning,
|
||||||
|
|
||||||
/// Cannot clone EventFd.
|
#[error("Cannot clone EventFd: {0}")]
|
||||||
EventFdClone(io::Error),
|
EventFdClone(#[source] io::Error),
|
||||||
|
|
||||||
/// Invalid VM state transition
|
#[error("invalid VM state transition: {0:?} to {1:?}")]
|
||||||
InvalidStateTransition(VmState, VmState),
|
InvalidStateTransition(VmState, VmState),
|
||||||
|
|
||||||
/// Error from CPU handling
|
#[error("Error from CPU manager: {0}")]
|
||||||
CpuManager(cpu::Error),
|
CpuManager(#[source] cpu::Error),
|
||||||
|
|
||||||
/// Cannot pause devices
|
#[error("Cannot pause devices: {0}")]
|
||||||
PauseDevices(MigratableError),
|
PauseDevices(#[source] MigratableError),
|
||||||
|
|
||||||
/// Cannot resume devices
|
#[error("Cannot resume devices: {0}")]
|
||||||
ResumeDevices(MigratableError),
|
ResumeDevices(#[source] MigratableError),
|
||||||
|
|
||||||
/// Cannot pause CPUs
|
#[error("Cannot pause CPUs: {0}")]
|
||||||
PauseCpus(MigratableError),
|
PauseCpus(#[source] MigratableError),
|
||||||
|
|
||||||
/// Cannot resume cpus
|
#[error("Cannot resume cpus: {0}")]
|
||||||
ResumeCpus(MigratableError),
|
ResumeCpus(#[source] MigratableError),
|
||||||
|
|
||||||
/// Cannot pause VM
|
#[error("Cannot pause VM: {0}")]
|
||||||
Pause(MigratableError),
|
Pause(#[source] MigratableError),
|
||||||
|
|
||||||
/// Cannot resume VM
|
#[error("Cannot resume VM: {0}")]
|
||||||
Resume(MigratableError),
|
Resume(#[source] MigratableError),
|
||||||
|
|
||||||
/// Memory manager error
|
#[error("Memory manager error: {0:?}")]
|
||||||
MemoryManager(MemoryManagerError),
|
MemoryManager(MemoryManagerError),
|
||||||
|
|
||||||
/// Eventfd write error
|
#[error("Eventfd write error: {0}")]
|
||||||
EventfdError(std::io::Error),
|
EventfdError(#[source] std::io::Error),
|
||||||
|
|
||||||
/// Cannot snapshot VM
|
#[error("Cannot snapshot VM: {0}")]
|
||||||
Snapshot(MigratableError),
|
Snapshot(#[source] MigratableError),
|
||||||
|
|
||||||
/// Cannot restore VM
|
#[error("Cannot restore VM: {0}")]
|
||||||
Restore(MigratableError),
|
Restore(#[source] MigratableError),
|
||||||
|
|
||||||
/// Cannot send VM snapshot
|
#[error("Cannot send VM snapshot: {0}")]
|
||||||
SnapshotSend(MigratableError),
|
SnapshotSend(#[source] MigratableError),
|
||||||
|
|
||||||
/// Cannot convert source URL from Path into &str
|
#[error("Invalid restore source URL")]
|
||||||
RestoreSourceUrlPathToStr,
|
InvalidRestoreSourceUrl,
|
||||||
|
|
||||||
/// Failed to validate config
|
#[error("Failed to validate config: {0}")]
|
||||||
ConfigValidation(ValidationError),
|
ConfigValidation(#[source] ValidationError),
|
||||||
|
|
||||||
/// No more that one virtio-vsock device
|
#[error("Too many virtio-vsock devices")]
|
||||||
TooManyVsockDevices,
|
TooManyVsockDevices,
|
||||||
|
|
||||||
/// Failed serializing into JSON
|
#[error("Failed serializing into JSON: {0}")]
|
||||||
SerializeJson(serde_json::Error),
|
SerializeJson(#[source] serde_json::Error),
|
||||||
|
|
||||||
/// Invalid configuration for NUMA.
|
#[error("Invalid NUMA configuration")]
|
||||||
InvalidNumaConfig,
|
InvalidNumaConfig,
|
||||||
|
|
||||||
/// Cannot create seccomp filter
|
#[error("Cannot create seccomp filter: {0}")]
|
||||||
CreateSeccompFilter(seccompiler::Error),
|
CreateSeccompFilter(#[source] seccompiler::Error),
|
||||||
|
|
||||||
/// Cannot apply seccomp filter
|
#[error("Cannot apply seccomp filter: {0}")]
|
||||||
ApplySeccompFilter(seccompiler::Error),
|
ApplySeccompFilter(#[source] seccompiler::Error),
|
||||||
|
|
||||||
/// Failed resizing a memory zone.
|
#[error("Failed resizing a memory zone")]
|
||||||
ResizeZone,
|
ResizeZone,
|
||||||
|
|
||||||
/// Cannot activate virtio devices
|
#[error("Cannot activate virtio devices: {0:?}")]
|
||||||
ActivateVirtioDevices(device_manager::DeviceManagerError),
|
ActivateVirtioDevices(DeviceManagerError),
|
||||||
|
|
||||||
/// Error triggering power button
|
#[error("Error triggering power button: {0:?}")]
|
||||||
PowerButton(device_manager::DeviceManagerError),
|
PowerButton(DeviceManagerError),
|
||||||
|
|
||||||
/// Kernel lacks PVH header
|
#[error("Kernel lacks PVH header")]
|
||||||
KernelMissingPvhHeader,
|
KernelMissingPvhHeader,
|
||||||
|
|
||||||
/// Failed to allocate firmware RAM
|
#[error("Failed to allocate firmware RAM: {0:?}")]
|
||||||
AllocateFirmwareMemory(MemoryManagerError),
|
AllocateFirmwareMemory(MemoryManagerError),
|
||||||
|
|
||||||
/// Error manipulating firmware file
|
#[error("Error manipulating firmware file: {0}")]
|
||||||
FirmwareFile(std::io::Error),
|
FirmwareFile(#[source] std::io::Error),
|
||||||
|
|
||||||
/// Firmware too big
|
#[error("Firmware too big")]
|
||||||
FirmwareTooLarge,
|
FirmwareTooLarge,
|
||||||
|
|
||||||
// Failed to copy to memory
|
#[error("Failed to copy firmware to memory: {0}")]
|
||||||
FirmwareLoad(vm_memory::GuestMemoryError),
|
FirmwareLoad(#[source] vm_memory::GuestMemoryError),
|
||||||
|
|
||||||
/// Error performing I/O on TDX firmware file
|
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
LoadTdvf(std::io::Error),
|
#[error("Error performing I/O on TDX firmware file: {0}")]
|
||||||
|
LoadTdvf(#[source] std::io::Error),
|
||||||
|
|
||||||
/// Error performing I/O on the payload file
|
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
LoadPayload(std::io::Error),
|
#[error("Error performing I/O on the TDX payload file: {0}")]
|
||||||
|
LoadPayload(#[source] std::io::Error),
|
||||||
|
|
||||||
/// Error parsing TDVF
|
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
ParseTdvf(arch::x86_64::tdx::TdvfError),
|
#[error("Error parsing TDVF: {0}")]
|
||||||
|
ParseTdvf(#[source] arch::x86_64::tdx::TdvfError),
|
||||||
|
|
||||||
/// Error populating HOB
|
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
PopulateHob(arch::x86_64::tdx::TdvfError),
|
#[error("Error populating TDX HOB: {0}")]
|
||||||
|
PopulateHob(#[source] arch::x86_64::tdx::TdvfError),
|
||||||
|
|
||||||
/// Error allocating TDVF memory
|
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
|
#[error("Error allocating TDVF memory: {0:?}")]
|
||||||
AllocatingTdvfMemory(crate::memory_manager::Error),
|
AllocatingTdvfMemory(crate::memory_manager::Error),
|
||||||
|
|
||||||
/// Error enabling TDX VM
|
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
InitializeTdxVm(hypervisor::HypervisorVmError),
|
#[error("Error enabling TDX VM: {0}")]
|
||||||
|
InitializeTdxVm(#[source] hypervisor::HypervisorVmError),
|
||||||
|
|
||||||
/// Error enabling TDX memory region
|
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
InitializeTdxMemoryRegion(hypervisor::HypervisorVmError),
|
#[error("Error enabling TDX memory region: {0}")]
|
||||||
|
InitializeTdxMemoryRegion(#[source] hypervisor::HypervisorVmError),
|
||||||
|
|
||||||
/// Error finalizing TDX setup
|
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
FinalizeTdx(hypervisor::HypervisorVmError),
|
#[error("Error finalizing TDX VM: {0}")]
|
||||||
|
FinalizeTdx(#[source] hypervisor::HypervisorVmError),
|
||||||
|
|
||||||
/// Invalid payload type
|
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
|
#[error("Invalid TDX payload type")]
|
||||||
InvalidPayloadType,
|
InvalidPayloadType,
|
||||||
|
|
||||||
/// Error debugging VM
|
|
||||||
#[cfg(feature = "gdb")]
|
#[cfg(feature = "gdb")]
|
||||||
|
#[error("Error debugging VM: {0:?}")]
|
||||||
Debug(DebuggableError),
|
Debug(DebuggableError),
|
||||||
}
|
}
|
||||||
pub type Result<T> = result::Result<T, Error>;
|
pub type Result<T> = result::Result<T, Error>;
|
||||||
|
Loading…
Reference in New Issue
Block a user