pub fn new(ver: u8) -> Result<Self> {
        if ver != 1 && ver != 2 {
            return Err(Error::CgroupInvalidVersion(ver.to_string()));
        }

        let mut b = CgroupBuilder {
            version: ver,
            hierarchies: HashMap::new(),
            mount_points: Vec::new(),
        };

        // search PROC_MOUNTS for cgroup mount points
        let f =
            File::open(PROC_MOUNTS).map_err(|e| Error::FileOpen(PathBuf::from(PROC_MOUNTS), e))?;

        // Regex courtesy of Filippo.
        // This will match on each line from /proc/mounts for both v1 and v2 mount points.
        //
        // /proc/mounts cointains lines that look like this:
        // cgroup2 /sys/fs/cgroup/unified cgroup2 rw,nosuid,nodev,noexec,relatime,nsdelegate 0 0
        // cgroup /sys/fs/cgroup/cpu,cpuacct cgroup rw,nosuid,nodev,noexec,relatime,cpu,cpuacct 0 0
        //
        // This Regex will extract:
        //      * "/sys/fs/cgroup/unified" in the "dir" capture group.
        //      * "2" in the "ver" capture group as the cgroup version taken from "cgroup2";
        //          for v1, the "ver" capture group will be empty (len = 0).
        //      * "[...],relatime,cpu,cpuacct" in the "options" capture group; this is used for
        //          cgroupv1 to determine what controllers are mounted at the location.
        let re = Regex::new(
            r"^([a-z2]*)[[:space:]](?P<dir>.*)[[:space:]]cgroup(?P<ver>2?)[[:space:]](?P<options>.*)[[:space:]]0[[:space:]]0$",
        ).map_err(Error::RegEx)?;

        for l in BufReader::new(f).lines() {
            let l = l.map_err(|e| Error::ReadLine(PathBuf::from(PROC_MOUNTS), e))?;
            if let Some(capture) = re.captures(&l) {
                if ver == 2 && capture["ver"].len() == 1 {
                    // Found the cgroupv2 unified mountpoint; with cgroupsv2 there is only one
                    // hierarchy so we insert it in the hashmap to use it later when creating
                    // cgroups
                    b.hierarchies
                        .insert("unified".to_string(), PathBuf::from(&capture["dir"]));
                    break;
                } else if ver == 1 && capture["ver"].is_empty() {
                    // Found a cgroupv1 mountpoint; with cgroupsv1 we can have multiple hierarchies.
                    // Since we don't know which one will be used, we cache the mountpoints now,
                    // and will create the hierachies on demand when a cgroup is built.
                    b.mount_points.push(CgroupMountPoint {
                        dir: String::from(&capture["dir"]),
                        options: String::from(&capture["options"]),
                    });
                }
            }
        }

        if b.hierarchies.is_empty() && b.mount_points.is_empty() {
            Err(Error::CgroupHierarchyMissing(
                "No hierarchy found for this cgroup version.".to_string(),
            ))
        } else {
            Ok(b)
        }
    }
// Creates the builder object
// It will discover cgroup mount points and hierarchies configured
// on the system and cache the info required to create cgroups later
// within this hierarchies
Creates the builder object
It will discover cgroup mount points and hierarchies configured
on the system and cache the info required to create cgroups later
within this hierarchies
Creates the builder object It will discover cgroup mount points and hierarchies configured on the system and cache the info required to create cgroups later within this hierarchies
pub fn new(ver: u8) -> Result<Self> {
        if ver != 1 && ver != 2 {
            return Err(Error::CgroupInvalidVersion(ver.to_string()));
        }
        let mut b = CgroupBuilder {
            version: ver,
            hierarchies: HashMap::new(),
            mount_points: Vec::new(),
        };
        // search PROC_MOUNTS for cgroup mount points
        let f =
            File::open(PROC_MOUNTS).map_err(|e| Error::FileOpen(PathBuf::from(PROC_MOUNTS), e))?;
        // Regex courtesy of Filippo.
        // This will match on each line from /proc/mounts for both v1 and v2 mount points.
        //
        // /proc/mounts cointains lines that look like this:
        // cgroup2 /sys/fs/cgroup/unified cgroup2 rw,nosuid,nodev,noexec,relatime,nsdelegate 0 0
        // cgroup /sys/fs/cgroup/cpu,cpuacct cgroup rw,nosuid,nodev,noexec,relatime,cpu,cpuacct 0 0
        //
        // This Regex will extract:
        //      * "/sys/fs/cgroup/unified" in the "dir" capture group.
        //      * "2" in the "ver" capture group as the cgroup version taken from "cgroup2";
        //          for v1, the "ver" capture group will be empty (len = 0).
        //      * "[...],relatime,cpu,cpuacct" in the "options" capture group; this is used for
        //          cgroupv1 to determine what controllers are mounted at the location.
        let re = Regex::new(
            r"^([a-z2]*)[[:space:]](?P<dir>.*)[[:space:]]cgroup(?P<ver>2?)[[:space:]](?P<options>.*)[[:space:]]0[[:space:]]0$",
        ).map_err(Error::RegEx)?;
        for l in BufReader::new(f).lines() {
            let l = l.map_err(|e| Error::ReadLine(PathBuf::from(PROC_MOUNTS), e))?;
            if let Some(capture) = re.captures(&l) {
                if ver == 2 && capture["ver"].len() == 1 {
                    // Found the cgroupv2 unified mountpoint; with cgroupsv2 there is only one
                    // hierarchy so we insert it in the hashmap to use it later when creating
                    // cgroups
                    b.hierarchies
                        .insert("unified".to_string(), PathBuf::from(&capture["dir"]));
                    break;
                } else if ver == 1 && capture["ver"].is_empty() {
                    // Found a cgroupv1 mountpoint; with cgroupsv1 we can have multiple hierarchies.
                    // Since we don't know which one will be used, we cache the mountpoints now,
                    // and will create the hierachies on demand when a cgroup is built.
                    b.mount_points.push(CgroupMountPoint {
                        dir: String::from(&capture["dir"]),
                        options: String::from(&capture["options"]),
                    });
                }
            }
        }
        if b.hierarchies.is_empty() && b.mount_points.is_empty() {
            Err(Error::CgroupHierarchyMissing(
                "No hierarchy found for this cgroup version.".to_string(),
            ))
        } else {
            Ok(b)
        }
    }
