From a3dcaedf7e1fcf417781a842d5725433acc26244 Mon Sep 17 00:00:00 2001 From: Philipp Schuster Date: Mon, 19 May 2025 09:51:07 +0200 Subject: [PATCH] misc: vhost_user_net: streamline #[source] and Error This streamlines the code base to follow best practices for error handling in Rust: Each error struct implements std::error::Error (most due via thiserror::Error derive macro) and sets its source accordingly. This allows future work that nicely prints the error chains, for example. So far, the convention is that each error prints its sub error as part of its Display::fmt() impl. Signed-off-by: Philipp Schuster On-behalf-of: SAP philipp.schuster@sap.com --- Cargo.lock | 1 + vhost_user_net/Cargo.toml | 1 + vhost_user_net/src/lib.rs | 34 ++++++++++++++++++---------------- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f58a8a496..bfe485779 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2353,6 +2353,7 @@ dependencies = [ "log", "net_util", "option_parser", + "thiserror 2.0.6", "vhost", "vhost-user-backend", "virtio-bindings", diff --git a/vhost_user_net/Cargo.toml b/vhost_user_net/Cargo.toml index 18ca3a2c7..4b9175667 100644 --- a/vhost_user_net/Cargo.toml +++ b/vhost_user_net/Cargo.toml @@ -13,6 +13,7 @@ libc = "0.2.167" log = "0.4.22" net_util = { path = "../net_util" } option_parser = { path = "../option_parser" } +thiserror = "2.0.6" vhost = { workspace = true, features = ["vhost-user-backend"] } vhost-user-backend = { workspace = true } virtio-bindings = { workspace = true } diff --git a/vhost_user_net/src/lib.rs b/vhost_user_net/src/lib.rs index d44dcd5ab..fa679e60f 100644 --- a/vhost_user_net/src/lib.rs +++ b/vhost_user_net/src/lib.rs @@ -10,7 +10,7 @@ use std::net::{IpAddr, Ipv4Addr}; use std::ops::Deref; use std::os::unix::io::{AsRawFd, RawFd}; use std::sync::{Arc, Mutex, RwLock}; -use std::{fmt, io, process}; +use std::{io, process}; use libc::EFD_NONBLOCK; use log::*; @@ -18,6 +18,7 @@ use net_util::{ open_tap, MacAddr, NetCounters, NetQueuePair, OpenTapError, RxVirtio, Tap, TxVirtio, }; use option_parser::{OptionParser, OptionParserError, Toggle}; +use thiserror::Error; use vhost::vhost_user::message::*; use vhost::vhost_user::Listener; use vhost_user_backend::bitmap::BitmapMmapRegion; @@ -33,40 +34,41 @@ type GuestMemoryMmap = vm_memory::GuestMemoryMmap; pub type Result = std::result::Result; type VhostUserBackendResult = std::result::Result; -#[derive(Debug)] +#[derive(Error, Debug)] pub enum Error { /// Failed to create kill eventfd. - CreateKillEventFd(io::Error), + #[error("Failed to create kill eventfd: {0}")] + CreateKillEventFd(#[source] io::Error), /// Failed to parse configuration string. - FailedConfigParse(OptionParserError), + #[error("Failed to parse configuration string: {0}")] + FailedConfigParse(#[source] OptionParserError), /// Failed to signal used queue. - FailedSignalingUsedQueue(io::Error), + #[error("Failed to signal used queue: {0}")] + FailedSignalingUsedQueue(#[source] io::Error), /// Failed to handle event other than input event. + #[error("Failed to handle event other than input event")] HandleEventNotEpollIn, /// Failed to handle unknown event. + #[error("Failed to handle unknown event")] HandleEventUnknownEvent, /// Failed to open tap device. - OpenTap(OpenTapError), + #[error("Failed to open tap device: {0}")] + OpenTap(#[source] OpenTapError), /// No socket provided. + #[error("No socket provided")] SocketParameterMissing, /// Underlying QueuePair error. - NetQueuePair(net_util::NetQueuePairError), + #[error("Underlying QueuePair error: {0}")] + NetQueuePair(#[source] net_util::NetQueuePairError), /// Failed to register the TAP listener. - RegisterTapListener(io::Error), + #[error("Failed to register the TAP listener: {0}")] + RegisterTapListener(#[source] io::Error), } pub const SYNTAX: &str = "vhost-user-net backend parameters \ \"ip=,mask=,socket=,client=on|off,\ num_queues=,queue_size=,tap=\""; -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "vhost_user_net_error: {self:?}") - } -} - -impl std::error::Error for Error {} - impl std::convert::From for std::io::Error { fn from(e: Error) -> Self { std::io::Error::other(e)