Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

migrate from failure to anyhow + thiserror #127

Merged
merged 7 commits into from
Feb 24, 2021
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
move dpdk/ffi/runtime to anyhow
  • Loading branch information
drunkirishcoder committed Feb 23, 2021
commit 831fa02be987c89a9a24d187af8ab81295c9cdf7
2 changes: 2 additions & 0 deletions core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -20,6 +20,7 @@ path = "src/lib.rs"
doctest = false

[dependencies]
anyhow = "1.0"
capsule-ffi = { version = "0.1.4", path = "../ffi" }
capsule-macros = { version = "0.1.4", path = "../macros" }
clap = "2.33"
@@ -33,6 +34,7 @@ once_cell = "1.2"
proptest = { version = "0.10", optional = true }
regex = "1"
serde = { version = "1.0", features = ["derive"] }
thiserror = "1.0"
tokio = "=0.2.0-alpha.6"
tokio-executor = { version = "=0.2.0-alpha.6", features = ["current-thread", "threadpool"] }
tokio-net = { version = "=0.2.0-alpha.6", features = ["signal"] }
17 changes: 9 additions & 8 deletions core/src/dpdk/kni.rs
Original file line number Diff line number Diff line change
@@ -24,12 +24,13 @@ use crate::ffi::{self, AsStr, ToResult};
use crate::metrics::{labels, Counter, SINK};
use crate::net::MacAddr;
use crate::{debug, error, warn};
use failure::{Fail, Fallible};
use anyhow::Result;
use futures::{future, Future, StreamExt};
use std::cmp;
use std::mem;
use std::os::raw;
use std::ptr::{self, NonNull};
use thiserror::Error;
use tokio::sync::mpsc::{self, UnboundedReceiver, UnboundedSender};

/// Creates a new KNI counter.
@@ -232,12 +233,12 @@ unsafe impl Send for KniRx {}
unsafe impl Send for KniTx {}

/// KNI errors.
#[derive(Debug, Fail)]
#[derive(Error, Debug)]
pub(crate) enum KniError {
#[fail(display = "KNI is not enabled for the port.")]
#[error("KNI is not enabled for the port.")]
Disabled,

#[fail(display = "Another core owns the handle.")]
#[error("Another core owns the handle.")]
NotAcquired,
}

@@ -277,12 +278,12 @@ impl Kni {
}

