#![deny(missing_docs)]
#[cfg_attr(feature = "vhost-user", macro_use)]
extern crate bitflags;
#[cfg_attr(feature = "vhost-kern", macro_use)]
extern crate vmm_sys_util;
mod backend;
pub use backend::*;
#[cfg(feature = "vhost-net")]
pub mod net;
#[cfg(feature = "vhost-vdpa")]
pub mod vdpa;
#[cfg(feature = "vhost-kern")]
pub mod vhost_kern;
#[cfg(feature = "vhost-user")]
pub mod vhost_user;
#[cfg(feature = "vhost-vsock")]
pub mod vsock;
#[cfg(all(
not(RUSTDOC_disable_feature_compat_errors),
not(doc),
feature = "postcopy",
feature = "xen"
))]
compile_error!("Both `postcopy` and `xen` features can not be enabled at the same time.");
#[derive(Debug)]
pub enum Error {
InvalidOperation,
InvalidGuestMemory,
InvalidGuestMemoryRegion,
InvalidIotlbMsg,
InvalidQueue,
DescriptorTableAddress,
UsedAddress,
AvailAddress,
LogAddress,
#[cfg(feature = "vhost-kern")]
VhostOpen(std::io::Error),
#[cfg(feature = "vhost-kern")]
IoctlError(std::io::Error),
IOError(std::io::Error),
#[cfg(feature = "vhost-user")]
VhostUserProtocol(vhost_user::Error),
}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Error::InvalidOperation => write!(f, "invalid vhost operations"),
Error::InvalidGuestMemory => write!(f, "invalid guest memory object"),
Error::InvalidGuestMemoryRegion => write!(f, "invalid guest memory region"),
Error::InvalidIotlbMsg => write!(f, "invalid IOTLB message"),
Error::InvalidQueue => write!(f, "invalid virtqueue"),
Error::DescriptorTableAddress => {
write!(f, "invalid virtqueue descriptor table address")
}
Error::UsedAddress => write!(f, "invalid virtqueue used table address"),
Error::AvailAddress => write!(f, "invalid virtqueue available table address"),
Error::LogAddress => write!(f, "invalid virtqueue log address"),
Error::IOError(e) => write!(f, "IO error: {e}"),
#[cfg(feature = "vhost-kern")]
Error::VhostOpen(e) => write!(f, "failure in opening vhost file: {e}"),
#[cfg(feature = "vhost-kern")]
Error::IoctlError(e) => write!(f, "failure in vhost ioctl: {e}"),
#[cfg(feature = "vhost-user")]
Error::VhostUserProtocol(e) => write!(f, "vhost-user: {e}"),
}
}
}
impl std::error::Error for Error {}
#[cfg(feature = "vhost-user")]
impl std::convert::From<vhost_user::Error> for Error {
fn from(err: vhost_user::Error) -> Self {
Error::VhostUserProtocol(err)
}
}
pub type Result<T> = std::result::Result<T, Error>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_error() {
assert_eq!(
format!("{}", Error::AvailAddress),
"invalid virtqueue available table address"
);
assert_eq!(
format!("{}", Error::InvalidOperation),
"invalid vhost operations"
);
assert_eq!(
format!("{}", Error::InvalidGuestMemory),
"invalid guest memory object"
);
assert_eq!(
format!("{}", Error::InvalidGuestMemoryRegion),
"invalid guest memory region"
);
assert_eq!(
format!("{}", Error::InvalidIotlbMsg),
"invalid IOTLB message"
);
assert_eq!(format!("{}", Error::InvalidQueue), "invalid virtqueue");
assert_eq!(
format!("{}", Error::DescriptorTableAddress),
"invalid virtqueue descriptor table address"
);
assert_eq!(
format!("{}", Error::UsedAddress),
"invalid virtqueue used table address"
);
assert_eq!(
format!("{}", Error::LogAddress),
"invalid virtqueue log address"
);
assert_eq!(format!("{:?}", Error::AvailAddress), "AvailAddress");
}
#[cfg(feature = "vhost-user")]
#[test]
fn test_convert_from_vhost_user_error() {
let e: Error = vhost_user::Error::OversizedMsg.into();
assert_eq!(format!("{e}"), "vhost-user: oversized message");
}
}