virtio-devices: Create a proper result type for VirtioPciDevice

Creating a dedicated Result type for VirtioPciDevice, associated with
the new VirtioPciDeviceError enum. This allows for a clearer handling of
the errors generated through VirtioPciDevice::new().

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf
2022-11-23 15:01:16 +01:00
committed by Rob Bradford
parent eae8043890
commit a50b3784fe
3 changed files with 56 additions and 35 deletions
+1 -1
View File
@@ -6,7 +6,7 @@ use vmm_sys_util::eventfd::EventFd;
mod pci_common_config; mod pci_common_config;
mod pci_device; mod pci_device;
pub use pci_common_config::{VirtioPciCommonConfig, VIRTIO_PCI_COMMON_CONFIG_ID}; pub use pci_common_config::{VirtioPciCommonConfig, VIRTIO_PCI_COMMON_CONFIG_ID};
pub use pci_device::{VirtioPciDevice, VirtioPciDeviceActivator}; pub use pci_device::{VirtioPciDevice, VirtioPciDeviceActivator, VirtioPciDeviceError};
pub trait VirtioTransport { pub trait VirtioTransport {
fn ioeventfds(&self, base_addr: u64) -> Vec<(&EventFd, u64)>; fn ioeventfds(&self, base_addr: u64) -> Vec<(&EventFd, u64)>;
+54 -33
View File
@@ -13,6 +13,7 @@ use crate::{
DEVICE_ACKNOWLEDGE, DEVICE_DRIVER, DEVICE_DRIVER_OK, DEVICE_FAILED, DEVICE_FEATURES_OK, DEVICE_ACKNOWLEDGE, DEVICE_DRIVER, DEVICE_DRIVER_OK, DEVICE_FAILED, DEVICE_FEATURES_OK,
DEVICE_INIT, DEVICE_INIT,
}; };
use anyhow::anyhow;
use libc::EFD_NONBLOCK; use libc::EFD_NONBLOCK;
use pci::{ use pci::{
BarReprogrammingParams, MsixCap, MsixConfig, PciBarConfiguration, PciBarRegionType, BarReprogrammingParams, MsixCap, MsixConfig, PciBarConfiguration, PciBarRegionType,
@@ -23,9 +24,9 @@ use std::any::Any;
use std::cmp; use std::cmp;
use std::io::Write; use std::io::Write;
use std::ops::Deref; use std::ops::Deref;
use std::result;
use std::sync::atomic::{AtomicBool, AtomicU16, AtomicUsize, Ordering}; use std::sync::atomic::{AtomicBool, AtomicU16, AtomicUsize, Ordering};
use std::sync::{Arc, Barrier, Mutex}; use std::sync::{Arc, Barrier, Mutex};
use thiserror::Error;
use versionize::{VersionMap, Versionize, VersionizeResult}; use versionize::{VersionMap, Versionize, VersionizeResult};
use versionize_derive::Versionize; use versionize_derive::Versionize;
use virtio_queue::{Queue, QueueT}; use virtio_queue::{Queue, QueueT};
@@ -40,7 +41,7 @@ use vm_migration::{
Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable, VersionMapped, Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable, VersionMapped,
}; };
use vm_virtio::AccessPlatform; use vm_virtio::AccessPlatform;
use vmm_sys_util::{errno::Result, eventfd::EventFd}; use vmm_sys_util::eventfd::EventFd;
use super::pci_common_config::VirtioPciCommonConfigState; use super::pci_common_config::VirtioPciCommonConfigState;
@@ -311,6 +312,13 @@ impl VirtioPciDeviceActivator {
} }
} }
#[derive(Error, Debug)]
pub enum VirtioPciDeviceError {
#[error("Failed creating VirtioPciDevice: {0}")]
CreateVirtioPciDevice(#[source] anyhow::Error),
}
pub type Result<T> = std::result::Result<T, VirtioPciDeviceError>;
pub struct VirtioPciDevice { pub struct VirtioPciDevice {
id: String, id: String,
@@ -389,7 +397,12 @@ impl VirtioPciDevice {
let mut locked_device = device.lock().unwrap(); let mut locked_device = device.lock().unwrap();
let mut queue_evts = Vec::new(); let mut queue_evts = Vec::new();
for _ in locked_device.queue_max_sizes().iter() { for _ in locked_device.queue_max_sizes().iter() {
queue_evts.push(EventFd::new(EFD_NONBLOCK)?) queue_evts.push(EventFd::new(EFD_NONBLOCK).map_err(|e| {
VirtioPciDeviceError::CreateVirtioPciDevice(anyhow!(
"Failed creating eventfd: {}",
e
))
})?)
} }
let num_queues = locked_device.queue_max_sizes().len(); let num_queues = locked_device.queue_max_sizes().len();
@@ -405,18 +418,25 @@ impl VirtioPciDevice {
let pci_device_id = VIRTIO_PCI_DEVICE_ID_BASE + locked_device.device_type() as u16; let pci_device_id = VIRTIO_PCI_DEVICE_ID_BASE + locked_device.device_type() as u16;
let interrupt_source_group = interrupt_manager.create_group(MsiIrqGroupConfig { let interrupt_source_group = interrupt_manager
base: 0, .create_group(MsiIrqGroupConfig {
count: msix_num as InterruptIndex, base: 0,
})?; count: msix_num as InterruptIndex,
})
.map_err(|e| {
VirtioPciDeviceError::CreateVirtioPciDevice(anyhow!(
"Failed creating MSI interrupt group: {}",
e
))
})?;
let msix_state = let msix_state =
vm_migration::versioned_state_from_id(snapshot.as_ref(), pci::MSIX_CONFIG_ID).map_err( vm_migration::versioned_state_from_id(snapshot.as_ref(), pci::MSIX_CONFIG_ID).map_err(
|e| { |e| {
std::io::Error::new( VirtioPciDeviceError::CreateVirtioPciDevice(anyhow!(
std::io::ErrorKind::Other, "Failed to get MsixConfigState from Snapshot: {}",
format!("Failed to get MsixConfigState from Snapshot: {}", e), e
) ))
}, },
)?; )?;
@@ -454,10 +474,10 @@ impl VirtioPciDevice {
let pci_configuration_state = let pci_configuration_state =
vm_migration::versioned_state_from_id(snapshot.as_ref(), pci::PCI_CONFIGURATION_ID) vm_migration::versioned_state_from_id(snapshot.as_ref(), pci::PCI_CONFIGURATION_ID)
.map_err(|e| { .map_err(|e| {
std::io::Error::new( VirtioPciDeviceError::CreateVirtioPciDevice(anyhow!(
std::io::ErrorKind::Other, "Failed to get PciConfigurationState from Snapshot: {}",
format!("Failed to get PciConfigurationState from Snapshot: {}", e), e
) ))
})?; })?;
let configuration = PciConfiguration::new( let configuration = PciConfiguration::new(
@@ -477,13 +497,10 @@ impl VirtioPciDevice {
let common_config_state = let common_config_state =
vm_migration::versioned_state_from_id(snapshot.as_ref(), VIRTIO_PCI_COMMON_CONFIG_ID) vm_migration::versioned_state_from_id(snapshot.as_ref(), VIRTIO_PCI_COMMON_CONFIG_ID)
.map_err(|e| { .map_err(|e| {
std::io::Error::new( VirtioPciDeviceError::CreateVirtioPciDevice(anyhow!(
std::io::ErrorKind::Other, "Failed to get VirtioPciCommonConfigState from Snapshot: {}",
format!( e
"Failed to get VirtioPciCommonConfigState from Snapshot: {}", ))
e
),
)
})?; })?;
let common_config = if let Some(common_config_state) = common_config_state { let common_config = if let Some(common_config_state) = common_config_state {
@@ -508,10 +525,10 @@ impl VirtioPciDevice {
.map(|s| s.to_versioned_state(&id)) .map(|s| s.to_versioned_state(&id))
.transpose() .transpose()
.map_err(|e| { .map_err(|e| {
std::io::Error::new( VirtioPciDeviceError::CreateVirtioPciDevice(anyhow!(
std::io::ErrorKind::Other, "Failed to get VirtioPciDeviceState from Snapshot: {}",
format!("Failed to get VirtioPciDeviceState from Snapshot: {}", e), e
) ))
})?; })?;
let (device_activated, interrupt_status) = if let Some(state) = state { let (device_activated, interrupt_status) = if let Some(state) = state {
@@ -592,10 +609,10 @@ impl VirtioPciDevice {
&& virtio_pci_device.is_driver_ready() && virtio_pci_device.is_driver_ready()
{ {
virtio_pci_device.activate().map_err(|e| { virtio_pci_device.activate().map_err(|e| {
std::io::Error::new( VirtioPciDeviceError::CreateVirtioPciDevice(anyhow!(
std::io::ErrorKind::Other, "Failed activating the device: {}",
format!("Failed activating the device: {}", e), e
) ))
})?; })?;
} }
@@ -1079,7 +1096,11 @@ impl PciDevice for VirtioPciDevice {
Ok(()) Ok(())
} }
fn move_bar(&mut self, old_base: u64, new_base: u64) -> result::Result<(), std::io::Error> { fn move_bar(
&mut self,
old_base: u64,
new_base: u64,
) -> std::result::Result<(), std::io::Error> {
// We only update our idea of the bar in order to support free_bars() above. // We only update our idea of the bar in order to support free_bars() above.
// The majority of the reallocation is done inside DeviceManager. // The majority of the reallocation is done inside DeviceManager.
for bar in self.bar_regions.iter_mut() { for bar in self.bar_regions.iter_mut() {
@@ -1236,11 +1257,11 @@ impl BusDevice for VirtioPciDevice {
} }
impl Pausable for VirtioPciDevice { impl Pausable for VirtioPciDevice {
fn pause(&mut self) -> result::Result<(), MigratableError> { fn pause(&mut self) -> std::result::Result<(), MigratableError> {
Ok(()) Ok(())
} }
fn resume(&mut self) -> result::Result<(), MigratableError> { fn resume(&mut self) -> std::result::Result<(), MigratableError> {
Ok(()) Ok(())
} }
} }
+1 -1
View File
@@ -226,7 +226,7 @@ pub enum DeviceManagerError {
UnRegisterIoevent(anyhow::Error), UnRegisterIoevent(anyhow::Error),
/// Cannot create virtio device /// Cannot create virtio device
VirtioDevice(vmm_sys_util::errno::Error), VirtioDevice(virtio_devices::transport::VirtioPciDeviceError),
/// Cannot add PCI device /// Cannot add PCI device
AddPciDevice(pci::PciRootError), AddPciDevice(pci::PciRootError),