aya: Implement FdLink::pin()

This allows for FdLinks to also be pinned to BpfFs.
In order for it to be called, the user would first call
`take_link` to get the underlying link. This can then
be destructured to an FdLink where FdLink::pin() may be called.

Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
pull/343/head
Dave Tucker 2 years ago
parent 5726b6d044
commit 64f8a434d2

@ -1,14 +1,40 @@
//! Program links. //! Program links.
use libc::{close, dup}; use libc::{close, dup};
use thiserror::Error;
use std::{ use std::{
borrow::Borrow, borrow::Borrow,
collections::{hash_map::Entry, HashMap}, collections::{hash_map::Entry, HashMap},
ffi::CString,
io,
ops::Deref, ops::Deref,
os::unix::prelude::RawFd, os::unix::prelude::RawFd,
path::Path,
}; };
use crate::{generated::bpf_attach_type, programs::ProgramError, sys::bpf_prog_detach}; use crate::{
generated::bpf_attach_type,
programs::ProgramError,
sys::{bpf_pin_object, bpf_prog_detach},
};
/// An error ocurred working with a Link.
#[derive(Error, Debug)]
pub enum LinkError {
/// Invalid Pin Path.
#[error("invalid pin path `{error}`")]
InvalidPinPath {
/// The error message.
error: String,
},
/// Pinning error.
#[error("BPF_OBJ_PIN failed")]
PinError {
/// The [`io::Error`] returned by the syscall.
#[source]
io_error: io::Error,
},
}
/// A Link. /// A Link.
pub trait Link: std::fmt::Debug + 'static { pub trait Link: std::fmt::Debug + 'static {
@ -111,6 +137,24 @@ impl FdLink {
pub(crate) fn new(fd: RawFd) -> FdLink { pub(crate) fn new(fd: RawFd) -> FdLink {
FdLink { fd } FdLink { fd }
} }
/// Pins the FdLink to a BPF filesystem.
///
/// When a BPF object is pinned to a BPF filesystem it will remain attached after
/// Aya has detached the link.
/// To remove the attachment, the file on the BPF filesystem must be remove.
/// Any directories in the the path provided should have been created by the caller.
pub fn pin<P: AsRef<Path>>(&self, path: P) -> Result<(), LinkError> {
let path_string =
CString::new(path.as_ref().to_string_lossy().into_owned()).map_err(|e| {
LinkError::InvalidPinPath {
error: e.to_string(),
}
})?;
bpf_pin_object(self.fd, &path_string)
.map_err(|(_code, io_error)| LinkError::PinError { io_error })?;
Ok(())
}
} }
impl Link for FdLink { impl Link for FdLink {

Loading…
Cancel
Save