/// Takes ownership of the RX handle.
pub(crate) fn take_rx(&mut self) -> Fallible<KniRx> {
pub(crate) fn take_rx(&mut self) -> Result<KniRx> {
self.rx.take().ok_or_else(|| KniError::NotAcquired.into())
}

/// Takes ownership of the TX handle.
pub(crate) fn take_tx(&mut self) -> Fallible<KniTx> {
pub(crate) fn take_tx(&mut self) -> Result<KniTx> {
self.tx.take().ok_or_else(|| KniError::NotAcquired.into())
}

@@ -378,7 +379,7 @@ impl<'a> KniBuilder<'a> {
self
}

pub(crate) fn finish(&mut self) -> Fallible<Kni> {
pub(crate) fn finish(&mut self) -> Result<Kni> {
self.conf.mbuf_size = ffi::RTE_MBUF_DEFAULT_BUF_SIZE;
self.ops.change_mtu = Some(change_mtu);
self.ops.config_network_if = Some(config_network_if);
@@ -394,7 +395,7 @@ impl<'a> KniBuilder<'a> {
}

/// Initializes and preallocates the KNI subsystem.
pub(crate) fn kni_init(max: usize) -> Fallible<()> {
pub(crate) fn kni_init(max: usize) -> Result<()> {
unsafe {
ffi::rte_kni_init(max as raw::c_uint)
.to_result(DpdkError::from_errno)
100 changes: 74 additions & 26 deletions core/src/dpdk/mbuf.rs
Original file line number Diff line number Diff line change
@@ -21,12 +21,13 @@ use crate::dpdk::{DpdkError, MempoolError};
use crate::ffi::{self, ToResult};
use crate::packets::{Internal, Packet};
use crate::{ensure, trace};
use failure::{Fail, Fallible};
use anyhow::Result;
use std::fmt;
use std::mem;
use std::os::raw;
use std::ptr::{self, NonNull};
use std::slice;
use thiserror::Error;

/// A trait for returning the size of a type in bytes.
///
@@ -81,21 +82,18 @@ impl SizeOf for ::std::net::Ipv6Addr {
}

/// Error indicating buffer access failures.
#[derive(Debug, Fail)]
#[derive(Error, Debug)]
pub(crate) enum BufferError {
/// The offset exceeds the buffer length.
#[fail(display = "Offset {} exceeds the buffer length {}.", _0, _1)]
#[error("Offset {0} exceeds the buffer length {1}.")]
BadOffset(usize, usize),

/// The buffer is not resized.
#[fail(display = "Buffer is not resized.")]
#[error("Buffer is not resized.")]
NotResized,

/// The struct size exceeds the remaining buffer length.
#[fail(
display = "Struct size {} exceeds the remaining buffer length {}.",
_0, _1
)]
#[error("Struct size {0} exceeds the remaining buffer length {1}.")]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is nicer.

OutOfBuffer(usize, usize),
}

@@ -143,8 +141,12 @@ impl Mbuf {
/// The Mbuf is allocated from the `Mempool` assigned to the current
/// executing thread by the `Runtime`. The call will fail if invoked
/// from a thread not managed by the `Runtime`.
///
/// # Errors
///
/// Returns `MempoolError::Exhausted` if the allocation of mbuf fails.
#[inline]
pub fn new() -> Fallible<Self> {
pub fn new() -> Result<Self> {
let mempool = MEMPOOL.with(|tls| tls.get());
let raw =
unsafe { ffi::_rte_pktmbuf_alloc(mempool).to_result(|_| MempoolError::Exhausted)? };
@@ -155,8 +157,14 @@ impl Mbuf {
}

/// Creates a new message buffer from a byte array.
///
/// # Errors
///
/// Returns `MempoolError::Exhausted` if the allocation of mbuf fails.
/// Returns `BufferError::NotResized` if the byte array is larger than
/// the maximum mbuf size.
#[inline]
pub fn from_bytes(data: &[u8]) -> Fallible<Self> {
pub fn from_bytes(data: &[u8]) -> Result<Self> {
let mut mbuf = Mbuf::new()?;
mbuf.extend(0, data.len())?;
mbuf.write_data_slice(0, data)?;
@@ -207,8 +215,14 @@ impl Mbuf {
///
/// If the offset is not at the end of the data. The data after the
/// offset is shifted down to make room.
///
/// # Errors
///
/// Returns `BufferError::NotResized` if the offset is out of bound,
/// or the length to extend is either 0 or exceeds the available free
/// buffer capacity.
#[inline]
pub fn extend(&mut self, offset: usize, len: usize) -> Fallible<()> {
pub fn extend(&mut self, offset: usize, len: usize) -> Result<()> {
ensure!(len > 0, BufferError::NotResized);
ensure!(offset <= self.data_len(), BufferError::NotResized);
ensure!(len < self.tailroom(), BufferError::NotResized);
@@ -233,8 +247,13 @@ impl Mbuf {
/// Shrinks the data buffer at offset by `len` bytes.
///
/// The data at offset is shifted up.
///
/// # Errors
///
/// Returns `BufferError::NotResized` if the length to shrink is either
/// 0 or exceeds the used buffer size starting at offset.
#[inline]
pub fn shrink(&mut self, offset: usize, len: usize) -> Fallible<()> {
pub fn shrink(&mut self, offset: usize, len: usize) -> Result<()> {
ensure!(len > 0, BufferError::NotResized);
ensure!(offset + len <= self.data_len(), BufferError::NotResized);

@@ -256,8 +275,10 @@ impl Mbuf {
}

/// Resizes the data buffer.
///
/// Delegates to either `extend` or `shrink`.
#[inline]
pub fn resize(&mut self, offset: usize, len: isize) -> Fallible<()> {
pub fn resize(&mut self, offset: usize, len: isize) -> Result<()> {
if len < 0 {
self.shrink(offset, -len as usize)
} else {
@@ -266,8 +287,13 @@ impl Mbuf {
}

/// Truncates the data buffer to len.
///
/// # Errors
///
/// Returns `BufferError::NotResized` if the target length exceeds the
/// actual used buffer size.
#[inline]
pub fn truncate(&mut self, to_len: usize) -> Fallible<()> {
pub fn truncate(&mut self, to_len: usize) -> Result<()> {
ensure!(to_len < self.data_len(), BufferError::NotResized);

self.raw_mut().data_len = to_len as u16;
@@ -277,8 +303,14 @@ impl Mbuf {
}

/// Reads the data at offset as `T` and returns it as a raw pointer.
///
/// # Errors
///
/// Returns `BufferError::BadOffset` if the offset is out of bound.
/// Returns `BufferError::OutOfBuffer` if the size of `T` exceeds the
/// size of the data stored at offset.
#[inline]
pub fn read_data<T: SizeOf>(&self, offset: usize) -> Fallible<NonNull<T>> {
pub fn read_data<T: SizeOf>(&self, offset: usize) -> Result<NonNull<T>> {
ensure!(
offset < self.data_len(),
BufferError::BadOffset(offset, self.data_len())
@@ -300,8 +332,13 @@ impl Mbuf {
/// Before writing to the data buffer, should call `Mbuf::extend` first
/// to make sure enough space is allocated for the write and data is not
/// being overridden.
///
/// # Errors
///
/// Returns `BufferError::OutOfBuffer` if the size of `T` exceeds the
/// available buffer capacity starting at offset.
#[inline]
pub fn write_data<T: SizeOf>(&mut self, offset: usize, item: &T) -> Fallible<NonNull<T>> {
pub fn write_data<T: SizeOf>(&mut self, offset: usize, item: &T) -> Result<NonNull<T>> {
ensure!(
offset + T::size_of() <= self.data_len(),
BufferError::OutOfBuffer(T::size_of(), self.data_len() - offset)
@@ -318,12 +355,14 @@ impl Mbuf {

/// Reads the data at offset as a slice of `T` and returns the slice as
/// a raw pointer.
///
/// # Errors
///
/// Returns `BufferError::BadOffset` if the offset is out of bound.
/// Returns `BufferError::OutOfBuffer` if the size of `T` slice exceeds
/// the size of the data stored at offset.
#[inline]
pub fn read_data_slice<T: SizeOf>(
&self,
offset: usize,
count: usize,
) -> Fallible<NonNull<[T]>> {
pub fn read_data_slice<T: SizeOf>(&self, offset: usize, count: usize) -> Result<NonNull<[T]>> {
ensure!(
offset < self.data_len(),
BufferError::BadOffset(offset, self.data_len())
@@ -346,12 +385,17 @@ impl Mbuf {
/// Before writing to the data buffer, should call `Mbuf::extend` first
/// to make sure enough space is allocated for the write and data is not
/// being overridden.
///
/// # Errors
///
/// Returns `BufferError::OutOfBuffer` if the size of `T` slice exceeds
/// the available buffer capacity starting at offset.
#[inline]
pub fn write_data_slice<T: SizeOf>(
&mut self,
offset: usize,
slice: &[T],
) -> Fallible<NonNull<[T]>> {
) -> Result<NonNull<[T]>> {
let count = slice.len();

ensure!(
@@ -380,7 +424,11 @@ impl Mbuf {
}

/// Allocates a Vec of `Mbuf`s of `len` size.
pub fn alloc_bulk(len: usize) -> Fallible<Vec<Mbuf>> {
///
/// # Errors
///
/// Returns `DpdkError` if the allocation of mbuf fails.
pub fn alloc_bulk(len: usize) -> Result<Vec<Mbuf>> {
let mut ptrs = Vec::with_capacity(len);
let mempool = MEMPOOL.with(|tls| tls.get());

@@ -479,12 +527,12 @@ impl Packet for Mbuf {
}

#[inline]
fn try_parse(envelope: Self::Envelope, _internal: Internal) -> Fallible<Self> {
fn try_parse(envelope: Self::Envelope, _internal: Internal) -> Result<Self> {
Ok(envelope)
}

#[inline]
fn try_push(envelope: Self::Envelope, _internal: Internal) -> Fallible<Self> {
fn try_push(envelope: Self::Envelope, _internal: Internal) -> Result<Self> {
Ok(envelope)
}

@@ -494,7 +542,7 @@ impl Packet for Mbuf {
}

#[inline]
fn remove(self) -> Fallible<Self::Envelope> {
fn remove(self) -> Result<Self::Envelope> {
Ok(self)
}

13 changes: 7 additions & 6 deletions core/src/dpdk/mempool.rs
Original file line number Diff line number Diff line change
@@ -20,13 +20,14 @@ use super::SocketId;
use crate::dpdk::DpdkError;
use crate::ffi::{self, AsStr, ToCString, ToResult};
use crate::{debug, info};
use failure::{Fail, Fallible};
use anyhow::Result;
use std::cell::Cell;
use std::collections::HashMap;
use std::fmt;
use std::os::raw;
use std::ptr::{self, NonNull};
use std::sync::atomic::{AtomicUsize, Ordering};
use thiserror::Error;

/// A memory pool is an allocator of message buffers, or `Mbuf`. For best
/// performance, each socket should have a dedicated `Mempool`.
@@ -51,7 +52,7 @@ impl Mempool {
/// # Errors
///
/// If allocation fails, then `DpdkError` is returned.
pub(crate) fn new(capacity: usize, cache_size: usize, socket_id: SocketId) -> Fallible<Self> {
pub(crate) fn new(capacity: usize, cache_size: usize, socket_id: SocketId) -> Result<Self> {
static MEMPOOL_COUNT: AtomicUsize = AtomicUsize::new(0);
let n = MEMPOOL_COUNT.fetch_add(1, Ordering::Relaxed);
let name = format!("mempool{}", n);
@@ -127,12 +128,12 @@ thread_local! {
}

/// Error indicating the `Mempool` is not found or is exhaused.
#[derive(Debug, Fail)]
#[derive(Error, Debug)]
pub(crate) enum MempoolError {
#[fail(display = "Cannot allocate a new mbuf from mempool")]
#[error("Cannot allocate a new mbuf from mempool")]
Exhausted,

#[fail(display = "Mempool for {:?} not found.", _0)]
#[error("Mempool for {0:?} not found.")]
NotFound(SocketId),
}

@@ -162,7 +163,7 @@ impl<'a> MempoolMap<'a> {
/// # Errors
///
/// If the value is not found, `MempoolError::NotFound` is returned.
pub(crate) fn get_raw(&mut self, socket_id: SocketId) -> Fallible<&mut ffi::rte_mempool> {
pub(crate) fn get_raw(&mut self, socket_id: SocketId) -> Result<&mut ffi::rte_mempool> {
self.inner
.get_mut(&socket_id)
.ok_or_else(|| MempoolError::NotFound(socket_id).into())
Loading