procfs_core/
cgroups.rs

1use crate::ProcResult;
2#[cfg(feature = "serde1")]
3use serde::{Deserialize, Serialize};
4use std::io::BufRead;
5
6#[derive(Debug, Clone)]
7#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
8/// Container group controller information.
9pub struct CGroupController {
10    /// The name of the controller.
11    pub name: String,
12    /// The  unique  ID  of  the  cgroup hierarchy on which this controller is mounted.
13    ///
14    /// If multiple cgroups v1 controllers are bound to the same  hierarchy, then each will show
15    /// the same hierarchy ID in this field.  The value in this field will be 0 if:
16    ///
17    /// * the controller is not mounted on a cgroups v1 hierarchy;
18    /// * the controller is bound to the cgroups v2 single unified hierarchy; or
19    /// * the controller is disabled (see below).
20    pub hierarchy: u32,
21    /// The number of control groups in this hierarchy using this controller.
22    pub num_cgroups: u32,
23    /// This field contains the value `true` if this controller is enabled, or `false` if it has been disabled
24    pub enabled: bool,
25}
26
27#[derive(Debug, Clone)]
28#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
29/// Container group controller information.
30// This contains a vector, but if each subsystem name is unique, maybe this can be a
31// hashmap instead
32pub struct CGroupControllers(pub Vec<CGroupController>);
33
34impl crate::FromBufRead for CGroupControllers {
35    fn from_buf_read<R: BufRead>(reader: R) -> ProcResult<Self> {
36        let mut vec = Vec::new();
37
38        for line in reader.lines() {
39            let line = line?;
40            if line.starts_with('#') {
41                continue;
42            }
43
44            let mut s = line.split_whitespace();
45            let name = expect!(s.next(), "name").to_owned();
46            let hierarchy = from_str!(u32, expect!(s.next(), "hierarchy"));
47            let num_cgroups = from_str!(u32, expect!(s.next(), "num_cgroups"));
48            let enabled = expect!(s.next(), "enabled") == "1";
49
50            vec.push(CGroupController {
51                name,
52                hierarchy,
53                num_cgroups,
54                enabled,
55            });
56        }
57
58        Ok(CGroupControllers(vec))
59    }
60}
61
62/// Information about a process cgroup
63#[derive(Debug, Clone)]
64#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
65pub struct ProcessCGroup {
66    /// For cgroups version 1 hierarchies, this field contains a  unique  hierarchy  ID  number
67    /// that  can  be  matched  to  a  hierarchy  ID  in /proc/cgroups.  For the cgroups version 2
68    /// hierarchy, this field contains the value 0.
69    pub hierarchy: u32,
70    /// For cgroups version 1 hierarchies, this field contains a comma-separated list of the
71    /// controllers bound to the hierarchy.
72    ///
73    /// For the cgroups version 2 hierarchy, this field is empty.
74    pub controllers: Vec<String>,
75
76    /// This field contains the pathname of the control group in the hierarchy to which the process
77    /// belongs.
78    ///
79    /// This pathname is  relative  to  the mount point of the hierarchy.
80    pub pathname: String,
81}
82
83/// Information about process cgroups.
84#[derive(Debug, Clone)]
85#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
86pub struct ProcessCGroups(pub Vec<ProcessCGroup>);
87
88impl crate::FromBufRead for ProcessCGroups {
89    fn from_buf_read<R: BufRead>(reader: R) -> ProcResult<Self> {
90        let mut vec = Vec::new();
91
92        for line in reader.lines() {
93            let line = line?;
94            if line.starts_with('#') {
95                continue;
96            }
97
98            let mut s = line.splitn(3, ':');
99            let hierarchy = from_str!(u32, expect!(s.next(), "hierarchy"));
100            let controllers = expect!(s.next(), "controllers")
101                .split(',')
102                .filter(|s| !s.is_empty())
103                .map(|s| s.to_owned())
104                .collect();
105            let pathname = expect!(s.next(), "path").to_owned();
106
107            vec.push(ProcessCGroup {
108                hierarchy,
109                controllers,
110                pathname,
111            });
112        }
113
114        Ok(ProcessCGroups(vec))
115    }
116}
117
118impl IntoIterator for ProcessCGroups {
119    type IntoIter = std::vec::IntoIter<ProcessCGroup>;
120    type Item = ProcessCGroup;
121
122    fn into_iter(self) -> Self::IntoIter {
123        self.0.into_iter()
124    }
125}
126
127impl<'a> IntoIterator for &'a ProcessCGroups {
128    type IntoIter = std::slice::Iter<'a, ProcessCGroup>;
129    type Item = &'a ProcessCGroup;
130
131    fn into_iter(self) -> Self::IntoIter {
132        self.0.iter()
133    }
134}