virtio-devices: trim qualified paths

Import the modules used in the crate instead of spelling the full paths
at every use site, and drop the now-unnecessary crate-level
#![expect(clippy::absolute_paths)].

Signed-off-by: Henry Hrvoje Tonkovac <htonkovac@gmail.com>
Assisted-by: Claude:Opus-4.8
This commit is contained in:
Henry Hrvoje Tonkovac
2026-06-18 14:45:14 +02:00
committed by Rob Bradford
parent 2f2f709a0e
commit 74a749b960
32 changed files with 304 additions and 313 deletions

View File

@@ -17,9 +17,9 @@
use std::io::{self, Write};
use std::mem::size_of;
use std::os::unix::io::AsRawFd;
use std::result;
use std::sync::atomic::AtomicBool;
use std::sync::{Arc, Barrier};
use std::{cmp, result};
use anyhow::anyhow;
use event_monitor::event;
@@ -38,6 +38,7 @@ use vm_virtio::AccessPlatform;
use vm_virtio::checked_descriptor::DescriptorChainExt;
use vmm_sys_util::eventfd::EventFd;
use crate::device::ActivationContext;
use crate::seccomp_filters::Thread;
use crate::{
ActivateResult, EPOLL_HELPER_EVENT_LAST, EpollHelper, EpollHelperError, EpollHelperHandler,
@@ -76,9 +77,9 @@ pub enum Error {
#[error("Guest gave us bad memory addresses.")]
GuestMemory(#[source] GuestMemoryError),
#[error("Fallocate fail.")]
FallocateFail(#[source] std::io::Error),
FallocateFail(#[source] io::Error),
#[error("Madvise fail.")]
MadviseFail(#[source] std::io::Error),
MadviseFail(#[source] io::Error),
#[error("Invalid queue index: {0}")]
InvalidQueueIndex(usize),
#[error("Failed to signal")]
@@ -201,7 +202,7 @@ impl BalloonEpollHandler {
// No underflow possible because range_base was found in the region by `find_region`.
let offset = range_base.0 - region.start_addr().0;
let region_limit = region.len() - offset;
let len = std::cmp::min(range_len as u64, region_limit);
let len = cmp::min(range_len as u64, region_limit);
if len < range_len as u64 {
warn!(
"Clamping reported range at GPA 0x{:x} from {} to {} bytes \
@@ -631,13 +632,13 @@ impl VirtioDevice for Balloon {
if let Some(end) = offset.checked_add(config.len() as u64) {
let mut offset_config =
&mut config[offset as usize..std::cmp::min(end, config_len) as usize];
&mut config[offset as usize..cmp::min(end, config_len) as usize];
offset_config.write_all(data).unwrap();
}
}
fn activate(&mut self, context: crate::device::ActivationContext) -> ActivateResult {
let crate::device::ActivationContext {
fn activate(&mut self, context: ActivationContext) -> ActivateResult {
let ActivationContext {
mem,
interrupt_cb,
mut queues,
@@ -721,7 +722,7 @@ impl Snapshottable for Balloon {
self.id.clone()
}
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
fn snapshot(&mut self) -> result::Result<Snapshot, MigratableError> {
Snapshot::new_from_state(&self.state())
}
}

View File

@@ -19,7 +19,7 @@ use std::path::PathBuf;
use std::sync::atomic::{AtomicBool, AtomicU8, AtomicU64, AtomicUsize, Ordering};
use std::sync::{Arc, Barrier};
use std::time::{Duration, Instant};
use std::{io, result, thread};
use std::{io, mem, result, thread};
use anyhow::anyhow;
use block::async_io::{AsyncIo, AsyncIoError};
@@ -51,6 +51,7 @@ use super::{
EpollHelperHandler, Error as DeviceError, VirtioCommon, VirtioDevice, VirtioDeviceType,
VirtioInterruptType,
};
use crate::device::ActivationContext;
use crate::seccomp_filters::Thread;
use crate::{GuestMemoryMmap, VirtioInterrupt};
@@ -651,7 +652,7 @@ impl BlockEpollHandler {
// Prepare the CPU set the current queue thread is expected to run onto.
let cpuset = self.host_cpus.as_ref().map(|host_cpus| {
// SAFETY: all zeros is a valid pattern
let mut cpuset: libc::cpu_set_t = unsafe { std::mem::zeroed() };
let mut cpuset: libc::cpu_set_t = unsafe { mem::zeroed() };
// SAFETY: FFI call, trivially safe
unsafe { libc::CPU_ZERO(&mut cpuset) };
for host_cpu in host_cpus {
@@ -665,9 +666,8 @@ impl BlockEpollHandler {
if let Some(cpuset) = cpuset.as_ref() {
let cpuset: *const libc::cpu_set_t = cpuset;
// SAFETY: FFI call with correct arguments
let ret = unsafe {
libc::sched_setaffinity(0, std::mem::size_of::<libc::cpu_set_t>(), cpuset)
};
let ret =
unsafe { libc::sched_setaffinity(0, mem::size_of::<libc::cpu_set_t>(), cpuset) };
if ret != 0 {
error!(
@@ -1148,8 +1148,7 @@ impl VirtioDevice for Block {
// The "writeback" field is the only mutable field
let writeback_offset =
(&raw const self.config.writeback as u64) - (&raw const self.config as u64);
if offset != writeback_offset || data.len() != std::mem::size_of_val(&self.config.writeback)
{
if offset != writeback_offset || data.len() != mem::size_of_val(&self.config.writeback) {
error!(
"Attempt to write to read-only field: offset {:x} length {}",
offset,
@@ -1162,8 +1161,8 @@ impl VirtioDevice for Block {
self.set_writeback_mode(writeback);
}
fn activate(&mut self, context: crate::device::ActivationContext) -> ActivateResult {
let crate::device::ActivationContext {
fn activate(&mut self, context: ActivationContext) -> ActivateResult {
let ActivationContext {
mem,
interrupt_cb,
mut queues,
@@ -1346,7 +1345,7 @@ impl Snapshottable for Block {
self.id.clone()
}
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
fn snapshot(&mut self) -> result::Result<Snapshot, MigratableError> {
Snapshot::new_from_state(&self.state())
}
}

View File

@@ -29,6 +29,7 @@ use super::{
Error as DeviceError, VIRTIO_F_ACCESS_PLATFORM, VIRTIO_F_VERSION_1, VirtioCommon, VirtioDevice,
VirtioDeviceType, VirtioInterruptType,
};
use crate::device::ActivationContext;
use crate::seccomp_filters::Thread;
use crate::{GuestMemoryMmap, VirtioInterrupt};
@@ -711,8 +712,8 @@ impl VirtioDevice for Console {
self.read_config_from_slice(self.config.lock().unwrap().as_slice(), offset, data);
}
fn activate(&mut self, context: crate::device::ActivationContext) -> ActivateResult {
let crate::device::ActivationContext {
fn activate(&mut self, context: ActivationContext) -> ActivateResult {
let ActivationContext {
mem,
interrupt_cb,
mut queues,
@@ -797,7 +798,7 @@ impl Snapshottable for Console {
self.id.clone()
}
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
fn snapshot(&mut self) -> result::Result<Snapshot, MigratableError> {
Snapshot::new_from_state(&self.state())
}
}

View File

@@ -11,7 +11,7 @@ use std::io::Write;
use std::num::Wrapping;
use std::sync::atomic::{AtomicBool, AtomicU8, Ordering};
use std::sync::{Arc, Barrier};
use std::thread;
use std::{cmp, io, result, thread};
use anyhow::anyhow;
use libc::EFD_NONBLOCK;
@@ -39,7 +39,7 @@ pub enum VirtioInterruptType {
}
pub trait VirtioInterrupt: Send + Sync {
fn trigger(&self, int_type: VirtioInterruptType) -> std::result::Result<(), std::io::Error>;
fn trigger(&self, int_type: VirtioInterruptType) -> io::Result<()>;
fn notifier(&self, _int_type: VirtioInterruptType) -> Option<EventFd> {
None
}
@@ -48,7 +48,7 @@ pub trait VirtioInterrupt: Send + Sync {
int_type: u32,
notifier: Option<EventFd>,
vm: &dyn hypervisor::Vm,
) -> std::io::Result<()>;
) -> io::Result<()>;
}
#[derive(Clone)]
@@ -139,7 +139,7 @@ pub trait VirtioDevice: Send {
fn set_shm_regions(
&mut self,
_shm_regions: VirtioSharedMemoryList,
) -> std::result::Result<(), Error> {
) -> result::Result<(), Error> {
std::unimplemented!()
}
@@ -149,10 +149,7 @@ pub trait VirtioDevice: Send {
/// after a shutdown() can lead to unpredictable results.
fn shutdown(&mut self) {}
fn add_memory_region(
&mut self,
_region: &Arc<GuestRegionMmap>,
) -> std::result::Result<(), Error> {
fn add_memory_region(&mut self, _region: &Arc<GuestRegionMmap>) -> result::Result<(), Error> {
Ok(())
}
@@ -181,7 +178,7 @@ pub trait VirtioDevice: Send {
return;
}
if let Some(end) = offset.checked_add(data.len() as u64) {
data.write_all(&config[offset as usize..std::cmp::min(end, config_len) as usize])
data.write_all(&config[offset as usize..cmp::min(end, config_len) as usize])
.unwrap();
}
}
@@ -209,20 +206,10 @@ pub trait DmaRemapping {
/// Provide a way to translate GVA address ranges into GPAs. The
/// implementation must reject translations whose [addr, addr+size)
/// span isn't entirely covered by a single mapping.
fn translate_gva(
&self,
id: u32,
addr: u64,
size: u64,
) -> std::result::Result<u64, std::io::Error>;
fn translate_gva(&self, id: u32, addr: u64, size: u64) -> io::Result<u64>;
/// Provide a way to translate GPA address ranges into GVAs. Same
/// span requirement as `translate_gva`.
fn translate_gpa(
&self,
id: u32,
addr: u64,
size: u64,
) -> std::result::Result<u64, std::io::Error>;
fn translate_gpa(&self, id: u32, addr: u64, size: u64) -> io::Result<u64>;
}
/// Owns a device's worker threads plus the kill event that stops them.
@@ -253,7 +240,7 @@ impl WorkerThreads {
/// Signal the workers to exit without joining; they are joined later when
/// this is dropped.
pub(crate) fn signal_exit(&self) -> std::io::Result<()> {
pub(crate) fn signal_exit(&self) -> io::Result<()> {
self.kill_evt.write(1)
}
@@ -414,7 +401,7 @@ impl VirtioCommon {
Ok(())
}
pub fn trigger_interrupt(&self, int_type: VirtioInterruptType) -> std::io::Result<()> {
pub fn trigger_interrupt(&self, int_type: VirtioInterruptType) -> io::Result<()> {
if let Some(interrupt_cb) = &self.interrupt_cb {
interrupt_cb.trigger(int_type)
} else {
@@ -462,7 +449,7 @@ impl VirtioCommon {
}
impl Pausable for VirtioCommon {
fn pause(&mut self) -> std::result::Result<(), MigratableError> {
fn pause(&mut self) -> result::Result<(), MigratableError> {
info!(
"Pausing virtio-{}",
VirtioDeviceType::from(self.device_type)
@@ -490,7 +477,7 @@ impl Pausable for VirtioCommon {
Ok(())
}
fn resume(&mut self) -> std::result::Result<(), MigratableError> {
fn resume(&mut self) -> result::Result<(), MigratableError> {
info!(
"Resuming virtio-{}",
VirtioDeviceType::from(self.device_type)
@@ -530,7 +517,7 @@ mod unit_tests {
struct NoopInterrupt;
impl VirtioInterrupt for NoopInterrupt {
fn trigger(&self, _: VirtioInterruptType) -> std::io::Result<()> {
fn trigger(&self, _: VirtioInterruptType) -> io::Result<()> {
Ok(())
}
fn set_notifier(
@@ -538,7 +525,7 @@ mod unit_tests {
_: u32,
_: Option<EventFd>,
_: &dyn hypervisor::Vm,
) -> std::io::Result<()> {
) -> io::Result<()> {
Ok(())
}
}

View File

@@ -12,7 +12,7 @@ use std::fs::File;
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
use std::sync::Barrier;
use std::sync::atomic::{AtomicBool, Ordering};
use std::thread;
use std::{io, result, thread};
use log::info;
use thiserror::Error;
@@ -26,13 +26,13 @@ pub struct EpollHelper {
#[derive(Error, Debug)]
pub enum EpollHelperError {
#[error("Failed to create Fd")]
CreateFd(#[source] std::io::Error),
CreateFd(#[source] io::Error),
#[error("Failed to epoll_ctl")]
Ctl(#[source] std::io::Error),
Ctl(#[source] io::Error),
#[error("IO error")]
IoError(#[source] std::io::Error),
IoError(#[source] io::Error),
#[error("Failed to epoll_wait")]
Wait(#[source] std::io::Error),
Wait(#[source] io::Error),
#[error("Failed to get virtio-queue index")]
QueueRingIndex(#[source] virtio_queue::Error),
#[error("Failed to handle virtio device events")]
@@ -82,10 +82,7 @@ pub trait EpollHelperHandler {
}
impl EpollHelper {
pub fn new(
kill_evt: &EventFd,
pause_evt: &EventFd,
) -> std::result::Result<Self, EpollHelperError> {
pub fn new(kill_evt: &EventFd, pause_evt: &EventFd) -> result::Result<Self, EpollHelperError> {
// Create the epoll file descriptor
let epoll_fd = epoll::create(true).map_err(EpollHelperError::CreateFd)?;
// Use 'File' to enforce closing on 'epoll_fd'
@@ -102,7 +99,7 @@ impl EpollHelper {
Ok(helper)
}
pub fn add_event(&mut self, fd: RawFd, id: u16) -> std::result::Result<(), EpollHelperError> {
pub fn add_event(&mut self, fd: RawFd, id: u16) -> result::Result<(), EpollHelperError> {
self.add_event_custom(fd, id, epoll::Events::EPOLLIN)
}
@@ -111,7 +108,7 @@ impl EpollHelper {
fd: RawFd,
id: u16,
evts: epoll::Events,
) -> std::result::Result<(), EpollHelperError> {
) -> result::Result<(), EpollHelperError> {
epoll::ctl(
self.epoll_file.as_raw_fd(),
epoll::ControlOptions::EPOLL_CTL_ADD,
@@ -126,7 +123,7 @@ impl EpollHelper {
fd: RawFd,
id: u16,
evts: epoll::Events,
) -> std::result::Result<(), EpollHelperError> {
) -> result::Result<(), EpollHelperError> {
epoll::ctl(
self.epoll_file.as_raw_fd(),
epoll::ControlOptions::EPOLL_CTL_MOD,
@@ -141,7 +138,7 @@ impl EpollHelper {
fd: RawFd,
id: u16,
evts: epoll::Events,
) -> std::result::Result<(), EpollHelperError> {
) -> result::Result<(), EpollHelperError> {
epoll::ctl(
self.epoll_file.as_raw_fd(),
epoll::ControlOptions::EPOLL_CTL_DEL,
@@ -156,7 +153,7 @@ impl EpollHelper {
paused: &AtomicBool,
paused_sync: &Barrier,
handler: &mut dyn EpollHelperHandler,
) -> std::result::Result<(), EpollHelperError> {
) -> result::Result<(), EpollHelperError> {
self.run_with_timeout(paused, paused_sync, handler, -1, false)
}
@@ -168,7 +165,7 @@ impl EpollHelper {
handler: &mut dyn EpollHelperHandler,
timeout: i32,
enable_event_list: bool,
) -> std::result::Result<(), EpollHelperError> {
) -> result::Result<(), EpollHelperError> {
const EPOLL_EVENTS_LEN: usize = 100;
let mut events = vec![epoll::Event::new(epoll::Events::empty(), 0); EPOLL_EVENTS_LEN];
@@ -185,7 +182,7 @@ impl EpollHelper {
match epoll::wait(self.epoll_file.as_raw_fd(), timeout, &mut events[..]) {
Ok(res) => res,
Err(e) => {
if e.kind() == std::io::ErrorKind::Interrupted {
if e.kind() == io::ErrorKind::Interrupted {
// It's well defined from the epoll_wait() syscall
// documentation that the epoll loop can be interrupted
// before any of the requested events occurred or the
@@ -255,7 +252,7 @@ impl EpollHelper {
handler: &mut dyn EpollHelperHandler,
_timeout: i32,
_enable_event_list: bool,
) -> std::result::Result<(), EpollHelperError> {
) -> result::Result<(), EpollHelperError> {
const EPOLL_EVENTS_LEN: usize = 100;
let mut events = vec![epoll::Event::new(epoll::Events::empty(), 0); EPOLL_EVENTS_LEN];
@@ -263,7 +260,7 @@ impl EpollHelper {
let num_events = match epoll::wait(self.epoll_file.as_raw_fd(), 0, &mut events[..]) {
Ok(res) => res,
Err(e) => {
if e.kind() == std::io::ErrorKind::Interrupted {
if e.kind() == io::ErrorKind::Interrupted {
// It's well defined from the epoll_wait() syscall
// documentation that the epoll loop can be interrupted
// before any of the requested events occurred or the

View File

@@ -7,7 +7,7 @@ use std::mem::size_of;
use std::os::unix::io::AsRawFd;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Barrier, Mutex, RwLock};
use std::{io, result};
use std::{io, mem, result};
use anyhow::anyhow;
use event_monitor::event;
@@ -30,6 +30,7 @@ use super::{
Error as DeviceError, VIRTIO_F_ACCESS_PLATFORM, VIRTIO_F_VERSION_1, VirtioCommon, VirtioDevice,
VirtioDeviceType,
};
use crate::device::ActivationContext;
use crate::seccomp_filters::Thread;
use crate::{DmaRemapping, GuestMemoryMmap, VirtioInterrupt, VirtioInterruptType};
@@ -985,7 +986,7 @@ fn inclusive_end(addr: u64, size: u64) -> Option<u64> {
addr.checked_add(size - 1)
}
fn span_end(addr: u64, size: u64) -> std::result::Result<u64, io::Error> {
fn span_end(addr: u64, size: u64) -> io::Result<u64> {
inclusive_end(addr, size).ok_or_else(|| {
io::Error::other(format!(
"translate span overflow or zero size: addr 0x{addr:x} size 0x{size:x}"
@@ -994,12 +995,7 @@ fn span_end(addr: u64, size: u64) -> std::result::Result<u64, io::Error> {
}
impl DmaRemapping for IommuMapping {
fn translate_gva(
&self,
id: u32,
addr: u64,
size: u64,
) -> std::result::Result<u64, std::io::Error> {
fn translate_gva(&self, id: u32, addr: u64, size: u64) -> io::Result<u64> {
debug!("Translate GVA addr 0x{addr:x} size 0x{size:x}");
let end = span_end(addr, size)?;
if let Some(domain_id) = self.endpoints.read().unwrap().get(&id) {
@@ -1030,12 +1026,7 @@ impl DmaRemapping for IommuMapping {
)))
}
fn translate_gpa(
&self,
id: u32,
addr: u64,
size: u64,
) -> std::result::Result<u64, std::io::Error> {
fn translate_gpa(&self, id: u32, addr: u64, size: u64) -> io::Result<u64> {
debug!("Translate GPA addr 0x{addr:x} size 0x{size:x}");
let end = span_end(addr, size)?;
if let Some(domain_id) = self.endpoints.read().unwrap().get(&id) {
@@ -1080,10 +1071,10 @@ impl AccessPlatformMapping {
}
impl AccessPlatform for AccessPlatformMapping {
fn translate_gva(&self, base: u64, size: u64) -> std::result::Result<u64, std::io::Error> {
fn translate_gva(&self, base: u64, size: u64) -> io::Result<u64> {
self.mapping.translate_gva(self.id, base, size)
}
fn translate_gpa(&self, base: u64, size: u64) -> std::result::Result<u64, std::io::Error> {
fn translate_gpa(&self, base: u64, size: u64) -> io::Result<u64> {
self.mapping.translate_gpa(self.id, base, size)
}
}
@@ -1283,7 +1274,7 @@ impl VirtioDevice for Iommu {
// The "bypass" field is the only mutable field
let bypass_offset =
(&raw const self.config.bypass as u64) - (&raw const self.config as u64);
if offset != bypass_offset || data.len() != std::mem::size_of_val(&self.config.bypass) {
if offset != bypass_offset || data.len() != mem::size_of_val(&self.config.bypass) {
error!(
"Attempt to write to read-only field: offset {:x} length {}",
offset,
@@ -1299,8 +1290,8 @@ impl VirtioDevice for Iommu {
self.update_bypass();
}
fn activate(&mut self, context: crate::device::ActivationContext) -> ActivateResult {
let crate::device::ActivationContext {
fn activate(&mut self, context: ActivationContext) -> ActivateResult {
let ActivationContext {
mem,
interrupt_cb,
mut queues,
@@ -1364,7 +1355,7 @@ impl Snapshottable for Iommu {
self.id.clone()
}
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
fn snapshot(&mut self) -> result::Result<Snapshot, MigratableError> {
Snapshot::new_from_state(&self.state())
}
}

View File

@@ -10,11 +10,8 @@
//! Implements virtio devices, queues, and transport mechanisms.
// TODO: Trim qualified paths in this crate, then drop this expectation.
#![expect(clippy::absolute_paths)]
use std::io;
use std::sync::atomic::{AtomicU8, Ordering};
use std::{fmt, io, result};
use serde::{Deserialize, Serialize};
use thiserror::Error;
@@ -84,7 +81,7 @@ const DEVICE_FAILED: u32 = 0x80;
pub(crate) fn mark_device_needs_reset(
device_status: &AtomicU8,
interrupt_cb: &dyn self::VirtioInterrupt,
context: std::fmt::Arguments<'_>,
context: fmt::Arguments<'_>,
) {
log::warn!(
"Corrupted request detected ({context}). Setting device status to 'NEEDS_RESET' and stopping processing queues until reset."
@@ -112,9 +109,9 @@ pub enum ActivateError {
#[error("Failed to activate virtio device")]
BadActivate,
#[error("Failed to clone EventFd")]
CloneEventFd(#[source] std::io::Error),
CloneEventFd(#[source] io::Error),
#[error("Failed to spawn thread")]
ThreadSpawn(#[source] std::io::Error),
ThreadSpawn(#[source] io::Error),
#[error("Failed to setup vhost-user-fs daemon")]
VhostUserFsSetup(#[source] vhost_user::Error),
#[error("Failed to setup vhost-user daemon")]
@@ -122,12 +119,12 @@ pub enum ActivateError {
#[error("Failed to create seccomp filter")]
CreateSeccompFilter(#[source] seccompiler::Error),
#[error("Failed to create rate limiter")]
CreateRateLimiter(#[source] std::io::Error),
CreateRateLimiter(#[source] io::Error),
#[error("Failed to activate the vDPA device")]
ActivateVdpa(#[source] vdpa::Error),
}
pub type ActivateResult = std::result::Result<(), ActivateError>;
pub type ActivateResult = result::Result<(), ActivateError>;
pub type DeviceEventT = u16;
@@ -164,7 +161,7 @@ pub struct RateLimiterConfig {
impl TryInto<rate_limiter::RateLimiter> for RateLimiterConfig {
type Error = io::Error;
fn try_into(self) -> std::result::Result<rate_limiter::RateLimiter, Self::Error> {
fn try_into(self) -> result::Result<rate_limiter::RateLimiter, Self::Error> {
let bw = self.bandwidth.unwrap_or_default();
let ops = self.ops.unwrap_or_default();
rate_limiter::RateLimiter::new(

View File

@@ -42,6 +42,7 @@ use super::{
EpollHelperHandler, Error as DeviceError, VIRTIO_F_VERSION_1, VirtioCommon, VirtioDevice,
VirtioDeviceType,
};
use crate::device::ActivationContext;
use crate::seccomp_filters::Thread;
use crate::{GuestMemoryMmap, GuestRegionMmap, VirtioInterrupt, VirtioInterruptType};
@@ -119,11 +120,11 @@ pub enum Error {
#[error("Invalid configuration")]
ValidateError(#[source] anyhow::Error),
#[error("Failed discarding memory range")]
DiscardMemoryRange(#[source] std::io::Error),
DiscardMemoryRange(#[source] io::Error),
#[error("Failed DMA mapping")]
DmaMap(#[source] std::io::Error),
DmaMap(#[source] io::Error),
#[error("Failed DMA unmapping")]
DmaUnmap(#[source] std::io::Error),
DmaUnmap(#[source] io::Error),
#[error("Invalid DMA mapping handler")]
InvalidDmaMappingHandler,
#[error("Failed adding used index")]
@@ -943,8 +944,8 @@ impl VirtioDevice for Mem {
self.read_config_from_slice(self.config.lock().unwrap().as_slice(), offset, data);
}
fn activate(&mut self, context: crate::device::ActivationContext) -> ActivateResult {
let crate::device::ActivationContext {
fn activate(&mut self, context: ActivationContext) -> ActivateResult {
let ActivationContext {
mem,
interrupt_cb,
mut queues,
@@ -1023,7 +1024,7 @@ impl Snapshottable for Mem {
self.id.clone()
}
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
fn snapshot(&mut self) -> result::Result<Snapshot, MigratableError> {
Snapshot::new_from_state(&self.state())
}
}

View File

@@ -10,9 +10,9 @@ use std::net::IpAddr;
use std::num::Wrapping;
use std::ops::Deref;
use std::os::unix::io::{AsRawFd, RawFd};
use std::result;
use std::sync::atomic::{AtomicBool, AtomicU8, Ordering};
use std::sync::{Arc, Barrier};
use std::{io, result};
use anyhow::anyhow;
use event_monitor::event;
@@ -40,6 +40,7 @@ use super::{
EpollHelperHandler, Error as DeviceError, RateLimiterConfig, VirtioCommon, VirtioDevice,
VirtioDeviceType, VirtioInterruptType,
};
use crate::device::ActivationContext;
use crate::seccomp_filters::Thread;
use crate::{GuestMemoryMmap, VirtioInterrupt};
@@ -76,7 +77,7 @@ impl NetCtrlEpollHandler {
&mut self,
paused: &AtomicBool,
paused_sync: &Barrier,
) -> std::result::Result<(), EpollHelperError> {
) -> result::Result<(), EpollHelperError> {
let mut helper = EpollHelper::new(&self.kill_evt, &self.pause_evt)?;
helper.add_event(self.queue_evt.as_raw_fd(), CTRL_QUEUE_EVENT)?;
helper.run(paused, paused_sync, self)?;
@@ -159,7 +160,7 @@ pub enum Error {
#[error("Using existing tap")]
TapError(#[source] TapError),
#[error("Error calling dup() on tap fd")]
DuplicateTapFd(#[source] std::io::Error),
DuplicateTapFd(#[source] io::Error),
}
pub type Result<T> = result::Result<T, Error>;
@@ -600,7 +601,7 @@ impl Net {
// SAFETY: FFI call to dup. Trivially safe.
let fd = unsafe { libc::dup(*fd) };
if fd < 0 {
return Err(Error::DuplicateTapFd(std::io::Error::last_os_error()));
return Err(Error::DuplicateTapFd(io::Error::last_os_error()));
}
let tap = Tap::from_tap_fd(fd, num_queue_pairs).map_err(Error::TapError)?;
taps.push(tap);
@@ -665,8 +666,8 @@ impl VirtioDevice for Net {
self.read_config_from_slice(self.config.as_slice(), offset, data);
}
fn activate(&mut self, context: crate::device::ActivationContext) -> ActivateResult {
let crate::device::ActivationContext {
fn activate(&mut self, context: ActivationContext) -> ActivateResult {
let ActivationContext {
mem,
interrupt_cb,
mut queues,
@@ -850,7 +851,7 @@ impl Snapshottable for Net {
self.id.clone()
}
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
fn snapshot(&mut self) -> result::Result<Snapshot, MigratableError> {
Snapshot::new_from_state(&self.state())
}
}

View File

@@ -35,6 +35,7 @@ use super::{
EpollHelperHandler, Error as DeviceError, VIRTIO_F_ACCESS_PLATFORM, VIRTIO_F_VERSION_1,
VirtioCommon, VirtioDevice, VirtioDeviceType,
};
use crate::device::ActivationContext;
use crate::seccomp_filters::Thread;
use crate::{GuestMemoryMmap, VirtioInterrupt, VirtioInterruptType};
@@ -370,8 +371,8 @@ impl VirtioDevice for Pmem {
self.read_config_from_slice(self.config.as_slice(), offset, data);
}
fn activate(&mut self, context: crate::device::ActivationContext) -> ActivateResult {
let crate::device::ActivationContext {
fn activate(&mut self, context: ActivationContext) -> ActivateResult {
let ActivationContext {
mem,
interrupt_cb,
mut queues,
@@ -450,7 +451,7 @@ impl Snapshottable for Pmem {
self.id.clone()
}
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
fn snapshot(&mut self) -> result::Result<Snapshot, MigratableError> {
Snapshot::new_from_state(&self.state())
}
}

View File

@@ -28,6 +28,7 @@ use super::{
EpollHelperHandler, Error as DeviceError, VIRTIO_F_ACCESS_PLATFORM, VIRTIO_F_VERSION_1,
VirtioCommon, VirtioDevice, VirtioDeviceType,
};
use crate::device::ActivationContext;
use crate::seccomp_filters::Thread;
use crate::{GuestMemoryMmap, VirtioInterrupt, VirtioInterruptType};
@@ -245,8 +246,8 @@ impl VirtioDevice for Rng {
self.common.ack_features(value);
}
fn activate(&mut self, context: crate::device::ActivationContext) -> ActivateResult {
let crate::device::ActivationContext {
fn activate(&mut self, context: ActivationContext) -> ActivateResult {
let ActivationContext {
mem,
interrupt_cb,
mut queues,
@@ -321,7 +322,7 @@ impl Snapshottable for Rng {
self.id.clone()
}
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
fn snapshot(&mut self) -> result::Result<Snapshot, MigratableError> {
Snapshot::new_from_state(&self.state())
}
}

View File

@@ -4,9 +4,11 @@
//
use std::mem::size_of;
use std::ops::Deref;
use std::os::unix::io::AsRawFd;
use std::sync::atomic::AtomicBool;
use std::sync::{Arc, Barrier};
use std::time::{SystemTime, UNIX_EPOCH};
use std::{io, result};
use anyhow::anyhow;
@@ -16,7 +18,7 @@ use seccompiler::SeccompAction;
use serde::{Deserialize, Serialize};
use thiserror::Error;
use virtio_queue::{Queue, QueueT};
use vm_memory::{Address, ByteValued, Bytes, GuestAddressSpace, GuestMemoryAtomic};
use vm_memory::{Address, ByteValued, Bytes, GuestAddressSpace, GuestMemoryAtomic, guest_memory};
use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable};
use vm_virtio::{AccessPlatform, Translatable};
use vmm_sys_util::eventfd::EventFd;
@@ -178,9 +180,9 @@ enum Error {
#[error("Failed to translate guest address")]
AddressTranslation(#[source] io::Error),
#[error("Failed to read request from guest memory")]
GuestMemoryRead(#[source] vm_memory::guest_memory::Error),
GuestMemoryRead(#[source] guest_memory::Error),
#[error("Failed to write to guest memory")]
GuestMemoryWrite(#[source] vm_memory::guest_memory::Error),
GuestMemoryWrite(#[source] guest_memory::Error),
#[error("Failed adding used index")]
QueueAddUsed(#[source] virtio_queue::Error),
}
@@ -228,7 +230,7 @@ impl RtcEpollHandler {
desc_chain: &mut virtio_queue::DescriptorChain<M>,
) -> Result<u32, Error>
where
M: std::ops::Deref,
M: Deref,
M::Target: vm_memory::GuestMemory,
{
let req_desc = desc_chain.next().ok_or(Error::DescriptorChainTooShort)?;
@@ -416,7 +418,7 @@ impl RtcEpollHandler {
// clock for chronyd in MSHV L2 guests, so readings must track the L1 host's
// NTP-disciplined wall clock. CLOCK_MONOTONIC would drift from L1 wall time
// as NTP adjusts, causing L2-L1 divergence.
0 => match std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH) {
0 => match SystemTime::now().duration_since(UNIX_EPOCH) {
Ok(now) => {
let nanos = now.as_nanos();
if nanos > u64::MAX as u128 {
@@ -683,7 +685,7 @@ impl Snapshottable for Rtc {
self.id.clone()
}
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
fn snapshot(&mut self) -> result::Result<Snapshot, MigratableError> {
Snapshot::new_from_state(&self.state())
}
}

View File

@@ -4,6 +4,8 @@
//
// SPDX-License-Identifier: Apache-2.0
use std::env;
use block::{BLKDISCARD, BLKZEROOUT};
use libc::{FIONBIO, TIOCGWINSZ, TUNSETOFFLOAD};
use seccompiler::SeccompCmpOp::Eq;
@@ -373,7 +375,7 @@ pub fn get_seccomp_filter(
get_seccomp_rules(thread_type).into_iter().collect(),
SeccompAction::Log,
SeccompAction::Allow,
std::env::consts::ARCH.try_into().unwrap(),
env::consts::ARCH.try_into().unwrap(),
)
.and_then(|filter| filter.try_into())
.map_err(Error::Backend),
@@ -381,7 +383,7 @@ pub fn get_seccomp_filter(
get_seccomp_rules(thread_type).into_iter().collect(),
SeccompAction::Trap,
SeccompAction::Allow,
std::env::consts::ARCH.try_into().unwrap(),
env::consts::ARCH.try_into().unwrap(),
)
.and_then(|filter| filter.try_into())
.map_err(Error::Backend),

View File

@@ -7,6 +7,7 @@ use std::panic::AssertUnwindSafe;
use std::sync::Arc;
use std::sync::atomic::AtomicU8;
use std::thread::{self, JoinHandle};
use std::{panic, result};
use log::error;
use seccompiler::{SeccompAction, apply_filter};
@@ -28,7 +29,7 @@ pub(crate) fn spawn_virtio_thread<F>(
f: F,
) -> Result<(), ActivateError>
where
F: FnOnce() -> std::result::Result<(), EpollHelperError>,
F: FnOnce() -> result::Result<(), EpollHelperError>,
F: Send + 'static,
{
let seccomp_filter = get_seccomp_filter(seccomp_action, thread_type)
@@ -47,7 +48,7 @@ where
thread_exit_evt.write(1).ok();
return;
}
match std::panic::catch_unwind(AssertUnwindSafe(f)) {
match panic::catch_unwind(AssertUnwindSafe(f)) {
Err(_) => {
error!("{thread_name} thread panicked");
thread_exit_evt.write(1).ok();

View File

@@ -6,6 +6,7 @@
//
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
use std::result;
use std::sync::atomic::{AtomicBool, AtomicU8, AtomicU16, Ordering};
use std::sync::{Arc, Mutex};
@@ -435,7 +436,7 @@ impl Snapshottable for VirtioPciCommonConfig {
String::from(VIRTIO_PCI_COMMON_CONFIG_ID)
}
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
fn snapshot(&mut self) -> result::Result<Snapshot, MigratableError> {
Snapshot::new_from_state(&self.state())
}
}

View File

@@ -7,12 +7,12 @@
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
use std::any::Any;
use std::cmp;
use std::io::Write;
use std::mem::size_of;
use std::ops::Deref;
use std::sync::atomic::{AtomicBool, AtomicU8, AtomicU16, AtomicUsize, Ordering};
use std::sync::{Arc, Barrier, Mutex};
use std::{cmp, io, mem, result};
use anyhow::anyhow;
use libc::EFD_NONBLOCK;
@@ -91,7 +91,7 @@ const VIRTIO_PCI_CAP_LEN_OFFSET: u8 = 2;
impl VirtioPciCap {
pub fn new(cfg_type: PciCapabilityType, pci_bar: u8, offset: u32, length: u32) -> Self {
VirtioPciCap {
cap_len: (std::mem::size_of::<VirtioPciCap>() as u8) + VIRTIO_PCI_CAP_LEN_OFFSET,
cap_len: (mem::size_of::<VirtioPciCap>() as u8) + VIRTIO_PCI_CAP_LEN_OFFSET,
cfg_type: cfg_type as u8,
pci_bar,
id: 0,
@@ -131,8 +131,7 @@ impl VirtioPciNotifyCap {
) -> Self {
VirtioPciNotifyCap {
cap: VirtioPciCap {
cap_len: (std::mem::size_of::<VirtioPciNotifyCap>() as u8)
+ VIRTIO_PCI_CAP_LEN_OFFSET,
cap_len: (mem::size_of::<VirtioPciNotifyCap>() as u8) + VIRTIO_PCI_CAP_LEN_OFFSET,
cfg_type: cfg_type as u8,
pci_bar,
id: 0,
@@ -169,7 +168,7 @@ impl VirtioPciCap64 {
pub fn new(cfg_type: PciCapabilityType, pci_bar: u8, id: u8, offset: u64, length: u64) -> Self {
VirtioPciCap64 {
cap: VirtioPciCap {
cap_len: (std::mem::size_of::<VirtioPciCap64>() as u8) + VIRTIO_PCI_CAP_LEN_OFFSET,
cap_len: (mem::size_of::<VirtioPciCap64>() as u8) + VIRTIO_PCI_CAP_LEN_OFFSET,
cfg_type: cfg_type as u8,
pci_bar,
id,
@@ -360,7 +359,7 @@ pub enum VirtioPciDeviceError {
#[error("Failed creating VirtioPciDevice")]
CreateVirtioPciDevice(#[source] anyhow::Error),
}
pub type Result<T> = std::result::Result<T, VirtioPciDeviceError>;
pub type Result<T> = result::Result<T, VirtioPciDeviceError>;
pub struct VirtioPciDevice {
id: String,
@@ -610,7 +609,7 @@ impl VirtioPciDevice {
// in the context of a restore given the device might require some
// activation, meaning it will require locking. Dropping the lock
// prevents from a subtle deadlock.
std::mem::drop(locked_device);
drop(locked_device);
let virtio_interrupt = Arc::new(VirtioInterruptMsix::new(
msix_config.clone(),
@@ -702,7 +701,7 @@ impl VirtioPciDevice {
.get_bar_addr(VIRTIO_COMMON_BAR_INDEX.into())
}
fn add_pci_capabilities(&mut self) -> std::result::Result<(), PciDeviceError> {
fn add_pci_capabilities(&mut self) -> result::Result<(), PciDeviceError> {
// Add pointers to the different configuration structures from the PCI capabilities.
let common_cap = VirtioPciCap::new(
PciCapabilityType::Common,
@@ -777,7 +776,7 @@ impl VirtioPciDevice {
return;
}
if offset < std::mem::size_of::<VirtioPciCap>() {
if offset < mem::size_of::<VirtioPciCap>() {
if let Some(end) = offset.checked_add(data_len) {
// This write can't fail, offset and end are checked against config_len.
data.write_all(&cap_slice[offset..cmp::min(end, cap_len)])
@@ -800,7 +799,7 @@ impl VirtioPciDevice {
return None;
}
if offset < std::mem::size_of::<VirtioPciCap>() {
if offset < mem::size_of::<VirtioPciCap>() {
let (_, right) = cap_slice.split_at_mut(offset);
right[..data_len].copy_from_slice(data);
None
@@ -907,7 +906,7 @@ impl VirtioInterruptMsix {
}
impl VirtioInterrupt for VirtioInterruptMsix {
fn trigger(&self, int_type: VirtioInterruptType) -> std::result::Result<(), std::io::Error> {
fn trigger(&self, int_type: VirtioInterruptType) -> io::Result<()> {
if matches!(int_type, VirtioInterruptType::Config) {
self.config_changed.store(true, Ordering::Release);
}
@@ -970,7 +969,7 @@ impl VirtioInterrupt for VirtioInterruptMsix {
interrupt: u32,
eventfd: Option<EventFd>,
vm: &dyn hypervisor::Vm,
) -> std::io::Result<()> {
) -> io::Result<()> {
self.interrupt_source_group
.set_notifier(interrupt, eventfd, vm)
}
@@ -1025,7 +1024,7 @@ impl PciDevice for VirtioPciDevice {
mmio32_allocator: &mut AddressAllocator,
mmio64_allocator: &mut AddressAllocator,
resources: Option<Vec<Resource>>,
) -> std::result::Result<Vec<PciBarConfiguration>, PciDeviceError> {
) -> result::Result<Vec<PciBarConfiguration>, PciDeviceError> {
let mut bars = Vec::new();
let device_clone = self.device.clone();
let device = device_clone.lock().unwrap();
@@ -1146,7 +1145,7 @@ impl PciDevice for VirtioPciDevice {
_allocator: &mut SystemAllocator,
mmio32_allocator: &mut AddressAllocator,
mmio64_allocator: &mut AddressAllocator,
) -> std::result::Result<(), PciDeviceError> {
) -> result::Result<(), PciDeviceError> {
for bar in self.bar_regions.drain(..) {
match bar.region_type() {
PciBarRegionType::Memory32BitRegion => {
@@ -1161,11 +1160,7 @@ impl PciDevice for VirtioPciDevice {
Ok(())
}
fn move_bar(
&mut self,
old_base: u64,
new_base: u64,
) -> std::result::Result<(), std::io::Error> {
fn move_bar(&mut self, old_base: u64, new_base: u64) -> io::Result<()> {
// We only update our idea of the bar in order to support free_bars() above.
// The majority of the reallocation is done inside DeviceManager.
for bar in self.bar_regions.iter_mut() {
@@ -1318,11 +1313,11 @@ impl BusDevice for VirtioPciDevice {
}
impl Pausable for VirtioPciDevice {
fn pause(&mut self) -> std::result::Result<(), MigratableError> {
fn pause(&mut self) -> result::Result<(), MigratableError> {
Ok(())
}
fn resume(&mut self) -> std::result::Result<(), MigratableError> {
fn resume(&mut self) -> result::Result<(), MigratableError> {
Ok(())
}
}
@@ -1332,7 +1327,7 @@ impl Snapshottable for VirtioPciDevice {
self.id.clone()
}
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
fn snapshot(&mut self) -> result::Result<Snapshot, MigratableError> {
let mut virtio_pci_dev_snapshot = Snapshot::new_from_state(&self.state())?;
// Snapshot PciConfiguration
@@ -1357,6 +1352,8 @@ impl Migratable for VirtioPciDevice {}
#[cfg(test)]
mod unit_tests {
use std::thread;
use vm_device::interrupt::InterruptSourceConfig;
use super::*;
@@ -1367,7 +1364,7 @@ mod unit_tests {
}
impl InterruptSourceGroup for TestInterruptSourceGroup {
fn trigger(&self, _index: InterruptIndex) -> std::result::Result<(), std::io::Error> {
fn trigger(&self, _index: InterruptIndex) -> io::Result<()> {
self.event_fd.write(1)
}
fn notifier(&self, _index: InterruptIndex) -> Option<EventFd> {
@@ -1379,10 +1376,10 @@ mod unit_tests {
_config: InterruptSourceConfig,
_masked: bool,
_set_gsi: bool,
) -> std::result::Result<(), std::io::Error> {
) -> io::Result<()> {
Ok(())
}
fn set_gsi(&self) -> std::result::Result<(), std::io::Error> {
fn set_gsi(&self) -> io::Result<()> {
Ok(())
}
}
@@ -1533,7 +1530,7 @@ mod unit_tests {
fn queue_max_sizes(&self) -> &[u16] {
&[]
}
fn activate(&mut self, _context: crate::device::ActivationContext) -> ActivateResult {
fn activate(&mut self, _context: ActivationContext) -> ActivateResult {
self.result.lock().unwrap().take().unwrap()
}
}
@@ -1543,7 +1540,7 @@ mod unit_tests {
}
impl VirtioInterrupt for TestVirtioInterrupt {
fn trigger(&self, int_type: VirtioInterruptType) -> std::io::Result<()> {
fn trigger(&self, int_type: VirtioInterruptType) -> io::Result<()> {
self.triggers.lock().unwrap().push(int_type);
Ok(())
}
@@ -1552,7 +1549,7 @@ mod unit_tests {
_int_type: u32,
_notifier: Option<EventFd>,
_vm: &dyn hypervisor::Vm,
) -> std::io::Result<()> {
) -> io::Result<()> {
Ok(())
}
}
@@ -1598,7 +1595,7 @@ mod unit_tests {
// Simulate the vCPU thread blocked on the activation
// barrier after writing DRIVER_OK.
let waiter = std::thread::spawn(move || barrier.wait());
let waiter = thread::spawn(move || barrier.wait());
let result = activator.activate();
@@ -1622,7 +1619,7 @@ mod unit_tests {
let (activator, status, device_activated, interrupt, barrier) = make_activator(Ok(()));
let initial_status = status.load(Ordering::SeqCst);
let waiter = std::thread::spawn(move || barrier.wait());
let waiter = thread::spawn(move || barrier.wait());
let result = activator.activate();

View File

@@ -6,7 +6,7 @@
use std::collections::BTreeMap;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Mutex};
use std::{io, result};
use std::{io, mem, result};
use anyhow::anyhow;
use event_monitor::event;
@@ -26,6 +26,7 @@ use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottabl
use vm_virtio::{AccessPlatform, Translatable};
use vmm_sys_util::eventfd::EventFd;
use crate::device::ActivationContext;
use crate::{
ActivateError, ActivateResult, DEVICE_ACKNOWLEDGE, DEVICE_DRIVER, DEVICE_DRIVER_OK,
DEVICE_FEATURES_OK, GuestMemoryMmap, VIRTIO_F_ACCESS_PLATFORM, VirtioCommon, VirtioDevice,
@@ -89,10 +90,10 @@ pub enum Error {
#[error("Failed to set vring size")]
SetVringNum(#[source] vhost::Error),
#[error("Failed to translate address")]
TranslateAddress(#[source] std::io::Error),
TranslateAddress(#[source] io::Error),
}
pub type Result<T> = std::result::Result<T, Error>;
pub type Result<T> = result::Result<T, Error>;
#[derive(Serialize, Deserialize)]
pub struct VdpaState {
@@ -252,7 +253,7 @@ impl Vdpa {
.desc_table()
.translate_gpa(
self.common.access_platform().as_deref(),
queue_size as usize * std::mem::size_of::<RawDescriptor>(),
queue_size as usize * mem::size_of::<RawDescriptor>(),
)
.map_err(Error::TranslateAddress)?,
used_ring_addr: queue
@@ -438,8 +439,8 @@ impl VirtioDevice for Vdpa {
}
}
fn activate(&mut self, context: crate::device::ActivationContext) -> ActivateResult {
let crate::device::ActivationContext {
fn activate(&mut self, context: ActivationContext) -> ActivateResult {
let ActivationContext {
mem,
interrupt_cb: virtio_interrupt,
queues,
@@ -477,7 +478,7 @@ impl VirtioDevice for Vdpa {
}
impl Pausable for Vdpa {
fn pause(&mut self) -> std::result::Result<(), MigratableError> {
fn pause(&mut self) -> result::Result<(), MigratableError> {
if self.migrating {
Ok(())
} else {
@@ -487,7 +488,7 @@ impl Pausable for Vdpa {
}
}
fn resume(&mut self) -> std::result::Result<(), MigratableError> {
fn resume(&mut self) -> result::Result<(), MigratableError> {
if !self.common.paused.load(Ordering::SeqCst) {
return Ok(());
}
@@ -507,7 +508,7 @@ impl Snapshottable for Vdpa {
self.id.clone()
}
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
fn snapshot(&mut self) -> result::Result<Snapshot, MigratableError> {
if !self.migrating {
return Err(MigratableError::Snapshot(anyhow!(
"Can't snapshot a vDPA device outside live migration"
@@ -530,7 +531,7 @@ impl Snapshottable for Vdpa {
impl Transportable for Vdpa {}
impl Migratable for Vdpa {
fn start_migration(&mut self) -> std::result::Result<(), MigratableError> {
fn start_migration(&mut self) -> result::Result<(), MigratableError> {
self.migrating = true;
// Given there's no way to track dirty pages, we must suspend the
// device as soon as the migration process starts.
@@ -546,7 +547,7 @@ impl Migratable for Vdpa {
}
}
fn complete_migration(&mut self) -> std::result::Result<(), MigratableError> {
fn complete_migration(&mut self) -> result::Result<(), MigratableError> {
self.migrating = false;
Ok(())
}
@@ -595,7 +596,7 @@ impl<M: GuestAddressSpace + Sync + Send> ExternalDmaMapping for VdpaDmaMapping<M
}
}
fn unmap(&self, iova: u64, size: u64) -> std::result::Result<(), std::io::Error> {
fn unmap(&self, iova: u64, size: u64) -> io::Result<()> {
debug!("DMA unmap iova 0x{iova:x} size 0x{size:x}");
self.device
.lock()

View File

@@ -25,6 +25,7 @@ use vmm_sys_util::eventfd::EventFd;
use super::super::{ActivateResult, VirtioCommon, VirtioDevice, VirtioDeviceType};
use super::vu_common_ctrl::{VhostUserConfig, VhostUserHandle};
use super::{DEFAULT_VIRTIO_FEATURES, Error, Result};
use crate::device::ActivationContext;
use crate::seccomp_filters::Thread;
use crate::vhost_user::{VhostUserCommon, VhostUserState};
use crate::{GuestRegionMmap, VIRTIO_F_ACCESS_PLATFORM};
@@ -196,7 +197,7 @@ impl Blk {
})
}
fn state(&self) -> std::result::Result<State, MigratableError> {
fn state(&self) -> result::Result<State, MigratableError> {
self.vu_common.state(self.config)
}
}
@@ -236,8 +237,7 @@ impl VirtioDevice for Blk {
// The "writeback" field is the only mutable field
let writeback_offset =
(&raw const self.config.writeback as u64) - (&raw const self.config as u64);
if offset != writeback_offset || data.len() != std::mem::size_of_val(&self.config.writeback)
{
if offset != writeback_offset || data.len() != mem::size_of_val(&self.config.writeback) {
error!(
"Attempt to write to read-only field: offset {:x} length {}",
offset,
@@ -263,8 +263,8 @@ impl VirtioDevice for Blk {
}
}
fn activate(&mut self, context: crate::device::ActivationContext) -> ActivateResult {
let crate::device::ActivationContext {
fn activate(&mut self, context: ActivationContext) -> ActivateResult {
let ActivationContext {
mem,
interrupt_cb,
queues,
@@ -317,7 +317,7 @@ impl VirtioDevice for Blk {
fn add_memory_region(
&mut self,
region: &Arc<GuestRegionMmap>,
) -> std::result::Result<(), crate::Error> {
) -> result::Result<(), crate::Error> {
self.vu_common.add_memory_region(region)
}
}
@@ -339,30 +339,30 @@ impl Snapshottable for Blk {
self.id.clone()
}
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
fn snapshot(&mut self) -> result::Result<Snapshot, MigratableError> {
self.vu_common.snapshot(&self.state()?)
}
}
impl Transportable for Blk {}
impl Migratable for Blk {
fn start_dirty_log(&mut self) -> std::result::Result<(), MigratableError> {
fn start_dirty_log(&mut self) -> result::Result<(), MigratableError> {
self.vu_common.start_dirty_log()
}
fn stop_dirty_log(&mut self) -> std::result::Result<(), MigratableError> {
fn stop_dirty_log(&mut self) -> result::Result<(), MigratableError> {
self.vu_common.stop_dirty_log()
}
fn dirty_log(&mut self) -> std::result::Result<MemoryRangeTable, MigratableError> {
fn dirty_log(&mut self) -> result::Result<MemoryRangeTable, MigratableError> {
self.vu_common.dirty_log()
}
fn start_migration(&mut self) -> std::result::Result<(), MigratableError> {
fn start_migration(&mut self) -> result::Result<(), MigratableError> {
self.vu_common.start_migration()
}
fn complete_migration(&mut self) -> std::result::Result<(), MigratableError> {
fn complete_migration(&mut self) -> result::Result<(), MigratableError> {
self.vu_common.complete_migration()
}
}

View File

@@ -20,6 +20,7 @@ use vmm_sys_util::eventfd::EventFd;
use super::vu_common_ctrl::VhostUserHandle;
use super::{DEFAULT_VIRTIO_FEATURES, Error, Result};
use crate::device::ActivationContext;
use crate::seccomp_filters::Thread;
use crate::vhost_user::{VhostUserCommon, VhostUserState};
use crate::{
@@ -202,7 +203,7 @@ impl Fs {
})
}
fn state(&self) -> std::result::Result<State, MigratableError> {
fn state(&self) -> result::Result<State, MigratableError> {
self.vu_common.state(self.config)
}
}
@@ -238,8 +239,8 @@ impl VirtioDevice for Fs {
self.read_config_from_slice(self.config.as_slice(), offset, data);
}
fn activate(&mut self, context: crate::device::ActivationContext) -> ActivateResult {
let crate::device::ActivationContext {
fn activate(&mut self, context: ActivationContext) -> ActivateResult {
let ActivationContext {
mem,
interrupt_cb,
queues,
@@ -296,7 +297,7 @@ impl VirtioDevice for Fs {
fn set_shm_regions(
&mut self,
shm_regions: VirtioSharedMemoryList,
) -> std::result::Result<(), crate::Error> {
) -> result::Result<(), crate::Error> {
if let Some(cache) = self.cache.as_mut() {
cache.0 = shm_regions;
Ok(())
@@ -308,7 +309,7 @@ impl VirtioDevice for Fs {
fn add_memory_region(
&mut self,
region: &Arc<GuestRegionMmap>,
) -> std::result::Result<(), crate::Error> {
) -> result::Result<(), crate::Error> {
self.vu_common.add_memory_region(region)
}
@@ -344,30 +345,30 @@ impl Snapshottable for Fs {
self.id.clone()
}
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
fn snapshot(&mut self) -> result::Result<Snapshot, MigratableError> {
self.vu_common.snapshot(&self.state()?)
}
}
impl Transportable for Fs {}
impl Migratable for Fs {
fn start_dirty_log(&mut self) -> std::result::Result<(), MigratableError> {
fn start_dirty_log(&mut self) -> result::Result<(), MigratableError> {
self.vu_common.start_dirty_log()
}
fn stop_dirty_log(&mut self) -> std::result::Result<(), MigratableError> {
fn stop_dirty_log(&mut self) -> result::Result<(), MigratableError> {
self.vu_common.stop_dirty_log()
}
fn dirty_log(&mut self) -> std::result::Result<MemoryRangeTable, MigratableError> {
fn dirty_log(&mut self) -> result::Result<MemoryRangeTable, MigratableError> {
self.vu_common.dirty_log()
}
fn start_migration(&mut self) -> std::result::Result<(), MigratableError> {
fn start_migration(&mut self) -> result::Result<(), MigratableError> {
self.vu_common.start_migration()
}
fn complete_migration(&mut self) -> std::result::Result<(), MigratableError> {
fn complete_migration(&mut self) -> result::Result<(), MigratableError> {
self.vu_common.complete_migration()
}
}

View File

@@ -2,9 +2,9 @@
// Copyright 2025 Demi Marie Obenour.
// SPDX-License-Identifier: Apache-2.0
use std::result;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Barrier, Mutex};
use std::{io, result};
use event_monitor::event;
use log::{error, info, warn};
@@ -20,6 +20,7 @@ use vmm_sys_util::eventfd::EventFd;
use super::vu_common_ctrl::VhostUserHandle;
use super::{Error, Result};
use crate::device::ActivationContext;
use crate::seccomp_filters::Thread;
use crate::vhost_user::{VhostUserCommon, VhostUserState};
use crate::{
@@ -34,12 +35,12 @@ struct BackendReqHandler {
}
impl VhostUserFrontendReqHandler for BackendReqHandler {
fn handle_config_change(&self) -> std::io::Result<u64> {
fn handle_config_change(&self) -> io::Result<u64> {
self.interrupt_cb
.trigger(VirtioInterruptType::Config)
.map_err(|e| {
error!("Failed to signal config change: {e:?}");
std::io::Error::other(e)
io::Error::other(e)
})?;
Ok(0)
}
@@ -176,7 +177,7 @@ since the backend only supports {backend_num_queues}\n",
})
}
fn state(&self) -> std::result::Result<State, MigratableError> {
fn state(&self) -> result::Result<State, MigratableError> {
self.vu_common.state(())
}
@@ -275,8 +276,8 @@ impl VirtioDevice for GenericVhostUser {
}
}
fn activate(&mut self, context: crate::device::ActivationContext) -> ActivateResult {
let crate::device::ActivationContext {
fn activate(&mut self, context: ActivationContext) -> ActivateResult {
let ActivationContext {
mem,
interrupt_cb,
queues,
@@ -357,7 +358,7 @@ impl VirtioDevice for GenericVhostUser {
fn set_shm_regions(
&mut self,
shm_regions: VirtioSharedMemoryList,
) -> std::result::Result<(), crate::Error> {
) -> result::Result<(), crate::Error> {
if let Some(cache) = self.cache.as_mut() {
cache.0 = shm_regions;
Ok(())
@@ -369,7 +370,7 @@ impl VirtioDevice for GenericVhostUser {
fn add_memory_region(
&mut self,
region: &Arc<GuestRegionMmap>,
) -> std::result::Result<(), crate::Error> {
) -> result::Result<(), crate::Error> {
self.vu_common.add_memory_region(region)
}
@@ -405,30 +406,30 @@ impl Snapshottable for GenericVhostUser {
self.id.clone()
}
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
fn snapshot(&mut self) -> result::Result<Snapshot, MigratableError> {
self.vu_common.snapshot(&self.state()?)
}
}
impl Transportable for GenericVhostUser {}
impl Migratable for GenericVhostUser {
fn start_dirty_log(&mut self) -> std::result::Result<(), MigratableError> {
fn start_dirty_log(&mut self) -> result::Result<(), MigratableError> {
self.vu_common.start_dirty_log()
}
fn stop_dirty_log(&mut self) -> std::result::Result<(), MigratableError> {
fn stop_dirty_log(&mut self) -> result::Result<(), MigratableError> {
self.vu_common.stop_dirty_log()
}
fn dirty_log(&mut self) -> std::result::Result<MemoryRangeTable, MigratableError> {
fn dirty_log(&mut self) -> result::Result<MemoryRangeTable, MigratableError> {
self.vu_common.dirty_log()
}
fn start_migration(&mut self) -> std::result::Result<(), MigratableError> {
fn start_migration(&mut self) -> result::Result<(), MigratableError> {
self.vu_common.start_migration()
}
fn complete_migration(&mut self) -> std::result::Result<(), MigratableError> {
fn complete_migration(&mut self) -> result::Result<(), MigratableError> {
self.vu_common.complete_migration()
}
}

View File

@@ -1,12 +1,13 @@
// Copyright 2019 Intel Corporation. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
use std::io;
use std::fs::{File, remove_file};
use std::io::ErrorKind;
use std::ops::Deref;
use std::os::unix::io::AsRawFd;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::atomic::{AtomicBool, AtomicU8, Ordering};
use std::sync::{Arc, Barrier, Mutex};
use std::{io, result};
use anyhow::anyhow;
use event_monitor::event;
@@ -117,7 +118,7 @@ pub enum Error {
#[error("Failed to read vhost eventfd")]
VhostUserMemoryRegion(#[source] MmapError),
#[error("Failed to create the frontend request handler from backend")]
FrontendReqHandlerCreation(#[source] vhost::vhost_user::Error),
FrontendReqHandlerCreation(#[source] VhostUserError),
#[error("Set backend request fd failed")]
VhostUserSetBackendRequestFd(#[source] vhost::Error),
#[error("Add memory region failed")]
@@ -179,7 +180,7 @@ pub enum Error {
#[error("Aborted vhost-user connect: kill event received")]
ConnectKilled,
}
type Result<T> = std::result::Result<T, Error>;
type Result<T> = result::Result<T, Error>;
fn io_error_is_connection_lost(error: &io::Error) -> bool {
matches!(
@@ -262,7 +263,7 @@ const BACKEND_REQ_EVENT: u16 = EPOLL_HELPER_EVENT_LAST + 2;
#[derive(Default)]
pub struct Inflight {
pub info: VhostUserInflight,
pub fd: Option<std::fs::File>,
pub fd: Option<File>,
}
pub struct VhostUserEpollHandler<S: VhostUserFrontendReqHandler> {
@@ -287,7 +288,7 @@ impl<S: VhostUserFrontendReqHandler> VhostUserEpollHandler<S> {
&mut self,
paused: &AtomicBool,
paused_sync: &Barrier,
) -> std::result::Result<(), EpollHelperError> {
) -> result::Result<(), EpollHelperError> {
let mut helper = EpollHelper::new(&self.kill_evt, &self.pause_evt)?;
helper.add_event_custom(
self.vu.lock().unwrap().socket_handle().as_raw_fd(),
@@ -304,7 +305,7 @@ impl<S: VhostUserFrontendReqHandler> VhostUserEpollHandler<S> {
Ok(())
}
fn reconnect(&mut self, helper: &mut EpollHelper) -> std::result::Result<(), EpollHelperError> {
fn reconnect(&mut self, helper: &mut EpollHelper) -> result::Result<(), EpollHelperError> {
let result = self.reconnect_inner(helper);
if result.is_err() {
// If reconnect fails, mark disconnected to avoid repeated failed socket calls.
@@ -316,7 +317,7 @@ impl<S: VhostUserFrontendReqHandler> VhostUserEpollHandler<S> {
fn reconnect_inner(
&mut self,
helper: &mut EpollHelper,
) -> std::result::Result<(), EpollHelperError> {
) -> result::Result<(), EpollHelperError> {
helper.del_event_custom(
self.vu.lock().unwrap().socket_handle().as_raw_fd(),
HUP_CONNECTION_EVENT,
@@ -336,7 +337,7 @@ impl<S: VhostUserFrontendReqHandler> VhostUserEpollHandler<S> {
// event and will tear down on its next iteration.
Err(Error::ConnectKilled) => return Ok(()),
Err(e) => {
return Err(EpollHelperError::IoError(std::io::Error::other(format!(
return Err(EpollHelperError::IoError(io::Error::other(format!(
"failed connecting vhost-user backend for socket {}: {e:?}",
self.socket_path
))));
@@ -360,7 +361,7 @@ impl<S: VhostUserFrontendReqHandler> VhostUserEpollHandler<S> {
self.inflight.as_mut(),
)
.map_err(|e| {
EpollHelperError::IoError(std::io::Error::other(format!(
EpollHelperError::IoError(io::Error::other(format!(
"failed reconnecting vhost-user backend: {e:?}"
)))
})?;
@@ -384,7 +385,7 @@ impl<S: VhostUserFrontendReqHandler> EpollHelperHandler for VhostUserEpollHandle
&mut self,
helper: &mut EpollHelper,
event: &epoll::Event,
) -> std::result::Result<(), EpollHelperError> {
) -> result::Result<(), EpollHelperError> {
let ev_type = event.data as u16;
let result = match ev_type {
HUP_CONNECTION_EVENT => {
@@ -483,7 +484,7 @@ impl VhostUserCommon {
backend_req_handler: Option<FrontendReqHandler<T>>,
kill_evt: EventFd,
pause_evt: EventFd,
) -> std::result::Result<VhostUserEpollHandler<T>, ActivateError> {
) -> result::Result<VhostUserEpollHandler<T>, ActivateError> {
self.guest_memory = Some(mem.clone());
if self.disconnected.load(Ordering::Relaxed) {
@@ -551,12 +552,12 @@ impl VhostUserCommon {
seccomp_action: &SeccompAction,
thread_type: Thread,
exit_evt: &EventFd,
device_status: Arc<std::sync::atomic::AtomicU8>,
device_status: Arc<AtomicU8>,
interrupt_cb: Arc<dyn VirtioInterrupt>,
f: F,
) -> std::result::Result<(), ActivateError>
) -> result::Result<(), ActivateError>
where
F: FnOnce() -> std::result::Result<(), EpollHelperError> + Send + 'static,
F: FnOnce() -> result::Result<(), EpollHelperError> + Send + 'static,
{
if let Err(e) = self.virtio_common.spawn_worker(
id,
@@ -624,7 +625,7 @@ impl VhostUserCommon {
// Remove socket path if needed
if self.server {
let _ = std::fs::remove_file(&self.socket_path);
let _ = remove_file(&self.socket_path);
}
// Drop the vhost-user handle
@@ -651,7 +652,7 @@ impl VhostUserCommon {
pub fn add_memory_region(
&mut self,
region: &Arc<GuestRegionMmap>,
) -> std::result::Result<(), crate::Error> {
) -> result::Result<(), crate::Error> {
if self.disconnected.load(Ordering::Relaxed) {
warn!(
"Skipping add memory region on disconnected dev with socket: {}",
@@ -678,7 +679,7 @@ impl VhostUserCommon {
Ok(())
}
pub fn pause(&mut self) -> std::result::Result<(), MigratableError> {
pub fn pause(&mut self) -> result::Result<(), MigratableError> {
if self.disconnected.load(Ordering::Relaxed) {
return Err(MigratableError::DeviceDisconnected(
self.socket_path.clone(),
@@ -703,7 +704,7 @@ impl VhostUserCommon {
Ok(())
}
fn resume_internal(&mut self) -> std::result::Result<(), MigratableError> {
fn resume_internal(&mut self) -> result::Result<(), MigratableError> {
// Skip the resume_vhost_user call if the backend is disconnected. Process the queue
// interrupts to kick any paused workers.
if self.disconnected.load(Ordering::Relaxed) {
@@ -731,7 +732,7 @@ impl VhostUserCommon {
Ok(())
}
pub fn resume(&mut self) -> std::result::Result<(), MigratableError> {
pub fn resume(&mut self) -> result::Result<(), MigratableError> {
let ret = self.resume_internal();
// Always run the interrupt loop so workers don't get stuck.
@@ -747,7 +748,7 @@ impl VhostUserCommon {
pub fn state<C: Default>(
&self,
config: C,
) -> std::result::Result<VhostUserState<C>, MigratableError> {
) -> result::Result<VhostUserState<C>, MigratableError> {
let mut state = VhostUserState {
avail_features: self.virtio_common.avail_features,
acked_features: self.virtio_common.acked_features,
@@ -771,7 +772,7 @@ impl VhostUserCommon {
Ok(state)
}
pub fn snapshot<T>(&mut self, state: &T) -> std::result::Result<Snapshot, MigratableError>
pub fn snapshot<T>(&mut self, state: &T) -> result::Result<Snapshot, MigratableError>
where
T: Serialize,
{
@@ -788,7 +789,7 @@ impl VhostUserCommon {
Ok(snapshot)
}
pub fn start_dirty_log(&mut self) -> std::result::Result<(), MigratableError> {
pub fn start_dirty_log(&mut self) -> result::Result<(), MigratableError> {
if let Some(vu) = &self.vu {
if let Some(guest_memory) = &self.guest_memory {
let last_ram_addr = guest_memory.memory().last_addr().raw_value();
@@ -812,7 +813,7 @@ impl VhostUserCommon {
}
}
pub fn stop_dirty_log(&mut self) -> std::result::Result<(), MigratableError> {
pub fn stop_dirty_log(&mut self) -> result::Result<(), MigratableError> {
if let Some(vu) = &self.vu {
vu.lock().unwrap().stop_dirty_log().map_err(|e| {
MigratableError::StopDirtyLog(anyhow!(
@@ -825,7 +826,7 @@ impl VhostUserCommon {
Ok(())
}
pub fn dirty_log(&mut self) -> std::result::Result<MemoryRangeTable, MigratableError> {
pub fn dirty_log(&mut self) -> result::Result<MemoryRangeTable, MigratableError> {
if let Some(vu) = &self.vu {
if let Some(guest_memory) = &self.guest_memory {
let last_ram_addr = guest_memory.memory().last_addr().raw_value();
@@ -842,12 +843,12 @@ impl VhostUserCommon {
}
}
pub fn start_migration(&mut self) -> std::result::Result<(), MigratableError> {
pub fn start_migration(&mut self) -> result::Result<(), MigratableError> {
self.migration_started = true;
Ok(())
}
pub fn complete_migration(&mut self) -> std::result::Result<(), MigratableError> {
pub fn complete_migration(&mut self) -> result::Result<(), MigratableError> {
self.migration_started = false;
self.dirty_logging = false;

View File

@@ -23,6 +23,7 @@ use vm_migration::protocol::MemoryRangeTable;
use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable};
use vmm_sys_util::eventfd::EventFd;
use crate::device::ActivationContext;
use crate::seccomp_filters::Thread;
use crate::vhost_user::vu_common_ctrl::{VhostUserConfig, VhostUserHandle};
use crate::vhost_user::{DEFAULT_VIRTIO_FEATURES, Error, Result, VhostUserCommon, VhostUserState};
@@ -223,7 +224,7 @@ impl Net {
})
}
fn state(&self) -> std::result::Result<State, MigratableError> {
fn state(&self) -> result::Result<State, MigratableError> {
self.vu_common.state(self.config)
}
}
@@ -259,8 +260,8 @@ impl VirtioDevice for Net {
self.read_config_from_slice(self.config.as_slice(), offset, data);
}
fn activate(&mut self, context: crate::device::ActivationContext) -> ActivateResult {
let crate::device::ActivationContext {
fn activate(&mut self, context: ActivationContext) -> ActivateResult {
let ActivationContext {
mem,
interrupt_cb,
mut queues,
@@ -366,7 +367,7 @@ impl VirtioDevice for Net {
fn add_memory_region(
&mut self,
region: &Arc<GuestRegionMmap>,
) -> std::result::Result<(), crate::Error> {
) -> result::Result<(), crate::Error> {
self.vu_common.add_memory_region(region)
}
}
@@ -388,30 +389,30 @@ impl Snapshottable for Net {
self.id.clone()
}
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
fn snapshot(&mut self) -> result::Result<Snapshot, MigratableError> {
self.vu_common.snapshot(&self.state()?)
}
}
impl Transportable for Net {}
impl Migratable for Net {
fn start_dirty_log(&mut self) -> std::result::Result<(), MigratableError> {
fn start_dirty_log(&mut self) -> result::Result<(), MigratableError> {
self.vu_common.start_dirty_log()
}
fn stop_dirty_log(&mut self) -> std::result::Result<(), MigratableError> {
fn stop_dirty_log(&mut self) -> result::Result<(), MigratableError> {
self.vu_common.stop_dirty_log()
}
fn dirty_log(&mut self) -> std::result::Result<MemoryRangeTable, MigratableError> {
fn dirty_log(&mut self) -> result::Result<MemoryRangeTable, MigratableError> {
self.vu_common.dirty_log()
}
fn start_migration(&mut self) -> std::result::Result<(), MigratableError> {
fn start_migration(&mut self) -> result::Result<(), MigratableError> {
self.vu_common.start_migration()
}
fn complete_migration(&mut self) -> std::result::Result<(), MigratableError> {
fn complete_migration(&mut self) -> result::Result<(), MigratableError> {
self.vu_common.complete_migration()
}
}

View File

@@ -1,7 +1,6 @@
// Copyright 2019 Intel Corporation. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
use std::ffi;
use std::fs::File;
use std::io::{Read, Write};
use std::os::unix::io::{AsRawFd, FromRawFd, OwnedFd, RawFd};
@@ -9,6 +8,7 @@ use std::os::unix::net::{UnixListener, UnixStream};
use std::sync::Arc;
use std::sync::atomic::Ordering;
use std::time::{Duration, Instant};
use std::{ffi, fs, io, mem, slice};
use log::{error, info};
use vhost::vhost_kern::vhost_binding::VHOST_VRING_F_LOG;
@@ -228,7 +228,7 @@ impl VhostUserHandle {
desc_table_addr: get_host_address_range(
mem,
GuestAddress(queue.desc_table()),
actual_size * std::mem::size_of::<RawDescriptor>(),
actual_size * mem::size_of::<RawDescriptor>(),
)
.ok_or(Error::DescriptorTableAddress)? as u64,
// The used ring is {flags: u16; idx: u16; virtq_used_elem [{id: u16, len: u16}; actual_size]},
@@ -385,7 +385,7 @@ impl VhostUserHandle {
) -> Result<Self> {
if server {
if unlink_socket {
std::fs::remove_file(socket_path).map_err(Error::RemoveSocketPath)?;
fs::remove_file(socket_path).map_err(Error::RemoveSocketPath)?;
}
info!("Binding vhost-user listener...");
@@ -467,7 +467,7 @@ impl VhostUserHandle {
loop {
match epoll.wait(-1, &mut events) {
Ok(_) => break,
Err(e) if e.kind() == std::io::ErrorKind::Interrupted => continue,
Err(e) if e.kind() == io::ErrorKind::Interrupted => continue,
Err(e) => return Err(Error::EpollWait(e)),
}
}
@@ -640,7 +640,7 @@ impl VhostUserHandle {
)
};
if res < 0 {
return Err(Error::SetSeals(std::io::Error::last_os_error()));
return Err(Error::SetSeals(io::Error::last_os_error()));
}
// Mmap shm_log region
@@ -744,7 +744,7 @@ impl VhostUserHandle {
let bitmap: &[u64] = unsafe {
// Cast the pointer to u64
let ptr = region.as_ptr().cast();
std::slice::from_raw_parts(ptr, len)
slice::from_raw_parts(ptr, len)
};
Ok(MemoryRangeTable::from_dirty_bitmap(
bitmap.iter().copied(),
@@ -757,12 +757,12 @@ impl VhostUserHandle {
}
}
fn memfd_create(name: &ffi::CStr, flags: u32) -> std::result::Result<RawFd, std::io::Error> {
fn memfd_create(name: &ffi::CStr, flags: u32) -> io::Result<RawFd> {
// SAFETY: FFI call with valid arguments
let res = unsafe { libc::syscall(libc::SYS_memfd_create, name.as_ptr(), flags) };
if res < 0 {
Err(std::io::Error::last_os_error())
Err(io::Error::last_os_error())
} else {
Ok(res as RawFd)
}

View File

@@ -84,6 +84,7 @@ use std::io::{ErrorKind, Read, Write};
use std::num::Wrapping;
use std::os::unix::io::{AsRawFd, RawFd};
use std::time::{Duration, Instant};
use std::{cmp, io};
use log::{debug, error, info, warn};
use vm_memory::{ReadVolatile, WriteVolatile};
@@ -230,7 +231,7 @@ where
// The maximum amount of data we can read in is limited by both the RX buffer size and
// the peer available buffer space.
let max_len = std::cmp::min(buf_capacity, self.peer_avail_credit());
let max_len = cmp::min(buf_capacity, self.peer_avail_credit());
// Read data from the stream straight to the RX buffer, for maximum throughput.
match pkt.read_volatile_from(&mut self.stream, max_len) {
@@ -739,7 +740,7 @@ where
"vsock: error shutting down host write side (lp={}, pp={}): {:?}",
self.local_port,
self.peer_port,
std::io::Error::last_os_error()
io::Error::last_os_error()
);
}
self.host_write_shutdown = true;
@@ -790,6 +791,7 @@ where
#[cfg(test)]
mod unit_tests {
use std::io::{Error as IoError, Result as IoResult};
use std::{result, thread};
use libc::EFD_NONBLOCK;
use virtio_queue::QueueOwnedT;
@@ -853,7 +855,7 @@ mod unit_tests {
if self.read_buf.is_empty() {
return Err(IoError::new(ErrorKind::WouldBlock, "EAGAIN"));
}
let len = std::cmp::min(data.len(), self.read_buf.len());
let len = cmp::min(data.len(), self.read_buf.len());
assert_ne!(len, 0);
data[..len].copy_from_slice(&self.read_buf[..len]);
self.read_buf = self.read_buf.split_off(len);
@@ -885,7 +887,7 @@ mod unit_tests {
fn read_volatile<B: BitmapSlice>(
&mut self,
data: &mut VolatileSlice<B>,
) -> std::result::Result<usize, VolatileMemoryError> {
) -> result::Result<usize, VolatileMemoryError> {
let mut buf = vec![0u8; data.len()];
let len = self.read(&mut buf).map_err(VolatileMemoryError::IOError)?;
data.copy_from(&buf[..len]);
@@ -897,7 +899,7 @@ mod unit_tests {
fn write_volatile<B: BitmapSlice>(
&mut self,
data: &VolatileSlice<B>,
) -> std::result::Result<usize, VolatileMemoryError> {
) -> result::Result<usize, VolatileMemoryError> {
let mut buf = vec![0u8; data.len()];
data.copy_to(&mut buf);
self.write(&buf).map_err(VolatileMemoryError::IOError)
@@ -1101,9 +1103,7 @@ mod unit_tests {
assert_eq!(ctx.pkt.op(), uapi::VSOCK_OP_REQUEST);
assert!(ctx.conn.will_expire());
assert!(!ctx.conn.has_expired());
std::thread::sleep(std::time::Duration::from_millis(
defs::CONN_REQUEST_TIMEOUT_MS,
));
thread::sleep(Duration::from_millis(defs::CONN_REQUEST_TIMEOUT_MS));
assert!(ctx.conn.has_expired());
}

View File

@@ -4,6 +4,8 @@
//! This module implements our vsock connection state machine. The heavy lifting is done by
//! `connection::VsockConnection`, while this file only defines some constants and helper structs.
use std::{io, result};
use thiserror::Error;
mod connection;
@@ -33,16 +35,16 @@ pub enum Error {
TxBufFull,
/// An I/O error occurred, when attempting to flush the connection TX buffer.
#[error("Error flushing TX buffer")]
TxBufFlush(#[source] std::io::Error),
TxBufFlush(#[source] io::Error),
/// An I/O error occurred, when attempting to write data to the host-side stream.
#[error("Error writing to host side stream")]
StreamWrite(#[source] std::io::Error),
StreamWrite(#[source] io::Error),
/// An I/O error occurred, when reading packet data.
#[error("Error reading packet buffer")]
PktBufRead,
}
type Result<T> = std::result::Result<T, Error>;
type Result<T> = result::Result<T, Error>;
/// A vsock connection state.
///

View File

@@ -2,6 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
//
use std::cmp;
use std::io::Write;
use std::num::Wrapping;
@@ -85,7 +86,7 @@ impl TxBuf {
// ring-buffer head wraps around.
// First copy length: we can only go from the head offset up to the total buffer size.
let first_len = std::cmp::min(Self::SIZE - head_ofs, len);
let first_len = cmp::min(Self::SIZE - head_ofs, len);
src.copy_to_tx_buf(offset, &mut data[head_ofs..(head_ofs + first_len)])?;
// If the data didn't fit, the buffer head will wrap around, and pushing continues
@@ -125,7 +126,7 @@ impl TxBuf {
// head.
// First write length: the lesser of tail to slice end, or tail to head.
let len_to_write = std::cmp::min(Self::SIZE - tail_ofs, self.len());
let len_to_write = cmp::min(Self::SIZE - tail_ofs, self.len());
// It's safe to unwrap here, since we've already checked if the buffer was empty.
let data = self.data.as_ref().unwrap();
@@ -201,7 +202,7 @@ mod unit_tests {
if self.err.is_some() {
return Err(self.err.take().unwrap());
}
let len_to_push = std::cmp::min(self.capacity - self.data.len(), src.len());
let len_to_push = cmp::min(self.capacity - self.data.len(), src.len());
self.data.extend_from_slice(&src[..len_to_push]);
Ok(len_to_push)
}

View File

@@ -12,7 +12,7 @@ use std::os::unix::io::AsRawFd;
use std::path::PathBuf;
use std::sync::atomic::AtomicBool;
use std::sync::{Arc, Barrier, RwLock};
use std::{io, result};
use std::{fs, io, result};
use anyhow::anyhow;
use byteorder::{ByteOrder, LittleEndian};
@@ -47,6 +47,7 @@ use vmm_sys_util::eventfd::EventFd;
/// - a backend FD.
///
use super::{VsockBackend, VsockPacket};
use crate::device::ActivationContext;
use crate::seccomp_filters::Thread;
use crate::{
ActivateResult, EPOLL_HELPER_EVENT_LAST, EpollHelper, EpollHelperError, EpollHelperHandler,
@@ -461,8 +462,8 @@ where
}
}
fn activate(&mut self, context: crate::device::ActivationContext) -> ActivateResult {
let crate::device::ActivationContext {
fn activate(&mut self, context: ActivationContext) -> ActivateResult {
let ActivationContext {
mem,
interrupt_cb,
queues,
@@ -512,7 +513,7 @@ where
}
fn shutdown(&mut self) {
std::fs::remove_file(&self.path).ok();
fs::remove_file(&self.path).ok();
}
fn set_access_platform(&mut self, access_platform: Arc<dyn AccessPlatform>) {
@@ -545,7 +546,7 @@ where
self.id.clone()
}
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
fn snapshot(&mut self) -> result::Result<Snapshot, MigratableError> {
Snapshot::new_from_state(&self.state())
}
}
@@ -554,6 +555,8 @@ impl<B> Migratable for Vsock<B> where B: VsockBackend + Sync + 'static {}
#[cfg(test)]
mod unit_tests {
use std::sync::atomic::AtomicU8;
use libc::EFD_NONBLOCK;
use super::super::unit_tests::{NoopVirtioInterrupt, TestContext};
@@ -621,11 +624,11 @@ mod unit_tests {
let memory = GuestMemoryAtomic::new(ctx.mem.clone());
// Test a bad activation.
let bad_activate = ctx.device.activate(crate::device::ActivationContext {
let bad_activate = ctx.device.activate(ActivationContext {
mem: memory.clone(),
interrupt_cb: Arc::new(NoopVirtioInterrupt {}),
queues: Vec::new(),
device_status: Arc::new(std::sync::atomic::AtomicU8::new(0)),
device_status: Arc::new(AtomicU8::new(0)),
});
match bad_activate {
Err(ActivateError::BadActivate) => (),
@@ -634,7 +637,7 @@ mod unit_tests {
// Test a correct activation.
ctx.device
.activate(crate::device::ActivationContext {
.activate(ActivationContext {
mem: memory,
interrupt_cb: Arc::new(NoopVirtioInterrupt {}),
queues: vec![
@@ -654,7 +657,7 @@ mod unit_tests {
EventFd::new(EFD_NONBLOCK).unwrap(),
),
],
device_status: Arc::new(std::sync::atomic::AtomicU8::new(0)),
device_status: Arc::new(AtomicU8::new(0)),
})
.unwrap();
}

View File

@@ -14,6 +14,7 @@ mod packet;
mod unix;
use std::os::unix::io::RawFd;
use std::result;
use packet::VsockPacket;
use thiserror::Error;
@@ -103,7 +104,7 @@ pub enum VsockError {
#[error("Encountered an unexpected read-only virtio descriptor")]
UnwritableDescriptor,
}
type Result<T> = std::result::Result<T, VsockError>;
type Result<T> = result::Result<T, VsockError>;
/// A passive, event-driven object, that needs to be notified whenever an epoll-able event occurs.
///
@@ -158,6 +159,7 @@ pub trait VsockBackend: VsockChannel + VsockEpollListener + Send {
#[cfg(any(test, fuzzing))]
pub mod unit_tests {
use std::io;
use std::os::unix::io::AsRawFd;
use std::path::PathBuf;
use std::sync::{Arc, RwLock};
@@ -178,10 +180,7 @@ pub mod unit_tests {
pub struct NoopVirtioInterrupt {}
impl VirtioInterrupt for NoopVirtioInterrupt {
fn trigger(
&self,
_int_type: VirtioInterruptType,
) -> std::result::Result<(), std::io::Error> {
fn trigger(&self, _int_type: VirtioInterruptType) -> io::Result<()> {
Ok(())
}
@@ -190,7 +189,7 @@ pub mod unit_tests {
_interrupt: u32,
_eventfd: Option<EventFd>,
_vm: &dyn hypervisor::Vm,
) -> std::io::Result<()> {
) -> io::Result<()> {
unimplemented!()
}
}

View File

@@ -15,6 +15,7 @@
//! checked range, so it can be moved with volatile I/O without exposing raw host pointers.
//! Multi-descriptor TX packets use a local bounce buffer.
use std::cmp;
use std::io::{self, ErrorKind, Read, Write};
use std::ops::Deref;
@@ -357,7 +358,7 @@ impl VsockPacket {
let desc_len = desc.len() as usize;
if desc_len > 0 && offset < total_len {
let to_copy = std::cmp::min(desc_len, total_len - offset);
let to_copy = cmp::min(desc_len, total_len - offset);
desc_chain
.memory()
.read_slice(&mut owned[offset..offset + to_copy], desc.addr())
@@ -678,7 +679,7 @@ impl VsockPacket {
#[cfg(test)]
mod unit_tests {
use virtio_bindings::virtio_ring::VRING_DESC_F_WRITE;
use virtio_bindings::virtio_ring::{VRING_DESC_F_NEXT, VRING_DESC_F_WRITE};
use virtio_queue::QueueOwnedT;
use vm_memory::GuestAddress;
use vm_virtio::queue::testing::{VirtQueue as GuestQ, VirtqDesc as GuestQDesc};
@@ -823,17 +824,13 @@ mod unit_tests {
guest_txvq.dtable[0].set(
0x0061_0000,
VSOCK_PKT_HDR_SIZE as u32,
virtio_bindings::virtio_ring::VRING_DESC_F_NEXT
.try_into()
.unwrap(),
VRING_DESC_F_NEXT.try_into().unwrap(),
1,
);
guest_txvq.dtable[1].set(
0x0061_1000,
4 * 1024,
virtio_bindings::virtio_ring::VRING_DESC_F_NEXT
.try_into()
.unwrap(),
VRING_DESC_F_NEXT.try_into().unwrap(),
2,
);
guest_txvq.dtable[2].set(0x0061_2000, 4 * 1024, 0, 0);

View File

@@ -13,6 +13,9 @@ mod muxer;
mod muxer_killq;
mod muxer_rxq;
use std::os::unix::net::UnixStream;
use std::{io, num, result, str};
pub use Error as VsockUnixError;
pub use muxer::VsockMuxer as VsockUnixBackend;
use thiserror::Error;
@@ -32,38 +35,38 @@ mod defs {
pub enum Error {
/// Error converting from UTF-8
#[error("Error converting from UTF-8")]
ConvertFromUtf8(#[source] std::str::Utf8Error),
ConvertFromUtf8(#[source] str::Utf8Error),
/// Error registering a new epoll-listening FD.
#[error("Error registering a new epoll-listening FD")]
EpollAdd(#[source] std::io::Error),
EpollAdd(#[source] io::Error),
/// Error creating an epoll FD.
#[error("Error creating an epoll FD")]
EpollFdCreate(#[source] std::io::Error),
EpollFdCreate(#[source] io::Error),
/// The host made an invalid vsock port connection request.
#[error("The host made an invalid vsock port connection request")]
InvalidPortRequest,
/// Error parsing integer.
#[error("Error parsing integer")]
ParseInteger(#[source] std::num::ParseIntError),
ParseInteger(#[source] num::ParseIntError),
/// Error reading stream port.
#[error("Error reading stream port")]
ReadStreamPort(#[source] Box<Error>),
/// Error accepting a new connection from the host-side Unix socket.
#[error("Error accepting a new connection from the host-side Unix socket")]
UnixAccept(#[source] std::io::Error),
UnixAccept(#[source] io::Error),
/// Error binding to the host-side Unix socket.
#[error("Error binding to the host-side Unix socket")]
UnixBind(#[source] std::io::Error),
UnixBind(#[source] io::Error),
/// Error connecting to a host-side Unix socket.
#[error("Error connecting to a host-side Unix socket")]
UnixConnect(#[source] std::io::Error),
UnixConnect(#[source] io::Error),
/// Error reading from host-side Unix socket.
#[error("Error reading from host-side Unix socket")]
UnixRead(#[source] std::io::Error),
UnixRead(#[source] io::Error),
/// Muxer connection limit reached.
#[error("Muxer connection limit reached")]
TooManyConnections,
}
type Result<T> = std::result::Result<T, Error>;
type MuxerConnection = super::csm::VsockConnection<std::os::unix::net::UnixStream>;
type Result<T> = result::Result<T, Error>;
type MuxerConnection = super::csm::VsockConnection<UnixStream>;

View File

@@ -44,6 +44,7 @@ use std::fs::File;
use std::io::{self, ErrorKind, Read};
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
use std::os::unix::net::{UnixListener, UnixStream};
use std::str;
use log::{debug, error, info, warn};
@@ -514,7 +515,7 @@ impl VsockMuxer {
if command.len < connect_prefix.len() {
return match opt_new_line_position {
Some(_) => Err(Error::InvalidPortRequest),
None => Err(Error::UnixRead(std::io::ErrorKind::WouldBlock.into())),
None => Err(Error::UnixRead(io::ErrorKind::WouldBlock.into())),
};
}
@@ -530,12 +531,12 @@ impl VsockMuxer {
// we parsed correctly `connect ` but need to wait for `\n`
let new_line_position =
opt_new_line_position.ok_or(Error::UnixRead(std::io::ErrorKind::WouldBlock.into()))?;
opt_new_line_position.ok_or(Error::UnixRead(io::ErrorKind::WouldBlock.into()))?;
// we now have the newline, we will treat everything in between as the port
let port_string_as_bytes = &command.buf[connect_prefix.len()..new_line_position];
std::str::from_utf8(port_string_as_bytes)
str::from_utf8(port_string_as_bytes)
.map_err(|_| Error::InvalidPortRequest)?
.trim()
.parse::<u32>()
@@ -887,10 +888,11 @@ impl VsockMuxer {
#[cfg(test)]
mod unit_tests {
use std::cmp::min;
use std::fs;
use std::io::Write;
use std::net::Shutdown;
use std::path::{Path, PathBuf};
use std::time::Duration;
use std::{fs, thread};
use virtio_queue::QueueOwnedT;
@@ -921,7 +923,7 @@ mod unit_tests {
impl Drop for MuxerTestContext {
fn drop(&mut self) {
std::fs::remove_file(self.muxer.host_sock_path.as_str()).unwrap();
fs::remove_file(self.muxer.host_sock_path.as_str()).unwrap();
}
}
@@ -1094,7 +1096,7 @@ mod unit_tests {
}
impl Drop for LocalListener {
fn drop(&mut self) {
std::fs::remove_file(&self.path).unwrap();
fs::remove_file(&self.path).unwrap();
}
}
@@ -1499,9 +1501,7 @@ mod unit_tests {
assert!(!ctx.muxer.has_pending_rx());
// Wait for the kill timers to expire.
std::thread::sleep(std::time::Duration::from_millis(
csm_defs::CONN_SHUTDOWN_TIMEOUT_MS,
));
thread::sleep(Duration::from_millis(csm_defs::CONN_SHUTDOWN_TIMEOUT_MS));
// Trigger a kill queue sweep, by requesting a new connection.
ctx.init_pkt(

View File

@@ -8,10 +8,10 @@
use std::fs::File;
use std::io::{self, Read};
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
use std::result;
use std::sync::atomic::AtomicBool;
use std::sync::{Arc, Barrier, Mutex};
use std::time::Instant;
use std::{ptr, result};
use anyhow::anyhow;
use event_monitor::event;
@@ -20,7 +20,7 @@ use seccompiler::SeccompAction;
use serde::{Deserialize, Serialize};
use thiserror::Error;
use virtio_queue::{Queue, QueueT};
use vm_memory::{Bytes, GuestAddressSpace, GuestMemoryAtomic};
use vm_memory::{Bytes, GuestAddressSpace, GuestMemoryAtomic, guest_memory};
use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable};
use vm_virtio::checked_descriptor::DescriptorChainExt;
use vmm_sys_util::eventfd::EventFd;
@@ -30,6 +30,7 @@ use super::{
EpollHelperHandler, Error as DeviceError, VIRTIO_F_ACCESS_PLATFORM, VIRTIO_F_VERSION_1,
VirtioCommon, VirtioDevice, VirtioDeviceType,
};
use crate::device::ActivationContext;
use crate::seccomp_filters::Thread;
use crate::{GuestMemoryMmap, VirtioInterrupt, VirtioInterruptType};
@@ -59,7 +60,7 @@ enum Error {
#[error("Invalid descriptor")]
InvalidDescriptor,
#[error("Failed to write to guest memory")]
GuestMemoryWrite(#[source] vm_memory::guest_memory::Error),
GuestMemoryWrite(#[source] guest_memory::Error),
}
struct WatchdogEpollHandler {
@@ -299,7 +300,7 @@ fn timerfd_setup(timer: &File, secs: i64) -> Result<(), io::Error> {
let res =
// SAFETY: FFI call with correct arguments
unsafe { libc::timerfd_settime(timer.as_raw_fd(), 0, &periodic, std::ptr::null_mut()) };
unsafe { libc::timerfd_settime(timer.as_raw_fd(), 0, &periodic, ptr::null_mut()) };
if res < 0 {
Err(io::Error::last_os_error())
@@ -325,8 +326,8 @@ impl VirtioDevice for Watchdog {
self.common.ack_features(value);
}
fn activate(&mut self, context: crate::device::ActivationContext) -> ActivateResult {
let crate::device::ActivationContext {
fn activate(&mut self, context: ActivationContext) -> ActivateResult {
let ActivationContext {
mem,
interrupt_cb,
mut queues,
@@ -407,7 +408,7 @@ impl Snapshottable for Watchdog {
self.id.clone()
}
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
fn snapshot(&mut self) -> result::Result<Snapshot, MigratableError> {
Snapshot::new_from_state(&self.state())
}
}