#[derive(Debug)]
pub struct CgroupFileDescriptor(RawFd);
impl Into<File> for CgroupFileDescriptor
{
#[inline(always)]
fn into(self) -> File
{
unsafe { File::from_raw_fd(self.into_raw_fd()) }
}
}
impl Drop for CgroupFileDescriptor
{
#[inline(always)]
fn drop(&mut self)
{
self.as_raw_fd().close()
}
}
impl AsRawFd for CgroupFileDescriptor
{
#[inline(always)]
fn as_raw_fd(&self) -> RawFd
{
self.0
}
}
impl IntoRawFd for CgroupFileDescriptor
{
#[inline(always)]
fn into_raw_fd(self) -> RawFd
{
self.as_raw_fd()
}
}
impl FromRawFd for CgroupFileDescriptor
{
#[inline(always)]
unsafe fn from_raw_fd(fd: RawFd) -> Self
{
Self(fd)
}
}
impl FileDescriptor for CgroupFileDescriptor
{
}
impl UsedAsValueInArrayMapDescriptor for CgroupFileDescriptor
{
#[inline(always)]
fn transmute_from_file_descriptor_copies(values: &[Self]) -> &[RawFd]
{
unsafe { transmute(values) }
}
}
impl ExtendedBpfProgramCanBeAttachedFileDescriptor for CgroupFileDescriptor
{
type ProgramAttachmentType = CgroupProgramAttachmentType;
type ProgramQueryFlags = CgroupProgramQueryFlags;
type ProgramAttachmentFlags = CgroupProgramAttachmentFlags;
type ProgramAttachmentOptions = CgroupProgramAttachmentOptions;
const InitialProgramCountGuess: usize = 64;
}
impl CgroupFileDescriptor
{
#[inline(always)]
pub fn new<C: Cgroup>(mount_point: &CgroupMountPoint, cgroup: &C) -> io::Result<Self>
{
let path = cgroup.to_path(mount_point);
let file = File::open(path)?;
Ok(unsafe { Self::from_raw_fd(file.into_raw_fd()) })
}
pub fn attach_link(cgroup: &CgroupFileDescriptor, program_attachment_type: CgroupProgramAttachmentType, attach_program: &ExtendedBpfProgramFileDescriptor) -> Result<CgroupLinkFileDescriptor, ()>
{
let mut attr = bpf_attr::default();
attr.link_create = BpfCommandLinkCreate
{
prog_fd: attach_program.as_raw_fd(),
target_fd: cgroup.as_raw_fd(),
attach_type: program_attachment_type.to_bpf_attach_type(),
flags: 0,
};
let result = attr.syscall(bpf_cmd::BPF_LINK_CREATE);
if likely!(result >= 0)
{
Ok(CgroupLinkFileDescriptor(result))
}
else if likely!(result == -1)
{
match errno().0
{
EINVAL => panic!("Invalid attr or invalid attach type"),
EPERM => panic!("Permission denied"),
errno @ _ => panic!("Unexpected error `{}` from bpf(BPF_LINK_CREATE)", errno),
}
}
else
{
unreachable_code(format_args!("Unexpected result `{}` from bpf(BPF_LINK_CREATE)", result))
}
}
}