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 <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
This commit is contained in:
Philipp Schuster 2025-05-19 09:50:59 +02:00 committed by Rob Bradford
parent 80e66657cc
commit eb0b14f70e
3 changed files with 13 additions and 12 deletions

1
Cargo.lock generated
View file

@ -2333,6 +2333,7 @@ dependencies = [
"libc",
"log",
"option_parser",
"thiserror 2.0.6",
"vhost",
"vhost-user-backend",
"virtio-bindings",

View file

@ -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 }

View file

@ -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<T> = std::result::Result<T, Error>;
type VhostUserBackendResult<T> = std::result::Result<T, std::io::Error>;
#[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=<size_of_each_queue>,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<Error> for io::Error {
fn from(e: Error) -> Self {
io::Error::other(e)