From eb0b14f70ed5ed44b76579145fd2a741c0100ae4 Mon Sep 17 00:00:00 2001 From: Philipp Schuster Date: Mon, 19 May 2025 09:50:59 +0200 Subject: [PATCH] misc: vhost_user_block: 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_block/Cargo.toml | 1 + vhost_user_block/src/lib.rs | 23 +++++++++++------------ 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b7af3e20e..f58a8a496 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2333,6 +2333,7 @@ dependencies = [ "libc", "log", "option_parser", + "thiserror 2.0.6", "vhost", "vhost-user-backend", "virtio-bindings", diff --git a/vhost_user_block/Cargo.toml b/vhost_user_block/Cargo.toml index 03d0db501..3f543687d 100644 --- a/vhost_user_block/Cargo.toml +++ b/vhost_user_block/Cargo.toml @@ -13,6 +13,7 @@ epoll = "4.3.3" libc = "0.2.167" log = "0.4.22" 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_block/src/lib.rs b/vhost_user_block/src/lib.rs index d17e24082..5344e4104 100644 --- a/vhost_user_block/src/lib.rs +++ b/vhost_user_block/src/lib.rs @@ -16,13 +16,14 @@ use std::path::PathBuf; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Mutex, RwLock, RwLockWriteGuard}; use std::time::Instant; -use std::{convert, error, fmt, io, process, result}; +use std::{convert, io, process, result}; use block::qcow::{self, ImageType, QcowFile}; use block::{build_serial, Request, VirtioBlockConfig}; use libc::EFD_NONBLOCK; use log::*; 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; @@ -52,19 +53,25 @@ type Result = std::result::Result; type VhostUserBackendResult = std::result::Result; #[allow(dead_code)] -#[derive(Debug)] +#[derive(Error, Debug)] 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 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, /// No path provided + #[error("No path provided")] PathParameterMissing, /// No socket provided + #[error("No socket provided")] SocketParameterMissing, } @@ -73,14 +80,6 @@ pub const SYNTAX: &str = "vhost-user-block backend parameters \ queue_size=,readonly=true|false,direct=true|false,\ poll_queue=true|false\""; -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "vhost_user_block_error: {self:?}") - } -} - -impl error::Error for Error {} - impl convert::From for io::Error { fn from(e: Error) -> Self { io::Error::other(e)