pub fn new ( ver : u8 ) -> Result < Self > { if ver != 1 && ver != 2 { return Err ( Error :: CgroupInvalidVersion ( ver . to_string ( ) ) ) ; } let mut b = CgroupBuilder { version : ver , hierarchies : HashMap :: new ( ) , mount_points : Vec :: new ( ) , } ; // search PROC_MOUNTS for cgroup mount points let f = File :: open ( PROC_MOUNTS ) . map_err ( | e | Error :: FileOpen ( PathBuf :: from ( PROC_MOUNTS ) , e ) ) ? ; // Regex courtesy of Filippo. // This will match on each line from /proc/mounts for both v1 and v2 mount points. // // /proc/mounts cointains lines that look like this: // cgroup2 /sys/fs/cgroup/unified cgroup2 rw,nosuid,nodev,noexec,relatime,nsdelegate 0 0 // cgroup /sys/fs/cgroup/cpu,cpuacct cgroup rw,nosuid,nodev,noexec,relatime,cpu,cpuacct 0 0 // // This Regex will extract: //      * "/sys/fs/cgroup/unified" in the "dir" capture group. //      * "2" in the "ver" capture group as the cgroup version taken from "cgroup2"; //          for v1, the "ver" capture group will be empty (len = 0). //      * "[...],relatime,cpu,cpuacct" in the "options" capture group; this is used for //          cgroupv1 to determine what controllers are mounted at the location. let re = Regex :: new ( r"^([a-z2]*)[[:space:]](?P<dir>.*)[[:space:]]cgroup(?P<ver>2?)[[:space:]](?P<options>.*)[[:space:]]0[[:space:]]0$" , ) . map_err ( Error :: RegEx ) ? ; for l in BufReader :: new ( f ) . lines ( ) { let l = l . map_err ( | e | Error :: ReadLine ( PathBuf :: from ( PROC_MOUNTS ) , e ) ) ? ; if let Some ( capture ) = re . captures ( & l ) { if ver == 2 && capture [ " " ] . len ( ) == 1 { // Found the cgroupv2 unified mountpoint; with cgroupsv2 there is only one // hierarchy so we insert it in the hashmap to use it later when creating // cgroups b . hierarchies . insert ( " " . to_string ( ) , PathBuf :: from ( & capture [ " " ] ) ) ; break ; } else if ver == 1 && capture [ " " ] . is_empty ( ) { // Found a cgroupv1 mountpoint; with cgroupsv1 we can have multiple hierarchies. // Since we don't know which one will be used, we cache the mountpoints now, // and will create the hierachies on demand when a cgroup is built. b . mount_points . push ( CgroupMountPoint { dir : String :: from ( & capture [ " " ] ) , options : String :: from ( & capture [ " " ] ) , } ) ; } } } if b . hierarchies . is_empty ( ) && b . mount_points . is_empty ( ) { Err ( Error :: CgroupHierarchyMissing ( " " . to_string ( ) , ) ) } else { Ok ( b ) } }
Creates the builder object
It will discover cgroup mount points and hierarchies configured
on the system and cache the info required to create cgroups later
within this hierarchies
Creates the builder object It will discover cgroup mount points and hierarchies configured on the system and cache the info required to create cgroups later within this hierarchies
ver
u8
ver
u8