mirror of https://github.com/aya-rs/aya
Merge e899c8e408
into f9b34fe76f
commit
1d8cc984ab
@ -0,0 +1,535 @@
|
|||||||
|
//! Aya Error types.
|
||||||
|
|
||||||
|
use std::{error::Error, ffi::NulError, io, path::PathBuf};
|
||||||
|
|
||||||
|
use aya_obj::{
|
||||||
|
btf::{BtfError, BtfRelocationError},
|
||||||
|
relocation::EbpfRelocationError,
|
||||||
|
InvalidTypeBinding, ParseError, VerifierLog,
|
||||||
|
};
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
/// The error type returned by [`Ebpf::load_file`] and [`Ebpf::load`].
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
#[cfg_attr(not(test), non_exhaustive)]
|
||||||
|
pub enum EbpfError {
|
||||||
|
/// Error loading file.
|
||||||
|
#[error("error loading {path}")]
|
||||||
|
FileError {
|
||||||
|
/// The file path.
|
||||||
|
path: PathBuf,
|
||||||
|
#[source]
|
||||||
|
/// The original [`io::Error`].
|
||||||
|
error: io::Error,
|
||||||
|
},
|
||||||
|
|
||||||
|
#[error("map error: {0}")]
|
||||||
|
/// A map error.
|
||||||
|
MapError(#[from] MapError),
|
||||||
|
|
||||||
|
#[error("program error: {0}")]
|
||||||
|
/// A program error.
|
||||||
|
ProgramError(#[from] ProgramError),
|
||||||
|
|
||||||
|
/// An irrecoverable error occurred.
|
||||||
|
#[error(transparent)]
|
||||||
|
Other(#[from] Box<dyn Error>),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub(crate) enum EbpfInternalError {
|
||||||
|
#[error("error parsing BPF object: {0}")]
|
||||||
|
ParseError(#[from] ParseError),
|
||||||
|
|
||||||
|
#[error("BTF error: {0}")]
|
||||||
|
BtfError(#[from] BtfError),
|
||||||
|
|
||||||
|
#[error("error relocating function")]
|
||||||
|
RelocationError(#[from] EbpfRelocationError),
|
||||||
|
|
||||||
|
#[error("error relocating section")]
|
||||||
|
BtfRelocationError(#[from] BtfRelocationError),
|
||||||
|
|
||||||
|
#[error("no BTF parsed for object")]
|
||||||
|
NoBTF,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Error type returned when working with programs.
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum ProgramError {
|
||||||
|
/// The program is already loaded.
|
||||||
|
#[error("the program is already loaded")]
|
||||||
|
AlreadyLoaded,
|
||||||
|
|
||||||
|
/// The program is not loaded.
|
||||||
|
#[error("the program is not loaded")]
|
||||||
|
NotLoaded,
|
||||||
|
|
||||||
|
/// Loading the program failed.
|
||||||
|
#[error("the BPF_PROG_LOAD syscall failed. Verifier output: {verifier_log}")]
|
||||||
|
LoadError {
|
||||||
|
/// The [`SysError`] returned by the `BPF_PROG_LOAD` syscall.
|
||||||
|
#[source]
|
||||||
|
source: SysError,
|
||||||
|
/// The error log produced by the kernel verifier.
|
||||||
|
verifier_log: VerifierLog,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// The program is not of the expected type.
|
||||||
|
#[error("unexpected program type")]
|
||||||
|
UnexpectedProgramType,
|
||||||
|
|
||||||
|
/// A syscall failed.
|
||||||
|
#[error("syscall failed")]
|
||||||
|
Syscall(#[from] SysError),
|
||||||
|
|
||||||
|
/// An irrecoverable error occurred.
|
||||||
|
#[error(transparent)]
|
||||||
|
Other(#[from] Box<dyn Error>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<EbpfInternalError> for ProgramError {
|
||||||
|
fn from(e: EbpfInternalError) -> Self {
|
||||||
|
Self::Other(Box::new(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<(i64, SysError)> for ProgramError {
|
||||||
|
fn from((_, error): (i64, SysError)) -> Self {
|
||||||
|
error.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<io::Error> for ProgramError {
|
||||||
|
fn from(e: io::Error) -> Self {
|
||||||
|
Self::Other(Box::new(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<BtfError> for ProgramError {
|
||||||
|
fn from(e: BtfError) -> Self {
|
||||||
|
Self::Other(Box::new(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<LinkError> for ProgramError {
|
||||||
|
fn from(e: LinkError) -> Self {
|
||||||
|
Self::Other(Box::new(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<NulError> for ProgramError {
|
||||||
|
fn from(e: NulError) -> Self {
|
||||||
|
Self::Other(Box::new(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An error ocurred working with a pinned BPF object.
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub(crate) enum PinError {
|
||||||
|
/// The path for the BPF object is not valid.
|
||||||
|
#[error("invalid pin path `{}`", path.display())]
|
||||||
|
InvalidPinPath {
|
||||||
|
/// The path.
|
||||||
|
path: std::path::PathBuf,
|
||||||
|
|
||||||
|
#[source]
|
||||||
|
/// The source error.
|
||||||
|
error: std::ffi::NulError,
|
||||||
|
},
|
||||||
|
/// An irrecoverable error occurred.
|
||||||
|
#[error(transparent)]
|
||||||
|
Other(#[from] Box<dyn Error>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<InternalMapError> for MapError {
|
||||||
|
fn from(e: InternalMapError) -> Self {
|
||||||
|
Self::Other(Box::new(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Errors from operations on maps.
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub enum MapError {
|
||||||
|
/// Key not found
|
||||||
|
#[error("key not found")]
|
||||||
|
KeyNotFound,
|
||||||
|
|
||||||
|
/// Element not found
|
||||||
|
#[error("element not found")]
|
||||||
|
ElementNotFound,
|
||||||
|
|
||||||
|
/// Index is out of bounds
|
||||||
|
#[error("the index is {index} but `max_entries` is {max_entries}")]
|
||||||
|
OutOfBounds {
|
||||||
|
/// Index accessed
|
||||||
|
index: u32,
|
||||||
|
/// Map size
|
||||||
|
max_entries: u32,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Chained programs are not supported.
|
||||||
|
#[error("chained programs are not supported by the current kernel")]
|
||||||
|
ChainedProgramNotSupported,
|
||||||
|
|
||||||
|
/// Invalid map type encontered
|
||||||
|
#[error("invalid map type {map_type}")]
|
||||||
|
InvalidMapType {
|
||||||
|
/// The map type
|
||||||
|
map_type: u32,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// A syscall failed.
|
||||||
|
#[error(transparent)]
|
||||||
|
Syscall(#[from] SysError),
|
||||||
|
|
||||||
|
/// An internal and irrecoverable error occurred.
|
||||||
|
#[error(transparent)]
|
||||||
|
Other(#[from] Box<dyn Error>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<(i64, SysError)> for MapError {
|
||||||
|
fn from((_, error): (i64, SysError)) -> Self {
|
||||||
|
error.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<io::Error> for MapError {
|
||||||
|
fn from(e: io::Error) -> Self {
|
||||||
|
Self::Other(Box::new(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<NulError> for MapError {
|
||||||
|
fn from(e: NulError) -> Self {
|
||||||
|
Self::Other(Box::new(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<PinError> for MapError {
|
||||||
|
fn from(e: PinError) -> Self {
|
||||||
|
Self::Other(Box::new(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
/// Errors occuring from working with Maps
|
||||||
|
pub(crate) enum InternalMapError {
|
||||||
|
/// Invalid map name encountered
|
||||||
|
#[error("invalid map name `{name}`")]
|
||||||
|
InvalidName {
|
||||||
|
/// The map name
|
||||||
|
name: String,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Failed to create map
|
||||||
|
#[error("failed to create map `{name}` with code {code}")]
|
||||||
|
CreateError {
|
||||||
|
/// Map name
|
||||||
|
name: String,
|
||||||
|
/// Error code
|
||||||
|
code: i64,
|
||||||
|
#[source]
|
||||||
|
/// Original io::Error
|
||||||
|
source: SysError,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Invalid key size
|
||||||
|
#[error("invalid key size {size}, expected {expected}")]
|
||||||
|
InvalidKeySize {
|
||||||
|
/// Size encountered
|
||||||
|
size: usize,
|
||||||
|
/// Size expected
|
||||||
|
expected: usize,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Invalid value size
|
||||||
|
#[error("invalid value size {size}, expected {expected}")]
|
||||||
|
InvalidValueSize {
|
||||||
|
/// Size encountered
|
||||||
|
size: usize,
|
||||||
|
/// Size expected
|
||||||
|
expected: usize,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// An IO error occurred
|
||||||
|
#[error(transparent)]
|
||||||
|
IoError(#[from] io::Error),
|
||||||
|
|
||||||
|
/// Syscall failed
|
||||||
|
#[error(transparent)]
|
||||||
|
SysError(#[from] SysError),
|
||||||
|
|
||||||
|
/// Map type not supported
|
||||||
|
#[error("map {0}: type is not supported")]
|
||||||
|
Unsupported(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<InvalidTypeBinding<u32>> for MapError {
|
||||||
|
fn from(e: InvalidTypeBinding<u32>) -> Self {
|
||||||
|
let InvalidTypeBinding { value } = e;
|
||||||
|
Self::InvalidMapType { map_type: value }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Perf buffer error.
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub enum PerfBufferError {
|
||||||
|
/// the page count value passed to [`PerfEventArray::open`](crate::maps::PerfEventArray::open) is invalid.
|
||||||
|
#[error("invalid page count {page_count}, the value must be a power of two")]
|
||||||
|
InvalidPageCount {
|
||||||
|
/// the page count
|
||||||
|
page_count: usize,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// `perf_event_open` failed.
|
||||||
|
#[error("perf_event_open failed: {io_error}")]
|
||||||
|
OpenError {
|
||||||
|
/// the source of this error
|
||||||
|
#[source]
|
||||||
|
io_error: io::Error,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// `mmap`-ping the buffer failed.
|
||||||
|
#[error("mmap failed: {io_error}")]
|
||||||
|
MMapError {
|
||||||
|
/// the source of this error
|
||||||
|
#[source]
|
||||||
|
io_error: io::Error,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// The `PERF_EVENT_IOC_ENABLE` ioctl failed
|
||||||
|
#[error("PERF_EVENT_IOC_ENABLE failed: {io_error}")]
|
||||||
|
PerfEventEnableError {
|
||||||
|
#[source]
|
||||||
|
/// the source of this error
|
||||||
|
io_error: io::Error,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// `read_events()` was called with no output buffers.
|
||||||
|
#[error("read_events() was called with no output buffers")]
|
||||||
|
NoBuffers,
|
||||||
|
|
||||||
|
/// `read_events()` was called with a buffer that is not large enough to
|
||||||
|
/// contain the next event in the perf buffer.
|
||||||
|
#[deprecated(
|
||||||
|
since = "0.10.8",
|
||||||
|
note = "read_events() now calls BytesMut::reserve() internally, so this error is never returned"
|
||||||
|
)]
|
||||||
|
#[error("the buffer needs to be of at least {size} bytes")]
|
||||||
|
MoreSpaceNeeded {
|
||||||
|
/// expected size
|
||||||
|
size: usize,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// An IO error occurred.
|
||||||
|
#[error(transparent)]
|
||||||
|
IOError(#[from] io::Error),
|
||||||
|
|
||||||
|
/// An irrecoverable error occurred.
|
||||||
|
#[error(transparent)]
|
||||||
|
Other(#[from] Box<dyn Error>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<SysError> for PerfBufferError {
|
||||||
|
fn from(e: SysError) -> Self {
|
||||||
|
match e {
|
||||||
|
SysError::Syscall { call: _, io_error } => Self::Other(Box::new(io_error)),
|
||||||
|
SysError::Mmap { io_error } => Self::MMapError { io_error },
|
||||||
|
_ => Self::Other(Box::new(e)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<(i64, SysError)> for PerfBufferError {
|
||||||
|
fn from((_, error): (i64, SysError)) -> Self {
|
||||||
|
error.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
/// Errors from operations on links.
|
||||||
|
pub enum LinkError {
|
||||||
|
/// Invalid link.
|
||||||
|
#[error("Invalid link")]
|
||||||
|
InvalidLink,
|
||||||
|
|
||||||
|
/// The program is not attached.
|
||||||
|
#[error("the program is not attached")]
|
||||||
|
NotAttached,
|
||||||
|
|
||||||
|
/// The program is already attached.
|
||||||
|
#[error("the program is already attached")]
|
||||||
|
AlreadyAttached,
|
||||||
|
|
||||||
|
/// A file error.
|
||||||
|
#[error("file error: {path}")]
|
||||||
|
FileError {
|
||||||
|
/// The file path.
|
||||||
|
path: PathBuf,
|
||||||
|
/// The original [`io::Error`].
|
||||||
|
#[source]
|
||||||
|
error: io::Error,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// An irrecoverable error occurred.
|
||||||
|
#[error(transparent)]
|
||||||
|
Other(#[from] Box<dyn Error>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<(PathBuf, io::Error)> for LinkError {
|
||||||
|
fn from((path, error): (PathBuf, io::Error)) -> Self {
|
||||||
|
Self::FileError { path, error }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<SysError> for LinkError {
|
||||||
|
fn from(e: SysError) -> Self {
|
||||||
|
match e {
|
||||||
|
SysError::Syscall { call: _, io_error } => Self::Other(Box::new(io_error)),
|
||||||
|
_ => Self::Other(Box::new(e)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<(i64, SysError)> for LinkError {
|
||||||
|
fn from((_, error): (i64, SysError)) -> Self {
|
||||||
|
error.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ProgramError> for LinkError {
|
||||||
|
fn from(e: ProgramError) -> Self {
|
||||||
|
Self::Other(Box::new(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<io::Error> for LinkError {
|
||||||
|
fn from(e: io::Error) -> Self {
|
||||||
|
Self::Other(Box::new(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<NulError> for LinkError {
|
||||||
|
fn from(e: NulError) -> Self {
|
||||||
|
Self::Other(Box::new(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<std::num::ParseIntError> for LinkError {
|
||||||
|
fn from(e: std::num::ParseIntError) -> Self {
|
||||||
|
Self::Other(Box::new(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ResolveSymbolError> for LinkError {
|
||||||
|
fn from(e: ResolveSymbolError) -> Self {
|
||||||
|
Self::Other(Box::new(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub(crate) enum InternalLinkError {
|
||||||
|
#[error("the target program is not loaded")]
|
||||||
|
TargetProgramNotLoaded,
|
||||||
|
|
||||||
|
#[error("target program does not have BTF")]
|
||||||
|
TargetNoBtf,
|
||||||
|
|
||||||
|
#[error("error reading ld.so.cache file")]
|
||||||
|
LdSoCache {
|
||||||
|
#[source]
|
||||||
|
io_error: &'static io::Error,
|
||||||
|
},
|
||||||
|
|
||||||
|
#[error("could not resolve uprobe target `{path}`")]
|
||||||
|
InvalidTarget {
|
||||||
|
/// path to target
|
||||||
|
path: PathBuf,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// netlink error while attaching XDP program
|
||||||
|
#[error("Netlink error")]
|
||||||
|
NetlinkError {
|
||||||
|
/// the [`io::Error`] from the netlink call
|
||||||
|
#[source]
|
||||||
|
io_error: io::Error,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// operation not supported for programs loaded via tcx
|
||||||
|
#[error("operation not supported for programs loaded via tcx")]
|
||||||
|
InvalidLinkOperation,
|
||||||
|
|
||||||
|
/// tcx links can only be attached to ingress or egress, custom attachment is not supported
|
||||||
|
#[error("tcx links can only be attached to ingress or egress, custom attachment: {0} is not supported")]
|
||||||
|
InvalidTcxAttach(u32),
|
||||||
|
|
||||||
|
/// The network interface does not exist.
|
||||||
|
#[error("unknown network interface {name}")]
|
||||||
|
UnknownInterface {
|
||||||
|
/// interface name
|
||||||
|
name: String,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Setting the `SO_ATTACH_BPF` socket option failed.
|
||||||
|
#[error("setsockopt SO_ATTACH_BPF failed")]
|
||||||
|
SoAttachEbpf {
|
||||||
|
/// original [`io::Error`]
|
||||||
|
#[source]
|
||||||
|
io_error: io::Error,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<InternalLinkError> for LinkError {
|
||||||
|
fn from(e: InternalLinkError) -> Self {
|
||||||
|
Self::Other(Box::new(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub(crate) enum ResolveSymbolError {
|
||||||
|
#[error(transparent)]
|
||||||
|
Io(#[from] io::Error),
|
||||||
|
|
||||||
|
#[error("error parsing ELF")]
|
||||||
|
Object(#[from] object::Error),
|
||||||
|
|
||||||
|
#[error("unknown symbol `{0}`")]
|
||||||
|
Unknown(String),
|
||||||
|
|
||||||
|
#[error("symbol `{0}` does not appear in section")]
|
||||||
|
NotInSection(String),
|
||||||
|
|
||||||
|
#[error("symbol `{0}` in section `{1:?}` which has no offset")]
|
||||||
|
SectionFileRangeNone(String, Result<String, object::Error>),
|
||||||
|
|
||||||
|
#[error("failed to access debuglink file `{0}`: `{1}`")]
|
||||||
|
DebuglinkAccessError(String, io::Error),
|
||||||
|
|
||||||
|
#[error("symbol `{0}` not found, mismatched build IDs in main and debug files")]
|
||||||
|
BuildIdMismatch(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Errors from Syscalls.
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum SysError {
|
||||||
|
/// A syscall failed.
|
||||||
|
#[error("{call} failed")]
|
||||||
|
Syscall {
|
||||||
|
/// The name of the syscall which failed.
|
||||||
|
call: String,
|
||||||
|
/// The [`io::Error`] returned by the syscall.
|
||||||
|
#[source]
|
||||||
|
io_error: io::Error,
|
||||||
|
},
|
||||||
|
/// A mmap operation failed.
|
||||||
|
#[error("mmap failed")]
|
||||||
|
Mmap {
|
||||||
|
/// The [`io::Error`] returned by the mmap operation.
|
||||||
|
#[source]
|
||||||
|
io_error: io::Error,
|
||||||
|
},
|
||||||
|
/// An irecoverable error occurred.
|
||||||
|
#[error(transparent)]
|
||||||
|
Other(#[from] Box<dyn Error>),
|
||||||
|
}
|
@ -1,29 +0,0 @@
|
|||||||
//! Pinning BPF objects to the BPF filesystem.
|
|
||||||
|
|
||||||
use thiserror::Error;
|
|
||||||
|
|
||||||
use crate::sys::SyscallError;
|
|
||||||
|
|
||||||
/// An error ocurred working with a pinned BPF object.
|
|
||||||
#[derive(Error, Debug)]
|
|
||||||
pub enum PinError {
|
|
||||||
/// The object FD is not known by Aya.
|
|
||||||
#[error("the BPF object `{name}`'s FD is not known")]
|
|
||||||
NoFd {
|
|
||||||
/// Object name.
|
|
||||||
name: String,
|
|
||||||
},
|
|
||||||
/// The path for the BPF object is not valid.
|
|
||||||
#[error("invalid pin path `{}`", path.display())]
|
|
||||||
InvalidPinPath {
|
|
||||||
/// The path.
|
|
||||||
path: std::path::PathBuf,
|
|
||||||
|
|
||||||
#[source]
|
|
||||||
/// The source error.
|
|
||||||
error: std::ffi::NulError,
|
|
||||||
},
|
|
||||||
/// An error ocurred making a syscall.
|
|
||||||
#[error(transparent)]
|
|
||||||
SyscallError(#[from] SyscallError),
|
|
||||||
}
|
|
@ -1 +1 @@
|
|||||||
Subproject commit 20ea95b4505c477af3b6ff6ce9d19cee868ddc5d
|
Subproject commit a2258003f21d9d52afd48aa64787b65ef80bd355
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue