liboj-cgroups 0.1.0

Cgroup wrapping for liboj
Documentation
use std::fs;
use std::io;
use std::path::Path;
use std::time::Duration;

use super::Controller;
use crate::{
    attr_file::{AttrFile, ReadAttr, StatMap, WriteAttr},
    hierarchy::HierarchyNode,
};

pub trait CpuController: Controller {
    fn shares(&self) -> Box<dyn '_ + AttrFile<usize>>;
    fn stat(&self) -> Box<dyn '_ + ReadAttr<Stat>>;
    fn cfs_period_us(&self) -> Box<dyn '_ + AttrFile<Duration>>;
    fn cfs_quota_us(&self) -> Box<dyn '_ + AttrFile<Duration>>;
}

impl CpuController for HierarchyNode {
    fn shares(&self) -> Box<dyn '_ + AttrFile<usize>> {
        unimplemented!()
    }

    fn stat(&self) -> Box<dyn '_ + ReadAttr<Stat>> {
        let file = StatFile(self.as_path().join("cpu.cfs_period_us"));
        Box::new(file)
    }

    fn cfs_period_us(&self) -> Box<dyn '_ + AttrFile<Duration>> {
        let file = CpuTimeFile(self.as_path().join("cpu.cfs_period_us"));
        Box::new(file)
    }

    fn cfs_quota_us(&self) -> Box<dyn '_ + AttrFile<Duration>> {
        let file = CpuTimeFile(self.as_path().join("cpu.cfs_quota_us"));
        Box::new(file)
    }
}

struct CpuTimeFile<P: AsRef<Path>>(P);

impl<P: AsRef<Path>> ReadAttr<Duration> for CpuTimeFile<P> {
    fn read(&self) -> io::Result<Duration> {
        match fs::read_to_string(&self.0)?.trim().parse() {
            Ok(us) => Ok(Duration::from_micros(us)),
            Err(_) => Err(io::Error::new(
                io::ErrorKind::InvalidData,
                format!("failed to parse time from {}", self.0.as_ref().display()),
            )),
        }
    }
}

impl<P: AsRef<Path>> WriteAttr<Duration> for CpuTimeFile<P> {
    fn write(&self, attr: &Duration) -> io::Result<()> {
        fs::write(&self.0, attr.as_micros().to_string())
    }
}

struct StatFile<P: AsRef<Path>>(P);

impl<P: AsRef<Path>> ReadAttr<Stat> for StatFile<P> {
    fn read(&self) -> io::Result<Stat> {
        let s = fs::read_to_string(&self.0)?;
        let stat_map = StatMap::from(s.as_str());
        let res = stat_attr!(stat_map, Stat, [nr_periods, nr_throttled, throttled_time]);
        Ok(res)
    }
}

pub struct Stat {
    pub nr_periods: u64,
    pub nr_throttled: u64,
    pub throttled_time: u64,
}