vhost_user_net: Propagate errors correctly

Clean up the error handling and ensure that where possible errors are
propagated. Make use of std::convert::From in order to translate error
types.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford 2019-10-15 16:34:47 +01:00 committed by Sebastien Boeuf
parent 8663b429b3
commit cc72ed1cc9

View File

@ -19,6 +19,7 @@ use epoll;
use libc::{self, EAGAIN, EFD_NONBLOCK}; use libc::{self, EAGAIN, EFD_NONBLOCK};
use log::*; use log::*;
use std::cmp; use std::cmp;
use std::fmt;
use std::io::Read; use std::io::Read;
use std::io::{self, Write}; use std::io::{self, Write};
use std::mem; use std::mem;
@ -105,6 +106,20 @@ pub enum Error {
TapEnable(TapError), TapEnable(TapError),
} }
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<Error> for std::io::Error {
fn from(e: Error) -> Self {
std::io::Error::new(io::ErrorKind::Other, e)
}
}
#[derive(Clone)] #[derive(Clone)]
struct TxVirtio { struct TxVirtio {
iovec: Vec<(GuestAddress, usize)>, iovec: Vec<(GuestAddress, usize)>,
@ -368,7 +383,7 @@ impl VhostUserNetBackend {
read_count += limit - read_count; read_count += limit - read_count;
} }
Err(e) => { Err(e) => {
println!("Failed to read slice: {:?}", e); error!("Failed to read slice: {:?}", e);
break; break;
} }
} }
@ -378,7 +393,7 @@ impl VhostUserNetBackend {
match write_result { match write_result {
Ok(_) => {} Ok(_) => {}
Err(e) => { Err(e) => {
println!("net: tx: error failed to write to tap: {}", e); error!("net: tx: error failed to write to tap: {}", e);
} }
}; };
} }
@ -430,14 +445,13 @@ impl VhostUserBackend for VhostUserNetBackend {
vrings: &[Arc<RwLock<Vring>>], vrings: &[Arc<RwLock<Vring>>],
) -> VhostUserBackendResult<bool> { ) -> VhostUserBackendResult<bool> {
if evset != epoll::Events::EPOLLIN { if evset != epoll::Events::EPOLLIN {
println!("Invalid events operation!\n"); return Err(Error::HandleEventNotEpollIn.into());
return Ok(false);
} }
match device_event { match device_event {
RX_QUEUE_EVENT => { RX_QUEUE_EVENT => {
let mut vring = vrings[0].write().unwrap(); let mut vring = vrings[0].write().unwrap();
self.resume_rx(&mut vring).unwrap(); self.resume_rx(&mut vring)?;
if !self.rx_tap_listening { if !self.rx_tap_listening {
self.vring_worker.as_ref().unwrap().register_listener( self.vring_worker.as_ref().unwrap().register_listener(
@ -450,7 +464,7 @@ impl VhostUserBackend for VhostUserNetBackend {
} }
TX_QUEUE_EVENT => { TX_QUEUE_EVENT => {
let mut vring = vrings[1].write().unwrap(); let mut vring = vrings[1].write().unwrap();
self.process_tx(&mut vring).unwrap(); self.process_tx(&mut vring)?;
} }
RX_TAP_EVENT => { RX_TAP_EVENT => {
let mut vring = vrings[0].write().unwrap(); let mut vring = vrings[0].write().unwrap();
@ -458,24 +472,22 @@ impl VhostUserBackend for VhostUserNetBackend {
// Process a deferred frame first if available. Don't read from tap again // Process a deferred frame first if available. Don't read from tap again
// until we manage to receive this deferred frame. // until we manage to receive this deferred frame.
{ {
if self.rx_single_frame(&mut vring).unwrap() { if self.rx_single_frame(&mut vring)? {
self.rx.deferred_frame = false; self.rx.deferred_frame = false;
self.process_rx(&mut vring).unwrap(); self.process_rx(&mut vring)?;
} else if self.rx.deferred_irqs { } else if self.rx.deferred_irqs {
self.rx.deferred_irqs = false; self.rx.deferred_irqs = false;
vring.signal_used_queue().unwrap(); vring.signal_used_queue()?;
} }
} else { } else {
self.process_rx(&mut vring).unwrap(); self.process_rx(&mut vring)?;
} }
} }
KILL_EVENT => { KILL_EVENT => {
self.kill_evt.read().unwrap(); self.kill_evt.read().unwrap();
return Ok(true); return Ok(true);
} }
_ => { _ => return Err(Error::HandleEventUnknownEvent.into()),
println!("Unknown event for vhost-user-net");
}
} }
Ok(false) Ok(false)
@ -562,22 +574,20 @@ fn main() {
.unwrap(); .unwrap();
let vring_worker = net_daemon.get_vring_worker(); let vring_worker = net_daemon.get_vring_worker();
if vring_worker if let Err(e) = vring_worker.register_listener(
.register_listener( net_backend.read().unwrap().kill_evt.as_raw_fd(),
net_backend.read().unwrap().kill_evt.as_raw_fd(), epoll::Events::EPOLLIN,
epoll::Events::EPOLLIN, u64::from(KILL_EVENT),
u64::from(KILL_EVENT), ) {
) println!("failed to register listener for kill event: {:?}", e);
.is_err() process::exit(1);
{
println!("failed to register listener for kill event\n");
} }
net_backend.write().unwrap().vring_worker = Some(vring_worker); net_backend.write().unwrap().vring_worker = Some(vring_worker);
if let Err(e) = net_daemon.start() { if let Err(e) = net_daemon.start() {
println!( println!(
"failed to start daemon for vhost-user-net with error: {:?}\n", "failed to start daemon for vhost-user-net with error: {:?}",
e e
); );
process::exit(1); process::exit(1);